diff --git a/Framework/Algorithms/test/Rebin2DTest.h b/Framework/Algorithms/test/Rebin2DTest.h index 015b5e11b6e8a5a1d25f1eb930dd08f5c4fd84ef..6509fe9f5767f8ec28842c3dee77d665074c64f2 100644 --- a/Framework/Algorithms/test/Rebin2DTest.h +++ b/Framework/Algorithms/test/Rebin2DTest.h @@ -7,8 +7,9 @@ #ifndef MANTID_ALGORITHMS_REBIN2DTEST_H_ #define MANTID_ALGORITHMS_REBIN2DTEST_H_ -#include "MantidAlgorithms/Rebin2D.h" #include "MantidAPI/BinEdgeAxis.h" +#include "MantidAlgorithms/Rebin2D.h" +#include "MantidDataObjects/RebinnedOutput.h" #include "MantidTestHelpers/WorkspaceCreationHelper.h" #include <cxxtest/TestSuite.h> @@ -16,6 +17,7 @@ using Mantid::Algorithms::Rebin2D; using namespace Mantid::API; +using namespace Mantid::DataObjects; namespace { /** @@ -193,12 +195,17 @@ public: const auto midValue = thetaAxis->getValue(middle); thetaAxis->setValue(middle - 1, midValue); constexpr bool useFractionalBinning = false; - MatrixWorkspace_sptr outputWS = - runAlgorithm(inputWS, "5.,2.,15.", "-0.5,10.,9.5", useFractionalBinning); + MatrixWorkspace_sptr outputWS = runAlgorithm( + inputWS, "5.,2.,15.", "-0.5,10.,9.5", useFractionalBinning); TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 1) + const auto expectedY = 2. * 9. * 2.; + const auto expectedE = std::sqrt(expectedY); const auto &Ys = outputWS->y(0); - for (size_t j = 0; j < Ys.size(); ++j) { - TS_ASSERT(!std::isnan(Ys[j])) + const auto &Es = outputWS->e(0); + for (size_t i = 0; i < Ys.size(); ++i) { + TS_ASSERT(!std::isnan(Ys[i])) + TS_ASSERT_DELTA(Ys[i], expectedY, 1e-12) + TS_ASSERT_DELTA(Es[i], expectedE, 1e-12) } } @@ -211,12 +218,19 @@ public: const auto midValue = thetaAxis->getValue(middle); thetaAxis->setValue(middle - 1, midValue); constexpr bool useFractionalBinning = true; - MatrixWorkspace_sptr outputWS = - runAlgorithm(inputWS, "5.,2.,15.", "-0.5,10.,9.5", useFractionalBinning); - TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 1) - const auto &Ys = outputWS->y(0); - for (size_t j = 0; j < Ys.size(); ++j) { - TS_ASSERT(!std::isnan(Ys[j])) + MatrixWorkspace_sptr outputWS = runAlgorithm( + inputWS, "5.,2.,15.", "-0.5,10.,9.5", useFractionalBinning); + const auto &rebinned = *dynamic_cast<RebinnedOutput *>(outputWS.get()); + TS_ASSERT_EQUALS(rebinned.getNumberHistograms(), 1) + const auto expectedY = 2. * 9. * 2.; + const auto expectedE = std::sqrt(expectedY); + const auto &Fs = rebinned.dataF(0); + const auto &Ys = rebinned.y(0); + const auto &Es = rebinned.e(0); + for (size_t i = 0; i < Ys.size(); ++i) { + TS_ASSERT(!std::isnan(Ys[i])) + TS_ASSERT_DELTA(Ys[i] * Fs[i], expectedY, 1e-12) + TS_ASSERT_DELTA(Es[i] * Fs[i], expectedE, 1e-12) } } @@ -307,7 +321,8 @@ public: void test_Use_Fractional_Area() { constexpr bool useFractionalArea = true; - runAlgorithm(m_inputWS, "100,10,41000", "-0.5,0.5,499.5", useFractionalArea); + runAlgorithm(m_inputWS, "100,10,41000", "-0.5,0.5,499.5", + useFractionalArea); } private: diff --git a/Framework/DataObjects/src/FractionalRebinning.cpp b/Framework/DataObjects/src/FractionalRebinning.cpp index 2dfe63eeb30dff937e11a5cef53e009069368fb9..8869b8aa370a4288467541599117affac860985c 100644 --- a/Framework/DataObjects/src/FractionalRebinning.cpp +++ b/Framework/DataObjects/src/FractionalRebinning.cpp @@ -552,6 +552,8 @@ void rebinToOutput(const Quadrilateral &inputQ, for (size_t y = qstart; y < qend; ++y) { const double vlo = verticalAxis[y]; const double vhi = verticalAxis[y + 1]; + auto &outY = outputWS.mutableY(y); + auto &outE = outputWS.mutableE(y); for (size_t xi = x_start; xi < x_end; ++xi) { const V2D ll(X[xi], vlo); const V2D lr(X[xi + 1], vlo); @@ -565,7 +567,11 @@ void rebinToOutput(const Quadrilateral &inputQ, } intersectOverlap.clear(); if (intersection(outputQ, inputQ, intersectOverlap)) { - const double weight = intersectOverlap.area() / inputQ.area(); + const double overlapArea = intersectOverlap.area(); + if (overlapArea == 0.) { + continue; + } + const double weight = overlapArea / inputQ.area(); yValue *= weight; double eValue = inE[j]; if (inputWS->isDistribution()) { @@ -576,8 +582,8 @@ void rebinToOutput(const Quadrilateral &inputQ, } eValue = eValue * eValue * weight; PARALLEL_CRITICAL(overlap_sum) { - outputWS.mutableY(y)[xi] += yValue; - outputWS.mutableE(y)[xi] += eValue; + outY[xi] += yValue; + outE[xi] += eValue; } } } @@ -667,6 +673,9 @@ void rebinToFractionalOutput(const Quadrilateral &inputQ, const double variance = error * error; for (const auto &ai : areaInfos) { + if (ai.weight == 0.) { + continue; + } const double weight = ai.weight / inputQArea; PARALLEL_CRITICAL(overlap) { outputWS.mutableY(ai.wsIndex)[ai.binIndex] += signal * weight; diff --git a/Framework/Kernel/src/VectorHelper.cpp b/Framework/Kernel/src/VectorHelper.cpp index 223fc4fec9d98da0f2d6a23b745f5bcc627d35ad..0c7d9638c31c42e745ca54648cb47cea24e2c656 100644 --- a/Framework/Kernel/src/VectorHelper.cpp +++ b/Framework/Kernel/src/VectorHelper.cpp @@ -391,7 +391,7 @@ void convertToBinCentre(const std::vector<double> &bin_edges, */ void convertToBinBoundary(const std::vector<double> &bin_centers, std::vector<double> &bin_edges) { - const std::vector<double>::size_type n = bin_centers.size(); + const auto n = bin_centers.size(); // Special case empty input: output is also empty if (n == 0) {