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