I am trying to use MakeSelector to reduce the size of a root file by applying several cuts to the tree variables and save the reduced tree. I found several old posts about it so I followed them easily except that the result I obtained is quite unexpected. Let’s say my original root tree has three variables inside x,y, and z.
In MySelector::Init I define the new file and I clone the original tree
newfile = new TFile("test_selector.root","RECREATE");
newtree = tree->CloneTree(0);
In MySelector::Process I apply the selection criteria and I fill the new reduced tree
if (*x < 0) return kFALSE;
And, finally, in MySelector::Terminate I write the tree and delete the objects
Now, if I launch TBrowser and look at the variables, the number of entries is correct but for the new tree only the variable x has been filled. The other two are empty.
If I add a simple printout statement to the Process:
If (*x < 0) return kFALSE;
std::cout << *x << " " << *y << " " << *z << std::endl;
the tree is filled correctly for all the three variables. What am I missing? I feel it’s something trivial that I don’t see.
Thanks a lot
Could you post the full selector?
Which version of ROOT are you using?
I’m using ROOT 6.06.02. I attached the source files and a small data file to reproduce the problem.
Thanks a lot
MySel.tar (60 KB)
The reason is that, via the TTreeReader, the variables are only read when used.
I also suspect that the fact it works is some how by chance: TTreeReader is really done for reading trees.
In your case you are writing a new tree and you should as you were creating a new TTree, i.e. you should define the connection between the branches and the variables from where to get the values when filling.
Something like (to be tried):
- Add members for the variables in the class definition (MySelector.h)
a. Define fChain
fChain = tree;
b. Connect to the branches
// Entry values are read in ftxX, ftxY, ftxZ
// Entry values read in ftxX, ftxY, ftxZ are transferred to the new tree
- In MySelector::Process
if (*vtxZ < 0) return kFALSE;
GetEntry(entry); // Read the full entry from original tree
newtree->Fill(); // Write the full entry to target tree
Thanks for your reply and for the explanation. I can actually do the same job with MakeClass without much efforts and with the results I want. I was looking at MakeSelector as an alternative solution that I remember using when I was a student long time ago
Thanks a lot again
You should also be able to use MakeSelector if you request the ‘legacy’ version ( mytree->MakeSelector(selectorname, "=legacy); )