// $Id$ //----------------------------------------------------------------------- // The GSI Online Offline Object Oriented (Go4) Project // Experiment Data Processing at EE department, GSI //----------------------------------------------------------------------- // Copyright (C) 2000- GSI Helmholtzzentrum für Schwerionenforschung GmbH // Planckstr. 1, 64291 Darmstadt, Germany // Contact: http://go4.gsi.de //----------------------------------------------------------------------- // This software can be used under the license agreements as stated // in Go4License.txt file which is part of the distribution. //----------------------------------------------------------------------- #include "TGo4MbsFile.h" #include "Riostream.h" #include "Riosfwd.h" #include "TSystem.h" #include "TROOT.h" #include "string.h" #include "TGo4Log.h" #include "TGo4MbsFileParameter.h" #include "TGo4EventErrorException.h" #include "TGo4EventTimeoutException.h" #include "TGo4EventEndException.h" #include "TGo4AnalysisImp.h" const char* TGo4MbsFile::fgcNOTAGFILE="GO4-NOLMDTAG"; const char* TGo4MbsFile::fgcWILDFILE=".go4inputs"; const char* TGo4MbsFile::fgcLMDSUF=".lmd"; const char* TGo4MbsFile::fgcFILELISTSUF=".lml"; TGo4MbsFile::TGo4MbsFile() : TGo4MbsSource(), fbMultipleMode(kFALSE), fbWildcardMode(kFALSE), fxMultiFile(0), fbFileOpen(kFALSE) { TRACE((15,"TGo4MbsFile::TGo4MbsFile()",__LINE__, __FILE__)); } TGo4MbsFile::TGo4MbsFile(const char* name) : TGo4MbsSource(name , GETEVT__FILE), fbMultipleMode(kFALSE), fbWildcardMode(kFALSE), fxMultiFile(0), fbFileOpen(kFALSE) { TRACE((15,"TGo4MbsFile::TGo4MbsFile(const char*)",__LINE__, __FILE__)); TGo4Log::Debug(" New Event Source MbsFile %s: ",name); fxTagFile=fgcNOTAGFILE; Open(); } TGo4MbsFile::TGo4MbsFile(TGo4MbsFileParameter* par) : TGo4MbsSource(par , GETEVT__FILE), fbMultipleMode(kFALSE), fbWildcardMode(kFALSE), fxMultiFile(0), fbFileOpen(kFALSE) { TRACE((15,"TGo4MbsFile::TGo4MbsFile(TGo4MbsFileParameter**)",__LINE__, __FILE__)); TGo4Log::Debug(" New Event Source MbsFile %s: ",GetName()); if(par!=0) fxTagFile=par->GetTagName(); Open(); } TGo4MbsFile::~TGo4MbsFile() { TRACE((15,"TGo4MbsFile::~TGo4MbsFile()",__LINE__, __FILE__)); Close(); } Int_t TGo4MbsFile::NextEvent() { TRACE((12,"TGo4MbsFile::NextEvent()",__LINE__, __FILE__)); try{ Int_t skip=0; // test if we had reached the last event: if(fuStopEvent!=0 && fuEventCounter>=fuStopEvent) { SetEventStatus(GETEVT__NOMORE); } else { if(fbFirstEvent) { if(fuStartEvent>0) { // we want to work with "real" event number for first event skip=(Int_t) fuStartEvent-1; if(skip) fuEventCounter++; // need to correct for init value of event counter below! } else { skip=0; } fbFirstEvent=kFALSE; } else { skip= (Int_t) fuEventInterval; } void* evptr=&fxEvent; // some new compilers may warn if we directly dereference member variable in function argument Int_t status=f_evt_get_tagnext( fxInputChannel, skip, (Int_t **) evptr); if(skip) fuEventCounter+=skip; else fuEventCounter++; SetEventStatus(status); } if(GetEventStatus()!=0) { char buffer[TGo4EventSource::fguTXTLEN]; f_evt_error(GetEventStatus(),buffer,1); // provide text message for later output SetErrMess(buffer); } if(GetEventStatus() ==GETEVT__NOMORE) throw TGo4EventEndException(this); else if(GetEventStatus()!=0) throw TGo4EventErrorException(this); else ; return GetEventStatus(); } // try catch(TGo4EventEndException& ex) { if(fbMultipleMode) { ex.Handle(); // display message // catch here the end of file case only // try to open next file in list: while(NextFile()<0){;} //skip filenames with open error until a file // in the list opens properly (retval==0) SetErrMess(Form("\n Eventsource Open file: %s tagfile:%s first:%lu last:%lu delta:%lu", GetCurrentFileName(),GetCurrentTagName(), fuStartEvent,fuStopEvent, fuEventInterval)); NewFileAction(); throw TGo4EventErrorException(this,0); // priority 0 means do not stop analysis // we (mis-)use an error exception with no stop to // skip the processing of the previous event in the // subsequent analysis for a second time // note that NextFile() throws an exception itself // if list of files is at end } else { throw; // normal end of input for one file } } } Int_t TGo4MbsFile::Close() { TRACE((12,"TGo4MbsFile::Close()",__LINE__, __FILE__)); if(!fbIsOpen) return -1; //cout << "Close of TGo4MbsFile"<< endl; Int_t rev = GetCreateStatus(); // close connection/file if(CloseFile() == GETEVT__SUCCESS) fbIsOpen = kFALSE; if(fxMultiFile) { delete fxMultiFile; fxMultiFile=0; } if(fbWildcardMode) gSystem->Exec(Form("rm %s",fxMultiName.Data())); return rev; } Int_t TGo4MbsFile::Open() { TRACE((12,"TGo4MbsFile::Open()",__LINE__, __FILE__)); // if(fbIsOpen) return -1; const char* multiname=0; // evaluate wildcard input: if(*GetName()=='@') // old style: filelist name starts with @ { //cout <<"Multiple mode with @" << endl; // name indicates steering file fbMultipleMode=kTRUE; fbWildcardMode=kFALSE; multiname=strstr(GetName(),"@"); multiname++; // skip at character fxMultiName=multiname; } else if(fName.EndsWith(fgcFILELISTSUF))// new style: list mode list { //cout <<"Multiple mode for .lml " << endl; fbMultipleMode=kTRUE; fbWildcardMode=kFALSE; fxMultiName=GetName(); } else if(strstr(GetName(),"*") || strstr(GetName(),"?")) { //cout <<"Wildcard mode" << endl; // name indicates wildcard expression fbWildcardMode=kTRUE; fbMultipleMode=kTRUE; multiname = fgcWILDFILE; // evaluate expression here and create input file: TString wildexpr; if(!strstr(GetName(),fgcLMDSUF)) wildexpr = Form("%s%s",GetName(),fgcLMDSUF); else wildexpr = GetName(); const char* homedir = gSystem->Getenv("HOME"); fxMultiName = Form("%s/%s", homedir, multiname); TString command = Form("ls -1 %s > %s",wildexpr.Data(), fxMultiName.Data()); //cout <<"Executing command "<Exec(command.Data()); // write input file from wildcard expression } else { // name is name of single input lmd file //cout <<"Simple mode" << endl; fbMultipleMode=kFALSE; fbWildcardMode=kFALSE; } ///////////////////////////// // now treat different input modes: if(fbMultipleMode) { //cout <<"Opening multiple file "<Message(1,Form( "Eventsource TGo4MbsFile:%s \n Eventsource Open file: %s tag:%s first:%lu last:%lu delta:%lu", GetName(),GetCurrentFileName(),GetCurrentTagName(), fuStartEvent,fuStopEvent, fuEventInterval)); } else { //cout <<"Open in single mode" << endl; if(NextFile()<0) fbIsOpen=kFALSE; // only for single mode the // error result of first NextFile() // will indicate that open failed else { fbIsOpen=kTRUE; TGo4Log::Info("TGo4MbsFile: Open file %s", GetCurrentFileName()); } } // note that open flag indicates state of complete mbssource, // not the state of one single file in the multiple file list. //////////////////// provide dummy event for testing //int fiNumSub=2; // number of subevents, fix //int fiNumDat=16; // maximum allocated data longs per subevent //int fiDLen=(sizeof(s_ve10_1)-sizeof(s_evhe)+fiNumSub*(sizeof(s_ves10_1)+fiNumDat*sizeof(Int_t))) / 2 ; //fxEvent= (s_ve10_1*) new Short_t[fiDLen+sizeof(s_evhe)]; ; //fxEvent->l_dlen=fiDLen; //fxEvent->i_subtype=1; //fxEvent->i_type=10; //fxEvent->l_count=0; //s_ves10_1* subevt=(s_ves10_1*) (void*) (fxEvent+1); //for(Int_t i=0;ifiNumDat) l_val_num=fiNumDat; // never exceed allocated field // // setup subevent header: // subevt->i_type=10; // subevt->i_subtype=1; // subevt->h_subcrate=i+1; // set subevent id numbers: // subevt->h_control=2*i; // subevt->i_procid=4*i; // //subevt->l_dlen=fiNumDat*2+2; // length in short units + 2 // subevt->l_dlen=l_val_num*2+2; // subevent length in short units + 2 // fxEvent->l_dlen+=(l_val_num*sizeof(Int_t)) / 2 ; // add datalength to total length in shorts // // //cout <<"\t dlen="<l_dlen << endl; // Int_t* subdata= (Int_t*) (subevt+1); // data starts after subevt // //cout <<"\t data="<l_dlen+=(sizeof(s_ve10_1)-sizeof(s_evhe)+fiNumSub*sizeof(s_ves10_1))/2; //// finally, add length of headers to totalevent length /////// end dummy event return 0; } Int_t TGo4MbsFile::NextFile() { CloseFile(); fuEventCounter=0; // read next name from namesfile if(fbMultipleMode && fxMultiFile!=0) { char nextline[TGo4EventSource::fguTXTLEN]; char nextfile[TGo4EventSource::fguTXTLEN]; char nexttag[TGo4EventSource::fguTXTLEN]; char* command=0; char* rem1=0; char* rem2=0; Int_t convs=0; //static int cnt=0; do { fxMultiFile->getline(nextline,TGo4EventSource::fguTXTLEN, '\n' ); // read whole line //cout <<"read line "<rdstate()==ios::eofbit) if(fxMultiFile->eof() || !fxMultiFile->good()) { // reached last filename, or read error? SetCreateStatus(GETEVT__NOFILE); SetErrMess(Form("End of multiple input namesfile %s", fxMultiName.Data())); //throw TGo4EventErrorException(this,3); throw TGo4EventEndException(this); } rem1=strstr(nextline,"!"); rem2=strstr(nextline,"#"); command=strstr(nextline,"@"); if(command!=0 && !(rem1!=0 && rem1Message(1,"TGo4MbsFile list:%s-- executing command: %s ", GetName(), command); //TGo4Log::Info("TGo4MbsFile list:%s-- executing command: %s ", GetName(), command); gROOT->ProcessLineSync(command); } } while(strlen(nextline)==0 || rem1!=0 || rem2!=0 || command!=0); // skip any comments and empty lines, and continue after macro execution convs=sscanf(nextline,"%s %s %lu %lu %lu",nextfile,nexttag, &fuStartEvent, &fuStopEvent, &fuEventInterval); if(convs<2) { // line contained not all parameters, reset remaining fuStartEvent=0; fuStopEvent=0; fuEventInterval=0; strncpy(nexttag, TGo4MbsFile::fgcNOTAGFILE, TGo4EventSource::fguTXTLEN); } // cout <<"Read next filename "<(tagfile) , const_cast( GetCurrentFileName() ), (Char_t**) headptr, 0); SetCreateStatus(status); if(GetCreateStatus() !=GETEVT__SUCCESS) { char buffer[TGo4EventSource::fguTXTLEN]; f_evt_error(GetCreateStatus(),buffer,1); // provide text message for later output SetErrMess(buffer); fbFileOpen=kFALSE; throw TGo4EventErrorException(this); } else { fbFileOpen=kTRUE; fbFirstEvent=kTRUE; TGo4Log::Debug(" Mbs File -- opened %s ", GetName()); } return status; } Int_t TGo4MbsFile::CloseFile() { if(!fbFileOpen) return -1; Int_t rev=f_evt_get_tagclose(fxInputChannel); if(rev == GETEVT__SUCCESS) fbFileOpen=kFALSE; return rev; } Int_t TGo4MbsFile::NewFileAction(Bool_t dosave) { TGo4Analysis* ana=TGo4Analysis::Instance(); ana->SetNewInputFile(kTRUE); if(ana->IsAutoSaveFileChange()) { TString fname=GetCurrentFileName(); fname.ReplaceAll(".lmd",4,"_ASF",4); if(dosave) ana->AutoSave(); ana->ClearObjects("Histograms"); TString asfname=fname+".root"; cout <<"Setting autosavefile to name "<SetAutoSaveFile(asfname.Data()); if(dosave) ana->AutoSave(); } return 0; } const char* TGo4MbsFile::GetActiveName() { return GetCurrentFileName(); }