Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
TEntryListArray.cxx
Go to the documentation of this file.
1// @(#)root/tree:$Id$
2// Author: Bruno Lenzi 12/07/2011
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 TEntryListArray
13\ingroup tree
14
15A list of entries and subentries in a TTree or TChain.
16
17TEntryListArray is an extension of TEntryList, used to hold selected entries and
18subentries (sublists) for when the user has a TTree with containers (vectors, arrays, ...).
19
20## Usage with TTree::Draw to select entries and subentries
21
22### To fill a list elist
23~~~ {.cpp}
24 tree->Draw(">> elist", "x > 0", "entrylistarray");`
25~~~
26### To use a list to select entries and subentries
27~~~ {.cpp}
28 tree->SetEntryList(elist);
29 tree->Draw("y");
30 tree->Draw("z");
31~~~
32Its main purpose is to improve the performance of a code that needs to apply
33complex cuts on TTree::Draw multiple times. After the first call above to
34TTree::Draw, a TEntryListArray is created and filled with the entries and the
35indices of the arrays that satisfied the selection cut (x > 0). In the subsequent
36calls to TTree::Draw, only these entries / subentries are used to fill histograms.
37
38## About the class
39
40The class derives from TEntryList and can be used basically in the same way.
41This same class is used to keep entries and subentries, so there are two types of
42TEntryListArray's:
43
441. The ones that only hold subentries
45 - fEntry is set to the entry# for which the subentries correspond
46 - fSubLists must be 0
472. The ones that hold entries and eventually lists with subentries in fSubLists.
48 - fEntry = -1 for those
49 - If there are no sublists for a given entry, all the subentries will be used
50 in the selection
51
52## Additions with respect to TEntryList
53
541. Data members:
55 - fSubLists: a container to hold the sublists
56 - fEntry: the entry number if the list is used to hold subentries
57 - fLastSubListQueried and fSubListIter: a pointer to the last sublist queried
58 and an iterator to resume the loop from the last sublist queried (to speed up
59 selection and insertion in TTree::Draw)
602. Public methods:
61 - Contains, Enter and Remove with subentry as argument
62 - GetSubListForEntry: to return the sublist corresponding to the given entry
633. Protected methods:
64 - AddEntriesAndSubLists: called by Add when adding two TEntryList arrays with sublists
65 - ConvertToTEntryListArray: convert TEntryList to TEntryListArray
66 - RemoveSubList: to remove the given sublist
67 - RemoveSubListForEntry: to remove the sublist corresponding to the given entry
68 - SetEntry: to get / set a sublist for the given entry
69*/
70
71#include "TEntryListArray.h"
72#include "TEntryListBlock.h"
73#include "TTree.h"
74#include "TList.h"
75#include <iostream>
76
77
78////////////////////////////////////////////////////////////////////////////////
79/// Initialize data members, called by Reset
80
82{
83 fSubLists = nullptr;
84 fEntry = -1;
85 fLastSubListQueried = nullptr;
86 fSubListIter = nullptr;
87}
88
89////////////////////////////////////////////////////////////////////////////////
90/// Default c-tor
91
95
96////////////////////////////////////////////////////////////////////////////////
97/// c-tor with name and title
98
99TEntryListArray::TEntryListArray(const char *name, const char *title): TEntryList(name, title), fSubLists(nullptr), fEntry(-1), fLastSubListQueried(nullptr), fSubListIter(nullptr)
100{
101}
102
103////////////////////////////////////////////////////////////////////////////////
104///constructor with name and title, which also sets the tree
105
106TEntryListArray::TEntryListArray(const char *name, const char *title, const TTree *tree): TEntryList(name, title, tree), fSubLists(nullptr), fEntry(-1), fLastSubListQueried(nullptr), fSubListIter(nullptr)
107{
108}
109
110////////////////////////////////////////////////////////////////////////////////
111/// c-tor with name and title, which also sets the treename and the filename
112
113TEntryListArray::TEntryListArray(const char *name, const char *title, const char *treename, const char *filename): TEntryList(name, title, treename, filename), fSubLists(nullptr), fEntry(-1), fLastSubListQueried(nullptr), fSubListIter(nullptr)
114{
115}
116
117////////////////////////////////////////////////////////////////////////////////
118/// c-tor, which sets the tree
119
121{
122}
123
124////////////////////////////////////////////////////////////////////////////////
125/// Copy c-tor
126
128{
129 fEntry = elist.fEntry;
130 Add(&elist);
131}
132
133////////////////////////////////////////////////////////////////////////////////
134/// c-tor, from TEntryList
135
137{
138}
139
140////////////////////////////////////////////////////////////////////////////////
141/// d-tor
142
144{
145 if (fSubLists) {
146 fSubLists->Delete();
147 delete fSubLists;
148 }
149 fSubLists = nullptr;
150 delete fSubListIter;
151 fSubListIter = nullptr;
152}
153
154////////////////////////////////////////////////////////////////////////////////
155/// Add 2 entry lists
156
158{
159 if (!elist) return;
160
161 if (fEntry != -1) {
162 TEntryList::Add(elist);
163 return;
164 }
165
166 // Include in this list all the trees present in elist, so the sublists can be added
167 // This would happen in any case when calling TEntryList::Add
168 if (elist->GetLists()) { // the other list has lists to hold multiple trees, add one by one
169 TIter next(elist->GetLists());
170 const TEntryList *e = nullptr;
171 while ((e = (const TEntryList*)next())) {
172 SetTree(e->GetTreeName(), e->GetFileName());
173 }
174 } else {
175 SetTree(elist->GetTreeName(), elist->GetFileName());
176 }
177
179}
180
181////////////////////////////////////////////////////////////////////////////////
182/// The method that really adds two entry lists with sublists
183/// If lists are split (fLists != 0), look for the ones whose trees match and call the method for those lists.
184/// Add first the sublists, and then use TEntryList::Add to deal with the entries
185
187{
188 // WARNING: cannot call TEntryList::Add in the beginning:
189 // - Need to know which entries are present in each list when adding the sublists
190 // - TEL::Add is recursive, so it will call this guy after the first iteration
191
192 // Add to the entries and sublists of this list, the ones from the other list
193 if (!elist) return;
194
195 if (fLists) { // This list is split
196 TEntryListArray* e = nullptr;
197 TIter next(fLists);
198 fN = 0; // reset fN to set it to the sum of fN in each list
199 // Only need to do it here and the next condition will be called only from here
200 while ((e = (TEntryListArray*) next())) {
201 e->AddEntriesAndSubLists(elist);
202 fN += e->GetN();
203 }
204 } else if (elist->GetLists()) { // The other list is split --> will be called only from the previous if
205 TIter next(elist->GetLists());
206 TEntryList *e = nullptr;
207 while ((e = (TEntryList*) next())) {
209 }
210 } else { // None of the lists are split
211 if (strcmp(elist->GetTreeName(), fTreeName.Data()) || strcmp(elist->GetFileName(), fFileName.Data()))
212 return; // Lists are for different trees
213 const TEntryListArray *elist_array = dynamic_cast< const TEntryListArray *>(elist);
214 if (!fSubLists && (!elist_array || !elist_array->GetSubLists())) { // no sublists in neither
215 TEntryList::Add(elist);
216 return;
217 }
218 // Deal with the sublists: Loop over both fSubLists
219 // - If the sublists are for the same entry, Add the sublists
220 // - For sublists only in this list, check if entry is in elist, and remove the sublist if so
221 // - For sublists only in the other list, insert them in fSubLists
222 if (!fSubLists && elist_array->GetSubLists()) {
223 fSubLists = new TList();
224 }
225 TEntryListArray *el1;
226 const TEntryListArray *el2;
227 TCollection *other_sublists = nullptr;
228 if (elist_array) {
229 other_sublists = elist_array->GetSubLists();
230 }
231 TIter next1(fSubLists);
232 TIter next2(other_sublists); // should work even if elist->fSubLists is null
233
234 for (el1 = (TEntryListArray*) next1(), el2 = (const TEntryListArray*) next2(); el1 || el2;) {
235 if (el1 && el2 && el1->fEntry == el2->fEntry) { // sublists for the same entry, Add them
236 el1->TEntryList::Add(el2);
237 el1 = (TEntryListArray*) next1();
238 el2 = (const TEntryListArray*) next2();
239 } else if (el1 && (!el2 || el1->fEntry < el2->fEntry)) { // el1->fEntry is not in elist->fSubLists
240 if ((const_cast<TEntryList*>(elist))->Contains(el1->fEntry)) {
241 RemoveSubList(el1);
242 }
243 el1 = (TEntryListArray*) next1();
244 } else { // el2->fEntry is not in fSubLists --> make a copy and add it
245 if (!Contains(el2->fEntry)) {
246 if (!el1) {
247 fSubLists->AddLast(new TEntryListArray(*el2));
248 } else {
249 fSubLists->AddBefore(el1, new TEntryListArray(*el2));
250 }
251 }
252 el2 = (const TEntryListArray*) next2();
253 }
254 }
255 TEntryList::Add(elist);
256 }
257}
258
259////////////////////////////////////////////////////////////////////////////////
260/// - When tree = 0, returns from the current list
261/// - When tree != 0, finds the list corresponding to this tree
262/// - When tree is a chain, the entry is assumed to be global index and the local
263///
264/// entry is recomputed from the treeoffset information of the chain
265/// When subentry != -1, return true if the enter is present and not split
266/// or if the subentry list is found and contains \#subentry
267
269{
270
271
272 if (tree) {
273 Long64_t localentry = tree->LoadTree(entry);
274 SetTree(tree->GetTree());
275 TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
276 if (currentArray) {
277 return currentArray->Contains(localentry, nullptr, subentry);
278 }
279 return 0;
280 }
281 // tree = 0
282 Int_t result = TEntryList::Contains(entry);
283 if (result && fSubLists) {
285 if (t) {
286 result = t->TEntryList::Contains(subentry);
287 }
288 }
289 return result;
290}
291
292////////////////////////////////////////////////////////////////////////////////
293/// Create a TEntryListArray based on the given TEntryList
294/// Called by SetTree when the given list is added to fLists
295/// Replace it by a TEntryListArray and delete the given list
296
298{
299 // TODO: Keep the blocks and the number of entries to transfer without copying?
300 // TObjArray *blocks = e->fBlocks;
301 // Int_t NBlocks = e->fNBlocks;
302 // Long64_t N = e->fN;
303 // e->fBlocks = 0;
304 // e->fNBlocks = 0;
305 // e->fN = 0;
306
307 TEntryListArray *earray = new TEntryListArray(*e);
308// earray->fBlocks = blocks;
309// earray->fNBlocks = NBlocks;
310// earray->fN = N;
311
312 if (e == fCurrent) {
313 fCurrent = earray;
314 }
315 // If the list has just been split, earray will be the first one
316 // and must keep the current sublists
317 if (fSubLists) {
318 earray->fSubLists = fSubLists;
319 fSubLists = nullptr;
320 }
321 if (e == fLists->First()) {
322 fLists->AddFirst(earray);
323 } else {
324 fLists->Add(earray);
325 }
326 fLists->Remove(e);
327 delete e;
328 e = nullptr;
329}
330
331////////////////////////////////////////////////////////////////////////////////
332/// Add entry \#entry (, \#subentry) to the list
333/// - When tree = 0, adds to the current list
334/// - When tree != 0, finds the list corresponding to this tree (or add a new one)
335/// - When tree is a chain, the entry is assumed to be global index and the local
336/// entry is recomputed from the treeoffset information of the chain
337
338bool TEntryListArray::Enter(Long64_t entry, TTree *tree, Long64_t subentry)
339{
340 //When subentry = -1, add all subentries (remove the sublist if it exists)
341 //When subentry != -1 and the entry is not present,
342 //add only the given subentry, creating a TEntryListArray to hold the subentries for the given entry
343 //Return true only if the entry is new (not the subentry)
344
345 bool result = false;
346
347 if (tree) {
348 Long64_t localentry = tree->LoadTree(entry);
349 SetTree(tree->GetTree());
350 TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
351 if (currentArray) {
352 if ((result = currentArray->Enter(localentry, nullptr, subentry)))
353 if (fLists) ++fN;
354 }
355 return result;
356 }
357 if (fLists) {
358 if (!fCurrent) fCurrent = (TEntryList*)fLists->First();
359 TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
360 if (currentArray && (result = currentArray->Enter(entry, nullptr, subentry))) {
361 ++fN;
362 }
363 return result;
364 }
365 // tree = 0 && !fLists
366 // Sub entries were already present ?
368 if (t) { // Sub entries were already present
369 if (subentry != -1) {
370 t->TEntryList::Enter(subentry);
371 } else { // remove the sub entries
372 RemoveSubList(t);
373 }
374 } else {
375 result = TEntryList::Enter(entry);
376 if (subentry != -1 && result) { // a sub entry was given and the entry was not present
377 t = SetEntry(entry);
378 if (t) t->TEntryList::Enter(subentry);
379 }
380 }
381 return result;
382}
383
384bool TEntryListArray::Enter(Long64_t localentry, const char *treename, const char *filename, Long64_t subentry)
385{
386 bool result = false;
387 SetTree(treename, filename);
388 TEntryListArray *currentArray = dynamic_cast<TEntryListArray *>(fCurrent);
389 if (currentArray) {
390 if ((result = currentArray->Enter(localentry, nullptr, subentry)))
391 if (fLists)
392 ++fN;
393 }
394 return result;
395}
396
397////////////////////////////////////////////////////////////////////////////////
398/// Return the list holding the subentries for the given entry or 0
399
401{
402 if (tree) {
403 Long64_t localentry = tree->LoadTree(entry);
404 SetTree(tree->GetTree());
405 if (fCurrent) {
406 TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
407 if (currentArray) {
408 return currentArray->GetSubListForEntry(localentry);
409 }
410 }
411 return nullptr;
412 }
413 // tree = 0
414
415 if (!fSubLists || !fSubLists->GetEntries()) {
416 return nullptr;
417 }
418
419 if (!fSubListIter) {
422 }
423 else if (!fLastSubListQueried || entry < fLastSubListQueried->fEntry) {
424 // Restart the loop: fLastSubListQueried should point to the newest entry
425 // or where we stoped the last search
426 // (it is 0 only if we reached the end of the loop)
427 fSubListIter->Reset();
429 }
430
431 if (entry == fLastSubListQueried->fEntry) {
432 return fLastSubListQueried;
433 }
434
435 while ((fLastSubListQueried = (TEntryListArray*) fSubListIter->Next())) {
436 if (fLastSubListQueried->fEntry == entry) {
437 return fLastSubListQueried;
438 }
439 if (fLastSubListQueried->fEntry > entry) {
440 break;
441 }
442 }
443 return nullptr;
444}
445
446////////////////////////////////////////////////////////////////////////////////
447/// Print this list
448/// - option = "" - default - print the name of the tree and file
449/// - option = "all" - print all the entry numbers
450/// - option = "subentries" - print all the entry numbers and associated subentries
451
452void TEntryListArray::Print(const Option_t* option) const
453{
454 TString opt = option;
455 opt.ToUpper();
456 bool new_line = !opt.Contains("EOL");
457
458 if (!opt.Contains("S") && new_line) {
459 TEntryList::Print(option);
460 return;
461 }
462
463 if (fLists) {
464 TIter next(fLists);
465 TEntryListArray *e = nullptr;
466 while ((e = (TEntryListArray*)next())) {
467 std::cout << e->fTreeName << ":" << std::endl;
468 e->Print(option);
469 }
470 return;
471 }
472
473 // Print all subentries
474 TEntryListArray *tmp = const_cast<TEntryListArray *>(this);
475 TIter next(fSubLists);
477 for (Int_t i = 0; i < tmp->fN; ++i) {
478 Long64_t entry = tmp->GetEntry(i);
479 std::cout << entry << " ";
480 if (fSubLists) {
481 std::cout << " : ";
482 }
483 if (e && e->fEntry == entry) {
484 e->Print("all,EOL");
485 e = (TEntryListArray*)next();
486 }
487 if (new_line) {
488 std::cout << std::endl;
489 }
490 }
491}
492
493////////////////////////////////////////////////////////////////////////////////
494/// Remove entry \#entry (, \#subentry) from the list
495/// - When tree = 0, removes from the current list
496/// - When tree != 0, finds the list, corresponding to this tree
497/// - When tree is a chain, the entry is assumed to be global index and the local
498/// entry is recomputed from the treeoffset information of the chain
499///
500/// If subentry != -1, only the given subentry is removed
501
502bool TEntryListArray::Remove(Long64_t entry, TTree *tree, Long64_t subentry)
503{
504 bool result = false;
505
506 if (tree) {
507 Long64_t localentry = tree->LoadTree(entry);
508 SetTree(tree->GetTree());
509 TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
510 if (currentArray && (result = currentArray->Remove(localentry, nullptr, subentry))) {
511 if (fLists) {
512 --fN;
513 }
514 }
515 return result;
516 }
517 if (fLists) {
518 if (!fCurrent) fCurrent = (TEntryList*)fLists->First();
519 TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
520 if (currentArray && (result = currentArray->Remove(entry, nullptr, subentry)) && fLists) {
521 --fN;
522 }
523 return result;
524 }
525
526 // tree = 0 && !fLists
528 if (e) {
529 if (subentry != -1) {
530 e->TEntryList::Remove(subentry);
531 }
532 if (subentry == -1 || !e->GetN()) {
533 RemoveSubList(e, tree);
534 return TEntryList::Remove(entry);
535 }
536 } else if (subentry == -1) {
537 return TEntryList::Remove(entry);
538 }
539 return false;
540}
541
542////////////////////////////////////////////////////////////////////////////////
543/// Remove the given sublist and return true if succeeded
544
546{
547 if (!e) return false;
548 if (tree) {
549 SetTree(tree->GetTree());
550 TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
551 if (currentArray) {
552 return currentArray->RemoveSubList(e);
553 }
554 }
555
556 if (!fSubLists || !fSubLists->Remove(e)) {
557 return false;
558 }
559 // fSubLists->Sort(); --> for TObjArray
560 delete e;
561 if (!fSubLists->GetEntries()) {
562 delete fSubLists;
563 fSubLists = nullptr;
564 }
565 return true;
566}
567
568////////////////////////////////////////////////////////////////////////////////
569/// Remove the sublists for the given entry --> not being used...
570
572{
573 if (tree) {
574 Long64_t localentry = tree->LoadTree(entry);
575 SetTree(tree->GetTree());
576 TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
577 if (currentArray) {
578 return currentArray->RemoveSubListForEntry(localentry);
579 }
580 }
581 return RemoveSubList(GetSubListForEntry(entry));
582}
583
584////////////////////////////////////////////////////////////////////////////////
585/// Reset all entries and remove all sublists
586
588{
590 if (fSubLists) {
591 if (!((TEntryListArray*)fSubLists->First())->GetDirectory()) {
592 fSubLists->Delete();
593 }
594 delete fSubLists;
595 }
596 delete fSubListIter;
597 Init();
598}
599
600////////////////////////////////////////////////////////////////////////////////
601/// Create a sublist for the given entry and returns it --> should be called
602/// after calling GetSubListForEntry
603
605{
606 if (entry < 0) return nullptr;
607
608 // If tree is given, switch to the list that contains tree
609 if (tree) {
610 Long64_t localentry = tree->LoadTree(entry);
611 SetTree(tree->GetTree());
612 TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
613 if (currentArray) {
614 return currentArray->SetEntry(localentry);
615 }
616 return nullptr;
617 }
618 // tree = 0
619 if (!fSubLists) {
620 fSubLists = new TList();
621 }
622 TEntryListArray *newlist = new TEntryListArray();
623 newlist->fEntry = entry;
625 fSubLists->AddBefore(fLastSubListQueried, newlist);
626 fSubListIter->Reset(); // Reset the iterator to avoid missing the entry next to the new one (bug in TIter?)
627 } else {
628 fSubLists->AddLast(newlist);
629 }
630 fLastSubListQueried = newlist;
631 return newlist;
632}
633
634////////////////////////////////////////////////////////////////////////////////
635/// Remove all the entries (and subentries) of this entry list that are contained
636/// in elist.
637/// If for a given entry present in both lists, one has subentries and the other
638/// does not, the whole entry is removed
639
641{
642 if (!elist) return;
643
644 if (fLists) { // This list is split
645 TEntryListArray* e = nullptr;
646 TIter next(fLists);
647 fN = 0; // reset fN to set it to the sum of fN in each list
648 while ((e = (TEntryListArray*) next())) {
649 e->Subtract(elist);
650 fN += e->GetN();
651 }
652 } else if (elist->GetLists()) { // The other list is split
653 TIter next(elist->GetLists());
654 TEntryList *e = nullptr;
655 while ((e = (TEntryList*) next())) {
656 Subtract(e);
657 }
658 } else { // None of the lists are split
659 if (strcmp(elist->GetTreeName(), fTreeName.Data()) || strcmp(elist->GetFileName(), fFileName.Data()))
660 return; // Lists are for different trees
661 const TEntryListArray *elist_array = dynamic_cast< const TEntryListArray *>(elist);
662 if (!fSubLists || !elist_array || !elist_array->GetSubLists()) { // there are no sublists in one of the lists
664 if (fSubLists) {
665 TEntryListArray *e = nullptr;
666 TIter next(fSubLists);
667 while ((e = (TEntryListArray*) next())) {
668 if (!Contains(e->fEntry))
670 }
671 }
672 } else { // Both lists have subentries, will have to loop over them
673 TEntryListArray *el1, *el2;
674 TIter next1(fSubLists);
675 TIter next2(elist_array->GetSubLists());
676 el1 = (TEntryListArray*) next1();
677 el2 = (TEntryListArray*) next2();
678
679 Long64_t n2 = elist->GetN();
680 Long64_t entry;
681 for (Int_t i = 0; i < n2; ++i) {
682 entry = (const_cast<TEntryList*>(elist))->GetEntry(i);
683 // Try to find the sublist for this entry in list
684 while (el1 && el1->fEntry < entry) { // && el2
685 el1 = (TEntryListArray*) next1();
686 }
687 while (el2 && el2->fEntry < entry) { // && el1
688 el2 = (TEntryListArray*) next2();
689 }
690
691 if (el1 && el2 && entry == el1->fEntry && entry == el2->fEntry) { // both lists have sublists for this entry
692 el1->Subtract(el2);
693 if (!el1->fN) {
694 Remove(entry);
695 }
696 } else {
697 Remove(entry);
698 }
699 }
700 }
701 }
702}
703
704////////////////////////////////////////////////////////////////////////////////
705/// If a list for a tree with such name and filename exists, sets it as the current sublist
706/// If not, creates this list and sets it as the current sublist
707
708void TEntryListArray::SetTree(const char *treename, const char *filename)
709{
710 // ! the filename is taken as provided, no extensions to full path or url !
711
712 // Uses the method from the base class: if the tree is new, the a new TEntryList will be created (and stored in fLists) and needs to be converted to a TEntryListArray
713
714 Int_t nLists = -1;
715 if (fLists) {
716 nLists = fLists->GetEntries();
717 }
718 TEntryList::SetTree(treename, filename);
719 if (fLists && fLists->GetEntries() != nLists) { // fList was created and/or has new additions
720 if (nLists == -1) {
721 // The list has just been split (fList was created)
722 // There should be two TEntryLists in fLists:
723 // must convert both to TEntryListArray
724 // and transfer the sublists to the first one
726 }
728 }
729}
#define e(i)
Definition RSha256.hxx:103
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
const char Option_t
Option string (const char).
Definition RtypesCore.h:80
char name[80]
Definition TGX11.cxx:148
Collection abstract base class.
Definition TCollection.h:65
virtual TEntryListArray * GetSubListForEntry(Long64_t entry, TTree *tree=nullptr)
Return the list holding the subentries for the given entry or 0.
virtual bool RemoveSubList(TEntryListArray *e, TTree *tree=nullptr)
Remove the given sublist and return true if succeeded.
~TEntryListArray() override
d-tor
void Print(const Option_t *option="") const override
Print this list.
void SetTree(const char *treename, const char *filename) override
If a list for a tree with such name and filename exists, sets it as the current sublist If not,...
void Reset() override
Reset all entries and remove all sublists.
void Init()
Initialize data members, called by Reset.
virtual TEntryListArray * SetEntry(Long64_t entry, TTree *tree=nullptr)
Create a sublist for the given entry and returns it --> should be called after calling GetSubListForE...
TEntryListArray * fLastSubListQueried
! last sublist checked by GetSubListForEntry
TList * fSubLists
a list of underlying entry lists for each event of a TEntryList
TEntryListArray()
Default c-tor.
virtual bool RemoveSubListForEntry(Long64_t entry, TTree *tree=nullptr)
Remove the sublists for the given entry --> not being used...
virtual void ConvertToTEntryListArray(TEntryList *e)
Create a TEntryListArray based on the given TEntryList Called by SetTree when the given list is added...
void Subtract(const TEntryList *elist) override
Remove all the entries (and subentries) of this entry list that are contained in elist.
Long64_t fEntry
the entry number, when the list is used for subentries
void Add(const TEntryList *elist) override
Add 2 entry lists.
virtual TList * GetSubLists() const
virtual Int_t Contains(Long64_t entry, TTree *tree, Long64_t subentry)
virtual void AddEntriesAndSubLists(const TEntryList *elist)
The method that really adds two entry lists with sublists If lists are split (fLists !...
virtual bool Enter(Long64_t entry, TTree *tree, Long64_t subentry)
Add entry #entry (, #subentry) to the list.
TIter * fSubListIter
! to iterate over fSubLists and keep last one checked
virtual bool Remove(Long64_t entry, TTree *tree, Long64_t subentry)
Remove entry #entry (, #subentry) from the list.
TString fFileName
name of the file, where the tree is
Definition TEntryList.h:39
virtual TList * GetLists() const
Definition TEntryList.h:76
virtual Int_t Contains(Long64_t entry, TTree *tree=nullptr)
virtual bool Enter(Long64_t entry, TTree *tree=nullptr)
virtual bool Remove(Long64_t entry, TTree *tree=nullptr)
virtual Long64_t GetEntry(Long64_t index)
Long64_t fN
number of entries in the list
Definition TEntryList.h:36
virtual void SetTree(const TTree *tree)
virtual void Subtract(const TEntryList *elist)
virtual const char * GetTreeName() const
Definition TEntryList.h:79
virtual void Add(const TEntryList *elist)
TEntryList * fCurrent
! currently filled entry list
Definition TEntryList.h:32
void Print(const Option_t *option="") const override
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)
TString fTreeName
name of the tree
Definition TEntryList.h:38
virtual void Reset()
virtual Long64_t GetN() const
Definition TEntryList.h:78
A doubly linked list.
Definition TList.h:38
Basic string class.
Definition TString.h:138
void ToUpper()
Change string to upper case.
Definition TString.cxx:1202
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:641
A TTree represents a columnar dataset.
Definition TTree.h:89
virtual TTree * GetTree() const
Definition TTree.h:604
virtual Long64_t LoadTree(Long64_t entry)
Set current entry.
Definition TTree.cxx:6584