How to include in a TTree an array of objects?

Dear ROOTers,

actually I’m filling my Tree with simple data structures like:


//.. in .h
  struct _cluster
  {
    int nClust;
    int firsthitClust[MAXNUMOFCLUSTER];
    int lasthitClust[MAXNUMOFCLUSTER];
    int maxchgposClust[MAXNUMOFCLUSTER];
    int maxchgClust[MAXNUMOFCLUSTER];
    float posClust[MAXNUMOFCLUSTER];
    float chargeClust[MAXNUMOFCLUSTER];
  } clusterm1x, clusterm1y, clusterm2x, clusterm2y, clusterm3x, clusterm3y;

//.. in .C

   precluster->Branch("clusterm1xN", &(clusterm1x.nClust), "m1xN/I2");
   precluster->Branch("clusterm1xhit1", &(clusterm1x.firsthitClust[0]),
		      "m1xhit1[m1xN]/I2");
[..etc..]

//.. access in main routine with something like
   mytree->Draw("m1xpos:m2xpos","m1xN==1 && m2xN==1")

but I’d like to move to another approach, where I have a class “Cluster” and I fill my Tree events with several arrays of these objects, one per detector.

I’d love that people access to data with something like (if possible):

where m1x and m2x are arrays of Cluster objects and I have some variable or method that give me the number of elements.

I tried at first to write a cluster class:

class Cluster {
  public:
    short firstch;
    short lastch;
    short maxpos;
    short maxq;
    float pos;
    float q;
     //Default constructor
    Cluster (short firstch = -1, short lastch = -1,
	     short maxpos = -1, short maxq = 0,
	     float pos = -1., float q = 0.);
    //Copy constructor
    Cluster (Cluster& original);
    // Other methods...

It works and I can insert this kind of object in a TTree after the compilation of the class which provide also the dictionary (as far as I read from manual, this is the only prerequisite for an object to be inserted in a Tree)

The problematic part is how to design and include in a TTree the “array of Clusters”.

FIRST APPROACH: STL
I tried at first with STL container vector: in the manual it seems they can be inserted in the TTree but it is not so clear. Anyway the problem I get is that ROOT has no dictionary for the template specialization vector.

Even if I’ll probably go to the next approach with TClonesArray, can you explain me, for my personal knowledge, how you can include an STL container in the tree?

SECOND APPROACH: TClonesArray
I followed the example in the TTree chapter of the manual (and the TClonesArray reference), but I put in the branch directly the the TCloneArray instead of embedding it. Of course I had to derive Cluster from TObject and to add the ClassDef macro.

TClonesArray *m1x = new TClonesArray("RD51TB::Cluster", 10); new((*m1x)[0]) RD51TB::Cluster(a); //what is this syntax?!!??!?! new((*m1x)[1]) RD51TB::Cluster(b); new((*m1x)[2]) RD51TB::Cluster(c); mytree.Branch("m1x","TClonesArray",&m1x);

It seems to work, the only thing I don’t like are the additional two variables that come from TObject… is there any way to remove or at least hide them?
Moreover, again for my knowledge, may you explain me how do I read that strange “new” syntax? I have never seen something like that…

Thanks a lot,
Matteo

[quote]Even if I’ll probably go to the next approach with TClonesArray, can you explain me, for my personal knowledge, how you can include an STL container in the tree? [/quote]Simply generate a dictionary for the vector :slight_smile:

[quote]is there any way to remove or at least hide them? [/quote]Call TClass::GetClass(“Cluster”)->IgnoreTObjectStreamer();

[quote]Moreover, again for my knowledge, may you explain me how do I read that strange “new” syntax? I have never seen something like that… [/quote]This is a C++ syntax called ‘new with placement’, it tells the compiler to not allocate memory (and use the result of ((*mlx)[0]) instead) but to still run the constructor.

Cheers,
Philippe.

The problem is that I don’t know how to do that… I always use:

that, compiling the code, produce also the dictionary. How can I produce the dictionary?

where should I put this statement? Somewhere in the Cluster class code, or in the main code?

I have only old C++ books :slight_smile:

Hi,

[quote]How can I produce the dictionary?[/quote]Add:#ifdef __MAKECINT__ #pragma link C++ class vector<Cluster>+; #endif // __MAKECINT__to your classfile.cpp

[quote]where should I put this statement?[/quote]As one of the very first statement of your code.

Cheers,
Philippe.