From a0e7c24a6e55101196198a4f856d923a3e02c76d Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Tue, 28 Oct 2025 22:02:56 +0100 Subject: [PATCH 1/9] Add basic class and example --- .../example_data/diffusion_data_example.h5 | Bin 0 -> 67392 bytes .../example_data/vanadium_data_example.h5 | Bin 0 -> 67392 bytes examples/experiment_example.ipynb | 50 ++++++++ src/easydynamics/experiment/__init__.py | 7 ++ src/easydynamics/experiment/experiment.py | 110 ++++++++++++++++++ 5 files changed, 167 insertions(+) create mode 100644 examples/example_data/diffusion_data_example.h5 create mode 100644 examples/example_data/vanadium_data_example.h5 create mode 100644 examples/experiment_example.ipynb create mode 100644 src/easydynamics/experiment/__init__.py create mode 100644 src/easydynamics/experiment/experiment.py diff --git a/examples/example_data/diffusion_data_example.h5 b/examples/example_data/diffusion_data_example.h5 new file mode 100644 index 0000000000000000000000000000000000000000..78baba303499b64ae89ee2aa771c4ccece9f5dc9 GIT binary patch literal 67392 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

V1=E*A+nX97#5k%}3+X_Jt$f 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 Vl^rjj=?4}vu>1^e?7##mpaK48d07Ae literal 0 HcmV?d00001 diff --git a/examples/example_data/vanadium_data_example.h5 b/examples/example_data/vanadium_data_example.h5 new file mode 100644 index 0000000000000000000000000000000000000000..0c7534a36b04206035789971fcfcd4aea602fb7a GIT binary patch literal 67392 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 TpCj|5}j6& Date: Tue, 28 Oct 2025 22:36:33 +0100 Subject: [PATCH 2/9] Tests --- src/easydynamics/experiment/experiment.py | 59 +++++---- .../unit_tests/experiment/test_experiment.py | 112 ++++++++++++++++++ 2 files changed, 151 insertions(+), 20 deletions(-) create mode 100644 tests/unit_tests/experiment/test_experiment.py diff --git a/src/easydynamics/experiment/experiment.py b/src/easydynamics/experiment/experiment.py index e7d7f65..ab5769e 100644 --- a/src/easydynamics/experiment/experiment.py +++ b/src/easydynamics/experiment/experiment.py @@ -19,27 +19,35 @@ def __init__( *args, **kwargs, ): - super(Experiment, self).__init__(name, *args, **kwargs) + super().__init__(name, *args, **kwargs) - if isinstance(data, str): + if data is None: + self._data: Optional[sc.DataArray] = None + elif isinstance(data, str): self.load_hdf5(filename=data) - elif isinstance(data, sc.DataArray): self._data = data + else: + raise TypeError( + f"Data must be a sc.DataArray or a filename string, not {type(data).__name__}" + ) - def load_hdf5(self, filename: str): + def load_hdf5(self, filename: str, name: Optional[str] = None): """ Load data from an HDF5 file. Args: - file_path (str): Path to the data file. - name (str): Name to assign to the loaded dataset. + filename (str): Path to the HDF5 file. """ if not isinstance(filename, str): raise TypeError(f"Filename must be a string, not {type(filename).__name__}") - # TODO: Add checks of dimensions etc. I'm not yet sure what dimensions I want to allow, so for now I trust myself. + if name is not None: + if not isinstance(name, str): + raise TypeError(f"Name must be a string, not {type(name).__name__}") + self.name = name + # TODO: Add checks of dimensions etc. I'm not yet sure what dimensions I want to allow, so for now I trust myself. self._data = sc_load_hdf5(filename) def save_hdf5(self, filename: Optional[str] = None): @@ -63,6 +71,22 @@ def save_hdf5(self, filename: Optional[str] = None): os.makedirs(os.path.dirname(filename), exist_ok=True) sc_save_hdf5(self._data, filename) + def remove_data(self): + """Remove the dataset from the experiment.""" + self._data = None + + @property + def data(self) -> Optional[sc.DataArray]: + """Get the dataset associated with this experiment.""" + return self._data + + @data.setter + def data(self, value: sc.DataArray): + """Set the dataset associated with this experiment.""" + if not isinstance(value, sc.DataArray): + raise TypeError(f"Data must be a sc.DataArray, not {type(value).__name__}") + self._data = value + def plot_data(self): """Plot the dataset using plopp.""" @@ -94,17 +118,12 @@ def _in_notebook(): except (NameError, ImportError): return False # Standard Python (no IPython) - @staticmethod - def _in_notebook(): - try: - from IPython import get_ipython + def __repr__(self) -> str: + return f"Experiment `{self.name}` with data: {self._data}" - shell = get_ipython().__class__.__name__ - if shell == "ZMQInteractiveShell": - return True # Jupyter notebook or JupyterLab - elif shell == "TerminalInteractiveShell": - return False # Terminal IPython - else: - return False - except (NameError, ImportError): - return False # Standard Python (no IPython) + def __copy__(self) -> "Experiment": + """Return a copy of the object.""" + temp = self.as_dict(skip=["unique_name"]) + new_obj = self.__class__.from_dict(temp) + new_obj.data = self.data.copy() if self.data is not None else None + return new_obj diff --git a/tests/unit_tests/experiment/test_experiment.py b/tests/unit_tests/experiment/test_experiment.py new file mode 100644 index 0000000..e18350c --- /dev/null +++ b/tests/unit_tests/experiment/test_experiment.py @@ -0,0 +1,112 @@ +from copy import copy + +import numpy as np +import pytest +import scipp as sc + +from easydynamics.experiment import Experiment + + +class TestExperiment: + @pytest.fixture + def experiment(self): + Q = sc.linspace("Q", 0.5, 1.5, num=10, unit="1/Angstrom") + energy = sc.linspace("energy", -5, 5, num=11, unit="meV") + values = sc.array(dims=["Q", "energy"], values=np.ones((10, 11))) + data = sc.DataArray(data=values, coords={"Q": Q, "energy": energy}) + + experiment = Experiment(name="test_experiment", data=data) + return experiment + + def test_init(self, experiment): + # THEN EXPECT + assert experiment.name == "test_experiment" + assert isinstance(experiment._data, sc.DataArray) + assert "Q" in experiment._data.dims + assert "energy" in experiment._data.dims + assert experiment._data.sizes["Q"] == 10 + assert experiment._data.sizes["energy"] == 11 + assert sc.identical( + experiment._data.data, + sc.array(dims=["Q", "energy"], values=np.ones((10, 11))), + ) + + def test_init_no_data(self): + # WHEN + experiment = Experiment(name="empty_experiment") + + # THEN EXPECT + assert experiment.name == "empty_experiment" + assert experiment._data is None + + def test_init_invalid_data(self): + # WHEN / THEN EXPECT + with pytest.raises(TypeError): + Experiment(name="invalid_experiment", data=123) + + def test_load_hdf5(self, tmp_path, experiment): + # WHEN + # First create a file to load from + filename = tmp_path / "test.h5" + data_to_save = experiment.data + sc.io.save_hdf5(data_to_save, filename) + + # THEN + new_experiment = Experiment("new_experiment") + new_experiment.load_hdf5(str(filename), name="loaded_data") + loaded_data = new_experiment.data + + # EXPECT + assert sc.identical(data_to_save, loaded_data) + assert new_experiment.name == "loaded_data" + + def test_save_hdf5(self, tmp_path, experiment): + # WHEN THEN + filename = tmp_path / "saved_data.h5" + experiment.save_hdf5(str(filename)) + + # EXPECT + loaded_data = sc.io.load_hdf5(str(filename)) + original_data = experiment.data + assert sc.identical(original_data, loaded_data) + + def test_remove_data(self, experiment): + # WHEN + experiment.remove_data() + + # THEN EXPECT + assert experiment._data is None + + def test_load_hdf5_invalid_filename(self, experiment): + # WHEN / THEN EXPECT + with pytest.raises(TypeError): + experiment.load_hdf5(123) + + def test_load_hdf5_invalid_file(self, experiment): + # WHEN / THEN EXPECT + with pytest.raises(OSError): + experiment.load_hdf5("non_existent_file.h5") + + def test_save_hdf5_invalid_filename(self, experiment): + # WHEN / THEN EXPECT + with pytest.raises(TypeError): + experiment.save_hdf5(123) + + def test_repr(self, experiment): + # WHEN + repr_str = repr(experiment) + + # THEN EXPECT + assert ( + repr_str == f"Experiment `{experiment.name}` with data: {experiment._data}" + ) + + def test_copy_experiment(self, experiment): + # WHEN + copied_experiment = copy(experiment) + + # THEN EXPECT + assert copied_experiment.name == experiment.name + assert sc.identical(copied_experiment.data, experiment.data) + assert copied_experiment is not experiment + assert copied_experiment.data is not experiment.data From fac0bfad7e4db54b227b8c993d75286dc0233084 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Tue, 28 Oct 2025 22:43:24 +0100 Subject: [PATCH 3/9] Added some tests --- .../unit_tests/experiment/test_experiment.py | 78 +++++++++++++++---- 1 file changed, 64 insertions(+), 14 deletions(-) diff --git a/tests/unit_tests/experiment/test_experiment.py b/tests/unit_tests/experiment/test_experiment.py index e18350c..8e562d3 100644 --- a/tests/unit_tests/experiment/test_experiment.py +++ b/tests/unit_tests/experiment/test_experiment.py @@ -18,7 +18,7 @@ def experiment(self): experiment = Experiment(name="test_experiment", data=data) return experiment - def test_init(self, experiment): + def test_init_array(self, experiment): # THEN EXPECT assert experiment.name == "test_experiment" assert isinstance(experiment._data, sc.DataArray) @@ -31,6 +31,31 @@ def test_init(self, experiment): sc.array(dims=["Q", "energy"], values=np.ones((10, 11))), ) + def test_init_string(self, tmp_path): + # WHEN + Q = sc.linspace("Q", 0.5, 1.5, num=10, unit="1/Angstrom") + energy = sc.linspace("energy", -5, 5, num=11, unit="meV") + values = sc.array(dims=["Q", "energy"], values=np.ones((10, 11))) + data = sc.DataArray(data=values, coords={"Q": Q, "energy": energy}) + + filename = tmp_path / "test_experiment.h5" + sc.io.save_hdf5(data, filename) + + # THEN + experiment = Experiment(name="loaded_experiment", data=str(filename)) + + # EXPECT + assert experiment.name == "loaded_experiment" + assert isinstance(experiment._data, sc.DataArray) + assert "Q" in experiment._data.dims + assert "energy" in experiment._data.dims + assert experiment._data.sizes["Q"] == 10 + assert experiment._data.sizes["energy"] == 11 + assert sc.identical( + experiment._data.data, + sc.array(dims=["Q", "energy"], values=np.ones((10, 11))), + ) + def test_init_no_data(self): # WHEN experiment = Experiment(name="empty_experiment") @@ -60,6 +85,21 @@ def test_load_hdf5(self, tmp_path, experiment): assert sc.identical(data_to_save, loaded_data) assert new_experiment.name == "loaded_data" + def test_load_hdf5_invalid_name_raises(self, experiment): + # WHEN / THEN EXPECT + with pytest.raises(TypeError): + experiment.load_hdf5("some_file.h5", name=123) + + def test_load_hdf5_invalid_filename_raises(self, experiment): + # WHEN / THEN EXPECT + with pytest.raises(TypeError): + experiment.load_hdf5(123) + + def test_load_hdf5_invalid_file_raises(self, experiment): + # WHEN / THEN EXPECT + with pytest.raises(OSError): + experiment.load_hdf5("non_existent_file.h5") + def test_save_hdf5(self, tmp_path, experiment): # WHEN THEN filename = tmp_path / "saved_data.h5" @@ -70,27 +110,37 @@ def test_save_hdf5(self, tmp_path, experiment): original_data = experiment.data assert sc.identical(original_data, loaded_data) - def test_remove_data(self, experiment): + def test_save_hdf5_default_name(self, tmp_path, experiment): + # WHEN THEN + current_dir = tmp_path + experiment.name = "default_name_experiment" + expected_filename = current_dir / "default_name_experiment.h5" + experiment.save_hdf5() + + # EXPECT + loaded_data = sc.io.load_hdf5(str(expected_filename)) + original_data = experiment.data + assert sc.identical(original_data, loaded_data) + + def test_save_hdf5_no_data_raises(self): # WHEN - experiment.remove_data() + experiment = Experiment(name="no_data_experiment") # THEN EXPECT - assert experiment._data is None + with pytest.raises(AttributeError): + experiment.save_hdf5("should_fail.h5") - def test_load_hdf5_invalid_filename(self, experiment): + def test_save_hdf5_invalid_filename_raises(self, experiment): # WHEN / THEN EXPECT with pytest.raises(TypeError): - experiment.load_hdf5(123) + experiment.save_hdf5(123) - def test_load_hdf5_invalid_file(self, experiment): - # WHEN / THEN EXPECT - with pytest.raises(OSError): - experiment.load_hdf5("non_existent_file.h5") + def test_remove_data(self, experiment): + # WHEN + experiment.remove_data() - def test_save_hdf5_invalid_filename(self, experiment): - # WHEN / THEN EXPECT - with pytest.raises(TypeError): - experiment.save_hdf5(123) + # THEN EXPECT + assert experiment._data is None def test_repr(self, experiment): # WHEN From 658314e31d1e0decdeb86c7accd98a90deee2b79 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Tue, 28 Oct 2025 22:45:42 +0100 Subject: [PATCH 4/9] Comment tests --- tests/unit_tests/experiment/test_experiment.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/unit_tests/experiment/test_experiment.py b/tests/unit_tests/experiment/test_experiment.py index 8e562d3..e7fed6a 100644 --- a/tests/unit_tests/experiment/test_experiment.py +++ b/tests/unit_tests/experiment/test_experiment.py @@ -19,7 +19,8 @@ def experiment(self): return experiment def test_init_array(self, experiment): - # THEN EXPECT + "Test initialization with a Scipp DataArray" + # WHEN THEN EXPECT assert experiment.name == "test_experiment" assert isinstance(experiment._data, sc.DataArray) assert "Q" in experiment._data.dims @@ -32,6 +33,7 @@ def test_init_array(self, experiment): ) def test_init_string(self, tmp_path): + "Test initialization with a filename string - should load the file" # WHEN Q = sc.linspace("Q", 0.5, 1.5, num=10, unit="1/Angstrom") energy = sc.linspace("energy", -5, 5, num=11, unit="meV") @@ -57,6 +59,7 @@ def test_init_string(self, tmp_path): ) def test_init_no_data(self): + "Test initialization with no data" # WHEN experiment = Experiment(name="empty_experiment") @@ -65,11 +68,13 @@ def test_init_no_data(self): assert experiment._data is None def test_init_invalid_data(self): + "Test initialization with invalid data type" # WHEN / THEN EXPECT with pytest.raises(TypeError): Experiment(name="invalid_experiment", data=123) def test_load_hdf5(self, tmp_path, experiment): + "Test loading data from an HDF5 file. First use scipp to save data to a file, then load it using the method." # WHEN # First create a file to load from filename = tmp_path / "test.h5" @@ -86,21 +91,25 @@ def test_load_hdf5(self, tmp_path, experiment): assert new_experiment.name == "loaded_data" def test_load_hdf5_invalid_name_raises(self, experiment): + "Test loading data from an HDF5 file, giving the Experiment an invalid name" # WHEN / THEN EXPECT with pytest.raises(TypeError): experiment.load_hdf5("some_file.h5", name=123) def test_load_hdf5_invalid_filename_raises(self, experiment): + "Test loading data from an HDF5 file with an invalid filename" # WHEN / THEN EXPECT with pytest.raises(TypeError): experiment.load_hdf5(123) def test_load_hdf5_invalid_file_raises(self, experiment): + "Test loading data from a non-existent HDF5 file" # WHEN / THEN EXPECT with pytest.raises(OSError): experiment.load_hdf5("non_existent_file.h5") def test_save_hdf5(self, tmp_path, experiment): + "Test saving data to an HDF5 file. Load the saved file using scipp and compare to the original data." # WHEN THEN filename = tmp_path / "saved_data.h5" experiment.save_hdf5(str(filename)) @@ -111,6 +120,7 @@ def test_save_hdf5(self, tmp_path, experiment): assert sc.identical(original_data, loaded_data) def test_save_hdf5_default_name(self, tmp_path, experiment): + "Test saving data to an HDF5 file with default filename (based on experiment name). Load the saved file using scipp and compare to the original data." # WHEN THEN current_dir = tmp_path experiment.name = "default_name_experiment" @@ -123,6 +133,7 @@ def test_save_hdf5_default_name(self, tmp_path, experiment): assert sc.identical(original_data, loaded_data) def test_save_hdf5_no_data_raises(self): + "Test saving data to an HDF5 file when no data is present in the experiment" # WHEN experiment = Experiment(name="no_data_experiment") @@ -131,11 +142,13 @@ def test_save_hdf5_no_data_raises(self): experiment.save_hdf5("should_fail.h5") def test_save_hdf5_invalid_filename_raises(self, experiment): + "Test saving data to an HDF5 file with an invalid filename" # WHEN / THEN EXPECT with pytest.raises(TypeError): experiment.save_hdf5(123) def test_remove_data(self, experiment): + "Test removing data from the experiment" # WHEN experiment.remove_data() @@ -152,6 +165,7 @@ def test_repr(self, experiment): ) def test_copy_experiment(self, experiment): + "Test copying an Experiment object. The copied object should have the same attributes but be a different object in memory." # WHEN copied_experiment = copy(experiment) From d616c78db0e97d050b5fce697c547d87faa2bf76 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Tue, 28 Oct 2025 22:49:21 +0100 Subject: [PATCH 5/9] Fix a test --- tests/unit_tests/experiment/test_experiment.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/tests/unit_tests/experiment/test_experiment.py b/tests/unit_tests/experiment/test_experiment.py index e7fed6a..3a1d1c7 100644 --- a/tests/unit_tests/experiment/test_experiment.py +++ b/tests/unit_tests/experiment/test_experiment.py @@ -119,26 +119,13 @@ def test_save_hdf5(self, tmp_path, experiment): original_data = experiment.data assert sc.identical(original_data, loaded_data) - def test_save_hdf5_default_name(self, tmp_path, experiment): - "Test saving data to an HDF5 file with default filename (based on experiment name). Load the saved file using scipp and compare to the original data." - # WHEN THEN - current_dir = tmp_path - experiment.name = "default_name_experiment" - expected_filename = current_dir / "default_name_experiment.h5" - experiment.save_hdf5() - - # EXPECT - loaded_data = sc.io.load_hdf5(str(expected_filename)) - original_data = experiment.data - assert sc.identical(original_data, loaded_data) - def test_save_hdf5_no_data_raises(self): "Test saving data to an HDF5 file when no data is present in the experiment" # WHEN experiment = Experiment(name="no_data_experiment") # THEN EXPECT - with pytest.raises(AttributeError): + with pytest.raises(ValueError): experiment.save_hdf5("should_fail.h5") def test_save_hdf5_invalid_filename_raises(self, experiment): From cd4464af09eb4ea540909ed3d36e2d71a60c8107 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 31 Oct 2025 10:31:31 +0100 Subject: [PATCH 6/9] update example --- examples/experiment_example.ipynb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/experiment_example.ipynb b/examples/experiment_example.ipynb index 5344af3..565e16c 100644 --- a/examples/experiment_example.ipynb +++ b/examples/experiment_example.ipynb @@ -7,9 +7,7 @@ "metadata": {}, "outputs": [], "source": [ - "from easydynamics.experiment import Experiment\n", - "\n", - "import scipp as sc\n" + "from easydynamics.experiment import Experiment\n" ] }, { From 02bf7af7f56f0712380cb51db6e74f7133dae204 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 5 Nov 2025 22:08:25 +0100 Subject: [PATCH 7/9] add tests as suggested in review --- src/easydynamics/experiment/experiment.py | 12 +++++- .../unit_tests/experiment/test_experiment.py | 42 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/easydynamics/experiment/experiment.py b/src/easydynamics/experiment/experiment.py index ab5769e..0b0262d 100644 --- a/src/easydynamics/experiment/experiment.py +++ b/src/easydynamics/experiment/experiment.py @@ -48,7 +48,12 @@ def load_hdf5(self, filename: str, name: Optional[str] = None): self.name = name # TODO: Add checks of dimensions etc. I'm not yet sure what dimensions I want to allow, so for now I trust myself. - self._data = sc_load_hdf5(filename) + loaded_data = sc_load_hdf5(filename) + if not isinstance(loaded_data, sc.DataArray): + raise TypeError( + f"Loaded data must be a sc.DataArray, not {type(loaded_data).__name__}" + ) + self._data = loaded_data def save_hdf5(self, filename: Optional[str] = None): """Save the dataset to HDF5. @@ -68,7 +73,10 @@ def save_hdf5(self, filename: Optional[str] = None): import os - os.makedirs(os.path.dirname(filename), exist_ok=True) + dir_name = os.path.dirname(filename) + if dir_name: + os.makedirs(dir_name, exist_ok=True) + sc_save_hdf5(self._data, filename) def remove_data(self): diff --git a/tests/unit_tests/experiment/test_experiment.py b/tests/unit_tests/experiment/test_experiment.py index 3a1d1c7..bf64f34 100644 --- a/tests/unit_tests/experiment/test_experiment.py +++ b/tests/unit_tests/experiment/test_experiment.py @@ -1,4 +1,5 @@ from copy import copy +from unittest.mock import MagicMock, patch import numpy as np import pytest @@ -161,3 +162,44 @@ def test_copy_experiment(self, experiment): assert sc.identical(copied_experiment.data, experiment.data) assert copied_experiment is not experiment assert copied_experiment.data is not experiment.data + + def test_plot_data_success(self, experiment): + "Test plotting data successfully when in notebook environment" + # WHEN + with ( + patch.object(Experiment, "_in_notebook", return_value=True), + patch("plopp.plot") as mock_plot, + patch("IPython.display.display") as mock_display, + ): + mock_fig = MagicMock() + mock_plot.return_value = mock_fig + + # THEN + experiment.plot_data() + + # EXPECT + mock_plot.assert_called_once() + args, kwargs = mock_plot.call_args + assert sc.identical(args[0], experiment._data.transpose()) + assert kwargs["title"] == f"{experiment.name}" + mock_display.assert_called_once_with(mock_fig) + + def test_plot_data_no_data_raises(self): + "Test plotting data raises ValueError when no data is present" + # WHEN + experiment = Experiment(name="empty_experiment") + + # THEN EXPECT + with pytest.raises(ValueError, match="No data to plot"): + experiment.plot_data() + + def test_plot_data_not_in_notebook_raises(self, experiment): + "Test plotting data raises RuntimeError when not in notebook environment" + # WHEN + with patch.object(Experiment, "_in_notebook", return_value=False): + # THEN EXPECT + with pytest.raises( + RuntimeError, + match="plot_data\\(\\) can only be used in a Jupyter notebook environment", + ): + experiment.plot_data() From 30a39a328fb3b8d323111088f2c1b087fd317dc7 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 5 Nov 2025 22:21:19 +0100 Subject: [PATCH 8/9] Update tests --- src/easydynamics/experiment/experiment.py | 2 +- .../unit_tests/experiment/test_experiment.py | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/easydynamics/experiment/experiment.py b/src/easydynamics/experiment/experiment.py index 0b0262d..e38740f 100644 --- a/src/easydynamics/experiment/experiment.py +++ b/src/easydynamics/experiment/experiment.py @@ -47,7 +47,7 @@ def load_hdf5(self, filename: str, name: Optional[str] = None): raise TypeError(f"Name must be a string, not {type(name).__name__}") self.name = name - # TODO: Add checks of dimensions etc. I'm not yet sure what dimensions I want to allow, so for now I trust myself. + # TODO: Add checks of dimensions etc. I'm not yet sure what dimensions I want to allow, so for now I trust that the data is valid. loaded_data = sc_load_hdf5(filename) if not isinstance(loaded_data, sc.DataArray): raise TypeError( diff --git a/tests/unit_tests/experiment/test_experiment.py b/tests/unit_tests/experiment/test_experiment.py index bf64f34..70827ec 100644 --- a/tests/unit_tests/experiment/test_experiment.py +++ b/tests/unit_tests/experiment/test_experiment.py @@ -120,6 +120,20 @@ def test_save_hdf5(self, tmp_path, experiment): original_data = experiment.data assert sc.identical(original_data, loaded_data) + def test_save_hdf5_default_filename(self, tmp_path, experiment, monkeypatch): + "Test saving data to an HDF5 file with default filename" + # WHEN + monkeypatch.chdir(tmp_path) + + # THEN + experiment.save_hdf5() + + # EXPECT + expected_filename = tmp_path / f"{experiment.name}.h5" + loaded_data = sc.io.load_hdf5(str(expected_filename)) + original_data = experiment.data + assert sc.identical(original_data, loaded_data) + def test_save_hdf5_no_data_raises(self): "Test saving data to an HDF5 file when no data is present in the experiment" # WHEN @@ -143,6 +157,12 @@ def test_remove_data(self, experiment): # THEN EXPECT assert experiment._data is None + def test_data_setter_raises_type_error(self, experiment): + "Test setting data to an invalid type raises TypeError" + # WHEN THEN EXPECT + with pytest.raises(TypeError): + experiment.data = 123 + def test_repr(self, experiment): # WHEN repr_str = repr(experiment) From 8b241bb6bc4c71c9c973568c21cbfae2b3341784 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 5 Nov 2025 22:32:17 +0100 Subject: [PATCH 9/9] Add tests of _in_notebook --- .../unit_tests/experiment/test_experiment.py | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tests/unit_tests/experiment/test_experiment.py b/tests/unit_tests/experiment/test_experiment.py index 70827ec..f17ff4b 100644 --- a/tests/unit_tests/experiment/test_experiment.py +++ b/tests/unit_tests/experiment/test_experiment.py @@ -223,3 +223,55 @@ def test_plot_data_not_in_notebook_raises(self, experiment): match="plot_data\\(\\) can only be used in a Jupyter notebook environment", ): experiment.plot_data() + + def test_in_notebook_returns_true_for_jupyter(self, monkeypatch): + """Should return True when IPython shell is ZMQInteractiveShell (Jupyter).""" + + # WHEN + class ZMQInteractiveShell: + __name__ = "ZMQInteractiveShell" + + # THEN + monkeypatch.setattr("IPython.get_ipython", lambda: ZMQInteractiveShell()) + + # EXPECT + assert Experiment._in_notebook() is True + + def test_in_notebook_returns_false_for_terminal_ipython(self, monkeypatch): + """Should return False when IPython shell is TerminalInteractiveShell.""" + + # WHEN + class TerminalInteractiveShell: + __name__ = "TerminalInteractiveShell" + + # THEN + + monkeypatch.setattr("IPython.get_ipython", lambda: TerminalInteractiveShell()) + + # EXPECT + assert Experiment._in_notebook() is False + + def test_in_notebook_returns_false_for_unknown_shell(self, monkeypatch): + """Should return False when IPython shell type is unrecognized.""" + + # WHEN + class UnknownShell: + __name__ = "UnknownShell" + + # THEN + monkeypatch.setattr("IPython.get_ipython", lambda: UnknownShell()) + # EXPECT + assert Experiment._in_notebook() is False + + def test_in_notebook_returns_false_when_no_ipython(self, monkeypatch): + """Should return False when IPython is not installed or available.""" + + # WHEN + def raise_import_error(*args, **kwargs): + raise ImportError + + # THEN + monkeypatch.setattr("builtins.__import__", raise_import_error) + + # EXPECT + assert Experiment._in_notebook() is False