Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
1d7bafd
add initial toolbar
MialLewis Aug 12, 2025
70064a0
enable toggling of shape options
MialLewis Aug 12, 2025
57110a5
initial pass add selectors
MialLewis Aug 14, 2025
4a80592
add selector deactivation
MialLewis Aug 14, 2025
1319459
fix issues with weak refs to selectors
MialLewis Aug 15, 2025
4ff221b
finalise shape toolbar behaviour
MialLewis Aug 15, 2025
71aebaf
first pass model
MialLewis Aug 18, 2025
edde91e
add rect and elliptical masking to model
MialLewis Aug 19, 2025
9ffe34c
add intersecting line logic
MialLewis Aug 19, 2025
0674186
add polygon masking model logic
MialLewis Aug 20, 2025
3c036ce
add direct map application
MialLewis Aug 20, 2025
9b1d818
handle polygon error
MialLewis Aug 20, 2025
c97dfca
deactivate selector after error
MialLewis Aug 20, 2025
3438bbe
handle mask removal from model if esc pressed
MialLewis Aug 21, 2025
7f1cba3
add numeric axis and bin centring partially finished
MialLewis Aug 22, 2025
f2c1e84
correct spectrum num masking
MialLewis Aug 22, 2025
4a72197
fix edge case bugs
MialLewis Aug 27, 2025
c2a878e
disable masking on numeric y axis, handle tranpose
MialLewis Aug 28, 2025
ef5a632
disable masking for md workspaces
MialLewis Sep 2, 2025
1ff063f
correct sv tests
MialLewis Sep 2, 2025
f3fd49d
fix region selector tests
MialLewis Sep 3, 2025
c056cfb
use index rather than spec number
MialLewis Sep 3, 2025
e37257f
make code rabbit changes
MialLewis Sep 3, 2025
3f1c7a7
slight test refactor
MialLewis Sep 4, 2025
5430391
finish main presenter tests
MialLewis Sep 4, 2025
f267e33
finish presenter tests
MialLewis Sep 4, 2025
fb3415b
use spec num for masking
MialLewis Sep 5, 2025
34dc6a4
add masking model tests
MialLewis Sep 5, 2025
f8ea045
add masking model tests
MialLewis Sep 5, 2025
3859e59
add maskig model tests
MialLewis Sep 5, 2025
8064451
disable masking for refl gui
MialLewis Sep 5, 2025
075a4e9
revert terrible coderabbit suggestion
MialLewis Sep 5, 2025
8894894
readd accidently removed tests
MialLewis Sep 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Framework/Algorithms/src/MaskBins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ using DataObjects::EventWorkspace_const_sptr;
using DataObjects::EventWorkspace_sptr;

void MaskBins::init() {
declareWorkspaceInputProperties<MatrixWorkspace>("InputWorkspace",
"The name of the input workspace. Must contain histogram data.",
std::make_shared<HistogramValidator>());
declareWorkspaceInputProperties<MatrixWorkspace, static_cast<int>(IndexType::WorkspaceIndex) |
static_cast<int>(IndexType::SpectrumNum)>(
"InputWorkspace", "The name of the input workspace. Must contain histogram data.",
std::make_shared<HistogramValidator>());
declareProperty(std::make_unique<WorkspaceProperty<>>("OutputWorkspace", "", Direction::Output),
"The name of the Workspace containing the masked bins.");

Expand Down
10 changes: 8 additions & 2 deletions Framework/Algorithms/src/MaskBinsFromTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ void MaskBinsFromTable::init() {
std::make_unique<WorkspaceProperty<DataObjects::TableWorkspace>>("MaskingInformation", "", Direction::Input),
"Input TableWorkspace containing parameters, XMin and "
"XMax and either SpectraList or DetectorIDsList");
this->declareProperty(
std::make_unique<IndexTypeProperty>("InputWorkspaceIndexType", static_cast<int>(IndexType::SpectrumNum) |
static_cast<int>(IndexType::WorkspaceIndex)),
"Identity input index list as spectra or index numbers");
}

//----------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -75,7 +79,7 @@ void MaskBinsFromTable::maskBins(const API::MatrixWorkspace_sptr &dataws) {
maskbins->initialize();

// Set properties
g_log.debug() << "Input to MaskBins: SpetraList = '" << m_spectraVec[ib] << "'; Xmin = " << m_xminVec[ib]
g_log.debug() << "Input to MaskBins: SpectraList = '" << m_spectraVec[ib] << "'; Xmin = " << m_xminVec[ib]
<< ", Xmax = " << m_xmaxVec[ib] << ".\n";

if (firstloop) {
Expand All @@ -87,7 +91,9 @@ void MaskBinsFromTable::maskBins(const API::MatrixWorkspace_sptr &dataws) {
maskbins->setProperty("InputWorkspace", outputws);
}
maskbins->setProperty("OutputWorkspace", this->getPropertyValue("OutputWorkspace"));
maskbins->setPropertyValue("SpectraList", m_spectraVec[ib]);
const std::string &indexType = getProperty("InputWorkspaceIndexType");
maskbins->setPropertyValue("InputWorkspaceIndexType", indexType);
maskbins->setPropertyValue("InputWorkspaceIndexSet", m_spectraVec[ib]);
maskbins->setProperty("XMin", m_xminVec[ib]);
maskbins->setProperty("XMax", m_xmaxVec[ib]);

Expand Down
2 changes: 2 additions & 0 deletions qt/python/mantidqt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ set(PYTHON_WIDGET_QT5_ONLY_TESTS
mantidqt/widgets/sliceviewer/test/test_sliceviewer_cursortracker.py
mantidqt/widgets/sliceviewer/test/test_sliceviewer_imageinfowidget.py
mantidqt/widgets/sliceviewer/test/test_sliceviewer_lineplots.py
mantidqt/widgets/sliceviewer/test/test_sliceviewer_maskingpresenter.py
mantidqt/widgets/sliceviewer/test/test_sliceviewer_maskingmodel.py
mantidqt/widgets/sliceviewer/test/test_sliceviewer_model.py
mantidqt/widgets/sliceviewer/test/test_sliceviewer_movemousecursor.py
mantidqt/widgets/sliceviewer/test/test_sliceviewer_presenter.py
Expand Down
23 changes: 22 additions & 1 deletion qt/python/mantidqt/mantidqt/widgets/regionselector/presenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,13 @@ def __init__(self, ws=None, parent=None, view=None, image_info_widget=None):

self.notifyee = None
self.view = view if view else RegionSelectorView(self, parent, image_info_widget=image_info_widget)
super().__init__(ws, self.view.data_view)
super().__init__(ws, self.view.data_view, disable_masking_override=True)
self._selectors: list[Selector] = []
self._drawing_region = False

# For now, disable masking - not implemented for regionselector
self._toggle_masking_options(False)

if ws:
self._initialise_dimensions(ws)
self._set_workspace(ws)
Expand Down Expand Up @@ -258,3 +261,21 @@ def get_extra_image_info_columns(self, xdata, ydata):

def is_integer_frame(self):
return False, False

def masking(self, active):
pass

def rect_masking_clicked(self, active):
pass

def elli_masking_clicked(self, active):
pass

def poly_masking_clicked(self, active):
pass

def export_masking_clicked(self):
pass

def apply_masking_clicked(self):
pass
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from mantidqt.widgets.regionselector.presenter import RegionSelector
from mantidqt.widgets.sliceviewer.models.workspaceinfo import WS_TYPE
from mantid.api import MatrixWorkspace


class RegionSelectorTest(unittest.TestCase):
Expand All @@ -24,10 +25,10 @@ def tearDown(self) -> None:
self._ws_info_patcher.stop()

def test_matrix_workspaces_allowed(self):
self.assertIsNotNone(RegionSelector(Mock(), view=Mock()))
self.assertIsNotNone(RegionSelector(ws=Mock(spec=MatrixWorkspace), view=Mock()))

def test_show_all_data_not_called_on_creation(self):
region_selector = RegionSelector(ws=Mock(), view=Mock())
region_selector = RegionSelector(ws=Mock(spec=MatrixWorkspace), view=Mock())
region_selector.show_all_data_clicked = Mock()

region_selector.show_all_data_clicked.assert_not_called()
Expand All @@ -49,15 +50,15 @@ def test_creation_without_workspace(self):
def test_update_workspace_updates_model(self):
region_selector = RegionSelector(view=Mock())
region_selector.show_all_data_clicked = Mock()
mock_ws = Mock()
mock_ws = Mock(spec=MatrixWorkspace)

region_selector.update_workspace(mock_ws)

self.assertEqual(mock_ws, region_selector.model.ws)

def test_update_workspace_with_invalid_workspaces_fails(self):
invalid_types = [WS_TYPE.MDH, WS_TYPE.MDE, None]
mock_ws = Mock()
mock_ws = Mock(spec=MatrixWorkspace)
region_selector = RegionSelector(view=Mock())

for ws_type in invalid_types:
Expand All @@ -69,15 +70,15 @@ def test_update_workspace_updates_view(self):
mock_view = Mock()
region_selector = RegionSelector(view=mock_view)
region_selector.show_all_data_clicked = Mock()
mock_ws = Mock()
mock_ws = Mock(spec=MatrixWorkspace)

region_selector.update_workspace(mock_ws)

mock_view.set_workspace.assert_called_once_with(mock_ws)
region_selector.show_all_data_clicked.assert_called_once()

def test_add_rectangular_region_creates_selector(self):
region_selector = RegionSelector(ws=Mock(), view=self.mock_view)
region_selector = RegionSelector(ws=Mock(spec=MatrixWorkspace), view=self.mock_view)

region_selector.add_rectangular_region("test", "black", "/")

Expand All @@ -86,7 +87,7 @@ def test_add_rectangular_region_creates_selector(self):
self.assertEqual("test", region_selector._selectors[0].region_type())

def test_add_second_rectangular_region_deactivates_first_selector(self):
region_selector = RegionSelector(ws=Mock(), view=self.mock_view)
region_selector = RegionSelector(ws=Mock(spec=MatrixWorkspace), view=self.mock_view)

region_selector.add_rectangular_region("test", "black", "/")
region_selector._drawing_region = False
Expand All @@ -100,7 +101,7 @@ def test_add_second_rectangular_region_deactivates_first_selector(self):
def test_clear_workspace_will_clear_all_the_selectors_and_model_workspace(self):
region_selector = RegionSelector(view=self.mock_view)
region_selector.show_all_data_clicked = Mock()
mock_ws = Mock()
mock_ws = Mock(spec=MatrixWorkspace)

region_selector.update_workspace(mock_ws)
region_selector.add_rectangular_region("test", "black", "/")
Expand Down Expand Up @@ -176,7 +177,7 @@ def test_canvas_clicked_sets_only_one_selector_active_if_multiple_contain_point(
selector_two.set_active.assert_called_once_with(False)

def test_delete_key_pressed_will_do_nothing_if_no_selectors_exist(self):
region_selector = RegionSelector(ws=Mock(), view=Mock())
region_selector = RegionSelector(ws=Mock(spec=MatrixWorkspace), view=Mock())

event = Mock()
event.key = "delete"
Expand Down Expand Up @@ -228,7 +229,7 @@ def test_delete_key_pressed_will_notify_region_changed(self):
mock_observer.notifyRegionChanged.assert_called_once()

def test_mouse_moved_will_not_set_override_cursor_if_no_selectors_exist(self):
region_selector = RegionSelector(ws=Mock(), view=Mock())
region_selector = RegionSelector(ws=Mock(spec=MatrixWorkspace), view=Mock())
region_selector.view.set_override_cursor = Mock()

event = Mock()
Expand Down Expand Up @@ -275,7 +276,7 @@ def test_mouse_moved_will_set_override_cursor_if_hovering_over_active_selector(s
region_selector.view.set_override_cursor.assert_called_once_with(True)

def test_on_rectangle_selected_notifies_observer(self):
region_selector = RegionSelector(ws=Mock(), view=self.mock_view)
region_selector = RegionSelector(ws=Mock(spec=MatrixWorkspace), view=self.mock_view)
mock_observer = Mock()
region_selector.subscribe(mock_observer)

Expand All @@ -285,15 +286,15 @@ def test_on_rectangle_selected_notifies_observer(self):
mock_observer.notifyRegionChanged.assert_called_once()

def test_cancel_drawing_region_will_remove_last_selector(self):
region_selector = RegionSelector(ws=Mock(), view=self.mock_view)
region_selector = RegionSelector(ws=Mock(spec=MatrixWorkspace), view=self.mock_view)
region_selector.add_rectangular_region("test", "black", "/")
self.assertEqual(1, len(region_selector._selectors))
region_selector.cancel_drawing_region()
self.assertEqual(0, len(region_selector._selectors))

def test_when_multiple_region_adds_are_requested_only_one_region_is_added(self):
# Given
region_selector = RegionSelector(ws=Mock(), view=self.mock_view)
region_selector = RegionSelector(ws=Mock(spec=MatrixWorkspace), view=self.mock_view)
region_selector.add_rectangular_region("test", "black", "/")
self.assertEqual(1, len(region_selector._selectors))

Expand All @@ -305,11 +306,11 @@ def test_when_multiple_region_adds_are_requested_only_one_region_is_added(self):
self.assertEqual(region_selector._selectors[0]._region_type, "test2")

def test_cancel_drawing_region_with_no_selectors_does_not_crash(self):
region_selector = RegionSelector(ws=Mock(), view=Mock())
region_selector = RegionSelector(ws=Mock(spec=MatrixWorkspace), view=Mock())
region_selector.cancel_drawing_region()

def test_display_rectangular_region_creates_selector(self):
region_selector = RegionSelector(ws=Mock(), view=self._mock_view_with_axes_limits((2000, 10000), (0, 500)))
region_selector = RegionSelector(ws=Mock(spec=MatrixWorkspace), view=self._mock_view_with_axes_limits((2000, 10000), (0, 500)))
# The expected extents should be within the axes x and y limits
expected_extents = (4000, 6000, 100, 300)
region_type = "test"
Expand All @@ -321,22 +322,22 @@ def test_display_rectangular_region_creates_selector(self):

def test_display_rectangular_region_y1_out_of_bounds_does_not_add_selector(self):
y_limits = (200, 500)
region_selector = RegionSelector(ws=Mock(), view=self._mock_view_with_axes_limits((2000, 10000), y_limits))
region_selector = RegionSelector(ws=Mock(spec=MatrixWorkspace), view=self._mock_view_with_axes_limits((2000, 10000), y_limits))

region_selector.display_rectangular_region("test", "black", "/", y_limits[0] - 50, y_limits[1])

self.assertEqual(0, len(region_selector._selectors))

def test_display_rectangular_region_y2_out_of_bounds_does_not_add_selector(self):
y_limits = (200, 500)
region_selector = RegionSelector(ws=Mock(), view=self._mock_view_with_axes_limits((2000, 10000), y_limits))
region_selector = RegionSelector(ws=Mock(spec=MatrixWorkspace), view=self._mock_view_with_axes_limits((2000, 10000), y_limits))

region_selector.display_rectangular_region("test", "black", "/", y_limits[0], y_limits[1] + 50)

self.assertEqual(0, len(region_selector._selectors))

def test_display_rectangular_region_does_not_add_duplicate_selector(self):
region_selector = RegionSelector(ws=Mock(), view=self._mock_view_with_axes_limits((2000, 10000), (0, 500)))
region_selector = RegionSelector(ws=Mock(spec=MatrixWorkspace), view=self._mock_view_with_axes_limits((2000, 10000), (0, 500)))
# The expected extents should be within the axes x and y limits
expected_extents = (4000, 6000, 100, 300)
region_type = "test"
Expand All @@ -351,7 +352,7 @@ def test_display_rectangular_region_does_not_add_duplicate_selector(self):
self._check_rectangular_region(region_selector._selectors[0], region_type, expected_extents)

def test_display_rectangular_region_adds_second_different_selector(self):
region_selector = RegionSelector(ws=Mock(), view=self._mock_view_with_axes_limits((2000, 10000), (0, 500)))
region_selector = RegionSelector(ws=Mock(spec=MatrixWorkspace), view=self._mock_view_with_axes_limits((2000, 10000), (0, 500)))
# The expected extents should be within the axes x and y limits
expected_x_values = (4000, 6000)
first_y_values = (100, 200)
Expand All @@ -376,7 +377,7 @@ def _mock_selectors(selector_one_type="signal", selector_two_type="signal"):
selector_one.extents = [1, 2, 3, 4]
selector_two.extents = [5, 6, 7, 8]

region_selector = RegionSelector(ws=Mock(), view=Mock())
region_selector = RegionSelector(ws=Mock(spec=MatrixWorkspace), view=Mock())
region_selector._selectors.append(selector_one)
region_selector._selectors.append(selector_two)

Expand Down
Loading