Skip to content

Commit

Permalink
Merge pull request #300 from mantidproject/297_remember_cut_axes
Browse files Browse the repository at this point in the history
Remembering cut axes in non-PSD mode
  • Loading branch information
martyngigg authored Mar 29, 2018
2 parents 5475ea3 + d20eaf8 commit 88b73eb
Show file tree
Hide file tree
Showing 14 changed files with 68 additions and 39 deletions.
11 changes: 1 addition & 10 deletions mslice/app/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@
from mslice.presenters.main_presenter import MainPresenter
from mslice.util.qt import load_ui
from mslice.views.mainview import MainView
from mslice.widgets.workspacemanager import TAB_2D, TAB_EVENT, TAB_HISTO, TAB_NONPSD
from mslice.widgets.workspacemanager.command import Command as ws_command
from mslice.widgets.cut.command import Command as cut_command

TAB_2D = 0
TAB_EVENT = 1
TAB_HISTO = 2
TAB_NONPSD = 3
TAB_SLICE = 1
TAB_CUT = 2
TAB_POWDER = 0
Expand Down Expand Up @@ -54,7 +51,6 @@ def __init__(self):
self.cut_presenter.set_workspace_provider(workspace_provider)

self.wgtWorkspacemanager.tab_changed.connect(self.ws_tab_changed)
self.wgtWorkspacemanager.nonpsd.connect(self.switch_nonpsd_mode)
self.setup_save()
self.btnSave.clicked.connect(self.button_save)
self.btnAdd.clicked.connect(self.button_add)
Expand Down Expand Up @@ -93,13 +89,8 @@ def ws_tab_changed(self, tab):
self.enable_widget_tabs(tab)
self.enable_buttons(tab)

def switch_nonpsd_mode(self, nonpsd):
self.wgtCut.enable_integration_axis(nonpsd)
self.wgtSlice.enable_units_choice(nonpsd)

def enable_widget_tabs(self, workspace_tab):
'''enables correct powder/slice/cut tabs based on workspace tab'''
self.btnMerge.setEnabled(workspace_tab == TAB_EVENT)
self.tabWidget_2.show()
tab_to_show = self.tabs_to_show[workspace_tab]
for tab_index in range(3):
Expand Down
1 change: 1 addition & 0 deletions mslice/models/cut/cut_plotter.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class CutPlotter(object):
def __init__(self, _cut_algorithm):
self.workspace_provider = None
raise Exception('This class is an interface')

def plot_cut(self, selected_workspace, cut_axis, integration_axis, norm_to_one, intensity_start,
Expand Down
10 changes: 7 additions & 3 deletions mslice/presenters/cut_presenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,16 @@ def workspace_selection_changed(self):
self._previous_cut = None
self._previous_axis = None
workspace_selection = self._main_presenter.get_selected_workspaces()
if len(workspace_selection) < 1:
if len(workspace_selection) == 0 or not all([self._cut_algorithm.is_cuttable(ws)
for ws in workspace_selection]):
self._cut_view.clear_input_fields()
self._cut_view.disable()
self._previous_cut = None
self._previous_axis = None
return
self._populate_fields_using_workspace(workspace_selection[0])
else:
non_psd = all([not self._cut_plotter.workspace_provider.is_PSD(ws) for ws in workspace_selection])
self._cut_view.enable_integration_axis(non_psd)
self._populate_fields_using_workspace(workspace_selection[0])

def _populate_fields_using_workspace(self, workspace, plotting=False):
if self._cut_algorithm.is_cuttable(workspace):
Expand Down Expand Up @@ -217,6 +220,7 @@ def _populate_fields_using_workspace(self, workspace, plotting=False):
self._cut_view.populate_cut_axis_options(axis)
self._cut_view.enable()
self._cut_view.set_cut_axis(current_axis)
self._cut_view.update_integration_axis()
if not plotting and saved_parameters is not None:
self._cut_view.populate_input_fields(saved_parameters)
self._previous_cut = workspace
Expand Down
24 changes: 13 additions & 11 deletions mslice/presenters/slice_plotter_presenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,16 @@ def workspace_selection_changed(self):
if len(workspace_selection) != 1 or not self._slice_plotter.is_sliceable(workspace_selection[0]):
self._slice_view.clear_input_fields()
self._slice_view.disable()
return
workspace_selection = workspace_selection[0]
else:
non_psd = all([not self._slice_plotter.workspace_provider.is_PSD(ws) for ws in workspace_selection])
workspace_selection = workspace_selection[0]

self._slice_view.enable()
axis = self._slice_plotter.get_available_axis(workspace_selection)
self._slice_view.populate_slice_x_options(axis)
self._slice_view.populate_slice_y_options(axis[::-1])
self.populate_slice_params()
self._slice_view.enable()
self._slice_view.enable_units_choice(non_psd)
axis = self._slice_plotter.get_available_axis(workspace_selection)
self._slice_view.populate_slice_x_options(axis)
self._slice_view.populate_slice_y_options(axis[::-1])
self.populate_slice_params()

def populate_slice_params(self):
try:
Expand All @@ -162,10 +164,10 @@ def populate_slice_params(self):
except (KeyError, RuntimeError, IndexError):
self._slice_view.clear_input_fields()
self._slice_view.disable()
return
self._slice_view.enable()
self._slice_view.populate_slice_x_params(*["%.5f" % x for x in (x_min, x_max, x_step)])
self._slice_view.populate_slice_y_params(*["%.5f" % x for x in (y_min, y_max, y_step)])
else:
self._slice_view.enable()
self._slice_view.populate_slice_x_params(*["%.5f" % x for x in (x_min, x_max, x_step)])
self._slice_view.populate_slice_y_params(*["%.5f" % x for x in (y_min, y_max, y_step)])

def invalidate_slice_cache(self):
self._slice_plotter.slice_cache.clear()
Expand Down
14 changes: 13 additions & 1 deletion mslice/presenters/workspace_manager_presenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@
from six import string_types

from mslice.widgets.workspacemanager.command import Command
from mslice.widgets.workspacemanager import TAB_2D, TAB_NONPSD
from mslice.models.workspacemanager.file_io import get_save_directory
from .interfaces.workspace_manager_presenter import WorkspaceManagerPresenterInterface
from .interfaces.main_presenter import MainPresenterInterface
from .validation_decorators import require_main_presenter



class WorkspaceManagerPresenter(WorkspaceManagerPresenterInterface):
def __init__(self, workspace_view, workspace_provider):
# TODO add validation checks
self._workspace_manager_view = workspace_view
self._workspace_provider = workspace_provider
self._main_presenter = None
self._psd = True

def register_master(self, main_presenter):
assert (isinstance(main_presenter, MainPresenterInterface))
Expand Down Expand Up @@ -48,6 +49,7 @@ def notify(self, command):
self._workspace_manager_view.busy.emit(False)

def _broadcast_selected_workspaces(self):
self.workspace_selection_changed()
self._get_main_presenter().notify_workspace_selection_changed()

@require_main_presenter
Expand All @@ -60,6 +62,16 @@ def change_tab(self, tab):
def highlight_tab(self, tab):
self._workspace_manager_view.highlight_tab(tab)

def workspace_selection_changed(self):
if self._workspace_manager_view.current_tab() == TAB_2D:
psd = all([self.get_workspace_provider().is_PSD(ws) for ws in self._workspace_manager_view.get_workspace_selected()])
if psd and not self._psd:
self._workspace_manager_view.tab_changed.emit(TAB_2D)
self._psd = True
elif not psd and self._psd:
self._workspace_manager_view.tab_changed.emit(TAB_NONPSD)
self._psd = False

def _confirm_workspace_overwrite(self, ws_name):
if ws_name in self._workspace_provider.get_workspace_names():
return self._workspace_manager_view.confirm_overwrite_workspace()
Expand Down
10 changes: 10 additions & 0 deletions mslice/tests/cut_presenter_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from mslice.models.cut.cut_algorithm import CutAlgorithm
from mslice.models.cut.cut_plotter import CutPlotter
from mslice.models.workspacemanager.workspace_provider import WorkspaceProvider
from mslice.presenters.cut_presenter import CutPresenter
from mslice.presenters.interfaces.main_presenter import MainPresenterInterface
from mslice.presenters.slice_plotter_presenter import Axis
Expand Down Expand Up @@ -66,6 +67,8 @@ def test_workspace_selection_changed_single_cuttable_workspace(self):
self.cut_algorithm.get_available_axis = mock.Mock(return_value=available_dimensions)
self.cut_algorithm.set_cut_axis = mock.Mock
self.cut_algorithm.get_saved_cut_parameters = mock.Mock(return_value=(None, None))
self.cut_plotter.workspace_provider = mock.create_autospec(WorkspaceProvider)
self.cut_plotter.workspace_provider.is_PSD = mock.Mock(return_value=True)
cut_presenter.workspace_selection_changed()
self.view.populate_cut_axis_options.assert_called_with(available_dimensions)
self.view.enable.assert_called_with()
Expand Down Expand Up @@ -95,6 +98,8 @@ def test_workspace_selection_changed_single_noncut_workspace(self):
self.main_presenter.get_selected_workspaces = mock.Mock(return_value=[workspace])
self.cut_algorithm.is_cuttable = mock.Mock(return_value=False)
self.cut_algorithm.is_cut = mock.Mock(return_value=False)
self.cut_plotter.workspace_provider = mock.create_autospec(WorkspaceProvider)
self.cut_plotter.workspace_provider.is_PSD = mock.Mock(return_value=True)
cut_presenter.workspace_selection_changed()
self.view.clear_input_fields.assert_called_with()
self.view.disable.assert_called_with()
Expand Down Expand Up @@ -343,6 +348,8 @@ def test_change_axis(self):
available_dimensions = ["dim1", "dim2"]
self.cut_algorithm.get_available_axis = mock.Mock(return_value=available_dimensions)
self.cut_algorithm.get_saved_cut_parameters = mock.Mock(return_value=(None, None))
self.cut_plotter.workspace_provider = mock.create_autospec(WorkspaceProvider)
self.cut_plotter.workspace_provider.is_PSD = mock.Mock(return_value=True)
cut_presenter.workspace_selection_changed()
# Set up a set of input values for this cut, then simulate changing axes.
fields1 = dict()
Expand Down Expand Up @@ -381,13 +388,16 @@ def test_cut_step_size(self):
workspace = 'workspace'
self.main_presenter.get_selected_workspaces = mock.Mock(return_value=[workspace])
self.cut_algorithm.is_cuttable = mock.Mock(return_value=True)
self.cut_plotter.workspace_provider = mock.create_autospec(WorkspaceProvider)
self.cut_plotter.workspace_provider.is_PSD = mock.Mock(return_value=True)
available_dimensions = ["dim1", "dim2"]
self.cut_algorithm.get_available_axis = mock.Mock(return_value=available_dimensions)
self.cut_algorithm.get_saved_cut_parameters = mock.Mock(return_value=(None, None))
cut_presenter.workspace_selection_changed()
self.cut_algorithm.get_axis_range.assert_any_call(workspace, available_dimensions[0])
self.cut_algorithm.get_axis_range.assert_any_call(workspace, available_dimensions[1])
self.cut_algorithm.get_axis_range = mock.Mock(side_effect=KeyError)

cut_presenter.workspace_selection_changed()
self.view.set_minimum_step.assert_called_with(None)

Expand Down
3 changes: 3 additions & 0 deletions mslice/tests/slice_plotter_presenter_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import unittest

from mslice.models.slice.slice_plotter import SlicePlotter
from mslice.models.workspacemanager.workspace_provider import WorkspaceProvider
from mslice.presenters.interfaces.main_presenter import MainPresenterInterface
from mslice.presenters.slice_plotter_presenter import SlicePlotterPresenter,Axis
from mslice.views.slice_plotter_view import SlicePlotterView
Expand Down Expand Up @@ -345,6 +346,8 @@ def test_workspace_selection_changed(self):
dims = ['dim1', 'dim2']
self.slice_plotter.get_available_axis = mock.Mock(return_value=dims)
self.slice_plotter.get_axis_range = mock.Mock(return_value=(0,1,0.1))
self.slice_plotter.workspace_provider = mock.create_autospec(WorkspaceProvider)
self.slice_plotter.workspace_provider.is_PSD = mock.Mock(return_value=True)
slice_plotter_presenter.workspace_selection_changed()
self.slice_view.populate_slice_x_options.assert_called()
self.slice_view.populate_slice_y_options.assert_called()
Expand Down
3 changes: 3 additions & 0 deletions mslice/views/cut_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ def populate_cut_params(self, cut_start=None, cut_end=None, cut_step=None):
def populate_integration_params(self, integration_start=None, integration_end=None):
pass

def enable_integration_axis(self, enabled):
pass

def enable(self):
pass

Expand Down
3 changes: 3 additions & 0 deletions mslice/views/slice_plotter_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ def populate_slice_x_params(self, x_start, x_end, x_step):
def populate_slice_y_params(self, y_start, y_end, y_step):
raise NotImplementedError("This method must be implemented in a concrete view before being called")

def enable_units_choice(self, enabled):
raise NotImplementedError("This method must be implemented in a concrete view before being called")

def clear_input_fields(self):
raise NotImplementedError("This method must be implemented in a concrete view before being called")

Expand Down
3 changes: 3 additions & 0 deletions mslice/views/workspace_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ def display_loaded_workspaces(self, workspaces):
def add_workspace_dialog(self):
raise NotImplementedError("This method must be implemented in a concrete view before being called")

def current_tab(self):
raise NotImplementedError("This method must be implemented in a concrete view before being called")

def get_workspace_to_load_path(self):
raise NotImplementedError("This method must be implemented in a concrete view before being called")

Expand Down
1 change: 0 additions & 1 deletion mslice/widgets/cut/cut.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ def populate_cut_axis_options(self, options):
for option in options:
self.cmbCutAxis.addItem(option)
self.cmbCutAxis.blockSignals(False)
self.update_integration_axis()

def populate_integration_axis_options(self, options):
self.cmbIntegrationAxis.blockSignals(True)
Expand Down
4 changes: 4 additions & 0 deletions mslice/widgets/workspacemanager/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
TAB_2D = 0
TAB_EVENT = 1
TAB_HISTO = 2
TAB_NONPSD = 3
1 change: 1 addition & 0 deletions mslice/widgets/workspacemanager/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
# Classes and functions
# -----------------------------------------------------------------------------


class Command(object):
SaveSelectedWorkspaceNexus = 1
RemoveSelectedWorkspaces = 2
Expand Down
19 changes: 6 additions & 13 deletions mslice/widgets/workspacemanager/workspacemanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@
from mslice.views.workspace_view import WorkspaceView
from .command import Command
from .subtract_input_box import SubtractInputBox

TAB_2D = 0
TAB_EVENT = 1
TAB_HISTO = 2
TAB_NONPSD = 3
from . import TAB_2D, TAB_EVENT, TAB_HISTO


class WorkspaceManagerWidget(WorkspaceView, QWidget):
Expand All @@ -23,14 +19,14 @@ class WorkspaceManagerWidget(WorkspaceView, QWidget):
error_occurred = Signal('QString')
tab_changed = Signal(int)
busy = Signal(bool)
nonpsd = Signal(bool)

def __init__(self, parent=None):
QWidget.__init__(self, parent)
load_ui(__file__, 'workspacemanager.ui', self)
self.button_mappings = {}
self._main_window = None
self.onscreen_workspaces = []
self.tab = None
self.tab_to_list = {TAB_2D: self.listWorkspaces2D,
TAB_EVENT: self.listWorkspacesEvent,
TAB_HISTO: self.listWorkspacesHisto}
Expand All @@ -45,6 +41,7 @@ def _display_error(self, error_string):

def tab_changed_method(self, tab_index):
self.clear_selection()
self.tab = tab_index
if self.tabWidget.tabText(tab_index)[-1:] == "*":
self.tabWidget.setTabText(tab_index, self.tabWidget.tabText(tab_index)[:-1])
self.tab_changed.emit(tab_index)
Expand All @@ -56,6 +53,9 @@ def clear_selection(self):
def current_list(self):
return self.tab_to_list[self.tabWidget.currentIndex()]

def current_tab(self):
return self.tab if self.tab is not None else self.tabWidget.currentIndex()

def change_tab(self, tab):
self.tabWidget.setCurrentIndex(tab)

Expand Down Expand Up @@ -180,13 +180,6 @@ def get_presenter(self):
return self._presenter

def list_item_changed(self):
if self.sender() == self.listWorkspaces2D:
if all([self._presenter.get_workspace_provider().is_PSD(ws) for ws in self.get_workspace_selected()]):
self.tab_changed.emit(TAB_2D)
self.nonpsd.emit(False)
else:
self.tab_changed.emit(TAB_NONPSD)
self.nonpsd.emit(True)
self._presenter.notify(Command.SelectionChanged)

def error_unable_to_save(self):
Expand Down

0 comments on commit 88b73eb

Please sign in to comment.