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