Unable extract correct data from Hits tree of ROOT file obtained from GATE simulation


Please read tips for efficient and successful posting and posting code

ROOT Version: 6.16
Platform: Ubuntu 18.04.3 LTS
Compiler: g++


I am new in ROOT. I want to analyse a root output file obtained from GATE (Geant4 based software). For that, I have written a C++ program (shown below). But the problem is, I am not able loop-through the Hits Tree data contained inside the root file. The main for loop inside the C++ program not even able to print the loop index ā€˜iā€™ correctly. It is showing only one large number in terminal output - 1769234804. Besides various data like posX, posY, posZ, ā€¦ etc. shows unphysical values. Interestingly, for another root file (corresponding to different GATE simulation) it is showing some different behaviour - printing ā€˜iā€™ value up to 16 only. And if I do for (Int_t i = 17 ; i < 100 ; i++), then it is showing correct iā€™s. Please excuse me if the content is very immature. :blush:

#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include "TROOT.h"
#include "TSystem.h"
#include "TChain.h"
#include "TH2D.h" 
#include "TDirectory.h"
#include "TList.h"
#include "Rtypes.h"
#include "TChainElement.h"
#include "TTree.h"
#include "TFile.h"
#include "TStyle.h"
#include "TH2.h"
#include "TH2F.h"
#include "TCanvas.h"
#include "TRandom.h"

using namespace std ;



int main(int argc, char** argv)
{

 if(argc<1) 
 {
   std::cout<<" Right number of input argument please !! "<<std::endl ;
   return 1;
 }
 
 string filedir, inputfilename ;

 filedir = argv[1] ; 
 inputfilename = filedir + "*.root" ;

 cout << "Input file name is " << inputfilename << endl;
 TChain *Hits = new TChain("Hits") ;                                             
 Hits->Add(inputfilename.c_str()) ;                                              

 FILE *Outputfile;
 Outputfile=fopen("Output.txt","wb");

 Double_t	time;
 Float_t	edep,posX,posY,posZ;
 Int_t		eventID;
 Int_t         processName;  
 Int_t         nbytes = 0;

 Hits->SetBranchStatus("*",0);                                                  
 Hits->SetBranchAddress("time",&time);                                            
 Hits->SetBranchAddress("edep",&edep);                                           
 Hits->SetBranchAddress("posX",&posX);                                           
 Hits->SetBranchAddress("posY",&posY);                                           
 Hits->SetBranchAddress("posZ",&posZ);                                           
 Hits->SetBranchAddress("eventID",&eventID);                                     
 Hits->SetBranchAddress("processName",&processName);                             

 Int_t nentries = (Int_t)(Hits->GetEntries());                                   

 printf("Total Number of Hits:= %d \n",nentries ); 
 
  //for (Int_t i = 0 ; i < nentries ; i++)
  for (Int_t i = 0 ; i < 20 ; i++)

   {      

     
     nbytes += Hits->GetEntry(i);

     printf("%d\n",i);
     //printf("%0.20f\n",time);

   }

 fclose(Outputfile);

 return(0);

}```

This request the TTree to read no data what so ever ā€¦ If you are going to use this pattern you need to call

Hits->SetBranchStatus(branchname, true);

for all the branch you do want to read.

1 Like

That is weird ā€¦ I see no reason from the code why this would be ā€¦ Maybe run the failing example with valgrind to get more information?

1 Like

Thank you pcanal for your prompt reply. :slightly_smiling_face: Found the silly mistake! :v: The error is due to trying to read a leaf data containing physics process names with char variable with not enough array index (Int_t processName is replaced by Char_t processName[40]). Now the text extracted data and root data (seen through TBrowser) are consistent. However, I am still interested about the line Hits->SetBranchStatus("*",0);. You said that I need to change it. But in the corrected code, I have kept that line as it is and the program is working fine.

Hits->SetBranchStatus("*",0); .

That lines tells TTree::GetEntry (and a few other tools) to ignore all the branche (ignore because of 0 and all because of the *). The original code snippets says:

Hits->GetEntry(...);

which should read nothing after that call unless there are calls to SetBranchStatus(..., true);

On the other hand calls to TBranch::GetEntry would still be fine.

Cheers,
Philippe.