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