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