Skip to content

Commit

Permalink
ROI support for RITS export (#1958)
Browse files Browse the repository at this point in the history
  • Loading branch information
JackEAllen authored Nov 22, 2023
2 parents 2d2e2e0 + ab79dcf commit c227fb2
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 31 deletions.
2 changes: 2 additions & 0 deletions docs/release_notes/next/feature-1957-rits-roi
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#1957 : ROI support for RITS export

26 changes: 13 additions & 13 deletions mantidimaging/gui/windows/spectrum_viewer/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

LOG = getLogger(__name__)

ROI_ALL = "all"
ROI_RITS = "rits_roi"


class SpecType(Enum):
SAMPLE = 1
Expand All @@ -44,7 +47,7 @@ def __init__(self, presenter: 'SpectrumViewerWindowPresenter'):
self.presenter = presenter
self._roi_id_counter = 0
self._roi_ranges = {}
self.default_roi_list = ["all"]
self.special_roi_list = [ROI_ALL]

def roi_name_generator(self) -> str:
"""
Expand Down Expand Up @@ -77,7 +80,7 @@ def set_stack(self, stack: Optional[ImageStack]) -> None:
return
self._roi_id_counter = 0
self.tof_range = (0, stack.data.shape[0] - 1)
self.set_new_roi(self.default_roi_list[0])
self.set_new_roi(ROI_ALL)

def set_new_roi(self, name: str) -> None:
"""
Expand Down Expand Up @@ -198,21 +201,18 @@ def save_rits(self, path: Path, normalized: bool) -> None:
if self._stack is None:
raise ValueError("No stack selected")

# Default_roi will likely need updating once UI is implemented
default_roi = self.default_roi_list[0]

tof = self.get_stack_time_of_flight()
if tof is None:
raise ValueError("No Time of Flights for sample. Make sure spectra log has been loaded")

# RITS expects ToF in μs
tof *= 1e6

transmission_error = np.zeros_like(tof)
transmission_error = np.full_like(tof, 0.1)
if normalized:
if self._normalise_stack is None:
raise RuntimeError("No normalisation stack selected")
transmission = self.get_spectrum(default_roi, SpecType.SAMPLE_NORMED)
transmission = self.get_spectrum(ROI_RITS, SpecType.SAMPLE_NORMED)
self.export_spectrum_to_rits(path, tof, transmission, transmission_error)
else:
LOG.error("Data is not normalised to open beam. This will not export to a valid RITS format")
Expand Down Expand Up @@ -266,8 +266,8 @@ def remove_roi(self, roi_name) -> None:
@param roi_name: The name of the ROI to remove
"""
if roi_name in self._roi_ranges.keys():
if roi_name in self.default_roi_list:
raise RuntimeError("Cannot remove the 'all' or 'roi' ROIs")
if roi_name in self.special_roi_list:
raise RuntimeError(f"Cannot remove ROI: {roi_name}")
del self._roi_ranges[roi_name]
else:
raise KeyError(
Expand All @@ -283,14 +283,14 @@ def rename_roi(self, old_name: str, new_name: str) -> None:
@raises RuntimeError: If the ROI is 'all'
"""
if old_name in self._roi_ranges.keys() and new_name not in self._roi_ranges.keys():
if old_name == self.default_roi_list[0]:
raise RuntimeError("Cannot rename the 'all' ROI")
if old_name in self.special_roi_list:
raise RuntimeError(f"Cannot remove ROI: {old_name}")
self._roi_ranges[new_name] = self._roi_ranges.pop(old_name)
else:
raise KeyError(f"Cannot rename {old_name} to {new_name} Available:{self._roi_ranges.keys()}")

def remove_all_roi(self) -> None:
"""
Remove all ROIs from the model excluding default ROI 'all'
Remove all ROIs from the model
"""
self._roi_ranges = {key: value for key, value in self._roi_ranges.items() if key in self.default_roi_list}
self._roi_ranges = {}
12 changes: 10 additions & 2 deletions mantidimaging/gui/windows/spectrum_viewer/presenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from logging import getLogger
from mantidimaging.core.data.dataset import StrictDataset
from mantidimaging.gui.mvp_base import BasePresenter
from mantidimaging.gui.windows.spectrum_viewer.model import SpectrumViewerWindowModel, SpecType
from mantidimaging.gui.windows.spectrum_viewer.model import SpectrumViewerWindowModel, SpecType, ROI_RITS

if TYPE_CHECKING:
from mantidimaging.gui.windows.spectrum_viewer.view import SpectrumViewerWindowView # pragma: no cover
Expand Down Expand Up @@ -75,6 +75,7 @@ def handle_sample_change(self, uuid: Optional['UUID']) -> None:
self.model.set_normalise_stack(norm_stack)

self.do_add_roi()
self.add_rits_roi()
self.view.set_normalise_error(self.model.normalise_issue())
self.show_new_sample()

Expand Down Expand Up @@ -205,6 +206,13 @@ def do_add_roi(self) -> None:
self.view.auto_range_image()
self.do_add_roi_to_table(roi_name)

def add_rits_roi(self) -> None:
roi_name = ROI_RITS
self.model.set_new_roi(roi_name)
self.view.spectrum.add_roi(self.model.get_roi(roi_name), roi_name)
self.view.set_spectrum(roi_name, self.model.get_spectrum(roi_name, self.spectrum_mode))
self.view.set_roi_alpha(0, ROI_RITS)

def do_add_roi_to_table(self, roi_name: str) -> None:
"""
Add a given ROI to the table by ROI name
Expand All @@ -224,7 +232,7 @@ def rename_roi(self, old_name: str, new_name: str) -> None:
self.view.spectrum.rename_roi(old_name, new_name)
self.model.rename_roi(old_name, new_name)

def do_remove_roi(self, roi_name=None) -> None:
def do_remove_roi(self, roi_name: str | None = None) -> None:
"""
Remove a given ROI from the table by ROI name or all ROIs from
the table if no name is passed as an argument
Expand Down
3 changes: 3 additions & 0 deletions mantidimaging/gui/windows/spectrum_viewer/roi_table_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ def row_data(self, row: int) -> list:
"""
return self._data[row]

def __getitem__(self, item: int) -> list:
return self.row_data(item)

def column_data(self, column: int) -> list:
"""
Return data from selected column
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def __init__(self) -> None:
self.nextRow()
self.spectrum = self.addPlot()

self.spectrum_data_dict: dict[str, np.ndarray] = {}
self.spectrum_data_dict: dict[str, np.ndarray | None] = {}
self.nextRow()
self._tof_range_label = self.addLabel()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ def test_WHEN_remove_all_rois_called_THEN_all_but_default_rois_removed(self):
self.model.set_new_roi("new_roi_2")
self.assertListEqual(self.model.get_list_of_roi_names(), ["all", "new_roi", "new_roi_2"])
self.model.remove_all_roi()
self.assertListEqual(self.model.get_list_of_roi_names(), ["all"])
self.assertListEqual(self.model.get_list_of_roi_names(), [])

def test_WHEN_roi_renamed_THEN_roi_name_changed_in_list_of_roi_names(self):
self.model.set_stack(generate_images())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,4 +256,4 @@ def test_WHEN_do_remove_roi_called_with_no_arguments_THEN_all_rois_removed(self)
self.presenter.do_add_roi()
self.assertEqual(["all", "roi", "roi_1", "roi_2"], self.presenter.model.get_list_of_roi_names())
self.presenter.do_remove_roi()
self.assertEqual(["all"], self.presenter.model.get_list_of_roi_names())
self.assertEqual([], self.presenter.model.get_list_of_roi_names())
29 changes: 16 additions & 13 deletions mantidimaging/gui/windows/spectrum_viewer/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from mantidimaging.core.utility import finder
from mantidimaging.gui.mvp_base import BaseMainWindowView
from mantidimaging.gui.widgets.dataset_selector import DatasetSelectorWidgetView
from .model import ROI_RITS
from .presenter import SpectrumViewerWindowPresenter, ExportMode
from mantidimaging.gui.widgets import RemovableRowTableView
from .spectrum_widget import SpectrumWidget
Expand Down Expand Up @@ -142,19 +143,22 @@ def on_visibility_change(self) -> None:
"""
When the visibility of an ROI is changed, update the visibility of the ROI in the spectrum widget
"""
for roi_item in range(self.roi_table_model.rowCount()):
if self.presenter.export_mode == ExportMode.ROI_MODE:
roi_name, _, roi_visible = self.roi_table_model.row_data(roi_item)
if self.presenter.export_mode == ExportMode.ROI_MODE:
for roi_name, _, roi_visible in self.roi_table_model:
if roi_visible is False:
self.set_roi_alpha(0, roi_name)
else:
self.set_roi_alpha(255, roi_name)
self.presenter.redraw_spectrum(roi_name)
else:
roi_name, _, _ = self.roi_table_model.row_data(roi_item)
else:
for roi_name, _, _ in self.roi_table_model:
self.set_roi_alpha(0, roi_name)

return
if self.presenter.export_mode == ExportMode.IMAGE_MODE:
self.set_roi_alpha(255, ROI_RITS)
self.presenter.redraw_spectrum(ROI_RITS)
else:
self.set_roi_alpha(0, ROI_RITS)

@property
def roi_table_model(self) -> TableModel:
Expand Down Expand Up @@ -209,9 +213,7 @@ def set_spectrum(self, name: str, spectrum_data: 'np.ndarray'):
self.spectrum.spectrum_data_dict[name] = spectrum_data
self.spectrum.spectrum.clearPlots()

for key, value in self.spectrum.spectrum_data_dict.items():
if key in self.spectrum.roi_dict:
self.spectrum.spectrum.plot(value, name=key, pen=self.spectrum.roi_dict[key].colour)
self.show_visible_spectrums()

def clear(self) -> None:
self.spectrum.spectrum_data_dict = {}
Expand Down Expand Up @@ -252,14 +254,15 @@ def set_roi_alpha(self, alpha: float, roi_name: str) -> None:
"""
self.spectrum.set_roi_alpha(roi_name, alpha)
if alpha == 0:
self.spectrum.spectrum_data_dict[roi_name] = np.zeros(self.spectrum.spectrum_data_dict[roi_name].shape)
else:
self.spectrum.spectrum_data_dict[roi_name] = self.spectrum.spectrum_data_dict[roi_name]
self.spectrum.spectrum_data_dict[roi_name] = None

self.spectrum.spectrum.clearPlots()
self.spectrum.spectrum.update()
self.show_visible_spectrums()

def show_visible_spectrums(self):
for key, value in self.spectrum.spectrum_data_dict.items():
if key in self.spectrum.roi_dict:
if value is not None and key in self.spectrum.roi_dict:
self.spectrum.spectrum.plot(value, name=key, pen=self.spectrum.roi_dict[key].colour)

def add_roi_table_row(self, name: str, colour: tuple[int, int, int]):
Expand Down

0 comments on commit c227fb2

Please sign in to comment.