Dear Root-Users,
I am currently working with GATE for a Project and therefore with ROOT 6.14/06. My OS is Ubuntu 16.04LTS.
I have a problem using the TChain and I think I probably use it wrong and was hoping that maybe some of you guys could shed some light on that.
I want to read-in multiple files, do some calculations with some the data (keep the rest) and than write it into a new .root-file. And it works fine for one file. But when I use two files the TChain->GetEntry() function gets really slow.
I thinned out the code a little bit because I know where the Problem lies. I compile with:
g++ -std=c++1y Name.cpp NameofClass.cpp -o NameOut root-config --cflags --glibs
-Wall
It compiles fine, no warnings or anything.
// Type aliases to make accessing nested type easier using clock_t = std::chrono::high_resolution_clock; using second_t = std::chrono::duration<double, std::ratio<1> >; std::chrono::time_point<clock_t> m_beg; std::chrono::time_point<clock_t> m_temptime;
// I want to get the Events of the “Singles” TTree in all the files
TChain* InputTree = new TChain(“Singles”);// Adding multiple files to TChain, m_infilenames is a vector
for(unsigned int f=0; f<m_infilenames.size(); f++)
{
InputTree->Add(m_infilenames[f].c_str());
InputTree->LoadTree(f);if (InputTree->LoadTree(f) < 0) { cout << "Could not read file: " << m_infilenames[f] << "\nAbort" << endl; exit(1); } } // Open Outputfile TFile *newfile = new TFile(m_outfile.c_str(), "recreate"); // // check if both TFiles are open if (!newfile->IsOpen()) { cout << "Could not read file " << m_outfile << "\n"; exit(1); }
InputTree->SetBranchAddress(“time”, &m_Stime);
InputTree->SetBranchAddress(“layerName”, &m_Slayername);TObjArray *fileElements= InputTree->GetListOfFiles(); // TIter next(fileElements); TChainElement *chEl=0; // TObjArray *mylist = (TObjArray*)InputTree->GetListOfBranches(); // Set some variables needed for the Loop m_TotalEntries = InputTree->GetEntries(); // All entries int NumOfFiles = fileElements->GetEntries(); // Get Number of file in TChain Long64_t DynIdxBegin = 0; // Index where new File begins Long64_t DynIdxEnd = 0; // Index where new File ends Long64_t EntriesCurrentFile = 0; // contains entries of current file // Resize all vectors according to files m_TimeContainer.resize(m_TotalEntries); m_TimeSorted.resize(m_TotalEntries); m_LayerChar.resize(m_TotalEntries); m_beg = clock_t::now(); // loop over files via chEL for (int FileIndex=0; FileIndex<NumOfFiles; FileIndex++) { // make chEL point to current file chEl = (TChainElement*)fileElements->At(FileIndex); // Get the amount of entries of current File EntriesCurrentFile = chEl->GetEntries(); DynIdxBegin = DynIdxEnd; DynIdxEnd = DynIdxBegin + EntriesCurrentFile; for(Long64_t i=DynIdxBegin; i<DynIdxEnd; i++) { InputTree->GetEntry(i); [...] Do some calculations and file the } m_beg = clock_t::now(); vector<Long64_t> idx = sort_indexes(m_TimeContainer); for (Long64_t i=0; i<m_TotalEntries; i++) { [...] Fill the m_TimeSorted vector } m_beg = clock_t::now(); for(Long64_t i=0; i<NewIndex; i++) { m_temptime = clock_t::now(); // HERE IS THE PROBLEM InputTree->GetEntry(m_TimeSorted[i].Index); cout << "i: " << i << "\tTemp: " << std::chrono::duration_cast<second_t>(clock_t::now() - m_temptime).count() << endl; m_CoincID = m_TimeSorted[i].Id; // Save Time in new root file in seconds m_Stime = m_TimeSorted[i].Time; m_NewCoincidences->Fill(); cout << "i: " << i << "\tTime: " << std::chrono::duration_cast<second_t>(clock_t::now() -m_beg).count() << endl; } m_beg = clock_t::now(); m_NewCoincidences->Write(); newfile->Close();
The output if I use two files is:
i: 0 Temp: 1.4478942770
i: 0 Time: 1.4481196320
i: 1 Temp: 2.9032056620
i: 1 Time: 4.3513756090
i: 2 Temp: 2.9014497060
i: 2 Time: 7.2528713680
i: 3 Temp: 0.0002660290
i: 3 Time: 7.2531582510
i: 4 Temp: 0.0000029560
i: 4 Time: 7.2531717200
[…]
When I only use one file, the programm takes about 0.16 Seconds. When I use two files (I use the same file twice but renamed it) it takes around 7 Seconds until it reaches the value of 2. The “Temp” values displays how long it takes for the InputTree()->GetEntry(i) statement.
What am I doing wrong?
Greetings
Andi