yoda is hosted by Hepforge, IPPP Durham
YODA - Yet more Objects for Data Analysis 2.0.2
BinnedEstimate.h
Go to the documentation of this file.
1// -*- C++ -*-
2//
3// This file is part of YODA -- Yet more Objects for Data Analysis
4// Copyright (C) 2008-2024 The YODA collaboration (see AUTHORS for details)
5//
6#ifndef YODA_BinnedEstimate_h
7#define YODA_BinnedEstimate_h
8
10#include "YODA/BinnedStorage.h"
11#include "YODA/Estimate.h"
12#include "YODA/Scatter.h"
13#include "YODA/Transformation.h"
15#include <regex>
16
17namespace YODA {
18
20 namespace {
22 template<size_t axisN, typename BinT>
23 std::pair<double, double> nullifyIfDisc(const BinT& /* b */, const double /* val */, std::false_type, const double null = 0.0) {
24 return { null, null };
25 }
26
29 template<size_t axisN, typename BinT>
30 std::pair<double, double> nullifyIfDisc(const BinT& b, const double val, std::true_type, const double /* null */ = 0.0) {
31 return { val - b.template min<axisN>(), b.template max<axisN>() - val };
32 }
33
35 template<size_t axisN, typename BinT>
36 double unifyIfDisc(const BinT& /* b */, std::false_type, const double unity = 1.0) {
37 return unity;
38 }
39
41 template<size_t axisN, typename BinT>
42 double unifyIfDisc(const BinT& b, std::true_type, const double /* unity */ = 1.0) {
43 return b.template width<axisN>();
44 }
45
47 template<size_t axisN, typename BinT>
48 double coordPicker(const BinT& b, std::false_type, std::false_type) {
49 return b.index();
50 }
51
53 template<size_t axisN, typename BinT>
54 double coordPicker(const BinT& b, std::true_type, std::false_type) {
55 return b.template edge<axisN>();
56 }
58 template<size_t axisN, typename BinT>
59 double coordPicker(const BinT& b, std::true_type, std::true_type) {
60 return b.template mid<axisN>();
61 }
62 }
63
64
66 template <typename... AxisT>
67 class BinnedEstimate;
68
74 template<typename... AxisT>
76 : public BinnedStorage<Estimate, AxisT...>,
77 public AnalysisObject {
78 protected:
79
80 using BaseT = BinnedStorage<Estimate, AxisT...>;
81 using BinningT = typename BaseT::BinningT;
82 using BinT = typename BaseT::BinT;
83
84 public:
85
86 using BinType = BinT;
87 using AnalysisObject::operator =;
88
91
93 EstimateStorage(const std::string& path = "", const std::string& title = "")
94 : BaseT(), AnalysisObject(mkTypeString<AxisT...>(), path, title) { }
95
101 EstimateStorage(std::vector<AxisT>&&... binsEdges, const std::string& path = "", const std::string& title = "")
102 : BaseT(Axis<AxisT>(std::move(binsEdges))...), AnalysisObject(mkTypeString<AxisT...>(), path, title) { }
103
109 EstimateStorage(const std::vector<AxisT>&... binsEdges, const std::string& path = "", const std::string& title = "")
110 : BaseT(Axis<AxisT>(binsEdges)...), AnalysisObject(mkTypeString<AxisT...>(), path, title) { }
111
117 EstimateStorage(std::initializer_list<AxisT>&&... binsEdges, const std::string& path = "", const std::string& title = "")
118 : BaseT(Axis<AxisT>(std::move(binsEdges))...), AnalysisObject(mkTypeString<AxisT...>(), path, title) { }
119
121 template <typename EdgeT = double, typename = enable_if_all_CAxisT<EdgeT, AxisT...>>
122 EstimateStorage(const std::vector<size_t>& nBins,
123 const std::vector<std::pair<EdgeT, EdgeT>>& limitsLowUp,
124 const std::string& path = "", const std::string& title = "")
125 //: BaseT( BinningT(nBins, limitsLowUp, std::make_index_sequence<sizeof...(AxisT)>{}) ),
126 : BaseT( _mkBinning(nBins, limitsLowUp, std::make_index_sequence<sizeof...(AxisT)>{}) ),
127 AnalysisObject(mkTypeString<AxisT...>(), path, title) { }
128
130 EstimateStorage(const BinningT& binning, const std::string& path = "", const std::string& title = "")
131 : BaseT(binning), AnalysisObject(mkTypeString<AxisT...>(), path, title) { }
132
134 EstimateStorage(BinningT&& binning, const std::string& path = "", const std::string& title = "")
135 : BaseT(std::move(binning)), AnalysisObject(mkTypeString<AxisT...>(), path, title) { }
136
138 template <typename EdgeT = double, typename = enable_if_all_CAxisT<EdgeT, AxisT...>>
139 EstimateStorage(const ScatterND<sizeof...(AxisT)+1>& s, const std::string& path = "", const std::string& title = "")
140 : BaseT(_mkBinning(s, std::make_index_sequence<sizeof...(AxisT)>{})),
141 AnalysisObject(mkTypeString<AxisT...>(), path, title) { }
142
146 EstimateStorage(const EstimateStorage& other, const std::string& path = "") : BaseT(other),
147 AnalysisObject(mkTypeString<AxisT...>(), path!=""? path : other.path(), other, other.title()) { }
148
152 EstimateStorage(EstimateStorage&& other, const std::string& path = "") : BaseT(std::move(other)),
153 AnalysisObject(mkTypeString<AxisT...>(), path!=""? path : other.path(), other, other.title()) { }
154
156 EstimateStorage clone() const noexcept {
157 return EstimateStorage(*this);
158 }
159
161 EstimateStorage* newclone() const noexcept {
162 return new EstimateStorage(*this);
163 }
164
166
167
170
171 private:
172
173 // @brief Render information about this AO (private implementation)
174 template<size_t... Is>
175 void _renderYODA_aux(std::ostream& os, const int width, std::index_sequence<Is...>) const noexcept {
176
177 // print bin edges
178 BaseT::_binning._renderYODA(os);
179
180 // Assemble union of error sources, as it's not guaranteed
181 // that every bin has the same error breakdown
182 const std::vector<std::string> labels = this->sources();
183 if (labels.size()) {
184 os << "ErrorLabels: [";
185 for (size_t i = 0; i < labels.size(); ++i) {
186 const std::string& src = labels[i];
187 if (i) os << ", ";
188 os << std::quoted(src);
189 }
190 os << "]\n";
191 }
192
193 // column header: content types
194 os << std::setw(width) << std::left << "# value" << "\t";
195 const int errwidth = std::max(int(std::to_string(labels.size()).size()+7), width); // "errDn(" + src + ")"
196 for (size_t i = 0; i < labels.size(); ++i) {
197 const std::string& src = labels[i];
198 if (src.empty()) {
199 os << std::setw(errwidth) << std::left << "totalDn" << "\t"
200 << std::setw(errwidth) << std::left << "totalUp" << "\t";
201 }
202 else {
203 os << std::setw(errwidth) << std::left << ("errDn(" + std::to_string(i+1) + ")") << "\t"
204 << std::setw(errwidth) << std::left << ("errUp(" + std::to_string(i+1) + ")") << "\t";
205 }
206 }
207 os << "\n";
208
209 for (const auto& b : BaseT::bins(true, true)) {
210 os << std::setw(width) << std::left << b.val() << "\t"; // print value
211 // print systs if available
212 for (const std::string& src : labels) {
213 if (!b.hasSource(src)) {
214 os << std::setw(errwidth) << std::left << "---" << "\t"
215 << std::setw(errwidth) << std::left << "---" << "\t";
216 continue;
217 }
218 const auto& err = b.err(src);
219 os << std::setw(errwidth) << std::left << err.first << "\t"
220 << std::setw(errwidth) << std::left << err.second << "\t";
221 }
222 os << "\n";
223 }
224 }
225
226 public:
227
230
231 // @brief Render information about this AO
232 void _renderYODA(std::ostream& os, const int width = 13) const noexcept {
233 _renderYODA_aux(os, width, std::make_index_sequence<sizeof...(AxisT)>{});
234 }
235
236 // @brief Render scatter-like information about this AO
237 void _renderFLAT(std::ostream& os, const int width = 13) const noexcept {
238 const ScatterND<sizeof...(AxisT)+1> tmp = mkScatter();
239 tmp._renderYODA(os, width);
240 }
241
243
244
247
249 void scale(const double scalefactor) noexcept {
250 setAnnotation("ScaledBy", annotation<double>("ScaledBy", 1.0) * scalefactor);
251 for (auto& bin : BaseT::_bins) {
252 bin.scale(scalefactor);
253 }
254 }
255
256
265 template <size_t axisN>
266 void rebinBy(unsigned int n, size_t begin=1, size_t end=UINT_MAX) {
267 if (n < 1) throw UserError("Rebinning requested in groups of 0!");
268 if (!begin) throw UserError("Visible bins start with index 1!");
269 if (end > BaseT::numBinsAt(axisN)+1) end = BaseT::numBinsAt(axisN) + 1;
270 for (size_t m = begin; m < end; ++m) {
271 if (m > BaseT::numBinsAt(axisN)+1) break; // nothing to be done
272 const size_t myend = (m+n-1 < BaseT::numBinsAt(axisN)+1) ? m+n-1 : BaseT::numBinsAt(axisN);
273 if (myend > m) {
274 BaseT::template mergeBins<axisN>({m, myend});
275 end -= myend-m; //< reduce upper index by the number of removed bins
276 }
277 }
278 }
279
281 template <size_t axisN>
282 void rebin(unsigned int n, size_t begin=1, size_t end=UINT_MAX) {
283 rebinBy<axisN>(n, begin, end);
284 }
285
287 template <size_t axisN>
288 void rebinTo(const std::vector<typename BinningT::template getAxisT<axisN>::EdgeT>& newedges) {
289 if (newedges.size() < 2)
290 throw UserError("Requested rebinning to an edge list which defines no bins");
291 using thisAxisT = typename BinningT::template getAxisT<axisN>;
292 using thisEdgeT = typename thisAxisT::EdgeT;
293 // get list of shared edges
294 thisAxisT& oldAxis = BaseT::_binning.template axis<axisN>();
295 const thisAxisT newAxis(std::move(newedges));
296 const std::vector<thisEdgeT> eshared = oldAxis.sharedEdges(newAxis);
297 if (eshared.size() != newAxis.edges().size())
298 throw BinningError("Requested rebinning to incompatible edges");
299 // loop over new lower bin edges (= first bin index of merge range)
300 for (size_t begin = 0; begin < eshared.size() - 1; ++begin) {
301 // find index of upper edge along old axis
302 // (subtracting 1 gives index of last bin to be merged)
303 size_t end = oldAxis.index(eshared[begin+1]) - 1;
304 // if the current edge is the last visible edge before the overflow
305 // merge the remaining bins into the overflow
306 if (begin == newAxis.numBins(true)-1) end = oldAxis.numBins(true)-1;
307 // merge this range
308 if (end > begin) BaseT::template mergeBins<axisN>({begin, end});
309 if (eshared.size() == oldAxis.edges().size()) break; // we're done
310 }
311 }
312
314 template <size_t axisN>
315 void rebin(const std::vector<typename BinningT::template getAxisT<axisN>::EdgeT>& newedges) {
316 rebinTo<axisN>(std::move(newedges));
317 }
318
322 void reset() noexcept { BaseT::clearBins(); }
323
326 if (this != &est) {
329 }
330 return *this;
331 }
332
335 if (this != &est) {
337 BaseT::operator = (std::move(est));
338 }
339 return *this;
340 }
341
347 const std::string& pat_uncorr="^stat|^uncor" ) {
348 if (*this != est)
349 throw BinningError("Arithmetic operation requires compatible binning!");
350 if (AO::hasAnnotation("ScaledBy")) AO::rmAnnotation("ScaledBy");
351 for (size_t i = 0; i< BaseT::numBins(true, true); ++i) {
352 BaseT::bin(i).add(est.bin(i), pat_uncorr);
353 }
354 BaseT::maskBins(est.maskedBins(), true);
355 return *this;
356 }
357 //
359 return add(est);
360 }
361
367 const std::string& pat_uncorr="^stat|^uncor" ) {
368 if (*this != est)
369 throw BinningError("Arithmetic operation requires compatible binning!");
370 if (AO::hasAnnotation("ScaledBy")) AO::rmAnnotation("ScaledBy");
371 for (size_t i = 0; i< BaseT::numBins(true, true); ++i) {
372 BaseT::bin(i).add(std::move(est.bin(i)), pat_uncorr);
373 }
374 BaseT::maskBins(est.maskedBins(), true);
375 return *this;
376 }
377 //
379 return add(std::move(est));
380 }
381
382
388 const std::string& pat_uncorr="^stat|^uncor" ) {
389 if (*this != est)
390 throw BinningError("Arithmetic operation requires compatible binning!");
391 if (AO::hasAnnotation("ScaledBy")) AO::rmAnnotation("ScaledBy");
392 for (size_t i = 0; i< BaseT::numBins(true, true); ++i) {
393 BaseT::bin(i).subtract(est.bin(i), pat_uncorr);
394 }
395 BaseT::maskBins(est.maskedBins(), true);
396 return *this;
397 }
398 //
400 return subtract(est);
401 }
402
405 const std::string& pat_uncorr="^stat|^uncor" ) {
406 if (*this != est)
407 throw BinningError("Arithmetic operation requires compatible binning!");
408 if (AO::hasAnnotation("ScaledBy")) AO::rmAnnotation("ScaledBy");
409 for (size_t i = 0; i< BaseT::numBins(true, true); ++i) {
410 BaseT::bin(i) -= std::move(est.bin(i), pat_uncorr);
411 }
412 BaseT::maskBins(est.maskedBins(), true);
413 return *this;
414 }
415 //
417 return subtract(std::move(est));
418 }
419
421
422
425
427 size_t dim() const noexcept { return sizeof...(AxisT) + 1; }
428
430 std::string _config() const noexcept { return mkAxisConfig<AxisT...>(); }
431
436 template <size_t I, typename E = typename BinningT::template getEdgeT<I>>
437 std::vector<E> edges(const bool includeOverflows = false) const noexcept {
438 return BaseT::_binning.template edges<I>(includeOverflows);
439 }
440
447 template <size_t I, typename E = typename BinningT::template getEdgeT<I>>
448 std::enable_if_t<std::is_floating_point<E>::value, std::vector<E>>
449 widths(const bool includeOverflows = false) const noexcept {
450 return BaseT::_binning.template widths<I>(includeOverflows);
451 }
452
456 template <size_t I, typename E = typename BinningT::template getEdgeT<I>>
457 std::enable_if_t<std::is_floating_point<E>::value, E> min() const noexcept {
458 return BaseT::_binning.template min<I>();
459 }
460
464 template <size_t I, typename E = typename BinningT::template getEdgeT<I>>
465 std::enable_if_t<std::is_floating_point<E>::value, E> max() const noexcept {
466 return BaseT::_binning.template max<I>();
467 }
468
470
471
474
476 std::vector<double> vals(const bool includeOverflows=false,
477 const bool includeMaskedBins=false) const {
478 std::vector<double> rtn;
479 rtn.reserve(BaseT::numBins(includeOverflows, includeMaskedBins));
480 for (const auto& b : BaseT::bins(includeOverflows, includeMaskedBins)) {
481 rtn.push_back(b.val());
482 }
483 return rtn;
484 }
485
487 std::vector<std::string> sources() const {
488 // Assemble union of error sources, as it's not guaranteed
489 // that every bin has the same error breakdown
490 std::vector<std::string> rtn;
491
492 for (const auto& b : BaseT::bins(true)) {
493 std::vector<std::string> keys = b.sources();
494 rtn.insert(std::end(rtn),
495 std::make_move_iterator(std::begin(keys)),
496 std::make_move_iterator(std::end(keys)));
497 }
498 std::sort(rtn.begin(), rtn.end());
499 rtn.erase( std::unique(rtn.begin(), rtn.end()), rtn.end() );
500
501 return rtn;
502 }
503
507 double areaUnderCurve(const bool includeBinVol=true,
508 const bool includeOverflows=false,
509 const bool includeMaskedBins=false) const {
510 double ret = 0.;
511 for (const auto& b : BaseT::bins(includeOverflows, includeMaskedBins)) {
512 const double val = fabs(b.val());
513 const double vol = includeBinVol? b.dVol() : 1.0;
514 if (std::isfinite(vol)) ret += val*vol; // aggregate bin volume
515 }
516 return ret;
517 }
518
520 double auc(const bool includeBinVol=true,
521 const bool includeOverflows=false,
522 const bool includeMaskedBins=false) const {
523 return areaUnderCurve(includeBinVol, includeOverflows, includeMaskedBins);
524 }
525
526
527
529 std::vector<std::vector<double> > covarianceMatrix(const bool ignoreOffDiagonalTerms=false,
530 const bool includeOverflows=false,
531 const bool includeMaskedBins=false,
532 const std::string& pat_uncorr="^stat|^uncor") const {
533 const size_t nBins = BaseT::numBins(includeOverflows,includeMaskedBins);
534 std::vector<std::vector<double> > covM(nBins);
535
536 // initialise cov matrix to be the right shape
537 for (size_t i = 0; i < nBins; ++i) {
538 covM[i] = std::vector<double>(nBins, 0.0);
539 }
540
541 const std::vector<std::string> error_sources = sources();
542
543 // nominal-only case, i.e. total uncertainty, labelled as empty string
544 if (error_sources.size() == 1 && error_sources[0] == "") {
545 size_t i = 0;
546 for (const auto& b : BaseT::bins(includeOverflows,includeMaskedBins)) {
547 covM[i][i] = b.hasSource("")? sqr(0.5*(b.err("").first+b.err("").second)) : 1.0;
548 ++i;
549 }
550 return covM;
551 }
552
553 // more interesting case where we actually have some uncertainty breakdown!
554 std::smatch match;
555 const std::regex re(pat_uncorr, std::regex_constants::icase);
556 for (const std::string& sname : error_sources) {
557 if (sname == "") continue;
558 std::vector<double> systErrs(nBins, 0.0);
559 size_t k = 0;
560 for (const auto& b : BaseT::bins(includeOverflows,includeMaskedBins)) {
561 if (b.hasSource(sname)) {
562 const auto& errs = b.err(sname); // dn-up pair
563 systErrs[k] = 0.5 *( fabs(errs.first)+fabs(errs.second));
564 }
565 ++k;
566 }
567 const bool skipOffDiag = (ignoreOffDiagonalTerms
568 || std::regex_search(sname, match, re));
569 for (size_t i = 0; i < nBins; ++i) {
570 for (size_t j = 0; j < nBins; ++j) {
571 if (skipOffDiag && i != j) continue;
572 covM[i][j] += systErrs[i]*systErrs[j];
573 }
574 }
575 }
576
577 return covM;
578 }
579
581
584
586 auto mkScatter(const std::string& path="", const std::string& pat_match = "",
587 const bool includeOverflows=false,
588 const bool includeMaskedBins=false) const {
589
590 constexpr size_t N = sizeof...(AxisT);
591
592 ScatterND<N+1> rtn;
593 for (const std::string& a : annotations()) {
594 if (a != "Type") rtn.setAnnotation(a, annotation(a));
595 }
596 rtn.setAnnotation("Path", path);
597
598 const bool incOF = all_CAxes<AxisT...>::value && includeOverflows;
599 for (const auto& b : BaseT::bins(incOF, includeMaskedBins)) {
600
601 // Create the vector of coordinates
602 Utils::ndarray<double, N+1> vals;
603 // first fill bin centres, use bin index if axis non-arithmetic
604 auto indexIfDiscrete = [&vals, &b](auto I) {
605 using isContinuous = typename BinningT::template is_CAxis<I>;
606 using isArithmetic = typename BinningT::template is_Arithmetic<I>;
607 vals[I] = coordPicker<I>(b, std::integral_constant<bool, isArithmetic::value>{},
608 std::integral_constant<bool, isContinuous::value>{});
609 };
610 MetaUtils::staticFor<BinningT::Dimension::value>(indexIfDiscrete);
611 // then fill bin content
612 vals[N] = b.val();
613
614 // Create the vector of error pairs, use 0 if axis not continuous
615 Utils::ndarray<std::pair<double,double>, N+1> errs;
616 auto nullifyDiscrete = [&errs, &vals, &b](auto I) {
617 using isContinuous = typename BinningT::template is_CAxis<I>;
618 errs[I] = nullifyIfDisc<I>(b, vals[I], std::integral_constant<bool, isContinuous::value>{});
619 };
620 MetaUtils::staticFor<BinningT::Dimension::value>(nullifyDiscrete);
621 const double tot = fabs(b.totalErrPos(pat_match)); // use positive error component
622 errs[N] = { tot, tot };
623
624 // Add the PointND
625 rtn.addPoint( PointND<N+1>(vals, errs) );
626 }
627
628 // Decorate output scatter with the discrete edges
629 const BinningT& binning = BaseT::_binning;
630 auto decorateEdges = [&rtn, &binning](auto I) {
631 using isContinuous = typename BinningT::template is_CAxis<I>;
632 if constexpr( !isContinuous::value ) {
633 const auto& axis = binning.template axis<I>();
634 if (axis.numBins()) {
635 std::stringstream ss;
636 axis._renderYODA(ss);
637 rtn.setAnnotation("EdgesA" + std::to_string(I+1), ss.str());
638 }
639 }
640 };
641 MetaUtils::staticFor<BinningT::Dimension::value>(decorateEdges);
642
643 return rtn;
644 }
645
650 template<size_t axisN, typename = std::enable_if_t< (axisN < sizeof...(AxisT) && sizeof...(AxisT)>=2) >>
651 auto mkEstimates(const std::string& path="", const bool includeOverflows=false) const {
652
653 // Need to provide a prescription for how to add the two bin contents
654 auto how2add = [](auto& pivot, const BinType& toCopy) { pivot = toCopy; };
655 auto rtn = BaseT::template mkBinnedSlices<axisN, BinnedEstimate>(how2add, includeOverflows);
656 for (const std::string& a : annotations()) {
657 if (a == "Type") continue;
658 for (size_t i = 0; i < rtn.size(); ++i) {
659 rtn[i].setAnnotation(a, annotation(a));
660 }
661 }
662 for (size_t i = 0; i < rtn.size(); ++i) {
663 rtn[i].setAnnotation("Path", path);
664 }
665
666 return rtn;
667 }
668
669
671 AnalysisObject* mkInert(const std::string& path = "",
672 const std::string& source = "") const noexcept {
673 EstimateStorage* rtn = newclone();
674 rtn->setPath(path);
675 for (auto& b : rtn->bins(true, true)) {
676 if (b.numErrs() == 1) {
677 try {
678 b.renameSource("", source);
679 }
680 catch (YODA::UserError& e) { }
681 }
682 }
683 return rtn;
684 }
685
687
689
690
691 size_t lengthContent(bool fixed_length = false) const noexcept {
692 size_t rtn = 0;
693 for (const auto& bin : BaseT::bins(true, true)) {
694 rtn += bin._lengthContent(fixed_length);
695 }
696 return rtn;
697 }
698
699 std::vector<double> serializeContent(bool fixed_length = false) const noexcept {
700 std::vector<double> rtn;
701 const size_t nBins = BaseT::numBins(true, true);
702 rtn.reserve(nBins * 4);
703 for (size_t i = 0; i < nBins; ++i) {
704 const auto& b = BaseT::bin(i);
705 std::vector<double> bdata = b._serializeContent(fixed_length);
706 rtn.insert(std::end(rtn),
707 std::make_move_iterator(std::begin(bdata)),
708 std::make_move_iterator(std::end(bdata)));
709 }
710 return rtn;
711 }
712
713
714 void deserializeContent(const std::vector<double>& data) {
715
716 const size_t nBins = BaseT::numBins(true, true);
717 const size_t minLen = 2*nBins;
718 if (data.size() < minLen)
719 throw UserError("Length of serialized data should be at least " + std::to_string(minLen)+"!");
720
721 size_t i = 0;
722 auto itr = data.cbegin();
723 const auto itrEnd = data.cend();
724 const bool fixedLen = data.size() == 2*minLen;
725 while (itr != itrEnd) {
726 // for estimates, the first element represents the central,
727 // the subsequent value represents the number of error pairs
728 const size_t nErrs = fixedLen? 1 : (*(itr + 1) + 0.5); // add 0.5 to avoid rounding issues
729 auto last = itr + 2*(nErrs+1); // last element + 1
730 BaseT::bin(i)._deserializeContent(std::vector<double>{itr, last}, fixedLen);
731 // update for next iteration
732 itr = last;
733 ++i;
734 }
735 }
736
737 // @}
738
739 private:
740
743 template<size_t... Is>
744 BinningT _mkBinning(const std::vector<size_t>& nBins,
745 const std::vector<std::pair<double, double>>& limitsLowUp,
746 std::index_sequence<Is...>) const {
747 return BinningT({((void)Is, Axis<AxisT>(nBins[Is], limitsLowUp[Is].first, limitsLowUp[Is].second))...});
748 }
749
751 template<size_t... Is>
752 BinningT _mkBinning(const ScatterND<sizeof...(AxisT)+1>& s, std::index_sequence<Is...>) const {
753 return BinningT({((void)Is, Axis<AxisT>(s.edges(Is)))...});
754 }
755
756 };
757
758
759
761 template <typename... AxisT>
762 class BinnedEstimate : public EstimateStorage<AxisT...> {
763 public:
764 using EstimateT = BinnedEstimate<AxisT...>;
765 using BaseT = EstimateStorage<AxisT...>;
766 using BinType = typename BaseT::BinT;
767 using Ptr = std::shared_ptr<EstimateT>;
768
770 using BaseT::BaseT;
771
772 BinnedEstimate(const EstimateT&) = default;
776 using AnalysisObject::operator =;
777
781 BinnedEstimate(const BaseT& other) : BaseT(other) {}
782 //
783 BinnedEstimate(const EstimateT& other, const std::string& path) : BaseT(other, path) {}
784
786 BinnedEstimate(BaseT&& other) : BaseT(std::move(other)) {}
787 //
788 BinnedEstimate(EstimateT&& other, const std::string& path) : BaseT(std::move(other), path) {}
789
790 };
791
792
794 template <typename AxisT>
795 class BinnedEstimate<AxisT>
796 : public EstimateStorage<AxisT>,
797 public XAxisMixin<BinnedEstimate<AxisT>, AxisT> {
798 public:
801 using BinType = typename BaseT::BinT;
802 using Ptr = std::shared_ptr<EstimateT>;
803
805 using BaseT::BaseT;
806
807 BinnedEstimate(const EstimateT&) = default;
811 using AnalysisObject::operator =;
812
816 BinnedEstimate(const BaseT& other) : BaseT(other) {}
817 //
818 BinnedEstimate(const EstimateT& other, const std::string& path) : BaseT(other, path) {}
819
821 BinnedEstimate(BaseT&& other) : BaseT(std::move(other)) {}
822 //
823 BinnedEstimate(EstimateT&& other, const std::string& path) : BaseT(std::move(other), path) {}
824
825
826 BinnedEstimate(std::vector<AxisT>&& edges, const std::string& path="", const std::string& title="")
827 : BaseT(std::move(edges), path, title) {}
828
829 BinnedEstimate(const std::vector<AxisT>& edges, const std::string& path="", const std::string& title="")
830 : BaseT(edges, path, title) {}
831
838 template <typename EdgeT = double, typename = enable_if_all_CAxisT<EdgeT, AxisT>>
839 BinnedEstimate(size_t nbins, double lower, double upper, const std::string& path = "", const std::string& title = "")
840 : BaseT({nbins}, {{lower, upper}}, path, title) {}
841
843 EstimateT clone() const noexcept {
844 return EstimateT(*this);
845 }
846
848 EstimateT* newclone() const noexcept {
849 return new EstimateT(*this);
850 }
851
853 size_t indexAt(const AxisT xCoord) const noexcept {
854 return BaseT::binAt( {xCoord} ).index();
855 }
856
858 void maskBinAt(const AxisT xCoord, const bool status = true) noexcept {
859 return BaseT::maskBin({xCoord}, status);
860 }
861
862 };
863
864
865
867 template <typename AxisT1, typename AxisT2>
868 class BinnedEstimate<AxisT1, AxisT2>
869 : public EstimateStorage<AxisT1, AxisT2>,
870 public XAxisMixin<BinnedEstimate<AxisT1, AxisT2>, AxisT1>,
871 public YAxisMixin<BinnedEstimate<AxisT1, AxisT2>, AxisT2> {
872 public:
875 using BinType = typename BaseT::BinT;
876 using Ptr = std::shared_ptr<EstimateT>;
877
879 using BaseT::BaseT;
880
881 BinnedEstimate(const EstimateT&) = default;
885 using AnalysisObject::operator =;
886
890 BinnedEstimate(const BaseT& other) : BaseT(std::move(other)) {}
891 //
892 BinnedEstimate(const EstimateT& other, const std::string& path) : BaseT(other, path) {}
893
895 BinnedEstimate(BaseT&& other) : BaseT(std::move(other)) {}
896 //
897 BinnedEstimate(EstimateT&& other, const std::string& path) : BaseT(std::move(other), path) {}
898
899 BinnedEstimate(std::vector<AxisT1>&& xEdges, std::vector<AxisT2>&& yEdges,
900 const std::string& path="", const std::string& title="")
901 : BaseT(std::move(xEdges), std::move(yEdges), path, title) {}
902
903 BinnedEstimate(const std::vector<AxisT1>& xEdges, const std::vector<AxisT2>& yEdges,
904 const std::string& path="", const std::string& title="")
905 : BaseT(xEdges, yEdges, path, title) {}
906
913 template <typename EdgeT = double, typename = enable_if_all_CAxisT<EdgeT, AxisT1, AxisT2>>
914 BinnedEstimate(size_t nbinsX, double lowerX, double upperX,
915 size_t nbinsY, double lowerY, double upperY,
916 const std::string& path = "", const std::string& title = "")
917 : BaseT({nbinsX, nbinsY}, {{lowerX, upperX}, {lowerY, upperY}}, path, title) {}
918
920 EstimateT clone() const noexcept {
921 return EstimateT(*this);
922 }
923
925 EstimateT* newclone() const noexcept {
926 return new EstimateT(*this);
927 }
928
930 BinType& bin(const size_t index) noexcept {
931 return BaseT::bin(index);
932 }
933
935 const BinType& bin(const size_t index) const noexcept {
936 return BaseT::bin(index);
937 }
938
940 BinType& bin(const size_t localX, const size_t localY) noexcept {
941 return BaseT::bin( {localX, localY} );
942 }
943
945 const BinType& bin(const size_t localX, const size_t localY) const noexcept {
946 return BaseT::bin( {localX, localY} );
947 }
948
950 BinType& binAt(const AxisT1 xCoord, const AxisT2 yCoord) noexcept {
951 return BaseT::binAt( {xCoord, yCoord} );
952 }
953
955 const BinType& binAt(const AxisT1 xCoord, const AxisT2 yCoord) const noexcept {
956 return BaseT::binAt( {xCoord, yCoord} );
957 }
958
960 size_t indexAt(const AxisT1 xCoord, const AxisT2 yCoord) const noexcept {
961 return BaseT::binAt( {xCoord, yCoord} ).index();
962 }
963
965 void maskBinAt(const AxisT1 xCoord, const AxisT2 yCoord, const bool status = true) noexcept {
966 return BaseT::maskBin({xCoord, yCoord}, status);
967 }
968
969 };
970
971
973 template <typename AxisT1, typename AxisT2, typename AxisT3>
974 class BinnedEstimate<AxisT1, AxisT2, AxisT3>
975 : public EstimateStorage<AxisT1, AxisT2, AxisT3>,
976 public XAxisMixin<BinnedEstimate<AxisT1, AxisT2, AxisT3>, AxisT1>,
977 public YAxisMixin<BinnedEstimate<AxisT1, AxisT2, AxisT3>, AxisT2>,
978 public ZAxisMixin<BinnedEstimate<AxisT1, AxisT2, AxisT3>, AxisT3> {
979 public:
982 using BinType = typename BaseT::BinT;
983 using Ptr = std::shared_ptr<EstimateT>;
984
986 using BaseT::BaseT;
987
988 BinnedEstimate(const EstimateT&) = default;
992 using AnalysisObject::operator =;
993
997 BinnedEstimate(const BaseT& other) : BaseT(other) {}
998 //
999 BinnedEstimate(const EstimateT& other, const std::string& path) : BaseT(other, path) {}
1000
1002 BinnedEstimate(BaseT&& other) : BaseT(std::move(other)) {}
1003 //
1004 BinnedEstimate(EstimateT&& other, const std::string& path) : BaseT(std::move(other), path) {}
1005
1012 template <typename EdgeT = double, typename = enable_if_all_CAxisT<EdgeT, AxisT1, AxisT2, AxisT3>>
1013 BinnedEstimate(size_t nbinsX, double lowerX, double upperX,
1014 size_t nbinsY, double lowerY, double upperY,
1015 size_t nbinsZ, double lowerZ, double upperZ,
1016 const std::string& path = "", const std::string& title = "")
1017 : BaseT({nbinsX, nbinsY, nbinsZ}, {{lowerX, upperX}, {lowerY, upperY},
1018 {lowerZ, upperZ}}, path, title) {}
1019
1021 EstimateT clone() const noexcept {
1022 return EstimateT(*this);
1023 }
1024
1026 EstimateT* newclone() const noexcept {
1027 return new EstimateT(*this);
1028 }
1029
1031 BinType& bin(const size_t index) noexcept {
1032 return BaseT::bin(index);
1033 }
1034
1036 const BinType& bin(const size_t index) const noexcept {
1037 return BaseT::bin(index);
1038 }
1039
1041 BinType& bin(const size_t localX, const size_t localY, const size_t localZ) noexcept {
1042 return BaseT::bin( {localX, localY, localZ} );
1043 }
1044
1046 const BinType& bin(const size_t localX, const size_t localY, const size_t localZ) const noexcept {
1047 return BaseT::bin( {localX, localY, localZ} );
1048 }
1049
1051 BinType& binAt(const AxisT1 xCoord, const AxisT2 yCoord, const AxisT3 zCoord) noexcept {
1052 return BaseT::binAt( {xCoord, yCoord, zCoord} );
1053 }
1054
1056 const BinType& binAt(const AxisT1 xCoord, const AxisT2 yCoord, const AxisT3 zCoord) const noexcept {
1057 return BaseT::binAt( {xCoord, yCoord, zCoord} );
1058 }
1059
1061 size_t indexAt(const AxisT1 xCoord, const AxisT2 yCoord, const AxisT3 zCoord) const noexcept {
1062 return BaseT::binAt( {xCoord, yCoord, zCoord} ).index();
1063 }
1064
1066 void maskBinAt(const AxisT1 xCoord, const AxisT2 yCoord, const AxisT3 zCoord, const bool status = true) noexcept {
1067 return BaseT::maskBin({xCoord, yCoord, zCoord}, status);
1068 }
1069
1070 };
1071
1074
1076 template <typename... AxisT>
1077 inline BinnedEstimate<AxisT...>
1079 first += second;
1080 return first;
1081 }
1082
1083
1085 template <typename... AxisT>
1086 inline BinnedEstimate<AxisT...>
1088 first += std::move(second);
1089 return first;
1090 }
1091
1092
1094 template <typename... AxisT>
1095 inline BinnedEstimate< AxisT...>
1097 first -= second;
1098 return first;
1099 }
1100
1102 template <typename... AxisT>
1103 inline BinnedEstimate< AxisT...>
1105 first -= std::move(second);
1106 return first;
1107 }
1108
1110 template <typename... AxisT>
1111 inline BinnedEstimate<AxisT...>
1113 const std::string& pat_uncorr="^stat|^uncor" ) {
1114 if (numer != denom) {
1115 throw BinningError("Arithmetic operation requires compatible binning!");
1116 }
1117
1118 BinnedEstimate<AxisT...> rtn(numer.binning());
1119 if (numer.path() == denom.path()) rtn.setPath(numer.path());
1120 if (rtn.hasAnnotation("ScaledBy")) rtn.rmAnnotation("ScaledBy");
1121
1122 for (const auto& b_num : numer.bins(true, true)) {
1123 const size_t idx = b_num.index();
1124 rtn.bin(idx) = divide(b_num, denom.bin(idx), pat_uncorr);
1125 }
1126 rtn.maskBins(denom.maskedBins(), true);
1127
1128 return rtn;
1129 }
1130
1132 template <typename... AxisT>
1133 inline BinnedEstimate<AxisT...>
1135 return divide(numer, denom);
1136 }
1137
1139 template <typename... AxisT>
1140 inline BinnedEstimate<AxisT...>
1142 return divide(std::move(numer), denom);
1143 }
1144
1146 template <typename... AxisT>
1147 inline BinnedEstimate<AxisT...>
1149 return divide(numer, std::move(denom));
1150 }
1151
1153 template <typename... AxisT>
1154 inline BinnedEstimate<AxisT...>
1156 return divide(std::move(numer), std::move(denom));
1157 }
1158
1159
1164 template <typename... AxisT>
1165 inline BinnedEstimate<AxisT...>
1167 const std::string& pat_uncorr="^stat|^uncor" ) {
1168
1169 if (accepted != total) {
1170 throw BinningError("Arithmetic operation requires compatible binning!");
1171 }
1172
1173 BinnedEstimate<AxisT...> rtn(accepted.binning());
1174
1175 for (const auto& b_acc : accepted.bins(true, true)) {
1176 Estimate est;
1177 const size_t idx = b_acc.index();
1178 try {
1179 est = efficiency(b_acc, total.bin(idx), pat_uncorr);
1180 } catch (const UserError& e) {
1181 //
1182 }
1183 rtn.bin(idx).set(est);
1184 }
1185 return rtn;
1186 }
1187
1188
1190 template <typename... AxisT>
1191 inline BinnedEstimate<AxisT...>
1193 const BinnedEstimate<AxisT...>& b,
1194 const std::string& pat_uncorr="^stat|^uncor" ) {
1195 return divde(subtract(a-b, pat_uncorr), add(a+b, pat_uncorr), pat_uncorr);
1196 }
1197
1198
1200
1201
1204
1205 template <typename... AxisT>
1206 inline void transform(BinnedEstimate<AxisT...>& est, const Trf<1>& fn) {
1207 for (auto& b : est.bins(true, true)) {
1208 b.transform(fn);
1209 }
1210 }
1211
1212 template <typename... AxisT, typename FN>
1213 inline void transform(BinnedEstimate<AxisT...>& est, const FN& fn) {
1214 transform(est, Trf<1>(fn));
1215 }
1216
1218
1219
1222
1224 template<typename A1>
1226
1227 template <typename A1, typename A2>
1229
1230 template <typename A1, typename A2, typename A3>
1232
1234 namespace {
1235 template <class T>
1236 struct EstimateMaker;
1237
1238 template<size_t... Is>
1239 struct EstimateMaker<std::index_sequence<Is...>> {
1241 };
1242 }
1243
1244 template<size_t N>
1245 using EstimateND = typename EstimateMaker<std::make_index_sequence<N>>::type;
1246
1247
1248 // User-friendly names (continuous axes only)
1252
1254
1255}
1256
1257#endif
AnalysisObject is the base class for histograms and scatters.
virtual AnalysisObject & operator=(const AnalysisObject &ao) noexcept
Default copy assignment operator.
void setAnnotation(const std::string &name, const T &value)
Add or set an annotation by name (templated for remaining types)
void setPath(const std::string &path)
const std::string title() const
Get the AO title.
std::vector< std::string > annotations() const
const std::string path() const
Get the AO path.
void rmAnnotation(const std::string &name)
Delete an annotation by name.
const std::string & annotation(const std::string &name) const
Get an annotation by name (as a string)
bool hasAnnotation(const std::string &name) const
Check if an annotation is defined.
AnalysisObject()
Default constructor.
Discrete axis with edges of non-floating-point-type.
Definition BinnedAxis.h:91
Specialisation of the BinnedEstimate for a 3D BinnedEstimate.
BinType & binAt(const AxisT1 xCoord, const AxisT2 yCoord, const AxisT3 zCoord) noexcept
Bin access using coordinates.
const BinType & bin(const size_t index) const noexcept
Bin access using global index (const version)
BinnedEstimate(const EstimateT &other, const std::string &path)
EstimateT clone() const noexcept
Make a copy on the stack.
BinType & bin(const size_t index) noexcept
Bin access using global index.
void maskBinAt(const AxisT1 xCoord, const AxisT2 yCoord, const AxisT3 zCoord, const bool status=true) noexcept
Mask/Unmask bin at given set of coordinates.
EstimateT * newclone() const noexcept
Make a copy on the heap.
BinnedEstimate(size_t nbinsX, double lowerX, double upperX, size_t nbinsY, double lowerY, double upperY, size_t nbinsZ, double lowerZ, double upperZ, const std::string &path="", const std::string &title="")
Constructor with auto-setup of evenly spaced axes.
const BinType & bin(const size_t localX, const size_t localY, const size_t localZ) const noexcept
Bin access using local indices.
BinnedEstimate(const BaseT &other)
Copy constructor (needed for clone functions).
const BinType & binAt(const AxisT1 xCoord, const AxisT2 yCoord, const AxisT3 zCoord) const noexcept
Bin access using coordinates (const version)
BinnedEstimate(EstimateT &&other, const std::string &path)
size_t indexAt(const AxisT1 xCoord, const AxisT2 yCoord, const AxisT3 zCoord) const noexcept
Find bin index for given coordinates.
BinType & bin(const size_t localX, const size_t localY, const size_t localZ) noexcept
Bin access using local indices.
BinnedEstimate(BaseT &&other)
Move constructor.
Specialisation of the BinnedEstimate for a 2D BinnedEstimate.
BinType & bin(const size_t index) noexcept
Bin access using global index.
BinType & bin(const size_t localX, const size_t localY) noexcept
Bin access using local indices.
BinnedEstimate(EstimateT &&other, const std::string &path)
const BinType & binAt(const AxisT1 xCoord, const AxisT2 yCoord) const noexcept
Bin access using coordinates (const version)
EstimateT clone() const noexcept
Make a copy on the stack.
BinnedEstimate(const EstimateT &other, const std::string &path)
BinnedEstimate(EstimateT &&)=default
BinnedEstimate(const BaseT &other)
Copy constructor (needed for clone functions).
const BinType & bin(const size_t index) const noexcept
Bin access using global index (const version)
BinnedEstimate(const std::vector< AxisT1 > &xEdges, const std::vector< AxisT2 > &yEdges, const std::string &path="", const std::string &title="")
std::shared_ptr< EstimateT > Ptr
BinType & binAt(const AxisT1 xCoord, const AxisT2 yCoord) noexcept
Bin access using coordinates.
BinnedEstimate(BaseT &&other)
Move constructor.
size_t indexAt(const AxisT1 xCoord, const AxisT2 yCoord) const noexcept
Find bin index for given coordinates.
BinnedEstimate(const EstimateT &)=default
BinnedEstimate(std::vector< AxisT1 > &&xEdges, std::vector< AxisT2 > &&yEdges, const std::string &path="", const std::string &title="")
const BinType & bin(const size_t localX, const size_t localY) const noexcept
Bin access using local indices (const version)
EstimateT * newclone() const noexcept
Make a copy on the heap.
void maskBinAt(const AxisT1 xCoord, const AxisT2 yCoord, const bool status=true) noexcept
Mask/Unmask bin at given set of coordinates.
BinnedEstimate(size_t nbinsX, double lowerX, double upperX, size_t nbinsY, double lowerY, double upperY, const std::string &path="", const std::string &title="")
Constructor with auto-setup of evenly spaced axes.
Specialisation of the BinnedEstimate for a 1D histogram.
typename BaseT::BinT BinType
BinnedEstimate(EstimateT &&)=default
EstimateT * newclone() const noexcept
Make a copy on the heap.
size_t indexAt(const AxisT xCoord) const noexcept
Find bin index for given coordinates.
BinnedEstimate(BaseT &&other)
Move constructor.
BinnedEstimate(const BaseT &other)
Copy constructor (needed for clone functions).
EstimateT clone() const noexcept
Make a copy on the stack.
BinnedEstimate(std::vector< AxisT > &&edges, const std::string &path="", const std::string &title="")
BinnedEstimate(const std::vector< AxisT > &edges, const std::string &path="", const std::string &title="")
void maskBinAt(const AxisT xCoord, const bool status=true) noexcept
Mask/Unmask bin at given set of coordinates.
BinnedEstimate(size_t nbins, double lower, double upper, const std::string &path="", const std::string &title="")
Constructor with auto-setup of evenly spaced axes.
BinnedEstimate(const EstimateT &)=default
BinnedEstimate(const EstimateT &other, const std::string &path)
BinnedEstimate(EstimateT &&other, const std::string &path)
std::shared_ptr< EstimateT > Ptr
Forward declaration.
typename BaseT::BinT BinType
BinnedEstimate(EstimateT &&)=default
BinnedEstimate(BaseT &&other)
Move constructor.
BinnedEstimate(const BaseT &other)
Copy constructor (needed for clone functions).
BinnedEstimate< AxisT... > EstimateT
BinnedEstimate & operator=(const EstimateT &)=default
BinnedEstimate(const EstimateT &)=default
BinnedEstimate(const EstimateT &other, const std::string &path)
BinnedEstimate(EstimateT &&other, const std::string &path)
std::shared_ptr< EstimateT > Ptr
BinnedStorage, stores the bins and coordinates access to them.
void maskBin(const size_t indexToMask, const bool status=true) noexcept
Mask a bin at a given index.
BinT & bin(size_t idx) noexcept
Returns reference to the bin at idx.
void maskBins(const std::vector< size_t > &indicesToMask, const bool status=true) noexcept
Mask a range of bins.
size_t numBinsAt(const size_t axisN, const bool includeOverflows=false) const noexcept
Number of bins in the BinnedStorage.
size_t numBins(const bool includeOverflows=false, const bool includeMaskedBins=false) const noexcept
Number of bins in the BinnedStorage.
Binning< std::decay_t< decltype(std::declval< Axis< AxisT > >())>... > BinningT
Convenience alias to be used in constructor.
BinnedStorage & operator=(const BinnedStorage &other) noexcept
Copy assignment.
Bin< sizeof...(AxisT), Estimate, BinningT > BinT
void clearBins() noexcept
Deletes all bins and creates empty new ones.
BinsVecWrapper< BinsVecT > bins(const bool includeOverflows=false, const bool includeMaskedBins=false) noexcept
Returns bins vector wrapper, which skips masked elements when iterated over.
const BinningT & binning() const noexcept
Returns dimension underlying binning object reference.
std::vector< size_t > maskedBins() const noexcept
BinT & binAt(typename BinningT::EdgeTypesTuple &&coords) noexcept
Returns reference to the bin at coordinates.
Error for general binning problems.
Definition Exceptions.h:27
EstimateStorage convenience class based on BinnedStorage.
void scale(const double scalefactor) noexcept
Rescale as if all fill weights had been different by factor scalefactor.
std::enable_if_t< std::is_floating_point< E >::value, E > min() const noexcept
Get the lowest non-overflow edge of the axis.
std::vector< double > vals(const bool includeOverflows=false, const bool includeMaskedBins=false) const
Get list of central values.
EstimateStorage & operator+=(const EstimateStorage &est)
typename BaseT::BinT BinT
std::vector< double > serializeContent(bool fixed_length=false) const noexcept
Content serialisation for MPI reduce operations.
EstimateStorage(EstimateStorage &&other, const std::string &path="")
Move constructor.
EstimateStorage(const std::string &path="", const std::string &title="")
Nullary constructor for unique pointers etc.
void rebinTo(const std::vector< typename BinningT::template getAxisT< axisN >::EdgeT > &newedges)
Rebin to the given list of bin edges.
EstimateStorage(std::vector< AxisT > &&... binsEdges, const std::string &path="", const std::string &title="")
Constructor giving explicit bin edges as rvalue reference.
EstimateStorage & add(const EstimateStorage &est, const std::string &pat_uncorr="^stat|^uncor")
Add two EstimateStorages.
EstimateStorage & add(EstimateStorage &&est, const std::string &pat_uncorr="^stat|^uncor")
Add two (rvalue) EstimateStorages.
auto mkScatter(const std::string &path="", const std::string &pat_match="", const bool includeOverflows=false, const bool includeMaskedBins=false) const
Produce a ScatterND from a EstimateStorage.
EstimateStorage & operator-=(const EstimateStorage &est)
double auc(const bool includeBinVol=true, const bool includeOverflows=false, const bool includeMaskedBins=false) const
Convenient alias for areaUnderCurve()
EstimateStorage * newclone() const noexcept
Make a copy on the heap.
EstimateStorage(std::initializer_list< AxisT > &&... binsEdges, const std::string &path="", const std::string &title="")
Constructor giving explicit bin edges as initializer list.
EstimateStorage(const std::vector< size_t > &nBins, const std::vector< std::pair< EdgeT, EdgeT > > &limitsLowUp, const std::string &path="", const std::string &title="")
Constructor giving range and number of bins.
void reset() noexcept
Reset the EstimateStorage.
EstimateStorage(const ScatterND< sizeof...(AxisT)+1 > &s, const std::string &path="", const std::string &title="")
Constructor given a scatter.
AnalysisObject * mkInert(const std::string &path="", const std::string &source="") const noexcept
Method returns clone of the estimate with streamlined error source.
void rebin(unsigned int n, size_t begin=1, size_t end=UINT_MAX)
Overloaded alias for rebinBy.
void rebinBy(unsigned int n, size_t begin=1, size_t end=UINT_MAX)
Merge every group of n bins, from start to end inclusive.
double areaUnderCurve(const bool includeBinVol=true, const bool includeOverflows=false, const bool includeMaskedBins=false) const
Calculate the volume underneath the EstimateStorage.
void rebin(const std::vector< typename BinningT::template getAxisT< axisN >::EdgeT > &newedges)
Overloaded alias for rebinTo.
EstimateStorage(const std::vector< AxisT > &... binsEdges, const std::string &path="", const std::string &title="")
Constructor giving explicit bin edges as lvalue reference.
std::vector< std::vector< double > > covarianceMatrix(const bool ignoreOffDiagonalTerms=false, const bool includeOverflows=false, const bool includeMaskedBins=false, const std::string &pat_uncorr="^stat|^uncor") const
Construct a covariance matrix from the error breakdown.
EstimateStorage(const EstimateStorage &other, const std::string &path="")
Copy constructor.
EstimateStorage clone() const noexcept
Make a copy on the stack.
EstimateStorage & subtract(EstimateStorage &&est, const std::string &pat_uncorr="^stat|^uncor")
Subtract one (rvalue) EstimateStorages from another one.
std::enable_if_t< std::is_floating_point< E >::value, E > max() const noexcept
Get the highest non-overflow edge of the axis.
EstimateStorage(BinningT &&binning, const std::string &path="", const std::string &title="")
Constructor given an rvalue BinningT.
EstimateStorage & subtract(const EstimateStorage &est, const std::string &pat_uncorr="^stat|^uncor")
Subtract one EstimateStorages from another one.
EstimateStorage & operator=(const EstimateStorage &est) noexcept
Copy assignment.
size_t dim() const noexcept
Total dimension of the object (number of axes + estimate)
auto mkEstimates(const std::string &path="", const bool includeOverflows=false) const
Split into vector of BinnedEstimates along axisN.
std::vector< std::string > sources() const
Get list of error sources.
BinnedStorage< Estimate, AxisT... > BaseT
std::vector< E > edges(const bool includeOverflows=false) const noexcept
Templated version to get edges of axis N by value. +-inf edges are included.
size_t lengthContent(bool fixed_length=false) const noexcept
Length of serialized content vector for MPI reduce operations.
typename BaseT::BinningT BinningT
EstimateStorage(const BinningT &binning, const std::string &path="", const std::string &title="")
Constructor given a binning type.
std::enable_if_t< std::is_floating_point< E >::value, std::vector< E > > widths(const bool includeOverflows=false) const noexcept
Templated version to get bin widths of axis N by value.
void deserializeContent(const std::vector< double > &data)
Content deserialisation for MPI reduce operations.
A point estimate (base class for the Estimate)
Definition Estimate.h:29
A generic data type which is just a collection of n-dim data points with errors.
Definition Scatter.h:154
ScatterND< N > & addPoint(const PointND< N > &pt)
Insert a new point.
Definition Scatter.h:379
Error for problems introduced outside YODA, to put it nicely.
Definition Exceptions.h:100
Anonymous namespace to limit visibility.
std::string mkTypeString()
Helper function to construct the BinnedDbn and BinnedEstimate type names.
void transform(BinnedEstimate< AxisT... > &est, const Trf< 1 > &fn)
std::enable_if_t< all_CAxes< EdgeT... >::value > enable_if_all_CAxisT
Checks if all edge types are continuous.
std::string mkAxisConfig()
Helper function to construct the axis config.
typename std::conjunction< std::is_floating_point< EdgeT >... > all_CAxes
BinnedDbn< DbnN, AxisT... > operator+(BinnedDbn< DbnN, AxisT... > first, BinnedDbn< DbnN, AxisT... > &&second)
Add two BinnedDbn objects.
Definition BinnedDbn.h:1060
BinnedEstimate< AxisT... > operator/(const BinnedDbn< DbnN, AxisT... > &numer, const BinnedDbn< DbnN, AxisT... > &denom)
Definition BinnedDbn.h:1133
NUM sqr(NUM a)
Named number-type squaring operation.
Definition MathUtils.h:216
BinnedEstimate< AxisT... > efficiency(const BinnedDbn< DbnN, AxisT... > &accepted, const BinnedDbn< DbnN, AxisT... > &total)
Calculate a binned efficiency ratio of two BinnedDbn objects.
Definition BinnedDbn.h:1162
typename EstimateMaker< std::make_index_sequence< N > >::type EstimateND
BinnedEstimate< AxisT... > asymm(const BinnedDbn< DbnN, AxisT... > &a, const BinnedDbn< DbnN, AxisT... > &b)
Calculate the asymmetry (a-b)/(a+b) of two BinnedDbn objects.
Definition BinnedDbn.h:1201
BinnedEstimate< AxisT... > add(const BinnedDbn< DbnN, AxisT... > &dbn, const BinnedEstimate< AxisT... > &est)
Calculate the addition of a BinnedDbn with a BinnedEstimate.
Definition BinnedDbn.h:1270
BinnedEstimate< AxisT... > subtract(const BinnedDbn< DbnN, AxisT... > &dbn, const BinnedEstimate< AxisT... > &est)
Calculate the subtraction of a BinnedEstimate from a BinnedDbn.
Definition BinnedDbn.h:1302
BinnedDbn< DbnN, AxisT... > operator-(BinnedDbn< DbnN, AxisT... > first, BinnedDbn< DbnN, AxisT... > &&second)
Subtract one BinnedDbn object from another.
Definition BinnedDbn.h:1076
BinnedEstimate< AxisT... > divide(const BinnedDbn< DbnN, AxisT... > &numer, const BinnedDbn< DbnN, AxisT... > &denom)
Divide two BinnedDbn objects.
Definition BinnedDbn.h:1092
CRTP mixin introducing convenience aliases along X axis.
Definition BinnedUtils.h:18
CRTP mixin introducing convenience aliases along Y axis.
CRTP mixin introducing convenience aliases along Z axis.