00001 #ifndef PSANA_EVENTLOOP_H 00002 #define PSANA_EVENTLOOP_H 00003 00004 //-------------------------------------------------------------------------- 00005 // File and Version Information: 00006 // $Id: EventLoop.h 10732 2015-09-23 22:07:46Z davidsch@SLAC.STANFORD.EDU $ 00007 // 00008 // Description: 00009 // Class EventLoop. 00010 // 00011 //------------------------------------------------------------------------ 00012 00013 //----------------- 00014 // C/C++ Headers -- 00015 //----------------- 00016 #include <boost/shared_ptr.hpp> 00017 #include <boost/utility.hpp> 00018 #include <deque> 00019 #include <vector> 00020 #include <utility> 00021 00022 //---------------------- 00023 // Base Class Headers -- 00024 //---------------------- 00025 00026 //------------------------------- 00027 // Collaborating Class Headers -- 00028 //------------------------------- 00029 #include "psana/Module.h" 00030 #include "psana/Index.h" 00031 #include "psana/InputModule.h" 00032 #include "PSEnv/Env.h" 00033 #include "PSEvt/Event.h" 00034 00035 //------------------------------------ 00036 // Collaborating Class Declarations -- 00037 //------------------------------------ 00038 namespace psana { 00039 class InputIter; 00040 class InputModule; 00041 } 00042 00043 // --------------------- 00044 // -- Class Interface -- 00045 // --------------------- 00046 00047 namespace psana { 00048 00049 /// @addtogroup psana 00050 00051 /** 00052 * @ingroup psana 00053 * 00054 * @brief Implementation of the event loop for psana. 00055 * 00056 * The purpose of this class is to provide iteration over "events" 00057 * in psana framework with well-defined properties. Event in this 00058 * context means not only regular events but also transitions 00059 * like BeginRun, EndRun, etc. Instance of this class acts like 00060 * iterator which returns two items for each iteration - 00061 * event type and event contents (PSEvt::Event object). It guarantees 00062 * correct nesting of transitions and events, so that regular events 00063 * happen only inside BeginCalibCycle/EndCalibCycle, which in turn 00064 * happen only inside BeginRun/EndRun. On every iteration this instance 00065 * calls corresponding method of the user modules before returning 00066 * event to caller so that user modules can add more data to event. 00067 * 00068 * This software was developed for the LCLS project. If you use all or 00069 * part of it, please give an appropriate acknowledgment. 00070 * 00071 * @version $Id: EventLoop.h 10732 2015-09-23 22:07:46Z davidsch@SLAC.STANFORD.EDU $ 00072 * 00073 * @author Andy Salnikov 00074 */ 00075 00076 class EventLoop : boost::noncopyable { 00077 public: 00078 00079 /// Enumeration for the event types returned by iterator 00080 enum EventType { 00081 BeginJob, ///< Returned at the begin of job 00082 BeginRun, ///< Returned at the begin of run 00083 BeginCalibCycle, ///< Returned at the begin of calib cycle 00084 Event, ///< Returned for regular event 00085 EndCalibCycle, ///< Returned at the end of calib cycle 00086 EndRun, ///< Returned at the end of run 00087 EndJob, ///< Returned at the end of job 00088 None, ///< Returned if there are no more events 00089 }; 00090 00091 typedef boost::shared_ptr<PSEvt::Event> EventPtr; 00092 typedef std::pair<EventType, EventPtr> value_type; 00093 00094 /** 00095 * @brief Constructor takes instance of input module, and a list of 00096 * user modules. 00097 */ 00098 EventLoop(const boost::shared_ptr<InputModule>& inputModule, 00099 const std::vector<boost::shared_ptr<Module> >& modules, 00100 const boost::shared_ptr<PSEnv::Env>& env); 00101 00102 // Destructor 00103 ~EventLoop(); 00104 00105 /// Get environment object 00106 PSEnv::Env& env() const; 00107 00108 /** 00109 * Method that runs one iteration and returns event type, 00110 * and event object. 00111 */ 00112 value_type next(); 00113 00114 /** 00115 * @brief "Return" an event back to the input stream. 00116 * 00117 * If you want to look ahead for the next event, to check its type, 00118 * for example, then you can call next() followed by putback(). 00119 */ 00120 void putback(const value_type& value) { m_values.push_front(value); } 00121 00122 00123 /* 00124 * @breif Add a PSANA module to list of modules 00125 * 00126 */ 00127 void addmodule(boost::shared_ptr<Module> module) { m_modules.push_back(module); } 00128 00129 00130 // Returns True if live mode and the available events > numEvents arg 00131 // Used to skip events and catch up with latest for live data. 00132 // Calculation of available events is approximate 00133 bool liveAvail(int numEvents); 00134 00135 Index& index(); 00136 00137 00138 protected: 00139 00140 private: 00141 00142 enum {NumEventTypes = None+1}; 00143 00144 typedef void (Module::*ModuleMethod)(PSEvt::Event& evt, PSEnv::Env& env); 00145 00146 /** 00147 * Calls a method on all modules and returns summary status. 00148 * 00149 * @param[in] modules List of modules 00150 * @param[in] method Pointer to the member function 00151 * @param[in] evt Event object 00152 * @param[in] env Environment object 00153 * @param[in] ignoreSkip Should be set to false for event() method, true for all others 00154 */ 00155 Module::Status callModuleMethod(ModuleMethod method, PSEvt::Event& evt, PSEnv::Env& env, bool ignoreSkip); 00156 00157 00158 boost::shared_ptr<InputIter> m_inputIter; 00159 std::vector<boost::shared_ptr<Module> > m_modules; 00160 ModuleMethod m_eventMethods[NumEventTypes]; 00161 std::deque<value_type> m_values; 00162 00163 // for indexing only 00164 const boost::shared_ptr<InputModule> m_inputModule; 00165 }; 00166 00167 } // namespace psana 00168 00169 #endif // PSANA_EVENTLOOP_H