Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
15Manages entry lists from different files, when they are not loaded
16in memory at the same time.
17
18This entry list should only be used when processing a TChain (see
19TChain::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
23If the list name is not specified (by passing filename_elist.root/listname to
24the TChain::SetEntryList() function, the first object of class TEntryList
25in the file is taken.
26It is assumed that there are as many lists, as there are chain elements,
27and they are in the same order.
28
29If one of the list files can't be opened, or there is an error reading a list
30from the file, this list is skipped and the entry loop continues on the next
31list.
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
64TEntryListFromFile::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{
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{
169 for (Int_t i=0; i<fNFiles; i++){
171 LoadList(i);
172 }
173 }
174 }
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 the file #%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
305void 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}
#define f(i)
Definition RSha256.hxx:104
long long Long64_t
Definition RtypesCore.h:80
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:364
#define R__ASSERT(e)
Definition TError.h:118
int nentries
TList * GetListOfKeys() const override
TObject * Get(const char *namecycle) override
Return pointer to object identified by namecycle.
Manages entry lists from different files, when they are not loaded in memory at the same time.
virtual ~TEntryListFromFile()
d-tor
TString fListName
name of the list
virtual Long64_t Next()
Returns the next entry in the list.
virtual Int_t LoadList(Int_t listnumber)
Loads the list #listnumber This is the only function that can modify fCurrent and fFile data members.
TFile * fFile
currently open file fCurrent points to the currently open list
Int_t fNFiles
total number of files
virtual void Print(const Option_t *option="") const
Print info about this list.
virtual Long64_t GetEntryAndTree(Long64_t index, Int_t &treenum)
Return the entry corresponding to the index parameter and the number of the tree, where this entry is...
virtual Long64_t GetEntries()
Returns the total number of entries in the list.
TString fListFileName
from this string names of all files can be found
TObjArray * fFileNames
! points to the fFiles data member of the corresponding chain
Long64_t * fListOffset
[fNFiles] numbers of entries in ind. lists
virtual Long64_t GetEntry(Long64_t index)
Returns entry #index See also Next() for a faster alternative.
A List of entry numbers in a TTree or TChain.
Definition TEntryList.h:26
Long64_t fLastIndexQueried
! used to optimize GetEntry() function from a loop
Definition TEntryList.h:44
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
Long64_t fN
number of entries in the list
Definition TEntryList.h:36
Long64_t fLastIndexReturned
! used to optimize GetEntry() function from a loop
Definition TEntryList.h:45
virtual Long64_t Next()
Return the next non-zero entry index (next after fLastIndexQueried) this function is faster than GetE...
virtual Long64_t GetEntry(Long64_t index)
Return the number of the entry #index of this TEntryList in the TTree or TChain See also Next().
TEntryList * fCurrent
! currently filled entry list
Definition TEntryList.h:32
virtual void Print(const Option_t *option="") const
Print this list.
virtual Long64_t GetN() const
Definition TEntryList.h:77
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition TFile.h:54
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:4025
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
virtual const char * GetClassName() const
Definition TKey.h:76
virtual TObject * ReadObj()
To read a TObject* from the file.
Definition TKey.cxx:750
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
virtual const char * GetTitle() const
Returns title of object.
Definition TNamed.h:48
TObject * At(Int_t idx) const
Definition TObjArray.h:164
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition TObject.h:153
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:963
Basic string class.
Definition TString.h:136
Ssiz_t Length() const
Definition TString.h:410
const char * Data() const
Definition TString.h:369
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:692
TString & Remove(Ssiz_t pos)
Definition TString.h:673
TString & Append(const char *cs)
Definition TString.h:564
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:624
static constexpr Long64_t kMaxEntries
Definition TTree.h:226