STEER/TFndGeb2hdtMan.cxx

00001 // @(#)fROOT/STEER:$Name:  $:$Id: TFndGeb2hdtMan.cxx,v 1.77 2007/09/24 07:32:41 Diego_Faso Exp $
00002 // Author: Diego Faso <mailto:faso@to.infn.it>, 2006/06/05
00003 
00004 #include "TFndGeb2hdtMan.h"
00005 #include "TFndGeb2hdtGUI.h"
00006 
00007   ClassImp(TFndGeb2hdtMan)
00008 
00009 
00010 //_____________________________
00011 TFndGeb2hdtMan::TFndGeb2hdtMan():
00012  fRun(),fDebug(),
00013  fMsqlHost(),fDataPath(),fFileName(),fNevents(),fGebIp(),
00014  fStartTime(),fStopTime(),fOnlFlg(),fConsumControlFile(),
00015  fTimeLimit(),fTimedOut(),fUpdateEvGap(),fUpdatingProd(),
00016  fCurEv(),fLastUpdEv(),fRate(),fExitVal(),fManStop(),fPaused(),
00017  fHdtRootFile(),
00018  fMonSaveThread(),
00019  fConfFileRead(),
00020  fHdtTree(),fMustSaveHdt(kTRUE)
00021 {
00022   // the default constructor shall not be used by standard users
00023 
00024   fRun = new TFndRun();
00025 }
00026 
00027 //_____________________________
00028 // TFndGeb2hdtMan::TFndGeb2hdtMan(TString msqlhost,TString fpth,TString fnam,Int_t nevts,Int_t gebip):
00029 //   fRun(),fDebug(),
00030 //   fMsqlHost(msqlhost),fDataPath(fpth),fFileName(fnam),fNevents(nevts),fGebIp(gebip),
00031 //   fStartTime(),fStopTime(),fOnlFlg(),fConsumControlFile(),
00032 //   fTimeLimit(),fTimedOut(),fUpdateEvGap(),fUpdatingProd(),
00033 //   fCurEv(),fRate(),fExitVal(),fManStop(),fPaused(),
00034 //   fHdtRootFile(),
00035 //   fMonSaveThread(),
00036 //   fConfFileRead(),
00037 //   fHdtTree(),fMustSaveHdt(kTRUE)
00038 // {
00039 //   // the PID of current process is stored into a text file
00040 
00041 //   fRun = new TFndRun();
00042   
00043 //   TString cmdpid = TString("echo \"prod: ");
00044 //   cmdpid+=gSystem->GetPid();
00045 //   cmdpid+="\" > ";
00046 //   cmdpid+=FROOT::ExpandPathName(".froot_pid");
00047 //   gSystem->Exec(cmdpid.Data());  
00048 
00049 
00050 // }
00051 
00052 //_____________________________
00053 TFndGeb2hdtMan::TFndGeb2hdtMan(const TString &msqlhost,const TString &fpth,const TString &run_type,const Int_t &run_num,const Int_t &nevts,Int_t gebip):
00054   fRun(),fDebug(),
00055   fMsqlHost(msqlhost),fDataPath(fpth),fFileName(),fNevents(nevts),fGebIp(gebip),
00056   fStartTime(),fStopTime(),fOnlFlg(),fConsumControlFile(),
00057   fTimeLimit(),fTimedOut(),fUpdateEvGap(),fUpdatingProd(),
00058   fCurEv(),fRate(),fExitVal(),fManStop(),fPaused(),
00059   fHdtRootFile(),
00060   fMonSaveThread(),
00061   fConfFileRead(),
00062   fHdtTree(),fMustSaveHdt(kTRUE)
00063 {
00064   
00065   // the PID of current process is stored into a text file
00066   fFileName = BuildRunName(run_type,run_num);
00067   fRun = new TFndRun();
00068   
00069   TString cmdpid = TString("echo \"prod: ");
00070   cmdpid+=gSystem->GetPid();
00071   cmdpid+="\" > ";
00072   cmdpid+=FROOT::ExpandPathName(".froot_pid");
00073   gSystem->Exec(cmdpid.Data());  
00074   
00075 }
00076 
00077 //_____________________________
00078 TFndGeb2hdtMan::~TFndGeb2hdtMan(){
00079 
00080   //  if(fHdtTree) delete fHdtTree;
00081   delete fRun;
00082 }
00083 
00084 //_____________________________
00085 void TFndGeb2hdtMan::CreateHdtFile(){
00086   // create new hdt.root file (in $FND_HDT) depending on current run name/number
00087   
00088   if(!fMustSaveHdt){
00089     Info("CreateHdtFile","HDT file will not be created");
00090     return;
00091   }
00092   
00093   TString start_pth = ExpandPathName("$FND_HDT");
00094   TString foname;
00095 #if defined _FND_OUTPUTS_USE_SUBDIR
00096   Bool_t use_subdir = kFALSE;
00097   if(fOnlFlg == ONL_OFF){
00098     use_subdir = kTRUE;
00099     CreateGrpSubDir(fRun->GetRunType(),fRun->GetRunNumber(),start_pth);
00100   }
00101   TString BuiltName = BuildRunName(fRun->GetRunType(),fRun->GetRunNumber(),use_subdir);
00102 #else
00103   TString BuiltName = BuildRunName(fRun->GetRunType(),fRun->GetRunNumber());
00104 #endif
00105   
00106   foname.Form("%s/%s.hdt.root",
00107               start_pth.Data(),
00108               BuiltName.Data());
00109   
00110   Info("TFndRun", "Creating HDT file \"%s\"", foname.Data());
00111   
00112   if(fHdtRootFile && fHdtRootFile->IsOpen()) {
00113     fHdtRootFile->Close(); 
00114     delete fHdtRootFile;
00115   }
00116   fHdtRootFile =  new TFile(foname,"RECREATE","Finuda Hit-Data-Tape file");
00117   fHdtRootFile->SetCompressionLevel(1);
00118   
00119 }
00120 
00121 //_____________________________
00122 void TFndGeb2hdtMan::WriteHdtFile(){
00123 
00124   if(!fMustSaveHdt) return;
00125 
00126   if(!fHdtRootFile){
00127     Warning("WriteHdtFile","hdt-file not availabla (check your configuration file)");
00128     return;
00129   }
00130   fHdtRootFile->cd();
00131   if(fRun->GetGenInfo()) fRun->GetGenInfo()->Write("",TObject::kOverwrite); 
00132   else Warning("WriteHdtFile", "fGenInfo not available from TFndRun");
00133   
00134   if(fRun->GetFeeMap()) fRun->GetFeeMap()->Write("",TObject::kOverwrite) ;
00135   else Warning("WriteHdtFile", "fFeeMap not available from TFndRun");
00136   
00137   Info("WriteHdtFile","==============> Writing HDT TREE...");
00138   fHdtTree->Write();
00139   Info("WriteHdtFile","==============> Purging HDT FILE..."); 
00140   fHdtRootFile->Purge();
00141   
00142   fHdtRootFile->Close();
00143   delete fHdtRootFile; fHdtRootFile = 0;
00144   
00145 }
00146 
00147 //______________________
00148 void TFndGeb2hdtMan::UpdateProducers(){
00149 
00150   HandleConsumerActions(0);      // inhibit consumer(s)
00151 
00152   // GTS histograms update and HDT flush are
00153   //  faster than others...
00154   //  ...updating them more often...  
00155 
00156   fUpdatingProd = kTRUE;
00157 
00158   FlushHdtTree();
00159 
00160   if(fRun->GtsMon()) fRun->GtsMon()->Update();
00161 
00162   if(fRun->TofMon()) fRun->TofMon()->Update();
00163 
00164   FlushHdtTree();
00165   if(fRun->GtsMon()) fRun->GtsMon()->Update(); //
00166 
00167   if(fRun->IsmMon()){
00168     //    Info("UpdateProducers","Updating ISIM");
00169     fRun->IsmMon()->Update();
00170   }
00171   if(fRun->OsmMon()){
00172     //    Info("UpdateProducers","Updating OSIM");
00173     fRun->OsmMon()->Update();
00174   }
00175 
00176   FlushHdtTree();
00177   if(fRun->GtsMon()) fRun->GtsMon()->Update(); //
00178 
00179   if(fRun->LmdMon()) fRun->LmdMon()->Update();
00180 
00181   FlushHdtTree();
00182   if(fRun->GtsMon()) fRun->GtsMon()->Update(); //
00183 
00184   if(fRun->StbMon()) fRun->StbMon()->Update();  
00185 
00186   TouchMapFiles();
00187 
00188 
00189   //  Info("UpdateProducers","===> All monitors updated(producer) <===");
00190   
00191   HandleConsumerActions(1);      // inhibit consumer(s)
00192 
00193   fUpdatingProd = kFALSE;
00194 
00195   return;
00196 }
00197 
00198 //_____________________________
00199 void TFndGeb2hdtMan::FlushHdtTree(){
00200   // used in online-mode only in order to update
00201   // the content of shared HDT tree (used by the Event-Display)
00202 
00203   //   Info("FlushHdtTree","method disabled");
00204   //   return;
00205 
00206   if(!fMustSaveHdt) return;
00207 
00208   if(!fHdtRootFile){
00209     Warning("FlushHdtTree","hdt-file not availabla (check your configuration file)");
00210     return;
00211   }
00212 
00213   //  Info("FlushHdtTree","cd-ing");
00214   fHdtRootFile->cd();
00215   fHdtTree->AutoSave("SaveSelf");
00216   
00217   //   Info("FlushHdtTree","writing");
00218   //   fHdtTree->Write();
00219   //   Info("FlushHdtTree","purging");
00220   //   fHdtRootFile->Purge();
00221   //   Info("FlushHdtTree","flushing");
00222   //   fHdtRootFile->Flush();
00223   Info("FlushHdtTree","done");
00224   usleep(5000000);
00225 
00226 }
00227 
00228 //_____________________________
00229 void TFndGeb2hdtMan::ReadConfFile(){
00230 
00231   if(!fRun) TerminateFroot(0,"TFndGeb2hdtMan::ReadConfFile ---> fRun not defined!");
00232 
00233   // Configuration file
00234   cout << "Reading configuration file." << endl;
00235   fRun->ReadConfigFile();
00236   fRun->RunConfiguration()->Print();
00237 
00238   fDebug = fRun->RunConfiguration()->Debug(); 
00239   fUsingGUI = fRun->RunConfiguration()->Geb2hdtUsingGUI();
00240 
00241   fUpdateEvGap = fRun->RunConfiguration()->Geb2hdtUpdateEvGap();
00242   fMustSaveHdt = fRun->RunConfiguration()->GetMustSaveHdt();
00243   // ---
00244   fConfFileRead = kTRUE;
00245 }
00246 
00247 //_____________________________
00248 void TFndGeb2hdtMan::InitRun(){
00249 
00250   if(!gSystem->AccessPathName(".froot_onlstopped") ) gSystem->Exec("rm -f .froot_onlstopped");
00251 
00252   TDatime start_time = TDatime();
00253   fStartTime = (Int_t)start_time.Convert();
00254   fStopTime = fStartTime; // this will change
00255 
00256   // build up input file name
00257   cout << endl << " -> mSQL DB Host: " << fMsqlHost.Data() << endl;
00258   cout << " -> Data path: "    << fDataPath.Data() << endl;
00259   cout << " -> Run: "          << fFileName.Data() << endl;
00260   cout << " -> " << fNevents << " events will be processed." << endl;
00261   
00262   TString grptit = TString("");
00263 
00264   if(!fConfFileRead) ReadConfFile();
00265 
00266   fRun->SetDataPath(fDataPath);
00267   fRun->SetDBHost(fMsqlHost);
00268   //
00269   fRun->SetMaxNumberOfEvents(fNevents);
00270   
00271   cout << "TFndGeb2hdtMan::InitRun ---> debug_lev = " << fDebug << endl;
00272   printf("TFndGeb2hdtMan::InitRun ---> debug_raw = 0x%x\n",fRun->GetDebugRawEv());
00273 
00275   // temporary: MUST MODIFY geb2hdt!
00276   TString run_type = fFileName;
00277   run_type.Resize(4);
00278   TString num = fFileName;
00279   num.Remove(0,4);
00280   Int_t run_num = num.Atoi();
00281 
00282   if(!run_type.CompareTo("ONLM")) run_num = -1;
00284   Int_t in_val = fRun->InitNewRun(run_type,run_num);
00285   if (in_val == -3) TerminateFroot(0,TString("wrong argument received as \"run-type\" (\""+run_type)+"\").");  
00286   if(in_val != 0){
00287     fExitVal = 4;
00288     FinishRun();
00289     return;
00290   }
00291   //............. set host, path, run, gebip number of events
00292   // perform old constructor operations
00293   fOnlFlg = fRun->Onlflg();
00294   cout << "fndrun constructed: online flag is: " << fOnlFlg << endl;
00295   
00296   fConsumControlFile = ExpandPathName("$FND_SHR/.shared_msg.txt");
00297   // connection to database is automatically handled directly by TFndRun
00298   
00299   CreateHdtFile();
00300   
00302   // If you are wondering why "Bronch"
00303   // is used instead of "Branch" don't change it.
00305   fHdtTree= new TTree("FIN_HDT_TREE","Tree with FINUDA hdt-events");
00306   fHdtTree->Bronch("fndhdt","TFndHdt",&TFndRun::fgFinHdt,128000,1);
00307   if(fOnlFlg == ONL_ALL ) fHdtTree->SetCircular(5000);
00308   //  if(geb_run->GetOnlFlag() == ONL_ALL ) fHdtTree->SetCircular(5000);
00310 }
00311 
00312 //___________________
00313 void TFndGeb2hdtMan::EventLoop(){
00314   // fExitVal values:
00315   //               -2: No answer received from DAQ (online mode only
00316   //               -1: DB error
00317   //                0: next event will be processed
00318   //                1: requested number of events reached
00319   //                2: end of run reached
00320   //                3: process timed out
00321   //                4: requested run was not found
00322   //
00323   // fManStop is not dependent on fExitVal
00324 
00325   Int_t RateCheck1 = 0;
00326   Int_t RateCheck2 = 0;
00327 
00328   RealTimeInfo(G2H_INFO_EV_LOOP_START,"EventLoop","Starting event loop...");
00329   StartMonitors();
00330 
00331   if(fOnlFlg) RealTimeInfo(G2H_INFO_CAN_START_CONS,"EventLoop","Shared memories created: Consumer can start");
00332   while(!fExitVal && !fManStop) {
00333     if(fPaused){
00334       gSystem->Sleep(500);
00335       continue;
00336     }
00337     
00338     if(fTimedOut){
00339       fExitVal = 3;
00340       return;
00341     }
00342 
00343     // exit if timed-out
00344     TDatime stop_time = TDatime();
00345     fStopTime = (Int_t)stop_time.Convert();
00346     if(fTimeLimit>=0 && (fStopTime - fStartTime) > fTimeLimit) {
00347       fTimedOut = kTRUE;
00348       RealTimeInfo(G2H_INFO_TIMED_OUT,"EventLoop","Process has timed out");
00349       cout << "process time-out" << endl;
00350     }
00351     //
00352     // --- event processing    
00353     if(fOnlFlg){
00354       if(fCurEv == 0) RealTimeInfo(G2H_INFO_SEND_FIRST_REQ,"EventLoop","Sending request for the first event...");
00355       else if(fCurEv == 1){
00356         RealTimeInfo(G2H_INFO_PRINT,"EventLoop","Monitoring process started");
00357         StartSavingThread();
00358       }
00359     }    
00360     
00361     fExitVal = fRun->GetNextEvent(kTRUE);
00362     //     fRun->GetNextRawEvent(fExitVal); // already performend by GetNextEvent(kTRUE)
00363     //     if(fExitVal == 0) fExitVal = fRun->ReadRawEvent(); // already performed by GetNextEvent(kTRUE)
00364 
00365     if(fExitVal == 0 && fHdtTree){
00366       Int_t fill_size = fHdtTree->Fill();
00367       if(fDebug) Info("EventLoop","Filled  (ev %d : size: %d)\n",fRun->GetEvNum_Raw(),fill_size);
00368     }
00369 
00370 
00371     if(fOnlFlg && fRun->GetNofProcessedEvents()%10 == 0 && fRun->GetCurOnlineRunNmber() > 0){
00372       cerr << "Producer msg ===> Run: " << fRun->GetCurOnlineRunNmber() << "; Last event: " << fRun->GetEvNum_Raw() << endl;;
00373     }
00374     
00376     // --- stop management: see "TFndRun::GetNextEvent"
00377     if(fExitVal == 1) { // requested number of events reached
00378       cout << "fExitVal: " << fExitVal << endl;
00379       //      fCurEv--;
00380       fRun->ClearEvent(); //fRun->CleanEvent() called by TFndRun::FinishRun();
00381       break;
00382     }    
00383     else if(fExitVal == 2) { // end of run reached
00384       fRun->ClearEvent(); //fRun->CleanEvent() called by TFndRun::FinishRun();
00385       return; 
00386     }
00387     else if(fExitVal == -1){ // DB-error
00388       fRun->ClearEvent(); //fRun->CleanEvent() called by TFndRun::FinishRun();
00389       cout << "Database error" << endl;
00390       break;
00391     }
00392     else if(fExitVal == -2){ // No answer received from DAQ (online mode only)
00393       RealTimeInfo(G2H_INFO_NO_ANSWER,"EventLoop","No answer received from DAQ...retrying...");
00394       gSystem->Sleep(500);
00395       RealTimeInfo(G2H_INFO_SEND_REQ_TO_DAQ,"EventLoop","Sending new event request to DAQ...");
00396       //      fCurEv--;
00397       fExitVal = 0;
00398       fRun->ClearEvent();
00399       continue;
00400     }
00401     if(fExitVal != 0){ // check (could be removed in the future...)
00402       Error("EventLoop","Maybe you have found a BUG!");
00403       TerminateFroot(0,"Application BUG!");
00404     }
00406     // --- if you are here, then you have correctly processed this event
00407     fCurEv++;
00408     //    Info("EventLoop","==============================> %d",fCurEv);
00409     
00410     if(PrintInfo(RateCheck1,RateCheck2)){
00411       
00412       TString grp_msg = TString("");
00413       //       if(fOnlFlg){
00414       //        RealTimeInfo(G2H_INFO_UPDATING_PROD_SHR,"EventLoop","Updating producer shared memories");
00415       //        //      UpdateProducers(); // handled within the dedicated thread
00416       //        //      TThread::Lock();
00417       //        //      WriteHdtFile();
00418       //        //      TThread::UnLock();
00419       //        grp_msg.Form("Last update at event %d",fCurEv);
00420       //       }
00421       //       else grp_msg.Form("%s%d: event %d",fRun->GetRunType().Data(),fRun->GetRunNumber(),fCurEv);
00422       // ---
00423       
00424       if(fTimeLimit>=0){
00425         grp_msg+=" ; time remaining: ";
00426         grp_msg+=fTimeLimit - (fStopTime-fStartTime);
00427         grp_msg+=" s.";
00428       }
00429       else grp_msg+=" ; time unlimited.";
00430       //
00431       fLastUpdEv = fCurEv;
00432     }
00434     fRun->ClearEvent();
00435     //fRun->CleanEvent() called by TFndRun::FinishRun();
00436   }
00437   StopSavingThread();
00438   //  cout << "store on output file at event " << fCurEv << endl;
00439   printf("Elapsed time: %d s\n",(Int_t)(fStopTime-fStartTime));
00440   return;
00441 }
00442 
00443 //________________________________
00444 void TFndGeb2hdtMan::StartMonitors(){
00445   
00446   TString msg = "";
00447   msg.Form("Starting monitors (online flag = %d)",fOnlFlg);
00448   RealTimeInfo(G2H_INFO_STARTING_MONITORS,"Starting Monitors",msg);
00449   
00450   //  HandleConsumerActions(0); // inhibit consumer(s)
00451   // if(fOnlFlg) TMapFile::SetMapAddress(K_MapsStartAddress); 
00452   fRun->StartMonitors();
00453   //#if defined _FND_ONL_USE_MAP_FILES_
00454   //  if(fOnlFlg) UpdateProducers();
00455   //#endif
00456   //if(fOnlFlg) TouchMapFiles();
00457   //  HandleConsumerActions(1); // allow consumer(s)
00458   return;
00459 }
00460 
00461 //__________________________________________________________
00462 void TFndGeb2hdtMan::FinishRun(){
00463   // fExitVal values:
00464   //               -2: No answer received from DAQ (online mode only)
00465   //               -1: DB error
00466   //                0: next event will be processed
00467   //                1: requested number of events reached
00468   //                2: end of run reached
00469   //                3: process timed out
00470   //                4: file not foud during initialization
00471   
00472   //  HandleConsumerActions(1);  // allow consumer(s)
00473   while(fUpdatingProd){
00474     Info("FinishRun","Waiting for producer update to be completed");
00475     gSystem->Sleep(1000);
00476   }
00477 
00478   cout << "________________________________________________" << endl;
00479   TString msg = TString();
00480   switch(fExitVal){
00481   case -2: msg = "No answer received from DAQ";                     break;
00482   case -1: msg = "DB error";                                        break;
00483   case  1: msg.Form("Requested number of events reached (%d)");     break;
00484   case  2: msg = "End of run reached: ";                            break;
00485   case  3: msg.Form("geb2hdt process timed out (%d s)",fTimeLimit); break;
00486   case  4: msg.Form("Requested run not found."); break;
00487   default:
00488     if(fManStop) msg = "geb2hdt process manually stopped.";
00489     else{
00490       msg.Form("What's happening? fExitVal = %d --- fManStop = %d",fExitVal,fManStop);
00491       Warning("FinishRun","Unexpected value for fExitVal");
00492     }
00493     break; 
00494   }
00495   RealTimeInfo(G2H_INFO_FINISH_RUN,"FinishRun",msg);
00496   //  fTextMessages->SetText(msg.Data());
00497   printf("TFndGeb2hdtMan::FinishRun ---> \"%s\"\n",(Char_t *)msg.Data());
00498   printf("Total number of events =====> %d\n",fCurEv);
00499   printf("Elapsed time: %d s\n",(Int_t)(fStopTime-fStartTime));
00500   cout << "________________________________________________" << endl;
00501 
00502   fRun->FinishRun(kTRUE);
00503   WriteHdtFile();
00504 
00505   cout << "HDT file written" << endl;
00506   TDatime end_time = TDatime();
00507   fStopTime = end_time.Convert();
00508 
00509   TString final_msg = "";
00510   final_msg.Form("geb2hdt process completed...elapsed time: %d s",(Int_t)(fStopTime-fStartTime));
00511   cout << final_msg.Data() << endl;
00512   RealTimeInfo(G2H_INFO_EXITING,"FinishRun",final_msg);
00513   
00514   Info("FinishRun","files closed...");
00515   cout << "geb2hdt completed" << endl;
00516   
00517 }
00518 
00519 //_____________________________
00520 void TFndGeb2hdtMan::StopProducer() { 
00521   // Method used to stop the current producer from outside
00522   // (GUI button or user macro)
00523 
00524   RealTimeInfo(G2H_INFO_STOPPING,"StopProducer","...stopping producer...");
00525   fManStop = kTRUE;
00526   gSystem->Exec("touch .froot_onlstopped");
00527 }
00528 
00529 //_____________________________
00530 void TFndGeb2hdtMan::PauseProducer() { 
00531   //  HandleConsumerActions(1);  // allow consumer(s)
00532   fPaused = !fPaused;
00533   
00534   if(fPaused) RealTimeInfo(G2H_INFO_PAUSED,   "PauseProducer","Producer paused");
00535   else        RealTimeInfo(G2H_INFO_RESTARTED,"PauseProducer","Producer restarted");
00536 }
00537 //__________________________________________________________
00538 Int_t TFndGeb2hdtMan::TouchMapFiles(){
00539   // simply touch all shared map-files
00540   // needed by NFS to update consumer(s)
00541   //  
00542   // return value:
00543   //           number of touched map-files
00544 
00545 #if !defined _FND_ONL_USE_MAP_FILES_
00546   return 0;
00547 #endif
00548   
00549 #if !defined _FND_USE_TOUCH_MAP_FILES
00550   return 0;
00551 #endif
00552   
00553   Info("TouchMapFiles"," Touching all shared files...");
00554   //   gSystem->Sleep(300);
00555   //   gSystem->ProcessEvents();
00556   const Int_t nmaps = 18;
00557 
00558   TString MapsList[nmaps];
00559   MapsList[0]  = "lmd.map";
00560   MapsList[1]  = "lmd_o_adc.map";
00561   MapsList[2]  = "stb.map";
00562   MapsList[3]  = "stb_tdc_3.map";
00563   MapsList[4]  = "stb_tdc_6.map";
00564   MapsList[5]  = "tof_tdc.map";
00565   MapsList[6]  = "gts.map";
00566   MapsList[7]  = "lmd_i_adc.map";
00567   MapsList[8]  = "lmd_o_tdc.map";
00568   MapsList[9]  = "stb_tdc_1.map";
00569   MapsList[10] = "stb_tdc_4.map";
00570   MapsList[11] = "tof_adc.map";
00571   MapsList[12] = "ism.map";
00572   MapsList[13] = "lmd_i_tdc.map";
00573   MapsList[14] = "osm.map";
00574   MapsList[15] = "stb_tdc_2.map";
00575   MapsList[16] = "stb_tdc_5.map";
00576   MapsList[17] = "tof_map.map";
00577   
00578   Int_t touch_counter = 0;
00579   TString PathString;
00580   for(Int_t i=0;i<nmaps;i++){
00581     PathString.Form("$FND_SHR/%s",MapsList[i].Data());
00582     if(!gSystem->AccessPathName(FROOT::ExpandPathName(PathString.Data()).Data())){ // 0 if found
00583       TString touch_str = TString("touch ");
00584       touch_str += FROOT::ExpandPathName(PathString.Data()).Data();
00585       gSystem->Exec(touch_str.Data());
00586       gSystem->ProcessEvents(); 
00587       if(fDebug) Info("TouchMapFiles()","Map file \"%s\" touched",FROOT::ExpandPathName(PathString.Data()).Data());
00588       touch_counter++;
00589     }
00590   }
00591   if(!touch_counter) Warning("TouchMapFiles()","Shared mmories not found!");
00592   return touch_counter;
00593 }
00594 
00595 
00596 //__________________________________________________________
00597 void TFndGeb2hdtMan::HandleConsumerActions(Bool_t allow){
00598   // the content of the shared text file '.shared_msg.txt' is
00599   // used by the consumer(s).
00600   // Consumer(s) can act (open, read...map-files) if 'allow' is true
00601 
00602   // shared messages are needed only while using TMapFile
00603 
00604 #if !defined _FND_USE_HANDLE_CONSUMER_ACTIONS
00605   return;
00606 #endif
00607 
00608 #if !defined _FND_ONL_USE_MAP_FILES_
00609   return;
00610 #endif
00611 
00612   if(!fOnlFlg) return; // not needed while working offline
00613 
00614   Info("TFndGeb2hdtMan::HandleConsumerActions","allow: %d",allow);
00615   
00616   TString com = TString("echo ");
00617   Int_t size1 = com.Sizeof()-1;
00618   
00619   if(allow) com+="\"go\" > ";
00620   else com+="\"wait\" > ";
00621 
00622   com+=fConsumControlFile.Data();
00623   gSystem->Exec(com.Data());
00624 
00625   com.Resize(size1);
00626   com+="\"\" >> ";
00627   com+=fConsumControlFile.Data();
00628   gSystem->Exec(com.Data());
00629 }
00630 
00631 //__________________________________________________________
00632 void TFndGeb2hdtMan::KillYourself(){
00633 
00634   TString pid_kill = TString("kill -9 ");
00635   
00636   FILE *f = fopen(FROOT::ExpandPathName(".froot_pid"),"r");
00637   Char_t file[200][200];
00638   if(!f){
00639     gROOT->Warning("TFndGeb2hdtMan::KillYourself","PID file not found"); // must use gROOT (static method)
00640     return;
00641   }
00642   TString cur_line = TString();
00643   int l=0;
00644   const Char_t *prod_pid = 0;
00645   while (fgets(file[l],200,f)) { 
00646     Char_t *line=file[l++];
00647     if(strlen(line)<2) continue;
00648     line[strlen(line)-1]='\0';
00649     cur_line = line;
00650     printf("line: \"%s\" --- cur_line: \"%s\"\n",line,(Char_t *)cur_line.Data());
00651     Int_t SpacePos = (Int_t) cur_line.Index(" ");
00652     printf("space at pos: %d\n",SpacePos);
00653     if(!strncmp(cur_line.Data(),"prod:",SpacePos)){ 
00654       prod_pid = ((TSubString)(cur_line.SubString("",SpacePos+1))).Data(); // read content after space
00655       }
00656   }
00657   pid_kill += prod_pid;
00658   gROOT->Info("TFndGeb2hdtMan::KillYourself","Killing producer "); // must use gROOT (static method)
00659   gROOT->Warning("TFndGeb2hdtMan::KillYourself","Shared memories will not be cleaned yet!"); // must use gROOT (static method)
00660   gSystem->Exec(pid_kill.Data());
00661 }
00662 
00663 //__________________________________________________________
00664 Int_t TFndGeb2hdtMan::PrintInfo(Int_t &rate1,Int_t &rate2){
00665   // emit a signal here! (RealTimeInfo)    
00666   // return value:
00667   //              1: printing information (producer needs to be updated)
00668   //              0: not printing information (producer does not need to be updated)
00669   //
00670   // This will drive the ONLINE-HDT producer update
00671 
00672   Int_t LastProcEvts = fCurEv - fLastUpdEv;
00673 
00674   Int_t minimumnum; // don't allow producer histos before this
00675   Int_t minimumsec; // don't allow producer histos before this
00676   Int_t maximumsec; // update producer histos in any case
00677 #if defined _FND_ONL_USE_SHARED_FILES_
00678   minimumnum = 10; // was 100 before using the separate thread for saving histos
00679   minimumsec = 5; // was 60 before using the separate thread for saving histos
00680   maximumsec = 15; // was 120 before using the separate thread for saving histos
00681   //  return 0;
00682 #elif defined _FND_ONL_USE_MAP_FILES_
00683   minimumnum = 30;
00684   minimumsec = 5;
00685   maximumsec = 10;
00686 #endif
00687 
00688   //  cout << " -> Processing event: " <<  fCurEv << "; fLastUpdEv: " << fLastUpdEv << "; LastProcEvts: " << LastProcEvts << endl;;
00689 
00690   if(LastProcEvts < minimumnum) return 0;
00691     
00692   //  Printf(" -> Processing event: %d",fCurEv);
00693   TDatime check_time = TDatime();
00694   rate2 = (Int_t)check_time.Convert();
00695   if(!rate1) rate1 = fStartTime;
00696 
00697   if((Int_t)(rate2-rate1) < minimumsec && fOnlFlg == ONL_ALL ) return 0;
00698   if((Int_t)(rate2-rate1) < maximumsec && LastProcEvts < fUpdateEvGap) return 0;
00699   // the following code will be executed after having processed 'fUpdateEvGap' events
00700   //  or every three seconds (if the monitor is receiving events)
00701 
00702   
00703   fRate = (Int_t )((Float_t)(LastProcEvts) / (Float_t)(rate2-rate1));
00704   TString info_msg;
00705   
00706   Int_t crun =  fndrun->GetRunNumber();
00707   if (crun == -1) crun = (Int_t) fndrun->GetCurOnlineRunNmber();
00708   
00709   if(rate2-rate1 > 0)
00710     info_msg.Form(" -> Run %d - Event %d (%d ev. processed in %d s: running at %d ev/s)",
00711                   crun,
00712                   fCurEv,LastProcEvts,
00713                   (Int_t)(rate2-rate1),
00714                   fRate);
00715   else 
00716     info_msg.Form(" -> Run %d - Event %d (%d ev. processed in %d s)",
00717                   crun,
00718                   fCurEv,
00719                   LastProcEvts,
00720                   (Int_t)(rate2-rate1));
00721 
00722   Info("PrintInfo",info_msg.Data());
00723   RealTimeInfo(G2H_INFO_PRINT,"PrintInfo","Printing information about the running producer...");
00724   
00725   rate1 = rate2;
00726   return 1;
00727 }
00728 
00729 //________________________________
00730 void TFndGeb2hdtMan::ResetGts(){
00731   
00732   //  if(!fRun->Rdt()->Gts()) return; 
00733   RealTimeInfo(G2H_INFO_RESET_GTS,"ResetGts","Resetting GTSshared memories");
00734   fRun->GtsMon()->ResetHistos();
00735   fRun->GtsMon()->Update();
00736 }
00737 
00738 //________________________________
00739 void TFndGeb2hdtMan::ResetTof(){ 
00740   
00741   //  if(!fRun->Rdt()->Tof()) return;
00742   RealTimeInfo(G2H_INFO_RESET_TOF,"ResetTof","Resetting TOF shared memories");
00743   fRun->TofMon()->ResetHistos();
00744   fRun->TofMon()->Update();
00745   
00746 }
00747 
00748 //________________________________
00749 void TFndGeb2hdtMan::ResetSil(){
00750 
00751   //  if(!fRun->Rdt()->Ism() || !fRun->Rdt()->Osm()) return;
00752   RealTimeInfo(G2H_INFO_RESET_SIL,"ResetSil","Resetting SILshared memories");
00753   fRun->IsmMon()->ResetHistos();
00754   fRun->OsmMon()->ResetHistos();
00755   fRun->IsmMon()->Update();
00756   fRun->OsmMon()->Update();
00757 }
00758 
00759 //________________________________
00760 void TFndGeb2hdtMan::ResetLmd(){
00761 
00762   //  if(!fRun->Rdt()->Lmd()) return;
00763   RealTimeInfo(G2H_INFO_RESET_LMD,"ResetLmd","Resetting LMDshared memories");
00764   fRun->LmdMon()->ResetHistos();
00765   fRun->LmdMon()->Update();
00766 }
00767 
00768 //________________________________
00769 void TFndGeb2hdtMan::ResetStb(){
00770 
00771   //  if(!fRun->Rdt()->Stb()) return;
00772   RealTimeInfo(G2H_INFO_RESET_STB,"ResetStb","Resetting STBshared memories");
00773   fRun->StbMon()->ResetHistos();
00774   fRun->StbMon()->Update();
00775 }
00776 
00777 
00778 //__________________________________________________________
00779 void TFndGeb2hdtMan::RealTimeInfo(Int_t Info_id,TString method,TString info){
00780   // required by the related GUI (if used)
00781   Info(method,info);
00782   SendRealTimeInfo(Info_id);
00783 }
00784 
00785 //__________________________________________________________
00786 void TFndGeb2hdtMan::SendRealTimeInfo(Int_t Info_id){
00787   // required by the related GUI (if used)
00788   // remember to check for "TFndGeb2hdtMan::fExitVal" and "TFndGeb2hdtMan::fManStop" in case of "Info_id==G2H_INFO_FINISH_RUN"
00789 
00790   Emit("SendRealTimeInfo(Int_t)",Info_id);
00791 }
00792 
00793 //__________________________________________________________
00794 void *TFndGeb2hdtMan::SavingThread(void *arg){
00795   // Update producer outputs within a dedicate thread
00796   // In this way the update process is continuous
00797   // (even while filling histograms)
00798 
00799   TFndGeb2hdtMan *context = (TFndGeb2hdtMan *)arg;
00800 
00801   while(1){
00802     printf("------------ Monitor Saving thread (%d)\n",context->GetCurrentEvent());
00803     TThread::CancelPoint();
00804     context->UpdateProducers();
00805     usleep(10000000);
00806     //context->WriteHdtFile();
00807     //    cout << "------------ ----- Cancel point passed" << endl;
00808   }
00809 }
00810 
00811 //__________________________________________________________
00812 void TFndGeb2hdtMan::StartSavingThread(){
00813   
00814   cout << "Starting \"Monitor Saving thread\"" << endl;
00815   fMonSaveThread = new TThread("Monitor_Saver",SavingThread,(void *)this);
00816 
00817   TThread::SetCancelOff(); // this is the default
00818   TThread::SetCancelDeferred(); // this is the default
00819 
00820   fMonSaveThread->Run();
00821   
00822 }
00823 
00824 //__________________________________________________________
00825 void TFndGeb2hdtMan::StopSavingThread(){
00826   
00827   if(fMonSaveThread){
00828     if(fMonSaveThread->GetState() == TThread::kRunningState){
00829       cout << "killing \"Monitor Saving thread\"" << endl;
00830       fMonSaveThread->Kill();
00831       TThread::Delete(fMonSaveThread);
00832       delete fMonSaveThread;
00833       fMonSaveThread = 0;
00834     }
00835     else cout << "Monitor Saving thread found, but not running" << endl; 
00836   }
00837   else cout << "Monitor Saving thread not found" << endl;
00838 
00839 
00840   
00841 }

Generated on Tue Oct 16 15:40:48 2007 by  doxygen 1.5.2