$treeview $search $mathjax $extrastylesheet
otsdaq
v2_03_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include "otsdaq/DataLoggerApp/DataLoggerApp.h" 00002 00003 //#include "otsdaq-core/Macros/CoutMacros.h" 00004 //#include "otsdaq-core/MessageFacility/MessageFacility.h" 00005 //#include "otsdaq-core/SOAPUtilities/SOAPCommand.h" 00006 //#include "otsdaq-core/SOAPUtilities/SOAPUtilities.h" 00007 //#include "otsdaq-core/XmlUtilities/HttpXmlDocument.h" 00008 // 00009 //#include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h" 00010 //#include "otsdaq-core/TablePluginDataFormats/XDAQContextTable.h" 00011 // 00012 //#include <toolbox/fsm/FailedEvent.h> 00013 // 00014 //#include <xdaq/NamespaceURI.h> 00015 //#include <xoap/Method.h> 00016 // 00017 //#include <memory> 00018 #include "artdaq-core/Utilities/configureMessageFacility.hh" 00019 #include "artdaq/BuildInfo/GetPackageBuildInfo.hh" 00020 #include "artdaq/DAQdata/Globals.hh" 00021 #include "cetlib_except/exception.h" 00022 #include "fhiclcpp/make_ParameterSet.h" 00023 //#include "messagefacility/MessageLogger/MessageLogger.h" 00024 00025 #include <boost/exception/all.hpp> 00026 00027 //#include <cassert> 00028 //#include <fstream> 00029 //#include <iostream> 00030 //#include "otsdaq-core/TableCore/TableGroupKey.h" 00031 00032 using namespace ots; 00033 00034 XDAQ_INSTANTIATOR_IMPL(DataLoggerApp) 00035 00036 #define ARTDAQ_FCL_PATH std::string(getenv("USER_DATA")) + "/" + "ARTDAQConfigurations/" 00037 #define ARTDAQ_FILE_PREAMBLE "aggregator" 00038 00039 //======================================================================================================================== 00040 DataLoggerApp::DataLoggerApp(xdaq::ApplicationStub* stub) : CoreSupervisorBase(stub) 00041 // : xdaq::Application(s) 00042 // , SOAPMessenger(this) 00043 // , RunControlStateMachine("UnnamedAggregator") 00044 // , stateMachineWorkLoopManager_( 00045 // toolbox::task::bind(this, &DataLoggerApp::stateMachineThread, "StateMachine")) 00046 // , stateMachineSemaphore_(toolbox::BSem::FULL) 00047 // , theConfigurationManager_( 00048 // new ConfigurationManager) //(Singleton<ConfigurationManager>::getInstance()) 00049 // ////I always load the full config but if I want to 00050 // // load a partial configuration (new 00051 // // ConfigurationManager) 00052 // , XDAQContextTableName_( 00053 // theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)->getTableName()) 00054 // , supervisorConfigurationPath_( 00055 // "INITIALIZED INSIDE THE CONTRUCTOR BECAUSE IT NEEDS supervisorContextUID_ and 00056 // " "supervisorApplicationUID_") 00057 // , supervisorContextUID_("INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION") 00058 // , supervisorApplicationUID_( 00059 // "INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION") 00060 { 00061 __SUP_COUT__ << "Constructor." << __E__; 00062 00063 INIT_MF("DataLoggerApp"); 00064 00065 // xgi::bind(this, &DataLoggerApp::Default, "Default"); 00066 // xgi::bind(this, &DataLoggerApp::stateMachineXgiHandler, "StateMachineXgiHandler"); 00067 // 00068 // xoap::bind(this, 00069 // &DataLoggerApp::stateMachineStateRequest, 00070 // "StateMachineStateRequest", 00071 // XDAQ_NS_URI); 00072 // xoap::bind(this, 00073 // &DataLoggerApp::stateMachineErrorMessageRequest, 00074 // "StateMachineErrorMessageRequest", 00075 // XDAQ_NS_URI); 00076 // 00077 // try 00078 // { 00079 // supervisorContextUID_ = 00080 // theConfigurationManager_->__GET_CONFIG__(XDAQContextTable) 00081 // ->getContextUID( 00082 // getApplicationContext()->getContextDescriptor()->getURL()); 00083 // } 00084 // catch(...) 00085 // { 00086 // __SUP_COUT_ERR__ 00087 // << "XDAQ Supervisor could not access it's configuration through " 00088 // "the Configuration Manager." 00089 // << ". The getApplicationContext()->getContextDescriptor()->getURL() = " 00090 // << getApplicationContext()->getContextDescriptor()->getURL() << __E__; 00091 // throw; 00092 // } 00093 // try 00094 // { 00095 // supervisorApplicationUID_ = 00096 // theConfigurationManager_->__GET_CONFIG__(XDAQContextTable) 00097 // ->getApplicationUID( 00098 // getApplicationContext()->getContextDescriptor()->getURL(), 00099 // getApplicationDescriptor()->getLocalId()); 00100 // } 00101 // catch(...) 00102 // { 00103 // __SUP_COUT_ERR__ << "XDAQ Supervisor could not access it's configuration 00104 //through " "the Configuration Manager." 00105 // << " The supervisorContextUID_ = " << supervisorContextUID_ 00106 // << ". The supervisorApplicationUID = " << 00107 // supervisorApplicationUID_ 00108 // << __E__; 00109 // throw; 00110 // } 00111 // supervisorConfigurationPath_ = "/" + supervisorContextUID_ + 00112 // "/LinkToApplicationTable/" + 00113 // supervisorApplicationUID_ + 00114 //"/LinkToSupervisorTable"; 00115 // 00116 // setStateMachineName(supervisorApplicationUID_); 00117 __SUP_COUT__ << "Constructed." << __E__; 00118 } // end constructor() 00119 00120 //======================================================================================================================== 00121 DataLoggerApp::~DataLoggerApp(void) 00122 { 00123 __SUP_COUT__ << "Destructor." << __E__; 00124 destroy(); 00125 __SUP_COUT__ << "Destructed." << __E__; 00126 } // end destructor() 00127 00128 //======================================================================================================================== 00129 void DataLoggerApp::init(void) 00130 { 00131 __SUP_COUT__ << "Initializing..." << __E__; 00132 00133 // allSupervisorInfo_.init(getApplicationContext()); 00134 artdaq::configureMessageFacility("DataLogger"); 00135 __SUP_COUT__ << "artdaq MF configured." << __E__; 00136 00137 // initialization 00138 00139 std::string name = "DataLogger"; 00140 unsigned short port = 5300; 00141 00142 // artdaq::setMsgFacAppName(supervisorApplicationUID_, port); 00143 artdaq::setMsgFacAppName(name, port); 00144 // mf::LogDebug(supervisorApplicationUID_) << "artdaq version " << 00145 TLOG(TLVL_DEBUG, name + "Supervisor") 00146 << "artdaq version " 00147 << artdaq::GetPackageBuildInfo::getPackageBuildInfo().getPackageVersion() 00148 << ", built " 00149 << artdaq::GetPackageBuildInfo::getPackageBuildInfo().getBuildTimestamp(); 00150 00151 // create the DataLoggerInterface 00152 app_name = name; 00153 my_rank = this->getApplicationDescriptor()->getLocalId(); 00154 00155 theDataLoggerInterface_.reset(new artdaq::DataLoggerApp()); 00156 00157 __SUP_COUT__ << "Initialized." << __E__; 00158 } // end init() 00159 00160 //======================================================================================================================== 00161 void DataLoggerApp::destroy(void) 00162 { 00163 __SUP_COUT__ << "Destroying..." << __E__; 00164 theDataLoggerInterface_.reset(nullptr); 00165 __SUP_COUT__ << "Destroyed." << __E__; 00166 } // end destroy() 00167 // 00169 // void DataLoggerApp::Default(xgi::Input* in, xgi::Output* out) 00170 //{ 00171 // *out << "<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame " 00172 // "src='/WebPath/html/DataLoggerApp.html?urn=" 00173 // << this->getApplicationDescriptor()->getLocalId() << "'></frameset></html>"; 00174 //} 00175 // 00177 // void DataLoggerApp::stateMachineXgiHandler(xgi::Input* in, xgi::Output* out) {} 00178 // 00180 // void DataLoggerApp::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out) {} 00181 // 00183 // xoap::MessageReference DataLoggerApp::stateMachineXoapHandler( 00184 // xoap::MessageReference message) 00185 //{ 00186 // __SUP_COUT__ << "Soap Handler!" << __E__; 00187 // stateMachineWorkLoopManager_.removeProcessedRequests(); 00188 // stateMachineWorkLoopManager_.processRequest(message); 00189 // __SUP_COUT__ << "Done - Soap Handler!" << __E__; 00190 // return message; 00191 //} 00192 // 00194 // xoap::MessageReference DataLoggerApp::stateMachineResultXoapHandler( 00195 // xoap::MessageReference message) 00196 //{ 00197 // __SUP_COUT__ << "Soap Handler!" << __E__; 00198 // // stateMachineWorkLoopManager_.removeProcessedRequests(); 00199 // // stateMachineWorkLoopManager_.processRequest(message); 00200 // __SUP_COUT__ << "Done - Soap Handler!" << __E__; 00201 // return message; 00202 //} 00203 // 00205 // bool DataLoggerApp::stateMachineThread(toolbox::task::WorkLoop* workLoop) 00206 //{ 00207 // stateMachineSemaphore_.take(); 00208 // __SUP_COUT__ << "Re-sending message..." 00209 // << SOAPUtilities::translate( 00210 // stateMachineWorkLoopManager_.getMessage(workLoop)) 00211 // .getCommand() 00212 // << __E__; 00213 // std::string reply = send(this->getApplicationDescriptor(), 00214 // stateMachineWorkLoopManager_.getMessage(workLoop)); 00215 // stateMachineWorkLoopManager_.report(workLoop, reply, 100, true); 00216 // __SUP_COUT__ << "Done with message" << __E__; 00217 // stateMachineSemaphore_.give(); 00218 // return false; // execute once and automatically remove the workloop so in 00219 // // WorkLoopManager the try workLoop->remove(job_) could be commented 00220 // // out return true;//go on and then you must do the 00221 // // workLoop->remove(job_) in WorkLoopManager 00222 //} 00223 // 00225 // xoap::MessageReference DataLoggerApp::stateMachineStateRequest( 00226 // xoap::MessageReference message) 00227 //{ 00228 // __SUP_COUT__ << theStateMachine_.getCurrentStateName() << __E__; 00229 // return SOAPUtilities::makeSOAPMessageReference( 00230 // theStateMachine_.getCurrentStateName()); 00231 //} 00232 // 00234 // xoap::MessageReference DataLoggerApp::stateMachineErrorMessageRequest( 00235 // xoap::MessageReference message) 00236 //{ 00237 // __SUP_COUT__ << "theStateMachine_.getErrorMessage() = " 00238 // << theStateMachine_.getErrorMessage() << __E__; 00239 // 00240 // SOAPParameters retParameters; 00241 // retParameters.addParameter("ErrorMessage", theStateMachine_.getErrorMessage()); 00242 // return SOAPUtilities::makeSOAPMessageReference("stateMachineErrorMessageRequestReply", 00243 // retParameters); 00244 //} 00245 // 00247 // void DataLoggerApp::stateInitial(toolbox::fsm::FiniteStateMachine& fsm) {} 00248 // 00250 // void DataLoggerApp::stateHalted(toolbox::fsm::FiniteStateMachine& fsm) {} 00251 // 00253 // void DataLoggerApp::stateRunning(toolbox::fsm::FiniteStateMachine& fsm) {} 00254 // 00256 // void DataLoggerApp::stateConfigured(toolbox::fsm::FiniteStateMachine& fsm) {} 00257 // 00259 // void DataLoggerApp::statePaused(toolbox::fsm::FiniteStateMachine& fsm) {} 00260 // 00262 // void DataLoggerApp::inError(toolbox::fsm::FiniteStateMachine& fsm) 00263 //{ 00264 // __SUP_COUT__ 00265 // << "Fsm current state: " << theStateMachine_.getCurrentStateName() 00266 // << __E__; 00267 // // rcmsStateNotifier_.stateChanged("Error", ""); 00268 //} 00269 // 00271 // void DataLoggerApp::enteringError(toolbox::Event::Reference e) 00272 //{ 00273 // __SUP_COUT__ 00274 // << "Fsm current state: " << theStateMachine_.getCurrentStateName() 00275 // << __E__; 00276 // toolbox::fsm::FailedEvent& failedEvent = dynamic_cast<toolbox::fsm::FailedEvent&>(*e); 00277 // std::ostringstream error; 00278 // error << "Failure performing transition from " << failedEvent.getFromState() << " to " 00279 // << failedEvent.getToState() 00280 // << " exception: " << failedEvent.getException().what(); 00281 // __SUP_COUT__ << error.str() << __E__; 00282 // // diagService_->reportError(errstr.str(),DIAGERROR); 00283 //} 00284 00285 //======================================================================================================================== 00286 void DataLoggerApp::transitionConfiguring(toolbox::Event::Reference e) 00287 { 00288 __SUP_COUT__ << "Configuring..." << __E__; 00289 __SUP_COUT__ << SOAPUtilities::translate(theStateMachine_.getCurrentMessage()) 00290 << __E__; 00291 00292 std::pair<std::string /*group name*/, TableGroupKey> theGroup( 00293 SOAPUtilities::translate(theStateMachine_.getCurrentMessage()) 00294 .getParameters() 00295 .getValue("ConfigurationTableGroupName"), 00296 TableGroupKey(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()) 00297 .getParameters() 00298 .getValue("ConfigurationTableGroupKey"))); 00299 00300 __SUP_COUT__ << "Configuration group name: " << theGroup.first 00301 << " key: " << theGroup.second << __E__; 00302 00303 theConfigurationManager_->loadTableGroup(theGroup.first, theGroup.second, true); 00304 00305 // load fcl string from dedicated file 00306 fhicl::ParameterSet pset; 00307 00308 std::string filename = ARTDAQ_FCL_PATH + ARTDAQ_FILE_PREAMBLE + "-"; 00309 const std::string& uid = CorePropertySupervisorBase::getSupervisorUID(); 00310 00311 __SUP_COUTV__(uid); 00312 for(unsigned int i = 0; i < uid.size(); ++i) 00313 if((uid[i] >= 'a' && uid[i] <= 'z') || (uid[i] >= 'A' && uid[i] <= 'Z') || 00314 (uid[i] >= '0' && uid[i] <= '9')) // only allow alpha numeric in file name 00315 filename += uid[i]; 00316 filename += ".fcl"; 00317 00318 __SUP_COUTV__(filename); 00319 00320 std::string fileFclString; 00321 { 00322 std::ifstream in(filename, std::ios::in | std::ios::binary); 00323 if(in) 00324 { 00325 std::string contents; 00326 in.seekg(0, std::ios::end); 00327 fileFclString.resize(in.tellg()); 00328 in.seekg(0, std::ios::beg); 00329 in.read(&fileFclString[0], fileFclString.size()); 00330 in.close(); 00331 } 00332 } 00333 00334 __SUP_COUTV__(fileFclString); 00335 00336 try 00337 { 00338 fhicl::make_ParameterSet(fileFclString, pset); 00339 theDataLoggerInterface_->initialize(pset, 0, 0); 00340 } 00341 catch(const cet::coded_exception<fhicl::error, &fhicl::detail::translate>& e) 00342 { 00343 __SUP_SS__ << "Error was caught while configuring: " << e.what() << __E__; 00344 __SUP_COUT_ERR__ << "\n" << ss.str(); 00345 theStateMachine_.setErrorMessage(ss.str()); 00346 throw toolbox::fsm::exception::Exception( 00347 "Transition Error" /*name*/, 00348 ss.str() /* message*/, 00349 "DataLoggerApp::transitionConfiguring" /*module*/, 00350 __LINE__ /*line*/, 00351 __FUNCTION__ /*function*/ 00352 ); 00353 } 00354 00355 __SUP_COUT__ << "Configured." << __E__; 00356 } // end transitionConfiguring() 00357 00358 //======================================================================================================================== 00359 void DataLoggerApp::transitionHalting(toolbox::Event::Reference e) 00360 { 00361 __SUP_COUT__ << "Halting..." << __E__; 00362 try 00363 { 00364 theDataLoggerInterface_->stop(45, 0); 00365 } 00366 catch(...) 00367 { 00368 // It is okay for this to fail, esp. if already stopped... 00369 __SUP_COUT__ << "Ignoring error on halt." << __E__; 00370 } 00371 00372 try 00373 { 00374 theDataLoggerInterface_->shutdown(45); 00375 } 00376 catch(...) 00377 { 00378 __SUP_COUT_ERR__ << "Error occurred during shutdown! State=" 00379 << theDataLoggerInterface_->status(); 00380 } 00381 00382 init(); 00383 00384 __SUP_COUT__ << "Halted." << __E__; 00385 } // end transitionHalting() 00386 00387 //======================================================================================================================== 00388 void DataLoggerApp::transitionInitializing(toolbox::Event::Reference e) 00389 { 00390 __SUP_COUT__ << "Initializing..." << __E__; 00391 init(); 00392 __SUP_COUT__ << "Initialized." << __E__; 00393 } // end transitionInitializing() 00394 00395 //======================================================================================================================== 00396 void DataLoggerApp::transitionPausing(toolbox::Event::Reference e) 00397 { 00398 __SUP_COUT__ << "Pausing..." << __E__; 00399 theDataLoggerInterface_->pause(0, 0); 00400 __SUP_COUT__ << "Paused." << __E__; 00401 } // end transitionPausing() 00402 00403 //======================================================================================================================== 00404 void DataLoggerApp::transitionResuming(toolbox::Event::Reference e) 00405 { 00406 __SUP_COUT__ << "Resuming..." << __E__; 00407 theDataLoggerInterface_->resume(0, 0); 00408 __SUP_COUT__ << "Resumed." << __E__; 00409 } // end transitionResuming() 00410 00411 //======================================================================================================================== 00412 void DataLoggerApp::transitionStarting(toolbox::Event::Reference e) 00413 { 00414 __SUP_COUT__ << "Starting..." << __E__; 00415 auto runNumber = SOAPUtilities::translate(theStateMachine_.getCurrentMessage()) 00416 .getParameters() 00417 .getValue("RunNumber"); 00418 try 00419 { 00420 art::RunID runId( 00421 (art::RunNumber_t)boost::lexical_cast<art::RunNumber_t>(runNumber)); 00422 theDataLoggerInterface_->start(runId, 0, 0); 00423 } 00424 catch(const boost::exception& e) 00425 { 00426 __SUP_SS__ << "Error parsing string to art::RunNumber_t: " << runNumber << __E__; 00427 __SUP_SS_THROW__; 00428 } 00429 __SUP_COUT__ << "Started." << __E__; 00430 } // end transitionStarting() 00431 00432 //======================================================================================================================== 00433 void DataLoggerApp::transitionStopping(toolbox::Event::Reference e) 00434 { 00435 __SUP_COUT__ << "Stopping..." << __E__; 00436 theDataLoggerInterface_->stop(45, 0); 00437 __SUP_COUT__ << "Stopped." << __E__; 00438 } // end transitionStopping()