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