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