#ifndef __JTRIGGER__JTRIGGER3N__ #define __JTRIGGER__JTRIGGER3N__ #include #include #include "JGeometry3D/JOmega3D.hh" #include "JGeometry3D/JRotator3D.hh" #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 { using JGEOMETRY3D::JOmega3D; using JGEOMETRY3D::JRotator3D; /** * General purpose muon trigger. * * The 3D match criterion is used followed by a scan of directions. * For each direction, the 1D match criterion is applied. * A trigger is fired when the specified minimum number of hits is * detected for any of the directions. */ class JTrigger3N : public JTriggerInterface { public: typedef JLANG::JSharedPointer JMatch_t; /** * Trigger parameters. */ struct JParameters { /** * 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 omega set of directions * \param match3d 3D match operator * \param match1d 1D 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 JOmega3D& omega, const match_type& match3d, const match_type& match1d, const int factory_limit) : enabled (option), numberOfHits (number_of_hits), numberOfModules(number_of_modules), TMaxEvent_ns (Tmax_ns), rotator (omega), match3D (match3d.clone()), match1D (match1d.clone()), factoryLimit (factory_limit) {} bool enabled; int numberOfHits; int numberOfModules; double TMaxEvent_ns; JRotator3D rotator; JMatch_t match3D; JMatch_t match1D; int factoryLimit; }; /** * Constructor. * * \param input trigger parameters */ JTrigger3N(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) { const match_type& match3D = *parameters.match3D; const match_type& match1D = *parameters.match1D; 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) { for (JGEOMETRY3D::JRotator3D_t::const_iterator R = parameters.rotator.begin(); R != parameters.rotator.end(); ++R) { for (JTriggerInput::iterator i = root; i != __q; ++i) { i->JPosition3D::rotate(*R); } JTriggerInput::iterator __z = partition(__p, __q, JBind2nd(match1D,*root)); if (distance (root,__z) >= parameters.numberOfHits && getNumberOfModules(root,__z) >= parameters.numberOfModules) { __z = clusterize(__p, __z, match1D, parameters.numberOfHits - 1); if (distance (root,__z) >= parameters.numberOfHits && getNumberOfModules(root,__z) >= parameters.numberOfModules) { *out = JEvent(input.getDAQChronometer(), root, __q, this->getTriggerBit()); ++out; break; } } } } } } ++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