Problem reading just a branch from a TTree

Dear ROOTers,

to debug a problem I have in a more complex code I arrived to the :

example. Now I have a very “light” version that is even only reading the input tree:

[code]void copytree_mio() {

gSystem->Load("$ROOTSYS/test/libEvent");

TFile *oldfile = new TFile("$ROOTSYS/test/Event.root");
TTree oldtree = (TTree)oldfile->Get(“T”);

Int_t Nvertex;
oldtree->SetBranchAddress(“fNvertex”, &Nvertex);

for (int ii=0; iiGetEntries(); ii++) {
oldtree->GetEntry(ii);
printf("%d\n", Nvertex);
}

delete oldfile;
}[/code]

if I run this code (even loading the libEvent.so before and then compiling the macro

and then launching the main function) I read always 0. Where’s the error in this very simple code?

Thanks,
Matteo

[EDIT] Just check Pepes answer

TTree *oldtree; oldfile->GetObject("T", oldtree); oldtree->SetMakeClass(1); oldtree->SetBranchStatus("*", 0); oldtree->SetBranchStatus("fNvertex", 1);

I created it with

as suggested in copytree.C, without any change at all in the Event class or in the Event main. Is 37 MB, I cannot attach…

Using Scan:

[code]root [3] T->Scan(“fNvertex”)


  • Row * fNvertex *

  •    0 *        19 *
    
  •    1 *        16 *
    
  •    2 *        18 *
    
  •    3 *         9 *
    
  •    4 *        15 *
    
  •    5 *        10 *
    
  •    6 *        20 *
    
  •    7 *        11 *
    
  •    8 *         2 *
    
  •    9 *        19 *
    
  •   10 *        20 *
    
  •   11 *        18 *
    
  •   12 *        19 *
    
  •   13 *         6 *
    
  •   14 *         7 *
    
  •   15 *        14 *
    
  •   16 *        18 *
    
  •   17 *         4 *
    
  •   18 *         4 *
    
  •   19 *        13 *
    
  •   20 *        19 *
    
  •   21 *        18 *
    
  •   22 *         7 *
    
  •   23 *        19 *
    
  •   24 *        18 *[/code]
    

and also reading the Tree setting the branch address to the Event and then accessing everything via the Event. The problem is that I do not understand why is not working if I try to access just the sub-branches…

Thanks,
Matteo

Ciao,

I saw the Pepe answer now. I’m going to try, but then I’ll come back to ask why!

Thanks,
Matteo

Ok… I working.

If I run in CINT I have, anyhow:

[code]Processing copytree_mio.C…
Warning in TStreamerInfo::BuildCheck:
The StreamerInfo of class Event read from file /Volumes/CaseSensitive/amssw/duranti/root_git_v5.34.34_patched_clang/test/Event.root
has the same version (=1) as the active class but a different checksum.
You should update the version to ClassDef(Event,2).
Do not try to write objects with the current class definition,
the files will not be readable.

Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
char fType; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
char* fEventName; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
int fNtrack; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
int fNseg; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
int fNvertex; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
unsigned int fFlag; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
double fTemperature; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
int fMeasures; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
double fMatrix; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
double* fClosestDistance; //fNvertex
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
EventHeader fEvtHdr; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
TClonesArray* fTracks; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
TRefArray* fHighPt; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
TRefArray* fMuons; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
TRef fLastTrack; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
TRef fWebHistogram; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
TH1F* fH; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
TBits fTriggerBits; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘Event’ is missing from
the on-file layout version 1:
bool fIsValid; //
Warning in TStreamerInfo::BuildCheck:
The StreamerInfo of class EventHeader read from file /Volumes/CaseSensitive/amssw/duranti/root_git_v5.34.34_patched_clang/test/Event.root
has the same version (=1) as the active class but a different checksum.
You should update the version to ClassDef(EventHeader,2).
Do not try to write objects with the current class definition,
the files will not be readable.

Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘EventHeader’ is missing from
the on-file layout version 1:
int fEvtNum; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘EventHeader’ is missing from
the on-file layout version 1:
int fRun; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 1 of class ‘EventHeader’ is missing from
the on-file layout version 1:
int fDate; //
Warning in TStreamerInfo::BuildCheck:
The StreamerInfo of class Track read from file /Volumes/CaseSensitive/amssw/duranti/root_git_v5.34.34_patched_clang/test/Event.root
has the same version (=2) as the active class but a different checksum.
You should update the version to ClassDef(Track,3).
Do not try to write objects with the current class definition,
the files will not be readable.

Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
float fPx; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
float fPy; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
float fPz; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
float fRandom; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
float fMass2; //0,0,8
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
float fBx; //0,0,10
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
float fBy; //0,0,10
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
float fMeanCharge; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
float fXfirst; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
float fXlast; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
float fYfirst; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
float fYlast; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
float fZfirst; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
float fZlast; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
double fCharge; //-1,1,2
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
double fVertex; //-30,30,16
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
int fNpoint; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
short fValid; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
int fNsp; //
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
double* fPointValue; //fNsp
Warning in TStreamerInfo::CompareContent: The following data member of
the in-memory layout version 2 of class ‘Track’ is missing from
the on-file layout version 2:
TBits fTriggerBits; //[/code]

but then the values seem correct. If I compile with ACliC and then run the function, the warnings disappear.

Thanks.

Ok, now can you explain why please?

Matteo

Ciao,

and my original test was in order to “skim” the file removing some events and also some branches (that is a ‘variation’ of the original copytree example). Here’s my code:

#include <unistd.h>
#include <TFile.h>
#include <TTree.h>
#include <TSystem.h>
#include <../../test/Event.h>

void copytree_mio() {
  
  // Example of Root macro to copy a subset of a Tree to a new Tree
  // The input file has been generated by the program in $ROOTSYS/test/Event
  // with   Event 1000 1 1 1
  //Author: Rene Brun
  
  gSystem->Load("$ROOTSYS/test/libEvent");
  
  //Get old file, old tree and set top branch address
  TFile *oldfile = new TFile("$ROOTSYS/test/Event.root");
  TTree *oldtree = (TTree*)oldfile->Get("T");
  
  //   oldtree->GetEntry(0);
  printf("Entries=%d\n", (int)oldtree->GetEntries());

  printf("GetMakeClass = %d\n", oldtree->GetMakeClass());
  oldtree->SetMakeClass(1);
  oldtree->SetBranchStatus("*", 0);
  // oldtree->SetBranchStatus("event",1);
  oldtree->SetBranchStatus("fNtrack",1);
  oldtree->SetBranchStatus("fNseg",1);
  // oldtree->SetBranchStatus("fNvertex", 1);
  
  //Create a new file + a clone of old tree in new file
  TFile *newfile = new TFile("small.root","recreate");
  TTree *newtree = oldtree->CloneTree(0);
  
  //  oldtree->SetBranchStatus("event",1);
  oldtree->SetBranchStatus("fNvertex", 1);

  Int_t Nvertex;
  oldtree->SetBranchAddress("fNvertex", &Nvertex);
  TBranch* brfNvertex = oldtree->GetBranch("fNvertex");
  printf("%p\n", brfNvertex);

  Int_t Ntrack;
  oldtree->SetBranchAddress("fNtrack", &Ntrack);
  TBranch* brfNtrack = oldtree->GetBranch("fNtrack");
  printf("%p\n", brfNtrack);
  
  Int_t Nseg;
  oldtree->SetBranchAddress("fNseg", &Nseg);
  TBranch* brfNseg = oldtree->GetBranch("fNseg");
  printf("%p\n", brfNseg);
  
  // Event *event   = new Event();
  // oldtree->SetBranchAddress("event",&event);
  
  for (int ii=0; ii<oldtree->GetEntries(); ii++) {
    //    oldtree->GetEntry(ii);
    brfNvertex->GetEntry(ii);
    brfNtrack->GetEntry(ii);
    brfNseg->GetEntry(ii);
    //     if (event->GetNvertex()>12) {
    //    printf("%d %d\n", Nvertex, event->GetNvertex());
    printf("%d\n", Nvertex);
    printf("%d %d\n", Ntrack, Nseg);
    if (Nvertex>12) {
      newtree->Fill();
    }
  }
  
  newtree->Print();
  newfile->Write("Overwrite");
  delete oldfile;
  delete newfile;
}

I spent some time to find a combinations (and an order) of istructions to make the stuff working… Now I read the correct things and I stream on file the desired ones correctly:

...
10
604 6033
19
595 5933
******************************************************************************
*Tree    :T         : An example of a ROOT tree                              *
*Entries :      395 : Total =            9280 bytes  File  Size =          0 *
*        :          : Tree compression factor =   1.00                       *
******************************************************************************
*Branch  :event                                                              *
*Entries :      395 : BranchElement (see below)                              *
*............................................................................*
*Br    0 :fNtrack   : Int_t                                                  *
*Entries :      395 : Total  Size=       2224 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      51200 bytes  Compression=   1.00     *
*............................................................................*
*Br    1 :fNseg     : Int_t                                                  *
*Entries :      395 : Total  Size=       2212 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      51200 bytes  Compression=   1.00     *
*............................................................................*
*Br    2 :TRefTable : List of branch numbers with referenced objects         *
*Entries :      395 : Total  Size=       5102 bytes  One basket in memory    *
*Baskets :        0 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*

and than if I read small.root:

root [1] gSystem->Load("$ROOTSYS/test/libEvent");
root [2] T->Scan("fNtrack")
************************
*    Row   *   fNtrack *
************************
*        0 *       600 *
*        1 *       589 *
*        2 *       597 *
*        3 *       602 *
*        4 *       603 *
*        5 *       608 *
*        6 *       604 *
*        7 *       596 *
*        8 *       605 *
*        9 *       602 *
*       10 *       598 *
*       11 *       612 *
*       12 *       598 *
*       13 *       601 *
*       14 *       605 *
*       15 *       589 *
*       16 *       593 *
*       17 *       600 *
*       18 *       609 *
*       19 *       591 *
*       20 *       599 *
*       21 *       603 *
*       22 *       591 *
*       23 *       599 *
*       24 *       596 *
Type <CR> to continue or q to quit ==> q
************************
(Long64_t)25

(different ordering of the various SetBranchAddress, CloneTree, etc… were giving a wrong reading from the input file and/or a wring streaming on the output one.

If I uncomment:

Event *event   = new Event();
oldtree->SetBranchAddress("event",&event);

I read just rubbish (uninitialized values) or at least this is what I print, but, really puzzling me, I stream on the small.root output file the right things! Really I’m unable to understand…

Can you help me in understand a little bit?

Thanks,
Matteo

The “MakeClass” mode is not compatible with TTree cloning (you can try to use TTree::MakeProxy): How are multiple TTree->Draw()s done?
See also: Difficulties with cloning only some branches of a TTree

Dear Pepe,

ok, but I put MakeClass because you gave me it as a secret potion… But my original final goal was to Clone the Tree…

Now I found another secret recipe that is working:

#include <unistd.h>
#include <TFile.h>
#include <TTree.h>
#include <TSystem.h>
#include <../../test/Event.h>

void copytree_mio() {
  
  // Example of Root macro to copy a subset of a Tree to a new Tree
  // The input file has been generated by the program in $ROOTSYS/test/Event
  // with   Event 1000 1 1 1
  //Author: Rene Brun
  
  gSystem->Load("$ROOTSYS/test/libEvent");
  
  //Get old file, old tree and set top branch address
  TFile *oldfile = new TFile("$ROOTSYS/test/Event.root");
  TTree *oldtree = (TTree*)oldfile->Get("T");
  
  //   oldtree->GetEntry(0);
  printf("Entries=%d\n", (int)oldtree->GetEntries());

  printf("GetMakeClass = %d\n", oldtree->GetMakeClass());
  oldtree->SetBranchStatus("*", 0);
  // oldtree->SetBranchStatus("event",1);
  oldtree->SetBranchStatus("fNtrack",1);
  oldtree->SetBranchStatus("fNseg",1);
  // oldtree->SetBranchStatus("fNvertex", 1);
  
  //Create a new file + a clone of old tree in new file
  TFile *newfile = new TFile("small.root","recreate");
  TTree *newtree = oldtree->CloneTree(0);

  oldtree->SetMakeClass(1);
  newtree->SetMakeClass(1);
  
  //  oldtree->SetBranchStatus("event*",1);
  oldtree->SetBranchStatus("fNvertex", 1);

  Int_t Nvertex;
  oldtree->SetBranchAddress("fNvertex", &Nvertex);
  TBranch* brfNvertex = oldtree->GetBranch("fNvertex");
  printf("%p\n", brfNvertex);

  Int_t Ntrack;
  oldtree->SetBranchAddress("fNtrack", &Ntrack);
  TBranch* brfNtrack = oldtree->GetBranch("fNtrack");
  printf("%p\n", brfNtrack);
  
  Int_t Nseg;
  oldtree->SetBranchAddress("fNseg", &Nseg);
  TBranch* brfNseg = oldtree->GetBranch("fNseg");
  printf("%p\n", brfNseg);
  
  // Event *event   = new Event();
  // oldtree->SetBranchAddress("event",&event);
  
  for (int ii=0; ii<oldtree->GetEntries(); ii++) {
    oldtree->GetEntry(ii);
    // brfNvertex->GetEntry(ii);
    // brfNtrack->GetEntry(ii);
    // brfNseg->GetEntry(ii);
    //     if (event->GetNvertex()>12) {
    //    printf("%d %d\n", Nvertex, event->GetNvertex());
    printf("%d\n", Nvertex);
    printf("%d %d\n", Ntrack, Nseg);
     if (Nvertex>12) {
       newtree->Fill();
     }
  }
  
  newtree->Print();
  newfile->Write("Overwrite");
  delete oldfile;
  delete newfile;
}

that moves the SetMakeClass after the Clone (since you said is not compatible). For a reason that I do not fully understand I have to call, anyhow, the SetMakeClass also for the cloned tree.

If I uncomment:

  oldtree->SetBranchStatus("event*",1);
  Event *event   = new Event();
  oldtree->SetBranchAddress("event",&event);

I read (or at least I print) wrong numbers and the small.root seems to have the numbers of the fNvertex branch (read for the selection but in principle not to be written), both for fNtrack and fNseg…

Matteo

P.S.: The first version of code I posted was not correct (was using CloneTree() and not the newtree->Fill()). Now I changed to right one and checked again the behaviour (that in fact is different, so I changed the post accordingly)

[quote]that moves the SetMakeClass after the Clone (since you said is not compatible)[/quote]When the input TTree is put in SetMakeClass mode unfortunately the output TTree can no longer properly be used as the input data (of the branch set in makeClass mode). So you can not use MakeClass at all …

At least in this simple case, you have a straightforward alternative:[code] TFile *newfile = new TFile(“small.root”,“recreate”);

TTree *newtree = oldtree->CopyTree(“fNvertex > 12”);
newtree->Print();
newfile->Write(“Overwrite”);
delete oldfile;
delete newfile;
[/code]

Cheers,
Philippe.

I understand… But this is working just for this “simple” selection and is “effective” if I just need to stream out a single skimmed tree. If I want to do in a more general framework, this is not practical…

I understand that this ‘MakeClass’ is creating all these problems but I want to re-clarify that this was suggested as “magical” (and still I don’t understand why…) to solve another problem. If I can remove it for me is even clearer…

Thanks,
Matteo

Hi Matteo,

Sorry for the late answer.

MakeClass allows to access individual data member of the object contained in the TTree without having to create (or be able to created) the object itself.

One good alternative in v6 is to use a TTreeReader accessor instead.

Cheers,
Philippe.