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