otsdaq  v1_01_02
 All Classes Namespaces Functions
FEVInterfacesManager.cc
1 #include "otsdaq-core/FECore/FEVInterfacesManager.h"
2 #include "otsdaq-core/MessageFacility/MessageFacility.h"
3 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
4 #include "otsdaq-core/FECore/FEVInterface.h"
5 #include "otsdaq-core/PluginMakers/MakeInterface.h"
6 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
7 #include "otsdaq-core/ConfigurationDataFormats/FEInterfaceConfigurationBase.h"
8 #include "otsdaq-core/ConfigurationPluginDataFormats/FEConfiguration.h"
9 
10 #include "messagefacility/MessageLogger/MessageLogger.h"
11 #include "artdaq/DAQdata/configureMessageFacility.hh"
12 #include "artdaq/BuildInfo/GetPackageBuildInfo.hh"
13 #include "fhiclcpp/make_ParameterSet.h"
14 
15 #include <iostream>
16 #include <sstream>
17 
18 using namespace ots;
19 
20 //========================================================================================================================
21 FEVInterfacesManager::FEVInterfacesManager(const ConfigurationTree& theXDAQContextConfigTree, const std::string& supervisorConfigurationPath)
22 : Configurable(theXDAQContextConfigTree, supervisorConfigurationPath)
23 {
24  init();
25 }
26 
27 //========================================================================================================================
28 FEVInterfacesManager::~FEVInterfacesManager(void)
29 {
30  destroy();
31 }
32 
33 //========================================================================================================================
34 void FEVInterfacesManager::init(void)
35 {
36 }
37 
38 //========================================================================================================================
39 void FEVInterfacesManager::destroy(void)
40 {
41  for(auto& it : theFEInterfaces_)
42  it.second.reset();
43 
44  theFEInterfaces_.clear();
45 }
46 
47 //========================================================================================================================
48 void FEVInterfacesManager::createInterfaces(void)
49 {
50  destroy();
51 
52  __MOUT__ << "Path: "<< theConfigurationPath_+"/LinkToFEInterfaceConfiguration" << std::endl;
53  for(const auto& interface: theXDAQContextConfigTree_.getNode(theConfigurationPath_+"/LinkToFEInterfaceConfiguration").getChildren())
54  {
55  try
56  {
57  if(!interface.second.getNode("Status").getValue<bool>()) continue;
58  }
59  catch(...) //if Status column not there ignore (for backwards compatibility)
60  {
61  __MOUT_INFO__ << "Ignoring FE Status since Status column is missing!" << std::endl;
62  }
63 
64  __MOUT__ << "Interface Plugin Name: "<< interface.second.getNode("FEInterfacePluginName").getValue<std::string>() << std::endl;
65  __MOUT__ << "Interface Name: "<< interface.first << std::endl;
66  __MOUT__ << "XDAQContext Node: "<< theXDAQContextConfigTree_ << std::endl;
67  __MOUT__ << "Path to configuration: "<< (theConfigurationPath_ + "/LinkToFEInterfaceConfiguration/" + interface.first + "/LinkToFETypeConfiguration") << std::endl;
68  theFEInterfaces_[interface.first] = makeInterface(
69  interface.second.getNode("FEInterfacePluginName").getValue<std::string>(),
70  interface.first,
71  theXDAQContextConfigTree_,
72  (theConfigurationPath_ + "/LinkToFEInterfaceConfiguration/" + interface.first + "/LinkToFETypeConfiguration")
73  );
74  }
75  __MOUT__ << "Done creating interfaces" << std::endl;
76 }
77 
78 //========================================================================================================================
79 //used by MacroMaker
80 int FEVInterfacesManager::universalRead(const std::string &interfaceID, char* address, char* returnValue)
81 {
82  __MOUT__ << "interfaceID: " << interfaceID << " and size: " << theFEInterfaces_.size() << std::endl;
83 
84  if (theFEInterfaces_[interfaceID]->universalRead(address, returnValue) < 0) return -1;
85  return 0;
86 }
87 
88 
89 //========================================================================================================================
90 //used by MacroMaker
91 unsigned int FEVInterfacesManager::getInterfaceUniversalAddressSize(const std::string &interfaceID)
92 { return theFEInterfaces_[interfaceID]->getUniversalAddressSize(); } //used by MacroMaker
93 
94 //========================================================================================================================
95 //used by MacroMaker
96 unsigned int FEVInterfacesManager::getInterfaceUniversalDataSize(const std::string &interfaceID)
97 { return theFEInterfaces_[interfaceID]->getUniversalDataSize(); } //used by MacroMaker
98 
99 //========================================================================================================================
100 //used by MacroMaker
101 void FEVInterfacesManager::universalWrite(const std::string &interfaceID, char* address, char* writeValue)
102 {
103 
104  __MOUT__ << "interfaceID: " << interfaceID << " and size: " << theFEInterfaces_.size() << std::endl;
105 
106  theFEInterfaces_[interfaceID]->universalWrite(address, writeValue);
107 
108 // if(interfaceIndex >= theFEInterfaces_.size())
109 // {
110 // __MOUT__ << "ERROR!!!! Invalid interface index" << std::endl;
111 // return; //invalid interface index
112 // }
113 
114 
115 }
116 
117 //========================================================================================================================
118 //getFEListString
119 // returns string with each new line indicating the macros for a FE
120 // each line:
121 // <interface type>:<parent supervisor lid>:<interface UID>
122 std::string FEVInterfacesManager::getFEListString(const std::string &supervisorLid)
123 {
124  std::string retList = "";
125 
126  for(const auto& it : theFEInterfaces_)
127  {
128  __MOUT__ << "Just curious: it.first is " << it.first << std::endl;
129 
130  retList += it.second->getInterfaceType() +
131  ":" + supervisorLid + ":" +
132  it.second->getInterfaceUID() + "\n";
133  }
134  return retList;
135 }
136 
137 //========================================================================================================================
138 //runFEMacro
139 // Runs the FE Macro in the specified FE interface.
140 //
141 // inputs:
142 // - inputArgs: colon-separated name/value pairs, and then comma-separated
143 // - outputArgs: comma-separated
144 //
145 // outputs:
146 // - throws exception on failure
147 // - outputArgs: colon-separate name/value pairs, and then comma-separated
148 void FEVInterfacesManager::runFEMacro(const std::string &interfaceID,
149  const std::string &feMacroName, const std::string &inputArgs, std::string &outputArgs)
150 {
151  //check for interfaceID
152  auto FEVInterfaceIt = theFEInterfaces_.find(interfaceID);
153  if(FEVInterfaceIt == theFEInterfaces_.end())
154  {
155  __SS__ << "interfaceID '" << interfaceID << "' was not found!" << std::endl;
156  __MOUT_ERR__ << "\n" << ss.str();
157  throw std::runtime_error(ss.str());
158  }
159 
160  //have pointer to virtual FEInterface, find Macro structure
161  auto FEMacroIt = FEVInterfaceIt->second->getMapOfFEMacroFunctions().find(feMacroName);
162  if(FEMacroIt == FEVInterfaceIt->second->getMapOfFEMacroFunctions().end())
163  {
164  __SS__ << "FE Macro '" << feMacroName << "' of interfaceID '" <<
165  interfaceID << "' was not found!" << std::endl;
166  __MOUT_ERR__ << "\n" << ss.str();
167  throw std::runtime_error(ss.str());
168  }
169 
170  //build input arguments
171  // parse args, colon-separated pairs, and then comma-separated
172  std::vector<FEVInterface::frontEndMacroInArg_t> argsIn;
173  {
174  std::istringstream inputStream(inputArgs);
175  std::string splitVal, argName, argValue;
176  while (getline(inputStream, splitVal, ';'))
177  {
178  std::istringstream pairInputStream(splitVal);
179  getline(pairInputStream, argName, ',');
180  getline(pairInputStream, argValue, ',');
181  argsIn.push_back(std::pair<std::string,std::string>(argName,argValue));
182  }
183  }
184 
185  //check namesOfInputArguments_
186  if(FEMacroIt->second.namesOfInputArguments_.size() != argsIn.size())
187  {
188  __SS__ << "FE Macro '" << feMacroName << "' of interfaceID '" <<
189  interfaceID << "' was attempted with a mismatch in" <<
190  " number of input arguments. " << argsIn.size() <<
191  " were given. " << FEMacroIt->second.namesOfInputArguments_.size() <<
192  " expected." << std::endl;
193  __MOUT_ERR__ << "\n" << ss.str();
194  throw std::runtime_error(ss.str());
195  }
196  for(unsigned int i=0;i<argsIn.size();++i)
197  if(argsIn[i].first != FEMacroIt->second.namesOfInputArguments_[i])
198  {
199  __SS__ << "FE Macro '" << feMacroName << "' of interfaceID '" <<
200  interfaceID << "' was attempted with a mismatch in" <<
201  " a name of an input argument. " <<
202  argsIn[i].first << " were given. " <<
203  FEMacroIt->second.namesOfInputArguments_[i] <<
204  " expected." << std::endl;
205  __MOUT_ERR__ << "\n" << ss.str();
206  throw std::runtime_error(ss.str());
207  }
208 
209 
210 
211  //build output arguments
212  std::vector<std::string> returnStrings;
213  std::vector<FEVInterface::frontEndMacroOutArg_t> argsOut;
214 
215  {
216  std::istringstream inputStream(outputArgs);
217  std::string argName;
218  while (getline(inputStream, argName, ','))
219  {
220  __MOUT__ << "argName " << argName << std::endl;
221 
222  returnStrings.push_back( "valueLore" );//std::string());
223  argsOut.push_back(FEVInterface::frontEndMacroOutArg_t(
224  argName,
225  returnStrings[returnStrings.size()-1]));
226  //
227  // __MOUT__ << argsOut[argsOut.size()-1].first << std::endl;
228  __MOUT__ << (uint64_t) &(returnStrings[returnStrings.size()-1]) << std::endl;
229  }
230  }
231 
232  //check namesOfOutputArguments_
233  if(FEMacroIt->second.namesOfOutputArguments_.size() != argsOut.size())
234  {
235  __SS__ << "FE Macro '" << feMacroName << "' of interfaceID '" <<
236  interfaceID << "' was attempted with a mismatch in" <<
237  " number of output arguments. " << argsOut.size() <<
238  " were given. " << FEMacroIt->second.namesOfOutputArguments_.size() <<
239  " expected." << std::endl;
240  __MOUT_ERR__ << "\n" << ss.str();
241  throw std::runtime_error(ss.str());
242  }
243  for(unsigned int i=0;i<argsOut.size();++i)
244  if(argsOut[i].first != FEMacroIt->second.namesOfOutputArguments_[i])
245  {
246  __SS__ << "FE Macro '" << feMacroName << "' of interfaceID '" <<
247  interfaceID << "' was attempted with a mismatch in" <<
248  " a name of an output argument. " <<
249  argsOut[i].first << " were given. " <<
250  FEMacroIt->second.namesOfOutputArguments_[i] <<
251  " expected." << std::endl;
252  __MOUT_ERR__ << "\n" << ss.str();
253  throw std::runtime_error(ss.str());
254  }
255 
256 
257 
258 
259 
260 
261  __MOUT__ << "# of input args = " << argsIn.size() << std::endl;
262  for(auto &argIn:argsIn)
263  __MOUT__ << argIn.first << ": " << argIn.second << std::endl;
264 
265  // __MOUT__ << "# of output args = " << argsOut.size() << std::endl;
266  // for(unsigned int i=0;i<argsOut.size();++i)
267  // __MOUT__ << i << ": " << argsOut[i].first << std::endl;
268  // for(unsigned int i=0;i<returnStrings.size();++i)
269  // __MOUT__ << i << ": " << returnStrings[i] << std::endl;
270 
271 
272 
273 
274  __MOUT__ << "Trying it " << std::endl;
275 
276  //have pointer to Macro structure, so run it
277  (FEVInterfaceIt->second.get()->*(FEMacroIt->second.macroFunction_))(argsIn,argsOut);
278 
279  __MOUT__ << "Made it " << std::endl;
280 
281  __MOUT__ << "# of output args = " << argsOut.size() << std::endl;
282  for(const auto &arg:argsOut)
283  __MOUT__ << arg.first << ": " << arg.second << std::endl;
284 
285 
286 
287 
288 
289  //check namesOfOutputArguments_ size
290  if(FEMacroIt->second.namesOfOutputArguments_.size() != argsOut.size())
291  {
292  __SS__ << "FE Macro '" << feMacroName << "' of interfaceID '" <<
293  interfaceID << "' was attempted but the FE macro "
294  "manipulated the output arguments vector. It is illegal "
295  "to add or remove output vector name/value pairs." << std::endl;
296  __MOUT_ERR__ << "\n" << ss.str();
297  throw std::runtime_error(ss.str());
298  }
299 
300 
301 
302  //Success! at this point so return the output string
303  outputArgs = "";
304  for(unsigned int i=0; i<argsOut.size(); ++i)
305  {
306  if(i) outputArgs += ";";
307  outputArgs += argsOut[i].first + "," + argsOut[i].second;
308  }
309 
310  __MOUT__ << "outputArgs = " << outputArgs << std::endl;
311 
312 }
313 
314 //========================================================================================================================
315 //getFEMacrosString
316 // returns string with each new line indicating the macros for a FE
317 // each line:
318 // <interface type>:<parent supervisor lid>:<interface UID>
319 // :<macro name>:<macro permissions req>:<macro num of inputs>:...<input names : separated>...
320 // :<macro num of outputs>:...<output names : separated>...
321 std::string FEVInterfacesManager::getFEMacrosString(const std::string &supervisorLid)
322 {
323  std::string retList = "";
324 
325  for(const auto& it : theFEInterfaces_)
326  {
327  __MOUT__ << "FE interface UID = " << it.first << std::endl;
328 
329  retList += it.second->getInterfaceType() +
330  ":" + supervisorLid + ":" +
331  it.second->getInterfaceUID();
332 
333  for(const auto& macroPair : it.second->getMapOfFEMacroFunctions())
334  {
335  __MOUT__ << "FE Macro name = " << macroPair.first << std::endl;
336  retList +=
337  ":" + macroPair.first +
338  ":" + std::to_string(macroPair.second.requiredUserPermissions_) +
339  ":" + std::to_string(macroPair.second.namesOfInputArguments_.size());
340  for(const auto& name:macroPair.second.namesOfInputArguments_)
341  retList += ":" + name;
342 
343  retList +=
344  ":" + std::to_string(macroPair.second.namesOfOutputArguments_.size());
345  for(const auto& name:macroPair.second.namesOfOutputArguments_)
346  retList += ":" + name;
347  }
348 
349  retList += "\n";
350  }
351  return retList;
352 }
353 
354 
355 //========================================================================================================================
356 void FEVInterfacesManager::configure(void)
357 {
358  createInterfaces();
359  for(const auto& it : theFEInterfaces_)
360  {
361 // if(supervisorType_ == "FER")
362 // it.second->initLocalGroup((int)local_group_comm_);
363 
364  __MOUT__ << "Configuring interface " << it.first << std::endl;
365  __MOUT__ << "Configuring interface " << it.first << std::endl;
366  __MOUT__ << "Configuring interface " << it.first << std::endl;
367  it.second->configure();
368 
369  //configure slow controls and start slow controls workloop
370  // slow controls workloop stays alive through start/stop.. and dies on halt
371  //LOREit.second->configureSlowControls();
372  //WAS ALREADY COMMENTED OUTit.second->startSlowControlsWorkLooop();
373 
374 // if((supervisorType_ == "FEW") || (supervisorType_ == "FEWR") )
375 // {
376 
377  __MOUT__ << "Done configuring interface " << it.first << std::endl;
378  __MOUT__ << "Done configuring interface " << it.first << std::endl;
379  __MOUT__ << "Done configuring interface " << it.first << std::endl;
380  //throw std::runtime_error(ss.str());
381  // it.second->configureDetector(theConfigurationManager_->getDACStream(it.first));
382 
383 // }
384  }
385  __MOUT__ << "Done Configure" << std::endl;
386 }
387 
388 //========================================================================================================================
389 void FEVInterfacesManager::halt(void)
390 {
391  for(const auto& it : theFEInterfaces_)
392  {
393  it.second->halt();
394  it.second->stopWorkLoop();
395  //it.second->stopSlowControlsWorkLooop();
396  }
397 
398  destroy(); //destroy all FE interfaces on halt, must be configured for FE interfaces to exist
399 }
400 
401 //========================================================================================================================
402 void FEVInterfacesManager::pause(void)
403 {
404  for(const auto& it : theFEInterfaces_)
405  {
406  it.second->pause();
407  it.second->stopWorkLoop();
408  }
409 }
410 
411 //========================================================================================================================
412 void FEVInterfacesManager::resume(void)
413 {
414  for(const auto& it : theFEInterfaces_)
415  {
416  it.second->resume();
417  it.second->startWorkLoop();
418  }
419 }
420 
421 //========================================================================================================================
422 void FEVInterfacesManager::start(std::string runNumber)
423 {
424  for(const auto& it : theFEInterfaces_)
425  {
426  it.second->start(runNumber);
427  it.second->startWorkLoop();
428  }
429 }
430 //========================================================================================================================
431 void FEVInterfacesManager::stop(void)
432 {
433  for(const auto& it : theFEInterfaces_)
434  {
435  it.second->stopWorkLoop();
436  it.second->stop();
437  }
438 }