#ifndef __JDETECTOR__JMODULEMAPPER__ #define __JDETECTOR__JMODULEMAPPER__ #include #include #include "JLang/JNullType.hh" #include "JMath/JMathToolkit.hh" #include "JDetector/JModuleRouter.hh" #include "JDetector/JModuleAddress.hh" #include "JDetector/JDetector.hh" /** * \file * Map of associated modules in detector. * \author mdejong */ namespace JDETECTOR {} namespace JPP { using namespace JDETECTOR; } namespace JDETECTOR { using JLANG::JNullType; /** * Template method to set module attributes. * This method should be overloaded for each type of module attributes. * * \param first first module * \param second second module * \param attributes module attributes */ template void setAttributes(const JModule& first, const JModule& second, JAttributes_t& attributes); /** * Template specialisation to set no attributes for the default empty object. * * \param first first module * \param second second module * \param attributes module attributes */ template<> void setAttributes(const JModule& first, const JModule& second, JNullType& attributes) {} /** * Data structure for module address and module attributes. * * The template argument refers to the module attributes * for which the following method should be overloaded: *
   *     void setAttributes(const JModule& first,
   *                        const JModule& second,
   *                        JAttributes_t& attributes);
   * 
*/ template struct JModuleAttributes : public JModuleAddress, public JAttributes_t { /** * Get module attributes. * * \param first first module * \param second second module * \return module attributes */ static const JAttributes_t& getAttributes(const JModule& first, const JModule& second) { static JAttributes_t attributes; setAttributes(first, second, attributes); return attributes; } /** * Default constructor. */ JModuleAttributes() : JModuleAddress(), JAttributes_t() {} /** * Constructor. * * \param index index of module in detector data structure * \param first first module * \param second second module */ JModuleAttributes(const int index, const JModule& first, const JModule& second) : JModuleAddress(index), JAttributes_t(getAttributes(first, second)) {} }; /** * Auxiliary class to match modules according maximal distance. */ struct JMaximalDistance { /** * Constructor. * * \param Dmax_m maximal distance [m] */ JMaximalDistance(const double Dmax_m) : dmax(Dmax_m) {} /** * Get maximal distance. * * \return maximal distance [m] */ double getDmax() const { return dmax; } /** * Test whether two module match. * * \param first first module * \param second second module * \return true if distance between modules less than limit; else false */ bool operator()(const JModule& first, const JModule& second) const { return getDistance(first.getPosition(), second.getPosition()) <= dmax; } protected: double dmax; }; /** * Mapper for directly addressing of associated modules in the detector data structure. * The template argument refers to the module attributes. * Note that, by construction, a module will not be assiciated to itself. */ template class JModuleMapper : public JModuleRouter { public: /** * Type definition of module data. */ typedef JModuleAttributes moduleattributes_type; /** * Type definition of a list with module data. */ typedef std::vector container_type; /** * Constructor. * * \param detector detector */ JModuleMapper(const JDetector& detector) : JModuleRouter(detector) { configure(JMaximalDistance(std::numeric_limits::max())); } /** * Constructor. * * \param router module router */ JModuleMapper(const JModuleRouter& router) : JModuleRouter(router) { configure(JMaximalDistance(std::numeric_limits::max())); } /** * Constructor. * * The argument matchrefers to a template which should implement the following operator: *
     *       bool operator()(const JModule& first, const JModule& second);
     * 
* * \param detector detector * \param match module matcher */ template JModuleMapper(const JDetector& detector, JMatch_t match) : JModuleRouter(detector) { configure(match); } /** * Constructor. * * The argument matchrefers to a template which should implement the following operator: *
     *       bool operator()(const JModule& first, const JModule& second);
     * 
* * \param router module router * \param match module matcher */ template JModuleMapper(const JModuleRouter& router, JMatch_t match) : JModuleRouter(router) { configure(match); } /** * Get list with module data matching given module. * * \param id module identifier * \return module data */ const container_type& getList(const JObjectID& id) const { return zmap[this->getAddress(id).first]; } /** * Configure this module mapper. * * The argument matchrefers to a template which should implement the following operator: *
     *       bool operator()(const JModule& first, const JModule& second);
     * 
* * \param match module matcher */ template void configure(JMatch_t match) { const JDetector& detector = this->getReference(); zmap.resize(detector.size()); for (typename std::vector::iterator i = zmap.begin(); i != zmap.end(); ++i) { i->clear(); } for (int i = 0; i != (int) detector.size(); ++i) { for (int j = i; ++j != (int) detector.size(); ) { if (match(detector[i], detector[j])) { zmap[i].push_back(moduleattributes_type(j, detector[i], detector[j])); zmap[j].push_back(moduleattributes_type(i, detector[j], detector[i])); } } } } protected: std::vector zmap; }; } #endif