00001 #include "otsdaq-core/FECore/FEVInterfacesManager.h"
00002 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00003 #include "otsdaq-core/Macros/CoutMacros.h"
00004 #include "otsdaq-core/FECore/FEVInterface.h"
00005 #include "otsdaq-core/PluginMakers/MakeInterface.h"
00006 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
00007
00008 #include "messagefacility/MessageLogger/MessageLogger.h"
00009 #include "artdaq-core/Utilities/configureMessageFacility.hh"
00010 #include "artdaq/BuildInfo/GetPackageBuildInfo.hh"
00011 #include "fhiclcpp/make_ParameterSet.h"
00012
00013 #include <iostream>
00014 #include <sstream>
00015
00016 using namespace ots;
00017
00018
00019 FEVInterfacesManager::FEVInterfacesManager(const ConfigurationTree& theXDAQContextConfigTree, const std::string& supervisorConfigurationPath)
00020 : Configurable(theXDAQContextConfigTree, supervisorConfigurationPath)
00021 {
00022 init();
00023 }
00024
00025
00026 FEVInterfacesManager::~FEVInterfacesManager(void)
00027 {
00028 destroy();
00029 }
00030
00031
00032 void FEVInterfacesManager::init(void)
00033 {
00034 }
00035
00036
00037 void FEVInterfacesManager::destroy(void)
00038 {
00039 for(auto& it : theFEInterfaces_)
00040 it.second.reset();
00041
00042 theFEInterfaces_.clear();
00043 }
00044
00045
00046 void FEVInterfacesManager::createInterfaces(void)
00047 {
00048 destroy();
00049
00050 __COUT__ << "Path: "<< theConfigurationPath_+"/LinkToFEInterfaceConfiguration" << std::endl;
00051 for(const auto& interface: theXDAQContextConfigTree_.getNode(theConfigurationPath_+"/LinkToFEInterfaceConfiguration").getChildren())
00052 {
00053 try
00054 {
00055 if(!interface.second.getNode(ViewColumnInfo::COL_NAME_STATUS).getValue<bool>()) continue;
00056 }
00057 catch(...)
00058 {
00059 __COUT_INFO__ << "Ignoring FE Status since Status column is missing!" << std::endl;
00060 }
00061
00062 __COUT__ << "Interface Plugin Name: "<< interface.second.getNode("FEInterfacePluginName").getValue<std::string>() << std::endl;
00063 __COUT__ << "Interface Name: "<< interface.first << std::endl;
00064 __COUT__ << "XDAQContext Node: "<< theXDAQContextConfigTree_ << std::endl;
00065 __COUT__ << "Path to configuration: "<< (theConfigurationPath_ + "/LinkToFEInterfaceConfiguration/" + interface.first + "/LinkToFETypeConfiguration") << std::endl;
00066
00067 try
00068 {
00069 theFEInterfaces_[interface.first] = makeInterface(
00070 interface.second.getNode("FEInterfacePluginName").getValue<std::string>(),
00071 interface.first,
00072 theXDAQContextConfigTree_,
00073 (theConfigurationPath_ + "/LinkToFEInterfaceConfiguration/" + interface.first + "/LinkToFETypeConfiguration")
00074 );
00075 }
00076 catch(const cet::exception& e)
00077 {
00078 __SS__ << "Failed to instantiate plugin named '" <<
00079 interface.first << "' of type '" <<
00080 interface.second.getNode("FEInterfacePluginName").getValue<std::string>()
00081 << "' due to the following error: \n" << e.what() << __E__;
00082 __COUT_ERR__ << ss.str();
00083 __MOUT_ERR__ << ss.str();
00084 throw std::runtime_error(ss.str());
00085 }
00086 }
00087 __COUT__ << "Done creating interfaces" << std::endl;
00088 }
00089
00090
00091
00092 int FEVInterfacesManager::universalRead(const std::string &interfaceID, char* address, char* returnValue)
00093 {
00094 if(theFEInterfaces_.find(interfaceID) == theFEInterfaces_.end())
00095 {
00096 __SS__ << "Interface ID '" << interfaceID << "' not found in configured interfaces." << __E__;
00097 throw std::runtime_error(ss.str());
00098 }
00099
00100 __COUT__ << "interfaceID: " << interfaceID << " and size: " << theFEInterfaces_.size() << std::endl;
00101
00102 if (theFEInterfaces_[interfaceID]->universalRead(address, returnValue) < 0) return -1;
00103 return 0;
00104 }
00105
00106
00107
00108
00109 unsigned int FEVInterfacesManager::getInterfaceUniversalAddressSize(const std::string &interfaceID)
00110 {
00111 if(theFEInterfaces_.find(interfaceID) == theFEInterfaces_.end())
00112 {
00113 __SS__ << "Interface ID '" << interfaceID << "' not found in configured interfaces." << __E__;
00114 throw std::runtime_error(ss.str());
00115 }
00116 return theFEInterfaces_[interfaceID]->getUniversalAddressSize();
00117 }
00118
00119
00120
00121 unsigned int FEVInterfacesManager::getInterfaceUniversalDataSize(const std::string &interfaceID)
00122 {
00123 if(theFEInterfaces_.find(interfaceID) == theFEInterfaces_.end())
00124 {
00125 __SS__ << "Interface ID '" << interfaceID << "' not found in configured interfaces." << __E__;
00126 throw std::runtime_error(ss.str());
00127 }
00128 return theFEInterfaces_[interfaceID]->getUniversalDataSize();
00129 }
00130
00131
00132
00133 void FEVInterfacesManager::universalWrite(const std::string &interfaceID, char* address, char* writeValue)
00134 {
00135 if(theFEInterfaces_.find(interfaceID) == theFEInterfaces_.end())
00136 {
00137 __SS__ << "Interface ID '" << interfaceID << "' not found in configured interfaces." << __E__;
00138 throw std::runtime_error(ss.str());
00139 }
00140
00141 __COUT__ << "interfaceID: " << interfaceID << " and size: " << theFEInterfaces_.size() << std::endl;
00142
00143 theFEInterfaces_[interfaceID]->universalWrite(address, writeValue);
00144
00145
00146
00147
00148
00149
00150
00151
00152 }
00153
00154
00155
00156
00157
00158
00159 std::string FEVInterfacesManager::getFEListString(const std::string &supervisorLid)
00160 {
00161 std::string retList = "";
00162
00163 for(const auto& it : theFEInterfaces_)
00164 {
00165 __COUT__ << "FE name = " << it.first << std::endl;
00166
00167 retList += it.second->getInterfaceType() +
00168 ":" + supervisorLid + ":" +
00169 it.second->getInterfaceUID() + "\n";
00170 }
00171 return retList;
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 void FEVInterfacesManager::runFEMacro(const std::string &interfaceID,
00186 const std::string &feMacroName, const std::string &inputArgs, std::string &outputArgs)
00187 {
00188
00189 auto FEVInterfaceIt = theFEInterfaces_.find(interfaceID);
00190 if(FEVInterfaceIt == theFEInterfaces_.end())
00191 {
00192 __SS__ << "interfaceID '" << interfaceID << "' was not found!" << std::endl;
00193 __COUT_ERR__ << "\n" << ss.str();
00194 throw std::runtime_error(ss.str());
00195 }
00196
00197
00198 auto FEMacroIt = FEVInterfaceIt->second->getMapOfFEMacroFunctions().find(feMacroName);
00199 if(FEMacroIt == FEVInterfaceIt->second->getMapOfFEMacroFunctions().end())
00200 {
00201 __SS__ << "FE Macro '" << feMacroName << "' of interfaceID '" <<
00202 interfaceID << "' was not found!" << std::endl;
00203 __COUT_ERR__ << "\n" << ss.str();
00204 throw std::runtime_error(ss.str());
00205 }
00206
00207
00208
00209 std::vector<FEVInterface::frontEndMacroInArg_t> argsIn;
00210 {
00211 std::istringstream inputStream(inputArgs);
00212 std::string splitVal, argName, argValue;
00213 while (getline(inputStream, splitVal, ';'))
00214 {
00215 std::istringstream pairInputStream(splitVal);
00216 getline(pairInputStream, argName, ',');
00217 getline(pairInputStream, argValue, ',');
00218 argsIn.push_back(std::pair<std::string,std::string>(argName,argValue));
00219 }
00220 }
00221
00222
00223 if(FEMacroIt->second.namesOfInputArguments_.size() != argsIn.size())
00224 {
00225 __SS__ << "FE Macro '" << feMacroName << "' of interfaceID '" <<
00226 interfaceID << "' was attempted with a mismatch in" <<
00227 " number of input arguments. " << argsIn.size() <<
00228 " were given. " << FEMacroIt->second.namesOfInputArguments_.size() <<
00229 " expected." << std::endl;
00230 __COUT_ERR__ << "\n" << ss.str();
00231 throw std::runtime_error(ss.str());
00232 }
00233 for(unsigned int i=0;i<argsIn.size();++i)
00234 if(argsIn[i].first != FEMacroIt->second.namesOfInputArguments_[i])
00235 {
00236 __SS__ << "FE Macro '" << feMacroName << "' of interfaceID '" <<
00237 interfaceID << "' was attempted with a mismatch in" <<
00238 " a name of an input argument. " <<
00239 argsIn[i].first << " were given. " <<
00240 FEMacroIt->second.namesOfInputArguments_[i] <<
00241 " expected." << std::endl;
00242 __COUT_ERR__ << "\n" << ss.str();
00243 throw std::runtime_error(ss.str());
00244 }
00245
00246
00247
00248
00249 std::vector<std::string> returnStrings;
00250 std::vector<FEVInterface::frontEndMacroOutArg_t> argsOut;
00251
00252 {
00253 std::istringstream inputStream(outputArgs);
00254 std::string argName;
00255 while (getline(inputStream, argName, ','))
00256 {
00257 __COUT__ << "argName " << argName << std::endl;
00258
00259 returnStrings.push_back( "DEFAULT" );
00260 argsOut.push_back(FEVInterface::frontEndMacroOutArg_t(
00261 argName,
00262 returnStrings[returnStrings.size()-1]));
00263
00264
00265 __COUT__ << (uint64_t) &(returnStrings[returnStrings.size()-1]) << std::endl;
00266 }
00267 }
00268
00269
00270 if(FEMacroIt->second.namesOfOutputArguments_.size() != argsOut.size())
00271 {
00272 __SS__ << "FE Macro '" << feMacroName << "' of interfaceID '" <<
00273 interfaceID << "' was attempted with a mismatch in" <<
00274 " number of output arguments. " << argsOut.size() <<
00275 " were given. " << FEMacroIt->second.namesOfOutputArguments_.size() <<
00276 " expected." << std::endl;
00277 __COUT_ERR__ << "\n" << ss.str();
00278 throw std::runtime_error(ss.str());
00279 }
00280 for(unsigned int i=0;i<argsOut.size();++i)
00281 if(argsOut[i].first != FEMacroIt->second.namesOfOutputArguments_[i])
00282 {
00283 __SS__ << "FE Macro '" << feMacroName << "' of interfaceID '" <<
00284 interfaceID << "' was attempted with a mismatch in" <<
00285 " a name of an output argument. " <<
00286 argsOut[i].first << " were given. " <<
00287 FEMacroIt->second.namesOfOutputArguments_[i] <<
00288 " expected." << std::endl;
00289 __COUT_ERR__ << "\n" << ss.str();
00290 throw std::runtime_error(ss.str());
00291 }
00292
00293
00294
00295
00296
00297
00298 __COUT__ << "# of input args = " << argsIn.size() << std::endl;
00299 for(auto &argIn:argsIn)
00300 __COUT__ << argIn.first << ": " << argIn.second << std::endl;
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 __MOUT__ << "Launching FE Macro '" << feMacroName << "' ..." << std::endl;
00312 __COUT__ << "Launching FE Macro '" << feMacroName << "' ..." << std::endl;
00313
00314
00315 (FEVInterfaceIt->second.get()->*(FEMacroIt->second.macroFunction_))(argsIn,argsOut);
00316
00317 __COUT__ << "FE Macro complete!" << std::endl;
00318
00319 __COUT__ << "# of output args = " << argsOut.size() << std::endl;
00320 for(const auto &arg:argsOut)
00321 __COUT__ << arg.first << ": " << arg.second << std::endl;
00322
00323
00324
00325
00326
00327
00328 if(FEMacroIt->second.namesOfOutputArguments_.size() != argsOut.size())
00329 {
00330 __SS__ << "FE Macro '" << feMacroName << "' of interfaceID '" <<
00331 interfaceID << "' was attempted but the FE macro "
00332 "manipulated the output arguments vector. It is illegal "
00333 "to add or remove output vector name/value pairs." << std::endl;
00334 __COUT_ERR__ << "\n" << ss.str();
00335 throw std::runtime_error(ss.str());
00336 }
00337
00338
00339
00340
00341 outputArgs = "";
00342 for(unsigned int i=0; i<argsOut.size(); ++i)
00343 {
00344 if(i) outputArgs += ";";
00345 outputArgs += argsOut[i].first + "," + argsOut[i].second;
00346 }
00347
00348 __COUT__ << "outputArgs = " << outputArgs << std::endl;
00349
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359 std::string FEVInterfacesManager::getFEMacrosString(const std::string &supervisorLid)
00360 {
00361 std::string retList = "";
00362
00363 for(const auto& it : theFEInterfaces_)
00364 {
00365 __COUT__ << "FE interface UID = " << it.first << std::endl;
00366
00367 retList += it.second->getInterfaceType() +
00368 ":" + supervisorLid + ":" +
00369 it.second->getInterfaceUID();
00370
00371 for(const auto& macroPair : it.second->getMapOfFEMacroFunctions())
00372 {
00373 __COUT__ << "FE Macro name = " << macroPair.first << std::endl;
00374 retList +=
00375 ":" + macroPair.first +
00376 ":" + std::to_string(macroPair.second.requiredUserPermissions_) +
00377 ":" + std::to_string(macroPair.second.namesOfInputArguments_.size());
00378 for(const auto& name:macroPair.second.namesOfInputArguments_)
00379 retList += ":" + name;
00380
00381 retList +=
00382 ":" + std::to_string(macroPair.second.namesOfOutputArguments_.size());
00383 for(const auto& name:macroPair.second.namesOfOutputArguments_)
00384 retList += ":" + name;
00385 }
00386
00387 retList += "\n";
00388 }
00389 return retList;
00390 }
00391
00392
00393 bool FEVInterfacesManager::allFEWorkloopsAreDone(void)
00394 {
00395 bool allFEWorkloopsAreDone = true;
00396 bool isActive;
00397
00398 for(const auto& FEInterface: theFEInterfaces_)
00399 {
00400 isActive = FEInterface.second->isActive();
00401 __COUT__ << FEInterface.second->getInterfaceUID() << " of type " <<
00402 FEInterface.second->getInterfaceType() << ": \t" <<
00403 "workLoop_->isActive() " <<
00404 (isActive?"yes":"no") << std::endl;
00405
00406 if(isActive)
00407 {
00408 allFEWorkloopsAreDone = false;
00409 break;
00410 }
00411 }
00412
00413 return allFEWorkloopsAreDone;
00414 }
00415
00416
00417 void FEVInterfacesManager::configure(void)
00418 {
00419 createInterfaces();
00420 for(const auto& it : theFEInterfaces_)
00421 {
00422
00423
00424
00425 __COUT__ << "Configuring interface " << it.first << std::endl;
00426 __COUT__ << "Configuring interface " << it.first << std::endl;
00427 __COUT__ << "Configuring interface " << it.first << std::endl;
00428
00429 it.second->configure();
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 __COUT__ << "Done configuring interface " << it.first << std::endl;
00440 __COUT__ << "Done configuring interface " << it.first << std::endl;
00441 __COUT__ << "Done configuring interface " << it.first << std::endl;
00442
00443
00444
00445
00446 }
00447
00448
00449 __COUT__ << "Done Configure" << std::endl;
00450 }
00451
00452
00453 void FEVInterfacesManager::halt(void)
00454 {
00455 for(const auto& it : theFEInterfaces_)
00456 {
00457 it.second->halt();
00458 it.second->stopWorkLoop();
00459
00460 }
00461
00462 destroy();
00463 }
00464
00465
00466 void FEVInterfacesManager::pause(void)
00467 {
00468 for(const auto& it : theFEInterfaces_)
00469 {
00470 it.second->pause();
00471 it.second->stopWorkLoop();
00472 }
00473 }
00474
00475
00476 void FEVInterfacesManager::resume(void)
00477 {
00478 for(const auto& it : theFEInterfaces_)
00479 {
00480 it.second->resume();
00481 it.second->startWorkLoop();
00482 }
00483 }
00484
00485
00486 void FEVInterfacesManager::start(std::string runNumber)
00487 {
00488 for(const auto& it : theFEInterfaces_)
00489 {
00490 it.second->start(runNumber);
00491 it.second->startWorkLoop();
00492 }
00493 }
00494
00495 void FEVInterfacesManager::stop(void)
00496 {
00497 for(const auto& it : theFEInterfaces_)
00498 {
00499 it.second->stopWorkLoop();
00500 it.second->stop();
00501 }
00502 }