diff --git a/Framework/API/inc/MantidAPI/MatrixWorkspace.h b/Framework/API/inc/MantidAPI/MatrixWorkspace.h index 533287868eaea300fde596302d3ce901dce92387..3003b3a5c90c83c26db45afa554006932818925c 100644 --- a/Framework/API/inc/MantidAPI/MatrixWorkspace.h +++ b/Framework/API/inc/MantidAPI/MatrixWorkspace.h @@ -418,6 +418,9 @@ public: /// always safe to assume it is just 2 size_t numberOfAxis() const; + /// Returns true if the workspace contains common X bins with log spacing + virtual bool isCommonLogBins() const; + /// Returns true if the workspace contains data in histogram form (as /// opposed to point-like) virtual bool isHistogramData() const; diff --git a/Framework/API/src/MatrixWorkspace.cpp b/Framework/API/src/MatrixWorkspace.cpp index a293272dba911efb5dabe0605c9c38aa8fbf91ef..7a5e5c4ae8e656762d4c42e9f97e302bac1aaecd 100644 --- a/Framework/API/src/MatrixWorkspace.cpp +++ b/Framework/API/src/MatrixWorkspace.cpp @@ -876,6 +876,46 @@ void MatrixWorkspace::replaceAxis(const std::size_t &axisIndex, m_axes[axisIndex] = newAxis; } +/** + * Whether the workspace contains common X bins with logarithmic spacing + * @return whether the workspace contains common X bins with log spacing + */ +bool MatrixWorkspace::isCommonLogBins() const { + if (!this->isCommonBins()) { + return false; + } + + if (this->getNumberHistograms() == 0) { + return false; + } + + const auto &x0 = this->x(0); + if (x0.size() < 2) { + return false; + } + + // guard against all axis elements being equal + if (x0[1] == x0[0]) { + return false; + } + + double diff = x0[1] / x0[0]; + if (!std::isfinite(diff)) { + return false; + } + // ignore final bin, since it may be a different size + for (size_t i = 1; i < x0.size() - 2; ++i) { + if (std::isfinite(x0[i + 1]) && std::isfinite(x0[i])) { + if (std::abs(x0[i + 1] / x0[i] - diff) > EPSILON) { + return false; + } + } else { + return false; + } + } + return true; +} + /** * Return the number of Axis stored by this workspace * @return int diff --git a/Framework/API/test/MatrixWorkspaceTest.h b/Framework/API/test/MatrixWorkspaceTest.h index 6d63a81e36a1aad3ac30d2be05e520c84da9bb57..0a6aca379b3b21b97cc3dfbcbd417bc001062327 100644 --- a/Framework/API/test/MatrixWorkspaceTest.h +++ b/Framework/API/test/MatrixWorkspaceTest.h @@ -23,6 +23,9 @@ #include "MantidGeometry/Instrument/Detector.h" #include "MantidGeometry/Instrument/DetectorInfo.h" #include "MantidGeometry/Instrument/ReferenceFrame.h" +#include "MantidHistogramData/Histogram.h" +#include "MantidHistogramData/LinearGenerator.h" +#include "MantidHistogramData/LogarithmicGenerator.h" #include "MantidIndexing/IndexInfo.h" #include "MantidKernel/TimeSeriesProperty.h" #include "MantidKernel/VMD.h" @@ -467,6 +470,7 @@ public: void testEmptyWorkspace() { WorkspaceTester ws; TS_ASSERT(ws.isCommonBins()); + TS_ASSERT_EQUALS(ws.isCommonLogBins(), false); TS_ASSERT_EQUALS(ws.blocksize(), 0); TS_ASSERT_EQUALS(ws.size(), 0); } @@ -476,6 +480,7 @@ public: ws.initialize(10, 10, 10); // After initialization, ws should contain a shared HistogramX. TS_ASSERT(ws.isCommonBins()); + TS_ASSERT_EQUALS(ws.isCommonLogBins(), false); // Modifying the value of one Spectrum will cause this Histogram to detach. // Since the value is identical, isCommonBins is still true. ws.mutableX(0)[0] = 1.; @@ -485,6 +490,26 @@ public: TS_ASSERT_EQUALS(ws.isCommonBins(), false); } + void testIsCommonLogAxis() { + WorkspaceTester ws; + ws.initialize(10, 10, 10); + TS_ASSERT_EQUALS(ws.isCommonLogBins(), false); + + auto logAxis = Kernel::make_cow<Mantid::HistogramData::HistogramX>( + 10, Mantid::HistogramData::LogarithmicGenerator(1., 0.1)); + for (size_t i = 0; i < ws.getNumberHistograms(); ++i) { + ws.setSharedX(i, logAxis); + } + TS_ASSERT_EQUALS(ws.isCommonLogBins(), true); + + auto linearAxis = Kernel::make_cow<Mantid::HistogramData::HistogramX>( + 10, Mantid::HistogramData::LinearGenerator(1., 0.1)); + for (size_t i = 0; i < ws.getNumberHistograms(); ++i) { + ws.setSharedX(i, linearAxis); + } + TS_ASSERT_EQUALS(ws.isCommonLogBins(), false); + } + void test_updateSpectraUsing() { WorkspaceTester testWS; testWS.initialize(3, 1, 1); diff --git a/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp index 73ecaa17d0bffc054230bbeb97e63a321b7d2239..06e20a930f9835abcffae3940ac98f13396d2e0d 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp @@ -429,7 +429,9 @@ void export_MatrixWorkspace() { .def("clearMonitorWorkspace", &clearMonitorWorkspace, args("self"), "Forget about monitor workspace, attached to the current workspace") .def("isCommonBins", &MatrixWorkspace::isCommonBins, - "Returns true if the workspace has common X bins."); + "Returns true if the workspace has common X bins.") + .def("isCommonLogBins", &MatrixWorkspace::isCommonLogBins, + "Returns true if the workspace has common X bins with log spacing."); RegisterWorkspacePtrToPython<MatrixWorkspace>(); } diff --git a/Framework/PythonInterface/test/python/mantid/api/MatrixWorkspaceTest.py b/Framework/PythonInterface/test/python/mantid/api/MatrixWorkspaceTest.py index a7e3f52eb8fe55339378b9895fa29c618d378e19..39b0f622a26086f2154c9c38c301848841241ae4 100644 --- a/Framework/PythonInterface/test/python/mantid/api/MatrixWorkspaceTest.py +++ b/Framework/PythonInterface/test/python/mantid/api/MatrixWorkspaceTest.py @@ -10,11 +10,11 @@ import unittest import sys import math from testhelpers import create_algorithm, run_algorithm, can_be_instantiated, WorkspaceCreationHelper - from mantid.api import (MatrixWorkspace, MatrixWorkspaceProperty, WorkspaceProperty, Workspace, ExperimentInfo, AnalysisDataService, WorkspaceFactory) from mantid.geometry import Detector from mantid.kernel import Direction, V3D +from mantid.simpleapi import CreateSampleWorkspace, Rebin import numpy as np from six.moves import range @@ -428,6 +428,14 @@ class MatrixWorkspaceTest(unittest.TestCase): def test_isCommonBins(self): self.assertTrue(self._test_ws.isCommonBins()) + def test_isCommonLogBins(self): + self.assertFalse(self._test_ws.isCommonLogBins()) + ws=CreateSampleWorkspace('Event') + ws=Rebin(ws, '1,-1,10000') + self.assertTrue(ws.isCommonLogBins()) + ws=Rebin(ws, '1,-0.1,10000') + self.assertTrue(ws.isCommonLogBins()) + def test_hasMaskedBins(self): numBins = 10 numHist=11 diff --git a/docs/source/release/v4.1.0/framework.rst b/docs/source/release/v4.1.0/framework.rst index c3d76a4edb5df3ed7afd8dd6a3f965fd0d9063c9..2d79f75cac8bcd1284fd0bf8dff1c262fa9fb346 100644 --- a/docs/source/release/v4.1.0/framework.rst +++ b/docs/source/release/v4.1.0/framework.rst @@ -36,6 +36,7 @@ Removed Data Objects ------------ +- Added method `isCommonLogBins` to check if the `MatrixWorkspace` contains common X bins with logarithmic spacing. Python ------