psddl_psana/include/EpicsLib.h

Go to the documentation of this file.
00001 #ifndef PSDDL_PSANA_EPICSLIB_H
00002 #define PSDDL_PSANA_EPICSLIB_H
00003 
00004 //--------------------------------------------------------------------------
00005 // File and Version Information:
00006 //      $Id: EpicsLib.h 5771 2013-03-15 23:50:14Z salnikov@SLAC.STANFORD.EDU $
00007 //
00008 // Description:
00009 //      Class EpicsLib.
00010 //
00011 //------------------------------------------------------------------------
00012 
00013 //-----------------
00014 // C/C++ Headers --
00015 //-----------------
00016 #include <string>
00017 #include <stdexcept>
00018 #include <boost/numeric/conversion/cast.hpp>
00019 #include <boost/lexical_cast.hpp>
00020 
00021 //----------------------
00022 // Base Class Headers --
00023 //----------------------
00024 
00025 //-------------------------------
00026 // Collaborating Class Headers --
00027 //-------------------------------
00028 #include "psddl_psana/epics.ddl.h"
00029 
00030 //------------------------------------
00031 // Collaborating Class Declarations --
00032 //------------------------------------
00033 
00034 //              ---------------------
00035 //              -- Class Interface --
00036 //              ---------------------
00037 
00038 namespace Psana {
00039 namespace EpicsLib {
00040 
00041 /**
00042  *  Set of helper classes simplifying access to EPICS data.
00043  *
00044  *  This software was developed for the LCLS project.  If you use all or 
00045  *  part of it, please give an appropriate acknowledgment.
00046  *
00047  *  @version $Id: EpicsLib.h 5771 2013-03-15 23:50:14Z salnikov@SLAC.STANFORD.EDU $
00048  *
00049  *  @author Andrei Salnikov
00050  */
00051 
00052 /**
00053  *  Non-specialized version of the class which extracts value from
00054  *  EPICS PV and converts it to requested type. This version works for
00055  *  numeric EPICS types and numeric resulting types.
00056  */
00057 template <typename PVClass, typename ValueType>
00058 struct EpicsValue {
00059   static ValueType value(const Epics::EpicsPvHeader& pv, int index) {
00060     return boost::numeric_cast<ValueType>(static_cast<const PVClass&>(pv).value(index));
00061   }
00062 };
00063 
00064 /**
00065  *  Specialized version of the class which extracts value from
00066  *  EPICS PV and converts it to requested type. This version works for
00067  *  numeric EPICS types and std::string as result type.
00068  */
00069 template <typename PVClass>
00070 struct EpicsValue<PVClass, std::string> {
00071   static std::string value(const Epics::EpicsPvHeader& pv, int index) {
00072     return boost::lexical_cast<std::string>(static_cast<const PVClass&>(pv).value(index));
00073   }
00074 };
00075 
00076 /**
00077  *  Specialized version of the class which extracts value from
00078  *  EPICS PV and converts it to requested type. This version works for
00079  *  string EPICS types and numeric result type.
00080  */
00081 template <typename ValueType>
00082 struct EpicsValue<Epics::EpicsPvCtrlString, ValueType> {
00083   static ValueType value(const Epics::EpicsPvHeader& pv, int index) {
00084     return boost::lexical_cast<ValueType>(
00085         static_cast<const Epics::EpicsPvCtrlString&>(pv).value(index));
00086   }
00087 };
00088 
00089 /**
00090  *  Specialized version of the class which extracts value from
00091  *  EPICS PV and converts it to requested type. This version works for
00092  *  string EPICS types and numeric result type.
00093  */
00094 template <typename ValueType>
00095 struct EpicsValue<Epics::EpicsPvTimeString, ValueType> {
00096   static ValueType value(const Epics::EpicsPvHeader& pv, int index) {
00097     return boost::lexical_cast<ValueType>(
00098         static_cast<const Epics::EpicsPvTimeString&>(pv).value(index));
00099   }
00100 };
00101 
00102 /**
00103  *  Specialized version of the class which extracts value from
00104  *  EPICS PV and converts it to requested type. This version works for
00105  *  string EPICS types and string result type.
00106  */
00107 template <>
00108 struct EpicsValue<Epics::EpicsPvCtrlString, std::string> {
00109   static std::string value(const Epics::EpicsPvHeader& pv, int index) {
00110     return static_cast<const Epics::EpicsPvCtrlString&>(pv).value(index);
00111   }
00112 };
00113 
00114 /**
00115  *  Specialized version of the class which extracts value from
00116  *  EPICS PV and converts it to requested type. This version works for
00117  *  string EPICS types and string result type.
00118  */
00119 template <>
00120 struct EpicsValue<Epics::EpicsPvTimeString, std::string> {
00121   static std::string value(const Epics::EpicsPvHeader& pv, int index) {
00122     return static_cast<const Epics::EpicsPvTimeString&>(pv).value(index);
00123   }
00124 };
00125 
00126 
00127 /**
00128  *  Function which extracts value from EPICS PV and converts it to requested type.
00129  *  
00130  *  @throw boost::numeric::bad_numeric_cast  in case of overflows 
00131  *  @throw boost::bad_lexical_cast   if string vale cannot be converted to number
00132  *  @throw std::invalid_argument   if PV has unexpected type
00133  */
00134 template <typename ValueType>
00135 ValueType getEpicsValue(const Epics::EpicsPvHeader& pv, int index)
00136 {
00137   switch(pv.dbrType()) {
00138   case Epics::DBR_TIME_STRING:
00139     return EpicsValue<Epics::EpicsPvTimeString,ValueType>::value(pv, index);
00140   case Epics::DBR_TIME_SHORT:
00141     return EpicsValue<Epics::EpicsPvTimeShort,ValueType>::value(pv, index);
00142   case Epics::DBR_TIME_FLOAT:
00143     return EpicsValue<Epics::EpicsPvTimeFloat,ValueType>::value(pv, index);
00144   case Epics::DBR_TIME_ENUM:
00145     return EpicsValue<Epics::EpicsPvTimeEnum,ValueType>::value(pv, index);
00146   case Epics::DBR_TIME_CHAR:
00147     return EpicsValue<Epics::EpicsPvTimeChar,ValueType>::value(pv, index);
00148   case Epics::DBR_TIME_LONG:
00149     return EpicsValue<Epics::EpicsPvTimeLong,ValueType>::value(pv, index);
00150   case Epics::DBR_TIME_DOUBLE:
00151     return EpicsValue<Epics::EpicsPvTimeDouble,ValueType>::value(pv, index);
00152   case Epics::DBR_CTRL_STRING:
00153     return EpicsValue<Epics::EpicsPvCtrlString,ValueType>::value(pv, index);
00154   case Epics::DBR_CTRL_SHORT:
00155     return EpicsValue<Epics::EpicsPvCtrlShort,ValueType>::value(pv, index);
00156   case Epics::DBR_CTRL_FLOAT:
00157     return EpicsValue<Epics::EpicsPvCtrlFloat,ValueType>::value(pv, index);
00158   case Epics::DBR_CTRL_ENUM:
00159     return EpicsValue<Epics::EpicsPvCtrlEnum,ValueType>::value(pv, index);
00160   case Epics::DBR_CTRL_CHAR:
00161     return EpicsValue<Epics::EpicsPvCtrlChar,ValueType>::value(pv, index);
00162   case Epics::DBR_CTRL_LONG:
00163     return EpicsValue<Epics::EpicsPvCtrlLong,ValueType>::value(pv, index);
00164   case Epics::DBR_CTRL_DOUBLE:
00165     return EpicsValue<Epics::EpicsPvCtrlDouble,ValueType>::value(pv, index);
00166   default:
00167     throw std::invalid_argument("EpicsLib::getEpicsValue - unexpected PV type: " +
00168         boost::lexical_cast<std::string>(pv.dbrType()));
00169   }
00170 }
00171 
00172 
00173 /**
00174  * Type traits for epics DBR types. DBR can be one of the dbr_time_xxx or dbr_ctrl_xxx types.
00175  */
00176 template <typename DBR>
00177 struct DBRTypeTraits {  
00178 };
00179 
00180 template <>
00181 struct DBRTypeTraits<Epics::dbr_time_string> {
00182   typedef char value_type[Epics::MAX_STRING_SIZE];
00183   typedef Epics::EpicsPvTimeString pv_type;
00184 };
00185 
00186 template <>
00187 struct DBRTypeTraits<Epics::dbr_time_enum> {
00188   typedef uint16_t value_type;
00189   typedef Epics::EpicsPvTimeEnum pv_type;
00190 };
00191 
00192 template <>
00193 struct DBRTypeTraits<Epics::dbr_time_char> {
00194   typedef uint8_t value_type;
00195   typedef Epics::EpicsPvTimeChar pv_type;
00196 };
00197 
00198 template <>
00199 struct DBRTypeTraits<Epics::dbr_time_short> {
00200   typedef int16_t value_type;
00201   typedef Epics::EpicsPvTimeShort pv_type;
00202 };
00203 
00204 template <>
00205 struct DBRTypeTraits<Epics::dbr_time_long> {
00206   typedef int32_t value_type;
00207   typedef Epics::EpicsPvTimeLong pv_type;
00208 };
00209 
00210 template <>
00211 struct DBRTypeTraits<Epics::dbr_time_float> {
00212   typedef float value_type;
00213   typedef Epics::EpicsPvTimeFloat pv_type;
00214 };
00215 
00216 template <>
00217 struct DBRTypeTraits<Epics::dbr_time_double> {
00218   typedef double value_type;
00219   typedef Epics::EpicsPvTimeDouble pv_type;
00220 };
00221 
00222 template <>
00223 struct DBRTypeTraits<Epics::dbr_sts_string> {
00224   typedef char value_type[Epics::MAX_STRING_SIZE];
00225   typedef Epics::EpicsPvCtrlString pv_type;
00226 };
00227 
00228 template <>
00229 struct DBRTypeTraits<Epics::dbr_ctrl_enum> {
00230   typedef uint16_t value_type;
00231   typedef Epics::EpicsPvCtrlEnum pv_type;
00232 };
00233 
00234 template <>
00235 struct DBRTypeTraits<Epics::dbr_ctrl_char> {
00236   typedef uint8_t value_type;
00237   typedef Epics::EpicsPvCtrlChar pv_type;
00238 };
00239 
00240 template <>
00241 struct DBRTypeTraits<Epics::dbr_ctrl_short> {
00242   typedef int16_t value_type;
00243   typedef Epics::EpicsPvCtrlShort pv_type;
00244 };
00245 
00246 template <>
00247 struct DBRTypeTraits<Epics::dbr_ctrl_long> {
00248   typedef int32_t value_type;
00249   typedef Epics::EpicsPvCtrlLong pv_type;
00250 };
00251 
00252 template <>
00253 struct DBRTypeTraits<Epics::dbr_ctrl_float> {
00254   typedef float value_type;
00255   typedef Epics::EpicsPvCtrlFloat pv_type;
00256 };
00257 
00258 template <>
00259 struct DBRTypeTraits<Epics::dbr_ctrl_double> {
00260   typedef double value_type;
00261   typedef Epics::EpicsPvCtrlDouble pv_type;
00262 };
00263 
00264 
00265 /**
00266  * Type traits for epics PV types. PV can be one of the Epics::EpicsPvXxx types.
00267  */
00268 template <typename PV>
00269 struct PVTypeTraits {  
00270 };
00271 
00272 template <>
00273 struct PVTypeTraits<Epics::EpicsPvTimeString> {
00274   typedef char value_type[Epics::MAX_STRING_SIZE];
00275   typedef Epics::dbr_time_string dbr_type;
00276 };
00277 
00278 template <>
00279 struct PVTypeTraits<Epics::EpicsPvTimeEnum> {
00280   typedef uint16_t value_type;
00281   typedef Epics::dbr_time_enum dbr_type;
00282 };
00283 
00284 template <>
00285 struct PVTypeTraits<Epics::EpicsPvTimeChar> {
00286   typedef uint8_t value_type;
00287   typedef Epics::dbr_time_char dbr_type;
00288 };
00289 
00290 template <>
00291 struct PVTypeTraits<Epics::EpicsPvTimeShort> {
00292   typedef int16_t value_type;
00293   typedef Epics::dbr_time_short dbr_type;
00294 };
00295 
00296 template <>
00297 struct PVTypeTraits<Epics::EpicsPvTimeLong> {
00298   typedef int32_t value_type;
00299   typedef Epics::dbr_time_long dbr_type;
00300 };
00301 
00302 template <>
00303 struct PVTypeTraits<Epics::EpicsPvTimeFloat> {
00304   typedef float value_type;
00305   typedef Epics::dbr_time_float dbr_type;
00306 };
00307 
00308 template <>
00309 struct PVTypeTraits<Epics::EpicsPvTimeDouble> {
00310   typedef double value_type;
00311   typedef Epics::dbr_time_double dbr_type;
00312 };
00313 
00314 template <>
00315 struct PVTypeTraits<Epics::EpicsPvCtrlString> {
00316   typedef char value_type[Epics::MAX_STRING_SIZE];
00317   typedef Epics::dbr_sts_string dbr_type;
00318 };
00319 
00320 template <>
00321 struct PVTypeTraits<Epics::EpicsPvCtrlEnum> {
00322   typedef uint16_t value_type;
00323   typedef Epics::dbr_ctrl_enum dbr_type;
00324 };
00325 
00326 template <>
00327 struct PVTypeTraits<Epics::EpicsPvCtrlChar> {
00328   typedef uint8_t value_type;
00329   typedef Epics::dbr_ctrl_char dbr_type;
00330 };
00331 
00332 template <>
00333 struct PVTypeTraits<Epics::EpicsPvCtrlShort> {
00334   typedef int16_t value_type;
00335   typedef Epics::dbr_ctrl_short dbr_type;
00336 };
00337 
00338 template <>
00339 struct PVTypeTraits<Epics::EpicsPvCtrlLong> {
00340   typedef int32_t value_type;
00341   typedef Epics::dbr_ctrl_long dbr_type;
00342 };
00343 
00344 template <>
00345 struct PVTypeTraits<Epics::EpicsPvCtrlFloat> {
00346   typedef float value_type;
00347   typedef Epics::dbr_ctrl_float dbr_type;
00348 };
00349 
00350 template <>
00351 struct PVTypeTraits<Epics::EpicsPvCtrlDouble> {
00352   typedef double value_type;
00353   typedef Epics::dbr_ctrl_double dbr_type;
00354 };
00355 
00356 
00357 } // namespace EpicsLib
00358 } // namespace Psana
00359 
00360 #endif // PSDDL_PSANA_EPICSLIB_H

Generated on 19 Dec 2016 for PSANAclasses by  doxygen 1.4.7