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