diff --git a/Framework/API/inc/MantidAPI/MatrixWorkspace.h b/Framework/API/inc/MantidAPI/MatrixWorkspace.h index 9377027226e6eeb8ce4a2879b76a77dd72a66904..d32afacfefdd55aa7a855a94881420d892f64a7f 100644 --- a/Framework/API/inc/MantidAPI/MatrixWorkspace.h +++ b/Framework/API/inc/MantidAPI/MatrixWorkspace.h @@ -585,12 +585,14 @@ private: /// A text label for use when plotting spectra std::string m_YUnitLabel; +protected: /// Flag indicating whether the m_isCommonBinsFlag has been set. False by /// default mutable bool m_isCommonBinsFlagSet{false}; /// Flag indicating whether the data has common bins. False by default mutable bool m_isCommonBinsFlag{false}; +private: /// The set of masked bins in a map keyed on workspace index std::map<int64_t, MaskList> m_masks; diff --git a/Framework/API/src/MatrixWorkspace.cpp b/Framework/API/src/MatrixWorkspace.cpp index 1a22e83f8c0d389ada4736da45e78eb65075c028..fd6bb81feafb94be6bf06c7e3d368ec9ddf0b354 100644 --- a/Framework/API/src/MatrixWorkspace.cpp +++ b/Framework/API/src/MatrixWorkspace.cpp @@ -23,6 +23,7 @@ #include "MantidIndexing/GlobalSpectrumIndex.h" #include "MantidIndexing/IndexInfo.h" #include "MantidKernel/MDUnit.h" +#include "MantidKernel/MultiThreaded.h" #include "MantidKernel/Strings.h" #include "MantidKernel/TimeSeriesProperty.h" #include "MantidKernel/VectorHelper.h" @@ -979,30 +980,30 @@ bool MatrixWorkspace::isCommonBins() const { // there being only one or zero histograms is accepted as not being an // error if (m_isCommonBinsFlag) { - // otherwise will compare some of the data, to save time just check two - // the first and the last + const size_t numBins = x(0).size(); const size_t lastSpec = numHist - 1; - // Quickest check is to see if they are actually the same vector - if (&(x(0)[0]) != &(x(lastSpec)[0])) { - // Now check numerically - const double first = std::accumulate(x(0).begin(), x(0).end(), 0.); - const double last = - std::accumulate(x(lastSpec).begin(), x(lastSpec).end(), 0.); - if (std::abs(first - last) / std::abs(first + last) > 1.0E-9) { - m_isCommonBinsFlag = false; - } - - // handle Nan's and inf's - if ((std::isinf(first) != std::isinf(last)) || - (std::isnan(first) != std::isnan(last))) { - m_isCommonBinsFlag = false; + for (size_t i = 0; i < lastSpec; ++i) { + const auto &xi = x(i); + const auto &xip1 = x(i + 1); + for (size_t j = 0; j < numBins; ++j) { + const double first = xi[j]; + const double next = xip1[j]; + if (std::abs(first - next) / std::abs(first + next) > 1.0E-9) { + m_isCommonBinsFlag = false; + break; + } + // handle Nan's and inf's + if ((std::isinf(first) != std::isinf(next)) || + (std::isnan(first) != std::isnan(next))) { + m_isCommonBinsFlag = false; + break; + } } } } } m_isCommonBinsFlagSet = true; } - return m_isCommonBinsFlag; } diff --git a/Framework/DataObjects/inc/MantidDataObjects/EventWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/EventWorkspace.h index f531ab34e85e01f2c0571338cd9e3b99072850cc..270b697a9ffb19d13877b5f844d33021ab4a7247 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/EventWorkspace.h +++ b/Framework/DataObjects/inc/MantidDataObjects/EventWorkspace.h @@ -92,7 +92,7 @@ public: Mantid::Types::Core::DateAndTime getTimeAtSampleMax(double tofOffset = 0) const override; - double getEventXMin() const; + double getEventMatrixWorkXMin() const; double getEventXMax() const; void getEventXMinMax(double &xmin, double &xmax) const; @@ -151,6 +151,9 @@ public: const bool entireRange) const override; EventWorkspace &operator=(const EventWorkspace &other) = delete; + /// Returns true if the workspace contains has common X bins + bool isCommonBins() const override; + protected: /// Protected copy constructor. May be used by childs for cloning. EventWorkspace(const EventWorkspace &other); diff --git a/Framework/DataObjects/inc/MantidDataObjects/Workspace2D.h b/Framework/DataObjects/inc/MantidDataObjects/Workspace2D.h index acc8dddc9f7f6e71426ad9a450112ac586d86cc3..34082b267c8ee9281e7b228f9f8997ce2e4d7f80 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/Workspace2D.h +++ b/Framework/DataObjects/inc/MantidDataObjects/Workspace2D.h @@ -80,6 +80,9 @@ public: bool loadAsRectImg = false, double scale_1 = 1.0, bool parallelExecution = true); + /// Returns true if the workspace contains has common X bins + bool isCommonBins() const override; + protected: /// Protected copy constructor. May be used by childs for cloning. Workspace2D(const Workspace2D &other); diff --git a/Framework/DataObjects/src/EventWorkspace.cpp b/Framework/DataObjects/src/EventWorkspace.cpp index d9ac64c79e879063051fea5a684b7d38f6b4495a..b151573b39ce91b8c1fe46939a9cbf5c73ec4d77 100644 --- a/Framework/DataObjects/src/EventWorkspace.cpp +++ b/Framework/DataObjects/src/EventWorkspace.cpp @@ -605,6 +605,30 @@ void EventWorkspace::resetAllXToSingleBin() { setAllX({tofmin, tofmax}); } +bool EventWorkspace::isCommonBins() const { + if (!m_isCommonBinsFlagSet) { + m_isCommonBinsFlag = true; + const size_t numHist = this->getNumberHistograms(); + // there being only one or zero histograms is accepted as not being an error + if (numHist > 1) { + // First check if the x-axis shares a common cow_ptr. + auto first = data[0]->ptrX(); + for (const auto &el : data) { + if (el->ptrX() != first) { + m_isCommonBinsFlag = false; + break; + } + } + // If false, we need to check more carefully. + if (!m_isCommonBinsFlag) { + return MatrixWorkspace::isCommonBins(); + } + } + m_isCommonBinsFlagSet = true; + } + return m_isCommonBinsFlag; +} + /** Task for sorting an event list */ class EventSortingTask { public: diff --git a/Framework/DataObjects/src/Workspace2D.cpp b/Framework/DataObjects/src/Workspace2D.cpp index a791567cc6b030d7dd9e2ee9637c8be3b96b3b6d..ef01141f435715ab313c3c5c6773ffe251cb475a 100644 --- a/Framework/DataObjects/src/Workspace2D.cpp +++ b/Framework/DataObjects/src/Workspace2D.cpp @@ -359,11 +359,33 @@ void Workspace2D::generateHistogram(const std::size_t index, const MantidVec &X, } Workspace2D *Workspace2D::doClone() const { return new Workspace2D(*this); } - Workspace2D *Workspace2D::doCloneEmpty() const { return new Workspace2D(storageMode()); } +bool Workspace2D::isCommonBins() const { + if (!m_isCommonBinsFlagSet) { + m_isCommonBinsFlag = true; + const size_t numHist = this->getNumberHistograms(); + // there being only one or zero histograms is accepted as not being an error + if (numHist > 1) { + // First check if the x-axis shares a common cow_ptr. + auto first = data[0]->ptrX(); + for (const auto &histogram : data) { + if (histogram->ptrX() != first) { + m_isCommonBinsFlag = false; + break; + } + } + // If false, we need to check more carefully. + if (!m_isCommonBinsFlag) { + return MatrixWorkspace::isCommonBins(); + } + } + m_isCommonBinsFlagSet = true; + } + return m_isCommonBinsFlag; +} } // namespace DataObjects } // namespace Mantid diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h b/Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h index e961c55ef803ea274a14369d0330e4199a9bf1a3..d6f3098374ce747982c6e720c4a151ce21eb6bf6 100644 --- a/Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h +++ b/Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h @@ -200,6 +200,31 @@ protected: "Cloning of AxeslessWorkspaceTester is not implemented."); } + bool isCommonBins() const override { + if (!m_isCommonBinsFlagSet) { + m_isCommonBinsFlag = true; + const size_t numHist = this->getNumberHistograms(); + // there being only one or zero histograms is accepted as not being an + // error + if (numHist > 1) { + // First check if the x-axis shares a common cow_ptr. + auto first = data[0]->ptrX(); + for (const auto &st : data) { + if (st->ptrX() != first) { + m_isCommonBinsFlag = false; + break; + } + } + // If false, we need to check more carefully. + if (!m_isCommonBinsFlag) { + return MatrixWorkspace::isCommonBins(); + } + } + m_isCommonBinsFlagSet = true; + } + return m_isCommonBinsFlag; + } + private: std::vector<SpectrumTester> m_vec; size_t m_spec;