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