Commit ec9fce3b authored by Harry Saunders's avatar Harry Saunders
Browse files

Correct Y-unit label when plotting as distribution

parent 99680f9e
......@@ -430,7 +430,8 @@ public:
std::string YUnit() const;
void setYUnit(const std::string &newUnit);
std::string YUnitLabel(bool useLatexText = false) const;
std::string YUnitLabel(bool useLatex = false,
bool plotAsDistribution = false) const;
void setYUnitLabel(const std::string &newLabel);
/// Are the Y-values dimensioned?
......
......@@ -32,6 +32,7 @@
#include "MantidParallel/Communicator.h"
#include "MantidTypes/SpectrumDefinition.h"
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <cmath>
......@@ -933,19 +934,30 @@ void MatrixWorkspace::setYUnit(const std::string &newUnit) {
}
/// Returns a caption for the units of the data in the workspace
std::string MatrixWorkspace::YUnitLabel(bool useLatexText /* = false */) const {
std::string
MatrixWorkspace::YUnitLabel(bool useLatex /* = false */,
bool plotAsDistribution /* = false */) const {
std::string retVal;
if (!m_YUnitLabel.empty()) {
retVal = m_YUnitLabel;
if (useLatexText) {
// If the workspace is marked as a distribution its units are already
// correct, if the workspace is not a distribution but is being plotted as
// one we must adjust the unit
if (plotAsDistribution && !this->isDistribution()) {
if (useLatex) {
retVal += " per $" + this->getAxis(0)->unit()->label().latex() + "$";
} else {
retVal += " per " + this->getAxis(0)->unit()->label().ascii();
}
}
if (useLatex) {
std::vector<std::string> splitVec;
boost::split_regex(splitVec, retVal, boost::regex(" per "));
if (splitVec.size() > 1) {
retVal = splitVec[0];
std::string unitString = "";
for (size_t i = 1; i < splitVec.size(); i++)
unitString += splitVec[i];
retVal += " ($" + unitString + "$)$^{-1}$";
splitVec.erase(splitVec.begin());
std::string unitString = boost::algorithm::join(splitVec, " ");
retVal += " (" + unitString + ")$^{-1}$";
}
}
} else {
......@@ -954,9 +966,9 @@ std::string MatrixWorkspace::YUnitLabel(bool useLatexText /* = false */) const {
// has its unit set then append that unit to the string to be returned
if (!retVal.empty() && this->isDistribution() && this->axes() &&
this->getAxis(0)->unit()) {
if (useLatexText) {
retVal = retVal + " ($" + this->getAxis(0)->unit()->label().ascii() +
"$)$^{-1}$";
if (useLatex) {
retVal = retVal + " (" + this->getAxis(0)->unit()->label().latex() +
")$^{-1}$";
} else {
retVal = retVal + " per " + this->getAxis(0)->unit()->label().ascii();
}
......
......@@ -65,7 +65,7 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(MatrixWorkspace_yIndexOfXOverloads,
MatrixWorkspace::yIndexOfX, 1, 3)
// Overloads for YUnitLabel which has 1 optional argument
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(MatrixWorkspace_YUnitLabelOverloads,
YUnitLabel, 0, 1)
YUnitLabel, 0, 2)
GNU_DIAG_ON("conversion")
GNU_DIAG_ON("unused-local-typedef")
......@@ -289,7 +289,7 @@ void export_MatrixWorkspace() {
"Returns the current Y unit for the data (Y axis) in the workspace")
.def("YUnitLabel", &MatrixWorkspace::YUnitLabel,
MatrixWorkspace_YUnitLabelOverloads(
(arg("self"), arg("useLatexText")),
(arg("self"), arg("useLatex"), arg("plotAsDistribution")),
"Returns the caption for the Y axis"))
.def("hasMaskedBins", &MatrixWorkspace::hasMaskedBins,
(arg("self"), arg("workspaceIndex")),
......
......@@ -566,7 +566,7 @@ def get_sample_log(workspace, **kwargs):
# ====================================================
def get_axes_labels(workspace, indices=None):
def get_axes_labels(workspace, indices=None, plot_as_dist=True, use_latex=True):
"""
Get axis labels from a Workspace2D or an MDHistoWorkspace
Returns a tuple. The first element is the quantity label, such as "Intensity" or "Counts".
......@@ -576,9 +576,12 @@ def get_axes_labels(workspace, indices=None):
If MDWorkspace then the last element will be the values selected by the indices, to be set as title.
:param workspace: :class:`mantid.api.MatrixWorkspace` or :class:`mantid.api.IMDHistoWorkspace`
:param indices:
:param plot_as_dist: bool: plotting as distribution
:param use_latex: bool: return y-unit label in Latex form
"""
if isinstance(workspace, MultipleExperimentInfos):
axes = ['Intensity']
axes_labels = ['Intensity']
title = ''
if indices is None:
dims = workspace.getNonIntegratedDimensions()
......@@ -597,11 +600,12 @@ def get_axes_labels(workspace, indices=None):
axis_unit = axis_unit.replace('DeltaE', 'meV')
axis_unit = axis_unit.replace('Angstrom', r'$\AA$')
axis_unit = axis_unit.replace('MomentumTransfer', r'$\AA^{-1}$')
axes.append('{0} ({1})'.format(axis_title, axis_unit))
axes.append(title.strip())
axes_labels.append('{0} ({1})'.format(axis_title, axis_unit))
axes_labels.append(title.strip())
else:
# For matrix workspaces, return a tuple of ``(YUnit, <other units>)`
axes_labels = [workspace.YUnitLabel(useLatexText=True)]
# For matrix workspaces, return a tuple of ``(YUnit, <other units>)``
axes_labels = [workspace.YUnitLabel(useLatex=use_latex,
plotAsDistribution=plot_as_dist)]
for index in range(workspace.axes()):
axis = workspace.getAxis(index)
unit = axis.getUnit()
......
......@@ -66,6 +66,26 @@ class HelperFunctionsTest(unittest.TestCase):
def setUpClass(cls):
cls.g1da = config['graph1d.autodistribution']
config['graph1d.autodistribution'] = 'On'
cls.ws2d_non_distribution = CreateWorkspace(
DataX=[10, 20, 30, 10, 20, 30],
DataY=[2, 3, 4, 5],
DataE=[1, 2, 3, 4],
NSpec=2,
Distribution=False,
UnitX='Wavelength',
YUnitLabel='Counts per microAmp.hour',
VerticalAxisUnit='DeltaE',
VerticalAxisValues=[4, 6, 8],
OutputWorkspace='ws2d_non_distribution')
cls.ws2d_distribution = CreateWorkspace(
DataX=[10, 20, 30, 10, 20, 30],
DataY=[2, 3, 4, 5, 6],
DataE=[1, 2, 3, 4, 6],
NSpec=1,
Distribution=True,
UnitX='Wavelength',
YUnitLabel='Counts per microAmp.hour',
OutputWorkspace='ws2d_distribution')
cls.ws2d_histo = CreateWorkspace(DataX=[10, 20, 30, 10, 20, 30],
DataY=[2, 3, 4, 5],
DataE=[1, 2, 3, 4],
......@@ -75,13 +95,6 @@ class HelperFunctionsTest(unittest.TestCase):
VerticalAxisUnit='DeltaE',
VerticalAxisValues=[4, 6, 8],
OutputWorkspace='ws2d_histo')
cls.ws1d_distribution = CreateWorkspace(DataX=[10, 20, 30, 10, 20, 30],
DataY=[2, 3, 4, 5, 6],
DataE=[1, 2, 3, 4, 6],
NSpec=1,
Distribution=True,
UnitX='meV',
OutputWorkspace='ws1d_distribution')
cls.ws2d_point = CreateWorkspace(DataX=[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4],
DataY=[2] * 12,
NSpec=3,
......@@ -145,8 +158,9 @@ class HelperFunctionsTest(unittest.TestCase):
@classmethod
def tearDownClass(cls):
config['graph1d.autodistribution'] = cls.g1da
DeleteWorkspace('ws2d_non_distribution')
DeleteWorkspace('ws2d_distribution')
DeleteWorkspace('ws2d_histo')
DeleteWorkspace('ws1d_distribution')
DeleteWorkspace('ws2d_point')
DeleteWorkspace('ws1d_point')
DeleteWorkspace('ws_MD_2d')
......@@ -175,10 +189,24 @@ class HelperFunctionsTest(unittest.TestCase):
self.assertEqual(axs, ('', 'Wavelength ($\\AA$)', 'Energy transfer ($meV$)'))
def test_y_units_correct_on_distribution_workspace(self):
ws = self.ws1d_distribution
ws.setYUnit('Counts')
ws = self.ws2d_distribution
labels = funcs.get_axes_labels(ws)
self.assertEqual(labels[0], 'Counts ($meV$)$^{-1}$')
self.assertEqual(labels[0], 'Counts (microAmp.hour)$^{-1}$')
def test_y_units_for_distribution_and_autodist_off(self):
ws = self.ws2d_distribution
labels = funcs.get_axes_labels(ws, plot_as_dist=False)
self.assertEqual(labels[0], 'Counts (microAmp.hour)$^{-1}$')
def test_y_units_for_non_distribution_and_autodist_on_with_ascii(self):
ws = self.ws2d_non_distribution
labels = funcs.get_axes_labels(ws, plot_as_dist=True, use_latex=False)
self.assertEqual(labels[0], 'Counts per microAmp.hour per Angstrom')
def test_y_units_for_non_distribution_and_autodist_on_with_latex(self):
ws = self.ws2d_non_distribution
labels = funcs.get_axes_labels(ws, plot_as_dist=True)
self.assertEqual(labels[0], 'Counts (microAmp.hour $\\AA$)$^{-1}$')
def test_get_axes_label_2d_MDWS(self):
axs = funcs.get_axes_labels(self.ws_MD_2d)
......@@ -334,7 +362,8 @@ class HelperFunctionsTest(unittest.TestCase):
np.testing.assert_allclose(y, np.array([0.5, 1.5, 2.5]))
# mesh from ragged histo data
x, y, z = funcs.get_matrix_2d_ragged(self.ws2d_histo_rag, True, histogram2D=True)
np.testing.assert_allclose(x, np.array([1.03125, 1.96875, 2.90625, 3.84375, 4.78125, 5.71875, 6.65625, 7.59375, 8.53125, 9.46875]))
np.testing.assert_allclose(x, np.array(
[1.03125, 1.96875, 2.90625, 3.84375, 4.78125, 5.71875, 6.65625, 7.59375, 8.53125, 9.46875]))
np.testing.assert_allclose(y, np.array([4., 6, 8., 10.]))
# check that fails for uneven data
self.assertRaises(ValueError, funcs.get_matrix_2d_data, self.ws2d_point_uneven, True)
......
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