00001 #ifndef PSXTCINPUT_DGRAMSOURCEFILE_H 00002 #define PSXTCINPUT_DGRAMSOURCEFILE_H 00003 00004 //-------------------------------------------------------------------------- 00005 // File and Version Information: 00006 // $Id: DgramSourceFile.h 12582 2016-09-08 17:45:48Z dubrovin@SLAC.STANFORD.EDU $ 00007 // 00008 // Description: 00009 // Class DgramSourceFile. 00010 // 00011 //------------------------------------------------------------------------ 00012 00013 //----------------- 00014 // C/C++ Headers -- 00015 //----------------- 00016 #include <string> 00017 #include <vector> 00018 #include <boost/thread/thread.hpp> 00019 #include <boost/scoped_ptr.hpp> 00020 00021 //---------------------- 00022 // Base Class Headers -- 00023 //---------------------- 00024 #include "PSXtcInput/IDatagramSource.h" 00025 #include "psana/Configurable.h" 00026 00027 //------------------------------- 00028 // Collaborating Class Headers -- 00029 //------------------------------- 00030 #include "XtcInput/LiveAvail.h" 00031 00032 //------------------------------------ 00033 // Collaborating Class Declarations -- 00034 //------------------------------------ 00035 namespace XtcInput { 00036 class DgramQueue; 00037 } 00038 00039 // --------------------- 00040 // -- Class Interface -- 00041 // --------------------- 00042 00043 namespace PSXtcInput { 00044 00045 /// @addtogroup PSXtcInput 00046 00047 /** 00048 * @ingroup PSXtcInput 00049 * 00050 * @brief Implementation of IDatagramSource interface which reads data from input files. 00051 * 00052 * @note This software was developed for the LCLS project. If you use all or 00053 * part of it, please give an appropriate acknowledgment. 00054 * 00055 * @version $Id: DgramSourceFile.h 12582 2016-09-08 17:45:48Z dubrovin@SLAC.STANFORD.EDU $ 00056 * 00057 * @author Andy Salnikov 00058 */ 00059 00060 class DgramSourceFile : public IDatagramSource, public psana::Configurable { 00061 public: 00062 00063 // Constructor takes the name of the input module, used for accessing module 00064 // configuration parameters. 00065 DgramSourceFile(const std::string& name); 00066 00067 // Destructor 00068 virtual ~DgramSourceFile(); 00069 00070 /** 00071 * Initialization method for datagram source, this is typically called 00072 * in beginJob() method and it may contain initialization code which 00073 * cannot be executed during construction of an instance. 00074 */ 00075 virtual void init(); 00076 00077 /** 00078 * @brief Return next datagram(s) from the source. 00079 * 00080 * This method returns two sets of datagrams - eventDg is the set of histograms 00081 * belonging to the next event, nonEventDg is the set of datagrams which has some 00082 * other data (like EPICS) which is needed for correct interpretation of current 00083 * event. Currently eventDg should contain one datagram but potentially in the 00084 * future we may start event building in offline and that list can grow longer. 00085 * It nonEventDg is non-empty then it has to be processed first as those datagram 00086 * should come from earlier time than eventDg and eventDg may contain data that 00087 * overrides data in nonEventDg (e.g. some EPICS PV data may be contained in both 00088 * nonEventDg and eventDg). 00089 * 00090 * This method will called repeatedly until it returns false. 00091 * 00092 * @param[out] eventDg returned set of datagrams for current event 00093 * @param[out] nonEventDg returned set of datagrams containing other information. 00094 * @return false if there are no more events, both eventDg and nonEventDg will be empty in this case. 00095 */ 00096 virtual bool next(std::vector<XtcInput::Dgram>& eventDg, std::vector<XtcInput::Dgram>& nonEventDg); 00097 00098 00099 00100 /** 00101 * "Returns true if in live mode and the available events on disk is >= the argument numEvents 00102 */ 00103 virtual bool liveAvail(int numEvents); 00104 00105 protected: 00106 00107 /** 00108 * @brief returns true if two datagrams are part of the same event. 00109 * 00110 * For regular data (L1Accept transitions) will only return true if at least one 00111 * is a ControlStream and there is a sec/fid match. Two non-L1's match if the 00112 * clocks are the same. 00113 * 00114 * @param eventDg first datagram 00115 * @param otherDg second datagram 00116 * @return false if not part of the same event, true if they are 00117 */ 00118 bool sameEvent(const XtcInput::Dgram &eventDg, const XtcInput::Dgram &otherDg) const; 00119 00120 /** 00121 * @brief returns true if two datagrams fiducials match, and their seconds are close 00122 * 00123 * max difference in seconds for clocks can be changed with psana option 00124 * max_stream_clock_diff, however this should not be neccessary. 00125 * 00126 * @param dgA first datagram 00127 * @param dgB second datagram 00128 * @return true if they match, false otherwise 00129 */ 00130 bool fiducialSecondsMatch(const XtcInput::Dgram &dgA, const XtcInput::Dgram &dgB) const; 00131 00132 private: 00133 00134 boost::scoped_ptr<XtcInput::DgramQueue> m_dgQueue; ///< Input datagram queue 00135 boost::shared_ptr<XtcInput::LiveAvail> m_liveAvail; /// 00136 boost::scoped_ptr<boost::thread> m_readerThread; ///< Thread which does datagram reading 00137 std::vector<std::string> m_fileNames; ///< List of file names/datasets to read data from 00138 int m_firstControlStream; ///< Starting index of control streams 00139 unsigned m_maxStreamClockDiffSec; ///< Maximum clock difference between streams (in seconds) 00140 }; 00141 00142 } // namespace PSXtcInput 00143 00144 #endif // PSXTCINPUT_DGRAMSOURCEFILE_H