Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TEntryList.cxx
Go to the documentation of this file.
1// @(#)root/tree:$Id$
2// Author: Anna Kreshuk 27/10/2006
3
4/*************************************************************************
5 * Copyright (C) 1995-2006, 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 TEntryList
13\ingroup tree
14
15A List of entry numbers in a TTree or TChain.
16
17Note: It is recommended to use approaches such as TTreeReader::SetEntryRange or
18ROOT::RDataFrame instead of TEntryList if possible.
19
20## Operations on entry lists
21
22- __Add__() - if the lists are for the same tree, adds all the entries of the second list
23 to the first list. If the lists are for different trees, creates a TEntryList
24 with 2 sublists for each TTree. If the lists are for TChains, merges the ones
25 for the same trees and adds new sublists for the TTrees that were not included
26 in the first TEntryList
27- __Subtract__() - if the lists are for the same TTree, removes the entries of the second
28 list from the first list. If the lists are for TChains, loops over all
29 sub-lists
30- __GetEntry(n)__ - returns the n-th entry number
31- __Next__() - returns next entry number. Note, that this function is
32 much faster than GetEntry, and it's called when GetEntry() is called
33 for 2 or more indices in a row.
34
35## TTree::Draw() and TChain::Draw()
36
37Use option __entrylist__ to write the results of TTree::Draw and TChain::Draw into
38an entry list. Example:
39~~~ {.cpp}
40 tree->Draw(">>elist", "x<0 && y>0", "entrylist");
41 TEntryList *elist = (TEntryList*)gDirectory->Get("elist");
42~~~
43## Example of Loop on TEntryList with a TChain
44~~~ {.cpp}
45 void loopChain() {
46 TFile *fe = TFile::Open("myelist.root");
47 TEntryList *myelist = (TEntryList*)fe->Get("myelist");
48 TChain *chain = new TChain("ntuple");
49 chain->Add("hsimple.root");
50 chain->Add("hsimple2.root");
51 Long64_t listEntries = myelist->GetN();
52 Long64_t chainEntries = chain->GetEntries();
53 Int_t treenum = 0;
54 chain->SetEntryList(myelist);
55
56 for (entry=start;entry < end;entry++) {
57 entryNumber = chain->GetEntryNumber(entry);
58 if (entryNumber < 0) break;
59 localEntry = chain->LoadTree(entryNumber);
60 if (localEntry < 0) break;
61 ....
62 then either call
63 branch->GetEntry(localEntry);
64 or
65 chain->GetEntry(entryNumber);
66 In the later case the LoadTree is then somewhat redundant.
67 ...
68 }
69 }
70~~~
71When using the TEntryList interface directly, you can get the 'tree number' and entry in
72the current tree (i.e. value similar to the return value of LoadTree) from calling
73TEntryList::GetEntryAndTree:
74~~~ {.cpp}
75 Long64_t treeEntry = myelist->GetEntryAndTree(el,treenum);
76~~~
77to obtain the entry number within the chain you need to add to it the value of
78`treeEntry+ch->GetTreeOffset()[treenum]`
79such that the loop in the previous example can also be written as:
80~~~ {.cpp}
81 for (Long64_t el = 0; el < listEntries; el++) {
82 Long64_t treeEntry = myelist->GetEntryAndTree(el,treenum);
83 Long64_t chainEntry = treeEntry+ch->GetTreeOffset()[treenum];
84 printf("el=%lld, treeEntry=%lld, chainEntry=%lld, treenum=%d\n", el, treeEntry, chainEntry, treenum);
85
86 ch->LoadTree(chainEntry); // this also returns treeEntry
87 needed_branch->GetEntry(treeEntry);
88 }
89~~~
90## TSelectors
91
92To fill an TEntryList from a TSelector correctly, one must add the TEntryList object
93to the output list of the selector (TSelector::fOutput). This is the only way to
94make the sub-lists of the TEntryList switch when the current tree of the TChain is
95changed.
96
97## Using a TEntryList as input (TTree::SetEntryList() and TChain::SetEntryList())
98
99while the TTree::SetEntryList() function is only setting the TTree::fEntryList
100data member, the same function in TChain also finds correspondence between
101the TTrees of this TChain and the sub-lists of this TEntryList.
102
103## TEntryList and the current directory
104
105TEntryList objects are automatically added to the current directory (like TTrees).
106However, in case of a TEntryList for a chain, only the top-level entry list is added,
107not the sub-lists for specific trees. Placing entry lists in the current directory
108allows calling them as a part of a TTreeFormula expression, so if the user wants
109to extract a sublist from a TChain entry list via the GetEntryList() or some other
110function, they have to add it to the current directory to be able to use it in
111TTreeFormula expressions.
112
113## TEntryList and TEventList
114
115TTree::SetEventList() and TChain::SetEventList() transform a TEventList into a TEntryList
116See comments to those functions for more details
117
118## Types of entry lists
119There are two types of entry lists:
120
121#### 1.
122 for a TTree (fBlocks data member is non-zero)
123 Entry numbers are stored in TEntryListBlocks, which, in their turn, are stored
124 in the TObjArray fBlocks. The range of the entry numbers is cut into intervals
125 of kBlockSize entries (currently 64000), so that the first block contains
126 information which entries out of the first 64000 pass the selection, the second
127 block - which entries out of the 64000-127999 interval pass the selection, etc.
128 Some blocks, obviously, might be empty. The internal representation of entry
129 numbers in the blocks is described in the TEntryListBlock class description, and
130 this representation might be changed by calling OptimizeStorage() function
131 (when the list is filled via the Enter() function, this is done automatically,
132 except for the last block).
133 Individual entry lists can be merged (functions Merge() and Add())
134 to make an entry list for a TChain of corresponding TTrees.
135Begin_Macro
136entrylist_figure1.C
137End_Macro
138
139#### 2.
140 for a TChain (fLists data member is non-zero)
141 It contains a TList of sub-lists (TEntryList objects, corresponding to each TTree)
142 Trees and lists are matched by the TTree name and its file name (full path).
143 All sub-lists are returned by the GetLists() function and individual lists are
144 returned by GetEntryList() function. Such lists are no different from the lists for
145 TTrees, described above.
146Begin_Macro
147entrylist_figure2.C
148End_Macro
149
150
151*/
152
153#include "TEntryList.h"
154#include "TEntryListBlock.h"
155#include "TError.h"
156#include "TKey.h"
157#include "TBuffer.h"
158#include "TTree.h"
159#include "TFile.h"
160#include "TRegexp.h"
161#include "TSystem.h"
162#include "TObjString.h"
163
164
165////////////////////////////////////////////////////////////////////////////////
166/// default c-tor
167
168TEntryList::TEntryList() = default;
169
170////////////////////////////////////////////////////////////////////////////////
171/// c-tor with name and title
172
173TEntryList::TEntryList(const char *name, const char *title) : TNamed(name, title)
174{
175
177 if (fDirectory)
178 fDirectory->Append(this);
179}
180
181////////////////////////////////////////////////////////////////////////////////
182/// constructor with name and title, which also sets the tree
183
184TEntryList::TEntryList(const char *name, const char *title, const TTree *tree) : TNamed(name, title)
185{
187
189 if (fDirectory)
190 fDirectory->Append(this);
191}
192
193////////////////////////////////////////////////////////////////////////////////
194/// c-tor with name and title, which also sets the treename and the filename
195
196TEntryList::TEntryList(const char *name, const char *title, const char *treename, const char *filename)
197 : TNamed(name, title)
198{
200
202 if (fDirectory)
203 fDirectory->Append(this);
204}
205
206////////////////////////////////////////////////////////////////////////////////
207/// c-tor, which sets the tree
208
209TEntryList::TEntryList(const TTree *tree)
210{
211 SetTree(tree);
212
214 if (fDirectory)
215 fDirectory->Append(this);
216}
217
218////////////////////////////////////////////////////////////////////////////////
219/// copy c-tor
220
222 : TNamed(elist),
223 fNBlocks(elist.fNBlocks),
224 fN(elist.fN),
225 fEntriesToProcess(elist.fEntriesToProcess),
226 fTreeName(elist.fTreeName),
227 fFileName(elist.fFileName),
228 fStringHash(elist.fStringHash),
229 fTreeNumber(elist.fTreeNumber),
230 fShift(elist.fShift),
231 fReapply(elist.fReapply)
232{
233 if (elist.fLists){
234 fLists = new TList();
235 TEntryList *el1 = nullptr;
236 TEntryList *el2 = nullptr;
237 TIter next(elist.fLists);
238 while((el1 = (TEntryList*)next())){
239 el2 = new TEntryList(*el1);
240 if (el1==elist.fCurrent)
241 fCurrent = el2;
242 fLists->Add(el2);
243 }
244 } else {
245 if (elist.fBlocks){
246 TEntryListBlock *block1 = nullptr;
247 TEntryListBlock *block2 = nullptr;
248 //or just copy it as a TObjArray??
249 fBlocks = new TObjArray();
250 for (Int_t i=0; i<fNBlocks; i++){
254 }
255 }
256 fCurrent = this;
257 }
258}
259
260////////////////////////////////////////////////////////////////////////////////
261/// Destructor.
262
264{
265 if (fBlocks){
266 fBlocks->Delete();
267 delete fBlocks;
268 }
269 fBlocks = nullptr;
270 if (fLists){
271 fLists->Delete();
272 delete fLists;
273 }
274
275 fLists = nullptr;
276
277 if (fDirectory) fDirectory->Remove(this);
278 fDirectory = nullptr;
279
280}
281
282////////////////////////////////////////////////////////////////////////////////
283/// \brief Add 2 entry lists.
284///
285/// \param[in] elist The list that should be added to the current one.
286///
287/// \note If you are creating a TEntryList for a TChain and you would like to
288/// have a one to one mapping between the sub lists of the TEntryList and
289/// the sub trees in the TChain, please do not call this function but use
290/// TEntryList::AddSubList instead and pair it with a call to
291/// TChain::SetEntryList with option "sync". See the AddSubList function
292/// documentation for an example usage. This helps for example in a
293/// testing or benchmark scenario where a TChain holds multiple times the
294/// same tree in the same file. In that case, this function would not be
295/// be able to distinguish different sub entry lists that refer to the
296/// same treename and filename. Instead it would create a union of all the
297/// sub entry lists into one list.
298
299void TEntryList::Add(const TEntryList *elist)
300{
301 if (fN==0){
302 if (!fLists && fTreeName=="" && fFileName==""){
303 //this list is empty. copy the other list completely
304 fNBlocks = elist->fNBlocks;
305 fTreeName = elist->fTreeName;
306 fFileName = elist->fFileName;
307 fStringHash = elist->fStringHash;
308 fTreeNumber = elist->fTreeNumber;
311 fN = elist->fN;
312 if (elist->fLists){
313 fLists = new TList();
314 TEntryList *el1 = nullptr;
315 TEntryList *el2 = nullptr;
316 TIter next(elist->fLists);
317 while((el1 = (TEntryList*)next())){
318 el2 = new TEntryList(*el1);
319 if (el1==elist->fCurrent)
320 fCurrent = el2;
321 fLists->Add(el2);
322 }
323 } else {
324 if (elist->fBlocks){
325 TEntryListBlock *block1 = nullptr;
326 TEntryListBlock *block2 = nullptr;
327 fBlocks = new TObjArray();
328 for (Int_t i=0; i<fNBlocks; i++){
332 }
333 }
334 fCurrent = nullptr;
335 }
336 return;
337 }
338 }
339
340 if (!fLists){
341 if (!elist->fLists){
342 if (!strcmp(elist->fTreeName.Data(),fTreeName.Data()) && !strcmp(elist->fFileName.Data(),fFileName.Data())){
343 //entry lists are for the same tree
344 if (!elist->fBlocks)
345 //the other list is empty list
346 return;
347 if (!fBlocks){
348 //this entry list is empty
349 TEntryListBlock *block1 = nullptr;
350 TEntryListBlock *block2 = nullptr;
351 fNBlocks = elist->fNBlocks;
352 fN = elist->fN;
353 fBlocks = new TObjArray();
354 for (Int_t i=0; i<fNBlocks; i++){
358 }
359 return;
360 }
361 //both not empty, merge block by block
362 TEntryListBlock *block1=nullptr;
363 TEntryListBlock *block2=nullptr;
364 Int_t i;
365 Int_t nmin = std::min(fNBlocks, elist->fNBlocks);
367 for (i=0; i<nmin; i++){
370 nold = block1->GetNPassed();
371 nnew = block1->Merge(block2);
372 fN = fN - nold + nnew;
373 }
375 Int_t nmax = elist->fNBlocks;
376 for (i=nmin; i<nmax; i++){
380 fN+=block1->GetNPassed();
381 fNBlocks++;
382 }
383 }
386 } else {
387 //entry lists are for different trees. create a chain entry list with
388 //2 sub lists for the first and second entry lists
391 fLists = new TList();
392 TEntryList *el = new TEntryList();
393 el->fTreeName = fTreeName;
394 el->fFileName = fFileName;
395 el->fBlocks = fBlocks;
396 fBlocks = nullptr;
397 el->fNBlocks = fNBlocks;
398 el->fN = fN;
399 el->fLastIndexQueried = -1;
400 el->fLastIndexReturned = 0;
401 fLists->Add(el);
402 el = new TEntryList(*elist);
403 el->fLastIndexQueried = -1;
404 el->fLastIndexReturned = 0;
405 fLists->Add(el);
406 fN+=el->GetN();
407 fCurrent = nullptr;
408 }
409 } else {
410 //second list already has sublists. add one by one
411 TEntryList *el = nullptr;
412 TIter next(elist->fLists);
413 while ((el = (TEntryList*)next())){
414 Add(el);
415 }
416 fCurrent = nullptr;
417 }
418 } else {
419 //there are already some sublists in this list, just add another one
420 if (!elist->fLists){
421 //the other list doesn't have sublists
422 TIter next(fLists);
423 TEntryList *el = nullptr;
424 bool found = false;
425 while ((el = (TEntryList*)next())){
426 if (!strcmp(el->fTreeName.Data(), elist->fTreeName.Data()) &&
427 !strcmp(el->fFileName.Data(), elist->fFileName.Data())){
428 // if (el->fStringHash == elist->fStringHash){
429 //found a list for the same tree
430 Long64_t oldn = el->GetN();
431 el->Add(elist);
432 found = true;
433 fN = fN - oldn + el->GetN();
434 break;
435 }
436 }
437 if (!found){
438 el = new TEntryList(*elist);
439 el->fLastIndexQueried = -1;
440 el->fLastIndexReturned = 0;
441 fLists->Add(el);
442 fN+=el->GetN();
443 }
444 } else {
445 //add all sublists from the other list
446 TEntryList *el = nullptr;
447 TIter next(elist->fLists);
448 while ((el = (TEntryList*)next())){
449 Add(el);
450 }
451 fCurrent = nullptr;
452 }
453 if (fCurrent){
454 if (fCurrent->fBlocks){
457 block->ResetIndices();
460 }
461 }
462 fCurrent = nullptr;
463 }
464
465}
466
467////////////////////////////////////////////////////////////////////////////////
468/// \brief Add a sub entry list to the current list.
469/// \param[in] elist an entry list that should be added as a sub list of this list.
470///
471/// This function is specifically targeted at situations where there is a global
472/// TEntryList that should hold one or more sub TEntryList objects. For example,
473/// if one wants to create a one to one mapping between the sub entry lists and
474/// the trees in the files that make a TChain. Note that in such cases this
475/// configuration of the entry list should be used in pair with the option \p "sync"
476/// of the function TChain::SetEntryList
477///
478/// ~~~{.cpp}
479/// // Create a TChain with two files. Each contains a tree with 20 entries
480/// TChain chain{"entries"};
481/// chain.Add("file_20entries_1.root");
482/// chain.Add("file_20entries_2.root");
483///
484/// // Create a global, empty TEntryList.
485/// TEntryList elists;
486/// // Create two entry lists. Each one will be referring to a different tree in the chain
487/// TEntryList elist1{"","","entries","file_20entries_1.root"};
488/// TEntryList elist2{"","","entries","file_20entries_2.root"};
489///
490/// // Select the first ten entries from the first tree and all entries from the second
491/// for(auto entry = 0; entry < 10; entry++){
492/// elist1.Enter(entry);
493/// }
494/// for(auto entry = 0; entry < 20; entry++){
495/// elist2.Enter(entry);
496/// }
497///
498/// // Add sub entry lists to the global list
499/// elists.AddSubList(&elist1);
500/// elists.AddSubList(&elist2);
501///
502/// // Set the entry list in the chain. Note the usage of option "sync"
503/// chain.SetEntryList(&elists, "sync");
504/// ~~~
505
507
508 auto elistcopy = new TEntryList{*elist};
509
510 fN += elistcopy->fN;
511
512 if (!fLists){
513 fLists = new TList();
514 }
516}
517
518////////////////////////////////////////////////////////////////////////////////
519/// - When tree = 0, returns from the current list
520/// - When tree != 0, finds the list, corresponding to this tree
521/// - When tree is a chain, the entry is assumed to be global index and the local
522/// entry is recomputed from the treeoffset information of the chain
523
525{
526 if (!tree){
527 if (fBlocks) {
528 //this entry list doesn't contain any sub-lists
529 TEntryListBlock *block = nullptr;
531 if (nblock >= fNBlocks) return 0;
533 return block->Contains(entry-nblock*kBlockSize);
534 }
535 if (fLists) {
537 return fCurrent->Contains(entry);
538 }
539 return 0;
540 } else {
542 SetTree(tree->GetTree());
543 if (fCurrent)
545 }
546 return 0;
547
548}
549
550////////////////////////////////////////////////////////////////////////////////
551/// Called by TKey and others to automatically add us to a directory when we are read from a file.
552
554{
555 SetDirectory(dir);
556}
557
558////////////////////////////////////////////////////////////////////////////////
559/// Add entry \#entry to the list
560/// - When tree = 0, adds to the current list
561/// - When tree != 0, finds the list, corresponding to this tree
562/// - When tree is a chain, the entry is assumed to be global index and the local
563/// entry is recomputed from the treeoffset information of the chain
564
566{
567 if (!tree){
568 if (!fLists) {
569 if (!fBlocks) fBlocks = new TObjArray();
570 TEntryListBlock *block = nullptr;
572 if (nblock >= fNBlocks) {
573 if (fNBlocks>0){
575 if (!block) return false;
576 block->OptimizeStorage();
577 }
578 for (Int_t i=fNBlocks; i<=nblock; i++){
579 block = new TEntryListBlock();
580 fBlocks->Add(block);
581 }
582 fNBlocks = nblock+1;
583 }
585 if (block->Enter(entry-nblock*kBlockSize)) {
586 fN++;
587 return true;
588 }
589 } else {
590 //the entry in the current entry list
592 if (fCurrent->Enter(entry)) {
593 if (fLists)
594 fN++;
595 return true;
596 }
597 }
598 } else {
600 SetTree(tree->GetTree());
601 if (fCurrent){
602 if (fCurrent->Enter(localentry)) {
603 if (fLists)
604 fN++;
605 return true;
606 }
607 }
608 }
609 return false;
610
612
613bool TEntryList::Enter(Long64_t localentry, const char *treename, const char *filename)
614{
616 if (fCurrent) {
617 if (fCurrent->Enter(localentry)) {
618 if (fLists)
619 fN++;
620 return true;
621 }
622 }
623 return false;
624}
625
626/////////////////////////////////////////////////////////////////////////////
627/// \brief Enter all entries in a range in the TEntryList.
628/// \param[in] start starting entry to enter.
629/// \param[in] end ending entry to enter.
630/// \param[in] tree passed as is to TEntryList::Enter.
631/// \param[in] step step increase of the loop entering the entries.
632///
633/// This is a helper function that enters all entries between \p start
634/// (inclusive) and \p end (exclusive) to the TEntryList in a loop. It
635/// is useful also in PyROOT to avoid having to do the same in a Python loop.
636
637void TEntryList::EnterRange(Long64_t start, Long64_t end, TTree *tree, UInt_t step)
638{
639 for (auto entry = start; entry < end; entry += step) {
640 this->Enter(entry, tree);
641 }
642}
643
644////////////////////////////////////////////////////////////////////////////////
645/// Remove entry \#entry from the list
646/// - When tree = 0, removes from the current list
647/// - When tree != 0, finds the list, corresponding to this tree
648/// - When tree is a chain, the entry is assumed to be global index and the local
649/// entry is recomputed from the treeoffset information of the chain
650
652{
653 if (entry < 0)
654 return false;
655 if (!tree) {
656 if (!fLists) {
657 if (!fBlocks) return false;
658 TEntryListBlock *block = nullptr;
661 if (!block) return false;
663 if (block->Remove(blockindex)){
664 fN--;
665 return true;
666 }
667 } else {
669 if (fCurrent->Remove(entry)){
670 if (fLists)
671 fN--;
672 return true;
673 }
674 }
675 } else {
677 SetTree(tree->GetTree());
678 if (fCurrent){
679 if (fCurrent->Remove(localentry)) {
680 if (fLists)
681 fN--;
682 return true;
683 }
684 }
685 }
686 return false;
687}
688
689////////////////////////////////////////////////////////////////////////////////
690/// Return the number of the entry \#index of this TEntryList in the TTree or TChain
691/// See also Next().
692
694{
695
696 if ((index>=fN) || (index<0)) {
697 return -1;
698 }
699 if (index==fLastIndexQueried+1){
700 //in a loop
701 return Next();
702 } else {
703 if (fBlocks) {
704 TEntryListBlock *block = nullptr;
706 Int_t i=0;
707 while (total_passed<=index && i<fNBlocks){
709 total_passed+=block->GetNPassed();
710 i++;
711 }
712 i--;
713 total_passed-=block->GetNPassed();
716 block->ResetIndices();
718 }
719
721 Long64_t blockindex = block->GetEntry(localindex);
722 if (blockindex < 0) return -1;
725 fLastIndexReturned = res;
726 return res;
727 } else {
728 //find the corresponding list
730 TIter next(fLists);
732 Long64_t ntotal = 0;
733 if (fCurrent){
734 //reset all indices of the current list
735 if (fCurrent->fBlocks){
738 block->ResetIndices();
741 }
742 }
743 while ((templist = (TEntryList*)next())){
744 if (!fShift){
745 ntotal += templist->GetN();
746 } else {
747 if (templist->GetTreeNumber() >= 0)
748 ntotal += templist->GetN();
749 }
750 if (ntotal > index)
751 break;
752 }
754 if (!fCurrent) return -1;
758 return fLastIndexReturned;
759 }
760
761 }
762 return -1;
763}
764
765////////////////////////////////////////////////////////////////////////////////
766/// Return the index of "index"-th non-zero entry in the TTree or TChain
767/// and the # of the corresponding tree in the chain
768
770{
771//If shift is true, then when the requested entry is found in an entry list,
772//for which there is no corresponding tree in the chain, this list is not
773//taken into account, and entry from the next list with a tree is returned.
774//Example:
775//First sublist - 20 entries, second sublist - 5 entries, third sublist - 10 entries
776//Second sublist doesn't correspond to any trees of the chain
777//Then, when GetEntryAndTree(21, treenum, true) is called, first entry of the
778//third sublist will be returned
779
781 if (result < 0) {
782 treenum = -1;
783 return result;
784 }
785 R__ASSERT(fLists == nullptr || (fLists != nullptr && fCurrent != nullptr));
786 if (fCurrent)
788 else
790 if (treenum < 0)
791 return -1;
792
793 return result;
794}
795
796////////////////////////////////////////////////////////////////////////////////
797/// To be able to re-localize the entry-list we identify the file by just the
798/// name and the anchor, i.e. we drop protocol, host, options, ...
799/// The result in the form 'file#anchor' (or 'file', if no anchor is present)
800/// is saved in 'fn'.
801/// The function optionally (is 'local' is defined) checks file locality (i.e.
802/// protocol 'file://') returning the result in '*local' .
803
804void TEntryList::GetFileName(const char *filename, TString &fn, bool *local)
805{
806 TUrl u(filename, true);
807 if (local) *local = (!strcmp(u.GetProtocol(), "file")) ? true : false;
808 if (strlen(u.GetAnchor()) > 0) {
809 fn.Form("%s#%s", u.GetFile(), u.GetAnchor());
810 } else {
811 fn = u.GetFile();
812 }
813 // Done
814 return;
815}
816
817////////////////////////////////////////////////////////////////////////////////
818/// Return the entry list, corresponding to treename and filename
819/// By default, the filename is first tried as is, and then, if the corresponding list
820/// is not found, the filename is expanded to the absolute path, and compared again.
821/// To avoid it, use option "ne"
822
823TEntryList *TEntryList::GetEntryList(const char *treename, const char *filename, Option_t *opt)
824{
825 if (gDebug > 1)
826 Info("GetEntryList","tree: %s, file: %s",
827 (treename ? treename : "-"), (filename ? filename : "-"));
828
829 if (!treename || !filename) return nullptr;
830 TString option = opt;
831 option.ToUpper();
832 bool nexp = option.Contains("NE");
833
834 TString fn;
835 bool local;
837 if (nexp) local = false;
838
839 if (gDebug > 1)
840 Info("GetEntryList", "file: %s, local? %d", filename, local);
841
842 if (!fLists){
843 //there are no sublists
844 if (!strcmp(treename, fTreeName.Data()) && !(strcmp(fn.Data(), fFileName.Data()))){
845 return this;
846 } else {
847 //if the file is local, try the full name, unless "ne" option was specified
848 if (!nexp && local){
853 if (!strcmp(treename, fTreeName.Data()) && !(strcmp(fn.Data(), fFileName.Data())))
854 return this;
855 }
856 return nullptr;
857 }
858 }
859
861 stotal.Append(fn);
862 ULong_t newhash = stotal.Hash();
863
864 TIter next(fLists);
866 while ((templist = (TEntryList*)next())){
867 if (templist->fStringHash==0){
868 stotal = templist->fTreeName + templist->fFileName;
869 templist->fStringHash = stotal.Hash();
870 }
871 if (gDebug > 1)
872 Info("GetEntryList", "file: %s (fn: %s), hash: %lu, element hash: %lu",
873 filename, fn.Data(), newhash, templist->fStringHash);
874 if (newhash == templist->fStringHash){
875 if (!strcmp(templist->GetTreeName(), treename) && !strcmp(templist->GetFileName(), fn.Data())){
876 return templist;
877 }
878 }
879 }
880
881 //didn't find anything for this filename, try the full name too
882 if (!nexp && local){
889 stotal.Append(longname);
890 newhash = stotal.Hash();
891 next.Reset();
892 while ((templist = (TEntryList*)next())){
893 if (templist->fStringHash==0){
894 stotal = templist->fTreeName + templist->fFileName;
895 templist->fStringHash = stotal.Hash();
896 }
897 if (gDebug > 1)
898 Info("GetEntryList", "file: %s (longname: %s), hash: %lu, element hash: %lu",
899 filename, longname.Data(), newhash, templist->fStringHash);
900 if (newhash == templist->fStringHash){
901 if (templist->fTreeName == treename && templist->fFileName == longname){
902 return templist;
903 }
904 }
905 }
906 }
907 return nullptr;
908}
909
910////////////////////////////////////////////////////////////////////////////////
911/// Merge this list with the lists from the collection
912
914{
915 if (!list) return -1;
916 TIter next(list);
917 TEntryList *elist = nullptr;
918 while ((elist = (TEntryList*)next())) {
919 if (!elist->InheritsFrom(TEntryList::Class())) {
920 Error("Add","Attempt to add object of class: %s to a %s",elist->ClassName(),this->ClassName());
921 return -1;
922 }
923 Add(elist);
924 }
925 return 0;
926}
927
928////////////////////////////////////////////////////////////////////////////////
929/// Return the next non-zero entry index (next after fLastIndexQueried)
930/// this function is faster than GetEntry()
931
933{
935 if (fN == fLastIndexQueried+1 || fN==0){
936 return -1;
937 }
938 if (fBlocks){
941 result = current_block->Next();
942 if (result>=0) {
945 return fLastIndexReturned;
946 }
947 else {
948 while (result<0 && iblock<fNBlocks-1) {
949 current_block->ResetIndices();
950 iblock++;
952 current_block->ResetIndices();
953 result = current_block->Next();
954 }
955 if (result<0) {
958 return -1;
959 }
962
963 return fLastIndexReturned;
964 }
965 } else {
966 if (!fCurrent) {
968 if (!fCurrent) return 0;
969 if (fShift) {
970 while (fCurrent->GetTreeNumber()<0) {
972 if (!fCurrent) return 0;
973 }
974 }
975 }
976 result = fCurrent->Next();
977 if (result>=0) {
980 return result;
981 } else {
982 if (fCurrent){
983 //reset all indices of the current list
984 if (fCurrent->fBlocks){
987 block->ResetIndices();
990 }
991 }
992
993 //find the list with the next non-zero entry
994 while (result<0 && fCurrent!=((TEntryList*)fLists->Last())){
995 if (!fCurrent) return 0;
999 // fCurrent is guarantee to be non-zero because it is not the 'last'
1000 // element of the list.
1001 if (!fCurrent) return 0;
1002 if (!fShift)
1003 result = fCurrent->Next();
1004 else {
1005 if (fCurrent->GetTreeNumber() >= 0)
1006 result = fCurrent->Next();
1007 }
1008 }
1011 return result;
1012 }
1013 }
1014}
1015
1016////////////////////////////////////////////////////////////////////////////////
1017/// Checks if the array representation is more economical and if so, switches to it
1018
1020{
1021 if (fBlocks){
1022 TEntryListBlock *block = nullptr;
1023 for (Int_t i=0; i<fNBlocks; i++){
1025 block->OptimizeStorage();
1026 }
1027 }
1028}
1029
1030////////////////////////////////////////////////////////////////////////////////
1031/// Print this list
1032/// - option = "" - default - print the name of the tree and file
1033/// - option = "all" - print all the entry numbers
1034
1035void TEntryList::Print(const Option_t* option) const
1036{
1037 TString opt = option;
1038 opt.ToUpper();
1039 if (fBlocks) {
1040 Printf("%s %s %lld", fTreeName.Data(), fFileName.Data(), fN);
1041 if (opt.Contains("A")){
1042 TEntryListBlock* block = nullptr;
1043 for (Int_t i=0; i<fNBlocks; i++){
1045 Int_t shift = i*kBlockSize;
1046 block->PrintWithShift(shift);
1047 }
1048 }
1049 }
1050 else {
1051 TEntryList *elist = nullptr;
1052 if (fN>0){
1053 TIter next(fLists);
1054 while((elist = (TEntryList*)next())){
1055 elist->Print(option);
1056 }
1057 } else {
1058 if (!fLists) Printf("%s %s %lld", fTreeName.Data(), fFileName.Data(), fN);
1059 else {
1060 TIter next(fLists);
1061 while ((elist = (TEntryList*)next())){
1062 Printf("%s %s %lld", elist->GetTreeName(), elist->GetFileName(), elist->GetN());
1063 }
1064 }
1065 }
1066 }
1067}
1068
1069////////////////////////////////////////////////////////////////////////////////
1070/// Reset this list
1071
1072void TEntryList::Reset()
1073{
1074 //Maybe not delete, but just reset the number of blocks to 0????
1075
1076 if (fBlocks){
1077 fBlocks->Delete();
1078 delete fBlocks;
1079 fBlocks = nullptr;
1080 }
1081 if (fLists){
1082 if (!((TEntryList*)fLists->First())->GetDirectory()){
1083 fLists->Delete();
1084 }
1085 delete fLists;
1086 fLists = nullptr;
1087 }
1088 fCurrent = nullptr;
1089 fBlocks = nullptr;
1090 fNBlocks = 0;
1091 fN = 0;
1092 fTreeName = "";
1093 fFileName = "";
1094 fStringHash = 0;
1095 fTreeNumber = -1;
1096 fLastIndexQueried = -1;
1098 fReapply = false;
1099}
1100
1101////////////////////////////////////////////////////////////////////////////////
1102/// Add reference to directory dir. dir can be 0.
1103
1105{
1106 if (fDirectory == dir) return;
1107 if (fDirectory) fDirectory->Remove(this);
1108 fDirectory = dir;
1109 if (fDirectory) fDirectory->Append(this);
1110}
1111
1112////////////////////////////////////////////////////////////////////////////////
1113/// If a list for a tree with such name and filename exists, sets it as the current sublist
1114/// If not, creates this list and sets it as the current sublist
1115///
1116/// ! the filename is taken as provided, no extensions to full path or url !
1117
1118void TEntryList::SetTree(const char *treename, const char *filename)
1119{
1120 TEntryList *elist = nullptr;
1121
1122 TString fn;
1124
1126 stotal.Append(fn.Data());
1127 //printf("setting tree %s\n", stotal.Data());
1128 ULong_t newhash = stotal.Hash();
1129 if (fLists) {
1130 //find the corresponding entry list and make it current
1132 if (fCurrent->fStringHash == 0){
1134 fCurrent->fStringHash = stotal.Hash();
1135 }
1136 if (newhash == fCurrent->fStringHash){
1137 //this list is current
1139 return;
1140 }
1141 }
1142 TIter next(fLists);
1143 while ((elist = (TEntryList*)next())){
1144 if (newhash == elist->fStringHash){
1145 if (elist->fTreeName == treename && elist->fFileName == fn.Data()) {
1146 //the current entry list was changed. reset the fLastIndexQueried,
1147 //so that Next() doesn't start with the wrong current list
1148 //Also, reset those indices in the previously current list
1149 if (fCurrent->fBlocks){
1152 block->ResetIndices();
1155 }
1156 fCurrent = elist;
1157 fLastIndexQueried = -3;
1158 return;
1159 }
1160 }
1161 }
1162 //didn't find an entry list for this tree, create a new one
1163 elist = new TEntryList("", "", treename, fn.Data());
1164 if (elist->GetDirectory()) {
1165 //sub lists are not added to the current directory
1166 elist->GetDirectory()->Remove(elist);
1167 elist->SetDirectory(nullptr);
1168 }
1169 fLists->Add(elist);
1170 fCurrent = elist;
1171 return;
1172 } else {
1173 if (fN==0 && fTreeName=="" && fFileName==""){
1174 //this is the first tree set to this list
1176 fFileName = fn;
1178 //fStringHash = stotal.Hash();
1180 fCurrent = this;
1181 } else {
1182 if (fStringHash == 0){
1184 fStringHash = stotal.Hash();
1185 }
1186 if (newhash != fStringHash){
1187 //we have a chain and already have an entry list for the first tree
1188 //move the first entry list to the fLists
1189 fLists = new TList();
1190 elist = new TEntryList();
1191 elist->fTreeName = fTreeName;
1192 elist->fFileName = fFileName;
1193 elist->fStringHash = fStringHash;
1194 elist->fN = fN;
1195 elist->fTreeNumber = fTreeNumber;
1196 elist->fBlocks = fBlocks;
1197 fBlocks = nullptr;
1198 elist->fNBlocks = fNBlocks;
1199 fLists->Add(elist);
1200 elist = new TEntryList("", "", treename, fn.Data());
1201 if (elist->GetDirectory()) {
1202 //sub lists are not added to the current directory
1203 elist->GetDirectory()->Remove(elist);
1204 elist->SetDirectory(nullptr);
1205 }
1206 fLists->Add(elist);
1207 fCurrent = elist;
1208 //the current entry list was changed. reset the fLastIndexQueried,
1209 //so that Next() doesn't start with the wrong current list
1210 fLastIndexQueried = -3;
1211
1212 }
1213 else {
1214 //same tree as in the current entry list, don't do anything
1215 return;
1216 }
1217 }
1218 }
1219}
1220
1221////////////////////////////////////////////////////////////////////////////////
1222/// If a list for a tree with such name and filename exists, sets it as the current sublist
1223/// If not, creates this list and sets it as the current sublist
1224/// The name of the file, where the tree is, is taken as
1225/// `tree->GetTree()->GetCurrentFile()->GetName()`, and then expanded either to the absolute path,
1226/// or to full url. If, for some reason, you want to provide
1227/// the filename in a different format, use SetTree(const char *treename, const char *filename),
1228/// where the filename is taken "as is".
1229
1230void TEntryList::SetTree(const TTree *tree)
1231{
1232 if (!tree) return;
1233 auto thisTree = tree->GetTree();
1234 if (!thisTree) return;
1235
1237 if (tree->GetDirectory()->InheritsFrom("TFile")) {
1238 treename = thisTree->GetName();
1239 } else {
1240 treename = TString::Format("%s/%s",tree->GetDirectory()->GetName(),thisTree->GetName());
1241 }
1242
1244 if (tree->GetTree()->GetCurrentFile()){
1245 filename = tree->GetTree()->GetCurrentFile()->GetName();
1246 TUrl url(filename.Data(), true);
1247 if (!strcmp(url.GetProtocol(), "file")){
1248 filename = url.GetFile(); // Get the file part, excluding the anchor, then expand
1253 url.SetFile(filename);
1254 }
1255 filename = url.GetUrl();
1256 } else {
1257 //memory-resident
1258 filename = "";
1259 }
1261
1262}
1263
1264////////////////////////////////////////////////////////////////////////////////
1265/// Remove all the entries of this entry list, that are contained in elist
1266
1267void TEntryList::Subtract(const TEntryList *elist)
1268{
1269 TEntryList *templist = nullptr;
1270 if (!fLists){
1271 if (!fBlocks) return;
1272 //check if lists are for the same tree
1273 if (!elist->fLists){
1274 //second list is also only for 1 tree
1275 if (!strcmp(elist->fTreeName.Data(),fTreeName.Data()) &&
1276 !strcmp(elist->fFileName.Data(),fFileName.Data())){
1277 //same tree
1278 Long64_t n2 = elist->GetN();
1280 for (Int_t i=0; i<n2; i++){
1281 entry = (const_cast<TEntryList*>(elist))->GetEntry(i);
1282 Remove(entry);
1283 }
1284 } else {
1285 //different trees
1286 return;
1287 }
1288 } else {
1289 //second list has sublists, try to find one for the same tree as this list
1290 TIter next1(elist->GetLists());
1291 templist = nullptr;
1292 bool found = false;
1293 while ((templist = (TEntryList*)next1())){
1294 if (!strcmp(templist->fTreeName.Data(),fTreeName.Data()) &&
1295 !strcmp(templist->fFileName.Data(),fFileName.Data())){
1296 found = true;
1297 break;
1298 }
1299 }
1300 if (found) {
1302 }
1303 }
1304 } else {
1305 //this list has sublists
1307 templist = nullptr;
1308 Long64_t oldn=0;
1309 while ((templist = (TEntryList*)next2())){
1310 oldn = templist->GetN();
1311 templist->Subtract(elist);
1312 fN = fN - oldn + templist->GetN();
1313 }
1314 }
1315 return;
1316}
1317
1318////////////////////////////////////////////////////////////////////////////////
1319
1321{
1323 //eresult = elist1;
1324 // printf("internal in operator1\n");
1325 eresult.Print("all");
1326 eresult.Add(&elist2);
1327 // printf("internal in operator2\n");
1328 eresult.Print("all");
1329
1330 return eresult;
1331}
1332
1333////////////////////////////////////////////////////////////////////////////////
1334/// Relocate the file paths.
1335/// If `oldroot` is defined, replace `oldroot` with `newroot` in all file names,
1336/// i.e. `oldroot/re/st/of/the/path` will become `newroot`/re/st/of/the/path`.
1337/// If `oldroot` is null, the new path will be just `newroot/path`.
1338/// Relocation is mandatory to use the entry-list with the same dataset at a different
1339/// location (i.e. on a different cluster, machine or disks).
1340
1341Int_t TEntryList::RelocatePaths(const char *newroot, const char *oldroot)
1342{
1343 // At least newroot must be given
1344 if (!newroot || (newroot && strlen(newroot) <= 0)) {
1345 Warning("RelocatePaths", "the new location must be given!");
1346 return -1;
1347 }
1348
1349 if (strlen(GetName()) > 0)
1350 Info("RelocatePaths", "'%s': relocating paths '%s' to '%s'",
1351 GetName(), oldroot ? oldroot : "*", newroot);
1352
1353 Int_t nrl = 0, xnrl = 0;
1354 // Apply to all underlying lists, if any
1355 if (fLists) {
1356 TIter nxl(fLists);
1357 TEntryList *enl = nullptr;
1358 while ((enl = (TEntryList *) nxl())) {
1359 if ((xnrl = enl->RelocatePaths(newroot, oldroot)) < 0) {
1360 Warning("RelocatePaths", "problems relocating '%s'", enl->GetName());
1361 } else {
1362 nrl += xnrl;
1363 }
1364 }
1365 }
1366 // Apply to ourselves
1367 TString temp;
1368 Ssiz_t lo = 0;
1369 if (oldroot && (lo = strlen(oldroot)) > 0) {
1371 fFileName.Replace(0, lo, newroot);
1372 nrl++;
1373 }
1374 } else {
1375 Ssiz_t ilst = fFileName.Last('/');
1376 if (ilst != kNPOS) {
1378 } else {
1380 }
1381 nrl++;
1382 }
1383 if (fStringHash != 0) {
1384 temp.Form("%s%s", fTreeName.Data(), fFileName.Data());
1385 fStringHash = temp.Hash();
1386 }
1387
1388 // Done
1389 return nrl;
1390}
1391
1392////////////////////////////////////////////////////////////////////////////////
1393/// Relocate entry list 'enlnm' in file 'fn' replacing 'oldroot' with 'newroot' in
1394/// filenames. If 'enlnm' is null or '*' all entry lists in the file are relocated.
1395/// Relocation is mandatory to use the entry-list with the same dataset at a different
1396/// location (i.e. on a different cluster, machine or disks).
1397/// This function can be called as many times as need to reach the desired result.
1398/// The existing 'locations' can be checked qith TEntryList::Scan .
1399
1400Int_t TEntryList::Relocate(const char *fn,
1401 const char *newroot, const char *oldroot, const char *enlnm)
1402{
1403 // Open the file for updating
1404 TFile *fl = TFile::Open(fn, "UPDATE");
1405 if (!fl || (fl&& fl->IsZombie())) {
1406 ::Error("TEntryList::Relocate", "file '%s' cannot be open for updating", fn);
1407 return -1;
1408 }
1409
1410 Int_t nrl = 0;
1411 // Read the lists
1412 TString nm(enlnm);
1413 if (nm.IsNull()) nm = "*";
1414 TRegexp nmrg(nm, true);
1415 TIter nxk(fl->GetListOfKeys());
1416 TKey *key = nullptr;
1417 while ((key = (TKey *) nxk())) {
1418 if (!strcmp(key->GetClassName(), "TEntryList")) {
1419 TString knm(key->GetName());
1420 if (knm.Index(nmrg) != kNPOS) {
1421 TEntryList *enl = dynamic_cast<TEntryList *>(fl->Get(knm));
1422 if (enl) {
1423 Int_t xnrl = enl->RelocatePaths(newroot, oldroot);
1424 if (xnrl >= 0) {
1425 enl->Write(knm, TObject::kOverwrite);
1426 nrl += xnrl;
1427 } else {
1428 ::Error("TEntryList::Relocate", "problems relocating '%s' ...", enl->GetName());
1429 }
1430 }
1431 }
1432 }
1433 }
1434 // Close the file
1435 fl->Close();
1436 delete fl;
1437 // Done
1438 return nrl;
1439}
1440
1441////////////////////////////////////////////////////////////////////////////////
1442/// Get in 'c' the string in common at the beginning of 'a' and 'b'
1443///
1444/// Return:
1445/// - 0 a and b are not contained in each other, i.e. c != a && c != b
1446/// - 1 a is contained in b, i.e. c == a (includes a == empty)
1447/// - 2 b is contained in a, i.e. c == b (includes b == empty)
1448/// - 3 b is a, i.e. c == b == a (includes a == b == empty)
1449/// Auxiliary function for path scans.
1450
1452{
1453 if (a == b) {
1454 c = a;
1455 return 3;
1456 }
1457 if (a.IsNull()) {
1458 c = "";
1459 return 1;
1460 }
1461 if (b.IsNull()) {
1462 c = "";
1463 return 2;
1464 }
1465 bool ashort = (a.Length() > b.Length()) ? false : true;
1466 Ssiz_t len = (ashort) ? a.Length() : b.Length();
1467 Int_t lcom = 0;
1468 for (Int_t i = 0; i < len; i++) {
1469 if (a[i] != b[i]) break;
1470 lcom++;
1471 }
1472 if (lcom == len) {
1473 c = ashort ? a : b;
1474 return ashort ? 1 : 2;
1475 }
1476 c = a(0,lcom);
1477 // Done
1478 return 0;
1479}
1480
1481////////////////////////////////////////////////////////////////////////////////
1482/// Scan the paths to find the common roots. If 'roots' is defined, add
1483/// the found roots to the list as TObjStrings.
1484/// Return the number of roots found.
1485
1487{
1488 TList *xrl = roots ? roots : new TList;
1489
1490 Int_t nrl = 0;
1491 // Apply to all underlying lists, if any
1492 if (fLists) {
1493 TIter nxl(fLists);
1494 TEntryList *enl = nullptr;
1495 while ((enl = (TEntryList *) nxl()))
1496 nrl += enl->ScanPaths(xrl, false);
1497 }
1498 // Apply to ourselves
1499 bool newobjs = true;
1501 TObjString *objs = nullptr;
1502 TIter nxr(xrl);
1503 while ((objs = (TObjString *) nxr())) {
1504 Int_t rc = 0;
1505 if ((rc = GetCommonString(path, objs->GetString(), com)) != 2) {
1506 TUrl ucom(com);
1507 if (strlen(ucom.GetFile()) > 0 && strcmp(ucom.GetFile(), "/")) {
1508 objs->SetString(com.Data());
1509 newobjs = false;
1510 break;
1511 }
1512 }
1513 }
1514 if (newobjs) xrl->Add(new TObjString(path));
1515
1516 // Done
1517 nrl = xrl->GetSize();
1518 if (notify) {
1519 Printf(" * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ *");
1520 Printf(" * Entry-list: %s", GetName());
1521 Printf(" * %d common root paths found", nrl);
1522 nxr.Reset();
1523 while ((objs = (TObjString *) nxr())) {
1524 Printf(" * %s", objs->GetName());
1525 }
1526 Printf(" * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ *");
1527 }
1528
1529 if (xrl != roots) {
1530 xrl->SetOwner(true);
1531 SafeDelete(xrl);
1532 }
1533
1534 // Done
1535 return nrl;
1536}
1537
1538////////////////////////////////////////////////////////////////////////////////
1539/// Scan TEntryList in 'fn' to find the common parts of paths.
1540/// If 'roots' is defined, add the found roots to the list as TObjStrings.
1541/// Return the number of common root paths found.
1542
1543Int_t TEntryList::Scan(const char *fn, TList *roots)
1544{
1545 // Open the file for updating
1546 TFile *fl = TFile::Open(fn);
1547 if (!fl || (fl&& fl->IsZombie())) {
1548 ::Error("TEntryList::Relocate", "file '%s' cannot be open for reading", fn);
1549 return -1;
1550 }
1551
1552 Int_t nrs = 0;
1553 // Read the lists
1554 TIter nxk(fl->GetListOfKeys());
1555 TKey *key = nullptr;
1556 while ((key = (TKey *) nxk())) {
1557 if (!strcmp(key->GetClassName(), "TEntryList")) {
1558 TEntryList *enl = dynamic_cast<TEntryList *>(fl->Get(key->GetName()));
1559 if (enl) {
1560 nrs += enl->ScanPaths(roots);
1561 } else {
1562 ::Error("TEntryList::Scan", "object entry-list '%s' not found or not loadable!", key->GetName());
1563 }
1564 }
1565 }
1566 // Close the file
1567 fl->Close();
1568 delete fl;
1569
1570 // Done
1571 return nrs;
1572}
1573
1574////////////////////////////////////////////////////////////////////////////////
1575/// Custom streamer for class TEntryList to handle the different interpretation
1576/// of fFileName between version 1 and >1 .
1577
1579{
1580 if (b.IsReading()) {
1581 UInt_t R__s, R__c;
1582 Version_t R__v = b.ReadVersion(&R__s, &R__c);
1583 b.ReadClassBuffer(TEntryList::Class(), this, R__v, R__s, R__c);
1584 if (R__v <= 1) {
1585 // The filename contained also the protocol and host: this was dropped
1586 // in version > 1 to allow re-localization
1588 }
1589 } else {
1590 b.WriteClassBuffer(TEntryList::Class(), this);
1591 }
1592}
#define SafeDelete(p)
Definition RConfig.hxx:531
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
short Version_t
Class version identifier (short)
Definition RtypesCore.h:80
int Ssiz_t
String size (currently int)
Definition RtypesCore.h:82
unsigned long ULong_t
Unsigned long integer 4 bytes (unsigned long). Size depends on architecture.
Definition RtypesCore.h:70
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:132
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:84
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define gDirectory
Definition TDirectory.h:385
static Int_t GetCommonString(TString a, TString b, TString &c)
Get in 'c' the string in common at the beginning of 'a' and 'b'.
TEntryList operator||(TEntryList &elist1, TEntryList &elist2)
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
char name[80]
Definition TGX11.cxx:148
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:777
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2584
R__EXTERN TSystem * gSystem
Definition TSystem.h:582
Buffer base class used for serializing objects.
Definition TBuffer.h:43
Collection abstract base class.
Definition TCollection.h:65
Describe directory structure in memory.
Definition TDirectory.h:45
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
virtual TObject * Remove(TObject *)
Remove an object from the in-memory list.
Used by TEntryList to store the entry numbers.
A List of entry numbers in a TTree or TChain.
Definition TEntryList.h:26
virtual bool Enter(Long64_t entry, TTree *tree=nullptr)
Add entry #entry to the list.
bool fReapply
If true, TTree::Draw will 'reapply' the original cut.
Definition TEntryList.h:49
Long64_t fLastIndexQueried
! used to optimize GetEntry() function from a loop
Definition TEntryList.h:44
virtual TEntryList * GetEntryList(const char *treename, const char *filename, Option_t *opt="")
Return the entry list, corresponding to treename and filename By default, the filename is first tried...
virtual Int_t GetTreeNumber() const
Definition TEntryList.h:81
static TClass * Class()
TString fFileName
name of the file, where the tree is
Definition TEntryList.h:39
virtual void OptimizeStorage()
Checks if the array representation is more economical and if so, switches to it.
virtual TList * GetLists() const
Definition TEntryList.h:76
virtual Int_t Contains(Long64_t entry, TTree *tree=nullptr)
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 Int_t ScanPaths(TList *roots, bool notify=true)
Scan the paths to find the common roots.
virtual bool Remove(Long64_t entry, TTree *tree=nullptr)
Remove entry #entry from the list.
virtual void SetTree(const TTree *tree)
If a list for a tree with such name and filename exists, sets it as the current sublist If not,...
TDirectory * fDirectory
! Pointer to directory holding this tree
Definition TEntryList.h:48
virtual TDirectory * GetDirectory() const
Definition TEntryList.h:77
TObjArray * fBlocks
blocks with indices of passing events (TEntryListBlocks)
Definition TEntryList.h:35
virtual Long64_t GetEntryAndTree(Long64_t index, Int_t &treenum)
Return the index of "index"-th non-zero entry in the TTree or TChain and the # of the corresponding t...
virtual const char * GetFileName() const
Definition TEntryList.h:80
static Int_t Scan(const char *fn, TList *roots)
Scan TEntryList in 'fn' to find the common parts of paths.
virtual void DirectoryAutoAdd(TDirectory *)
Called by TKey and others to automatically add us to a directory when we are read from a file.
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 void SetDirectory(TDirectory *dir)
Add reference to directory dir. dir can be 0.
void EnterRange(Long64_t start, Long64_t end, TTree *tree=nullptr, UInt_t step=1U)
Enter all entries in a range in the TEntryList.
virtual void Reset()
Reset this list.
Int_t fNBlocks
number of TEntryListBlocks
Definition TEntryList.h:34
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().
void Streamer(TBuffer &) override
Custom streamer for class TEntryList to handle the different interpretation of fFileName between vers...
virtual Int_t RelocatePaths(const char *newloc, const char *oldloc=nullptr)
Relocate the file paths.
virtual const char * GetTreeName() const
Definition TEntryList.h:79
virtual Int_t Merge(TCollection *list)
Merge this list with the lists from the collection.
TEntryList * fCurrent
! currently filled entry list
Definition TEntryList.h:32
bool fShift
! true when some sub-lists don't correspond to trees (when the entry list is used as input in TChain)
Definition TEntryList.h:46
void Print(const Option_t *option="") const override
Print this list.
ULong_t fStringHash
! Hash value of a string of treename and filename
Definition TEntryList.h:40
static Int_t Relocate(const char *fn, const char *newroot, const char *oldroot=nullptr, const char *enlnm=nullptr)
Relocate entry list 'enlnm' in file 'fn' replacing 'oldroot' with 'newroot' in filenames.
TList * fLists
a list of underlying entry lists for each tree of a chain
Definition TEntryList.h:31
void GetFileName(const char *filename, TString &fn, bool *=nullptr)
To be able to re-localize the entry-list we identify the file by just the name and the anchor,...
~TEntryList() override
Destructor.
TString fTreeName
name of the tree
Definition TEntryList.h:38
void AddSubList(TEntryList *elist)
Add a sub entry list to the current list.
TEntryList()
default c-tor
virtual void Subtract(const TEntryList *elist)
Remove all the entries of this entry list, that are contained in elist.
virtual void Add(const TEntryList *elist)
Add 2 entry lists.
virtual Long64_t GetN() const
Definition TEntryList.h:78
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:3797
void Reset()
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
A doubly linked list.
Definition TList.h:38
TObject * After(const TObject *obj) const override
Returns the object after object obj.
Definition TList.cxx:460
void Add(TObject *obj) override
Definition TList.h:81
TObject * Last() const override
Return the last object in the list. Returns 0 when list is empty.
Definition TList.cxx:823
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:789
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:600
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
An array of TObjects.
Definition TObjArray.h:31
void Delete(Option_t *option="") override
Remove all objects from the array AND delete all heap based objects.
TObject * UncheckedAt(Int_t i) const
Definition TObjArray.h:90
void Add(TObject *obj) override
Definition TObjArray.h:68
Collectable string class.
Definition TObjString.h:28
@ kOverwrite
overwrite existing object with same name
Definition TObject.h:101
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:226
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1082
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:548
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1096
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1070
Regular expression class.
Definition TRegexp.h:31
Basic string class.
Definition TString.h:138
TString & Insert(Ssiz_t pos, const char *s)
Definition TString.h:672
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition TString.h:705
const char * Data() const
Definition TString.h:386
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition TString.cxx:938
void ToUpper()
Change string to upper case.
Definition TString.cxx:1202
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:634
Bool_t IsNull() const
Definition TString.h:424
UInt_t Hash(ECaseCompare cmp=kExact) const
Return hash value.
Definition TString.cxx:684
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2459
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2437
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:643
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1289
const char * pwd()
Definition TSystem.h:444
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1096
virtual const char * UnixPathName(const char *unixpathname)
Convert from a local pathname to a Unix pathname.
Definition TSystem.cxx:1077
virtual Bool_t IsAbsoluteFileName(const char *dir)
Return true if dir is an absolute pathname.
Definition TSystem.cxx:965
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1046
A TTree represents a columnar dataset.
Definition TTree.h:89
TDirectory * GetDirectory() const
Definition TTree.h:509
virtual TTree * GetTree() const
Definition TTree.h:604
virtual Long64_t LoadTree(Long64_t entry)
Set current entry.
Definition TTree.cxx:6584
This class represents a WWW compatible URL.
Definition TUrl.h:33
TCanvas * roots()
Definition roots.C:1