Hi Steve, In your attempt to mimic the code of TTreePlayer::CopyTree, you put code inside the loop that should be outside. Try the bit of code below Rene Brun void OldTree::Loop() { if (fChain == 0) return; TFile oFile("newfile.root","recreate"); // Added by Steve TTree* newtree = (TTree*)fChain->GetTree()->CloneTree(0); Int_t nentries = Int_t(fChain->GetEntriesFast()); Int_t nbytes = 0, nb = 0, tnumber = -1; for (Int_t jentry=0; jentry<nentries;jentry++) { Int_t ientry = LoadTree(jentry); if (ientry < 0) break; nb = fChain->GetEntry(jentry); nbytes += nb; if (tnumber != fChain->GetTreeNumber()) { tnumber = fChain->GetTreeNumber(); fChain->CopyAddresses(newtree); } if (passAnalysis()) newtree->Fill(); } newtree->Write(); } On Mon, 12 Aug 2002, Steve Sekula wrote: > Hello, > > The general question which I am hoping to address is as follows: given > an TChain of files, chain, containing a TTree, oldtree, what is the > "correct" way to obtain a new tree, newtree, which contains a subset of > oldtree's events? > > In my current analysis, I begin with one of the TFiles in the chain, > "file.root", and generate a class based off the tree, oldtree, in that file: > > > TFile f("file.root") > > oldtree->MakeClass("OldTree"); > > Inside of OldTree.h I define a new method, passAnalysis(), which returns > a boolean. I then flesh out this method in OldTree.C, but the bottom > line is that it examines the values of branches (and functions of those > branches) in the structure of oldtree and decides whether or not to pass > the event. > > I then edit the Loop() function and add the following code, so that a > new TTree is created from the old one, based on the results of the > passAnalysis() method: > > void OldTree::Loop() > { > if (fChain == 0) return; > > TFile oFile("newfile.root","recreate"); // Added by Steve > TTree* newtree; // Added by Steve > > Int_t nentries = Int_t(fChain->GetEntriesFast()); > > Int_t nbytes = 0, nb = 0; > for (Int_t jentry=0; jentry<nentries;jentry++) { > Int_t ientry = LoadTree(jentry); //in case of a TChain, ientry is > the entry number in the current file > if (ientry < 0) break; > nb = fChain->GetEntry(jentry); nbytes += nb; > > if (jentry == 0) { // Copy the structure of the old tree, added by > Steve > newtree = (fChain->GetTree())->CloneTree(0); // added by Steve > fChain->CopyAddresses(newtree); // added by Steve > } > > Bool_t passes = passAnalysis(); > if (passes) newtree->Fill(); > } > > if (newtree) newtree->Write(); > oFile.Close() > } > > I then start ROOT and run the code on a TChain of files with _identical_ > structure to file.root: > > > .L OldTree.C; > > TChain chain("oldtree"); > > chain.Add("*.root"); > > OldTree test(&chain); > > test.Loop(); > > This then leads to the memory filling extremely rapidly on the host > machine (about 5% per second) until I achieve a wonderful segementation > violation (long before the completion of the for-loop). However, this > method of copying only a subset of interesting events in the tree has > worked in the past. > > The first thing that occurred to me was that instead of the above one > could use CopyTree and apply it with conditions supplied by TCut > objects. However, our current analysis structure is based not just on > the values of the branches in the TTree but also on complicated > functions derived from those branches which are called by > passAnalysis(); it's therefore not a simple matter of using TCut objects. > > It seems like the above procedure - CloneTree(0), copy addresses, and > Fill() - ought to work. But it seems to lead to a rapid fill of the > system memory and the inevitable crash that results from such behaviour. > We are in the process of finding a simple way to migrate to TCut > objects, but since this above procedure carried us through ROOT version > 3.03.05 (we are now using 3.03.07) it seems it ought to still work. > > So to retiterate my question: (apart from using CopyTree and TCut > objects) what is the best/correct way to make a copy of the subset of > events in one TTree into another TTree with identical structure? > > Regards, > Steve Sekula > > >
This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:51:04 MET