Re: reading events from a TTree

Rene Brun (Rene.Brun@cern.ch)
Mon, 02 Mar 1998 09:23:28 +0100


Root supports two techniques to read a TTree:
1- you do not have access to the code containing the classes,
(in your example Event, Header, etc). You can use the function
TTree::MakeCode to generate the skeleton code for an analysis
function. This case, however, has some restrictions. If you
have pointers to objects in a class, MakeCode will generate
dummy (commented) code for the corresponding branch that it cannot
process. You are using this case in your example below.
Unfortunately, in case your class contains arrays, there is
a bug in Root version 1.03/09 that very likely explains
your problem below. This bug has been fixed in our development
version.
2- You have access to the class used to generate the TTree. This is
obviously the prefered solution because you can use the same
navigation technique in the analysis code than in the program
generating/filling the Tree. That is what you show in your
second mail. Pasha Murat has already answered your question
how to access the elements of a TClonesArray in an analysis job.

I take this opportunity to mention again a complete and more
realistic example illustrating how to create a Tree using
a variable length list of TClonesArray objects.
See URL: http://root.cern.ch/root/Atlfast.html

Rene Brun

Dirk Meier wrote:
>
> Hello,
>
> reading two events from a TTree I find the following behaviour
>
> root [0] .x anal.C // this is my analysis macro
> EventNumber : 1 // print the event counter, and now do Dump()
> fHeader.fEventNumber 256
> fHeader.fRunNumber 288
> fHeader.fDate 970723
> fHeader.fTime 133445
> fHeader.fMTime 2036085
> fHeader.fType 1
> fNentry 15
> *fData ->4046b198
> fUniqueID 0 object unique identifier
> fBits 50331648 bit field status word
>
> // now I dump a second event
>
> fHeader.fEventNumber 257
> fHeader.fRunNumber 288
> fHeader.fDate 970723
> fHeader.fTime 133445
> fHeader.fMTime 2036085
> fHeader.fType 1
> fNentry 19
> *fData ->4046b198
> fUniqueID 0 object unique identifier
> fBits 50331648 bit field status word
>
> this is fine, but as soon as I fprint() e.g. a counting variable
> in between reading both events I receive segmentation fault,
> here the macro
>
> {
> //////////////////////////////////////////////////////////
> // This file has been automatically generated
> // (Sun Mar 1 13:07:33 1998 by ROOT version 1.03/09)
> // from TTree T/RD42/DIME/July97/Preliminary
> // found on file: /online/vsrd04/user/diamond/data/DSF288_980228.root
> //////////////////////////////////////////////////////////
>
> //Reset ROOT and connect tree file
> gROOT->Reset();
> TFile *f = new
> TFile("/online/vsrd04/user/diamond/data/DSF288_980228.root");
> TTree *T = (TTree*)f->Get("T");
>
> //Declaration of leaves types
> DEvent *fEvent = 0;
> Int_t fHeader_fEventNumber;
> Int_t fHeader_fRunNumber;
> Int_t fHeader_fDate;
> Int_t fHeader_fTime;
> Int_t fHeader_fMTime;
> Int_t fHeader_fType;
> Int_t fNentry;
> Int_t fData_;
> Int_t fData_fPlaneNumber[24];
> Int_t fData_fNhits[24];
> Int_t fData_fHitNumber[24];
> // ... and so on
> UInt_t fUniqueID;
> UInt_t fBits;
>
> //Set branch addresses
> T->SetBranchAddress("fEvent",&fEvent);
> T->SetBranchAddress("fHeader.fEventNumber",&fHeader_fEventNumber);
> T->SetBranchAddress("fHeader.fRunNumber",&fHeader_fRunNumber);
> T->SetBranchAddress("fHeader.fDate",&fHeader_fDate);
> T->SetBranchAddress("fHeader.fTime",&fHeader_fTime);
> T->SetBranchAddress("fHeader.fMTime",&fHeader_fMTime);
> T->SetBranchAddress("fHeader.fType",&fHeader_fType);
> T->SetBranchAddress("fNentry",&fNentry);
> T->SetBranchAddress("fData_",&fData_);
> T->SetBranchAddress("fData.fPlaneNumber",fData_fPlaneNumber);
> T->SetBranchAddress("fData.fNhits",fData_fNhits);
> T->SetBranchAddress("fData.fHitNumber",fData_fHitNumber);
> // and so on
> T->SetBranchAddress("fData.fBits",fData_fBits);
> T->SetBranchAddress("fUniqueID",&fUniqueID);
> T->SetBranchAddress("fBits",&fBits);
>
> // This is the loop skeleton
> // To read only selected branches, Insert statements like:
> //T->SetBranchStatus("*",0);
> //T->SetBranchStatus("fHeader",1);
> //T->SetBranchStatus("fData",1);
>
> DEvent *fEvent = new DEvent(); // declare and create like
> // in Event example
>
> TClonesArray *fData = fEvent->GetData(); // like in Event::GetTracks()
>
> TBranch *branch = T->GetBranch("fEvent");
>
> branch->SetAddress(&fEvent);
>
> Int_t nentries = T->GetEntries();
>
> Int_t n = 1;
> Int_t m = 2;
>
> printf("EventNumber : %d\n",n); // accessing n still works
>
> T->GetEvent(n); // after this GetEvent(),
> // I can not access n or
> // any other variable any more
> fEvent->Dump(); // this works and Dumps as shown
>
> //printf("EventNumber : %d\n",m);// <-- this print causes seg. fault
> // also looping over events causes seg.fault
> T->GetEvent(2); // <-- also T->GetEvent(m) would cause
> // seg.fault!!!, but T->GetEvent(2)
> // works instead.
> fEvent->Dump();
>
> }
>
> At the end I need to access values in the TClonesArray* fData
> (analog to the TClonesArray* track examples in the tutorial)
>
> thank you for any help
>
> Dirk