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
41
43 fListFileName(""), fListName(""), fNFiles(0), fListOffset(nullptr), fFile(nullptr), fFileNames(nullptr)
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
63TEntryListFromFile::TEntryListFromFile(const char *filename, const char *listname, Int_t nfiles) : TEntryList(),
64 fListFileName(filename), fListName(listname), fNFiles(nfiles), fListOffset(nullptr), fFile(nullptr), fFileNames(nullptr)
65{
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 = nullptr;
81 delete fFile;
82 fFile = nullptr;
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{
168 for (Int_t i=0; i<fNFiles; i++){
170 LoadList(i);
171 }
172 }
173 }
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 the file #%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 = nullptr;
237 fCurrent = nullptr;
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 {
256 TString filename = fListFileName;
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 = nullptr;
266 }
267 fCurrent = nullptr;
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 {
282 fCurrent = (TEntryList*)fFile->Get(fListName.Data());
283 }
284
285 if (!fCurrent){
286 Error("LoadList", "List %s not found in the file\n", fListName.Data());
287 fCurrent = nullptr;
288 fListOffset[listnumber+1]=fListOffset[listnumber];
289 return -1;
290 }
291 fTreeNumber = listnumber;
292 Long64_t nentries = fCurrent->GetN();
296 }
297
298 return 1;
299}
300
301////////////////////////////////////////////////////////////////////////////////
302/// Print info about this list
303
304void TEntryListFromFile::Print(const Option_t* option) const
305{
306 printf("total number of files: %d\n", fNFiles);
307 TFile *f;
308 TEntryList *el=nullptr;
309 if (fFileNames==nullptr) {
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 {
324 TString filename = fListFileName;
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}
#define f(i)
Definition RSha256.hxx:104
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
const char Option_t
Option string (const char).
Definition RtypesCore.h:80
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
int nentries
TString fListName
name of 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.
~TEntryListFromFile() override
d-tor
TFile * fFile
currently open file fCurrent points to the currently open list
void Print(const Option_t *option="") const override
Print info about this list.
Int_t fNFiles
total number of files
Long64_t Next() override
Returns the next entry in the list.
Long64_t GetEntryAndTree(Long64_t index, Int_t &treenum) override
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
Long64_t GetEntry(Long64_t index) override
Returns entry #index See also Next() for a faster alternative.
TObjArray * fFileNames
! points to the fFiles data member of the corresponding chain
Long64_t * fListOffset
[fNFiles] numbers of entries in ind. lists
Long64_t fLastIndexQueried
! used to optimize GetEntry() function from a loop
Definition TEntryList.h:44
Int_t fTreeNumber
!
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
TEntryList * fCurrent
! currently filled entry list
Definition TEntryList.h:32
void Print(const Option_t *option="") const override
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
Definition TFile.h:130
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:3787
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:77
virtual TObject * ReadObj()
To read a TObject* from the file.
Definition TKey.cxx:792
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
TNamed()
Definition TNamed.h:38
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1098
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:425
const char * Data() const
Definition TString.h:384
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:713
TString & Remove(Ssiz_t pos)
Definition TString.h:694
TString & Append(const char *cs)
Definition TString.h:581
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:641
static constexpr Long64_t kMaxEntries
Used as the max value for any TTree range operation.
Definition TTree.h:273