1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
19 #include "AliArrayBranch.h"
24 #include "TRealData.h"
25 #include "TDataType.h"
26 #include "TDataMember.h"
29 #include "TBranchClones.h"
37 #include "TLeafObject.h"
39 #include "AliObjectArray.h"
40 #include "AliDataType.h"
42 //-----------------------------------------------------
43 // A Branch for the case of an array of clone objects.
44 //-----------------------------------------------------
48 R__EXTERN TTree *gTree;
50 ClassImp(AliArraySubBranch)
51 ClassImp(AliArrayBranch)
52 ClassImp(AliObjectBranch)
57 Int_t AliArraySubBranch::GetEntryExport(Int_t entry, Int_t /*getall*/, AliObjectArray *list, Int_t nentries)
59 //*-*-*-*-*-*Read all leaves of entry and return total number of bytes*-*-*
60 //*-* export buffers to real objects in the AliObjectArray list.
63 if (TestBit(kDoNotProcess)) return 0;
64 if (fReadEntry == entry) return 1;
65 if (entry < 0 || entry >= fEntryNumber) return 0;
67 Int_t first = fBasketEntry[fReadBasket];
69 if (fReadBasket == fWriteBasket) last = fEntryNumber - 1;
70 else last = fBasketEntry[fReadBasket+1] - 1;
72 // Are we still in the same ReadBasket?
73 if (entry < first || entry > last) {
74 fReadBasket = TMath::BinarySearch(fWriteBasket+1, fBasketEntry, entry);
75 first = fBasketEntry[fReadBasket];
78 // We have found the basket containing this entry.
79 // make sure basket buffers are in memory.
80 TBasket *basket = GetBasket(fReadBasket);
81 if (!basket) return 0;
82 TBuffer *buf = basket->GetBufferRef();
83 // Set entry offset in buffer and read data from all leaves
84 if (!buf->IsReading()) {
85 basket->SetReadMode();
87 // Int_t bufbegin = basket->GetEntryPointer(entry-first);
89 Int_t *entryOffset = basket->GetEntryOffset();
90 if (entryOffset) bufbegin = entryOffset[entry-first];
91 else bufbegin = basket->GetKeylen() + (entry-first)*basket->GetNevBufSize();
92 buf->SetBufferOffset(bufbegin);
94 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0);
95 // leaf->ReadBasketExport(*buf,list,nentries); //!!! MI
96 ReadBasketExport(*buf,leaf, list,nentries);
97 nbytes = buf->Length() - bufbegin;
103 void AliArraySubBranch::ReadBasketExport(TBuffer &b, TLeaf *leaf, AliObjectArray *list, Int_t n)
107 Int_t len = leaf->GetLenStatic();
108 Int_t offset = leaf->GetOffset();
109 void *value = leaf->GetValuePointer();
112 if (leaf->IsA()==TLeafB::Class()){
114 for (Int_t i=0;i<n;i++) {
115 memcpy((char*)list->UncheckedAt(i) + offset,&((Char_t*)value)[j], len);
119 //variable length string.
120 if (leaf->IsA()==TLeafC::Class()){
124 if (len >= len) len = len-1;
125 b.ReadFastArray((Char_t*)value,len);
126 ((Char_t*)value)[len] = 0;
131 for (Int_t i=0;i<n;i++) {
132 memcpy((char*)list->UncheckedAt(i) + offset,&((Char_t*)value)[j], 1);
137 if (leaf->IsA()==TLeafD::Class()){
138 b.ReadFastArray(((Double_t*)value),n*len);
140 for (Int_t i=0;i<n;i++) {
141 memcpy((char*)list->UncheckedAt(i) + offset,&((Double_t*)value)[j], 8*len);
146 if (leaf->IsA()==TLeafF::Class()){
148 b >> ((Float_t*)value)[0];
150 b.ReadFastArray(((Float_t*)value),n*len);
153 Float_t *val = (Float_t*)value;
154 for (Int_t i=0;i<n;i++) {
155 char *first = (char*)list->UncheckedAt(i);
156 Float_t *ff = (Float_t*)&first[offset];
157 for (Int_t j=0;j<len;j++) {
165 if (leaf->IsA()==TLeafS::Class()){
167 b >> ((Short_t*)value)[0];
169 b.ReadFastArray(((Short_t*)value),n*len);
171 Short_t *val = (Short_t*)value;
172 for (Int_t i=0;i<n;i++) {
173 char *first = (char*)list->UncheckedAt(i);
174 Short_t *ii = (Short_t*)&first[offset];
175 for (Int_t j=0;j<len;j++) {
183 if (leaf->IsA()==TLeafI::Class()){
185 b >> ((Int_t*)value)[0];
187 b.ReadFastArray(((Int_t*)value),n*len);
189 Int_t *val = (Int_t*)value;
190 for (Int_t i=0;i<n;i++) {
191 char *first = (char*)list->UncheckedAt(i);
192 Int_t *ii = (Int_t*)&first[offset];
193 for (Int_t j=0;j<len;j++) {
203 //______________________________________________________________________________
204 AliArrayBranch::AliArrayBranch(): TBranch()
206 //*-*-*-*-*-*Default constructor for BranchClones*-*-*-*-*-*-*-*-*-*
207 //*-* ====================================
217 //______________________________________________________________________________
218 AliArrayBranch::AliArrayBranch(const Text_t *name, void *pointer, TTree * tree, Int_t basketsize, Int_t compress)
221 //*-*-*-*-*-*-*-*-*-*-*-*-*Create a BranchClones*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
222 //*-* =====================
226 char branchcount[64];
228 gTree = tree; // MI because some bug in ROOT I didn't obtain proper gTree
229 // it is necesary to set gTree because oder subranchces defined below need it
231 if (compress == -1) {
232 TFile *bfile = fTree->GetDirectory()->GetFile();
233 if (bfile) compress = bfile->GetCompressionLevel();
235 char *cpointer = (char*)pointer;
236 char **ppointer = (char**)(cpointer);
237 fList = (AliObjectArray*)(*ppointer);
243 AliClassInfo *clinfo = fList->GetClassInfo();
245 fClassName = clinfo->GetName();
247 //*-*- Create a branch to store the array count
248 if (basketsize < 100) basketsize = 100;
249 sprintf(leaflist,"%s_/I",name);
250 sprintf(branchcount,"%s_",name);
251 fBranchCount = new TBranch(branchcount,&fN,leaflist,basketsize);
252 fBranchCount->SetBit(kIsClone);
253 TLeaf *leafcount = (TLeaf*)fBranchCount->GetListOfLeaves()->UncheckedAt(0);
255 //*-*- Create the first basket
257 fDirectory = fTree->GetDirectory();
260 TBasket *basket = new TBasket(branchcount,fTree->GetName(),this);
261 fBaskets.Add(basket);
263 //*-*- Loop on all public data members of the class and its base classes
265 TClass *cl = fList->GetClass();
267 if (!cl->GetListOfRealData()) cl->BuildRealData();
269 const char *itype = 0;
271 TIter next(cl->GetListOfRealData());
272 while ((rd = (TRealData *) next())) {
273 TDataMember *member = rd->GetDataMember();
274 if (!member->IsBasic()) {
275 Warning("BranchClones","Cannot process member:%s",member->GetName());
278 if (!member->IsPersistent()) continue; //do not process members with a ! as the first
279 // character in the comment field
280 TDataType *membertype = member->GetDataType();
281 Int_t type = membertype->GetType();
283 Warning("BranchClones","Cannot process member:%s",member->GetName());
286 if (type == 1) itype = "B";
287 if (type == 11) itype = "b";
288 if (type == 3) itype = "I";
289 if (type == 5) itype = "F";
290 if (type == 8) itype = "D";
291 if (type == 13) itype = "i";
292 if (type == 2) itype = "S";
293 if (type == 12) itype = "s";
296 Int_t arraydim = member->GetArrayDim();
299 sprintf(leaflist,"%s[%s]/%s",member->GetName(),branchcount,itype);
300 Int_t comp = compress;
301 if (type == 5) comp--;
302 sprintf(branchname,"%s.%s",name,rd->GetName());
303 TBranch *branch = new AliArraySubBranch(branchname,this,leaflist,basketsize,comp);
304 branch->SetBit(kIsClone);
305 TObjArray *leaves = branch->GetListOfLeaves();
306 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
307 leaf->SetOffset(rd->GetThisOffset());
308 leaf->SetLeafCount(leafcount);
309 Int_t arraydim = member->GetArrayDim();
311 Int_t maxindex = member->GetMaxIndex(arraydim-1);
312 leaf->SetLen(maxindex);
314 fBranches.Add(branch);
317 for (Int_t i=0;i< member->GetMaxIndex(0);i++){
318 const char * dmname = member->GetName() ;
321 while ( (dmname[j]!='[') && (dmname[j]!=0) ){
326 sprintf(leaflist,"%s(%d)[%s]/%s",bname,i,branchcount,itype);
327 Int_t comp = compress;
328 if (type == 5) comp--;
329 sprintf(branchname,"%s.%s(%d)",name,bname,i);
330 TBranch *branch = new AliArraySubBranch(branchname,this,leaflist,basketsize,comp);
331 branch->SetBit(kIsClone);
332 TObjArray *leaves = branch->GetListOfLeaves();
333 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
334 leaf->SetOffset(rd->GetThisOffset()+membertype->Size()*i);
335 leaf->SetLeafCount(leafcount);
336 fBranches.Add(branch);
341 else if (clinfo->IsA()->InheritsFrom("AliDataType")){ //branch for basic type
342 Int_t type = (((AliDataType*)clinfo)->GetDataType())->GetType();
343 const char *itype = 0;
345 Warning("BranchClones","Cannot process member:%s",clinfo->GetName());
348 if (type == 1) itype = "B";
349 if (type == 11) itype = "b";
350 if (type == 3) itype = "I";
351 if (type == 5) itype = "F";
352 if (type == 8) itype = "D";
353 if (type == 13) itype = "i";
354 if (type == 2) itype = "S";
355 if (type == 12) itype = "s";
356 sprintf(leaflist,"%s[%s]/%s",name,branchcount,itype);
357 Int_t comp = compress;
358 if (type == 5) comp--;
359 sprintf(branchname,"%s",clinfo->GetName());
360 TBranch *branch = new AliArraySubBranch(branchname,this,leaflist,basketsize,comp);
361 branch->SetBit(kIsClone);
362 TObjArray *leaves = branch->GetListOfLeaves();
363 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
365 leaf->SetLeafCount(leafcount);
366 fBranches.Add(branch);
373 //______________________________________________________________________________
374 AliArrayBranch::~AliArrayBranch()
376 //*-*-*-*-*-*Default destructor for a BranchClones*-*-*-*-*-*-*-*-*-*-*-*
377 //*-* =====================================
386 //______________________________________________________________________________
387 void AliArrayBranch::Browse(TBrowser *b)
389 fBranches.Browse( b );
392 //______________________________________________________________________________
393 Int_t AliArrayBranch::Fill()
395 //*-*-*-*-*Loop on all Branches of this BranchClones to fill Basket buffer*-*
396 //*-* ===============================================================
400 Int_t nbranches = fBranches.GetEntriesFast();
401 char **ppointer = (char**)(fAddress);
402 if (ppointer == 0) return 0;
403 fList = (AliObjectArray*)(*ppointer);
404 // fN = fList->GetEntriesFast();
405 fN = fList->GetSize();
408 if (fN > fNdataMax) {
409 fNdataMax = fList->GetSize();
410 char branchcount[64];
411 sprintf(branchcount,"%s_",GetName());
412 TLeafI *leafi = (TLeafI*)fBranchCount->GetLeaf(branchcount);
413 leafi->SetMaximum(fNdataMax);
414 for (i=0;i<nbranches;i++) {
415 TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
416 TObjArray *leaves = branch->GetListOfLeaves();
417 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
421 nbytes += fBranchCount->Fill();
422 for (i=0;i<nbranches;i++) {
423 TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
424 TObjArray *leaves = branch->GetListOfLeaves();
425 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
426 // leaf->Import(fList, fN); // MI
427 Import(leaf,fN); // MI change
428 nbytes += branch->Fill();
433 //______________________________________________________________________________
434 Int_t AliArrayBranch::GetEntry(Int_t entry, Int_t getall)
436 //*-*-*-*-*Read all branches of a BranchClones and return total number of bytes
437 //*-* ====================================================================
439 if (TestBit(kDoNotProcess) && !getall) return 0;
440 Int_t nbytes = fBranchCount->GetEntry(entry);
441 TLeaf *leafcount = (TLeaf*)fBranchCount->GetListOfLeaves()->UncheckedAt(0);
442 fN = Int_t(leafcount->GetValue());
443 if (fN <= 0) return 0;
446 Int_t nbranches = fBranches.GetEntriesFast();
448 // if fList exists, create clonesarray objects
450 //fList->ExpandCreateFast(fN); //MI
451 fList->Resize(fN); //MI change
452 for (Int_t i=0;i<nbranches;i++) {
453 branch = (TBranch*)fBranches.UncheckedAt(i);
454 nbytes += ((AliArraySubBranch*)branch)->GetEntryExport(entry, getall, fList, fN); // !!!MI
457 for (Int_t i=0;i<nbranches;i++) {
458 branch = (TBranch*)fBranches.UncheckedAt(i);
459 nbytes += branch->GetEntry(entry, getall);
465 //______________________________________________________________________________
466 void AliArrayBranch::Print(Option_t *option) const
468 //*-*-*-*-*-*-*-*-*-*-*-*Print TBranch parameters*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
469 //*-* ========================
471 fBranchCount->Print(option);
473 Int_t nbranches = fBranches.GetEntriesFast();
474 for (i=0;i<nbranches;i++) {
475 TBranch *branch = (TBranch*)fBranches[i];
476 branch->Print(option);
480 //______________________________________________________________________________
481 void AliArrayBranch::Reset(Option_t *option)
483 //*-*-*-*-*-*-*-*Reset a Branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
484 //*-* ====================
486 // Existing buffers are deleted
487 // Entries, max and min are reset
494 Int_t nbranches = fBranches.GetEntriesFast();
495 for (i=0;i<nbranches;i++) {
496 TBranch *branch = (TBranch*)fBranches[i];
497 branch->Reset(option);
499 fBranchCount->Reset();
502 //______________________________________________________________________________
503 void AliArrayBranch::SetAddress(void *add)
505 //*-*-*-*-*-*-*-*Set address of this branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
506 //*-* ====================
510 fAddress = (char*)add;
511 char **ppointer = (char**)(fAddress);
512 if ( (*ppointer)==0 ) { //MI change
513 *ppointer = (char*) new AliObjectArray(fClassName);
514 fAddress = (char*)ppointer;
516 fList = (AliObjectArray*)(*ppointer);
517 fBranchCount->SetAddress(&fN);
521 //______________________________________________________________________________
522 void AliArrayBranch::SetBasketSize(Int_t buffsize)
524 //*-*-*-*-*-*-*-*Reset basket size for all subbranches of this branchclones
525 //*-* ==========================================================
528 fBasketSize = buffsize;
530 Int_t nbranches = fBranches.GetEntriesFast();
531 for (i=0;i<nbranches;i++) {
532 TBranch *branch = (TBranch*)fBranches[i];
533 branch->SetBasketSize(buffsize);
537 //_______________________________________________________________________
538 void AliArrayBranch::Streamer(TBuffer &b)
540 //*-*-*-*-*-*-*-*-*Stream a class object*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
541 //*-* =========================================
543 b.ReadVersion(); //Version_t v = b.ReadVersion();
547 b >> fEntryOffsetLen;
556 fClassName.Streamer(b);
557 fBranches.Streamer(b);
561 Int_t nbranches = fBranches.GetEntriesFast();
562 for (Int_t i=0;i<nbranches;i++) {
563 branch = (TBranch*)fBranches[i];
564 branch->SetBit(kIsClone);
565 leaf = (TLeaf*)branch->GetListOfLeaves()->UncheckedAt(0);
570 AliClassInfo *clinfo = AliClassInfo::FindClassInfo(fClassName);
572 AliObjectArray tmp(fClassName);
573 //MI change - object array to construct class description
574 clinfo = AliClassInfo::FindClassInfo(fClassName);
578 TClass *cl = clinfo->GetClass();
580 // Warning("Streamer","Unknow class: %s. Cannot read BranchClones: %s",
581 // fClassName.Data(),GetName());
586 if (!cl->GetListOfRealData()) cl->BuildRealData();
589 TIter next(cl->GetListOfRealData());
590 while ((rd = (TRealData *) next())) {
591 TDataMember *member = rd->GetDataMember();
592 if (!member->IsBasic()) continue;
593 if (!member->IsPersistent()) continue;
594 TDataType *membertype = member->GetDataType();
595 if (membertype->GetType() == 0) continue;
596 //MI change - for array spliting
597 Int_t arraydim = member->GetArrayDim();
599 for (Int_t i=0;i< member->GetMaxIndex(0);i++){
600 const char * dmname = member->GetName() ;
603 while ( (dmname[j]!='[') && (dmname[j]!=0) ){
608 sprintf(branchname,"%s.%s(%d)",GetName(),bname,i);
609 branch = (TBranch*)fBranches.FindObject(branchname);
610 if (!branch) continue;
611 TObjArray *leaves = branch->GetListOfLeaves();
612 leaf = (TLeaf*)leaves->UncheckedAt(0);
613 leaf->SetOffset(rd->GetThisOffset()+membertype->Size()*i);
616 sprintf(branchname,"%s.%s",GetName(),rd->GetName());
617 branch = (TBranch*)fBranches.FindObject(branchname);
618 if (!branch) continue;
619 TObjArray *leaves = branch->GetListOfLeaves();
620 leaf = (TLeaf*)leaves->UncheckedAt(0);
621 leaf->SetOffset(rd->GetThisOffset());
625 else if (clinfo->IsA()->InheritsFrom("AliDataType")){ //branch for basic type
626 char branchname[100];
627 sprintf(branchname,"%s",clinfo->GetName());
628 branch = (TBranch*)fBranches.FindObject(branchname);
630 TObjArray *leaves = branch->GetListOfLeaves();
631 leaf = (TLeaf*)leaves->UncheckedAt(0);
638 b.WriteVersion(AliArrayBranch::IsA());
642 b << fEntryOffsetLen;
651 fClassName.Streamer(b);
652 fBranches.Streamer(b);
658 void AliArrayBranch::Import(TLeaf * leaf, Int_t n)
661 const Int_t kIntUndefined = -9999;
664 Int_t len = leaf->GetLenStatic();
665 Int_t offset = leaf->GetOffset();
666 void *value = leaf->GetValuePointer();
668 for (Int_t i=0;i<n;i++) {
669 clone = (char*)fList->UncheckedAt(i);
671 if (leaf->IsA()==TLeafB::Class()){
672 memcpy(&((Char_t*)value)[j],clone + offset, len);
675 if (leaf->IsA()==TLeafC::Class()){
676 memcpy(&((Char_t*)value)[j],clone + offset, 1);
679 if (leaf->IsA()==TLeafD::Class()){
680 if (clone) memcpy(&((Double_t*)value)[j],clone + offset, 8*len);
681 else memcpy(&((Double_t*)value)[j],&kIntUndefined, 8*len);
684 if (leaf->IsA()==TLeafF::Class()){
685 if (clone) memcpy(&((Float_t*)value)[j],clone + offset, 4*len);
686 else memcpy(&((Float_t*)value)[j],&kIntUndefined, 4*len);
689 if (leaf->IsA()==TLeafI::Class()){
690 if (clone) memcpy(&((Int_t*)value)[j],clone + offset, 4*len);
691 else memcpy(&((Int_t*)value)[j],&kIntUndefined, 4*len);
694 if (leaf->IsA()==TLeafS::Class()){
695 if (clone) memcpy(&((Short_t*)value)[j],clone + offset, 2*len);
696 else memcpy(&((Short_t*)value)[j],&kIntUndefined, 2*len);
703 AliObjectBranch::AliObjectBranch(const Text_t *name, const Text_t *classname, void *addobj,
705 Int_t basketsize, Int_t splitlevel, Int_t compress): TBranchObject()
707 //*-*-*-*-*-*-*-*-*-*-*-*-*Create a BranchObject*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
708 //*-* =====================
710 TClass *cl = gROOT->GetClass(classname);
711 fTree =tree; //MI change
713 Error("TBranchObject","Cannot find class:%s",classname);
716 if (!cl->GetListOfRealData()) cl->BuildRealData();
717 Int_t bufsize=basketsize; //MI ?
720 fCompress = compress;
721 if (compress == -1) {
722 TFile *bfile = fTree->GetDirectory()->GetFile(); //MI chnge fTrre - gTree
723 if (bfile) fCompress = bfile->GetCompressionLevel();
725 if (basketsize < 100) basketsize = 100;
726 fBasketSize = basketsize;
727 fAddress = (char*)addobj;
728 fClassName = classname;
729 fBasketEntry = new Int_t[fMaxBaskets];
730 fBasketBytes = new Int_t[fMaxBaskets];
731 #if ROOT_VERSION_CODE >= 262146
732 fBasketSeek = new Long64_t[fMaxBaskets];
734 fBasketSeek = new Seek_t[fMaxBaskets];
738 fBasketEntry[0] = fEntryNumber;
741 TLeaf *leaf = new TLeafObject(name,classname);
742 leaf->SetBranch(this);
743 leaf->SetAddress(addobj);
746 fTree->GetListOfLeaves()->Add(leaf); //MI change fTree-gTree
748 // Set the bit kAutoDelete to specify that when reading
749 // in TLeafObject::ReadBasket, the object should be deleted
750 // before calling Streamer.
751 // It is foreseen to not set this bit in a future version.
752 SetAutoDelete(kTRUE);
754 //*-*- Create the first basket
755 // fTree = gTree; //MI change - no need anymore
756 fDirectory = fTree->GetDirectory();
760 TBasket *basket = new TBasket(name,fTree->GetName(),this);
761 fBaskets.Add(basket);
767 TBranch * branch =this;
768 TObjArray *blist = branch->GetListOfBranches();
772 if (!cl->GetListOfRealData()) cl->BuildRealData();
773 char **apointer = (char**)(addobj);
774 TObject *obj = (TObject*)(*apointer);
775 Bool_t delobj = kFALSE;
777 obj = (TObject*)cl->New();
780 //*-*- Loop on all public data members of the class and its base classes
781 Int_t lenName = strlen(name);
783 if (name[lenName-1] == '.') isDot = 1;
784 TBranch *branch1 = 0;
786 TIter next(cl->GetListOfRealData());
787 while ((rd = (TRealData *) next())) {
788 TDataMember *dm = rd->GetDataMember();
789 if (!dm->IsPersistent()) continue; //do not process members with a ! as the first
790 // character in the comment field
791 rdname = rd->GetName();
792 dname = dm->GetName();
794 // Next line now commented, functionality to process arrays is now implemented
795 // the statement is left to show how to use Property() and kIsArray
796 // if (dm->Property() & kIsArray) continue;
798 TDataType *dtype = dm->GetDataType();
800 if (dtype) code = dm->GetDataType()->GetType();
802 //*-*- Encode branch name. Use real data member name
803 sprintf(branchname,"%s",rdname);
805 if (dm->IsaPointer()) sprintf(branchname,"%s%s",name,&rdname[1]);
806 else sprintf(branchname,"%s%s",name,&rdname[0]);
809 Int_t offset = rd->GetThisOffset();
810 char *pointer = (char*)obj + offset;
811 if (dm->IsaPointer()) {
813 if (!dm->IsBasic()) clobj = gROOT->GetClass(dm->GetTypeName());
814 if (clobj && !strcmp("TClonesArray",clobj->GetName())) {
815 char *cpointer =(char*)pointer;
816 char **ppointer =(char**)cpointer;
817 TClonesArray *list = (TClonesArray*)(*ppointer);
818 if (splitlevel != 100) {
819 if (isDot) branch1 = new TBranchClones(&branchname[0],pointer,bufsize);
820 else branch1 = new TBranchClones(&branchname[1],pointer,bufsize);
823 if (isDot) branch1 = new TBranchObject(&branchname[0],list->ClassName(),pointer,bufsize);
824 else branch1 = new TBranchObject(&branchname[1],list->ClassName(),pointer,bufsize);
829 if (clobj && !strcmp("AliObjectArray",clobj->GetName())) {
830 char *cpointer =(char*)pointer;
831 char **ppointer =(char**)cpointer;
832 TClonesArray *list = (TClonesArray*)(*ppointer);
833 if (splitlevel != 100) {
834 if (isDot) branch1 = new AliArrayBranch(&branchname[0],pointer,fTree,bufsize,compress);
835 else branch1 = new AliArrayBranch(&branchname[1],pointer,fTree,bufsize,compress);
838 if (isDot) branch1 = new AliObjectBranch(&branchname[0],list->ClassName(),pointer,fTree,bufsize);
839 else branch1 = new AliObjectBranch(&branchname[1],list->ClassName(),pointer,fTree,bufsize);
845 if (code != 1) continue;
846 sprintf(leaflist,"%s/%s",dname,"C");
847 branch1 = new TBranch(branchname,pointer,leaflist,bufsize);
848 branch1->SetTitle(dname);
851 if (!clobj->InheritsFrom(TObject::Class())) continue;
852 //branch1 = new TBranchObject(dname,clobj->GetName(),pointer,bufsize,0); //MI change
853 branch1 = new AliObjectBranch(dname,clobj->GetName(),pointer,fTree,bufsize,splitlevel);
854 if (isDot) branch1->SetName(&branchname[0]);
855 else branch1->SetName(&branchname[1]); //do not use the first character (*)
860 //*-*-------------Data Member is a basic data type----------
862 if (code == 1) sprintf(leaflist,"%s/%s",rdname,"B");
863 else if (code == 11) sprintf(leaflist,"%s/%s",rdname,"b");
864 else if (code == 2) sprintf(leaflist,"%s/%s",rdname,"S");
865 else if (code == 12) sprintf(leaflist,"%s/%s",rdname,"s");
866 else if (code == 3) sprintf(leaflist,"%s/%s",rdname,"I");
867 else if (code == 13) sprintf(leaflist,"%s/%s",rdname,"i");
868 else if (code == 5) sprintf(leaflist,"%s/%s",rdname,"F");
869 else if (code == 8) sprintf(leaflist,"%s/%s",rdname,"D");
871 printf("Cannot create branch for rdname=%s, code=%d\n",branchname, code);
874 branch1 = new TBranch(branchname,pointer,leaflist,bufsize);
875 branch1->SetTitle(rdname);
879 if (branch1) branch1->SetOffset(offset);
880 else Warning("Branch","Cannot process member:%s",rdname);
882 if (delobj) delete obj;
887 //______________________________________________________________________________
888 void AliObjectBranch::SetAddress(void *add)
890 //*-*-*-*-*-*-*-*Set address of this branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
891 //*-* ====================
894 //special case when called from code generated by TTree::MakeClass
895 if (Long_t(add) == -1) {
900 Int_t nbranches = fBranches.GetEntriesFast();
901 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0);
902 if (leaf) leaf->SetAddress(add);
904 fAddress = (char*)add;
905 char *pointer = fAddress;
906 void **ppointer = (void**)add;
907 TObject *obj = (TObject*)(*ppointer);
908 TClass *cl = gROOT->GetClass(fClassName.Data());
910 obj = (TObject*)cl->New();
911 *ppointer = (void*)obj;
915 for (i=0;i<nbranches;i++) {
916 branch = (TBranch*)fBranches[i];
917 pointer = (char*)obj;
918 branch->SetAddress(pointer);
922 if (!cl->GetListOfRealData()) cl->BuildRealData();
923 char *fullname = new char[200];
924 const char *bname = GetName();
925 Int_t lenName = strlen(bname);
927 if (bname[lenName-1] == '.') isDot = 1;
930 TIter next(cl->GetListOfRealData());
931 while ((rd = (TRealData *) next())) {
932 TDataMember *dm = rd->GetDataMember();
933 if (!dm->IsPersistent()) continue;
934 rdname = rd->GetName();
935 TDataType *dtype = dm->GetDataType();
937 if (dtype) code = dm->GetDataType()->GetType();
938 offset = rd->GetThisOffset();
939 pointer = (char*)obj + offset;
941 if (dm->IsaPointer()) {
943 if (!dm->IsBasic()) clobj = gROOT->GetClass(dm->GetTypeName());
944 if (clobj && !strcmp("TClonesArray",clobj->GetName())) {
945 if (isDot) sprintf(fullname,"%s%s",bname,&rdname[1]);
946 else sprintf(fullname,"%s",&rdname[1]);
947 branch = (TBranch*)fBranches.FindObject(fullname);
950 if (clobj && !strcmp("AliObjectArray",clobj->GetName())) {
951 if (isDot) sprintf(fullname,"%s%s",bname,&rdname[1]);
952 else sprintf(fullname,"%s",&rdname[1]);
953 branch = (TBranch*)fBranches.FindObject(fullname);
957 if (code != 1) continue;
958 if (isDot) sprintf(fullname,"%s%s",bname,&rdname[0]);
959 else sprintf(fullname,"%s",&rdname[0]);
960 branch = (TBranch*)fBranches.FindObject(fullname);
962 if (!clobj->InheritsFrom(TObject::Class())) continue;
963 if (isDot) sprintf(fullname,"%s%s",bname,&rdname[1]);
964 else sprintf(fullname,"%s",&rdname[1]);
965 branch = (TBranch*)fBranches.FindObject(fullname);
970 if (isDot) sprintf(fullname,"%s%s",bname,&rdname[0]);
971 else sprintf(fullname,"%s",&rdname[0]);
972 branch = (TBranch*)fBranches.FindObject(fullname);
975 if(branch) branch->SetAddress(pointer);
984 AliTree::AliTree(const char *name,const char *title, Int_t maxvirtualsize):
985 TTree(name,title,maxvirtualsize)
988 //default constructor for AliTree
992 TBranch * AliTree::AliBranch(const char *name, void *clonesaddress, Int_t bufsize, Int_t splitlevel,
995 if (clonesaddress == 0) return 0;
996 char *cpointer =(char*)clonesaddress;
997 char **ppointer =(char**)cpointer;
998 AliObjectArray *list = (AliObjectArray*)(*ppointer);
999 if (list == 0) return 0;
1002 TBranch *branch = new AliArrayBranch(name,clonesaddress,this,bufsize, compres);
1003 fBranches.Add(branch);
1006 TBranchObject *branch = new TBranchObject(name,list->ClassName(),clonesaddress,bufsize,0);
1007 fBranches.Add(branch);
1012 TBranch* AliTree::AliBranch(const char *name, const char *classname, void *addobj,
1013 Int_t bufsize, Int_t splitlevel)
1016 TClass *cl = gROOT->GetClass(classname);
1018 Error("BranchObject","Cannot find class:%s",classname);
1021 TBranch * branch = new AliObjectBranch(name,classname,addobj, this, bufsize,splitlevel);
1022 fBranches.Add(branch);