#ifndef __JSUPPORT_JEVTWEIGHTFILESCANNERSET__ #define __JSUPPORT_JEVTWEIGHTFILESCANNERSET__ #include #include #include #include "km3net-dataformat/offline/Head.hh" #include "km3net-dataformat/offline/Evt.hh" #include "JLang/JException.hh" #include "JLang/JPredicate.hh" #include "JLang/JComparator.hh" #include "JAAnet/JHead.hh" #include "JAAnet/JEvtWeightToolkit.hh" #include "JAAnet/JEvtWeightFactor.hh" #include "JAAnet/JEvtWeightFactorMultiParticle.hh" #include "JAAnet/JFlux.hh" #include "JSupport/JMultipleFileScanner.hh" #include "JSupport/JEvtWeightFileScanner.hh" #include "JSupport/JMonteCarloFileSupportkit.hh" /** * \author bjung */ namespace JSUPPORT {} namespace JPP { using namespace JSUPPORT; } namespace JSUPPORT { using JAANET::JHead; using JAANET::JEvtWeightFactor; using JAANET::JEvtWeightFactorMultiParticle; using JAANET::JFlux; /** * Auxiliary class for organising Monte Carlo file scanners associated with event weighters. * * Note: The template class must be derived from JMultipleFileScanner. */ template, class JComparator_t = std::less > struct JEvtWeightFileScannerSet : public std::vector< JEvtWeightFileScanner > { typedef JEvtWeightFileScannerSet filescannerset_type; typedef JEvtWeightFileScanner filescanner_type; typedef typename filescanner_type::input_type input_type; typedef typename std::vector::value_type value_type; typedef typename std::vector::reference reference; typedef typename std::vector::const_reference const_reference; typedef typename std::vector::const_iterator const_iterator; typedef typename std::vector::iterator iterator; typedef typename std::vector::const_reverse_iterator const_reverse_iterator; typedef typename std::vector::reverse_iterator reverse_iterator; /** * Default constructor. */ JEvtWeightFileScannerSet() {} /** * Constructor. * * \param input input files */ JEvtWeightFileScannerSet(const input_type& input) { put(input); } /** * 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 std; using namespace JPP; const JHead& head = getHeader(input); iterator i = lower_bound(this->begin(), this->end(), head, make_comparator(&JHead::getHeader, compare)); if (i == this->end() || !i->getHeader().match(head)) { i = this->insert(i, value_type(getEventWeighter(head))); } return i->put(input); } /** * Get unique identifier for a file-scanner contained within this set of event-weighter-associated file-scanners. * * \param p iterator to contained file-scanner * \return unique identifier of contained file-scanner */ std::string getUniqueIdentifier(const_iterator p) const { using namespace std; using namespace JPP; static const char SEPARATOR = '.'; string name = p->getProgramName(); int index = 0; for (const_iterator i = this->cbegin(); i != this->cend() && i != p; ++i) { if (i->getProgramName() == name) { ++index; } } return MAKE_STRING(name << SEPARATOR << index); } /** * Find file scanner compatible with a given header. * * \param head header * \return file scanner */ const_reference find(const JHead& head) const { using namespace JPP; for (const_iterator i = this->begin(); i != this->end(); ++i) { if (i->match(head)) { return *i; } } THROW(JValueOutOfRange, "JEvtWeightFileScannerSet::get(): No corresponding scanner found for given header."); } /** * Set event-weighting factor for all MC-files 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-weighting factor will only be assigned to those files\n * whose header exclusively lists the given PDG code as primary. * * \param type PDG code * \param factor event-weight factor * \return number of modified event weighters */ template size_t setEvtWeightFactor(const int type, const JEvtWeightFactor_t& factor) { using namespace std; using namespace JPP; size_t n = 0; for (iterator i = this->begin(); i != this->end(); ++i) { n += (size_t) i->template setEvtWeightFactor(type, factor); } return n; } /** * Set event-weight factor of all MC-files 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&)`. * * If the boolean `requireAll` argument is set to `true`, * the given event-weighting factor will only be assigned to those files\n * whose header lists < b>all< /b> of the specified PDG codes as primaries. * * \param types set of PDG codes * \param factor event-weight factor * \param requireAll toggle requirement that each file header must contain every given PDG code. * \return number of modified event weighters */ template size_t setEvtWeightFactor(const std::set& types, const JEvtWeightFactor_t& factor, const bool requireAll = false) { using namespace std; using namespace JPP; size_t n = 0; if (requireAll) { for (iterator i = this->begin(); i != this->end(); ++i) { n += (size_t) i->template setEvtWeightFactor(types, factor); } } else { for (iterator i = this->begin(); i != this->end(); ++i) { bool isSet = false; for (set::const_iterator j = types.cbegin(); j != types.cend() && !isSet; ++j) { isSet = i->template setEvtWeightFactor(*i, factor); } n += (size_t) isSet; } } return n; } /** * Set event-weight factor of all MC-files corresponding to a given multi-particle flux. * * The template argument corresponds to the desired class of event-weight factor. * This class must contain the method `getFactor(const Evt&)`. * * If the boolean `requireAll` argument is set to `true`, * the given flux factor will only be assigned to those files\n * whose header lists < b>all< /b> of the PDG codes associated with the multi-particle flux interface as primaries. * * \param multiParticleFactor multi-particle event-weight factor * \param requireAll toggle requirement that each file header must contain every given PDG code. * \return number of modified event weighters */ template size_t setEvtWeightFactor(const JEvtWeightFactorMultiParticle& multiParticleFactor, const bool requireAll = false) { using namespace std; using namespace JPP; size_t n = 0; if (requireAll) { for (iterator i = this->begin(); i != this->end(); ++i) { n += (size_t) i->template setEvtWeightFactor(multiParticleFactor); } } else { for (iterator i = this->begin(); i != this->end(); ++i) { bool isSet = false; for (typename JEvtWeightFactorMultiParticle::const_iterator j = multiParticleFactor.cbegin(); j != multiParticleFactor.cend() && !isSet; ++j) { isSet = i->template setEvtWeightFactor(j->first, *(j->second)); } n += (size_t) isSet; } } return n; } /** * Set flux function for all MC-files corresponding to a given PDG code. * * Note that only the given flux function will only be assigned to those files\n * whose header exclusively lists the given PDG code as primary. * * \param type PDG code * \param flux flux function * \return number of modified event weighters */ size_t setFlux(const int type, const JFlux& flux) { return setEvtWeightFactor(type, flux); } /** * Set flux function of all MC-files corresponding to a given set of PDG codes. * * If the boolean `requireAll` argument is set to `true`, * the given flux function will only be assigned to those files\n * whose header lists < b>all< /b> of the specified PDG codes as primaries. * * \param types set of PDG codes * \param flux flux function * \param requireAll toggle requirement that each file header must contain every given PDG code. * \return number of modified event weighters */ size_t setFlux(const std::set& types, const JFlux& flux, const bool requireAll = false) { return setEvtWeightFactor(types, flux, requireAll); } /** * Set flux function of all MC-files corresponding to a given multi-particle flux interface. * * If the boolean `requireAll` argument is set to `true`, * the given flux factor will only be assigned to those files\n * whose header lists < b>all< /b> of the PDG codes associated with the multi-particle flux interface as primaries. * * \param multiParticleFlux multi-particle flux object * \param requireAll toggle requirement that each file header must contain every given PDG code. * \return number of modified event weighters */ size_t setFlux(const JEvtWeightFactorMultiParticle& multiParticleFlux, const bool requireAll = false) { return setEvtWeightFactor(multiParticleFlux, requireAll); } /** * Function object for comparison of headers. */ JComparator_t compare; }; } #endif