otsdaq  v1_01_03
 All Classes Namespaces Functions
ARTDAQProducer_processor.cc
1 #include "otsdaq-core/DataProcessorPlugins/ARTDAQProducer.h"
2 #include "otsdaq-core/MessageFacility/MessageFacility.h"
3 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
4 #include "artdaq/Application/Commandable.hh"
5 #include "otsdaq-core/Macros/ProcessorPluginMacros.h"
6 #include "fhiclcpp/make_ParameterSet.h"
7 #include "otsdaq-core/DataManager/DataManagerSingleton.h"
8 #include "otsdaq-core/DataManager/DataManager.h"
9 
10 
11 #include <fstream>
12 #include <iostream>
13 #include <cstdint>
14 #include <set>
15 
16 using namespace ots;
17 
18 #define ARTDAQ_FCL_PATH std::string(getenv("USER_DATA")) + "/"+ "ARTDAQConfigurations/"
19 #define ARTDAQ_FILE_PREAMBLE "boardReader"
20 
21 //========================================================================================================================
22 ARTDAQProducer::ARTDAQProducer (std::string supervisorApplicationUID, std::string bufferUID, std::string processorUID, const ConfigurationTree& theXDAQContextConfigTree, const std::string& configurationPath)
23 : WorkLoop (processorUID)
24 , DataProducer (supervisorApplicationUID, bufferUID,
25  processorUID)
26  //theXDAQContextConfigTree.getNode(configurationPath).getNode("BufferSize").getValue<unsigned int>())
27 , Configurable (theXDAQContextConfigTree, configurationPath)
28 {
29  __MOUT__ << "ARTDAQ PRODUCER CONSTRUCTOR!!!" << std::endl;
30  //__MOUT__ << "Configuration string:-" << theXDAQContextConfigTree.getNode(configurationPath).getNode("ConfigurationString").getValue<std::string>() << "-" << std::endl;
31 
32 
33  std::string filename = ARTDAQ_FCL_PATH + ARTDAQ_FILE_PREAMBLE + "-";
34  std::string uid = theXDAQContextConfigTree.getNode(configurationPath).getValue();
35 
36  __MOUT__ << "uid: " << uid << std::endl;
37  for(unsigned int i=0;i<uid.size();++i)
38  if((uid[i] >= 'a' && uid[i] <= 'z') ||
39  (uid[i] >= 'A' && uid[i] <= 'Z') ||
40  (uid[i] >= '0' && uid[i] <= '9')) //only allow alpha numeric in file name
41  filename += uid[i];
42  filename += ".fcl";
43 
44  __MOUT__ << std::endl;
45  __MOUT__ << std::endl;
46  __MOUT__ << "filename: " << filename << std::endl;
47 
48  std::string fileFclString;
49  {
50  std::ifstream in(filename, std::ios::in | std::ios::binary);
51  if (in)
52  {
53  std::string contents;
54  in.seekg(0, std::ios::end);
55  fileFclString.resize(in.tellg());
56  in.seekg(0, std::ios::beg);
57  in.read(&fileFclString[0], fileFclString.size());
58  in.close();
59  }
60  }
61  //__MOUT__ << fileFclString << std::endl;
62 
63  //find fragment_receiver {
64  // and insert e.g.,
65  // SupervisorApplicationUID:"ARTDataManager0"
66  // BufferUID:"ART_S0_DM0_DataBuffer0"
67  // ProcessorUID:"ART_S0_DM0_DB0_ARTConsumer0"
68  size_t fcli = fileFclString.find("fragment_receiver: {") +
69  +strlen("fragment_receiver: {");
70  if(fcli == std::string::npos)
71  {
72  __SS__ << "Could not find 'fragment_receiver: {' in Board Reader fcl string!" << std::endl;
73  __MOUT__ << "\n" << ss.str();
74  throw std::runtime_error(ss.str());
75  }
76 
77  //get the parent IDs from configurationPath
78  __MOUT__ << "configurationPath " << configurationPath << std::endl;
79 
80  std::string consumerID, bufferID, appID;
81  unsigned int backSteps; //at 2, 4, and 7 are the important parent IDs
82  size_t backi = -1, backj;
83  backSteps = 7;
84  for(unsigned int i=0; i<backSteps; i++)
85  {
86  //__MOUT__ << "backsteps: " << i+1 << std::endl;
87 
88  backj = backi;
89  backi = configurationPath.rfind('/',backi-1);
90 
91  //__MOUT__ << "backi:" << backi << " backj:" << backj << std::endl;
92  //__MOUT__ << "substr: " << configurationPath.substr(backi+1,backj-backi-1) << std::endl;
93 
94  if(i+1 == 2)
95  consumerID = configurationPath.substr(backi+1,backj-backi-1);
96  else if(i+1 == 4)
97  bufferID = configurationPath.substr(backi+1,backj-backi-1);
98  else if(i+1 == 7)
99  appID = configurationPath.substr(backi+1,backj-backi-1);
100  }
101 
102  //insert parent IDs into fcl string
103  fileFclString = fileFclString.substr(0,fcli) + "\n\t\t" +
104  "SupervisorApplicationUID: \"" + appID + "\"\n\t\t" +
105  "BufferUID: \"" + bufferID + "\"\n\t\t" +
106  "ProcessorUID: \"" + consumerID + "\"\n" +
107  fileFclString.substr(fcli);
108 
109  __MOUT__ << fileFclString << std::endl;
110 
111  fhicl::make_ParameterSet(fileFclString, fhiclConfiguration_);
112 
113 
114  //fhicl::make_ParameterSet(theXDAQContextConfigTree.getNode(configurationPath).getNode("ConfigurationString").getValue<std::string>(), fhiclConfiguration_);
115 }
116 
117 //========================================================================================================================
118 //ARTDAQProducer::ARTDAQProducer(std::string interfaceID, MPI_Comm local_group_comm, std::string name)
119 //:FEVInterface (feId, 0)
120 //,local_group_comm_(local_group_comm)
121 //,name_ (name)
122 //{}
123 
124 //========================================================================================================================
125 ARTDAQProducer::~ARTDAQProducer(void)
126 {
127  halt();
128  __MOUT__ << "DONE DELETING!" << std::endl;
129 }
130 
131 //========================================================================================================================
132 void ARTDAQProducer::initLocalGroup(int rank)
133 {
134  name_ = "BoardReader_" + DataProducer::processorUID_;
135  configure(rank);
136 }
137 
138 #define ARTDAQ_FCL_PATH std::string(getenv("USER_DATA")) + "/"+ "ARTDAQConfigurations/"
139 #define ARTDAQ_FILE_PREAMBLE "boardReader"
140 
141 //========================================================================================================================
142 void ARTDAQProducer::configure(int rank)
143 {
144  std::cout << __COUT_HDR_FL__ << "\tConfigure" << std::endl;
145 
146  report_string_ = "";
147  external_request_status_ = true;
148 
149  // in the following block, we first destroy the existing BoardReader
150  // instance, then create a new one. Doing it in one step does not
151  // produce the desired result since that creates a new instance and
152  // then deletes the old one, and we need the opposite order.
153  artdaq::Commandable tmpCommandable;
154  fragment_receiver_ptr_.reset(nullptr);
155  std::cout << __COUT_HDR_FL__ << "\tNew core" << std::endl;
156  fragment_receiver_ptr_.reset(new artdaq::BoardReaderCore(tmpCommandable, rank, name_));
157  //FIXME These are passed as parameters
158  uint64_t timeout = 45;
159  //uint64_t timestamp = 184467440737095516;
160  uint64_t timestamp = 184467440737095516;
161  std::cout << __COUT_HDR_FL__ << "\tInitialize: " << std::endl;//<< fhiclConfiguration_.to_string() << std::endl;
162  external_request_status_ = fragment_receiver_ptr_->initialize(fhiclConfiguration_, timeout, timestamp);
163  std::cout << __COUT_HDR_FL__ << "\tDone Initialize" << std::endl;
164  if (! external_request_status_)
165  {
166  report_string_ = "Error initializing ";
167  report_string_.append(name_ + " ");
168  report_string_.append("with ParameterSet = \"" + fhiclConfiguration_.to_string() + "\".");
169  }
170  std::cout << __COUT_HDR_FL__ << "\tDone Configure" << std::endl;
171 }
172 
173 //========================================================================================================================
174 void ARTDAQProducer::halt(void)
175 {
176  std::cout << __COUT_HDR_FL__ << "\tHalt" << std::endl;
177  //FIXME These are passed as parameters
178  uint64_t timeout = 45;
179  //uint64_t timestamp = 184467440737095516;
180  report_string_ = "";
181  external_request_status_ = fragment_receiver_ptr_->shutdown(timeout);
182  if (! external_request_status_)
183  {
184  report_string_ = "Error shutting down ";
185  report_string_.append(name_ + ".");
186  }
187 }
188 
189 //========================================================================================================================
190 void ARTDAQProducer::pauseProcessingData(void)
191 {
192  std::cout << __COUT_HDR_FL__ << "\tPause" << std::endl;
193  //FIXME These are passed as parameters
194  uint64_t timeout = 45;
195  uint64_t timestamp = 184467440737095516;
196  report_string_ = "";
197  external_request_status_ = fragment_receiver_ptr_->pause(timeout, timestamp);
198  if (! external_request_status_)
199  {
200  report_string_ = "Error pausing ";
201  report_string_.append(name_ + ".");
202  }
203 
204  if (fragment_processing_future_.valid())
205  {
206  int number_of_fragments_sent = fragment_processing_future_.get();
207  mf::LogDebug(name_+"App::do_pause(uint64_t, uint64_t)")
208  << "Number of fragments sent = " << number_of_fragments_sent
209  << ".";
210  }
211 }
212 
213 //========================================================================================================================
214 void ARTDAQProducer::resumeProcessingData(void)
215 {
216  std::cout << __COUT_HDR_FL__ << "\tResume" << std::endl;
217  //FIXME These are passed as parameters
218  uint64_t timeout = 45;
219  uint64_t timestamp = 184467440737095516;
220  report_string_ = "";
221  external_request_status_ = fragment_receiver_ptr_->resume(timeout, timestamp);
222  if (! external_request_status_)
223  {
224  report_string_ = "Error resuming ";
225  report_string_.append(name_ + ".");
226  }
227 
228  fragment_processing_future_ = std::async(std::launch::async, &artdaq::BoardReaderCore::process_fragments, fragment_receiver_ptr_.get());
229 
230 }
231 
232 //========================================================================================================================
233 void ARTDAQProducer::startProcessingData(std::string runNumber)
234 {
235  std::cout << __COUT_HDR_FL__ << "\tStart" << std::endl;
236 
237  art::RunID runId((art::RunNumber_t)boost::lexical_cast<art::RunNumber_t>(runNumber));
238 
239  //FIXME These are passed as parameters
240  uint64_t timeout = 45;
241  uint64_t timestamp = 184467440737095516;
242 
243  report_string_ = "";
244  std::cout << __COUT_HDR_FL__ << "\tStart run: " << runId << std::endl;
245  external_request_status_ = fragment_receiver_ptr_->start(runId, timeout, timestamp);
246  std::cout << __COUT_HDR_FL__ << "\tStart already crashed "<< std::endl;
247  if (! external_request_status_)
248  {
249  report_string_ = "Error starting ";
250  report_string_.append(name_ + " ");
251  report_string_.append("for run number ");
252  report_string_.append(boost::lexical_cast<std::string>(runId.run()));
253  report_string_.append(", timeout ");
254  report_string_.append(boost::lexical_cast<std::string>(timeout));
255  report_string_.append(", timestamp ");
256  report_string_.append(boost::lexical_cast<std::string>(timestamp));
257  report_string_.append(".");
258  }
259 
260  std::cout << __COUT_HDR_FL__ << "STARTING BOARD READER THREAD" << std::endl;
261  fragment_processing_future_ = std::async(std::launch::async, &artdaq::BoardReaderCore::process_fragments, fragment_receiver_ptr_.get());
262 
263 }
264 
265 //========================================================================================================================
266 void ARTDAQProducer::stopProcessingData(void)
267 {
268  std::cout << __COUT_HDR_FL__ << "\tStop" << std::endl;
269  //FIXME These are passed as parameters
270  uint64_t timeout = 45;
271  uint64_t timestamp = 184467440737095516;
272  report_string_ = "";
273  external_request_status_ = fragment_receiver_ptr_->stop(timeout, timestamp);
274  if (! external_request_status_)
275  {
276  report_string_ = "Error stopping ";
277  report_string_.append(name_ + ".");
278  //return false;
279  }
280 
281  if (fragment_processing_future_.valid())
282  {
283  int number_of_fragments_sent = fragment_processing_future_.get();
284  mf::LogDebug(name_ + "App::do_stop(uint64_t, uint64_t)")
285  << "Number of fragments sent = " << number_of_fragments_sent
286  << ".";
287  }
288 
289 }
290 
291 DEFINE_OTS_PROCESSOR(ARTDAQProducer)