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