TTree friend with event/track structure

Hello ROOTers,

I have a TTree T1with an Event/Track structure, where every entry is a MyEvent class containing a TClonesArray of MyTrack class.

I’d like to add information (simple variables) to each track and put it in a friend TTree (TF) without having the second tree dependent on another/my own personal class. I thought I could make a TClonesArray of TObjArray holding TParameter’s, but I can’t seem to get the variables to show up through Draw, which is really what I want (to be able to use Draw and make cuts on T1 based on the corresponding variables in TF).

This is my attempt at making the friend tree, for 1 entry:

    TTree *tree2 = new TTree("HitTree","HitTree");
    TClonesArray *event = new TClonesArray("TObjArray",100);
    tree2->Branch("HitEvent",&event,512000,1);
    TParameter<int> index("Index",0);
    TParameter<int> var1("Var1",0);
    TParameter<int> var2("Var2",0);
    TObjArray *track; 

    for(int i = 0; i < 10; i++) {
        track = new TObjArray(3);
        track->SetName("Track");
        index->SetVal(i);
        var1->SetVal(i*2);
        var2->SetVal(i*3);
        track->Add(&index);
        track->Add(&var1);
        track->Add(&var2);
        new ( (*event)[event->GetLast()+1] ) TObjArray(*track);
        delete track;
    }
    tree2->Fill();
    tree2->Print();

It fills the tree, but I can’t easily access (i.e. without looping over events and tracks) those new variables I just put in.
What am I doing wrong here?

Why don’t you use a TNtuple as friend tree. See root.cern.ch/root/html/TNtuple.html. So there is no overhead from TClonesArrays, TObjArrays and TParameters.

Cheers, Fons.

Thanks for the suggestion. TNtuple would make things simple, as I only need to add in simple variables. But I thought the entries on the friend tree need to line up with the entries of the original tree?

If I use a TNTuple, I would make an entry for every Track, whereas in the original tree, T1, I have an entry for every Event (which in turn contains Tracks).

Perhaps I’m not understanding exactly how the elements of T1 are arranged, structure-wise, but can a Track-by-Track TNtuple entries line up with the Tracks in the T1 tree?

Priscilla

[quote] But I thought the entries on the friend tree need to line up with the entries of the original tree?[/quote]Indeed (however they don’t need to be in the same order is you build an index).

[quote]If I use a TNTuple, I would make an entry for every Track, whereas in the original tree, T1, I have an entry for every Event (which in turn contains Tracks)… but can a Track-by-Track TNtuple entries line up with the Tracks in the T1 tree?[/quote]You are right, it will not work.

[quote]I thought I could make a TClonesArray of TObjArray holding TParameter’s, but I can’t seem to get the variables to show up through Draw, which is really what I want (to be able to use Draw and make cuts on T1 based on the corresponding variables in TF).[/quote]TTree::Draw can not iterate through a TObjArray (because it can not assume that all the elements are of the same type.

You should be able to do what you need simply by storing one (or more) std::vector directly in the friend TTree.

Cheers,
Philippe.

VIVE L’AMOUR!

root [0] TClonesArray *event = new TClonesArray("TObjArray",100);
root [1] event
(class TClonesArray*)0x9103878
root [2] &event
Error: reference type event with no initialization  (tmpfile):1:
Error: event already declared as different type (tmpfile):1:
*** Interpreter error recovered ***

I am stupid. No?
Pepe Le Pew.

Hi Pepe,

Yes this is a known harmless limitation do root [0] TClonesArray *event = new TClonesArray("TObjArray",100); root [1] void * p = &event;

Cheers,
Philippe.

PS. This is unrelated to this topic and should probably be in its owns topic/bug report.

VIVE L’AMOUR!
Well, I’ve got curious how the “tree2->Branch(“HitEvent”,&event,512000,1);” can possibly work. :open_mouth:
Looking at the http://root.cern.ch/root/html/TTree.html I haven’t been able to explain it at all (just try to click these various “Branch” methods, the link relevant to “&event”, and the three preceding ones, are “dead”). [-X
But after I’ve taken a peek into the http://root.cern.ch/root/html/src/TTree.h.html file itself, I noticed it’s a templated method (and that explains why a “reference to a pointer to an object” works in this case. =D>
The automatic method of the HTML documentation for classes generation misbehaves (i.e. produces incorrect methods’ descriptions). [-X
I think, in the TTree HTML documentation, I like the “return Branch” method’s prototype the most (i.e. the “Branch” method which returns “return”), especially that it’s description says it is there “to avoid confusion”. :mrgreen:
A pitiful case, am I not?
Pepe Le Pew.
P.S. Just for reference … :mrgreen:

root [0] TClonesArray *event = new TClonesArray("TObjArray",100);
root [1] event
(class TClonesArray*)0x8d453c0
root [2] void * p = &event;
root [3] p
(void*)0x89b52c8
root [4] *p
Error: Illegal pointer operation (tovalue) (tmpfile):1:
(void)144397000
*** Interpreter error recovered ***

[quote]root [4] *p
Error: Illegal pointer operation (tovalue) (tmpfile):1:
[/quote]Deferencing a void pointer can not possibly work …

[quote]Looking at the root.cern.ch/root/html/TTree.html I haven’t been able …[/quote]Indeed documentation of templated member function is not ideal.

Philippe

You are right, I should have tried “(void*)(long)p”. :mrgreen: