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,
77 MSG_WARNING(
"EventMixing is not fully validated. Use with caution.");
79 _defaultWeightIdx = defaultIdx;
81 for(
double o = oMin; o < oMax; o+=deltao )
86 using Projection::operator =;
93 bool hasMixingEvents()
const {
95 if(mixItr ==
mixEvents.end() || mixItr->second.size() <
nMix + 1)
101 vector<MixEvent> getMixingEvents()
const {
102 if (!hasMixingEvents())
103 return vector<MixEvent>();
105 return vector<MixEvent>(mixItr->second.begin(), mixItr->second.end() - 1);
110 virtual const Particles particles()
const {
112 if (!hasMixingEvents())
116 vector<MixEvent>
mixEvents(mixItr->second.begin(), mixItr->second.end() - 1);
119 vector<double> weights;
121 for (
size_t i = 0; i <
mixEvents.size(); ++i)
123 mixParticles.reserve(pSize);
124 weights.reserve(pSize);
126 for (
size_t i = 0; i <
mixEvents.size(); ++i) {
127 mixParticles.insert(mixParticles.end(),
mixEvents[i].first.begin(),
mixEvents[i].first.end());
129 weights.insert(weights.end(), tmp.begin(), tmp.end());
136 std::shuffle(mixParticles.begin(), mixParticles.end(),
rng());
139 weighted_shuffle(mixParticles.begin(), mixParticles.end(), weights.begin(), weights.end(),
rng());
140 Particles tmp = vector<Particle>(mixParticles.begin(), mixParticles.begin() +
size_t(ceil(mixParticles.size() / 2)));
150 virtual void calculateMixingObs(
const Projection* mProj) = 0;
155 const Projection* mixObsProjPtr = &applyProjection<Projection>(e,
"OBS");
156 calculateMixingObs(mixObsProjPtr);
160 MSG_DEBUG(
"Mixing observable out of bounds.");
164 mixItr->second.push_back(make_pair(mix,e.
weights()[_defaultWeightIdx]));
170 if (mixItr->second.size() >
nMix + 1)
171 mixItr->second.pop_front();
196 size_t _defaultWeightIdx;
205 const ParticleFinder& mix,
size_t nMixIn,
double oMin,
double oMax,
206 double deltao,
const size_t defaultIdx) :
207 EventMixingBase(mixObsProj, mix, nMixIn, oMin, oMax, deltao, defaultIdx) {
208 setName(
"EventMixingFinalState");
214 using Projection::operator =;
220 virtual void calculateMixingObs(
const Projection* mProj) {
232 const ParticleFinder& mix,
size_t nMixIn,
double oMin,
double oMax,
233 double deltao,
const size_t defaultIdx) :
234 EventMixingBase(mixObsProj, mix, nMixIn, oMin, oMax, deltao, defaultIdx) {
235 setName(
"EventMixingCentrality");
241 using Projection::operator =;
246 virtual void calculateMixingObs(
const Projection* mProj) {
Used together with the percentile-based analysis objects Percentile and PercentileXaxis.
Definition CentralityProjection.hh:27
Definition EventMixingFinalState.hh:66
size_t nMix
The number of event to mix with.
Definition EventMixingFinalState.hh:188
bool unitWeights
Using unit weights or not.
Definition EventMixingFinalState.hh:194
MixMap mixEvents
The event map.
Definition EventMixingFinalState.hh:191
void project(const Event &e)
Perform the projection on the Event.
Definition EventMixingFinalState.hh:154
double mObs
The mixing observable of the current event.
Definition EventMixingFinalState.hh:182
CmpState compare(const Projection &p) const
Compare with other projections.
Definition EventMixingFinalState.hh:176
Definition EventMixingFinalState.hh:228
Definition EventMixingFinalState.hh:202
Representation of a HepMC event, and enabler of Projection caching.
Definition Event.hh:22
std::valarray< double > weights() const
The generation weights associated with the event.
Base class for projections which return subsets of an event's particles.
Definition ParticleFinder.hh:11
virtual const Particles & particles() const
Get the particles in no particular order, with no cuts.
Definition ParticleFinder.hh:52
Specialised vector of Particle objects.
Definition Particle.hh:25
const PROJ & declare(const PROJ &proj, const std::string &name)
Register a contained projection (user-facing version)
Definition ProjectionApplier.hh:170
Base class for all Rivet projections.
Definition Projection.hh:29
void setName(const std::string &name)
Used by derived classes to set their name.
Definition Projection.hh:142
Cmp< Projection > mkNamedPCmp(const Projection &otherparent, const std::string &pname) const
#define MSG_DEBUG(x)
Debug messaging, not enabled by default, using MSG_LVL.
Definition Logging.hh:195
#define MSG_WARNING(x)
Warning messages for non-fatal bad things, using MSG_LVL.
Definition Logging.hh:200
double p(const ParticleBase &p)
Unbound function access to p.
Definition ParticleBaseUtils.hh:684
Definition MC_Cent_pPb.hh:10
std::mt19937 & rng()
Return a thread-safe random number generator (mainly for internal use)