#ifndef __JAANET__JEVTWEIGHTFACTORMULTIPARTICLE__ #define __JAANET__JEVTWEIGHTFACTORMULTIPARTICLE__ #include #include "km3net-dataformat/offline/Evt.hh" #include "km3net-dataformat/offline/Trk.hh" #include "JLang/JClonable.hh" #include "JLang/JPredicate.hh" #include "JLang/JException.hh" #include "JAAnet/JHead.hh" #include "JAAnet/JFlux.hh" #include "JAAnet/JAAnetToolkit.hh" #include "JAAnet/JEvtWeightFactor.hh" #include "JAAnet/JEvtWeightFactorHelper.hh" /** * \author bjung */ namespace JAANET { using JLANG::JClonable; using JLANG::JValueOutOfRange; /** * Implementation of event-weight factor for multiple particle types. * * The first template argument corresponds to the type of event-weight factor class. * This class must contain the method `getFactor(const Evt&)`. * The second template argument refers to the helper-class to the event-weight factor * of the type of the first template argument. */ template struct JEvtWeightFactorMultiParticle : public JClonable >, public std::map > { typedef JEvtWeightFactorHelper JEvtWeightFactorHelper_t; typedef std::map map_type; /** * Default constructor. */ JEvtWeightFactorMultiParticle() : map_type() {} /** * Constructor. * * The multi-particle flux function is created\n * listing all the primaries in the JHead::flux vector field of the given header. * * \param header header * \param factor factor */ JEvtWeightFactorMultiParticle(const JHead& header, const JEvtWeightFactor_t& factor) : map_type() { if (!header.flux.empty()) { for (vector::const_iterator i = header.flux.cbegin(); i != header.flux.cend(); ++i) { insert(i->type, factor); } } else { THROW(JValueOutOfRange, "JEvtWeightFactorMultiParticle::JEvtWeightFactorMultiParticle(): Empty flux header-field."); } } /** * Constructor. * * \param type particle PDG code * \param factor event-weight factor * \param args remaining pairs of PDG codes and event-weight factors */ template JEvtWeightFactorMultiParticle(const int type, const JEvtWeightFactor_t& factor, const Args& ...args) : map_type() { insert(type, factor, args...); } /** * Insert pair of particle code and event-weight factor. * * \param type particle PDG code * \param factor event-weight factor */ void insert(const int type, const JEvtWeightFactor_t& factor) { map_type::insert(std::make_pair(type, JEvtWeightFactorHelper_t(factor))); } /** * Insert pairs of particle codes and event-weight factors. * * \param type particle PDG code * \param factor event-weight factor * \param args remaining pairs of PDG codes and event-weight factors */ template void insert(const int type, const JEvtWeightFactor_t& factor, const Args& ...args) { insert(type, factor); insert(args...); } /** * Get weight factor of given event. * * \param evt event * \return weight-factor for given event */ virtual double getFactor(const Evt& evt) const override { using namespace std; using namespace JPP; vector::const_iterator primary = find_if(evt.mc_trks.cbegin(), evt.mc_trks.cend(), make_predicate(&Trk::is_primary, true)); if (primary != evt.mc_trks.cend()) { return this->at(primary->type).getFactor(evt); } else if (has_neutrino(evt)) { const Trk& neutrino = get_neutrino(evt); return this->at(neutrino.type).getFactor(evt); } else { THROW(JValueOutOfRange, "JEvtWeightFactorMultiParticle::getFactor(): No primary track found for event " << evt.id << "."); } } }; /** * Type-definition of multi-particle event-weight factor for fluxes. */ typedef JEvtWeightFactorMultiParticle JFluxMultiParticle; } #endif