Logo ROOT   6.18/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
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 "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
65TEntryListFromFile::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{
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{
170 for (Int_t i=0; i<fNFiles; i++){
172 LoadList(i);
173 }
174 }
175 }
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;
298 }
299
300 return 1;
301}
302
303////////////////////////////////////////////////////////////////////////////////
304/// Print info about this list
305
306void 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}
#define f(i)
Definition: RSha256.hxx:104
int Int_t
Definition: RtypesCore.h:41
long long Long64_t
Definition: RtypesCore.h:69
const char Option_t
Definition: RtypesCore.h:62
#define ClassImp(name)
Definition: Rtypes.h:365
#define R__ASSERT(e)
Definition: TError.h:96
int nentries
Definition: THbookFile.cxx:89
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
virtual TList * GetListOfKeys() const
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 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 void Print(const Option_t *option="") const
Print info about this list.
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(Int_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...
Definition: TEntryList.cxx:894
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:655
TEntryList * fCurrent
! currently filled entry list
Definition: TEntryList.h:32
virtual void Print(const Option_t *option="") const
Print this list.
Definition: TEntryList.cxx:997
virtual Long64_t GetN() const
Definition: TEntryList.h:75
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition: TFile.h:48
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseGeneralPurpose, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3980
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:24
virtual const char * GetClassName() const
Definition: TKey.h:71
virtual TObject * ReadObj()
To read a TObject* from the file.
Definition: TKey.cxx:722
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:166
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition: TObject.h:134
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
const char * Data() const
Definition: TString.h:364
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
TString & Append(const char *cs)
Definition: TString.h:559
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
static constexpr Long64_t kMaxEntries
Definition: TTree.h:215