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