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 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..3b7cda17118f --- /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/utils/reflectometry +) 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/orso_helper.py b/Framework/PythonInterface/mantid/utils/reflectometry/orso_helper.py index 92e701bc69a6..795b83ff17aa 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, + 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) + self._create_mandatory_header(ws, dataset_name, reduction_timestamp, creator_name, creator_affiliation, is_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,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 + 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) @@ -111,7 +122,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 is_polarized_dataset else None + measurement = Measurement(instrument_settings=instrument_settings, data_files=[]) data_source = DataSource(owner=owner, experiment=experiment, sample=sample, measurement=measurement) 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@ +} diff --git a/Framework/PythonInterface/plugins/algorithms/SaveISISReflectometryORSO.py b/Framework/PythonInterface/plugins/algorithms/SaveISISReflectometryORSO.py index e8a2a0631dc5..201d1eb8bbc9 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 @@ -141,15 +151,22 @@ def _set_name(self): if self.is_stitched: self._name = "Stitched" elif self._q_conversion_theta is not None: - self._name = str(self._q_conversion_theta) + 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(): + 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"): + self._spin_state = self._ws.getRun().getLogData("spin_state_ORSO").value + class SaveISISReflectometryORSO(PythonAlgorithm): """ @@ -395,6 +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, + is_polarized_dataset=refl_dataset.is_polarized, ) def _add_optional_header_info(self, dataset: MantidORSODataset, refl_dataset: ReflectometryDataset) -> None: @@ -407,6 +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)) + 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: 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..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 @@ -225,7 +226,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, is_polarized_dataset=False + ) orso_dataset = dataset.dataset self.assertIsNotNone(orso_dataset) @@ -253,6 +256,12 @@ 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) + dataset.set_polarization(SpinStatesORSO.PP) + + 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() call = "ReflectometryReductionCall" @@ -353,8 +362,8 @@ 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(), "", "", is_polarized_dataset=polarized) 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 diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py index b5e2fc78d4d2..172fd38b8632 100644 --- a/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py +++ b/Framework/PythonInterface/test/python/plugins/algorithms/SaveISISReflectometryORSOTest.py @@ -11,17 +11,14 @@ 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, -) +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 +from mantid.utils.reflectometry import SpinStatesORSO class SaveISISReflectometryORSOTest(unittest.TestCase): @@ -484,7 +481,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 +496,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 +577,43 @@ 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): + theta = 0.5 + w_name = "ws" + angle_pol = namedtuple("angle_pol", "angle polarization") + 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=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=[w_name], OutputWorkspace=f"{w_name}_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 = [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) + + self._check_file_header(["instrument_settings:\n" "# incident_angle: null\n" "# wavelength: null"]) + for state in spin_states: + 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 ws = CreateSampleWorkspace( @@ -594,6 +628,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): + 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) + 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): files_entry = [f"{self._DATA_FILES_HEADING}\n"] 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); 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) + } + } }; 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 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 ----- 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.