#ifndef __JTRIGGER__JBUILDL1__ #define __JTRIGGER__JBUILDL1__ #include #include #include "JTrigger/JHitToolkit.hh" #include "JTrigger/JSuperFrame1D.hh" #include "JTrigger/JSuperFrame2D.hh" #include "JTrigger/JSuperFrameClone2D.hh" #include "JTrigger/JHit.hh" #include "JTrigger/JHitL0.hh" #include "JTrigger/JHitL1.hh" #include "JTrigger/JHitR1.hh" #include "JTrigger/JBuildHelper.hh" #include "JTrigger/JBuild.hh" #include "JTrigger/JTriggerParameters.hh" #include "km3net-dataformat/online/JDAQSuperFrame.hh" #include "JDetector/JModule.hh" /** * \author mdejong */ namespace JTRIGGER {} namespace JPP { using namespace JTRIGGER; } namespace JTRIGGER { using KM3NETDAQ::JDAQSuperFrame; using JDETECTOR::JModule; /** * Auxiliary data structure for L1 build parameters. */ struct JBuildL1Parameters { /** * Constructor. * * \param Tmax_ns maximal time difference between consecutive hits [ns] * \param combine combine multiple L1 hits within given time window */ JBuildL1Parameters(const double Tmax_ns, const bool combine) : TMax_ns(Tmax_ns), combine(combine) {} /** * Constructor. * * \param parameters trigger parameters */ JBuildL1Parameters(const JTriggerParameters& parameters) : TMax_ns(parameters.TMaxLocal_ns), combine(parameters.combineL1) {} /** * Constructor. * * \param parameters L2 parameters */ JBuildL1Parameters(const JL2Parameters& parameters) : TMax_ns(parameters.TMaxLocal_ns), combine(true) {} double TMax_ns; bool combine; }; /** * Template L1 hit builder. * * An L1 hit is a local coincidence between two hits within the same optical module. */ template class JBuildL1 : public JBuildL1Parameters, public JBuildHelper< JBuildL1 >, public JBuild, public JHitToolkit { public: using JBuildHelper< JBuildL1 >::operator(); typedef JHit_t value_type; /** * Constructor. * * \param parameters build L1 parameters */ JBuildL1(const JBuildL1Parameters& parameters) : JBuildL1Parameters(parameters) {} /** * Build hits from calibrated data. * * The output data are time sorted. * * \param input input L0 data * \param out output L1 data */ template void operator()(const JSuperFrame2D& input, JOutput_t out) const { (*this)(input.begin(), input.end(), out); } /** * Build hits from set of frames with calibrated data. * * The output data are time sorted. * * \param __begin begin of input L0 data * \param __end end of input L0 data * \param out output L1 data */ template void operator()(typename JSuperFrame2D::const_iterator __begin, typename JSuperFrame2D::const_iterator __end, JOutput_t out) const { (*this)(JSuperFrame1D::multiplex(__begin, __end), out); } /** * Build hits from calibrated data. * * The output data are time sorted. * * \param input input L0 data * \param out output L1 data */ template void operator()(const JSuperFrame1D& input, JOutput_t out) const { int n = input.size(); for (typename JSuperFrame1D::const_iterator q = input.begin(), p = q++; n != 0; ++q, --n) { if (this->getTimeDifference(*p,*q) <= TMax_ns) { *out = *p; ++out; if (combine) { for (++q, --n; this->getTimeDifference(*p,*q) <= TMax_ns; ++q, --n) {} } } p = q; } } /** * Build hits from DAQ data. * * The time calibration is applied. * The output data are time sorted. * * \param input DAQ super frame * \param module module * \param out output L1 data */ template void operator()(const JDAQSuperFrame& input, const JModule& module, JOutput_t out) const { if (!input.empty()) { (*this)(this->demultiplex(input, module), out); } } }; /** * Template specialisation of L1 builder for JHitL1 data type. */ template<> class JBuildL1 : public JBuildL1, public JBuildHelper< JBuildL1 > { public: using JBuildHelper< JBuildL1 >::operator(); typedef JHitL1 value_type; /** * Constructor. * * \param parameters build L1 parameters */ JBuildL1(const JBuildL1Parameters& parameters) : JBuildL1(parameters) {} /** * Build hits from calibrated data. * * The output data are time sorted. * * \param input input L0 data * \param out output L1 data */ template void operator()(const JSuperFrame2D& input, JOutput_t out) const { const JSuperFrameClone2D clone(input); buffer.clear(); static_cast&>(*this)(input, std::back_inserter(buffer)); for (typename std::vector::const_iterator p = buffer.begin(); p != buffer.end(); ++p) { JHitL1 hit(input.getModuleID()); for (typename JSuperFrameClone2D::const_iterator i = clone.begin(); i != clone.end(); ++i) { for (typename JSuperFrameClone2D::value_type::const_iterator q = i->fast_forward(*p); this->getTimeDifference(*p,*q) <= TMax_ns; ++q) { hit.push_back(JHitL0(i->getPMTIdentifier(), i->getAxis(), *q)); } } *out = hit.sort(); ++out; } } /** * Build hits from uncalibrated DAQ data. * * The time calibration is applied. * The output data are time sorted. * * \param input DAQ super frame * \param module module * \param out output L1 data */ template void operator()(const JDAQSuperFrame& input, const JModule& module, JOutput_t out) const { if (!input.empty()) { (*this)(this->demultiplex(input, module), out); } } private: mutable std::vector buffer; }; /** * Template specialisation of L1 builder for JHitR1 data type. */ template<> class JBuildL1 : public JBuildL1, public JBuildHelper< JBuildL1 > { public: using JBuildHelper< JBuildL1 >::operator(); typedef JHitR1 value_type; /** * Constructor. * * \param parameters build L1 parameters */ JBuildL1(const JBuildL1Parameters& parameters) : JBuildL1(parameters) {} /** * Build hits from calibrated data. * * The output data are time sorted. * * \param input input L0 data * \param out output L1 data */ template void operator()(const JSuperFrame2D& input, JOutput_t out) const { const JSuperFrameClone2D clone(input); buffer.clear(); static_cast&>(*this)(input, std::back_inserter(buffer)); for (typename std::vector::const_iterator p = buffer.begin(); p != buffer.end(); ++p) { JHitR1 hit(input.getModuleID(), input.getPosition()); clone.fast_forward(*p); for (typename JSuperFrameClone2D::const_iterator i = clone.begin(); i != clone.end(); ++i) { if (i->getTimeDifference(*p) <= TMax_ns) { if (hit.getN() == 0) hit.set(i->getJHit()); else hit.add(i->getJHit()); } if (i->getT() < hit.getT()) { hit.setPosition(i->getPosition()); } } *out = hit; ++out; } } /** * Build hits from uncalibrated DAQ data. * * The time calibration is applied. * The output data are time sorted. * * \param input DAQ super frame * \param module module * \param out output L1 data */ template void operator()(const JDAQSuperFrame& input, const JModule& module, JOutput_t out) const { if (!input.empty()) { (*this)(this->demultiplex(input, module), out); } } private: mutable std::vector buffer; }; } #endif