From 6d916406008ccd6bd659e1e439044f8769f77b69 Mon Sep 17 00:00:00 2001 From: rboston628 Date: Tue, 22 Oct 2024 10:39:27 -0400 Subject: [PATCH] replace comparisons with floating point ops --- Framework/API/src/MatrixWorkspace.cpp | 2 +- Framework/API/src/NumericAxis.cpp | 8 ++++- Framework/API/src/WorkspaceOpOverloads.cpp | 10 +++--- .../CalculateCarpenterSampleCorrection.cpp | 8 ++--- .../Algorithms/src/DetectorEfficiencyCor.cpp | 7 ++-- .../src/FindCenterOfMassPosition2.cpp | 8 ++--- Framework/Algorithms/src/FitPeak.cpp | 4 +-- .../Algorithms/src/He3TubeEfficiency.cpp | 9 ++--- Framework/Algorithms/src/Integration.cpp | 1 + Framework/Algorithms/src/RealFFT.cpp | 2 ++ .../SampleLogsBehaviour.cpp | 3 +- Framework/Algorithms/src/Stitch1D.cpp | 5 +-- Framework/Algorithms/src/UnwrapMonitor.cpp | 5 +-- Framework/Crystal/src/FindSXPeaksHelper.cpp | 7 ++-- Framework/Crystal/src/PredictPeaks.cpp | 13 ++++---- .../src/PDLoadCharacterizations.cpp | 12 ++----- Framework/DataHandling/src/SaveGSS.cpp | 5 ++- .../inc/MantidDataObjects/TableColumn.h | 33 ++++++++----------- Framework/Kernel/inc/MantidKernel/V3D.h | 6 ++++ Framework/Kernel/test/V3DTest.h | 1 + .../src/ComponentCreationHelper.cpp | 7 ++-- .../CMake/CppCheck_Suppressions.txt.in | 26 ++++++--------- 22 files changed, 88 insertions(+), 94 deletions(-) diff --git a/Framework/API/src/MatrixWorkspace.cpp b/Framework/API/src/MatrixWorkspace.cpp index e704a0985d07..f249209e217b 100644 --- a/Framework/API/src/MatrixWorkspace.cpp +++ b/Framework/API/src/MatrixWorkspace.cpp @@ -1951,7 +1951,7 @@ std::pair MatrixWorkspace::getXIndex(size_t i, double x, bool is auto index = static_cast(std::distance(X.begin(), ix)); if (isLeft) --index; - return std::make_pair(index, fabs((X[index] - x) / (*ix - *(ix - 1)))); + return std::make_pair(index, std::abs((X[index] - x) / (*ix - *(ix - 1)))); } } // I don't think we can ever get here diff --git a/Framework/API/src/NumericAxis.cpp b/Framework/API/src/NumericAxis.cpp index 22f0989bbd98..4b5e2babc57b 100644 --- a/Framework/API/src/NumericAxis.cpp +++ b/Framework/API/src/NumericAxis.cpp @@ -9,6 +9,7 @@ //---------------------------------------------------------------------- #include "MantidAPI/NumericAxis.h" #include "MantidKernel/Exception.h" +#include "MantidKernel/FloatingPointComparison.h" #include "MantidKernel/VectorHelper.h" #include @@ -22,12 +23,17 @@ Mantid::Kernel::Logger g_log("NumericAxis"); class EqualWithinTolerance { public: explicit EqualWithinTolerance(double tolerance) : m_tolerance(tolerance){}; + /** + * This handles NaNs and infs differently than the FloatingPointComparison operations. + * If this is not necessary, then this entire class may be replaced with + * Mantid::Kernel::withinAbsoluteDifference + */ bool operator()(double a, double b) { if (std::isnan(a) && std::isnan(b)) return true; if (std::isinf(a) && std::isinf(b)) return true; - return std::abs(a - b) <= m_tolerance; + return Mantid::Kernel::withinAbsoluteDifference(a, b, m_tolerance); } private: diff --git a/Framework/API/src/WorkspaceOpOverloads.cpp b/Framework/API/src/WorkspaceOpOverloads.cpp index 47cea3d4b05d..3d5f6df67642 100644 --- a/Framework/API/src/WorkspaceOpOverloads.cpp +++ b/Framework/API/src/WorkspaceOpOverloads.cpp @@ -13,6 +13,7 @@ #include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/WorkspaceFactory.h" #include "MantidAPI/WorkspaceGroup.h" +#include "MantidKernel/FloatingPointComparison.h" #include "MantidKernel/Property.h" #include @@ -376,10 +377,10 @@ bool WorkspaceHelpers::matchingBins(const MatrixWorkspace &ws1, const MatrixWork const double secondWS = std::accumulate(ws2.x(0).begin(), ws2.x(0).end(), 0.); if (std::abs(firstWS) < 1.0E-7 && std::abs(secondWS) < 1.0E-7) { for (size_t i = 0; i < ws1.x(0).size(); i++) { - if (std::abs(ws1.x(0)[i] - ws2.x(0)[i]) > 1.0E-7) + if (!Kernel::withinAbsoluteDifference(ws1.x(0)[i], ws2.x(0)[i], 1.0E-7)) return false; } - } else if (std::abs(firstWS - secondWS) / std::max(std::abs(firstWS), std::abs(secondWS)) > 1.0E-7) + } else if (!Kernel::withinRelativeDifference(firstWS, secondWS, 1.0E-7)) return false; // If we were only asked to check the first spectrum, return now @@ -409,11 +410,10 @@ bool WorkspaceHelpers::matchingBins(const MatrixWorkspace &ws1, const MatrixWork const double secondWSLoop = std::accumulate(ws2.x(i).begin(), ws2.x(i).end(), 0.); if (std::abs(firstWSLoop) < 1.0E-7 && std::abs(secondWSLoop) < 1.0E-7) { for (size_t j = 0; j < ws1.x(i).size(); j++) { - if (std::abs(ws1.x(i)[j] - ws2.x(i)[j]) > 1.0E-7) + if (!Kernel::withinAbsoluteDifference(ws1.x(i)[j], ws2.x(i)[j], 1.0E-7)) return false; } - } else if (std::abs(firstWSLoop - secondWSLoop) / std::max(std::abs(firstWSLoop), std::abs(secondWSLoop)) > - 1.0E-7) + } else if (!Kernel::withinRelativeDifference(firstWSLoop, secondWSLoop, 1.0E-7)) return false; } diff --git a/Framework/Algorithms/src/CalculateCarpenterSampleCorrection.cpp b/Framework/Algorithms/src/CalculateCarpenterSampleCorrection.cpp index bda9b39a19f9..281535b354ec 100644 --- a/Framework/Algorithms/src/CalculateCarpenterSampleCorrection.cpp +++ b/Framework/Algorithms/src/CalculateCarpenterSampleCorrection.cpp @@ -15,6 +15,7 @@ #include "MantidDataObjects/WorkspaceCreation.h" #include "MantidGeometry/Instrument.h" #include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/FloatingPointComparison.h" #include "MantidKernel/Material.h" #include @@ -128,12 +129,11 @@ void CalculateCarpenterSampleCorrection::exec() { const Material &sampleMaterial = inputWksp->sample().getMaterial(); if (sampleMaterial.totalScatterXSection() != 0.0) { g_log.information() << "Using material \"" << sampleMaterial.name() << "\" from workspace\n"; - if (std::abs(coeff1 - 2.8) < std::numeric_limits::epsilon()) + if (Kernel::equals(coeff1, 2.8)) coeff1 = sampleMaterial.absorbXSection(LAMBDA_REF) / LAMBDA_REF; - if ((std::abs(coeff2 - 0.0721) < std::numeric_limits::epsilon()) && - (!isEmpty(sampleMaterial.numberDensity()))) + if (Kernel::equals(coeff2, 0.0721) && !isEmpty(sampleMaterial.numberDensity())) coeff2 = sampleMaterial.numberDensity(); - if (std::abs(coeff3 - 5.1) < std::numeric_limits::epsilon()) + if (Kernel::equals(coeff3, 5.1)) coeff3 = sampleMaterial.totalScatterXSection(); } else // Save input in Sample with wrong atomic number and name { diff --git a/Framework/Algorithms/src/DetectorEfficiencyCor.cpp b/Framework/Algorithms/src/DetectorEfficiencyCor.cpp index ae7187fe744d..910187e7458a 100644 --- a/Framework/Algorithms/src/DetectorEfficiencyCor.cpp +++ b/Framework/Algorithms/src/DetectorEfficiencyCor.cpp @@ -19,6 +19,7 @@ #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/CompositeValidator.h" #include "MantidKernel/Exception.h" +#include "MantidKernel/FloatingPointComparison.h" #include "MantidKernel/PhysicalConstants.h" #include "MantidTypes/SpectrumDefinition.h" @@ -301,7 +302,7 @@ void DetectorEfficiencyCor::getDetectorGeometry(const Geometry::IDetector &det, if (it == m_shapeCache.end()) { double xDist = distToSurface(V3D(DIST_TO_UNIVERSE_EDGE, 0, 0), shape_sptr.get()); double zDist = distToSurface(V3D(0, 0, DIST_TO_UNIVERSE_EDGE), shape_sptr.get()); - if (std::abs(zDist - xDist) < 1e-8) { + if (withinAbsoluteDifference(zDist, xDist, 1e-6)) { detRadius = zDist / 2.0; detAxis = V3D(0, 1, 0); // assume radi in z and x and the axis is in the y @@ -311,7 +312,7 @@ void DetectorEfficiencyCor::getDetectorGeometry(const Geometry::IDetector &det, return; } double yDist = distToSurface(V3D(0, DIST_TO_UNIVERSE_EDGE, 0), shape_sptr.get()); - if (std::abs(yDist - zDist) < 1e-8) { + if (withinAbsoluteDifference(yDist, zDist, 1e-8)) { detRadius = yDist / 2.0; detAxis = V3D(1, 0, 0); // assume that y and z are radi of the cylinder's circular cross-section @@ -322,7 +323,7 @@ void DetectorEfficiencyCor::getDetectorGeometry(const Geometry::IDetector &det, return; } - if (std::abs(xDist - yDist) < 1e-8) { + if (withinAbsoluteDifference(xDist, yDist, 1e-8)) { detRadius = xDist / 2.0; detAxis = V3D(0, 0, 1); PARALLEL_CRITICAL(deteff_shapecachec) { diff --git a/Framework/Algorithms/src/FindCenterOfMassPosition2.cpp b/Framework/Algorithms/src/FindCenterOfMassPosition2.cpp index 522212a9f439..c01dac53ff51 100644 --- a/Framework/Algorithms/src/FindCenterOfMassPosition2.cpp +++ b/Framework/Algorithms/src/FindCenterOfMassPosition2.cpp @@ -18,6 +18,7 @@ #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/FloatingPointComparison.h" #include "MantidKernel/PhysicalConstants.h" namespace Mantid::Algorithms { @@ -29,11 +30,6 @@ using namespace API; using namespace Geometry; using namespace DataObjects; -namespace { // anonymous namespace -/// Equal within machine tolerance -bool almost_equals(const double a, const double b) { return fabs(a - b) < std::numeric_limits::min(); } -} // anonymous namespace - void FindCenterOfMassPosition2::init() { const auto wsValidator = std::make_shared(); const auto positiveDouble = std::make_shared>(); @@ -113,7 +109,7 @@ void FindCenterOfMassPosition2::findCenterOfMass(const API::MatrixWorkspace_sptr // Check to see if we have the same result // as the previous iteration - if (almost_equals(distanceFromPrevious, distanceFromPreviousPrevious)) { + if (Kernel::equals(distanceFromPrevious, distanceFromPreviousPrevious)) { totalLocalMinima++; } else { totalLocalMinima = 0; diff --git a/Framework/Algorithms/src/FitPeak.cpp b/Framework/Algorithms/src/FitPeak.cpp index aa32a557c542..33bae882ac81 100644 --- a/Framework/Algorithms/src/FitPeak.cpp +++ b/Framework/Algorithms/src/FitPeak.cpp @@ -237,7 +237,7 @@ void FitOneSinglePeak::setupGuessedFWHM(double usrwidth, int minfwhm, int maxfwh void FitOneSinglePeak::setFitPeakCriteria(bool usepeakpostol, double peakpostol) { m_usePeakPositionTolerance = usepeakpostol; if (usepeakpostol) { - m_peakPositionTolerance = fabs(peakpostol); + m_peakPositionTolerance = std::abs(peakpostol); if (peakpostol < 1.0E-13) g_log.warning("Peak position tolerance is very tight. "); } @@ -931,7 +931,7 @@ void FitOneSinglePeak::processNStoreFitResult(double rwp, bool storebkgd) { double f_centre = m_peakFunc->centre(); if (m_usePeakPositionTolerance) { // Peak position criteria is on position tolerance - if (fabs(f_centre - m_userPeakCentre) > m_peakPositionTolerance) { + if (!Kernel::withinAbsoluteDifference(f_centre, m_userPeakCentre, m_peakPositionTolerance)) { rwp = DBL_MAX; failreason = "Peak centre out of tolerance. "; fitsuccess = false; diff --git a/Framework/Algorithms/src/He3TubeEfficiency.cpp b/Framework/Algorithms/src/He3TubeEfficiency.cpp index 48c1ebbeff78..d485891a61df 100644 --- a/Framework/Algorithms/src/He3TubeEfficiency.cpp +++ b/Framework/Algorithms/src/He3TubeEfficiency.cpp @@ -20,6 +20,7 @@ #include "MantidKernel/ArrayBoundedValidator.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/FloatingPointComparison.h" #include #include @@ -216,7 +217,7 @@ double He3TubeEfficiency::calculateExponential(std::size_t spectraIndex, const G double sinTheta = std::sqrt(1.0 - cosTheta * cosTheta); const double straight_path = detDiameter - twiceTubeThickness; - if (std::fabs(straight_path - 0.0) < TOL) { + if (Kernel::withinAbsoluteDifference(straight_path, 0.0, TOL)) { throw std::out_of_range("Twice tube thickness cannot be greater than " "or equal to the tube diameter"); } @@ -245,7 +246,7 @@ void He3TubeEfficiency::getDetectorGeometry(const Geometry::IDetector &det, doub if (it == m_shapeCache.end()) { double xDist = distToSurface(Kernel::V3D(DIST_TO_UNIVERSE_EDGE, 0, 0), shape_sptr.get()); double zDist = distToSurface(Kernel::V3D(0, 0, DIST_TO_UNIVERSE_EDGE), shape_sptr.get()); - if (std::abs(zDist - xDist) < 1e-8) { + if (Kernel::withinAbsoluteDifference(zDist, xDist, 1e-8)) { detRadius = zDist / 2.0; detAxis = Kernel::V3D(0, 1, 0); // assume radii in z and x and the axis is in the y @@ -253,7 +254,7 @@ void He3TubeEfficiency::getDetectorGeometry(const Geometry::IDetector &det, doub return; } double yDist = distToSurface(Kernel::V3D(0, DIST_TO_UNIVERSE_EDGE, 0), shape_sptr.get()); - if (std::abs(yDist - zDist) < 1e-8) { + if (Kernel::withinAbsoluteDifference(yDist, zDist, 1e-8)) { detRadius = yDist / 2.0; detAxis = Kernel::V3D(1, 0, 0); // assume that y and z are radii of the cylinder's circular cross-section @@ -262,7 +263,7 @@ void He3TubeEfficiency::getDetectorGeometry(const Geometry::IDetector &det, doub return; } - if (std::abs(xDist - yDist) < 1e-8) { + if (Kernel::withinAbsoluteDifference(xDist, yDist, 1e-8)) { detRadius = xDist / 2.0; detAxis = Kernel::V3D(0, 0, 1); PARALLEL_CRITICAL(deteff_shapecachec) { m_shapeCache.insert({shape_sptr.get(), {detRadius, detAxis}}); } diff --git a/Framework/Algorithms/src/Integration.cpp b/Framework/Algorithms/src/Integration.cpp index ed60de63ace6..e232cc1fd6ae 100644 --- a/Framework/Algorithms/src/Integration.cpp +++ b/Framework/Algorithms/src/Integration.cpp @@ -68,6 +68,7 @@ struct tolerant_less { bool operator()(const double &left, const double &right) const { // soft equal, if the diff left-right is below a numerical error // (uncertainty) threshold, we cannot say + // NOTE this could perhaps use FloatingPointComparison::equal operation return (left < right) && (std::abs(left - right) > 1 * std::numeric_limits::epsilon()); } }; diff --git a/Framework/Algorithms/src/RealFFT.cpp b/Framework/Algorithms/src/RealFFT.cpp index afa8e35b0f6e..32d2c2b70e65 100644 --- a/Framework/Algorithms/src/RealFFT.cpp +++ b/Framework/Algorithms/src/RealFFT.cpp @@ -79,6 +79,8 @@ void RealFFT::exec() { double dx = (X.back() - X.front()) / static_cast(X.size() - 1); if (!IgnoreXBins) { for (size_t i = 0; i < X.size() - 2; i++) + // note this cannot be replaced with Kernel::withinRelativeDifference, + // or fails to detect some errors if (std::abs(dx - X[i + 1] + X[i]) / dx > 1e-7) throw std::invalid_argument("X axis must be linear (all bins have same " "width). This can be ignored if " diff --git a/Framework/Algorithms/src/RunCombinationHelpers/SampleLogsBehaviour.cpp b/Framework/Algorithms/src/RunCombinationHelpers/SampleLogsBehaviour.cpp index 95b03bc7c097..b11b3a2e742d 100644 --- a/Framework/Algorithms/src/RunCombinationHelpers/SampleLogsBehaviour.cpp +++ b/Framework/Algorithms/src/RunCombinationHelpers/SampleLogsBehaviour.cpp @@ -10,6 +10,7 @@ #include "MantidAPI/Run.h" #include "MantidAlgorithms/RunCombinationHelpers/SampleLogsBehaviour.h" #include "MantidGeometry/Instrument.h" +#include "MantidKernel/FloatingPointComparison.h" #include "MantidKernel/Property.h" #include "MantidKernel/StringTokenizer.h" #include "MantidKernel/Strings.h" @@ -531,7 +532,7 @@ void SampleLogsBehaviour::checkErrorProperty(const MatrixWorkspace &addeeWS, Pro bool SampleLogsBehaviour::isWithinTolerance(const SampleLogBehaviour &behaviour, const double addeeWSNumericValue, const double outWSNumericValue) { if (behaviour.isNumeric && behaviour.tolerance > 0.0) { - return std::abs(addeeWSNumericValue - outWSNumericValue) < behaviour.tolerance; + return Kernel::withinAbsoluteDifference(addeeWSNumericValue, outWSNumericValue, behaviour.tolerance); } return false; diff --git a/Framework/Algorithms/src/Stitch1D.cpp b/Framework/Algorithms/src/Stitch1D.cpp index 0fa8f61ab032..c23abacb4604 100644 --- a/Framework/Algorithms/src/Stitch1D.cpp +++ b/Framework/Algorithms/src/Stitch1D.cpp @@ -16,6 +16,7 @@ #include "MantidHistogramData/HistogramY.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/FloatingPointComparison.h" #include "MantidKernel/MultiThreaded.h" #include "MantidKernel/PropertyWithValue.h" #include "MantidKernel/RebinParamsValidator.h" @@ -491,10 +492,10 @@ void Stitch1D::exec() { const double xMin = params.front(); const double xMax = params.back(); - if (std::abs(xMin - startOverlap) < 1E-6) + if (Kernel::withinAbsoluteDifference(xMin, startOverlap, 1E-6)) startOverlap = xMin; - if (std::abs(xMax - endOverlap) < 1E-6) + if (Kernel::withinAbsoluteDifference(xMax, endOverlap, 1E-6)) endOverlap = xMax; if (startOverlap < xMin) { diff --git a/Framework/Algorithms/src/UnwrapMonitor.cpp b/Framework/Algorithms/src/UnwrapMonitor.cpp index 754d34d7a27d..55b65c13d475 100644 --- a/Framework/Algorithms/src/UnwrapMonitor.cpp +++ b/Framework/Algorithms/src/UnwrapMonitor.cpp @@ -16,6 +16,7 @@ #include "MantidGeometry/Instrument.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/FloatingPointComparison.h" #include "MantidKernel/PhysicalConstants.h" #include "MantidKernel/UnitFactory.h" @@ -204,7 +205,7 @@ const std::vector UnwrapMonitor::unwrapX(std::vector &newX, const i const double wavelength = m_conversionConstant / velocity; newX.emplace_back(wavelength); // Remove the duplicate boundary bin - if (tof == m_Tmax && std::abs(wavelength - tempX_L.front()) < 1.0e-5) + if (tof == m_Tmax && Kernel::withinAbsoluteDifference(wavelength, tempX_L.front(), 1.0e-5)) newX.pop_back(); // Record the bins that fall in this range for copying over the data & // errors @@ -223,7 +224,7 @@ const std::vector UnwrapMonitor::unwrapX(std::vector &newX, const i // Record the point at which the unwrapped sections are joined, first time // through only - Property *join = getProperty("JoinWavelength"); + Property const *join = getProperty("JoinWavelength"); if (join->isDefault()) { g_log.information() << "Joining wavelength: " << tempX_L.front() << " Angstrom\n"; setProperty("JoinWavelength", tempX_L.front()); diff --git a/Framework/Crystal/src/FindSXPeaksHelper.cpp b/Framework/Crystal/src/FindSXPeaksHelper.cpp index 559e7a850f22..268cba7eb6a2 100644 --- a/Framework/Crystal/src/FindSXPeaksHelper.cpp +++ b/Framework/Crystal/src/FindSXPeaksHelper.cpp @@ -8,6 +8,7 @@ #include "MantidAPI/Progress.h" #include "MantidGeometry/Instrument/DetectorGroup.h" #include "MantidKernel/ConfigService.h" +#include "MantidKernel/FloatingPointComparison.h" #include "MantidKernel/Logger.h" #include "MantidKernel/PhysicalConstants.h" #include "MantidKernel/Unit.h" @@ -118,11 +119,11 @@ Object comparision @param tolerance : tolerance */ bool SXPeak::compare(const SXPeak &rhs, double tolerance) const { - if (std::abs(m_tof / m_nPixels - rhs.m_tof / rhs.m_nPixels) > tolerance * m_tof / m_nPixels) + if (!Kernel::withinRelativeDifference(m_tof / m_nPixels, rhs.m_tof / rhs.m_nPixels, tolerance)) return false; - if (std::abs(m_phi / m_nPixels - rhs.m_phi / rhs.m_nPixels) > tolerance * m_phi / m_nPixels) + if (!Kernel::withinRelativeDifference(m_phi / m_nPixels, rhs.m_phi / rhs.m_nPixels, tolerance)) return false; - if (std::abs(m_twoTheta / m_nPixels - rhs.m_twoTheta / rhs.m_nPixels) > tolerance * m_twoTheta / m_nPixels) + if (!Kernel::withinRelativeDifference(m_twoTheta / m_nPixels, rhs.m_twoTheta / rhs.m_nPixels, tolerance)) return false; return true; } diff --git a/Framework/Crystal/src/PredictPeaks.cpp b/Framework/Crystal/src/PredictPeaks.cpp index 6ae473ec5013..3ff9922c4013 100644 --- a/Framework/Crystal/src/PredictPeaks.cpp +++ b/Framework/Crystal/src/PredictPeaks.cpp @@ -25,6 +25,7 @@ #include "MantidGeometry/Objects/InstrumentRayTracer.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/EnabledWhenProperty.h" +#include "MantidKernel/FloatingPointComparison.h" #include "MantidKernel/ListValidator.h" #include @@ -201,7 +202,7 @@ void PredictPeaks::exec() { // Get all goniometer matrices DblMatrix lastGoniometerMatrix = Matrix(3, 3, false); for (int i = 0; i < static_cast(peaksWS->getNumberPeaks()); ++i) { - IPeak &p = peaksWS->getPeak(i); + IPeak const &p = peaksWS->getPeak(i); DblMatrix currentGoniometerMatrix = p.getGoniometerMatrix(); if (!(currentGoniometerMatrix == lastGoniometerMatrix)) { gonioVec.emplace_back(currentGoniometerMatrix); @@ -289,7 +290,7 @@ void PredictPeaks::exec() { m_detectorCacheSearch = std::make_unique(m_inst, m_pw->detectorInfo()); if (!usingInstrument) { - for (auto &possibleHKL : possibleHKLs) { + for (auto const &possibleHKL : possibleHKLs) { calculateQAndAddToOutputLeanElastic(possibleHKL, ub); } } else if (getProperty("CalculateGoniometerForCW")) { @@ -329,7 +330,7 @@ void PredictPeaks::exec() { if (!std::isfinite(angle) || angle < angleMin || angle > angleMax) continue; - if (std::abs(wavelength - lambda) < 0.01) { + if (Kernel::withinAbsoluteDifference(wavelength, lambda, 0.01)) { g_log.information() << "Found goniometer rotation to be in YZY convention [" << angles[0] << ", " << angles[1] << ". " << angles[2] << "] degrees for Q sample = " << q_sample << "\n"; calculateQAndAddToOutput(possibleHKL, orientedUB, goniometer.getR()); @@ -341,7 +342,7 @@ void PredictPeaks::exec() { logNumberOfPeaksFound(allowedPeakCount); } else { - for (auto &goniometerMatrix : gonioVec) { + for (auto const &goniometerMatrix : gonioVec) { // Final transformation matrix (HKL to Q in lab frame) DblMatrix orientedUB = goniometerMatrix * ub; @@ -357,7 +358,7 @@ void PredictPeaks::exec() { "no extended detector space has been defined\n"; } - for (auto &possibleHKL : possibleHKLs) { + for (auto const &possibleHKL : possibleHKLs) { if (lambdaFilter.isAllowed(possibleHKL)) { calculateQAndAddToOutput(possibleHKL, orientedUB, goniometerMatrix); ++allowedPeakCount; @@ -503,7 +504,7 @@ void PredictPeaks::fillPossibleHKLsUsingPeaksWorkspace(const IPeaksWorkspace_spt double peaks_q_convention_factor = qConventionFactor(peaksWorkspace->getConvention()); for (int i = 0; i < static_cast(peaksWorkspace->getNumberPeaks()); ++i) { - IPeak &p = peaksWorkspace->getPeak(i); + IPeak const &p = peaksWorkspace->getPeak(i); // Get HKL from that peak V3D hkl = p.getHKL() * peaks_q_convention_factor; diff --git a/Framework/DataHandling/src/PDLoadCharacterizations.cpp b/Framework/DataHandling/src/PDLoadCharacterizations.cpp index 6a2fb1a53e51..81fc1199ae11 100644 --- a/Framework/DataHandling/src/PDLoadCharacterizations.cpp +++ b/Framework/DataHandling/src/PDLoadCharacterizations.cpp @@ -11,6 +11,7 @@ #include "MantidAPI/TableRow.h" #include "MantidAPI/WorkspaceFactory.h" #include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/FloatingPointComparison.h" #include "MantidKernel/Property.h" #include "MantidKernel/StringTokenizer.h" #include "MantidKernel/Strings.h" @@ -419,16 +420,7 @@ void PDLoadCharacterizations::readVersion0(const std::string &filename, API::ITa } namespace { -bool closeEnough(const double left, const double right) { - // the same value - const double diff = fabs(left - right); - if (diff == 0.) - return true; - - // same within 5% - const double relativeDiff = diff * 2 / (left + right); - return relativeDiff < .05; -} +bool closeEnough(const double left, const double right) { return Kernel::withinRelativeDifference(left, right, 0.05); } int findRow(API::ITableWorkspace_sptr &wksp, const std::vector &values) { // don't have a good way to mark error location in these casts diff --git a/Framework/DataHandling/src/SaveGSS.cpp b/Framework/DataHandling/src/SaveGSS.cpp index a33c3fb94cc7..36cc3abc14ad 100644 --- a/Framework/DataHandling/src/SaveGSS.cpp +++ b/Framework/DataHandling/src/SaveGSS.cpp @@ -16,6 +16,7 @@ #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/CompositeValidator.h" #include "MantidKernel/Exception.h" +#include "MantidKernel/FloatingPointComparison.h" #include "MantidKernel/ListValidator.h" #include "MantidKernel/PhysicalConstants.h" #include "MantidKernel/TimeSeriesProperty.h" @@ -67,9 +68,7 @@ double fixErrorValue(const double value) { } bool isEqual(const double left, const double right) { - if (left == right) - return true; - return (2. * std::fabs(left - right) <= std::fabs(m_TOLERANCE * (right + left))); + return Kernel::withinRelativeDifference(left, right, m_TOLERANCE); } bool isConstantDelta(const HistogramData::BinEdges &xAxis) { diff --git a/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h b/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h index 2827ac4b5f2d..9478aa7c517b 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h +++ b/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h @@ -299,13 +299,14 @@ inline bool TableColumn::compareVectors(const std::vector inline bool TableColumn::compareVectors(const std::vector &newVector, double tolerance, - bool const) const { + bool const nanEqual) const { for (size_t i = 0; i < m_data.size(); i++) { - double dif_x = fabs(m_data[i].X() - newVector[i].X()); - double dif_y = fabs(m_data[i].Y() - newVector[i].Y()); - double dif_z = fabs(m_data[i].Z() - newVector[i].Z()); - if (dif_x > tolerance || dif_y > tolerance || dif_z > tolerance) { - return false; + for (std::size_t xyz = 0; xyz < m_data[i].size(); xyz++) { + double left = m_data[i][xyz], right = newVector[i][xyz]; + if (nanEqual && std::isnan(left) && isnan(right)) + continue; + else if (!Kernel::withinAbsoluteDifference(left, right, tolerance)) + return false; } } return true; @@ -328,22 +329,14 @@ inline bool TableColumn::compareVectorsRelError(const std::vector< /// Template specialisation for V3D for comparison template <> inline bool TableColumn::compareVectorsRelError(const std::vector &newVector, - double tolerance, bool const) const { + double tolerance, bool const nanEqual) const { for (size_t i = 0; i < m_data.size(); i++) { - double dif_x = fabs(m_data[i].X() - newVector[i].X()); - double dif_y = fabs(m_data[i].Y() - newVector[i].Y()); - double dif_z = fabs(m_data[i].Z() - newVector[i].Z()); - double den_x = 0.5 * (fabs(m_data[i].X()) + fabs(newVector[i].X())); - double den_y = 0.5 * (fabs(m_data[i].X()) + fabs(newVector[i].X())); - double den_z = 0.5 * (fabs(m_data[i].X()) + fabs(newVector[i].X())); - if (den_x > tolerance || den_y > tolerance || den_z > tolerance) { - if (dif_x / den_x > tolerance || dif_y / den_y > tolerance || dif_z / den_z > tolerance) { - return false; - } - } else { - if (dif_x > tolerance || dif_y > tolerance || dif_z > tolerance) { + for (std::size_t xyz = 0; xyz < m_data[i].size(); xyz++) { + double left = m_data[i][xyz], right = newVector[i][xyz]; + if (nanEqual && std::isnan(left) && isnan(right)) + continue; + else if (!Kernel::withinRelativeDifference(m_data[i][xyz], newVector[i][xyz], tolerance)) return false; - } } } return true; diff --git a/Framework/Kernel/inc/MantidKernel/V3D.h b/Framework/Kernel/inc/MantidKernel/V3D.h index 073b0ba58ae4..c8da1e58bf8d 100644 --- a/Framework/Kernel/inc/MantidKernel/V3D.h +++ b/Framework/Kernel/inc/MantidKernel/V3D.h @@ -42,6 +42,12 @@ class MANTID_KERNEL_DLL V3D final { // explicit conversion into vector operator std::vector() const { return std::vector(m_pt.cbegin(), m_pt.cend()); } + /** + Number of components in V3D + @return 3 + */ + std::size_t size() const noexcept { return m_pt.size(); } + /** Addtion operator @param v :: Vector to add diff --git a/Framework/Kernel/test/V3DTest.h b/Framework/Kernel/test/V3DTest.h index 72b275fe670f..3605e3183c01 100644 --- a/Framework/Kernel/test/V3DTest.h +++ b/Framework/Kernel/test/V3DTest.h @@ -23,6 +23,7 @@ class V3DTest : public CxxTest::TestSuite { Mantid::Kernel::V3D a, b, c, d; public: + void testSize() { TS_ASSERT_EQUALS(a.size(), 3); } void testEmptyConstructor() { // very important as a MD geometry rely on it later TS_ASSERT_EQUALS(a.X(), 0.0); diff --git a/Framework/TestHelpers/src/ComponentCreationHelper.cpp b/Framework/TestHelpers/src/ComponentCreationHelper.cpp index 40013cc7552a..1786df0efcd0 100644 --- a/Framework/TestHelpers/src/ComponentCreationHelper.cpp +++ b/Framework/TestHelpers/src/ComponentCreationHelper.cpp @@ -30,6 +30,7 @@ #include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidKernel/ConfigService.h" #include "MantidKernel/DateAndTime.h" +#include "MantidKernel/FloatingPointComparison.h" #include "MantidKernel/Matrix.h" #include "MantidKernel/Quat.h" #include "MantidKernel/UnitFactory.h" @@ -426,11 +427,7 @@ createCylInstrumentWithVerticalOffsetsSpecified(size_t nTubes, std::vector &L2, const std::vector &polar, diff --git a/buildconfig/CMake/CppCheck_Suppressions.txt.in b/buildconfig/CMake/CppCheck_Suppressions.txt.in index 5771b38af2c6..442dd100e5b2 100644 --- a/buildconfig/CMake/CppCheck_Suppressions.txt.in +++ b/buildconfig/CMake/CppCheck_Suppressions.txt.in @@ -240,7 +240,7 @@ uselessOverride:${CMAKE_SOURCE_DIR}/Framework/Algorithms/inc/MantidAlgorithms/In uselessOverride:${CMAKE_SOURCE_DIR}/Framework/Algorithms/inc/MantidAlgorithms/InterpolatingRebin.h:71 passedByValue:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/GeneratePeaks.cpp:662 constVariableReference:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/GeneratePeaks.cpp:518 -shadowVariable:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/He3TubeEfficiency.cpp:373 +shadowVariable:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/He3TubeEfficiency.cpp:374 knownConditionTrueFalse:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/FindPeaks.cpp:892 knownConditionTrueFalse:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/FindPeaks.cpp:999 unreadVariable:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/InterpolatingRebin.cpp:69 @@ -305,8 +305,8 @@ uselessOverride:${CMAKE_SOURCE_DIR}/Framework/Algorithms/inc/MantidAlgorithms/Re constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/SANSCollimationLengthEstimator.cpp:172 constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/SANSCollimationLengthEstimator.cpp:174 constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/RingProfile.cpp:338 -constParameterPointer:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/RunCombinationHelpers/SampleLogsBehaviour.cpp:484 -constParameterPointer:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/RunCombinationHelpers/SampleLogsBehaviour.cpp:510 +constParameterPointer:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/RunCombinationHelpers/SampleLogsBehaviour.cpp:485 +constParameterPointer:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/RunCombinationHelpers/SampleLogsBehaviour.cpp:511 constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/ShiftLogTime.cpp:61 constParameterPointer:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/SofQCommon.cpp:25 containerOutOfBounds:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/SampleCorrections/SparseWorkspace.cpp:32 @@ -346,7 +346,6 @@ constParameterPointer:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/UnwrapMonitor missingOverride:${CMAKE_SOURCE_DIR}/Framework/API/inc/MantidAPI/BoxControllerSettingsAlgorithm.h:43 constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/API/src/BoxControllerSettingsAlgorithm.cpp:78 uselessOverride:${CMAKE_SOURCE_DIR}/Framework/Algorithms/inc/MantidAlgorithms/SofQWNormalisedPolygon.h:55 -constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/UnwrapMonitor.cpp:226 constVariableReference:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp:537 missingOverride:${CMAKE_SOURCE_DIR}/Framework/Algorithms/inc/MantidAlgorithms/XrayAbsorptionCorrection.h:36 returnByReference:${CMAKE_SOURCE_DIR}/Framework/API/inc/MantidAPI/IMDWorkspace.h:92 @@ -362,7 +361,7 @@ unreadVariable:${CMAKE_SOURCE_DIR}/Framework/Algorithms/src/WeightedMeanOfWorksp constVariableReference:${CMAKE_SOURCE_DIR}/Framework/API/src/IMDEventWorkspace.cpp:50 constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/API/src/IMDEventWorkspace.cpp:85 constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/API/src/IMDEventWorkspace.cpp:92 -unreadVariable:${CMAKE_SOURCE_DIR}/Framework/API/src/NumericAxis.cpp:160 +unreadVariable:${CMAKE_SOURCE_DIR}/Framework/API/src/NumericAxis.cpp:166 constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/API/src/ParameterReference.cpp:52 constVariableReference:${CMAKE_SOURCE_DIR}/Framework/API/src/MultiDomainFunction.cpp:135 constVariableReference:${CMAKE_SOURCE_DIR}/Framework/API/src/MultiDomainFunction.cpp:174 @@ -462,12 +461,7 @@ constVariableReference:${CMAKE_SOURCE_DIR}/Framework/CurveFitting/src/Algorithms constVariableReference:${CMAKE_SOURCE_DIR}/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp:408 constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp:362 constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp:389 -constVariableReference:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/PredictPeaks.cpp:204 -constVariableReference:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/PredictPeaks.cpp:292 -constVariableReference:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/PredictPeaks.cpp:311 -constVariableReference:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/PredictPeaks.cpp:344 -constVariableReference:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/PredictPeaks.cpp:360 -constVariableReference:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/PredictPeaks.cpp:506 +constVariableReference:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/PredictPeaks.cpp:312 passedByValue:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/SaveIsawPeaks.cpp:508 constVariableReference:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/PeakIntegration.cpp:105 shadowVariable:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/SCDCalibratePanels.cpp:189 @@ -542,9 +536,9 @@ constVariableReference:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/IntegratePeakTi constVariableReference:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/IntegratePeakTimeSlices.cpp:1469 constVariableReference:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/IntegratePeakTimeSlices.cpp:1471 constParameterReference:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/IntegratePeakTimeSlices.cpp:1835 -variableScope:${CMAKE_SOURCE_DIR}/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters3.cpp:1300 constVariable:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/IntegratePeakTimeSlices.cpp:1049 constVariable:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/IntegratePeakTimeSlices.cpp:2388 +variableScope:${CMAKE_SOURCE_DIR}/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters3.cpp:1300 passedByValue:${CMAKE_SOURCE_DIR}/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters3.cpp:1201 passedByValue:${CMAKE_SOURCE_DIR}/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters3.cpp:1219 constVariableReference:${CMAKE_SOURCE_DIR}/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters3.cpp:662 @@ -761,8 +755,8 @@ uninitMemberVarPrivate:${CMAKE_SOURCE_DIR}/Framework/DataHandling/inc/MantidData uselessOverride:${CMAKE_SOURCE_DIR}/Framework/DataHandling/inc/MantidDataHandling/SaveNexusESS.h:26 uselessOverride:${CMAKE_SOURCE_DIR}/Framework/DataHandling/inc/MantidDataHandling/SaveNexusESS.h:27 knownConditionTrueFalse:${CMAKE_SOURCE_DIR}/Framework/DataHandling/src/SaveIsawDetCal.cpp:110 -constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/DataHandling/src/SaveGSS.cpp:433 -constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/DataHandling/src/SaveGSS.cpp:567 +constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/DataHandling/src/SaveGSS.cpp:432 +constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/DataHandling/src/SaveGSS.cpp:566 constVariableReference:${CMAKE_SOURCE_DIR}/Framework/DataHandling/src/SaveNXTomo.cpp:150 shadowVariable:${CMAKE_SOURCE_DIR}/Framework/DataHandling/src/LoadTOFRawNexus.cpp:285 shadowVariable:${CMAKE_SOURCE_DIR}/Framework/DataHandling/src/LoadTOFRawNexus.cpp:357 @@ -1048,8 +1042,8 @@ unusedScopedObject:${CMAKE_SOURCE_DIR}/Framework/PythonInterface/mantid/dataobje unusedScopedObject:${CMAKE_SOURCE_DIR}/Framework/PythonInterface/mantid/dataobjects/src/Exports/SpecialWorkspace2D.cpp:57 unusedScopedObject:${CMAKE_SOURCE_DIR}/Framework/PythonInterface/mantid/dataobjects/src/Exports/WorkspaceSingleValue.cpp:24 unusedScopedObject:${CMAKE_SOURCE_DIR}/Framework/PythonInterface/mantid/dataobjects/src/Exports/RebinnedOutput.cpp:84 -passedByValue:${CMAKE_SOURCE_DIR}/Framework/TestHelpers/src/ComponentCreationHelper.cpp:383 -unreadVariable:${CMAKE_SOURCE_DIR}/Framework/TestHelpers/src/ComponentCreationHelper.cpp:411 +passedByValue:${CMAKE_SOURCE_DIR}/Framework/TestHelpers/src/ComponentCreationHelper.cpp:384 +unreadVariable:${CMAKE_SOURCE_DIR}/Framework/TestHelpers/src/ComponentCreationHelper.cpp:412 unusedScopedObject:${CMAKE_SOURCE_DIR}/Framework/PythonInterface/mantid/dataobjects/src/Exports/OffsetsWorkspace.cpp:23 unusedScopedObject:${CMAKE_SOURCE_DIR}/Framework/PythonInterface/mantid/dataobjects/src/Exports/GroupingWorkspace.cpp:42 unusedScopedObject:${CMAKE_SOURCE_DIR}/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp:173