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#include "TROOT.h"
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{
177 if (fDirectory)
178 fDirectory->Append(this);
179 }
180}
181
182////////////////////////////////////////////////////////////////////////////////
183/// constructor with name and title, which also sets the tree
184
185TEntryList::TEntryList(const char *name, const char *title, const TTree *tree) : TNamed(name, title)
186{
188
191 if (fDirectory)
192 fDirectory->Append(this);
193 }
194}
195
196////////////////////////////////////////////////////////////////////////////////
197/// c-tor with name and title, which also sets the treename and the filename
198
199TEntryList::TEntryList(const char *name, const char *title, const char *treename, const char *filename)
200 : TNamed(name, title)
201{
203
206 if (fDirectory)
207 fDirectory->Append(this);
208 }
209}
210
211////////////////////////////////////////////////////////////////////////////////
212/// c-tor, which sets the tree
213
214TEntryList::TEntryList(const TTree *tree)
215{
216 SetTree(tree);
217
220 if (fDirectory)
221 fDirectory->Append(this);
222 }
223}
224
225////////////////////////////////////////////////////////////////////////////////
226/// copy c-tor
227
229 : TNamed(elist),
230 fNBlocks(elist.fNBlocks),
231 fN(elist.fN),
232 fEntriesToProcess(elist.fEntriesToProcess),
233 fTreeName(elist.fTreeName),
234 fFileName(elist.fFileName),
235 fStringHash(elist.fStringHash),
236 fTreeNumber(elist.fTreeNumber),
237 fShift(elist.fShift),
238 fReapply(elist.fReapply)
239{
240 if (elist.fLists){
241 fLists = new TList();
242 TEntryList *el1 = nullptr;
243 TEntryList *el2 = nullptr;
244 TIter next(elist.fLists);
245 while((el1 = (TEntryList*)next())){
246 el2 = new TEntryList(*el1);
247 if (el1==elist.fCurrent)
248 fCurrent = el2;
249 fLists->Add(el2);
250 }
251 } else {
252 if (elist.fBlocks){
253 TEntryListBlock *block1 = nullptr;
254 TEntryListBlock *block2 = nullptr;
255 //or just copy it as a TObjArray??
256 fBlocks = new TObjArray();
257 for (Int_t i=0; i<fNBlocks; i++){
261 }
262 }
263 fCurrent = this;
264 }
265}
266
267////////////////////////////////////////////////////////////////////////////////
268/// Destructor.
269
271{
272 if (fBlocks){
273 fBlocks->Delete();
274 delete fBlocks;
275 }
276 fBlocks = nullptr;
277 if (fLists){
278 fLists->Delete();
279 delete fLists;
280 }
281
282 fLists = nullptr;
283
284 if (fDirectory) fDirectory->Remove(this);
285 fDirectory = nullptr;
286
287}
288
289////////////////////////////////////////////////////////////////////////////////
290/// \brief Add 2 entry lists.
291///
292/// \param[in] elist The list that should be added to the current one.
293///
294/// \note If you are creating a TEntryList for a TChain and you would like to
295/// have a one to one mapping between the sub lists of the TEntryList and
296/// the sub trees in the TChain, please do not call this function but use
297/// TEntryList::AddSubList instead and pair it with a call to
298/// TChain::SetEntryList with option "sync". See the AddSubList function
299/// documentation for an example usage. This helps for example in a
300/// testing or benchmark scenario where a TChain holds multiple times the
301/// same tree in the same file. In that case, this function would not be
302/// be able to distinguish different sub entry lists that refer to the
303/// same treename and filename. Instead it would create a union of all the
304/// sub entry lists into one list.
305
306void TEntryList::Add(const TEntryList *elist)
307{
308 if (fN==0){
309 if (!fLists && fTreeName=="" && fFileName==""){
310 //this list is empty. copy the other list completely
311 fNBlocks = elist->fNBlocks;
312 fTreeName = elist->fTreeName;
313 fFileName = elist->fFileName;
314 fStringHash = elist->fStringHash;
315 fTreeNumber = elist->fTreeNumber;
318 fN = elist->fN;
319 if (elist->fLists){
320 fLists = new TList();
321 TEntryList *el1 = nullptr;
322 TEntryList *el2 = nullptr;
323 TIter next(elist->fLists);
324 while((el1 = (TEntryList*)next())){
325 el2 = new TEntryList(*el1);
326 if (el1==elist->fCurrent)
327 fCurrent = el2;
328 fLists->Add(el2);
329 }
330 } else {
331 if (elist->fBlocks){
332 TEntryListBlock *block1 = nullptr;
333 TEntryListBlock *block2 = nullptr;
334 fBlocks = new TObjArray();
335 for (Int_t i=0; i<fNBlocks; i++){
339 }
340 }
341 fCurrent = nullptr;
342 }
343 return;
344 }
345 }
346
347 if (!fLists){
348 if (!elist->fLists){
349 if (!strcmp(elist->fTreeName.Data(),fTreeName.Data()) && !strcmp(elist->fFileName.Data(),fFileName.Data())){
350 //entry lists are for the same tree
351 if (!elist->fBlocks)
352 //the other list is empty list
353 return;
354 if (!fBlocks){
355 //this entry list is empty
356 TEntryListBlock *block1 = nullptr;
357 TEntryListBlock *block2 = nullptr;
358 fNBlocks = elist->fNBlocks;
359 fN = elist->fN;
360 fBlocks = new TObjArray();
361 for (Int_t i=0; i<fNBlocks; i++){
365 }
366 return;
367 }
368 //both not empty, merge block by block
369 TEntryListBlock *block1=nullptr;
370 TEntryListBlock *block2=nullptr;
371 Int_t i;
372 Int_t nmin = std::min(fNBlocks, elist->fNBlocks);
374 for (i=0; i<nmin; i++){
377 nold = block1->GetNPassed();
378 nnew = block1->Merge(block2);
379 fN = fN - nold + nnew;
380 }
382 Int_t nmax = elist->fNBlocks;
383 for (i=nmin; i<nmax; i++){
387 fN+=block1->GetNPassed();
388 fNBlocks++;
389 }
390 }
393 } else {
394 //entry lists are for different trees. create a chain entry list with
395 //2 sub lists for the first and second entry lists
398 fLists = new TList();
399 TEntryList *el = new TEntryList();
400 el->fTreeName = fTreeName;
401 el->fFileName = fFileName;
402 el->fBlocks = fBlocks;
403 fBlocks = nullptr;
404 el->fNBlocks = fNBlocks;
405 el->fN = fN;
406 el->fLastIndexQueried = -1;
407 el->fLastIndexReturned = 0;
408 fLists->Add(el);
409 el = new TEntryList(*elist);
410 el->fLastIndexQueried = -1;
411 el->fLastIndexReturned = 0;
412 fLists->Add(el);
413 fN+=el->GetN();
414 fCurrent = nullptr;
415 }
416 } else {
417 //second list already has sublists. add one by one
418 TEntryList *el = nullptr;
419 TIter next(elist->fLists);
420 while ((el = (TEntryList*)next())){
421 Add(el);
422 }
423 fCurrent = nullptr;
424 }
425 } else {
426 //there are already some sublists in this list, just add another one
427 if (!elist->fLists){
428 //the other list doesn't have sublists
429 TIter next(fLists);
430 TEntryList *el = nullptr;
431 bool found = false;
432 while ((el = (TEntryList*)next())){
433 if (!strcmp(el->fTreeName.Data(), elist->fTreeName.Data()) &&
434 !strcmp(el->fFileName.Data(), elist->fFileName.Data())){
435 // if (el->fStringHash == elist->fStringHash){
436 //found a list for the same tree
437 Long64_t oldn = el->GetN();
438 el->Add(elist);
439 found = true;
440 fN = fN - oldn + el->GetN();
441 break;
442 }
443 }
444 if (!found){
445 el = new TEntryList(*elist);
446 el->fLastIndexQueried = -1;
447 el->fLastIndexReturned = 0;
448 fLists->Add(el);
449 fN+=el->GetN();
450 }
451 } else {
452 //add all sublists from the other list
453 TEntryList *el = nullptr;
454 TIter next(elist->fLists);
455 while ((el = (TEntryList*)next())){
456 Add(el);
457 }
458 fCurrent = nullptr;
459 }
460 if (fCurrent){
461 if (fCurrent->fBlocks){
464 block->ResetIndices();
467 }
468 }
469 fCurrent = nullptr;
470 }
471
472}
473
474////////////////////////////////////////////////////////////////////////////////
475/// \brief Add a sub entry list to the current list.
476/// \param[in] elist an entry list that should be added as a sub list of this list.
477///
478/// This function is specifically targeted at situations where there is a global
479/// TEntryList that should hold one or more sub TEntryList objects. For example,
480/// if one wants to create a one to one mapping between the sub entry lists and
481/// the trees in the files that make a TChain. Note that in such cases this
482/// configuration of the entry list should be used in pair with the option \p "sync"
483/// of the function TChain::SetEntryList
484///
485/// ~~~{.cpp}
486/// // Create a TChain with two files. Each contains a tree with 20 entries
487/// TChain chain{"entries"};
488/// chain.Add("file_20entries_1.root");
489/// chain.Add("file_20entries_2.root");
490///
491/// // Create a global, empty TEntryList.
492/// TEntryList elists;
493/// // Create two entry lists. Each one will be referring to a different tree in the chain
494/// TEntryList elist1{"","","entries","file_20entries_1.root"};
495/// TEntryList elist2{"","","entries","file_20entries_2.root"};
496///
497/// // Select the first ten entries from the first tree and all entries from the second
498/// for(auto entry = 0; entry < 10; entry++){
499/// elist1.Enter(entry);
500/// }
501/// for(auto entry = 0; entry < 20; entry++){
502/// elist2.Enter(entry);
503/// }
504///
505/// // Add sub entry lists to the global list
506/// elists.AddSubList(&elist1);
507/// elists.AddSubList(&elist2);
508///
509/// // Set the entry list in the chain. Note the usage of option "sync"
510/// chain.SetEntryList(&elists, "sync");
511/// ~~~
512
514
515 auto elistcopy = new TEntryList{*elist};
516
517 fN += elistcopy->fN;
518
519 if (!fLists){
520 fLists = new TList();
521 }
523}
524
525////////////////////////////////////////////////////////////////////////////////
526/// - When tree = 0, returns from the current list
527/// - When tree != 0, finds the list, corresponding to this tree
528/// - When tree is a chain, the entry is assumed to be global index and the local
529/// entry is recomputed from the treeoffset information of the chain
530
532{
533 if (!tree){
534 if (fBlocks) {
535 //this entry list doesn't contain any sub-lists
536 TEntryListBlock *block = nullptr;
538 if (nblock >= fNBlocks) return 0;
540 return block->Contains(entry-nblock*kBlockSize);
541 }
542 if (fLists) {
544 return fCurrent->Contains(entry);
545 }
546 return 0;
547 } else {
549 SetTree(tree->GetTree());
550 if (fCurrent)
552 }
553 return 0;
554
555}
556
557////////////////////////////////////////////////////////////////////////////////
558/// Called by TKey and others to automatically add us to a directory when we are read from a file.
559
561{
562 SetDirectory(dir);
563}
564
565////////////////////////////////////////////////////////////////////////////////
566/// Add entry \#entry to the list
567/// - When tree = 0, adds to the current list
568/// - When tree != 0, finds the list, corresponding to this tree
569/// - When tree is a chain, the entry is assumed to be global index and the local
570/// entry is recomputed from the treeoffset information of the chain
571
573{
574 if (!tree){
575 if (!fLists) {
576 if (!fBlocks) fBlocks = new TObjArray();
577 TEntryListBlock *block = nullptr;
579 if (nblock >= fNBlocks) {
580 if (fNBlocks>0){
582 if (!block) return false;
583 block->OptimizeStorage();
584 }
585 for (Int_t i=fNBlocks; i<=nblock; i++){
586 block = new TEntryListBlock();
587 fBlocks->Add(block);
588 }
589 fNBlocks = nblock+1;
590 }
592 if (block->Enter(entry-nblock*kBlockSize)) {
593 fN++;
594 return true;
595 }
596 } else {
597 //the entry in the current entry list
599 if (fCurrent->Enter(entry)) {
600 if (fLists)
601 fN++;
602 return true;
603 }
604 }
605 } else {
607 SetTree(tree->GetTree());
608 if (fCurrent){
609 if (fCurrent->Enter(localentry)) {
610 if (fLists)
611 fN++;
612 return true;
613 }
614 }
615 }
616 return false;
617
619
620bool TEntryList::Enter(Long64_t localentry, const char *treename, const char *filename)
621{
623 if (fCurrent) {
624 if (fCurrent->Enter(localentry)) {
625 if (fLists)
626 fN++;
627 return true;
628 }
629 }
630 return false;
631}
632
633/////////////////////////////////////////////////////////////////////////////
634/// \brief Enter all entries in a range in the TEntryList.
635/// \param[in] start starting entry to enter.
636/// \param[in] end ending entry to enter.
637/// \param[in] tree passed as is to TEntryList::Enter.
638/// \param[in] step step increase of the loop entering the entries.
639///
640/// This is a helper function that enters all entries between \p start
641/// (inclusive) and \p end (exclusive) to the TEntryList in a loop. It
642/// is useful also in PyROOT to avoid having to do the same in a Python loop.
643
644void TEntryList::EnterRange(Long64_t start, Long64_t end, TTree *tree, UInt_t step)
645{
646 for (auto entry = start; entry < end; entry += step) {
647 this->Enter(entry, tree);
648 }
649}
650
651////////////////////////////////////////////////////////////////////////////////
652/// Remove entry \#entry from the list
653/// - When tree = 0, removes from the current list
654/// - When tree != 0, finds the list, corresponding to this tree
655/// - When tree is a chain, the entry is assumed to be global index and the local
656/// entry is recomputed from the treeoffset information of the chain
657
659{
660 if (entry < 0)
661 return false;
662 if (!tree) {
663 if (!fLists) {
664 if (!fBlocks) return false;
665 TEntryListBlock *block = nullptr;
668 if (!block) return false;
670 if (block->Remove(blockindex)){
671 fN--;
672 return true;
673 }
674 } else {
676 if (fCurrent->Remove(entry)){
677 if (fLists)
678 fN--;
679 return true;
680 }
681 }
682 } else {
684 SetTree(tree->GetTree());
685 if (fCurrent){
686 if (fCurrent->Remove(localentry)) {
687 if (fLists)
688 fN--;
689 return true;
690 }
691 }
692 }
693 return false;
694}
695
696////////////////////////////////////////////////////////////////////////////////
697/// Return the number of the entry \#index of this TEntryList in the TTree or TChain
698/// See also Next().
699
701{
702
703 if ((index>=fN) || (index<0)) {
704 return -1;
705 }
706 if (index==fLastIndexQueried+1){
707 //in a loop
708 return Next();
709 } else {
710 if (fBlocks) {
711 TEntryListBlock *block = nullptr;
713 Int_t i=0;
714 while (total_passed<=index && i<fNBlocks){
716 total_passed+=block->GetNPassed();
717 i++;
718 }
719 i--;
720 total_passed-=block->GetNPassed();
723 block->ResetIndices();
725 }
726
728 Long64_t blockindex = block->GetEntry(localindex);
729 if (blockindex < 0) return -1;
732 fLastIndexReturned = res;
733 return res;
734 } else {
735 //find the corresponding list
737 TIter next(fLists);
739 Long64_t ntotal = 0;
740 if (fCurrent){
741 //reset all indices of the current list
742 if (fCurrent->fBlocks){
745 block->ResetIndices();
748 }
749 }
750 while ((templist = (TEntryList*)next())){
751 if (!fShift){
752 ntotal += templist->GetN();
753 } else {
754 if (templist->GetTreeNumber() >= 0)
755 ntotal += templist->GetN();
756 }
757 if (ntotal > index)
758 break;
759 }
761 if (!fCurrent) return -1;
765 return fLastIndexReturned;
766 }
767
768 }
769 return -1;
770}
771
772////////////////////////////////////////////////////////////////////////////////
773/// Return the index of "index"-th non-zero entry in the TTree or TChain
774/// and the # of the corresponding tree in the chain
775
777{
778//If shift is true, then when the requested entry is found in an entry list,
779//for which there is no corresponding tree in the chain, this list is not
780//taken into account, and entry from the next list with a tree is returned.
781//Example:
782//First sublist - 20 entries, second sublist - 5 entries, third sublist - 10 entries
783//Second sublist doesn't correspond to any trees of the chain
784//Then, when GetEntryAndTree(21, treenum, true) is called, first entry of the
785//third sublist will be returned
786
788 if (result < 0) {
789 treenum = -1;
790 return result;
791 }
792 R__ASSERT(fLists == nullptr || (fLists != nullptr && fCurrent != nullptr));
793 if (fCurrent)
795 else
797 if (treenum < 0)
798 return -1;
799
800 return result;
801}
802
803////////////////////////////////////////////////////////////////////////////////
804/// To be able to re-localize the entry-list we identify the file by just the
805/// name and the anchor, i.e. we drop protocol, host, options, ...
806/// The result in the form 'file#anchor' (or 'file', if no anchor is present)
807/// is saved in 'fn'.
808/// The function optionally (is 'local' is defined) checks file locality (i.e.
809/// protocol 'file://') returning the result in '*local' .
810
811void TEntryList::GetFileName(const char *filename, TString &fn, bool *local)
812{
813 TUrl u(filename, true);
814 if (local) *local = (!strcmp(u.GetProtocol(), "file")) ? true : false;
815 if (strlen(u.GetAnchor()) > 0) {
816 fn.Form("%s#%s", u.GetFile(), u.GetAnchor());
817 } else {
818 fn = u.GetFile();
819 }
820 // Done
821 return;
822}
823
824////////////////////////////////////////////////////////////////////////////////
825/// Return the entry list, corresponding to treename and filename
826/// By default, the filename is first tried as is, and then, if the corresponding list
827/// is not found, the filename is expanded to the absolute path, and compared again.
828/// To avoid it, use option "ne"
829
830TEntryList *TEntryList::GetEntryList(const char *treename, const char *filename, Option_t *opt)
831{
832 if (gDebug > 1)
833 Info("GetEntryList","tree: %s, file: %s",
834 (treename ? treename : "-"), (filename ? filename : "-"));
835
836 if (!treename || !filename) return nullptr;
837 TString option = opt;
838 option.ToUpper();
839 bool nexp = option.Contains("NE");
840
841 TString fn;
842 bool local;
844 if (nexp) local = false;
845
846 if (gDebug > 1)
847 Info("GetEntryList", "file: %s, local? %d", filename, local);
848
849 if (!fLists){
850 //there are no sublists
851 if (!strcmp(treename, fTreeName.Data()) && !(strcmp(fn.Data(), fFileName.Data()))){
852 return this;
853 } else {
854 //if the file is local, try the full name, unless "ne" option was specified
855 if (!nexp && local){
860 if (!strcmp(treename, fTreeName.Data()) && !(strcmp(fn.Data(), fFileName.Data())))
861 return this;
862 }
863 return nullptr;
864 }
865 }
866
868 stotal.Append(fn);
869 ULong_t newhash = stotal.Hash();
870
871 TIter next(fLists);
873 while ((templist = (TEntryList*)next())){
874 if (templist->fStringHash==0){
875 stotal = templist->fTreeName + templist->fFileName;
876 templist->fStringHash = stotal.Hash();
877 }
878 if (gDebug > 1)
879 Info("GetEntryList", "file: %s (fn: %s), hash: %lu, element hash: %lu",
880 filename, fn.Data(), newhash, templist->fStringHash);
881 if (newhash == templist->fStringHash){
882 if (!strcmp(templist->GetTreeName(), treename) && !strcmp(templist->GetFileName(), fn.Data())){
883 return templist;
884 }
885 }
886 }
887
888 //didn't find anything for this filename, try the full name too
889 if (!nexp && local){
896 stotal.Append(longname);
897 newhash = stotal.Hash();
898 next.Reset();
899 while ((templist = (TEntryList*)next())){
900 if (templist->fStringHash==0){
901 stotal = templist->fTreeName + templist->fFileName;
902 templist->fStringHash = stotal.Hash();
903 }
904 if (gDebug > 1)
905 Info("GetEntryList", "file: %s (longname: %s), hash: %lu, element hash: %lu",
906 filename, longname.Data(), newhash, templist->fStringHash);
907 if (newhash == templist->fStringHash){
908 if (templist->fTreeName == treename && templist->fFileName == longname){
909 return templist;
910 }
911 }
912 }
913 }
914 return nullptr;
915}
916
917////////////////////////////////////////////////////////////////////////////////
918/// Merge this list with the lists from the collection
919
921{
922 if (!list) return -1;
923 TIter next(list);
924 TEntryList *elist = nullptr;
925 while ((elist = (TEntryList*)next())) {
926 if (!elist->InheritsFrom(TEntryList::Class())) {
927 Error("Add","Attempt to add object of class: %s to a %s",elist->ClassName(),this->ClassName());
928 return -1;
929 }
930 Add(elist);
931 }
932 return 0;
933}
934
935////////////////////////////////////////////////////////////////////////////////
936/// Return the next non-zero entry index (next after fLastIndexQueried)
937/// this function is faster than GetEntry()
938
940{
942 if (fN == fLastIndexQueried+1 || fN==0){
943 return -1;
944 }
945 if (fBlocks){
948 result = current_block->Next();
949 if (result>=0) {
952 return fLastIndexReturned;
953 }
954 else {
955 while (result<0 && iblock<fNBlocks-1) {
956 current_block->ResetIndices();
957 iblock++;
959 current_block->ResetIndices();
960 result = current_block->Next();
961 }
962 if (result<0) {
965 return -1;
966 }
969
970 return fLastIndexReturned;
971 }
972 } else {
973 if (!fCurrent) {
975 if (!fCurrent) return 0;
976 if (fShift) {
977 while (fCurrent->GetTreeNumber()<0) {
979 if (!fCurrent) return 0;
980 }
981 }
982 }
983 result = fCurrent->Next();
984 if (result>=0) {
987 return result;
988 } else {
989 if (fCurrent){
990 //reset all indices of the current list
991 if (fCurrent->fBlocks){
994 block->ResetIndices();
997 }
998 }
999
1000 //find the list with the next non-zero entry
1001 while (result<0 && fCurrent!=((TEntryList*)fLists->Last())){
1002 if (!fCurrent) return 0;
1006 // fCurrent is guarantee to be non-zero because it is not the 'last'
1007 // element of the list.
1008 if (!fCurrent) return 0;
1009 if (!fShift)
1010 result = fCurrent->Next();
1011 else {
1012 if (fCurrent->GetTreeNumber() >= 0)
1013 result = fCurrent->Next();
1014 }
1015 }
1018 return result;
1019 }
1020 }
1021}
1022
1023////////////////////////////////////////////////////////////////////////////////
1024/// Checks if the array representation is more economical and if so, switches to it
1025
1027{
1028 if (fBlocks){
1029 TEntryListBlock *block = nullptr;
1030 for (Int_t i=0; i<fNBlocks; i++){
1032 block->OptimizeStorage();
1033 }
1034 }
1035}
1036
1037////////////////////////////////////////////////////////////////////////////////
1038/// Print this list
1039/// - option = "" - default - print the name of the tree and file
1040/// - option = "all" - print all the entry numbers
1041
1042void TEntryList::Print(const Option_t* option) const
1043{
1044 TString opt = option;
1045 opt.ToUpper();
1046 if (fBlocks) {
1047 Printf("%s %s %lld", fTreeName.Data(), fFileName.Data(), fN);
1048 if (opt.Contains("A")){
1049 TEntryListBlock* block = nullptr;
1050 for (Int_t i=0; i<fNBlocks; i++){
1052 Int_t shift = i*kBlockSize;
1053 block->PrintWithShift(shift);
1054 }
1055 }
1056 }
1057 else {
1058 TEntryList *elist = nullptr;
1059 if (fN>0){
1060 TIter next(fLists);
1061 while((elist = (TEntryList*)next())){
1062 elist->Print(option);
1063 }
1064 } else {
1065 if (!fLists) Printf("%s %s %lld", fTreeName.Data(), fFileName.Data(), fN);
1066 else {
1067 TIter next(fLists);
1068 while ((elist = (TEntryList*)next())){
1069 Printf("%s %s %lld", elist->GetTreeName(), elist->GetFileName(), elist->GetN());
1070 }
1071 }
1072 }
1073 }
1074}
1075
1076////////////////////////////////////////////////////////////////////////////////
1077/// Reset this list
1078
1079void TEntryList::Reset()
1080{
1081 //Maybe not delete, but just reset the number of blocks to 0????
1082
1083 if (fBlocks){
1084 fBlocks->Delete();
1085 delete fBlocks;
1086 fBlocks = nullptr;
1087 }
1088 if (fLists){
1089 if (!((TEntryList*)fLists->First())->GetDirectory()){
1090 fLists->Delete();
1091 }
1092 delete fLists;
1093 fLists = nullptr;
1094 }
1095 fCurrent = nullptr;
1096 fBlocks = nullptr;
1097 fNBlocks = 0;
1098 fN = 0;
1099 fTreeName = "";
1100 fFileName = "";
1101 fStringHash = 0;
1102 fTreeNumber = -1;
1103 fLastIndexQueried = -1;
1105 fReapply = false;
1106}
1107
1108////////////////////////////////////////////////////////////////////////////////
1109/// Add reference to directory dir. dir can be 0.
1110
1112{
1113 if (fDirectory == dir) return;
1114 if (fDirectory) fDirectory->Remove(this);
1115 fDirectory = dir;
1116 if (fDirectory) fDirectory->Append(this);
1117}
1118
1119////////////////////////////////////////////////////////////////////////////////
1120/// If a list for a tree with such name and filename exists, sets it as the current sublist
1121/// If not, creates this list and sets it as the current sublist
1122///
1123/// ! the filename is taken as provided, no extensions to full path or url !
1124
1125void TEntryList::SetTree(const char *treename, const char *filename)
1126{
1127 TEntryList *elist = nullptr;
1128
1129 TString fn;
1131
1133 stotal.Append(fn.Data());
1134 //printf("setting tree %s\n", stotal.Data());
1135 ULong_t newhash = stotal.Hash();
1136 if (fLists) {
1137 //find the corresponding entry list and make it current
1139 if (fCurrent->fStringHash == 0){
1141 fCurrent->fStringHash = stotal.Hash();
1142 }
1143 if (newhash == fCurrent->fStringHash){
1144 //this list is current
1146 return;
1147 }
1148 }
1149 TIter next(fLists);
1150 while ((elist = (TEntryList*)next())){
1151 if (newhash == elist->fStringHash){
1152 if (elist->fTreeName == treename && elist->fFileName == fn.Data()) {
1153 //the current entry list was changed. reset the fLastIndexQueried,
1154 //so that Next() doesn't start with the wrong current list
1155 //Also, reset those indices in the previously current list
1156 if (fCurrent->fBlocks){
1159 block->ResetIndices();
1162 }
1163 fCurrent = elist;
1164 fLastIndexQueried = -3;
1165 return;
1166 }
1167 }
1168 }
1169 //didn't find an entry list for this tree, create a new one
1170 elist = new TEntryList("", "", treename, fn.Data());
1171 if (elist->GetDirectory()) {
1172 //sub lists are not added to the current directory
1173 elist->GetDirectory()->Remove(elist);
1174 elist->SetDirectory(nullptr);
1175 }
1176 fLists->Add(elist);
1177 fCurrent = elist;
1178 return;
1179 } else {
1180 if (fN==0 && fTreeName=="" && fFileName==""){
1181 //this is the first tree set to this list
1183 fFileName = fn;
1185 //fStringHash = stotal.Hash();
1187 fCurrent = this;
1188 } else {
1189 if (fStringHash == 0){
1191 fStringHash = stotal.Hash();
1192 }
1193 if (newhash != fStringHash){
1194 //we have a chain and already have an entry list for the first tree
1195 //move the first entry list to the fLists
1196 fLists = new TList();
1197 elist = new TEntryList();
1198 elist->fTreeName = fTreeName;
1199 elist->fFileName = fFileName;
1200 elist->fStringHash = fStringHash;
1201 elist->fN = fN;
1202 elist->fTreeNumber = fTreeNumber;
1203 elist->fBlocks = fBlocks;
1204 fBlocks = nullptr;
1205 elist->fNBlocks = fNBlocks;
1206 fLists->Add(elist);
1207 elist = new TEntryList("", "", treename, fn.Data());
1208 if (elist->GetDirectory()) {
1209 //sub lists are not added to the current directory
1210 elist->GetDirectory()->Remove(elist);
1211 elist->SetDirectory(nullptr);
1212 }
1213 fLists->Add(elist);
1214 fCurrent = elist;
1215 //the current entry list was changed. reset the fLastIndexQueried,
1216 //so that Next() doesn't start with the wrong current list
1217 fLastIndexQueried = -3;
1218
1219 }
1220 else {
1221 //same tree as in the current entry list, don't do anything
1222 return;
1223 }
1224 }
1225 }
1226}
1227
1228////////////////////////////////////////////////////////////////////////////////
1229/// If a list for a tree with such name and filename exists, sets it as the current sublist
1230/// If not, creates this list and sets it as the current sublist
1231/// The name of the file, where the tree is, is taken as
1232/// `tree->GetTree()->GetCurrentFile()->GetName()`, and then expanded either to the absolute path,
1233/// or to full url. If, for some reason, you want to provide
1234/// the filename in a different format, use SetTree(const char *treename, const char *filename),
1235/// where the filename is taken "as is".
1236
1237void TEntryList::SetTree(const TTree *tree)
1238{
1239 if (!tree) return;
1240 auto thisTree = tree->GetTree();
1241 if (!thisTree) return;
1242
1244 if (tree->GetDirectory()->InheritsFrom("TFile")) {
1245 treename = thisTree->GetName();
1246 } else {
1247 treename = TString::Format("%s/%s",tree->GetDirectory()->GetName(),thisTree->GetName());
1248 }
1249
1251 if (tree->GetTree()->GetCurrentFile()){
1252 filename = tree->GetTree()->GetCurrentFile()->GetName();
1253 TUrl url(filename.Data(), true);
1254 if (!strcmp(url.GetProtocol(), "file")){
1255 filename = url.GetFile(); // Get the file part, excluding the anchor, then expand
1260 url.SetFile(filename);
1261 }
1262 filename = url.GetUrl();
1263 } else {
1264 //memory-resident
1265 filename = "";
1266 }
1268
1269}
1270
1271////////////////////////////////////////////////////////////////////////////////
1272/// Remove all the entries of this entry list, that are contained in elist
1273
1274void TEntryList::Subtract(const TEntryList *elist)
1275{
1276 TEntryList *templist = nullptr;
1277 if (!fLists){
1278 if (!fBlocks) return;
1279 //check if lists are for the same tree
1280 if (!elist->fLists){
1281 //second list is also only for 1 tree
1282 if (!strcmp(elist->fTreeName.Data(),fTreeName.Data()) &&
1283 !strcmp(elist->fFileName.Data(),fFileName.Data())){
1284 //same tree
1285 Long64_t n2 = elist->GetN();
1287 for (Int_t i=0; i<n2; i++){
1288 entry = (const_cast<TEntryList*>(elist))->GetEntry(i);
1289 Remove(entry);
1290 }
1291 } else {
1292 //different trees
1293 return;
1294 }
1295 } else {
1296 //second list has sublists, try to find one for the same tree as this list
1297 TIter next1(elist->GetLists());
1298 templist = nullptr;
1299 bool found = false;
1300 while ((templist = (TEntryList*)next1())){
1301 if (!strcmp(templist->fTreeName.Data(),fTreeName.Data()) &&
1302 !strcmp(templist->fFileName.Data(),fFileName.Data())){
1303 found = true;
1304 break;
1305 }
1306 }
1307 if (found) {
1309 }
1310 }
1311 } else {
1312 //this list has sublists
1314 templist = nullptr;
1315 Long64_t oldn=0;
1316 while ((templist = (TEntryList*)next2())){
1317 oldn = templist->GetN();
1318 templist->Subtract(elist);
1319 fN = fN - oldn + templist->GetN();
1320 }
1321 }
1322 return;
1323}
1324
1325////////////////////////////////////////////////////////////////////////////////
1326
1328{
1330 //eresult = elist1;
1331 // printf("internal in operator1\n");
1332 eresult.Print("all");
1333 eresult.Add(&elist2);
1334 // printf("internal in operator2\n");
1335 eresult.Print("all");
1336
1337 return eresult;
1338}
1339
1340////////////////////////////////////////////////////////////////////////////////
1341/// Relocate the file paths.
1342/// If `oldroot` is defined, replace `oldroot` with `newroot` in all file names,
1343/// i.e. `oldroot/re/st/of/the/path` will become `newroot`/re/st/of/the/path`.
1344/// If `oldroot` is null, the new path will be just `newroot/path`.
1345/// Relocation is mandatory to use the entry-list with the same dataset at a different
1346/// location (i.e. on a different cluster, machine or disks).
1347
1348Int_t TEntryList::RelocatePaths(const char *newroot, const char *oldroot)
1349{
1350 // At least newroot must be given
1351 if (!newroot || (newroot && strlen(newroot) <= 0)) {
1352 Warning("RelocatePaths", "the new location must be given!");
1353 return -1;
1354 }
1355
1356 if (strlen(GetName()) > 0)
1357 Info("RelocatePaths", "'%s': relocating paths '%s' to '%s'",
1358 GetName(), oldroot ? oldroot : "*", newroot);
1359
1360 Int_t nrl = 0, xnrl = 0;
1361 // Apply to all underlying lists, if any
1362 if (fLists) {
1363 TIter nxl(fLists);
1364 TEntryList *enl = nullptr;
1365 while ((enl = (TEntryList *) nxl())) {
1366 if ((xnrl = enl->RelocatePaths(newroot, oldroot)) < 0) {
1367 Warning("RelocatePaths", "problems relocating '%s'", enl->GetName());
1368 } else {
1369 nrl += xnrl;
1370 }
1371 }
1372 }
1373 // Apply to ourselves
1374 TString temp;
1375 Ssiz_t lo = 0;
1376 if (oldroot && (lo = strlen(oldroot)) > 0) {
1378 fFileName.Replace(0, lo, newroot);
1379 nrl++;
1380 }
1381 } else {
1382 Ssiz_t ilst = fFileName.Last('/');
1383 if (ilst != kNPOS) {
1385 } else {
1387 }
1388 nrl++;
1389 }
1390 if (fStringHash != 0) {
1391 temp.Form("%s%s", fTreeName.Data(), fFileName.Data());
1392 fStringHash = temp.Hash();
1393 }
1394
1395 // Done
1396 return nrl;
1397}
1398
1399////////////////////////////////////////////////////////////////////////////////
1400/// Relocate entry list 'enlnm' in file 'fn' replacing 'oldroot' with 'newroot' in
1401/// filenames. If 'enlnm' is null or '*' all entry lists in the file are relocated.
1402/// Relocation is mandatory to use the entry-list with the same dataset at a different
1403/// location (i.e. on a different cluster, machine or disks).
1404/// This function can be called as many times as need to reach the desired result.
1405/// The existing 'locations' can be checked qith TEntryList::Scan .
1406
1407Int_t TEntryList::Relocate(const char *fn,
1408 const char *newroot, const char *oldroot, const char *enlnm)
1409{
1410 // Open the file for updating
1411 TFile *fl = TFile::Open(fn, "UPDATE");
1412 if (!fl || (fl&& fl->IsZombie())) {
1413 ::Error("TEntryList::Relocate", "file '%s' cannot be open for updating", fn);
1414 return -1;
1415 }
1416
1417 Int_t nrl = 0;
1418 // Read the lists
1419 TString nm(enlnm);
1420 if (nm.IsNull()) nm = "*";
1421 TRegexp nmrg(nm, true);
1422 TIter nxk(fl->GetListOfKeys());
1423 TKey *key = nullptr;
1424 while ((key = (TKey *) nxk())) {
1425 if (!strcmp(key->GetClassName(), "TEntryList")) {
1426 TString knm(key->GetName());
1427 if (knm.Index(nmrg) != kNPOS) {
1428 TEntryList *enl = dynamic_cast<TEntryList *>(fl->Get(knm));
1429 if (enl) {
1430 Int_t xnrl = enl->RelocatePaths(newroot, oldroot);
1431 if (xnrl >= 0) {
1432 enl->Write(knm, TObject::kOverwrite);
1433 nrl += xnrl;
1434 } else {
1435 ::Error("TEntryList::Relocate", "problems relocating '%s' ...", enl->GetName());
1436 }
1437 }
1438 }
1439 }
1440 }
1441 // Close the file
1442 fl->Close();
1443 delete fl;
1444 // Done
1445 return nrl;
1446}
1447
1448////////////////////////////////////////////////////////////////////////////////
1449/// Get in 'c' the string in common at the beginning of 'a' and 'b'
1450///
1451/// Return:
1452/// - 0 a and b are not contained in each other, i.e. c != a && c != b
1453/// - 1 a is contained in b, i.e. c == a (includes a == empty)
1454/// - 2 b is contained in a, i.e. c == b (includes b == empty)
1455/// - 3 b is a, i.e. c == b == a (includes a == b == empty)
1456/// Auxiliary function for path scans.
1457
1459{
1460 if (a == b) {
1461 c = a;
1462 return 3;
1463 }
1464 if (a.IsNull()) {
1465 c = "";
1466 return 1;
1467 }
1468 if (b.IsNull()) {
1469 c = "";
1470 return 2;
1471 }
1472 bool ashort = (a.Length() > b.Length()) ? false : true;
1473 Ssiz_t len = (ashort) ? a.Length() : b.Length();
1474 Int_t lcom = 0;
1475 for (Int_t i = 0; i < len; i++) {
1476 if (a[i] != b[i]) break;
1477 lcom++;
1478 }
1479 if (lcom == len) {
1480 c = ashort ? a : b;
1481 return ashort ? 1 : 2;
1482 }
1483 c = a(0,lcom);
1484 // Done
1485 return 0;
1486}
1487
1488////////////////////////////////////////////////////////////////////////////////
1489/// Scan the paths to find the common roots. If 'roots' is defined, add
1490/// the found roots to the list as TObjStrings.
1491/// Return the number of roots found.
1492
1494{
1495 TList *xrl = roots ? roots : new TList;
1496
1497 Int_t nrl = 0;
1498 // Apply to all underlying lists, if any
1499 if (fLists) {
1500 TIter nxl(fLists);
1501 TEntryList *enl = nullptr;
1502 while ((enl = (TEntryList *) nxl()))
1503 nrl += enl->ScanPaths(xrl, false);
1504 }
1505 // Apply to ourselves
1506 bool newobjs = true;
1508 TObjString *objs = nullptr;
1509 TIter nxr(xrl);
1510 while ((objs = (TObjString *) nxr())) {
1511 Int_t rc = 0;
1512 if ((rc = GetCommonString(path, objs->GetString(), com)) != 2) {
1513 TUrl ucom(com);
1514 if (strlen(ucom.GetFile()) > 0 && strcmp(ucom.GetFile(), "/")) {
1515 objs->SetString(com.Data());
1516 newobjs = false;
1517 break;
1518 }
1519 }
1520 }
1521 if (newobjs) xrl->Add(new TObjString(path));
1522
1523 // Done
1524 nrl = xrl->GetSize();
1525 if (notify) {
1526 Printf(" * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ *");
1527 Printf(" * Entry-list: %s", GetName());
1528 Printf(" * %d common root paths found", nrl);
1529 nxr.Reset();
1530 while ((objs = (TObjString *) nxr())) {
1531 Printf(" * %s", objs->GetName());
1532 }
1533 Printf(" * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ *");
1534 }
1535
1536 if (xrl != roots) {
1537 xrl->SetOwner(true);
1538 SafeDelete(xrl);
1539 }
1540
1541 // Done
1542 return nrl;
1543}
1544
1545////////////////////////////////////////////////////////////////////////////////
1546/// Scan TEntryList in 'fn' to find the common parts of paths.
1547/// If 'roots' is defined, add the found roots to the list as TObjStrings.
1548/// Return the number of common root paths found.
1549
1550Int_t TEntryList::Scan(const char *fn, TList *roots)
1551{
1552 // Open the file for updating
1553 TFile *fl = TFile::Open(fn);
1554 if (!fl || (fl&& fl->IsZombie())) {
1555 ::Error("TEntryList::Relocate", "file '%s' cannot be open for reading", fn);
1556 return -1;
1557 }
1558
1559 Int_t nrs = 0;
1560 // Read the lists
1561 TIter nxk(fl->GetListOfKeys());
1562 TKey *key = nullptr;
1563 while ((key = (TKey *) nxk())) {
1564 if (!strcmp(key->GetClassName(), "TEntryList")) {
1565 TEntryList *enl = dynamic_cast<TEntryList *>(fl->Get(key->GetName()));
1566 if (enl) {
1567 nrs += enl->ScanPaths(roots);
1568 } else {
1569 ::Error("TEntryList::Scan", "object entry-list '%s' not found or not loadable!", key->GetName());
1570 }
1571 }
1572 }
1573 // Close the file
1574 fl->Close();
1575 delete fl;
1576
1577 // Done
1578 return nrs;
1579}
1580
1581////////////////////////////////////////////////////////////////////////////////
1582/// Custom streamer for class TEntryList to handle the different interpretation
1583/// of fFileName between version 1 and >1 .
1584
1586{
1587 if (b.IsReading()) {
1588 UInt_t R__s, R__c;
1589 Version_t R__v = b.ReadVersion(&R__s, &R__c);
1590 b.ReadClassBuffer(TEntryList::Class(), this, R__v, R__s, R__c);
1591 if (R__v <= 1) {
1592 // The filename contained also the protocol and host: this was dropped
1593 // in version > 1 to allow re-localization
1595 }
1596 } else {
1597 b.WriteClassBuffer(TEntryList::Class(), this);
1598 }
1599}
#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:792
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:6606
This class represents a WWW compatible URL.
Definition TUrl.h:33
bool ObjectAutoRegistrationEnabled()
Test whether objects in this thread auto-register themselves, e.g.
Definition TROOT.cxx:776
TCanvas * roots()
Definition roots.C:1