Logo ROOT   6.12/07
Reference Guide
TTree.cxx
Go to the documentation of this file.
1 // @(#)root/tree:$Id$
2 // Author: Rene Brun 12/01/96
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  \defgroup tree Tree Library
13 
14  To store large quantities of same-class objects, ROOT provides the TTree and
15  TNtuple classes. The TTree class is optimized to
16  reduce disk space and enhance access speed. A TNtuple is a TTree that is limited
17  to only hold floating-point numbers; a TTree on the other hand can hold all kind
18  of data, such as objects or arrays in addition to all the simple types.
19 
20 */
21 
22 /** \class TTree
23 \ingroup tree
24 
25 A TTree object has a header with a name and a title.
26 
27 It consists of a list of independent branches (TBranch). Each branch has its own
28 definition and list of buffers. Branch buffers may be automatically written to
29 disk or kept in memory until the Tree attribute `fMaxVirtualSize` is reached.
30 Variables of one branch are written to the same buffer. A branch buffer is
31 automatically compressed if the file compression attribute is set (default).
32 
33 Branches may be written to different files (see TBranch::SetFile).
34 
35 The ROOT user can decide to make one single branch and serialize one object into
36 one single I/O buffer or to make several branches. Making one single branch and
37 one single buffer can be the right choice when one wants to process only a subset
38 of all entries in the tree. (you know for example the list of entry numbers you
39 want to process). Making several branches is particularly interesting in the
40 data analysis phase, when one wants to histogram some attributes of an object
41 (entry) without reading all the attributes.
42 ~~~ {.cpp}
43  TTree *tree = new TTree(name, title)
44 ~~~
45 Creates a Tree with name and title.
46 
47 Various kinds of branches can be added to a tree:
48 
49 - simple structures or list of variables. (may be for C or Fortran structures)
50 - any object (inheriting from TObject). (we expect this option be the most frequent)
51 - a ClonesArray. (a specialized object for collections of same class objects)
52 
53 
54 ## Case A
55 
56 ~~~ {.cpp}
57  TBranch *branch = tree->Branch(branchname, address, leaflist, bufsize)
58 ~~~
59 - address is the address of the first item of a structure
60 - leaflist is the concatenation of all the variable names and types
61  separated by a colon character :
62  The variable name and the variable type are separated by a
63  slash (/). The variable type must be 1 character. (Characters
64  after the first are legal and will be appended to the visible
65  name of the leaf, but have no effect.) If no type is given, the
66  type of the variable is assumed to be the same as the previous
67  variable. If the first variable does not have a type, it is
68  assumed of type F by default. The list of currently supported
69  types is given below:
70  - `C` : a character string terminated by the 0 character
71  - `B` : an 8 bit signed integer (`Char_t`)
72  - `b` : an 8 bit unsigned integer (`UChar_t`)
73  - `S` : a 16 bit signed integer (`Short_t`)
74  - `s` : a 16 bit unsigned integer (`UShort_t`)
75  - `I` : a 32 bit signed integer (`Int_t`)
76  - `i` : a 32 bit unsigned integer (`UInt_t`)
77  - `F` : a 32 bit floating point (`Float_t`)
78  - `D` : a 64 bit floating point (`Double_t`)
79  - `L` : a 64 bit signed integer (`Long64_t`)
80  - `l` : a 64 bit unsigned integer (`ULong64_t`)
81  - `O` : [the letter `o`, not a zero] a boolean (`Bool_t`)
82 - If the address points to a single numerical variable, the leaflist is optional:
83  int value;
84  `tree->Branch(branchname, &value);`
85 - If the address points to more than one numerical variable, we strongly recommend
86  that the variable be sorted in decreasing order of size. Any other order will
87  result in a non-portable (even between CINT and compiled code on the platform)
88  TTree (i.e. you will not be able to read it back on a platform with a different
89  padding strategy).
90 
91 
92 ## Case B
93 
94 ~~~ {.cpp}
95  TBranch *branch = tree->Branch(branchname, &p_object, bufsize, splitlevel)
96  TBranch *branch = tree->Branch(branchname, className, &p_object, bufsize, splitlevel)
97 ~~~
98 - p_object is a pointer to an object.
99 - If className is not specified, Branch uses the type of p_object to determine the
100  type of the object.
101 - If className is used to specify explicitly the object type, the className must
102  be of a type related to the one pointed to by the pointer. It should be either
103  a parent or derived class.
104 - if splitlevel=0, the object is serialized in the branch buffer.
105 - if splitlevel=1, this branch will automatically be split
106  into subbranches, with one subbranch for each data member or object
107  of the object itself. In case the object member is a TClonesArray,
108  the mechanism described in case C is applied to this array.
109 - if splitlevel=2 ,this branch will automatically be split
110  into subbranches, with one subbranch for each data member or object
111  of the object itself. In case the object member is a TClonesArray,
112  it is processed as a TObject*, only one branch.
113 
114 Note: The pointer whose address is passed to TTree::Branch must not
115  be destroyed (i.e. go out of scope) until the TTree is deleted or
116  TTree::ResetBranchAddress is called.
117 
118 Note: The pointer p_object must be initialized before calling TTree::Branch
119 - Do either:
120 ~~~ {.cpp}
121  MyDataClass* p_object = 0;
122  tree->Branch(branchname, &p_object);
123 ~~~
124 - Or:
125 ~~~ {.cpp}
126  MyDataClass* p_object = new MyDataClass;
127  tree->Branch(branchname, &p_object);
128 ~~~
129 Whether the pointer is set to zero or not, the ownership of the object
130 is not taken over by the TTree. I.e. even though an object will be allocated
131 by TTree::Branch if the pointer p_object is zero, the object will <b>not</b>
132 be deleted when the TTree is deleted.
133 
134 
135 ## Case C
136 
137 ~~~ {.cpp}
138  MyClass object;
139  TBranch *branch = tree->Branch(branchname, &object, bufsize, splitlevel)
140 ~~~
141 Note: The 2nd parameter must be the address of a valid object.
142  The object must not be destroyed (i.e. be deleted) until the TTree
143  is deleted or TTree::ResetBranchAddress is called.
144 
145 - if splitlevel=0, the object is serialized in the branch buffer.
146 - if splitlevel=1 (default), this branch will automatically be split
147  into subbranches, with one subbranch for each data member or object
148  of the object itself. In case the object member is a TClonesArray,
149  the mechanism described in case C is applied to this array.
150 - if splitlevel=2 ,this branch will automatically be split
151  into subbranches, with one subbranch for each data member or object
152  of the object itself. In case the object member is a TClonesArray,
153  it is processed as a TObject*, only one branch.
154 
155 
156 ## Case D
157 
158 ~~~ {.cpp}
159  TBranch *branch = tree->Branch(branchname,clonesarray, bufsize, splitlevel)
160  clonesarray is the address of a pointer to a TClonesArray.
161 ~~~
162 The TClonesArray is a direct access list of objects of the same class.
163 For example, if the TClonesArray is an array of TTrack objects,
164 this function will create one subbranch for each data member of
165 the object TTrack.
166 
167 
168 ## Case E
169 
170 ~~~ {.cpp}
171  TBranch *branch = tree->Branch( branchname, STLcollection, buffsize, splitlevel);
172 ~~~
173 STLcollection is the address of a pointer to std::vector, std::list,
174 std::deque, std::set or std::multiset containing pointers to objects.
175 If the splitlevel is a value bigger than 100 (TTree::kSplitCollectionOfPointers)
176 then the collection will be written in split mode, e.g. if it contains objects of
177 any types deriving from TTrack this function will sort the objects
178 based on their type and store them in separate branches in split
179 mode.
180 ~~~ {.cpp}
181  branch->SetAddress(Void *address)
182 ~~~
183 In case of dynamic structures changing with each entry for example, one must
184 redefine the branch address before filling the branch again.
185 This is done via the TBranch::SetAddress member function.
186 ~~~ {.cpp}
187  tree->Fill()
188 ~~~
189 loops on all defined branches and for each branch invokes the Fill function.
190 
191 See also the class TNtuple (a simple Tree with branches of floats)
192 and the class TNtupleD (a simple Tree with branches of doubles)
193 
194 ## Adding a Branch to an Existing Tree
195 
196 You may want to add a branch to an existing tree. For example,
197 if one variable in the tree was computed with a certain algorithm,
198 you may want to try another algorithm and compare the results.
199 One solution is to add a new branch, fill it, and save the tree.
200 The code below adds a simple branch to an existing tree.
201 Note the kOverwrite option in the Write method, it overwrites the
202 existing tree. If it is not specified, two copies of the tree headers
203 are saved.
204 ~~~ {.cpp}
205  void tree3AddBranch() {
206  TFile f("tree3.root", "update");
207 
208  Float_t new_v;
209  TTree *t3 = (TTree*)f->Get("t3");
210  TBranch *newBranch = t3->Branch("new_v", &new_v, "new_v/F");
211 
212  Long64_t nentries = t3->GetEntries(); // read the number of entries in the t3
213 
214  for (Long64_t i = 0; i < nentries; i++) {
215  new_v= gRandom->Gaus(0, 1);
216  newBranch->Fill();
217  }
218 
219  t3->Write("", TObject::kOverwrite); // save only the new version of the tree
220  }
221 ~~~
222 Adding a branch is often not possible because the tree is in a read-only
223 file and you do not have permission to save the modified tree with the
224 new branch. Even if you do have the permission, you risk losing the
225 original tree with an unsuccessful attempt to save the modification.
226 Since trees are usually large, adding a branch could extend it over the
227 2GB limit. In this case, the attempt to write the tree fails, and the
228 original data is erased.
229 In addition, adding a branch to a tree enlarges the tree and increases
230 the amount of memory needed to read an entry, and therefore decreases
231 the performance.
232 
233 For these reasons, ROOT offers the concept of friends for trees (and chains).
234 We encourage you to use TTree::AddFriend rather than adding a branch manually.
235 
236 Begin_Macro
237 ../../../tutorials/tree/tree.C
238 End_Macro
239 
240 ~~~ {.cpp}
241  // A simple example with histograms and a tree
242  //
243  // This program creates :
244  // - a one dimensional histogram
245  // - a two dimensional histogram
246  // - a profile histogram
247  // - a tree
248  //
249  // These objects are filled with some random numbers and saved on a file.
250 
251  #include "TFile.h"
252  #include "TH1.h"
253  #include "TH2.h"
254  #include "TProfile.h"
255  #include "TRandom.h"
256  #include "TTree.h"
257 
258  //__________________________________________________________________________
259  main(int argc, char **argv)
260  {
261  // Create a new ROOT binary machine independent file.
262  // Note that this file may contain any kind of ROOT objects, histograms,trees
263  // pictures, graphics objects, detector geometries, tracks, events, etc..
264  // This file is now becoming the current directory.
265  TFile hfile("htree.root","RECREATE","Demo ROOT file with histograms & trees");
266 
267  // Create some histograms and a profile histogram
268  TH1F *hpx = new TH1F("hpx","This is the px distribution",100,-4,4);
269  TH2F *hpxpy = new TH2F("hpxpy","py ps px",40,-4,4,40,-4,4);
270  TProfile *hprof = new TProfile("hprof","Profile of pz versus px",100,-4,4,0,20);
271 
272  // Define some simple structures
273  typedef struct {Float_t x,y,z;} POINT;
274  typedef struct {
275  Int_t ntrack,nseg,nvertex;
276  UInt_t flag;
277  Float_t temperature;
278  } EVENTN;
279  static POINT point;
280  static EVENTN eventn;
281 
282  // Create a ROOT Tree
283  TTree *tree = new TTree("T","An example of ROOT tree with a few branches");
284  tree->Branch("point",&point,"x:y:z");
285  tree->Branch("eventn",&eventn,"ntrack/I:nseg:nvertex:flag/i:temperature/F");
286  tree->Branch("hpx","TH1F",&hpx,128000,0);
287 
288  Float_t px,py,pz;
289  static Float_t p[3];
290 
291  // Here we start a loop on 1000 events
292  for ( Int_t i=0; i<1000; i++) {
293  gRandom->Rannor(px,py);
294  pz = px*px + py*py;
295  Float_t random = gRandom->::Rndm(1);
296 
297  // Fill histograms
298  hpx->Fill(px);
299  hpxpy->Fill(px,py,1);
300  hprof->Fill(px,pz,1);
301 
302  // Fill structures
303  p[0] = px;
304  p[1] = py;
305  p[2] = pz;
306  point.x = 10*(random-1);;
307  point.y = 5*random;
308  point.z = 20*random;
309  eventn.ntrack = Int_t(100*random);
310  eventn.nseg = Int_t(2*eventn.ntrack);
311  eventn.nvertex = 1;
312  eventn.flag = Int_t(random+0.5);
313  eventn.temperature = 20+random;
314 
315  // Fill the tree. For each event, save the 2 structures and 3 objects
316  // In this simple example, the objects hpx, hprof and hpxpy are slightly
317  // different from event to event. We expect a big compression factor!
318  tree->Fill();
319  }
320  // End of the loop
321 
322  tree->Print();
323 
324  // Save all objects in this file
325  hfile.Write();
326 
327  // Close the file. Note that this is automatically done when you leave
328  // the application.
329  hfile.Close();
330 
331  return 0;
332 }
333 ~~~
334 */
335 
336 #include "RConfig.h"
337 #include "TTree.h"
338 
339 #include "ROOT/TIOFeatures.hxx"
340 #include "TArrayC.h"
341 #include "TBufferFile.h"
342 #include "TBaseClass.h"
343 #include "TBasket.h"
344 #include "TBranchClones.h"
345 #include "TBranchElement.h"
346 #include "TBranchObject.h"
347 #include "TBranchRef.h"
348 #include "TBrowser.h"
349 #include "TClass.h"
350 #include "TClassEdit.h"
351 #include "TClonesArray.h"
352 #include "TCut.h"
353 #include "TDataMember.h"
354 #include "TDataType.h"
355 #include "TDirectory.h"
356 #include "TError.h"
357 #include "TEntryList.h"
358 #include "TEnv.h"
359 #include "TEventList.h"
360 #include "TFile.h"
361 #include "TFolder.h"
362 #include "TFriendElement.h"
363 #include "TInterpreter.h"
364 #include "TLeaf.h"
365 #include "TLeafB.h"
366 #include "TLeafC.h"
367 #include "TLeafD.h"
368 #include "TLeafElement.h"
369 #include "TLeafF.h"
370 #include "TLeafI.h"
371 #include "TLeafL.h"
372 #include "TLeafObject.h"
373 #include "TLeafS.h"
374 #include "TList.h"
375 #include "TMath.h"
376 #include "TROOT.h"
377 #include "TRealData.h"
378 #include "TRegexp.h"
379 #include "TStreamerElement.h"
380 #include "TStreamerInfo.h"
381 #include "TStyle.h"
382 #include "TSystem.h"
383 #include "TTreeCloner.h"
384 #include "TTreeCache.h"
385 #include "TTreeCacheUnzip.h"
386 #include "TVirtualCollectionProxy.h"
388 #include "TVirtualFitter.h"
389 #include "TVirtualIndex.h"
390 #include "TVirtualPerfStats.h"
391 #include "TVirtualPad.h"
392 #include "TBranchSTL.h"
393 #include "TSchemaRuleSet.h"
394 #include "TFileMergeInfo.h"
395 #include "ROOT/StringConv.hxx"
396 #include "TVirtualMutex.h"
397 
398 #include "TBranchIMTHelper.h"
399 
400 #include <chrono>
401 #include <cstddef>
402 #include <iostream>
403 #include <fstream>
404 #include <sstream>
405 #include <string>
406 #include <stdio.h>
407 #include <limits.h>
408 #include <algorithm>
409 
410 #ifdef R__USE_IMT
411 #include "ROOT/TThreadExecutor.hxx"
412 #include <thread>
413 #include <string>
414 #include <sstream>
415 #endif
416 
417 constexpr Int_t kNEntriesResort = 100;
420 Int_t TTree::fgBranchStyle = 1; // Use new TBranch style with TBranchElement.
421 Long64_t TTree::fgMaxTreeSize = 100000000000LL;
422 
423 ClassImp(TTree);
424 
425 ////////////////////////////////////////////////////////////////////////////////
426 ////////////////////////////////////////////////////////////////////////////////
427 ////////////////////////////////////////////////////////////////////////////////
428 
429 static char DataTypeToChar(EDataType datatype)
430 {
431  // Return the leaflist 'char' for a given datatype.
432 
433  switch(datatype) {
434  case kChar_t: return 'B';
435  case kUChar_t: return 'b';
436  case kBool_t: return 'O';
437  case kShort_t: return 'S';
438  case kUShort_t: return 's';
439  case kCounter:
440  case kInt_t: return 'I';
441  case kUInt_t: return 'i';
442  case kDouble_t:
443  case kDouble32_t: return 'D';
444  case kFloat_t:
445  case kFloat16_t: return 'F';
446  case kLong_t: return 0; // unsupported
447  case kULong_t: return 0; // unsupported?
448  case kchar: return 0; // unsupported
449  case kLong64_t: return 'L';
450  case kULong64_t: return 'l';
451 
452  case kCharStar: return 'C';
453  case kBits: return 0; //unsupported
454 
455  case kOther_t:
456  case kNoType_t:
457  default:
458  return 0;
459  }
460  return 0;
461 }
462 
463 ////////////////////////////////////////////////////////////////////////////////
464 /// \class TTree::TFriendLock
465 /// Helper class to prevent infinite recursion in the usage of TTree Friends.
466 
467 ////////////////////////////////////////////////////////////////////////////////
468 /// Record in tree that it has been used while recursively looks through the friends.
469 
471 : fTree(tree)
472 {
473  // We could also add some code to acquire an actual
474  // lock to prevent multi-thread issues
475  fMethodBit = methodbit;
476  if (fTree) {
477  fPrevious = fTree->fFriendLockStatus & fMethodBit;
478  fTree->fFriendLockStatus |= fMethodBit;
479  } else {
480  fPrevious = 0;
481  }
482 }
483 
484 ////////////////////////////////////////////////////////////////////////////////
485 /// Copy constructor.
486 
488  fTree(tfl.fTree),
489  fMethodBit(tfl.fMethodBit),
490  fPrevious(tfl.fPrevious)
491 {
492 }
493 
494 ////////////////////////////////////////////////////////////////////////////////
495 /// Assignment operator.
496 
498 {
499  if(this!=&tfl) {
500  fTree=tfl.fTree;
502  fPrevious=tfl.fPrevious;
503  }
504  return *this;
505 }
506 
507 ////////////////////////////////////////////////////////////////////////////////
508 /// Restore the state of tree the same as before we set the lock.
509 
511 {
512  if (fTree) {
513  if (!fPrevious) {
515  }
516  }
517 }
518 
519 ////////////////////////////////////////////////////////////////////////////////
520 /// \class TTree::TClusterIterator
521 /// Helper class to iterate over cluster of baskets.
522 
523 ////////////////////////////////////////////////////////////////////////////////
524 /// Regular constructor.
525 /// TTree is not set as const, since we might modify if it is a TChain.
526 
527 TTree::TClusterIterator::TClusterIterator(TTree *tree, Long64_t firstEntry) : fTree(tree), fClusterRange(0), fStartEntry(0), fNextEntry(0)
528 {
529  if ( fTree->GetAutoFlush() <= 0 ) {
530  // Case of old files before November 9 2009
531  fStartEntry = firstEntry;
532  } else if (fTree->fNClusterRange) {
533  // Find the correct cluster range.
534  //
535  // Since fClusterRangeEnd contains the inclusive upper end of the range, we need to search for the
536  // range that was containing the previous entry and add 1 (because BinarySearch consider the values
537  // to be the inclusive start of the bucket).
538  fClusterRange = TMath::BinarySearch(fTree->fNClusterRange, fTree->fClusterRangeEnd, firstEntry - 1) + 1;
539 
540  Long64_t entryInRange;
541  Long64_t pedestal;
542  if (fClusterRange == 0) {
543  pedestal = 0;
544  entryInRange = firstEntry;
545  } else {
546  pedestal = fTree->fClusterRangeEnd[fClusterRange-1] + 1;
547  entryInRange = firstEntry - pedestal;
548  }
549  Long64_t autoflush;
550  if (fClusterRange == fTree->fNClusterRange) {
551  autoflush = fTree->fAutoFlush;
552  } else {
553  autoflush = fTree->fClusterSize[fClusterRange];
554  }
555  if (autoflush == 0) {
556  autoflush = GetEstimatedClusterSize();
557  }
558  fStartEntry = pedestal + entryInRange - entryInRange%autoflush;
559  } else {
560  fStartEntry = firstEntry - firstEntry%fTree->GetAutoFlush();
561  }
562  fNextEntry = fStartEntry; // Position correctly for the first call to Next()
563 }
564 
565 ////////////////////////////////////////////////////////////////////////////////
566 /// In the case where the cluster size was not fixed (old files and
567 /// case where autoflush was explicitly set to zero, we need estimate
568 /// a cluster size in relation to the size of the cache.
569 
571 {
572  Long64_t zipBytes = fTree->GetZipBytes();
573  if (zipBytes == 0) {
574  return fTree->GetEntries() - 1;
575  } else {
576  Long64_t clusterEstimate = 1;
577  Long64_t cacheSize = fTree->GetCacheSize();
578  if (cacheSize == 0) {
579  // Humm ... let's double check on the file.
581  if (file) {
582  TFileCacheRead *cache = file->GetCacheRead(fTree);
583  if (cache) {
584  cacheSize = cache->GetBufferSize();
585  }
586  }
587  }
588  if (cacheSize > 0) {
589  clusterEstimate = fTree->GetEntries() * cacheSize / zipBytes;
590  if (clusterEstimate == 0)
591  clusterEstimate = 1;
592  }
593  return clusterEstimate;
594  }
595 }
596 
597 ////////////////////////////////////////////////////////////////////////////////
598 /// Move on to the next cluster and return the starting entry
599 /// of this next cluster
600 
602 {
603  fStartEntry = fNextEntry;
604  if ( fTree->GetAutoFlush() <= 0 ) {
605  // Case of old files before November 9 2009
606  Long64_t clusterEstimate = GetEstimatedClusterSize();
607  fNextEntry = fStartEntry + clusterEstimate;
608  } else {
609  if (fClusterRange == fTree->fNClusterRange) {
610  // We are looking at a range which size
611  // is defined by AutoFlush itself and goes to the GetEntries.
612  fNextEntry += fTree->GetAutoFlush();
613  } else {
614  if (fStartEntry > fTree->fClusterRangeEnd[fClusterRange]) {
615  ++fClusterRange;
616  }
617  if (fClusterRange == fTree->fNClusterRange) {
618  // We are looking at the last range which size
619  // is defined by AutoFlush itself and goes to the GetEntries.
620  fNextEntry += fTree->GetAutoFlush();
621  } else {
622  Long64_t clusterSize = fTree->fClusterSize[fClusterRange];
623  if (clusterSize == 0) {
624  clusterSize = GetEstimatedClusterSize();
625  }
626  fNextEntry += clusterSize;
627  if (fNextEntry > fTree->fClusterRangeEnd[fClusterRange]) {
628  // The last cluster of the range was a partial cluster,
629  // so the next cluster starts at the beginning of the
630  // next range.
631  fNextEntry = fTree->fClusterRangeEnd[fClusterRange] + 1;
632  }
633  }
634  }
635  }
636  if (fNextEntry > fTree->GetEntries()) {
637  fNextEntry = fTree->GetEntries();
638  }
639  return fStartEntry;
640 }
641 
642 ////////////////////////////////////////////////////////////////////////////////
643 /// Move on to the previous cluster and return the starting entry
644 /// of this previous cluster
645 
647 {
648  fNextEntry = fStartEntry;
649  if (fTree->GetAutoFlush() <= 0) {
650  // Case of old files before November 9 2009
651  Long64_t clusterEstimate = GetEstimatedClusterSize();
652  fStartEntry = fNextEntry - clusterEstimate;
653  } else {
654  if (fClusterRange == 0 || fTree->fNClusterRange == 0) {
655  // We are looking at a range which size
656  // is defined by AutoFlush itself.
657  fStartEntry -= fTree->GetAutoFlush();
658  } else {
659  if (fNextEntry <= fTree->fClusterRangeEnd[fClusterRange]) {
660  --fClusterRange;
661  }
662  if (fClusterRange == 0) {
663  // We are looking at the first range.
664  fStartEntry = 0;
665  } else {
666  Long64_t clusterSize = fTree->fClusterSize[fClusterRange];
667  if (clusterSize == 0) {
668  clusterSize = GetEstimatedClusterSize();
669  }
670  fStartEntry -= clusterSize;
671  }
672  }
673  }
674  if (fStartEntry < 0) {
675  fStartEntry = 0;
676  }
677  return fStartEntry;
678 }
679 
680 ////////////////////////////////////////////////////////////////////////////////
681 ////////////////////////////////////////////////////////////////////////////////
682 ////////////////////////////////////////////////////////////////////////////////
683 
684 ////////////////////////////////////////////////////////////////////////////////
685 /// Default constructor and I/O constructor.
686 ///
687 /// Note: We do *not* insert ourself into the current directory.
688 ///
689 
690 TTree::TTree()
692 , TAttLine()
693 , TAttFill()
694 , TAttMarker()
695 , fEntries(0)
696 , fTotBytes(0)
697 , fZipBytes(0)
698 , fSavedBytes(0)
699 , fFlushedBytes(0)
700 , fWeight(1)
701 , fTimerInterval(0)
702 , fScanField(25)
703 , fUpdate(0)
705 , fNClusterRange(0)
706 , fMaxClusterRange(0)
707 , fMaxEntries(0)
708 , fMaxEntryLoop(0)
709 , fMaxVirtualSize(0)
710 , fAutoSave( -300000000)
711 , fAutoFlush(-30000000)
712 , fEstimate(1000000)
713 , fClusterRangeEnd(0)
714 , fClusterSize(0)
715 , fCacheSize(0)
716 , fChainOffset(0)
717 , fReadEntry(-1)
718 , fTotalBuffers(0)
719 , fPacketSize(100)
720 , fNfill(0)
721 , fDebug(0)
722 , fDebugMin(0)
723 , fDebugMax(9999999)
724 , fMakeClass(0)
725 , fFileNumber(0)
726 , fNotify(0)
727 , fDirectory(0)
728 , fBranches()
729 , fLeaves()
730 , fAliases(0)
731 , fEventList(0)
732 , fEntryList(0)
733 , fIndexValues()
734 , fIndex()
735 , fTreeIndex(0)
736 , fFriends(0)
737 , fPerfStats(0)
738 , fUserInfo(0)
739 , fPlayer(0)
740 , fClones(0)
741 , fBranchRef(0)
743 , fTransientBuffer(0)
749 {
750  fMaxEntries = 1000000000;
751  fMaxEntries *= 1000;
752 
753  fMaxEntryLoop = 1000000000;
754  fMaxEntryLoop *= 1000;
755 
757 }
758 
759 ////////////////////////////////////////////////////////////////////////////////
760 /// Normal tree constructor.
761 ///
762 /// The tree is created in the current directory.
763 /// Use the various functions Branch below to add branches to this tree.
764 ///
765 /// If the first character of title is a "/", the function assumes a folder name.
766 /// In this case, it creates automatically branches following the folder hierarchy.
767 /// splitlevel may be used in this case to control the split level.
768 
769 TTree::TTree(const char* name, const char* title, Int_t splitlevel /* = 99 */,
770  TDirectory* dir /* = gDirectory*/)
771 : TNamed(name, title)
772 , TAttLine()
773 , TAttFill()
774 , TAttMarker()
775 , fEntries(0)
776 , fTotBytes(0)
777 , fZipBytes(0)
778 , fSavedBytes(0)
779 , fFlushedBytes(0)
780 , fWeight(1)
781 , fTimerInterval(0)
782 , fScanField(25)
783 , fUpdate(0)
785 , fNClusterRange(0)
786 , fMaxClusterRange(0)
787 , fMaxEntries(0)
788 , fMaxEntryLoop(0)
789 , fMaxVirtualSize(0)
790 , fAutoSave( -300000000)
791 , fAutoFlush(-30000000)
792 , fEstimate(1000000)
793 , fClusterRangeEnd(0)
794 , fClusterSize(0)
795 , fCacheSize(0)
796 , fChainOffset(0)
797 , fReadEntry(-1)
798 , fTotalBuffers(0)
799 , fPacketSize(100)
800 , fNfill(0)
801 , fDebug(0)
802 , fDebugMin(0)
803 , fDebugMax(9999999)
804 , fMakeClass(0)
805 , fFileNumber(0)
806 , fNotify(0)
807 , fDirectory(dir)
808 , fBranches()
809 , fLeaves()
810 , fAliases(0)
811 , fEventList(0)
812 , fEntryList(0)
813 , fIndexValues()
814 , fIndex()
815 , fTreeIndex(0)
816 , fFriends(0)
817 , fPerfStats(0)
818 , fUserInfo(0)
819 , fPlayer(0)
820 , fClones(0)
821 , fBranchRef(0)
823 , fTransientBuffer(0)
829 {
830  // TAttLine state.
834 
835  // TAttFill state.
838 
839  // TAttMarkerState.
843 
844  fMaxEntries = 1000000000;
845  fMaxEntries *= 1000;
846 
847  fMaxEntryLoop = 1000000000;
848  fMaxEntryLoop *= 1000;
849 
850  // Insert ourself into the current directory.
851  // FIXME: This is very annoying behaviour, we should
852  // be able to choose to not do this like we
853  // can with a histogram.
854  if (fDirectory) fDirectory->Append(this);
855 
857 
858  // If title starts with "/" and is a valid folder name, a superbranch
859  // is created.
860  // FIXME: Why?
861  if (strlen(title) > 2) {
862  if (title[0] == '/') {
863  Branch(title+1,32000,splitlevel);
864  }
865  }
866 }
867 
868 ////////////////////////////////////////////////////////////////////////////////
869 /// Destructor.
870 
872 {
873  if (fDirectory) {
874  // We are in a directory, which may possibly be a file.
875  if (fDirectory->GetList()) {
876  // Remove us from the directory listing.
877  fDirectory->Remove(this);
878  }
879  //delete the file cache if it points to this Tree
881  MoveReadCache(file,0);
882  }
883  // We don't own the leaves in fLeaves, the branches do.
884  fLeaves.Clear();
885  // I'm ready to destroy any objects allocated by
886  // SetAddress() by my branches. If I have clones,
887  // tell them to zero their pointers to this shared
888  // memory.
889  if (fClones && fClones->GetEntries()) {
890  // I have clones.
891  // I am about to delete the objects created by
892  // SetAddress() which we are sharing, so tell
893  // the clones to release their pointers to them.
894  for (TObjLink* lnk = fClones->FirstLink(); lnk; lnk = lnk->Next()) {
895  TTree* clone = (TTree*) lnk->GetObject();
896  // clone->ResetBranchAddresses();
897 
898  // Reset only the branch we have set the address of.
899  CopyAddresses(clone,kTRUE);
900  }
901  }
902  // Get rid of our branches, note that this will also release
903  // any memory allocated by TBranchElement::SetAddress().
904  fBranches.Delete();
905  // FIXME: We must consider what to do with the reset of these if we are a clone.
906  delete fPlayer;
907  fPlayer = 0;
908  if (fFriends) {
909  fFriends->Delete();
910  delete fFriends;
911  fFriends = 0;
912  }
913  if (fAliases) {
914  fAliases->Delete();
915  delete fAliases;
916  fAliases = 0;
917  }
918  if (fUserInfo) {
919  fUserInfo->Delete();
920  delete fUserInfo;
921  fUserInfo = 0;
922  }
923  if (fClones) {
924  // Clone trees should no longer be removed from fClones when they are deleted.
925  {
927  gROOT->GetListOfCleanups()->Remove(fClones);
928  }
929  // Note: fClones does not own its content.
930  delete fClones;
931  fClones = 0;
932  }
933  if (fEntryList) {
935  // Delete the entry list if it is marked to be deleted and it is not also
936  // owned by a directory. (Otherwise we would need to make sure that a
937  // TDirectoryFile that has a TTree in it does a 'slow' TList::Delete.
938  delete fEntryList;
939  fEntryList=0;
940  }
941  }
942  delete fTreeIndex;
943  fTreeIndex = 0;
944  delete fBranchRef;
945  fBranchRef = 0;
946  delete [] fClusterRangeEnd;
947  fClusterRangeEnd = 0;
948  delete [] fClusterSize;
949  fClusterSize = 0;
950  // Must be done after the destruction of friends.
951  // Note: We do *not* own our directory.
952  fDirectory = 0;
953 
954  if (fTransientBuffer) {
955  delete fTransientBuffer;
956  fTransientBuffer = 0;
957  }
958 }
959 
960 ////////////////////////////////////////////////////////////////////////////////
961 /// Returns the transient buffer currently used by this TTree for reading/writing baskets.
962 
964 {
965  if (fTransientBuffer) {
966  if (fTransientBuffer->BufferSize() < size) {
967  fTransientBuffer->Expand(size);
968  }
969  return fTransientBuffer;
970  }
972  return fTransientBuffer;
973 }
974 
975 ////////////////////////////////////////////////////////////////////////////////
976 /// Add branch with name bname to the Tree cache.
977 /// If bname="*" all branches are added to the cache.
978 /// if subbranches is true all the branches of the subbranches are
979 /// also put to the cache.
980 ///
981 /// Returns:
982 /// - 0 branch added or already included
983 /// - -1 on error
984 
985 Int_t TTree::AddBranchToCache(const char*bname, Bool_t subbranches)
986 {
987  if (!GetTree()) {
988  if (LoadTree(0)<0) {
989  Error("AddBranchToCache","Could not load a tree");
990  return -1;
991  }
992  }
993  if (GetTree()) {
994  if (GetTree() != this) {
995  return GetTree()->AddBranchToCache(bname, subbranches);
996  }
997  } else {
998  Error("AddBranchToCache", "No tree is available. Branch was not added to the cache");
999  return -1;
1000  }
1001 
1002  TFile *f = GetCurrentFile();
1003  if (!f) {
1004  Error("AddBranchToCache", "No file is available. Branch was not added to the cache");
1005  return -1;
1006  }
1007  TTreeCache *tc = GetReadCache(f,kTRUE);
1008  if (!tc) {
1009  Error("AddBranchToCache", "No cache is available, branch not added");
1010  return -1;
1011  }
1012  return tc->AddBranch(bname,subbranches);
1013 }
1014 
1015 ////////////////////////////////////////////////////////////////////////////////
1016 /// Add branch b to the Tree cache.
1017 /// if subbranches is true all the branches of the subbranches are
1018 /// also put to the cache.
1019 ///
1020 /// Returns:
1021 /// - 0 branch added or already included
1022 /// - -1 on error
1023 
1026  if (!GetTree()) {
1027  if (LoadTree(0)<0) {
1028  Error("AddBranchToCache","Could not load a tree");
1029  return -1;
1030  }
1031  }
1032  if (GetTree()) {
1033  if (GetTree() != this) {
1034  Int_t res = GetTree()->AddBranchToCache(b, subbranches);
1035  if (res<0) {
1036  Error("AddBranchToCache", "Error adding branch");
1037  }
1038  return res;
1039  }
1040  } else {
1041  Error("AddBranchToCache", "No tree is available. Branch was not added to the cache");
1042  return -1;
1043  }
1044 
1045  TFile *f = GetCurrentFile();
1046  if (!f) {
1047  Error("AddBranchToCache", "No file is available. Branch was not added to the cache");
1048  return -1;
1049  }
1050  TTreeCache *tc = GetReadCache(f,kTRUE);
1051  if (!tc) {
1052  Error("AddBranchToCache", "No cache is available, branch not added");
1053  return -1;
1054  }
1055  return tc->AddBranch(b,subbranches);
1056 }
1057 
1058 ////////////////////////////////////////////////////////////////////////////////
1059 /// Remove the branch with name 'bname' from the Tree cache.
1060 /// If bname="*" all branches are removed from the cache.
1061 /// if subbranches is true all the branches of the subbranches are
1062 /// also removed from the cache.
1063 ///
1064 /// Returns:
1065 /// - 0 branch dropped or not in cache
1066 /// - -1 on error
1067 
1068 Int_t TTree::DropBranchFromCache(const char*bname, Bool_t subbranches)
1070  if (!GetTree()) {
1071  if (LoadTree(0)<0) {
1072  Error("DropBranchFromCache","Could not load a tree");
1073  return -1;
1074  }
1075  }
1076  if (GetTree()) {
1077  if (GetTree() != this) {
1078  return GetTree()->DropBranchFromCache(bname, subbranches);
1079  }
1080  } else {
1081  Error("DropBranchFromCache", "No tree is available. Branch was not dropped from the cache");
1082  return -1;
1083  }
1084 
1085  TFile *f = GetCurrentFile();
1086  if (!f) {
1087  Error("DropBranchFromCache", "No file is available. Branch was not dropped from the cache");
1088  return -1;
1089  }
1090  TTreeCache *tc = GetReadCache(f,kTRUE);
1091  if (!tc) {
1092  Error("DropBranchFromCache", "No cache is available, branch not dropped");
1093  return -1;
1094  }
1095  return tc->DropBranch(bname,subbranches);
1096 }
1097 
1098 ////////////////////////////////////////////////////////////////////////////////
1099 /// Remove the branch b from the Tree cache.
1100 /// if subbranches is true all the branches of the subbranches are
1101 /// also removed from the cache.
1102 ///
1103 /// Returns:
1104 /// - 0 branch dropped or not in cache
1105 /// - -1 on error
1106 
1109  if (!GetTree()) {
1110  if (LoadTree(0)<0) {
1111  Error("DropBranchFromCache","Could not load a tree");
1112  return -1;
1113  }
1114  }
1115  if (GetTree()) {
1116  if (GetTree() != this) {
1117  Int_t res = GetTree()->DropBranchFromCache(b, subbranches);
1118  if (res<0) {
1119  Error("DropBranchFromCache", "Error dropping branch");
1120  }
1121  return res;
1122  }
1123  } else {
1124  Error("DropBranchFromCache", "No tree is available. Branch was not dropped from the cache");
1125  return -1;
1126  }
1127 
1128  TFile *f = GetCurrentFile();
1129  if (!f) {
1130  Error("DropBranchFromCache", "No file is available. Branch was not dropped from the cache");
1131  return -1;
1132  }
1133  TTreeCache *tc = GetReadCache(f,kTRUE);
1134  if (!tc) {
1135  Error("DropBranchFromCache", "No cache is available, branch not dropped");
1136  return -1;
1137  }
1138  return tc->DropBranch(b,subbranches);
1139 }
1140 
1141 ////////////////////////////////////////////////////////////////////////////////
1142 /// Add a cloned tree to our list of trees to be notified whenever we change
1143 /// our branch addresses or when we are deleted.
1144 
1145 void TTree::AddClone(TTree* clone)
1147  if (!fClones) {
1148  fClones = new TList();
1149  fClones->SetOwner(false);
1150  // So that the clones are automatically removed from the list when
1151  // they are deleted.
1152  {
1154  gROOT->GetListOfCleanups()->Add(fClones);
1155  }
1156  }
1157  if (!fClones->FindObject(clone)) {
1158  fClones->Add(clone);
1159  }
1160 }
1161 
1162 ////////////////////////////////////////////////////////////////////////////////
1163 /// Add a TFriendElement to the list of friends.
1164 ///
1165 /// This function:
1166 /// - opens a file if filename is specified
1167 /// - reads a Tree with name treename from the file (current directory)
1168 /// - adds the Tree to the list of friends
1169 /// see other AddFriend functions
1170 ///
1171 /// A TFriendElement TF describes a TTree object TF in a file.
1172 /// When a TFriendElement TF is added to the the list of friends of an
1173 /// existing TTree T, any variable from TF can be referenced in a query
1174 /// to T.
1175 ///
1176 /// A tree keeps a list of friends. In the context of a tree (or a chain),
1177 /// friendship means unrestricted access to the friends data. In this way
1178 /// it is much like adding another branch to the tree without taking the risk
1179 /// of damaging it. To add a friend to the list, you can use the TTree::AddFriend
1180 /// method. The tree in the diagram below has two friends (friend_tree1 and
1181 /// friend_tree2) and now has access to the variables a,b,c,i,j,k,l and m.
1182 ///
1183 /// \image html ttree_friend1.png
1184 ///
1185 /// The AddFriend method has two parameters, the first is the tree name and the
1186 /// second is the name of the ROOT file where the friend tree is saved.
1187 /// AddFriend automatically opens the friend file. If no file name is given,
1188 /// the tree called ft1 is assumed to be in the same file as the original tree.
1189 ///
1190 /// tree.AddFriend("ft1","friendfile1.root");
1191 /// If the friend tree has the same name as the original tree, you can give it
1192 /// an alias in the context of the friendship:
1193 ///
1194 /// tree.AddFriend("tree1 = tree","friendfile1.root");
1195 /// Once the tree has friends, we can use TTree::Draw as if the friend's
1196 /// variables were in the original tree. To specify which tree to use in
1197 /// the Draw method, use the syntax:
1198 /// ~~~ {.cpp}
1199 /// <treeName>.<branchname>.<varname>
1200 /// ~~~
1201 /// If the variablename is enough to uniquely identify the variable, you can
1202 /// leave out the tree and/or branch name.
1203 /// For example, these commands generate a 3-d scatter plot of variable "var"
1204 /// in the TTree tree versus variable v1 in TTree ft1 versus variable v2 in
1205 /// TTree ft2.
1206 /// ~~~ {.cpp}
1207 /// tree.AddFriend("ft1","friendfile1.root");
1208 /// tree.AddFriend("ft2","friendfile2.root");
1209 /// tree.Draw("var:ft1.v1:ft2.v2");
1210 /// ~~~
1211 /// \image html ttree_friend2.png
1212 ///
1213 /// The picture illustrates the access of the tree and its friends with a
1214 /// Draw command.
1215 /// When AddFriend is called, the ROOT file is automatically opened and the
1216 /// friend tree (ft1) is read into memory. The new friend (ft1) is added to
1217 /// the list of friends of tree.
1218 /// The number of entries in the friend must be equal or greater to the number
1219 /// of entries of the original tree. If the friend tree has fewer entries a
1220 /// warning is given and the missing entries are not included in the histogram.
1221 /// To retrieve the list of friends from a tree use TTree::GetListOfFriends.
1222 /// When the tree is written to file (TTree::Write), the friends list is saved
1223 /// with it. And when the tree is retrieved, the trees on the friends list are
1224 /// also retrieved and the friendship restored.
1225 /// When a tree is deleted, the elements of the friend list are also deleted.
1226 /// It is possible to declare a friend tree that has the same internal
1227 /// structure (same branches and leaves) as the original tree, and compare the
1228 /// same values by specifying the tree.
1229 /// ~~~ {.cpp}
1230 /// tree.Draw("var:ft1.var:ft2.var")
1231 /// ~~~
1232 
1233 TFriendElement* TTree::AddFriend(const char* treename, const char* filename)
1235  if (!fFriends) {
1236  fFriends = new TList();
1237  }
1238  TFriendElement* fe = new TFriendElement(this, treename, filename);
1239 
1240  fFriends->Add(fe);
1241  TTree* t = fe->GetTree();
1242  if (t) {
1243  if (!t->GetTreeIndex() && (t->GetEntries() < fEntries)) {
1244  Warning("AddFriend", "FriendElement %s in file %s has less entries %lld than its parent Tree: %lld", treename, filename, t->GetEntries(), fEntries);
1245  }
1246  } else {
1247  Warning("AddFriend", "Cannot add FriendElement %s in file %s", treename, filename);
1248  }
1249  return fe;
1250 }
1251 
1252 ////////////////////////////////////////////////////////////////////////////////
1253 /// Add a TFriendElement to the list of friends.
1254 ///
1255 /// The TFile is managed by the user (e.g. the user must delete the file).
1256 /// For complete description see AddFriend(const char *, const char *).
1257 /// This function:
1258 /// - reads a Tree with name treename from the file
1259 /// - adds the Tree to the list of friends
1260 
1261 TFriendElement* TTree::AddFriend(const char* treename, TFile* file)
1263  if (!fFriends) {
1264  fFriends = new TList();
1265  }
1266  TFriendElement *fe = new TFriendElement(this, treename, file);
1267  R__ASSERT(fe);
1268  fFriends->Add(fe);
1269  TTree *t = fe->GetTree();
1270  if (t) {
1271  if (!t->GetTreeIndex() && (t->GetEntries() < fEntries)) {
1272  Warning("AddFriend", "FriendElement %s in file %s has less entries %lld than its parent tree: %lld", treename, file->GetName(), t->GetEntries(), fEntries);
1273  }
1274  } else {
1275  Warning("AddFriend", "unknown tree '%s' in file '%s'", treename, file->GetName());
1276  }
1277  return fe;
1278 }
1279 
1280 ////////////////////////////////////////////////////////////////////////////////
1281 /// Add a TFriendElement to the list of friends.
1282 ///
1283 /// The TTree is managed by the user (e.g., the user must delete the file).
1284 /// For a complete description see AddFriend(const char *, const char *).
1285 
1286 TFriendElement* TTree::AddFriend(TTree* tree, const char* alias, Bool_t warn)
1288  if (!tree) {
1289  return 0;
1290  }
1291  if (!fFriends) {
1292  fFriends = new TList();
1293  }
1294  TFriendElement* fe = new TFriendElement(this, tree, alias);
1295  R__ASSERT(fe); // this assert is for historical reasons. Don't remove it unless you understand all the consequences.
1296  fFriends->Add(fe);
1297  TTree* t = fe->GetTree();
1298  if (warn && (t->GetEntries() < fEntries)) {
1299  Warning("AddFriend", "FriendElement '%s' in file '%s' has less entries %lld than its parent tree: %lld",
1300  tree->GetName(), fe->GetFile() ? fe->GetFile()->GetName() : "(memory resident)", t->GetEntries(), fEntries);
1301  }
1302  return fe;
1303 }
1304 
1305 ////////////////////////////////////////////////////////////////////////////////
1306 /// AutoSave tree header every fAutoSave bytes.
1307 ///
1308 /// When large Trees are produced, it is safe to activate the AutoSave
1309 /// procedure. Some branches may have buffers holding many entries.
1310 /// If fAutoSave is negative, AutoSave is automatically called by
1311 /// TTree::Fill when the number of bytes generated since the previous
1312 /// AutoSave is greater than -fAutoSave bytes.
1313 /// If fAutoSave is positive, AutoSave is automatically called by
1314 /// TTree::Fill every N entries.
1315 /// This function may also be invoked by the user.
1316 /// Each AutoSave generates a new key on the file.
1317 /// Once the key with the tree header has been written, the previous cycle
1318 /// (if any) is deleted.
1319 ///
1320 /// Note that calling TTree::AutoSave too frequently (or similarly calling
1321 /// TTree::SetAutoSave with a small value) is an expensive operation.
1322 /// You should make tests for your own application to find a compromise
1323 /// between speed and the quantity of information you may loose in case of
1324 /// a job crash.
1325 ///
1326 /// In case your program crashes before closing the file holding this tree,
1327 /// the file will be automatically recovered when you will connect the file
1328 /// in UPDATE mode.
1329 /// The Tree will be recovered at the status corresponding to the last AutoSave.
1330 ///
1331 /// if option contains "SaveSelf", gDirectory->SaveSelf() is called.
1332 /// This allows another process to analyze the Tree while the Tree is being filled.
1333 ///
1334 /// if option contains "FlushBaskets", TTree::FlushBaskets is called and all
1335 /// the current basket are closed-out and written to disk individually.
1336 ///
1337 /// By default the previous header is deleted after having written the new header.
1338 /// if option contains "Overwrite", the previous Tree header is deleted
1339 /// before written the new header. This option is slightly faster, but
1340 /// the default option is safer in case of a problem (disk quota exceeded)
1341 /// when writing the new header.
1342 ///
1343 /// The function returns the number of bytes written to the file.
1344 /// if the number of bytes is null, an error has occurred while writing
1345 /// the header to the file.
1346 ///
1347 /// ## How to write a Tree in one process and view it from another process
1348 ///
1349 /// The following two scripts illustrate how to do this.
1350 /// The script treew.C is executed by process1, treer.C by process2
1351 ///
1352 /// script treew.C:
1353 /// ~~~ {.cpp}
1354 /// void treew() {
1355 /// TFile f("test.root","recreate");
1356 /// TNtuple *ntuple = new TNtuple("ntuple","Demo","px:py:pz:random:i");
1357 /// Float_t px, py, pz;
1358 /// for ( Int_t i=0; i<10000000; i++) {
1359 /// gRandom->Rannor(px,py);
1360 /// pz = px*px + py*py;
1361 /// Float_t random = gRandom->Rndm(1);
1362 /// ntuple->Fill(px,py,pz,random,i);
1363 /// if (i%1000 == 1) ntuple->AutoSave("SaveSelf");
1364 /// }
1365 /// }
1366 /// ~~~
1367 /// script treer.C:
1368 /// ~~~ {.cpp}
1369 /// void treer() {
1370 /// TFile f("test.root");
1371 /// TTree *ntuple = (TTree*)f.Get("ntuple");
1372 /// TCanvas c1;
1373 /// Int_t first = 0;
1374 /// while(1) {
1375 /// if (first == 0) ntuple->Draw("px>>hpx", "","",10000000,first);
1376 /// else ntuple->Draw("px>>+hpx","","",10000000,first);
1377 /// first = (Int_t)ntuple->GetEntries();
1378 /// c1.Update();
1379 /// gSystem->Sleep(1000); //sleep 1 second
1380 /// ntuple->Refresh();
1381 /// }
1382 /// }
1383 /// ~~~
1384 
1387  if (!fDirectory || fDirectory == gROOT || !fDirectory->IsWritable()) return 0;
1388  if (gDebug > 0) {
1389  Info("AutoSave", "Tree:%s after %lld bytes written\n",GetName(),GetTotBytes());
1390  }
1391  TString opt = option;
1392  opt.ToLower();
1393 
1394  if (opt.Contains("flushbaskets")) {
1395  if (gDebug > 0) Info("AutoSave", "calling FlushBaskets \n");
1396  FlushBaskets();
1397  }
1398 
1400 
1402  Long64_t nbytes;
1403  if (opt.Contains("overwrite")) {
1404  nbytes = fDirectory->WriteTObject(this,"","overwrite");
1405  } else {
1406  nbytes = fDirectory->WriteTObject(this); //nbytes will be 0 if Write failed (disk space exceeded)
1407  if (nbytes && key) {
1408  key->Delete();
1409  delete key;
1410  }
1411  }
1412  // save StreamerInfo
1413  TFile *file = fDirectory->GetFile();
1414  if (file) file->WriteStreamerInfo();
1415 
1416  if (opt.Contains("saveself")) {
1417  fDirectory->SaveSelf();
1418  //the following line is required in case GetUserInfo contains a user class
1419  //for which the StreamerInfo must be written. One could probably be a bit faster (Rene)
1420  if (file) file->WriteHeader();
1421  }
1422 
1423  return nbytes;
1424 }
1425 
1426 namespace {
1427  // This error message is repeated several times in the code. We write it once.
1428  const char* writeStlWithoutProxyMsg = "The class requested (%s) for the branch \"%s\""
1429  " is an instance of an stl collection and does not have a compiled CollectionProxy."
1430  " Please generate the dictionary for this collection (%s) to avoid to write corrupted data.";
1431 }
1432 
1433 ////////////////////////////////////////////////////////////////////////////////
1434 /// Same as TTree::Branch() with added check that addobj matches className.
1435 ///
1436 /// See TTree::Branch() for other details.
1437 ///
1438 
1439 TBranch* TTree::BranchImp(const char* branchname, const char* classname, TClass* ptrClass, void* addobj, Int_t bufsize, Int_t splitlevel)
1441  TClass* claim = TClass::GetClass(classname);
1442  if (!ptrClass) {
1443  if (claim && claim->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(claim->GetCollectionProxy())) {
1444  Error("Branch", writeStlWithoutProxyMsg,
1445  claim->GetName(), branchname, claim->GetName());
1446  return 0;
1447  }
1448  return Branch(branchname, classname, (void*) addobj, bufsize, splitlevel);
1449  }
1450  TClass* actualClass = 0;
1451  void** addr = (void**) addobj;
1452  if (addr) {
1453  actualClass = ptrClass->GetActualClass(*addr);
1454  }
1455  if (ptrClass && claim) {
1456  if (!(claim->InheritsFrom(ptrClass) || ptrClass->InheritsFrom(claim))) {
1457  // Note we currently do not warn in case of splicing or over-expectation).
1458  if (claim->IsLoaded() && ptrClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), ptrClass->GetTypeInfo()->name() ) == 0) {
1459  // The type is the same according to the C++ type_info, we must be in the case of
1460  // a template of Double32_t. This is actually a correct case.
1461  } else {
1462  Error("Branch", "The class requested (%s) for \"%s\" is different from the type of the pointer passed (%s)",
1463  claim->GetName(), branchname, ptrClass->GetName());
1464  }
1465  } else if (actualClass && (claim != actualClass) && !actualClass->InheritsFrom(claim)) {
1466  if (claim->IsLoaded() && actualClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), actualClass->GetTypeInfo()->name() ) == 0) {
1467  // The type is the same according to the C++ type_info, we must be in the case of
1468  // a template of Double32_t. This is actually a correct case.
1469  } else {
1470  Error("Branch", "The actual class (%s) of the object provided for the definition of the branch \"%s\" does not inherit from %s",
1471  actualClass->GetName(), branchname, claim->GetName());
1472  }
1473  }
1474  }
1475  if (claim && claim->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(claim->GetCollectionProxy())) {
1476  Error("Branch", writeStlWithoutProxyMsg,
1477  claim->GetName(), branchname, claim->GetName());
1478  return 0;
1479  }
1480  return Branch(branchname, classname, (void*) addobj, bufsize, splitlevel);
1481 }
1482 
1483 ////////////////////////////////////////////////////////////////////////////////
1484 /// Same as TTree::Branch but automatic detection of the class name.
1485 /// See TTree::Branch for other details.
1486 
1487 TBranch* TTree::BranchImp(const char* branchname, TClass* ptrClass, void* addobj, Int_t bufsize, Int_t splitlevel)
1489  if (!ptrClass) {
1490  Error("Branch", "The pointer specified for %s is not of a class known to ROOT", branchname);
1491  return 0;
1492  }
1493  TClass* actualClass = 0;
1494  void** addr = (void**) addobj;
1495  if (addr && *addr) {
1496  actualClass = ptrClass->GetActualClass(*addr);
1497  if (!actualClass) {
1498  Warning("Branch", "The actual TClass corresponding to the object provided for the definition of the branch \"%s\" is missing.\n\tThe object will be truncated down to its %s part",
1499  branchname, ptrClass->GetName());
1500  actualClass = ptrClass;
1501  } else if ((ptrClass != actualClass) && !actualClass->InheritsFrom(ptrClass)) {
1502  Error("Branch", "The actual class (%s) of the object provided for the definition of the branch \"%s\" does not inherit from %s", actualClass->GetName(), branchname, ptrClass->GetName());
1503  return 0;
1504  }
1505  } else {
1506  actualClass = ptrClass;
1507  }
1508  if (actualClass && actualClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(actualClass->GetCollectionProxy())) {
1509  Error("Branch", writeStlWithoutProxyMsg,
1510  actualClass->GetName(), branchname, actualClass->GetName());
1511  return 0;
1512  }
1513  return Branch(branchname, actualClass->GetName(), (void*) addobj, bufsize, splitlevel);
1514 }
1515 
1516 ////////////////////////////////////////////////////////////////////////////////
1517 /// Same as TTree::Branch but automatic detection of the class name.
1518 /// See TTree::Branch for other details.
1519 
1520 TBranch* TTree::BranchImpRef(const char* branchname, const char *classname, TClass* ptrClass, void *addobj, Int_t bufsize, Int_t splitlevel)
1522  TClass* claim = TClass::GetClass(classname);
1523  if (!ptrClass) {
1524  if (claim && claim->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(claim->GetCollectionProxy())) {
1525  Error("Branch", writeStlWithoutProxyMsg,
1526  claim->GetName(), branchname, claim->GetName());
1527  return 0;
1528  } else if (claim == 0) {
1529  Error("Branch", "The pointer specified for %s is not of a class known to ROOT and %s is not a known class", branchname, classname);
1530  return 0;
1531  }
1532  ptrClass = claim;
1533  }
1534  TClass* actualClass = 0;
1535  if (!addobj) {
1536  Error("Branch", "Reference interface requires a valid object (for branch: %s)!", branchname);
1537  return 0;
1538  }
1539  actualClass = ptrClass->GetActualClass(addobj);
1540  if (ptrClass && claim) {
1541  if (!(claim->InheritsFrom(ptrClass) || ptrClass->InheritsFrom(claim))) {
1542  // Note we currently do not warn in case of splicing or over-expectation).
1543  if (claim->IsLoaded() && ptrClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), ptrClass->GetTypeInfo()->name() ) == 0) {
1544  // The type is the same according to the C++ type_info, we must be in the case of
1545  // a template of Double32_t. This is actually a correct case.
1546  } else {
1547  Error("Branch", "The class requested (%s) for \"%s\" is different from the type of the object passed (%s)",
1548  claim->GetName(), branchname, ptrClass->GetName());
1549  }
1550  } else if (actualClass && (claim != actualClass) && !actualClass->InheritsFrom(claim)) {
1551  if (claim->IsLoaded() && actualClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), actualClass->GetTypeInfo()->name() ) == 0) {
1552  // The type is the same according to the C++ type_info, we must be in the case of
1553  // a template of Double32_t. This is actually a correct case.
1554  } else {
1555  Error("Branch", "The actual class (%s) of the object provided for the definition of the branch \"%s\" does not inherit from %s",
1556  actualClass->GetName(), branchname, claim->GetName());
1557  }
1558  }
1559  }
1560  if (!actualClass) {
1561  Warning("Branch", "The actual TClass corresponding to the object provided for the definition of the branch \"%s\" is missing.\n\tThe object will be truncated down to its %s part",
1562  branchname, ptrClass->GetName());
1563  actualClass = ptrClass;
1564  } else if ((ptrClass != actualClass) && !actualClass->InheritsFrom(ptrClass)) {
1565  Error("Branch", "The actual class (%s) of the object provided for the definition of the branch \"%s\" does not inherit from %s", actualClass->GetName(), branchname, ptrClass->GetName());
1566  return 0;
1567  }
1568  if (actualClass && actualClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(actualClass->GetCollectionProxy())) {
1569  Error("Branch", writeStlWithoutProxyMsg,
1570  actualClass->GetName(), branchname, actualClass->GetName());
1571  return 0;
1572  }
1573  return BronchExec(branchname, actualClass->GetName(), (void*) addobj, kFALSE, bufsize, splitlevel);
1574 }
1575 
1576 ////////////////////////////////////////////////////////////////////////////////
1577 /// Same as TTree::Branch but automatic detection of the class name.
1578 /// See TTree::Branch for other details.
1579 
1580 TBranch* TTree::BranchImpRef(const char* branchname, TClass* ptrClass, EDataType datatype, void* addobj, Int_t bufsize, Int_t splitlevel)
1582  if (!ptrClass) {
1583  if (datatype == kOther_t || datatype == kNoType_t) {
1584  Error("Branch", "The pointer specified for %s is not of a class or type known to ROOT", branchname);
1585  } else {
1586  TString varname; varname.Form("%s/%c",branchname,DataTypeToChar(datatype));
1587  return Branch(branchname,addobj,varname.Data(),bufsize);
1588  }
1589  return 0;
1590  }
1591  TClass* actualClass = 0;
1592  if (!addobj) {
1593  Error("Branch", "Reference interface requires a valid object (for branch: %s)!", branchname);
1594  return 0;
1595  }
1596  actualClass = ptrClass->GetActualClass(addobj);
1597  if (!actualClass) {
1598  Warning("Branch", "The actual TClass corresponding to the object provided for the definition of the branch \"%s\" is missing.\n\tThe object will be truncated down to its %s part",
1599  branchname, ptrClass->GetName());
1600  actualClass = ptrClass;
1601  } else if ((ptrClass != actualClass) && !actualClass->InheritsFrom(ptrClass)) {
1602  Error("Branch", "The actual class (%s) of the object provided for the definition of the branch \"%s\" does not inherit from %s", actualClass->GetName(), branchname, ptrClass->GetName());
1603  return 0;
1604  }
1605  if (actualClass && actualClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(actualClass->GetCollectionProxy())) {
1606  Error("Branch", writeStlWithoutProxyMsg,
1607  actualClass->GetName(), branchname, actualClass->GetName());
1608  return 0;
1609  }
1610  return BronchExec(branchname, actualClass->GetName(), (void*) addobj, kFALSE, bufsize, splitlevel);
1611 }
1612 
1613 ////////////////////////////////////////////////////////////////////////////////
1614 /// Deprecated function. Use next function instead.
1615 
1616 Int_t TTree::Branch(TList* li, Int_t bufsize /* = 32000 */ , Int_t splitlevel /* = 99 */)
1618  return Branch((TCollection*) li, bufsize, splitlevel);
1619 }
1620 
1621 ////////////////////////////////////////////////////////////////////////////////
1622 /// Create one branch for each element in the collection.
1623 ///
1624 /// Each entry in the collection becomes a top level branch if the
1625 /// corresponding class is not a collection. If it is a collection, the entry
1626 /// in the collection becomes in turn top level branches, etc.
1627 /// The splitlevel is decreased by 1 every time a new collection is found.
1628 /// For example if list is a TObjArray*
1629 /// - if splitlevel = 1, one top level branch is created for each element
1630 /// of the TObjArray.
1631 /// - if splitlevel = 2, one top level branch is created for each array element.
1632 /// if, in turn, one of the array elements is a TCollection, one top level
1633 /// branch will be created for each element of this collection.
1634 ///
1635 /// In case a collection element is a TClonesArray, the special Tree constructor
1636 /// for TClonesArray is called.
1637 /// The collection itself cannot be a TClonesArray.
1638 ///
1639 /// The function returns the total number of branches created.
1640 ///
1641 /// If name is given, all branch names will be prefixed with name_.
1642 ///
1643 /// IMPORTANT NOTE1: This function should not be called with splitlevel < 1.
1644 ///
1645 /// IMPORTANT NOTE2: The branches created by this function will have names
1646 /// corresponding to the collection or object names. It is important
1647 /// to give names to collections to avoid misleading branch names or
1648 /// identical branch names. By default collections have a name equal to
1649 /// the corresponding class name, e.g. the default name for a TList is "TList".
1650 ///
1651 /// And in general in any cases two or more master branches contain subbranches
1652 /// with identical names, one must add a "." (dot) character at the end
1653 /// of the master branch name. This will force the name of the subbranch
1654 /// to be master.subbranch instead of simply subbranch.
1655 /// This situation happens when the top level object (say event)
1656 /// has two or more members referencing the same class.
1657 /// For example, if a Tree has two branches B1 and B2 corresponding
1658 /// to objects of the same class MyClass, one can do:
1659 /// ~~~ {.cpp}
1660 /// tree.Branch("B1.","MyClass",&b1,8000,1);
1661 /// tree.Branch("B2.","MyClass",&b2,8000,1);
1662 /// ~~~
1663 /// if MyClass has 3 members a,b,c, the two instructions above will generate
1664 /// subbranches called B1.a, B1.b ,B1.c, B2.a, B2.b, B2.c
1665 ///
1666 /// Example:
1667 /// ~~~ {.cpp}
1668 /// {
1669 /// TTree T("T","test list");
1670 /// TList *list = new TList();
1671 ///
1672 /// TObjArray *a1 = new TObjArray();
1673 /// a1->SetName("a1");
1674 /// list->Add(a1);
1675 /// TH1F *ha1a = new TH1F("ha1a","ha1",100,0,1);
1676 /// TH1F *ha1b = new TH1F("ha1b","ha1",100,0,1);
1677 /// a1->Add(ha1a);
1678 /// a1->Add(ha1b);
1679 /// TObjArray *b1 = new TObjArray();
1680 /// b1->SetName("b1");
1681 /// list->Add(b1);
1682 /// TH1F *hb1a = new TH1F("hb1a","hb1",100,0,1);
1683 /// TH1F *hb1b = new TH1F("hb1b","hb1",100,0,1);
1684 /// b1->Add(hb1a);
1685 /// b1->Add(hb1b);
1686 ///
1687 /// TObjArray *a2 = new TObjArray();
1688 /// a2->SetName("a2");
1689 /// list->Add(a2);
1690 /// TH1S *ha2a = new TH1S("ha2a","ha2",100,0,1);
1691 /// TH1S *ha2b = new TH1S("ha2b","ha2",100,0,1);
1692 /// a2->Add(ha2a);
1693 /// a2->Add(ha2b);
1694 ///
1695 /// T.Branch(list,16000,2);
1696 /// T.Print();
1697 /// }
1698 /// ~~~
1699 
1700 Int_t TTree::Branch(TCollection* li, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */, const char* name /* = "" */)
1702 
1703  if (!li) {
1704  return 0;
1705  }
1706  TObject* obj = 0;
1707  Int_t nbranches = GetListOfBranches()->GetEntries();
1708  if (li->InheritsFrom(TClonesArray::Class())) {
1709  Error("Branch", "Cannot call this constructor for a TClonesArray");
1710  return 0;
1711  }
1712  Int_t nch = strlen(name);
1713  TString branchname;
1714  TIter next(li);
1715  while ((obj = next())) {
1716  if ((splitlevel > 1) && obj->InheritsFrom(TCollection::Class()) && !obj->InheritsFrom(TClonesArray::Class())) {
1717  TCollection* col = (TCollection*) obj;
1718  if (nch) {
1719  branchname.Form("%s_%s_", name, col->GetName());
1720  } else {
1721  branchname.Form("%s_", col->GetName());
1722  }
1723  Branch(col, bufsize, splitlevel - 1, branchname);
1724  } else {
1725  if (nch && (name[nch-1] == '_')) {
1726  branchname.Form("%s%s", name, obj->GetName());
1727  } else {
1728  if (nch) {
1729  branchname.Form("%s_%s", name, obj->GetName());
1730  } else {
1731  branchname.Form("%s", obj->GetName());
1732  }
1733  }
1734  if (splitlevel > 99) {
1735  branchname += ".";
1736  }
1737  Bronch(branchname, obj->ClassName(), li->GetObjectRef(obj), bufsize, splitlevel - 1);
1738  }
1739  }
1740  return GetListOfBranches()->GetEntries() - nbranches;
1741 }
1742 
1743 ////////////////////////////////////////////////////////////////////////////////
1744 /// Create one branch for each element in the folder.
1745 /// Returns the total number of branches created.
1746 
1747 Int_t TTree::Branch(const char* foldername, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */)
1749  TObject* ob = gROOT->FindObjectAny(foldername);
1750  if (!ob) {
1751  return 0;
1752  }
1753  if (ob->IsA() != TFolder::Class()) {
1754  return 0;
1755  }
1756  Int_t nbranches = GetListOfBranches()->GetEntries();
1757  TFolder* folder = (TFolder*) ob;
1758  TIter next(folder->GetListOfFolders());
1759  TObject* obj = 0;
1760  char* curname = new char[1000];
1761  char occur[20];
1762  while ((obj = next())) {
1763  snprintf(curname,1000, "%s/%s", foldername, obj->GetName());
1764  if (obj->IsA() == TFolder::Class()) {
1765  Branch(curname, bufsize, splitlevel - 1);
1766  } else {
1767  void* add = (void*) folder->GetListOfFolders()->GetObjectRef(obj);
1768  for (Int_t i = 0; i < 1000; ++i) {
1769  if (curname[i] == 0) {
1770  break;
1771  }
1772  if (curname[i] == '/') {
1773  curname[i] = '.';
1774  }
1775  }
1776  Int_t noccur = folder->Occurence(obj);
1777  if (noccur > 0) {
1778  snprintf(occur,20, "_%d", noccur);
1779  strlcat(curname, occur,1000);
1780  }
1781  TBranchElement* br = (TBranchElement*) Bronch(curname, obj->ClassName(), add, bufsize, splitlevel - 1);
1782  if (br) br->SetBranchFolder();
1783  }
1784  }
1785  delete[] curname;
1786  return GetListOfBranches()->GetEntries() - nbranches;
1787 }
1788 
1789 ////////////////////////////////////////////////////////////////////////////////
1790 /// Create a new TTree Branch.
1791 ///
1792 /// This Branch constructor is provided to support non-objects in
1793 /// a Tree. The variables described in leaflist may be simple
1794 /// variables or structures. // See the two following
1795 /// constructors for writing objects in a Tree.
1796 ///
1797 /// By default the branch buffers are stored in the same file as the Tree.
1798 /// use TBranch::SetFile to specify a different file
1799 ///
1800 /// * address is the address of the first item of a structure.
1801 /// * leaflist is the concatenation of all the variable names and types
1802 /// separated by a colon character :
1803 /// The variable name and the variable type are separated by a slash (/).
1804 /// The variable type may be 0,1 or 2 characters. If no type is given,
1805 /// the type of the variable is assumed to be the same as the previous
1806 /// variable. If the first variable does not have a type, it is assumed
1807 /// of type F by default. The list of currently supported types is given below:
1808 /// - `C` : a character string terminated by the 0 character
1809 /// - `B` : an 8 bit signed integer (`Char_t`)
1810 /// - `b` : an 8 bit unsigned integer (`UChar_t`)
1811 /// - `S` : a 16 bit signed integer (`Short_t`)
1812 /// - `s` : a 16 bit unsigned integer (`UShort_t`)
1813 /// - `I` : a 32 bit signed integer (`Int_t`)
1814 /// - `i` : a 32 bit unsigned integer (`UInt_t`)
1815 /// - `F` : a 32 bit floating point (`Float_t`)
1816 /// - `D` : a 64 bit floating point (`Double_t`)
1817 /// - `L` : a 64 bit signed integer (`Long64_t`)
1818 /// - `l` : a 64 bit unsigned integer (`ULong64_t`)
1819 /// - `O` : [the letter `o`, not a zero] a boolean (`Bool_t`)
1820 ///
1821 /// Arrays of values are supported with the following syntax:
1822 /// - If leaf name has the form var[nelem], where nelem is alphanumeric, then
1823 /// if nelem is a leaf name, it is used as the variable size of the array,
1824 /// otherwise return 0.
1825 /// - If leaf name has the form var[nelem], where nelem is a non-negative integer, then
1826 /// it is used as the fixed size of the array.
1827 /// - If leaf name has the form of a multi-dimensional array (e.g. var[nelem][nelem2])
1828 /// where nelem and nelem2 are non-negative integer) then
1829 /// it is used as a 2 dimensional array of fixed size.
1830 ///
1831 /// Any of other form is not supported.
1832 ///
1833 /// Note that the TTree will assume that all the item are contiguous in memory.
1834 /// On some platform, this is not always true of the member of a struct or a class,
1835 /// due to padding and alignment. Sorting your data member in order of decreasing
1836 /// sizeof usually leads to their being contiguous in memory.
1837 ///
1838 /// * bufsize is the buffer size in bytes for this branch
1839 /// The default value is 32000 bytes and should be ok for most cases.
1840 /// You can specify a larger value (e.g. 256000) if your Tree is not split
1841 /// and each entry is large (Megabytes)
1842 /// A small value for bufsize is optimum if you intend to access
1843 /// the entries in the Tree randomly and your Tree is in split mode.
1844 
1845 TBranch* TTree::Branch(const char* name, void* address, const char* leaflist, Int_t bufsize /* = 32000 */)
1847  TBranch* branch = new TBranch(this, name, address, leaflist, bufsize);
1848  if (branch->IsZombie()) {
1849  delete branch;
1850  branch = 0;
1851  return 0;
1852  }
1853  fBranches.Add(branch);
1854  return branch;
1855 }
1856 
1857 ////////////////////////////////////////////////////////////////////////////////
1858 /// Create a new branch with the object of class classname at address addobj.
1859 ///
1860 /// WARNING:
1861 ///
1862 /// Starting with Root version 3.01, the Branch function uses the new style
1863 /// branches (TBranchElement). To get the old behaviour, you can:
1864 /// - call BranchOld or
1865 /// - call TTree::SetBranchStyle(0)
1866 ///
1867 /// Note that with the new style, classname does not need to derive from TObject.
1868 /// It must derived from TObject if the branch style has been set to 0 (old)
1869 ///
1870 /// Note: See the comments in TBranchElement::SetAddress() for a more
1871 /// detailed discussion of the meaning of the addobj parameter in
1872 /// the case of new-style branches.
1873 ///
1874 /// Use splitlevel < 0 instead of splitlevel=0 when the class
1875 /// has a custom Streamer
1876 ///
1877 /// Note: if the split level is set to the default (99), TTree::Branch will
1878 /// not issue a warning if the class can not be split.
1879 
1880 TBranch* TTree::Branch(const char* name, const char* classname, void* addobj, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */)
1882  if (fgBranchStyle == 1) {
1883  return Bronch(name, classname, addobj, bufsize, splitlevel);
1884  } else {
1885  if (splitlevel < 0) {
1886  splitlevel = 0;
1887  }
1888  return BranchOld(name, classname, addobj, bufsize, splitlevel);
1889  }
1890 }
1891 
1892 ////////////////////////////////////////////////////////////////////////////////
1893 /// Create a new TTree BranchObject.
1894 ///
1895 /// Build a TBranchObject for an object of class classname.
1896 /// addobj is the address of a pointer to an object of class classname.
1897 /// IMPORTANT: classname must derive from TObject.
1898 /// The class dictionary must be available (ClassDef in class header).
1899 ///
1900 /// This option requires access to the library where the corresponding class
1901 /// is defined. Accessing one single data member in the object implies
1902 /// reading the full object.
1903 /// See the next Branch constructor for a more efficient storage
1904 /// in case the entry consists of arrays of identical objects.
1905 ///
1906 /// By default the branch buffers are stored in the same file as the Tree.
1907 /// use TBranch::SetFile to specify a different file
1908 ///
1909 /// IMPORTANT NOTE about branch names:
1910 ///
1911 /// In case two or more master branches contain subbranches with
1912 /// identical names, one must add a "." (dot) character at the end
1913 /// of the master branch name. This will force the name of the subbranch
1914 /// to be master.subbranch instead of simply subbranch.
1915 /// This situation happens when the top level object (say event)
1916 /// has two or more members referencing the same class.
1917 /// For example, if a Tree has two branches B1 and B2 corresponding
1918 /// to objects of the same class MyClass, one can do:
1919 /// ~~~ {.cpp}
1920 /// tree.Branch("B1.","MyClass",&b1,8000,1);
1921 /// tree.Branch("B2.","MyClass",&b2,8000,1);
1922 /// ~~~
1923 /// if MyClass has 3 members a,b,c, the two instructions above will generate
1924 /// subbranches called B1.a, B1.b ,B1.c, B2.a, B2.b, B2.c
1925 ///
1926 /// bufsize is the buffer size in bytes for this branch
1927 /// The default value is 32000 bytes and should be ok for most cases.
1928 /// You can specify a larger value (e.g. 256000) if your Tree is not split
1929 /// and each entry is large (Megabytes)
1930 /// A small value for bufsize is optimum if you intend to access
1931 /// the entries in the Tree randomly and your Tree is in split mode.
1932 
1933 TBranch* TTree::BranchOld(const char* name, const char* classname, void* addobj, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 1 */)
1935  TClass* cl = TClass::GetClass(classname);
1936  if (!cl) {
1937  Error("BranchOld", "Cannot find class: '%s'", classname);
1938  return 0;
1939  }
1940  if (!cl->IsTObject()) {
1941  if (fgBranchStyle == 0) {
1942  Fatal("BranchOld", "The requested class ('%s') does not inherit from TObject.\n"
1943  "\tfgBranchStyle is set to zero requesting by default to use BranchOld.\n"
1944  "\tIf this is intentional use Bronch instead of Branch or BranchOld.", classname);
1945  } else {
1946  Fatal("BranchOld", "The requested class ('%s') does not inherit from TObject.\n"
1947  "\tYou can not use BranchOld to store objects of this type.",classname);
1948  }
1949  return 0;
1950  }
1951  TBranch* branch = new TBranchObject(this, name, classname, addobj, bufsize, splitlevel);
1952  fBranches.Add(branch);
1953  if (!splitlevel) {
1954  return branch;
1955  }
1956  // We are going to fully split the class now.
1957  TObjArray* blist = branch->GetListOfBranches();
1958  const char* rdname = 0;
1959  const char* dname = 0;
1960  TString branchname;
1961  char** apointer = (char**) addobj;
1962  TObject* obj = (TObject*) *apointer;
1963  Bool_t delobj = kFALSE;
1964  if (!obj) {
1965  obj = (TObject*) cl->New();
1966  delobj = kTRUE;
1967  }
1968  // Build the StreamerInfo if first time for the class.
1969  BuildStreamerInfo(cl, obj);
1970  // Loop on all public data members of the class and its base classes.
1971  Int_t lenName = strlen(name);
1972  Int_t isDot = 0;
1973  if (name[lenName-1] == '.') {
1974  isDot = 1;
1975  }
1976  TBranch* branch1 = 0;
1977  TRealData* rd = 0;
1978  TRealData* rdi = 0;
1979  TIter nexti(cl->GetListOfRealData());
1980  TIter next(cl->GetListOfRealData());
1981  // Note: This loop results in a full split because the
1982  // real data list includes all data members of
1983  // data members.
1984  while ((rd = (TRealData*) next())) {
1985  if (rd->TestBit(TRealData::kTransient)) continue;
1986 
1987  // Loop over all data members creating branches for each one.
1988  TDataMember* dm = rd->GetDataMember();
1989  if (!dm->IsPersistent()) {
1990  // Do not process members with an "!" as the first character in the comment field.
1991  continue;
1992  }
1993  if (rd->IsObject()) {
1994  // We skip data members of class type.
1995  // But we do build their real data, their
1996  // streamer info, and write their streamer
1997  // info to the current directory's file.
1998  // Oh yes, and we also do this for all of
1999  // their base classes.
2000  TClass* clm = TClass::GetClass(dm->GetFullTypeName());
2001  if (clm) {
2002  BuildStreamerInfo(clm, (char*) obj + rd->GetThisOffset());
2003  }
2004  continue;
2005  }
2006  rdname = rd->GetName();
2007  dname = dm->GetName();
2008  if (cl->CanIgnoreTObjectStreamer()) {
2009  // Skip the TObject base class data members.
2010  // FIXME: This prevents a user from ever
2011  // using these names themself!
2012  if (!strcmp(dname, "fBits")) {
2013  continue;
2014  }
2015  if (!strcmp(dname, "fUniqueID")) {
2016  continue;
2017  }
2018  }
2019  TDataType* dtype = dm->GetDataType();
2020  Int_t code = 0;
2021  if (dtype) {
2022  code = dm->GetDataType()->GetType();
2023  }
2024  // Encode branch name. Use real data member name
2025  branchname = rdname;
2026  if (isDot) {
2027  if (dm->IsaPointer()) {
2028  // FIXME: This is wrong! The asterisk is not usually in the front!
2029  branchname.Form("%s%s", name, &rdname[1]);
2030  } else {
2031  branchname.Form("%s%s", name, &rdname[0]);
2032  }
2033  }
2034  // FIXME: Change this to a string stream.
2035  TString leaflist;
2036  Int_t offset = rd->GetThisOffset();
2037  char* pointer = ((char*) obj) + offset;
2038  if (dm->IsaPointer()) {
2039  // We have a pointer to an object or a pointer to an array of basic types.
2040  TClass* clobj = 0;
2041  if (!dm->IsBasic()) {
2042  clobj = TClass::GetClass(dm->GetTypeName());
2043  }
2044  if (clobj && clobj->InheritsFrom(TClonesArray::Class())) {
2045  // We have a pointer to a clones array.
2046  char* cpointer = (char*) pointer;
2047  char** ppointer = (char**) cpointer;
2048  TClonesArray* li = (TClonesArray*) *ppointer;
2049  if (splitlevel != 2) {
2050  if (isDot) {
2051  branch1 = new TBranchClones(branch,branchname, pointer, bufsize);
2052  } else {
2053  // FIXME: This is wrong! The asterisk is not usually in the front!
2054  branch1 = new TBranchClones(branch,&branchname.Data()[1], pointer, bufsize);
2055  }
2056  blist->Add(branch1);
2057  } else {
2058  if (isDot) {
2059  branch1 = new TBranchObject(branch, branchname, li->ClassName(), pointer, bufsize);
2060  } else {
2061  // FIXME: This is wrong! The asterisk is not usually in the front!
2062  branch1 = new TBranchObject(branch, &branchname.Data()[1], li->ClassName(), pointer, bufsize);
2063  }
2064  blist->Add(branch1);
2065  }
2066  } else if (clobj) {
2067  // We have a pointer to an object.
2068  //
2069  // It must be a TObject object.
2070  if (!clobj->IsTObject()) {
2071  continue;
2072  }
2073  branch1 = new TBranchObject(branch, dname, clobj->GetName(), pointer, bufsize, 0);
2074  if (isDot) {
2075  branch1->SetName(branchname);
2076  } else {
2077  // FIXME: This is wrong! The asterisk is not usually in the front!
2078  // Do not use the first character (*).
2079  branch1->SetName(&branchname.Data()[1]);
2080  }
2081  blist->Add(branch1);
2082  } else {
2083  // We have a pointer to an array of basic types.
2084  //
2085  // Check the comments in the text of the code for an index specification.
2086  const char* index = dm->GetArrayIndex();
2087  if (index[0]) {
2088  // We are a pointer to a varying length array of basic types.
2089  //check that index is a valid data member name
2090  //if member is part of an object (e.g. fA and index=fN)
2091  //index must be changed from fN to fA.fN
2092  TString aindex (rd->GetName());
2093  Ssiz_t rdot = aindex.Last('.');
2094  if (rdot>=0) {
2095  aindex.Remove(rdot+1);
2096  aindex.Append(index);
2097  }
2098  nexti.Reset();
2099  while ((rdi = (TRealData*) nexti())) {
2100  if (rdi->TestBit(TRealData::kTransient)) continue;
2101 
2102  if (!strcmp(rdi->GetName(), index)) {
2103  break;
2104  }
2105  if (!strcmp(rdi->GetName(), aindex)) {
2106  index = rdi->GetName();
2107  break;
2108  }
2109  }
2110 
2111  char vcode = DataTypeToChar((EDataType)code);
2112  // Note that we differentiate between strings and
2113  // char array by the fact that there is NO specified
2114  // size for a string (see next if (code == 1)
2115 
2116  if (vcode) {
2117  leaflist.Form("%s[%s]/%c", &rdname[0], index, vcode);
2118  } else {
2119  Error("BranchOld", "Cannot create branch for rdname: %s code: %d", branchname.Data(), code);
2120  leaflist = "";
2121  }
2122  } else {
2123  // We are possibly a character string.
2124  if (code == 1) {
2125  // We are a character string.
2126  leaflist.Form("%s/%s", dname, "C");
2127  } else {
2128  // Invalid array specification.
2129  // FIXME: We need an error message here.
2130  continue;
2131  }
2132  }
2133  // There are '*' in both the branchname and leaflist, remove them.
2134  TString bname( branchname );
2135  bname.ReplaceAll("*","");
2136  leaflist.ReplaceAll("*","");
2137  // Add the branch to the tree and indicate that the address
2138  // is that of a pointer to be dereferenced before using.
2139  branch1 = new TBranch(branch, bname, *((void**) pointer), leaflist, bufsize);
2140  TLeaf* leaf = (TLeaf*) branch1->GetListOfLeaves()->At(0);
2142  leaf->SetAddress((void**) pointer);
2143  blist->Add(branch1);
2144  }
2145  } else if (dm->IsBasic()) {
2146  // We have a basic type.
2147 
2148  char vcode = DataTypeToChar((EDataType)code);
2149  if (vcode) {
2150  leaflist.Form("%s/%c", rdname, vcode);
2151  } else {
2152  Error("BranchOld", "Cannot create branch for rdname: %s code: %d", branchname.Data(), code);
2153  leaflist = "";
2154  }
2155  branch1 = new TBranch(branch, branchname, pointer, leaflist, bufsize);
2156  branch1->SetTitle(rdname);
2157  blist->Add(branch1);
2158  } else {
2159  // We have a class type.
2160  // Note: This cannot happen due to the rd->IsObject() test above.
2161  // FIXME: Put an error message here just in case.
2162  }
2163  if (branch1) {
2164  branch1->SetOffset(offset);
2165  } else {
2166  Warning("BranchOld", "Cannot process member: '%s'", rdname);
2167  }
2168  }
2169  if (delobj) {
2170  delete obj;
2171  obj = 0;
2172  }
2173  return branch;
2174 }
2175 
2176 ////////////////////////////////////////////////////////////////////////////////
2177 /// Build the optional branch supporting the TRefTable.
2178 /// This branch will keep all the information to find the branches
2179 /// containing referenced objects.
2180 ///
2181 /// At each Tree::Fill, the branch numbers containing the
2182 /// referenced objects are saved to the TBranchRef basket.
2183 /// When the Tree header is saved (via TTree::Write), the branch
2184 /// is saved keeping the information with the pointers to the branches
2185 /// having referenced objects.
2186 
2189  if (!fBranchRef) {
2190  fBranchRef = new TBranchRef(this);
2191  }
2192  return fBranchRef;
2193 }
2194 
2195 ////////////////////////////////////////////////////////////////////////////////
2196 /// Create a new TTree BranchElement.
2197 ///
2198 /// ## WARNING about this new function
2199 ///
2200 /// This function is designed to replace the internal
2201 /// implementation of the old TTree::Branch (whose implementation
2202 /// has been moved to BranchOld).
2203 ///
2204 /// NOTE: The 'Bronch' method supports only one possible calls
2205 /// signature (where the object type has to be specified
2206 /// explicitly and the address must be the address of a pointer).
2207 /// For more flexibility use 'Branch'. Use Bronch only in (rare)
2208 /// cases (likely to be legacy cases) where both the new and old
2209 /// implementation of Branch needs to be used at the same time.
2210 ///
2211 /// This function is far more powerful than the old Branch
2212 /// function. It supports the full C++, including STL and has
2213 /// the same behaviour in split or non-split mode. classname does
2214 /// not have to derive from TObject. The function is based on
2215 /// the new TStreamerInfo.
2216 ///
2217 /// Build a TBranchElement for an object of class classname.
2218 ///
2219 /// addr is the address of a pointer to an object of class
2220 /// classname. The class dictionary must be available (ClassDef
2221 /// in class header).
2222 ///
2223 /// Note: See the comments in TBranchElement::SetAddress() for a more
2224 /// detailed discussion of the meaning of the addr parameter.
2225 ///
2226 /// This option requires access to the library where the
2227 /// corresponding class is defined. Accessing one single data
2228 /// member in the object implies reading the full object.
2229 ///
2230 /// By default the branch buffers are stored in the same file as the Tree.
2231 /// use TBranch::SetFile to specify a different file
2232 ///
2233 /// IMPORTANT NOTE about branch names:
2234 ///
2235 /// In case two or more master branches contain subbranches with
2236 /// identical names, one must add a "." (dot) character at the end
2237 /// of the master branch name. This will force the name of the subbranch
2238 /// to be master.subbranch instead of simply subbranch.
2239 /// This situation happens when the top level object (say event)
2240 /// has two or more members referencing the same class.
2241 /// For example, if a Tree has two branches B1 and B2 corresponding
2242 /// to objects of the same class MyClass, one can do:
2243 /// ~~~ {.cpp}
2244 /// tree.Branch("B1.","MyClass",&b1,8000,1);
2245 /// tree.Branch("B2.","MyClass",&b2,8000,1);
2246 /// ~~~
2247 /// if MyClass has 3 members a,b,c, the two instructions above will generate
2248 /// subbranches called B1.a, B1.b ,B1.c, B2.a, B2.b, B2.c
2249 ///
2250 /// bufsize is the buffer size in bytes for this branch
2251 /// The default value is 32000 bytes and should be ok for most cases.
2252 /// You can specify a larger value (e.g. 256000) if your Tree is not split
2253 /// and each entry is large (Megabytes)
2254 /// A small value for bufsize is optimum if you intend to access
2255 /// the entries in the Tree randomly and your Tree is in split mode.
2256 ///
2257 /// Use splitlevel < 0 instead of splitlevel=0 when the class
2258 /// has a custom Streamer
2259 ///
2260 /// Note: if the split level is set to the default (99), TTree::Branch will
2261 /// not issue a warning if the class can not be split.
2262 
2263 TBranch* TTree::Bronch(const char* name, const char* classname, void* addr, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */)
2265  return BronchExec(name, classname, addr, kTRUE, bufsize, splitlevel);
2266 }
2267 
2268 ////////////////////////////////////////////////////////////////////////////////
2269 /// Helper function implementing TTree::Bronch and TTree::Branch(const char *name, T &obj);
2270 
2271 TBranch* TTree::BronchExec(const char* name, const char* classname, void* addr, Bool_t isptrptr, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */)
2273  TClass* cl = TClass::GetClass(classname);
2274  if (!cl) {
2275  Error("Bronch", "Cannot find class:%s", classname);
2276  return 0;
2277  }
2278 
2279  //if splitlevel <= 0 and class has a custom Streamer, we must create
2280  //a TBranchObject. We cannot assume that TClass::ReadBuffer is consistent
2281  //with the custom Streamer. The penalty is that one cannot process
2282  //this Tree without the class library containing the class.
2283 
2284  char* objptr = 0;
2285  if (!isptrptr) {
2286  objptr = (char*)addr;
2287  } else if (addr) {
2288  objptr = *((char**) addr);
2289  }
2290 
2291  if (cl == TClonesArray::Class()) {
2292  TClonesArray* clones = (TClonesArray*) objptr;
2293  if (!clones) {
2294  Error("Bronch", "Pointer to TClonesArray is null");
2295  return 0;
2296  }
2297  if (!clones->GetClass()) {
2298  Error("Bronch", "TClonesArray with no class defined in branch: %s", name);
2299  return 0;
2300  }
2301  if (!clones->GetClass()->HasDataMemberInfo()) {
2302  Error("Bronch", "TClonesArray with no dictionary defined in branch: %s", name);
2303  return 0;
2304  }
2305  bool hasCustomStreamer = clones->GetClass()->TestBit(TClass::kHasCustomStreamerMember);
2306  if (splitlevel > 0) {
2307  if (hasCustomStreamer)
2308  Warning("Bronch", "Using split mode on a class: %s with a custom Streamer", clones->GetClass()->GetName());
2309  } else {
2310  if (hasCustomStreamer) clones->BypassStreamer(kFALSE);
2311  TBranchObject *branch = new TBranchObject(this,name,classname,addr,bufsize,0,/*compress=*/ -1,isptrptr);
2312  fBranches.Add(branch);
2313  return branch;
2314  }
2315  }
2316 
2317  if (cl->GetCollectionProxy()) {
2318  TVirtualCollectionProxy* collProxy = cl->GetCollectionProxy();
2319  //if (!collProxy) {
2320  // Error("Bronch", "%s is missing its CollectionProxy (for branch %s)", classname, name);
2321  //}
2322  TClass* inklass = collProxy->GetValueClass();
2323  if (!inklass && (collProxy->GetType() == 0)) {
2324  Error("Bronch", "%s with no class defined in branch: %s", classname, name);
2325  return 0;
2326  }
2327  if ((splitlevel > 0) && inklass && (inklass->GetCollectionProxy() == 0)) {
2328  ROOT::ESTLType stl = cl->GetCollectionType();
2329  if ((stl != ROOT::kSTLmap) && (stl != ROOT::kSTLmultimap)) {
2330  if (!inklass->HasDataMemberInfo()) {
2331  Error("Bronch", "Container with no dictionary defined in branch: %s", name);
2332  return 0;
2333  }
2334  if (inklass->TestBit(TClass::kHasCustomStreamerMember)) {
2335  Warning("Bronch", "Using split mode on a class: %s with a custom Streamer", inklass->GetName());
2336  }
2337  }
2338  }
2339  //-------------------------------------------------------------------------
2340  // If the splitting switch is enabled, the split level is big enough and
2341  // the collection contains pointers we can split it
2342  //////////////////////////////////////////////////////////////////////////
2343 
2344  TBranch *branch;
2345  if( splitlevel > kSplitCollectionOfPointers && collProxy->HasPointers() )
2346  branch = new TBranchSTL( this, name, collProxy, bufsize, splitlevel );
2347  else
2348  branch = new TBranchElement(this, name, collProxy, bufsize, splitlevel);
2349  fBranches.Add(branch);
2350  if (isptrptr) {
2351  branch->SetAddress(addr);
2352  } else {
2353  branch->SetObject(addr);
2354  }
2355  return branch;
2356  }
2357 
2358  Bool_t hasCustomStreamer = kFALSE;
2359  if (!cl->HasDataMemberInfo() && !cl->GetCollectionProxy()) {
2360  Error("Bronch", "Cannot find dictionary for class: %s", classname);
2361  return 0;
2362  }
2363 
2365  // Not an STL container and the linkdef file had a "-" after the class name.
2366  hasCustomStreamer = kTRUE;
2367  }
2368 
2369  if (splitlevel < 0 || ((splitlevel == 0) && hasCustomStreamer && cl->IsTObject())) {
2370  TBranchObject* branch = new TBranchObject(this, name, classname, addr, bufsize, 0, /*compress=*/ -1, isptrptr);
2371  fBranches.Add(branch);
2372  return branch;
2373  }
2374 
2375  if (cl == TClonesArray::Class()) {
2376  // Special case of TClonesArray.
2377  // No dummy object is created.
2378  // The streamer info is not rebuilt unoptimized.
2379  // No dummy top-level branch is created.
2380  // No splitting is attempted.
2381  TBranchElement* branch = new TBranchElement(this, name, (TClonesArray*) objptr, bufsize, splitlevel%kSplitCollectionOfPointers);
2382  fBranches.Add(branch);
2383  if (isptrptr) {
2384  branch->SetAddress(addr);
2385  } else {
2386  branch->SetObject(addr);
2387  }
2388  return branch;
2389  }
2390 
2391  //
2392  // If we are not given an object to use as an i/o buffer
2393  // then create a temporary one which we will delete just
2394  // before returning.
2395  //
2396 
2397  Bool_t delobj = kFALSE;
2398 
2399  if (!objptr) {
2400  objptr = (char*) cl->New();
2401  delobj = kTRUE;
2402  }
2403 
2404  //
2405  // Avoid splitting unsplittable classes.
2406  //
2407 
2408  if ((splitlevel > 0) && !cl->CanSplit()) {
2409  if (splitlevel != 99) {
2410  Warning("Bronch", "%s cannot be split, resetting splitlevel to 0", cl->GetName());
2411  }
2412  splitlevel = 0;
2413  }
2414 
2415  //
2416  // Make sure the streamer info is built and fetch it.
2417  //
2418  // If we are splitting, then make sure the streamer info
2419  // is built unoptimized (data members are not combined).
2420  //
2421 
2422  TStreamerInfo* sinfo = BuildStreamerInfo(cl, objptr, splitlevel==0);
2423  if (!sinfo) {
2424  Error("Bronch", "Cannot build the StreamerInfo for class: %s", cl->GetName());
2425  return 0;
2426  }
2427 
2428  //
2429  // Create a dummy top level branch object.
2430  //
2431 
2432  Int_t id = -1;
2433  if (splitlevel > 0) {
2434  id = -2;
2435  }
2436  TBranchElement* branch = new TBranchElement(this, name, sinfo, id, objptr, bufsize, splitlevel);
2437  fBranches.Add(branch);
2438 
2439  //
2440  // Do splitting, if requested.
2441  //
2442 
2443  if (splitlevel%kSplitCollectionOfPointers > 0) {
2444  branch->Unroll(name, cl, sinfo, objptr, bufsize, splitlevel);
2445  }
2446 
2447  //
2448  // Setup our offsets into the user's i/o buffer.
2449  //
2450 
2451  if (isptrptr) {
2452  branch->SetAddress(addr);
2453  } else {
2454  branch->SetObject(addr);
2455  }
2456 
2457  if (delobj) {
2458  cl->Destructor(objptr);
2459  objptr = 0;
2460  }
2461 
2462  return branch;
2463 }
2464 
2465 ////////////////////////////////////////////////////////////////////////////////
2466 /// Browse content of the TTree.
2467 
2468 void TTree::Browse(TBrowser* b)
2470  fBranches.Browse(b);
2471  if (fUserInfo) {
2472  if (strcmp("TList",fUserInfo->GetName())==0) {
2473  fUserInfo->SetName("UserInfo");
2474  b->Add(fUserInfo);
2475  fUserInfo->SetName("TList");
2476  } else {
2477  b->Add(fUserInfo);
2478  }
2479  }
2480 }
2481 
2482 ////////////////////////////////////////////////////////////////////////////////
2483 /// Build a Tree Index (default is TTreeIndex).
2484 /// See a description of the parameters and functionality in
2485 /// TTreeIndex::TTreeIndex().
2486 ///
2487 /// The return value is the number of entries in the Index (< 0 indicates failure).
2488 ///
2489 /// A TTreeIndex object pointed by fTreeIndex is created.
2490 /// This object will be automatically deleted by the TTree destructor.
2491 /// See also comments in TTree::SetTreeIndex().
2492 
2493 Int_t TTree::BuildIndex(const char* majorname, const char* minorname /* = "0" */)
2495  fTreeIndex = GetPlayer()->BuildIndex(this, majorname, minorname);
2496  if (fTreeIndex->IsZombie()) {
2497  delete fTreeIndex;
2498  fTreeIndex = 0;
2499  return 0;
2500  }
2501  return fTreeIndex->GetN();
2502 }
2503 
2504 ////////////////////////////////////////////////////////////////////////////////
2505 /// Build StreamerInfo for class cl.
2506 /// pointer is an optional argument that may contain a pointer to an object of cl.
2507 
2508 TStreamerInfo* TTree::BuildStreamerInfo(TClass* cl, void* pointer /* = 0 */, Bool_t canOptimize /* = kTRUE */ )
2510  if (!cl) {
2511  return 0;
2512  }
2513  cl->BuildRealData(pointer);
2515 
2516  // Create StreamerInfo for all base classes.
2517  TBaseClass* base = 0;
2518  TIter nextb(cl->GetListOfBases());
2519  while((base = (TBaseClass*) nextb())) {
2520  if (base->IsSTLContainer()) {
2521  continue;
2522  }
2523  TClass* clm = TClass::GetClass(base->GetName());
2524  BuildStreamerInfo(clm, pointer, canOptimize);
2525  }
2526  if (sinfo && fDirectory) {
2527  sinfo->ForceWriteInfo(fDirectory->GetFile());
2528  }
2529  return sinfo;
2530 }
2531 
2532 ////////////////////////////////////////////////////////////////////////////////
2533 /// Called by TTree::Fill() when file has reached its maximum fgMaxTreeSize.
2534 /// Create a new file. If the original file is named "myfile.root",
2535 /// subsequent files are named "myfile_1.root", "myfile_2.root", etc.
2536 ///
2537 /// Returns a pointer to the new file.
2538 ///
2539 /// Currently, the automatic change of file is restricted
2540 /// to the case where the tree is in the top level directory.
2541 /// The file should not contain sub-directories.
2542 ///
2543 /// Before switching to a new file, the tree header is written
2544 /// to the current file, then the current file is closed.
2545 ///
2546 /// To process the multiple files created by ChangeFile, one must use
2547 /// a TChain.
2548 ///
2549 /// The new file name has a suffix "_N" where N is equal to fFileNumber+1.
2550 /// By default a Root session starts with fFileNumber=0. One can set
2551 /// fFileNumber to a different value via TTree::SetFileNumber.
2552 /// In case a file named "_N" already exists, the function will try
2553 /// a file named "__N", then "___N", etc.
2554 ///
2555 /// fgMaxTreeSize can be set via the static function TTree::SetMaxTreeSize.
2556 /// The default value of fgMaxTreeSize is 100 Gigabytes.
2557 ///
2558 /// If the current file contains other objects like TH1 and TTree,
2559 /// these objects are automatically moved to the new file.
2560 ///
2561 /// IMPORTANT NOTE:
2562 ///
2563 /// Be careful when writing the final Tree header to the file!
2564 ///
2565 /// Don't do:
2566 /// ~~~ {.cpp}
2567 /// TFile *file = new TFile("myfile.root","recreate");
2568 /// TTree *T = new TTree("T","title");
2569 /// T->Fill(); //loop
2570 /// file->Write();
2571 /// file->Close();
2572 /// ~~~
2573 /// but do the following:
2574 /// ~~~ {.cpp}
2575 /// TFile *file = new TFile("myfile.root","recreate");
2576 /// TTree *T = new TTree("T","title");
2577 /// T->Fill(); //loop
2578 /// file = T->GetCurrentFile(); //to get the pointer to the current file
2579 /// file->Write();
2580 /// file->Close();
2581 /// ~~~
2582 
2585  file->cd();
2586  Write();
2587  Reset();
2588  char* fname = new char[2000];
2589  ++fFileNumber;
2590  char uscore[10];
2591  for (Int_t i = 0; i < 10; ++i) {
2592  uscore[i] = 0;
2593  }
2594  Int_t nus = 0;
2595  // Try to find a suitable file name that does not already exist.
2596  while (nus < 10) {
2597  uscore[nus] = '_';
2598  fname[0] = 0;
2599  strlcpy(fname, file->GetName(),2000);
2600 
2601  if (fFileNumber > 1) {
2602  char* cunder = strrchr(fname, '_');
2603  if (cunder) {
2604  snprintf(cunder,2000-Int_t(cunder-fname), "%s%d", uscore, fFileNumber);
2605  const char* cdot = strrchr(file->GetName(), '.');
2606  if (cdot) {
2607  strlcat(fname, cdot,2000);
2608  }
2609  } else {
2610  char fcount[10];
2611  snprintf(fcount,10, "%s%d", uscore, fFileNumber);
2612  strlcat(fname, fcount,2000);
2613  }
2614  } else {
2615  char* cdot = strrchr(fname, '.');
2616  if (cdot) {
2617  snprintf(cdot,2000-Int_t(fname-cdot), "%s%d", uscore, fFileNumber);
2618  strlcat(fname, strrchr(file->GetName(), '.'),2000);
2619  } else {
2620  char fcount[10];
2621  snprintf(fcount,10, "%s%d", uscore, fFileNumber);
2622  strlcat(fname, fcount,2000);
2623  }
2624  }
2625  if (gSystem->AccessPathName(fname)) {
2626  break;
2627  }
2628  ++nus;
2629  Warning("ChangeFile", "file %s already exist, trying with %d underscores", fname, nus+1);
2630  }
2631  Int_t compress = file->GetCompressionSettings();
2632  TFile* newfile = TFile::Open(fname, "recreate", "chain files", compress);
2633  if (newfile == 0) {
2634  Error("Fill","Failed to open new file %s, continuing as a memory tree.",fname);
2635  } else {
2636  Printf("Fill: Switching to new file: %s", fname);
2637  }
2638  // The current directory may contain histograms and trees.
2639  // These objects must be moved to the new file.
2640  TBranch* branch = 0;
2641  TObject* obj = 0;
2642  while ((obj = file->GetList()->First())) {
2643  file->Remove(obj);
2644  // Histogram: just change the directory.
2645  if (obj->InheritsFrom("TH1")) {
2646  gROOT->ProcessLine(TString::Format("((%s*)0x%lx)->SetDirectory((TDirectory*)0x%lx);", obj->ClassName(), (Long_t) obj, (Long_t) newfile));
2647  continue;
2648  }
2649  // Tree: must save all trees in the old file, reset them.
2650  if (obj->InheritsFrom(TTree::Class())) {
2651  TTree* t = (TTree*) obj;
2652  if (t != this) {
2653  t->AutoSave();
2654  t->Reset();
2655  t->fFileNumber = fFileNumber;
2656  }
2657  t->SetDirectory(newfile);
2658  TIter nextb(t->GetListOfBranches());
2659  while ((branch = (TBranch*)nextb())) {
2660  branch->SetFile(newfile);
2661  }
2662  if (t->GetBranchRef()) {
2663  t->GetBranchRef()->SetFile(newfile);
2664  }
2665  continue;
2666  }
2667  // Not a TH1 or a TTree, move object to new file.
2668  if (newfile) newfile->Append(obj);
2669  file->Remove(obj);
2670  }
2671  delete file;
2672  file = 0;
2673  delete[] fname;
2674  fname = 0;
2675  return newfile;
2676 }
2677 
2678 ////////////////////////////////////////////////////////////////////////////////
2679 /// Check whether or not the address described by the last 3 parameters
2680 /// matches the content of the branch. If a Data Model Evolution conversion
2681 /// is involved, reset the fInfo of the branch.
2682 /// The return values are:
2683 //
2684 /// - kMissingBranch (-5) : Missing branch
2685 /// - kInternalError (-4) : Internal error (could not find the type corresponding to a data type number)
2686 /// - kMissingCompiledCollectionProxy (-3) : Missing compiled collection proxy for a compiled collection
2687 /// - kMismatch (-2) : Non-Class Pointer type given does not match the type expected by the branch
2688 /// - kClassMismatch (-1) : Class Pointer type given does not match the type expected by the branch
2689 /// - kMatch (0) : perfect match
2690 /// - kMatchConversion (1) : match with (I/O) conversion
2691 /// - kMatchConversionCollection (2) : match with (I/O) conversion of the content of a collection
2692 /// - kMakeClass (3) : MakeClass mode so we can not check.
2693 /// - kVoidPtr (4) : void* passed so no check was made.
2694 /// - kNoCheck (5) : Underlying TBranch not yet available so no check was made.
2695 
2696 Int_t TTree::CheckBranchAddressType(TBranch* branch, TClass* ptrClass, EDataType datatype, Bool_t isptr)
2698  if (GetMakeClass()) {
2699  // If we are in MakeClass mode so we do not really use classes.
2700  return kMakeClass;
2701  }
2702 
2703  // Let's determine what we need!
2704  TClass* expectedClass = 0;
2705  EDataType expectedType = kOther_t;
2706  if (0 != branch->GetExpectedType(expectedClass,expectedType) ) {
2707  // Something went wrong, the warning message has already be issued.
2708  return kInternalError;
2709  }
2710  if (expectedClass && datatype == kOther_t && ptrClass == 0) {
2711  if (branch->InheritsFrom( TBranchElement::Class() )) {
2712  TBranchElement* bEl = (TBranchElement*)branch;
2713  bEl->SetTargetClass( expectedClass->GetName() );
2714  }
2715  if (expectedClass && expectedClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(expectedClass->GetCollectionProxy())) {
2716  Error("SetBranchAddress", "Unable to determine the type given for the address for \"%s\". "
2717  "The class expected (%s) refers to an stl collection and do not have a compiled CollectionProxy. "
2718  "Please generate the dictionary for this class (%s)",
2719  branch->GetName(), expectedClass->GetName(), expectedClass->GetName());
2721  }
2722  if (!expectedClass->IsLoaded()) {
2723  // The originally expected class does not have a dictionary, it is then plausible that the pointer being passed is the right type
2724  // (we really don't know). So let's express that.
2725  Error("SetBranchAddress", "Unable to determine the type given for the address for \"%s\". "
2726  "The class expected (%s) does not have a dictionary and needs to be emulated for I/O purposes but is being passed a compiled object."
2727  "Please generate the dictionary for this class (%s)",
2728  branch->GetName(), expectedClass->GetName(), expectedClass->GetName());
2729  } else {
2730  Error("SetBranchAddress", "Unable to determine the type given for the address for \"%s\". "
2731  "This is probably due to a missing dictionary, the original data class for this branch is %s.", branch->GetName(), expectedClass->GetName());
2732  }
2733  return kClassMismatch;
2734  }
2735  if (expectedClass && ptrClass && (branch->GetMother() == branch)) {
2736  // Top Level branch
2737  if (!isptr) {
2738  Error("SetBranchAddress", "The address for \"%s\" should be the address of a pointer!", branch->GetName());
2739  }
2740  }
2741  if (expectedType == kFloat16_t) {
2742  expectedType = kFloat_t;
2743  }
2744  if (expectedType == kDouble32_t) {
2745  expectedType = kDouble_t;
2746  }
2747  if (datatype == kFloat16_t) {
2748  datatype = kFloat_t;
2749  }
2750  if (datatype == kDouble32_t) {
2751  datatype = kDouble_t;
2752  }
2753 
2754  /////////////////////////////////////////////////////////////////////////////
2755  // Deal with the class renaming
2756  /////////////////////////////////////////////////////////////////////////////
2757 
2758  if( expectedClass && ptrClass &&
2759  expectedClass != ptrClass &&
2760  branch->InheritsFrom( TBranchElement::Class() ) &&
2761  ptrClass->GetSchemaRules() &&
2762  ptrClass->GetSchemaRules()->HasRuleWithSourceClass( expectedClass->GetName() ) ) {
2763  TBranchElement* bEl = (TBranchElement*)branch;
2764 
2765  if ( ptrClass->GetCollectionProxy() && expectedClass->GetCollectionProxy() ) {
2766  if (gDebug > 7)
2767  Info("SetBranchAddress", "Matching STL collection (at least according to the SchemaRuleSet when "
2768  "reading a %s into a %s",expectedClass->GetName(),ptrClass->GetName());
2769 
2770  bEl->SetTargetClass( ptrClass->GetName() );
2771  return kMatchConversion;
2772 
2773  } else if ( !ptrClass->GetConversionStreamerInfo( expectedClass, bEl->GetClassVersion() ) &&
2774  !ptrClass->FindConversionStreamerInfo( expectedClass, bEl->GetCheckSum() ) ) {
2775  Error("SetBranchAddress", "The pointer type given \"%s\" does not correspond to the type needed \"%s\" by the branch: %s", ptrClass->GetName(), bEl->GetClassName(), branch->GetName());
2776 
2777  bEl->SetTargetClass( expectedClass->GetName() );
2778  return kClassMismatch;
2779  }
2780  else {
2781 
2782  bEl->SetTargetClass( ptrClass->GetName() );
2783  return kMatchConversion;
2784  }
2785 
2786  } else if (expectedClass && ptrClass && !expectedClass->InheritsFrom(ptrClass)) {
2787 
2788  if (expectedClass->GetCollectionProxy() && ptrClass->GetCollectionProxy() &&
2789  branch->InheritsFrom( TBranchElement::Class() ) &&
2790  expectedClass->GetCollectionProxy()->GetValueClass() &&
2791  ptrClass->GetCollectionProxy()->GetValueClass() )
2792  {
2793  // In case of collection, we know how to convert them, if we know how to convert their content.
2794  // NOTE: we need to extend this to std::pair ...
2795 
2796  TClass *onfileValueClass = expectedClass->GetCollectionProxy()->GetValueClass();
2797  TClass *inmemValueClass = ptrClass->GetCollectionProxy()->GetValueClass();
2798 
2799  if (inmemValueClass->GetSchemaRules() &&
2800  inmemValueClass->GetSchemaRules()->HasRuleWithSourceClass(onfileValueClass->GetName() ) )
2801  {
2802  TBranchElement* bEl = (TBranchElement*)branch;
2803  bEl->SetTargetClass( ptrClass->GetName() );
2805  }
2806  }
2807 
2808  Error("SetBranchAddress", "The pointer type given (%s) does not correspond to the class needed (%s) by the branch: %s", ptrClass->GetName(), expectedClass->GetName(), branch->GetName());
2809  if (branch->InheritsFrom( TBranchElement::Class() )) {
2810  TBranchElement* bEl = (TBranchElement*)branch;
2811  bEl->SetTargetClass( expectedClass->GetName() );
2812  }
2813  return kClassMismatch;
2814 
2815  } else if ((expectedType != kOther_t) && (datatype != kOther_t) && (expectedType != kNoType_t) && (datatype != kNoType_t) && (expectedType != datatype)) {
2816  if (datatype != kChar_t) {
2817  // For backward compatibility we assume that (char*) was just a cast and/or a generic address
2818  Error("SetBranchAddress", "The pointer type given \"%s\" (%d) does not correspond to the type needed \"%s\" (%d) by the branch: %s",
2819  TDataType::GetTypeName(datatype), datatype, TDataType::GetTypeName(expectedType), expectedType, branch->GetName());
2820  return kMismatch;
2821  }
2822  } else if ((expectedClass && (datatype != kOther_t && datatype != kNoType_t && datatype != kInt_t)) ||
2823  (ptrClass && (expectedType != kOther_t && expectedType != kNoType_t && datatype != kInt_t)) ) {
2824  // Sometime a null pointer can look an int, avoid complaining in that case.
2825  if (expectedClass) {
2826  Error("SetBranchAddress", "The pointer type given \"%s\" (%d) does not correspond to the type needed \"%s\" by the branch: %s",
2827  TDataType::GetTypeName(datatype), datatype, expectedClass->GetName(), branch->GetName());
2828  if (branch->InheritsFrom( TBranchElement::Class() )) {
2829  TBranchElement* bEl = (TBranchElement*)branch;
2830  bEl->SetTargetClass( expectedClass->GetName() );
2831  }
2832  } else {
2833  // In this case, it is okay if the first data member is of the right type (to support the case where we are being passed
2834  // a struct).
2835  bool found = false;
2836  if (ptrClass->IsLoaded()) {
2837  TIter next(ptrClass->GetListOfRealData());
2838  TRealData *rdm;
2839  while ((rdm = (TRealData*)next())) {
2840  if (rdm->GetThisOffset() == 0) {
2841  TDataType *dmtype = rdm->GetDataMember()->GetDataType();
2842  if (dmtype) {
2843  EDataType etype = (EDataType)dmtype->GetType();
2844  if (etype == expectedType) {
2845  found = true;
2846  }
2847  }
2848  break;
2849  }
2850  }
2851  } else {
2852  TIter next(ptrClass->GetListOfDataMembers());
2853  TDataMember *dm;
2854  while ((dm = (TDataMember*)next())) {
2855  if (dm->GetOffset() == 0) {
2856  TDataType *dmtype = dm->GetDataType();
2857  if (dmtype) {
2858  EDataType etype = (EDataType)dmtype->GetType();
2859  if (etype == expectedType) {
2860  found = true;
2861  }
2862  }
2863  break;
2864  }
2865  }
2866  }
2867  if (found) {
2868  // let's check the size.
2869  TLeaf *last = (TLeaf*)branch->GetListOfLeaves()->Last();
2870  long len = last->GetOffset() + last->GetLenType() * last->GetLen();
2871  if (len <= ptrClass->Size()) {
2872  return kMatch;
2873  }
2874  }
2875  Error("SetBranchAddress", "The pointer type given \"%s\" does not correspond to the type needed \"%s\" (%d) by the branch: %s",
2876  ptrClass->GetName(), TDataType::GetTypeName(expectedType), expectedType, branch->GetName());
2877  }
2878  return kMismatch;
2879  }
2880  if (expectedClass && expectedClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(expectedClass->GetCollectionProxy())) {
2881  Error("SetBranchAddress", writeStlWithoutProxyMsg,
2882  expectedClass->GetName(), branch->GetName(), expectedClass->GetName());
2883  if (branch->InheritsFrom( TBranchElement::Class() )) {
2884  TBranchElement* bEl = (TBranchElement*)branch;
2885  bEl->SetTargetClass( expectedClass->GetName() );
2886  }
2888  }
2889  if (expectedClass && branch->InheritsFrom( TBranchElement::Class() )) {
2890  TBranchElement* bEl = (TBranchElement*)branch;
2891  bEl->SetTargetClass( expectedClass->GetName() );
2892  }
2893  return kMatch;
2894 }
2895 
2896 ////////////////////////////////////////////////////////////////////////////////
2897 /// Create a clone of this tree and copy nentries.
2898 ///
2899 /// By default copy all entries.
2900 /// The compression level of the cloned tree is set to the destination
2901 /// file's compression level.
2902 ///
2903 /// NOTE: Only active branches are copied.
2904 /// NOTE: If the TTree is a TChain, the structure of the first TTree
2905 /// is used for the copy.
2906 ///
2907 /// IMPORTANT: The cloned tree stays connected with this tree until
2908 /// this tree is deleted. In particular, any changes in
2909 /// branch addresses in this tree are forwarded to the
2910 /// clone trees, unless a branch in a clone tree has had
2911 /// its address changed, in which case that change stays in
2912 /// effect. When this tree is deleted, all the addresses of
2913 /// the cloned tree are reset to their default values.
2914 ///
2915 /// If 'option' contains the word 'fast' and nentries is -1, the
2916 /// cloning will be done without unzipping or unstreaming the baskets
2917 /// (i.e., a direct copy of the raw bytes on disk).
2918 ///
2919 /// When 'fast' is specified, 'option' can also contain a sorting
2920 /// order for the baskets in the output file.
2921 ///
2922 /// There are currently 3 supported sorting order:
2923 ///
2924 /// - SortBasketsByOffset (the default)
2925 /// - SortBasketsByBranch
2926 /// - SortBasketsByEntry
2927 ///
2928 /// When using SortBasketsByOffset the baskets are written in the
2929 /// output file in the same order as in the original file (i.e. the
2930 /// baskets are sorted by their offset in the original file; Usually
2931 /// this also means that the baskets are sorted by the index/number of
2932 /// the _last_ entry they contain)
2933 ///
2934 /// When using SortBasketsByBranch all the baskets of each individual
2935 /// branches are stored contiguously. This tends to optimize reading
2936 /// speed when reading a small number (1->5) of branches, since all
2937 /// their baskets will be clustered together instead of being spread
2938 /// across the file. However it might decrease the performance when
2939 /// reading more branches (or the full entry).
2940 ///
2941 /// When using SortBasketsByEntry the baskets with the lowest starting
2942 /// entry are written first. (i.e. the baskets are sorted by the
2943 /// index/number of the first entry they contain). This means that on
2944 /// the file the baskets will be in the order in which they will be
2945 /// needed when reading the whole tree sequentially.
2946 ///
2947 /// For examples of CloneTree, see tutorials:
2948 ///
2949 /// - copytree.C:
2950 /// A macro to copy a subset of a TTree to a new TTree.
2951 /// The input file has been generated by the program in
2952 /// $ROOTSYS/test/Event with: Event 1000 1 1 1
2953 ///
2954 /// - copytree2.C:
2955 /// A macro to copy a subset of a TTree to a new TTree.
2956 /// One branch of the new Tree is written to a separate file.
2957 /// The input file has been generated by the program in
2958 /// $ROOTSYS/test/Event with: Event 1000 1 1 1
2959 
2960 TTree* TTree::CloneTree(Long64_t nentries /* = -1 */, Option_t* option /* = "" */)
2962  // Options
2963  Bool_t fastClone = kFALSE;
2964 
2965  TString opt = option;
2966  opt.ToLower();
2967  if (opt.Contains("fast")) {
2968  fastClone = kTRUE;
2969  }
2970 
2971  // If we are a chain, switch to the first tree.
2972  if ((fEntries > 0) && (LoadTree(0) < 0)) {
2973  // FIXME: We need an error message here.
2974  return 0;
2975  }
2976 
2977  // Note: For a tree we get the this pointer, for
2978  // a chain we get the chain's current tree.
2979  TTree* thistree = GetTree();
2980 
2981  // We will use this to override the IO features on the cloned branches.
2982  ROOT::TIOFeatures features = this->GetIOFeatures();
2983  ;
2984 
2985  // Note: For a chain, the returned clone will be
2986  // a clone of the chain's first tree.
2987  TTree* newtree = (TTree*) thistree->Clone();
2988  if (!newtree) {
2989  return 0;
2990  }
2991 
2992  // The clone should not delete any objects allocated by SetAddress().
2993  TObjArray* branches = newtree->GetListOfBranches();
2994  Int_t nb = branches->GetEntriesFast();
2995  for (Int_t i = 0; i < nb; ++i) {
2996  TBranch* br = (TBranch*) branches->UncheckedAt(i);
2997  if (br->InheritsFrom(TBranchElement::Class())) {
2998  ((TBranchElement*) br)->ResetDeleteObject();
2999  }
3000  }
3001 
3002  // Add the new tree to the list of clones so that
3003  // we can later inform it of changes to branch addresses.
3004  thistree->AddClone(newtree);
3005  if (thistree != this) {
3006  // In case this object is a TChain, add the clone
3007  // also to the TChain's list of clones.
3008  AddClone(newtree);
3009  }
3010 
3011  newtree->Reset();
3012 
3013  TDirectory* ndir = newtree->GetDirectory();
3014  TFile* nfile = 0;
3015  if (ndir) {
3016  nfile = ndir->GetFile();
3017  }
3018  Int_t newcomp = -1;
3019  if (nfile) {
3020  newcomp = nfile->GetCompressionSettings();
3021  }
3022 
3023  //
3024  // Delete non-active branches from the clone.
3025  //
3026  // Note: If we are a chain, this does nothing
3027  // since chains have no leaves.
3028  TObjArray* leaves = newtree->GetListOfLeaves();
3029  Int_t nleaves = leaves->GetEntriesFast();
3030  for (Int_t lndx = 0; lndx < nleaves; ++lndx) {
3031  TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(lndx);
3032  if (!leaf) {
3033  continue;
3034  }
3035  TBranch* branch = leaf->GetBranch();
3036  if (branch && (newcomp > -1)) {
3037  branch->SetCompressionSettings(newcomp);
3038  }
3039  if (branch) branch->SetIOFeatures(features);
3040  if (!branch || !branch->TestBit(kDoNotProcess)) {
3041  continue;
3042  }
3043  // size might change at each iteration of the loop over the leaves.
3044  nb = branches->GetEntriesFast();
3045  for (Long64_t i = 0; i < nb; ++i) {
3046  TBranch* br = (TBranch*) branches->UncheckedAt(i);
3047  if (br == branch) {
3048  branches->RemoveAt(i);
3049  delete br;
3050  br = 0;
3051  branches->Compress();
3052  break;
3053  }
3054  TObjArray* lb = br->GetListOfBranches();
3055  Int_t nb1 = lb->GetEntriesFast();
3056  for (Int_t j = 0; j < nb1; ++j) {
3057  TBranch* b1 = (TBranch*) lb->UncheckedAt(j);
3058  if (!b1) {
3059  continue;
3060  }
3061  if (b1 == branch) {
3062  lb->RemoveAt(j);
3063  delete b1;
3064  b1 = 0;
3065  lb->Compress();
3066  break;
3067  }
3068  TObjArray* lb1 = b1->GetListOfBranches();
3069  Int_t nb2 = lb1->GetEntriesFast();
3070  for (Int_t k = 0; k < nb2; ++k) {
3071  TBranch* b2 = (TBranch*) lb1->UncheckedAt(k);
3072  if (!b2) {
3073  continue;
3074  }
3075  if (b2 == branch) {
3076  lb1->RemoveAt(k);
3077  delete b2;
3078  b2 = 0;
3079  lb1->Compress();
3080  break;
3081  }
3082  }
3083  }
3084  }
3085  }
3086  leaves->Compress();
3087 
3088  // Copy MakeClass status.
3089  newtree->SetMakeClass(fMakeClass);
3090 
3091  // Copy branch addresses.
3092  CopyAddresses(newtree);
3093 
3094  //
3095  // Copy entries if requested.
3096  //
3097 
3098  if (nentries != 0) {
3099  if (fastClone && (nentries < 0)) {
3100  if ( newtree->CopyEntries( this, -1, option ) < 0 ) {
3101  // There was a problem!
3102  Error("CloneTTree", "TTree has not been cloned\n");
3103  delete newtree;
3104  newtree = 0;
3105  return 0;
3106  }
3107  } else {
3108  newtree->CopyEntries( this, nentries, option );
3109  }
3110  }
3111 
3112  return newtree;
3113 }
3114 
3115 ////////////////////////////////////////////////////////////////////////////////
3116 /// Set branch addresses of passed tree equal to ours.
3117 /// If undo is true, reset the branch address instead of copying them.
3118 /// This insures 'separation' of a cloned tree from its original
3119 
3120 void TTree::CopyAddresses(TTree* tree, Bool_t undo)
3122  // Copy branch addresses starting from branches.
3124  Int_t nbranches = branches->GetEntriesFast();
3125  for (Int_t i = 0; i < nbranches; ++i) {
3126  TBranch* branch = (TBranch*) branches->UncheckedAt(i);
3127  if (branch->TestBit(kDoNotProcess)) {
3128  continue;
3129  }
3130  if (undo) {
3131  TBranch* br = tree->GetBranch(branch->GetName());
3132  tree->ResetBranchAddress(br);
3133  } else {
3134  char* addr = branch->GetAddress();
3135  if (!addr) {
3136  if (branch->IsA() == TBranch::Class()) {
3137  // If the branch was created using a leaflist, the branch itself may not have
3138  // an address but the leaf might already.
3139  TLeaf *firstleaf = (TLeaf*)branch->GetListOfLeaves()->At(0);
3140  if (!firstleaf || firstleaf->GetValuePointer()) {
3141  // Either there is no leaf (and thus no point in copying the address)
3142  // or the leaf has an address but we can not copy it via the branche
3143  // this will be copied via the next loop (over the leaf).
3144  continue;
3145  }
3146  }
3147  // Note: This may cause an object to be allocated.
3148  branch->SetAddress(0);
3149  addr = branch->GetAddress();
3150  }
3151  // FIXME: The GetBranch() function is braindead and may
3152  // not find the branch!
3153  TBranch* br = tree->GetBranch(branch->GetName());
3154  if (br) {
3155  br->SetAddress(addr);
3156  // The copy does not own any object allocated by SetAddress().
3157  if (br->InheritsFrom(TBranchElement::Class())) {
3158  ((TBranchElement*) br)->ResetDeleteObject();
3159  }
3160  } else {
3161  Warning("CopyAddresses", "Could not find branch named '%s' in tree named '%s'", branch->GetName(), tree->GetName());
3162  }
3163  }
3164  }
3165 
3166  // Copy branch addresses starting from leaves.
3167  TObjArray* tleaves = tree->GetListOfLeaves();
3168  Int_t ntleaves = tleaves->GetEntriesFast();
3169  for (Int_t i = 0; i < ntleaves; ++i) {
3170  TLeaf* tleaf = (TLeaf*) tleaves->UncheckedAt(i);
3171  TBranch* tbranch = tleaf->GetBranch();
3172  TBranch* branch = GetBranch(tbranch->GetName());
3173  if (!branch) {
3174  continue;
3175  }
3176  TLeaf* leaf = branch->GetLeaf(tleaf->GetName());
3177  if (!leaf) {
3178  continue;
3179  }
3180  if (branch->TestBit(kDoNotProcess)) {
3181  continue;
3182  }
3183  if (undo) {
3184  // Now we know whether the address has been transfered
3185  tree->ResetBranchAddress(tbranch);
3186  } else {
3187  TBranchElement *mother = dynamic_cast<TBranchElement*>(leaf->GetBranch()->GetMother());
3188  if (leaf->GetLeafCount() && (leaf->TestBit(TLeaf::kNewValue) || !leaf->GetValuePointer() || (mother && mother->IsObjectOwner())) && tleaf->GetLeafCount())
3189  {
3190  // If it is an array and it was allocated by the leaf itself,
3191  // let's make sure it is large enough for the incoming data.
3192  if (leaf->GetLeafCount()->GetMaximum() < tleaf->GetLeafCount()->GetMaximum()) {
3193  tleaf->IncludeRange( leaf );
3194  if (leaf->GetValuePointer()) {
3195  if (leaf->IsA() == TLeafElement::Class() && mother)
3196  mother->ResetAddress();
3197  else
3198  leaf->SetAddress(nullptr);
3199  }
3200  }
3201  }
3202  if (!branch->GetAddress() && !leaf->GetValuePointer()) {
3203  // We should attempts to set the address of the branch.
3204  // something like:
3205  //(TBranchElement*)branch->GetMother()->SetAddress(0)
3206  //plus a few more subtilities (see TBranchElement::GetEntry).
3207  //but for now we go the simplest route:
3208  //
3209  // Note: This may result in the allocation of an object.
3210  branch->SetupAddresses();
3211  }
3212  if (branch->GetAddress()) {
3213  tree->SetBranchAddress(branch->GetName(), (void*) branch->GetAddress());
3214  TBranch* br = tree->GetBranch(branch->GetName());
3215  if (br) {
3216  // The copy does not own any object allocated by SetAddress().
3217  // FIXME: We do too much here, br may not be a top-level branch.
3218  if (br->InheritsFrom(TBranchElement::Class())) {
3219  ((TBranchElement*) br)->ResetDeleteObject();
3220  }
3221  } else {
3222  Warning("CopyAddresses", "Could not find branch named '%s' in tree named '%s'", branch->GetName(), tree->GetName());
3223  }
3224  } else {
3225  tleaf->SetAddress(leaf->GetValuePointer());
3226  }
3227  }
3228  }
3229 
3230  if (undo &&
3231  ( tree->IsA()->InheritsFrom("TNtuple") || tree->IsA()->InheritsFrom("TNtupleD") )
3232  ) {
3233  tree->ResetBranchAddresses();
3234  }
3235 }
3236 
3237 namespace {
3238 
3239  enum EOnIndexError { kDrop, kKeep, kBuild };
3241  static Bool_t R__HandleIndex(EOnIndexError onIndexError, TTree *newtree, TTree *oldtree)
3242  {
3243  // Return true if we should continue to handle indices, false otherwise.
3244 
3245  Bool_t withIndex = kTRUE;
3246 
3247  if ( newtree->GetTreeIndex() ) {
3248  if ( oldtree->GetTree()->GetTreeIndex() == 0 ) {
3249  switch (onIndexError) {
3250  case kDrop:
3251  delete newtree->GetTreeIndex();
3252  newtree->SetTreeIndex(0);
3253  withIndex = kFALSE;
3254  break;
3255  case kKeep:
3256  // Nothing to do really.
3257  break;
3258  case kBuild:
3259  // Build the index then copy it
3260  if (oldtree->GetTree()->BuildIndex(newtree->GetTreeIndex()->GetMajorName(), newtree->GetTreeIndex()->GetMinorName())) {
3261  newtree->GetTreeIndex()->Append(oldtree->GetTree()->GetTreeIndex(), kTRUE);
3262  // Clean up
3263  delete oldtree->GetTree()->GetTreeIndex();
3264  oldtree->GetTree()->SetTreeIndex(0);
3265  }
3266  break;
3267  }
3268  } else {
3269  newtree->GetTreeIndex()->Append(oldtree->GetTree()->GetTreeIndex(), kTRUE);
3270  }
3271  } else if ( oldtree->GetTree()->GetTreeIndex() != 0 ) {
3272  // We discover the first index in the middle of the chain.
3273  switch (onIndexError) {
3274  case kDrop:
3275  // Nothing to do really.
3276  break;
3277  case kKeep: {
3278  TVirtualIndex *index = (TVirtualIndex*) oldtree->GetTree()->GetTreeIndex()->Clone();
3279  index->SetTree(newtree);
3280  newtree->SetTreeIndex(index);
3281  break;
3282  }
3283  case kBuild:
3284  if (newtree->GetEntries() == 0) {
3285  // Start an index.
3286  TVirtualIndex *index = (TVirtualIndex*) oldtree->GetTree()->GetTreeIndex()->Clone();
3287  index->SetTree(newtree);
3288  newtree->SetTreeIndex(index);
3289  } else {
3290  // Build the index so far.
3291  if (newtree->BuildIndex(oldtree->GetTree()->GetTreeIndex()->GetMajorName(), oldtree->GetTree()->GetTreeIndex()->GetMinorName())) {
3292  newtree->GetTreeIndex()->Append(oldtree->GetTree()->GetTreeIndex(), kTRUE);
3293  }
3294  }
3295  break;
3296  }
3297  } else if ( onIndexError == kDrop ) {
3298  // There is no index on this or on tree->GetTree(), we know we have to ignore any further
3299  // index
3300  withIndex = kFALSE;
3301  }
3302  return withIndex;
3303  }
3304 }
3305 
3306 ////////////////////////////////////////////////////////////////////////////////
3307 /// Copy nentries from given tree to this tree.
3308 /// This routines assumes that the branches that intended to be copied are
3309 /// already connected. The typical case is that this tree was created using
3310 /// tree->CloneTree(0).
3311 ///
3312 /// By default copy all entries.
3313 ///
3314 /// Returns number of bytes copied to this tree.
3315 ///
3316 /// If 'option' contains the word 'fast' and nentries is -1, the cloning will be
3317 /// done without unzipping or unstreaming the baskets (i.e., a direct copy of the
3318 /// raw bytes on disk).
3319 ///
3320 /// When 'fast' is specified, 'option' can also contains a sorting order for the
3321 /// baskets in the output file.
3322 ///
3323 /// There are currently 3 supported sorting order:
3324 ///
3325 /// - SortBasketsByOffset (the default)
3326 /// - SortBasketsByBranch
3327 /// - SortBasketsByEntry
3328 ///
3329 /// See TTree::CloneTree for a detailed explanation of the semantics of these 3 options.
3330 ///
3331 /// If the tree or any of the underlying tree of the chain has an index, that index and any
3332 /// index in the subsequent underlying TTree objects will be merged.
3333 ///
3334 /// There are currently three 'options' to control this merging:
3335 /// - NoIndex : all the TTreeIndex object are dropped.
3336 /// - DropIndexOnError : if any of the underlying TTree object do no have a TTreeIndex,
3337 /// they are all dropped.
3338 /// - AsIsIndexOnError [default]: In case of missing TTreeIndex, the resulting TTree index has gaps.
3339 /// - BuildIndexOnError : If any of the underlying TTree objects do not have a TTreeIndex,
3340 /// all TTreeIndex are 'ignored' and the missing piece are rebuilt.
3341 
3342 Long64_t TTree::CopyEntries(TTree* tree, Long64_t nentries /* = -1 */, Option_t* option /* = "" */)
3344  if (!tree) {
3345  return 0;
3346  }
3347  // Options
3348  TString opt = option;
3349  opt.ToLower();
3350  Bool_t fastClone = opt.Contains("fast");
3351  Bool_t withIndex = !opt.Contains("noindex");
3352  EOnIndexError onIndexError;
3353  if (opt.Contains("asisindex")) {
3354  onIndexError = kKeep;
3355  } else if (opt.Contains("buildindex")) {
3356  onIndexError = kBuild;
3357  } else if (opt.Contains("dropindex")) {
3358  onIndexError = kDrop;
3359  } else {
3360  onIndexError = kBuild;
3361  }
3362  Ssiz_t cacheSizeLoc = opt.Index("cachesize=");
3363  Int_t cacheSize = -1;
3364  if (cacheSizeLoc != TString::kNPOS) {
3365  // If the parse faile, cacheSize stays at -1.
3366  Ssiz_t cacheSizeEnd = opt.Index(" ",cacheSizeLoc+10) - (cacheSizeLoc+10);
3367  TSubString cacheSizeStr( opt(cacheSizeLoc+10,cacheSizeEnd) );
3368  auto parseResult = ROOT::FromHumanReadableSize(cacheSizeStr,cacheSize);
3369  if (parseResult == ROOT::EFromHumanReadableSize::kParseFail) {
3370  Warning("CopyEntries","The cachesize option can not be parsed: %s. The default size will be used.",cacheSizeStr.String().Data());
3371  } else if (parseResult == ROOT::EFromHumanReadableSize::kOverflow) {
3372  double m;
3373  const char *munit = nullptr;
3374  ROOT::ToHumanReadableSize(std::numeric_limits<decltype(cacheSize)>::max(),false,&m,&munit);
3375 
3376  Warning("CopyEntries","The cachesize option is too large: %s (%g%s max). The default size will be used.",cacheSizeStr.String().Data(),m,munit);
3377  }
3378  }
3379  if (gDebug > 0 && cacheSize != -1) Info("CopyEntries","Using Cache size: %d\n",cacheSize);
3380 
3381  Long64_t nbytes = 0;
3382  Long64_t treeEntries = tree->GetEntriesFast();
3383  if (nentries < 0) {
3384  nentries = treeEntries;
3385  } else if (nentries > treeEntries) {
3386  nentries = treeEntries;
3387  }
3388 
3389  if (fastClone && (nentries < 0 || nentries == tree->GetEntriesFast())) {
3390  // Quickly copy the basket without decompression and streaming.
3391  Long64_t totbytes = GetTotBytes();
3392  for (Long64_t i = 0; i < nentries; i += tree->GetTree()->GetEntries()) {
3393  if (tree->LoadTree(i) < 0) {
3394  break;
3395  }
3396  if ( withIndex ) {
3397  withIndex = R__HandleIndex( onIndexError, this, tree );
3398  }
3399  if (this->GetDirectory()) {
3400  TFile* file2 = this->GetDirectory()->GetFile();
3401  if (file2 && (file2->GetEND() > TTree::GetMaxTreeSize())) {
3402  if (this->GetDirectory() == (TDirectory*) file2) {
3403  this->ChangeFile(file2);
3404  }
3405  }
3406  }
3407  TTreeCloner cloner(tree->GetTree(), this, option, TTreeCloner::kNoWarnings);
3408  if (cloner.IsValid()) {
3409  this->SetEntries(this->GetEntries() + tree->GetTree()->GetEntries());
3410  if (cacheSize != -1) cloner.SetCacheSize(cacheSize);
3411  cloner.Exec();
3412  } else {
3413  if (i == 0) {
3414  Warning("CopyEntries","%s",cloner.GetWarning());
3415  // If the first cloning does not work, something is really wrong
3416  // (since apriori the source and target are exactly the same structure!)
3417  return -1;
3418  } else {
3419  if (cloner.NeedConversion()) {
3420  TTree *localtree = tree->GetTree();
3421  Long64_t tentries = localtree->GetEntries();
3422  for (Long64_t ii = 0; ii < tentries; ii++) {
3423  if (localtree->GetEntry(ii) <= 0) {
3424  break;
3425  }
3426  this->Fill();
3427  }
3428  if (this->GetTreeIndex()) {
3429  this->GetTreeIndex()->Append(tree->GetTree()->GetTreeIndex(), kTRUE);
3430  }
3431  } else {
3432  Warning("CopyEntries","%s",cloner.GetWarning());
3433  if (tree->GetDirectory() && tree->GetDirectory()->GetFile()) {
3434  Warning("CopyEntries", "Skipped file %s\n", tree->GetDirectory()->GetFile()->GetName());
3435  } else {
3436  Warning("CopyEntries", "Skipped file number %d\n", tree->GetTreeNumber());
3437  }
3438  }
3439  }
3440  }
3441 
3442  }
3443  if (this->GetTreeIndex()) {
3444  this->GetTreeIndex()->Append(0,kFALSE); // Force the sorting
3445  }
3446  nbytes = GetTotBytes() - totbytes;
3447  } else {
3448  if (nentries < 0) {
3449  nentries = treeEntries;
3450  } else if (nentries > treeEntries) {
3451  nentries = treeEntries;
3452  }
3453  Int_t treenumber = -1;
3454  for (Long64_t i = 0; i < nentries; i++) {
3455  if (tree->LoadTree(i) < 0) {
3456  break;
3457  }
3458  if (treenumber != tree->GetTreeNumber()) {
3459  if ( withIndex ) {
3460  withIndex = R__HandleIndex( onIndexError, this, tree );
3461  }
3462  treenumber = tree->GetTreeNumber();
3463  }
3464  if (tree->GetEntry(i) <= 0) {
3465  break;
3466  }
3467  nbytes += this->Fill();
3468  }
3469  if (this->GetTreeIndex()) {
3470  this->GetTreeIndex()->Append(0,kFALSE); // Force the sorting
3471  }
3472  }
3473  return nbytes;
3474 }
3475 
3476 ////////////////////////////////////////////////////////////////////////////////
3477 /// Copy a tree with selection.
3478 ///
3479 /// ### Important:
3480 ///
3481 /// The returned copied tree stays connected with the original tree
3482 /// until the original tree is deleted. In particular, any changes
3483 /// to the branch addresses in the original tree are also made to
3484 /// the copied tree. Any changes made to the branch addresses of the
3485 /// copied tree are overridden anytime the original tree changes its
3486 /// branch addresses. When the original tree is deleted, all the
3487 /// branch addresses of the copied tree are set to zero.
3488 ///
3489 /// For examples of CopyTree, see the tutorials:
3490 ///
3491 /// - copytree.C:
3492 /// Example macro to copy a subset of a tree to a new tree.
3493 /// The input file was generated by running the program in
3494 /// $ROOTSYS/test/Event in this way:
3495 /// ~~~ {.cpp}
3496 /// ./Event 1000 1 1 1
3497 /// ~~~
3498 /// - copytree2.C
3499 /// Example macro to copy a subset of a tree to a new tree.
3500 /// One branch of the new tree is written to a separate file.
3501 /// The input file was generated by running the program in
3502 /// $ROOTSYS/test/Event in this way:
3503 /// ~~~ {.cpp}
3504 /// ./Event 1000 1 1 1
3505 /// ~~~
3506 /// - copytree3.C
3507 /// Example macro to copy a subset of a tree to a new tree.
3508 /// Only selected entries are copied to the new tree.
3509 /// NOTE that only the active branches are copied.
3510 
3511 TTree* TTree::CopyTree(const char* selection, Option_t* option /* = 0 */, Long64_t nentries /* = TTree::kMaxEntries */, Long64_t firstentry /* = 0 */)
3513  GetPlayer();
3514  if (fPlayer) {
3515  return fPlayer->CopyTree(selection, option, nentries, firstentry);
3516  }
3517  return 0;
3518 }
3519 
3520 ////////////////////////////////////////////////////////////////////////////////
3521 /// Create a basket for this tree and given branch.
3522 
3525  if (!branch) {
3526  return 0;
3527  }
3528  return new TBasket(branch->GetName(), GetName(), branch);
3529 }
3530 
3531 ////////////////////////////////////////////////////////////////////////////////
3532 /// Delete this tree from memory or/and disk.
3533 ///
3534 /// - if option == "all" delete Tree object from memory AND from disk
3535 /// all baskets on disk are deleted. All keys with same name
3536 /// are deleted.
3537 /// - if option =="" only Tree object in memory is deleted.
3538 
3539 void TTree::Delete(Option_t* option /* = "" */)
3541  TFile *file = GetCurrentFile();
3542 
3543  // delete all baskets and header from file
3544  if (file && !strcmp(option,"all")) {
3545  if (!file->IsWritable()) {
3546  Error("Delete","File : %s is not writable, cannot delete Tree:%s", file->GetName(),GetName());
3547  return;
3548  }
3549 
3550  //find key and import Tree header in memory
3551  TKey *key = fDirectory->GetKey(GetName());
3552  if (!key) return;
3553 
3554  TDirectory *dirsav = gDirectory;
3555  file->cd();
3556 
3557  //get list of leaves and loop on all the branches baskets
3558  TIter next(GetListOfLeaves());
3559  TLeaf *leaf;
3560  char header[16];
3561  Int_t ntot = 0;
3562  Int_t nbask = 0;
3563  Int_t nbytes,objlen,keylen;
3564  while ((leaf = (TLeaf*)next())) {
3565  TBranch *branch = leaf->GetBranch();
3566  Int_t nbaskets = branch->GetMaxBaskets();
3567  for (Int_t i=0;i<nbaskets;i++) {
3568  Long64_t pos = branch->GetBasketSeek(i);
3569  if (!pos) continue;
3570  TFile *branchFile = branch->GetFile();
3571  if (!branchFile) continue;
3572  branchFile->GetRecordHeader(header,pos,16,nbytes,objlen,keylen);
3573  if (nbytes <= 0) continue;
3574  branchFile->MakeFree(pos,pos+nbytes-1);
3575  ntot += nbytes;
3576  nbask++;
3577  }
3578  }
3579 
3580  // delete Tree header key and all keys with the same name
3581  // A Tree may have been saved many times. Previous cycles are invalid.
3582  while (key) {
3583  ntot += key->GetNbytes();
3584  key->Delete();
3585  delete key;
3586  key = fDirectory->GetKey(GetName());
3587  }
3588  if (dirsav) dirsav->cd();
3589  if (gDebug) Info("TTree::Delete", "Deleting Tree: %s: %d baskets deleted. Total space freed = %d bytes\n",GetName(),nbask,ntot);
3590  }
3591 
3592  if (fDirectory) {
3593  fDirectory->Remove(this);
3594  //delete the file cache if it points to this Tree
3595  MoveReadCache(file,0);
3596  fDirectory = 0;
3598  }
3599 
3600  // Delete object from CINT symbol table so it can not be used anymore.
3601  gCling->DeleteGlobal(this);
3602 
3603  // Warning: We have intentional invalidated this object while inside a member function!
3604  delete this;
3605 }
3606 
3607  ///////////////////////////////////////////////////////////////////////////////
3608  /// Called by TKey and TObject::Clone to automatically add us to a directory
3609  /// when we are read from a file.
3610 
3613  if (fDirectory == dir) return;
3614  if (fDirectory) {
3615  fDirectory->Remove(this);
3616  // Delete or move the file cache if it points to this Tree
3617  TFile *file = fDirectory->GetFile();
3618  MoveReadCache(file,dir);
3619  }
3620  fDirectory = dir;
3621  TBranch* b = 0;
3622  TIter next(GetListOfBranches());
3623  while((b = (TBranch*) next())) {
3624  b->UpdateFile();
3625  }
3626  if (fBranchRef) {
3628  }
3629  if (fDirectory) fDirectory->Append(this);
3630 }
3631 
3632 ////////////////////////////////////////////////////////////////////////////////
3633 /// Draw expression varexp for specified entries.
3634 ///
3635 /// \return -1 in case of error or number of selected events in case of success.
3636 ///
3637 /// This function accepts TCut objects as arguments.
3638 /// Useful to use the string operator +
3639 ///
3640 /// Example:
3641 ///
3642 /// ~~~ {.cpp}
3643 /// ntuple.Draw("x",cut1+cut2+cut3);
3644 /// ~~~
3645 
3646 
3647 Long64_t TTree::Draw(const char* varexp, const TCut& selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
3649  return TTree::Draw(varexp, selection.GetTitle(), option, nentries, firstentry);
3650 }
3651 
3652 ////////////////////////////////////////////////////////////////////////////////
3653 /// Draw expression varexp for specified entries.
3654 ///
3655 /// \return -1 in case of error or number of selected events in case of success.
3656 ///
3657 /// \param [in] varexp is an expression of the general form
3658 /// - "e1" produces a 1-d histogram (TH1F) of expression "e1"
3659 /// - "e1:e2" produces an unbinned 2-d scatter-plot (TGraph) of "e1"
3660 /// on the y-axis versus "e2" on the x-axis
3661 /// - "e1:e2:e3" produces an unbinned 3-d scatter-plot (TPolyMarker3D) of "e1"
3662 /// vs "e2" vs "e3" on the x-, y-, z-axis, respectively.
3663 /// - "e1:e2:e3:e4" produces an unbinned 3-d scatter-plot (TPolyMarker3D) of "e1"
3664 /// vs "e2" vs "e3" and "e4" mapped on the current color palette.
3665 /// (to create histograms in the 2, 3, and 4 dimensional case,
3666 /// see section "Saving the result of Draw to an histogram")
3667 ///
3668 /// Example:
3669 /// - varexp = x simplest case: draw a 1-Dim distribution of column named x
3670 /// - varexp = sqrt(x) : draw distribution of sqrt(x)
3671 /// - varexp = x*y/z
3672 /// - varexp = y:sqrt(x) 2-Dim distribution of y versus sqrt(x)
3673 /// - varexp = px:py:pz:2.5*E produces a 3-d scatter-plot of px vs py ps pz
3674 /// and the color number of each marker will be 2.5*E.
3675 /// If the color number is negative it is set to 0.
3676 /// If the color number is greater than the current number of colors
3677 /// it is set to the highest color number.The default number of
3678 /// colors is 50. see TStyle::SetPalette for setting a new color palette.
3679 ///
3680 /// Note that the variables e1, e2 or e3 may contain a selection.
3681 /// example, if e1= x*(y<0), the value histogrammed will be x if y<0
3682 /// and will be 0 otherwise.
3683 ///
3684 /// The expressions can use all the operations and build-in functions
3685 /// supported by TFormula (See TFormula::Analyze), including free
3686 /// standing function taking numerical arguments (TMath::Bessel).
3687 /// In addition, you can call member functions taking numerical
3688 /// arguments. For example:
3689 /// ~~~ {.cpp}
3690 /// TMath::BreitWigner(fPx,3,2)
3691 /// event.GetHistogram().GetXaxis().GetXmax()
3692 /// ~~~
3693 /// Note: You can only pass expression that depend on the TTree's data
3694 /// to static functions and you can only call non-static member function
3695 /// with 'fixed' parameters.
3696 ///
3697 /// \param [in] selection is an expression with a combination of the columns.
3698 /// In a selection all the C++ operators are authorized.
3699 /// The value corresponding to the selection expression is used as a weight
3700 /// to fill the histogram.
3701 /// If the expression includes only boolean operations, the result
3702 /// is 0 or 1. If the result is 0, the histogram is not filled.
3703 /// In general, the expression may be of the form:
3704 /// ~~~ {.cpp}
3705 /// value*(boolean expression)
3706 /// ~~~
3707 /// if boolean expression is true, the histogram is filled with
3708 /// a `weight = value`.
3709 /// Examples:
3710 /// - selection1 = "x<y && sqrt(z)>3.2"
3711 /// - selection2 = "(x+y)*(sqrt(z)>3.2)"
3712 /// - selection1 returns a weight = 0 or 1
3713 /// - selection2 returns a weight = x+y if sqrt(z)>3.2
3714 /// returns a weight = 0 otherwise.
3715 ///
3716 /// \param [in] option is the drawing option.
3717 /// - When an histogram is produced it can be any histogram drawing option
3718 /// listed in THistPainter.
3719 /// - when no option is specified:
3720 /// - the default histogram drawing option is used
3721 /// if the expression is of the form "e1".
3722 /// - if the expression is of the form "e1:e2"or "e1:e2:e3" a cloud of
3723 /// unbinned 2D or 3D points is drawn respectively.
3724 /// - if the expression has four fields "e1:e2:e3:e4" a 2D scatter is
3725 /// produced with e1 vs e2 vs e3, and e4 is mapped on the current color
3726 /// palette.
3727 /// - If option COL is specified when varexp has three fields:
3728 /// ~~~ {.cpp}
3729 /// tree.Draw("e1:e2:e3","","col");
3730 /// ~~~
3731 /// a 2D scatter is produced with e1 vs e2, and e3 is mapped on the current
3732 /// color palette. The colors for e3 are evaluated once in linear scale before
3733 /// painting. Therefore changing the pad to log scale along Z as no effect
3734 /// on the colors.
3735 /// - if expression has more than four fields the option "PARA"or "CANDLE"
3736 /// can be used.
3737 /// - If option contains the string "goff", no graphics is generated.
3738 ///
3739 /// \param [in] nentries is the number of entries to process (default is all)
3740 ///
3741 /// \param [in] firstentry is the first entry to process (default is 0)
3742 ///
3743 /// ### Drawing expressions using arrays and array elements
3744 ///
3745 /// Let assumes, a leaf fMatrix, on the branch fEvent, which is a 3 by 3 array,
3746 /// or a TClonesArray.
3747 /// In a TTree::Draw expression you can now access fMatrix using the following
3748 /// syntaxes:
3749 ///
3750 /// | String passed | What is used for each entry of the tree
3751 /// |-----------------|--------------------------------------------------------|
3752 /// | `fMatrix` | the 9 elements of fMatrix |
3753 /// | `fMatrix[][]` | the 9 elements of fMatrix |
3754 /// | `fMatrix[2][2]` | only the elements fMatrix[2][2] |
3755 /// | `fMatrix[1]` | the 3 elements fMatrix[1][0], fMatrix[1][1] and fMatrix[1][2] |
3756 /// | `fMatrix[1][]` | the 3 elements fMatrix[1][0], fMatrix[1][1] and fMatrix[1][2] |
3757 /// | `fMatrix[][0]` | the 3 elements fMatrix[0][0], fMatrix[1][0] and fMatrix[2][0] |
3758 ///
3759 /// "fEvent.fMatrix...." same as "fMatrix..." (unless there is more than one leaf named fMatrix!).
3760 ///
3761 /// In summary, if a specific index is not specified for a dimension, TTree::Draw
3762 /// will loop through all the indices along this dimension. Leaving off the
3763 /// last (right most) dimension of specifying then with the two characters '[]'
3764 /// is equivalent. For variable size arrays (and TClonesArray) the range
3765 /// of the first dimension is recalculated for each entry of the tree.
3766 /// You can also specify the index as an expression of any other variables from the
3767 /// tree.
3768 ///
3769 /// TTree::Draw also now properly handling operations involving 2 or more arrays.
3770 ///
3771 /// Let assume a second matrix fResults[5][2], here are a sample of some
3772 /// of the possible combinations, the number of elements they produce and
3773 /// the loop used:
3774 ///
3775 /// | expression | element(s) | Loop |
3776 /// |----------------------------------|------------|--------------------------|
3777 /// | `fMatrix[2][1] - fResults[5][2]` | one | no loop |
3778 /// | `fMatrix[2][] - fResults[5][2]` | three | on 2nd dim fMatrix |
3779 /// | `fMatrix[2][] - fResults[5][]` | two | on both 2nd dimensions |
3780 /// | `fMatrix[][2] - fResults[][1]` | three | on both 1st dimensions |
3781 /// | `fMatrix[][2] - fResults[][]` | six | on both 1st and 2nd dimensions of fResults |
3782 /// | `fMatrix[][2] - fResults[3][]` | two | on 1st dim of fMatrix and 2nd of fResults (at the same time) |
3783 /// | `fMatrix[][] - fResults[][]` | six | on 1st dim then on 2nd dim |
3784 /// | `fMatrix[][fResult[][]]` | 30 | on 1st dim of fMatrix then on both dimensions of fResults. The value if fResults[j][k] is used as the second index of fMatrix.|
3785 ///
3786 ///
3787 /// In summary, TTree::Draw loops through all unspecified dimensions. To
3788 /// figure out the range of each loop, we match each unspecified dimension
3789 /// from left to right (ignoring ALL dimensions for which an index has been
3790 /// specified), in the equivalent loop matched dimensions use the same index
3791 /// and are restricted to the smallest range (of only the matched dimensions).
3792 /// When involving variable arrays, the range can of course be different
3793 /// for each entry of the tree.
3794 ///
3795 /// So the loop equivalent to "fMatrix[][2] - fResults[3][]" is:
3796 /// ~~~ {.cpp}
3797 /// for (Int_t i0; i < min(3,2); i++) {
3798 /// use the value of (fMatrix[i0][2] - fMatrix[3][i0])
3799 /// }
3800 /// ~~~
3801 /// So the loop equivalent to "fMatrix[][2] - fResults[][]" is:
3802 /// ~~~ {.cpp}
3803 /// for (Int_t i0; i < min(3,5); i++) {
3804 /// for (Int_t i1; i1 < 2; i1++) {
3805 /// use the value of (fMatrix[i0][2] - fMatrix[i0][i1])
3806 /// }
3807 /// }
3808 /// ~~~
3809 /// So the loop equivalent to "fMatrix[][] - fResults[][]" is:
3810 /// ~~~ {.cpp}
3811 /// for (Int_t i0; i < min(3,5); i++) {
3812 /// for (Int_t i1; i1 < min(3,2); i1++) {
3813 /// use the value of (fMatrix[i0][i1] - fMatrix[i0][i1])
3814 /// }
3815 /// }
3816 /// ~~~
3817 /// So the loop equivalent to "fMatrix[][fResults[][]]" is:
3818 /// ~~~ {.cpp}
3819 /// for (Int_t i0; i0 < 3; i0++) {
3820 /// for (Int_t j2; j2 < 5; j2++) {
3821 /// for (Int_t j3; j3 < 2; j3++) {
3822 /// i1 = fResults[j2][j3];
3823 /// use the value of fMatrix[i0][i1]
3824 /// }
3825 /// }
3826 /// ~~~
3827 /// ### Retrieving the result of Draw
3828 ///
3829 /// By default the temporary histogram created is called "htemp", but only in
3830 /// the one dimensional Draw("e1") it contains the TTree's data points. For
3831 /// a two dimensional Draw, the data is filled into a TGraph which is named
3832 /// "Graph". They can be retrieved by calling
3833 /// ~~~ {.cpp}
3834 /// TH1F *htemp = (TH1F*)gPad->GetPrimitive("htemp"); // 1D
3835 /// TGraph *graph = (TGraph*)gPad->GetPrimitive("Graph"); // 2D
3836 /// ~~~
3837 /// For a three and four dimensional Draw the TPolyMarker3D is unnamed, and
3838 /// cannot be retrieved.
3839 ///
3840 /// gPad always contains a TH1 derived object called "htemp" which allows to
3841 /// access the axes:
3842 /// ~~~ {.cpp}
3843 /// TGraph *graph = (TGraph*)gPad->GetPrimitive("Graph"); // 2D
3844 /// TH2F *htemp = (TH2F*)gPad->GetPrimitive("htemp"); // empty, but has axes
3845 /// TAxis *xaxis = htemp->GetXaxis();
3846 /// ~~~
3847 /// ### Saving the result of Draw to an histogram
3848 ///
3849 /// If varexp0 contains >>hnew (following the variable(s) name(s),
3850 /// the new histogram created is called hnew and it is kept in the current
3851 /// directory (and also the current pad). This works for all dimensions.
3852 ///
3853 /// Example:
3854 /// ~~~ {.cpp}
3855 /// tree.Draw("sqrt(x)>>hsqrt","y>0")
3856 /// ~~~
3857 /// will draw `sqrt(x)` and save the histogram as "hsqrt" in the current
3858 /// directory. To retrieve it do:
3859 /// ~~~ {.cpp}
3860 /// TH1F *hsqrt = (TH1F*)gDirectory->Get("hsqrt");
3861 /// ~~~
3862 /// The binning information is taken from the environment variables
3863 /// ~~~ {.cpp}
3864 /// Hist.Binning.?D.?
3865 /// ~~~
3866 /// In addition, the name of the histogram can be followed by up to 9
3867 /// numbers between '(' and ')', where the numbers describe the
3868 /// following:
3869 ///
3870 /// - 1 - bins in x-direction
3871 /// - 2 - lower limit in x-direction
3872 /// - 3 - upper limit in x-direction
3873 /// - 4-6 same for y-direction
3874 /// - 7-9 same for z-direction
3875 ///
3876 /// When a new binning is used the new value will become the default.
3877 /// Values can be skipped.
3878 ///
3879 /// Example:
3880 /// ~~~ {.cpp}
3881 /// tree.Draw("sqrt(x)>>hsqrt(500,10,20)")
3882 /// // plot sqrt(x) between 10 and 20 using 500 bins
3883 /// tree.Draw("sqrt(x):sin(y)>>hsqrt(100,10,60,50,.1,.5)")
3884 /// // plot sqrt(x) against sin(y)
3885 /// // 100 bins in x-direction; lower limit on x-axis is 10; upper limit is 60
3886 /// // 50 bins in y-direction; lower limit on y-axis is .1; upper limit is .5
3887 /// ~~~
3888 /// By default, the specified histogram is reset.
3889 /// To continue to append data to an existing histogram, use "+" in front
3890 /// of the histogram name.
3891 ///
3892 /// A '+' in front of the histogram name is ignored, when the name is followed by
3893 /// binning information as described in the previous paragraph.
3894 /// ~~~ {.cpp}
3895 /// tree.Draw("sqrt(x)>>+hsqrt","y>0")
3896 /// ~~~
3897 /// will not reset `hsqrt`, but will continue filling. This works for 1-D, 2-D
3898 /// and 3-D histograms.
3899 ///
3900 /// ### Accessing collection objects
3901 ///
3902 /// TTree::Draw default's handling of collections is to assume that any
3903 /// request on a collection pertain to it content. For example, if fTracks
3904 /// is a collection of Track objects, the following:
3905 /// ~~~ {.cpp}
3906 /// tree->Draw("event.fTracks.fPx");
3907 /// ~~~
3908 /// will plot the value of fPx for each Track objects inside the collection.
3909 /// Also
3910 /// ~~~ {.cpp}
3911 /// tree->Draw("event.fTracks.size()");
3912 /// ~~~
3913 /// would plot the result of the member function Track::size() for each
3914 /// Track object inside the collection.
3915 /// To access information about the collection itself, TTree::Draw support
3916 /// the '@' notation. If a variable which points to a collection is prefixed
3917 /// or postfixed with '@', the next part of the expression will pertain to
3918 /// the collection object. For example:
3919 /// ~~~ {.cpp}
3920 /// tree->Draw("event.@fTracks.size()");
3921 /// ~~~
3922 /// will plot the size of the collection referred to by `fTracks` (i.e the number
3923 /// of Track objects).
3924 ///
3925 /// ### Drawing 'objects'
3926 ///
3927 /// When a class has a member function named AsDouble or AsString, requesting
3928 /// to directly draw the object will imply a call to one of the 2 functions.
3929 /// If both AsDouble and AsString are present, AsDouble will be used.
3930 /// AsString can return either a char*, a std::string or a TString.s
3931 /// For example, the following
3932 /// ~~~ {.cpp}
3933 /// tree->Draw("event.myTTimeStamp");
3934 /// ~~~
3935 /// will draw the same histogram as
3936 /// ~~~ {.cpp}
3937 /// tree->Draw("event.myTTimeStamp.AsDouble()");
3938 /// ~~~
3939 /// In addition, when the object is a type TString or std::string, TTree::Draw
3940 /// will call respectively `TString::Data` and `std::string::c_str()`
3941 ///
3942 /// If the object is a TBits, the histogram will contain the index of the bit
3943 /// that are turned on.
3944 ///
3945 /// ### Retrieving information about the tree itself.
3946 ///
3947 /// You can refer to the tree (or chain) containing the data by using the
3948 /// string 'This'.
3949 /// You can then could any TTree methods. For example:
3950 /// ~~~ {.cpp}
3951 /// tree->Draw("This->GetReadEntry()");
3952 /// ~~~
3953 /// will display the local entry numbers be read.
3954 /// ~~~ {.cpp}
3955 /// tree->Draw("This->GetUserInfo()->At(0)->GetName()");
3956 /// ~~~
3957 /// will display the name of the first 'user info' object.
3958 ///
3959 /// ### Special functions and variables
3960 ///
3961 /// `Entry$`: A TTree::Draw formula can use the special variable `Entry$`
3962 /// to access the entry number being read. For example to draw every
3963 /// other entry use:
3964 /// ~~~ {.cpp}
3965 /// tree.Draw("myvar","Entry$%2==0");
3966 /// ~~~
3967 /// - `Entry$` : return the current entry number (`== TTree::GetReadEntry()`)
3968 /// - `LocalEntry$` : return the current entry number in the current tree of a
3969 /// chain (`== GetTree()->GetReadEntry()`)
3970 /// - `Entries$` : return the total number of entries (== TTree::GetEntries())
3971 /// - `LocalEntries$` : return the total number of entries in the current tree
3972 /// of a chain (== GetTree()->TTree::GetEntries())
3973 /// - `Length$` : return the total number of element of this formula for this
3974 /// entry (`==TTreeFormula::GetNdata()`)
3975 /// - `Iteration$` : return the current iteration over this formula for this
3976 /// entry (i.e. varies from 0 to `Length$`).
3977 /// - `Length$(formula )` : return the total number of element of the formula
3978 /// given as a parameter.
3979 /// - `Sum$(formula )` : return the sum of the value of the elements of the
3980 /// formula given as a parameter. For example the mean for all the elements in
3981 /// one entry can be calculated with: `Sum$(formula )/Length$(formula )`
3982 /// - `Min$(formula )` : return the minimun (within one TTree entry) of the value of the
3983 /// elements of the formula given as a parameter.
3984 /// - `Max$(formula )` : return the maximum (within one TTree entry) of the value of the
3985 /// elements of the formula given as a parameter.
3986 /// - `MinIf$(formula,condition)`
3987 /// - `MaxIf$(formula,condition)` : return the minimum (maximum) (within one TTree entry)
3988 /// of the value of the elements of the formula given as a parameter
3989 /// if they match the condition. If no element matches the condition,
3990 /// the result is zero. To avoid the resulting peak at zero, use the
3991 /// pattern:
3992 /// ~~~ {.cpp}
3993 /// tree->Draw("MinIf$(formula,condition)","condition");
3994 /// ~~~
3995 /// which will avoid calculation `MinIf$` for the entries that have no match
3996 /// for the condition.
3997 /// - `Alt$(primary,alternate)` : return the value of "primary" if it is available
3998 /// for the current iteration otherwise return the value of "alternate".
3999 /// For example, with arr1[3] and arr2[2]
4000 /// ~~~ {.cpp}
4001 /// tree->Draw("arr1+Alt$(arr2,0)");
4002 /// ~~~
4003 /// will draw arr1[0]+arr2[0] ; arr1[1]+arr2[1] and arr1[2]+0
4004 /// Or with a variable size array arr3
4005 /// ~~~ {.cpp}
4006 /// tree->Draw("Alt$(arr3[0],0)+Alt$(arr3[1],0)+Alt$(arr3[2],0)");
4007 /// ~~~
4008 /// will draw the sum arr3 for the index 0 to min(2,actual_size_of_arr3-1)
4009 /// As a comparison
4010 /// ~~~ {.cpp}
4011 /// tree->Draw("arr3[0]+arr3[1]+arr3[2]");
4012 /// ~~~
4013 /// will draw the sum arr3 for the index 0 to 2 only if the
4014 /// actual_size_of_arr3 is greater or equal to 3.
4015 /// Note that the array in 'primary' is flattened/linearized thus using
4016 /// `Alt$` with multi-dimensional arrays of different dimensions in unlikely
4017 /// to yield the expected results. To visualize a bit more what elements
4018 /// would be matched by TTree::Draw, TTree::Scan can be used:
4019 /// ~~~ {.cpp}
4020 /// tree->Scan("arr1:Alt$(arr2,0)");
4021 /// ~~~
4022 /// will print on one line the value of arr1 and (arr2,0) that will be
4023 /// matched by
4024 /// ~~~ {.cpp}
4025 /// tree->Draw("arr1-Alt$(arr2,0)");
4026 /// ~~~
4027 /// The ternary operator is not directly supported in TTree::Draw however, to plot the
4028 /// equivalent of `var2<20 ? -99 : var1`, you can use:
4029 /// ~~~ {.cpp}
4030 /// tree->Draw("(var2<20)*99+(var2>=20)*var1","");
4031 /// ~~~
4032 ///
4033 /// ### Drawing a user function accessing the TTree data directly
4034 ///
4035 /// If the formula contains a file name, TTree::MakeProxy will be used
4036 /// to load and execute this file. In particular it will draw the
4037 /// result of a function with the same name as the file. The function
4038 /// will be executed in a context where the name of the branches can
4039 /// be used as a C++ variable.
4040 ///
4041 /// For example draw px using the file hsimple.root (generated by the
4042 /// hsimple.C tutorial), we need a file named hsimple.cxx:
4043 /// ~~~ {.cpp}
4044 /// double hsimple() {
4045 /// return px;
4046 /// }
4047 /// ~~~
4048 /// MakeProxy can then be used indirectly via the TTree::Draw interface
4049 /// as follow:
4050 /// ~~~ {.cpp}
4051 /// new TFile("hsimple.root")
4052 /// ntuple->Draw("hsimple.cxx");
4053 /// ~~~
4054 /// A more complete example is available in the tutorials directory:
4055 /// `h1analysisProxy.cxx`, `h1analysProxy.h` and `h1analysisProxyCut.C`
4056 /// which reimplement the selector found in `h1analysis.C`
4057 ///
4058 /// The main features of this facility are:
4059 ///
4060 /// * on-demand loading of branches
4061 /// * ability to use the 'branchname' as if it was a data member
4062 /// * protection against array out-of-bound
4063 /// * ability to use the branch data as object (when the user code is available)
4064 ///
4065 /// See TTree::MakeProxy for more details.
4066 ///
4067 /// ### Making a Profile histogram
4068 ///
4069 /// In case of a 2-Dim expression, one can generate a TProfile histogram
4070 /// instead of a TH2F histogram by specifying option=prof or option=profs
4071 /// or option=profi or option=profg ; the trailing letter select the way
4072 /// the bin error are computed, See TProfile2D::SetErrorOption for
4073 /// details on the differences.
4074 /// The option=prof is automatically selected in case of y:x>>pf
4075 /// where pf is an existing TProfile histogram.
4076 ///
4077 /// ### Making a 2D Profile histogram
4078 ///
4079 /// In case of a 3-Dim expression, one can generate a TProfile2D histogram
4080 /// instead of a TH3F histogram by specifying option=prof or option=profs.
4081 /// or option=profi or option=profg ; the trailing letter select the way
4082 /// the bin error are computed, See TProfile2D::SetErrorOption for
4083 /// details on the differences.
4084 /// The option=prof is automatically selected in case of z:y:x>>pf
4085 /// where pf is an existing TProfile2D histogram.
4086 ///
4087 /// ### Making a 5D plot using GL
4088 ///
4089 /// If option GL5D is specified together with 5 variables, a 5D plot is drawn
4090 /// using OpenGL. See $ROOTSYS/tutorials/tree/staff.C as example.
4091 ///
4092 /// ### Making a parallel coordinates plot
4093 ///
4094 /// In case of a 2-Dim or more expression with the option=para, one can generate
4095 /// a parallel coordinates plot. With that option, the number of dimensions is
4096 /// arbitrary. Giving more than 4 variables without the option=para or
4097 /// option=candle or option=goff will produce an error.
4098 ///
4099 /// ### Making a candle sticks chart
4100 ///
4101 /// In case of a 2-Dim or more expression with the option=candle, one can generate
4102 /// a candle sticks chart. With that option, the number of dimensions is
4103 /// arbitrary. Giving more than 4 variables without the option=para or
4104 /// option=candle or option=goff will produce an error.
4105 ///
4106 /// ### Normalizing the output histogram to 1
4107 ///
4108 /// When option contains "norm" the output histogram is normalized to 1.
4109 ///
4110 /// ### Saving the result of Draw to a TEventList, a TEntryList or a TEntryListArray
4111 ///
4112 /// TTree::Draw can be used to fill a TEventList object (list of entry numbers)
4113 /// instead of histogramming one variable.
4114 /// If varexp0 has the form >>elist , a TEventList object named "elist"
4115 /// is created in the current directory. elist will contain the list
4116 /// of entry numbers satisfying the current selection.
4117 /// If option "entrylist" is used, a TEntryList object is created
4118 /// If the selection contains arrays, vectors or any container class and option
4119 /// "entrylistarray" is used, a TEntryListArray object is created
4120 /// containing also the subentries satisfying the selection, i.e. the indices of
4121 /// the branches which hold containers classes.
4122 /// Example:
4123 /// ~~~ {.cpp}
4124 /// tree.Draw(">>yplus","y>0")
4125 /// ~~~
4126 /// will create a TEventList object named "yplus" in the current directory.
4127 /// In an interactive session, one can type (after TTree::Draw)
4128 /// ~~~ {.cpp}
4129 /// yplus.Print("all")
4130 /// ~~~
4131 /// to print the list of entry numbers in the list.
4132 /// ~~~ {.cpp}
4133 /// tree.Draw(">>yplus", "y>0", "entrylist")
4134 /// ~~~
4135 /// will create a TEntryList object names "yplus" in the current directory
4136 /// ~~~ {.cpp}
4137 /// tree.Draw(">>yplus", "y>0", "entrylistarray")
4138 /// ~~~
4139 /// will create a TEntryListArray object names "yplus" in the current directory
4140 ///
4141 /// By default, the specified entry list is reset.
4142 /// To continue to append data to an existing list, use "+" in front
4143 /// of the list name;
4144 /// ~~~ {.cpp}
4145 /// tree.Draw(">>+yplus","y>0")
4146 /// ~~~
4147 /// will not reset yplus, but will enter the selected entries at the end
4148 /// of the existing list.
4149 ///
4150 /// ### Using a TEventList, TEntryList or TEntryListArray as Input
4151 ///
4152 /// Once a TEventList or a TEntryList object has been generated, it can be used as input
4153 /// for TTree::Draw. Use TTree::SetEventList or TTree::SetEntryList to set the
4154 /// current event list
4155 ///
4156 /// Example 1:
4157 /// ~~~ {.cpp}
4158 /// TEventList *elist = (TEventList*)gDirectory->Get("yplus");
4159 /// tree->SetEventList(elist);
4160 /// tree->Draw("py");
4161 /// ~~~
4162 /// Example 2:
4163 /// ~~~ {.cpp}
4164 /// TEntryList *elist = (TEntryList*)gDirectory->Get("yplus");
4165 /// tree->SetEntryList(elist);
4166 /// tree->Draw("py");
4167 /// ~~~
4168 /// If a TEventList object is used as input, a new TEntryList object is created
4169 /// inside the SetEventList function. In case of a TChain, all tree headers are loaded
4170 /// for this transformation. This new object is owned by the chain and is deleted
4171 /// with it, unless the user extracts it by calling GetEntryList() function.
4172 /// See also comments to SetEventList() function of TTree and TChain.
4173 ///
4174 /// If arrays are used in the selection criteria and TEntryListArray is not used,
4175 /// all the entries that have at least one element of the array that satisfy the selection
4176 /// are entered in the list.
4177 ///
4178 /// Example:
4179 /// ~~~ {.cpp}
4180 /// tree.Draw(">>pyplus","fTracks.fPy>0");
4181 /// tree->SetEventList(pyplus);
4182 /// tree->Draw("fTracks.fPy");
4183 /// ~~~
4184 /// will draw the fPy of ALL tracks in event with at least one track with
4185 /// a positive fPy.
4186 ///
4187 /// To select only the elements that did match the original selection
4188 /// use TEventList::SetReapplyCut or TEntryList::SetReapplyCut.
4189 ///
4190 /// Example:
4191 /// ~~~ {.cpp}
4192 /// tree.Draw(">>pyplus","fTracks.fPy>0");
4193 /// pyplus->SetReapplyCut(kTRUE);
4194 /// tree->SetEventList(pyplus);
4195 /// tree->Draw("fTracks.fPy");
4196 /// ~~~
4197 /// will draw the fPy of only the tracks that have a positive fPy.
4198 ///
4199 /// To draw only the elements that match a selection in case of arrays,
4200 /// you can also use TEntryListArray (faster in case of a more general selection).
4201 ///
4202 /// Example:
4203 /// ~~~ {.cpp}
4204 /// tree.Draw(">>pyplus","fTracks.fPy>0", "entrylistarray");
4205 /// tree->SetEntryList(pyplus);
4206 /// tree->Draw("fTracks.fPy");
4207 /// ~~~
4208 /// will draw the fPy of only the tracks that have a positive fPy,
4209 /// but without redoing the selection.
4210 ///
4211 /// Note: Use tree->SetEventList(0) if you do not want use the list as input.
4212 ///
4213 /// ### How to obtain more info from TTree::Draw
4214 ///
4215 /// Once TTree::Draw has been called, it is possible to access useful
4216 /// information still stored in the TTree object via the following functions:
4217 ///
4218 /// - GetSelectedRows() // return the number of values accepted by the selection expression. In case where no selection was specified, returns the number of values processed.
4219 /// - GetV1() // returns a pointer to the double array of V1
4220 /// - GetV2() // returns a pointer to the double array of V2
4221 /// - GetV3() // returns a pointer to the double array of V3
4222 /// - GetV4() // returns a pointer to the double array of V4
4223 /// - GetW() // returns a pointer to the double array of Weights where weight equal the result of the selection expression.
4224 ///
4225 /// where V1,V2,V3 correspond to the expressions in
4226 /// ~~~ {.cpp}
4227 /// TTree::Draw("V1:V2:V3:V4",selection);
4228 /// ~~~
4229 /// If the expression has more than 4 component use GetVal(index)
4230 ///
4231 /// Example:
4232 /// ~~~ {.cpp}
4233 /// Root > ntuple->Draw("py:px","pz>4");
4234 /// Root > TGraph *gr = new TGraph(ntuple->GetSelectedRows(),
4235 /// ntuple->GetV2(), ntuple->GetV1());
4236 /// Root > gr->Draw("ap"); //draw graph in current pad
4237 /// ~~~
4238 ///
4239 /// A more complete complete tutorial (treegetval.C) shows how to use the
4240 /// GetVal() method.
4241 ///
4242 /// creates a TGraph object with a number of points corresponding to the
4243 /// number of entries selected by the expression "pz>4", the x points of the graph
4244 /// being the px values of the Tree and the y points the py values.
4245 ///
4246 /// Important note: By default TTree::Draw creates the arrays obtained
4247 /// with GetW, GetV1, GetV2, GetV3, GetV4, GetVal with a length corresponding
4248 /// to the parameter fEstimate. The content will be the last `GetSelectedRows() % GetEstimate()`
4249 /// values calculated.
4250 /// By default fEstimate=1000000 and can be modified
4251 /// via TTree::SetEstimate. To keep in memory all the results (in case
4252 /// where there is only one result per entry), use
4253 /// ~~~ {.cpp}
4254 /// tree->SetEstimate(tree->GetEntries()+1); // same as tree->SetEstimate(-1);
4255 /// ~~~
4256 /// You must call SetEstimate if the expected number of selected rows
4257 /// you need to look at is greater than 1000000.
4258 ///
4259 /// You can use the option "goff" to turn off the graphics output
4260 /// of TTree::Draw in the above example.
4261 ///
4262 /// ### Automatic interface to TTree::Draw via the TTreeViewer
4263 ///
4264 /// A complete graphical interface to this function is implemented
4265 /// in the class TTreeViewer.
4266 /// To start the TTreeViewer, three possibilities:
4267 /// - select TTree context menu item "StartViewer"
4268 /// - type the command "TTreeViewer TV(treeName)"
4269 /// - execute statement "tree->StartViewer();"
4270 
4271 Long64_t TTree::Draw(const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
4273  GetPlayer();
4274  if (fPlayer)
4275  return fPlayer->DrawSelect(varexp,selection,option,nentries,firstentry);
4276  return -1;
4277 }
4278 
4279 ////////////////////////////////////////////////////////////////////////////////
4280 /// Remove some baskets from memory.
4281 
4282 void TTree::DropBaskets()
4284  TBranch* branch = 0;
4286  for (Int_t i = 0; i < nb; ++i) {
4287  branch = (TBranch*) fBranches.UncheckedAt(i);
4288  branch->DropBaskets("all");
4289  }
4290 }
4291 
4292 ////////////////////////////////////////////////////////////////////////////////
4293 /// Drop branch buffers to accommodate nbytes below MaxVirtualsize.
4294 
4297  // Be careful not to remove current read/write buffers.
4298  Int_t ndrop = 0;
4299  Int_t nleaves = fLeaves.GetEntriesFast();
4300  for (Int_t i = 0; i < nleaves; ++i) {
4301  TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
4302  TBranch* branch = (TBranch*) leaf->GetBranch();
4303  Int_t nbaskets = branch->GetListOfBaskets()->GetEntries();
4304  for (Int_t j = 0; j < nbaskets - 1; ++j) {
4305  if ((j == branch->GetReadBasket()) || (j == branch->GetWriteBasket())) {
4306  continue;
4307  }
4308  TBasket* basket = (TBasket*)branch->GetListOfBaskets()->UncheckedAt(j);
4309  if (basket) {
4310  ndrop += basket->DropBuffers();
4312  return;
4313  }
4314  }
4315  }
4316  }
4317 }
4318 
4319 ////////////////////////////////////////////////////////////////////////////////
4320 /// Fill all branches.
4321 ///
4322 /// This function loops on all the branches of this tree. For
4323 /// each branch, it copies to the branch buffer (basket) the current
4324 /// values of the leaves data types. If a leaf is a simple data type,
4325 /// a simple conversion to a machine independent format has to be done.
4326 ///
4327 /// This machine independent version of the data is copied into a
4328 /// basket (each branch has its own basket). When a basket is full
4329 /// (32k worth of data by default), it is then optionally compressed
4330 /// and written to disk (this operation is also called committing or
4331 /// 'flushing' the basket). The committed baskets are then
4332 /// immediately removed from memory.
4333 ///
4334 /// The function returns the number of bytes committed to the
4335 /// individual branches.
4336 ///
4337 /// If a write error occurs, the number of bytes returned is -1.
4338 ///
4339 /// If no data are written, because, e.g., the branch is disabled,
4340 /// the number of bytes returned is 0.
4341 ///
4342 /// __The baskets are flushed and the Tree header saved at regular intervals__
4343 ///
4344 /// At regular intervals, when the amount of data written so far is
4345 /// greater than fAutoFlush (see SetAutoFlush) all the baskets are flushed to disk.
4346 /// This makes future reading faster as it guarantees that baskets belonging to nearby
4347 /// entries will be on the same disk region.
4348 /// When the first call to flush the baskets happen, we also take this opportunity
4349 /// to optimize the baskets buffers.
4350 /// We also check if the amount of data written is greater than fAutoSave (see SetAutoSave).
4351 /// In this case we also write the Tree header. This makes the Tree recoverable up to this point
4352 /// in case the program writing the Tree crashes.
4353 /// The decisions to FlushBaskets and Auto Save can be made based either on the number
4354 /// of bytes written (fAutoFlush and fAutoSave negative) or on the number of entries
4355 /// written (fAutoFlush and fAutoSave positive).
4356 /// Note that the user can decide to call FlushBaskets and AutoSave in her event loop
4357 /// base on the number of events written instead of the number of bytes written.
4358 ///
4359 /// Note that calling FlushBaskets too often increases the IO time.
4360 ///
4361 /// Note that calling AutoSave too often increases the IO time and also the file size.
4362 
4365  Int_t nbytes = 0;
4366  Int_t nwrite = 0;
4367  Int_t nerror = 0;
4368  Int_t nbranches = fBranches.GetEntriesFast();
4369 
4370  // Case of one single super branch. Automatically update
4371  // all the branch addresses if a new object was created.
4372  if (nbranches == 1)
4373  ((TBranch *)fBranches.UncheckedAt(0))->UpdateAddress();
4374 
4375  if (fBranchRef)
4376  fBranchRef->Clear();
4377 
4378 #ifdef R__USE_IMT
4380  if (fIMTEnabled) {
4381  fIMTFlush = true;
4382  fIMTZipBytes.store(0);
4383  fIMTTotBytes.store(0);
4384  }
4385 #endif
4386 
4387  for (Int_t i = 0; i < nbranches; ++i) {
4388  // Loop over all branches, filling and accumulating bytes written and error counts.
4389  TBranch *branch = (TBranch *)fBranches.UncheckedAt(i);
4390 
4391  if (branch->TestBit(kDoNotProcess))
4392  continue;
4393 
4394 #ifndef R__USE_IMT
4395  nwrite = branch->FillImpl(nullptr);
4396 #else
4397  nwrite = branch->FillImpl(fIMTEnabled ? &imtHelper : nullptr);
4398 #endif
4399  if (nwrite < 0) {
4400  if (nerror < 2) {
4401  Error("Fill", "Failed filling branch:%s.%s, nbytes=%d, entry=%lld\n"
4402  " This error is symptomatic of a Tree created as a memory-resident Tree\n"
4403  " Instead of doing:\n"
4404  " TTree *T = new TTree(...)\n"
4405  " TFile *f = new TFile(...)\n"
4406  " you should do:\n"
4407  " TFile *f = new TFile(...)\n"
4408  " TTree *T = new TTree(...)\n\n",
4409  GetName(), branch->GetName(), nwrite, fEntries + 1);
4410  } else {
4411  Error("Fill", "Failed filling branch:%s.%s, nbytes=%d, entry=%lld", GetName(), branch->GetName(), nwrite,
4412  fEntries + 1);
4413  }
4414  ++nerror;
4415  } else {
4416  nbytes += nwrite;
4417  }
4418  }
4419 
4420 #ifdef R__USE_IMT
4421  if (fIMTFlush) {
4422  imtHelper.Wait();
4423  fIMTFlush = false;
4424  const_cast<TTree *>(this)->AddTotBytes(fIMTTotBytes);
4425  const_cast<TTree *>(this)->AddZipBytes(fIMTZipBytes);
4426  nbytes += imtHelper.GetNbytes();
4427  nerror += imtHelper.GetNerrors();
4428  }
4429 #endif
4430 
4431  if (fBranchRef)
4432  fBranchRef->Fill();
4433 
4434  ++fEntries;
4435 
4436  if (fEntries > fMaxEntries)
4437  KeepCircular();
4438 
4439  if (gDebug > 0)
4440  Info("TTree::Fill", " - A: %d %lld %lld %lld %lld %lld %lld \n", nbytes, fEntries, fAutoFlush, fAutoSave,
4442 
4443  bool autoFlush = false;
4444  bool autoSave = false;
4445 
4446  if (fAutoFlush != 0 || fAutoSave != 0) {
4447  // Is it time to flush or autosave baskets?
4448  if (fFlushedBytes == 0) {
4449  // If fFlushedBytes == 0, it means we never flushed or saved, so
4450  // we need to check if it's time to do it and recompute the values
4451  // of fAutoFlush and fAutoSave in terms of the number of entries.
4452  // Decision can be based initially either on the number of bytes
4453  // or the number of entries written.
4454  Long64_t zipBytes = GetZipBytes();
4455 
4456  if (fAutoFlush)
4457  autoFlush = fAutoFlush < 0 ? (zipBytes > -fAutoFlush) : fEntries % fAutoFlush == 0;
4458 
4459  if (fAutoSave)
4460  autoSave = fAutoSave < 0 ? (zipBytes > -fAutoSave) : fEntries % fAutoSave == 0;
4461 
4462  if (autoFlush || autoSave) {
4463  // First call FlushBasket to make sure that fTotBytes is up to date.
4464  FlushBaskets();
4465  OptimizeBaskets(GetTotBytes(), 1, "");
4466  autoFlush = false; // avoid auto flushing again later
4467 
4468  if (gDebug > 0)
4469  Info("TTree::Fill", "OptimizeBaskets called at entry %lld, fZipBytes=%lld, fFlushedBytes=%lld\n",
4471 
4473  fAutoFlush = fEntries; // Use test on entries rather than bytes
4474 
4475  // subsequently in run
4476  if (fAutoSave < 0) {
4477  // Set fAutoSave to the largest integer multiple of
4478  // fAutoFlush events such that fAutoSave*fFlushedBytes
4479  // < (minus the input value of fAutoSave)
4480  Long64_t totBytes = GetTotBytes();
4481  if (zipBytes != 0) {
4482  fAutoSave = TMath::Max(fAutoFlush, fEntries * ((-fAutoSave / zipBytes) / fEntries));
4483  } else if (totBytes != 0) {
4484  fAutoSave = TMath::Max(fAutoFlush, fEntries * ((-fAutoSave / totBytes) / fEntries));
4485  } else {
4486  TBufferFile b(TBuffer::kWrite, 10000);
4487  TTree::Class()->WriteBuffer(b, (TTree *)this);
4488  Long64_t total = b.Length();
4490  }
4491  } else if (fAutoSave > 0) {
4493  }
4494 
4495  if (fAutoSave != 0 && fEntries >= fAutoSave)
4496  autoSave = true;
4497 
4498  if (gDebug > 0)
4499  Info("TTree::Fill", "First AutoFlush. fAutoFlush = %lld, fAutoSave = %lld\n", fAutoFlush, fAutoSave);
4500  }
4501  } else {
4502  // Check if we need to auto flush
4503  if (fAutoFlush) {
4504  if (fNClusterRange == 0)
4505  autoFlush = fEntries > 1 && fEntries % fAutoFlush == 0;
4506  else
4507  autoFlush = (fEntries - (fClusterRangeEnd[fNClusterRange - 1] + 1)) % fAutoFlush == 0;
4508  }
4509  // Check if we need to auto save
4510  if (fAutoSave)
4511  autoSave = fEntries % fAutoSave == 0;
4512  }
4513  }
4514 
4515  if (autoFlush) {
4516  FlushBaskets();
4517  if (gDebug > 0)
4518  Info("TTree::Fill", "FlushBaskets() called at entry %lld, fZipBytes=%lld, fFlushedBytes=%lld\n", fEntries,
4521  }
4522 
4523  if (autoSave) {
4524  AutoSave(); // does not call FlushBaskets() again
4525  if (gDebug > 0)
4526  Info("TTree::Fill", "AutoSave called at entry %lld, fZipBytes=%lld, fSavedBytes=%lld\n", fEntries,
4528  }
4529 
4530  // Check that output file is still below the maximum size.
4531  // If above, close the current file and continue on a new file.
4532  // Currently, the automatic change of file is restricted
4533  // to the case where the tree is in the top level directory.
4534  if (fDirectory)
4535  if (TFile *file = fDirectory->GetFile())
4536  if ((TDirectory *)file == fDirectory && (file->GetEND() > fgMaxTreeSize))
4537  ChangeFile(file);
4538 
4539  return nerror == 0 ? nbytes : -1;
4540 }
4541 
4542 ////////////////////////////////////////////////////////////////////////////////
4543 /// Search in the array for a branch matching the branch name,
4544 /// with the branch possibly expressed as a 'full' path name (with dots).
4545 
4546 static TBranch *R__FindBranchHelper(TObjArray *list, const char *branchname) {
4547  if (list==0 || branchname == 0 || branchname[0] == '\0') return 0;
4548 
4549  Int_t nbranches = list->GetEntries();
4550 
4551  UInt_t brlen = strlen(branchname);
4552 
4553  for(Int_t index = 0; index < nbranches; ++index) {
4554  TBranch *where = (TBranch*)list->UncheckedAt(index);
4555 
4556  const char *name = where->GetName();
4557  UInt_t len = strlen(name);
4558  if (len && name[len-1]==']') {
4559  const char *dim = strchr(name,'[');
4560  if (dim) {
4561  len = dim - name;
4562  }
4563  }
4564  if (brlen == len && strncmp(branchname,name,len)==0) {
4565  return where;
4566  }
4567  TBranch *next = 0;
4568  if ((brlen >= len) && (branchname[len] == '.')
4569  && strncmp(name, branchname, len) == 0) {
4570  // The prefix subbranch name match the branch name.
4571 
4572  next = where->FindBranch(branchname);
4573  if (!next) {
4574  next = where->FindBranch(branchname+len+1);
4575  }
4576  if (next) return next;
4577  }
4578  const char *dot = strchr((char*)branchname,'.');
4579  if (dot) {
4580  if (len==(size_t)(dot-branchname) &&
4581  strncmp(branchname,name,dot-branchname)==0 ) {
4582  return R__FindBranchHelper(where->GetListOfBranches(),dot+1);
4583  }
4584  }
4585  }
4586  return 0;
4587 }
4588 
4589 ////////////////////////////////////////////////////////////////////////////////
4590 /// Return the branch that correspond to the path 'branchname', which can
4591 /// include the name of the tree or the omitted name of the parent branches.
4592 /// In case of ambiguity, returns the first match.
4593 
4594 TBranch* TTree::FindBranch(const char* branchname)
4596  // We already have been visited while recursively looking
4597  // through the friends tree, let return
4599  return 0;
4600  }
4601 
4602  TBranch* branch = 0;
4603  // If the first part of the name match the TTree name, look for the right part in the
4604  // list of branches.
4605  // This will allow the branchname to be preceded by
4606  // the name of this tree.
4607  if (strncmp(fName.Data(),branchname,fName.Length())==0 && branchname[fName.Length()]=='.') {
4608  branch = R__FindBranchHelper( GetListOfBranches(), branchname + fName.Length() + 1);
4609  if (branch) return branch;
4610  }
4611  // If we did not find it, let's try to find the full name in the list of branches.
4612  branch = R__FindBranchHelper(GetListOfBranches(), branchname);
4613  if (branch) return branch;
4614 
4615  // If we still did not find, let's try to find it within each branch assuming it does not the branch name.
4616  TIter next(GetListOfBranches());
4617  while ((branch = (TBranch*) next())) {
4618  TBranch* nestedbranch = branch->FindBranch(branchname);
4619  if (nestedbranch) {
4620  return nestedbranch;
4621  }
4622  }
4623 
4624  // Search in list of friends.
4625  if (!fFriends) {
4626  return 0;
4627  }
4628  TFriendLock lock(this, kFindBranch);
4629  TIter nextf(fFriends);
4630  TFriendElement* fe = 0;
4631  while ((fe = (TFriendElement*) nextf())) {
4632  TTree* t = fe->GetTree();
4633  if (!t) {
4634  continue;
4635  }
4636  // If the alias is present replace it with the real name.
4637  const char *subbranch = strstr(branchname, fe->GetName());
4638  if (subbranch != branchname) {
4639  subbranch = 0;
4640  }
4641  if (subbranch) {
4642  subbranch += strlen(fe->GetName());
4643  if (*subbranch != '.') {
4644  subbranch = 0;
4645  } else {
4646  ++subbranch;
4647  }
4648  }
4649  std::ostringstream name;
4650  if (subbranch) {
4651  name << t->GetName() << "." << subbranch;
4652  } else {
4653  name << branchname;
4654  }
4655  branch = t->FindBranch(name.str().c_str());
4656  if (branch) {
4657  return branch;
4658  }
4659  }
4660  return 0;
4661 }
4662 
4663 ////////////////////////////////////////////////////////////////////////////////
4664 /// Find leaf..
4665 
4666 TLeaf* TTree::FindLeaf(const char* searchname)
4668  // We already have been visited while recursively looking
4669  // through the friends tree, let's return.
4670  if (kFindLeaf & fFriendLockStatus) {
4671  return 0;
4672  }
4673 
4674  // This will allow the branchname to be preceded by
4675  // the name of this tree.
4676  char* subsearchname = (char*) strstr(searchname, GetName());
4677  if (subsearchname != searchname) {
4678  subsearchname = 0;
4679  }
4680  if (subsearchname) {
4681  subsearchname += strlen(GetName());
4682  if (*subsearchname != '.') {
4683  subsearchname = 0;
4684  } else {
4685  ++subsearchname;
4686  if (subsearchname[0]==0) {
4687  subsearchname = 0;
4688  }
4689  }
4690  }
4691 
4692  TString leafname;
4693  TString leaftitle;
4694  TString longname;
4695  TString longtitle;
4696 
4697  // For leaves we allow for one level up to be prefixed to the name.
4698  TIter next(GetListOfLeaves());
4699  TLeaf* leaf = 0;
4700  while ((leaf = (TLeaf*) next())) {
4701  leafname = leaf->GetName();
4702  Ssiz_t dim = leafname.First('[');
4703  if (dim >= 0) leafname.Remove(dim);
4704 
4705  if (leafname == searchname) {
4706  return leaf;
4707  }
4708  if (subsearchname && leafname == subsearchname) {
4709  return leaf;
4710  }
4711  // The TLeafElement contains the branch name
4712  // in its name, let's use the title.
4713  leaftitle = leaf->GetTitle();
4714  dim = leaftitle.First('[');
4715  if (dim >= 0) leaftitle.Remove(dim);
4716 
4717  if (leaftitle == searchname) {
4718  return leaf;
4719  }
4720  if (subsearchname && leaftitle == subsearchname) {
4721  return leaf;
4722  }
4723  TBranch* branch = leaf->GetBranch();
4724  if (branch) {
4725  longname.Form("%s.%s",branch->GetName(),leafname.Data());
4726  dim = longname.First('[');
4727  if (dim>=0) longname.Remove(dim);
4728  if (longname == searchname) {
4729  return leaf;
4730  }
4731  if (subsearchname && longname == subsearchname) {
4732  return leaf;
4733  }
4734  longtitle.Form("%s.%s",branch->GetName(),leaftitle.Data());
4735  dim = longtitle.First('[');
4736  if (dim>=0) longtitle.Remove(dim);
4737  if (longtitle == searchname) {
4738  return leaf;
4739  }
4740  if (subsearchname && longtitle == subsearchname) {
4741  return leaf;
4742  }
4743  // The following is for the case where the branch is only
4744  // a sub-branch. Since we do not see it through
4745  // TTree::GetListOfBranches, we need to see it indirectly.
4746  // This is the less sturdy part of this search ... it may
4747  // need refining ...
4748  if (strstr(searchname, ".") && !strcmp(searchname, branch->GetName())) {
4749  return leaf;
4750  }
4751  if (subsearchname && strstr(subsearchname, ".") && !strcmp(subsearchname, branch->GetName())) {
4752  return leaf;
4753  }
4754  }
4755  }
4756  // Search in list of friends.
4757  if (!fFriends) {
4758  return 0;
4759  }
4760  TFriendLock lock(this, kFindLeaf);
4761  TIter nextf(fFriends);
4762  TFriendElement* fe = 0;
4763  while ((fe = (TFriendElement*) nextf())) {
4764  TTree* t = fe->GetTree();
4765  if (!t) {
4766  continue;
4767  }
4768  // If the alias is present replace it with the real name.
4769  subsearchname = (char*) strstr(searchname, fe->GetName());
4770  if (subsearchname != searchname) {
4771  subsearchname = 0;
4772  }
4773  if (subsearchname) {
4774  subsearchname += strlen(fe->GetName());
4775  if (*subsearchname != '.') {
4776  subsearchname = 0;
4777  } else {
4778  ++subsearchname;
4779  }
4780  }
4781  if (subsearchname) {
4782  leafname.Form("%s.%s",t->GetName(),subsearchname);
4783  } else {
4784  leafname = searchname;
4785  }
4786  leaf = t->FindLeaf(leafname);
4787  if (leaf) {
4788  return leaf;
4789  }
4790  }
4791  return 0;
4792 }
4793 
4794 ////////////////////////////////////////////////////////////////////////////////
4795 /// Fit a projected item(s) from a tree.
4796 ///
4797 /// funcname is a TF1 function.
4798 ///
4799 /// See TTree::Draw() for explanations of the other parameters.
4800 ///
4801 /// By default the temporary histogram created is called htemp.
4802 /// If varexp contains >>hnew , the new histogram created is called hnew
4803 /// and it is kept in the current directory.
4804 ///
4805 /// The function returns the number of selected entries.
4806 ///
4807 /// Example:
4808 /// ~~~ {.cpp}
4809 /// tree.Fit(pol4,"sqrt(x)>>hsqrt","y>0")
4810 /// ~~~
4811 /// will fit sqrt(x) and save the histogram as "hsqrt" in the current
4812 /// directory.
4813 ///
4814 /// See also TTree::UnbinnedFit
4815 ///
4816 /// ## Return status
4817 ///
4818 /// The function returns the status of the histogram fit (see TH1::Fit)
4819 /// If no entries were selected, the function returns -1;
4820 /// (i.e. fitResult is null if the fit is OK)
4821 
4822 Int_t TTree::Fit(const char* funcname, const char* varexp, const char* selection, Option_t* option, Option_t* goption, Long64_t nentries, Long64_t firstentry)
4824  GetPlayer();
4825  if (fPlayer) {
4826  return fPlayer->Fit(funcname, varexp, selection, option, goption, nentries, firstentry);
4827  }
4828  return -1;
4829 }
4830 
4831 namespace {
4832 struct BoolRAIIToggle {
4833  Bool_t &m_val;
4834 
4835  BoolRAIIToggle(Bool_t &val) : m_val(val) { m_val = true; }
4836  ~BoolRAIIToggle() { m_val = false; }
4837 };
4838 }
4839 
4840 ////////////////////////////////////////////////////////////////////////////////
4841 /// Write to disk all the basket that have not yet been individually written.
4842 ///
4843 /// If ROOT has IMT-mode enabled, this will launch multiple TBB tasks in parallel
4844 /// via TThreadExecutor to do this operation; one per basket compression. If the
4845 /// caller utilizes TBB also, care must be taken to prevent deadlocks.
4846 ///
4847 /// For example, let's say the caller holds mutex A and calls FlushBaskets; while
4848 /// TBB is waiting for the ROOT compression tasks to complete, it may decide to
4849 /// run another one of the user's tasks in this thread. If the second user task
4850 /// tries to acquire A, then a deadlock will occur. The example call sequence
4851 /// looks like this:
4852 ///
4853 /// - User acquires mutex A
4854 /// - User calls FlushBaskets.
4855 /// - ROOT launches N tasks and calls wait.
4856 /// - TBB schedules another user task, T2.
4857 /// - T2 tries to acquire mutex A.
4858 ///
4859 /// At this point, the thread will deadlock: the code may function with IMT-mode
4860 /// disabled if the user assumed the legacy code never would run their own TBB
4861 /// tasks.
4862 ///
4863 /// SO: users of TBB who want to enable IMT-mode should carefully review their
4864 /// locking patterns and make sure they hold no coarse-grained application
4865 /// locks when they invoke ROOT.
4866 ///
4867 /// Return the number of bytes written or -1 in case of write error.
4868 
4869 Int_t TTree::FlushBaskets() const
4871  if (!fDirectory) return 0;
4872  Int_t nbytes = 0;
4873  Int_t nerror = 0;
4874  TObjArray *lb = const_cast<TTree*>(this)->GetListOfBranches();
4875  Int_t nb = lb->GetEntriesFast();
4876 
4877 #ifdef R__USE_IMT
4878  if (fIMTEnabled) {
4879  if (fSortedBranches.empty()) { const_cast<TTree*>(this)->InitializeBranchLists(false); }
4880 
4881  BoolRAIIToggle sentry(fIMTFlush);
4882  fIMTZipBytes.store(0);
4883  fIMTTotBytes.store(0);
4884  std::atomic<Int_t> nerrpar(0);
4885  std::atomic<Int_t> nbpar(0);
4886  std::atomic<Int_t> pos(0);
4887 
4888  auto mapFunction = [&]() {
4889  // The branch to process is obtained when the task starts to run.
4890  // This way, since branches are sorted, we make sure that branches
4891  // leading to big tasks are processed first. If we assigned the
4892  // branch at task creation time, the scheduler would not necessarily
4893  // respect our sorting.
4894  Int_t j = pos.fetch_add(1);
4895 
4896  auto branch = fSortedBranches[j].second;
4897  if (R__unlikely(!branch)) { return; }
4898 
4899  if (R__unlikely(gDebug > 0)) {
4900  std::stringstream ss;
4901  ss << std::this_thread::get_id();
4902  Info("FlushBaskets", "[IMT] Thread %s", ss.str().c_str());
4903  Info("FlushBaskets", "[IMT] Running task for branch #%d: %s", j, branch->GetName());
4904  }
4905 
4906  Int_t nbtask = branch->FlushBaskets();
4907 
4908  if (nbtask < 0) { nerrpar++; }
4909  else { nbpar += nbtask; }
4910  };
4911 
4912  ROOT::TThreadExecutor pool;
4913  pool.Foreach(mapFunction, nb);
4914 
4915  fIMTFlush = false;
4916  const_cast<TTree*>(this)->AddTotBytes(fIMTTotBytes);
4917  const_cast<TTree*>(this)->AddZipBytes(fIMTZipBytes);
4918 
4919  return nerrpar ? -1 : nbpar.load();
4920  }
4921 #endif
4922  for (Int_t j = 0; j < nb; j++) {
4923  TBranch* branch = (TBranch*) lb->UncheckedAt(j);
4924  if (branch) {
4925  Int_t nwrite = branch->FlushBaskets();
4926  if (nwrite<0) {
4927  ++nerror;
4928  } else {
4929  nbytes += nwrite;
4930  }
4931  }
4932  }
4933  if (nerror) {
4934  return -1;
4935  } else {
4936  return nbytes;
4937  }
4938 }
4939 
4940 ////////////////////////////////////////////////////////////////////////////////
4941 /// Returns the expanded value of the alias. Search in the friends if any.
4942 
4943 const char* TTree::GetAlias(const char* aliasName) const
4945  // We already have been visited while recursively looking
4946  // through the friends tree, let's return.
4947  if (kGetAlias & fFriendLockStatus) {
4948  return 0;
4949  }
4950  if (fAliases) {
4951  TObject* alias = fAliases->FindObject(aliasName);
4952  if (alias) {
4953  return alias->GetTitle();
4954  }
4955  }
4956  if (!fFriends) {
4957  return 0;
4958  }
4959  TFriendLock lock(const_cast<TTree*>(this), kGetAlias);
4960  TIter nextf(fFriends);
4961  TFriendElement* fe = 0;
4962  while ((fe = (TFriendElement*) nextf())) {
4963  TTree* t = fe->GetTree();
4964  if (t) {
4965  const char* alias = t->GetAlias(aliasName);
4966  if (alias) {
4967  return alias;
4968  }
4969  const char* subAliasName = strstr(aliasName, fe->GetName());
4970  if (subAliasName && (subAliasName[strlen(fe->GetName())] == '.')) {
4971  alias = t->GetAlias(aliasName + strlen(fe->GetName()) + 1);
4972  if (alias) {
4973  return alias;
4974  }
4975  }
4976  }
4977  }
4978  return 0;
4979 }
4980 
4981 ////////////////////////////////////////////////////////////////////////////////
4982 /// Return pointer to the branch with the given name in this tree or its friends.
4983 
4984 TBranch* TTree::GetBranch(const char* name)
4986  if (name == 0) return 0;
4987 
4988  // We already have been visited while recursively
4989  // looking through the friends tree, let's return.
4990  if (kGetBranch & fFriendLockStatus) {
4991  return 0;
4992  }
4993 
4994  // Search using branches.
4996  for (Int_t i = 0; i < nb; i++) {
4997  TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
4998  if (!branch) {
4999  continue;
5000  }
5001  if (!strcmp(branch->GetName(), name)) {
5002  return branch;
5003  }
5004  TObjArray* lb = branch->GetListOfBranches();
5005  Int_t nb1 = lb->GetEntriesFast();
5006  for (Int_t j = 0; j < nb1; j++) {
5007  TBranch* b1 = (TBranch*) lb->UncheckedAt(j);
5008  if (!strcmp(b1->GetName(), name)) {
5009  return b1;
5010  }
5011  TObjArray* lb1 = b1->GetListOfBranches();
5012  Int_t nb2 = lb1->GetEntriesFast();
5013  for (Int_t k = 0; k < nb2; k++) {
5014  TBranch* b2 = (TBranch*) lb1->UncheckedAt(k);
5015  if (!strcmp(b2->GetName(), name)) {
5016  return b2;
5017  }
5018  }
5019  }
5020  }
5021 
5022  // Search using leaves.
5023  TObjArray* leaves = GetListOfLeaves();
5024  Int_t nleaves = leaves->GetEntriesFast();
5025  for (Int_t i = 0; i < nleaves; i++) {
5026  TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(i);
5027  TBranch* branch = leaf->GetBranch();
5028  if (!strcmp(branch->GetName(), name)) {
5029  return branch;
5030  }
5031  }
5032 
5033  if (!fFriends) {
5034  return 0;
5035  }
5036 
5037  // Search in list of friends.
5038  TFriendLock lock(this, kGetBranch);
5039  TIter next(fFriends);
5040  TFriendElement* fe = 0;
5041  while ((fe = (TFriendElement*) next())) {
5042  TTree* t = fe->GetTree();
5043  if (t) {
5044  TBranch* branch = t->GetBranch(name);
5045  if (branch) {
5046  return branch;
5047  }
5048  }
5049  }
5050 
5051  // Second pass in the list of friends when
5052  // the branch name is prefixed by the tree name.
5053  next.Reset();
5054  while ((fe = (TFriendElement*) next())) {
5055  TTree* t = fe->GetTree();
5056  if (!t) {
5057  continue;
5058  }
5059  char* subname = (char*) strstr(name, fe->GetName());
5060  if (subname != name) {
5061  continue;
5062  }
5063  Int_t l = strlen(fe->GetName());
5064  subname += l;
5065  if (*subname != '.') {
5066  continue;
5067  }
5068  subname++;
5069  TBranch* branch = t->GetBranch(subname);
5070  if (branch) {
5071  return branch;
5072  }
5073  }
5074  return 0;
5075 }
5076 
5077 ////////////////////////////////////////////////////////////////////////////////
5078 /// Return status of branch with name branchname.
5079 ///
5080 /// - 0 if branch is not activated
5081 /// - 1 if branch is activated
5082 
5083 Bool_t TTree::GetBranchStatus(const char* branchname) const
5085  TBranch* br = const_cast<TTree*>(this)->GetBranch(branchname);
5086  if (br) {
5087  return br->TestBit(kDoNotProcess) == 0;
5088  }
5089  return 0;
5090 }
5091 
5092 ////////////////////////////////////////////////////////////////////////////////
5093 /// Static function returning the current branch style.
5094 ///
5095 /// - style = 0 old Branch
5096 /// - style = 1 new Bronch
5097 
5100  return fgBranchStyle;
5101 }
5102 
5103 ////////////////////////////////////////////////////////////////////////////////
5104 /// Used for automatic sizing of the cache.
5105 ///
5106 /// Estimates a suitable size for the tree cache based on AutoFlush.
5107 /// A cache sizing factor is taken from the configuration. If this yields zero
5108 /// and withDefault is true the historical algorithm for default size is used.
5109 
5110 Long64_t TTree::GetCacheAutoSize(Bool_t withDefault /* = kFALSE */ ) const
5112  const char *stcs;
5113  Double_t cacheFactor = 0.0;
5114  if (!(stcs = gSystem->Getenv("ROOT_TTREECACHE_SIZE")) || !*stcs) {
5115  cacheFactor = gEnv->GetValue("TTreeCache.Size", 1.0);
5116  } else {
5117  cacheFactor = TString(stcs).Atof();
5118  }
5119 
5120  if (cacheFactor < 0.0) {
5121  // ignore negative factors
5122  cacheFactor = 0.0;
5123  }
5124 
5125  Long64_t cacheSize = 0;
5126 
5127  if (fAutoFlush < 0) cacheSize = Long64_t(-cacheFactor*fAutoFlush);
5128  else if (fAutoFlush == 0) cacheSize = 0;
5129  else cacheSize = Long64_t(cacheFactor*1.5*fAutoFlush*GetZipBytes()/(fEntries+1));
5130 
5131  if (cacheSize >= (INT_MAX / 4)) {
5132  cacheSize = INT_MAX / 4;
5133  }
5134 
5135  if (cacheSize < 0) {
5136  cacheSize = 0;
5137  }
5138 
5139  if (cacheSize == 0 && withDefault) {
5140  if (fAutoFlush < 0) cacheSize = -fAutoFlush;
5141  else if (fAutoFlush == 0) cacheSize = 0;
5142  else cacheSize = Long64_t(1.5*fAutoFlush*GetZipBytes()/(fEntries+1));
5143  }
5144 
5145  return cacheSize;
5146 }
5147 
5148 ////////////////////////////////////////////////////////////////////////////////
5149 /// Return an iterator over the cluster of baskets starting at firstentry.
5150 ///
5151 /// This iterator is not yet supported for TChain object.
5152 /// ~~~ {.cpp}
5153 /// TTree::TClusterIterator clusterIter = tree->GetClusterIterator(entry);
5154 /// Long64_t clusterStart;
5155 /// while( (clusterStart = clusterIter()) < tree->GetEntries() ) {
5156 /// printf("The cluster starts at %lld and ends at %lld (inclusive)\n",clusterStart,clusterIter.GetNextEntry()-1);
5157 /// }
5158 /// ~~~
5159 
5162  // create cache if wanted
5164 
5165  return TClusterIterator(this,firstentry);
5166 }
5167 
5168 ////////////////////////////////////////////////////////////////////////////////
5169 /// Return pointer to the current file.
5170 
5173  if (!fDirectory || fDirectory==gROOT) {
5174  return 0;
5175  }
5176  return fDirectory->GetFile();
5177 }
5178 
5179 ////////////////////////////////////////////////////////////////////////////////
5180 /// Return the number of entries matching the selection.
5181 /// Return -1 in case of errors.
5182 ///
5183 /// If the selection uses any arrays or containers, we return the number
5184 /// of entries where at least one element match the selection.
5185 /// GetEntries is implemented using the selector class TSelectorEntries,
5186 /// which can be used directly (see code in TTreePlayer::GetEntries) for
5187 /// additional option.
5188 /// If SetEventList was used on the TTree or TChain, only that subset
5189 /// of entries will be considered.
5190 
5191 Long64_t TTree::GetEntries(const char *selection)
5193  GetPlayer();
5194  if (fPlayer) {
5195  return fPlayer->GetEntries(selection);
5196  }
5197  return -1;
5198 }
5199 
5200 ////////////////////////////////////////////////////////////////////////////////
5201 /// Return pointer to the 1st Leaf named name in any Branch of this Tree or
5202 /// any branch in the list of friend trees.
5203 
5206  if (fEntries) return fEntries;
5207  if (!fFriends) return 0;
5209  if (!fr) return 0;
5210  TTree *t = fr->GetTree();
5211  if (t==0) return 0;
5212  return t->GetEntriesFriend();
5213 }
5214 
5215 ////////////////////////////////////////////////////////////////////////////////
5216 /// Read all branches of entry and return total number of bytes read.
5217 ///
5218 /// - `getall = 0` : get only active branches
5219 /// - `getall = 1` : get all branches
5220 ///
5221 /// The function returns the number of bytes read from the input buffer.
5222 /// If entry does not exist the function returns 0.
5223 /// If an I/O error occurs, the function returns -1.
5224 ///
5225 /// If the Tree has friends, also read the friends entry.
5226 ///
5227 /// To activate/deactivate one or more branches, use TBranch::SetBranchStatus
5228 /// For example, if you have a Tree with several hundred branches, and you
5229 /// are interested only by branches named "a" and "b", do
5230 /// ~~~ {.cpp}
5231 /// mytree.SetBranchStatus("*",0); //disable all branches
5232 /// mytree.SetBranchStatus("a",1);
5233 /// mytree.SetBranchStatus("b",1);
5234 /// ~~~
5235 /// when calling mytree.GetEntry(i); only branches "a" and "b" will be read.
5236 ///
5237 /// __WARNING!!__
5238 /// If your Tree has been created in split mode with a parent branch "parent.",
5239 /// ~~~ {.cpp}
5240 /// mytree.SetBranchStatus("parent",1);
5241 /// ~~~
5242 /// will not activate the sub-branches of "parent". You should do:
5243 /// ~~~ {.cpp}
5244 /// mytree.SetBranchStatus("parent*",1);
5245 /// ~~~
5246 /// Without the trailing dot in the branch creation you have no choice but to
5247 /// call SetBranchStatus explicitly for each of the sub branches.
5248 ///
5249 /// An alternative is to call directly
5250 /// ~~~ {.cpp}
5251 /// brancha.GetEntry(i)
5252 /// branchb.GetEntry(i);
5253 /// ~~~
5254 /// ## IMPORTANT NOTE
5255 ///
5256 /// By default, GetEntry reuses the space allocated by the previous object
5257 /// for each branch. You can force the previous object to be automatically
5258 /// deleted if you call mybranch.SetAutoDelete(kTRUE) (default is kFALSE).
5259 ///
5260 /// Example:
5261 ///
5262 /// Consider the example in $ROOTSYS/test/Event.h
5263 /// The top level branch in the tree T is declared with:
5264 /// ~~~ {.cpp}
5265 /// Event *event = 0; //event must be null or point to a valid object
5266 /// //it must be initialized
5267 /// T.SetBranchAddress("event",&event);
5268 /// ~~~
5269 /// When reading the Tree, one can choose one of these 3 options:
5270 ///
5271 /// ## OPTION 1
5272 ///
5273 /// ~~~ {.cpp}
5274 /// for (Long64_t i=0;i<nentries;i++) {
5275 /// T.GetEntry(i);
5276 /// // the object event has been filled at this point
5277 /// }
5278 /// ~~~
5279 /// The default (recommended). At the first entry an object of the class
5280 /// Event will be created and pointed by event. At the following entries,
5281 /// event will be overwritten by the new data. All internal members that are
5282 /// TObject* are automatically deleted. It is important that these members
5283 /// be in a valid state when GetEntry is called. Pointers must be correctly
5284 /// initialized. However these internal members will not be deleted if the
5285 /// characters "->" are specified as the first characters in the comment
5286 /// field of the data member declaration.
5287 ///
5288 /// If "->" is specified, the pointer member is read via pointer->Streamer(buf).
5289 /// In this case, it is assumed that the pointer is never null (case of
5290 /// pointer TClonesArray *fTracks in the Event example). If "->" is not
5291 /// specified, the pointer member is read via buf >> pointer. In this case
5292 /// the pointer may be null. Note that the option with "->" is faster to
5293 /// read or write and it also consumes less space in the file.
5294 ///
5295 /// ## OPTION 2
5296 ///
5297 /// The option AutoDelete is set
5298 /// ~~~ {.cpp}
5299 /// TBranch *branch = T.GetBranch("event");
5300 /// branch->SetAddress(&event);
5301 /// branch->SetAutoDelete(kTRUE);
5302 /// for (Long64_t i=0;i<nentries;i++) {
5303 /// T.GetEntry(i);
5304 /// // the object event has been filled at this point
5305 /// }
5306 /// ~~~
5307 /// In this case, at each iteration, the object event is deleted by GetEntry
5308 /// and a new instance of Event is created and filled.
5309 ///
5310 /// ## OPTION 3
5311 /// ~~~ {.cpp}
5312 /// Same as option 1, but you delete yourself the event.
5313 ///
5314 /// for (Long64_t i=0;i<nentries;i++) {
5315 /// delete event;
5316 /// event = 0; // EXTREMELY IMPORTANT
5317 /// T.GetEntry(i);
5318 /// // the object event has been filled at this point
5319 /// }
5320 /// ~~~
5321 /// It is strongly recommended to use the default option 1. It has the
5322 /// additional advantage that functions like TTree::Draw (internally calling
5323 /// TTree::GetEntry) will be functional even when the classes in the file are
5324 /// not available.
5325 ///
5326 /// Note: See the comments in TBranchElement::SetAddress() for the
5327 /// object ownership policy of the underlying (user) data.
5328 
5329 Int_t TTree::GetEntry(Long64_t entry, Int_t getall)
5331 
5332  // We already have been visited while recursively looking
5333  // through the friends tree, let return
5334  if (kGetEntry & fFriendLockStatus) return 0;
5335 
5336  if (entry < 0 || entry >= fEntries) return 0;
5337  Int_t i;
5338  Int_t nbytes = 0;
5339  fReadEntry = entry;
5340 
5341  // create cache if wanted
5343 
5344  Int_t nbranches = fBranches.GetEntriesFast();
5345  Int_t nb=0;
5346 
5347  auto seqprocessing = [&]() {
5348  TBranch *branch;
5349  for (i=0;i<nbranches;i++) {
5350  branch = (TBranch*)fBranches.UncheckedAt(i);
5351  nb = branch->GetEntry(entry, getall);
5352  if (nb < 0) break;
5353  nbytes += nb;
5354  }
5355  };
5356 
5357 #ifdef R__USE_IMT
5359  if (fSortedBranches.empty()) InitializeBranchLists(true);
5360 
5361  // Count branches are processed first and sequentially
5362  for (auto branch : fSeqBranches) {
5363  nb = branch->GetEntry(entry, getall);
5364  if (nb < 0) break;
5365  nbytes += nb;
5366  }
5367  if (nb < 0) return nb;
5368 
5369  // Enable this IMT use case (activate its locks)
5371 
5372  Int_t errnb = 0;
5373  std::atomic<Int_t> pos(0);
5374  std::atomic<Int_t> nbpar(0);
5375 
5376  auto mapFunction = [&]() {
5377  // The branch to process is obtained when the task starts to run.
5378  // This way, since branches are sorted, we make sure that branches
5379  // leading to big tasks are processed first. If we assigned the
5380  // branch at task creation time, the scheduler would not necessarily
5381  // respect our sorting.
5382  Int_t j = pos.fetch_add(1);
5383 
5384  Int_t nbtask = 0;
5385  auto branch = fSortedBranches[j].second;
5386 
5387  if (gDebug > 0) {
5388  std::stringstream ss;
5389  ss << std::this_thread::get_id();
5390  Info("GetEntry", "[IMT] Thread %s", ss.str().c_str());
5391  Info("GetEntry", "[IMT] Running task for branch #%d: %s", j, branch->GetName());
5392  }
5393 
5394  std::chrono::time_point<std::chrono::system_clock> start, end;
5395 
5396  start = std::chrono::system_clock::now();
5397  nbtask = branch->GetEntry(entry, getall);
5398  end = std::chrono::system_clock::now();
5399 
5400  Long64_t tasktime = (Long64_t)std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
5401  fSortedBranches[j].first += tasktime;
5402 
5403  if (nbtask < 0) errnb = nbtask;
5404  else nbpar += nbtask;
5405  };
5406 
5407  ROOT::TThreadExecutor pool;
5408  pool.Foreach(mapFunction, fSortedBranches.size());
5409 
5410  if (errnb < 0) {
5411  nb = errnb;
5412  }
5413  else {
5414  // Save the number of bytes read by the tasks
5415  nbytes += nbpar;
5416 
5417  // Re-sort branches if necessary
5421  }
5422  }
5423  }
5424  else {
5425  seqprocessing();
5426  }
5427 #else
5428  seqprocessing();
5429 #endif
5430  if (nb < 0) return nb;
5431 
5432  // GetEntry in list of friends
5433  if (!fFriends) return nbytes;
5434  TFriendLock lock(this,kGetEntry);
5435  TIter nextf(fFriends);
5436  TFriendElement *fe;
5437  while ((fe = (TFriendElement*)nextf())) {
5438  TTree *t = fe->GetTree();
5439  if (t) {
5441  nb = t->GetEntry(t->GetReadEntry(),getall);
5442  } else {
5443  if ( t->LoadTreeFriend(entry,this) >= 0 ) {
5444  nb = t->GetEntry(t->GetReadEntry(),getall);
5445  } else nb = 0;
5446  }
5447  if (nb < 0) return nb;
5448  nbytes += nb;
5449  }
5450  }
5451  return nbytes;
5452 }
5453 
5454 
5455 ////////////////////////////////////////////////////////////////////////////////
5456 /// Divides the top-level branches into two vectors: (i) branches to be
5457 /// processed sequentially and (ii) branches to be processed in parallel.
5458 /// Even if IMT is on, some branches might need to be processed first and in a
5459 /// sequential fashion: in the parallelization of GetEntry, those are the
5460 /// branches that store the size of another branch for every entry
5461 /// (e.g. the size of an array branch). If such branches were processed
5462 /// in parallel with the rest, there could be two threads invoking
5463 /// TBranch::GetEntry on one of them at the same time, since a branch that
5464 /// depends on a size (or count) branch will also invoke GetEntry on the latter.
5465 /// \param[in] checkLeafCount True if we need to check whether some branches are
5466 /// count leaves.
5467 
5468 void TTree::InitializeBranchLists(bool checkLeafCount)
5470  Int_t nbranches = fBranches.GetEntriesFast();
5471 
5472  // The branches to be processed sequentially are those that are the leaf count of another branch
5473  if (checkLeafCount) {
5474  for (Int_t i = 0; i < nbranches; i++) {
5475  TBranch* branch = (TBranch*)fBranches.UncheckedAt(i);
5476  auto leafCount = ((TLeaf*)branch->GetListOfLeaves()->At(0))->GetLeafCount();
5477  if (leafCount) {
5478  auto countBranch = leafCount->GetBranch();
5479  if (std::find(fSeqBranches.begin(), fSeqBranches.end(), countBranch) == fSeqBranches.end()) {
5480  fSeqBranches.push_back(countBranch);
5481  }
5482  }
5483  }
5484  }
5485 
5486  // The special branch fBranchRef also needs to be processed sequentially
5487  if (fBranchRef) {
5488  fSeqBranches.push_back(fBranchRef);
5489  }
5490 
5491  // Any branch that is not a leaf count can be safely processed in parallel when reading
5492  for (Int_t i = 0; i < nbranches; i++) {
5493  Long64_t bbytes = 0;
5494  TBranch* branch = (TBranch*)fBranches.UncheckedAt(i);
5495  if (std::find(fSeqBranches.begin(), fSeqBranches.end(), branch) == fSeqBranches.end()) {
5496  bbytes = branch->GetTotBytes("*");
5497  fSortedBranches.emplace_back(bbytes, branch);
5498  }
5499  }
5500 
5501  // Initially sort parallel branches by size
5502  std::sort(fSortedBranches.begin(),
5503  fSortedBranches.end(),
5504  [](std::pair<Long64_t,TBranch*> a, std::pair<Long64_t,TBranch*> b) {
5505  return a.first > b.first;
5506  });
5507 
5508  for (size_t i = 0; i < fSortedBranches.size(); i++) {
5509  fSortedBranches[i].first = 0LL;
5510  }
5511 }
5512 
5513 ////////////////////////////////////////////////////////////////////////////////
5514 /// Sorts top-level branches by the last average task time recorded per branch.
5515 
5518  for (size_t i = 0; i < fSortedBranches.size(); i++) {
5519  fSortedBranches[i].first *= kNEntriesResortInv;
5520  }
5521 
5522  std::sort(fSortedBranches.begin(),
5523  fSortedBranches.end(),
5524  [](std::pair<Long64_t,TBranch*> a, std::pair<Long64_t,TBranch*> b) {
5525  return a.first > b.first;
5526  });
5527 
5528  for (size_t i = 0; i < fSortedBranches.size(); i++) {
5529  fSortedBranches[i].first = 0LL;
5530  }
5531 }
5532 
5533 ////////////////////////////////////////////////////////////////////////////////
5534 ///Returns the entry list, set to this tree
5535 
5538  return fEntryList;
5539 }
5540 
5541 ////////////////////////////////////////////////////////////////////////////////
5542 /// Return entry number corresponding to entry.
5543 ///
5544 /// if no TEntryList set returns entry
5545 /// else returns the entry number corresponding to the list index=entry
5546 
5549  if (!fEntryList) {
5550  return entry;
5551  }
5552 
5553  return fEntryList->GetEntry(entry);
5554 }
5555 
5556 ////////////////////////////////////////////////////////////////////////////////
5557 /// Return entry number corresponding to major and minor number.
5558 /// Note that this function returns only the entry number, not the data
5559 /// To read the data corresponding to an entry number, use TTree::GetEntryWithIndex
5560 /// the BuildIndex function has created a table of Long64_t* of sorted values
5561 /// corresponding to val = major<<31 + minor;
5562 /// The function performs binary search in this sorted table.
5563 /// If it finds a pair that matches val, it returns directly the
5564 /// index in the table.
5565 /// If an entry corresponding to major and minor is not found, the function
5566 /// returns the index of the major,minor pair immediately lower than the
5567 /// requested value, ie it will return -1 if the pair is lower than
5568 /// the first entry in the index.
5569 ///
5570 /// See also GetEntryNumberWithIndex
5571 
5574  if (!fTreeIndex) {
5575  return -1;
5576  }
5577  return fTreeIndex->GetEntryNumberWithBestIndex(major, minor);
5578 }
5579 
5580 ////////////////////////////////////////////////////////////////////////////////
5581 /// Return entry number corresponding to major and minor number.
5582 /// Note that this function returns only the entry number, not the data
5583 /// To read the data corresponding to an entry number, use TTree::GetEntryWithIndex
5584 /// the BuildIndex function has created a table of Long64_t* of sorted values
5585 /// corresponding to val = major<<31 + minor;
5586 /// The function performs binary search in this sorted table.
5587 /// If it finds a pair that matches val, it returns directly the
5588 /// index in the table, otherwise it returns -1.
5589 ///
5590 /// See also GetEntryNumberWithBestIndex
5591 
5594  if (!fTreeIndex) {
5595  return -1;
5596  }
5597  return fTreeIndex->GetEntryNumberWithIndex(major, minor);
5598 }
5599 
5600 ////////////////////////////////////////////////////////////////////////////////
5601 /// Read entry corresponding to major and minor number.
5602 ///
5603 /// The function returns the total number of bytes read.
5604 /// If the Tree has friend trees, the corresponding entry with
5605 /// the index values (major,minor) is read. Note that the master Tree
5606 /// and its friend may have different entry serial numbers corresponding
5607 /// to (major,minor).
5608 
5611  // We already have been visited while recursively looking
5612  // through the friends tree, let's return.
5614  return 0;
5615  }
5616  Long64_t serial = GetEntryNumberWithIndex(major, minor);
5617  if (serial < 0) {
5618  return -1;
5619  }
5620  // create cache if wanted
5622 
5623  Int_t i;
5624  Int_t nbytes = 0;
5625  fReadEntry = serial;
5626  TBranch *branch;
5627  Int_t nbranches = fBranches.GetEntriesFast();
5628  Int_t nb;
5629  for (i = 0; i < nbranches; ++i) {
5630  branch = (TBranch*)fBranches.UncheckedAt(i);
5631  nb = branch->GetEntry(serial);
5632  if (nb < 0) return nb;
5633  nbytes += nb;
5634  }
5635  // GetEntry in list of friends
5636  if (!fFriends) return nbytes;
5637  TFriendLock lock(this,kGetEntryWithIndex);
5638  TIter nextf(fFriends);
5639  TFriendElement* fe = 0;
5640  while ((fe = (TFriendElement*) nextf())) {
5641  TTree *t = fe->GetTree();
5642  if (t) {
5643  serial = t->GetEntryNumberWithIndex(major,minor);
5644  if (serial <0) return -nbytes;
5645  nb = t->GetEntry(serial);
5646  if (nb < 0) return nb;
5647  nbytes += nb;
5648  }
5649  }
5650  return nbytes;
5651 }
5652 
5653 ////////////////////////////////////////////////////////////////////////////////
5654 /// Return a pointer to the TTree friend whose name or alias is 'friendname.
5655 
5656 TTree* TTree::GetFriend(const char *friendname) const
5658 
5659  // We already have been visited while recursively
5660  // looking through the friends tree, let's return.
5661  if (kGetFriend & fFriendLockStatus) {
5662  return 0;
5663  }
5664  if (!fFriends) {
5665  return 0;
5666  }
5667  TFriendLock lock(const_cast<TTree*>(this), kGetFriend);
5668  TIter nextf(fFriends);
5669  TFriendElement* fe = 0;
5670  while ((fe = (TFriendElement*) nextf())) {
5671  if (strcmp(friendname,fe->GetName())==0
5672  || strcmp(friendname,fe->GetTreeName())==0) {
5673  return fe->GetTree();
5674  }
5675  }
5676  // After looking at the first level,
5677  // let's see if it is a friend of friends.
5678  nextf.Reset();
5679  fe = 0;
5680  while ((fe = (TFriendElement*) nextf())) {
5681  TTree *res = fe->GetTree()->GetFriend(friendname);
5682  if (res) {
5683  return res;
5684  }
5685  }
5686  return 0;
5687 }
5688 
5689 ////////////////////////////////////////////////////////////////////////////////
5690 /// If the 'tree' is a friend, this method returns its alias name.
5691 ///
5692 /// This alias is an alternate name for the tree.
5693 ///
5694 /// It can be used in conjunction with a branch or leaf name in a TTreeFormula,
5695 /// to specify in which particular tree the branch or leaf can be found if
5696 /// the friend trees have branches or leaves with the same name as the master
5697 /// tree.
5698 ///
5699 /// It can also be used in conjunction with an alias created using
5700 /// TTree::SetAlias in a TTreeFormula, e.g.:
5701 /// ~~~ {.cpp}
5702 /// maintree->Draw("treealias.fPx - treealias.myAlias");
5703 /// ~~~
5704 /// where fPx is a branch of the friend tree aliased as 'treealias' and 'myAlias'
5705 /// was created using TTree::SetAlias on the friend tree.
5706 ///
5707 /// However, note that 'treealias.myAlias' will be expanded literally,
5708 /// without remembering that it comes from the aliased friend and thus
5709 /// the branch name might not be disambiguated properly, which means
5710 /// that you may not be able to take advantage of this feature.
5711 ///
5712 
5713 const char* TTree::GetFriendAlias(TTree* tree) const
5715  if ((tree == this) || (tree == GetTree())) {
5716  return 0;
5717  }
5718 
5719  // We already have been visited while recursively
5720  // looking through the friends tree, let's return.
5722  return 0;
5723  }
5724  if (!fFriends) {
5725  return 0;
5726  }
5727  TFriendLock lock(const_cast<TTree*>(this), kGetFriendAlias);
5728  TIter nextf(fFriends);
5729  TFriendElement* fe = 0;
5730  while ((fe = (TFriendElement*) nextf())) {
5731  TTree* t = fe->GetTree();
5732  if (t == tree) {
5733  return fe->GetName();
5734  }
5735  // Case of a chain:
5736  if (t && t->GetTree() == tree) {
5737  return fe->GetName();
5738  }
5739  }
5740  // After looking at the first level,
5741  // let's see if it is a friend of friends.
5742  nextf.Reset();
5743  fe = 0;
5744  while ((fe = (TFriendElement*) nextf())) {
5745  const char* res = fe->GetTree()->GetFriendAlias(tree);
5746  if (res) {
5747  return res;
5748  }
5749  }
5750  return 0;
5751 }
5752