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