tdaq-develop-2025-02-12
ARTDAQEventBuilderTable_table.cc
1 #include "otsdaq/Macros/TablePluginMacros.h"
2 #include "otsdaq/TablePlugins/ARTDAQEventBuilderTable.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_artdaqEventBuilder-ai.dbg"): \
12  (EPICS_CONFIG_PATH + "/_otsdaq_artdaqEventBuilder-ai.dbg") )
13 
14 // clang-format on
15 
16 //==============================================================================
17 ARTDAQEventBuilderTable::ARTDAQEventBuilderTable(void)
18  : TableBase("ARTDAQEventBuilderTable")
19  , ARTDAQTableBase("ARTDAQEventBuilderTable")
20  , SlowControlsTableBase("ARTDAQEventBuilderTable")
21 {
23  // WARNING: the names used in C++ MUST match the Table INFO //
25  __COUT__ << "ARTDAQEventBuilderTable Constructed." << __E__;
26 } // end constructor()
27 
28 //==============================================================================
29 ARTDAQEventBuilderTable::~ARTDAQEventBuilderTable(void) {}
30 
31 //==============================================================================
33 {
34  lastConfigManager_ = configManager;
35 
36  // use isFirstAppInContext to only run once per context, for example to avoid
37  // generating files on local disk multiple times.
38  isFirstAppInContext_ = configManager->isOwnerFirstAppInContext();
39 
40  //__COUTV__(isFirstAppInContext);
42  return;
43 
44  //if artdaq supervisor is disabled, skip fcl handling
45  if(!ARTDAQTableBase::isARTDAQEnabled(configManager))
46  {
47  __COUT_INFO__ << "ARTDAQ Supervisor is disabled, so skipping fcl handling."
48  << __E__;
49  return;
50  }
51 
52  // make directory just in case
53  mkdir((ARTDAQTableBase::ARTDAQ_FCL_PATH).c_str(), 0755);
54 
55  // __COUT__ << "*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*" << __E__;
56  // __COUT__ << configManager->__SELF_NODE__ << __E__;
57 
58  // handle fcl file generation, wherever the level of this table
59 
60  auto buiders = lastConfigManager_->getNode(ARTDAQTableBase::getTableName())
61  .getChildren(
62  /*default filterMap*/ std::map<std::string /*relative-path*/,
63  std::string /*value*/>(),
64  /*default byPriority*/ false,
65  /*TRUE! onlyStatusTrue*/ true);
66 
67  for(auto& builder : buiders)
68  {
70  builder.second, ARTDAQTableBase::ARTDAQAppType::EventBuilder);
71  ARTDAQTableBase::flattenFHICL(ARTDAQAppType::EventBuilder,
72  builder.second.getValue());
73  }
74 } // end init()
75 
76 //==============================================================================
77 unsigned int ARTDAQEventBuilderTable::slowControlsHandlerConfig(
78  std::stringstream& out,
79  ConfigurationManager* configManager,
80  std::vector<std::pair<std::string /*channelName*/, std::vector<std::string>>>*
81  channelList /*= 0*/
82 ) const
83 {
85  // generate xdaq run parameter file
86 
87  std::string tabStr = "";
88  std::string commentStr = "";
89 
90  // loop through ARTDAQ EventBuilder records starting at ARTDAQSupervisorTable
91  std::vector<std::pair<std::string, ConfigurationTree>> artdaqRecords =
92  configManager->getNode("ARTDAQSupervisorTable").getChildren();
93 
94  unsigned int numberOfEventBuiderMetricParameters = 0;
95 
96  for(auto& artdaqPair : artdaqRecords) // start main artdaq record loop
97  {
98  if(artdaqPair.second.getNode(colARTDAQSupervisor_.colLinkToEventBuilders_)
99  .isDisconnected())
100  continue;
101 
102  std::vector<std::pair<std::string, ConfigurationTree>> eventBuilderRecords =
103  artdaqPair.second.getNode(colARTDAQSupervisor_.colLinkToEventBuilders_)
104  .getChildren();
105 
106  for(auto& eventBuilderPair :
107  eventBuilderRecords) // start main eventBuilder record loop
108  {
109  if(!eventBuilderPair.second.status())
110  continue;
111 
112  try
113  {
114  if(eventBuilderPair.second.getNode("daqLink").isDisconnected())
115  continue;
116 
117  auto daqLink = eventBuilderPair.second.getNode("daqLink");
118 
119  if(daqLink.getNode("daqMetricsLink").isDisconnected())
120  continue;
121 
122  auto daqMetricsLinks = daqLink.getNode("daqMetricsLink").getChildren();
123  for(auto& daqMetricsLink :
124  daqMetricsLinks) // start daqMetricsLinks record loop
125  {
126  if(!daqMetricsLink.second.status())
127  continue;
128 
129  if(daqMetricsLink.second.getNode("metricParametersLink")
130  .isDisconnected())
131  continue;
132 
133  // ConfigurationTree slowControlsLink = configManager->getNode("ARTDAQMetricAlarmThresholdsTable");
134  ConfigurationTree slowControlsLink =
135  eventBuilderPair.second.getNode("MetricAlarmThresholdsLink");
136 
137  auto metricParametersLinks =
138  daqMetricsLink.second.getNode("metricParametersLink")
139  .getChildren();
140  for(auto& metricParametersLink :
141  metricParametersLinks) // start daq MetricParametersLinks record loop
142  {
143  if(!metricParametersLink.second.status())
144  continue;
145 
146  std::string subsystem =
147  metricParametersLink.second.getNode("metricParameterValue")
148  .getValueWithDefault<std::string>(std::string("TDAQ_") +
149  __ENV__("MU2E_OWNER"));
150  if(subsystem.find("Mu2e:") != std::string::npos)
151  subsystem = subsystem.replace(subsystem.find("Mu2e:"), 5, "");
152  while(subsystem.find("\"") != std::string::npos)
153  subsystem = subsystem.replace(subsystem.find("\""), 1, "");
154 
155  numberOfEventBuiderMetricParameters =
156  slowControlsHandler(out,
157  tabStr,
158  commentStr,
159  subsystem,
160  eventBuilderPair.first,
161  slowControlsLink,
162  channelList);
163 
164  __COUT__ << "EventBuilder '" << eventBuilderPair.first
165  << "' number of metrics for slow controls: "
166  << numberOfEventBuiderMetricParameters << __E__;
167  }
168  }
169  }
170  catch(const std::runtime_error& e)
171  {
172  __COUT_ERR__ << "Ignoring EventBuilder error: " << e.what() << __E__;
173  }
174  }
175  }
176 
177  return numberOfEventBuiderMetricParameters;
178 } // end slowControlsHandlerConfig()
179 
180 //==============================================================================
183 {
184  return SLOWCONTROL_PV_FILE_PATH;
185 }
186 
187 DEFINE_OTS_TABLE(ARTDAQEventBuilderTable)
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
static void outputDataReceiverFHICL(const ConfigurationTree &receiverNode, ARTDAQAppType appType, size_t maxFragmentSizeBytes=DEFAULT_MAX_FRAGMENT_SIZE, size_t routingTimeoutMs=DEFAULT_ROUTING_TIMEOUT_MS, size_t routingRetryCount=DEFAULT_ROUTING_RETRY_COUNT)
ConfigurationTree getNode(const std::string &nodeString, bool doNotThrowOnBrokenUIDLinks=false) const
"root/parent/parent/"
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
const std::string & getTableName(void) const
Getters.
Definition: TableBase.cc:681