Hi,
I need to copy a subset of the branches of a chain of trees to a single new tree.
In the root tutorials I found a macro ( root.cern.ch/root/html/examples/copytree.C.html ) that copies a subset of a tree to a new tree. Is there a way to do the same for a chain of trees ?
I have tryed using this same macro but the new Tree seems to get corrputed .
Thanks,
Andre
PS: Bellow follows the macro that I addapted and doesn’t work !
make_subtree( TString& files_list){
// Root macro to copy a subset of a Chain of Trees to a new Tree
// The input Trees have been generated by the CMS Famos package
gROOT->Reset();
gSystem->Load(“libExRootAnalysisReader”);
// Create a chain with the list of input files
TChain chain(“Analysis”);
FillChain(chain, files_list);
// Use ExRootAnalysisReader method to access the branch
ExRootTreeReader *treeReader = new ExRootTreeReader(&chain);
TClonesArray *branchMuonGLB = treeReader->UseBranch(“MuonGLB”);
// Enable only the branches one wants to keep
chain.SetBranchAddress(“MuonGLB”, &branchMuonGLB );
chain.SetBranchStatus("*",0);
chain.SetBranchStatus(“MuonGLB”,1);
//Create a new file + a clone of old tree in new file
TFile *newfile = new TFile(“small.root”,“recreate”);
TTree *newtree = chain.CloneTree();
I think I have a similar problem – but can’t fix it. What I have is a certain class structure (the infamous ExRootAnalysis of CMS) in a Tree.
What I want to do is read an event, check/calculate something and write it to a new tree. What I do in short is:
I read the source trees into a chain and activate all branches:
In the event loop over the source tree I get every entry and calculate something with some of the branches. Based upon this I fill the clone tree.
Now the problem is: the cloned tree has the perfectly right structure, all branches and leafs in place. But some of the branches are simply not filled, that is: they have no entries.
What I don’t understand is, that there is no system to which branches are (not) filled. Say I use the branches “A” and “B” to calculate something and never use branch “C” and “D”.
When I look into the created file with the new tree, then I find that the entries in the branches “A” and “C” perfectly match what I filled in there. But unfortunately the branches “B” and “D” are empty, as in “no entries”.
As far as I checked internally is everything alright (addresses right and accessible). I truly don’t know any further.
You do not mention any SetBranchStatus with 0 as a parameter (hence all you branch status are no-op as far as I can tell). If this is the case, there are not explanation for your observation expect if you read explicitly the branches (aka branchA->GetEntry instead of theChain->GetEntry) [and in this case of the branch you read you be properly filled.
Another possibility is the way you set the addresses, you must set the address through the original chain (theChain) and you must be very carefully if setting any addresses other than the top level.
The simpliest is probably that you sent me your code.
its really not much more than the following, I snip the unimportant parts.
vector<TString> inFileList; // gets initialized with the list of filenames
TChain theChain("Analysis");
for(vector<TString>::iterator iter = inFileList.begin(); iter < inFileList.end(); iter++)
{ if(!( theChain.Add( (*iter) ) > 0) ) ; } // omitted the error message for failure
ExRootTreeReader *treeReader = new ExRootTreeReader(&theChain); // the "support" structure
theChain.SetBranchStatus("MuonGLB",1); // ...and all the other branches
// define the clone
TFile theCloneFile = new TFile("theClone.root","recreate");
TTree* theCloneTree = theChain.CloneTree(0);
// now do the loop
Long64_t allEntries = treeReader->GetEntries();
for(Long64_t currentevent = 0; currentevent < allEntries; currentevent++)
{
treeReader->ReadEntry(currentevent);
// now do something on the MuonGLB branch
// e.g. count the muons, store into
// int numberOfMuons;
// and do something similar on a jet branch
if( (numberOfMuons > 0) && (numberOfJets > 4) )
theCloneTree->Fill();
} // end event loop
The produced Tree has the perfectly right jet objects in the Jet branch, but not a single member in the “MuonGLB” branch. The same for two unmentioned (but activated) other branches.
The problem must be coming from the implementation of ExRootTreeReader and whether it issues any SetBranchStatus and what it does in ExRootTreeReader::ReadEntry.
Your code in itself seems fine except that instead of
theChain.SetBranchStatus("MuonGLB",1); // ...and all the other branches
you might be meaning:
Sorry for resurrecting this post, but i have almost the same problem.
I need to filter some of the events produced in a private sample.
The code given below is simply checks the number of jets in each event and tries to save some of them.
The branch structure and leaves are all there in the output file, I even see the size information for each branch.
The output of the root file seems like it is filled but the leaves are empty.
Here is the code i used i wonder if you could take a look?
Thank you in advance.
void testv2()
{
gROOT->Reset();
//gSystem->Load("libExRootAnalysis");
gSystem->Load("libDelphes");
TChain theChain("Delphes");
theChain.Add("tag_1_delphes_events_s.root");
// Create object of class ExRootTreeReader
ExRootTreeReader *treeReader = new ExRootTreeReader(&theChain);
Long64_t allEntries = treeReader->GetEntries();
cout << "There are " <<allEntries<< " events" <<endl;
// Get pointers to branches used in this analysis
TClonesArray *branchJet = treeReader->UseBranch("Jet");
theChain.SetBranchStatus("Jet*",1);
TFile *myfile = new TFile("filtered_events.root","recreate");
TTree* theCloneTree = theChain.CloneTree(0);
// now do the loop
for(Long64_t currentevent = 0; currentevent < 1000; currentevent++)
{
treeReader->ReadEntry(currentevent);
int counter_jet=0;
if(branchJet->GetEntries() > 0)
{
Jet *jet;
for (int i=0; i< branchJet->GetEntries(); i++)
{
jet = (Jet*) branchJet->At(i);
if (jet ->PT > 50 ) counter_jet++;
}
}
if ( counter_jet > 3 ) theCloneTree->Fill();
} // end event loop
theCloneTree->Write();
myfile->Close();
}
On first approximation this looks ‘okay’ but depend on the actual implementation of ExRootTreeReader. Most likely, for some reason, the input and output branches are not looking at the same addresses.