Re: filtering a tree

From: T Auger (thauger@phns27.saclay.cea.fr)
Date: Mon Oct 05 1998 - 17:08:48 MEST


Hi Rene,
I tried your suggestion and I still run into the same problem. It
seems related to memory issue since it works when I fill the new tree
with only a few events ~10-20 but it still crashes when I try to call
Draw() after I filled it about 100 times. I did another test directly
with CloneTree (ROOT version 2.11), it gives the same result:

root [0] TFile f("/home/crash30/thierry/run12415/run12415_v1.root");
root [1] TTree *tree = (TTree*)gDirectory->Get("T");
root [2] TClasEvent *event2;
root [3] tree->SetBranchAddress("event",&event2);
root [4] TTree *tree2 = (TTree*) tree->CloneTree(100);
root [5] tree2.Draw("event.Mm_gp()")
Warning in <MakeDefCanvas>: creating a default canvas with name c1
Warning in <TBranchObject::GetBasket>: Estimated keylen too small=2468
Fatal in <operator new>: storage exhausted
aborting

if I try with only 10 events it works...
I am clueless,
Thierry.

Rene Brun writes:
 > Hi Thierry,
 > In $ROOTSYS/tutorials/copytree.C and copytree2.C, we show
 > examples how to copy a subset of a Tree to another file.
 > The first part of your macro below preceeding the statement
 >  TEventList *elist1 = ...
 > could be replaced by 
 >  TTree *tree_out = tree->CloneTree(0);
 > 
 > When specifying the argument 0 (number of events to copy),
 > CloneTree will only build the new Tree header. You can then
 > loop with your EventList to copy only the selected events.
 > I do not have the specs of your TClasEvent class.
 > It could be that you hit a patological problem that I fixed
 > in our development version in TTree::CloneTree.
 > The logic in CloneTree now looks like:
 > 
 >   // we make a full copy of this tree
 >    TTree *tree = (TTree*)Clone();
 >    if (tree == 0) return 0;
 > 
 >    tree->Reset();
 > 
 >   // copy branch addresses starting from branches
 >    Int_t i;
 >    TObjArray *branches  = GetListOfBranches();
 >    Int_t nbranches = branches->GetEntriesFast();
 >    for (i=0;i<nbranches;i++) {
 >       TBranch *branch = (TBranch*)branches->UncheckedAt(i);
 >       if (branch->GetAddress()) {
 >          tree->SetBranchAddress(branch->GetName(),branch->GetAddress());
 >       }
 >    }
 >   // copy branch addresses starting from leaves
 >    TObjArray *leaves  = GetListOfLeaves();
 >    TObjArray *tleaves = tree->GetListOfLeaves();
 >    Int_t nleaves = leaves->GetEntriesFast();
 >    for (i=0;i<nleaves;i++) {
 >       TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(i);
 >       TBranch *branch = leaf->GetBranch();
 >       if (branch->GetAddress()) {
 >          tree->SetBranchAddress(branch->GetName(),branch->GetAddress());
 >       } else {
 >          TLeaf *leaf2 = (TLeaf*)tleaves->UncheckedAt(i);
 >          leaf2->SetAddress(leaf->GetValuePointer());
 >       }
 >    }
 > 
 >   // may be copy some events
 >    if (nevents < 0) nevents = Int_t(fEntries);
 >    if (nevents > fEntries) nevents = Int_t(fEntries);
 >    for (i=0;i<nevents;i++) {
 >       GetEvent(i);
 >       tree->Fill();
 >    }
 >    return tree;
 > 
 > 
 > Let me know if this fixes your problem. If it does, then
 > I would suggest you replace the bulk of your code by CloneTree(0)
 > once the new version 2.00/12 appears.
 > 
 > Rene Brun
 > 
 > 
 > T Auger wrote:
 > > 
 > > Hi ROOTers,
 > > I am trying to copy from an existing tree only a fraction of the
 > > events into a new tree. To do this filtering, I would like to be able to use
 > > TCut as arguments like when I do a tree.Draw(); so I create an
 > > TEventList which I then use to get the events which do satisfy my
 > > criteria. I can create a tree but when I try to do a Draw() on this
 > > new tree, ROOT bumps with this message:
 > > 
 > > root [3] tree_out.Draw("event.Mm_gp()")
 > > Warning in <MakeDefCanvas>: creating a default canvas with name c1
 > > Warning in <TBranchObject::GetBasket>: Estimated keylen too small=2468
 > > Fatal in <operator new>: storage exhausted
 > > aborting
 > > 
 > > I do not understand what's happening. It is quite similar to what's being
 > > done in the CloneTree() TTree member function.
 > > here is the macro :
 > > 
 > > {
 > > gROOT->Reset();
 > > TFile f("/home/crash30/thierry/run12415/run12415_v1.root");
 > > TTree *tree = (TTree*)gDirectory->Get("T");
 > > TTree *tree_out = (TTree*) tree->Clone();
 > > TClasEvent *event;
 > >    Int_t nbytes = 0;
 > > Float_t test;
 > >    tree->SetBranchAddress("event",&event);
 > > cout<<" Nentries "<<tree->GetEntries()<<endl;
 > >    tree_out->Reset();
 > > //    tree_out->Branch("event", "TClasEvent", &event, 1000,0);
 > >   // copy branch addresses
 > >    Int_t i;
 > >    TObjArray *leaves  = tree->GetListOfLeaves();
 > >    TObjArray *tleaves = tree_out->GetListOfLeaves();
 > >    Int_t nleaves = leaves->GetEntriesFast();
 > >    for (i=0;i<nleaves;i++) {
 > >       TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(i);
 > >       TBranch *branch = leaf->GetBranch();
 > >       if (branch->GetAddress()) {
 > >          tree_out->SetBranchAddress(branch->GetName(),branch->GetAddress());
 > >       } else {
 > >          TLeaf *leaf2 = (TLeaf*)tleaves->UncheckedAt(i);
 > >          leaf2->SetAddress(leaf->GetValuePointer());
 > >       }
 > >    }
 > > 
 > > TEventList *elist1 = new TEventList("elist1","test",10000);
 > > 
 > > tree->Draw(">>elist1","event.Mm_gp()>0","",1000);
 > >    Int_t nentries = elist1->GetN();
 > >     for (Int_t i=0; i<nentries;i++) {
 > >       if(i%100 == 0) cout<<"alors"<<endl;
 > >       nbytes += tree->GetEvent(elist1->GetEntry(i));
 > >       tree_out->Fill();
 > >       event->Clear();
 > >     }
 > > }
 > > 
 > > Does anyone see how this could work (or why it doesn't work)?
 > > sincerely,
 > > Thierry.
 > 



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:34:38 MET