Mantid
Loading...
Searching...
No Matches
EqualBinsChecker.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
9#include <cmath>
10#include <ostream>
11#include <sstream>
12#include <stdexcept>
13#include <vector>
14
15namespace {
16// Initialize the logger
17Mantid::Kernel::Logger g_log("EqualBinsChecker");
18} // namespace
19
20namespace Mantid::Kernel {
21
33EqualBinsChecker::EqualBinsChecker(std::span<double const> xData, const double errorLevel, const double warningLevel)
34 : m_xData(xData), m_errorLevel(errorLevel), m_warn(warningLevel > 0), m_warningLevel(warningLevel),
35 m_refBinType(ReferenceBin::Average), m_errorType(ErrorType::Cumulative) {}
36
43void EqualBinsChecker::setReferenceBin(const ReferenceBin &refBinType) { m_refBinType = refBinType; }
44
51void EqualBinsChecker::setErrorType(const ErrorType &errorType) { m_errorType = errorType; }
52
57std::string EqualBinsChecker::validate() const {
58 const auto &xData = m_xData;
59 const auto xSize = xData.size();
60 // First check for empty input
61 if (xSize == 0) {
62 return "Input workspace must not be empty";
63 }
64
65 // reference bin width to compare to
66 const double dx = getReferenceDx();
67
68 // Check each width against dx
69 bool printWarning = false;
70 for (size_t bin = 0; bin < xSize - 2; bin++) {
71 const double diff = getDifference(bin, dx);
72 if (diff > m_errorLevel) {
73 std::stringstream errorStr;
74 errorStr << "X axis must be linear (all bins must have the same width) ";
75 errorStr << "dx=" << xData[bin + 1] - xData[bin] << " reference dx=" << dx << " bin number=" << bin;
76 return errorStr.str();
77 } else if (m_warn && diff > m_warningLevel) {
78 // just warn the user
79 printWarning = true;
80 }
81 }
82
83 if (printWarning) {
84 g_log.warning() << "Bin widths differ by more than " << m_warningLevel * 100 << "% of average." << std::endl;
85 }
86
87 return std::string();
88}
89
97 if (m_xData.size() < 2) {
98 throw std::runtime_error("No bins in input X data");
99 }
100
102 // average bin width
103 const auto xSize = m_xData.size();
104 return (m_xData[xSize - 1] - m_xData[0]) / static_cast<double>(xSize - 1);
105 } else {
106 // first bin width
107 return m_xData[1] - m_xData[0];
108 }
109}
110
118double EqualBinsChecker::getDifference(const size_t bin, const double dx) const {
119 if (bin > m_xData.size() - 2) {
120 throw std::invalid_argument("Not enough bins in input X data");
121 }
122
124 return std::fabs(dx - m_xData[bin + 1] + m_xData[bin]) / dx;
125 } else {
126 // cumulative errors
127 return std::fabs((m_xData[bin + 1] - m_xData[0] - static_cast<double>(bin + 1) * dx) / dx);
128 }
129}
130
131} // namespace Mantid::Kernel
virtual double getDifference(const size_t bin, const double dx) const
Returns the error (simple or cumulative) at the given point.
virtual double getReferenceDx() const
Returns the bin width to compare against: either the average or the first depending on options.
virtual std::string validate() const
Perform validation of the given X array.
virtual void setErrorType(const ErrorType &errorType)
Set whether to use cumulative errors or compare each in turn.
ErrorType
Type of errors to check.
ReferenceBin
Type of bin to compare others to.
std::span< double const > const m_xData
EqualBinsChecker(std::span< double const > xData, const double errorLevel, const double warningLevel=-1)
Constructor, setting data and thresholds for errors and warnings.
virtual void setReferenceBin(const ReferenceBin &refBinType)
Set whether to compare each bin to the first bin width or the average.
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition Logger.h:51
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
Kernel::Logger g_log("DetermineSpinStateOrder")