yoda is hosted by Hepforge, IPPP Durham
YODA - Yet more Objects for Data Analysis 2.0.3
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 public:
79
80 using BaseT = BinnedStorage<Estimate, AxisT...>;
81 using BinningT = typename BaseT::BinningT;
82 using BinT = typename BaseT::BinT;
83 using BinType = BinT;
84 using AnalysisObject::operator =;
85
88
90 EstimateStorage(const std::string& path = "", const std::string& title = "")
91 : BaseT(), AnalysisObject(mkTypeString<AxisT...>(), path, title) { }
92
98 EstimateStorage(std::vector<AxisT>&&... binsEdges, const std::string& path = "", const std::string& title = "")
99 : BaseT(Axis<AxisT>(std::move(binsEdges))...), AnalysisObject(mkTypeString<AxisT...>(), path, title) { }
100
106 EstimateStorage(const std::vector<AxisT>&... binsEdges, const std::string& path = "", const std::string& title = "")
107 : BaseT(Axis<AxisT>(binsEdges)...), AnalysisObject(mkTypeString<AxisT...>(), path, title) { }
108
114 EstimateStorage(std::initializer_list<AxisT>&&... binsEdges, const std::string& path = "", const std::string& title = "")
115 : BaseT(Axis<AxisT>(std::move(binsEdges))...), AnalysisObject(mkTypeString<AxisT...>(), path, title) { }
116
118 template <typename EdgeT = double, typename = enable_if_all_CAxisT<EdgeT, AxisT...>>
119 EstimateStorage(const std::vector<size_t>& nBins,
120 const std::vector<std::pair<EdgeT, EdgeT>>& limitsLowUp,
121 const std::string& path = "", const std::string& title = "")
122 //: BaseT( BinningT(nBins, limitsLowUp, std::make_index_sequence<sizeof...(AxisT)>{}) ),
123 : BaseT( _mkBinning(nBins, limitsLowUp, std::make_index_sequence<sizeof...(AxisT)>{}) ),
124 AnalysisObject(mkTypeString<AxisT...>(), path, title) { }
125
127 EstimateStorage(const BinningT& binning, const std::string& path = "", const std::string& title = "")
128 : BaseT(binning), AnalysisObject(mkTypeString<AxisT...>(), path, title) { }
129
131 EstimateStorage(BinningT&& binning, const std::string& path = "", const std::string& title = "")
132 : BaseT(std::move(binning)), AnalysisObject(mkTypeString<AxisT...>(), path, title) { }
133
135 template <typename EdgeT = double, typename = enable_if_all_CAxisT<EdgeT, AxisT...>>
136 EstimateStorage(const ScatterND<sizeof...(AxisT)+1>& s, const std::string& path = "", const std::string& title = "")
137 : BaseT(_mkBinning(s, std::make_index_sequence<sizeof...(AxisT)>{})),
138 AnalysisObject(mkTypeString<AxisT...>(), path, title) { }
139
143 EstimateStorage(const EstimateStorage& other, const std::string& path = "") : BaseT(other),
144 AnalysisObject(mkTypeString<AxisT...>(), path!=""? path : other.path(), other, other.title()) { }
145
149 EstimateStorage(EstimateStorage&& other, const std::string& path = "") : BaseT(std::move(other)),
150 AnalysisObject(mkTypeString<AxisT...>(), path!=""? path : other.path(), other, other.title()) { }
151
153 EstimateStorage clone() const noexcept {
154 return EstimateStorage(*this);
155 }
156
158 EstimateStorage* newclone() const noexcept {
159 return new EstimateStorage(*this);
160 }
161
163
164
167
168 private:
169
170 // @brief Render information about this AO (private implementation)
171 template<size_t... Is>
172 void _renderYODA_aux(std::ostream& os, const int width, std::index_sequence<Is...>) const noexcept {
173
174 // print bin edges
175 BaseT::_binning._renderYODA(os);
176
177 // Assemble union of error sources, as it's not guaranteed
178 // that every bin has the same error breakdown
179 const std::vector<std::string> labels = this->sources();
180 if (labels.size()) {
181 os << "ErrorLabels: [";
182 for (size_t i = 0; i < labels.size(); ++i) {
183 const std::string& src = labels[i];
184 if (i) os << ", ";
185 os << std::quoted(src);
186 }
187 os << "]\n";
188 }
189
190 // column header: content types
191 os << std::setw(width) << std::left << "# value" << "\t";
192 const int errwidth = std::max(int(std::to_string(labels.size()).size()+7), width); // "errDn(" + src + ")"
193 for (size_t i = 0; i < labels.size(); ++i) {
194 const std::string& src = labels[i];
195 if (src.empty()) {
196 os << std::setw(errwidth) << std::left << "totalDn" << "\t"
197 << std::setw(errwidth) << std::left << "totalUp" << "\t";
198 }
199 else {
200 os << std::setw(errwidth) << std::left << ("errDn(" + std::to_string(i+1) + ")") << "\t"
201 << std::setw(errwidth) << std::left << ("errUp(" + std::to_string(i+1) + ")") << "\t";
202 }
203 }
204 os << "\n";
205
206 for (const auto& b : BaseT::bins(true, true)) {
207 os << std::setw(width) << std::left << b.val() << "\t"; // print value
208 // print systs if available
209 for (const std::string& src : labels) {
210 if (!b.hasSource(src)) {
211 os << std::setw(errwidth) << std::left << "---" << "\t"
212 << std::setw(errwidth) << std::left << "---" << "\t";
213 continue;
214 }
215 const auto& err = b.err(src);
216 os << std::setw(errwidth) << std::left << err.first << "\t"
217 << std::setw(errwidth) << std::left << err.second << "\t";
218 }
219 os << "\n";
220 }
221 }
222
223 public:
224
227
228 // @brief Render information about this AO
229 void _renderYODA(std::ostream& os, const int width = 13) const noexcept {
230 _renderYODA_aux(os, width, std::make_index_sequence<sizeof...(AxisT)>{});
231 }
232
233 // @brief Render scatter-like information about this AO
234 void _renderFLAT(std::ostream& os, const int width = 13) const noexcept {
235 const ScatterND<sizeof...(AxisT)+1> tmp = mkScatter();
236 tmp._renderYODA(os, width);
237 }
238
240
241
244
246 void scale(const double scalefactor) noexcept {
247 setAnnotation("ScaledBy", annotation<double>("ScaledBy", 1.0) * scalefactor);
248 for (auto& bin : BaseT::_bins) {
249 bin.scale(scalefactor);
250 }
251 }
252
253
262 template <size_t axisN>
263 void rebinBy(unsigned int n, size_t begin=1, size_t end=UINT_MAX) {
264 if (n < 1) throw UserError("Rebinning requested in groups of 0!");
265 if (!begin) throw UserError("Visible bins start with index 1!");
266 if (end > BaseT::numBinsAt(axisN)+1) end = BaseT::numBinsAt(axisN) + 1;
267 for (size_t m = begin; m < end; ++m) {
268 if (m > BaseT::numBinsAt(axisN)+1) break; // nothing to be done
269 const size_t myend = (m+n-1 < BaseT::numBinsAt(axisN)+1) ? m+n-1 : BaseT::numBinsAt(axisN);
270 if (myend > m) {
271 BaseT::template mergeBins<axisN>({m, myend});
272 end -= myend-m; //< reduce upper index by the number of removed bins
273 }
274 }
275 }
276
278 template <size_t axisN>
279 void rebin(unsigned int n, size_t begin=1, size_t end=UINT_MAX) {
280 rebinBy<axisN>(n, begin, end);
281 }
282
284 template <size_t axisN>
285 void rebinTo(const std::vector<typename BinningT::template getAxisT<axisN>::EdgeT>& newedges) {
286 if (newedges.size() < 2)
287 throw UserError("Requested rebinning to an edge list which defines no bins");
288 using thisAxisT = typename BinningT::template getAxisT<axisN>;
289 using thisEdgeT = typename thisAxisT::EdgeT;
290 // get list of shared edges
291 thisAxisT& oldAxis = BaseT::_binning.template axis<axisN>();
292 const thisAxisT newAxis(std::move(newedges));
293 const std::vector<thisEdgeT> eshared = oldAxis.sharedEdges(newAxis);
294 if (eshared.size() != newAxis.edges().size())
295 throw BinningError("Requested rebinning to incompatible edges");
296 // loop over new lower bin edges (= first bin index of merge range)
297 for (size_t begin = 0; begin < eshared.size() - 1; ++begin) {
298 // find index of upper edge along old axis
299 // (subtracting 1 gives index of last bin to be merged)
300 size_t end = oldAxis.index(eshared[begin+1]) - 1;
301 // if the current edge is the last visible edge before the overflow
302 // merge the remaining bins into the overflow
303 if (begin == newAxis.numBins(true)-1) end = oldAxis.numBins(true)-1;
304 // merge this range
305 if (end > begin) BaseT::template mergeBins<axisN>({begin, end});
306 if (eshared.size() == oldAxis.edges().size()) break; // we're done
307 }
308 }
309
311 template <size_t axisN>
312 void rebin(const std::vector<typename BinningT::template getAxisT<axisN>::EdgeT>& newedges) {
313 rebinTo<axisN>(std::move(newedges));
314 }
315
319 void reset() noexcept { BaseT::clearBins(); }
320
323 if (this != &est) {
326 }
327 return *this;
328 }
329
332 if (this != &est) {
334 BaseT::operator = (std::move(est));
335 }
336 return *this;
337 }
338
344 const std::string& pat_uncorr="^stat|^uncor" ) {
345 if (*this != est)
346 throw BinningError("Arithmetic operation requires compatible binning!");
347 if (AO::hasAnnotation("ScaledBy")) AO::rmAnnotation("ScaledBy");
348 for (size_t i = 0; i< BaseT::numBins(true, true); ++i) {
349 BaseT::bin(i).add(est.bin(i), pat_uncorr);
350 }
351 BaseT::maskBins(est.maskedBins(), true);
352 return *this;
353 }
354 //
356 return add(est);
357 }
358
364 const std::string& pat_uncorr="^stat|^uncor" ) {
365 if (*this != est)
366 throw BinningError("Arithmetic operation requires compatible binning!");
367 if (AO::hasAnnotation("ScaledBy")) AO::rmAnnotation("ScaledBy");
368 for (size_t i = 0; i< BaseT::numBins(true, true); ++i) {
369 BaseT::bin(i).add(std::move(est.bin(i)), pat_uncorr);
370 }
371 BaseT::maskBins(est.maskedBins(), true);
372 return *this;
373 }
374 //
376 return add(std::move(est));
377 }
378
379
385 const std::string& pat_uncorr="^stat|^uncor" ) {
386 if (*this != est)
387 throw BinningError("Arithmetic operation requires compatible binning!");
388 if (AO::hasAnnotation("ScaledBy")) AO::rmAnnotation("ScaledBy");
389 for (size_t i = 0; i< BaseT::numBins(true, true); ++i) {
390 BaseT::bin(i).subtract(est.bin(i), pat_uncorr);
391 }
392 BaseT::maskBins(est.maskedBins(), true);
393 return *this;
394 }
395 //
397 return subtract(est);
398 }
399
402 const std::string& pat_uncorr="^stat|^uncor" ) {
403 if (*this != est)
404 throw BinningError("Arithmetic operation requires compatible binning!");
405 if (AO::hasAnnotation("ScaledBy")) AO::rmAnnotation("ScaledBy");
406 for (size_t i = 0; i< BaseT::numBins(true, true); ++i) {
407 BaseT::bin(i) -= std::move(est.bin(i), pat_uncorr);
408 }
409 BaseT::maskBins(est.maskedBins(), true);
410 return *this;
411 }
412 //
414 return subtract(std::move(est));
415 }
416
418
419
422
424 size_t dim() const noexcept { return sizeof...(AxisT) + 1; }
425
427 std::string _config() const noexcept { return mkAxisConfig<AxisT...>(); }
428
433 template <size_t I, typename E = typename BinningT::template getEdgeT<I>>
434 std::vector<E> edges(const bool includeOverflows = false) const noexcept {
435 return BaseT::_binning.template edges<I>(includeOverflows);
436 }
437
444 template <size_t I, typename E = typename BinningT::template getEdgeT<I>>
445 std::enable_if_t<std::is_floating_point<E>::value, std::vector<E>>
446 widths(const bool includeOverflows = false) const noexcept {
447 return BaseT::_binning.template widths<I>(includeOverflows);
448 }
449
453 template <size_t I, typename E = typename BinningT::template getEdgeT<I>>
454 std::enable_if_t<std::is_floating_point<E>::value, E> min() const noexcept {
455 return BaseT::_binning.template min<I>();
456 }
457
461 template <size_t I, typename E = typename BinningT::template getEdgeT<I>>
462 std::enable_if_t<std::is_floating_point<E>::value, E> max() const noexcept {
463 return BaseT::_binning.template max<I>();
464 }
465
467
468
471
473 std::vector<double> vals(const bool includeOverflows=false,
474 const bool includeMaskedBins=false) const {
475 std::vector<double> rtn;
476 rtn.reserve(BaseT::numBins(includeOverflows, includeMaskedBins));
477 for (const auto& b : BaseT::bins(includeOverflows, includeMaskedBins)) {
478 rtn.push_back(b.val());
479 }
480 return rtn;
481 }
482
484 std::vector<std::string> sources() const {
485 // Assemble union of error sources, as it's not guaranteed
486 // that every bin has the same error breakdown
487 std::vector<std::string> rtn;
488
489 for (const auto& b : BaseT::bins(true)) {
490 std::vector<std::string> keys = b.sources();
491 rtn.insert(std::end(rtn),
492 std::make_move_iterator(std::begin(keys)),
493 std::make_move_iterator(std::end(keys)));
494 }
495 std::sort(rtn.begin(), rtn.end());
496 rtn.erase( std::unique(rtn.begin(), rtn.end()), rtn.end() );
497
498 return rtn;
499 }
500
504 double areaUnderCurve(const bool includeBinVol=true,
505 const bool includeOverflows=false,
506 const bool includeMaskedBins=false) const {
507 double ret = 0.;
508 for (const auto& b : BaseT::bins(includeOverflows, includeMaskedBins)) {
509 const double val = fabs(b.val());
510 const double vol = includeBinVol? b.dVol() : 1.0;
511 if (std::isfinite(vol)) ret += val*vol; // aggregate bin volume
512 }
513 return ret;
514 }
515
517 double auc(const bool includeBinVol=true,
518 const bool includeOverflows=false,
519 const bool includeMaskedBins=false) const {
520 return areaUnderCurve(includeBinVol, includeOverflows, includeMaskedBins);
521 }
522
523
524
526 std::vector<std::vector<double> > covarianceMatrix(const bool ignoreOffDiagonalTerms=false,
527 const bool includeOverflows=false,
528 const bool includeMaskedBins=false,
529 const std::string& pat_uncorr="^stat|^uncor") const {
530 const size_t nBins = BaseT::numBins(includeOverflows,includeMaskedBins);
531 std::vector<std::vector<double> > covM(nBins);
532
533 // initialise cov matrix to be the right shape
534 for (size_t i = 0; i < nBins; ++i) {
535 covM[i] = std::vector<double>(nBins, 0.0);
536 }
537
538 const std::vector<std::string> error_sources = sources();
539
540 // nominal-only case, i.e. total uncertainty, labelled as empty string
541 if (error_sources.size() == 1 && error_sources[0] == "") {
542 size_t i = 0;
543 for (const auto& b : BaseT::bins(includeOverflows,includeMaskedBins)) {
544 covM[i][i] = b.hasSource("")? sqr(0.5*(b.err("").first+b.err("").second)) : 1.0;
545 ++i;
546 }
547 return covM;
548 }
549
550 // more interesting case where we actually have some uncertainty breakdown!
551 std::smatch match;
552 const std::regex re(pat_uncorr, std::regex_constants::icase);
553 for (const std::string& sname : error_sources) {
554 if (sname == "") continue;
555 std::vector<double> systErrs(nBins, 0.0);
556 size_t k = 0;
557 for (const auto& b : BaseT::bins(includeOverflows,includeMaskedBins)) {
558 if (b.hasSource(sname)) {
559 const auto& errs = b.err(sname); // dn-up pair
560 systErrs[k] = 0.5 *( fabs(errs.first)+fabs(errs.second));
561 }
562 ++k;
563 }
564 const bool skipOffDiag = (ignoreOffDiagonalTerms
565 || std::regex_search(sname, match, re));
566 for (size_t i = 0; i < nBins; ++i) {
567 for (size_t j = 0; j < nBins; ++j) {
568 if (skipOffDiag && i != j) continue;
569 covM[i][j] += systErrs[i]*systErrs[j];
570 }
571 }
572 }
573
574 return covM;
575 }
576
578
581
583 auto mkScatter(const std::string& path="", const std::string& pat_match = "",
584 const bool includeOverflows=false,
585 const bool includeMaskedBins=false) const {
586
587 constexpr size_t N = sizeof...(AxisT);
588
589 ScatterND<N+1> rtn;
590 for (const std::string& a : annotations()) {
591 if (a != "Type") rtn.setAnnotation(a, annotation(a));
592 }
593 rtn.setAnnotation("Path", path);
594
595 const bool incOF = all_CAxes<AxisT...>::value && includeOverflows;
596 for (const auto& b : BaseT::bins(incOF, includeMaskedBins)) {
597
598 // Create the vector of coordinates
599 Utils::ndarray<double, N+1> vals;
600 // first fill bin centres, use bin index if axis non-arithmetic
601 auto indexIfDiscrete = [&vals, &b](auto I) {
602 using isContinuous = typename BinningT::template is_CAxis<I>;
603 using isArithmetic = typename BinningT::template is_Arithmetic<I>;
604 vals[I] = coordPicker<I>(b, std::integral_constant<bool, isArithmetic::value>{},
605 std::integral_constant<bool, isContinuous::value>{});
606 };
607 MetaUtils::staticFor<BinningT::Dimension::value>(indexIfDiscrete);
608 // then fill bin content
609 vals[N] = b.val();
610
611 // Create the vector of error pairs, use 0 if axis not continuous
612 Utils::ndarray<std::pair<double,double>, N+1> errs;
613 auto nullifyDiscrete = [&errs, &vals, &b](auto I) {
614 using isContinuous = typename BinningT::template is_CAxis<I>;
615 errs[I] = nullifyIfDisc<I>(b, vals[I], std::integral_constant<bool, isContinuous::value>{});
616 };
617 MetaUtils::staticFor<BinningT::Dimension::value>(nullifyDiscrete);
618 const double tot = fabs(b.totalErrPos(pat_match)); // use positive error component
619 errs[N] = { tot, tot };
620
621 // Add the PointND
622 rtn.addPoint( PointND<N+1>(vals, errs) );
623 }
624
625 // Decorate output scatter with the discrete edges
626 const BinningT& binning = BaseT::_binning;
627 auto decorateEdges = [&rtn, &binning](auto I) {
628 using isContinuous = typename BinningT::template is_CAxis<I>;
629 if constexpr( !isContinuous::value ) {
630 const auto& axis = binning.template axis<I>();
631 if (axis.numBins()) {
632 std::stringstream ss;
633 axis._renderYODA(ss);
634 rtn.setAnnotation("EdgesA" + std::to_string(I+1), ss.str());
635 }
636 }
637 };
638 MetaUtils::staticFor<BinningT::Dimension::value>(decorateEdges);
639
640 return rtn;
641 }
642
647 template<size_t axisN, typename = std::enable_if_t< (axisN < sizeof...(AxisT) && sizeof...(AxisT)>=2) >>
648 auto mkEstimates(const std::string& path="", const bool includeOverflows=false) const {
649
650 // Need to provide a prescription for how to add the two bin contents
651 auto how2add = [](auto& pivot, const BinType& toCopy) { pivot = toCopy; };
652 auto rtn = BaseT::template mkBinnedSlices<axisN, BinnedEstimate>(how2add, includeOverflows);
653 for (const std::string& a : annotations()) {
654 if (a == "Type") continue;
655 for (size_t i = 0; i < rtn.size(); ++i) {
656 rtn[i].setAnnotation(a, annotation(a));
657 }
658 }
659 for (size_t i = 0; i < rtn.size(); ++i) {
660 rtn[i].setAnnotation("Path", path);
661 }
662
663 return rtn;
664 }
665
666
668 AnalysisObject* mkInert(const std::string& path = "",
669 const std::string& source = "") const noexcept {
670 EstimateStorage* rtn = newclone();
671 rtn->setPath(path);
672 for (auto& b : rtn->bins(true, true)) {
673 if (b.numErrs() == 1) {
674 try {
675 b.renameSource("", source);
676 }
677 catch (YODA::UserError& e) { }
678 }
679 }
680 return rtn;
681 }
682
684
686
687
688 size_t lengthContent(bool fixed_length = false) const noexcept {
689 size_t rtn = 0;
690 for (const auto& bin : BaseT::bins(true, true)) {
691 rtn += bin._lengthContent(fixed_length);
692 }
693 return rtn;
694 }
695
696 std::vector<double> serializeContent(bool fixed_length = false) const noexcept {
697 std::vector<double> rtn;
698 const size_t nBins = BaseT::numBins(true, true);
699 rtn.reserve(nBins * 4);
700 for (size_t i = 0; i < nBins; ++i) {
701 const auto& b = BaseT::bin(i);
702 std::vector<double> bdata = b._serializeContent(fixed_length);
703 rtn.insert(std::end(rtn),
704 std::make_move_iterator(std::begin(bdata)),
705 std::make_move_iterator(std::end(bdata)));
706 }
707 return rtn;
708 }
709
710
711 void deserializeContent(const std::vector<double>& data) {
712
713 const size_t nBins = BaseT::numBins(true, true);
714 const size_t minLen = 2*nBins;
715 if (data.size() < minLen)
716 throw UserError("Length of serialized data should be at least " + std::to_string(minLen)+"!");
717
718 size_t i = 0;
719 auto itr = data.cbegin();
720 const auto itrEnd = data.cend();
721 const bool fixedLen = data.size() == 2*minLen;
722 while (itr != itrEnd) {
723 // for estimates, the first element represents the central,
724 // the subsequent value represents the number of error pairs
725 const size_t nErrs = fixedLen? 1 : (*(itr + 1) + 0.5); // add 0.5 to avoid rounding issues
726 auto last = itr + 2*(nErrs+1); // last element + 1
727 BaseT::bin(i)._deserializeContent(std::vector<double>{itr, last}, fixedLen);
728 // update for next iteration
729 itr = last;
730 ++i;
731 }
732 }
733
734 // @}
735
736 private:
737
740 template<size_t... Is>
741 BinningT _mkBinning(const std::vector<size_t>& nBins,
742 const std::vector<std::pair<double, double>>& limitsLowUp,
743 std::index_sequence<Is...>) const {
744 return BinningT({((void)Is, Axis<AxisT>(nBins[Is], limitsLowUp[Is].first, limitsLowUp[Is].second))...});
745 }
746
748 template<size_t... Is>
749 BinningT _mkBinning(const ScatterND<sizeof...(AxisT)+1>& s, std::index_sequence<Is...>) const {
750 return BinningT({((void)Is, Axis<AxisT>(s.edges(Is)))...});
751 }
752
753 };
754
755
756
758 template <typename... AxisT>
759 class BinnedEstimate : public EstimateStorage<AxisT...> {
760 public:
761 using EstimateT = BinnedEstimate<AxisT...>;
762 using BaseT = EstimateStorage<AxisT...>;
763 using BinType = typename BaseT::BinT;
764 using Ptr = std::shared_ptr<EstimateT>;
765
767 using BaseT::BaseT;
768
769 BinnedEstimate(const EstimateT&) = default;
773 using AnalysisObject::operator =;
774
778 BinnedEstimate(const BaseT& other) : BaseT(other) {}
779 //
780 BinnedEstimate(const EstimateT& other, const std::string& path) : BaseT(other, path) {}
781
783 BinnedEstimate(BaseT&& other) : BaseT(std::move(other)) {}
784 //
785 BinnedEstimate(EstimateT&& other, const std::string& path) : BaseT(std::move(other), path) {}
786
787 };
788
789
791 template <typename AxisT>
792 class BinnedEstimate<AxisT>
793 : public EstimateStorage<AxisT>,
794 public XAxisMixin<BinnedEstimate<AxisT>, AxisT> {
795 public:
798 using BinType = typename BaseT::BinT;
799 using Ptr = std::shared_ptr<EstimateT>;
800
802 using BaseT::BaseT;
803
804 BinnedEstimate(const EstimateT&) = default;
808 using AnalysisObject::operator =;
809
813 BinnedEstimate(const BaseT& other) : BaseT(other) {}
814 //
815 BinnedEstimate(const EstimateT& other, const std::string& path) : BaseT(other, path) {}
816
818 BinnedEstimate(BaseT&& other) : BaseT(std::move(other)) {}
819 //
820 BinnedEstimate(EstimateT&& other, const std::string& path) : BaseT(std::move(other), path) {}
821
822
823 BinnedEstimate(std::vector<AxisT>&& edges, const std::string& path="", const std::string& title="")
824 : BaseT(std::move(edges), path, title) {}
825
826 BinnedEstimate(const std::vector<AxisT>& edges, const std::string& path="", const std::string& title="")
827 : BaseT(edges, path, title) {}
828
835 template <typename EdgeT = double, typename = enable_if_all_CAxisT<EdgeT, AxisT>>
836 BinnedEstimate(size_t nbins, double lower, double upper, const std::string& path = "", const std::string& title = "")
837 : BaseT({nbins}, {{lower, upper}}, path, title) {}
838
840 EstimateT clone() const noexcept {
841 return EstimateT(*this);
842 }
843
845 EstimateT* newclone() const noexcept {
846 return new EstimateT(*this);
847 }
848
850 size_t indexAt(const AxisT xCoord) const noexcept {
851 return BaseT::binAt( {xCoord} ).index();
852 }
853
855 void maskBinAt(const AxisT xCoord, const bool status = true) noexcept {
856 return BaseT::maskBin({xCoord}, status);
857 }
858
859 };
860
861
862
864 template <typename AxisT1, typename AxisT2>
865 class BinnedEstimate<AxisT1, AxisT2>
866 : public EstimateStorage<AxisT1, AxisT2>,
867 public XAxisMixin<BinnedEstimate<AxisT1, AxisT2>, AxisT1>,
868 public YAxisMixin<BinnedEstimate<AxisT1, AxisT2>, AxisT2> {
869 public:
872 using BinType = typename BaseT::BinT;
873 using Ptr = std::shared_ptr<EstimateT>;
874
876 using BaseT::BaseT;
877
878 BinnedEstimate(const EstimateT&) = default;
882 using AnalysisObject::operator =;
883
887 BinnedEstimate(const BaseT& other) : BaseT(std::move(other)) {}
888 //
889 BinnedEstimate(const EstimateT& other, const std::string& path) : BaseT(other, path) {}
890
892 BinnedEstimate(BaseT&& other) : BaseT(std::move(other)) {}
893 //
894 BinnedEstimate(EstimateT&& other, const std::string& path) : BaseT(std::move(other), path) {}
895
896 BinnedEstimate(std::vector<AxisT1>&& xEdges, std::vector<AxisT2>&& yEdges,
897 const std::string& path="", const std::string& title="")
898 : BaseT(std::move(xEdges), std::move(yEdges), path, title) {}
899
900 BinnedEstimate(const std::vector<AxisT1>& xEdges, const std::vector<AxisT2>& yEdges,
901 const std::string& path="", const std::string& title="")
902 : BaseT(xEdges, yEdges, path, title) {}
903
910 template <typename EdgeT = double, typename = enable_if_all_CAxisT<EdgeT, AxisT1, AxisT2>>
911 BinnedEstimate(size_t nbinsX, double lowerX, double upperX,
912 size_t nbinsY, double lowerY, double upperY,
913 const std::string& path = "", const std::string& title = "")
914 : BaseT({nbinsX, nbinsY}, {{lowerX, upperX}, {lowerY, upperY}}, path, title) {}
915
917 EstimateT clone() const noexcept {
918 return EstimateT(*this);
919 }
920
922 EstimateT* newclone() const noexcept {
923 return new EstimateT(*this);
924 }
925
927 BinType& bin(const size_t index) noexcept {
928 return BaseT::bin(index);
929 }
930
932 const BinType& bin(const size_t index) const noexcept {
933 return BaseT::bin(index);
934 }
935
937 BinType& bin(const size_t localX, const size_t localY) noexcept {
938 return BaseT::bin( {localX, localY} );
939 }
940
942 const BinType& bin(const size_t localX, const size_t localY) const noexcept {
943 return BaseT::bin( {localX, localY} );
944 }
945
947 BinType& binAt(const AxisT1 xCoord, const AxisT2 yCoord) noexcept {
948 return BaseT::binAt( {xCoord, yCoord} );
949 }
950
952 const BinType& binAt(const AxisT1 xCoord, const AxisT2 yCoord) const noexcept {
953 return BaseT::binAt( {xCoord, yCoord} );
954 }
955
957 size_t indexAt(const AxisT1 xCoord, const AxisT2 yCoord) const noexcept {
958 return BaseT::binAt( {xCoord, yCoord} ).index();
959 }
960
962 void maskBinAt(const AxisT1 xCoord, const AxisT2 yCoord, const bool status = true) noexcept {
963 return BaseT::maskBin({xCoord, yCoord}, status);
964 }
965
966 };
967
968
970 template <typename AxisT1, typename AxisT2, typename AxisT3>
971 class BinnedEstimate<AxisT1, AxisT2, AxisT3>
972 : public EstimateStorage<AxisT1, AxisT2, AxisT3>,
973 public XAxisMixin<BinnedEstimate<AxisT1, AxisT2, AxisT3>, AxisT1>,
974 public YAxisMixin<BinnedEstimate<AxisT1, AxisT2, AxisT3>, AxisT2>,
975 public ZAxisMixin<BinnedEstimate<AxisT1, AxisT2, AxisT3>, AxisT3> {
976 public:
979 using BinType = typename BaseT::BinT;
980 using Ptr = std::shared_ptr<EstimateT>;
981
983 using BaseT::BaseT;
984
985 BinnedEstimate(const EstimateT&) = default;
989 using AnalysisObject::operator =;
990
994 BinnedEstimate(const BaseT& other) : BaseT(other) {}
995 //
996 BinnedEstimate(const EstimateT& other, const std::string& path) : BaseT(other, path) {}
997
999 BinnedEstimate(BaseT&& other) : BaseT(std::move(other)) {}
1000 //
1001 BinnedEstimate(EstimateT&& other, const std::string& path) : BaseT(std::move(other), path) {}
1002
1009 template <typename EdgeT = double, typename = enable_if_all_CAxisT<EdgeT, AxisT1, AxisT2, AxisT3>>
1010 BinnedEstimate(size_t nbinsX, double lowerX, double upperX,
1011 size_t nbinsY, double lowerY, double upperY,
1012 size_t nbinsZ, double lowerZ, double upperZ,
1013 const std::string& path = "", const std::string& title = "")
1014 : BaseT({nbinsX, nbinsY, nbinsZ}, {{lowerX, upperX}, {lowerY, upperY},
1015 {lowerZ, upperZ}}, path, title) {}
1016
1018 EstimateT clone() const noexcept {
1019 return EstimateT(*this);
1020 }
1021
1023 EstimateT* newclone() const noexcept {
1024 return new EstimateT(*this);
1025 }
1026
1028 BinType& bin(const size_t index) noexcept {
1029 return BaseT::bin(index);
1030 }
1031
1033 const BinType& bin(const size_t index) const noexcept {
1034 return BaseT::bin(index);
1035 }
1036
1038 BinType& bin(const size_t localX, const size_t localY, const size_t localZ) noexcept {
1039 return BaseT::bin( {localX, localY, localZ} );
1040 }
1041
1043 const BinType& bin(const size_t localX, const size_t localY, const size_t localZ) const noexcept {
1044 return BaseT::bin( {localX, localY, localZ} );
1045 }
1046
1048 BinType& binAt(const AxisT1 xCoord, const AxisT2 yCoord, const AxisT3 zCoord) noexcept {
1049 return BaseT::binAt( {xCoord, yCoord, zCoord} );
1050 }
1051
1053 const BinType& binAt(const AxisT1 xCoord, const AxisT2 yCoord, const AxisT3 zCoord) const noexcept {
1054 return BaseT::binAt( {xCoord, yCoord, zCoord} );
1055 }
1056
1058 size_t indexAt(const AxisT1 xCoord, const AxisT2 yCoord, const AxisT3 zCoord) const noexcept {
1059 return BaseT::binAt( {xCoord, yCoord, zCoord} ).index();
1060 }
1061
1063 void maskBinAt(const AxisT1 xCoord, const AxisT2 yCoord, const AxisT3 zCoord, const bool status = true) noexcept {
1064 return BaseT::maskBin({xCoord, yCoord, zCoord}, status);
1065 }
1066
1067 };
1068
1071
1073 template <typename... AxisT>
1074 inline BinnedEstimate<AxisT...>
1076 first += second;
1077 return first;
1078 }
1079
1080
1082 template <typename... AxisT>
1083 inline BinnedEstimate<AxisT...>
1085 first += std::move(second);
1086 return first;
1087 }
1088
1089
1091 template <typename... AxisT>
1092 inline BinnedEstimate< AxisT...>
1094 first -= second;
1095 return first;
1096 }
1097
1099 template <typename... AxisT>
1100 inline BinnedEstimate< AxisT...>
1102 first -= std::move(second);
1103 return first;
1104 }
1105
1107 template <typename... AxisT>
1108 inline BinnedEstimate<AxisT...>
1110 const std::string& pat_uncorr="^stat|^uncor" ) {
1111 if (numer != denom) {
1112 throw BinningError("Arithmetic operation requires compatible binning!");
1113 }
1114
1115 BinnedEstimate<AxisT...> rtn(numer.binning());
1116 if (numer.path() == denom.path()) rtn.setPath(numer.path());
1117 if (rtn.hasAnnotation("ScaledBy")) rtn.rmAnnotation("ScaledBy");
1118
1119 for (const auto& b_num : numer.bins(true, true)) {
1120 const size_t idx = b_num.index();
1121 rtn.bin(idx) = divide(b_num, denom.bin(idx), pat_uncorr);
1122 }
1123 rtn.maskBins(denom.maskedBins(), true);
1124
1125 return rtn;
1126 }
1127
1129 template <typename... AxisT>
1130 inline BinnedEstimate<AxisT...>
1132 return divide(numer, denom);
1133 }
1134
1136 template <typename... AxisT>
1137 inline BinnedEstimate<AxisT...>
1139 return divide(std::move(numer), denom);
1140 }
1141
1143 template <typename... AxisT>
1144 inline BinnedEstimate<AxisT...>
1146 return divide(numer, std::move(denom));
1147 }
1148
1150 template <typename... AxisT>
1151 inline BinnedEstimate<AxisT...>
1153 return divide(std::move(numer), std::move(denom));
1154 }
1155
1156
1161 template <typename... AxisT>
1162 inline BinnedEstimate<AxisT...>
1164 const std::string& pat_uncorr="^stat|^uncor" ) {
1165
1166 if (accepted != total) {
1167 throw BinningError("Arithmetic operation requires compatible binning!");
1168 }
1169
1170 BinnedEstimate<AxisT...> rtn(accepted.binning());
1171
1172 for (const auto& b_acc : accepted.bins(true, true)) {
1173 Estimate est;
1174 const size_t idx = b_acc.index();
1175 try {
1176 est = efficiency(b_acc, total.bin(idx), pat_uncorr);
1177 } catch (const UserError& e) {
1178 //
1179 }
1180 rtn.bin(idx).set(est);
1181 }
1182 return rtn;
1183 }
1184
1185
1187 template <typename... AxisT>
1188 inline BinnedEstimate<AxisT...>
1190 const BinnedEstimate<AxisT...>& b,
1191 const std::string& pat_uncorr="^stat|^uncor" ) {
1192 return divde(subtract(a-b, pat_uncorr), add(a+b, pat_uncorr), pat_uncorr);
1193 }
1194
1195
1197
1198
1201
1202 template <typename... AxisT>
1203 inline void transform(BinnedEstimate<AxisT...>& est, const Trf<1>& fn) {
1204 for (auto& b : est.bins(true, true)) {
1205 b.transform(fn);
1206 }
1207 }
1208
1209 template <typename... AxisT, typename FN>
1210 inline void transform(BinnedEstimate<AxisT...>& est, const FN& fn) {
1211 transform(est, Trf<1>(fn));
1212 }
1213
1215
1216
1219
1221 template<typename A1>
1223
1224 template <typename A1, typename A2>
1226
1227 template <typename A1, typename A2, typename A3>
1229
1231 namespace {
1232 template <class T>
1233 struct EstimateMaker;
1234
1235 template<size_t... Is>
1236 struct EstimateMaker<std::index_sequence<Is...>> {
1238 };
1239 }
1240
1241 template<size_t N>
1242 using EstimateND = typename EstimateMaker<std::make_index_sequence<N>>::type;
1243
1244
1245 // User-friendly names (continuous axes only)
1249
1251
1252}
1253
1254#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:86
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:1080
BinnedEstimate< AxisT... > operator/(const BinnedDbn< DbnN, AxisT... > &numer, const BinnedDbn< DbnN, AxisT... > &denom)
Definition BinnedDbn.h:1153
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:1182
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:1216
BinnedEstimate< AxisT... > add(const BinnedDbn< DbnN, AxisT... > &dbn, const BinnedEstimate< AxisT... > &est)
Calculate the addition of a BinnedDbn with a BinnedEstimate.
Definition BinnedDbn.h:1285
BinnedEstimate< AxisT... > subtract(const BinnedDbn< DbnN, AxisT... > &dbn, const BinnedEstimate< AxisT... > &est)
Calculate the subtraction of a BinnedEstimate from a BinnedDbn.
Definition BinnedDbn.h:1317
BinnedDbn< DbnN, AxisT... > operator-(BinnedDbn< DbnN, AxisT... > first, BinnedDbn< DbnN, AxisT... > &&second)
Subtract one BinnedDbn object from another.
Definition BinnedDbn.h:1096
BinnedEstimate< AxisT... > divide(const BinnedDbn< DbnN, AxisT... > &numer, const BinnedDbn< DbnN, AxisT... > &denom)
Divide two BinnedDbn objects.
Definition BinnedDbn.h:1112
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.