rivet is hosted by Hepforge, IPPP Durham
Rivet  2.7.0
CentralityBinner.hh
1 // -*- C++ -*-
2 #ifndef RIVET_CENTRALITYBINNER_HH
3 #define RIVET_CENTRALITYBINNER_HH
4 #include <tuple>
5 #include "Rivet/Config/RivetCommon.hh"
6 #include "Rivet/Tools/RivetYODA.hh"
7 
8 namespace Rivet {
9 
36 public:
37 
39  CentralityEstimator(): _estimate(-1.0) {}
40 
43 
44 protected:
45 
47  void project(const Event& e) {
48  _estimate = -1.0;
49  const HepMC::HeavyIon * hi = e.genEvent()->heavy_ion();
50  if ( hi ) _estimate = hi->impact_parameter() > 0.0?
51  1.0/hi->impact_parameter(): numeric_limits<double>::max();
52  }
53 
55  int compare(const Projection& p) const {
56  return mkNamedPCmp(p, "CentEst");
57  }
58 
59 
60 public:
61 
63  double estimate() const { return _estimate; }
64 
65 
66 protected:
67 
69  double _estimate;
70 
71 };
72 
73 
77 template <typename T>
79 
81  static T clone(const T & t) {
82  return T(t->newclone());
83  }
84 
86  static void add(T & t, const T & o) {
87  *t += *o;
88  }
89 
91  static void scale(T & t, double f) {
92  t->scaleW(f);
93  }
94 
97  static void normalize(T & t, double sumw) {
98  if ( t->sumW() > 0.0 ) t->normalize(t->sumW()/sumw);
99  }
100 
102  static string path(T t) {
103  return t->path();
104  }
105 
106 };
107 
112 
122  static double dist(double cestLo, double cestHi, double weight,
123  double clo, double chi, double, double) {
124  return (cestHi - cestLo)*weight/(cestHi*(chi - clo));
125  }
126 };
127 
128 
136 template <typename T = Histo1DPtr, typename MDist = MergeDistance>
138  public:
139 
144  CentralityBinner(int maxbins = 200, double wlim = 0.02)
145  : _currentCEst(-1.0), _maxBins(maxbins), _warnlimit(wlim), _weightsum(0.0) {
146  _percentiles.insert(0.0);
147  _percentiles.insert(1.0);
148  }
149 
152  void setProjection(const CentralityEstimator & p, string pname) {
153  declare(p, pname);
154  _estimator = pname;
155  }
156 
158  virtual std::string name() const {
159  return "Rivet::CentralityBinner";
160  }
161 
166 
170 
173 
174  void add(T t, double cmin, double cmax,
175  double cestmin = -1.0, double cestmax = -1.0 ) {
176  _percentiles.insert(max(1.0 - cmax/100.0, 0.0));
177  _percentiles.insert(min(1.0 - cmin/100.0, 1.0));
178  if ( _unfilled.empty() && _ready.empty() )
179  _devnull = CentralityBinTraits<T>::clone(t);
180  if ( cestmin < 0.0 )
181  _unfilled.push_back(Bin(t, 1.0 - cmax/100.0, 1.0 - cmin/100.0));
182  else
183  _ready[t] = Bin(t, 1.0 - cmax/100.0, 1.0 - cmin/100.0, cestmin, cestmax);
184  }
185 
194  T select(const Event & event, double weight = 1.0) {
195  return select(applyProjection<CentralityEstimator>
196  (event, _estimator).estimate(), weight);
197  }
198 
205  T select(double cest, double weight = 1.0);
206 
213  void finalize();
214 
218  for ( auto & b : _ready ) b.second.normalizePerEvent();
219  }
220 
223  map<double,double> edges() const {
224  map<double,double> ret;
225  for ( auto & b : _ready ) {
226  ret[1.0 - b.second._centLo] = b.second._cestLo;
227  ret[1.0 - b.second._centHi] = b.second._cestHi;
228  }
229  return ret;
230  }
231 
233  const T & current() const {
234  return _currenT;
235  }
236 
239  double estimator() const {
240  return _currentCEst;
241  }
242 
243  vector<T> allObjects() {
244  vector<T> ret;
245  for ( auto & fb : _flexiBins ) ret.push_back(fb._t);
246  if ( !ret.empty() ) return ret;
247  for ( auto b : _ready ) ret.push_back(b.second._t);
248  return ret;
249  }
250 
251 private:
252 
254  struct FlexiBin {
255 
258  FlexiBin(T & t, double cest = 0.0, double weight = 0.0)
259  : _t(t), _cestLo(cest), _cestHi(cest), _weightsum(weight), _n(1), _m(0) {}
260 
262  FlexiBin(double cest)
263  : _cestLo(cest), _cestHi(cest), _weightsum(0.0), _n(0), _m(0) {}
264 
266  void merge(const FlexiBin & fb) {
267  _cestLo = min(_cestLo, fb._cestLo);
268  _cestHi = max(_cestHi, fb._cestHi);
269  _weightsum += fb._weightsum;
270  CentralityBinTraits<T>::add(_t, fb._t);
271  _n += fb._n;
272  _m += fb._m + 1;
273  }
274 
276  bool operator< (const FlexiBin & fb) const {
277  return _cestLo < fb._cestLo;
278  }
279 
282  bool inRange(double cest) const {
283  return cest == _cestLo || ( _cestLo < cest && cest < _cestHi );
284  }
285 
287  T _t;
288 
291  double _cestLo, _cestHi;
292 
295  mutable double _weightsum;
296 
298  mutable int _n;
299 
301  mutable int _m;
302 
303  };
304 
305  struct Bin {
306 
308  Bin()
309  : _centLo(-1.0), _centHi(-1.0), _cestLo(-1.0), _cestHi(-1.0),
310  _weightsum(0.0), _underflow(0.0), _overflow(0.0),
311  _ambiguous(0), _ambweight(0.0) {}
312 
317  Bin(T t, double centLo, double centHi,
318  double cestLo = -1.0, double cestHi = -1.0)
319  : _t(t), _centLo(centLo), _centHi(centHi),
320  _cestLo(cestLo), _cestHi(cestHi),
321  _weightsum(0.0), _underflow(0.0), _overflow(0.0),
322  _ambiguous(0.0), _ambweight(0.0) {}
323 
326  bool inRange(double cest) const {
327  return _cestLo >= 0 && _cestLo <= cest &&
328  ( _cestHi < 0.0 || cest <= _cestHi );
329  }
330 
332  void normalizePerEvent() {
333  CentralityBinTraits<T>::normalize(_t, _weightsum);
334  }
335 
337  T _t;
338 
340  double _centLo, _centHi;
341 
343  double _cestLo, _cestHi;
344 
346  double _weightsum;
347 
350  double _underflow;
351 
354  double _overflow;
355 
357  double _ambiguous;
358 
360  double _ambweight;
361 
362  };
363 
364 protected:
365 
367  typedef set<FlexiBin> FlexiBinSet;
368 
371  typename FlexiBinSet::iterator _findBin(double cest) {
372  if ( _flexiBins.empty() ) return _flexiBins.end();
373  auto it = _flexiBins.lower_bound(FlexiBin(cest));
374  if ( it->_cestLo == cest ) return it;
375  if ( it != _flexiBins.begin() ) --it;
376  if ( it->_cestLo < cest && cest < it->_cestHi ) return it;
377  return _flexiBins.end();
378  }
379 
381  string _estimator;
382 
385  T _currenT;
386 
388  double _currentCEst;
389 
392  int _maxBins;
393 
396  double _warnlimit;
397 
400  vector<Bin> _unfilled;
401 
403  FlexiBinSet _flexiBins;
404 
406  double _weightsum;
407 
409  set<double> _percentiles;
410 
412  map<T, Bin> _ready;
413 
416  T _devnull;
417 
418 public:
419 
421  void debug();
422  void fulldebug();
423 
424 };
425 
426 
428 template <>
429 struct CentralityBinTraits<Profile1DPtr> {
430 
431  typedef Profile1DPtr T;
432 
434  static T clone(const T & t) {
435  return Profile1DPtr(t->newclone());
436  }
437 
439  static void add(T & t, const T & o) {
440  *t += *o;
441  }
442 
444  static void scale(T & t, double f) {
445  t->scaleW(f);
446  }
447 
448  static void normalize(T & t, double sumw) {}
449 
451  static string path(T t) {
452  return t->path();
453  }
454 
455 };
456 
457 
459 template <>
460 struct CentralityBinTraits<Profile2DPtr> {
461 
462  typedef Profile2DPtr T;
463 
465  static T clone(const T & t) {
466  return Profile2DPtr(t->newclone());
467  }
468 
470  static void add(T & t, const T & o) {
471  *t += *o;
472  }
473 
475  static void scale(T & t, double f) {
476  t->scaleW(f);
477  }
478 
479  static void normalize(T & t, double sumw) {}
480 
482  static string path(T t) {
483  return t->path();
484  }
485 
486 };
487 
488 template <typename T>
489 struct CentralityBinTraits< vector<T> > {
490 
492  static vector<T> clone(const vector<T> & tv) {
493  vector<T> rtv;
494  for ( auto t : tv ) rtv.push_back(CentralityBinTraits<T>::clone(t));
495  return rtv;
496  }
497 
499  static void add(vector<T> & tv, const vector<T> & ov) {
500  for ( int i = 0, N = tv.size(); i < N; ++i )
501  CentralityBinTraits::add(tv[i], ov[i]);
502  }
503 
505  static void scale(vector<T> & tv, double f) {
506  for ( auto t : tv ) CentralityBinTraits<T>::scale(t, f);
507  }
508 
509  static void normalize(vector<T> & tv, double sumw) {
510  for ( auto t : tv ) CentralityBinTraits<T>::normalize(t, sumw);
511  }
512 
514  static string path(const vector<T> & tv) {
515  string ret = "(vector:";
516  for ( auto t : tv ) {
517  ret += " ";
519  }
520  ret += ")";
521  return ret;
522  }
523 
524 };
525 
526 template <size_t I, typename... Types>
528 
529  typedef tuple<Types...> Tuple;
530  typedef typename tuple_element<I-1,Tuple>::type T;
531 
532  static void clone(Tuple & ret, const Tuple & tup) {
533  get<I-1>(ret) = CentralityBinTraits<T>::clone(get<I-1>(tup));
535  }
536 
537  static void add(Tuple & tup, const Tuple & otup) {
538  CentralityBinTraits<T>::add(get<I-1>(tup),get<I-1>(otup));
540  }
541 
542  static void scale(Tuple & tup, double f) {
543  CentralityBinTraits<T>::scale(get<I-1>(tup), f);
545  }
546 
547  static void normalize(Tuple & tup, double sumw) {
548  CentralityBinTraits<T>::normalize(get<I-1>(tup), sumw);
550  }
551 
552  static string path(const Tuple & tup) {
553  return " " + CentralityBinTraits<T>::path(get<I-1>(tup))
555  }
556 };
557 
558 template <typename... Types>
559 struct TupleCentralityBinTraitsHelper<0,Types...> {
560 
561  typedef tuple<Types...> Tuple;
562 
563  static void clone(Tuple &, const Tuple &) {}
564  static void add(Tuple & tup, const Tuple & otup) {}
565  static void scale(Tuple & tup, double f) {}
566  static void normalize(Tuple & tup, double sumw) {}
567  static string path(const Tuple & tup) {return "";}
568 
569 };
570 
571 template <typename... Types>
572 struct CentralityBinTraits< tuple<Types...> > {
573 
574  typedef tuple<Types...> Tuple;
575  static const size_t N = tuple_size<Tuple>::value;
576 
578  static Tuple clone(const Tuple & tup) {
579  Tuple ret;
581  return ret;
582  }
583 
585  static void add(Tuple & tup, const Tuple & otup) {
587  }
588 
590  static void scale(Tuple & tup, double f) {
592  }
593 
594  static void normalize(Tuple & tup, double sumw) {
596  }
597 
599  static string path(const Tuple & tup) {
600  string ret = "(tuple:";
602  ret += ")";
603  return ret;
604  }
605 
606 };
607 
608 template <typename T, typename MDist>
609 T CentralityBinner<T,MDist>::select(double cest, double weight) {
610  _currenT = _devnull;
611  _currentCEst = cest;
612  _weightsum += weight;
613 
614  // If estimator is negative, something has gone wrong.
615  if ( _currentCEst < 0.0 ) return _currenT;
616 
617  // If we already have finalized the limits on the centrality
618  // estimator, we just add the weights to their bins and return the
619  // corresponding AnalysisObject.
620  if ( _unfilled.empty() ) {
621  for ( auto & b : _ready ) if ( b.second.inRange(_currentCEst) ) {
622  b.second._weightsum += weight;
623  return b.second._t;
624  }
625  return _currenT;
626  }
627 
628  auto it = _findBin(cest);
629  if ( it == _flexiBins.end() ) {
630  _currenT = CentralityBinTraits<T>::clone(_unfilled.begin()->_t);
631  it = _flexiBins.insert(FlexiBin(_currenT, _currentCEst, weight)).first;
632  } else {
633  it->_weightsum += weight;
634  ++(it->_n);
635  _currenT = it->_t;
636  }
637 
638  if ( (int)_flexiBins.size() <= _maxBins ) return _currenT;
639 
640 
641  set<double>::iterator citn = _percentiles.begin();
642  set<double>::iterator cit0 = citn++;
643  auto selectit = _flexiBins.end();
644  double mindist = -1.0;
645  double acc = 0.0;
646  auto next = _flexiBins.begin();
647  auto prev = next++;
648  for ( ; next != _flexiBins.end(); prev = next++ ) {
649  acc += prev->_weightsum/_weightsum;
650  if ( acc > *citn ) {
651  cit0 = citn++;
652  continue;
653  }
654  if ( acc + next->_weightsum/_weightsum > *citn ) continue;
655  double dist = MDist::dist(prev->_cestLo, next->_cestHi,
656  next->_weightsum + prev->_weightsum,
657  *cit0, *citn, next->_n + prev->_n,
658  next->_m + prev->_m);
659  if ( mindist < 0.0 || dist < mindist ) {
660  selectit = prev;
661  mindist = dist;
662  }
663  }
664 
665  if ( selectit == _flexiBins.end() ) return _currenT;
666  auto mergeit = selectit++;
667  FlexiBin merged = *mergeit;
668  merged.merge(*selectit);
669  if ( merged.inRange(cest) || selectit->inRange(cest) )
670  _currenT = merged._t;
671  _flexiBins.erase(mergeit);
672  _flexiBins.erase(selectit);
673  _flexiBins.insert(merged);
674 
675  return _currenT;
676 
677 }
678 
679 
680 template <typename T, typename MDist>
682 
683  // Take the contents of the dynamical binning and fill the original
684  // AnalysisObjects.
685 
686  double clo = 0.0;
687  for ( const FlexiBin & fb : _flexiBins ) {
688  double chi = min(clo + fb._weightsum/_weightsum, 1.0);
689  for ( Bin & bin : _unfilled ) {
690  double olo = bin._centLo;
691  double ohi = bin._centHi;
692  if ( clo > ohi || chi <= olo ) continue;
693  // If we only have partial overlap we need to scale
694  double lo = max(olo, clo);
695  double hi = min(ohi, chi);
696  T t = CentralityBinTraits<T>::clone(fb._t);
697  double frac = (hi - lo)/(chi - clo);
699  CentralityBinTraits<T>::add(bin._t, t);
700  bin._weightsum += fb._weightsum*frac;
701  if ( clo <= olo ) bin._cestLo = fb._cestLo +
702  (fb._cestHi - fb._cestLo)*(olo - clo)/(chi - clo);
703  if ( clo < olo ) {
704  bin._underflow = clo;
705  bin._ambiguous += fb._n*frac;
706  bin._ambweight += fb._weightsum*frac*(1.0 - frac);
707  }
708  if ( chi > ohi ) {
709  bin._cestHi =
710  fb._cestLo + (fb._cestHi - fb._cestLo)*(ohi - clo)/(chi - clo);
711  bin._overflow = chi;
712  bin._ambiguous += fb._n*frac;
713  bin._ambweight += fb._weightsum*frac*(1.0 - frac);
714  }
715  }
716  clo = chi;
717  }
718  _flexiBins.clear();
719  for ( Bin & bin : _unfilled ) {
720  if ( bin._overflow == 0.0 ) bin._overflow = 1.0;
721  _ready[bin._t] = bin;
722  if ( bin._ambweight/bin._weightsum >_warnlimit )
723  MSG_WARNING("Analysis object \"" << CentralityBinTraits<T>::path(bin._t)
724  << "\", contains events with centralities between "
725  << bin._underflow*100.0
726  << " and " << bin._overflow*100.0 << "% ("
727  << int(bin._ambiguous + 0.5)
728  << " ambiguous events with effectively "
729  << 100.0*bin._ambweight/bin._weightsum
730  << "% of the weights)."
731  << "Consider increasing the number of bins.");
732 
733  }
734  _unfilled.clear();
735 
736 }
737 
738 template <typename T, typename MDist>
740  cerr << endl;
741  double acc = 0.0;
742  set<double>::iterator citn = _percentiles.begin();
743  set<double>::iterator cit0 = citn++;
744  int i = 0;
745  for ( auto it = _flexiBins.begin(); it != _flexiBins.end(); ) {
746  ++i;
747  auto curr = it++;
748  double w = curr->_weightsum/_weightsum;
749  acc += w;
750  if ( curr == _flexiBins.begin() || it == _flexiBins.end() || acc > *citn )
751  cerr << "*";
752  else
753  cerr << " ";
754  if ( acc > *citn ) cit0 = citn++;
755  cerr << setw(6) << i
756  << setw(12) << acc - w
757  << setw(12) << acc
758  << setw(8) << curr->_n
759  << setw(8) << curr->_m
760  << setw(12) << curr->_cestLo
761  << setw(12) << curr->_cestHi << endl;
762  }
763  cerr << "Number of sampler bins: " << _flexiBins.size() << endl;
764 }
765 
766 template <typename T, typename MDist>
768  cerr << endl;
769  double acc = 0.0;
770  int i = 0;
771  set<double>::iterator citn = _percentiles.begin();
772  set<double>::iterator cit0 = citn++;
773  for ( auto it = _flexiBins.begin(); it != _flexiBins.end(); ) {
774  auto curr = it++;
775  ++i;
776  double w = curr->_weightsum/_weightsum;
777  acc += w;
778  if ( curr == _flexiBins.begin() || it == _flexiBins.end() || acc > *citn ) {
779  if ( acc > *citn ) cit0 = citn++;
780  cerr << setw(6) << i
781  << setw(12) << acc - w
782  << setw(12) << acc
783  << setw(8) << curr->_n
784  << setw(8) << curr->_m
785  << setw(12) << curr->_cestLo
786  << setw(12) << curr->_cestHi << endl;
787 
788  }
789  }
790  cerr << "Number of sampler bins: " << _flexiBins.size() << endl;
791 }
792 
796 
797 public:
798 
801 
804 
805 protected:
806 
808  void project(const Event& e) {
809  _estimate = -1.0;
810 #if HEPMC_VERSION_CODE >= 3000000
811  const HepMC::HeavyIon * hi = e.genEvent()->heavy_ion();
812  if ( hi ) _estimate = 100.0 - hi->centrality; // @TODO We don't really know how to interpret this number!
813 #endif
814  }
815 
817  int compare(const Projection& p) const {
818  return mkNamedPCmp(p, "GeneratedCentrality");
819  }
820 
821 };
822 
823 
824 
825 }
826 
827 #endif
Definition: CentralityBinner.hh:527
Definition: ALICE_2010_I880049.cc:13
static string path(T t)
Return the name of an AnalysisObject.
Definition: CentralityBinner.hh:482
static void add(T &t, const T &o)
Add the contents of o to t.
Definition: CentralityBinner.hh:86
int compare(const Projection &p) const
Compare projections.
Definition: CentralityBinner.hh:55
static T clone(const T &t)
Make a clone of the given object.
Definition: CentralityBinner.hh:81
virtual unique_ptr< Projection > clone() const =0
Clone on the heap.
CentralityBinner(int maxbins=200, double wlim=0.02)
Definition: CentralityBinner.hh:144
static T clone(const T &t)
Make a clone of the given object.
Definition: CentralityBinner.hh:465
void debug()
Print out the _flexiBins to cerr.
Definition: CentralityBinner.hh:767
static void add(vector< T > &tv, const vector< T > &ov)
Add the contents of o to t.
Definition: CentralityBinner.hh:499
void project(const Event &e)
Perform the projection on the Event.
Definition: CentralityBinner.hh:47
DEFAULT_RIVET_PROJ_CLONE(CentralityEstimator)
Clone on the heap.
CentralityEstimator()
Constructor.
Definition: CentralityBinner.hh:39
Definition: CentralityBinner.hh:78
static void scale(Tuple &tup, double f)
Scale the contents of a given object.
Definition: CentralityBinner.hh:590
static string path(const vector< T > &tv)
Return the path of an AnalysisObject.
Definition: CentralityBinner.hh:514
static T clone(const T &t)
Make a clone of the given object.
Definition: CentralityBinner.hh:434
const GenEvent * genEvent() const
The generated event obtained from an external event generator.
Definition: Event.hh:51
void add(T t, double cmin, double cmax, double cestmin=-1.0, double cestmax=-1.0)
Definition: CentralityBinner.hh:174
double estimator() const
Definition: CentralityBinner.hh:239
static void scale(T &t, double f)
Scale the contents of a given object.
Definition: CentralityBinner.hh:444
Definition: Event.hh:22
set< FlexiBin > FlexiBinSet
Convenient typedefs.
Definition: CentralityBinner.hh:367
static void add(Tuple &tup, const Tuple &otup)
Add the contents of o to t.
Definition: CentralityBinner.hh:585
void finalize()
Definition: CentralityBinner.hh:681
Common base class for Projection and Analysis, used for internal polymorphism.
Definition: ProjectionApplier.hh:21
Base class for projections giving the value of an observable sensitive to the centrality of a collisi...
Definition: CentralityBinner.hh:35
std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value &&std::is_arithmetic< N3 >::value, bool >::type inRange(N1 value, N2 low, N3 high, RangeBoundary lowbound=CLOSED, RangeBoundary highbound=OPEN)
Determine if value is in the range low to high, for floating point numbers.
Definition: MathUtils.hh:103
map< double, double > edges() const
Definition: CentralityBinner.hh:223
virtual std::string name() const
Return the class name.
Definition: CentralityBinner.hh:158
void setProjection(const CentralityEstimator &p, string pname)
Definition: CentralityBinner.hh:152
Definition: CentralityBinner.hh:795
void project(const Event &e)
Perform the projection on the Event.
Definition: CentralityBinner.hh:808
Cmp< Projection > mkNamedPCmp(const Projection &otherparent, const std::string &pname) const
Definition: Projection.cc:51
static string path(T t)
Return the path of an AnalysisObject.
Definition: CentralityBinner.hh:102
double estimate() const
The value of the centrality estimate.
Definition: CentralityBinner.hh:63
static string path(const Tuple &tup)
Return the path of an AnalysisObject.
Definition: CentralityBinner.hh:599
const PROJ & declare(const PROJ &proj, const std::string &name)
Register a contained projection (user-facing version)
Definition: ProjectionApplier.hh:160
static void scale(vector< T > &tv, double f)
Scale the contents of a given object.
Definition: CentralityBinner.hh:505
double max(const vector< double > &in, double errval=DBL_NAN)
Find the maximum value in the vector.
Definition: Utils.hh:465
static double dist(double cestLo, double cestHi, double weight, double clo, double chi, double, double)
Definition: CentralityBinner.hh:122
static Tuple clone(const Tuple &tup)
Make a clone of the given object.
Definition: CentralityBinner.hh:578
const T & current() const
Return the current AnalysisObject from the latest call to select().
Definition: CentralityBinner.hh:233
static string path(T t)
Return the path of an AnalysisObject.
Definition: CentralityBinner.hh:451
static vector< T > clone(const vector< T > &tv)
Make a clone of the given object.
Definition: CentralityBinner.hh:492
static void add(T &t, const T &o)
Add the contents of o to t.
Definition: CentralityBinner.hh:439
static void normalize(T &t, double sumw)
Definition: CentralityBinner.hh:97
void normalizePerEvent()
Definition: CentralityBinner.hh:217
static void scale(T &t, double f)
Scale the contents of a given object.
Definition: CentralityBinner.hh:475
static void scale(T &t, double f)
Scale the contents of a given object.
Definition: CentralityBinner.hh:91
Base class for all Rivet projections.
Definition: Projection.hh:29
int compare(const Projection &p) const
Compare projections.
Definition: CentralityBinner.hh:817
Definition: CentralityBinner.hh:137
T select(const Event &event, double weight=1.0)
Definition: CentralityBinner.hh:194
static void add(T &t, const T &o)
Add the contents of o to t.
Definition: CentralityBinner.hh:470
double min(const vector< double > &in, double errval=DBL_NAN)
Find the minimum value in the vector.
Definition: Utils.hh:459
Definition: CentralityBinner.hh:111
GeneratedCentrality()
Constructor.
Definition: CentralityBinner.hh:800