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 "TMemFile.h"
398 #include "TROOT.h"
399 #include "TRealData.h"
400 #include "TRegexp.h"
401 #include "TRefTable.h"
402 #include "TStreamerElement.h"
403 #include "TStreamerInfo.h"
404 #include "TStyle.h"
405 #include "TSystem.h"
406 #include "TTreeCloner.h"
407 #include "TTreeCache.h"
408 #include "TTreeCacheUnzip.h"
409 #include "TVirtualCollectionProxy.h"
411 #include "TVirtualIndex.h"
412 #include "TVirtualPerfStats.h"
413 #include "TVirtualPad.h"
414 #include "TBranchSTL.h"
415 #include "TSchemaRuleSet.h"
416 #include "TFileMergeInfo.h"
417 #include "ROOT/StringConv.hxx"
418 #include "TVirtualMutex.h"
419 #include "strlcpy.h"
420 #include "snprintf.h"
421 
422 #include "TBranchIMTHelper.h"
423 #include "TNotifyLink.h"
424 
425 #include <chrono>
426 #include <cstddef>
427 #include <iostream>
428 #include <fstream>
429 #include <sstream>
430 #include <string>
431 #include <cstdio>
432 #include <climits>
433 #include <algorithm>
434 #include <set>
435 
436 #ifdef R__USE_IMT
437 #include "ROOT/TThreadExecutor.hxx"
438 #include <thread>
439 #endif
440 
441 constexpr Int_t kNEntriesResort = 100;
443 
444 Int_t TTree::fgBranchStyle = 1; // Use new TBranch style with TBranchElement.
445 Long64_t TTree::fgMaxTreeSize = 100000000000LL;
446 
447 ClassImp(TTree);
448 
449 ////////////////////////////////////////////////////////////////////////////////
450 ////////////////////////////////////////////////////////////////////////////////
451 ////////////////////////////////////////////////////////////////////////////////
452 
453 static char DataTypeToChar(EDataType datatype)
454 {
455  // Return the leaflist 'char' for a given datatype.
456 
457  switch(datatype) {
458  case kChar_t: return 'B';
459  case kUChar_t: return 'b';
460  case kBool_t: return 'O';
461  case kShort_t: return 'S';
462  case kUShort_t: return 's';
463  case kCounter:
464  case kInt_t: return 'I';
465  case kUInt_t: return 'i';
466  case kDouble_t: return 'D';
467  case kDouble32_t: return 'd';
468  case kFloat_t: return 'F';
469  case kFloat16_t: return 'f';
470  case kLong_t: return 'G';
471  case kULong_t: return 'g';
472  case kchar: return 0; // unsupported
473  case kLong64_t: return 'L';
474  case kULong64_t: return 'l';
475 
476  case kCharStar: return 'C';
477  case kBits: return 0; //unsupported
478 
479  case kOther_t:
480  case kNoType_t:
481  default:
482  return 0;
483  }
484  return 0;
485 }
486 
487 ////////////////////////////////////////////////////////////////////////////////
488 /// \class TTree::TFriendLock
489 /// Helper class to prevent infinite recursion in the usage of TTree Friends.
490 
491 ////////////////////////////////////////////////////////////////////////////////
492 /// Record in tree that it has been used while recursively looks through the friends.
493 
495 : fTree(tree)
496 {
497  // We could also add some code to acquire an actual
498  // lock to prevent multi-thread issues
499  fMethodBit = methodbit;
500  if (fTree) {
503  } else {
504  fPrevious = 0;
505  }
506 }
507 
508 ////////////////////////////////////////////////////////////////////////////////
509 /// Copy constructor.
510 
512  fTree(tfl.fTree),
513  fMethodBit(tfl.fMethodBit),
514  fPrevious(tfl.fPrevious)
515 {
516 }
517 
518 ////////////////////////////////////////////////////////////////////////////////
519 /// Assignment operator.
520 
522 {
523  if(this!=&tfl) {
524  fTree=tfl.fTree;
525  fMethodBit=tfl.fMethodBit;
526  fPrevious=tfl.fPrevious;
527  }
528  return *this;
529 }
530 
531 ////////////////////////////////////////////////////////////////////////////////
532 /// Restore the state of tree the same as before we set the lock.
533 
535 {
536  if (fTree) {
537  if (!fPrevious) {
538  fTree->fFriendLockStatus &= ~(fMethodBit & kBitMask);
539  }
540  }
541 }
542 
543 ////////////////////////////////////////////////////////////////////////////////
544 /// \class TTree::TClusterIterator
545 /// Helper class to iterate over cluster of baskets.
546 
547 ////////////////////////////////////////////////////////////////////////////////
548 /// Regular constructor.
549 /// TTree is not set as const, since we might modify if it is a TChain.
550 
551 TTree::TClusterIterator::TClusterIterator(TTree *tree, Long64_t firstEntry) : fTree(tree), fClusterRange(0), fStartEntry(0), fNextEntry(0), fEstimatedSize(-1)
552 {
553  if (fTree->fNClusterRange) {
554  // Find the correct cluster range.
555  //
556  // Since fClusterRangeEnd contains the inclusive upper end of the range, we need to search for the
557  // range that was containing the previous entry and add 1 (because BinarySearch consider the values
558  // to be the inclusive start of the bucket).
560 
561  Long64_t entryInRange;
562  Long64_t pedestal;
563  if (fClusterRange == 0) {
564  pedestal = 0;
565  entryInRange = firstEntry;
566  } else {
567  pedestal = fTree->fClusterRangeEnd[fClusterRange-1] + 1;
568  entryInRange = firstEntry - pedestal;
569  }
570  Long64_t autoflush;
572  autoflush = fTree->fAutoFlush;
573  } else {
574  autoflush = fTree->fClusterSize[fClusterRange];
575  }
576  if (autoflush <= 0) {
577  autoflush = GetEstimatedClusterSize();
578  }
579  fStartEntry = pedestal + entryInRange - entryInRange%autoflush;
580  } else if ( fTree->GetAutoFlush() <= 0 ) {
581  // Case of old files before November 9 2009 *or* small tree where AutoFlush was never set.
582  fStartEntry = firstEntry;
583  } else {
584  fStartEntry = firstEntry - firstEntry%fTree->GetAutoFlush();
585  }
586  fNextEntry = fStartEntry; // Position correctly for the first call to Next()
587 }
588 
589 ////////////////////////////////////////////////////////////////////////////////
590 /// Estimate the cluster size.
591 ///
592 /// In almost all cases, this quickly returns the size of the auto-flush
593 /// in the TTree.
594 ///
595 /// However, in the case where the cluster size was not fixed (old files and
596 /// case where autoflush was explicitly set to zero), we need estimate
597 /// a cluster size in relation to the size of the cache.
598 ///
599 /// After this value is calculated once for the TClusterIterator, it is
600 /// cached and reused in future calls.
601 
603 {
604  auto autoFlush = fTree->GetAutoFlush();
605  if (autoFlush > 0) return autoFlush;
606  if (fEstimatedSize > 0) return fEstimatedSize;
607 
608  Long64_t zipBytes = fTree->GetZipBytes();
609  if (zipBytes == 0) {
610  fEstimatedSize = fTree->GetEntries() - 1;
611  if (fEstimatedSize <= 0)
612  fEstimatedSize = 1;
613  } else {
614  Long64_t clusterEstimate = 1;
615  Long64_t cacheSize = fTree->GetCacheSize();
616  if (cacheSize == 0) {
617  // Humm ... let's double check on the file.
618  TFile *file = fTree->GetCurrentFile();
619  if (file) {
620  TFileCacheRead *cache = fTree->GetReadCache(file);
621  if (cache) {
622  cacheSize = cache->GetBufferSize();
623  }
624  }
625  }
626  // If neither file nor tree has a cache, use the current default.
627  if (cacheSize <= 0) {
628  cacheSize = 30000000;
629  }
630  clusterEstimate = fTree->GetEntries() * cacheSize / zipBytes;
631  // If there are no entries, then just default to 1.
632  fEstimatedSize = clusterEstimate ? clusterEstimate : 1;
633  }
634  return fEstimatedSize;
635 }
636 
637 ////////////////////////////////////////////////////////////////////////////////
638 /// Move on to the next cluster and return the starting entry
639 /// of this next cluster
640 
642 {
643  fStartEntry = fNextEntry;
644  if (fTree->fNClusterRange || fTree->GetAutoFlush() > 0) {
645  if (fClusterRange == fTree->fNClusterRange) {
646  // We are looking at a range which size
647  // is defined by AutoFlush itself and goes to the GetEntries.
648  fNextEntry += GetEstimatedClusterSize();
649  } else {
650  if (fStartEntry > fTree->fClusterRangeEnd[fClusterRange]) {
651  ++fClusterRange;
652  }
653  if (fClusterRange == fTree->fNClusterRange) {
654  // We are looking at the last range which size
655  // is defined by AutoFlush itself and goes to the GetEntries.
656  fNextEntry += GetEstimatedClusterSize();
657  } else {
658  Long64_t clusterSize = fTree->fClusterSize[fClusterRange];
659  if (clusterSize == 0) {
660  clusterSize = GetEstimatedClusterSize();
661  }
662  fNextEntry += clusterSize;
663  if (fNextEntry > fTree->fClusterRangeEnd[fClusterRange]) {
664  // The last cluster of the range was a partial cluster,
665  // so the next cluster starts at the beginning of the
666  // next range.
667  fNextEntry = fTree->fClusterRangeEnd[fClusterRange] + 1;
668  }
669  }
670  }
671  } else {
672  // Case of old files before November 9 2009
673  fNextEntry = fStartEntry + GetEstimatedClusterSize();
674  }
675  if (fNextEntry > fTree->GetEntries()) {
676  fNextEntry = fTree->GetEntries();
677  }
678  return fStartEntry;
679 }
680 
681 ////////////////////////////////////////////////////////////////////////////////
682 /// Move on to the previous cluster and return the starting entry
683 /// of this previous cluster
684 
686 {
687  fNextEntry = fStartEntry;
688  if (fTree->fNClusterRange || fTree->GetAutoFlush() > 0) {
689  if (fClusterRange == 0 || fTree->fNClusterRange == 0) {
690  // We are looking at a range which size
691  // is defined by AutoFlush itself.
692  fStartEntry -= GetEstimatedClusterSize();
693  } else {
694  if (fNextEntry <= fTree->fClusterRangeEnd[fClusterRange]) {
695  --fClusterRange;
696  }
697  if (fClusterRange == 0) {
698  // We are looking at the first range.
699  fStartEntry = 0;
700  } else {
701  Long64_t clusterSize = fTree->fClusterSize[fClusterRange];
702  if (clusterSize == 0) {
703  clusterSize = GetEstimatedClusterSize();
704  }
705  fStartEntry -= clusterSize;
706  }
707  }
708  } else {
709  // Case of old files before November 9 2009 or trees that never auto-flushed.
710  fStartEntry = fNextEntry - GetEstimatedClusterSize();
711  }
712  if (fStartEntry < 0) {
713  fStartEntry = 0;
714  }
715  return fStartEntry;
716 }
717 
718 ////////////////////////////////////////////////////////////////////////////////
719 ////////////////////////////////////////////////////////////////////////////////
720 ////////////////////////////////////////////////////////////////////////////////
721 
722 ////////////////////////////////////////////////////////////////////////////////
723 /// Default constructor and I/O constructor.
724 ///
725 /// Note: We do *not* insert ourself into the current directory.
726 ///
727 
728 TTree::TTree()
729 : TNamed()
730 , TAttLine()
731 , TAttFill()
732 , TAttMarker()
733 , fEntries(0)
734 , fTotBytes(0)
735 , fZipBytes(0)
736 , fSavedBytes(0)
737 , fFlushedBytes(0)
738 , fWeight(1)
739 , fTimerInterval(0)
740 , fScanField(25)
741 , fUpdate(0)
743 , fNClusterRange(0)
744 , fMaxClusterRange(0)
745 , fMaxEntries(0)
746 , fMaxEntryLoop(0)
747 , fMaxVirtualSize(0)
748 , fAutoSave( -300000000)
749 , fAutoFlush(-30000000)
750 , fEstimate(1000000)
751 , fClusterRangeEnd(0)
752 , fClusterSize(0)
753 , fCacheSize(0)
754 , fChainOffset(0)
755 , fReadEntry(-1)
756 , fTotalBuffers(0)
757 , fPacketSize(100)
758 , fNfill(0)
759 , fDebug(0)
760 , fDebugMin(0)
761 , fDebugMax(9999999)
762 , fMakeClass(0)
763 , fFileNumber(0)
764 , fNotify(0)
765 , fDirectory(0)
766 , fBranches()
767 , fLeaves()
768 , fAliases(0)
769 , fEventList(0)
770 , fEntryList(0)
771 , fIndexValues()
772 , fIndex()
773 , fTreeIndex(0)
774 , fFriends(0)
775 , fExternalFriends(0)
776 , fPerfStats(0)
777 , fUserInfo(0)
778 , fPlayer(0)
779 , fClones(0)
780 , fBranchRef(0)
782 , fTransientBuffer(0)
788 {
789  fMaxEntries = 1000000000;
790  fMaxEntries *= 1000;
791 
792  fMaxEntryLoop = 1000000000;
793  fMaxEntryLoop *= 1000;
794 
796 }
797 
798 ////////////////////////////////////////////////////////////////////////////////
799 /// Normal tree constructor.
800 ///
801 /// The tree is created in the current directory.
802 /// Use the various functions Branch below to add branches to this tree.
803 ///
804 /// If the first character of title is a "/", the function assumes a folder name.
805 /// In this case, it creates automatically branches following the folder hierarchy.
806 /// splitlevel may be used in this case to control the split level.
807 
808 TTree::TTree(const char* name, const char* title, Int_t splitlevel /* = 99 */,
809  TDirectory* dir /* = gDirectory*/)
810 : TNamed(name, title)
811 , TAttLine()
812 , TAttFill()
813 , TAttMarker()
814 , fEntries(0)
815 , fTotBytes(0)
816 , fZipBytes(0)
817 , fSavedBytes(0)
818 , fFlushedBytes(0)
819 , fWeight(1)
820 , fTimerInterval(0)
821 , fScanField(25)
822 , fUpdate(0)
823 , fDefaultEntryOffsetLen(1000)
824 , fNClusterRange(0)
825 , fMaxClusterRange(0)
826 , fMaxEntries(0)
827 , fMaxEntryLoop(0)
828 , fMaxVirtualSize(0)
829 , fAutoSave( -300000000)
830 , fAutoFlush(-30000000)
831 , fEstimate(1000000)
832 , fClusterRangeEnd(0)
833 , fClusterSize(0)
834 , fCacheSize(0)
835 , fChainOffset(0)
836 , fReadEntry(-1)
837 , fTotalBuffers(0)
838 , fPacketSize(100)
839 , fNfill(0)
840 , fDebug(0)
841 , fDebugMin(0)
842 , fDebugMax(9999999)
843 , fMakeClass(0)
844 , fFileNumber(0)
845 , fNotify(0)
846 , fDirectory(dir)
847 , fBranches()
848 , fLeaves()
849 , fAliases(0)
850 , fEventList(0)
851 , fEntryList(0)
852 , fIndexValues()
853 , fIndex()
854 , fTreeIndex(0)
855 , fFriends(0)
856 , fExternalFriends(0)
857 , fPerfStats(0)
858 , fUserInfo(0)
859 , fPlayer(0)
860 , fClones(0)
861 , fBranchRef(0)
862 , fFriendLockStatus(0)
863 , fTransientBuffer(0)
864 , fCacheDoAutoInit(kTRUE)
865 , fCacheDoClusterPrefetch(kFALSE)
866 , fCacheUserSet(kFALSE)
867 , fIMTEnabled(ROOT::IsImplicitMTEnabled())
868 , fNEntriesSinceSorting(0)
869 {
870  // TAttLine state.
874 
875  // TAttFill state.
878 
879  // TAttMarkerState.
883 
884  fMaxEntries = 1000000000;
885  fMaxEntries *= 1000;
886 
887  fMaxEntryLoop = 1000000000;
888  fMaxEntryLoop *= 1000;
889 
890  // Insert ourself into the current directory.
891  // FIXME: This is very annoying behaviour, we should
892  // be able to choose to not do this like we
893  // can with a histogram.
894  if (fDirectory) fDirectory->Append(this);
895 
897 
898  // If title starts with "/" and is a valid folder name, a superbranch
899  // is created.
900  // FIXME: Why?
901  if (strlen(title) > 2) {
902  if (title[0] == '/') {
903  Branch(title+1,32000,splitlevel);
904  }
905  }
906 }
907 
908 ////////////////////////////////////////////////////////////////////////////////
909 /// Destructor.
910 
912 {
913  if (auto link = dynamic_cast<TNotifyLinkBase*>(fNotify)) {
914  link->Clear();
915  }
916  if (fAllocationCount && (gDebug > 0)) {
917  Info("TTree::~TTree", "For tree %s, allocation count is %u.", GetName(), fAllocationCount.load());
918 #ifdef R__TRACK_BASKET_ALLOC_TIME
919  Info("TTree::~TTree", "For tree %s, allocation time is %lluus.", GetName(), fAllocationTime.load());
920 #endif
921  }
922 
923  if (fDirectory) {
924  // We are in a directory, which may possibly be a file.
925  if (fDirectory->GetList()) {
926  // Remove us from the directory listing.
927  fDirectory->Remove(this);
928  }
929  //delete the file cache if it points to this Tree
931  MoveReadCache(file,0);
932  }
933  // We don't own the leaves in fLeaves, the branches do.
934  fLeaves.Clear();
935  // I'm ready to destroy any objects allocated by
936  // SetAddress() by my branches. If I have clones,
937  // tell them to zero their pointers to this shared
938  // memory.
939  if (fClones && fClones->GetEntries()) {
940  // I have clones.
941  // I am about to delete the objects created by
942  // SetAddress() which we are sharing, so tell
943  // the clones to release their pointers to them.
944  for (TObjLink* lnk = fClones->FirstLink(); lnk; lnk = lnk->Next()) {
945  TTree* clone = (TTree*) lnk->GetObject();
946  // clone->ResetBranchAddresses();
947 
948  // Reset only the branch we have set the address of.
949  CopyAddresses(clone,kTRUE);
950  }
951  }
952  // Get rid of our branches, note that this will also release
953  // any memory allocated by TBranchElement::SetAddress().
954  fBranches.Delete();
955  // FIXME: We must consider what to do with the reset of these if we are a clone.
956  delete fPlayer;
957  fPlayer = 0;
958  if (fExternalFriends) {
959  using namespace ROOT::Detail;
961  fetree->Reset();
962  fExternalFriends->Clear("nodelete");
964  }
965  if (fFriends) {
966  fFriends->Delete();
967  delete fFriends;
968  fFriends = 0;
969  }
970  if (fAliases) {
971  fAliases->Delete();
972  delete fAliases;
973  fAliases = 0;
974  }
975  if (fUserInfo) {
976  fUserInfo->Delete();
977  delete fUserInfo;
978  fUserInfo = 0;
979  }
980  if (fClones) {
981  // Clone trees should no longer be removed from fClones when they are deleted.
982  {
984  gROOT->GetListOfCleanups()->Remove(fClones);
985  }
986  // Note: fClones does not own its content.
987  delete fClones;
988  fClones = 0;
989  }
990  if (fEntryList) {
992  // Delete the entry list if it is marked to be deleted and it is not also
993  // owned by a directory. (Otherwise we would need to make sure that a
994  // TDirectoryFile that has a TTree in it does a 'slow' TList::Delete.
995  delete fEntryList;
996  fEntryList=0;
997  }
998  }
999  delete fTreeIndex;
1000  fTreeIndex = 0;
1001  delete fBranchRef;
1002  fBranchRef = 0;
1003  delete [] fClusterRangeEnd;
1004  fClusterRangeEnd = 0;
1005  delete [] fClusterSize;
1006  fClusterSize = 0;
1007  // Must be done after the destruction of friends.
1008  // Note: We do *not* own our directory.
1009  fDirectory = 0;
1010 
1011  if (fTransientBuffer) {
1012  delete fTransientBuffer;
1013  fTransientBuffer = 0;
1014  }
1015 }
1016 
1017 ////////////////////////////////////////////////////////////////////////////////
1018 /// Returns the transient buffer currently used by this TTree for reading/writing baskets.
1021 {
1022  if (fTransientBuffer) {
1023  if (fTransientBuffer->BufferSize() < size) {
1024  fTransientBuffer->Expand(size);
1025  }
1026  return fTransientBuffer;
1027  }
1029  return fTransientBuffer;
1030 }
1031 
1032 ////////////////////////////////////////////////////////////////////////////////
1033 /// Add branch with name bname to the Tree cache.
1034 /// If bname="*" all branches are added to the cache.
1035 /// if subbranches is true all the branches of the subbranches are
1036 /// also put to the cache.
1037 ///
1038 /// Returns:
1039 /// - 0 branch added or already included
1040 /// - -1 on error
1042 Int_t TTree::AddBranchToCache(const char*bname, Bool_t subbranches)
1043 {
1044  if (!GetTree()) {
1045  if (LoadTree(0)<0) {
1046  Error("AddBranchToCache","Could not load a tree");
1047  return -1;
1048  }
1049  }
1050  if (GetTree()) {
1051  if (GetTree() != this) {
1052  return GetTree()->AddBranchToCache(bname, subbranches);
1053  }
1054  } else {
1055  Error("AddBranchToCache", "No tree is available. Branch was not added to the cache");
1056  return -1;
1057  }
1058 
1059  TFile *f = GetCurrentFile();
1060  if (!f) {
1061  Error("AddBranchToCache", "No file is available. Branch was not added to the cache");
1062  return -1;
1063  }
1064  TTreeCache *tc = GetReadCache(f,kTRUE);
1065  if (!tc) {
1066  Error("AddBranchToCache", "No cache is available, branch not added");
1067  return -1;
1068  }
1069  return tc->AddBranch(bname,subbranches);
1070 }
1071 
1072 ////////////////////////////////////////////////////////////////////////////////
1073 /// Add branch b to the Tree cache.
1074 /// if subbranches is true all the branches of the subbranches are
1075 /// also put to the cache.
1076 ///
1077 /// Returns:
1078 /// - 0 branch added or already included
1079 /// - -1 on error
1082 {
1083  if (!GetTree()) {
1084  if (LoadTree(0)<0) {
1085  Error("AddBranchToCache","Could not load a tree");
1086  return -1;
1087  }
1088  }
1089  if (GetTree()) {
1090  if (GetTree() != this) {
1091  Int_t res = GetTree()->AddBranchToCache(b, subbranches);
1092  if (res<0) {
1093  Error("AddBranchToCache", "Error adding branch");
1094  }
1095  return res;
1096  }
1097  } else {
1098  Error("AddBranchToCache", "No tree is available. Branch was not added to the cache");
1099  return -1;
1100  }
1101 
1102  TFile *f = GetCurrentFile();
1103  if (!f) {
1104  Error("AddBranchToCache", "No file is available. Branch was not added to the cache");
1105  return -1;
1106  }
1107  TTreeCache *tc = GetReadCache(f,kTRUE);
1108  if (!tc) {
1109  Error("AddBranchToCache", "No cache is available, branch not added");
1110  return -1;
1111  }
1112  return tc->AddBranch(b,subbranches);
1113 }
1114 
1115 ////////////////////////////////////////////////////////////////////////////////
1116 /// Remove the branch with name 'bname' from the Tree cache.
1117 /// If bname="*" all branches are removed from the cache.
1118 /// if subbranches is true all the branches of the subbranches are
1119 /// also removed from the cache.
1120 ///
1121 /// Returns:
1122 /// - 0 branch dropped or not in cache
1123 /// - -1 on error
1125 Int_t TTree::DropBranchFromCache(const char*bname, Bool_t subbranches)
1126 {
1127  if (!GetTree()) {
1128  if (LoadTree(0)<0) {
1129  Error("DropBranchFromCache","Could not load a tree");
1130  return -1;
1131  }
1132  }
1133  if (GetTree()) {
1134  if (GetTree() != this) {
1135  return GetTree()->DropBranchFromCache(bname, subbranches);
1136  }
1137  } else {
1138  Error("DropBranchFromCache", "No tree is available. Branch was not dropped from the cache");
1139  return -1;
1140  }
1141 
1142  TFile *f = GetCurrentFile();
1143  if (!f) {
1144  Error("DropBranchFromCache", "No file is available. Branch was not dropped from the cache");
1145  return -1;
1146  }
1147  TTreeCache *tc = GetReadCache(f,kTRUE);
1148  if (!tc) {
1149  Error("DropBranchFromCache", "No cache is available, branch not dropped");
1150  return -1;
1151  }
1152  return tc->DropBranch(bname,subbranches);
1153 }
1154 
1155 ////////////////////////////////////////////////////////////////////////////////
1156 /// Remove the branch b from the Tree cache.
1157 /// if subbranches is true all the branches of the subbranches are
1158 /// also removed from the cache.
1159 ///
1160 /// Returns:
1161 /// - 0 branch dropped or not in cache
1162 /// - -1 on error
1165 {
1166  if (!GetTree()) {
1167  if (LoadTree(0)<0) {
1168  Error("DropBranchFromCache","Could not load a tree");
1169  return -1;
1170  }
1171  }
1172  if (GetTree()) {
1173  if (GetTree() != this) {
1174  Int_t res = GetTree()->DropBranchFromCache(b, subbranches);
1175  if (res<0) {
1176  Error("DropBranchFromCache", "Error dropping branch");
1177  }
1178  return res;
1179  }
1180  } else {
1181  Error("DropBranchFromCache", "No tree is available. Branch was not dropped from the cache");
1182  return -1;
1183  }
1184 
1185  TFile *f = GetCurrentFile();
1186  if (!f) {
1187  Error("DropBranchFromCache", "No file is available. Branch was not dropped from the cache");
1188  return -1;
1189  }
1190  TTreeCache *tc = GetReadCache(f,kTRUE);
1191  if (!tc) {
1192  Error("DropBranchFromCache", "No cache is available, branch not dropped");
1193  return -1;
1194  }
1195  return tc->DropBranch(b,subbranches);
1196 }
1197 
1198 ////////////////////////////////////////////////////////////////////////////////
1199 /// Add a cloned tree to our list of trees to be notified whenever we change
1200 /// our branch addresses or when we are deleted.
1202 void TTree::AddClone(TTree* clone)
1203 {
1204  if (!fClones) {
1205  fClones = new TList();
1206  fClones->SetOwner(false);
1207  // So that the clones are automatically removed from the list when
1208  // they are deleted.
1209  {
1211  gROOT->GetListOfCleanups()->Add(fClones);
1212  }
1213  }
1214  if (!fClones->FindObject(clone)) {
1215  fClones->Add(clone);
1216  }
1217 }
1218 
1219 // Check whether mainTree and friendTree can be friends w.r.t. the kEntriesReshuffled bit.
1220 // In particular, if any has the bit set, then friendTree must have a TTreeIndex and the
1221 // branches used for indexing must be present in mainTree.
1222 // Return true if the trees can be friends, false otherwise.
1223 bool CheckReshuffling(TTree &mainTree, TTree &friendTree)
1224 {
1225  const auto isMainReshuffled = mainTree.TestBit(TTree::kEntriesReshuffled);
1226  const auto isFriendReshuffled = friendTree.TestBit(TTree::kEntriesReshuffled);
1227  const auto friendHasValidIndex = [&] {
1228  auto idx = friendTree.GetTreeIndex();
1229  return idx ? idx->IsValidFor(&mainTree) : kFALSE;
1230  }();
1231 
1232  if ((isMainReshuffled || isFriendReshuffled) && !friendHasValidIndex) {
1233  const auto reshuffledTreeName = isMainReshuffled ? mainTree.GetName() : friendTree.GetName();
1234  const auto msg = "Tree '%s' has the kEntriesReshuffled bit set, and cannot be used as friend nor can be added as "
1235  "a friend unless the main tree has a TTreeIndex on the friend tree '%s'. You can also unset the "
1236  "bit manually if you know what you are doing.";
1237  Error("AddFriend", msg, reshuffledTreeName, friendTree.GetName());
1238  return false;
1239  }
1240  return true;
1241 }
1242 
1243 ////////////////////////////////////////////////////////////////////////////////
1244 /// Add a TFriendElement to the list of friends.
1245 ///
1246 /// This function:
1247 /// - opens a file if filename is specified
1248 /// - reads a Tree with name treename from the file (current directory)
1249 /// - adds the Tree to the list of friends
1250 /// see other AddFriend functions
1251 ///
1252 /// A TFriendElement TF describes a TTree object TF in a file.
1253 /// When a TFriendElement TF is added to the the list of friends of an
1254 /// existing TTree T, any variable from TF can be referenced in a query
1255 /// to T.
1256 ///
1257 /// A tree keeps a list of friends. In the context of a tree (or a chain),
1258 /// friendship means unrestricted access to the friends data. In this way
1259 /// it is much like adding another branch to the tree without taking the risk
1260 /// of damaging it. To add a friend to the list, you can use the TTree::AddFriend
1261 /// method. The tree in the diagram below has two friends (friend_tree1 and
1262 /// friend_tree2) and now has access to the variables a,b,c,i,j,k,l and m.
1263 ///
1264 /// \image html ttree_friend1.png
1265 ///
1266 /// The AddFriend method has two parameters, the first is the tree name and the
1267 /// second is the name of the ROOT file where the friend tree is saved.
1268 /// AddFriend automatically opens the friend file. If no file name is given,
1269 /// the tree called ft1 is assumed to be in the same file as the original tree.
1270 ///
1271 /// tree.AddFriend("ft1","friendfile1.root");
1272 /// If the friend tree has the same name as the original tree, you can give it
1273 /// an alias in the context of the friendship:
1274 ///
1275 /// tree.AddFriend("tree1 = tree","friendfile1.root");
1276 /// Once the tree has friends, we can use TTree::Draw as if the friend's
1277 /// variables were in the original tree. To specify which tree to use in
1278 /// the Draw method, use the syntax:
1279 /// ~~~ {.cpp}
1280 /// <treeName>.<branchname>.<varname>
1281 /// ~~~
1282 /// If the variablename is enough to uniquely identify the variable, you can
1283 /// leave out the tree and/or branch name.
1284 /// For example, these commands generate a 3-d scatter plot of variable "var"
1285 /// in the TTree tree versus variable v1 in TTree ft1 versus variable v2 in
1286 /// TTree ft2.
1287 /// ~~~ {.cpp}
1288 /// tree.AddFriend("ft1","friendfile1.root");
1289 /// tree.AddFriend("ft2","friendfile2.root");
1290 /// tree.Draw("var:ft1.v1:ft2.v2");
1291 /// ~~~
1292 /// \image html ttree_friend2.png
1293 ///
1294 /// The picture illustrates the access of the tree and its friends with a
1295 /// Draw command.
1296 /// When AddFriend is called, the ROOT file is automatically opened and the
1297 /// friend tree (ft1) is read into memory. The new friend (ft1) is added to
1298 /// the list of friends of tree.
1299 /// The number of entries in the friend must be equal or greater to the number
1300 /// of entries of the original tree. If the friend tree has fewer entries a
1301 /// warning is given and the missing entries are not included in the histogram.
1302 /// To retrieve the list of friends from a tree use TTree::GetListOfFriends.
1303 /// When the tree is written to file (TTree::Write), the friends list is saved
1304 /// with it. And when the tree is retrieved, the trees on the friends list are
1305 /// also retrieved and the friendship restored.
1306 /// When a tree is deleted, the elements of the friend list are also deleted.
1307 /// It is possible to declare a friend tree that has the same internal
1308 /// structure (same branches and leaves) as the original tree, and compare the
1309 /// same values by specifying the tree.
1310 /// ~~~ {.cpp}
1311 /// tree.Draw("var:ft1.var:ft2.var")
1312 /// ~~~
1314 TFriendElement *TTree::AddFriend(const char *treename, const char *filename)
1315 {
1316  if (!fFriends) {
1317  fFriends = new TList();
1318  }
1319  TFriendElement *fe = new TFriendElement(this, treename, filename);
1320 
1321  TTree *t = fe->GetTree();
1322  bool canAddFriend = true;
1323  if (t) {
1324  canAddFriend = CheckReshuffling(*this, *t);
1325  if (!t->GetTreeIndex() && (t->GetEntries() < fEntries)) {
1326  Warning("AddFriend", "FriendElement %s in file %s has less entries %lld than its parent Tree: %lld", treename,
1327  filename, t->GetEntries(), fEntries);
1328  }
1329  } else {
1330  Error("AddFriend", "Cannot find tree '%s' in file '%s', friend not added", treename, filename);
1331  canAddFriend = false;
1332  }
1333 
1334  if (canAddFriend)
1335  fFriends->Add(fe);
1336  return fe;
1337 }
1338 
1339 ////////////////////////////////////////////////////////////////////////////////
1340 /// Add a TFriendElement to the list of friends.
1341 ///
1342 /// The TFile is managed by the user (e.g. the user must delete the file).
1343 /// For complete description see AddFriend(const char *, const char *).
1344 /// This function:
1345 /// - reads a Tree with name treename from the file
1346 /// - adds the Tree to the list of friends
1348 TFriendElement *TTree::AddFriend(const char *treename, TFile *file)
1349 {
1350  if (!fFriends) {
1351  fFriends = new TList();
1352  }
1353  TFriendElement *fe = new TFriendElement(this, treename, file);
1354  R__ASSERT(fe);
1355  TTree *t = fe->GetTree();
1356  bool canAddFriend = true;
1357  if (t) {
1358  canAddFriend = CheckReshuffling(*this, *t);
1359  if (!t->GetTreeIndex() && (t->GetEntries() < fEntries)) {
1360  Warning("AddFriend", "FriendElement %s in file %s has less entries %lld than its parent tree: %lld", treename,
1361  file->GetName(), t->GetEntries(), fEntries);
1362  }
1363  } else {
1364  Error("AddFriend", "Cannot find tree '%s' in file '%s', friend not added", treename, file->GetName());
1365  canAddFriend = false;
1366  }
1367 
1368  if (canAddFriend)
1369  fFriends->Add(fe);
1370  return fe;
1371 }
1372 
1373 ////////////////////////////////////////////////////////////////////////////////
1374 /// Add a TFriendElement to the list of friends.
1375 ///
1376 /// The TTree is managed by the user (e.g., the user must delete the file).
1377 /// For a complete description see AddFriend(const char *, const char *).
1379 TFriendElement *TTree::AddFriend(TTree *tree, const char *alias, Bool_t warn)
1380 {
1381  if (!tree) {
1382  return 0;
1383  }
1384  if (!fFriends) {
1385  fFriends = new TList();
1386  }
1387  TFriendElement *fe = new TFriendElement(this, tree, alias);
1388  R__ASSERT(fe); // this assert is for historical reasons. Don't remove it unless you understand all the consequences.
1389  TTree *t = fe->GetTree();
1390  if (warn && (t->GetEntries() < fEntries)) {
1391  Warning("AddFriend", "FriendElement '%s' in file '%s' has less entries %lld than its parent tree: %lld",
1392  tree->GetName(), fe->GetFile() ? fe->GetFile()->GetName() : "(memory resident)", t->GetEntries(),
1393  fEntries);
1394  }
1395  if (CheckReshuffling(*this, *t)) {
1396  fFriends->Add(fe);
1397  tree->RegisterExternalFriend(fe);
1398  }
1399  return fe;
1400 }
1401 
1402 ////////////////////////////////////////////////////////////////////////////////
1403 /// AutoSave tree header every fAutoSave bytes.
1404 ///
1405 /// When large Trees are produced, it is safe to activate the AutoSave
1406 /// procedure. Some branches may have buffers holding many entries.
1407 /// If fAutoSave is negative, AutoSave is automatically called by
1408 /// TTree::Fill when the number of bytes generated since the previous
1409 /// AutoSave is greater than -fAutoSave bytes.
1410 /// If fAutoSave is positive, AutoSave is automatically called by
1411 /// TTree::Fill every N entries.
1412 /// This function may also be invoked by the user.
1413 /// Each AutoSave generates a new key on the file.
1414 /// Once the key with the tree header has been written, the previous cycle
1415 /// (if any) is deleted.
1416 ///
1417 /// Note that calling TTree::AutoSave too frequently (or similarly calling
1418 /// TTree::SetAutoSave with a small value) is an expensive operation.
1419 /// You should make tests for your own application to find a compromise
1420 /// between speed and the quantity of information you may loose in case of
1421 /// a job crash.
1422 ///
1423 /// In case your program crashes before closing the file holding this tree,
1424 /// the file will be automatically recovered when you will connect the file
1425 /// in UPDATE mode.
1426 /// The Tree will be recovered at the status corresponding to the last AutoSave.
1427 ///
1428 /// if option contains "SaveSelf", gDirectory->SaveSelf() is called.
1429 /// This allows another process to analyze the Tree while the Tree is being filled.
1430 ///
1431 /// if option contains "FlushBaskets", TTree::FlushBaskets is called and all
1432 /// the current basket are closed-out and written to disk individually.
1433 ///
1434 /// By default the previous header is deleted after having written the new header.
1435 /// if option contains "Overwrite", the previous Tree header is deleted
1436 /// before written the new header. This option is slightly faster, but
1437 /// the default option is safer in case of a problem (disk quota exceeded)
1438 /// when writing the new header.
1439 ///
1440 /// The function returns the number of bytes written to the file.
1441 /// if the number of bytes is null, an error has occurred while writing
1442 /// the header to the file.
1443 ///
1444 /// ## How to write a Tree in one process and view it from another process
1445 ///
1446 /// The following two scripts illustrate how to do this.
1447 /// The script treew.C is executed by process1, treer.C by process2
1448 ///
1449 /// script treew.C:
1450 /// ~~~ {.cpp}
1451 /// void treew() {
1452 /// TFile f("test.root","recreate");
1453 /// TNtuple *ntuple = new TNtuple("ntuple","Demo","px:py:pz:random:i");
1454 /// Float_t px, py, pz;
1455 /// for ( Int_t i=0; i<10000000; i++) {
1456 /// gRandom->Rannor(px,py);
1457 /// pz = px*px + py*py;
1458 /// Float_t random = gRandom->Rndm(1);
1459 /// ntuple->Fill(px,py,pz,random,i);
1460 /// if (i%1000 == 1) ntuple->AutoSave("SaveSelf");
1461 /// }
1462 /// }
1463 /// ~~~
1464 /// script treer.C:
1465 /// ~~~ {.cpp}
1466 /// void treer() {
1467 /// TFile f("test.root");
1468 /// TTree *ntuple = (TTree*)f.Get("ntuple");
1469 /// TCanvas c1;
1470 /// Int_t first = 0;
1471 /// while(1) {
1472 /// if (first == 0) ntuple->Draw("px>>hpx", "","",10000000,first);
1473 /// else ntuple->Draw("px>>+hpx","","",10000000,first);
1474 /// first = (Int_t)ntuple->GetEntries();
1475 /// c1.Update();
1476 /// gSystem->Sleep(1000); //sleep 1 second
1477 /// ntuple->Refresh();
1478 /// }
1479 /// }
1480 /// ~~~
1483 {
1484  if (!fDirectory || fDirectory == gROOT || !fDirectory->IsWritable()) return 0;
1485  if (gDebug > 0) {
1486  Info("AutoSave", "Tree:%s after %lld bytes written\n",GetName(),GetTotBytes());
1487  }
1488  TString opt = option;
1489  opt.ToLower();
1490 
1491  if (opt.Contains("flushbaskets")) {
1492  if (gDebug > 0) Info("AutoSave", "calling FlushBaskets \n");
1493  FlushBasketsImpl();
1494  }
1495 
1497 
1499  Long64_t nbytes;
1500  if (opt.Contains("overwrite")) {
1501  nbytes = fDirectory->WriteTObject(this,"","overwrite");
1502  } else {
1503  nbytes = fDirectory->WriteTObject(this); //nbytes will be 0 if Write failed (disk space exceeded)
1504  if (nbytes && key && strcmp(ClassName(), key->GetClassName()) == 0) {
1505  key->Delete();
1506  delete key;
1507  }
1508  }
1509  // save StreamerInfo
1510  TFile *file = fDirectory->GetFile();
1511  if (file) file->WriteStreamerInfo();
1512 
1513  if (opt.Contains("saveself")) {
1514  fDirectory->SaveSelf();
1515  //the following line is required in case GetUserInfo contains a user class
1516  //for which the StreamerInfo must be written. One could probably be a bit faster (Rene)
1517  if (file) file->WriteHeader();
1518  }
1519 
1520  return nbytes;
1521 }
1522 
1523 namespace {
1524  // This error message is repeated several times in the code. We write it once.
1525  const char* writeStlWithoutProxyMsg = "The class requested (%s) for the branch \"%s\""
1526  " is an instance of an stl collection and does not have a compiled CollectionProxy."
1527  " Please generate the dictionary for this collection (%s) to avoid to write corrupted data.";
1528 }
1529 
1530 ////////////////////////////////////////////////////////////////////////////////
1531 /// Same as TTree::Branch() with added check that addobj matches className.
1532 ///
1533 /// See TTree::Branch() for other details.
1534 ///
1536 TBranch* TTree::BranchImp(const char* branchname, const char* classname, TClass* ptrClass, void* addobj, Int_t bufsize, Int_t splitlevel)
1537 {
1538  TClass* claim = TClass::GetClass(classname);
1539  if (!ptrClass) {
1540  if (claim && claim->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(claim->GetCollectionProxy())) {
1541  Error("Branch", writeStlWithoutProxyMsg,
1542  claim->GetName(), branchname, claim->GetName());
1543  return 0;
1544  }
1545  return Branch(branchname, classname, (void*) addobj, bufsize, splitlevel);
1546  }
1547  TClass* actualClass = 0;
1548  void** addr = (void**) addobj;
1549  if (addr) {
1550  actualClass = ptrClass->GetActualClass(*addr);
1551  }
1552  if (ptrClass && claim) {
1553  if (!(claim->InheritsFrom(ptrClass) || ptrClass->InheritsFrom(claim))) {
1554  // Note we currently do not warn in case of splicing or over-expectation).
1555  if (claim->IsLoaded() && ptrClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), ptrClass->GetTypeInfo()->name() ) == 0) {
1556  // The type is the same according to the C++ type_info, we must be in the case of
1557  // a template of Double32_t. This is actually a correct case.
1558  } else {
1559  Error("Branch", "The class requested (%s) for \"%s\" is different from the type of the pointer passed (%s)",
1560  claim->GetName(), branchname, ptrClass->GetName());
1561  }
1562  } else if (actualClass && (claim != actualClass) && !actualClass->InheritsFrom(claim)) {
1563  if (claim->IsLoaded() && actualClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), actualClass->GetTypeInfo()->name() ) == 0) {
1564  // The type is the same according to the C++ type_info, we must be in the case of
1565  // a template of Double32_t. This is actually a correct case.
1566  } else {
1567  Error("Branch", "The actual class (%s) of the object provided for the definition of the branch \"%s\" does not inherit from %s",
1568  actualClass->GetName(), branchname, claim->GetName());
1569  }
1570  }
1571  }
1572  if (claim && claim->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(claim->GetCollectionProxy())) {
1573  Error("Branch", writeStlWithoutProxyMsg,
1574  claim->GetName(), branchname, claim->GetName());
1575  return 0;
1576  }
1577  return Branch(branchname, classname, (void*) addobj, bufsize, splitlevel);
1578 }
1579 
1580 ////////////////////////////////////////////////////////////////////////////////
1581 /// Same as TTree::Branch but automatic detection of the class name.
1582 /// See TTree::Branch for other details.
1584 TBranch* TTree::BranchImp(const char* branchname, TClass* ptrClass, void* addobj, Int_t bufsize, Int_t splitlevel)
1585 {
1586  if (!ptrClass) {
1587  Error("Branch", "The pointer specified for %s is not of a class known to ROOT", branchname);
1588  return 0;
1589  }
1590  TClass* actualClass = 0;
1591  void** addr = (void**) addobj;
1592  if (addr && *addr) {
1593  actualClass = ptrClass->GetActualClass(*addr);
1594  if (!actualClass) {
1595  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",
1596  branchname, ptrClass->GetName());
1597  actualClass = ptrClass;
1598  } else if ((ptrClass != actualClass) && !actualClass->InheritsFrom(ptrClass)) {
1599  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());
1600  return 0;
1601  }
1602  } else {
1603  actualClass = ptrClass;
1604  }
1605  if (actualClass && actualClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(actualClass->GetCollectionProxy())) {
1606  Error("Branch", writeStlWithoutProxyMsg,
1607  actualClass->GetName(), branchname, actualClass->GetName());
1608  return 0;
1609  }
1610  return Branch(branchname, actualClass->GetName(), (void*) addobj, bufsize, splitlevel);
1611 }
1612 
1613 ////////////////////////////////////////////////////////////////////////////////
1614 /// Same as TTree::Branch but automatic detection of the class name.
1615 /// See TTree::Branch for other details.
1617 TBranch* TTree::BranchImpRef(const char* branchname, const char *classname, TClass* ptrClass, void *addobj, Int_t bufsize, Int_t splitlevel)
1618 {
1619  TClass* claim = TClass::GetClass(classname);
1620  if (!ptrClass) {
1621  if (claim && claim->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(claim->GetCollectionProxy())) {
1622  Error("Branch", writeStlWithoutProxyMsg,
1623  claim->GetName(), branchname, claim->GetName());
1624  return 0;
1625  } else if (claim == 0) {
1626  Error("Branch", "The pointer specified for %s is not of a class known to ROOT and %s is not a known class", branchname, classname);
1627  return 0;
1628  }
1629  ptrClass = claim;
1630  }
1631  TClass* actualClass = 0;
1632  if (!addobj) {
1633  Error("Branch", "Reference interface requires a valid object (for branch: %s)!", branchname);
1634  return 0;
1635  }
1636  actualClass = ptrClass->GetActualClass(addobj);
1637  if (ptrClass && claim) {
1638  if (!(claim->InheritsFrom(ptrClass) || ptrClass->InheritsFrom(claim))) {
1639  // Note we currently do not warn in case of splicing or over-expectation).
1640  if (claim->IsLoaded() && ptrClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), ptrClass->GetTypeInfo()->name() ) == 0) {
1641  // The type is the same according to the C++ type_info, we must be in the case of
1642  // a template of Double32_t. This is actually a correct case.
1643  } else {
1644  Error("Branch", "The class requested (%s) for \"%s\" is different from the type of the object passed (%s)",
1645  claim->GetName(), branchname, ptrClass->GetName());
1646  }
1647  } else if (actualClass && (claim != actualClass) && !actualClass->InheritsFrom(claim)) {
1648  if (claim->IsLoaded() && actualClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), actualClass->GetTypeInfo()->name() ) == 0) {
1649  // The type is the same according to the C++ type_info, we must be in the case of
1650  // a template of Double32_t. This is actually a correct case.
1651  } else {
1652  Error("Branch", "The actual class (%s) of the object provided for the definition of the branch \"%s\" does not inherit from %s",
1653  actualClass->GetName(), branchname, claim->GetName());
1654  }
1655  }
1656  }
1657  if (!actualClass) {
1658  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",
1659  branchname, ptrClass->GetName());
1660  actualClass = ptrClass;
1661  } else if ((ptrClass != actualClass) && !actualClass->InheritsFrom(ptrClass)) {
1662  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());
1663  return 0;
1664  }
1665  if (actualClass && actualClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(actualClass->GetCollectionProxy())) {
1666  Error("Branch", writeStlWithoutProxyMsg,
1667  actualClass->GetName(), branchname, actualClass->GetName());
1668  return 0;
1669  }
1670  return BronchExec(branchname, actualClass->GetName(), (void*) addobj, kFALSE, bufsize, splitlevel);
1671 }
1672 
1673 ////////////////////////////////////////////////////////////////////////////////
1674 /// Same as TTree::Branch but automatic detection of the class name.
1675 /// See TTree::Branch for other details.
1677 TBranch* TTree::BranchImpRef(const char* branchname, TClass* ptrClass, EDataType datatype, void* addobj, Int_t bufsize, Int_t splitlevel)
1678 {
1679  if (!ptrClass) {
1680  if (datatype == kOther_t || datatype == kNoType_t) {
1681  Error("Branch", "The pointer specified for %s is not of a class or type known to ROOT", branchname);
1682  } else {
1683  TString varname; varname.Form("%s/%c",branchname,DataTypeToChar(datatype));
1684  return Branch(branchname,addobj,varname.Data(),bufsize);
1685  }
1686  return 0;
1687  }
1688  TClass* actualClass = 0;
1689  if (!addobj) {
1690  Error("Branch", "Reference interface requires a valid object (for branch: %s)!", branchname);
1691  return 0;
1692  }
1693  actualClass = ptrClass->GetActualClass(addobj);
1694  if (!actualClass) {
1695  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",
1696  branchname, ptrClass->GetName());
1697  actualClass = ptrClass;
1698  } else if ((ptrClass != actualClass) && !actualClass->InheritsFrom(ptrClass)) {
1699  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());
1700  return 0;
1701  }
1702  if (actualClass && actualClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(actualClass->GetCollectionProxy())) {
1703  Error("Branch", writeStlWithoutProxyMsg,
1704  actualClass->GetName(), branchname, actualClass->GetName());
1705  return 0;
1706  }
1707  return BronchExec(branchname, actualClass->GetName(), (void*) addobj, kFALSE, bufsize, splitlevel);
1708 }
1709 
1710 ////////////////////////////////////////////////////////////////////////////////
1711 // Wrapper to turn Branch call with an std::array into the relevant leaf list
1712 // call
1713 TBranch *TTree::BranchImpArr(const char *branchname, EDataType datatype, std::size_t N, void *addobj, Int_t bufsize,
1714  Int_t /* splitlevel */)
1715 {
1716  if (datatype == kOther_t || datatype == kNoType_t) {
1717  Error("Branch",
1718  "The inner type of the std::array passed specified for %s is not of a class or type known to ROOT",
1719  branchname);
1720  } else {
1721  TString varname;
1722  varname.Form("%s[%d]/%c", branchname, (int)N, DataTypeToChar(datatype));
1723  return Branch(branchname, addobj, varname.Data(), bufsize);
1724  }
1725  return nullptr;
1726 }
1727 
1728 ////////////////////////////////////////////////////////////////////////////////
1729 /// Deprecated function. Use next function instead.
1731 Int_t TTree::Branch(TList* li, Int_t bufsize /* = 32000 */ , Int_t splitlevel /* = 99 */)
1732 {
1733  return Branch((TCollection*) li, bufsize, splitlevel);
1734 }
1735 
1736 ////////////////////////////////////////////////////////////////////////////////
1737 /// Create one branch for each element in the collection.
1738 ///
1739 /// Each entry in the collection becomes a top level branch if the
1740 /// corresponding class is not a collection. If it is a collection, the entry
1741 /// in the collection becomes in turn top level branches, etc.
1742 /// The splitlevel is decreased by 1 every time a new collection is found.
1743 /// For example if list is a TObjArray*
1744 /// - if splitlevel = 1, one top level branch is created for each element
1745 /// of the TObjArray.
1746 /// - if splitlevel = 2, one top level branch is created for each array element.
1747 /// if, in turn, one of the array elements is a TCollection, one top level
1748 /// branch will be created for each element of this collection.
1749 ///
1750 /// In case a collection element is a TClonesArray, the special Tree constructor
1751 /// for TClonesArray is called.
1752 /// The collection itself cannot be a TClonesArray.
1753 ///
1754 /// The function returns the total number of branches created.
1755 ///
1756 /// If name is given, all branch names will be prefixed with name_.
1757 ///
1758 /// IMPORTANT NOTE1: This function should not be called with splitlevel < 1.
1759 ///
1760 /// IMPORTANT NOTE2: The branches created by this function will have names
1761 /// corresponding to the collection or object names. It is important
1762 /// to give names to collections to avoid misleading branch names or
1763 /// identical branch names. By default collections have a name equal to
1764 /// the corresponding class name, e.g. the default name for a TList is "TList".
1765 ///
1766 /// And in general, in case two or more master branches contain subbranches
1767 /// with identical names, one must add a "." (dot) character at the end
1768 /// of the master branch name. This will force the name of the subbranches
1769 /// to be of the form `master.subbranch` instead of simply `subbranch`.
1770 /// This situation happens when the top level object
1771 /// has two or more members referencing the same class.
1772 /// For example, if a Tree has two branches B1 and B2 corresponding
1773 /// to objects of the same class MyClass, one can do:
1774 /// ~~~ {.cpp}
1775 /// tree.Branch("B1.","MyClass",&b1,8000,1);
1776 /// tree.Branch("B2.","MyClass",&b2,8000,1);
1777 /// ~~~
1778 /// if MyClass has 3 members a,b,c, the two instructions above will generate
1779 /// subbranches called B1.a, B1.b ,B1.c, B2.a, B2.b, B2.c
1780 ///
1781 /// Example:
1782 /// ~~~ {.cpp}
1783 /// {
1784 /// TTree T("T","test list");
1785 /// TList *list = new TList();
1786 ///
1787 /// TObjArray *a1 = new TObjArray();
1788 /// a1->SetName("a1");
1789 /// list->Add(a1);
1790 /// TH1F *ha1a = new TH1F("ha1a","ha1",100,0,1);
1791 /// TH1F *ha1b = new TH1F("ha1b","ha1",100,0,1);
1792 /// a1->Add(ha1a);
1793 /// a1->Add(ha1b);
1794 /// TObjArray *b1 = new TObjArray();
1795 /// b1->SetName("b1");
1796 /// list->Add(b1);
1797 /// TH1F *hb1a = new TH1F("hb1a","hb1",100,0,1);
1798 /// TH1F *hb1b = new TH1F("hb1b","hb1",100,0,1);
1799 /// b1->Add(hb1a);
1800 /// b1->Add(hb1b);
1801 ///
1802 /// TObjArray *a2 = new TObjArray();
1803 /// a2->SetName("a2");
1804 /// list->Add(a2);
1805 /// TH1S *ha2a = new TH1S("ha2a","ha2",100,0,1);
1806 /// TH1S *ha2b = new TH1S("ha2b","ha2",100,0,1);
1807 /// a2->Add(ha2a);
1808 /// a2->Add(ha2b);
1809 ///
1810 /// T.Branch(list,16000,2);
1811 /// T.Print();
1812 /// }
1813 /// ~~~
1815 Int_t TTree::Branch(TCollection* li, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */, const char* name /* = "" */)
1816 {
1817 
1818  if (!li) {
1819  return 0;
1820  }
1821  TObject* obj = 0;
1822  Int_t nbranches = GetListOfBranches()->GetEntries();
1823  if (li->InheritsFrom(TClonesArray::Class())) {
1824  Error("Branch", "Cannot call this constructor for a TClonesArray");
1825  return 0;
1826  }
1827  Int_t nch = strlen(name);
1828  TString branchname;
1829  TIter next(li);
1830  while ((obj = next())) {
1831  if ((splitlevel > 1) && obj->InheritsFrom(TCollection::Class()) && !obj->InheritsFrom(TClonesArray::Class())) {
1832  TCollection* col = (TCollection*) obj;
1833  if (nch) {
1834  branchname.Form("%s_%s_", name, col->GetName());
1835  } else {
1836  branchname.Form("%s_", col->GetName());
1837  }
1838  Branch(col, bufsize, splitlevel - 1, branchname);
1839  } else {
1840  if (nch && (name[nch-1] == '_')) {
1841  branchname.Form("%s%s", name, obj->GetName());
1842  } else {
1843  if (nch) {
1844  branchname.Form("%s_%s", name, obj->GetName());
1845  } else {
1846  branchname.Form("%s", obj->GetName());
1847  }
1848  }
1849  if (splitlevel > 99) {
1850  branchname += ".";
1851  }
1852  Bronch(branchname, obj->ClassName(), li->GetObjectRef(obj), bufsize, splitlevel - 1);
1853  }
1854  }
1855  return GetListOfBranches()->GetEntries() - nbranches;
1856 }
1857 
1858 ////////////////////////////////////////////////////////////////////////////////
1859 /// Create one branch for each element in the folder.
1860 /// Returns the total number of branches created.
1862 Int_t TTree::Branch(const char* foldername, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */)
1863 {
1864  TObject* ob = gROOT->FindObjectAny(foldername);
1865  if (!ob) {
1866  return 0;
1867  }
1868  if (ob->IsA() != TFolder::Class()) {
1869  return 0;
1870  }
1871  Int_t nbranches = GetListOfBranches()->GetEntries();
1872  TFolder* folder = (TFolder*) ob;
1873  TIter next(folder->GetListOfFolders());
1874  TObject* obj = 0;
1875  char* curname = new char[1000];
1876  char occur[20];
1877  while ((obj = next())) {
1878  snprintf(curname,1000, "%s/%s", foldername, obj->GetName());
1879  if (obj->IsA() == TFolder::Class()) {
1880  Branch(curname, bufsize, splitlevel - 1);
1881  } else {
1882  void* add = (void*) folder->GetListOfFolders()->GetObjectRef(obj);
1883  for (Int_t i = 0; i < 1000; ++i) {
1884  if (curname[i] == 0) {
1885  break;
1886  }
1887  if (curname[i] == '/') {
1888  curname[i] = '.';
1889  }
1890  }
1891  Int_t noccur = folder->Occurence(obj);
1892  if (noccur > 0) {
1893  snprintf(occur,20, "_%d", noccur);
1894  strlcat(curname, occur,1000);
1895  }
1896  TBranchElement* br = (TBranchElement*) Bronch(curname, obj->ClassName(), add, bufsize, splitlevel - 1);
1897  if (br) br->SetBranchFolder();
1898  }
1899  }
1900  delete[] curname;
1901  return GetListOfBranches()->GetEntries() - nbranches;
1902 }
1903 
1904 ////////////////////////////////////////////////////////////////////////////////
1905 /// Create a new TTree Branch.
1906 ///
1907 /// This Branch constructor is provided to support non-objects in
1908 /// a Tree. The variables described in leaflist may be simple
1909 /// variables or structures. // See the two following
1910 /// constructors for writing objects in a Tree.
1911 ///
1912 /// By default the branch buffers are stored in the same file as the Tree.
1913 /// use TBranch::SetFile to specify a different file
1914 ///
1915 /// * address is the address of the first item of a structure.
1916 /// * leaflist is the concatenation of all the variable names and types
1917 /// separated by a colon character :
1918 /// The variable name and the variable type are separated by a slash (/).
1919 /// The variable type may be 0,1 or 2 characters. If no type is given,
1920 /// the type of the variable is assumed to be the same as the previous
1921 /// variable. If the first variable does not have a type, it is assumed
1922 /// of type F by default. The list of currently supported types is given below:
1923 /// - `C` : a character string terminated by the 0 character
1924 /// - `B` : an 8 bit signed integer (`Char_t`)
1925 /// - `b` : an 8 bit unsigned integer (`UChar_t`)
1926 /// - `S` : a 16 bit signed integer (`Short_t`)
1927 /// - `s` : a 16 bit unsigned integer (`UShort_t`)
1928 /// - `I` : a 32 bit signed integer (`Int_t`)
1929 /// - `i` : a 32 bit unsigned integer (`UInt_t`)
1930 /// - `F` : a 32 bit floating point (`Float_t`)
1931 /// - `f` : a 24 bit floating point with truncated mantissa (`Float16_t`)
1932 /// - `D` : a 64 bit floating point (`Double_t`)
1933 /// - `d` : a 24 bit truncated floating point (`Double32_t`)
1934 /// - `L` : a 64 bit signed integer (`Long64_t`)
1935 /// - `l` : a 64 bit unsigned integer (`ULong64_t`)
1936 /// - `G` : a long signed integer, stored as 64 bit (`Long_t`)
1937 /// - `g` : a long unsigned integer, stored as 64 bit (`ULong_t`)
1938 /// - `O` : [the letter `o`, not a zero] a boolean (`Bool_t`)
1939 ///
1940 /// Arrays of values are supported with the following syntax:
1941 /// - If leaf name has the form var[nelem], where nelem is alphanumeric, then
1942 /// if nelem is a leaf name, it is used as the variable size of the array,
1943 /// otherwise return 0.
1944 /// - If leaf name has the form var[nelem], where nelem is a non-negative integer, then
1945 /// it is used as the fixed size of the array.
1946 /// - If leaf name has the form of a multi-dimensional array (e.g. var[nelem][nelem2])
1947 /// where nelem and nelem2 are non-negative integer) then
1948 /// it is used as a 2 dimensional array of fixed size.
1949 /// - In case of the truncated floating point types (Float16_t and Double32_t) you can
1950 /// furthermore specify the range in the style [xmin,xmax] or [xmin,xmax,nbits] after
1951 /// the type character. See `TStreamerElement::GetRange()` for further information.
1952 ///
1953 /// Any of other form is not supported.
1954 ///
1955 /// Note that the TTree will assume that all the item are contiguous in memory.
1956 /// On some platform, this is not always true of the member of a struct or a class,
1957 /// due to padding and alignment. Sorting your data member in order of decreasing
1958 /// sizeof usually leads to their being contiguous in memory.
1959 ///
1960 /// * bufsize is the buffer size in bytes for this branch
1961 /// The default value is 32000 bytes and should be ok for most cases.
1962 /// You can specify a larger value (e.g. 256000) if your Tree is not split
1963 /// and each entry is large (Megabytes)
1964 /// A small value for bufsize is optimum if you intend to access
1965 /// the entries in the Tree randomly and your Tree is in split mode.
1967 TBranch* TTree::Branch(const char* name, void* address, const char* leaflist, Int_t bufsize /* = 32000 */)
1968 {
1969  TBranch* branch = new TBranch(this, name, address, leaflist, bufsize);
1970  if (branch->IsZombie()) {
1971  delete branch;
1972  branch = 0;
1973  return 0;
1974  }
1975  fBranches.Add(branch);
1976  return branch;
1977 }
1978 
1979 ////////////////////////////////////////////////////////////////////////////////
1980 /// Create a new branch with the object of class classname at address addobj.
1981 ///
1982 /// WARNING:
1983 ///
1984 /// Starting with Root version 3.01, the Branch function uses the new style
1985 /// branches (TBranchElement). To get the old behaviour, you can:
1986 /// - call BranchOld or
1987 /// - call TTree::SetBranchStyle(0)
1988 ///
1989 /// Note that with the new style, classname does not need to derive from TObject.
1990 /// It must derived from TObject if the branch style has been set to 0 (old)
1991 ///
1992 /// Note: See the comments in TBranchElement::SetAddress() for a more
1993 /// detailed discussion of the meaning of the addobj parameter in
1994 /// the case of new-style branches.
1995 ///
1996 /// Use splitlevel < 0 instead of splitlevel=0 when the class
1997 /// has a custom Streamer
1998 ///
1999 /// Note: if the split level is set to the default (99), TTree::Branch will
2000 /// not issue a warning if the class can not be split.
2002 TBranch* TTree::Branch(const char* name, const char* classname, void* addobj, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */)
2003 {
2004  if (fgBranchStyle == 1) {
2005  return Bronch(name, classname, addobj, bufsize, splitlevel);
2006  } else {
2007  if (splitlevel < 0) {
2008  splitlevel = 0;
2009  }
2010  return BranchOld(name, classname, addobj, bufsize, splitlevel);
2011  }
2012 }
2013 
2014 ////////////////////////////////////////////////////////////////////////////////
2015 /// Create a new TTree BranchObject.
2016 ///
2017 /// Build a TBranchObject for an object of class classname.
2018 /// addobj is the address of a pointer to an object of class classname.
2019 /// IMPORTANT: classname must derive from TObject.
2020 /// The class dictionary must be available (ClassDef in class header).
2021 ///
2022 /// This option requires access to the library where the corresponding class
2023 /// is defined. Accessing one single data member in the object implies
2024 /// reading the full object.
2025 /// See the next Branch constructor for a more efficient storage
2026 /// in case the entry consists of arrays of identical objects.
2027 ///
2028 /// By default the branch buffers are stored in the same file as the Tree.
2029 /// use TBranch::SetFile to specify a different file
2030 ///
2031 /// IMPORTANT NOTE about branch names:
2032 ///
2033 /// And in general, in case two or more master branches contain subbranches
2034 /// with identical names, one must add a "." (dot) character at the end
2035 /// of the master branch name. This will force the name of the subbranches
2036 /// to be of the form `master.subbranch` instead of simply `subbranch`.
2037 /// This situation happens when the top level object
2038 /// has two or more members referencing the same class.
2039 /// For example, if a Tree has two branches B1 and B2 corresponding
2040 /// to objects of the same class MyClass, one can do:
2041 /// ~~~ {.cpp}
2042 /// tree.Branch("B1.","MyClass",&b1,8000,1);
2043 /// tree.Branch("B2.","MyClass",&b2,8000,1);
2044 /// ~~~
2045 /// if MyClass has 3 members a,b,c, the two instructions above will generate
2046 /// subbranches called B1.a, B1.b ,B1.c, B2.a, B2.b, B2.c
2047 ///
2048 /// bufsize is the buffer size in bytes for this branch
2049 /// The default value is 32000 bytes and should be ok for most cases.
2050 /// You can specify a larger value (e.g. 256000) if your Tree is not split
2051 /// and each entry is large (Megabytes)
2052 /// A small value for bufsize is optimum if you intend to access
2053 /// the entries in the Tree randomly and your Tree is in split mode.
2055 TBranch* TTree::BranchOld(const char* name, const char* classname, void* addobj, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 1 */)
2056 {
2057  TClass* cl = TClass::GetClass(classname);
2058  if (!cl) {
2059  Error("BranchOld", "Cannot find class: '%s'", classname);
2060  return 0;
2061  }
2062  if (!cl->IsTObject()) {
2063  if (fgBranchStyle == 0) {
2064  Fatal("BranchOld", "The requested class ('%s') does not inherit from TObject.\n"
2065  "\tfgBranchStyle is set to zero requesting by default to use BranchOld.\n"
2066  "\tIf this is intentional use Bronch instead of Branch or BranchOld.", classname);
2067  } else {
2068  Fatal("BranchOld", "The requested class ('%s') does not inherit from TObject.\n"
2069  "\tYou can not use BranchOld to store objects of this type.",classname);
2070  }
2071  return 0;
2072  }
2073  TBranch* branch = new TBranchObject(this, name, classname, addobj, bufsize, splitlevel);
2074  fBranches.Add(branch);
2075  if (!splitlevel) {
2076  return branch;
2077  }
2078  // We are going to fully split the class now.
2079  TObjArray* blist = branch->GetListOfBranches();
2080  const char* rdname = 0;
2081  const char* dname = 0;
2082  TString branchname;
2083  char** apointer = (char**) addobj;
2084  TObject* obj = (TObject*) *apointer;
2085  Bool_t delobj = kFALSE;
2086  if (!obj) {
2087  obj = (TObject*) cl->New();
2088  delobj = kTRUE;
2089  }
2090  // Build the StreamerInfo if first time for the class.
2091  BuildStreamerInfo(cl, obj);
2092  // Loop on all public data members of the class and its base classes.
2093  Int_t lenName = strlen(name);
2094  Int_t isDot = 0;
2095  if (name[lenName-1] == '.') {
2096  isDot = 1;
2097  }
2098  TBranch* branch1 = 0;
2099  TRealData* rd = 0;
2100  TRealData* rdi = 0;
2101  TIter nexti(cl->GetListOfRealData());
2102  TIter next(cl->GetListOfRealData());
2103  // Note: This loop results in a full split because the
2104  // real data list includes all data members of
2105  // data members.
2106  while ((rd = (TRealData*) next())) {
2107  if (rd->TestBit(TRealData::kTransient)) continue;
2108 
2109  // Loop over all data members creating branches for each one.
2110  TDataMember* dm = rd->GetDataMember();
2111  if (!dm->IsPersistent()) {
2112  // Do not process members with an "!" as the first character in the comment field.
2113  continue;
2114  }
2115  if (rd->IsObject()) {
2116  // We skip data members of class type.
2117  // But we do build their real data, their
2118  // streamer info, and write their streamer
2119  // info to the current directory's file.
2120  // Oh yes, and we also do this for all of
2121  // their base classes.
2122  TClass* clm = TClass::GetClass(dm->GetFullTypeName());
2123  if (clm) {
2124  BuildStreamerInfo(clm, (char*) obj + rd->GetThisOffset());
2125  }
2126  continue;
2127  }
2128  rdname = rd->GetName();
2129  dname = dm->GetName();
2130  if (cl->CanIgnoreTObjectStreamer()) {
2131  // Skip the TObject base class data members.
2132  // FIXME: This prevents a user from ever
2133  // using these names themself!
2134  if (!strcmp(dname, "fBits")) {
2135  continue;
2136  }
2137  if (!strcmp(dname, "fUniqueID")) {
2138  continue;
2139  }
2140  }
2141  TDataType* dtype = dm->GetDataType();
2142  Int_t code = 0;
2143  if (dtype) {
2144  code = dm->GetDataType()->GetType();
2145  }
2146  // Encode branch name. Use real data member name
2147  branchname = rdname;
2148  if (isDot) {
2149  if (dm->IsaPointer()) {
2150  // FIXME: This is wrong! The asterisk is not usually in the front!
2151  branchname.Form("%s%s", name, &rdname[1]);
2152  } else {
2153  branchname.Form("%s%s", name, &rdname[0]);
2154  }
2155  }
2156  // FIXME: Change this to a string stream.
2157  TString leaflist;
2158  Int_t offset = rd->GetThisOffset();
2159  char* pointer = ((char*) obj) + offset;
2160  if (dm->IsaPointer()) {
2161  // We have a pointer to an object or a pointer to an array of basic types.
2162  TClass* clobj = 0;
2163  if (!dm->IsBasic()) {
2164  clobj = TClass::GetClass(dm->GetTypeName());
2165  }
2166  if (clobj && clobj->InheritsFrom(TClonesArray::Class())) {
2167  // We have a pointer to a clones array.
2168  char* cpointer = (char*) pointer;
2169  char** ppointer = (char**) cpointer;
2170  TClonesArray* li = (TClonesArray*) *ppointer;
2171  if (splitlevel != 2) {
2172  if (isDot) {
2173  branch1 = new TBranchClones(branch,branchname, pointer, bufsize);
2174  } else {
2175  // FIXME: This is wrong! The asterisk is not usually in the front!
2176  branch1 = new TBranchClones(branch,&branchname.Data()[1], pointer, bufsize);
2177  }
2178  blist->Add(branch1);
2179  } else {
2180  if (isDot) {
2181  branch1 = new TBranchObject(branch, branchname, li->ClassName(), pointer, bufsize);
2182  } else {
2183  // FIXME: This is wrong! The asterisk is not usually in the front!
2184  branch1 = new TBranchObject(branch, &branchname.Data()[1], li->ClassName(), pointer, bufsize);
2185  }
2186  blist->Add(branch1);
2187  }
2188  } else if (clobj) {
2189  // We have a pointer to an object.
2190  //
2191  // It must be a TObject object.
2192  if (!clobj->IsTObject()) {
2193  continue;
2194  }
2195  branch1 = new TBranchObject(branch, dname, clobj->GetName(), pointer, bufsize, 0);
2196  if (isDot) {
2197  branch1->SetName(branchname);
2198  } else {
2199  // FIXME: This is wrong! The asterisk is not usually in the front!
2200  // Do not use the first character (*).
2201  branch1->SetName(&branchname.Data()[1]);
2202  }
2203  blist->Add(branch1);
2204  } else {
2205  // We have a pointer to an array of basic types.
2206  //
2207  // Check the comments in the text of the code for an index specification.
2208  const char* index = dm->GetArrayIndex();
2209  if (index[0]) {
2210  // We are a pointer to a varying length array of basic types.
2211  //check that index is a valid data member name
2212  //if member is part of an object (e.g. fA and index=fN)
2213  //index must be changed from fN to fA.fN
2214  TString aindex (rd->GetName());
2215  Ssiz_t rdot = aindex.Last('.');
2216  if (rdot>=0) {
2217  aindex.Remove(rdot+1);
2218  aindex.Append(index);
2219  }
2220  nexti.Reset();
2221  while ((rdi = (TRealData*) nexti())) {
2222  if (rdi->TestBit(TRealData::kTransient)) continue;
2223 
2224  if (!strcmp(rdi->GetName(), index)) {
2225  break;
2226  }
2227  if (!strcmp(rdi->GetName(), aindex)) {
2228  index = rdi->GetName();
2229  break;
2230  }
2231  }
2232 
2233  char vcode = DataTypeToChar((EDataType)code);
2234  // Note that we differentiate between strings and
2235  // char array by the fact that there is NO specified
2236  // size for a string (see next if (code == 1)
2237 
2238  if (vcode) {
2239  leaflist.Form("%s[%s]/%c", &rdname[0], index, vcode);
2240  } else {
2241  Error("BranchOld", "Cannot create branch for rdname: %s code: %d", branchname.Data(), code);
2242  leaflist = "";
2243  }
2244  } else {
2245  // We are possibly a character string.
2246  if (code == 1) {
2247  // We are a character string.
2248  leaflist.Form("%s/%s", dname, "C");
2249  } else {
2250  // Invalid array specification.
2251  // FIXME: We need an error message here.
2252  continue;
2253  }
2254  }
2255  // There are '*' in both the branchname and leaflist, remove them.
2256  TString bname( branchname );
2257  bname.ReplaceAll("*","");
2258  leaflist.ReplaceAll("*","");
2259  // Add the branch to the tree and indicate that the address
2260  // is that of a pointer to be dereferenced before using.
2261  branch1 = new TBranch(branch, bname, *((void**) pointer), leaflist, bufsize);
2262  TLeaf* leaf = (TLeaf*) branch1->GetListOfLeaves()->At(0);
2264  leaf->SetAddress((void**) pointer);
2265  blist->Add(branch1);
2266  }
2267  } else if (dm->IsBasic()) {
2268  // We have a basic type.
2269 
2270  char vcode = DataTypeToChar((EDataType)code);
2271  if (vcode) {
2272  leaflist.Form("%s/%c", rdname, vcode);
2273  } else {
2274  Error("BranchOld", "Cannot create branch for rdname: %s code: %d", branchname.Data(), code);
2275  leaflist = "";
2276  }
2277  branch1 = new TBranch(branch, branchname, pointer, leaflist, bufsize);
2278  branch1->SetTitle(rdname);
2279  blist->Add(branch1);
2280  } else {
2281  // We have a class type.
2282  // Note: This cannot happen due to the rd->IsObject() test above.
2283  // FIXME: Put an error message here just in case.
2284  }
2285  if (branch1) {
2286  branch1->SetOffset(offset);
2287  } else {
2288  Warning("BranchOld", "Cannot process member: '%s'", rdname);
2289  }
2290  }
2291  if (delobj) {
2292  delete obj;
2293  obj = 0;
2294  }
2295  return branch;
2296 }
2297 
2298 ////////////////////////////////////////////////////////////////////////////////
2299 /// Build the optional branch supporting the TRefTable.
2300 /// This branch will keep all the information to find the branches
2301 /// containing referenced objects.
2302 ///
2303 /// At each Tree::Fill, the branch numbers containing the
2304 /// referenced objects are saved to the TBranchRef basket.
2305 /// When the Tree header is saved (via TTree::Write), the branch
2306 /// is saved keeping the information with the pointers to the branches
2307 /// having referenced objects.
2310 {
2311  if (!fBranchRef) {
2312  fBranchRef = new TBranchRef(this);
2313  }
2314  return fBranchRef;
2315 }
2316 
2317 ////////////////////////////////////////////////////////////////////////////////
2318 /// Create a new TTree BranchElement.
2319 ///
2320 /// ## WARNING about this new function
2321 ///
2322 /// This function is designed to replace the internal
2323 /// implementation of the old TTree::Branch (whose implementation
2324 /// has been moved to BranchOld).
2325 ///
2326 /// NOTE: The 'Bronch' method supports only one possible calls
2327 /// signature (where the object type has to be specified
2328 /// explicitly and the address must be the address of a pointer).
2329 /// For more flexibility use 'Branch'. Use Bronch only in (rare)
2330 /// cases (likely to be legacy cases) where both the new and old
2331 /// implementation of Branch needs to be used at the same time.
2332 ///
2333 /// This function is far more powerful than the old Branch
2334 /// function. It supports the full C++, including STL and has
2335 /// the same behaviour in split or non-split mode. classname does
2336 /// not have to derive from TObject. The function is based on
2337 /// the new TStreamerInfo.
2338 ///
2339 /// Build a TBranchElement for an object of class classname.
2340 ///
2341 /// addr is the address of a pointer to an object of class
2342 /// classname. The class dictionary must be available (ClassDef
2343 /// in class header).
2344 ///
2345 /// Note: See the comments in TBranchElement::SetAddress() for a more
2346 /// detailed discussion of the meaning of the addr parameter.
2347 ///
2348 /// This option requires access to the library where the
2349 /// corresponding class is defined. Accessing one single data
2350 /// member in the object implies reading the full object.
2351 ///
2352 /// By default the branch buffers are stored in the same file as the Tree.
2353 /// use TBranch::SetFile to specify a different file
2354 ///
2355 /// IMPORTANT NOTE about branch names:
2356 ///
2357 /// And in general, in case two or more master branches contain subbranches
2358 /// with identical names, one must add a "." (dot) character at the end
2359 /// of the master branch name. This will force the name of the subbranches
2360 /// to be of the form `master.subbranch` instead of simply `subbranch`.
2361 /// This situation happens when the top level object
2362 /// has two or more members referencing the same class.
2363 /// For example, if a Tree has two branches B1 and B2 corresponding
2364 /// to objects of the same class MyClass, one can do:
2365 /// ~~~ {.cpp}
2366 /// tree.Branch("B1.","MyClass",&b1,8000,1);
2367 /// tree.Branch("B2.","MyClass",&b2,8000,1);
2368 /// ~~~
2369 /// if MyClass has 3 members a,b,c, the two instructions above will generate
2370 /// subbranches called B1.a, B1.b ,B1.c, B2.a, B2.b, B2.c
2371 ///
2372 /// bufsize is the buffer size in bytes for this branch
2373 /// The default value is 32000 bytes and should be ok for most cases.
2374 /// You can specify a larger value (e.g. 256000) if your Tree is not split
2375 /// and each entry is large (Megabytes)
2376 /// A small value for bufsize is optimum if you intend to access
2377 /// the entries in the Tree randomly and your Tree is in split mode.
2378 ///
2379 /// Use splitlevel < 0 instead of splitlevel=0 when the class
2380 /// has a custom Streamer
2381 ///
2382 /// Note: if the split level is set to the default (99), TTree::Branch will
2383 /// not issue a warning if the class can not be split.
2385 TBranch* TTree::Bronch(const char* name, const char* classname, void* addr, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */)
2386 {
2387  return BronchExec(name, classname, addr, kTRUE, bufsize, splitlevel);
2388 }
2389 
2390 ////////////////////////////////////////////////////////////////////////////////
2391 /// Helper function implementing TTree::Bronch and TTree::Branch(const char *name, T &obj);
2393 TBranch* TTree::BronchExec(const char* name, const char* classname, void* addr, Bool_t isptrptr, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */)
2394 {
2395  TClass* cl = TClass::GetClass(classname);
2396  if (!cl) {
2397  Error("Bronch", "Cannot find class:%s", classname);
2398  return 0;
2399  }
2400 
2401  //if splitlevel <= 0 and class has a custom Streamer, we must create
2402  //a TBranchObject. We cannot assume that TClass::ReadBuffer is consistent
2403  //with the custom Streamer. The penalty is that one cannot process
2404  //this Tree without the class library containing the class.
2405 
2406  char* objptr = 0;
2407  if (!isptrptr) {
2408  objptr = (char*)addr;
2409  } else if (addr) {
2410  objptr = *((char**) addr);
2411  }
2412 
2413  if (cl == TClonesArray::Class()) {
2414  TClonesArray* clones = (TClonesArray*) objptr;
2415  if (!clones) {
2416  Error("Bronch", "Pointer to TClonesArray is null");
2417  return 0;
2418  }
2419  if (!clones->GetClass()) {
2420  Error("Bronch", "TClonesArray with no class defined in branch: %s", name);
2421  return 0;
2422  }
2423  if (!clones->GetClass()->HasDataMemberInfo()) {
2424  Error("Bronch", "TClonesArray with no dictionary defined in branch: %s", name);
2425  return 0;
2426  }
2427  bool hasCustomStreamer = clones->GetClass()->TestBit(TClass::kHasCustomStreamerMember);
2428  if (splitlevel > 0) {
2429  if (hasCustomStreamer)
2430  Warning("Bronch", "Using split mode on a class: %s with a custom Streamer", clones->GetClass()->GetName());
2431  } else {
2432  if (hasCustomStreamer) clones->BypassStreamer(kFALSE);
2433  TBranchObject *branch = new TBranchObject(this,name,classname,addr,bufsize,0,/*compress=*/ -1,isptrptr);
2434  fBranches.Add(branch);
2435  return branch;
2436  }
2437  }
2438 
2439  if (cl->GetCollectionProxy()) {
2440  TVirtualCollectionProxy* collProxy = cl->GetCollectionProxy();
2441  //if (!collProxy) {
2442  // Error("Bronch", "%s is missing its CollectionProxy (for branch %s)", classname, name);
2443  //}
2444  TClass* inklass = collProxy->GetValueClass();
2445  if (!inklass && (collProxy->GetType() == 0)) {
2446  Error("Bronch", "%s with no class defined in branch: %s", classname, name);
2447  return 0;
2448  }
2449  if ((splitlevel > 0) && inklass && (inklass->GetCollectionProxy() == 0)) {
2450  ROOT::ESTLType stl = cl->GetCollectionType();
2451  if ((stl != ROOT::kSTLmap) && (stl != ROOT::kSTLmultimap)) {
2452  if (!inklass->HasDataMemberInfo()) {
2453  Error("Bronch", "Container with no dictionary defined in branch: %s", name);
2454  return 0;
2455  }
2456  if (inklass->TestBit(TClass::kHasCustomStreamerMember)) {
2457  Warning("Bronch", "Using split mode on a class: %s with a custom Streamer", inklass->GetName());
2458  }
2459  }
2460  }
2461  //-------------------------------------------------------------------------
2462  // If the splitting switch is enabled, the split level is big enough and
2463  // the collection contains pointers we can split it
2464  //////////////////////////////////////////////////////////////////////////
2465 
2466  TBranch *branch;
2467  if( splitlevel > kSplitCollectionOfPointers && collProxy->HasPointers() )
2468  branch = new TBranchSTL( this, name, collProxy, bufsize, splitlevel );
2469  else
2470  branch = new TBranchElement(this, name, collProxy, bufsize, splitlevel);
2471  fBranches.Add(branch);
2472  if (isptrptr) {
2473  branch->SetAddress(addr);
2474  } else {
2475  branch->SetObject(addr);
2476  }
2477  return branch;
2478  }
2479 
2480  Bool_t hasCustomStreamer = kFALSE;
2481  if (!cl->HasDataMemberInfo() && !cl->GetCollectionProxy()) {
2482  Error("Bronch", "Cannot find dictionary for class: %s", classname);
2483  return 0;
2484  }
2485 
2487  // Not an STL container and the linkdef file had a "-" after the class name.
2488  hasCustomStreamer = kTRUE;
2489  }
2490 
2491  if (splitlevel < 0 || ((splitlevel == 0) && hasCustomStreamer && cl->IsTObject())) {
2492  TBranchObject* branch = new TBranchObject(this, name, classname, addr, bufsize, 0, /*compress=*/ ROOT::RCompressionSetting::EAlgorithm::kInherit, isptrptr);
2493  fBranches.Add(branch);
2494  return branch;
2495  }
2496 
2497  if (cl == TClonesArray::Class()) {
2498  // Special case of TClonesArray.
2499  // No dummy object is created.
2500  // The streamer info is not rebuilt unoptimized.
2501  // No dummy top-level branch is created.
2502  // No splitting is attempted.
2503  TBranchElement* branch = new TBranchElement(this, name, (TClonesArray*) objptr, bufsize, splitlevel%kSplitCollectionOfPointers);
2504  fBranches.Add(branch);
2505  if (isptrptr) {
2506  branch->SetAddress(addr);
2507  } else {
2508  branch->SetObject(addr);
2509  }
2510  return branch;
2511  }
2512 
2513  //
2514  // If we are not given an object to use as an i/o buffer
2515  // then create a temporary one which we will delete just
2516  // before returning.
2517  //
2518 
2519  Bool_t delobj = kFALSE;
2520 
2521  if (!objptr) {
2522  objptr = (char*) cl->New();
2523  delobj = kTRUE;
2524  }
2525 
2526  //
2527  // Avoid splitting unsplittable classes.
2528  //
2529 
2530  if ((splitlevel > 0) && !cl->CanSplit()) {
2531  if (splitlevel != 99) {
2532  Warning("Bronch", "%s cannot be split, resetting splitlevel to 0", cl->GetName());
2533  }
2534  splitlevel = 0;
2535  }
2536 
2537  //
2538  // Make sure the streamer info is built and fetch it.
2539  //
2540  // If we are splitting, then make sure the streamer info
2541  // is built unoptimized (data members are not combined).
2542  //
2543 
2544  TStreamerInfo* sinfo = BuildStreamerInfo(cl, objptr, splitlevel==0);
2545  if (!sinfo) {
2546  Error("Bronch", "Cannot build the StreamerInfo for class: %s", cl->GetName());
2547  return 0;
2548  }
2549 
2550  //
2551  // Create a dummy top level branch object.
2552  //
2553 
2554  Int_t id = -1;
2555  if (splitlevel > 0) {
2556  id = -2;
2557  }
2558  TBranchElement* branch = new TBranchElement(this, name, sinfo, id, objptr, bufsize, splitlevel);
2559  fBranches.Add(branch);
2560 
2561  //
2562  // Do splitting, if requested.
2563  //
2564 
2565  if (splitlevel%kSplitCollectionOfPointers > 0) {
2566  branch->Unroll(name, cl, sinfo, objptr, bufsize, splitlevel);
2567  }
2568 
2569  //
2570  // Setup our offsets into the user's i/o buffer.
2571  //
2572 
2573  if (isptrptr) {
2574  branch->SetAddress(addr);
2575  } else {
2576  branch->SetObject(addr);
2577  }
2578 
2579  if (delobj) {
2580  cl->Destructor(objptr);
2581  objptr = 0;
2582  }
2583 
2584  return branch;
2585 }
2586 
2587 ////////////////////////////////////////////////////////////////////////////////
2588 /// Browse content of the TTree.
2590 void TTree::Browse(TBrowser* b)
2591 {
2592  fBranches.Browse(b);
2593  if (fUserInfo) {
2594  if (strcmp("TList",fUserInfo->GetName())==0) {
2595  fUserInfo->SetName("UserInfo");
2596  b->Add(fUserInfo);
2597  fUserInfo->SetName("TList");
2598  } else {
2599  b->Add(fUserInfo);
2600  }
2601  }
2602 }
2603 
2604 ////////////////////////////////////////////////////////////////////////////////
2605 /// Build a Tree Index (default is TTreeIndex).
2606 /// See a description of the parameters and functionality in
2607 /// TTreeIndex::TTreeIndex().
2608 ///
2609 /// The return value is the number of entries in the Index (< 0 indicates failure).
2610 ///
2611 /// A TTreeIndex object pointed by fTreeIndex is created.
2612 /// This object will be automatically deleted by the TTree destructor.
2613 /// If an index is already existing, this is replaced by the new one without being
2614 /// deleted. This behaviour prevents the deletion of a previously external index
2615 /// assigned to the TTree via the TTree::SetTreeIndex() method.
2616 /// See also comments in TTree::SetTreeIndex().
2618 Int_t TTree::BuildIndex(const char* majorname, const char* minorname /* = "0" */)
2619 {
2620  fTreeIndex = GetPlayer()->BuildIndex(this, majorname, minorname);
2621  if (fTreeIndex->IsZombie()) {
2622  delete fTreeIndex;
2623  fTreeIndex = 0;
2624  return 0;
2625  }
2626  return fTreeIndex->GetN();
2627 }
2628 
2629 ////////////////////////////////////////////////////////////////////////////////
2630 /// Build StreamerInfo for class cl.
2631 /// pointer is an optional argument that may contain a pointer to an object of cl.
2633 TStreamerInfo* TTree::BuildStreamerInfo(TClass* cl, void* pointer /* = 0 */, Bool_t canOptimize /* = kTRUE */ )
2634 {
2635  if (!cl) {
2636  return 0;
2637  }
2638  cl->BuildRealData(pointer);
2640 
2641  // Create StreamerInfo for all base classes.
2642  TBaseClass* base = 0;
2643  TIter nextb(cl->GetListOfBases());
2644  while((base = (TBaseClass*) nextb())) {
2645  if (base->IsSTLContainer()) {
2646  continue;
2647  }
2648  TClass* clm = TClass::GetClass(base->GetName());
2649  BuildStreamerInfo(clm, pointer, canOptimize);
2650  }
2651  if (sinfo && fDirectory) {
2652  sinfo->ForceWriteInfo(fDirectory->GetFile());
2653  }
2654  return sinfo;
2655 }
2656 
2657 ////////////////////////////////////////////////////////////////////////////////
2658 /// Called by TTree::Fill() when file has reached its maximum fgMaxTreeSize.
2659 /// Create a new file. If the original file is named "myfile.root",
2660 /// subsequent files are named "myfile_1.root", "myfile_2.root", etc.
2661 ///
2662 /// Returns a pointer to the new file.
2663 ///
2664 /// Currently, the automatic change of file is restricted
2665 /// to the case where the tree is in the top level directory.
2666 /// The file should not contain sub-directories.
2667 ///
2668 /// Before switching to a new file, the tree header is written
2669 /// to the current file, then the current file is closed.
2670 ///
2671 /// To process the multiple files created by ChangeFile, one must use
2672 /// a TChain.
2673 ///
2674 /// The new file name has a suffix "_N" where N is equal to fFileNumber+1.
2675 /// By default a Root session starts with fFileNumber=0. One can set
2676 /// fFileNumber to a different value via TTree::SetFileNumber.
2677 /// In case a file named "_N" already exists, the function will try
2678 /// a file named "__N", then "___N", etc.
2679 ///
2680 /// fgMaxTreeSize can be set via the static function TTree::SetMaxTreeSize.
2681 /// The default value of fgMaxTreeSize is 100 Gigabytes.
2682 ///
2683 /// If the current file contains other objects like TH1 and TTree,
2684 /// these objects are automatically moved to the new file.
2685 ///
2686 /// \warning Be careful when writing the final Tree header to the file!
2687 /// Don't do:
2688 /// ~~~ {.cpp}
2689 /// TFile *file = new TFile("myfile.root","recreate");
2690 /// TTree *T = new TTree("T","title");
2691 /// T->Fill(); // Loop
2692 /// file->Write();
2693 /// file->Close();
2694 /// ~~~
2695 /// \warning but do the following:
2696 /// ~~~ {.cpp}
2697 /// TFile *file = new TFile("myfile.root","recreate");
2698 /// TTree *T = new TTree("T","title");
2699 /// T->Fill(); // Loop
2700 /// file = T->GetCurrentFile(); // To get the pointer to the current file
2701 /// file->Write();
2702 /// file->Close();
2703 /// ~~~
2704 ///
2705 /// \note This method is never called if the input file is a `TMemFile` or derivate.
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 a histogram
4017 ///
4018 /// If `varexp` contains `>>hnew` (following the variable(s) name(s)),
4019 /// the new histogram called `hnew` is created 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 Calling `TTree::FlushBaskets` too often increases the IO time.
4529 ///
4530 /// \note Calling `TTree::AutoSave` too often increases the IO time and also the
4531 /// file size.
4532 ///
4533 /// \note This method calls `TTree::ChangeFile` when the tree reaches a size
4534 /// greater than `TTree::fgMaxTreeSize`. This doesn't happen if the tree is
4535 /// attached to a `TMemFile` or derivate.
4538 {
4539  Int_t nbytes = 0;
4540  Int_t nwrite = 0;
4541  Int_t nerror = 0;
4542  Int_t nbranches = fBranches.GetEntriesFast();
4543 
4544  // Case of one single super branch. Automatically update
4545  // all the branch addresses if a new object was created.
4546  if (nbranches == 1)
4547  ((TBranch *)fBranches.UncheckedAt(0))->UpdateAddress();
4548 
4549  if (fBranchRef)
4550  fBranchRef->Clear();
4551 
4552 #ifdef R__USE_IMT
4553  const auto useIMT = ROOT::IsImplicitMTEnabled() && fIMTEnabled;
4555  if (useIMT) {
4556  fIMTFlush = true;
4557  fIMTZipBytes.store(0);
4558  fIMTTotBytes.store(0);
4559  }
4560 #endif
4561 
4562  for (Int_t i = 0; i < nbranches; ++i) {
4563  // Loop over all branches, filling and accumulating bytes written and error counts.
4564  TBranch *branch = (TBranch *)fBranches.UncheckedAt(i);
4565 
4566  if (branch->TestBit(kDoNotProcess))
4567  continue;
4568 
4569 #ifndef R__USE_IMT
4570  nwrite = branch->FillImpl(nullptr);
4571 #else
4572  nwrite = branch->FillImpl(useIMT ? &imtHelper : nullptr);
4573 #endif
4574  if (nwrite < 0) {
4575  if (nerror < 2) {
4576  Error("Fill", "Failed filling branch:%s.%s, nbytes=%d, entry=%lld\n"
4577  " This error is symptomatic of a Tree created as a memory-resident Tree\n"
4578  " Instead of doing:\n"
4579  " TTree *T = new TTree(...)\n"
4580  " TFile *f = new TFile(...)\n"
4581  " you should do:\n"
4582  " TFile *f = new TFile(...)\n"
4583  " TTree *T = new TTree(...)\n\n",
4584  GetName(), branch->GetName(), nwrite, fEntries + 1);
4585  } else {
4586  Error("Fill", "Failed filling branch:%s.%s, nbytes=%d, entry=%lld", GetName(), branch->GetName(), nwrite,
4587  fEntries + 1);
4588  }
4589  ++nerror;
4590  } else {
4591  nbytes += nwrite;
4592  }
4593  }
4594 
4595 #ifdef R__USE_IMT
4596  if (fIMTFlush) {
4597  imtHelper.Wait();
4598  fIMTFlush = false;
4599  const_cast<TTree *>(this)->AddTotBytes(fIMTTotBytes);
4600  const_cast<TTree *>(this)->AddZipBytes(fIMTZipBytes);
4601  nbytes += imtHelper.GetNbytes();
4602  nerror += imtHelper.GetNerrors();
4603  }
4604 #endif
4605 
4606  if (fBranchRef)
4607  fBranchRef->Fill();
4608 
4609  ++fEntries;
4610 
4611  if (fEntries > fMaxEntries)
4612  KeepCircular();
4613 
4614  if (gDebug > 0)
4615  Info("TTree::Fill", " - A: %d %lld %lld %lld %lld %lld %lld \n", nbytes, fEntries, fAutoFlush, fAutoSave,
4617 
4618  bool autoFlush = false;
4619  bool autoSave = false;
4620 
4621  if (fAutoFlush != 0 || fAutoSave != 0) {
4622  // Is it time to flush or autosave baskets?
4623  if (fFlushedBytes == 0) {
4624  // If fFlushedBytes == 0, it means we never flushed or saved, so
4625  // we need to check if it's time to do it and recompute the values
4626  // of fAutoFlush and fAutoSave in terms of the number of entries.
4627  // Decision can be based initially either on the number of bytes
4628  // or the number of entries written.
4629  Long64_t zipBytes = GetZipBytes();
4630 
4631  if (fAutoFlush)
4632  autoFlush = fAutoFlush < 0 ? (zipBytes > -fAutoFlush) : fEntries % fAutoFlush == 0;
4633 
4634  if (fAutoSave)
4635  autoSave = fAutoSave < 0 ? (zipBytes > -fAutoSave) : fEntries % fAutoSave == 0;
4636 
4637  if (autoFlush || autoSave) {
4638  // First call FlushBasket to make sure that fTotBytes is up to date.
4639  FlushBasketsImpl();
4640  autoFlush = false; // avoid auto flushing again later
4641 
4642  // When we are in one-basket-per-cluster mode, there is no need to optimize basket:
4643  // they will automatically grow to the size needed for an event cluster (with the basket
4644  // shrinking preventing them from growing too much larger than the actually-used space).
4646  OptimizeBaskets(GetTotBytes(), 1, "");
4647  if (gDebug > 0)
4648  Info("TTree::Fill", "OptimizeBaskets called at entry %lld, fZipBytes=%lld, fFlushedBytes=%lld\n",
4650  }
4652  fAutoFlush = fEntries; // Use test on entries rather than bytes
4653 
4654  // subsequently in run
4655  if (fAutoSave < 0) {
4656  // Set fAutoSave to the largest integer multiple of
4657  // fAutoFlush events such that fAutoSave*fFlushedBytes
4658  // < (minus the input value of fAutoSave)
4659  Long64_t totBytes = GetTotBytes();
4660  if (zipBytes != 0) {
4661  fAutoSave = TMath::Max(fAutoFlush, fEntries * ((-fAutoSave / zipBytes) / fEntries));
4662  } else if (totBytes != 0) {
4663  fAutoSave = TMath::Max(fAutoFlush, fEntries * ((-fAutoSave / totBytes) / fEntries));
4664  } else {
4665  TBufferFile b(TBuffer::kWrite, 10000);
4666  TTree::Class()->WriteBuffer(b, (TTree *)this);
4667  Long64_t total = b.Length();
4669  }
4670  } else if (fAutoSave > 0) {
4672  }
4673 
4674  if (fAutoSave != 0 && fEntries >= fAutoSave)
4675  autoSave = true;
4676 
4677  if (gDebug > 0)
4678  Info("TTree::Fill", "First AutoFlush. fAutoFlush = %lld, fAutoSave = %lld\n", fAutoFlush, fAutoSave);
4679  }
4680  } else {
4681  // Check if we need to auto flush
4682  if (fAutoFlush) {
4683  if (fNClusterRange == 0)
4684  autoFlush = fEntries > 1 && fEntries % fAutoFlush == 0;
4685  else
4686  autoFlush = (fEntries - (fClusterRangeEnd[fNClusterRange - 1] + 1)) % fAutoFlush == 0;
4687  }
4688  // Check if we need to auto save
4689  if (fAutoSave)
4690  autoSave = fEntries % fAutoSave == 0;
4691  }
4692  }
4693 
4694  if (autoFlush) {
4695  FlushBasketsImpl();
4696  if (gDebug > 0)
4697  Info("TTree::Fill", "FlushBaskets() called at entry %lld, fZipBytes=%lld, fFlushedBytes=%lld\n", fEntries,
4700  }
4701 
4702  if (autoSave) {
4703  AutoSave(); // does not call FlushBasketsImpl() again
4704  if (gDebug > 0)
4705  Info("TTree::Fill", "AutoSave called at entry %lld, fZipBytes=%lld, fSavedBytes=%lld\n", fEntries,
4707  }
4708 
4709  // Check that output file is still below the maximum size.
4710  // If above, close the current file and continue on a new file.
4711  // Currently, the automatic change of file is restricted
4712  // to the case where the tree is in the top level directory.
4713  if (fDirectory)
4714  if (TFile *file = fDirectory->GetFile())
4715  if (static_cast<TDirectory *>(file) == fDirectory && (file->GetEND() > fgMaxTreeSize))
4716  // Changing file clashes with the design of TMemFile and derivates, see #6523.
4717  if (!(dynamic_cast<TMemFile *>(file)))
4718  ChangeFile(file);
4719 
4720  return nerror == 0 ? nbytes : -1;
4721 }
4722 
4723 ////////////////////////////////////////////////////////////////////////////////
4724 /// Search in the array for a branch matching the branch name,
4725 /// with the branch possibly expressed as a 'full' path name (with dots).
4727 static TBranch *R__FindBranchHelper(TObjArray *list, const char *branchname) {
4728  if (list==0 || branchname == 0 || branchname[0] == '\0') return 0;
4729 
4730  Int_t nbranches = list->GetEntries();
4731 
4732  UInt_t brlen = strlen(branchname);
4733 
4734  for(Int_t index = 0; index < nbranches; ++index) {
4735  TBranch *where = (TBranch*)list->UncheckedAt(index);
4736 
4737  const char *name = where->GetName();
4738  UInt_t len = strlen(name);
4739  if (len && name[len-1]==']') {
4740  const char *dim = strchr(name,'[');
4741  if (dim) {
4742  len = dim - name;
4743  }
4744  }
4745  if (brlen == len && strncmp(branchname,name,len)==0) {
4746  return where;
4747  }
4748  TBranch *next = 0;
4749  if ((brlen >= len) && (branchname[len] == '.')
4750  && strncmp(name, branchname, len) == 0) {
4751  // The prefix subbranch name match the branch name.
4752 
4753  next = where->FindBranch(branchname);
4754  if (!next) {
4755  next = where->FindBranch(branchname+len+1);
4756  }
4757  if (next) return next;
4758  }
4759  const char *dot = strchr((char*)branchname,'.');
4760  if (dot) {
4761  if (len==(size_t)(dot-branchname) &&
4762  strncmp(branchname,name,dot-branchname)==0 ) {
4763  return R__FindBranchHelper(where->GetListOfBranches(),dot+1);
4764  }
4765  }
4766  }
4767  return 0;
4768 }
4769 
4770 ////////////////////////////////////////////////////////////////////////////////
4771 /// Return the branch that correspond to the path 'branchname', which can
4772 /// include the name of the tree or the omitted name of the parent branches.
4773 /// In case of ambiguity, returns the first match.
4775 TBranch* TTree::FindBranch(const char* branchname)
4776 {
4777  // We already have been visited while recursively looking
4778  // through the friends tree, let return
4780  return 0;
4781  }
4782 
4783  TBranch* branch = 0;
4784  // If the first part of the name match the TTree name, look for the right part in the
4785  // list of branches.
4786  // This will allow the branchname to be preceded by
4787  // the name of this tree.
4788  if (strncmp(fName.Data(),branchname,fName.Length())==0 && branchname[fName.Length()]=='.') {
4789  branch = R__FindBranchHelper( GetListOfBranches(), branchname + fName.Length() + 1);
4790  if (branch) return branch;
4791  }
4792  // If we did not find it, let's try to find the full name in the list of branches.
4793  branch = R__FindBranchHelper(GetListOfBranches(), branchname);
4794  if (branch) return branch;
4795 
4796  // If we still did not find, let's try to find it within each branch assuming it does not the branch name.
4797  TIter next(GetListOfBranches());
4798  while ((branch = (TBranch*) next())) {
4799  TBranch* nestedbranch = branch->FindBranch(branchname);
4800  if (nestedbranch) {
4801  return nestedbranch;
4802  }
4803  }
4804 
4805  // Search in list of friends.
4806  if (!fFriends) {
4807  return 0;
4808  }
4809  TFriendLock lock(this, kFindBranch);
4810  TIter nextf(fFriends);
4811  TFriendElement* fe = 0;
4812  while ((fe = (TFriendElement*) nextf())) {
4813  TTree* t = fe->GetTree();
4814  if (!t) {
4815  continue;
4816  }
4817  // If the alias is present replace it with the real name.
4818  const char *subbranch = strstr(branchname, fe->GetName());
4819  if (subbranch != branchname) {
4820  subbranch = 0;
4821  }
4822  if (subbranch) {
4823  subbranch += strlen(fe->GetName());
4824  if (*subbranch != '.') {
4825  subbranch = 0;
4826  } else {
4827  ++subbranch;
4828  }
4829  }
4830  std::ostringstream name;
4831  if (subbranch) {
4832  name << t->GetName() << "." << subbranch;
4833  } else {
4834  name << branchname;
4835  }
4836  branch = t->FindBranch(name.str().c_str());
4837  if (branch) {
4838  return branch;
4839  }
4840  }
4841  return 0;
4842 }
4843 
4844 ////////////////////////////////////////////////////////////////////////////////
4845 /// Find leaf..
4847 TLeaf* TTree::FindLeaf(const char* searchname)
4848 {
4849  // We already have been visited while recursively looking
4850  // through the friends tree, let's return.
4851  if (kFindLeaf & fFriendLockStatus) {
4852  return 0;
4853  }
4854 
4855  // This will allow the branchname to be preceded by
4856  // the name of this tree.
4857  char* subsearchname = (char*) strstr(searchname, GetName());
4858  if (subsearchname != searchname) {
4859  subsearchname = 0;
4860  }
4861  if (subsearchname) {
4862  subsearchname += strlen(GetName());
4863  if (*subsearchname != '.') {
4864  subsearchname = 0;
4865  } else {
4866  ++subsearchname;
4867  if (subsearchname[0]==0) {
4868  subsearchname = 0;
4869  }
4870  }
4871  }
4872 
4873  TString leafname;
4874  TString leaftitle;
4875  TString longname;
4876  TString longtitle;
4877 
4878  const bool searchnameHasDot = strchr(searchname, '.') != nullptr;
4879 
4880  // For leaves we allow for one level up to be prefixed to the name.
4881  TIter next(GetListOfLeaves());
4882  TLeaf* leaf = 0;
4883  while ((leaf = (TLeaf*) next())) {
4884  leafname = leaf->GetName();
4885  Ssiz_t dim = leafname.First('[');
4886  if (dim >= 0) leafname.Remove(dim);
4887 
4888  if (leafname == searchname) {
4889  return leaf;
4890  }
4891  if (subsearchname && leafname == subsearchname) {
4892  return leaf;
4893  }
4894  // The TLeafElement contains the branch name
4895  // in its name, let's use the title.
4896  leaftitle = leaf->GetTitle();
4897  dim = leaftitle.First('[');
4898  if (dim >= 0) leaftitle.Remove(dim);
4899 
4900  if (leaftitle == searchname) {
4901  return leaf;
4902  }
4903  if (subsearchname && leaftitle == subsearchname) {
4904  return leaf;
4905  }
4906  if (!searchnameHasDot)
4907  continue;
4908  TBranch* branch = leaf->GetBranch();
4909  if (branch) {
4910  longname.Form("%s.%s",branch->GetName(),leafname.Data());
4911  dim = longname.First('[');
4912  if (dim>=0) longname.Remove(dim);
4913  if (longname == searchname) {
4914  return leaf;
4915  }
4916  if (subsearchname && longname == subsearchname) {
4917  return leaf;
4918  }
4919  longtitle.Form("%s.%s",branch->GetName(),leaftitle.Data());
4920  dim = longtitle.First('[');
4921  if (dim>=0) longtitle.Remove(dim);
4922  if (longtitle == searchname) {
4923  return leaf;
4924  }
4925  if (subsearchname && longtitle == subsearchname) {
4926  return leaf;
4927  }
4928  // The following is for the case where the branch is only
4929  // a sub-branch. Since we do not see it through
4930  // TTree::GetListOfBranches, we need to see it indirectly.
4931  // This is the less sturdy part of this search ... it may
4932  // need refining ...
4933  if (strstr(searchname, ".") && !strcmp(searchname, branch->GetName())) {
4934  return leaf;
4935  }
4936  if (subsearchname && strstr(subsearchname, ".") && !strcmp(subsearchname, branch->GetName())) {
4937  return leaf;
4938  }
4939  }
4940  }
4941  // Search in list of friends.
4942  if (!fFriends) {
4943  return 0;
4944  }
4945  TFriendLock lock(this, kFindLeaf);
4946  TIter nextf(fFriends);
4947  TFriendElement* fe = 0;
4948  while ((fe = (TFriendElement*) nextf())) {
4949  TTree* t = fe->GetTree();
4950  if (!t) {
4951  continue;
4952  }
4953  // If the alias is present replace it with the real name.
4954  subsearchname = (char*) strstr(searchname, fe->GetName());
4955  if (subsearchname != searchname) {
4956  subsearchname = 0;
4957  }
4958  if (subsearchname) {
4959  subsearchname += strlen(fe->GetName());
4960  if (*subsearchname != '.') {
4961  subsearchname = 0;
4962  } else {
4963  ++subsearchname;
4964  }
4965  }
4966  if (subsearchname) {
4967  leafname.Form("%s.%s",t->GetName(),subsearchname);
4968  } else {
4969  leafname = searchname;
4970  }
4971  leaf = t->FindLeaf(leafname);
4972  if (leaf) {
4973  return leaf;
4974  }
4975  }
4976  return 0;
4977 }
4978 
4979 ////////////////////////////////////////////////////////////////////////////////
4980 /// Fit a projected item(s) from a tree.
4981 ///
4982 /// funcname is a TF1 function.
4983 ///
4984 /// See TTree::Draw() for explanations of the other parameters.
4985 ///
4986 /// By default the temporary histogram created is called htemp.
4987 /// If varexp contains >>hnew , the new histogram created is called hnew
4988 /// and it is kept in the current directory.
4989 ///
4990 /// The function returns the number of selected entries.
4991 ///
4992 /// Example:
4993 /// ~~~ {.cpp}
4994 /// tree.Fit(pol4,"sqrt(x)>>hsqrt","y>0")
4995 /// ~~~
4996 /// will fit sqrt(x) and save the histogram as "hsqrt" in the current
4997 /// directory.
4998 ///
4999 /// See also TTree::UnbinnedFit
5000 ///
5001 /// ## Return status
5002 ///
5003 /// The function returns the status of the histogram fit (see TH1::Fit)
5004 /// If no entries were selected, the function returns -1;
5005 /// (i.e. fitResult is null if the fit is OK)
5007 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)
5008 {
5009  GetPlayer();
5010  if (fPlayer) {
5011  return fPlayer->Fit(funcname, varexp, selection, option, goption, nentries, firstentry);
5012  }
5013  return -1;
5014 }
5015 
5016 namespace {
5017 struct BoolRAIIToggle {
5018  Bool_t &m_val;
5019 
5020  BoolRAIIToggle(Bool_t &val) : m_val(val) { m_val = true; }
5021  ~BoolRAIIToggle() { m_val = false; }
5022 };
5023 }
5024 
5025 ////////////////////////////////////////////////////////////////////////////////
5026 /// Write to disk all the basket that have not yet been individually written and
5027 /// create an event cluster boundary (by default).
5028 ///
5029 /// If the caller wishes to flush the baskets but not create an event cluster,
5030 /// then set create_cluster to false.
5031 ///
5032 /// If ROOT has IMT-mode enabled, this will launch multiple TBB tasks in parallel
5033 /// via TThreadExecutor to do this operation; one per basket compression. If the
5034 /// caller utilizes TBB also, care must be taken to prevent deadlocks.
5035 ///
5036 /// For example, let's say the caller holds mutex A and calls FlushBaskets; while
5037 /// TBB is waiting for the ROOT compression tasks to complete, it may decide to
5038 /// run another one of the user's tasks in this thread. If the second user task
5039 /// tries to acquire A, then a deadlock will occur. The example call sequence
5040 /// looks like this:
5041 ///
5042 /// - User acquires mutex A
5043 /// - User calls FlushBaskets.
5044 /// - ROOT launches N tasks and calls wait.
5045 /// - TBB schedules another user task, T2.
5046 /// - T2 tries to acquire mutex A.
5047 ///
5048 /// At this point, the thread will deadlock: the code may function with IMT-mode
5049 /// disabled if the user assumed the legacy code never would run their own TBB
5050 /// tasks.
5051 ///
5052 /// SO: users of TBB who want to enable IMT-mode should carefully review their
5053 /// locking patterns and make sure they hold no coarse-grained application
5054 /// locks when they invoke ROOT.
5055 ///
5056 /// Return the number of bytes written or -1 in case of write error.
5057 Int_t TTree::FlushBaskets(Bool_t create_cluster) const
5058 {
5059  Int_t retval = FlushBasketsImpl();
5060  if (retval == -1) return retval;
5061 
5062  if (create_cluster) const_cast<TTree *>(this)->MarkEventCluster();
5063  return retval;
5064 }
5065 
5066 ////////////////////////////////////////////////////////////////////////////////
5067 /// Internal implementation of the FlushBaskets algorithm.
5068 /// Unlike the public interface, this does NOT create an explicit event cluster
5069 /// boundary; it is up to the (internal) caller to determine whether that should
5070 /// done.
5071 ///
5072 /// Otherwise, the comments for FlushBaskets applies.
5073 ///
5075 {
5076  if (!fDirectory) return 0;
5077  Int_t nbytes = 0;
5078  Int_t nerror = 0;
5079  TObjArray *lb = const_cast<TTree*>(this)->GetListOfBranches();
5080  Int_t nb = lb->GetEntriesFast();
5081 
5082 #ifdef R__USE_IMT
5083  const auto useIMT = ROOT::IsImplicitMTEnabled() && fIMTEnabled;
5084  if (useIMT) {
5085  // ROOT-9668: here we need to check if the size of fSortedBranches is different from the
5086  // size of the list of branches before triggering the initialisation of the fSortedBranches
5087  // container to cover two cases:
5088  // 1. This is the first time we flush. fSortedBranches is empty and we need to fill it.
5089  // 2. We flushed at least once already but a branch has been be added to the tree since then
5090  if (fSortedBranches.size() != unsigned(nb)) { const_cast<TTree*>(this)->InitializeBranchLists(false); }
5091 
5092  BoolRAIIToggle sentry(fIMTFlush);
5093  fIMTZipBytes.store(0);
5094  fIMTTotBytes.store(0);
5095  std::atomic<Int_t> nerrpar(0);
5096  std::atomic<Int_t> nbpar(0);
5097  std::atomic<Int_t> pos(0);
5098 
5099  auto mapFunction = [&]() {
5100  // The branch to process is obtained when the task starts to run.
5101  // This way, since branches are sorted, we make sure that branches
5102  // leading to big tasks are processed first. If we assigned the
5103  // branch at task creation time, the scheduler would not necessarily
5104  // respect our sorting.
5105  Int_t j = pos.fetch_add(1);
5106 
5107  auto branch = fSortedBranches[j].second;
5108  if (R__unlikely(!branch)) { return; }
5109 
5110  if (R__unlikely(gDebug > 0)) {
5111  std::stringstream ss;
5112  ss << std::this_thread::get_id();
5113  Info("FlushBaskets", "[IMT] Thread %s", ss.str().c_str());
5114  Info("FlushBaskets", "[IMT] Running task for branch #%d: %s", j, branch->GetName());
5115  }
5116 
5117  Int_t nbtask = branch->FlushBaskets();
5118 
5119  if (nbtask < 0) { nerrpar++; }
5120  else { nbpar += nbtask; }
5121  };
5122 
5123  ROOT::TThreadExecutor pool;
5124  pool.Foreach(mapFunction, nb);
5125 
5126  fIMTFlush = false;
5127  const_cast<TTree*>(this)->AddTotBytes(fIMTTotBytes);
5128  const_cast<TTree*>(this)->AddZipBytes(fIMTZipBytes);
5129 
5130  return nerrpar ? -1 : nbpar.load();
5131  }
5132 #endif
5133  for (Int_t j = 0; j < nb; j++) {
5134  TBranch* branch = (TBranch*) lb->UncheckedAt(j);
5135  if (branch) {
5136  Int_t nwrite = branch->FlushBaskets();
5137  if (nwrite<0) {
5138  ++nerror;
5139  } else {
5140  nbytes += nwrite;
5141  }
5142  }
5143  }
5144  if (nerror) {
5145  return -1;
5146  } else {
5147  return nbytes;
5148  }
5149 }
5150 
5151 ////////////////////////////////////////////////////////////////////////////////
5152 /// Returns the expanded value of the alias. Search in the friends if any.
5154 const char* TTree::GetAlias(const char* aliasName) const
5155 {
5156  // We already have been visited while recursively looking
5157  // through the friends tree, let's return.
5158  if (kGetAlias & fFriendLockStatus) {
5159  return 0;
5160  }
5161  if (fAliases) {
5162  TObject* alias = fAliases->FindObject(aliasName);
5163  if (alias) {
5164  return alias->GetTitle();
5165  }
5166  }
5167  if (!fFriends) {
5168  return 0;
5169  }
5170  TFriendLock lock(const_cast<TTree*>(this), kGetAlias);
5171  TIter nextf(fFriends);
5172  TFriendElement* fe = 0;
5173  while ((fe = (TFriendElement*) nextf())) {
5174  TTree* t = fe->GetTree();
5175  if (t) {
5176  const char* alias = t->GetAlias(aliasName);
5177  if (alias) {
5178  return alias;
5179  }
5180  const char* subAliasName = strstr(aliasName, fe->GetName());
5181  if (subAliasName && (subAliasName[strlen(fe->GetName())] == '.')) {
5182  alias = t->GetAlias(aliasName + strlen(fe->GetName()) + 1);
5183  if (alias) {
5184  return alias;
5185  }
5186  }
5187  }
5188  }
5189  return 0;
5190 }
5191 
5192 namespace {
5193 /// Do a breadth first search through the implied hierarchy
5194 /// of branches.
5195 /// To avoid scanning through the list multiple time
5196 /// we also remember the 'depth-first' match.
5197 TBranch *R__GetBranch(const TObjArray &branches, const char *name)
5198 {
5199  TBranch *result = nullptr;
5200  Int_t nb = branches.GetEntriesFast();
5201  for (Int_t i = 0; i < nb; i++) {
5202  TBranch* b = (TBranch*)branches.UncheckedAt(i);
5203  if (!b)
5204  continue;
5205  if (!strcmp(b->GetName(), name)) {
5206  return b;
5207  }
5208  if (!strcmp(b->GetFullName(), name)) {
5209  return b;
5210  }
5211  if (!result)
5212  result = R__GetBranch(*(b->GetListOfBranches()), name);
5213  }
5214  return result;
5215 }
5216 }
5217 
5218 ////////////////////////////////////////////////////////////////////////////////
5219 /// Return pointer to the branch with the given name in this tree or its friends.
5220 /// The search is done breadth first.
5222 TBranch* TTree::GetBranch(const char* name)
5223 {
5224  if (name == 0) return 0;
5225 
5226  // We already have been visited while recursively
5227  // looking through the friends tree, let's return.
5228  if (kGetBranch & fFriendLockStatus) {
5229  return 0;
5230  }
5231 
5232  // Look for an exact match in the list of top level
5233  // branches.
5234  TBranch *result = (TBranch*)fBranches.FindObject(name);
5235  if (result)
5236  return result;
5237 
5238  // Search using branches, breadth first.
5239  result = R__GetBranch(fBranches, name);
5240  if (result)
5241  return result;
5242 
5243  // Search using leaves.
5244  TObjArray* leaves = GetListOfLeaves();
5245  Int_t nleaves = leaves->GetEntriesFast();
5246  for (Int_t i = 0; i < nleaves; i++) {
5247  TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(i);
5248  TBranch* branch = leaf->GetBranch();
5249  if (!strcmp(branch->GetName(), name)) {
5250  return branch;
5251  }
5252  if (!strcmp(branch->GetFullName(), name)) {
5253  return branch;
5254  }
5255  }
5256 
5257  if (!fFriends) {
5258  return 0;
5259  }
5260 
5261  // Search in list of friends.
5262  TFriendLock lock(this, kGetBranch);
5263  TIter next(fFriends);
5264  TFriendElement* fe = 0;
5265  while ((fe = (TFriendElement*) next())) {
5266  TTree* t = fe->GetTree();
5267  if (t) {
5268  TBranch* branch = t->GetBranch(name);
5269  if (branch) {
5270  return branch;
5271  }
5272  }
5273  }
5274 
5275  // Second pass in the list of friends when
5276  // the branch name is prefixed by the tree name.
5277  next.Reset();
5278  while ((fe = (TFriendElement*) next())) {
5279  TTree* t = fe->GetTree();
5280  if (!t) {
5281  continue;
5282  }
5283  char* subname = (char*) strstr(name, fe->GetName());
5284  if (subname != name) {
5285  continue;
5286  }
5287  Int_t l = strlen(fe->GetName());
5288  subname += l;
5289  if (*subname != '.') {
5290  continue;
5291  }
5292  subname++;
5293  TBranch* branch = t->GetBranch(subname);
5294  if (branch) {
5295  return branch;
5296  }
5297  }
5298  return 0;
5299 }
5300 
5301 ////////////////////////////////////////////////////////////////////////////////
5302 /// Return status of branch with name branchname.
5303 ///
5304 /// - 0 if branch is not activated
5305 /// - 1 if branch is activated
5307 Bool_t TTree::GetBranchStatus(const char* branchname) const
5308 {
5309  TBranch* br = const_cast<TTree*>(this)->GetBranch(branchname);
5310  if (br) {
5311  return br->TestBit(kDoNotProcess) == 0;
5312  }
5313  return 0;
5314 }
5315 
5316 ////////////////////////////////////////////////////////////////////////////////
5317 /// Static function returning the current branch style.
5318 ///
5319 /// - style = 0 old Branch
5320 /// - style = 1 new Bronch
5323 {
5324  return fgBranchStyle;
5325 }
5326 
5327 ////////////////////////////////////////////////////////////////////////////////
5328 /// Used for automatic sizing of the cache.
5329 ///
5330 /// Estimates a suitable size for the tree cache based on AutoFlush.
5331 /// A cache sizing factor is taken from the configuration. If this yields zero
5332 /// and withDefault is true the historical algorithm for default size is used.
5334 Long64_t TTree::GetCacheAutoSize(Bool_t withDefault /* = kFALSE */ ) const
5335 {
5336  const char *stcs;
5337  Double_t cacheFactor = 0.0;
5338  if (!(stcs = gSystem->Getenv("ROOT_TTREECACHE_SIZE")) || !*stcs) {
5339  cacheFactor = gEnv->GetValue("TTreeCache.Size", 1.0);
5340  } else {
5341  cacheFactor = TString(stcs).Atof();
5342  }
5343 
5344  if (cacheFactor < 0.0) {
5345  // ignore negative factors
5346  cacheFactor = 0.0;
5347  }
5348 
5349  Long64_t cacheSize = 0;
5350 
5351  if (fAutoFlush < 0) cacheSize = Long64_t(-cacheFactor*fAutoFlush);
5352  else if (fAutoFlush == 0) cacheSize = 0;
5353  else cacheSize = Long64_t(cacheFactor*1.5*fAutoFlush*GetZipBytes()/(fEntries+1));
5354 
5355  if (cacheSize >= (INT_MAX / 4)) {
5356  cacheSize = INT_MAX / 4;
5357  }
5358 
5359  if (cacheSize < 0) {
5360  cacheSize = 0;
5361  }
5362 
5363  if (cacheSize == 0 && withDefault) {
5364  if (fAutoFlush < 0) cacheSize = -fAutoFlush;
5365  else if (fAutoFlush == 0) cacheSize = 0;
5366  else cacheSize = Long64_t(1.5*fAutoFlush*GetZipBytes()/(fEntries+1));
5367  }
5368 
5369  return cacheSize;
5370 }
5371 
5372 ////////////////////////////////////////////////////////////////////////////////
5373 /// Return an iterator over the cluster of baskets starting at firstentry.
5374 ///
5375 /// This iterator is not yet supported for TChain object.
5376 /// ~~~ {.cpp}
5377 /// TTree::TClusterIterator clusterIter = tree->GetClusterIterator(entry);
5378 /// Long64_t clusterStart;
5379 /// while( (clusterStart = clusterIter()) < tree->GetEntries() ) {
5380 /// printf("The cluster starts at %lld and ends at %lld (inclusive)\n",clusterStart,clusterIter.GetNextEntry()-1);
5381 /// }
5382 /// ~~~
5385 {
5386  // create cache if wanted
5387  if (fCacheDoAutoInit)
5388  SetCacheSizeAux();
5389 
5390  return TClusterIterator(this,firstentry);
5391 }
5392 
5393 ////////////////////////////////////////////////////////////////////////////////
5394 /// Return pointer to the current file.
5397 {
5398  if (!fDirectory || fDirectory==gROOT) {
5399  return 0;
5400  }
5401  return fDirectory->GetFile();
5402 }
5403 
5404 ////////////////////////////////////////////////////////////////////////////////
5405 /// Return the number of entries matching the selection.
5406 /// Return -1 in case of errors.
5407 ///
5408 /// If the selection uses any arrays or containers, we return the number
5409 /// of entries where at least one element match the selection.
5410 /// GetEntries is implemented using the selector class TSelectorEntries,
5411 /// which can be used directly (see code in TTreePlayer::GetEntries) for
5412 /// additional option.
5413 /// If SetEventList was used on the TTree or TChain, only that subset
5414 /// of entries will be considered.
5416 Long64_t TTree::GetEntries(const char *selection)
5417 {
5418  GetPlayer();
5419  if (fPlayer) {
5420  return fPlayer->GetEntries(selection);
5421  }
5422  return -1;
5423 }
5424 
5425 ////////////////////////////////////////////////////////////////////////////////
5426 /// Return pointer to the 1st Leaf named name in any Branch of this Tree or
5427 /// any branch in the list of friend trees.
5430 {
5431  if (fEntries) return fEntries;
5432  if (!fFriends) return 0;
5434  if (!fr) return 0;
5435  TTree *t = fr->GetTree();
5436  if (t==0) return 0;
5437  return t->GetEntriesFriend();
5438 }
5439 
5440 ////////////////////////////////////////////////////////////////////////////////
5441 /// Read all branches of entry and return total number of bytes read.
5442 ///
5443 /// - `getall = 0` : get only active branches
5444 /// - `getall = 1` : get all branches
5445 ///
5446 /// The function returns the number of bytes read from the input buffer.
5447 /// If entry does not exist the function returns 0.
5448 /// If an I/O error occurs, the function returns -1.
5449 ///
5450 /// If the Tree has friends, also read the friends entry.
5451 ///
5452 /// To activate/deactivate one or more branches, use TBranch::SetBranchStatus
5453 /// For example, if you have a Tree with several hundred branches, and you
5454 /// are interested only by branches named "a" and "b", do
5455 /// ~~~ {.cpp}
5456 /// mytree.SetBranchStatus("*",0); //disable all branches
5457 /// mytree.SetBranchStatus("a",1);
5458 /// mytree.SetBranchStatus("b",1);
5459 /// ~~~
5460 /// when calling mytree.GetEntry(i); only branches "a" and "b" will be read.
5461 ///
5462 /// __WARNING!!__
5463 /// If your Tree has been created in split mode with a parent branch "parent.",
5464 /// ~~~ {.cpp}
5465 /// mytree.SetBranchStatus("parent",1);
5466 /// ~~~
5467 /// will not activate the sub-branches of "parent". You should do:
5468 /// ~~~ {.cpp}
5469 /// mytree.SetBranchStatus("parent*",1);
5470 /// ~~~
5471 /// Without the trailing dot in the branch creation you have no choice but to
5472 /// call SetBranchStatus explicitly for each of the sub branches.
5473 ///
5474 /// An alternative is to call directly
5475 /// ~~~ {.cpp}
5476 /// brancha.GetEntry(i)
5477 /// branchb.GetEntry(i);
5478 /// ~~~
5479 /// ## IMPORTANT NOTE
5480 ///
5481 /// By default, GetEntry reuses the space allocated by the previous object
5482 /// for each branch. You can force the previous object to be automatically
5483 /// deleted if you call mybranch.SetAutoDelete(kTRUE) (default is kFALSE).
5484 ///
5485 /// Example:
5486 ///
5487 /// Consider the example in $ROOTSYS/test/Event.h
5488 /// The top level branch in the tree T is declared with:
5489 /// ~~~ {.cpp}
5490 /// Event *event = 0; //event must be null or point to a valid object
5491 /// //it must be initialized
5492 /// T.SetBranchAddress("event",&event);
5493 /// ~~~
5494 /// When reading the Tree, one can choose one of these 3 options:
5495 ///
5496 /// ## OPTION 1
5497 ///
5498 /// ~~~ {.cpp}
5499 /// for (Long64_t i=0;i<nentries;i++) {
5500 /// T.GetEntry(i);
5501 /// // the object event has been filled at this point
5502 /// }
5503 /// ~~~
5504 /// The default (recommended). At the first entry an object of the class
5505 /// Event will be created and pointed by event. At the following entries,
5506 /// event will be overwritten by the new data. All internal members that are
5507 /// TObject* are automatically deleted. It is important that these members
5508 /// be in a valid state when GetEntry is called. Pointers must be correctly
5509 /// initialized. However these internal members will not be deleted if the
5510 /// characters "->" are specified as the first characters in the comment
5511 /// field of the data member declaration.
5512 ///
5513 /// If "->" is specified, the pointer member is read via pointer->Streamer(buf).
5514 /// In this case, it is assumed that the pointer is never null (case of
5515 /// pointer TClonesArray *fTracks in the Event example). If "->" is not
5516 /// specified, the pointer member is read via buf >> pointer. In this case
5517 /// the pointer may be null. Note that the option with "->" is faster to
5518 /// read or write and it also consumes less space in the file.
5519 ///
5520 /// ## OPTION 2
5521 ///
5522 /// The option AutoDelete is set
5523 /// ~~~ {.cpp}
5524 /// TBranch *branch = T.GetBranch("event");
5525 /// branch->SetAddress(&event);
5526 /// branch->SetAutoDelete(kTRUE);
5527 /// for (Long64_t i=0;i<nentries;i++) {
5528 /// T.GetEntry(i);
5529 /// // the object event has been filled at this point
5530 /// }
5531 /// ~~~
5532 /// In this case, at each iteration, the object event is deleted by GetEntry
5533 /// and a new instance of Event is created and filled.
5534 ///
5535 /// ## OPTION 3
5536 ///
5537 /// ~~~ {.cpp}
5538 /// Same as option 1, but you delete yourself the event.
5539 ///
5540 /// for (Long64_t i=0;i<nentries;i++) {
5541 /// delete event;
5542 /// event = 0; // EXTREMELY IMPORTANT
5543 /// T.GetEntry(i);
5544 /// // the object event has been filled at this point
5545 /// }
5546 /// ~~~
5547 /// It is strongly recommended to use the default option 1. It has the
5548 /// additional advantage that functions like TTree::Draw (internally calling
5549 /// TTree::GetEntry) will be functional even when the classes in the file are
5550 /// not available.
5551 ///
5552 /// Note: See the comments in TBranchElement::SetAddress() for the
5553 /// object ownership policy of the underlying (user) data.
5555 Int_t TTree::GetEntry(Long64_t entry, Int_t getall)
5556 {
5557 
5558  // We already have been visited while recursively looking
5559  // through the friends tree, let return
5560  if (kGetEntry & fFriendLockStatus) return 0;
5561 
5562  if (entry < 0 || entry >= fEntries) return 0;
5563  Int_t i;
5564  Int_t nbytes = 0;
5565  fReadEntry = entry;
5566 
5567  // create cache if wanted
5568  if (fCacheDoAutoInit)
5569  SetCacheSizeAux();
5570 
5571  Int_t nbranches = fBranches.GetEntriesUnsafe();
5572  Int_t nb=0;
5573 
5574  auto seqprocessing = [&]() {
5575  TBranch *branch;
5576  for (i=0;i<nbranches;i++) {
5577  branch = (TBranch*)fBranches.UncheckedAt(i);
5578  nb = branch->GetEntry(entry, getall);
5579  if (nb < 0) break;
5580  nbytes += nb;
5581  }
5582  };
5583 
5584 #ifdef R__USE_IMT
5586  if (fSortedBranches.empty())
5587  InitializeBranchLists(true);
5588 
5589  // Count branches are processed first and sequentially
5590  for (auto branch : fSeqBranches) {
5591  nb = branch->GetEntry(entry, getall);
5592  if (nb < 0) break;
5593  nbytes += nb;
5594  }
5595  if (nb < 0) return nb;
5596 
5597  // Enable this IMT use case (activate its locks)
5599 
5600  Int_t errnb = 0;
5601  std::atomic<Int_t> pos(0);
5602  std::atomic<Int_t> nbpar(0);
5603 
5604  auto mapFunction = [&]() {
5605  // The branch to process is obtained when the task starts to run.
5606  // This way, since branches are sorted, we make sure that branches
5607  // leading to big tasks are processed first. If we assigned the
5608  // branch at task creation time, the scheduler would not necessarily
5609  // respect our sorting.
5610  Int_t j = pos.fetch_add(1);
5611 
5612  Int_t nbtask = 0;
5613  auto branch = fSortedBranches[j].second;
5614 
5615  if (gDebug > 0) {
5616  std::stringstream ss;
5617  ss << std::this_thread::get_id();
5618  Info("GetEntry", "[IMT] Thread %s", ss.str().c_str());
5619  Info("GetEntry", "[IMT] Running task for branch #%d: %s", j, branch->GetName());
5620  }
5621 
5622  std::chrono::time_point<std::chrono::system_clock> start, end;
5623 
5624  start = std::chrono::system_clock::now();
5625  nbtask = branch->GetEntry(entry, getall);
5626  end = std::chrono::system_clock::now();
5627 
5628  Long64_t tasktime = (Long64_t)std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
5629  fSortedBranches[j].first += tasktime;
5630 
5631  if (nbtask < 0) errnb = nbtask;
5632  else nbpar += nbtask;
5633  };
5634 
5635  ROOT::TThreadExecutor pool;
5636  pool.Foreach(mapFunction, fSortedBranches.size());
5637 
5638  if (errnb < 0) {
5639  nb = errnb;
5640  }
5641  else {
5642  // Save the number of bytes read by the tasks
5643  nbytes += nbpar;
5644 
5645  // Re-sort branches if necessary
5649  }
5650  }
5651  }
5652  else {
5653  seqprocessing();
5654  }
5655 #else
5656  seqprocessing();
5657 #endif
5658  if (nb < 0) return nb;
5659 
5660  // GetEntry in list of friends
5661  if (!fFriends) return nbytes;
5662  TFriendLock lock(this,kGetEntry);
5663  TIter nextf(fFriends);
5664  TFriendElement *fe;
5665  while ((fe = (TFriendElement*)nextf())) {
5666  TTree *t = fe->GetTree();
5667  if (t) {
5669  nb = t->GetEntry(t->GetReadEntry(),getall);
5670  } else {
5671  if ( t->LoadTreeFriend(entry,this) >= 0 ) {
5672  nb = t->GetEntry(t->GetReadEntry(),getall);
5673  } else nb = 0;
5674  }
5675  if (nb < 0) return nb;
5676  nbytes += nb;
5677  }
5678  }
5679  return nbytes;
5680 }
5681 
5682 
5683 ////////////////////////////////////////////////////////////////////////////////
5684 /// Divides the top-level branches into two vectors: (i) branches to be
5685 /// processed sequentially and (ii) branches to be processed in parallel.
5686 /// Even if IMT is on, some branches might need to be processed first and in a
5687 /// sequential fashion: in the parallelization of GetEntry, those are the
5688 /// branches that store the size of another branch for every entry
5689 /// (e.g. the size of an array branch). If such branches were processed
5690 /// in parallel with the rest, there could be two threads invoking
5691 /// TBranch::GetEntry on one of them at the same time, since a branch that
5692 /// depends on a size (or count) branch will also invoke GetEntry on the latter.
5693 /// This method can be invoked several times during the event loop if the TTree
5694 /// is being written, for example when adding new branches. In these cases, the
5695 /// `checkLeafCount` parameter is false.
5696 /// \param[in] checkLeafCount True if we need to check whether some branches are
5697 /// count leaves.
5699 void TTree::InitializeBranchLists(bool checkLeafCount)
5700 {
5701  Int_t nbranches = fBranches.GetEntriesFast();
5702 
5703  // The special branch fBranchRef needs to be processed sequentially:
5704  // we add it once only.
5705  if (fBranchRef && fBranchRef != fSeqBranches[0]) {
5706  fSeqBranches.push_back(fBranchRef);
5707  }
5708 
5709  // The branches to be processed sequentially are those that are the leaf count of another branch
5710  if (checkLeafCount) {
5711  for (Int_t i = 0; i < nbranches; i++) {
5712  TBranch* branch = (TBranch*)fBranches.UncheckedAt(i);
5713  auto leafCount = ((TLeaf*)branch->GetListOfLeaves()->At(0))->GetLeafCount();
5714  if (leafCount) {
5715  auto countBranch = leafCount->GetBranch();
5716  if (std::find(fSeqBranches.begin(), fSeqBranches.end(), countBranch) == fSeqBranches.end()) {
5717  fSeqBranches.push_back(countBranch);
5718  }
5719  }
5720  }
5721  }
5722 
5723  // Any branch that is not a leaf count can be safely processed in parallel when reading
5724  // We need to reset the vector to make sure we do not re-add several times the same branch.
5725  if (!checkLeafCount) {
5726  fSortedBranches.clear();
5727  }
5728  for (Int_t i = 0; i < nbranches; i++) {
5729  Long64_t bbytes = 0;
5730  TBranch* branch = (TBranch*)fBranches.UncheckedAt(i);
5731  if (std::find(fSeqBranches.begin(), fSeqBranches.end(), branch) == fSeqBranches.end()) {
5732  bbytes = branch->GetTotBytes("*");
5733  fSortedBranches.emplace_back(bbytes, branch);
5734  }
5735  }
5736 
5737  // Initially sort parallel branches by size
5738  std::sort(fSortedBranches.begin(),
5739