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 if (fFriends) {
1344 // The current tree has not changed but some of its friends might.
1345 //
1346 TIter next(fFriends);
1347 TFriendLock lock(this, kLoadTree);
1348 TFriendElement* fe = nullptr;
1349 while ((fe = (TFriendElement*) next())) {
1350 TTree* at = fe->GetTree();
1351 // If the tree is a
1352 // direct friend of the chain, it should be scanned
1353 // used the chain entry number and NOT the tree entry
1354 // number (treeReadEntry) hence we do:
1355 at->LoadTreeFriend(entry, this);
1356 }
1357 bool needUpdate = false;
1358 if (fTree->GetListOfFriends()) {
1360 if (fetree->IsUpdated()) {
1361 needUpdate = true;
1362 fetree->ResetUpdated();
1363 }
1364 }
1365 }
1366 if (needUpdate) {
1367 // Update the branch/leaf addresses and
1368 // the list of leaves in all TTreeFormula of the TTreePlayer (if any).
1369
1370 // Set the branch statuses for the newly opened file.
1371 TChainElement *frelement;
1372 TIter fnext(fStatus);
1373 while ((frelement = (TChainElement*) fnext())) {
1374 Int_t status = frelement->GetStatus();
1375 fTree->SetBranchStatus(frelement->GetName(), status);
1376 }
1377
1378 // Set the branch addresses for the newly opened file.
1379 fnext.Reset();
1380 while ((frelement = (TChainElement*) fnext())) {
1381 void* addr = frelement->GetBaddress();
1382 if (addr) {
1383 TBranch* br = fTree->GetBranch(frelement->GetName());
1384 TBranch** pp = frelement->GetBranchPtr();
1385 if (pp) {
1386 // FIXME: What if br is zero here?
1387 *pp = br;
1388 }
1389 if (br) {
1390 if (!frelement->GetCheckedType()) {
1392 (EDataType) frelement->GetBaddressType(), frelement->GetBaddressIsPtr());
1393 if ((res & kNeedEnableDecomposedObj) && !br->GetMakeClass()) {
1394 br->SetMakeClass(true);
1395 }
1396 frelement->SetDecomposedObj(br->GetMakeClass());
1397 frelement->SetCheckedType(true);
1398 }
1399 // FIXME: We may have to tell the branch it should
1400 // not be an owner of the object pointed at.
1401 br->SetAddress(addr);
1402 if (TestBit(kAutoDelete)) {
1403 br->SetAutoDelete(true);
1404 }
1405 }
1406 }
1407 }
1408 if (fPlayer) {
1410 }
1411 // Notify user if requested.
1412 if (fNotify) {
1413 if(!fNotify->Notify()) return -6;
1414 }
1415 }
1416 }
1417 return treeReadEntry;
1418 }
1419
1420 if (fExternalFriends) {
1422 external_fe->MarkUpdated();
1423 }
1424 }
1425
1426 // Delete the current tree and open the new tree.
1427 TTreeCache* tpf = nullptr;
1428 // Delete file unless the file owns this chain!
1429 // FIXME: The "unless" case here causes us to leak memory.
1430 if (fFile) {
1431 if (!fDirectory->GetList()->FindObject(this)) {
1432 if (fTree) {
1433 // (fFile != 0 && fTree == 0) can happen when
1434 // InvalidateCurrentTree is called (for example from
1435 // AddFriend). Having fTree === 0 is necessary in that
1436 // case because in some cases GetTree is used as a check
1437 // to see if a TTree is already loaded.
1438 // However, this prevent using the following to reuse
1439 // the TTreeCache object.
1440 tpf = fTree->GetReadCache(fFile);
1441 if (tpf) {
1442 tpf->ResetCache();
1443 }
1444
1445 fFile->SetCacheRead(nullptr, fTree);
1446 // If the tree has clones, copy them into the chain
1447 // clone list so we can change their branch addresses
1448 // when necessary.
1449 //
1450 // This is to support the syntax:
1451 //
1452 // TTree* clone = chain->GetTree()->CloneTree(0);
1453 //
1454 // We need to call the invalidate exactly here, since
1455 // we no longer need the value of fTree and it is
1456 // about to be deleted.
1458 }
1459
1460 if (fCanDeleteRefs) {
1461 fFile->Close("R");
1462 }
1463 delete fFile;
1464 fFile = nullptr;
1465 } else {
1466 // If the tree has clones, copy them into the chain
1467 // clone list so we can change their branch addresses
1468 // when necessary.
1469 //
1470 // This is to support the syntax:
1471 //
1472 // TTree* clone = chain->GetTree()->CloneTree(0);
1473 //
1475 }
1476 }
1477
1478 TChainElement* element = (TChainElement*) fFiles->At(treenum);
1479 if (!element) {
1480 if (treeReadEntry) {
1481 return -4;
1482 }
1483 // Last attempt, just in case all trees in the chain have 0 entries.
1484 element = (TChainElement*) fFiles->At(0);
1485 if (!element) {
1486 return -4;
1487 }
1488 }
1489
1490 // FIXME: We leak memory here, we've just lost the open file
1491 // if we did not delete it above.
1492 {
1494 const char *option = fGlobalRegistration ? "READ" : "READ_WITHOUT_GLOBALREGISTRATION";
1495 fFile = TFile::Open(element->GetTitle(), option);
1498 }
1499
1500 // ----- Begin of modifications by MvL
1501 Int_t returnCode = 0;
1502 if (!fFile || fFile->IsZombie()) {
1503 if (fFile) {
1504 delete fFile;
1505 fFile = nullptr;
1506 }
1507 // Note: We do *not* own fTree.
1508 fTree = nullptr;
1509 returnCode = -3;
1510 } else {
1511 if (fPerfStats)
1513
1514 // Note: We do *not* own fTree after this, the file does!
1515 fTree = dynamic_cast<TTree*>(fFile->Get(element->GetName()));
1516 if (!fTree) {
1517 // Now that we do not check during the addition, we need to check here!
1518 Error("LoadTree", "Cannot find tree with name %s in file %s", element->GetName(), element->GetTitle());
1519 delete fFile;
1520 fFile = nullptr;
1521 // We do not return yet so that 'fEntries' can be updated with the
1522 // sum of the entries of all the other trees.
1523 returnCode = -4;
1524 } else if (!fGlobalRegistration) {
1526 }
1527 }
1528
1529 fTreeNumber = treenum;
1530 // FIXME: We own fFile, we must be careful giving away a pointer to it!
1531 // FIXME: We may set fDirectory to zero here!
1532 fDirectory = fFile;
1533
1534 // Reuse cache from previous file (if any).
1535 if (tpf) {
1536 if (fFile) {
1537 // FIXME: fTree may be zero here.
1538 tpf->UpdateBranches(fTree);
1539 tpf->ResetCache();
1540 fFile->SetCacheRead(tpf, fTree);
1541 } else {
1542 // FIXME: One of the file in the chain is missing
1543 // we have no place to hold the pointer to the
1544 // TTreeCache.
1545 delete tpf;
1546 tpf = nullptr;
1547 }
1548 } else {
1549 if (fCacheUserSet) {
1550 this->SetCacheSize(fCacheSize);
1551 }
1552 }
1553
1554 // Check if fTreeOffset has really been set.
1555 Long64_t nentries = 0;
1556 if (fTree) {
1558 }
1559
1563 element->SetNumberEntries(nentries);
1564 // Below we must test >= in case the tree has no entries.
1565 if (entry >= fTreeOffset[fTreeNumber+1]) {
1566 if ((fTreeNumber < (fNtrees - 1)) && (entry < fTreeOffset[fTreeNumber+2])) {
1567 // The request entry is not in the tree 'fTreeNumber' we will need
1568 // to look further.
1569
1570 // Before moving on, let's record the result.
1571 element->SetLoadResult(returnCode);
1572
1573 // Before trying to read the file file/tree, notify the user
1574 // that we have switched trees if requested; the user might need
1575 // to properly account for the number of files/trees even if they
1576 // have no entries.
1577 if (fNotify) {
1578 if(!fNotify->Notify()) return -6;
1579 }
1580
1581 // Load the next TTree.
1582 return LoadTree(entry);
1583 } else {
1584 treeReadEntry = fReadEntry = -2;
1585 }
1586 }
1587 }
1588
1589
1590 if (!fTree) {
1591 // The Error message already issued. However if we reach here
1592 // we need to make sure that we do not use fTree.
1593 //
1594 // Force a reload of the tree next time.
1595 fTreeNumber = -1;
1596
1597 element->SetLoadResult(returnCode);
1598 return returnCode;
1599 }
1600 // ----- End of modifications by MvL
1601
1602 // Copy the chain's clone list into the new tree's
1603 // clone list so that branch addresses stay synchronized.
1604 if (fClones) {
1605 for (TObjLink* lnk = fClones->FirstLink(); lnk; lnk = lnk->Next()) {
1606 TTree* clone = (TTree*) lnk->GetObject();
1607 ((TChain*) fTree)->TTree::AddClone(clone);
1608 }
1609 }
1610
1611 // Since some of the friends of this chain might simple trees
1612 // (i.e., not really chains at all), we need to execute this
1613 // before calling LoadTree(entry) on the friends (so that
1614 // they use the correct read entry number).
1615
1616 // Change the new current tree to the new entry.
1617 Long64_t loadResult = fTree->LoadTree(treeReadEntry);
1618 if (loadResult == treeReadEntry) {
1619 element->SetLoadResult(0);
1620 } else {
1621 // This is likely to be an internal error, if treeReadEntry was not in range
1622 // (or intentionally -2 for TChain::GetEntries) then something happened
1623 // that is very odd/surprising.
1624 element->SetLoadResult(-5);
1625 }
1626
1627
1628 // Change the chain friends to the new entry.
1629 if (fFriends) {
1630 // An alternative would move this code to each of the function
1631 // calling LoadTree (and to overload a few more).
1632 TIter next(fFriends);
1633 TFriendLock lock(this, kLoadTree);
1634 TFriendElement* fe = nullptr;
1635 while ((fe = (TFriendElement*) next())) {
1636 TTree* t = fe->GetTree();
1637 if (!t) continue;
1638 if (t->GetTreeIndex()) {
1639 t->GetTreeIndex()->UpdateFormulaLeaves(nullptr);
1640 }
1641 if (t->GetTree() && t->GetTree()->GetTreeIndex()) {
1643 }
1644 if (treeReadEntry == -2) {
1645 // an entry after the end of the chain was requested (it usually happens when GetEntries is called)
1646 t->LoadTree(entry);
1647 } else {
1648 t->LoadTreeFriend(entry, this);
1649 }
1650 TTree* friend_t = t->GetTree();
1651 if (friend_t) {
1652 auto localfe = fTree->AddFriend(t, fe->GetName());
1654 }
1655 }
1656 }
1657
1660
1663
1664 // Set the branch statuses for the newly opened file.
1665 TIter next(fStatus);
1666 while ((element = (TChainElement*) next())) {
1667 Int_t status = element->GetStatus();
1668 fTree->SetBranchStatus(element->GetName(), status);
1669 }
1670
1671 // Set the branch addresses for the newly opened file.
1672 next.Reset();
1673 while ((element = (TChainElement*) next())) {
1674 void* addr = element->GetBaddress();
1675 if (addr) {
1676 TBranch* br = fTree->GetBranch(element->GetName());
1677 TBranch** pp = element->GetBranchPtr();
1678 if (pp) {
1679 // FIXME: What if br is zero here?
1680 *pp = br;
1681 }
1682 if (br) {
1683 if (!element->GetCheckedType()) {
1685 (EDataType) element->GetBaddressType(), element->GetBaddressIsPtr());
1686 if ((res & kNeedEnableDecomposedObj) && !br->GetMakeClass()) {
1687 br->SetMakeClass(true);
1688 }
1689 element->SetDecomposedObj(br->GetMakeClass());
1690 element->SetCheckedType(true);
1691 }
1692 // FIXME: We may have to tell the branch it should
1693 // not be an owner of the object pointed at.
1694 br->SetAddress(addr);
1695 if (TestBit(kAutoDelete)) {
1696 br->SetAutoDelete(true);
1697 }
1698 }
1699 }
1700 }
1701
1702 // Update the addresses of the chain's cloned trees, if any.
1703 if (fClones) {
1704 for (TObjLink* lnk = fClones->FirstLink(); lnk; lnk = lnk->Next()) {
1705 TTree* clone = (TTree*) lnk->GetObject();
1707 }
1708 }
1709
1710 // Update list of leaves in all TTreeFormula's of the TTreePlayer (if any).
1711 if (fPlayer) {
1713 }
1714
1715 // Notify user we have switched trees if requested.
1716 if (fNotify) {
1717 if(!fNotify->Notify()) return -6;
1718 }
1719
1720 // Return the new local entry number.
1721 return treeReadEntry;
1722}
1723
1724////////////////////////////////////////////////////////////////////////////////
1725/// Check / locate the files in the chain.
1726/// By default only the files not yet looked up are checked.
1727/// Use force = true to check / re-check every file.
1728
1729void TChain::Lookup(bool force)
1730{
1731 TIter next(fFiles);
1732 TChainElement* element = nullptr;
1733 Int_t nelements = fFiles->GetEntries();
1734 printf("\n");
1735 printf("TChain::Lookup - Looking up %d files .... \n", nelements);
1736 Int_t nlook = 0;
1737 TFileStager *stg = nullptr;
1738 while ((element = (TChainElement*) next())) {
1739 // Do not do it more than needed
1740 if (element->HasBeenLookedUp() && !force) continue;
1741 // Count
1742 nlook++;
1743 // Get the Url
1744 TUrl elemurl(element->GetTitle(), true);
1745 // Save current options and anchor
1746 TString anchor = elemurl.GetAnchor();
1747 TString options = elemurl.GetOptions();
1748 // Reset options and anchor
1749 elemurl.SetOptions("");
1750 elemurl.SetAnchor("");
1751 // Locate the file
1752 TString eurl(elemurl.GetUrl());
1753 if (!stg || !stg->Matches(eurl)) {
1754 SafeDelete(stg);
1755 {
1757 stg = TFileStager::Open(eurl);
1758 }
1759 if (!stg) {
1760 Error("Lookup", "TFileStager instance cannot be instantiated");
1761 break;
1762 }
1763 }
1764 Int_t n1 = (nelements > 100) ? (Int_t) nelements / 100 : 1;
1765 if (stg->Locate(eurl.Data(), eurl) == 0) {
1766 if (nlook > 0 && !(nlook % n1)) {
1767 printf("Lookup | %3d %% finished\r", 100 * nlook / nelements);
1768 fflush(stdout);
1769 }
1770 // Get the effective end-point Url
1771 elemurl.SetUrl(eurl);
1772 // Restore original options and anchor, if any
1773 elemurl.SetOptions(options);
1774 elemurl.SetAnchor(anchor);
1775 // Save it into the element
1776 element->SetTitle(elemurl.GetUrl());
1777 // Remember
1778 element->SetLookedUp();
1779 } else {
1780 // Failure: remove
1781 fFiles->Remove(element);
1782 if (gSystem->AccessPathName(eurl))
1783 Error("Lookup", "file %s does not exist\n", eurl.Data());
1784 else
1785 Error("Lookup", "file %s cannot be read\n", eurl.Data());
1786 }
1787 }
1788 if (nelements > 0)
1789 printf("Lookup | %3d %% finished\n", 100 * nlook / nelements);
1790 else
1791 printf("\n");
1792 fflush(stdout);
1793 SafeDelete(stg);
1794}
1795
1796////////////////////////////////////////////////////////////////////////////////
1797/// Loop on nentries of this chain starting at firstentry. (NOT IMPLEMENTED)
1798
1800{
1801 Error("Loop", "Function not yet implemented");
1802
1803 if (option || nentries || firstentry) { } // keep warnings away
1804
1805#if 0
1806 if (LoadTree(firstentry) < 0) return;
1807
1808 if (firstentry < 0) firstentry = 0;
1809 Long64_t lastentry = firstentry + nentries -1;
1810 if (lastentry > fEntries-1) {
1811 lastentry = fEntries -1;
1812 }
1813
1814 GetPlayer();
1815 GetSelector();
1816 fSelector->Start(option);
1817
1818 Long64_t entry = firstentry;
1819 Int_t tree,e0,en;
1820 for (tree=0;tree<fNtrees;tree++) {
1821 e0 = fTreeOffset[tree];
1822 en = fTreeOffset[tree+1] - 1;
1823 if (en > lastentry) en = lastentry;
1824 if (entry > en) continue;
1825
1826 LoadTree(entry);
1827 fSelector->BeginFile();
1828
1829 while (entry <= en) {
1830 fSelector->Execute(fTree, entry - e0);
1831 entry++;
1832 }
1833 fSelector->EndFile();
1834 }
1835
1836 fSelector->Finish(option);
1837#endif
1838}
1839
1840////////////////////////////////////////////////////////////////////////////////
1841/// List the chain.
1842
1844{
1846 TIter next(fFiles);
1847 TChainElement* file = nullptr;
1849 while ((file = (TChainElement*)next())) {
1850 file->ls(option);
1851 }
1853}
1854
1855////////////////////////////////////////////////////////////////////////////////
1856/// Merge all the entries in the chain into a new tree in a new file.
1857///
1858/// See important note in the following function Merge().
1859///
1860/// If the chain is expecting the input tree inside a directory,
1861/// this directory is NOT created by this routine.
1862///
1863/// So in a case where we have:
1864/// ~~~ {.cpp}
1865/// TChain ch("mydir/mytree");
1866/// ch.Merge("newfile.root");
1867/// ~~~
1868/// The resulting file will have not subdirectory. To recreate
1869/// the directory structure do:
1870/// ~~~ {.cpp}
1871/// TFile* file = TFile::Open("newfile.root", "RECREATE");
1872/// file->mkdir("mydir")->cd();
1873/// ch.Merge(file, 0);
1874/// ~~~
1875
1877{
1878 TFile *file = TFile::Open(name, "recreate", "chain files", 1);
1879 return Merge(file, 0, option);
1880}
1881
1882////////////////////////////////////////////////////////////////////////////////
1883/// Merge all chains in the collection. (NOT IMPLEMENTED)
1884
1885Long64_t TChain::Merge(TCollection* /* list */, Option_t* /* option */ )
1886{
1887 Error("Merge", "not implemented");
1888 return -1;
1889}
1890
1891////////////////////////////////////////////////////////////////////////////////
1892/// Merge all chains in the collection. (NOT IMPLEMENTED)
1893
1895{
1896 Error("Merge", "not implemented");
1897 return -1;
1898}
1899
1900////////////////////////////////////////////////////////////////////////////////
1901/// Merge all the entries in the chain into a new tree in the current file.
1902///
1903/// Note: The "file" parameter is *not* the file where the new
1904/// tree will be inserted. The new tree is inserted into
1905/// gDirectory, which is usually the most recently opened
1906/// file, or the directory most recently cd()'d to.
1907///
1908/// If option = "C" is given, the compression level for all branches
1909/// in the new Tree is set to the file compression level. By default,
1910/// the compression level of all branches is the original compression
1911/// level in the old trees.
1912///
1913/// If basketsize > 1000, the basket size for all branches of the
1914/// new tree will be set to basketsize.
1915///
1916/// Example using the file generated in $ROOTSYS/test/Event
1917/// merge two copies of Event.root
1918/// ~~~ {.cpp}
1919/// gSystem.Load("libEvent");
1920/// TChain ch("T");
1921/// ch.Add("Event1.root");
1922/// ch.Add("Event2.root");
1923/// ch.Merge("all.root");
1924/// ~~~
1925/// If the chain is expecting the input tree inside a directory,
1926/// this directory is NOT created by this routine.
1927///
1928/// So if you do:
1929/// ~~~ {.cpp}
1930/// TChain ch("mydir/mytree");
1931/// ch.Merge("newfile.root");
1932/// ~~~
1933/// The resulting file will not have subdirectories. In order to
1934/// preserve the directory structure do the following instead:
1935/// ~~~ {.cpp}
1936/// TFile* file = TFile::Open("newfile.root", "RECREATE");
1937/// file->mkdir("mydir")->cd();
1938/// ch.Merge(file, 0);
1939/// ~~~
1940/// If 'option' contains the word 'fast' the merge will be done without
1941/// unzipping or unstreaming the baskets (i.e., a direct copy of the raw
1942/// bytes on disk).
1943///
1944/// When 'fast' is specified, 'option' can also contains a
1945/// sorting order for the baskets in the output file.
1946///
1947/// There is currently 3 supported sorting order:
1948/// ~~~ {.cpp}
1949/// SortBasketsByOffset (the default)
1950/// SortBasketsByBranch
1951/// SortBasketsByEntry
1952/// ~~~
1953/// When using SortBasketsByOffset the baskets are written in
1954/// the output file in the same order as in the original file
1955/// (i.e. the basket are sorted on their offset in the original
1956/// file; Usually this also means that the baskets are sorted
1957/// on the index/number of the _last_ entry they contain)
1958///
1959/// When using SortBasketsByBranch all the baskets of each
1960/// individual branches are stored contiguously. This tends to
1961/// optimize reading speed when reading a small number (1->5) of
1962/// branches, since all their baskets will be clustered together
1963/// instead of being spread across the file. However it might
1964/// decrease the performance when reading more branches (or the full
1965/// entry).
1966///
1967/// When using SortBasketsByEntry the baskets with the lowest
1968/// starting entry are written first. (i.e. the baskets are
1969/// sorted on the index/number of the first entry they contain).
1970/// This means that on the file the baskets will be in the order
1971/// in which they will be needed when reading the whole tree
1972/// sequentially.
1973///
1974/// ## IMPORTANT Note 1: AUTOMATIC FILE OVERFLOW
1975///
1976/// When merging many files, it may happen that the resulting file
1977/// reaches a size > TTree::fgMaxTreeSize (default = 100 GBytes).
1978/// In this case the current file is automatically closed and a new
1979/// file started. If the name of the merged file was "merged.root",
1980/// the subsequent files will be named "merged_1.root", "merged_2.root",
1981/// etc. fgMaxTreeSize may be modified via the static function
1982/// TTree::SetMaxTreeSize.
1983/// When in fast mode, the check and switch is only done in between each
1984/// input file.
1985///
1986/// ## IMPORTANT Note 2: The output file is automatically closed and deleted.
1987///
1988/// This is required because in general the automatic file overflow described
1989/// above may happen during the merge.
1990/// If only the current file is produced (the file passed as first argument),
1991/// one can instruct Merge to not close and delete the file by specifying
1992/// the option "keep".
1993///
1994/// The function returns the total number of files produced.
1995/// To check that all files have been merged use something like:
1996/// ~~~ {.cpp}
1997/// if (newchain->GetEntries()!=oldchain->GetEntries()) {
1998/// ... not all the file have been copied ...
1999/// }
2000/// ~~~
2001
2003{
2004 // We must have been passed a file, we will use it
2005 // later to reset the compression level of the branches.
2006 if (!file) {
2007 // FIXME: We need an error message here.
2008 return 0;
2009 }
2010
2011 // Options
2012 bool fastClone = false;
2013 TString opt = option;
2014 opt.ToLower();
2015 if (opt.Contains("fast")) {
2016 fastClone = true;
2017 }
2018
2019 // The chain tree must have a list of branches
2020 // because we may try to change their basket
2021 // size later.
2022 TObjArray* lbranches = GetListOfBranches();
2023 if (!lbranches) {
2024 // FIXME: We need an error message here.
2025 return 0;
2026 }
2027
2028 // The chain must have a current tree because
2029 // that is the one we will clone.
2030 if (!fTree) {
2031 // -- LoadTree() has not yet been called, no current tree.
2032 // FIXME: We need an error message here.
2033 return 0;
2034 }
2035
2036 // Copy the chain's current tree without
2037 // copying any entries, we will do that later.
2038 TTree* newTree = CloneTree(0);
2039 if (!newTree) {
2040 // FIXME: We need an error message here.
2041 return 0;
2042 }
2043
2044 // Strip out the (potential) directory name.
2045 // FIXME: The merged chain may or may not have the
2046 // same name as the original chain. This is
2047 // bad because the chain name determines the
2048 // names of the trees in the chain by default.
2049 newTree->SetName(gSystem->BaseName(GetName()));
2050
2051 // FIXME: Why do we do this?
2052 newTree->SetAutoSave(2000000000);
2053
2054 // Circularity is incompatible with merging, it may
2055 // force us to throw away entries, which is not what
2056 // we are supposed to do.
2057 newTree->SetCircular(0);
2058
2059 // Reset the compression level of the branches.
2060 if (opt.Contains("c")) {
2061 TBranch* branch = nullptr;
2062 TIter nextb(newTree->GetListOfBranches());
2063 while ((branch = (TBranch*) nextb())) {
2065 }
2066 }
2067
2068 // Reset the basket size of the branches.
2069 if (basketsize > 1000) {
2070 TBranch* branch = nullptr;
2071 TIter nextb(newTree->GetListOfBranches());
2072 while ((branch = (TBranch*) nextb())) {
2073 branch->SetBasketSize(basketsize);
2074 }
2075 }
2076
2077 // Copy the entries.
2078 if (fastClone) {
2079 if ( newTree->CopyEntries( this, -1, option ) < 0 ) {
2080 // There was a problem!
2081 Error("Merge", "TTree has not been cloned\n");
2082 }
2083 } else {
2084 newTree->CopyEntries( this, -1, option );
2085 }
2086
2087 // Write the new tree header.
2088 newTree->Write();
2089
2090 // Get our return value.
2091 Int_t nfiles = newTree->GetFileNumber() + 1;
2092
2093 // Close and delete the current file of the new tree.
2094 if (!opt.Contains("keep")) {
2095 // Delete the currentFile and the TTree object.
2096 delete newTree->GetCurrentFile();
2097 }
2098 return nfiles;
2099}
2100
2101////////////////////////////////////////////////////////////////////////////////
2102/// Get the tree url or filename and other information from the name
2103///
2104/// A treename and a url's query section is split off from name. The
2105/// splitting depends on whether the resulting filename is to be
2106/// subsequently treated for wildcards or not, since the question mark is
2107/// both the url query identifier and a wildcard. Wildcard matching is not
2108/// done in this method itself.
2109/// ~~~ {.cpp}
2110/// [xxx://host]/a/path/file_name[?query[#treename]]
2111/// ~~~
2112///
2113/// The following way to specify the treename is still supported with the
2114/// constrain that the file name contains the sub-string '.root'.
2115/// This is now deprecated and will be removed in future versions.
2116/// ~~~ {.cpp}
2117/// [xxx://host]/a/path/file.root[.oext][/treename]
2118/// [xxx://host]/a/path/file.root[.oext][/treename][?query]
2119/// ~~~
2120///
2121/// Note that in a case like this
2122/// ~~~ {.cpp}
2123/// [xxx://host]/a/path/file#treename
2124/// ~~~
2125/// i.e. anchor but no options (query), the filename will be the full path, as
2126/// the anchor may be the internal file name of an archive. Use '?#%treename' to
2127/// pass the treename if the query field is empty.
2128///
2129/// \param[in] name is the original name
2130/// \param[out] filename the url or filename to be opened or matched
2131/// \param[out] treename the treename, which may be found in a url fragment section
2132/// as a trailing part of the name (deprecated).
2133/// If not found this will be empty.
2134/// Exception: a fragment containing the '=' character is _not_
2135/// interpreted as a treename
2136/// \param[out] query is the url query section, including the leading question
2137/// mark. If not found or the query section is only followed by
2138/// a fragment this will be empty.
2139/// \param[out] suffix the portion of name which was removed to from filename.
2140
2141void TChain::ParseTreeFilename(const char *name, TString &filename, TString &treename, TString &query,
2142 TString &suffix) const
2143{
2144 Ssiz_t pIdx = kNPOS;
2145 filename.Clear();
2146 treename.Clear();
2147 query.Clear();
2148 suffix.Clear();
2149
2150 // General case
2151 TUrl url(name, true);
2152 filename = (strcmp(url.GetProtocol(), "file")) ? url.GetUrl() : url.GetFileAndOptions();
2153
2154 TString fn = url.GetFile();
2155 // Extract query, if any
2156 if (url.GetOptions() && (strlen(url.GetOptions()) > 0))
2157 query.Form("?%s", url.GetOptions());
2158 // The treename can be passed as anchor
2159 const char *anchor = url.GetAnchor();
2160 if (anchor && anchor[0] != '\0') {
2161 // Support "?#tree_name" and "?query#tree_name"
2162 // "#tree_name" (no '?' is for tar archives)
2163 // If the treename would contain a '=', treat the anchor as part of the query instead. This makes sure
2164 // that Davix parameters are passed.
2165 if (!query.IsNull() || strstr(name, "?#")) {
2166 if (strstr(anchor, "=")) {
2167 query.Append("#");
2168 query.Append(anchor);
2169 } else {
2170 treename = anchor;
2171 }
2172 } else {
2173 // The anchor is part of the file name
2174 fn = url.GetFileAndOptions();
2175 }
2176 }
2177 // Suffix
2178 suffix = url.GetFileAndOptions();
2179 // Get options from suffix by removing the file name
2180 suffix.Replace(suffix.Index(fn), fn.Length(), "");
2181 // Remove the options suffix from the original file name
2182 filename.Replace(filename.Index(suffix), suffix.Length(), "");
2183
2184 // Special case: [...]file.root/treename
2185 static const char *dotr = ".root";
2186 static Ssiz_t dotrl = strlen(dotr);
2187 // Find the last one
2188 Ssiz_t js = filename.Index(dotr);
2189 while (js != kNPOS) {
2190 pIdx = js;
2191 js = filename.Index(dotr, js + 1);
2192 }
2193 if (pIdx != kNPOS) {
2194 static const char *slash = "/";
2195 static Ssiz_t slashl = strlen(slash);
2196 // Find the last one
2197 Ssiz_t ppIdx = filename.Index(slash, pIdx + dotrl);
2198 if (ppIdx != kNPOS) {
2199 // Good treename with the old recipe
2200 treename = filename(ppIdx + slashl, filename.Length());
2201 filename.Remove(ppIdx + slashl - 1);
2202 suffix.Insert(0, TString::Format("/%s", treename.Data()));
2203 }
2204 }
2205}
2206
2207////////////////////////////////////////////////////////////////////////////////
2208/// Print the header information of each tree in the chain.
2209/// See TTree::Print for a list of options.
2210
2212{
2213 TIter next(fFiles);
2214 TChainElement *element;
2215 while ((element = (TChainElement*)next())) {
2216 Printf("******************************************************************************");
2217 Printf("*Chain :%-10s: %-54s *", GetName(), element->GetTitle());
2218 Printf("******************************************************************************");
2219 TFile *file = TFile::Open(element->GetTitle());
2220 if (file && !file->IsZombie()) {
2221 TTree *tree = (TTree*)file->Get(element->GetName());
2222 if (tree) tree->Print(option);
2223 }
2224 delete file;
2225 }
2226}
2227
2228////////////////////////////////////////////////////////////////////////////////
2229/// Process all entries in this chain, calling functions in filename.
2230/// The return value is -1 in case of error and TSelector::GetStatus() in
2231/// in case of success.
2232/// See TTree::Process.
2233
2235{
2236 if (fProofChain) {
2237 // Make sure the element list is up to date
2238 if (!TestBit(kProofUptodate))
2239 SetProof(true, true);
2242 return fProofChain->Process(filename, option, nentries, firstentry);
2243 }
2244
2245 if (LoadTree(firstentry) < 0) {
2246 return 0;
2247 }
2248 return TTree::Process(filename, option, nentries, firstentry);
2249}
2250
2251////////////////////////////////////////////////////////////////////////////////
2252/// Process this chain executing the code in selector.
2253/// The return value is -1 in case of error and TSelector::GetStatus() in
2254/// in case of success.
2255
2257{
2258 if (fProofChain) {
2259 // Make sure the element list is up to date
2260 if (!TestBit(kProofUptodate))
2261 SetProof(true, true);
2264 return fProofChain->Process(selector, option, nentries, firstentry);
2265 }
2266
2267 return TTree::Process(selector, option, nentries, firstentry);
2268}
2269
2270////////////////////////////////////////////////////////////////////////////////
2271/// Make sure that obj (which is being deleted or will soon be) is no
2272/// longer referenced by this TTree.
2273
2275{
2276 if (fFile == obj) {
2277 fFile = nullptr;
2278 fDirectory = nullptr;
2279 fTree = nullptr;
2280 }
2281 if (fDirectory == obj) {
2282 fDirectory = nullptr;
2283 fTree = nullptr;
2284 }
2285 if (fTree == obj) {
2286 fTree = nullptr;
2287 }
2288}
2289
2290////////////////////////////////////////////////////////////////////////////////
2291/// Remove a friend from the list of friends.
2292
2294{
2295 // We already have been visited while recursively looking
2296 // through the friends tree, let return
2297
2298 if (!fFriends) {
2299 return;
2300 }
2301
2302 TTree::RemoveFriend(oldFriend);
2303
2304 if (fProofChain)
2305 // This updates the proxy chain when we will really use PROOF
2307
2308 // We need to invalidate the loading of the current tree because its list
2309 // of real friends is now obsolete. It is repairable only from LoadTree.
2311}
2312
2313////////////////////////////////////////////////////////////////////////////////
2314/// Resets the state of this chain.
2315
2317{
2318 delete fFile;
2319 fFile = nullptr;
2320 fNtrees = 0;
2321 fTreeNumber = -1;
2322 fTree = nullptr;
2323 fFile = nullptr;
2324 fFiles->Delete();
2325 fStatus->Delete();
2326 fTreeOffset[0] = 0;
2327 TChainElement* element = new TChainElement("*", "");
2328 fStatus->Add(element);
2329 fDirectory = nullptr;
2330
2331 TTree::Reset();
2332}
2333
2334////////////////////////////////////////////////////////////////////////////////
2335/// Resets the state of this chain after a merge (keep the customization but
2336/// forget the data).
2337
2339{
2340 fNtrees = 0;
2341 fTreeNumber = -1;
2342 fTree = nullptr;
2343 fFile = nullptr;
2344 fFiles->Delete();
2345 fTreeOffset[0] = 0;
2346
2348}
2349
2350////////////////////////////////////////////////////////////////////////////////
2351/// Save TChain as a C++ statements on output stream out.
2352/// With the option "friend" save the description of all the
2353/// TChain's friend trees or chains as well.
2354
2355void TChain::SavePrimitive(std::ostream &out, Option_t *option)
2356{
2357 static Int_t chCounter = 0;
2358
2359 TString chName = gInterpreter->MapCppName(GetName());
2360 if (chName.IsNull())
2361 chName = "_chain";
2362 ++chCounter;
2363 chName += chCounter;
2364
2365 TString opt = option;
2366 opt.ToLower();
2367
2368 out << " TChain *" << chName.Data() << " = new TChain(\"" << GetName() << "\");" << std::endl;
2369
2370 if (opt.Contains("friend")) {
2371 opt.ReplaceAll("friend", "");
2372 for (TObject *frel : *fFriends) {
2373 TTree *frtree = ((TFriendElement *)frel)->GetTree();
2374 if (dynamic_cast<TChain *>(frtree)) {
2375 if (strcmp(frtree->GetName(), GetName()) != 0)
2376 --chCounter; // make friends get the same chain counter
2377 frtree->SavePrimitive(out, opt.Data());
2378 out << " " << chName.Data() << "->AddFriend(\"" << frtree->GetName() << "\");" << std::endl;
2379 } else { // ordinary friend TTree
2380 TDirectory *file = frtree->GetDirectory();
2381 if (file && dynamic_cast<TFile *>(file))
2382 out << " " << chName.Data() << "->AddFriend(\"" << frtree->GetName() << "\", \"" << file->GetName()
2383 << "\");" << std::endl;
2384 }
2385 }
2386 }
2387 out << std::endl;
2388
2389 for (TObject *el : *fFiles) {
2390 TChainElement *chel = (TChainElement *)el;
2391 // Save tree file if it is really loaded to the chain
2392 if (chel->GetLoadResult() == 0 && chel->GetEntries() != 0) {
2393 if (chel->GetEntries() == TTree::kMaxEntries) // tree number of entries is not yet known
2394 out << " " << chName.Data() << "->AddFile(\"" << chel->GetTitle() << "\");" << std::endl;
2395 else
2396 out << " " << chName.Data() << "->AddFile(\"" << chel->GetTitle() << "\"," << chel->GetEntries() << ");"
2397 << std::endl;
2398 }
2399 }
2400 out << std::endl;
2401
2402 SaveMarkerAttributes(out, chName.Data(), 1, 1, 1);
2403}
2404
2405////////////////////////////////////////////////////////////////////////////////
2406/// Loop on tree and print entries passing selection.
2407/// - If varexp is 0 (or "") then print only first 8 columns.
2408/// - If varexp = "*" print all columns.
2409/// - Otherwise a columns selection can be made using "var1:var2:var3".
2410/// See TTreePlayer::Scan for more information.
2411
2412Long64_t TChain::Scan(const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
2413{
2414 if (LoadTree(firstentry) < 0) {
2415 return 0;
2416 }
2417 return TTree::Scan(varexp, selection, option, nentries, firstentry);
2418}
2419
2420////////////////////////////////////////////////////////////////////////////////
2421/// Set the global branch kAutoDelete bit.
2422///
2423/// When LoadTree loads a new Tree, the branches for which
2424/// the address is set will have the option AutoDelete set
2425/// For more details on AutoDelete, see TBranch::SetAutoDelete.
2426
2427void TChain::SetAutoDelete(bool autodelete)
2428{
2429 if (autodelete) {
2430 SetBit(kAutoDelete, true);
2431 } else {
2432 SetBit(kAutoDelete, false);
2433 }
2434}
2435
2437{
2438 // Set the cache size of the underlying TTree,
2439 // See TTree::SetCacheSize.
2440 // Returns 0 cache state ok (exists or not, as appropriate)
2441 // -1 on error
2442
2443 Int_t res = 0;
2444
2445 // remember user has requested this cache setting
2446 fCacheUserSet = true;
2447
2448 if (fTree) {
2449 res = fTree->SetCacheSize(cacheSize);
2450 } else {
2451 // If we don't have a TTree yet only record the cache size wanted
2452 res = 0;
2453 }
2454 fCacheSize = cacheSize; // Record requested size.
2455 return res;
2456}
2457
2458////////////////////////////////////////////////////////////////////////////////
2459/// Reset the addresses of the branch.
2460
2462{
2463 TChainElement* element = (TChainElement*) fStatus->FindObject(branch->GetName());
2464 if (element) {
2465 element->SetBaddress(nullptr);
2466 }
2467 if (fTree) {
2468 fTree->ResetBranchAddress(branch);
2469 }
2470}
2471
2472////////////////////////////////////////////////////////////////////////////////
2473/// Reset the addresses of the branches.
2474
2476{
2477 TIter next(fStatus);
2478 TChainElement* element = nullptr;
2479 while ((element = (TChainElement*) next())) {
2480 element->SetBaddress(nullptr);
2481 }
2482 if (fTree) {
2484 }
2485}
2486
2487////////////////////////////////////////////////////////////////////////////////
2488/// Set branch address.
2489///
2490/// \param[in] bname is the name of a branch.
2491/// \param[in] add is the address of the branch.
2492/// \param[in] ptr
2493///
2494/// Note: See the comments in TBranchElement::SetAddress() for a more
2495/// detailed discussion of the meaning of the add parameter.
2496///
2497/// IMPORTANT REMARK:
2498///
2499/// In case TChain::SetBranchStatus is called, it must be called
2500/// BEFORE calling this function.
2501///
2502/// See TTree::CheckBranchAddressType for the semantic of the return value.
2503
2504Int_t TChain::SetBranchAddress(const char *bname, void* add, TBranch** ptr)
2505{
2506 Int_t res = kNoCheck;
2507
2508 // Check if bname is already in the status list.
2509 // If not, create a TChainElement object and set its address.
2510 TChainElement* element = (TChainElement*) fStatus->FindObject(bname);
2511 if (!element) {
2512 element = new TChainElement(bname, "");
2513 fStatus->Add(element);
2514 }
2515 element->SetBaddress(add);
2516 element->SetBranchPtr(ptr);
2517 // Also set address in current tree.
2518 // FIXME: What about the chain clones?
2519 if (fTreeNumber >= 0) {
2520 TBranch* branch = fTree->GetBranch(bname);
2521 if (ptr) {
2522 *ptr = branch;
2523 }
2524 if (branch) {
2526 if ((res & kNeedEnableDecomposedObj) && !branch->GetMakeClass()) {
2527 branch->SetMakeClass(true);
2528 }
2529 element->SetDecomposedObj(branch->GetMakeClass());
2530 element->SetCheckedType(true);
2531 if (fClones) {
2532 void* oldAdd = branch->GetAddress();
2533 for (TObjLink* lnk = fClones->FirstLink(); lnk; lnk = lnk->Next()) {
2534 TTree* clone = (TTree*) lnk->GetObject();
2535 TBranch* cloneBr = clone->GetBranch(bname);
2536 if (cloneBr && (cloneBr->GetAddress() == oldAdd)) {
2537 // the clone's branch is still pointing to us
2538 cloneBr->SetAddress(add);
2539 if ((res & kNeedEnableDecomposedObj) && !cloneBr->GetMakeClass()) {
2540 cloneBr->SetMakeClass(true);
2541 }
2542 }
2543 }
2544 }
2545
2546 branch->SetAddress(add);
2547 } else {
2548 Error("SetBranchAddress", "unknown branch -> %s", bname);
2549 return kMissingBranch;
2550 }
2551 } else {
2552 if (ptr) {
2553 *ptr = nullptr;
2554 }
2555 }
2556 return res;
2557}
2558
2559////////////////////////////////////////////////////////////////////////////////
2560/// Check if bname is already in the status list, and if not, create a TChainElement object and set its address.
2561/// See TTree::CheckBranchAddressType for the semantic of the return value.
2562///
2563/// Note: See the comments in TBranchElement::SetAddress() for a more
2564/// detailed discussion of the meaning of the add parameter.
2565
2566Int_t TChain::SetBranchAddress(const char* bname, void* add, TClass* realClass, EDataType datatype, bool isptr)
2567{
2568 return SetBranchAddress(bname, add, nullptr, realClass, datatype, isptr);
2569}
2570
2571////////////////////////////////////////////////////////////////////////////////
2572/// Check if bname is already in the status list, and if not, create a TChainElement object and set its address.
2573/// See TTree::CheckBranchAddressType for the semantic of the return value.
2574///
2575/// Note: See the comments in TBranchElement::SetAddress() for a more
2576/// detailed discussion of the meaning of the add parameter.
2577
2578Int_t TChain::SetBranchAddress(const char* bname, void* add, TBranch** ptr, TClass* realClass, EDataType datatype, bool isptr)
2579{
2580 TChainElement* element = (TChainElement*) fStatus->FindObject(bname);
2581 if (!element) {
2582 element = new TChainElement(bname, "");
2583 fStatus->Add(element);
2584 }
2585 if (realClass) {
2586 element->SetBaddressClassName(realClass->GetName());
2587 }
2588 element->SetBaddressType((UInt_t) datatype);
2589 element->SetBaddressIsPtr(isptr);
2590 element->SetBranchPtr(ptr);
2591 return SetBranchAddress(bname, add, ptr);
2592}
2593
2594////////////////////////////////////////////////////////////////////////////////
2595/// Set branch status to Process or DoNotProcess
2596///
2597/// \param[in] bname is the name of a branch. if bname="*", apply to all branches.
2598/// \param[in] status = 1 branch will be processed,
2599/// = 0 branch will not be processed
2600/// \param[out] found
2601///
2602/// See IMPORTANT REMARKS in TTree::SetBranchStatus and TChain::SetBranchAddress
2603///
2604/// If found is not 0, the number of branch(es) found matching the regular
2605/// expression is returned in *found AND the error message 'unknown branch'
2606/// is suppressed.
2607
2608void TChain::SetBranchStatus(const char* bname, bool status, UInt_t* found)
2609{
2610 // FIXME: We never explicitly set found to zero!
2611
2612 // Check if bname is already in the status list,
2613 // if not create a TChainElement object and set its status.
2614 TChainElement* element = (TChainElement*) fStatus->FindObject(bname);
2615 if (element) {
2616 fStatus->Remove(element);
2617 } else {
2618 element = new TChainElement(bname, "");
2619 }
2620 fStatus->Add(element);
2621 element->SetStatus(status);
2622 // Also set status in current tree.
2623 if (fTreeNumber >= 0) {
2624 fTree->SetBranchStatus(bname, status, found);
2625 } else if (found) {
2626 *found = 1;
2627 }
2628}
2629
2630////////////////////////////////////////////////////////////////////////////////
2631/// Remove reference to this chain from current directory and add
2632/// reference to new directory dir. dir can be 0 in which case the chain
2633/// does not belong to any directory.
2634
2636{
2637 if (fDirectory == dir) return;
2638 if (fDirectory) fDirectory->Remove(this);
2639 fDirectory = dir;
2640 if (fDirectory) {
2641 fDirectory->Append(this);
2643 } else {
2644 fFile = nullptr;
2645 }
2646}
2647
2648////////////////////////////////////////////////////////////////////////////////
2649/// \brief Set the input entry list (processing the entries of the chain will
2650/// then be limited to the entries in the list).
2651///
2652/// \param[in] elist The entry list to be assigned to this chain.
2653/// \param[in] opt An option string. Possible values are:
2654/// - "" (default): both the file names of the chain elements and the file
2655/// names of the TEntryList sublists are expanded to full path name.
2656/// - "ne": the file names are taken as they are and not expanded
2657/// - "sync": the TChain will go through the TEntryList in lockstep with the
2658/// trees in the chain rather than performing a lookup based on
2659/// treename and filename. This is mostly useful when the TEntryList
2660/// has multiple sublists for the same tree and filename.
2661/// \throws std::runtime_error If option "sync" was chosen and either:
2662/// - \p elist doesn't have sub entry lists.
2663/// - the number of sub entry lists in \p elist is different than the
2664/// number of trees in the chain.
2665/// - any of the sub entry lists in \p elist doesn't correspond to the
2666/// tree of the chain with the same index (i.e. it doesn't share the
2667/// same tree name and file name).
2668///
2669/// This function finds correspondence between the sub-lists of the TEntryList
2670/// and the trees of the TChain.
2671
2673{
2674 if (fEntryList){
2675 //check, if the chain is the owner of the previous entry list
2676 //(it happens, if the previous entry list was created from a user-defined
2677 //TEventList in SetEventList() function)
2679 TEntryList *tmp = fEntryList;
2680 fEntryList = nullptr; // Avoid problem with RecursiveRemove.
2681 delete tmp;
2682 } else {
2683 fEntryList = nullptr;
2684 }
2685 }
2686 if (!elist){
2687 fEntryList = nullptr;
2688 fEventList = nullptr;
2689 return;
2690 }
2691 if (!elist->TestBit(kCanDelete)){
2692 //this is a direct call to SetEntryList, not via SetEventList
2693 fEventList = nullptr;
2694 }
2695 if (elist->GetN() == 0){
2696 fEntryList = elist;
2697 return;
2698 }
2699 if (fProofChain){
2700 //for processing on proof, event list and entry list can't be
2701 //set at the same time.
2702 fEventList = nullptr;
2703 fEntryList = elist;
2704 return;
2705 }
2706
2707 Int_t ne = fFiles->GetEntries();
2708 Int_t listfound=0;
2709 TString treename, filename;
2710
2711 TEntryList *templist = nullptr;
2712
2713 const auto *subentrylists = elist->GetLists();
2714 if(strcmp(opt, "sync") == 0){
2715 if(!subentrylists){
2716 std::string msg{"In 'TChain::SetEntryList': "};
2717 msg += "the input TEntryList doesn't have sub entry lists. Please make sure too add them through ";
2718 msg += "TEntryList::AddSubList";
2719 throw std::runtime_error(msg);
2720 }
2721 const auto nsubelists = subentrylists->GetEntries();
2722 if(nsubelists != ne){
2723 std::string msg{"In 'TChain::SetEntryList': "};
2724 msg += "the number of sub entry lists in the input TEntryList (";
2725 msg += std::to_string(nsubelists);
2726 msg += ") is not equal to the number of files in the chain (";
2727 msg += std::to_string(ne);
2728 msg += ")";
2729 throw std::runtime_error(msg);
2730 }
2731 }
2732
2733 for (Int_t ie = 0; ie<ne; ie++){
2734 auto chainElement = (TChainElement*)fFiles->UncheckedAt(ie);
2735 treename = chainElement->GetName();
2736 filename = chainElement->GetTitle();
2737
2738 if(strcmp(opt, "sync") == 0){
2739 // If the user asked for "sync" option, there should be a 1:1 mapping
2740 // between trees in the chain and sub entry lists in the argument elist
2741 // We have already checked that the input TEntryList has a number of
2742 // sub entry lists equal to the number of files in the chain.
2743 templist = static_cast<TEntryList*>(subentrylists->At(ie));
2744 auto elisttreename = templist->GetTreeName();
2745 auto elistfilename = templist->GetFileName();
2746
2747 if (strcmp(treename, elisttreename) != 0 || strcmp(filename, elistfilename) != 0){
2748 std::string msg{"In 'TChain::SetEntryList': "};
2749 msg += "the sub entry list at index ";
2750 msg += std::to_string(ie);
2751 msg += " doesn't correspond to treename '";
2752 msg += treename;
2753 msg += "' and filename '";
2754 msg += filename;
2755 msg += "': it has treename '";
2756 msg += elisttreename;
2757 msg += "' and filename '";
2758 msg += elistfilename;
2759 msg += "'";
2760 throw std::runtime_error(msg);
2761 }
2762
2763 }else{
2764 templist = elist->GetEntryList(treename, filename, opt);
2765 }
2766
2767 if (templist) {
2768 listfound++;
2769 templist->SetTreeNumber(ie);
2770 }
2771 }
2772
2773 if (listfound == 0){
2774 Error("SetEntryList", "No list found for the trees in this chain");
2775 fEntryList = nullptr;
2776 return;
2777 }
2778 fEntryList = elist;
2779 TList *elists = elist->GetLists();
2780 bool shift = false;
2781 TIter next(elists);
2782
2783 //check, if there are sub-lists in the entry list, that don't
2784 //correspond to any trees in the chain
2785 while((templist = (TEntryList*)next())){
2786 if (templist->GetTreeNumber() < 0){
2787 shift = true;
2788 break;
2789 }
2790 }
2791 fEntryList->SetShift(shift);
2792
2793}
2794
2795////////////////////////////////////////////////////////////////////////////////
2796/// Set the input entry list (processing the entries of the chain will then be
2797/// limited to the entries in the list). This function creates a special kind
2798/// of entry list (TEntryListFromFile object) that loads lists, corresponding
2799/// to the chain elements, one by one, so that only one list is in memory at a time.
2800///
2801/// If there is an error opening one of the files, this file is skipped and the
2802/// next file is loaded
2803///
2804/// File naming convention:
2805///
2806/// - by default, filename_elist.root is used, where filename is the
2807/// name of the chain element
2808/// - xxx$xxx.root - $ sign is replaced by the name of the chain element
2809///
2810/// If the list name is not specified (by passing filename_elist.root/listname to
2811/// the TChain::SetEntryList() function, the first object of class TEntryList
2812/// in the file is taken.
2813///
2814/// It is assumed, that there are as many list files, as there are elements in
2815/// the chain and they are in the same order
2816
2817void TChain::SetEntryListFile(const char *filename, Option_t * /*opt*/)
2818{
2819
2820 if (fEntryList){
2821 //check, if the chain is the owner of the previous entry list
2822 //(it happens, if the previous entry list was created from a user-defined
2823 //TEventList in SetEventList() function)
2825 TEntryList *tmp = fEntryList;
2826 fEntryList = nullptr; // Avoid problem with RecursiveRemove.
2827 delete tmp;
2828 } else {
2829 fEntryList = nullptr;
2830 }
2831 }
2832
2833 fEventList = nullptr;
2834
2835 TString basename(filename);
2836
2837 Int_t dotslashpos = basename.Index(".root/");
2838 TString behind_dot_root = "";
2839 if (dotslashpos>=0) {
2840 // Copy the list name specification
2841 behind_dot_root = basename(dotslashpos+6,basename.Length()-dotslashpos+6);
2842 // and remove it from basename
2843 basename.Remove(dotslashpos+5);
2844 }
2845 fEntryList = new TEntryListFromFile(basename.Data(), behind_dot_root.Data(), fNtrees);
2847 fEntryList->SetDirectory(nullptr);
2848 ((TEntryListFromFile*)fEntryList)->SetFileNames(fFiles);
2849}
2850
2851////////////////////////////////////////////////////////////////////////////////
2852/// This function transfroms the given TEventList into a TEntryList
2853///
2854/// NOTE, that this function loads all tree headers, because the entry numbers
2855/// in the TEventList are global and have to be recomputed, taking into account
2856/// the number of entries in each tree.
2857///
2858/// The new TEntryList is owned by the TChain and gets deleted when the chain
2859/// is deleted. This TEntryList is returned by GetEntryList() function, and after
2860/// GetEntryList() function is called, the TEntryList is not owned by the chain
2861/// any more and will not be deleted with it.
2862
2864{
2865 fEventList = evlist;
2866 if (fEntryList) {
2868 TEntryList *tmp = fEntryList;
2869 fEntryList = nullptr; // Avoid problem with RecursiveRemove.
2870 delete tmp;
2871 } else {
2872 fEntryList = nullptr;
2873 }
2874 }
2875
2876 if (!evlist) {
2877 fEntryList = nullptr;
2878 fEventList = nullptr;
2879 return;
2880 }
2881
2882 if(fProofChain) {
2883 //on proof, fEventList and fEntryList shouldn't be set at the same time
2884 if (fEntryList){
2885 //check, if the chain is the owner of the previous entry list
2886 //(it happens, if the previous entry list was created from a user-defined
2887 //TEventList in SetEventList() function)
2889 TEntryList *tmp = fEntryList;
2890 fEntryList = nullptr; // Avoid problem with RecursiveRemove.
2891 delete tmp;
2892 } else {
2893 fEntryList = nullptr;
2894 }
2895 }
2896 return;
2897 }
2898
2899 char enlistname[100];
2900 snprintf(enlistname,100, "%s_%s", evlist->GetName(), "entrylist");
2901 TEntryList *enlist = new TEntryList(enlistname, evlist->GetTitle());
2902 enlist->SetDirectory(nullptr);
2903
2904 Int_t nsel = evlist->GetN();
2905 Long64_t globalentry, localentry;
2906 const char *treename;
2907 const char *filename;
2909 //Load all the tree headers if the tree offsets are not known
2910 //It is assumed here, that loading the last tree will load all
2911 //previous ones
2912 printf("loading trees\n");
2913 (const_cast<TChain*>(this))->LoadTree(evlist->GetEntry(evlist->GetN()-1));
2914 }
2915 for (Int_t i=0; i<nsel; i++){
2916 globalentry = evlist->GetEntry(i);
2917 //add some protection from globalentry<0 here
2918 Int_t treenum = 0;
2919 while (globalentry>=fTreeOffset[treenum])
2920 treenum++;
2921 treenum--;
2922 localentry = globalentry - fTreeOffset[treenum];
2923 // printf("globalentry=%lld, treeoffset=%lld, localentry=%lld\n", globalentry, fTreeOffset[treenum], localentry);
2924 treename = ((TNamed*)fFiles->At(treenum))->GetName();
2925 filename = ((TNamed*)fFiles->At(treenum))->GetTitle();
2926 //printf("entering for tree %s %s\n", treename, filename);
2927 enlist->SetTree(treename, filename);
2928 enlist->Enter(localentry);
2929 }
2930 enlist->SetBit(kCanDelete, true);
2931 enlist->SetReapplyCut(evlist->GetReapplyCut());
2932 SetEntryList(enlist);
2933}
2934
2935////////////////////////////////////////////////////////////////////////////////
2936/// Change the name of this TChain.
2937
2938void TChain::SetName(const char* name)
2939{
2940 if (fGlobalRegistration) {
2941 // Should this be extended to include the call to TTree::SetName?
2942 R__WRITE_LOCKGUARD(ROOT::gCoreMutex); // Take the lock once rather than 3 times.
2943 gROOT->GetListOfCleanups()->Remove(this);
2944 gROOT->GetListOfSpecials()->Remove(this);
2945 gROOT->GetListOfDataSets()->Remove(this);
2946 }
2948 if (fGlobalRegistration) {
2949 // Should this be extended to include the call to TTree::SetName?
2950 R__WRITE_LOCKGUARD(ROOT::gCoreMutex); // Take the lock once rather than 3 times.
2951 gROOT->GetListOfCleanups()->Add(this);
2952 gROOT->GetListOfSpecials()->Add(this);
2953 gROOT->GetListOfDataSets()->Add(this);
2954 }
2955}
2956
2957////////////////////////////////////////////////////////////////////////////////
2958/// Set number of entries per packet for parallel root.
2959
2961{
2962 fPacketSize = size;
2963 TIter next(fFiles);
2964 TChainElement *element;
2965 while ((element = (TChainElement*)next())) {
2966 element->SetPacketSize(size);
2967 }
2968}
2969
2970////////////////////////////////////////////////////////////////////////////////
2971/// Enable/Disable PROOF processing on the current default Proof (gProof).
2972///
2973/// "Draw" and "Processed" commands will be handled by PROOF.
2974/// The refresh and gettreeheader are meaningful only if on == true.
2975/// If refresh is true the underlying fProofChain (chain proxy) is always
2976/// rebuilt (even if already existing).
2977/// If gettreeheader is true the header of the tree will be read from the
2978/// PROOF cluster: this is only needed for browsing and should be used with
2979/// care because it may take a long time to execute.
2980
2981void TChain::SetProof(bool on, bool refresh, bool gettreeheader)
2982{
2983 if (!on) {
2984 // Disable
2986 // Reset related bit
2988 } else {
2989 if (fProofChain && !refresh &&
2990 (!gettreeheader || (gettreeheader && fProofChain->GetTree()))) {
2991 return;
2992 }
2995
2996 // Make instance of TChainProof via the plugin manager
2998 if ((h = gROOT->GetPluginManager()->FindHandler("TChain", "proof"))) {
2999 if (h->LoadPlugin() == -1)
3000 return;
3001 if (!(fProofChain = reinterpret_cast<TChain *>(h->ExecPlugin(2, this, gettreeheader))))
3002 Error("SetProof", "creation of TProofChain failed");
3003 // Set related bits
3005 }
3006 }
3007}
3008
3009////////////////////////////////////////////////////////////////////////////////
3010/// Set chain weight.
3011///
3012/// The weight is used by TTree::Draw to automatically weight each
3013/// selected entry in the resulting histogram.
3014/// For example the equivalent of
3015/// ~~~ {.cpp}
3016/// chain.Draw("x","w")
3017/// ~~~
3018/// is
3019/// ~~~ {.cpp}
3020/// chain.SetWeight(w,"global");
3021/// chain.Draw("x");
3022/// ~~~
3023/// By default the weight used will be the weight
3024/// of each Tree in the TChain. However, one can force the individual
3025/// weights to be ignored by specifying the option "global".
3026/// In this case, the TChain global weight will be used for all Trees.
3027
3029{
3030 fWeight = w;
3031 TString opt = option;
3032 opt.ToLower();
3034 if (opt.Contains("global")) {
3036 }
3037}
3038
3039////////////////////////////////////////////////////////////////////////////////
3040/// Stream a class object.
3041
3043{
3044 if (b.IsReading()) {
3045 // Remove using the 'old' name.
3046 {
3048 gROOT->GetListOfCleanups()->Remove(this);
3049 }
3050
3051 UInt_t R__s, R__c;
3052 Version_t R__v = b.ReadVersion(&R__s, &R__c);
3053 if (R__v > 2) {
3054 b.ReadClassBuffer(TChain::Class(), this, R__v, R__s, R__c);
3055 } else {
3056 //====process old versions before automatic schema evolution
3058 b >> fTreeOffsetLen;
3059 b >> fNtrees;
3060 fFiles->Streamer(b);
3061 if (R__v > 1) {
3062 fStatus->Streamer(b);
3064 b.ReadFastArray(fTreeOffset,fTreeOffsetLen);
3065 }
3066 b.CheckByteCount(R__s, R__c, TChain::IsA());
3067 //====end of old versions
3068 }
3069 // Re-add using the new name.
3070 {
3072 gROOT->GetListOfCleanups()->Add(this);
3073 }
3074
3075 } else {
3076 b.WriteClassBuffer(TChain::Class(),this);
3077 }
3078}
3079
3080////////////////////////////////////////////////////////////////////////////////
3081/// Dummy function kept for back compatibility.
3082/// The cache is now activated automatically when processing TTrees/TChain.
3083
3084void TChain::UseCache(Int_t /* maxCacheSize */, Int_t /* pageSize */)
3085{
3086}
#define SafeDelete(p)
Definition RConfig.hxx:550
#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:560
#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:2436
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:3042
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:2427
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:2672
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:2211
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:2274
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:2981
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:2316
void ResetAfterMerge(TFileMergeInfo *) override
Resets the state of this chain after a merge (keep the customization but forget the data).
Definition TChain.cxx:2338
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:2475
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save TChain as a C++ statements on output stream out.
Definition TChain.cxx:2355
void SetEventList(TEventList *evlist) override
This function transfroms the given TEventList into a TEntryList.
Definition TChain.cxx:2863
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:2412
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:3028
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:1799
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:2504
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:2234
void RemoveFriend(TTree *) override
Remove a friend from the list of friends.
Definition TChain.cxx:2293
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:2461
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:2635
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:1876
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:2141
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:2817
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:2938
void ls(Option_t *option="") const override
List the chain.
Definition TChain.cxx:1843
void SetBranchStatus(const char *bname, bool status=true, UInt_t *found=nullptr) override
Set branch status to Process or DoNotProcess.
Definition TChain.cxx:2608
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:3084
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:2960
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:1729
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 composed of a header, followed by consecutive data records (TKey instances) with a wel...
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:2346
Int_t GetCompressionSettings() const
Definition TFile.h:396
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:4070
void Close(Option_t *option="") override
Close a file.
Definition TFile.cxx:931
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:1191
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:578
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:822
virtual TObjLink * FirstLink() const
Definition TList.h:102
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:470
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:164
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:201
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:962
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:976
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1004
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:200
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:62
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:72
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition TObject.h:64
static Int_t IncreaseDirLevel()
Increase the indentation level for ls().
Definition TROOT.cxx:2825
static Int_t DecreaseDirLevel()
Decrease the indentation level for ls().
Definition TROOT.cxx:2707
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:419
void ToLower()
Change string to lower-case.
Definition TString.cxx:1182
TString & Insert(Ssiz_t pos, const char *s)
Definition TString.h:663
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:696
const char * Data() const
Definition TString.h:378
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:706
Bool_t IsNull() const
Definition TString.h:416
TString & Remove(Ssiz_t pos)
Definition TString.h:687
TString & Append(const char *cs)
Definition TString.h:574
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:634
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:653
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:1284
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:922
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
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
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