Filling a tree from another tree

Hello,
I have two trees which have different format. I will call them tree 1 and tree 2.
I want to

  1. make a copy of the tree 1 (call it tree 3)with all the variables set to zero
  2. fill only a susbset of variables of tree 3 using some variables of tree 2
  3. save the new resulting tree 3 in a root file

Any examples/ suggestions to do it in a quick and clean manner?

Hi,

Try:TTree *tree3 = tree1->CloneTree(-1); // Copying the structure // Detach the tree3 from tree1 so the data is not copied. tree1->GetListOfClones()->Remove(tree3); tree3->ResetBranchAddress(); // Set the branch address for tree2 and tree3 for the branch we will copy tree2->SetBranchAddress("tobecopied",&variable); tree3->SetBranchAddress("tobecopied",&variable); // Copy for(Long64_t i = 0; i < tree2->GetEntriesFast(); ++i) { if ( tree2->GetEntry(i) < 0) break; tree3->Fill(); } outpufile->Write();

Cheers,
Philippe.

Hello Philippe,
thanks for the reply.
I am trying to follow your sggestion
A question

when you suggest

[quote=“pcanal”] tree2->SetBranchAddress("tobecopied",&variable); tree3->SetBranchAddress("tobecopied",&variable);
[/quote]

I assume I already loaded and defined the variables for ttree1 and consequently fro ttree 3
Are you suggesting that I should use the name of the variable already defined by tree3?

So for instance assume tree3 has a variable called jet_pt ( :smiley: ) which is a vector and is hosted in a branch whose name is “jet_pt”; I want to fill this variable with the variable of tree2 which also happes to be called jet_pt, it is a vector> float and it is hosted on a branch wth name “jet_pt”. So the name sof the variables are the same in this case.

Should I load ttree 2 (where filename is the name of the file containing ttree2)

TFile* f= (TFile*) gRoot->GetListOfFiles()->FindObject("filename")
TTree* tree2= (TTree*) gDirectory->Get("ttree2")

and then set

tree2->SetBranchAddress("jet_pt",&jet_pt);
tree3->SetBranchAddress("jet_pt",&jet_pt);

trusting that when I do

tree2->GetEntriesFast();
the variable from the branch named "jet_pt " will be loaded on the already existing jet_pt variable from tree3 ?

[quote=“pcanal”]Hi,

Try:TTree *tree3 = tree1->CloneTree(-1); // Copying the structure // Detach the tree3 from tree1 so the data is not copied. tree1->GetListOfClones()->Remove(tree3); tree3->ResetBranchAddress(); // Set the branch address for tree2 and tree3 for the branch we will copy tree2->SetBranchAddress("tobecopied",&variable); tree3->SetBranchAddress("tobecopied",&variable); // Copy for(Long64_t i = 0; i < tree2->GetEntriesFast(); ++i) { if ( tree2->GetEntry(i) < 0) break; tree3->Fill(); } outpufile->Write();

Cheers,
Philippe.[/quote]

[quote]I assume I already loaded and defined the variables for ttree1 and consequently fro ttree 3
Are you suggesting that I should use the name of the variable already defined by tree3?[/quote]Since you are not interested in the data from tree1, you probably do not need to define anything for tree1.

[quote]tree2->GetEntriesFast();
the variable from the branch named "jet_pt " will be loaded on the already existing jet_pt variable from tree3 ?
[/quote]Yes, except that the data loading is done by tree2->GetEntry(i).

Cheers,
Philippe.

Hello Philippe,
thanks for making it clearer.

I am using the line you suggest in

  TTree *tree3 = fChain->CloneTree(-1);// Copying the structure                                                                                               
  // Detach the tree3 from tree1 so the data is not copied.                                                                                                   
  fChain->GetListOfClones()->Remove(tree3);
  tree3->ResetBranchAddress();

but when I try to compile I find the following error

/nevis3/spano/data/QCDformDAtaRel152010/QCDntuples/./physics.C:40: error: no matching function for call to ‘TTree::ResetBranchAddress()’
/afs/cern.ch/sw/lcg/app/releases/ROOT/5.27.06/slc4_amd64_gcc34/root/include/TTree.h:407: note: candidates are: virtual void TTree::ResetBranchAddress(TBranch*)

am I doing something wrong?
when I look at the definition of
root.cern.ch/root/html528/TTree. … nchAddress

I see

so it should work.
Am I missing anything?

Cheers,
Francesco

Hi,

I mis-spelled this function name, it should read ResetBranchAddresses.

Sorry,
Philippe.

Hi Philippe,
thanks!
It compiles now … I will let you know if my implementation works :smiley:

Hello Philippe,
I still find a problem
I do makeClass to have some code to load tree1.
The class is called physics.C.In physics.h I have the usual structure of the MakeClass with the constructor using the Init() method to set the addresses of all the branches.
In this class I have the Loop method that is defined along your suggestion

void physics::Loop()
{
// open output file
  TFile* File = new TFile("output.root","RECREATE");
  // fChain in tree1
  TTree *tree3 = fChain->CloneTree(-1);// Copying the structure                                                                                                                        
  // Detach the tree3 from tree1 so the data is not copied.                                                                                                                            
  fChain->GetListOfClones()->Remove(tree3);
  // reset addresses
  tree3->ResetBranchAddresses();

  for(Long64_t i = 0; i < tree2->GetEntriesFast(); ++i) {
    if ( tree2->GetEntry(i) < 0) break;
    tree3->Fill();
  }
  // going to the file where one has to write it all
  File->cd();
  tree3->Write();
    //  outpufile->Write();                                                                                                                                                            
  File->Close();
}

So I open ROOT, compile physcis.C, then define an object of type physics and I see the following result:

  1. the two pointers are of different types and I need to fix this: should I define an intermediate variable? Given that I do not have many of them to copy I can do this

  2. the other that is worrying me more actually is that only the variables that correspond to vector types ( vector for instance) present the error above related to the attempt to fill the branch.
    The other non vector variables (UINt_t, Int_bool) are not mentioned…Any idea about what the problem can be?

[quote]1) the two pointers are of different types and I need to fix this: should I define an intermediate variable? Given that I do not have many of them to copy I can do this[/quote]Yes.

[quote]The other non vector variables (UINt_t, Int_bool) are not mentioned…Any idea about what the problem can be?[/quote]Are you also changing the type there?

Philippe.