Skip to content

Commit

Permalink
Merge pull request #453 from mantidproject/451_load_indirect_nxspe
Browse files Browse the repository at this point in the history
Fixed bug to allow plotting indirect nxspe files
  • Loading branch information
martyngigg authored Mar 21, 2019
2 parents 4c8d1e2 + 5e54232 commit 2633351
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 15 deletions.
24 changes: 19 additions & 5 deletions mslice/models/cut/cut_algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from mantid.api import PythonAlgorithm, WorkspaceProperty
from mantid.kernel import Direction, PropertyManagerProperty, StringMandatoryValidator
from mantid.simpleapi import BinMD, ConvertSpectrumAxis, CreateMDHistoWorkspace, Rebin2D, SofQW3, TransformMD, \
ConvertToMD, DeleteWorkspace
ConvertToMD, DeleteWorkspace, CreateSimulationWorkspace, AddSampleLog, CopyLogs

from mslice.models.alg_workspace_ops import fill_in_missing_input, get_number_of_steps
from mslice.models.axis import Axis
Expand Down Expand Up @@ -91,10 +91,20 @@ def _compute_cut_nonPSD(selected_workspace, cut_axis, integration_axis, emode):
extents = " ,".join(map(str, (xdim.getMinimum(), xdim.getMaximum())))

# Hack to (deep) copy log data (ExperimentInfo)
_tmpws = ConvertToMD(ws_out, EnableLogging=False, StoreInADS=False, PreprocDetectorsWS='-')
_tmpws = CreateSimulationWorkspace(Instrument='MAR', BinParams=[-1, 1, 1], UnitX='DeltaE', OutputWorkspace=name,
EnableLogging=False)
CopyLogs(ws_out, _tmpws, EnableLogging=False)
AddSampleLog(_tmpws, LogName='Ei', LogText='3.', LogType='Number', EnableLogging=False)
_tmpws = ConvertToMD(_tmpws, EnableLogging=False, StoreInADS=False, PreprocDetectorsWS='-',
QDimensions='|Q|', dEAnalysisMode='Direct')
# TODO: Refactor the above code after Mantid framework has been changed to avoid the hack.
# The above lines create an empty MD workspace with the same logs as the calculated Workspace2D output of the
# cut algorithms. These logs are then copied (using copyExperimentInfos below) to the generated MDHistoWorkspace
# Ideally we should be able to use the CopyLogs algorithm between a Workspace2D and MD workspace or
# copyExperimentInfos should understand a Workspace2D input, either of which will need changes to Mantid.
ws_out = CreateMDHistoWorkspace(SignalInput=ws_out.extractY(), ErrorInput=ws_out.extractE(), Dimensionality=1,
Extents=extents, NumberOfBins=xdim.getNBins(), Names=name, Units=unit,
StoreInADS=False)
StoreInADS=False, EnableLogging=False)
ws_out.copyExperimentInfos(_tmpws)
DeleteWorkspace(_tmpws, EnableLogging=False)

Expand All @@ -112,6 +122,10 @@ def _cut_nonPSD_theta(cut_binning, int_binning, selected_workspace):


def _cut_nonPSD_momentum(q_binning, e_binning, emode, selected_workspace):
ws_out = SofQW3(InputWorkspace=selected_workspace, OutputWorkspace='out', EMode=emode, QAxisBinning=q_binning,
EAxisBinning=e_binning, StoreInADS=False)
if 'Indirect' in emode and selected_workspace.run().hasProperty('Efix'):
ws_out = SofQW3(InputWorkspace=selected_workspace, QAxisBinning=q_binning, EAxisBinning=e_binning, EMode=emode,
StoreInADS=False, EFixed=selected_workspace.run().getProperty('Efix').value)
else:
ws_out = SofQW3(InputWorkspace=selected_workspace, OutputWorkspace='out', EMode=emode, QAxisBinning=q_binning,
EAxisBinning=e_binning, StoreInADS=False)
return ws_out
8 changes: 6 additions & 2 deletions mslice/models/slice/slice_algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,12 @@ def _compute_slice_nonPSD(self, workspace, x_axis, y_axis, e_mode, norm_to_one):
ebin = '%f, %f, %f' % (axes[e_axis].start_meV, axes[e_axis].step_meV, axes[e_axis].end_meV)
qbin = '%f, %f, %f' % (axes[q_axis].start_meV, axes[q_axis].step_meV, axes[q_axis].end_meV)
if axes[q_axis].units == '|Q|':
thisslice = SofQW3(InputWorkspace=workspace, QAxisBinning=qbin, EAxisBinning=ebin, EMode=e_mode,
StoreInADS=False)
if 'Indirect' in e_mode and workspace.run().hasProperty('Efix'):
thisslice = SofQW3(InputWorkspace=workspace, QAxisBinning=qbin, EAxisBinning=ebin, EMode=e_mode,
StoreInADS=False, EFixed=workspace.run().getProperty('Efix').value)
else:
thisslice = SofQW3(InputWorkspace=workspace, QAxisBinning=qbin, EAxisBinning=ebin, EMode=e_mode,
StoreInADS=False)
elif axes[q_axis].units == '2Theta':
thisslice = ConvertSpectrumAxis(InputWorkspace=workspace, Target='Theta', StoreInADS=False)
thisslice = Rebin2D(InputWorkspace=thisslice, Axis1Binning=ebin, Axis2Binning=qbin, StoreInADS=False)
Expand Down
2 changes: 1 addition & 1 deletion mslice/models/slice/slice_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ def _compute_powder_line_momentum(ws_name, q_axis, element, cif_file):
def _crystal_structure(ws_name, element, cif_file):
if cif_file:
ws = get_workspace_handle(ws_name).raw_ws
LoadCIF(InputWorkspace=ws, InputFile=cif_file)
LoadCIF(Workspace=ws, InputFile=cif_file)
return ws.sample().getCrystalStructure()
else:
return CrystalStructure(crystal_structure[element][0], crystal_structure[element][1],
Expand Down
5 changes: 3 additions & 2 deletions mslice/models/workspacemanager/workspace_algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ def processEfixed(workspace):
def _processLoadedWSLimits(workspace):
""" Processes an (angle-deltaE) workspace to get the limits and step size in angle, energy and |Q| """
# For cases, e.g. indirect, where EFixed has not been set yet, return calculate later.
workspace.e_fixed = get_EFixed(workspace.raw_ws)
if workspace.e_fixed is None:
return
workspace.e_fixed = get_EFixed(workspace.raw_ws)
if workspace.e_fixed is None:
return
if isinstance(workspace, PixelWorkspace):
process_limits_event(workspace)
elif isinstance(workspace, Workspace):
Expand Down
4 changes: 3 additions & 1 deletion mslice/presenters/data_loader_presenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import os

from .busy import show_busy
from mslice.models.workspacemanager.workspace_algorithms import load
from mslice.models.workspacemanager.workspace_algorithms import load, get_limits
from mslice.models.workspacemanager.workspace_provider import get_workspace_handle, get_visible_workspace_names
from mslice.presenters.interfaces.data_loader_presenter import DataLoaderPresenterInterface
from mslice.presenters.presenter_utility import PresenterUtility
Expand Down Expand Up @@ -74,6 +74,8 @@ def check_efixed(self, ws_name, multi=False):
Ef, allChecked = self._view.get_workspace_efixed(ws_name, multi, self._EfCache)
self._EfCache = Ef
ws.e_fixed = Ef
ws.raw_ws.run().addProperty('Efix', Ef, True)
get_limits(ws_name, 'DeltaE') # This is call needed to process the limits.
return allChecked

def _confirm_workspace_overwrite(self, ws_name):
Expand Down
16 changes: 12 additions & 4 deletions mslice/tests/data_loader_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from mslice.presenters.data_loader_presenter import DataLoaderPresenter
from mslice.presenters.interfaces.main_presenter import MainPresenterInterface
from mslice.widgets.dataloader.dataloader import DataLoaderWidget
from mslice.workspace.workspace import Workspace


class DataLoaderTest(unittest.TestCase):
Expand All @@ -20,15 +21,16 @@ def setUp(self):
self.presenter = DataLoaderPresenter(self.view)
self.presenter.register_master(self.main_presenter)

@patch('mslice.models.workspacemanager.workspace_algorithms.process_limits')
@patch('mslice.presenters.data_loader_presenter.load')
@patch('mslice.presenters.data_loader_presenter.get_workspace_handle')
def test_load_one_workspace(self, get_ws_handle_mock, load_mock):
def test_load_one_workspace(self, get_ws_handle_mock, load_mock, process_limits):
# Create a view that will return a path on call to get_workspace_to_load_path
tempdir = gettempdir() # To ensure sample paths are valid on platform of execution
path_to_nexus = join(tempdir, 'cde.nxs')
workspace_name = 'cde'
self.view.get_workspace_efixed = mock.Mock(return_value=(1.845, False))
ws_mock = mock.Mock()
ws_mock = mock.Mock(spec=Workspace)
get_ws_handle_mock.return_value = ws_mock
e_fixed = PropertyMock()
e_mode = PropertyMock(return_value="Indirect")
Expand All @@ -37,9 +39,15 @@ def test_load_one_workspace(self, get_ws_handle_mock, load_mock):
type(ws_mock).e_mode = e_mode
type(ws_mock).ef_defined = ef_defined

self.presenter.load_workspace([path_to_nexus])
with patch('mslice.models.workspacemanager.workspace_algorithms.get_workspace_handle') as gwh:
gwh.return_value = ws_mock
limits = PropertyMock(side_effect=({} if i < 2 else {'DeltaE':[-1, 1]} for i in range(6)))
type(ws_mock).limits = limits
e_fixed.return_value = 1.845
self.presenter.load_workspace([path_to_nexus])
load_mock.assert_called_with(filename=path_to_nexus, output_workspace=workspace_name)
e_fixed.assert_called_once_with(1.845)
e_fixed.assert_has_calls([call(1.845), call()])
process_limits.assert_called_once_with(ws_mock)
self.main_presenter.show_workspace_manager_tab.assert_called_once()
self.main_presenter.show_tab_for_workspace.assert_called_once()
self.main_presenter.update_displayed_workspaces.assert_called_once()
Expand Down

0 comments on commit 2633351

Please sign in to comment.