psana_examples/src/DumpEpics.cpp

Go to the documentation of this file.
00001 //--------------------------------------------------------------------------
00002 // File and Version Information:
00003 //      $Id: DumpEpics.cpp 10250 2015-06-09 21:29:07Z davidsch@SLAC.STANFORD.EDU $
00004 //
00005 // Description:
00006 //      Class DumpEpics...
00007 //
00008 // Author List:
00009 //      Andrei Salnikov
00010 //
00011 //------------------------------------------------------------------------
00012 
00013 //-----------------------
00014 // This Class's Header --
00015 //-----------------------
00016 #include "psana_examples/DumpEpics.h"
00017 
00018 //-----------------
00019 // C/C++ Headers --
00020 //-----------------
00021 #include <vector>
00022 #include <algorithm>
00023 #include <sstream>
00024 
00025 //-------------------------------
00026 // Collaborating Class Headers --
00027 //-------------------------------
00028 #include "MsgLogger/MsgLogger.h"
00029 
00030 //-----------------------------------------------------------------------
00031 // Local Macros, Typedefs, Structures, Unions and Forward Declarations --
00032 //-----------------------------------------------------------------------
00033 
00034 using namespace psana_examples;
00035 PSANA_MODULE_FACTORY(DumpEpics)
00036 
00037 //              ----------------------------------------
00038 //              -- Public Function Member Definitions --
00039 //              ----------------------------------------
00040 
00041 namespace psana_examples {
00042 
00043 //----------------
00044 // Constructors --
00045 //----------------
00046 DumpEpics::DumpEpics (const std::string& name)
00047   : Module(name)
00048 {
00049 }
00050 
00051 //--------------
00052 // Destructor --
00053 //--------------
00054 DumpEpics::~DumpEpics ()
00055 {
00056 }
00057 
00058 /// Method which is called at the beginning of the calibration cycle
00059 void
00060 DumpEpics::beginCalibCycle(Event& evt, Env& env)
00061 {
00062   const EpicsStore& estore = env.epicsStore();
00063 
00064   // Print the list of aliases
00065   const std::vector<std::string>& aliases = estore.aliases();
00066   WithMsgLog(name(), info, str) {
00067     str << "Total number of EPICS Aliases: " << aliases.size();
00068     for (std::vector<std::string>::const_iterator it = aliases.begin(); it != aliases.end(); ++ it) {
00069       str << "\n  '" << *it << "' -> '" << estore.pvName(*it) << "'";
00070     }
00071   }
00072 
00073   // and dump all values as well
00074   event(evt, env);
00075 }
00076 
00077 // Method which is called with event data
00078 void 
00079 DumpEpics::event(Event& evt, Env& env)
00080 {
00081   // access EPICS store
00082   const EpicsStore& estore = env.epicsStore();
00083   
00084   // get the names of EPICS PVs
00085   std::vector<std::string> pvNames = estore.pvNames();
00086   std::sort(pvNames.begin(), pvNames.end());
00087   size_t size = pvNames.size();
00088   
00089   std::stringstream str;
00090 
00091   str << "Total number of EPICS PVs: " << pvNames.size() << '\n';
00092 
00093   for (size_t i = 0; i < size; ++ i) {
00094       
00095    // get generic PV object, only useful if you want to access
00096     // its type, and array size
00097     shared_ptr<Psana::Epics::EpicsPvHeader> pv = estore.getPV(pvNames[i]);
00098     
00099     // print generic info
00100     str << "  " << pvNames[i] << " id=" << pv->pvId()
00101         << " type=" << pv->dbrType()  
00102         << " isCtrl=" << int(pv->isCtrl())
00103         << " isTime=" << int(pv->isTime())
00104         << " size=" << pv->numElements() << '\n';
00105       
00106     // print status info
00107     int status, severity;
00108     PSTime::Time time;
00109     estore.status(pvNames[i], status, severity, time);
00110     str << "    status=" << status << ", severity=" << severity 
00111         << " time=" << time << '\n';
00112     
00113     // print all values. Either use simpler interface of the 
00114     // epicsStore value function, or for demonstration purposes, get a 
00115     // pointer to the actual epics type. Using the value function is
00116     // generally simplest, but when working with epics pv's that are 
00117     // waveforms, getting the actual type may be simpler.
00118     
00119     str << "    values: ";
00120     
00121     std::string dataArrayStr;
00122     if (pv->numElements() > 1) {
00123       dataArrayStr = dumpPvDataArray(estore, pvNames[i]);
00124     }
00125 
00126     if (dataArrayStr.size()>0) {
00127       str << dataArrayStr;
00128     } else {
00129       // demo simpler way to get values, through estore.value with pvName lookup:
00130       for (int e = 0; e < pv->numElements(); ++ e) {
00131         // get value and convert to string 
00132         // if value is numeric, could also assign it to appropriate
00133         // numberic types, int, double, float, etc)
00134         const std::string& value = estore.value(pvNames[i], e);
00135         str << ' ' << value;
00136       }
00137     }
00138     str << std::endl;
00139   }
00140   MsgLog(name(), info, str.str());
00141 }
00142 
00143 //              ----------------------------------------
00144 //              -- Protected Function Member Definitions --
00145 //              ----------------------------------------
00146 
00147 std::string  DumpEpics::dumpPvDataArray(const PSEnv::EpicsStore &estore, const std::string &pvName) {
00148   // Since we don't know the type of data, we'll try a few (see psddl_psana/include/epics.ddl.h for all types)
00149   // An alternative, below, is to switch on the dbrType
00150   std::stringstream str;
00151   boost::shared_ptr<Psana::Epics::EpicsPvTimeShort> pvTimeShort = estore.getPV(pvName);
00152   if (pvTimeShort) {
00153     ndarray<const int16_t, 1> data = pvTimeShort->data();
00154     str << data;
00155   } else {
00156     boost::shared_ptr<Psana::Epics::EpicsPvTimeFloat> pvTimeFloat = estore.getPV(pvName);
00157     if (pvTimeFloat) {
00158       ndarray<const float, 1> data = pvTimeFloat->data();
00159       str << data;
00160     } else {
00161       boost::shared_ptr<Psana::Epics::EpicsPvCtrlShort> pvCtrlShort = estore.getPV(pvName);
00162       if (pvCtrlShort) {
00163         ndarray<const int16_t, 1> data = pvCtrlShort->data();
00164         str << data;
00165       } else {
00166         boost::shared_ptr<Psana::Epics::EpicsPvCtrlFloat> pvCtrlFloat = estore.getPV(pvName);
00167         if (pvCtrlFloat) {
00168           ndarray<const float, 1> data = pvCtrlFloat->data();
00169           str << data;
00170         }
00171       }
00172     }
00173   }
00174 
00175   // demo switching on the dbr type. see psddl_psana/include/epics.ddl.h for all DBR types
00176   if (str.str().size() == 0) {
00177     shared_ptr<Psana::Epics::EpicsPvHeader> pv = estore.getPV(pvName);
00178     if (pv) {
00179       switch (pv->dbrType()) {
00180       case Psana::Epics::DBR_TIME_DOUBLE:
00181         {
00182           boost::shared_ptr<Psana::Epics::EpicsPvTimeDouble> pvTimeDouble = estore.getPV(pvName);
00183           if (not pvTimeDouble) {
00184             MsgLog(name(), error, "unexpected: dbrType/psana type mismatch");
00185             break;
00186           }
00187           ndarray<const double, 1> data = pvTimeDouble->data();
00188           str << data;
00189         }
00190         break;
00191 
00192       case Psana::Epics::DBR_CTRL_DOUBLE:
00193         {
00194           boost::shared_ptr<Psana::Epics::EpicsPvCtrlDouble> pvCtrlDouble = estore.getPV(pvName);
00195           if (not pvCtrlDouble) {
00196             MsgLog(name(), error, "unexpected: dbrType/psana type mismatch");
00197             break;
00198           }
00199           ndarray<const double, 1> data = pvCtrlDouble->data();
00200           str << data;
00201         }
00202         break;
00203       }
00204     }
00205   }
00206   
00207   return str.str();
00208 }
00209 
00210 
00211   
00212 } // namespace psana_examples

Generated on 19 Dec 2016 for PSANAmodules by  doxygen 1.4.7