#ifndef __JCLUSTERBUILDER__ #define __JCLUSTERBUILDER__ #include #include #include #include #include "JTrigger/JBuildL1.hh" #include "JTrigger/JHitL0.hh" #include "JTrigger/JHitL1.hh" #include "JTrigger/JHitToolkit.hh" #include "JTrigger/JSuperFrame2D.hh" #include "JDetector/JModule.hh" #include "km3net-dataformat/online/JDAQSuperFrame.hh" #include "JMonitor/JCluster.hh" /** * \author mjongen */ namespace JMONITOR {} namespace JPP { using namespace JMONITOR; } namespace JMONITOR { using namespace std ; using namespace JTRIGGER ; using JDETECTOR::JModule ; using KM3NETDAQ::JDAQSuperFrame ; /** Local coincidence cluster builder. A coincidence cluster is defined as two or more hits on the same DOM within the defined time window. Given a JDAQSuperframe (for the hits) and the corresponding JModule (for the timing) all the coincidence clusters are extracted and sorted by multiplicity. Internally, the clusters are stored as a vector of JClusters \param frame JDAQSuperframe containing the hits \param module module corresponding to the JDAQSuperframe \param window time window used for clustering **/ class JClusterBuilder : public JBuildL1, public vector, public JModule { public : /// default constructor JClusterBuilder(const double window, const bool combine) : JBuildL1(JBuildL1Parameters(window,combine)), JModule(), max_multiplicity(31), end_iterators(max_multiplicity+2) { // order using std::partition setEndIterators() ; } /// constructor JClusterBuilder( const JDAQSuperFrame& frame, const JModule& module, const double window, const bool combine ) : JBuildL1(JBuildL1Parameters(window,combine)), JModule(module), max_multiplicity(31), end_iterators(max_multiplicity+2) { // use the () operator of JBuildL1 to build L1s (*this)(frame,module,back_inserter( *( (vector*)this) ) ) ; // order using std::partition setEndIterators() ; } /** This is a way to re-use the allocated memory. It behaves like the constructor, but new memory does not have to be allocated for vector all the time. **/ void reset( const JDAQSuperFrame& frame, const JModule& module ) { static_cast(*this) = module ; vector::clear() ; // vector is emptied, but memory stays allocated (*this)(frame,module,back_inserter( *( (vector*)this) ) ) ; setEndIterators() ; } /// returns begin iterator for clusters with exactly the given multiplicity vector::const_iterator begin_m( unsigned int multiplicity ) const { // restrict to allowed range multiplicity = max( (unsigned int)0,multiplicity) ; multiplicity = min(max_multiplicity,multiplicity) ; return end_iterators[multiplicity+1] ; } /// returns end iterator for clusters with exactly the given multiplicity vector::const_iterator end_m( unsigned int multiplicity ) const { // restrict to allowed range multiplicity = max( (unsigned int)0,multiplicity) ; multiplicity = min(max_multiplicity,multiplicity) ; return end_iterators[multiplicity] ; } /// returns begin iterator for clusters with at least the given multiplicity vector::const_iterator begin_inclusive_m( unsigned int multiplicity ) const { return end_iterators[max_multiplicity+1] ; } /// returns end iterator for clusters with at least the given multiplicity vector::const_iterator end_inclusive_m( unsigned int multiplicity ) const { return end_m(multiplicity) ; } /// return the number of clusters with exactly the given multiplicity unsigned int getNclusters( const unsigned int multiplicity ) const { return distance( begin_m(multiplicity), end_m(multiplicity) ) ; } /// return the number of clusters with at least the given multiplicity unsigned int getInclusiveNclusters( const unsigned int multiplicity ) const { return distance( begin_inclusive_m(multiplicity), end_inclusive_m(multiplicity) ) ; } protected : /** Use std::partition to sort the clusters in order of decreasing multiplicity. The end_iterators denote the boundaries. **/ void setEndIterators() { end_iterators[0] = vector::end() ; for( unsigned int m=max_multiplicity; m>0; --m ) { end_iterators[m] = partition( vector::begin(), vector::end(), MinimalMultiplicityFunctor(m) ) ; } end_iterators[max_multiplicity+1] = vector::begin() ; } /** functor that compares the multiplicity of a JCluster to some fixed given multiplicity. **/ class MinimalMultiplicityFunctor { public : MinimalMultiplicityFunctor( const unsigned int _m ) : m(_m) {} bool operator()(const JCluster& cluster) const { return cluster.getMultiplicity() >= m ; } protected : const unsigned int m ; } ; /// the highest allowed value for the multiplicity const unsigned int max_multiplicity ; /** iterators pointing to the first element whose multiplicity is lower than the index **/ vector< vector::iterator > end_iterators ; } ; } #endif