11 #include "TRFIOFile.h"
14 void DummyErrorHandlerFunc(
int , Bool_t ,
const char *,
const char *){;}
19 const char* TFOPT[9] = {
"0",
"READ",
"RECREATE",
"UPDATE",
20 "0",
"READ",
"RECREATE",
"UPDATE",0};
21 const char RWU[] =
"0rwu0rnu0rcu";
24 Int_t StIO::fgDebug = 0;
26 static inline Int_t IntOMode(
char ciomode)
28 char *c=(
char *)strchr(RWU,tolower(ciomode));
29 return (c) ? (c-RWU)&3 : 0;
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);
45 class Cat :
public TNamed {
47 Cat(){fNGeant=0;fNKeys=0;fNRecs=0;fSize=0;fNFiles=0;};
58 void StIOEvent::Browse(TBrowser *b)
60 if (b && fObj && (Long_t)fObj != (-1)) fObj->Browse(b);
63 void StIOEvent::Streamer(TBuffer &R__b)
67 if (R__b.IsReading()) {
68 Version_t R__v = R__b.ReadVersion();
if (R__v) { }
69 TObject::Streamer(R__b);
72 R__b.WriteVersion(StIOEvent::IsA());
73 TObject::Streamer(R__b);
80 Int_t StIO::Write(TFile *file,
const StUKey &ukey, TObject *obj)
86 event.fObj = obj;
event.SetUniqueID(ukey.GetSum());
88 TDirectory *bakdir = gDirectory; file->cd();
90 event.Write(ukey.GetKey(),TObject::kOverwrite|TObject::kSingleKey);
91 if (gFile) gFile->Flush();
97 TObject *StIO::Read(TFile *file,
const char *name)
103 TFile *bakfile = gFile; TDirectory *bakdir = gDirectory; file->cd();
105 if (!gFile) { printf(
"<StIO::Read> No file open \n");
goto RETURN;}
108 key = (TKey*)gDirectory->GetListOfKeys()->At(0);
109 if (strcmp(
".StreamerList",key->GetName())==0)
110 key = (TKey*)gDirectory->GetListOfKeys()->At(1);
112 else key = (TKey*)gDirectory->GetListOfKeys()->FindObject(name);
115 if(fgDebug) printf(
"<StIO::Read> Key %s not found\n",name);
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; }
123 toread = key->ReadObj();
if (!toread) toread = (TObject*)(-1);
127 gDirectory=bakdir;
return toread;
130 TObject *StIO::Read(TFile *file,
const StUKey &ukey)
134 retn = Read(file,ukey.GetKey());
136 if (retn == (TObject*)(-1))
return retn;
137 if (retn->IsA()!=StIOEvent::Class())
return retn;
140 assert( !retn || retn==(TObject*)(-1) || event->GetUniqueID()==ukey.GetSum());
145 Int_t StIO::GetNextKey(TFile *file,
StUKey &ukey,ULong_t &handle)
147 TObjLink *lnk; TList *lk;
const char *kname; TObject *obj;
151 TString tk = ukey.GetKey(); ukey = kUMAX;
152 const char* prevkey = (
const char*)tk;
153 int lname = strlen(ukey.GetName())+1;
155 lk = file->GetListOfKeys();
if(!lk)
return 1;
156 if (!lk->TestBit(kSorted)) {lk->Sort(); lk->SetBit(kSorted);handle = 0;}
164 lnk = (TObjLink*)handle;
166 obj = lnk->GetObject();
167 if (strcmp(prevkey,obj->GetName())>0) lnk = lk->FirstLink();
169 lnk = lk->FirstLink();
173 obj = lnk->GetObject();
174 kname = obj->GetName();
175 if (strcmp(prevkey, kname)<0)
break;
179 if (strncmp(prevkey,kname,lname)) lnk = 0;
182 handle = (ULong_t)lnk;
186 TObject *StIO::ReadNext(TFile *file,
StUKey &ukey, ULong_t &handle)
188 if(GetNextKey(file,ukey,handle))
return 0;;
189 return Read(file,ukey);
192 TString StIO::RFIOName(
const char *name)
196 TList *rfiomap = (TList *)gROOT->GetListOfSpecials()->FindObject(
".rfiomap");
197 if (file.Contains(
".daq")) rfiomap = 0;
200 while ((tn = (TNamed*)next())) {
201 int n = strlen(tn->GetName());
203 if (strncmp(file,tn->GetName(),n))
continue;
204 file.Replace(0,0,tn->GetTitle());
211 TFile *StIO::Open(
const char *name, Option_t *option,
const char *title,Int_t compress)
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;
225 Int_t StIO::IfExi(
const char *name)
227 TString file = (name);
230 gSystem->ExpandPathName(file);
233 ErrorHandlerFunc_t dummy = &DummyErrorHandlerFunc;
234 ErrorHandlerFunc_t curre = SetErrorHandler(dummy);
239 if (!gSystem->AccessPathName(file)){
240 SetErrorHandler(curre);
246 int l = file.Length();
247 if (file(l-5,5)!=
".root"){
248 SetErrorHandler(curre);
249 return !gSystem->AccessPathName(file);
256 TFile *tf = TFile::Open(file);
258 SetErrorHandler(curre);
261 int z = (!tf || tf->IsZombie());
275 SetTitle(
".StBranch");
276 fNEvents=0;fUKey=name;fUKey=0;fIOMode=0;fTFile=0;fDebug=0;fHandle=0;
280 StBranch::~StBranch()
286 void StBranch::SetOption(Option_t *opt)
288 if (opt) fOption = opt;
292 void StBranch::SetIOMode(Option_t *iomode)
295 if (!iomode || !iomode[0])
return;
296 fIOMode = ::IntOMode(iomode[0]);
300 Option_t *StBranch::GetIOMode()
302 IOMODE[0]=0;
if (
fIOMode>0) IOMODE[0] = RWU[int(
fIOMode)];
return IOMODE;
306 Int_t StBranch::SetFile(
const char *file,
const char *mode,
int insist)
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);
316 Int_t StBranch::UpdateFile(
const char *file)
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);
327 if (strncmp(
".none ",GetFile(),6)==0) {
329 TString ts(GetFile()); ts.Remove(0,6); SetFile(ts);
332 dir[1] = gSystem->DirName (GetFile());
333 bas[1] = gSystem->BaseName(GetFile());
335 if (bas[0] == bas[1] || bas[0].Contains(nam)) SetIOMode(
"r");
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)) {
343 printf(
"<StBranch::UpdateFile> Branch=%s file %s\n",GetName(),newFile);
351 Int_t StBranch::SetTFile(TFile *tfile)
353 if (!tfile)
return 0;
354 if (fTFile==tfile)
return 0;
358 SetFile(tfile->GetName());
364 void StBranch::Close(
const char *)
369 if (strncmp(
".none",GetFile(),4)==0)
return;
372 TString ts(tf->GetTitle());
373 int idx = ts.Index(
"StBranch=Y");
375 ts.Replace(idx+9,1,
"");
377 if (ts.Contains(
"StBranch=Y"))
return;
379 printf(
"** <StBranch::Close> Branch=%s \tFile=%s \tClosed **\n"
380 ,GetName(),(
const char*)
fFile);
384 ts.Replace(0,0,
".none ");
385 SetFile((
const char*)ts);
388 const char *StBranch::GetFile()
392 if (!
fFile.IsNull()) kase = 2;
393 if (kase &&
fFile[
fFile.Length()-1]==
'/') kase = 1;
399 const char* base = tree->GetBaseName();
400 if (base) {
fFile.Insert(0,
".");
fFile.Insert(0,base);}}
401 if (kase==1)
fFile.Insert(0,dir);
404 return (
const char*)
fFile;
409 Int_t StBranch::Open()
412 if (fTFile)
return 0;
413 if (strncmp(
".none",GetFile(),4)==0)
return 1;
418 Int_t StBranch::WriteEvent(
const StUKey &ukey)
423 fUKey.Update(ukey,GetName());
425 if (!fList->First())
return kStWarn;
430 SetParAll(0,
this,&savList);
431 if (IsOption(
"const")) {
432 StUKey uk(fUKey); uk = (UInt_t)(-2);
433 iret = StIO::Write(fTFile,uk, fList);
436 iret = StIO::Write(fTFile,fUKey,fList);
444 Int_t StBranch::GetEvent(Int_t mode)
449 Delete();
if (fList)
delete fList; fList=0;
452 if (IsOption(
"const")) {
453 StUKey uk(fUKey); uk = (UInt_t)(-2);
457 obj = StIO::ReadNext(fTFile,fUKey,
fHandle);
460 obj = StIO::Read (fTFile,fUKey);
463 if (obj == 0)
return kStEOF;
464 if (obj == (TObject*)(-1))
return kStErr;
467 SetParAll(
this,
this,0);
472 Int_t StBranch::ReadEvent(
const StUKey &ukey)
476 fUKey.Update(ukey,GetName());
480 Int_t StBranch::NextEvent()
489 Int_t StBranch::NextEvent (
StUKey &ukey)
494 fUKey.Update(ukey,GetName());
495 int iret = GetEvent(1);
504 while ((son=next())) {
505 p = son->GetParent();
509 savList->AddFirst(son); savList->AddFirst(p);
510 SetParAll(son,son,savList);
515 void StBranch::SetParAll(TList *savList)
520 savList->Remove(par);
522 savList->Remove(son);
527 void StBranch::OpenTFile()
531 TFile *tf= gROOT->GetFile(GetFile());
534 fTFile = StIO::Open(GetFile(),TFOPT[
int(
fIOMode)],GetName());
538 Error(
"OpenTFile",
"File %s NOT OPENED ***\n",GetFile());
539 Error(
"OpenTFile",
"Branch %s desactivated ***\n",GetName());
540 delete fTFile; fTFile=0; SetIOMode(
"0");
542 TString ts(fTFile->GetTitle());
543 if (ts.Contains(
"StBranch="))
544 { ts.ReplaceAll(
"StBranch=",
"StBranch=Y");}
546 { ts +=
" StBranch=Y";}
547 fTFile->SetTitle(ts);
550 printf(
"** <StBranch::Open> Branch=%s \tMode=%s \tFile=%s \tOpened **\n"
556 void StBranch::Clear(Option_t *)
575 void StTree::SetIOMode(Option_t *iomode)
577 StBranch::SetIOMode(iomode);
579 while ((br=(
StBranch*)next())) { br->SetIOMode(iomode);}
582 Int_t StTree::SetFile(
const char *file,
const char *mode,
int )
584 if (mode && *mode) StBranch::SetIOMode(mode);
585 if (!file || !*file)
return 0;
599 void StTree::Clear(Option_t*)
602 while ((br=(
StBranch*)next())) { br->Clear();}
610 if (brA->GetIOMode()[0]==
'0')
continue;
611 if (brA->GetTFile())
continue;
617 Int_t StTree::UpdateFile(
const char *file)
620 while ((br=(
StBranch*)next())) br->UpdateFile(file);
625 Int_t StTree::WriteEvent(
const StUKey &ukey)
627 fUKey.Update(ukey,GetName()); Open();
629 while ((br=(
StBranch*)next())) br->WriteEvent(fUKey);
635 Int_t StTree::ReadEvent(
const StUKey &ukey)
638 fUKey.Update(ukey,GetName()); Open();
641 if ( (br->
fIOMode<0))
continue;
642 if (!(br->
fIOMode&1))
continue;
643 iret=br->ReadEvent(fUKey);
651 Int_t StTree::NextKey()
653 if (Open())
return kStEOF;
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;
666 if (tryKey.Compare(minKey)<0) minKey=tryKey;
669 return minKey.EOK() ?
kStEOF:0;
672 Int_t StTree::Skip(
int nskip)
674 for (; nskip; nskip--)
683 Int_t StTree::NextEvent(
StUKey &ukey)
685 fUKey.Update(ukey,GetName());
int iret=NextEvent(); ukey.Update(fUKey);
return iret;
688 Int_t StTree::NextEvent()
696 case 0: kase=1; br0 = br;
699 iret = br->NextEvent();
700 if (iret)
return iret;
703 if ( (br->
fIOMode<0))
continue;
704 if (!(br->
fIOMode&1))
continue;
705 iret = br->ReadEvent(br0->GetUKey());
714 void StTree::Close(
const char* opt)
723 TFile *tfbr = br->GetTFile();
if(!tfbr)
continue;
724 if (tfbr->IsWritable()) {
726 StIO::Write(tfbr,fUKey,
this);
729 if ((opt && strcmp(opt,
"keep")==0))
continue;
735 StTree *StTree::GetTree(TFile *file,
const char *treeName)
737 StUKey treeKey(treeName,2000);
739 if ((Long_t)ret == -1)
return 0;
743 br->fUKey = br->GetName();
750 void StTree::SetBaseName(
const char *baseName,
const char *dirname)
753 fBaseName = gSystem->BaseName(baseName);
754 if (dirname && *dirname) {
756 if (ts[ts.Length()-1]!=
'/') ts +=
"/";
760 dot = strrchr(fBaseName.Data(),
'.');
762 int fz = (strstr(
".fz .fzd .daq",dot)!=0);
763 fBaseName.Remove(dot-fBaseName.Data());
765 dot = strrchr(fBaseName.Data(),
'.');
767 if (
'0' <=dot[1] && dot[1]<=
'9')
return;
768 fBaseName.Remove(dot-fBaseName.Data());
776 fIter = -1; fKeyIter = 0;
777 SetTitle(
" nbranches=1 ");
778 if (fileList) AddFile(fileList);
785 delete fKeyIter; fKeyIter = 0;
788 Int_t StFile::GetNextBundle()
791 if (fIter>-1 && !fDS->At(fIter))
return 1;
792 return (!fDS->At(++fIter));
796 Int_t StFile::GetNBundles()
798 return fDS->GetListSize();
801 Int_t StFile::GetNFiles()
803 return fDS->GetListSize();
806 TDataSet *StFile::GetFileDS(Int_t idx)
816 const char *StFile::GetFileName(Int_t idx)
818 if (idx == -1) { idx=0;
if (GetNextBundle())
return 0;}
821 return strstr(df->GetTitle(),
"file=")+5;
824 const char *StFile::GetFormat(Int_t idx)
827 return GetAttr(df,
"format=");
830 const char *StFile::GetCompName(Int_t idx)
833 return GetAttr(df,
"branch=");
836 Int_t StFile::AddFile(
const char **fileList)
839 if (!fileList)
return 0;
840 for(
int i=0; (file = fileList[i]);i++){
841 if (file) AddFile(file);
846 Int_t StFile::AddFile(
const char *file,
const char *opt)
851 TString tfile,tit,base,famy;
852 if (strpbrk(file,
"*\\[]#@"))
return AddWild(file,opt);
856 if (ts.Contains(
"REMOVE" ,TString::kIgnoreCase))
remove=1;
857 if (ts.Contains(
"EXCLUDE",TString::kIgnoreCase))
remove=1;
861 tfile = file; gSystem->ExpandPathName(tfile);
865 if (!StIO::IfExi(tfile)) {
866 Warning(
"AddFile",
"*** IGNORED *** File %s does NOT exist \n",
870 const char* cc = strrchr(tfile,
'.');
871 if (!cc || !strstr(
".root .daq .dat",cc)){
872 Warning(
"AddFile",
"*** IGNORED *** File %s has wrong extention \n",
873 (
const char *)tfile);
876 base = gSystem->BaseName(tfile);
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,
"");
885 if (!dsfam &&
remove)
return 0;
886 if (!dsfam) fDS->Add((dsfam =
new TObjectSet(famy,0)));
889 tit = tfile; tit.Replace(0,0,
" file=");
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;}
908 if (GetDebug()) printf(
"<%s::AddFile> Added file %s %s\n",
909 ClassName(),ds->GetName(),ds->GetTitle());
914 Int_t StFile::AddWild(
const char *file,
const char *opt )
916 const char* fullname;
918 while((fullname=dirIter.NextFile())) { AddFile(fullname,opt);}
923 Int_t StFile::AddEvent(UInt_t r,UInt_t e)
931 sprintf(cbuf,
".%010u.%010u",r,e);
936 StUKey StFile::GetNextEvent()
941 if (!dsfam)
return uk;
944 if (!dskeys)
return uk;
947 if (!dskey){ uk = kUMAX;
delete fKeyIter; fKeyIter=0;
return uk;}
948 uk.SetKey(dskey->GetName());
958 TString tit(ds->GetTitle());
960 if (strstr(tit,
"format=")) known += 1;
961 if (strstr(tit,
"branch=")) known += 2;
962 if (known==3)
return;
964 const char *fname = strstr(ds->GetTitle(),
"file=")+5;
965 const char *ext = strrchr(fname,
'.');
968 tit.Replace(0,0,
" branch=NONE ");
971 if (strcmp(
".daq",ext)==0) {
972 tit.Replace(0,0,
" format=daq ");
978 if (strcmp(
".dat",ext)==0) {
979 tit.Replace(0,0,
" format=dat ");
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 ");
990 tit.Replace(0,0,
" format=root " );
994 TString bran = fname;
995 bran.ReplaceAll(
".root",
"");
998 bran.Replace(0,i+1,
"");
1000 i = tit.Index(
"branch=NONE"); assert(i>=0);
1001 tit.Replace(i+7,4,bran);
1008 tf = TFile::Open(fname,
"READ");
1009 assert(tf && !tf->IsZombie());
1010 TList *kl = gFile->GetListOfKeys();
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,
"."));
1029 void StFile::ls(Option_t *opt)
1032 if (opt && *opt ) {lsFull(opt);
return;}
1036 while((fam=famIter.
Next())) {
1037 if (!fam->
First())
continue;
1039 while((fil=filIter.
Next())) {
1040 const char *fname = strstr(fil->GetTitle(),
"file=");
1041 if (!fname)
continue;
1043 printf(
"%3d - %s\n",num,fname+5);
1048 void StFile::lsFull(Option_t *opt)
1053 int savIter = fIter; fIter=-1;
1055 TString oldirname(
"_");
1056 while (!GetNextBundle()) {
1057 for (
int idx=0; idx<999; idx++) {
1058 const char *fil = GetFileName(idx);
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,
"");
1067 if (i<0) { br =
"undef";}
else { br.Replace(0,i+1,
"");};
1069 if (oldirname != dirname) {
1070 printf(
"\nDirName =%s\n\n",dirname.Data());
1071 oldirname.Replace(0,999,dirname);}
1073 cat = (
Cat*)(blist.FindObject(br));
1074 if (!cat) { cat =
new Cat(); cat->SetName(br); blist.Add(cat);}
1078 if (opt && opt[0]==
'r') tf = StIO::Open(fil,
"update");
1079 if (!tf) tf = StIO::Open(fil,
"read" );
1082 TList *keys = tf->GetListOfKeys();
1083 int nkeys=0,nreks=0;
1088 while ((key=(TKey*)nextk())) {
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));
1096 cat->SetName(keyname);
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));
1108 cat->SetName(clasname);
1112 cat->fSize += key->GetObjlen();
1116 printf(
"%4d BR=%-7s NK=%-4d NR=%-4d SZ=%8.2fM File= %s\n",
1117 numFile,br.Data(),nkeys,nreks,dsize,basname.Data());
1124 printf(
"\n\n In Total ==================================================\n");
1126 TIter nextBr(&blist);
1128 while ( (cat = (
Cat*)nextBr())){
1130 printf(
"%4d BR=%-10s NK=%-4d NR=%-4d SZ=%8.2fM NFiles %4d\n",
1142 const char *StFile::GetAttr(
TDataSet *ds,
const char *att)
1144 static TString brName;
1147 const char *bn = strstr(ds->GetTitle(),att);
1150 int n = strcspn(bn,
" ");
1151 brName.Replace(0,999,bn,n);
1152 return (
const char*)brName;
TString fFile
1=ReadOnly; 2=WriteOnly; 1+2=Update;0=do nothing
char fIOMode
Current RunEvent number.
virtual TDataSet * First() const
Return the first object in the list. Returns 0 when list is empty.
virtual TDataSet * Next(TDataSet::EDataSetPass mode=TDataSet::kContinue)
virtual void Delete(Option_t *opt="")
virtual TDataSet * Last() const
Return the last object in the list. Returns 0 when list is empty.
virtual void SetObject(TObject *obj)
The depricated method (left here for the sake of the backward compatibility)
ULong_t fHandle
debug level
virtual TDataSet * Next() const
virtual TObject * GetObject() const
The depricated method (left here for the sake of the backward compatibility)
virtual void SetParent(TDataSet *parent=0)
virtual TObject * GetObject() const
The depricated method (left here for the sake of the backward compatibility)
virtual TDataSet * Find(const char *path) const