46 #if ROOT_VERSION_CODE < ROOT_VERSION(3,00,0)
56 #include "TBranchElement.h"
57 #include "TFriendElement.h"
60 #include "TStreamerInfo.h"
61 #include "TStreamerElement.h"
62 #include "TTreeIter.h"
64 #include "TObjArray.h"
71 enum ETTI { kUnknown=0
72 ,kChar = 1, kShort = 2, kInt = 3, kLong = 4, kFloat = 5, kDouble = 8,kDouble32 = 9
73 ,kUChar = 11, kUShort = 12, kUInt = 13, kULong = 14};
75 const char* NTTI[] = {
"Unknown"
76 ,
"Char_t" ,
"Short_t" ,
"Int_t" ,
"Long_t" ,
"Float_t"
77 ,
"_______" ,
"_______" ,
"Double_t" ,
"Double32_t" ,
"_______"
78 ,
"UChar_t" ,
"UShort_t" ,
"UInt_t" ,
"ULong_t" ,
"_______"
79 ,
"_______" ,
"_______" ,
"_______" ,
"_______" ,
"_______"
80 ,
"Char_t*" ,
"Short_t*" ,
"Int_t*" ,
"Long_*t" ,
"Float_t*"
81 ,
"_______*" ,
"_______*" ,
"Double_t*" ,
"_______*" ,
"_______*"
82 ,
"UChar_t*" ,
"UShort_t*" ,
"UInt_t*" ,
"ULong_t*" ,
"_______*"
83 ,
"_______" ,
"_______" ,
"_______" ,
"_______" ,
"_______"
84 ,
"char" ,
"short" ,
"int" ,
"long" ,
"float"
85 ,
"_____" ,
"_____" ,
"double" ,
"_____" ,
"_____"
86 ,
"uchar" ,
"ushort" ,
"uint" ,
"ulong" ,
"_____"
87 ,
"_____" ,
"_____" ,
"_____" ,
"_____" ,
"_____"
88 ,
"char*" ,
"short*" ,
"int*" ,
"long_*t" ,
"float*"
89 ,
"_____*" ,
"_____*" ,
"double*" ,
"_____*" ,
"_____*"
90 ,
"uchar*" ,
"ushort*" ,
"uint*" ,
"ulong*" ,
"_____*"
91 ,
"_____" ,
"_____" ,
"_____" ,
"_____" ,
"_____"
92 ,
"char" ,
"short" ,
"int" ,
"long" ,
"float"
93 ,
"_____" ,
"_____" ,
"double" ,
"_____" ,
"_____"
94 ,
"unsigned char" ,
"unsigned short" ,
"unsigned int" ,
"unsigned long" ,
"_____"
95 ,
"_____" ,
"_____" ,
"_____" ,
"_____" ,
"_____"
96 ,
"char*" ,
"short*" ,
"int*" ,
"long_*t" ,
"float*"
97 ,
"_____*" ,
"_____*" ,
"double*" ,
"_____*" ,
"_____*"
98 ,
"unsigned char*",
"unsigned short*",
"unsigned int*",
"unsigned long*",
"_____*"
99 ,
"_____" ,
"_____" ,
"_____" ,
"_____" ,
"_____"
105 void TTreeIterCast::Set(
void* v,Int_t t,
const char* name)
107 if (t==kDouble32 ) t = kDouble;
108 if (t==kDouble32+20) t = kDouble+20;
112 void *TTreeIterCast::Addr(Int_t outType)
114 void *v = (outType>20) ? fV: *((
void**)fV);
115 if (fT+20 == outType) {
116 Warning(
"Addr",
"*** Possible wrong cast:variable %s %s to %s ACCEPTED ***",
117 TTreeIter::TypeName(fT),fN,TTreeIter::TypeName(outType));
119 else if (fT != outType) {
120 Error(
"Addr",
"*** Wrong cast:variable %s %s to %s IGNORED ***",
121 TTreeIter::TypeName(fT),fN,TTreeIter::TypeName(outType));
130 TTreeIterCast::operator
const Char_t &()
131 {
return *((
const Char_t*)Addr(kChar));}
133 TTreeIterCast::operator
const Short_t &()
134 {
return *((
const Short_t*)Addr(kShort));}
136 TTreeIterCast::operator
const Int_t &()
137 {
return *((
const Int_t*)Addr(kInt));}
139 TTreeIterCast::operator
const Long_t &()
140 {
return *((
const Long_t*)Addr(kLong));}
142 TTreeIterCast::operator
const Float_t &()
143 {
return *((
const Float_t*)Addr(kFloat));}
145 TTreeIterCast::operator
const Double_t &()
146 {
return *((
const Double_t*)Addr(kDouble));}
149 TTreeIterCast::operator
const UChar_t &()
150 {
return *((
const UChar_t*)Addr(kUChar));}
152 TTreeIterCast::operator
const UShort_t &()
153 {
return *((
const UShort_t*)Addr(kUShort));}
155 TTreeIterCast::operator
const UInt_t &()
156 {
return *((
const UInt_t*)Addr(kUInt));}
158 TTreeIterCast::operator
const ULong_t &()
159 {
return *((
const ULong_t*)Addr(kULong));}
162 TTreeIterCast::operator
const Char_t *&()
163 {
return *((
const Char_t**)Addr(kChar+20));}
165 TTreeIterCast::operator
const Short_t *&()
166 {
return *((
const Short_t**)Addr(kShort+20));}
168 TTreeIterCast::operator
const Int_t *&()
169 {
return *((
const Int_t**)Addr(kInt+20));}
171 TTreeIterCast::operator
const Long_t *&()
172 {
return *((
const Long_t**)Addr(kLong+20));}
174 TTreeIterCast::operator
const Float_t *&()
175 {
return *((
const Float_t**)Addr(kFloat+20));}
177 TTreeIterCast::operator
const Double_t *&()
178 {
return *((
const Double_t**)Addr(kDouble+20));}
181 TTreeIterCast::operator
const UChar_t *&()
182 {
return *((
const UChar_t**)Addr(kUChar+20));}
184 TTreeIterCast::operator
const UShort_t *&()
185 {
return *((
const UShort_t**)Addr(kUShort+20));}
187 TTreeIterCast::operator
const UInt_t *&()
188 {
return *((
const UInt_t**)Addr(kUInt+20));}
190 TTreeIterCast::operator
const ULong_t *&()
191 {
return *((
const ULong_t**)Addr(kULong+20));}
206 TTreeIterMem(
const char *name,Int_t type,Int_t units,
const char *tyName);
208 void **Alloc(
int units=-1);
209 void **GetMem(){
return (
void**)&fMem;}
212 TTreeIterMem::TTreeIterMem(
const char *name,Int_t type,Int_t units,
const char *tyName)
224 void **TTreeIterMem::Alloc(
int units)
226 if (units>-1) fUnits = units;
227 if (!fUnits) fUnits=1;
228 delete [] fMem; fMem=0;
230 int uSize =
sizeof(
void*);
232 fSize = TTreeIter::TypeSize(fType)*fUnits;
234 if (fTyName[fTyName.Length()-1]!=
'*') {
235 kl = gROOT->GetClass(fTyName);
237 Warning(
"Alloc",
"No dictionary for class %s",fTyName.Data());
241 fSize = uSize*fUnits;
243 fMem =
new char[fSize+8];
244 memset(fMem,0,fSize);
245 if (kl){
for (
char *cc=fMem; cc < fMem+fSize; cc+=uSize){kl->New((
void*)cc);}}
246 strcpy(fMem+fSize,
"Perev");
247 return (
void**)&fMem;
259 fTree =
new TChain(tree->GetName());
260 if (tree->IsA() == TChain::Class()) fTree->Add((TChain*)tree);
266 TTreeIter::TTreeIter(TChain *tree):fCast(&fNErr)
275 TTreeIter::TTreeIter(
const char *treeName):fCast(&fNErr)
279 if (treeName && treeName[0] && treeName[0]!=
' ') fTree =
new TChain(treeName);
284 void TTreeIter::Init()
290 if (
fTree==0)
return;
292 fTree->SetMakeClass(1);
294 fTree->SetBranchStatus(
"*",0);
295 fTree->SetNotify(
this);
299 TTreeIter::~TTreeIter()
308 void TTreeIter::GetInfo(
const TBranch *tbp,
const char *&tyName
309 ,Int_t &units,
void *&add, Int_t &brType)
313 TBranch *tb = (TBranch*)tbp;
314 add = tb->GetAddress();
317 const char *des = strchr(tb->GetName(),
'[');
321 int ii = strtol(des+1,&nxt,10);
322 if (des+1 != nxt) units *=ii;
329 if (strcmp(tb->ClassName(),
"TBranchElement")==0) kase = 1;
330 if (strcmp(tb->ClassName(),
"TBranchClones" )==0) kase = 2;
333 case 1: {TBranchElement *te = (TBranchElement*)tb;
334 max = te->GetMaximum();
335 brType = te->GetType();
336 TString ts(te->GetName());
338 while ((i=ts.Index(
"."))>=0) { ts.Replace(0,i+1,
"");}
339 i=ts.Index(
"[");
if (i>=0) ts.Replace(i,9999,
"");
340 TStreamerInfo *si = te->GetInfo();
342 TStreamerElement *se = si->GetStreamerElement(ts.Data(),i);
343 if (!se) { tyName = si->GetName(); }
344 else { tyName = se->GetTypeName();}
346 if (strcmp(
"TClonesArray",tyName)==0 && tb->GetSplitLevel()) tyName=0;
349 case 2: max = 0; tyName =
"Int_t";
return;
352 TLeaf *lf = (TLeaf*)tb->GetListOfLeaves()->First();
354 if (lf) lc = lf->GetLeafCount();
355 if (lc) max = lc->GetMaximum();
358 if (max) {
if (!units) units = 1; units *= max;}
359 if (brType==3) units=0;
362 TObjArray *lfList = tb->GetListOfLeaves();
363 TLeaf *tl = (lfList) ? (TLeaf*)lfList->UncheckedAt(0):0;
364 tyName= (tl) ? tl->GetTypeName():0;
367 TBranch *TTreeIter::GetBranch(
int idx)
const
369 TObjArray *ll =
fTree->GetListOfLeaves();
371 if (idx>ll->GetLast())
return 0;
373 return ((TLeaf*)ll->At(idx))->GetBranch();
377 void **TTreeIter::Void(
const TString varname)
380 return Void(varname.Data());
383 void **TTreeIter::Void(
const char *varname)
385 fCast.Set(0,0,varname);
387 TBranch *br =
fTree->GetBranch(varname);
388 if (br && strcmp(br->ClassName(),
"TBranchClones")==0) {
389 TString ts(varname); ts+=
"_";
390 br =
fTree->GetBranch(ts.Data());
393 Warning(
"operator()",
"Branch %s NOT FOUND",varname);
400 GetInfo(br,tyName,
fUnits,addr,brType);
402 int tyCode = TypeCode(tyName);
411 pddr = mem->GetMem();
412 fTree->SetBranchStatus(br->GetName(),1);
414 fTree->SetBranchAddress(br->GetName(),*pddr);
417 pddr = mem->GetMem();
422 if (fUnits) {
if(tyCode) tyCode+=20;}
423 fCast.Set(pddr,tyCode,varname);
431 return operator() (varname.Data());
437 void *addr = fCast.Addr();
447 Int_t TTreeIter::Next(Int_t entry)
450 Warning(
"Next",
"It was %d errors in Init. Loop ignored",fNErr);
452 if (!TestBit(1)) { SetBit(1); Notify();}
454 int ientry = (entry >= 0) ? entry:fEntry++;
458 ans =
fTree->GetEntry(ientry);
461 for (
int i=0;i<n;i++) {
462 TBranch *b = (TBranch*)
fBraList.UncheckedAt(i);
463 ans +=b->GetEntry(ientry);
466 assert(!IsCorrupted());
473 Bool_t TTreeIter::Notify()
478 assert(!IsCorrupted());
479 fTree->SetBranchStatus(
"*",0);
482 for (
int i=0;i<n;i++) {
484 fTree->SetBranchStatus(t->GetName(),1);
485 TBranch *b =
fTree->GetBranch(t->GetName());
487 GetInfo(b,tyName,units,add,brType);
488 void **pddr = t->GetMem();
489 if (units > t->fUnits) {
490 pddr = t->Alloc(units);
492 fTree->SetBranchAddress(t->GetName(),*pddr);
499 for (
int idx=0;(br=GetBranch(idx));idx++) {
500 if (br->TestBit(kDoNotProcess))
continue;
501 if (
fMemList.FindObject(br->GetName()))
continue;
504 GetInfo(br,tyName,units,add,brType);
505 if (brType==3 || brType==4 ) {
506 (*this)(br->GetName());
507 printf(
"Branch %s activated\n",br->GetName());
510 TObjArray *brl = br->GetListOfBranches();
511 if (brl && brl->GetEntriesFast()) {
512 printf(
"Node Branch %s ignored\n",br->GetName());
518 fTree->SetBranchStatus(br->GetName(),0);
519 br->SetBit(kDoNotProcess);
520 printf(
"Branch %s desactivated\n",br->GetName());
527 for (
int i=0;i<n;i++) {
529 TBranch *b =
fTree->GetBranch(t->GetName());
536 const char *TTreeIter::IsCorrupted()
const
540 assert(n>=0 && n<10000);
541 for (
int i=0;i<n;i++) {
547 char *perev = t->fMem+t->fSize;
548 if (strcmp(perev,
"Perev") ==0 )
continue;
549 Error(
"IsCorrupted",
"Branch=%s Units=%d Mem=%p ***\n",t->GetName(),
fUnits,perev);
555 void TTreeIter::ls(
const TObjArray *brList,Int_t lvl,Option_t* option)
560 Int_t nb = brList->GetEntriesFast();
561 for (
int iBr=0;iBr<nb;iBr++) {
562 branch = (TBranch*)brList->UncheckedAt(iBr);
563 if (!branch)
continue;
564 Print(branch,lvl,option);
565 ls(branch->GetListOfBranches(),lvl+1,option);
569 void TTreeIter::ls(
const TTree *ttp, Option_t* option)
571 TTree *tt = (TTree *)ttp;
573 ls(tt->GetListOfBranches(),0,option);
576 void TTreeIter::ls(Option_t* option)
const
578 if(option && strstr(option,
"fil")) {
580 if(!
fTree->GetListOfFiles())
return;
581 fTree->GetListOfFiles()->ls();
587 void TTreeIter::Print(Option_t* option)
const
592 void TTreeIter::Print(
const TBranch *tb,Int_t lvl, Option_t* option)
596 char active[2]={0,0};
599 GetInfo(tb,tyName,units,add,brType);
601 if (tb->TestBit(kDoNotProcess)) active[0]=0;
603 printf(
"%10p(%10p) - ",(
void*)tb,(
void*)add);
604 for (
int i=0;i<lvl;i++){printf(
" ");}
606 printf(
"%s%s(%s)",active,tb->GetName(),tb->ClassName());
608 printf(
"\t // Max=%d Type=%s,brType=%d",units,tyName,brType);
612 const char* TTreeIter::TypeName(Int_t ity)
617 Int_t TTreeIter::TypeSize(Int_t ity)
621 case kChar:;
case kShort:;
return t;
622 case kInt:
return sizeof(Int_t);
623 case kLong:
return sizeof(Long_t);
624 case kFloat:
return sizeof(Float_t);
625 case kDouble:
return sizeof(Double_t);
626 case kDouble32:
return sizeof(Double_t);
632 Int_t TTreeIter::TypeCode(
const char *typeName)
634 for (
int i=1; NTTI[i]; i++) {
if (strcmp(typeName,NTTI[i])==0)
return i%20;}
639 void TTreeIter::Streamer(TBuffer &) {assert(0);}
641 Int_t TTreeIter::AddFile(
const Char_t *file)
643 const char* fullname;
646 while((fullname=dirIter.NextFile())) {
648 printf(
"%04d - TTreeIter::AddFile %s\n",fNFiles,fullname);
649 if (
fTree == 0) WhichTree(fullname);
657 void TTreeIter::WhichTree(
const char *fileName)
659 TString fileNameS = fileName;
660 gSystem->ExpandPathName(fileNameS);
665 TFile *tfile = TFile::Open(fileNameS.Data());
666 if (! tfile || tfile->IsZombie()) {
667 printf(
"*** Can NOT open %s ***\n",fileNameS.Data());
670 TList *keyList = tfile->GetListOfKeys();
671 TListIter NextKey(keyList);
672 TKey *key;
const char *ttName=0;
673 while ( (key = (TKey*)NextKey()) )
675 if (strcmp(
"TTree" ,key->GetClassName())!=0
676 && strcmp(
"TNtuple",key->GetClassName())!=0)
continue;
677 ttName = key->GetName();
break;
679 if (ttName==0)
return;
680 printf(
" Got TTree = %s\n",ttName);
682 fTree =
new TChain(ttName);
TObjArray fMemList
pointer to TTree/TChain object
Int_t fUnits
list of used branches
TObjArray fBraList
list of mem objects
TChain * fTree
current entry number