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