00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
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;
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
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;
00394 case kULong_t: return 0;
00395 case kchar: return 0;
00396 case kLong64_t: return 'L';
00397 case kULong64_t: return 'l';
00398
00399 case kCharStar: return 'C';
00400 case kBits: return 0;
00401
00402 case kOther_t:
00403 case kNoType_t:
00404 default:
00405 return 0;
00406 }
00407 return 0;
00408 }
00409
00410
00411
00412
00413
00414 TTree::TFriendLock::TFriendLock(TTree* tree, UInt_t methodbit)
00415 : fTree(tree)
00416 {
00417
00418
00419
00420
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
00437 }
00438
00439
00440 TTree::TFriendLock& TTree::TFriendLock::operator=(const TTree::TFriendLock& tfl)
00441 {
00442
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
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
00520
00521
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 )
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
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 SetLineColor(gStyle->GetHistLineColor());
00592 SetLineStyle(gStyle->GetHistLineStyle());
00593 SetLineWidth(gStyle->GetHistLineWidth());
00594
00595
00596 SetFillColor(gStyle->GetHistFillColor());
00597 SetFillStyle(gStyle->GetHistFillStyle());
00598
00599
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
00611
00612
00613
00614 fDirectory = gDirectory;
00615 fDirectory->Append(this);
00616
00617
00618 gTree = this;
00619
00620
00621
00622
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
00634
00635 if (fDirectory) {
00636
00637 if (fDirectory->GetList()) {
00638
00639 fDirectory->Remove(this);
00640 }
00641
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
00656 fLeaves.Clear();
00657
00658
00659
00660
00661 if (fClones && fClones->GetEntries()) {
00662
00663
00664
00665
00666 for (TObjLink* lnk = fClones->FirstLink(); lnk; lnk = lnk->Next()) {
00667 TTree* clone = (TTree*) lnk->GetObject();
00668
00669
00670
00671 CopyAddresses(clone,kTRUE);
00672 }
00673 }
00674
00675
00676 fBranches.Delete();
00677
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
00697 gROOT->GetListOfCleanups()->Remove(fClones);
00698
00699 delete fClones;
00700 fClones = 0;
00701 }
00702 if (fEntryList) {
00703 if (fEntryList->TestBit(kCanDelete) && fEntryList->GetDirectory()==0) {
00704
00705
00706
00707 delete fEntryList;
00708 fEntryList=0;
00709 }
00710 }
00711 delete fTreeIndex;
00712 fTreeIndex = 0;
00713 delete fBranchRef;
00714 fBranchRef = 0;
00715
00716
00717 fDirectory = 0;
00718 }
00719
00720
00721 void TTree::AddBranchToCache(const char*bname, Bool_t subbranches)
00722 {
00723
00724
00725
00726
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
00738
00739
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
00752
00753
00754 if (!fClones) {
00755 fClones = new TList();
00756 fClones->SetOwner(false);
00757
00758
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
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848 if (!fFriends) {
00849 fFriends = new TList();
00850 }
00851 TFriendElement* fe = new TFriendElement(this, treename, filename);
00852 R__ASSERT(fe);
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
00869
00870
00871
00872
00873
00874
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
00897
00898
00899
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);
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
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
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);
01014 if (nbytes && key) {
01015 key->Delete();
01016 delete key;
01017 }
01018 }
01019
01020 TFile *file = fDirectory->GetFile();
01021 if (file) file->WriteStreamerInfo();
01022
01023 if (opt.Contains("saveself")) {
01024 fDirectory->SaveSelf();
01025
01026
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
01037
01038
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
01059 if (claim->IsLoaded() && ptrClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), ptrClass->GetTypeInfo()->name() ) == 0) {
01060
01061
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
01069
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
01089
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
01122
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
01146 if (claim->IsLoaded() && ptrClass->IsLoaded() && strcmp( claim->GetTypeInfo()->name(), ptrClass->GetTypeInfo()->name() ) == 0) {
01147
01148
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
01156
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
01183
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 , Int_t splitlevel )
01218 {
01219
01220 return Branch((TCollection*) li, bufsize, splitlevel);
01221 }
01222
01223
01224 Int_t TTree::Branch(TCollection* li, Int_t bufsize , Int_t splitlevel , const char* name )
01225 {
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
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 , Int_t splitlevel )
01332 {
01333
01334
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 )
01378 {
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
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 , Int_t splitlevel )
01444 {
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
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 , Int_t splitlevel )
01478 {
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
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
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
01540 BuildStreamerInfo(cl, obj);
01541
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
01553
01554
01555 while ((rd = (TRealData*) next())) {
01556 if (rd->TestBit(TRealData::kTransient)) continue;
01557
01558
01559 TDataMember* dm = rd->GetDataMember();
01560 if (!dm->IsPersistent()) {
01561
01562 continue;
01563 }
01564 if (rd->IsObject()) {
01565
01566
01567
01568
01569
01570
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
01581
01582
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
01596 branchname = rdname;
01597 if (isDot) {
01598 if (dm->IsaPointer()) {
01599
01600 branchname.Form("%s%s", name, &rdname[1]);
01601 } else {
01602 branchname.Form("%s%s", name, &rdname[0]);
01603 }
01604 }
01605
01606 TString leaflist;
01607 Int_t offset = rd->GetThisOffset();
01608 char* pointer = ((char*) obj) + offset;
01609 if (dm->IsaPointer()) {
01610
01611 TClass* clobj = 0;
01612 if (!dm->IsBasic()) {
01613 clobj = TClass::GetClass(dm->GetTypeName());
01614 }
01615 if (clobj && clobj->InheritsFrom(TClonesArray::Class())) {
01616
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
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
01633 branch1 = new TBranchObject(branch, &branchname.Data()[1], li->ClassName(), pointer, bufsize);
01634 }
01635 blist->Add(branch1);
01636 }
01637 } else if (clobj) {
01638
01639
01640
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
01649
01650 branch1->SetName(&branchname.Data()[1]);
01651 }
01652 blist->Add(branch1);
01653 } else {
01654
01655
01656
01657 const char* index = dm->GetArrayIndex();
01658 if (strlen(index) != 0) {
01659
01660
01661
01662
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
01684
01685
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
01695 if (code == 1) {
01696
01697 leaflist.Form("%s/%s", dname, "C");
01698 } else {
01699
01700
01701 continue;
01702 }
01703 }
01704
01705 TString bname( branchname );
01706 bname.ReplaceAll("*","");
01707 leaflist.ReplaceAll("*","");
01708
01709
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
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
01731
01732
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
01751
01752
01753
01754
01755
01756
01757
01758
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 , Int_t splitlevel )
01768 {
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
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 , Int_t splitlevel )
01826 {
01827
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
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
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
01885
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
01907
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
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
01942
01943
01944
01945
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
01958
01959
01960
01961
01962 Bool_t delobj = kFALSE;
01963
01964 if (!objptr) {
01965 objptr = (char*) cl->New();
01966 delobj = kTRUE;
01967 }
01968
01969
01970
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
01982
01983
01984
01985
01986
01987 TStreamerInfo* sinfo = BuildStreamerInfo(cl, objptr, splitlevel==0);
01988
01989
01990
01991
01992
01993
01994
01995
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
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
02016
02017
02018 if (splitlevel%kSplitCollectionOfPointers > 0) {
02019
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
02033
02034
02035
02036 Bool_t isBase = (element->IsA() == TStreamerBase::Class());
02037 if (isBase) {
02038 TClass* clbase = element->GetClassPointer();
02039 if ((clbase == TObject::Class()) && cl->CanIgnoreTObjectStreamer()) {
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050 --id;
02051 continue;
02052 }
02053 }
02054 if (dot) {
02055 if (dotlast) {
02056 bname.Form("%s%s", name, element->GetFullName());
02057 } else {
02058
02059
02060
02061
02062
02063
02064 if (isBase) {
02065
02066
02067
02068
02069
02070
02071 bname = name;
02072 } else {
02073 bname.Form("%s.%s", name, element->GetFullName());
02074 }
02075 }
02076 } else {
02077
02078
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
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
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 )
02135 {
02136
02137
02138
02139
02140
02141
02142
02143
02144
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 , Bool_t canOptimize )
02157 {
02158
02159
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
02169
02170
02171 sinfo->SetBit(TVirtualStreamerInfo::kCannotOptimize);
02172 sinfo->Compile();
02173 }
02174
02175
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
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
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
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
02288
02289 TBranch* branch = 0;
02290 TObject* obj = 0;
02291 while ((obj = file->GetList()->First())) {
02292 file->Remove(obj);
02293
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
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
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
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346 if (GetMakeClass()) {
02347
02348 return kMakeClass;
02349 }
02350
02351
02352 TClass* expectedClass = 0;
02353 EDataType expectedType = kOther_t;
02354 if (0 != branch->GetExpectedType(expectedClass,expectedType) ) {
02355
02356 return kInternalError;
02357 }
02358 if (expectedClass && ptrClass && (branch->GetMother() == branch)) {
02359
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
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
02407
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
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 , Option_t* option )
02442 {
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510 Bool_t fastClone = kFALSE;
02511
02512 TString opt = option;
02513 opt.ToLower();
02514 if (opt.Contains("fast")) {
02515 fastClone = kTRUE;
02516 }
02517
02518
02519 if ((fEntries > 0) && (LoadTree(0) < 0)) {
02520
02521 return 0;
02522 }
02523
02524
02525
02526 TTree* thistree = GetTree();
02527
02528
02529
02530 TTree* newtree = (TTree*) thistree->Clone();
02531 if (!newtree) {
02532 return 0;
02533 }
02534
02535
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
02546
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
02563
02564
02565
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
02581
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
02626 newtree->SetMakeClass(fMakeClass);
02627
02628
02629 CopyAddresses(newtree);
02630
02631
02632
02633
02634
02635 if (nentries != 0) {
02636 if (fastClone && (nentries < 0)) {
02637 if ( newtree->CopyEntries( this, -1, option ) < 0 ) {
02638
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
02656
02657
02658
02659
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
02675
02676 TLeaf *firstleaf = (TLeaf*)branch->GetListOfLeaves()->At(0);
02677 if (!firstleaf || firstleaf->GetValuePointer()) {
02678
02679
02680
02681 continue;
02682 }
02683 }
02684
02685 branch->SetAddress(0);
02686 addr = branch->GetAddress();
02687 }
02688
02689
02690 TBranch* br = tree->GetBranch(branch->GetName());
02691 if (br) {
02692 br->SetAddress(addr);
02693
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
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
02722 tree->ResetBranchAddress(tbranch);
02723 } else {
02724 if (!branch->GetAddress() && !leaf->GetValuePointer()) {
02725
02726
02727
02728
02729
02730
02731
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
02739
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
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
02779 break;
02780 case kBuild:
02781
02782 oldtree->GetTree()->BuildIndex(newtree->GetTreeIndex()->GetMajorName(), newtree->GetTreeIndex()->GetMinorName());
02783 newtree->GetTreeIndex()->Append(oldtree->GetTree()->GetTreeIndex(), kTRUE);
02784
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
02794 switch (onIndexError) {
02795 case kDrop:
02796
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
02807 TVirtualIndex *index = (TVirtualIndex*) oldtree->GetTree()->GetTreeIndex()->Clone();
02808 index->SetTree(newtree);
02809 newtree->SetTreeIndex(index);
02810 } else {
02811
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
02819
02820 withIndex = kFALSE;
02821 }
02822 return withIndex;
02823 }
02824 }
02825
02826
02827 Long64_t TTree::CopyEntries(TTree* tree, Long64_t nentries , Option_t* option )
02828 {
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863 if (!tree) {
02864 return 0;
02865 }
02866
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
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
02915
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);
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);
02970 }
02971 }
02972 return nbytes;
02973 }
02974
02975
02976 TTree* TTree::CopyTree(const char* selection, Option_t* option , Long64_t nentries , Long64_t firstentry )
02977 {
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
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
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
03041
03042
03043
03044
03045
03046
03047 TFile *file = GetCurrentFile();
03048
03049
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
03057 TKey *key = fDirectory->GetKey(GetName());
03058 if (!key) return;
03059
03060 TDirectory *dirsav = gDirectory;
03061 file->cd();
03062
03063
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
03087
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
03105 gCint->DeleteGlobal(this);
03106
03107
03108 delete this;
03109 }
03110
03111
03112 void TTree::DirectoryAutoAdd(TDirectory* dir)
03113 {
03114
03115
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
03135
03136
03137
03138
03139
03140
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
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251
03252
03253
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412
03413
03414
03415
03416
03417
03418
03419
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441
03442
03443
03444
03445
03446
03447
03448
03449
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511
03512
03513
03514
03515
03516
03517
03518
03519
03520
03521
03522
03523
03524
03525
03526
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540
03541
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571
03572
03573
03574
03575
03576
03577
03578
03579
03580
03581
03582
03583
03584
03585
03586
03587
03588
03589
03590
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606
03607
03608
03609
03610
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620
03621
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635
03636
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
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
03662
03663
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
03687
03688
03689
03690
03691
03692
03693
03694
03695
03696
03697
03698
03699
03700
03701
03702
03703
03704
03705
03706
03707
03708
03709
03710
03711
03712
03713
03714
03715
03716
03717
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728 Int_t nbytes = 0;
03729 Int_t nerror = 0;
03730 Int_t nb = fBranches.GetEntriesFast();
03731 if (nb == 1) {
03732
03733
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
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
03778 if (fFlushedBytes == 0) {
03779
03780
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
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;
03791
03792 if (fAutoSave < 0) {
03793
03794
03795
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();
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
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
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
03817
03818
03819
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
03838
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
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
03886
03887
03888
03889
03890
03891 if (kFindBranch & fFriendLockStatus) {
03892 return 0;
03893 }
03894
03895 TBranch* branch = 0;
03896
03897
03898
03899
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
03905 branch = R__FindBranchHelper(GetListOfBranches(), branchname);
03906 if (branch) return branch;
03907
03908
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
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
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
03960
03961
03962
03963 if (kFindLeaf & fFriendLockStatus) {
03964 return 0;
03965 }
03966
03967
03968
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
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
04005
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
04037
04038
04039
04040
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
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
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
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103
04104
04105
04106
04107
04108
04109
04110
04111
04112
04113
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
04126
04127
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
04156
04157
04158
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
04197
04198 if (name == 0) return 0;
04199
04200
04201
04202 if (kGetBranch & fFriendLockStatus) {
04203 return 0;
04204 }
04205
04206
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
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
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
04261
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
04290
04291
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
04304
04305
04306
04307 return fgBranchStyle;
04308 }
04309
04310
04311 TFile* TTree::GetCurrentFile() const
04312 {
04313
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
04325
04326
04327
04328
04329
04330
04331
04332
04333
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
04346
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
04361
04362
04363
04364
04365
04366
04367
04368
04369
04370
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380
04381
04382
04383
04384
04385
04386
04387
04388
04389
04390
04391
04392
04393
04394
04395
04396
04397
04398
04399
04400
04401
04402
04403
04404
04405
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422
04423
04424
04425
04426
04427
04428
04429
04430
04431
04432
04433
04434
04435
04436
04437
04438
04439
04440
04441
04442
04443
04444
04445
04446
04447
04448
04449
04450
04451
04452
04453
04454
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
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
04498
04499 return fEntryList;
04500 }
04501
04502
04503 Long64_t TTree::GetEntryNumber(Long64_t entry) const
04504 {
04505
04506
04507
04508
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
04521
04522
04523
04524
04525
04526
04527
04528
04529
04530
04531
04532
04533
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
04545
04546
04547
04548
04549
04550
04551
04552
04553
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
04565
04566
04567
04568
04569
04570
04571
04572
04573
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
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
04614
04615
04616
04617
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
04634
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
04650
04651
04652
04653
04654
04655
04656
04657
04658
04659
04660
04661
04662
04663
04664
04665
04666
04667
04668
04669
04670
04671
04672 if ((tree == this) || (tree == GetTree())) {
04673 return 0;
04674 }
04675
04676
04677
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
04693 if (t->GetTree() == tree) {
04694 return fe->GetName();
04695 }
04696 }
04697
04698
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
04714
04715 return new TTreeFriendLeafIter(this, dir);
04716 }
04717
04718
04719 TLeaf* TTree::GetLeaf(const char* aname)
04720 {
04721
04722
04723
04724
04725 if (aname == 0) return 0;
04726
04727
04728
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
04763 if (strncmp(brname,aname+motherlen+1,nbch-motherlen-1)) {
04764
04765 continue;
04766 }
04767 } else {
04768
04769 continue;
04770 }
04771 } else {
04772 continue;
04773 }
04774 }
04775
04776
04777
04778
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
04798
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
04827
04828
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
04854
04855 return fgMaxTreeSize;
04856 }
04857
04858
04859 Double_t TTree::GetMinimum(const char* columname)
04860 {
04861
04862
04863
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
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
04901
04902
04903
04904
04905
04906
04907
04908
04909
04910
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
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
04938
04939
04940
04941
04942
04943
04944
04945
04946
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();
04955 }
04956 return nimported;
04957 }
04958
04959
04960 Long64_t TTree::LoadTree(Long64_t entry)
04961 {
04962
04963
04964
04965
04966
04967
04968
04969
04970
04971 if (kLoadTree & fFriendLockStatus) {
04972
04973
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
04987
04988
04989
04990 Bool_t needUpdate = kFALSE;
04991 {
04992
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
04999
05000 continue;
05001 }
05002 TTree* friendTree = fe->GetTree();
05003 if (friendTree->IsA() == TTree::Class()) {
05004
05005 if (friendTree->LoadTreeFriend(entry, this) >= 0) {
05006 friendHasEntry = kTRUE;
05007 }
05008 } else {
05009
05010
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
05018
05019 needUpdate = kTRUE;
05020 }
05021 }
05022 }
05023 }
05024 if (needUpdate) {
05025
05026 if (fPlayer) {
05027 fPlayer->UpdateFormulaLeaves();
05028 }
05029
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
05047
05048
05049
05050
05051
05052
05053
05054
05055
05056
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
05069
05070
05071
05072
05073
05074
05075
05076
05077
05078
05079
05080
05081
05082
05083
05084
05085
05086
05087
05088
05089
05090
05091
05092
05093
05094
05095
05096
05097
05098
05099
05100
05101
05102
05103
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
05117
05118
05119
05120
05121
05122
05123
05124
05125
05126
05127
05128
05129
05130
05131
05132
05133
05134
05135
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
05148
05149
05150
05151
05152
05153
05154
05155
05156
05157
05158
05159
05160
05161
05162
05163
05164
05165
05166
05167
05168
05169
05170
05171
05172
05173
05174
05175
05176
05177
05178
05179
05180
05181
05182
05183
05184
05185
05186
05187
05188
05189
05190
05191
05192
05193
05194
05195
05196
05197
05198
05199
05200
05201
05202
05203
05204
05205
05206
05207
05208
05209
05210
05211
05212
05213
05214
05215
05216
05217
05218
05219
05220
05221
05222
05223
05224
05225
05226
05227
05228
05229
05230
05231
05232
05233
05234
05235
05236
05237
05238
05239
05240
05241
05242
05243
05244
05245
05246
05247
05248
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
05259
05260
05261
05262
05263
05264
05265
05266
05267
05268
05269
05270
05271
05272
05273
05274
05275
05276
05277
05278
05279
05280
05281
05282
05283
05284
05285
05286
05287 return MakeClass(selector, "selector");
05288 }
05289
05290
05291 Bool_t TTree::MemoryFull(Int_t nbytes)
05292 {
05293
05294
05295 if ((fTotalBuffers + nbytes) < fMaxVirtualSize) {
05296 return kFALSE;
05297 }
05298 return kTRUE;
05299 }
05300
05301
05302 TTree* TTree::MergeTrees(TList* li, Option_t* )
05303 {
05304
05305
05306
05307
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
05324
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();
05337 if (newtree->GetTreeIndex()) {
05338 newtree->GetTreeIndex()->Append(tree->GetTreeIndex(),kTRUE);
05339 }
05340 }
05341 if (newtree && newtree->GetTreeIndex()) {
05342 newtree->GetTreeIndex()->Append(0,kFALSE);
05343 }
05344 return newtree;
05345 }
05346
05347
05348 Long64_t TTree::Merge(TCollection* li, Option_t* )
05349 {
05350
05351
05352
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);
05380 }
05381 return GetEntries();
05382 }
05383
05384
05385 Bool_t TTree::Notify()
05386 {
05387
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
05402
05403
05404
05405
05406
05407
05408
05409
05410
05411
05412
05413
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
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
05433
05434
05435 for (Int_t pass =0;pass<2;pass++) {
05436 oldMemsize = 0;
05437 newMemsize = 0;
05438 oldBaskets = 0;
05439 newBaskets = 0;
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;
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
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;
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
05493
05494
05495
05496
05497
05498
05499
05500
05501
05502
05503
05504
05505
05506
05507
05508
05509
05510
05511
05512
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
05526
05527
05528
05529
05530
05531
05532
05533
05534
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
05604 if (fBranchRef) fBranchRef->Print(option);
05605
05606
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
05621
05622
05623
05624
05625
05626
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
05638
05639
05640
05641
05642
05643
05644
05645
05646
05647
05648
05649
05650
05651
05652
05653
05654
05655
05656
05657
05658
05659
05660
05661
05662
05663
05664
05665
05666
05667
05668
05669
05670
05671
05672
05673
05674
05675
05676
05677
05678
05679
05680
05681
05682
05683
05684
05685
05686
05687
05688
05689
05690
05691
05692
05693
05694
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
05708
05709
05710
05711
05712
05713
05714
05715
05716
05717
05718
05719
05720
05721
05722
05723
05724
05725
05726
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
05739
05740
05741
05742
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
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
05771
05772
05773
05774
05775
05776
05777
05778
05779
05780
05781
05782
05783
05784
05785
05786
05787
05788
05789
05790
05791
05792
05793
05794
05795
05796
05797
05798
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
05813
05814
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
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
05841
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
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
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
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
05916
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
05945
05946
05947
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
05959 fEntries = tree->fEntries;
05960 fTotBytes = tree->fTotBytes;
05961 fZipBytes = tree->fZipBytes;
05962 fSavedBytes = tree->fSavedBytes;
05963 fTotalBuffers = tree->fTotalBuffers;
05964
05965
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
05982
05983
05984
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
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
06036
06037
06038
06039 if (br && br->GetTree()) {
06040 br->ResetAddress();
06041 }
06042 }
06043
06044
06045 void TTree::ResetBranchAddresses()
06046 {
06047
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
06061
06062
06063
06064
06065
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
06079
06080
06081
06082
06083
06084
06085
06086
06087
06088
06089
06090
06091
06092
06093
06094
06095
06096
06097
06098
06099
06100
06101
06102
06103
06104
06105
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
06131
06132
06133
06134
06135
06136
06137
06138
06139
06140
06141
06142
06143
06144
06145
06146
06147
06148
06149
06150
06151
06152
06153
06154
06155
06156
06157 fAutoFlush = autof;
06158 }
06159
06160
06161 void TTree::SetAutoSave(Long64_t autos)
06162 {
06163
06164
06165
06166
06167
06168
06169
06170 fAutoSave = autos;
06171 }
06172
06173
06174 void TTree::SetBasketSize(const char* bname, Int_t buffsize)
06175 {
06176
06177
06178
06179
06180
06181
06182
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
06207
06208
06209
06210
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
06225
06226
06227
06228
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
06238
06239
06240
06241
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
06262
06263
06264
06265
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
06292
06293
06294
06295
06296
06297
06298
06299
06300
06301
06302
06303
06304
06305
06306
06307
06308
06309
06310
06311
06312
06313
06314
06315
06316
06317
06318
06319
06320
06321
06322
06323
06324
06325
06326
06327
06328
06329
06330
06331
06332
06333
06334
06335
06336
06337
06338
06339
06340
06341
06342
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
06356
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,"*")) {
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
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
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
06421
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
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
06451
06452
06453
06454
06455 fgBranchStyle = style;
06456 }
06457
06458
06459 void TTree::SetCacheSize(Long64_t cacheSize)
06460 {
06461
06462
06463
06464
06465
06466
06467
06468
06469
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
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
06519
06520 TTreeCache::SetLearnEntries(n);
06521 }
06522
06523
06524 void TTree::SetCircular(Long64_t maxEntries)
06525 {
06526
06527
06528
06529
06530
06531
06532
06533
06534
06535
06536
06537
06538
06539
06540
06541
06542
06543
06544
06545
06546
06547 if (maxEntries <= 0) {
06548
06549 fMaxEntries = 1000000000;
06550 fMaxEntries *= 1000;
06551 ResetBit(kCircular);
06552
06553
06554
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
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
06578
06579
06580
06581
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
06592
06593
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
06615
06616
06617
06618
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
06649
06650
06651
06652
06653
06654
06655
06656
06657
06658
06659
06660
06661
06662
06663 if (n >= 0) {
06664 fEntries = n;
06665 return n;
06666 }
06667
06668
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 * )
06691 {
06692
06693
06694 if (fEntryList) {
06695
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
06714
06715
06716
06717 fEventList = evlist;
06718 if (fEntryList){
06719 if (fEntryList->TestBit(kCanDelete)) {
06720 TEntryList *tmp = fEntryList;
06721 fEntryList = 0;
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);
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
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
06769
06770
06771
06772
06773
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
06787
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
06802
06803
06804
06805
06806
06807
06808
06809
06810 fgMaxTreeSize = maxsize;
06811 }
06812
06813
06814 void TTree::SetName(const char* name)
06815 {
06816
06817
06818 if (gPad) {
06819 gPad->Modified();
06820 }
06821
06822
06823 if (fDirectory) {
06824 fDirectory->Remove(this);
06825 }
06826
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
06837
06838 if (gPad) {
06839 gPad->Modified();
06840 }
06841
06842
06843
06844 if (fDirectory) {
06845 fDirectory->Remove(this);
06846 }
06847
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
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
06874
06875
06876
06877
06878
06879
06880
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
06892
06893
06894
06895
06896
06897
06898
06899
06900
06901
06902
06903
06904
06905
06906
06907
06908
06909
06910 fWeight = w;
06911 }
06912
06913
06914 void TTree::Show(Long64_t entry, Int_t lenmax)
06915 {
06916
06917
06918
06919
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
06991
06992
06993
06994
06995 GetPlayer();
06996 if (fPlayer) {
06997 fPlayer->StartViewer(600, 400);
06998 }
06999 }
07000
07001
07002 void TTree::StopCacheLearningPhase()
07003 {
07004
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
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
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
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
07081
07082
07083
07084
07085
07086
07087
07088
07089
07090
07091
07092
07093
07094
07095
07096
07097
07098
07099
07100
07101
07102
07103
07104
07105
07106
07107
07108
07109
07110
07111
07112
07113
07114
07115
07116
07117
07118
07119
07120
07121
07122
07123
07124
07125
07126
07127
07128
07129
07130
07131
07132
07133
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
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
07172
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
07182
07183
07184 return ((const TTree*)this)->Write(name, option, bufsize);
07185 }
07186
07187
07188
07189
07190
07191
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
07205
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
07217
07218 }
07219
07220
07221 TIterator& TTreeFriendLeafIter::operator=(const TIterator& rhs)
07222 {
07223
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
07236
07237 if (this != &rhs) {
07238 fDirection = rhs.fDirection;
07239 }
07240 return *this;
07241 }
07242
07243
07244 TObject* TTreeFriendLeafIter::Next()
07245 {
07246
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;
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
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
07283
07284 if (fLeafIter) return fLeafIter->GetOption();
07285 return "";
07286 }