diff --git a/src/ess/nmx/mcstas/load.py b/src/ess/nmx/mcstas/load.py index 53d6c18..02ed179 100644 --- a/src/ess/nmx/mcstas/load.py +++ b/src/ess/nmx/mcstas/load.py @@ -67,11 +67,25 @@ def load_raw_event_data( def load_crystal_rotation( file_path: FilePath, instrument: McStasInstrument ) -> CrystalRotation: - """Retrieve crystal rotation from the file.""" + """Retrieve crystal rotation from the file. + + Raises + ------ + KeyError + If the crystal rotation is not found in the file. + + """ with snx.File(file_path, 'r') as file: - return sc.vector( - value=[file[f"entry1/simulation/Param/XtalPhi{key}"][...] for key in "XYZ"], - unit=instrument.simulation_settings.angle_unit, + param_keys = tuple(f"entry1/simulation/Param/XtalPhi{key}" for key in "XYZ") + if not all(key in file for key in param_keys): + raise KeyError( + f"Crystal rotations [{', '.join(param_keys)}] not found in file." + ) + return CrystalRotation( + sc.vector( + value=[file[param_key][...] for param_key in param_keys], + unit=instrument.simulation_settings.angle_unit, + ) ) diff --git a/tests/loader_test.py b/tests/loader_test.py index cd758f6..1e8cca9 100644 --- a/tests/loader_test.py +++ b/tests/loader_test.py @@ -10,7 +10,7 @@ import scippnexus as snx from ess.nmx import default_parameters from ess.nmx.data import small_mcstas_2_sample, small_mcstas_3_sample -from ess.nmx.mcstas.load import bank_names_to_detector_names +from ess.nmx.mcstas.load import bank_names_to_detector_names, load_crystal_rotation from ess.nmx.mcstas.load import providers as loader_providers from ess.nmx.reduction import NMXData from ess.nmx.types import ( @@ -192,6 +192,26 @@ def test_file_reader_mcstas_additional_fields(tmp_mcstas_file: pathlib.Path) -> assert isinstance(dg, sc.DataGroup) +@pytest.fixture() +def rotation_mission_tmp_file(tmp_mcstas_file: pathlib.Path) -> pathlib.Path: + import h5py + + param_keys = tuple(f"entry1/simulation/Param/XtalPhi{key}" for key in "XYZ") + + # Remove the rotation parameters from the file. + with h5py.File(tmp_mcstas_file, 'a') as file: + for key in param_keys: + del file[key] + + return tmp_mcstas_file + + +def test_missing_rotation(rotation_mission_tmp_file: FilePath) -> None: + with pytest.raises(KeyError, match="XtalPhiX"): + load_crystal_rotation(rotation_mission_tmp_file, None) + # McStasInstrument is not used due to error in the file. + + def test_bank_names_to_detector_names_two_detectors(): res = bank_names_to_detector_names(two_detectors_two_filenames) assert len(res) == 2