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