MakeClass question

Dear Experts,

I have the following problem, using ROOT 4.04/02:

I have several user trees (over 100), all of them filled separately, but they are identical in the structure (I run the same code on different data samples). On some array variables (branches) I use dynamical length to save space, for example in the compiled code it is:


const Int_t JDTX_rows_max = 96;


Int_t JDTX_rows;
Int_t JDTX_trig_ch[JDTX_rows_max];


mytree->Branch(“JDTX_rows”,&JDTX_rows,“JDTX_rows/I”);
mytree->Branch(“JDTX_trig_ch”,JDTX_trig_ch,“JDTX_trig_ch[JDTX_rows]/I”);

In the ROOT, I use TChain to add them together:

root [3] TChain chain(“mytree”) //mytree is the name of tree in all files
root [4] chain.Add(“tree.r0.4.r2815.RunListClean.10dst1.c050*.root”)
(Int_t)115

And then MakeClass():

root [11] chain.MakeClass(“chaIN”)
Info in TTreePlayer::MakeClass: Files: chaIN.h and chaIN.C generated from TTree: mytree
(Int_t)0

Now, in the Loop() body (in “chaIN.C”) I want to print all values of array JDTX_trig_ch[] above 40:



if (JDTX_rows > 40)
{
printf(“number of trigger channels in this event (JDTX_rows): %i\n”, JDTX_rows);
for (int i=40; i< JDTX_rows; i++)
{
printf(“trigger channel %i, value %i\n”,i,JDTX_trig_ch[i]);
}
}

As you can see, I expect that length of JDTX_trig_ch[] array to be exactly of “JDTX_rows”, because of the branch definition above.

Now I observe the following problem when I want to work with JDTX_trig_ch[] variable:

In some cases, the length of JDTX_trig_ch[] array is not corresponding to JDTX_rows at all:

ROOT OUTPUT:


number of trigger channels in this event (JDTX_rows): 47
trigger channel 40, value 88
trigger channel 41, value 89
trigger channel 42, value 62
Error: Array index out of range JDTX_trig_ch -> [43] valid upto JDTX_trig_ch[41] FILE:chaIN.C LINE:37
trigger channel 43, value 43
*** Interpreter error recovered ***

END OF ROOT OUTPUT

Then I looked into “chaIN.h” and saw this:

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

// Declaration of leave types


Int_t JDTX_rows;
Int_t JDTX_trig_ch[42]; //[JDTX_rows]


It looks like the maximum length of JDTX_trig_ch[] is 42. But this does_not correspond to what I see if I plot the distribution of the JDTX_rows in the ROOT after all trees are in “chain”… There are some events having JDTX_rows much more than 42… After all, that is the reason to set
const Int_t JDTX_rows_max = 96 (see above)

I don’t really understand what is going on, I thought that the generated length of variable after calling MakeClass() would be the greatest of all values in all entries in the given chain… or something like that… or does it depend only on the first tree in the chain?

When I change the line in “chaIN.h” to

Int_t JDTX_trig_ch[96]; //[JDTX_rows]

everything works (at least it does not crashes), but I can’t be sure of the content of the array above the 42th position.

Could you please help me in this case? How to properly work with dynamical arrays in such case, when I chain many “identical” trees? I would greatly appreciate any help, I don’t see any solution to this problem myself :frowning:

Thank you very much,

Have a nice day all,

Tomas

[quote]I don’t really understand what is going on, I thought that the generated length of variable after calling MakeClass() would be the greatest of all values in all entries in the given chain… or something like that… or does it depend only on the first tree in the chain?
[/quote]Unfortunately MakeClass only looks in the first file of the chain. This is a known weakness of the scheme currenlty used by MakeClass (aka. modifying the value by hand is the right thing to do).

Cheers,
Philippe

Is it possible to make this clearer or mention that in the documentation?

I use Makeclass extensively with trees containing variables with variable length, and it took me quite a while and a lot of problems to discover this weakness.

Gernot

Philippe said:

[quote]Unfortunately MakeClass only looks in the first file of the chain. This is a known weakness of the scheme currenlty used by MakeClass (aka. modifying the value by hand is the right thing to do).
[/quote]
This is not true. If you use MakeClass on a TChain, the size of the arrays
is based on a complete loop on all Trees in the TChain.
The problem is that very often, users call TTree::MakeClass on one file
and use the generated code to process a TChain.

REne

OK, I run MakeClass only on one Tree, this wasn’t clear to me.

I think this is really worth a sentence in the documentation (at least it would have helped me a lot…).

Gernot

[quote=“brun”]
If you use MakeClass on a TChain, the size of the arrays
is based on a complete loop on all Trees in the TChain.
The problem is that very often, users call TTree::MakeClass on one file
and use the generated code to process a TChain.
REne[/quote]
I did the MakeClass() for the TChain, see my 1st post on the top:

root [3] TChain chain(“mytree”) //mytree is the name of tree in all files
root [4] chain.Add(“tree.r0.4.r2815.RunListClean.10dst1.c050*.root”)
(Int_t)115
root [11] chain.MakeClass(“chaIN”)

(the fact that command numbering goes from [3]->[4]->[11] means only that I Draw() something between [4] and [11], nothing else)

  • I opened 115 trees at once, but the arrays were still shorter in the “chaIN.h” than their maximum expected length.

Or I made some mistake in the process above?

Thank you for any help, I am still using the “handmade” method to correct this…

Tomas