Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8a39876
Retrieve spin state form sample logs and add to ReflectometryDataSet …
adriazalvarez Nov 28, 2024
a9083af
Add instrument settings header file if polarization is present, also …
adriazalvarez Nov 28, 2024
95307da
Add spin state to logs in polarization efficiencies correction algorithm
adriazalvarez Nov 28, 2024
eb1963c
Add test for checking polarization state is correctly saved on orso file
adriazalvarez Nov 28, 2024
2f78dee
Add release notes
adriazalvarez Dec 2, 2024
a8b1269
Add test for checking dataset names with different polarization/angles
adriazalvarez Dec 2, 2024
e2e4d7d
Update SaveISISReflectomtryORSO entry on docs
adriazalvarez Dec 2, 2024
556b237
Add polarization in orso_helper_test
adriazalvarez Dec 3, 2024
7d3df69
Don' print ws name when data is polarized
adriazalvarez Dec 4, 2024
331a3d6
Fix tests printing output name when data is polarized
adriazalvarez Dec 4, 2024
01c54dd
Update system tests data files for save orso
adriazalvarez Dec 4, 2024
2e64f74
Add python module for reflectometry constansts
adriazalvarez Dec 9, 2024
87cd34a
Add dependency on the interface:
adriazalvarez Dec 9, 2024
0b6f38b
change python destination path
adriazalvarez Dec 10, 2024
fb62ad2
Add tests to check that ReflectometryReductionAuto is adding logs if …
adriazalvarez Dec 10, 2024
8470c7d
Add polarized parameter as is_polarized and as optional
adriazalvarez Dec 10, 2024
4393325
Correct unique dataset names for Stitched workspaces
adriazalvarez Dec 10, 2024
1c44c20
Add constants from cpp PolarizationCorrectionHelpers
adriazalvarez Dec 10, 2024
40f0cb4
Add constants from cpp PolarizationCorrectionHelpers
adriazalvarez Dec 10, 2024
adaaa8f
Add test for python module of polarization constants
adriazalvarez Jan 2, 2025
0679b9e
Use cpp defined polarization constants
adriazalvarez Jan 7, 2025
859036f
Update date
adriazalvarez Jan 7, 2025
4f8aed9
Remove duplicate line:
adriazalvarez Jan 7, 2025
8b7f125
Use polarization correction constants to refer to orso logs
adriazalvarez Jan 7, 2025
3925735
Update documentation with new naming convention for polarized and not…
adriazalvarez Jan 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Framework/PythonInterface/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions Framework/PythonInterface/mantid/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Original file line number Diff line number Diff line change
@@ -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
)
Original file line number Diff line number Diff line change
@@ -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())
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand All @@ -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

Expand All @@ -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)

Expand All @@ -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)

Expand Down
Original file line number Diff line number Diff line change
@@ -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 <boost/python/class.hpp>

namespace {
class SpinStatesORSO {};
} // namespace

void export_SpinStatesORSO() {
using namespace boost::python;

class_<SpinStatesORSO>("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);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 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 <boost/python/def.hpp>
#include <boost/python/module.hpp>

// Forward declare
@EXPORT_DECLARE@

BOOST_PYTHON_MODULE(_polarization_helpers)
{
@EXPORT_FUNCTIONS@
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
# SPDX - License - Identifier: GPL - 3.0 +
from mantid.utils.reflectometry.orso_helper import MantidORSODataColumns, MantidORSODataset, MantidORSOSaver
from mantid.utils.reflectometry import SpinStatesORSO

from mantid.kernel import (
Direction,
Expand Down Expand Up @@ -48,9 +49,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
Expand All @@ -69,6 +72,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
Expand All @@ -85,6 +92,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
Expand Down Expand Up @@ -141,15 +152,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

Comment on lines +159 to +162
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if self.is_polarized:
self._name = f"{self._name} {self._spin_state}"
return
if self.is_polarized:
self._name = f"{self._name} {self._spin_state}"
return

Here I have decided to return early because if the dataset is polarized is not necessary to prepend the ws name for unique datasets and in some cases the ws name would be repeated.

# 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(SpinStatesORSO.LOG_NAME):
self._spin_state = self._ws.getRun().getLogData(SpinStatesORSO.LOG_NAME).value


class SaveISISReflectometryORSO(PythonAlgorithm):
"""
Expand Down Expand Up @@ -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,
is_polarized_dataset=refl_dataset.is_polarized,
)

def _add_optional_header_info(self, dataset: MantidORSODataset, refl_dataset: ReflectometryDataset) -> None:
Expand All @@ -407,6 +426,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:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# mantid.utils.reflectometry tests

set(TEST_PY_FILES orso_helper_test.py)
set(TEST_PY_FILES orso_helper_test.py polarization_helpers_test.py)

check_tests_valid(${CMAKE_CURRENT_SOURCE_DIR} ${TEST_PY_FILES})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Mantid Repository : https://github.com/mantidproject/mantid
#
# Copyright &copy; 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 +
import unittest

from mantid.utils.reflectometry import SpinStatesORSO


class PolarizationHelpersTest(unittest.TestCase):
def test_ORSO_spin_state_definitions_are_imported_correctly(self):
self.assertEqual("pp", SpinStatesORSO.PP)
self.assertEqual("pm", SpinStatesORSO.PM)
self.assertEqual("mp", SpinStatesORSO.MP)
self.assertEqual("mm", SpinStatesORSO.MM)
self.assertEqual("po", SpinStatesORSO.PO)
self.assertEqual("mo", SpinStatesORSO.MO)
self.assertEqual("spin_state_ORSO", SpinStatesORSO.LOG_NAME)


if __name__ == "__main__":
unittest.main()
Loading
Loading