#ifndef __JTRIGGER__JTRIGGER3D__ #define __JTRIGGER__JTRIGGER3D__ #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" /** * \author mdejong */ namespace JTRIGGER {} namespace JPP { using namespace JTRIGGER; } namespace JTRIGGER { /** * General purpose majority trigger. */ class JTrigger3D : public JTriggerInterface { public: /** * Trigger parameters. */ struct JParameters { typedef JLANG::JSharedPointer JMatch_t; /** * Constructor. * * \param option enable/disable trigger * \param number_of_hits minimal number of hits to trigger event * \param number_of_modules minimal number of modules 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 bool option, const int number_of_hits, const int number_of_modules, const double Tmax_ns, const match_type& match3d, const int factory_limit) : enabled (option), numberOfHits (number_of_hits), numberOfModules(number_of_modules), TMaxEvent_ns (Tmax_ns), match3D (match3d.clone()), factoryLimit (factory_limit) {} bool enabled; int numberOfHits; int numberOfModules; double TMaxEvent_ns; JMatch_t match3D; int factoryLimit; }; /** * Constructor. * * \param input trigger parameters */ JTrigger3D(const JParameters& input) : parameters(input) { if (parameters.numberOfHits == 0) { parameters.numberOfHits = 1; } if (parameters.numberOfHits == 1) { parameters.factoryLimit = 1; } buffer.resize(parameters.factoryLimit); } /** * Process trigger. * * \param input input data * \param out output data */ void operator()(const JTriggerInput& input, std::back_insert_iterator out) const { using std::distance; if (parameters.enabled && input.size() >= (size_t) parameters.numberOfHits) { match_type& 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 && getNumberOfModules(p,q) >= parameters.numberOfModules) { if (distance(p,q) < parameters.factoryLimit) { do { if (distance (p,q) >= parameters.numberOfHits && getNumberOfModules(p,q) >= parameters.numberOfModules) { // copy JTriggerInput::iterator root = buffer.begin(); JTriggerInput::iterator __p = buffer.begin(); JTriggerInput::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 && getNumberOfModules(root,__q) >= parameters.numberOfModules) { __q = clusterize(__p, __q, match3D, parameters.numberOfHits - 1); if (distance (root,__q) >= parameters.numberOfHits && getNumberOfModules(root,__q) >= parameters.numberOfModules) { *out = JEvent(input.getDAQChronometer(), root, __q, this->getTriggerBit()); ++out; } } } ++p; } while (q->getT() - p->getT() >= parameters.TMaxEvent_ns); } else { // Anomalous large event JEvent event(input.getDAQChronometer(), p, q, this->getTriggerBit()); event.addTriggerBit(FACTORY_LIMIT); *out = event; ++out; p = q; } } else { for (++p; q->getT() - p->getT() >= parameters.TMaxEvent_ns; ++p) {} } } } } JParameters parameters; private: mutable std::vector buffer; }; } #endif