#ifndef __JTRIGGER__JCHECKSUM__ #define __JTRIGGER__JCHECKSUM__ #include #include #include "km3net-dataformat/online/JDAQ.hh" #include "km3net-dataformat/online/JDAQClock.hh" #include "km3net-dataformat/online/JDAQHit.hh" #include "km3net-dataformat/online/JDAQSuperFrame.hh" #include "JLang/JException.hh" #include "Jeep/JStatus.hh" /** * \author mdejong */ namespace JTRIGGER {} namespace JPP { using namespace JTRIGGER; } namespace JTRIGGER { using KM3NETDAQ::JDAQHit; using KM3NETDAQ::JDAQSuperFrame; using KM3NETDAQ::NUMBER_OF_PMTS; using JLANG::JValueOutOfRange; using JLANG::JIndexOutOfRange; using JEEP::JStatus; /** * Maximal frame size. */ static int MAXIMAL_FRAME_SIZE = std::numeric_limits::max(); /** * Auxiliary class to perform check-sum on raw data. */ struct JChecksum { /** * Error types. */ enum error_types { EPMT_t = 1, //!< PMT number error ETDC_t, //!< TDC value error TIME_t, //!< Time order error EUDP_t, //!< UDP packet error SIZE_t //!< size error }; /** * Error. */ struct error { /** * Default constructor. */ error() : pos (-1), type(-1) {} /** * Constructor. * * \param pos index in frame * \param type error type */ error(const int pos, const int type) : pos (pos), type(type) {} int pos; //!< index in frame int type; //!< error type }; /** * Auxiliary data structure for result of checksum. */ struct result_type : public std::vector { /** * Type conversion operator. * * \return true if okay; else false */ operator bool() const { return this->empty(); } /** * Check for errors with given error mask. * * \param mask error mask * \return true if error present; else false */ bool has(const JStatus& mask) const { for (const_iterator i = this->begin(); i != this->end(); ++i) { if (mask.has(i->type)) { return true; } } return false; } }; typedef result_type::const_iterator const_iterator; typedef result_type::const_reverse_iterator const_reverse_iterator; /** * Default constructor. */ JChecksum() { t0.resize(NUMBER_OF_PMTS, 0); } /** * Check sum. * * The following checks are made: * -# UDP packet assembly is complete; * -# PMT number greater or equals zero and less than NUMBER_OF_PMTS; * -# TDC value less than frame time (with 5% margin); * -# TDC values from same PMT are monotonously increasing; * * \param frame DAQ frame * \return list of errors; empty if all okay */ const result_type& operator()(const JDAQSuperFrame& frame) const { using namespace std; using namespace KM3NETDAQ; const JDAQHit::JTDC_t Tmax = (JDAQHit::JTDC_t) (getTimeSinceRTS(frame.getFrameIndex()) + 1.05 * getFrameTime()); buffer.clear(); for (vector::iterator i = t0.begin(); i != t0.end(); ++i) { *i = 0; } if (frame.size() > MAXIMAL_FRAME_SIZE) { buffer.push_back(error(-1, SIZE_t)); } if (!frame.testDAQStatus()) { buffer.push_back(error(-1, EUDP_t)); } for (JDAQSuperFrame::const_iterator hit = frame.begin(); hit != frame.end(); ++hit) { const JDAQHit::JTDC_t pmt = hit->getPMT(); const JDAQHit::JTDC_t tdc = hit->getT(); if (pmt < NUMBER_OF_PMTS) { if (tdc < t0[pmt]) { buffer.push_back(error(distance(frame.begin(), hit), TIME_t)); } if (tdc > Tmax) { buffer.push_back(error(distance(frame.begin(), hit), ETDC_t)); } t0[pmt] = tdc; } else { buffer.push_back(error(distance(frame.begin(), hit), EPMT_t)); } } return buffer; } private: mutable std::vector t0; mutable result_type buffer; }; /** * Function object to perform check-sum of raw data. */ static const JChecksum checksum; } #endif