Containers definition
[u/mrichter/AliRoot.git] / CONTAINERS / AliArrayBranch.cxx
CommitLineData
08edbb90 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/*
17$Log$
18*/
19#include "TROOT.h"
20#include "AliArrayBranch.h"
21#include "TFile.h"
22#include "TTree.h"
23#include "TBasket.h"
24#include "TClass.h"
25#include "TRealData.h"
26#include "TDataType.h"
27#include "TDataMember.h"
28
29#include "TBranch.h"
30#include "TBranchClones.h"
31#include "TLeaf.h"
32#include "TLeafB.h"
33#include "TLeafC.h"
34#include "TLeafF.h"
35#include "TLeafD.h"
36#include "TLeafI.h"
37#include "TLeafS.h"
38#include "TLeafObject.h"
39
40#include "AliObjectArray.h"
41#include "AliDataType.h"
42
43//-----------------------------------------------------
44// A Branch for the case of an array of clone objects.
45//-----------------------------------------------------
46
47//*KEND.
48
49R__EXTERN TTree *gTree;
50
51ClassImp(AliArraySubBranch)
52ClassImp(AliArrayBranch)
53ClassImp(AliObjectBranch)
54ClassImp(AliTree)
55
56
57
58Int_t AliArraySubBranch::GetEntryExport(Int_t entry, Int_t getall, AliObjectArray *list, Int_t nentries)
59{
60//*-*-*-*-*-*Read all leaves of entry and return total number of bytes*-*-*
61//*-* export buffers to real objects in the AliObjectArray list.
62//*-*
63
64 if (TestBit(kDoNotProcess)) return 0;
65 if (fReadEntry == entry) return 1;
66 if (entry < 0 || entry >= fEntryNumber) return 0;
67 Int_t nbytes;
68 Int_t first = fBasketEntry[fReadBasket];
69 Int_t last;
70 if (fReadBasket == fWriteBasket) last = fEntryNumber - 1;
71 else last = fBasketEntry[fReadBasket+1] - 1;
72//
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];
77 }
78
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();
87 }
88// Int_t bufbegin = basket->GetEntryPointer(entry-first);
89 Int_t bufbegin;
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);
94
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;
99 fReadEntry = entry;
100
101 return nbytes;
102}
103
104void AliArraySubBranch::ReadBasketExport(TBuffer &b, TLeaf *leaf, AliObjectArray *list, Int_t n)
105{
106 //
107 //
108 Int_t len = leaf->GetLenStatic();
109 Int_t offset = leaf->GetOffset();
110 void *value = leaf->GetValuePointer();
111
112 //8bit integer
113 if (leaf->IsA()==TLeafB::Class()){
114 Int_t j = 0;
115 for (Int_t i=0;i<n;i++) {
116 memcpy((char*)list->UncheckedAt(i) + offset,&((Char_t*)value)[j], len);
117 j += len;
118 }
119 }
120 //variable length string.
121 if (leaf->IsA()==TLeafC::Class()){
122 UChar_t len;
123 b >> len;
124 if (len) {
125 if (len >= len) len = len-1;
126 b.ReadFastArray((Char_t*)value,len);
127 ((Char_t*)value)[len] = 0;
128 } else {
129 value = 0;
130 }
131 Int_t j = 0;
132 for (Int_t i=0;i<n;i++) {
133 memcpy((char*)list->UncheckedAt(i) + offset,&((Char_t*)value)[j], 1);
134 j += len;
135 }
136 }
137 //double
138 if (leaf->IsA()==TLeafD::Class()){
139 b.ReadFastArray(((Double_t*)value),n*len);
140 Int_t j = 0;
141 for (Int_t i=0;i<n;i++) {
142 memcpy((char*)list->UncheckedAt(i) + offset,&((Double_t*)value)[j], 8*len);
143 j += len;
144 }
145 }
146 //float
147 if (leaf->IsA()==TLeafF::Class()){
148 if (n*len == 1) {
149 b >> ((Float_t*)value)[0];
150 } else {
151 b.ReadFastArray(((Float_t*)value),n*len);
152 }
153
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++) {
159 ff[j] = val[j];
160 }
161 val += len;
162 }
163 return;
164 }
165 //int2
166 if (leaf->IsA()==TLeafS::Class()){
167 if (n*len == 1) {
168 b >> ((Short_t*)value)[0];
169 } else {
170 b.ReadFastArray(((Short_t*)value),n*len);
171 }
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++) {
177 ii[j] = val[j];
178 }
179 val += len;
180 }
181 return;
182 }
183 //int4
184 if (leaf->IsA()==TLeafI::Class()){
185 if (n*len == 1) {
186 b >> ((Int_t*)value)[0];
187 } else {
188 b.ReadFastArray(((Int_t*)value),n*len);
189 }
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++) {
195 ii[j] = val[j];
196 }
197 val += len;
198 }
199 return;
200 }
201}
202
203
204//______________________________________________________________________________
205AliArrayBranch::AliArrayBranch(): TBranch()
206{
207//*-*-*-*-*-*Default constructor for BranchClones*-*-*-*-*-*-*-*-*-*
208//*-* ====================================
209
210 fList = 0;
211 fRead = 0;
212 fN = 0;
213 fNdataMax = 0;
214 fBranchCount = 0;
215}
216
217
218//______________________________________________________________________________
219AliArrayBranch::AliArrayBranch(const Text_t *name, void *pointer, TTree * tree, Int_t basketsize, Int_t compress)
220 :TBranch()
221{
222//*-*-*-*-*-*-*-*-*-*-*-*-*Create a BranchClones*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
223//*-* =====================
224//
225 char leaflist[80];
226 char branchname[80];
227 char branchcount[64];
228 fTree = tree;
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
231 SetName(name);
232 if (compress == -1) {
233 TFile *bfile = fTree->GetDirectory()->GetFile();
234 if (bfile) compress = bfile->GetCompressionLevel();
235 }
236 char *cpointer = (char*)pointer;
237 char **ppointer = (char**)(cpointer);
238 fList = (AliObjectArray*)(*ppointer);
239 fAddress = cpointer;
240 fRead = 0;
241 fN = 0;
242 fNdataMax = 0;
243
244 AliClassInfo *clinfo = fList->GetClassInfo();
245 if (!clinfo) return;
246 fClassName = clinfo->GetName();
247
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);
255
256//*-*- Create the first basket
257
258 fDirectory = fTree->GetDirectory();
259 fFileName = "";
260
261 TBasket *basket = new TBasket(branchcount,fTree->GetName(),this);
262 fBaskets.Add(basket);
263
264//*-*- Loop on all public data members of the class and its base classes
265
266 TClass *cl = fList->GetClass();
267 if (cl){
268 if (!cl->GetListOfRealData()) cl->BuildRealData();
269
270 const char *itype = 0;
271 TRealData *rd;
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());
277 continue;
278 }
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();
283 if (type == 0) {
284 Warning("BranchClones","Cannot process member:%s",member->GetName());
285 continue;
286 }
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";
295
296
297 Int_t arraydim = member->GetArrayDim();
298 if (arraydim!=1){
299 // OLD Version
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();
311 if (arraydim) {
312 Int_t maxindex = member->GetMaxIndex(arraydim-1);
313 leaf->SetLen(maxindex);
314 }
315 fBranches.Add(branch);
316 }
317 else
318 for (Int_t i=0;i< member->GetMaxIndex(0);i++){
319 const char * dmname = member->GetName() ;
320 char bname[200];
321 Int_t j=0;
322 while ( (dmname[j]!='[') && (dmname[j]!=0) ){
323 bname[j]=dmname[j];
324 j++;
325 }
326 bname[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);
338 }
339
340 }
341 }
342 else if (clinfo->IsA()->InheritsFrom("AliDataType")){ //branch for basic type
343 Int_t type = (((AliDataType*)clinfo)->GetDataType())->GetType();
344 char *itype = 0;
345 if (type <=0)
346 Warning("BranchClones","Cannot process member:%s",clinfo->GetName());
347 else{
348
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);
365 leaf->SetOffset(0);
366 leaf->SetLeafCount(leafcount);
367 fBranches.Add(branch);
368 }
369 }
370
371}
372
373
374//______________________________________________________________________________
375AliArrayBranch::~AliArrayBranch()
376{
377//*-*-*-*-*-*Default destructor for a BranchClones*-*-*-*-*-*-*-*-*-*-*-*
378//*-* =====================================
379
380 delete fBranchCount;
381 fBranchCount = 0;
382 fBranches.Delete();
383 fList = 0;
384}
385
386
387//______________________________________________________________________________
388void AliArrayBranch::Browse(TBrowser *b)
389{
390 fBranches.Browse( b );
391}
392
393//______________________________________________________________________________
394Int_t AliArrayBranch::Fill()
395{
396//*-*-*-*-*Loop on all Branches of this BranchClones to fill Basket buffer*-*
397//*-* ===============================================================
398
399 Int_t i;
400 Int_t nbytes = 0;
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();
407 fEntries++;
408
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);
419 leaf->SetAddress();
420 }
421 }
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();
430 }
431 return nbytes;
432}
433
434//______________________________________________________________________________
435Int_t AliArrayBranch::GetEntry(Int_t entry, Int_t getall)
436{
437//*-*-*-*-*Read all branches of a BranchClones and return total number of bytes
438//*-* ====================================================================
439
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;
445
446 TBranch *branch;
447 Int_t nbranches = fBranches.GetEntriesFast();
448
449 // if fList exists, create clonesarray objects
450 if (fList) {
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
456 }
457 } else {
458 for (Int_t i=0;i<nbranches;i++) {
459 branch = (TBranch*)fBranches.UncheckedAt(i);
460 nbytes += branch->GetEntry(entry, getall);
461 }
462 }
463 return nbytes;
464}
465
466//______________________________________________________________________________
467void AliArrayBranch::Print(Option_t *option)
468{
469//*-*-*-*-*-*-*-*-*-*-*-*Print TBranch parameters*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
470//*-* ========================
471
472 fBranchCount->Print(option);
473 Int_t i;
474 Int_t nbranches = fBranches.GetEntriesFast();
475 for (i=0;i<nbranches;i++) {
476 TBranch *branch = (TBranch*)fBranches[i];
477 branch->Print(option);
478 }
479}
480
481//______________________________________________________________________________
482void AliArrayBranch::Reset(Option_t *option)
483{
484//*-*-*-*-*-*-*-*Reset a Branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
485//*-* ====================
486//
487// Existing buffers are deleted
488// Entries, max and min are reset
489//
490
491 fEntries = 0;
492 fTotBytes = 0;
493 fZipBytes = 0;
494 Int_t i;
495 Int_t nbranches = fBranches.GetEntriesFast();
496 for (i=0;i<nbranches;i++) {
497 TBranch *branch = (TBranch*)fBranches[i];
498 branch->Reset(option);
499 }
500 fBranchCount->Reset();
501}
502
503//______________________________________________________________________________
504void AliArrayBranch::SetAddress(void *add)
505{
506//*-*-*-*-*-*-*-*Set address of this branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
507//*-* ====================
508//*-*
509
510 fReadEntry = -1;
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;
516 }
517 fList = (AliObjectArray*)(*ppointer);
518 fBranchCount->SetAddress(&fN);
519
520}
521
522//______________________________________________________________________________
523void AliArrayBranch::SetBasketSize(Int_t buffsize)
524{
525//*-*-*-*-*-*-*-*Reset basket size for all subbranches of this branchclones
526//*-* ==========================================================
527//
528
529 fBasketSize = buffsize;
530 Int_t i;
531 Int_t nbranches = fBranches.GetEntriesFast();
532 for (i=0;i<nbranches;i++) {
533 TBranch *branch = (TBranch*)fBranches[i];
534 branch->SetBasketSize(buffsize);
535 }
536}
537
538//_______________________________________________________________________
539void AliArrayBranch::Streamer(TBuffer &b)
540{
541//*-*-*-*-*-*-*-*-*Stream a class object*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
542//*-* =========================================
543 if (b.IsReading()) {
544 b.ReadVersion(); //Version_t v = b.ReadVersion();
545 TNamed::Streamer(b);
546 b >> fCompress;
547 b >> fBasketSize;
548 b >> fEntryOffsetLen;
549 b >> fMaxBaskets;
550 b >> fWriteBasket;
551 b >> fEntryNumber;
552 b >> fEntries;
553 b >> fTotBytes;
554 b >> fZipBytes;
555 b >> fOffset;
556 b >> fBranchCount;
557 fClassName.Streamer(b);
558 fBranches.Streamer(b);
559 fTree = gTree;
560 TBranch *branch;
561 TLeaf *leaf;
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);
567 leaf->SetOffset(0);
568 }
569 fRead = 1;
570
571 AliClassInfo *clinfo = AliClassInfo::FindClassInfo(fClassName);
572 if (!clinfo) {
573 AliObjectArray tmp(fClassName);
574 //MI change - object array to construct class description
575 clinfo = AliClassInfo::FindClassInfo(fClassName);
576 }
577 if (!clinfo) return;
578
579 TClass *cl = clinfo->GetClass();
580 // if (!cl) {
581 // Warning("Streamer","Unknow class: %s. Cannot read BranchClones: %s",
582 // fClassName.Data(),GetName());
583 // return;
584 //}
585 if (cl){
586
587 if (!cl->GetListOfRealData()) cl->BuildRealData();
588 char branchname[80];
589 TRealData *rd;
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();
599 if (arraydim==1){
600 for (Int_t i=0;i< member->GetMaxIndex(0);i++){
601 const char * dmname = member->GetName() ;
602 char bname[200];
603 Int_t j=0;
604 while ( (dmname[j]!='[') && (dmname[j]!=0) ){
605 bname[j]=dmname[j];
606 j++;
607 }
608 bname[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);
615 }
616 }
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());
623 }
624
625 }
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);
630 if (branch){
631 TObjArray *leaves = branch->GetListOfLeaves();
632 leaf = (TLeaf*)leaves->UncheckedAt(0);
633 leaf->SetOffset(0);
634 }
635 }
636 }
637 else{
638
639 b.WriteVersion(AliArrayBranch::IsA());
640 TNamed::Streamer(b);
641 b << fCompress;
642 b << fBasketSize;
643 b << fEntryOffsetLen;
644 b << fMaxBaskets;
645 b << fWriteBasket;
646 b << fEntryNumber;
647 b << fEntries;
648 b << fTotBytes;
649 b << fZipBytes;
650 b << fOffset;
651 b << fBranchCount;
652 fClassName.Streamer(b);
653 fBranches.Streamer(b);
654 }
655}
656
657
658
659void AliArrayBranch::Import(TLeaf * leaf, Int_t n)
660{
661
662 const Int_t kIntUndefined = -9999;
663 Int_t j = 0;
664 char *clone;
665 Int_t len = leaf->GetLenStatic();
666 Int_t fOffset = leaf->GetOffset();
667 void *value = leaf->GetValuePointer();
668 //
669 for (Int_t i=0;i<n;i++) {
670 clone = (char*)fList->UncheckedAt(i);
671 //8bit int
672 if (leaf->IsA()==TLeafB::Class()){
673 memcpy(&((Char_t*)value)[j],clone + fOffset, len);
674 }
675 //var size
676 if (leaf->IsA()==TLeafC::Class()){
677 memcpy(&((Char_t*)value)[j],clone + fOffset, 1);
678 }
679 //double
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);
683 }
684 //float
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);
688 }
689 //int
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);
693 }
694 //short
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);
698 }
699 j += len;
700 }
701 //
702}
703
704AliObjectBranch::AliObjectBranch(const Text_t *name, const Text_t *classname, void *addobj,
705 TTree * tree,
706 Int_t basketsize, Int_t splitlevel, Int_t compress): TBranchObject()
707{
708//*-*-*-*-*-*-*-*-*-*-*-*-*Create a BranchObject*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
709//*-* =====================
710//
711 TClass *cl = gROOT->GetClass(classname);
712 fTree =tree; //MI change
713 if (!cl) {
714 Error("TBranchObject","Cannot find class:%s",classname);
715 return;
716 }
717 if (!cl->GetListOfRealData()) cl->BuildRealData();
718 Int_t bufsize=basketsize; //MI ?
719 SetName(name);
720 SetTitle(name);
721 fCompress = compress;
722 if (compress == -1) {
723 TFile *bfile = fTree->GetDirectory()->GetFile(); //MI chnge fTrre - gTree
724 if (bfile) fCompress = bfile->GetCompressionLevel();
725 }
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];
733 fOldObject = 0;
734
735 fBasketEntry[0] = fEntryNumber;
736 fBasketBytes[0] = 0;
737
738 TLeaf *leaf = new TLeafObject(name,classname);
739 leaf->SetBranch(this);
740 leaf->SetAddress(addobj);
741 fNleaves = 1;
742 fLeaves.Add(leaf);
743 fTree->GetListOfLeaves()->Add(leaf); //MI change fTree-gTree
744
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);
750
751//*-*- Create the first basket
752 // fTree = gTree; //MI change - no need anymore
753 fDirectory = fTree->GetDirectory();
754 fFileName = "";
755
756 if (!splitlevel){
757 TBasket *basket = new TBasket(name,fTree->GetName(),this);
758 fBaskets.Add(basket);
759 return;
760 }
761
762 //
763 //
764 TBranch * branch =this;
765 TObjArray *blist = branch->GetListOfBranches();
766 const char *rdname;
767 const char *dname;
768 char branchname[64];
769 if (!cl->GetListOfRealData()) cl->BuildRealData();
770 char **apointer = (char**)(addobj);
771 TObject *obj = (TObject*)(*apointer);
772 Bool_t delobj = kFALSE;
773 if (!obj) {
774 obj = (TObject*)cl->New();
775 delobj = kTRUE;
776 }
777//*-*- Loop on all public data members of the class and its base classes
778 Int_t lenName = strlen(name);
779 Int_t isDot = 0;
780 if (name[lenName-1] == '.') isDot = 1;
781 TBranch *branch1 = 0;
782 TRealData *rd;
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();
790
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;
794
795 TDataType *dtype = dm->GetDataType();
796 Int_t code = 0;
797 if (dtype) code = dm->GetDataType()->GetType();
798
799//*-*- Encode branch name. Use real data member name
800 sprintf(branchname,"%s",rdname);
801 if (isDot) {
802 if (dm->IsaPointer()) sprintf(branchname,"%s%s",name,&rdname[1]);
803 else sprintf(branchname,"%s%s",name,&rdname[0]);
804 }
805 char leaflist[64];
806 Int_t offset = rd->GetThisOffset();
807 char *pointer = (char*)obj + offset;
808 if (dm->IsaPointer()) {
809 TClass *clobj = 0;
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);
818 blist->Add(branch1);
819 } else {
820 if (isDot) branch1 = new TBranchObject(&branchname[0],list->ClassName(),pointer,bufsize);
821 else branch1 = new TBranchObject(&branchname[1],list->ClassName(),pointer,bufsize);
822 blist->Add(branch1);
823 }
824 }
825 else
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);
833 blist->Add(branch1);
834 } else {
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);
837 blist->Add(branch1);
838 }
839 }
840 else {
841 if (!clobj) {
842 if (code != 1) continue;
843 sprintf(leaflist,"%s/%s",dname,"C");
844 branch1 = new TBranch(branchname,pointer,leaflist,bufsize);
845 branch1->SetTitle(dname);
846 blist->Add(branch1);
847 } else {
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 (*)
853 blist->Add(branch1);
854 }
855 }
856 }else {
857//*-*-------------Data Member is a basic data type----------
858 if (dm->IsBasic()) {
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");
867 else {
868 printf("Cannot create branch for rdname=%s, code=%d\n",branchname, code);
869 leaflist[0] = 0;
870 }
871 branch1 = new TBranch(branchname,pointer,leaflist,bufsize);
872 branch1->SetTitle(rdname);
873 blist->Add(branch1);
874 }
875 }
876 if (branch1) branch1->SetOffset(offset);
877 else Warning("Branch","Cannot process member:%s",rdname);
878 }
879 if (delobj) delete obj;
880}
881
882
883
884//______________________________________________________________________________
885void AliObjectBranch::SetAddress(void *add)
886{
887//*-*-*-*-*-*-*-*Set address of this branch*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
888//*-* ====================
889//
890
891 //special case when called from code generated by TTree::MakeClass
892 if (Long_t(add) == -1) {
893 SetBit(kWarn);
894 return;
895 }
896 fReadEntry = -1;
897 Int_t nbranches = fBranches.GetEntriesFast();
898 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0);
899 if (leaf) leaf->SetAddress(add);
900 TBranch *branch;
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());
906 if (!obj && cl) {
907 obj = (TObject*)cl->New();
908 *ppointer = (void*)obj;
909 }
910 Int_t i, offset;
911 if (!cl) {
912 for (i=0;i<nbranches;i++) {
913 branch = (TBranch*)fBranches[i];
914 pointer = (char*)obj;
915 branch->SetAddress(pointer);
916 }
917 return;
918 }
919 if (!cl->GetListOfRealData()) cl->BuildRealData();
920 char *fullname = new char[200];
921 const char *bname = GetName();
922 Int_t lenName = strlen(bname);
923 Int_t isDot = 0;
924 if (bname[lenName-1] == '.') isDot = 1;
925 const char *rdname;
926 TRealData *rd;
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();
933 Int_t code = 0;
934 if (dtype) code = dm->GetDataType()->GetType();
935 offset = rd->GetThisOffset();
936 pointer = (char*)obj + offset;
937 branch = 0;
938 if (dm->IsaPointer()) {
939 TClass *clobj = 0;
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);
945 }
946 else
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);
951 }
952 else {
953 if (!clobj) {
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);
958 } else {
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);
963 }
964 }
965 } else {
966 if (dm->IsBasic()) {
967 if (isDot) sprintf(fullname,"%s%s",bname,&rdname[0]);
968 else sprintf(fullname,"%s",&rdname[0]);
969 branch = (TBranch*)fBranches.FindObject(fullname);
970 }
971 }
972 if(branch) branch->SetAddress(pointer);
973 }
974 delete [] fullname;
975}
976
977
978
979
980
981AliTree::AliTree(const char *name,const char *title, Int_t maxvirtualsize):
982 TTree(name,title,maxvirtualsize)
983{
984 //
985 //default constructor for AliTree
986 gTree =this;
987}
988
989TBranch * AliTree::AliBranch(const char *name, void *clonesaddress, Int_t bufsize, Int_t splitlevel,
990 Int_t compres)
991{
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;
997 gTree = this;
998 if (splitlevel) {
999 TBranch *branch = new AliArrayBranch(name,clonesaddress,this,bufsize, compres);
1000 fBranches.Add(branch);
1001 return branch;
1002 } else {
1003 TBranchObject *branch = new TBranchObject(name,list->ClassName(),clonesaddress,bufsize,0);
1004 fBranches.Add(branch);
1005 return branch;
1006 }
1007}
1008
1009TBranch* AliTree::AliBranch(const char *name, const char *classname, void *addobj,
1010 Int_t bufsize, Int_t splitlevel)
1011{
1012 gTree = this;
1013 TClass *cl = gROOT->GetClass(classname);
1014 if (!cl) {
1015 Error("BranchObject","Cannot find class:%s",classname);
1016 return 0;
1017 }
1018 TBranch * branch = new AliObjectBranch(name,classname,addobj, this, bufsize,splitlevel);
1019 fBranches.Add(branch);
1020 return branch;
1021}
1022
1023