#ifndef __JTRIGGER3D__ #define __JTRIGGER3D__ #include #include #include #include #include "JLang/JSharedPointer.hh" #include "JTrigger/JEvent.hh" #include "JTrigger/JMatch.hh" #include "JTrigger/JBind2nd.hh" #include "JTrigger/JAlgorithm.hh" #include "JTrigger/JTriggerInterface.hh" #include "JTrigger/JTriggerInput.hh" #include "JTrigger/JTriggerOutput.hh" namespace JTRIGGER { namespace { using std::distance; using JLANG::JSharedPointer; } /** * General purpose majority trigger. */ class JTrigger3D : public JTriggerInterface { typedef std::vector::const_iterator const_iterator; typedef std::vector::iterator iterator; public: typedef JMatch JMatch_t; /** * Trigger parameters. */ class JParameters { public: /** * Constructor. * * \param number_of_hits minimal number of hits to trigger event * \param Tmax_ns maximal time between first and last hit [ns] * \param match3d 3D match operator * \param factory_limit maximal number of hits to apply trigger logic (above this limit, always trigger) */ JParameters(const int number_of_hits, const double Tmax_ns, const JMatch_t& match3d, const int factory_limit = FACTORY_LIMIT) : numberOfHits(number_of_hits), TMaxEvent_ns(Tmax_ns), match3D (match3d.clone()), factoryLimit(factory_limit) { if (factoryLimit > FACTORY_LIMIT) factoryLimit = FACTORY_LIMIT; } int numberOfHits; double TMaxEvent_ns; JSharedPointer match3D; int factoryLimit; }; /** * Constructor. * * \param input trigger parameters */ JTrigger3D(const JParameters& input) : parameters(input) { if (parameters.factoryLimit != FACTORY_LIMIT) buffer.resize(parameters.factoryLimit); if (parameters.numberOfHits == 0) parameters.numberOfHits = 1; if (parameters.numberOfHits == 1) parameters.factoryLimit = 1; } /** * Process trigger. * * \param input input data * \param out output data */ void operator()(const JTriggerInput& input, std::back_insert_iterator out) const { if (input.size() >= parameters.numberOfHits) { const JMatch& match3D = *parameters.match3D; for (JTriggerInput::const_iterator p = input.begin(), q = p; p != input.end(); ) { for (++q; q->getT() - p->getT() < parameters.TMaxEvent_ns; ++q) {} if (distance(p,q) >= parameters.numberOfHits) { if (distance(p,q) < parameters.factoryLimit) { do { if (distance(p,q) >= parameters.numberOfHits) { // copy iterator root = buffer.begin(); iterator __p = buffer.begin(); iterator __q = buffer.begin(); *root = *p; ++__p; ++__q; for (JTriggerInput::const_iterator i = p; ++i != q; ) { if (match3D(*p,*i)) { *__q = *i; ++__q; } } if (distance(root,__q) >= parameters.numberOfHits) { __q = clusterize(__p, __q, match3D, parameters.numberOfHits - 1); if (distance(root,__q) >= parameters.numberOfHits) { *out = JEvent(input.getDAQChronometer(), root, __q, this->getTriggerBit()); ++out; } } } ++p; } while (q->getT() - p->getT() >= parameters.TMaxEvent_ns); } else { // Anomalous large event *out = JEvent(input.getDAQChronometer(), p, q, this->getTriggerBit()); ++out; p = q; } } else for (++p; q->getT() - p->getT() >= parameters.TMaxEvent_ns; ++p) {} } } } protected: JParameters parameters; private: mutable vector buffer; }; } #endif