#ifndef __JTRIGGEREDEVENT__ #define __JTRIGGEREDEVENT__ #include #include #include #include "JDAQ/JDAQEvent.hh" #include "JTrigger/JEvent.hh" #include "JDetector/JModuleRouter.hh" #include "JDetector/JDetectorToolkit.hh" #include "JTrigger/JTimesliceRouter.hh" namespace JTRIGGER { namespace { using KM3NETDAQ::JDAQEvent; using KM3NETDAQ::JDAQTriggeredHit; using KM3NETDAQ::JDAQSnapshotHit; using JSIRENE::JModule; using JSIRENE::JModuleRouter; using JSIRENE::JTimeRange; using JSIRENE::getTimeRange; } /** * Auxiliary class to build JDAQEvent for a triggered event. * * The data structure includes a list of raw data hits that triggered the event and * optionally a list of all raw hits within a preset time window around the event (snapshot). */ class JTriggeredEvent : public JDAQEvent { public: /** * Default constructor. */ JTriggeredEvent() : JDAQEvent() {} /** * Constructor. * * \param event event * \param timesliceRouter timeslice router * \param moduleRouter module router * \param TMaxLocal_ns Maximal time for L1 [ns] * \param snapshot time before first (<= 0) and after last (>= 0) triggered hit [ns]. */ JTriggeredEvent(const JEvent& event, const JTimesliceRouter& timesliceRouter, const JModuleRouter& moduleRouter, const double TMaxLocal_ns, const JTimeRange& snapshot = JTimeRange::JDEFAULT_RANGE) : JDAQEvent() { using namespace std; // Header setDAQChronometer(event.getDAQChronometer()); overlays = event.getOverlays(); trigger_mask = event.getTriggerMask(); // Triggered hits for (JEvent::const_iterator hit = event.begin(); hit != event.end(); ++hit) { const JTimeRange timeRange(hit->getT(), hit->getT() + TMaxLocal_ns); const JModule& module = moduleRouter.getModule(hit->getModuleID()); const JDAQFrameSubset subset = timesliceRouter.getFrameSubset(hit->getModuleIdentifier(), getTimeRange(timeRange, module)); for (JDAQFrameSubset::const_iterator i = subset.begin(); i != subset.end(); ++i) { const JCalibration& calibration = module.getPMT(i->getPMT()).getCalibration(); const double t1 = getTime(*i, calibration); if (timeRange(t1)) triggeredHits.push_back(JDAQTriggeredHit(hit->getModuleIdentifier(), *i, hit->getTriggerMask())); } } if (!triggeredHits.empty()) { // combine trigger masks of identical hits and remove redundant hits sort(triggeredHits.begin(), triggeredHits.end(), JToolkit::compare); vector::iterator out = triggeredHits.begin(); for (vector::const_iterator i = triggeredHits.begin(); ++i != triggeredHits.end(); ) { if (JToolkit::equal(*i,*out)) *(out) |= *i; else *(++out) = *i; } triggeredHits.resize(distance(triggeredHits.begin(), out)); } // Snapshot hits if (snapshot.is_valid()) { const JTimeRange timeRange(event. begin()->getT() + snapshot.getLowerLimit(), event.rbegin()->getT() + snapshot.getUpperLimit()); for (JDAQTimeslice::const_iterator super_frame = timesliceRouter.begin(); super_frame != timesliceRouter.end(); ++super_frame) { if (!super_frame->empty()) { const JModule& module = moduleRouter.getModule(super_frame->getModuleID()); const JDAQFrameSubset& subset = timesliceRouter.getFrameSubset(super_frame->getModuleIdentifier(), getTimeRange(timeRange, module)); for (JDAQFrameSubset::const_iterator i = subset.begin(); i != subset.end(); ++i) { const JCalibration& calibration = module.getPMT(i->getPMT()).getCalibration(); const double t1 = getTime(*i, calibration); if (timeRange(t1)) snapshotHits.push_back(JDAQSnapshotHit(super_frame->getModuleIdentifier(), *i)); } } } } } /** * Toolkit for comparisons of triggered hits. * These comparions are required to combine trigger masks of identical hits and remove redundant hits. */ struct JToolkit { /** * Comparison of triggered hits. * The comparison is applied first to the module identifier, then to the PMT identifier and finally to the time. * * \param first triggered hit * \param second triggered hit * \result true if first hit is less than second hit; else false */ static bool compare(const JDAQTriggeredHit& first, const JDAQTriggeredHit& second) { if (first.getModuleID() == second.getModuleID()) { if (first.getPMT() == second.getPMT()) return first.getT() < second.getT(); else return first.getPMT() < second.getPMT(); } else return first.getModuleID() < second.getModuleID(); } /** * Comparison of triggered hits. * The comparison is applied to the module identifier, to the PMT identifier and to the time. * * \param first triggered hit * \param second triggered hit * \result true if first hit is equal to second hit; else false */ static bool equal(const JDAQTriggeredHit& first, const JDAQTriggeredHit& second) { return (first.getModuleID() == second.getModuleID() && first.getPMT() == second.getPMT() && first.getT() == second.getT()); } }; }; } #endif