From 5b55f50bb011b657e91e9dcc14f15c98b661ab8e Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Thu, 28 Nov 2024 16:40:05 +0000 Subject: [PATCH 01/19] Retrieve spin state form sample logs and add to ReflectometryDataSet class, save the polarization in orso file if necessary --- .../algorithms/SaveISISReflectometryORSO.py | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/Framework/PythonInterface/plugins/algorithms/SaveISISReflectometryORSO.py b/Framework/PythonInterface/plugins/algorithms/SaveISISReflectometryORSO.py index e8a2a0631dc5..07cd8caf4fd5 100644 --- a/Framework/PythonInterface/plugins/algorithms/SaveISISReflectometryORSO.py +++ b/Framework/PythonInterface/plugins/algorithms/SaveISISReflectometryORSO.py @@ -48,9 +48,11 @@ def __init__(self, ws, is_ws_grp_member: bool): self._stitch_history = None self._q_conversion_history = None self._q_conversion_theta: Optional[float] = None + self._spin_state: str = "" self._populate_histories() self._populate_q_conversion_info() + self._set_spin_state_from_logs() self._set_name() @property @@ -69,6 +71,10 @@ def is_ws_grp_member(self) -> bool: def instrument_name(self) -> str: return self._ws.getInstrument().getName() + @property + def spin_state(self) -> str: + return self._spin_state + @property def reduction_history(self): return self._reduction_history @@ -85,6 +91,10 @@ def stitch_history(self): def is_stitched(self) -> bool: return self._stitch_history is not None + @property + def is_polarized(self) -> bool: + return len(self._spin_state) > 0 + @property def q_conversion_history(self): return self._q_conversion_history @@ -138,10 +148,14 @@ def _populate_q_conversion_info(self): self._q_conversion_theta = float(np.rad2deg(self._ws.spectrumInfo().signedTwoTheta(0))) / 2.0 def _set_name(self): + theta_assigned: bool = self._q_conversion_theta is not None + if self.is_stitched: self._name = "Stitched" - elif self._q_conversion_theta is not None: - self._name = str(self._q_conversion_theta) + elif theta_assigned or self.is_polarized: + theta_str = f"{self._q_conversion_theta:.3f}" if theta_assigned else "" + space_str = " " if (theta_assigned and self.is_polarized) else "" + self._name = f"{theta_str}{space_str}{self._spin_state}" else: self._name = self._ws.name() @@ -150,6 +164,10 @@ def _set_name(self): if self._is_ws_grp_member and self._name != self._ws.name(): self._name = f"{self._ws.name()} {self._name}" + def _set_spin_state_from_logs(self) -> None: + if self._ws.getRun().hasProperty("spin_state_ORSO"): + self._spin_state = self._ws.getRun().getLogData("spin_state_ORSO").value + class SaveISISReflectometryORSO(PythonAlgorithm): """ @@ -395,6 +413,7 @@ def _create_dataset_with_mandatory_header( reduction_timestamp=self._get_reduction_timestamp(refl_dataset.reduction_history), creator_name=self.name(), creator_affiliation=MantidORSODataset.SOFTWARE_NAME, + polarized_dataset=refl_dataset.is_polarized, ) def _add_optional_header_info(self, dataset: MantidORSODataset, refl_dataset: ReflectometryDataset) -> None: @@ -407,6 +426,7 @@ def _add_optional_header_info(self, dataset: MantidORSODataset, refl_dataset: Re dataset.set_proposal_id(rb_number) dataset.set_doi(doi) dataset.set_reduction_call(self._get_reduction_script(refl_dataset)) + dataset.set_polarization(refl_dataset.spin_state) reduction_workflow_histories = refl_dataset.reduction_workflow_histories if not refl_dataset.reduction_workflow_histories: From 5b935cb3cb43d7d9ce518a75194981a3b96e21be Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Thu, 28 Nov 2024 16:41:16 +0000 Subject: [PATCH 02/19] Add instrument settings header file if polarization is present, also add function to set polarization --- .../mantid/utils/reflectometry/orso_helper.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Framework/PythonInterface/mantid/utils/reflectometry/orso_helper.py b/Framework/PythonInterface/mantid/utils/reflectometry/orso_helper.py index 92e701bc69a6..d03ddc2f1bc0 100644 --- a/Framework/PythonInterface/mantid/utils/reflectometry/orso_helper.py +++ b/Framework/PythonInterface/mantid/utils/reflectometry/orso_helper.py @@ -8,7 +8,7 @@ from datetime import datetime, timezone from typing import Optional, Union, List import re -from orsopy.fileio.data_source import DataSource, Person, Experiment, Sample, Measurement +from orsopy.fileio.data_source import DataSource, Person, Experiment, Sample, Measurement, Polarization, InstrumentSettings from orsopy.fileio import Reduction, Software from orsopy.fileio.orso import Orso, OrsoDataset, save_orso, save_nexus from orsopy.fileio.base import Column, ErrorColumn, File @@ -62,11 +62,12 @@ def __init__( reduction_timestamp: datetime, creator_name: str, creator_affiliation: str, + polarized_dataset: bool, ) -> None: self._data_columns = data_columns self._header = None - self._create_mandatory_header(ws, dataset_name, reduction_timestamp, creator_name, creator_affiliation) + self._create_mandatory_header(ws, dataset_name, reduction_timestamp, creator_name, creator_affiliation, polarized_dataset) @property def dataset(self) -> OrsoDataset: @@ -81,6 +82,10 @@ def set_proposal_id(self, proposal_id: str) -> None: def set_doi(self, doi: str) -> None: self._header.data_source.experiment.doi = doi + def set_polarization(self, pol: str) -> None: + if self._header.data_source.measurement.instrument_settings is not None: + self._header.data_source.measurement.instrument_settings.polarization = Polarization(pol) + def set_reduction_call(self, call: str) -> None: self._header.reduction.call = call @@ -97,7 +102,7 @@ def _create_file(filename: str, timestamp: Optional[datetime] = None, comment: O return File(filename, timestamp, comment) def _create_mandatory_header( - self, ws, dataset_name: str, reduction_timestamp: datetime, creator_name: str, creator_affiliation: str + self, ws, dataset_name: str, reduction_timestamp: datetime, creator_name: str, creator_affiliation: str, polarized_dataset: bool ) -> None: owner = Person(name=None, affiliation=None) @@ -111,7 +116,9 @@ def _create_mandatory_header( sample = Sample(name=ws.getTitle()) - measurement = Measurement(instrument_settings=None, data_files=[]) + # This will initially only consider polarization + instrument_settings = InstrumentSettings(None, None) if polarized_dataset else None + measurement = Measurement(instrument_settings=instrument_settings, data_files=[]) data_source = DataSource(owner=owner, experiment=experiment, sample=sample, measurement=measurement) From 1f939f4a17a572aab711142951256f4e49cdfff0 Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Thu, 28 Nov 2024 16:42:05 +0000 Subject: [PATCH 03/19] Add spin state to logs in polarization efficiencies correction algorithm --- Framework/Reflectometry/src/ReflectometryReductionOneAuto3.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Framework/Reflectometry/src/ReflectometryReductionOneAuto3.cpp b/Framework/Reflectometry/src/ReflectometryReductionOneAuto3.cpp index 4ec88171d8cf..54fc6b880bb3 100644 --- a/Framework/Reflectometry/src/ReflectometryReductionOneAuto3.cpp +++ b/Framework/Reflectometry/src/ReflectometryReductionOneAuto3.cpp @@ -1085,6 +1085,7 @@ void ReflectometryReductionOneAuto3::applyPolarizationCorrection(const std::stri polAlg->setProperty("Efficiencies", efficiencies); polAlg->setProperty("CorrectionMethod", correctionMethod); polAlg->setProperty(CorrectionMethod::OPTION_NAME.at(correctionMethod), correctionOption); + polAlg->setProperty("AddSpinStateToLog", true); if (correctionMethod == "Fredrikze") { polAlg->setProperty("InputWorkspaceGroup", outputIvsLam); From b4e1fe7fa292bb34fafe660c3e30853f734ee169 Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Thu, 28 Nov 2024 16:42:50 +0000 Subject: [PATCH 04/19] Add test for checking polarization state is correctly saved on orso file --- .../SaveISISReflectometryORSOTest.py | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py index b5e2fc78d4d2..f0d17e97f132 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py +++ b/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py @@ -13,12 +13,7 @@ from datetime import datetime, timezone, date, time from mantid import config -from mantid.simpleapi import ( - CreateSampleWorkspace, - SaveISISReflectometryORSO, - ConvertToPointData, - GroupWorkspaces, -) +from mantid.simpleapi import CreateSampleWorkspace, SaveISISReflectometryORSO, ConvertToPointData, GroupWorkspaces, AddSampleLog from mantid.api import AnalysisDataService from mantid.kernel import version, DateAndTime from mantid.utils.reflectometry.orso_helper import MantidORSODataset, MantidORSOSaver @@ -484,7 +479,7 @@ def test_stitched_data_has_correct_dataset_name(self, mock_alg_histories): @patch("mantid.api.WorkspaceHistory.getAlgorithmHistories") def test_unstitched_data_gets_dataset_name_from_ref_roi(self, mock_alg_histories): - angle = "2.3" + angle = "2.300" ws = self._create_sample_workspace() self._configure_q_conversion_alg_mock_history(mock_alg_histories, self._REF_ROI, {"ScatteringAngle": angle}) @@ -499,7 +494,7 @@ def test_unstitched_data_gets_dataset_name_from_convert_units(self, mock_alg_his self._run_save_alg(ws, write_resolution=False) - self._check_file_header([self._get_dataset_name_entry(f"'{self._get_theta_value(ws)}'")]) + self._check_file_header([self._get_dataset_name_entry(f"'{self._get_theta_value(ws):.3f}'")]) @patch("mantid.api.WorkspaceHistory.getAlgorithmHistories") def test_unstitched_data_sets_dataset_name_to_ws_name_as_default(self, mock_alg_histories): @@ -580,6 +575,16 @@ def test_saved_as_nexus_if_relevant_filename_extension(self, mock_save_orso_nexu mock_save_orso_nexus.assert_called_once() mock_save_orso_ascii.assert_not_called() + def test_data_with_spin_state_logs_adds_polarization_metadata_in_instrument_settings_header(self): + spin_states = ["pp", "mm", "mp", "pm"] + ws_grp = self._create_sample_workspace_group_with_spin_state(spin_states, instrument_name="POLREF") + + self._run_save_alg(ws_grp, write_resolution=False, include_extra_cols=False) + + self._check_file_header(["instrument_settings:\n" "# incident_angle: null\n" "# wavelength: null"]) + for state in spin_states: + self._check_file_header([f"# polarization: {state}"]) + def _create_sample_workspace(self, rb_num_log_name=_LOG_RB_NUMBER, instrument_name="", ws_name="ws"): # Create a single spectrum workspace in units of momentum transfer ws = CreateSampleWorkspace( @@ -594,6 +599,15 @@ def _create_sample_workspace_group(self, member_ws_names, group_name="sample_gro self._create_sample_workspace(ws_name=ws_name, instrument_name=instrument_name) return GroupWorkspaces(InputWorkspaces=",".join(member_ws_names), OutputWorkspace=group_name) + def _create_sample_workspace_group_with_spin_state(self, spin_states, instrument_name=""): + group_member_names = [] + for state in spin_states: + ws_name = "ws_" + state + group_member_names.append(ws_name) + self._create_sample_workspace(ws_name=ws_name, instrument_name=instrument_name) + AddSampleLog(Workspace=ws_name, LogName="spin_state_ORSO", LogText=state) + return GroupWorkspaces(InputWorkspaces=",".join(group_member_names), OutputWorkspace="group_pol") + def _get_expected_data_file_metadata(self, expected_entries, expected_section_end): files_entry = [f"{self._DATA_FILES_HEADING}\n"] From 40effd80079cf5708468bc7ff90d315a4ac20b9a Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Mon, 2 Dec 2024 13:22:12 +0000 Subject: [PATCH 05/19] Add release notes --- docs/source/release/v6.12.0/Reflectometry/New_features/36685.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/source/release/v6.12.0/Reflectometry/New_features/36685.rst diff --git a/docs/source/release/v6.12.0/Reflectometry/New_features/36685.rst b/docs/source/release/v6.12.0/Reflectometry/New_features/36685.rst new file mode 100644 index 000000000000..cf1e10a263da --- /dev/null +++ b/docs/source/release/v6.12.0/Reflectometry/New_features/36685.rst @@ -0,0 +1 @@ +- Group workspaces subject to polarization efficiency correction algorithms will be saved with the spin state in ORSO format in the :ref:`algm-SaveISISReflectometryORSO` algorithm. From a110dd9ce00588fba14fca849f4edcdd8b2bc7fe Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Mon, 2 Dec 2024 14:12:43 +0000 Subject: [PATCH 06/19] Add test for checking dataset names with different polarization/angles --- .../SaveISISReflectometryORSOTest.py | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py index f0d17e97f132..9f78efb1b9d9 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py +++ b/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py @@ -11,6 +11,7 @@ from unittest.mock import Mock, patch from pathlib import Path from datetime import datetime, timezone, date, time +from collections import namedtuple from mantid import config from mantid.simpleapi import CreateSampleWorkspace, SaveISISReflectometryORSO, ConvertToPointData, GroupWorkspaces, AddSampleLog @@ -575,15 +576,34 @@ def test_saved_as_nexus_if_relevant_filename_extension(self, mock_save_orso_nexu mock_save_orso_nexus.assert_called_once() mock_save_orso_ascii.assert_not_called() + @patch("mantid.api.WorkspaceHistory.getAlgorithmHistories") + def test_dataset_name_is_correctly_generated_for_different_angle_polarization_settings_in_ws_groups(self, mock_alg_histories): + angle_pol = namedtuple("angle_pol", "angle polarization") + angle_polarization_inputs = [angle_pol(None, "pp"), angle_pol(0.5, ""), angle_pol(0.5, "pp"), angle_pol(None, "")] + dataset_name_outputs = ["ws pp", "ws 0.500", "ws 0.500 pp", "ws"] + for in_params, out_dataset_name in zip(angle_polarization_inputs, dataset_name_outputs): + with self.subTest(test_case=in_params): + ws = self._create_sample_workspace() + AddSampleLog(Workspace=ws, LogName="spin_state_ORSO", LogText=in_params.polarization) + if in_params.angle is not None: + self._configure_q_conversion_alg_mock_history(mock_alg_histories, self._REF_ROI, {"ScatteringAngle": in_params.angle}) + GroupWorkspaces(InputWorkspaces=["ws"], OutputWorkspace="ws_group") + + self._run_save_alg("ws_group") + + self._check_file_header([self._get_dataset_name_entry(out_dataset_name)]) + mock_alg_histories.reset_mock(return_value=True) + def test_data_with_spin_state_logs_adds_polarization_metadata_in_instrument_settings_header(self): spin_states = ["pp", "mm", "mp", "pm"] - ws_grp = self._create_sample_workspace_group_with_spin_state(spin_states, instrument_name="POLREF") + ws_grp = self._create_sample_workspace_group_with_spin_state(spin_states) self._run_save_alg(ws_grp, write_resolution=False, include_extra_cols=False) self._check_file_header(["instrument_settings:\n" "# incident_angle: null\n" "# wavelength: null"]) for state in spin_states: - self._check_file_header([f"# polarization: {state}"]) + with self.subTest(test_case=state): + self._check_file_header([f"# polarization: {state}"]) def _create_sample_workspace(self, rb_num_log_name=_LOG_RB_NUMBER, instrument_name="", ws_name="ws"): # Create a single spectrum workspace in units of momentum transfer @@ -599,12 +619,12 @@ def _create_sample_workspace_group(self, member_ws_names, group_name="sample_gro self._create_sample_workspace(ws_name=ws_name, instrument_name=instrument_name) return GroupWorkspaces(InputWorkspaces=",".join(member_ws_names), OutputWorkspace=group_name) - def _create_sample_workspace_group_with_spin_state(self, spin_states, instrument_name=""): + def _create_sample_workspace_group_with_spin_state(self, spin_states): group_member_names = [] for state in spin_states: ws_name = "ws_" + state group_member_names.append(ws_name) - self._create_sample_workspace(ws_name=ws_name, instrument_name=instrument_name) + self._create_sample_workspace(ws_name=ws_name) AddSampleLog(Workspace=ws_name, LogName="spin_state_ORSO", LogText=state) return GroupWorkspaces(InputWorkspaces=",".join(group_member_names), OutputWorkspace="group_pol") From ff774f88a6e18632e3ba1f54171a7c16ddf9737f Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Mon, 2 Dec 2024 14:14:37 +0000 Subject: [PATCH 07/19] Update SaveISISReflectomtryORSO entry on docs --- docs/source/algorithms/SaveISISReflectometryORSO-v1.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/source/algorithms/SaveISISReflectometryORSO-v1.rst b/docs/source/algorithms/SaveISISReflectometryORSO-v1.rst index dd0035918494..9bbfa3b01825 100644 --- a/docs/source/algorithms/SaveISISReflectometryORSO-v1.rst +++ b/docs/source/algorithms/SaveISISReflectometryORSO-v1.rst @@ -32,7 +32,8 @@ Dataset names A dataset name is generated automatically for each individual workspace in the input list or workspace group. This is done as follows: - If there is a call to :ref:`algm-Stitch1DMany` in the workspace history then the dataset is given the name "Stitched". -- If it is not a stitched dataset then, if available in the workspace reduction history, the value of theta that was used for conversion to Q is given as the dataset name. +- If it is not a stitched dataset then, if available in the workspace reduction history, the value of theta that was used for conversion to Q and/or the polarization + encountered in the sample logs is given as the dataset name. - If a dataset name cannot be generated from either of the above, then the workspace name is used as the dataset name. For a workspace that is a member of a workspace group, if the generated dataset name is either "Stitched" or the theta value, then the individual workspace name is also included in the dataset name. @@ -99,6 +100,9 @@ the file is saved without this metadata included. | | correction workspace or file name and the calibration file name from | | | :ref:`algm-ReflectometryISISLoadAndProcess` in the workspace history. | +---------------------+-----------------------------------------------------------------------------------------------+ +|polarization | For input workspaces containing the ``spin_state_ORSO`` sample log, polarization information | +| | will be added to the header using the ORSO format [#ORSO]_. | ++---------------------+-----------------------------------------------------------------------------------------------+ Usage ----- From aa1bd775274921775817c0a196a90f4e44fde56d Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Tue, 3 Dec 2024 20:17:59 +0000 Subject: [PATCH 08/19] Add polarization in orso_helper_test --- .../utils/reflectometry/orso_helper_test.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/Framework/PythonInterface/test/python/mantid/utils/reflectometry/orso_helper_test.py b/Framework/PythonInterface/test/python/mantid/utils/reflectometry/orso_helper_test.py index 497edc3e87d4..e1244c681824 100644 --- a/Framework/PythonInterface/test/python/mantid/utils/reflectometry/orso_helper_test.py +++ b/Framework/PythonInterface/test/python/mantid/utils/reflectometry/orso_helper_test.py @@ -225,7 +225,9 @@ def test_create_mantid_orso_dataset(self): reduction_timestamp = datetime.now() creator_name = "Creator Name" creator_affiliation = "Creator Affiliation" - dataset = MantidORSODataset(dataset_name, self._data_columns, self._ws, reduction_timestamp, creator_name, creator_affiliation) + dataset = MantidORSODataset( + dataset_name, self._data_columns, self._ws, reduction_timestamp, creator_name, creator_affiliation, polarized_dataset=False + ) orso_dataset = dataset.dataset self.assertIsNotNone(orso_dataset) @@ -253,6 +255,13 @@ def test_set_doi_on_mantid_orso_dataset(self): self.assertEqual(doi, dataset.dataset.info.data_source.experiment.doi) + def test_set_polarization_on_mantid_orso_dataset(self): + dataset = self._create_test_dataset(polarized=True) + pol = "pp" + dataset.set_polarization(pol) + + self.assertEqual("pp", dataset.dataset.info.data_source.measurement.instrument_settings.polarization) + def test_set_reduction_call_on_mantid_orso_dataset(self): dataset = self._create_test_dataset() call = "ReflectometryReductionCall" @@ -353,10 +362,12 @@ def test_add_multiple_additional_files_to_mantid_orso_dataset(self): self._check_files_are_created(dataset, filenames, 0, len(filenames), False) - def _create_test_dataset(self): - return MantidORSODataset("Test dataset", self._data_columns, self._ws, datetime.now(), "", "") + def _create_test_dataset(self, polarized=False): + return MantidORSODataset("Test dataset", self._data_columns, self._ws, datetime.now(), "", "", polarized_dataset=polarized) - def _check_mantid_default_header(self, orso_dataset, dataset_name, ws, reduction_timestamp, creator_name, creator_affiliation): + def _check_mantid_default_header( + self, orso_dataset, dataset_name, ws, reduction_timestamp, creator_name, creator_affiliation, polarization=False + ): """Check that the default header contains only the information that can be shared for all Mantid implementations of the standard """ From 91277579c8f254eefdc2435654ac49358f663abb Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Wed, 4 Dec 2024 13:53:09 +0000 Subject: [PATCH 09/19] Don' print ws name when data is polarized --- .../plugins/algorithms/SaveISISReflectometryORSO.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Framework/PythonInterface/plugins/algorithms/SaveISISReflectometryORSO.py b/Framework/PythonInterface/plugins/algorithms/SaveISISReflectometryORSO.py index 07cd8caf4fd5..beab61bc9e36 100644 --- a/Framework/PythonInterface/plugins/algorithms/SaveISISReflectometryORSO.py +++ b/Framework/PythonInterface/plugins/algorithms/SaveISISReflectometryORSO.py @@ -162,7 +162,8 @@ def _set_name(self): # Ensure unique dataset names for workspace group members. # Eventually we will specify the polarization spin state to provide the unique names for polarised datasets. if self._is_ws_grp_member and self._name != self._ws.name(): - self._name = f"{self._ws.name()} {self._name}" + ws_name = f"{self._ws.name()} " if not self.is_polarized else "" + self._name = f"{ws_name}{self._name}" def _set_spin_state_from_logs(self) -> None: if self._ws.getRun().hasProperty("spin_state_ORSO"): From 7b7888ed3f5bc6764e1de46840e559942c296955 Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Wed, 4 Dec 2024 13:53:43 +0000 Subject: [PATCH 10/19] Fix tests printing output name when data is polarized --- .../python/plugins/algorithms/SaveISISReflectometryORSOTest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py index 9f78efb1b9d9..a2ee0e4a72df 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py +++ b/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py @@ -580,7 +580,7 @@ def test_saved_as_nexus_if_relevant_filename_extension(self, mock_save_orso_nexu def test_dataset_name_is_correctly_generated_for_different_angle_polarization_settings_in_ws_groups(self, mock_alg_histories): angle_pol = namedtuple("angle_pol", "angle polarization") angle_polarization_inputs = [angle_pol(None, "pp"), angle_pol(0.5, ""), angle_pol(0.5, "pp"), angle_pol(None, "")] - dataset_name_outputs = ["ws pp", "ws 0.500", "ws 0.500 pp", "ws"] + dataset_name_outputs = ["pp", "ws 0.500", "0.500 pp", "ws"] for in_params, out_dataset_name in zip(angle_polarization_inputs, dataset_name_outputs): with self.subTest(test_case=in_params): ws = self._create_sample_workspace() From 97ae1013baf25f055c08ba00637931c294e3cfcc Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Wed, 4 Dec 2024 13:54:12 +0000 Subject: [PATCH 11/19] Update system tests data files for save orso --- .../reference/ISISReducedPeriodDataWorkspaceORSOFile.ort.md5 | 2 +- .../framework/reference/ISISReducedWorkspaceORSOFile.ort.md5 | 2 +- .../framework/reference/ISISStitchedWorkspaceORSOFile.ort.md5 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Testing/SystemTests/tests/framework/reference/ISISReducedPeriodDataWorkspaceORSOFile.ort.md5 b/Testing/SystemTests/tests/framework/reference/ISISReducedPeriodDataWorkspaceORSOFile.ort.md5 index 7d660f25c4a0..70c337f55bf7 100644 --- a/Testing/SystemTests/tests/framework/reference/ISISReducedPeriodDataWorkspaceORSOFile.ort.md5 +++ b/Testing/SystemTests/tests/framework/reference/ISISReducedPeriodDataWorkspaceORSOFile.ort.md5 @@ -1 +1 @@ -de95ca11fc9fc2d82906fe92e5b5a5df +13e148d44b87ae870b4f0a46b2e44e97 diff --git a/Testing/SystemTests/tests/framework/reference/ISISReducedWorkspaceORSOFile.ort.md5 b/Testing/SystemTests/tests/framework/reference/ISISReducedWorkspaceORSOFile.ort.md5 index 27b4dbaf6da6..6ca0201c6439 100644 --- a/Testing/SystemTests/tests/framework/reference/ISISReducedWorkspaceORSOFile.ort.md5 +++ b/Testing/SystemTests/tests/framework/reference/ISISReducedWorkspaceORSOFile.ort.md5 @@ -1 +1 @@ -480e9a065373a1340b32c2e311bc8d4a +7c83fccdc77f8fae5cf2089826e9784b diff --git a/Testing/SystemTests/tests/framework/reference/ISISStitchedWorkspaceORSOFile.ort.md5 b/Testing/SystemTests/tests/framework/reference/ISISStitchedWorkspaceORSOFile.ort.md5 index 59885268d90d..23266bab30a6 100644 --- a/Testing/SystemTests/tests/framework/reference/ISISStitchedWorkspaceORSOFile.ort.md5 +++ b/Testing/SystemTests/tests/framework/reference/ISISStitchedWorkspaceORSOFile.ort.md5 @@ -1 +1 @@ -72cfcb05294bedaf07d4709ce10b652b +b450cb92b5b3e4ddbc86a82436837ae4 From 568667b8a52d4d1f73c0a59a95346b2081d7c073 Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Mon, 9 Dec 2024 17:35:10 +0000 Subject: [PATCH 12/19] Add python module for reflectometry constansts --- .../PythonInterface/mantid/CMakeLists.txt | 1 + .../mantid/utils/reflectometry/CMakeLists.txt | 25 ++++++++++++++++++ .../mantid/utils/reflectometry/__init__.py | 9 ++++++- .../Exports/PolarizationCorrectionHelpers.cpp | 26 +++++++++++++++++++ .../src/polarization_helpers.cpp.in | 20 ++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 Framework/PythonInterface/mantid/utils/reflectometry/CMakeLists.txt create mode 100644 Framework/PythonInterface/mantid/utils/reflectometry/src/Exports/PolarizationCorrectionHelpers.cpp create mode 100644 Framework/PythonInterface/mantid/utils/reflectometry/src/polarization_helpers.cpp.in diff --git a/Framework/PythonInterface/mantid/CMakeLists.txt b/Framework/PythonInterface/mantid/CMakeLists.txt index b2e1fa8c0046..b5eecde9f362 100644 --- a/Framework/PythonInterface/mantid/CMakeLists.txt +++ b/Framework/PythonInterface/mantid/CMakeLists.txt @@ -22,6 +22,7 @@ add_subdirectory(geometry) add_subdirectory(api) add_subdirectory(dataobjects) add_subdirectory(_plugins) +add_subdirectory(utils/reflectometry) # Defines the target the will cause the Python bundle to be copied set(PYBUNDLE_POST_TARGET PythonModule) diff --git a/Framework/PythonInterface/mantid/utils/reflectometry/CMakeLists.txt b/Framework/PythonInterface/mantid/utils/reflectometry/CMakeLists.txt new file mode 100644 index 000000000000..27036e7a7ddf --- /dev/null +++ b/Framework/PythonInterface/mantid/utils/reflectometry/CMakeLists.txt @@ -0,0 +1,25 @@ +# _polarization_helpers Python module + +set(MODULE_TEMPLATE src/polarization_helpers.cpp.in) + +# Files containing export definitions, these are automatically processed -- Do NOT sort this list. The order defines the +# order in which the export definitions occur and some depend on their base classes being exported first -- +set(EXPORT_FILES src/Exports/PolarizationCorrectionHelpers.cpp) + +set(MODULE_DEFINITION ${CMAKE_CURRENT_BINARY_DIR}/polarization_helpers.cpp) +create_module(${MODULE_TEMPLATE} ${MODULE_DEFINITION} ${EXPORT_FILES}) + +# Create the target for this directory +add_library(PythonReflHelpersModule ${MODULE_DEFINITION} ${EXPORT_FILES} ${PYTHON_INSTALL_FILES}) +add_library(PythonReflectometryHelpersModule ALIAS PythonReflHelpersModule) + +set_python_properties(PythonReflHelpersModule _polarization_helpers) + +# Add the required dependencies +target_link_libraries(PythonReflHelpersModule PRIVATE Mantid::Algorithms Mantid::PythonInterfaceCore) + +# Installation settings +set_target_properties(PythonReflHelpersModule PROPERTIES INSTALL_RPATH "${EXT_INSTALL_RPATH}") +mtd_install_shared_library( + TARGETS PythonReflHelpersModule DESTINATION ${Python_SITELIB_RELPATH}/mantid/polarization_helpers.cpp +) diff --git a/Framework/PythonInterface/mantid/utils/reflectometry/__init__.py b/Framework/PythonInterface/mantid/utils/reflectometry/__init__.py index 42dad64e006a..bea9a7813786 100644 --- a/Framework/PythonInterface/mantid/utils/reflectometry/__init__.py +++ b/Framework/PythonInterface/mantid/utils/reflectometry/__init__.py @@ -1,6 +1,13 @@ # Mantid Repository : https://github.com/mantidproject/mantid # -# Copyright © 2023 ISIS Rutherford Appleton Laboratory UKRI, +# Copyright © 2024 ISIS Rutherford Appleton Laboratory UKRI, # NScD Oak Ridge National Laboratory, European Spallation Source, # Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS # SPDX - License - Identifier: GPL - 3.0 + + +############################################################################### +# Load the C++ library and register the C++ class exports +############################################################################### +from mantid.utils import import_mantid_cext + +import_mantid_cext("._polarization_helpers", "mantid.utils.reflectometry", globals()) diff --git a/Framework/PythonInterface/mantid/utils/reflectometry/src/Exports/PolarizationCorrectionHelpers.cpp b/Framework/PythonInterface/mantid/utils/reflectometry/src/Exports/PolarizationCorrectionHelpers.cpp new file mode 100644 index 000000000000..b137ea42568f --- /dev/null +++ b/Framework/PythonInterface/mantid/utils/reflectometry/src/Exports/PolarizationCorrectionHelpers.cpp @@ -0,0 +1,26 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2024 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source, +// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS +// SPDX - License - Identifier: GPL - 3.0 + + +#include "MantidAlgorithms/PolarizationCorrections/PolarizationCorrectionsHelpers.h" +#include + +namespace { +class SpinStatesORSO {}; +} // namespace + +void export_SpinStatesORSO() { + using namespace boost::python; + + class_("SpinStatesORSO") + .def_readonly("PP", &Mantid::Algorithms::SpinStatesORSO::PP) + .def_readonly("PM", &Mantid::Algorithms::SpinStatesORSO::PM) + .def_readonly("MP", &Mantid::Algorithms::SpinStatesORSO::MP) + .def_readonly("MM", &Mantid::Algorithms::SpinStatesORSO::MM) + .def_readonly("PO", &Mantid::Algorithms::SpinStatesORSO::PO) + .def_readonly("MO", &Mantid::Algorithms::SpinStatesORSO::MO) + .def_readonly("LOG_NAME", &Mantid::Algorithms::SpinStatesORSO::LOG_NAME); +} diff --git a/Framework/PythonInterface/mantid/utils/reflectometry/src/polarization_helpers.cpp.in b/Framework/PythonInterface/mantid/utils/reflectometry/src/polarization_helpers.cpp.in new file mode 100644 index 000000000000..66213a987060 --- /dev/null +++ b/Framework/PythonInterface/mantid/utils/reflectometry/src/polarization_helpers.cpp.in @@ -0,0 +1,20 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2024 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source, +// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS +// SPDX - License - Identifier: GPL - 3.0 + + +@AUTO_GENERATE_WARNING@ +/********** Source = polarization_helpers.cpp.in **********************************************************/ + +#include +#include + +// Forward declare +@EXPORT_DECLARE@ + +BOOST_PYTHON_MODULE(_polarization_helpers) +{ +@EXPORT_FUNCTIONS@ +} From 212a7be46e8c18dbcddddf4d02fb142d15fda234 Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Mon, 9 Dec 2024 21:20:30 +0000 Subject: [PATCH 13/19] Add dependency on the interface: --- Framework/PythonInterface/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Framework/PythonInterface/CMakeLists.txt b/Framework/PythonInterface/CMakeLists.txt index 7dadc91ca744..95d36dc75eb6 100644 --- a/Framework/PythonInterface/CMakeLists.txt +++ b/Framework/PythonInterface/CMakeLists.txt @@ -109,6 +109,7 @@ add_dependencies( PythonAPIModule PythonDataObjectsModule PythonCurveFittingModule + PythonReflHelpersModule ) # Clear any leftover bin/$(Configuration)/mantid/ folder, from when PythonInterface was being copied over. The last From 74a7e37543d4ff445182e40fe407589f30a1e016 Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Tue, 10 Dec 2024 13:12:04 +0000 Subject: [PATCH 14/19] change python destination path --- .../PythonInterface/mantid/utils/reflectometry/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/PythonInterface/mantid/utils/reflectometry/CMakeLists.txt b/Framework/PythonInterface/mantid/utils/reflectometry/CMakeLists.txt index 27036e7a7ddf..3b7cda17118f 100644 --- a/Framework/PythonInterface/mantid/utils/reflectometry/CMakeLists.txt +++ b/Framework/PythonInterface/mantid/utils/reflectometry/CMakeLists.txt @@ -21,5 +21,5 @@ target_link_libraries(PythonReflHelpersModule PRIVATE Mantid::Algorithms Mantid: # Installation settings set_target_properties(PythonReflHelpersModule PROPERTIES INSTALL_RPATH "${EXT_INSTALL_RPATH}") mtd_install_shared_library( - TARGETS PythonReflHelpersModule DESTINATION ${Python_SITELIB_RELPATH}/mantid/polarization_helpers.cpp + TARGETS PythonReflHelpersModule DESTINATION ${Python_SITELIB_RELPATH}/mantid/utils/reflectometry ) From ce8c598a2931f78acde6949da998d333628e072c Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Tue, 10 Dec 2024 14:23:17 +0000 Subject: [PATCH 15/19] Add tests to check that ReflectometryReductionAuto is adding logs if it is a polarized dataset --- .../test/ReflectometryReductionOneAuto3Test.h | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/Framework/Reflectometry/test/ReflectometryReductionOneAuto3Test.h b/Framework/Reflectometry/test/ReflectometryReductionOneAuto3Test.h index 049204ee3de7..a380b127fcaf 100644 --- a/Framework/Reflectometry/test/ReflectometryReductionOneAuto3Test.h +++ b/Framework/Reflectometry/test/ReflectometryReductionOneAuto3Test.h @@ -769,6 +769,48 @@ class ReflectometryReductionOneAuto3Test : public CxxTest::TestSuite { TS_ASSERT(!AnalysisDataService::Instance().doesExist("IvsLam")); } + void test_workspace_group_with_no_polarization_analysis_does_not_create_spin_state_sample_logs() { + ReflectometryReductionOneAuto3 alg; + setup_alg_on_input_workspace_group_with_run_number(alg); + alg.setProperty("PolarizationAnalysis", false); + TS_ASSERT_THROWS_NOTHING(alg.execute()); + + auto outQGroup = retrieveOutWS("IvsQ_1234"); + auto outQGroupBinned = retrieveOutWS("IvsQ_binned_1234"); + auto outQGroupLam = retrieveOutWS("IvsLam_1234"); + check_output_group_contains_sample_logs_for_spin_state_ORSO(outQGroup, false); + check_output_group_contains_sample_logs_for_spin_state_ORSO(outQGroupBinned, false); + check_output_group_contains_sample_logs_for_spin_state_ORSO(outQGroupLam, false); + } + + void test_workspace_group_with_polarization_analysis_creates_spin_state_sample_logs() { + std::string const name = "input"; + prepareInputGroup(name, "Wildes"); + applyPolarizationEfficiencies(name); + + ReflectometryReductionOneAuto3 alg; + alg.initialize(); + alg.setPropertyValue("InputWorkspace", name); + alg.setProperty("ThetaIn", 10.0); + alg.setProperty("WavelengthMin", 1.0); + alg.setProperty("WavelengthMax", 15.0); + alg.setProperty("ProcessingInstructions", "2"); + alg.setProperty("MomentumTransferStep", 0.04); + alg.setProperty("PolarizationAnalysis", true); + alg.setPropertyValue("OutputWorkspace", "IvsQ"); + alg.setPropertyValue("OutputWorkspaceBinned", "IvsQ_binned"); + alg.setPropertyValue("OutputWorkspaceWavelength", "IvsLam"); + alg.execute(); + + auto outQGroup = retrieveOutWS("IvsQ"); + auto outQGroupBinned = retrieveOutWS("IvsQ_binned"); + auto outQGroupLam = retrieveOutWS("IvsLam"); + + check_output_group_contains_sample_logs_for_spin_state_ORSO(outQGroup, true); + check_output_group_contains_sample_logs_for_spin_state_ORSO(outQGroupBinned, true); + check_output_group_contains_sample_logs_for_spin_state_ORSO(outQGroupLam, true); + } + void test_polarization_correction() { std::string const name = "input"; @@ -1962,4 +2004,11 @@ class ReflectometryReductionOneAuto3Test : public CxxTest::TestSuite { TS_ASSERT_EQUALS(selectedChildHistories->getPropertyValue(prop), value); } } + + void check_output_group_contains_sample_logs_for_spin_state_ORSO(std::vector const &wsGroup, + bool has_sample_logs = false) { + for (auto const &ws : wsGroup) { + TS_ASSERT_EQUALS(ws->mutableRun().hasProperty("spin_state_ORSO"), has_sample_logs) + } + } }; From 4654bed975cb3083150b7a60933b8f1188e444fa Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Tue, 10 Dec 2024 15:30:45 +0000 Subject: [PATCH 16/19] Add polarized parameter as is_polarized and as optional --- .../mantid/utils/reflectometry/orso_helper.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Framework/PythonInterface/mantid/utils/reflectometry/orso_helper.py b/Framework/PythonInterface/mantid/utils/reflectometry/orso_helper.py index d03ddc2f1bc0..795b83ff17aa 100644 --- a/Framework/PythonInterface/mantid/utils/reflectometry/orso_helper.py +++ b/Framework/PythonInterface/mantid/utils/reflectometry/orso_helper.py @@ -62,12 +62,12 @@ def __init__( reduction_timestamp: datetime, creator_name: str, creator_affiliation: str, - polarized_dataset: bool, + is_polarized_dataset: bool, ) -> None: self._data_columns = data_columns self._header = None - self._create_mandatory_header(ws, dataset_name, reduction_timestamp, creator_name, creator_affiliation, polarized_dataset) + self._create_mandatory_header(ws, dataset_name, reduction_timestamp, creator_name, creator_affiliation, is_polarized_dataset) @property def dataset(self) -> OrsoDataset: @@ -102,7 +102,13 @@ def _create_file(filename: str, timestamp: Optional[datetime] = None, comment: O return File(filename, timestamp, comment) def _create_mandatory_header( - self, ws, dataset_name: str, reduction_timestamp: datetime, creator_name: str, creator_affiliation: str, polarized_dataset: bool + self, + ws, + dataset_name: str, + reduction_timestamp: datetime, + creator_name: str, + creator_affiliation: str, + is_polarized_dataset: Optional[bool] = None, ) -> None: owner = Person(name=None, affiliation=None) @@ -117,7 +123,7 @@ def _create_mandatory_header( sample = Sample(name=ws.getTitle()) # This will initially only consider polarization - instrument_settings = InstrumentSettings(None, None) if polarized_dataset else None + instrument_settings = InstrumentSettings(None, None) if is_polarized_dataset else None measurement = Measurement(instrument_settings=instrument_settings, data_files=[]) data_source = DataSource(owner=owner, experiment=experiment, sample=sample, measurement=measurement) From 11b29e6d315b0bdd3a042c127c826c1bdf4583fc Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Tue, 10 Dec 2024 15:32:26 +0000 Subject: [PATCH 17/19] Correct unique dataset names for Stitched workspaces --- .../algorithms/SaveISISReflectometryORSO.py | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/Framework/PythonInterface/plugins/algorithms/SaveISISReflectometryORSO.py b/Framework/PythonInterface/plugins/algorithms/SaveISISReflectometryORSO.py index beab61bc9e36..201d1eb8bbc9 100644 --- a/Framework/PythonInterface/plugins/algorithms/SaveISISReflectometryORSO.py +++ b/Framework/PythonInterface/plugins/algorithms/SaveISISReflectometryORSO.py @@ -148,22 +148,20 @@ def _populate_q_conversion_info(self): self._q_conversion_theta = float(np.rad2deg(self._ws.spectrumInfo().signedTwoTheta(0))) / 2.0 def _set_name(self): - theta_assigned: bool = self._q_conversion_theta is not None - if self.is_stitched: self._name = "Stitched" - elif theta_assigned or self.is_polarized: - theta_str = f"{self._q_conversion_theta:.3f}" if theta_assigned else "" - space_str = " " if (theta_assigned and self.is_polarized) else "" - self._name = f"{theta_str}{space_str}{self._spin_state}" + elif self._q_conversion_theta is not None: + self._name = f"{self._q_conversion_theta:.3f}" else: self._name = self._ws.name() + if self.is_polarized: + self._name = f"{self._name} {self._spin_state}" + return + # Ensure unique dataset names for workspace group members. - # Eventually we will specify the polarization spin state to provide the unique names for polarised datasets. - if self._is_ws_grp_member and self._name != self._ws.name(): - ws_name = f"{self._ws.name()} " if not self.is_polarized else "" - self._name = f"{ws_name}{self._name}" + if self._is_ws_grp_member and self._ws.name() != self._name: + self._name = f"{self._ws.name()} {self._name}" def _set_spin_state_from_logs(self) -> None: if self._ws.getRun().hasProperty("spin_state_ORSO"): @@ -414,7 +412,7 @@ def _create_dataset_with_mandatory_header( reduction_timestamp=self._get_reduction_timestamp(refl_dataset.reduction_history), creator_name=self.name(), creator_affiliation=MantidORSODataset.SOFTWARE_NAME, - polarized_dataset=refl_dataset.is_polarized, + is_polarized_dataset=refl_dataset.is_polarized, ) def _add_optional_header_info(self, dataset: MantidORSODataset, refl_dataset: ReflectometryDataset) -> None: @@ -427,7 +425,8 @@ def _add_optional_header_info(self, dataset: MantidORSODataset, refl_dataset: Re dataset.set_proposal_id(rb_number) dataset.set_doi(doi) dataset.set_reduction_call(self._get_reduction_script(refl_dataset)) - dataset.set_polarization(refl_dataset.spin_state) + if refl_dataset.is_polarized: + dataset.set_polarization(refl_dataset.spin_state) reduction_workflow_histories = refl_dataset.reduction_workflow_histories if not refl_dataset.reduction_workflow_histories: From 9b8e58061a3474b2497adbaef9db970f7e6afcd3 Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Tue, 10 Dec 2024 15:36:35 +0000 Subject: [PATCH 18/19] Add constants from cpp PolarizationCorrectionHelpers --- .../mantid/utils/reflectometry/orso_helper_test.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Framework/PythonInterface/test/python/mantid/utils/reflectometry/orso_helper_test.py b/Framework/PythonInterface/test/python/mantid/utils/reflectometry/orso_helper_test.py index e1244c681824..5a69fe3942df 100644 --- a/Framework/PythonInterface/test/python/mantid/utils/reflectometry/orso_helper_test.py +++ b/Framework/PythonInterface/test/python/mantid/utils/reflectometry/orso_helper_test.py @@ -12,6 +12,7 @@ from mantid.simpleapi import CreateSampleWorkspace from mantid.utils.reflectometry.orso_helper import MantidORSODataColumns, MantidORSODataset, MantidORSOSaver +from mantid.utils.reflectometry import SpinStatesORSO from orsopy.fileio.base import Column, ErrorColumn @@ -226,7 +227,7 @@ def test_create_mantid_orso_dataset(self): creator_name = "Creator Name" creator_affiliation = "Creator Affiliation" dataset = MantidORSODataset( - dataset_name, self._data_columns, self._ws, reduction_timestamp, creator_name, creator_affiliation, polarized_dataset=False + dataset_name, self._data_columns, self._ws, reduction_timestamp, creator_name, creator_affiliation, is_polarized_dataset=False ) orso_dataset = dataset.dataset @@ -257,10 +258,9 @@ def test_set_doi_on_mantid_orso_dataset(self): def test_set_polarization_on_mantid_orso_dataset(self): dataset = self._create_test_dataset(polarized=True) - pol = "pp" - dataset.set_polarization(pol) + dataset.set_polarization(SpinStatesORSO.PP) - self.assertEqual("pp", dataset.dataset.info.data_source.measurement.instrument_settings.polarization) + self.assertEqual(SpinStatesORSO.PP, dataset.dataset.info.data_source.measurement.instrument_settings.polarization) def test_set_reduction_call_on_mantid_orso_dataset(self): dataset = self._create_test_dataset() @@ -363,11 +363,9 @@ def test_add_multiple_additional_files_to_mantid_orso_dataset(self): self._check_files_are_created(dataset, filenames, 0, len(filenames), False) def _create_test_dataset(self, polarized=False): - return MantidORSODataset("Test dataset", self._data_columns, self._ws, datetime.now(), "", "", polarized_dataset=polarized) + return MantidORSODataset("Test dataset", self._data_columns, self._ws, datetime.now(), "", "", is_polarized_dataset=polarized) - def _check_mantid_default_header( - self, orso_dataset, dataset_name, ws, reduction_timestamp, creator_name, creator_affiliation, polarization=False - ): + def _check_mantid_default_header(self, orso_dataset, dataset_name, ws, reduction_timestamp, creator_name, creator_affiliation): """Check that the default header contains only the information that can be shared for all Mantid implementations of the standard """ From 14c696f2be7813b8d15071ce99ccc04518e87574 Mon Sep 17 00:00:00 2001 From: adriazalvarez Date: Tue, 10 Dec 2024 15:37:22 +0000 Subject: [PATCH 19/19] Add constants from cpp PolarizationCorrectionHelpers --- .../SaveISISReflectometryORSOTest.py | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py index a2ee0e4a72df..172fd38b8632 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py +++ b/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py @@ -18,6 +18,7 @@ from mantid.api import AnalysisDataService from mantid.kernel import version, DateAndTime from mantid.utils.reflectometry.orso_helper import MantidORSODataset, MantidORSOSaver +from mantid.utils.reflectometry import SpinStatesORSO class SaveISISReflectometryORSOTest(unittest.TestCase): @@ -578,24 +579,32 @@ def test_saved_as_nexus_if_relevant_filename_extension(self, mock_save_orso_nexu @patch("mantid.api.WorkspaceHistory.getAlgorithmHistories") def test_dataset_name_is_correctly_generated_for_different_angle_polarization_settings_in_ws_groups(self, mock_alg_histories): + theta = 0.5 + w_name = "ws" angle_pol = namedtuple("angle_pol", "angle polarization") - angle_polarization_inputs = [angle_pol(None, "pp"), angle_pol(0.5, ""), angle_pol(0.5, "pp"), angle_pol(None, "")] - dataset_name_outputs = ["pp", "ws 0.500", "0.500 pp", "ws"] + angle_polarization_inputs = [ + angle_pol(None, SpinStatesORSO.PP), + angle_pol(theta, ""), + angle_pol(theta, SpinStatesORSO.PP), + angle_pol(None, ""), + ] + dataset_name_outputs = [f"{w_name} {SpinStatesORSO.PP}", f"{w_name} {theta:.3f}", f"{theta:.3f} {SpinStatesORSO.PP}", w_name] + dataset_name_outputs = [f"{w_name} {SpinStatesORSO.PP}", f"{w_name} {theta:.3f}", f"{theta:.3f} {SpinStatesORSO.PP}", w_name] for in_params, out_dataset_name in zip(angle_polarization_inputs, dataset_name_outputs): with self.subTest(test_case=in_params): ws = self._create_sample_workspace() - AddSampleLog(Workspace=ws, LogName="spin_state_ORSO", LogText=in_params.polarization) + AddSampleLog(Workspace=ws, LogName=SpinStatesORSO.LOG_NAME, LogText=in_params.polarization) if in_params.angle is not None: self._configure_q_conversion_alg_mock_history(mock_alg_histories, self._REF_ROI, {"ScatteringAngle": in_params.angle}) - GroupWorkspaces(InputWorkspaces=["ws"], OutputWorkspace="ws_group") + GroupWorkspaces(InputWorkspaces=[w_name], OutputWorkspace=f"{w_name}_group") - self._run_save_alg("ws_group") + self._run_save_alg(f"{w_name}_group") self._check_file_header([self._get_dataset_name_entry(out_dataset_name)]) mock_alg_histories.reset_mock(return_value=True) def test_data_with_spin_state_logs_adds_polarization_metadata_in_instrument_settings_header(self): - spin_states = ["pp", "mm", "mp", "pm"] + spin_states = [SpinStatesORSO.PP, SpinStatesORSO.MM, SpinStatesORSO.MP, SpinStatesORSO.PM] ws_grp = self._create_sample_workspace_group_with_spin_state(spin_states) self._run_save_alg(ws_grp, write_resolution=False, include_extra_cols=False) @@ -625,7 +634,7 @@ def _create_sample_workspace_group_with_spin_state(self, spin_states): ws_name = "ws_" + state group_member_names.append(ws_name) self._create_sample_workspace(ws_name=ws_name) - AddSampleLog(Workspace=ws_name, LogName="spin_state_ORSO", LogText=state) + AddSampleLog(Workspace=ws_name, LogName=SpinStatesORSO.LOG_NAME, LogText=state) return GroupWorkspaces(InputWorkspaces=",".join(group_member_names), OutputWorkspace="group_pol") def _get_expected_data_file_metadata(self, expected_entries, expected_section_end):