2 #ifndef RIVET_EventMixingFinalState_HH 3 #define RIVET_EventMixingFinalState_HH 5 #include "Rivet/Projection.hh" 6 #include "Rivet/Projections/ParticleFinder.hh" 7 #include "Rivet/Tools/Random.hh" 34 template <
class RandomAccessIterator,
35 class WeightIterator,
class RandomNumberGenerator>
36 void weighted_shuffle(RandomAccessIterator first, RandomAccessIterator last,
37 WeightIterator fw, WeightIterator lw, RandomNumberGenerator& g) {
38 while(first != last && fw != lw) {
39 std::discrete_distribution<int> weightDist(fw, lw);
40 int i = weightDist(g);
42 std::iter_swap(first, next(first, i));
43 std::iter_swap(fw, next(fw, i));
50 typedef pair<Particles, double> MixEvent;
51 typedef map<double, std::deque<MixEvent> > MixMap;
70 size_t nMixIn,
double oMin,
double oMax,
double deltao) : nMix(nMixIn),
77 MSG_WARNING(
"EventMixing is not fully validated. Use with caution.");
80 for(
double o = oMin; o < oMax; o+=deltao )
81 mixEvents[o] = std::deque<MixEvent>();
88 bool hasMixingEvents()
const {
89 MixMap::const_iterator mixItr = mixEvents.lower_bound(
mObs);
90 if(mixItr == mixEvents.end() || mixItr->second.size() < nMix + 1)
96 vector<MixEvent> getMixingEvents()
const {
97 if (!hasMixingEvents())
98 return vector<MixEvent>();
99 MixMap::const_iterator mixItr = mixEvents.lower_bound(
mObs);
100 return vector<MixEvent>(mixItr->second.begin(), mixItr->second.end() - 1);
105 virtual const Particles particles()
const {
107 if (!hasMixingEvents())
110 MixMap::const_iterator mixItr = mixEvents.lower_bound(
mObs);
111 vector<MixEvent> mixEvents(mixItr->second.begin(), mixItr->second.end() - 1);
113 Particles mixParticles;
114 vector<double> weights;
116 for (
size_t i = 0; i < mixEvents.size(); ++i)
117 pSize+=mixEvents[i].first.size();
118 mixParticles.reserve(pSize);
119 weights.reserve(pSize);
121 for (
size_t i = 0; i < mixEvents.size(); ++i) {
122 mixParticles.insert(mixParticles.end(), mixEvents[i].first.begin(), mixEvents[i].first.end());
123 vector<double> tmp(mixEvents[i].first.size(), mixEvents[i].second);
124 weights.insert(weights.end(), tmp.begin(), tmp.end());
131 std::shuffle(mixParticles.begin(), mixParticles.end(),
rng());
134 weighted_shuffle(mixParticles.begin(), mixParticles.end(), weights.begin(), weights.end(),
rng());
135 Particles tmp = vector<Particle>(mixParticles.begin(), mixParticles.begin() + size_t(ceil(mixParticles.size() / 2)));
145 virtual void calculateMixingObs(
const Projection* mProj) = 0;
150 const Projection* mixObsProjPtr = &applyProjection<Projection>(e,
"OBS");
151 calculateMixingObs(mixObsProjPtr);
152 MixMap::iterator mixItr = mixEvents.lower_bound(
mObs);
153 if (mixItr == mixEvents.end()){
155 MSG_DEBUG(
"Mixing observable out of bounds.");
158 const Particles mix = applyProjection<ParticleFinder>(e,
"MIX").particles();
159 mixItr->second.push_back(make_pair(mix,e.weights()[0]));
161 if (unitWeights && e.weights()[0] != 1.0 ) {
165 if (mixItr->second.size() > nMix + 1)
166 mixItr->second.pop_front();
198 const ParticleFinder& mix,
size_t nMixIn,
double oMin,
double oMax,
201 setName(
"EventMixingFinalState");
209 virtual void calculateMixingObs(
const Projection* mProj) {
221 const ParticleFinder& mix,
size_t nMixIn,
double oMin,
double oMax,
224 setName(
"EventMixingCentrality");
231 virtual void calculateMixingObs(
const Projection* mProj) {
void setName(const std::string &name)
Used by derived classes to set their name.
Definition: Projection.hh:142
Definition: MC_Cent_pPb.hh:10
Used together with the percentile-based analysis objects Percentile and PercentileXaxis.
Definition: CentralityProjection.hh:26
void project(const Event &e)
Perform the projection on the Event.
Definition: EventMixingFinalState.hh:149
Definition: EventMixingFinalState.hh:66
CmpState compare(const Projection &p) const
Compare with other projections.
Definition: EventMixingFinalState.hh:171
Base class for projections which return subsets of an event's particles.
Definition: ParticleFinder.hh:11
Representation of a HepMC event, and enabler of Projection caching.
Definition: Event.hh:22
double mObs
The mixing observable of the current event.
Definition: EventMixingFinalState.hh:177
const PROJ & declare(const PROJ &proj, const std::string &name)
Register a contained projection (user-facing version)
Definition: ProjectionApplier.hh:160
Cmp< Projection > mkNamedPCmp(const Projection &otherparent, const std::string &pname) const
Definition: EventMixingFinalState.hh:195
Definition: EventMixingFinalState.hh:217
Base class for all Rivet projections.
Definition: Projection.hh:29
std::mt19937 & rng()
Return a thread-safe random number generator (mainly for internal use)