otsdaq  3.03.00
ARTDAQBoardReaderTable_table.cc
1 #include "otsdaq/Macros/TablePluginMacros.h"
2 #include "otsdaq/TablePlugins/ARTDAQBoardReaderTable.h"
3 
4 using namespace ots;
5 
6 // clang-format off
7 
8 #define SLOWCONTROL_PV_FILE_PATH \
9  std::string( \
10  getenv("OTSDAQ_EPICS_DATA")? \
11  (std::string(getenv("OTSDAQ_EPICS_DATA")) + "/" + __ENV__("MU2E_OWNER") + "_otsdaq_artdaqBoardReader-ai.dbg"): \
12  (EPICS_CONFIG_PATH + "/_otsdaq_artdaqBoardReader-ai.dbg") )
13 
14 // clang-format on
15 
16 //==============================================================================
17 ARTDAQBoardReaderTable::ARTDAQBoardReaderTable(void)
18  : TableBase("ARTDAQBoardReaderTable")
19  , ARTDAQTableBase("ARTDAQBoardReaderTable")
20  , SlowControlsTableBase("ARTDAQBoardReaderTable")
21 {
23  // WARNING: the names used in C++ MUST match the Table INFO //
25  // December 2021 started seeing an issue where traceTID is found to be cleared to 0
26  // which crashes TRACE if __COUT__ is used in a Table plugin constructor
27  // This check and re-initialization seems to cover up the issue for now.
28  // Why it is cleared to 0 after the constructor sets it to -1 is still unknown.
29  // Note: it seems to only happen on the first alphabetially ARTDAQ Configure Table plugin.
30  if(traceTID == 0)
31  {
32  std::cout << "ARTDAQBoardReaderTable Before traceTID=" << traceTID << __E__;
33  char buf[40];
34  traceInit(trace_name(TRACE_NAME, __TRACE_FILE__, buf, sizeof(buf)), 0);
35  std::cout << "ARTDAQBoardReaderTable After traceTID=" << traceTID << __E__;
36  __COUT__ << "ARTDAQBoardReaderTable TRACE reinit and Constructed." << __E__;
37  }
38  else
39  __COUT__ << "ARTDAQBoardReaderTable Constructed." << __E__;
40 } // end constructor()
41 
42 //==============================================================================
43 ARTDAQBoardReaderTable::~ARTDAQBoardReaderTable(void) {}
44 
45 //==============================================================================
47 {
48  lastConfigManager_ = configManager;
49 
50  // use isFirstAppInContext to only run once per context, for example to avoid
51  // generating files on local disk multiple times.
52  isFirstAppInContext_ = configManager->isOwnerFirstAppInContext();
53 
54  //__COUTV__(isFirstAppInContext_);
56  return;
57 
58  //if artdaq supervisor is disabled, skip fcl handling
59  if(!ARTDAQTableBase::isARTDAQEnabled(configManager))
60  {
61  __COUT_INFO__ << "ARTDAQ Supervisor is disabled, so skipping fcl handling."
62  << __E__;
63  return;
64  }
65 
66  // make directory just in case
67  mkdir((ARTDAQTableBase::ARTDAQ_FCL_PATH).c_str(), 0755);
68 
69  __COUTS__(3) << "*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*" << __E__;
70  __COUTS__(3) << configManager->__SELF_NODE__ << __E__;
71 
72  // handle fcl file generation, wherever the level of this table
73 
74  // auto readers = lastConfigManager_->getNode(ARTDAQTableBase::getTableName()).getChildren(
75  auto readers = lastConfigManager_->__SELF_NODE__.getChildren(
76  /*default filterMap*/ std::map<std::string /*relative-path*/,
77  std::string /*value*/>(),
78  /*default byPriority*/ false,
79  /*TRUE! onlyStatusTrue*/ true);
80 
81  for(auto& reader : readers)
82  {
83  ARTDAQTableBase::outputBoardReaderFHICL(reader.second);
84  ARTDAQTableBase::flattenFHICL(ARTDAQAppType::BoardReader,
85  reader.second.getValue());
86  }
87  __COUTS__(3) << "*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*" << __E__;
88 } // end init()
89 
90 //==============================================================================
91 unsigned int ARTDAQBoardReaderTable::slowControlsHandlerConfig(
92  std::stringstream& out,
93  ConfigurationManager* configManager,
94  std::vector<std::pair<std::string /*channelName*/, std::vector<std::string>>>*
95  channelList /*= 0*/
96 ) const
97 {
99  // generate xdaq run parameter file
100 
101  std::string tabStr = "";
102  std::string commentStr = "";
103 
104  // loop through ARTDAQ BoardReader records starting at ARTDAQSupervisorTable
105  std::vector<std::pair<std::string, ConfigurationTree>> artdaqRecords =
106  configManager->getNode("ARTDAQSupervisorTable").getChildren();
107 
108  unsigned int numberOfBoardReaderMetricParameters = 0;
109 
110  for(auto& artdaqPair : artdaqRecords) // start main artdaq record loop
111  {
112  if(artdaqPair.second.getNode(colARTDAQSupervisor_.colLinkToBoardReaders_)
113  .isDisconnected())
114  continue;
115 
116  std::vector<std::pair<std::string, ConfigurationTree>> boardReaderRecords =
117  artdaqPair.second.getNode(colARTDAQSupervisor_.colLinkToBoardReaders_)
118  .getChildren();
119 
120  for(auto& boardReaderPair :
121  boardReaderRecords) // start main boardReader record loop
122  {
123  if(!boardReaderPair.second.status())
124  continue;
125 
126  try
127  {
128  if(boardReaderPair.second.getNode("daqMetricsLink").isDisconnected())
129  continue;
130 
131  auto daqMetricsLinks =
132  boardReaderPair.second.getNode("daqMetricsLink").getChildren();
133  for(auto& daqMetricsLink :
134  daqMetricsLinks) // start daqMetricsLinks record loop
135  {
136  if(!daqMetricsLink.second.status())
137  continue;
138 
139  if(daqMetricsLink.second.getNode("metricParametersLink")
140  .isDisconnected())
141  continue;
142 
143  // ConfigurationTree slowControlsLink = configManager->getNode("ARTDAQMetricAlarmThresholdsTable");
144  ConfigurationTree slowControlsLink =
145  boardReaderPair.second.getNode("MetricAlarmThresholdsLink");
146 
147  auto metricParametersLinks =
148  daqMetricsLink.second.getNode("metricParametersLink")
149  .getChildren();
150  for(auto& metricParametersLink :
151  metricParametersLinks) // start daq MetricParametersLinks record loop
152  {
153  if(!metricParametersLink.second.status())
154  continue;
155 
156  std::string subsystem =
157  metricParametersLink.second.getNode("metricParameterValue")
158  .getValueWithDefault<std::string>(std::string("TDAQ_") +
159  __ENV__("MU2E_OWNER"));
160  if(subsystem.find("Mu2e:") != std::string::npos)
161  subsystem = subsystem.replace(subsystem.find("Mu2e:"), 5, "");
162  while(subsystem.find("\"") != std::string::npos)
163  subsystem = subsystem.replace(subsystem.find("\""), 1, "");
164 
165  numberOfBoardReaderMetricParameters =
166  slowControlsHandler(out,
167  tabStr,
168  commentStr,
169  subsystem,
170  boardReaderPair.first,
171  slowControlsLink,
172  channelList);
173 
174  __COUT__ << "BoardReader '" << boardReaderPair.first
175  << "' number of metrics for slow controls: "
176  << numberOfBoardReaderMetricParameters << __E__;
177  }
178  }
179  }
180  catch(const std::runtime_error& e)
181  {
182  __COUT_ERR__ << "Ignoring BoardReader error: " << e.what() << __E__;
183  }
184  }
185  }
186 
187  return numberOfBoardReaderMetricParameters;
188 } // end slowControlsHandlerConfig()
189 
190 //==============================================================================
193 {
194  return SLOWCONTROL_PV_FILE_PATH;
195 }
196 
197 DEFINE_OTS_TABLE(ARTDAQBoardReaderTable)
virtual std::string setFilePath() const override
return out file path
void init(ConfigurationManager *configManager) override
Methods.
<virtual so future plugins can inherit from multiple table base classes
static bool isARTDAQEnabled(const ConfigurationManager *cfgMgr)
isARTDAQEnabled
ConfigurationTree getNode(const std::string &nodeString, bool doNotThrowOnBrokenUIDLinks=false) const
"root/parent/parent/"
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, TableVersion > *memberMap=0, std::string *accumulatedTreeErrors=0) const
ConfigurationTree getNode(const std::string &nodeName, bool doNotThrowOnBrokenUIDLinks=false) const
navigating between nodes
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool byPriority=false, bool onlyStatusTrue=false) const
<virtual so future plugins can inherit from multiple table base classes
bool isFirstAppInContext_
for managing if PV list has changed