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