tdaq-develop-2025-02-12
FEVInterface.h
1 #ifndef _ots_FEVInterface_h_
2 #define _ots_FEVInterface_h_
3 
4 #define TRACEMF_USE_VERBATIM 1 // for trace longer path filenames
5 #include "artdaq/DAQdata/Globals.hh"
6 
7 #include "otsdaq/Configurable/Configurable.h"
8 #include "otsdaq/FECore/FESlowControlsWorkLoop.h"
9 #include "otsdaq/FiniteStateMachine/VStateMachine.h"
10 #include "otsdaq/WorkLoopManager/WorkLoop.h"
11 
12 #include "otsdaq/CoreSupervisors/CoreSupervisorBase.h"
13 
14 #include "otsdaq/SupervisorInfo/AllSupervisorInfo.h" //to send errors to Gateway, e.g.
15 
16 #include "otsdaq/FECore/FESlowControlsChannel.h"
17 #include "otsdaq/SOAPUtilities/SOAPMessenger.h" //for xdaq::ApplicationDescriptor communication
18 
19 #include <array>
20 #include <iostream>
21 #include <string>
22 #include <vector>
23 
24 #include "otsdaq/Macros/CoutMacros.h"
25 
26 #define __ARGS__ \
27  [[maybe_unused]] const frontEndMacroStruct_t & feMacroStruct, \
28  [[maybe_unused]] FEVInterface::frontEndMacroConstArgs_t argsIn, \
29  [[maybe_unused]] FEVInterface::frontEndMacroArgs_t argsOut
30 
31 #define __GET_ARG_IN_NO_DEFAULT__(X, Y) getFEMacroConstArgumentValue<Y>(argsIn, X)
32 #define __GET_ARG_IN_DEFAULT__(X, Y, D) getFEMacroConstArgumentValue<Y>(argsIn, X, D)
33 #define GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4
34 #define __GET_ARG_IN_CHOOSER__(...) \
35  GET_4TH_ARG(__VA_ARGS__, __GET_ARG_IN_DEFAULT__, __GET_ARG_IN_NO_DEFAULT__, )
36 #define __GET_ARG_IN__(...) __GET_ARG_IN_CHOOSER__(__VA_ARGS__)(__VA_ARGS__)
37 #define __GET_ARG_OUT__(X, Y) getFEMacroArgumentValue<Y>(argsOut, X)
38 
39 #define __SET_ARG_IN__(X, Y) FEVInterface::emplaceFEMacroArgumentValue(argsIn, X, Y)
40 #define __SET_ARG_OUT__(X, Y) FEVInterface::setFEMacroArgumentValue(argsOut, X, Y)
41 
42 namespace ots
43 {
44 class FEVInterfacesManager;
45 
55 class FEVInterface : public WorkLoop, public Configurable, public VStateMachine
56 {
57  // clang-format off
58 
59  friend class FEVInterfacesManager;
60 
61  public:
63  const std::string& interfaceUID,
64  const ConfigurationTree& theXDAQContextConfigTree,
65  const std::string& configurationPath);
66 
67  virtual ~FEVInterface(void);
68 
69  FEVInterfacesManager* parentInterfaceManager_;
70 
71  const std::string& getInterfaceUID (void) const { return interfaceUID_; }
72  const std::string& getInterfaceType (void) const { return interfaceType_; }
73 
74  virtual void universalRead (char* address, char* returnValue) = 0;
75  virtual void universalWrite (char* address, char* writeValue) = 0;
76  const unsigned int& getUniversalAddressSize (void) { return universalAddressSize_; }
77  const unsigned int& getUniversalDataSize (void) { return universalDataSize_; }
78  virtual void universalBlockRead (char* address, char* returnValue, unsigned int numberOfBytes) { throw std::runtime_error("UNDEFINED BLOCK READ"); /* to make compiler happy, use params */ __COUTV__((void*)address); __COUTV__((void*)returnValue); __COUTV__(numberOfBytes); }
80  virtual void universalBlockWrite (char* address, char* writeValue, unsigned int numberOfBytes) { throw std::runtime_error("UNDEFINED BLOCK WRITE"); /* to make compiler happy, use params */ __COUTV__((void*)address); __COUTV__((void*)writeValue); __COUTV__(numberOfBytes); }
81 
82 
83  void runSequenceOfCommands (const std::string& treeLinkName);
84 
85  static void sendAsyncExceptionToGateway (FEVInterface* fe, const std::string& errMsg, bool isPauseException, bool isStopException);
86 
89  virtual void configure (void)
90  {
91  __COUT__ << "\t Configure" << std::endl;
93  "LinkToConfigureSequence"); /*Run Configure Sequence Commands*/
94  }
95  virtual void start (std::string /*runNumber*/)
96  {
97  __COUT__ << "\t Start" << std::endl;
98  runSequenceOfCommands("LinkToStartSequence"); /*Run Start Sequence Commands*/
99  }
100  virtual void stop (void)
101  {
102  __COUT__ << "\t Stop" << std::endl;
103  runSequenceOfCommands("LinkToStopSequence"); /*Run Stop Sequence Commands*/
104  }
105  virtual void halt (void) { stop(); }
106  virtual void pause (void) { stop(); }
107  virtual void resume (void) { start(""); }
108  virtual bool running (void) { /*while(WorkLoop::continueWorkLoop_){;}*/ return false; }
114  virtual void configureSlowControls (void);
115  void addSlowControlsChannels (ConfigurationTree slowControlsGroupLink, std::map<std::string /* ROC UID*/, FESlowControlsChannel>* mapOfSlowControlsChannels);
116 
117  virtual void resetSlowControlsChannelIterator (void);
119  virtual unsigned int getSlowControlsChannelCount (void);
120  bool slowControlsRunning (void);
121  void startSlowControlsWorkLoop (void) { slowControlsWorkLoop_.startWorkLoop(); }
122  void stopSlowControlsWorkLoop (void) { slowControlsWorkLoop_.stopWorkLoop(); }
123 
124 
125  static const std::string UNKNOWN_TYPE;
126 
127  protected:
129  std::map<std::string, FESlowControlsChannel> mapOfSlowControlsChannels_;
130  std::map<std::string,
131  FESlowControlsChannel>::iterator slowControlsChannelsIterator_;
132  FESlowControlsWorkLoop slowControlsWorkLoop_;
138  public:
140  using frontEndMacroArg_t = std::pair<const std::string /* arg name */, std::string /* arg return value */>;
141  using frontEndMacroArgs_t = std::vector<frontEndMacroArg_t>&;
142  using frontEndMacroConstArgs_t = const std::vector<frontEndMacroArg_t>&;
143  struct frontEndMacroStruct_t;
144  using frontEndMacroFunction_t = void (ots::FEVInterface::*)(__ARGS__);
146  {
148  const std::string& feMacroName,
149  const frontEndMacroFunction_t& feMacroFunction,
150  const std::vector<std::string>& namesOfInputArgs,
151  const std::vector<std::string>& namesOfOutputArgs,
152  const std::string& requiredUserPermissions = "1" /*Level definition: 0:no-access,1:=user,255:=admin*/,
153  const std::string& allowedCallingFrontEnds = "*" /*StringMacros:: wild card set match string (i.e. string-to-set, then wild-card-set match)*/,
154  const std::string& feMacroTooltip = "")
155  : feMacroName_ (feMacroName)
156  , macroFunction_ (feMacroFunction)
157  , namesOfInputArguments_ (namesOfInputArgs)
158  , namesOfOutputArguments_ (namesOfOutputArgs)
159  , requiredUserPermissions_ (requiredUserPermissions)
160  , allowedCallingFrontEnds_ (allowedCallingFrontEnds)
161  , feMacroTooltip_ (feMacroTooltip)
162  {
163  }
164 
165  const std::string feMacroName_;
167  const std::vector<std::string> namesOfInputArguments_, namesOfOutputArguments_;
168  const std::string requiredUserPermissions_;
169  const std::string allowedCallingFrontEnds_;
170  const std::string feMacroTooltip_;
171  }; //end frontEndMacroStruct_t
172  const std::map<std::string, frontEndMacroStruct_t>& getMapOfFEMacroFunctions(void)
173  {
174  return mapOfFEMacroFunctions_;
175  }
176  void runSelfFrontEndMacro (
177  const std::string& feMacroName,
178  const std::vector<FEVInterface::frontEndMacroArg_t>& inputArgs,
179  std::vector<FEVInterface::frontEndMacroArg_t>& outputArgs);
186  {
187  macroStruct_t(const std::string& macroString);
188 
189  enum
190  {
191  OP_TYPE_READ,
192  OP_TYPE_WRITE,
193  OP_TYPE_DELAY,
194  };
195 
196  struct readOp_t
197  {
198  uint64_t address_;
199  bool addressIsVar_;
200  std::string addressVarName_;
201  bool dataIsVar_;
202  std::string dataVarName_;
203  }; // end macroStruct_t::writeOp_t declaration
204 
205  struct writeOp_t
206  {
207  uint64_t address_;
208  bool addressIsVar_;
209  std::string addressVarName_;
210  uint64_t data_;
211  bool dataIsVar_;
212  std::string dataVarName_;
213  }; // end macroStruct_t::writeOp_t declaration
214 
215  struct delayOp_t
216  {
217  uint64_t delay_;
218  bool delayIsVar_;
219  std::string delayVarName_;
220  }; // end macroStruct_t::writeOp_t declaration
221 
222  std::string macroName_;
223  std::vector<std::pair<unsigned int /*op type*/,
224  unsigned int /*index in specific type vector*/> >
225  operations_;
226  std::vector<macroStruct_t::readOp_t> readOps_;
227  std::vector<macroStruct_t::writeOp_t> writeOps_;
228  std::vector<macroStruct_t::delayOp_t> delayOps_;
229  std::set<std::string> namesOfInputArguments_, namesOfOutputArguments_;
230  bool lsbf_;
231  }; // end macroStruct_t declaration
232  protected:
234  std::map<std::string /*name*/, uint64_t /*value*/>& variableMap);
235 
236  public:
243  template<class T>
244  void sendToFrontEnd (const std::string& targetInterfaceID, const T& value) const;
245  void runFrontEndMacro (const std::string& targetInterfaceID,const std::string& feMacroName, const std::vector<FEVInterface::frontEndMacroArg_t>& inputArgs, std::vector<FEVInterface::frontEndMacroArg_t>& outputArgs) const;
246 
251  template<class T>
252  void receiveFromFrontEnd (const std::string& requester, T& retValue, unsigned int timeoutInSeconds = 1) const;
254  void receiveFromFrontEnd (const std::string& requester, std::string& retValue, unsigned int timeoutInSeconds = 1) const;
257  template<class T>
258  T receiveFromFrontEnd (const std::string& requester = "*", unsigned int timeoutInSeconds = 1) const;
260  std::string receiveFromFrontEnd (const std::string& requester = "*", unsigned int timeoutInSeconds = 1) const;
261 
265  protected:
266  bool workLoopThread (toolbox::task::WorkLoop* workLoop);
267 
268  std::string interfaceUID_, interfaceType_;
269  std::string mfSubject_;
270 
271  unsigned int universalAddressSize_ = 0;
272  unsigned int universalDataSize_ = 0;
273 
274 
277  std::map<std::string, frontEndMacroStruct_t> mapOfFEMacroFunctions_;
279  const std::string& feMacroName,
280  frontEndMacroFunction_t feMacroFunction,
281  const std::vector<std::string>& namesOfInputArgs,
282  const std::vector<std::string>& namesOfOutputArgs,
283  uint8_t requiredUserPermissions = 1 /*Level definition: 0:no-access,1:=user,255:=admin*/,
284  const std::string& allowedCallingFEs = "*" /*StringMacros:: wild card set match string (i.e. string-to-set, then wild-card-set match)*/,
285  const std::string& feMacroTooltip = "");
287  const std::string& feMacroName,
288  frontEndMacroFunction_t feMacroFunction,
289  const std::vector<std::string>& namesOfInputArgs,
290  const std::vector<std::string>& namesOfOutputArgs,
291  const std::string& requiredUserPermissions = WebUsers::DEFAULT_USER_GROUP + ":1" /*Level definition: 0:no-access,1:=user,255:=admin*/,
292  const std::string& allowedCallingFEs = "*" /*StringMacros:: wild card set match string (i.e. string-to-set, then wild-card-set match)*/,
293  const std::string& feMacroTooltip = "");
294 
295  public:
296  static const std::string& getFEMacroConstArgument (frontEndMacroConstArgs_t args, const std::string& argName);
297  static std::string& getFEMacroArgument (frontEndMacroArgs_t args, const std::string& argName);
298 
299  protected:
300  template<class T>
301  std::string& setFEMacroArgumentValue (frontEndMacroArgs_t args, const std::string& argName, const T& value) const;
302 
303  template<class T>
304  std::string& emplaceFEMacroArgumentValue (frontEndMacroArgs_t args, const std::string& argName, const T& value) const;
305 
306 
307 }; // end FEVInterface class
308 
309 template<class T>
310 T getFEMacroConstArgumentValue (FEVInterface::frontEndMacroConstArgs_t args, const std::string& argName, const T& defaultValue = T());
311 
313 template<>
314 std::string getFEMacroConstArgumentValue<std::string> (FEVInterface::frontEndMacroConstArgs_t args, const std::string& argName, const std::string& defaultValue);
315 
316 template<class T>
317 T getFEMacroArgumentValue (FEVInterface::frontEndMacroArgs_t args, const std::string& argName);
318 
320 template<>
321 std::string getFEMacroArgumentValue<std::string> (FEVInterface::frontEndMacroArgs_t argsIn, const std::string& argName);
322 
324 #include "otsdaq/FECore/FEVInterface.icc"
325 
326 // clang-format on
327 
328 } // namespace ots
329 
330 #endif
void runMacro(FEVInterface::macroStruct_t &macro, std::map< std::string, uint64_t > &variableMap)
runMacro
virtual void resetSlowControlsChannelIterator(void)
virtual in case channels are handled in multiple maps, for example
void(ots::FEVInterface::*)(const frontEndMacroStruct_t &feMacroStruct, FEVInterface::frontEndMacroConstArgs_t argsIn, FEVInterface::frontEndMacroArgs_t argsOut) frontEndMacroFunction_t
void function (vector-of-inputs, vector-of-outputs)
Definition: FEVInterface.h:144
virtual void configureSlowControls(void)
end State Machine handlers
Definition: FEVInterface.cc:65
static void sendAsyncExceptionToGateway(FEVInterface *fe, const std::string &errMsg, bool isPauseException, bool isStopException)
void runSequenceOfCommands(const std::string &treeLinkName)
virtual void configure(void)
Definition: FEVInterface.h:89
std::map< std::string, frontEndMacroStruct_t > mapOfFEMacroFunctions_
Map of FE Macro functions members.
Definition: FEVInterface.h:277
static const std::string & getFEMacroConstArgument(frontEndMacroConstArgs_t args, const std::string &argName)
< for external specialized template access
bool universalBlockReadImplementationConfirmed
is confirmed by slow controls handling (for example) that universalBlockRead is implemented by the FE...
Definition: FEVInterface.h:79
void addSlowControlsChannels(ConfigurationTree slowControlsGroupLink, std::map< std::string, FESlowControlsChannel > *mapOfSlowControlsChannels)
std::string mfSubject_
for GEN_COUT decorations which would be safe in destructors, e.g. mirror interfaceUID_
Definition: FEVInterface.h:269
std::pair< const std::string, std::string > frontEndMacroArg_t
end Slow Controls
Definition: FEVInterface.h:140
virtual FESlowControlsChannel * getNextSlowControlsChannel(void)
virtual in case channels are handled in multiple maps, for example
void runFrontEndMacro(const std::string &targetInterfaceID, const std::string &feMacroName, const std::vector< FEVInterface::frontEndMacroArg_t > &inputArgs, std::vector< FEVInterface::frontEndMacroArg_t > &outputArgs) const
virtual void universalRead(char *address, char *returnValue)=0
throw std::runtime_error exception on error/timeout
void runSelfFrontEndMacro(const std::string &feMacroName, const std::vector< FEVInterface::frontEndMacroArg_t > &inputArgs, std::vector< FEVInterface::frontEndMacroArg_t > &outputArgs)
T receiveFromFrontEnd(const std::string &requester="*", unsigned int timeoutInSeconds=1) const
static std::string & getFEMacroArgument(frontEndMacroArgs_t args, const std::string &argName)
virtual bool running(void)
Definition: FEVInterface.h:108
bool slowControlsRunning(void)
slow controls workloop calls this
virtual unsigned int getSlowControlsChannelCount(void)
virtual in case channels are handled in multiple maps, for example
void receiveFromFrontEnd(const std::string &requester, T &retValue, unsigned int timeoutInSeconds=1) const
bool workLoopThread(toolbox::task::WorkLoop *workLoop)
end FE Communication helpers //////
void sendToFrontEnd(const std::string &targetInterfaceID, const T &value) const
end FE Macros
void registerFEMacroFunction(const std::string &feMacroName, frontEndMacroFunction_t feMacroFunction, const std::vector< std::string > &namesOfInputArgs, const std::vector< std::string > &namesOfOutputArgs, uint8_t requiredUserPermissions=1, const std::string &allowedCallingFEs="*", const std::string &feMacroTooltip="")
std::map< std::string, FESlowControlsChannel > mapOfSlowControlsChannels_
Slow Controls members.
Definition: FEVInterface.h:129
< members fully define a front-end macro function
Definition: FEVInterface.h:146
const frontEndMacroFunction_t macroFunction_
Note: must be called using this instance.
Definition: FEVInterface.h:166
macroStruct_t(const std::string &macroString)
macroStruct_t constructor
bool lsbf_
least significant byte first
Definition: FEVInterface.h:230