TTree.cxx

Go to the documentation of this file.
00001 // @(#)root/tree:$Id: TTree.cxx 38060 2011-02-13 21:17:54Z pcanal $
00002 // Author: Rene Brun   12/01/96
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TTree                                                                //
00015 //                                                                      //
00016 //  A TTree object has a header with a name and a title.
00017 //  It consists of a list of independent branches (TBranch). Each branch
00018 //  has its own definition and list of buffers. Branch buffers may be
00019 //  automatically written to disk or kept in memory until the Tree attribute
00020 //  fMaxVirtualSize is reached. Variables of one branch are written to the
00021 //  same buffer. A branch buffer is automatically compressed if the file
00022 //  compression attribute is set (default).
00023 //
00024 //  Branches may be written to different files (see TBranch::SetFile).
00025 //
00026 //  The ROOT user can decide to make one single branch and serialize one
00027 //  object into one single I/O buffer or to make several branches.
00028 //  Making one single branch and one single buffer can be the right choice
00029 //  when one wants to process only a subset of all entries in the tree.
00030 //  (you know for example the list of entry numbers you want to process).
00031 //  Making several branches is particularly interesting in the data analysis
00032 //  phase, when one wants to histogram some attributes of an object (entry)
00033 //  without reading all the attributes.
00034 //
00035 //  ==> TTree *tree = new TTree(name, title)
00036 //     Creates a Tree with name and title.
00037 //
00038 //     Various kinds of branches can be added to a tree:
00039 //
00040 //  ==> Case A
00041 //      ======
00042 //     TBranch *branch = tree->Branch(branchname, address, leaflist, bufsize)
00043 //       * address is the address of the first item of a structure
00044 //       * leaflist is the concatenation of all the variable names and types
00045 //         separated by a colon character :
00046 //         The variable name and the variable type are separated by a slash (/).
00047 //         The variable type may be 0,1 or 2 characters. If no type is given,
00048 //         the type of the variable is assumed to be the same as the previous
00049 //         variable. If the first variable does not have a type, it is assumed
00050 //         of type F by default. The list of currently supported types is given below:
00051 //            - C : a character string terminated by the 0 character
00052 //            - B : an 8 bit signed integer (Char_t)
00053 //            - b : an 8 bit unsigned integer (UChar_t)
00054 //            - S : a 16 bit signed integer (Short_t)
00055 //            - s : a 16 bit unsigned integer (UShort_t)
00056 //            - I : a 32 bit signed integer (Int_t)
00057 //            - i : a 32 bit unsigned integer (UInt_t)
00058 //            - F : a 32 bit floating point (Float_t)
00059 //            - D : a 64 bit floating point (Double_t)
00060 //            - L : a 64 bit signed integer (Long64_t)
00061 //            - l : a 64 bit unsigned integer (ULong64_t)
00062 //            - O : a boolean (Bool_t)
00063 //       * If the address points to a single numerical variable, the leaflist is optional:
00064 //           int value;
00065 //           tree->Branch(branchname, &value);
00066 //       * If the address points to more than one numerical variable, we strongly recommend
00067 //         that the variable be sorted in decreasing order of size.  Any other order will
00068 //         result in a non-portable (even between CINT and compiled code on the platform)
00069 //         TTree (i.e. you will not be able to read it back on a platform with a different
00070 //         padding strategy).
00071 //
00072 //  ==> Case B
00073 //      ======
00074 //     TBranch *branch = tree->Branch(branchname, &p_object, bufsize, splitlevel)/
00075 //     TBranch *branch = tree->Branch(branchname, className, &p_object, bufsize, splitlevel)
00076 //       * p_object is a pointer to an object.
00077 //       * If className is not specified, Branch uses the type of p_object to determine the
00078 //           type of the object.
00079 //       * If className is used to specify explicitly the object type, the className must
00080 //           be of a type related to the one pointed to by the pointer.  It should be either
00081 //           a parent or derived class.
00082 //       * if splitlevel=0, the object is serialized in the branch buffer.
00083 //       * if splitlevel=1, this branch will automatically be split
00084 //           into subbranches, with one subbranch for each data member or object
00085 //           of the object itself. In case the object member is a TClonesArray,
00086 //           the mechanism described in case C is applied to this array.
00087 //       * if splitlevel=2 ,this branch will automatically be split
00088 //           into subbranches, with one subbranch for each data member or object
00089 //           of the object itself. In case the object member is a TClonesArray,
00090 //           it is processed as a TObject*, only one branch.
00091 //
00092 //       Note: The pointer whose address is passed to TTree::Branch must not
00093 //             be destroyed (i.e. go out of scope) until the TTree is deleted or
00094 //             TTree::ResetBranchAddress is called.
00095 //
00096 //       Note: The pointer p_object must be initialized before calling TTree::Branch
00097 //          Do either:
00098 //             MyDataClass* p_object = 0;
00099 //             tree->Branch(branchname, &p_object);
00100 //          Or
00101 //             MyDataClass* p_object = new MyDataClass;
00102 //             tree->Branch(branchname, &p_object);
00103 //
00104 //  ==> Case C
00105 //      ======
00106 //     MyClass object;
00107 //     TBranch *branch = tree->Branch(branchname, &object, bufsize, splitlevel)
00108 //
00109 //       Note: The 2nd parameter must be the address of a valid object.
00110 //              The object must not be destroyed (i.e. be deleted) until the TTree
00111 //               is deleted or TTree::ResetBranchAddress is called.
00112 //
00113 //       * if splitlevel=0, the object is serialized in the branch buffer.
00114 //       * if splitlevel=1 (default), this branch will automatically be split
00115 //           into subbranches, with one subbranch for each data member or object
00116 //           of the object itself. In case the object member is a TClonesArray,
00117 //           the mechanism described in case C is applied to this array.
00118 //       * if splitlevel=2 ,this branch will automatically be split
00119 //           into subbranches, with one subbranch for each data member or object
00120 //           of the object itself. In case the object member is a TClonesArray,
00121 //           it is processed as a TObject*, only one branch.
00122 //
00123 //  ==> Case D
00124 //      ======
00125 //     TBranch *branch = tree->Branch(branchname,clonesarray, bufsize, splitlevel)
00126 //         clonesarray is the address of a pointer to a TClonesArray.
00127 //         The TClonesArray is a direct access list of objects of the same class.
00128 //         For example, if the TClonesArray is an array of TTrack objects,
00129 //         this function will create one subbranch for each data member of
00130 //         the object TTrack.
00131 //
00132 //  ==> Case E
00133 //      ======
00134 //     TBranch *branch = tree->Branch( branchname, STLcollection, buffsize, splitlevel);
00135 //         STLcollection is the address of a pointer to std::vector, std::list,
00136 //         std::deque, std::set or std::multiset containing pointers to objects.
00137 //         If the splitlevel is a value bigger than 100 (TTree::kSplitCollectionOfPointers)
00138 //         then the collection will be written in split mode. Ie. if it contains objects of 
00139 //         any types deriving from TTrack this function will sort the objects
00140 //         basing on their type and store them in separate branches in split
00141 //         mode.
00142 //
00143 //  ==> branch->SetAddress(Void *address)
00144 //      In case of dynamic structures changing with each entry for example, one must
00145 //      redefine the branch address before filling the branch again.
00146 //      This is done via the TBranch::SetAddress member function.
00147 //
00148 //  ==> tree->Fill()
00149 //      loops on all defined branches and for each branch invokes the Fill function.
00150 //
00151 //         See also the class TNtuple (a simple Tree with branches of floats)
00152 //
00153 //       Adding a Branch to an Existing Tree
00154 //       ===================================
00155 // You may want to add a branch to an existing tree. For example,
00156 // if one variable in the tree was computed with a certain algorithm,
00157 // you may want to try another algorithm and compare the results.
00158 // One solution is to add a new branch, fill it, and save the tree.
00159 // The code below adds a simple branch to an existing tree.
00160 // Note the kOverwrite option in the Write method, it overwrites the
00161 // existing tree. If it is not specified, two copies of the tree headers
00162 // are saved.
00163 //
00164 // void tree3AddBranch(){
00165 //   TFile f("tree3.root", "update");
00166 //
00167 //   Float_t new_v;
00168 //   TTree *t3 = (TTree*)f->Get("t3");
00169 //   TBranch *newBranch = t3->Branch("new_v", &new_v, "new_v/F");
00170 //
00171 //   //read the number of entries in the t3
00172 //   Long64_t nentries = t3->GetEntries();
00173 //
00174 //   for (Long64_t i = 0; i < nentries; i++){
00175 //     new_v= gRandom->Gaus(0, 1);
00176 //     newBranch->Fill();
00177 //   }
00178 //   // save only the new version of the tree
00179 //   t3->Write("", TObject::kOverwrite);
00180 // }
00181 // Adding a branch is often not possible because the tree is in a read-only
00182 // file and you do not have permission to save the modified tree with the
00183 // new branch. Even if you do have the permission, you risk losing the
00184 // original tree with an unsuccessful attempt to save  the modification.
00185 // Since trees are usually large, adding a branch could extend it over the
00186 // 2GB limit. In this case, the attempt to write the tree fails, and the
00187 // original data is erased.
00188 // In addition, adding a branch to a tree enlarges the tree and increases
00189 // the amount of memory needed to read an entry, and therefore decreases
00190 // the performance.
00191 //
00192 // For these reasons, ROOT offers the concept of friends for trees (and chains).
00193 // We encourage you to use TTree::AddFriend rather than adding a branch manually.
00194 //
00195 //Begin_Html
00196 /*
00197 <img src="gif/tree_layout.gif">
00198 */
00199 //End_Html
00200 //  =============================================================================
00201 //______________________________________________________________________________
00202 //*-*-*-*-*-*-*A simple example with histograms and a tree*-*-*-*-*-*-*-*-*-*
00203 //*-*          ===========================================
00204 //
00205 //  This program creates :
00206 //    - a one dimensional histogram
00207 //    - a two dimensional histogram
00208 //    - a profile histogram
00209 //    - a tree
00210 //
00211 //  These objects are filled with some random numbers and saved on a file.
00212 //
00213 //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
00214 //
00215 // #include "TFile.h"
00216 // #include "TH1.h"
00217 // #include "TH2.h"
00218 // #include "TProfile.h"
00219 // #include "TRandom.h"
00220 // #include "TTree.h"
00221 //
00222 //
00223 // //______________________________________________________________________________
00224 // main(int argc, char **argv)
00225 // {
00226 // // Create a new ROOT binary machine independent file.
00227 // // Note that this file may contain any kind of ROOT objects, histograms,trees
00228 // // pictures, graphics objects, detector geometries, tracks, events, etc..
00229 // // This file is now becoming the current directory.
00230 //   TFile hfile("htree.root","RECREATE","Demo ROOT file with histograms & trees");
00231 //
00232 // // Create some histograms and a profile histogram
00233 //   TH1F *hpx   = new TH1F("hpx","This is the px distribution",100,-4,4);
00234 //   TH2F *hpxpy = new TH2F("hpxpy","py ps px",40,-4,4,40,-4,4);
00235 //   TProfile *hprof = new TProfile("hprof","Profile of pz versus px",100,-4,4,0,20);
00236 //
00237 // // Define some simple structures
00238 //   typedef struct {Float_t x,y,z;} POINT;
00239 //   typedef struct {
00240 //      Int_t ntrack,nseg,nvertex;
00241 //      UInt_t flag;
00242 //      Float_t temperature;
00243 //   } EVENTN;
00244 //   static POINT point;
00245 //   static EVENTN eventn;
00246 //
00247 // // Create a ROOT Tree
00248 //   TTree *tree = new TTree("T","An example of ROOT tree with a few branches");
00249 //   tree->Branch("point",&point,"x:y:z");
00250 //   tree->Branch("eventn",&eventn,"ntrack/I:nseg:nvertex:flag/i:temperature/F");
00251 //   tree->Branch("hpx","TH1F",&hpx,128000,0);
00252 //
00253 //   Float_t px,py,pz;
00254 //   static Float_t p[3];
00255 //
00256 // //--------------------Here we start a loop on 1000 events
00257 //   for ( Int_t i=0; i<1000; i++) {
00258 //      gRandom->Rannor(px,py);
00259 //      pz = px*px + py*py;
00260 //      Float_t random = gRandom->::Rndm(1);
00261 //
00262 // //         Fill histograms
00263 //      hpx->Fill(px);
00264 //      hpxpy->Fill(px,py,1);
00265 //      hprof->Fill(px,pz,1);
00266 //
00267 // //         Fill structures
00268 //      p[0] = px;
00269 //      p[1] = py;
00270 //      p[2] = pz;
00271 //      point.x = 10*(random-1);;
00272 //      point.y = 5*random;
00273 //      point.z = 20*random;
00274 //      eventn.ntrack  = Int_t(100*random);
00275 //      eventn.nseg    = Int_t(2*eventn.ntrack);
00276 //      eventn.nvertex = 1;
00277 //      eventn.flag    = Int_t(random+0.5);
00278 //      eventn.temperature = 20+random;
00279 //
00280 // //        Fill the tree. For each event, save the 2 structures and 3 objects
00281 // //      In this simple example, the objects hpx, hprof and hpxpy are slightly
00282 // //      different from event to event. We expect a big compression factor!
00283 //      tree->Fill();
00284 //   }
00285 //  //--------------End of the loop
00286 //
00287 //   tree->Print();
00288 //
00289 // // Save all objects in this file
00290 //   hfile.Write();
00291 //
00292 // // Close the file. Note that this is automatically done when you leave
00293 // // the application.
00294 //   hfile.Close();
00295 //
00296 //   return 0;
00297 // }
00298 //                                                                      //
00299 //////////////////////////////////////////////////////////////////////////
00300 
00301 #include "RConfig.h"
00302 #include "TTree.h"
00303 
00304 #include "TArrayC.h"
00305 #include "TBufferFile.h"
00306 #include "TBaseClass.h"
00307 #include "TBasket.h"
00308 #include "TBranchClones.h"
00309 #include "TBranchElement.h"
00310 #include "TBranchObject.h"
00311 #include "TBranchRef.h"
00312 #include "TBrowser.h"
00313 #include "TClass.h"
00314 #include "TClassEdit.h"
00315 #include "TClonesArray.h"
00316 #include "TCut.h"
00317 #include "TDataMember.h"
00318 #include "TDataType.h"
00319 #include "TDirectory.h"
00320 #include "TError.h"
00321 #include "TEntryList.h"
00322 #include "TEventList.h"
00323 #include "TFile.h"
00324 #include "TFolder.h"
00325 #include "TFriendElement.h"
00326 #include "TInterpreter.h"
00327 #include "TLeaf.h"
00328 #include "TLeafB.h"
00329 #include "TLeafC.h"
00330 #include "TLeafD.h"
00331 #include "TLeafElement.h"
00332 #include "TLeafF.h"
00333 #include "TLeafI.h"
00334 #include "TLeafL.h"
00335 #include "TLeafObject.h"
00336 #include "TLeafS.h"
00337 #include "TList.h"
00338 #include "TMath.h"
00339 #include "TROOT.h"
00340 #include "TRealData.h"
00341 #include "TRegexp.h"
00342 #include "TStreamerElement.h"
00343 #include "TStreamerInfo.h"
00344 #include "TStyle.h"
00345 #include "TSystem.h"
00346 #include "TTreeCloner.h"
00347 #include "TTreeCache.h"
00348 #include "TTreeCacheUnzip.h"
00349 #include "TVirtualCollectionProxy.h"
00350 #include "TEmulatedCollectionProxy.h"
00351 #include "TVirtualFitter.h"
00352 #include "TVirtualIndex.h"
00353 #include "TVirtualPad.h"
00354 #include "TBranchSTL.h"
00355 #include "TSchemaRuleSet.h"
00356 
00357 #include <cstddef>
00358 #include <fstream>
00359 #include <sstream>
00360 #include <string>
00361 #include <stdio.h>
00362 
00363 Int_t    TTree::fgBranchStyle = 1;  // Use new TBranch style with TBranchElement.
00364 Long64_t TTree::fgMaxTreeSize = 100000000000LL;
00365 
00366 TTree* gTree;
00367 
00368 ClassImp(TTree)
00369 
00370 //
00371 //------------------------------------------------------------------------------
00372 //------------------------------------------------------------------------------
00373 //------------------------------------------------------------------------------
00374 //
00375 
00376 static char DataTypeToChar(EDataType datatype)
00377 {
00378    // Return the leaflist 'char' for a given datatype.
00379 
00380    switch(datatype) {
00381    case kChar_t:     return 'B';
00382    case kUChar_t:    return 'b';
00383    case kBool_t:     return 'O';
00384    case kShort_t:    return 'S';
00385    case kUShort_t:   return 's';
00386    case kCounter:
00387    case kInt_t:      return 'I';
00388    case kUInt_t:     return 'i';
00389    case kDouble_t:
00390    case kDouble32_t: return 'D';
00391    case kFloat_t:
00392    case kFloat16_t:  return 'F';
00393    case kLong_t:     return 0; // unsupported
00394    case kULong_t:    return 0; // unsupported?
00395    case kchar:       return 0; // unsupported
00396    case kLong64_t:   return 'L';
00397    case kULong64_t:  return 'l';
00398 
00399    case kCharStar:   return 'C';
00400    case kBits:       return 0; //unsupported
00401 
00402    case kOther_t:
00403    case kNoType_t:
00404    default:
00405       return 0;
00406    }
00407    return 0;
00408 }
00409 
00410 //______________________________________________________________________________
00411 //  Helper class to prevent infinite recursion in the usage of TTree Friends.
00412 
00413 //______________________________________________________________________________
00414 TTree::TFriendLock::TFriendLock(TTree* tree, UInt_t methodbit)
00415 : fTree(tree)
00416 {
00417    // Record in tree that it has been used while recursively looks through the friends.
00418 
00419    // We could also add some code to acquire an actual
00420    // lock to prevent multi-thread issues
00421    fMethodBit = methodbit;
00422    if (fTree) {
00423       fPrevious = fTree->fFriendLockStatus & fMethodBit;
00424       fTree->fFriendLockStatus |= fMethodBit;
00425    } else {
00426       fPrevious = 0;
00427    }
00428 }
00429 
00430 //______________________________________________________________________________
00431 TTree::TFriendLock::TFriendLock(const TFriendLock& tfl) :
00432   fTree(tfl.fTree),
00433   fMethodBit(tfl.fMethodBit),
00434   fPrevious(tfl.fPrevious)
00435 {
00436    //copy constructor
00437 }
00438 
00439 //______________________________________________________________________________
00440 TTree::TFriendLock& TTree::TFriendLock::operator=(const TTree::TFriendLock& tfl)
00441 {
00442    //assignement operator
00443    if(this!=&tfl) {
00444       fTree=tfl.fTree;
00445       fMethodBit=tfl.fMethodBit;
00446       fPrevious=tfl.fPrevious;
00447    }
00448    return *this;
00449 }
00450 
00451 //______________________________________________________________________________
00452 TTree::TFriendLock::~TFriendLock()
00453 {
00454    // Restore the state of tree the same as before we set the lock.
00455 
00456    if (fTree) {
00457       if (!fPrevious) {
00458          fTree->fFriendLockStatus &= ~(fMethodBit & kBitMask);
00459       }
00460    }
00461 }
00462 
00463 //
00464 //------------------------------------------------------------------------------
00465 //------------------------------------------------------------------------------
00466 //------------------------------------------------------------------------------
00467 //
00468 
00469 //______________________________________________________________________________
00470 TTree::TTree()
00471 : TNamed()
00472 , TAttLine()
00473 , TAttFill()
00474 , TAttMarker()
00475 , fEntries(0)
00476 , fTotBytes(0)
00477 , fZipBytes(0)
00478 , fSavedBytes(0)
00479 , fFlushedBytes(0)
00480 , fWeight(1)
00481 , fTimerInterval(0)
00482 , fScanField(25)
00483 , fUpdate(0)
00484 , fDefaultEntryOffsetLen(1000)
00485 , fMaxEntries(0)
00486 , fMaxEntryLoop(0)
00487 , fMaxVirtualSize(0)
00488 , fAutoSave( -300000000)
00489 , fAutoFlush(-30000000)
00490 , fEstimate(1000000)
00491 , fCacheSize(0)
00492 , fChainOffset(0)
00493 , fReadEntry(-1)
00494 , fTotalBuffers(0)
00495 , fPacketSize(100)
00496 , fNfill(0)
00497 , fDebug(0)
00498 , fDebugMin(0)
00499 , fDebugMax(9999999)
00500 , fMakeClass(0)
00501 , fFileNumber(0)
00502 , fNotify(0)
00503 , fDirectory(0)
00504 , fBranches()
00505 , fLeaves()
00506 , fAliases(0)
00507 , fEventList(0)
00508 , fEntryList(0)
00509 , fIndexValues()
00510 , fIndex()
00511 , fTreeIndex(0)
00512 , fFriends(0)
00513 , fUserInfo(0)
00514 , fPlayer(0)
00515 , fClones(0)
00516 , fBranchRef(0)
00517 , fFriendLockStatus(0)
00518 {
00519    // Default constructor and I/O constructor.
00520    //
00521    // Note: We do *not* insert ourself into the current directory.
00522    //
00523 
00524    fMaxEntries = 1000000000;
00525    fMaxEntries *= 1000;
00526 
00527    fMaxEntryLoop = 1000000000;
00528    fMaxEntryLoop *= 1000;
00529 }
00530 
00531 //______________________________________________________________________________
00532 TTree::TTree(const char* name, const char* title, Int_t splitlevel /* = 99 */)
00533 : TNamed(name, title)
00534 , TAttLine()
00535 , TAttFill()
00536 , TAttMarker()
00537 , fEntries(0)
00538 , fTotBytes(0)
00539 , fZipBytes(0)
00540 , fSavedBytes(0)
00541 , fFlushedBytes(0)
00542 , fWeight(1)
00543 , fTimerInterval(0)
00544 , fScanField(25)
00545 , fUpdate(0)
00546 , fDefaultEntryOffsetLen(1000)
00547 , fMaxEntries(0)
00548 , fMaxEntryLoop(0)
00549 , fMaxVirtualSize(0)
00550 , fAutoSave( -300000000)
00551 , fAutoFlush(-30000000)
00552 , fEstimate(1000000)
00553 , fCacheSize(0)
00554 , fChainOffset(0)
00555 , fReadEntry(-1)
00556 , fTotalBuffers(0)
00557 , fPacketSize(100)
00558 , fNfill(0)
00559 , fDebug(0)
00560 , fDebugMin(0)
00561 , fDebugMax(9999999)
00562 , fMakeClass(0)
00563 , fFileNumber(0)
00564 , fNotify(0)
00565 , fDirectory(0)
00566 , fBranches()
00567 , fLeaves()
00568 , fAliases(0)
00569 , fEventList(0)
00570 , fEntryList(0)
00571 , fIndexValues()
00572 , fIndex()
00573 , fTreeIndex(0)
00574 , fFriends(0)
00575 , fUserInfo(0)
00576 , fPlayer(0)
00577 , fClones(0)
00578 , fBranchRef(0)
00579 , fFriendLockStatus(0)
00580 {
00581    // Normal tree constructor.
00582    //
00583    // The tree is created in the current directory.
00584    // Use the various functions Branch below to add branches to this tree.
00585    //
00586    // If the first character of title is a "/", the function assumes a folder name.
00587    // In this case, it creates automatically branches following the folder hierarchy.
00588    // splitlevel may be used in this case to control the split level.
00589 
00590    // TAttLine state.
00591    SetLineColor(gStyle->GetHistLineColor());
00592    SetLineStyle(gStyle->GetHistLineStyle());
00593    SetLineWidth(gStyle->GetHistLineWidth());
00594 
00595    // TAttFill state.
00596    SetFillColor(gStyle->GetHistFillColor());
00597    SetFillStyle(gStyle->GetHistFillStyle());
00598 
00599    // TAttMarkerState.
00600    SetMarkerColor(gStyle->GetMarkerColor());
00601    SetMarkerStyle(gStyle->GetMarkerStyle());
00602    SetMarkerSize(gStyle->GetMarkerSize());
00603 
00604    fMaxEntries = 1000000000;
00605    fMaxEntries *= 1000;
00606 
00607    fMaxEntryLoop = 1000000000;
00608    fMaxEntryLoop *= 1000;
00609 
00610    // Insert ourself into the current directory.
00611    // FIXME: This is very annoying behaviour, we should
00612    //        be able to choose to not do this like we
00613    //        can with a histogram.
00614    fDirectory = gDirectory;
00615    fDirectory->Append(this);
00616 
00617    // We become the current tree.
00618    gTree = this;
00619 
00620    // If title starts with "/" and is a valid folder name, a superbranch
00621    // is created.
00622    // FIXME: Why?
00623    if (strlen(title) > 2) {
00624       if (title[0] == '/') {
00625          Branch(title+1,32000,splitlevel);
00626       }
00627    }
00628 }
00629 
00630 //______________________________________________________________________________
00631 TTree::~TTree()
00632 {
00633    // Destructor.
00634 
00635    if (fDirectory) {
00636       // We are in a directory, which may possibly be a file.
00637       if (fDirectory->GetList()) {
00638          // Remove us from the directory listing.
00639          fDirectory->Remove(this);
00640       }
00641       //delete the file cache if it points to this Tree
00642       TFile *file = fDirectory->GetFile();
00643       if (file) {
00644          TFileCacheRead *pf = file->GetCacheRead();
00645          if (pf && pf->InheritsFrom(TTreeCache::Class())) {
00646             TTreeCache *tpf = (TTreeCache*)pf;
00647             if (tpf->GetOwner() == this) {
00648                delete tpf;
00649                tpf = 0;
00650                file->SetCacheRead(0);
00651             }
00652          }
00653       }
00654    }
00655    // We don't own the leaves in fLeaves, the branches do.
00656    fLeaves.Clear();
00657    // I'm ready to destroy any objects allocated by
00658    // SetAddress() by my branches.  If I have clones,
00659    // tell them to zero their pointers to this shared
00660    // memory.
00661    if (fClones && fClones->GetEntries()) {
00662       // I have clones.
00663       // I am about to delete the objects created by
00664       // SetAddress() which we are sharing, so tell
00665       // the clones to release their pointers to them.
00666       for (TObjLink* lnk = fClones->FirstLink(); lnk; lnk = lnk->Next()) {
00667          TTree* clone = (TTree*) lnk->GetObject();
00668          // clone->ResetBranchAddresses();
00669 
00670          // Reset only the branch we have set the address of.
00671          CopyAddresses(clone,kTRUE);
00672       }
00673    }
00674    // Get rid of our branches, note that this will also release
00675    // any memory allocated by TBranchElement::SetAddress().
00676    fBranches.Delete();
00677    // FIXME: We must consider what to do with the reset of these if we are a clone.
00678    delete fPlayer;
00679    fPlayer = 0;
00680    if (fFriends) {
00681       fFriends->Delete();
00682       delete fFriends;
00683       fFriends = 0;
00684    }
00685    if (fAliases) {
00686       fAliases->Delete();
00687       delete fAliases;
00688       fAliases = 0;
00689    }
00690    if (fUserInfo) {
00691       fUserInfo->Delete();
00692       delete fUserInfo;
00693       fUserInfo = 0;
00694    }
00695    if (fClones) {
00696       // Clone trees should no longer be removed from fClones when they are deleted.
00697       gROOT->GetListOfCleanups()->Remove(fClones);
00698       // Note: fClones does not own its content.
00699       delete fClones;
00700       fClones = 0;
00701    }
00702    if (fEntryList) {
00703       if (fEntryList->TestBit(kCanDelete) && fEntryList->GetDirectory()==0) {
00704          // Delete the entry list if it is marked to be deleted and it is not also
00705          // owned by a directory.  (Otherwise we would need to make sure that a
00706          // TDirectoryFile that has a TTree in it does a 'slow' TList::Delete.
00707          delete fEntryList;
00708          fEntryList=0;
00709       }
00710    }
00711    delete fTreeIndex;
00712    fTreeIndex = 0;
00713    delete fBranchRef;
00714    fBranchRef = 0;
00715    // Must be done after the destruction of friends.
00716    // Note: We do *not* own our directory.
00717    fDirectory = 0;
00718 }
00719 
00720 //______________________________________________________________________________
00721 void TTree::AddBranchToCache(const char*bname, Bool_t subbranches)
00722 {
00723    // Add branch with name bname to the Tree cache.
00724    // If bname="*" all branches are added to the cache.
00725    // if subbranches is true all the branches of the subbranches are
00726    // also put to the cache.
00727 
00728    TFile *f = GetCurrentFile();
00729    if (!f) return;
00730    TTreeCache *tc = (TTreeCache*)f->GetCacheRead();
00731    if (tc) tc->AddBranch(bname,subbranches);
00732 }
00733 
00734 //______________________________________________________________________________
00735 void TTree::AddBranchToCache(TBranch *b, Bool_t subbranches)
00736 {
00737    // Add branch b to the Tree cache.
00738    // if subbranches is true all the branches of the subbranches are
00739    // also put to the cache.
00740 
00741    TFile *f = GetCurrentFile();
00742    if (!f) return;
00743    TTreeCache *tc = (TTreeCache*)f->GetCacheRead();
00744    if (tc) tc->AddBranch(b,subbranches);
00745 }
00746 
00747 
00748 //______________________________________________________________________________
00749 void TTree::AddClone(TTree* clone)
00750 {
00751    // Add a cloned tree to our list of trees to be notified whenever we change
00752    // our branch addresses or when we are deleted.
00753 
00754    if (!fClones) {
00755       fClones = new TList();
00756       fClones->SetOwner(false);
00757       // So that the clones are automatically removed from the list when
00758       // they are deleted.
00759       gROOT->GetListOfCleanups()->Add(fClones);
00760    }
00761    if (!fClones->FindObject(clone)) {
00762       fClones->Add(clone);
00763    }
00764 }
00765 
00766 
00767 //______________________________________________________________________________
00768 TFriendElement* TTree::AddFriend(const char* treename, const char* filename)
00769 {
00770    // Add a TFriendElement to the list of friends.
00771    //
00772    // This function:
00773    //   -opens a file if filename is specified
00774    //   -reads a Tree with name treename from the file (current directory)
00775    //   -adds the Tree to the list of friends
00776    // see other AddFriend functions
00777    //
00778    // A TFriendElement TF describes a TTree object TF in a file.
00779    // When a TFriendElement TF is added to the the list of friends of an
00780    // existing TTree T, any variable from TF can be referenced in a query
00781    // to T.
00782    //
00783    //   A tree keeps a list of friends. In the context of a tree (or a chain),
00784    // friendship means unrestricted access to the friends data. In this way
00785    // it is much like adding another branch to the tree without taking the risk
00786    // of damaging it. To add a friend to the list, you can use the TTree::AddFriend
00787    // method.  The tree in the diagram below has two friends (friend_tree1 and
00788    // friend_tree2) and now has access to the variables a,b,c,i,j,k,l and m.
00789    //
00790    //Begin_Html
00791    /*
00792    <img src="gif/tree_friend1.gif">
00793    */
00794    //End_Html
00795    //
00796    // The AddFriend method has two parameters, the first is the tree name and the
00797    // second is the name of the ROOT file where the friend tree is saved.
00798    // AddFriend automatically opens the friend file. If no file name is given,
00799    // the tree called ft1 is assumed to be in the same file as the original tree.
00800    //
00801    // tree.AddFriend("ft1","friendfile1.root");
00802    // If the friend tree has the same name as the original tree, you can give it
00803    // an alias sin the context of the friendship:
00804    //
00805    // tree.AddFriend("tree1 = tree","friendfile1.root");
00806    // Once the tree has friends, we can use TTree::Draw as if the friend's
00807    // variables were in the original tree. To specify which tree to use in
00808    // the Draw method, use the syntax:
00809    //
00810    // <treeName>.<branchname>.<varname>
00811    // If the variablename is enough to uniquely identify the variable, you can
00812    // leave out the tree and/or branch name.
00813    // For example, these commands generate a 3-d scatter plot of variable "var"
00814    // in the TTree tree versus variable v1 in TTree ft1 versus variable v2 in
00815    // TTree ft2.
00816    //
00817    // tree.AddFriend("ft1","friendfile1.root");
00818    // tree.AddFriend("ft2","friendfile2.root");
00819    // tree.Draw("var:ft1.v1:ft2.v2");
00820    //
00821    //Begin_Html
00822    /*
00823    <img src="gif/tree_friend2.gif">
00824    */
00825    //End_Html
00826    //
00827    // The picture illustrates the access of the tree and its friends with a
00828    // Draw command.
00829    // When AddFriend is called, the ROOT file is automatically opened and the
00830    // friend tree (ft1) is read into memory. The new friend (ft1) is added to
00831    // the list of friends of tree.
00832    // The number of entries in the friend must be equal or greater to the number
00833    // of entries of the original tree. If the friend tree has fewer entries a
00834    // warning is given and the missing entries are not included in the histogram.
00835    // To retrieve the list of friends from a tree use TTree::GetListOfFriends.
00836    // When the tree is written to file (TTree::Write), the friends list is saved
00837    // with it. And when the tree is retrieved, the trees on the friends list are
00838    // also retrieved and the friendship restored.
00839    // When a tree is deleted, the elements of the friend list are also deleted.
00840    // It is possible to declare a friend tree that has the same internal
00841    // structure (same branches and leaves) as the original tree, and compare the
00842    // same values by specifying the tree.
00843    //
00844    //  tree.Draw("var:ft1.var:ft2.var")
00845 
00846    //if (kAddFriend & fFriendLockStatus)
00847 
00848    if (!fFriends) {
00849       fFriends = new TList();
00850    }
00851    TFriendElement* fe = new TFriendElement(this, treename, filename);
00852    R__ASSERT(fe); // this assert is for historical reasons. Don't remove it unless you understand all the consequences.
00853    fFriends->Add(fe);
00854    TTree* t = fe->GetTree();
00855    if (t) {
00856       if (!t->GetTreeIndex() && (t->GetEntries() < fEntries)) {
00857          Warning("AddFriend", "FriendElement %s in file %s has less entries %lld than its parent Tree: %lld", treename, filename, t->GetEntries(), fEntries);
00858       }
00859    } else {
00860       Warning("AddFriend", "Cannot add FriendElement %s in file %s", treename, filename);
00861    }
00862    return fe;
00863 }
00864 
00865 //______________________________________________________________________________
00866 TFriendElement* TTree::AddFriend(const char* treename, TFile* file)
00867 {
00868    // Add a TFriendElement to the list of friends.
00869    //
00870    // The TFile is managed by the user (e.g. the user must delete the file).
00871    // For complete description see AddFriend(const char *, const char *).
00872    // This function:
00873    //   -reads a Tree with name treename from the file
00874    //   -adds the Tree to the list of friends
00875 
00876    if (!fFriends) {
00877       fFriends = new TList();
00878    }
00879    TFriendElement *fe = new TFriendElement(this, treename, file);
00880    R__ASSERT(fe);
00881    fFriends->Add(fe);
00882    TTree *t = fe->GetTree();
00883    if (t) {
00884       if (!t->GetTreeIndex() && (t->GetEntries() < fEntries)) {
00885          Warning("AddFriend", "FriendElement %s in file %s has less entries %lld than its parent tree: %lld", treename, file->GetName(), t->GetEntries(), fEntries);
00886       }
00887    } else {
00888       Warning("AddFriend", "unknown tree '%s' in file '%s'", treename, file->GetName());
00889    }
00890    return fe;
00891 }
00892 
00893 //______________________________________________________________________________
00894 TFriendElement* TTree::AddFriend(TTree* tree, const char* alias, Bool_t warn)
00895 {
00896    // Add a TFriendElement to the list of friends.
00897    //
00898    // The TTree is managed by the user (e.g., the user must delete the file).
00899    // For a complete description see AddFriend(const char *, const char *).
00900 
00901    if (!tree) {
00902       return 0;
00903    }
00904    if (!fFriends) {
00905       fFriends = new TList();
00906    }
00907    TFriendElement* fe = new TFriendElement(this, tree, alias);
00908    R__ASSERT(fe); // this assert is for historical reasons. Don't remove it unless you understand all the consequences.
00909    fFriends->Add(fe);
00910    TTree* t = fe->GetTree();
00911    if (warn && (t->GetEntries() < fEntries)) {
00912       Warning("AddFriend", "FriendElement '%s' in file '%s' has less entries %lld than its parent tree: %lld", tree->GetName(), fe->GetFile() ? fe->GetFile()->GetName() : "(memory resident)", t->GetEntries(), fEntries);
00913    }
00914    return fe;
00915 }
00916 
00917 //______________________________________________________________________________
00918 Long64_t TTree::AutoSave(Option_t* option)
00919 {
00920    // AutoSave tree header every fAutoSave bytes.
00921    //
00922    //   When large Trees are produced, it is safe to activate the AutoSave
00923    //   procedure. Some branches may have buffers holding many entries.
00924    //   AutoSave is automatically called by TTree::Fill when the number of bytes
00925    //   generated since the previous AutoSave is greater than fAutoSave bytes.
00926    //   This function may also be invoked by the user, for example every
00927    //   N entries.
00928    //   Each AutoSave generates a new key on the file.
00929    //   Once the key with the tree header has been written, the previous cycle
00930    //   (if any) is deleted.
00931    //
00932    //   Note that calling TTree::AutoSave too frequently (or similarly calling
00933    //   TTree::SetAutoSave with a small value) is an expensive operation.
00934    //   You should make tests for your own application to find a compromize
00935    //   between speed and the quantity of information you may loose in case of
00936    //   a job crash.
00937    //
00938    //   In case your program crashes before closing the file holding this tree,
00939    //   the file will be automatically recovered when you will connect the file
00940    //   in UPDATE mode.
00941    //   The Tree will be recovered at the status corresponding to the last AutoSave.
00942    //
00943    //   if option contains "SaveSelf", gDirectory->SaveSelf() is called.
00944    //   This allows another process to analyze the Tree while the Tree is being filled.
00945    //
00946    //   if option contains "FlushBaskets", TTree::FlushBaskets is called and all
00947    //   the current basket are closed-out and written to disk individually.
00948    //
00949    //   By default the previous header is deleted after having written the new header.
00950    //   if option contains "Overwrite", the previous Tree header is deleted
00951    //   before written the new header. This option is slightly faster, but
00952    //   the default option is safer in case of a problem (disk quota exceeded)
00953    //   when writing the new header.
00954    //
00955    //   The function returns the number of bytes written to the file.
00956    //   if the number of bytes is null, an error has occured while writing
00957    //   the header to the file.
00958    //
00959    //   How to write a Tree in one process and view it from another process
00960    //   ===================================================================
00961    //   The following two scripts illustrate how to do this.
00962    //   The script treew.C is executed by process1, treer.C by process2
00963    //
00964    //   ----- script treew.C
00965    //   void treew() {
00966    //     TFile f("test.root","recreate");
00967    //     TNtuple *ntuple = new TNtuple("ntuple","Demo","px:py:pz:random:i");
00968    //     Float_t px, py, pz;
00969    //     for ( Int_t i=0; i<10000000; i++) {
00970    //        gRandom->Rannor(px,py);
00971    //        pz = px*px + py*py;
00972    //        Float_t random = gRandom->Rndm(1);
00973    //        ntuple->Fill(px,py,pz,random,i);
00974    //        if (i%1000 == 1) ntuple->AutoSave("SaveSelf");
00975    //     }
00976    //   }
00977    //
00978    //   ----- script treer.C
00979    //   void treer() {
00980    //      TFile f("test.root");
00981    //      TTree *ntuple = (TTree*)f.Get("ntuple");
00982    //      TCanvas c1;
00983    //      Int_t first = 0;
00984    //      while(1) {
00985    //         if (first == 0) ntuple->Draw("px>>hpx", "","",10000000,first);
00986    //         else            ntuple->Draw("px>>+hpx","","",10000000,first);
00987    //         first = (Int_t)ntuple->GetEntries();
00988    //         c1.Update();
00989    //         gSystem->Sleep(1000); //sleep 1 second
00990    //         ntuple->Refresh();
00991    //      }
00992    //   }
00993 
00994    if (!fDirectory || fDirectory == gROOT || !fDirectory->IsWritable()) return 0;
00995    if (gDebug > 0) {
00996       printf("AutoSave Tree:%s after %lld bytes written\n",GetName(),fTotBytes);
00997    }
00998    TString opt = option;
00999    opt.ToLower();
01000 
01001    if (opt.Contains("flushbaskets")) {
01002       if (gDebug > 0) printf("AutoSave:  calling FlushBaskets \n");
01003       FlushBaskets();
01004    }
01005 
01006    fSavedBytes = fZipBytes;
01007 
01008    TKey *key = (TKey*)fDirectory->GetListOfKeys()->FindObject(GetName());
01009    Long64_t nbytes;
01010    if (opt.Contains("overwrite")) {
01011       nbytes = fDirectory->WriteTObject(this,"","",TObject::kOverwrite);
01012    } else {
01013       nbytes = fDirectory->WriteTObject(this); //nbytes will be 0 if Write failed (disk space exceeded)
01014       if (nbytes && key) {
01015          key->Delete();
01016          delete key;
01017       }
01018    }
01019    // save StreamerInfo
01020    TFile *file = fDirectory->GetFile();
01021    if (file) file->WriteStreamerInfo();
01022 
01023    if (opt.Contains("saveself")) {
01024       fDirectory->SaveSelf();
01025       //the following line is required in case GetUserInfo contains a user class
01026       //for which the StreamerInfo must be written. One could probably be a bit faster (Rene)
01027       if (file) file->WriteHeader();
01028    }
01029 
01030    return nbytes;
01031 }
01032 
01033 //______________________________________________________________________________
01034 TBranch* TTree::BranchImp(const char* branchname, const char* classname, TClass* ptrClass, void* addobj, Int_t bufsize, Int_t splitlevel)
01035 {
01036    // Same as TTree::Branch() with added check that addobj matches className.
01037    //
01038    // See TTree::Branch() for other details.
01039    //
01040 
01041    TClass* claim = TClass::GetClass(classname);
01042    if (!ptrClass) {
01043       if (claim && claim->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(claim->GetCollectionProxy())) {
01044          Error("Branch", "The class requested (%s) for the branch \"%s\" refer to an stl collection and do not have a compiled CollectionProxy.  "
01045                "Please generate the dictionary for this class (%s)",
01046                claim->GetName(), branchname, claim->GetName());
01047          return 0;
01048       }
01049       return Branch(branchname, classname, (void*) addobj, bufsize, splitlevel);
01050    }
01051    TClass* actualClass = 0;
01052    void** addr = (void**) addobj;
01053    if (addr) {
01054       actualClass = ptrClass->GetActualClass(*addr);
01055    }
01056    if (ptrClass && claim) {
01057       if (!(claim->InheritsFrom(ptrClass) || ptrClass->InheritsFrom(claim))) {
01058          // Note we currently do not warn in case of splicing or over-expectation).
01059          if (claim->IsLoaded() && ptrClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), ptrClass->GetTypeInfo()->name() ) == 0) {
01060             // The type is the same according to the C++ type_info, we must be in the case of
01061             // a template of Double32_t.  This is actually a correct case.
01062          } else {
01063             Error("Branch", "The class requested (%s) for \"%s\" is different from the type of the pointer passed (%s)",
01064                   claim->GetName(), branchname, ptrClass->GetName());
01065          }
01066       } else if (actualClass && (claim != actualClass) && !actualClass->InheritsFrom(claim)) {
01067          if (claim->IsLoaded() && actualClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), actualClass->GetTypeInfo()->name() ) == 0) {
01068             // The type is the same according to the C++ type_info, we must be in the case of
01069             // a template of Double32_t.  This is actually a correct case.
01070          } else {
01071             Error("Branch", "The actual class (%s) of the object provided for the definition of the branch \"%s\" does not inherit from %s",
01072                   actualClass->GetName(), branchname, claim->GetName());
01073          }
01074       }
01075    }
01076    if (claim && claim->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(claim->GetCollectionProxy())) {
01077       Error("Branch", "The class requested (%s) for the branch \"%s\" refer to an stl collection and do not have a compiled CollectionProxy.  "
01078             "Please generate the dictionary for this class (%s)",
01079             claim->GetName(), branchname, claim->GetName());
01080       return 0;
01081    }
01082    return Branch(branchname, classname, (void*) addobj, bufsize, splitlevel);
01083 }
01084 
01085 //______________________________________________________________________________
01086 TBranch* TTree::BranchImp(const char* branchname, TClass* ptrClass, void* addobj, Int_t bufsize, Int_t splitlevel)
01087 {
01088    // Same as TTree::Branch but automatic detection of the class name.
01089    // See TTree::Branch for other details.
01090 
01091    if (!ptrClass) {
01092       Error("Branch", "The pointer specified for %s is not of a class known to ROOT", branchname);
01093       return 0;
01094    }
01095    TClass* actualClass = 0;
01096    void** addr = (void**) addobj;
01097    if (addr && *addr) {
01098       actualClass = ptrClass->GetActualClass(*addr);
01099       if (!actualClass) {
01100          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", branchname, ptrClass->GetName());
01101          actualClass = ptrClass;
01102       } else if ((ptrClass != actualClass) && !actualClass->InheritsFrom(ptrClass)) {
01103          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());
01104          return 0;
01105       }
01106    } else {
01107       actualClass = ptrClass;
01108    }
01109    if (actualClass && actualClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(actualClass->GetCollectionProxy())) {
01110       Error("Branch", "The class requested (%s) for the branch \"%s\" refer to an stl collection and do not have a compiled CollectionProxy.  "
01111             "Please generate the dictionary for this class (%s)",
01112             actualClass->GetName(), branchname, actualClass->GetName());
01113       return 0;
01114    }
01115    return Branch(branchname, actualClass->GetName(), (void*) addobj, bufsize, splitlevel);
01116 }
01117 
01118 //______________________________________________________________________________
01119 TBranch* TTree::BranchImpRef(const char* branchname, const char *classname, TClass* ptrClass, void *addobj, Int_t bufsize, Int_t splitlevel)
01120 {
01121    // Same as TTree::Branch but automatic detection of the class name.
01122    // See TTree::Branch for other details.
01123    
01124    TClass* claim = TClass::GetClass(classname);
01125    if (!ptrClass) {
01126       if (claim && claim->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(claim->GetCollectionProxy())) {
01127          Error("Branch", "The class requested (%s) for the branch \"%s\" refer to an stl collection and do not have a compiled CollectionProxy.  "
01128                "Please generate the dictionary for this class (%s)",
01129                claim->GetName(), branchname, claim->GetName());
01130          return 0;
01131       } else if (claim == 0) {
01132          Error("Branch", "The pointer specified for %s is not of a class known to ROOT and %s is not a known class", branchname, classname);         
01133          return 0;
01134       }
01135       ptrClass = claim;
01136    }
01137    TClass* actualClass = 0;
01138    if (!addobj) {
01139       Error("Branch", "Reference interface requires a valid object (for branch: %s)!", branchname);
01140       return 0;
01141    }
01142    actualClass = ptrClass->GetActualClass(addobj);
01143    if (ptrClass && claim) {
01144       if (!(claim->InheritsFrom(ptrClass) || ptrClass->InheritsFrom(claim))) {
01145          // Note we currently do not warn in case of splicing or over-expectation).
01146          if (claim->IsLoaded() && ptrClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), ptrClass->GetTypeInfo()->name() ) == 0) {
01147             // The type is the same according to the C++ type_info, we must be in the case of
01148             // a template of Double32_t.  This is actually a correct case.
01149          } else {
01150             Error("Branch", "The class requested (%s) for \"%s\" is different from the type of the object passed (%s)",
01151                   claim->GetName(), branchname, ptrClass->GetName());
01152          }
01153       } else if (actualClass && (claim != actualClass) && !actualClass->InheritsFrom(claim)) {
01154          if (claim->IsLoaded() && actualClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), actualClass->GetTypeInfo()->name() ) == 0) {
01155             // The type is the same according to the C++ type_info, we must be in the case of
01156             // a template of Double32_t.  This is actually a correct case.
01157          } else {
01158             Error("Branch", "The actual class (%s) of the object provided for the definition of the branch \"%s\" does not inherit from %s",
01159                   actualClass->GetName(), branchname, claim->GetName());
01160          }
01161       }
01162    }
01163    if (!actualClass) {
01164       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", branchname, ptrClass->GetName());
01165       actualClass = ptrClass;
01166    } else if ((ptrClass != actualClass) && !actualClass->InheritsFrom(ptrClass)) {
01167       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());
01168       return 0;
01169    }
01170    if (actualClass && actualClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(actualClass->GetCollectionProxy())) {
01171       Error("Branch", "The class requested (%s) for the branch \"%s\" refer to an stl collection and do not have a compiled CollectionProxy.  "
01172             "Please generate the dictionary for this class (%s)",
01173             actualClass->GetName(), branchname, actualClass->GetName());
01174       return 0;
01175    }
01176    return BronchExec(branchname, actualClass->GetName(), (void*) addobj, kFALSE, bufsize, splitlevel);
01177 }
01178 
01179 //______________________________________________________________________________
01180 TBranch* TTree::BranchImpRef(const char* branchname, TClass* ptrClass, EDataType datatype, void* addobj, Int_t bufsize, Int_t splitlevel)
01181 {
01182    // Same as TTree::Branch but automatic detection of the class name.
01183    // See TTree::Branch for other details.
01184    
01185    if (!ptrClass) {
01186       if (datatype == kOther_t || datatype == kNoType_t) {
01187          Error("Branch", "The pointer specified for %s is not of a class or type known to ROOT", branchname);
01188       } else {
01189          TString varname; varname.Form("%s/%c",branchname,DataTypeToChar(datatype));
01190          return Branch(branchname,addobj,varname.Data(),bufsize);
01191       }
01192       return 0;
01193    }
01194    TClass* actualClass = 0;
01195    if (!addobj) {
01196       Error("Branch", "Reference interface requires a valid object (for branch: %s)!", branchname);
01197       return 0;
01198    }
01199    actualClass = ptrClass->GetActualClass(addobj);
01200    if (!actualClass) {
01201       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", branchname, ptrClass->GetName());
01202       actualClass = ptrClass;
01203    } else if ((ptrClass != actualClass) && !actualClass->InheritsFrom(ptrClass)) {
01204       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());
01205       return 0;
01206    }
01207    if (actualClass && actualClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(actualClass->GetCollectionProxy())) {
01208       Error("Branch", "The class requested (%s) for the branch \"%s\" refer to an stl collection and do not have a compiled CollectionProxy.  "
01209             "Please generate the dictionary for this class (%s)",
01210             actualClass->GetName(), branchname, actualClass->GetName());
01211       return 0;
01212    }
01213    return BronchExec(branchname, actualClass->GetName(), (void*) addobj, kFALSE, bufsize, splitlevel);
01214 }
01215 
01216 //______________________________________________________________________________
01217 Int_t TTree::Branch(TList* li, Int_t bufsize /* = 32000 */ , Int_t splitlevel /* = 99 */)
01218 {
01219    // Deprecated function. Use next function instead.
01220    return Branch((TCollection*) li, bufsize, splitlevel);
01221 }
01222 
01223 //______________________________________________________________________________
01224 Int_t TTree::Branch(TCollection* li, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */, const char* name /* = "" */)
01225 {
01226    // Create one branch for each element in the collection.
01227    //
01228    //   Each entry in the collection becomes a top level branch if the
01229    //   corresponding class is not a collection. If it is a collection, the entry
01230    //   in the collection becomes in turn top level branches, etc.
01231    //   The splitlevel is decreased by 1 everytime a new collection is found.
01232    //   For example if list is a TObjArray*
01233    //     - if splitlevel = 1, one top level branch is created for each element
01234    //        of the TObjArray.
01235    //     - if splitlevel = 2, one top level branch is created for each array element.
01236    //       if, in turn, one of the array elements is a TCollection, one top level
01237    //       branch will be created for each element of this collection.
01238    //
01239    //   In case a collection element is a TClonesArray, the special Tree constructor
01240    //   for TClonesArray is called.
01241    //   The collection itself cannot be a TClonesArray.
01242    //
01243    //   The function returns the total number of branches created.
01244    //
01245    //   If name is given, all branch names will be prefixed with name_.
01246    //
01247    // IMPORTANT NOTE1: This function should not be called with splitlevel < 1.
01248    //
01249    // IMPORTANT NOTE2: The branches created by this function will have names
01250    // corresponding to the collection or object names. It is important
01251    // to give names to collections to avoid misleading branch names or
01252    // identical branch names. By default collections have a name equal to
01253    // the corresponding class name, eg the default name for a TList is "TList".
01254    //
01255    // Example--------------------------------------------------------------:
01256    /*
01257    {
01258          TTree T("T","test list");
01259          TList *l = new TList();
01260 
01261          TObjArray *a1 = new TObjArray();
01262          a1->SetName("a1");
01263          l->Add(a1);
01264          TH1F *ha1a = new TH1F("ha1a","ha1",100,0,1);
01265          TH1F *ha1b = new TH1F("ha1b","ha1",100,0,1);
01266          a1->Add(ha1a);
01267          a1->Add(ha1b);
01268          TObjArray *b1 = new TObjArray();
01269          b1->SetName("b1");
01270          l->Add(b1);
01271          TH1F *hb1a = new TH1F("hb1a","hb1",100,0,1);
01272          TH1F *hb1b = new TH1F("hb1b","hb1",100,0,1);
01273          b1->Add(hb1a);
01274          b1->Add(hb1b);
01275 
01276          TObjArray *a2 = new TObjArray();
01277          a2->SetName("a2");
01278          l->Add(a2);
01279          TH1S *ha2a = new TH1S("ha2a","ha2",100,0,1);
01280          TH1S *ha2b = new TH1S("ha2b","ha2",100,0,1);
01281          a2->Add(ha2a);
01282          a2->Add(ha2b);
01283 
01284          T.Branch(l,16000,2);
01285          T.Print();
01286    }
01287    */
01288    //----------------------------------------------------------------------
01289 
01290    if (!li) {
01291       return 0;
01292    }
01293    TObject* obj = 0;
01294    Int_t nbranches = GetListOfBranches()->GetEntries();
01295    if (li->InheritsFrom(TClonesArray::Class())) {
01296       Error("Branch", "Cannot call this constructor for a TClonesArray");
01297       return 0;
01298    }
01299    Int_t nch = strlen(name);
01300    TString branchname;
01301    TIter next(li);
01302    while ((obj = next())) {
01303       if ((splitlevel > 1) &&  obj->InheritsFrom(TCollection::Class()) && !obj->InheritsFrom(TClonesArray::Class())) {
01304          TCollection* col = (TCollection*) obj;
01305          if (nch) {
01306             branchname.Form("%s_%s_", name, col->GetName());
01307          } else {
01308             branchname.Form("%s_", col->GetName());
01309          }
01310          Branch(col, bufsize, splitlevel - 1, branchname);
01311       } else {
01312          if (nch && (name[nch-1] == '_')) {
01313             branchname.Form("%s%s", name, obj->GetName());
01314          } else {
01315             if (nch) {
01316                branchname.Form("%s_%s", name, obj->GetName());
01317             } else {
01318                branchname.Form("%s", obj->GetName());
01319             }
01320          }
01321          if (splitlevel > 99) {
01322             branchname += ".";
01323          }
01324          Bronch(branchname, obj->ClassName(), li->GetObjectRef(obj), bufsize, splitlevel - 1);
01325       }
01326    }
01327    return GetListOfBranches()->GetEntries() - nbranches;
01328 }
01329 
01330 //______________________________________________________________________________
01331 Int_t TTree::Branch(const char* foldername, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */)
01332 {
01333    // Create one branch for each element in the folder.
01334    // Returns the total number of branches created.
01335 
01336    TObject* ob = gROOT->FindObjectAny(foldername);
01337    if (!ob) {
01338       return 0;
01339    }
01340    if (ob->IsA() != TFolder::Class()) {
01341       return 0;
01342    }
01343    Int_t nbranches = GetListOfBranches()->GetEntries();
01344    TFolder* folder = (TFolder*) ob;
01345    TIter next(folder->GetListOfFolders());
01346    TObject* obj = 0;
01347    char* curname = new char[1000];
01348    char occur[20];
01349    while ((obj = next())) {
01350       snprintf(curname,1000, "%s/%s", foldername, obj->GetName());
01351       if (obj->IsA() == TFolder::Class()) {
01352          Branch(curname, bufsize, splitlevel - 1);
01353       } else {
01354          void* add = (void*) folder->GetListOfFolders()->GetObjectRef(obj);
01355          for (Int_t i = 0; i < 1000; ++i) {
01356             if (curname[i] == 0) {
01357                break;
01358             }
01359             if (curname[i] == '/') {
01360                curname[i] = '.';
01361             }
01362          }
01363          Int_t noccur = folder->Occurence(obj);
01364          if (noccur > 0) {
01365             snprintf(occur,20, "_%d", noccur);
01366             strlcat(curname, occur,1000); 
01367          }
01368          TBranchElement* br = (TBranchElement*) Bronch(curname, obj->ClassName(), add, bufsize, splitlevel - 1);
01369          br->SetBranchFolder();
01370       }
01371    }
01372    delete[] curname;
01373    return GetListOfBranches()->GetEntries() - nbranches;
01374 }
01375 
01376 //______________________________________________________________________________
01377 TBranch* TTree::Branch(const char* name, void* address, const char* leaflist, Int_t bufsize /* = 32000 */)
01378 {
01379    // Create a new TTree Branch.
01380    //
01381    //    This Branch constructor is provided to support non-objects in
01382    //    a Tree. The variables described in leaflist may be simple
01383    //    variables or structures.  // See the two following
01384    //    constructors for writing objects in a Tree.
01385    //
01386    //    By default the branch buffers are stored in the same file as the Tree.
01387    //    use TBranch::SetFile to specify a different file
01388    //
01389    //       * address is the address of the first item of a structure.
01390    //       * leaflist is the concatenation of all the variable names and types
01391    //         separated by a colon character :
01392    //         The variable name and the variable type are separated by a slash (/).
01393    //         The variable type may be 0,1 or 2 characters. If no type is given,
01394    //         the type of the variable is assumed to be the same as the previous
01395    //         variable. If the first variable does not have a type, it is assumed
01396    //         of type F by default. The list of currently supported types is given below:
01397    //            - C : a character string terminated by the 0 character
01398    //            - B : an 8 bit signed integer (Char_t)
01399    //            - b : an 8 bit unsigned integer (UChar_t)
01400    //            - S : a 16 bit signed integer (Short_t)
01401    //            - s : a 16 bit unsigned integer (UShort_t)
01402    //            - I : a 32 bit signed integer (Int_t)
01403    //            - i : a 32 bit unsigned integer (UInt_t)
01404    //            - F : a 32 bit floating point (Float_t)
01405    //            - D : a 64 bit floating point (Double_t)
01406    //            - L : a 64 bit signed integer (Long64_t)
01407    //            - l : a 64 bit unsigned integer (ULong64_t)
01408    //            - O : a boolean (Bool_t)
01409    //
01410    //         By default, a variable will be copied to the buffer with the number of
01411    //         bytes specified in the type descriptor character. However, if the type
01412    //         consists of 2 characters, the second character is an integer that
01413    //         specifies the number of bytes to be used when copying the variable
01414    //         to the output buffer. Example:
01415    //             X         ; variable X, type Float_t
01416    //             Y/I       : variable Y, type Int_t
01417    //             Y/I2      ; variable Y, type Int_t converted to a 16 bits integer
01418    //
01419    //    Note that the TTree will assume that all the item are contiguous in memory.
01420    //    On some platform, this is not always true of the member of a struct or a class,
01421    //    due to padding and alignment.  Sorting your data member in order of decreasing
01422    //    sizeof usually leads to their being contiguous in memory.
01423    //
01424    //       * bufsize is the buffer size in bytes for this branch
01425    //         The default value is 32000 bytes and should be ok for most cases.
01426    //         You can specify a larger value (eg 256000) if your Tree is not split
01427    //         and each entry is large (Megabytes)
01428    //         A small value for bufsize is optimum if you intend to access
01429    //         the entries in the Tree randomly and your Tree is in split mode.
01430 
01431    gTree = this;
01432    TBranch* branch = new TBranch(this, name, address, leaflist, bufsize);
01433    if (branch->IsZombie()) {
01434       delete branch;
01435       branch = 0;
01436       return 0;
01437    }
01438    fBranches.Add(branch);
01439    return branch;
01440 }
01441 
01442 //______________________________________________________________________________
01443 TBranch* TTree::Branch(const char* name, const char* classname, void* addobj, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */)
01444 {
01445    // Create a new branch with the object of class classname at address addobj.
01446    //
01447    // WARNING:
01448    // Starting with Root version 3.01, the Branch function uses the new style
01449    // branches (TBranchElement). To get the old behaviour, you can:
01450    //   - call BranchOld or
01451    //   - call TTree::SetBranchStyle(0)
01452    //
01453    // Note that with the new style, classname does not need to derive from TObject.
01454    // It must derived from TObject if the branch style has been set to 0 (old)
01455    //
01456    // Note: See the comments in TBranchElement::SetAddress() for a more
01457    //       detailed discussion of the meaning of the addobj parameter in
01458    //       the case of new-style branches.
01459    //
01460    // Use splitlevel < 0 instead of splitlevel=0 when the class
01461    // has a custom Streamer
01462    //
01463    // Note: if the split level is set to the default (99),  TTree::Branch will
01464    // not issue a warning if the class can not be split.
01465 
01466    if (fgBranchStyle == 1) {
01467       return Bronch(name, classname, addobj, bufsize, splitlevel);
01468    } else {
01469       if (splitlevel < 0) {
01470          splitlevel = 0;
01471       }
01472       return BranchOld(name, classname, addobj, bufsize, splitlevel);
01473    }
01474 }
01475 
01476 //______________________________________________________________________________
01477 TBranch* TTree::BranchOld(const char* name, const char* classname, void* addobj, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 1 */)
01478 {
01479    // Create a new TTree BranchObject.
01480    //
01481    //    Build a TBranchObject for an object of class classname.
01482    //    addobj is the address of a pointer to an object of class classname.
01483    //    IMPORTANT: classname must derive from TObject.
01484    //    The class dictionary must be available (ClassDef in class header).
01485    //
01486    //    This option requires access to the library where the corresponding class
01487    //    is defined. Accessing one single data member in the object implies
01488    //    reading the full object.
01489    //    See the next Branch constructor for a more efficient storage
01490    //    in case the entry consists of arrays of identical objects.
01491    //
01492    //    By default the branch buffers are stored in the same file as the Tree.
01493    //    use TBranch::SetFile to specify a different file
01494    //
01495    //      IMPORTANT NOTE about branch names
01496    //    In case two or more master branches contain subbranches with
01497    //    identical names, one must add a "." (dot) character at the end
01498    //    of the master branch name. This will force the name of the subbranch
01499    //    to be master.subbranch instead of simply subbranch.
01500    //    This situation happens when the top level object (say event)
01501    //    has two or more members referencing the same class.
01502    //    For example, if a Tree has two branches B1 and B2 corresponding
01503    //    to objects of the same class MyClass, one can do:
01504    //       tree.Branch("B1.","MyClass",&b1,8000,1);
01505    //       tree.Branch("B2.","MyClass",&b2,8000,1);
01506    //    if MyClass has 3 members a,b,c, the two instructions above will generate
01507    //    subbranches called B1.a, B1.b ,B1.c, B2.a, B2.b, B2.c
01508    //
01509    //    bufsize is the buffer size in bytes for this branch
01510    //    The default value is 32000 bytes and should be ok for most cases.
01511    //    You can specify a larger value (eg 256000) if your Tree is not split
01512    //    and each entry is large (Megabytes)
01513    //    A small value for bufsize is optimum if you intend to access
01514    //    the entries in the Tree randomly and your Tree is in split mode.
01515 
01516    gTree = this;
01517    TClass* cl = TClass::GetClass(classname);
01518    if (!cl) {
01519       Error("BranchOld", "Cannot find class: '%s'", classname);
01520       return 0;
01521    }
01522    TBranch* branch = new TBranchObject(this, name, classname, addobj, bufsize, splitlevel);
01523    fBranches.Add(branch);
01524    if (!splitlevel) {
01525       return branch;
01526    }
01527    // We are going to fully split the class now.
01528    TObjArray* blist = branch->GetListOfBranches();
01529    const char* rdname = 0;
01530    const char* dname = 0;
01531    TString branchname;
01532    char** apointer = (char**) addobj;
01533    TObject* obj = (TObject*) *apointer;
01534    Bool_t delobj = kFALSE;
01535    if (!obj) {
01536       obj = (TObject*) cl->New();
01537       delobj = kTRUE;
01538    }
01539    // Build the StreamerInfo if first time for the class.
01540    BuildStreamerInfo(cl, obj);
01541    // Loop on all public data members of the class and its base classes.
01542    Int_t lenName = strlen(name);
01543    Int_t isDot = 0;
01544    if (name[lenName-1] == '.') {
01545       isDot = 1;
01546    }
01547    TBranch* branch1 = 0;
01548    TRealData* rd = 0;
01549    TRealData* rdi = 0;
01550    TIter nexti(cl->GetListOfRealData());
01551    TIter next(cl->GetListOfRealData());
01552    // Note: This loop results in a full split because the
01553    //       real data list includes all data members of
01554    //       data members.
01555    while ((rd = (TRealData*) next())) {
01556       if (rd->TestBit(TRealData::kTransient)) continue;
01557 
01558       // Loop over all data members creating branches for each one.
01559       TDataMember* dm = rd->GetDataMember();
01560       if (!dm->IsPersistent()) {
01561          // Do not process members with an "!" as the first character in the comment field.
01562          continue;
01563       }
01564       if (rd->IsObject()) {
01565          // We skip data members of class type.
01566          // But we do build their real data, their
01567          // streamer info, and write their streamer
01568          // info to the current directory's file.
01569          // Oh yes, and we also do this for all of
01570          // their base classes.
01571          TClass* clm = TClass::GetClass(dm->GetFullTypeName());
01572          if (clm) {
01573             BuildStreamerInfo(clm, (char*) obj + rd->GetThisOffset());
01574          }
01575          continue;
01576       }
01577       rdname = rd->GetName();
01578       dname = dm->GetName();
01579       if (cl->CanIgnoreTObjectStreamer()) {
01580          // Skip the TObject base class data members.
01581          // FIXME: This prevents a user from ever
01582          //        using these names himself!
01583          if (!strcmp(dname, "fBits")) {
01584             continue;
01585          }
01586          if (!strcmp(dname, "fUniqueID")) {
01587             continue;
01588          }
01589       }
01590       TDataType* dtype = dm->GetDataType();
01591       Int_t code = 0;
01592       if (dtype) {
01593          code = dm->GetDataType()->GetType();
01594       }
01595       // Encode branch name. Use real data member name
01596       branchname = rdname;
01597       if (isDot) {
01598          if (dm->IsaPointer()) {
01599             // FIXME: This is wrong!  The asterisk is not usually in the front!
01600             branchname.Form("%s%s", name, &rdname[1]);
01601          } else {
01602             branchname.Form("%s%s", name, &rdname[0]);
01603          }
01604       }
01605       // FIXME: Change this to a string stream.
01606       TString leaflist;
01607       Int_t offset = rd->GetThisOffset();
01608       char* pointer = ((char*) obj) + offset;
01609       if (dm->IsaPointer()) {
01610          // We have a pointer to an object or a pointer to an array of basic types.
01611          TClass* clobj = 0;
01612          if (!dm->IsBasic()) {
01613             clobj = TClass::GetClass(dm->GetTypeName());
01614          }
01615          if (clobj && clobj->InheritsFrom(TClonesArray::Class())) {
01616             // We have a pointer to a clones array.
01617             char* cpointer = (char*) pointer;
01618             char** ppointer = (char**) cpointer;
01619             TClonesArray* li = (TClonesArray*) *ppointer;
01620             if (splitlevel != 2) {
01621                if (isDot) {
01622                   branch1 = new TBranchClones(branch,branchname, pointer, bufsize);
01623                } else {
01624                   // FIXME: This is wrong!  The asterisk is not usually in the front!
01625                   branch1 = new TBranchClones(branch,&branchname.Data()[1], pointer, bufsize);
01626                }
01627                blist->Add(branch1);
01628             } else {
01629                if (isDot) {
01630                   branch1 = new TBranchObject(branch, branchname, li->ClassName(), pointer, bufsize);
01631                } else {
01632                   // FIXME: This is wrong!  The asterisk is not usually in the front!
01633                   branch1 = new TBranchObject(branch, &branchname.Data()[1], li->ClassName(), pointer, bufsize);
01634                }
01635                blist->Add(branch1);
01636             }
01637          } else if (clobj) {
01638             // We have a pointer to an object.
01639             //
01640             // It must be a TObject object.
01641             if (!clobj->InheritsFrom(TObject::Class())) {
01642                continue;
01643             }
01644             branch1 = new TBranchObject(branch, dname, clobj->GetName(), pointer, bufsize, 0);
01645             if (isDot) {
01646                branch1->SetName(branchname);
01647             } else {
01648                // FIXME: This is wrong!  The asterisk is not usually in the front!
01649                // Do not use the first character (*).
01650                branch1->SetName(&branchname.Data()[1]);
01651             }
01652             blist->Add(branch1);
01653          } else {
01654             // We have a pointer to an array of basic types.
01655             //
01656             // Check the comments in the text of the code for an index specification.
01657             const char* index = dm->GetArrayIndex();
01658             if (strlen(index) != 0) {
01659                // We are a pointer to a varying length array of basic types.
01660                //check that index is a valid data member name
01661                //if member is part of an object (eg fA and index=fN)
01662                //index must be changed from fN to fA.fN
01663                TString aindex (rd->GetName());
01664                Ssiz_t rdot = aindex.Last('.');
01665                if (rdot>=0) {
01666                   aindex.Remove(rdot+1);
01667                   aindex.Append(index);
01668                }
01669                nexti.Reset();
01670                while ((rdi = (TRealData*) nexti())) {
01671                   if (rdi->TestBit(TRealData::kTransient)) continue;
01672 
01673                   if (!strcmp(rdi->GetName(), index)) {
01674                      break;
01675                   }
01676                   if (!strcmp(rdi->GetName(), aindex)) {
01677                      index = rdi->GetName();
01678                      break;
01679                   }
01680                }
01681 
01682                char vcode = DataTypeToChar((EDataType)code);
01683                // Note that we differentiate between strings and
01684                // char array by the fact that there is NO specified
01685                // size for a string (see next if (code == 1)
01686 
01687                if (vcode) {
01688                   leaflist.Form("%s[%s]/%c", &rdname[0], index, vcode);
01689                } else {
01690                   Error("BranchOld", "Cannot create branch for rdname: %s code: %d", branchname.Data(), code);
01691                   leaflist = "";
01692                }
01693             } else {
01694                // We are possibly a character string.
01695                if (code == 1) {
01696                   // We are a character string.
01697                   leaflist.Form("%s/%s", dname, "C");
01698                } else {
01699                   // Invalid array specification.
01700                   // FIXME: We need an error message here.
01701                   continue;
01702                }
01703             }
01704             // There are '*' in both the branchname and leaflist, remove them.
01705             TString bname( branchname );
01706             bname.ReplaceAll("*","");
01707             leaflist.ReplaceAll("*","");
01708             // Add the branch to the tree and indicate that the address
01709             // is that of a pointer to be dereferenced before using.
01710             branch1 = new TBranch(branch, bname, *((void**) pointer), leaflist, bufsize);
01711             TLeaf* leaf = (TLeaf*) branch1->GetListOfLeaves()->At(0);
01712             leaf->SetBit(TLeaf::kIndirectAddress);
01713             leaf->SetAddress((void**) pointer);
01714             blist->Add(branch1);
01715          }
01716       } else if (dm->IsBasic()) {
01717          // We have a basic type.
01718 
01719          char vcode = DataTypeToChar((EDataType)code);
01720          if (vcode) {
01721             leaflist.Form("%s/%c", rdname, vcode);
01722          } else {
01723             Error("BranchOld", "Cannot create branch for rdname: %s code: %d", branchname.Data(), code);
01724             leaflist = "";
01725          }
01726          branch1 = new TBranch(branch, branchname, pointer, leaflist, bufsize);
01727          branch1->SetTitle(rdname);
01728          blist->Add(branch1);
01729       } else {
01730          // We have a class type.
01731          // Note: This cannot happen due to the rd->IsObject() test above.
01732          // FIXME: Put an error message here just in case.
01733       }
01734       if (branch1) {
01735          branch1->SetOffset(offset);
01736       } else {
01737          Warning("BranchOld", "Cannot process member: '%s'", rdname);
01738       }
01739    }
01740    if (delobj) {
01741       delete obj;
01742       obj = 0;
01743    }
01744    return branch;
01745 }
01746 
01747 //______________________________________________________________________________
01748 TBranch* TTree::BranchRef()
01749 {
01750    // Build the optional branch supporting the TRefTable.
01751    // This branch will keep all the information to find the branches
01752    // containing referenced objects.
01753    //
01754    // At each Tree::Fill, the branch numbers containing the
01755    // referenced objects are saved to the TBranchRef basket.
01756    // When the Tree header is saved (via TTree::Write), the branch
01757    // is saved keeping the information with the pointers to the branches
01758    // having referenced objects.
01759 
01760    if (!fBranchRef) {
01761       fBranchRef = new TBranchRef(this);
01762    }
01763    return fBranchRef;
01764 }
01765 
01766 //______________________________________________________________________________
01767 TBranch* TTree::Bronch(const char* name, const char* classname, void* addr, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */)
01768 {
01769    // Create a new TTree BranchElement.
01770    //
01771    //    WARNING about this new function
01772    //    ===============================
01773    //    This function is designed to replace the function TTree::Branch above.
01774    //    This function is far more powerful than the Branch function.
01775    //    It supports the full C++, including STL and has the same behaviour
01776    //    in split or non-split mode. classname does not have to derive from TObject.
01777    //    The function is based on the new TStreamerInfo.
01778    //
01779    //    Build a TBranchElement for an object of class classname.
01780    //
01781    //    addr is the address of a pointer to an object of class classname.
01782    //    The class dictionary must be available (ClassDef in class header).
01783    //
01784    //    Note: See the comments in TBranchElement::SetAddress() for a more
01785    //          detailed discussion of the meaning of the addr parameter.
01786    //
01787    //    This option requires access to the library where the corresponding class
01788    //    is defined. Accessing one single data member in the object implies
01789    //    reading the full object.
01790    //
01791    //    By default the branch buffers are stored in the same file as the Tree.
01792    //    use TBranch::SetFile to specify a different file
01793    //
01794    //      IMPORTANT NOTE about branch names
01795    //    In case two or more master branches contain subbranches with
01796    //    identical names, one must add a "." (dot) character at the end
01797    //    of the master branch name. This will force the name of the subbranch
01798    //    to be master.subbranch instead of simply subbranch.
01799    //    This situation happens when the top level object (say event)
01800    //    has two or more members referencing the same class.
01801    //    For example, if a Tree has two branches B1 and B2 corresponding
01802    //    to objects of the same class MyClass, one can do:
01803    //       tree.Branch("B1.","MyClass",&b1,8000,1);
01804    //       tree.Branch("B2.","MyClass",&b2,8000,1);
01805    //    if MyClass has 3 members a,b,c, the two instructions above will generate
01806    //    subbranches called B1.a, B1.b ,B1.c, B2.a, B2.b, B2.c
01807    //
01808    //    bufsize is the buffer size in bytes for this branch
01809    //    The default value is 32000 bytes and should be ok for most cases.
01810    //    You can specify a larger value (eg 256000) if your Tree is not split
01811    //    and each entry is large (Megabytes)
01812    //    A small value for bufsize is optimum if you intend to access
01813    //    the entries in the Tree randomly and your Tree is in split mode.
01814    //
01815    //    Use splitlevel < 0 instead of splitlevel=0 when the class
01816    //    has a custom Streamer
01817    //
01818    //    Note: if the split level is set to the default (99),  TTree::Branch will
01819    //    not issue a warning if the class can not be split.
01820 
01821    return BronchExec(name, classname, addr, kTRUE, bufsize, splitlevel);
01822 }
01823 
01824 //______________________________________________________________________________
01825 TBranch* TTree::BronchExec(const char* name, const char* classname, void* addr, Bool_t isptrptr, Int_t bufsize /* = 32000 */, Int_t splitlevel /* = 99 */)
01826 {
01827    // Helper function implementing TTree::Bronch and TTree::Branch(const char *name, T &obj);
01828 
01829    gTree = this;
01830    TClass* cl = TClass::GetClass(classname);
01831    if (!cl) {
01832       Error("Bronch", "Cannot find class:%s", classname);
01833       return 0;
01834    }
01835 
01836    //if splitlevel <= 0 and class has a custom Streamer, we must create
01837    //a TBranchObject. We cannot assume that TClass::ReadBuffer is consistent
01838    //with the custom Streamer. The penalty is that one cannot process
01839    //this Tree without the class library containing the class.
01840    //The following convention is used for the RootFlag
01841    // #pragma link C++ class TExMap;     rootflag = 0
01842    // #pragma link C++ class TList-;     rootflag = 1
01843    // #pragma link C++ class TArray!;    rootflag = 2
01844    // #pragma link C++ class TArrayC-!;  rootflag = 3
01845    // #pragma link C++ class TBits+;     rootflag = 4
01846    // #pragma link C++ class Txxxx+!;    rootflag = 6
01847 
01848    char* objptr = 0;
01849    if (!isptrptr) {
01850       objptr = (char*)addr;
01851    } else if (addr) {
01852       objptr = *((char**) addr);
01853    }
01854 
01855    if (cl == TClonesArray::Class()) {
01856       TClonesArray* clones = (TClonesArray*) objptr;
01857       if (!clones) {
01858          Error("Bronch", "Pointer to TClonesArray is null");
01859          return 0;
01860       }
01861       if (!clones->GetClass()) {
01862          Error("Bronch", "TClonesArray with no class defined in branch: %s", name);
01863          return 0;
01864       }
01865       void* classinfo = clones->GetClass()->GetClassInfo();
01866       if (!classinfo) {
01867          Error("Bronch", "TClonesArray with no dictionary defined in branch: %s", name);
01868          return 0;
01869       }
01870       int rootflag = gCint->ClassInfo_RootFlag(classinfo);
01871       if (splitlevel > 0) {
01872          if (rootflag & 1)
01873             Warning("Bronch", "Using split mode on a class: %s with a custom Streamer", clones->GetClass()->GetName());
01874       } else {
01875          if (rootflag & 1) clones->BypassStreamer(kFALSE);
01876          TBranchObject *branch = new TBranchObject(this,name,classname,addr,bufsize,0,isptrptr);
01877          fBranches.Add(branch);
01878          return branch;
01879       }
01880    }
01881 
01882    if (cl->GetCollectionProxy()) {
01883       TVirtualCollectionProxy* collProxy = cl->GetCollectionProxy();
01884       //if (!collProxy) {
01885       //   Error("Bronch", "%s is missing its CollectionProxy (for branch %s)", classname, name);
01886       //}
01887       TClass* inklass = collProxy->GetValueClass();
01888       if (!inklass && (collProxy->GetType() == 0)) {
01889          Error("Bronch", "%s with no class defined in branch: %s", classname, name);
01890          return 0;
01891       }
01892       if ((splitlevel > 0) && inklass && (inklass->GetCollectionProxy() == 0)) {
01893          Int_t stl = -TClassEdit::IsSTLCont(cl->GetName(), 0);
01894          if ((stl != TClassEdit::kMap) && (stl != TClassEdit::kMultiMap)) {
01895             void *classinfo = inklass->GetClassInfo();
01896             if (!classinfo) {
01897                Error("Bronch", "Container with no dictionary defined in branch: %s", name);
01898                return 0;
01899             }
01900             if (gCint->ClassInfo_RootFlag(classinfo) & 1) {
01901                Warning("Bronch", "Using split mode on a class: %s with a custom Streamer", inklass->GetName());
01902             }
01903          }
01904       }
01905       //-------------------------------------------------------------------------
01906       // If the splitting switch is enabled, the split level is big enough and
01907       // the collection contains pointers we can split it
01908       //-------------------------------------------------------------------------
01909       TBranch *branch;
01910       if( splitlevel > kSplitCollectionOfPointers && collProxy->HasPointers() )
01911          branch = new TBranchSTL( this, name, collProxy, bufsize, splitlevel );
01912       else
01913          branch = new TBranchElement(this, name, collProxy, bufsize, splitlevel);
01914       fBranches.Add(branch);
01915       if (isptrptr) {
01916          branch->SetAddress(addr);
01917       } else {
01918          branch->SetObject(addr);
01919       }
01920       return branch;
01921    }
01922 
01923    Bool_t hasCustomStreamer = kFALSE;
01924    if (!cl->GetClassInfo() && !cl->GetCollectionProxy()) {
01925       Error("Bronch", "Cannot find dictionary for class: %s", classname);
01926       return 0;
01927    }
01928 
01929    if (!cl->GetCollectionProxy() && (gCint->ClassInfo_RootFlag(cl->GetClassInfo()) & 1)) {
01930       // Not an STL container and the linkdef file had a "-" after the class name.
01931       hasCustomStreamer = kTRUE;
01932    }
01933 
01934    if (splitlevel < 0 || ((splitlevel == 0) && hasCustomStreamer && cl->InheritsFrom(TObject::Class()))) {
01935       TBranchObject* branch = new TBranchObject(this, name, classname, addr, bufsize, 0, isptrptr);
01936       fBranches.Add(branch);
01937       return branch;
01938    }
01939 
01940    if (cl == TClonesArray::Class()) {
01941       // Special case of TClonesArray.
01942       // No dummy object is created.
01943       // The streamer info is not rebuilt unoptimized.
01944       // No dummy top-level branch is created.
01945       // No splitting is attempted.
01946       TBranchElement* branch = new TBranchElement(this, name, (TClonesArray*) objptr, bufsize, splitlevel%kSplitCollectionOfPointers);
01947       fBranches.Add(branch);
01948       if (isptrptr) {
01949          branch->SetAddress(addr);
01950       } else {
01951          branch->SetObject(addr);
01952       }
01953       return branch;
01954    }
01955 
01956    //
01957    // If we are not given an object to use as an i/o buffer
01958    // then create a temporary one which we will delete just
01959    // before returning.
01960    //
01961 
01962    Bool_t delobj = kFALSE;
01963 
01964    if (!objptr) {
01965       objptr = (char*) cl->New();
01966       delobj = kTRUE;
01967    }
01968 
01969    //
01970    // Avoid splitting unsplittable classes.
01971    //
01972 
01973    if ((splitlevel > 0) && !cl->CanSplit()) {
01974       if (splitlevel != 99) {
01975          Warning("Bronch", "%s cannot be split, resetting splitlevel to 0", cl->GetName());
01976       }
01977       splitlevel = 0;
01978    }
01979 
01980    //
01981    // Make sure the streamer info is built and fetch it.
01982    //
01983    // If we are splitting, then make sure the streamer info
01984    // is built unoptimized (data members are not combined).
01985    //
01986 
01987    TStreamerInfo* sinfo = BuildStreamerInfo(cl, objptr, splitlevel==0);
01988 
01989    //
01990    // Do we have a final dot in our name?
01991    //
01992 
01993    // Note: The branch constructor which takes a folder as input
01994    //       creates top-level branch names with dots in them to
01995    //       indicate the folder heirarchy.
01996    char* dot = (char*) strchr(name, '.');
01997    Int_t nch = strlen(name);
01998    Bool_t dotlast = kFALSE;
01999    if (nch && (name[nch-1] == '.')) {
02000       dotlast = kTRUE;
02001    }
02002 
02003    //
02004    // Create a dummy top level branch object.
02005    //
02006 
02007    Int_t id = -1;
02008    if (splitlevel > 0) {
02009       id = -2;
02010    }
02011    TBranchElement* branch = new TBranchElement(this, name, sinfo, id, objptr, bufsize, splitlevel);
02012    fBranches.Add(branch);
02013 
02014    //
02015    // Do splitting, if requested.
02016    //
02017 
02018    if (splitlevel%kSplitCollectionOfPointers > 0) {
02019       // Loop on all public data members of the class and its base classes and create branches for each one.
02020       TObjArray* blist = branch->GetListOfBranches();
02021       TIter next(sinfo->GetElements());
02022       TStreamerElement* element = 0;
02023       TString bname;
02024       for (id = 0; (element = (TStreamerElement*) next()); ++id) {
02025          if (element->IsA() == TStreamerArtificial::Class()) {
02026             continue;
02027          }
02028          if (element->TestBit(TStreamerElement::kRepeat)) {
02029             continue;
02030          }
02031          char* pointer = (char*) (objptr + element->GetOffset());
02032          // FIXME: This is not good enough, an STL container can be
02033          //        a base, and the test will fail.
02034          //        See TBranchElement::InitializeOffsets() for the
02035          //        correct test.
02036          Bool_t isBase = (element->IsA() == TStreamerBase::Class());
02037          if (isBase) {
02038             TClass* clbase = element->GetClassPointer();
02039             if ((clbase == TObject::Class()) && cl->CanIgnoreTObjectStreamer()) {
02040                // Note: TStreamerInfo::Compile() leaves this element
02041                //       out of the compiled info, although it does
02042                //       exists in the non-compiled info.  We must
02043                //       account for the fact that this element is
02044                //       missing in the compiled streamer info by
02045                //       making sure that we do not consume an id
02046                //       number for it.
02047                // FIXME: The test that TStreamerInfo::Compile() uses
02048                //        is element->GetType() < 0, so that is what
02049                //        we should do as well.
02050                --id;
02051                continue;
02052             }
02053          }
02054          if (dot) {
02055             if (dotlast) {
02056                bname.Form("%s%s", name, element->GetFullName());
02057             } else {
02058                // FIXME: We are in the case where we have a top-level
02059                //        branch name that was created by the branch
02060                //        constructor which takes a folder as input.
02061                //        The internal dots in the name are in place of
02062                //        of the original slashes and represent the
02063                //        folder heirarchy.
02064                if (isBase) {
02065                   // FIXME: This is very strange, this is the only case where
02066                   //        we create a branch for a base class that does
02067                   //        not have the base class name in the branch name.
02068                   // FIXME: This is also quite bad since classes with two
02069                   //        or more base classes end up with sub-branches
02070                   //        that have the same name.
02071                   bname = name;
02072                } else {
02073                   bname.Form("%s.%s", name, element->GetFullName());
02074                }
02075             }
02076          } else {
02077             // Note: For a base class element, this results in the branchname
02078             //       being the name of the base class.
02079             bname.Form("%s", element->GetFullName());
02080          }
02081 
02082          if( splitlevel > kSplitCollectionOfPointers && element->GetClass() &&
02083              element->GetClass()->GetCollectionProxy() &&
02084              element->GetClass()->GetCollectionProxy()->HasPointers() )
02085          {
02086             TBranchSTL* brSTL = new TBranchSTL( branch, bname, element->GetClass()->GetCollectionProxy(), bufsize, splitlevel-1, sinfo, id );
02087             blist->Add(brSTL);
02088          }
02089          else
02090          {
02091             TBranchElement* bre = new TBranchElement(branch, bname, sinfo, id, pointer, bufsize, splitlevel - 1);
02092             bre->SetParentClass(cl);
02093             blist->Add(bre);
02094          }
02095       }
02096    }
02097 
02098    //
02099    // Setup our offsets into the user's i/o buffer.
02100    //
02101 
02102    if (isptrptr) {
02103       branch->SetAddress(addr);
02104    } else {
02105       branch->SetObject(addr);
02106    }
02107 
02108    if (delobj) {
02109       cl->Destructor(objptr);
02110       objptr = 0;
02111    }
02112 
02113    return branch;
02114 }
02115 
02116 //______________________________________________________________________________
02117 void TTree::Browse(TBrowser* b)
02118 {
02119    // Browse content of the TTree.
02120 
02121    fBranches.Browse(b);
02122    if (fUserInfo) {
02123       if (strcmp("TList",fUserInfo->GetName())==0) {
02124          fUserInfo->SetName("UserInfo");
02125          b->Add(fUserInfo);
02126          fUserInfo->SetName("TList");
02127       } else {
02128          b->Add(fUserInfo);
02129       }
02130    }
02131 }
02132 
02133 //______________________________________________________________________________
02134 Int_t TTree::BuildIndex(const char* majorname, const char* minorname /* = "0" */)
02135 {
02136    // Build a Tree Index (default is TTreeIndex).
02137    // See a description of the parameters and functionality in
02138    // TTreeIndex::TTreeIndex().
02139    //
02140    // The return value is the number of entries in the Index (< 0 indicates failure).
02141    //
02142    // A TTreeIndex object pointed by fTreeIndex is created.
02143    // This object will be automatically deleted by the TTree destructor.
02144    // See also comments in TTree::SetTreeIndex().
02145 
02146    fTreeIndex = GetPlayer()->BuildIndex(this, majorname, minorname);
02147    if (fTreeIndex->IsZombie()) {
02148       delete fTreeIndex;
02149       fTreeIndex = 0;
02150       return 0;
02151    }
02152    return fTreeIndex->GetN();
02153 }
02154 
02155 //______________________________________________________________________________
02156 TStreamerInfo* TTree::BuildStreamerInfo(TClass* cl, void* pointer /* = 0 */, Bool_t canOptimize /* = kTRUE */ )
02157 {
02158    // Build StreamerInfo for class cl.
02159    // pointer is an optional argument that may contain a pointer to an object of cl.
02160 
02161    if (!cl) {
02162       return 0;
02163    }
02164    cl->BuildRealData(pointer);
02165    TStreamerInfo* sinfo = (TStreamerInfo*)cl->GetStreamerInfo(cl->GetClassVersion());
02166 
02167    if (!canOptimize && (!sinfo->IsCompiled() || sinfo->IsOptimized()) ) {
02168       // Streamer info has not yet been compiled.
02169       //
02170       // Optimizing does not work with splitting.
02171       sinfo->SetBit(TVirtualStreamerInfo::kCannotOptimize);
02172       sinfo->Compile();
02173    }
02174 
02175    // Create StreamerInfo for all base classes.
02176    TBaseClass* base = 0;
02177    TIter nextb(cl->GetListOfBases());
02178    while((base = (TBaseClass*) nextb())) {
02179       if (base->IsSTLContainer()) {
02180          continue;
02181       }
02182       TClass* clm = TClass::GetClass(base->GetName());
02183       BuildStreamerInfo(clm, pointer, canOptimize);
02184    }
02185    if (fDirectory) {
02186       sinfo->ForceWriteInfo(fDirectory->GetFile());
02187    }
02188    return sinfo;
02189 }
02190 
02191 //______________________________________________________________________________
02192 TFile* TTree::ChangeFile(TFile* file)
02193 {
02194    // Called by TTree::Fill() when file has reached its maximum fgMaxTreeSize.
02195    // Create a new file. If the original file is named "myfile.root",
02196    // subsequent files are named "myfile_1.root", "myfile_2.root", etc.
02197    //
02198    // Returns a pointer to the new file.
02199    //
02200    // Currently, the automatic change of file is restricted
02201    // to the case where the tree is in the top level directory.
02202    // The file should not contain sub-directories.
02203    //
02204    // Before switching to a new file, the tree header is written
02205    // to the current file, then the current file is closed.
02206    //
02207    // To process the multiple files created by ChangeFile, one must use
02208    // a TChain.
02209    //
02210    // The new file name has a suffix "_N" where N is equal to fFileNumber+1.
02211    // By default a Root session starts with fFileNumber=0. One can set
02212    // fFileNumber to a different value via TTree::SetFileNumber.
02213    // In case a file named "_N" already exists, the function will try
02214    // a file named "__N", then "___N", etc.
02215    //
02216    // fgMaxTreeSize can be set via the static function TTree::SetMaxTreeSize.
02217    // The default value of fgMaxTreeSize is 100 Gigabytes.
02218    //
02219    // If the current file contains other objects like TH1 and TTree,
02220    // these objects are automatically moved to the new file.
02221    //
02222    // IMPORTANT NOTE:
02223    // Be careful when writing the final Tree header to the file!
02224    // Don't do:
02225    //  TFile *file = new TFile("myfile.root","recreate");
02226    //  TTree *T = new TTree("T","title");
02227    //  T->Fill(); //loop
02228    //  file->Write();
02229    //  file->Close();
02230    // but do the following:
02231    //  TFile *file = new TFile("myfile.root","recreate");
02232    //  TTree *T = new TTree("T","title");
02233    //  T->Fill(); //loop
02234    //  file = T->GetCurrentFile(); //to get the pointer to the current file
02235    //  file->Write();
02236    //  file->Close();
02237 
02238    file->cd();
02239    Write();
02240    Reset();
02241    char* fname = new char[2000];
02242    ++fFileNumber;
02243    char uscore[10];
02244    for (Int_t i = 0; i < 10; ++i) {
02245       uscore[i] = 0;
02246    }
02247    Int_t nus = 0;
02248    // Try to find a suitable file name that does not already exist.
02249    while (nus < 10) {
02250       uscore[nus] = '_';
02251       fname[0] = 0;
02252       strlcpy(fname, file->GetName(),2000);
02253       
02254       if (fFileNumber > 1) {
02255          char* cunder = strrchr(fname, '_');
02256          if (cunder) {
02257             snprintf(cunder,2000-Int_t(cunder-fname), "%s%d", uscore, fFileNumber);
02258             const char* cdot = strrchr(file->GetName(), '.');
02259             if (cdot) {
02260                strlcat(fname, cdot,2000); 
02261             }
02262          } else {
02263             char fcount[10];
02264             snprintf(fcount,10, "%s%d", uscore, fFileNumber);
02265             strlcat(fname, fcount,2000); 
02266          }
02267       } else {
02268          char* cdot = strrchr(fname, '.');
02269          if (cdot) {
02270             snprintf(cdot,2000-Int_t(fname-cdot), "%s%d", uscore, fFileNumber);
02271             strlcat(fname, strrchr(file->GetName(), '.'),2000); 
02272          } else {
02273             char fcount[10];
02274             snprintf(fcount,10, "%s%d", uscore, fFileNumber);
02275             strlcat(fname, fcount,2000); 
02276          }
02277       }
02278       if (gSystem->AccessPathName(fname)) {
02279          break;
02280       }
02281       ++nus;
02282       Warning("ChangeFile", "file %s already exist, trying with %d underscores", fname, nus+1);
02283    }
02284    Int_t compress = file->GetCompressionLevel();
02285    TFile* newfile = TFile::Open(fname, "recreate", "chain files", compress);
02286    Printf("Fill: Switching to new file: %s", fname);
02287    // The current directory may contain histograms and trees.
02288    // These objects must be moved to the new file.
02289    TBranch* branch = 0;
02290    TObject* obj = 0;
02291    while ((obj = file->GetList()->First())) {
02292       file->Remove(obj);
02293       // Histogram: just change the directory.
02294       if (obj->InheritsFrom("TH1")) {
02295          gROOT->ProcessLine(Form("((%s*)0x%lx)->SetDirectory((TDirectory*)0x%lx);", obj->ClassName(), (Long_t) obj, (Long_t) newfile));
02296          continue;
02297       }
02298       // Tree: must save all trees in the old file, reset them.
02299       if (obj->InheritsFrom(TTree::Class())) {
02300          TTree* t = (TTree*) obj;
02301          if (t != this) {
02302             t->AutoSave();
02303             t->Reset();
02304             t->fFileNumber = fFileNumber;
02305          }
02306          t->SetDirectory(newfile);
02307          TIter nextb(t->GetListOfBranches());
02308          while ((branch = (TBranch*)nextb())) {
02309             branch->SetFile(newfile);
02310          }
02311          if (t->GetBranchRef()) {
02312             t->GetBranchRef()->SetFile(newfile);
02313          }
02314          continue;
02315       }
02316       // Not a TH1 or a TTree, move object to new file.
02317       newfile->Append(obj);
02318       file->Remove(obj);
02319    }
02320    delete file;
02321    file = 0;
02322    delete[] fname;
02323    fname = 0;
02324    return newfile;
02325 }
02326 
02327 //______________________________________________________________________________
02328 Int_t TTree::CheckBranchAddressType(TBranch* branch, TClass* ptrClass, EDataType datatype, Bool_t isptr)
02329 {
02330    // Check whether or not the address described by the last 3 parameters
02331    // matches the content of the branch. If a Data Model Evolution conversion
02332    // is involved, reset the fInfo of the branch.
02333    // The return values are:
02334    //  kMissingBranch (-5) : Missing branch
02335    //  kInternalError (-4) : Internal error (could not find the type corresponding to a data type number)
02336    //  kMissingCompiledCollectionProxy (-3) : Missing compiled collection proxy for a compiled collection
02337    //  kMismatch (-2) : Non-Class Pointer type given does not match the type expected by the branch
02338    //  kClassMismatch (-1) : Class Pointer type given does not match the type expected by the branch
02339    //  kMatch (0) : perfect match
02340    //  kMatchConversion (1) : match with (I/O) conversion
02341    //  kMatchConversionCollection (2) : match with (I/O) conversion of the content of a collection
02342    //  kMakeClass (3) : MakeClass mode so we can not check.
02343    //  kVoidPtr (4) : void* passed so no check was made.
02344    //  kNoCheck (5) : Underlying TBranch not yet available so no check was made.
02345 
02346    if (GetMakeClass()) {
02347       // If we are in MakeClass mode so we do not really use classes.
02348       return kMakeClass;
02349    }
02350 
02351    // Let's determine what we need!
02352    TClass* expectedClass = 0;
02353    EDataType expectedType = kOther_t;
02354    if (0 != branch->GetExpectedType(expectedClass,expectedType) ) {
02355       // Something went wrong, the warning message has already be issued.
02356       return kInternalError;
02357    }
02358    if (expectedClass && ptrClass && (branch->GetMother() == branch)) {
02359       // Top Level branch
02360       if (!isptr) {
02361          Error("SetBranchAddress", "The address for \"%s\" should be the address of a pointer!", branch->GetName());
02362       }
02363    }
02364    if (expectedType == kFloat16_t) {
02365       expectedType = kFloat_t;
02366    }
02367    if (expectedType == kDouble32_t) {
02368       expectedType = kDouble_t;
02369    }
02370    if (datatype == kFloat16_t) {
02371       datatype = kFloat_t;
02372    }
02373    if (datatype == kDouble32_t) {
02374       datatype = kDouble_t;
02375    }
02376 
02377    //---------------------------------------------------------------------------
02378    // Deal with the class renaming
02379    //---------------------------------------------------------------------------
02380    if( expectedClass && ptrClass &&
02381        expectedClass != ptrClass &&
02382        branch->InheritsFrom( TBranchElement::Class() ) &&
02383        ptrClass->GetSchemaRules() &&
02384        ptrClass->GetSchemaRules()->HasRuleWithSourceClass( expectedClass->GetName() ) ) {
02385 
02386       TBranchElement* bEl = (TBranchElement*)branch;
02387 
02388       if( !ptrClass->GetConversionStreamerInfo( expectedClass, bEl->GetClassVersion() ) &&
02389           !ptrClass->FindConversionStreamerInfo( expectedClass, bEl->GetCheckSum() ) ) {
02390          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());
02391          return kClassMismatch;
02392       }
02393       else {
02394 
02395          bEl->SetTargetClass( ptrClass->GetName() );
02396          return kMatchConversion;
02397       }
02398 
02399    } else if (expectedClass && ptrClass && !expectedClass->InheritsFrom(ptrClass)) {
02400 
02401       if (expectedClass->GetCollectionProxy() && ptrClass->GetCollectionProxy() &&
02402           branch->InheritsFrom( TBranchElement::Class() ) &&
02403           expectedClass->GetCollectionProxy()->GetValueClass() &&
02404           ptrClass->GetCollectionProxy()->GetValueClass() )
02405       {
02406          // In case of collection, we know how to convert them, if we know how to convert their content.
02407          // NOTE: we need to extend this to std::pair ...
02408 
02409          TClass *onfileValueClass = expectedClass->GetCollectionProxy()->GetValueClass();
02410          TClass *inmemValueClass = ptrClass->GetCollectionProxy()->GetValueClass();
02411 
02412          if (inmemValueClass->GetSchemaRules() &&
02413              inmemValueClass->GetSchemaRules()->HasRuleWithSourceClass(onfileValueClass->GetName() ) )
02414          {
02415             TBranchElement* bEl = (TBranchElement*)branch;
02416             bEl->SetTargetClass( ptrClass->GetName() );
02417             return kMatchConversionCollection;
02418          }
02419       }
02420 
02421       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());
02422       return kClassMismatch;
02423 
02424    } else if ((expectedType != kOther_t) && (datatype != kOther_t) && (expectedType != kNoType_t) && (datatype != kNoType_t) && (expectedType != datatype)) {
02425       if (datatype != kChar_t) {
02426          // For backward compatibility we assume that (char*) was just a cast and/or a generic address
02427          Error("SetBranchAddress", "The pointer type given \"%s\" (%d) does not correspond to the type needed \"%s\" (%d) by the branch: %s", TDataType::GetTypeName(datatype), datatype, TDataType::GetTypeName(expectedType), expectedType, branch->GetName());
02428          return kMismatch;
02429       }
02430    }
02431    if (expectedClass && expectedClass->GetCollectionProxy() && dynamic_cast<TEmulatedCollectionProxy*>(expectedClass->GetCollectionProxy())) {
02432       Error("SetBranchAddress", "The class requested (%s) for the branch \"%s\" refer to an stl collection and do not have a compiled CollectionProxy.  "
02433             "Please generate the dictionary for this class (%s)",
02434             expectedClass->GetName(), branch->GetName(), expectedClass->GetName());
02435       return kMissingCompiledCollectionProxy;
02436    }
02437    return kMatch;
02438 }
02439 
02440 //______________________________________________________________________________
02441 TTree* TTree::CloneTree(Long64_t nentries /* = -1 */, Option_t* option /* = "" */)
02442 {
02443    // Create a clone of this tree and copy nentries.
02444    //
02445    // By default copy all entries.
02446    // Note that only active branches are copied.
02447    // The compression level of the cloned tree is set to the destination file's
02448    // compression level.
02449    //
02450    // IMPORTANT: The cloned tree stays connected with this tree until this tree
02451    //            is deleted.  In particular, any changes in branch addresses
02452    //            in this tree are forwarded to the clone trees, unless a branch
02453    //            in a clone tree has had its address changed, in which case
02454    //            that change stays in effect.  When this tree is deleted, all the
02455    //            addresses of the cloned tree are reset to their default values.
02456    //
02457    // If 'option' contains the word 'fast' and nentries is -1, the cloning will be
02458    // done without unzipping or unstreaming the baskets (i.e., a direct copy of the
02459    // raw bytes on disk).
02460    //
02461    // When 'fast' is specified, 'option' can also contains a
02462    // sorting order for the baskets in the output file.
02463    //
02464    // There are currently 3 supported sorting order:
02465    //    SortBasketsByOffset (the default)
02466    //    SortBasketsByBranch
02467    //    SortBasketsByEntry
02468    //
02469    // When using SortBasketsByOffset the baskets are written in
02470    // the output file in the same order as in the original file
02471    // (i.e. the basket are sorted on their offset in the original
02472    // file; Usually this also means that the baskets are sorted
02473    // on the index/number of the _last_ entry they contain)
02474    //
02475    // When using SortBasketsByBranch all the baskets of each
02476    // individual branches are stored contiguously.  This tends to
02477    // optimize reading speed when reading a small number (1->5) of
02478    // branches, since all their baskets will be clustered together
02479    // instead of being spread across the file.  However it might
02480    // decrease the performance when reading more branches (or the full
02481    // entry).
02482    //
02483    // When using SortBasketsByEntry the baskets with the lowest
02484    // starting entry are written first.  (i.e. the baskets are
02485    // sorted on the index/number of the first entry they contain).
02486    // This means that on the file the baskets will be in the order
02487    // in which they will be needed when reading the whole tree
02488    // sequentially.
02489    //
02490    // For examples of CloneTree, see tutorials:
02491    //
02492    //  -- copytree
02493    //
02494    //     A macro to copy a subset of a TTree to a new TTree.
02495    //
02496    //     The input file has been generated by the program in $ROOTSYS/test/Event
02497    //     with:  Event 1000 1 1 1
02498    //
02499    //  -- copytree2
02500    //
02501    //     A macro to copy a subset of a TTree to a new TTree.
02502    //
02503    //     One branch of the new Tree is written to a separate file.
02504    //
02505    //     The input file has been generated by the program in $ROOTSYS/test/Event
02506    //     with:  Event 1000 1 1 1
02507    //
02508 
02509    // Options
02510    Bool_t fastClone = kFALSE;
02511 
02512    TString opt = option;
02513    opt.ToLower();
02514    if (opt.Contains("fast")) {
02515       fastClone = kTRUE;
02516    }
02517 
02518    // If we are a chain, switch to the first tree.
02519    if ((fEntries > 0) && (LoadTree(0) < 0)) {
02520          // FIXME: We need an error message here.
02521          return 0;
02522    }
02523 
02524    // Note: For a tree we get the this pointer, for
02525    //       a chain we get the chain's current tree.
02526    TTree* thistree = GetTree();
02527 
02528    // Note: For a chain, the returned clone will be
02529    //       a clone of the chain's first tree.
02530    TTree* newtree = (TTree*) thistree->Clone();
02531    if (!newtree) {
02532       return 0;
02533    }
02534 
02535    // The clone should not delete any objects allocated by SetAddress().
02536    TObjArray* branches = newtree->GetListOfBranches();
02537    Int_t nb = branches->GetEntriesFast();
02538    for (Int_t i = 0; i < nb; ++i) {
02539       TBranch* br = (TBranch*) branches->UncheckedAt(i);
02540       if (br->InheritsFrom(TBranchElement::Class())) {
02541          ((TBranchElement*) br)->ResetDeleteObject();
02542       }
02543    }
02544 
02545    // Add the new tree to the list of clones so that
02546    // we can later inform it of changes to branch addresses.
02547    thistree->AddClone(newtree);
02548 
02549    newtree->Reset();
02550 
02551    TDirectory* ndir = newtree->GetDirectory();
02552    TFile* nfile = 0;
02553    if (ndir) {
02554       nfile = ndir->GetFile();
02555    }
02556    Int_t newcomp = -1;
02557    if (nfile) {
02558       newcomp = nfile->GetCompressionLevel();
02559    }
02560 
02561    //
02562    // Delete non-active branches from the clone.
02563    //
02564    // Note: If we are a chain, this does nothing
02565    //       since chains have no leaves.
02566    TObjArray* leaves = newtree->GetListOfLeaves();
02567    Int_t nleaves = leaves->GetEntriesFast();
02568    for (Int_t lndx = 0; lndx < nleaves; ++lndx) {
02569       TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(lndx);
02570       if (!leaf) {
02571          continue;
02572       }
02573       TBranch* branch = leaf->GetBranch();
02574       if (branch && (newcomp > -1)) {
02575          branch->SetCompressionLevel(newcomp);
02576       }
02577       if (!branch || !branch->TestBit(kDoNotProcess)) {
02578          continue;
02579       }
02580 //      TObjArray* branches = newtree->GetListOfBranches();
02581 //      Int_t nb = branches->GetEntriesFast();
02582       for (Long64_t i = 0; i < nb; ++i) {
02583          TBranch* br = (TBranch*) branches->UncheckedAt(i);
02584          if (br == branch) {
02585             branches->RemoveAt(i);
02586             delete br;
02587             br = 0;
02588             branches->Compress();
02589             break;
02590          }
02591          TObjArray* lb = br->GetListOfBranches();
02592          Int_t nb1 = lb->GetEntriesFast();
02593          for (Int_t j = 0; j < nb1; ++j) {
02594             TBranch* b1 = (TBranch*) lb->UncheckedAt(j);
02595             if (!b1) {
02596                continue;
02597             }
02598             if (b1 == branch) {
02599                lb->RemoveAt(j);
02600                delete b1;
02601                b1 = 0;
02602                lb->Compress();
02603                break;
02604             }
02605             TObjArray* lb1 = b1->GetListOfBranches();
02606             Int_t nb2 = lb1->GetEntriesFast();
02607             for (Int_t k = 0; k < nb2; ++k) {
02608                TBranch* b2 = (TBranch*) lb1->UncheckedAt(k);
02609                if (!b2) {
02610                   continue;
02611                }
02612                if (b2 == branch) {
02613                   lb1->RemoveAt(k);
02614                   delete b2;
02615                   b2 = 0;
02616                   lb1->Compress();
02617                   break;
02618                }
02619             }
02620          }
02621       }
02622    }
02623    leaves->Compress();
02624 
02625    // Copy MakeClass status.
02626    newtree->SetMakeClass(fMakeClass);
02627 
02628    // Copy branch addresses.
02629    CopyAddresses(newtree);
02630 
02631    //
02632    // Copy entries if requested.
02633    //
02634 
02635    if (nentries != 0) {
02636       if (fastClone && (nentries < 0)) {
02637          if ( newtree->CopyEntries( this, -1, option ) < 0 ) {
02638             // There was a problem!
02639             Error("Merge", "TTree has not been cloned\n");
02640             delete newtree;
02641             newtree = 0;
02642             return 0;
02643          }
02644       } else {
02645          newtree->CopyEntries( this, nentries, option );
02646       }
02647    }
02648 
02649    return newtree;
02650 }
02651 
02652 //______________________________________________________________________________
02653 void TTree::CopyAddresses(TTree* tree, Bool_t undo)
02654 {
02655    // Set branch addresses of passed tree equal to ours.
02656    // If undo is true, reset the branch address instead of copying them.
02657    //    This insures 'separation' of a cloned tree from its original
02658 
02659    // Copy branch addresses starting from branches.
02660    TObjArray* branches = GetListOfBranches();
02661    Int_t nbranches = branches->GetEntriesFast();
02662    for (Int_t i = 0; i < nbranches; ++i) {
02663       TBranch* branch = (TBranch*) branches->UncheckedAt(i);
02664       if (branch->TestBit(kDoNotProcess)) {
02665          continue;
02666       }
02667       if (undo) {
02668          TBranch* br = tree->GetBranch(branch->GetName());
02669          tree->ResetBranchAddress(br);
02670       } else {
02671          char* addr = branch->GetAddress();
02672          if (!addr) {
02673             if (branch->IsA() == TBranch::Class()) {
02674                // If the branch was created using a leaflist, the branch itself may not have 
02675                // an address but the leat might already do.
02676                TLeaf *firstleaf = (TLeaf*)branch->GetListOfLeaves()->At(0);
02677                if (!firstleaf || firstleaf->GetValuePointer()) {
02678                   // Either there is no leaf (and thus no point in copying the address)
02679                   // or the leaf has an address but we can not copy it via the branche
02680                   // this will be copied via the the next loop (over the leaf).
02681                   continue;
02682                }
02683             } 
02684             // Note: This may cause an object to be allocated.
02685             branch->SetAddress(0);
02686             addr = branch->GetAddress();
02687          }
02688          // FIXME: The GetBranch() function is braindead and may
02689          //        not find the branch!
02690          TBranch* br = tree->GetBranch(branch->GetName());
02691          if (br) {
02692             br->SetAddress(addr);
02693             // The copy does not own any object allocated by SetAddress().
02694             if (br->InheritsFrom(TBranchElement::Class())) {
02695                ((TBranchElement*) br)->ResetDeleteObject();
02696             }
02697          } else {
02698             Warning("CopyAddresses", "Could not find branch named '%s' in tree named '%s'", branch->GetName(), tree->GetName());
02699          }
02700       }
02701    }
02702 
02703    // Copy branch addresses starting from leaves.
02704    TObjArray* tleaves = tree->GetListOfLeaves();
02705    Int_t ntleaves = tleaves->GetEntriesFast();
02706    for (Int_t i = 0; i < ntleaves; ++i) {
02707       TLeaf* tleaf = (TLeaf*) tleaves->UncheckedAt(i);
02708       TBranch* tbranch = tleaf->GetBranch();
02709       TBranch* branch = GetBranch(tbranch->GetName());
02710       if (!branch) {
02711          continue;
02712       }
02713       TLeaf* leaf = branch->GetLeaf(tleaf->GetName());
02714       if (!leaf) {
02715          continue;
02716       }
02717       if (branch->TestBit(kDoNotProcess)) {
02718          continue;
02719       }
02720       if (undo) {
02721          // Now we know wether the address has been transfered
02722          tree->ResetBranchAddress(tbranch);
02723       } else {
02724          if (!branch->GetAddress() && !leaf->GetValuePointer()) {
02725             // We should attempts to set the address of the branch.
02726             // something like:
02727             //(TBranchElement*)branch->GetMother()->SetAddress(0)
02728             //plus a few more subtilities (see TBranchElement::GetEntry).
02729             //but for now we go the simpliest route:
02730             //
02731             // Note: This may result in the allocation of an object.
02732             branch->SetupAddresses();
02733          }
02734          if (branch->GetAddress()) {
02735             tree->SetBranchAddress(branch->GetName(), (void*) branch->GetAddress());
02736             TBranch* br = tree->GetBranch(branch->GetName());
02737             if (br) {
02738                // The copy does not own any object allocated by SetAddress().
02739                // FIXME: We do too much here, br may not be a top-level branch.
02740                if (br->InheritsFrom(TBranchElement::Class())) {
02741                   ((TBranchElement*) br)->ResetDeleteObject();
02742                }
02743             } else {
02744                Warning("CopyAddresses", "Could not find branch named '%s' in tree named '%s'", branch->GetName(), tree->GetName());
02745             }
02746          } else {
02747             tleaf->SetAddress(leaf->GetValuePointer());
02748          }
02749       }
02750    }
02751 
02752    if (undo &&
02753        ( tree->IsA()->InheritsFrom("TNtuple") || tree->IsA()->InheritsFrom("TNtupleD") )
02754        ) {
02755       tree->ResetBranchAddresses();
02756    }
02757 }
02758 
02759 namespace {
02760 
02761    enum EOnIndexError { kDrop, kKeep, kBuild };
02762 
02763    static bool R__HandleIndex(EOnIndexError onIndexError, TTree *newtree, TTree *oldtree)
02764    {
02765       // Return true if we should continue to handle indices, false otherwise.
02766 
02767       bool withIndex = kTRUE;
02768 
02769       if ( newtree->GetTreeIndex() ) {
02770          if ( oldtree->GetTree()->GetTreeIndex() == 0 ) {
02771             switch (onIndexError) {
02772                case kDrop:
02773                   delete newtree->GetTreeIndex();
02774                   newtree->SetTreeIndex(0);
02775                   withIndex = kFALSE;
02776                   break;
02777                case kKeep:
02778                   // Nothing to do really.
02779                   break;
02780                case kBuild:
02781                   // Build the index then copy it
02782                   oldtree->GetTree()->BuildIndex(newtree->GetTreeIndex()->GetMajorName(), newtree->GetTreeIndex()->GetMinorName());
02783                   newtree->GetTreeIndex()->Append(oldtree->GetTree()->GetTreeIndex(), kTRUE);
02784                   // Clean up
02785                   delete oldtree->GetTree()->GetTreeIndex();
02786                   oldtree->GetTree()->SetTreeIndex(0);
02787                   break;
02788             }
02789          } else {
02790             newtree->GetTreeIndex()->Append(oldtree->GetTree()->GetTreeIndex(), kTRUE);
02791          }
02792       } else if ( oldtree->GetTree()->GetTreeIndex() != 0 ) {
02793          // We discover the first index in the middle of the chain.
02794          switch (onIndexError) {
02795             case kDrop:
02796                // Nothing to do really.
02797                break;
02798             case kKeep: {
02799                TVirtualIndex *index = (TVirtualIndex*) oldtree->GetTree()->GetTreeIndex()->Clone();
02800                index->SetTree(newtree);
02801                newtree->SetTreeIndex(index);
02802                break;
02803             }
02804             case kBuild:
02805                if (newtree->GetEntries() == 0) {
02806                   // Start an index.
02807                   TVirtualIndex *index = (TVirtualIndex*) oldtree->GetTree()->GetTreeIndex()->Clone();
02808                   index->SetTree(newtree);
02809                   newtree->SetTreeIndex(index);
02810                } else {
02811                   // Build the index so far.
02812                   newtree->BuildIndex(oldtree->GetTree()->GetTreeIndex()->GetMajorName(), oldtree->GetTree()->GetTreeIndex()->GetMinorName());
02813                   newtree->GetTreeIndex()->Append(oldtree->GetTree()->GetTreeIndex(), kTRUE);
02814                }
02815                break;
02816          }
02817       } else if ( onIndexError == kDrop ) {
02818          // There is no index on this or on tree->GetTree(), we know we have to ignore any further
02819          // index
02820          withIndex = kFALSE;
02821       }
02822       return withIndex;
02823    }
02824 }
02825 
02826 //______________________________________________________________________________
02827 Long64_t TTree::CopyEntries(TTree* tree, Long64_t nentries /* = -1 */, Option_t* option /* = "" */)
02828 {
02829    // Copy nentries from given tree to this tree.
02830    // This routines assumes that the branches that intended to be copied are
02831    // already connected.   The typical case is that this tree was created using
02832    // tree->CloneTree(0).
02833    //
02834    // By default copy all entries.
02835    //
02836    // Returns number of bytes copied to this tree.
02837    //
02838    // If 'option' contains the word 'fast' and nentries is -1, the cloning will be
02839    // done without unzipping or unstreaming the baskets (i.e., a direct copy of the
02840    // raw bytes on disk).
02841    //
02842    // When 'fast' is specified, 'option' can also contains a sorting order for the
02843    // baskets in the output file.
02844    //
02845    // There are currently 3 supported sorting order:
02846    //    SortBasketsByOffset (the default)
02847    //    SortBasketsByBranch
02848    //    SortBasketsByEntry
02849    //
02850    // See TTree::CloneTree for a detailed explanation of the semantics of these 3 options.
02851    //
02852    // If the tree or any of the underlying tree of the chain has an index, that index and any
02853    // index in the subsequent underlying TTree objects will be merged.
02854    //
02855    // There are currently three 'options' to control this merging:
02856    //    NoIndex             : all the TTreeIndex object are dropped.
02857    //    DropIndexOnError    : if any of the underlying TTree object do no have a TTreeIndex,
02858    //                          they are all dropped.
02859    //    AsIsIndexOnError [default]: In case of missing TTreeIndex, the resulting TTree index has gaps.
02860    //    BuildIndexOnError : If any of the underlying TTree object do no have a TTreeIndex,
02861    //                          all TTreeIndex are 'ignored' and the mising piece are rebuilt.
02862 
02863    if (!tree) {
02864       return 0;
02865    }
02866    // Options
02867    TString opt = option;
02868    opt.ToLower();
02869    Bool_t fastClone = opt.Contains("fast");
02870    Bool_t withIndex = !opt.Contains("noindex");
02871    EOnIndexError onIndexError;
02872    if (opt.Contains("asisindex")) {
02873       onIndexError = kKeep;
02874    } else if (opt.Contains("buildindex")) {
02875       onIndexError = kBuild;
02876    } else if (opt.Contains("dropindex")) {
02877       onIndexError = kDrop;
02878    } else {
02879       onIndexError = kBuild;
02880    }
02881 
02882    Long64_t nbytes = 0;
02883    Long64_t treeEntries = tree->GetEntriesFast();
02884    if (nentries < 0) {
02885       nentries = treeEntries;
02886    } else if (nentries > treeEntries) {
02887       nentries = treeEntries;
02888    }
02889 
02890    if (fastClone && (nentries < 0 || nentries == tree->GetEntriesFast())) {
02891       // Quickly copy the basket without decompression and streaming.
02892       Long64_t totbytes = GetTotBytes();
02893       for (Long64_t i = 0; i < nentries; i += tree->GetTree()->GetEntries()) {
02894          if (tree->LoadTree(i) < 0) {
02895             break;
02896          }
02897          if ( withIndex ) {
02898             withIndex = R__HandleIndex( onIndexError, this, tree );
02899          }
02900          if (this->GetDirectory()) {
02901             TFile* file2 = this->GetDirectory()->GetFile();
02902             if (file2 && (file2->GetEND() > TTree::GetMaxTreeSize())) {
02903                if (this->GetDirectory() == (TDirectory*) file2) {
02904                   this->ChangeFile(file2);
02905                }
02906             }
02907          }
02908          TTreeCloner cloner(tree->GetTree(), this, option, TTreeCloner::kNoWarnings);
02909          if (cloner.IsValid()) {
02910             this->SetEntries(this->GetEntries() + tree->GetTree()->GetEntries());
02911             cloner.Exec();
02912          } else {
02913             if (i == 0) {
02914                // If the first cloning does not work, something is really wrong
02915                // (since apriori the source and target are exactly the same structure!)
02916                return -1;
02917             } else {
02918                if (cloner.NeedConversion()) {
02919                   TTree *localtree = tree->GetTree();
02920                   Long64_t tentries = localtree->GetEntries();
02921                   for (Long64_t ii = 0; ii < tentries; ii++) {
02922                      if (localtree->GetEntry(ii) <= 0) {
02923                         break;
02924                      }
02925                      this->Fill();
02926                   }
02927                   if (this->GetTreeIndex()) {
02928                      this->GetTreeIndex()->Append(tree->GetTree()->GetTreeIndex(), kTRUE);
02929                   }
02930                } else {
02931                   Warning("CopyEntries","%s",cloner.GetWarning());
02932                   if (tree->GetDirectory() && tree->GetDirectory()->GetFile()) {
02933                      Warning("CopyEntries", "Skipped file %s\n", tree->GetDirectory()->GetFile()->GetName());
02934                   } else {
02935                      Warning("CopyEntries", "Skipped file number %d\n", tree->GetTreeNumber());
02936                   }
02937                }
02938             }
02939          }
02940 
02941       }
02942       if (this->GetTreeIndex()) {
02943          this->GetTreeIndex()->Append(0,kFALSE); // Force the sorting
02944       }
02945       nbytes = GetTotBytes() - totbytes;
02946    } else {
02947       if (nentries < 0) {
02948          nentries = treeEntries;
02949       } else if (nentries > treeEntries) {
02950          nentries = treeEntries;
02951       }
02952       Int_t treenumber = -1;
02953       for (Long64_t i = 0; i < nentries; i++) {
02954          if (tree->LoadTree(i) < 0) {
02955             break;
02956          }
02957          if (treenumber != tree->GetTreeNumber()) {
02958             if ( withIndex ) {
02959                withIndex = R__HandleIndex( onIndexError, this, tree );
02960             }
02961             treenumber = tree->GetTreeNumber();
02962          }
02963          if (tree->GetEntry(i) <= 0) {
02964             break;
02965          }
02966          nbytes += this->Fill();
02967       }
02968       if (this->GetTreeIndex()) {
02969          this->GetTreeIndex()->Append(0,kFALSE); // Force the sorting
02970       }
02971    }
02972    return nbytes;
02973 }
02974 
02975 //______________________________________________________________________________
02976 TTree* TTree::CopyTree(const char* selection, Option_t* option /* = 0 */, Long64_t nentries /* = 1000000000 */, Long64_t firstentry /* = 0 */)
02977 {
02978    // Copy a tree with selection.
02979    //
02980    // IMPORTANT:
02981    //
02982    //   The returned copied tree stays connected with the original tree
02983    //   until the original tree is deleted.  In particular, any changes
02984    //   to the branch addresses in the original tree are also made to
02985    //   the copied tree.  Any changes made to the branch addresses of the
02986    //   copied tree are overridden anytime the original tree changes its
02987    //   branch addresses.  When the original tree is deleted, all the
02988    //   branch addresses of the copied tree are set to zero.
02989    //
02990    // For examples of CopyTree, see the tutorials:
02991    //
02992    // copytree
02993    //
02994    // Example macro to copy a subset of a tree to a new tree.
02995    //
02996    // The input file was generated by running the program in
02997    // $ROOTSYS/test/Event in this way:
02998    //
02999    //      ./Event 1000 1 1 1
03000    //
03001    // copytree2
03002    //
03003    // Example macro to copy a subset of a tree to a new tree.
03004    //
03005    // One branch of the new tree is written to a separate file.
03006    //
03007    // The input file was generated by running the program in
03008    // $ROOTSYS/test/Event in this way:
03009    //
03010    //      ./Event 1000 1 1 1
03011    //
03012    // copytree3
03013    //
03014    // Example macro to copy a subset of a tree to a new tree.
03015    //
03016    // Only selected entries are copied to the new tree.
03017    // NOTE that only the active branches are copied.
03018    //
03019 
03020    GetPlayer();
03021    if (fPlayer) {
03022       return fPlayer->CopyTree(selection, option, nentries, firstentry);
03023    }
03024    return 0;
03025 }
03026 
03027 //______________________________________________________________________________
03028 TBasket* TTree::CreateBasket(TBranch* branch)
03029 {
03030    // Create a basket for this tree and given branch.
03031    if (!branch) {
03032       return 0;
03033    }
03034    return new TBasket(branch->GetName(), GetName(), branch);
03035 }
03036 
03037 //______________________________________________________________________________
03038 void TTree::Delete(Option_t* option /* = "" */)
03039 {
03040    // Delete this tree from memory or/and disk.
03041    //
03042    //  if option == "all" delete Tree object from memory AND from disk
03043    //                     all baskets on disk are deleted. All keys with same name
03044    //                     are deleted.
03045    //  if option =="" only Tree object in memory is deleted.
03046 
03047    TFile *file = GetCurrentFile();
03048 
03049    // delete all baskets and header from file
03050    if (file && !strcmp(option,"all")) {
03051       if (!file->IsWritable()) {
03052          Error("Delete","File : %s is not writable, cannot delete Tree:%s", file->GetName(),GetName());
03053          return;
03054       }
03055 
03056       //find key and import Tree header in memory
03057       TKey *key = fDirectory->GetKey(GetName());
03058       if (!key) return;
03059 
03060       TDirectory *dirsav = gDirectory;
03061       file->cd();
03062 
03063       //get list of leaves and loop on all the branches baskets
03064       TIter next(GetListOfLeaves());
03065       TLeaf *leaf;
03066       char header[16];
03067       Int_t ntot  = 0;
03068       Int_t nbask = 0;
03069       Int_t nbytes,objlen,keylen;
03070       while ((leaf = (TLeaf*)next())) {
03071          TBranch *branch = leaf->GetBranch();
03072          Int_t nbaskets = branch->GetMaxBaskets();
03073          for (Int_t i=0;i<nbaskets;i++) {
03074             Long64_t pos = branch->GetBasketSeek(i);
03075             if (!pos) continue;
03076             TFile *branchFile = branch->GetFile();
03077             if (!branchFile) continue;
03078             branchFile->GetRecordHeader(header,pos,16,nbytes,objlen,keylen);
03079             if (nbytes <= 0) continue;
03080             branchFile->MakeFree(pos,pos+nbytes-1);
03081             ntot += nbytes;
03082             nbask++;
03083          }
03084       }
03085 
03086       // delete Tree header key and all keys with the same name
03087       // A Tree may have been saved many times. Previous cycles are invalid.
03088       while (key) {
03089          ntot += key->GetNbytes();
03090          key->Delete();
03091          delete key;
03092          key = fDirectory->GetKey(GetName());
03093       }
03094       if (dirsav) dirsav->cd();
03095       if (gDebug) printf(" Deleting Tree: %s: %d baskets deleted. Total space freed = %d bytes\n",GetName(),nbask,ntot);
03096    }
03097 
03098    if (fDirectory) {
03099       fDirectory->Remove(this);
03100       fDirectory = 0;
03101       ResetBit(kMustCleanup);
03102    }
03103 
03104     // Delete object from CINT symbol table so it can not be used anymore.
03105    gCint->DeleteGlobal(this);
03106 
03107    // Warning: We have intentional invalidated this object while inside a member function!
03108    delete this;
03109 }
03110 
03111  //______________________________________________________________________________
03112 void TTree::DirectoryAutoAdd(TDirectory* dir)
03113 {
03114    // Called by TKey and TObject::Clone to automatically add us to a directory
03115    // when we are read from a file.
03116 
03117    if (fDirectory == dir) return;
03118    if (fDirectory) fDirectory->Remove(this);
03119    fDirectory = dir;
03120    TBranch* b = 0;
03121    TIter next(GetListOfBranches());
03122    while((b = (TBranch*) next())) {
03123       b->UpdateFile();
03124    }
03125    if (fBranchRef) {
03126       fBranchRef->UpdateFile();
03127    }
03128    if (fDirectory) fDirectory->Append(this);
03129 }
03130 
03131 //______________________________________________________________________________
03132 Long64_t TTree::Draw(const char* varexp, const TCut& selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
03133 {
03134    // Draw expression varexp for specified entries.
03135    // Returns -1 in case of error or number of selected events in case of success.
03136    //
03137    //      This function accepts TCut objects as arguments.
03138    //      Useful to use the string operator +
03139    //         example:
03140    //            ntuple.Draw("x",cut1+cut2+cut3);
03141    //
03142 
03143    return TTree::Draw(varexp, selection.GetTitle(), option, nentries, firstentry);
03144 }
03145 
03146 //______________________________________________________________________________
03147 Long64_t TTree::Draw(const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
03148 {
03149    // Draw expression varexp for specified entries.
03150    // Returns -1 in case of error or number of selected events in case of success.
03151    //
03152    //  varexp is an expression of the general form
03153    //   - "e1"           produces a 1-d histogram (TH1F) of expression "e1"
03154    //   - "e1:e2"        produces an unbinned 2-d scatter-plot (TGraph) of "e1" versus "e2"
03155    //   - "e1:e2:e3"     produces an unbinned 3-d scatter-plot (TPolyMarker3D) of "e1"
03156    //                    versus "e2" versus "e3"
03157    //   - "e1:e2:e3:e4"  produces an unbinned 3-d scatter-plot (TPolyMarker3D) of "e1"
03158    //                    versus "e2" versus "e3" and "e4" mapped on the color number.
03159    //  (to create histograms in the 2, 3, and 4 dimesional case, see section "Saving
03160    //  the result of Draw to an histogram")
03161    //
03162    //  Example:
03163    //     varexp = x     simplest case: draw a 1-Dim distribution of column named x
03164    //            = sqrt(x)            : draw distribution of sqrt(x)
03165    //            = x*y/z
03166    //            = y:sqrt(x) 2-Dim distribution of y versus sqrt(x)
03167    //            = px:py:pz:2.5*E  produces a 3-d scatter-plot of px vs py ps pz
03168    //              and the color number of each marker will be 2.5*E.
03169    //              If the color number is negative it is set to 0.
03170    //              If the color number is greater than the current number of colors
03171    //                 it is set to the highest color number.
03172    //              The default number of colors is 50.
03173    //              see TStyle::SetPalette for setting a new color palette.
03174    //
03175    //  Note that the variables e1, e2 or e3 may contain a selection.
03176    //  example, if e1= x*(y<0), the value histogrammed will be x if y<0
03177    //  and will be 0 otherwise.
03178    //
03179    //  The expressions can use all the operations and build-in functions
03180    //  supported by TFormula (See TFormula::Analyze), including free
03181    //  standing function taking numerical arguments (TMath::Bessel).
03182    //  In addition, you can call member functions taking numerical
03183    //  arguments. For example:
03184    //      - "TMath::BreitWigner(fPx,3,2)"
03185    //      - "event.GetHistogram().GetXaxis().GetXmax()"
03186    //  Note: You can only pass expression that depend on the TTree's data
03187    //  to static functions and you can only call non-static member function
03188    //  with 'fixed' parameters.
03189    //
03190    //  selection is an expression with a combination of the columns.
03191    //  In a selection all the C++ operators are authorized.
03192    //  The value corresponding to the selection expression is used as a weight
03193    //  to fill the histogram.
03194    //  If the expression includes only boolean operations, the result
03195    //  is 0 or 1. If the result is 0, the histogram is not filled.
03196    //  In general, the expression may be of the form:
03197    //      value*(boolean expression)
03198    //  if boolean expression is true, the histogram is filled with
03199    //  a weight = value.
03200    //  Examples:
03201    //      selection1 = "x<y && sqrt(z)>3.2"
03202    //      selection2 = "(x+y)*(sqrt(z)>3.2)"
03203    //  selection1 returns a weigth = 0 or 1
03204    //  selection2 returns a weight = x+y if sqrt(z)>3.2
03205    //             returns a weight = 0 otherwise.
03206    //
03207    //  option is the drawing option.
03208    //    - See TH1::Draw for the list of all drawing options.
03209    //    - If option COL is specified when varexp has three fields:
03210    //            tree.Draw("e1:e2:e3","","col");
03211    //      a 2D scatter is produced with e1 vs e2, and e3 is mapped on the color
03212    //      table.
03213    //    - If option contains the string "goff", no graphics is generated.
03214    //
03215    //  nentries is the number of entries to process (default is all)
03216    //  first is the first entry to process (default is 0)
03217    //
03218    //  This function returns the number of selected entries. It returns -1
03219    //  if an error occurs.
03220    //
03221    //     Drawing expressions using arrays and array elements
03222    //     ===================================================
03223    // Let assumes, a leaf fMatrix, on the branch fEvent, which is a 3 by 3 array,
03224    // or a TClonesArray.
03225    // In a TTree::Draw expression you can now access fMatrix using the following
03226    // syntaxes:
03227    //
03228    //   String passed    What is used for each entry of the tree
03229    //
03230    //   "fMatrix"       the 9 elements of fMatrix
03231    //   "fMatrix[][]"   the 9 elements of fMatrix
03232    //   "fMatrix[2][2]" only the elements fMatrix[2][2]
03233    //   "fMatrix[1]"    the 3 elements fMatrix[1][0], fMatrix[1][1] and fMatrix[1][2]
03234    //   "fMatrix[1][]"  the 3 elements fMatrix[1][0], fMatrix[1][1] and fMatrix[1][2]
03235    //   "fMatrix[][0]"  the 3 elements fMatrix[0][0], fMatrix[1][0] and fMatrix[2][0]
03236    //
03237    //   "fEvent.fMatrix...." same as "fMatrix..." (unless there is more than one leaf named fMatrix!).
03238    //
03239    // In summary, if a specific index is not specified for a dimension, TTree::Draw
03240    // will loop through all the indices along this dimension.  Leaving off the
03241    // last (right most) dimension of specifying then with the two characters '[]'
03242    // is equivalent.  For variable size arrays (and TClonesArray) the range
03243    // of the first dimension is recalculated for each entry of the tree.
03244    //
03245    // TTree::Draw also now properly handling operations involving 2 or more arrays.
03246    //
03247    // Let assume a second matrix fResults[5][2], here are a sample of some
03248    // of the possible combinations, the number of elements they produce and
03249    // the loop used:
03250    //
03251    //  expression                       element(s)  Loop
03252    //
03253    //  "fMatrix[2][1] - fResults[5][2]"   one     no loop
03254    //  "fMatrix[2][]  - fResults[5][2]"   three   on 2nd dim fMatrix
03255    //  "fMatrix[2][]  - fResults[5][]"    two     on both 2nd dimensions
03256    //  "fMatrix[][2]  - fResults[][1]"    three   on both 1st dimensions
03257    //  "fMatrix[][2]  - fResults[][]"     six     on both 1st and 2nd dimensions of
03258    //                                             fResults
03259    //  "fMatrix[][2]  - fResults[3][]"    two     on 1st dim of fMatrix and 2nd of
03260    //                                             fResults (at the same time)
03261    //  "fMatrix[][]   - fResults[][]"     six     on 1st dim then on  2nd dim
03262    //
03263    //
03264    // In summary, TTree::Draw loops through all un-specified dimensions.  To
03265    // figure out the range of each loop, we match each unspecified dimension
03266    // from left to right (ignoring ALL dimensions for which an index has been
03267    // specified), in the equivalent loop matched dimensions use the same index
03268    // and are restricted to the smallest range (of only the matched dimensions).
03269    // When involving variable arrays, the range can of course be different
03270    // for each entry of the tree.
03271    //
03272    // So the loop equivalent to "fMatrix[][2] - fResults[3][]" is:
03273    //
03274    //    for (Int_t i0; i < min(3,2); i++) {
03275    //       use the value of (fMatrix[i0][2] - fMatrix[3][i0])
03276    //    }
03277    //
03278    // So the loop equivalent to "fMatrix[][2] - fResults[][]" is:
03279    //
03280    //    for (Int_t i0; i < min(3,5); i++) {
03281    //       for (Int_t i1; i1 < 2; i1++) {
03282    //          use the value of (fMatrix[i0][2] - fMatrix[i0][i1])
03283    //       }
03284    //    }
03285    //
03286    // So the loop equivalent to "fMatrix[][] - fResults[][]" is:
03287    //
03288    //    for (Int_t i0; i < min(3,5); i++) {
03289    //       for (Int_t i1; i1 < min(3,2); i1++) {
03290    //          use the value of (fMatrix[i0][i1] - fMatrix[i0][i1])
03291    //       }
03292    //    }
03293    //
03294    //     Retrieving the result of Draw
03295    //     =============================
03296    //
03297    //  By default the temporary histogram created is called "htemp", but only in
03298    //  the one dimensional Draw("e1") it contains the TTree's data points. For
03299    //  a two dimensional Draw, the data is filled into a TGraph which is named
03300    //  "Graph". They can be retrieved by calling
03301    //    TH1F *htemp = (TH1F*)gPad->GetPrimitive("htemp"); // 1D
03302    //    TGraph *graph = (TGraph*)gPad->GetPrimitive("Graph"); // 2D
03303    //
03304    //  For a three and four dimensional Draw the TPloyMarker3D is unnamed, and
03305    //  cannot be retrieved.
03306    //
03307    //  gPad always contains a TH1 derived object called "htemp" which allows to
03308    //  access the axes:
03309    //    TGraph *graph = (TGraph*)gPad->GetPrimitive("Graph"); // 2D
03310    //    TH2F   *htemp = (TH2F*)gPad->GetPrimitive("htemp"); // empty, but has axes
03311    //    TAxis  *xaxis = htemp->GetXaxis();
03312    //
03313    //     Saving the result of Draw to an histogram
03314    //     =========================================
03315    //
03316    //  If varexp0 contains >>hnew (following the variable(s) name(s),
03317    //  the new histogram created is called hnew and it is kept in the current
03318    //  directory (and also the current pad). This works for all dimensions.
03319    //  Example:
03320    //    tree.Draw("sqrt(x)>>hsqrt","y>0")
03321    //    will draw sqrt(x) and save the histogram as "hsqrt" in the current
03322    //    directory.  To retrieve it do:
03323    //    TH1F *hsqrt = (TH1F*)gDirectory->Get("hsqrt");
03324    //
03325    //  The binning information is taken from the environment variables
03326    //
03327    //     Hist.Binning.?D.?
03328    //
03329    //  In addition, the name of the histogram can be followed by up to 9
03330    //  numbers between '(' and ')', where the numbers describe the
03331    //  following:
03332    //
03333    //   1 - bins in x-direction
03334    //   2 - lower limit in x-direction
03335    //   3 - upper limit in x-direction
03336    //   4-6 same for y-direction
03337    //   7-9 same for z-direction
03338    //
03339    //   When a new binning is used the new value will become the default.
03340    //   Values can be skipped.
03341    //  Example:
03342    //    tree.Draw("sqrt(x)>>hsqrt(500,10,20)")
03343    //          // plot sqrt(x) between 10 and 20 using 500 bins
03344    //    tree.Draw("sqrt(x):sin(y)>>hsqrt(100,10,60,50,.1,.5)")
03345    //          // plot sqrt(x) against sin(y)
03346    //          // 100 bins in x-direction; lower limit on x-axis is 10; upper limit is 60
03347    //          //  50 bins in y-direction; lower limit on y-axis is .1; upper limit is .5
03348    //
03349    //  By default, the specified histogram is reset.
03350    //  To continue to append data to an existing histogram, use "+" in front
03351    //  of the histogram name.
03352    //  A '+' in front of the histogram name is ignored, when the name is followed by
03353    //  binning information as described in the previous paragraph.
03354    //    tree.Draw("sqrt(x)>>+hsqrt","y>0")
03355    //      will not reset hsqrt, but will continue filling.
03356    //  This works for 1-D, 2-D and 3-D histograms.
03357    //
03358    //     Accessing collection objects
03359    //     ============================
03360    //
03361    //  TTree::Draw default's handling of collections is to assume that any
03362    //  request on a collection pertain to it content.  For example, if fTracks
03363    //  is a collection of Track objects, the following:
03364    //      tree->Draw("event.fTracks.fPx");
03365    //  will plot the value of fPx for each Track objects inside the collection.
03366    //  Also
03367    //     tree->Draw("event.fTracks.size()");
03368    //  would plot the result of the member function Track::size() for each
03369    //  Track object inside the collection.
03370    //  To access information about the collection itself, TTree::Draw support
03371    //  the '@' notation.  If a variable which points to a collection is prefixed
03372    //  or postfixed with '@', the next part of the expression will pertain to
03373    //  the collection object.  For example:
03374    //     tree->Draw("event.@fTracks.size()");
03375    //  will plot the size of the collection refered to by fTracks (i.e the number
03376    //  of Track objects).
03377    //
03378    //     Drawing 'objects'
03379    //     =================
03380    //
03381    //  When a class has a member function named AsDouble or AsString, requesting
03382    //  to directly draw the object will imply a call to one of the 2 functions.
03383    //  If both AsDouble and AsString are present, AsDouble will be used.
03384    //  AsString can return either a char*, a std::string or a TString.s
03385    //  For example, the following
03386    //     tree->Draw("event.myTTimeStamp");
03387    //  will draw the same histogram as
03388    //     tree->Draw("event.myTTimeStamp.AsDouble()");
03389    //  In addition, when the object is a type TString or std::string, TTree::Draw
03390    //  will call respectively TString::Data and std::string::c_str()
03391    //
03392    //  If the object is a TBits, the histogram will contain the index of the bit
03393    //  that are turned on.
03394    //
03395    //     Retrieving  information about the tree itself.
03396    //     ============================================
03397    //
03398    //  You can refer to the tree (or chain) containing the data by using the
03399    //  string 'This'.
03400    //  You can then could any TTree methods.  For example:
03401    //     tree->Draw("This->GetReadEntry()");
03402    //  will display the local entry numbers be read.
03403    //     tree->Draw("This->GetUserInfo()->At(0)->GetName()");
03404    //  will display the name of the first 'user info' object.
03405    //
03406    //     Special functions and variables
03407    //     ===============================
03408    //
03409    //  Entry$:  A TTree::Draw formula can use the special variable Entry$
03410    //  to access the entry number being read.  For example to draw every
03411    //  other entry use:
03412    //    tree.Draw("myvar","Entry$%2==0");
03413    //
03414    //  Entry$      : return the current entry number (== TTree::GetReadEntry())
03415    //  LocalEntry$ : return the current entry number in the current tree of a
03416    //                chain (== GetTree()->GetReadEntry())
03417    //  Entries$    : return the total number of entries (== TTree::GetEntries())
03418    //  Length$     : return the total number of element of this formula for this
03419    //                 entry (==TTreeFormula::GetNdata())
03420    //  Iteration$: return the current iteration over this formula for this
03421    //                 entry (i.e. varies from 0 to Length$).
03422    //
03423    //  Length$(formula): return the total number of element of the formula given as a
03424    //                    parameter.
03425    //  Sum$(formula): return the sum of the value of the elements of the formula given
03426    //                    as a parameter.  For example the mean for all the elements in
03427    //                    one entry can be calculated with:
03428    //                Sum$(formula)/Length$(formula)
03429    //  Min$(formula): return the minimun (within one TTree entry) of the value of the
03430    //                    elements of the formula given as a parameter.
03431    //  Max$(formula): return the maximum (within one TTree entry) of the value of the
03432    //                    elements of the formula given as a parameter.
03433    //  MinIf$(formula,condition)
03434    //  MaxIf$(formula,condition): return the minimum (maximum) (within one TTree entry)
03435    //                    of the value of the elements of the formula given as a parameter
03436    //                    if they match the condition. If not element match the condition, the result is zero.  To avoid the
03437    //                    the result is zero.  To avoid the consequent peak a zero, use the
03438    //                    pattern:
03439    //    tree->Draw("MinIf$(formula,condition)","condition");
03440    //                    which will avoid calculation MinIf$ for the entries that have no match
03441    //                    for the condition.
03442    //
03443    //  Alt$(primary,alternate) : return the value of "primary" if it is available
03444    //                 for the current iteration otherwise return the value of "alternate".
03445    //                 For example, with arr1[3] and arr2[2]
03446    //    tree->Draw("arr1+Alt$(arr2,0)");
03447    //                 will draw arr1[0]+arr2[0] ; arr1[1]+arr2[1] and arr1[2]+0
03448    //                 Or with a variable size array arr3
03449    //    tree->Draw("Alt$(arr3[0],0)+Alt$(arr3[1],0)+Alt$(arr3[2],0)");
03450    //                 will draw the sum arr3 for the index 0 to min(2,actual_size_of_arr3-1)
03451    //                 As a comparison
03452    //    tree->Draw("arr3[0]+arr3[1]+arr3[2]");
03453    //                 will draw the sum arr3 for the index 0 to 2 only if the
03454    //                 actual_size_of_arr3 is greater or equal to 3.
03455    //                 Note that the array in 'primary' is flatened/linearilized thus using
03456    //                 Alt$ with multi-dimensional arrays of different dimensions in unlikely
03457    //                 to yield the expected results.  To visualize a bit more what elements
03458    //                 would be matched by TTree::Draw, TTree::Scan can be used:
03459    //    tree->Scan("arr1:Alt$(arr2,0)");
03460    //                 will print on one line the value of arr1 and (arr2,0) that will be
03461    //                 matched by
03462    //    tree->Draw("arr1-Alt$(arr2,0)");
03463    //
03464    //  The ternary operator is not directly support in TTree::Draw however, to plot the
03465    //  equivalent of 'var2<20 ? -99 : var1', you can use:
03466    //     tree->Draw("(var2<20)*99+(var2>=20)*var1","");
03467    //
03468    //     Drawing a user function accessing the TTree data directly
03469    //     =========================================================
03470    //
03471    //  If the formula contains  a file name, TTree::MakeProxy will be used
03472    //  to load and execute this file.   In particular it will draw the
03473    //  result of a function with the same name as the file.  The function
03474    //  will be executed in a context where the name of the branches can
03475    //  be used as a C++ variable.
03476    //
03477    //  For example draw px using the file hsimple.root (generated by the
03478    //  hsimple.C tutorial), we need a file named hsimple.cxx:
03479    //
03480    //     double hsimple() {
03481    //        return px;
03482    //     }
03483    //
03484    //  MakeProxy can then be used indirectly via the TTree::Draw interface
03485    //  as follow:
03486    //     new TFile("hsimple.root")
03487    //     ntuple->Draw("hsimple.cxx");
03488    //
03489    //  A more complete example is available in the tutorials directory:
03490    //    h1analysisProxy.cxx , h1analysProxy.h and h1analysisProxyCut.C
03491    //  which reimplement the selector found in h1analysis.C
03492    //
03493    //  The main features of this facility are:
03494    //
03495    //    * on-demand loading of branches
03496    //    * ability to use the 'branchname' as if it was a data member
03497    //    * protection against array out-of-bound
03498    //    * ability to use the branch data as object (when the user code is available)
03499    //
03500    //  See TTree::MakeProxy for more details.
03501    //
03502    //     Making a Profile histogram
03503    //     ==========================
03504    //  In case of a 2-Dim expression, one can generate a TProfile histogram
03505    //  instead of a TH2F histogram by specyfying option=prof or option=profs.
03506    //  The option=prof is automatically selected in case of y:x>>pf
03507    //  where pf is an existing TProfile histogram.
03508    //
03509    //     Making a 5D plot using GL
03510    //     =========================
03511    //  If option GL5D is specified together with 5 variables, a 5D plot is drawn
03512    //  using OpenGL. See $ROOTSYS/tutorials/tree/staff.C as example.
03513    //
03514    //     Making a parallel coordinates plot
03515    //     ==================================
03516    //  In case of a 2-Dim or more expression with the option=para, one can generate
03517    //  a parallel coordinates plot. With that option, the number of dimensions is
03518    //  arbitrary. Giving more than 4 variables without the option=para or
03519    //  option=candle or option=goff will produce an error.
03520    //
03521    //     Making a candle sticks chart
03522    //     ============================
03523    //  In case of a 2-Dim or more expression with the option=candle, one can generate
03524    //  a candle sticks chart. With that option, the number of dimensions is
03525    //  arbitrary. Giving more than 4 variables without the option=para or
03526    //  option=candle or option=goff will produce an error.
03527    //
03528    //     Saving the result of Draw to a TEventList or a TEntryList
03529    //     =========================================================
03530    //  TTree::Draw can be used to fill a TEventList object (list of entry numbers)
03531    //  instead of histogramming one variable.
03532    //  If varexp0 has the form >>elist , a TEventList object named "elist"
03533    //  is created in the current directory. elist will contain the list
03534    //  of entry numbers satisfying the current selection.
03535    //  If option "entrylist" is used, a TEntryList object is created
03536    //  Example:
03537    //    tree.Draw(">>yplus","y>0")
03538    //    will create a TEventList object named "yplus" in the current directory.
03539    //    In an interactive session, one can type (after TTree::Draw)
03540    //       yplus.Print("all")
03541    //    to print the list of entry numbers in the list.
03542    //    tree.Draw(">>yplus", "y>0", "entrylist")
03543    //    will create a TEntryList object names "yplus" in the current directory
03544    //
03545    //  By default, the specified entry list is reset.
03546    //  To continue to append data to an existing list, use "+" in front
03547    //  of the list name;
03548    //    tree.Draw(">>+yplus","y>0")
03549    //      will not reset yplus, but will enter the selected entries at the end
03550    //      of the existing list.
03551    //
03552    //      Using a TEventList or a TEntryList as Input
03553    //      ===========================
03554    //  Once a TEventList or a TEntryList object has been generated, it can be used as input
03555    //  for TTree::Draw. Use TTree::SetEventList or TTree::SetEntryList to set the
03556    //  current event list
03557    //  Example1:
03558    //     TEventList *elist = (TEventList*)gDirectory->Get("yplus");
03559    //     tree->SetEventList(elist);
03560    //     tree->Draw("py");
03561    //  Example2:
03562    //     TEntryList *elist = (TEntryList*)gDirectory->Get("yplus");
03563    //     tree->SetEntryList(elist);
03564    //     tree->Draw("py");
03565    //  If a TEventList object is used as input, a new TEntryList object is created
03566    //  inside the SetEventList function. In case of a TChain, all tree headers are loaded
03567    //  for this transformation. This new object is owned by the chain and is deleted
03568    //  with it, unless the user extracts it by calling GetEntryList() function.
03569    //  See also comments to SetEventList() function of TTree and TChain.
03570    //
03571    //  If arrays are used in the selection critera, the entry entered in the
03572    //  list are all the entries that have at least one element of the array that
03573    //  satisfy the selection.
03574    //  Example:
03575    //      tree.Draw(">>pyplus","fTracks.fPy>0");
03576    //      tree->SetEventList(pyplus);
03577    //      tree->Draw("fTracks.fPy");
03578    //  will draw the fPy of ALL tracks in event with at least one track with
03579    //  a positive fPy.
03580    //
03581    //  To select only the elements that did match the original selection
03582    //  use TEventList::SetReapplyCut or TEntryList::SetReapplyCut.
03583    //  Example:
03584    //      tree.Draw(">>pyplus","fTracks.fPy>0");
03585    //      pyplus->SetReapplyCut(kTRUE);
03586    //      tree->SetEventList(pyplus);
03587    //      tree->Draw("fTracks.fPy");
03588    //  will draw the fPy of only the tracks that have a positive fPy.
03589    //
03590    //  Note: Use tree->SetEventList(0) if you do not want use the list as input.
03591    //
03592    //      How to obtain more info from TTree::Draw
03593    //      ========================================
03594    //
03595    //  Once TTree::Draw has been called, it is possible to access useful
03596    //  information still stored in the TTree object via the following functions:
03597    //    -GetSelectedRows()    // return the number of entries accepted by the
03598    //                          //selection expression. In case where no selection
03599    //                          //was specified, returns the number of entries processed.
03600    //    -GetV1()              //returns a pointer to the double array of V1
03601    //    -GetV2()              //returns a pointer to the double array of V2
03602    //    -GetV3()              //returns a pointer to the double array of V3
03603    //    -GetW()               //returns a pointer to the double array of Weights
03604    //                          //where weight equal the result of the selection expression.
03605    //   where V1,V2,V3 correspond to the expressions in
03606    //   TTree::Draw("V1:V2:V3",selection);
03607    //
03608    //   Example:
03609    //    Root > ntuple->Draw("py:px","pz>4");
03610    //    Root > TGraph *gr = new TGraph(ntuple->GetSelectedRows(),
03611    //                                   ntuple->GetV2(), ntuple->GetV1());
03612    //    Root > gr->Draw("ap"); //draw graph in current pad
03613    //    creates a TGraph object with a number of points corresponding to the
03614    //    number of entries selected by the expression "pz>4", the x points of the graph
03615    //    being the px values of the Tree and the y points the py values.
03616    //
03617    //   Important note: By default TTree::Draw creates the arrays obtained
03618    //    with GetV1, GetV2, GetV3, GetW with a length corresponding to the
03619    //    parameter fEstimate. By default fEstimate=1000000 and can be modified
03620    //    via TTree::SetEstimate. A possible recipee is to do
03621    //       tree->SetEstimate(tree->GetEntries());
03622    //    You must call SetEstimate if the expected number of selected rows
03623    //    is greater than 1000000.
03624    //
03625    //    You can use the option "goff" to turn off the graphics output
03626    //    of TTree::Draw in the above example.
03627    //
03628    //           Automatic interface to TTree::Draw via the TTreeViewer
03629    //           ======================================================
03630    //
03631    //    A complete graphical interface to this function is implemented
03632    //    in the class TTreeViewer.
03633    //    To start the TTreeViewer, three possibilities:
03634    //       - select TTree context menu item "StartViewer"
03635    //       - type the command  "TTreeViewer TV(treeName)"
03636    //       - execute statement "tree->StartViewer();"
03637    //
03638 
03639    GetPlayer();
03640    if (fPlayer)
03641       return fPlayer->DrawSelect(varexp,selection,option,nentries,firstentry);
03642    return -1;
03643 }
03644 
03645 //______________________________________________________________________________
03646 void TTree::DropBaskets()
03647 {
03648    // Remove some baskets from memory.
03649 
03650    TBranch* branch = 0;
03651    Int_t nb = fBranches.GetEntriesFast();
03652    for (Int_t i = 0; i < nb; ++i) {
03653       branch = (TBranch*) fBranches.UncheckedAt(i);
03654       branch->DropBaskets("all");
03655    }
03656 }
03657 
03658 //______________________________________________________________________________
03659 void TTree::DropBuffers(Int_t)
03660 {
03661    // Drop branch buffers to accomodate nbytes below MaxVirtualsize.
03662 
03663    // Be careful not to remove current read/write buffers.
03664    Int_t ndrop = 0;
03665    Int_t nleaves = fLeaves.GetEntriesFast();
03666    for (Int_t i = 0; i < nleaves; ++i)  {
03667       TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
03668       TBranch* branch = (TBranch*) leaf->GetBranch();
03669       Int_t nbaskets = branch->GetListOfBaskets()->GetEntriesFast();
03670       for (Int_t j = 0; j < nbaskets - 1; ++j) {
03671          if ((j == branch->GetReadBasket()) || (j == branch->GetWriteBasket())) {
03672             continue;
03673          }
03674          TBasket* basket = branch->GetBasket(j);
03675          ndrop += basket->DropBuffers();
03676          if (fTotalBuffers < fMaxVirtualSize) {
03677             return;
03678          }
03679       }
03680    }
03681 }
03682 
03683 //______________________________________________________________________________
03684 Int_t TTree::Fill()
03685 {
03686    // Fill all branches.
03687    //
03688    //   This function loops on all the branches of this tree.  For
03689    //   each branch, it copies to the branch buffer (basket) the current
03690    //   values of the leaves data types. If a leaf is a simple data type,
03691    //   a simple conversion to a machine independent format has to be done.
03692    //
03693    //   This machine independent version of the data is copied into a
03694    //   basket (each branch has its own basket).  When a basket is full
03695    //   (32k worth of data by default), it is then optionally compressed
03696    //   and written to disk (this operation is also called comitting or
03697    //   'flushing' the basket).  The committed baskets are then
03698    //   immediately removed from memory.
03699    //
03700    //   The function returns the number of bytes committed to the
03701    //   individual branches.
03702    //
03703    //   If a write error occurs, the number of bytes returned is -1.
03704    //
03705    //   If no data are written, because, e.g., the branch is disabled,
03706    //   the number of bytes returned is 0.
03707    //
03708    //        The baskets are flushed and the Tree header saved at regular intervals
03709    //         ---------------------------------------------------------------------
03710    //   At regular intervals, when the amount of data written so far is
03711    //   greater than fAutoFlush (see SetAutoFlush) all the baskets are flushed to disk.
03712    //   This makes future reading faster as it guarantees that baskets belonging to nearby
03713    //   entries will be on the same disk region.
03714    //   When the first call to flush the baskets happen, we also take this opportunity
03715    //   to optimize the baskets buffers.
03716    //   We also check if the amount of data written is greater than fAutoSave (see SetAutoSave).
03717    //   In this case we also write the Tree header. This makes the Tree recoverable up to this point
03718    //   in case the program writing the Tree crashes.
03719    //   The decisions to FlushBaskets and Auto Save can be made based either on the number
03720    //   of bytes written (fAutoFlush and fAutoSave negative) or on the number of entries
03721    //   written (fAutoFlush and fAutoSave positive).
03722    //   Note that the user can decide to call FlushBaskets and AutoSave in her event loop
03723    //   base on the number of events written instead of the number of bytes written.
03724    //
03725    //   Note that calling FlushBaskets too often increases the IO time.
03726    //   Note that calling AutoSave too often increases the IO time and also the file size.
03727 
03728    Int_t nbytes = 0;
03729    Int_t nerror = 0;
03730    Int_t nb = fBranches.GetEntriesFast();
03731    if (nb == 1) {
03732       // Case of one single super branch. Automatically update
03733       // all the branch addresses if a new object was created.
03734       TBranch* branch = (TBranch*) fBranches.UncheckedAt(0);
03735       branch->UpdateAddress();
03736    }
03737    if (fBranchRef) {
03738       fBranchRef->Clear();
03739    }
03740    for (Int_t i = 0; i < nb; ++i) {
03741       // Loop over all branches, filling and accumulating bytes written and error counts.
03742       TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
03743       if (branch->TestBit(kDoNotProcess)) {
03744          continue;
03745       }
03746       Int_t nwrite = branch->Fill();
03747       if (nwrite < 0)  {
03748          if (nerror < 2) {
03749             Error("Fill", "Failed filling branch:%s.%s, nbytes=%d, entry=%lld\n"
03750                   " This error is symptomatic of a Tree created as a memory-resident Tree\n"
03751                   " Instead of doing:\n"
03752                   "    TTree *T = new TTree(...)\n"
03753                   "    TFile *f = new TFile(...)\n"
03754                   " you should do:\n"
03755                   "    TFile *f = new TFile(...)\n"
03756                   "    TTree *T = new TTree(...)",
03757                   GetName(), branch->GetName(), nwrite,fEntries+1);
03758          } else {
03759             Error("Fill", "Failed filling branch:%s.%s, nbytes=%d, entry=%lld", GetName(), branch->GetName(), nwrite,fEntries+1);
03760          }
03761          ++nerror;
03762       } else {
03763          nbytes += nwrite;
03764       }
03765    }
03766    if (fBranchRef) {
03767       fBranchRef->Fill();
03768    }
03769    ++fEntries;
03770    if (fEntries > fMaxEntries) {
03771       KeepCircular();
03772    }
03773    if (gDebug > 0) printf("TTree::Fill - A:  %d %lld %lld %lld %lld %lld %lld \n",
03774        nbytes, fEntries, fAutoFlush,fAutoSave,fZipBytes,fFlushedBytes,fSavedBytes);
03775 
03776    if (fAutoFlush != 0 || fAutoSave != 0) {
03777       // Is it time to flush or autosave baskets?
03778       if (fFlushedBytes == 0) {
03779          // Decision can be based initially either on the number of bytes
03780          // or the number of entries written.
03781          if ((fAutoFlush<0 && fZipBytes > -fAutoFlush)  ||
03782              (fAutoSave <0 && fZipBytes > -fAutoSave )  ||
03783              (fAutoFlush>0 && fEntries%TMath::Max((Long64_t)1,fAutoFlush) == 0) ||
03784              (fAutoSave >0 && fEntries%TMath::Max((Long64_t)1,fAutoSave)  == 0) ) {
03785 
03786             //we take the opportunity to Optimizebaskets at this point (it calls FlushBaskets)
03787             OptimizeBaskets(fTotBytes,1,"");
03788             if (gDebug > 0) Info("TTree::Fill","OptimizeBaskets called at entry %lld, fZipBytes=%lld, fFlushedBytes=%lld\n",fEntries,fZipBytes,fFlushedBytes);
03789             fFlushedBytes = fZipBytes;
03790             fAutoFlush    = fEntries;  // Use test on entries rather than bytes
03791             // subsequently in run
03792             if (fAutoSave < 0) {
03793                // Set fAutoSave to the largest integer multiple of
03794                // fAutoFlush events such that fAutoSave*fFlushedBytes
03795                // < (minus the input value of fAutoSave)
03796                fAutoSave =  TMath::Max( fAutoFlush, fEntries*((-fAutoSave/fZipBytes)/fEntries));
03797             } else if(fAutoSave > 0) {
03798                fAutoSave = fEntries*(fAutoSave/fEntries);
03799             }
03800             if (fAutoSave!=0 && fEntries >= fAutoSave) AutoSave();    // FlushBaskets not called in AutoSave
03801             if (gDebug > 0) Info("TTree::Fill","First AutoFlush.  fAutoFlush = %lld, fAutoSave = %lld\n", fAutoFlush, fAutoSave);
03802          }
03803       } else if (fEntries > 1 && fEntries%fAutoFlush == 0) {
03804          if (fAutoSave != 0 && fEntries%fAutoSave == 0) {
03805             //We are at an AutoSave point. AutoSave flushes baskets and saves the Tree header
03806             AutoSave("flushbaskets");
03807             if (gDebug > 0) Info("TTree::Fill","AutoSave called at entry %lld, fZipBytes=%lld, fSavedBytes=%lld\n",fEntries,fZipBytes,fSavedBytes);
03808          } else {
03809             //We only FlushBaskets
03810             FlushBaskets();
03811             if (gDebug > 0) Info("TTree::Fill","FlushBasket called at entry %lld, fZipBytes=%lld, fFlushedBytes=%lld\n",fEntries,fZipBytes,fFlushedBytes);
03812          }
03813          fFlushedBytes = fZipBytes;
03814       }
03815    }
03816    // Check that output file is still below the maximum size.
03817    // If above, close the current file and continue on a new file.
03818    // Currently, the automatic change of file is restricted
03819    // to the case where the tree is in the top level directory.
03820    if (!fDirectory) {
03821       return nbytes;
03822    }
03823    TFile* file = fDirectory->GetFile();
03824    if (file && (file->GetEND() > fgMaxTreeSize)) {
03825       if (fDirectory == (TDirectory*) file) {
03826          ChangeFile(file);
03827       }
03828    }
03829    if (nerror) {
03830       return -1;
03831    }
03832    return nbytes;
03833 }
03834 
03835 //______________________________________________________________________________
03836 static TBranch *R__FindBranchHelper(TObjArray *list, const char *branchname) {
03837    // Search in the array for a branch matching the branch name,
03838    // with the branch possibly expressed as a 'full' path name (with dots).
03839 
03840    if (list==0 || branchname == 0 || branchname[0] == '\0') return 0;
03841 
03842    Int_t nbranches = list->GetEntries();
03843 
03844    UInt_t brlen = strlen(branchname);
03845 
03846    for(Int_t index = 0; index < nbranches; ++index) {
03847       TBranch *where = (TBranch*)list->UncheckedAt(index);
03848 
03849       const char *name = where->GetName();
03850       UInt_t len = strlen(name);
03851       if (name[len-1]==']') {
03852          const  char *dim = strchr(name,'[');
03853          if (dim) {
03854             len = dim - name;
03855          }
03856       }
03857       if (brlen == len && strncmp(branchname,name,len)==0) {
03858          return where;
03859       }
03860       TBranch *next = 0;
03861       if ((brlen >= len) && (branchname[len] == '.')
03862           && strncmp(name, branchname, len) == 0) {
03863          // The prefix subbranch name match the branch name.
03864 
03865          next = where->FindBranch(branchname);
03866          if (!next) {
03867             next = where->FindBranch(branchname+len+1);
03868          }
03869          if (next) return next;
03870       }
03871       const char *dot = strchr((char*)branchname,'.');
03872       if (dot) {
03873          if (len==(size_t)(dot-branchname) &&
03874              strncmp(branchname,name,dot-branchname)==0 ) {
03875             return R__FindBranchHelper(where->GetListOfBranches(),dot+1);
03876          }
03877       }
03878    }
03879    return 0;
03880 }
03881 
03882 //______________________________________________________________________________
03883 TBranch* TTree::FindBranch(const char* branchname)
03884 {
03885    // Return the branch that correspond to the path 'branchname', which can
03886    // include the name of the tree or the ommited name of the parent branches.
03887    // In case of ambiguity, returns the first match.
03888 
03889    // We already have been visited while recursively looking
03890    // through the friends tree, let return
03891    if (kFindBranch & fFriendLockStatus) {
03892       return 0;
03893    }
03894 
03895    TBranch* branch = 0;
03896    // If the first part of the name match the TTree name, look for the right part in the
03897    // list of branches.
03898    // This will allow the branchname to be preceded by
03899    // the name of this tree.
03900    if (strncmp(fName.Data(),branchname,fName.Length())==0 && branchname[fName.Length()]=='.') {
03901       branch = R__FindBranchHelper( GetListOfBranches(), branchname + fName.Length() + 1);
03902       if (branch) return branch;
03903    }
03904    // If we did not find it, let's try to find the full name in the list of branches.
03905    branch = R__FindBranchHelper(GetListOfBranches(), branchname);
03906    if (branch) return branch;
03907 
03908    // If we still did not find, let's try to find it within each branch assuming it does not the branch name.
03909    TIter next(GetListOfBranches());
03910    while ((branch = (TBranch*) next())) {
03911       TBranch* nestedbranch = branch->FindBranch(branchname);
03912       if (nestedbranch) {
03913          return nestedbranch;
03914       }
03915    }
03916 
03917    // Search in list of friends.
03918    if (!fFriends) {
03919       return 0;
03920    }
03921    TFriendLock lock(this, kFindBranch);
03922    TIter nextf(fFriends);
03923    TFriendElement* fe = 0;
03924    while ((fe = (TFriendElement*) nextf())) {
03925       TTree* t = fe->GetTree();
03926       if (!t) {
03927          continue;
03928       }
03929       // If the alias is present replace it with the real name.
03930       const char *subbranch = strstr(branchname, fe->GetName());
03931       if (subbranch != branchname) {
03932          subbranch = 0;
03933       }
03934       if (subbranch) {
03935          subbranch += strlen(fe->GetName());
03936          if (*subbranch != '.') {
03937             subbranch = 0;
03938          } else {
03939             ++subbranch;
03940          }
03941       }
03942       std::ostringstream name;
03943       if (subbranch) {
03944          name << t->GetName() << "." << subbranch;
03945       } else {
03946          name << branchname;
03947       }
03948       branch = t->FindBranch(name.str().c_str());
03949       if (branch) {
03950          return branch;
03951       }
03952    }
03953    return 0;
03954 }
03955 
03956 //______________________________________________________________________________
03957 TLeaf* TTree::FindLeaf(const char* searchname)
03958 {
03959    // FIXME: Describe this function.
03960 
03961    // We already have been visited while recursively looking
03962    // through the friends tree, let's return.
03963    if (kFindLeaf & fFriendLockStatus) {
03964       return 0;
03965    }
03966 
03967    // This will allow the branchname to be preceded by
03968    // the name of this tree.
03969    char* subsearchname = (char*) strstr(searchname, GetName());
03970    if (subsearchname != searchname) {
03971       subsearchname = 0;
03972    }
03973    if (subsearchname) {
03974       subsearchname += strlen(GetName());
03975       if (*subsearchname != '.') {
03976          subsearchname = 0;
03977       } else {
03978          ++subsearchname;
03979          if (subsearchname[0]==0) {
03980             subsearchname = 0;
03981          }
03982       }
03983    }
03984 
03985    TString leafname;
03986    TString leaftitle;
03987    TString longname;
03988    TString longtitle;
03989 
03990    // For leaves we allow for one level up to be prefixed to the name.
03991    TIter next(GetListOfLeaves());
03992    TLeaf* leaf = 0;
03993    while ((leaf = (TLeaf*) next())) {
03994       leafname = leaf->GetName();
03995       Ssiz_t dim = leafname.First('[');
03996       if (dim >= 0) leafname.Remove(dim);
03997 
03998       if (leafname == searchname) {
03999          return leaf;
04000       }
04001       if (subsearchname && leafname == subsearchname) {
04002          return leaf;
04003       }
04004       // The TLeafElement contains the branch name
04005       // in its name, let's use the title.
04006       leaftitle = leaf->GetTitle();
04007       dim = leaftitle.First('[');
04008       if (dim >= 0) leaftitle.Remove(dim);
04009 
04010       if (leaftitle == searchname) {
04011          return leaf;
04012       }
04013       if (subsearchname && leaftitle == subsearchname) {
04014          return leaf;
04015       }
04016       TBranch* branch = leaf->GetBranch();
04017       if (branch) {
04018          longname.Form("%s.%s",branch->GetName(),leafname.Data());
04019          dim = longname.First('[');
04020          if (dim>=0) longname.Remove(dim);
04021          if (longname == searchname) {
04022             return leaf;
04023          }
04024          if (subsearchname && longname == subsearchname) {
04025             return leaf;
04026          }
04027          longtitle.Form("%s.%s",branch->GetName(),leaftitle.Data());
04028          dim = longtitle.First('[');
04029          if (dim>=0) longtitle.Remove(dim);
04030          if (longtitle == searchname) {
04031             return leaf;
04032          }
04033          if (subsearchname && longtitle == subsearchname) {
04034             return leaf;
04035          }
04036          // The following is for the case where the branch is only
04037          // a sub-branch.  Since we do not see it through
04038          // TTree::GetListOfBranches, we need to see it indirectly.
04039          // This is the less sturdy part of this search ... it may
04040          // need refining ...
04041          if (strstr(searchname, ".") && !strcmp(searchname, branch->GetName())) {
04042             return leaf;
04043          }
04044          if (subsearchname && strstr(subsearchname, ".") && !strcmp(subsearchname, branch->GetName())) {
04045             return leaf;
04046          }
04047       }
04048    }
04049    // Search in list of friends.
04050    if (!fFriends) {
04051       return 0;
04052    }
04053    TFriendLock lock(this, kFindLeaf);
04054    TIter nextf(fFriends);
04055    TFriendElement* fe = 0;
04056    while ((fe = (TFriendElement*) nextf())) {
04057       TTree* t = fe->GetTree();
04058       if (!t) {
04059          continue;
04060       }
04061       // If the alias is present replace it with the real name.
04062       subsearchname = (char*) strstr(searchname, fe->GetName());
04063       if (subsearchname != searchname) {
04064          subsearchname = 0;
04065       }
04066       if (subsearchname) {
04067          subsearchname += strlen(fe->GetName());
04068          if (*subsearchname != '.') {
04069             subsearchname = 0;
04070          } else {
04071             ++subsearchname;
04072          }
04073       }
04074       if (subsearchname) {
04075          leafname.Form("%s.%s",t->GetName(),subsearchname);
04076       } else {
04077          leafname = searchname;
04078       }
04079       leaf = t->FindLeaf(leafname);
04080       if (leaf) {
04081          return leaf;
04082       }
04083    }
04084    return 0;
04085 }
04086 
04087 //______________________________________________________________________________
04088 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)
04089 {
04090    // Fit  a projected item(s) from a tree.
04091    //
04092    //  funcname is a TF1 function.
04093    //
04094    //  See TTree::Draw() for explanations of the other parameters.
04095    //
04096    //  By default the temporary histogram created is called htemp.
04097    //  If varexp contains >>hnew , the new histogram created is called hnew
04098    //  and it is kept in the current directory.
04099    //
04100    //  The function returns the number of selected entries.
04101    //
04102    //  Example:
04103    //    tree.Fit(pol4,sqrt(x)>>hsqrt,y>0)
04104    //    will fit sqrt(x) and save the histogram as "hsqrt" in the current
04105    //    directory.
04106    //
04107    //   See also TTree::UnbinnedFit
04108    //
04109    //   Return status
04110    //   =============
04111    //  The function returns the status of the histogram fit (see TH1::Fit)
04112    //  If no entries were selected, the function returns -1;
04113    //   (ie fitResult is null is the fit is OK)
04114 
04115    GetPlayer();
04116    if (fPlayer) {
04117       return fPlayer->Fit(funcname, varexp, selection, option, goption, nentries, firstentry);
04118    }
04119    return -1;
04120 }
04121 
04122 //______________________________________________________________________________
04123 Int_t TTree::FlushBaskets() const
04124 {
04125    // Write to disk all the basket that have not yet been individually written.
04126    //
04127    // Return the number of bytes written or -1 in case of write error.
04128 
04129    if (!fDirectory) return 0;
04130    Int_t nbytes = 0;
04131    Int_t nerror = 0;
04132    TObjArray *lb = const_cast<TTree*>(this)->GetListOfBranches();
04133    Int_t nb = lb->GetEntriesFast();
04134    for (Int_t j = 0; j < nb; j++) {
04135       TBranch* branch = (TBranch*) lb->UncheckedAt(j);
04136       if (branch) {
04137          Int_t nwrite = branch->FlushBaskets();
04138          if (nwrite<0) {
04139             ++nerror;
04140          } else {
04141             nbytes += nwrite;
04142          }
04143       }
04144    }
04145    if (nerror) {
04146       return -1;
04147    } else {
04148       return nbytes;
04149    }
04150 }
04151 
04152 //______________________________________________________________________________
04153 const char* TTree::GetAlias(const char* aliasName) const
04154 {
04155    // Returns the expanded value of the alias.  Search in the friends if any.
04156 
04157    // We already have been visited while recursively looking
04158    // through the friends tree, let's return.
04159    if (kGetAlias & fFriendLockStatus) {
04160       return 0;
04161    }
04162    if (fAliases) {
04163       TObject* alias = fAliases->FindObject(aliasName);
04164       if (alias) {
04165          return alias->GetTitle();
04166       }
04167    }
04168    if (!fFriends) {
04169       return 0;
04170    }
04171    TFriendLock lock(const_cast<TTree*>(this), kGetAlias);
04172    TIter nextf(fFriends);
04173    TFriendElement* fe = 0;
04174    while ((fe = (TFriendElement*) nextf())) {
04175       TTree* t = fe->GetTree();
04176       if (t) {
04177          const char* alias = t->GetAlias(aliasName);
04178          if (alias) {
04179             return alias;
04180          }
04181          const char* subAliasName = strstr(aliasName, fe->GetName());
04182          if (subAliasName && (subAliasName[strlen(fe->GetName())] == '.')) {
04183             alias = t->GetAlias(aliasName + strlen(fe->GetName()) + 1);
04184             if (alias) {
04185                return alias;
04186             }
04187          }
04188       }
04189    }
04190    return 0;
04191 }
04192 
04193 //______________________________________________________________________________
04194 TBranch* TTree::GetBranch(const char* name)
04195 {
04196    // Return pointer to the branch with the given name in this tree or its friends.
04197 
04198    if (name == 0) return 0;
04199 
04200    // We already have been visited while recursively
04201    // looking through the friends tree, let's return.
04202    if (kGetBranch & fFriendLockStatus) {
04203       return 0;
04204    }
04205 
04206    // Search using branches.
04207    Int_t nb = fBranches.GetEntriesFast();
04208    for (Int_t i = 0; i < nb; i++) {
04209       TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
04210       if (!strcmp(branch->GetName(), name)) {
04211          return branch;
04212       }
04213       TObjArray* lb = branch->GetListOfBranches();
04214       Int_t nb1 = lb->GetEntriesFast();
04215       for (Int_t j = 0; j < nb1; j++) {
04216          TBranch* b1 = (TBranch*) lb->UncheckedAt(j);
04217          if (!strcmp(b1->GetName(), name)) {
04218             return b1;
04219          }
04220          TObjArray* lb1 = b1->GetListOfBranches();
04221          Int_t nb2 = lb1->GetEntriesFast();
04222          for (Int_t k = 0; k < nb2; k++) {
04223             TBranch* b2 = (TBranch*) lb1->UncheckedAt(k);
04224             if (!strcmp(b2->GetName(), name)) {
04225                return b2;
04226             }
04227          }
04228       }
04229    }
04230 
04231    // Search using leaves.
04232    TObjArray* leaves = GetListOfLeaves();
04233    Int_t nleaves = leaves->GetEntriesFast();
04234    for (Int_t i = 0; i < nleaves; i++) {
04235       TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(i);
04236       TBranch* branch = leaf->GetBranch();
04237       if (!strcmp(branch->GetName(), name)) {
04238          return branch;
04239       }
04240    }
04241 
04242    if (!fFriends) {
04243       return 0;
04244    }
04245 
04246    // Search in list of friends.
04247    TFriendLock lock(this, kGetBranch);
04248    TIter next(fFriends);
04249    TFriendElement* fe = 0;
04250    while ((fe = (TFriendElement*) next())) {
04251       TTree* t = fe->GetTree();
04252       if (t) {
04253          TBranch* branch = t->GetBranch(name);
04254          if (branch) {
04255             return branch;
04256          }
04257       }
04258    }
04259 
04260    // Second pass in the list of friends when
04261    // the branch name is prefixed by the tree name.
04262    next.Reset();
04263    while ((fe = (TFriendElement*) next())) {
04264       TTree* t = fe->GetTree();
04265       if (!t) {
04266          continue;
04267       }
04268       char* subname = (char*) strstr(name, fe->GetName());
04269       if (subname != name) {
04270          continue;
04271       }
04272       Int_t l = strlen(fe->GetName());
04273       subname += l;
04274       if (*subname != '.') {
04275          continue;
04276       }
04277       subname++;
04278       TBranch* branch = t->GetBranch(subname);
04279       if (branch) {
04280          return branch;
04281       }
04282    }
04283    return 0;
04284 }
04285 
04286 //______________________________________________________________________________
04287 Bool_t TTree::GetBranchStatus(const char* branchname) const
04288 {
04289    // Return status of branch with name branchname.
04290    // 0 if branch is not activated
04291    // 1 if branch is activated
04292 
04293    TBranch* br = const_cast<TTree*>(this)->GetBranch(branchname);
04294    if (br) {
04295       return br->TestBit(kDoNotProcess) == 0;
04296    }
04297    return 0;
04298 }
04299 
04300 //______________________________________________________________________________
04301 Int_t TTree::GetBranchStyle()
04302 {
04303    // Static function returning the current branch style.
04304    // style = 0 old Branch
04305    // style = 1 new Bronch
04306 
04307    return fgBranchStyle;
04308 }
04309 
04310 //______________________________________________________________________________
04311 TFile* TTree::GetCurrentFile() const
04312 {
04313    // Return pointer to the current file.
04314 
04315    if (!fDirectory || fDirectory==gROOT) {
04316       return 0;
04317    }
04318    return fDirectory->GetFile();
04319 }
04320 
04321 //______________________________________________________________________________
04322 Long64_t TTree::GetEntries(const char *selection)
04323 {
04324    // Return the number of entries matching the selection.
04325    // Return -1 in case of errors.
04326    //
04327    // If the selection uses any arrays or containers, we return the number
04328    // of entries where at least one element match the selection.
04329    // GetEntries is implemented using the selector class TSelectorEntries,
04330    // which can be used directly (see code in TTreePlayer::GetEntries) for
04331    // additional option.
04332    // If SetEventList was used on the TTree or TChain, only that subset
04333    // of entries will be considered.
04334 
04335    GetPlayer();
04336    if (fPlayer) {
04337       return fPlayer->GetEntries(selection);
04338    }
04339    return -1;
04340 }
04341 
04342 //______________________________________________________________________________
04343 Long64_t TTree::GetEntriesFriend() const
04344 {
04345    // Return pointer to the 1st Leaf named name in any Branch of this Tree or
04346    // any branch in the list of friend trees.
04347 
04348    if (fEntries) return fEntries;
04349    if (!fFriends) return 0;
04350    TFriendElement *fr = (TFriendElement*)fFriends->At(0);
04351    if (!fr) return 0;
04352    TTree *t = fr->GetTree();
04353    if (t==0) return 0;
04354    return t->GetEntriesFriend();
04355 }
04356 
04357 //______________________________________________________________________________
04358 Int_t TTree::GetEntry(Long64_t entry, Int_t getall)
04359 {
04360    // Read all branches of entry and return total number of bytes read.
04361    //
04362    //     getall = 0 : get only active branches
04363    //     getall = 1 : get all branches
04364    //
04365    //  The function returns the number of bytes read from the input buffer.
04366    //  If entry does not exist  the function returns 0.
04367    //  If an I/O error occurs,  the function returns -1.
04368    //
04369    //  If the Tree has friends, also read the friends entry
04370    //
04371    //  To activate/deactivate one or more branches, use TBranch::SetBranchStatus
04372    //  For example, if you have a Tree with several hundred branches, and you
04373    //  are interested only by branches named "u" and "v", do
04374    //     mytree.SetBranchStatus("*",0); //disable all branches
04375    //     mytree.SetBranchStatus("a",1);
04376    //     mytree.SetBranchStatus("b",1);
04377    //  when calling mytree.GetEntry(i); only branches "a" and "b" will be read.
04378    //
04379    //  WARNING!!
04380    //  If your Tree has been created in split mode with a parent branch "parent",
04381    //     mytree.SetBranchStatus("parent",1);
04382    //  will not activate the sub-branches of "parent". You should do:
04383    //     mytree.SetBranchStatus("parent*",1);
04384    //
04385    //  An alternative is to call directly
04386    //     brancha.GetEntry(i)
04387    //     branchb.GetEntry(i);
04388    //
04389    //  IMPORTANT NOTE
04390    //  ==============
04391    // By default, GetEntry reuses the space allocated by the previous object
04392    // for each branch. You can force the previous object to be automatically
04393    // deleted if you call mybranch.SetAutoDelete(kTRUE) (default is kFALSE).
04394    // Example:
04395    // Consider the example in $ROOTSYS/test/Event.h
04396    // The top level branch in the tree T is declared with:
04397    //    Event *event = 0;  //event must be null or point to a valid object
04398    //                       //it must be initialized
04399    //    T.SetBranchAddress("event",&event);
04400    // When reading the Tree, one can choose one of these 3 options:
04401    //
04402    //   OPTION 1
04403    //   --------
04404    //
04405    //    for (Long64_t i=0;i<nentries;i++) {
04406    //       T.GetEntry(i);
04407    //       // the object event has been filled at this point
04408    //    }
04409    //   The default (recommended). At the first entry an object of the
04410    //   class Event will be created and pointed by event.
04411    //   At the following entries, event will be overwritten by the new data.
04412    //   All internal members that are TObject* are automatically deleted.
04413    //   It is important that these members be in a valid state when GetEntry
04414    //   is called. Pointers must be correctly initialized.
04415    //   However these internal members will not be deleted if the characters "->"
04416    //   are specified as the first characters in the comment field of the data
04417    //   member declaration.
04418    //   If "->" is specified, the pointer member is read via pointer->Streamer(buf).
04419    //   In this case, it is assumed that the pointer is never null (case
04420    //   of pointer TClonesArray *fTracks in the Event example).
04421    //   If "->" is not specified, the pointer member is read via buf >> pointer.
04422    //   In this case the pointer may be null. Note that the option with "->"
04423    //   is faster to read or write and it also consumes less space in the file.
04424    //
04425    //   OPTION 2
04426    //   --------
04427    //  The option AutoDelete is set
04428    //   TBranch *branch = T.GetBranch("event");
04429    //   branch->SetAddress(&event);
04430    //   branch->SetAutoDelete(kTRUE);
04431    //    for (Long64_t i=0;i<nentries;i++) {
04432    //       T.GetEntry(i);
04433    //       // the object event has been filled at this point
04434    //    }
04435    //   In this case, at each iteration, the object event is deleted by GetEntry
04436    //   and a new instance of Event is created and filled.
04437    //
04438    //   OPTION 3
04439    //   --------
04440    //   Same as option 1, but you delete yourself the event.
04441    //    for (Long64_t i=0;i<nentries;i++) {
04442    //       delete event;
04443    //       event = 0;  // EXTREMELY IMPORTANT
04444    //       T.GetEntry(i);
04445    //       // the object event has been filled at this point
04446    //    }
04447    //
04448    //  It is strongly recommended to use the default option 1. It has the
04449    //  additional advantage that functions like TTree::Draw (internally
04450    //  calling TTree::GetEntry) will be functional even when the classes in the
04451    //  file are not available.
04452 
04453    // We already have been visited while recursively looking
04454    // through the friends tree, let return
04455    if (kGetEntry & fFriendLockStatus) return 0;
04456 
04457    if (entry < 0 || entry >= fEntries) return 0;
04458    Int_t i;
04459    Int_t nbytes = 0;
04460    fReadEntry = entry;
04461    TBranch *branch;
04462 
04463    Int_t nbranches = fBranches.GetEntriesFast();
04464    Int_t nb=0;
04465    for (i=0;i<nbranches;i++)  {
04466       branch = (TBranch*)fBranches.UncheckedAt(i);
04467       nb = branch->GetEntry(entry, getall);
04468       if (nb < 0) return nb;
04469       nbytes += nb;
04470    }
04471 
04472    // GetEntry in list of friends
04473    if (!fFriends) return nbytes;
04474    TFriendLock lock(this,kGetEntry);
04475    TIter nextf(fFriends);
04476    TFriendElement *fe;
04477    while ((fe = (TFriendElement*)nextf())) {
04478       TTree *t = fe->GetTree();
04479       if (t) {
04480          if (fe->TestBit(TFriendElement::kFromChain)) {
04481             nb = t->GetEntry(t->GetReadEntry(),getall);
04482          } else {
04483             if ( t->LoadTreeFriend(entry,this) >= 0 ) {
04484                nb = t->GetEntry(t->GetReadEntry(),getall);
04485             } else nb = 0;
04486          }
04487          if (nb < 0) return nb;
04488          nbytes += nb;
04489       }
04490    }
04491    return nbytes;
04492 }
04493 
04494 //______________________________________________________________________________
04495 TEntryList* TTree::GetEntryList()
04496 {
04497 //Returns the entry list, set to this tree
04498 
04499    return fEntryList;
04500 }
04501 
04502 //______________________________________________________________________________
04503 Long64_t TTree::GetEntryNumber(Long64_t entry) const
04504 {
04505    // Return entry number corresponding to entry.
04506    //
04507    // if no TEntryList set returns entry
04508    // else returns the entry number corresponding to the list index=entry
04509 
04510    if (!fEntryList) {
04511       return entry;
04512    }
04513 
04514    return fEntryList->GetEntry(entry);
04515 }
04516 
04517 //______________________________________________________________________________
04518 Long64_t TTree::GetEntryNumberWithBestIndex(Int_t major, Int_t minor) const
04519 {
04520    // Return entry number corresponding to major and minor number.
04521    // Note that this function returns only the entry number, not the data
04522    // To read the data corresponding to an entry number, use TTree::GetEntryWithIndex
04523    // the BuildIndex function has created a table of Long64_t* of sorted values
04524    // corresponding to val = major<<31 + minor;
04525    // The function performs binary search in this sorted table.
04526    // If it finds a pair that maches val, it returns directly the
04527    // index in the table.
04528    // If an entry corresponding to major and minor is not found, the function
04529    // returns the index of the major,minor pair immediatly lower than the
04530    // requested value, ie it will return -1 if the pair is lower than
04531    // the first entry in the index.
04532    //
04533    // See also GetEntryNumberWithIndex
04534 
04535    if (!fTreeIndex) {
04536       return -1;
04537    }
04538    return fTreeIndex->GetEntryNumberWithBestIndex(major, minor);
04539 }
04540 
04541 //______________________________________________________________________________
04542 Long64_t TTree::GetEntryNumberWithIndex(Int_t major, Int_t minor) const
04543 {
04544    // Return entry number corresponding to major and minor number.
04545    // Note that this function returns only the entry number, not the data
04546    // To read the data corresponding to an entry number, use TTree::GetEntryWithIndex
04547    // the BuildIndex function has created a table of Long64_t* of sorted values
04548    // corresponding to val = major<<31 + minor;
04549    // The function performs binary search in this sorted table.
04550    // If it finds a pair that maches val, it returns directly the
04551    // index in the table, otherwise it returns -1.
04552    //
04553    // See also GetEntryNumberWithBestIndex
04554 
04555    if (!fTreeIndex) {
04556       return -1;
04557    }
04558    return fTreeIndex->GetEntryNumberWithIndex(major, minor);
04559 }
04560 
04561 //______________________________________________________________________________
04562 Int_t TTree::GetEntryWithIndex(Int_t major, Int_t minor)
04563 {
04564    // Read entry corresponding to major and minor number.
04565    //
04566    //  The function returns the total number of bytes read.
04567    //  If the Tree has friend trees, the corresponding entry with
04568    //  the index values (major,minor) is read. Note that the master Tree
04569    //  and its friend may have different entry serial numbers corresponding
04570    //  to (major,minor).
04571 
04572    // We already have been visited while recursively looking
04573    // through the friends tree, let's return.
04574    if (kGetEntryWithIndex & fFriendLockStatus) {
04575       return 0;
04576    }
04577    Long64_t serial = GetEntryNumberWithIndex(major, minor);
04578    if (serial < 0) {
04579       return -1;
04580    }
04581    Int_t i;
04582    Int_t nbytes = 0;
04583    fReadEntry = serial;
04584    TBranch *branch;
04585    Int_t nbranches = fBranches.GetEntriesFast();
04586    Int_t nb;
04587    for (i = 0; i < nbranches; ++i) {
04588       branch = (TBranch*)fBranches.UncheckedAt(i);
04589       nb = branch->GetEntry(serial);
04590       if (nb < 0) return nb;
04591       nbytes += nb;
04592    }
04593    // GetEntry in list of friends
04594    if (!fFriends) return nbytes;
04595    TFriendLock lock(this,kGetEntryWithIndex);
04596    TIter nextf(fFriends);
04597    TFriendElement* fe = 0;
04598    while ((fe = (TFriendElement*) nextf())) {
04599       TTree *t = fe->GetTree();
04600       if (t) {
04601          serial = t->GetEntryNumberWithIndex(major,minor);
04602          if (serial <0) return -nbytes;
04603          nb = t->GetEntry(serial);
04604          if (nb < 0) return nb;
04605          nbytes += nb;
04606       }
04607    }
04608    return nbytes;
04609 }
04610 //______________________________________________________________________________
04611 TTree* TTree::GetFriend(const char *friendname) const
04612 {
04613    // Return a pointer to the TTree friend whose name or alias is 'friendname.
04614 
04615 
04616    // We already have been visited while recursively
04617    // looking through the friends tree, let's return.
04618    if (kGetFriend & fFriendLockStatus) {
04619       return 0;
04620    }
04621    if (!fFriends) {
04622       return 0;
04623    }
04624    TFriendLock lock(const_cast<TTree*>(this), kGetFriend);
04625    TIter nextf(fFriends);
04626    TFriendElement* fe = 0;
04627    while ((fe = (TFriendElement*) nextf())) {
04628       if (strcmp(friendname,fe->GetName())==0
04629           || strcmp(friendname,fe->GetTreeName())==0) {
04630          return fe->GetTree();
04631       }
04632    }
04633    // After looking at the first level,
04634    // let's see if it is a friend of friends.
04635    nextf.Reset();
04636    fe = 0;
04637    while ((fe = (TFriendElement*) nextf())) {
04638       TTree *res = fe->GetTree()->GetFriend(friendname);
04639       if (res) {
04640          return res;
04641       }
04642    }
04643    return 0;
04644 }
04645 
04646 //______________________________________________________________________________
04647 const char* TTree::GetFriendAlias(TTree* tree) const
04648 {
04649    // If the the 'tree' is a friend, this method returns its alias name.
04650    //
04651    // This alias is an alternate name for the tree.
04652    //
04653    // It can be used in conjunction with a branch or leaf name in a TTreeFormula,
04654    // to specify in which particular tree the branch or leaf can be found if
04655    // the friend trees have branches or leaves with the same name as the master
04656    // tree.
04657    //
04658    // It can also be used in conjunction with an alias created using
04659    // TTree::SetAlias in a TTreeFormula, e.g.:
04660    //
04661    //      maintree->Draw("treealias.fPx - treealias.myAlias");
04662    //
04663    // where fPx is a branch of the friend tree aliased as 'treealias' and 'myAlias'
04664    // was created using TTree::SetAlias on the friend tree.
04665    //
04666    // However, note that 'treealias.myAlias' will be expanded literally,
04667    // without remembering that it comes from the aliased friend and thus
04668    // the branch name might not be disambiguated properly, which means
04669    // that you may not be able to take advantage of this feature.
04670    //
04671 
04672    if ((tree == this) || (tree == GetTree())) {
04673       return 0;
04674    }
04675 
04676    // We already have been visited while recursively
04677    // looking through the friends tree, let's return.
04678    if (kGetFriendAlias & fFriendLockStatus) {
04679       return 0;
04680    }
04681    if (!fFriends) {
04682       return 0;
04683    }
04684    TFriendLock lock(const_cast<TTree*>(this), kGetFriendAlias);
04685    TIter nextf(fFriends);
04686    TFriendElement* fe = 0;
04687    while ((fe = (TFriendElement*) nextf())) {
04688       TTree* t = fe->GetTree();
04689       if (t == tree) {
04690          return fe->GetName();
04691       }
04692       // Case of a chain:
04693       if (t->GetTree() == tree) {
04694          return fe->GetName();
04695       }
04696    }
04697    // After looking at the first level,
04698    // let's see if it is a friend of friends.
04699    nextf.Reset();
04700    fe = 0;
04701    while ((fe = (TFriendElement*) nextf())) {
04702       const char* res = fe->GetTree()->GetFriendAlias(tree);
04703       if (res) {
04704          return res;
04705       }
04706    }
04707    return 0;
04708 }
04709 
04710 //______________________________________________________________________________
04711 TIterator* TTree::GetIteratorOnAllLeaves(Bool_t dir)
04712 {
04713    // Creates a new iterator that will go through all the leaves on the tree itself and its friend.
04714 
04715    return new TTreeFriendLeafIter(this, dir);
04716 }
04717 
04718 //______________________________________________________________________________
04719 TLeaf* TTree::GetLeaf(const char* aname)
04720 {
04721    // Return pointer to the 1st Leaf named name in any Branch of this Tree or any branch in the list of friend trees.
04722    //
04723    //  aname may be of the form branchname/leafname
04724 
04725    if (aname == 0) return 0;
04726 
04727    // We already have been visited while recursively looking
04728    // through the friends tree, let return
04729    if (kGetLeaf & fFriendLockStatus) {
04730       return 0;
04731    }
04732    TLeaf *leaf = 0;
04733    char* slash = (char*) strchr(aname, '/');
04734    char* name = 0;
04735    UInt_t nbch = 0;
04736    if (slash) {
04737       name = slash + 1;
04738       nbch = slash - aname;
04739       TString brname(aname,nbch);
04740       TBranch *branch = FindBranch(brname);
04741       if (branch) {
04742          leaf = branch->GetLeaf(name);
04743          if (leaf) {
04744             return leaf;
04745          }
04746       }
04747    } else {
04748       name = (char*) aname;
04749    }
04750    TIter nextl(GetListOfLeaves());
04751    while ((leaf = (TLeaf*)nextl())) {
04752       if (strcmp(leaf->GetName(),name)) continue;
04753       if (slash) {
04754          TBranch *br = leaf->GetBranch();
04755          const char* brname = br->GetName();
04756          TBranch *mother = br->GetMother();
04757          if (strncmp(brname,aname,nbch)) {
04758             if (mother != br) {
04759                const char *mothername = mother->GetName();
04760                UInt_t motherlen = strlen(mothername);
04761                if (nbch > motherlen && strncmp(mothername,aname,motherlen)==0 && (mothername[motherlen-1]=='.' || aname[motherlen]=='.')) {
04762                   // 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.
04763                   if (strncmp(brname,aname+motherlen+1,nbch-motherlen-1)) {
04764                      // No it does not
04765                      continue;
04766                   } // else we have match so we can proceed.
04767                } else {
04768                   // no match
04769                   continue;
04770                }
04771             } else {
04772                continue;
04773             }
04774          }
04775          // The start of the branch name is indentical to the content
04776          // of 'aname' before the first '/'.
04777          // Let's make sure that it is not longer (we are trying
04778          // to avoid having jet2/value match the branch jet23
04779          if ((strlen(brname) > nbch) && (brname[nbch] != '.') && (brname[nbch] != '[')) {
04780             continue;
04781          }
04782       }
04783       return leaf;
04784    }
04785    if (!fFriends) return 0;
04786    TFriendLock lock(this,kGetLeaf);
04787    TIter next(fFriends);
04788    TFriendElement *fe;
04789    while ((fe = (TFriendElement*)next())) {
04790       TTree *t = fe->GetTree();
04791       if (t) {
04792          leaf = t->GetLeaf(aname);
04793          if (leaf) return leaf;
04794       }
04795    }
04796 
04797    //second pass in the list of friends when the leaf name
04798    //is prefixed by the tree name
04799    TString strippedArg;
04800    next.Reset();
04801    while ((fe = (TFriendElement*)next())) {
04802       TTree *t = fe->GetTree();
04803       if (t==0) continue;
04804       char *subname = (char*)strstr(name,fe->GetName());
04805       if (subname != name) continue;
04806       Int_t l = strlen(fe->GetName());
04807       subname += l;
04808       if (*subname != '.') continue;
04809       subname++;
04810       if (slash) {
04811          strippedArg = aname;
04812          strippedArg.Remove(nbch+1);
04813       } else {
04814          strippedArg = "";
04815       }
04816       strippedArg += subname;
04817       leaf = t->GetLeaf(strippedArg);
04818       if (leaf) return leaf;
04819    }
04820    return 0;
04821 }
04822 
04823 //______________________________________________________________________________
04824 Double_t TTree::GetMaximum(const char* columname)
04825 {
04826    // Return maximum of column with name columname.
04827    // if the Tree has an associated TEventList or TEntryList, the maximum
04828    // is computed for the entries in this list.
04829 
04830    TLeaf* leaf = this->GetLeaf(columname);
04831    if (!leaf) {
04832       return 0;
04833    }
04834    TBranch* branch = leaf->GetBranch();
04835    Double_t cmax = -FLT_MAX;
04836    for (Long64_t i = 0; i < fEntries; ++i) {
04837       Long64_t entryNumber = this->GetEntryNumber(i);
04838       if (entryNumber < 0) break;
04839       branch->GetEntry(entryNumber);
04840       for (Int_t j = 0; j < leaf->GetLen(); ++j) {
04841          Double_t val = leaf->GetValue(j);
04842          if (val > cmax) {
04843             cmax = val;
04844          }
04845       }
04846    }
04847    return cmax;
04848 }
04849 
04850 //______________________________________________________________________________
04851 Long64_t TTree::GetMaxTreeSize()
04852 {
04853    // Static function which returns the tree file size limit in bytes.
04854 
04855    return fgMaxTreeSize;
04856 }
04857 
04858 //______________________________________________________________________________
04859 Double_t TTree::GetMinimum(const char* columname)
04860 {
04861    // Return minimum of column with name columname.
04862    // if the Tree has an associated TEventList or TEntryList, the minimum
04863    // is computed for the entries in this list.
04864 
04865    TLeaf* leaf = this->GetLeaf(columname);
04866    if (!leaf) {
04867       return 0;
04868    }
04869    TBranch* branch = leaf->GetBranch();
04870    Double_t cmin = FLT_MAX;
04871    for (Long64_t i = 0; i < fEntries; ++i) {
04872       Long64_t entryNumber = this->GetEntryNumber(i);
04873       if (entryNumber < 0) break;
04874       branch->GetEntry(entryNumber);
04875       for (Int_t j = 0;j < leaf->GetLen(); ++j) {
04876          Double_t val = leaf->GetValue(j);
04877          if (val < cmin) {
04878             cmin = val;
04879          }
04880       }
04881    }
04882    return cmin;
04883 }
04884 
04885 //______________________________________________________________________________
04886 TVirtualTreePlayer* TTree::GetPlayer()
04887 {
04888    // Load the TTreePlayer (if not already done).
04889 
04890    if (fPlayer) {
04891       return fPlayer;
04892    }
04893    fPlayer = TVirtualTreePlayer::TreePlayer(this);
04894    return fPlayer;
04895 }
04896 
04897 //______________________________________________________________________________
04898 TList* TTree::GetUserInfo()
04899 {
04900    // Return a pointer to the list containing user objects associated to this tree.
04901    //
04902    // The list is automatically created if it does not exist.
04903    //
04904    // WARNING: By default the TTree destructor will delete all objects added
04905    //          to this list. If you do not want these objects to be deleted,
04906    //          call:
04907    //
04908    //               mytree->GetUserInfo()->Clear();
04909    //
04910    //          before deleting the tree.
04911 
04912    if (!fUserInfo) {
04913       fUserInfo = new TList();
04914       fUserInfo->SetName("UserInfo");
04915    }
04916    return fUserInfo;
04917 }
04918 
04919 //______________________________________________________________________________
04920 void TTree::KeepCircular()
04921 {
04922    // Keep a maximum of fMaxEntries in memory.
04923 
04924    Int_t nb = fBranches.GetEntriesFast();
04925    Long64_t maxEntries = fMaxEntries - (fMaxEntries / 10);
04926    for (Int_t i = 0; i < nb; ++i)  {
04927       TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
04928       branch->KeepCircular(maxEntries);
04929    }
04930    fEntries = maxEntries;
04931    fReadEntry = -1;
04932 }
04933 
04934 //______________________________________________________________________________
04935 Int_t TTree::LoadBaskets(Long64_t maxmemory)
04936 {
04937    // Read in memory all baskets from all branches up to the limit of maxmemory bytes.
04938    //
04939    // If maxmemory is non null and positive SetMaxVirtualSize is called
04940    // with this value. Default for maxmemory is 2000000000 (2 Gigabytes).
04941    // The function returns the total number of baskets read into memory
04942    // if negative an error occured while loading the branches.
04943    // This method may be called to force branch baskets in memory
04944    // when random access to branch entries is required.
04945    // If random access to only a few branches is required, you should
04946    // call directly TBranch::LoadBaskets.
04947 
04948    if (maxmemory > 0) SetMaxVirtualSize(maxmemory);
04949 
04950    TIter next(GetListOfLeaves());
04951    TLeaf *leaf;
04952    Int_t nimported = 0;
04953    while ((leaf=(TLeaf*)next())) {
04954       nimported += leaf->GetBranch()->LoadBaskets();//break;
04955    }
04956    return nimported;
04957 }
04958 
04959 //______________________________________________________________________________
04960 Long64_t TTree::LoadTree(Long64_t entry)
04961 {
04962    // Set current entry.
04963    //
04964    // Returns -2 if entry does not exist (just as TChain::LoadTree()).
04965    //
04966    // Note: This function is overloaded in TChain.
04967    //
04968 
04969    // We already have been visited while recursively looking
04970    // through the friends tree, let return
04971    if (kLoadTree & fFriendLockStatus) {
04972       // We need to return a negative value to avoid a circular list of friend
04973       // to think that there is always an entry somewhere in the lisst.
04974       return -1;
04975    }
04976 
04977    if (fNotify) {
04978       if (fReadEntry < 0) {
04979          fNotify->Notify();
04980       }
04981    }
04982    fReadEntry = entry;
04983 
04984    Bool_t friendHasEntry = kFALSE;
04985    if (fFriends) {
04986       // Set current entry in friends as well.
04987       //
04988       // An alternative would move this code to each of the
04989       // functions calling LoadTree (and to overload a few more).
04990       Bool_t needUpdate = kFALSE;
04991       {
04992          // This scope is need to insure the lock is released at the right time
04993          TIter nextf(fFriends);
04994          TFriendLock lock(this, kLoadTree);
04995          TFriendElement* fe = 0;
04996          while ((fe = (TFriendElement*) nextf())) {
04997             if (fe->TestBit(TFriendElement::kFromChain)) {
04998                // This friend element was added by the chain that owns this
04999                // tree, the chain will deal with loading the correct entry.
05000                continue;
05001             }
05002             TTree* friendTree = fe->GetTree();
05003             if (friendTree->IsA() == TTree::Class()) {
05004                // Friend is actually a tree.
05005                if (friendTree->LoadTreeFriend(entry, this) >= 0) {
05006                   friendHasEntry = kTRUE;
05007                }
05008             } else {
05009                // Friend is actually a chain.
05010                // FIXME: This logic should be in the TChain override.
05011                Int_t oldNumber = friendTree->GetTreeNumber();
05012                if (friendTree->LoadTreeFriend(entry, this) >= 0) {
05013                   friendHasEntry = kTRUE;
05014                }
05015                Int_t newNumber = friendTree->GetTreeNumber();
05016                if (oldNumber != newNumber) {
05017                   // We can not just compare the tree pointers because they could be reused.
05018                   // So we compare the tree number instead.
05019                   needUpdate = kTRUE;
05020                }
05021             }
05022          } // for each friend
05023       }
05024       if (needUpdate) {
05025          //update list of leaves in all TTreeFormula of the TTreePlayer (if any)
05026          if (fPlayer) {
05027             fPlayer->UpdateFormulaLeaves();
05028          }
05029          //Notify user if requested
05030          if (fNotify) {
05031             fNotify->Notify();
05032          }
05033       }
05034    }
05035 
05036    if ((fReadEntry >= fEntries) && !friendHasEntry) {
05037       fReadEntry = -1;
05038       return -2;
05039    }
05040    return fReadEntry;
05041 }
05042 
05043 //______________________________________________________________________________
05044 Long64_t TTree::LoadTreeFriend(Long64_t entry, TTree* masterTree)
05045 {
05046    // Load entry on behalf of our master tree, we may use an index.
05047    //
05048    // Called by LoadTree() when the masterTree looks for the entry
05049    // number in a friend tree (us) corresponding to the passed entry
05050    // number in the masterTree.
05051    //
05052    // If we have no index, our entry number and the masterTree entry
05053    // number are the same.
05054    //
05055    // If we *do* have an index, we must find the (major, minor) value pair
05056    // in masterTree to locate our corresponding entry.
05057    //
05058 
05059    if (!fTreeIndex) {
05060       return LoadTree(entry);
05061    }
05062    return LoadTree(fTreeIndex->GetEntryNumberFriend(masterTree));
05063 }
05064 
05065 //______________________________________________________________________________
05066 Int_t TTree::MakeClass(const char* classname, Option_t* option)
05067 {
05068    // Generate a skeleton analysis class for this tree.
05069    //
05070    // The following files are produced: classname.h and classname.C.
05071    // If classname is 0, classname will be called "nameoftree".
05072    //
05073    // The generated code in classname.h includes the following:
05074    //    - Identification of the original tree and the input file name.
05075    //    - Definition of an analysis class (data members and member functions).
05076    //    - The following member functions:
05077    //       - constructor (by default opening the tree file),
05078    //       - GetEntry(Long64_t entry),
05079    //       - Init(TTree* tree) to initialize a new TTree,
05080    //       - Show(Long64_t entry) to read and dump entry.
05081    //
05082    // The generated code in classname.C includes only the main
05083    // analysis function Loop.
05084    //
05085    // To use this function:
05086    //    - Open your tree file (eg: TFile f("myfile.root");)
05087    //    - T->MakeClass("MyClass");
05088    // where T is the name of the TTree in file myfile.root,
05089    // and MyClass.h, MyClass.C the name of the files created by this function.
05090    // In a ROOT session, you can do:
05091    //    root > .L MyClass.C
05092    //    root > MyClass* t = new MyClass;
05093    //    root > t->GetEntry(12); // Fill data members of t with entry number 12.
05094    //    root > t->Show();       // Show values of entry 12.
05095    //    root > t->Show(16);     // Read and show values of entry 16.
05096    //    root > t->Loop();       // Loop on all entries.
05097    //
05098    //  NOTE: Do not use the code generated for a single TTree which is part
05099    //        of a TChain to process that entire TChain.  The maximum dimensions
05100    //        calculated for arrays on the basis of a single TTree from the TChain
05101    //        might be (will be!) too small when processing all of the TTrees in
05102    //        the TChain.  You must use myChain.MakeClass() to generate the code,
05103    //        not myTree.MakeClass(...).
05104    //
05105 
05106    GetPlayer();
05107    if (!fPlayer) {
05108       return 0;
05109    }
05110    return fPlayer->MakeClass(classname, option);
05111 }
05112 
05113 //______________________________________________________________________________
05114 Int_t TTree::MakeCode(const char* filename)
05115 {
05116    // Generate a skeleton function for this tree.
05117    //
05118    // The function code is written on filename.
05119    // If filename is 0, filename will be called nameoftree.C
05120    //
05121    // The generated code includes the following:
05122    //    - Identification of the original Tree and Input file name,
05123    //    - Opening the Tree file,
05124    //    - Declaration of Tree variables,
05125    //    - Setting of branches addresses,
05126    //    - A skeleton for the entry loop.
05127    //
05128    // To use this function:
05129    //    - Open your Tree file (eg: TFile f("myfile.root");)
05130    //    - T->MakeCode("MyAnalysis.C");
05131    // where T is the name of the TTree in file myfile.root
05132    // and MyAnalysis.C the name of the file created by this function.
05133    //
05134    // NOTE: Since the implementation of this function, a new and better
05135    //       function TTree::MakeClass() has been developed.
05136 
05137    Warning("MakeCode", "MakeCode is obsolete. Use MakeClass or MakeSelector instead");
05138 
05139    GetPlayer();
05140    if (!fPlayer) return 0;
05141    return fPlayer->MakeCode(filename);
05142 }
05143 
05144 //______________________________________________________________________________
05145 Int_t TTree::MakeProxy(const char* proxyClassname, const char* macrofilename, const char* cutfilename, const char* option, Int_t maxUnrolling)
05146 {
05147    // Generate a skeleton analysis class for this Tree using TBranchProxy.
05148    //
05149    // TBranchProxy is the base of a class hierarchy implementing an
05150    // indirect access to the content of the branches of a TTree.
05151    //
05152    // "proxyClassname" is expected to be of the form:
05153    //    [path/]fileprefix
05154    // The skeleton will then be generated in the file:
05155    //    fileprefix.h
05156    // located in the current directory or in 'path/' if it is specified.
05157    // The class generated will be named 'fileprefix'
05158    //
05159    // "macrofilename" and optionally "cutfilename" are expected to point
05160    // to source files which will be included by the generated skeleton.
05161    // Method of the same name as the file(minus the extension and path)
05162    // will be called by the generated skeleton's Process method as follow:
05163    //    [if (cutfilename())] htemp->Fill(macrofilename());
05164    //
05165    // "option" can be used select some of the optional features during
05166    // the code generation.  The possible options are:
05167    //    nohist : indicates that the generated ProcessFill should not
05168    //             fill the histogram.
05169    //
05170    // 'maxUnrolling' controls how deep in the class hierachy does the
05171    // system 'unroll' classes that are not split.  Unrolling a class
05172    // allows direct access to its data members (this emulates the behavior
05173    // of TTreeFormula).
05174    //
05175    // The main features of this skeleton are:
05176    //
05177    //    * on-demand loading of branches
05178    //    * ability to use the 'branchname' as if it was a data member
05179    //    * protection against array out-of-bounds errors
05180    //    * ability to use the branch data as an object (when the user code is available)
05181    //
05182    // For example with Event.root, if
05183    //    Double_t somePx = fTracks.fPx[2];
05184    // is executed by one of the method of the skeleton,
05185    // somePx will updated with the current value of fPx of the 3rd track.
05186    //
05187    // Both macrofilename and the optional cutfilename are expected to be
05188    // the name of source files which contain at least a free standing
05189    // function with the signature:
05190    //     x_t macrofilename(); // i.e function with the same name as the file
05191    // and
05192    //     y_t cutfilename();   // i.e function with the same name as the file
05193    //
05194    // x_t and y_t needs to be types that can convert respectively to a double
05195    // and a bool (because the skeleton uses:
05196    //     if (cutfilename()) htemp->Fill(macrofilename());
05197    //
05198    // These two functions are run in a context such that the branch names are
05199    // available as local variables of the correct (read-only) type.
05200    //
05201    // Note that if you use the same 'variable' twice, it is more efficient
05202    // to 'cache' the value. For example
05203    //   Int_t n = fEventNumber; // Read fEventNumber
05204    //   if (n<10 || n>10) { ... }
05205    // is more efficient than
05206    //   if (fEventNumber<10 || fEventNumber>10)
05207    //
05208    // Also, optionally, the generated selector will also call methods named
05209    // macrofilename_methodname in each of 6 main selector methods if the method
05210    // macrofilename_methodname exist (Where macrofilename is stripped of its
05211    // extension).
05212    //
05213    // Concretely, with the script named h1analysisProxy.C,
05214    //
05215    // The method         calls the method (if it exist)
05216    // Begin           -> void h1analysisProxy_Begin(TTree*);
05217    // SlaveBegin      -> void h1analysisProxy_SlaveBegin(TTree*);
05218    // Notify          -> Bool_t h1analysisProxy_Notify();
05219    // Process         -> Bool_t h1analysisProxy_Process(Long64_t);
05220    // SlaveTerminate  -> void h1analysisProxy_SlaveTerminate();
05221    // Terminate       -> void h1analysisProxy_Terminate();
05222    //
05223    // If a file name macrofilename.h (or .hh, .hpp, .hxx, .hPP, .hXX) exist
05224    // it is included before the declaration of the proxy class.  This can
05225    // be used in particular to insure that the include files needed by
05226    // the macro file are properly loaded.
05227    //
05228    // The default histogram is accessible via the variable named 'htemp'.
05229    //
05230    // If the library of the classes describing the data in the branch is
05231    // loaded, the skeleton will add the needed #include statements and
05232    // give the ability to access the object stored in the branches.
05233    //
05234    // To draw px using the file hsimple.root (generated by the
05235    // hsimple.C tutorial), we need a file named hsimple.cxx:
05236    //
05237    //     double hsimple() {
05238    //        return px;
05239    //     }
05240    //
05241    // MakeProxy can then be used indirectly via the TTree::Draw interface
05242    // as follow:
05243    //     new TFile("hsimple.root")
05244    //     ntuple->Draw("hsimple.cxx");
05245    //
05246    // A more complete example is available in the tutorials directory:
05247    //   h1analysisProxy.cxx , h1analysProxy.h and h1analysisProxyCut.C
05248    // which reimplement the selector found in h1analysis.C
05249 
05250    GetPlayer();
05251    if (!fPlayer) return 0;
05252    return fPlayer->MakeProxy(proxyClassname,macrofilename,cutfilename,option,maxUnrolling);
05253 }
05254 
05255 //______________________________________________________________________________
05256 Int_t TTree::MakeSelector(const char* selector)
05257 {
05258    // Generate skeleton selector class for this tree.
05259    //
05260    // The following files are produced: selector.h and selector.C.
05261    // If selector is 0, the selector will be called "nameoftree".
05262    //
05263    // The generated code in selector.h includes the following:
05264    //    - Identification of the original Tree and Input file name
05265    //    - Definition of selector class (data and functions)
05266    //    - The following class functions:
05267    //       - constructor and destructor
05268    //       - void    Begin(TTree *tree)
05269    //       - void    SlaveBegin(TTree *tree)
05270    //       - void    Init(TTree *tree)
05271    //       - Bool_t  Notify()
05272    //       - Bool_t  Process(Long64_t entry)
05273    //       - void    Terminate()
05274    //       - void    SlaveTerminate()
05275    //
05276    // The class selector derives from TSelector.
05277    // The generated code in selector.C includes empty functions defined above.
05278    //
05279    // To use this function:
05280    //    - connect your Tree file (eg: TFile f("myfile.root");)
05281    //    - T->MakeSelector("myselect");
05282    // where T is the name of the Tree in file myfile.root
05283    // and myselect.h, myselect.C the name of the files created by this function.
05284    // In a ROOT session, you can do:
05285    //    root > T->Process("myselect.C")
05286 
05287    return MakeClass(selector, "selector");
05288 }
05289 
05290 //______________________________________________________________________________
05291 Bool_t TTree::MemoryFull(Int_t nbytes)
05292 {
05293    // Check if adding nbytes to memory we are still below MaxVirtualsize.
05294 
05295    if ((fTotalBuffers + nbytes) < fMaxVirtualSize) {
05296       return kFALSE;
05297    }
05298    return kTRUE;
05299 }
05300 
05301 //______________________________________________________________________________
05302 TTree* TTree::MergeTrees(TList* li, Option_t* /* option */)
05303 {
05304    // Static function merging the trees in the TList into a new tree.
05305    //
05306    // Trees in the list can be memory or disk-resident trees.
05307    // The new tree is created in the current directory (memory if gROOT).
05308    //
05309 
05310    if (!li) return 0;
05311    TIter next(li);
05312    TTree *newtree = 0;
05313    TObject *obj;
05314 
05315    while ((obj=next())) {
05316       if (!obj->InheritsFrom(TTree::Class())) continue;
05317       TTree *tree = (TTree*)obj;
05318       Long64_t nentries = tree->GetEntries();
05319       if (nentries == 0) continue;
05320       if (!newtree) {
05321          newtree = (TTree*)tree->CloneTree();
05322 
05323          // Once the cloning is done, separate the trees,
05324          // to avoid as many side-effects as possible
05325          tree->GetListOfClones()->Remove(newtree);
05326          tree->ResetBranchAddresses();
05327          newtree->ResetBranchAddresses();
05328          continue;
05329       }
05330 
05331       newtree->CopyAddresses(tree);
05332       for (Long64_t i=0;i<nentries;i++) {
05333          tree->GetEntry(i);
05334          newtree->Fill();
05335       }
05336       tree->ResetBranchAddresses(); // Disconnect from new tree.
05337       if (newtree->GetTreeIndex()) {
05338          newtree->GetTreeIndex()->Append(tree->GetTreeIndex(),kTRUE);
05339       }
05340    }
05341    if (newtree && newtree->GetTreeIndex()) {
05342       newtree->GetTreeIndex()->Append(0,kFALSE); // Force the sorting
05343    }
05344    return newtree;
05345 }
05346 
05347 //______________________________________________________________________________
05348 Long64_t TTree::Merge(TCollection* li, Option_t* /* option */)
05349 {
05350    // Merge the trees in the TList into this tree.
05351    //
05352    // Returns the total number of entries in the merged tree.
05353    //
05354 
05355    if (!li) return 0;
05356    TIter next(li);
05357    TTree *tree;
05358    while ((tree = (TTree*)next())) {
05359       if (tree==this) continue;
05360       if (!tree->InheritsFrom(TTree::Class())) {
05361          Error("Add","Attempt to add object of class: %s to a %s", tree->ClassName(), ClassName());
05362          return -1;
05363       }
05364 
05365       Long64_t nentries = tree->GetEntries();
05366       if (nentries == 0) continue;
05367 
05368       CopyAddresses(tree);
05369       for (Long64_t i=0; i<nentries ; i++) {
05370          tree->GetEntry(i);
05371          Fill();
05372       }
05373       if (GetTreeIndex()) {
05374          GetTreeIndex()->Append(tree->GetTreeIndex(),kTRUE);
05375       }
05376       tree->ResetBranchAddresses();
05377    }
05378    if (GetTreeIndex()) {
05379       GetTreeIndex()->Append(0,kFALSE); // Force the sorting
05380    }
05381    return GetEntries();
05382 }
05383 
05384 //______________________________________________________________________________
05385 Bool_t TTree::Notify()
05386 {
05387    // Function called when loading a new class library.
05388 
05389    TIter next(GetListOfLeaves());
05390    TLeaf* leaf = 0;
05391    while ((leaf = (TLeaf*) next())) {
05392       leaf->Notify();
05393       leaf->GetBranch()->Notify();
05394    }
05395    return kTRUE;
05396 }
05397 
05398 //______________________________________________________________________________
05399 void TTree::OptimizeBaskets(ULong64_t maxMemory, Float_t minComp, Option_t *option)
05400 {
05401    //This function may be called after having filled some entries in a Tree
05402    //Using the information in the existing branch buffers, it will reassign
05403    //new branch buffer sizes to optimize time and memory.
05404    //
05405    //The function computes the best values for branch buffer sizes such that
05406    //the total buffer sizes is less than maxMemory and nearby entries written
05407    //at the same time.
05408    //In case the branch compression factor for the data written so far is less
05409    //than compMin, the compression is disabled.
05410    //
05411    //if option ="d" an analysis report is printed.
05412 
05413    //Flush existing baskets if the file is writable
05414    if (this->GetDirectory()->IsWritable()) this->FlushBaskets();
05415 
05416    TString opt( option );
05417    opt.ToLower();
05418    Bool_t pDebug = opt.Contains("d");
05419    TObjArray *leaves = this->GetListOfLeaves();
05420    Int_t nleaves = leaves->GetEntries();
05421    Double_t treeSize = (Double_t)this->GetTotBytes();
05422 
05423    if (nleaves == 0 || treeSize == 0) {
05424       // We're being called too early, we really have nothing to do ...
05425       return;
05426    }
05427    Double_t aveSize = treeSize/nleaves;
05428    UInt_t bmin = 512;
05429    UInt_t bmax = 256000;
05430    Double_t memFactor = 1;
05431    Int_t i, oldMemsize,newMemsize,oldBaskets,newBaskets;
05432    //we make two passes
05433    //one pass to compute the relative branch buffer sizes
05434    //a second pass to compute the absolute values
05435    for (Int_t pass =0;pass<2;pass++) {
05436       oldMemsize = 0;  //to count size of baskets in memory with old buffer size
05437       newMemsize = 0;  //to count size of baskets in memory with new buffer size
05438       oldBaskets = 0;  //to count number of baskets with old buffer size
05439       newBaskets = 0;  //to count number of baskets with new buffer size
05440       for (i=0;i<nleaves;i++) {
05441          TLeaf *leaf = (TLeaf*)leaves->At(i);
05442          TBranch *branch = leaf->GetBranch();
05443          Double_t totBytes = (Double_t)branch->GetTotBytes();
05444          Double_t idealFactor = totBytes/aveSize;
05445          Int_t oldBsize = branch->GetBasketSize();
05446          oldMemsize += oldBsize;
05447          oldBaskets += 1+Int_t(totBytes/oldBsize);
05448          Int_t nb = branch->GetListOfBranches()->GetEntries();
05449          if (nb > 0) {
05450             newBaskets += 1+Int_t(totBytes/oldBsize);
05451             continue;
05452          }
05453          Double_t bsize = oldBsize*idealFactor*memFactor; //bsize can be very large !
05454          if (bsize < 0) bsize = bmax;
05455          if (bsize > bmax) bsize = bmax;
05456          UInt_t newBsize = UInt_t(bsize);
05457          newBsize = newBsize - newBsize%512;
05458          if (newBsize < bmin) newBsize = bmin;
05459          if (newBsize > 10000000) newBsize = bmax;
05460          if (pass) {
05461             if (pDebug) printf("Changing buffer size from %6d to %6d bytes for %s\n",oldBsize,newBsize,branch->GetName());
05462             branch->SetBasketSize(newBsize);
05463          }
05464          newMemsize += newBsize;
05465          newBaskets += 1+Int_t(totBytes/newBsize);
05466          if (pass == 0) continue;
05467          //Reset the compression level in case the compression factor is small
05468          Double_t comp = 1;
05469          if (branch->GetZipBytes() > 0) comp = totBytes/Double_t(branch->GetZipBytes());
05470          if (comp > 1 && comp < minComp) {
05471             if (pDebug) printf("Disabling compression for branch : %s\n",branch->GetName());
05472             branch->SetCompressionLevel(0);
05473          }
05474       }
05475       memFactor = Double_t(maxMemory)/Double_t(newMemsize);
05476       if (memFactor > 100) memFactor = 100;
05477       Double_t bmin_new = bmin*memFactor;
05478       Double_t bmax_new = bmax*memFactor;
05479       static const UInt_t hardmax = 1*1024*1024*1024; // Really, really never give more than 1Gb to a single buffer.
05480       bmin = (bmin_new > hardmax) ? hardmax : (UInt_t)bmin_new;
05481       bmax = (bmax_new > hardmax) ? bmin : (UInt_t)bmax_new;         
05482    }
05483    if (pDebug) {
05484       printf("oldMemsize = %d,  newMemsize = %d\n",oldMemsize, newMemsize);
05485       printf("oldBaskets = %d,  newBaskets = %d\n",oldBaskets, newBaskets);
05486    }
05487 }
05488 
05489 //______________________________________________________________________________
05490 TPrincipal* TTree::Principal(const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
05491 {
05492    // Interface to the Principal Components Analysis class.
05493    //
05494    //   Create an instance of TPrincipal
05495    //   Fill it with the selected variables
05496    //   if option "n" is specified, the TPrincipal object is filled with
05497    //                 normalized variables.
05498    //   If option "p" is specified, compute the principal components
05499    //   If option "p" and "d" print results of analysis
05500    //   If option "p" and "h" generate standard histograms
05501    //   If option "p" and "c" generate code of conversion functions
05502    //   return a pointer to the TPrincipal object. It is the user responsability
05503    //   to delete this object.
05504    //   The option default value is "np"
05505    //
05506    //   see TTree::Draw for explanation of the other parameters.
05507    //
05508    //   The created object is  named "principal" and a reference to it
05509    //   is added to the list of specials Root objects.
05510    //   you can retrieve a pointer to the created object via:
05511    //      TPrincipal *principal =
05512    //        (TPrincipal*)gROOT->GetListOfSpecials()->FindObject("principal");
05513    //
05514 
05515    GetPlayer();
05516    if (fPlayer) {
05517       return fPlayer->Principal(varexp, selection, option, nentries, firstentry);
05518    }
05519    return 0;
05520 }
05521 
05522 //______________________________________________________________________________
05523 void TTree::Print(Option_t* option) const
05524 {
05525    // Print a summary of the tree contents.
05526    //
05527    // If option contains "all" friend trees are also printed.
05528    // If option contains "toponly" only the top level branches are printed.
05529    //
05530    // Wildcarding can be used to print only a subset of the branches, e.g.,
05531    // T.Print("Elec*") will print all branches with name starting with "Elec".
05532 
05533    // We already have been visited while recursively looking
05534    // through the friends tree, let's return.
05535    if (kPrint & fFriendLockStatus) {
05536       return;
05537    }
05538    Int_t s = 0;
05539    Int_t skey = 0;
05540    if (fDirectory) {
05541       TKey* key = fDirectory->GetKey(GetName());
05542       if (key) {
05543          skey = key->GetKeylen();
05544          s = key->GetNbytes();
05545       }
05546    }
05547    Long64_t total = skey;
05548    if (fZipBytes > 0) {
05549       total += fTotBytes;
05550    }
05551    TBufferFile b(TBuffer::kWrite, 10000);
05552    TTree::Class()->WriteBuffer(b, (TTree*) this);
05553    total += b.Length();
05554    Long64_t file = fZipBytes + s;
05555    Float_t cx = 1;
05556    if (fZipBytes) {
05557       cx = (fTotBytes + 0.00001) / fZipBytes;
05558    }
05559    Printf("******************************************************************************");
05560    Printf("*Tree    :%-10s: %-54s *", GetName(), GetTitle());
05561    Printf("*Entries : %8lld : Total = %15lld bytes  File  Size = %10lld *", fEntries, total, file);
05562    Printf("*        :          : Tree compression factor = %6.2f                       *", cx);
05563    Printf("******************************************************************************");
05564    Int_t nl = const_cast<TTree*>(this)->GetListOfLeaves()->GetEntries();
05565    Int_t l;
05566    TBranch* br = 0;
05567    TLeaf* leaf = 0;
05568    if (strstr(option, "toponly")) {
05569       Long64_t *count = new Long64_t[nl];
05570       Int_t keep =0;
05571       for (l=0;l<nl;l++) {
05572          leaf = (TLeaf *)const_cast<TTree*>(this)->GetListOfLeaves()->At(l);
05573          br   = leaf->GetBranch();
05574          if (strchr(br->GetName(),'.')) {
05575             count[l] = -1;
05576             count[keep] += br->GetZipBytes();
05577          } else {
05578             keep = l;
05579             count[keep]  = br->GetZipBytes();
05580          }
05581       }
05582       for (l=0;l<nl;l++) {
05583          if (count[l] < 0) continue;
05584          leaf = (TLeaf *)const_cast<TTree*>(this)->GetListOfLeaves()->At(l);
05585          br   = leaf->GetBranch();
05586          printf("branch: %-20s %9lld\n",br->GetName(),count[l]);
05587       }
05588       delete [] count;
05589    } else {
05590       TString reg = "*";
05591       if (strlen(option) && strchr(option,'*')) reg = option;
05592       TRegexp re(reg,kTRUE);
05593       TIter next(const_cast<TTree*>(this)->GetListOfBranches());
05594       TBranch::ResetCount();
05595       while ((br= (TBranch*)next())) {
05596          TString st = br->GetName();
05597          st.ReplaceAll("/","_");
05598          if (st.Index(re) == kNPOS) continue;
05599          br->Print(option);
05600       }
05601    }
05602 
05603    //print TRefTable (if one)
05604    if (fBranchRef) fBranchRef->Print(option);
05605 
05606    //print friends if option "all"
05607    if (!fFriends || !strstr(option,"all")) return;
05608    TIter nextf(fFriends);
05609    TFriendLock lock(const_cast<TTree*>(this),kPrint);
05610    TFriendElement *fr;
05611    while ((fr = (TFriendElement*)nextf())) {
05612       TTree * t = fr->GetTree();
05613       if (t) t->Print(option);
05614    }
05615 }
05616 
05617 //______________________________________________________________________________
05618 void TTree::PrintCacheStats(Option_t* option) const
05619 {
05620    // print statistics about the TreeCache for this tree, like
05621    //   ******TreeCache statistics for file: cms2.root ******
05622    //   Reading 73921562 bytes in 716 transactions
05623    //   Average transaction = 103.242405 Kbytes
05624    //   Number of blocks in current cache: 202, total size : 6001193
05625    //
05626    // if option = "a" the list of blocks in the cache is printed
05627 
05628    TFile *f = GetCurrentFile();
05629    if (!f) return;
05630    TTreeCache *tc = (TTreeCache*)f->GetCacheRead();
05631    if (tc) tc->Print(option);
05632 }
05633 
05634 //______________________________________________________________________________
05635 Long64_t TTree::Process(const char* filename, Option_t* option, Long64_t nentries, Long64_t firstentry)
05636 {
05637    // Process this tree executing the TSelector code in the specified filename.
05638    // The return value is -1 in case of error and TSelector::GetStatus() in
05639    // in case of success.
05640    //
05641    // The code in filename is loaded (interpreted or compiled, see below),
05642    // filename must contain a valid class implementation derived from TSelector,
05643    // where TSelector has the following member functions:
05644    //
05645    //    Begin():        called everytime a loop on the tree starts,
05646    //                    a convenient place to create your histograms.
05647    //    SlaveBegin():   called after Begin(), when on PROOF called only on the
05648    //                    slave servers.
05649    //    Process():      called for each event, in this function you decide what
05650    //                    to read and fill your histograms.
05651    //    SlaveTerminate: called at the end of the loop on the tree, when on PROOF
05652    //                    called only on the slave servers.
05653    //    Terminate():    called at the end of the loop on the tree,
05654    //                    a convenient place to draw/fit your histograms.
05655    //
05656    // If filename is of the form file.C, the file will be interpreted.
05657    // If filename is of the form file.C++, the file file.C will be compiled
05658    // and dynamically loaded.
05659    // If filename is of the form file.C+, the file file.C will be compiled
05660    // and dynamically loaded. At next call, if file.C is older than file.o
05661    // and file.so, the file.C is not compiled, only file.so is loaded.
05662    //
05663    //  NOTE1
05664    //  It may be more interesting to invoke directly the other Process function
05665    //  accepting a TSelector* as argument.eg
05666    //     MySelector *selector = (MySelector*)TSelector::GetSelector(filename);
05667    //     selector->CallSomeFunction(..);
05668    //     mytree.Process(selector,..);
05669    //
05670    //  NOTE2
05671    //  One should not call this function twice with the same selector file
05672    //  in the same script. If this is required, proceed as indicated in NOTE1,
05673    //  by getting a pointer to the corresponding TSelector,eg
05674    //    workaround 1
05675    //    ------------
05676    //void stubs1() {
05677    //   TSelector *selector = TSelector::GetSelector("h1test.C");
05678    //   TFile *f1 = new TFile("stubs_nood_le1.root");
05679    //   TTree *h1 = (TTree*)f1->Get("h1");
05680    //   h1->Process(selector);
05681    //   TFile *f2 = new TFile("stubs_nood_le1_coarse.root");
05682    //   TTree *h2 = (TTree*)f2->Get("h1");
05683    //   h2->Process(selector);
05684    //}
05685    //  or use ACLIC to compile the selector
05686    //   workaround 2
05687    //   ------------
05688    //void stubs2() {
05689    //   TFile *f1 = new TFile("stubs_nood_le1.root");
05690    //   TTree *h1 = (TTree*)f1->Get("h1");
05691    //   h1->Process("h1test.C+");
05692    //   TFile *f2 = new TFile("stubs_nood_le1_coarse.root");
05693    //   TTree *h2 = (TTree*)f2->Get("h1");
05694    //   h2->Process("h1test.C+");
05695    //}
05696 
05697    GetPlayer();
05698    if (fPlayer) {
05699       return fPlayer->Process(filename, option, nentries, firstentry);
05700    }
05701    return -1;
05702 }
05703 
05704 //______________________________________________________________________________
05705 Long64_t TTree::Process(TSelector* selector, Option_t* option, Long64_t nentries, Long64_t firstentry)
05706 {
05707    // Process this tree executing the code in the specified selector.
05708    // The return value is -1 in case of error and TSelector::GetStatus() in
05709    // in case of success.
05710    //
05711    //   The TSelector class has the following member functions:
05712    //
05713    //    Begin():        called everytime a loop on the tree starts,
05714    //                    a convenient place to create your histograms.
05715    //    SlaveBegin():   called after Begin(), when on PROOF called only on the
05716    //                    slave servers.
05717    //    Process():      called for each event, in this function you decide what
05718    //                    to read and fill your histograms.
05719    //    SlaveTerminate: called at the end of the loop on the tree, when on PROOF
05720    //                    called only on the slave servers.
05721    //    Terminate():    called at the end of the loop on the tree,
05722    //                    a convenient place to draw/fit your histograms.
05723    //
05724    //  If the Tree (Chain) has an associated EventList, the loop is on the nentries
05725    //  of the EventList, starting at firstentry, otherwise the loop is on the
05726    //  specified Tree entries.
05727 
05728    GetPlayer();
05729    if (fPlayer) {
05730       return fPlayer->Process(selector, option, nentries, firstentry);
05731    }
05732    return -1;
05733 }
05734 
05735 //______________________________________________________________________________
05736 Long64_t TTree::Project(const char* hname, const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
05737 {
05738    // Make a projection of a tree using selections.
05739    //
05740    // Depending on the value of varexp (described in Draw) a 1-D, 2-D, etc.,
05741    // projection of the tree will be filled in histogram hname.
05742    // Note that the dimension of hname must match with the dimension of varexp.
05743    //
05744 
05745    TString var;
05746    var.Form("%s>>%s", varexp, hname);
05747    TString opt("goff");
05748    if (option) {
05749       opt.Form("%sgoff", option);
05750    }
05751    Long64_t nsel = Draw(var, selection, opt, nentries, firstentry);
05752    return nsel;
05753 }
05754 
05755 //______________________________________________________________________________
05756 TSQLResult* TTree::Query(const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
05757 {
05758    // Loop over entries and return a TSQLResult object containing entries following selection.
05759 
05760    GetPlayer();
05761    if (fPlayer) {
05762       return fPlayer->Query(varexp, selection, option, nentries, firstentry);
05763    }
05764    return 0;
05765 }
05766 
05767 //______________________________________________________________________________
05768 Long64_t TTree::ReadFile(const char* filename, const char* branchDescriptor)
05769 {
05770    // Create or simply read branches from filename.
05771    //
05772    // if branchDescriptor = "" (default), it is assumed that the Tree descriptor
05773    //    is given in the first line of the file with a syntax like
05774    //     A/D:Table[2]/F:Ntracks/I:astring/C
05775    //  otherwise branchDescriptor must be specified with the above syntax.
05776    //  -If the type of the first variable is not specified, it is assumed to be "/F"
05777    //  -if the type of any other variable is not specified, the type of the previous
05778    //    variable is assumed. eg
05779    //      x:y:z      (all variables are assumed of type "F"
05780    //      x/D:y:z    (all variables are of type "D"
05781    //      x:y/D:z    (x is type "F", y and z of type "D"
05782    //  -If the type is a string of characters. This will read
05783    //  subsequent characters until a whitespace is found (whitespace
05784    //  characters are considered to be blank, newline and tab).
05785    //
05786    // Lines in the input file starting with "#" are ignored.
05787    // This function will read and ignore any whitespace characters
05788    // (this includes blank spaces and the newline and tab characters).
05789    //
05790    // A TBranch object is created for each variable in the expression.
05791    // The total number of rows read from the file is returned.
05792    //
05793    // FILLING a TTree WITH MULTIPLE INPUT TEXT FILES
05794    // ----------------------------------------------
05795    // To fill a TTree with multiple input text files, proceed as indicated above
05796    // for the first input file and omit the second argument for subsequent calls
05797    //    T.ReadFile("file1.dat","branch descriptor");
05798    //    T.ReadFile("file2.dat");
05799 
05800    std::ifstream in;
05801    in.open(filename);
05802    if (!in.good()) {
05803       Error("ReadFile","Cannot open file: %s",filename);
05804       return 0;
05805    }
05806    return ReadStream(in, branchDescriptor);
05807 }
05808 
05809 //______________________________________________________________________________
05810 Long64_t TTree::ReadStream(istream& inputStream, const char *branchDescriptor)
05811 {
05812    // Create or simply read branches from an input stream.
05813    //
05814    // See reference information for TTree::ReadFile
05815 
05816    gTree = this;
05817    std::istream& in = inputStream;
05818    TBranch *branch;
05819    Int_t nbranches = fBranches.GetEntries();
05820    if (nbranches == 0) {
05821       char *bdname = new char[4000];
05822       char *bd = new char[100000];
05823       Int_t nch = 0;
05824       if (branchDescriptor) nch = strlen(branchDescriptor);
05825       // branch Descriptor is null, read its definition from the first line in the file
05826       if (!nch) {
05827          in >> bd;
05828          if (!in.good()) {
05829             delete [] bdname;
05830             delete [] bd;
05831             Error("ReadStream","Error reading stream");
05832             return 0;
05833          }
05834          in.ignore(8192,'\n');
05835          nch = strlen(bd);
05836       } else {
05837          strlcpy(bd,branchDescriptor,100000);
05838       }
05839 
05840       //parse the branch descriptor and create a branch for each element
05841       //separated by ":"
05842       void *address = &bd[90000];
05843       char *bdcur = bd;
05844       TString desc="", olddesc="F";
05845       while (bdcur) {
05846          char *colon = strchr(bdcur,':');
05847          if (colon) *colon = 0;
05848          strlcpy(bdname,bdcur,4000);
05849          char *slash = strchr(bdname,'/');
05850          if (slash) {
05851             *slash = 0;
05852             desc = bdcur;
05853             olddesc = slash+1;
05854          } else {
05855             desc = Form("%s/%s",bdname,olddesc.Data());
05856          }
05857          char *bracket = strchr(bdname,'[');
05858          if (bracket) {
05859             *bracket = 0;
05860          }
05861          branch = new TBranch(this,bdname,address,desc.Data(),32000);
05862          if (branch->IsZombie()) {
05863             delete branch;
05864             Warning("ReadStream","Illegal branch definition: %s",bdcur);
05865          } else {
05866             fBranches.Add(branch);
05867             branch->SetAddress(0);
05868          }
05869          if (!colon)break;
05870          bdcur = colon+1;
05871       }
05872       delete [] bdname;
05873       delete [] bd;
05874 
05875    }
05876 
05877    //loop on all lines in the file
05878    nbranches = fBranches.GetEntries();
05879    Bool_t status = kTRUE;
05880    Long64_t nlines = 0;
05881    while(1) {
05882 
05883       while (isspace(in.peek())) {
05884          in.get();
05885       }
05886       if ( in.peek() != '#' ) {
05887          //loop on branches and read the branch values into their buffer
05888          for (Int_t i=0;i<nbranches;i++) {
05889             branch = (TBranch*)fBranches.At(i);
05890             TLeaf *leaf = (TLeaf*)branch->GetListOfLeaves()->At(0);
05891             leaf->ReadValue(in);
05892             if (in.eof()) return nlines;
05893             status = in.good();
05894             if (!status) {
05895                Warning("ReadStream","Illegal value after line %lld\n",nlines);
05896                in.clear();
05897                break;
05898             }
05899          }
05900          //we are now ready to fill the tree
05901          if (status) {
05902             Fill();
05903             nlines++;
05904          }
05905       }
05906       in.ignore(8192,'\n');
05907    }
05908 
05909    return nlines;
05910 }
05911 
05912 //______________________________________________________________________________
05913 void TTree::RecursiveRemove(TObject *obj)
05914 {
05915    // Make sure that obj (which is being deleted or will soon be) is no
05916    // longer referenced by this TTree.
05917 
05918    if (obj == fEventList) {
05919       fEventList = 0;
05920    }
05921    if (obj == fEntryList) {
05922       fEntryList = 0;
05923    }
05924    if (fUserInfo) {
05925       fUserInfo->RecursiveRemove(obj);
05926    }
05927    if (fPlayer == obj) {
05928       fPlayer = 0;
05929    }
05930    if (fTreeIndex == obj) {
05931       fTreeIndex = 0;
05932    }
05933    if (fAliases) {
05934       fAliases->RecursiveRemove(obj);
05935    }
05936    if (fFriends) {
05937       fFriends->RecursiveRemove(obj);
05938    }
05939 }
05940 
05941 //______________________________________________________________________________
05942 void TTree::Refresh()
05943 {
05944    //  Refresh contents of this tree and its branches from the current status on disk.
05945    //
05946    //  One can call this function in case the tree file is being
05947    //  updated by another process.
05948 
05949    if (!fDirectory->GetFile()) {
05950       return;
05951    }
05952    fDirectory->ReadKeys();
05953    fDirectory->Remove(this);
05954    TTree* tree; fDirectory->GetObject(GetName(),tree);
05955    if (!tree) {
05956       return;
05957    }
05958    //copy info from tree header into this Tree
05959    fEntries = tree->fEntries;
05960    fTotBytes = tree->fTotBytes;
05961    fZipBytes = tree->fZipBytes;
05962    fSavedBytes = tree->fSavedBytes;
05963    fTotalBuffers = tree->fTotalBuffers;
05964 
05965    //loop on all branches and update them
05966    Int_t nleaves = fLeaves.GetEntriesFast();
05967    for (Int_t i = 0; i < nleaves; i++)  {
05968       TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
05969       TBranch* branch = (TBranch*) leaf->GetBranch();
05970       branch->Refresh(tree->GetBranch(branch->GetName()));
05971    }
05972    fDirectory->Remove(tree);
05973    fDirectory->Append(this);
05974    delete tree;
05975    tree = 0;
05976 }
05977 
05978 //______________________________________________________________________________
05979 void TTree::RemoveFriend(TTree* oldFriend)
05980 {
05981    // Remove a friend from the list of friends.
05982 
05983    // We already have been visited while recursively looking
05984    // through the friends tree, let return
05985    if (kRemoveFriend & fFriendLockStatus) {
05986       return;
05987    }
05988    if (!fFriends) {
05989       return;
05990    }
05991    TFriendLock lock(this, kRemoveFriend);
05992    TIter nextf(fFriends);
05993    TFriendElement* fe = 0;
05994    while ((fe = (TFriendElement*) nextf())) {
05995       TTree* friend_t = fe->GetTree();
05996       if (friend_t == oldFriend) {
05997          fFriends->Remove(fe);
05998          delete fe;
05999          fe = 0;
06000       }
06001    }
06002 }
06003 
06004 //______________________________________________________________________________
06005 void TTree::Reset(Option_t* option)
06006 {
06007    // Reset baskets, buffers and entries count in all branches and leaves.
06008 
06009    fNotify = 0;
06010    fEntries = 0;
06011    fTotBytes = 0;
06012    fZipBytes = 0;
06013    fSavedBytes = 0;
06014    fTotalBuffers = 0;
06015    fChainOffset = 0;
06016    fReadEntry = -1;
06017 
06018    delete fTreeIndex;
06019    fTreeIndex = 0;
06020 
06021    Int_t nb = fBranches.GetEntriesFast();
06022    for (Int_t i = 0; i < nb; ++i)  {
06023       TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
06024       branch->Reset(option);
06025    }
06026 
06027    if (fBranchRef) {
06028       fBranchRef->Reset();
06029    }
06030 }
06031 
06032 //______________________________________________________________________________
06033 void TTree::ResetBranchAddress(TBranch *br)
06034 {
06035    // Tell all of our branches to set their addresses to zero.
06036    //
06037    // Note: If any of our branches own any objects, they are deleted.
06038 
06039    if (br && br->GetTree()) {
06040       br->ResetAddress();
06041    }
06042 }
06043 
06044 //______________________________________________________________________________
06045 void TTree::ResetBranchAddresses()
06046 {
06047    // Tell all of our branches to drop their current objects and allocate new ones.
06048 
06049    TObjArray* branches = GetListOfBranches();
06050    Int_t nbranches = branches->GetEntriesFast();
06051    for (Int_t i = 0; i < nbranches; ++i) {
06052       TBranch* branch = (TBranch*) branches->UncheckedAt(i);
06053       branch->ResetAddress();
06054    }
06055 }
06056 
06057 //______________________________________________________________________________
06058 Long64_t TTree::Scan(const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
06059 {
06060    // Loop over tree entries and print entries passing selection.
06061    //
06062    // If varexp is 0 (or "") then print only first 8 columns.
06063    // If varexp = "*" print all columns.
06064    // Otherwise a columns selection can be made using "var1:var2:var3".
06065    // See TTreePlayer::Scan for more information
06066    //
06067 
06068    GetPlayer();
06069    if (fPlayer) {
06070       return fPlayer->Scan(varexp, selection, option, nentries, firstentry);
06071    }
06072    return -1;
06073 }
06074 
06075 //______________________________________________________________________________
06076 Bool_t TTree::SetAlias(const char* aliasName, const char* aliasFormula)
06077 {
06078    // Set a tree variable alias.
06079    //
06080    //  Set an alias for an expression/formula based on the tree 'variables'.
06081    //
06082    //  The content of 'aliasName' can be used in TTreeFormula (i.e. TTree::Draw,
06083    //  TTree::Scan, TTreeViewer) and will be evaluated as the content of
06084    //  'aliasFormula'.
06085    //  If the content of 'aliasFormula' only contains symbol names, periods and
06086    //  array index specification (for example event.fTracks[3]), then
06087    //  the content of 'aliasName' can be used as the start of symbol.
06088    //
06089    //  If the alias 'aliasName' already existed, it is replaced by the new
06090    //  value.
06091    //
06092    //  When being used, the alias can be preceded by an eventual 'Friend Alias'
06093    //  (see TTree::GetFriendAlias)
06094    //
06095    //  Return true if it was added properly.
06096    //
06097    //  For example:
06098    //     tree->SetAlias("x1","(tdc1[1]-tdc1[0])/49");
06099    //     tree->SetAlias("y1","(tdc1[3]-tdc1[2])/47");
06100    //     tree->SetAlias("x2","(tdc2[1]-tdc2[0])/49");
06101    //     tree->SetAlias("y2","(tdc2[3]-tdc2[2])/47");
06102    //     tree->Draw("y2-y1:x2-x1");
06103    //
06104    //     tree->SetAlias("theGoodTrack","event.fTracks[3]");
06105    //     tree->Draw("theGoodTrack.fPx"); // same as "event.fTracks[3].fPx"
06106 
06107    if (!aliasName || !aliasFormula) {
06108       return kFALSE;
06109    }
06110    if (!strlen(aliasName) || !strlen(aliasFormula)) {
06111       return kFALSE;
06112    }
06113    if (!fAliases) {
06114       fAliases = new TList;
06115    } else {
06116       TNamed* oldHolder = (TNamed*) fAliases->FindObject(aliasName);
06117       if (oldHolder) {
06118          oldHolder->SetTitle(aliasFormula);
06119          return kTRUE;
06120       }
06121    }
06122    TNamed* holder = new TNamed(aliasName, aliasFormula);
06123    fAliases->Add(holder);
06124    return kTRUE;
06125 }
06126 
06127 //_______________________________________________________________________
06128 void TTree::SetAutoFlush(Long64_t autof)
06129 {
06130    // This function may be called at the start of a program to change
06131    // the default value for fAutoFlush.
06132    //
06133    //     CASE 1 : autof > 0
06134    //     ------------------
06135    // autof is the number of consecutive entries after which TTree::Fill will
06136    // flush all branch buffers to disk.
06137    //
06138    //     CASE 2 : autof < 0
06139    //     ------------------
06140    // When filling the Tree the branch buffers will be flushed to disk when
06141    // more than autof bytes have been written to the file. At the first FlushBaskets
06142    // TTree::Fill will replace fAutoFlush by the current value of fEntries.
06143    //
06144    // Calling this function with autof<0 is interesting when it is hard to estimate
06145    // the size of one entry. This value is also independent of the Tree.
06146    //
06147    // The Tree is initialized with fAutoFlush=-30000000, ie that, by default,
06148    // the first AutoFlush will be done when 30 MBytes of data are written to the file.
06149    //
06150    //     CASE 3 : autof = 0
06151    //     ------------------
06152    // The AutoFlush mechanism is disabled.
06153    //
06154    // Flushing the buffers at regular intervals optimize the location of
06155    // consecutive entries on the disk.
06156 
06157    fAutoFlush = autof;
06158 }
06159 
06160 //_______________________________________________________________________
06161 void TTree::SetAutoSave(Long64_t autos)
06162 {
06163    //This function may be called at the start of a program to change
06164    //the default value for fAutoSave(300000000, ie 300 MBytes).
06165    //When filling the Tree the branch buffers as well as the Tree header
06166    //will be flushed to disk when more than fAutoSave bytes have been written to the file.
06167    //In case of a program crash, it will be possible to recover the data in the Tree
06168    //up to the last AutoSave point.
06169 
06170    fAutoSave = autos;
06171 }
06172 
06173 //_______________________________________________________________________
06174 void TTree::SetBasketSize(const char* bname, Int_t buffsize)
06175 {
06176    // Set a branch's basket size.
06177    //
06178    // bname is the name of a branch.
06179    // if bname="*", apply to all branches.
06180    // if bname="xxx*", apply to all branches with name starting with xxx
06181    // see TRegexp for wildcarding options
06182    // buffsize = branc basket size
06183    //
06184 
06185    Int_t nleaves = fLeaves.GetEntriesFast();
06186    TRegexp re(bname, kTRUE);
06187    Int_t nb = 0;
06188    for (Int_t i = 0; i < nleaves; i++)  {
06189       TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
06190       TBranch* branch = (TBranch*) leaf->GetBranch();
06191       TString s = branch->GetName();
06192       if (strcmp(bname, branch->GetName()) && (s.Index(re) == kNPOS)) {
06193          continue;
06194       }
06195       nb++;
06196       branch->SetBasketSize(buffsize);
06197    }
06198    if (!nb) {
06199       Error("SetBasketSize", "unknown branch -> '%s'", bname);
06200    }
06201 }
06202 
06203 //_______________________________________________________________________
06204 Int_t TTree::SetBranchAddress(const char* bname, void* addr, TBranch** ptr)
06205 {
06206    // Change branch address, dealing with clone trees properly.
06207    // See TTree::CheckBranchAddressType for the semantic of the return value.
06208    //
06209    // Note: See the comments in TBranchElement::SetAddress() for the
06210    //       meaning of the addr parameter.
06211    //
06212 
06213    TBranch* branch = GetBranch(bname);
06214    if (!branch) {
06215       Error("SetBranchAddress", "unknown branch -> %s", bname);
06216       return kMissingBranch;
06217    }
06218    return SetBranchAddressImp(branch,addr,ptr);
06219 }
06220 
06221 //_______________________________________________________________________
06222 Int_t TTree::SetBranchAddress(const char* bname, void* addr, TClass* ptrClass, EDataType datatype, Bool_t isptr)
06223 {
06224    // Verify the validity of the type of addr before calling SetBranchAddress.
06225    // See TTree::CheckBranchAddressType for the semantic of the return value.
06226    //
06227    // Note: See the comments in TBranchElement::SetAddress() for the
06228    //       meaning of the addr parameter.
06229    //
06230 
06231    return SetBranchAddress(bname, addr, 0, ptrClass, datatype, isptr);
06232 }
06233 
06234 //_______________________________________________________________________
06235 Int_t TTree::SetBranchAddress(const char* bname, void* addr, TBranch** ptr, TClass* ptrClass, EDataType datatype, Bool_t isptr)
06236 {
06237    // Verify the validity of the type of addr before calling SetBranchAddress.
06238    // See TTree::CheckBranchAddressType for the semantic of the return value.
06239    //
06240    // Note: See the comments in TBranchElement::SetAddress() for the
06241    //       meaning of the addr parameter.
06242    //
06243 
06244    TBranch* branch = GetBranch(bname);
06245    if (!branch) {
06246       Error("SetBranchAddress", "unknown branch -> %s", bname);
06247       return kMissingBranch;
06248    }
06249    if (ptr) {
06250       *ptr = branch;
06251    }
06252 
06253    Int_t res = CheckBranchAddressType(branch, ptrClass, datatype, isptr);
06254    SetBranchAddressImp(branch,addr,ptr);
06255    return res;
06256 }
06257 
06258 //_______________________________________________________________________
06259 Int_t TTree::SetBranchAddressImp(TBranch *branch, void* addr, TBranch** ptr)
06260 {
06261    // Change branch address, dealing with clone trees properly.
06262    // See TTree::CheckBranchAddressType for the semantic of the return value.
06263    //
06264    // Note: See the comments in TBranchElement::SetAddress() for the
06265    //       meaning of the addr parameter.
06266    //
06267 
06268    if (ptr) {
06269       *ptr = branch;
06270    }
06271    if (fClones) {
06272       void* oldAddr = branch->GetAddress();
06273       TIter next(fClones);
06274       TTree* clone = 0;
06275       const char *bname = branch->GetName();
06276       while ((clone = (TTree*) next())) {
06277          TBranch* cloneBr = clone->GetBranch(bname);
06278          if (cloneBr && (cloneBr->GetAddress() == oldAddr)) {
06279             cloneBr->SetAddress(addr);
06280          }
06281       }
06282    }
06283    branch->SetAddress(addr);
06284    return kVoidPtr;
06285 }
06286 
06287 
06288 //_______________________________________________________________________
06289 void TTree::SetBranchStatus(const char* bname, Bool_t status, UInt_t* found)
06290 {
06291    // Set branch status to Process or DoNotProcess.
06292    //
06293    //  When reading a Tree, by default, all branches are read.
06294    //  One can speed up considerably the analysis phase by activating
06295    //  only the branches that hold variables involved in a query.
06296    //
06297    //     bname is the name of a branch.
06298    //     if bname="*", apply to all branches.
06299    //     if bname="xxx*", apply to all branches with name starting with xxx
06300    //     see TRegexp for wildcarding options
06301    //      status = 1  branch will be processed
06302    //             = 0  branch will not be processed
06303    //    Example:
06304    //  Assume a tree T with sub-branches a,b,c,d,e,f,g,etc..
06305    //  when doing T.GetEntry(i) all branches are read for entry i.
06306    //  to read only the branches c and e, one can do
06307    //    T.SetBranchStatus("*",0); //disable all branches
06308    //    T.SetBranchStatus("c",1);
06309    //    T.setBranchStatus("e",1);
06310    //    T.GetEntry(i);
06311    //
06312    //  WARNING! WARNING! WARNING!
06313    //  SetBranchStatus is matching the branch based on regular expression match
06314    //  of the branch 'name' and not on the branch hierarchy!
06315    //  In order to be able to selectively enable a top level object that is 'split'
06316    //  you need to make sure the name of the top level branch is prefixed to the
06317    //  sub-branches' name(by adding a dot ('.') at the end of the Branch creation
06318    //  and use the corresponding regular expression.
06319    //
06320    //  I.e If your Tree has been created in split mode with a parent branch "parent."
06321    //  (note the trailing dot).
06322    //     T.SetBranchStatus("parent",1);
06323    //  will not activate the sub-branches of "parent". You should do:
06324    //     T.SetBranchStatus("parent*",1);
06325    //
06326    //  Without the trailing dot in the branch creation you have no choice but to
06327    //  call SetBranchStatus explicitly for each of the sub branches.
06328    //
06329    //
06330    //  An alternative to this function is to read directly and only
06331    //  the interesting branches. Example:
06332    //    TBranch *brc = T.GetBranch("c");
06333    //    TBranch *bre = T.GetBranch("e");
06334    //    brc->GetEntry(i);
06335    //    bre->GetEntry(i);
06336    //
06337    //  If found is not 0, the number of branch(es) found matching the regular
06338    //  expression is returned in *found AND the error message 'unknown branch'
06339    //  is suppressed.
06340 
06341    // We already have been visited while recursively looking
06342    // through the friends tree, let return
06343    if (kSetBranchStatus & fFriendLockStatus) {
06344       return;
06345    }
06346 
06347    TBranch *branch, *bcount, *bson;
06348    TLeaf *leaf, *leafcount;
06349 
06350    Int_t i,j;
06351    Int_t nleaves = fLeaves.GetEntriesFast();
06352    TRegexp re(bname,kTRUE);
06353    Int_t nb = 0;
06354 
06355    // first pass, loop on all branches
06356    // for leafcount branches activate/deactivate in function of status
06357    for (i=0;i<nleaves;i++)  {
06358       leaf = (TLeaf*)fLeaves.UncheckedAt(i);
06359       branch = (TBranch*)leaf->GetBranch();
06360       TString s = branch->GetName();
06361       if (strcmp(bname,"*")) { //Regexp gives wrong result for [] in name
06362          TString longname;
06363          longname.Form("%s.%s",GetName(),branch->GetName());
06364          if (strcmp(bname,branch->GetName())
06365              && longname != bname
06366              && s.Index(re) == kNPOS) continue;
06367       }
06368       nb++;
06369       if (status) branch->ResetBit(kDoNotProcess);
06370       else        branch->SetBit(kDoNotProcess);
06371       leafcount = leaf->GetLeafCount();
06372       if (leafcount) {
06373          bcount = leafcount->GetBranch();
06374          if (status) bcount->ResetBit(kDoNotProcess);
06375          else        bcount->SetBit(kDoNotProcess);
06376       }
06377    }
06378    if (nb==0 && strchr(bname,'*')==0) {
06379       branch = GetBranch(bname);
06380       if (branch) {
06381          if (status) branch->ResetBit(kDoNotProcess);
06382          else        branch->SetBit(kDoNotProcess);
06383          ++nb;
06384       }
06385    }
06386 
06387    //search in list of friends
06388    UInt_t foundInFriend = 0;
06389    if (fFriends) {
06390       TFriendLock lock(this,kSetBranchStatus);
06391       TIter nextf(fFriends);
06392       TFriendElement *fe;
06393       TString name;
06394       while ((fe = (TFriendElement*)nextf())) {
06395          TTree *t = fe->GetTree();
06396          if (t==0) continue;
06397 
06398          // If the alias is present replace it with the real name.
06399          char *subbranch = (char*)strstr(bname,fe->GetName());
06400          if (subbranch!=bname) subbranch = 0;
06401          if (subbranch) {
06402             subbranch += strlen(fe->GetName());
06403             if ( *subbranch != '.' ) subbranch = 0;
06404             else subbranch ++;
06405          }
06406          if (subbranch) {
06407             name.Form("%s.%s",t->GetName(),subbranch);
06408          } else {
06409             name = bname;
06410          }
06411          t->SetBranchStatus(name,status, &foundInFriend);
06412       }
06413    }
06414    if (!nb && !foundInFriend) {
06415       if (found==0) Error("SetBranchStatus", "unknown branch -> %s", bname);
06416       return;
06417    }
06418    if (found) *found = nb + foundInFriend;
06419 
06420    // second pass, loop again on all branches
06421    // activate leafcount branches for active branches only
06422    for (i = 0; i < nleaves; i++) {
06423       leaf = (TLeaf*)fLeaves.UncheckedAt(i);
06424       branch = (TBranch*)leaf->GetBranch();
06425       if (!branch->TestBit(kDoNotProcess)) {
06426          leafcount = leaf->GetLeafCount();
06427          if (leafcount) {
06428             bcount = leafcount->GetBranch();
06429             bcount->ResetBit(kDoNotProcess);
06430          }
06431       } else {
06432          //Int_t nbranches = branch->GetListOfBranches()->GetEntriesFast();
06433          Int_t nbranches = branch->GetListOfBranches()->GetEntries();
06434          for (j=0;j<nbranches;j++) {
06435             bson = (TBranch*)branch->GetListOfBranches()->UncheckedAt(j);
06436             if (!bson) continue;
06437             if (!bson->TestBit(kDoNotProcess)) {
06438                if (bson->GetNleaves() <= 0) continue;
06439                branch->ResetBit(kDoNotProcess);
06440                break;
06441             }
06442          }
06443       }
06444    }
06445 }
06446 
06447 //______________________________________________________________________________
06448 void TTree::SetBranchStyle(Int_t style)
06449 {
06450    // Set the current branch style.  (static function)
06451    //
06452    // style = 0 old Branch
06453    // style = 1 new Bronch
06454 
06455    fgBranchStyle = style;
06456 }
06457 
06458 //______________________________________________________________________________
06459 void TTree::SetCacheSize(Long64_t cacheSize)
06460 {
06461    // Set maximum size of the file cache .
06462    // if cachesize = 0 the existing cache (if any) is deleted.
06463    // if cachesize = -1 (default) it is set to the AutoFlush value when writing
06464    //    the Tree (default is 30 MBytes).
06465    // WARNING: Currently only ONE TTree object can be 'cached' per TFile object.
06466    // This call disable the cache for the other TTree objects read from the same
06467    // TFile object as this TTree (The SetCacheSize called __last__ wins).
06468    // To cache multiple TTree objects in the same ROOT file, you must create
06469    // one TFile object per TTree object.
06470 
06471    if (cacheSize < 0) {
06472       if (fAutoFlush < 0) cacheSize = -fAutoFlush;
06473       else cacheSize = Long64_t(1.5*fAutoFlush*fZipBytes/(fEntries+1));
06474    }
06475    TFile* file = GetCurrentFile();
06476    if (!file) {
06477       fCacheSize = cacheSize;
06478       return;
06479    }
06480    TFileCacheRead* pf = file->GetCacheRead();
06481    if (pf) {
06482       if (cacheSize == fCacheSize) {
06483          return;
06484       }
06485       delete pf;
06486       pf = 0;
06487       if (cacheSize == 0) {
06488          file->SetCacheRead(0);
06489          fCacheSize=0;
06490          return;
06491       }
06492    }
06493    fCacheSize = cacheSize;
06494    if (cacheSize == 0) {
06495       return;
06496    }
06497 
06498    if(TTreeCacheUnzip::IsParallelUnzip() && file->GetCompressionLevel() > 0)
06499       new TTreeCacheUnzip(this, cacheSize);
06500    else
06501       new TTreeCache(this, cacheSize);
06502 }
06503 
06504 //______________________________________________________________________________
06505 void TTree::SetCacheEntryRange(Long64_t first, Long64_t last)
06506 {
06507    //interface to TTreeCache to set the cache entry range
06508 
06509    TFile *f = GetCurrentFile();
06510    if (!f) return;
06511    TTreeCache *tc = (TTreeCache*)f->GetCacheRead();
06512    if (tc) tc->SetEntryRange(first,last);
06513 }
06514 
06515 //______________________________________________________________________________
06516 void TTree::SetCacheLearnEntries(Int_t n)
06517 {
06518    //interface to TTreeCache to set the number of entries for the learning phase
06519 
06520    TTreeCache::SetLearnEntries(n);
06521 }
06522 
06523 //______________________________________________________________________________
06524 void TTree::SetCircular(Long64_t maxEntries)
06525 {
06526    // Enable/Disable circularity for this tree.
06527    //
06528    // if maxEntries > 0 a maximum of maxEntries is kept in one buffer/basket
06529    // per branch in memory.
06530    //   Note that when this function is called (maxEntries>0) the Tree
06531    //   must be empty or having only one basket per branch.
06532    // if maxEntries <= 0 the tree circularity is disabled.
06533    //
06534    // NOTE 1:
06535    //  Circular Trees are interesting in online real time environments
06536    //  to store the results of the last maxEntries events.
06537    // NOTE 2:
06538    //  Calling SetCircular with maxEntries <= 0 is necessary before
06539    //  merging circular Trees that have been saved on files.
06540    // NOTE 3:
06541    //  SetCircular with maxEntries <= 0 is automatically called
06542    //  by TChain::Merge
06543    // NOTE 4:
06544    //  A circular Tree can still be saved in a file. When read back,
06545    //  it is still a circular Tree and can be filled again.
06546 
06547    if (maxEntries <= 0) {
06548       // Disable circularity.
06549       fMaxEntries = 1000000000;
06550       fMaxEntries *= 1000;
06551       ResetBit(kCircular);
06552       //in case the Tree was originally created in gROOT, the branch
06553       //compression level was set to -1. If the Tree is now associated to
06554       //a file, reset the compression level to the file compression level
06555       if (fDirectory) {
06556          TFile* bfile = fDirectory->GetFile();
06557          Int_t compress = 1;
06558          if (bfile) {
06559             compress = bfile->GetCompressionLevel();
06560          }
06561          Int_t nb = fBranches.GetEntriesFast();
06562          for (Int_t i = 0; i < nb; i++) {
06563             TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
06564             branch->SetCompressionLevel(compress);
06565          }
06566       }
06567    } else {
06568       // Enable circularity.
06569       fMaxEntries = maxEntries;
06570       SetBit(kCircular);
06571    }
06572 }
06573 
06574 //______________________________________________________________________________
06575 void TTree::SetDebug(Int_t level, Long64_t min, Long64_t max)
06576 {
06577    // Set the debug level and the debug range.
06578    //
06579    // For entries in the debug range, the functions TBranchElement::Fill
06580    // and TBranchElement::GetEntry will print the number of bytes filled
06581    // or read for each branch.
06582 
06583    fDebug = level;
06584    fDebugMin = min;
06585    fDebugMax = max;
06586 }
06587 
06588 //______________________________________________________________________________
06589 void TTree::SetDefaultEntryOffsetLen(Int_t newdefault, Bool_t updateExisting)
06590 {
06591    // Update the default value for the branch's fEntryOffsetLen.
06592    // If updateExisting is true, also update all the existing branches.
06593    // If newdefault is less than 10, the new default value will be 10.
06594 
06595    if (newdefault < 10) {
06596       newdefault = 10;
06597    }
06598    fDefaultEntryOffsetLen = newdefault;
06599    if (updateExisting) {
06600       TIter next( GetListOfBranches() );
06601       TBranch *b;
06602       while ( ( b = (TBranch*)next() ) ) {
06603          b->SetEntryOffsetLen( newdefault, kTRUE );
06604       }
06605       if (fBranchRef) {
06606          fBranchRef->SetEntryOffsetLen( newdefault, kTRUE );
06607       }
06608    }
06609 }
06610 
06611 //______________________________________________________________________________
06612 void TTree::SetDirectory(TDirectory* dir)
06613 {
06614    // Change the tree's directory.
06615    //
06616    // Remove reference to this tree from current directory and
06617    // add reference to new directory dir.  The dir parameter can
06618    // be 0 in which case the tree does not belong to any directory.
06619    //
06620 
06621    if (fDirectory == dir) {
06622       return;
06623    }
06624    if (fDirectory) {
06625       fDirectory->Remove(this);
06626    }
06627    fDirectory = dir;
06628    if (fDirectory) {
06629       fDirectory->Append(this);
06630    }
06631    TFile* file = 0;
06632    if (fDirectory) {
06633       file = fDirectory->GetFile();
06634    }
06635    if (fBranchRef) {
06636       fBranchRef->SetFile(file);
06637    }
06638    TBranch* b = 0;
06639    TIter next(GetListOfBranches());
06640    while((b = (TBranch*) next())) {
06641       b->SetFile(file);
06642    }
06643 }
06644 
06645 //_______________________________________________________________________
06646 Long64_t TTree::SetEntries(Long64_t n)
06647 {
06648    // Change number of entries in the tree.
06649    //
06650    // If n >= 0, set number of entries in the tree = n.
06651    //
06652    // If n < 0, set number of entries in the tree to match the
06653    // number of entries in each branch. (default for n is -1)
06654    //
06655    // This function should be called only when one fills each branch
06656    // independently via TBranch::Fill without calling TTree::Fill.
06657    // Calling TTree::SetEntries() make sense only if the number of entries
06658    // in each branch is identical, a warning is issued otherwise.
06659    // The function returns the number of entries.
06660    //
06661 
06662    // case 1 : force number of entries to n
06663    if (n >= 0) {
06664       fEntries = n;
06665       return n;
06666    }
06667 
06668    // case 2; compute the number of entries from the number of entries in the branches
06669    TBranch* b = 0;
06670    Long64_t nMin = 99999999;
06671    Long64_t nMax = 0;
06672    TIter next(GetListOfBranches());
06673    while((b = (TBranch*) next())){
06674       Long64_t n2 = b->GetEntries();
06675       if (n2 < nMin) {
06676          nMin = n2;
06677       }
06678       if (n2 > nMax) {
06679          nMax = n2;
06680       }
06681    }
06682    if (nMin != nMax) {
06683       Warning("SetEntries", "Tree branches have different numbers of entries, with %lld maximum.", nMax);
06684    }
06685    fEntries = nMax;
06686    return fEntries;
06687 }
06688 
06689 //_______________________________________________________________________
06690 void TTree::SetEntryList(TEntryList *enlist, Option_t * /*opt*/)
06691 {
06692    //Set an EntryList
06693 
06694    if (fEntryList) {
06695       //check if the previous entry list is owned by the tree
06696       if (fEntryList->TestBit(kCanDelete)){
06697          delete fEntryList;
06698       }
06699    }
06700    fEventList = 0;
06701    if (!enlist) {
06702       fEntryList = 0;
06703       return;
06704    }
06705    fEntryList = enlist;
06706    fEntryList->SetTree(this);
06707 
06708 }
06709 
06710 //_______________________________________________________________________
06711 void TTree::SetEventList(TEventList *evlist)
06712 {
06713 //This function transfroms the given TEventList into a TEntryList
06714 //The new TEntryList is owned by the TTree and gets deleted when the tree
06715 //is deleted. This TEntryList can be returned by GetEntryList() function.
06716 
06717    fEventList = evlist;
06718    if (fEntryList){
06719       if (fEntryList->TestBit(kCanDelete)) {
06720          TEntryList *tmp = fEntryList;
06721          fEntryList = 0; // Avoid problem with RecursiveRemove.
06722          delete tmp;
06723       } else {
06724          fEntryList = 0;
06725       }
06726    }
06727 
06728    if (!evlist) {
06729       fEntryList = 0;
06730       fEventList = 0;
06731       return;
06732    }
06733 
06734    fEventList = evlist;
06735    char enlistname[100];
06736    snprintf(enlistname,100, "%s_%s", evlist->GetName(), "entrylist");
06737    fEntryList = new TEntryList(enlistname, evlist->GetTitle());
06738    fEntryList->SetDirectory(0); // We own this.
06739    Int_t nsel = evlist->GetN();
06740    fEntryList->SetTree(this);
06741    Long64_t entry;
06742    for (Int_t i=0; i<nsel; i++){
06743       entry = evlist->GetEntry(i);
06744       fEntryList->Enter(entry);
06745    }
06746    fEntryList->SetReapplyCut(evlist->GetReapplyCut());
06747    fEntryList->SetBit(kCanDelete, kTRUE);
06748 }
06749 
06750 //_______________________________________________________________________
06751 void TTree::SetEstimate(Long64_t n)
06752 {
06753    // Set number of entries to estimate variable limits.
06754 
06755    if (n <= 0) {
06756       n = 10000;
06757    }
06758    fEstimate = n;
06759    GetPlayer();
06760    if (fPlayer) {
06761       fPlayer->SetEstimate(n);
06762    }
06763 }
06764 
06765 //_______________________________________________________________________
06766 void TTree::SetFileNumber(Int_t number)
06767 {
06768    // Set fFileNumber to number.
06769    // fFileNumber is used by TTree::Fill to set the file name
06770    // for a new file to be created when the current file exceeds fgTreeMaxSize.
06771    //    (see TTree::ChangeFile)
06772    // if fFileNumber=10, the new file name will have a suffix "_11",
06773    // ie, fFileNumber is incremented before setting the file name
06774 
06775    if (fFileNumber < 0) {
06776       Warning("SetFileNumber", "file number must be positive. Set to 0");
06777       fFileNumber = 0;
06778       return;
06779    }
06780    fFileNumber = number;
06781 }
06782 
06783 //______________________________________________________________________________
06784 void TTree::SetMakeClass(Int_t make) 
06785 {
06786    // Set all the branches in this TTree to be in decomposed object mode
06787    // (also known as MakeClass mode).
06788    
06789    fMakeClass = make;
06790 
06791    Int_t nb = fBranches.GetEntriesFast();
06792    for (Int_t i = 0; i < nb; ++i)  {
06793       TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
06794       branch->SetMakeClass(make);
06795    }   
06796 }
06797 
06798 //______________________________________________________________________________
06799 void TTree::SetMaxTreeSize(Long64_t maxsize)
06800 {
06801    // Set the maximum size in bytes of a Tree file (static function).
06802    // The default size is 100000000000LL, ie 100 Gigabytes.
06803    //
06804    // In TTree::Fill, when the file has a size > fgMaxTreeSize,
06805    // the function closes the current file and starts writing into
06806    // a new file with a name of the style "file_1.root" if the original
06807    // requested file name was "file.root".
06808    //
06809 
06810    fgMaxTreeSize = maxsize;
06811 }
06812 
06813 //______________________________________________________________________________
06814 void TTree::SetName(const char* name)
06815 {
06816    // Change the name of this tree.
06817 
06818    if (gPad) {
06819       gPad->Modified();
06820    }
06821    // Trees are named objects in a THashList.
06822    // We must update the hashlist if we change the name.
06823    if (fDirectory) {
06824       fDirectory->Remove(this);
06825    }
06826    // This changes our hash value.
06827    fName = name;
06828    if (fDirectory) {
06829       fDirectory->Append(this);
06830    }
06831 }
06832 
06833 //______________________________________________________________________________
06834 void TTree::SetObject(const char* name, const char* title)
06835 {
06836    // Change the name and title of this tree.
06837 
06838    if (gPad) {
06839       gPad->Modified();
06840    }
06841 
06842    //  Trees are named objects in a THashList.
06843    //  We must update the hashlist if we change the name
06844    if (fDirectory) {
06845       fDirectory->Remove(this);
06846    }
06847    // This changes our hash value.
06848    fName = name;
06849    fTitle = title;
06850    if (fDirectory) {
06851       fDirectory->Append(this);
06852    }
06853 }
06854 
06855 //______________________________________________________________________________
06856 void TTree::SetParallelUnzip(Bool_t opt, Float_t RelSize)
06857 {
06858    //enable or disable parallel unzipping of Tree buffers
06859 
06860    if (opt) TTreeCacheUnzip::SetParallelUnzip(TTreeCacheUnzip::kEnable);
06861    else     TTreeCacheUnzip::SetParallelUnzip(TTreeCacheUnzip::kDisable);
06862 
06863    if (RelSize > 0)
06864      TTreeCacheUnzip::SetUnzipRelBufferSize(RelSize);
06865 
06866 
06867 
06868 }
06869 
06870 //______________________________________________________________________________
06871 void TTree::SetTreeIndex(TVirtualIndex* index)
06872 {
06873    // The current TreeIndex is replaced by the new index.
06874    // Note that this function does not delete the previous index.
06875    // This gives the possibility to play with more than one index, e.g.,
06876    // TVirtualIndex* oldIndex = tree.GetTreeIndex();
06877    // tree.SetTreeIndex(newIndex);
06878    // tree.Draw();
06879    // tree.SetTreeIndex(oldIndex);
06880    // tree.Draw(); etc
06881 
06882    if (fTreeIndex) {
06883       fTreeIndex->SetTree(0);
06884    }
06885    fTreeIndex = index;
06886 }
06887 
06888 //______________________________________________________________________________
06889 void TTree::SetWeight(Double_t w, Option_t*)
06890 {
06891    // Set tree weight.
06892    //
06893    // The weight is used by TTree::Draw to automatically weight each
06894    // selected entry in the resulting histogram.
06895    //
06896    // For example the equivalent of:
06897    //
06898    //      T.Draw("x", "w")
06899    //
06900    // is:
06901    //
06902    //      T.SetWeight(w);
06903    //      T.Draw("x");
06904    //
06905    // This function is redefined by TChain::SetWeight. In case of a
06906    // TChain, an option "global" may be specified to set the same weight
06907    // for all trees in the TChain instead of the default behaviour
06908    // using the weights of each tree in the chain (see TChain::SetWeight).
06909 
06910    fWeight = w;
06911 }
06912 
06913 //______________________________________________________________________________
06914 void TTree::Show(Long64_t entry, Int_t lenmax)
06915 {
06916    // Print values of all active leaves for entry.
06917    //
06918    // if entry==-1, print current entry (default)
06919    // if a leaf is an array, a maximum of lenmax elements is printed.
06920    //
06921    if (entry != -1) {
06922       Int_t ret = LoadTree(entry);
06923       if (ret == -2) {
06924          Error("Show()", "Cannot read entry %lld (entry does not exist)", entry);
06925          return;
06926       } else if (ret == -1) {
06927          Error("Show()", "Cannot read entry %lld (I/O error)", entry);
06928          return;
06929       }
06930       ret = GetEntry(entry);
06931       if (ret == -1) {
06932          Error("Show()", "Cannot read entry %lld (I/O error)", entry);
06933          return;
06934       } else if (ret == 0) {
06935          Error("Show()", "Cannot read entry %lld (no data read)", entry);
06936          return;
06937       }
06938    }
06939    printf("======> EVENT:%lld\n", fReadEntry);
06940    TObjArray* leaves  = GetListOfLeaves();
06941    Int_t nleaves = leaves->GetEntriesFast();
06942    Int_t ltype;
06943    for (Int_t i = 0; i < nleaves; i++) {
06944       TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(i);
06945       TBranch* branch = leaf->GetBranch();
06946       if (branch->TestBit(kDoNotProcess)) {
06947          continue;
06948       }
06949       Int_t len = leaf->GetLen();
06950       if (len <= 0) {
06951          continue;
06952       }
06953       len = TMath::Min(len, lenmax);
06954       if (leaf->IsA() == TLeafElement::Class()) {
06955          leaf->PrintValue(lenmax);
06956          continue;
06957       }
06958       if (branch->GetListOfBranches()->GetEntriesFast() > 0) {
06959          continue;
06960       }
06961       ltype = 10;
06962       if (leaf->IsA() == TLeafF::Class()) {
06963          ltype = 5;
06964       }
06965       if (leaf->IsA() == TLeafD::Class()) {
06966          ltype = 5;
06967       }
06968       if (leaf->IsA() == TLeafC::Class()) {
06969          len = 1;
06970          ltype = 5;
06971       };
06972       printf(" %-15s = ", leaf->GetName());
06973       for (Int_t l = 0; l < len; l++) {
06974          leaf->PrintValue(l);
06975          if (l == (len - 1)) {
06976             printf("\n");
06977             continue;
06978          }
06979          printf(", ");
06980          if ((l % ltype) == 0) {
06981             printf("\n                  ");
06982          }
06983       }
06984    }
06985 }
06986 
06987 //______________________________________________________________________________
06988 void TTree::StartViewer()
06989 {
06990    // Start the TTreeViewer on this tree.
06991    //
06992    //  ww is the width of the canvas in pixels
06993    //  wh is the height of the canvas in pixels
06994 
06995    GetPlayer();
06996    if (fPlayer) {
06997       fPlayer->StartViewer(600, 400);
06998    }
06999 }
07000 
07001 //______________________________________________________________________________
07002 void TTree::StopCacheLearningPhase()
07003 {
07004    // stop the cache learning phase
07005 
07006    TFile *f = GetCurrentFile();
07007    if (!f) return;
07008    TTreeCache *tc = (TTreeCache*)f->GetCacheRead();
07009    if (tc) tc->StopLearningPhase();
07010 }
07011 
07012 //______________________________________________________________________________
07013 void TTree::Streamer(TBuffer& b)
07014 {
07015    // Stream a class object.
07016    if (b.IsReading()) {
07017       UInt_t R__s, R__c;
07018       gTree = this;
07019       fDirectory = 0;
07020       Version_t R__v = b.ReadVersion(&R__s, &R__c);
07021       if (R__v > 4) {
07022          b.ReadClassBuffer(TTree::Class(), this, R__v, R__s, R__c);
07023 
07024          if (fTreeIndex) {
07025             fTreeIndex->SetTree(this);
07026          }
07027          if (fIndex.fN) {
07028             Warning("Streamer", "Old style index in this tree is deleted. Rebuild the index via TTree::BuildIndex");
07029             fIndex.Set(0);
07030             fIndexValues.Set(0);
07031          }
07032          if (fEstimate <= 10000) {
07033             fEstimate = 1000000;
07034          }
07035          fCacheSize    = fAutoFlush;
07036          ResetBit(kMustCleanup);
07037          return;
07038       }
07039       //====process old versions before automatic schema evolution
07040       Stat_t djunk;
07041       Int_t ijunk;
07042       TNamed::Streamer(b);
07043       TAttLine::Streamer(b);
07044       TAttFill::Streamer(b);
07045       TAttMarker::Streamer(b);
07046       b >> fScanField;
07047       b >> ijunk; fMaxEntryLoop   = (Long64_t)ijunk;
07048       b >> ijunk; fMaxVirtualSize = (Long64_t)ijunk;
07049       b >> djunk; fEntries  = (Long64_t)djunk;
07050       b >> djunk; fTotBytes = (Long64_t)djunk;
07051       b >> djunk; fZipBytes = (Long64_t)djunk;
07052       b >> ijunk; fAutoSave = (Long64_t)ijunk;
07053       b >> ijunk; fEstimate = (Long64_t)ijunk;
07054       if (fEstimate <= 10000) fEstimate = 1000000;
07055       fBranches.Streamer(b);
07056       fLeaves.Streamer(b);
07057       fSavedBytes = fTotBytes;
07058       if (R__v > 1) fIndexValues.Streamer(b);
07059       if (R__v > 2) fIndex.Streamer(b);
07060       if (R__v > 3) {
07061          TList OldInfoList;
07062          OldInfoList.Streamer(b);
07063          OldInfoList.Delete();
07064       }
07065       fDefaultEntryOffsetLen = 1000;
07066       ResetBit(kMustCleanup);
07067       b.CheckByteCount(R__s, R__c, TTree::IsA());
07068       //====end of old versions
07069    } else {
07070       if (fBranchRef) {
07071          fBranchRef->Clear();
07072       }
07073       b.WriteClassBuffer(TTree::Class(), this);
07074    }
07075 }
07076 
07077 //______________________________________________________________________________
07078 Int_t TTree::UnbinnedFit(const char* funcname, const char* varexp, const char* selection, Option_t* option, Long64_t nentries, Long64_t firstentry)
07079 {
07080    // Unbinned fit of one or more variable(s) from a tree.
07081    //
07082    //  funcname is a TF1 function.
07083    //
07084    //  See TTree::Draw for explanations of the other parameters.
07085    //
07086    //   Fit the variable varexp using the function funcname using the
07087    //   selection cuts given by selection.
07088    //
07089    //   The list of fit options is given in parameter option.
07090    //      option = "Q" Quiet mode (minimum printing)
07091    //             = "V" Verbose mode (default is between Q and V)
07092    //             = "E" Perform better Errors estimation using Minos technique
07093    //             = "M" More. Improve fit results
07094    //
07095    //   You can specify boundary limits for some or all parameters via
07096    //        func->SetParLimits(p_number, parmin, parmax);
07097    //   if parmin>=parmax, the parameter is fixed
07098    //   Note that you are not forced to fix the limits for all parameters.
07099    //   For example, if you fit a function with 6 parameters, you can do:
07100    //     func->SetParameters(0,3.1,1.e-6,0.1,-8,100);
07101    //     func->SetParLimits(4,-10,-4);
07102    //     func->SetParLimits(5, 1,1);
07103    //   With this setup, parameters 0->3 can vary freely
07104    //   Parameter 4 has boundaries [-10,-4] with initial value -8
07105    //   Parameter 5 is fixed to 100.
07106    //
07107    //   For the fit to be meaningful, the function must be self-normalized.
07108    //
07109    //   i.e. It must have the same integral regardless of the parameter
07110    //   settings.  Otherwise the fit will effectively just maximize the
07111    //   area.
07112    //
07113    //   It is mandatory to have a normalization variable
07114    //   which is fixed for the fit.  e.g.
07115    //
07116    //     TF1* f1 = new TF1("f1", "gaus(0)/sqrt(2*3.14159)/[2]", 0, 5);
07117    //     f1->SetParameters(1, 3.1, 0.01);
07118    //     f1->SetParLimits(0, 1, 1); // fix the normalization parameter to 1
07119    //     data->UnbinnedFit("f1", "jpsimass", "jpsipt>3.0");
07120    //   //
07121    //
07122    //   1, 2 and 3 Dimensional fits are supported.
07123    //   See also TTree::Fit
07124    //
07125    //    Return status
07126    //    =============
07127    //   The function return the status of the fit in the following form
07128    //     fitResult = migradResult + 10*minosResult + 100*hesseResult + 1000*improveResult
07129    //   The fitResult is 0 is the fit is OK.
07130    //   The fitResult is negative in case of an error not connected with the fit.
07131    //   The number of entries used in the fit can be obtained via
07132    //     mytree.GetSelectedRows();
07133    //   If the number of selected entries is null the function returns -1
07134 
07135    GetPlayer();
07136    if (fPlayer) {
07137       return fPlayer->UnbinnedFit(funcname, varexp, selection, option, nentries, firstentry);
07138    }
07139    return -1;
07140 }
07141 
07142 //______________________________________________________________________________
07143 void TTree::UseCurrentStyle()
07144 {
07145    // Replace current attributes by current style.
07146 
07147    if (gStyle->IsReading()) {
07148       SetFillColor(gStyle->GetHistFillColor());
07149       SetFillStyle(gStyle->GetHistFillStyle());
07150       SetLineColor(gStyle->GetHistLineColor());
07151       SetLineStyle(gStyle->GetHistLineStyle());
07152       SetLineWidth(gStyle->GetHistLineWidth());
07153       SetMarkerColor(gStyle->GetMarkerColor());
07154       SetMarkerStyle(gStyle->GetMarkerStyle());
07155       SetMarkerSize(gStyle->GetMarkerSize());
07156    } else {
07157       gStyle->SetHistFillColor(GetFillColor());
07158       gStyle->SetHistFillStyle(GetFillStyle());
07159       gStyle->SetHistLineColor(GetLineColor());
07160       gStyle->SetHistLineStyle(GetLineStyle());
07161       gStyle->SetHistLineWidth(GetLineWidth());
07162       gStyle->SetMarkerColor(GetMarkerColor());
07163       gStyle->SetMarkerStyle(GetMarkerStyle());
07164       gStyle->SetMarkerSize(GetMarkerSize());
07165    }
07166 }
07167 
07168 //______________________________________________________________________________
07169 Int_t TTree::Write(const char *name, Int_t option, Int_t bufsize) const
07170 {
07171    // Write this object to the current directory. For more see TObject::Write
07172    // Write calls TTree::FlushBaskets before writing the tree.
07173 
07174    FlushBaskets();
07175    return TObject::Write(name, option, bufsize);
07176 }
07177 
07178 //______________________________________________________________________________
07179 Int_t TTree::Write(const char *name, Int_t option, Int_t bufsize)
07180 {
07181    // Write this object to the current directory. For more see TObject::Write
07182    // If option & kFlushBasket, call FlushBasket before writing the tree.
07183 
07184    return ((const TTree*)this)->Write(name, option, bufsize);
07185 }
07186 
07187 //////////////////////////////////////////////////////////////////////////
07188 //                                                                      //
07189 // TTreeFriendLeafIter                                                  //
07190 //                                                                      //
07191 // Iterator on all the leaves in a TTree and its friend                 //
07192 //                                                                      //
07193 //////////////////////////////////////////////////////////////////////////
07194 
07195 ClassImp(TTreeFriendLeafIter)
07196 
07197 //______________________________________________________________________________
07198 TTreeFriendLeafIter::TTreeFriendLeafIter(const TTree* tree, Bool_t dir)
07199 : fTree(const_cast<TTree*>(tree))
07200 , fLeafIter(0)
07201 , fTreeIter(0)
07202 , fDirection(dir)
07203 {
07204    // Create a new iterator. By default the iteration direction
07205    // is kIterForward. To go backward use kIterBackward.
07206 }
07207 
07208 //______________________________________________________________________________
07209 TTreeFriendLeafIter::TTreeFriendLeafIter(const TTreeFriendLeafIter& iter)
07210 : TIterator(iter)
07211 , fTree(iter.fTree)
07212 , fLeafIter(0)
07213 , fTreeIter(0)
07214 , fDirection(iter.fDirection)
07215 {
07216    // Copy constructor.  Does NOT copy the 'cursor' location!
07217 
07218 }
07219 
07220 //______________________________________________________________________________
07221 TIterator& TTreeFriendLeafIter::operator=(const TIterator& rhs)
07222 {
07223    // Overridden assignment operator. Does NOT copy the 'cursor' location!
07224 
07225    if (this != &rhs && rhs.IsA() == TTreeFriendLeafIter::Class()) {
07226       const TTreeFriendLeafIter &rhs1 = (const TTreeFriendLeafIter &)rhs;
07227       fDirection = rhs1.fDirection;
07228    }
07229    return *this;
07230 }
07231 
07232 //______________________________________________________________________________
07233 TTreeFriendLeafIter& TTreeFriendLeafIter::operator=(const TTreeFriendLeafIter& rhs)
07234 {
07235    // Overridden assignment operator.  Does NOT copy the 'cursor' location!
07236 
07237    if (this != &rhs) {
07238       fDirection = rhs.fDirection;
07239    }
07240    return *this;
07241 }
07242 
07243 //______________________________________________________________________________
07244 TObject* TTreeFriendLeafIter::Next()
07245 {
07246    // Go the next friend element
07247 
07248    if (!fTree) return 0;
07249 
07250    TObject * next;
07251    TTree * nextTree;
07252 
07253    if (!fLeafIter) {
07254       TObjArray *list = fTree->GetListOfLeaves();
07255       if (!list) return 0; // Can happen with an empty chain.
07256       fLeafIter =  list->MakeIterator(fDirection);
07257    }
07258 
07259    next = fLeafIter->Next();
07260    if (!next) {
07261       if (!fTreeIter) {
07262          TCollection * list = fTree->GetListOfFriends();
07263          if (!list) return next;
07264          fTreeIter = list->MakeIterator(fDirection);
07265       }
07266       TFriendElement * nextFriend = (TFriendElement*) fTreeIter->Next();
07267       ///nextTree = (TTree*)fTreeIter->Next();
07268       if (nextFriend) {
07269          nextTree = const_cast<TTree*>(nextFriend->GetTree());
07270          if (!nextTree) return Next();
07271          SafeDelete(fLeafIter);
07272          fLeafIter = nextTree->GetListOfLeaves()->MakeIterator(fDirection);
07273          next = fLeafIter->Next();
07274       }
07275    }
07276    return next;
07277 }
07278 
07279 //______________________________________________________________________________
07280 Option_t* TTreeFriendLeafIter::GetOption() const
07281 {
07282    // Returns the object option stored in the list.
07283 
07284    if (fLeafIter) return fLeafIter->GetOption();
07285    return "";
07286 }

Generated on Tue Jul 5 15:34:10 2011 for ROOT_528-00b_version by  doxygen 1.5.1