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