File indexing completed on 2026-06-05 08:44:23
0001
0002
0003
0004
0005
0006 #ifndef YODA_Estimate0D_h
0007 #define YODA_Estimate0D_h
0008
0009 #include "YODA/AnalysisObject.h"
0010 #include "YODA/Exceptions.h"
0011 #include "YODA/Estimate.h"
0012 #include "YODA/Scatter.h"
0013
0014 #ifdef HAVE_HDF5
0015 #include "YODA/Utils/H5Utils.h"
0016 #endif
0017
0018 #include <string>
0019
0020 namespace YODA {
0021
0022
0023
0024
0025
0026
0027
0028 class Estimate0D : public Estimate,
0029 public AnalysisObject {
0030 public:
0031
0032 using Ptr = std::shared_ptr<Estimate0D>;
0033 using BaseT = Estimate;
0034 using BaseT::operator =;
0035 using BaseT::operator +=;
0036 using BaseT::operator -=;
0037 using AnalysisObject::operator =;
0038
0039
0040
0041
0042
0043
0044
0045
0046 Estimate0D(const std::string& path = "", const std::string& title = "")
0047 : BaseT(), AnalysisObject("Estimate0D", path, title) { }
0048
0049
0050
0051
0052
0053 Estimate0D(double v,
0054 std::map<std::string,std::pair<double,double>>& errors,
0055 const std::string& path = "", const std::string& title = "")
0056 : BaseT(v, errors), AnalysisObject("Estimate0D", path, title) { }
0057
0058
0059
0060 Estimate0D(const double v, const std::pair<double,double>& e, const std::string& source = "",
0061 const std::string& path = "", const std::string& title = "")
0062 : BaseT(v, e, source), AnalysisObject("Estimate0D", path, title) { }
0063
0064
0065
0066
0067 Estimate0D(const Estimate0D& other) : Estimate(other),
0068 AnalysisObject(other.type(), other.path(), other, other.title()) { }
0069
0070
0071 Estimate0D(Estimate0D&& other) : BaseT(std::move(other)),
0072 AnalysisObject(other.type(), other.path(), other, other.title()) { }
0073
0074
0075 Estimate0D(const BaseT& other, const std::string& path = "", const std::string& title = "")
0076 : BaseT(other), AnalysisObject("Estimate0D", path, title) { }
0077
0078
0079 Estimate0D(BaseT&& other, const std::string& path = "", const std::string& title = "")
0080 : BaseT(std::move(other)), AnalysisObject("Estimate0D", path, title) { }
0081
0082
0083 Estimate0D clone() const noexcept {
0084 return Estimate0D(*this);
0085 }
0086
0087
0088 Estimate0D* newclone() const noexcept {
0089 return new Estimate0D(*this);
0090 }
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 Estimate0D& operator=(const Estimate0D& toCopy) noexcept {
0102 if (this != &toCopy) {
0103 AnalysisObject::operator = (toCopy);
0104 BaseT::operator = (toCopy);
0105 }
0106 return *this;
0107 }
0108
0109
0110 Estimate0D& operator = (Estimate0D&& toMove) noexcept {
0111 if (this != &toMove) {
0112 AnalysisObject::operator = (toMove);
0113 BaseT::operator = (std::move(toMove));
0114 }
0115 return *this;
0116 }
0117
0118
0119 Estimate0D& add(const Estimate0D& toAdd, const std::string& pat_uncorr="^stat|^uncor" ) {
0120 if (hasAnnotation("ScaledBy")) rmAnnotation("ScaledBy");
0121 BaseT::add(toAdd, pat_uncorr);
0122 return *this;
0123 }
0124
0125 Estimate0D& operator+=(const Estimate0D& toAdd) {
0126 return add(toAdd);
0127 }
0128
0129
0130 Estimate0D& add(Estimate0D&& toAdd, const std::string& pat_uncorr="^stat|^uncor" ) {
0131 if (hasAnnotation("ScaledBy")) rmAnnotation("ScaledBy");
0132 BaseT::add(std::move(toAdd), pat_uncorr);
0133 return *this;
0134 }
0135
0136 Estimate0D& operator+=(Estimate0D&& toAdd) {
0137 return add(std::move(toAdd));
0138 }
0139
0140
0141 Estimate0D& subtract(const Estimate0D& toSubtract, const std::string& pat_uncorr="^stat|^uncor" ) {
0142 if (hasAnnotation("ScaledBy")) rmAnnotation("ScaledBy");
0143 BaseT::subtract(toSubtract, pat_uncorr);
0144 return *this;
0145 }
0146
0147 Estimate0D& operator-=(const Estimate0D& toSubtract) {
0148 return subtract(toSubtract);
0149 }
0150
0151
0152 Estimate0D& subtract(Estimate0D&& toSubtract, const std::string& pat_uncorr="^stat|^uncor" ) {
0153 if (hasAnnotation("ScaledBy")) rmAnnotation("ScaledBy");
0154 BaseT::subtract(std::move(toSubtract), pat_uncorr);
0155 return *this;
0156 }
0157 Estimate0D& operator-=(Estimate0D&& toSubtract) {
0158 return subtract(std::move(toSubtract));
0159 }
0160
0161
0162
0163
0164
0165
0166
0167 size_t dim() const noexcept { return 1; }
0168
0169
0170
0171
0172
0173
0174
0175 void reset() noexcept {
0176 BaseT::reset();
0177 }
0178
0179
0180
0181
0182
0183
0184
0185 void _renderYODA(std::ostream& os, const int width = 13) const noexcept {
0186
0187
0188 const std::vector<std::string> labels = this->sources();
0189 if (labels.size()) {
0190 os << "ErrorLabels: [";
0191 for (size_t i = 0; i < labels.size(); ++i) {
0192 const std::string& src = labels[i];
0193 if (i) os << ", ";
0194 os << std::quoted(src);
0195 }
0196 os << "]\n";
0197 }
0198
0199
0200 os << std::setw(width) << std::left << "# value" << "\t";
0201 const int errwidth = std::max(int(std::to_string(labels.size()).size()+7), width);
0202 for (size_t i = 0; i < labels.size(); ++i) {
0203 const std::string& src = labels[i];
0204 if (src.empty()) {
0205 os << std::setw(errwidth) << std::left << "totalDn" << "\t";
0206 os << std::setw(errwidth) << std::left << "totalUp" << "\t";
0207 }
0208 else {
0209 os << std::setw(errwidth) << std::left << ("errDn(" + std::to_string(i+1) + ")") << "\t";
0210 os << std::setw(errwidth) << std::left << ("errUp(" + std::to_string(i+1) + ")") << "\t";
0211 }
0212 }
0213 os << "\n";
0214
0215 os << std::setw(width) << std::left << val() << "\t";
0216
0217 for (const std::string& src : labels) {
0218 if (!hasSource(src)) {
0219 os << std::setw(errwidth) << std::left << "---" << "\t"
0220 << std::setw(errwidth) << std::left << "---" << "\t";
0221 continue;
0222 }
0223 const auto& errs = err(src);
0224 os << std::setw(errwidth) << std::left << errs.first << "\t"
0225 << std::setw(errwidth) << std::left << errs.second << "\t";
0226 }
0227 os << "\n";
0228 }
0229
0230
0231 void _renderFLAT(std::ostream& os, const int width = 13) const noexcept {
0232 const Scatter1D tmp = mkScatter();
0233 tmp._renderYODA(os, width);
0234 }
0235
0236 #ifdef HAVE_HDF5
0237
0238
0239 void _extractLabels(std::vector<std::string>& labels,
0240 std::vector<size_t>& labelsizes) const noexcept {
0241
0242 std::vector<std::string> keys = sources();
0243 labelsizes.emplace_back(keys.size()+1);
0244 labels.insert(std::end(labels),
0245 std::make_move_iterator(std::begin(keys)),
0246 std::make_move_iterator(std::end(keys)));
0247
0248 std::sort(labels.begin(), labels.end());
0249 labels.erase( std::unique(labels.begin(), labels.end()), labels.end() );
0250 }
0251
0252
0253 void _extractEdges(std::map<std::string, EdgeHandlerBasePtr>& edges,
0254 const std::vector<std::string>& labels) const noexcept {
0255
0256 using lenT = EdgeHandler<size_t>;
0257 using lenPtr = EdgeHandlerPtr<size_t>;
0258 const std::string lengthID("sizeinfo");
0259 lenPtr nedges = std::static_pointer_cast<lenT>(edges.find(lengthID)->second);
0260
0261 std::vector<std::string> keys = sources();
0262 nedges->extend({ keys.size() });
0263 const auto& itr = labels.cbegin();
0264 const auto& itrEnd = labels.cend();
0265 for (const string& k : keys) {
0266 size_t dist = std::find(itr, itrEnd, k) - itr;
0267 nedges->extend({ dist });
0268 }
0269
0270 }
0271
0272 #endif
0273
0274
0275
0276
0277
0278
0279 size_t lengthContent(bool fixed_length = false) const noexcept {
0280 return BaseT::_lengthContent(fixed_length);
0281 }
0282
0283 std::vector<double> serializeContent(bool fixed_length = false) const noexcept {
0284 return BaseT::_serializeContent(fixed_length);
0285 }
0286
0287 void deserializeContent(const std::vector<double>& data) {
0288 BaseT::_deserializeContent(data, data.size() == 4);
0289 }
0290
0291
0292
0293
0294
0295
0296 inline Scatter1D mkScatter(const std::string& path = "",
0297 const std::string& pat_match = "") const noexcept {
0298 Scatter1D rtn;
0299 for (const std::string& a : annotations()) {
0300 if (a != "Type") rtn.setAnnotation(a, annotation(a));
0301 }
0302 rtn.setAnnotation("Path", path);
0303
0304
0305 const std::pair<double,double> tot = totalErr(pat_match);
0306 rtn.addPoint( Point1D(val(), {fabs(tot.first), tot.second}) );
0307
0308 return rtn;
0309 }
0310
0311
0312 AnalysisObject* mkInert(const std::string& path = "",
0313 const std::string& source = "") const noexcept {
0314 Estimate0D* rtn = newclone();
0315 rtn->setPath(path);
0316 if (rtn->numErrs() == 1) {
0317 try {
0318 rtn->renameSource("", source);
0319 }
0320 catch (YODA::UserError& e) { }
0321 }
0322 return rtn;
0323 }
0324
0325
0326
0327 };
0328
0329
0330
0331
0332 inline void transform(Estimate0D& est, const Trf<1>& fn) {
0333 est.transform(fn);
0334 }
0335
0336 template <typename FN>
0337 inline void transform(Estimate0D& est, const FN& fn) {
0338 transform(est, Trf<1>(fn));
0339 }
0340
0341
0342
0343
0344
0345
0346
0347
0348 inline Estimate0D operator + (Estimate0D lhs, const Estimate0D& rhs) {
0349 lhs += rhs;
0350 return lhs;
0351 }
0352
0353
0354 inline Estimate0D operator + (Estimate0D lhs, Estimate0D&& rhs) {
0355 lhs += std::move(rhs);
0356 return lhs;
0357 }
0358
0359
0360 inline Estimate0D operator - (Estimate0D lhs, const Estimate0D& rhs) {
0361 lhs -= rhs;
0362 return lhs;
0363 }
0364
0365
0366 inline Estimate0D operator - (Estimate0D lhs, Estimate0D&& rhs) {
0367 lhs -= std::move(rhs);
0368 return lhs;
0369 }
0370
0371
0372 inline Estimate0D divide(const Estimate0D& numer, const Estimate0D& denom,
0373 const std::string& pat_uncorr="^stat|^uncor" ) {
0374 Estimate0D rtn = divide(static_cast<const Estimate&>(numer),
0375 static_cast<const Estimate&>(denom), pat_uncorr);
0376 if (rtn.hasAnnotation("ScaledBy")) rtn.rmAnnotation("ScaledBy");
0377 if (numer.path() == denom.path()) rtn.setPath(numer.path());
0378 return rtn;
0379 }
0380
0381
0382 inline Estimate0D operator / (const Estimate0D& numer, const Estimate0D& denom) {
0383 return divide(numer, denom);
0384 }
0385
0386
0387 inline Estimate0D operator / (Estimate0D&& numer, const Estimate0D& denom) {
0388 return divide(std::move(numer), denom);
0389 }
0390
0391
0392 inline Estimate0D operator / (const Estimate0D& numer, Estimate0D&& denom) {
0393 return divide(numer, std::move(denom));
0394 }
0395
0396
0397 inline Estimate0D operator / (Estimate0D&& numer, Estimate0D&& denom) {
0398 return divide(std::move(numer), std::move(denom));
0399 }
0400
0401
0402 inline Estimate0D efficiency(const Estimate0D& accepted, const Estimate0D& total,
0403 const std::string& pat_uncorr="^stat|^uncor" ) {
0404 Estimate0D rtn = efficiency(static_cast<const Estimate&>(accepted),
0405 static_cast<const Estimate&>(total), pat_uncorr);
0406 if (rtn.hasAnnotation("ScaledBy")) rtn.rmAnnotation("ScaledBy");
0407 if (accepted.path() == total.path()) rtn.setPath(total.path());
0408 return rtn;
0409 }
0410
0411
0412
0413 }
0414
0415 #endif