#ifndef __JSUPPORT__JEVTWEIGHTFILESCANNER__ #define __JSUPPORT__JEVTWEIGHTFILESCANNER__ #include #include #include #include "km3net-dataformat/offline/Head.hh" #include "km3net-dataformat/offline/Evt.hh" #include "JLang/JException.hh" #include "JAAnet/JHead.hh" #include "JAAnet/JEvtWeightHelper.hh" #include "JAAnet/JEvtWeightToolkit.hh" #include "JAAnet/JEvtWeightFactor.hh" #include "JAAnet/JEvtWeightFactorHelper.hh" #include "JAAnet/JEvtWeightFactorMultiParticle.hh" #include "JAAnet/JFlux.hh" #include "JSupport/JMultipleFileScanner.hh" #include "JSupport/JMonteCarloFileSupportkit.hh" /** * \author bjung */ namespace JSUPPORT { using JLANG::JNoValue; using JAANET::JHead; using JAANET::JEvtWeight; using JAANET::JEvtWeightHelper; using JAANET::JEvtWeightFactor; using JAANET::JEvtWeightFactorHelper; using JAANET::JEvtWeightFactorMultiParticle; using JAANET::JFlux; /** * Template event-weighter-associated file scanner. * * Note: The template class must be derived from JMultipleFileScanner */ template > struct JEvtWeightFileScanner : public JEvtWeightHelper, public JFileScanner_t { typedef typename JFileScanner_t::input_type input_type; /** * Default constructor. */ JEvtWeightFileScanner() : JEvtWeightHelper(), JFileScanner_t() {} /** * Constructor. * * \param weighter event weighter */ JEvtWeightFileScanner(const JEvtWeight& weighter) : JEvtWeightHelper(), JFileScanner_t() { reset(weighter); } /** * Constructor. * * \param input input */ JEvtWeightFileScanner(const input_type& input) : JEvtWeightHelper(), JFileScanner_t() { using namespace JPP; const JHead& header = JSUPPORT::getHeader(input); const JEvtWeight& weighter = getEventWeighter(header); reset(weighter); put (input); } /** * Get name of simulation program. * * \return unique identifier */ std::string getProgramName() const { using namespace std; using namespace JPP; static const char SEPARATOR = '.'; const JHead& header = this->getHeader(); if (header.simul.size() > 0) { string name = header.simul.cbegin()->program; for (vector::const_iterator i = next(header.simul.cbegin()); i != header.simul.cend(); ++i) { name += MAKE_STRING(SEPARATOR << i->program); } return name; } else { THROW(JNoValue, "JEvtWeightFileScanner::getProgramName(): Missing simul header-field!"); } } /** * Reset file scanner and event weighter. * * \param weighter event weighter */ void reset(const JEvtWeight& weighter) { JEvtWeightHelper::configure(weighter); JFileScanner_t ::clear(); } /** * Put files. * * \param input input files * \return number of added files */ size_t put(const input_type& input) { size_t n = 0; for (typename input_type::const_iterator i = input.begin(); i != input.end(); ++i) { n += size_t(this->put(*i)); } return n; } /** * Put file. * * \param input input file * \return true if successfully added; else false. */ bool put(const std::string& input) { using namespace JPP; const JHead& head = JSUPPORT::getHeader(input); if (this->check(head)) { JEvtWeightHelper::add(head); JFileScanner_t ::push_back(input); return true; } else { return false; } } /** * Set event-weight factor corresponding to a given PDG code. * * The template argument corresponds to the desired class of event-weight factor. * This class must contain the method `getFactor(const Evt&)`. * * Note that the given event-weight factor will only be assigned if the header < b>exclusively< /b> lists the given PDG code as primary. * * \param type PDG code * \param factor event-weight factor * \return true if event-weight factor set successfully; else false */ template bool setEvtWeightFactor(const int type, const JEvtWeightFactor_t& factor) { using namespace std; using namespace JPP; typedef JEvtWeightFactorHelper JEvtWeightFactorHelper_t; const JHead& header = this->getHeader(); vector::const_iterator i = find_if(header.flux.cbegin(), header.flux.cend(), make_predicate(&flux::type, type)); if ((header.primary.type == type) || (abs(type) == TRACK_TYPE_MUON && is_mupage(header)) || (header.flux.size() == 1 && i != header.flux.end())) { JEvtWeightFactorHelper_t* helper = dynamic_cast(this->get()); if (helper != NULL) { helper->configure(factor); return true; } } return false; } /** * Set event-weight factor corresponding to a given set of PDG codes. * * The template argument corresponds to the desired class of event-weight factor. * This class must contain the method `getFactor(const Evt&)`. * * Note that the given event-weight factor will only be assigned\n * if the header lists < b>all< /b> of the specified PDG codes as primaries. * * \param types set of PDG codes * \param factor event-weight factor * \return true if event-weight factor set successfully; else false */ template bool setEvtWeightFactor(const std::set& types, const JEvtWeightFactor_t& factor) { using namespace std; using namespace JPP; typedef JEvtWeightFactorHelper JEvtWeightFactorHelper_t; bool matching = (!types.empty()); const JHead& header = this->getHeader(); for (std::set::const_iterator i = types.cbegin(); i != types.cend() && matching; ++i) { vector::const_iterator flux = find_if(header.flux.cbegin(), header.flux.cend(), make_predicate(&flux::type, *i)); matching = (flux != header.flux.cend()); } if (matching) { JEvtWeightFactorHelper_t* helper = dynamic_cast(this->get()); if (helper != NULL) { helper->configure(factor); return true; } } return false; } /** * Set event-weight factor corresponding to a given multi-particle weighting factor interface. * * The template argument corresponds to the desired class of event-weight factor. * This class must contain the method `getFactor(const Evt&)`. * * Note that the given event-weight factors will only be assigned\n * if the header lists < b>all< /b> of the PDG codes associated with the multi-particle event-weight factor interface as primaries. * * \param multiParticleFactor multi-particle event-weight factor * \return true if multi-particle event-weight factor set successfully; else false */ template bool setEvtWeightFactor(const JEvtWeightFactorMultiParticle& multiParticleFactor) { using namespace std; using namespace JPP; typedef JEvtWeightFactorHelper JEvtWeightFactorHelper_t; typedef JEvtWeightFactorMultiParticle JEvtWeightFactorMultiParticle_t; typedef typename JEvtWeightFactorMultiParticle_t::const_iterator const_iterator; bool matching = (!multiParticleFactor.empty()); const JHead& header = this->getHeader(); for (const_iterator i = multiParticleFactor.cbegin(); i != multiParticleFactor.cend() && matching; ++i) { vector::const_iterator flux = find_if(header.flux.cbegin(), header.flux.cend(), make_predicate(&flux::type, i->first)); matching = (flux != header.flux.cend()); } if (matching) { JEvtWeightFactorHelper_t* helper = dynamic_cast(this->get()); if (helper != NULL) { helper->configure(multiParticleFactor); return true; } } return false; } /** * Set flux function corresponding to a given PDG code. * * Note that only the given flux function will only be assigned\n * if the header exclusively lists the given PDG code as primary. * * \param type PDG code * \param function flux function * \return true if event-weight factor set successfully; else false */ bool setFlux(const int type, const JFlux& function) { return setEvtWeightFactor(type, function); } /** * Set flux function corresponding to a given set of PDG codes. * * Note that the given flux function will only be assigned\n * if the header lists < b>all< /b> of the specified PDG codes as primaries. * * \param types set of PDG codes * \param function flux function * \return true if event-weight factor set successfully; else false */ bool setFlux(const std::set& types, const JFlux& function) { return setEvtWeightFactor(types, function); } /** * Set flux function corresponding to a given multi-particle flux interface. * * Note that the given flux functions will only be assigned\n * if the lists < b>all< /b> of the PDG codes associated with the multi-particle flux object as primaries. * * \param multiParticleFlux multi-particle flux object * \return true if multi-particle event-weight factor set successfully; else false */ bool setFlux(const JEvtWeightFactorMultiParticle& multiParticleFlux) { return setEvtWeightFactor(multiParticleFlux); } }; } #endif