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