#ifndef __JSUPPORT__JRANDOMSAMPLER__ #define __JSUPPORT__JRANDOMSAMPLER__ #include #include #include "TRandom3.h" #include "JLang/JObjectIterator.hh" /** * \author mdejong */ namespace JSUPPORT {} namespace JPP { using namespace JSUPPORT; } namespace JSUPPORT { using JLANG::skip_type; /** * Template class for randomly sampling from a JLANG::JRewindableObjectIterator using a JLANG::JObjectSampler. * * The JRandomSampler class provides for an implementation of randomly sampling objects.\n * The sampling is controlled via two parameters, namely: * - a sequential iteration of a predefined average number of objects (JRandomSampler::averageOn); and * - a predefined average number of objects to skip (JRandomSampler::averageOff). */ template struct JRandomSampler { /** * Default constructor. * * This constructor will sample all objects. */ JRandomSampler() : averageOn (1), averageOff(0), count (0) {} /** * Constructor. * * \param on average number of consecutively accepted events * \param off average number of consecutively rejected events */ JRandomSampler(const unsigned int on, const unsigned int off) : averageOn (on), averageOff(off), count (0) {} /** * Get random sampler. * * \return random sampler */ const JRandomSampler& getRandomSampler() const { return static_cast(*this); } /** * Get random sampler. * * \return random sampler */ JRandomSampler& getRandomSampler() { return static_cast(*this); } /** * Acceptance test operator. * Return value 0 means accept and >0 number of objects to skip. * * \param object object * \return number of objects to skip */ skip_type operator()(const T& object) const { if (count == 0) { count = gRandom->Integer(2 * averageOn); return (skip_type) gRandom->Integer(2 * averageOff); } else { count -= 1; return 0; } } /** * Read random sampler from input. * * \param in input stream * \param sampler random sampler * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JRandomSampler& sampler) { in >> sampler.averageOn; in >> sampler.averageOff; sampler.count = 0; return in; } /** * Write random sampler to output. * * \param out output stream * \param sampler random sampler * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JRandomSampler& sampler) { out << sampler.averageOn; out << ' '; out << sampler.averageOff; return out; } protected: skip_type averageOn; skip_type averageOff; mutable skip_type count; }; } #endif