Creating a vector and adding it as a branch to the tree

Hello everyone,

I want to create a vector which contains trackid’s and it is created using the root file "linked_tracks.root " and then I want to add this vector as a branch to the tree and the new file is named “out_linked.root”. I checked for similiar topics and then I wrote my code like this:

#define linked_cxx
#include "linked.h"
#include <TH2.h>
#include <TStyle.h>
#include <TCanvas.h>

void linked::Loop()
{
//   In a ROOT session, you can do:
//      root> .L linked.C
//      root> linked t
//      root> t.GetEntry(12); // Fill t data members with entry number 12
//      root> t.Show();       // Show values of entry 12
//      root> t.Show(16);     // Read and show values of entry 16
//      root> t.Loop();       // Loop on all entries
//

//     This is the loop skeleton where:
//    jentry is the global entry number in the chain
//    ientry is the entry number in the current Tree
//  Note that the argument to GetEntry must be:
//    jentry for TChain::GetEntry
//    ientry for TTree::GetEntry and TBranch::GetEntry
//
//       To read only selected branches, Insert statements like:
// METHOD1:
//    fChain->SetBranchStatus("*",0);  // disable all branches
//    fChain->SetBranchStatus("branchname",1);  // activate branchname
// METHOD2: replace line
//    fChain->GetEntry(jentry);       //read all branches
//by  b_branchname->GetEntry(ientry); //read only this branch
   if (fChain == 0) return;

   //new vector for incoming protons
   std::vector<int> first_pro;

   Long64_t nentries = fChain->GetEntriesFast();

   // create a new file and clone existing tree on it
   TFile out("out_linked.root","recreate");
   auto newTree =fChain->CloneTree(0);
 
   // branch for new vector
   gInterpreter->GenerateDictionary("vector<int>", "vector");
   newTree->Branch("first_pro",&first_pro);

   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) 
   {
      Long64_t ientry = LoadTree(jentry);
      if (ientry < 0) break;
      nb = fChain->GetEntry(jentry);   nbytes += nb;
      // if (Cut(ientry) < 0) continue;

      for(int i=0; i<nseg; i++ )
      {
          int pdg = s_eMCTrack[i] ;
          int plateid = s_ePID[i];
         

	   if(plateid==0 && pdg==2212)
	   {
             first_pro.push_back(trid);
	   }
      }

   newTree->Fill();
   first_pro.clear();

   }

   newTree->Write();
   out.Write();
   out.Close();
}

It worked out however the problem is while my “linked_tracks.root” file is 1.5 GB and contains 1 tree, the created “out_linked.root” file is 826.8 MB and it contains 3 trees. In a way my file is corrupted I guess but I can not figure out why. Would you help me to solve the problem?
Screenshot from 2022-10-31 19-19-23


_ROOT Version:6.24/06"


Hi @flyinpenguin ,

those are likely not 3 trees but simply 3 “cycles” of the same tree, see also ROOT files - ROOT . It’s actually normal that multiple cycles are created when writing out a large TTree – only the one with the largest number is what’s important.

About the code, you should not need to generate a dictionary for vector<int> (ROOT should already know how to write std::vectors of fundamental types). Other than that as a first glance it looks ok to me.
The difference in size could be due to a different compression algorithm being used, a different amount of branches in the input/output file, a different basket size…

You can check the contents of out_linked.root to make sure that the output tree has the correct number of entries and the correct values (you can just print a few entries and compare with the original file).

You can also run the program under a debugger to make sure that what’s happening is what you actually want to happen.

Cheers,
Enrico