Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TChain.cxx
Go to the documentation of this file.
1// @(#)root/tree:$Id$
2// Author: Rene Brun 03/02/97
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, 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 TChain
13\ingroup tree
14
15A chain is a collection of files containing TTree objects.
16When the chain is created, the first parameter is the default name
17for the Tree to be processed later on.
18
19Enter a new element in the chain via the TChain::Add function.
20Once a chain is defined, one can use the normal TTree functions
21to Draw,Scan,etc.
22
23Use TChain::SetBranchStatus to activate one or more branches for all
24the trees in the chain.
25*/
26
27#include "TChain.h"
28
29#include <iostream>
30#include <cfloat>
31#include <string>
32
33#include "TBranch.h"
34#include "TBrowser.h"
35#include "TBuffer.h"
36#include "TChainElement.h"
37#include "TClass.h"
38#include "TColor.h"
39#include "TCut.h"
40#include "TError.h"
41#include "TFile.h"
42#include "TFileInfo.h"
43#include "TFriendElement.h"
44#include "TLeaf.h"
45#include "TList.h"
46#include "TObjString.h"
47#include "TPluginManager.h"
48#include "TROOT.h"
49#include "TRegexp.h"
50#include "TSelector.h"
51#include "TSystem.h"
52#include "TTree.h"
53#include "TTreeCache.h"
54#include "TUrl.h"
55#include "TVirtualIndex.h"
56#include "TEventList.h"
57#include "TEntryList.h"
58#include "TEntryListFromFile.h"
59#include "TFileStager.h"
60#include "TFilePrefetch.h"
61#include "TVirtualMutex.h"
62#include "TVirtualPerfStats.h"
63#include "strlcpy.h"
64#include "snprintf.h"
65
67
68////////////////////////////////////////////////////////////////////////////////
69/// Default constructor.
70
72 : TTree(), fTreeOffsetLen(100), fNtrees(0), fTreeNumber(-1), fTreeOffset(0), fCanDeleteRefs(kFALSE), fTree(0),
73 fFile(0), fFiles(0), fStatus(0), fProofChain(0), fGlobalRegistration(mode == kWithGlobalRegistration)
74{
77 fStatus = new TList();
78 fTreeOffset[0] = 0;
80 gROOT->GetListOfSpecials()->Add(this);
81 }
82 fFile = 0;
83 fDirectory = 0;
84
85 // Reset PROOF-related bits
88
90 // Add to the global list
91 gROOT->GetListOfDataSets()->Add(this);
92
93 // Make sure we are informed if the TFile is deleted.
95 gROOT->GetListOfCleanups()->Add(this);
96 }
97}
98
99////////////////////////////////////////////////////////////////////////////////
100/// Create a chain.
101///
102/// A TChain is a collection of TFile objects.
103/// the first parameter "name" is the name of the TTree object
104/// in the files added with Add.
105/// Use TChain::Add to add a new element to this chain.
106///
107/// In case the Tree is in a subdirectory, do, eg:
108/// ~~~ {.cpp}
109/// TChain ch("subdir/treename");
110/// ~~~
111/// Example:
112/// Suppose we have 3 files f1.root, f2.root and f3.root. Each file
113/// contains a TTree object named "T".
114/// ~~~ {.cpp}
115/// TChain ch("T"); creates a chain to process a Tree called "T"
116/// ch.Add("f1.root");
117/// ch.Add("f2.root");
118/// ch.Add("f3.root");
119/// ch.Draw("x");
120/// ~~~
121/// The Draw function above will process the variable "x" in Tree "T"
122/// reading sequentially the 3 files in the chain ch.
123///
124/// The TChain data structure:
125///
126/// Each TChainElement has a name equal to the tree name of this TChain
127/// and a title equal to the file name. So, to loop over the
128/// TFiles that have been added to this chain:
129/// ~~~ {.cpp}
130/// TObjArray *fileElements=chain->GetListOfFiles();
131/// TIter next(fileElements);
132/// TChainElement *chEl=0;
133/// while (( chEl=(TChainElement*)next() )) {
134/// TFile f(chEl->GetTitle());
135/// ... do something with f ...
136/// }
137/// ~~~
138
139TChain::TChain(const char *name, const char *title, Mode mode)
140 : TTree(name, title, /*splitlevel*/ 99, nullptr), fTreeOffsetLen(100), fNtrees(0), fTreeNumber(-1), fTreeOffset(0),
141 fCanDeleteRefs(kFALSE), fTree(0), fFile(0), fFiles(0), fStatus(0), fProofChain(0),
142 fGlobalRegistration(mode == kWithGlobalRegistration)
143{
144 //
145 //*-*
146
149 fStatus = new TList();
150 fTreeOffset[0] = 0;
151 fFile = 0;
152
153 // Reset PROOF-related bits
156
159
160 // Add to the global lists
161 gROOT->GetListOfSpecials()->Add(this);
162 gROOT->GetListOfDataSets()->Add(this);
163
164 // Make sure we are informed if the TFile is deleted.
165 gROOT->GetListOfCleanups()->Add(this);
166 }
167}
168
169////////////////////////////////////////////////////////////////////////////////
170/// Destructor.
171
173{
174 bool rootAlive = gROOT && !gROOT->TestBit(TObject::kInvalidObject);
175
176 if (rootAlive && fGlobalRegistration) {
178 gROOT->GetListOfCleanups()->Remove(this);
179 }
180
182 fStatus->Delete();
183 delete fStatus;
184 fStatus = 0;
185 fFiles->Delete();
186 delete fFiles;
187 fFiles = 0;
188
189 //first delete cache if exists
190 auto tc = fFile && fTree ? fTree->GetReadCache(fFile) : nullptr;
191 if (tc) {
192 delete tc;
194 }
195
196 delete fFile;
197 fFile = 0;
198 // Note: We do *not* own the tree.
199 fTree = 0;
200 delete[] fTreeOffset;
201 fTreeOffset = 0;
202
203 // Remove from the global lists
204 if (rootAlive && fGlobalRegistration) {
206 gROOT->GetListOfSpecials()->Remove(this);
207 gROOT->GetListOfDataSets()->Remove(this);
208 }
209
210 // This is the same as fFile, don't delete it a second time.
211 fDirectory = 0;
212}
213
214////////////////////////////////////////////////////////////////////////////////
215/// Add all files referenced by the passed chain to this chain.
216/// The function returns the total number of files connected.
217
219{
220 if (!chain) return 0;
221
222 // Check for enough space in fTreeOffset.
223 if ((fNtrees + chain->GetNtrees()) >= fTreeOffsetLen) {
224 fTreeOffsetLen += 2 * chain->GetNtrees();
225 Long64_t* trees = new Long64_t[fTreeOffsetLen];
226 for (Int_t i = 0; i <= fNtrees; i++) {
227 trees[i] = fTreeOffset[i];
228 }
229 delete[] fTreeOffset;
230 fTreeOffset = trees;
231 }
232 chain->GetEntries(); //to force the computation of nentries
233 TIter next(chain->GetListOfFiles());
234 Int_t nf = 0;
235 TChainElement* element = 0;
236 while ((element = (TChainElement*) next())) {
237 Long64_t nentries = element->GetEntries();
240 } else {
242 }
243 fNtrees++;
245 TChainElement* newelement = new TChainElement(element->GetName(), element->GetTitle());
246 newelement->SetPacketSize(element->GetPacketSize());
247 newelement->SetNumberEntries(nentries);
248 fFiles->Add(newelement);
249 nf++;
250 }
251 if (fProofChain)
252 // This updates the proxy chain when we will really use PROOF
254
255 return nf;
256}
257
258////////////////////////////////////////////////////////////////////////////////
259/// \brief Add a new file to this chain.
260///
261/// \param[in] name The path to the file to be added. See below for details.
262/// \param[in] nentries Number of entries in the file. This can be an estimate
263/// or queried from the file. See below for details.
264/// \returns There are different possible return values:
265/// - If nentries>0 (including the default of TTree::kMaxEntries) and no
266/// wildcarding is used, ALWAYS returns 1 irrespective of whether the file
267/// exists or contains the correct tree.
268/// - If wildcarding is used, regardless of the value of \p nentries, returns
269/// the number of files matching the name irrespective of whether they contain
270/// the correct tree.
271/// - If nentries<=0 and wildcarding is not used, returns 1 if the file
272/// exists and contains the correct tree and 0 otherwise.
273///
274/// <h4>Details of the name parameter</h4>
275/// There are two sets of formats accepted for the parameter \p name . The first
276/// one is:
277///
278/// ~~~{.cpp}
279/// [//machine]/path/file_name[?[query][#tree_name]]
280/// or [//machine]/path/file_name.root[.oext][/tree_name]
281/// ~~~
282///
283/// Note the following:
284/// - If the \p tree_name part is missing, it will be assumed that
285/// the file contains a tree with the same name as the chain.
286/// - Tagging the name of the tree with a slash (e.g. \p /tree_name ) is only
287/// supported for backward compatibility; it requires the file name to contain
288/// the string '.root' and its use is deprecated. Instead, use the form
289/// \p ?#tree_name (that is an "?" followed by an empty query), for example:
290/// ~~~{.cpp}
291/// TChain c;
292/// // DO NOT DO THIS
293/// // c.Add("myfile.root/treename");
294/// // DO THIS INSTEAD
295/// c.Add("myfile.root?#treename");
296/// ~~~
297/// - Wildcard treatment is triggered by any of the special characters:
298/// <b>[]*?</b> which may be used in the file name, eg. specifying "xxx*.root"
299/// adds all files starting with xxx in the current file system directory.
300///
301/// The second format accepted for \p name may have the form of a URL, e.g.:
302///
303/// ~~~ {.cpp}
304/// root://machine/path/file_name[?[query][#tree_name]]
305/// or root://machine/path/file_name
306/// or root://machine/path/file_name.root[.oext]/tree_name
307/// or root://machine/path/file_name.root[.oext]/tree_name?query
308/// ~~~
309///
310/// Note the following:
311/// - The optional "query" token is to be interpreted by the remote server.
312/// - Wildcards may be supported in URLs, depending on the protocol plugin and
313/// the remote server.
314/// - \p http or \p https URLs can contain a query identifier without
315/// \p tree_name, but generally URLs can not be written with them because of
316/// ambiguity with the wildcard character. (Also see the documentation for
317/// TChain::AddFile, which does not support wildcards but allows the URL name
318/// to contain a query).
319/// - The rules for tagging the name of the tree in the file are the same as
320/// in the format above.
321///
322/// <h4>Details of the nentries parameter</h4>
323/// Depending on the value of the parameter, the number of entries in the file
324/// is retrieved differently:
325/// - If <tt>nentries <= 0</tt>, the file is connected and the tree header read
326/// in memory to get the number of entries.
327/// - If <tt>nentries > 0</tt>, the file is not connected, \p nentries is
328/// assumed to be the number of entries in the file. In this case, no check is
329/// made that the file exists and that the corresponding tree exists as well.
330/// This second mode is interesting in case the number of entries in the file
331/// is already stored in a run data base for example.
332/// - If <tt>nentries == TTree::kMaxEntries</tt> (default), the file is not
333/// connected. The number of entries in each file will be read only when the
334/// file will need to be connected to read an entry. This option is the
335/// default and very efficient if one processes the chain sequentially. Note
336/// that in case TChain::GetEntry(entry) is called and entry refers to an
337/// entry in the 3rd file, for example, this forces the tree headers in the
338/// first and second file to be read to find the number of entries in these
339/// files. Note that calling TChain::GetEntriesFast after having
340/// created a chain with this default returns TTree::kMaxEntries ! Using
341/// TChain::GetEntries instead will force all the tree headers in the chain to
342/// be read to get the number of entries in each tree.
343///
344/// <h4>The %TChain data structure</h4>
345/// Each element of the chain is a TChainElement object. It has a name equal to
346/// the tree name of this chain (or the name of the specific tree in the added
347/// file if it was explicitly tagged) and a title equal to the file name. So, to
348/// loop over the files that have been added to this chain:
349/// ~~~ {.cpp}
350/// TObjArray *fileElements=chain->GetListOfFiles();
351/// for (TObject *op: *fileElements) {
352/// auto chainElement = static_cast<TChainElement *>(op);
353/// TFile f{chainElement->GetTitle()};
354/// TTree *tree = f.Get<TTree>(chainElement->GetName());
355/// // Do something with the file or the tree
356/// }
357/// ~~~
358///
359/// \note To add all the files of a another \p TChain to this one, use
360/// TChain::Add(TChain* chain).
361
362Int_t TChain::Add(const char* name, Long64_t nentries /* = TTree::kMaxEntries */)
363{
364 TString basename, treename, query, suffix;
365 ParseTreeFilename(name, basename, treename, query, suffix, kTRUE);
366
367 // case with one single file
368 if (!basename.MaybeWildcard()) {
369 return AddFile(name, nentries);
370 }
371
372 // wildcarding used in name
373 Int_t nf = 0;
374
375 Int_t slashpos = basename.Last('/');
376 TString directory;
377 if (slashpos>=0) {
378 directory = basename(0,slashpos); // Copy the directory name
379 basename.Remove(0,slashpos+1); // and remove it from basename
380 } else {
382 }
383
384 const char *file;
385 const char *epath = gSystem->ExpandPathName(directory.Data());
386 void *dir = gSystem->OpenDirectory(epath);
387 delete [] epath;
388 if (dir) {
389 //create a TList to store the file names (not yet sorted)
390 TList l;
391 TRegexp re(basename,kTRUE);
392 while ((file = gSystem->GetDirEntry(dir))) {
393 if (!strcmp(file,".") || !strcmp(file,"..")) continue;
394 TString s = file;
395 if ( (basename!=file) && s.Index(re) == kNPOS) continue;
396 l.Add(new TObjString(file));
397 }
399 //sort the files in alphanumeric order
400 l.Sort();
401 TIter next(&l);
402 TObjString *obj;
403 while ((obj = (TObjString*)next())) {
404 file = obj->GetName();
405 nf += AddFile(TString::Format("%s/%s%s",directory.Data(),file,suffix.Data()),nentries);
406 }
407 l.Delete();
408 }
409 if (fProofChain)
410 // This updates the proxy chain when we will really use PROOF
412
413 return nf;
414}
415
416////////////////////////////////////////////////////////////////////////////////
417/// Add a new file to this chain.
418///
419/// Filename formats are similar to TChain::Add. Wildcards are not
420/// applied. urls may also contain query and fragment identifiers
421/// where the tree name can be specified in the url fragment.
422///
423/// eg.
424/// ~~~ {.cpp}
425/// root://machine/path/file_name[?query[#tree_name]]
426/// root://machine/path/file_name.root[.oext]/tree_name[?query]
427/// ~~~
428/// If tree_name is given as a part of the file name it is used to
429/// as the name of the tree to load from the file. Otherwise if tname
430/// argument is specified the chain will load the tree named tname from
431/// the file, otherwise the original treename specified in the TChain
432/// constructor will be used.
433/// Tagging the tree_name with a slash [/tree_name] is only supported for
434/// backward compatibility; it requires the file name ot contain the string
435/// '.root' and its use is deprecated.
436///
437/// A. If nentries <= 0, the file is opened and the tree header read
438/// into memory to get the number of entries.
439///
440/// B. If nentries > 0, the file is not opened, and nentries is assumed
441/// to be the number of entries in the file. In this case, no check
442/// is made that the file exists nor that the tree exists in the file.
443/// This second mode is interesting in case the number of entries in
444/// the file is already stored in a run database for example.
445///
446/// C. If nentries == TTree::kMaxEntries (default), the file is not opened.
447/// The number of entries in each file will be read only when the file
448/// is opened to read an entry. This option is the default and very
449/// efficient if one processes the chain sequentially. Note that in
450/// case GetEntry(entry) is called and entry refers to an entry in the
451/// third file, for example, this forces the tree headers in the first
452/// and second file to be read to find the number of entries in those
453/// files. Note that if one calls GetEntriesFast() after having created
454/// a chain with this default, GetEntriesFast() will return TTree::kMaxEntries!
455/// Using the GetEntries() function instead will force all of the tree
456/// headers in the chain to be read to read the number of entries in
457/// each tree.
458///
459/// D. The TChain data structure
460/// Each TChainElement has a name equal to the tree name of this TChain
461/// and a title equal to the file name. So, to loop over the
462/// TFiles that have been added to this chain:
463/// ~~~ {.cpp}
464/// TObjArray *fileElements=chain->GetListOfFiles();
465/// TIter next(fileElements);
466/// TChainElement *chEl=0;
467/// while (( chEl=(TChainElement*)next() )) {
468/// TFile f(chEl->GetTitle());
469/// ... do something with f ...
470/// }
471/// ~~~
472/// The function returns 1 if the file is successfully connected, 0 otherwise.
473
474Int_t TChain::AddFile(const char* name, Long64_t nentries /* = TTree::kMaxEntries */, const char* tname /* = "" */)
475{
476 if(name==0 || name[0]=='\0') {
477 Error("AddFile", "No file name; no files connected");
478 return 0;
479 }
480
481 const char *treename = GetName();
482 if (tname && strlen(tname) > 0) treename = tname;
483
484 TString basename, tn, query, suffix;
485 ParseTreeFilename(name, basename, tn, query, suffix, kFALSE);
486
487 if (!tn.IsNull()) {
488 treename = tn.Data();
489 }
490
491 Int_t nch = basename.Length() + query.Length();
492 char *filename = new char[nch+1];
493 strlcpy(filename,basename.Data(),nch+1);
494 strlcat(filename,query.Data(),nch+1);
495
496 //Check enough space in fTreeOffset
497 if (fNtrees+1 >= fTreeOffsetLen) {
498 fTreeOffsetLen *= 2;
499 Long64_t *trees = new Long64_t[fTreeOffsetLen];
500 for (Int_t i=0;i<=fNtrees;i++) trees[i] = fTreeOffset[i];
501 delete [] fTreeOffset;
502 fTreeOffset = trees;
503 }
504
505 // Open the file to get the number of entries.
506 Int_t pksize = 0;
507 if (nentries <= 0) {
508 TFile* file;
509 {
511 const char *option = fGlobalRegistration ? "READ" : "READ_WITHOUT_GLOBALREGISTRATION";
512 file = TFile::Open(filename, option);
513 }
514 if (!file || file->IsZombie()) {
515 delete file;
516 file = 0;
517 delete[] filename;
518 filename = 0;
519 return 0;
520 }
521
522 // Check that tree with the right name exists in the file.
523 // Note: We are not the owner of obj, the file is!
524 TObject* obj = file->Get(treename);
525 if (!obj || !obj->InheritsFrom(TTree::Class())) {
526 Error("AddFile", "cannot find tree with name %s in file %s", treename, filename);
527 delete file;
528 file = 0;
529 delete[] filename;
530 filename = 0;
531 return 0;
532 }
533 TTree* tree = (TTree*) obj;
534 nentries = tree->GetEntries();
535 pksize = tree->GetPacketSize();
536 // Note: This deletes the tree we fetched.
537 delete file;
538 file = 0;
539 }
540
541 if (nentries > 0) {
545 } else {
548 }
549 fNtrees++;
550
551 TChainElement* element = new TChainElement(treename, filename);
552 element->SetPacketSize(pksize);
553 element->SetNumberEntries(nentries);
554 fFiles->Add(element);
555 } else {
556 Warning("AddFile", "Adding tree with no entries from file: %s", filename);
557 }
558
559 delete [] filename;
560 if (fProofChain)
561 // This updates the proxy chain when we will really use PROOF
563
564 return 1;
565}
566
567////////////////////////////////////////////////////////////////////////////////
568/// Add all files referenced in the list to the chain. The object type in the
569/// list must be either TFileInfo or TObjString or TUrl .
570/// The function return 1 if successful, 0 otherwise.
571
572Int_t TChain::AddFileInfoList(TCollection* filelist, Long64_t nfiles /* = TTree::kMaxEntries */)
573{
574 if (!filelist)
575 return 0;
576 TIter next(filelist);
577
578 TObject *o = 0;
579 Long64_t cnt=0;
580 while ((o = next())) {
581 // Get the url
582 TString cn = o->ClassName();
583 const char *url = 0;
584 if (cn == "TFileInfo") {
585 TFileInfo *fi = (TFileInfo *)o;
586 url = (fi->GetCurrentUrl()) ? fi->GetCurrentUrl()->GetUrl() : 0;
587 if (!url) {
588 Warning("AddFileInfoList", "found TFileInfo with empty Url - ignoring");
589 continue;
590 }
591 } else if (cn == "TUrl") {
592 url = ((TUrl*)o)->GetUrl();
593 } else if (cn == "TObjString") {
594 url = ((TObjString*)o)->GetName();
595 }
596 if (!url) {
597 Warning("AddFileInfoList", "object is of type %s : expecting TFileInfo, TUrl"
598 " or TObjString - ignoring", o->ClassName());
599 continue;
600 }
601 // Good entry
602 cnt++;
603 AddFile(url);
604 if (cnt >= nfiles)
605 break;
606 }
607 if (fProofChain) {
608 // This updates the proxy chain when we will really use PROOF
610 }
611
612 return 1;
613}
614
615////////////////////////////////////////////////////////////////////////////////
616/// Add a TFriendElement to the list of friends of this chain.
617///
618/// A TChain has a list of friends similar to a tree (see TTree::AddFriend).
619/// You can add a friend to a chain with the TChain::AddFriend method, and you
620/// can retrieve the list of friends with TChain::GetListOfFriends.
621/// This example has four chains each has 20 ROOT trees from 20 ROOT files.
622/// ~~~ {.cpp}
623/// TChain ch("t"); // a chain with 20 trees from 20 files
624/// TChain ch1("t1");
625/// TChain ch2("t2");
626/// TChain ch3("t3");
627/// ~~~
628/// Now we can add the friends to the first chain.
629/// ~~~ {.cpp}
630/// ch.AddFriend("t1")
631/// ch.AddFriend("t2")
632/// ch.AddFriend("t3")
633/// ~~~
634/// \image html tchain_friend.png
635///
636///
637/// The parameter is the name of friend chain (the name of a chain is always
638/// the name of the tree from which it was created).
639/// The original chain has access to all variable in its friends.
640/// We can use the TChain::Draw method as if the values in the friends were
641/// in the original chain.
642/// To specify the chain to use in the Draw method, use the syntax:
643/// ~~~ {.cpp}
644/// <chainname>.<branchname>.<varname>
645/// ~~~
646/// If the variable name is enough to uniquely identify the variable, you can
647/// leave out the chain and/or branch name.
648/// For example, this generates a 3-d scatter plot of variable "var" in the
649/// TChain ch versus variable v1 in TChain t1 versus variable v2 in TChain t2.
650/// ~~~ {.cpp}
651/// ch.Draw("var:t1.v1:t2.v2");
652/// ~~~
653/// When a TChain::Draw is executed, an automatic call to TTree::AddFriend
654/// connects the trees in the chain. When a chain is deleted, its friend
655/// elements are also deleted.
656///
657/// The number of entries in the friend must be equal or greater to the number
658/// of entries of the original chain. If the friend has fewer entries a warning
659/// is given and the resulting histogram will have missing entries.
660/// For additional information see TTree::AddFriend.
661
662TFriendElement* TChain::AddFriend(const char* chain, const char* dummy /* = "" */)
663{
664 if (!fFriends) {
665 fFriends = new TList();
666 }
667 TFriendElement* fe = new TFriendElement(this, chain, dummy);
668
669 R__ASSERT(fe); // There used to be a "if (fe)" test ... Keep this assert until we are sure that fe is never null
670
671 fFriends->Add(fe);
672
673 if (fProofChain)
674 // This updates the proxy chain when we will really use PROOF
676
677 // We need to invalidate the loading of the current tree because its list
678 // of real friends is now obsolete. It is repairable only from LoadTree.
680
681 TTree* tree = fe->GetTree();
682 if (!tree) {
683 Warning("AddFriend", "Unknown TChain %s", chain);
684 }
685 return fe;
686}
687
688////////////////////////////////////////////////////////////////////////////////
689/// Add the whole chain or tree as a friend of this chain.
690
691TFriendElement* TChain::AddFriend(const char* chain, TFile* dummy)
692{
693 if (!fFriends) fFriends = new TList();
694 TFriendElement *fe = new TFriendElement(this,chain,dummy);
695
696 R__ASSERT(fe); // There used to be a "if (fe)" test ... Keep this assert until we are sure that fe is never null
697
698 fFriends->Add(fe);
699
700 if (fProofChain)
701 // This updates the proxy chain when we will really use PROOF
703
704 // We need to invalidate the loading of the current tree because its list
705 // of real friend is now obsolete. It is repairable only from LoadTree
707
708 TTree *t = fe->GetTree();
709 if (!t) {
710 Warning("AddFriend","Unknown TChain %s",chain);
711 }
712 return fe;
713}
714
715////////////////////////////////////////////////////////////////////////////////
716/// Add the whole chain or tree as a friend of this chain.
717
718TFriendElement* TChain::AddFriend(TTree* chain, const char* alias, Bool_t /* warn = kFALSE */)
719{
720 if (!chain) return nullptr;
721 if (!fFriends) fFriends = new TList();
722 TFriendElement *fe = new TFriendElement(this,chain,alias);
723 R__ASSERT(fe);
724
725 fFriends->Add(fe);
726
727 if (fProofChain)
728 // This updates the proxy chain when we will really use PROOF
730
731 // We need to invalidate the loading of the current tree because its list
732 // of real friend is now obsolete. It is repairable only from LoadTree
734
735 TTree *t = fe->GetTree();
736 if (!t) {
737 Warning("AddFriend","Unknown TChain %s",chain->GetName());
738 }
739 return fe;
740}
741
742////////////////////////////////////////////////////////////////////////////////
743/// Browse the contents of the chain.
744
746{
748}
749
750////////////////////////////////////////////////////////////////////////////////
751/// When closing a file during the chain processing, the file
752/// may be closed with option "R" if flag is set to kTRUE.
753/// by default flag is kTRUE.
754/// When closing a file with option "R", all TProcessIDs referenced by this
755/// file are deleted.
756/// Calling TFile::Close("R") might be necessary in case one reads a long list
757/// of files having TRef, writing some of the referenced objects or TRef
758/// to a new file. If the TRef or referenced objects of the file being closed
759/// will not be referenced again, it is possible to minimize the size
760/// of the TProcessID data structures in memory by forcing a delete of
761/// the unused TProcessID.
762
763void TChain::CanDeleteRefs(Bool_t flag /* = kTRUE */)
764{
765 fCanDeleteRefs = flag;
766}
767
768////////////////////////////////////////////////////////////////////////////////
769/// Initialize the packet descriptor string.
770
772{
773 TIter next(fFiles);
774 TChainElement* element = 0;
775 while ((element = (TChainElement*) next())) {
776 element->CreatePackets();
777 }
778}
779
780////////////////////////////////////////////////////////////////////////////////
781/// Override the TTree::DirectoryAutoAdd behavior:
782/// we never auto add.
783
785{
786}
787
788////////////////////////////////////////////////////////////////////////////////
789/// Draw expression varexp for selected entries.
790/// Returns -1 in case of error or number of selected events in case of success.
791///
792/// This function accepts TCut objects as arguments.
793/// Useful to use the string operator +, example:
794/// ~~~{.cpp}
795/// ntuple.Draw("x",cut1+cut2+cut3);
796/// ~~~
797///
798
799Long64_t TChain::Draw(const char* varexp, const TCut& selection,
800 Option_t* option, Long64_t nentries, Long64_t firstentry)
801{
802 if (fProofChain) {
803 // Make sure the element list is up to date
808 return fProofChain->Draw(varexp, selection, option, nentries, firstentry);
809 }
810
811 return TChain::Draw(varexp, selection.GetTitle(), option, nentries, firstentry);
812}
813
814////////////////////////////////////////////////////////////////////////////////
815/// Process all entries in this chain and draw histogram corresponding to
816/// expression varexp.
817/// Returns -1 in case of error or number of selected events in case of success.
818
819Long64_t TChain::Draw(const char* varexp, const char* selection,
820 Option_t* option,Long64_t nentries, Long64_t firstentry)
821{
822 if (fProofChain) {
823 // Make sure the element list is up to date
828 return fProofChain->Draw(varexp, selection, option, nentries, firstentry);
829 }
830 GetPlayer();
831 if (LoadTree(firstentry) < 0) return 0;
832 return TTree::Draw(varexp,selection,option,nentries,firstentry);
833}
834
835////////////////////////////////////////////////////////////////////////////////
836/// See TTree::GetReadEntry().
837
838TBranch* TChain::FindBranch(const char* branchname)
839{
841 // Make sure the element list is up to date
844 return fProofChain->FindBranch(branchname);
845 }
846 if (fTree) {
847 return fTree->FindBranch(branchname);
848 }
849 LoadTree(0);
850 if (fTree) {
851 return fTree->FindBranch(branchname);
852 }
853 return 0;
854}
855
856////////////////////////////////////////////////////////////////////////////////
857/// See TTree::GetReadEntry().
858
859TLeaf* TChain::FindLeaf(const char* searchname)
860{
862 // Make sure the element list is up to date
865 return fProofChain->FindLeaf(searchname);
866 }
867 if (fTree) {
868 return fTree->FindLeaf(searchname);
869 }
870 LoadTree(0);
871 if (fTree) {
872 return fTree->FindLeaf(searchname);
873 }
874 return 0;
875}
876
877////////////////////////////////////////////////////////////////////////////////
878/// Returns the expanded value of the alias. Search in the friends if any.
879
880const char* TChain::GetAlias(const char* aliasName) const
881{
882 const char* alias = TTree::GetAlias(aliasName);
883 if (alias) {
884 return alias;
885 }
886 if (fTree) {
887 return fTree->GetAlias(aliasName);
888 }
889 const_cast<TChain*>(this)->LoadTree(0);
890 if (fTree) {
891 return fTree->GetAlias(aliasName);
892 }
893 return 0;
894}
895
896////////////////////////////////////////////////////////////////////////////////
897/// Return pointer to the branch name in the current tree.
898
900{
902 // Make sure the element list is up to date
905 return fProofChain->GetBranch(name);
906 }
907 if (fTree) {
908 return fTree->GetBranch(name);
909 }
910 LoadTree(0);
911 if (fTree) {
912 return fTree->GetBranch(name);
913 }
914 return 0;
915}
916
917////////////////////////////////////////////////////////////////////////////////
918/// See TTree::GetReadEntry().
919
920Bool_t TChain::GetBranchStatus(const char* branchname) const
921{
923 // Make sure the element list is up to date
925 Warning("GetBranchStatus", "PROOF proxy not up-to-date:"
926 " run TChain::SetProof(kTRUE, kTRUE) first");
927 return fProofChain->GetBranchStatus(branchname);
928 }
929 return TTree::GetBranchStatus(branchname);
930}
931
932////////////////////////////////////////////////////////////////////////////////
933/// Return an iterator over the cluster of baskets starting at firstentry.
934///
935/// This iterator is not yet supported for TChain object.
936
938{
939 Fatal("GetClusterIterator","Not support for TChain object");
940 return TTree::GetClusterIterator(-1);
941}
942
943////////////////////////////////////////////////////////////////////////////////
944/// Return absolute entry number in the chain.
945/// The input parameter entry is the entry number in
946/// the current tree of this chain.
947
949{
950 return entry + fTreeOffset[fTreeNumber];
951}
952
953////////////////////////////////////////////////////////////////////////////////
954/// Return the total number of entries in the chain.
955/// In case the number of entries in each tree is not yet known,
956/// the offset table is computed.
957
959{
961 // Make sure the element list is up to date
963 Warning("GetEntries", "PROOF proxy not up-to-date:"
964 " run TChain::SetProof(kTRUE, kTRUE) first");
965 return fProofChain->GetEntries();
966 }
968 const_cast<TChain*>(this)->LoadTree(TTree::kMaxEntries-1);
969 }
970 return fEntries;
971}
972
973////////////////////////////////////////////////////////////////////////////////
974/// Get entry from the file to memory.
975///
976/// - getall = 0 : get only active branches
977/// - getall = 1 : get all branches
978///
979/// Return the total number of bytes read,
980/// 0 bytes read indicates a failure.
981
983{
984 Long64_t treeReadEntry = LoadTree(entry);
985 if (treeReadEntry < 0) {
986 return 0;
987 }
988 if (!fTree) {
989 return 0;
990 }
991 return fTree->GetEntry(treeReadEntry, getall);
992}
993
994////////////////////////////////////////////////////////////////////////////////
995/// Return entry number corresponding to entry.
996///
997/// if no TEntryList set returns entry
998/// else returns entry \#entry from this entry list and
999/// also computes the global entry number (loads all tree headers)
1000
1002{
1003
1004 if (fEntryList){
1005 Int_t treenum = 0;
1006 Long64_t localentry = fEntryList->GetEntryAndTree(entry, treenum);
1007 //find the global entry number
1008 //same const_cast as in the GetEntries() function
1009 if (localentry<0) return -1;
1010 if (treenum != fTreeNumber){
1011 if (fTreeOffset[treenum]==TTree::kMaxEntries){
1012 for (Int_t i=0; i<=treenum; i++){
1014 (const_cast<TChain*>(this))->LoadTree(fTreeOffset[i-1]);
1015 }
1016 }
1017 //(const_cast<TChain*>(this))->LoadTree(fTreeOffset[treenum]);
1018 }
1019 Long64_t globalentry = fTreeOffset[treenum] + localentry;
1020 return globalentry;
1021 }
1022 return entry;
1023}
1024
1025////////////////////////////////////////////////////////////////////////////////
1026/// Return entry corresponding to major and minor number.
1027///
1028/// The function returns the total number of bytes read.
1029/// If the Tree has friend trees, the corresponding entry with
1030/// the index values (major,minor) is read. Note that the master Tree
1031/// and its friend may have different entry serial numbers corresponding
1032/// to (major,minor).
1033
1035{
1036 Long64_t serial = GetEntryNumberWithIndex(major, minor);
1037 if (serial < 0) return -1;
1038 return GetEntry(serial);
1039}
1040
1041////////////////////////////////////////////////////////////////////////////////
1042/// Return a pointer to the current file.
1043/// If no file is connected, the first file is automatically loaded.
1044
1046{
1047 if (fFile) {
1048 return fFile;
1049 }
1050 // Force opening the first file in the chain.
1051 const_cast<TChain*>(this)->LoadTree(0);
1052 return fFile;
1053}
1054
1055////////////////////////////////////////////////////////////////////////////////
1056/// Return a pointer to the leaf name in the current tree.
1057
1058TLeaf* TChain::GetLeaf(const char* branchname, const char *leafname)
1059{
1061 // Make sure the element list is up to date
1062 if (!TestBit(kProofUptodate))
1064 return fProofChain->GetLeaf(branchname, leafname);
1065 }
1066 if (fTree) {
1067 return fTree->GetLeaf(branchname, leafname);
1068 }
1069 LoadTree(0);
1070 if (fTree) {
1071 return fTree->GetLeaf(branchname, leafname);
1072 }
1073 return 0;
1074}
1075
1076////////////////////////////////////////////////////////////////////////////////
1077/// Return a pointer to the leaf name in the current tree.
1078
1080{
1082 // Make sure the element list is up to date
1083 if (!TestBit(kProofUptodate))
1085 return fProofChain->GetLeaf(name);
1086 }
1087 if (fTree) {
1088 return fTree->GetLeaf(name);
1089 }
1090 LoadTree(0);
1091 if (fTree) {
1092 return fTree->GetLeaf(name);
1093 }
1094 return 0;
1095}
1096
1097////////////////////////////////////////////////////////////////////////////////
1098/// Return a pointer to the list of branches of the current tree.
1099///
1100/// Warning: If there is no current TTree yet, this routine will open the
1101/// first in the chain.
1102///
1103/// Returns 0 on failure.
1104
1106{
1108 // Make sure the element list is up to date
1109 if (!TestBit(kProofUptodate))
1112 }
1113 if (fTree) {
1114 return fTree->GetListOfBranches();
1115 }
1116 LoadTree(0);
1117 if (fTree) {
1118 return fTree->GetListOfBranches();
1119 }
1120 return 0;
1121}
1122
1123////////////////////////////////////////////////////////////////////////////////
1124/// Return a pointer to the list of leaves of the current tree.
1125///
1126/// Warning: May set the current tree!
1127
1129{
1131 // Make sure the element list is up to date
1132 if (!TestBit(kProofUptodate))
1134 return fProofChain->GetListOfLeaves();
1135 }
1136 if (fTree) {
1137 return fTree->GetListOfLeaves();
1138 }
1139 LoadTree(0);
1140 if (fTree) {
1141 return fTree->GetListOfLeaves();
1142 }
1143 return 0;
1144}
1145
1146////////////////////////////////////////////////////////////////////////////////
1147/// Return maximum of column with name columname.
1148
1149Double_t TChain::GetMaximum(const char* columname)
1150{
1151 Double_t theMax = -DBL_MAX;
1152 for (Int_t file = 0; file < fNtrees; file++) {
1154 LoadTree(first);
1155 Double_t curmax = fTree->GetMaximum(columname);
1156 if (curmax > theMax) {
1157 theMax = curmax;
1158 }
1159 }
1160 return theMax;
1161}
1162
1163////////////////////////////////////////////////////////////////////////////////
1164/// Return minimum of column with name columname.
1165
1166Double_t TChain::GetMinimum(const char* columname)
1167{
1168 Double_t theMin = DBL_MAX;
1169 for (Int_t file = 0; file < fNtrees; file++) {
1171 LoadTree(first);
1172 Double_t curmin = fTree->GetMinimum(columname);
1173 if (curmin < theMin) {
1174 theMin = curmin;
1175 }
1176 }
1177 return theMin;
1178}
1179
1180////////////////////////////////////////////////////////////////////////////////
1181/// Return the number of branches of the current tree.
1182///
1183/// Warning: May set the current tree!
1184
1186{
1187 if (fTree) {
1188 return fTree->GetNbranches();
1189 }
1190 LoadTree(0);
1191 if (fTree) {
1192 return fTree->GetNbranches();
1193 }
1194 return 0;
1195}
1196
1197////////////////////////////////////////////////////////////////////////////////
1198/// See TTree::GetReadEntry().
1199
1201{
1203 // Make sure the element list is up to date
1204 if (!TestBit(kProofUptodate))
1205 Warning("GetBranchStatus", "PROOF proxy not up-to-date:"
1206 " run TChain::SetProof(kTRUE, kTRUE) first");
1207 return fProofChain->GetReadEntry();
1208 }
1209 return TTree::GetReadEntry();
1210}
1211
1212////////////////////////////////////////////////////////////////////////////////
1213/// Return the chain weight.
1214///
1215/// By default the weight is the weight of the current tree.
1216/// However, if the weight has been set in TChain::SetWeight()
1217/// with the option "global", then that weight will be returned.
1218///
1219/// Warning: May set the current tree!
1220
1222{
1223 if (TestBit(kGlobalWeight)) {
1224 return fWeight;
1225 } else {
1226 if (fTree) {
1227 return fTree->GetWeight();
1228 }
1229 const_cast<TChain*>(this)->LoadTree(0);
1230 if (fTree) {
1231 return fTree->GetWeight();
1232 }
1233 return 0;
1234 }
1235}
1236
1237////////////////////////////////////////////////////////////////////////////////
1238/// Move content to a new file. (NOT IMPLEMENTED for TChain)
1239Bool_t TChain::InPlaceClone(TDirectory * /* new directory */, const char * /* options */)
1240{
1241 Error("InPlaceClone", "not implemented");
1242 return false;
1243}
1244
1245////////////////////////////////////////////////////////////////////////////////
1246/// Set the TTree to be reloaded as soon as possible. In particular this
1247/// is needed when adding a Friend.
1248///
1249/// If the tree has clones, copy them into the chain
1250/// clone list so we can change their branch addresses
1251/// when necessary.
1252///
1253/// This is to support the syntax:
1254/// ~~~ {.cpp}
1255/// TTree* clone = chain->GetTree()->CloneTree(0);
1256/// ~~~
1257
1259{
1260 if (fTree && fTree->GetListOfClones()) {
1261 for (TObjLink* lnk = fTree->GetListOfClones()->FirstLink(); lnk; lnk = lnk->Next()) {
1262 TTree* clone = (TTree*) lnk->GetObject();
1263 AddClone(clone);
1264 }
1265 }
1266 fTreeNumber = -1;
1267 fTree = 0;
1268}
1269
1270////////////////////////////////////////////////////////////////////////////////
1271/// Dummy function.
1272/// It could be implemented and load all baskets of all trees in the chain.
1273/// For the time being use TChain::Merge and TTree::LoadBasket
1274/// on the resulting tree.
1275
1277{
1278 Error("LoadBaskets", "Function not yet implemented for TChain.");
1279 return 0;
1280}
1281
1282////////////////////////////////////////////////////////////////////////////////
1283/// Find the tree which contains entry, and set it as the current tree.
1284///
1285/// Returns the entry number in that tree.
1286///
1287/// The input argument entry is the entry serial number in the whole chain.
1288///
1289/// In case of error, LoadTree returns a negative number:
1290/// * -1: The chain is empty.
1291/// * -2: The requested entry number is less than zero or too large for the chain.
1292/// * -3: The file corresponding to the entry could not be correctly open
1293/// * -4: The TChainElement corresponding to the entry is missing or
1294/// the TTree is missing from the file.
1295/// * -5: Internal error, please report the circumstance when this happen
1296/// as a ROOT issue.
1297/// * -6: An error occurred within the notify callback.
1298///
1299/// Note: This is the only routine which sets the value of fTree to
1300/// a non-zero pointer.
1301
1303{
1304 // We already have been visited while recursively looking
1305 // through the friends tree, let's return.
1307 return 0;
1308 }
1309
1310 if (!fNtrees) {
1311 // -- The chain is empty.
1312 return -1;
1313 }
1314
1315 if ((entry < 0) || ((entry > 0) && (entry >= fEntries && entry!=(TTree::kMaxEntries-1) ))) {
1316 // -- Invalid entry number.
1317 if (fTree) fTree->LoadTree(-1);
1318 fReadEntry = -1;
1319 return -2;
1320 }
1321
1322 // Find out which tree in the chain contains the passed entry.
1323 Int_t treenum = fTreeNumber;
1324 if ((fTreeNumber == -1) || (entry < fTreeOffset[fTreeNumber]) || (entry >= fTreeOffset[fTreeNumber+1]) || (entry==TTree::kMaxEntries-1)) {
1325 // -- Entry is *not* in the chain's current tree.
1326 // Do a linear search of the tree offset array.
1327 // FIXME: We could be smarter by starting at the
1328 // current tree number and going forwards,
1329 // then wrapping around at the end.
1330 for (treenum = 0; treenum < fNtrees; treenum++) {
1331 if (entry < fTreeOffset[treenum+1]) {
1332 break;
1333 }
1334 }
1335 }
1336
1337 // Calculate the entry number relative to the found tree.
1338 Long64_t treeReadEntry = entry - fTreeOffset[treenum];
1339 fReadEntry = entry;
1340
1341 // If entry belongs to the current tree return entry.
1342 if (fTree && treenum == fTreeNumber) {
1343 // First set the entry the tree on its owns friends
1344 // (the friends of the chain will be updated in the
1345 // next loop).
1346 fTree->LoadTree(treeReadEntry);
1347 if (fFriends) {
1348 // The current tree has not changed but some of its friends might.
1349 //
1350 TIter next(fFriends);
1351 TFriendLock lock(this, kLoadTree);
1352 TFriendElement* fe = 0;
1353 while ((fe = (TFriendElement*) next())) {
1354 TTree* at = fe->GetTree();
1355 // If the tree is a
1356 // direct friend of the chain, it should be scanned
1357 // used the chain entry number and NOT the tree entry
1358 // number (treeReadEntry) hence we do:
1359 at->LoadTreeFriend(entry, this);
1360 }
1361 Bool_t needUpdate = kFALSE;
1362 if (fTree->GetListOfFriends()) {
1364 if (fetree->IsUpdated()) {
1365 needUpdate = kTRUE;
1366 fetree->ResetUpdated();
1367 }
1368 }
1369 }
1370 if (needUpdate) {
1371 // Update the branch/leaf addresses and
1372 // the list of leaves in all TTreeFormula of the TTreePlayer (if any).
1373
1374 // Set the branch statuses for the newly opened file.
1375 TChainElement *frelement;
1376 TIter fnext(fStatus);
1377 while ((frelement = (TChainElement*) fnext())) {
1378 Int_t status = frelement->GetStatus();
1379 fTree->SetBranchStatus(frelement->GetName(), status);
1380 }
1381
1382 // Set the branch addresses for the newly opened file.
1383 fnext.Reset();
1384 while ((frelement = (TChainElement*) fnext())) {
1385 void* addr = frelement->GetBaddress();
1386 if (addr) {
1387 TBranch* br = fTree->GetBranch(frelement->GetName());
1388 TBranch** pp = frelement->GetBranchPtr();
1389 if (pp) {
1390 // FIXME: What if br is zero here?
1391 *pp = br;
1392 }
1393 if (br) {
1394 if (!frelement->GetCheckedType()) {
1396 (EDataType) frelement->GetBaddressType(), frelement->GetBaddressIsPtr());
1397 if ((res & kNeedEnableDecomposedObj) && !br->GetMakeClass()) {
1398 br->SetMakeClass(kTRUE);
1399 }
1400 frelement->SetDecomposedObj(br->GetMakeClass());
1401 frelement->SetCheckedType(kTRUE);
1402 }
1403 // FIXME: We may have to tell the branch it should
1404 // not be an owner of the object pointed at.
1405 br->SetAddress(addr);
1406 if (TestBit(kAutoDelete)) {
1407 br->SetAutoDelete(kTRUE);
1408 }
1409 }
1410 }
1411 }
1412 if (fPlayer) {
1414 }
1415 // Notify user if requested.
1416 if (fNotify) {
1417 if(!fNotify->Notify()) return -6;
1418 }
1419 }
1420 }
1421 return treeReadEntry;
1422 }
1423
1424 if (fExternalFriends) {
1426 external_fe->MarkUpdated();
1427 }
1428 }
1429
1430 // Delete the current tree and open the new tree.
1431 TTreeCache* tpf = 0;
1432 // Delete file unless the file owns this chain!
1433 // FIXME: The "unless" case here causes us to leak memory.
1434 if (fFile) {
1435 if (!fDirectory->GetList()->FindObject(this)) {
1436 if (fTree) {
1437 // (fFile != 0 && fTree == 0) can happen when
1438 // InvalidateCurrentTree is called (for example from
1439 // AddFriend). Having fTree === 0 is necessary in that
1440 // case because in some cases GetTree is used as a check
1441 // to see if a TTree is already loaded.
1442 // However, this prevent using the following to reuse
1443 // the TTreeCache object.
1444 tpf = fTree->GetReadCache(fFile);
1445 if (tpf) {
1446 tpf->ResetCache();
1447 }
1448
1450 // If the tree has clones, copy them into the chain
1451 // clone list so we can change their branch addresses
1452 // when necessary.
1453 //
1454 // This is to support the syntax:
1455 //
1456 // TTree* clone = chain->GetTree()->CloneTree(0);
1457 //
1458 // We need to call the invalidate exactly here, since
1459 // we no longer need the value of fTree and it is
1460 // about to be deleted.
1462 }
1463
1464 if (fCanDeleteRefs) {
1465 fFile->Close("R");
1466 }
1467 delete fFile;
1468 fFile = 0;
1469 } else {
1470 // If the tree has clones, copy them into the chain
1471 // clone list so we can change their branch addresses
1472 // when necessary.
1473 //
1474 // This is to support the syntax:
1475 //
1476 // TTree* clone = chain->GetTree()->CloneTree(0);
1477 //
1479 }
1480 }
1481
1482 TChainElement* element = (TChainElement*) fFiles->At(treenum);
1483 if (!element) {
1484 if (treeReadEntry) {
1485 return -4;
1486 }
1487 // Last attempt, just in case all trees in the chain have 0 entries.
1488 element = (TChainElement*) fFiles->At(0);
1489 if (!element) {
1490 return -4;
1491 }
1492 }
1493
1494 // FIXME: We leak memory here, we've just lost the open file
1495 // if we did not delete it above.
1496 {
1498 const char *option = fGlobalRegistration ? "READ" : "READ_WITHOUT_GLOBALREGISTRATION";
1499 fFile = TFile::Open(element->GetTitle(), option);
1502 }
1503
1504 // ----- Begin of modifications by MvL
1505 Int_t returnCode = 0;
1506 if (!fFile || fFile->IsZombie()) {
1507 if (fFile) {
1508 delete fFile;
1509 fFile = 0;
1510 }
1511 // Note: We do *not* own fTree.
1512 fTree = 0;
1513 returnCode = -3;
1514 } else {
1515 if (fPerfStats)
1517
1518 // Note: We do *not* own fTree after this, the file does!
1519 fTree = dynamic_cast<TTree*>(fFile->Get(element->GetName()));
1520 if (!fTree) {
1521 // Now that we do not check during the addition, we need to check here!
1522 Error("LoadTree", "Cannot find tree with name %s in file %s", element->GetName(), element->GetTitle());
1523 delete fFile;
1524 fFile = 0;
1525 // We do not return yet so that 'fEntries' can be updated with the
1526 // sum of the entries of all the other trees.
1527 returnCode = -4;
1528 } else if (!fGlobalRegistration) {
1530 }
1531 }
1532
1533 fTreeNumber = treenum;
1534 // FIXME: We own fFile, we must be careful giving away a pointer to it!
1535 // FIXME: We may set fDirectory to zero here!
1536 fDirectory = fFile;
1537
1538 // Reuse cache from previous file (if any).
1539 if (tpf) {
1540 if (fFile) {
1541 // FIXME: fTree may be zero here.
1542 tpf->UpdateBranches(fTree);
1543 tpf->ResetCache();
1544 fFile->SetCacheRead(tpf, fTree);
1545 } else {
1546 // FIXME: One of the file in the chain is missing
1547 // we have no place to hold the pointer to the
1548 // TTreeCache.
1549 delete tpf;
1550 tpf = 0;
1551 }
1552 } else {
1553 if (fCacheUserSet) {
1554 this->SetCacheSize(fCacheSize);
1555 }
1556 }
1557
1558 // Check if fTreeOffset has really been set.
1559 Long64_t nentries = 0;
1560 if (fTree) {
1562 }
1563
1567 element->SetNumberEntries(nentries);
1568 // Below we must test >= in case the tree has no entries.
1569 if (entry >= fTreeOffset[fTreeNumber+1]) {
1570 if ((fTreeNumber < (fNtrees - 1)) && (entry < fTreeOffset[fTreeNumber+2])) {
1571 // The request entry is not in the tree 'fTreeNumber' we will need
1572 // to look further.
1573
1574 // Before moving on, let's record the result.
1575 element->SetLoadResult(returnCode);
1576
1577 // Before trying to read the file file/tree, notify the user
1578 // that we have switched trees if requested; the user might need
1579 // to properly account for the number of files/trees even if they
1580 // have no entries.
1581 if (fNotify) {
1582 if(!fNotify->Notify()) return -6;
1583 }
1584
1585 // Load the next TTree.
1586 return LoadTree(entry);
1587 } else {
1588 treeReadEntry = fReadEntry = -2;
1589 }
1590 }
1591 }
1592
1593
1594 if (!fTree) {
1595 // The Error message already issued. However if we reach here
1596 // we need to make sure that we do not use fTree.
1597 //
1598 // Force a reload of the tree next time.
1599 fTreeNumber = -1;
1600
1601 element->SetLoadResult(returnCode);
1602 return returnCode;
1603 }
1604 // ----- End of modifications by MvL
1605
1606 // Copy the chain's clone list into the new tree's
1607 // clone list so that branch addresses stay synchronized.
1608 if (fClones) {
1609 for (TObjLink* lnk = fClones->FirstLink(); lnk; lnk = lnk->Next()) {
1610 TTree* clone = (TTree*) lnk->GetObject();
1611 ((TChain*) fTree)->TTree::AddClone(clone);
1612 }
1613 }
1614
1615 // Since some of the friends of this chain might simple trees
1616 // (i.e., not really chains at all), we need to execute this
1617 // before calling LoadTree(entry) on the friends (so that
1618 // they use the correct read entry number).
1619
1620 // Change the new current tree to the new entry.
1621 Long64_t loadResult = fTree->LoadTree(treeReadEntry);
1622 if (loadResult == treeReadEntry) {
1623 element->SetLoadResult(0);
1624 } else {
1625 // This is likely to be an internal error, if treeReadEntry was not in range
1626 // (or intentionally -2 for TChain::GetEntries) then something happened
1627 // that is very odd/surprising.
1628 element->SetLoadResult(-5);
1629 }
1630
1631
1632 // Change the chain friends to the new entry.
1633 if (fFriends) {
1634 // An alternative would move this code to each of the function
1635 // calling LoadTree (and to overload a few more).
1636 TIter next(fFriends);
1637 TFriendLock lock(this, kLoadTree);
1638 TFriendElement* fe = 0;
1639 while ((fe = (TFriendElement*) next())) {
1640 TTree* t = fe->GetTree();
1641 if (!t) continue;
1642 if (t->GetTreeIndex()) {
1644 }
1645 if (t->GetTree() && t->GetTree()->GetTreeIndex()) {
1647 }
1648 if (treeReadEntry == -2) {
1649 // an entry after the end of the chain was requested (it usually happens when GetEntries is called)
1650 t->LoadTree(entry);
1651 } else {
1652 t->LoadTreeFriend(entry, this);
1653 }
1654 TTree* friend_t = t->GetTree();
1655 if (friend_t) {
1656 auto localfe = fTree->AddFriend(t, fe->GetName());
1658 }
1659 }
1660 }
1661
1664
1666
1667 // Set the branch statuses for the newly opened file.
1668 TIter next(fStatus);
1669 while ((element = (TChainElement*) next())) {
1670 Int_t status = element->GetStatus();
1671 fTree->SetBranchStatus(element->GetName(), status);
1672 }
1673
1674 // Set the branch addresses for the newly opened file.
1675 next.Reset();
1676 while ((element = (TChainElement*) next())) {
1677 void* addr = element->GetBaddress();
1678 if (addr) {
1679 TBranch* br = fTree->GetBranch(element->GetName());
1680 TBranch** pp = element->GetBranchPtr();
1681 if (pp) {
1682 // FIXME: What if br is zero here?
1683 *pp = br;
1684 }
1685 if (br) {
1686 if (!element->GetCheckedType()) {
1688 (EDataType) element->GetBaddressType(), element->GetBaddressIsPtr());
1689 if ((res & kNeedEnableDecomposedObj) && !br->GetMakeClass()) {
1690 br->SetMakeClass(kTRUE);
1691 }
1692 element->SetDecomposedObj(br->GetMakeClass());
1693 element->SetCheckedType(kTRUE);
1694 }
1695 // FIXME: We may have to tell the branch it should
1696 // not be an owner of the object pointed at.
1697 br->SetAddress(addr);
1698 if (TestBit(kAutoDelete)) {
1699 br->SetAutoDelete(kTRUE);
1700 }
1701 }
1702 }
1703 }
1704
1705 // Update the addresses of the chain's cloned trees, if any.
1706 if (fClones) {
1707 for (TObjLink* lnk = fClones->FirstLink(); lnk; lnk = lnk->Next()) {
1708 TTree* clone = (TTree*) lnk->GetObject();
1709 CopyAddresses(clone);
1710 }
1711 }
1712
1713 // Update list of leaves in all TTreeFormula's of the TTreePlayer (if any).
1714 if (fPlayer) {
1716 }
1717
1718 // Notify user we have switched trees if requested.
1719 if (fNotify) {
1720 if(!fNotify->Notify()) return -6;
1721 }
1722
1723 // Return the new local entry number.
1724 return treeReadEntry;
1725}
1726
1727////////////////////////////////////////////////////////////////////////////////
1728/// Check / locate the files in the chain.
1729/// By default only the files not yet looked up are checked.
1730/// Use force = kTRUE to check / re-check every file.
1731
1733{
1734 TIter next(fFiles);
1735 TChainElement* element = 0;
1736 Int_t nelements = fFiles->GetEntries();
1737 printf("\n");
1738 printf("TChain::Lookup - Looking up %d files .... \n", nelements);
1739 Int_t nlook = 0;
1740 TFileStager *stg = 0;
1741 while ((element = (TChainElement*) next())) {
1742 // Do not do it more than needed
1743 if (element->HasBeenLookedUp() && !force) continue;
1744 // Count
1745 nlook++;
1746 // Get the Url
1747 TUrl elemurl(element->GetTitle(), kTRUE);
1748 // Save current options and anchor
1749 TString anchor = elemurl.GetAnchor();
1750 TString options = elemurl.GetOptions();
1751 // Reset options and anchor
1752 elemurl.SetOptions("");
1753 elemurl.SetAnchor("");
1754 // Locate the file
1755 TString eurl(elemurl.GetUrl());
1756 if (!stg || !stg->Matches(eurl)) {
1757 SafeDelete(stg);
1758 {
1760 stg = TFileStager::Open(eurl);
1761 }
1762 if (!stg) {
1763 Error("Lookup", "TFileStager instance cannot be instantiated");
1764 break;
1765 }
1766 }
1767 Int_t n1 = (nelements > 100) ? (Int_t) nelements / 100 : 1;
1768 if (stg->Locate(eurl.Data(), eurl) == 0) {
1769 if (nlook > 0 && !(nlook % n1)) {
1770 printf("Lookup | %3d %% finished\r", 100 * nlook / nelements);
1771 fflush(stdout);
1772 }
1773 // Get the effective end-point Url
1774 elemurl.SetUrl(eurl);
1775 // Restore original options and anchor, if any
1776 elemurl.SetOptions(options);
1777 elemurl.SetAnchor(anchor);
1778 // Save it into the element
1779 element->SetTitle(elemurl.GetUrl());
1780 // Remember
1781 element->SetLookedUp();
1782 } else {
1783 // Failure: remove
1784 fFiles->Remove(element);
1785 if (gSystem->AccessPathName(eurl))
1786 Error("Lookup", "file %s does not exist\n", eurl.Data());
1787 else
1788 Error("Lookup", "file %s cannot be read\n", eurl.Data());
1789 }
1790 }
1791 if (nelements > 0)
1792 printf("Lookup | %3d %% finished\n", 100 * nlook / nelements);
1793 else
1794 printf("\n");
1795 fflush(stdout);
1796 SafeDelete(stg);
1797}
1798
1799////////////////////////////////////////////////////////////////////////////////
1800/// Loop on nentries of this chain starting at firstentry. (NOT IMPLEMENTED)
1801
1803{
1804 Error("Loop", "Function not yet implemented");
1805
1806 if (option || nentries || firstentry) { } // keep warnings away
1807
1808#if 0
1809 if (LoadTree(firstentry) < 0) return;
1810
1811 if (firstentry < 0) firstentry = 0;
1812 Long64_t lastentry = firstentry + nentries -1;
1813 if (lastentry > fEntries-1) {
1814 lastentry = fEntries -1;
1815 }
1816
1817 GetPlayer();
1818 GetSelector();
1819 fSelector->Start(option);
1820
1821 Long64_t entry = firstentry;
1822 Int_t tree,e0,en;
1823 for (tree=0;tree<fNtrees;tree++) {
1824 e0 = fTreeOffset[tree];
1825 en = fTreeOffset[tree+1] - 1;
1826 if (en > lastentry) en = lastentry;
1827 if (entry > en) continue;
1828
1829 LoadTree(entry);
1830 fSelector->BeginFile();
1831
1832 while (entry <= en) {
1833 fSelector->Execute(fTree, entry - e0);
1834 entry++;
1835 }
1836 fSelector->EndFile();
1837 }
1838
1839 fSelector->Finish(option);
1840#endif
1841}
1842
1843////////////////////////////////////////////////////////////////////////////////
1844/// List the chain.
1845
1846void TChain::ls(Option_t* option) const
1847{
1848 TObject::ls(option);
1849 TIter next(fFiles);
1850 TChainElement* file = 0;
1852 while ((file = (TChainElement*)next())) {
1853 file->ls(option);
1854 }
1856}
1857
1858////////////////////////////////////////////////////////////////////////////////
1859/// Merge all the entries in the chain into a new tree in a new file.
1860///
1861/// See important note in the following function Merge().
1862///
1863/// If the chain is expecting the input tree inside a directory,
1864/// this directory is NOT created by this routine.
1865///
1866/// So in a case where we have:
1867/// ~~~ {.cpp}
1868/// TChain ch("mydir/mytree");
1869/// ch.Merge("newfile.root");
1870/// ~~~
1871/// The resulting file will have not subdirectory. To recreate
1872/// the directory structure do:
1873/// ~~~ {.cpp}
1874/// TFile* file = TFile::Open("newfile.root", "RECREATE");
1875/// file->mkdir("mydir")->cd();
1876/// ch.Merge(file);
1877/// ~~~
1878
1880{
1881 TFile *file = TFile::Open(name, "recreate", "chain files", 1);
1882 return Merge(file, 0, option);
1883}
1884
1885////////////////////////////////////////////////////////////////////////////////
1886/// Merge all chains in the collection. (NOT IMPLEMENTED)
1887
1888Long64_t TChain::Merge(TCollection* /* list */, Option_t* /* option */ )
1889{
1890 Error("Merge", "not implemented");
1891 return -1;
1892}
1893
1894////////////////////////////////////////////////////////////////////////////////
1895/// Merge all chains in the collection. (NOT IMPLEMENTED)
1896
1898{
1899 Error("Merge", "not implemented");
1900 return -1;
1901}
1902
1903////////////////////////////////////////////////////////////////////////////////
1904/// Merge all the entries in the chain into a new tree in the current file.
1905///
1906/// Note: The "file" parameter is *not* the file where the new
1907/// tree will be inserted. The new tree is inserted into
1908/// gDirectory, which is usually the most recently opened
1909/// file, or the directory most recently cd()'d to.
1910///
1911/// If option = "C" is given, the compression level for all branches
1912/// in the new Tree is set to the file compression level. By default,
1913/// the compression level of all branches is the original compression
1914/// level in the old trees.
1915///
1916/// If basketsize > 1000, the basket size for all branches of the
1917/// new tree will be set to basketsize.
1918///
1919/// Example using the file generated in $ROOTSYS/test/Event
1920/// merge two copies of Event.root
1921/// ~~~ {.cpp}
1922/// gSystem.Load("libEvent");
1923/// TChain ch("T");
1924/// ch.Add("Event1.root");
1925/// ch.Add("Event2.root");
1926/// ch.Merge("all.root");
1927/// ~~~
1928/// If the chain is expecting the input tree inside a directory,
1929/// this directory is NOT created by this routine.
1930///
1931/// So if you do:
1932/// ~~~ {.cpp}
1933/// TChain ch("mydir/mytree");
1934/// ch.Merge("newfile.root");
1935/// ~~~
1936/// The resulting file will not have subdirectories. In order to
1937/// preserve the directory structure do the following instead:
1938/// ~~~ {.cpp}
1939/// TFile* file = TFile::Open("newfile.root", "RECREATE");
1940/// file->mkdir("mydir")->cd();
1941/// ch.Merge(file);
1942/// ~~~
1943/// If 'option' contains the word 'fast' the merge will be done without
1944/// unzipping or unstreaming the baskets (i.e., a direct copy of the raw
1945/// bytes on disk).
1946///
1947/// When 'fast' is specified, 'option' can also contains a
1948/// sorting order for the baskets in the output file.
1949///
1950/// There is currently 3 supported sorting order:
1951/// ~~~ {.cpp}
1952/// SortBasketsByOffset (the default)
1953/// SortBasketsByBranch
1954/// SortBasketsByEntry
1955/// ~~~
1956/// When using SortBasketsByOffset the baskets are written in
1957/// the output file in the same order as in the original file
1958/// (i.e. the basket are sorted on their offset in the original
1959/// file; Usually this also means that the baskets are sorted
1960/// on the index/number of the _last_ entry they contain)
1961///
1962/// When using SortBasketsByBranch all the baskets of each
1963/// individual branches are stored contiguously. This tends to
1964/// optimize reading speed when reading a small number (1->5) of
1965/// branches, since all their baskets will be clustered together
1966/// instead of being spread across the file. However it might
1967/// decrease the performance when reading more branches (or the full
1968/// entry).
1969///
1970/// When using SortBasketsByEntry the baskets with the lowest
1971/// starting entry are written first. (i.e. the baskets are
1972/// sorted on the index/number of the first entry they contain).
1973/// This means that on the file the baskets will be in the order
1974/// in which they will be needed when reading the whole tree
1975/// sequentially.
1976///
1977/// ## IMPORTANT Note 1: AUTOMATIC FILE OVERFLOW
1978///
1979/// When merging many files, it may happen that the resulting file
1980/// reaches a size > TTree::fgMaxTreeSize (default = 100 GBytes).
1981/// In this case the current file is automatically closed and a new
1982/// file started. If the name of the merged file was "merged.root",
1983/// the subsequent files will be named "merged_1.root", "merged_2.root",
1984/// etc. fgMaxTreeSize may be modified via the static function
1985/// TTree::SetMaxTreeSize.
1986/// When in fast mode, the check and switch is only done in between each
1987/// input file.
1988///
1989/// ## IMPORTANT Note 2: The output file is automatically closed and deleted.
1990///
1991/// This is required because in general the automatic file overflow described
1992/// above may happen during the merge.
1993/// If only the current file is produced (the file passed as first argument),
1994/// one can instruct Merge to not close and delete the file by specifying
1995/// the option "keep".
1996///
1997/// The function returns the total number of files produced.
1998/// To check that all files have been merged use something like:
1999/// ~~~ {.cpp}
2000/// if (newchain->GetEntries()!=oldchain->GetEntries()) {
2001/// ... not all the file have been copied ...
2002/// }
2003/// ~~~
2004
2006{
2007 // We must have been passed a file, we will use it
2008 // later to reset the compression level of the branches.
2009 if (!file) {
2010 // FIXME: We need an error message here.
2011 return 0;
2012 }
2013
2014 // Options
2015 Bool_t fastClone = kFALSE;
2016 TString opt = option;
2017 opt.ToLower();
2018 if (opt.Contains("fast")) {
2019 fastClone = kTRUE;
2020 }
2021
2022 // The chain tree must have a list of branches
2023 // because we may try to change their basket
2024 // size later.
2025 TObjArray* lbranches = GetListOfBranches();
2026 if (!lbranches) {
2027 // FIXME: We need an error message here.
2028 return 0;
2029 }
2030
2031 // The chain must have a current tree because
2032 // that is the one we will clone.
2033 if (!fTree) {
2034 // -- LoadTree() has not yet been called, no current tree.
2035 // FIXME: We need an error message here.
2036 return 0;
2037 }
2038
2039 // Copy the chain's current tree without
2040 // copying any entries, we will do that later.
2041 TTree* newTree = CloneTree(0);
2042 if (!newTree) {
2043 // FIXME: We need an error message here.
2044 return 0;
2045 }
2046
2047 // Strip out the (potential) directory name.
2048 // FIXME: The merged chain may or may not have the
2049 // same name as the original chain. This is
2050 // bad because the chain name determines the
2051 // names of the trees in the chain by default.
2052 newTree->SetName(gSystem->BaseName(GetName()));
2053
2054 // FIXME: Why do we do this?
2055 newTree->SetAutoSave(2000000000);
2056
2057 // Circularity is incompatible with merging, it may
2058 // force us to throw away entries, which is not what
2059 // we are supposed to do.
2060 newTree->SetCircular(0);
2061
2062 // Reset the compression level of the branches.
2063 if (opt.Contains("c")) {
2064 TBranch* branch = 0;
2065 TIter nextb(newTree->GetListOfBranches());
2066 while ((branch = (TBranch*) nextb())) {
2067 branch->SetCompressionSettings(file->GetCompressionSettings());
2068 }
2069 }
2070
2071 // Reset the basket size of the branches.
2072 if (basketsize > 1000) {
2073 TBranch* branch = 0;
2074 TIter nextb(newTree->GetListOfBranches());
2075 while ((branch = (TBranch*) nextb())) {
2076 branch->SetBasketSize(basketsize);
2077 }
2078 }
2079
2080 // Copy the entries.
2081 if (fastClone) {
2082 if ( newTree->CopyEntries( this, -1, option ) < 0 ) {
2083 // There was a problem!
2084 Error("Merge", "TTree has not been cloned\n");
2085 }
2086 } else {
2087 newTree->CopyEntries( this, -1, option );
2088 }
2089
2090 // Write the new tree header.
2091 newTree->Write();
2092
2093 // Get our return value.
2094 Int_t nfiles = newTree->GetFileNumber() + 1;
2095
2096 // Close and delete the current file of the new tree.
2097 if (!opt.Contains("keep")) {
2098 // Delete the currentFile and the TTree object.
2099 delete newTree->GetCurrentFile();
2100 }
2101 return nfiles;
2102}
2103
2104////////////////////////////////////////////////////////////////////////////////
2105/// Get the tree url or filename and other information from the name
2106///
2107/// A treename and a url's query section is split off from name. The
2108/// splitting depends on whether the resulting filename is to be
2109/// subsequently treated for wildcards or not, since the question mark is
2110/// both the url query identifier and a wildcard. Wildcard matching is not
2111/// done in this method itself.
2112/// ~~~ {.cpp}
2113/// [xxx://host]/a/path/file_name[?query[#treename]]
2114/// ~~~
2115///
2116/// The following way to specify the treename is still supported with the
2117/// constrain that the file name contains the sub-string '.root'.
2118/// This is now deprecated and will be removed in future versions.
2119/// ~~~ {.cpp}
2120/// [xxx://host]/a/path/file.root[.oext][/treename]
2121/// [xxx://host]/a/path/file.root[.oext][/treename][?query]
2122/// ~~~
2123///
2124/// Note that in a case like this
2125/// ~~~ {.cpp}
2126/// [xxx://host]/a/path/file#treename
2127/// ~~~
2128/// i.e. anchor but no options (query), the filename will be the full path, as
2129/// the anchor may be the internal file name of an archive. Use '?#treename' to
2130/// pass the treename if the query field is empty.
2131///
2132/// \param[in] name is the original name
2133/// \param[in] wildcards indicates if the resulting filename will be treated for
2134/// wildcards. For backwards compatibility, with most protocols
2135/// this flag suppresses the search for the url fragment
2136/// identifier and limits the query identifier search to cases
2137/// where the tree name is given as a trailing slash-separated
2138/// string at the end of the file name.
2139/// \param[out] filename the url or filename to be opened or matched
2140/// \param[out] treename the treename, which may be found in a url fragment section
2141/// as a trailing part of the name (deprecated).
2142/// If not found this will be empty.
2143/// \param[out] query is the url query section, including the leading question
2144/// mark. If not found or the query section is only followed by
2145/// a fragment this will be empty.
2146/// \param[out] suffix the portion of name which was removed to from filename.
2147
2148void TChain::ParseTreeFilename(const char *name, TString &filename, TString &treename, TString &query, TString &suffix,
2149 Bool_t) const
2150{
2151 Ssiz_t pIdx = kNPOS;
2152 filename.Clear();
2153 treename.Clear();
2154 query.Clear();
2155 suffix.Clear();
2156
2157 // General case
2158 TUrl url(name, kTRUE);
2159 filename = (strcmp(url.GetProtocol(), "file")) ? url.GetUrl() : url.GetFileAndOptions();
2160
2161 TString fn = url.GetFile();
2162 // Extract query, if any
2163 if (url.GetOptions() && (strlen(url.GetOptions()) > 0))
2164 query.Form("?%s", url.GetOptions());
2165 // The treename can be passed as anchor
2166 if (url.GetAnchor() && (strlen(url.GetAnchor()) > 0)) {
2167 // Support "?#tree_name" and "?query#tree_name"
2168 // "#tree_name" (no '?' is for tar archives)
2169 if (!query.IsNull() || strstr(name, "?#")) {
2170 treename = url.GetAnchor();
2171 } else {
2172 // The anchor is part of the file name
2173 fn = url.GetFileAndOptions();
2174 }
2175 }
2176 // Suffix
2177 suffix = url.GetFileAndOptions();
2178 // Get options from suffix by removing the file name
2179 suffix.Replace(suffix.Index(fn), fn.Length(), "");
2180 // Remove the options suffix from the original file name
2181 filename.Replace(filename.Index(suffix), suffix.Length(), "");
2182
2183 // Special case: [...]file.root/treename
2184 static const char *dotr = ".root";
2185 static Ssiz_t dotrl = strlen(dotr);
2186 // Find the last one
2187 Ssiz_t js = filename.Index(dotr);
2188 while (js != kNPOS) {
2189 pIdx = js;
2190 js = filename.Index(dotr, js + 1);
2191 }
2192 if (pIdx != kNPOS) {
2193 static const char *slash = "/";
2194 static Ssiz_t slashl = strlen(slash);
2195 // Find the last one
2196 Ssiz_t ppIdx = filename.Index(slash, pIdx + dotrl);
2197 if (ppIdx != kNPOS) {
2198 // Good treename with the old recipe
2199 treename = filename(ppIdx + slashl, filename.Length());
2200 filename.Remove(ppIdx + slashl - 1);
2201 suffix.Insert(0, TString::Format("/%s", treename.Data()));
2202 }
2203 }
2204}
2205
2206////////////////////////////////////////////////////////////////////////////////
2207/// Print the header information of each tree in the chain.
2208/// See TTree::Print for a list of options.
2209
2210void TChain::Print(Option_t *option) const
2211{
2212 TIter next(fFiles);
2213 TChainElement *element;
2214 while ((element = (TChainElement*)next())) {
2215 Printf("******************************************************************************");
2216 Printf("*Chain :%-10s: %-54s *", GetName(), element->GetTitle());
2217 Printf("******************************************************************************");
2218 TFile *file = TFile::Open(element->GetTitle());
2219 if (file && !file->IsZombie()) {
2220 TTree *tree = (TTree*)file->Get(element->GetName());
2221 if (tree) tree->Print(option);
2222 }
2223 delete file;
2224 }
2225}
2226
2227////////////////////////////////////////////////////////////////////////////////
2228/// Process all entries in this chain, calling functions in filename.
2229/// The return value is -1 in case of error and TSelector::GetStatus() in
2230/// in case of success.
2231/// See TTree::Process.
2232
2233Long64_t TChain::Process(const char *filename, Option_t *option, Long64_t nentries, Long64_t firstentry)
2234{
2235 if (fProofChain) {
2236 // Make sure the element list is up to date
2237 if (!TestBit(kProofUptodate))
2241 return fProofChain->Process(filename, option, nentries, firstentry);
2242 }
2243
2244 if (LoadTree(firstentry) < 0) {
2245 return 0;
2246 }
2247 return TTree::Process(filename, option, nentries, firstentry);
2248}
2249
2250////////////////////////////////////////////////////////////////////////////////
2251/// Process this chain executing the code in selector.
2252/// The return value is -1 in case of error and TSelector::GetStatus() in
2253/// in case of success.
2254
2256{
2257 if (fProofChain) {
2258 // Make sure the element list is up to date
2259 if (!TestBit(kProofUptodate))
2263 return fProofChain->Process(selector, option, nentries, firstentry);
2264 }
2265
2266 return TTree::Process(selector, option, nentries, firstentry);
2267}
2268
2269////////////////////////////////////////////////////////////////////////////////
2270/// Make sure that obj (which is being deleted or will soon be) is no
2271/// longer referenced by this TTree.
2272
2274{
2275 if (fFile == obj) {
2276 fFile = 0;
2277 fDirectory = 0;
2278 fTree = 0;
2279 }
2280 if (fDirectory == obj) {
2281 fDirectory = 0;
2282 fTree = 0;
2283 }
2284 if (fTree == obj) {
2285 fTree = 0;
2286 }
2287}
2288
2289////////////////////////////////////////////////////////////////////////////////
2290/// Remove a friend from the list of friends.
2291
2293{
2294 // We already have been visited while recursively looking
2295 // through the friends tree, let return
2296
2297 if (!fFriends) {
2298 return;
2299 }
2300
2301 TTree::RemoveFriend(oldFriend);
2302
2303 if (fProofChain)
2304 // This updates the proxy chain when we will really use PROOF
2306
2307 // We need to invalidate the loading of the current tree because its list
2308 // of real friends is now obsolete. It is repairable only from LoadTree.
2310}
2311
2312////////////////////////////////////////////////////////////////////////////////
2313/// Resets the state of this chain.
2314
2316{
2317 delete fFile;
2318 fFile = 0;
2319 fNtrees = 0;
2320 fTreeNumber = -1;
2321 fTree = 0;
2322 fFile = 0;
2323 fFiles->Delete();
2324 fStatus->Delete();
2325 fTreeOffset[0] = 0;
2326 TChainElement* element = new TChainElement("*", "");
2327 fStatus->Add(element);
2328 fDirectory = 0;
2329
2330 TTree::Reset();
2331}
2332
2333////////////////////////////////////////////////////////////////////////////////
2334/// Resets the state of this chain after a merge (keep the customization but
2335/// forget the data).
2336
2338{
2339 fNtrees = 0;
2340 fTreeNumber = -1;
2341 fTree = 0;
2342 fFile = 0;
2343 fFiles->Delete();
2344 fTreeOffset[0] = 0;
2345
2347}
2348
2349////////////////////////////////////////////////////////////////////////////////
2350/// Save TChain as a C++ statements on output stream out.
2351/// With the option "friend" save the description of all the
2352/// TChain's friend trees or chains as well.
2353
2354void TChain::SavePrimitive(std::ostream &out, Option_t *option)
2355{
2356 static Int_t chCounter = 0;
2357
2358 TString chName = gInterpreter->MapCppName(GetName());
2359 if (chName.IsNull())
2360 chName = "_chain";
2361 ++chCounter;
2362 chName += chCounter;
2363
2364 TString opt = option;
2365 opt.ToLower();
2366
2367 out << " TChain *" << chName.Data() << " = new TChain(\"" << GetName() << "\");" << std::endl;
2368
2369 if (opt.Contains("friend")) {
2370 opt.ReplaceAll("friend", "");
2371 for (TObject *frel : *fFriends) {
2372 TTree *frtree = ((TFriendElement *)frel)->GetTree();
2373 if (dynamic_cast<TChain *>(frtree)) {
2374 if (strcmp(frtree->GetName(), GetName()) != 0)
2375 --chCounter; // make friends get the same chain counter
2376 frtree->SavePrimitive(out, opt.Data());
2377 out << " " << chName.Data() << "->AddFriend(\"" << frtree->GetName() << "\");" << std::endl;
2378 } else { // ordinary friend TTree
2379 TDirectory *file = frtree->GetDirectory();
2380 if (file && dynamic_cast<TFile *>(file))
2381 out << " " << chName.Data() << "->AddFriend(\"" << frtree->GetName() << "\", \"" << file->GetName()
2382 << "\");" << std::endl;
2383 }
2384 }
2385 }
2386 out << std::endl;
2387
2388 for (TObject *el : *fFiles) {
2389 TChainElement *chel = (TChainElement *)el;
2390 // Save tree file if it is really loaded to the chain
2391 if (chel->GetLoadResult() == 0 && chel->GetEntries() != 0) {
2392 if (chel->GetEntries() == TTree::kMaxEntries) // tree number of entries is not yet known
2393 out << " " << chName.Data() << "->AddFile(\"" << chel->GetTitle() << "\");" << std::endl;
2394 else
2395 out << " " << chName.Data() << "->AddFile(\"" << chel->GetTitle() << "\"," << chel->GetEntries() << ");"
2396 << std::endl;
2397 }
2398 }
2399 out << std::endl;
2400
2401 if (GetMarkerColor() != 1) {
2402 if (GetMarkerColor() > 228) {
2404 out << " " << chName.Data() << "->SetMarkerColor(ci);" << std::endl;
2405 } else
2406 out << " " << chName.Data() << "->SetMarkerColor(" << GetMarkerColor() << ");" << std::endl;
2407 }
2408 if (GetMarkerStyle() != 1) {
2409 out << " " << chName.Data() << "->SetMarkerStyle(" << GetMarkerStyle() << ");" << std::endl;
2410 }
2411 if (GetMarkerSize() != 1) {
2412 out << " " << chName.Data() << "->SetMarkerSize(" << GetMarkerSize() << ");" << std::endl;
2413 }
2414}
2415
2416////////////////////////////////////////////////////////////////////////////////
2417/// Loop on tree and print entries passing selection.
2418/// - If varexp is 0 (or "") then print only first 8 columns.
2419/// - If varexp = "*" print all columns.
2420/// - Otherwise a columns selection can be made using "var1:var2:var3".
2421/// See TTreePlayer::Scan for more information.
2422
2423Long64_t TChain::Scan(const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
2424{
2425 if (LoadTree(firstentry) < 0) {
2426 return 0;
2427 }
2428 return TTree::Scan(varexp, selection, option, nentries, firstentry);
2429}
2430
2431////////////////////////////////////////////////////////////////////////////////
2432/// Set the global branch kAutoDelete bit.
2433///
2434/// When LoadTree loads a new Tree, the branches for which
2435/// the address is set will have the option AutoDelete set
2436/// For more details on AutoDelete, see TBranch::SetAutoDelete.
2437
2439{
2440 if (autodelete) {
2441 SetBit(kAutoDelete, 1);
2442 } else {
2443 SetBit(kAutoDelete, 0);
2444 }
2445}
2446
2448{
2449 // Set the cache size of the underlying TTree,
2450 // See TTree::SetCacheSize.
2451 // Returns 0 cache state ok (exists or not, as appropriate)
2452 // -1 on error
2453
2454 Int_t res = 0;
2455
2456 // remember user has requested this cache setting
2458
2459 if (fTree) {
2460 res = fTree->SetCacheSize(cacheSize);
2461 } else {
2462 // If we don't have a TTree yet only record the cache size wanted
2463 res = 0;
2464 }
2465 fCacheSize = cacheSize; // Record requested size.
2466 return res;
2467}
2468
2469////////////////////////////////////////////////////////////////////////////////
2470/// Reset the addresses of the branch.
2471
2473{
2474 TChainElement* element = (TChainElement*) fStatus->FindObject(branch->GetName());
2475 if (element) {
2476 element->SetBaddress(0);
2477 }
2478 if (fTree) {
2479 fTree->ResetBranchAddress(branch);
2480 }
2481}
2482
2483////////////////////////////////////////////////////////////////////////////////
2484/// Reset the addresses of the branches.
2485
2487{
2488 TIter next(fStatus);
2489 TChainElement* element = 0;
2490 while ((element = (TChainElement*) next())) {
2491 element->SetBaddress(0);
2492 }
2493 if (fTree) {
2495 }
2496}
2497
2498////////////////////////////////////////////////////////////////////////////////
2499/// Set branch address.
2500///
2501/// \param[in] bname is the name of a branch.
2502/// \param[in] add is the address of the branch.
2503/// \param[in] ptr
2504///
2505/// Note: See the comments in TBranchElement::SetAddress() for a more
2506/// detailed discussion of the meaning of the add parameter.
2507///
2508/// IMPORTANT REMARK:
2509///
2510/// In case TChain::SetBranchStatus is called, it must be called
2511/// BEFORE calling this function.
2512///
2513/// See TTree::CheckBranchAddressType for the semantic of the return value.
2514
2515Int_t TChain::SetBranchAddress(const char *bname, void* add, TBranch** ptr)
2516{
2517 Int_t res = kNoCheck;
2518
2519 // Check if bname is already in the status list.
2520 // If not, create a TChainElement object and set its address.
2521 TChainElement* element = (TChainElement*) fStatus->FindObject(bname);
2522 if (!element) {
2523 element = new TChainElement(bname, "");
2524 fStatus->Add(element);
2525 }
2526 element->SetBaddress(add);
2527 element->SetBranchPtr(ptr);
2528 // Also set address in current tree.
2529 // FIXME: What about the chain clones?
2530 if (fTreeNumber >= 0) {
2531 TBranch* branch = fTree->GetBranch(bname);
2532 if (ptr) {
2533 *ptr = branch;
2534 }
2535 if (branch) {
2537 if ((res & kNeedEnableDecomposedObj) && !branch->GetMakeClass()) {
2538 branch->SetMakeClass(kTRUE);
2539 }
2540 element->SetDecomposedObj(branch->GetMakeClass());
2541 element->SetCheckedType(kTRUE);
2542 if (fClones) {
2543 void* oldAdd = branch->GetAddress();
2544 for (TObjLink* lnk = fClones->FirstLink(); lnk; lnk = lnk->Next()) {
2545 TTree* clone = (TTree*) lnk->GetObject();
2546 TBranch* cloneBr = clone->GetBranch(bname);
2547 if (cloneBr && (cloneBr->GetAddress() == oldAdd)) {
2548 // the clone's branch is still pointing to us
2549 cloneBr->SetAddress(add);
2550 if ((res & kNeedEnableDecomposedObj) && !cloneBr->GetMakeClass()) {
2551 cloneBr->SetMakeClass(kTRUE);
2552 }
2553 }
2554 }
2555 }
2556
2557 branch->SetAddress(add);
2558 } else {
2559 Error("SetBranchAddress", "unknown branch -> %s", bname);
2560 return kMissingBranch;
2561 }
2562 } else {
2563 if (ptr) {
2564 *ptr = 0;
2565 }
2566 }
2567 return res;
2568}
2569
2570////////////////////////////////////////////////////////////////////////////////
2571/// Check if bname is already in the status list, and if not, create a TChainElement object and set its address.
2572/// See TTree::CheckBranchAddressType for the semantic of the return value.
2573///
2574/// Note: See the comments in TBranchElement::SetAddress() for a more
2575/// detailed discussion of the meaning of the add parameter.
2576
2577Int_t TChain::SetBranchAddress(const char* bname, void* add, TClass* realClass, EDataType datatype, Bool_t isptr)
2578{
2579 return SetBranchAddress(bname, add, 0, realClass, datatype, isptr);
2580}
2581
2582////////////////////////////////////////////////////////////////////////////////
2583/// Check if bname is already in the status list, and if not, create a TChainElement object and set its address.
2584/// See TTree::CheckBranchAddressType for the semantic of the return value.
2585///
2586/// Note: See the comments in TBranchElement::SetAddress() for a more
2587/// detailed discussion of the meaning of the add parameter.
2588
2589Int_t TChain::SetBranchAddress(const char* bname, void* add, TBranch** ptr, TClass* realClass, EDataType datatype, Bool_t isptr)
2590{
2591 TChainElement* element = (TChainElement*) fStatus->FindObject(bname);
2592 if (!element) {
2593 element = new TChainElement(bname, "");
2594 fStatus->Add(element);
2595 }
2596 if (realClass) {
2597 element->SetBaddressClassName(realClass->GetName());
2598 }
2599 element->SetBaddressType((UInt_t) datatype);
2600 element->SetBaddressIsPtr(isptr);
2601 element->SetBranchPtr(ptr);
2602 return SetBranchAddress(bname, add, ptr);
2603}
2604
2605////////////////////////////////////////////////////////////////////////////////
2606/// Set branch status to Process or DoNotProcess
2607///
2608/// \param[in] bname is the name of a branch. if bname="*", apply to all branches.
2609/// \param[in] status = 1 branch will be processed,
2610/// = 0 branch will not be processed
2611/// \param[out] found
2612///
2613/// See IMPORTANT REMARKS in TTree::SetBranchStatus and TChain::SetBranchAddress
2614///
2615/// If found is not 0, the number of branch(es) found matching the regular
2616/// expression is returned in *found AND the error message 'unknown branch'
2617/// is suppressed.
2618
2619void TChain::SetBranchStatus(const char* bname, Bool_t status, UInt_t* found)
2620{
2621 // FIXME: We never explicitly set found to zero!
2622
2623 // Check if bname is already in the status list,
2624 // if not create a TChainElement object and set its status.
2625 TChainElement* element = (TChainElement*) fStatus->FindObject(bname);
2626 if (element) {
2627 fStatus->Remove(element);
2628 } else {
2629 element = new TChainElement(bname, "");
2630 }
2631 fStatus->Add(element);
2632 element->SetStatus(status);
2633 // Also set status in current tree.
2634 if (fTreeNumber >= 0) {
2635 fTree->SetBranchStatus(bname, status, found);
2636 } else if (found) {
2637 *found = 1;
2638 }
2639}
2640
2641////////////////////////////////////////////////////////////////////////////////
2642/// Remove reference to this chain from current directory and add
2643/// reference to new directory dir. dir can be 0 in which case the chain
2644/// does not belong to any directory.
2645
2647{
2648 if (fDirectory == dir) return;
2649 if (fDirectory) fDirectory->Remove(this);
2650 fDirectory = dir;
2651 if (fDirectory) {
2652 fDirectory->Append(this);
2654 } else {
2655 fFile = 0;
2656 }
2657}
2658
2659////////////////////////////////////////////////////////////////////////////////
2660/// \brief Set the input entry list (processing the entries of the chain will
2661/// then be limited to the entries in the list).
2662///
2663/// \param[in] elist The entry list to be assigned to this chain.
2664/// \param[in] opt An option string. Possible values are:
2665/// - "" (default): both the file names of the chain elements and the file
2666/// names of the TEntryList sublists are expanded to full path name.
2667/// - "ne": the file names are taken as they are and not expanded
2668/// - "sync": the TChain will go through the TEntryList in lockstep with the
2669/// trees in the chain rather than performing a lookup based on
2670/// treename and filename. This is mostly useful when the TEntryList
2671/// has multiple sublists for the same tree and filename.
2672/// \throws std::runtime_error If option "sync" was chosen and either:
2673/// - \p elist doesn't have sub entry lists.
2674/// - the number of sub entry lists in \p elist is different than the
2675/// number of trees in the chain.
2676/// - any of the sub entry lists in \p elist doesn't correspond to the
2677/// tree of the chain with the same index (i.e. it doesn't share the
2678/// same tree name and file name).
2679///
2680/// This function finds correspondence between the sub-lists of the TEntryList
2681/// and the trees of the TChain.
2682
2684{
2685 if (fEntryList){
2686 //check, if the chain is the owner of the previous entry list
2687 //(it happens, if the previous entry list was created from a user-defined
2688 //TEventList in SetEventList() function)
2690 TEntryList *tmp = fEntryList;
2691 fEntryList = 0; // Avoid problem with RecursiveRemove.
2692 delete tmp;
2693 } else {
2694 fEntryList = 0;
2695 }
2696 }
2697 if (!elist){
2698 fEntryList = 0;
2699 fEventList = 0;
2700 return;
2701 }
2702 if (!elist->TestBit(kCanDelete)){
2703 //this is a direct call to SetEntryList, not via SetEventList
2704 fEventList = 0;
2705 }
2706 if (elist->GetN() == 0){
2707 fEntryList = elist;
2708 return;
2709 }
2710 if (fProofChain){
2711 //for processing on proof, event list and entry list can't be
2712 //set at the same time.
2713 fEventList = 0;
2714 fEntryList = elist;
2715 return;
2716 }
2717
2718 Int_t ne = fFiles->GetEntries();
2719 Int_t listfound=0;
2720 TString treename, filename;
2721
2722 TEntryList *templist = 0;
2723
2724 const auto *subentrylists = elist->GetLists();
2725 if(strcmp(opt, "sync") == 0){
2726 if(!subentrylists){
2727 std::string msg{"In 'TChain::SetEntryList': "};
2728 msg += "the input TEntryList doesn't have sub entry lists. Please make sure too add them through ";
2729 msg += "TEntryList::AddSubList";
2730 throw std::runtime_error(msg);
2731 }
2732 const auto nsubelists = subentrylists->GetEntries();
2733 if(nsubelists != ne){
2734 std::string msg{"In 'TChain::SetEntryList': "};
2735 msg += "the number of sub entry lists in the input TEntryList (";
2736 msg += std::to_string(nsubelists);
2737 msg += ") is not equal to the number of files in the chain (";
2738 msg += std::to_string(ne);
2739 msg += ")";
2740 throw std::runtime_error(msg);
2741 }
2742 }
2743
2744 for (Int_t ie = 0; ie<ne; ie++){
2745 auto chainElement = (TChainElement*)fFiles->UncheckedAt(ie);
2746 treename = chainElement->GetName();
2747 filename = chainElement->GetTitle();
2748
2749 if(strcmp(opt, "sync") == 0){
2750 // If the user asked for "sync" option, there should be a 1:1 mapping
2751 // between trees in the chain and sub entry lists in the argument elist
2752 // We have already checked that the input TEntryList has a number of
2753 // sub entry lists equal to the number of files in the chain.
2754 templist = static_cast<TEntryList*>(subentrylists->At(ie));
2755 auto elisttreename = templist->GetTreeName();
2756 auto elistfilename = templist->GetFileName();
2757
2758 if (strcmp(treename, elisttreename) != 0 || strcmp(filename, elistfilename) != 0){
2759 std::string msg{"In 'TChain::SetEntryList': "};
2760 msg += "the sub entry list at index ";
2761 msg += std::to_string(ie);
2762 msg += " doesn't correspond to treename '";
2763 msg += treename;
2764 msg += "' and filename '";
2765 msg += filename;
2766 msg += "': it has treename '";
2767 msg += elisttreename;
2768 msg += "' and filename '";
2769 msg += elistfilename;
2770 msg += "'";
2771 throw std::runtime_error(msg);
2772 }
2773
2774 }else{
2775 templist = elist->GetEntryList(treename, filename, opt);
2776 }
2777
2778 if (templist) {
2779 listfound++;
2780 templist->SetTreeNumber(ie);
2781 }
2782 }
2783
2784 if (listfound == 0){
2785 Error("SetEntryList", "No list found for the trees in this chain");
2786 fEntryList = 0;
2787 return;
2788 }
2789 fEntryList = elist;
2790 TList *elists = elist->GetLists();
2791 Bool_t shift = kFALSE;
2792 TIter next(elists);
2793
2794 //check, if there are sub-lists in the entry list, that don't
2795 //correspond to any trees in the chain
2796 while((templist = (TEntryList*)next())){
2797 if (templist->GetTreeNumber() < 0){
2798 shift = kTRUE;
2799 break;
2800 }
2801 }
2802 fEntryList->SetShift(shift);
2803
2804}
2805
2806////////////////////////////////////////////////////////////////////////////////
2807/// Set the input entry list (processing the entries of the chain will then be
2808/// limited to the entries in the list). This function creates a special kind
2809/// of entry list (TEntryListFromFile object) that loads lists, corresponding
2810/// to the chain elements, one by one, so that only one list is in memory at a time.
2811///
2812/// If there is an error opening one of the files, this file is skipped and the
2813/// next file is loaded
2814///
2815/// File naming convention:
2816///
2817/// - by default, filename_elist.root is used, where filename is the
2818/// name of the chain element
2819/// - xxx$xxx.root - $ sign is replaced by the name of the chain element
2820///
2821/// If the list name is not specified (by passing filename_elist.root/listname to
2822/// the TChain::SetEntryList() function, the first object of class TEntryList
2823/// in the file is taken.
2824///
2825/// It is assumed, that there are as many list files, as there are elements in
2826/// the chain and they are in the same order
2827
2828void TChain::SetEntryListFile(const char *filename, Option_t * /*opt*/)
2829{
2830
2831 if (fEntryList){
2832 //check, if the chain is the owner of the previous entry list
2833 //(it happens, if the previous entry list was created from a user-defined
2834 //TEventList in SetEventList() function)
2836 TEntryList *tmp = fEntryList;
2837 fEntryList = 0; // Avoid problem with RecursiveRemove.
2838 delete tmp;
2839 } else {
2840 fEntryList = 0;
2841 }
2842 }
2843
2844 fEventList = 0;
2845
2846 TString basename(filename);
2847
2848 Int_t dotslashpos = basename.Index(".root/");
2849 TString behind_dot_root = "";
2850 if (dotslashpos>=0) {
2851 // Copy the list name specification
2852 behind_dot_root = basename(dotslashpos+6,basename.Length()-dotslashpos+6);
2853 // and remove it from basename
2854 basename.Remove(dotslashpos+5);
2855 }
2856 fEntryList = new TEntryListFromFile(basename.Data(), behind_dot_root.Data(), fNtrees);
2859 ((TEntryListFromFile*)fEntryList)->SetFileNames(fFiles);
2860}
2861
2862////////////////////////////////////////////////////////////////////////////////
2863/// This function transfroms the given TEventList into a TEntryList
2864///
2865/// NOTE, that this function loads all tree headers, because the entry numbers
2866/// in the TEventList are global and have to be recomputed, taking into account
2867/// the number of entries in each tree.
2868///
2869/// The new TEntryList is owned by the TChain and gets deleted when the chain
2870/// is deleted. This TEntryList is returned by GetEntryList() function, and after
2871/// GetEntryList() function is called, the TEntryList is not owned by the chain
2872/// any more and will not be deleted with it.
2873
2875{
2876 fEventList = evlist;
2877 if (fEntryList) {
2879 TEntryList *tmp = fEntryList;
2880 fEntryList = 0; // Avoid problem with RecursiveRemove.
2881 delete tmp;
2882 } else {
2883 fEntryList = 0;
2884 }
2885 }
2886
2887 if (!evlist) {
2888 fEntryList = 0;
2889 fEventList = 0;
2890 return;
2891 }
2892
2893 if(fProofChain) {
2894 //on proof, fEventList and fEntryList shouldn't be set at the same time
2895 if (fEntryList){
2896 //check, if the chain is the owner of the previous entry list
2897 //(it happens, if the previous entry list was created from a user-defined
2898 //TEventList in SetEventList() function)
2900 TEntryList *tmp = fEntryList;
2901 fEntryList = 0; // Avoid problem with RecursiveRemove.
2902 delete tmp;
2903 } else {
2904 fEntryList = 0;
2905 }
2906 }
2907 return;
2908 }
2909
2910 char enlistname[100];
2911 snprintf(enlistname,100, "%s_%s", evlist->GetName(), "entrylist");
2912 TEntryList *enlist = new TEntryList(enlistname, evlist->GetTitle());
2913 enlist->SetDirectory(0);
2914
2915 Int_t nsel = evlist->GetN();
2916 Long64_t globalentry, localentry;
2917 const char *treename;
2918 const char *filename;
2920 //Load all the tree headers if the tree offsets are not known
2921 //It is assumed here, that loading the last tree will load all
2922 //previous ones
2923 printf("loading trees\n");
2924 (const_cast<TChain*>(this))->LoadTree(evlist->GetEntry(evlist->GetN()-1));
2925 }
2926 for (Int_t i=0; i<nsel; i++){
2927 globalentry = evlist->GetEntry(i);
2928 //add some protection from globalentry<0 here
2929 Int_t treenum = 0;
2930 while (globalentry>=fTreeOffset[treenum])
2931 treenum++;
2932 treenum--;
2933 localentry = globalentry - fTreeOffset[treenum];
2934 // printf("globalentry=%lld, treeoffset=%lld, localentry=%lld\n", globalentry, fTreeOffset[treenum], localentry);
2935 treename = ((TNamed*)fFiles->At(treenum))->GetName();
2936 filename = ((TNamed*)fFiles->At(treenum))->GetTitle();
2937 //printf("entering for tree %s %s\n", treename, filename);
2938 enlist->SetTree(treename, filename);
2939 enlist->Enter(localentry);
2940 }
2941 enlist->SetBit(kCanDelete, kTRUE);
2942 enlist->SetReapplyCut(evlist->GetReapplyCut());
2943 SetEntryList(enlist);
2944}
2945
2946////////////////////////////////////////////////////////////////////////////////
2947/// Change the name of this TChain.
2948
2949void TChain::SetName(const char* name)
2950{
2951 if (fGlobalRegistration) {
2952 // Should this be extended to include the call to TTree::SetName?
2953 R__WRITE_LOCKGUARD(ROOT::gCoreMutex); // Take the lock once rather than 3 times.
2954 gROOT->GetListOfCleanups()->Remove(this);
2955 gROOT->GetListOfSpecials()->Remove(this);
2956 gROOT->GetListOfDataSets()->Remove(this);
2957 }
2959 if (fGlobalRegistration) {
2960 // Should this be extended to include the call to TTree::SetName?
2961 R__WRITE_LOCKGUARD(ROOT::gCoreMutex); // Take the lock once rather than 3 times.
2962 gROOT->GetListOfCleanups()->Add(this);
2963 gROOT->GetListOfSpecials()->Add(this);
2964 gROOT->GetListOfDataSets()->Add(this);
2965 }
2966}
2967
2968////////////////////////////////////////////////////////////////////////////////
2969/// Set number of entries per packet for parallel root.
2970
2972{
2973 fPacketSize = size;
2974 TIter next(fFiles);
2975 TChainElement *element;
2976 while ((element = (TChainElement*)next())) {
2977 element->SetPacketSize(size);
2978 }
2979}
2980
2981////////////////////////////////////////////////////////////////////////////////
2982/// Enable/Disable PROOF processing on the current default Proof (gProof).
2983///
2984/// "Draw" and "Processed" commands will be handled by PROOF.
2985/// The refresh and gettreeheader are meaningful only if on == kTRUE.
2986/// If refresh is kTRUE the underlying fProofChain (chain proxy) is always
2987/// rebuilt (even if already existing).
2988/// If gettreeheader is kTRUE the header of the tree will be read from the
2989/// PROOF cluster: this is only needed for browsing and should be used with
2990/// care because it may take a long time to execute.
2991
2992void TChain::SetProof(Bool_t on, Bool_t refresh, Bool_t gettreeheader)
2993{
2994 if (!on) {
2995 // Disable
2997 // Reset related bit
2999 } else {
3000 if (fProofChain && !refresh &&
3001 (!gettreeheader || (gettreeheader && fProofChain->GetTree()))) {
3002 return;
3003 }
3006
3007 // Make instance of TChainProof via the plugin manager
3009 if ((h = gROOT->GetPluginManager()->FindHandler("TChain", "proof"))) {
3010 if (h->LoadPlugin() == -1)
3011 return;
3012 if (!(fProofChain = reinterpret_cast<TChain *>(h->ExecPlugin(2, this, gettreeheader))))
3013 Error("SetProof", "creation of TProofChain failed");
3014 // Set related bits
3016 }
3017 }
3018}
3019
3020////////////////////////////////////////////////////////////////////////////////
3021/// Set chain weight.
3022///
3023/// The weight is used by TTree::Draw to automatically weight each
3024/// selected entry in the resulting histogram.
3025/// For example the equivalent of
3026/// ~~~ {.cpp}
3027/// chain.Draw("x","w")
3028/// ~~~
3029/// is
3030/// ~~~ {.cpp}
3031/// chain.SetWeight(w,"global");
3032/// chain.Draw("x");
3033/// ~~~
3034/// By default the weight used will be the weight
3035/// of each Tree in the TChain. However, one can force the individual
3036/// weights to be ignored by specifying the option "global".
3037/// In this case, the TChain global weight will be used for all Trees.
3038
3040{
3041 fWeight = w;
3042 TString opt = option;
3043 opt.ToLower();
3045 if (opt.Contains("global")) {
3047 }
3048}
3049
3050////////////////////////////////////////////////////////////////////////////////
3051/// Stream a class object.
3052
3053void TChain::Streamer(TBuffer& b)
3054{
3055 if (b.IsReading()) {
3056 // Remove using the 'old' name.
3057 {
3059 gROOT->GetListOfCleanups()->Remove(this);
3060 }
3061
3062 UInt_t R__s, R__c;
3063 Version_t R__v = b.ReadVersion(&R__s, &R__c);
3064 if (R__v > 2) {
3065 b.ReadClassBuffer(TChain::Class(), this, R__v, R__s, R__c);
3066 } else {
3067 //====process old versions before automatic schema evolution
3068 TTree::Streamer(b);
3069 b >> fTreeOffsetLen;
3070 b >> fNtrees;
3071 fFiles->Streamer(b);
3072 if (R__v > 1) {
3073 fStatus->Streamer(b);
3075 b.ReadFastArray(fTreeOffset,fTreeOffsetLen);
3076 }
3077 b.CheckByteCount(R__s, R__c, TChain::IsA());
3078 //====end of old versions
3079 }
3080 // Re-add using the new name.
3081 {
3083 gROOT->GetListOfCleanups()->Add(this);
3084 }
3085
3086 } else {
3087 b.WriteClassBuffer(TChain::Class(),this);
3088 }
3089}
3090
3091////////////////////////////////////////////////////////////////////////////////
3092/// Dummy function kept for back compatibility.
3093/// The cache is now activated automatically when processing TTrees/TChain.
3094
3095void TChain::UseCache(Int_t /* maxCacheSize */, Int_t /* pageSize */)
3096{
3097}
#define SafeDelete(p)
Definition RConfig.hxx:537
#define b(i)
Definition RSha256.hxx:100
#define h(i)
Definition RSha256.hxx:106
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
const Ssiz_t kNPOS
Definition RtypesCore.h:124
short Version_t
Definition RtypesCore.h:65
unsigned int UInt_t
Definition RtypesCore.h:46
const Bool_t kFALSE
Definition RtypesCore.h:101
double Double_t
Definition RtypesCore.h:59
long long Long64_t
Definition RtypesCore.h:80
const Bool_t kTRUE
Definition RtypesCore.h:100
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:364
EDataType
Definition TDataType.h:28
#define R__ASSERT(e)
Definition TError.h:118
char name[80]
Definition TGX11.cxx:110
int nentries
#define gInterpreter
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#define gROOT
Definition TROOT.h:404
void Printf(const char *fmt,...)
R__EXTERN TSystem * gSystem
Definition TSystem.h:559
#define R__LOCKGUARD(mutex)
#define R__WRITE_LOCKGUARD(mutex)
#define snprintf
Definition civetweb.c:1540
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition TAttMarker.h:32
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition TAttMarker.h:31
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition TAttMarker.h:33
A TTree is a list of TBranches.
Definition TBranch.h:89
virtual void SetAutoDelete(Bool_t autodel=kTRUE)
Set the automatic delete bit.
Definition TBranch.cxx:2654
virtual char * GetAddress() const
Definition TBranch.h:208
void SetCompressionSettings(Int_t settings=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault)
Set compression settings.
Definition TBranch.cxx:2743
virtual void SetAddress(void *add)
Set address of this branch.
Definition TBranch.cxx:2620
virtual Bool_t GetMakeClass() const
Return whether this branch is in a mode where the object are decomposed or not (Also known as MakeCla...
Definition TBranch.cxx:2055
virtual Bool_t SetMakeClass(Bool_t decomposeObj=kTRUE)
Set the branch in a mode where the object are decomposed (Also known as MakeClass mode).
Definition TBranch.cxx:2865
virtual void SetBasketSize(Int_t buffsize)
Set the basket size The function makes sure that the basket size is greater than fEntryOffsetlen.
Definition TBranch.cxx:2667
Using a TBrowser one can browse all ROOT objects.
Definition TBrowser.h:37
Buffer base class used for serializing objects.
Definition TBuffer.h:43
A TChainElement describes a component of a TChain.
void SetLoadResult(Int_t result)
void SetCheckedType(Bool_t m)
virtual void SetBaddressClassName(const char *clname)
virtual Long64_t GetEntries() const
void SetDecomposedObj(Bool_t m)
virtual void SetLookedUp(Bool_t y=kTRUE)
Set/Reset the looked-up bit.
virtual void SetPacketSize(Int_t size=100)
Set number of entries per packet for parallel root.
virtual void SetStatus(Int_t status)
virtual UInt_t GetBaddressType() const
virtual void SetNumberEntries(Long64_t n)
virtual TBranch ** GetBranchPtr() const
virtual Int_t GetPacketSize() const
virtual void SetBaddress(void *add)
virtual void CreatePackets()
Initialize the packet descriptor string.
virtual void SetBranchPtr(TBranch **ptr)
Int_t GetLoadResult() const
virtual Int_t GetStatus() const
Bool_t GetCheckedType() const
virtual Bool_t HasBeenLookedUp()
virtual Bool_t GetBaddressIsPtr() const
virtual void * GetBaddress() const
virtual void SetBaddressType(UInt_t type)
virtual const char * GetBaddressClassName() const
virtual void SetBaddressIsPtr(Bool_t isptr)
A chain is a collection of files containing TTree objects.
Definition TChain.h:33
virtual void Reset(Option_t *option="")
Resets the state of this chain.
Definition TChain.cxx:2315
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch name in the current tree.
Definition TChain.cxx:899
virtual ~TChain()
Destructor.
Definition TChain.cxx:172
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save TChain as a C++ statements on output stream out.
Definition TChain.cxx:2354
virtual Long64_t Draw(const char *varexp, const TCut &selection, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Draw expression varexp for selected entries.
Definition TChain.cxx:799
virtual void ResetAfterMerge(TFileMergeInfo *)
Resets the state of this chain after a merge (keep the customization but forget the data).
Definition TChain.cxx:2337
virtual Int_t GetEntry(Long64_t entry=0, Int_t getall=0)
Get entry from the file to memory.
Definition TChain.cxx:982
Int_t fNtrees
Number of trees.
Definition TChain.h:37
TObjArray * GetListOfFiles() const
Definition TChain.h:110
virtual void SetAutoDelete(Bool_t autodel=kTRUE)
Set the global branch kAutoDelete bit.
Definition TChain.cxx:2438
virtual void SetWeight(Double_t w=1, Option_t *option="")
Set chain weight.
Definition TChain.cxx:3039
virtual Long64_t LoadTree(Long64_t entry)
Find the tree which contains entry, and set it as the current tree.
Definition TChain.cxx:1302
virtual void SetDirectory(TDirectory *dir)
Remove reference to this chain from current directory and add reference to new directory dir.
Definition TChain.cxx:2646
virtual Long64_t Process(const char *filename, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Process all entries in this chain, calling functions in filename.
Definition TChain.cxx:2233
virtual void Print(Option_t *option="") const
Print the header information of each tree in the chain.
Definition TChain.cxx:2210
virtual Double_t GetMaximum(const char *columname)
Return maximum of column with name columname.
Definition TChain.cxx:1149
virtual void DirectoryAutoAdd(TDirectory *)
Override the TTree::DirectoryAutoAdd behavior: we never auto add.
Definition TChain.cxx:784
virtual TObjArray * GetListOfBranches()
Return a pointer to the list of branches of the current tree.
Definition TChain.cxx:1105
virtual void RemoveFriend(TTree *)
Remove a friend from the list of friends.
Definition TChain.cxx:2292
TChain(const TChain &)
virtual TObjArray * GetListOfLeaves()
Return a pointer to the list of leaves of the current tree.
Definition TChain.cxx:1128
virtual Int_t AddFile(const char *name, Long64_t nentries=TTree::kMaxEntries, const char *tname="")
Add a new file to this chain.
Definition TChain.cxx:474
Long64_t * fTreeOffset
[fTreeOffsetLen] Array of variables
Definition TChain.h:39
virtual Bool_t GetBranchStatus(const char *branchname) const
See TTree::GetReadEntry().
Definition TChain.cxx:920
virtual TTree * GetTree() const
Definition TChain.h:118
virtual TLeaf * FindLeaf(const char *name)
See TTree::GetReadEntry().
Definition TChain.cxx:859
virtual void SetEntryList(TEntryList *elist, Option_t *opt="")
Set the input entry list (processing the entries of the chain will then be limited to the entries in ...
Definition TChain.cxx:2683
virtual TBranch * FindBranch(const char *name)
See TTree::GetReadEntry().
Definition TChain.cxx:838
virtual Bool_t InPlaceClone(TDirectory *newdirectory, const char *options="")
Move content to a new file. (NOT IMPLEMENTED for TChain)
Definition TChain.cxx:1239
virtual void Loop(Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Loop on nentries of this chain starting at firstentry. (NOT IMPLEMENTED)
Definition TChain.cxx:1802
TChain * fProofChain
! chain proxy when going to be processed by PROOF
Definition TChain.h:45
virtual void Browse(TBrowser *)
Browse the contents of the chain.
Definition TChain.cxx:745
virtual Int_t AddFileInfoList(TCollection *list, Long64_t nfiles=TTree::kMaxEntries)
Add all files referenced in the list to the chain.
Definition TChain.cxx:572
virtual Int_t SetCacheSize(Long64_t cacheSize=-1)
Set maximum size of the file cache .
Definition TChain.cxx:2447
virtual Long64_t Scan(const char *varexp="", const char *selection="", Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Loop on tree and print entries passing selection.
Definition TChain.cxx:2423
virtual void SetBranchStatus(const char *bname, Bool_t status=1, UInt_t *found=0)
Set branch status to Process or DoNotProcess.
Definition TChain.cxx:2619
virtual void CreatePackets()
Initialize the packet descriptor string.
Definition TChain.cxx:771
void ParseTreeFilename(const char *name, TString &filename, TString &treename, TString &query, TString &suffix, Bool_t wildcards) const
Get the tree url or filename and other information from the name.
Definition TChain.cxx:2148
virtual TLeaf * GetLeaf(const char *branchname, const char *leafname)
Return a pointer to the leaf name in the current tree.
Definition TChain.cxx:1058
TList * fStatus
-> List of active/inactive branches (TChainElement, owned)
Definition TChain.h:44
virtual Long64_t Merge(const char *name, Option_t *option="")
Merge all the entries in the chain into a new tree in a new file.
Definition TChain.cxx:1879
TTree * fTree
! Pointer to current tree (Note: We do not own this tree.)
Definition TChain.h:41
virtual Long64_t GetEntries() const
Return the total number of entries in the chain.
Definition TChain.cxx:958
virtual Int_t Add(TChain *chain)
Add all files referenced by the passed chain to this chain.
Definition TChain.cxx:218
virtual TFriendElement * AddFriend(const char *chainname, const char *dummy="")
Add a TFriendElement to the list of friends of this chain.
Definition TChain.cxx:662
virtual const char * GetAlias(const char *aliasName) const
Returns the expanded value of the alias. Search in the friends if any.
Definition TChain.cxx:880
virtual void ResetBranchAddress(TBranch *)
Reset the addresses of the branch.
Definition TChain.cxx:2472
virtual void ResetBranchAddresses()
Reset the addresses of the branches.
Definition TChain.cxx:2486
virtual Int_t LoadBaskets(Long64_t maxmemory)
Dummy function.
Definition TChain.cxx:1276
virtual void SetProof(Bool_t on=kTRUE, Bool_t refresh=kFALSE, Bool_t gettreeheader=kFALSE)
Enable/Disable PROOF processing on the current default Proof (gProof).
Definition TChain.cxx:2992
bool fGlobalRegistration
! if true, bypass use of global lists
Definition TChain.h:46
virtual void SetEntryListFile(const char *filename="", Option_t *opt="")
Set the input entry list (processing the entries of the chain will then be limited to the entries in ...
Definition TChain.cxx:2828
Int_t fTreeOffsetLen
Current size of fTreeOffset array.
Definition TChain.h:36
virtual void CanDeleteRefs(Bool_t flag=kTRUE)
When closing a file during the chain processing, the file may be closed with option "R" if flag is se...
Definition TChain.cxx:763
virtual Long64_t GetReadEntry() const
See TTree::GetReadEntry().
Definition TChain.cxx:1200
virtual Int_t GetEntryWithIndex(Int_t major, Int_t minor=0)
Return entry corresponding to major and minor number.
Definition TChain.cxx:1034
virtual TClusterIterator GetClusterIterator(Long64_t firstentry)
Return an iterator over the cluster of baskets starting at firstentry.
Definition TChain.cxx:937
virtual Int_t GetNbranches()
Return the number of branches of the current tree.
Definition TChain.cxx:1185
TObjArray * fFiles
-> List of file names containing the trees (TChainElement, owned)
Definition TChain.h:43
virtual void SetEventList(TEventList *evlist)
This function transfroms the given TEventList into a TEntryList.
Definition TChain.cxx:2874
Int_t GetNtrees() const
Definition TChain.h:98
virtual void RecursiveRemove(TObject *obj)
Make sure that obj (which is being deleted or will soon be) is no longer referenced by this TTree.
Definition TChain.cxx:2273
Bool_t fCanDeleteRefs
! If true, TProcessIDs are deleted when closing a file
Definition TChain.h:40
TFile * fFile
! Pointer to current file (We own the file).
Definition TChain.h:42
virtual Double_t GetWeight() const
Return the chain weight.
Definition TChain.cxx:1221
virtual Long64_t GetEntryNumber(Long64_t entry) const
Return entry number corresponding to entry.
Definition TChain.cxx:1001
virtual void UseCache(Int_t maxCacheSize=10, Int_t pageSize=0)
Dummy function kept for back compatibility.
Definition TChain.cxx:3095
virtual void SetName(const char *name)
Change the name of this TChain.
Definition TChain.cxx:2949
void InvalidateCurrentTree()
Set the TTree to be reloaded as soon as possible.
Definition TChain.cxx:1258
virtual void ls(Option_t *option="") const
List the chain.
Definition TChain.cxx:1846
TFile * GetFile() const
Return a pointer to the current file.
Definition TChain.cxx:1045
virtual void SetPacketSize(Int_t size=100)
Set number of entries per packet for parallel root.
Definition TChain.cxx:2971
Int_t fTreeNumber
! Current Tree number in fTreeOffset table
Definition TChain.h:38
void Lookup(Bool_t force=kFALSE)
Check / locate the files in the chain.
Definition TChain.cxx:1732
virtual Double_t GetMinimum(const char *columname)
Return minimum of column with name columname.
Definition TChain.cxx:1166
virtual Long64_t GetChainEntryNumber(Long64_t entry) const
Return absolute entry number in the chain.
Definition TChain.cxx:948
virtual Int_t SetBranchAddress(const char *bname, void *add, TBranch **ptr=0)
Set branch address.
Definition TChain.cxx:2515
@ kProofLite
Definition TChain.h:63
@ kAutoDelete
Definition TChain.h:61
@ kProofUptodate
Definition TChain.h:62
@ kGlobalWeight
Definition TChain.h:60
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:80
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:2966
Collection abstract base class.
Definition TCollection.h:65
static void SaveColor(std::ostream &out, Int_t ci)
Save a color with index > 228 as a C++ statement(s) on output stream out.
Definition TColor.cxx:2174
A specialized string object used for TTree selections.
Definition TCut.h:25
TObject * Get(const char *namecycle) override
Return pointer to object identified by namecycle.
TDirectory::TContext keeps track and restore the current directory.
Definition TDirectory.h:89
Describe directory structure in memory.
Definition TDirectory.h:45
virtual TList * GetList() const
Definition TDirectory.h:222
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
virtual TFile * GetFile() const
Definition TDirectory.h:220
virtual TObject * Remove(TObject *)
Remove an object from the in-memory list.
Manages entry lists from different files, when they are not loaded in memory at the same time.
A List of entry numbers in a TTree or TChain.
Definition TEntryList.h:26
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:80
virtual void SetShift(Bool_t shift)
Definition TEntryList.h:101
virtual TList * GetLists() const
Definition TEntryList.h:75
virtual void SetReapplyCut(Bool_t apply=kFALSE)
Definition TEntryList.h:107
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,...
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 void SetTreeNumber(Int_t index)
Definition TEntryList.h:106
virtual void SetDirectory(TDirectory *dir)
Add reference to directory dir. dir can be 0.
virtual Bool_t Enter(Long64_t entry, TTree *tree=0)
Add entry #entry to the list.
virtual const char * GetTreeName() const
Definition TEntryList.h:78
void GetFileName(const char *filename, TString &fn, Bool_t *=0)
To be able to re-localize the entry-list we identify the file by just the name and the anchor,...
virtual Long64_t GetN() const
Definition TEntryList.h:77
A TEventList object is a list of selected events (entries) in a TTree.
Definition TEventList.h:31
virtual Long64_t GetEntry(Int_t index) const
Return value of entry at index in the list.
virtual Int_t GetN() const
Definition TEventList.h:56
virtual Bool_t GetReapplyCut() const
Definition TEventList.h:57
Class describing a generic file including meta information.
Definition TFileInfo.h:39
TUrl * GetCurrentUrl() const
Return the current url.
virtual Bool_t Matches(const char *s)
Definition TFileStager.h:46
static TFileStager * Open(const char *stager)
Open a stager, after having loaded the relevant plug-in.
virtual Int_t Locate(const char *u, TString &f)
Just check if the file exists locally.
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition TFile.h:54
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:4025
void Close(Option_t *option="") override
Close a file.
Definition TFile.cxx:899
virtual void SetCacheRead(TFileCacheRead *cache, TObject *tree=0, ECacheAction action=kDisconnect)
Set a pointer to the read cache.
Definition TFile.cxx:2303
A TFriendElement TF describes a TTree object TF in a file.
virtual TTree * GetTree()
Return pointer to friend TTree.
void Reset()
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition TLeaf.h:57
A doubly linked list.
Definition TList.h:38
virtual void Add(TObject *obj)
Definition TList.h:81
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition TList.cxx:822
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition TList.cxx:578
virtual TObjLink * FirstLink() const
Definition TList.h:102
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:470
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:164
virtual const char * GetTitle() const
Returns title of object.
Definition TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition TNamed.h:47
An array of TObjects.
Definition TObjArray.h:31
void Add(TObject *obj)
Definition TObjArray.h:68
Int_t GetEntries() const
Return the number of objects in array (i.e.
TObject * UncheckedAt(Int_t i) const
Definition TObjArray.h:84
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
virtual TObject * Remove(TObject *obj)
Remove object from array.
TObject * At(Int_t idx) const
Definition TObjArray.h:164
Collectable string class.
Definition TObjString.h:28
const char * GetName() const
Returns name of object.
Definition TObjString.h:38
Mother of all ROOT objects.
Definition TObject.h:41
virtual Bool_t Notify()
This method must be overridden to handle object notification.
Definition TObject.cxx:578
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:201
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:200
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:949
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition TObject.cxx:736
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition TObject.h:153
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:766
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:515
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:963
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:991
virtual void ls(Option_t *option="") const
The ls function lists the contents of a class on stdout.
Definition TObject.cxx:564
void ResetBit(UInt_t f)
Definition TObject.h:200
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:62
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:72
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition TObject.h:64
static Int_t IncreaseDirLevel()
Increase the indentation level for ls().
Definition TROOT.cxx:2811
static Int_t DecreaseDirLevel()
Decrease the indentation level for ls().
Definition TROOT.cxx:2704
Regular expression class.
Definition TRegexp.h:31
A TSelector object is used by the TTree::Draw, TTree::Scan, TTree::Process to navigate in a TTree and...
Definition TSelector.h:31
Basic string class.
Definition TString.h:136
Ssiz_t Length() const
Definition TString.h:410
void ToLower()
Change string to lower-case.
Definition TString.cxx:1150
TString & Insert(Ssiz_t pos, const char *s)
Definition TString.h:649
void Clear()
Clear string without changing its capacity.
Definition TString.cxx:1201
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition TString.h:682
const char * Data() const
Definition TString.h:369
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:692
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition TString.cxx:916
Bool_t IsNull() const
Definition TString.h:407
TString & Remove(Ssiz_t pos)
Definition TString.h:673
Bool_t MaybeWildcard() const
Returns true if string contains one of the wildcard characters "[]*?".
Definition TString.cxx:949
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:2336
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2314
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:624
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:639
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1274
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:846
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition TSystem.cxx:837
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition TSystem.cxx:1296
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:854
virtual const char * UnixPathName(const char *unixpathname)
Convert from a local pathname to a Unix pathname.
Definition TSystem.cxx:1063
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:935
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:872
A cache to speed-up the reading of ROOT datasets.
Definition TTreeCache.h:32
virtual void UpdateBranches(TTree *tree)
Update pointer to current Tree and recompute pointers to the branches in the cache.
virtual void ResetCache()
This will simply clear the cache.
Helper class to iterate over cluster of baskets.
Definition TTree.h:267
Helper class to prevent infinite recursion in the usage of TTree Friends.
Definition TTree.h:185
A TTree represents a columnar dataset.
Definition TTree.h:79
virtual TFriendElement * AddFriend(const char *treename, const char *filename="")
Add a TFriendElement to the list of friends.
Definition TTree.cxx:1330
virtual TBranch * FindBranch(const char *name)
Return the branch that correspond to the path 'branchname', which can include the name of the tree or...
Definition TTree.cxx:4832
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition TTree.cxx:5279
TList * fFriends
pointer to list of friend elements
Definition TTree.h:127
UInt_t fFriendLockStatus
! Record which method is locking the friend recursion
Definition TTree.h:134
TEventList * fEventList
! Pointer to event selection list (if one)
Definition TTree.h:122
virtual Int_t GetEntry(Long64_t entry, Int_t getall=0)
Read all branches of entry and return total number of bytes read.
Definition TTree.cxx:5622
virtual void SetCircular(Long64_t maxEntries)
Enable/Disable circularity for this tree.
Definition TTree.cxx:8858
virtual TClusterIterator GetClusterIterator(Long64_t firstentry)
Return an iterator over the cluster of baskets starting at firstentry.
Definition TTree.cxx:5451
virtual void ResetBranchAddress(TBranch *)
Tell all of our branches to set their addresses to zero.
Definition TTree.cxx:8044
virtual Int_t CheckBranchAddressType(TBranch *branch, TClass *ptrClass, EDataType datatype, Bool_t ptr)
Check whether or not the address described by the last 3 parameters matches the content of the branch...
Definition TTree.cxx:2864
virtual Long64_t GetEntryNumberWithIndex(Long64_t major, Long64_t minor=0) const
Return entry number corresponding to major and minor number.
Definition TTree.cxx:5894
virtual TObjArray * GetListOfLeaves()
Definition TTree.h:486
TFile * GetCurrentFile() const
Return pointer to the current file.
Definition TTree.cxx:5463
TVirtualTreePlayer * GetPlayer()
Load the TTreePlayer (if not already done).
Definition TTree.cxx:6289
virtual Double_t GetWeight() const
Definition TTree.h:541
virtual Long64_t CopyEntries(TTree *tree, Long64_t nentries=-1, Option_t *option="", Bool_t needCopyAddresses=false)
Copy nentries from given tree to this tree.
Definition TTree.cxx:3528
virtual Double_t GetMaximum(const char *columname)
Return maximum of column with name columname.
Definition TTree.cxx:6219
TVirtualTreePlayer * fPlayer
! Pointer to current Tree player
Definition TTree.h:131
virtual void SetMakeClass(Int_t make)
Set all the branches in this TTree to be in decomposed object mode (also known as MakeClass mode).
Definition TTree.cxx:9143
TDirectory * GetDirectory() const
Definition TTree.h:459
TTreeCache * GetReadCache(TFile *file) const
Find and return the TTreeCache registered with the file and which may contain branches for us.
Definition TTree.cxx:6302
Bool_t fCacheUserSet
! true if the cache setting was explicitly given by user
Definition TTree.h:138
Long64_t fEntries
Number of entries.
Definition TTree.h:84
virtual Bool_t GetBranchStatus(const char *branchname) const
Return status of branch with name branchname.
Definition TTree.cxx:5364
TEntryList * fEntryList
! Pointer to event selection list (if one)
Definition TTree.h:123
virtual TVirtualIndex * GetTreeIndex() const
Definition TTree.h:515
TList * fExternalFriends
! List of TFriendsElement pointing to us and need to be notified of LoadTree. Content not owned.
Definition TTree.h:128
virtual void SetMaxVirtualSize(Long64_t size=0)
Definition TTree.h:622
virtual void SetAutoSave(Long64_t autos=-300000000)
This function may be called at the start of a program to change the default value for fAutoSave (and ...
Definition TTree.cxx:8313
virtual Long64_t Process(const char *filename, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Process this tree executing the TSelector code in the specified filename.
Definition TTree.cxx:7434
virtual void ResetAfterMerge(TFileMergeInfo *)
Resets the state of this TTree after a merge (keep the customization but forget the data).
Definition TTree.cxx:8013
virtual void CopyAddresses(TTree *, Bool_t undo=kFALSE)
Set branch addresses of passed tree equal to ours.
Definition TTree.cxx:3293
virtual Long64_t GetEntries() const
Definition TTree.h:460
virtual TTree * CloneTree(Long64_t nentries=-1, Option_t *option="")
Create a clone of this tree and copy nentries.
Definition TTree.cxx:3133
virtual TLeaf * GetLeaf(const char *branchname, const char *leafname)
Return pointer to the 1st Leaf named name in any Branch of this Tree or any branch in the list of fri...
Definition TTree.cxx:6179
virtual void Reset(Option_t *option="")
Reset baskets, buffers and entries count in all branches and leaves.
Definition TTree.cxx:7982
Long64_t fMaxVirtualSize
Maximum total size of buffers kept in memory.
Definition TTree.h:99
TVirtualPerfStats * fPerfStats
! pointer to the current perf stats object
Definition TTree.h:129
Double_t fWeight
Tree weight (see TTree::SetWeight)
Definition TTree.h:90
virtual Long64_t GetReadEntry() const
Definition TTree.h:506
virtual TObjArray * GetListOfBranches()
Definition TTree.h:485
virtual TTree * GetTree() const
Definition TTree.h:514
virtual Long64_t LoadTree(Long64_t entry)
Set current entry.
Definition TTree.cxx:6457
virtual const char * GetAlias(const char *aliasName) const
Returns the expanded value of the alias. Search in the friends if any.
Definition TTree.cxx:5211
virtual Double_t GetMinimum(const char *columname)
Return minimum of column with name columname.
Definition TTree.cxx:6259
virtual void RemoveFriend(TTree *)
Remove a friend from the list of friends.
Definition TTree.cxx:7956
virtual Long64_t LoadTreeFriend(Long64_t entry, TTree *T)
Load entry on behalf of our master tree, we may use an index.
Definition TTree.cxx:6541
virtual void Browse(TBrowser *)
Browse content of the TTree.
Definition TTree.cxx:2606
TObject * fNotify
! Object to be notified when loading a Tree
Definition TTree.h:117
virtual TList * GetListOfClones()
Definition TTree.h:484
Long64_t fCacheSize
! Maximum size of file buffers
Definition TTree.h:105
TList * fClones
! List of cloned trees which share our addresses
Definition TTree.h:132
@ kLoadTree
Definition TTree.h:218
virtual void Draw(Option_t *opt)
Default Draw method for all objects.
Definition TTree.h:428
virtual void SetName(const char *name)
Change the name of this tree.
Definition TTree.cxx:9171
virtual TList * GetListOfFriends() const
Definition TTree.h:487
Long64_t fReadEntry
! Number of the entry being processed
Definition TTree.h:107
virtual Int_t GetNbranches()
Definition TTree.h:499
virtual TLeaf * FindLeaf(const char *name)
Find leaf..
Definition TTree.cxx:4904
TDirectory * fDirectory
! Pointer to directory holding this tree
Definition TTree.h:118
@ kNeedEnableDecomposedObj
Definition TTree.h:241
@ kNoCheck
Definition TTree.h:240
@ kMissingBranch
Definition TTree.h:230
virtual void ResetBranchAddresses()
Tell all of our branches to drop their current objects and allocate new ones.
Definition TTree.cxx:8054
virtual Int_t SetCacheSize(Long64_t cachesize=-1)
Set maximum size of the file cache .
Definition TTree.cxx:8652
void AddClone(TTree *)
Add a cloned tree to our list of trees to be notified whenever we change our branch addresses or when...
Definition TTree.cxx:1218
virtual void SetBranchStatus(const char *bname, Bool_t status=1, UInt_t *found=0)
Set branch status to Process or DoNotProcess.
Definition TTree.cxx:8505
virtual Int_t GetFileNumber() const
Definition TTree.h:473
virtual void SetChainOffset(Long64_t offset=0)
Definition TTree.h:606
Int_t fPacketSize
! Number of entries in one packet for parallel root
Definition TTree.h:109
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition TTree.cxx:9693
virtual Long64_t Scan(const char *varexp="", const char *selection="", Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Loop over tree entries and print entries passing selection.
Definition TTree.cxx:8073
Int_t fMakeClass
! not zero when processing code generated by MakeClass
Definition TTree.h:115
static constexpr Long64_t kMaxEntries
Definition TTree.h:226
This class represents a WWW compatible URL.
Definition TUrl.h:33
const char * GetAnchor() const
Definition TUrl.h:70
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition TUrl.cxx:389
void SetAnchor(const char *anchor)
Definition TUrl.h:86
const char * GetFileAndOptions() const
Return the file and its options (the string specified behind the ?).
Definition TUrl.cxx:503
const char * GetFile() const
Definition TUrl.h:69
void SetUrl(const char *url, Bool_t defaultIsFile=kFALSE)
Parse url character string and split in its different subcomponents.
Definition TUrl.cxx:110
void SetOptions(const char *opt)
Definition TUrl.h:87
const char * GetOptions() const
Definition TUrl.h:71
const char * GetProtocol() const
Definition TUrl.h:64
virtual void UpdateFormulaLeaves(const TTree *parent)=0
virtual void SetFile(TFile *)=0
virtual void UpdateFormulaLeaves()=0
R__EXTERN TVirtualRWMutex * gCoreMutex
Definition file.py:1
Definition first.py:1
Definition tree.py:1
TCanvas * slash()
Definition slash.C:1
auto * l
Definition textangle.C:4