Problem to copy copy a subset of a Tree to a new Tree

Hi

I am trying to follow the root.cern.ch/root/html/tutorial … ee3.C.html example but my created root is empty- Please note that I would like also to keep the TH1 as well from the initial file (although this is not included in my current code implementation). I am attaching the .C and a small .root as input.

Any help is highly appreciated

Thanks

Alex
copytrees.C (1.11 KB)
SMS-TStauStau_52.root (1.77 MB)

Hi,

What do you mean by ‘empty’? I just ran your example and got data into the file:

[code]$ root.exe -b -l skim.root
groot [0]
Attaching file skim.root as _file0…
gFile(TFile ) 0x7ff29af7f580
root [1] gFile->ls()
TFile
* skim.root
TFile* skim.root
KEY: TTree AC1B;4 AC1B
KEY: TTree AC1B;3 AC1B
KEY: TTree AC1B;2 AC1B
root [2] AC1B->Scan("")


  • Row * Instance * errors * event_nr * event_run * event_tim * event_tim * event_lum * trigger_l * trigger_l *

  •    0 *        0 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *         0 *        11 *
    
  •    0 *        1 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *         0 *         0 *
    
  •    0 *        2 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *         0 *         0 *
    
  •    0 *        3 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *         0 *         0 *
    
  •    0 *        4 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *         0 *         0 *
    
  •    0 *        5 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *         0 *         4 *
    
  •    0 *        6 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *         0 *       128 *
    
  •    0 *        7 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *         0 *       117 *
    
  •    0 *        8 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *           *         3 *
    
  •    0 *        9 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *           *         0 *
    
  •    0 *       10 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *           *        64 *
    
  •    0 *       11 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *           *         0 *
    
  •    0 *       12 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *           *         0 *
    
  •    0 *       13 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *           *         0 *
    
  •    0 *       14 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *           *         0 *
    
  •    0 *       15 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *           *         0 *
    
  •    0 *       16 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *           *         0 *
    
  •    0 *       17 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *           *         0 *
    
  •    0 *       18 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *           *         0 *
    
  •    0 *       19 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *           *         0 *
    
  •    0 *       20 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *           *         0 *
    
  •    0 *       21 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *           *         0 *
    
  •    0 *       22 *         0 *   6894337 *         1 *         0 *   5000001 *     17297 *           *         0 *
    
  • [/code]

However, the two input trees have the same name and thus ‘differentiating’ their clone on the single output file is not easy :frowning:

So I am not sure what you are meaning to do, the ‘closest’ to your example is to give them into two different name TTree *inittreenew = inittreeold->CloneTree(0); inittreenew->SetName("AC1B_init"); TTree *maketreenew = maketreeold->CloneTree(0); maketreenew->SetName("AC1B_make");

If you are trying to concatenate the two tree, then you ought to use a TChain.

Cheers,
Philippe.

Hi

Thanks for your trial - indeed changing the name helps. By the way, is there a simple way to also directly copy recursively the TH’s1 under each directory as well ?

Regards

Alex

Hi,

you could do something like this to recreate the initial “file pathes” in the new file:

void copytrees() {
// Example of Root macro to copy a subset of a Tree to a new Tree
   
   //Get old file, old tree and set top branch address
   TFile *oldfile = new TFile("SMS-TStauStau_52.root","read");
   
   const char *makepath = "makeroottree/AC1B";
   TTree *maketreeold = (TTree*)oldfile->Get(makepath);
   const char *initpath = "initroottree/AC1B";
   TTree *inittreeold = (TTree*)oldfile->Get(initpath);
 
   Long64_t nentriesinit = inittreeold->GetEntries();
   Long64_t nentriesmake = maketreeold->GetEntries();

   inittreeold->SetBranchStatus("*",1);
   maketreeold->SetBranchStatus("*",1);
  
   //Create a new file + a clone of old tree in new file
   TFile *newfile = new TFile("skim.root","recreate");
   newfile->cd();
   
   TTree *inittreenew = inittreeold->CloneTree(0);
   TTree *maketreenew = maketreeold->CloneTree(0);  
   
   for (Long64_t i=0;i< nentriesinit; ++i) {
      inittreeold->GetEntry(i);
      inittreenew->Fill();
   }

   for (Long64_t i=0;i<nentriesmake; ++i) {
      maketreeold->GetEntry(i);
      maketreenew->Fill();
   }
   
   if(!newfile->cd(makepath)) newfile->mkdir(makepath);
   newfile->cd(makepath);
   maketreenew->Write();
   
   if(!newfile->cd(initpath)) newfile->mkdir(initpath);
   newfile->cd(initpath);
   inittreenew->Write();
   
   newfile->Close();
   delete oldfile;
   delete newfile;
}

[quote]By the way, is there a simple way to also directly copy recursively the TH’s1 under each directory as well ? [/quote]That depends how you want to handle histograms that have the same directory and name in two or more files (that you collating together). The usual choice is to merge (i.e. add) those histogram together (and to append the TTree to one another). In the usual case, you can then simply use the ‘hadd’ utility (or directly the TFileMerger).

If instead you want to keep the histogram ‘as-is’ and write them next to each, then you need to not only copy the histo but also rename them. In this case, we have no premade tools and you would have to write explicitly the traversal of the input file and the creation of the structure in the output file.

Cheers,
Philippe