File indexing completed on 2025-04-19 09:06:53
0001 #ifndef PERCENTILE_HH
0002 #define PERCENTILE_HH
0003
0004 #include "Rivet/Event.hh"
0005 #include "Rivet/Projections/CentralityProjection.hh"
0006 #include "Rivet/ProjectionApplier.hh"
0007
0008 namespace Rivet {
0009
0010
0011
0012 class Analysis;
0013
0014
0015
0016
0017
0018
0019 class PercentileBase {
0020 public:
0021
0022
0023
0024
0025
0026
0027 PercentileBase(Analysis * ana, string projName)
0028 : _ana(ana), _projName(projName) {}
0029
0030
0031 PercentileBase() {}
0032
0033
0034
0035
0036
0037
0038 void selectBins(const Event &);
0039
0040
0041 static bool inRange(double x, pair<float,float> range) {
0042 return x >= range.first && ( x < range.second || ( x == 100.0 && x == range.second ) );
0043 }
0044
0045
0046 void copyFrom(const PercentileBase & other) {
0047 _ana = other._ana;
0048 _projName = other._projName;
0049 _cent = other._cent;
0050 }
0051
0052
0053 bool compatible(const PercentileBase & other) const {
0054 return ( _ana == other._ana &&
0055 _projName == other._projName &&
0056 _cent == other._cent );
0057 }
0058
0059
0060
0061
0062
0063 const vector< pair<float, float> > & centralities() const {
0064 return _cent;
0065 }
0066
0067
0068 protected:
0069
0070
0071 Analysis* _ana;
0072
0073
0074 string _projName;
0075
0076
0077
0078 vector<int> _activeBins;
0079
0080
0081
0082 vector<pair<float, float> > _cent;
0083
0084 };
0085
0086
0087
0088
0089
0090
0091
0092 template<class T>
0093 class PercentileTBase : public PercentileBase {
0094 public:
0095
0096
0097 using TPtr = MultiplexPtr<Multiplexer<T>>;
0098
0099
0100
0101
0102
0103
0104 PercentileTBase(Analysis * ana, string projName)
0105 : PercentileBase(ana, projName), _histos() {}
0106
0107
0108 PercentileTBase() {}
0109
0110
0111 ~PercentileTBase() {}
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122 void add(TPtr ao, CounterPtr cnt,
0123 pair<float,float> cent = {0.0, 100.0} ) {
0124 _cent.push_back(cent);
0125 _histos.push_back( { ao, cnt } );
0126 }
0127
0128
0129
0130
0131
0132
0133 bool add(const PercentileBase & other, const vector<TPtr> & tv) {
0134 copyFrom(other);
0135 if ( tv.size() != _cent.size() ) return false;
0136 for ( auto t : tv )
0137 _histos.push_back( { t, CounterPtr() } );
0138 return true;
0139 }
0140
0141
0142
0143
0144 bool init(const Event & event) {
0145 selectBins(event);
0146 for (const auto bin : _activeBins)
0147 _histos[bin].second->fill();
0148 return !_activeBins.empty();
0149 }
0150
0151
0152
0153
0154
0155 void normalizePerEvent() {
0156 for (const auto &hist : _histos)
0157 if ( hist.second->numEntries() > 0 && hist.first->numEntries() > 0)
0158 hist.first->scaleW(1./hist.second->val());
0159 }
0160
0161
0162 void scale(float scale) {
0163 for (const auto hist : _histos)
0164 hist.first->scaleW(scale);
0165 }
0166
0167
0168 void exec(function<void(T&)> f) { for ( auto hist : _histos) f(hist); }
0169
0170
0171
0172
0173
0174
0175
0176 const vector<pair<TPtr, CounterPtr > > &
0177 analysisObjects() const{
0178 return _histos;
0179 }
0180
0181
0182 protected:
0183
0184
0185
0186
0187
0188 vector<pair<TPtr, CounterPtr > > _histos;
0189
0190 };
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202 template<class T>
0203 class Percentile : public PercentileTBase<T> {
0204 public:
0205
0206
0207
0208
0209
0210
0211 Percentile(Analysis * ana, string projName)
0212 : PercentileTBase<T>(ana, projName) {}
0213
0214
0215 Percentile() {}
0216
0217
0218 ~Percentile() {}
0219
0220
0221 using PercentileTBase<T>::_histos;
0222
0223
0224 using PercentileTBase<T>::_activeBins;
0225
0226
0227
0228 template<typename... Args>
0229 void fill(Args... args) {
0230 for (const auto bin : _activeBins) {
0231 _histos[bin].first->fill(args...);
0232 }
0233 }
0234
0235
0236 Percentile<T> &operator-=(const Percentile<T> &rhs) {
0237 const int nCent = _histos.size();
0238 for (int iCent = 0; iCent < nCent; ++iCent) {
0239 *_histos[iCent].first -= *rhs._histos[iCent].first;
0240 }
0241 }
0242
0243
0244 Percentile<T> &operator+=(const Percentile<T> &rhs) {
0245 const int nCent = _histos.size();
0246 for (int iCent = 0; iCent < nCent; ++iCent) {
0247 *_histos[iCent].first += *rhs._histos[iCent].first;
0248
0249 }
0250 }
0251
0252
0253 Percentile<T> *operator->() { return this; }
0254
0255
0256 Percentile<T> &operator->*(function<void(T&)> f) { exec(f); return *this; }
0257
0258 };
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276 template<class T>
0277 class PercentileXaxis : public PercentileTBase<T> {
0278 public:
0279
0280
0281
0282
0283
0284
0285 PercentileXaxis(Analysis * ana, string projName)
0286 : PercentileTBase<T>(ana, projName) {}
0287
0288
0289 PercentileXaxis() {}
0290
0291
0292 ~PercentileXaxis() {}
0293
0294
0295 using PercentileTBase<T>::_histos;
0296
0297
0298 using PercentileTBase<T>::_activeBins;
0299
0300
0301
0302 template<typename... Args>
0303 void fill(Args... args) {
0304 for (const auto bin : _activeBins) {
0305 _histos[bin].first->fill(bin, args...);
0306 }
0307 }
0308
0309
0310 PercentileXaxis<T> &operator-=(const PercentileXaxis<T> &rhs) {
0311 const int nCent = _histos.size();
0312 for (int iCent = 0; iCent < nCent; ++iCent) {
0313 *_histos[iCent].first -= *rhs._histos[iCent].first;
0314 }
0315 }
0316
0317
0318 PercentileXaxis<T> &operator+=(const PercentileXaxis<T> &rhs) {
0319 const int nCent = this->_histos.size();
0320 for (int iCent = 0; iCent < nCent; ++iCent) {
0321 *_histos[iCent].first += *rhs._histos[iCent].first;
0322 }
0323 }
0324
0325
0326 PercentileXaxis<T> *operator->() { return this; }
0327
0328
0329 PercentileXaxis<T> &operator->*(function<void(T&)> f) { exec(f); return *this; }
0330
0331 };
0332
0333
0334
0335
0336
0337
0338
0339
0340 template <typename T>
0341 Percentile<typename ReferenceTraits<T>::RefT>
0342 divide(const Percentile<T> numer, const Percentile<T> denom) {
0343 typedef typename ReferenceTraits<T>::RefT ScatT;
0344 Percentile<ScatT> ret;
0345 vector<typename ScatT::Ptr> scatters;
0346 assert( numer.compatible(denom) );
0347 for ( int i = 0, N = numer.analysisObjects().size(); i < N; ++i )
0348 scatters.push_back(make_shared<ScatT>(divide(*numer.analysisObjects()[i].first,
0349 *denom.analysisObjects()[i].first)));
0350 ret.add(numer, scatters);
0351 return ret;
0352 }
0353
0354 template <typename T>
0355 Percentile<typename ReferenceTraits<T>::RefT>
0356 divide(const Percentile<T> numer,
0357 const Percentile<typename ReferenceTraits<T>::RefT> denom) {
0358 typedef typename ReferenceTraits<T>::RefT ScatT;
0359 Percentile<ScatT> ret;
0360 vector<typename ScatT::Ptr> scatters;
0361 assert( numer.compatible(denom) );
0362 for ( int i = 0, N = numer.analysisObjects().size(); i < N; ++i )
0363 scatters.push_back(make_shared<ScatT>(divide(*numer.analysisObjects()[i].first,
0364 *denom.analysisObjects()[i].first)));
0365 ret.add(numer, scatters);
0366 return ret;
0367 }
0368
0369 template <typename T>
0370 Percentile<typename ReferenceTraits<T>::RefT>
0371 divide(const Percentile<typename ReferenceTraits<T>::RefT> numer,
0372 const Percentile<T> denom) {
0373 typedef typename ReferenceTraits<T>::RefT ScatT;
0374 Percentile<typename ReferenceTraits<T>::RefT> ret;
0375 vector<typename ScatT::Ptr> scatters;
0376 assert( numer.compatible(denom) );
0377 for ( int i = 0, N = numer.analysisObjects().size(); i < N; ++i )
0378 scatters.push_back(make_shared<ScatT>(divide(*numer.analysisObjects()[i].first,
0379 *denom.analysisObjects()[i].first)));
0380 ret.add(numer, scatters);
0381 return ret;
0382 }
0383
0384 template <typename T>
0385 Percentile<T> add(const Percentile<T> pctla, const Percentile<T> pctlb) {
0386 Percentile<T> ret;
0387 vector<typename T::Ptr> aos;
0388 assert( pctla.compatible(pctlb) );
0389 for ( int i = 0, N = pctla.analysisObjects().size(); i < N; ++i )
0390 aos.push_back(make_shared<T>(add(*pctla.analysisObjects()[i].first,
0391 *pctlb.analysisObjects()[i].first)));
0392 ret.add(pctla, aos);
0393 return ret;
0394 }
0395
0396 template <typename T>
0397 Percentile<typename ReferenceTraits<T>::RefT>
0398 add(const Percentile<T> pctla,
0399 const Percentile<typename ReferenceTraits<T>::RefT> pctlb) {
0400 typedef typename ReferenceTraits<T>::RefT ScatT;
0401 Percentile<ScatT> ret;
0402 vector<typename ScatT::Ptr> scatters;
0403 assert( pctla.compatible(pctlb) );
0404 for ( int i = 0, N = pctla.analysisObjects().size(); i < N; ++i )
0405 scatters.push_back(make_shared<ScatT>(add(*pctla.analysisObjects()[i].first,
0406 *pctlb.analysisObjects()[i].first)));
0407 ret.add(pctla, scatters);
0408 return ret;
0409 }
0410
0411 template <typename T>
0412 Percentile<typename ReferenceTraits<T>::RefT>
0413 add(const Percentile<typename ReferenceTraits<T>::RefT> pctla,
0414 const Percentile<T> pctlb) {
0415 typedef typename ReferenceTraits<T>::RefT ScatT;
0416 Percentile<ScatT> ret;
0417 vector<typename ScatT::Ptr> scatters;
0418 assert( pctla.compatible(pctlb) );
0419 for ( int i = 0, N = pctla.analysisObjects().size(); i < N; ++i )
0420 scatters.push_back(make_shared<ScatT>(add(*pctla.analysisObjects()[i].first,
0421 *pctlb.analysisObjects()[i].first)));
0422 ret.add(pctla, scatters);
0423 return ret;
0424 }
0425
0426 template <typename T>
0427 Percentile<T> subtract(const Percentile<T> pctla, const Percentile<T> pctlb) {
0428 Percentile<T> ret;
0429 vector<typename T::Ptr> aos;
0430 assert( pctla.compatible(pctlb) );
0431 for ( int i = 0, N = pctla.analysisObjects().size(); i < N; ++i )
0432 aos.push_back(make_shared<T>(subtract(*pctla.analysisObjects()[i].first,
0433 *pctlb.analysisObjects()[i].first)));
0434 ret.add(pctla, aos);
0435 return ret;
0436 }
0437
0438 template <typename T>
0439 Percentile<typename ReferenceTraits<T>::RefT>
0440 subtract(const Percentile<T> pctla,
0441 const Percentile<typename ReferenceTraits<T>::RefT> pctlb) {
0442 typedef typename ReferenceTraits<T>::RefT ScatT;
0443 Percentile<ScatT> ret;
0444 vector<typename ScatT::Ptr> scatters;
0445 assert( pctla.compatible(pctlb) );
0446 for ( int i = 0, N = pctla.analysisObjects().size(); i < N; ++i )
0447 scatters.push_back(make_shared<ScatT>(subtract(*pctla.analysisObjects()[i].first,
0448 *pctlb.analysisObjects()[i].first)));
0449 ret.add(pctla, scatters);
0450 return ret;
0451 }
0452
0453 template <typename T>
0454 Percentile<typename ReferenceTraits<T>::RefT>
0455 subtract(const Percentile<typename ReferenceTraits<T>::RefT> pctla,
0456 const Percentile<T> pctlb) {
0457 typedef typename ReferenceTraits<T>::RefT ScatT;
0458 Percentile<ScatT> ret;
0459 vector<typename ScatT::Ptr> scatters;
0460 assert( pctla.compatible(pctlb) );
0461 for ( int i = 0, N = pctla.analysisObjects().size(); i < N; ++i )
0462 scatters.push_back(make_shared<ScatT>(subtract(*pctla.analysisObjects()[i].first,
0463 *pctlb.analysisObjects()[i].first)));
0464 ret.add(pctla, scatters);
0465 return ret;
0466 }
0467
0468 template <typename T>
0469 Percentile<typename ReferenceTraits<T>::RefT>
0470 multiply(const Percentile<T> pctla,
0471 const Percentile<typename ReferenceTraits<T>::RefT> pctlb) {
0472 typedef typename ReferenceTraits<T>::RefT ScatT;
0473 Percentile<ScatT> ret;
0474 vector<typename ScatT::Ptr> scatters;
0475 assert( pctla.compatible(pctlb) );
0476 for ( int i = 0, N = pctla.analysisObjects().size(); i < N; ++i )
0477 scatters.push_back(make_shared<ScatT>(multiply(*pctla.analysisObjects()[i].first,
0478 *pctlb.analysisObjects()[i].first)));
0479 ret.add(pctla, scatters);
0480 return ret;
0481 }
0482
0483 template <typename T>
0484 Percentile<typename ReferenceTraits<T>::RefT>
0485 multiply(const Percentile<typename ReferenceTraits<T>::RefT> pctla,
0486 const Percentile<T> pctlb) {
0487 typedef typename ReferenceTraits<T>::RefT ScatT;
0488 Percentile<ScatT> ret;
0489 vector<typename ScatT::Ptr> scatters;
0490 assert( pctla.compatible(pctlb) );
0491 for ( int i = 0, N = pctla.analysisObjects().size(); i < N; ++i )
0492 scatters.push_back(make_shared<ScatT>(multiply(*pctla.analysisObjects()[i].first,
0493 *pctlb.analysisObjects()[i].first)));
0494 ret.add(pctla, scatters);
0495 return ret;
0496 }
0497
0498
0499
0500 template <typename T>
0501 PercentileXaxis<typename ReferenceTraits<T>::RefT>
0502 divide(const PercentileXaxis<T> numer, const PercentileXaxis<T> denom) {
0503 typedef typename ReferenceTraits<T>::RefT ScatT;
0504 PercentileXaxis<ScatT> ret;
0505 vector<typename ScatT::Ptr> scatters;
0506 assert( numer.compatible(denom) );
0507 for ( int i = 0, N = numer.analysisObjects().size(); i < N; ++i )
0508 scatters.push_back(make_shared<ScatT>(divide(*numer.analysisObjects()[i].first,
0509 *denom.analysisObjects()[i].first)));
0510 ret.add(numer, scatters);
0511 return ret;
0512 }
0513
0514 template <typename T>
0515 PercentileXaxis<typename ReferenceTraits<T>::RefT>
0516 divide(const PercentileXaxis<T> numer,
0517 const PercentileXaxis<typename ReferenceTraits<T>::RefT> denom) {
0518 typedef typename ReferenceTraits<T>::RefT ScatT;
0519 PercentileXaxis<ScatT> ret;
0520 vector<typename ScatT::Ptr> scatters;
0521 assert( numer.compatible(denom) );
0522 for ( int i = 0, N = numer.analysisObjects().size(); i < N; ++i )
0523 scatters.push_back(make_shared<ScatT>(divide(*numer.analysisObjects()[i].first,
0524 *denom.analysisObjects()[i].first)));
0525 ret.add(numer, scatters);
0526 return ret;
0527 }
0528
0529 template <typename T>
0530 PercentileXaxis<typename ReferenceTraits<T>::RefT>
0531 divide(const PercentileXaxis<typename ReferenceTraits<T>::RefT> numer,
0532 const PercentileXaxis<T> denom) {
0533 typedef typename ReferenceTraits<T>::RefT ScatT;
0534 PercentileXaxis<typename ReferenceTraits<T>::RefT> ret;
0535 vector<typename ScatT::Ptr> scatters;
0536 assert( numer.compatible(denom) );
0537 for ( int i = 0, N = numer.analysisObjects().size(); i < N; ++i )
0538 scatters.push_back(make_shared<ScatT>(divide(*numer.analysisObjects()[i].first,
0539 *denom.analysisObjects()[i].first)));
0540 ret.add(numer, scatters);
0541 return ret;
0542 }
0543
0544 template <typename T>
0545 PercentileXaxis<T> add(const PercentileXaxis<T> pctla, const PercentileXaxis<T> pctlb) {
0546 PercentileXaxis<T> ret;
0547 vector<typename T::Ptr> aos;
0548 assert( pctla.compatible(pctlb) );
0549 for ( int i = 0, N = pctla.analysisObjects().size(); i < N; ++i )
0550 aos.push_back(make_shared<T>(add(*pctla.analysisObjects()[i].first,
0551 *pctlb.analysisObjects()[i].first)));
0552 ret.add(pctla, aos);
0553 return ret;
0554 }
0555
0556 template <typename T>
0557 PercentileXaxis<typename ReferenceTraits<T>::RefT>
0558 add(const PercentileXaxis<T> pctla,
0559 const PercentileXaxis<typename ReferenceTraits<T>::RefT> pctlb) {
0560 typedef typename ReferenceTraits<T>::RefT ScatT;
0561 PercentileXaxis<ScatT> ret;
0562 vector<typename ScatT::Ptr> scatters;
0563 assert( pctla.compatible(pctlb) );
0564 for ( int i = 0, N = pctla.analysisObjects().size(); i < N; ++i )
0565 scatters.push_back(make_shared<ScatT>(add(*pctla.analysisObjects()[i].first,
0566 *pctlb.analysisObjects()[i].first)));
0567 ret.add(pctla, scatters);
0568 return ret;
0569 }
0570
0571 template <typename T>
0572 PercentileXaxis<typename ReferenceTraits<T>::RefT>
0573 add(const PercentileXaxis<typename ReferenceTraits<T>::RefT> pctla,
0574 const PercentileXaxis<T> pctlb) {
0575 typedef typename ReferenceTraits<T>::RefT ScatT;
0576 PercentileXaxis<ScatT> ret;
0577 vector<typename ScatT::Ptr> scatters;
0578 assert( pctla.compatible(pctlb) );
0579 for ( int i = 0, N = pctla.analysisObjects().size(); i < N; ++i )
0580 scatters.push_back(make_shared<ScatT>(add(*pctla.analysisObjects()[i].first,
0581 *pctlb.analysisObjects()[i].first)));
0582 ret.add(pctla, scatters);
0583 return ret;
0584 }
0585
0586 template <typename T>
0587 PercentileXaxis<T> subtract(const PercentileXaxis<T> pctla, const PercentileXaxis<T> pctlb) {
0588 PercentileXaxis<T> ret;
0589 vector<typename T::Ptr> aos;
0590 assert( pctla.compatible(pctlb) );
0591 for ( int i = 0, N = pctla.analysisObjects().size(); i < N; ++i )
0592 aos.push_back(make_shared<T>(subtract(*pctla.analysisObjects()[i].first,
0593 *pctlb.analysisObjects()[i].first)));
0594 ret.add(pctla, aos);
0595 return ret;
0596 }
0597
0598 template <typename T>
0599 PercentileXaxis<typename ReferenceTraits<T>::RefT>
0600 subtract(const PercentileXaxis<T> pctla,
0601 const PercentileXaxis<typename ReferenceTraits<T>::RefT> pctlb) {
0602 typedef typename ReferenceTraits<T>::RefT ScatT;
0603 PercentileXaxis<ScatT> ret;
0604 vector<typename ScatT::Ptr> scatters;
0605 assert( pctla.compatible(pctlb) );
0606 for ( int i = 0, N = pctla.analysisObjects().size(); i < N; ++i )
0607 scatters.push_back(make_shared<ScatT>(subtract(*pctla.analysisObjects()[i].first,
0608 *pctlb.analysisObjects()[i].first)));
0609 ret.add(pctla, scatters);
0610 return ret;
0611 }
0612
0613 template <typename T>
0614 PercentileXaxis<typename ReferenceTraits<T>::RefT>
0615 subtract(const PercentileXaxis<typename ReferenceTraits<T>::RefT> pctla,
0616 const PercentileXaxis<T> pctlb) {
0617 typedef typename ReferenceTraits<T>::RefT ScatT;
0618 PercentileXaxis<ScatT> ret;
0619 vector<typename ScatT::Ptr> scatters;
0620 assert( pctla.compatible(pctlb) );
0621 for ( int i = 0, N = pctla.analysisObjects().size(); i < N; ++i )
0622 scatters.push_back(make_shared<ScatT>(subtract(*pctla.analysisObjects()[i].first,
0623 *pctlb.analysisObjects()[i].first)));
0624 ret.add(pctla, scatters);
0625 return ret;
0626 }
0627
0628 template <typename T>
0629 PercentileXaxis<typename ReferenceTraits<T>::RefT>
0630 multiply(const PercentileXaxis<T> pctla,
0631 const PercentileXaxis<typename ReferenceTraits<T>::RefT> pctlb) {
0632 typedef typename ReferenceTraits<T>::RefT ScatT;
0633 PercentileXaxis<ScatT> ret;
0634 vector<typename ScatT::Ptr> scatters;
0635 assert( pctla.compatible(pctlb) );
0636 for ( int i = 0, N = pctla.analysisObjects().size(); i < N; ++i )
0637 scatters.push_back(make_shared<ScatT>(multiply(*pctla.analysisObjects()[i].first,
0638 *pctlb.analysisObjects()[i].first)));
0639 ret.add(pctla, scatters);
0640 return ret;
0641 }
0642
0643 template <typename T>
0644 PercentileXaxis<typename ReferenceTraits<T>::RefT>
0645 multiply(const PercentileXaxis<typename ReferenceTraits<T>::RefT> pctla,
0646 const PercentileXaxis<T> pctlb) {
0647 typedef typename ReferenceTraits<T>::RefT ScatT;
0648 PercentileXaxis<ScatT> ret;
0649 vector<typename ScatT::Ptr> scatters;
0650 assert( pctla.compatible(pctlb) );
0651 for ( int i = 0, N = pctla.analysisObjects().size(); i < N; ++i )
0652 scatters.push_back(make_shared<ScatT>(multiply(*pctla.analysisObjects()[i].first,
0653 *pctlb.analysisObjects()[i].first)));
0654 ret.add(pctla, scatters);
0655 return ret;
0656 }
0657
0658 template <typename T>
0659 Percentile<T>
0660 operator+(const Percentile<T> pctla, const Percentile<T> pctlb) {
0661 return add(pctla, pctlb);
0662 }
0663
0664 template <typename T>
0665 Percentile<T>
0666 operator-(const Percentile<T> pctla, const Percentile<T> pctlb) {
0667 return subtract(pctla, pctlb);
0668 }
0669
0670 template <typename T>
0671 Percentile<typename ReferenceTraits<T>::RefT>
0672 operator/(const Percentile<T> numer, const Percentile<T> denom) {
0673 return divide(numer, denom);
0674 }
0675
0676 template <typename T>
0677 PercentileXaxis<T>
0678 operator+(const PercentileXaxis<T> pctla, const PercentileXaxis<T> pctlb) {
0679 return add(pctla, pctlb);
0680 }
0681
0682 template <typename T>
0683 PercentileXaxis<T>
0684 operator-(const PercentileXaxis<T> pctla, const PercentileXaxis<T> pctlb) {
0685 return subtract(pctla, pctlb);
0686 }
0687
0688 template <typename T>
0689 PercentileXaxis<typename ReferenceTraits<T>::RefT>
0690 operator/(const PercentileXaxis<T> numer, const PercentileXaxis<T> denom) {
0691 return divide(numer, denom);
0692 }
0693
0694
0695
0696
0697 }
0698
0699 #endif