00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
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
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
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
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
00139 continue;
00140 }
00141 if (!member->IsBasic() || member->IsaPointer()) {
00142 Warning("BranchClones", "Cannot process: %s::%s", cl->GetName(), member->GetName());
00143 continue;
00144 }
00145
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
00210
00211 delete fBranchCount;
00212 fBranchCount = 0;
00213 fBranches.Delete();
00214
00215 fList = 0;
00216 }
00217
00218
00219 void TBranchClones::Browse(TBrowser* b)
00220 {
00221
00222
00223 fBranches.Browse(b);
00224 }
00225
00226
00227 Int_t TBranchClones::Fill()
00228 {
00229
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
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
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
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
00321
00322
00323
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
00341
00342 fReadEntry = -1;
00343 fAddress = (char*) addr;
00344 char** pp= (char**) fAddress;
00345 if (pp && (*pp == 0)) {
00346
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
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
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
00459
00460
00461
00462 fBranchCount->UpdateFile();
00463 TBranch::UpdateFile();
00464 }