Array of a custom class not recognized by TTree

Hi,

I’ve been playing with the having multiple embedded custom classes. I originally wanted vectors of vectors of objects, but that seems too many variable arrays. So I tried having a vector of an object that holds an array of another object.

class SecondEmbeddedClass : public TObject {
  public:
    SecondEmbeddedClass() { variable2=2; variable3 = 3;}
    virtual ~SecondEmbeddedClass() {;}
    
    double variable2;
    int variable3;
  ClassDef(SecondEmbeddedClass, 1)
};

class FirstEmbeddedClass : public TObject {
  public:
    FirstEmbeddedClass() { variable1=1; }
    virtual ~FirstEmbeddedClass() {;}
    
    double variable1;
    SecondEmbeddedClass secondvector[10]; //[10]   tired //-> with the same results
  ClassDef(FirstEmbeddedClass, 1)
};

class MainClass : public TObject {
  public:
    MainClass() { variable0=0; firstvector.resize(5); }
    virtual ~MainClass() {;}
    
    double variable0;
    std::vector<FirstEmbeddedClass> firstvector;
  ClassDef(MainClass, 1)
};
#include "MyClasses.h"
#include "TFile.h"
#include "TTree.h"

using namespace std;

void Test(int argc, char *argv[]) {
  MainClass *myclass = new MainClass();
  
  TFile f("MyClasses.root", "recreate");
  TTree *tree = new TTree("tree", "Testing");
  tree->Branch("main", "MainClass", &myclass, 32000, 99);
  tree->Fill();
  tree->Write();
  delete tree;
  delete myclass;
}

#ifndef __MAKECINT__
int main(int argc, char *argv[]) {
  Test(argc, argv);
  return 0;
}
#endif

The code compiled and ran without warnings or errors. When I opened up the root file, the TTree viewer had a leaf with no name attached to it.


I check the Streamer info, which looked fine.

root [2] f.ShowStreamerInfo()
OBJ: TList	TList	Doubly linked list : 0

StreamerInfo for class: MainClass, version=1, checksum=0xf9da1a25
  TObject        BASE            offset=  0 type=66 Basic ROOT object   
  double         variable0       offset=  0 type= 8                     
  vector<FirstEmbeddedClass> firstvector     offset=  0 type=300 ,stl=1, ctype=61,  (FirstEmbeddedClass)

StreamerInfo for class: TObject, version=1, checksum=0x52d96731
  UInt_t         fUniqueID       offset=  0 type=13 object unique identifier
  UInt_t         fBits           offset=  0 type=15 bit field status word

StreamerInfo for class: FirstEmbeddedClass, version=1, checksum=0xcf97857f
  TObject        BASE            offset=  0 type=66 Basic ROOT object   
  double         variable1       offset=  0 type= 8                     
  SecondEmbeddedClass secondvector[10] offset=  0 type=81 [10]                

StreamerInfo for class: SecondEmbeddedClass, version=1, checksum=0x6d31c85e
  TObject        BASE            offset=  0 type=66 Basic ROOT object   
  double         variable2       offset=  0 type= 8                     
  int            variable3       offset=  0 type= 3 

When I do MakeClass(), it comments out the SecondEmbeddedClass array.

class test {
public :
   TTree          *fChain;   //!pointer to the analyzed TTree or TChain
   Int_t           fCurrent; //!current Tree number in a TChain

   // Declaration of leaf types
 //MainClass       *main;
   UInt_t          fUniqueID;
   UInt_t          fBits;
   Double_t        variable0;
   Int_t           firstvector_;
   UInt_t          firstvector_fUniqueID[kMaxfirstvector];   //[firstvector_]
   UInt_t          firstvector_fBits[kMaxfirstvector];   //[firstvector_]
   Double_t        firstvector_variable1[kMaxfirstvector];   //[firstvector_]
 //SecondEmbeddedClass firstvector_secondvector[10][kMaxfirstvector];

   // List of branches
   TBranch        *b_main_fUniqueID;   //!
   TBranch        *b_main_fBits;   //!
   TBranch        *b_main_variable0;   //!
   TBranch        *b_main_firstvector_;   //!
   TBranch        *b_firstvector_fUniqueID;   //!
   TBranch        *b_firstvector_fBits;   //!
   TBranch        *b_firstvector_variable1;   //!

   test(TTree *tree=0);
   virtual ~test();
   virtual Int_t    Cut(Long64_t entry);
   virtual Int_t    GetEntry(Long64_t entry);
   virtual Long64_t LoadTree(Long64_t entry);
   virtual void     Init(TTree *tree);
   virtual void     Loop();
   virtual Bool_t   Notify();
   virtual void     Show(Long64_t entry = -1);
};

#endif

I noticed if i just declare std::vector secondvector instead of SecondEmbeddedClass secondvector[10], this blank tag and behavior doesn’t occur. The secondvector will not be splite because of “too many variable arrays.” So when I try to circumvent the too many variable arrays with a set size array, this happens. Why is this happening? And how can I get the SecondEmbeddedClass to be split?

I attached the program below.
MyClasses.tar.gz (1.21 KB)

Hi,

This has been fixed in the trunk (rev. 43728) and in 5.32 patches (rev. 43729). Thanks for reporting this issue (and sorry for the delay).

Cheers, Bertrand.