00001 #ifndef PSANA_INPUTMODULE_H 00002 #define PSANA_INPUTMODULE_H 00003 00004 //-------------------------------------------------------------------------- 00005 // File and Version Information: 00006 // $Id: InputModule.h 10732 2015-09-23 22:07:46Z davidsch@SLAC.STANFORD.EDU $ 00007 // 00008 // Description: 00009 // Class InputModule. 00010 // 00011 //------------------------------------------------------------------------ 00012 00013 //----------------- 00014 // C/C++ Headers -- 00015 //----------------- 00016 #include <string> 00017 #include <iosfwd> 00018 #include <boost/utility.hpp> 00019 00020 //---------------------- 00021 // Base Class Headers -- 00022 //---------------------- 00023 #include "psana/Configurable.h" 00024 00025 //------------------------------- 00026 // Collaborating Class Headers -- 00027 //------------------------------- 00028 #include "psana/Index.h" 00029 #include "PSEnv/Env.h" 00030 #include "PSEvt/Event.h" 00031 00032 //------------------------------------ 00033 // Collaborating Class Declarations -- 00034 //------------------------------------ 00035 00036 // this is not nice thing to do but we want to simplify user's life 00037 // and provide bunch of simple interfaces to our system 00038 00039 namespace psana {} 00040 using namespace psana; 00041 using namespace PSEnv; 00042 using namespace PSEvt; 00043 00044 // define macro for definition of the factory function 00045 #if defined(PSANACAT2_) 00046 #undef PSANACAT2_ 00047 #endif 00048 #define PSANACAT2_(a,b) a ## b 00049 #define PSANA_INPUT_MODULE_FACTORY(UserModule) \ 00050 extern "C" \ 00051 psana::InputModule* \ 00052 PSANACAT2_(_psana_input_module_,UserModule)(const std::string& name) {\ 00053 return new UserModule(name);\ 00054 } 00055 00056 // --------------------- 00057 // -- Class Interface -- 00058 // --------------------- 00059 00060 namespace psana { 00061 00062 /** 00063 * @ingroup psana 00064 * 00065 * @brief Base class for psana input modules. 00066 * 00067 * Psana input module is responsible for reading input files or other event 00068 * sources and decide what framework should do with the next read event. 00069 * In a sense input module drives the framework event loop based on the input 00070 * event data. 00071 * 00072 * This software was developed for the LCLS project. If you use all or 00073 * part of it, please give an appropriate acknowledgment. 00074 * 00075 * @see Module 00076 * 00077 * @version \$Id: InputModule.h 10732 2015-09-23 22:07:46Z davidsch@SLAC.STANFORD.EDU $ 00078 * 00079 * @author Andrei Salnikov 00080 */ 00081 00082 class InputModule : boost::noncopyable, protected Configurable { 00083 public: 00084 00085 /** 00086 * @brief Event processing status. 00087 * 00088 * The value returned from event() signals to framework what it should do next. 00089 */ 00090 enum Status { 00091 BeginRun, ///< beginRun() should be called for all modules 00092 BeginCalibCycle, ///< beginCalibCycle() should be called for all modules 00093 DoEvent, ///< event() should be called for all modules 00094 EndCalibCycle, ///< endCalibCycle() should be called for all modules 00095 EndRun, ///< endRun() should be called for all modules 00096 Skip, ///< skip all remaining modules for this event 00097 Stop, ///< gracefully finish with the event loop 00098 Abort ///< abort immediately, no finalization 00099 }; 00100 00101 // Destructor 00102 virtual ~InputModule () ; 00103 00104 // Returns the name of the module 00105 using Configurable::name; 00106 00107 // Returns the class name of the module 00108 using Configurable::className; 00109 00110 /** 00111 * @brief Method which is called once at the beginning of the job. 00112 * 00113 * Input module is supposed to populate environment with the configuration 00114 * objects and EPICS data from Configure transition. 00115 * 00116 * @param[out] evt Event object 00117 * @param[out] env Environment object 00118 */ 00119 virtual void beginJob(Event& evt, Env& env) = 0; 00120 00121 /** 00122 * @brief Method which is called for the next event in the event loop. 00123 * 00124 * Input module should try to read next event from input source and fill 00125 * event object and environment object if possible. Depending on what has 00126 * been read it also signals framework what to do next by returning one of 00127 * the Status enum values. 00128 * 00129 * @param[out] evt Event object 00130 * @param[out] env Environment object 00131 */ 00132 virtual Status event(Event& evt, Env& env) = 0; 00133 00134 virtual Index& index(); 00135 /** 00136 * @brief Method which is called once at the end of the job 00137 * 00138 * Input module can stop reading data and close/reset its sources. It does 00139 * not need to update environment but can use some data from it. 00140 * 00141 * @param[out] evt Event object 00142 * @param[out] env Environment object 00143 */ 00144 virtual void endJob(Event& evt, Env& env) = 0; 00145 00146 virtual bool liveAvail(int numEvents) { 00147 return false; 00148 } 00149 00150 protected: 00151 00152 /// Constructor may be called from subclass only. 00153 InputModule (const std::string& name) ; 00154 00155 private: 00156 00157 }; 00158 00159 /// formatting for InputModule::Status enum 00160 std::ostream& 00161 operator<<(std::ostream& out, InputModule::Status stat); 00162 00163 } // namespace psana 00164 00165 #endif // PSANA_INPUTMODULE_H