otsdaq  v2_05_02_indev
ARTDAQReaderProcessorBase.cc
1 #include "otsdaq/ARTDAQReaderCore/ARTDAQReaderProcessorBase.h"
2 #include "artdaq/Application/Commandable.hh"
3 #include "fhiclcpp/make_ParameterSet.h"
4 #include "otsdaq/DataManager/DataManager.h"
5 #include "otsdaq/DataManager/DataManagerSingleton.h"
6 #include "otsdaq/Macros/CoutMacros.h"
7 //#include "otsdaq/Macros/ProcessorPluginMacros.h"
8 #include "otsdaq/MessageFacility/MessageFacility.h"
9 
10 #include <cstdint>
11 #include <fstream>
12 #include <iostream>
13 #include <set>
14 
15 using namespace ots;
16 
17 #define ARTDAQ_FCL_PATH std::string(__ENV__("USER_DATA")) + "/" + "ARTDAQConfigurations/"
18 #define ARTDAQ_FILE_PREAMBLE "boardReader"
19 
20 //==============================================================================
21 ARTDAQReaderProcessorBase::ARTDAQReaderProcessorBase(std::string /*supervisorApplicationUID*/,
22  std::string /*bufferUID*/,
23  std::string processorUID,
24  const ConfigurationTree& theXDAQContextConfigTree,
25  const std::string& configurationPath)
26  // : WorkLoop(processorUID)
27  // , DataProducer(supervisorApplicationUID, bufferUID, processorUID)
28  // theXDAQContextConfigTree.getNode(configurationPath).getNode("BufferSize").getValue<unsigned
29  // int>())
30  : Configurable(theXDAQContextConfigTree, configurationPath), name_("BoardReader_" + processorUID)
31 {
32  INIT_MF("." /*directory used is USER_DATA/LOG/.*/);
33 
34  __CFG_COUT__ << "Constructing..." << __E__;
35  //__CFG_COUT__ << "Configuration string:-" <<
36  // theXDAQContextConfigTree.getNode(configurationPath).getNode("ConfigurationString").getValue<std::string>()
37  //<< "-" << __E__;
38 
39  std::string filename = ARTDAQ_FCL_PATH + ARTDAQ_FILE_PREAMBLE + "-";
40  std::string uid = theXDAQContextConfigTree.getNode(configurationPath).getValue();
41 
42  __CFG_COUT__ << "uid: " << uid << __E__;
43  for(unsigned int i = 0; i < uid.size(); ++i)
44  if((uid[i] >= 'a' && uid[i] <= 'z') || (uid[i] >= 'A' && uid[i] <= 'Z') || (uid[i] >= '0' && uid[i] <= '9')) // only allow alpha numeric in file name
45  filename += uid[i];
46  filename += ".fcl";
47 
48  __CFG_COUT__ << __E__;
49  __CFG_COUT__ << __E__;
50  __CFG_COUT__ << "filename: " << filename << __E__;
51 
52  std::string fileFclString;
53  {
54  std::ifstream in(filename, std::ios::in | std::ios::binary);
55  if(in)
56  {
57  std::string contents;
58  in.seekg(0, std::ios::end);
59  fileFclString.resize(in.tellg());
60  in.seekg(0, std::ios::beg);
61  in.read(&fileFclString[0], fileFclString.size());
62  in.close();
63  }
64  }
65  //__CFG_COUT__ << fileFclString << __E__;
66 
67  // find fragment_receiver {
68  // and insert e.g.,
69  // SupervisorApplicationUID:"ARTDataManager0"
70  // BufferUID:"ART_S0_DM0_DataBuffer0"
71  // ProcessorUID:"ART_S0_DM0_DB0_ARTConsumer0"
72  size_t fcli = fileFclString.find("fragment_receiver: {") + +strlen("fragment_receiver: {");
73  if(fcli == std::string::npos)
74  {
75  __SS__ << "Could not find 'fragment_receiver: {' in Board Reader fcl string!" << __E__;
76  __CFG_COUT__ << "\n" << ss.str();
77  __SS_THROW__;
78  }
79 
80  // get the parent IDs from configurationPath
81  __CFG_COUT__ << "configurationPath " << configurationPath << __E__;
82 
83  std::string consumerID, bufferID, appID;
84  unsigned int backSteps; // at 2, 4, and 7 are the important parent IDs
85  size_t backi = -1, backj;
86  backSteps = 7;
87  for(unsigned int i = 0; i < backSteps; i++)
88  {
89  //__CFG_COUT__ << "backsteps: " << i+1 << __E__;
90 
91  backj = backi;
92  backi = configurationPath.rfind('/', backi - 1);
93 
94  //__CFG_COUT__ << "backi:" << backi << " backj:" << backj << __E__;
95  //__CFG_COUT__ << "substr: " << configurationPath.substr(backi+1,backj-backi-1) <<
96  // __E__;
97 
98  if(i + 1 == 2)
99  consumerID = configurationPath.substr(backi + 1, backj - backi - 1);
100  else if(i + 1 == 4)
101  bufferID = configurationPath.substr(backi + 1, backj - backi - 1);
102  else if(i + 1 == 7)
103  appID = configurationPath.substr(backi + 1, backj - backi - 1);
104  }
105 
106  // insert parent IDs into fcl string
107  fileFclString = fileFclString.substr(0, fcli) + "\n\t\t" + "SupervisorApplicationUID: \"" + appID + "\"\n\t\t" + "BufferUID: \"" + bufferID + "\"\n\t\t" +
108  "ProcessorUID: \"" + consumerID + "\"\n" + fileFclString.substr(fcli);
109 
110  __CFG_COUT__ << fileFclString << __E__;
111 
112  try
113  {
114  fhicl::make_ParameterSet(fileFclString, fhiclConfiguration_);
115  }
116  catch(const cet::coded_exception<fhicl::error, &fhicl::detail::translate>& e)
117  {
118  __CFG_SS__ << "Error was caught while configuring: " << e.what() << __E__;
119  __CFG_SS_THROW__;
120  }
121  catch(const cet::exception& e)
122  {
123  __CFG_SS__ << "Error was caught while configuring: " << e.explain_self() << __E__;
124  __CFG_SS_THROW__;
125  }
126  catch(...)
127  {
128  __CFG_SS__ << "Unknown error was caught while configuring." << __E__;
129  __CFG_SS_THROW__;
130  }
131 
132  // fhicl::make_ParameterSet(theXDAQContextConfigTree.getNode(configurationPath).getNode("ConfigurationString").getValue<std::string>(),
133  // fhiclConfiguration_);
134 
135 } // end constructor()
136 
137 //==============================================================================
138 // ARTDAQReaderProcessorBase::ARTDAQReaderProcessorBase(std::string interfaceID, MPI_Comm
139 // local_group_comm, std::string name) :FEVInterface (feId, 0)
140 // ,local_group_comm_(local_group_comm)
141 //,name_ (name)
142 //{}
143 
144 //==============================================================================
145 ARTDAQReaderProcessorBase::~ARTDAQReaderProcessorBase(void)
146 {
147  halt();
148  __CFG_COUT__ << "DONE DELETING!" << __E__;
149 }
150 
151 //==============================================================================
152 void ARTDAQReaderProcessorBase::initLocalGroup(int rank) { configure(rank); }
153 
154 #define ARTDAQ_FCL_PATH std::string(__ENV__("USER_DATA")) + "/" + "ARTDAQConfigurations/"
155 #define ARTDAQ_FILE_PREAMBLE "boardReader"
156 
157 //==============================================================================
158 void ARTDAQReaderProcessorBase::configure(int rank)
159 {
160  __CFG_COUT__ << "Configuring..." << __E__;
161 
162  // in the following block, we first destroy the existing BoardReader
163  // instance, then create a new one. Doing it in one step does not
164  // produce the desired result since that creates a new instance and
165  // then deletes the old one, and we need the opposite order.
166  fragment_receiver_ptr_.reset(nullptr);
167  __CFG_COUT__ << "New core" << __E__;
168  my_rank = rank;
169  app_name = name_;
170  fragment_receiver_ptr_.reset(new artdaq::BoardReaderApp());
171 
172  // FIXME These are passed as parameters
173  // should they come from the Configuration Tree?
174  uint64_t timeout = 45;
175  uint64_t timestamp = 184467440737095516;
176  __CFG_COUT__ << "Initializing '" << name_ << "'" << __E__; //<< fhiclConfiguration_.to_string() << __E__;
177 
178  if(!fragment_receiver_ptr_->initialize(fhiclConfiguration_, timeout, timestamp))
179  {
180  __CFG_SS__ << "Error initializing '" << name_ << "' with ParameterSet = \n" << fhiclConfiguration_.to_string() << __E__;
181  ss << "Here is the Board Reader report: \n" << fragment_receiver_ptr_->report("" /* or "transition_status" */) << __E__;
182  __CFG_SS_THROW__;
183  }
184  __CFG_COUT__ << "Done Initializing." << __E__;
185 
186  // do any other configure steps here
187 
188  __CFG_COUT__ << "Configured." << __E__;
189 } // end configure()
190 
191 //==============================================================================
192 void ARTDAQReaderProcessorBase::halt(void)
193 {
194  __CFG_COUT__ << "Halting..." << __E__;
195 
196  // FIXME These are passed as parameters
197  // should they come from the Configuration Tree?
198  uint64_t timeout = 45;
199 
200  if(!fragment_receiver_ptr_->shutdown(timeout))
201  {
202  __CFG_SS__ << "Error shutting down '" << name_ << ".'" << __E__;
203  __CFG_SS_THROW__;
204  }
205 
206  __CFG_COUT__ << "Halted." << __E__;
207 } // end halt()
208 
209 //==============================================================================
210 void ARTDAQReaderProcessorBase::pause(void)
211 {
212  __CFG_COUT__ << "Pausing..." << __E__;
213 
214  // FIXME These are passed as parameters
215  // should they come from the Configuration Tree?
216  uint64_t timeout = 45;
217  uint64_t timestamp = 184467440737095516;
218 
219  if(!fragment_receiver_ptr_->pause(timeout, timestamp))
220  {
221  __CFG_SS__ << "Error pausing '" << name_ << ".'" << __E__;
222  __CFG_SS_THROW__;
223  }
224 
225  __CFG_COUT__ << "Paused." << __E__;
226 } // end pause()
227 
228 //==============================================================================
229 void ARTDAQReaderProcessorBase::resume(void)
230 {
231  __CFG_COUT__ << "Resuming..." << __E__;
232 
233  // FIXME These are passed as parameters
234  // should they come from the Configuration Tree?
235  uint64_t timeout = 45;
236  uint64_t timestamp = 184467440737095516;
237 
238  if(!fragment_receiver_ptr_->resume(timeout, timestamp))
239  {
240  __CFG_SS__ << "Error resuming '" << name_ << ".'" << __E__;
241  __CFG_SS_THROW__;
242  }
243 
244  __CFG_COUT__ << "Resumed." << __E__;
245 } // end resume ()
246 
247 //==============================================================================
248 void ARTDAQReaderProcessorBase::start(const std::string& runNumber)
249 {
250  __CFG_COUT__ << "Starting..." << __E__;
251 
252  art::RunID runId((art::RunNumber_t)boost::lexical_cast<art::RunNumber_t>(runNumber));
253 
254  // FIXME These are passed as parameters
255  // should they come from the Configuration Tree?
256  uint64_t timeout = 45;
257  uint64_t timestamp = 184467440737095516;
258 
259  __CFG_COUT__ << "Start run: " << runId << __E__;
260  if(!fragment_receiver_ptr_->start(runId, timeout, timestamp))
261  {
262  __CFG_SS__ << "Error starting '" << name_ << "' for run number '" << runId << ",'" << __E__;
263  __CFG_SS_THROW__;
264  }
265 
266  __CFG_COUT__ << "Started." << __E__;
267 } // end start()
268 
269 //==============================================================================
270 void ARTDAQReaderProcessorBase::stop(void)
271 {
272  __CFG_COUT__ << "Stop" << __E__;
273 
274  // FIXME These are passed as parameters
275  // should they come from the Configuration Tree?
276  uint64_t timeout = 45;
277  uint64_t timestamp = 184467440737095516;
278 
279  auto sts = fragment_receiver_ptr_->status();
280  if(sts == "Ready")
281  {
282  __CFG_COUT__ << "Already stopped - never started!" << __E__;
283  return; // Already stopped/never started
284  }
285 
286  if(!fragment_receiver_ptr_->stop(timeout, timestamp))
287  {
288  __CFG_SS__ << "Error stopping '" << name_ << ".'" << __E__;
289  __CFG_SS_THROW__;
290  }
291 
292  __CFG_COUT__ << "Stopped." << __E__;
293 } // end stop()