Hello,
I use TChain to loop over my tree files with TChain::GetEntry(int). It runs for a while and then crashes with:
My code:
#define AMPT_cxx
#include "AMPT.h"
#include <TString.h>
#include <TRandom3.h>
#include <TSystem.h>
#include <TFile.h>
#include <TChain.h>
#include <TTree.h>
#include <TMath.h>
#include <TH1.h>
#include <TH2.h>
#include <TGraph.h>
#include <TStopwatch.h>
#include <iostream>
#include <fstream>
using namespace std;
void test()
{
ifstream in_stream;
in_stream.open("list.txt");
if(in_stream.fail()) cout << "Input file opening failed" << endl;
char inFile[800];
TChain *chain = new TChain("AMPT");
while(in_stream >> inFile)
{
chain->Add(inFile);
}
AMPT *Eve = new AMPT(chain);
Int_t nEvents = chain->GetEntries();
cout<<"# of Events :" <<nEvents<<endl;
for(int ievt = 0; ievt<nEvents; ievt++) {
chain->GetEntry(ievt);
if(ievt%10000==0) cout<< ievt << endl;
}
}
‘list.txt’ is the input tree files list.
‘AMPT.h’ is from the MakeClass() of the tree file:
//////////////////////////////////////////////////////////
// This class has been automatically generated on
// Sat Jun 1 19:53:35 2013 by ROOT version 5.30/00
// from TTree AMPT/AMPT DST Tree
// found on file: ampt_afterART.root
//////////////////////////////////////////////////////////
#ifndef AMPT_h
#define AMPT_h
#include <TROOT.h>
#include <TChain.h>
#include <TFile.h>
class AMPT {
public :
TTree *fChain; //!pointer to the analyzed TTree or TChain
Int_t fCurrent; //!current Tree number in a TChain
// Declaration of leaf types
Int_t Event_nevent;
Int_t Event_nrun;
Int_t Event_multi;
Float_t Event_impactpar;
Int_t Event_NpartP;
Int_t Event_NpartT;
Int_t Event_NELP;
Int_t Event_NINP;
Int_t Event_NELT;
Int_t Event_NINT;
Float_t Event_px_trig1;
Float_t Event_py_trig1;
Float_t Event_pz_trig1;
Float_t Event_energy_trig1;
Float_t Event_mass_trig1;
Int_t Event_id_trig1;
Float_t Event_px_trig2;
Float_t Event_py_trig2;
Float_t Event_pz_trig2;
Float_t Event_energy_trig2;
Float_t Event_mass_trig2;
Int_t Event_id_trig2;
Float_t Event_VVX;
Float_t Event_VVY;
Int_t Indx[636]; //[multi]
Int_t ID[636]; //[multi]
Float_t Px[636]; //[multi]
Float_t Py[636]; //[multi]
Float_t Pz[636]; //[multi]
Float_t Mass[636]; //[multi]
Float_t X[636]; //[multi]
Float_t Y[636]; //[multi]
Float_t Z[636]; //[multi]
Float_t Time[636]; //[multi]
// List of branches
TBranch *b_Event; //!
TBranch *b_Indx; //!
TBranch *b_ID; //!
TBranch *b_Px; //!
TBranch *b_Py; //!
TBranch *b_Pz; //!
TBranch *b_Mass; //!
TBranch *b_X; //!
TBranch *b_Y; //!
TBranch *b_Z; //!
TBranch *b_Time; //!
AMPT(TTree *tree=0);
virtual ~AMPT();
virtual Int_t Cut(Long64_t entry);
virtual Int_t GetEntry(Long64_t entry);
virtual Long64_t LoadTree(Long64_t entry);
virtual void Init(TTree *tree);
virtual void Loop();
virtual Bool_t Notify();
virtual void Show(Long64_t entry = -1);
};
#endif
#ifdef AMPT_cxx
AMPT::AMPT(TTree *tree)
{
// if parameter tree is not specified (or zero), connect the file
// used to generate this class and read the Tree.
if (tree == 0) {
TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject("ampt_afterART.root");
if (!f || !f->IsOpen()) {
f = new TFile("ampt_afterART.root");
}
f->GetObject("AMPT",tree);
}
Init(tree);
}
AMPT::~AMPT()
{
if (!fChain) return;
delete fChain->GetCurrentFile();
}
Int_t AMPT::GetEntry(Long64_t entry)
{
// Read contents of entry.
if (!fChain) return 0;
return fChain->GetEntry(entry);
}
Long64_t AMPT::LoadTree(Long64_t entry)
{
// Set the environment to read one entry
if (!fChain) return -5;
Long64_t centry = fChain->LoadTree(entry);
if (centry < 0) return centry;
if (fChain->GetTreeNumber() != fCurrent) {
fCurrent = fChain->GetTreeNumber();
Notify();
}
return centry;
}
void AMPT::Init(TTree *tree)
{
// The Init() function is called when the selector needs to initialize
// a new tree or chain. Typically here the branch addresses and branch
// pointers of the tree will be set.
// It is normally not necessary to make changes to the generated
// code, but the routine can be extended by the user if needed.
// Init() will be called many times when running on PROOF
// (once per file to be processed).
// Set branch addresses and branch pointers
if (!tree) return;
fChain = tree;
fCurrent = -1;
fChain->SetMakeClass(1);
fChain->SetBranchAddress("Event", &Event_nevent, &b_Event);
fChain->SetBranchAddress("Indx", Indx, &b_Indx);
fChain->SetBranchAddress("ID", ID, &b_ID);
fChain->SetBranchAddress("Px", Px, &b_Px);
fChain->SetBranchAddress("Py", Py, &b_Py);
fChain->SetBranchAddress("Pz", Pz, &b_Pz);
fChain->SetBranchAddress("Mass", Mass, &b_Mass);
fChain->SetBranchAddress("X", X, &b_X);
fChain->SetBranchAddress("Y", Y, &b_Y);
fChain->SetBranchAddress("Z", Z, &b_Z);
fChain->SetBranchAddress("Time", Time, &b_Time);
Notify();
}
Bool_t AMPT::Notify()
{
// The Notify() function is called when a new file is opened. This
// can be either for a new TTree in a TChain or when when a new TTree
// is started when using PROOF. It is normally not necessary to make changes
// to the generated code, but the routine can be extended by the
// user if needed. The return value is currently not used.
return kTRUE;
}
void AMPT::Show(Long64_t entry)
{
// Print contents of entry.
// If entry is not specified, print current entry
if (!fChain) return;
fChain->Show(entry);
}
Int_t AMPT::Cut(Long64_t entry)
{
// This function may be called from Loop.
// returns 1 if entry is accepted.
// returns -1 otherwise.
return 1;
}
void AMPT::Loop()
{
// In a ROOT session, you can do:
// Root > .L AMPT.C
// Root > AMPT 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;
Long64_t nentries = fChain->GetEntriesFast();
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;
}
}
#endif // #ifdef AMPT_cxx
When running a few files, it works fine. However, it can not finish all files.
If GetEntry is not called and TChain::Draw() is called directly, it works fine.
The full error message is: (The beginning numbers is the event counting.)
Valgrind gives thing:
Thank you for discussion,
ly