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 } 1154