TTreeReader with cloneTree

I need to clone a tree with some cut and add some selection

I use TTreeReader

TChain *chain = new TChain("result");
chain->Add("./data/*.root");
TTreeReader reader(chain);
TTreeReaderArray<double> r1(reader, "r1");
TTreeReaderArray<double> r2(reader, "r2");
......
TFile * resultfile = new TFile("RESULT.root", "recreate");
TTree *newtree = chain->CloneTree(0);

while(reader.Next()){
  *r1;             // how to delete this line??
  *r2;
  .......
   newtree->Fill();
}

before is OK!

if I delete the
*r1;
*r2;
two line;
the branch in newtree is fill with 0, (default value);
it seems the value is not read in memory?
is there a easy way to read all value in one line code?

Hi,
the underlying problem is that you are mixing usage of TTreeReader and TTree/TChain.
TTreeReader assumes that everything you are doing with the data you do through its TTreeReaderValue/Arrays, but you are doing a clone on the same TChain that TTreeReader is reading, in the same event loop.

What is happening is that TTreeReader is trying to help your code run faster by only loading r1 and r2 in memory if absolutely necessary. The only way it can judge whether it is necessary, is to check whether r1 or r2 are used anywhere, that’s why when you do *r1 it “fixes” your problem.

I’m not 100% sure but you might be able to substitute *r1, *r2 etc. with a call to chain->GetEntry(reader.GetCurrentEntry()), which should load all active branches in the TChain.

If you have access to ROOT v6.14, though, this kind of application is exactly why we introduced RDataFrame:

ROOT::RDataFrame df("result", "./data/*.root");
df.Filter("x > 0") // some cut expression -- you can also pass a C++ function
  .Snapshot("result", "RESULT.root"); // write to file all events that pass the filter

Those three lines do a cut and clone, you don’t need anything else.

Hope this clarifies things a bit!
Cheers,
Enrico

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.

Yes. You need to request the loading of (all) the branches:

   chain->GetEntry( reader.GetCurrentEntry() ); // Would be more complicated if a TEntryList is attached to the reader.

Cheers,
Philippe.