From 1b996d28f456794d0819dc0baf46036d164ac8c4 Mon Sep 17 00:00:00 2001 From: Sam Tygier Date: Thu, 19 Sep 2024 15:52:30 +0100 Subject: [PATCH 1/9] do_nexus_saving: switch to Dataset, check if has sample --- mantidimaging/core/io/saver.py | 10 +++++----- mantidimaging/gui/windows/main/model.py | 12 ++++++------ mantidimaging/gui/windows/main/test/model_test.py | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/mantidimaging/core/io/saver.py b/mantidimaging/core/io/saver.py index b2efa277817..587f3579da0 100644 --- a/mantidimaging/core/io/saver.py +++ b/mantidimaging/core/io/saver.py @@ -22,7 +22,7 @@ from ..utility.version_check import CheckVersion if TYPE_CHECKING: - from ..data.dataset import StrictDataset + from ..data.dataset import Dataset from ..data.imagestack import ImageStack from ..utility.data_containers import Indices @@ -180,7 +180,7 @@ def image_save(images: ImageStack, return names -def nexus_save(dataset: StrictDataset, path: str, sample_name: str, save_as_float: bool) -> None: +def nexus_save(dataset: Dataset, path: str, sample_name: str, save_as_float: bool) -> None: """ Uses information from a StrictDataset to create a NeXus file. :param dataset: The dataset to save as a NeXus file. @@ -202,7 +202,7 @@ def nexus_save(dataset: StrictDataset, path: str, sample_name: str, save_as_floa nexus_file.close() -def _nexus_save(nexus_file: h5py.File, dataset: StrictDataset, sample_name: str, save_as_float: bool) -> None: +def _nexus_save(nexus_file: h5py.File, dataset: Dataset, sample_name: str, save_as_float: bool) -> None: """ Takes a NeXus file and writes the StrictDataset information to it. :param nexus_file: The NeXus file. @@ -255,7 +255,7 @@ def _nexus_save(nexus_file: h5py.File, dataset: StrictDataset, sample_name: str, _save_recon_to_nexus(nexus_file, recon, dataset.sample.filenames[0]) -def _save_processed_data_to_nexus(nexus_file: h5py.File, dataset: StrictDataset, rotation_angle: h5py.Dataset, +def _save_processed_data_to_nexus(nexus_file: h5py.File, dataset: Dataset, rotation_angle: h5py.Dataset, image_key: h5py.Dataset, save_as_float: bool) -> None: data = nexus_file.create_group(NEXUS_PROCESSED_DATA_PATH) data["rotation_angle"] = rotation_angle @@ -270,7 +270,7 @@ def _save_processed_data_to_nexus(nexus_file: h5py.File, dataset: StrictDataset, process.create_dataset("version", data=np.bytes_(package_version)) -def _save_image_stacks_to_nexus(dataset: StrictDataset, data_group: h5py.Group, save_as_float: bool) -> None: +def _save_image_stacks_to_nexus(dataset: Dataset, data_group: h5py.Group, save_as_float: bool) -> None: combined_data_shape = (sum([len(arr) for arr in dataset.nexus_arrays]), ) + dataset.nexus_arrays[0].shape[1:] index = 0 diff --git a/mantidimaging/gui/windows/main/model.py b/mantidimaging/gui/windows/main/model.py index 1a6095bd2f8..fa9473f00ea 100644 --- a/mantidimaging/gui/windows/main/model.py +++ b/mantidimaging/gui/windows/main/model.py @@ -87,13 +87,13 @@ def do_images_saving(self, images_id: uuid.UUID, output_dir: str, name_prefix: s images.filenames = filenames return True - def do_nexus_saving(self, dataset_id: uuid.UUID, path: str, sample_name: str, save_as_float: bool) -> bool: + def do_nexus_saving(self, dataset_id: uuid.UUID, path: str, sample_name: str, save_as_float: bool) -> None: dataset = self.datasets.get(dataset_id) - if isinstance(dataset, StrictDataset): - saver.nexus_save(dataset, path, sample_name, save_as_float) - return True - else: - raise RuntimeError(f"Failed to get StrictDataset with ID {dataset_id}") + if not dataset: + raise RuntimeError(f"Failed to get Dataset with ID {dataset_id}") + if not dataset.sample: + raise RuntimeError(f"Dataset with ID {dataset_id} does not have a sample") + saver.nexus_save(dataset, path, sample_name, save_as_float) def get_existing_180_id(self, dataset_id: uuid.UUID) -> uuid.UUID | None: """ diff --git a/mantidimaging/gui/windows/main/test/model_test.py b/mantidimaging/gui/windows/main/test/model_test.py index 23e6d8ba364..b2ee2e3321a 100644 --- a/mantidimaging/gui/windows/main/test/model_test.py +++ b/mantidimaging/gui/windows/main/test/model_test.py @@ -522,7 +522,7 @@ def test_do_nexus_saving_fails_from_no_dataset(self): self.model.do_nexus_saving("bad-dataset-id", "path", "sample-name", True) def test_do_nexus_saving_fails_from_wrong_dataset(self): - md = MixedDataset() + md = Dataset() # no sample self.model.add_dataset_to_model(md) with self.assertRaises(RuntimeError): @@ -530,7 +530,7 @@ def test_do_nexus_saving_fails_from_wrong_dataset(self): @mock.patch("mantidimaging.gui.windows.main.model.saver.nexus_save") def test_do_nexus_save_success(self, nexus_save): - sd = StrictDataset(sample=generate_images()) + sd = Dataset(sample=generate_images()) self.model.add_dataset_to_model(sd) path = "path" sample_name = "sample-name" From 3d4f530f88ce18b88bccb21c004e334252cf7638 Mon Sep 17 00:00:00 2001 From: Sam Tygier Date: Mon, 23 Sep 2024 14:38:49 +0100 Subject: [PATCH 2/9] SpectrumViewerWindowPresenter: handle any dataset type --- mantidimaging/gui/windows/spectrum_viewer/presenter.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mantidimaging/gui/windows/spectrum_viewer/presenter.py b/mantidimaging/gui/windows/spectrum_viewer/presenter.py index 5c74f325188..077d08fabe8 100644 --- a/mantidimaging/gui/windows/spectrum_viewer/presenter.py +++ b/mantidimaging/gui/windows/spectrum_viewer/presenter.py @@ -11,7 +11,6 @@ import numpy as np from PyQt5.QtCore import QSignalBlocker -from mantidimaging.core.data.dataset import StrictDataset from mantidimaging.core.utility.sensible_roi import SensibleROI from mantidimaging.gui.dialogs.async_task import start_async_task_view, TaskWorkerThread from mantidimaging.gui.mvp_base import BasePresenter @@ -158,7 +157,7 @@ def auto_find_flat_stack(self, new_dataset_id: UUID) -> None: self.view.current_dataset_id = new_dataset_id new_dataset = self.main_window.get_dataset(new_dataset_id) - if isinstance(new_dataset, StrictDataset): + if new_dataset is not None: if new_dataset.flat_before is not None: self.view.try_to_select_relevant_normalise_stack(new_dataset.flat_before.name) elif new_dataset.flat_after is not None: From ef66b174b4e5ea225d5a2049bbec32203540f37d Mon Sep 17 00:00:00 2001 From: Sam Tygier Date: Mon, 23 Sep 2024 15:15:10 +0100 Subject: [PATCH 3/9] MainWindowModel: move things to use Dataset --- mantidimaging/gui/windows/main/model.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mantidimaging/gui/windows/main/model.py b/mantidimaging/gui/windows/main/model.py index fa9473f00ea..1974139b33b 100644 --- a/mantidimaging/gui/windows/main/model.py +++ b/mantidimaging/gui/windows/main/model.py @@ -187,9 +187,9 @@ def remove_container(self, container_id: uuid.UUID) -> list[uuid.UUID]: for dataset in self.datasets.values(): if container_id in dataset: proj_180_id = None - # If we're deleting a sample from a StrictDataset then any linked 180 projection will also be + # If we're deleting a sample then any linked 180 projection will also be # deleted - if isinstance(dataset, StrictDataset) and dataset.proj180deg: + if dataset.proj180deg: assert dataset.sample is not None if dataset.sample.id == container_id: proj_180_id = dataset.proj180deg.id @@ -222,13 +222,13 @@ def images(self) -> list[ImageStack]: def proj180s(self) -> list[ImageStack]: proj180s = [] for dataset in self.datasets.values(): - if isinstance(dataset, StrictDataset) and dataset.proj180deg is not None: + if dataset.proj180deg is not None: proj180s.append(dataset.proj180deg) return proj180s def get_parent_dataset(self, member_id: uuid.UUID) -> uuid.UUID: """ - Takes the ID of an image stack and returns the ID of its parent strict dataset. + Takes the ID of an image stack and returns the ID of its parent dataset. :param member_id: The ID of the image stack. :return: The ID of the parent dataset if found. """ From 851d3941045cb0741ce9cc4ba24ecf069cf884da Mon Sep 17 00:00:00 2001 From: Sam Tygier Date: Mon, 23 Sep 2024 15:52:50 +0100 Subject: [PATCH 4/9] MoveStackPresenter unify datasets --- .../windows/move_stack_dialog/presenter.py | 16 ++++++--------- .../move_stack_dialog/test/presenter_test.py | 20 +++++-------------- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/mantidimaging/gui/windows/move_stack_dialog/presenter.py b/mantidimaging/gui/windows/move_stack_dialog/presenter.py index 91f419dbe26..4ccaf967d5f 100644 --- a/mantidimaging/gui/windows/move_stack_dialog/presenter.py +++ b/mantidimaging/gui/windows/move_stack_dialog/presenter.py @@ -9,8 +9,7 @@ if TYPE_CHECKING: from mantidimaging.gui.windows.move_stack_dialog.view import MoveStackDialog -STRICT_DATASET_ATTRS = ["Sample", "Flat Before", "Flat After", "Dark Before", "Dark After", "Recon"] -MIXED_DATASET_TYPES = ["Images", "Recon"] +DATASET_ATTRS = ["Sample", "Flat Before", "Flat After", "Dark Before", "Dark After", "Images", "Recon"] class Notification(Enum): @@ -45,12 +44,9 @@ def _on_dataset_changed(self): """ self.view.destinationTypeComboBox.clear() - if self.view.datasetSelector.current_is_strict(): - if self.view.datasetSelector.current() == self.view.origin_dataset_id: - same_ds_list = STRICT_DATASET_ATTRS.copy() - same_ds_list.remove(self.view.originDataType.text()) - self.view.destinationTypeComboBox.addItems(same_ds_list) - else: - self.view.destinationTypeComboBox.addItems(STRICT_DATASET_ATTRS) + if self.view.datasetSelector.current() == self.view.origin_dataset_id: + same_ds_list = DATASET_ATTRS.copy() + same_ds_list.remove(self.view.originDataType.text()) + self.view.destinationTypeComboBox.addItems(same_ds_list) else: - self.view.destinationTypeComboBox.addItems(MIXED_DATASET_TYPES) + self.view.destinationTypeComboBox.addItems(DATASET_ATTRS) diff --git a/mantidimaging/gui/windows/move_stack_dialog/test/presenter_test.py b/mantidimaging/gui/windows/move_stack_dialog/test/presenter_test.py index 61aa6baedbf..44679214f6d 100644 --- a/mantidimaging/gui/windows/move_stack_dialog/test/presenter_test.py +++ b/mantidimaging/gui/windows/move_stack_dialog/test/presenter_test.py @@ -4,8 +4,7 @@ import unittest from unittest import mock -from mantidimaging.gui.windows.move_stack_dialog.presenter import MoveStackPresenter, Notification, \ - STRICT_DATASET_ATTRS, MIXED_DATASET_TYPES +from mantidimaging.gui.windows.move_stack_dialog.presenter import MoveStackPresenter, Notification, DATASET_ATTRS from mantidimaging.gui.windows.move_stack_dialog.view import MoveStackDialog @@ -35,29 +34,20 @@ def test_notify_exception(self): self.presenter.notify(Notification.ACCEPTED) self.view.show_error_dialog.assert_called_once() - def test_destination_combo_box_when_moving_to_same_strict_dataset(self): - self.view.datasetSelector.current_is_strict.return_value = True + def test_destination_combo_box_when_moving_to_same_dataset(self): self.view.datasetSelector.current.return_value = self.view.origin_dataset_id = "dataset-id" self.view.originDataType.text.return_value = origin_data_type = "Flat Before" self.presenter.notify(Notification.DATASET_CHANGED) self.view.destinationTypeComboBox.clear.assert_called_once() - type_list = STRICT_DATASET_ATTRS.copy() + type_list = DATASET_ATTRS.copy() type_list.remove(origin_data_type) self.view.destinationTypeComboBox.addItems.assert_called_once_with(type_list) - def test_destination_combo_box_when_moving_to_different_strict_dataset(self): - self.view.datasetSelector.current_is_strict.return_value = True + def test_destination_combo_box_when_moving_to_different_dataset(self): self.view.datasetSelector.current.return_value = "dest-dataset-id" self.view.origin_dataset_id = "origin-dataset-id" self.presenter.notify(Notification.DATASET_CHANGED) self.view.destinationTypeComboBox.clear.assert_called_once() - self.view.destinationTypeComboBox.addItems.assert_called_once_with(STRICT_DATASET_ATTRS) - - def test_destination_combo_box_when_moving_to_mixed_dataset(self): - self.view.datasetSelector.current_is_strict.return_value = False - self.presenter.notify(Notification.DATASET_CHANGED) - - self.view.destinationTypeComboBox.clear.assert_called_once() - self.view.destinationTypeComboBox.addItems.assert_called_once_with(MIXED_DATASET_TYPES) + self.view.destinationTypeComboBox.addItems.assert_called_once_with(DATASET_ATTRS) From dc6f1bcb711615c2ae99c2f46848c9f7e54e8c5e Mon Sep 17 00:00:00 2001 From: Sam Tygier Date: Mon, 23 Sep 2024 16:05:43 +0100 Subject: [PATCH 5/9] Remove unused current_is_strict methods --- mantidimaging/gui/widgets/dataset_selector/presenter.py | 6 ------ .../gui/widgets/dataset_selector/test/presenter_test.py | 9 --------- .../gui/widgets/dataset_selector/test/view_test.py | 3 --- mantidimaging/gui/widgets/dataset_selector/view.py | 3 --- 4 files changed, 21 deletions(-) diff --git a/mantidimaging/gui/widgets/dataset_selector/presenter.py b/mantidimaging/gui/widgets/dataset_selector/presenter.py index f489791f81a..18524f2c9ae 100644 --- a/mantidimaging/gui/widgets/dataset_selector/presenter.py +++ b/mantidimaging/gui/widgets/dataset_selector/presenter.py @@ -97,9 +97,3 @@ def do_select_eligible_stack(self) -> None: if "dark" not in name and "flat" not in name and "180deg" not in name: self.view.setCurrentIndex(i) break - - @property - def current_is_strict(self) -> bool: - if self.current_dataset is None: - return False - return self.view.main_window.is_dataset_strict(self.current_dataset) diff --git a/mantidimaging/gui/widgets/dataset_selector/test/presenter_test.py b/mantidimaging/gui/widgets/dataset_selector/test/presenter_test.py index a3150f7c40e..d5373c41553 100644 --- a/mantidimaging/gui/widgets/dataset_selector/test/presenter_test.py +++ b/mantidimaging/gui/widgets/dataset_selector/test/presenter_test.py @@ -117,12 +117,3 @@ def test_do_reload_datasets_by_dataset_type(self): self.view.addItem.assert_any_call(self.img1.name, self.img1.id) self.view.addItem.assert_any_call(self.img2.name, self.img2.id) self.view.addItem.assert_any_call(self.img3.name, self.img3.id) - - def test_current_is_strict(self): - self.presenter.current_dataset = "current-dataset-id" - self.assertEqual(self.presenter.current_is_strict, self.view.main_window.is_dataset_strict.return_value) - self.view.main_window.is_dataset_strict.assert_called_once_with(self.presenter.current_dataset) - - def test_current_is_strict_returns_false_when_current_is_none(self): - self.presenter.current_dataset = None - self.assertFalse(self.presenter.current_is_strict) diff --git a/mantidimaging/gui/widgets/dataset_selector/test/view_test.py b/mantidimaging/gui/widgets/dataset_selector/test/view_test.py index 41c7b42034c..08980506e90 100644 --- a/mantidimaging/gui/widgets/dataset_selector/test/view_test.py +++ b/mantidimaging/gui/widgets/dataset_selector/test/view_test.py @@ -52,6 +52,3 @@ def test_try_to_select_relevant_stack(self): self.view.try_to_select_relevant_stack("flat") self.assertEqual(self.view.currentIndex(), 0) self.assertEqual(self.view.currentText(), "flat_0001") - - def test_current_is_strict(self): - self.assertEqual(self.view.current_is_strict(), self.presenter.current_is_strict) diff --git a/mantidimaging/gui/widgets/dataset_selector/view.py b/mantidimaging/gui/widgets/dataset_selector/view.py index 8a9e4bebf59..be2a5dc32b4 100644 --- a/mantidimaging/gui/widgets/dataset_selector/view.py +++ b/mantidimaging/gui/widgets/dataset_selector/view.py @@ -75,6 +75,3 @@ def try_to_select_relevant_stack(self, name: str) -> None: def select_eligible_stack(self) -> None: self.presenter.notify(Notification.SELECT_ELIGIBLE_STACK) - - def current_is_strict(self) -> bool: - return self.presenter.current_is_strict From 6da08e7f83d749e5f3ba5c6474d0bd84c1c21150 Mon Sep 17 00:00:00 2001 From: Sam Tygier Date: Mon, 23 Sep 2024 16:12:42 +0100 Subject: [PATCH 6/9] Remove unused is_dataset_strict methods --- mantidimaging/gui/windows/main/model.py | 12 ------------ mantidimaging/gui/windows/main/presenter.py | 3 --- mantidimaging/gui/windows/main/test/model_test.py | 14 -------------- .../gui/windows/main/test/presenter_test.py | 5 ----- mantidimaging/gui/windows/main/test/view_test.py | 5 ----- mantidimaging/gui/windows/main/view.py | 3 --- 6 files changed, 42 deletions(-) diff --git a/mantidimaging/gui/windows/main/model.py b/mantidimaging/gui/windows/main/model.py index 1974139b33b..459474f92c8 100644 --- a/mantidimaging/gui/windows/main/model.py +++ b/mantidimaging/gui/windows/main/model.py @@ -256,15 +256,3 @@ def recon_list_ids(self) -> list[uuid.UUID]: def get_recon_list_id(self, parent_id: uuid.UUID) -> uuid.UUID: return self.datasets[parent_id].recons.id - - def is_dataset_strict(self, ds_id: uuid.UUID) -> bool: - """ - :param ds_id: The dataset ID - :return: True if the dataset is Strict, False otherwise - """ - for ds in self.datasets.values(): - if ds.id == ds_id: - if isinstance(ds, StrictDataset): - return True - return False - raise RuntimeError(f"Unable to find dataset with ID {ds_id}") diff --git a/mantidimaging/gui/windows/main/presenter.py b/mantidimaging/gui/windows/main/presenter.py index 0c7c30e6af8..a3364398c09 100644 --- a/mantidimaging/gui/windows/main/presenter.py +++ b/mantidimaging/gui/windows/main/presenter.py @@ -843,9 +843,6 @@ def _create_strict_dataset_stack_name(stack_type: str, dataset_name: str) -> str """ return f"{stack_type} {dataset_name}" - def is_dataset_strict(self, ds_id: uuid.UUID) -> bool: - return self.model.is_dataset_strict(ds_id) - def do_update_UI(self) -> None: if settings.value('use_os_defaults', defaultValue='True') == 'True': extra_style = settings.value('extra_style_default') diff --git a/mantidimaging/gui/windows/main/test/model_test.py b/mantidimaging/gui/windows/main/test/model_test.py index b2ee2e3321a..8c830286f82 100644 --- a/mantidimaging/gui/windows/main/test/model_test.py +++ b/mantidimaging/gui/windows/main/test/model_test.py @@ -538,17 +538,3 @@ def test_do_nexus_save_success(self, nexus_save): self.model.do_nexus_saving(sd.id, path, sample_name, save_as_float) nexus_save.assert_called_once_with(sd, path, sample_name, save_as_float) - - def test_is_dataset_strict_returns_true(self): - strict_ds = StrictDataset(sample=generate_images()) - self.model.add_dataset_to_model(strict_ds) - self.assertTrue(self.model.is_dataset_strict(strict_ds.id)) - - def test_is_dataset_strict_returns_false(self): - mixed_ds = MixedDataset(stacks=[generate_images()]) - self.model.add_dataset_to_model(mixed_ds) - self.assertFalse(self.model.is_dataset_strict(mixed_ds.id)) - - def test_is_dataset_strict_raises(self): - with self.assertRaises(RuntimeError): - self.model.is_dataset_strict(uuid.uuid4()) diff --git a/mantidimaging/gui/windows/main/test/presenter_test.py b/mantidimaging/gui/windows/main/test/presenter_test.py index 96babbb8a79..58da11e7e79 100644 --- a/mantidimaging/gui/windows/main/test/presenter_test.py +++ b/mantidimaging/gui/windows/main/test/presenter_test.py @@ -1060,11 +1060,6 @@ def test_move_stack_to_strict_dataset(self): self.assertNotIn(stack_to_move, origin_dataset) assert stack_to_move.name == new_stack_name - def test_is_dataset_strict(self): - ds_id = "ds-id" - self.presenter.is_dataset_strict(ds_id) - self.model.is_dataset_strict.assert_called_once_with(ds_id) - if __name__ == '__main__': unittest.main() diff --git a/mantidimaging/gui/windows/main/test/view_test.py b/mantidimaging/gui/windows/main/test/view_test.py index d6f536bb963..965388b0871 100644 --- a/mantidimaging/gui/windows/main/test/view_test.py +++ b/mantidimaging/gui/windows/main/test/view_test.py @@ -515,11 +515,6 @@ def test_show_move_stack_dialog(self): stack_data_type) move_stack_mock.return_value.show.assert_called_once() - def test_is_dataset_strict(self): - ds_id = "ds-id" - self.view.is_dataset_strict(ds_id) - self.presenter.is_dataset_strict.assert_called_once_with(ds_id) - @mock.patch("PyQt5.QtWidgets.QFileDialog.getExistingDirectory") @mock.patch("mantidimaging.gui.windows.main.MainWindowView.show_live_viewer") def test_live_viewer_asks_for_data_dir(self, mock_show_live_viewer, mock_get_existing_dir): diff --git a/mantidimaging/gui/windows/main/view.py b/mantidimaging/gui/windows/main/view.py index 7ed92a420d1..28f7c8804a7 100644 --- a/mantidimaging/gui/windows/main/view.py +++ b/mantidimaging/gui/windows/main/view.py @@ -776,6 +776,3 @@ def show_move_stack_dialog(self, origin_dataset_id: uuid.UUID, stack_id: uuid.UU self.move_stack_dialog = MoveStackDialog(self, origin_dataset_id, stack_id, origin_dataset_name, stack_data_type) self.move_stack_dialog.show() - - def is_dataset_strict(self, ds_id: UUID) -> bool: - return self.presenter.is_dataset_strict(ds_id) From df32579c5ddd560e14c103052022d416b210aea3 Mon Sep 17 00:00:00 2001 From: Sam Tygier Date: Tue, 24 Sep 2024 14:38:46 +0100 Subject: [PATCH 7/9] Remove MainWindowView.strict_dataset_list --- mantidimaging/gui/windows/main/nexus_save_dialog.py | 10 ++++++---- mantidimaging/gui/windows/main/presenter.py | 13 ------------- .../gui/windows/main/test/nexus_save_test.py | 9 +++++---- .../gui/windows/main/test/presenter_test.py | 4 ++-- mantidimaging/gui/windows/main/test/view_test.py | 2 +- mantidimaging/gui/windows/main/view.py | 8 ++------ 6 files changed, 16 insertions(+), 30 deletions(-) diff --git a/mantidimaging/gui/windows/main/nexus_save_dialog.py b/mantidimaging/gui/windows/main/nexus_save_dialog.py index 78f1664d4db..ce286b63cca 100644 --- a/mantidimaging/gui/windows/main/nexus_save_dialog.py +++ b/mantidimaging/gui/windows/main/nexus_save_dialog.py @@ -3,11 +3,12 @@ from __future__ import annotations import os import uuid +from collections.abc import Iterable from PyQt5.QtWidgets import QDialogButtonBox, QFileDialog, QRadioButton +from mantidimaging.core.data.dataset import Dataset from mantidimaging.gui.mvp_base import BaseDialogView -from mantidimaging.gui.windows.main.presenter import DatasetId NXS_EXT = ".nxs" @@ -18,7 +19,7 @@ class NexusSaveDialog(BaseDialogView): floatRadioButton: QRadioButton intRadioButton: QRadioButton - def __init__(self, parent, dataset_list: list[DatasetId]): + def __init__(self, parent, dataset_list: Iterable[Dataset]): super().__init__(parent, 'gui/ui/nexus_save_dialog.ui') self.browseButton.clicked.connect(self._set_save_path) @@ -32,9 +33,10 @@ def __init__(self, parent, dataset_list: list[DatasetId]): self.selected_dataset = None - def _create_dataset_lists(self, dataset_list): + def _create_dataset_lists(self, dataset_list: Iterable[Dataset]): if dataset_list: - self.dataset_uuids, dataset_names = zip(*dataset_list, strict=True) + self.dataset_uuids = [ds.id for ds in dataset_list] + dataset_names = [ds.name for ds in dataset_list] self.datasetNames.addItems(dataset_names) def accept(self) -> None: diff --git a/mantidimaging/gui/windows/main/presenter.py b/mantidimaging/gui/windows/main/presenter.py index a3364398c09..47a1e49451c 100644 --- a/mantidimaging/gui/windows/main/presenter.py +++ b/mantidimaging/gui/windows/main/presenter.py @@ -40,11 +40,6 @@ class StackId(NamedTuple): name: str -class DatasetId(NamedTuple): - id: uuid.UUID - name: str - - logger = getLogger(__name__) @@ -419,14 +414,6 @@ def stack_visualiser_list(self) -> list[StackId]: def datasets(self) -> Iterable[Dataset]: return self.model.datasets.values() - @property - def strict_dataset_list(self) -> list[DatasetId]: - datasets = [ - DatasetId(dataset.id, dataset.name) for dataset in self.model.datasets.values() - if isinstance(dataset, StrictDataset) - ] - return sorted(datasets, key=lambda x: x.name) - @property def all_dataset_ids(self) -> Iterable[uuid.UUID]: return self.model.datasets.keys() diff --git a/mantidimaging/gui/windows/main/test/nexus_save_test.py b/mantidimaging/gui/windows/main/test/nexus_save_test.py index 4e44b276f5c..782537301d6 100644 --- a/mantidimaging/gui/windows/main/test/nexus_save_test.py +++ b/mantidimaging/gui/windows/main/test/nexus_save_test.py @@ -5,7 +5,6 @@ from unittest import mock from mantidimaging.gui.windows.main.nexus_save_dialog import NexusSaveDialog -from mantidimaging.gui.windows.main.presenter import DatasetId from mantidimaging.test_helpers import start_qapplication @@ -62,11 +61,13 @@ def test_save_enabled(self): def test_dataset_lists_creation(self): dataset_id = "dataset-id" dataset_name = "dataset-name" + ds = mock.Mock(id=dataset_id) + ds.name = dataset_name self.nexus_save_dialog.datasetNames = mock.Mock() - self.nexus_save_dialog._create_dataset_lists([DatasetId(dataset_id, dataset_name)]) + self.nexus_save_dialog._create_dataset_lists([ds]) - self.assertEqual(self.nexus_save_dialog.dataset_uuids, (dataset_id, )) - self.nexus_save_dialog.datasetNames.addItems.assert_called_once_with((dataset_name, )) + self.assertEqual(self.nexus_save_dialog.dataset_uuids, [dataset_id]) + self.nexus_save_dialog.datasetNames.addItems.assert_called_once_with([dataset_name]) @mock.patch("mantidimaging.gui.windows.main.nexus_save_dialog.QFileDialog.getSaveFileName") def test_set_save_path_adds_extension(self, get_save_file_name_mock): diff --git a/mantidimaging/gui/windows/main/test/presenter_test.py b/mantidimaging/gui/windows/main/test/presenter_test.py index 58da11e7e79..997e65fa41b 100644 --- a/mantidimaging/gui/windows/main/test/presenter_test.py +++ b/mantidimaging/gui/windows/main/test/presenter_test.py @@ -497,8 +497,8 @@ def test_dataset_list(self): self.model.datasets = {"id1": dataset_1, "id2": dataset_2, "id3": mixed_dataset} - dataset_list = self.presenter.strict_dataset_list - assert len(dataset_list) == 2 + dataset_list = list(self.presenter.datasets) + assert len(dataset_list) == 3 def test_add_child_item_to_tree_view(self): dataset_item_mock = self.view.get_dataset_tree_view_item.return_value diff --git a/mantidimaging/gui/windows/main/test/view_test.py b/mantidimaging/gui/windows/main/test/view_test.py index 965388b0871..db8b467107c 100644 --- a/mantidimaging/gui/windows/main/test/view_test.py +++ b/mantidimaging/gui/windows/main/test/view_test.py @@ -449,7 +449,7 @@ def test_show_image_save_dialog(self, image_save_dialog_mock): @mock.patch("mantidimaging.gui.windows.main.view.NexusSaveDialog") def test_show_nexus_save_dialog(self, nexus_save_dialog_mock): self.view.show_nexus_save_dialog() - nexus_save_dialog_mock.assert_called_once_with(self.view, self.view.strict_dataset_list) + nexus_save_dialog_mock.assert_called_once_with(self.view, self.view.presenter.datasets) nexus_save_dialog_mock.return_value.show.assert_called_once() def test_execute_add_to_dataset_calls_notify(self): diff --git a/mantidimaging/gui/windows/main/view.py b/mantidimaging/gui/windows/main/view.py index 28f7c8804a7..0af73b23d39 100644 --- a/mantidimaging/gui/windows/main/view.py +++ b/mantidimaging/gui/windows/main/view.py @@ -29,7 +29,7 @@ from mantidimaging.gui.windows.add_images_to_dataset_dialog.view import AddImagesToDatasetDialog from mantidimaging.gui.windows.image_load_dialog import ImageLoadDialog from mantidimaging.gui.windows.main.nexus_save_dialog import NexusSaveDialog -from mantidimaging.gui.windows.main.presenter import MainWindowPresenter, Notification, DatasetId, StackId +from mantidimaging.gui.windows.main.presenter import MainWindowPresenter, Notification, StackId from mantidimaging.gui.windows.main.presenter import Notification as PresNotification from mantidimaging.gui.windows.main.image_save_dialog import ImageSaveDialog from mantidimaging.gui.windows.move_stack_dialog.view import MoveStackDialog @@ -424,7 +424,7 @@ def show_image_save_dialog(self) -> None: self.image_save_dialog.show() def show_nexus_save_dialog(self) -> None: - self.nexus_save_dialog = NexusSaveDialog(self, self.strict_dataset_list) + self.nexus_save_dialog = NexusSaveDialog(self, self.presenter.datasets) self.nexus_save_dialog.show() def show_settings_window(self) -> None: @@ -484,10 +484,6 @@ def show_live_viewer(self, live_data_path: Path) -> None: def stack_list(self) -> list[StackId]: return self.presenter.stack_visualiser_list - @property - def strict_dataset_list(self) -> list[DatasetId]: - return self.presenter.strict_dataset_list - @property def stack_names(self) -> list[str]: return self.presenter.stack_visualiser_names From 59bf04c2da947545e8951aba0e1eb37679d5fbb4 Mon Sep 17 00:00:00 2001 From: Sam Tygier Date: Tue, 24 Sep 2024 17:31:55 +0100 Subject: [PATCH 8/9] Main window screenshots: reduce move tests to the 2 possible cases --- mantidimaging/eyes_tests/base_eyes.py | 15 ++++----- mantidimaging/eyes_tests/main_window_test.py | 35 +++----------------- 2 files changed, 12 insertions(+), 38 deletions(-) diff --git a/mantidimaging/eyes_tests/base_eyes.py b/mantidimaging/eyes_tests/base_eyes.py index cf1f61155d6..6eb54b6024c 100644 --- a/mantidimaging/eyes_tests/base_eyes.py +++ b/mantidimaging/eyes_tests/base_eyes.py @@ -13,7 +13,7 @@ from PyQt5.QtWidgets import QMainWindow, QMenu, QWidget, QApplication from mantidimaging.core.data import ImageStack -from mantidimaging.core.data.dataset import StrictDataset, MixedDataset +from mantidimaging.core.data.dataset import StrictDataset, Dataset from mantidimaging.core.io.loader import loader from mantidimaging.core.utility.data_containers import Indices from mantidimaging.eyes_tests.eyes_manager import EyesManager @@ -118,16 +118,15 @@ def _load_strict_data_set(self, set_180: bool = False): return vis - def _create_mixed_dataset(self) -> MixedDataset: - mixed_dataset = MixedDataset(stacks=[generate_images()], name="a-mixed-dataset") - - self.imaging.presenter.model.add_dataset_to_model(mixed_dataset) - self.imaging.presenter.create_mixed_dataset_tree_view_items(mixed_dataset) - self.imaging.presenter.create_mixed_dataset_stack_windows(mixed_dataset) + def _create_new_dataset(self) -> Dataset: + new_dataset = Dataset(sample=generate_images(), name="new") + self.imaging.presenter.create_strict_dataset_stack_windows(new_dataset) + self.imaging.presenter.create_strict_dataset_tree_view_items(new_dataset) + self.imaging.presenter.model.add_dataset_to_model(new_dataset) QApplication.sendPostedEvents() - return mixed_dataset + return new_dataset def _get_top_level_widget(cls, widget_type): for widget in cls.app.topLevelWidgets(): diff --git a/mantidimaging/eyes_tests/main_window_test.py b/mantidimaging/eyes_tests/main_window_test.py index f3bef847cf1..247341dcac1 100644 --- a/mantidimaging/eyes_tests/main_window_test.py +++ b/mantidimaging/eyes_tests/main_window_test.py @@ -94,44 +94,19 @@ def test_clicking_tab_changes_tree_view_selection(self): self.check_target() - def test_move_stack_dialog_when_both_strict(self): + def test_move_within_dataset(self): sample_vis = self._load_strict_data_set() - self._load_strict_data_set() - self.imaging.presenter._set_tree_view_selection_with_id(sample_vis.id) - self.imaging._move_stack() - self.check_target(self.imaging.move_stack_dialog) - - def test_move_stack_dialog_strict_to_mixed(self): - sample_vis = self._load_strict_data_set() - mixed_ds = self._create_mixed_dataset() - - self.imaging.presenter._set_tree_view_selection_with_id(sample_vis.id) - self.imaging._move_stack() - self.imaging.move_stack_dialog.datasetSelector.setCurrentText(mixed_ds.name) self.check_target(self.imaging.move_stack_dialog) - def test_move_stack_dialog_mixed_to_strict(self): - mixed_ds = self._create_mixed_dataset() + def test_move_to_another_dataset(self): sample_vis = self._load_strict_data_set() - strict_ds_id = self.imaging.presenter.model.get_parent_dataset(sample_vis.id) - strict_ds = self.imaging.get_dataset(strict_ds_id) - - self.imaging.presenter._set_tree_view_selection_with_id(mixed_ds.all[0].id) + new_dataset = self._create_new_dataset() + self.imaging.presenter._set_tree_view_selection_with_id(sample_vis.id) self.imaging._move_stack() - self.imaging.move_stack_dialog.datasetSelector.setCurrentText(strict_ds.name) - self.check_target(self.imaging.move_stack_dialog) + self.imaging.move_stack_dialog.datasetSelector.setCurrentText(new_dataset.name) - def test_move_stack_dialog_both_mixed(self): - mixed_ds_1 = self._create_mixed_dataset() - mixed_ds_2 = self._create_mixed_dataset() - mixed_ds_2.name = "other-mixed-ds-name" - - self.imaging.presenter._set_tree_view_selection_with_id(mixed_ds_1.all[0].id) - - self.imaging._move_stack() - self.imaging.move_stack_dialog.datasetSelector.setCurrentText(mixed_ds_2.name) self.check_target(self.imaging.move_stack_dialog) From 8bdd7597430d7ca64a7b80ee71fcb4034a17cc0e Mon Sep 17 00:00:00 2001 From: Sam Tygier Date: Wed, 25 Sep 2024 11:22:57 +0100 Subject: [PATCH 9/9] Fix NexusSaveDialogTest for strict_dataset_list removal --- mantidimaging/eyes_tests/nexus_save_dialog_test.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/mantidimaging/eyes_tests/nexus_save_dialog_test.py b/mantidimaging/eyes_tests/nexus_save_dialog_test.py index 657fe41cd92..ba7a421d2b2 100644 --- a/mantidimaging/eyes_tests/nexus_save_dialog_test.py +++ b/mantidimaging/eyes_tests/nexus_save_dialog_test.py @@ -2,21 +2,18 @@ # SPDX - License - Identifier: GPL-3.0-or-later from __future__ import annotations -from typing import NamedTuple from unittest import mock -from uuid import UUID, uuid4 +from mantidimaging.core.data.dataset import Dataset from mantidimaging.eyes_tests.base_eyes import BaseEyesTest class NexusSaveDialogTest(BaseEyesTest): def test_save_dialog_opens_with_dataset(self): - TestTuple = NamedTuple('TestTuple', [('id', UUID), ('name', str)]) - dataset_list = [TestTuple(uuid4(), 'Test Dataset')] - with mock.patch("mantidimaging.gui.windows.main.MainWindowView.strict_dataset_list", - new_callable=mock.PropertyMock) as mock_dataset_list: - mock_dataset_list.return_value = dataset_list + with mock.patch("mantidimaging.gui.windows.main.MainWindowPresenter.datasets", + new_callable=mock.PropertyMock) as mock_datasets: + mock_datasets.return_value = [Dataset(name='Test Dataset')] self.imaging.actionSaveNeXusFile.trigger() self.check_target(widget=self.imaging.nexus_save_dialog)