ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 "TBuffer.h"
34 #include "TObjArray.h"
35 #include "TFile.h"
36 #include "TKey.h"
37 #include "TError.h"
38 #include "TTree.h"
39 
41 
43  fListFileName(""), fListName(""), fNFiles(0), fListOffset(0), fFile(0), fFileNames(0)
44 {
45  // default constructor.
46 
47 }
48 
49 ////////////////////////////////////////////////////////////////////////////////
50 /// File naming convention:
51 /// - by default, filename_elist.root is used, where filename is the
52 /// name of the chain element
53 /// - xxx$xxx.root - $ sign is replaced by the name of the chain element
54 ///
55 /// The TObjArray of chain elements is set by the TEntryListFromFile::SetFileNames()
56 /// function.
57 ///
58 /// If the list name is not specified, the first object of class TEntryList
59 /// in the file is taken.
60 ///
61 /// nfiles is the total number of files to process
62 
63 TEntryListFromFile::TEntryListFromFile(const char *filename, const char *listname, Int_t nfiles) : TEntryList(),
64  fListFileName(filename), fListName(listname), fNFiles(nfiles), fListOffset(0), fFile(0), fFileNames(0)
65 {
66  fListOffset = new Long64_t[fNFiles+1];
67  fListOffset[0]=0;
68  for (Int_t i=1; i<fNFiles+1; i++){
70  }
72 }
73 
74 ////////////////////////////////////////////////////////////////////////////////
75 /// d-tor
76 
78 {
79  delete [] fListOffset;
80  fListOffset = 0;
81  delete fFile;
82  fFile = 0;
83 }
84 
85 ////////////////////////////////////////////////////////////////////////////////
86 /// Returns entry #index
87 /// See also Next() for a faster alternative
88 
90 {
91  if (index<0) return -1;
92 
94  Error("GetEntry", "Index value is too large\n");
95  return -1;
96  }
97 
98  if (index==fLastIndexQueried+1)
99  return Next();
100 
101  Int_t itree =0;
102  while (!fCurrent && itree<fNFiles){
103  LoadList(itree);
104  itree++;
105  }
106  if (itree == fNFiles){
107  Error("GetEntry", "All lists are empty\n");
108  return -1;
109  }
110 
111  if (index < fListOffset[fTreeNumber]) {
112  //this entry is in one of previously opened lists
113  itree=0;
114  for (itree=0; itree<fTreeNumber; itree++){
115  if (index >= fListOffset[itree] && fListOffset[itree]!=fListOffset[itree+1])
116  break;
117  }
118  LoadList(itree);
119  }
120  else if (index >= fListOffset[fTreeNumber+1]){
121  //this entry is in one of following lists
122  itree = fTreeNumber;
123  while (itree < fNFiles){
124  itree++;
125  if (fListOffset[itree+1]==TTree::kMaxEntries){
126  //this list hasn't been loaded yet
127  LoadList(itree);
128  }
129  if (index < fListOffset[itree+1]){
130  //the entry is in this list
131  break;
132  }
133  }
134  if (fTreeNumber == fNFiles){
135  Error("GetEntry", "Entry number is too big\n");
136  return -1;
137  }
138  if (fTreeNumber!=itree)
139  LoadList(itree);
140  }
141  //now the entry is in the currently opened list
142  Long64_t localentry = index - fListOffset[fTreeNumber];
143  Long64_t retentry = fCurrent->GetEntry(localentry);
144  fLastIndexQueried = index;
145  fLastIndexReturned = retentry;
146  return retentry;
147 
148 }
149 
150 ////////////////////////////////////////////////////////////////////////////////
151 /// Return the entry corresponding to the index parameter and the
152 /// number of the tree, where this entry is
153 
155 {
156  Long64_t result = GetEntry(index);
157  treenum = fTreeNumber;
158  return result;
159 }
160 
161 ////////////////////////////////////////////////////////////////////////////////
162 /// Returns the total number of entries in the list.
163 /// If some lists have not been loaded, loads them.
164 
166 {
167  if (fN==TTree::kMaxEntries){
168  for (Int_t i=0; i<fNFiles; i++){
169  if (fListOffset[i+1]==TTree::kMaxEntries){
170  LoadList(i);
171  }
172  }
173  }
175  fLastIndexQueried = -3;
176  return fN;
177 }
178 
179 ////////////////////////////////////////////////////////////////////////////////
180 /// Returns the next entry in the list.
181 /// Faster than GetEntry()
182 
184 {
185  Int_t itree =0;
186  while (!fCurrent && itree<fNFiles){
187  LoadList(itree);
188  itree++;
189  }
190  if (itree == fNFiles){
191  Error("Next", "All lists are empty\n");
192  return -1;
193  }
194 
195  Long64_t retentry = fCurrent->Next();
196  if (retentry<0){
198  //requested entry is in the next list
199  if (fTreeNumber == fNFiles -1){
200  // Error("Next", "No more entries, last list\n");
201  return -1;
202  }
203  do{
204  //load the next non-empty list. fTreeNumber is changed by LoadList()
205  fTreeNumber++;
209  //no more lists
210  return -1;
211  }
212  retentry = fCurrent->Next();
213  } else {
214  Error("Next", "Something wrong with reading the current list, even though thefile #%d and the list exist\n", fTreeNumber);
215  return -1;
216  }
217 
218  }
219 
221  fLastIndexReturned = retentry;
222  return retentry;
223 
224 }
225 
226 ////////////////////////////////////////////////////////////////////////////////
227 /// Loads the list #listnumber
228 /// This is the only function that can modify fCurrent and fFile data members
229 
231 {
232  //first close the current list
233  if (fCurrent){
234  if (fFile) {
235  delete fFile;
236  fFile = 0;
237  fCurrent = 0;
238  }
239  }
240 
242 
243  //find the right name
244  //get the name of the corresponding chain element (with the treenumber=listnumber)
245  TNamed *nametitle = (TNamed*)fFileNames->At(listnumber);
246  TString filename_short = nametitle->GetTitle();
247  if (filename_short.Contains(".root")){
248  filename_short.Remove(filename_short.Length()-5, 5);
249  }
250  if (!strcmp(fListFileName.Data(), "")){
251  //no name supplied, use the one of the chain file
252  filename_short.Append("_elist.root");
253  //printf("filename: %s\n", filename_short.Data());
254  fFile = TFile::Open(filename_short.Data());
255  } else {
257  filename.ReplaceAll("$", filename_short);
258  //printf("filename: %s\n", filename.Data());
259  fFile = TFile::Open(filename.Data());
260  }
261 
262  if (!fFile || fFile->IsZombie()){
263  if (fFile) {
264  delete fFile;
265  fFile = 0;
266  }
267  fCurrent = 0;
268  fListOffset[listnumber+1] = fListOffset[listnumber];
269  return -1;
270  }
271 
272  if (!strcmp(fListName.Data(), "")){
273  TKey *key;
274  TIter nextkey(fFile->GetListOfKeys());
275  while ((key=(TKey*)nextkey())){
276  if (strcmp("TEntryList", key->GetClassName())==0){
277  //found an object of class TEntryList
278  fCurrent = (TEntryList*)key->ReadObj();
279  }
280  }
281  } else {
283  }
284 
285  if (!fCurrent){
286  Error("LoadList", "List %s not found in the file\n", fListName.Data());
287  fCurrent = 0;
288  fListOffset[listnumber+1]=fListOffset[listnumber];
289  return -1;
290  }
291  fTreeNumber = listnumber;
293  if (fListOffset[fTreeNumber+1] != (fListOffset[fTreeNumber] + nentries)) {
296  }
297 
298  return 1;
299 }
300 
301 ////////////////////////////////////////////////////////////////////////////////
302 /// Print info about this list
303 
304 void TEntryListFromFile::Print(const Option_t* option) const
305 {
306  printf("total number of files: %d\n", fNFiles);
307  TFile *f;
308  TEntryList *el=0;
309  if (fFileNames==0) {
310  Error("Print","fFileNames was not set properly.");
311  } else {
312  for (Int_t listnumber=0; listnumber<fNFiles; listnumber++){
313  TNamed *nametitle = (TNamed*)fFileNames->At(listnumber);
314  TString filename_short = nametitle->GetTitle();
315  if (filename_short.Contains(".root")){
316  filename_short.Remove(filename_short.Length()-5, 5);
317  }
318  if (!strcmp(fListFileName.Data(), "")){
319  //no name supplied, use the one of the chain file
320  filename_short.Append("_elist.root");
321  //printf("filename: %s\n", filename_short.Data());
322  f = TFile::Open(filename_short.Data());
323  } else {
325  filename.ReplaceAll("$", filename_short);
326  //printf("filename: %s\n", filename.Data());
327  f = TFile::Open(filename.Data());
328  }
329  if (f && !f->IsZombie()){
330  if (!strcmp(fListName.Data(), "")){
331  TKey *key;
332  TIter nextkey(f->GetListOfKeys());
333  while ((key=(TKey*)nextkey())){
334  if (strcmp("TEntryList", key->GetClassName())==0){
335  //found an object of class TEntryList
336  el = (TEntryList*)key->ReadObj();
337  }
338  }
339  } else {
340  el = (TEntryList*)f->Get(fListName.Data());
341  }
342  if (el)
343  el->Print(option);
344  }
345  }
346  }
347 
348 }
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
TFile * f
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
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:221