TBranchClones.cxx

Go to the documentation of this file.
00001 // @(#)root/tree:$Id: TBranchClones.cxx 33097 2010-04-19 21:47:55Z pcanal $
00002 // Author: Rene Brun   11/02/96
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // A Branch for the case of an array of clone objects                   //
00015 //                                                                      //
00016 // See TTree.                                                           //
00017 //                                                                      //
00018 //////////////////////////////////////////////////////////////////////////
00019 
00020 #include "TBranchClones.h"
00021 
00022 #include "TBasket.h"
00023 #include "TClass.h"
00024 #include "TClonesArray.h"
00025 #include "TDataMember.h"
00026 #include "TDataType.h"
00027 #include "TFile.h"
00028 #include "TLeafI.h"
00029 #include "TRealData.h"
00030 #include "TTree.h"
00031 
00032 #include <cstring>
00033 
00034 R__EXTERN TTree* gTree;
00035 
00036 ClassImp(TBranchClones)
00037 
00038 //______________________________________________________________________________
00039 TBranchClones::TBranchClones()
00040 : TBranch()
00041 , fList(0)
00042 , fRead(0)
00043 , fN(0)
00044 , fNdataMax(0)
00045 , fBranchCount(0)
00046 {
00047    // -- Default and i/o constructor.
00048 
00049 }
00050 
00051 //______________________________________________________________________________
00052 TBranchClones::TBranchClones(TTree *tree, const char* name, void* pointer, Int_t basketsize, Int_t compress, Int_t splitlevel)
00053 : TBranch()
00054 , fList(0)
00055 , fRead(0)
00056 , fN(0)
00057 , fNdataMax(0)
00058 , fBranchCount(0)
00059 {
00060    // -- Constructor.
00061 
00062    Init(tree,0,name,pointer,basketsize,compress,splitlevel);
00063 }
00064 
00065 //______________________________________________________________________________
00066 TBranchClones::TBranchClones(TBranch *parent, const char* name, void* pointer, Int_t basketsize, Int_t compress, Int_t splitlevel)
00067 : TBranch()
00068 , fList(0)
00069 , fRead(0)
00070 , fN(0)
00071 , fNdataMax(0)
00072 , fBranchCount(0)
00073 {
00074    // -- Constructor.
00075 
00076    Init(0,parent,name,pointer,basketsize,compress,splitlevel);
00077 }
00078 
00079 //______________________________________________________________________________
00080 void TBranchClones::Init(TTree *tree, TBranch *parent, const char* name, void* pointer, Int_t basketsize, Int_t compress, Int_t splitlevel)
00081 {
00082    // Initialization (non-virtual, to be called from constructor).
00083 
00084    if (tree==0 && parent!=0) tree = parent->GetTree();
00085    fTree   = tree;
00086    fMother = parent ? parent->GetMother() : this;
00087    fParent = parent;
00088 
00089    TString leaflist;
00090    TString branchname;
00091    TString branchcount;
00092    SetName(name);
00093    if ((compress == -1) && tree->GetDirectory()) {
00094       TFile* bfile = 0;
00095       if (tree->GetDirectory()) {
00096          bfile = tree->GetDirectory()->GetFile();
00097       }
00098       if (bfile) {
00099          compress = bfile->GetCompressionLevel();
00100       }
00101    }
00102    char* cpointer = (char*) pointer;
00103    char** ppointer = (char**) pointer;
00104    fList = (TClonesArray*) *ppointer;
00105    fAddress = cpointer;
00106    TClass* cl = fList->GetClass();
00107    if (!cl) {
00108       return;
00109    }
00110    tree->BuildStreamerInfo(cl);
00111    fClassName = cl->GetName();
00112    fSplitLevel = splitlevel;
00113 
00114    // Create a branch to store the array count.
00115    if (basketsize < 100) {
00116       basketsize = 100;
00117    }
00118    leaflist.Form("%s_/I", name);
00119    branchcount.Form("%s_", name);
00120    fBranchCount = new TBranch(this, branchcount, &fN, leaflist, basketsize);
00121    fBranchCount->SetBit(kIsClone);
00122    TLeaf* leafcount = (TLeaf*) fBranchCount->GetListOfLeaves()->UncheckedAt(0);
00123    fDirectory = fTree->GetDirectory();
00124    fFileName = "";
00125 
00126    // Loop on all public data members of the class and its base classes.
00127    const char* itype = 0;
00128    TRealData* rd = 0;
00129    TIter next(cl->GetListOfRealData());
00130    while ((rd = (TRealData *) next())) {
00131       if (rd->TestBit(TRealData::kTransient)) continue;
00132 
00133       if (rd->IsObject()) {
00134          continue;
00135       }
00136       TDataMember* member = rd->GetDataMember();
00137       if (!member->IsPersistent()) {
00138          // -- Skip non-persistent members.
00139          continue;
00140       }
00141       if (!member->IsBasic() || member->IsaPointer()) {
00142          Warning("BranchClones", "Cannot process: %s::%s", cl->GetName(), member->GetName());
00143          continue;
00144       }
00145       // Forget TObject part if splitlevel = 2.
00146       if ((splitlevel > 1) || fList->TestBit(TClonesArray::kForgetBits) || cl->CanIgnoreTObjectStreamer()) {
00147          if (!std::strcmp(member->GetName(), "fBits")) {
00148             continue;
00149          }
00150          if (!std::strcmp(member->GetName(), "fUniqueID")) {
00151             continue;
00152          }
00153       }
00154       tree->BuildStreamerInfo(TClass::GetClass(member->GetFullTypeName()));
00155       TDataType* membertype = member->GetDataType();
00156       Int_t type = membertype->GetType();
00157       if (!type) {
00158          Warning("BranchClones", "Cannot process: %s::%s of type zero!", cl->GetName(), member->GetName());
00159          continue;
00160       }
00161 
00162       if (type ==  1) {
00163          itype = "B";
00164       } else if (type == 2) {
00165          itype = "S";
00166       } else if (type == 3) {
00167          itype = "I";
00168       } else if (type == 5) {
00169          itype = "F";
00170       } else if (type == 8) {
00171          itype = "D";
00172       } else if (type == 9) {
00173          itype = "D";
00174       } else if (type == 11) {
00175          itype = "b";
00176       } if (type == 12) {
00177          itype = "s";
00178       } if (type == 13) {
00179          itype = "i";
00180       }
00181 
00182       leaflist.Form("%s[%s]/%s", member->GetName(), branchcount.Data(), itype);
00183       Int_t comp = compress;
00184       if (type == 5) {
00185          comp--;
00186       }
00187       branchname.Form("%s.%s", name, rd->GetName());
00188       TBranch* branch  = new TBranch(this, branchname, this, leaflist, basketsize, comp);
00189       branch->SetBit(kIsClone);
00190       TObjArray* leaves = branch->GetListOfLeaves();
00191       TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(0);
00192       leaf->SetOffset(rd->GetThisOffset());
00193       leaf->SetLeafCount(leafcount);
00194       Int_t arraydim = member->GetArrayDim();
00195       if (arraydim) {
00196          Int_t maxindex = 1;
00197          while (arraydim) {
00198             maxindex *= member->GetMaxIndex(--arraydim);
00199          }
00200          leaf->SetLen(maxindex);
00201       }
00202       fBranches.Add(branch);
00203    }
00204 }
00205 
00206 //______________________________________________________________________________
00207 TBranchClones::~TBranchClones()
00208 {
00209    // -- Destructor.
00210 
00211    delete fBranchCount;
00212    fBranchCount = 0;
00213    fBranches.Delete();
00214    // FIXME: We might own this, possible memory leak.
00215    fList = 0;
00216 }
00217 
00218 //______________________________________________________________________________
00219 void TBranchClones::Browse(TBrowser* b)
00220 {
00221    // -- Browse this branch.
00222 
00223    fBranches.Browse(b);
00224 }
00225 
00226 //______________________________________________________________________________
00227 Int_t TBranchClones::Fill()
00228 {
00229    // -- Loop on all branches and fill Basket buffer.
00230 
00231    Int_t i = 0;
00232    Int_t nbytes = 0;
00233    Int_t nbranches = fBranches.GetEntriesFast();
00234    char** ppointer = (char**) fAddress;
00235    if (!ppointer) {
00236       return 0;
00237    }
00238    fList = (TClonesArray*) *ppointer;
00239    fN = fList->GetEntriesFast();
00240    fEntries++;
00241    if (fN > fNdataMax) {
00242       fNdataMax = fList->GetSize();
00243       TString branchcount;
00244       branchcount.Form("%s_", GetName());
00245       TLeafI* leafi = (TLeafI*) fBranchCount->GetLeaf(branchcount);
00246       leafi->SetMaximum(fNdataMax);
00247       for (i = 0; i < nbranches; i++) {
00248          TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
00249          TObjArray* leaves = branch->GetListOfLeaves();
00250          TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(0);
00251          leaf->SetAddress();
00252       }
00253    }
00254    nbytes += fBranchCount->Fill();
00255    for (i = 0; i < nbranches; i++)  {
00256       TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
00257       TObjArray* leaves = branch->GetListOfLeaves();
00258       TLeaf* leaf = (TLeaf*) leaves->UncheckedAt(0);
00259       leaf->Import(fList, fN);
00260       nbytes += branch->Fill();
00261    }
00262    return nbytes;
00263 }
00264 
00265 //______________________________________________________________________________
00266 Int_t TBranchClones::GetEntry(Long64_t entry, Int_t getall)
00267 {
00268    // -- Read all branches and return total number of bytes read.
00269 
00270    if (TestBit(kDoNotProcess) && !getall) {
00271       return 0;
00272    }
00273    Int_t nbytes = fBranchCount->GetEntry(entry, getall);
00274    TLeaf* leafcount = (TLeaf*) fBranchCount->GetListOfLeaves()->UncheckedAt(0);
00275    fN = Int_t(leafcount->GetValue());
00276    if (fN <= 0) {
00277       if (fList) {
00278          fList->Clear();
00279       }
00280       return 0;
00281    }
00282    TBranch* branch = 0;
00283    Int_t nbranches = fBranches.GetEntriesFast();
00284    // If fList exists, create clones array objects.
00285    if (fList) {
00286       fList->Clear();
00287       fList->ExpandCreateFast(fN);
00288       for (Int_t i = 0; i < nbranches; i++)  {
00289          branch = (TBranch*) fBranches.UncheckedAt(i);
00290          if (((TLeaf*) branch->GetListOfLeaves()->UncheckedAt(0))->GetOffset() < 0) {
00291             continue;
00292          }
00293          nbytes += branch->GetEntryExport(entry, getall, fList, fN);
00294       }
00295    } else {
00296       for (Int_t i = 0; i < nbranches; i++)  {
00297          branch = (TBranch*) fBranches.UncheckedAt(i);
00298          nbytes += branch->GetEntry(entry, getall);
00299       }
00300    }
00301    return nbytes;
00302 }
00303 
00304 //______________________________________________________________________________
00305 void TBranchClones::Print(Option_t *option) const
00306 {
00307    // -- Print branch parameters.
00308 
00309    fBranchCount->Print(option);
00310    Int_t nbranches = fBranches.GetEntriesFast();
00311    for (Int_t i = 0; i < nbranches; i++) {
00312       TBranch* branch = (TBranch*) fBranches.At(i);
00313       branch->Print(option);
00314    }
00315 }
00316 
00317 //______________________________________________________________________________
00318 void TBranchClones::Reset(Option_t* option)
00319 {
00320    // -- Reset branch.
00321    //
00322    //    Existing buffers are deleted
00323    //    Entries, max and min are reset
00324    //
00325 
00326    fEntries = 0;
00327    fTotBytes = 0;
00328    fZipBytes = 0;
00329    Int_t nbranches = fBranches.GetEntriesFast();
00330    for (Int_t i = 0; i < nbranches; i++) {
00331       TBranch* branch = (TBranch*) fBranches.At(i);
00332       branch->Reset(option);
00333    }
00334    fBranchCount->Reset();
00335 }
00336 
00337 //______________________________________________________________________________
00338 void TBranchClones::SetAddress(void* addr)
00339 {
00340    // -- Set address of this branch.
00341 
00342    fReadEntry = -1;
00343    fAddress = (char*) addr;
00344    char** pp= (char**) fAddress;
00345    if (pp && (*pp == 0)) {
00346       // We've been asked to allocate an object for the user.
00347       *pp= (char*) new TClonesArray(fClassName);
00348    }
00349    fList = 0;
00350    if (pp) {
00351       fList = (TClonesArray*) *pp;
00352    }
00353    fBranchCount->SetAddress(&fN);
00354 }
00355 
00356 //______________________________________________________________________________
00357 void TBranchClones::SetBasketSize(Int_t buffsize)
00358 {
00359    // -- Reset basket size for all sub-branches.
00360 
00361    TBranch::SetBasketSize(buffsize);
00362 
00363    Int_t nbranches = fBranches.GetEntriesFast();
00364    for (Int_t i = 0; i < nbranches; i++)  {
00365       TBranch* branch = (TBranch*) fBranches[i];
00366       branch->SetBasketSize(fBasketSize);
00367    }
00368 }
00369 
00370 //_______________________________________________________________________
00371 void TBranchClones::Streamer(TBuffer& b)
00372 {
00373    // -- Serialize/Deserialize from a buffer.
00374    UInt_t R__s, R__c;
00375    if (b.IsReading()) {
00376       b.ReadVersion(&R__s, &R__c);
00377       TNamed::Streamer(b);
00378       b >> fCompress;
00379       b >> fBasketSize;
00380       b >> fEntryOffsetLen;
00381       b >> fMaxBaskets;
00382       b >> fWriteBasket;
00383       b >> fEntryNumber;
00384       b >> fEntries;
00385       b >> fTotBytes;
00386       b >> fZipBytes;
00387       b >> fOffset;
00388       b >> fBranchCount;
00389       fClassName.Streamer(b);
00390       fBranches.Streamer(b);
00391       fTree = gTree;
00392       TBranch* branch = 0;
00393       TLeaf* leaf = 0;
00394       Int_t nbranches = fBranches.GetEntriesFast();
00395       for (Int_t i = 0; i < nbranches; i++) {
00396          branch = (TBranch*) fBranches[i];
00397          branch->SetBit(kIsClone);
00398          leaf = (TLeaf*) branch->GetListOfLeaves()->UncheckedAt(0);
00399          leaf->SetOffset(-1);
00400       }
00401       fRead = 1;
00402       TClass* cl = TClass::GetClass((const char*) fClassName);
00403       if (!cl) {
00404          Warning("Streamer", "Unknown class: %s. Cannot read BranchClones: %s", fClassName.Data(), GetName());
00405          SetBit(kDoNotProcess);
00406          return;
00407       }
00408       if (!cl->GetListOfRealData()) {
00409          cl->BuildRealData();
00410       }
00411       TString branchname;
00412       TRealData* rd = 0;
00413       TIter next(cl->GetListOfRealData());
00414       while ((rd = (TRealData*) next())) {
00415          if (rd->TestBit(TRealData::kTransient)) continue;
00416 
00417          TDataMember* member = rd->GetDataMember();
00418          if (!member || !member->IsBasic() || !member->IsPersistent()) {
00419             continue;
00420          }
00421          TDataType* membertype = member->GetDataType();
00422          if (!membertype->GetType()) {
00423             continue;
00424          }
00425          branchname.Form("%s.%s", GetName(), rd->GetName());
00426          branch = (TBranch*) fBranches.FindObject(branchname);
00427          if (!branch) {
00428             continue;
00429          }
00430          TObjArray* leaves = branch->GetListOfLeaves();
00431          leaf = (TLeaf*) leaves->UncheckedAt(0);
00432          leaf->SetOffset(rd->GetThisOffset());
00433       }
00434       b.CheckByteCount(R__s, R__c, TBranchClones::IsA());
00435    } else {
00436       R__c = b.WriteVersion(TBranchClones::IsA(), kTRUE);
00437       TNamed::Streamer(b);
00438       b << fCompress;
00439       b << fBasketSize;
00440       b << fEntryOffsetLen;
00441       b << fMaxBaskets;
00442       b << fWriteBasket;
00443       b << fEntryNumber;
00444       b << fEntries;
00445       b << fTotBytes;
00446       b << fZipBytes;
00447       b << fOffset;
00448       b << fBranchCount;
00449       fClassName.Streamer(b);
00450       fBranches.Streamer(b);
00451       b.SetByteCount(R__c, kTRUE);
00452    }
00453 }
00454 
00455 //______________________________________________________________________________
00456 void TBranchClones::UpdateFile()
00457 {
00458    // Refresh the value of fDirectory (i.e. where this branch writes/reads its buffers)
00459    // with the current value of fTree->GetCurrentFile unless this branch has been
00460    // redirected to a different file.  Also update the sub-branches.
00461 
00462    fBranchCount->UpdateFile();
00463    TBranch::UpdateFile();
00464 }

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