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