otsdaq  v2_01_00
FEVInterface.h
1 #ifndef _ots_FEVInterface_h_
2 #define _ots_FEVInterface_h_
3 
4 #include "otsdaq-core/FiniteStateMachine/VStateMachine.h"
5 #include "otsdaq-core/WorkLoopManager/WorkLoop.h"
6 #include "otsdaq-core/Configurable/Configurable.h"
7 #include "otsdaq-core/FECore/FESlowControlsWorkLoop.h"
8 
9 
10 //#include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
11 #include "otsdaq-core/FECore/FESlowControlsChannel.h"
12 
13 #include <string>
14 #include <iostream>
15 #include <vector>
16 #include <array>
17 
18 #define __ARGS__ FEVInterface::frontEndMacroInArgs_t argsIn, FEVInterface::frontEndMacroOutArgs_t argsOut
19 #define __GET_ARG_IN__(X,Y) getFEMacroInputArgumentValue<Y> (argsIn ,X)
20 #define __GET_ARG_OUT__(X) FEVInterface::getFEMacroOutputArgument (argsOut,X)
21 #define __SET_ARG_OUT__(X,Y) FEVInterface::setFEMacroOutputArgumentValue (argsOut,X,Y)
22 
23 namespace ots
24 {
25 
26 class FrontEndHardwareBase;
27 class FrontEndFirmwareBase;
28 class FEInterfaceConfigurationBase;
29 //class SlowControlsChannelInfo;
30 
31 //FEVInterface
32 // This class is a virtual class defining the features of front-end interface plugin class.
33 // The features include configuration hooks, finite state machine handlers, Front-end Macros for web accessible C++ handlers, slow controls hooks, as well as universal write and read for
34 // Macro Maker compatibility.
35 class FEVInterface : public VStateMachine, public WorkLoop, public Configurable
36 {
37 public:
38 
39  FEVInterface (const std::string& interfaceUID, const ConfigurationTree& theXDAQContextConfigTree, const std::string& configurationPath)
40 : WorkLoop (interfaceUID)
41 , Configurable (theXDAQContextConfigTree, configurationPath)
42 , interfaceUID_ (interfaceUID)
43 , interfaceType_ (theXDAQContextConfigTree_.getBackNode(theConfigurationPath_).getNode("FEInterfacePluginName").getValue<std::string>())
44 , daqHardwareType_ ("NOT SET")
45 , firmwareType_ ("NOT SET")
46 , slowControlsWorkLoop_ (interfaceUID + "-SlowControls", this)
47 {}
48 
49  virtual ~FEVInterface (void) {;}
50 
52  //start OLD - but keeping around for a while, in case we realize we need it
53  //
54  //virtual void initLocalGroup (int local_group_comm_) {std::cout << __PRETTY_FUNCTION__ << std::endl;}
55  //void setConfigurationManager(ConfigurationManager* configurationManager){theConfigurationManager_ = configurationManager;}
56  //virtual void configureDetector(const DACStream& theDACStream) = 0;
57  //virtual void resetDetector() = 0;
58  //virtual void configureFEW (void) = 0;
59  //
60  //end OLD
62 
63  const std::string& getInterfaceUID (void) const {return interfaceUID_;}
64  const std::string& getDaqHardwareType (void) const {return daqHardwareType_;}
65  const std::string& getFirmwareType (void) const {return firmwareType_;}
66  const std::string& getInterfaceType (void) const {return interfaceType_;}
67 
68  virtual int universalRead (char* address, char* returnValue) = 0;
69  virtual void universalWrite (char* address, char* writeValue) = 0;
70  const unsigned int& getUniversalAddressSize (void) {return universalAddressSize_;}
71  const unsigned int& getUniversalDataSize (void) {return universalDataSize_;}
72 
73  FrontEndHardwareBase* getHardwareP (void) const {return theFrontEndHardware_;}
74  FrontEndFirmwareBase* getFirmwareP (void) const {return theFrontEndFirmware_;}
75 
76  void runSequenceOfCommands (const std::string &treeLinkName);
77 
79  //start State Machine handlers
80  void configure (void) { __COUT__ << "\t Configure" << std::endl; runSequenceOfCommands("LinkToConfigureSequence"); /*Run Configure Sequence Commands*/}
81  void start (std::string runNumber) { __COUT__ << "\t Start" << std::endl; runSequenceOfCommands("LinkToStartSequence"); /*Run Start Sequence Commands*/}
82  void stop (void) { __COUT__ << "\t Stop" << std::endl; runSequenceOfCommands("LinkToStopSequence"); /*Run Stop Sequence Commands*/}
83  void halt (void) { stop();}
84  void pause (void) { stop();}
85  void resume (void) { start("");}
86  bool running (void) { /*while(WorkLoop::continueWorkLoop_){;}*/ return false;}
87  //end State Machine handlers
89 
91  //start Slow Controls
92  void configureSlowControls (void);
93  bool slowControlsRunning (void);
94  void startSlowControlsWorkLooop (void) {slowControlsWorkLoop_.startWorkLoop();}
95  void stopSlowControlsWorkLooop (void) {slowControlsWorkLoop_.stopWorkLoop();}
96  //end Slow Controls
98 
99 
101  //start FE Macros
102 
103  //public types and functions for map of FE macros
104  using frontEndMacroInArg_t = std::pair<const std::string /* input arg name */ , const std::string /* arg input value */ >;
105  using frontEndMacroInArgs_t = const std::vector<frontEndMacroInArg_t> &;
106  using frontEndMacroOutArg_t = std::pair<const std::string /* output arg name */, std::string /* arg return value */>;
107  using frontEndMacroOutArgs_t = std::vector<frontEndMacroOutArg_t> &;
108  using frontEndMacroFunction_t = void (ots::FEVInterface::* )(frontEndMacroInArgs_t, frontEndMacroOutArgs_t); //void function (vector-of-inputs, vector-of-outputs)
109  struct frontEndMacroStruct_t //members fully define a front-end macro function
110  {
111  frontEndMacroStruct_t(const frontEndMacroFunction_t &feMacroFunction,
112  const std::vector<std::string> &namesOfInputArgs,
113  const std::vector<std::string> &namesOfOutputArgs,
114  const uint8_t requiredUserPermissions)
115  :macroFunction_(feMacroFunction)
116  ,namesOfInputArguments_(namesOfInputArgs)
117  ,namesOfOutputArguments_(namesOfOutputArgs)
118  ,requiredUserPermissions_(requiredUserPermissions)
119  {}
120 
121  const frontEndMacroFunction_t macroFunction_; //Note: must be called using this instance
122  const std::vector<std::string> namesOfInputArguments_, namesOfOutputArguments_;
123  const uint8_t requiredUserPermissions_;
124  };
125  const std::map<std::string, frontEndMacroStruct_t>& getMapOfFEMacroFunctions() {return mapOfFEMacroFunctions_;}
126  //end FE Macros
128 
129 protected:
130  bool workLoopThread(toolbox::task::WorkLoop* workLoop){continueWorkLoop_ = running(); /* in case users return false, without using continueWorkLoop_*/ return continueWorkLoop_;}
131  std::string interfaceUID_;
132  std::string interfaceType_;
133 
134 
135  std::string daqHardwareType_;
136  std::string firmwareType_;
137 
138  FrontEndHardwareBase* theFrontEndHardware_ = nullptr;
139  FrontEndFirmwareBase* theFrontEndFirmware_ = nullptr;
140 
141  unsigned int universalAddressSize_ = 0;
142  unsigned int universalDataSize_ = 0;
143 
144  //Controls members
145  std::map<std::string, FESlowControlsChannel> mapOfSlowControlsChannels_;
146  FESlowControlsWorkLoop slowControlsWorkLoop_;
147 
148 
149  //FE Macro Function members and helper functions:
150 
151  std::map<std::string, frontEndMacroStruct_t> mapOfFEMacroFunctions_; //Map of FE Macro functions members
152  void registerFEMacroFunction(const std::string &feMacroName, frontEndMacroFunction_t feMacroFunction, const std::vector<std::string> &namesOfInputArgs, const std::vector<std::string> &namesOfOutputArgs, uint8_t requiredUserPermissions);
153 
154 public: //for external specialized template access
155  static const std::string& getFEMacroInputArgument (frontEndMacroInArgs_t &argsIn, const std::string &argName);
156 protected:
157  static std::string& getFEMacroOutputArgument (frontEndMacroOutArgs_t &argsOut, const std::string& argName);
158 
159 
160  template<class T>
161  std::string& setFEMacroOutputArgumentValue(
162  frontEndMacroOutArgs_t &argsOut,
163  const std::string &argName, const T& value) const
164  {
165  std::string& argOut = getFEMacroOutputArgument(argsOut,argName);
166  std::stringstream ss; ss << value;
167  argOut = ss.str();
168  return argOut;
169  }
170 
171 };
172 
173 
174 template<class T>
175 T getFEMacroInputArgumentValue(
176  FEVInterface::frontEndMacroInArgs_t &argsIn, const std::string &argName)
177 {
178  //stolen from ConfigurationView
179  // only handles number types (strings are handled in non-template function override
180 
181  const std::string& data = FEVInterface::getFEMacroInputArgument(argsIn, argName);
182 
183 
184  T retValue;
185 
186  if(!StringMacros::getNumber(data,retValue))
187  {
188  __SS__ << "Error extracting value for argument named '" <<
189  argName << ".' The value '" << data << "' is not a number!" << std::endl;
190  __COUT__ << "\n" << ss.str();
191  throw std::runtime_error(ss.str());
192  }
193 
194  return retValue;
195 }
196 //specialized template version of getFEMacroInputArgumentValue for string
197 template<>
198 std::string getFEMacroInputArgumentValue<std::string> (FEVInterface::frontEndMacroInArgs_t &argsIn, const std::string &argName);
199 
200 
201 }
202 
203 #endif