Adding array branches

Hi all,

So here is my code to add to calibrated arrays to the preexistent tree contained in the file “Runs_Pb_4He.root”.

void TreeMerger()
{
TFile *fin = new TFile("Runs_Pb_4He.root","read");
TFile *fout = new TFile("RunsCal_Pb_4He.root","recreate");
TTree *Tree_cal = new TTree("Tree_cal","Tree_cal"); 
Tree_cal=(TTree*)fin->Get("Tree");
Tree_cal->SetBranchStatus("*", 0);

/*VARIABLES AND COEFFICIENTS DEFFINITIONS
...
...
*/
//NEW BRANCHES TO ADD:
TBranch *b_Ecal_SiLi = Tree_cal->Branch("Ecal_SiLi",Ecal_SiLi,"Ecal_SiLi[2][16]/F");
Tree_cal->SetBranchStatus("Ecal_SiLi", 1);
TBranch *b_Erecal = Tree_cal->Branch("Erecal",Erecal,"Erecal[2]/F");
Tree_cal->SetBranchStatus("Erecal", 1);
TBranch *b_Ecal_DE = Tree_cal->Branch("Ecal_DE",Ecal_DE,"Ecal_DE[2][16]/F");
Tree_cal->SetBranchStatus("Ecal_DE", 1);

//PREEXISTENT VARIABLES I MAKE USE OF
Tree_cal->SetBranchAddress("E_SiLi", E_SiLi);
Tree_cal->SetBranchStatus("E_SiLi", 1);
Tree_cal->SetBranchAddress("E_DE", E_DE);
Tree_cal->SetBranchStatus("E_DE", 1);
ULong_t nentries=Tree_cal->GetEntries();

fout->cd();

for(ULong_t j=0;j<nentries;j++)
   {
   Tree_cal->GetEntry(j);
   for(int tel=0; tel<2; tel++)
      {
      if(k<paso) {k++;}
      else {k=0; i++;}
      Erecal[tel]=a[tel][i]*E_SiLi[tel]+b[tel][i];
      Ecal_SiLi[tel][0]=0;
      Ecal_SiLi[tel][15]=0;
      Ecal_DE[tel][0]=0;
      Ecal_DE[tel][15]=0;
      for(int str=1; str<15; str++)
         {
         Ecal_SiLi[tel][str]=a_sili[tel][str]*Erecal[tel]+b_sili[tel][str];
         Ecal_DE[tel][str]=a_de[tel][str]*E_DE[tel][str]+b_de[tel][str];
         if(j%100000==0) {cout << j << " " << Ecal_SiLi[tel][str] << endl;}
         }
      }
   Tree_cal->Fill();
   }
Tree_cal->Print();
Tree_cal->Write();
fout->Close();
delete fin;
delete fout;
}

I get the following error-message:

Error in TTree::Fill: Failed filling branch:Tree.Ecal_DE
Error in TTree::Fill: Failed filling branch:Tree.Ecal_SiLi

I have tried different approaches recommended in the forum but none of them seems to work. Any help is more than welcome!

Ricardo

First, this looks suspicious to me: You create a new TTree (Tree_cal), and then you re-assign the pointer to another TTree, read from the input file. Is it really what you want?
What about cloning the old tree, like in tis example:

   TFile *oldfile = TFile::Open("oldfile.root");
   TTree *oldtree = (TTree *)oldfile->Get("T");

   //Create a new file + a clone of old tree in new file
   TFile *newfile = TFile::Open("newfile.root", "RECREATE");
   TTree *newtree = oldtree->CloneTree();
   [...]

See also This topic

2 Likes

Hi,

what could also be done in this case is to use TDataFrame (https://root.cern/doc/master/classROOT_1_1Experimental_1_1TDataFrame.html). The class allows you to open a tree, modify the dataset and write on disk the new quantities.
Here you can see how:
https://root.cern/doc/master/tdf007__snapshot_8C.html

Cheers,
D

2 Likes

Hi,

thank you both for the answers, cloning the tree solved the problem. But there was a problem with the memory access once I was done with the routine. I finally figured out that the problem was with:

Tree_cal->SetBranchStatus("*", 0);
Tree_cal->SetBranchStatus(“E_SiLi”, 1);

This apparently rendered the branches illegible once the tree was modified.

Kind regards,

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