StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StTree.cxx
1 #include <stdio.h>
2 #include "Stypes.h"
3 #include "StTree.h"
4 #include "TRegexp.h"
5 #include "TDirIter.h"
6 #include "TKey.h"
7 #include "TError.h"
8 #include <stdlib.h>
9 
10 #ifdef __RFIO__
11 #include "TRFIOFile.h"
12 #endif
13 
14 void DummyErrorHandlerFunc(int , Bool_t , const char *, const char *){;}
15 
16 
17 
18 
19 const char* TFOPT[9] = {"0","READ","RECREATE","UPDATE",
20  "0","READ","RECREATE","UPDATE",0};
21 const char RWU[] = "0rwu0rnu0rcu";
22 char IOMODE[] = "0";
23 
24 Int_t StIO::fgDebug = 0;
25 
26 static inline Int_t IntOMode(char ciomode)
27 {
28 char *c=(char *)strchr(RWU,tolower(ciomode));
29 return (c) ? (c-RWU)&3 : 0;
30 }
31 
32 #ifdef __RFIO__
33 extern "C" {
34  int rfio_open(const char *filepath, int flags, int mode);
35  int rfio_close(int s);
36  int rfio_read(int s, char *ptr, int size);
37  int rfio_write(int s, char *ptr, int size);
38  int rfio_lseek(int s, int offset, int how);
39  int rfio_access(const char *filepath, int mode);
40  int rfio_unlink(const char *filepath);
41  int rfio_parse(const char *name, char **host, char **path);
42 };
43 #endif
44 
45 class Cat : public TNamed {
46 public:
47  Cat(){fNGeant=0;fNKeys=0;fNRecs=0;fSize=0;fNFiles=0;};
48  double fSize;
49  int fNGeant;
50  int fNKeys;
51  int fNRecs;
52  int fNFiles;
53 };
54 
55 ClassImp(StIOEvent)
56 StIOEvent::StIOEvent():TObject(){fObj=(TObject*)(-1);};
57 //______________________________________________________________________________
58 void StIOEvent::Browse(TBrowser *b)
59 {
60  if (b && fObj && (Long_t)fObj != (-1)) fObj->Browse(b);
61 }
62 //______________________________________________________________________________
63 void StIOEvent::Streamer(TBuffer &R__b)
64 {
65  // Stream an object of class StIOEvent.
66 
67  if (R__b.IsReading()) {
68  Version_t R__v = R__b.ReadVersion(); if (R__v) { }
69  TObject::Streamer(R__b);
70  R__b >> fObj;
71  } else {
72  R__b.WriteVersion(StIOEvent::IsA());
73  TObject::Streamer(R__b);
74  R__b << fObj;
75  }
76 }
77 
78 //_______________________________________________________________________________
79 
80 Int_t StIO::Write(TFile *file, const StUKey &ukey, TObject *obj)
81 {
82  assert(file);
83  if (!obj) return kStWarn;
84 
85  StIOEvent event;
86  event.fObj = obj; event.SetUniqueID(ukey.GetSum());
87  // TFile *bakfile = gFile;
88  TDirectory *bakdir = gDirectory; file->cd();
89 
90  event.Write(ukey.GetKey(),TObject::kOverwrite|TObject::kSingleKey);
91  if (gFile) gFile->Flush();
92  // gFile=bakfile;
93  gDirectory=bakdir;
94  return 0;
95 }
96 //_______________________________________________________________________________
97 TObject *StIO::Read(TFile *file, const char *name)
98 {
99  TObject *toread=0;
100  TKey *key = 0;
101  assert(file);
102 
103  TFile *bakfile = gFile; TDirectory *bakdir = gDirectory; file->cd();
104 
105  if (!gFile) { printf("<StIO::Read> No file open \n"); goto RETURN;}
106 
107  if (name[0]=='*') {
108  key = (TKey*)gDirectory->GetListOfKeys()->At(0);
109  if (strcmp(".StreamerList",key->GetName())==0)
110  key = (TKey*)gDirectory->GetListOfKeys()->At(1);
111  }
112  else key = (TKey*)gDirectory->GetListOfKeys()->FindObject(name);
113 
114  if (!key) {
115  if(fgDebug) printf("<StIO::Read> Key %s not found\n",name);
116  goto RETURN; }
117 
118  if (name[0]!='*' && strcmp(key->GetClassName(),"StIOEvent"))
119  { printf("<StIO::Read> Key %s has wrong className %s\n",
120  key->GetName(),key->GetClassName());
121  toread = (TObject*)(-1); goto RETURN; }
122 
123  toread = key->ReadObj(); if (!toread) toread = (TObject*)(-1);
124 
125 RETURN:
126  // gFile=bakfile;
127  gDirectory=bakdir; return toread;
128 }
129 //_______________________________________________________________________________
130 TObject *StIO::Read(TFile *file, const StUKey &ukey)
131 {
132  StIOEvent *event = 0;
133  TObject *retn = 0;
134  retn = Read(file,ukey.GetKey());
135  if (!retn) return 0;
136  if (retn == (TObject*)(-1)) return retn;
137  if (retn->IsA()!=StIOEvent::Class()) return retn;
138  event = (StIOEvent*)retn;
139  retn = event->fObj;
140  assert( !retn || retn==(TObject*)(-1) || event->GetUniqueID()==ukey.GetSum());
141  delete event;
142  return retn;
143 }
144 //_______________________________________________________________________________
145 Int_t StIO::GetNextKey(TFile *file, StUKey &ukey,ULong_t &handle)
146 {
147  TObjLink *lnk; TList *lk; const char *kname; TObject *obj;
148  enum { kSorted = 1};
149  assert(file);
150 
151  TString tk = ukey.GetKey(); ukey = kUMAX;
152  const char* prevkey = (const char*)tk;
153  int lname = strlen(ukey.GetName())+1;
154 
155  lk = file->GetListOfKeys(); if(!lk) return 1;
156  if (!lk->TestBit(kSorted)) {lk->Sort(); lk->SetBit(kSorted);handle = 0;}
157 
158  // Find an object in this list using its name. Requires a sequential
159  // scan till the object has been found. Returns 0 if object with specified
160  // name is not found. This method overrides the generic FindObject()
161  // of TCollection for efficiency reasons.
162 
163  if (handle) {
164  lnk = (TObjLink*)handle;
165  handle = 0;
166  obj = lnk->GetObject();
167  if (strcmp(prevkey,obj->GetName())>0) lnk = lk->FirstLink();
168  } else {
169  lnk = lk->FirstLink();
170  }
171 
172  while (lnk) {
173  obj = lnk->GetObject();
174  kname = obj->GetName();
175  if (strcmp(prevkey, kname)<0) break;
176  lnk = lnk->Next();
177  }
178  if (!lnk) return 1;
179  if (strncmp(prevkey,kname,lname)) lnk = 0;
180  if (!lnk) return 1;
181  ukey.SetKey(kname);
182  handle = (ULong_t)lnk;
183  return 0;
184 }
185 //_______________________________________________________________________________
186 TObject *StIO::ReadNext(TFile *file, StUKey &ukey, ULong_t &handle)
187 {
188  if(GetNextKey(file,ukey,handle)) return 0;;
189  return Read(file,ukey);
190 }
191 //_______________________________________________________________________________
192 TString StIO::RFIOName(const char *name)
193 {
194  TString file(name);
195  TNamed *tn;
196  TList *rfiomap = (TList *)gROOT->GetListOfSpecials()->FindObject(".rfiomap");
197  if (file.Contains(".daq")) rfiomap = 0; //no RFIO for .daq
198  if (rfiomap) { // check the map
199  TIter next(rfiomap);
200  while ((tn = (TNamed*)next())) {//matching loop
201  int n = strlen(tn->GetName());
202  if (!n) continue;
203  if (strncmp(file,tn->GetName(),n)) continue;
204  file.Replace(0,0,tn->GetTitle());
205  break;
206  } //end matching loop
207  } //end check the map
208  return file;
209 }
210 //_______________________________________________________________________________
211 TFile *StIO::Open(const char *name, Option_t *option,const char *title,Int_t compress)
212 {
213  //printf("DEBUG:: StIO::Open(%s)\n",name);
214 
215  TString file = RFIOName(name);
216  if(strcmp("READ",option)==0 && !IfExi(name)) return 0;
217  if(strcmp("read",option)==0 && !IfExi(name)) return 0;
218  if(strcmp("Read",option)==0 && !IfExi(name)) return 0;
219  TFile *tf = TFile::Open(file,option,title,compress);
220  if (!tf || !tf->IsZombie()) return tf;
221  delete tf;
222  return 0;
223 }
224 //_______________________________________________________________________________
225 Int_t StIO::IfExi(const char *name)
226 {
227  TString file = (name);
228 
229  //printf("DEBUG:: StIO::IfExi Expanding(%s)\n",name);
230  gSystem->ExpandPathName(file);
231 
232  // Supress error message
233  ErrorHandlerFunc_t dummy = &DummyErrorHandlerFunc;
234  ErrorHandlerFunc_t curre = SetErrorHandler(dummy);
235 
236  //printf("DEBUG:: StIO::IfExi AccessingPathName(%s)\n",file.Data());
237  // JL - This attempts to do a root auth even if xroot
238 #if 0
239  if (!gSystem->AccessPathName(file)){
240  SetErrorHandler(curre);
241  return 1;
242 
243  } else
244 #endif
245  {
246  int l = file.Length();
247  if (file(l-5,5)!=".root"){
248  SetErrorHandler(curre);
249  return !gSystem->AccessPathName(file);
250  } else {
251  //printf("DEBUG:: Opening %s\n",name);
252  // Workaround:
253  // Due the ROOT (4.04.02) TSystem::FindHelper bug one can not
254  // use TSystem::AccessPathName method to test files on
255  // the "rootd" servers
256  TFile *tf = TFile::Open(file);
257  // return old error handler
258  SetErrorHandler(curre);
259  //printf("DEBUG:: Done with %s\n",name);
260 
261  int z = (!tf || tf->IsZombie());
262  delete tf;
263  return !z;
264  }
265  }
266 }
267 //===============================================================================
268 
269 ClassImp(StBranch)
270 
271 //_______________________________________________________________________________
272 StBranch::StBranch(const char *name, StTree *parent,Option_t *opt):TDataSet(name,parent)
273 {
274 
275  SetTitle(".StBranch");
276  fNEvents=0;fUKey=name;fUKey=0;fIOMode=0;fTFile=0;fDebug=0;fHandle=0;
277  SetOption(opt);
278 
279 }
280 StBranch::~StBranch()
281 {
282  Close();
283 
284 }
285 //_______________________________________________________________________________
286 void StBranch::SetOption(Option_t *opt)
287 {
288  if (opt) fOption = opt;
289  fOption.ToUpper();
290 }
291 //_______________________________________________________________________________
292 void StBranch::SetIOMode(Option_t *iomode)
293 {
294 
295 if (!iomode || !iomode[0]) return;
296 fIOMode = ::IntOMode(iomode[0]);
297 fHandle=0;
298 }
299 //_______________________________________________________________________________
300 Option_t *StBranch::GetIOMode()
301 {
302 IOMODE[0]=0; if (fIOMode>0) IOMODE[0] = RWU[int(fIOMode)]; return IOMODE;
303 }
304 
305 //_______________________________________________________________________________
306 Int_t StBranch::SetFile(const char *file,const char *mode,int insist)
307 {
308  fHandle=0;
309  fIOMode = abs(fIOMode);
310  if (fTFile && !insist) { Error("SetFile","File is already opened");return kStWarn;}
311  if (file && file[0]) fFile=file;
312  if (mode && mode[0]) SetIOMode(mode);
313  return 0;
314 }
315 //_______________________________________________________________________________
316 Int_t StBranch::UpdateFile(const char *file)
317 {
318 fHandle=0;
319 fIOMode = abs(fIOMode);
320 TString bas[2],dir[2];
321 TString nam(GetName()); nam.ReplaceAll("Branch","");
322 nam.Insert(0,"."); nam += ".root";
323 TString outFile = file; gSystem->ExpandPathName(outFile);
324  dir[0] = gSystem->DirName (outFile);
325  bas[0] = gSystem->BaseName(outFile);
326 
327 if (strncmp(".none ",GetFile(),6)==0) {//FileName was corrupted by old bug
328 
329  TString ts(GetFile()); ts.Remove(0,6); SetFile(ts);
330 }
331 
332  dir[1] = gSystem->DirName (GetFile());
333  bas[1] = gSystem->BaseName(GetFile());
334 //VP SetIOMode("0");
335  if (bas[0] == bas[1] || bas[0].Contains(nam)) SetIOMode("r");
336  //VP?? else bas[0]=bas[1];
337  for (int d=0; d<2; d++) {
338  for (int b=0; b<2; b++) {
339  if (!bas[b].Contains(nam)) continue;
340  char *newFile = gSystem->ConcatFileName(dir[d],bas[b]);
341  if (StIO::IfExi(newFile)) {
342  fFile = newFile;
343  printf("<StBranch::UpdateFile> Branch=%s file %s\n",GetName(),newFile);
344  delete [] newFile;
345  return 0;
346  } } }
347  fIOMode = -abs(fIOMode);
348  return 0;
349 }
350 //_______________________________________________________________________________
351 Int_t StBranch::SetTFile(TFile *tfile)
352 {
353  if (!tfile) return 0;
354  if (fTFile==tfile) return 0;
355  fHandle=0;
356  if (fTFile) Close();
357  fTFile=0;
358  SetFile(tfile->GetName());
359  Open();
360  return 0;
361 }
362 
363 //_______________________________________________________________________________
364 void StBranch::Close(const char *)
365 {
366  fHandle=0;
367  if (!fIOMode) return;
368  if (!fTFile) return;
369  if (strncmp(".none",GetFile(),4)==0) return;
370  TFile *tf = fTFile;
371  fTFile = 0;
372  TString ts(tf->GetTitle());
373  int idx = ts.Index("StBranch=Y");
374  assert (idx>=0);
375  ts.Replace(idx+9,1,"");
376  tf->SetTitle(ts);
377  if (ts.Contains("StBranch=Y")) return;
378  tf->Close("");
379  printf("** <StBranch::Close> Branch=%s \tFile=%s \tClosed **\n"
380  ,GetName(),(const char*)fFile);
381  delete tf;
382  if (!(fIOMode&2)) return;
383  ts = GetFile();
384  ts.Replace(0,0,".none ");
385  SetFile((const char*)ts);
386 }
387 //_______________________________________________________________________________
388 const char *StBranch::GetFile()
389 {
390  TString dir(fFile);
391  int kase=0;
392  if (!fFile.IsNull()) kase = 2;
393  if (kase && fFile[fFile.Length()-1]=='/') kase = 1;
394 
395  if (kase<2) { // Construct file name
396  fFile=GetName(); fFile.ReplaceAll("Branch",""); fFile+=".root";
397  StTree *tree = (StTree*)GetParent();
398  if (tree) { // include base name
399  const char* base = tree->GetBaseName();
400  if (base) {fFile.Insert(0,"."); fFile.Insert(0,base);}}
401  if (kase==1) fFile.Insert(0,dir);
402  }
403 
404  return (const char*)fFile;
405 }
406 
407 
408 //_______________________________________________________________________________
409 Int_t StBranch::Open()
410 {
411  if (fIOMode<=0) return 0;
412  if (fTFile) return 0;
413  if (strncmp(".none",GetFile(),4)==0) return 1;
414  OpenTFile();
415  return 0;
416 }
417 //_______________________________________________________________________________
418 Int_t StBranch::WriteEvent(const StUKey &ukey)
419 {
420  int iret;
421  if ( fIOMode<=0) return 0;
422  if (!(fIOMode&2)) return 0;
423  fUKey.Update(ukey,GetName());
424  if (!fList) return kStWarn; //empty
425  if (!fList->First()) return kStWarn; //empty
426  if(Open()) return 1;
427  fNEvents++;
428 
429  TList savList;
430  SetParAll(0,this,&savList);
431  if (IsOption("const")) {//Write constant branch (event independent)
432  StUKey uk(fUKey); uk = (UInt_t)(-2);
433  iret = StIO::Write(fTFile,uk, fList);
434  fIOMode = -fIOMode;
435  } else {
436  iret = StIO::Write(fTFile,fUKey,fList);
437  }
438  SetParAll(&savList);
439 
440  return 0;
441 }
442 
443 //_______________________________________________________________________________
444 Int_t StBranch::GetEvent(Int_t mode)
445 {
446  TObject *obj=0;
447  if ( fIOMode<=0) return 0;
448  if (!(fIOMode&1)) return 0;
449  Delete(); if (fList) delete fList; fList=0;
450  if(Open()) return 1;
451 
452  if (IsOption("const")) {//Read constant branch (event independent)
453  StUKey uk(fUKey); uk = (UInt_t)(-2);
454  obj = StIO::Read (fTFile,uk); fIOMode = -fIOMode;
455 
456  } else if (mode) {//Read next
457  obj = StIO::ReadNext(fTFile,fUKey,fHandle);
458 
459  } else {//Read this one
460  obj = StIO::Read (fTFile,fUKey);
461  }
462 
463  if (obj == 0) return kStEOF;
464  if (obj == (TObject*)(-1)) return kStErr;
465  fList = (TList*)obj;
466 
467  SetParAll(this,this,0);
468 
469  return 0;
470 }
471 //_______________________________________________________________________________
472 Int_t StBranch::ReadEvent(const StUKey &ukey)
473 {
474  if ( fIOMode<=0) return 0;
475  if (!(fIOMode&1)) return 0;
476  fUKey.Update(ukey,GetName());
477  return GetEvent(0);
478 }
479 //_______________________________________________________________________________
480 Int_t StBranch::NextEvent()
481 {
482  if ( fIOMode<=0) return 0;
483  if (!(fIOMode&1)) return 0;
484  Clear();
485  return GetEvent(1);
486 }
487 
488 //_______________________________________________________________________________
489 Int_t StBranch::NextEvent (StUKey &ukey)
490 {
491  if ( fIOMode<=0) return 0;
492  if (!(fIOMode&1)) return 0;
493  Clear();
494  fUKey.Update(ukey,GetName());
495  int iret = GetEvent(1);
496  ukey.Update(fUKey);
497  return iret;
498 }
499 //_______________________________________________________________________________
500 void StBranch::SetParAll(TDataSet *parNew,TDataSet *parOld,TList *savList)
501 {
502  TDataSetIter next(parOld);
503  TDataSet *son,*p;
504  while ((son=next())) {
505  p = son->GetParent();
506  son->SetParent(parNew);
507  if (savList) {
508  assert(p);
509  savList->AddFirst(son); savList->AddFirst(p);
510  SetParAll(son,son,savList);
511  }
512  }// end while
513 }
514 //_______________________________________________________________________________
515 void StBranch::SetParAll(TList *savList)
516 {
517  assert(savList);
518  TDataSet *son,*par;
519  while ((par=(TDataSet*)savList->First())) {
520  savList->Remove(par);
521  son = (TDataSet*)savList->First(); assert(son);
522  savList->Remove(son);
523  son->SetParent(par);
524  }// end while
525 }
526 //_______________________________________________________________________________
527 void StBranch::OpenTFile()
528 {
529  if (fTFile) return;
530  fHandle = 0;
531  TFile *tf= gROOT->GetFile(GetFile());
532  fTFile = tf;
533  if (!fTFile) {
534  fTFile = StIO::Open(GetFile(),TFOPT[int(fIOMode)],GetName());
535 
536  }
537  if (!fTFile) {
538  Error("OpenTFile","File %s NOT OPENED ***\n",GetFile());
539  Error("OpenTFile","Branch %s desactivated ***\n",GetName());
540  delete fTFile; fTFile=0; SetIOMode("0");
541  } else {
542  TString ts(fTFile->GetTitle());
543  if (ts.Contains("StBranch="))
544  { ts.ReplaceAll("StBranch=","StBranch=Y");}
545  else
546  { ts += " StBranch=Y";}
547  fTFile->SetTitle(ts);
548  if (tf) return;
549 
550  printf("** <StBranch::Open> Branch=%s \tMode=%s \tFile=%s \tOpened **\n"
551  ,GetName(),TFOPT[int(fIOMode)],(const char*)fFile);
552 
553  }
554 }
555 //_______________________________________________________________________________
556 void StBranch::Clear(Option_t *)
557 {
558  Delete();
559 }
560 //===============================================================================
561 
562 ClassImp(StTree)
563 
564 //_______________________________________________________________________________
565 StTree::StTree(const char *name):StBranch(name)
566 {
567  SetTitle(".StTree");
568 }
569 
570 //_______________________________________________________________________________
571 StTree::~StTree()
572 { Close(); Delete();}
573 
574 //_______________________________________________________________________________
575 void StTree::SetIOMode(Option_t *iomode)
576 {
577  StBranch::SetIOMode(iomode);
578  TDataSetIter next(this);StBranch *br;
579  while ((br=(StBranch*)next())) { br->SetIOMode(iomode);}
580 }
581 //_______________________________________________________________________________
582 Int_t StTree::SetFile(const char *file,const char *mode,int /* insist */)
583 {
584  if (mode && *mode) StBranch::SetIOMode(mode);
585  if (!file || !*file) return 0;
586 
587  if (fIOMode&1) { //ReadMode
588  UpdateFile(file);
589 
590  }
591  if (fIOMode&2) { //WriteMode
592 
593  SetBaseName(file);
594  }
595  return 0;
596 }
597 
598 //_______________________________________________________________________________
599 void StTree::Clear(Option_t*)
600 {
601  TDataSetIter next(this);StBranch *br;
602  while ((br=(StBranch*)next())) {/*if(!br->IsOption("const"))*/ br->Clear();}
603 }
604 
605 //_______________________________________________________________________________
606 Int_t StTree::Open()
607 {
608  TDataSetIter nextA(this);StBranch *brA;
609  while ((brA=(StBranch*)nextA())) {
610  if (brA->GetIOMode()[0]=='0') continue;
611  if (brA->GetTFile()) continue;
612  brA->Open();
613  }
614  return 0;
615 }
616 //_______________________________________________________________________________
617 Int_t StTree::UpdateFile(const char *file)
618 {
619  TDataSetIter next(this);StBranch *br;
620  while ((br=(StBranch*)next())) br->UpdateFile(file);
621  return 0;
622 }
623 
624 //_______________________________________________________________________________
625 Int_t StTree::WriteEvent(const StUKey &ukey)
626 {
627  fUKey.Update(ukey,GetName()); Open();
628  TDataSetIter next(this);StBranch *br;
629  while ((br=(StBranch*)next())) br->WriteEvent(fUKey);
630  fNEvents++;
631  return 0;
632 }
633 
634 //_______________________________________________________________________________
635 Int_t StTree::ReadEvent(const StUKey &ukey)
636 {
637  Int_t iret=0,num=0;
638  fUKey.Update(ukey,GetName()); Open();
639  TDataSetIter next(this);StBranch *br;
640  while ((br=(StBranch*)next())) { //Read all branches
641  if ( (br->fIOMode<0)) continue;
642  if (!(br->fIOMode&1)) continue;
643  iret=br->ReadEvent(fUKey);
644  if (!iret) num++;
645  if(iret==kStErr) return kStErr;
646  }
647  return (num)? 0:kStEOF;
648 }
649 
650 //_______________________________________________________________________________
651 Int_t StTree::NextKey()
652 {
653  if (Open()) return kStEOF;
654  TDataSetIter next(this); StBranch *br;
655  StUKey minKey = kUMAX;
656  StUKey tryKey;
657 
658 
659  while ((br=(StBranch*)next())) {
660  if ( (br->fIOMode<0)) continue;
661  if (!(br->fIOMode&1)) continue;
662  if (br->IsOption("const")) continue;
663  tryKey.Update(fUKey,br->GetName());
664  if (StIO::GetNextKey(br->fTFile,tryKey,br->fHandle))continue;
665  tryKey = "";
666  if (tryKey.Compare(minKey)<0) minKey=tryKey;
667  }
668  fUKey = minKey;
669  return minKey.EOK() ? kStEOF:0;
670 }
671 //_____________________________________________________________________________
672 Int_t StTree::Skip(int nskip)
673 {
674  for (; nskip; nskip--)
675  {
676  int ret = NextKey();
677  if (ret) break;
678  }
679 
680  return nskip;
681 }
682 //_______________________________________________________________________________
683 Int_t StTree::NextEvent(StUKey &ukey)
684 {
685  fUKey.Update(ukey,GetName());int iret=NextEvent(); ukey.Update(fUKey); return iret;
686 }
687 //_______________________________________________________________________________
688 Int_t StTree::NextEvent()
689 {
690  int iret=0,nAkt=0;
691  TDataSetIter next(this); StBranch *br=0;
692 
693  int kase = 0; StBranch *br0=0;
694  while ((br=(StBranch*)next())) {
695  switch(kase) {
696  case 0: kase=1; br0 = br;
697  if ( (br->fIOMode<0)) return kStEOF;
698  if (!(br->fIOMode&1)) return kStEOF;
699  iret = br->NextEvent();
700  if (iret) return iret;
701  break;
702  case 1:
703  if ( (br->fIOMode<0)) continue;
704  if (!(br->fIOMode&1)) continue;
705  iret = br->ReadEvent(br0->GetUKey());
706  }
707  nAkt++;
708  }
709 
710  return (nAkt) ? 0:kStEOF;
711 }
712 
713 //_______________________________________________________________________________
714 void StTree::Close(const char* opt)
715 {
716  Clear();
717  fUKey = 2000;
718  TDataSetIter next(this); StBranch *br;
719  while ((br=(StBranch*)next())) { //branch loop
720  br->fIOMode = abs(br->fIOMode);
721  if (br->fIOMode&2) {
722  br->Open();
723  TFile *tfbr = br->GetTFile(); if(!tfbr) continue;
724  if (tfbr->IsWritable()) {
725  TDataSet *par = GetParent(); SetParent(0);
726  StIO::Write(tfbr,fUKey,this);
727  SetParent(par);}
728  }
729  if ((opt && strcmp(opt,"keep")==0)) continue;
730  br->Close();
731  }// end branch loop
732 }
733 
734 //_______________________________________________________________________________
735 StTree *StTree::GetTree(TFile *file, const char *treeName)
736 {
737  StUKey treeKey(treeName,2000);
738  StTree *ret = (StTree*)StIO::Read(file,treeKey);
739  if ((Long_t)ret == -1) return 0;
740  TDataSetIter next(ret);StBranch *br=0;
741  while ((br=(StBranch*)next())) {
742  br->SetIOMode("0");
743  br->fUKey = br->GetName();
744  br->fUKey = 0;
745  }
746  return ret;
747 }
748 
749 //_______________________________________________________________________________
750 void StTree::SetBaseName(const char *baseName,const char *dirname)
751 {
752  const char *dot;
753  fBaseName = gSystem->BaseName(baseName);
754  if (dirname && *dirname) {
755  TString ts(dirname);
756  if (ts[ts.Length()-1]!='/') ts += "/";
757  ts += fBaseName;
758  fBaseName = ts;
759  }
760  dot = strrchr(fBaseName.Data(),'.');
761  if (!dot) return;
762  int fz = (strstr(".fz .fzd .daq",dot)!=0);
763  fBaseName.Remove(dot-fBaseName.Data());
764  if (fz) return;
765  dot = strrchr(fBaseName.Data(),'.');
766  if (!dot) return;
767  if ('0' <=dot[1] && dot[1]<='9') return;
768  fBaseName.Remove(dot-fBaseName.Data());
769 }
770 
771 //_____________________________________________________________________________
772 ClassImp(StFile)
773  StFile::StFile(const char** fileList):StFileI("StFile")
774 {
775  fDS = new TDataSet();
776  fIter = -1; fKeyIter = 0;
777  SetTitle(" nbranches=1 ");
778  if (fileList) AddFile(fileList);
779 }
780 //_____________________________________________________________________________
781  StFile::~StFile()
782 {
783  delete fDS; fDS = 0;
784  fIter = -1;
785  delete fKeyIter; fKeyIter = 0;
786 }
787 //_____________________________________________________________________________
788 Int_t StFile::GetNextBundle()
789 {
790  if (!fDS) return 1;
791  if (fIter>-1 && !fDS->At(fIter)) return 1;
792  return (!fDS->At(++fIter));
793 
794 }
795 //_____________________________________________________________________________
796 Int_t StFile::GetNBundles()
797 {
798  return fDS->GetListSize();
799 }
800 //_____________________________________________________________________________
801 Int_t StFile::GetNFiles()
802 {
803  return fDS->GetListSize();
804 }
805 //_____________________________________________________________________________
806 TDataSet *StFile::GetFileDS(Int_t idx)
807 {
808  TDataSet *fam = fDS->At(fIter);
809  if (!fam) return 0;
810  TDataSet *df = fam->At(idx);
811  if (!df) return 0;
812  SetInfo(df);
813  return df;
814 }
815 //_____________________________________________________________________________
816 const char *StFile::GetFileName(Int_t idx)
817 {
818  if (idx == -1) { idx=0; if (GetNextBundle()) return 0;}
819  TDataSet *df = GetFileDS(idx);
820  if (!df) return 0;
821  return strstr(df->GetTitle(),"file=")+5;
822 }
823 //_____________________________________________________________________________
824 const char *StFile::GetFormat(Int_t idx)
825 {
826  TDataSet *df = GetFileDS(idx);
827  return GetAttr(df,"format=");
828 }
829 //_____________________________________________________________________________
830 const char *StFile::GetCompName(Int_t idx)
831 {
832  TDataSet *df = GetFileDS(idx);
833  return GetAttr(df,"branch=");
834 }
835 //_____________________________________________________________________________
836 Int_t StFile::AddFile(const char **fileList)
837 {
838  const char *file;
839  if (!fileList) return 0;
840  for(int i=0; (file = fileList[i]);i++){
841  if (file) AddFile(file);
842  }
843  return 0;
844 }
845 //_____________________________________________________________________________
846 Int_t StFile::AddFile(const char *file,const char *opt)
847 {
848 
849  //printf("DEBUG:: StFile::AddFile\n");
850 
851  TString tfile,tit,base,famy;
852  if (strpbrk(file,"*\\[]#@")) return AddWild(file,opt);
853  int remove = 0;
854  if (opt && *opt) {
855  TString ts(opt);
856  if (ts.Contains("REMOVE" ,TString::kIgnoreCase)) remove=1;
857  if (ts.Contains("EXCLUDE",TString::kIgnoreCase)) remove=1;
858  }
859 
860  //printf("DEBUG:: StFile::AddFile - ExpandPathName\n");
861  tfile = file; gSystem->ExpandPathName(tfile);
862 
863  //printf("DEBUG:: StFile::AddFile - testing IfExi\n");
864 
865  if (!StIO::IfExi(tfile)) {// file does not exist
866  Warning("AddFile","*** IGNORED *** File %s does NOT exist \n",
867  (const char*)tfile);
868  return kStWarn;}
869 
870  const char* cc = strrchr(tfile,'.');
871  if (!cc || !strstr(".root .daq .dat",cc)){// No extention
872  Warning("AddFile","*** IGNORED *** File %s has wrong extention \n",
873  (const char *)tfile);
874  return kStWarn;}
875 
876  base = gSystem->BaseName(tfile);
877 
878  famy = base;
879  int dot = famy.Last('.');
880  if (dot>0) famy.Replace(dot,999,"");
881  dot = famy.Last('.');
882  if (dot>0) famy.Replace(dot+1,999,"");
883 
884  TDataSet *dsfam = fDS->Find(famy);
885  if (!dsfam && remove) return 0;
886  if (!dsfam) fDS->Add((dsfam = new TObjectSet(famy,0)));
887 
888  TDataSet *twice = dsfam->Find(base);
889  tit = tfile; tit.Replace(0,0," file=");
890  if (twice) {
891  if (!remove) {
892  // compare the full path
893  // if (tit == twice->GetTitle() )
894  Warning("AddFile","File \"%s\" is already added from \"%s\",\n\tThe file \"%s\" is accepted anyway. \n"
895  ,(const char *)base, twice->GetTitle(), (const char *)tit );
896  } else { delete twice; return 0;}
897  }
898  // TDataSet *dss = dsfam->First();
899  //if (dss)
900  // Warning("AddFile","Files %s and %s are from the same family \n",
901  // (const char *)tfile,dss->GetName());
902 
903 
904  TDataSet *ds = new TDataSet(base,dsfam);
905  ds->SetTitle(tit);
906 
907 
908  if (GetDebug()) printf("<%s::AddFile> Added file %s %s\n",
909  ClassName(),ds->GetName(),ds->GetTitle());
910 
911  return 0;
912 }
913 //_____________________________________________________________________________
914 Int_t StFile::AddWild(const char *file,const char *opt )
915 {
916  const char* fullname;
917  TDirIter dirIter(file);
918  while((fullname=dirIter.NextFile())) { AddFile(fullname,opt);}
919 
920  return 0;
921 }
922 //_____________________________________________________________________________
923 Int_t StFile::AddEvent(UInt_t r,UInt_t e)
924 {
925  TObjectSet *dsfam = (TObjectSet*)fDS->Last(); if(!dsfam) return 1;
926  TDataSet *dsfil = dsfam->Last(); if(!dsfil) return 1;
927 
928  TDataSet *dskey = (TDataSet*)dsfam->GetObject();
929  if (!dskey) { dskey = new TDataSet("uklist");dsfam->SetObject(dskey,1);}
930  char cbuf[40];
931  sprintf(cbuf,".%010u.%010u",r,e);
932  new TDataSet(cbuf,dskey);
933  return 0;
934 }
935 //_____________________________________________________________________________
936 StUKey StFile::GetNextEvent()
937 {
938  StUKey uk(kUMAX);
939  if (!fDS) return uk;
940  TDataSet *dsfam = fDS->At(fIter);
941  if (!dsfam) return uk;
942  uk = 0;
943  TDataSet *dskeys = (TDataSet*)dsfam->GetObject();
944  if (!dskeys) return uk;
945  if (!fKeyIter) fKeyIter = new TDataSetIter(dskeys);
946  TDataSet *dskey = fKeyIter->Next();
947  if (!dskey){ uk = kUMAX; delete fKeyIter; fKeyIter=0; return uk;}
948  uk.SetKey(dskey->GetName());
949  return uk;
950 }
951 //_____________________________________________________________________________
952 void StFile::SetInfo(TDataSet *ds)
953 {
954  int i;
955  TFile *tf=0;
956 
957  if (!ds) return;
958  TString tit(ds->GetTitle());
959  Int_t known = 0;
960  if (strstr(tit,"format=")) known += 1;
961  if (strstr(tit,"branch=")) known += 2;
962  if (known==3) return;
963 
964  const char *fname = strstr(ds->GetTitle(),"file=")+5;
965  const char *ext = strrchr(fname,'.');
966  assert(ext);
967 
968  tit.Replace(0,0," branch=NONE ");
969 
970 // DAQ
971  if (strcmp(".daq",ext)==0) {
972  tit.Replace(0,0," format=daq ");
973  known = 3;
974  goto RETN;
975  }
976 
977 // DAT
978  if (strcmp(".dat",ext)==0) {
979  tit.Replace(0,0," format=dat ");
980  known = 3;
981  goto RETN;
982  }
983 
984 // ROOT
985  if (strcmp(".root",ext)==0) {
986  int lfname = strlen(fname);
987  if (strcmp(".MuDst.root",fname+lfname-11)==0){
988  tit.Replace(0,0," format=mudst ");
989  } else {
990  tit.Replace(0,0," format=root " );
991  }
992  known |= 1;
993 // ... now try to know branch name
994  TString bran = fname;
995  bran.ReplaceAll(".root","");
996  i = bran.Last('.');
997  if (i>0) {
998  bran.Replace(0,i+1,"");
999  known = 3;
1000  i = tit.Index("branch=NONE"); assert(i>=0);
1001  tit.Replace(i+7,4,bran);
1002  goto RETN;
1003  }
1004 
1005 
1006 // ... branch name still unknown
1007 
1008  tf = TFile::Open(fname,"READ");
1009  assert(tf && !tf->IsZombie());
1010  TList *kl = gFile->GetListOfKeys();
1011  TIter nextKey(kl);
1012  TKey *ky;
1013  while ((ky = (TKey*)nextKey())) {
1014  if (strcmp("StIOEvent",ky->GetClassName())) continue;
1015  const char *bra=ky->GetName();
1016  if (strstr(bra,"tree")) continue;
1017  if (strstr(bra,"Tree")) continue;
1018  if (strstr(bra,".")==0) continue;
1019  i = tit.Index("branch=NONE"); assert(i>=0);
1020  tit.Replace(i+7,4,bra,strcspn(bra,"."));
1021  break;
1022  } }
1023 
1024 RETN:;
1025  delete tf;
1026  ds->SetTitle(tit);
1027 }
1028 //_____________________________________________________________________________
1029 void StFile::ls(Option_t *opt)
1030 {
1031  if (!fDS) return;
1032  if (opt && *opt ) {lsFull(opt); return;}
1033  TDataSetIter famIter(fDS);
1034  TDataSet *fam,*fil;
1035  int num = 0;
1036  while((fam=famIter.Next())) {
1037  if (!fam->First()) continue;
1038  TDataSetIter filIter(fam);
1039  while((fil=filIter.Next())) {
1040  const char *fname = strstr(fil->GetTitle(),"file=");
1041  if (!fname) continue;
1042  num++;
1043  printf("%3d - %s\n",num,fname+5);
1044  }
1045  }
1046 }
1047 //_____________________________________________________________________________
1048 void StFile::lsFull(Option_t *opt)
1049 {
1050  TList blist;
1051  int ibr=0,i;
1052  Cat *cat;
1053  int savIter = fIter; fIter=-1;
1054  int numFile=0;
1055  TString oldirname("_");
1056  while (!GetNextBundle()) { //Bundle loop
1057  for (int idx=0; idx<999; idx++) { //File loop
1058  const char *fil = GetFileName(idx);
1059  if (!fil) break;
1060  numFile++;
1061  TString dirname = gSystem->DirName(fil);
1062  TString basname = gSystem->BaseName(fil);
1063  TString br(basname);
1064  i = br.Last('.'); if (i<0) continue;
1065  br.Replace(i,999,"");
1066  i = br.Last('.');
1067  if (i<0) { br = "undef";} else { br.Replace(0,i+1,"");};
1068 
1069  if (oldirname != dirname) {
1070  printf("\nDirName =%s\n\n",dirname.Data());
1071  oldirname.Replace(0,999,dirname);}
1072 
1073  cat = (Cat*)(blist.FindObject(br));
1074  if (!cat) { cat = new Cat(); cat->SetName(br); blist.Add(cat);}
1075  cat->fNFiles++;
1076 
1077  TFile *tf = 0;
1078  if (opt && opt[0]=='r') tf = StIO::Open(fil,"update");
1079  if (!tf) tf = StIO::Open(fil,"read" );
1080  if (!tf) continue;
1081 
1082  TList *keys = tf->GetListOfKeys();
1083  int nkeys=0,nreks=0;
1084  double dsize=0;
1085 
1086  TIter nextk(keys);
1087  TKey *key;
1088  while ((key=(TKey*)nextk())) { //Key loop
1089  TString keyname(key->GetName());
1090  i = keyname.First('.');
1091  if (i>0) keyname.Replace(i,9999,"");
1092  keyname.ReplaceAll("Branch","");
1093  cat = (Cat*)(blist.FindObject(keyname));
1094  if (!cat) {
1095  cat = new Cat();
1096  cat->SetName(keyname);
1097  blist.Add(cat);
1098  }
1099  nkeys++;
1100  cat->fNKeys++;
1101  if (keyname==br) { nreks++; cat->fNRecs++;};
1102  dsize += key->GetObjlen();
1103  cat->fSize += key->GetObjlen();
1104  TString clasname(key->GetClassName());
1105  cat = (Cat*)(blist.FindObject(clasname));
1106  if (!cat) {
1107  cat = new Cat();
1108  cat->SetName(clasname);
1109  blist.Add(cat);
1110  }
1111  cat->fNKeys++;
1112  cat->fSize += key->GetObjlen();
1113 
1114  }// End key loop
1115  dsize/=1000000.;
1116  printf("%4d BR=%-7s NK=%-4d NR=%-4d SZ=%8.2fM File= %s\n",
1117  numFile,br.Data(),nkeys,nreks,dsize,basname.Data());
1118  delete tf;
1119 
1120 // printf("%4d %s\n",numFile,fil);
1121  } //*end File loop*/
1122  }//*end Bundle loop*/
1123 
1124  printf("\n\n In Total ==================================================\n");
1125  blist.Sort();
1126  TIter nextBr(&blist);
1127  ibr = 0;
1128  while ( (cat = (Cat*)nextBr())){
1129  ibr++;
1130  printf("%4d BR=%-10s NK=%-4d NR=%-4d SZ=%8.2fM NFiles %4d\n",
1131  ibr,
1132  cat->GetName(),
1133  cat->fNKeys,
1134  cat->fNRecs,
1135  cat->fSize*1.e-6,
1136  cat->fNFiles);
1137  }
1138  blist.Delete();
1139  fIter = savIter;
1140 }
1141 //_____________________________________________________________________________
1142 const char *StFile::GetAttr(TDataSet *ds,const char *att)
1143 {
1144  static TString brName;
1145  if (!ds) return 0;
1146  SetInfo(ds);
1147  const char *bn = strstr(ds->GetTitle(),att);
1148  if (!bn) return 0;
1149  bn += strlen(att);
1150  int n = strcspn(bn," ");
1151  brName.Replace(0,999,bn,n);
1152  return (const char*)brName;
1153 }
TString fFile
1=ReadOnly; 2=WriteOnly; 1+2=Update;0=do nothing
Definition: StTree.h:75
char fIOMode
Current RunEvent number.
Definition: StTree.h:74
virtual TDataSet * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TDataSet.cxx:403
Definition: FJcore.h:367
Definition: StTree.cxx:45
Definition: StTree.h:125
virtual TDataSet * Next(TDataSet::EDataSetPass mode=TDataSet::kContinue)
virtual void Delete(Option_t *opt="")
Definition: TDataSet.cxx:320
virtual TDataSet * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TDataSet.cxx:437
virtual void SetObject(TObject *obj)
The depricated method (left here for the sake of the backward compatibility)
Definition: TObjectSet.h:59
ULong_t fHandle
debug level
Definition: StTree.h:79
virtual TDataSet * Next() const
Definition: TDataSet.cxx:447
Definition: Stypes.h:43
virtual TObject * GetObject() const
The depricated method (left here for the sake of the backward compatibility)
Definition: TDataSet.cxx:428
Definition: Stypes.h:42
virtual void SetParent(TDataSet *parent=0)
Definition: TDataSet.cxx:784
Definition: StFileI.h:13
Definition: StTree.h:84
virtual TObject * GetObject() const
The depricated method (left here for the sake of the backward compatibility)
Definition: TObjectSet.h:56
Definition: Stypes.h:44
virtual TDataSet * Find(const char *path) const
Definition: TDataSet.cxx:362