otsdaq  v1_01_02
 All Classes Namespaces Functions
EventBuilderApp.cc
1 #include "otsdaq/EventBuilderApp/EventBuilderApp.h"
2 #include "otsdaq/EventBuilderApp/EventBuilderInterface.h"
3 #include "otsdaq-core/MessageFacility/MessageFacility.h"
4 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
5 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
6 #include "otsdaq-core/SOAPUtilities/SOAPUtilities.h"
7 #include "otsdaq-core/SOAPUtilities/SOAPCommand.h"
8 
9 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationGroupKey.h"
10 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
11 #include "otsdaq-core/ConfigurationPluginDataFormats/XDAQContextConfiguration.h"
12 
13 #include <toolbox/fsm/FailedEvent.h>
14 
15 #include <xdaq/NamespaceURI.h>
16 #include <xoap/Method.h>
17 
18 #include <memory>
19 #include "messagefacility/MessageLogger/MessageLogger.h"
20 #include "artdaq/DAQdata/configureMessageFacility.hh"
21 #include "artdaq/DAQrate/quiet_mpi.hh"
22 #include "cetlib/exception.h"
23 #include "artdaq/BuildInfo/GetPackageBuildInfo.hh"
24 #include "fhiclcpp/make_ParameterSet.h"
25 
26 #include <fstream>
27 #include <iostream>
28 #include <cassert>
29 
30 using namespace ots;
31 
32 XDAQ_INSTANTIATOR_IMPL(EventBuilderApp)
33 
34 //========================================================================================================================
35 EventBuilderApp::EventBuilderApp(xdaq::ApplicationStub* stub)
36 throw (xdaq::exception::Exception)
37 : xdaq::Application (stub)
38 , SOAPMessenger (this)
39 , stateMachineWorkLoopManager_ (toolbox::task::bind(this, &EventBuilderApp::stateMachineThread, "StateMachine"))
40 , stateMachineSemaphore_ (toolbox::BSem::FULL)
41 , theConfigurationManager_ (new ConfigurationManager)//(Singleton<ConfigurationManager>::getInstance()) //I always load the full config but if I want to load a partial configuration (new ConfigurationManager)
42 , XDAQContextConfigurationName_(theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getConfigurationName())
43 , supervisorConfigurationPath_ ("INITIALIZED INSIDE THE CONTRUCTOR BECAUSE IT NEEDS supervisorContextUID_ and supervisorApplicationUID_")
44 , supervisorContextUID_ ("INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION")
45 , supervisorApplicationUID_ ("INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION")
46 //, theConfigurationGroupKey_ (nullptr)
47 //, supervisorInstance_ (this->getApplicationDescriptor()->getInstance())
48 // theFEWInterfacesManager_ (theConfigurationManager_,this->getApplicationDescriptor()->getInstance())
49 {
50  INIT_MF("EventBuilderApp");
51  xgi::bind (this, &EventBuilderApp::Default, "Default" );
52  xgi::bind (this, &EventBuilderApp::stateMachineXgiHandler, "StateMachineXgiHandler");
53 
54  xoap::bind(this, &EventBuilderApp::stateMachineStateRequest, "StateMachineStateRequest", XDAQ_NS_URI );
55  try
56  {
57  supervisorContextUID_ = theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getContextUID(getApplicationContext()->getContextDescriptor()->getURL());
58  }
59  catch(...)
60  {
61  __MOUT_ERR__ << "XDAQ Supervisor could not access it's configuration through the Configuration Context Group." <<
62  " The XDAQContextConfigurationName = " << XDAQContextConfigurationName_ <<
63  ". The supervisorApplicationUID = " << supervisorApplicationUID_ << std::endl;
64  throw;
65  }
66  try
67  {
68  supervisorApplicationUID_ = theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getApplicationUID
69  (
70  getApplicationContext()->getContextDescriptor()->getURL(),
71  getApplicationDescriptor()->getLocalId()
72  );
73  }
74  catch(...)
75  {
76  __MOUT_ERR__ << "XDAQ Supervisor could not access it's configuration through the Configuration Application Group."
77  << " The supervisorApplicationUID = " << supervisorApplicationUID_ << std::endl;
78  throw;
79  }
80  supervisorConfigurationPath_ = "/" + supervisorContextUID_ + "/LinkToApplicationConfiguration/" + supervisorApplicationUID_ + "/LinkToSupervisorConfiguration";
81 
82  setStateMachineName(supervisorApplicationUID_);
83  init();
84 }
85 
86 //========================================================================================================================
87 EventBuilderApp::~EventBuilderApp(void)
88 {
89  destroy();
90 }
91 //========================================================================================================================
92 void EventBuilderApp::init(void)
93 {
94  std::cout << __COUT_HDR_FL__ << "ARTDAQBUILDER SUPERVISOR INIT START!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
95  theSupervisorDescriptorInfo_.init(getApplicationContext());
96  artdaq::configureMessageFacility("eventbuilder");
97 
98  // initialization
99 
100  int const wanted_threading_level { MPI_THREAD_MULTIPLE };
101  //int const wanted_threading_level { MPI_THREAD_FUNNELED };
102 
103  MPI_Comm local_group_comm;
104  try
105  {
106  std::cout << __COUT_HDR_FL__ << "ARTDAQBUILDER SUPERVISOR TRYING MPISENTRY!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
107  mpiSentry_.reset( new artdaq::MPISentry(0, 0, wanted_threading_level, artdaq::TaskType::EventBuilderTask, local_group_comm) );
108  std::cout << __COUT_HDR_FL__ << "ARTDAQBUILDER SUPERVISOR DONE MPISENTRY!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
109  }
110  catch (cet::exception& errormsg)
111  {
112  std::cout << __COUT_HDR_FL__ << "ARTDAQBUILDER SUPERVISOR INIT ERROR!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
113  mf::LogError("EventBuilderMain") << errormsg ;
114  mf::LogError("EventBuilderMain") << "MPISentry error encountered in EventBuilderMain; exiting...";
115  throw errormsg;
116  }
117 
118  std::cout << __COUT_HDR_FL__ << "ARTDAQBUILDER SUPERVISOR NO ERRORS MAKING MSG FACILITY!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
119  std::string name = "Builder";
120  unsigned short port = 5200;
121  //artdaq::setMsgFacAppName(supervisorApplicationUID_, port);
122  artdaq::setMsgFacAppName(name, port);
123  std::cout << __COUT_HDR_FL__ << "ARTDAQBUILDER SUPERVISOR MSG FACILITY DONE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
124  mf::LogDebug(name + "Supervisor") << "artdaq version " <<
125 // mf::LogDebug(supervisorApplicationUID_) << " artdaq version " <<
126  artdaq::GetPackageBuildInfo::getPackageBuildInfo().getPackageVersion()
127  << ", built " <<
128  artdaq::GetPackageBuildInfo::getPackageBuildInfo().getBuildTimestamp();
129 
130  // create the EventBuilderInterface
131  //theARTDAQEventBuilderInterfaces_[0] = new EventBuilderInterface(mpiSentry_->rank(), local_group_comm, name );
132  theARTDAQEventBuilderInterfaces_[0] = new EventBuilderInterface(mpiSentry_->rank(), name );
133  //theARTDAQEventBuilderInterfaces_[0] = new EventBuilderInterface(mpiSentry_->rank(), local_group_comm, supervisorApplicationUID_ );
134  std::cout << __COUT_HDR_FL__ << "ARTDAQBUILDER SUPERVISOR INIT DONE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
135 }
136 
137 //========================================================================================================================
138 void EventBuilderApp::destroy(void)
139 {
140  //called by destructor
141  mpiSentry_.reset();
142 }
143 
144 //========================================================================================================================
145 void EventBuilderApp::Default(xgi::Input * in, xgi::Output * out )
146 throw (xgi::exception::Exception)
147 {
148 
149  *out << "<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame src='/WebPath/html/EventBuilderApp.html?urn=" <<
150  this->getApplicationDescriptor()->getLocalId() <<"'></frameset></html>";
151 }
152 
153 //========================================================================================================================
154 void EventBuilderApp::stateMachineXgiHandler(xgi::Input * in, xgi::Output * out )
155 throw (xgi::exception::Exception)
156 {}
157 
158 //========================================================================================================================
159 void EventBuilderApp::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out )
160 throw (xgi::exception::Exception)
161 {}
162 
163 //========================================================================================================================
164 xoap::MessageReference EventBuilderApp::stateMachineXoapHandler(xoap::MessageReference message )
165 throw (xoap::exception::Exception)
166 {
167  std::cout << __COUT_HDR_FL__ << "Soap Handler!" << std::endl;
168  stateMachineWorkLoopManager_.removeProcessedRequests();
169  stateMachineWorkLoopManager_.processRequest(message);
170  std::cout << __COUT_HDR_FL__ << "Done - Soap Handler!" << std::endl;
171  return message;
172 }
173 
174 //========================================================================================================================
175 xoap::MessageReference EventBuilderApp::stateMachineResultXoapHandler(xoap::MessageReference message )
176 throw (xoap::exception::Exception)
177 {
178  std::cout << __COUT_HDR_FL__ << "Soap Handler!" << std::endl;
179  //stateMachineWorkLoopManager_.removeProcessedRequests();
180  //stateMachineWorkLoopManager_.processRequest(message);
181  std::cout << __COUT_HDR_FL__ << "Done - Soap Handler!" << std::endl;
182  return message;
183 }
184 
185 //========================================================================================================================
186 bool EventBuilderApp::stateMachineThread(toolbox::task::WorkLoop* workLoop)
187 {
188  stateMachineSemaphore_.take();
189  std::cout << __COUT_HDR_FL__ << "Re-sending message..." << SOAPUtilities::translate(stateMachineWorkLoopManager_.getMessage(workLoop)).getCommand() << std::endl;
190  std::string reply = send(this->getApplicationDescriptor(),stateMachineWorkLoopManager_.getMessage(workLoop));
191  stateMachineWorkLoopManager_.report(workLoop, reply, 100, true);
192  std::cout << __COUT_HDR_FL__ << "Done with message" << std::endl;
193  stateMachineSemaphore_.give();
194  return false;//execute once and automatically remove the workloop so in WorkLoopManager the try workLoop->remove(job_) could be commented out
195  //return true;//go on and then you must do the workLoop->remove(job_) in WorkLoopManager
196 }
197 
198 //========================================================================================================================
199 xoap::MessageReference EventBuilderApp::stateMachineStateRequest(xoap::MessageReference message)
200 throw (xoap::exception::Exception)
201 {
202  std::cout << __COUT_HDR_FL__ << theStateMachine_.getCurrentStateName() << std::endl;
203  return SOAPUtilities::makeSOAPMessageReference(theStateMachine_.getCurrentStateName());
204 }
205 
206 //========================================================================================================================
207 void EventBuilderApp::stateInitial(toolbox::fsm::FiniteStateMachine& fsm)
208 throw (toolbox::fsm::exception::Exception)
209 {
210 
211 }
212 
213 //========================================================================================================================
214 void EventBuilderApp::stateHalted(toolbox::fsm::FiniteStateMachine& fsm)
215 throw (toolbox::fsm::exception::Exception)
216 {
217 
218 }
219 
220 //========================================================================================================================
221 void EventBuilderApp::stateRunning(toolbox::fsm::FiniteStateMachine& fsm)
222 throw (toolbox::fsm::exception::Exception)
223 {
224 
225 }
226 
227 //========================================================================================================================
228 void EventBuilderApp::stateConfigured(toolbox::fsm::FiniteStateMachine& fsm)
229 throw (toolbox::fsm::exception::Exception)
230 {
231 
232 }
233 
234 //========================================================================================================================
235 void EventBuilderApp::statePaused(toolbox::fsm::FiniteStateMachine& fsm)
236 throw (toolbox::fsm::exception::Exception)
237 {
238 
239 }
240 
241 //========================================================================================================================
242 void EventBuilderApp::inError (toolbox::fsm::FiniteStateMachine & fsm)
243 throw (toolbox::fsm::exception::Exception)
244 {
245  std::cout << __COUT_HDR_FL__ << "Fsm current state: " << theStateMachine_.getCurrentStateName()<< std::endl;
246  //rcmsStateNotifier_.stateChanged("Error", "");
247 }
248 
249 //========================================================================================================================
250 void EventBuilderApp::enteringError (toolbox::Event::Reference e)
251 throw (toolbox::fsm::exception::Exception)
252 {
253  std::cout << __COUT_HDR_FL__ << "Fsm current state: " << theStateMachine_.getCurrentStateName()<< std::endl;
254  toolbox::fsm::FailedEvent& failedEvent = dynamic_cast<toolbox::fsm::FailedEvent&>(*e);
255  std::ostringstream error;
256  error << "Failure performing transition from "
257  << failedEvent.getFromState()
258  << " to "
259  << failedEvent.getToState()
260  << " exception: " << failedEvent.getException().what();
261  std::cout << __COUT_HDR_FL__ << error.str() << std::endl;
262  //diagService_->reportError(errstr.str(),DIAGERROR);
263 
264 }
265 
266 #define ARTDAQ_FCL_PATH std::string(getenv("USER_DATA")) + "/"+ "ARTDAQConfigurations/"
267 #define ARTDAQ_FILE_PREAMBLE "builder"
268 
269 //========================================================================================================================
270 void EventBuilderApp::transitionConfiguring(toolbox::Event::Reference e)
271 throw (toolbox::fsm::exception::Exception)
272 {
273 
274  std::cout << __COUT_HDR_FL__ << "ARTDAQBUILDER SUPERVISOR CONFIGURING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
275  std::cout << __COUT_HDR_FL__ << SOAPUtilities::translate(theStateMachine_.getCurrentMessage()) << std::endl;
276 
277 
278  std::pair<std::string /*group name*/, ConfigurationGroupKey> theGroup(
279  SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).
280  getParameters().getValue("ConfigurationGroupName"),
281  ConfigurationGroupKey(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).
282  getParameters().getValue("ConfigurationGroupKey")));
283 
284  __MOUT__ << "Configuration group name: " << theGroup.first << " key: " <<
285  theGroup.second << std::endl;
286 
287  theConfigurationManager_->loadConfigurationGroup(
288  theGroup.first,
289  theGroup.second, true);
290 
291  //theConfigurationManager_->setupEventBuilderAppConfiguration(theConfigurationGroupKey_,supervisorInstance_);
292 
293  //Now that the configuration manager has all the necessary configurations I can create all objects dependent of the configuration
294  //std::string configString = "daq:{event_builder:{expected_fragments_per_event:2 first_fragment_receiver_rank:0 fragment_receiver_count:2 mpi_buffer_count:16 print_event_store_stats:true send_triggers:true trigger_port:5001 use_art:true verbose:false} max_fragment_size_words:2.097152e6} outputs:{netMonOutput:{module_type:\"NetMonOutput\"}} physics:{my_output_modules:[\"netMonOutput\"]} process_name:\"DAQ\" services:{Timing:{summaryOnly:true} scheduler:{fileMode:\"NOMERGE\"} user:{NetMonTransportServiceInterface:{data_receiver_count:1 first_data_receiver_rank:4 max_fragment_size_words:2.097152e6 mpi_buffer_count:8 service_provider:\"NetMonTransportService\"}}} source:{fragment_type_map:[[1,\"UDP\"]] module_type:\"RawInput\" resume_after_timeout:true waiting_time:900}";
295 
296  //ONLY 1 BOARD READER IN THE SYSTEM
297  //std::string configString = "daq:{event_builder:{expected_fragments_per_event:1 first_fragment_receiver_rank:0 fragment_receiver_count:1 mpi_buffer_count:16 print_event_store_stats:true send_triggers:true trigger_port:5001 use_art:true verbose:false} max_fragment_size_words:2.097152e6} outputs:{netMonOutput:{module_type:\"RootMPIOutput\"}} physics:{analyzers:{wf: {module_type:\"WFViewer\" fragment_ids:[0] fragment_type_labels:[ \"DataGen\" ] prescale:60 write_to_file:true fileName:\"/tmp/otsdaqdemo_onmon_evb.root\"}} a1:[\"wf\"] my_output_modules:[\"netMonOutput\"]} process_name:\"DAQ\" services:{Timing:{summaryOnly:true} scheduler:{fileMode:\"NOMERGE\" errorOnFailureToPut: false} user:{NetMonTransportServiceInterface:{data_receiver_count:1 first_data_receiver_rank:2 max_fragment_size_words:2.097152e6 mpi_buffer_count:8 service_provider:\"NetMonTransportService\"}}} source:{fragment_type_map:[[1,\"UDP\"], [4,\"DataGen\"]] module_type:\"RawInput\" resume_after_timeout:true waiting_time:900}";
298 
299  //2 BOARD READERS IN THE SYSTEM
300  //std::string configString = "daq:{event_builder:{expected_fragments_per_event:1 first_fragment_receiver_rank:0 fragment_receiver_count:1 mpi_buffer_count:16 print_event_store_stats:true send_triggers:true trigger_port:5001 use_art:true verbose:false} max_fragment_size_words:2.097152e6} outputs:{netMonOutput:{module_type:\"RootMPIOutput\"}} physics:{analyzers:{wf: {module_type:\"WFViewer\" fragment_ids:[0] fragment_type_labels:[ \"DataGen\" ] prescale:60 write_to_file:true fileName:\"/tmp/otsdaqdemo_onmon_evb.root\"}} a1:[\"wf\"] my_output_modules:[\"netMonOutput\"]} process_name:\"DAQ\" services:{Timing:{summaryOnly:true} scheduler:{fileMode:\"NOMERGE\" errorOnFailureToPut: false} user:{NetMonTransportServiceInterface:{data_receiver_count:1 first_data_receiver_rank:2 max_fragment_size_words:2.097152e6 mpi_buffer_count:8 service_provider:\"NetMonTransportService\"}}} source:{fragment_type_map:[[1,\"UDP\"], [4,\"DataGen\"]] module_type:\"RawInput\" resume_after_timeout:true waiting_time:900}";
301 
302  //__MOUT__ << configString << std::endl;
303  __MOUT__ << std::endl;
304  __MOUT__ << std::endl;
305  //__MOUT__ << theConfigurationManager_->getNode(XDAQContextConfigurationName_).getNode(supervisorConfigurationPath_).getNode("ConfigurationString").getValue<std::string>() << std::endl;
306  fhicl::ParameterSet pset;
307  //fhicl::make_ParameterSet(configString, pset);
308 
309 
310  std::string filename = ARTDAQ_FCL_PATH + ARTDAQ_FILE_PREAMBLE + "-";
311  std::string uid = theConfigurationManager_->getNode(XDAQContextConfigurationName_).getNode(supervisorConfigurationPath_).getValue();
312 
313  __MOUT__ << "uid: " << uid << std::endl;
314  for(unsigned int i=0;i<uid.size();++i)
315  if((uid[i] >= 'a' && uid[i] <= 'z') ||
316  (uid[i] >= 'A' && uid[i] <= 'Z') ||
317  (uid[i] >= '0' && uid[i] <= '9')) //only allow alpha numeric in file name
318  filename += uid[i];
319  filename += ".fcl";
320 
321  __MOUT__ << "filename: " << filename << std::endl;
322 
323  std::string fileFclString;
324  {
325  std::ifstream in(filename, std::ios::in | std::ios::binary);
326  if (in)
327  {
328  std::string contents;
329  in.seekg(0, std::ios::end);
330  fileFclString.resize(in.tellg());
331  in.seekg(0, std::ios::beg);
332  in.read(&fileFclString[0], fileFclString.size());
333  in.close();
334  }
335  }
336  __MOUT__ << fileFclString << std::endl;
337  fhicl::make_ParameterSet(fileFclString, pset);
338 
339  //fhicl::make_ParameterSet(theConfigurationManager_->getNode(XDAQContextConfigurationName_).getNode(supervisorConfigurationPath_).getNode("ConfigurationString").getValue<std::string>(), pset);
340 
341  for(std::map<int,EventBuilderInterface*>::iterator it=theARTDAQEventBuilderInterfaces_.begin(); it!=theARTDAQEventBuilderInterfaces_.end(); it++)
342  it->second->configure(pset);
343  std::cout << __COUT_HDR_FL__ << "ARTDAQBUILDER SUPERVISOR DONE CONFIGURING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
344 
345 }
346 
347 //========================================================================================================================
348 void EventBuilderApp::transitionHalting(toolbox::Event::Reference e)
349 throw (toolbox::fsm::exception::Exception)
350 {
351 
352  for(auto it=theARTDAQEventBuilderInterfaces_.begin(); it!=theARTDAQEventBuilderInterfaces_.end(); it++)
353  it->second->halt();
354 }
355 
356 //========================================================================================================================
357 void EventBuilderApp::transitionInitializing(toolbox::Event::Reference e)
358 throw (toolbox::fsm::exception::Exception)
359 {
360 
361 }
362 
363 //========================================================================================================================
364 void EventBuilderApp::transitionPausing(toolbox::Event::Reference e)
365 throw (toolbox::fsm::exception::Exception)
366 {
367 
368  for(std::map<int,EventBuilderInterface*>::iterator it=theARTDAQEventBuilderInterfaces_.begin(); it!=theARTDAQEventBuilderInterfaces_.end(); it++)
369  it->second->pause();
370 }
371 
372 //========================================================================================================================
373 void EventBuilderApp::transitionResuming(toolbox::Event::Reference e)
374 throw (toolbox::fsm::exception::Exception)
375 {
376 
377  for(std::map<int,EventBuilderInterface*>::iterator it=theARTDAQEventBuilderInterfaces_.begin(); it!=theARTDAQEventBuilderInterfaces_.end(); it++)
378  it->second->resume();
379 }
380 
381 //========================================================================================================================
382 void EventBuilderApp::transitionStarting(toolbox::Event::Reference e)
383 throw (toolbox::fsm::exception::Exception)
384 {
385 
386  for(std::map<int,EventBuilderInterface*>::iterator it=theARTDAQEventBuilderInterfaces_.begin(); it!=theARTDAQEventBuilderInterfaces_.end(); it++)
387  it->second->start(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).getParameters().getValue("RunNumber"));
388 }
389 
390 //========================================================================================================================
391 void EventBuilderApp::transitionStopping(toolbox::Event::Reference e)
392 throw (toolbox::fsm::exception::Exception)
393 {
394 
395  for(std::map<int,EventBuilderInterface*>::iterator it=theARTDAQEventBuilderInterfaces_.begin(); it!=theARTDAQEventBuilderInterfaces_.end(); it++)
396  it->second->stop();
397 
398  for(std::map<int,EventBuilderInterface*>::iterator it=theARTDAQEventBuilderInterfaces_.begin(); it!=theARTDAQEventBuilderInterfaces_.end(); it++)
399  it->second->halt();
400 }