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 **************************************************************************/
18 Revision 1.1 2000/11/01 16:01:22 kowal2
19 Classes for handling the new hits structures
23 #include "AliArrayBranch.h"
28 #include "TRealData.h"
29 #include "TDataType.h"
30 #include "TDataMember.h"
33 #include "TBranchClones.h"
41 #include "TLeafObject.h"
43 #include "AliObjectArray.h"
44 #include "AliDataType.h"
46 //-----------------------------------------------------
47 // A Branch for the case of an array of clone objects.
48 //-----------------------------------------------------
52 R__EXTERN TTree *gTree;
54 ClassImp(AliArraySubBranch)
55 ClassImp(AliArrayBranch)
56 ClassImp(AliObjectBranch)
61 Int_t AliArraySubBranch::GetEntryExport(Int_t entry, Int_t getall, AliObjectArray *list, Int_t nentries)
63 //*-*-*-*-*-*Read all leaves of entry and return total number of bytes*-*-*
64 //*-* export buffers to real objects in the AliObjectArray list.
67 if (TestBit(kDoNotProcess)) return 0;
68 if (fReadEntry == entry) return 1;
69 if (entry < 0 || entry >= fEntryNumber) return 0;
71 Int_t first = fBasketEntry[fReadBasket];
73 if (fReadBasket == fWriteBasket) last = fEntryNumber - 1;
74 else last = fBasketEntry[fReadBasket+1] - 1;
76 // Are we still in the same ReadBasket?
77 if (entry < first || entry > last) {
78 fReadBasket = TMath::BinarySearch(fWriteBasket+1, fBasketEntry, entry);
79 first = fBasketEntry[fReadBasket];
82 // We have found the basket containing this entry.
83 // make sure basket buffers are in memory.
84 TBasket *basket = GetBasket(fReadBasket);
85 if (!basket) return 0;
86 TBuffer *buf = basket->GetBufferRef();
87 // Set entry offset in buffer and read data from all leaves
88 if (!buf->IsReading()) {
89 basket->SetReadMode();
91 // Int_t bufbegin = basket->GetEntryPointer(entry-first);
93 Int_t *entryOffset = basket->GetEntryOffset();
94 if (entryOffset) bufbegin = entryOffset[entry-first];
95 else bufbegin = basket->GetKeylen() + (entry-first)*basket->GetNevBufSize();
96 buf->SetBufferOffset(bufbegin);
98 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0);
99 // leaf->ReadBasketExport(*buf,list,nentries); //!!! MI
100 ReadBasketExport(*buf,leaf, list,nentries);
101 nbytes = buf->Length() - bufbegin;
107 void AliArraySubBranch::ReadBasketExport(TBuffer &b, TLeaf *leaf, AliObjectArray *list, Int_t n)
111 Int_t len = leaf->GetLenStatic();
112 Int_t offset = leaf->GetOffset();
113 void *value = leaf->GetValuePointer();
116 if (leaf->IsA()==TLeafB::Class()){
118 for (Int_t i=0;i<n;i++) {
119 memcpy((char*)list->UncheckedAt(i) + offset,&((Char_t*)value)[j], len);
123 //variable length string.
124 if (leaf->IsA()==TLeafC::Class()){
128 if (len >= len) len = len-1;
129 b.ReadFastArray((Char_t*)value,len);
130 ((Char_t*)value)[len] = 0;
135 for (Int_t i=0;i<n;i++) {
136 memcpy((char*)list->UncheckedAt(i) + offset,&((Char_t*)value)[j], 1);
141 if (leaf->IsA()==TLeafD::Class()){
142 b.ReadFastArray(((Double_t*)value),n*len);
144 for (Int_t i=0;i<n;i++) {
145 memcpy((char*)list->UncheckedAt(i) + offset,&((Double_t*)value)[j], 8*len);
150 if (leaf->IsA()==TLeafF::Class()){
152 b >> ((Float_t*)value)[0];
154 b.ReadFastArray(((Float_t*)value),n*len);
157 Float_t *val = (Float_t*)value;
158 for (Int_t i=0;i<n;i++) {
159 char *first = (char*)list->UncheckedAt(i);
160 Float_t *ff = (Float_t*)&first[offset];
161 for (Int_t j=0;j<len;j++) {
169 if (leaf->IsA()==TLeafS::Class()){
171 b >> ((Short_t*)value)[0];
173 b.ReadFastArray(((Short_t*)value),n*len);
175 Short_t *val = (Short_t*)value;
176 for (Int_t i=0;i<n;i++) {
177 char *first = (char*)list->UncheckedAt(i);
178 Short_t *ii = (Short_t*)&first[offset];
179 for (Int_t j=0;j<len;j++) {
187 if (leaf->IsA()==TLeafI::Class()){
189 b >> ((Int_t*)value)[0];
191 b.ReadFastArray(((Int_t*)value),n*len);
193 Int_t *val = (Int_t*)value;
194 for (Int_t i=0;i<n;i++) {
195 char *first = (char*)list->UncheckedAt(i);
196 Int_t *ii = (Int_t*)&first[offset];
197 for (Int_t j=0;j<len;j++) {
207 //______________________________________________________________________________
208 AliArrayBranch::AliArrayBranch(): TBranch()
210 //*-*-*-*-*-*Default constructor for BranchClones*-*-*-*-*-*-*-*-*-*
211 //*-* ====================================
221 //______________________________________________________________________________
222 AliArrayBranch::AliArrayBranch(const Text_t *name, void *pointer, TTree * tree, Int_t basketsize, Int_t compress)
225 //*-*-*-*-*-*-*-*-*-*-*-*-*Create a BranchClones*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
226 //*-* =====================
230 char branchcount[64];
232 gTree = tree; // MI because some bug in ROOT I didn't obtain proper gTree
233 // it is necesary to set gTree because oder subranchces defined below need it
235 if (compress == -1) {
236 TFile *bfile = fTree->GetDirectory()->GetFile();
237 if (bfile) compress = bfile->GetCompressionLevel();
239 char *cpointer = (char*)pointer;
240 char **ppointer = (char**)(cpointer);
241 fList = (AliObjectArray*)(*ppointer);
247 AliClassInfo *clinfo = fList->GetClassInfo();
249 fClassName = clinfo->GetName();
251 //*-*- Create a branch to store the array count
252 if (basketsize < 100) basketsize = 100;
253 sprintf(leaflist,"%s_/I",name);
254 sprintf(branchcount,"%s_",name);
255 fBranchCount = new TBranch(branchcount,&fN,leaflist,basketsize);
256 fBranchCount->SetBit(kIsClone);
257 TLeaf *leafcount = (TLeaf*)fBranchCount->GetListOfLeaves()->UncheckedAt(0);
259 //*-*- Create the first basket
261 fDirectory = fTree->GetDirectory();
264 TBasket *basket = new TBasket(branchcount,fTree->GetName(),this);
265 fBaskets.Add(basket);
267 //*-*- Loop on all public data members of the class and its base classes
269 TClass *cl = fList->GetClass();
271 if (!cl->GetListOfRealData()) cl->BuildRealData();
273 const char *itype = 0;
275 TIter next(cl->GetListOfRealData());
276 while ((rd = (TRealData *) next())) {
277 TDataMember *member = rd->GetDataMember();
278 if (!member->IsBasic()) {
279 Warning("BranchClones","Cannot process member:%s",member->GetName());
282 if (!member->IsPersistent()) continue; //do not process members with a ! as the first
283 // character in the comment field
284 TDataType *membertype = member->GetDataType();
285 Int_t type = membertype->GetType();
287 Warning("BranchClones","Cannot process member:%s",member->GetName());
290 if (type == 1) itype = "B";
291 if (type == 11) itype = "b";
292 if (type == 3) itype = "I";
293 if (type == 5) itype = "F";
294 if (type == 8) itype = "D";
295 if (type == 13) itype = "i";
296 if (type == 2) itype = "S";
297 if (type == 12) itype = "s";
300 Int_t arraydim = member->GetArrayDim();
303 sprintf(leaflist,"%s[%s]/%s",member->GetName(),branchcount,itype);
304 Int_t comp = compress;
305 if (type == 5) comp--;
306 sprintf(branchname,"%s.%s",name,rd->GetName());
307 TBranch *branch = new AliArraySubBranch(branchname,this,leaflist,basketsize,comp);
308 branch->SetBit(kIsClone);
309 TObjArray *leaves = branch->GetListOfLeaves();
310 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
311 leaf->SetOffset(rd->GetThisOffset());
312 leaf->SetLeafCount(leafcount);
313 Int_t arraydim = member->GetArrayDim();
315 Int_t maxindex = member->GetMaxIndex(arraydim-1);
316 leaf->SetLen(maxindex);
318 fBranches.Add(branch);
321 for (Int_t i=0;i< member->GetMaxIndex(0);i++){
322 const char * dmname = member->GetName() ;
325 while ( (dmname[j]!='[') && (dmname[j]!=0) ){
330 sprintf(leaflist,"%s(%d)[%s]/%s",bname,i,branchcount,itype);
331 Int_t comp = compress;
332 if (type == 5) comp--;
333 sprintf(branchname,"%s.%s(%d)",name,bname,i);
334 TBranch *branch = new AliArraySubBranch(branchname,this,leaflist,basketsize,comp);
335 branch->SetBit(kIsClone);
336 TObjArray *leaves = branch->GetListOfLeaves();
337 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
338 leaf->SetOffset(rd->GetThisOffset()+membertype->Size()*i);
339 leaf->SetLeafCount(leafcount);
340 fBranches.Add(branch);
345 else if (clinfo->IsA()->InheritsFrom("AliDataType")){ //branch for basic type
346 Int_t type = (((AliDataType*)clinfo)->GetDataType())->GetType();
349 Warning("BranchClones","Cannot process member:%s",clinfo->GetName());
352 if (type == 1) itype = "B";
353 if (type == 11) itype = "b";
354 if (type == 3) itype = "I";
355 if (type == 5) itype = "F";
356 if (type == 8) itype = "D";
357 if (type == 13) itype = "i";
358 if (type == 2) itype = "S";
359 if (type == 12) itype = "s";
360 sprintf(leaflist,"%s[%s]/%s",name,branchcount,itype);
361 Int_t comp = compress;
362 if (type == 5) comp--;
363 sprintf(branchname,"%s",clinfo->GetName());
364 TBranch *branch = new AliArraySubBranch(branchname,this,leaflist,basketsize,comp);
365 branch->SetBit(kIsClone);
366 TObjArray *leaves = branch->GetListOfLeaves();
367 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
369 leaf->SetLeafCount(leafcount);
370 fBranches.Add(branch);
377 //______________________________________________________________________________
378 AliArrayBranch::~AliArrayBranch()
380 //*-*-*-*-*-*Default destructor for a BranchClones*-*-*-*-*-*-*-*-*-*-*-*
381 //*-* =====================================
390 //______________________________________________________________________________
391 void AliArrayBranch::Browse(TBrowser *b)
393 fBranches.Browse( b );
396 //______________________________________________________________________________
397 Int_t AliArrayBranch::Fill()
399 //*-*-*-*-*Loop on all Branches of this BranchClones to fill Basket buffer*-*
400 //*-* ===============================================================
404 Int_t nbranches = fBranches.GetEntriesFast();
405 char **ppointer = (char**)(fAddress);
406 if (ppointer == 0) return 0;
407 fList = (AliObjectArray*)(*ppointer);
408 // fN = fList->GetEntriesFast();
409 fN = fList->GetSize();
412 if (fN > fNdataMax) {
413 fNdataMax = fList->GetSize();
414 char branchcount[64];
415 sprintf(branchcount,"%s_",GetName());
416 TLeafI *leafi = (TLeafI*)fBranchCount->GetLeaf(branchcount);
417 leafi->SetMaximum(fNdataMax);
418 for (i=0;i<nbranches;i++) {
419 TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
420 TObjArray *leaves = branch->GetListOfLeaves();
421 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
425 nbytes += fBranchCount->Fill();
426 for (i=0;i<nbranches;i++) {
427 TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
428 TObjArray *leaves = branch->GetListOfLeaves();
429 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
430 // leaf->Import(fList, fN); // MI
431 Import(leaf,fN); // MI change
432 nbytes += branch->Fill();
437 //______________________________________________________________________________
438 Int_t AliArrayBranch::GetEntry(Int_t entry, Int_t getall)
440 //*-*-*-*-*Read all branches of a BranchClones and return total number of bytes
441 //*-* ====================================================================
443 if (TestBit(kDoNotProcess) && !getall) return 0;
444 Int_t nbytes = fBranchCount->GetEntry(entry);
445 TLeaf *leafcount = (TLeaf*)fBranchCount->GetListOfLeaves()->UncheckedAt(0);
446 fN = Int_t(leafcount->GetValue());
447 if (fN <= 0) return 0;
450 Int_t nbranches = fBranches.GetEntriesFast();
452 // if fList exists, create clonesarray objects
454 //fList->ExpandCreateFast(fN); //MI
455 fList->Resize(fN); //MI change
456 for (Int_t i=0;i<nbranches;i++) {
457 branch = (TBranch*)fBranches.UncheckedAt(i);
458 nbytes += ((AliArraySubBranch*)branch)->GetEntryExport(entry, getall, fList, fN); // !!!MI
461 for (Int_t i=0;i<nbranches;i++) {
462 branch = (TBranch*)fBranches.UncheckedAt(i);
463 nbytes += branch->GetEntry(entry, getall);
469 //______________________________________________________________________________
470 void AliArrayBranch::Print(Option_t *option)
472 //*-*-*-*-*-*-*-*-*-*-*-*Print TBranch parameters*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
473 //*-* ========================
475 fBranchCount->Print(option);
477 Int_t nbranches = fBranches.GetEntriesFast();
478 for (i=0;i<nbranches;i++) {
479 TBranch *branch = (TBranch*)fBranches[i];
480 branch->Print(option);
484 //______________________________________________________________________________
485 void AliArrayBranch::Reset(Option_t *option)
487 //*-*-*-*-*-*-*-*Reset a Branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
488 //*-* ====================
490 // Existing buffers are deleted
491 // Entries, max and min are reset
498 Int_t nbranches = fBranches.GetEntriesFast();
499 for (i=0;i<nbranches;i++) {
500 TBranch *branch = (TBranch*)fBranches[i];
501 branch->Reset(option);
503 fBranchCount->Reset();
506 //______________________________________________________________________________
507 void AliArrayBranch::SetAddress(void *add)
509 //*-*-*-*-*-*-*-*Set address of this branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
510 //*-* ====================
514 fAddress = (char*)add;
515 char **ppointer = (char**)(fAddress);
516 if ( (*ppointer)==0 ) { //MI change
517 *ppointer = (char*) new AliObjectArray(fClassName);
518 fAddress = (char*)ppointer;
520 fList = (AliObjectArray*)(*ppointer);
521 fBranchCount->SetAddress(&fN);
525 //______________________________________________________________________________
526 void AliArrayBranch::SetBasketSize(Int_t buffsize)
528 //*-*-*-*-*-*-*-*Reset basket size for all subbranches of this branchclones
529 //*-* ==========================================================
532 fBasketSize = buffsize;
534 Int_t nbranches = fBranches.GetEntriesFast();
535 for (i=0;i<nbranches;i++) {
536 TBranch *branch = (TBranch*)fBranches[i];
537 branch->SetBasketSize(buffsize);
541 //_______________________________________________________________________
542 void AliArrayBranch::Streamer(TBuffer &b)
544 //*-*-*-*-*-*-*-*-*Stream a class object*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
545 //*-* =========================================
547 b.ReadVersion(); //Version_t v = b.ReadVersion();
551 b >> fEntryOffsetLen;
560 fClassName.Streamer(b);
561 fBranches.Streamer(b);
565 Int_t nbranches = fBranches.GetEntriesFast();
566 for (Int_t i=0;i<nbranches;i++) {
567 branch = (TBranch*)fBranches[i];
568 branch->SetBit(kIsClone);
569 leaf = (TLeaf*)branch->GetListOfLeaves()->UncheckedAt(0);
574 AliClassInfo *clinfo = AliClassInfo::FindClassInfo(fClassName);
576 AliObjectArray tmp(fClassName);
577 //MI change - object array to construct class description
578 clinfo = AliClassInfo::FindClassInfo(fClassName);
582 TClass *cl = clinfo->GetClass();
584 // Warning("Streamer","Unknow class: %s. Cannot read BranchClones: %s",
585 // fClassName.Data(),GetName());
590 if (!cl->GetListOfRealData()) cl->BuildRealData();
593 TIter next(cl->GetListOfRealData());
594 while ((rd = (TRealData *) next())) {
595 TDataMember *member = rd->GetDataMember();
596 if (!member->IsBasic()) continue;
597 if (!member->IsPersistent()) continue;
598 TDataType *membertype = member->GetDataType();
599 if (membertype->GetType() == 0) continue;
600 //MI change - for array spliting
601 Int_t arraydim = member->GetArrayDim();
603 for (Int_t i=0;i< member->GetMaxIndex(0);i++){
604 const char * dmname = member->GetName() ;
607 while ( (dmname[j]!='[') && (dmname[j]!=0) ){
612 sprintf(branchname,"%s.%s(%d)",GetName(),bname,i);
613 branch = (TBranch*)fBranches.FindObject(branchname);
614 if (!branch) continue;
615 TObjArray *leaves = branch->GetListOfLeaves();
616 leaf = (TLeaf*)leaves->UncheckedAt(0);
617 leaf->SetOffset(rd->GetThisOffset()+membertype->Size()*i);
620 sprintf(branchname,"%s.%s",GetName(),rd->GetName());
621 branch = (TBranch*)fBranches.FindObject(branchname);
622 if (!branch) continue;
623 TObjArray *leaves = branch->GetListOfLeaves();
624 leaf = (TLeaf*)leaves->UncheckedAt(0);
625 leaf->SetOffset(rd->GetThisOffset());
629 else if (clinfo->IsA()->InheritsFrom("AliDataType")){ //branch for basic type
630 char branchname[100];
631 sprintf(branchname,"%s",clinfo->GetName());
632 branch = (TBranch*)fBranches.FindObject(branchname);
634 TObjArray *leaves = branch->GetListOfLeaves();
635 leaf = (TLeaf*)leaves->UncheckedAt(0);
642 b.WriteVersion(AliArrayBranch::IsA());
646 b << fEntryOffsetLen;
655 fClassName.Streamer(b);
656 fBranches.Streamer(b);
662 void AliArrayBranch::Import(TLeaf * leaf, Int_t n)
665 const Int_t kIntUndefined = -9999;
668 Int_t len = leaf->GetLenStatic();
669 Int_t fOffset = leaf->GetOffset();
670 void *value = leaf->GetValuePointer();
672 for (Int_t i=0;i<n;i++) {
673 clone = (char*)fList->UncheckedAt(i);
675 if (leaf->IsA()==TLeafB::Class()){
676 memcpy(&((Char_t*)value)[j],clone + fOffset, len);
679 if (leaf->IsA()==TLeafC::Class()){
680 memcpy(&((Char_t*)value)[j],clone + fOffset, 1);
683 if (leaf->IsA()==TLeafD::Class()){
684 if (clone) memcpy(&((Double_t*)value)[j],clone + fOffset, 8*len);
685 else memcpy(&((Double_t*)value)[j],&kIntUndefined, 8*len);
688 if (leaf->IsA()==TLeafF::Class()){
689 if (clone) memcpy(&((Float_t*)value)[j],clone + fOffset, 4*len);
690 else memcpy(&((Float_t*)value)[j],&kIntUndefined, 4*len);
693 if (leaf->IsA()==TLeafI::Class()){
694 if (clone) memcpy(&((Int_t*)value)[j],clone + fOffset, 4*len);
695 else memcpy(&((Int_t*)value)[j],&kIntUndefined, 4*len);
698 if (leaf->IsA()==TLeafS::Class()){
699 if (clone) memcpy(&((Short_t*)value)[j],clone + fOffset, 2*len);
700 else memcpy(&((Short_t*)value)[j],&kIntUndefined, 2*len);
707 AliObjectBranch::AliObjectBranch(const Text_t *name, const Text_t *classname, void *addobj,
709 Int_t basketsize, Int_t splitlevel, Int_t compress): TBranchObject()
711 //*-*-*-*-*-*-*-*-*-*-*-*-*Create a BranchObject*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
712 //*-* =====================
714 TClass *cl = gROOT->GetClass(classname);
715 fTree =tree; //MI change
717 Error("TBranchObject","Cannot find class:%s",classname);
720 if (!cl->GetListOfRealData()) cl->BuildRealData();
721 Int_t bufsize=basketsize; //MI ?
724 fCompress = compress;
725 if (compress == -1) {
726 TFile *bfile = fTree->GetDirectory()->GetFile(); //MI chnge fTrre - gTree
727 if (bfile) fCompress = bfile->GetCompressionLevel();
729 if (basketsize < 100) basketsize = 100;
730 fBasketSize = basketsize;
731 fAddress = (char*)addobj;
732 fClassName = classname;
733 fBasketEntry = new Int_t[fMaxBaskets];
734 fBasketBytes = new Int_t[fMaxBaskets];
735 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);