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 **************************************************************************/
20 #include "AliArrayBranch.h"
25 #include "TRealData.h"
26 #include "TDataType.h"
27 #include "TDataMember.h"
30 #include "TBranchClones.h"
38 #include "TLeafObject.h"
40 #include "AliObjectArray.h"
41 #include "AliDataType.h"
43 //-----------------------------------------------------
44 // A Branch for the case of an array of clone objects.
45 //-----------------------------------------------------
49 R__EXTERN TTree *gTree;
51 ClassImp(AliArraySubBranch)
52 ClassImp(AliArrayBranch)
53 ClassImp(AliObjectBranch)
58 Int_t AliArraySubBranch::GetEntryExport(Int_t entry, Int_t getall, AliObjectArray *list, Int_t nentries)
60 //*-*-*-*-*-*Read all leaves of entry and return total number of bytes*-*-*
61 //*-* export buffers to real objects in the AliObjectArray list.
64 if (TestBit(kDoNotProcess)) return 0;
65 if (fReadEntry == entry) return 1;
66 if (entry < 0 || entry >= fEntryNumber) return 0;
68 Int_t first = fBasketEntry[fReadBasket];
70 if (fReadBasket == fWriteBasket) last = fEntryNumber - 1;
71 else last = fBasketEntry[fReadBasket+1] - 1;
73 // Are we still in the same ReadBasket?
74 if (entry < first || entry > last) {
75 fReadBasket = TMath::BinarySearch(fWriteBasket+1, fBasketEntry, entry);
76 first = fBasketEntry[fReadBasket];
79 // We have found the basket containing this entry.
80 // make sure basket buffers are in memory.
81 TBasket *basket = GetBasket(fReadBasket);
82 if (!basket) return 0;
83 TBuffer *buf = basket->GetBufferRef();
84 // Set entry offset in buffer and read data from all leaves
85 if (!buf->IsReading()) {
86 basket->SetReadMode();
88 // Int_t bufbegin = basket->GetEntryPointer(entry-first);
90 Int_t *entryOffset = basket->GetEntryOffset();
91 if (entryOffset) bufbegin = entryOffset[entry-first];
92 else bufbegin = basket->GetKeylen() + (entry-first)*basket->GetNevBufSize();
93 buf->SetBufferOffset(bufbegin);
95 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0);
96 // leaf->ReadBasketExport(*buf,list,nentries); //!!! MI
97 ReadBasketExport(*buf,leaf, list,nentries);
98 nbytes = buf->Length() - bufbegin;
104 void AliArraySubBranch::ReadBasketExport(TBuffer &b, TLeaf *leaf, AliObjectArray *list, Int_t n)
108 Int_t len = leaf->GetLenStatic();
109 Int_t offset = leaf->GetOffset();
110 void *value = leaf->GetValuePointer();
113 if (leaf->IsA()==TLeafB::Class()){
115 for (Int_t i=0;i<n;i++) {
116 memcpy((char*)list->UncheckedAt(i) + offset,&((Char_t*)value)[j], len);
120 //variable length string.
121 if (leaf->IsA()==TLeafC::Class()){
125 if (len >= len) len = len-1;
126 b.ReadFastArray((Char_t*)value,len);
127 ((Char_t*)value)[len] = 0;
132 for (Int_t i=0;i<n;i++) {
133 memcpy((char*)list->UncheckedAt(i) + offset,&((Char_t*)value)[j], 1);
138 if (leaf->IsA()==TLeafD::Class()){
139 b.ReadFastArray(((Double_t*)value),n*len);
141 for (Int_t i=0;i<n;i++) {
142 memcpy((char*)list->UncheckedAt(i) + offset,&((Double_t*)value)[j], 8*len);
147 if (leaf->IsA()==TLeafF::Class()){
149 b >> ((Float_t*)value)[0];
151 b.ReadFastArray(((Float_t*)value),n*len);
154 Float_t *val = (Float_t*)value;
155 for (Int_t i=0;i<n;i++) {
156 char *first = (char*)list->UncheckedAt(i);
157 Float_t *ff = (Float_t*)&first[offset];
158 for (Int_t j=0;j<len;j++) {
166 if (leaf->IsA()==TLeafS::Class()){
168 b >> ((Short_t*)value)[0];
170 b.ReadFastArray(((Short_t*)value),n*len);
172 Short_t *val = (Short_t*)value;
173 for (Int_t i=0;i<n;i++) {
174 char *first = (char*)list->UncheckedAt(i);
175 Short_t *ii = (Short_t*)&first[offset];
176 for (Int_t j=0;j<len;j++) {
184 if (leaf->IsA()==TLeafI::Class()){
186 b >> ((Int_t*)value)[0];
188 b.ReadFastArray(((Int_t*)value),n*len);
190 Int_t *val = (Int_t*)value;
191 for (Int_t i=0;i<n;i++) {
192 char *first = (char*)list->UncheckedAt(i);
193 Int_t *ii = (Int_t*)&first[offset];
194 for (Int_t j=0;j<len;j++) {
204 //______________________________________________________________________________
205 AliArrayBranch::AliArrayBranch(): TBranch()
207 //*-*-*-*-*-*Default constructor for BranchClones*-*-*-*-*-*-*-*-*-*
208 //*-* ====================================
218 //______________________________________________________________________________
219 AliArrayBranch::AliArrayBranch(const Text_t *name, void *pointer, TTree * tree, Int_t basketsize, Int_t compress)
222 //*-*-*-*-*-*-*-*-*-*-*-*-*Create a BranchClones*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
223 //*-* =====================
227 char branchcount[64];
229 gTree = tree; // MI because some bug in ROOT I didn't obtain proper gTree
230 // it is necesary to set gTree because oder subranchces defined below need it
232 if (compress == -1) {
233 TFile *bfile = fTree->GetDirectory()->GetFile();
234 if (bfile) compress = bfile->GetCompressionLevel();
236 char *cpointer = (char*)pointer;
237 char **ppointer = (char**)(cpointer);
238 fList = (AliObjectArray*)(*ppointer);
244 AliClassInfo *clinfo = fList->GetClassInfo();
246 fClassName = clinfo->GetName();
248 //*-*- Create a branch to store the array count
249 if (basketsize < 100) basketsize = 100;
250 sprintf(leaflist,"%s_/I",name);
251 sprintf(branchcount,"%s_",name);
252 fBranchCount = new TBranch(branchcount,&fN,leaflist,basketsize);
253 fBranchCount->SetBit(kIsClone);
254 TLeaf *leafcount = (TLeaf*)fBranchCount->GetListOfLeaves()->UncheckedAt(0);
256 //*-*- Create the first basket
258 fDirectory = fTree->GetDirectory();
261 TBasket *basket = new TBasket(branchcount,fTree->GetName(),this);
262 fBaskets.Add(basket);
264 //*-*- Loop on all public data members of the class and its base classes
266 TClass *cl = fList->GetClass();
268 if (!cl->GetListOfRealData()) cl->BuildRealData();
270 const char *itype = 0;
272 TIter next(cl->GetListOfRealData());
273 while ((rd = (TRealData *) next())) {
274 TDataMember *member = rd->GetDataMember();
275 if (!member->IsBasic()) {
276 Warning("BranchClones","Cannot process member:%s",member->GetName());
279 if (!member->IsPersistent()) continue; //do not process members with a ! as the first
280 // character in the comment field
281 TDataType *membertype = member->GetDataType();
282 Int_t type = membertype->GetType();
284 Warning("BranchClones","Cannot process member:%s",member->GetName());
287 if (type == 1) itype = "B";
288 if (type == 11) itype = "b";
289 if (type == 3) itype = "I";
290 if (type == 5) itype = "F";
291 if (type == 8) itype = "D";
292 if (type == 13) itype = "i";
293 if (type == 2) itype = "S";
294 if (type == 12) itype = "s";
297 Int_t arraydim = member->GetArrayDim();
300 sprintf(leaflist,"%s[%s]/%s",member->GetName(),branchcount,itype);
301 Int_t comp = compress;
302 if (type == 5) comp--;
303 sprintf(branchname,"%s.%s",name,rd->GetName());
304 TBranch *branch = new AliArraySubBranch(branchname,this,leaflist,basketsize,comp);
305 branch->SetBit(kIsClone);
306 TObjArray *leaves = branch->GetListOfLeaves();
307 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
308 leaf->SetOffset(rd->GetThisOffset());
309 leaf->SetLeafCount(leafcount);
310 Int_t arraydim = member->GetArrayDim();
312 Int_t maxindex = member->GetMaxIndex(arraydim-1);
313 leaf->SetLen(maxindex);
315 fBranches.Add(branch);
318 for (Int_t i=0;i< member->GetMaxIndex(0);i++){
319 const char * dmname = member->GetName() ;
322 while ( (dmname[j]!='[') && (dmname[j]!=0) ){
327 sprintf(leaflist,"%s(%d)[%s]/%s",bname,i,branchcount,itype);
328 Int_t comp = compress;
329 if (type == 5) comp--;
330 sprintf(branchname,"%s.%s(%d)",name,bname,i);
331 TBranch *branch = new AliArraySubBranch(branchname,this,leaflist,basketsize,comp);
332 branch->SetBit(kIsClone);
333 TObjArray *leaves = branch->GetListOfLeaves();
334 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
335 leaf->SetOffset(rd->GetThisOffset()+membertype->Size()*i);
336 leaf->SetLeafCount(leafcount);
337 fBranches.Add(branch);
342 else if (clinfo->IsA()->InheritsFrom("AliDataType")){ //branch for basic type
343 Int_t type = (((AliDataType*)clinfo)->GetDataType())->GetType();
346 Warning("BranchClones","Cannot process member:%s",clinfo->GetName());
349 if (type == 1) itype = "B";
350 if (type == 11) itype = "b";
351 if (type == 3) itype = "I";
352 if (type == 5) itype = "F";
353 if (type == 8) itype = "D";
354 if (type == 13) itype = "i";
355 if (type == 2) itype = "S";
356 if (type == 12) itype = "s";
357 sprintf(leaflist,"%s[%s]/%s",name,branchcount,itype);
358 Int_t comp = compress;
359 if (type == 5) comp--;
360 sprintf(branchname,"%s",clinfo->GetName());
361 TBranch *branch = new AliArraySubBranch(branchname,this,leaflist,basketsize,comp);
362 branch->SetBit(kIsClone);
363 TObjArray *leaves = branch->GetListOfLeaves();
364 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
366 leaf->SetLeafCount(leafcount);
367 fBranches.Add(branch);
374 //______________________________________________________________________________
375 AliArrayBranch::~AliArrayBranch()
377 //*-*-*-*-*-*Default destructor for a BranchClones*-*-*-*-*-*-*-*-*-*-*-*
378 //*-* =====================================
387 //______________________________________________________________________________
388 void AliArrayBranch::Browse(TBrowser *b)
390 fBranches.Browse( b );
393 //______________________________________________________________________________
394 Int_t AliArrayBranch::Fill()
396 //*-*-*-*-*Loop on all Branches of this BranchClones to fill Basket buffer*-*
397 //*-* ===============================================================
401 Int_t nbranches = fBranches.GetEntriesFast();
402 char **ppointer = (char**)(fAddress);
403 if (ppointer == 0) return 0;
404 fList = (AliObjectArray*)(*ppointer);
405 // fN = fList->GetEntriesFast();
406 fN = fList->GetSize();
409 if (fN > fNdataMax) {
410 fNdataMax = fList->GetSize();
411 char branchcount[64];
412 sprintf(branchcount,"%s_",GetName());
413 TLeafI *leafi = (TLeafI*)fBranchCount->GetLeaf(branchcount);
414 leafi->SetMaximum(fNdataMax);
415 for (i=0;i<nbranches;i++) {
416 TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
417 TObjArray *leaves = branch->GetListOfLeaves();
418 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
422 nbytes += fBranchCount->Fill();
423 for (i=0;i<nbranches;i++) {
424 TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
425 TObjArray *leaves = branch->GetListOfLeaves();
426 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
427 // leaf->Import(fList, fN); // MI
428 Import(leaf,fN); // MI change
429 nbytes += branch->Fill();
434 //______________________________________________________________________________
435 Int_t AliArrayBranch::GetEntry(Int_t entry, Int_t getall)
437 //*-*-*-*-*Read all branches of a BranchClones and return total number of bytes
438 //*-* ====================================================================
440 if (TestBit(kDoNotProcess) && !getall) return 0;
441 Int_t nbytes = fBranchCount->GetEntry(entry);
442 TLeaf *leafcount = (TLeaf*)fBranchCount->GetListOfLeaves()->UncheckedAt(0);
443 fN = Int_t(leafcount->GetValue());
444 if (fN <= 0) return 0;
447 Int_t nbranches = fBranches.GetEntriesFast();
449 // if fList exists, create clonesarray objects
451 //fList->ExpandCreateFast(fN); //MI
452 fList->Resize(fN); //MI change
453 for (Int_t i=0;i<nbranches;i++) {
454 branch = (TBranch*)fBranches.UncheckedAt(i);
455 nbytes += ((AliArraySubBranch*)branch)->GetEntryExport(entry, getall, fList, fN); // !!!MI
458 for (Int_t i=0;i<nbranches;i++) {
459 branch = (TBranch*)fBranches.UncheckedAt(i);
460 nbytes += branch->GetEntry(entry, getall);
466 //______________________________________________________________________________
467 void AliArrayBranch::Print(Option_t *option)
469 //*-*-*-*-*-*-*-*-*-*-*-*Print TBranch parameters*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
470 //*-* ========================
472 fBranchCount->Print(option);
474 Int_t nbranches = fBranches.GetEntriesFast();
475 for (i=0;i<nbranches;i++) {
476 TBranch *branch = (TBranch*)fBranches[i];
477 branch->Print(option);
481 //______________________________________________________________________________
482 void AliArrayBranch::Reset(Option_t *option)
484 //*-*-*-*-*-*-*-*Reset a Branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
485 //*-* ====================
487 // Existing buffers are deleted
488 // Entries, max and min are reset
495 Int_t nbranches = fBranches.GetEntriesFast();
496 for (i=0;i<nbranches;i++) {
497 TBranch *branch = (TBranch*)fBranches[i];
498 branch->Reset(option);
500 fBranchCount->Reset();
503 //______________________________________________________________________________
504 void AliArrayBranch::SetAddress(void *add)
506 //*-*-*-*-*-*-*-*Set address of this branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
507 //*-* ====================
511 fAddress = (char*)add;
512 char **ppointer = (char**)(fAddress);
513 if ( (*ppointer)==0 ) { //MI change
514 *ppointer = (char*) new AliObjectArray(fClassName);
515 fAddress = (char*)ppointer;
517 fList = (AliObjectArray*)(*ppointer);
518 fBranchCount->SetAddress(&fN);
522 //______________________________________________________________________________
523 void AliArrayBranch::SetBasketSize(Int_t buffsize)
525 //*-*-*-*-*-*-*-*Reset basket size for all subbranches of this branchclones
526 //*-* ==========================================================
529 fBasketSize = buffsize;
531 Int_t nbranches = fBranches.GetEntriesFast();
532 for (i=0;i<nbranches;i++) {
533 TBranch *branch = (TBranch*)fBranches[i];
534 branch->SetBasketSize(buffsize);
538 //_______________________________________________________________________
539 void AliArrayBranch::Streamer(TBuffer &b)
541 //*-*-*-*-*-*-*-*-*Stream a class object*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
542 //*-* =========================================
544 b.ReadVersion(); //Version_t v = b.ReadVersion();
548 b >> fEntryOffsetLen;
557 fClassName.Streamer(b);
558 fBranches.Streamer(b);
562 Int_t nbranches = fBranches.GetEntriesFast();
563 for (Int_t i=0;i<nbranches;i++) {
564 branch = (TBranch*)fBranches[i];
565 branch->SetBit(kIsClone);
566 leaf = (TLeaf*)branch->GetListOfLeaves()->UncheckedAt(0);
571 AliClassInfo *clinfo = AliClassInfo::FindClassInfo(fClassName);
573 AliObjectArray tmp(fClassName);
574 //MI change - object array to construct class description
575 clinfo = AliClassInfo::FindClassInfo(fClassName);
579 TClass *cl = clinfo->GetClass();
581 // Warning("Streamer","Unknow class: %s. Cannot read BranchClones: %s",
582 // fClassName.Data(),GetName());
587 if (!cl->GetListOfRealData()) cl->BuildRealData();
590 TIter next(cl->GetListOfRealData());
591 while ((rd = (TRealData *) next())) {
592 TDataMember *member = rd->GetDataMember();
593 if (!member->IsBasic()) continue;
594 if (!member->IsPersistent()) continue;
595 TDataType *membertype = member->GetDataType();
596 if (membertype->GetType() == 0) continue;
597 //MI change - for array spliting
598 Int_t arraydim = member->GetArrayDim();
600 for (Int_t i=0;i< member->GetMaxIndex(0);i++){
601 const char * dmname = member->GetName() ;
604 while ( (dmname[j]!='[') && (dmname[j]!=0) ){
609 sprintf(branchname,"%s.%s(%d)",GetName(),bname,i);
610 branch = (TBranch*)fBranches.FindObject(branchname);
611 if (!branch) continue;
612 TObjArray *leaves = branch->GetListOfLeaves();
613 leaf = (TLeaf*)leaves->UncheckedAt(0);
614 leaf->SetOffset(rd->GetThisOffset()+membertype->Size()*i);
617 sprintf(branchname,"%s.%s",GetName(),rd->GetName());
618 branch = (TBranch*)fBranches.FindObject(branchname);
619 if (!branch) continue;
620 TObjArray *leaves = branch->GetListOfLeaves();
621 leaf = (TLeaf*)leaves->UncheckedAt(0);
622 leaf->SetOffset(rd->GetThisOffset());
626 else if (clinfo->IsA()->InheritsFrom("AliDataType")){ //branch for basic type
627 char branchname[100];
628 sprintf(branchname,"%s",clinfo->GetName());
629 branch = (TBranch*)fBranches.FindObject(branchname);
631 TObjArray *leaves = branch->GetListOfLeaves();
632 leaf = (TLeaf*)leaves->UncheckedAt(0);
639 b.WriteVersion(AliArrayBranch::IsA());
643 b << fEntryOffsetLen;
652 fClassName.Streamer(b);
653 fBranches.Streamer(b);
659 void AliArrayBranch::Import(TLeaf * leaf, Int_t n)
662 const Int_t kIntUndefined = -9999;
665 Int_t len = leaf->GetLenStatic();
666 Int_t fOffset = leaf->GetOffset();
667 void *value = leaf->GetValuePointer();
669 for (Int_t i=0;i<n;i++) {
670 clone = (char*)fList->UncheckedAt(i);
672 if (leaf->IsA()==TLeafB::Class()){
673 memcpy(&((Char_t*)value)[j],clone + fOffset, len);
676 if (leaf->IsA()==TLeafC::Class()){
677 memcpy(&((Char_t*)value)[j],clone + fOffset, 1);
680 if (leaf->IsA()==TLeafD::Class()){
681 if (clone) memcpy(&((Double_t*)value)[j],clone + fOffset, 8*len);
682 else memcpy(&((Double_t*)value)[j],&kIntUndefined, 8*len);
685 if (leaf->IsA()==TLeafF::Class()){
686 if (clone) memcpy(&((Float_t*)value)[j],clone + fOffset, 4*len);
687 else memcpy(&((Float_t*)value)[j],&kIntUndefined, 4*len);
690 if (leaf->IsA()==TLeafI::Class()){
691 if (clone) memcpy(&((Int_t*)value)[j],clone + fOffset, 4*len);
692 else memcpy(&((Int_t*)value)[j],&kIntUndefined, 4*len);
695 if (leaf->IsA()==TLeafS::Class()){
696 if (clone) memcpy(&((Short_t*)value)[j],clone + fOffset, 2*len);
697 else memcpy(&((Short_t*)value)[j],&kIntUndefined, 2*len);
704 AliObjectBranch::AliObjectBranch(const Text_t *name, const Text_t *classname, void *addobj,
706 Int_t basketsize, Int_t splitlevel, Int_t compress): TBranchObject()
708 //*-*-*-*-*-*-*-*-*-*-*-*-*Create a BranchObject*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
709 //*-* =====================
711 TClass *cl = gROOT->GetClass(classname);
712 fTree =tree; //MI change
714 Error("TBranchObject","Cannot find class:%s",classname);
717 if (!cl->GetListOfRealData()) cl->BuildRealData();
718 Int_t bufsize=basketsize; //MI ?
721 fCompress = compress;
722 if (compress == -1) {
723 TFile *bfile = fTree->GetDirectory()->GetFile(); //MI chnge fTrre - gTree
724 if (bfile) fCompress = bfile->GetCompressionLevel();
726 if (basketsize < 100) basketsize = 100;
727 fBasketSize = basketsize;
728 fAddress = (char*)addobj;
729 fClassName = classname;
730 fBasketEntry = new Int_t[fMaxBaskets];
731 fBasketBytes = new Int_t[fMaxBaskets];
732 fBasketSeek = new Seek_t[fMaxBaskets];
735 fBasketEntry[0] = fEntryNumber;
738 TLeaf *leaf = new TLeafObject(name,classname);
739 leaf->SetBranch(this);
740 leaf->SetAddress(addobj);
743 fTree->GetListOfLeaves()->Add(leaf); //MI change fTree-gTree
745 // Set the bit kAutoDelete to specify that when reading
746 // in TLeafObject::ReadBasket, the object should be deleted
747 // before calling Streamer.
748 // It is foreseen to not set this bit in a future version.
749 SetAutoDelete(kTRUE);
751 //*-*- Create the first basket
752 // fTree = gTree; //MI change - no need anymore
753 fDirectory = fTree->GetDirectory();
757 TBasket *basket = new TBasket(name,fTree->GetName(),this);
758 fBaskets.Add(basket);
764 TBranch * branch =this;
765 TObjArray *blist = branch->GetListOfBranches();
769 if (!cl->GetListOfRealData()) cl->BuildRealData();
770 char **apointer = (char**)(addobj);
771 TObject *obj = (TObject*)(*apointer);
772 Bool_t delobj = kFALSE;
774 obj = (TObject*)cl->New();
777 //*-*- Loop on all public data members of the class and its base classes
778 Int_t lenName = strlen(name);
780 if (name[lenName-1] == '.') isDot = 1;
781 TBranch *branch1 = 0;
783 TIter next(cl->GetListOfRealData());
784 while ((rd = (TRealData *) next())) {
785 TDataMember *dm = rd->GetDataMember();
786 if (!dm->IsPersistent()) continue; //do not process members with a ! as the first
787 // character in the comment field
788 rdname = rd->GetName();
789 dname = dm->GetName();
791 // Next line now commented, functionality to process arrays is now implemented
792 // the statement is left to show how to use Property() and kIsArray
793 // if (dm->Property() & kIsArray) continue;
795 TDataType *dtype = dm->GetDataType();
797 if (dtype) code = dm->GetDataType()->GetType();
799 //*-*- Encode branch name. Use real data member name
800 sprintf(branchname,"%s",rdname);
802 if (dm->IsaPointer()) sprintf(branchname,"%s%s",name,&rdname[1]);
803 else sprintf(branchname,"%s%s",name,&rdname[0]);
806 Int_t offset = rd->GetThisOffset();
807 char *pointer = (char*)obj + offset;
808 if (dm->IsaPointer()) {
810 if (!dm->IsBasic()) clobj = gROOT->GetClass(dm->GetTypeName());
811 if (clobj && !strcmp("TClonesArray",clobj->GetName())) {
812 char *cpointer =(char*)pointer;
813 char **ppointer =(char**)cpointer;
814 TClonesArray *list = (TClonesArray*)(*ppointer);
815 if (splitlevel != 2) {
816 if (isDot) branch1 = new TBranchClones(&branchname[0],pointer,bufsize);
817 else branch1 = new TBranchClones(&branchname[1],pointer,bufsize);
820 if (isDot) branch1 = new TBranchObject(&branchname[0],list->ClassName(),pointer,bufsize);
821 else branch1 = new TBranchObject(&branchname[1],list->ClassName(),pointer,bufsize);
826 if (clobj && !strcmp("AliObjectArray",clobj->GetName())) {
827 char *cpointer =(char*)pointer;
828 char **ppointer =(char**)cpointer;
829 TClonesArray *list = (TClonesArray*)(*ppointer);
830 if (splitlevel != 2) {
831 if (isDot) branch1 = new AliArrayBranch(&branchname[0],pointer,fTree,bufsize,compress);
832 else branch1 = new AliArrayBranch(&branchname[1],pointer,fTree,bufsize,compress);
835 if (isDot) branch1 = new AliObjectBranch(&branchname[0],list->ClassName(),pointer,fTree,bufsize);
836 else branch1 = new AliObjectBranch(&branchname[1],list->ClassName(),pointer,fTree,bufsize);
842 if (code != 1) continue;
843 sprintf(leaflist,"%s/%s",dname,"C");
844 branch1 = new TBranch(branchname,pointer,leaflist,bufsize);
845 branch1->SetTitle(dname);
848 if (!clobj->InheritsFrom(TObject::Class())) continue;
849 //branch1 = new TBranchObject(dname,clobj->GetName(),pointer,bufsize,0); //MI change
850 branch1 = new AliObjectBranch(dname,clobj->GetName(),pointer,fTree,bufsize,splitlevel);
851 if (isDot) branch1->SetName(&branchname[0]);
852 else branch1->SetName(&branchname[1]); //do not use the first character (*)
857 //*-*-------------Data Member is a basic data type----------
859 if (code == 1) sprintf(leaflist,"%s/%s",rdname,"B");
860 else if (code == 11) sprintf(leaflist,"%s/%s",rdname,"b");
861 else if (code == 2) sprintf(leaflist,"%s/%s",rdname,"S");
862 else if (code == 12) sprintf(leaflist,"%s/%s",rdname,"s");
863 else if (code == 3) sprintf(leaflist,"%s/%s",rdname,"I");
864 else if (code == 13) sprintf(leaflist,"%s/%s",rdname,"i");
865 else if (code == 5) sprintf(leaflist,"%s/%s",rdname,"F");
866 else if (code == 8) sprintf(leaflist,"%s/%s",rdname,"D");
868 printf("Cannot create branch for rdname=%s, code=%d\n",branchname, code);
871 branch1 = new TBranch(branchname,pointer,leaflist,bufsize);
872 branch1->SetTitle(rdname);
876 if (branch1) branch1->SetOffset(offset);
877 else Warning("Branch","Cannot process member:%s",rdname);
879 if (delobj) delete obj;
884 //______________________________________________________________________________
885 void AliObjectBranch::SetAddress(void *add)
887 //*-*-*-*-*-*-*-*Set address of this branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
888 //*-* ====================
891 //special case when called from code generated by TTree::MakeClass
892 if (Long_t(add) == -1) {
897 Int_t nbranches = fBranches.GetEntriesFast();
898 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0);
899 if (leaf) leaf->SetAddress(add);
901 fAddress = (char*)add;
902 char *pointer = fAddress;
903 void **ppointer = (void**)add;
904 TObject *obj = (TObject*)(*ppointer);
905 TClass *cl = gROOT->GetClass(fClassName.Data());
907 obj = (TObject*)cl->New();
908 *ppointer = (void*)obj;
912 for (i=0;i<nbranches;i++) {
913 branch = (TBranch*)fBranches[i];
914 pointer = (char*)obj;
915 branch->SetAddress(pointer);
919 if (!cl->GetListOfRealData()) cl->BuildRealData();
920 char *fullname = new char[200];
921 const char *bname = GetName();
922 Int_t lenName = strlen(bname);
924 if (bname[lenName-1] == '.') isDot = 1;
927 TIter next(cl->GetListOfRealData());
928 while ((rd = (TRealData *) next())) {
929 TDataMember *dm = rd->GetDataMember();
930 if (!dm->IsPersistent()) continue;
931 rdname = rd->GetName();
932 TDataType *dtype = dm->GetDataType();
934 if (dtype) code = dm->GetDataType()->GetType();
935 offset = rd->GetThisOffset();
936 pointer = (char*)obj + offset;
938 if (dm->IsaPointer()) {
940 if (!dm->IsBasic()) clobj = gROOT->GetClass(dm->GetTypeName());
941 if (clobj && !strcmp("TClonesArray",clobj->GetName())) {
942 if (isDot) sprintf(fullname,"%s%s",bname,&rdname[1]);
943 else sprintf(fullname,"%s",&rdname[1]);
944 branch = (TBranch*)fBranches.FindObject(fullname);
947 if (clobj && !strcmp("AliObjectArray",clobj->GetName())) {
948 if (isDot) sprintf(fullname,"%s%s",bname,&rdname[1]);
949 else sprintf(fullname,"%s",&rdname[1]);
950 branch = (TBranch*)fBranches.FindObject(fullname);
954 if (code != 1) continue;
955 if (isDot) sprintf(fullname,"%s%s",bname,&rdname[0]);
956 else sprintf(fullname,"%s",&rdname[0]);
957 branch = (TBranch*)fBranches.FindObject(fullname);
959 if (!clobj->InheritsFrom(TObject::Class())) continue;
960 if (isDot) sprintf(fullname,"%s%s",bname,&rdname[1]);
961 else sprintf(fullname,"%s",&rdname[1]);
962 branch = (TBranch*)fBranches.FindObject(fullname);
967 if (isDot) sprintf(fullname,"%s%s",bname,&rdname[0]);
968 else sprintf(fullname,"%s",&rdname[0]);
969 branch = (TBranch*)fBranches.FindObject(fullname);
972 if(branch) branch->SetAddress(pointer);
981 AliTree::AliTree(const char *name,const char *title, Int_t maxvirtualsize):
982 TTree(name,title,maxvirtualsize)
985 //default constructor for AliTree
989 TBranch * AliTree::AliBranch(const char *name, void *clonesaddress, Int_t bufsize, Int_t splitlevel,
992 if (clonesaddress == 0) return 0;
993 char *cpointer =(char*)clonesaddress;
994 char **ppointer =(char**)cpointer;
995 AliObjectArray *list = (AliObjectArray*)(*ppointer);
996 if (list == 0) return 0;
999 TBranch *branch = new AliArrayBranch(name,clonesaddress,this,bufsize, compres);
1000 fBranches.Add(branch);
1003 TBranchObject *branch = new TBranchObject(name,list->ClassName(),clonesaddress,bufsize,0);
1004 fBranches.Add(branch);
1009 TBranch* AliTree::AliBranch(const char *name, const char *classname, void *addobj,
1010 Int_t bufsize, Int_t splitlevel)
1013 TClass *cl = gROOT->GetClass(classname);
1015 Error("BranchObject","Cannot find class:%s",classname);
1018 TBranch * branch = new AliObjectBranch(name,classname,addobj, this, bufsize,splitlevel);
1019 fBranches.Add(branch);