StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TTreeIter.cxx
1 // Author: Victor Perev 08/04/01
2 
4 // //
5 // TTreeIter //
6 // //
7 // is a helper class for TTree. //
8 // It is analysis tool to TTree. //
9 // Functionality is similar to TTree::MakeClass() //
10 // But: //
11 // 1. user do not need to create special class, TTreeIter is //
12 // universal; //
13 // //
14 // 2. AUTOMATICALLY, only branches wich user needs to use are READ. //
15 // For complicated TTree it is much faster. //
16 // //
17 // //
18 // Example (see tutorials/tree4.C) : //
19 // TFile f("t4.root"); //
20 // TTree* t4 = (TTree*)f.Get("t4"); //
21 // TTreeIter TH(t4); //
22 // //
23 // init user variables //
24 // const Float_t &temp = TH("fTemperature"); //temperature //
25 // const Int_t &ntrk = TH("fTracks"); //size of clone array//
26 // const Float_t* &pz = TH("fTracks.fPz"); //pz array //
27 // //
28 // TH1F *hz = new TH1F("PX","Px distr", 100,-.5,.5) //
29 // //loop //
30 // while(TH.Next()) { //
31 // //
32 // if (temp >100 ) continue; // too hot //
33 // for (int itr=0; itr<ntrk; itr++) {hz->Fill( pz[itr] );} //
34 // } //
35 // TH.Reset(); //ready for next loop //
36 // //
38 
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <assert.h>
43 
44 #include "TROOT.h"
45 
46 #if ROOT_VERSION_CODE < ROOT_VERSION(3,00,0)
47 #define __OLDROOT__
48 #endif
49 
50 #include "TFile.h"
51 #include "TKey.h"
52 #include "TTree.h"
53 #include "TChain.h"
54 #include "TBranch.h"
55 #ifndef __OLDROOT__
56 #include "TBranchElement.h"
57 #include "TFriendElement.h"
58 #endif
59 #include "TLeaf.h"
60 #include "TStreamerInfo.h"
61 #include "TStreamerElement.h"
62 #include "TTreeIter.h"
63 #include "TList.h"
64 #include "TObjArray.h"
65 #include "TNamed.h"
66 #include "TSystem.h"
67 #include "TRegexp.h"
68 #include "TError.h"
69 #include "TDirIter.h"
70 
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};
74 
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 ,"_____" ,"_____" ,"_____" ,"_____" ,"_____"
100 ,0};
101 
102 
103 
104 //______________________________________________________________________________
105 void TTreeIterCast::Set(void* v,Int_t t,const char* name)
106 {
107 if (t==kDouble32 ) t = kDouble;
108 if (t==kDouble32+20) t = kDouble+20;
109 fV=v;fT=t;fN=name;
110 }
111 //______________________________________________________________________________
112 void *TTreeIterCast::Addr(Int_t outType)
113 {
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));
118  }
119  else if (fT != outType) {
120  Error("Addr","*** Wrong cast:variable %s %s to %s IGNORED ***",
121  TTreeIter::TypeName(fT),fN,TTreeIter::TypeName(outType));
122  v = 0;
123  }
124  if (!v) fE[0]++;
125 // printf("TTreeIterCast::Addr = %p\n",v);
126  return v;
127 }
128 
129 //______________________________________________________________________________
130 TTreeIterCast::operator const Char_t &()
131 {return *((const Char_t*)Addr(kChar));}
132 //______________________________________________________________________________
133 TTreeIterCast::operator const Short_t &()
134 {return *((const Short_t*)Addr(kShort));}
135 //______________________________________________________________________________
136 TTreeIterCast::operator const Int_t &()
137 {return *((const Int_t*)Addr(kInt));}
138 //______________________________________________________________________________
139 TTreeIterCast::operator const Long_t &()
140 {return *((const Long_t*)Addr(kLong));}
141 //______________________________________________________________________________
142 TTreeIterCast::operator const Float_t &()
143 {return *((const Float_t*)Addr(kFloat));}
144 //______________________________________________________________________________
145 TTreeIterCast::operator const Double_t &()
146 {return *((const Double_t*)Addr(kDouble));}
147 
148 //______________________________________________________________________________
149 TTreeIterCast::operator const UChar_t &()
150 {return *((const UChar_t*)Addr(kUChar));}
151 //______________________________________________________________________________
152 TTreeIterCast::operator const UShort_t &()
153 {return *((const UShort_t*)Addr(kUShort));}
154 //______________________________________________________________________________
155 TTreeIterCast::operator const UInt_t &()
156 {return *((const UInt_t*)Addr(kUInt));}
157 //______________________________________________________________________________
158 TTreeIterCast::operator const ULong_t &()
159 {return *((const ULong_t*)Addr(kULong));}
160 
161 //______________________________________________________________________________
162 TTreeIterCast::operator const Char_t *&()
163 {return *((const Char_t**)Addr(kChar+20));}
164 //______________________________________________________________________________
165 TTreeIterCast::operator const Short_t *&()
166 {return *((const Short_t**)Addr(kShort+20));}
167 //______________________________________________________________________________
168 TTreeIterCast::operator const Int_t *&()
169 {return *((const Int_t**)Addr(kInt+20));}
170 //______________________________________________________________________________
171 TTreeIterCast::operator const Long_t *&()
172 {return *((const Long_t**)Addr(kLong+20));}
173 //______________________________________________________________________________
174 TTreeIterCast::operator const Float_t *&()
175 {return *((const Float_t**)Addr(kFloat+20));}
176 //______________________________________________________________________________
177 TTreeIterCast::operator const Double_t *&()
178 {return *((const Double_t**)Addr(kDouble+20));}
179 
180 //______________________________________________________________________________
181 TTreeIterCast::operator const UChar_t *&()
182 {return *((const UChar_t**)Addr(kUChar+20));}
183 //______________________________________________________________________________
184 TTreeIterCast::operator const UShort_t *&()
185 {return *((const UShort_t**)Addr(kUShort+20));}
186 //______________________________________________________________________________
187 TTreeIterCast::operator const UInt_t *&()
188 {return *((const UInt_t**)Addr(kUInt+20));}
189 //______________________________________________________________________________
190 TTreeIterCast::operator const ULong_t *&()
191 {return *((const ULong_t**)Addr(kULong+20));}
192 
193 
194 
195 
196 //______________________________________________________________________________
197 class TTreeIterMem : public TNamed { //special class for TTreeIter
198 public:
199  Int_t fType;
200  Int_t fUnits;
201  Int_t fSize;
202  TString fTyName;
203  Char_t *fMem;
204 
205 public:
206  TTreeIterMem(const char *name,Int_t type,Int_t units,const char *tyName);
207  ~TTreeIterMem(){ delete [] fMem;}
208  void **Alloc(int units=-1);
209  void **GetMem(){return (void**)&fMem;}
210 };
211 //______________________________________________________________________________
212 TTreeIterMem::TTreeIterMem(const char *name,Int_t type,Int_t units,const char *tyName)
213  :TNamed(name,"")
214 {
215  fType = type;
216  fTyName = tyName;
217  fUnits = units;
218  fSize = 0;
219  fMem = 0;
220  Alloc();
221 }
222 
223 //______________________________________________________________________________
224 void **TTreeIterMem::Alloc(int units)
225 {
226  if (units>-1) fUnits = units;
227  if (!fUnits) fUnits=1;
228  delete [] fMem; fMem=0;
229  TClass *kl = 0;
230  int uSize = sizeof(void*);
231  if (fType) {
232  fSize = TTreeIter::TypeSize(fType)*fUnits;
233  } else { //real class
234  if (fTyName[fTyName.Length()-1]!='*') { // not a pointer
235  kl = gROOT->GetClass(fTyName);
236  if (!kl) {
237  Warning("Alloc","No dictionary for class %s",fTyName.Data());
238  return 0;}
239  uSize = kl->Size();
240  }
241  fSize = uSize*fUnits;
242  }
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;
248 }
249 
250 //______________________________________________________________________________
251 ClassImp(TTreeIter)
252 //______________________________________________________________________________
253 
254 TTreeIter::TTreeIter(TTree *tree):fCast(&fNErr)
255 {
256  fNFiles = 0;
257  fTree = 0;
258  if (tree) {
259  fTree = new TChain(tree->GetName());
260  if (tree->IsA() == TChain::Class()) fTree->Add((TChain*)tree);
261  }
262  Init();
263 }
264 //______________________________________________________________________________
265 
266 TTreeIter::TTreeIter(TChain *tree):fCast(&fNErr)
267 {
268  fNFiles = 0;
269  fTree = 0;
270  fTree = tree;
271  Init();
272 }
273 //______________________________________________________________________________
274 
275 TTreeIter::TTreeIter(const char *treeName):fCast(&fNErr)
276 {
277  fTree = 0;
278  fNFiles = 0;
279  if (treeName && treeName[0] && treeName[0]!=' ') fTree = new TChain(treeName);
280  Init();
281 }
282 //______________________________________________________________________________
283 
284 void TTreeIter::Init()
285 {
286  fCint = 0;
287  fNErr = 0;
288  fEntry = 0;
289  fUnits = 0;
290  if (fTree==0) return;
291 #ifndef __OLDROOT__
292  fTree->SetMakeClass(1);
293 #endif
294  fTree->SetBranchStatus("*",0);
295  fTree->SetNotify(this);
296 
297 }
298 //______________________________________________________________________________
299 TTreeIter::~TTreeIter()
300 {
301  fEntry = 0;
302  delete fTree;
303  fMemList.Delete();
304 
305 }
306 
307 //______________________________________________________________________________
308 void TTreeIter::GetInfo(const TBranch *tbp, const char *&tyName
309  ,Int_t &units,void *&add, Int_t &brType)
310 {
311  tyName = 0;
312  brType = 0;
313  TBranch *tb = (TBranch*)tbp;
314  add = tb->GetAddress();
315  units = 0;
316  char *nxt=0;
317  const char *des = strchr(tb->GetName(),'[');
318  if (des) {
319  units = 1;
320  while(des){
321  int ii = strtol(des+1,&nxt,10);
322  if (des+1 != nxt) units *=ii;
323  if ( !*nxt) break;
324  des = nxt;
325  } }
326 
327  int max = 0;
328  int kase = 0;
329  if (strcmp(tb->ClassName(),"TBranchElement")==0) kase = 1;
330  if (strcmp(tb->ClassName(),"TBranchClones" )==0) kase = 2;
331  switch (kase) {
332 #ifndef __OLDROOT__
333  case 1: {TBranchElement *te = (TBranchElement*)tb;
334  max = te->GetMaximum();
335  brType = te->GetType();
336  TString ts(te->GetName());
337  int i = 0;
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();
341  assert(si);
342  TStreamerElement *se = si->GetStreamerElement(ts.Data(),i);
343  if (!se) { tyName = si->GetName(); }
344  else { tyName = se->GetTypeName();}
345  }
346  if (strcmp("TClonesArray",tyName)==0 && tb->GetSplitLevel()) tyName=0;
347  break;
348 #endif
349  case 2: max = 0; tyName = "Int_t"; return;
350 
351  case 0:
352  TLeaf *lf = (TLeaf*)tb->GetListOfLeaves()->First();
353  TLeaf *lc = 0;
354  if (lf) lc = lf->GetLeafCount();
355  if (lc) max = lc->GetMaximum();
356 
357  }
358  if (max) {if (!units) units = 1; units *= max;}
359  if (brType==3) units=0;
360  if (tyName) return;
361 
362  TObjArray *lfList = tb->GetListOfLeaves();
363  TLeaf *tl = (lfList) ? (TLeaf*)lfList->UncheckedAt(0):0;
364  tyName= (tl) ? tl->GetTypeName():0;
365 }
366 //______________________________________________________________________________
367 TBranch *TTreeIter::GetBranch(int idx) const
368 {
369  TObjArray *ll = fTree->GetListOfLeaves();
370  if (!ll) return 0;
371  if (idx>ll->GetLast()) return 0;
372 
373  return ((TLeaf*)ll->At(idx))->GetBranch();
374 }
375 
376 //______________________________________________________________________________
377 void **TTreeIter::Void(const TString varname)
378 {
379  fCint = 1;
380  return Void(varname.Data());
381 }
382 //______________________________________________________________________________
383 void **TTreeIter::Void(const char *varname)
384 {
385  fCast.Set(0,0,varname);
386 // TBranch *br = GetBranch(varname);
387  TBranch *br = fTree->GetBranch(varname);
388  if (br && strcmp(br->ClassName(),"TBranchClones")==0) {//wrong object
389  TString ts(varname); ts+="_";
390  br = fTree->GetBranch(ts.Data());
391  }
392  if (!br) {
393  Warning("operator()","Branch %s NOT FOUND",varname);
394  return 0;
395  }
396 
397  void *addr,**pddr;
398  const char *tyName;
399  Int_t brType;
400  GetInfo(br,tyName,fUnits,addr,brType);
401 
402  int tyCode = TypeCode(tyName);
403  if (!tyCode) {
404 // Warning("operator()","Branch %s non basic %s type,Units %d brType %d",varname,tyName,fUnits,brType);
405  }
406  TTreeIterMem *mem;
407  mem = (TTreeIterMem*)fMemList.FindObject(br->GetName());
408  if (!mem) {
409  mem = new TTreeIterMem(br->GetName(),tyCode,fUnits,tyName);
410  fMemList.Add(mem);
411  pddr = mem->GetMem();
412  fTree->SetBranchStatus(br->GetName(),1);
413  br->SetBit(1);
414  fTree->SetBranchAddress(br->GetName(),*pddr);
415  fBraList.Add(br);
416  } else {
417  pddr = mem->GetMem();
418  }
419 // addr = *pddr;
420 // if (fUnits) { if(tyCode) tyCode+=20; addr = (void*)pddr;}
421 // fCast.Set(addr,tyCode,varname);
422  if (fUnits) { if(tyCode) tyCode+=20;}
423  fCast.Set(pddr,tyCode,varname);
424 
425  return pddr;
426 }
427 //______________________________________________________________________________
428 TTreeIterCast &TTreeIter::operator() (const TString varname)
429 {
430  fCint = 1;
431  return operator() (varname.Data());
432 }
433 //______________________________________________________________________________
434 TTreeIterCast &TTreeIter::operator() (const char *varname)
435 {
436  Void(varname);
437  void *addr = fCast.Addr();
438  if (fCint) {
439  fCint = 0;
440  TTreeIterCast *v =(TTreeIterCast*)addr;
441 // printf("CINT Address %p\n",(void*)v);
442  return *v;//CINT workaround
443  }
444  return fCast;
445 }
446 //______________________________________________________________________________
447 Int_t TTreeIter::Next(Int_t entry)
448 {
449  if (fNErr) {
450  Warning("Next","It was %d errors in Init. Loop ignored",fNErr);
451  fEntry=0; return 0;}
452  if (!TestBit(1)) { SetBit(1); Notify();}
453 
454  int ientry = (entry >= 0) ? entry:fEntry++;
455 
456  Int_t ans = 0;
457 
458  ans = fTree->GetEntry(ientry);
459 #if 0
460  int n = fBraList.GetEntriesFast();
461  for (int i=0;i<n;i++) {
462  TBranch *b = (TBranch*)fBraList.UncheckedAt(i);
463  ans +=b->GetEntry(ientry);
464  }
465 #endif //0
466  assert(!IsCorrupted());
467  if (ans) return ans;
468  fEntry=0;
469  return 0;
470 
471 }
472 //______________________________________________________________________________
473 Bool_t TTreeIter::Notify()
474 {
475  const char *tyName;
476  Int_t units,brType;
477  void *add;
478  assert(!IsCorrupted());
479  fTree->SetBranchStatus("*",0);
480  fBraList.Clear();
481  int n = fMemList.GetEntriesFast();
482  for (int i=0;i<n;i++) {
483  TTreeIterMem *t = (TTreeIterMem*)fMemList.UncheckedAt(i);
484  fTree->SetBranchStatus(t->GetName(),1);
485  TBranch *b = fTree->GetBranch(t->GetName());
486  assert(b);
487  GetInfo(b,tyName,units,add,brType);
488  void **pddr = t->GetMem();
489  if (units > t->fUnits) {
490  pddr = t->Alloc(units);
491  }
492  fTree->SetBranchAddress(t->GetName(),*pddr);
493  }
494 
495  TBranch *br=0;
496  int added = 1;
497  while(added) {
498  added = 0;
499  for (int idx=0;(br=GetBranch(idx));idx++) {
500  if (br->TestBit(kDoNotProcess)) continue;
501  if (fMemList.FindObject(br->GetName())) continue;
502  added++;
503 
504  GetInfo(br,tyName,units,add,brType);
505  if (brType==3 || brType==4 ) {//add counter
506  (*this)(br->GetName());
507  printf("Branch %s activated\n",br->GetName());
508  continue;
509  }
510  TObjArray *brl = br->GetListOfBranches();
511  if (brl && brl->GetEntriesFast()) {//Node
512  printf("Node Branch %s ignored\n",br->GetName());
513  added--;
514  continue;
515  }
516 
517  {// We are here because of ROOT bug. Do workaround
518  fTree->SetBranchStatus(br->GetName(),0);
519  br->SetBit(kDoNotProcess);
520  printf("Branch %s desactivated\n",br->GetName());
521  continue;
522  }
523  }
524  }
525  fMemList.Sort();
526  n = fMemList.GetEntriesFast();
527  for (int i=0;i<n;i++) {
528  TTreeIterMem *t = (TTreeIterMem*)fMemList.UncheckedAt(i);
529  TBranch *b = fTree->GetBranch(t->GetName());
530  assert(b);
531  fBraList.Add(b);
532  }
533  return 0;
534 }
535 //______________________________________________________________________________
536 const char *TTreeIter::IsCorrupted() const
537 {
538 
539  int n = fMemList.GetEntriesFast();
540  assert(n>=0 && n<10000);
541  for (int i=0;i<n;i++) {
542  TTreeIterMem *t = (TTreeIterMem*)fMemList.UncheckedAt(i);
543  assert(t);
544  assert(t->fMem);
545  assert(t->fSize>0);
546 
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);
550  return t->GetName();
551  }
552  return 0;
553 }
554 //______________________________________________________________________________
555 void TTreeIter::ls(const TObjArray *brList,Int_t lvl,Option_t* option)
556 {
557  TBranch *branch;
558  if (!brList) return;
559 
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);
566  }
567 }
568 //______________________________________________________________________________
569 void TTreeIter::ls(const TTree *ttp, Option_t* option)
570 {
571  TTree *tt = (TTree *)ttp;
572  if (!tt) return;
573  ls(tt->GetListOfBranches(),0,option);
574 }
575 //______________________________________________________________________________
576 void TTreeIter::ls(Option_t* option) const
577 {
578  if(option && strstr(option,"fil")) {
579  if(!fTree) return;
580  if(!fTree->GetListOfFiles()) return;
581  fTree->GetListOfFiles()->ls();
582  return;
583  }
584  ls(fTree,option);
585 }
586 //______________________________________________________________________________
587 void TTreeIter::Print(Option_t* option) const
588 {
589  ls(fTree,option);
590 }
591 //______________________________________________________________________________
592 void TTreeIter::Print(const TBranch *tb,Int_t lvl, Option_t* option)
593 {
594  const char *tyName;
595  Int_t units,brType;
596  char active[2]={0,0};
597  void *add;
598 
599  GetInfo(tb,tyName,units,add,brType);
600  active[0]='*';
601  if (tb->TestBit(kDoNotProcess)) active[0]=0;
602 
603  printf("%10p(%10p) - ",(void*)tb,(void*)add);
604  for (int i=0;i<lvl;i++){printf(" ");}
605 
606  printf("%s%s(%s)",active,tb->GetName(),tb->ClassName());
607 
608  printf("\t // Max=%d Type=%s,brType=%d",units,tyName,brType);
609  printf("\n");
610 }
611 //______________________________________________________________________________
612 const char* TTreeIter::TypeName(Int_t ity)
613 {
614  return NTTI[ity];
615 }
616 //______________________________________________________________________________
617 Int_t TTreeIter::TypeSize(Int_t ity)
618 {
619  int t = ity%10;
620  switch(t) {
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);
627  default: return 0;
628  }
629 }
630 
631 //______________________________________________________________________________
632 Int_t TTreeIter::TypeCode(const char *typeName)
633 {
634  for (int i=1; NTTI[i]; i++) {if (strcmp(typeName,NTTI[i])==0) return i%20;}
635 // printf("*** TypeCode ERROR: %s is UNKNOWN ***\n",typeName);
636  return 0;
637 }
638 //______________________________________________________________________________
639 void TTreeIter::Streamer(TBuffer &) {assert(0);}
640 //_____________________________________________________________________________
641 Int_t TTreeIter::AddFile(const Char_t *file)
642 {
643  const char* fullname;
644  int num = 0;
645  TDirIter dirIter(file);
646  while((fullname=dirIter.NextFile())) {
647  fNFiles++; num++;
648  printf("%04d - TTreeIter::AddFile %s\n",fNFiles,fullname);
649  if (fTree == 0) WhichTree(fullname);
650  if (fTree) fTree->Add(fullname);
651  }
652 
653  Init();
654  return num;
655 }
656 //______________________________________________________________________________
657 void TTreeIter::WhichTree(const char *fileName)
658 {
659  TString fileNameS = fileName;
660  gSystem->ExpandPathName(fileNameS);
661 // printf(" fileName = %s\n",fileNameS.Data());
662 
663 
664 
665  TFile *tfile = TFile::Open(fileNameS.Data());
666  if (! tfile || tfile->IsZombie()) {
667  printf("*** Can NOT open %s ***\n",fileNameS.Data());
668  return;}
669 
670  TList *keyList = tfile->GetListOfKeys();
671  TListIter NextKey(keyList);
672  TKey *key; const char *ttName=0;
673  while ( (key = (TKey*)NextKey()) )
674  {
675  if (strcmp("TTree" ,key->GetClassName())!=0
676  && strcmp("TNtuple",key->GetClassName())!=0) continue;
677  ttName = key->GetName(); break;
678  }
679  if (ttName==0) return;
680  printf(" Got TTree = %s\n",ttName);
681 
682  fTree = new TChain(ttName);
683  delete tfile;
684  Init();
685 }
686 
687 
688 
Definition: FJcore.h:367
TObjArray fMemList
pointer to TTree/TChain object
Definition: TTreeIter.h:65
Int_t fUnits
list of used branches
Definition: TTreeIter.h:67
TObjArray fBraList
list of mem objects
Definition: TTreeIter.h:66
TChain * fTree
current entry number
Definition: TTreeIter.h:64