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