otsdaq_mu2e  v2_04_02
DTCInterfaceTable_table.cc
1 #include "otsdaq-mu2e/TablePlugins/DTCInterfaceTable.h"
2 #include "otsdaq/Macros/TablePluginMacros.h" //for DEFINE_OTS_TABLE
3 
4 #include <sys/stat.h> //for mkdir
5 #include <iostream>
6 
7 using namespace ots;
8 
9 // clang-format off
10 
11 #define SLOWCONTROL_PV_FILE_PATH \
12  std::string( \
13  getenv("OTSDAQ_EPICS_DATA")? \
14  (std::string(getenv("OTSDAQ_EPICS_DATA")) + "/" + __ENV__("MU2E_OWNER") + "_otsdaq_dtc-ai.dbg"): \
15  (EPICS_CONFIG_PATH + "/otsdaq_dtc-ai.dbg") )
16 
17 // clang-format on
18 
19 //==============================================================================
20 DTCInterfaceTable::DTCInterfaceTable(void)
21  : TableBase("DTCInterfaceTable")
22  , SlowControlsTableBase("DTCInterfaceTable")
23 {
24 }
25 
26 //==============================================================================
27 DTCInterfaceTable::~DTCInterfaceTable(void)
28 {
29 }
30 
31 //==============================================================================
32 // init
33 // Generates EPICS PV config file
34 void DTCInterfaceTable::init(ConfigurationManager* configManager)
35 {
36 
37  lastConfigManager_ = configManager;
38 
39  // use isFirstAppInContext to only run once per context, for example to avoid
40  // generating files on local disk multiple times.
41  isFirstAppInContext_ = configManager->isOwnerFirstAppInContext();
42 
43  channelListHasChanged_ = false;
44 
45  //__COUTV__(isFirstAppInContext);
46  if(!isFirstAppInContext_)
47  return;
48 
49  // make directory just in case
50  mkdir(EPICS_CONFIG_PATH.c_str(), 0755);
51 
52  // check for valid data types
53  __COUT__ << "*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*" << __E__;
54  __COUT__ << configManager->__SELF_NODE__ << __E__;
55 
56  //outputEpicsPVFile(configManager);
57 } // end init()
58 
59 //==============================================================================
60 // Configuruing and start of slowControlsHandler function
61 unsigned int DTCInterfaceTable::slowControlsHandlerConfig (
62  std::stringstream& out
63  , ConfigurationManager* configManager
64  , std::vector<std::pair<std::string /*channelName*/, std::vector<std::string>>>* channelList /*= 0*/
65  ) const
66 {
68  // generate xdaq run parameter file
69 
70  std::string tabStr = "";
71  std::string commentStr = "";
72 
73  // loop through DTC records starting at FE Interface Table
74  std::vector<std::pair<std::string, ConfigurationTree>> feRecords =
75  configManager->getNode("FEInterfaceTable").getChildren();
76 
77  std::string rocPluginType;
78  unsigned int numberOfDTCs = 0;
79  std::string subsystem = std::string("TDAQ_") + __ENV__("MU2E_OWNER");
80 
81  for(auto& fePair : feRecords) // start main fe/DTC record loop
82  {
83  if(!fePair.second.status() ||
84  fePair.second.getNode(feColNames_.colFEInterfacePluginName_)
85  .getValue<std::string>() != DTC_FE_PLUGIN_TYPE)
86  continue;
87 
88  ++numberOfDTCs;
89 
90  // check each row in table
91  __COUT__ << "DTC record: " << fePair.first << __E__;
92 
93  // loop through each DTC slow controls channel and make entry in EPICS file
94  {
95  ConfigurationTree slowControlsLink =
96  fePair.second.getNode(feColNames_.colLinkToSlowControlsChannelTable_);
97  unsigned int numberOfDTCSlowControlsChannels =
98  slowControlsHandler(out,
99  tabStr,
100  commentStr,
101  subsystem,
102  fePair.first,
103  slowControlsLink,
104  channelList);
105 
106  __COUT__ << "DTC '" << fePair.first << "' number of slow controls channels: "
107  << numberOfDTCSlowControlsChannels << __E__;
108  } // end DTC slow controls channel handling
109 
110  // loop through ROC records
111  // use plugin type to indicate subsystem type
112 
113  ConfigurationTree DTCLink =
114  fePair.second.getNode(feColNames_.colLinkToFETypeTable);
115  if(DTCLink.isDisconnected())
116  {
117  __COUT__ << "Disconnected DTC type table information. So assuming no ROCs."
118  << __E__;
119  continue;
120  }
121  ConfigurationTree ROCLink = DTCLink.getNode(dtcColNames_.colLinkToROCGroupTable_);
122  if(ROCLink.isDisconnected())
123  {
124  __COUT__ << "Disconnected ROC link. So assuming no ROCs." << __E__;
125  continue;
126  }
127  std::vector<std::pair<std::string, ConfigurationTree>> rocChildren =
128  ROCLink.getChildren();
129 
130  unsigned int numberOfROCSlowControlsChannels;
131  for(auto& rocChildPair : rocChildren)
132  {
133  __COUT__ << "\t"
134  << "ROC record: " << rocChildPair.first << __E__;
135  numberOfROCSlowControlsChannels = 0;
136  try
137  {
138  rocPluginType =
139  rocChildPair.second.getNode(rocColNames_.colROCInterfacePluginName_)
140  .getValue<std::string>();
141  __COUTV__(rocPluginType);
142 
143  ConfigurationTree slowControlsLink = rocChildPair.second.getNode(
144  rocColNames_.colLinkToSlowControlsChannelTable_);
145  numberOfROCSlowControlsChannels = slowControlsHandler(out,
146  tabStr,
147  commentStr,
148  subsystem,
149  rocChildPair.first,
150  slowControlsLink,
151  channelList);
152  }
153  catch(const std::runtime_error& e)
154  {
155  __COUT_ERR__ << "Ignoring ROC error: " << e.what() << __E__;
156  }
157 
158  __COUT__ << "\t"
159  << "ROC '" << rocChildPair.first
160  << "' number of slow controls channels: "
161  << numberOfROCSlowControlsChannels << __E__;
162 
163  } // end ROC record loop
164  } // end main fe/DTC record loop
165 
166  return numberOfDTCs;
167 } // end slowControlsHandlerConfig()
168 
169 //==============================================================================
170 // return out file path
171 std::string DTCInterfaceTable::setFilePath() const { return SLOWCONTROL_PV_FILE_PATH; }
172 
173 DEFINE_OTS_TABLE(DTCInterfaceTable)