#ifndef __JBUILDL2__ #define __JBUILDL2__ #include #include "JTrigger/JSuperFrameClone.hh" #include "JTrigger/JHitToolkit.hh" #include "JTrigger/JHitL1.hh" namespace JTRIGGER { /** * Template L2 builder. * An L2 hit is an L1 hit satisfying additional requirements. */ template class JBuildL2 : public JSuperFrameClone { public: typedef typename JSuperFrameClone::iterator iterator; typedef typename JSuperFrameClone::const_iterator const_iterator; /** * Default constructor. */ JBuildL2() : JSuperFrameClone(), numberOfHits(0), TMaxLocal_ns(0.0), ctMin (0.0) {} /** * Constructor. * * \param super_frame super frame * \param number_of_hits minimal number of hits * \param Tmax_ns maximal time difference between hits [ns] * \param ct minimal cosine between PMT axes */ JBuildL2(const JSuperFrame& super_frame, const int number_of_hits, const double Tmax_ns, const double ct) : JSuperFrameClone(), numberOfHits(number_of_hits), TMaxLocal_ns(Tmax_ns), ctMin (ct) { for (typename JSuperFrame::const_iterator i = super_frame.begin(); i != super_frame.end(); ++i) this->push_back(JFrameClone(*i)); } /** * Copy hits from template L1 input to template L2 output, if requirements are satisfied. * * \param input input data * \param out output data */ template class JInputContainer_t, class JInputAllocator_t, template class JOutputContainer_t, class JOutputAllocator_t> void operator()(const JInputContainer_t& input, std::back_insert_iterator< JOutputContainer_t > out) const { this->rewind(); for (typename JInputContainer_t::const_iterator hit = input.begin(); hit != input.end(); ++hit) { this->fast_forward(getT(*hit)); if (isL2(*hit)) { *out = *hit; ++out; } } } /** * Copy hits from template L1 input to JHitL1 output, if requirements are satisfied. * * \param input input data * \param out output data */ template class JInputContainer_t, class JInputAllocator_t, template class JOutputContainer_t, class JOutputAllocator_t> void operator()(const JInputContainer_t& input, std::back_insert_iterator< JOutputContainer_t > out) const { this->rewind(); for (typename JInputContainer_t::const_iterator hit = input.begin(); hit != input.end(); ++hit) { this->fast_forward(getT(*hit)); if (isL2(*hit)) { JHitL1 hitL1(this->getModuleID()); for (const_iterator i = this->begin(); i != this->end(); ++i) { if (getTimeDifference(*hit,i->getHit()) < TMaxLocal_ns) { hitL1.push_back(JHitL0(i->getPMTIdentifier(), i->getGeometry(), JHit(i->getHit()))); for (const_iterator j = i; ++j != this->end(); ) { if (getTimeDifference(*hit,j->getHit()) < TMaxLocal_ns) { hitL1.push_back(JHitL0(j->getPMTIdentifier(), j->getGeometry(), JHit(j->getHit()))); } } } } *out = hitL1; ++out; } } } /** * Test if requirements for given hit are satisfied. * * \param hit L1 hit * \return true if L2 condition met; else false */ inline bool operator()(const JElement_t& hit) const { this->lower_bound(getT(hit)); return isL2(hit); } int numberOfHits; double TMaxLocal_ns; double ctMin; protected: /** * Test if requirements for given hit are satisfied. * The internal iterators should be set before this test operation. * * \param hit L1 hit * \return true is L2 condition is satisfied; else false */ bool isL2(const JElement_t& hit) const { for (const_iterator i = this->begin(); i != this->end(); ++i) { if (getTimeDifference(hit,i->getHit()) < TMaxLocal_ns) { int n = 1; for (const_iterator j = i; ++j != this->end(); ) { if (getTimeDifference(hit,j->getHit()) < TMaxLocal_ns) { if (dot(i->getDirection(), j->getDirection()) >= ctMin) { if (++n >= numberOfHits) return true; } } } } } return false; } }; } #endif