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