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