Logo ROOT  
Reference Guide
TEntryListFromFile.cxx
Go to the documentation of this file.
1 // @(#)root/tree:$Id$
2 // Author: Anna Kreshuk 17/03/2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TEntryListFromFile
13 \ingroup tree
14 
15 Manages entry lists from different files, when they are not loaded
16 in memory at the same time.
17 
18 This entry list should only be used when processing a TChain (see
19 TChain::SetEntryList() function). File naming convention:
20 - by default, filename_elist.root is used, where filename is the
21  name of the chain element.
22 - xxx$xxx.root - $ sign is replaced by the name of the chain element
23 If the list name is not specified (by passing filename_elist.root/listname to
24 the TChain::SetEntryList() function, the first object of class TEntryList
25 in the file is taken.
26 It is assumed that there are as many lists, as there are chain elements,
27 and they are in the same order.
28 
29 If one of the list files can't be opened, or there is an error reading a list
30 from the file, this list is skipped and the entry loop continues on the next
31 list.
32 */
33 
34 #include "TEntryListFromFile.h"
35 #include "TObjArray.h"
36 #include "TFile.h"
37 #include "TKey.h"
38 #include "TError.h"
39 #include "TTree.h"
40 
42 
44  fListFileName(""), fListName(""), fNFiles(0), fListOffset(0), fFile(0), fFileNames(0)
45 {
46  // default constructor.
47 
48 }
49 
50 ////////////////////////////////////////////////////////////////////////////////
51 /// File naming convention:
52 /// - by default, filename_elist.root is used, where filename is the
53 /// name of the chain element
54 /// - xxx$xxx.root - $ sign is replaced by the name of the chain element
55 ///
56 /// The TObjArray of chain elements is set by the TEntryListFromFile::SetFileNames()
57 /// function.
58 ///
59 /// If the list name is not specified, the first object of class TEntryList
60 /// in the file is taken.
61 ///
62 /// nfiles is the total number of files to process
63 
64 TEntryListFromFile::TEntryListFromFile(const char *filename, const char *listname, Int_t nfiles) : TEntryList(),
65  fListFileName(filename), fListName(listname), fNFiles(nfiles), fListOffset(0), fFile(0), fFileNames(0)
66 {
67  fListOffset = new Long64_t[fNFiles+1];
68  fListOffset[0]=0;
69  for (Int_t i=1; i<fNFiles+1; i++){
71  }
73 }
74 
75 ////////////////////////////////////////////////////////////////////////////////
76 /// d-tor
77 
79 {
80  delete [] fListOffset;
81  fListOffset = 0;
82  delete fFile;
83  fFile = 0;
84 }
85 
86 ////////////////////////////////////////////////////////////////////////////////
87 /// Returns entry \#index
88 /// See also Next() for a faster alternative
89 
91 {
92  if (index<0) return -1;
93 
95  Error("GetEntry", "Index value is too large\n");
96  return -1;
97  }
98 
99  if (index==fLastIndexQueried+1)
100  return Next();
101 
102  Int_t itree =0;
103  while (!fCurrent && itree<fNFiles){
104  LoadList(itree);
105  itree++;
106  }
107  if (itree == fNFiles){
108  Error("GetEntry", "All lists are empty\n");
109  return -1;
110  }
111 
112  if (index < fListOffset[fTreeNumber]) {
113  //this entry is in one of previously opened lists
114  itree=0;
115  for (itree=0; itree<fTreeNumber; itree++){
116  if (index >= fListOffset[itree] && fListOffset[itree]!=fListOffset[itree+1])
117  break;
118  }
119  LoadList(itree);
120  }
121  else if (index >= fListOffset[fTreeNumber+1]){
122  //this entry is in one of following lists
123  itree = fTreeNumber;
124  while (itree < fNFiles){
125  itree++;
126  if (fListOffset[itree+1]==TTree::kMaxEntries){
127  //this list hasn't been loaded yet
128  LoadList(itree);
129  }
130  if (index < fListOffset[itree+1]){
131  //the entry is in this list
132  break;
133  }
134  }
135  if (fTreeNumber == fNFiles){
136  Error("GetEntry", "Entry number is too big\n");
137  return -1;
138  }
139  if (fTreeNumber!=itree)
140  LoadList(itree);
141  }
142  //now the entry is in the currently opened list
143  Long64_t localentry = index - fListOffset[fTreeNumber];
144  Long64_t retentry = fCurrent->GetEntry(localentry);
145  fLastIndexQueried = index;
146  fLastIndexReturned = retentry;
147  return retentry;
148 
149 }
150 
151 ////////////////////////////////////////////////////////////////////////////////
152 /// Return the entry corresponding to the index parameter and the
153 /// number of the tree, where this entry is
154 
156 {
157  Long64_t result = GetEntry(index);
158  treenum = fTreeNumber;
159  return result;
160 }
161 
162 ////////////////////////////////////////////////////////////////////////////////
163 /// Returns the total number of entries in the list.
164 /// If some lists have not been loaded, loads them.
165 
167 {
168  if (fN==TTree::kMaxEntries){
169  for (Int_t i=0; i<fNFiles; i++){
170  if (fListOffset[i+1]==TTree::kMaxEntries){
171  LoadList(i);
172  }
173  }
174  }
176  fLastIndexQueried = -3;
177  return fN;
178 }
179 
180 ////////////////////////////////////////////////////////////////////////////////
181 /// Returns the next entry in the list.
182 /// Faster than GetEntry()
183 
185 {
186  Int_t itree =0;
187  while (!fCurrent && itree<fNFiles){
188  LoadList(itree);
189  itree++;
190  }
191  if (itree == fNFiles){
192  Error("Next", "All lists are empty\n");
193  return -1;
194  }
195 
196  Long64_t retentry = fCurrent->Next();
197  if (retentry<0){
199  //requested entry is in the next list
200  if (fTreeNumber == fNFiles -1){
201  // Error("Next", "No more entries, last list\n");
202  return -1;
203  }
204  do{
205  //load the next non-empty list. fTreeNumber is changed by LoadList()
206  fTreeNumber++;
210  //no more lists
211  return -1;
212  }
213  retentry = fCurrent->Next();
214  } else {
215  Error("Next", "Something wrong with reading the current list, even though thefile #%d and the list exist\n", fTreeNumber);
216  return -1;
217  }
218 
219  }
220 
222  fLastIndexReturned = retentry;
223  return retentry;
224 
225 }
226 
227 ////////////////////////////////////////////////////////////////////////////////
228 /// Loads the list \#listnumber
229 /// This is the only function that can modify fCurrent and fFile data members
230 
232 {
233  //first close the current list
234  if (fCurrent){
235  if (fFile) {
236  delete fFile;
237  fFile = 0;
238  fCurrent = 0;
239  }
240  }
241 
243 
244  //find the right name
245  //get the name of the corresponding chain element (with the treenumber=listnumber)
246  TNamed *nametitle = (TNamed*)fFileNames->At(listnumber);
247  TString filename_short = nametitle->GetTitle();
248  if (filename_short.Contains(".root")){
249  filename_short.Remove(filename_short.Length()-5, 5);
250  }
251  if (!strcmp(fListFileName.Data(), "")){
252  //no name supplied, use the one of the chain file
253  filename_short.Append("_elist.root");
254  //printf("filename: %s\n", filename_short.Data());
255  fFile = TFile::Open(filename_short.Data());
256  } else {
257  TString filename = fListFileName;
258  filename.ReplaceAll("$", filename_short);
259  //printf("filename: %s\n", filename.Data());
260  fFile = TFile::Open(filename.Data());
261  }
262 
263  if (!fFile || fFile->IsZombie()){
264  if (fFile) {
265  delete fFile;
266  fFile = 0;
267  }
268  fCurrent = 0;
269  fListOffset[listnumber+1] = fListOffset[listnumber];
270  return -1;
271  }
272 
273  if (!strcmp(fListName.Data(), "")){
274  TKey *key;
275  TIter nextkey(fFile->GetListOfKeys());
276  while ((key=(TKey*)nextkey())){
277  if (strcmp("TEntryList", key->GetClassName())==0){
278  //found an object of class TEntryList
279  fCurrent = (TEntryList*)key->ReadObj();
280  }
281  }
282  } else {
284  }
285 
286  if (!fCurrent){
287  Error("LoadList", "List %s not found in the file\n", fListName.Data());
288  fCurrent = 0;
289  fListOffset[listnumber+1]=fListOffset[listnumber];
290  return -1;
291  }
292  fTreeNumber = listnumber;
297  }
298 
299  return 1;
300 }
301 
302 ////////////////////////////////////////////////////////////////////////////////
303 /// Print info about this list
304 
305 void TEntryListFromFile::Print(const Option_t* option) const
306 {
307  printf("total number of files: %d\n", fNFiles);
308  TFile *f;
309  TEntryList *el=0;
310  if (fFileNames==0) {
311  Error("Print","fFileNames was not set properly.");
312  } else {
313  for (Int_t listnumber=0; listnumber<fNFiles; listnumber++){
314  TNamed *nametitle = (TNamed*)fFileNames->At(listnumber);
315  TString filename_short = nametitle->GetTitle();
316  if (filename_short.Contains(".root")){
317  filename_short.Remove(filename_short.Length()-5, 5);
318  }
319  if (!strcmp(fListFileName.Data(), "")){
320  //no name supplied, use the one of the chain file
321  filename_short.Append("_elist.root");
322  //printf("filename: %s\n", filename_short.Data());
323  f = TFile::Open(filename_short.Data());
324  } else {
325  TString filename = fListFileName;
326  filename.ReplaceAll("$", filename_short);
327  //printf("filename: %s\n", filename.Data());
328  f = TFile::Open(filename.Data());
329  }
330  if (f && !f->IsZombie()){
331  if (!strcmp(fListName.Data(), "")){
332  TKey *key;
333  TIter nextkey(f->GetListOfKeys());
334  while ((key=(TKey*)nextkey())){
335  if (strcmp("TEntryList", key->GetClassName())==0){
336  //found an object of class TEntryList
337  el = (TEntryList*)key->ReadObj();
338  }
339  }
340  } else {
341  el = (TEntryList*)f->Get(fListName.Data());
342  }
343  if (el)
344  el->Print(option);
345  }
346  }
347  }
348 
349 }
TEntryListFromFile
Definition: TEntryListFromFile.h:40
f
#define f(i)
Definition: RSha256.hxx:122
TString::Data
const char * Data() const
Definition: TString.h:369
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TEntryListFromFile::Next
virtual Long64_t Next()
Returns the next entry in the list.
Definition: TEntryListFromFile.cxx:184
TNamed::GetTitle
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:54
Long64_t
long long Long64_t
Definition: RtypesCore.h:73
TObject::Error
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:890
TEntryList::fCurrent
TEntryList * fCurrent
! currently filled entry list
Definition: TEntryList.h:32
TEntryListFromFile::fNFiles
Int_t fNFiles
total number of files
Definition: TEntryListFromFile.h:45
TFile::Open
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3946
TEntryList::fLastIndexQueried
Long64_t fLastIndexQueried
! used to optimize GetEntry() function from a loop
Definition: TEntryList.h:44
TString::Contains
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:624
TString::Length
Ssiz_t Length() const
Definition: TString.h:410
nentries
int nentries
Definition: THbookFile.cxx:91
TObjArray::At
TObject * At(Int_t idx) const
Definition: TObjArray.h:166
TTree.h
TString
Definition: TString.h:136
TEntryListFromFile::TEntryListFromFile
TEntryListFromFile()
Definition: TEntryListFromFile.cxx:43
TFile.h
TString::ReplaceAll
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:692
TEntryListFromFile::GetEntries
virtual Long64_t GetEntries()
Returns the total number of entries in the list.
Definition: TEntryListFromFile.cxx:166
TDirectoryFile::GetListOfKeys
TList * GetListOfKeys() const override
Definition: TDirectoryFile.h:93
TDirectoryFile::Get
TObject * Get(const char *namecycle) override
Return pointer to object identified by namecycle.
Definition: TDirectoryFile.cxx:909
Option_t
const typedef char Option_t
Definition: RtypesCore.h:66
TEntryList::GetEntry
virtual Long64_t GetEntry(Int_t index)
Return the number of the entry #index of this TEntryList in the TTree or TChain See also Next().
Definition: TEntryList.cxx:657
TKey::GetClassName
virtual const char * GetClassName() const
Definition: TKey.h:76
TEntryListFromFile::fFile
TFile * fFile
currently open file fCurrent points to the currently open list
Definition: TEntryListFromFile.h:47
TString::Remove
TString & Remove(Ssiz_t pos)
Definition: TString.h:673
TNamed
Definition: TNamed.h:29
TString::Append
TString & Append(const char *cs)
Definition: TString.h:564
TEntryListFromFile::~TEntryListFromFile
virtual ~TEntryListFromFile()
d-tor
Definition: TEntryListFromFile.cxx:78
TEntryListFromFile::Print
virtual void Print(const Option_t *option="") const
Print info about this list.
Definition: TEntryListFromFile.cxx:305
TEntryListFromFile::GetEntryAndTree
virtual Long64_t GetEntryAndTree(Int_t index, Int_t &treenum)
Return the entry corresponding to the index parameter and the number of the tree, where this entry is...
Definition: TEntryListFromFile.cxx:155
TEntryListFromFile::fListFileName
TString fListFileName
from this string names of all files can be found
Definition: TEntryListFromFile.h:43
TFile
Definition: TFile.h:54
TEntryList
Definition: TEntryList.h:25
TEntryList::Next
virtual Long64_t Next()
Return the next non-zero entry index (next after fLastIndexQueried) this function is faster than GetE...
Definition: TEntryList.cxx:896
TObject::IsZombie
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition: TObject.h:134
TKey
Definition: TKey.h:28
TKey::ReadObj
virtual TObject * ReadObj()
To read a TObject* from the file.
Definition: TKey.cxx:750
TEntryListFromFile::LoadList
virtual Int_t LoadList(Int_t listnumber)
Loads the list #listnumber This is the only function that can modify fCurrent and fFile data members.
Definition: TEntryListFromFile.cxx:231
R__ASSERT
#define R__ASSERT(e)
Definition: TError.h:120
TObjArray.h
TEntryList::Print
virtual void Print(const Option_t *option="") const
Print this list.
Definition: TEntryList.cxx:999
TEntryListFromFile::fFileNames
TObjArray * fFileNames
! points to the fFiles data member of the corresponding chain
Definition: TEntryListFromFile.h:49
TEntryListFromFile.h
TIter
Definition: TCollection.h:233
TEntryList::fLastIndexReturned
Long64_t fLastIndexReturned
! used to optimize GetEntry() function from a loop
Definition: TEntryList.h:45
TKey.h
TEntryListFromFile::fListName
TString fListName
name of the list
Definition: TEntryListFromFile.h:44
TTree::kMaxEntries
static constexpr Long64_t kMaxEntries
Definition: TTree.h:225
TEntryList::fN
Long64_t fN
number of entries in the list
Definition: TEntryList.h:36
TEntryList::fTreeNumber
Int_t fTreeNumber
! the index of the tree in the chain (used when the entry list is used as input (TTree::SetEntryList(...
Definition: TEntryList.h:41
TEntryListFromFile::fListOffset
Long64_t * fListOffset
[fNFiles] numbers of entries in ind. lists
Definition: TEntryListFromFile.h:46
TEntryList::GetN
virtual Long64_t GetN() const
Definition: TEntryList.h:75
TEntryListFromFile::GetEntry
virtual Long64_t GetEntry(Int_t index)
Returns entry #index See also Next() for a faster alternative.
Definition: TEntryListFromFile.cxx:90
int
TError.h