Re: [ROOT] TTree::MakeSelector needs unique variable names

From: Rene Brun (Rene.Brun@cern.ch)
Date: Wed May 21 2003 - 14:27:38 MEST


Hi Robert,

Use a "." in case members in sub-branches have identical names.
See doc of TTree::Branch that says:

//
//      IMPORTANT NOTE about branch names
//    In case two or more master branches contain subbranches with
//    identical names, one must add a "." (dot) character at the end
//    of the master branch name. This will force the name of the 
subbranch
//    to be master.subbranch instead of simply subbranch.
//    This situation happens when the top level object (say event)
//    has two or more members referencing the same class.
//    For example, if a Tree has two branches B1 and B2 corresponding
//    to objects of the same class MyClass, one can do:
//       tree.Branch("B1.","MyClass",&b1,8000,1);
//       tree.Branch("B2.","MyClass",&b2,8000,1);
//    if MyClass has 3 members a,b,c, the two instructions above will 
generate
//    subbranches called B1.a, B1.b ,B1.c, B2.a, B2.b, B2.c


Rene Brun

On 
Tue, 
20 
May 2003, Robert Feuerbach wrote:

> 
> Hi ROOT-Team,
> 
> I'm noticing some odd/incorrect behavior out of 
> TTree::MakeSelector, where the automatically generated code 
> does not have unique names for the variables to hold the data 
> for each branch and leaf. I'm currently testing this with 
> ROOT 3.05-04, but similar results are from 3.02-07 as well. This 
> was run on a Linux RH7.3 machine.
> 
> 
> A simple test example is (do_1 and then do_2):
> 
> //------------------------------
> void do_1 ()
> {
>   gSystem.Load("libPhysics");
>   TFile *testf = new TFile("test.root","RECREATE");
>   TTree *myT = new TTree("myT","test tree");
> 
>   TVector3 *dirAp = new TVector3(0.,0.,1);
>   TVector3 *dirBp = new TVector3(0.,0.,2);
> 
>   myT->Branch("dirA","TVector3",&dirAp);
>   myT->Branch("dirB","TVector3",&dirBp);
> 
>   myT->Fill();
> 
>   dirAp->SetXYZ(1.,0.,0.);
>   dirBp->SetXYZ(2.,0.,0.);
>   myT->Fill();
>   myT->Write();
>   testf->Close();
> }
> 
> void do_2 ()
> {
>   TFile *testf = new TFile("test.root");
>   TTree *myT = (TTree*)gDirectory->Get("myT");
>   myT->Print();
>   myT->MakeSelector("my_test");
> }
> //------------------------------
> 
> The resulting TSelector class looks something like:
> 
> // part of my_test.h, created by TTree::MakeSelector
> --------------------------------------------
> class my_test : public TSelector {
>    public :
>    TTree          *fChain;   //!pointer to the analyzed TTree or 
> TChain
> //Declaration of leaves types
>    TVector3        *dirA;
>    UInt_t          fUniqueID;   // <-- NOT UNIQUE
>    UInt_t          fBits;       
>    Double_t        fX;          
>    Double_t        fY;          
>    Double_t        fZ;
>    TVector3        *dirB;
>    UInt_t          fUniqueID;
>    UInt_t          fBits;
>    Double_t        fX;
>    Double_t        fY;
>    Double_t        fZ;
> 
> //List of branches
>    TBranch        *b_TObject_fUniqueID;   //!
>    TBranch        *b_TObject_fBits;   //!
>    TBranch        *b_dirA_fX;   //!
>    TBranch        *b_dirA_fY;   //!
>    TBranch        *b_dirA_fZ;   //!
>    TBranch        *b_TObject_fUniqueID;   //!
>    TBranch        *b_TObject_fBits;   //!
>    TBranch        *b_dirB_fX;   //!
>    TBranch        *b_dirB_fY;   //!
>    TBranch        *b_dirB_fZ;   //!
> ...
> ---------------------------------------------
> 
> 
> So, this is different from what I expected. What I would expect 
> to happen is:
> 
>   BEST CASE:  The dirA and dirB branches are directly 
>      connected to TVector3 objects.
>   
>   WORKABLE:   The TBranch's are read into unique variables 
>      dirA_fX, dirA_fY, dirB_fX, etc...
> 
> 
> While I can generate the correct code for a small case like this, 
> the automatic code generation is invaluable for processing large 
> trees. Am I doing something wrong?
> 
> I think the problem is in the name generation in
> TTree::MakeClass, but the code seems to build the names for
> TBranch's and the temporary variables in many places. Perhaps 
> one should use a single 'MakeUniqueLeafName' method, and then 
> just stick a 'b_' in front for a TBranch?
> 
> Thanks for your help,
> Rob
> 
> 



This archive was generated by hypermail 2b29 : Thu Jan 01 2004 - 17:50:11 MET