Commit d09d748d authored by Robert Applin's avatar Robert Applin
Browse files

Refs #30071. Add useful functions to matrixworkspace API.

parent ac337631
......@@ -135,6 +135,10 @@ public:
/// This throws an exception if the lengths are not identical across the
/// spectra.
virtual std::size_t blocksize() const = 0;
/// Returns the number of bins for a given histogram index.
virtual std::size_t getNumberBins(const std::size_t &index) const = 0;
/// Returns the maximum number of bins in a workspace (works on ragged data).
virtual std::size_t getMaxNumberBins() const = 0;
/// Returns the number of histograms in the workspace
virtual std::size_t getNumberHistograms() const = 0;
......@@ -165,7 +169,7 @@ public:
return getSpectrum(index).histogram();
}
template <typename... T>
void setHistogram(const size_t index, T &&... data) & {
void setHistogram(const size_t index, T &&...data) & {
getSpectrum(index).setHistogram(std::forward<T>(data)...);
}
void convertToCounts(const size_t index) {
......@@ -184,20 +188,19 @@ public:
pointStandardDeviations(const size_t index) const {
return getSpectrum(index).pointStandardDeviations();
}
template <typename... T>
void setBinEdges(const size_t index, T &&... data) & {
template <typename... T> void setBinEdges(const size_t index, T &&...data) & {
getSpectrum(index).setBinEdges(std::forward<T>(data)...);
}
template <typename... T> void setPoints(const size_t index, T &&... data) & {
template <typename... T> void setPoints(const size_t index, T &&...data) & {
getSpectrum(index).setPoints(std::forward<T>(data)...);
}
template <typename... T>
void setPointVariances(const size_t index, T &&... data) & {
void setPointVariances(const size_t index, T &&...data) & {
getSpectrumWithoutInvalidation(index).setPointVariances(
std::forward<T>(data)...);
}
template <typename... T>
void setPointStandardDeviations(const size_t index, T &&... data) & {
void setPointStandardDeviations(const size_t index, T &&...data) & {
getSpectrumWithoutInvalidation(index).setPointStandardDeviations(
std::forward<T>(data)...);
}
......@@ -222,31 +225,31 @@ public:
frequencyStandardDeviations(const size_t index) const {
return getSpectrum(index).frequencyStandardDeviations();
}
template <typename... T> void setCounts(const size_t index, T &&... data) & {
template <typename... T> void setCounts(const size_t index, T &&...data) & {
getSpectrumWithoutInvalidation(index).setCounts(std::forward<T>(data)...);
}
template <typename... T>
void setCountVariances(const size_t index, T &&... data) & {
void setCountVariances(const size_t index, T &&...data) & {
getSpectrumWithoutInvalidation(index).setCountVariances(
std::forward<T>(data)...);
}
template <typename... T>
void setCountStandardDeviations(const size_t index, T &&... data) & {
void setCountStandardDeviations(const size_t index, T &&...data) & {
getSpectrumWithoutInvalidation(index).setCountStandardDeviations(
std::forward<T>(data)...);
}
template <typename... T>
void setFrequencies(const size_t index, T &&... data) & {
void setFrequencies(const size_t index, T &&...data) & {
getSpectrumWithoutInvalidation(index).setFrequencies(
std::forward<T>(data)...);
}
template <typename... T>
void setFrequencyVariances(const size_t index, T &&... data) & {
void setFrequencyVariances(const size_t index, T &&...data) & {
getSpectrumWithoutInvalidation(index).setFrequencyVariances(
std::forward<T>(data)...);
}
template <typename... T>
void setFrequencyStandardDeviations(const size_t index, T &&... data) & {
void setFrequencyStandardDeviations(const size_t index, T &&...data) & {
getSpectrumWithoutInvalidation(index).setFrequencyStandardDeviations(
std::forward<T>(data)...);
}
......
......@@ -68,12 +68,16 @@ public:
// Get the blocksize, aka the number of bins in the histogram
std::size_t blocksize() const override;
size_t getMemorySize() const override;
/// Returns the number of bins for a given histogram index.
std::size_t getNumberBins(const std::size_t &index) const override;
/// Returns the maximum number of bins in a workspace (works on ragged data).
std::size_t getMaxNumberBins() const override;
// Get the number of histograms. aka the number of pixels or detectors.
std::size_t getNumberHistograms() const override;
size_t getMemorySize() const override;
EventList &getSpectrum(const size_t index) override {
invalidateCommonBinsFlag();
return getSpectrumWithoutInvalidation(index);
......
......@@ -51,12 +51,17 @@ public:
/// Returns true if the workspace is ragged (has differently sized spectra).
bool isRaggedWorkspace() const override;
/// Returns the histogram number
std::size_t getNumberHistograms() const override;
// section required for iteration
std::size_t size() const override;
std::size_t blocksize() const override;
/// Returns the number of bins for a given histogram index.
std::size_t getNumberBins(const std::size_t &index) const override;
/// Returns the maximum number of bins in a workspace (works on ragged data).
std::size_t getMaxNumberBins() const override;
/// Returns the histogram number
std::size_t getNumberHistograms() const override;
Histogram1D &getSpectrum(const size_t index) override {
invalidateCommonBinsFlag();
......@@ -109,4 +114,4 @@ private:
virtual std::size_t getHistogramNumberHelper() const;
};
} // namespace DataObjects
} // Namespace Mantid
\ No newline at end of file
} // Namespace Mantid
......@@ -47,6 +47,13 @@ public:
/// Returns the size of each block of data returned by the dataX accessors
std::size_t blocksize() const override { return 1; }
/// Returns the number of bins for a given histogram index.
std::size_t getNumberBins(const std::size_t &index) const override {
UNUSED_ARG(index);
return 1;
}
/// Returns the maximum number of bins in a workspace.
std::size_t getMaxNumberBins() const override { return 1; }
/// @return the number of histograms (spectra)
std::size_t getNumberHistograms() const override { return 1; }
......
......@@ -178,6 +178,36 @@ size_t EventWorkspace::blocksize() const {
}
}
/** Returns the number of bins for a given histogram index.
* @param index :: The histogram index to check for the number of bins.
* @return the number of bins for a given histogram index.
*/
std::size_t EventWorkspace::getNumberBins(const std::size_t &index) const {
if (index <= data.size())
return data[index]->histogram_size();
throw std::invalid_argument(
"Could not find number of bins in a histogram at index " +
std::to_string(index) + ": index is too large.");
}
/** Returns the maximum number of bins in a workspace (works on ragged data).
* @return the maximum number of bins in a workspace.
*/
std::size_t EventWorkspace::getMaxNumberBins() const {
if (data.empty()) {
return 0;
} else {
auto maxNumberOfBins = data[0]->histogram_size();
for (const auto &iter : data) {
const auto numberOfBins = iter->histogram_size();
if (numberOfBins > maxNumberOfBins)
maxNumberOfBins = numberOfBins;
}
return maxNumberOfBins;
}
}
/** Get the number of histograms, usually the same as the number of pixels or
detectors.
@returns the number of histograms / event lists
......
......@@ -149,6 +149,36 @@ size_t Workspace2D::blocksize() const {
}
}
/** Returns the number of bins for a given histogram index.
* @param index :: The histogram index to check for the number of bins.
* @return the number of bins for a given histogram index.
*/
std::size_t Workspace2D::getNumberBins(const std::size_t &index) const {
if (index <= data.size())
return data[index]->size();
throw std::invalid_argument(
"Could not find number of bins in a histogram at index " +
std::to_string(index) + ": index is too large.");
}
/** Returns the maximum number of bins in a workspace (works on ragged data).
* @return the maximum number of bins in a workspace.
*/
std::size_t Workspace2D::getMaxNumberBins() const {
if (data.empty()) {
return 0;
} else {
auto maxNumberOfBins = data[0]->size();
for (const auto &iter : data) {
const auto numberOfBins = iter->size();
if (numberOfBins > maxNumberOfBins)
maxNumberOfBins = numberOfBins;
}
return maxNumberOfBins;
}
}
/**
* Copy the data (Y's) from an image to this workspace.
* @param image :: An image to copy the data from.
......
......@@ -184,18 +184,6 @@ void setDxFromPyObject(MatrixWorkspace &self, const size_t wsIndex,
setSpectrumFromPyObject(self, &MatrixWorkspace::dataDx, wsIndex, values);
}
/**
* Adds a deprecation warning to the getNumberBins call to warn about using
* blocksize instead
* @param self A reference to the calling object
* @returns The blocksize()
*/
size_t getNumberBinsDeprecated(MatrixWorkspace &self) {
PyErr_Warn(PyExc_DeprecationWarning,
"``getNumberBins`` is deprecated, use ``blocksize`` instead.");
return self.blocksize();
}
/**
* Adds a deprecation warning to the getSampleDetails call to warn about using
* getRun instead
......@@ -350,6 +338,12 @@ void export_MatrixWorkspace() {
"spectra).")
.def("blocksize", &MatrixWorkspace::blocksize, arg("self"),
"Returns size of the Y data array")
.def("getNumberBins", &MatrixWorkspace::getNumberBins,
(arg("self"), arg("index")),
"Returns the number of bins for a given histogram index.")
.def("getMaxNumberBins", &MatrixWorkspace::getMaxNumberBins, arg("self"),
"Returns the maximum number of bins in a workspace (works on ragged "
"data).")
.def("getNumberHistograms", &MatrixWorkspace::getNumberHistograms,
arg("self"), "Returns the number of spectra in the workspace")
.def("getSpectrumNumbers", &getSpectrumNumbers, arg("self"),
......@@ -424,11 +418,6 @@ void export_MatrixWorkspace() {
"Find first index in Y equal to value. Start may be specified to "
"begin at a specifc index. Returns tuple with the "
"histogram and bin indices.")
// Deprecated
.def("getNumberBins", &getNumberBinsDeprecated, arg("self"),
"Returns size of the Y data array (deprecated, use "
":class:`~mantid.api.MatrixWorkspace.blocksize` "
"instead)")
.def("getSampleDetails", &getSampleDetailsDeprecated, arg("self"),
return_internal_reference<>(),
"Return the Run object for this workspace (deprecated, use "
......
......@@ -79,7 +79,7 @@ class PearlMCAbsorption(PythonAlgorithm):
"""
#c = math.exp(-1.0*mu*thickness)
num_hist = input_ws.getNumberHistograms()
num_vals = input_ws.getNumberBins()
num_vals = input_ws.blocksize()
for i in range(num_hist):
mu_values = input_ws.readY(i)
for j in range(num_vals):
......
......@@ -172,7 +172,7 @@ class LoadDNSLegacyTest(unittest.TestCase):
ws = AnalysisDataService.retrieve(outputWorkspaceName)
# dimensions
self.assertEqual(24, ws.getNumberHistograms())
self.assertEqual(100, ws.getNumberBins())
self.assertEqual(100, ws.blocksize())
# data array
self.assertEqual(8, ws.readY(19)[23])
self.assertAlmostEqual(tof1, ws.readX(0)[0], 3)
......
......@@ -31,31 +31,31 @@ class LoadGudrunOutputTest(unittest.TestCase):
def test_load_dcs(self):
actual = LoadGudrunOutput(self.file_name.format('.dcs'))
self.assertIsInstance(actual, Workspace)
self.assertEqual(actual.getNumberBins(), 100)
self.assertEqual(actual.blocksize(), 100)
self.assertEqual(actual.getNumberHistograms(), 5)
def test_load_mdsc(self):
actual = LoadGudrunOutput(self.file_name.format('.mdcs'))
self.assertIsInstance(actual, Workspace)
self.assertEqual(actual.getNumberBins(), 100)
self.assertEqual(actual.blocksize(), 100)
self.assertEqual(actual.getNumberHistograms(), 1)
def test_load_mint(self):
actual = LoadGudrunOutput(self.file_name.format('.mint'))
self.assertIsInstance(actual, Workspace)
self.assertEqual(actual.getNumberBins(), 100)
self.assertEqual(actual.blocksize(), 100)
self.assertEqual(actual.getNumberHistograms(), 1)
def test_load_mdor(self):
actual = LoadGudrunOutput(self.file_name.format('.mdor'))
self.assertIsInstance(actual, Workspace)
self.assertEqual(actual.getNumberBins(), 100)
self.assertEqual(actual.blocksize(), 100)
self.assertEqual(actual.getNumberHistograms(), 1)
def test_load_mgor(self):
actual = LoadGudrunOutput(self.file_name.format('.mgor'))
self.assertIsInstance(actual, Workspace)
self.assertEqual(actual.getNumberBins(), 100)
self.assertEqual(actual.blocksize(), 100)
self.assertEqual(actual.getNumberHistograms(), 1)
def test_one_column_data_file(self):
......
......@@ -23,6 +23,7 @@
* Author: Janik Zikovsky
*/
#include <algorithm>
#include <fstream>
#include <map>
#include <string>
......@@ -166,6 +167,26 @@ public:
}
return m_vec.empty() ? 0 : m_vec[0].dataY().size();
}
std::size_t getNumberBins(const std::size_t &index) const override {
if (index > m_vec.size())
return 0;
return m_vec[index].dataY().size();
}
std::size_t getMaxNumberBins() const override {
if (m_vec.empty()) {
return 0;
} else {
const auto iter = std::max_element(
m_vec.cbegin(), m_vec.cend(),
[](const SpectrumTester &s1, const SpectrumTester &s2) {
return s1.dataY().size() < s2.dataY().size();
});
return iter->dataY().size();
}
}
ISpectrum &getSpectrum(const size_t index) override {
invalidateCommonBinsFlag();
m_vec[index].setMatrixWorkspace(this, index);
......
......@@ -259,7 +259,7 @@ class AbsorptionCompare(systemtesting.MantidSystemTest):
SetSample(InputWorkspace='V_abs',
Material={'ChemicalFormula': 'V', 'SampleNumberDensity': 0.0721},
Geometry={'Shape': 'Cylinder', 'Height': 6.97, 'Radius': (0.63 / 2), 'Center': [0., 0., 0.]})
self.assertEqual(absorptionWS.getNumberBins(), num_wl_bins)
self.assertEqual(absorptionWS.blocksize(), num_wl_bins)
# calculate the absorption
CylinderAbsorption(InputWorkspace='V_abs', OutputWorkspace='V_abs',
NumberOfSlices=20, NumberOfAnnuli=3)
......
......@@ -289,7 +289,7 @@ class WorkspaceWidget(PluginWidget):
TableWorkspaceDisplay.supports(ws)
self._do_show_data([name])
except ValueError:
if hasattr(ws, 'blocksize') and ws.blocksize() == 1:
if hasattr(ws, 'getMaxNumberBins') and ws.getMaxNumberBins() == 1:
#If this is ws is just a single value show the data, else plot the bin
if hasattr(ws, 'getNumberHistograms') and ws.getNumberHistograms() == 1:
self._do_show_data([name])
......
......@@ -61,7 +61,7 @@ class MatrixWorkspaceTableViewModel(QAbstractTableModel):
self.ws = ws
self.ws_spectrum_info = self.ws.spectrumInfo()
self.row_count = self.ws.getNumberHistograms()
self.column_count = self._get_column_count()
self.column_count = self.ws.getMaxNumberBins()
self.masked_rows_cache = []
self.monitor_rows_cache = []
......@@ -90,29 +90,6 @@ class MatrixWorkspaceTableViewModel(QAbstractTableModel):
else:
raise ValueError("Unknown model type {0}".format(self.type))
def _get_column_count(self):
"""
Gets the size of the spectrum data in the workspace (i.e. number of bins). If blocksize fails, then the
workspace is ragged.
:return: The number of columns required to display the workspace in a table.
"""
try:
return self.ws.blocksize()
except RuntimeError:
return self._get_max_column_count()
def _get_max_column_count(self):
"""
Gets the number of columns required to display the workspace. This method is used for ragged workspaces.
:return: The number of columns required to display the workspace in a table.
"""
max_column_count = 0
for i in range(self.ws.getNumberHistograms()):
column_count = len(self.ws.readY(i))
if column_count > max_column_count:
max_column_count = column_count
return max_column_count
def _makeVerticalHeader(self, section, role):
def _numeric_axis_value_unit(axis):
# binned/point data
......
......@@ -392,14 +392,14 @@ class ISISPowderCommonTest(unittest.TestCase):
Function='Flat background', NumBanks=1, BankPixelWidth=1, XMax=10, BinWidth=1)
new_bin_width = 0.5
# Originally had bins at 1 unit each. So binning of 0.5 should give us 2n bins back
original_number_bins = ws.getNumberBins()
original_number_bins = ws.blocksize()
original_first_x_val = ws.readX(0)[0]
original_last_x_val = ws.readX(0)[-1]
expected_bins = original_number_bins * 2
ws = common.rebin_workspace(workspace=ws, new_bin_width=new_bin_width)
self.assertEqual(ws.getNumberBins(), expected_bins)
self.assertEqual(ws.blocksize(), expected_bins)
# Check bin boundaries were preserved
self.assertEqual(ws.readX(0)[0], original_first_x_val)
......@@ -413,7 +413,7 @@ class ISISPowderCommonTest(unittest.TestCase):
# Originally we had 10 bins from 0, 10. Resize from 0, 0.5, 5 so we should have the same number of output
# bins with different boundaries
new_bin_width = 0.5
original_number_bins = ws.getNumberBins()
original_number_bins = ws.blocksize()
expected_start_x = 1
expected_end_x = 6
......@@ -422,7 +422,7 @@ class ISISPowderCommonTest(unittest.TestCase):
start_x=expected_start_x, end_x=expected_end_x)
# Check number of bins is the same as we halved the bin width and interval so we should have n bins
self.assertEqual(ws.getNumberBins(), original_number_bins)
self.assertEqual(ws.blocksize(), original_number_bins)
# Check bin boundaries were changed
self.assertEqual(ws.readX(0)[0], expected_start_x)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment