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