otsdaq  v2_04_01
DataLoggerApp.cc
1 #include "otsdaq/DataLoggerApp/DataLoggerApp.h"
2 
3 //#include "otsdaq-core/Macros/CoutMacros.h"
4 //#include "otsdaq-core/MessageFacility/MessageFacility.h"
5 //#include "otsdaq-core/SOAPUtilities/SOAPCommand.h"
6 //#include "otsdaq-core/SOAPUtilities/SOAPUtilities.h"
7 //#include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
8 //
9 //#include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
10 //#include "otsdaq-core/TablePlugins/XDAQContextTable.h"
11 //
12 //#include <toolbox/fsm/FailedEvent.h>
13 //
14 //#include <xdaq/NamespaceURI.h>
15 //#include <xoap/Method.h>
16 //
17 //#include <memory>
18 #include "artdaq-core/Utilities/configureMessageFacility.hh"
19 #include "artdaq/BuildInfo/GetPackageBuildInfo.hh"
20 #include "artdaq/DAQdata/Globals.hh"
21 #include "cetlib_except/exception.h"
22 #include "fhiclcpp/make_ParameterSet.h"
23 //#include "messagefacility/MessageLogger/MessageLogger.h"
24 
25 #include <boost/exception/all.hpp>
26 
27 //#include <cassert>
28 //#include <fstream>
29 //#include <iostream>
30 //#include "otsdaq-core/TableCore/TableGroupKey.h"
31 
32 using namespace ots;
33 
34 XDAQ_INSTANTIATOR_IMPL(DataLoggerApp)
35 
36 #define ARTDAQ_FCL_PATH std::string(__ENV__("USER_DATA")) + "/" + "ARTDAQConfigurations/"
37 #define ARTDAQ_FILE_PREAMBLE "aggregator"
38 
39 //========================================================================================================================
40 DataLoggerApp::DataLoggerApp(xdaq::ApplicationStub* stub) : CoreSupervisorBase(stub)
41 // : xdaq::Application(s)
42 // , SOAPMessenger(this)
43 // , RunControlStateMachine("UnnamedAggregator")
44 // , stateMachineWorkLoopManager_(
45 // toolbox::task::bind(this, &DataLoggerApp::stateMachineThread, "StateMachine"))
46 // , stateMachineSemaphore_(toolbox::BSem::FULL)
47 // , theConfigurationManager_(
48 // new ConfigurationManager) //(Singleton<ConfigurationManager>::getInstance())
49 // ////I always load the full config but if I want to
50 // // load a partial configuration (new
51 // // ConfigurationManager)
52 // , XDAQContextTableName_(
53 // theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)->getTableName())
54 // , supervisorConfigurationPath_(
55 // "INITIALIZED INSIDE THE CONTRUCTOR BECAUSE IT NEEDS supervisorContextUID_ and
56 // " "supervisorApplicationUID_")
57 // , supervisorContextUID_("INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION")
58 // , supervisorApplicationUID_(
59 // "INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION")
60 {
61  __SUP_COUT__ << "Constructor." << __E__;
62 
63  INIT_MF("DataLoggerApp");
64 
65  // xgi::bind(this, &DataLoggerApp::Default, "Default");
66  // xgi::bind(this, &DataLoggerApp::stateMachineXgiHandler, "StateMachineXgiHandler");
67  //
68  // xoap::bind(this,
69  // &DataLoggerApp::stateMachineStateRequest,
70  // "StateMachineStateRequest",
71  // XDAQ_NS_URI);
72  // xoap::bind(this,
73  // &DataLoggerApp::stateMachineErrorMessageRequest,
74  // "StateMachineErrorMessageRequest",
75  // XDAQ_NS_URI);
76  //
77  // try
78  // {
79  // supervisorContextUID_ =
80  // theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)
81  // ->getContextUID(
82  // getApplicationContext()->getContextDescriptor()->getURL());
83  // }
84  // catch(...)
85  // {
86  // __SUP_COUT_ERR__
87  // << "XDAQ Supervisor could not access it's configuration through "
88  // "the Configuration Manager."
89  // << ". The getApplicationContext()->getContextDescriptor()->getURL() = "
90  // << getApplicationContext()->getContextDescriptor()->getURL() << __E__;
91  // throw;
92  // }
93  // try
94  // {
95  // supervisorApplicationUID_ =
96  // theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)
97  // ->getApplicationUID(
98  // getApplicationContext()->getContextDescriptor()->getURL(),
99  // getApplicationDescriptor()->getLocalId());
100  // }
101  // catch(...)
102  // {
103  // __SUP_COUT_ERR__ << "XDAQ Supervisor could not access it's configuration
104  // through " "the Configuration Manager."
105  // << " The supervisorContextUID_ = " << supervisorContextUID_
106  // << ". The supervisorApplicationUID = " <<
107  // supervisorApplicationUID_
108  // << __E__;
109  // throw;
110  // }
111  // supervisorConfigurationPath_ = "/" + supervisorContextUID_ +
112  // "/LinkToApplicationTable/" +
113  // supervisorApplicationUID_ +
114  //"/LinkToSupervisorTable";
115  //
116  // setStateMachineName(supervisorApplicationUID_);
117  __SUP_COUT__ << "Constructed." << __E__;
118 } // end constructor()
119 
120 //========================================================================================================================
121 DataLoggerApp::~DataLoggerApp(void)
122 {
123  __SUP_COUT__ << "Destructor." << __E__;
124  destroy();
125  __SUP_COUT__ << "Destructed." << __E__;
126 } // end destructor()
127 
128 //========================================================================================================================
129 void DataLoggerApp::init(void)
130 {
131  __SUP_COUT__ << "Initializing..." << __E__;
132 
133  // allSupervisorInfo_.init(getApplicationContext());
134  artdaq::configureMessageFacility("DataLogger");
135  __SUP_COUT__ << "artdaq MF configured." << __E__;
136 
137  // initialization
138 
139  std::string name = "DataLogger";
140  unsigned short port = 5300;
141 
142  // artdaq::setMsgFacAppName(supervisorApplicationUID_, port);
143  artdaq::setMsgFacAppName(name, port);
144  // mf::LogDebug(supervisorApplicationUID_) << "artdaq version " <<
145  TLOG(TLVL_DEBUG, name + "Supervisor")
146  << "artdaq version "
147  << artdaq::GetPackageBuildInfo::getPackageBuildInfo().getPackageVersion()
148  << ", built "
149  << artdaq::GetPackageBuildInfo::getPackageBuildInfo().getBuildTimestamp();
150 
151  // create the DataLoggerInterface
152  app_name = name;
153  my_rank = this->getApplicationDescriptor()->getLocalId();
154 
155  theDataLoggerInterface_.reset(new artdaq::DataLoggerApp());
156 
157  __SUP_COUT__ << "Initialized." << __E__;
158 } // end init()
159 
160 //========================================================================================================================
161 void DataLoggerApp::destroy(void)
162 {
163  __SUP_COUT__ << "Destroying..." << __E__;
164  theDataLoggerInterface_.reset(nullptr);
165  __SUP_COUT__ << "Destroyed." << __E__;
166 } // end destroy()
167 //
169 // void DataLoggerApp::Default(xgi::Input* in, xgi::Output* out)
170 //{
171 // *out << "<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
172 // "src='/WebPath/html/DataLoggerApp.html?urn="
173 // << this->getApplicationDescriptor()->getLocalId() << "'></frameset></html>";
174 //}
175 //
177 // void DataLoggerApp::stateMachineXgiHandler(xgi::Input* in, xgi::Output* out) {}
178 //
180 // void DataLoggerApp::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out) {}
181 //
183 // xoap::MessageReference DataLoggerApp::stateMachineXoapHandler(
184 // xoap::MessageReference message)
185 //{
186 // __SUP_COUT__ << "Soap Handler!" << __E__;
187 // stateMachineWorkLoopManager_.removeProcessedRequests();
188 // stateMachineWorkLoopManager_.processRequest(message);
189 // __SUP_COUT__ << "Done - Soap Handler!" << __E__;
190 // return message;
191 //}
192 //
194 // xoap::MessageReference DataLoggerApp::stateMachineResultXoapHandler(
195 // xoap::MessageReference message)
196 //{
197 // __SUP_COUT__ << "Soap Handler!" << __E__;
198 // // stateMachineWorkLoopManager_.removeProcessedRequests();
199 // // stateMachineWorkLoopManager_.processRequest(message);
200 // __SUP_COUT__ << "Done - Soap Handler!" << __E__;
201 // return message;
202 //}
203 //
205 // bool DataLoggerApp::stateMachineThread(toolbox::task::WorkLoop* workLoop)
206 //{
207 // stateMachineSemaphore_.take();
208 // __SUP_COUT__ << "Re-sending message..."
209 // << SOAPUtilities::translate(
210 // stateMachineWorkLoopManager_.getMessage(workLoop))
211 // .getCommand()
212 // << __E__;
213 // std::string reply = send(this->getApplicationDescriptor(),
214 // stateMachineWorkLoopManager_.getMessage(workLoop));
215 // stateMachineWorkLoopManager_.report(workLoop, reply, 100, true);
216 // __SUP_COUT__ << "Done with message" << __E__;
217 // stateMachineSemaphore_.give();
218 // return false; // execute once and automatically remove the workloop so in
219 // // WorkLoopManager the try workLoop->remove(job_) could be commented
220 // // out return true;//go on and then you must do the
221 // // workLoop->remove(job_) in WorkLoopManager
222 //}
223 //
225 // xoap::MessageReference DataLoggerApp::stateMachineStateRequest(
226 // xoap::MessageReference message)
227 //{
228 // __SUP_COUT__ << theStateMachine_.getCurrentStateName() << __E__;
229 // return SOAPUtilities::makeSOAPMessageReference(
230 // theStateMachine_.getCurrentStateName());
231 //}
232 //
234 // xoap::MessageReference DataLoggerApp::stateMachineErrorMessageRequest(
235 // xoap::MessageReference message)
236 //{
237 // __SUP_COUT__ << "theStateMachine_.getErrorMessage() = "
238 // << theStateMachine_.getErrorMessage() << __E__;
239 //
240 // SOAPParameters retParameters;
241 // retParameters.addParameter("ErrorMessage", theStateMachine_.getErrorMessage());
242 // return SOAPUtilities::makeSOAPMessageReference("stateMachineErrorMessageRequestReply",
243 // retParameters);
244 //}
245 //
247 // void DataLoggerApp::stateInitial(toolbox::fsm::FiniteStateMachine& fsm) {}
248 //
250 // void DataLoggerApp::stateHalted(toolbox::fsm::FiniteStateMachine& fsm) {}
251 //
253 // void DataLoggerApp::stateRunning(toolbox::fsm::FiniteStateMachine& fsm) {}
254 //
256 // void DataLoggerApp::stateConfigured(toolbox::fsm::FiniteStateMachine& fsm) {}
257 //
259 // void DataLoggerApp::statePaused(toolbox::fsm::FiniteStateMachine& fsm) {}
260 //
262 // void DataLoggerApp::inError(toolbox::fsm::FiniteStateMachine& fsm)
263 //{
264 // __SUP_COUT__
265 // << "Fsm current state: " << theStateMachine_.getCurrentStateName()
266 // << __E__;
267 // // rcmsStateNotifier_.stateChanged("Error", "");
268 //}
269 //
271 // void DataLoggerApp::enteringError(toolbox::Event::Reference e)
272 //{
273 // __SUP_COUT__
274 // << "Fsm current state: " << theStateMachine_.getCurrentStateName()
275 // << __E__;
276 // toolbox::fsm::FailedEvent& failedEvent = dynamic_cast<toolbox::fsm::FailedEvent&>(*e);
277 // std::ostringstream error;
278 // error << "Failure performing transition from " << failedEvent.getFromState() << " to "
279 // << failedEvent.getToState()
280 // << " exception: " << failedEvent.getException().what();
281 // __SUP_COUT__ << error.str() << __E__;
282 // // diagService_->reportError(errstr.str(),DIAGERROR);
283 //}
284 
285 //========================================================================================================================
286 void DataLoggerApp::transitionConfiguring(toolbox::Event::Reference e)
287 {
288  __SUP_COUT__ << "Configuring..." << __E__;
289  __SUP_COUT__ << SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
290  << __E__;
291 
292  std::pair<std::string /*group name*/, TableGroupKey> theGroup(
293  SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
294  .getParameters()
295  .getValue("ConfigurationTableGroupName"),
296  TableGroupKey(SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
297  .getParameters()
298  .getValue("ConfigurationTableGroupKey")));
299 
300  __SUP_COUT__ << "Configuration group name: " << theGroup.first
301  << " key: " << theGroup.second << __E__;
302 
303  theConfigurationManager_->loadTableGroup(theGroup.first, theGroup.second, true);
304 
305  // load fcl string from dedicated file
306  fhicl::ParameterSet pset;
307 
308  std::string filename = ARTDAQ_FCL_PATH + ARTDAQ_FILE_PREAMBLE + "-";
309  const std::string& uid =
310  theConfigurationManager_
311  ->getNode(ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME + "/" +
312  CorePropertySupervisorBase::getSupervisorUID() + "/" +
313  "LinkToSupervisorTable")
314  .getValueAsString();
315 
316  __SUP_COUTV__(uid);
317  for(unsigned int i = 0; i < uid.size(); ++i)
318  if((uid[i] >= 'a' && uid[i] <= 'z') || (uid[i] >= 'A' && uid[i] <= 'Z') ||
319  (uid[i] >= '0' && uid[i] <= '9')) // only allow alpha numeric in file name
320  filename += uid[i];
321  filename += ".fcl";
322 
323  __SUP_COUTV__(filename);
324 
325  std::string fileFclString;
326  {
327  std::ifstream in(filename, std::ios::in | std::ios::binary);
328  if(in)
329  {
330  std::string contents;
331  in.seekg(0, std::ios::end);
332  fileFclString.resize(in.tellg());
333  in.seekg(0, std::ios::beg);
334  in.read(&fileFclString[0], fileFclString.size());
335  in.close();
336  }
337  else
338  {
339  __SUP_SS__ << "Fhicl file not found! " << filename << __E__;
340  __SUP_SS_THROW__;
341  }
342  }
343 
344  __SUP_COUTV__(fileFclString);
345 
346  try
347  {
348  fhicl::make_ParameterSet(fileFclString, pset);
349  theDataLoggerInterface_->initialize(pset, 0, 0);
350  }
351  catch(const cet::coded_exception<fhicl::error, &fhicl::detail::translate>& e)
352  {
353  __SUP_SS__ << "Error was caught while configuring: " << e.what() << __E__;
354  __SUP_COUT_ERR__ << "\n" << ss.str();
355  theStateMachine_.setErrorMessage(ss.str());
356  throw toolbox::fsm::exception::Exception(
357  "Transition Error" /*name*/,
358  ss.str() /* message*/,
359  "DataLoggerApp::transitionConfiguring" /*module*/,
360  __LINE__ /*line*/,
361  __FUNCTION__ /*function*/
362  );
363  }
364 
365  __SUP_COUT__ << "Configured." << __E__;
366 } // end transitionConfiguring()
367 
368 //========================================================================================================================
369 void DataLoggerApp::transitionHalting(toolbox::Event::Reference e)
370 {
371  __SUP_COUT__ << "Halting..." << __E__;
372  try
373  {
374  theDataLoggerInterface_->stop(45, 0);
375  }
376  catch(...)
377  {
378  // It is okay for this to fail, esp. if already stopped...
379  __SUP_COUT__ << "Ignoring error on halt." << __E__;
380  }
381 
382  try
383  {
384  theDataLoggerInterface_->shutdown(45);
385  }
386  catch(...)
387  {
388  __SUP_COUT_ERR__ << "Error occurred during shutdown! State="
389  << theDataLoggerInterface_->status();
390  }
391 
392  init();
393 
394  __SUP_COUT__ << "Halted." << __E__;
395 } // end transitionHalting()
396 
397 //========================================================================================================================
398 void DataLoggerApp::transitionInitializing(toolbox::Event::Reference e)
399 {
400  __SUP_COUT__ << "Initializing..." << __E__;
401  init();
402  __SUP_COUT__ << "Initialized." << __E__;
403 } // end transitionInitializing()
404 
405 //========================================================================================================================
406 void DataLoggerApp::transitionPausing(toolbox::Event::Reference e)
407 {
408  __SUP_COUT__ << "Pausing..." << __E__;
409  theDataLoggerInterface_->pause(0, 0);
410  __SUP_COUT__ << "Paused." << __E__;
411 } // end transitionPausing()
412 
413 //========================================================================================================================
414 void DataLoggerApp::transitionResuming(toolbox::Event::Reference e)
415 {
416  __SUP_COUT__ << "Resuming..." << __E__;
417  theDataLoggerInterface_->resume(0, 0);
418  __SUP_COUT__ << "Resumed." << __E__;
419 } // end transitionResuming()
420 
421 //========================================================================================================================
422 void DataLoggerApp::transitionStarting(toolbox::Event::Reference e)
423 {
424  __SUP_COUT__ << "Starting..." << __E__;
425  auto runNumber = SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
426  .getParameters()
427  .getValue("RunNumber");
428  try
429  {
430  art::RunID runId(
431  (art::RunNumber_t)boost::lexical_cast<art::RunNumber_t>(runNumber));
432  theDataLoggerInterface_->start(runId, 0, 0);
433  }
434  catch(const boost::exception& e)
435  {
436  __SUP_SS__ << "Error parsing string to art::RunNumber_t: " << runNumber << __E__;
437  __SUP_SS_THROW__;
438  }
439  __SUP_COUT__ << "Started." << __E__;
440 } // end transitionStarting()
441 
442 //========================================================================================================================
443 void DataLoggerApp::transitionStopping(toolbox::Event::Reference e)
444 {
445  __SUP_COUT__ << "Stopping..." << __E__;
446  theDataLoggerInterface_->stop(45, 0);
447  __SUP_COUT__ << "Stopped." << __E__;
448 } // end transitionStopping()