rivet is hosted by Hepforge, IPPP Durham
Rivet 4.0.0
PercentileProjection.hh
1// -*- C++ -*-
2#ifndef RIVET_PERCENTILEPROJECTION_HH
3#define RIVET_PERCENTILEPROJECTION_HH
4
5#include "Rivet/Projections/SingleValueProjection.hh"
6#include "Rivet/Tools/RivetYODA.hh"
7#include <map>
8
9namespace Rivet {
10
11 enum class PercentileOrder { INCREASING, DECREASING };
12
13
20 public:
21
22 using SingleValueProjection::operator =;
23
29 PercentileProjection(const SingleValueProjection & sv, const Histo1D& calhist,
30 PercentileOrder pctorder=PercentileOrder::DECREASING)
31 : _calhist("EMPTY"),
32 _increasing(pctorder == PercentileOrder::INCREASING)
33 {
34 setName("PercentileProjection");
35 declare(sv, "OBSERVABLE");
36 //if ( !calhist ) return;
37 MSG_DEBUG("Constructing PercentileProjection from " << calhist.path());
38 _calhist = calhist.path();
39 int N = calhist.numBins();
40 double sum = calhist.sumW();
41 if ( _increasing ) {
42 double acc = 0.0;
43 for (int i = 0; i <= N; ++i) {
44 acc += calhist.bin(i).sumW();
45 _table.insert(make_pair(calhist.bin(i).xMax(), 100.0*acc/sum));
46 }
47 }
48 else {
49 double acc = 0.0;
50 for (int i = N+1; i > 0; --i) {
51 acc += calhist.bin(i).sumW();
52 _table.insert(make_pair(calhist.bin(i).xMin(), 100.0*acc/sum));
53 }
54 }
55 if (getLog().isActive(Log::DEBUG)) {
56 MSG_DEBUG("Mapping from observable to percentile:");
57 for (auto p : _table) {
58 std::cout << std::setw(16) << p.first << " -> "
59 << std::setw(16) << p.second << "%" << std::endl;
60 if (not _increasing and p.second <= 0) break;
61 if (_increasing and p.second >= 100) break;
62 }
63 }
64 }
65
66
67 // Constructor taking a SingleValueProjection and a calibration
68 // histogram. If increasing it means that low values corresponds to
69 // lower percentiles.
70 PercentileProjection(const SingleValueProjection & sv, const Estimate1D& calest,
71 PercentileOrder pctorder=PercentileOrder::DECREASING)
72 : _calhist("EMPTY"),
73 _increasing(pctorder == PercentileOrder::INCREASING)
74 {
75 declare(sv, "OBSERVABLE");
76
77 //if ( !calest ) return;
78 MSG_DEBUG("Constructing PercentileProjection from " << calest.path());
79 _calhist = calest.path();
80 int N = calest.numBins();
81 double sum = 0.0;
82 for (const auto &b : calest.bins() ) sum += b.val();
83
84 double acc = 0.0;
85 if ( _increasing ) {
86 _table.insert(make_pair(calest.bin(1).xMin(), 100.0*acc/sum));
87 for ( int i = 0; i < N; ++i ) {
88 acc += calest.bin(i+1).val();
89 _table.insert(make_pair(calest.bin(i+1).xMax(), 100.0*acc/sum));
90 }
91 }
92 else {
93 _table.insert(make_pair(calest.bin(N).xMax(), 100.0*acc/sum));
94 for (int i = N - 1; i >= 0; --i) {
95 acc += calest.bin(i+1).val();
96 _table.insert(make_pair(calest.bin(i+1).xMin(), 100.0*acc/sum));
97 }
98 }
99 }
100
101
102 RIVET_DEFAULT_PROJ_CLONE(PercentileProjection);
103
105 using Projection::operator =;
106
107
108 // The projection function takes the assigned SingeValueProjection
109 // and sets the value of this projection to the corresponding
110 // percentile. If no calibration has been provided, -1 will be
111 // returned. If values are outside of the calibration histogram, 0
112 // or 100 will be returned.
113 void project(const Event& e) {
114 clear();
115 if ( _table.empty() ) return;
116 auto& pobs = apply<SingleValueProjection>(e, "OBSERVABLE");
117 double obs = pobs();
118 double pcnt = lookup(obs);
119 if ( pcnt >= 0.0 ) setValue(pcnt);
120 MSG_DEBUG("Observable(" << pobs.name() << ")="
121 << std::setw(16) << obs
122 << "-> Percentile=" << std::setw(16) << pcnt << "%");
123 }
124
125 // Standard comparison function.
126 CmpState compare(const Projection& p) const {
127 const PercentileProjection pp = dynamic_cast<const PercentileProjection&>(p);
128 return mkNamedPCmp(p, "OBSERVABLE") ||
129 cmp(_increasing, pp._increasing) ||
130 cmp(_calhist, pp._calhist);
131 }
132
133
134 protected:
135
136 // The (interpolated) lookup table
137 double lookup(double obs) const {
138 auto low = _table.upper_bound(obs);
139 if ( low == _table.end() ) return _increasing? 100.0: 0.0;
140 if ( low == _table.begin() ) return _increasing? 0.0: 100.0;
141 auto high = low--;
142 return low->second + (obs - low->first)*(high->second - low->second)/
143 (high->first - low->first);
144 }
145
146 // Astring identifying the calibration histogram.
147 string _calhist;
148
149 // A lookup table to find (by interpolation) the percentile given
150 // the value of the underlying SingleValueProjection.
151 map<double,double> _table;
152
153 // A flag to say whether the distribution should be integrated from
154 // below or above.
155 bool _increasing;
156
157 };
158
159
160}
161
162#endif
Representation of a HepMC event, and enabler of Projection caching.
Definition Event.hh:22
class for projections that reports the percentile for a given SingleValueProjection when initialized ...
Definition PercentileProjection.hh:19
void project(const Event &e)
Definition PercentileProjection.hh:113
CmpState compare(const Projection &p) const
Definition PercentileProjection.hh:126
PercentileProjection(const SingleValueProjection &sv, const Histo1D &calhist, PercentileOrder pctorder=PercentileOrder::DECREASING)
Definition PercentileProjection.hh:29
const PROJ & declare(const PROJ &proj, const std::string &name) const
Register a contained projection (user-facing version)
Definition ProjectionApplier.hh:175
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:148
Log & getLog() const
Get a Log object based on the getName() property of the calling projection object.
Definition Projection.hh:142
Cmp< Projection > mkNamedPCmp(const Projection &otherparent, const std::string &pname) const
Base class for projections returning a single floating point value.
Definition SingleValueProjection.hh:17
void setValue(double v)
Set the value.
Definition SingleValueProjection.hh:48
void clear()
Unset the value.
Definition SingleValueProjection.hh:54
#define MSG_DEBUG(x)
Debug messaging, not enabled by default, using MSG_LVL.
Definition Logging.hh:182
Definition MC_CENT_PPB_Projections.hh:10
T sum(const DressedLeptons &c, FN &&fn, const T &start=T())
Generic sum function, adding fn(x) for all x in container c, starting with start.
Definition DressedLepton.hh:60
Cmp< T > cmp(const T &t1, const T &t2)
Global helper function for easy creation of Cmp objects.
Definition Cmp.hh:255