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