ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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  To store large quantities of same-class objects, ROOT provides the TTree and
15  TNtuple classes. The TTree class is optimized to
16  reduce disk space and enhance access speed. A TNtuple is a TTree that is limited
17  to only hold floating-point numbers; a TTree on the other hand can hold all kind
18  of data, such as objects or arrays in addition to all the simple types.
19 
20 */
21 
22 /** \class TTree
23 \ingroup tree
24 
25 A TTree object has a header with a name and a title.
26 
27 It consists of a list of independent branches (TBranch). Each branch has its own
28 definition and list of buffers. Branch buffers may be automatically written to
29 disk or kept in memory until the Tree attribute `fMaxVirtualSize` is reached.
30 Variables of one branch are written to the same buffer. A branch buffer is
31 automatically compressed if the file compression attribute is set (default).
32 
33 Branches may be written to different files (see TBranch::SetFile).
34 
35 The ROOT user can decide to make one single branch and serialize one object into
36 one single I/O buffer or to make several branches. Making one single branch and
37 one single buffer can be the right choice when one wants to process only a subset
38 of all entries in the tree. (you know for example the list of entry numbers you
39 want to process). Making several branches is particularly interesting in the
40 data analysis phase, when one wants to histogram some attributes of an object
41 (entry) without reading all the attributes.
42 ~~~ {.cpp}
43  TTree *tree = new TTree(name, title)
44 ~~~
45 Creates a Tree with name and title.
46 
47 Various kinds of branches can be added to a tree:
48 
49 - simple structures or list of variables. (may be for C or Fortran structures)
50 - any object (inheriting from TObject). (we expect this option be the most frequent)
51 - a ClonesArray. (a specialized object for collections of same class objects)
52 
53 ## Case A
54 ~~~ {.cpp}
55  TBranch *branch = tree->Branch(branchname, address, leaflist, bufsize)
56 ~~~
57 - address is the address of the first item of a structure
58 - leaflist is the concatenation of all the variable names and types
59  separated by a colon character :
60  The variable name and the variable type are separated by a
61  slash (/). The variable type must be 1 character. (Characters
62  after the first are legal and will be appended to the visible
63  name of the leaf, but have no effect.) If no type is given, the
64  type of the variable is assumed to be the same as the previous
65  variable. If the first variable does not have a type, it is
66  assumed of type F by default. The list of currently supported
67  types is given below:
68  - C : a character string terminated by the 0 character
69  - B : an 8 bit signed integer (Char_t)
70  - b : an 8 bit unsigned integer (UChar_t)
71  - S : a 16 bit signed integer (Short_t)
72  - s : a 16 bit unsigned integer (UShort_t)
73  - I : a 32 bit signed integer (Int_t)
74  - i : a 32 bit unsigned integer (UInt_t)
75  - F : a 32 bit floating point (Float_t)
76  - D : a 64 bit floating point (Double_t)
77  - L : a 64 bit signed integer (Long64_t)
78  - l : a 64 bit unsigned integer (ULong64_t)
79  - O : [the letter 'o', not a zero] a boolean (Bool_t)
80 - If the address points to a single numerical variable, the leaflist is optional:
81  int value;
82  `tree->Branch(branchname, &value);`
83 - If the address points to more than one numerical variable, we strongly recommend
84  that the variable be sorted in decreasing order of size. Any other order will
85  result in a non-portable (even between CINT and compiled code on the platform)
86  TTree (i.e. you will not be able to read it back on a platform with a different
87  padding strategy).
88 
89 ## Case B
90 ~~~ {.cpp}
91  TBranch *branch = tree->Branch(branchname, &p_object, bufsize, splitlevel)
92  TBranch *branch = tree->Branch(branchname, className, &p_object, bufsize, splitlevel)
93 ~~~
94 - p_object is a pointer to an object.
95 - If className is not specified, Branch uses the type of p_object to determine the
96  type of the object.
97 - If className is used to specify explicitly the object type, the className must
98  be of a type related to the one pointed to by the pointer. It should be either
99  a parent or derived class.
100 - if splitlevel=0, the object is serialized in the branch buffer.
101 - if splitlevel=1, this branch will automatically be split
102  into subbranches, with one subbranch for each data member or object
103  of the object itself. In case the object member is a TClonesArray,
104  the mechanism described in case C is applied to this array.
105 - if splitlevel=2 ,this branch will automatically be split
106  into subbranches, with one subbranch for each data member or object
107  of the object itself. In case the object member is a TClonesArray,
108  it is processed as a TObject*, only one branch.
109 
110 Note: The pointer whose address is passed to TTree::Branch must not
111  be destroyed (i.e. go out of scope) until the TTree is deleted or
112  TTree::ResetBranchAddress is called.
113 
114 Note: The pointer p_object must be initialized before calling TTree::Branch
115 - Do either:
116 ~~~ {.cpp}
117  MyDataClass* p_object = 0;
118  tree->Branch(branchname, &p_object);
119 ~~~
120 - Or:
121 ~~~ {.cpp}
122  MyDataClass* p_object = new MyDataClass;
123  tree->Branch(branchname, &p_object);
124 ~~~
125 Whether the pointer is set to zero or not, the ownership of the object
126 is not taken over by the TTree. I.e. eventhough an object will be allocated
127 by TTree::Branch if the pointer p_object is zero, the object will <b>not</b>
128 be deleted when the TTree is deleted.
129 
130 ## Case C
131 ~~~ {.cpp}
132  MyClass object;
133  TBranch *branch = tree->Branch(branchname, &object, bufsize, splitlevel)
134 ~~~
135 Note: The 2nd parameter must be the address of a valid object.
136  The object must not be destroyed (i.e. be deleted) until the TTree
137  is deleted or TTree::ResetBranchAddress is called.
138 
139 - if splitlevel=0, the object is serialized in the branch buffer.
140 - if splitlevel=1 (default), this branch will automatically be split
141  into subbranches, with one subbranch for each data member or object
142  of the object itself. In case the object member is a TClonesArray,
143  the mechanism described in case C is applied to this array.
144 - if splitlevel=2 ,this branch will automatically be split
145  into subbranches, with one subbranch for each data member or object
146  of the object itself. In case the object member is a TClonesArray,
147  it is processed as a TObject*, only one branch.
148 
149 ## Case D
150 ~~~ {.cpp}
151  TBranch *branch = tree->Branch(branchname,clonesarray, bufsize, splitlevel)
152  clonesarray is the address of a pointer to a TClonesArray.
153 ~~~
154 The TClonesArray is a direct access list of objects of the same class.
155 For example, if the TClonesArray is an array of TTrack objects,
156 this function will create one subbranch for each data member of
157 the object TTrack.
158 
159 ## Case E
160 ~~~ {.cpp}
161  TBranch *branch = tree->Branch( branchname, STLcollection, buffsize, splitlevel);
162 ~~~
163 STLcollection is the address of a pointer to std::vector, std::list,
164 std::deque, std::set or std::multiset containing pointers to objects.
165 If the splitlevel is a value bigger than 100 (TTree::kSplitCollectionOfPointers)
166 then the collection will be written in split mode, e.g. if it contains objects of
167 any types deriving from TTrack this function will sort the objects
168 based on their type and store them in separate branches in split
169 mode.
170 ~~~ {.cpp}
171  branch->SetAddress(Void *address)
172 ~~~
173 In case of dynamic structures changing with each entry for example, one must
174 redefine the branch address before filling the branch again.
175 This is done via the TBranch::SetAddress member function.
176 ~~~ {.cpp}
177  tree->Fill()
178 ~~~
179 loops on all defined branches and for each branch invokes the Fill function.
180 
181 See also the class TNtuple (a simple Tree with branches of floats)
182 and the class TNtupleD (a simple Tree with branches of doubles)
183 
184 ## Adding a Branch to an Existing Tree
185 
186 You may want to add a branch to an existing tree. For example,
187 if one variable in the tree was computed with a certain algorithm,
188 you may want to try another algorithm and compare the results.
189 One solution is to add a new branch, fill it, and save the tree.
190 The code below adds a simple branch to an existing tree.
191 Note the kOverwrite option in the Write method, it overwrites the
192 existing tree. If it is not specified, two copies of the tree headers
193 are saved.
194 ~~~ {.cpp}
195  void tree3AddBranch() {
196  TFile f("tree3.root", "update");
197 
198  Float_t new_v;
199  TTree *t3 = (TTree*)f->Get("t3");
200  TBranch *newBranch = t3->Branch("new_v", &new_v, "new_v/F");
201 
202  Long64_t nentries = t3->GetEntries(); // read the number of entries in the t3
203 
204  for (Long64_t i = 0; i < nentries; i++) {
205  new_v= gRandom->Gaus(0, 1);
206  newBranch->Fill();
207  }
208 
209  t3->Write("", TObject::kOverwrite); // save only the new version of the tree
210  }
211 ~~~
212 Adding a branch is often not possible because the tree is in a read-only
213 file and you do not have permission to save the modified tree with the
214 new branch. Even if you do have the permission, you risk losing the
215 original tree with an unsuccessful attempt to save the modification.
216 Since trees are usually large, adding a branch could extend it over the
217 2GB limit. In this case, the attempt to write the tree fails, and the
218 original data is erased.
219 In addition, adding a branch to a tree enlarges the tree and increases
220 the amount of memory needed to read an entry, and therefore decreases
221 the performance.
222 
223 For these reasons, ROOT offers the concept of friends for trees (and chains).
224 We encourage you to use TTree::AddFriend rather than adding a branch manually.
225 
226 Begin_Macro
227 ../../../tutorials/tree/tree.C
228 End_Macro
229 
230 ~~~ {.cpp}
231  // A simple example with histograms and a tree
232  //
233  // This program creates :
234  // - a one dimensional histogram
235  // - a two dimensional histogram
236  // - a profile histogram
237  // - a tree
238  //
239  // These objects are filled with some random numbers and saved on a file.
240 
241  #include "TFile.h"
242  #include "TH1.h"
243  #include "TH2.h"
244  #include "TProfile.h"
245  #include "TRandom.h"
246  #include "TTree.h"
247 
248  //__________________________________________________________________________
249  main(int argc, char **argv)
250  {
251  // Create a new ROOT binary machine independent file.
252  // Note that this file may contain any kind of ROOT objects, histograms,trees
253  // pictures, graphics objects, detector geometries, tracks, events, etc..
254  // This file is now becoming the current directory.
255  TFile hfile("htree.root","RECREATE","Demo ROOT file with histograms & trees");
256 
257  // Create some histograms and a profile histogram
258  TH1F *hpx = new TH1F("hpx","This is the px distribution",100,-4,4);
259  TH2F *hpxpy = new TH2F("hpxpy","py ps px",40,-4,4,40,-4,4);
260  TProfile *hprof = new TProfile("hprof","Profile of pz versus px",100,-4,4,0,20);
261 
262  // Define some simple structures
263  typedef struct {Float_t x,y,z;} POINT;
264  typedef struct {
265  Int_t ntrack,nseg,nvertex;
266  UInt_t flag;
267  Float_t temperature;
268  } EVENTN;
269  static POINT point;
270  static EVENTN eventn;
271 
272  // Create a ROOT Tree
273  TTree *tree = new TTree("T","An example of ROOT tree with a few branches");
274  tree->Branch("point",&point,"x:y:z");
275  tree->Branch("eventn",&eventn,"ntrack/I:nseg:nvertex:flag/i:temperature/F");
276  tree->Branch("hpx","TH1F",&hpx,128000,0);
277 
278  Float_t px,py,pz;
279  static Float_t p[3];
280 
281  // Here we start a loop on 1000 events
282  for ( Int_t i=0; i<1000; i++) {
283  gRandom->Rannor(px,py);
284  pz = px*px + py*py;
285  Float_t random = gRandom->::Rndm(1);
286 
287  // Fill histograms
288  hpx->Fill(px);
289  hpxpy->Fill(px,py,1);
290  hprof->Fill(px,pz,1);
291 
292  // Fill structures
293  p[0] = px;
294  p[1] = py;
295  p[2] = pz;
296  point.x = 10*(random-1);;
297  point.y = 5*random;
298  point.z = 20*random;
299  eventn.ntrack = Int_t(100*random);
300  eventn.nseg = Int_t(2*eventn.ntrack);
301  eventn.nvertex = 1;
302  eventn.flag = Int_t(random+0.5);
303  eventn.temperature = 20+random;
304 
305  // Fill the tree. For each event, save the 2 structures and 3 objects
306  // In this simple example, the objects hpx, hprof and hpxpy are slightly
307  // different from event to event. We expect a big compression factor!
308  tree->Fill();
309  }
310  // End of the loop
311 
312  tree->Print();
313 
314  // Save all objects in this file
315  hfile.Write();
316 
317  // Close the file. Note that this is automatically done when you leave
318  // the application.
319  hfile.Close();
320 
321  return 0;
322 }
323 ~~~
324 */
325 
326 #include "RConfig.h"
327 #include "TTree.h"
328 
329 #include "TArrayC.h"
330 #include "TBufferFile.h"
331 #include "TBaseClass.h"
332 #include "TBasket.h"
333 #include "TBranchClones.h"
334 #include "TBranchElement.h"
335 #include "TBranchObject.h"
336 #include "TBranchRef.h"
337 #include "TBrowser.h"
338 #include "TClass.h"
339 #include "TClassEdit.h"
340 #include "TClonesArray.h"
341 #include "TCut.h"
342 #include "TDataMember.h"
343 #include "TDataType.h"
344 #include "TDirectory.h"
345 #include "TError.h"
346 #include "TEntryList.h"
347 #include "TEnv.h"
348 #include "TEventList.h"
349 #include "TFile.h"
350 #include "TFolder.h"
351 #include "TFriendElement.h"
352 #include "TInterpreter.h"
353 #include "TLeaf.h"
354 #include "TLeafB.h"
355 #include "TLeafC.h"
356 #include "TLeafD.h"
357 #include "TLeafElement.h"
358 #include "TLeafF.h"
359 #include "TLeafI.h"
360 #include "TLeafL.h"
361 #include "TLeafObject.h"
362 #include "TLeafS.h"
363 #include "TList.h"
364 #include "TMath.h"
365 #include "TROOT.h"
366 #include "TRealData.h"
367 #include "TRegexp.h"
368 #include "TStreamerElement.h"
369 #include "TStreamerInfo.h"
370 #include "TStyle.h"
371 #include "TSystem.h"
372 #include "TTreeCloner.h"
373 #include "TTreeCache.h"
374 #include "TTreeCacheUnzip.h"
375 #include "TVirtualCollectionProxy.h"
377 #include "TVirtualFitter.h"
378 #include "TVirtualIndex.h"
379 #include "TVirtualPerfStats.h"
380 #include "TVirtualPad.h"
381 #include "TBranchSTL.h"
382 #include "TSchemaRuleSet.h"
383 #include "TFileMergeInfo.h"
384 
385 #include <cstddef>
386 #include <fstream>
387 #include <sstream>
388 #include <string>
389 #include <stdio.h>
390 #include <limits.h>
391 
392 Int_t TTree::fgBranchStyle = 1; // Use new TBranch style with TBranchElement.
393 Long64_t TTree::fgMaxTreeSize = 100000000000LL;
394 
397 ////////////////////////////////////////////////////////////////////////////////
398 ////////////////////////////////////////////////////////////////////////////////
399 ////////////////////////////////////////////////////////////////////////////////
400 
401 static char DataTypeToChar(EDataType datatype)
402 {
403  // Return the leaflist 'char' for a given datatype.
404 
405  switch(datatype) {
406  case kChar_t: return 'B';
407  case kUChar_t: return 'b';
408  case kBool_t: return 'O';
409  case kShort_t: return 'S';
410  case kUShort_t: return 's';
411  case kCounter:
412  case kInt_t: return 'I';
413  case kUInt_t: return 'i';
414  case kDouble_t:
415  case kDouble32_t: return 'D';
416  case kFloat_t:
417  case kFloat16_t: return 'F';
418  case kLong_t: return 0; // unsupported
419  case kULong_t: return 0; // unsupported?
420  case kchar: return 0; // unsupported
421  case kLong64_t: return 'L';
422  case kULong64_t: return 'l';
423 
424  case kCharStar: return 'C';
425  case kBits: return 0; //unsupported
426 
427  case kOther_t:
428  case kNoType_t:
429  default:
430  return 0;
431  }
432  return 0;
433 }
434 
435 ////////////////////////////////////////////////////////////////////////////////
436 /// \class TTree::TFriendLock
437 /// Helper class to prevent infinite recursion in the usage of TTree Friends.
438 
439 ////////////////////////////////////////////////////////////////////////////////
440 /// Record in tree that it has been used while recursively looks through the friends.
441 
443 : fTree(tree)
444 {
445  // We could also add some code to acquire an actual
446  // lock to prevent multi-thread issues
447  fMethodBit = methodbit;
448  if (fTree) {
449  fPrevious = fTree->fFriendLockStatus & fMethodBit;
450  fTree->fFriendLockStatus |= fMethodBit;
451  } else {
452  fPrevious = 0;
453  }
454 }
455 
456 ////////////////////////////////////////////////////////////////////////////////
457 /// Copy constructor.
458 
460  fTree(tfl.fTree),
461  fMethodBit(tfl.fMethodBit),
462  fPrevious(tfl.fPrevious)
463 {
464 }
465 
466 ////////////////////////////////////////////////////////////////////////////////
467 /// Assignment operator.
468 
470 {
471  if(this!=&tfl) {
472  fTree=tfl.fTree;
474  fPrevious=tfl.fPrevious;
475  }
476  return *this;
477 }
478 
479 ////////////////////////////////////////////////////////////////////////////////
480 /// Restore the state of tree the same as before we set the lock.
481 
483 {
484  if (fTree) {
485  if (!fPrevious) {
486  fTree->fFriendLockStatus &= ~(fMethodBit & kBitMask);
487  }
488  }
489 }
490 
491 ////////////////////////////////////////////////////////////////////////////////
492 /// \class TTree::TClusterIterator
493 /// Helper class to iterate over cluster of baskets.
494 
495 ////////////////////////////////////////////////////////////////////////////////
496 /// Regular constructor.
497 /// TTree is not set as const, since we might modify if it is a TChain.
498 
499 TTree::TClusterIterator::TClusterIterator(TTree *tree, Long64_t firstEntry) : fTree(tree), fClusterRange(0), fStartEntry(0), fNextEntry(0)
500 {
501  if ( fTree->GetAutoFlush() <= 0 ) {
502  // Case of old files before November 9 2009
503  fStartEntry = firstEntry;
504  } else if (fTree->fNClusterRange) {
505  // Find the correct cluster range.
506  //
507  // Since fClusterRangeEnd contains the inclusive upper end of the range, we need to search for the
508  // range that was containing the previous entry and add 1 (because BinarySearch consider the values
509  // to be the inclusive start of the bucket).
510  fClusterRange = TMath::BinarySearch(fTree->fNClusterRange, fTree->fClusterRangeEnd, firstEntry - 1) + 1;
511 
512  Long64_t entryInRange;
513  Long64_t pedestal;
514  if (fClusterRange == 0) {
515  pedestal = 0;
516  entryInRange = firstEntry;
517  } else {
518  pedestal = fTree->fClusterRangeEnd[fClusterRange-1] + 1;
519  entryInRange = firstEntry - pedestal;
520  }
521  Long64_t autoflush;
522  if (fClusterRange == fTree->fNClusterRange) {
523  autoflush = fTree->fAutoFlush;
524  } else {
525  autoflush = fTree->fClusterSize[fClusterRange];
526  }
527  if (autoflush == 0) {
528  autoflush = GetEstimatedClusterSize();
529  }
530  fStartEntry = pedestal + entryInRange - entryInRange%autoflush;
531  } else {
532  fStartEntry = firstEntry - firstEntry%fTree->GetAutoFlush();
533  }
534  fNextEntry = fStartEntry; // Position correctly for the first call to Next()
535 }
536 
537 ////////////////////////////////////////////////////////////////////////////////
538 /// In the case where the cluster size was not fixed (old files and
539 /// case where autoflush was explicitly set to zero, we need estimate
540 /// a cluster size in relation to the size of the cache.
541 
543 {
544  Long64_t zipBytes = fTree->GetZipBytes();
545  if (zipBytes == 0) {
546  return fTree->GetEntries() - 1;
547  } else {
548  Long64_t clusterEstimate = 1;
549  Long64_t cacheSize = fTree->GetCacheSize();
550  if (cacheSize == 0) {
551  // Humm ... let's double check on the file.
552  TFile *file = fTree->GetCurrentFile();
553  if (file) {
554  TFileCacheRead *cache = file->GetCacheRead(fTree);
555  if (cache) {
556  cacheSize = cache->GetBufferSize();
557  }
558  }
559  }
560  if (cacheSize > 0) {
561  clusterEstimate = fTree->GetEntries() * cacheSize / zipBytes;
562  if (clusterEstimate == 0)
563  clusterEstimate = 1;
564  }
565  return clusterEstimate;
566  }
567 }
568 
569 ////////////////////////////////////////////////////////////////////////////////
570 /// Move on to the next cluster and return the starting entry
571 /// of this next cluster
572 
574 {
575  fStartEntry = fNextEntry;
576  if ( fTree->GetAutoFlush() <= 0 ) {
577  // Case of old files before November 9 2009
578  Long64_t clusterEstimate = GetEstimatedClusterSize();
579  fNextEntry = fStartEntry + clusterEstimate;
580  } else {
581  if (fClusterRange == fTree->fNClusterRange) {
582  // We are looking at the last range ; its size
583  // is defined by AutoFlush itself and goes to the GetEntries.
584  fNextEntry += fTree->GetAutoFlush();
585  } else {
586  if (fStartEntry > fTree->fClusterRangeEnd[fClusterRange]) {
587  ++fClusterRange;
588  }
589  if (fClusterRange == fTree->fNClusterRange) {
590  // We are looking at the last range which size
591  // is defined by AutoFlush itself and goes to the GetEntries.
592  fNextEntry += fTree->GetAutoFlush();
593  } else {
594  Long64_t clusterSize = fTree->fClusterSize[fClusterRange];
595  if (clusterSize == 0) {
596  clusterSize = GetEstimatedClusterSize();
597  }
598  fNextEntry += clusterSize;
599  if (fNextEntry > fTree->fClusterRangeEnd[fClusterRange]) {
600  // The last cluster of the range was a partial cluster,
601  // so the next cluster starts at the beginning of the
602  // next range.
603  fNextEntry = fTree->fClusterRangeEnd[fClusterRange] + 1;
604  }
605  }
606  }
607  }
608  if (fNextEntry > fTree->GetEntries()) {
609  fNextEntry = fTree->GetEntries();
610  }
611  return fStartEntry;
612 }
613 
614 ////////////////////////////////////////////////////////////////////////////////
615 ////////////////////////////////////////////////////////////////////////////////
616 ////////////////////////////////////////////////////////////////////////////////
617 
618 ////////////////////////////////////////////////////////////////////////////////
619 /// Default constructor and I/O constructor.
620 ///
621 /// Note: We do *not* insert ourself into the current directory.
622 ///
623 
624 TTree::TTree()
626 , TAttLine()
627 , TAttFill()
628 , TAttMarker()
629 , fEntries(0)
630 , fTotBytes(0)
631 , fZipBytes(0)
632 , fSavedBytes(0)
633 , fFlushedBytes(0)
634 , fWeight(1)
635 , fTimerInterval(0)
636 , fScanField(25)
637 , fUpdate(0)
639 , fNClusterRange(0)
640 , fMaxClusterRange(0)
641 , fMaxEntries(0)
642 , fMaxEntryLoop(0)
643 , fMaxVirtualSize(0)
644 , fAutoSave( -300000000)
645 , fAutoFlush(-30000000)
646 , fEstimate(1000000)
647 , fClusterRangeEnd(0)
648 , fClusterSize(0)
649 , fCacheSize(0)
650 , fChainOffset(0)
651 , fReadEntry(-1)
652 , fTotalBuffers(0)
653 , fPacketSize(100)
654 , fNfill(0)
655 , fDebug(0)
656 , fDebugMin(0)
657 , fDebugMax(9999999)
658 , fMakeClass(0)
659 , fFileNumber(0)
660 , fNotify(0)
661 , fDirectory(0)
662 , fBranches()
663 , fLeaves()
664 , fAliases(0)
665 , fEventList(0)
666 , fEntryList(0)
667 , fIndexValues()
668 , fIndex()
669 , fTreeIndex(0)
670 , fFriends(0)
671 , fPerfStats(0)
672 , fUserInfo(0)
673 , fPlayer(0)
674 , fClones(0)
675 , fBranchRef(0)
677 , fTransientBuffer(0)
680 {
681  fMaxEntries = 1000000000;
682  fMaxEntries *= 1000;
683 
684  fMaxEntryLoop = 1000000000;
685  fMaxEntryLoop *= 1000;
686 
688 }
689 
690 ////////////////////////////////////////////////////////////////////////////////
691 /// Normal tree constructor.
692 ///
693 /// The tree is created in the current directory.
694 /// Use the various functions Branch below to add branches to this tree.
695 ///
696 /// If the first character of title is a "/", the function assumes a folder name.
697 /// In this case, it creates automatically branches following the folder hierarchy.
698 /// splitlevel may be used in this case to control the split level.
699 
700 TTree::TTree(const char* name, const char* title, Int_t splitlevel /* = 99 */)
701 : TNamed(name, title)
702 , TAttLine()
703 , TAttFill()
704 , TAttMarker()
705 , fEntries(0)
706 , fTotBytes(0)
707 , fZipBytes(0)
708 , fSavedBytes(0)
709 , fFlushedBytes(0)
710 , fWeight(1)
711 , fTimerInterval(0)
712 , fScanField(25)
713 , fUpdate(0)
715 , fNClusterRange(0)
716 , fMaxClusterRange(0)
717 , fMaxEntries(0)
718 , fMaxEntryLoop(0)
719 , fMaxVirtualSize(0)
720 , fAutoSave( -300000000)
721 , fAutoFlush(-30000000)
722 , fEstimate(1000000)
723 , fClusterRangeEnd(0)
724 , fClusterSize(0)
725 , fCacheSize(0)
726 , fChainOffset(0)
727 , fReadEntry(-1)
728 , fTotalBuffers(0)
729 , fPacketSize(100)
730 , fNfill(0)
731 , fDebug(0)
732 , fDebugMin(0)
733 , fDebugMax(9999999)
734 , fMakeClass(0)
735 , fFileNumber(0)
736 , fNotify(0)
737 , fDirectory(0)
738 , fBranches()
739 , fLeaves()
740 , fAliases(0)
741 , fEventList(0)
742 , fEntryList(0)
743 , fIndexValues()
744 , fIndex()
745 , fTreeIndex(0)
746 , fFriends(0)
747 , fPerfStats(0)
748 , fUserInfo(0)
749 , fPlayer(0)
750 , fClones(0)
751 , fBranchRef(0)
753 , fTransientBuffer(0)
756 {
757  // TAttLine state.
761 
762  // TAttFill state.
765 
766  // TAttMarkerState.
770 
771  fMaxEntries = 1000000000;
772  fMaxEntries *= 1000;
773 
774  fMaxEntryLoop = 1000000000;
775  fMaxEntryLoop *= 1000;
776 
777  // Insert ourself into the current directory.
778  // FIXME: This is very annoying behaviour, we should
779  // be able to choose to not do this like we
780  // can with a histogram.
782  if (fDirectory) fDirectory->Append(this);
783 
785 
786  // If title starts with "/" and is a valid folder name, a superbranch
787  // is created.
788  // FIXME: Why?
789  if (strlen(title) > 2) {
790  if (title[0] == '/') {
791  Branch(title+1,32000,splitlevel);
792  }
793  }
794 }
795 
796 ////////////////////////////////////////////////////////////////////////////////
797 /// Destructor.
798 
800 {
801  if (fDirectory) {
802  // We are in a directory, which may possibly be a file.
803  if (fDirectory->GetList()) {
804  // Remove us from the directory listing.
805  fDirectory->Remove(this);
806  }
807  //delete the file cache if it points to this Tree
808  TFile *file = fDirectory->GetFile();
809  MoveReadCache(file,0);
810  }
811  // We don't own the leaves in fLeaves, the branches do.
812  fLeaves.Clear();
813  // I'm ready to destroy any objects allocated by
814  // SetAddress() by my branches. If I have clones,
815  // tell them to zero their pointers to this shared
816  // memory.
817  if (fClones && fClones->GetEntries()) {
818  // I have clones.
819  // I am about to delete the objects created by
820  // SetAddress() which we are sharing, so tell
821  // the clones to release their pointers to them.
822  for (TObjLink* lnk = fClones->FirstLink(); lnk; lnk = lnk->Next()) {
823  TTree* clone = (TTree*) lnk->GetObject();
824  // clone->ResetBranchAddresses();
825 
826  // Reset only the branch we have set the address of.
827  CopyAddresses(clone,kTRUE);
828  }
829  }
830  // Get rid of our branches, note that this will also release
831  // any memory allocated by TBranchElement::SetAddress().
832  fBranches.Delete();
833  // FIXME: We must consider what to do with the reset of these if we are a clone.
834  delete fPlayer;
835  fPlayer = 0;
836  if (fFriends) {
837  fFriends->Delete();
838  delete fFriends;
839  fFriends = 0;
840  }
841  if (fAliases) {
842  fAliases->Delete();
843  delete fAliases;
844  fAliases = 0;
845  }
846  if (fUserInfo) {
847  fUserInfo->Delete();
848  delete fUserInfo;
849  fUserInfo = 0;
850  }
851  if (fClones) {
852  // Clone trees should no longer be removed from fClones when they are deleted.
853  gROOT->GetListOfCleanups()->Remove(fClones);
854  // Note: fClones does not own its content.
855  delete fClones;
856  fClones = 0;
857  }
858  if (fEntryList) {
860  // Delete the entry list if it is marked to be deleted and it is not also
861  // owned by a directory. (Otherwise we would need to make sure that a
862  // TDirectoryFile that has a TTree in it does a 'slow' TList::Delete.
863  delete fEntryList;
864  fEntryList=0;
865  }
866  }
867  delete fTreeIndex;
868  fTreeIndex = 0;
869  delete fBranchRef;
870  fBranchRef = 0;
871  delete [] fClusterRangeEnd;
872  fClusterRangeEnd = 0;
873  delete [] fClusterSize;
874  fClusterSize = 0;
875  // Must be done after the destruction of friends.
876  // Note: We do *not* own our directory.
877  fDirectory = 0;
878 
879  if (fTransientBuffer) {
880  delete fTransientBuffer;
881  fTransientBuffer = 0;
882  }
883 }
884 
885 ////////////////////////////////////////////////////////////////////////////////
886 /// Returns the transient buffer currently used by this TTree for reading/writing baskets.
887 
889 {
890  if (fTransientBuffer) {
891  if (fTransientBuffer->BufferSize() < size) {
892  fTransientBuffer->Expand(size);
893  }
894  return fTransientBuffer;
895  }
897  return fTransientBuffer;
898 }
899 
900 ////////////////////////////////////////////////////////////////////////////////
901 /// Add branch with name bname to the Tree cache.
902 /// If bname="*" all branches are added to the cache.
903 /// if subbranches is true all the branches of the subbranches are
904 /// also put to the cache.
905 ///
906 /// Returns:
907 /// - 0 branch added or already included
908 /// - -1 on error
909 
910 Int_t TTree::AddBranchToCache(const char*bname, Bool_t subbranches)
911 {
912  if (!GetTree()) {
913  if (LoadTree(0)<0) {
914  Error("AddBranchToCache","Could not load a tree");
915  return -1;
916  }
917  }
918  if (GetTree()) {
919  if (GetTree() != this) {
920  return GetTree()->AddBranchToCache(bname, subbranches);
921  }
922  } else {
923  Error("AddBranchToCache", "No tree is available. Branch was not added to the cache");
924  return -1;
925  }
926 
927  TFile *f = GetCurrentFile();
928  if (!f) {
929  Error("AddBranchToCache", "No file is available. Branch was not added to the cache");
930  return -1;
931  }
932  TTreeCache *tc = GetReadCache(f,kTRUE);
933  if (!tc) {
934  Error("AddBranchToCache", "No cache is available, branch not added");
935  return -1;
936  }
937  return tc->AddBranch(bname,subbranches);
938 }
939 
940 ////////////////////////////////////////////////////////////////////////////////
941 /// Add branch b to the Tree cache.
942 /// if subbranches is true all the branches of the subbranches are
943 /// also put to the cache.
944 ///
945 /// Returns:
946 /// - 0 branch added or already included
947 /// - -1 on error
948 
950 {
951  if (!GetTree()) {
952  if (LoadTree(0)<0) {
953  Error("AddBranchToCache","Could not load a tree");
954  return -1;
955  }
956  }
957  if (GetTree()) {
958  if (GetTree() != this) {
959  Int_t res = GetTree()->AddBranchToCache(b, subbranches);
960  if (res<0) {
961  Error("AddBranchToCache", "Error adding branch");
962  }
963  return res;
964  }
965  } else {
966  Error("AddBranchToCache", "No tree is available. Branch was not added to the cache");
967  return -1;
968  }
969 
970  TFile *f = GetCurrentFile();
971  if (!f) {
972  Error("AddBranchToCache", "No file is available. Branch was not added to the cache");
973  return -1;
974  }
975  TTreeCache *tc = GetReadCache(f,kTRUE);
976  if (!tc) {
977  Error("AddBranchToCache", "No cache is available, branch not added");
978  return -1;
979  }
980  return tc->AddBranch(b,subbranches);
981 }
982 
983 ////////////////////////////////////////////////////////////////////////////////
984 /// Remove the branch with name 'bname' from the Tree cache.
985 /// If bname="*" all branches are removed from the cache.
986 /// if subbranches is true all the branches of the subbranches are
987 /// also removed from the cache.
988 ///
989 /// Returns:
990 /// - 0 branch dropped or not in cache
991 /// - -1 on error
992 
993 Int_t TTree::DropBranchFromCache(const char*bname, Bool_t subbranches)
994 {
995  if (!GetTree()) {
996  if (LoadTree(0)<0) {
997  Error("DropBranchFromCache","Could not load a tree");
998  return -1;
999  }
1000  }
1001  if (GetTree()) {
1002  if (GetTree() != this) {
1003  return GetTree()->DropBranchFromCache(bname, subbranches);
1004  }
1005  } else {
1006  Error("DropBranchFromCache", "No tree is available. Branch was not dropped from the cache");
1007  return -1;
1008  }
1009 
1010  TFile *f = GetCurrentFile();
1011  if (!f) {
1012  Error("DropBranchFromCache", "No file is available. Branch was not dropped from the cache");
1013  return -1;
1014  }
1015  TTreeCache *tc = GetReadCache(f,kTRUE);
1016  if (!tc) {
1017  Error("DropBranchFromCache", "No cache is available, branch not dropped");
1018  return -1;
1019  }
1020  return tc->DropBranch(bname,subbranches);
1021 }
1022 
1023 ////////////////////////////////////////////////////////////////////////////////
1024 /// Remove the branch b from the Tree cache.
1025 /// if subbranches is true all the branches of the subbranches are
1026 /// also removed from the cache.
1027 ///
1028 /// Returns:
1029 /// - 0 branch dropped or not in cache
1030 /// - -1 on error
1031 
1034  if (!GetTree()) {
1035  if (LoadTree(0)<0) {
1036  Error("DropBranchFromCache","Could not load a tree");
1037  return -1;
1038  }
1039  }
1040  if (GetTree()) {
1041  if (GetTree() != this) {
1042  Int_t res = GetTree()->DropBranchFromCache(b, subbranches);
1043  if (res<0) {
1044  Error("DropBranchFromCache", "Error dropping branch");
1045  }
1046  return res;
1047  }
1048  } else {
1049  Error("DropBranchFromCache", "No tree is available. Branch was not dropped from the cache");
1050  return -1;
1051  }
1052 
1053  TFile *f = GetCurrentFile();
1054  if (!f) {
1055  Error("DropBranchFromCache", "No file is available. Branch was not dropped from the cache");
1056  return -1;
1057  }
1058  TTreeCache *tc = GetReadCache(f,kTRUE);
1059  if (!tc) {
1060  Error("DropBranchFromCache", "No cache is available, branch not dropped");
1061  return -1;
1062  }
1063  return tc->DropBranch(b,subbranches);
1064 }
1065 
1066 ////////////////////////////////////////////////////////////////////////////////
1067 /// Add a cloned tree to our list of trees to be notified whenever we change
1068 /// our branch addresses or when we are deleted.
1069 
1070 void TTree::AddClone(TTree* clone)
1072  if (!fClones) {
1073  fClones = new TList();
1074  fClones->SetOwner(false);
1075  // So that the clones are automatically removed from the list when
1076  // they are deleted.
1077  gROOT->GetListOfCleanups()->Add(fClones);
1078  }
1079  if (!fClones->FindObject(clone)) {
1080  fClones->Add(clone);
1081  }
1082 }
1083 
1084 ////////////////////////////////////////////////////////////////////////////////
1085 /// Add a TFriendElement to the list of friends.
1086 ///
1087 /// This function:
1088 /// - opens a file if filename is specified
1089 /// - reads a Tree with name treename from the file (current directory)
1090 /// - adds the Tree to the list of friends
1091 /// see other AddFriend functions
1092 ///
1093 /// A TFriendElement TF describes a TTree object TF in a file.
1094 /// When a TFriendElement TF is added to the the list of friends of an
1095 /// existing TTree T, any variable from TF can be referenced in a query
1096 /// to T.
1097 ///
1098 /// A tree keeps a list of friends. In the context of a tree (or a chain),
1099 /// friendship means unrestricted access to the friends data. In this way
1100 /// it is much like adding another branch to the tree without taking the risk
1101 /// of damaging it. To add a friend to the list, you can use the TTree::AddFriend
1102 /// method. The tree in the diagram below has two friends (friend_tree1 and
1103 /// friend_tree2) and now has access to the variables a,b,c,i,j,k,l and m.
1104 ///
1105 /// \image html ttree_friend1.png
1106 ///
1107 /// The AddFriend method has two parameters, the first is the tree name and the
1108 /// second is the name of the ROOT file where the friend tree is saved.
1109 /// AddFriend automatically opens the friend file. If no file name is given,
1110 /// the tree called ft1 is assumed to be in the same file as the original tree.
1111 ///
1112 /// tree.AddFriend("ft1","friendfile1.root");
1113 /// If the friend tree has the same name as the original tree, you can give it
1114 /// an alias in the context of the friendship:
1115 ///
1116 /// tree.AddFriend("tree1 = tree","friendfile1.root");
1117 /// Once the tree has friends, we can use TTree::Draw as if the friend's
1118 /// variables were in the original tree. To specify which tree to use in
1119 /// the Draw method, use the syntax:
1120 /// ~~~ {.cpp}
1121 /// <treeName>.<branchname>.<varname>
1122 /// ~~~
1123 /// If the variablename is enough to uniquely identify the variable, you can
1124 /// leave out the tree and/or branch name.
1125 /// For example, these commands generate a 3-d scatter plot of variable "var"
1126 /// in the TTree tree versus variable v1 in TTree ft1 versus variable v2 in
1127 /// TTree ft2.
1128 /// ~~~ {.cpp}
1129 /// tree.AddFriend("ft1","friendfile1.root");
1130 /// tree.AddFriend("ft2","friendfile2.root");
1131 /// tree.Draw("var:ft1.v1:ft2.v2");
1132 /// ~~~
1133 /// \image html ttree_friend2.png
1134 ///
1135 /// The picture illustrates the access of the tree and its friends with a
1136 /// Draw command.
1137 /// When AddFriend is called, the ROOT file is automatically opened and the
1138 /// friend tree (ft1) is read into memory. The new friend (ft1) is added to
1139 /// the list of friends of tree.
1140 /// The number of entries in the friend must be equal or greater to the number
1141 /// of entries of the original tree. If the friend tree has fewer entries a
1142 /// warning is given and the missing entries are not included in the histogram.
1143 /// To retrieve the list of friends from a tree use TTree::GetListOfFriends.
1144 /// When the tree is written to file (TTree::Write), the friends list is saved
1145 /// with it. And when the tree is retrieved, the trees on the friends list are
1146 /// also retrieved and the friendship restored.
1147 /// When a tree is deleted, the elements of the friend list are also deleted.
1148 /// It is possible to declare a friend tree that has the same internal
1149 /// structure (same branches and leaves) as the original tree, and compare the
1150 /// same values by specifying the tree.
1151 /// ~~~ {.cpp}
1152 /// tree.Draw("var:ft1.var:ft2.var")
1153 /// ~~~
1154 
1155 TFriendElement* TTree::AddFriend(const char* treename, const char* filename)
1157  if (!fFriends) {
1158  fFriends = new TList();
1159  }
1160  TFriendElement* fe = new TFriendElement(this, treename, filename);
1161 
1162  fFriends->Add(fe);
1163  TTree* t = fe->GetTree();
1164  if (t) {
1165  if (!t->GetTreeIndex() && (t->GetEntries() < fEntries)) {
1166  Warning("AddFriend", "FriendElement %s in file %s has less entries %lld than its parent Tree: %lld", treename, filename, t->GetEntries(), fEntries);
1167  }
1168  } else {
1169  Warning("AddFriend", "Cannot add FriendElement %s in file %s", treename, filename);
1170  }
1171  return fe;
1172 }
1173 
1174 ////////////////////////////////////////////////////////////////////////////////
1175 /// Add a TFriendElement to the list of friends.
1176 ///
1177 /// The TFile is managed by the user (e.g. the user must delete the file).
1178 /// For complete description see AddFriend(const char *, const char *).
1179 /// This function:
1180 /// - reads a Tree with name treename from the file
1181 /// - adds the Tree to the list of friends
1182 
1183 TFriendElement* TTree::AddFriend(const char* treename, TFile* file)
1185  if (!fFriends) {
1186  fFriends = new TList();
1187  }
1188  TFriendElement *fe = new TFriendElement(this, treename, file);
1189  R__ASSERT(fe);
1190  fFriends->Add(fe);
1191  TTree *t = fe->GetTree();
1192  if (t) {
1193  if (!t->GetTreeIndex() && (t->GetEntries() < fEntries)) {
1194  Warning("AddFriend", "FriendElement %s in file %s has less entries %lld than its parent tree: %lld", treename, file->GetName(), t->GetEntries(), fEntries);
1195  }
1196  } else {
1197  Warning("AddFriend", "unknown tree '%s' in file '%s'", treename, file->GetName());
1198  }
1199  return fe;
1200 }
1201 
1202 ////////////////////////////////////////////////////////////////////////////////
1203 /// Add a TFriendElement to the list of friends.
1204 ///
1205 /// The TTree is managed by the user (e.g., the user must delete the file).
1206 /// For a complete description see AddFriend(const char *, const char *).
1207 
1208 TFriendElement* TTree::AddFriend(TTree* tree, const char* alias, Bool_t warn)
1210  if (!tree) {
1211  return 0;
1212  }
1213  if (!fFriends) {
1214  fFriends = new TList();
1215  }
1216  TFriendElement* fe = new TFriendElement(this, tree, alias);
1217  R__ASSERT(fe); // this assert is for historical reasons. Don't remove it unless you understand all the consequences.
1218  fFriends->Add(fe);
1219  TTree* t = fe->GetTree();
1220  if (warn && (t->GetEntries() < fEntries)) {
1221  Warning("AddFriend", "FriendElement '%s' in file '%s' has less entries %lld than its parent tree: %lld",
1222  tree->GetName(), fe->GetFile() ? fe->GetFile()->GetName() : "(memory resident)", t->GetEntries(), fEntries);
1223  }
1224  return fe;
1225 }
1226 
1227 ////////////////////////////////////////////////////////////////////////////////
1228 /// AutoSave tree header every fAutoSave bytes.
1229 ///
1230 /// When large Trees are produced, it is safe to activate the AutoSave
1231 /// procedure. Some branches may have buffers holding many entries.
1232 /// If fAutoSave is negative, AutoSave is automatically called by
1233 /// TTree::Fill when the number of bytes generated since the previous
1234 /// AutoSave is greater than -fAutoSave bytes.
1235 /// If fAutoSave is positive, AutoSave is automatically called by
1236 /// TTree::Fill every N entries.
1237 /// This function may also be invoked by the user.
1238 /// Each AutoSave generates a new key on the file.
1239 /// Once the key with the tree header has been written, the previous cycle
1240 /// (if any) is deleted.
1241 ///
1242 /// Note that calling TTree::AutoSave too frequently (or similarly calling
1243 /// TTree::SetAutoSave with a small value) is an expensive operation.
1244 /// You should make tests for your own application to find a compromise
1245 /// between speed and the quantity of information you may loose in case of
1246 /// a job crash.
1247 ///
1248 /// In case your program crashes before closing the file holding this tree,
1249 /// the file will be automatically recovered when you will connect the file
1250 /// in UPDATE mode.
1251 /// The Tree will be recovered at the status corresponding to the last AutoSave.
1252 ///
1253 /// if option contains "SaveSelf", gDirectory->SaveSelf() is called.
1254 /// This allows another process to analyze the Tree while the Tree is being filled.
1255 ///
1256 /// if option contains "FlushBaskets", TTree::FlushBaskets is called and all
1257 /// the current basket are closed-out and written to disk individually.
1258 ///
1259 /// By default the previous header is deleted after having written the new header.
1260 /// if option contains "Overwrite", the previous Tree header is deleted
1261 /// before written the new header. This option is slightly faster, but
1262 /// the default option is safer in case of a problem (disk quota exceeded)
1263 /// when writing the new header.
1264 ///
1265 /// The function returns the number of bytes written to the file.
1266 /// if the number of bytes is null, an error has occurred while writing
1267 /// the header to the file.
1268 ///
1269 /// ## How to write a Tree in one process and view it from another process
1270 ///
1271 /// The following two scripts illustrate how to do this.
1272 /// The script treew.C is executed by process1, treer.C by process2
1273 ///
1274 /// script treew.C:
1275 /// ~~~ {.cpp}
1276 /// void treew() {
1277 /// TFile f("test.root","recreate");
1278 /// TNtuple *ntuple = new TNtuple("ntuple","Demo","px:py:pz:random:i");
1279 /// Float_t px, py, pz;
1280 /// for ( Int_t i=0; i<10000000; i++) {
1281 /// gRandom->Rannor(px,py);
1282 /// pz = px*px + py*py;
1283 /// Float_t random = gRandom->Rndm(1);
1284 /// ntuple->Fill(px,py,pz,random,i);
1285 /// if (i%1000 == 1) ntuple->AutoSave("SaveSelf");
1286 /// }
1287 /// }
1288 /// ~~~
1289 /// script treer.C:
1290 /// ~~~ {.cpp}
1291 /// void treer() {
1292 /// TFile f("test.root");
1293 /// TTree *ntuple = (TTree*)f.Get("ntuple");
1294 /// TCanvas c1;
1295 /// Int_t first = 0;
1296 /// while(1) {
1297 /// if (first == 0) ntuple->Draw("px>>hpx", "","",10000000,first);
1298 /// else ntuple->Draw("px>>+hpx","","",10000000,first);
1299 /// first = (Int_t)ntuple->GetEntries();
1300 /// c1.Update();
1301 /// gSystem->Sleep(1000); //sleep 1 second
1302 /// ntuple->Refresh();
1303 /// }
1304 /// }
1305 /// ~~~
1306 
1309  if (!fDirectory || fDirectory == gROOT || !fDirectory->IsWritable()) return 0;
1310  if (gDebug > 0) {
1311  printf("AutoSave Tree:%s after %lld bytes written\n",GetName(),fTotBytes);
1312  }
1313  TString opt = option;
1314  opt.ToLower();
1315 
1316  if (opt.Contains("flushbaskets")) {
1317  if (gDebug > 0) printf("AutoSave: calling FlushBaskets \n");
1318  FlushBaskets();
1319  }
1320 
1322 
1324  Long64_t nbytes;
1325  if (opt.Contains("overwrite")) {
1326  nbytes = fDirectory->WriteTObject(this,"","overwrite");
1327  } else {
1328  nbytes = fDirectory->WriteTObject(this); //nbytes will be 0 if Write failed (disk space exceeded)
1329  if (nbytes && key) {
1330  key->Delete();
1331  delete key;
1332  }
1333  }
1334  // save StreamerInfo
1335  TFile *file = fDirectory->GetFile();
1336  if (file) file->WriteStreamerInfo();
1337 
1338  if (opt.Contains("saveself")) {
1339  fDirectory->SaveSelf();
1340  //the following line is required in case GetUserInfo contains a user class
1341  //for which the StreamerInfo must be written. One could probably be a bit faster (Rene)
1342  if (file) file->WriteHeader();
1343  }
1344 
1345  return nbytes;
1346 }
1347 
1348 namespace {
1349  // This error message is repeated several times in the code. We write it once.
1350  const char* writeStlWithoutProxyMsg = "The class requested (%s) for the branch \"%s\""
1351  " is an instance of an stl collection and does not have a compiled CollectionProxy."
1352  " Please generate the dictionary for this collection (%s) to avoid to write corrupted data.";
1353 }
1354 
1355 ////////////////////////////////////////////////////////////////////////////////
1356 /// Same as TTree::Branch() with added check that addobj matches className.
1357 ///
1358 /// See TTree::Branch() for other details.
1359 ///
1360 
1361 TBranch* TTree::BranchImp(const char* branchname, const char* classname, TClass* ptrClass, void* addobj, Int_t bufsize, Int_t splitlevel)
1363  TClass* claim = TClass::GetClass(classname);
1364  if (!ptrClass) {
1365  if (claim && claim->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(claim->GetCollectionProxy())) {
1366  Error("Branch", writeStlWithoutProxyMsg,
1367  claim->GetName(), branchname, claim->GetName());
1368  return 0;
1369  }
1370  return Branch(branchname, classname, (void*) addobj, bufsize, splitlevel);
1371  }
1372  TClass* actualClass = 0;
1373  void** addr = (void**) addobj;
1374  if (addr) {
1375  actualClass = ptrClass->GetActualClass(*addr);
1376  }
1377  if (ptrClass && claim) {
1378  if (!(claim->InheritsFrom(ptrClass) || ptrClass->InheritsFrom(claim))) {
1379  // Note we currently do not warn in case of splicing or over-expectation).
1380  if (claim->IsLoaded() && ptrClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), ptrClass->GetTypeInfo()->name() ) == 0) {
1381  // The type is the same according to the C++ type_info, we must be in the case of
1382  // a template of Double32_t. This is actually a correct case.
1383  } else {
1384  Error("Branch", "The class requested (%s) for \"%s\" is different from the type of the pointer passed (%s)",
1385  claim->GetName(), branchname, ptrClass->GetName());
1386  }
1387  } else if (actualClass && (claim != actualClass) && !actualClass->InheritsFrom(claim)) {
1388  if (claim->IsLoaded() && actualClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), actualClass->GetTypeInfo()->name() ) == 0) {
1389  // The type is the same according to the C++ type_info, we must be in the case of
1390  // a template of Double32_t. This is actually a correct case.
1391  } else {
1392  Error("Branch", "The actual class (%s) of the object provided for the definition of the branch \"%s\" does not inherit from %s",
1393  actualClass->GetName(), branchname, claim->GetName());
1394  }
1395  }
1396  }
1397  if (claim && claim->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(claim->GetCollectionProxy())) {
1398  Error("Branch", writeStlWithoutProxyMsg,
1399  claim->GetName(), branchname, claim->GetName());
1400  return 0;
1401  }
1402  return Branch(branchname, classname, (void*) addobj, bufsize, splitlevel);
1403 }
1404 
1405 ////////////////////////////////////////////////////////////////////////////////
1406 /// Same as TTree::Branch but automatic detection of the class name.
1407 /// See TTree::Branch for other details.
1408 
1409 TBranch* TTree::BranchImp(const char* branchname, TClass* ptrClass, void* addobj, Int_t bufsize, Int_t splitlevel)
1411  if (!ptrClass) {
1412  Error("Branch", "The pointer specified for %s is not of a class known to ROOT", branchname);
1413  return 0;
1414  }
1415  TClass* actualClass = 0;
1416  void** addr = (void**) addobj;
1417  if (addr && *addr) {
1418  actualClass = ptrClass->GetActualClass(*addr);
1419  if (!actualClass) {
1420  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",
1421  branchname, ptrClass->GetName());
1422  actualClass = ptrClass;
1423  } else if ((ptrClass != actualClass) && !actualClass->InheritsFrom(ptrClass)) {
1424  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());
1425  return 0;
1426  }
1427  } else {
1428  actualClass = ptrClass;
1429  }
1430  if (actualClass && actualClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(actualClass->GetCollectionProxy())) {
1431  Error("Branch", writeStlWithoutProxyMsg,
1432  actualClass->GetName(), branchname, actualClass->GetName());
1433  return 0;
1434  }
1435  return Branch(branchname, actualClass->GetName(), (void*) addobj, bufsize, splitlevel);
1436 }
1437 
1438 ////////////////////////////////////////////////////////////////////////////////
1439 /// Same as TTree::Branch but automatic detection of the class name.
1440 /// See TTree::Branch for other details.
1441 
1442 TBranch* TTree::BranchImpRef(const char* branchname, const char *classname, TClass* ptrClass, void *addobj, Int_t bufsize, Int_t splitlevel)
1444  TClass* claim = TClass::GetClass(classname);
1445  if (!ptrClass) {
1446  if (claim && claim->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(claim->GetCollectionProxy())) {
1447  Error("Branch", writeStlWithoutProxyMsg,
1448  claim->GetName(), branchname, claim->GetName());
1449  return 0;
1450  } else if (claim == 0) {
1451  Error("Branch", "The pointer specified for %s is not of a class known to ROOT and %s is not a known class", branchname, classname);
1452  return 0;
1453  }
1454  ptrClass = claim;
1455  }
1456  TClass* actualClass = 0;
1457  if (!addobj) {
1458  Error("Branch", "Reference interface requires a valid object (for branch: %s)!", branchname);
1459  return 0;
1460  }
1461  actualClass = ptrClass->GetActualClass(addobj);
1462  if (ptrClass && claim) {
1463  if (!(claim->InheritsFrom(ptrClass) || ptrClass->InheritsFrom(claim))) {
1464  // Note we currently do not warn in case of splicing or over-expectation).
1465  if (claim->IsLoaded() && ptrClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), ptrClass->GetTypeInfo()->name() ) == 0) {
1466  // The type is the same according to the C++ type_info, we must be in the case of
1467  // a template of Double32_t. This is actually a correct case.
1468  } else {
1469  Error("Branch", "The class requested (%s) for \"%s\" is different from the type of the object passed (%s)",
1470  claim->GetName(), branchname, ptrClass->GetName());
1471  }
1472  } else if (actualClass && (claim != actualClass) && !actualClass->InheritsFrom(claim)) {
1473  if (claim->IsLoaded() && actualClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), actualClass->GetTypeInfo()->name() ) == 0) {
1474  // The type is the same according to the C++ type_info, we must be in the case of
1475  // a template of Double32_t. This is actually a correct case.
1476  } else {
1477  Error("Branch", "The actual class (%s) of the object provided for the definition of the branch \"%s\" does not inherit from %s",
1478  actualClass->GetName(), branchname, claim->GetName());
1479  }
1480  }
1481  }
1482  if (!actualClass) {
1483  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",
1484  branchname, ptrClass->GetName());
1485  actualClass = ptrClass;
1486  } else if ((ptrClass != actualClass) && !actualClass->InheritsFrom(ptrClass)) {
1487  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());
1488  return 0;
1489  }
1490  if (actualClass && actualClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(actualClass->GetCollectionProxy())) {
1491  Error("Branch", writeStlWithoutProxyMsg,
1492  actualClass->GetName(), branchname, actualClass->GetName());
1493  return 0;
1494  }
1495  return BronchExec(branchname, actualClass->GetName(), (void*) addobj, kFALSE, bufsize, splitlevel);
1496 }
1497 
1498 ////////////////////////////////////////////////////////////////////////////////
1499 /// Same as TTree::Branch but automatic detection of the class name.
1500 /// See TTree::Branch for other details.
1501 
1502 TBranch* TTree::BranchImpRef(const char* branchname, TClass* ptrClass, EDataType datatype, void* addobj, Int_t bufsize, Int_t splitlevel)
1504  if (!ptrClass) {
1505  if (datatype == kOther_t || datatype == kNoType_t) {
1506  Error("Branch", "The pointer specified for %s is not of a class or type known to ROOT", branchname);
1507  } else {
1508  TString varname; varname.Form("%s/%c",branchname,DataTypeToChar(datatype));
1509  return Branch(branchname,addobj,varname.Data(),bufsize);
1510  }
1511  return 0;
1512  }
1513  TClass* actualClass = 0;
1514  if (!addobj) {
1515  Error("Branch", "Reference interface requires a valid object (for branch: %s)!", branchname);
1516  return 0;
1517  }
1518  actualClass = ptrClass->GetActualClass(addobj);
1519  if (!actualClass) {
1520  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",
1521  branchname, ptrClass->GetName());
1522  actualClass = ptrClass;
1523  } else if ((ptrClass != actualClass) && !actualClass->InheritsFrom(ptrClass)) {
1524  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());
1525  return 0;
1526  }
1527  if (actualClass && actualClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(actualClass->GetCollectionProxy())) {
1528  Error("Branch", writeStlWithoutProxyMsg,
1529  actualClass->GetName(), branchname, actualClass->GetName());
1530  return 0;
1531  }
1532  return BronchExec(branchname, actualClass->GetName(), (void*) addobj, kFALSE, bufsize, splitlevel);
1533 }
1534 
1535 ////////////////////////////////////////////////////////////////////////////////
1536 /// Deprecated function. Use next function instead.
1537 
1538 Int_t TTree::Branch(TList* li, Int_t bufsize /* = 32000 */ , Int_t splitlevel /* = 99 */)
1540  return Branch((TCollection*) li, bufsize, splitlevel);
1541 }
1542 
1543 ////////////////////////////////////////////////////////////////////////////////
1544 /// Create one branch for each element in the collection.
1545 ///
1546 /// Each entry in the collection becomes a top level branch if the
1547 /// corresponding class is not a collection. If it is a collection, the entry
1548 /// in the collection becomes in turn top level branches, etc.
1549 /// The splitlevel is decreased by 1 every time a new collection is found.
1550 /// For example if list is a TObjArray*
1551 /// - if splitlevel = 1, one top level branch is created for each element
1552 /// of the TObjArray.
1553 /// - if splitlevel = 2, one top level branch is created for each array element.
1554 /// if, in turn, one of the array elements is a TCollection, one top level
1555 /// branch will be created for each element of this collection.
1556 ///
1557 /// In case a collection element is a TClonesArray, the special Tree constructor
1558 /// for TClonesArray is called.
1559 /// The collection itself cannot be a TClonesArray.
1560 ///
1561 /// The function returns the total number of branches created.
1562 ///
1563 /// If name is given, all branch names will be prefixed with name_.
1564 ///
1565 /// IMPORTANT NOTE1: This function should not be called with splitlevel < 1.
1566 ///
1567 /// IMPORTANT NOTE2: The branches created by this function will have names
1568 /// corresponding to the collection or object names. It is important
1569 /// to give names to collections to avoid misleading branch names or
1570 /// identical branch names. By default collections have a name equal to
1571 /// the corresponding class name, e.g. the default name for a TList is "TList".
1572 ///
1573 /// And in general in any cases two or more master branches contain subbranches
1574 /// with identical names, one must add a "." (dot) character at the end
1575 /// of the master branch name. This will force the name of the subbranch
1576 /// to be master.subbranch instead of simply subbranch.
1577 /// This situation happens when the top level object (say event)
1578 /// has two or more members referencing the same class.
1579 /// For example, if a Tree has two branches B1 and B2 corresponding
1580 /// to objects of the same class MyClass, one can do:
1581 /// ~~~ {.cpp}
1582 /// tree.Branch("B1.","MyClass",&b1,8000,1);
1583 /// tree.Branch("B2.","MyClass",&b2,8000,1);
1584 /// ~~~
1585 /// if MyClass has 3 members a,b,c, the two instructions above will generate
1586 /// subbranches called B1.a, B1.b ,B1.c, B2.a, B2.b, B2.c
1587 ///
1588 /// Example:
1589 /// ~~~ {.cpp}
1590 /// {
1591 /// TTree T("T","test list");
1592 /// TList *list = new TList();
1593 ///
1594 /// TObjArray *a1 = new TObjArray();
1595 /// a1->SetName("a1");
1596 /// list->Add(a1);
1597 /// TH1F *ha1a = new TH1F("ha1a","ha1",100,0,1);
1598 /// TH1F *ha1b = new TH1F("ha1b","ha1",100,0,1);
1599 /// a1->Add(ha1a);
1600 /// a1->Add(ha1b);
1601 /// TObjArray *b1 = new TObjArray();
1602 /// b1->SetName("b1");
1603 /// list->Add(b1);
1604 /// TH1F *hb1a = new TH1F("hb1a","hb1",100,0,1);
1605 /// TH1F *hb1b = new TH1F("hb1b","hb1",100,0,1);
1606 /// b1->Add(hb1a);
1607 /// b1->Add(hb1b);
1608 ///
1609 /// TObjArray *a2 = new TObjArray();
1610 /// a2->SetName("a2");
1611 /// list->Add(a2);
1612 /// TH1S *ha2a = new TH1S("ha2a","ha2",100,0,1);
1613 /// TH1S *ha2b = new TH1S("ha2b","ha2",100,0,1);
1614 /// a2->Add(ha2a);
1615 /// a2->Add(ha2b);
1616 ///
1617 /// T.Branch(list,16000,2);
1618 /// T.Print();
1619 /// }
1620 /// ~~~
1621 
1622 Int_t TTree::Branch(TCollection* li, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */, const char* name /* = "" */)
1624 
1625  if (!li) {
1626  return 0;
1627  }
1628  TObject* obj = 0;
1629  Int_t nbranches = GetListOfBranches()->GetEntries();
1630  if (li->InheritsFrom(TClonesArray::Class())) {
1631  Error("Branch", "Cannot call this constructor for a TClonesArray");
1632  return 0;
1633  }
1634  Int_t nch = strlen(name);
1635  TString branchname;
1636  TIter next(li);
1637  while ((obj = next())) {
1638  if ((splitlevel > 1) && obj->InheritsFrom(TCollection::Class()) && !obj->InheritsFrom(TClonesArray::Class())) {
1639  TCollection* col = (TCollection*) obj;
1640  if (nch) {
1641  branchname.Form("%s_%s_", name, col->GetName());
1642  } else {
1643  branchname.Form("%s_", col->GetName());
1644  }
1645  Branch(col, bufsize, splitlevel - 1, branchname);
1646  } else {
1647  if (nch && (name[nch-1] == '_')) {
1648  branchname.Form("%s%s", name, obj->GetName());
1649  } else {
1650  if (nch) {
1651  branchname.Form("%s_%s", name, obj->GetName());
1652  } else {
1653  branchname.Form("%s", obj->GetName());
1654  }
1655  }
1656  if (splitlevel > 99) {
1657  branchname += ".";
1658  }
1659  Bronch(branchname, obj->ClassName(), li->GetObjectRef(obj), bufsize, splitlevel - 1);
1660  }
1661  }
1662  return GetListOfBranches()->GetEntries() - nbranches;
1663 }
1664 
1665 ////////////////////////////////////////////////////////////////////////////////
1666 /// Create one branch for each element in the folder.
1667 /// Returns the total number of branches created.
1668 
1669 Int_t TTree::Branch(const char* foldername, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */)
1671  TObject* ob = gROOT->FindObjectAny(foldername);
1672  if (!ob) {
1673  return 0;
1674  }
1675  if (ob->IsA() != TFolder::Class()) {
1676  return 0;
1677  }
1678  Int_t nbranches = GetListOfBranches()->GetEntries();
1679  TFolder* folder = (TFolder*) ob;
1680  TIter next(folder->GetListOfFolders());
1681  TObject* obj = 0;
1682  char* curname = new char[1000];
1683  char occur[20];
1684  while ((obj = next())) {
1685  snprintf(curname,1000, "%s/%s", foldername, obj->GetName());
1686  if (obj->IsA() == TFolder::Class()) {
1687  Branch(curname, bufsize, splitlevel - 1);
1688  } else {
1689  void* add = (void*) folder->GetListOfFolders()->GetObjectRef(obj);
1690  for (Int_t i = 0; i < 1000; ++i) {
1691  if (curname[i] == 0) {
1692  break;
1693  }
1694  if (curname[i] == '/') {
1695  curname[i] = '.';
1696  }
1697  }
1698  Int_t noccur = folder->Occurence(obj);
1699  if (noccur > 0) {
1700  snprintf(occur,20, "_%d", noccur);
1701  strlcat(curname, occur,1000);
1702  }
1703  TBranchElement* br = (TBranchElement*) Bronch(curname, obj->ClassName(), add, bufsize, splitlevel - 1);
1704  if (br) br->SetBranchFolder();
1705  }
1706  }
1707  delete[] curname;
1708  return GetListOfBranches()->GetEntries() - nbranches;
1709 }
1710 
1711 ////////////////////////////////////////////////////////////////////////////////
1712 /// Create a new TTree Branch.
1713 ///
1714 /// This Branch constructor is provided to support non-objects in
1715 /// a Tree. The variables described in leaflist may be simple
1716 /// variables or structures. // See the two following
1717 /// constructors for writing objects in a Tree.
1718 ///
1719 /// By default the branch buffers are stored in the same file as the Tree.
1720 /// use TBranch::SetFile to specify a different file
1721 ///
1722 /// * address is the address of the first item of a structure.
1723 /// * leaflist is the concatenation of all the variable names and types
1724 /// separated by a colon character :
1725 /// The variable name and the variable type are separated by a slash (/).
1726 /// The variable type may be 0,1 or 2 characters. If no type is given,
1727 /// the type of the variable is assumed to be the same as the previous
1728 /// variable. If the first variable does not have a type, it is assumed
1729 /// of type F by default. The list of currently supported types is given below:
1730 /// - C : a character string terminated by the 0 character
1731 /// - B : an 8 bit signed integer (Char_t)
1732 /// - b : an 8 bit unsigned integer (UChar_t)
1733 /// - S : a 16 bit signed integer (Short_t)
1734 /// - s : a 16 bit unsigned integer (UShort_t)
1735 /// - I : a 32 bit signed integer (Int_t)
1736 /// - i : a 32 bit unsigned integer (UInt_t)
1737 /// - F : a 32 bit floating point (Float_t)
1738 /// - D : a 64 bit floating point (Double_t)
1739 /// - L : a 64 bit signed integer (Long64_t)
1740 /// - l : a 64 bit unsigned integer (ULong64_t)
1741 /// - O : [the letter 'o', not a zero] a boolean (Bool_t)
1742 ///
1743 /// Arrays of values are supported with the following syntax:
1744 /// - If leaf name has the form var[nelem], where nelem is alphanumeric, then
1745 /// if nelem is a leaf name, it is used as the variable size of the array,
1746 /// otherwise return 0.
1747 /// - If leaf name has the form var[nelem], where nelem is a non-negative integer, then
1748 /// it is used as the fixed size of the array.
1749 /// - If leaf name has the form of a multi-dimensional array (e.g. var[nelem][nelem2])
1750 /// where nelem and nelem2 are non-negative integer) then
1751 /// it is used as a 2 dimensional array of fixed size.
1752 ///
1753 /// Any of other form is not supported.
1754 ///
1755 /// Note that the TTree will assume that all the item are contiguous in memory.
1756 /// On some platform, this is not always true of the member of a struct or a class,
1757 /// due to padding and alignment. Sorting your data member in order of decreasing
1758 /// sizeof usually leads to their being contiguous in memory.
1759 ///
1760 /// * bufsize is the buffer size in bytes for this branch
1761 /// The default value is 32000 bytes and should be ok for most cases.
1762 /// You can specify a larger value (e.g. 256000) if your Tree is not split
1763 /// and each entry is large (Megabytes)
1764 /// A small value for bufsize is optimum if you intend to access
1765 /// the entries in the Tree randomly and your Tree is in split mode.
1766 
1767 TBranch* TTree::Branch(const char* name, void* address, const char* leaflist, Int_t bufsize /* = 32000 */)
1769  TBranch* branch = new TBranch(this, name, address, leaflist, bufsize);
1770  if (branch->IsZombie()) {
1771  delete branch;
1772  branch = 0;
1773  return 0;
1774  }
1775  fBranches.Add(branch);
1776  return branch;
1777 }
1778 
1779 ////////////////////////////////////////////////////////////////////////////////
1780 /// Create a new branch with the object of class classname at address addobj.
1781 ///
1782 /// WARNING:
1783 ///
1784 /// Starting with Root version 3.01, the Branch function uses the new style
1785 /// branches (TBranchElement). To get the old behaviour, you can:
1786 /// - call BranchOld or
1787 /// - call TTree::SetBranchStyle(0)
1788 ///
1789 /// Note that with the new style, classname does not need to derive from TObject.
1790 /// It must derived from TObject if the branch style has been set to 0 (old)
1791 ///
1792 /// Note: See the comments in TBranchElement::SetAddress() for a more
1793 /// detailed discussion of the meaning of the addobj parameter in
1794 /// the case of new-style branches.
1795 ///
1796 /// Use splitlevel < 0 instead of splitlevel=0 when the class
1797 /// has a custom Streamer
1798 ///
1799 /// Note: if the split level is set to the default (99), TTree::Branch will
1800 /// not issue a warning if the class can not be split.
1801 
1802 TBranch* TTree::Branch(const char* name, const char* classname, void* addobj, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */)
1804  if (fgBranchStyle == 1) {
1805  return Bronch(name, classname, addobj, bufsize, splitlevel);
1806  } else {
1807  if (splitlevel < 0) {
1808  splitlevel = 0;
1809  }
1810  return BranchOld(name, classname, addobj, bufsize, splitlevel);
1811  }
1812 }
1813 
1814 ////////////////////////////////////////////////////////////////////////////////
1815 /// Create a new TTree BranchObject.
1816 ///
1817 /// Build a TBranchObject for an object of class classname.
1818 /// addobj is the address of a pointer to an object of class classname.
1819 /// IMPORTANT: classname must derive from TObject.
1820 /// The class dictionary must be available (ClassDef in class header).
1821 ///
1822 /// This option requires access to the library where the corresponding class
1823 /// is defined. Accessing one single data member in the object implies
1824 /// reading the full object.
1825 /// See the next Branch constructor for a more efficient storage
1826 /// in case the entry consists of arrays of identical objects.
1827 ///
1828 /// By default the branch buffers are stored in the same file as the Tree.
1829 /// use TBranch::SetFile to specify a different file
1830 ///
1831 /// IMPORTANT NOTE about branch names:
1832 ///
1833 /// In case two or more master branches contain subbranches with
1834 /// identical names, one must add a "." (dot) character at the end
1835 /// of the master branch name. This will force the name of the subbranch
1836 /// to be master.subbranch instead of simply subbranch.
1837 /// This situation happens when the top level object (say event)
1838 /// has two or more members referencing the same class.
1839 /// For example, if a Tree has two branches B1 and B2 corresponding
1840 /// to objects of the same class MyClass, one can do:
1841 /// ~~~ {.cpp}
1842 /// tree.Branch("B1.","MyClass",&b1,8000,1);
1843 /// tree.Branch("B2.","MyClass",&b2,8000,1);
1844 /// ~~~
1845 /// if MyClass has 3 members a,b,c, the two instructions above will generate
1846 /// subbranches called B1.a, B1.b ,B1.c, B2.a, B2.b, B2.c
1847 ///
1848 /// bufsize is the buffer size in bytes for this branch
1849 /// The default value is 32000 bytes and should be ok for most cases.
1850 /// You can specify a larger value (e.g. 256000) if your Tree is not split
1851 /// and each entry is large (Megabytes)
1852 /// A small value for bufsize is optimum if you intend to access
1853 /// the entries in the Tree randomly and your Tree is in split mode.
1854 
1855 TBranch* TTree::BranchOld(const char* name, const char* classname, void* addobj, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 1 */)
1857  TClass* cl = TClass::GetClass(classname);
1858  if (!cl) {
1859  Error("BranchOld", "Cannot find class: '%s'", classname);
1860  return 0;
1861  }
1862  if (!cl->IsTObject()) {
1863  if (fgBranchStyle == 0) {
1864  Fatal("BranchOld", "The requested class ('%s') does not inherit from TObject.\n"
1865  "\tfgBranchStyle is set to zero requesting by default to use BranchOld.\n"
1866  "\tIf this is intentional use Bronch instead of Branch or BranchOld.", classname);
1867  } else {
1868  Fatal("BranchOld", "The requested class ('%s') does not inherit from TObject.\n"
1869  "\tYou can not use BranchOld to store objects of this type.",classname);
1870  }
1871  return 0;
1872  }
1873  TBranch* branch = new TBranchObject(this, name, classname, addobj, bufsize, splitlevel);
1874  fBranches.Add(branch);
1875  if (!splitlevel) {
1876  return branch;
1877  }
1878  // We are going to fully split the class now.
1879  TObjArray* blist = branch->GetListOfBranches();
1880  const char* rdname = 0;
1881  const char* dname = 0;
1882  TString branchname;
1883  char** apointer = (char**) addobj;
1884  TObject* obj = (TObject*) *apointer;
1885  Bool_t delobj = kFALSE;
1886  if (!obj) {
1887  obj = (TObject*) cl->New();
1888  delobj = kTRUE;
1889  }
1890  // Build the StreamerInfo if first time for the class.
1891  BuildStreamerInfo(cl, obj);
1892  // Loop on all public data members of the class and its base classes.
1893  Int_t lenName = strlen(name);
1894  Int_t isDot = 0;
1895  if (name[lenName-1] == '.') {
1896  isDot = 1;
1897  }
1898  TBranch* branch1 = 0;
1899  TRealData* rd = 0;
1900  TRealData* rdi = 0;
1901  TIter nexti(cl->GetListOfRealData());
1902  TIter next(cl->GetListOfRealData());
1903  // Note: This loop results in a full split because the
1904  // real data list includes all data members of
1905  // data members.
1906  while ((rd = (TRealData*) next())) {
1907  if (rd->TestBit(TRealData::kTransient)) continue;
1908 
1909  // Loop over all data members creating branches for each one.
1910  TDataMember* dm = rd->GetDataMember();
1911  if (!dm->IsPersistent()) {
1912  // Do not process members with an "!" as the first character in the comment field.
1913  continue;
1914  }
1915  if (rd->IsObject()) {
1916  // We skip data members of class type.
1917  // But we do build their real data, their
1918  // streamer info, and write their streamer
1919  // info to the current directory's file.
1920  // Oh yes, and we also do this for all of
1921  // their base classes.
1922  TClass* clm = TClass::GetClass(dm->GetFullTypeName());
1923  if (clm) {
1924  BuildStreamerInfo(clm, (char*) obj + rd->GetThisOffset());
1925  }
1926  continue;
1927  }
1928  rdname = rd->GetName();
1929  dname = dm->GetName();
1930  if (cl->CanIgnoreTObjectStreamer()) {
1931  // Skip the TObject base class data members.
1932  // FIXME: This prevents a user from ever
1933  // using these names themself!
1934  if (!strcmp(dname, "fBits")) {
1935  continue;
1936  }
1937  if (!strcmp(dname, "fUniqueID")) {
1938  continue;
1939  }
1940  }
1941  TDataType* dtype = dm->GetDataType();
1942  Int_t code = 0;
1943  if (dtype) {
1944  code = dm->GetDataType()->GetType();
1945  }
1946  // Encode branch name. Use real data member name
1947  branchname = rdname;
1948  if (isDot) {
1949  if (dm->IsaPointer()) {
1950  // FIXME: This is wrong! The asterisk is not usually in the front!
1951  branchname.Form("%s%s", name, &rdname[1]);
1952  } else {
1953  branchname.Form("%s%s", name, &rdname[0]);
1954  }
1955  }
1956  // FIXME: Change this to a string stream.
1957  TString leaflist;
1958  Int_t offset = rd->GetThisOffset();
1959  char* pointer = ((char*) obj) + offset;
1960  if (dm->IsaPointer()) {
1961  // We have a pointer to an object or a pointer to an array of basic types.
1962  TClass* clobj = 0;
1963  if (!dm->IsBasic()) {
1964  clobj = TClass::GetClass(dm->GetTypeName());
1965  }
1966  if (clobj && clobj->InheritsFrom(TClonesArray::Class())) {
1967  // We have a pointer to a clones array.
1968  char* cpointer = (char*) pointer;
1969  char** ppointer = (char**) cpointer;
1970  TClonesArray* li = (TClonesArray*) *ppointer;
1971  if (splitlevel != 2) {
1972  if (isDot) {
1973  branch1 = new TBranchClones(branch,branchname, pointer, bufsize);
1974  } else {
1975  // FIXME: This is wrong! The asterisk is not usually in the front!
1976  branch1 = new TBranchClones(branch,&branchname.Data()[1], pointer, bufsize);
1977  }
1978  blist->Add(branch1);
1979  } else {
1980  if (isDot) {
1981  branch1 = new TBranchObject(branch, branchname, li->ClassName(), pointer, bufsize);
1982  } else {
1983  // FIXME: This is wrong! The asterisk is not usually in the front!
1984  branch1 = new TBranchObject(branch, &branchname.Data()[1], li->ClassName(), pointer, bufsize);
1985  }
1986  blist->Add(branch1);
1987  }
1988  } else if (clobj) {
1989  // We have a pointer to an object.
1990  //
1991  // It must be a TObject object.
1992  if (!clobj->IsTObject()) {
1993  continue;
1994  }
1995  branch1 = new TBranchObject(branch, dname, clobj->GetName(), pointer, bufsize, 0);
1996  if (isDot) {
1997  branch1->SetName(branchname);
1998  } else {
1999  // FIXME: This is wrong! The asterisk is not usually in the front!
2000  // Do not use the first character (*).
2001  branch1->SetName(&branchname.Data()[1]);
2002  }
2003  blist->Add(branch1);
2004  } else {
2005  // We have a pointer to an array of basic types.
2006  //
2007  // Check the comments in the text of the code for an index specification.
2008  const char* index = dm->GetArrayIndex();
2009  if (index[0]) {
2010  // We are a pointer to a varying length array of basic types.
2011  //check that index is a valid data member name
2012  //if member is part of an object (e.g. fA and index=fN)
2013  //index must be changed from fN to fA.fN
2014  TString aindex (rd->GetName());
2015  Ssiz_t rdot = aindex.Last('.');
2016  if (rdot>=0) {
2017  aindex.Remove(rdot+1);
2018  aindex.Append(index);
2019  }
2020  nexti.Reset();
2021  while ((rdi = (TRealData*) nexti())) {
2022  if (rdi->TestBit(TRealData::kTransient)) continue;
2023 
2024  if (!strcmp(rdi->GetName(), index)) {
2025  break;
2026  }
2027  if (!strcmp(rdi->GetName(), aindex)) {
2028  index = rdi->GetName();
2029  break;
2030  }
2031  }
2032 
2033  char vcode = DataTypeToChar((EDataType)code);
2034  // Note that we differentiate between strings and
2035  // char array by the fact that there is NO specified
2036  // size for a string (see next if (code == 1)
2037 
2038  if (vcode) {
2039  leaflist.Form("%s[%s]/%c", &rdname[0], index, vcode);
2040  } else {
2041  Error("BranchOld", "Cannot create branch for rdname: %s code: %d", branchname.Data(), code);
2042  leaflist = "";
2043  }
2044  } else {
2045  // We are possibly a character string.
2046  if (code == 1) {
2047  // We are a character string.
2048  leaflist.Form("%s/%s", dname, "C");
2049  } else {
2050  // Invalid array specification.
2051  // FIXME: We need an error message here.
2052  continue;
2053  }
2054  }
2055  // There are '*' in both the branchname and leaflist, remove them.
2056  TString bname( branchname );
2057  bname.ReplaceAll("*","");
2058  leaflist.ReplaceAll("*","");
2059  // Add the branch to the tree and indicate that the address
2060  // is that of a pointer to be dereferenced before using.
2061  branch1 = new TBranch(branch, bname, *((void**) pointer), leaflist, bufsize);
2062  TLeaf* leaf = (TLeaf*) branch1->GetListOfLeaves()->At(0);
2064  leaf->SetAddress((void**) pointer);
2065  blist->Add(branch1);
2066  }
2067  } else if (dm->IsBasic()) {
2068  // We have a basic type.
2069 
2070  char vcode = DataTypeToChar((EDataType)code);
2071  if (vcode) {
2072  leaflist.Form("%s/%c", rdname, vcode);
2073  } else {
2074  Error("BranchOld", "Cannot create branch for rdname: %s code: %d", branchname.Data(), code);
2075  leaflist = "";
2076  }
2077  branch1 = new TBranch(branch, branchname, pointer, leaflist, bufsize);
2078  branch1->SetTitle(rdname);
2079  blist->Add(branch1);
2080  } else {
2081  // We have a class type.
2082  // Note: This cannot happen due to the rd->IsObject() test above.
2083  // FIXME: Put an error message here just in case.
2084  }
2085  if (branch1) {
2086  branch1->SetOffset(offset);
2087  } else {
2088  Warning("BranchOld", "Cannot process member: '%s'", rdname);
2089  }
2090  }
2091  if (delobj) {
2092  delete obj;
2093  obj = 0;
2094  }
2095  return branch;
2096 }
2097 
2098 ////////////////////////////////////////////////////////////////////////////////
2099 /// Build the optional branch supporting the TRefTable.
2100 /// This branch will keep all the information to find the branches
2101 /// containing referenced objects.
2102 ///
2103 /// At each Tree::Fill, the branch numbers containing the
2104 /// referenced objects are saved to the TBranchRef basket.
2105 /// When the Tree header is saved (via TTree::Write), the branch
2106 /// is saved keeping the information with the pointers to the branches
2107 /// having referenced objects.
2108 
2111  if (!fBranchRef) {
2112  fBranchRef = new TBranchRef(this);
2113  }
2114  return fBranchRef;
2115 }
2116 
2117 ////////////////////////////////////////////////////////////////////////////////
2118 /// Create a new TTree BranchElement.
2119 ///
2120 /// ## WARNING about this new function
2121 ///
2122 /// This function is designed to replace the internal
2123 /// implementation of the old TTree::Branch (whose implementation
2124 /// has been moved to BranchOld).
2125 ///
2126 /// NOTE: The 'Bronch' method supports only one possible calls
2127 /// signature (where the object type has to be specified
2128 /// explicitly and the address must be the address of a pointer).
2129 /// For more flexibility use 'Branch'. Use Bronch only in (rare)
2130 /// cases (likely to be legacy cases) where both the new and old
2131 /// implementation of Branch needs to be used at the same time.
2132 ///
2133 /// This function is far more powerful than the old Branch
2134 /// function. It supports the full C++, including STL and has
2135 /// the same behaviour in split or non-split mode. classname does
2136 /// not have to derive from TObject. The function is based on
2137 /// the new TStreamerInfo.
2138 ///
2139 /// Build a TBranchElement for an object of class classname.
2140 ///
2141 /// addr is the address of a pointer to an object of class
2142 /// classname. The class dictionary must be available (ClassDef
2143 /// in class header).
2144 ///
2145 /// Note: See the comments in TBranchElement::SetAddress() for a more
2146 /// detailed discussion of the meaning of the addr parameter.
2147 ///
2148 /// This option requires access to the library where the
2149 /// corresponding class is defined. Accessing one single data
2150 /// member in the object implies reading the full object.
2151 ///
2152 /// By default the branch buffers are stored in the same file as the Tree.
2153 /// use TBranch::SetFile to specify a different file
2154 ///
2155 /// IMPORTANT NOTE about branch names:
2156 ///
2157 /// In case two or more master branches contain subbranches with
2158 /// identical names, one must add a "." (dot) character at the end
2159 /// of the master branch name. This will force the name of the subbranch
2160 /// to be master.subbranch instead of simply subbranch.
2161 /// This situation happens when the top level object (say event)
2162 /// has two or more members referencing the same class.
2163 /// For example, if a Tree has two branches B1 and B2 corresponding
2164 /// to objects of the same class MyClass, one can do:
2165 /// ~~~ {.cpp}
2166 /// tree.Branch("B1.","MyClass",&b1,8000,1);
2167 /// tree.Branch("B2.","MyClass",&b2,8000,1);
2168 /// ~~~
2169 /// if MyClass has 3 members a,b,c, the two instructions above will generate
2170 /// subbranches called B1.a, B1.b ,B1.c, B2.a, B2.b, B2.c
2171 ///
2172 /// bufsize is the buffer size in bytes for this branch
2173 /// The default value is 32000 bytes and should be ok for most cases.
2174 /// You can specify a larger value (e.g. 256000) if your Tree is not split
2175 /// and each entry is large (Megabytes)
2176 /// A small value for bufsize is optimum if you intend to access
2177 /// the entries in the Tree randomly and your Tree is in split mode.
2178 ///
2179 /// Use splitlevel < 0 instead of splitlevel=0 when the class
2180 /// has a custom Streamer
2181 ///
2182 /// Note: if the split level is set to the default (99), TTree::Branch will
2183 /// not issue a warning if the class can not be split.
2184 
2185 TBranch* TTree::Bronch(const char* name, const char* classname, void* addr, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */)
2187  return BronchExec(name, classname, addr, kTRUE, bufsize, splitlevel);
2188 }
2189 
2190 ////////////////////////////////////////////////////////////////////////////////
2191 /// Helper function implementing TTree::Bronch and TTree::Branch(const char *name, T &obj);
2192 
2193 TBranch* TTree::BronchExec(const char* name, const char* classname, void* addr, Bool_t isptrptr, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */)
2195  TClass* cl = TClass::GetClass(classname);
2196  if (!cl) {
2197  Error("Bronch", "Cannot find class:%s", classname);
2198  return 0;
2199  }
2200 
2201  //if splitlevel <= 0 and class has a custom Streamer, we must create
2202  //a TBranchObject. We cannot assume that TClass::ReadBuffer is consistent
2203  //with the custom Streamer. The penalty is that one cannot process
2204  //this Tree without the class library containing the class.
2205 
2206  char* objptr = 0;
2207  if (!isptrptr) {
2208  objptr = (char*)addr;
2209  } else if (addr) {
2210  objptr = *((char**) addr);
2211  }
2212 
2213  if (cl == TClonesArray::Class()) {
2214  TClonesArray* clones = (TClonesArray*) objptr;
2215  if (!clones) {
2216  Error("Bronch", "Pointer to TClonesArray is null");
2217  return 0;
2218  }
2219  if (!clones->GetClass()) {
2220  Error("Bronch", "TClonesArray with no class defined in branch: %s", name);
2221  return 0;
2222  }
2223  if (!clones->GetClass()->HasDataMemberInfo()) {
2224  Error("Bronch", "TClonesArray with no dictionary defined in branch: %s", name);
2225  return 0;
2226  }
2227  bool hasCustomStreamer = clones->GetClass()->TestBit(TClass::kHasCustomStreamerMember);
2228  if (splitlevel > 0) {
2229  if (hasCustomStreamer)
2230  Warning("Bronch", "Using split mode on a class: %s with a custom Streamer", clones->GetClass()->GetName());
2231  } else {
2232  if (hasCustomStreamer) clones->BypassStreamer(kFALSE);
2233  TBranchObject *branch = new TBranchObject(this,name,classname,addr,bufsize,0,/*compress=*/ -1,isptrptr);
2234  fBranches.Add(branch);
2235  return branch;
2236  }
2237  }
2238 
2239  if (cl->GetCollectionProxy()) {
2240  TVirtualCollectionProxy* collProxy = cl->GetCollectionProxy();
2241  //if (!collProxy) {
2242  // Error("Bronch", "%s is missing its CollectionProxy (for branch %s)", classname, name);
2243  //}
2244  TClass* inklass = collProxy->GetValueClass();
2245  if (!inklass && (collProxy->GetType() == 0)) {
2246  Error("Bronch", "%s with no class defined in branch: %s", classname, name);
2247  return 0;
2248  }
2249  if ((splitlevel > 0) && inklass && (inklass->GetCollectionProxy() == 0)) {
2250  ROOT::ESTLType stl = cl->GetCollectionType();
2251  if ((stl != ROOT::kSTLmap) && (stl != ROOT::kSTLmultimap)) {
2252  if (!inklass->HasDataMemberInfo()) {
2253  Error("Bronch", "Container with no dictionary defined in branch: %s", name);
2254  return 0;
2255  }
2256  if (inklass->TestBit(TClass::kHasCustomStreamerMember)) {
2257  Warning("Bronch", "Using split mode on a class: %s with a custom Streamer", inklass->GetName());
2258  }
2259  }
2260  }
2261  //-------------------------------------------------------------------------
2262  // If the splitting switch is enabled, the split level is big enough and
2263  // the collection contains pointers we can split it
2264  //////////////////////////////////////////////////////////////////////////
2265 
2266  TBranch *branch;
2267  if( splitlevel > kSplitCollectionOfPointers && collProxy->HasPointers() )
2268  branch = new TBranchSTL( this, name, collProxy, bufsize, splitlevel );
2269  else
2270  branch = new TBranchElement(this, name, collProxy, bufsize, splitlevel);
2271  fBranches.Add(branch);
2272  if (isptrptr) {
2273  branch->SetAddress(addr);
2274  } else {
2275  branch->SetObject(addr);
2276  }
2277  return branch;
2278  }
2279 
2280  Bool_t hasCustomStreamer = kFALSE;
2281  if (!cl->HasDataMemberInfo() && !cl->GetCollectionProxy()) {
2282  Error("Bronch", "Cannot find dictionary for class: %s", classname);
2283  return 0;
2284  }
2285 
2287  // Not an STL container and the linkdef file had a "-" after the class name.
2288  hasCustomStreamer = kTRUE;
2289  }
2290 
2291  if (splitlevel < 0 || ((splitlevel == 0) && hasCustomStreamer && cl->IsTObject())) {
2292  TBranchObject* branch = new TBranchObject(this, name, classname, addr, bufsize, 0, /*compress=*/ -1, isptrptr);
2293  fBranches.Add(branch);
2294  return branch;
2295  }
2296 
2297  if (cl == TClonesArray::Class()) {
2298  // Special case of TClonesArray.
2299  // No dummy object is created.
2300  // The streamer info is not rebuilt unoptimized.
2301  // No dummy top-level branch is created.
2302  // No splitting is attempted.
2303  TBranchElement* branch = new TBranchElement(this, name, (TClonesArray*) objptr, bufsize, splitlevel%kSplitCollectionOfPointers);
2304  fBranches.Add(branch);
2305  if (isptrptr) {
2306  branch->SetAddress(addr);
2307  } else {
2308  branch->SetObject(addr);
2309  }
2310  return branch;
2311  }
2312 
2313  //
2314  // If we are not given an object to use as an i/o buffer
2315  // then create a temporary one which we will delete just
2316  // before returning.
2317  //
2318 
2319  Bool_t delobj = kFALSE;
2320 
2321  if (!objptr) {
2322  objptr = (char*) cl->New();
2323  delobj = kTRUE;
2324  }
2325 
2326  //
2327  // Avoid splitting unsplittable classes.
2328  //
2329 
2330  if ((splitlevel > 0) && !cl->CanSplit()) {
2331  if (splitlevel != 99) {
2332  Warning("Bronch", "%s cannot be split, resetting splitlevel to 0", cl->GetName());
2333  }
2334  splitlevel = 0;
2335  }
2336 
2337  //
2338  // Make sure the streamer info is built and fetch it.
2339  //
2340  // If we are splitting, then make sure the streamer info
2341  // is built unoptimized (data members are not combined).
2342  //
2343 
2344  TStreamerInfo* sinfo = BuildStreamerInfo(cl, objptr, splitlevel==0);
2345  if (!sinfo) {
2346  Error("Bronch", "Cannot build the StreamerInfo for class: %s", cl->GetName());
2347  return 0;
2348  }
2349 
2350  //
2351  // Do we have a final dot in our name?
2352  //
2353 
2354  // Note: The branch constructor which takes a folder as input
2355  // creates top-level branch names with dots in them to
2356  // indicate the folder hierarchy.
2357  char* dot = (char*) strchr(name, '.');
2358  Int_t nch = strlen(name);
2359  Bool_t dotlast = kFALSE;
2360  if (nch && (name[nch-1] == '.')) {
2361  dotlast = kTRUE;
2362  }
2363 
2364  //
2365  // Create a dummy top level branch object.
2366  //
2367 
2368  Int_t id = -1;
2369  if (splitlevel > 0) {
2370  id = -2;
2371  }
2372  TBranchElement* branch = new TBranchElement(this, name, sinfo, id, objptr, bufsize, splitlevel);
2373  fBranches.Add(branch);
2374 
2375  //
2376  // Do splitting, if requested.
2377  //
2378 
2379  if (splitlevel%kSplitCollectionOfPointers > 0) {
2380  // Loop on all public data members of the class and its base classes and create branches for each one.
2381  TObjArray* blist = branch->GetListOfBranches();
2382  TIter next(sinfo->GetElements());
2383  TStreamerElement* element = 0;
2384  TString bname;
2385  for (id = 0; (element = (TStreamerElement*) next()); ++id) {
2386  if (element->IsA() == TStreamerArtificial::Class()) {
2387  continue;
2388  }
2389  if (element->TestBit(TStreamerElement::kRepeat)) {
2390  continue;
2391  }
2392  if (element->TestBit(TStreamerElement::kCache) && !element->TestBit(TStreamerElement::kWrite)) {
2393  continue;
2394  }
2395  char* pointer = (char*) (objptr + element->GetOffset());
2396  // FIXME: This is not good enough, an STL container can be
2397  // a base, and the test will fail.
2398  // See TBranchElement::InitializeOffsets() for the
2399  // correct test.
2400  Bool_t isBase = (element->IsA() == TStreamerBase::Class());
2401  if (isBase) {
2402  TClass* clbase = element->GetClassPointer();
2403  if ((clbase == TObject::Class()) && cl->CanIgnoreTObjectStreamer()) {
2404  // Note: TStreamerInfo::Compile() leaves this element
2405  // out of the optimized info, although it does
2406  // exists in the non-compiled and non-optimized info.
2407  // FIXME: The test that TStreamerInfo::Compile() uses
2408  // is element->GetType() < 0, so that is what
2409  // we should do as well.
2410  continue;
2411  }
2412  if (clbase->GetListOfRealData()->GetSize() == 0) {
2413  // Do not create a branch for empty bases.
2414  continue;
2415  }
2416  }
2417  if (dot) {
2418  if (dotlast) {
2419  bname.Form("%s%s", name, element->GetFullName());
2420  } else {
2421  // FIXME: We are in the case where we have a top-level
2422  // branch name that was created by the branch
2423  // constructor which takes a folder as input.
2424  // The internal dots in the name are in place of
2425  // of the original slashes and represent the
2426  // folder hierarchy.
2427  if (isBase) {
2428  // FIXME: This is very strange, this is the only case where
2429  // we create a branch for a base class that does
2430  // not have the base class name in the branch name.
2431  // FIXME: This is also quite bad since classes with two
2432  // or more base classes end up with sub-branches
2433  // that have the same name.
2434  bname = name;
2435  } else {
2436  bname.Form("%s.%s", name, element->GetFullName());
2437  }
2438  }
2439  } else {
2440  // Note: For a base class element, this results in the branchname
2441  // being the name of the base class.
2442  bname.Form("%s", element->GetFullName());
2443  }
2444 
2445  if( splitlevel > kSplitCollectionOfPointers && element->GetClass() &&
2446  element->GetClass()->GetCollectionProxy() &&
2447  element->GetClass()->GetCollectionProxy()->HasPointers() )
2448  {
2449  TBranchSTL* brSTL = new TBranchSTL( branch, bname, element->GetClass()->GetCollectionProxy(), bufsize, splitlevel-1, sinfo, id );
2450  blist->Add(brSTL);
2451  }
2452  else
2453  {
2454  TBranchElement* bre = new TBranchElement(branch, bname, sinfo, id, pointer, bufsize, splitlevel - 1);
2455  bre->SetParentClass(cl);
2456  blist->Add(bre);
2457  }
2458  }
2459  }
2460 
2461  //
2462  // Setup our offsets into the user's i/o buffer.
2463  //
2464 
2465  if (isptrptr) {
2466  branch->SetAddress(addr);
2467  } else {
2468  branch->SetObject(addr);
2469  }
2470 
2471  if (delobj) {
2472  cl->Destructor(objptr);
2473  objptr = 0;
2474  }
2475 
2476  return branch;
2477 }
2478 
2479 ////////////////////////////////////////////////////////////////////////////////
2480 /// Browse content of the TTree.
2481 
2482 void TTree::Browse(TBrowser* b)
2484  fBranches.Browse(b);
2485  if (fUserInfo) {
2486  if (strcmp("TList",fUserInfo->GetName())==0) {
2487  fUserInfo->SetName("UserInfo");
2488  b->Add(fUserInfo);
2489  fUserInfo->SetName("TList");
2490  } else {
2491  b->Add(fUserInfo);
2492  }
2493  }
2494 }
2495 
2496 ////////////////////////////////////////////////////////////////////////////////
2497 /// Build a Tree Index (default is TTreeIndex).
2498 /// See a description of the parameters and functionality in
2499 /// TTreeIndex::TTreeIndex().
2500 ///
2501 /// The return value is the number of entries in the Index (< 0 indicates failure).
2502 ///
2503 /// A TTreeIndex object pointed by fTreeIndex is created.
2504 /// This object will be automatically deleted by the TTree destructor.
2505 /// See also comments in TTree::SetTreeIndex().
2506 
2507 Int_t TTree::BuildIndex(const char* majorname, const char* minorname /* = "0" */)
2509  fTreeIndex = GetPlayer()->BuildIndex(this, majorname, minorname);
2510  if (fTreeIndex->IsZombie()) {
2511  delete fTreeIndex;
2512  fTreeIndex = 0;
2513  return 0;
2514  }
2515  return fTreeIndex->GetN();
2516 }
2517 
2518 ////////////////////////////////////////////////////////////////////////////////
2519 /// Build StreamerInfo for class cl.
2520 /// pointer is an optional argument that may contain a pointer to an object of cl.
2521 
2522 TStreamerInfo* TTree::BuildStreamerInfo(TClass* cl, void* pointer /* = 0 */, Bool_t canOptimize /* = kTRUE */ )
2524  if (!cl) {
2525  return 0;
2526  }
2527  cl->BuildRealData(pointer);
2529 
2530  // Create StreamerInfo for all base classes.
2531  TBaseClass* base = 0;
2532  TIter nextb(cl->GetListOfBases());
2533  while((base = (TBaseClass*) nextb())) {
2534  if (base->IsSTLContainer()) {
2535  continue;
2536  }
2537  TClass* clm = TClass::GetClass(base->GetName());
2538  BuildStreamerInfo(clm, pointer, canOptimize);
2539  }
2540  if (sinfo && fDirectory) {
2541  sinfo->ForceWriteInfo(fDirectory->GetFile());
2542  }
2543  return sinfo;
2544 }
2545 
2546 ////////////////////////////////////////////////////////////////////////////////
2547 /// Called by TTree::Fill() when file has reached its maximum fgMaxTreeSize.
2548 /// Create a new file. If the original file is named "myfile.root",
2549 /// subsequent files are named "myfile_1.root", "myfile_2.root", etc.
2550 ///
2551 /// Returns a pointer to the new file.
2552 ///
2553 /// Currently, the automatic change of file is restricted
2554 /// to the case where the tree is in the top level directory.
2555 /// The file should not contain sub-directories.
2556 ///
2557 /// Before switching to a new file, the tree header is written
2558 /// to the current file, then the current file is closed.
2559 ///
2560 /// To process the multiple files created by ChangeFile, one must use
2561 /// a TChain.
2562 ///
2563 /// The new file name has a suffix "_N" where N is equal to fFileNumber+1.
2564 /// By default a Root session starts with fFileNumber=0. One can set
2565 /// fFileNumber to a different value via TTree::SetFileNumber.
2566 /// In case a file named "_N" already exists, the function will try
2567 /// a file named "__N", then "___N", etc.
2568 ///
2569 /// fgMaxTreeSize can be set via the static function TTree::SetMaxTreeSize.
2570 /// The default value of fgMaxTreeSize is 100 Gigabytes.
2571 ///
2572 /// If the current file contains other objects like TH1 and TTree,
2573 /// these objects are automatically moved to the new file.
2574 ///
2575 /// IMPORTANT NOTE:
2576 ///
2577 /// Be careful when writing the final Tree header to the file!
2578 ///
2579 /// Don't do:
2580 /// ~~~ {.cpp}
2581 /// TFile *file = new TFile("myfile.root","recreate");
2582 /// TTree *T = new TTree("T","title");
2583 /// T->Fill(); //loop
2584 /// file->Write();
2585 /// file->Close();
2586 ///~~~
2587 /// but do the following:
2588 ///~~~ {.cpp}
2589 /// TFile *file = new TFile("myfile.root","recreate");
2590 /// TTree *T = new TTree("T","title");
2591 /// T->Fill(); //loop
2592 /// file = T->GetCurrentFile(); //to get the pointer to the current file
2593 /// file->Write();
2594 /// file->Close();
2595 /// ~~~
2596 
2599  file->cd();
2600  Write();
2601  Reset();
2602  char* fname = new char[2000];
2603  ++fFileNumber;
2604  char uscore[10];
2605  for (Int_t i = 0; i < 10; ++i) {
2606  uscore[i] = 0;
2607  }
2608  Int_t nus = 0;
2609  // Try to find a suitable file name that does not already exist.
2610  while (nus < 10) {
2611  uscore[nus] = '_';
2612  fname[0] = 0;
2613  strlcpy(fname, file->GetName(),2000);
2614 
2615  if (fFileNumber > 1) {
2616  char* cunder = strrchr(fname, '_');
2617  if (cunder) {
2618  snprintf(cunder,2000-Int_t(cunder-fname), "%s%d", uscore, fFileNumber);
2619  const char* cdot = strrchr(file->GetName(), '.');
2620  if (cdot) {
2621  strlcat(fname, cdot,2000);
2622  }
2623  } else {
2624  char fcount[10];
2625  snprintf(fcount,10, "%s%d", uscore, fFileNumber);
2626  strlcat(fname, fcount,2000);
2627  }
2628  } else {
2629  char* cdot = strrchr(fname, '.');
2630  if (cdot) {
2631  snprintf(cdot,2000-Int_t(fname-cdot), "%s%d", uscore, fFileNumber);
2632  strlcat(fname, strrchr(file->GetName(), '.'),2000);
2633  } else {
2634  char fcount[10];
2635  snprintf(fcount,10, "%s%d", uscore, fFileNumber);
2636  strlcat(fname, fcount,2000);
2637  }
2638  }
2639  if (gSystem->AccessPathName(fname)) {
2640  break;
2641  }
2642  ++nus;
2643  Warning("ChangeFile", "file %s already exist, trying with %d underscores", fname, nus+1);
2644  }
2645  Int_t compress = file->GetCompressionSettings();
2646  TFile* newfile = TFile::Open(fname, "recreate", "chain files", compress);
2647  if (newfile == 0) {
2648  Error("Fill","Failed to open new file %s, continuing as a memory tree.",fname);
2649  } else {
2650  Printf("Fill: Switching to new file: %s", fname);
2651  }
2652  // The current directory may contain histograms and trees.
2653  // These objects must be moved to the new file.
2654  TBranch* branch = 0;
2655  TObject* obj = 0;
2656  while ((obj = file->GetList()->First())) {
2657  file->Remove(obj);
2658  // Histogram: just change the directory.
2659  if (obj->InheritsFrom("TH1")) {
2660  gROOT->ProcessLine(TString::Format("((%s*)0x%lx)->SetDirectory((TDirectory*)0x%lx);", obj->ClassName(), (Long_t) obj, (Long_t) newfile));
2661  continue;
2662  }
2663  // Tree: must save all trees in the old file, reset them.
2664  if (obj->InheritsFrom(TTree::Class())) {
2665  TTree* t = (TTree*) obj;
2666  if (t != this) {
2667  t->AutoSave();
2668  t->Reset();
2669  t->fFileNumber = fFileNumber;
2670  }
2671  t->SetDirectory(newfile);
2672  TIter nextb(t->GetListOfBranches());
2673  while ((branch = (TBranch*)nextb())) {
2674  branch->SetFile(newfile);
2675  }
2676  if (t->GetBranchRef()) {
2677  t->GetBranchRef()->SetFile(newfile);
2678  }
2679  continue;
2680  }
2681  // Not a TH1 or a TTree, move object to new file.
2682  if (newfile) newfile->Append(obj);
2683  file->Remove(obj);
2684  }
2685  delete file;
2686  file = 0;
2687  delete[] fname;
2688  fname = 0;
2689  return newfile;
2690 }
2691 
2692 ////////////////////////////////////////////////////////////////////////////////
2693 /// Check whether or not the address described by the last 3 parameters
2694 /// matches the content of the branch. If a Data Model Evolution conversion
2695 /// is involved, reset the fInfo of the branch.
2696 /// The return values are:
2697 //
2698 /// - kMissingBranch (-5) : Missing branch
2699 /// - kInternalError (-4) : Internal error (could not find the type corresponding to a data type number)
2700 /// - kMissingCompiledCollectionProxy (-3) : Missing compiled collection proxy for a compiled collection
2701 /// - kMismatch (-2) : Non-Class Pointer type given does not match the type expected by the branch
2702 /// - kClassMismatch (-1) : Class Pointer type given does not match the type expected by the branch
2703 /// - kMatch (0) : perfect match
2704 /// - kMatchConversion (1) : match with (I/O) conversion
2705 /// - kMatchConversionCollection (2) : match with (I/O) conversion of the content of a collection
2706 /// - kMakeClass (3) : MakeClass mode so we can not check.
2707 /// - kVoidPtr (4) : void* passed so no check was made.
2708 /// - kNoCheck (5) : Underlying TBranch not yet available so no check was made.
2709 
2710 Int_t TTree::CheckBranchAddressType(TBranch* branch, TClass* ptrClass, EDataType datatype, Bool_t isptr)
2712  if (GetMakeClass()) {
2713  // If we are in MakeClass mode so we do not really use classes.
2714  return kMakeClass;
2715  }
2716 
2717  // Let's determine what we need!
2718  TClass* expectedClass = 0;
2719  EDataType expectedType = kOther_t;
2720  if (0 != branch->GetExpectedType(expectedClass,expectedType) ) {
2721  // Something went wrong, the warning message has already be issued.
2722  return kInternalError;
2723  }
2724  if (expectedClass && datatype == kOther_t && ptrClass == 0) {
2725  if (branch->InheritsFrom( TBranchElement::Class() )) {
2726  TBranchElement* bEl = (TBranchElement*)branch;
2727  bEl->SetTargetClass( expectedClass->GetName() );
2728  }
2729  if (expectedClass && expectedClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(expectedClass->GetCollectionProxy())) {
2730  Error("SetBranchAddress", "Unable to determine the type given for the address for \"%s\". "
2731  "The class expected (%s) refers to an stl collection and do not have a compiled CollectionProxy. "
2732  "Please generate the dictionary for this class (%s)",
2733  branch->GetName(), expectedClass->GetName(), expectedClass->GetName());
2735  }
2736  if (!expectedClass->IsLoaded()) {
2737  // The originally expected class does not have a dictionary, it is then plausible that the pointer being passed is the right type
2738  // (we really don't know). So let's express that.
2739  Error("SetBranchAddress", "Unable to determine the type given for the address for \"%s\". "
2740  "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."
2741  "Please generate the dictionary for this class (%s)",
2742  branch->GetName(), expectedClass->GetName(), expectedClass->GetName());
2743  } else {
2744  Error("SetBranchAddress", "Unable to determine the type given for the address for \"%s\". "
2745  "This is probably due to a missing dictionary, the original data class for this branch is %s.", branch->GetName(), expectedClass->GetName());
2746  }
2747  return kClassMismatch;
2748  }
2749  if (expectedClass && ptrClass && (branch->GetMother() == branch)) {
2750  // Top Level branch
2751  if (!isptr) {
2752  Error("SetBranchAddress", "The address for \"%s\" should be the address of a pointer!", branch->GetName());
2753  }
2754  }
2755  if (expectedType == kFloat16_t) {
2756  expectedType = kFloat_t;
2757  }
2758  if (expectedType == kDouble32_t) {
2759  expectedType = kDouble_t;
2760  }
2761  if (datatype == kFloat16_t) {
2762  datatype = kFloat_t;
2763  }
2764  if (datatype == kDouble32_t) {
2765  datatype = kDouble_t;
2766  }
2767 
2768  /////////////////////////////////////////////////////////////////////////////
2769  // Deal with the class renaming
2770  /////////////////////////////////////////////////////////////////////////////
2771 
2772  if( expectedClass && ptrClass &&
2773  expectedClass != ptrClass &&
2774  branch->InheritsFrom( TBranchElement::Class() ) &&
2775  ptrClass->GetSchemaRules() &&
2776  ptrClass->GetSchemaRules()->HasRuleWithSourceClass( expectedClass->GetName() ) ) {
2777  TBranchElement* bEl = (TBranchElement*)branch;
2778 
2779  if ( ptrClass->GetCollectionProxy() && expectedClass->GetCollectionProxy() ) {
2780  if (gDebug > 7)
2781  Info("SetBranchAddress", "Matching STL collection (at least according to the SchemaRuleSet when "
2782  "reading a %s into a %s",expectedClass->GetName(),ptrClass->GetName());
2783 
2784  bEl->SetTargetClass( ptrClass->GetName() );
2785  return kMatchConversion;
2786 
2787  } else if ( !ptrClass->GetConversionStreamerInfo( expectedClass, bEl->GetClassVersion() ) &&
2788  !ptrClass->FindConversionStreamerInfo( expectedClass, bEl->GetCheckSum() ) ) {
2789  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());
2790 
2791  bEl->SetTargetClass( expectedClass->GetName() );
2792  return kClassMismatch;
2793  }
2794  else {
2795 
2796  bEl->SetTargetClass( ptrClass->GetName() );
2797  return kMatchConversion;
2798  }
2799 
2800  } else if (expectedClass && ptrClass && !expectedClass->InheritsFrom(ptrClass)) {
2801 
2802  if (expectedClass->GetCollectionProxy() && ptrClass->GetCollectionProxy() &&
2803  branch->InheritsFrom( TBranchElement::Class() ) &&
2804  expectedClass->GetCollectionProxy()->GetValueClass() &&
2805  ptrClass->GetCollectionProxy()->GetValueClass() )
2806  {
2807  // In case of collection, we know how to convert them, if we know how to convert their content.
2808  // NOTE: we need to extend this to std::pair ...
2809 
2810  TClass *onfileValueClass = expectedClass->GetCollectionProxy()->GetValueClass();
2811  TClass *inmemValueClass = ptrClass->GetCollectionProxy()->GetValueClass();
2812 
2813  if (inmemValueClass->GetSchemaRules() &&
2814  inmemValueClass->GetSchemaRules()->HasRuleWithSourceClass(onfileValueClass->GetName() ) )
2815  {
2816  TBranchElement* bEl = (TBranchElement*)branch;
2817  bEl->SetTargetClass( ptrClass->GetName() );
2819  }
2820  }
2821 
2822  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());
2823  if (branch->InheritsFrom( TBranchElement::Class() )) {
2824  TBranchElement* bEl = (TBranchElement*)branch;
2825  bEl->SetTargetClass( expectedClass->GetName() );
2826  }
2827  return kClassMismatch;
2828 
2829  } else if ((expectedType != kOther_t) && (datatype != kOther_t) && (expectedType != kNoType_t) && (datatype != kNoType_t) && (expectedType != datatype)) {
2830  if (datatype != kChar_t) {
2831  // For backward compatibility we assume that (char*) was just a cast and/or a generic address
2832  Error("SetBranchAddress", "The pointer type given \"%s\" (%d) does not correspond to the type needed \"%s\" (%d) by the branch: %s",
2833  TDataType::GetTypeName(datatype), datatype, TDataType::GetTypeName(expectedType), expectedType, branch->GetName());
2834  return kMismatch;
2835  }
2836  } else if ((expectedClass && (datatype != kOther_t && datatype != kNoType_t && datatype != kInt_t)) ||
2837  (ptrClass && (expectedType != kOther_t && expectedType != kNoType_t && datatype != kInt_t)) ) {
2838  // Sometime a null pointer can look an int, avoid complaining in that case.
2839  if (expectedClass) {
2840  Error("SetBranchAddress", "The pointer type given \"%s\" (%d) does not correspond to the type needed \"%s\" by the branch: %s",
2841  TDataType::GetTypeName(datatype), datatype, expectedClass->GetName(), branch->GetName());
2842  if (branch->InheritsFrom( TBranchElement::Class() )) {
2843  TBranchElement* bEl = (TBranchElement*)branch;
2844  bEl->SetTargetClass( expectedClass->GetName() );
2845  }
2846  } else {
2847  // 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
2848  // a struct).
2849  bool good = false;
2850  if (ptrClass->IsLoaded()) {
2851  TIter next(ptrClass->GetListOfRealData());
2852  TRealData *rdm;
2853  while ((rdm = (TRealData*)next())) {
2854  if (rdm->GetThisOffset() == 0) {
2855  break;
2856  }
2857  }
2858  } else {
2859  TIter next(ptrClass->GetListOfDataMembers());
2860  TDataMember *dm;
2861  while ((dm = (TDataMember*)next())) {
2862  if (dm->GetOffset() == 0) {
2863  TDataType *dmtype = dm->GetDataType();
2864  if (dmtype) {
2865  EDataType etype = (EDataType)dmtype->GetType();
2866  good = (etype == expectedType);
2867  }
2868  break;
2869  }
2870  }
2871  }
2872  if (!good) {
2873  Error("SetBranchAddress", "The pointer type given \"%s\" does not correspond to the type needed \"%s\" (%d) by the branch: %s",
2874  ptrClass->GetName(), TDataType::GetTypeName(expectedType), expectedType, branch->GetName());
2875  }
2876  }
2877  return kMismatch;
2878  }
2879  if (expectedClass && expectedClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(expectedClass->GetCollectionProxy())) {
2880  Error("SetBranchAddress", writeStlWithoutProxyMsg,
2881  expectedClass->GetName(), branch->GetName(), expectedClass->GetName());
2882  if (branch->InheritsFrom( TBranchElement::Class() )) {
2883  TBranchElement* bEl = (TBranchElement*)branch;
2884  bEl->SetTargetClass( expectedClass->GetName() );
2885  }
2887  }
2888  if (expectedClass && branch->InheritsFrom( TBranchElement::Class() )) {
2889  TBranchElement* bEl = (TBranchElement*)branch;
2890  bEl->SetTargetClass( expectedClass->GetName() );
2891  }
2892  return kMatch;
2893 }
2894 
2895 ////////////////////////////////////////////////////////////////////////////////
2896 /// Create a clone of this tree and copy nentries.
2897 ///
2898 /// By default copy all entries.
2899 /// The compression level of the cloned tree is set to the destination
2900 /// file's compression level.
2901 ///
2902 /// NOTE: Only active branches are copied.
2903 /// NOTE: If the TTree is a TChain, the structure of the first TTree
2904 /// is used for the copy.
2905 ///
2906 /// IMPORTANT: The cloned tree stays connected with this tree until
2907 /// this tree is deleted. In particular, any changes in
2908 /// branch addresses in this tree are forwarded to the
2909 /// clone trees, unless a branch in a clone tree has had
2910 /// its address changed, in which case that change stays in
2911 /// effect. When this tree is deleted, all the addresses of
2912 /// the cloned tree are reset to their default values.
2913 ///
2914 /// If 'option' contains the word 'fast' and nentries is -1, the
2915 /// cloning will be done without unzipping or unstreaming the baskets
2916 /// (i.e., a direct copy of the raw bytes on disk).
2917 ///
2918 /// When 'fast' is specified, 'option' can also contain a sorting
2919 /// order for the baskets in the output file.
2920 ///
2921 /// There are currently 3 supported sorting order:
2922 ///
2923 /// - SortBasketsByOffset (the default)
2924 /// - SortBasketsByBranch
2925 /// - SortBasketsByEntry
2926 ///
2927 /// When using SortBasketsByOffset the baskets are written in the
2928 /// output file in the same order as in the original file (i.e. the
2929 /// baskets are sorted by their offset in the original file; Usually
2930 /// this also means that the baskets are sorted by the index/number of
2931 /// the _last_ entry they contain)
2932 ///
2933 /// When using SortBasketsByBranch all the baskets of each individual
2934 /// branches are stored contiguously. This tends to optimize reading
2935 /// speed when reading a small number (1->5) of branches, since all
2936 /// their baskets will be clustered together instead of being spread
2937 /// across the file. However it might decrease the performance when
2938 /// reading more branches (or the full entry).
2939 ///
2940 /// When using SortBasketsByEntry the baskets with the lowest starting
2941 /// entry are written first. (i.e. the baskets are sorted by the
2942 /// index/number of the first entry they contain). This means that on
2943 /// the file the baskets will be in the order in which they will be
2944 /// needed when reading the whole tree sequentially.
2945 ///
2946 /// For examples of CloneTree, see tutorials:
2947 ///
2948 /// - copytree:
2949 /// A macro to copy a subset of a TTree to a new TTree.
2950 /// The input file has been generated by the program in
2951 /// $ROOTSYS/test/Event with: Event 1000 1 1 1
2952 ///
2953 /// - copytree2:
2954 /// A macro to copy a subset of a TTree to a new TTree.
2955 /// One branch of the new Tree is written to a separate file.
2956 /// The input file has been generated by the program in
2957 /// $ROOTSYS/test/Event with: Event 1000 1 1 1
2958 
2959 TTree* TTree::CloneTree(Long64_t nentries /* = -1 */, Option_t* option /* = "" */)
2961  // Options
2962  Bool_t fastClone = kFALSE;
2963 
2964  TString opt = option;
2965  opt.ToLower();
2966  if (opt.Contains("fast")) {
2967  fastClone = kTRUE;
2968  }
2969 
2970  // If we are a chain, switch to the first tree.
2971  if ((fEntries > 0) && (LoadTree(0) < 0)) {
2972  // FIXME: We need an error message here.
2973  return 0;
2974  }
2975 
2976  // Note: For a tree we get the this pointer, for
2977  // a chain we get the chain's current tree.
2978  TTree* thistree = GetTree();
2979 
2980  // Note: For a chain, the returned clone will be
2981  // a clone of the chain's first tree.
2982  TTree* newtree = (TTree*) thistree->Clone();
2983  if (!newtree) {
2984  return 0;
2985  }
2986 
2987  // The clone should not delete any objects allocated by SetAddress().
2988  TObjArray* branches = newtree->GetListOfBranches();
2989  Int_t nb = branches->GetEntriesFast();
2990  for (Int_t i = 0; i < nb; ++i) {
2991  TBranch* br = (TBranch*) branches->UncheckedAt(i);
2992  if (br->InheritsFrom(TBranchElement::Class())) {
2993  ((TBranchElement*) br)->ResetDeleteObject();
2994  }
2995  }
2996 
2997  // Add the new tree to the list of clones so that
2998  // we can later inform it of changes to branch addresses.
2999  thistree->AddClone(newtree);
3000  if (thistree != this) {
3001  // In case this object is a TChain, add the clone
3002  // also to the TChain's list of clones.
3003  AddClone(newtree);
3004  }
3005 
3006  newtree->Reset();
3007 
3008  TDirectory* ndir = newtree->GetDirectory();
3009  TFile* nfile = 0;
3010  if (ndir) {
3011  nfile = ndir->GetFile();
3012  }
3013  Int_t newcomp = -1;
3014  if (nfile) {
3015  newcomp = nfile->GetCompressionSettings();
3016  }
3017 
3018  //
3019  // Delete non-active branches from the clone.
3020  //
3021  // Note: If we are a chain, this does nothing
3022  // since chains have no leaves.
3023  TObjArray* leaves = newtree->GetListOfLeaves();
3024  Int_t nleaves = leaves->GetEntriesFast();
3025  for (Int_t lndx = 0; lndx < nleaves; ++lndx) {
3026  TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(lndx);
3027  if (!leaf) {
3028  continue;
3029  }
3030  TBranch* branch = leaf->GetBranch();
3031  if (branch && (newcomp > -1)) {
3032  branch->SetCompressionSettings(newcomp);
3033  }
3034  if (!branch || !branch->TestBit(kDoNotProcess)) {
3035  continue;
3036  }
3037  // size might change at each iteration of the loop over the leaves.
3038  nb = branches->GetEntriesFast();
3039  for (Long64_t i = 0; i < nb; ++i) {
3040  TBranch* br = (TBranch*) branches->UncheckedAt(i);
3041  if (br == branch) {
3042  branches->RemoveAt(i);
3043  delete br;
3044  br = 0;
3045  branches->Compress();
3046  break;
3047  }
3048  TObjArray* lb = br->GetListOfBranches();
3049  Int_t nb1 = lb->GetEntriesFast();
3050  for (Int_t j = 0; j < nb1; ++j) {
3051  TBranch* b1 = (TBranch*) lb->UncheckedAt(j);
3052  if (!b1) {
3053  continue;
3054  }
3055  if (b1 == branch) {
3056  lb->RemoveAt(j);
3057  delete b1;
3058  b1 = 0;
3059  lb->Compress();
3060  break;
3061  }
3062  TObjArray* lb1 = b1->GetListOfBranches();
3063  Int_t nb2 = lb1->GetEntriesFast();
3064  for (Int_t k = 0; k < nb2; ++k) {
3065  TBranch* b2 = (TBranch*) lb1->UncheckedAt(k);
3066  if (!b2) {
3067  continue;
3068  }
3069  if (b2 == branch) {
3070  lb1->RemoveAt(k);
3071  delete b2;
3072  b2 = 0;
3073  lb1->Compress();
3074  break;
3075  }
3076  }
3077  }
3078  }
3079  }
3080  leaves->Compress();
3081 
3082  // Copy MakeClass status.
3083  newtree->SetMakeClass(fMakeClass);
3084 
3085  // Copy branch addresses.
3086  CopyAddresses(newtree);
3087 
3088  //
3089  // Copy entries if requested.
3090  //
3091 
3092  if (nentries != 0) {
3093  if (fastClone && (nentries < 0)) {
3094  if ( newtree->CopyEntries( this, -1, option ) < 0 ) {
3095  // There was a problem!
3096  Error("CloneTTree", "TTree has not been cloned\n");
3097  delete newtree;
3098  newtree = 0;
3099  return 0;
3100  }
3101  } else {
3102  newtree->CopyEntries( this, nentries, option );
3103  }
3104  }
3105 
3106  return newtree;
3107 }
3108 
3109 ////////////////////////////////////////////////////////////////////////////////
3110 /// Set branch addresses of passed tree equal to ours.
3111 /// If undo is true, reset the branch address instead of copying them.
3112 /// This insures 'separation' of a cloned tree from its original
3113 
3116  // Copy branch addresses starting from branches.
3117  TObjArray* branches = GetListOfBranches();
3118  Int_t nbranches = branches->GetEntriesFast();
3119  for (Int_t i = 0; i < nbranches; ++i) {
3120  TBranch* branch = (TBranch*) branches->UncheckedAt(i);
3121  if (branch->TestBit(kDoNotProcess)) {
3122  continue;
3123  }
3124  if (undo) {
3125  TBranch* br = tree->GetBranch(branch->GetName());
3126  tree->ResetBranchAddress(br);
3127  } else {
3128  char* addr = branch->GetAddress();
3129  if (!addr) {
3130  if (branch->IsA() == TBranch::Class()) {
3131  // If the branch was created using a leaflist, the branch itself may not have
3132  // an address but the leaf might already.
3133  TLeaf *firstleaf = (TLeaf*)branch->GetListOfLeaves()->At(0);
3134  if (!firstleaf || firstleaf->GetValuePointer()) {
3135  // Either there is no leaf (and thus no point in copying the address)
3136  // or the leaf has an address but we can not copy it via the branche
3137  // this will be copied via the next loop (over the leaf).
3138  continue;
3139  }
3140  }
3141  // Note: This may cause an object to be allocated.
3142  branch->SetAddress(0);
3143  addr = branch->GetAddress();
3144  }
3145  // FIXME: The GetBranch() function is braindead and may
3146  // not find the branch!
3147  TBranch* br = tree->GetBranch(branch->GetName());
3148  if (br) {
3149  br->SetAddress(addr);
3150  // The copy does not own any object allocated by SetAddress().
3151  if (br->InheritsFrom(TBranchElement::Class())) {
3152  ((TBranchElement*) br)->ResetDeleteObject();
3153  }
3154  } else {
3155  Warning("CopyAddresses", "Could not find branch named '%s' in tree named '%s'", branch->GetName(), tree->GetName());
3156  }
3157  }
3158  }
3159 
3160  // Copy branch addresses starting from leaves.
3161  TObjArray* tleaves = tree->GetListOfLeaves();
3162  Int_t ntleaves = tleaves->GetEntriesFast();
3163  for (Int_t i = 0; i < ntleaves; ++i) {
3164  TLeaf* tleaf = (TLeaf*) tleaves->UncheckedAt(i);
3165  TBranch* tbranch = tleaf->GetBranch();
3166  TBranch* branch = GetBranch(tbranch->GetName());
3167  if (!branch) {
3168  continue;
3169  }
3170  TLeaf* leaf = branch->GetLeaf(tleaf->GetName());
3171  if (!leaf) {
3172  continue;
3173  }
3174  if (branch->TestBit(kDoNotProcess)) {
3175  continue;
3176  }
3177  if (undo) {
3178  // Now we know whether the address has been transfered
3179  tree->ResetBranchAddress(tbranch);
3180  } else {
3181  if (!branch->GetAddress() && !leaf->GetValuePointer()) {
3182  // We should attempts to set the address of the branch.
3183  // something like:
3184  //(TBranchElement*)branch->GetMother()->SetAddress(0)
3185  //plus a few more subtilities (see TBranchElement::GetEntry).
3186  //but for now we go the simplest route:
3187  //
3188  // Note: This may result in the allocation of an object.
3189  branch->SetupAddresses();
3190  }
3191  if (branch->GetAddress()) {
3192  tree->SetBranchAddress(branch->GetName(), (void*) branch->GetAddress());
3193  TBranch* br = tree->GetBranch(branch->GetName());
3194  if (br) {
3195  // The copy does not own any object allocated by SetAddress().
3196  // FIXME: We do too much here, br may not be a top-level branch.
3197  if (br->InheritsFrom(TBranchElement::Class())) {
3198  ((TBranchElement*) br)->ResetDeleteObject();
3199  }
3200  } else {
3201  Warning("CopyAddresses", "Could not find branch named '%s' in tree named '%s'", branch->GetName(), tree->GetName());
3202  }
3203  } else {
3204  tleaf->SetAddress(leaf->GetValuePointer());
3205  }
3206  }
3207  }
3208 
3209  if (undo &&
3210  ( tree->IsA()->InheritsFrom("TNtuple") || tree->IsA()->InheritsFrom("TNtupleD") )
3211  ) {
3212  tree->ResetBranchAddresses();
3213  }
3214 }
3215 
3216 namespace {
3217 
3218  enum EOnIndexError { kDrop, kKeep, kBuild };
3220  static Bool_t R__HandleIndex(EOnIndexError onIndexError, TTree *newtree, TTree *oldtree)
3221  {
3222  // Return true if we should continue to handle indices, false otherwise.
3223 
3224  Bool_t withIndex = kTRUE;
3225 
3226  if ( newtree->GetTreeIndex() ) {
3227  if ( oldtree->GetTree()->GetTreeIndex() == 0 ) {
3228  switch (onIndexError) {
3229  case kDrop:
3230  delete newtree->GetTreeIndex();
3231  newtree->SetTreeIndex(0);
3232  withIndex = kFALSE;
3233  break;
3234  case kKeep:
3235  // Nothing to do really.
3236  break;
3237  case kBuild:
3238  // Build the index then copy it
3239  if (oldtree->GetTree()->BuildIndex(newtree->GetTreeIndex()->GetMajorName(), newtree->GetTreeIndex()->GetMinorName())) {
3240  newtree->GetTreeIndex()->Append(oldtree->GetTree()->GetTreeIndex(), kTRUE);
3241  // Clean up
3242  delete oldtree->GetTree()->GetTreeIndex();
3243  oldtree->GetTree()->SetTreeIndex(0);
3244  }
3245  break;
3246  }
3247  } else {
3248  newtree->GetTreeIndex()->Append(oldtree->GetTree()->GetTreeIndex(), kTRUE);
3249  }
3250  } else if ( oldtree->GetTree()->GetTreeIndex() != 0 ) {
3251  // We discover the first index in the middle of the chain.
3252  switch (onIndexError) {
3253  case kDrop:
3254  // Nothing to do really.
3255  break;
3256  case kKeep: {
3257  TVirtualIndex *index = (TVirtualIndex*) oldtree->GetTree()->GetTreeIndex()->Clone();
3258  index->SetTree(newtree);
3259  newtree->SetTreeIndex(index);
3260  break;
3261  }
3262  case kBuild:
3263  if (newtree->GetEntries() == 0) {
3264  // Start an index.
3265  TVirtualIndex *index = (TVirtualIndex*) oldtree->GetTree()->GetTreeIndex()->Clone();
3266  index->SetTree(newtree);
3267  newtree->SetTreeIndex(index);
3268  } else {
3269  // Build the index so far.
3270  if (newtree->BuildIndex(oldtree->GetTree()->GetTreeIndex()->GetMajorName(), oldtree->GetTree()->GetTreeIndex()->GetMinorName())) {
3271  newtree->GetTreeIndex()->Append(oldtree->GetTree()->GetTreeIndex(), kTRUE);
3272  }
3273  }
3274  break;
3275  }
3276  } else if ( onIndexError == kDrop ) {
3277  // There is no index on this or on tree->GetTree(), we know we have to ignore any further
3278  // index
3279  withIndex = kFALSE;
3280  }
3281  return withIndex;
3282  }
3283 }
3284 
3285 ////////////////////////////////////////////////////////////////////////////////
3286 /// Copy nentries from given tree to this tree.
3287 /// This routines assumes that the branches that intended to be copied are
3288 /// already connected. The typical case is that this tree was created using
3289 /// tree->CloneTree(0).
3290 ///
3291 /// By default copy all entries.
3292 ///
3293 /// Returns number of bytes copied to this tree.
3294 ///
3295 /// If 'option' contains the word 'fast' and nentries is -1, the cloning will be
3296 /// done without unzipping or unstreaming the baskets (i.e., a direct copy of the
3297 /// raw bytes on disk).
3298 ///
3299 /// When 'fast' is specified, 'option' can also contains a sorting order for the
3300 /// baskets in the output file.
3301 ///
3302 /// There are currently 3 supported sorting order:
3303 ///
3304 /// - SortBasketsByOffset (the default)
3305 /// - SortBasketsByBranch
3306 /// - SortBasketsByEntry
3307 ///
3308 /// See TTree::CloneTree for a detailed explanation of the semantics of these 3 options.
3309 ///
3310 /// If the tree or any of the underlying tree of the chain has an index, that index and any
3311 /// index in the subsequent underlying TTree objects will be merged.
3312 ///
3313 /// There are currently three 'options' to control this merging:
3314 /// - NoIndex : all the TTreeIndex object are dropped.
3315 /// - DropIndexOnError : if any of the underlying TTree object do no have a TTreeIndex,
3316 /// they are all dropped.
3317 /// - AsIsIndexOnError [default]: In case of missing TTreeIndex, the resulting TTree index has gaps.
3318 /// - BuildIndexOnError : If any of the underlying TTree objects do not have a TTreeIndex,
3319 /// all TTreeIndex are 'ignored' and the missing piece are rebuilt.
3320 
3321 Long64_t TTree::CopyEntries(TTree* tree, Long64_t nentries /* = -1 */, Option_t* option /* = "" */)
3323  if (!tree) {
3324  return 0;
3325  }
3326  // Options
3327  TString opt = option;
3328  opt.ToLower();
3329  Bool_t fastClone = opt.Contains("fast");
3330  Bool_t withIndex = !opt.Contains("noindex");
3331  EOnIndexError onIndexError;
3332  if (opt.Contains("asisindex")) {
3333  onIndexError = kKeep;
3334  } else if (opt.Contains("buildindex")) {
3335  onIndexError = kBuild;
3336  } else if (opt.Contains("dropindex")) {
3337  onIndexError = kDrop;
3338  } else {
3339  onIndexError = kBuild;
3340  }
3341 
3342  Long64_t nbytes = 0;
3343  Long64_t treeEntries = tree->GetEntriesFast();
3344  if (nentries < 0) {
3345  nentries = treeEntries;
3346  } else if (nentries > treeEntries) {
3347  nentries = treeEntries;
3348  }
3349 
3350  if (fastClone && (nentries < 0 || nentries == tree->GetEntriesFast())) {
3351  // Quickly copy the basket without decompression and streaming.
3352  Long64_t totbytes = GetTotBytes();
3353  for (Long64_t i = 0; i < nentries; i += tree->GetTree()->GetEntries()) {
3354  if (tree->LoadTree(i) < 0) {
3355  break;
3356  }
3357  if ( withIndex ) {
3358  withIndex = R__HandleIndex( onIndexError, this, tree );
3359  }
3360  if (this->GetDirectory()) {
3361  TFile* file2 = this->GetDirectory()->GetFile();
3362  if (file2 && (file2->GetEND() > TTree::GetMaxTreeSize())) {
3363  if (this->GetDirectory() == (TDirectory*) file2) {
3364  this->ChangeFile(file2);
3365  }
3366  }
3367  }
3368  TTreeCloner cloner(tree->GetTree(), this, option, TTreeCloner::kNoWarnings);
3369  if (cloner.IsValid()) {
3370  this->SetEntries(this->GetEntries() + tree->GetTree()->GetEntries());
3371  cloner.Exec();
3372  } else {
3373  if (i == 0) {
3374  Warning("CopyEntries","%s",cloner.GetWarning());
3375  // If the first cloning does not work, something is really wrong
3376  // (since apriori the source and target are exactly the same structure!)
3377  return -1;
3378  } else {
3379  if (cloner.NeedConversion()) {
3380  TTree *localtree = tree->GetTree();
3381  Long64_t tentries = localtree->GetEntries();
3382  for (Long64_t ii = 0; ii < tentries; ii++) {
3383  if (localtree->GetEntry(ii) <= 0) {
3384  break;
3385  }
3386  this->Fill();
3387  }
3388  if (this->GetTreeIndex()) {
3389  this->GetTreeIndex()->Append(tree->GetTree()->GetTreeIndex(), kTRUE);
3390  }
3391  } else {
3392  Warning("CopyEntries","%s",cloner.GetWarning());
3393  if (tree->GetDirectory() && tree->GetDirectory()->GetFile()) {
3394  Warning("CopyEntries", "Skipped file %s\n", tree->GetDirectory()->GetFile()->GetName());
3395  } else {
3396  Warning("CopyEntries", "Skipped file number %d\n", tree->GetTreeNumber());
3397  }
3398  }
3399  }
3400  }
3401 
3402  }
3403  if (this->GetTreeIndex()) {
3404  this->GetTreeIndex()->Append(0,kFALSE); // Force the sorting
3405  }
3406  nbytes = GetTotBytes() - totbytes;
3407  } else {
3408  if (nentries < 0) {
3409  nentries = treeEntries;
3410  } else if (nentries > treeEntries) {
3411  nentries = treeEntries;
3412  }
3413  Int_t treenumber = -1;
3414  for (Long64_t i = 0; i < nentries; i++) {
3415  if (tree->LoadTree(i) < 0) {
3416  break;
3417  }
3418  if (treenumber != tree->GetTreeNumber()) {
3419  if ( withIndex ) {
3420  withIndex = R__HandleIndex( onIndexError, this, tree );
3421  }
3422  treenumber = tree->GetTreeNumber();
3423  }
3424  if (tree->GetEntry(i) <= 0) {
3425  break;
3426  }
3427  nbytes += this->Fill();
3428  }
3429  if (this->GetTreeIndex()) {
3430  this->GetTreeIndex()->Append(0,kFALSE); // Force the sorting
3431  }
3432  }
3433  return nbytes;
3434 }
3435 
3436 ////////////////////////////////////////////////////////////////////////////////
3437 /// Copy a tree with selection.
3438 ///
3439 /// IMPORTANT:
3440 ///
3441 /// The returned copied tree stays connected with the original tree
3442 /// until the original tree is deleted. In particular, any changes
3443 /// to the branch addresses in the original tree are also made to
3444 /// the copied tree. Any changes made to the branch addresses of the
3445 /// copied tree are overridden anytime the original tree changes its
3446 /// branch addresses. When the original tree is deleted, all the
3447 /// branch addresses of the copied tree are set to zero.
3448 ///
3449 /// For examples of CopyTree, see the tutorials:
3450 ///
3451 /// - copytree:
3452 /// Example macro to copy a subset of a tree to a new tree.
3453 /// The input file was generated by running the program in
3454 /// $ROOTSYS/test/Event in this way:
3455 /// ~~~ {.cpp}
3456 /// ./Event 1000 1 1 1
3457 /// ~~~
3458 /// - copytree2
3459 /// Example macro to copy a subset of a tree to a new tree.
3460 /// One branch of the new tree is written to a separate file.
3461 /// The input file was generated by running the program in
3462 /// $ROOTSYS/test/Event in this way:
3463 /// ~~~ {.cpp}
3464 /// ./Event 1000 1 1 1
3465 /// ~~~
3466 /// - copytree3
3467 /// Example macro to copy a subset of a tree to a new tree.
3468 /// Only selected entries are copied to the new tree.
3469 /// NOTE that only the active branches are copied.
3470 
3471 TTree* TTree::CopyTree(const char* selection, Option_t* option /* = 0 */, Long64_t nentries /* = TTree::kMaxEntries */, Long64_t firstentry /* = 0 */)
3473  GetPlayer();
3474  if (fPlayer) {
3475  return fPlayer->CopyTree(selection, option, nentries, firstentry);
3476  }
3477  return 0;
3478 }
3479 
3480 ////////////////////////////////////////////////////////////////////////////////
3481 /// Create a basket for this tree and given branch.
3482 
3485  if (!branch) {
3486  return 0;
3487  }
3488  return new TBasket(branch->GetName(), GetName(), branch);
3489 }
3490 
3491 ////////////////////////////////////////////////////////////////////////////////
3492 /// Delete this tree from memory or/and disk.
3493 ///
3494 /// - if option == "all" delete Tree object from memory AND from disk
3495 /// all baskets on disk are deleted. All keys with same name
3496 /// are deleted.
3497 /// - if option =="" only Tree object in memory is deleted.
3498 
3499 void TTree::Delete(Option_t* option /* = "" */)
3501  TFile *file = GetCurrentFile();
3502 
3503  // delete all baskets and header from file
3504  if (file && !strcmp(option,"all")) {
3505  if (!file->IsWritable()) {
3506  Error("Delete","File : %s is not writable, cannot delete Tree:%s", file->GetName(),GetName());
3507  return;
3508  }
3509 
3510  //find key and import Tree header in memory
3511  TKey *key = fDirectory->GetKey(GetName());
3512  if (!key) return;
3513 
3514  TDirectory *dirsav = gDirectory;
3515  file->cd();
3516 
3517  //get list of leaves and loop on all the branches baskets
3519  TLeaf *leaf;
3520  char header[16];
3521  Int_t ntot = 0;
3522  Int_t nbask = 0;
3523  Int_t nbytes,objlen,keylen;
3524  while ((leaf = (TLeaf*)next())) {
3525  TBranch *branch = leaf->GetBranch();
3526  Int_t nbaskets = branch->GetMaxBaskets();
3527  for (Int_t i=0;i<nbaskets;i++) {
3528  Long64_t pos = branch->GetBasketSeek(i);
3529  if (!pos) continue;
3530  TFile *branchFile = branch->GetFile();
3531  if (!branchFile) continue;
3532  branchFile->GetRecordHeader(header,pos,16,nbytes,objlen,keylen);
3533  if (nbytes <= 0) continue;
3534  branchFile->MakeFree(pos,pos+nbytes-1);
3535  ntot += nbytes;
3536  nbask++;
3537  }
3538  }
3539 
3540  // delete Tree header key and all keys with the same name
3541  // A Tree may have been saved many times. Previous cycles are invalid.
3542  while (key) {
3543  ntot += key->GetNbytes();
3544  key->Delete();
3545  delete key;
3546  key = fDirectory->GetKey(GetName());
3547  }
3548  if (dirsav) dirsav->cd();
3549  if (gDebug) printf(" Deleting Tree: %s: %d baskets deleted. Total space freed = %d bytes\n",GetName(),nbask,ntot);
3550  }
3551 
3552  if (fDirectory) {
3553  fDirectory->Remove(this);
3554  //delete the file cache if it points to this Tree
3555  MoveReadCache(file,0);
3556  fDirectory = 0;
3558  }
3559 
3560  // Delete object from CINT symbol table so it can not be used anymore.
3561  gCling->DeleteGlobal(this);
3562 
3563  // Warning: We have intentional invalidated this object while inside a member function!
3564  delete this;
3565 }
3566 
3567  ///////////////////////////////////////////////////////////////////////////////
3568  /// Called by TKey and TObject::Clone to automatically add us to a directory
3569  /// when we are read from a file.
3570 
3573  if (fDirectory == dir) return;
3574  if (fDirectory) {
3575  fDirectory->Remove(this);
3576  // Delete or move the file cache if it points to this Tree
3577  TFile *file = fDirectory->GetFile();
3578  MoveReadCache(file,dir);
3579  }
3580  fDirectory = dir;
3581  TBranch* b = 0;
3583  while((b = (TBranch*) next())) {
3584  b->UpdateFile();
3585  }
3586  if (fBranchRef) {
3588  }
3589  if (fDirectory) fDirectory->Append(this);
3590 }
3591 
3592 ////////////////////////////////////////////////////////////////////////////////
3593 /// Draw expression varexp for specified entries.
3594 /// Returns -1 in case of error or number of selected events in case of success.
3595 ///
3596 /// This function accepts TCut objects as arguments.
3597 /// Useful to use the string operator +
3598 ///
3599 /// Example:
3600 ///
3601 /// ntuple.Draw("x",cut1+cut2+cut3);
3602 
3603 Long64_t TTree::Draw(const char* varexp, const TCut& selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
3605  return TTree::Draw(varexp, selection.GetTitle(), option, nentries, firstentry);
3606 }
3607 
3608 ////////////////////////////////////////////////////////////////////////////////
3609 /// Draw expression varexp for specified entries.
3610 /// Returns -1 in case of error or number of selected events in case of success.
3611 ///
3612 /// varexp is an expression of the general form
3613 /// - "e1" produces a 1-d histogram (TH1F) of expression "e1"
3614 /// - "e1:e2" produces an unbinned 2-d scatter-plot (TGraph) of "e1"
3615 /// on the y-axis versus "e2" on the x-axis
3616 /// - "e1:e2:e3" produces an unbinned 3-d scatter-plot (TPolyMarker3D) of "e1"
3617 /// versus "e2" versus "e3" on the x-, y-, z-axis, respectively.
3618 /// - "e1:e2:e3:e4" produces an unbinned 3-d scatter-plot (TPolyMarker3D) of "e1"
3619 /// versus "e2" versus "e3" and "e4" mapped on the color number.
3620 /// (to create histograms in the 2, 3, and 4 dimensional case, see section "Saving
3621 /// the result of Draw to an histogram")
3622 ///
3623 /// Example:
3624 /// - varexp = x simplest case: draw a 1-Dim distribution of column named x
3625 /// - varexp = sqrt(x) : draw distribution of sqrt(x)
3626 /// - varexp = x*y/z
3627 /// - varexp = y:sqrt(x) 2-Dim distribution of y versus sqrt(x)
3628 /// - varexp = px:py:pz:2.5*E produces a 3-d scatter-plot of px vs py ps pz
3629 /// and the color number of each marker will be 2.5*E.
3630 /// If the color number is negative it is set to 0.
3631 /// If the color number is greater than the current number of colors
3632 /// it is set to the highest color number.The default number of
3633 /// colors is 50. see TStyle::SetPalette for setting a new color palette.
3634 ///
3635 /// Note that the variables e1, e2 or e3 may contain a selection.
3636 /// example, if e1= x*(y<0), the value histogrammed will be x if y<0
3637 /// and will be 0 otherwise.
3638 ///
3639 /// The expressions can use all the operations and build-in functions
3640 /// supported by TFormula (See TFormula::Analyze), including free
3641 /// standing function taking numerical arguments (TMath::Bessel).
3642 /// In addition, you can call member functions taking numerical
3643 /// arguments. For example:
3644 /// ~~~ {.cpp}
3645 /// TMath::BreitWigner(fPx,3,2)
3646 /// event.GetHistogram().GetXaxis().GetXmax()
3647 /// ~~~
3648 /// Note: You can only pass expression that depend on the TTree's data
3649 /// to static functions and you can only call non-static member function
3650 /// with 'fixed' parameters.
3651 ///
3652 /// selection is an expression with a combination of the columns.
3653 /// In a selection all the C++ operators are authorized.
3654 /// The value corresponding to the selection expression is used as a weight
3655 /// to fill the histogram.
3656 /// If the expression includes only boolean operations, the result
3657 /// is 0 or 1. If the result is 0, the histogram is not filled.
3658 /// In general, the expression may be of the form:
3659 /// ~~~ {.cpp}
3660 /// value*(boolean expression)
3661 /// ~~~
3662 /// if boolean expression is true, the histogram is filled with
3663 /// a `weight = value`.
3664 ///
3665 /// Examples:
3666 /// - selection1 = "x<y && sqrt(z)>3.2"
3667 /// - selection2 = "(x+y)*(sqrt(z)>3.2)"
3668 ///
3669 /// - selection1 returns a weight = 0 or 1
3670 /// - selection2 returns a weight = x+y if sqrt(z)>3.2
3671 /// returns a weight = 0 otherwise.
3672 ///
3673 /// option is the drawing option.
3674 /// - See TH1::Draw for the list of all drawing options.
3675 /// - If option COL is specified when varexp has three fields:
3676 ///~~~ {.cpp}
3677 /// tree.Draw("e1:e2:e3","","col");
3678 ///~~~
3679 /// a 2D scatter is produced with e1 vs e2, and e3 is mapped on the color
3680 /// table. The colors for e3 are evaluated once in linear scale before
3681 /// painting. Therefore changing the pad to log scale along Z as no effect
3682 /// on the colors.
3683 /// - If option contains the string "goff", no graphics is generated.
3684 ///
3685 /// `nentries` is the number of entries to process (default is all)
3686 /// first is the first entry to process (default is 0)
3687 ///
3688 /// This function returns the number of selected entries. It returns -1
3689 /// if an error occurs.
3690 ///
3691 /// ## Drawing expressions using arrays and array elements
3692 ///
3693 /// Let assumes, a leaf fMatrix, on the branch fEvent, which is a 3 by 3 array,
3694 /// or a TClonesArray.
3695 /// In a TTree::Draw expression you can now access fMatrix using the following
3696 /// syntaxes:
3697 ///
3698 /// | String passed | What is used for each entry of the tree
3699 /// |-----------------|--------------------------------------------------------|
3700 /// | `fMatrix` | the 9 elements of fMatrix |
3701 /// | `fMatrix[][]` | the 9 elements of fMatrix |
3702 /// | `fMatrix[2][2]` | only the elements fMatrix[2][2] |
3703 /// | `fMatrix[1]` | the 3 elements fMatrix[1][0], fMatrix[1][1] and fMatrix[1][2] |
3704 /// | `fMatrix[1][]` | the 3 elements fMatrix[1][0], fMatrix[1][1] and fMatrix[1][2] |
3705 /// | `fMatrix[][0]` | the 3 elements fMatrix[0][0], fMatrix[1][0] and fMatrix[2][0] |
3706 ///
3707 /// "fEvent.fMatrix...." same as "fMatrix..." (unless there is more than one leaf named fMatrix!).
3708 ///
3709 /// In summary, if a specific index is not specified for a dimension, TTree::Draw
3710 /// will loop through all the indices along this dimension. Leaving off the
3711 /// last (right most) dimension of specifying then with the two characters '[]'
3712 /// is equivalent. For variable size arrays (and TClonesArray) the range
3713 /// of the first dimension is recalculated for each entry of the tree.
3714 /// You can also specify the index as an expression of any other variables from the
3715 /// tree.
3716 ///
3717 /// TTree::Draw also now properly handling operations involving 2 or more arrays.
3718 ///
3719 /// Let assume a second matrix fResults[5][2], here are a sample of some
3720 /// of the possible combinations, the number of elements they produce and
3721 /// the loop used:
3722 ///
3723 /// | expression | element(s) | Loop |
3724 /// |----------------------------------|------------|--------------------------|
3725 /// | `fMatrix[2][1] - fResults[5][2]` | one | no loop |
3726 /// | `fMatrix[2][] - fResults[5][2]` | three | on 2nd dim fMatrix |
3727 /// | `fMatrix[2][] - fResults[5][]` | two | on both 2nd dimensions |
3728 /// | `fMatrix[][2] - fResults[][1]` | three | on both 1st dimensions |
3729 /// | `fMatrix[][2] - fResults[][]` | six | on both 1st and 2nd dimensions of fResults |
3730 /// | `fMatrix[][2] - fResults[3][]` | two | on 1st dim of fMatrix and 2nd of fResults (at the same time) |
3731 /// | `fMatrix[][] - fResults[][]` | six | on 1st dim then on 2nd dim |
3732 /// | `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.|
3733 ///
3734 ///
3735 /// In summary, TTree::Draw loops through all unspecified dimensions. To
3736 /// figure out the range of each loop, we match each unspecified dimension
3737 /// from left to right (ignoring ALL dimensions for which an index has been
3738 /// specified), in the equivalent loop matched dimensions use the same index
3739 /// and are restricted to the smallest range (of only the matched dimensions).
3740 /// When involving variable arrays, the range can of course be different
3741 /// for each entry of the tree.
3742 ///
3743 /// So the loop equivalent to "fMatrix[][2] - fResults[3][]" is:
3744 /// ~~~ {.cpp}
3745 /// for (Int_t i0; i < min(3,2); i++) {
3746 /// use the value of (fMatrix[i0][2] - fMatrix[3][i0])
3747 /// }
3748 /// ~~~
3749 /// So the loop equivalent to "fMatrix[][2] - fResults[][]" is:
3750 /// ~~~ {.cpp}
3751 /// for (Int_t i0; i < min(3,5); i++) {
3752 /// for (Int_t i1; i1 < 2; i1++) {
3753 /// use the value of (fMatrix[i0][2] - fMatrix[i0][i1])
3754 /// }
3755 /// }
3756 /// ~~~
3757 /// So the loop equivalent to "fMatrix[][] - fResults[][]" is:
3758 /// ~~~ {.cpp}
3759 /// for (Int_t i0; i < min(3,5); i++) {
3760 /// for (Int_t i1; i1 < min(3,2); i1++) {
3761 /// use the value of (fMatrix[i0][i1] - fMatrix[i0][i1])
3762 /// }
3763 /// }
3764 /// ~~~
3765 /// So the loop equivalent to "fMatrix[][fResults[][]]" is:
3766 /// ~~~ {.cpp}
3767 /// for (Int_t i0; i0 < 3; i0++) {
3768 /// for (Int_t j2; j2 < 5; j2++) {
3769 /// for (Int_t j3; j3 < 2; j3++) {
3770 /// i1 = fResults[j2][j3];
3771 /// use the value of fMatrix[i0][i1]
3772 /// }
3773 /// }
3774 /// ~~~
3775 /// ## Retrieving the result of Draw
3776 ///
3777 /// By default the temporary histogram created is called "htemp", but only in
3778 /// the one dimensional Draw("e1") it contains the TTree's data points. For
3779 /// a two dimensional Draw, the data is filled into a TGraph which is named
3780 /// "Graph". They can be retrieved by calling
3781 /// ~~~ {.cpp}
3782 /// TH1F *htemp = (TH1F*)gPad->GetPrimitive("htemp"); // 1D
3783 /// TGraph *graph = (TGraph*)gPad->GetPrimitive("Graph"); // 2D
3784 /// ~~~
3785 /// For a three and four dimensional Draw the TPolyMarker3D is unnamed, and
3786 /// cannot be retrieved.
3787 ///
3788 /// gPad always contains a TH1 derived object called "htemp" which allows to
3789 /// access the axes:
3790 /// ~~~ {.cpp}
3791 /// TGraph *graph = (TGraph*)gPad->GetPrimitive("Graph"); // 2D
3792 /// TH2F *htemp = (TH2F*)gPad->GetPrimitive("htemp"); // empty, but has axes
3793 /// TAxis *xaxis = htemp->GetXaxis();
3794 /// ~~~
3795 /// ## Saving the result of Draw to an histogram
3796 ///
3797 /// If varexp0 contains >>hnew (following the variable(s) name(s),
3798 /// the new histogram created is called hnew and it is kept in the current
3799 /// directory (and also the current pad). This works for all dimensions.
3800 ///
3801 /// Example:
3802 /// ~~~ {.cpp}
3803 /// tree.Draw("sqrt(x)>>hsqrt","y>0")
3804 /// ~~~
3805 /// will draw `sqrt(x)` and save the histogram as "hsqrt" in the current
3806 /// directory. To retrieve it do:
3807 /// ~~~ {.cpp}
3808 /// TH1F *hsqrt = (TH1F*)gDirectory->Get("hsqrt");
3809 /// ~~~
3810 /// The binning information is taken from the environment variables
3811 /// ~~~ {.cpp}
3812 /// Hist.Binning.?D.?
3813 /// ~~~
3814 /// In addition, the name of the histogram can be followed by up to 9
3815 /// numbers between '(' and ')', where the numbers describe the
3816 /// following:
3817 ///
3818 /// - 1 - bins in x-direction
3819 /// - 2 - lower limit in x-direction
3820 /// - 3 - upper limit in x-direction
3821 /// - 4-6 same for y-direction
3822 /// - 7-9 same for z-direction
3823 ///
3824 /// When a new binning is used the new value will become the default.
3825 /// Values can be skipped.
3826 ///
3827 /// Example:
3828 /// ~~~ {.cpp}
3829 /// tree.Draw("sqrt(x)>>hsqrt(500,10,20)")
3830 /// // plot sqrt(x) between 10 and 20 using 500 bins
3831 /// tree.Draw("sqrt(x):sin(y)>>hsqrt(100,10,60,50,.1,.5)")
3832 /// // plot sqrt(x) against sin(y)
3833 /// // 100 bins in x-direction; lower limit on x-axis is 10; upper limit is 60
3834 /// // 50 bins in y-direction; lower limit on y-axis is .1; upper limit is .5
3835 /// ~~~
3836 /// By default, the specified histogram is reset.
3837 /// To continue to append data to an existing histogram, use "+" in front
3838 /// of the histogram name.
3839 ///
3840 /// A '+' in front of the histogram name is ignored, when the name is followed by
3841 /// binning information as described in the previous paragraph.
3842 /// ~~~ {.cpp}
3843 /// tree.Draw("sqrt(x)>>+hsqrt","y>0")
3844 /// ~~~
3845 /// will not reset `hsqrt`, but will continue filling. This works for 1-D, 2-D
3846 /// and 3-D histograms.
3847 ///
3848 /// ## Accessing collection objects
3849 ///
3850 /// TTree::Draw default's handling of collections is to assume that any
3851 /// request on a collection pertain to it content. For example, if fTracks
3852 /// is a collection of Track objects, the following:
3853 /// ~~~ {.cpp}
3854 /// tree->Draw("event.fTracks.fPx");
3855 /// ~~~
3856 /// will plot the value of fPx for each Track objects inside the collection.
3857 /// Also
3858 /// ~~~ {.cpp}
3859 /// tree->Draw("event.fTracks.size()");
3860 /// ~~~
3861 /// would plot the result of the member function Track::size() for each
3862 /// Track object inside the collection.
3863 /// To access information about the collection itself, TTree::Draw support
3864 /// the '@' notation. If a variable which points to a collection is prefixed
3865 /// or postfixed with '@', the next part of the expression will pertain to
3866 /// the collection object. For example:
3867 /// ~~~ {.cpp}
3868 /// tree->Draw("event.@fTracks.size()");
3869 /// ~~~
3870 /// will plot the size of the collection referred to by `fTracks` (i.e the number
3871 /// of Track objects).
3872 ///
3873 /// ## Drawing 'objects'
3874 ///
3875 /// When a class has a member function named AsDouble or AsString, requesting
3876 /// to directly draw the object will imply a call to one of the 2 functions.
3877 /// If both AsDouble and AsString are present, AsDouble will be used.
3878 /// AsString can return either a char*, a std::string or a TString.s
3879 /// For example, the following
3880 /// ~~~ {.cpp}
3881 /// tree->Draw("event.myTTimeStamp");
3882 /// ~~~
3883 /// will draw the same histogram as
3884 /// ~~~ {.cpp}
3885 /// tree->Draw("event.myTTimeStamp.AsDouble()");
3886 /// ~~~
3887 /// In addition, when the object is a type TString or std::string, TTree::Draw
3888 /// will call respectively `TString::Data` and `std::string::c_str()`
3889 ///
3890 /// If the object is a TBits, the histogram will contain the index of the bit
3891 /// that are turned on.
3892 ///
3893 /// ## Retrieving information about the tree itself.
3894 ///
3895 /// You can refer to the tree (or chain) containing the data by using the
3896 /// string 'This'.
3897 /// You can then could any TTree methods. For example:
3898 /// ~~~ {.cpp}
3899 /// tree->Draw("This->GetReadEntry()");
3900 /// ~~~
3901 /// will display the local entry numbers be read.
3902 /// ~~~ {.cpp}
3903 /// tree->Draw("This->GetUserInfo()->At(0)->GetName()");
3904 /// ~~~
3905 /// will display the name of the first 'user info' object.
3906 ///
3907 /// ## Special functions and variables
3908 ///
3909 /// `Entry$`: A TTree::Draw formula can use the special variable `Entry$`
3910 /// to access the entry number being read. For example to draw every
3911 /// other entry use:
3912 /// ~~~ {.cpp}
3913 /// tree.Draw("myvar","Entry$%2==0");
3914 /// ~~~
3915 /// - `Entry$` : return the current entry number (`== TTree::GetReadEntry()`)
3916 /// - `LocalEntry$` : return the current entry number in the current tree of a
3917 /// chain (`== GetTree()->GetReadEntry()`)
3918 /// - `Entries$` : return the total number of entries (== TTree::GetEntries())
3919 /// - `Length$` : return the total number of element of this formula for this
3920 /// entry (`==TTreeFormula::GetNdata()`)
3921 /// - `Iteration$` : return the current iteration over this formula for this
3922 /// entry (i.e. varies from 0 to `Length$`).
3923 /// - `Length$(formula )` : return the total number of element of the formula
3924 /// given as a parameter.
3925 /// - `Sum$(formula )` : return the sum of the value of the elements of the
3926 /// formula given as a parameter. For example the mean for all the elements in
3927 /// one entry can be calculated with:
3928 /// `Sum$(formula )/Length$(formula )`
3929 /// - `Min$(formula )` : return the minimun (within one TTree entry) of the value of the
3930 /// elements of the formula given as a parameter.
3931 /// - `Max$(formula )` : return the maximum (within one TTree entry) of the value of the
3932 /// elements of the formula given as a parameter.
3933 /// - `MinIf$(formula,condition)`
3934 /// - `MaxIf$(formula,condition)` : return the minimum (maximum) (within one TTree entry)
3935 /// of the value of the elements of the formula given as a parameter
3936 /// if they match the condition. If no element matches the condition,
3937 /// the result is zero. To avoid the resulting peak at zero, use the
3938 /// pattern:
3939 /// ~~~ {.cpp}
3940 /// tree->Draw("MinIf$(formula,condition)","condition");
3941 /// ~~~
3942 /// which will avoid calculation `MinIf$` for the entries that have no match
3943 /// for the condition.
3944 /// - `Alt$(primary,alternate)` : return the value of "primary" if it is available
3945 /// for the current iteration otherwise return the value of "alternate".
3946 /// For example, with arr1[3] and arr2[2]
3947 /// ~~~ {.cpp}
3948 /// tree->Draw("arr1+Alt$(arr2,0)");
3949 /// ~~~
3950 /// will draw arr1[0]+arr2[0] ; arr1[1]+arr2[1] and arr1[2]+0
3951 /// Or with a variable size array arr3
3952 /// ~~~ {.cpp}
3953 /// tree->Draw("Alt$(arr3[0],0)+Alt$(arr3[1],0)+Alt$(arr3[2],0)");
3954 /// ~~~
3955 /// will draw the sum arr3 for the index 0 to min(2,actual_size_of_arr3-1)
3956 /// As a comparison
3957 /// ~~~ {.cpp}
3958 /// tree->Draw("arr3[0]+arr3[1]+arr3[2]");
3959 /// ~~~
3960 /// will draw the sum arr3 for the index 0 to 2 only if the
3961 /// actual_size_of_arr3 is greater or equal to 3.
3962 /// Note that the array in 'primary' is flattened/linearized thus using
3963 /// Alt$ with multi-dimensional arrays of different dimensions in unlikely
3964 /// to yield the expected results. To visualize a bit more what elements
3965 /// would be matched by TTree::Draw, TTree::Scan can be used:
3966 /// ~~~ {.cpp}
3967 /// tree->Scan("arr1:Alt$(arr2,0)");
3968 /// ~~~
3969 /// will print on one line the value of arr1 and (arr2,0) that will be
3970 /// matched by
3971 /// ~~~ {.cpp}
3972 /// tree->Draw("arr1-Alt$(arr2,0)");
3973 /// ~~~
3974 /// The ternary operator is not directly supported in TTree::Draw however, to plot the
3975 /// equivalent of `var2<20 ? -99 : var1`, you can use:
3976 /// ~~~ {.cpp}
3977 /// tree->Draw("(var2<20)*99+(var2>=20)*var1","");
3978 /// ~~~
3979 /// ## Drawing a user function accessing the TTree data directly
3980 ///
3981 /// If the formula contains a file name, TTree::MakeProxy will be used
3982 /// to load and execute this file. In particular it will draw the
3983 /// result of a function with the same name as the file. The function
3984 /// will be executed in a context where the name of the branches can
3985 /// be used as a C++ variable.
3986 ///
3987 /// For example draw px using the file hsimple.root (generated by the
3988 /// hsimple.C tutorial), we need a file named hsimple.cxx:
3989 /// ~~~ {.cpp}
3990 /// double hsimple() {
3991 /// return px;
3992 /// }
3993 /// ~~~
3994 /// MakeProxy can then be used indirectly via the TTree::Draw interface
3995 /// as follow:
3996 /// ~~~ {.cpp}
3997 /// new TFile("hsimple.root")
3998 /// ntuple->Draw("hsimple.cxx");
3999 /// ~~~
4000 /// A more complete example is available in the tutorials directory:
4001 /// `h1analysisProxy.cxx`, `h1analysProxy.h` and `h1analysisProxyCut.C`
4002 /// which reimplement the selector found in `h1analysis.C`
4003 ///
4004 /// The main features of this facility are:
4005 ///
4006 /// * on-demand loading of branches
4007 /// * ability to use the 'branchname' as if it was a data member
4008 /// * protection against array out-of-bound
4009 /// * ability to use the branch data as object (when the user code is available)
4010 ///
4011 /// See TTree::MakeProxy for more details.
4012 ///
4013 /// ## Making a Profile histogram
4014 ///
4015 /// In case of a 2-Dim expression, one can generate a TProfile histogram
4016 /// instead of a TH2F histogram by specifying option=prof or option=profs
4017 /// or option=profi or option=profg ; the trailing letter select the way
4018 /// the bin error are computed, See TProfile2D::SetErrorOption for
4019 /// details on the differences.
4020 /// The option=prof is automatically selected in case of y:x>>pf
4021 /// where pf is an existing TProfile histogram.
4022 ///
4023 /// ## Making a 2D Profile histogram
4024 ///
4025 /// In case of a 3-Dim expression, one can generate a TProfile2D histogram
4026 /// instead of a TH3F histogram by specifying option=prof or option=profs.
4027 /// or option=profi or option=profg ; the trailing letter select the way
4028 /// the bin error are computed, See TProfile2D::SetErrorOption for
4029 /// details on the differences.
4030 /// The option=prof is automatically selected in case of z:y:x>>pf
4031 /// where pf is an existing TProfile2D histogram.
4032 ///
4033 /// ## Making a 5D plot using GL
4034 ///
4035 /// If option GL5D is specified together with 5 variables, a 5D plot is drawn
4036 /// using OpenGL. See $ROOTSYS/tutorials/tree/staff.C as example.
4037 ///
4038 /// ## Making a parallel coordinates plot
4039 ///
4040 /// In case of a 2-Dim or more expression with the option=para, one can generate
4041 /// a parallel coordinates plot. With that option, the number of dimensions is
4042 /// arbitrary. Giving more than 4 variables without the option=para or
4043 /// option=candle or option=goff will produce an error.
4044 ///
4045 /// ## Making a candle sticks chart
4046 ///
4047 /// In case of a 2-Dim or more expression with the option=candle, one can generate
4048 /// a candle sticks chart. With that option, the number of dimensions is
4049 /// arbitrary. Giving more than 4 variables without the option=para or
4050 /// option=candle or option=goff will produce an error.
4051 ///
4052 /// ## Normalizing the output histogram to 1
4053 ///
4054 /// When option contains "norm" the output histogram is normalized to 1.
4055 ///
4056 /// ## Saving the result of Draw to a TEventList, a TEntryList or a TEntryListArray
4057 ///
4058 /// TTree::Draw can be used to fill a TEventList object (list of entry numbers)
4059 /// instead of histogramming one variable.
4060 /// If varexp0 has the form >>elist , a TEventList object named "elist"
4061 /// is created in the current directory. elist will contain the list
4062 /// of entry numbers satisfying the current selection.
4063 /// If option "entrylist" is used, a TEntryList object is created
4064 /// If the selection contains arrays, vectors or any container class and option
4065 /// "entrylistarray" is used, a TEntryListArray object is created
4066 /// containing also the subentries satisfying the selection, i.e. the indices of
4067 /// the branches which hold containers classes.
4068 /// Example:
4069 /// ~~~ {.cpp}
4070 /// tree.Draw(">>yplus","y>0")
4071 /// ~~~
4072 /// will create a TEventList object named "yplus" in the current directory.
4073 /// In an interactive session, one can type (after TTree::Draw)
4074 /// ~~~ {.cpp}
4075 /// yplus.Print("all")
4076 /// ~~~
4077 /// to print the list of entry numbers in the list.
4078 /// ~~~ {.cpp}
4079 /// tree.Draw(">>yplus", "y>0", "entrylist")
4080 /// ~~~
4081 /// will create a TEntryList object names "yplus" in the current directory
4082 /// ~~~ {.cpp}
4083 /// tree.Draw(">>yplus", "y>0", "entrylistarray")
4084 /// ~~~
4085 /// will create a TEntryListArray object names "yplus" in the current directory
4086 ///
4087 /// By default, the specified entry list is reset.
4088 /// To continue to append data to an existing list, use "+" in front
4089 /// of the list name;
4090 /// ~~~ {.cpp}
4091 /// tree.Draw(">>+yplus","y>0")
4092 /// ~~~
4093 /// will not reset yplus, but will enter the selected entries at the end
4094 /// of the existing list.
4095 ///
4096 /// ## Using a TEventList, TEntryList or TEntryListArray as Input
4097 ///
4098 /// Once a TEventList or a TEntryList object has been generated, it can be used as input
4099 /// for TTree::Draw. Use TTree::SetEventList or TTree::SetEntryList to set the
4100 /// current event list
4101 ///
4102 /// Example 1:
4103 /// ~~~ {.cpp}
4104 /// TEventList *elist = (TEventList*)gDirectory->Get("yplus");
4105 /// tree->SetEventList(elist);
4106 /// tree->Draw("py");
4107 /// ~~~
4108 /// Example 2:
4109 /// ~~~ {.cpp}
4110 /// TEntryList *elist = (TEntryList*)gDirectory->Get("yplus");
4111 /// tree->SetEntryList(elist);
4112 /// tree->Draw("py");
4113 /// ~~~
4114 /// If a TEventList object is used as input, a new TEntryList object is created
4115 /// inside the SetEventList function. In case of a TChain, all tree headers are loaded
4116 /// for this transformation. This new object is owned by the chain and is deleted
4117 /// with it, unless the user extracts it by calling GetEntryList() function.
4118 /// See also comments to SetEventList() function of TTree and TChain.
4119 ///
4120 /// If arrays are used in the selection criteria and TEntryListArray is not used,
4121 /// all the entries that have at least one element of the array that satisfy the selection
4122 /// are entered in the list.
4123 ///
4124 /// Example:
4125 /// ~~~ {.cpp}
4126 /// tree.Draw(">>pyplus","fTracks.fPy>0");
4127 /// tree->SetEventList(pyplus);
4128 /// tree->Draw("fTracks.fPy");
4129 /// ~~~
4130 /// will draw the fPy of ALL tracks in event with at least one track with
4131 /// a positive fPy.
4132 ///
4133 /// To select only the elements that did match the original selection
4134 /// use TEventList::SetReapplyCut or TEntryList::SetReapplyCut.
4135 ///
4136 /// Example:
4137 /// ~~~ {.cpp}
4138 /// tree.Draw(">>pyplus","fTracks.fPy>0");
4139 /// pyplus->SetReapplyCut(kTRUE);
4140 /// tree->SetEventList(pyplus);
4141 /// tree->Draw("fTracks.fPy");
4142 /// ~~~
4143 /// will draw the fPy of only the tracks that have a positive fPy.
4144 ///
4145 /// To draw only the elements that match a selection in case of arrays,
4146 /// you can also use TEntryListArray (faster in case of a more general selection).
4147 ///
4148 /// Example:
4149 /// ~~~ {.cpp}
4150 /// tree.Draw(">>pyplus","fTracks.fPy>0", "entrylistarray");
4151 /// tree->SetEntryList(pyplus);
4152 /// tree->Draw("fTracks.fPy");
4153 /// ~~~
4154 /// will draw the fPy of only the tracks that have a positive fPy,
4155 /// but without redoing the selection.
4156 ///
4157 /// Note: Use tree->SetEventList(0) if you do not want use the list as input.
4158 ///
4159 /// ## How to obtain more info from TTree::Draw
4160 ///
4161 /// Once TTree::Draw has been called, it is possible to access useful
4162 /// information still stored in the TTree object via the following functions:
4163 ///
4164 /// - GetSelectedRows() // return the number of values accepted by the selection expression. In case where no selection was specified, returns the number of values processed.
4165 /// - GetV1() // returns a pointer to the double array of V1
4166 /// - GetV2() // returns a pointer to the double array of V2
4167 /// - GetV3() // returns a pointer to the double array of V3
4168 /// - GetV4() // returns a pointer to the double array of V4
4169 /// - GetW() // returns a pointer to the double array of Weights where weight equal the result of the selection expression.
4170 ///
4171 /// where V1,V2,V3 correspond to the expressions in
4172 /// ~~~ {.cpp}
4173 /// TTree::Draw("V1:V2:V3:V4",selection);
4174 /// ~~~
4175 /// If the expression has more than 4 component use GetVal(index)
4176 ///
4177 /// Example:
4178 /// ~~~ {.cpp}
4179 /// Root > ntuple->Draw("py:px","pz>4");
4180 /// Root > TGraph *gr = new TGraph(ntuple->GetSelectedRows(),
4181 /// ntuple->GetV2(), ntuple->GetV1());
4182 /// Root > gr->Draw("ap"); //draw graph in current pad
4183 /// ~~~
4184 /// creates a TGraph object with a number of points corresponding to the
4185 /// number of entries selected by the expression "pz>4", the x points of the graph
4186 /// being the px values of the Tree and the y points the py values.
4187 ///
4188 /// Important note: By default TTree::Draw creates the arrays obtained
4189 /// with GetW, GetV1, GetV2, GetV3, GetV4, GetVal with a length corresponding
4190 /// to the parameter fEstimate. The content will be the last `GetSelectedRows() % GetEstimate()`
4191 /// values calculated.
4192 /// By default fEstimate=1000000 and can be modified
4193 /// via TTree::SetEstimate. To keep in memory all the results (in case
4194 /// where there is only one result per entry), use
4195 /// ~~~ {.cpp}
4196 /// tree->SetEstimate(tree->GetEntries()+1); // same as tree->SetEstimate(-1);
4197 /// ~~~
4198 /// You must call SetEstimate if the expected number of selected rows
4199 /// you need to look at is greater than 1000000.
4200 ///
4201 /// You can use the option "goff" to turn off the graphics output
4202 /// of TTree::Draw in the above example.
4203 ///
4204 /// ## Automatic interface to TTree::Draw via the TTreeViewer
4205 ///
4206 /// A complete graphical interface to this function is implemented
4207 /// in the class TTreeViewer.
4208 /// To start the TTreeViewer, three possibilities:
4209 /// - select TTree context menu item "StartViewer"
4210 /// - type the command "TTreeViewer TV(treeName)"
4211 /// - execute statement "tree->StartViewer();"
4212 
4213 Long64_t TTree::Draw(const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
4215  GetPlayer();
4216  if (fPlayer)
4217  return fPlayer->DrawSelect(varexp,selection,option,nentries,firstentry);
4218  return -1;
4219 }
4220 
4221 ////////////////////////////////////////////////////////////////////////////////
4222 /// Remove some baskets from memory.
4223 
4224 void TTree::DropBaskets()
4226  TBranch* branch = 0;
4228  for (Int_t i = 0; i < nb; ++i) {
4229  branch = (TBranch*) fBranches.UncheckedAt(i);
4230  branch->DropBaskets("all");
4231  }
4232 }
4233 
4234 ////////////////////////////////////////////////////////////////////////////////
4235 /// Drop branch buffers to accommodate nbytes below MaxVirtualsize.
4236 
4239  // Be careful not to remove current read/write buffers.
4240  Int_t ndrop = 0;
4241  Int_t nleaves = fLeaves.GetEntriesFast();
4242  for (Int_t i = 0; i < nleaves; ++i) {
4243  TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
4244  TBranch* branch = (TBranch*) leaf->GetBranch();
4245  Int_t nbaskets = branch->GetListOfBaskets()->GetEntries();
4246  for (Int_t j = 0; j < nbaskets - 1; ++j) {
4247  if ((j == branch->GetReadBasket()) || (j == branch->GetWriteBasket())) {
4248  continue;
4249  }
4250  TBasket* basket = (TBasket*)branch->GetListOfBaskets()->UncheckedAt(j);
4251  if (basket) {
4252  ndrop += basket->DropBuffers();
4254  return;
4255  }
4256  }
4257  }
4258  }
4259 }
4260 
4261 ////////////////////////////////////////////////////////////////////////////////
4262 /// Fill all branches.
4263 ///
4264 /// This function loops on all the branches of this tree. For
4265 /// each branch, it copies to the branch buffer (basket) the current
4266 /// values of the leaves data types. If a leaf is a simple data type,
4267 /// a simple conversion to a machine independent format has to be done.
4268 ///
4269 /// This machine independent version of the data is copied into a
4270 /// basket (each branch has its own basket). When a basket is full
4271 /// (32k worth of data by default), it is then optionally compressed
4272 /// and written to disk (this operation is also called committing or
4273 /// 'flushing' the basket). The committed baskets are then
4274 /// immediately removed from memory.
4275 ///
4276 /// The function returns the number of bytes committed to the
4277 /// individual branches.
4278 ///
4279 /// If a write error occurs, the number of bytes returned is -1.
4280 ///
4281 /// If no data are written, because, e.g., the branch is disabled,
4282 /// the number of bytes returned is 0.
4283 ///
4284 /// __The baskets are flushed and the Tree header saved at regular intervals__
4285 ///
4286 /// At regular intervals, when the amount of data written so far is
4287 /// greater than fAutoFlush (see SetAutoFlush) all the baskets are flushed to disk.
4288 /// This makes future reading faster as it guarantees that baskets belonging to nearby
4289 /// entries will be on the same disk region.
4290 /// When the first call to flush the baskets happen, we also take this opportunity
4291 /// to optimize the baskets buffers.
4292 /// We also check if the amount of data written is greater than fAutoSave (see SetAutoSave).
4293 /// In this case we also write the Tree header. This makes the Tree recoverable up to this point
4294 /// in case the program writing the Tree crashes.
4295 /// The decisions to FlushBaskets and Auto Save can be made based either on the number
4296 /// of bytes written (fAutoFlush and fAutoSave negative) or on the number of entries
4297 /// written (fAutoFlush and fAutoSave positive).
4298 /// Note that the user can decide to call FlushBaskets and AutoSave in her event loop
4299 /// base on the number of events written instead of the number of bytes written.
4300 ///
4301 /// Note that calling FlushBaskets too often increases the IO time.
4302 ///
4303 /// Note that calling AutoSave too often increases the IO time and also the file size.
4304 
4307  // create cache if wanted
4309 
4310  Int_t nbytes = 0;
4311  Int_t nerror = 0;
4313  if (nb == 1) {
4314  // Case of one single super branch. Automatically update
4315  // all the branch addresses if a new object was created.
4316  TBranch* branch = (TBranch*) fBranches.UncheckedAt(0);
4317  branch->UpdateAddress();
4318  }
4319  if (fBranchRef) {
4320  fBranchRef->Clear();
4321  }
4322  for (Int_t i = 0; i < nb; ++i) {
4323  // Loop over all branches, filling and accumulating bytes written and error counts.
4324  TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
4325  if (branch->TestBit(kDoNotProcess)) {
4326  continue;
4327  }
4328  Int_t nwrite = branch->Fill();
4329  if (nwrite < 0) {
4330  if (nerror < 2) {
4331  Error("Fill", "Failed filling branch:%s.%s, nbytes=%d, entry=%lld\n"
4332  " This error is symptomatic of a Tree created as a memory-resident Tree\n"
4333  " Instead of doing:\n"
4334  " TTree *T = new TTree(...)\n"
4335  " TFile *f = new TFile(...)\n"
4336  " you should do:\n"
4337  " TFile *f = new TFile(...)\n"
4338  " TTree *T = new TTree(...)",
4339  GetName(), branch->GetName(), nwrite,fEntries+1);
4340  } else {
4341  Error("Fill", "Failed filling branch:%s.%s, nbytes=%d, entry=%lld", GetName(), branch->GetName(), nwrite,fEntries+1);
4342  }
4343  ++nerror;
4344  } else {
4345  nbytes += nwrite;
4346  }
4347  }
4348  if (fBranchRef) {
4349  fBranchRef->Fill();
4350  }
4351  ++fEntries;
4352  if (fEntries > fMaxEntries) {
4353  KeepCircular();
4354  }
4355  if (gDebug > 0) printf("TTree::Fill - A: %d %lld %lld %lld %lld %lld %lld \n",
4357 
4358  if (fAutoFlush != 0 || fAutoSave != 0) {
4359  // Is it time to flush or autosave baskets?
4360  if (fFlushedBytes == 0) {
4361  // Decision can be based initially either on the number of bytes
4362  // or the number of entries written.
4363  if ((fAutoFlush<0 && fZipBytes > -fAutoFlush) ||
4364  (fAutoSave <0 && fZipBytes > -fAutoSave ) ||
4365  (fAutoFlush>0 && fEntries%TMath::Max((Long64_t)1,fAutoFlush) == 0) ||
4366  (fAutoSave >0 && fEntries%TMath::Max((Long64_t)1,fAutoSave) == 0) ) {
4367 
4368  //First call FlushBasket to make sure that fTotBytes is up to date.
4369  FlushBaskets();
4370  OptimizeBaskets(fTotBytes,1,"");
4371  if (gDebug > 0) Info("TTree::Fill","OptimizeBaskets called at entry %lld, fZipBytes=%lld, fFlushedBytes=%lld\n",fEntries,fZipBytes,fFlushedBytes);
4373  fAutoFlush = fEntries; // Use test on entries rather than bytes
4374 
4375  // subsequently in run
4376  if (fAutoSave < 0) {
4377  // Set fAutoSave to the largest integer multiple of
4378  // fAutoFlush events such that fAutoSave*fFlushedBytes
4379  // < (minus the input value of fAutoSave)
4380  if (fZipBytes != 0) {
4382  } else if (fTotBytes != 0) {
4384  } else {
4385  TBufferFile b(TBuffer::kWrite, 10000);
4386  TTree::Class()->WriteBuffer(b, (TTree*) this);
4387  Long64_t total = b.Length();
4389  }
4390  } else if(fAutoSave > 0) {
4392  }
4393  if (fAutoSave!=0 && fEntries >= fAutoSave) AutoSave(); // FlushBaskets not called in AutoSave
4394  if (gDebug > 0) Info("TTree::Fill","First AutoFlush. fAutoFlush = %lld, fAutoSave = %lld\n", fAutoFlush, fAutoSave);
4395  }
4396  } else if (fNClusterRange && fAutoFlush && ( (fEntries-fClusterRangeEnd[fNClusterRange-1]) % fAutoFlush == 0) ) {
4397  if (fAutoSave != 0 && fEntries%fAutoSave == 0) {
4398  //We are at an AutoSave point. AutoSave flushes baskets and saves the Tree header
4399  AutoSave("flushbaskets");
4400  if (gDebug > 0) Info("TTree::Fill","AutoSave called at entry %lld, fZipBytes=%lld, fSavedBytes=%lld\n",fEntries,fZipBytes,fSavedBytes);
4401  } else {
4402  //We only FlushBaskets
4403  FlushBaskets();
4404  if (gDebug > 0) Info("TTree::Fill","FlushBasket called at entry %lld, fZipBytes=%lld, fFlushedBytes=%lld\n",fEntries,fZipBytes,fFlushedBytes);
4405  }
4407  } else if (fNClusterRange == 0 && fEntries > 1 && fAutoFlush && fEntries%fAutoFlush == 0) {
4408  if (fAutoSave != 0 && fEntries%fAutoSave == 0) {
4409  //We are at an AutoSave point. AutoSave flushes baskets and saves the Tree header
4410  AutoSave("flushbaskets");
4411  if (gDebug > 0) Info("TTree::Fill","AutoSave called at entry %lld, fZipBytes=%lld, fSavedBytes=%lld\n",fEntries,fZipBytes,fSavedBytes);
4412  } else {
4413  //We only FlushBaskets
4414  FlushBaskets();
4415  if (gDebug > 0) Info("TTree::Fill","FlushBasket called at entry %lld, fZipBytes=%lld, fFlushedBytes=%lld\n",fEntries,fZipBytes,fFlushedBytes);
4416  }
4418  }
4419  }
4420  // Check that output file is still below the maximum size.
4421  // If above, close the current file and continue on a new file.
4422  // Currently, the automatic change of file is restricted
4423  // to the case where the tree is in the top level directory.
4424  if (!fDirectory) {
4425  return nbytes;
4426  }
4427  TFile* file = fDirectory->GetFile();
4428  if (file && (file->GetEND() > fgMaxTreeSize)) {
4429  if (fDirectory == (TDirectory*) file) {
4430  ChangeFile(file);
4431  }
4432  }
4433  if (nerror) {
4434  return -1;
4435  }
4436  return nbytes;
4437 }
4438 
4439 ////////////////////////////////////////////////////////////////////////////////
4440 /// Search in the array for a branch matching the branch name,
4441 /// with the branch possibly expressed as a 'full' path name (with dots).
4442 
4443 static TBranch *R__FindBranchHelper(TObjArray *list, const char *branchname) {
4444  if (list==0 || branchname == 0 || branchname[0] == '\0') return 0;
4445 
4446  Int_t nbranches = list->GetEntries();
4447 
4448  UInt_t brlen = strlen(branchname);
4449 
4450  for(Int_t index = 0; index < nbranches; ++index) {
4451  TBranch *where = (TBranch*)list->UncheckedAt(index);
4452 
4453  const char *name = where->GetName();
4454  UInt_t len = strlen(name);
4455  if (len && name[len-1]==']') {
4456  const char *dim = strchr(name,'[');
4457  if (dim) {
4458  len = dim - name;
4459  }
4460  }
4461  if (brlen == len && strncmp(branchname,name,len)==0) {
4462  return where;
4463  }
4464  TBranch *next = 0;
4465  if ((brlen >= len) && (branchname[len] == '.')
4466  && strncmp(name, branchname, len) == 0) {
4467  // The prefix subbranch name match the branch name.
4468 
4469  next = where->FindBranch(branchname);
4470  if (!next) {
4471  next = where->FindBranch(branchname+len+1);
4472  }
4473  if (next) return next;
4474  }
4475  const char *dot = strchr((char*)branchname,'.');
4476  if (dot) {
4477  if (len==(size_t)(dot-branchname) &&
4478  strncmp(branchname,name,dot-branchname)==0 ) {
4479  return R__FindBranchHelper(where->GetListOfBranches(),dot+1);
4480  }
4481  }
4482  }
4483  return 0;
4484 }
4485 
4486 ////////////////////////////////////////////////////////////////////////////////
4487 /// Return the branch that correspond to the path 'branchname', which can
4488 /// include the name of the tree or the omitted name of the parent branches.
4489 /// In case of ambiguity, returns the first match.
4490 
4491 TBranch* TTree::FindBranch(const char* branchname)
4493  // We already have been visited while recursively looking
4494  // through the friends tree, let return
4496  return 0;
4497  }
4498 
4499  TBranch* branch = 0;
4500  // If the first part of the name match the TTree name, look for the right part in the
4501  // list of branches.
4502  // This will allow the branchname to be preceded by
4503  // the name of this tree.
4504  if (strncmp(fName.Data(),branchname,fName.Length())==0 && branchname[fName.Length()]=='.') {
4505  branch = R__FindBranchHelper( GetListOfBranches(), branchname + fName.Length() + 1);
4506  if (branch) return branch;
4507  }
4508  // If we did not find it, let's try to find the full name in the list of branches.
4509  branch = R__FindBranchHelper(GetListOfBranches(), branchname);
4510  if (branch) return branch;
4511 
4512  // If we still did not find, let's try to find it within each branch assuming it does not the branch name.
4514  while ((branch = (TBranch*) next())) {
4515  TBranch* nestedbranch = branch->FindBranch(branchname);
4516  if (nestedbranch) {
4517  return nestedbranch;
4518  }
4519  }
4520 
4521  // Search in list of friends.
4522  if (!fFriends) {
4523  return 0;
4524  }
4525  TFriendLock lock(this, kFindBranch);
4526  TIter nextf(fFriends);
4527  TFriendElement* fe = 0;
4528  while ((fe = (TFriendElement*) nextf())) {
4529  TTree* t = fe->GetTree();
4530  if (!t) {
4531  continue;
4532  }
4533  // If the alias is present replace it with the real name.
4534  const char *subbranch = strstr(branchname, fe->GetName());
4535  if (subbranch != branchname) {
4536  subbranch = 0;
4537  }
4538  if (subbranch) {
4539  subbranch += strlen(fe->GetName());
4540  if (*subbranch != '.') {
4541  subbranch = 0;
4542  } else {
4543  ++subbranch;
4544  }
4545  }
4546  std::ostringstream name;
4547  if (subbranch) {
4548  name << t->GetName() << "." << subbranch;
4549  } else {
4550  name << branchname;
4551  }
4552  branch = t->FindBranch(name.str().c_str());
4553  if (branch) {
4554  return branch;
4555  }
4556  }
4557  return 0;
4558 }
4559 
4560 ////////////////////////////////////////////////////////////////////////////////
4561 /// Find leaf..
4562 
4563 TLeaf* TTree::FindLeaf(const char* searchname)
4565  // We already have been visited while recursively looking
4566  // through the friends tree, let's return.
4567  if (kFindLeaf & fFriendLockStatus) {
4568  return 0;
4569  }
4570 
4571  // This will allow the branchname to be preceded by
4572  // the name of this tree.
4573  char* subsearchname = (char*) strstr(searchname, GetName());
4574  if (subsearchname != searchname) {
4575  subsearchname = 0;
4576  }
4577  if (subsearchname) {
4578  subsearchname += strlen(GetName());
4579  if (*subsearchname != '.') {
4580  subsearchname = 0;
4581  } else {
4582  ++subsearchname;
4583  if (subsearchname[0]==0) {
4584  subsearchname = 0;
4585  }
4586  }
4587  }
4588 
4589  TString leafname;
4590  TString leaftitle;
4591  TString longname;
4592  TString longtitle;
4593 
4594  // For leaves we allow for one level up to be prefixed to the name.
4596  TLeaf* leaf = 0;
4597  while ((leaf = (TLeaf*) next())) {
4598  leafname = leaf->GetName();
4599  Ssiz_t dim = leafname.First('[');
4600  if (dim >= 0) leafname.Remove(dim);
4601 
4602  if (leafname == searchname) {
4603  return leaf;
4604  }
4605  if (subsearchname && leafname == subsearchname) {
4606  return leaf;
4607  }
4608  // The TLeafElement contains the branch name
4609  // in its name, let's use the title.
4610  leaftitle = leaf->GetTitle();
4611  dim = leaftitle.First('[');
4612  if (dim >= 0) leaftitle.Remove(dim);
4613 
4614  if (leaftitle == searchname) {
4615  return leaf;
4616  }
4617  if (subsearchname && leaftitle == subsearchname) {
4618  return leaf;
4619  }
4620  TBranch* branch = leaf->GetBranch();
4621  if (branch) {
4622  longname.Form("%s.%s",branch->GetName(),leafname.Data());
4623  dim = longname.First('[');
4624  if (dim>=0) longname.Remove(dim);
4625  if (longname == searchname) {
4626  return leaf;
4627  }
4628  if (subsearchname && longname == subsearchname) {
4629  return leaf;
4630  }
4631  longtitle.Form("%s.%s",branch->GetName(),leaftitle.Data());
4632  dim = longtitle.First('[');
4633  if (dim>=0) longtitle.Remove(dim);
4634  if (longtitle == searchname) {
4635  return leaf;
4636  }
4637  if (subsearchname && longtitle == subsearchname) {
4638  return leaf;
4639  }
4640  // The following is for the case where the branch is only
4641  // a sub-branch. Since we do not see it through
4642  // TTree::GetListOfBranches, we need to see it indirectly.
4643  // This is the less sturdy part of this search ... it may
4644  // need refining ...
4645  if (strstr(searchname, ".") && !strcmp(searchname, branch->GetName())) {
4646  return leaf;
4647  }
4648  if (subsearchname && strstr(subsearchname, ".") && !strcmp(subsearchname, branch->GetName())) {
4649  return leaf;
4650  }
4651  }
4652  }
4653  // Search in list of friends.
4654  if (!fFriends) {
4655  return 0;
4656  }
4657  TFriendLock lock(this, kFindLeaf);
4658  TIter nextf(fFriends);
4659  TFriendElement* fe = 0;
4660  while ((fe = (TFriendElement*) nextf())) {
4661  TTree* t = fe->GetTree();
4662  if (!t) {
4663  continue;
4664  }
4665  // If the alias is present replace it with the real name.
4666  subsearchname = (char*) strstr(searchname, fe->GetName());
4667  if (subsearchname != searchname) {
4668  subsearchname = 0;
4669  }
4670  if (subsearchname) {
4671  subsearchname += strlen(fe->GetName());
4672  if (*subsearchname != '.') {
4673  subsearchname = 0;
4674  } else {
4675  ++subsearchname;
4676  }
4677  }
4678  if (subsearchname) {
4679  leafname.Form("%s.%s",t->GetName(),subsearchname);
4680  } else {
4681  leafname = searchname;
4682  }
4683  leaf = t->FindLeaf(leafname);
4684  if (leaf) {
4685  return leaf;
4686  }
4687  }
4688  return 0;
4689 }
4690 
4691 ////////////////////////////////////////////////////////////////////////////////
4692 /// Fit a projected item(s) from a tree.
4693 ///
4694 /// funcname is a TF1 function.
4695 ///
4696 /// See TTree::Draw() for explanations of the other parameters.
4697 ///
4698 /// By default the temporary histogram created is called htemp.
4699 /// If varexp contains >>hnew , the new histogram created is called hnew
4700 /// and it is kept in the current directory.
4701 ///
4702 /// The function returns the number of selected entries.
4703 ///
4704 /// Example:
4705 /// ~~~ {.cpp}
4706 /// tree.Fit(pol4,sqrt(x)>>hsqrt,y>0)
4707 /// ~~~
4708 /// will fit sqrt(x) and save the histogram as "hsqrt" in the current
4709 /// directory.
4710 ///
4711 /// See also TTree::UnbinnedFit
4712 ///
4713 /// ## Return status
4714 ///
4715 /// The function returns the status of the histogram fit (see TH1::Fit)
4716 /// If no entries were selected, the function returns -1;
4717 /// (i.e. fitResult is null is the fit is OK)
4718 
4719 Int_t TTree::Fit(const char* funcname, const char* varexp, const char* selection, Option_t* option, Option_t* goption, Long64_t nentries, Long64_t firstentry)
4721  GetPlayer();
4722  if (fPlayer) {
4723  return fPlayer->Fit(funcname, varexp, selection, option, goption, nentries, firstentry);
4724  }
4725  return -1;
4726 }
4727 
4728 ////////////////////////////////////////////////////////////////////////////////
4729 /// Write to disk all the basket that have not yet been individually written.
4730 ///
4731 /// Return the number of bytes written or -1 in case of write error.
4732 
4733 Int_t TTree::FlushBaskets() const
4735  if (!fDirectory) return 0;
4736  Int_t nbytes = 0;
4737  Int_t nerror = 0;
4738  TObjArray *lb = const_cast<TTree*>(this)->GetListOfBranches();
4739  Int_t nb = lb->GetEntriesFast();
4740  for (Int_t j = 0; j < nb; j++) {
4741  TBranch* branch = (TBranch*) lb->UncheckedAt(j);
4742  if (branch) {
4743  Int_t nwrite = branch->FlushBaskets();
4744  if (nwrite<0) {
4745  ++nerror;
4746  } else {
4747  nbytes += nwrite;
4748  }
4749  }
4750  }
4751  if (nerror) {
4752  return -1;
4753  } else {
4754  return nbytes;
4755  }
4756 }
4757 
4758 ////////////////////////////////////////////////////////////////////////////////
4759 /// Returns the expanded value of the alias. Search in the friends if any.
4760 
4761 const char* TTree::GetAlias(const char* aliasName) const
4763  // We already have been visited while recursively looking
4764  // through the friends tree, let's return.
4765  if (kGetAlias & fFriendLockStatus) {
4766  return 0;
4767  }
4768  if (fAliases) {
4769  TObject* alias = fAliases->FindObject(aliasName);
4770  if (alias) {
4771  return alias->GetTitle();
4772  }
4773  }
4774  if (!fFriends) {
4775  return 0;
4776  }
4777  TFriendLock lock(const_cast<TTree*>(this), kGetAlias);
4778  TIter nextf(fFriends);
4779  TFriendElement* fe = 0;
4780  while ((fe = (TFriendElement*) nextf())) {
4781  TTree* t = fe->GetTree();
4782  if (t) {
4783  const char* alias = t->GetAlias(aliasName);
4784  if (alias) {
4785  return alias;
4786  }
4787  const char* subAliasName = strstr(aliasName, fe->GetName());
4788  if (subAliasName && (subAliasName[strlen(fe->GetName())] == '.')) {
4789  alias = t->GetAlias(aliasName + strlen(fe->GetName()) + 1);
4790  if (alias) {
4791  return alias;
4792  }
4793  }
4794  }
4795  }
4796  return 0;
4797 }
4798 
4799 ////////////////////////////////////////////////////////////////////////////////
4800 /// Return pointer to the branch with the given name in this tree or its friends.
4801 
4802 TBranch* TTree::GetBranch(const char* name)
4804  if (name == 0) return 0;
4805 
4806  // We already have been visited while recursively
4807  // looking through the friends tree, let's return.
4808  if (kGetBranch & fFriendLockStatus) {
4809  return 0;
4810  }
4811 
4812  // Search using branches.
4814  for (Int_t i = 0; i < nb; i++) {
4815  TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
4816  if (!strcmp(branch->GetName(), name)) {
4817  return branch;
4818  }
4819  TObjArray* lb = branch->GetListOfBranches();
4820  Int_t nb1 = lb->GetEntriesFast();
4821  for (Int_t j = 0; j < nb1; j++) {
4822  TBranch* b1 = (TBranch*) lb->UncheckedAt(j);
4823  if (!strcmp(b1->GetName(), name)) {
4824  return b1;
4825  }
4826  TObjArray* lb1 = b1->GetListOfBranches();
4827  Int_t nb2 = lb1->GetEntriesFast();
4828  for (Int_t k = 0; k < nb2; k++) {
4829  TBranch* b2 = (TBranch*) lb1->UncheckedAt(k);
4830  if (!strcmp(b2->GetName(), name)) {
4831  return b2;
4832  }
4833  }
4834  }
4835  }
4836 
4837  // Search using leaves.
4838  TObjArray* leaves = GetListOfLeaves();
4839  Int_t nleaves = leaves->GetEntriesFast();
4840  for (Int_t i = 0; i < nleaves; i++) {
4841  TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(i);
4842  TBranch* branch = leaf->GetBranch();
4843  if (!strcmp(branch->GetName(), name)) {
4844  return branch;
4845  }
4846  }
4847 
4848  if (!fFriends) {
4849  return 0;
4850  }
4851 
4852  // Search in list of friends.
4853  TFriendLock lock(this, kGetBranch);
4854  TIter next(fFriends);
4855  TFriendElement* fe = 0;
4856  while ((fe = (TFriendElement*) next())) {
4857  TTree* t = fe->GetTree();
4858  if (t) {
4859  TBranch* branch = t->GetBranch(name);
4860  if (branch) {
4861  return branch;
4862  }
4863  }
4864  }
4865 
4866  // Second pass in the list of friends when
4867  // the branch name is prefixed by the tree name.
4868  next.Reset();
4869  while ((fe = (TFriendElement*) next())) {
4870  TTree* t = fe->GetTree();
4871  if (!t) {
4872  continue;
4873  }
4874  char* subname = (char*) strstr(name, fe->GetName());
4875  if (subname != name) {
4876  continue;
4877  }
4878  Int_t l = strlen(fe->GetName());
4879  subname += l;
4880  if (*subname != '.') {
4881  continue;
4882  }
4883  subname++;
4884  TBranch* branch = t->GetBranch(subname);
4885  if (branch) {
4886  return branch;
4887  }
4888  }
4889  return 0;
4890 }
4891 
4892 ////////////////////////////////////////////////////////////////////////////////
4893 /// Return status of branch with name branchname.
4894 ///
4895 /// - 0 if branch is not activated
4896 /// - 1 if branch is activated
4897 
4898 Bool_t TTree::GetBranchStatus(const char* branchname) const
4900  TBranch* br = const_cast<TTree*>(this)->GetBranch(branchname);
4901  if (br) {
4902  return br->TestBit(kDoNotProcess) == 0;
4903  }
4904  return 0;
4905 }
4906 
4907 ////////////////////////////////////////////////////////////////////////////////
4908 /// Static function returning the current branch style.
4909 ///
4910 /// - style = 0 old Branch
4911 /// - style = 1 new Bronch
4912 
4915  return fgBranchStyle;
4916 }
4917 
4918 ////////////////////////////////////////////////////////////////////////////////
4919 /// Used for automatic sizing of the cache.
4920 ///
4921 /// Estimates a suitable size for the tree cache based on AutoFlush.
4922 /// A cache sizing factor is taken from the configuration. If this yields zero
4923 /// and withDefault is true the historical algorithm for default size is used.
4924 
4925 Long64_t TTree::GetCacheAutoSize(Bool_t withDefault /* = kFALSE */ ) const
4927  const char *stcs;
4928  Double_t cacheFactor = 0.0;
4929  if (!(stcs = gSystem->Getenv("ROOT_TTREECACHE_SIZE")) || !*stcs) {
4930  cacheFactor = gEnv->GetValue("TTreeCache.Size", 1.0);
4931  } else {
4932  cacheFactor = TString(stcs).Atof();
4933  }
4934 
4935  if (cacheFactor < 0.0) {
4936  // ignore negative factors
4937  cacheFactor = 0.0;
4938  }
4939 
4940  Long64_t cacheSize = 0;
4941 
4942  if (fAutoFlush < 0) cacheSize = Long64_t(-cacheFactor*fAutoFlush);
4943  else if (fAutoFlush == 0) cacheSize = 0;
4944  else cacheSize = Long64_t(cacheFactor*1.5*fAutoFlush*fZipBytes/(fEntries+1));
4945 
4946  if (cacheSize >= (INT_MAX / 4)) {
4947  cacheSize = INT_MAX / 4;
4948  }
4949 
4950  if (cacheSize < 0) {
4951  cacheSize = 0;
4952  }
4953 
4954  if (cacheSize == 0 && withDefault) {
4955  if (fAutoFlush < 0) cacheSize = -fAutoFlush;
4956  else if (fAutoFlush == 0) cacheSize = 0;
4957  else cacheSize = Long64_t(1.5*fAutoFlush*fZipBytes/(fEntries+1));
4958  }
4959 
4960  return cacheSize;
4961 }
4962 
4963 ////////////////////////////////////////////////////////////////////////////////
4964 /// Return an iterator over the cluster of baskets starting at firstentry.
4965 ///
4966 /// This iterator is not yet supported for TChain object.
4967 /// ~~~ {.cpp}
4968 /// TTree::TClusterIterator clusterIter = tree->GetClusterIterator(entry);
4969 /// Long64_t clusterStart;
4970 /// while( (clusterStart = clusterIter()) < tree->GetEntries() ) {
4971 /// printf("The cluster starts at %lld and ends at %lld (inclusive)\n",clusterStart,clusterIter.GetNextEntry()-1);
4972 /// }
4973 /// ~~~
4974 
4977  // create cache if wanted
4979 
4980  return TClusterIterator(this,firstentry);
4981 }
4982 
4983 ////////////////////////////////////////////////////////////////////////////////
4984 /// Return pointer to the current file.
4985 
4988  if (!fDirectory || fDirectory==gROOT) {
4989  return 0;
4990  }
4991  return fDirectory->GetFile();
4992 }
4993 
4994 ////////////////////////////////////////////////////////////////////////////////
4995 /// Return the number of entries matching the selection.
4996 /// Return -1 in case of errors.
4997 ///
4998 /// If the selection uses any arrays or containers, we return the number
4999 /// of entries where at least one element match the selection.
5000 /// GetEntries is implemented using the selector class TSelectorEntries,
5001 /// which can be used directly (see code in TTreePlayer::GetEntries) for
5002 /// additional option.
5003 /// If SetEventList was used on the TTree or TChain, only that subset
5004 /// of entries will be considered.
5005 
5006 Long64_t TTree::GetEntries(const char *selection)
5008  GetPlayer();
5009  if (fPlayer) {
5010  return fPlayer->GetEntries(selection);
5011  }
5012  return -1;
5013 }
5014 
5015 ////////////////////////////////////////////////////////////////////////////////
5016 /// Return pointer to the 1st Leaf named name in any Branch of this Tree or
5017 /// any branch in the list of friend trees.
5018 
5021  if (fEntries) return fEntries;
5022  if (!fFriends) return 0;
5024  if (!fr) return 0;
5025  TTree *t = fr->GetTree();
5026  if (t==0) return 0;
5027  return t->GetEntriesFriend();
5028 }
5029 
5030 ////////////////////////////////////////////////////////////////////////////////
5031 /// Read all branches of entry and return total number of bytes read.
5032 ///
5033 /// - `getall = 0` : get only active branches
5034 /// - `getall = 1` : get all branches
5035 ///
5036 /// The function returns the number of bytes read from the input buffer.
5037 /// If entry does not exist the function returns 0.
5038 /// If an I/O error occurs, the function returns -1.
5039 ///
5040 /// If the Tree has friends, also read the friends entry.
5041 ///
5042 /// To activate/deactivate one or more branches, use TBranch::SetBranchStatus
5043 /// For example, if you have a Tree with several hundred branches, and you
5044 /// are interested only by branches named "a" and "b", do
5045 /// ~~~ {.cpp}
5046 /// mytree.SetBranchStatus("*",0); //disable all branches
5047 /// mytree.SetBranchStatus("a",1);
5048 /// mytree.SetBranchStatus("b",1);
5049 /// ~~~
5050 /// when calling mytree.GetEntry(i); only branches "a" and "b" will be read.
5051 ///
5052 /// __WARNING!!__
5053 /// If your Tree has been created in split mode with a parent branch "parent.",
5054 /// ~~~ {.cpp}
5055 /// mytree.SetBranchStatus("parent",1);
5056 /// ~~~
5057 /// will not activate the sub-branches of "parent". You should do:
5058 /// ~~~ {.cpp}
5059 /// mytree.SetBranchStatus("parent*",1);
5060 /// ~~~
5061 /// Without the trailing dot in the branch creation you have no choice but to
5062 /// call SetBranchStatus explicitly for each of the sub branches.
5063 ///
5064 /// An alternative is to call directly
5065 /// ~~~ {.cpp}
5066 /// brancha.GetEntry(i)
5067 /// branchb.GetEntry(i);
5068 /// ~~~
5069 /// ## IMPORTANT NOTE
5070 ///
5071 /// By default, GetEntry reuses the space allocated by the previous object
5072 /// for each branch. You can force the previous object to be automatically
5073 /// deleted if you call mybranch.SetAutoDelete(kTRUE) (default is kFALSE).
5074 ///
5075 /// Example:
5076 ///
5077 /// Consider the example in $ROOTSYS/test/Event.h
5078 /// The top level branch in the tree T is declared with:
5079 /// ~~~ {.cpp}
5080 /// Event *event = 0; //event must be null or point to a valid object
5081 /// //it must be initialized
5082 /// T.SetBranchAddress("event",&event);
5083 /// ~~~
5084 /// When reading the Tree, one can choose one of these 3 options:
5085 ///
5086 /// ## OPTION 1
5087 /// ~~~ {.cpp}
5088 /// for (Long64_t i=0;i<nentries;i++) {
5089 /// T.GetEntry(i);
5090 /// // the object event has been filled at this point
5091 /// }
5092 /// ~~~
5093 /// The default (recommended). At the first entry an object of the class
5094 /// Event will be created and pointed by event. At the following entries,
5095 /// event will be overwritten by the new data. All internal members that are
5096 /// TObject* are automatically deleted. It is important that these members
5097 /// be in a valid state when GetEntry is called. Pointers must be correctly
5098 /// initialized. However these internal members will not be deleted if the
5099 /// characters "->" are specified as the first characters in the comment
5100 /// field of the data member declaration.
5101 ///
5102 /// If "->" is specified, the pointer member is read via pointer->Streamer(buf).
5103 /// In this case, it is assumed that the pointer is never null (case of
5104 /// pointer TClonesArray *fTracks in the Event example). If "->" is not
5105 /// specified, the pointer member is read via buf >> pointer. In this case
5106 /// the pointer may be null. Note that the option with "->" is faster to
5107 /// read or write and it also consumes less space in the file.
5108 ///
5109 /// ## OPTION 2
5110 ///
5111 /// The option AutoDelete is set
5112 /// ~~~ {.cpp}
5113 /// TBranch *branch = T.GetBranch("event");
5114 /// branch->SetAddress(&event);
5115 /// branch->SetAutoDelete(kTRUE);
5116 /// for (Long64_t i=0;i<nentries;i++) {
5117 /// T.GetEntry(i);
5118 /// // the object event has been filled at this point
5119 /// }
5120 /// ~~~
5121 /// In this case, at each iteration, the object event is deleted by GetEntry
5122 /// and a new instance of Event is created and filled.
5123 ///
5124 /// ## OPTION 3
5125 /// ~~~ {.cpp}
5126 /// Same as option 1, but you delete yourself the event.
5127 ///
5128 /// for (Long64_t i=0;i<nentries;i++) {
5129 /// delete event;
5130 /// event = 0; // EXTREMELY IMPORTANT
5131 /// T.GetEntry(i);
5132 /// // the object event has been filled at this point
5133 /// }
5134 /// ~~~
5135 /// It is strongly recommended to use the default option 1. It has the
5136 /// additional advantage that functions like TTree::Draw (internally calling
5137 /// TTree::GetEntry) will be functional even when the classes in the file are
5138 /// not available.
5139 ///
5140 /// Note: See the comments in TBranchElement::SetAddress() for the
5141 /// object ownership policy of the underlying (user) data.
5142 
5145 
5146  // We already have been visited while recursively looking
5147  // through the friends tree, let return
5148  if (kGetEntry & fFriendLockStatus) return 0;
5149 
5150  if (entry < 0 || entry >= fEntries) return 0;
5151  Int_t i;
5152  Int_t nbytes = 0;
5153  fReadEntry = entry;
5154  TBranch *branch;
5155 
5156  // create cache if wanted
5158 
5159  Int_t nbranches = fBranches.GetEntriesFast();
5160  Int_t nb=0;
5161  for (i=0;i<nbranches;i++) {
5162  branch = (TBranch*)fBranches.UncheckedAt(i);
5163  nb = branch->GetEntry(entry, getall);
5164  if (nb < 0) return nb;
5165  nbytes += nb;
5166  }
5167 
5168  // GetEntry in list of friends
5169  if (!fFriends) return nbytes;
5170  TFriendLock lock(this,kGetEntry);
5171  TIter nextf(fFriends);
5172  TFriendElement *fe;
5173  while ((fe = (TFriendElement*)nextf())) {
5174  TTree *t = fe->GetTree();
5175  if (t) {
5177  nb = t->GetEntry(t->GetReadEntry(),getall);
5178  } else {
5179  if ( t->LoadTreeFriend(entry,this) >= 0 ) {
5180  nb = t->GetEntry(t->GetReadEntry(),getall);
5181  } else nb = 0;
5182  }
5183  if (nb < 0) return nb;
5184  nbytes += nb;
5185  }
5186  }
5187  return nbytes;
5188 }
5189 
5190 ////////////////////////////////////////////////////////////////////////////////
5191 ///Returns the entry list, set to this tree
5192 
5195  return fEntryList;
5196 }
5197 
5198 ////////////////////////////////////////////////////////////////////////////////
5199 /// Return entry number corresponding to entry.
5200 ///
5201 /// if no TEntryList set returns entry
5202 /// else returns the entry number corresponding to the list index=entry
5203 
5206  if (!fEntryList) {
5207  return entry;
5208  }
5209 
5210  return fEntryList->GetEntry(entry);
5211 }
5212 
5213 ////////////////////////////////////////////////////////////////////////////////
5214 /// Return entry number corresponding to major and minor number.
5215 /// Note that this function returns only the entry number, not the data
5216 /// To read the data corresponding to an entry number, use TTree::GetEntryWithIndex
5217 /// the BuildIndex function has created a table of Long64_t* of sorted values
5218 /// corresponding to val = major<<31 + minor;
5219 /// The function performs binary search in this sorted table.
5220 /// If it finds a pair that matches val, it returns directly the
5221 /// index in the table.
5222 /// If an entry corresponding to major and minor is not found, the function
5223 /// returns the index of the major,minor pair immediately lower than the
5224 /// requested value, ie it will return -1 if the pair is lower than
5225 /// the first entry in the index.
5226 ///
5227 /// See also GetEntryNumberWithIndex
5228 
5231  if (!fTreeIndex) {
5232  return -1;
5233  }
5234  return fTreeIndex->GetEntryNumberWithBestIndex(major, minor);
5235 }
5236 
5237 ////////////////////////////////////////////////////////////////////////////////
5238 /// Return entry number corresponding to major and minor number.
5239 /// Note that this function returns only the entry number, not the data
5240 /// To read the data corresponding to an entry number, use TTree::GetEntryWithIndex
5241 /// the BuildIndex function has created a table of Long64_t* of sorted values
5242 /// corresponding to val = major<<31 + minor;
5243 /// The function performs binary search in this sorted table.
5244 /// If it finds a pair that matches val, it returns directly the
5245 /// index in the table, otherwise it returns -1.
5246 ///
5247 /// See also GetEntryNumberWithBestIndex
5248 
5251  if (!fTreeIndex) {
5252  return -1;
5253  }
5254  return fTreeIndex->GetEntryNumberWithIndex(major, minor);
5255 }
5256 
5257 ////////////////////////////////////////////////////////////////////////////////
5258 /// Read entry corresponding to major and minor number.
5259 ///
5260 /// The function returns the total number of bytes read.
5261 /// If the Tree has friend trees, the corresponding entry with
5262 /// the index values (major,minor) is read. Note that the master Tree
5263 /// and its friend may have different entry serial numbers corresponding
5264 /// to (major,minor).
5265 
5268  // We already have been visited while recursively looking
5269  // through the friends tree, let's return.
5271  return 0;
5272  }
5273  Long64_t serial = GetEntryNumberWithIndex(major, minor);
5274  if (serial < 0) {
5275  return -1;
5276  }
5277  // create cache if wanted
5279 
5280  Int_t i;
5281  Int_t nbytes = 0;
5282  fReadEntry = serial;
5283  TBranch *branch;
5284  Int_t nbranches = fBranches.GetEntriesFast();
5285  Int_t nb;
5286  for (i = 0; i < nbranches; ++i) {
5287  branch = (TBranch*)fBranches.UncheckedAt(i);
5288  nb = branch->GetEntry(serial);
5289  if (nb < 0) return nb;
5290  nbytes += nb;
5291  }
5292  // GetEntry in list of friends
5293  if (!fFriends) return nbytes;
5294  TFriendLock lock(this,kGetEntryWithIndex);
5295  TIter nextf(fFriends);
5296  TFriendElement* fe = 0;
5297  while ((fe = (TFriendElement*) nextf())) {
5298  TTree *t = fe->GetTree();
5299  if (t) {
5300  serial = t->GetEntryNumberWithIndex(major,minor);
5301  if (serial <0) return -nbytes;
5302  nb = t->GetEntry(serial);
5303  if (nb < 0) return nb;
5304  nbytes += nb;
5305  }
5306  }
5307  return nbytes;
5308 }
5309 
5310 ////////////////////////////////////////////////////////////////////////////////
5311 /// Return a pointer to the TTree friend whose name or alias is 'friendname.
5312 
5313 TTree* TTree::GetFriend(const char *friendname) const
5315 
5316  // We already have been visited while recursively
5317  // looking through the friends tree, let's return.
5318  if (kGetFriend & fFriendLockStatus) {
5319  return 0;
5320  }
5321  if (!fFriends) {
5322  return 0;
5323  }
5324  TFriendLock lock(const_cast<TTree*>(this), kGetFriend);
5325  TIter nextf(fFriends);
5326  TFriendElement* fe = 0;
5327  while ((fe = (TFriendElement*) nextf())) {
5328  if (strcmp(friendname,fe->GetName())==0
5329  || strcmp(friendname,fe->GetTreeName())==0) {
5330  return fe->GetTree();
5331  }
5332  }
5333  // After looking at the first level,
5334  // let's see if it is a friend of friends.
5335  nextf.Reset();
5336  fe = 0;
5337  while ((fe = (TFriendElement*) nextf())) {
5338  TTree *res = fe->GetTree()->GetFriend(friendname);
5339  if (res) {
5340  return res;
5341  }
5342  }
5343  return 0;
5344 }
5345 
5346 ////////////////////////////////////////////////////////////////////////////////
5347 /// If the 'tree' is a friend, this method returns its alias name.
5348 ///
5349 /// This alias is an alternate name for the tree.
5350 ///
5351 /// It can be used in conjunction with a branch or leaf name in a TTreeFormula,
5352 /// to specify in which particular tree the branch or leaf can be found if
5353 /// the friend trees have branches or leaves with the same name as the master
5354 /// tree.
5355 ///
5356 /// It can also be used in conjunction with an alias created using
5357 /// TTree::SetAlias in a TTreeFormula, e.g.:
5358 /// ~~~ {.cpp}
5359 /// maintree->Draw("treealias.fPx - treealias.myAlias");
5360 /// ~~~
5361 /// where fPx is a branch of the friend tree aliased as 'treealias' and 'myAlias'
5362 /// was created using TTree::SetAlias on the friend tree.
5363 ///
5364 /// However, note that 'treealias.myAlias' will be expanded literally,
5365 /// without remembering that it comes from the aliased friend and thus
5366 /// the branch name might not be disambiguated properly, which means
5367 /// that you may not be able to take advantage of this feature.
5368 ///
5369 
5370 const char* TTree::GetFriendAlias(TTree* tree) const
5372  if ((tree == this) || (tree == GetTree())) {
5373  return 0;
5374  }
5375 
5376  // We already have been visited while recursively
5377  // looking through the friends tree, let's return.
5379  return 0;
5380  }
5381  if (!fFriends) {
5382  return 0;
5383  }
5384  TFriendLock lock(const_cast<TTree*>(this), kGetFriendAlias);
5385  TIter nextf(fFriends);
5386  TFriendElement* fe = 0;
5387  while ((fe = (TFriendElement*) nextf())) {
5388  TTree* t = fe->GetTree();
5389  if (t == tree) {
5390  return fe->GetName();
5391  }
5392  // Case of a chain:
5393  if (t->GetTree() == tree) {
5394  return fe->GetName();
5395  }
5396  }
5397  // After looking at the first level,
5398  // let's see if it is a friend of friends.
5399  nextf.Reset();
5400  fe = 0;
5401  while ((fe = (TFriendElement*) nextf())) {
5402  const char* res = fe->GetTree()->GetFriendAlias(tree);
5403  if (res) {
5404  return res;
5405  }
5406  }
5407  return 0;
5408 }
5409 
5410 ////////////////////////////////////////////////////////////////////////////////
5411 /// Creates a new iterator that will go through all the leaves on the tree itself and its friend.
5412 
5415  return new TTreeFriendLeafIter(this, dir);
5416 }
5417 
5418 ////////////////////////////////////////////////////////////////////////////////
5419 /// Return pointer to the 1st Leaf named name in any Branch of this
5420 /// Tree or any branch in the list of friend trees.
5421 ///
5422 /// The leaf name can contain the name of a friend tree with the
5423 /// syntax: friend_dir_and_tree.full_leaf_name
5424 /// the friend_dir_and_tree can be of the form:
5425 /// ~~~ {.cpp}
5426 /// TDirectoryName/TreeName
5427 /// ~~~
5428 
5429 TLeaf* TTree::GetLeafImpl(const char* branchname, const char *leafname)
5431  TLeaf *leaf = 0;
5432  if (branchname) {
5433  TBranch *branch = FindBranch(branchname);
5434  if (branch) {
5435  leaf = branch->GetLeaf(leafname);
5436  if (leaf) {
5437  return leaf;
5438  }
5439  }
5440  }
5441  TIter nextl(GetListOfLeaves());
5442  while ((leaf = (TLeaf*)nextl())) {
5443  if (strcmp(leaf->GetName(),leafname)) continue;
5444  if (branchname) {
5445  UInt_t nbch = strlen(branchname);
5446  TBranch *br = leaf->GetBranch();
5447  const char* brname = br->GetName();
5448  TBranch *mother = br->GetMother();
5449  if (strncmp(brname,branchname,nbch)) {
5450  if (mother != br) {
5451  const char *mothername = mother->GetName();
5452  UInt_t motherlen = strlen(mothername);
5453  if (nbch > motherlen && strncmp(mothername,branchname,motherlen)==0 && (mothername[motherlen-1]=='.' || branchname[motherlen]=='.')) {
5454  // The left part of the requested name match the name of the mother, let's see if the right part match the name of the branch.
5455  if (strncmp(brname,branchname+motherlen+1,nbch-motherlen-1)) {
5456  // No it does not
5457  continue;
5458  } // else we have match so we can proceed.
5459  } else {
5460  // no match
5461  continue;
5462  }
5463  } else {
5464  continue;
5465  }
5466  }
5467  // The start of the branch name is identical to the content
5468  // of 'aname' before the first '/'.
5469  // Let's make sure that it is not longer (we are trying
5470  // to avoid having jet2/value match the branch jet23
5471  if ((strlen(brname) > nbch) && (brname[nbch] != '.') && (brname[nbch] != '[')) {
5472  continue;
5473  }
5474  }
5475  return leaf;
5476  }
5477  if (!fFriends) return 0;
5478  TFriendLock lock(this,kGetLeaf);
5479  TIter next(fFriends);
5480  TFriendElement *fe;
5481  while ((fe = (TFriendElement*)next())) {
5482  TTree *t = fe->GetTree();
5483  if (t) {
5484  leaf = t->GetLeaf(leafname);
5485  if (leaf) return leaf;
5486  }
5487  }
5488 
5489  //second pass in the list of friends when the leaf name
5490  //is prefixed by the tree name
5491  TString strippedArg;
5492  next.Reset();
5493  while ((fe = (TFriendElement*)next())) {
5494  TTree *t = fe->GetTree();
5495  if (t==0) continue;
5496  char *subname = (char*)strstr(leafname,fe->GetName());
5497  if (subname != leafname) continue;
5498  Int_t l = strlen(fe->GetName());
5499  subname += l;
5500  if (*subname != '.') continue;
5501  subname++;
5502  strippedArg += subname;
5503  leaf = t->GetLeaf(branchname,subname);
5504  if (leaf) return leaf;
5505  }
5506  return 0;
5507 }
5508 
5509 ////////////////////////////////////////////////////////////////////////////////
5510 /// Return pointer to the 1st Leaf named name in any Branch of this
5511 /// Tree or any branch in the list of friend trees.
5512 ///
5513 /// The leaf name can contain the name of a friend tree with the
5514 /// syntax: friend_dir_and_tree.full_leaf_name
5515 /// the friend_dir_and_tree can be of the form:
5516 ///
5517 /// TDirectoryName/TreeName
5518 
5519 TLeaf* TTree::GetLeaf(const char* branchname, const char *leafname)
5521  if (leafname == 0) return 0;
5522 
5523  // We already have been visited while recursively looking
5524  // through the friends tree, let return
5525  if (kGetLeaf & fFriendLockStatus) {
5526  return 0;
5527  }
5528 
5529  return GetLeafImpl(branchname,leafname);
5530 }
5531 
5532 ////////////////////////////////////////////////////////////////////////////////
5533 /// Return pointer to the 1st Leaf named name in any Branch of this
5534 /// Tree or any branch in the list of friend trees.
5535 ///
5536 /// aname may be of the form branchname/leafname
5537 
5538 TLeaf* TTree::GetLeaf(const char* aname)
5540  if (aname == 0) return 0;
5541 
5542  // We already have been visited while recursively looking
5543  // through the friends tree, let return
5544  if (kGetLeaf & fFriendLockStatus) {
5545  return 0;
5546  }
5547  char* slash = (char*) strrchr(aname, '/');
5548  char* name = 0;
5549  UInt_t nbch = 0;
5550  if (slash) {
5551  name = slash + 1;
5552  nbch = slash - aname;
5553  TString brname(aname,nbch);
5554  return GetLeafImpl(brname.Data(),name);
5555  } else {
5556  return GetLeafImpl(0,aname);
5557  }
5558 }
5559 
5560 ////////////////////////////////////////////////////////////////////////////////
5561 /// Return maximum of column with name columname.
5562 /// if the Tree has an associated TEventList or TEntryList, the maximum
5563 /// is computed for the entries in this list.
5564 
5565 Double_t TTree::GetMaximum(const char* columname)
5567  TLeaf* leaf = this->GetLeaf(columname);
5568  if (!leaf) {
5569  return 0;
5570  }
5571 
5572  // create cache if wanted
5574 
5575  TBranch* branch = leaf->GetBranch();
5576  Double_t cmax = -DBL_MAX;
5577  for (Long64_t i = 0; i < fEntries; ++i) {
5578  Long64_t entryNumber = this->GetEntryNumber(i);
5579  if (entryNumber < 0) break;
5580  branch->GetEntry(entryNumber);
5581  for (Int_t j = 0; j < leaf->GetLen(); ++j) {
5582  Double_t val = leaf->GetValue(j);
5583  if (val > cmax) {
5584  cmax = val;
5585  }
5586  }
5587  }
5588  return cmax;
5589 }
5590 
5591 ////////////////////////////////////////////////////////////////////////////////
5592 /// Static function which returns the tree file size limit in bytes.
5593 
5596  return fgMaxTreeSize;
5597 }
5598 
5599 ////////////////////////////////////////////////////////////////////////////////
5600 /// Return minimum of column with name columname.
5601 /// if the Tree has an associated TEventList or TEntryList, the minimum
5602 /// is computed for the entries in this list.
5603 
5604 Double_t TTree::GetMinimum(const char* columname)
5606  TLeaf* leaf = this->GetLeaf(columname);
5607  if (!leaf) {
5608  return 0;
5609  }
5610 
5611  // create cache if wanted
5613 
5614  TBranch* branch = leaf->GetBranch();
5615  Double_t cmin = DBL_MAX;
5616  for (Long64_t i = 0; i < fEntries; ++i) {
5617  Long64_t entryNumber = this->GetEntryNumber(i);
5618  if (entryNumber < 0) break;
5619  branch->GetEntry(entryNumber);
5620  for (Int_t j = 0;j < leaf->GetLen(); ++j) {
5621  Double_t val = leaf->GetValue(j);
5622  if (val < cmin) {
5623  cmin = val;
5624  }
5625  }
5626  }
5627  return cmin;
5628 }
5629 
5630 ////////////////////////////////////////////////////////////////////////////////
5631 /// Load the TTreePlayer (if not already done).
5632 
5635  if (fPlayer) {
5636  return fPlayer;
5637  }
5639  return fPlayer;
5640 }
5641 
5642 ////////////////////////////////////////////////////////////////////////////////
5643 /// Find and return the TTreeCache registered with the file and which may
5644 /// contain branches for us. If create is true and there is no cache
5645 /// a new cache is created with default size.
5646 
5647 TTreeCache *TTree::GetReadCache(TFile *file, Bool_t create /* = kFALSE */ )
5649  TTreeCache *pe = dynamic_cast<TTreeCache*>(file->GetCacheRead(this));
5650  if (pe && pe->GetTree() != this) pe = 0;
5651  if (create && !pe) {
5653  pe = dynamic_cast<TTreeCache*>(file->GetCacheRead(this));
5654  if (pe && pe->GetTree() != this) pe = 0;
5655  }
5656  return pe;
5657 }
5658 
5659 ////////////////////////////////////////////////////////////////////////////////
5660 /// Return a pointer to the list containing user objects associated to this tree.
5661 ///
5662 /// The list is automatically created if it does not exist.
5663 ///
5664 /// WARNING: By default the TTree destructor will delete all objects added
5665 /// to this list. If you do not want these objects to be deleted,
5666 /// call:
5667 ///
5668 /// mytree->GetUserInfo()->Clear();
5669 ///
5670 /// before deleting the tree.
5671 
5674  if (!fUserInfo) {
5675  fUserInfo = new TList();
5676  fUserInfo->SetName("UserInfo");
5677  }
5678  return fUserInfo;
5679 }
5680 
5681 ////////////////////////////////////////////////////////////////////////////////
5682 /// Appends the cluster range information stored in 'fromtree' to this tree,
5683 /// including the value of fAutoFlush.
5684 ///
5685 /// This is used when doing a fast cloning (by TTreeCloner).
5686 /// See also fAutoFlush and fAutoSave if needed.
5687 
5688 void TTree::ImportClusterRanges(TTree *fromtree)
5690  Long64_t autoflush = fromtree->GetAutoFlush();
5691  if (fNClusterRange || fromtree->fNClusterRange) {
5692  Int_t newsize = fNClusterRange + 1 + fromtree->fNClusterRange;
5693  if (newsize > fMaxClusterRange) {
5694  if (fMaxClusterRange) {
5696  newsize*sizeof(Long64_t),fMaxClusterRange*sizeof(Long64_t));
5698  newsize*sizeof(Long64_t),fMaxClusterRange*sizeof(Long64_t));
5699  fMaxClusterRange = newsize;
5700  } else {
5701  fMaxClusterRange = newsize;
5704  }
5705  }
5708  ++fNClusterRange;
5709  for (Int_t i = 0 ; i < fromtree->fNClusterRange; ++i) {
5711  fClusterSize[fNClusterRange] = fromtree->fClusterSize[i];
5712  ++fNClusterRange;
5713  }
5714  fAutoFlush = autoflush;
5715  } else {
5716  SetAutoFlush( autoflush );
5717  }
5718  Long64_t autosave = GetAutoSave();
5719  if (autoflush > 0 && autosave > 0) {
5720  SetAutoSave( autoflush*(autosave/autoflush) );
5721  }
5722 }
5723 
5724 ////////////////////////////////////////////////////////////////////////////////
5725 /// Keep a maximum of fMaxEntries in memory.
5726 
5727 void TTree::KeepCircular()
5730  Long64_t maxEntries = fMaxEntries - (fMaxEntries / 10);
5731  for (Int_t i = 0; i < nb; ++i) {
5732  TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
5733  branch->KeepCircular(maxEntries);
5734  }
5735  if (fNClusterRange) {
5736  Long64_t entriesOffset = fEntries - maxEntries;
5737  Int_t oldsize = fNClusterRange;
5738  for(Int_t i = 0, j = 0; j < oldsize; ++j) {
5739  if (fClusterRangeEnd[j] > entriesOffset) {
5740  fClusterRangeEnd[i] = fClusterRangeEnd[j] - entriesOffset;
5741  ++i;
5742  } else {
5743  --fNClusterRange;
5744  }
5745  }
5746  }
5747  fEntries = maxEntries;
5748  fReadEntry = -1;
5749 }
5750 
5751 ////////////////////////////////////////////////////////////////////////////////
5752 /// Read in memory all baskets from all branches up to the limit of maxmemory bytes.
5753 ///
5754 /// If maxmemory is non null and positive SetMaxVirtualSize is called
5755 /// with this value. Default for maxmemory is 2000000000 (2 Gigabytes).
5756 /// The function returns the total number of baskets read into memory
5757 /// if negative an error occurred while loading the branches.
5758 /// This method may be called to force branch baskets in memory
5759 /// when random access to branch entries is required.
5760 /// If random access to only a few branches is required, you should
5761 /// call directly TBranch::LoadBaskets.
5762 
5765  if (maxmemory > 0) SetMaxVirtualSize(maxmemory);
5766 
5768  TLeaf *leaf;
5769  Int_t nimported = 0;
5770  while ((leaf=(TLeaf*)next())) {
5771  nimported += leaf->GetBranch()->LoadBaskets();//break;
5772  }
5773  return nimported;
5774 }
5775 
5776 ////////////////////////////////////////////////////////////////////////////////
5777 /// Set current entry.
5778 ///
5779 /// Returns -2 if entry does not exist (just as TChain::LoadTree()).
5780 ///
5781 /// Note: This function is overloaded in TChain.
5782 ///
5783 
5786  // We already have been visited while recursively looking
5787  // through the friends tree, let return
5788  if (kLoadTree & fFriendLockStatus) {
5789  // We need to return a negative value to avoid a circular list of friend
5790  // to think that there is always an entry somewhere in the list.
5791  return -1;
5792  }
5793 
5794  if (fNotify) {
5795  if (fReadEntry < 0) {
5796  fNotify->Notify();
5797  }
5798  }
5799  fReadEntry = entry;
5800 
5801  Bool_t friendHasEntry = kFALSE;
5802  if (fFriends) {
5803  // Set current entry in friends as well.
5804  //
5805  // An alternative would move this code to each of the
5806  // functions calling LoadTree (and to overload a few more).
5807  Bool_t needUpdate = kFALSE;
5808  {
5809  // This scope is need to insure the lock is released at the right time
5810  TIter nextf(fFriends);
5811  TFriendLock lock(this, kLoadTree);
5812  TFriendElement* fe = 0;
5813  while ((fe = (TFriendElement*) nextf())) {
5815  // This friend element was added by the chain that owns this
5816  // tree, the chain will deal with loading the correct entry.
5817  continue;
5818  }
5819  TTree* friendTree = fe->GetTree();
5820  if (friendTree == 0) {
5821  // Somehow we failed to retrieve the friend TTree.
5822  } else if (friendTree->IsA() == TTree::Class()) {
5823  // Friend is actually a tree.
5824  if (friendTree->LoadTreeFriend(entry, this) >= 0) {
5825  friendHasEntry = kTRUE;
5826  }
5827  } else {
5828  // Friend is actually a chain.
5829  // FIXME: This logic should be in the TChain override.
5830  Int_t oldNumber = friendTree->GetTreeNumber();
5831  if (friendTree->LoadTreeFriend(entry, this) >= 0) {
5832  friendHasEntry = kTRUE;
5833  }
5834  Int_t newNumber = friendTree->GetTreeNumber();
5835  if (oldNumber != newNumber) {
5836  // We can not just compare the tree pointers because they could be reused.
5837  // So we compare the tree number instead.
5838  needUpdate = kTRUE;
5839  }
5840  }
5841  } // for each friend
5842  }
5843  if (needUpdate) {
5844  //update list of leaves in all TTreeFormula of the TTreePlayer (if any)
5845  if (fPlayer) {
5847  }
5848  //Notify user if requested
5849  if (fNotify) {
5850  fNotify->Notify();
5851  }
5852  }
5853  }
5854 
5855  if ((fReadEntry >= fEntries) && !friendHasEntry) {
5856  fReadEntry = -1;
5857  return -2;
5858  }
5859  return fReadEntry;
5860 }
5861 
5862 ////////////////////////////////////////////////////////////////////////////////
5863 /// Load entry on behalf of our master tree, we may use an index.
5864 ///
5865 /// Called by LoadTree() when the masterTree looks for the entry
5866 /// number in a friend tree (us) corresponding to the passed entry
5867 /// number in the masterTree.
5868 ///
5869 /// If we have no index, our entry number and the masterTree entry
5870 /// number are the same.
5871 ///
5872 /// If we *do* have an index, we must find the (major, minor) value pair
5873 /// in masterTree to locate our corresponding entry.
5874 ///
5875 
5878  if (!fTreeIndex) {
5879  return LoadTree(entry);
5880  }
5881  return LoadTree(fTreeIndex->GetEntryNumberFriend(masterTree));
5882 }
5883 
5884 ////////////////////////////////////////////////////////////////////////////////
5885 /// Generate a skeleton analysis class for this tree.
5886 ///
5887 /// The following files are produced: classname.h and classname.C.
5888 /// If classname is 0, classname will be called "nameoftree".
5889 ///
5890 /// The generated code in classname.h includes the following:
5891 ///
5892 /// - Identification of the original tree and the input file name.
5893 /// - Definition of an analysis class (data members and member functions).
5894 /// - The following member functions:
5895 /// - constructor (by default opening the tree file),
5896 /// - GetEntry(Long64_t entry),
5897 /// - Init(TTree* tree) to initialize a new TTree,
5898 /// - Show(Long64_t entry) to read and dump entry.
5899 ///
5900 /// The generated code in classname.C includes only the main
5901 /// analysis function Loop.
5902 ///
5903 /// To use this function:
5904 ///
5905 /// - Open your tree file (eg: TFile f("myfile.root");)
5906 /// - T->MakeClass("MyClass");
5907 ///
5908 /// where T is the name of the TTree in file myfile.root,
5909 /// and MyClass.h, MyClass.C the name of the files created by this function.
5910 /// In a ROOT session, you can do:
5911 /// ~~~ {.cpp}
5912 /// root > .L MyClass.C
5913 /// root > MyClass* t = new MyClass;
5914 /// root > t->GetEntry(12); // Fill data members of t with entry number 12.
5915 /// root > t->Show(); // Show values of entry 12.
5916 /// root > t->Show(16); // Read and show values of entry 16.
5917 /// root > t->Loop(); // Loop on all entries.
5918 /// ~~~
5919 /// NOTE: Do not use the code generated for a single TTree which is part
5920 /// of a TChain to process that entire TChain. The maximum dimensions
5921 /// calculated for arrays on the basis of a single TTree from the TChain
5922 /// might be (will be!) too small when processing all of the TTrees in
5923 /// the TChain. You must use myChain.MakeClass() to generate the code,
5924 /// not myTree.MakeClass(...).
5925 
5926 Int_t TTree::MakeClass(const char* classname, Option_t* option)
5928  GetPlayer();
5929  if (!fPlayer) {
5930  return 0;
5931  }
5932  return fPlayer->MakeClass(classname, option);
5933 }
5934 
5935 ////////////////////////////////////////////////////////////////////////////////
5936 /// Generate a skeleton function for this tree.
5937 ///
5938 /// The function code is written on filename.
5939 /// If filename is 0, filename will be called nameoftree.C
5940 ///
5941 /// The generated code includes the following:
5942 /// - Identification of the original Tree and Input file name,
5943 /// - Opening the Tree file,
5944 /// - Declaration of Tree variables,
5945 /// - Setting of branches addresses,
5946 /// - A skeleton for the entry loop.
5947 ///
5948 /// To use this function:
5949 ///
5950 /// - Open your Tree file (eg: TFile f("myfile.root");)
5951 /// - T->MakeCode("MyAnalysis.C");
5952 ///
5953 /// where T is the name of the TTree in file myfile.root
5954 /// and MyAnalysis.C the name of the file created by this function.
5955 ///
5956 /// NOTE: Since the implementation of this function, a new and better
5957 /// function TTree::MakeClass() has been developed.
5958 
5959 Int_t TTree::MakeCode(const char* filename)
5961  Warning("MakeCode", "MakeCode is obsolete. Use MakeClass or MakeSelector instead");
5962 
5963  GetPlayer();
5964  if (!fPlayer) return 0;
5965  return fPlayer->MakeCode(filename);
5966 }
5967 
5968 ////////////////////////////////////////////////////////////////////////////////
5969 /// Generate a skeleton analysis class for this Tree using TBranchProxy.
5970 ///
5971 /// TBranchProxy is the base of a class hierarchy implementing an
5972 /// indirect access to the content of the branches of a TTree.
5973 ///
5974 /// "proxyClassname" is expected to be of the form:
5975 /// ~~~ {.cpp}
5976 /// [path/]fileprefix
5977 /// ~~~
5978 /// The skeleton will then be generated in the file:
5979 /// ~~~ {.cpp}
5980 /// fileprefix.h
5981 /// ~~~
5982 /// located in the current directory or in 'path/' if it is specified.
5983 /// The class generated will be named 'fileprefix'
5984 ///
5985 /// "macrofilename" and optionally "cutfilename" are expected to point
5986 /// to source files which will be included by the generated skeleton.
5987 /// Method of the same name as the file(minus the extension and path)
5988 /// will be called by the generated skeleton's Process method as follow:
5989 /// ~~~ {.cpp}
5990 /// [if (cutfilename())] htemp->Fill(macrofilename());
5991 /// ~~~
5992 /// "option" can be used select some of the optional features during
5993 /// the code generation. The possible options are:
5994 ///
5995 /// - nohist : indicates that the generated ProcessFill should not fill the histogram.
5996 ///
5997 /// 'maxUnrolling' controls how deep in the class hierarchy does the
5998 /// system 'unroll' classes that are not split. Unrolling a class
5999 /// allows direct access to its data members (this emulates the behavior
6000 /// of TTreeFormula).
6001 ///
6002 /// The main features of this skeleton are:
6003 ///
6004 /// * on-demand loading of branches
6005 /// * ability to use the 'branchname' as if it was a data member
6006 /// * protection against array out-of-bounds errors
6007 /// * ability to use the branch data as an object (when the user code is available)
6008 ///
6009 /// For example with Event.root, if
6010 /// ~~~ {.cpp}
6011 /// Double_t somePx = fTracks.fPx[2];
6012 /// ~~~
6013 /// is executed by one of the method of the skeleton,
6014 /// somePx will updated with the current value of fPx of the 3rd track.
6015 ///
6016 /// Both macrofilename and the optional cutfilename are expected to be
6017 /// the name of source files which contain at least a free standing
6018 /// function with the signature:
6019 /// ~~~ {.cpp}
6020 /// x_t macrofilename(); // i.e function with the same name as the file
6021 /// ~~~
6022 /// and
6023 /// ~~~ {.cpp}
6024 /// y_t cutfilename(); // i.e function with the same name as the file
6025 /// ~~~
6026 /// x_t and y_t needs to be types that can convert respectively to a double
6027 /// and a bool (because the skeleton uses:
6028 ///
6029 /// if (cutfilename()) htemp->Fill(macrofilename());
6030 ///
6031 /// These two functions are run in a context such that the branch names are
6032 /// available as local variables of the correct (read-only) type.
6033 ///
6034 /// Note that if you use the same 'variable' twice, it is more efficient
6035 /// to 'cache' the value. For example:
6036 /// ~~~ {.cpp}
6037 /// Int_t n = fEventNumber; // Read fEventNumber
6038 /// if (n<10 || n>10) { ... }
6039 /// ~~~
6040 /// is more efficient than
6041 /// ~~~ {.cpp}
6042 /// if (fEventNumber<10 || fEventNumber>10)
6043 /// ~~~
6044 /// Also, optionally, the generated selector will also call methods named
6045 /// macrofilename_methodname in each of 6 main selector methods if the method
6046 /// macrofilename_methodname exist (Where macrofilename is stripped of its
6047 /// extension).
6048 ///
6049 /// Concretely, with the script named h1analysisProxy.C,
6050 ///
6051 /// - The method calls the method (if it exist)
6052 /// - Begin -> void h1analysisProxy_Begin(TTree*);
6053 /// - SlaveBegin -> void h1analysisProxy_SlaveBegin(TTree*);
6054 /// - Notify -> Bool_t h1analysisProxy_Notify();
6055 /// - Process -> Bool_t h1analysisProxy_Process(Long64_t);
6056 /// - SlaveTerminate -> void h1analysisProxy_SlaveTerminate();
6057 /// - Terminate -> void h1analysisProxy_Terminate();
6058 ///
6059 /// If a file name macrofilename.h (or .hh, .hpp, .hxx, .hPP, .hXX) exist
6060 /// it is included before the declaration of the proxy class. This can
6061 /// be used in particular to insure that the include files needed by
6062 /// the macro file are properly loaded.
6063 ///
6064 /// The default histogram is accessible via the variable named 'htemp'.
6065 ///
6066 /// If the library of the classes describing the data in the branch is
6067 /// loaded, the skeleton will add the needed #include statements and
6068 /// give the ability to access the object stored in the branches.
6069 ///
6070 /// To draw px using the file hsimple.root (generated by the
6071 /// hsimple.C tutorial), we need a file named hsimple.cxx:
6072 /// ~~~ {.cpp}
6073 /// double hsimple() {
6074 /// return px;
6075 /// }
6076 /// ~~~
6077 /// MakeProxy can then be used indirectly via the TTree::Draw interface
6078 /// as follow:
6079 /// ~~~ {.cpp}
6080 /// new TFile("hsimple.root")
6081 /// ntuple->Draw("hsimple.cxx");
6082 /// ~~~
6083 /// A more complete example is available in the tutorials directory:
6084 /// h1analysisProxy.cxx , h1analysProxy.h and h1analysisProxyCut.C
6085 /// which reimplement the selector found in h1analysis.C
6086 
6087 Int_t TTree::MakeProxy(const char* proxyClassname, const char* macrofilename, const char* cutfilename, const char* option, Int_t maxUnrolling)
6089  GetPlayer();
6090  if (!fPlayer) return 0;
6091  return fPlayer->MakeProxy(proxyClassname,macrofilename,cutfilename,option,maxUnrolling);
6092 }
6093 
6094 ////////////////////////////////////////////////////////////////////////////////
6095 /// Generate skeleton selector class for this tree.
6096 ///
6097 /// The following files are produced: selector.h and selector.C.
6098 /// If selector is 0, the selector will be called "nameoftree".
6099 /// The option can be used to specify the branches that will have a data member.
6100 /// - If option is "=legacy", a pre-ROOT6 selector will be generated (data
6101 /// members and branch pointers instead of TTreeReaders).
6102 /// - If option is empty, readers will be generated for each leaf.
6103 /// - If option is "@", readers will be generated for the topmost branches.
6104 /// - Individual branches can also be picked by their name:
6105 /// - "X" generates readers for leaves of X.
6106 /// - "@X" generates a reader for X as a whole.
6107 /// - "@X;Y" generates a reader for X as a whole and also readers for the
6108 /// leaves of Y.
6109 /// - For further examples see the figure below.
6110 ///
6111 /// \image html ttree_makeselector_option_examples.png
6112 ///
6113 /// The generated code in selector.h includes the following:
6114 /// - Identification of the original Tree and Input file name
6115 /// - Definition of selector class (data and functions)
6116 /// - The following class functions:
6117 /// - constructor and destructor
6118 /// - void Begin(TTree *tree)
6119 /// - void SlaveBegin(TTree *tree)
6120 /// - void Init(TTree *tree)
6121 /// - Bool_t Notify()
6122 /// - Bool_t Process(Long64_t entry)
6123 /// - void Terminate()
6124 /// - void SlaveTerminate()
6125 ///
6126 /// The class selector derives from TSelector.
6127 /// The generated code in selector.C includes empty functions defined above.
6128 ///
6129 /// To use this function:
6130 ///
6131 /// - connect your Tree file (eg: `TFile f("myfile.root");`)
6132 /// - `T->MakeSelector("myselect");`
6133 ///
6134 /// where T is the name of the Tree in file myfile.root
6135 /// and myselect.h, myselect.C the name of the files created by this function.
6136 /// In a ROOT session, you can do:
6137 /// ~~~ {.cpp}
6138 /// root > T->Process("myselect.C")
6139 /// ~~~
6140 
6141 Int_t TTree::MakeSelector(const char* selector, Option_t* option)
6143  TString opt(option);
6144  if(opt.EqualTo("=legacy", TString::ECaseCompare::kIgnoreCase)) {
6145  return MakeClass(selector, "selector");
6146  } else {
6147  GetPlayer();
6148  if (!fPlayer) return 0;
6149  return fPlayer->MakeReader(selector, option);
6150  }
6151 }
6152 
6153 ////////////////////////////////////////////////////////////////////////////////
6154 /// Check if adding nbytes to memory we are still below MaxVirtualsize.
6155 
6158  if ((fTotalBuffers + nbytes) < fMaxVirtualSize) {
6159  return kFALSE;
6160  }
6161  return kTRUE;
6162 }
6163 
6164 ////////////////////////////////////////////////////////////////////////////////
6165 /// Static function merging the trees in the TList into a new tree.
6166 ///
6167 /// Trees in the list can be memory or disk-resident trees.
6168 /// The new tree is created in the current directory (memory if gROOT).
6169 
6170 TTree* TTree::MergeTrees(TList* li, Option_t* options)
6172  if (!li) return 0;
6173  TIter next(li);
6174  TTree *newtree = 0;
6175  TObject *obj;
6176 
6177  while ((obj=next())) {
6178  if (!obj->InheritsFrom(TTree::Class())) continue;
6179  TTree *tree = (TTree*)obj;
6180  Long64_t nentries = tree->GetEntries();
6181  if (nentries == 0) continue;
6182  if (!newtree) {
6183  newtree = (TTree*)tree->CloneTree();
6184  if (!newtree) continue;
6185 
6186  // Once the cloning is done, separate the trees,
6187  // to avoid as many side-effects as possible
6188  // The list of clones is guaranteed to exist since we
6189  // just cloned the tree.
6190  tree->GetListOfClones()->Remove(newtree);
6191  tree->ResetBranchAddresses();
6192  newtree->ResetBranchAddresses();
6193  continue;
6194  }
6195 
6196  newtree->CopyAddresses(tree);
6197 
6198  newtree->CopyEntries(tree,-1,options);
6199 
6200  tree->ResetBranchAddresses(); // Disconnect from new tree.
6201  }
6202  if (newtree && newtree->GetTreeIndex()) {
6203  newtree->GetTreeIndex()->Append(0,kFALSE); // Force the sorting
6204  }
6205  return newtree;
6206 }
6207 
6208 ////////////////////////////////////////////////////////////////////////////////
6209 /// Merge the trees in the TList into this tree.
6210 ///
6211 /// Returns the total number of entries in the merged tree.
6212 
6215  if (!li) return 0;
6216  Long64_t storeAutoSave = fAutoSave;
6217  // Disable the autosave as the TFileMerge keeps a list of key and deleting the underlying
6218  // key would invalidate its iteration (or require costly measure to not use the deleted keys).
6219  // Also since this is part of a merging operation, the output file is not as precious as in
6220  // the general case since the input file should still be around.
6221  fAutoSave = 0;
6222  TIter next(li);
6223  TTree *tree;
6224  while ((tree = (TTree*)next())) {
6225  if (tree==this) continue;
6226  if (!tree->InheritsFrom(TTree::Class())) {
6227  Error("Add","Attempt to add object of class: %s to a %s", tree->ClassName(), ClassName());
6228  fAutoSave = storeAutoSave;
6229  return -1;
6230  }
6231 
6232  Long64_t nentries = tree->GetEntries();
6233  if (nentries == 0) continue;
6234 
6235  CopyAddresses(tree);
6236 
6237  CopyEntries(tree,-1,options);
6238 
6239  tree->ResetBranchAddresses();
6240  }
6241  fAutoSave = storeAutoSave;
6242  return GetEntries();
6243 }
6244 
6245 ////////////////////////////////////////////////////////////////////////////////
6246 /// Merge the trees in the TList into this tree.
6247 /// If info->fIsFirst is true, first we clone this TTree info the directory
6248 /// info->fOutputDirectory and then overlay the new TTree information onto
6249 /// this TTree object (so that this TTree object is now the appropriate to
6250 /// use for further merging).
6251 ///
6252 /// Returns the total number of entries in the merged tree.
6253 
6256  const char *options = info ? info->fOptions.Data() : "";
6257  if (info && info->fIsFirst && info->fOutputDirectory && info->fOutputDirectory->GetFile() != GetCurrentFile()) {
6259  TTree *newtree = CloneTree(-1, options);
6260  if (newtree) {
6261  newtree->Write();
6262  delete newtree;
6263  }
6264  // Make sure things are really written out to disk before attempting any reading.
6265  info->fOutputDirectory->GetFile()->Flush();
6266  info->fOutputDirectory->ReadTObject(this,this->GetName());
6267  }
6268  if (!li) return 0;
6269  Long64_t storeAutoSave = fAutoSave;
6270  // Disable the autosave as the TFileMerge keeps a list of key and deleting the underlying
6271  // key would invalidate its iteration (or require costly measure to not use the deleted keys).
6272  // Also since this is part of a merging operation, the output file is not as precious as in
6273  // the general case since the input file should still be around.
6274  fAutoSave = 0;
6275  TIter next(li);
6276  TTree *tree;
6277  while ((tree = (TTree*)next())) {
6278  if (tree==this) continue;
6279  if (!tree->InheritsFrom(TTree::Class())) {
6280  Error("Add","Attempt to add object of class: %s to a %s", tree->ClassName(), ClassName());
6281  fAutoSave = storeAutoSave;
6282  return -1;
6283  }
6284  // Copy MakeClass status.
6285  tree->SetMakeClass(fMakeClass);
6286 
6287  // Copy branch addresses.
6288  CopyAddresses(tree);
6289 
6290  CopyEntries(tree,-1,options);
6291 
6292  tree->ResetBranchAddresses();
6293  }
6294  fAutoSave = storeAutoSave;
6295  return GetEntries();
6296 }
6297 
6298 ////////////////////////////////////////////////////////////////////////////////
6299 /// Move a cache from a file to the current file in dir.
6300 /// if src is null no operation is done, if dir is null or there is no
6301 /// current file the cache is deleted.
6302 
6305  if (!src) return;
6306  TFile *dst = (dir && dir != gROOT) ? dir->GetFile() : 0;
6307  if (src == dst) return;
6308 
6309  TTreeCache *pf = GetReadCache(src);
6310  if (dst) {
6311  src->SetCacheRead(0,this);
6312  dst->SetCacheRead(pf, this);
6313  } else {
6314  if (pf) {
6315  pf->WaitFinishPrefetch();
6316  }
6317  src->SetCacheRead(0,this);
6318  delete pf;
6319  }
6320 }
6321 
6322 ////////////////////////////////////////////////////////////////////////////////
6323 /// Function called when loading a new class library.
6324 
6328  TLeaf* leaf = 0;
6329  while ((leaf = (TLeaf*) next())) {
6330  leaf->Notify();
6331  leaf->GetBranch()->Notify();
6332  }
6333  return kTRUE;
6334 }
6335 
6336 ////////////////////////////////////////////////////////////////////////////////
6337 /// This function may be called after having filled some entries in a Tree
6338 /// Using the information in the existing branch buffers, it will reassign
6339 /// new branch buffer sizes to optimize time and memory.
6340 ///
6341 /// The function computes the best values for branch buffer sizes such that
6342 /// the total buffer sizes is less than maxMemory and nearby entries written
6343 /// at the same time.
6344 /// In case the branch compression factor for the data written so far is less
6345 /// than compMin, the compression is disabled.
6346 ///
6347 /// if option ="d" an analysis report is printed.
6348 
6349 void TTree::OptimizeBaskets(ULong64_t maxMemory, Float_t minComp, Option_t *option)
6351  //Flush existing baskets if the file is writable
6352  if (this->GetDirectory()->IsWritable()) this->FlushBaskets();
6353 
6354  TString opt( option );
6355  opt.ToLower();
6356  Bool_t pDebug = opt.Contains("d");
6357  TObjArray *leaves = this->GetListOfLeaves();
6358  Int_t nleaves = leaves->GetEntries();
6359  Double_t treeSize = (Double_t)this->GetTotBytes();
6360 
6361  if (nleaves == 0 || treeSize == 0) {
6362  // We're being called too early, we really have nothing to do ...
6363  return;
6364  }
6365  Double_t aveSize = treeSize/nleaves;
6366  UInt_t bmin = 512;
6367  UInt_t bmax = 256000;
6368  Double_t memFactor = 1;
6369  Int_t i, oldMemsize,newMemsize,oldBaskets,newBaskets;
6370  i = oldMemsize = newMemsize = oldBaskets = newBaskets = 0;
6371 
6372  //we make two passes
6373  //one pass to compute the relative branch buffer sizes
6374  //a second pass to compute the absolute values
6375  for (Int_t pass =0;pass<2;pass++) {
6376  oldMemsize = 0; //to count size of baskets in memory with old buffer size
6377  newMemsize = 0; //to count size of baskets in memory with new buffer size
6378  oldBaskets = 0; //to count number of baskets with old buffer size
6379  newBaskets = 0; //to count number of baskets with new buffer size
6380  for (i=0;i<nleaves;i++) {
6381  TLeaf *leaf = (TLeaf*)leaves->At(i);
6382  TBranch *branch = leaf->GetBranch();
6383  Double_t totBytes = (Double_t)branch->GetTotBytes();
6384  Double_t idealFactor = totBytes/aveSize;
6385  UInt_t sizeOfOneEntry;
6386  if (branch->GetEntries() == 0) {
6387  // There is no data, so let's make a guess ...
6388  sizeOfOneEntry = aveSize;
6389  } else {
6390  sizeOfOneEntry = 1+(UInt_t)(totBytes / (Double_t)branch->GetEntries());
6391  }
6392  Int_t oldBsize = branch->GetBasketSize();
6393  oldMemsize += oldBsize;
6394  oldBaskets += 1+Int_t(totBytes/oldBsize);
6395  Int_t nb = branch->GetListOfBranches()->GetEntries();
6396  if (nb > 0) {
6397  newBaskets += 1+Int_t(totBytes/oldBsize);
6398  continue;
6399  }
6400  Double_t bsize = oldBsize*idealFactor*memFactor; //bsize can be very large !
6401  if (bsize < 0) bsize = bmax;
6402  if (bsize > bmax) bsize = bmax;
6403  UInt_t newBsize = UInt_t(bsize);
6404  newBsize = newBsize - newBsize%512;
6405  if (newBsize < sizeOfOneEntry) newBsize = sizeOfOneEntry;
6406  if (newBsize < bmin) newBsize = bmin;
6407  if (newBsize > 10000000) newBsize = bmax;
6408  if (pass) {
6409  if (pDebug) printf("Changing buffer size from %6d to %6d bytes for %s\n",oldBsize,newBsize,branch->GetName());
6410  branch->SetBasketSize(newBsize);
6411  }
6412  newMemsize += newBsize;
6413  // For this number to be somewhat accurate when newBsize is 'low'
6414  // we do not include any space for meta data in the requested size (newBsize) even-though SetBasketSize will
6415  // not let it be lower than 100+TBranch::fEntryOffsetLen.
6416  newBaskets += 1+Int_t(totBytes/newBsize);
6417  if (pass == 0) continue;
6418  //Reset the compression level in case the compression factor is small
6419  Double_t comp = 1;
6420  if (branch->GetZipBytes() > 0) comp = totBytes/Double_t(branch->GetZipBytes());
6421  if (comp > 1 && comp < minComp) {
6422  if (pDebug) printf("Disabling compression for branch : %s\n",branch->GetName());
6423  branch->SetCompressionSettings(0);
6424  }
6425  }
6426  // coverity[divide_by_zero] newMemsize can not be zero as there is at least one leaf
6427  memFactor = Double_t(maxMemory)/Double_t(newMemsize);
6428  if (memFactor > 100) memFactor = 100;
6429  Double_t bmin_new = bmin*memFactor;
6430  Double_t bmax_new = bmax*memFactor;
6431  static const UInt_t hardmax = 1*1024*1024*1024; // Really, really never give more than 1Gb to a single buffer.
6432 
6433  // Really, really never go lower than 8 bytes (we use this number
6434  // so that the calculation of the number of basket is consistent
6435  // but in fact SetBasketSize will not let the size go below
6436  // TBranch::fEntryOffsetLen + (100 + strlen(branch->GetName())
6437  // (The 2nd part being a slight over estimate of the key length.
6438  static const UInt_t hardmin = 8;
6439  bmin = (bmin_new > hardmax) ? hardmax : ( bmin_new < hardmin ? hardmin : (UInt_t)bmin_new );
6440  bmax = (bmax_new > hardmax) ? bmin : (UInt_t)bmax_new;
6441  }
6442  if (pDebug) {
6443  printf("oldMemsize = %d, newMemsize = %d\n",oldMemsize, newMemsize);
6444  printf("oldBaskets = %d, newBaskets = %d\n",oldBaskets, newBaskets);
6445  }
6446 }
6447 
6448 ////////////////////////////////////////////////////////////////////////////////
6449 /// Interface to the Principal Components Analysis class.
6450 ///
6451 /// Create an instance of TPrincipal
6452 ///
6453 /// Fill it with the selected variables
6454 ///
6455 /// - if option "n" is specified, the TPrincipal object is filled with
6456 /// normalized variables.
6457 /// - If option "p" is specified, compute the principal components
6458 /// - If option "p" and "d" print results of analysis
6459 /// - If option "p" and "h" generate standard histograms
6460 /// - If option "p" and "c" generate code of conversion functions
6461 /// - return a pointer to the TPrincipal object. It is the user responsibility
6462 /// - to delete this object.
6463 /// - The option default value is "np"
6464 ///
6465 /// see TTree::Draw for explanation of the other parameters.
6466 ///
6467 /// The created object is named "principal" and a reference to it
6468 /// is added to the list of specials Root objects.
6469 /// you can retrieve a pointer to the created object via:
6470 /// ~~~ {.cpp}
6471 /// TPrincipal *principal =
6472 /// (TPrincipal*)gROOT->GetListOfSpecials()->FindObject("principal");
6473 /// ~~~
6474 
6475 TPrincipal* TTree::Principal(const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
6477  GetPlayer();
6478  if (fPlayer) {
6479  return fPlayer->Principal(varexp, selection, option, nentries, firstentry);
6480  }
6481  return 0;
6482 }
6483 
6484 ////////////////////////////////////////////////////////////////////////////////
6485 /// Print a summary of the tree contents.
6486 ///
6487 /// - If option contains "all" friend trees are also printed.
6488 /// - If option contains "toponly" only the top level branches are printed.
6489 /// - If option contains "clusters" information about the cluster of baskets is printed.
6490 ///
6491 /// Wildcarding can be used to print only a subset of the branches, e.g.,
6492 /// `T.Print("Elec*")` will print all branches with name starting with "Elec".
6493 
6494 void TTree::Print(Option_t* option) const
6496  // We already have been visited while recursively looking
6497  // through the friends tree, let's return.
6498  if (kPrint & fFriendLockStatus) {
6499  return;
6500  }
6501  Int_t s = 0;
6502  Int_t skey = 0;
6503  if (fDirectory) {
6504  TKey* key = fDirectory->GetKey(GetName());
6505  if (key) {
6506  skey = key->GetKeylen();
6507  s = key->GetNbytes();
6508  }
6509  }
6510  Long64_t total = skey;
6511  if (fZipBytes > 0) {
6512  total += fTotBytes;
6513  }
6514  TBufferFile b(TBuffer::kWrite, 10000);
6515  TTree::Class()->WriteBuffer(b, (TTree*) this);
6516  total += b.Length();
6517  Long64_t file = fZipBytes + s;
6518  Float_t cx = 1;
6519  if (fZipBytes) {
6520  cx = (fTotBytes + 0.00001) / fZipBytes;
6521  }
6522  Printf("******************************************************************************");
6523  Printf("*Tree :%-10s: %-54s *", GetName(), GetTitle());
6524  Printf("*Entries : %8lld : Total = %15lld bytes File Size = %10lld *", fEntries, total, file);
6525  Printf("* : : Tree compression factor = %6.2f *", cx);
6526  Printf("******************************************************************************");
6527 
6528  if (strncmp(option,"clusterRange",strlen("clusters"))==0) {
6529  Printf("%-16s %-16s %-16s %5s",
6530  "Cluster Range #", "Entry Start", "Last Entry", "Size");
6531  Int_t index= 0;
6532  Long64_t clusterRangeStart = 0;
6533  if (fNClusterRange) {
6534  for( ; index < fNClusterRange; ++index) {
6535  Printf("%-16d %-16lld %-16lld %5lld",
6536  index, clusterRangeStart, fClusterRangeEnd[index], fClusterSize[index]);
6537  clusterRangeStart = fClusterRangeEnd[index] + 1;
6538  }
6539  }
6540  Printf("%-16d %-16lld %-16lld %5lld",
6541  index, clusterRangeStart, fEntries - 1, fAutoFlush);
6542  return;
6543  }
6544 
6545  Int_t nl = const_cast<TTree*>(this)->GetListOfLeaves()->GetEntries();
6546  Int_t l;
6547  TBranch* br = 0;
6548  TLeaf* leaf = 0;
6549  if (strstr(option, "toponly")) {
6550  Long64_t *count = new Long64_t[nl];
6551  Int_t keep =0;
6552  for (l=0;l<nl;l++) {
6553  leaf = (TLeaf *)const_cast<TTree*>(this)->GetListOfLeaves()->At(l);
6554  br = leaf->GetBranch();
6555  if (strchr(br->GetName(),'.')) {
6556  count[l] = -1;
6557  count[keep] += br->GetZipBytes();
6558  } else {
6559  keep = l;
6560  count[keep] = br->GetZipBytes();
6561  }
6562  }
6563  for (l=0;l<nl;l++) {
6564  if (count[l] < 0) continue;
6565  leaf = (TLeaf *)const_cast<TTree*>(this)->GetListOfLeaves()->At(l);
6566  br = leaf->GetBranch();
6567  printf("branch: %-20s %9lld\n",br->GetName(),count[l]);
6568  }
6569  delete [] count;
6570  } else {
6571  TString reg = "*";
6572  if (strlen(option) && strchr(option,'*')) reg = option;
6573  TRegexp re(reg,kTRUE);
6574  TIter next(const_cast<TTree*>(this)->GetListOfBranches());
6576  while ((br= (TBranch*)next())) {
6577  TString st = br->GetName();
6578  st.ReplaceAll("/","_");
6579  if (st.Index(re) == kNPOS) continue;
6580  br->Print(option);
6581  }
6582  }
6583 
6584  //print TRefTable (if one)
6585  if (fBranchRef) fBranchRef->Print(option);
6586 
6587  //print friends if option "all"
6588  if (!fFriends || !strstr(option,"all")) return;
6589  TIter nextf(fFriends);
6590  TFriendLock lock(const_cast<TTree*>(this),kPrint);
6591  TFriendElement *fr;
6592  while ((fr = (TFriendElement*)nextf())) {
6593  TTree * t = fr->GetTree();
6594  if (t) t->Print(option);
6595  }
6596 }
6597 
6598 ////////////////////////////////////////////////////////////////////////////////
6599 /// print statistics about the TreeCache for this tree, like
6600 /// ~~~ {.cpp}
6601 /// ******TreeCache statistics for file: cms2.root ******
6602 /// Reading 73921562 bytes in 716 transactions
6603 /// Average transaction = 103.242405 Kbytes
6604 /// Number of blocks in current cache: 202, total size : 6001193
6605 /// ~~~
6606 /// if option = "a" the list of blocks in the cache is printed
6607 
6608 void TTree::PrintCacheStats(Option_t* option) const
6610  TFile *f = GetCurrentFile();
6611  if (!f) return;
6612  TTreeCache *tc = (TTreeCache*)f->GetCacheRead(const_cast<TTree*>(this));
6613  if (tc) tc->Print(option);
6614 }
6615 
6616 ////////////////////////////////////////////////////////////////////////////////
6617 /// Process this tree executing the TSelector code in the specified filename.
6618 /// The return value is -1 in case of error and TSelector::GetStatus() in
6619 /// in case of success.
6620 ///
6621 /// The code in filename is loaded (interpreted or compiled, see below),
6622 /// filename must contain a valid class implementation derived from TSelector,
6623 /// where TSelector has the following member functions:
6624 ///
6625 /// - `Begin()`: called every time a loop on the tree starts,
6626 /// a convenient place to create your histograms.
6627 /// - `SlaveBegin()`: called after Begin(), when on PROOF called only on the
6628 /// slave servers.
6629 /// - `Process()`: called for each event, in this function you decide what
6630 /// to read and fill your histograms.
6631 /// - `SlaveTerminate`: called at the end of the loop on the tree, when on PROOF
6632 /// called only on the slave servers.
6633 /// - `Terminate()`: called at the end of the loop on the tree,
6634 /// a convenient place to draw/fit your histograms.
6635 ///
6636 /// If filename is of the form file.C, the file will be interpreted.
6637 ///
6638 /// If filename is of the form file.C++, the file file.C will be compiled
6639 /// and dynamically loaded.
6640 ///
6641 /// If filename is of the form file.C+, the file file.C will be compiled
6642 /// and dynamically loaded. At next call, if file.C is older than file.o
6643 /// and file.so, the file.C is not compiled, only file.so is loaded.
6644 ///
6645 /// ## NOTE1
6646 ///
6647 /// It may be more interesting to invoke directly the other Process function
6648 /// accepting a TSelector* as argument.eg
6649 /// ~~~ {.cpp}
6650 /// MySelector *selector = (MySelector*)TSelector::GetSelector(filename);
6651 /// selector->CallSomeFunction(..);
6652 /// mytree.Process(selector,..);
6653 /// ~~~
6654 /// ## NOTE2
6655 //
6656 /// One should not call this function twice with the same selector file
6657 /// in the same script. If this is required, proceed as indicated in NOTE1,
6658 /// by getting a pointer to the corresponding TSelector,eg
6659 ///
6660 /// ### workaround 1
6661 /// ~~~ {.cpp}
6662 /// void stubs1() {
6663 /// TSelector *selector = TSelector::GetSelector("h1test.C");
6664 /// TFile *f1 = new TFile("stubs_nood_le1.root");
6665 /// TTree *h1 = (TTree*)f1->Get("h1");
6666 /// h1->Process(selector);
6667 /// TFile *f2 = new TFile("stubs_nood_le1_coarse.root");
6668 /// TTree *h2 = (TTree*)f2->Get("h1");
6669 /// h2->Process(selector);
6670 /// }
6671 /// ~~~
6672 /// or use ACLIC to compile the selector
6673 ///
6674 /// ### workaround 2
6675 /// ~~~ {.cpp}
6676 /// void stubs2() {
6677 /// TFile *f1 = new TFile("stubs_nood_le1.root");
6678 /// TTree *h1 = (TTree*)f1->Get("h1");
6679 /// h1->Process("h1test.C+");
6680 /// TFile *f2 = new TFile("stubs_nood_le1_coarse.root");
6681 /// TTree *h2 = (TTree*)f2->Get("h1");
6682 /// h2->Process("h1test.C+");
6683 /// }
6684 /// ~~~
6685 
6686 Long64_t TTree::Process(const char* filename, Option_t* option, Long64_t nentries, Long64_t firstentry)
6688  GetPlayer();
6689  if (fPlayer) {
6690  return fPlayer->Process(filename, option, nentries, firstentry);
6691  }
6692  return -1;
6693 }
6694 
6695 ////////////////////////////////////////////////////////////////////////////////
6696 /// Process this tree executing the code in the specified selector.
6697 /// The return value is -1 in case of error and TSelector::GetStatus() in
6698 /// in case of success.
6699 ///
6700 /// The TSelector class has the following member functions:
6701 ///
6702 /// - `Begin()`: called every time a loop on the tree starts,
6703 /// a convenient place to create your histograms.
6704 /// - `SlaveBegin()`: called after Begin(), when on PROOF called only on the
6705 /// slave servers.
6706 /// - `Process()`: called for each event, in this function you decide what
6707 /// to read and fill your histograms.
6708 /// - `SlaveTerminate`: called at the end of the loop on the tree, when on PROOF
6709 /// called only on the slave servers.
6710 /// - `Terminate()`: called at the end of the loop on the tree,
6711 /// a convenient place to draw/fit your histograms.
6712 ///
6713 /// If the Tree (Chain) has an associated EventList, the loop is on the nentries
6714 /// of the EventList, starting at firstentry, otherwise the loop is on the
6715 /// specified Tree entries.
6716 
6717 Long64_t TTree::Process(TSelector* selector, Option_t* option, Long64_t nentries, Long64_t firstentry)
6719  GetPlayer();
6720  if (fPlayer) {
6721  return fPlayer->Process(selector, option, nentries, firstentry);
6722  }
6723  return -1;
6724 }
6725 
6726 ////////////////////////////////////////////////////////////////////////////////
6727 /// Make a projection of a tree using selections.
6728 ///
6729 /// Depending on the value of varexp (described in Draw) a 1-D, 2-D, etc.,
6730 /// projection of the tree will be filled in histogram hname.
6731 /// Note that the dimension of hname must match with the dimension of varexp.
6732 ///
6733 
6734 Long64_t TTree::Project(const char* hname, const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
6736  TString var;
6737  var.Form("%s>>%s", varexp, hname);
6738  TString opt("goff");
6739  if (option) {
6740  opt.Form("%sgoff", option);
6741  }
6742  Long64_t nsel = Draw(var, selection, opt, nentries, firstentry);
6743  return nsel;
6744 }
6745 
6746 ////////////////////////////////////////////////////////////////////////////////
6747 /// Loop over entries and return a TSQLResult object containing entries following selection.
6748 
6749 TSQLResult* TTree::Query(const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
6751  GetPlayer();
6752  if (fPlayer) {
6753  return fPlayer->Query(varexp, selection, option, nentries, firstentry);
6754  }
6755  return 0;
6756 }
6757 
6758 ////////////////////////////////////////////////////////////////////////////////
6759 /// Create or simply read branches from filename.
6760 ///
6761 /// if branchDescriptor = "" (default), it is assumed that the Tree descriptor
6762 /// is given in the first line of the file with a syntax like
6763 /// ~~~ {.cpp}
6764 /// A/D:Table[2]/F:Ntracks/I:astring/C
6765 /// ~~~
6766 /// otherwise branchDescriptor must be specified with the above syntax.
6767 ///
6768 /// - If the type of the first variable is not specified, it is assumed to be "/F"
6769 /// - If the type of any other variable is not specified, the type of the previous
6770 /// variable is assumed. eg
6771 /// - `x:y:z` (all variables are assumed of type "F"
6772 /// - `x/D:y:z` (all variables are of type "D"
6773 /// - `x:y/D:z` (x is type "F", y and z of type "D"
6774 ///
6775 /// delimiter allows for the use of another delimiter besides whitespace.
6776 /// This provides support for direct import of common data file formats
6777 /// like csv. If delimiter != ' ' and branchDescriptor == "", then the
6778 /// branch description is taken from the first line in the file, but
6779 /// delimiter is used for the branch names tokenization rather than ':'.
6780 /// Note however that if the values in the first line do not use the
6781 /// /[type] syntax, all variables are assumed to be of type "F".
6782 /// If the filename ends with extensions .csv or .CSV and a delimiter is
6783 /// not specified (besides ' '), the delimiter is automatically set to ','.
6784 ///
6785 /// Lines in the input file starting with "#" are ignored. Leading whitespace
6786 /// for each column data is skipped. Empty lines are skipped.
6787 ///
6788 /// A TBranch object is created for each variable in the expression.
6789 /// The total number of rows read from the file is returned.
6790 ///
6791 /// ## FILLING a TTree WITH MULTIPLE INPUT TEXT FILES
6792 ///
6793 /// To fill a TTree with multiple input text files, proceed as indicated above
6794 /// for the first input file and omit the second argument for subsequent calls
6795 /// ~~~ {.cpp}
6796 /// T.ReadFile("file1.dat","branch descriptor");
6797 /// T.ReadFile("file2.dat");
6798 /// ~~~
6799 
6800 Long64_t TTree::ReadFile(const char* filename, const char* branchDescriptor, char delimiter)
6802  std::ifstream in;
6803  in.open(filename);
6804  if (!in.good()) {
6805  Error("ReadFile","Cannot open file: %s",filename);
6806  return 0;
6807  }
6808  const char* ext = strrchr(filename, '.');
6809  if(ext != NULL && ((strcmp(ext, ".csv") == 0) || (strcmp(ext, ".CSV") == 0)) && delimiter == ' ') {
6810  delimiter = ',';
6811  }
6812  return ReadStream(in, branchDescriptor, delimiter);
6813 }
6814 
6815 ////////////////////////////////////////////////////////////////////////////////
6816 /// Determine which newline this file is using.
6817 /// Return '\\r' for Windows '\\r\\n' as that already terminates.
6818 
6819 char TTree::GetNewlineValue(std::istream &inputStream)
6821  Long_t inPos = inputStream.tellg();
6822  char newline = '\n';
6823  while(1) {
6824  char c = 0;
6825  inputStream.get(c);
6826  if(!inputStream.good()) {
6827  Error("ReadStream","Error reading stream: no newline found.");
6828  return 0;
6829  }
6830  if(c == newline) break;
6831  if(c == '\r') {
6832  newline = '\r';
6833  break;
6834  }
6835  }
6836  inputStream.clear();
6837  inputStream.seekg(inPos);
6838  return newline;
6839 }
6840 
6841 ////////////////////////////////////////////////////////////////////////////////
6842 /// Create or simply read branches from an input stream.
6843 ///
6844 /// See reference information for TTree::ReadFile
6845 
6846 Long64_t TTree::ReadStream(std::istream& inputStream, const char *branchDescriptor, char delimiter)
6848  char newline = GetNewlineValue(inputStream);
6849  std::istream& in = inputStream;
6850  Long64_t nlines = 0;
6851 
6852  TBranch *branch = 0;
6853  Int_t nbranches = fBranches.GetEntries();
6854  if (nbranches == 0) {
6855  char *bdname = new char[4000];
6856  char *bd = new char[100000];
6857  Int_t nch = 0;
6858  if (branchDescriptor) nch = strlen(branchDescriptor);
6859  // branch Descriptor is null, read its definition from the first line in the file
6860  if (!nch) {
6861  do {
6862  in.getline(bd, 100000, newline);
6863  if (!in.good()) {
6864  delete [] bdname;
6865  delete [] bd;
6866  Error("ReadStream","Error reading stream");
6867  return 0;
6868  }
6869  char *cursor = bd;
6870  while( isspace(*cursor) && *cursor != '\n' && *cursor != '\0') {
6871  ++cursor;
6872  }
6873  if (*cursor != '#' && *cursor != '\n' && *cursor != '\0') {
6874  break;
6875  }
6876  } while (true);
6877  ++nlines;
6878  nch = strlen(bd);
6879  } else {
6880  strlcpy(bd,branchDescriptor,100000);
6881  }
6882 
6883  //parse the branch descriptor and create a branch for each element
6884  //separated by ":"
6885  void *address = &bd[90000];
6886  char *bdcur = bd;
6887  TString desc="", olddesc="F";
6888  char bdelim = ':';
6889  if(delimiter != ' ') {
6890  bdelim = delimiter;
6891  if (strchr(bdcur,bdelim)==0 && strchr(bdcur,':') != 0) {
6892  // revert to the default
6893  bdelim = ':';
6894  }
6895  }
6896  while (bdcur) {
6897  char *colon = strchr(bdcur,bdelim);
6898  if (colon) *colon = 0;
6899  strlcpy(bdname,bdcur,4000);
6900  char *slash = strchr(bdname,'/');
6901  if (slash) {
6902  *slash = 0;
6903  desc = bdcur;
6904  olddesc = slash+1;
6905  } else {
6906  desc.Form("%s/%s",bdname,olddesc.Data());
6907  }
6908  char *bracket = strchr(bdname,'[');
6909  if (bracket) {
6910  *bracket = 0;
6911  }
6912  branch = new TBranch(this,bdname,address,desc.Data(),32000);
6913  if (branch->IsZombie()) {
6914  delete branch;
6915  Warning("ReadStream","Illegal branch definition: %s",bdcur);
6916  } else {
6917  fBranches.Add(branch);
6918  branch->SetAddress(0);
6919  }
6920  if (!colon)break;
6921  bdcur = colon+1;
6922  }
6923  delete [] bdname;
6924  delete [] bd;
6925  }
6926 
6927  nbranches = fBranches.GetEntries();
6928 
6929  if (gDebug > 1) {
6930  Info("ReadStream", "Will use branches:");
6931  for (int i = 0 ; i < nbranches; ++i) {
6932  TBranch* br = (TBranch*) fBranches.At(i);
6933  Info("ReadStream", " %s: %s [%s]", br->GetName(),
6934  br->GetTitle(), br->GetListOfLeaves()->At(0)->IsA()->GetName());
6935  }
6936  if (gDebug > 3) {
6937  Info("ReadStream", "Dumping read tokens, format:");
6938  Info("ReadStream", "LLLLL:BBB:gfbe:GFBE:T");
6939  Info("ReadStream", " L: line number");
6940  Info("ReadStream", " B: branch number");
6941  Info("ReadStream", " gfbe: good / fail / bad / eof of token");
6942  Info("ReadStream", " GFBE: good / fail / bad / eof of file");
6943  Info("ReadStream", " T: Token being read");
6944  }
6945  }
6946 
6947  //loop on all lines in the file
6948  Long64_t nGoodLines = 0;
6949  std::string line;
6950  const char sDelimBuf[2] = { delimiter, 0 };
6951  const char* sDelim = sDelimBuf;
6952  if (delimiter == ' ') {
6953  // ' ' really means whitespace
6954  sDelim = "[ \t]";
6955  }
6956  while(in.good()) {
6957  if (newline == '\r' && in.peek() == '\n') {
6958  // Windows, skip '\n':
6959  in.get();
6960  }
6961  std::getline(in, line, newline);
6962  ++nlines;
6963 
6964  TString sLine(line);
6965  sLine = sLine.Strip(TString::kLeading); // skip leading whitespace
6966  if (sLine.IsNull()) {
6967  if (gDebug > 2) {
6968  Info("ReadStream", "Skipping empty line number %lld", nlines);
6969  }
6970  continue; // silently skip empty lines
6971  }
6972  if (sLine[0] == '#') {
6973  if (gDebug > 2) {
6974  Info("ReadStream", "Skipping comment line number %lld: '%s'",
6975  nlines, line.c_str());
6976  }
6977  continue;
6978  }
6979  if (gDebug > 2) {
6980  Info("ReadStream", "Parsing line number %lld: '%s'",
6981  nlines, line.c_str());
6982  }
6983 
6984  // Loop on branches and read the branch values into their buffer
6985  branch = 0;
6986  TString tok; // one column's data
6987  TString leafData; // leaf data, possibly multiple tokens for e.g. /I[2]
6988  std::stringstream sToken; // string stream feeding leafData into leaves
6989  Ssiz_t pos = 0;
6990  Int_t iBranch = 0;
6991  Bool_t goodLine = kTRUE; // whether the row can be filled into the tree
6992  Int_t remainingLeafLen = 0; // remaining columns for the current leaf
6993  while (goodLine && iBranch < nbranches
6994  && sLine.Tokenize(tok, pos, sDelim)) {
6995  tok = tok.Strip(TString::kLeading); // skip leading whitespace
6996  if (tok.IsNull() && delimiter == ' ') {
6997  // 1 2 should not be interpreted as 1,,,2 but 1, 2.
6998  // Thus continue until we have a non-empty token.
6999  continue;
7000  }
7001 
7002  if (!remainingLeafLen) {
7003  // next branch!
7004  branch = (TBranch*)fBranches.At(iBranch);
7005  }
7006  TLeaf *leaf = (TLeaf*)branch->GetListOfLeaves()->At(0);
7007  if (!remainingLeafLen) {
7008  remainingLeafLen = leaf->GetLen();
7009  if (leaf->GetMaximum() > 0) {
7010  // This is a dynamic leaf length, i.e. most likely a TLeafC's
7011  // string size. This still translates into one token:
7012  remainingLeafLen = 1;
7013  }
7014 
7015  leafData = tok;
7016  } else {
7017  // append token to laf data:
7018  leafData += " ";
7019  leafData += tok;
7020  }
7021  --remainingLeafLen;
7022  if (remainingLeafLen) {
7023  // need more columns for this branch:
7024  continue;
7025  }
7026  ++iBranch;
7027 
7028  // initialize stringstream with token
7029  sToken.clear();
7030  sToken.seekp(0, std::ios_base::beg);
7031  sToken.str(leafData.Data());
7032  sToken.seekg(0, std::ios_base::beg);
7033  leaf->ReadValue(sToken, 0 /* 0 = "all" */);
7034  if (gDebug > 3) {
7035  Info("ReadStream", "%5lld:%3d:%d%d%d%d:%d%d%d%d:%s",
7036  nlines, iBranch,
7037  (int)sToken.good(), (int)sToken.fail(),
7038  (int)sToken.bad(), (int)sToken.eof(),
7039  (int)in.good(), (int)in.fail(),
7040  (int)in.bad(), (int)in.eof(),
7041  sToken.str().c_str());
7042  }
7043 
7044  // Error handling
7045  if (sToken.bad()) {
7046  // How could that happen for a stringstream?
7047  Warning("ReadStream",
7048  "Buffer error while reading data for branch %s on line %lld",
7049  branch->GetName(), nlines);
7050  } else if (!sToken.eof()) {
7051  if (sToken.fail()) {
7052  Warning("ReadStream",
7053  "Couldn't read formatted data in \"%s\" for branch %s on line %lld; ignoring line",
7054  tok.Data(), branch->GetName(), nlines);
7055  goodLine = kFALSE;
7056  } else {
7057  std::string remainder;
7058  std::getline(sToken, remainder, newline);
7059  if (!remainder.empty()) {
7060  Warning("ReadStream",
7061  "Ignoring trailing \"%s\" while reading data for branch %s on line %lld",
7062  remainder.c_str(), branch->GetName(), nlines);
7063  }
7064  }
7065  }
7066  } // tokenizer loop
7067 
7068  if (iBranch < nbranches) {
7069  Warning("ReadStream",
7070  "Read too few columns (%d < %d) in line %lld; ignoring line",
7071  iBranch, nbranches, nlines);
7072  goodLine = kFALSE;
7073  } else if (pos != kNPOS) {
7074  sLine = sLine.Strip(TString::kTrailing);
7075  if (pos < sLine.Length()) {
7076  Warning("ReadStream",
7077  "Ignoring trailing \"%s\" while reading line %lld",
7078  sLine.Data() + pos - 1 /* also print delimiter */,
7079  nlines);
7080  }
7081  }
7082 
7083  //we are now ready to fill the tree
7084  if (goodLine) {
7085  Fill();
7086  ++nGoodLines;
7087  }
7088  }
7089 
7090  return nGoodLines;
7091 }
7092 
7093 ////////////////////////////////////////////////////////////////////////////////
7094 /// Make sure that obj (which is being deleted or will soon be) is no
7095 /// longer referenced by this TTree.
7096 
7099  if (obj == fEventList) {
7100  fEventList = 0;
7101  }
7102  if (obj == fEntryList) {
7103  fEntryList = 0;
7104  }
7105  if (fUserInfo) {
7106  fUserInfo->RecursiveRemove(obj);
7107  }
7108  if (fPlayer == obj) {
7109  fPlayer = 0;
7110  }
7111  if (fTreeIndex == obj) {
7112  fTreeIndex = 0;
7113  }
7114  if (fAliases) {
7115  fAliases->RecursiveRemove(obj);
7116  }
7117  if (fFriends) {
7118  fFriends->RecursiveRemove(obj);
7119  }
7120 }
7121 
7122 ////////////////////////////////////////////////////////////////////////////////
7123 /// Refresh contents of this tree and its branches from the current status on disk.
7124 ///
7125 /// One can call this function in case the tree file is being
7126 /// updated by another process.
7127 
7128 void TTree::Refresh()
7130  if (!fDirectory->GetFile()) {
7131  return;
7132  }
7133  fDirectory->ReadKeys();
7134  fDirectory->Remove(this);
7135  TTree* tree; fDirectory->GetObject(GetName(),tree);
7136  if (!tree) {
7137  return;
7138  }
7139  //copy info from tree header into this Tree
7140  fEntries = 0;
7141  fNClusterRange = 0;
7142  ImportClusterRanges(tree);
7143 
7144  fAutoSave = tree->fAutoSave;
7145  fEntries = tree->fEntries;
7146  fTotBytes = tree->fTotBytes;
7147  fZipBytes = tree->fZipBytes;
7148  fSavedBytes = tree->fSavedBytes;
7149  fTotalBuffers = tree->fTotalBuffers;
7150 
7151  //loop on all branches and update them
7152  Int_t nleaves = fLeaves.GetEntriesFast();
7153  for (Int_t i = 0; i < nleaves; i++) {
7154  TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
7155  TBranch* branch = (TBranch*) leaf->GetBranch();
7156  branch->Refresh(tree->GetBranch(branch->GetName()));
7157  }
7158  fDirectory->Remove(tree);
7159  fDirectory->Append(this);
7160  delete tree;
7161  tree = 0;
7162 }
7163 
7164 ////////////////////////////////////////////////////////////////////////////////
7165 /// Remove a friend from the list of friends.
7166 
7167 void TTree::RemoveFriend(TTree* oldFriend)
7169  // We already have been visited while recursively looking
7170  // through the friends tree, let return
7172  return;
7173  }
7174  if (!fFriends) {
7175  return;
7176  }
7177  TFriendLock lock(this, kRemoveFriend);
7178  TIter nextf(fFriends);
7179  TFriendElement* fe = 0;
7180  while ((fe = (TFriendElement*) nextf())) {
7181  TTree* friend_t = fe->GetTree();
7182  if (friend_t == oldFriend) {
7183  fFriends->Remove(fe);
7184  delete fe;
7185  fe = 0;
7186  }
7187  }
7188 }
7189 
7190 ////////////////////////////////////////////////////////////////////////////////
7191 /// Reset baskets, buffers and entries count in all branches and leaves.
7192 
7193 void TTree::Reset(Option_t* option)
7195  fNotify = 0;
7196  fEntries = 0;
7197  fNClusterRange = 0;
7198  fTotBytes = 0;
7199  fZipBytes = 0;
7200  fFlushedBytes = 0;
7201  fSavedBytes = 0;
7202  fTotalBuffers = 0;
7203  fChainOffset = 0;
7204  fReadEntry = -1;
7205 
7206  delete fTreeIndex;
7207  fTreeIndex = 0;
7208 
7210  for (Int_t i = 0; i < nb; ++i) {
7211  TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
7212  branch->Reset(option);
7213  }
7214 
7215  if (fBranchRef) {
7216  fBranchRef->Reset();
7217  }
7218 }
7219 
7220 ////////////////////////////////////////////////////////////////////////////////
7221 /// Resets the state of this TTree after a merge (keep the customization but
7222 /// forget the data).
7223 
7226  fEntries = 0;
7227  fNClusterRange = 0;
7228  fTotBytes = 0;
7229  fZipBytes = 0;
7230  fSavedBytes = 0;
7231  fFlushedBytes = 0;
7232  fTotalBuffers = 0;
7233  fChainOffset = 0;
7234  fReadEntry = -1;
7235 
7236  delete fTreeIndex;
7237  fTreeIndex = 0;
7238 
7240  for (Int_t i = 0; i < nb; ++i) {
7241  TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
7242  branch->ResetAfterMerge(info);
7243  }
7244 
7245  if (fBranchRef) {
7246  fBranchRef->ResetAfterMerge(info);
7247  }
7248 }
7249 
7250 ////////////////////////////////////////////////////////////////////////////////
7251 /// Tell all of our branches to set their addresses to zero.
7252 ///
7253 /// Note: If any of our branches own any objects, they are deleted.
7254 
7257  if (br && br->GetTree()) {
7258  br->ResetAddress();
7259  }
7260 }
7261 
7262 ////////////////////////////////////////////////////////////////////////////////
7263 /// Tell all of our branches to drop their current objects and allocate new ones.
7264 
7267  TObjArray* branches = GetListOfBranches();
7268  Int_t nbranches = branches->GetEntriesFast();
7269  for (Int_t i = 0; i < nbranches; ++i) {
7270  TBranch* branch = (TBranch*) branches->UncheckedAt(i);
7271  branch->ResetAddress();
7272  }
7273 }
7274 
7275 ////////////////////////////////////////////////////////////////////////////////
7276 /// Loop over tree entries and print entries passing selection.
7277 ///
7278 /// - If varexp is 0 (or "") then print only first 8 columns.
7279 /// - If varexp = "*" print all columns.
7280 ///
7281 /// Otherwise a columns selection can be made using "var1:var2:var3".
7282 /// See TTreePlayer::Scan for more information
7283 
7284 Long64_t TTree::Scan(const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
7286  GetPlayer();
7287  if (fPlayer) {
7288  return fPlayer->Scan(varexp, selection, option, nentries, firstentry);
7289  }
7290  return -1;
7291 }
7292 
7293 ////////////////////////////////////////////////////////////////////////////////
7294 /// Set a tree variable alias.
7295 ///
7296 /// Set an alias for an expression/formula based on the tree 'variables'.
7297 ///
7298 /// The content of 'aliasName' can be used in TTreeFormula (i.e. TTree::Draw,
7299 /// TTree::Scan, TTreeViewer) and will be evaluated as the content of
7300 /// 'aliasFormula'.
7301 ///
7302 /// If the content of 'aliasFormula' only contains symbol names, periods and
7303 /// array index specification (for example event.fTracks[3]), then
7304 /// the content of 'aliasName' can be used as the start of symbol.
7305 ///
7306 /// If the alias 'aliasName' already existed, it is replaced by the new
7307 /// value.
7308 ///
7309 /// When being used, the alias can be preceded by an eventual 'Friend Alias'
7310 /// (see TTree::GetFriendAlias)
7311 ///
7312 /// Return true if it was added properly.
7313 ///
7314 /// For example:
7315 /// ~~~ {.cpp}
7316 /// tree->SetAlias("x1","(tdc1[1]-tdc1[0])/49");
7317 /// tree->SetAlias("y1","(tdc1[3]-tdc1[2])/47");
7318 /// tree->SetAlias("x2","(tdc2[1]-tdc2[0])/49");
7319 /// tree->SetAlias("y2","(tdc2[3]-tdc2[2])/47");
7320 /// tree->Draw("y2-y1:x2-x1");
7321 ///
7322 /// tree->SetAlias("theGoodTrack","event.fTracks[3]");
7323 /// tree->Draw("theGoodTrack.fPx"); // same as "event.fTracks[3].fPx"
7324 /// ~~~
7325 
7326 Bool_t TTree::SetAlias(const char* aliasName, const char* aliasFormula)
7328  if (!aliasName || !aliasFormula) {
7329  return kFALSE;
7330  }
7331  if (!aliasName[0] || !aliasFormula[0]) {
7332  return kFALSE;
7333  }
7334  if (!fAliases) {
7335  fAliases = new TList;
7336  } else {
7337  TNamed* oldHolder = (TNamed*) fAliases->FindObject(aliasName);
7338  if (oldHolder) {
7339  oldHolder->SetTitle(aliasFormula);
7340  return kTRUE;
7341  }
7342  }
7343  TNamed* holder = new TNamed(aliasName, aliasFormula);
7344  fAliases->Add(holder);
7345  return kTRUE;
7346 }
7347 
7348 ////////////////////////////////////////////////////////////////////////////////
7349 /// This function may be called at the start of a program to change
7350 /// the default value for fAutoFlush.
7351 ///
7352 /// ### CASE 1 : autof > 0
7353 ///
7354 /// autof is the number of consecutive entries after which TTree::Fill will
7355 /// flush all branch buffers to disk.
7356 ///
7357 /// ### CASE 2 : autof < 0
7358 ///
7359 /// When filling the Tree the branch buffers will be flushed to disk when
7360 /// more than autof bytes have been written to the file. At the first FlushBaskets
7361 /// TTree::Fill will replace fAutoFlush by the current value of fEntries.
7362 ///
7363 /// Calling this function with autof<0 is interesting when it is hard to estimate
7364 /// the size of one entry. This value is also independent of the Tree.
7365 ///
7366 /// The Tree is initialized with fAutoFlush=-30000000, ie that, by default,
7367 /// the first AutoFlush will be done when 30 MBytes of data are written to the file.
7368 ///
7369 /// ### CASE 3 : autof = 0
7370 ///
7371 /// The AutoFlush mechanism is disabled.
7372 ///
7373 /// Flushing the buffers at regular intervals optimize the location of
7374 /// consecutive entries on the disk by creating clusters of baskets.
7375 ///
7376 /// A cluster of baskets is a set of baskets that contains all
7377 /// the data for a (consecutive) set of entries and that is stored
7378 /// consecutively on the disk. When reading all the branches, this
7379 /// is the minimum set of baskets that the TTreeCache will read.
7380 
7381 void TTree::SetAutoFlush(Long64_t autof /* = -30000000 */ )
7383  // Implementation note:
7384  //
7385  // A positive value of autoflush determines the size (in number of entries) of
7386  // a cluster of baskets.
7387  //
7388  // If the value of autoflush is changed over time (this happens in
7389  // particular when the TTree results from fast merging many trees),
7390  // we record the values of fAutoFlush in the data members:
7391  // fClusterRangeEnd and fClusterSize.
7392  // In the code we refer to a range of entries where the size of the
7393  // cluster of baskets is the same (i.e the value of AutoFlush was
7394  // constant) is called a ClusterRange.
7395  //
7396  // The 2 arrays (fClusterRangeEnd and fClusterSize) have fNClusterRange
7397  // active (used) values and have fMaxClusterRange allocated entries.
7398  //
7399  // fClusterRangeEnd contains the last entries number of a cluster range.
7400  // In particular this means that the 'next' cluster starts at fClusterRangeEnd[]+1
7401  // fClusterSize contains the size in number of entries of all the cluster
7402  // within the given range.
7403  // The last range (and the only one if fNClusterRange is zero) start at
7404  // fNClusterRange[fNClusterRange-1]+1 and ends at the end of the TTree. The
7405  // size of the cluster in this range is given by the value of fAutoFlush.
7406  //
7407  // For example printing the beginning and end of each the ranges can be done by:
7408  //
7409  // Printf("%-16s %-16s %-16s %5s",
7410  // "Cluster Range #", "Entry Start", "Last Entry", "Size");
7411  // Int_t index= 0;
7412  // Long64_t clusterRangeStart = 0;
7413  // if (fNClusterRange) {
7414  // for( ; index < fNClusterRange; ++index) {
7415  // Printf("%-16d %-16lld %-16lld %5lld",
7416  // index, clusterRangeStart, fClusterRangeEnd[index], fClusterSize[index]);
7417  // clusterRangeStart = fClusterRangeEnd[index] + 1;
7418  // }
7419  // }
7420  // Printf("%-16d %-16lld %-16lld %5lld",
7421  // index, prevEntry, fEntries - 1, fAutoFlush);
7422  //
7423 
7424  // Note: We store the entry number corresponding to the end of the cluster
7425  // rather than its start in order to avoid using the array if the cluster
7426  // size never varies (If there is only one value of AutoFlush for the whole TTree).
7427 
7428  if (fAutoFlush > 0 || autof > 0) {
7429  // The mechanism was already enabled, let's record the previous
7430  // cluster if needed.
7431  if (fFlushedBytes) {
7432  if ( (fNClusterRange+1) > fMaxClusterRange ) {
7433  if (fMaxClusterRange) {
7434  Int_t newsize = TMath::Max(10,Int_t(2*fMaxClusterRange));
7436  newsize*sizeof(Long64_t),fMaxClusterRange*sizeof(Long64_t));
7438  newsize*sizeof(Long64_t),fMaxClusterRange*sizeof(Long64_t));
7439  fMaxClusterRange = newsize;
7440  } else {
7441  fMaxClusterRange = 2;
7444  }
7445  }
7448  ++fNClusterRange;
7449  }
7450  }
7451  fAutoFlush = autof;
7452 }
7453 
7454 ////////////////////////////////////////////////////////////////////////////////
7455 /// This function may be called at the start of a program to change
7456 /// the default value for fAutoSave (and for SetAutoSave) is -300000000, ie 300 MBytes
7457 /// When filling the Tree the branch buffers as well as the Tree header
7458 /// will be flushed to disk when the watermark is reached.
7459 /// If fAutoSave is positive the watermark is reached when a multiple of fAutoSave
7460 /// entries have been written.
7461 /// If fAutoSave is negative the watermark is reached when -fAutoSave bytes
7462 /// have been written to the file.
7463 /// In case of a program crash, it will be possible to recover the data in the Tree
7464 /// up to the last AutoSave point.
7465 
7466 void TTree::SetAutoSave(Long64_t autos)
7468  fAutoSave = autos;
7469 }
7470 
7471 ////////////////////////////////////////////////////////////////////////////////
7472 /// Set a branch's basket size.
7473 ///
7474 /// bname is the name of a branch.
7475 ///
7476 /// - if bname="*", apply to all branches.
7477 /// - if bname="xxx*", apply to all branches with name starting with xxx
7478 ///
7479 /// see TRegexp for wildcarding options
7480 /// buffsize = branc basket size
7481 
7482 void TTree::SetBasketSize(const char* bname, Int_t buffsize)
7484  Int_t nleaves = fLeaves.GetEntriesFast();
7485  TRegexp re(bname, kTRUE);
7486  Int_t nb = 0;
7487  for (Int_t i = 0; i < nleaves; i++) {
7488  TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
7489  TBranch* branch = (TBranch*) leaf->GetBranch();
7490  TString s = branch->GetName();
7491  if (strcmp(bname, branch->GetName()) && (s.Index(re) == kNPOS)) {
7492  continue;
7493  }
7494  nb++;
7495  branch->SetBasketSize(buffsize);
7496  }
7497  if (!nb) {
7498  Error("SetBasketSize", "unknown branch -> '%s'", bname);
7499  }
7500 }
7501 
7502 ////////////////////////////////////////////////////////////////////////////////
7503 /// Change branch address, dealing with clone trees properly.
7504 /// See TTree::CheckBranchAddressType for the semantic of the return value.
7505 ///
7506 /// Note: See the comments in TBranchElement::SetAddress() for the
7507 /// meaning of the addr parameter and the object ownership policy.
7508 
7509 Int_t TTree::SetBranchAddress(const char* bname, void* addr, TBranch** ptr)
7511  TBranch* branch = GetBranch(bname);
7512  if (!branch) {
7513  if (ptr) *ptr = 0;
7514  Error("SetBranchAddress", "unknown branch -> %s", bname);
7515  return kMissingBranch;
7516  }
7517  return SetBranchAddressImp(branch,addr,ptr);
7518 }
7519 
7520 ////////////////////////////////////////////////////////////////////////////////
7521 /// Verify the validity of the type of addr before calling SetBranchAddress.
7522 /// See TTree::CheckBranchAddressType for the semantic of the return value.
7523 ///
7524 /// Note: See the comments in TBranchElement::SetAddress() for the
7525 /// meaning of the addr parameter and the object ownership policy.
7526 
7527 Int_t TTree::SetBranchAddress(const char* bname, void* addr, TClass* ptrClass, EDataType datatype, Bool_t isptr)
7529  return SetBranchAddress(bname, addr, 0, ptrClass, datatype, isptr);
7530 }
7531 
7532 ////////////////////////////////////////////////////////////////////////////////
7533 /// Verify the validity of the type of addr before calling SetBranchAddress.
7534 /// See TTree::CheckBranchAddressType for the semantic of the return value.
7535 ///
7536 /// Note: See the comments in TBranchElement::SetAddress() for the
7537 /// meaning of the addr parameter and the object ownership policy.
7538 
7539 Int_t TTree::SetBranchAddress(const char* bname, void* addr, TBranch** ptr, TClass* ptrClass, EDataType datatype, Bool_t isptr)
7541  TBranch* branch = GetBranch(bname);
7542  if (!branch) {
7543  if (ptr) *ptr = 0;
7544  Error("SetBranchAddress", "unknown branch -> %s", bname);
7545  return kMissingBranch;
7546  }
7547 
7548  Int_t res = CheckBranchAddressType(branch, ptrClass, datatype, isptr);
7549  // This will set the value of *ptr to branch.
7550  if (res >= 0) {
7551  // The check succeeded.
7552  SetBranchAddressImp(branch,addr,ptr);
7553  } else {
7554  if (ptr) *ptr = 0;
7555  }
7556  return res;
7557 }
7558 
7559 ////////////////////////////////////////////////////////////////////////////////
7560 /// Change branch address, dealing with clone trees properly.
7561 /// See TTree::CheckBranchAddressType for the semantic of the return value.
7562 ///
7563 /// Note: See the comments in TBranchElement::SetAddress() for the
7564 /// meaning of the addr parameter and the object ownership policy.
7565 
7566 Int_t TTree::SetBranchAddressImp(TBranch *branch, void* addr, TBranch** ptr)
7568  if (ptr) {
7569  *ptr = branch;
7570  }
7571  if (fClones) {
7572  void* oldAddr = branch->GetAddress();
7573  TIter next(fClones);
7574  TTree* clone = 0;
7575  const char *bname = branch->GetName();
7576  while ((clone = (TTree*) next())) {
7577  TBranch* cloneBr = clone->GetBranch(bname);
7578  if (cloneBr && (cloneBr->GetAddress() == oldAddr)) {
7579  cloneBr->SetAddress(addr);
7580  }
7581  }
7582  }
7583  branch->SetAddress(addr);
7584  return kVoidPtr;
7585 }
7586 
7587 ////////////////////////////////////////////////////////////////////////////////
7588 /// Set branch status to Process or DoNotProcess.
7589 ///
7590 /// When reading a Tree, by default, all branches are read.
7591 /// One can speed up considerably the analysis phase by activating
7592 /// only the branches that hold variables involved in a query.
7593 ///
7594 /// bname is the name of a branch.
7595 ///
7596 /// - if bname="*", apply to all branches.
7597 /// - if bname="xxx*", apply to all branches with name starting with xxx
7598 ///
7599 /// see TRegexp for wildcarding options
7600 ///
7601 /// - status = 1 branch will be processed
7602 /// - = 0 branch will not be processed
7603 ///
7604 /// Example:
7605 ///
7606 /// Assume a tree T with sub-branches a,b,c,d,e,f,g,etc..
7607 /// when doing T.GetEntry(i) all branches are read for entry i.
7608 /// to read only the branches c and e, one can do
7609 /// ~~~ {.cpp}
7610 /// T.SetBranchStatus("*",0); //disable all branches
7611 /// T.SetBranchStatus("c",1);
7612 /// T.setBranchStatus("e",1);
7613 /// T.GetEntry(i);
7614 /// ~~~
7615 /// bname is interpreted as a wildcarded TRegexp (see TRegexp::MakeWildcard).
7616 /// Thus, "a*b" or "a.*b" matches branches starting with "a" and ending with
7617 /// "b", but not any other branch with an "a" followed at some point by a
7618 /// "b". For this second behavior, use "*a*b*". Note that TRegExp does not
7619 /// support '|', and so you cannot select, e.g. track and shower branches
7620 /// with "track|shower".
7621 ///
7622 /// __WARNING! WARNING! WARNING!__
7623 ///
7624 /// SetBranchStatus is matching the branch based on match of the branch
7625 /// 'name' and not on the branch hierarchy! In order to be able to
7626 /// selectively enable a top level object that is 'split' you need to make
7627 /// sure the name of the top level branch is prefixed to the sub-branches'
7628 /// name (by adding a dot ('.') at the end of the Branch creation and use the
7629 /// corresponding bname.
7630 ///
7631 /// I.e If your Tree has been created in split mode with a parent branch "parent."
7632 /// (note the trailing dot).
7633 /// ~~~ {.cpp}
7634 /// T.SetBranchStatus("parent",1);
7635 /// ~~~
7636 /// will not activate the sub-branches of "parent". You should do:
7637 /// ~~~ {.cpp}
7638 /// T.SetBranchStatus("parent*",1);
7639 /// ~~~
7640 /// Without the trailing dot in the branch creation you have no choice but to
7641 /// call SetBranchStatus explicitly for each of the sub branches.
7642 ///
7643 /// An alternative to this function is to read directly and only
7644 /// the interesting branches. Example:
7645 /// ~~~ {.cpp}
7646 /// TBranch *brc = T.GetBranch("c");
7647 /// TBranch *bre = T.GetBranch("e");
7648 /// brc->GetEntry(i);
7649 /// bre->GetEntry(i);
7650 /// ~~~
7651 /// If found is not 0, the number of branch(es) found matching the regular
7652 /// expression is returned in *found AND the error message 'unknown branch'
7653 /// is suppressed.
7654 
7655 void TTree::SetBranchStatus(const char* bname, Bool_t status, UInt_t* found)
7657  // We already have been visited while recursively looking
7658  // through the friends tree, let return
7660  return;
7661  }
7662 
7663  TBranch *branch, *bcount, *bson;
7664  TLeaf *leaf, *leafcount;
7665 
7666  Int_t i,j;
7667  Int_t nleaves = fLeaves.GetEntriesFast();
7668  TRegexp re(bname,kTRUE);
7669  Int_t nb = 0;
7670 
7671  // first pass, loop on all branches
7672  // for leafcount branches activate/deactivate in function of status
7673  for (i=0;i<nleaves;i++) {
7674  leaf = (TLeaf*)fLeaves.UncheckedAt(i);
7675  branch = (TBranch*)leaf->GetBranch();
7676  TString s = branch->GetName();
7677  if (strcmp(bname,"*")) { //Regexp gives wrong result for [] in name
7678  TString longname;
7679  longname.Form("%s.%s",GetName(),branch->GetName());
7680  if (strcmp(bname,branch->GetName())
7681  && longname != bname
7682  && s.Index(re) == kNPOS) continue;
7683  }
7684  nb++;
7685  if (status) branch->ResetBit(kDoNotProcess);
7686  else branch->SetBit(kDoNotProcess);
7687  leafcount = leaf->GetLeafCount();
7688  if (leafcount) {
7689  bcount = leafcount->GetBranch();
7690  if (status) bcount->ResetBit(kDoNotProcess);
7691  else bcount->SetBit(kDoNotProcess);
7692  }
7693  }
7694  if (nb==0 && strchr(bname,'*')==0) {
7695  branch = GetBranch(bname);
7696  if (branch) {
7697  if (status) branch->ResetBit(kDoNotProcess);
7698  else branch->SetBit(kDoNotProcess);
7699  ++nb;
7700  }
7701  }
7702 
7703  //search in list of friends
7704  UInt_t foundInFriend = 0;
7705  if (fFriends) {
7706  TFriendLock lock(this,kSetBranchStatus);
7707  TIter nextf(fFriends);
7708  TFriendElement *fe;
7709  TString name;
7710  while ((fe = (TFriendElement*)nextf())) {
7711  TTree *t = fe->GetTree();
7712  if (t==0) continue;
7713 
7714  // If the alias is present replace it with the real name.
7715  char *subbranch = (char*)strstr(bname,fe->GetName());
7716  if (subbranch!=bname) subbranch = 0;
7717  if (subbranch) {
7718  subbranch += strlen(fe->GetName());
7719  if ( *subbranch != '.' ) subbranch = 0;
7720  else subbranch ++;
7721  }
7722  if (subbranch) {
7723  name.Form("%s.%s",t->GetName(),subbranch);
7724  } else {
7725  name = bname;
7726  }
7727  t->SetBranchStatus(name,status, &foundInFriend);
7728  }
7729  }
7730  if (!nb && !foundInFriend) {
7731  if (found==0) Error("SetBranchStatus", "unknown branch -> %s", bname);
7732  return;
7733  }
7734  if (found) *found = nb + foundInFriend;
7735 
7736  // second pass, loop again on all branches
7737  // activate leafcount branches for active branches only
7738  for (i = 0; i < nleaves; i++) {
7739  leaf = (TLeaf*)fLeaves.UncheckedAt(i);
7740  branch = (TBranch*)leaf->GetBranch();
7741  if (!branch->TestBit(kDoNotProcess)) {
7742  leafcount = leaf->GetLeafCount();
7743  if (leafcount) {
7744  bcount = leafcount->GetBranch();
7745  bcount->ResetBit(kDoNotProcess);
7746  }
7747  } else {
7748  //Int_t nbranches = branch->GetListOfBranches()->GetEntriesFast();
7749  Int_t nbranches = branch->GetListOfBranches()->GetEntries();
7750  for (j=0;j<nbranches;j++) {
7751  bson = (TBranch*)branch->GetListOfBranches()->UncheckedAt(j);
7752  if (!bson) continue;
7753  if (!bson->TestBit(kDoNotProcess)) {
7754  if (bson->GetNleaves() <= 0) continue;
7755  branch->ResetBit(kDoNotProcess);
7756  break;
7757  }
7758  }
7759  }
7760  }
7761 }
7762 
7763 ////////////////////////////////////////////////////////////////////////////////
7764 /// Set the current branch style. (static function)
7765 ///
7766 /// - style = 0 old Branch
7767 /// - style = 1 new Bronch
7768 
7771  fgBranchStyle = style;
7772 }
7773 
7774 ////////////////////////////////////////////////////////////////////////////////
7775 /// Set maximum size of the file cache .
7776 //
7777 /// - if cachesize = 0 the existing cache (if any) is deleted.
7778 /// - if cachesize = -1 (default) it is set to the AutoFlush value when writing
7779 /// the Tree (default is 30 MBytes).
7780 ///
7781 /// Returns:
7782 /// - 0 size set, cache was created if possible
7783 /// - -1 on error
7784 
7787  // remember that the user has requested an explicit cache setup
7788  fCacheUserSet = kTRUE;
7789 
7790  return SetCacheSizeAux(kFALSE, cacheSize);
7791 }
7792 
7793 ////////////////////////////////////////////////////////////////////////////////
7794 /// Set the size of the file cache and create it if possible.
7795 ///
7796 /// If autocache is true:
7797 /// this may be an autocreated cache, possibly enlarging an existing
7798 /// autocreated cache. The size is calculated. The value passed in cacheSize:
7799 /// - cacheSize = 0 make cache if default cache creation is enabled
7800 /// - cacheSize = -1 make a default sized cache in any case
7801 ///
7802 /// If autocache is false:
7803 /// this is a user requested cache. cacheSize is used to size the cache.
7804 /// This cache should never be automatically adjusted.
7805 ///
7806 /// Returns:
7807 /// - 0 size set, or existing autosized cache almost large enough.
7808 /// (cache was created if possible)
7809 /// - -1 on error
7810 
7811 Int_t TTree::SetCacheSizeAux(Bool_t autocache /* = kTRUE */, Long64_t cacheSize /* = 0 */ )
7813  if (autocache) {
7814  // used as a once only control for automatic cache setup
7816  }
7817 
7818  if (!autocache) {
7819  // negative size means the user requests the default
7820  if (cacheSize < 0) {
7821  cacheSize = GetCacheAutoSize(kTRUE);
7822  }
7823  } else {
7824  if (cacheSize == 0) {
7825  cacheSize = GetCacheAutoSize();
7826  } else if (cacheSize < 0) {
7827  cacheSize = GetCacheAutoSize(kTRUE);
7828  }
7829  }
7830 
7831  TFile* file = GetCurrentFile();
7832  if (!file || GetTree() != this) {
7833  // if there's no file or we are not a plain tree (e.g. if we're a TChain)
7834  // do not create a cache, only record the size if one was given
7835  if (!autocache) {
7836  fCacheSize = cacheSize;
7837  }
7838  if (GetTree() != this) {
7839  return 0;
7840  }
7841  if (!autocache && cacheSize>0) {
7842  Warning("SetCacheSizeAux", "A TTreeCache could not be created because the TTree has no file");
7843  }
7844  return 0;
7845  }
7846 
7847  // Check for an existing cache
7848  TTreeCache* pf = GetReadCache(file);
7849  if (pf) {
7850  if (autocache) {
7851  // reset our cache status tracking in case existing cache was added
7852  // by the user without using one of the TTree methods
7853  fCacheSize = pf->GetBufferSize();
7854  fCacheUserSet = !pf->IsAutoCreated();
7855 
7856  if (fCacheUserSet) {
7857  // existing cache was created by the user, don't change it
7858  return 0;
7859  }
7860  } else {
7861  // update the cache to ensure it records the user has explicitly
7862  // requested it
7863  pf->SetAutoCreated(kFALSE);
7864  }
7865 
7866  // if we're using an automatically calculated size and the existing
7867  // cache is already almost large enough don't resize
7868  if (autocache && Long64_t(0.80*cacheSize) < fCacheSize) {
7869  // already large enough
7870  return 0;
7871  }
7872 
7873  if (cacheSize == fCacheSize) {
7874  return 0;
7875  }
7876 
7877  if (cacheSize == 0) {
7878  // delete existing cache
7879  pf->WaitFinishPrefetch();
7880  file->SetCacheRead(0,this);
7881  delete pf;
7882  pf = 0;
7883  } else {
7884  // resize
7885  Int_t res = pf->SetBufferSize(cacheSize);
7886  if (res < 0) {
7887  return -1;
7888  }
7889  }
7890  } else {
7891  // no existing cache
7892  if (autocache) {
7893  if (fCacheUserSet) {
7894  // value was already set manually.
7895  if (fCacheSize == 0) return 0;
7896  // Expected a cache should exist; perhaps the user moved it
7897  // Do nothing more here.
7898  if (cacheSize) {
7899  Error("SetCacheSizeAux", "Not setting up an automatically sized TTreeCache because of missing cache previously set");
7900  }
7901  return -1;
7902  }
7903  }
7904  }
7905 
7906  fCacheSize = cacheSize;
7907  if (cacheSize == 0 || pf) {
7908  return 0;
7909  }
7910 
7912  pf = new TTreeCacheUnzip(this, cacheSize);
7913  else
7914  pf = new TTreeCache(this, cacheSize);
7915 
7916  pf->SetAutoCreated(autocache);
7917 
7918  return 0;
7919 }
7920 
7921 ////////////////////////////////////////////////////////////////////////////////
7922 ///interface to TTreeCache to set the cache entry range
7923 ///
7924 /// Returns:
7925 /// - 0 entry range set
7926 /// - -1 on error
7927 
7930  if (!GetTree()) {
7931  if (LoadTree(0)<0) {
7932  Error("SetCacheEntryRange","Could not load a tree");
7933  return -1;
7934  }
7935  }
7936  if (GetTree()) {
7937  if (GetTree() != this) {
7938  return GetTree()->SetCacheEntryRange(first, last);
7939  }
7940  } else {
7941  Error("SetCacheEntryRange", "No tree is available. Could not set cache entry range");
7942  return -1;
7943  }
7944 
7945  TFile *f = GetCurrentFile();
7946  if (!f) {
7947  Error("SetCacheEntryRange", "No file is available. Could not set cache entry range");
7948  return -1;
7949  }
7950  TTreeCache *tc = GetReadCache(f,kTRUE);
7951  if (!tc) {
7952  Error("SetCacheEntryRange", "No cache is available. Could not set entry range");
7953  return -1;
7954  }
7955  tc->SetEntryRange(first,last);
7956  return 0;
7957 }
7958 
7959 ////////////////////////////////////////////////////////////////////////////////
7960 /// Interface to TTreeCache to set the number of entries for the learning phase
7961 
7965 }
7966 
7967 ////////////////////////////////////////////////////////////////////////////////
7968 /// Enable/Disable circularity for this tree.
7969 ///
7970 /// if maxEntries > 0 a maximum of maxEntries is kept in one buffer/basket
7971 /// per branch in memory.
7972 /// Note that when this function is called (maxEntries>0) the Tree
7973 /// must be empty or having only one basket per branch.
7974 /// if maxEntries <= 0 the tree circularity is disabled.
7975 ///
7976 /// #### NOTE 1:
7977 /// Circular Trees are interesting in online real time environments
7978 /// to store the results of the last maxEntries events.
7979 /// #### NOTE 2:
7980 /// Calling SetCircular with maxEntries <= 0 is necessary before
7981 /// merging circular Trees that have been saved on files.
7982 /// #### NOTE 3:
7983 /// SetCircular with maxEntries <= 0 is automatically called
7984 /// by TChain::Merge
7985 /// #### NOTE 4:
7986 /// A circular Tree can still be saved in a file. When read back,
7987 /// it is still a circular Tree and can be filled again.
7988 
7989 void TTree::SetCircular(Long64_t maxEntries)
7991  if (maxEntries <= 0) {
7992  // Disable circularity.
7993  fMaxEntries = 1000000000;
7994  fMaxEntries *= 1000;
7996  //in case the Tree was originally created in gROOT, the branch
7997  //compression level was set to -1. If the Tree is now associated to
7998  //a file, reset the compression level to the file compression level
7999  if (fDirectory) {
8000  TFile* bfile = fDirectory->GetFile();
8001  Int_t compress = 1;
8002  if (bfile) {
8003  compress = bfile->GetCompressionSettings();
8004  }
8006  for (Int_t i = 0; i < nb; i++) {
8007  TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
8008  branch->SetCompressionSettings(compress);
8009  }
8010  }
8011  } else {
8012  // Enable circularity.
8013  fMaxEntries = maxEntries;
8014  SetBit(kCircular);
8015  }
8016 }
8017 
8018 ////////////////////////////////////////////////////////////////////////////////
8019 /// Set the debug level and the debug range.
8020 ///
8021 /// For entries in the debug range, the functions TBranchElement::Fill
8022 /// and TBranchElement::GetEntry will print the number of bytes filled
8023 /// or read for each branch.
8024 
8027  fDebug = level;
8028  fDebugMin = min;
8029  fDebugMax = max;
8030 }
8031 
8032 ////////////////////////////////////////////////////////////////////////////////
8033 /// Update the default value for the branch's fEntryOffsetLen.
8034 /// If updateExisting is true, also update all the existing branches.
8035 /// If newdefault is less than 10, the new default value will be 10.
8036 
8037 void TTree::SetDefaultEntryOffsetLen(Int_t newdefault, Bool_t updateExisting)
8039  if (newdefault < 10) {
8040  newdefault = 10;
8041  }
8042  fDefaultEntryOffsetLen = newdefault;
8043  if (updateExisting) {
8045  TBranch *b;
8046  while ( ( b = (TBranch*)next() ) ) {
8047  b->SetEntryOffsetLen( newdefault, kTRUE );
8048  }
8049  if (fBranchRef) {
8050  fBranchRef->SetEntryOffsetLen( newdefault, kTRUE );
8051  }
8052  }
8053 }
8054 
8055 ////////////////////////////////////////////////////////////////////////////////
8056 /// Change the tree's directory.
8057 ///
8058 /// Remove reference to this tree from current directory and
8059 /// add reference to new directory dir. The dir parameter can
8060 /// be 0 in which case the tree does not belong to any directory.
8061 ///
8062 
8065  if (fDirectory == dir) {
8066  return;
8067  }
8068  if (fDirectory) {
8069  fDirectory->Remove(this);
8070 
8071  // Delete or move the file cache if it points to this Tree
8072  TFile *file = fDirectory->GetFile();
8073  MoveReadCache(file,dir);
8074  }
8075  fDirectory = dir;
8076  if (fDirectory) {
8077  fDirectory->Append(this);
8078  }
8079  TFile* file = 0;
8080  if (fDirectory) {
8081  file = fDirectory->GetFile();
8082  }
8083  if (fBranchRef) {
8084  fBranchRef->SetFile(file);
8085  }
8086  TBranch* b = 0;
8088  while((b = (TBranch*) next())) {
8089  b->SetFile(file);
8090  }
8091 }
8092 
8093 ////////////////////////////////////////////////////////////////////////////////
8094 /// Change number of entries in the tree.
8095 ///
8096 /// If n >= 0, set number of entries in the tree = n.
8097 ///
8098 /// If n < 0, set number of entries in the tree to match the
8099 /// number of entries in each branch. (default for n is -1)
8100 ///
8101 /// This function should be called only when one fills each branch
8102 /// independently via TBranch::Fill without calling TTree::Fill.
8103 /// Calling TTree::SetEntries() make sense only if the number of entries
8104 /// in each branch is identical, a warning is issued otherwise.
8105 /// The function returns the number of entries.
8106 ///
8107 
8110  // case 1 : force number of entries to n
8111  if (n >= 0) {
8112  fEntries = n;
8113  return n;
8114  }
8115 
8116  // case 2; compute the number of entries from the number of entries in the branches
8117  TBranch* b = 0;
8118  Long64_t nMin = 99999999;
8119  Long64_t nMax = 0;
8121  while((b = (TBranch*) next())){
8122  Long64_t n2 = b->GetEntries();
8123  if (n2 < nMin) {
8124  nMin = n2;
8125  }
8126  if (n2 > nMax) {
8127  nMax = n2;
8128  }
8129  }
8130  if (nMin != nMax) {
8131  Warning("SetEntries", "Tree branches have different numbers of entries, with %lld maximum.", nMax);
8132  }
8133  fEntries = nMax;
8134  return fEntries;
8135 }
8136 
8137 ////////////////////////////////////////////////////////////////////////////////
8138 /// Set an EntryList
8139 
8140 void TTree::SetEntryList(TEntryList *enlist, Option_t * /*opt*/)
8142  if (fEntryList) {
8143  //check if the previous entry list is owned by the tree
8144  if (fEntryList->TestBit(kCanDelete)){
8145  delete fEntryList;
8146  }
8147  }
8148  fEventList = 0;
8149  if (!enlist) {
8150  fEntryList = 0;
8151  return;
8152  }
8153  fEntryList = enlist;
8154  fEntryList->SetTree(this);
8155 
8156 }
8157 
8158 ////////////////////////////////////////////////////////////////////////////////
8159 /// This function transfroms the given TEventList into a TEntryList
8160 /// The new TEntryList is owned by the TTree and gets deleted when the tree
8161 /// is deleted. This TEntryList can be returned by GetEntryList() function.
8162 
8163 void TTree::SetEventList(TEventList *evlist)
8165  fEventList = evlist;
8166  if (fEntryList){
8167  if (fEntryList->TestBit(kCanDelete)) {
8168  TEntryList *tmp = fEntryList;
8169  fEntryList = 0; // Avoid problem with RecursiveRemove.
8170  delete tmp;
8171  } else {
8172  fEntryList = 0;
8173  }
8174  }
8175 
8176  if (!evlist) {
8177  fEntryList = 0;
8178  fEventList = 0;
8179  return;
8180  }
8181 
8182  fEventList = evlist;
8183  char enlistname[100];
8184  snprintf(enlistname,100, "%s_%s", evlist->GetName(), "entrylist");
8185  fEntryList = new TEntryList(enlistname, evlist->GetTitle());
8186  fEntryList->SetDirectory(0); // We own this.
8187  Int_t nsel = evlist->GetN();
8188  fEntryList->SetTree(this);
8189  Long64_t entry;
8190  for (Int_t i=0; i<nsel; i++){
8191  entry = evlist->GetEntry(i);
8192  fEntryList->Enter(entry);
8193  }
8194  fEntryList->SetReapplyCut(evlist->GetReapplyCut());
8195  fEntryList->SetBit(kCanDelete, kTRUE);
8196 }
8197 
8198 ////////////////////////////////////////////////////////////////////////////////
8199 /// Set number of entries to estimate variable limits.
8200 /// If n is -1, the estimate is set to be the current maximum
8201 /// for the tree (i.e. GetEntries() + 1)
8202 /// If n is less than -1, the behavior is undefined.
8203 
8204 void TTree::SetEstimate(Long64_t n /* = 1000000 */)
8206  if (n == 0) {
8207  n = 10000;
8208  } else if (n < 0) {
8209  n = fEntries - n;
8210  }
8211  fEstimate = n;
8212  GetPlayer();
8213  if (fPlayer) {
8214  fPlayer->SetEstimate(n);
8215  }
8216 }
8217 
8218 ////////////////////////////////////////////////////////////////////////////////
8219 /// Set fFileNumber to number.
8220 /// fFileNumber is used by TTree::Fill to set the file name
8221 /// for a new file to be created when the current file exceeds fgTreeMaxSize.
8222 /// (see TTree::ChangeFile)
8223 /// if fFileNumber=10, the new file name will have a suffix "_11",
8224 /// ie, fFileNumber is incremented before setting the file name
8225 
8226 void TTree::SetFileNumber(Int_t number)
8228  if (fFileNumber < 0) {
8229  Warning("SetFileNumber", "file number must be positive. Set to 0");
8230  fFileNumber = 0;
8231  return;
8232  }
8233  fFileNumber = number;
8234 }
8235 
8236 ////////////////////////////////////////////////////////////////////////////////
8237 /// Set all the branches in this TTree to be in decomposed object mode
8238 /// (also known as MakeClass mode).
8239 
8242  fMakeClass = make;
8243 
8245  for (Int_t i = 0; i < nb; ++i) {
8246  TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
8247  branch->SetMakeClass(make);
8248  }
8249 }
8250 
8251 ////////////////////////////////////////////////////////////////////////////////
8252 /// Set the maximum size in bytes of a Tree file (static function).
8253 /// The default size is 100000000000LL, ie 100 Gigabytes.
8254 ///
8255 /// In TTree::Fill, when the file has a size > fgMaxTreeSize,
8256 /// the function closes the current file and starts writing into
8257 /// a new file with a name of the style "file_1.root" if the original
8258 /// requested file name was "file.root".
8259 
8263 }
8264 
8265 ////////////////////////////////////////////////////////////////////////////////
8266 /// Change the name of this tree.
8267 
8268 void TTree::SetName(const char* name)
8270  if (gPad) {
8271  gPad->Modified();
8272  }
8273  // Trees are named objects in a THashList.
8274  // We must update hashlists if we change the name.
8275  TFile *file = 0;
8276  TTreeCache *pf = 0;
8277  if (fDirectory) {
8278  fDirectory->Remove(this);
8279  if ((file = GetCurrentFile())) {
8280  pf = GetReadCache(file);
8281  file->SetCacheRead(0,this,TFile::kDoNotDisconnect);
8282  }
8283  }
8284  // This changes our hash value.
8285  fName = name;
8286  if (fDirectory) {
8287  fDirectory->Append(this);
8288  if (pf) {
8289  file->SetCacheRead(pf,this,TFile::kDoNotDisconnect);
8290  }
8291  }
8292 }
8293 
8294 ////////////////////////////////////////////////////////////////////////////////
8295 /// Change the name and title of this tree.
8296 
8297 void TTree::SetObject(const char* name, const char* title)
8299  if (gPad) {
8300  gPad->Modified();
8301  }
8302 
8303  // Trees are named objects in a THashList.
8304  // We must update hashlists if we change the name
8305  TFile *file = 0;
8306  TTreeCache *pf = 0;
8307  if (fDirectory) {
8308  fDirectory->Remove(this);
8309  if ((file = GetCurrentFile())) {
8310  pf = GetReadCache(file);
8311  file->SetCacheRead(0,this,TFile::kDoNotDisconnect);
8312  }
8313  }
8314  // This changes our hash value.
8315  fName = name;
8316  fTitle = title;
8317  if (fDirectory) {
8318  fDirectory->Append(this);
8319  if (pf) {
8320  file->SetCacheRead(pf,this,TFile::kDoNotDisconnect);
8321  }
8322  }
8323 }
8324 
8325 ////////////////////////////////////////////////////////////////////////////////
8326 /// Enable or disable parallel unzipping of Tree buffers.
8327 
8328 void TTree::SetParallelUnzip(Bool_t opt, Float_t RelSize)
8332 
8333  if (RelSize > 0) {
8335  }
8336 
8337 }
8338 
8339 ////////////////////////////////////////////////////////////////////////////////
8340 /// Set perf stats
8341 
8344  fPerfStats = perf;
8345 }
8346 
8347 ////////////////////////////////////////////////////////////////////////////////
8348 /// The current TreeIndex is replaced by the new index.
8349 /// Note that this function does not delete the previous index.
8350 /// This gives the possibility to play with more than one index, e.g.,
8351 /// ~~~ {.cpp}
8352 /// TVirtualIndex* oldIndex = tree.GetTreeIndex();
8353 /// tree.SetTreeIndex(newIndex);
8354 /// tree.Draw();
8355 /// tree.SetTreeIndex(oldIndex);
8356 /// tree.Draw(); etc
8357 /// ~~~
8358 
8361  if (fTreeIndex) {
8362  fTreeIndex->SetTree(0);
8363  }
8364  fTreeIndex = index;
8365 }
8366 
8367 ////////////////////////////////////////////////////////////////////////////////
8368 /// Set tree weight.
8369 ///
8370 /// The weight is used by TTree::Draw to automatically weight each
8371 /// selected entry in the resulting histogram.
8372 ///
8373 /// For example the equivalent of:
8374 /// ~~~ {.cpp}
8375 /// T.Draw("x", "w")
8376 /// ~~~
8377 /// is:
8378 /// ~~~ {.cpp}
8379 /// T.SetWeight(w);
8380 /// T.Draw("x");
8381 /// ~~~
8382 /// This function is redefined by TChain::SetWeight. In case of a
8383 /// TChain, an option "global" may be specified to set the same weight
8384 /// for all trees in the TChain instead of the default behaviour
8385 /// using the weights of each tree in the chain (see TChain::SetWeight).
8386 
8389  fWeight = w;
8390 }
8391 
8392 ////////////////////////////////////////////////////////////////////////////////
8393 /// Print values of all active leaves for entry.
8394 ///
8395 /// - if entry==-1, print current entry (default)
8396 /// - if a leaf is an array, a maximum of lenmax elements is printed.
8397 
8398 void TTree::Show(Long64_t entry, Int_t lenmax)
8400  if (entry != -1) {
8401  Int_t ret = LoadTree(entry);
8402  if (ret == -2) {
8403  Error("Show()", "Cannot read entry %lld (entry does not exist)", entry);
8404  return;
8405  } else if (ret == -1) {
8406  Error("Show()", "Cannot read entry %lld (I/O error)", entry);
8407  return;
8408  }
8409  ret = GetEntry(entry);
8410  if (ret == -1) {
8411  Error("Show()", "Cannot read entry %lld (I/O error)", entry);
8412  return;
8413  } else if (ret == 0) {
8414  Error("Show()", "Cannot read entry %lld (no data read)", entry);
8415  return;
8416  }
8417  }
8418  printf("======> EVENT:%lld\n", fReadEntry);
8419  TObjArray* leaves = GetListOfLeaves();
8420  Int_t nleaves = leaves->GetEntriesFast();
8421  Int_t ltype;
8422  for (Int_t i = 0; i < nleaves; i++) {
8423  TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(i);
8424  TBranch* branch = leaf->GetBranch();
8425  if (branch->TestBit(kDoNotProcess)) {
8426  continue;
8427  }
8428  Int_t len = leaf->GetLen();
8429  if (len <= 0) {
8430  continue;
8431  }
8432  len = TMath::Min(len, lenmax);
8433  if (leaf->IsA() == TLeafElement::Class()) {
8434  leaf->PrintValue(lenmax);
8435  continue;
8436  }
8437  if (branch->GetListOfBranches()->GetEntriesFast() > 0) {
8438  continue;
8439  }
8440  ltype = 10;
8441  if (leaf->IsA() == TLeafF::Class()) {
8442  ltype = 5;
8443  }
8444  if (leaf->IsA() == TLeafD::Class()) {
8445  ltype = 5;
8446  }
8447  if (leaf->IsA() == TLeafC::Class()) {
8448  len = 1;
8449  ltype = 5;
8450  };
8451  printf(" %-15s = ", leaf->GetName());
8452  for (Int_t l = 0; l < len; l++) {
8453  leaf->PrintValue(l);
8454  if (l == (len - 1)) {
8455  printf("\n");
8456  continue;
8457  }
8458  printf(", ");
8459  if ((l % ltype) == 0) {
8460  printf("\n ");
8461  }
8462  }
8463  }
8464 }
8465 
8466 ////////////////////////////////////////////////////////////////////////////////
8467 /// Start the TTreeViewer on this tree.
8468 ///
8469 /// - ww is the width of the canvas in pixels
8470 /// - wh is the height of the canvas in pixels
8471 
8472 void TTree::StartViewer()
8474  GetPlayer();
8475  if (fPlayer) {
8476  fPlayer->StartViewer(600, 400);
8477  }
8478 }
8479 
8480 ////////////////////////////////////////////////////////////////////////////////
8481 /// Stop the cache learning phase
8482 ///
8483 /// Returns:
8484 /// - 0 learning phase stopped or not active
8485 /// - -1 on error
8486 
8489  if (!GetTree()) {
8490  if (LoadTree(0)<0) {
8491  Error("StopCacheLearningPhase","Could not load a tree");
8492  return -1;
8493  }
8494  }
8495  if (GetTree()) {
8496  if (GetTree() != this) {
8497  return GetTree()->StopCacheLearningPhase();
8498  }
8499  } else {
8500  Error("StopCacheLearningPhase", "No tree is available. Could not stop cache learning phase");
8501  return -1;
8502  }
8503 
8504  TFile *f = GetCurrentFile();
8505  if (!f) {
8506  Error("StopCacheLearningPhase", "No file is available. Could not stop cache learning phase");
8507  return -1;
8508  }
8509  TTreeCache *tc = GetReadCache(f,kTRUE);
8510  if (!tc) {
8511  Error("StopCacheLearningPhase", "No cache is available. Could not stop learning phase");
8512  return -1;
8513  }
8514  tc->StopLearningPhase();
8515  return 0;
8516 }
8517 
8518 ////////////////////////////////////////////////////////////////////////////////
8519 /// Set the fTree member for all branches and sub branches.
8520 
8521 static void TBranch__SetTree(TTree *tree, TObjArray &branches)
8523  Int_t nb = branches.GetEntriesFast();
8524  for (Int_t i = 0; i < nb; ++i) {
8525  TBranch* br = (TBranch*) branches.UncheckedAt(i);
8526  br->SetTree(tree);
8527 
8528  Int_t nBaskets = br->GetListOfBaskets()->GetEntries();
8529  Int_t writeBasket = br->GetWriteBasket();
8530  for (Int_t j=writeBasket,n=0;j>=0 && n<nBaskets;--j) {
8531  TBasket *bk = (TBasket*)br->GetListOfBaskets()->UncheckedAt(j);
8532  if (bk) {
8533  tree->IncrementTotalBuffers(bk->GetBufferSize());
8534  ++n;
8535  }
8536  }
8537 
8538  TBranch__SetTree(tree,*br->GetListOfBranches());
8539  }
8540 }
8541 
8542 ////////////////////////////////////////////////////////////////////////////////
8543 /// Set the fTree member for all friend elements.
8544 
8545 void TFriendElement__SetTree(TTree *tree, TList *frlist)
8547  if (frlist) {
8548  TObjLink *lnk = frlist->FirstLink();
8549  while (lnk) {
8550  TFriendElement *elem = (TFriendElement*)lnk->GetObject();
8551  elem->fParentTree = tree;
8552  lnk = lnk->Next();
8553  }
8554  }
8555 }
8556 
8557 ////////////////////////////////////////////////////////////////////////////////
8558 /// Stream a class object.
8559 
8560 void TTree::Streamer(TBuffer& b)
8561 {
8562  if (b.IsReading()) {
8563  UInt_t R__s, R__c;
8564  if (fDirectory) {
8565  fDirectory->Remove(this);
8566  //delete the file cache if it points to this Tree
8567  TFile *file = fDirectory->GetFile();
8568  MoveReadCache(file,0);
8569  }
8570  fDirectory = 0;
8573  Version_t R__v = b.ReadVersion(&R__s, &R__c);
8574  if (R__v > 4) {
8575  b.ReadClassBuffer(TTree::Class(), this, R__v, R__s, R__c);
8576 
8577  fBranches.SetOwner(kTRUE); // True needed only for R__v < 19 and most R__v == 19
8578 
8579  if (fBranchRef) fBranchRef->SetTree(this);
8582 
8583  if (fTreeIndex) {
8584  fTreeIndex->SetTree(this);
8585  }
8586  if (fIndex.fN) {
8587  Warning("Streamer", "Old style index in this tree is deleted. Rebuild the index via TTree::BuildIndex");
8588  fIndex.Set(0);
8589  fIndexValues.Set(0);
8590  }
8591  if (fEstimate <= 10000) {
8592  fEstimate = 1000000;
8593  }
8594  if (GetCacheAutoSize() != 0) {
8595  // a cache will be automatically created.
8596  // No need for TTreePlayer::Process to enable the cache
8597  fCacheSize = 0;
8598  } else if (fAutoFlush < 0) {
8599  // If there is no autoflush set, let's keep the cache completely
8600  // disable by default for now.
8602  } else if (fAutoFlush != 0) {
8603  // Estimate the cluster size.
8604  // This will allow TTree::Process to enable the cache.
8605  if (fZipBytes != 0) {
8607  } else if (fTotBytes != 0) {
8609  } else {
8610  fCacheSize = 30000000;
8611  }
8612  if (fCacheSize >= (INT_MAX / 4)) {
8613  fCacheSize = INT_MAX / 4;
8614  } else if (fCacheSize == 0) {
8615  fCacheSize = 30000000;
8616  }
8617  } else {
8618  fCacheSize = 0;
8619  }
8621  return;
8622  }
8623  //====process old versions before automatic schema evolution
8624  Stat_t djunk;
8625  Int_t ijunk;
8626  TNamed::Streamer(b);
8627  TAttLine::Streamer(b);
8628  TAttFill::Streamer(b);
8629  TAttMarker::Streamer(b);
8630  b >> fScanField;
8631  b >> ijunk; fMaxEntryLoop = (Long64_t)ijunk;
8632  b >> ijunk; fMaxVirtualSize = (Long64_t)ijunk;
8633  b >> djunk; fEntries = (Long64_t)djunk;
8634  b >> djunk; fTotBytes = (Long64_t)djunk;
8635  b >> djunk; fZipBytes = (Long64_t)djunk;
8636  b >> ijunk; fAutoSave = (Long64_t)ijunk;
8637  b >> ijunk; fEstimate = (Long64_t)ijunk;
8638  if (fEstimate <= 10000) fEstimate = 1000000;
8639  fBranches.Streamer(b);
8640  if (fBranchRef) fBranchRef->SetTree(this);
8642  fLeaves.Streamer(b);
8644  if (R__v > 1) fIndexValues.Streamer(b);
8645  if (R__v > 2) fIndex.Streamer(b);
8646  if (R__v > 3) {
8647  TList OldInfoList;
8648  OldInfoList.Streamer(b);
8649  OldInfoList.Delete();
8650  }
8651  fNClusterRange = 0;
8652  fDefaultEntryOffsetLen = 1000;
8654  b.CheckByteCount(R__s, R__c, TTree::IsA());
8655  //====end of old versions
8656  } else {
8657  if (fBranchRef) {
8658  fBranchRef->Clear();
8659  }
8660  TRefTable *table = TRefTable::GetRefTable();
8661  if (table) TRefTable::SetRefTable(0);
8662 
8663  b.WriteClassBuffer(TTree::Class(), this);
8664 
8665  if (table) TRefTable::SetRefTable(table);
8666  }
8667 }
8668 
8669 ////////////////////////////////////////////////////////////////////////////////
8670 /// Unbinned fit of one or more variable(s) from a tree.
8671 ///
8672 /// funcname is a TF1 function.
8673 ///
8674 /// See TTree::Draw for explanations of the other parameters.
8675 ///
8676 /// Fit the variable varexp using the function funcname using the
8677 /// selection cuts given by selection.
8678 ///
8679 /// The list of fit options is given in parameter option.
8680 ///
8681 /// - option = "Q" Quiet mode (minimum printing)
8682 /// - option = "V" Verbose mode (default is between Q and V)
8683 /// - option = "E" Perform better Errors estimation using Minos technique
8684 /// - option = "M" More. Improve fit results
8685 ///
8686 /// You can specify boundary limits for some or all parameters via
8687 /// ~~~ {.cpp}
8688 /// func->SetParLimits(p_number, parmin, parmax);
8689 /// ~~~
8690 /// if parmin>=parmax, the parameter is fixed
8691 ///
8692 /// Note that you are not forced to fix the limits for all parameters.
8693 /// For example, if you fit a function with 6 parameters, you can do:
8694 /// ~~~ {.cpp}
8695 /// func->SetParameters(0,3.1,1.e-6,0.1,-8,100);
8696 /// func->SetParLimits(4,-10,-4);
8697 /// func->SetParLimits(5, 1,1);
8698 /// ~~~
8699 /// With this setup:
8700 ///
8701 /// - Parameters 0->3 can vary freely
8702 /// - Parameter 4 has boundaries [-10,-4] with initial value -8
8703 /// - Parameter 5 is fixed to 100.
8704 ///
8705 /// For the fit to be meaningful, the function must be self-normalized.
8706 ///
8707 /// i.e. It must have the same integral regardless of the parameter
8708 /// settings. Otherwise the fit will effectively just maximize the
8709 /// area.
8710 ///
8711 /// It is mandatory to have a normalization variable
8712 /// which is fixed for the fit. e.g.
8713 /// ~~~ {.cpp}
8714 /// TF1* f1 = new TF1("f1", "gaus(0)/sqrt(2*3.14159)/[2]", 0, 5);
8715 /// f1->SetParameters(1, 3.1, 0.01);
8716 /// f1->SetParLimits(0, 1, 1); // fix the normalization parameter to 1
8717 /// data->UnbinnedFit("f1", "jpsimass", "jpsipt>3.0");
8718 /// ~~~
8719 /// 1, 2 and 3 Dimensional fits are supported. See also TTree::Fit
8720 ///
8721 /// Return status:
8722 ///
8723 /// - The function return the status of the fit in the following form
8724 /// fitResult = migradResult + 10*minosResult + 100*hesseResult + 1000*improveResult
8725 /// - The fitResult is 0 is the fit is OK.
8726 /// - The fitResult is negative in case of an error not connected with the fit.
8727 /// - The number of entries used in the fit can be obtained via mytree.GetSelectedRows();
8728 /// - If the number of selected entries is null the function returns -1
8729 
8730 Int_t TTree::UnbinnedFit(const char* funcname, const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
8732  GetPlayer();
8733  if (fPlayer) {
8734  return fPlayer->UnbinnedFit(funcname, varexp, selection, option, nentries, firstentry);
8735  }
8736  return -1;
8737 }
8738 
8739 ////////////////////////////////////////////////////////////////////////////////
8740 /// Replace current attributes by current style.
8741 
8744  if (gStyle->IsReading()) {
8753  } else {
8762  }
8763 }
8764 
8765 ////////////////////////////////////////////////////////////////////////////////
8766 /// Write this object to the current directory. For more see TObject::Write
8767 /// Write calls TTree::FlushBaskets before writing the tree.
8768 
8769 Int_t TTree::Write(const char *name, Int_t option, Int_t bufsize) const
8771  FlushBaskets();
8772  return TObject::Write(name, option, bufsize);
8773 }
8774 
8775 ////////////////////////////////////////////////////////////////////////////////
8776 /// Write this object to the current directory. For more see TObject::Write
8777 /// If option & kFlushBasket, call FlushBasket before writing the tree.
8778 
8779 Int_t TTree::Write(const char *name, Int_t option, Int_t bufsize)
8781  return ((const TTree*)this)->Write(name, option, bufsize);
8782 }
8783 
8784 ////////////////////////////////////////////////////////////////////////////////
8785 /// \class TTreeFriendLeafIter
8786 ///
8787 /// Iterator on all the leaves in a TTree and its friend
8788 
8791 ////////////////////////////////////////////////////////////////////////////////
8792 /// Create a new iterator. By default the iteration direction
8793 /// is kIterForward. To go backward use kIterBackward.
8794 
8796 : fTree(const_cast<TTree*>(tree))
8797 , fLeafIter(0)
8798 , fTreeIter(0)
8799 , fDirection(dir)
8800 {
8801 }
8802 
8803 ////////////////////////////////////////////////////////////////////////////////
8804 /// Copy constructor. Does NOT copy the 'cursor' location!
8805 
8807 : TIterator(iter)
8808 , fTree(iter.fTree)
8809 , fLeafIter(0)
8810 , fTreeIter(0)
8811 , fDirection(iter.fDirection)
8812 {
8813 }
8814 
8815 ////////////////////////////////////////////////////////////////////////////////
8816 /// Overridden assignment operator. Does NOT copy the 'cursor' location!
8817 
8820  if (this != &rhs && rhs.IsA() == TTreeFriendLeafIter::Class()) {
8821  const TTreeFriendLeafIter &rhs1 = (const TTreeFriendLeafIter &)rhs;
8822  fDirection = rhs1.fDirection;
8823  }
8824  return *this;
8825 }
8826 
8827 ////////////////////////////////////////////////////////////////////////////////
8828 /// Overridden assignment operator. Does NOT copy the 'cursor' location!
8829 
8832  if (this != &rhs) {
8833  fDirection = rhs.fDirection;
8834  }
8835  return *this;
8836 }
8837 
8838 ////////////////////////////////////////////////////////////////////////////////
8839 /// Go the next friend element
8840 
8843  if (!fTree) return 0;
8844 
8845  TObject * next;
8846  TTree * nextTree;
8847 
8848  if (!fLeafIter) {
8849  TObjArray *list = fTree->GetListOfLeaves();
8850  if (!list) return 0; // Can happen with an empty chain.
8851  fLeafIter = list->MakeIterator(fDirection);
8852  if (!fLeafIter) return 0;
8853  }
8854 
8855  next = fLeafIter->Next();
8856  if (!next) {
8857  if (!fTreeIter) {
8858  TCollection * list = fTree->GetListOfFriends();
8859  if (!list) return next;
8860  fTreeIter = list->MakeIterator(fDirection);
8861  if (!fTreeIter) return 0;
8862  }
8863  TFriendElement * nextFriend = (TFriendElement*) fTreeIter->Next();
8864  ///nextTree = (TTree*)fTreeIter->Next();
8865  if (nextFriend) {
8866  nextTree = const_cast<TTree*>(nextFriend->GetTree());
8867  if (!nextTree) return Next();
8868  SafeDelete(fLeafIter);
8869  fLeafIter = nextTree->GetListOfLeaves()->MakeIterator(fDirection);
8870  if (!fLeafIter) return 0;
8871  next = fLeafIter->Next();
8872  }
8873  }
8874  return next;
8875 }
8876 
8877 ////////////////////////////////////////////////////////////////////////////////
8878 /// Returns the object option stored in the list.
8879 
8882  if (fLeafIter) return fLeafIter->GetOption();
8883  return "";
8884 }
TString fTitle
Definition: TNamed.h:37
TTree * fParentTree
void Add(TObject *obj, const char *name=0, Int_t check=-1)
Add object with name to browser.
Definition: TBrowser.cxx:259
virtual Int_t GetLen() const
Return the number of effective elements of this leaf.
Definition: TLeaf.cxx:276
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:47
virtual void UpdateAddress()
Definition: TBranch.h:217
virtual Bool_t cd(const char *path=0)
Change current directory to "this" directory.
virtual TBranch * FindBranch(const char *name)
Return the branch that correspond to the path 'branchname', which can include the name of the tree or...
Definition: TTree.cxx:4492
virtual Int_t GetEntries() const
Definition: TCollection.h:92
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition: TObject.cxx:823
virtual Bool_t GetReapplyCut() const
Definition: TEventList.h:59
Double_t fWeight
Definition: TTree.h:106
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1213
virtual Int_t MakeProxy(const char *classname, const char *macrofilename=0, const char *cutfilename=0, const char *option=0, Int_t maxUnrolling=3)=0
virtual Style_t GetLineStyle() const
Definition: TAttLine.h:48
virtual Style_t GetFillStyle() const
Definition: TAttFill.h:44
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition: TLeaf.h:37
virtual void SetLineWidth(Width_t lwidth)
Definition: TAttLine.h:57
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:851
TTreeCache * GetReadCache(TFile *file, Bool_t create=kFALSE)
Find and return the TTreeCache registered with the file and which may contain branches for us...
Definition: TTree.cxx:5648
A TFolder object is a collection of objects and folders.
Definition: TFolder.h:32
virtual void ResetAfterMerge(TFileMergeInfo *)
Reset a Branch after a Merge operation (drop data but keep customizations) TRefTable is cleared...
Definition: TBranchRef.cxx:196
virtual TList * GetListOfClones()
Definition: TTree.h:408
TList * GetListOfBases()
Return list containing the TBaseClass(es) of a class.
Definition: TClass.cxx:3368
virtual TTree * CopyTree(const char *selection, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)=0
ESTLType
Definition: ESTLType.h:28
TStreamerInfo * BuildStreamerInfo(TClass *cl, void *pointer=0, Bool_t canOptimize=kTRUE)
Build StreamerInfo for class cl.
Definition: TTree.cxx:2523
An array of TObjects.
Definition: TObjArray.h:39
static TDataType * GetDataType(EDataType type)
Given a EDataType type, get the TDataType* that represents it.
Definition: TDataType.cxx:436
Long64_t fDebugMin
Debug level.
Definition: TTree.h:128
Principal Components Analysis (PCA)
Definition: TPrincipal.h:28
virtual Long64_t GetAutoSave() const
Definition: TTree.h:372
Bool_t IsAutoCreated() const
Definition: TTreeCache.h:89
virtual void Append(const TVirtualIndex *, Bool_t delaySort=kFALSE)=0
virtual void PrintValue(Int_t i=0) const
Definition: TLeaf.h:123
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
Bool_t fPrevious
Definition: TTree.h:185
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:405
virtual void UpdateFile()
Refresh the value of fDirectory (i.e.
Definition: TBranch.cxx:2644
Bool_t CanSplit() const
Return true if the data member of this TClass can be saved separately.
Definition: TClass.cxx:2152
static Vc_ALWAYS_INLINE int_v min(const int_v &x, const int_v &y)
Definition: vector.h:433
TString GetTypeName()
Get basic type of typedef, e,g.
Definition: TDataType.cxx:149
virtual TTree * GetTree()
Return pointer to friend TTree.
The concrete implementation of TBuffer for writing/reading to/from a ROOT file or socket...
Definition: TBufferFile.h:51
virtual void SetAddress(void *add)
Set address of this branch.
Definition: TBranch.cxx:2049
virtual void OptimizeBaskets(ULong64_t maxMemory=10000000, Float_t minComp=1.1, Option_t *option="")
This function may be called after having filled some entries in a Tree Using the information in the e...
Definition: TTree.cxx:6350
virtual const char * GetFriendAlias(TTree *) const
If the 'tree' is a friend, this method returns its alias name.
Definition: TTree.cxx:5371
Bool_t MemoryFull(Int_t nbytes)
Check if adding nbytes to memory we are still below MaxVirtualsize.
Definition: TTree.cxx:6157
virtual TBranch * BranchImpRef(const char *branchname, const char *classname, TClass *ptrClass, void *addobj, Int_t bufsize, Int_t splitlevel)
Same as TTree::Branch but automatic detection of the class name.
Definition: TTree.cxx:1443
Long64_t fTotalBuffers
Number of the entry being processed.
Definition: TTree.h:124
virtual Int_t MakeCode(const char *filename=0)
Generate a skeleton function for this tree.
Definition: TTree.cxx:5960
long long Long64_t
Definition: RtypesCore.h:69
Abstract interface for Tree Index.
Definition: TVirtualIndex.h:31
virtual TLeaf * GetLeaf(const char *name) const
Return pointer to the 1st Leaf named name in thisBranch.
Definition: TBranch.cxx:1460
virtual Int_t MakeReader(const char *classname, Option_t *option)=0
virtual const char * GetName() const
Return name of this collection.
virtual Int_t StopCacheLearningPhase()
Stop the cache learning phase.
Definition: TTree.cxx:8488
Bool_t IsReading() const
Definition: TBuffer.h:83
virtual void SetBranchStatus(const char *bname, Bool_t status=1, UInt_t *found=0)
Set branch status to Process or DoNotProcess.
Definition: TTree.cxx:7656
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:487
virtual TList * GetListOfKeys() const
Definition: TDirectory.h:158
virtual void IncrementTotalBuffers(Int_t nbytes)
Definition: TTree.h:464
short Version_t
Definition: RtypesCore.h:61
virtual void Delete(Option_t *option="")
Delete this tree from memory or/and disk.
Definition: TTree.cxx:3500
Int_t GetType() const
Definition: TDataType.h:70
A Branch for the case of an object.
Definition: TBranchObject.h:28
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
Ssiz_t Length() const
Definition: TString.h:390
TObjArray * GetListOfBaskets()
Definition: TBranch.h:176
TLine * line
static Int_t fgBranchStyle
true if the cache setting was explicitly given by user
Definition: TTree.h:153
virtual void SetTree(const TTree *T)=0
virtual Int_t LoadBaskets(Long64_t maxmemory=2000000000)
Read in memory all baskets from all branches up to the limit of maxmemory bytes.
Definition: TTree.cxx:5764
virtual void Clear(Option_t *option="")
Remove all objects from the array.
Definition: TObjArray.cxx:298
float Float_t
Definition: RtypesCore.h:53
virtual Int_t GetExpectedType(TClass *&clptr, EDataType &type)
Fill expectedClass and expectedType with information on the data type of the object/values contained ...
Definition: TBranch.cxx:1363
static Long64_t GetMaxTreeSize()
Static function which returns the tree file size limit in bytes.
Definition: TTree.cxx:5595
virtual void SetParallelUnzip(Bool_t opt=kTRUE, Float_t RelSize=-1)
Enable or disable parallel unzipping of Tree buffers.
Definition: TTree.cxx:8329
virtual Int_t MakeCode(const char *filename)=0
Provides the interface for the PROOF internal performance measurement and event tracing.
Style_t GetHistLineStyle() const
Definition: TStyle.h:244
return c
A cache when reading files over the network.
const char Option_t
Definition: RtypesCore.h:62
virtual Bool_t Notify()
Function called when loading a new class library.
Definition: TTree.cxx:6326
TTree()
Default constructor and I/O constructor.
Definition: TTree.cxx:625
void GetObject(const char *namecycle, T *&ptr)
Definition: TDirectory.h:147
virtual TClass * GetValueClass() const =0
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:329
tuple offset
Definition: tree.py:93
virtual Long64_t GetReadEntry() const
Definition: TTree.h:428
All ROOT classes may have RTTI (run time type identification) support added.
Definition: TDataMember.h:33
TBuffer * fTransientBuffer
Record which method is locking the friend recursion.
Definition: TTree.h:149
virtual void Flush()
Synchronize a file's in-memory and on-disk states.
Definition: TFile.cxx:1080
virtual void SetCacheRead(TFileCacheRead *cache, TObject *tree=0, ECacheAction action=kDisconnect)
Set a pointer to the read cache.
Definition: TFile.cxx:2177
virtual Int_t Fit(const char *funcname, const char *varexp, const char *selection="", Option_t *option="", Option_t *goption="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Fit a projected item(s) from a tree.
Definition: TTree.cxx:4720
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
R__EXTERN TStyle * gStyle
Definition: TStyle.h:423
TList * fFriends
Definition: TTree.h:142
void SetHistLineWidth(Width_t width=1)
Definition: TStyle.h:378
TPrincipal * Principal(const char *varexp="", const char *selection="", Option_t *option="np", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Interface to the Principal Components Analysis class.
Definition: TTree.cxx:6476
const char Int_t perf
Definition: TXSlave.cxx:46
virtual Int_t Fill()
Fill all branches.
Definition: TTree.cxx:4306
virtual TEntryList * GetEntryList()
Returns the entry list, set to this tree.
Definition: TTree.cxx:5194
virtual void SetName(const char *name)
Change (i.e.
Definition: TNamed.cxx:128
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual TList * GetList() const
Definition: TDirectory.h:157
virtual void DropBaskets(Option_t *option="")
Loop on all branch baskets.
Definition: TBranch.cxx:627
Long64_t GetCacheAutoSize(Bool_t withDefault=kFALSE) const
Used for automatic sizing of the cache.
Definition: TTree.cxx:4926
Bool_t IsTObject() const
Return kTRUE is the class inherits from TObject.
Definition: TClass.cxx:5462
static void SetBranchStyle(Int_t style=1)
Set the current branch style.
Definition: TTree.cxx:7770
A specialized TFileCacheRead object for a TTree.
Definition: TTreeCache.h:34
virtual TLeaf * GetLeaf(const char *branchname, const char *leafname)
Return pointer to the 1st Leaf named name in any Branch of this Tree or any branch in the list of fri...
Definition: TTree.cxx:5520
virtual Long64_t GetEntriesFriend() const
Return pointer to the 1st Leaf named name in any Branch of this Tree or any branch in the list of fri...
Definition: TTree.cxx:5020
TTree * fTree
Definition: TTree.h:183
static Int_t SetParallelUnzip(TTreeCacheUnzip::EParUnzipMode option=TTreeCacheUnzip::kEnable)
Static function that (de)activates multithreading unzipping.
Double_t Atof() const
Return floating-point value contained in string.
Definition: TString.cxx:2017
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:892
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:45
virtual TLeaf * GetLeafImpl(const char *branchname, const char *leafname)
Return pointer to the 1st Leaf named name in any Branch of this Tree or any branch in the list of fri...
Definition: TTree.cxx:5430
Long64_t GetTotBytes(Option_t *option="") const
Return total number of bytes in the branch (excluding current buffer) if option ="*" includes all sub...
Definition: TBranch.cxx:1618
virtual void Print(Option_t *option="") const
Print TBranch parameters.
Definition: TBranch.cxx:1727
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
Regular expression class.
Definition: TRegexp.h:35
TDirectory * fDirectory
Object to be notified when loading a Tree.
Definition: TTree.h:133
static const char * filename()
Bool_t IsPersistent() const
Definition: TDataMember.h:89
Int_t fMakeClass
Last entry number to debug.
Definition: TTree.h:130
#define R__ASSERT(e)
Definition: TError.h:98
virtual TBasket * CreateBasket(TBranch *)
Create a basket for this tree and given branch.
Definition: TTree.cxx:3484
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
#define gROOT
Definition: TROOT.h:344
TList * GetListOfDataMembers(Bool_t load=kTRUE)
Return list containing the TDataMembers of a class.
Definition: TClass.cxx:3459
virtual Int_t WriteTObject(const TObject *obj, const char *name=0, Option_t *="", Int_t=0)
See TDirectoryFile::WriteTObject for details.
void ForceWriteInfo(TFile *file, Bool_t force=kFALSE)
Recursively mark streamer infos for writing to a file.
virtual TPrincipal * Principal(const char *varexp="", const char *selection="", Option_t *option="np", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)=0
TObject * ob
virtual void SetAutoSave(Long64_t autos=-300000000)
This function may be called at the start of a program to change the default value for fAutoSave (and ...
Definition: TTree.cxx:7467
virtual Int_t GetEntry(Long64_t entry=0, Int_t getall=0)
Read all branches of entry and return total number of bytes read.
Definition: TTree.cxx:5144
virtual Int_t ReadKeys(Bool_t=kTRUE)
Definition: TDirectory.h:182
Bool_t IsZombie() const
Definition: TObject.h:141
Basic string class.
Definition: TString.h:137
virtual TTree * GetFriend(const char *) const
Return a pointer to the TTree friend whose name or alias is 'friendname.
Definition: TTree.cxx:5314
virtual void SetAddress(void *addobj)
Point this branch at an object.
virtual Int_t MakeProxy(const char *classname, const char *macrofilename=0, const char *cutfilename=0, const char *option=0, Int_t maxUnrolling=3)
Generate a skeleton analysis class for this Tree using TBranchProxy.
Definition: TTree.cxx:6088
virtual Long64_t GetEntryNumberWithBestIndex(Long64_t major, Long64_t minor) const =0
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
virtual void SetTargetClass(const char *name)
Set the name of the class of the in-memory object into which the data will loaded.
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1075
static TBranch * R__FindBranchHelper(TObjArray *list, const char *branchname)
Search in the array for a branch matching the branch name, with the branch possibly expressed as a 'f...
Definition: TTree.cxx:4444
TAlienJobStatus * status
Definition: TAlienJob.cxx:51
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TDataType * GetDataType() const
Definition: TDataMember.h:74
virtual void PrintCacheStats(Option_t *option="") const
print statistics about the TreeCache for this tree, like ******TreeCache statistics for file: cms2...
Definition: TTree.cxx:6609
Bool_t IsaPointer() const
Return true if data member is a pointer.
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual void Browse(TBrowser *)
Browse content of the TTree.
Definition: TTree.cxx:2483
constexpr std::array< decltype(std::declval< F >)(std::declval< int >))), N > make(F f)
virtual void SetFillStyle(Style_t fstyle)
Definition: TAttFill.h:52
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:497
TBranch * GetBranch() const
Definition: TLeaf.h:70
virtual Long64_t GetBasketSeek(Int_t basket) const
Return address of basket in the file.
Definition: TBranch.cxx:1144
virtual void StopLearningPhase()
This is the counterpart of StartLearningPhase() and can be used to stop the learning phase...
virtual Long64_t GetEntryNumber(Long64_t entry) const
Return entry number corresponding to entry.
Definition: TTree.cxx:5205
Int_t fScanField
Definition: TTree.h:108
virtual Long64_t GetEND() const
Definition: TFile.h:191
virtual Int_t FlushBaskets() const
Write to disk all the basket that have not yet been individually written.
Definition: TTree.cxx:4734
Int_t GetEntriesFast() const
Definition: TObjArray.h:66
virtual TTree * CloneTree(Long64_t nentries=-1, Option_t *option="")
Create a clone of this tree and copy nentries.
Definition: TTree.cxx:2960
virtual TTree * CopyTree(const char *selection, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Copy a tree with selection.
Definition: TTree.cxx:3472
Definition: drr.cxx:518
virtual TVirtualIndex * GetTreeIndex() const
Definition: TTree.h:437
virtual void KeepCircular()
Keep a maximum of fMaxEntries in memory.
Definition: TTree.cxx:5728
TArrayD fIndexValues
Pointer to event selection list (if one)
Definition: TTree.h:139
Style_t GetHistFillStyle() const
Definition: TStyle.h:243
TTree * GetTree() const
Definition: TTreeCache.h:88
void SetAutoCreated(Bool_t val)
Definition: TTreeCache.h:101
TFile * GetCurrentFile() const
Return pointer to the current file.
Definition: TTree.cxx:4987
virtual EDataType GetType() const =0
virtual Long64_t GetEntries(const char *)=0
Long64_t fMaxEntryLoop
Definition: TTree.h:114
TVirtualTreePlayer * GetPlayer()
Load the TTreePlayer (if not already done).
Definition: TTree.cxx:5634
virtual void SetMaxVirtualSize(Long64_t size=0)
Definition: TTree.h:545
virtual TSQLResult * Query(const char *varexp="", const char *selection="", Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Loop over entries and return a TSQLResult object containing entries following selection.
Definition: TTree.cxx:6750
Streamer around an arbitrary STL like container, which implements basic container functionality...
virtual Int_t AddBranch(TBranch *b, Bool_t subgbranches=kFALSE)
Add a branch to the list of branches to be stored in the cache this function is called by TBranch::Ge...
Definition: TTreeCache.cxx:330
virtual Int_t DeleteGlobal(void *obj)=0
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:311
virtual void SetupAddresses()
If the branch address is not set, we set all addresses starting with the top level parent branch...
Definition: TBranch.cxx:2634
virtual void SetTree(const TTree *tree)
If a list for a tree with such name and filename exists, sets it as the current sublist If not...
TIterator * MakeIterator(Bool_t dir=kIterForward) const
Returns an array iterator.
Definition: TObjArray.cxx:591
Iterator abstract base class.
Definition: TIterator.h:32
const char * GetFullTypeName() const
Get full type description of data member, e,g.: "class TDirectory*".
virtual void Print(Option_t *option="") const
Print cache statistics.
Definition: TTreeCache.cxx:994
void Reset()
Definition: TCollection.h:161
TFile * f
void BypassStreamer(Bool_t bypass=kTRUE)
When the kBypassStreamer bit is set, the automatically generated Streamer can call directly TClass::W...
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
virtual void Reset(Option_t *option="")
Definition: TBranchRef.cxx:185
const char * GetArrayIndex() const
If the data member is pointer and has a valid array size in its comments GetArrayIndex returns a stri...
virtual Int_t Fit(const char *formula, const char *varexp, const char *selection, Option_t *option, Option_t *goption, Long64_t nentries, Long64_t firstentry)=0
virtual void Refresh()
Refresh contents of this tree and its branches from the current status on disk.
Definition: TTree.cxx:7129
virtual void SetFileNumber(Int_t number=0)
Set fFileNumber to number.
Definition: TTree.cxx:8227
virtual Double_t GetMinimum(const char *columname)
Return minimum of column with name columname.
Definition: TTree.cxx:5605
virtual void DirectoryAutoAdd(TDirectory *)
Called by TKey and TObject::Clone to automatically add us to a directory when we are read from a file...
Definition: TTree.cxx:3572
static Bool_t IsParallelUnzip()
Static function that tells wether the multithreading unzipping is activated.
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=1, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3851
virtual void SetTree(TTree *tree)
Definition: TBranch.h:215
virtual void SetDirectory(TDirectory *dir)
Add reference to directory dir. dir can be 0.
TList * GetListOfRealData() const
Definition: TClass.h:404
static void SetRefTable(TRefTable *table)
Static function setting the current TRefTable.
Definition: TRefTable.cxx:383
virtual Int_t GetN() const
Definition: TEventList.h:58
virtual void StartViewer()
Start the TTreeViewer on this tree.
Definition: TTree.cxx:8473
virtual Long64_t Merge(TCollection *list, Option_t *option="")
Merge the trees in the TList into this tree.
Definition: TTree.cxx:6214
Marker Attributes class.
Definition: TAttMarker.h:32
tuple branch1
Definition: tree.py:57
const char * Data() const
Definition: TString.h:349
virtual void Print(Option_t *option="") const
Print a summary of the tree contents.
Definition: TTree.cxx:6495
virtual void SetBranchFolder()
virtual TKey * GetKey(const char *, Short_t=9999) const
Definition: TDirectory.h:156
TFileCacheRead * GetCacheRead(TObject *tree=0) const
Return a pointer to the current read cache.
Definition: TFile.cxx:1196
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:946
virtual Int_t GetEntryWithIndex(Int_t major, Int_t minor=0)
Read entry corresponding to major and minor number.
Definition: TTree.cxx:5267
TList * fAliases
Definition: TTree.h:136
virtual Long64_t DrawSelect(const char *varexp, const char *selection, Option_t *option, Long64_t nentries, Long64_t firstentry)=0
#define SafeDelete(p)
Definition: RConfig.h:436
virtual TObjArray * GetListOfBranches()
Definition: TTree.h:409
Helper class to iterate over cluster of baskets.
Definition: TTree.h:249
TVirtualTreePlayer * fPlayer
Definition: TTree.h:145
Double_t dot(const TVector2 &v1, const TVector2 &v2)
Definition: CsgOps.cxx:333
Fill Area Attributes class.
Definition: TAttFill.h:32
void ImportClusterRanges(TTree *fromtree)
Appends the cluster range information stored in 'fromtree' to this tree, including the value of fAuto...
Definition: TTree.cxx:5689
virtual void SetAutoFlush(Long64_t autof=-30000000)
This function may be called at the start of a program to change the default value for fAutoFlush...
Definition: TTree.cxx:7382
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2321
TBonjourRegistrar * reg
Definition: hserv2bonj.C:28
Int_t GetCompressionLevel() const
Definition: TFile.h:357
virtual const char * GetTreeName() const
virtual Long64_t CopyEntries(TTree *tree, Long64_t nentries=-1, Option_t *option="")
Copy nentries from given tree to this tree.
Definition: TTree.cxx:3322
virtual Int_t SetBranchAddress(const char *bname, void *add, TBranch **ptr=0)
Change branch address, dealing with clone trees properly.
Definition: TTree.cxx:7510
void SetHistFillColor(Color_t color=1)
Definition: TStyle.h:374
Int_t fNfill
Number of entries in one packet for parallel root.
Definition: TTree.h:126
Int_t bsize[]
Definition: SparseFit4.cxx:31
virtual void SetObject(const char *name, const char *title)
Change the name and title of this tree.
Definition: TTree.cxx:8298
virtual void ReadValue(std::istream &, Char_t= ' ')
Definition: TLeaf.h:95
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
Int_t GetNbytes() const
Definition: TKey.h:88
void Class()
Definition: Class.C:29
virtual Bool_t Notify()
This method must be overridden to handle object notification.
Definition: TObject.cxx:550
virtual Long64_t LoadTree(Long64_t entry)
Set current entry.
Definition: TTree.cxx:5785
Bool_t fCacheUserSet
true if cache auto creation or resize check is needed
Definition: TTree.h:151
virtual void SetTreeIndex(TVirtualIndex *index)
The current TreeIndex is replaced by the new index.
Definition: TTree.cxx:8360
Int_t fMaxClusterRange
Definition: TTree.h:112
static Int_t GetBranchStyle()
Static function returning the current branch style.
Definition: TTree.cxx:4914
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition: TClass.cxx:4602
virtual Int_t BuildIndex(const char *majorname, const char *minorname="0")
Build a Tree Index (default is TTreeIndex).
Definition: TTree.cxx:2508
virtual Int_t UnbinnedFit(const char *funcname, const char *varexp, const char *selection="", Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Unbinned fit of one or more variable(s) from a tree.
Definition: TTree.cxx:8731
virtual Bool_t SetMakeClass(Bool_t decomposeObj=kTRUE)
Set the branch in a mode where the object are decomposed (Also known as MakeClass mode)...
Definition: TBranch.cxx:2294
virtual TBranch * BranchOld(const char *name, const char *classname, void *addobj, Int_t bufsize=32000, Int_t splitlevel=1)
Create a new TTree BranchObject.
Definition: TTree.cxx:1856
TClass * GetActualClass(const void *object) const
Return a pointer the the real class of the object.
Definition: TClass.cxx:2457
virtual void Show(Long64_t entry=-1, Int_t lenmax=20)
Print values of all active leaves for entry.
Definition: TTree.cxx:8399
std::map< std::string, std::string >::const_iterator iter
Definition: TAlienJob.cxx:54
virtual Int_t GetBufferSize() const
virtual TBranch * FindBranch(const char *name)
Find the immediate sub-branch with passed name.
Definition: TBranch.cxx:894
TBranchRef * fBranchRef
List of cloned trees which share our addresses.
Definition: TTree.h:147
virtual Int_t MakeClass(const char *classname=0, Option_t *option="")
Generate a skeleton analysis class for this tree.
Definition: TTree.cxx:5927
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1575
virtual TClusterIterator GetClusterIterator(Long64_t firstentry)
Return an iterator over the cluster of baskets starting at firstentry.
Definition: TTree.cxx:4976
virtual void SetMarkerColor(Color_t mcolor=1)
Definition: TAttMarker.h:51
const Int_t kDoNotProcess
Definition: TBranch.h:52
UInt_t fFriendLockStatus
Definition: TTree.h:148
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
const int maxsize
virtual Int_t MakeClass(const char *classname, const char *option)=0
Int_t fTimerInterval
Definition: TTree.h:107
Long64_t GetEntries() const
Definition: TBranch.h:182
virtual TFriendElement * AddFriend(const char *treename, const char *filename="")
Add a TFriendElement to the list of friends.
Definition: TTree.cxx:1156
Long64_t GetZipBytes(Option_t *option="") const
Return total number of zip bytes in the branch if option ="*" includes all sub-branches of this branc...
Definition: TBranch.cxx:1636
Bool_t IsWritable() const
virtual Long64_t Scan(const char *varexp="", const char *selection="", Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Loop over tree entries and print entries passing selection.
Definition: TTree.cxx:7285
Long64_t fFlushedBytes
Definition: TTree.h:105
TObjArray * GetListOfBranches()
Definition: TBranch.h:177
Specialization of TTreeCache for parallel Unzipping.
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:63
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:30
XFontStruct * id
Definition: TGX11.cxx:108
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
Bool_t IsObject() const
Definition: TRealData.h:60
virtual void Delete(Option_t *option="")
Delete an object from the file.
Definition: TKey.cxx:531
virtual Double_t GetMaximum(const char *columname)
Return maximum of column with name columname.
Definition: TTree.cxx:5566
void Set(Int_t n)
Set size of this array to n ints.
Definition: TArrayI.cxx:105
virtual void RemoveFriend(TTree *)
Remove a friend from the list of friends.
Definition: TTree.cxx:7168
virtual void SetAddress(void *add=0)
Definition: TLeaf.h:124
virtual TList * GetUserInfo()
Return a pointer to the list containing user objects associated to this tree.
Definition: TTree.cxx:5673
virtual void SetCacheLearnEntries(Int_t n=10)
Interface to TTreeCache to set the number of entries for the learning phase.
Definition: TTree.cxx:7963
A branch containing and managing a TRefTable for TRef autoloading.
Definition: TBranchRef.h:33
Long64_t fZipBytes
Definition: TTree.h:103
Long64_t fDebugMax
First entry number to debug.
Definition: TTree.h:129
virtual Double_t GetValue(Int_t i=0) const
Definition: TLeaf.h:122
virtual TBranch * BranchImp(const char *branchname, const char *classname, TClass *ptrClass, void *addobj, Int_t bufsize, Int_t splitlevel)
Same as TTree::Branch() with added check that addobj matches className.
Definition: TTree.cxx:1362
virtual void SetEventList(TEventList *list)
This function transfroms the given TEventList into a TEntryList The new TEntryList is owned by the TT...
Definition: TTree.cxx:8164
void Expand(Int_t newsize, Bool_t copy=kTRUE)
Expand (or shrink) the I/O buffer to newsize bytes.
Definition: TBuffer.cxx:199
ClassImp(TTree) static char DataTypeToChar(EDataType datatype)
Definition: TTree.cxx:396
void UseCurrentStyle()
Replace current attributes by current style.
Definition: TTree.cxx:8743
A specialized string object used for TTree selections.
Definition: TCut.h:27
A doubly linked list.
Definition: TList.h:47
virtual void ResetAfterMerge(TFileMergeInfo *)
Reset a Branch.
Definition: TBranch.cxx:1965
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition: TTree.cxx:4803
Bool_t fCacheDoAutoInit
Pointer to the current transient buffer.
Definition: TTree.h:150
virtual TFile * GetFile() const
Definition: TDirectory.h:155
Int_t GetRecordHeader(char *buf, Long64_t first, Int_t maxbytes, Int_t &nbytes, Int_t &objlen, Int_t &keylen)
Read the logical record header starting at a certain postion.
Definition: TFile.cxx:1233
virtual Int_t GetMaximum() const
Definition: TLeaf.h:76
virtual Int_t Fill()
Loop on all leaves of this branch to fill Basket buffer.
Definition: TBranch.cxx:724
TObject * UncheckedAt(Int_t i) const
Definition: TObjArray.h:91
TObjArray fLeaves
Definition: TTree.h:135
Long64_t * fClusterRangeEnd
Definition: TTree.h:119
static TVirtualTreePlayer * TreePlayer(TTree *obj)
virtual Long64_t GetTotBytes() const
Definition: TTree.h:435
virtual void SetLineColor(Color_t lcolor)
Definition: TAttLine.h:54
Bool_t IsReading() const
Definition: TStyle.h:296
void BuildRealData(void *pointer=0, Bool_t isTransient=kFALSE)
Build a full list of persistent data members.
Definition: TClass.cxx:1933
Int_t GetBufferSize() const
Definition: TBasket.h:75
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:41
Int_t fNClusterRange
Definition: TTree.h:111
Int_t fN
Definition: TArray.h:40
virtual Long64_t GetEntry(Int_t index) const
Return value of entry at index in the list.
Definition: TEventList.cxx:220
Bool_t HasRuleWithSourceClass(const TString &source) const
Return True if we have any rule whose source class is 'source'.
virtual char * GetAddress() const
Definition: TBranch.h:146
TEntryList * fEntryList
Pointer to event selection list (if one)
Definition: TTree.h:138
void SetParentClass(TClass *clparent)
virtual Size_t GetMarkerSize() const
Definition: TAttMarker.h:46
TThread * t[5]
Definition: threadsh1.C:13
virtual void SetEntryRange(Long64_t emin, Long64_t emax)
Set the minimum and maximum entry number to be processed this information helps to optimize the numbe...
const char * GetTypeName() const
Get type of data member, e,g.: "class TDirectory*" -> "TDirectory".
Option_t * GetOption() const
Returns the object option stored in the list.
Definition: TTree.cxx:8881
Color_t GetHistFillColor() const
Definition: TStyle.h:241
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition: TTree.cxx:8780
TVirtualStreamerInfo * FindConversionStreamerInfo(const char *onfile_classname, UInt_t checksum) const
Return a Conversion StreamerInfo from the class 'classname' for the layout represented by 'checksum' ...
Definition: TClass.cxx:6619
virtual void SetEstimate(Long64_t nentries=1000000)
Set number of entries to estimate variable limits.
Definition: TTree.cxx:8205
Width_t GetHistLineWidth() const
Definition: TStyle.h:245
virtual void SetOffset(Int_t offset=0)
Definition: TBranch.h:213
virtual Long64_t Process(const char *filename, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)=0
virtual void UpdateFormulaLeaves()=0
virtual Int_t DropBranch(TBranch *b, Bool_t subbranches=kFALSE)
Remove a branch to the list of branches to be stored in the cache this function is called by TBranch:...
Definition: TTreeCache.cxx:482
void SetHistFillStyle(Style_t styl=0)
Definition: TStyle.h:376
TObjArray * GetElements() const
void SetCompressionSettings(Int_t settings=1)
Set compression settings.
Definition: TBranch.cxx:2172
R__EXTERN TSystem * gSystem
Definition: TSystem.h:545
Long64_t fChainOffset
Maximum size of file buffers.
Definition: TTree.h:122
~TFriendLock()
Restore the state of tree the same as before we set the lock.
Definition: TTree.cxx:483
Long64_t * fClusterSize
Definition: TTree.h:120
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist...
Definition: TClass.cxx:4256
Bool_t EqualTo(const char *cs, ECaseCompare cmp=kExact) const
Definition: TString.h:576
TPaveLabel title(3, 27.1, 15, 28.7,"ROOT Environment and Tools")
virtual void WriteStreamerInfo()
Write the list of TStreamerInfo as a single object in this file The class Streamer description for al...
Definition: TFile.cxx:3561
virtual void SetFillColor(Color_t fcolor)
Definition: TAttFill.h:50
Basic data type descriptor (datatype information is obtained from CINT).
Definition: TDataType.h:46
void TFriendElement__SetTree(TTree *tree, TList *frlist)
Set the fTree member for all friend elements.
Definition: TTree.cxx:8546
TVirtualPerfStats * fPerfStats
Definition: TTree.h:143
virtual Int_t GetTreeNumber() const
Definition: TTree.h:438
virtual TIterator * MakeIterator(Bool_t dir=kIterForward) const =0
virtual TObject * RemoveAt(Int_t idx)
Remove object at index idx.
Definition: TObjArray.cxx:630
TDirectory * GetDirectory() const
Definition: TTree.h:385
TVirtualStreamerInfo * GetConversionStreamerInfo(const char *onfile_classname, Int_t version) const
Return a Conversion StreamerInfo from the class 'classname' for version number 'version' to this clas...
Definition: TClass.cxx:6522
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:494
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:187
virtual Int_t ReadTObject(TObject *, const char *)
Definition: TDirectory.h:183
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:675
Long64_t fReadEntry
Offset of 1st entry of this Tree in a TChain.
Definition: TTree.h:123
virtual Bool_t HasPointers() const =0
virtual ~TTree()
Destructor.
Definition: TTree.cxx:800
virtual Color_t GetFillColor() const
Definition: TAttFill.h:43
Collection abstract base class.
Definition: TCollection.h:48
virtual const char * GetAlias(const char *aliasName) const
Returns the expanded value of the alias. Search in the friends if any.
Definition: TTree.cxx:4762
TClass * IsA() const
void Destructor(void *obj, Bool_t dtorOnly=kFALSE)
Explicitly call destructor for object.
Definition: TClass.cxx:4959
TBranch * GetMother() const
Get our top-level parent branch in the tree.
Definition: TBranch.cxx:1533
TList * fUserInfo
pointer to the current perf stats object
Definition: TTree.h:144
TObjArray fBranches
Pointer to directory holding this tree.
Definition: TTree.h:134
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2308
unsigned int UInt_t
Definition: RtypesCore.h:42
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
virtual Long64_t GetN() const =0
static void SetMaxTreeSize(Long64_t maxsize=1900000000)
Set the maximum size in bytes of a Tree file (static function).
Definition: TTree.cxx:8261
virtual Long64_t GetEntry(Int_t index)
Return the number of the entry #index of this TEntryList in the TTree or TChain See also Next()...
Definition: TEntryList.cxx:653
virtual void MakeFree(Long64_t first, Long64_t last)
Mark unused bytes on the file.
Definition: TFile.cxx:1388
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
Definition: TDirectory.cxx:151
bool first
Definition: line3Dfit.C:48
Manages buffers for branches of a Tree.
Definition: TBasket.h:38
tuple w
Definition: qtexample.py:51
virtual TBranchRef * GetBranchRef() const
Definition: TTree.h:374
A TEventList object is a list of selected events (entries) in a TTree.
Definition: TEventList.h:33
TLine * l
Definition: textangle.C:4
virtual TLeaf * FindLeaf(const char *name)
Find leaf..
Definition: TTree.cxx:4564
The TRealData class manages the effective list of all data members for a given class.
Definition: TRealData.h:34
virtual Int_t GetEntry(Long64_t entry=0, Int_t getall=0)
Read all leaves of entry and return total number of bytes read.
Definition: TBranch.cxx:1199
virtual Long64_t GetEntryNumberWithIndex(Long64_t major, Long64_t minor=0) const
Return entry number corresponding to major and minor number.
Definition: TTree.cxx:5250
Bool_t CanIgnoreTObjectStreamer()
Definition: TClass.h:357
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
TArrayI fIndex
Definition: TTree.h:140
TSubString Strip(EStripType s=kTrailing, char c= ' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1056
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
virtual void SetMarkerStyle(Style_t mstyle=1)
Definition: TAttMarker.h:53
static void SetLearnEntries(Int_t n=10)
Static function to set the number of entries to be used in learning mode The default value for n is 1...
Version_t GetClassVersion() const
Definition: TClass.h:381
Bool_t IsNull() const
Definition: TString.h:387
virtual TObjLink * FirstLink() const
Definition: TList.h:101
void SetName(const char *name)
Definition: TCollection.h:116
virtual void ResetBranchAddress(TBranch *)
Tell all of our branches to set their addresses to zero.
Definition: TTree.cxx:7256
Bool_t fDirection
Definition: TTree.h:582
virtual Color_t GetLineColor() const
Definition: TAttLine.h:47
Long64_t entry
TEventList * fEventList
Definition: TTree.h:137
TString fName
Definition: TNamed.h:36
virtual TBranch * Bronch(const char *name, const char *classname, void *addobj, Int_t bufsize=32000, Int_t splitlevel=99)
Create a new TTree BranchElement.
Definition: TTree.cxx:2186
virtual void SetMarkerSize(Size_t msize=1)
Definition: TAttMarker.h:54
Long64_t fMaxEntries
Memory allocated for the cluster range.
Definition: TTree.h:113
TTree * GetTree() const
Definition: TBranch.h:183
void AddClone(TTree *)
Add a cloned tree to our list of trees to be notified whenever we change our branch addresses or when...
Definition: TTree.cxx:1071
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2227
virtual void KeepCircular(Long64_t maxEntries)
keep a maximum of fMaxEntries in memory
Definition: TBranch.cxx:1673
virtual TLeaf * GetLeafCount() const
Definition: TLeaf.h:71
Each class (see TClass) has a linked list of its base class(es).
Definition: TBaseClass.h:35
char GetNewlineValue(std::istream &inputStream)
Determine which newline this file is using.
Definition: TTree.cxx:6820
A Branch for the case of an object.
#define Printf
Definition: TGeoToOCC.h:18
virtual Int_t DropBranchFromCache(const char *bname, Bool_t subbranches=kFALSE)
Remove the branch with name 'bname' from the Tree cache.
Definition: TTree.cxx:994
TH1F * total
Definition: threadsh2.C:15
Int_t GetCompressionSettings() const
Definition: TFile.h:363
Long64_t fAutoSave
Definition: TTree.h:116
virtual void SaveSelf(Bool_t=kFALSE)
Definition: TDirectory.h:189
virtual void SetBasketSize(Int_t buffsize)
Set the basket size The function makes sure that the basket size is greater than fEntryOffsetlen.
Definition: TBranch.cxx:2096
virtual Int_t CheckBranchAddressType(TBranch *branch, TClass *ptrClass, EDataType datatype, Bool_t ptr)
Check whether or not the address described by the last 3 parameters matches the content of the branch...
Definition: TTree.cxx:2711
virtual void SetDebug(Int_t level=1, Long64_t min=0, Long64_t max=9999999)
Set the debug level and the debug range.
Definition: TTree.cxx:8026
virtual Long64_t Process(const char *filename, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Process this tree executing the TSelector code in the specified filename.
Definition: TTree.cxx:6687
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
long Long_t
Definition: RtypesCore.h:50
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition: TClass.cxx:5436
virtual Int_t GetBasketSize() const
Definition: TBranch.h:151
int Ssiz_t
Definition: RtypesCore.h:63
virtual Long64_t ReadStream(std::istream &inputStream, const char *branchDescriptor="", char delimiter= ' ')
Create or simply read branches from an input stream.
Definition: TTree.cxx:6847
virtual void DropBuffers(Int_t nbytes)
Drop branch buffers to accommodate nbytes below MaxVirtualsize.
Definition: TTree.cxx:4238
virtual Int_t Fill()
Fill the branch basket with the referenced objects parent numbers.
Definition: TBranchRef.cxx:101
virtual void SetMakeClass(Int_t make)
Set all the branches in this TTree to be in decomposed object mode (also known as MakeClass mode)...
Definition: TTree.cxx:8241
virtual void SetWeight(Double_t w=1, Option_t *option="")
Set tree weight.
Definition: TTree.cxx:8388
tuple tree
Definition: tree.py:24
Long64_t Next()
Move on to the next cluster and return the starting entry of this next cluster.
Definition: TTree.cxx:574
virtual Int_t GetSize() const
Definition: TCollection.h:95
virtual void SetDirectory(TDirectory *dir)
Change the tree's directory.
Definition: TTree.cxx:8064
virtual Long64_t LoadTreeFriend(Long64_t entry, TTree *T)
Load entry on behalf of our master tree, we may use an index.
Definition: TTree.cxx:5877
virtual void SetEstimate(Long64_t n)=0
virtual Long64_t GetAutoFlush() const
Definition: TTree.h:371
Long64_t fMaxVirtualSize
Definition: TTree.h:115
virtual TObject * Remove(TObject *)
Remove an object from the in-memory list.
TCollection * GetListOfFolders() const
Definition: TFolder.h:57
tuple file
Definition: fildir.py:20
virtual void StartViewer(Int_t ww, Int_t wh)=0
virtual void SetEntryList(TEntryList *list, Option_t *opt="")
Set an EntryList.
Definition: TTree.cxx:8141
TIterator & operator=(const TIterator &rhs)
Overridden assignment operator. Does NOT copy the 'cursor' location!
Definition: TTree.cxx:8819
virtual void ResetAddress()
Reset the address of the branch.
Definition: TBranch.cxx:2018
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:415
double Double_t
Definition: RtypesCore.h:55
virtual void Clear(Option_t *option="")
Clear entries in the TRefTable.
Definition: TBranchRef.cxx:93
static TRefTable * GetRefTable()
Static function returning the current TRefTable.
Definition: TRefTable.cxx:287
void SetHistLineStyle(Style_t styl=0)
Definition: TStyle.h:377
Long64_t fTotBytes
Definition: TTree.h:102
virtual void WaitFinishPrefetch()
TClass * GetClass() const
Definition: TClonesArray.h:57
Describe directory structure in memory.
Definition: TDirectory.h:44
virtual void SetPerfStats(TVirtualPerfStats *perf)
Set perf stats.
Definition: TTree.cxx:8343
static void TBranch__SetTree(TTree *tree, TObjArray &branches)
Set the fTree member for all branches and sub branches.
Definition: TTree.cxx:8522
virtual Long64_t GetEntriesFast() const
Definition: TTree.h:388
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
unsigned long long ULong64_t
Definition: RtypesCore.h:70
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
void dir(char *path=0)
Definition: rootalias.C:30
TNamed()
Definition: TNamed.h:40
Long64_t fAutoFlush
Definition: TTree.h:117
virtual void ResetBranchAddresses()
Tell all of our branches to drop their current objects and allocate new ones.
Definition: TTree.cxx:7266
virtual void Draw(Option_t *opt)
Default Draw method for all objects.
Definition: TTree.h:360
virtual void SetObject(void *objadd)
Set object this branch is pointing to.
TCanvas * style()
Definition: style.C:1
int nentries
Definition: THbookFile.cxx:89
A TRefTable maintains the association between a referenced object and the parent object supporting th...
Definition: TRefTable.h:37
Int_t GetKeylen() const
Definition: TKey.h:86
EDataType
Definition: TDataType.h:30
Int_t fDefaultEntryOffsetLen
Definition: TTree.h:110
virtual TTree * GetTree() const
Definition: TTree.h:436
void Browse(TBrowser *b)
Browse this collection (called by TBrowser).
Int_t GetNleaves() const
Definition: TBranch.h:180
Color_t GetHistLineColor() const
Definition: TStyle.h:242
TObjArray * GetListOfLeaves()
Definition: TBranch.h:178
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:494
Long64_t fEstimate
Definition: TTree.h:118
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
static void SetUnzipRelBufferSize(Float_t relbufferSize)
static function: Sets the unzip relatibe buffer size
UInt_t fMethodBit
Definition: TTree.h:184
Helper class to prevent infinite recursion in the usage of TTree Friends.
Definition: TTree.h:180
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2801
virtual Int_t SetBufferSize(Int_t buffersize)
Change the underlying buffer size of the cache.
virtual Int_t SetCacheSize(Long64_t cachesize=-1)
Set maximum size of the file cache .
Definition: TTree.cxx:7786
Int_t fDebug
Local for EntryLoop.
Definition: TTree.h:127
EOnIndexError
Definition: TTree.cxx:3219
TCanvas * slash()
Definition: slash.C:1
virtual Int_t UnbinnedFit(const char *formula, const char *varexp, const char *selection, Option_t *option, Long64_t nentries, Long64_t firstentry)=0
UInt_t GetCheckSum()
Int_t SetCacheSizeAux(Bool_t autocache=kTRUE, Long64_t cacheSize=0)
Set the size of the file cache and create it if possible.
Definition: TTree.cxx:7812
double Stat_t
Definition: RtypesCore.h:73
virtual void SetLineStyle(Style_t lstyle)
Definition: TAttLine.h:56
static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y)
Definition: vector.h:440
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition: TClass.cxx:2730
#define name(a, b)
Definition: linkTestLib0.cpp:5
virtual void SetBasketSize(const char *bname, Int_t buffsize=16000)
Set a branch's basket size.
Definition: TTree.cxx:7483
virtual TFile * GetFile()
Return pointer to TFile containing this friend TTree.
virtual TBranch * BranchRef()
Build the optional branch supporting the TRefTable.
Definition: TTree.cxx:2110
virtual void ResetAfterMerge(TFileMergeInfo *)
Resets the state of this TTree after a merge (keep the customization but forget the data)...
Definition: TTree.cxx:7225
virtual Bool_t SetAlias(const char *aliasName, const char *aliasFormula)
Set a tree variable alias.
Definition: TTree.cxx:7327
Int_t fFileNumber
not zero when processing code generated by MakeClass
Definition: TTree.h:131
Mother of all ROOT objects.
Definition: TObject.h:58
virtual Long64_t ReadFile(const char *filename, const char *branchDescriptor="", char delimiter= ' ')
Create or simply read branches from filename.
Definition: TTree.cxx:6801
Int_t fUpdate
Definition: TTree.h:109
A Branch handling STL collection of pointers (vectors, lists, queues, sets and multisets) while stori...
Definition: TBranchSTL.h:22
static void * ReAlloc(void *vp, size_t size)
Reallocate (i.e.
Definition: TStorage.cxx:177
virtual Int_t Branch(TCollection *list, Int_t bufsize=32000, Int_t splitlevel=99, const char *name="")
Create one branch for each element in the collection.
Definition: TTree.cxx:1623
TDirectory * fOutputDirectory
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:557
virtual void SetEntryOffsetLen(Int_t len, Bool_t updateSubBranches=kFALSE)
Update the default value for the branch's fEntryOffsetLen if and only if it was already non zero (and...
Definition: TBranch.cxx:2188
virtual Long64_t Scan(const char *varexp, const char *selection, Option_t *option, Long64_t nentries, Long64_t firstentry)=0
virtual void SetFile(TFile *file=0)
Set file where this branch writes/reads its buffers.
Definition: TBranch.cxx:2230
Long64_t fEntries
Definition: TTree.h:101
Int_t BufferSize() const
Definition: TBuffer.h:94
TList * fClones
Pointer to current Tree player.
Definition: TTree.h:146
Int_t GetMaxBaskets() const
Definition: TBranch.h:179
virtual void Refresh(TBranch *b)
Refresh this branch using new information in b This function is called by TTree::Refresh.
Definition: TBranch.cxx:1875
virtual Int_t MakeSelector(const char *selector=0, Option_t *option="")
Generate skeleton selector class for this tree.
Definition: TTree.cxx:6142
An array of clone (identical) objects.
Definition: TClonesArray.h:32
TBuffer * GetTransientBuffer(Int_t size)
Returns the transient buffer currently used by this TTree for reading/writing baskets.
Definition: TTree.cxx:889
virtual Color_t GetMarkerColor() const
Definition: TAttMarker.h:44
virtual TDirectory * GetDirectory() const
Definition: TEntryList.h:76
Class implementing or helping the various TTree cloning method.
Definition: TTreeCloner.h:39
virtual Bool_t cd(const char *path=0)
Change current directory to "this" directory.
Definition: TDirectory.cxx:433
virtual Int_t DropBuffers()
Drop buffers of this basket if it is not the current basket.
Definition: TBasket.cxx:192
ROOT::ESTLType IsSTLContainer()
Return which type (if any) of STL container the data member is.
Definition: TBaseClass.cxx:101
Abstract base class defining the interface for the plugins that implement Draw, Scan, Process, MakeProxy, etc.
A Branch for the case of an array of clone objects.
Definition: TBranchClones.h:31
virtual void * GetValuePointer() const
Definition: TLeaf.h:80
virtual void Add(TObject *obj)
Definition: TList.h:81
const Ssiz_t kNPOS
Definition: Rtypes.h:115
TClusterIterator(TTree *tree, Long64_t firstEntry)
Regular constructor.
Definition: TTree.cxx:500
Int_t Length() const
Definition: TBuffer.h:96
virtual void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition: TList.cxx:635
Int_t GetClassVersion()
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
virtual void Reset(Option_t *option="")
Reset a Branch.
Definition: TBranch.cxx:1924
A TFriendElement TF describes a TTree object TF in a file.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
virtual Bool_t IsWritable() const
Definition: TDirectory.h:171
virtual const char * GetMinorName() const =0
Iterator on all the leaves in a TTree and its friend.
Definition: TTree.h:576
virtual TBranch * BronchExec(const char *name, const char *classname, void *addobj, Bool_t isptrptr, Int_t bufsize, Int_t splitlevel)
Helper function implementing TTree::Bronch and TTree::Branch(const char *name, T &obj);.
Definition: TTree.cxx:2194
virtual void RecursiveRemove(TObject *obj)
Make sure that obj (which is being deleted or will soon be) is no longer referenced by this TTree...
Definition: TTree.cxx:7098
virtual Int_t LoadBaskets()
Baskets associated to this branch are forced to be in memory.
Definition: TBranch.cxx:1698
#define NULL
Definition: Rtypes.h:82
const ROOT::Detail::TSchemaRuleSet * GetSchemaRules() const
Return the set of the schema rules if any.
Definition: TClass.cxx:1834
#define gPad
Definition: TVirtualPad.h:288
virtual void SetCircular(Long64_t maxEntries)
Enable/Disable circularity for this tree.
Definition: TTree.cxx:7990
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
virtual void Reset(Option_t *option="")
Reset baskets, buffers and entries count in all branches and leaves.
Definition: TTree.cxx:7194
virtual const char * GetMajorName() const =0
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition: TClass.cxx:2719
Bool_t IsBasic() const
Return true if data member is a basic type, e.g. char, int, long...
TObject * fNotify
current file number (if file extensions)
Definition: TTree.h:132
virtual Int_t SetCacheEntryRange(Long64_t first, Long64_t last)
interface to TTreeCache to set the cache entry range
Definition: TTree.cxx:7929
void Add(TObject *obj)
Definition: TObjArray.h:75
virtual Long64_t GetEntries() const
Definition: TTree.h:386
A TTree object has a header with a name and a title.
Definition: TTree.h:98
#define gDirectory
Definition: TDirectory.h:221
TVirtualIndex * fTreeIndex
Definition: TTree.h:141
TFriendLock & operator=(const TFriendLock &)
Assignment operator.
Definition: TTree.cxx:470
Int_t SetBranchAddressImp(TBranch *branch, void *addr, TBranch **ptr)
Change branch address, dealing with clone trees properly.
Definition: TTree.cxx:7567
TDataMember * GetDataMember() const
Definition: TRealData.h:57
virtual TVirtualIndex * BuildIndex(const TTree *T, const char *majorname, const char *minorname)=0
void ResetBit(UInt_t f)
Definition: TObject.h:172
virtual void SetDefaultEntryOffsetLen(Int_t newdefault, Bool_t updateExisting=kFALSE)
Update the default value for the branch's fEntryOffsetLen.
Definition: TTree.cxx:8038
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition: TClass.cxx:4498
Int_t GetMakeClass() const
Definition: TTree.h:416
virtual TObject ** GetObjectRef(const TObject *obj) const =0
TObject * Next()
Go the next friend element.
Definition: TTree.cxx:8842
virtual void DropBaskets()
Remove some baskets from memory.
Definition: TTree.cxx:4225
Int_t FlushBaskets()
Flush to disk all the baskets of this branch and any of subbranches.
Definition: TBranch.cxx:995
Bool_t HasDataMemberInfo() const
Definition: TClass.h:370
virtual TSQLResult * Query(const char *varexp, const char *selection, Option_t *option, Long64_t nentries, Long64_t firstentry)=0
virtual TIterator * GetIteratorOnAllLeaves(Bool_t dir=kIterForward)
Creates a new iterator that will go through all the leaves on the tree itself and its friend...
Definition: TTree.cxx:5414
static Long64_t fgMaxTreeSize
Definition: TTree.h:154
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
virtual void WriteHeader()
Write File Header.
Definition: TFile.cxx:2396
virtual Long64_t GetEntryNumberFriend(const TTree *)=0
virtual TFile * GetFile(Int_t mode=0)
Return pointer to the file where branch buffers reside, returns 0 in case branch buffers reside in th...
Definition: TBranch.cxx:1382
virtual Long64_t SetEntries(Long64_t n=-1)
Change number of entries in the tree.
Definition: TTree.cxx:8109
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:504
virtual void Compress()
Remove empty slots from array.
Definition: TObjArray.cxx:309
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
virtual TFile * ChangeFile(TFile *file)
Called by TTree::Fill() when file has reached its maximum fgMaxTreeSize.
Definition: TTree.cxx:2598
virtual Int_t Occurence(const TObject *obj) const
Return occurence number of object in the list of objects of this folder.
Definition: TFolder.cxx:434
static TTree * MergeTrees(TList *list, Option_t *option="")
Static function merging the trees in the TList into a new tree.
Definition: TTree.cxx:6171
A TTree is a list of TBranches.
Definition: TBranch.h:58
virtual Bool_t GetBranchStatus(const char *branchname) const
Return status of branch with name branchname.
Definition: TTree.cxx:4899
virtual Style_t GetMarkerStyle() const
Definition: TAttMarker.h:45
A TSelector object is used by the TTree::Draw, TTree::Scan, TTree::Process to navigate in a TTree and...
Definition: TSelector.h:39
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual Width_t GetLineWidth() const
Definition: TAttLine.h:49
virtual const char * GetName() const
Returns name of object.
Definition: TRealData.h:56
Long_t GetThisOffset() const
Definition: TRealData.h:59
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:459
virtual void SetTitle(const char *title="")
Change (i.e. set) the title of the TNamed.
Definition: TNamed.cxx:152
void SetHistLineColor(Color_t color=1)
Definition: TStyle.h:375
TObject * obj
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:27
virtual Long64_t GetEntryNumberWithBestIndex(Long64_t major, Long64_t minor=0) const
Return entry number corresponding to major and minor number.
Definition: TTree.cxx:5230
virtual Int_t AddBranchToCache(const char *bname, Bool_t subbranches=kFALSE)
Add branch with name bname to the Tree cache.
Definition: TTree.cxx:911
Int_t fPacketSize
Total number of bytes in branch buffers.
Definition: TTree.h:125
void Set(Int_t n)
Set size of this array to n doubles.
Definition: TArrayD.cxx:105
const Int_t n
Definition: legend1.C:16
virtual Long64_t Project(const char *hname, const char *varexp, const char *selection="", Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Make a projection of a tree using selections.
Definition: TTree.cxx:6735
Line Attributes class.
Definition: TAttLine.h:32
virtual Long64_t GetEntryNumberWithIndex(Long64_t major, Long64_t minor) const =0
Int_t GetWriteBasket() const
Definition: TBranch.h:170
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition: TMath.h:944
const type_info * GetTypeInfo() const
Definition: TClass.h:450
TFriendLock(const TFriendLock &)
Copy constructor.
Definition: TTree.cxx:460
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:453
virtual void SetObject(void *objadd)
Set object this branch is pointing to.
Definition: TBranch.cxx:2303
Int_t GetReadBasket() const
Definition: TBranch.h:168
virtual void SetName(const char *name)
Change the name of this tree.
Definition: TTree.cxx:8269
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
Long64_t GetEstimatedClusterSize()
In the case where the cluster size was not fixed (old files and case where autoflush was explicitly s...
Definition: TTree.cxx:543
void MoveReadCache(TFile *src, TDirectory *dir)
Move a cache from a file to the current file in dir.
Definition: TTree.cxx:6304
virtual void CopyAddresses(TTree *, Bool_t undo=kFALSE)
Set branch addresses of passed tree equal to ours.
Definition: TTree.cxx:3115
virtual TObjArray * GetListOfLeaves()
Definition: TTree.h:410
static void ResetCount()
Static function resetting fgCount.
Definition: TBranch.cxx:2041
Long64_t fSavedBytes
Definition: TTree.h:104
Long64_t fCacheSize
Definition: TTree.h:121
virtual void Print(Option_t *option="") const
Print the TRefTable branch.
Definition: TBranchRef.cxx:157
virtual Long64_t AutoSave(Option_t *option="")
AutoSave tree header every fAutoSave bytes.
Definition: TTree.cxx:1308
int ii
Definition: hprod.C:34
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904