CloneTree in TSelector (or CopyTree)

Hi,
I am having difficulty using the TSelector class to successfully clone the input TTree and write selected events to file. I am trying to use the TSelector method because of a recommendation I saw on past roottalk posts. I have also attempted to use CopyTree (outside of the TSelector framework) and ran into what appears to be a memory issue that appears similar to what is discussed here (root.cern.ch/root/roottalk/roottalk03/2631.html). Unfortunately, I wasn’t able to implement the suggested solutions in a successful manner.

Here is my approach then.

In my TSelector Init function, I write (fOutputFileName is a parameter that I can set… I have verified that this is set correctly). I open and recreate the file before using CloneTree as done in the numerous copytree tutorials.

   TFile gh(fOutputFileName.Data(),"RECREATE");
   newtree=fChain->CloneTree(0);
   fOutput->Add(newtree);
   gh.Close();

In the Process function, I do the following (fCuts is a parameter that I can set.:

  GetEntry(entry);
  if (fCuts) {
    newtree->Fill();
    return kTRUE;}
  else {return kFALSE;}

Finally, in the Terminate function, I do the following:

  TFile a(fOutputFileName.Data(),"Update");
  fOutput->Write();
  a.Close();

I can run this successfully, but when I go to draw any variable, I get a seg fault. This seems like a memory issue like the one encountered some years ago in the roottalk posting that I have linked to, but I don’t know how to resolve it.

Again, any suggestions that accomplish the same basic idea of cloning a tree and writing selected events to file would be very much appreciated.

Thanks,
Zach

   TFile gh(fOutputFileName.Data(),"RECREATE");
   newtree=fChain->CloneTree(0);
   fOutput->Add(newtree);
   gh.Close();

The first line is a problem :slight_smile:. The TFile must stay open for the duration of the use of the TTree. When ‘gh.Close()’ is called the tree pointed to by ‘newtree’ is deleted from memory!. So instead you can simply do:

   TFile::Open(fOutputFileName.Data(),"RECREATE");
   newtree=fChain->CloneTree(0);
   fOutput->Add(newtree);
   // In terminate;
   newtree->GetFile()->Write();
   delete newtree->GetFile(); // This close the TFile and delete the TFile and TTree object from memory.

CHeers,
Philippe.

Thanks for your response. I modified the code as you suggested, but it fails at the newtree->GetFile()->Write() line because it says there is no method GetFile() associated with the TTree object (I don’t see one in the documentation either). Do you know what is going on with this?

Thanks!

Hi Zachary,

Yes, I misspelt the routine name :slight_smile:, it is actually GetCurrentFile.

Cheers,
Philippe

Dear Philippe (or Zachary)

11 years later, I am trying to produce the same type of result.
Things have certainly changed since and it crashes. I am using ROOT 5.34/18.

  • I am surprised that the fChain is NULL is the Begin() method. How can I change that ?

  • Then the CloneTree(0) (performed in Process() then, where it is not NULL crashes.

  • Finally opening/creating a TFile in Begin() leads to failure (see my previous post “Create TFriend in TSelector”). I tried to first save gDirectory and then gDirectory->cd(). No luck.

I can provide a simple non working example (although my TTree is rather complex), but before going there maybe there is another simple procedure I am missing ? Note that I do not want to simple create a smaller tree with conditions, otherwise I can always use something like CopyTree, which BTW works very well here.

Regards
Julien

Edit : found one of the problem (fChain NULL) -> place the code in Init() (as it is explained in the posts above, my bad). The rest still does not work.

Dear Wile,

Thank you for your quick answer.

I have been using TSelectors for a while now and I must admit I did not look at what MakeProxy can do.
Presently, the problem is that I have a rather complex TSelector working and I am “just” trying to extend it (if I must I will rewrite/convert it).
This being said,in all the documentation I could read (including the tutorials and this forum) I could not find anything about cloning a “second” tree within a TSelector. But maybe I missed it. Can you point me at it ?

Regards
Julien

Hi Julien,

The skeleton created by MakeSelector puts the TTree in mode where the reading of the TTree content is decomposed in ints and floats (‘MakeClass’ mode). This mode is currently incompatible with cloning the TTree (mismatch in what the writing and reading code expect). The result of MakeProxy on the other hand is compatible with CloneTree and should be such that the change in your code should be minimal.

Cheers,
Philippe.

Dear Philippe,

Thank you for the information. I will try the MakeProxy approach.
If it works I will edit this post.

Regards
Julien