From 0ad6305c18e516dbf428b6b4ed99bb4991f1e58a Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Wed, 15 May 2024 09:27:21 +0200 Subject: [PATCH 1/7] tests are passing --- .../calculators/refl1d/wrapper.py | 6 +- .../calculators/refnx/wrapper.py | 6 +- .../calculators/wrapper_base.py | 9 +- src/easyreflectometry/experiment/__init__.py | 12 +-- src/easyreflectometry/experiment/model.py | 24 +++-- .../experiment/resolution_functions.py | 95 ++++++++++++++----- tests/calculators/refnx/test_refnx_wrapper.py | 12 +-- tests/experiment/test_model.py | 40 ++++---- tests/experiment/test_resolution_functions.py | 82 +++++++++++++--- tests/test_fitting.py | 6 +- 10 files changed, 196 insertions(+), 96 deletions(-) diff --git a/src/easyreflectometry/calculators/refl1d/wrapper.py b/src/easyreflectometry/calculators/refl1d/wrapper.py index dd0cdb1e..bed77817 100644 --- a/src/easyreflectometry/calculators/refl1d/wrapper.py +++ b/src/easyreflectometry/calculators/refl1d/wrapper.py @@ -3,7 +3,7 @@ from typing import Tuple import numpy as np -from easyreflectometry.experiment.resolution_functions import is_percentage_fhwm_resolution_function +from easyreflectometry.experiment.resolution_functions import PercentageFhwm from refl1d import model from refl1d import names @@ -145,9 +145,9 @@ def calculate(self, q_array: np.ndarray, model_name: str) -> np.ndarray: :return: reflectivity calculated at q """ sample = _build_sample(self.storage, model_name) - dq_array = self._resolution_function(q_array) + dq_array = self._resolution_function.smearing(q_array) - if is_percentage_fhwm_resolution_function(self._resolution_function): + if isinstance(self._resolution_function, PercentageFhwm): # Get percentage of Q and change from sigma to FWHM dq_array = dq_array * q_array / 100 / (2 * np.sqrt(2 * np.log(2))) diff --git a/src/easyreflectometry/calculators/refnx/wrapper.py b/src/easyreflectometry/calculators/refnx/wrapper.py index a1f2fa2f..8d29b82b 100644 --- a/src/easyreflectometry/calculators/refnx/wrapper.py +++ b/src/easyreflectometry/calculators/refnx/wrapper.py @@ -3,7 +3,7 @@ from typing import Tuple import numpy as np -from easyreflectometry.experiment.resolution_functions import is_percentage_fhwm_resolution_function +from easyreflectometry.experiment.resolution_functions import PercentageFhwm from refnx import reflect from ..wrapper_base import WrapperBase @@ -129,8 +129,8 @@ def calculate(self, q_array: np.ndarray, model_name: str) -> np.ndarray: dq_type='pointwise', ) - dq_vector = self._resolution_function(q_array) - if is_percentage_fhwm_resolution_function(self._resolution_function): + dq_vector = self._resolution_function.smearing(q_array) + if isinstance(self._resolution_function, PercentageFhwm): # FWHM Percentage resolution is constant given as # For a constant resolution percentage refnx supports to pass a scalar value rather than a vector dq_vector = dq_vector[0] diff --git a/src/easyreflectometry/calculators/wrapper_base.py b/src/easyreflectometry/calculators/wrapper_base.py index caa2d464..37cbadd4 100644 --- a/src/easyreflectometry/calculators/wrapper_base.py +++ b/src/easyreflectometry/calculators/wrapper_base.py @@ -1,10 +1,9 @@ from abc import abstractmethod -from typing import Callable import numpy as np -from easyreflectometry.experiment import DEFAULT_RESOLUTION_FWHM_PERCENTAGE -from easyreflectometry.experiment import percentage_fhwm_resolution_function +from easyreflectometry.experiment import PercentageFhwm +from easyreflectometry.experiment import ResolutionFunction class WrapperBase: @@ -16,7 +15,7 @@ def __init__(self): 'item': {}, 'model': {}, } - self._resolution_function = percentage_fhwm_resolution_function(DEFAULT_RESOLUTION_FWHM_PERCENTAGE) + self._resolution_function = PercentageFhwm() def reset_storage(self): """Reset the storage area to blank.""" @@ -205,7 +204,7 @@ def get_item_value(self, name: str, key: str) -> float: item = getattr(item, key) return getattr(item, 'value') - def set_resolution_function(self, resolution_function: Callable[[np.array], np.array]) -> None: + def set_resolution_function(self, resolution_function: ResolutionFunction) -> None: """Set the resolution function for the calculator. :param resolution_function: The resolution function diff --git a/src/easyreflectometry/experiment/__init__.py b/src/easyreflectometry/experiment/__init__.py index 64dd7caa..50480cec 100644 --- a/src/easyreflectometry/experiment/__init__.py +++ b/src/easyreflectometry/experiment/__init__.py @@ -1,13 +1,13 @@ from .model import Model from .model_collection import ModelCollection -from .resolution_functions import DEFAULT_RESOLUTION_FWHM_PERCENTAGE -from .resolution_functions import linear_spline_resolution_function -from .resolution_functions import percentage_fhwm_resolution_function +from .resolution_functions import LinearSpline +from .resolution_functions import PercentageFhwm +from .resolution_functions import ResolutionFunction __all__ = ( - DEFAULT_RESOLUTION_FWHM_PERCENTAGE, - percentage_fhwm_resolution_function, - linear_spline_resolution_function, + LinearSpline, + PercentageFhwm, + ResolutionFunction, Model, ModelCollection, ) diff --git a/src/easyreflectometry/experiment/model.py b/src/easyreflectometry/experiment/model.py index 3bfd0f11..4994dbab 100644 --- a/src/easyreflectometry/experiment/model.py +++ b/src/easyreflectometry/experiment/model.py @@ -3,7 +3,6 @@ __author__ = 'github.com/arm61' from numbers import Number -from typing import Callable from typing import Union import numpy as np @@ -11,14 +10,14 @@ from easyscience.Objects.ObjectClasses import BaseObj from easyscience.Objects.ObjectClasses import Parameter -from easyreflectometry.experiment.resolution_functions import is_percentage_fhwm_resolution_function from easyreflectometry.parameter_utils import get_as_parameter from easyreflectometry.sample import BaseAssembly from easyreflectometry.sample import Layer from easyreflectometry.sample import LayerCollection from easyreflectometry.sample import Sample -from .resolution_functions import percentage_fhwm_resolution_function +from .resolution_functions import PercentageFhwm +from .resolution_functions import ResolutionFunction DEFAULTS = { 'scale': { @@ -59,7 +58,7 @@ def __init__( sample: Union[Sample, None] = None, scale: Union[Parameter, Number, None] = None, background: Union[Parameter, Number, None] = None, - resolution_function: Union[Callable[[np.array], float], None] = None, + resolution_function: Union[ResolutionFunction, None] = None, name: str = 'EasyModel', interface=None, ): @@ -69,7 +68,7 @@ def __init__( :param scale: Scaling factor of profile. :param background: Linear background magnitude. :param name: Name of the model, defaults to 'EasyModel'. - :param resolution_function: Resolution function, defaults to percentage_fhwm_resolution_function. + :param resolution_function: Resolution function, defaults to PercentageFhwm. :param interface: Calculator interface, defaults to `None`. """ @@ -77,7 +76,7 @@ def __init__( if sample is None: sample = Sample(interface=interface) if resolution_function is None: - resolution_function = percentage_fhwm_resolution_function(DEFAULTS['resolution']['value']) + resolution_function = PercentageFhwm(DEFAULTS['resolution']['value']) scale = get_as_parameter('scale', scale, DEFAULTS) background = get_as_parameter('background', background, DEFAULTS) @@ -88,8 +87,6 @@ def __init__( scale=scale, background=background, ) - if not callable(resolution_function): - raise ValueError('Resolution function must be a callable.') self.resolution_function = resolution_function # Must be set after resolution function self.interface = interface @@ -140,12 +137,12 @@ def remove_item(self, idx: int) -> None: del self.sample[idx] @property - def resolution_function(self) -> Callable[[np.array], np.array]: + def resolution_function(self) -> ResolutionFunction: """Return the resolution function.""" return self._resolution_function @resolution_function.setter - def resolution_function(self, resolution_function: Callable[[np.array], np.array]) -> None: + def resolution_function(self, resolution_function: ResolutionFunction) -> None: """Set the resolution function for the model.""" self._resolution_function = resolution_function if self.interface is not None: @@ -176,8 +173,8 @@ def uid(self) -> int: @property def _dict_repr(self) -> dict[str, dict[str, str]]: """A simplified dict representation.""" - if is_percentage_fhwm_resolution_function(self._resolution_function): - resolution_value = self._resolution_function([0])[0] + if isinstance(self._resolution_function, PercentageFhwm): + resolution_value = self._resolution_function.as_dict()['constant'] resolution = f'{resolution_value} %' else: resolution = 'function of Q' @@ -205,6 +202,7 @@ def as_dict(self, skip: list = None) -> dict: skip = [] this_dict = super().as_dict(skip=skip) this_dict['sample'] = self.sample.as_dict() + this_dict['resolution_function'] = self.resolution_function.as_dict() return this_dict @classmethod @@ -220,5 +218,5 @@ def from_dict(cls, data: dict) -> Model: # Ensure that the sample is also converted # TODO Should probably be handled in easyscience model.sample = model.sample.__class__.from_dict(data['sample']) - + model.resolution_function = ResolutionFunction.from_dict(data['resolution_function']) return model diff --git a/src/easyreflectometry/experiment/resolution_functions.py b/src/easyreflectometry/experiment/resolution_functions.py index ce7598bf..e6f22156 100644 --- a/src/easyreflectometry/experiment/resolution_functions.py +++ b/src/easyreflectometry/experiment/resolution_functions.py @@ -5,7 +5,11 @@ FWHM = 2.35 * sigma [2 * np.sqrt(2 * np.log(2)) * sigma]. """ -from typing import Callable +from __future__ import annotations + +from abc import abstractmethod + +# from typing import Callable from typing import Union import numpy as np @@ -13,39 +17,80 @@ DEFAULT_RESOLUTION_FWHM_PERCENTAGE = 5.0 -def percentage_fhwm_resolution_function(constant: float) -> Callable[[np.array], np.array]: - """Create a resolution function that is constant across the q range. +class ResolutionFunction: + @abstractmethod + def smearing(q: Union[np.array, float]) -> np.array: ... + + @abstractmethod + def as_dict() -> dict: ... + + @classmethod + def from_dict(cls, data: dict) -> ResolutionFunction: + if data['smearing'] == 'PercentageFhwm': + return PercentageFhwm(data['constant']) + if data['smearing'] == 'LinearSpline': + return LinearSpline(data['q_data_points'], data['fwhm_values']) + raise ValueError('Unknown resolution function type') + + +class PercentageFhwm: + def __init__(self, constant: Union[None, float] = None): + if constant is None: + constant = DEFAULT_RESOLUTION_FWHM_PERCENTAGE + self.constant = constant + + def smearing(self, q: Union[np.array, float]) -> np.array: + return np.ones(np.array(q).size) * self.constant + + def as_dict(self) -> dict: + return {'smearing': 'PercentageFhwm', 'constant': self.constant} + + +class LinearSpline: + def __init__(self, q_data_points: np.array, fwhm_values: np.array): + self.q_data_points = q_data_points + self.fwhm_values = fwhm_values + + def smearing(self, q: Union[np.array, float]) -> np.array: + return np.interp(q, self.q_data_points, self.fwhm_values) + + def as_dict(self) -> dict: + return {'smearing': 'LinearSpline', 'q_data_points': self.q_data_points, 'fwhm_values': self.fwhm_values} + + +# def percentage_fhwm_resolution_function(constant: float) -> Callable[[np.array], np.array]: +# """Create a resolution function that is constant across the q range. - :param constant: The constant resolution value. - """ +# :param constant: The constant resolution value. +# """ - def _constant(q: Union[np.array, float]) -> np.array: - """Function that calculates the resolution at a given q value. +# def _constant(q: Union[np.array, float]) -> np.array: +# """Function that calculates the resolution at a given q value. - The function uses the data points from the encapsulating function and produces a linearly interpolated between them. - """ - return np.ones(np.array(q).size) * constant +# The function uses the data points from the encapsulating function and produces a linearly interpolated between them. +# """ +# return np.ones(np.array(q).size) * constant - return _constant +# return _constant -def linear_spline_resolution_function(q_data_points: np.array, fwhm_values: np.array) -> Callable[[np.array], np.array]: - """Create a resolution function that is linearly interpolated between given data points. +# def linear_spline_resolution_function(q_data_points: np.array, fwhm_values: np.array) -> Callable[[np.array], np.array]: +# """Create a resolution function that is linearly interpolated between given data points. - :param q_data_points: The q values at which the resolution is defined. - :param fwhm_values: The resolution values at the given q values. - """ +# :param q_data_points: The q values at which the resolution is defined. +# :param fwhm_values: The resolution values at the given q values. +# """ - def _linear(q: np.array) -> np.array: - """Function that calculates the resolution at a given q value. +# def _linear(q: np.array) -> np.array: +# """Function that calculates the resolution at a given q value. - The function uses the data points from the encapsulating function and produces a linearly interpolated between them. - """ - return np.interp(q, q_data_points, fwhm_values) +# The function uses the data points from the encapsulating function and produces a linearly interpolated between them. +# """ +# return np.interp(q, q_data_points, fwhm_values) - return _linear +# return _linear -def is_percentage_fhwm_resolution_function(resolution_function: Callable[[np.array], np.array]) -> bool: - """Check if the resolution function is a constant.""" - return 'constant' in resolution_function.__name__ +# def is_percentage_fhwm_resolution_function(resolution_function: Callable[[np.array], np.array]) -> bool: +# """Check if the resolution function is a constant.""" +# return 'constant' in resolution_function.__name__ diff --git a/tests/calculators/refnx/test_refnx_wrapper.py b/tests/calculators/refnx/test_refnx_wrapper.py index 8b4fc63b..3a4bbd04 100644 --- a/tests/calculators/refnx/test_refnx_wrapper.py +++ b/tests/calculators/refnx/test_refnx_wrapper.py @@ -10,8 +10,8 @@ import numpy as np from easyreflectometry.calculators.refnx.wrapper import RefnxWrapper -from easyreflectometry.experiment import linear_spline_resolution_function -from easyreflectometry.experiment import percentage_fhwm_resolution_function +from easyreflectometry.experiment import LinearSpline +from easyreflectometry.experiment import PercentageFhwm from numpy.testing import assert_allclose from numpy.testing import assert_almost_equal from numpy.testing import assert_equal @@ -318,7 +318,7 @@ def test_calculate_github_test0(self): p.add_item('Item2', 'MyModel') p.add_item('Item3', 'MyModel') p.add_item('Item4', 'MyModel') - p.set_resolution_function(percentage_fhwm_resolution_function(0)) + p.set_resolution_function(PercentageFhwm(0)) p.update_model('MyModel', bkg=0) q = np.array( [ @@ -356,7 +356,7 @@ def test_calculate_github_test2(self): p.add_layer_to_item('Layer2', 'Item2') p.add_item('Item1', 'MyModel') p.add_item('Item2', 'MyModel') - p.set_resolution_function(percentage_fhwm_resolution_function(0)) + p.set_resolution_function(PercentageFhwm(0)) p.update_model('MyModel', bkg=0) q = np.array( [ @@ -410,7 +410,7 @@ def test_calculate_github_test4_constant_resolution(self): p.add_item('Item2', 'MyModel') p.add_item('Item3', 'MyModel') p.add_item('Item4', 'MyModel') - p.set_resolution_function(percentage_fhwm_resolution_function(5)) + p.set_resolution_function(PercentageFhwm(5)) p.update_model('MyModel', bkg=0) assert_allclose(p.calculate(test4_dat[:, 0], 'MyModel'), test4_dat[:, 1], rtol=0.03) @@ -450,7 +450,7 @@ def test_calculate_github_test4_spline_resolution(self): p.add_item('Item4', 'MyModel') p.update_model('MyModel', bkg=0) sigma_to_fhwm = 2.355 - p.set_resolution_function(linear_spline_resolution_function(test4_dat[:, 0], sigma_to_fhwm * test4_dat[:, 3])) + p.set_resolution_function(LinearSpline(test4_dat[:, 0], sigma_to_fhwm * test4_dat[:, 3])) assert_allclose(p.calculate(test4_dat[:, 0], 'MyModel'), test4_dat[:, 1], rtol=0.03) diff --git a/tests/experiment/test_model.py b/tests/experiment/test_model.py index c55ee969..ea99a69a 100644 --- a/tests/experiment/test_model.py +++ b/tests/experiment/test_model.py @@ -12,9 +12,9 @@ import numpy as np import pytest from easyreflectometry.calculators import CalculatorFactory +from easyreflectometry.experiment import LinearSpline from easyreflectometry.experiment import Model -from easyreflectometry.experiment import linear_spline_resolution_function -from easyreflectometry.experiment import percentage_fhwm_resolution_function +from easyreflectometry.experiment import PercentageFhwm from easyreflectometry.sample import Layer from easyreflectometry.sample import LayerCollection from easyreflectometry.sample import Material @@ -43,8 +43,8 @@ def test_default(self): assert_equal(p.background.min, 0.0) assert_equal(p.background.max, np.Inf) assert_equal(p.background.fixed, True) - assert p._resolution_function([1]) == 5.0 - assert p._resolution_function([100]) == 5.0 + assert p._resolution_function.smearing([1]) == 5.0 + assert p._resolution_function.smearing([100]) == 5.0 def test_from_pars(self): m1 = Material(6.908, -0.278, 'Boron') @@ -56,7 +56,7 @@ def test_from_pars(self): o1 = RepeatingMultilayer(ls1, 2.0, 'twoLayerItem1') o2 = RepeatingMultilayer(ls2, 1.0, 'oneLayerItem2') d = Sample(o1, o2, name='myModel') - resolution_function = percentage_fhwm_resolution_function(2.0) + resolution_function = PercentageFhwm(2.0) mod = Model( sample=d, scale=2, @@ -79,8 +79,8 @@ def test_from_pars(self): assert_equal(mod.background.min, 0.0) assert_equal(mod.background.max, np.Inf) assert_equal(mod.background.fixed, True) - assert mod._resolution_function([1]) == 2.0 - assert mod._resolution_function([100]) == 2.0 + assert mod._resolution_function.smearing([1]) == 2.0 + assert mod._resolution_function.smearing([100]) == 2.0 def test_add_item(self): m1 = Material(6.908, -0.278, 'Boron') @@ -94,7 +94,7 @@ def test_add_item(self): surfactant = SurfactantLayer() multilayer = Multilayer() d = Sample(o1, name='myModel') - resolution_function = percentage_fhwm_resolution_function(2.0) + resolution_function = PercentageFhwm(2.0) mod = Model(d, 2, 1e-5, resolution_function, 'newModel') assert_equal(len(mod.sample), 1) mod.add_item(o2) @@ -125,7 +125,7 @@ def test_add_item_with_interface_refnx(self): o1 = RepeatingMultilayer(ls1, 2.0, 'twoLayerItem1') o2 = RepeatingMultilayer(ls2, 1.0, 'oneLayerItem2') d = Sample(o1, name='myModel') - resolution_function = percentage_fhwm_resolution_function(2.0) + resolution_function = PercentageFhwm(2.0) mod = Model(d, 2, 1e-5, resolution_function, 'newModel', interface=interface) assert_equal(len(mod.interface()._wrapper.storage['item']), 1) assert_equal(len(mod.interface()._wrapper.storage['layer']), 2) @@ -145,7 +145,7 @@ def test_add_item_with_interface_refl1d(self): o1 = RepeatingMultilayer(ls1, 2.0, 'twoLayerItem1') o2 = RepeatingMultilayer(ls2, 1.0, 'oneLayerItem2') d = Sample(o1, name='myModel') - resolution_function = percentage_fhwm_resolution_function(2.0) + resolution_function = PercentageFhwm(2.0) mod = Model(d, 2, 1e-5, resolution_function, 'newModel', interface=interface) assert_equal(len(mod.interface()._wrapper.storage['item']), 1) assert_equal(len(mod.interface()._wrapper.storage['layer']), 2) @@ -182,7 +182,7 @@ def test_duplicate_item(self): o1 = RepeatingMultilayer(ls1, 2.0, 'twoLayerItem1') o2 = RepeatingMultilayer(ls2, 1.0, 'oneLayerItem2') d = Sample(o1, name='myModel') - resolution_function = percentage_fhwm_resolution_function(2.0) + resolution_function = PercentageFhwm(2.0) mod = Model(d, 2, 1e-5, resolution_function, 'newModel') assert_equal(len(mod.sample), 1) mod.add_item(o2) @@ -203,7 +203,7 @@ def test_duplicate_item_with_interface_refnx(self): o1 = RepeatingMultilayer(ls1, 2.0, 'twoLayerItem1') o2 = RepeatingMultilayer(ls2, 1.0, 'oneLayerItem2') d = Sample(o1, name='myModel') - resolution_function = percentage_fhwm_resolution_function(2.0) + resolution_function = PercentageFhwm(2.0) mod = Model(d, 2, 1e-5, resolution_function, 'newModel', interface=interface) assert_equal(len(mod.interface()._wrapper.storage['item']), 1) mod.add_item(o2) @@ -223,7 +223,7 @@ def test_duplicate_item_with_interface_refl1d(self): o1 = RepeatingMultilayer(ls1, 2.0, 'twoLayerItem1') o2 = RepeatingMultilayer(ls2, 1.0, 'oneLayerItem2') d = Sample(o1, name='myModel') - resolution_function = percentage_fhwm_resolution_function(2.0) + resolution_function = PercentageFhwm(2.0) mod = Model(d, 2, 1e-5, resolution_function, 'newModel', interface=interface) assert_equal(len(mod.interface()._wrapper.storage['item']), 1) mod.add_item(o2) @@ -260,7 +260,7 @@ def test_remove_item(self): o1 = RepeatingMultilayer(ls1, 2.0, 'twoLayerItem1') o2 = RepeatingMultilayer(ls2, 1.0, 'oneLayerItem2') d = Sample(o1, name='myModel') - resolution_function = percentage_fhwm_resolution_function(2.0) + resolution_function = PercentageFhwm(2.0) mod = Model(d, 2, 1e-5, resolution_function, 'newModel') assert_equal(len(mod.sample), 1) mod.add_item(o2) @@ -279,7 +279,7 @@ def test_remove_item_with_interface_refnx(self): o1 = RepeatingMultilayer(ls1, 2.0, 'twoLayerItem1') o2 = RepeatingMultilayer(ls2, 1.0, 'oneLayerItem2') d = Sample(o1, name='myModel') - resolution_function = percentage_fhwm_resolution_function(2.0) + resolution_function = PercentageFhwm(2.0) mod = Model(d, 2, 1e-5, resolution_function, 'newModel', interface=interface) assert_equal(len(mod.interface()._wrapper.storage['item']), 1) assert_equal(len(mod.interface()._wrapper.storage['layer']), 2) @@ -302,7 +302,7 @@ def test_remove_item_with_interface_refl1d(self): o1 = RepeatingMultilayer(ls1, 2.0, 'twoLayerItem1') o2 = RepeatingMultilayer(ls2, 1.0, 'oneLayerItem2') d = Sample(o1, name='myModel') - resolution_function = percentage_fhwm_resolution_function(2.0) + resolution_function = PercentageFhwm(2.0) mod = Model(d, 2, 1e-5, resolution_function, 'newModel', interface=interface) assert_equal(len(mod.interface()._wrapper.storage['item']), 1) assert_equal(len(mod.interface()._wrapper.storage['layer']), 2) @@ -384,7 +384,7 @@ def test_repr(self): ) def test_repr_resolution_function(self): - resolution_function = linear_spline_resolution_function([0, 10], [0, 10]) + resolution_function = LinearSpline([0, 10], [0, 10]) model = Model() model.resolution_function = resolution_function assert ( @@ -394,7 +394,7 @@ def test_repr_resolution_function(self): def test_dict_round_trip(self): # When - resolution_function = linear_spline_resolution_function([0, 10], [0, 10]) + resolution_function = LinearSpline([0, 10], [0, 10]) interface = CalculatorFactory() model = Model(interface=interface) model.resolution_function = resolution_function @@ -410,5 +410,5 @@ def test_dict_round_trip(self): model_from_dict = Model.from_dict(src_dict) # Expect - assert model.as_data_dict() == model_from_dict.as_data_dict() - assert model._resolution_function(5.5) == model_from_dict._resolution_function(5.5) + assert model.as_data_dict(skip=['resolution_function']) == model_from_dict.as_data_dict(skip=['resolution_function']) + assert model._resolution_function.smearing(5.5) == model_from_dict._resolution_function.smearing(5.5) diff --git a/tests/experiment/test_resolution_functions.py b/tests/experiment/test_resolution_functions.py index b8ccaf29..e9e05a05 100644 --- a/tests/experiment/test_resolution_functions.py +++ b/tests/experiment/test_resolution_functions.py @@ -1,17 +1,75 @@ import numpy as np -from easyreflectometry.experiment.resolution_functions import linear_spline_resolution_function -from easyreflectometry.experiment.resolution_functions import percentage_fhwm_resolution_function +from easyreflectometry.experiment.resolution_functions import DEFAULT_RESOLUTION_FWHM_PERCENTAGE +from easyreflectometry.experiment.resolution_functions import LinearSpline +from easyreflectometry.experiment.resolution_functions import PercentageFhwm +# from easyreflectometry.experiment.resolution_functions import linear_spline_resolution_function +# from easyreflectometry.experiment.resolution_functions import percentage_fhwm_resolution_function -def test_percentage_fhwm_resolution_function(): - resolution_function = percentage_fhwm_resolution_function(5) - assert np.all(resolution_function([0, 2.5]) == [5, 5]) - assert resolution_function([-100]) == 5 - assert resolution_function([100]) == 5 +# def test_percentage_fhwm_resolution_function(): +# # When Then +# resolution_function = percentage_fhwm_resolution_function(5) -def test_linear_spline_resolution_function(): - resolution_function = linear_spline_resolution_function([0, 10], [5, 10]) - assert np.all(resolution_function([0, 2.5]) == [5, 6.25]) - assert resolution_function([-100]) == 5 - assert resolution_function([100]) == 10 +# # Expect +# assert np.all(resolution_function([0, 2.5]) == [5, 5]) +# assert resolution_function([-100]) == 5 +# assert resolution_function([100]) == 5 + + +# def test_linear_spline_resolution_function(): +# # When Then +# resolution_function = linear_spline_resolution_function([0, 10], [5, 10]) + +# # Expect +# assert np.all(resolution_function([0, 2.5]) == [5, 6.25]) +# assert resolution_function([-100]) == 5 +# assert resolution_function([100]) == 10 + + +# def test_percentage_fhwm_resolution(): +# # When +# resolution_function = PercentageFhwm(1.0) + +# # Then Expect +# assert np.all(resolution_function.smearing([0, 2.5]) == [1.0, 1.0]) +# assert resolution_function.smearing([-100]) == 1.0 +# assert resolution_function.smearing([100]) == 1.0 + + +def test_percentage_fhwm_resolution_as_dict(): + # When + resolution_function = PercentageFhwm(1.0) + + # Then Expect + resolution_function.as_dict() == {'smearing': 'PercentageFhwm', 'constant': 1.0} + + +def test_percentage_fhwm_resolution_none(): + # When + resolution_function = PercentageFhwm() + + # Then Expect + assert np.all( + resolution_function.smearing([0, 2.5]) == [DEFAULT_RESOLUTION_FWHM_PERCENTAGE, DEFAULT_RESOLUTION_FWHM_PERCENTAGE] + ) + assert resolution_function.smearing([-100]) == DEFAULT_RESOLUTION_FWHM_PERCENTAGE + assert resolution_function.smearing([100]) == DEFAULT_RESOLUTION_FWHM_PERCENTAGE + + +def test_linear_spline_resolution(): + # When + resolution_function = LinearSpline(q_data_points=[0, 10], fwhm_values=[5, 10]) + + # Then Expect + assert np.all(resolution_function.smearing([0, 2.5]) == [5, 6.25]) + assert resolution_function.smearing([-100]) == 5 + assert resolution_function.smearing([100]) == 10 + + +def test_linear_spline_resolution_as_dict(): + # When + resolution_function = LinearSpline(q_data_points=[0, 10], fwhm_values=[5, 10]) + + # Then Expect + resolution_function.as_dict() == {'smearing': 'LinearSpline', 'q_data_points': [0, 10], 'fwhm_values': [5, 10]} diff --git a/tests/test_fitting.py b/tests/test_fitting.py index 3b1fddec..d92de5fd 100644 --- a/tests/test_fitting.py +++ b/tests/test_fitting.py @@ -7,13 +7,13 @@ from easyreflectometry.calculators import CalculatorFactory from easyreflectometry.data import load from easyreflectometry.experiment import Model -from easyreflectometry.experiment import percentage_fhwm_resolution_function +from easyreflectometry.experiment import PercentageFhwm from easyreflectometry.fitting import Fitter from easyreflectometry.sample import Layer from easyreflectometry.sample import Material from easyreflectometry.sample import Sample -PATH_STATIC = os.path.join(os.path.dirname(easyreflectometry.__file__), '..', '..', 'tests' , '_static') +PATH_STATIC = os.path.join(os.path.dirname(easyreflectometry.__file__), '..', '..', 'tests', '_static') class TestFitting(unittest.TestCase): @@ -35,7 +35,7 @@ def test_fitting(self): superphase, name='Film Structure', ) - resolution_function = percentage_fhwm_resolution_function(0.02) + resolution_function = PercentageFhwm(0.02) model = Model(sample, 1, 1e-6, resolution_function, 'Film Model') # Thicknesses sio2_layer.thickness.bounds = (15, 50) From 54df42fab984af844d54b25c564d7cc514991b7f Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Wed, 15 May 2024 09:44:24 +0200 Subject: [PATCH 2/7] code cleaning and more tests --- .../experiment/resolution_functions.py | 40 ------- tests/experiment/test_resolution_functions.py | 107 +++++++++--------- 2 files changed, 54 insertions(+), 93 deletions(-) diff --git a/src/easyreflectometry/experiment/resolution_functions.py b/src/easyreflectometry/experiment/resolution_functions.py index e6f22156..f6bcc56b 100644 --- a/src/easyreflectometry/experiment/resolution_functions.py +++ b/src/easyreflectometry/experiment/resolution_functions.py @@ -8,8 +8,6 @@ from __future__ import annotations from abc import abstractmethod - -# from typing import Callable from typing import Union import numpy as np @@ -56,41 +54,3 @@ def smearing(self, q: Union[np.array, float]) -> np.array: def as_dict(self) -> dict: return {'smearing': 'LinearSpline', 'q_data_points': self.q_data_points, 'fwhm_values': self.fwhm_values} - - -# def percentage_fhwm_resolution_function(constant: float) -> Callable[[np.array], np.array]: -# """Create a resolution function that is constant across the q range. - -# :param constant: The constant resolution value. -# """ - -# def _constant(q: Union[np.array, float]) -> np.array: -# """Function that calculates the resolution at a given q value. - -# The function uses the data points from the encapsulating function and produces a linearly interpolated between them. -# """ -# return np.ones(np.array(q).size) * constant - -# return _constant - - -# def linear_spline_resolution_function(q_data_points: np.array, fwhm_values: np.array) -> Callable[[np.array], np.array]: -# """Create a resolution function that is linearly interpolated between given data points. - -# :param q_data_points: The q values at which the resolution is defined. -# :param fwhm_values: The resolution values at the given q values. -# """ - -# def _linear(q: np.array) -> np.array: -# """Function that calculates the resolution at a given q value. - -# The function uses the data points from the encapsulating function and produces a linearly interpolated between them. -# """ -# return np.interp(q, q_data_points, fwhm_values) - -# return _linear - - -# def is_percentage_fhwm_resolution_function(resolution_function: Callable[[np.array], np.array]) -> bool: -# """Check if the resolution function is a constant.""" -# return 'constant' in resolution_function.__name__ diff --git a/tests/experiment/test_resolution_functions.py b/tests/experiment/test_resolution_functions.py index e9e05a05..a34f95b4 100644 --- a/tests/experiment/test_resolution_functions.py +++ b/tests/experiment/test_resolution_functions.py @@ -1,75 +1,76 @@ +import unittest + import numpy as np from easyreflectometry.experiment.resolution_functions import DEFAULT_RESOLUTION_FWHM_PERCENTAGE from easyreflectometry.experiment.resolution_functions import LinearSpline from easyreflectometry.experiment.resolution_functions import PercentageFhwm - -# from easyreflectometry.experiment.resolution_functions import linear_spline_resolution_function -# from easyreflectometry.experiment.resolution_functions import percentage_fhwm_resolution_function - - -# def test_percentage_fhwm_resolution_function(): -# # When Then -# resolution_function = percentage_fhwm_resolution_function(5) - -# # Expect -# assert np.all(resolution_function([0, 2.5]) == [5, 5]) -# assert resolution_function([-100]) == 5 -# assert resolution_function([100]) == 5 +from easyreflectometry.experiment.resolution_functions import ResolutionFunction -# def test_linear_spline_resolution_function(): -# # When Then -# resolution_function = linear_spline_resolution_function([0, 10], [5, 10]) +class TestPercentageFhwm(unittest.TestCase): + def test_constructor(self): + # When + resolution_function = PercentageFhwm(1.0) -# # Expect -# assert np.all(resolution_function([0, 2.5]) == [5, 6.25]) -# assert resolution_function([-100]) == 5 -# assert resolution_function([100]) == 10 + # Then Expect + assert np.all(resolution_function.smearing([0, 2.5]) == np.array([1.0, 1.0])) + assert resolution_function.smearing([-100]) == np.array([1.0]) + assert resolution_function.smearing([100]) == np.array([1.0]) + def test_constructor_none(self): + # When + resolution_function = PercentageFhwm() -# def test_percentage_fhwm_resolution(): -# # When -# resolution_function = PercentageFhwm(1.0) + # Then Expect + assert np.all( + resolution_function.smearing([0, 2.5]) == [DEFAULT_RESOLUTION_FWHM_PERCENTAGE, DEFAULT_RESOLUTION_FWHM_PERCENTAGE] + ) + assert resolution_function.smearing([-100]) == DEFAULT_RESOLUTION_FWHM_PERCENTAGE + assert resolution_function.smearing([100]) == DEFAULT_RESOLUTION_FWHM_PERCENTAGE -# # Then Expect -# assert np.all(resolution_function.smearing([0, 2.5]) == [1.0, 1.0]) -# assert resolution_function.smearing([-100]) == 1.0 -# assert resolution_function.smearing([100]) == 1.0 + def test_as_dict(self): + # When + resolution_function = PercentageFhwm(1.0) + # Then Expect + resolution_function.as_dict() == {'smearing': 'PercentageFhwm', 'constant': 1.0} -def test_percentage_fhwm_resolution_as_dict(): - # When - resolution_function = PercentageFhwm(1.0) + def test_dict_round_trip(self): + # When + expected_resolution_function = PercentageFhwm(1.0) + res_dict = expected_resolution_function.as_dict() - # Then Expect - resolution_function.as_dict() == {'smearing': 'PercentageFhwm', 'constant': 1.0} + # Then + resolution_function = ResolutionFunction.from_dict(res_dict) + # Expect + assert all(resolution_function.smearing([0, 2.5]) == expected_resolution_function.smearing([0, 2.5])) -def test_percentage_fhwm_resolution_none(): - # When - resolution_function = PercentageFhwm() - # Then Expect - assert np.all( - resolution_function.smearing([0, 2.5]) == [DEFAULT_RESOLUTION_FWHM_PERCENTAGE, DEFAULT_RESOLUTION_FWHM_PERCENTAGE] - ) - assert resolution_function.smearing([-100]) == DEFAULT_RESOLUTION_FWHM_PERCENTAGE - assert resolution_function.smearing([100]) == DEFAULT_RESOLUTION_FWHM_PERCENTAGE +class TestLinearSpline(unittest.TestCase): + def test_constructor(self): + # When + resolution_function = LinearSpline(q_data_points=[0, 10], fwhm_values=[5, 10]) + # Then Expect + assert np.all(resolution_function.smearing([0, 2.5]) == np.array([5, 6.25])) + assert resolution_function.smearing([-100]) == np.array([5.0]) + assert resolution_function.smearing([100]) == np.array([10.0]) -def test_linear_spline_resolution(): - # When - resolution_function = LinearSpline(q_data_points=[0, 10], fwhm_values=[5, 10]) + def test_as_dict(self): + # When + resolution_function = LinearSpline(q_data_points=[0, 10], fwhm_values=[5, 10]) - # Then Expect - assert np.all(resolution_function.smearing([0, 2.5]) == [5, 6.25]) - assert resolution_function.smearing([-100]) == 5 - assert resolution_function.smearing([100]) == 10 + # Then Expect + resolution_function.as_dict() == {'smearing': 'LinearSpline', 'q_data_points': [0, 10], 'fwhm_values': [5, 10]} + def test_dict_round_trip(self): + # When + expected_resolution_function = LinearSpline(q_data_points=[0, 10], fwhm_values=[5, 10]) + res_dict = expected_resolution_function.as_dict() -def test_linear_spline_resolution_as_dict(): - # When - resolution_function = LinearSpline(q_data_points=[0, 10], fwhm_values=[5, 10]) + # Then + resolution_function = ResolutionFunction.from_dict(res_dict) - # Then Expect - resolution_function.as_dict() == {'smearing': 'LinearSpline', 'q_data_points': [0, 10], 'fwhm_values': [5, 10]} + # Expect + assert all(resolution_function.smearing([0, 2.5]) == expected_resolution_function.smearing([0, 2.5])) From 2e65a011c98d227c61c4dd5e81f82ee43d83e2d7 Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Wed, 15 May 2024 14:27:23 +0200 Subject: [PATCH 3/7] ability to serialize model_collection --- src/easyreflectometry/experiment/model.py | 2 +- .../experiment/model_collection.py | 2 +- .../sample/base_element_collection.py | 14 ++++ src/easyreflectometry/sample/sample.py | 2 +- tests/experiment/test_model_collection.py | 72 +++++++++++++++++++ 5 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 tests/experiment/test_model_collection.py diff --git a/src/easyreflectometry/experiment/model.py b/src/easyreflectometry/experiment/model.py index 4994dbab..e9f1dd10 100644 --- a/src/easyreflectometry/experiment/model.py +++ b/src/easyreflectometry/experiment/model.py @@ -201,7 +201,7 @@ def as_dict(self, skip: list = None) -> dict: if skip is None: skip = [] this_dict = super().as_dict(skip=skip) - this_dict['sample'] = self.sample.as_dict() + this_dict['sample'] = self.sample.as_dict(skip=skip) this_dict['resolution_function'] = self.resolution_function.as_dict() return this_dict diff --git a/src/easyreflectometry/experiment/model_collection.py b/src/easyreflectometry/experiment/model_collection.py index fb0f8b04..351446d9 100644 --- a/src/easyreflectometry/experiment/model_collection.py +++ b/src/easyreflectometry/experiment/model_collection.py @@ -19,7 +19,7 @@ def __init__( interface=None, **kwargs, ): - if models is None: + if models == (): models = [Model(interface=interface) for _ in range(SIZE_DEFAULT_COLLECTION)] super().__init__(name, interface, *models, **kwargs) self.interface = interface diff --git a/src/easyreflectometry/sample/base_element_collection.py b/src/easyreflectometry/sample/base_element_collection.py index d55456b1..d59cc9cc 100644 --- a/src/easyreflectometry/sample/base_element_collection.py +++ b/src/easyreflectometry/sample/base_element_collection.py @@ -1,4 +1,6 @@ from typing import Any +from typing import List +from typing import Optional import yaml from easyscience.Objects.Groups import BaseCollection @@ -48,6 +50,18 @@ def _dict_repr(self) -> dict: """ return {self.name: [i._dict_repr for i in self]} + def as_dict(self, skip: Optional[List[str]] = None) -> dict: + """ + Create a dictionary representation of the collection. + + :return: A dictionary representation of the collection + """ + this_dict = super().as_dict(skip=skip) + this_dict['data'] = [] + for collection_element in self: + this_dict['data'].append(collection_element.as_dict(skip=skip)) + return this_dict + @classmethod def from_dict(cls, data: dict) -> Any: """ diff --git a/src/easyreflectometry/sample/sample.py b/src/easyreflectometry/sample/sample.py index 7b695341..7dec0c94 100644 --- a/src/easyreflectometry/sample/sample.py +++ b/src/easyreflectometry/sample/sample.py @@ -69,7 +69,7 @@ def as_dict(self, skip: list = None) -> dict: skip = [] this_dict = super().as_dict(skip=skip) for i, layer in enumerate(self.data): - this_dict['data'][i] = layer.as_dict() + this_dict['data'][i] = layer.as_dict(skip=skip) return this_dict @classmethod diff --git a/tests/experiment/test_model_collection.py b/tests/experiment/test_model_collection.py new file mode 100644 index 00000000..4b89246a --- /dev/null +++ b/tests/experiment/test_model_collection.py @@ -0,0 +1,72 @@ +import unittest + +from easyreflectometry.experiment.model import Model +from easyreflectometry.experiment.model_collection import ModelCollection + + +class TestModelCollection(unittest.TestCase): + def test_default(self): + # When Then + collection = ModelCollection() + + # Expect + assert collection.name == 'EasyModels' + assert collection.interface is None + assert len(collection) == 2 + assert collection[0].name == 'EasyModel' + assert collection[1].name == 'EasyModel' + + def test_from_pars(self): + # When + model_1 = Model(name='Model1') + model_2 = Model(name='Model2') + model_3 = Model(name='Model3') + + # Then + collection = ModelCollection(model_1, model_2, model_3) + + # Expect + assert collection.name == 'EasyModels' + assert collection.interface is None + assert len(collection) == 3 + assert collection[0].name == 'Model1' + assert collection[1].name == 'Model2' + assert collection[2].name == 'Model3' + + def test_add_model(self): + # When + model_1 = Model(name='Model1') + model_2 = Model(name='Model2') + + # Then + collection = ModelCollection(model_1) + collection.add_model(model_2) + + # Expect + assert len(collection) == 2 + assert collection[0].name == 'Model1' + assert collection[1].name == 'Model2' + + def test_delete_model(self): + # When + model_1 = Model(name='Model1') + model_2 = Model(name='Model2') + + # Then + collection = ModelCollection(model_1, model_2) + collection.remove_model(0) + + # Expect + assert len(collection) == 1 + assert collection[0].name == 'Model2' + + def test_as_dict(self): + # When + model_1 = Model(name='Model1') + collection = ModelCollection(model_1) + + # Then + dict_repr = collection.as_dict() + + # Expect + assert dict_repr['data'][0]['resolution_function'] == {'smearing': 'PercentageFhwm', 'constant': 5.0} From e6ae9233a3f98ed31b58f90e2bce9afc0b0ae3c2 Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Thu, 16 May 2024 10:14:23 +0200 Subject: [PATCH 4/7] more serialization --- src/easyreflectometry/experiment/model.py | 17 +++++++++------- .../experiment/model_collection.py | 19 ++++++++++++++++++ tests/experiment/test_model_collection.py | 20 +++++++++++++++++++ .../materials/test_material_collection.py | 6 ++++++ 4 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/easyreflectometry/experiment/model.py b/src/easyreflectometry/experiment/model.py index e9f1dd10..22d9d0db 100644 --- a/src/easyreflectometry/experiment/model.py +++ b/src/easyreflectometry/experiment/model.py @@ -206,17 +206,20 @@ def as_dict(self, skip: list = None) -> dict: return this_dict @classmethod - def from_dict(cls, data: dict) -> Model: + def from_dict(cls, this_dict: dict) -> Model: """ Create a Model from a dictionary. - :param data: dictionary of the Model + :param this_dict: dictionary of the Model :return: Model """ - model = super().from_dict(data) + resolution_function = ResolutionFunction.from_dict(this_dict['resolution_function']) + del this_dict['resolution_function'] + sample = Sample.from_dict(this_dict['sample']) + del this_dict['sample'] - # Ensure that the sample is also converted - # TODO Should probably be handled in easyscience - model.sample = model.sample.__class__.from_dict(data['sample']) - model.resolution_function = ResolutionFunction.from_dict(data['resolution_function']) + model = super().from_dict(this_dict) + + model.sample = sample + model.resolution_function = resolution_function return model diff --git a/src/easyreflectometry/experiment/model_collection.py b/src/easyreflectometry/experiment/model_collection.py index 351446d9..b248979f 100644 --- a/src/easyreflectometry/experiment/model_collection.py +++ b/src/easyreflectometry/experiment/model_collection.py @@ -1,3 +1,5 @@ +from __future__ import annotations + __author__ = 'github.com/arm61' from typing import Optional @@ -39,3 +41,20 @@ def remove_model(self, idx: int): :param idx: Index of the model to remove """ del self[idx] + + @classmethod + def from_dict(cls, this_dict: dict) -> ModelCollection: + """ + Create an instance of a collection from a dictionary. + + :param data: The dictionary for the collection + :return: An instance of the collection + """ + collection = super().from_dict(this_dict) # type: ModelCollection + + if len(collection) != len(this_dict['data']): + raise ValueError(f"Expected {len(collection)} models, got {len(this_dict['data'])}") + for i, model_data in enumerate(this_dict['data']): + collection[i] = Model.from_dict(model_data) + + return collection diff --git a/tests/experiment/test_model_collection.py b/tests/experiment/test_model_collection.py index 4b89246a..11c3ba71 100644 --- a/tests/experiment/test_model_collection.py +++ b/tests/experiment/test_model_collection.py @@ -70,3 +70,23 @@ def test_as_dict(self): # Expect assert dict_repr['data'][0]['resolution_function'] == {'smearing': 'PercentageFhwm', 'constant': 5.0} + + def test_dict_round_trip(self): + # When + model_1 = Model(name='Model1') + model_2 = Model(name='Model2') + model_3 = Model(name='Model3') + + # Then + collection = ModelCollection(model_1, model_2, model_3) + + src_dict = collection.as_dict() + + # Then + collection_from_dict = ModelCollection.from_dict(src_dict) + + # Expect + assert collection.as_data_dict(skip=['resolution_function', 'interface']) == collection_from_dict.as_data_dict( + skip=['resolution_function', 'interface'] + ) + assert collection[0]._resolution_function.smearing(5.5) == collection_from_dict[0]._resolution_function.smearing(5.5) diff --git a/tests/sample/elements/materials/test_material_collection.py b/tests/sample/elements/materials/test_material_collection.py index 05f309aa..1374dd6e 100644 --- a/tests/sample/elements/materials/test_material_collection.py +++ b/tests/sample/elements/materials/test_material_collection.py @@ -30,6 +30,12 @@ def test_from_pars(self): assert p[0].name == 'Boron' assert p[1].name == 'Potassium' + def test_empty_list(self): + p = MaterialCollection([]) + assert p.name == 'EasyMaterials' + assert p.interface is None + assert len(p) == 0 + def test_dict_repr(self): p = MaterialCollection() assert p._dict_repr == { From 09b1c19d29c9e708ac66c6b0984ba15a40d15a82 Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Fri, 17 May 2024 06:53:09 +0200 Subject: [PATCH 5/7] update docs --- docs/src/conf.py | 1 + .../{_static => fitting}/example.ort | 0 .../{_static => fitting}/polymer_film.png | Bin .../{_static => fitting}/polymer_film.svg | 0 .../tutorials/{ => fitting}/repeating.ipynb | 17 +- .../{_static => fitting}/repeating.png | Bin .../{_static => fitting}/repeating.svg | 0 .../{_static => fitting}/repeating_layers.ort | 0 .../{ => fitting}/simple_fitting.ipynb | 17 +- .../tutorials/{_static => sample}/d70d2o.ort | 0 .../tutorials/{_static => sample}/dspc.png | Bin docs/src/tutorials/sample/example.ort | 448 ++++++++++++++++++ .../{ => sample}/material_solvated.ipynb | 17 +- .../mod_pointwise_two_layer_sample_dq-0.0.ort | 0 .../mod_pointwise_two_layer_sample_dq-1.0.ort | 0 ...mod_pointwise_two_layer_sample_dq-10.0.ort | 0 .../tutorials/{ => sample}/monolayer.ipynb | 14 +- .../{_static => sample}/monolayer.png | Bin .../{_static => sample}/monolayer.svg | 0 .../{ => sample}/multi_contrast.ipynb | 9 +- .../{_static => sample}/multiple.ort | 0 .../{ => sample}/resolution_functions.ipynb | 27 +- .../{_static => sample}/two_layers.png | Bin .../{_static => sample}/two_layers.svg | 0 docs/src/tutorials/tutorials.rst | 12 +- pyproject.toml | 3 +- 26 files changed, 510 insertions(+), 55 deletions(-) rename docs/src/tutorials/{_static => fitting}/example.ort (100%) rename docs/src/tutorials/{_static => fitting}/polymer_film.png (100%) rename docs/src/tutorials/{_static => fitting}/polymer_film.svg (100%) rename docs/src/tutorials/{ => fitting}/repeating.ipynb (93%) rename docs/src/tutorials/{_static => fitting}/repeating.png (100%) rename docs/src/tutorials/{_static => fitting}/repeating.svg (100%) rename docs/src/tutorials/{_static => fitting}/repeating_layers.ort (100%) rename docs/src/tutorials/{ => fitting}/simple_fitting.ipynb (96%) rename docs/src/tutorials/{_static => sample}/d70d2o.ort (100%) rename docs/src/tutorials/{_static => sample}/dspc.png (100%) create mode 100644 docs/src/tutorials/sample/example.ort rename docs/src/tutorials/{ => sample}/material_solvated.ipynb (94%) rename docs/src/tutorials/{_static/resolution => sample}/mod_pointwise_two_layer_sample_dq-0.0.ort (100%) rename docs/src/tutorials/{_static/resolution => sample}/mod_pointwise_two_layer_sample_dq-1.0.ort (100%) rename docs/src/tutorials/{_static/resolution => sample}/mod_pointwise_two_layer_sample_dq-10.0.ort (100%) rename docs/src/tutorials/{ => sample}/monolayer.ipynb (95%) rename docs/src/tutorials/{_static => sample}/monolayer.png (100%) rename docs/src/tutorials/{_static => sample}/monolayer.svg (100%) rename docs/src/tutorials/{ => sample}/multi_contrast.ipynb (98%) rename docs/src/tutorials/{_static => sample}/multiple.ort (100%) rename docs/src/tutorials/{ => sample}/resolution_functions.ipynb (92%) rename docs/src/tutorials/{_static => sample}/two_layers.png (100%) rename docs/src/tutorials/{_static => sample}/two_layers.svg (100%) diff --git a/docs/src/conf.py b/docs/src/conf.py index 6df445ce..36235949 100644 --- a/docs/src/conf.py +++ b/docs/src/conf.py @@ -52,6 +52,7 @@ 'sphinx.ext.imgmath', 'sphinx.ext.mathjax', 'sphinx_autodoc_typehints', + 'sphinx_copybutton', 'nbsphinx', 'myst_parser' ] diff --git a/docs/src/tutorials/_static/example.ort b/docs/src/tutorials/fitting/example.ort similarity index 100% rename from docs/src/tutorials/_static/example.ort rename to docs/src/tutorials/fitting/example.ort diff --git a/docs/src/tutorials/_static/polymer_film.png b/docs/src/tutorials/fitting/polymer_film.png similarity index 100% rename from docs/src/tutorials/_static/polymer_film.png rename to docs/src/tutorials/fitting/polymer_film.png diff --git a/docs/src/tutorials/_static/polymer_film.svg b/docs/src/tutorials/fitting/polymer_film.svg similarity index 100% rename from docs/src/tutorials/_static/polymer_film.svg rename to docs/src/tutorials/fitting/polymer_film.svg diff --git a/docs/src/tutorials/repeating.ipynb b/docs/src/tutorials/fitting/repeating.ipynb similarity index 93% rename from docs/src/tutorials/repeating.ipynb rename to docs/src/tutorials/fitting/repeating.ipynb index 816b0e14..5d0e2514 100644 --- a/docs/src/tutorials/repeating.ipynb +++ b/docs/src/tutorials/fitting/repeating.ipynb @@ -7,11 +7,11 @@ "source": [ "# A multilayer fitting model\n", "\n", - "One of the main tools in `easyreflectometry` is the [assemblies library](../sample/assemblies_library.rst). \n", + "One of the main tools in `easyreflectometry` is the [assemblies library](../../sample/assemblies_library.rst). \n", "This allows the user to define their model, using specific parameters for their system of interest (if it is included in the assemblies library). \n", "These assemblies will impose necessary constraints and computational efficiencies based on the assembly that is used. \n", "\n", - "In this tutorial, we will look at one of these assemblies, that of a `RepeatingMultilayer` ([documented here](../sample/assemblies_library.rst#repeatingmultilayer)). \n", + "In this tutorial, we will look at one of these assemblies, that of a `RepeatingMultilayer` ([documented here](../../sample/assemblies_library.rst#repeatingmultilayer)). \n", "This tutorial is based on an example from the [BornAgain](https://www.bornagainproject.org) documentation looking at [specular reflectivity analysis](https://www.bornagainproject.org/m/py/fitting/extended/fit-specular-data/). \n", "Before performing analysis, we should import the packages that we need." ] @@ -43,7 +43,7 @@ "from easyreflectometry.sample import Material\n", "from easyreflectometry.sample import RepeatingMultilayer\n", "from easyreflectometry.experiment import Model\n", - "from easyreflectometry.experiment import percentage_fhwm_resolution_function\n", + "from easyreflectometry.experiment import PercentageFhwm\n", "from easyreflectometry.calculators import CalculatorFactory\n", "from easyreflectometry.fitting import Fitter\n", "from easyreflectometry.plot import plot" @@ -77,7 +77,8 @@ "source": [ "## Reading in experimental data\n", "\n", - "The data that we will investigate in this tutorial was generated with [GenX](https://aglavic.github.io/genx/) and is stored in an `.ort` [format file](https://github.com/reflectivity/file_format/blob/master/specification.md). " + "The data that we will investigate in this tutorial was generated with [GenX](https://aglavic.github.io/genx/) and is stored in an `.ort` [format file](https://github.com/reflectivity/file_format/blob/master/specification.md).\n", + "Use link to [download](repeating_layers.ort) the ort data." ] }, { @@ -87,7 +88,7 @@ "metadata": {}, "outputs": [], "source": [ - "data = load('_static/repeating_layers.ort')\n", + "data = load('repeating_layers.ort')\n", "data" ] }, @@ -121,7 +122,7 @@ "We show the model that will be used graphically below. \n", "\n", "
\n", - " A slab model description of the repeating multilayer system.\n", + " A slab model description of the repeating multilayer system.\n", "
\n", "
\n", " A slab model description of the repeating multilayer, showing the four layers of vacuum, titanium, nickel and silicon, with the titanium/nickel layers being repeated 10 times.\n", @@ -161,7 +162,7 @@ "id": "f63ec440-089f-46cf-8ff5-be5012ad8dc8", "metadata": {}, "source": [ - "Then, to produce the repeating multilayer, we use the `RepeatingMultilayer` [assembly type](../sample/assemblies_library.rst#RepeatingMultilayer). \n", + "Then, to produce the repeating multilayer, we use the `RepeatingMultilayer` [assembly type](../../sample/assemblies_library.rst#RepeatingMultilayer). \n", "This can be constructed in a range of different ways, however here we pass a list of `Layer` type objects and a number of repetitions. " ] }, @@ -191,7 +192,7 @@ "metadata": {}, "outputs": [], "source": [ - "resolution_function = percentage_fhwm_resolution_function(0)\n", + "resolution_function = PercentageFhwm(0)\n", "sample = Sample(superphase, rep_multilayer, subphase, name='Multilayer Structure')\n", "model = Model(\n", " sample=sample,\n", diff --git a/docs/src/tutorials/_static/repeating.png b/docs/src/tutorials/fitting/repeating.png similarity index 100% rename from docs/src/tutorials/_static/repeating.png rename to docs/src/tutorials/fitting/repeating.png diff --git a/docs/src/tutorials/_static/repeating.svg b/docs/src/tutorials/fitting/repeating.svg similarity index 100% rename from docs/src/tutorials/_static/repeating.svg rename to docs/src/tutorials/fitting/repeating.svg diff --git a/docs/src/tutorials/_static/repeating_layers.ort b/docs/src/tutorials/fitting/repeating_layers.ort similarity index 100% rename from docs/src/tutorials/_static/repeating_layers.ort rename to docs/src/tutorials/fitting/repeating_layers.ort diff --git a/docs/src/tutorials/simple_fitting.ipynb b/docs/src/tutorials/fitting/simple_fitting.ipynb similarity index 96% rename from docs/src/tutorials/simple_fitting.ipynb rename to docs/src/tutorials/fitting/simple_fitting.ipynb index 0a807533..136a98ad 100644 --- a/docs/src/tutorials/simple_fitting.ipynb +++ b/docs/src/tutorials/fitting/simple_fitting.ipynb @@ -37,7 +37,7 @@ "from easyreflectometry.sample import Material\n", "from easyreflectometry.sample import Multilayer\n", "from easyreflectometry.experiment import Model\n", - "from easyreflectometry.experiment import percentage_fhwm_resolution_function\n", + "from easyreflectometry.experiment import PercentageFhwm\n", "from easyreflectometry.calculators import CalculatorFactory\n", "from easyreflectometry.fitting import Fitter\n", "from easyreflectometry.plot import plot" @@ -69,8 +69,9 @@ "source": [ "## Reading in experimental data\n", "\n", - "`easyreflectometry` has support for the `.ort` file format, a [standard file format for reduced reflectivity data developed by the Open Reflectometry Standards Organisation](https://www.reflectometry.org/working_groups/file_formats/). \n", - "To load in a dataset, we use the `load` function. " + "`easyreflectometry` has support for the `.ort` file format, a [standard file format for reduced reflectivity data developed by the Open Reflectometry Standards Organisation](https://www.reflectometry.org/working_groups/file_formats/).\n", + "To load in a dataset, we use the `load` function.\n", + "Use link to [download](example.ort) the ort data." ] }, { @@ -80,7 +81,7 @@ "metadata": {}, "outputs": [], "source": [ - "data = load('_static/example.ort')" + "data = load('example.ort')" ] }, { @@ -136,7 +137,7 @@ "This is shown pictorially below, as a slab model. \n", "\n", "
\n", - " A slab model description of the polymer film system.\n", + " A slab model description of the polymer film system.\n", "
\n", "
\n", " A slab model description of the polymer film system (note that the layers are not to scale), showing the four layers of silicon, silicon dioxide, the polymer film and the heavy water subphase.\n", @@ -221,7 +222,7 @@ "id": "7247fc52-6874-47eb-a234-c7bb7db229fd", "metadata": {}, "source": [ - "Given that the silicon and silicon dioxide layer both compose the solid subphase, it can be helpful to combine these as a `Multilayer` [assembly type](../sample/assemblies_library.rst#multilayer) in our code. " + "Given that the silicon and silicon dioxide layer both compose the solid subphase, it can be helpful to combine these as a `Multilayer` [assembly type](../../sample/assemblies_library.rst#multilayer) in our code. " ] }, { @@ -239,7 +240,7 @@ "id": "a3a2df9b-8ddb-4b3e-a5c3-55b72280b651", "metadata": {}, "source": [ - "These objects are then combined as a `Sample`, where the constructor takes a series of layers (or some more complex `easyreflectometry` [assemblies](../sample/assemblies_library.rst)) and, optionally, some name for the sample." + "These objects are then combined as a `Sample`, where the constructor takes a series of layers (or some more complex `easyreflectometry` [assemblies](../../sample/assemblies_library.rst)) and, optionally, some name for the sample." ] }, { @@ -297,7 +298,7 @@ "metadata": {}, "outputs": [], "source": [ - "resolution_function = percentage_fhwm_resolution_function(0.02)\n", + "resolution_function = PercentageFhwm(0.02)\n", "model = Model(\n", " sample=sample,\n", " scale=1,\n", diff --git a/docs/src/tutorials/_static/d70d2o.ort b/docs/src/tutorials/sample/d70d2o.ort similarity index 100% rename from docs/src/tutorials/_static/d70d2o.ort rename to docs/src/tutorials/sample/d70d2o.ort diff --git a/docs/src/tutorials/_static/dspc.png b/docs/src/tutorials/sample/dspc.png similarity index 100% rename from docs/src/tutorials/_static/dspc.png rename to docs/src/tutorials/sample/dspc.png diff --git a/docs/src/tutorials/sample/example.ort b/docs/src/tutorials/sample/example.ort new file mode 100644 index 00000000..968fa7bb --- /dev/null +++ b/docs/src/tutorials/sample/example.ort @@ -0,0 +1,448 @@ +# # ORSO reflectivity data file | 0.1 standard | YAML encoding | https://www.reflectometry.org/ +# data_source: +# owner: +# name: Andrew Nelson +# affiliation: ANSTO +# contact: Andrew.Nelson@ansto.gov.au +# experiment: +# facility: ANSTO +# start_date: 2021-05-12 +# title: Example data file from refnx docs +# instrument: platypus +# probe: neutron +# sample: +# name: Polymer Film +# category: solid / liquid +# composition: Si / SiO2 / Film / D2O +# measurement: +# instrument_settings: +# wavelength: +# magnitude: 12 +# unit: angstrom +# incident_angle: +# magnitude: 3 +# unit: deg +# data_files: +# - Unknown.nxs +# scheme: angle-dispersive +# reduction: +# software: ess +# timestamp: 2022-01-27T15:33:59+01:00 +# corrections: +# - footprint +# - incident intensity +# - detector efficiency +# columns: +# - {name: Qz, unit: 1/angstrom, dimension: WW transfer} +# - {name: R, dimension: reflectivity} +# - {name: sR, dimension: error-reflectivity} +# - {name: sQz, unit: 1/angstrom, dimension: resolution-WW transfer} +## Qz RQz sR sQz +8.060220000e-03 7.095810000e-01 8.506760000e-02 1.407419648e-04 +8.136620000e-03 8.622810000e-01 1.123700000e-01 1.420996057e-04 +8.263750000e-03 9.086470000e-01 7.900470000e-02 1.443588017e-04 +8.370670000e-03 7.732920000e-01 7.927280000e-02 1.462583099e-04 +8.450330000e-03 1.057970000e+00 1.259590000e-01 1.476732801e-04 +8.530830000e-03 1.015660000e+00 1.132950000e-01 1.491031133e-04 +8.612170000e-03 7.347170000e-01 6.115660000e-02 1.505473850e-04 +8.694370000e-03 7.692160000e-01 6.170580000e-02 1.520069445e-04 +8.777430000e-03 1.115740000e+00 1.127300000e-01 1.534813672e-04 +8.861360000e-03 9.723030000e-01 8.971600000e-02 1.549710776e-04 +8.946160000e-03 7.512140000e-01 5.493930000e-02 1.564760759e-04 +9.031850000e-03 7.976490000e-01 5.671220000e-02 1.579963619e-04 +9.118440000e-03 9.221890000e-01 6.858410000e-02 1.595327850e-04 +9.205930000e-03 9.757550000e-01 7.293950000e-02 1.610844959e-04 +9.294320000e-03 8.195040000e-01 5.216170000e-02 1.626523440e-04 +9.383640000e-03 7.883200000e-01 4.794730000e-02 1.642367538e-04 +9.473890000e-03 7.947010000e-01 4.602240000e-02 1.658368761e-04 +9.565080000e-03 8.744000000e-01 5.151640000e-02 1.674535601e-04 +9.657210000e-03 8.396620000e-01 4.742850000e-02 1.690872306e-04 +9.750300000e-03 8.008720000e-01 4.399580000e-02 1.707370382e-04 +9.844360000e-03 1.117100000e+00 7.373300000e-02 1.724042569e-04 +9.939390000e-03 8.884110000e-01 4.954100000e-02 1.740884620e-04 +1.003540000e-02 7.791290000e-01 3.898730000e-02 1.757896536e-04 +1.013240000e-02 7.999680000e-01 3.899740000e-02 1.775086809e-04 +1.023040000e-02 8.431240000e-01 4.159800000e-02 1.792451193e-04 +1.032940000e-02 9.613320000e-01 4.925360000e-02 1.809989689e-04 +1.048680000e-02 8.805440000e-01 2.990830000e-02 1.837851690e-04 +1.063270000e-02 7.557350000e-01 3.208510000e-02 1.863700799e-04 +1.073590000e-02 9.712310000e-01 4.534850000e-02 1.881969711e-04 +1.084010000e-02 8.955490000e-01 3.905420000e-02 1.900425474e-04 +1.094540000e-02 8.625890000e-01 3.580720000e-02 1.919068087e-04 +1.105180000e-02 8.909920000e-01 3.612570000e-02 1.937906045e-04 +1.115930000e-02 9.003480000e-01 3.679240000e-02 1.956930853e-04 +1.126790000e-02 8.459270000e-01 3.218810000e-02 1.976151006e-04 +1.137760000e-02 9.431520000e-01 3.655330000e-02 1.995570749e-04 +1.148840000e-02 9.956310000e-01 3.901160000e-02 2.015185836e-04 +1.160040000e-02 9.695940000e-01 3.636230000e-02 2.034996267e-04 +1.171350000e-02 9.051810000e-01 3.204100000e-02 2.055014781e-04 +1.182780000e-02 8.933810000e-01 3.061190000e-02 2.075232887e-04 +1.194330000e-02 9.196020000e-01 3.146770000e-02 2.095659076e-04 +1.205990000e-02 9.189980000e-01 3.060970000e-02 2.116293349e-04 +1.217770000e-02 7.810560000e-01 2.355420000e-02 2.137135706e-04 +1.229680000e-02 8.649150000e-01 2.720250000e-02 2.158190394e-04 +1.241700000e-02 8.435160000e-01 2.550150000e-02 2.179457412e-04 +1.253850000e-02 9.984180000e-01 3.197220000e-02 2.200945253e-04 +1.266120000e-02 8.812600000e-01 2.602730000e-02 2.222645425e-04 +1.278520000e-02 8.835690000e-01 2.558620000e-02 2.244570667e-04 +1.291050000e-02 9.376700000e-01 2.746510000e-02 2.266716733e-04 +1.303700000e-02 1.019200000e+00 3.051070000e-02 2.289087870e-04 +1.316480000e-02 8.455260000e-01 2.262690000e-02 2.311684076e-04 +1.329390000e-02 8.738040000e-01 2.324680000e-02 2.334509599e-04 +1.342430000e-02 8.659530000e-01 2.249060000e-02 2.357568686e-04 +1.355610000e-02 8.779820000e-01 2.244910000e-02 2.380861337e-04 +1.368920000e-02 9.475450000e-01 2.489850000e-02 2.404387551e-04 +1.382370000e-02 8.881540000e-01 2.209620000e-02 2.428155821e-04 +1.395950000e-02 8.913620000e-01 2.181480000e-02 2.452161902e-04 +1.409670000e-02 8.884560000e-01 2.150920000e-02 2.476410039e-04 +1.423530000e-02 9.137170000e-01 2.225860000e-02 2.500908727e-04 +1.437530000e-02 8.103640000e-01 1.882890000e-02 2.525649471e-04 +1.451680000e-02 7.385480000e-01 1.688270000e-02 2.550645011e-04 +1.465970000e-02 6.865100000e-01 1.597420000e-02 2.575891102e-04 +1.480400000e-02 5.822400000e-01 1.350210000e-02 2.601396235e-04 +1.494980000e-02 4.468550000e-01 1.006260000e-02 2.627156166e-04 +1.509700000e-02 3.924610000e-01 9.155490000e-03 2.653175139e-04 +1.524580000e-02 3.205170000e-01 7.319590000e-03 2.679461649e-04 +1.539610000e-02 2.810060000e-01 6.399090000e-03 2.706011448e-04 +1.554790000e-02 2.401000000e-01 5.442390000e-03 2.732828784e-04 +1.570120000e-02 2.208810000e-01 5.024370000e-03 2.759917903e-04 +1.585610000e-02 1.920330000e-01 4.314410000e-03 2.787278805e-04 +1.601260000e-02 1.798490000e-01 4.051590000e-03 2.814919983e-04 +1.617070000e-02 1.600690000e-01 3.562020000e-03 2.842837190e-04 +1.633030000e-02 1.531290000e-01 3.467770000e-03 2.871038920e-04 +1.649160000e-02 1.342200000e-01 3.016000000e-03 2.899525174e-04 +1.665450000e-02 1.283300000e-01 2.888530000e-03 2.928300196e-04 +1.681900000e-02 1.247940000e-01 2.861820000e-03 2.957363988e-04 +1.698530000e-02 1.091270000e-01 2.483100000e-03 2.986720796e-04 +1.715320000e-02 1.044290000e-01 2.353920000e-03 3.016374867e-04 +1.732280000e-02 9.468300000e-02 2.091620000e-03 3.046326200e-04 +1.758810000e-02 8.969110000e-02 1.439380000e-03 3.093191777e-04 +1.784190000e-02 8.091440000e-02 1.872780000e-03 3.138010489e-04 +1.801850000e-02 7.465440000e-02 1.714220000e-03 3.169189092e-04 +1.819680000e-02 7.036610000e-02 1.634230000e-03 3.200686191e-04 +1.837700000e-02 6.904450000e-02 1.605300000e-03 3.232497539e-04 +1.855890000e-02 6.270550000e-02 1.461460000e-03 3.264631629e-04 +1.874270000e-02 5.939150000e-02 1.400070000e-03 3.297088462e-04 +1.892840000e-02 5.754770000e-02 1.360950000e-03 3.329872283e-04 +1.911590000e-02 5.138330000e-02 1.226680000e-03 3.362987340e-04 +1.930540000e-02 4.922670000e-02 1.178240000e-03 3.396437879e-04 +1.949670000e-02 4.521740000e-02 1.079620000e-03 3.430219654e-04 +1.969000000e-02 4.245560000e-02 1.022250000e-03 3.464349651e-04 +1.988520000e-02 4.126130000e-02 9.947810000e-04 3.498819376e-04 +2.008240000e-02 3.523330000e-02 8.777900000e-04 3.533637323e-04 +2.028150000e-02 3.352710000e-02 8.367470000e-04 3.568803492e-04 +2.048270000e-02 3.326840000e-02 8.339590000e-04 3.604326376e-04 +2.068590000e-02 3.166440000e-02 7.898860000e-04 3.640210222e-04 +2.089120000e-02 2.916000000e-02 7.496130000e-04 3.676450784e-04 +2.109850000e-02 2.652010000e-02 7.063830000e-04 3.713060800e-04 +2.130800000e-02 2.518290000e-02 6.713890000e-04 3.750036024e-04 +2.151950000e-02 2.387570000e-02 6.426930000e-04 3.787384951e-04 +2.173310000e-02 2.289290000e-02 6.330680000e-04 3.825111825e-04 +2.194900000e-02 2.086460000e-02 5.931280000e-04 3.863216648e-04 +2.216690000e-02 2.087710000e-02 5.920100000e-04 3.901703665e-04 +2.238710000e-02 1.822280000e-02 5.292050000e-04 3.940581370e-04 +2.260950000e-02 1.773460000e-02 5.251520000e-04 3.979849764e-04 +2.283410000e-02 1.587140000e-02 4.818770000e-04 4.019513092e-04 +2.306100000e-02 1.432550000e-02 4.516190000e-04 4.059575601e-04 +2.329020000e-02 1.427760000e-02 4.522490000e-04 4.100041538e-04 +2.352170000e-02 1.266240000e-02 4.198450000e-04 4.140919397e-04 +2.375550000e-02 1.221280000e-02 4.137860000e-04 4.182204929e-04 +2.399170000e-02 1.046080000e-02 3.745320000e-04 4.223906630e-04 +2.423020000e-02 1.061330000e-02 3.810520000e-04 4.266016005e-04 +2.447120000e-02 9.879030000e-03 3.641280000e-04 4.308567027e-04 +2.471450000e-02 8.372030000e-03 3.313930000e-04 4.351542710e-04 +2.496030000e-02 7.670480000e-03 3.077050000e-04 4.394943054e-04 +2.520860000e-02 7.344890000e-03 3.049780000e-04 4.438810525e-04 +2.545940000e-02 6.798650000e-03 2.898680000e-04 4.483102657e-04 +2.571270000e-02 5.916300000e-03 2.671780000e-04 4.527819450e-04 +2.596850000e-02 5.344980000e-03 2.515360000e-04 4.573003369e-04 +2.622690000e-02 5.122650000e-03 2.474120000e-04 4.618611950e-04 +2.648800000e-02 4.750310000e-03 2.379530000e-04 4.664730124e-04 +2.675160000e-02 4.307150000e-03 2.238500000e-04 4.711272958e-04 +2.701790000e-02 4.018170000e-03 2.200510000e-04 4.758325386e-04 +2.728680000e-02 3.539150000e-03 2.046530000e-04 4.805802475e-04 +2.755850000e-02 3.818190000e-03 2.079440000e-04 4.853789156e-04 +2.783290000e-02 2.864750000e-03 1.819210000e-04 4.902285431e-04 +2.811000000e-02 2.795800000e-03 1.766910000e-04 4.951206367e-04 +2.839000000e-02 2.621500000e-03 1.750020000e-04 5.000679362e-04 +2.867270000e-02 2.484770000e-03 1.694560000e-04 5.050619484e-04 +2.895830000e-02 2.420090000e-03 1.709250000e-04 5.101069199e-04 +2.924670000e-02 2.359260000e-03 1.700600000e-04 5.151986041e-04 +2.953810000e-02 1.978560000e-03 1.600210000e-04 5.203454942e-04 +2.983230000e-02 1.947200000e-03 1.582820000e-04 5.255475902e-04 +3.012960000e-02 1.735930000e-03 1.527310000e-04 5.307963989e-04 +3.042980000e-02 1.894590000e-03 1.603050000e-04 5.361004136e-04 +3.073300000e-02 1.696680000e-03 1.525740000e-04 5.414596341e-04 +3.103920000e-02 1.793690000e-03 1.592450000e-04 5.468698140e-04 +3.134860000e-02 1.786860000e-03 1.552020000e-04 5.523351998e-04 +3.166100000e-02 1.872010000e-03 1.583950000e-04 5.578557915e-04 +3.197660000e-02 1.688180000e-03 1.499840000e-04 5.634315891e-04 +3.229530000e-02 1.732370000e-03 1.543250000e-04 5.690625926e-04 +3.261730000e-02 1.537600000e-03 1.453960000e-04 5.747530487e-04 +3.294240000e-02 1.541340000e-03 1.497560000e-04 5.804987107e-04 +3.327080000e-02 1.700330000e-03 1.572080000e-04 5.863038252e-04 +3.360260000e-02 2.142240000e-03 1.728870000e-04 5.921683922e-04 +3.393760000e-02 1.944020000e-03 1.686890000e-04 5.980924118e-04 +3.422050000e-02 1.914000000e-03 1.077140000e-04 6.019483327e-04 +3.466450000e-02 1.986410000e-03 1.438280000e-04 6.103523719e-04 +3.502190000e-02 1.849740000e-03 1.279740000e-04 6.165099550e-04 +3.538500000e-02 1.932640000e-03 1.227080000e-04 6.227354838e-04 +3.571620000e-02 2.188990000e-03 1.495980000e-04 6.288506008e-04 +3.607730000e-02 2.314320000e-03 1.503450000e-04 6.351568151e-04 +3.646770000e-02 1.831770000e-03 1.041590000e-04 6.416328939e-04 +3.682630000e-02 1.797150000e-03 1.012920000e-04 6.480155472e-04 +3.716160000e-02 2.278740000e-03 1.417330000e-04 6.543599810e-04 +3.754210000e-02 2.183390000e-03 1.294600000e-04 6.609379784e-04 +3.794040000e-02 1.799000000e-03 9.624980000e-05 6.676221409e-04 +3.831280000e-02 1.828080000e-03 9.734640000e-05 6.742680840e-04 +3.868400000e-02 1.949850000e-03 1.082600000e-04 6.809692330e-04 +3.906920000e-02 2.042140000e-03 1.122450000e-04 6.877680540e-04 +3.947340000e-02 1.659460000e-03 8.395540000e-05 6.946772869e-04 +3.986330000e-02 1.620310000e-03 8.073380000e-05 7.016035062e-04 +4.026580000e-02 1.588620000e-03 7.617690000e-05 7.086189042e-04 +4.066080000e-02 1.582510000e-03 7.829120000e-05 7.156810150e-04 +4.107010000e-02 1.429900000e-03 7.034450000e-05 7.228323046e-04 +4.147810000e-02 1.336120000e-03 6.498820000e-05 7.300472933e-04 +4.187440000e-02 1.721900000e-03 9.200060000e-05 7.373174879e-04 +4.230490000e-02 1.404890000e-03 6.788170000e-05 7.446980943e-04 +4.273170000e-02 1.146480000e-03 5.315150000e-05 7.521381533e-04 +4.315460000e-02 1.030130000e-03 4.872800000e-05 7.596504046e-04 +4.358350000e-02 1.018640000e-03 4.851630000e-05 7.672348483e-04 +4.401550000e-02 1.060250000e-03 5.148880000e-05 7.748999775e-04 +4.445490000e-02 9.115610000e-04 4.517670000e-05 7.826415457e-04 +4.489830000e-02 7.795360000e-04 3.746760000e-05 7.904553063e-04 +4.534700000e-02 5.957570000e-04 2.867780000e-05 7.983539991e-04 +4.579470000e-02 6.476450000e-04 3.286690000e-05 8.063333774e-04 +4.625120000e-02 5.268390000e-04 2.666210000e-05 8.143891946e-04 +4.671240000e-02 4.365460000e-04 2.240950000e-05 8.225299441e-04 +4.717830000e-02 3.696050000e-04 1.929650000e-05 8.307471325e-04 +4.764690000e-02 3.315640000e-04 1.808550000e-05 8.390577463e-04 +4.812080000e-02 2.545840000e-04 1.440620000e-05 8.474405525e-04 +4.859940000e-02 2.090800000e-04 1.312430000e-05 8.559167841e-04 +4.908280000e-02 1.929370000e-04 1.261590000e-05 8.644779478e-04 +4.957100000e-02 1.309220000e-04 9.992220000e-06 8.731240437e-04 +5.006400000e-02 1.098230000e-04 9.080510000e-06 8.818635651e-04 +5.056190000e-02 9.565480000e-05 8.370090000e-06 8.906880186e-04 +5.106550000e-02 7.925720000e-05 7.699130000e-06 8.995974043e-04 +5.157340000e-02 7.956050000e-05 6.898560000e-06 9.086044619e-04 +5.208640000e-02 7.224950000e-05 6.102730000e-06 9.177006984e-04 +5.260450000e-02 7.825130000e-05 6.391360000e-06 9.268903603e-04 +5.312790000e-02 8.637120000e-05 6.561860000e-06 9.361734476e-04 +5.365650000e-02 1.331620000e-04 8.789840000e-06 9.455499603e-04 +5.419050000e-02 1.436320000e-04 8.178840000e-06 9.550241449e-04 +5.472980000e-02 1.586820000e-04 8.565340000e-06 9.645917550e-04 +5.527450000e-02 1.900070000e-04 9.755240000e-06 9.742612837e-04 +5.582470000e-02 2.354200000e-04 1.141720000e-05 9.840284844e-04 +5.638040000e-02 2.339320000e-04 1.034520000e-05 9.938933571e-04 +5.694170000e-02 2.433900000e-04 1.059550000e-05 1.003855902e-03 +5.750870000e-02 2.708580000e-04 1.125130000e-05 1.013924612e-03 +5.808130000e-02 3.109660000e-04 1.233550000e-05 1.024095240e-03 +5.865970000e-02 3.483270000e-04 1.357860000e-05 1.034367788e-03 +5.924390000e-02 3.329570000e-04 1.275590000e-05 1.044750747e-03 +5.983400000e-02 3.546590000e-04 1.322360000e-05 1.055235624e-03 +6.043000000e-02 3.544670000e-04 1.306610000e-05 1.065826667e-03 +6.103190000e-02 3.855150000e-04 1.408930000e-05 1.076523875e-03 +6.164000000e-02 3.325090000e-04 1.201760000e-05 1.087335742e-03 +6.225410000e-02 3.330870000e-04 1.197150000e-05 1.098253773e-03 +6.287440000e-02 3.303070000e-04 1.197230000e-05 1.109286464e-03 +6.350090000e-02 3.224690000e-04 1.162910000e-05 1.120433812e-03 +6.413370000e-02 2.744620000e-04 9.948790000e-06 1.131691573e-03 +6.477280000e-02 2.792430000e-04 1.025370000e-05 1.143063992e-03 +6.541840000e-02 2.389380000e-04 8.960850000e-06 1.154555315e-03 +6.607040000e-02 2.330280000e-04 8.726650000e-06 1.166165544e-03 +6.672900000e-02 1.863430000e-04 7.236140000e-06 1.177890432e-03 +6.739420000e-02 1.649490000e-04 6.619500000e-06 1.189738471e-03 +6.806600000e-02 1.332440000e-04 5.541570000e-06 1.201709662e-03 +6.874460000e-02 1.153760000e-04 4.971620000e-06 1.213799758e-03 +6.943000000e-02 8.250330000e-05 3.951150000e-06 1.226017252e-03 +7.012230000e-02 6.719230000e-05 3.570180000e-06 1.238357898e-03 +7.082150000e-02 5.033220000e-05 2.926230000e-06 1.250825942e-03 +7.152780000e-02 3.336120000e-05 2.509700000e-06 1.263421384e-03 +7.224110000e-02 2.290520000e-05 2.116380000e-06 1.276148471e-03 +7.293380000e-02 1.879440000e-05 1.860530000e-06 1.288068702e-03 +7.366830000e-02 1.553440000e-05 1.798210000e-06 1.301292643e-03 +7.440150000e-02 1.824520000e-05 1.951840000e-06 1.314359459e-03 +7.514050000e-02 2.235620000e-05 1.801000000e-06 1.327506960e-03 +7.587210000e-02 2.773620000e-05 1.890140000e-06 1.340293500e-03 +7.664020000e-02 3.931010000e-05 2.300950000e-06 1.354192651e-03 +7.739640000e-02 4.596690000e-05 2.332400000e-06 1.367582209e-03 +7.810610000e-02 5.541310000e-05 2.459260000e-06 1.379328330e-03 +7.886820000e-02 6.726050000e-05 2.729570000e-06 1.392692408e-03 +7.979530000e-02 7.650640000e-05 2.773090000e-06 1.409143772e-03 +8.072890000e-02 7.794720000e-05 2.857410000e-06 1.425518696e-03 +8.153340000e-02 8.505420000e-05 2.990400000e-06 1.439910454e-03 +8.233180000e-02 9.685690000e-05 3.222700000e-06 1.454408377e-03 +8.316050000e-02 9.462400000e-05 3.166210000e-06 1.469122877e-03 +8.402520000e-02 8.585640000e-05 2.824460000e-06 1.484058201e-03 +8.486480000e-02 8.101440000e-05 2.662540000e-06 1.499057224e-03 +8.573420000e-02 7.655920000e-05 2.549780000e-06 1.514268578e-03 +8.655530000e-02 7.385430000e-05 2.485840000e-06 1.529496917e-03 +8.743720000e-02 6.249710000e-05 2.190920000e-06 1.545009780e-03 +8.831630000e-02 5.495430000e-05 2.001270000e-06 1.560658534e-03 +8.911080000e-02 5.694540000e-05 2.081580000e-06 1.576247836e-03 +9.004160000e-02 4.229200000e-05 1.729710000e-06 1.592304265e-03 +9.095460000e-02 3.367540000e-05 1.458910000e-06 1.608462612e-03 +9.185040000e-02 2.545640000e-05 1.249630000e-06 1.624727124e-03 +9.274350000e-02 2.092210000e-05 1.159760000e-06 1.641140268e-03 +9.362890000e-02 1.531120000e-05 1.060140000e-06 1.657689303e-03 +9.455270000e-02 1.265650000e-05 9.577530000e-07 1.674480395e-03 +9.551780000e-02 9.331240000e-06 8.621390000e-07 1.691509297e-03 +9.647710000e-02 8.901520000e-06 7.828970000e-07 1.708691077e-03 +9.741890000e-02 1.079150000e-05 8.938470000e-07 1.725991763e-03 +9.842590000e-02 1.213680000e-05 9.113080000e-07 1.743589710e-03 +9.942010000e-02 1.540800000e-05 9.077770000e-07 1.761323549e-03 +1.004250000e-01 1.938030000e-05 9.602530000e-07 1.779248486e-03 +1.014340000e-01 2.091160000e-05 1.040890000e-06 1.797347534e-03 +1.024990000e-01 2.519250000e-05 1.078370000e-06 1.815722611e-03 +1.034980000e-01 2.818800000e-05 1.132170000e-06 1.834144401e-03 +1.045460000e-01 2.998100000e-05 1.178530000e-06 1.852837973e-03 +1.056080000e-01 3.056280000e-05 1.150490000e-06 1.871735383e-03 +1.066820000e-01 2.819030000e-05 1.099070000e-06 1.890832384e-03 +1.077580000e-01 2.692630000e-05 1.037400000e-06 1.910111989e-03 +1.088310000e-01 2.541920000e-05 1.012560000e-06 1.929574198e-03 +1.099160000e-01 2.282700000e-05 9.367100000e-07 1.949244491e-03 +1.110400000e-01 1.769170000e-05 7.904500000e-07 1.969169580e-03 +1.121170000e-01 1.547510000e-05 7.625400000e-07 1.989209328e-03 +1.132440000e-01 1.172580000e-05 6.688050000e-07 2.009529352e-03 +1.143190000e-01 1.050270000e-05 6.598050000e-07 2.029959788e-03 +1.154640000e-01 8.121530000e-06 5.847030000e-07 2.050708720e-03 +1.166450000e-01 4.988840000e-06 5.267190000e-07 2.071720941e-03 +1.177620000e-01 4.909990000e-06 5.360960000e-07 2.092830835e-03 +1.189250000e-01 5.304340000e-06 5.240840000e-07 2.114229497e-03 +1.201290000e-01 5.689050000e-06 4.912340000e-07 2.135895696e-03 +1.213460000e-01 6.444710000e-06 5.061070000e-07 2.157799706e-03 +1.225860000e-01 7.456190000e-06 5.058030000e-07 2.179954265e-03 +1.238230000e-01 8.248420000e-06 5.025600000e-07 2.202325401e-03 +1.250910000e-01 1.067490000e-05 5.845390000e-07 2.224964074e-03 +1.263610000e-01 1.131620000e-05 5.722280000e-07 2.247827816e-03 +1.276430000e-01 1.104400000e-05 5.762550000e-07 2.270937863e-03 +1.289320000e-01 1.062580000e-05 5.655340000e-07 2.294294212e-03 +1.302100000e-01 9.337660000e-06 5.254720000e-07 2.317858646e-03 +1.315470000e-01 8.922800000e-06 5.000680000e-07 2.341754314e-03 +1.328540000e-01 6.436110000e-06 4.446880000e-07 2.365841081e-03 +1.341620000e-01 6.181130000e-06 4.556250000e-07 2.390178397e-03 +1.355150000e-01 4.685680000e-06 4.034780000e-07 2.414821469e-03 +1.368240000e-01 4.667540000e-06 3.809290000e-07 2.439659885e-03 +1.382040000e-01 4.262500000e-06 3.763010000e-07 2.464842276e-03 +1.395890000e-01 3.884300000e-06 3.571580000e-07 2.490292204e-03 +1.409890000e-01 3.699480000e-06 3.796620000e-07 2.516022408e-03 +1.424300000e-01 3.659930000e-06 3.543380000e-07 2.542066861e-03 +1.438510000e-01 4.559390000e-06 3.665690000e-07 2.568357617e-03 +1.452630000e-01 4.580880000e-06 3.470620000e-07 2.594911663e-03 +1.467500000e-01 4.829290000e-06 3.503920000e-07 2.621826671e-03 +1.482250000e-01 4.930920000e-06 3.533300000e-07 2.649009215e-03 +1.497100000e-01 4.781000000e-06 3.612560000e-07 2.676489022e-03 +1.512250000e-01 4.644840000e-06 3.397110000e-07 2.704291571e-03 +1.527360000e-01 4.365080000e-06 3.324590000e-07 2.732374397e-03 +1.542610000e-01 3.807060000e-06 3.253780000e-07 2.760775718e-03 +1.558250000e-01 3.544150000e-06 3.053880000e-07 2.789516767e-03 +1.573660000e-01 2.632690000e-06 2.773550000e-07 2.818538093e-03 +1.589410000e-01 2.129680000e-06 2.570610000e-07 2.847903395e-03 +1.605110000e-01 2.509080000e-06 2.684170000e-07 2.877574452e-03 +1.621370000e-01 2.606260000e-06 2.683540000e-07 2.907627704e-03 +1.637550000e-01 2.467960000e-06 2.618110000e-07 2.937986711e-03 +1.654040000e-01 2.437690000e-06 2.457080000e-07 2.968710928e-03 +1.670350000e-01 2.818460000e-06 2.626350000e-07 2.999740899e-03 +1.687360000e-01 3.201910000e-06 2.677220000e-07 3.031182793e-03 +1.704100000e-01 3.020960000e-06 2.548660000e-07 3.062934688e-03 +1.721190000e-01 2.398550000e-06 2.324640000e-07 3.095064532e-03 +1.738390000e-01 2.458240000e-06 2.385460000e-07 3.127555337e-03 +1.755740000e-01 2.033660000e-06 2.231960000e-07 3.160419844e-03 +1.773360000e-01 1.684040000e-06 2.048280000e-07 3.193666546e-03 +1.790870000e-01 1.293830000e-06 2.007650000e-07 3.227265717e-03 +1.809070000e-01 1.439670000e-06 1.882070000e-07 3.261306534e-03 +1.827150000e-01 1.540200000e-06 1.999980000e-07 3.295708314e-03 +1.845350000e-01 1.338490000e-06 1.864820000e-07 3.330500781e-03 +1.863830000e-01 1.615990000e-06 1.863690000e-07 3.365705170e-03 +1.882470000e-01 1.493470000e-06 1.883860000e-07 3.401317233e-03 +1.901260000e-01 2.059680000e-06 1.920700000e-07 3.437345464e-03 +1.920380000e-01 1.690150000e-06 1.767700000e-07 3.473806849e-03 +1.939540000e-01 1.488370000e-06 1.792740000e-07 3.510675908e-03 +1.959000000e-01 1.403820000e-06 1.747280000e-07 3.547990861e-03 +1.978600000e-01 1.346890000e-06 1.705690000e-07 3.585734722e-03 +1.998450000e-01 9.477100000e-07 1.617790000e-07 3.623937217e-03 +2.018330000e-01 1.089550000e-06 1.735020000e-07 3.662568619e-03 +2.038630000e-01 1.246350000e-06 1.654660000e-07 3.701684134e-03 +2.059040000e-01 1.227370000e-06 1.644900000e-07 3.741254037e-03 +2.079590000e-01 1.168960000e-06 1.584560000e-07 3.781286820e-03 +2.100420000e-01 1.161720000e-06 1.521980000e-07 3.821807963e-03 +2.121400000e-01 1.216890000e-06 1.588540000e-07 3.862808973e-03 +2.142570000e-01 1.317570000e-06 1.546070000e-07 3.904298343e-03 +2.163990000e-01 1.032790000e-06 1.472920000e-07 3.946293059e-03 +2.185700000e-01 1.030660000e-06 1.514730000e-07 3.988805862e-03 +2.207810000e-01 5.945350000e-07 1.511720000e-07 4.031853738e-03 +2.229880000e-01 7.279960000e-07 1.429280000e-07 4.075394220e-03 +2.252160000e-01 7.806310000e-07 1.485250000e-07 4.119465528e-03 +2.274670000e-01 1.063390000e-06 1.499300000e-07 4.164076155e-03 +2.297410000e-01 6.526970000e-07 1.296680000e-07 4.209234596e-03 +2.320370000e-01 1.074380000e-06 1.484530000e-07 4.254932355e-03 +2.343560000e-01 8.687630000e-07 1.468620000e-07 4.301220393e-03 +2.366980000e-01 9.218680000e-07 1.450820000e-07 4.348060490e-03 +2.390640000e-01 6.471490000e-07 1.368090000e-07 4.395495113e-03 +2.414540000e-01 5.363930000e-07 1.356880000e-07 4.443524261e-03 +2.438670000e-01 6.337170000e-07 1.304030000e-07 4.492147934e-03 +2.463040000e-01 6.292700000e-07 1.365570000e-07 4.541408598e-03 +2.487660000e-01 6.332920000e-07 1.224530000e-07 4.591263788e-03 +2.512530000e-01 1.037050000e-06 1.354090000e-07 4.641713503e-03 +2.537640000e-01 8.252860000e-07 1.431610000e-07 4.692842675e-03 +2.563010000e-01 6.268250000e-07 1.192570000e-07 4.744608839e-03 +2.588630000e-01 5.252590000e-07 1.227410000e-07 4.797054460e-03 +2.614500000e-01 5.218320000e-07 1.309180000e-07 4.850137073e-03 +2.640640000e-01 3.916590000e-07 1.213700000e-07 4.903941609e-03 +2.667030000e-01 4.724390000e-07 1.399730000e-07 4.958425602e-03 +2.693690000e-01 5.595360000e-07 1.391510000e-07 5.013589053e-03 +2.720620000e-01 6.640700000e-07 1.448670000e-07 5.069474428e-03 +2.747820000e-01 4.593780000e-07 1.514660000e-07 5.126081726e-03 +2.775290000e-01 3.669610000e-07 1.435460000e-07 5.183453413e-03 +2.803030000e-01 5.315310000e-07 1.483080000e-07 5.241589490e-03 +2.831050000e-01 4.289140000e-07 1.361450000e-07 5.300447491e-03 +2.859350000e-01 5.520060000e-07 1.419830000e-07 5.360112348e-03 +2.887930000e-01 5.702640000e-07 1.529000000e-07 5.420541594e-03 +2.916800000e-01 5.047310000e-07 1.364290000e-07 5.481777696e-03 +2.945960000e-01 6.619230000e-07 1.407930000e-07 5.543863119e-03 +2.975410000e-01 7.601320000e-07 1.607210000e-07 5.606755399e-03 +3.005160000e-01 4.685270000e-07 1.348870000e-07 5.670454534e-03 +3.035200000e-01 4.428600000e-07 1.471340000e-07 5.735087923e-03 +3.065540000e-01 4.899790000e-07 1.404300000e-07 5.800528167e-03 +3.096190000e-01 3.601630000e-07 1.337280000e-07 5.866902666e-03 +3.127140000e-01 2.905630000e-07 1.480620000e-07 5.934168953e-03 +3.158410000e-01 5.199630000e-07 1.515620000e-07 6.002327027e-03 +3.189980000e-01 4.666650000e-07 1.562560000e-07 6.071461822e-03 +3.221870000e-01 3.888830000e-07 1.570110000e-07 6.141530870e-03 +3.254080000e-01 4.467780000e-07 1.555120000e-07 6.212576639e-03 +3.286620000e-01 3.238850000e-07 1.525860000e-07 6.284599127e-03 +3.319470000e-01 3.787360000e-07 1.581800000e-07 6.357640802e-03 +3.352660000e-01 3.881990000e-07 1.539110000e-07 6.431701663e-03 +3.386180000e-01 4.428770000e-07 1.490980000e-07 6.506824176e-03 +3.420030000e-01 2.477870000e-07 1.463210000e-07 6.582965876e-03 +3.454230000e-01 2.857690000e-07 1.351350000e-07 6.660211693e-03 +3.488760000e-01 4.759640000e-07 1.536640000e-07 6.738561630e-03 +3.523640000e-01 4.496390000e-07 1.539560000e-07 6.818015684e-03 +3.558870000e-01 2.471470000e-07 1.443220000e-07 6.898573857e-03 +3.594450000e-01 2.167640000e-07 1.491810000e-07 6.980363546e-03 +3.630390000e-01 5.205850000e-07 1.573690000e-07 7.063257354e-03 +3.666690000e-01 5.246970000e-07 1.545410000e-07 7.147425144e-03 +3.703350000e-01 3.644030000e-07 1.550240000e-07 7.232781985e-03 +3.740370000e-01 4.597520000e-07 1.653080000e-07 7.319370343e-03 +3.777770000e-01 5.359220000e-07 1.820430000e-07 7.407232683e-03 +3.815540000e-01 4.268070000e-07 1.770030000e-07 7.496411472e-03 +3.853690000e-01 4.036660000e-07 1.811100000e-07 7.586906710e-03 +3.892220000e-01 2.554540000e-07 1.597290000e-07 7.678718396e-03 +3.931130000e-01 9.269720000e-08 1.654020000e-07 7.771931464e-03 +3.970440000e-01 1.106720000e-07 1.808880000e-07 7.866503446e-03 +4.010140000e-01 4.521630000e-07 1.731910000e-07 7.962519276e-03 +4.050230000e-01 3.780660000e-07 1.515970000e-07 8.059978953e-03 +4.090730000e-01 3.091360000e-07 1.571950000e-07 8.158924942e-03 +4.131630000e-01 3.417740000e-07 1.448180000e-07 8.259357245e-03 +4.172940000e-01 3.449240000e-07 1.595810000e-07 8.361318327e-03 +4.214660000e-01 2.518400000e-07 1.597570000e-07 8.464850655e-03 +4.256800000e-01 4.017370000e-07 1.538140000e-07 8.569954228e-03 +4.299360000e-01 3.172790000e-07 1.691300000e-07 8.676713978e-03 +4.342350000e-01 5.506310000e-07 1.611420000e-07 8.785087440e-03 +4.385770000e-01 5.085100000e-07 1.649900000e-07 8.895159545e-03 +4.429620000e-01 6.025930000e-07 1.738350000e-07 9.006930294e-03 +4.473910000e-01 4.384540000e-07 1.653500000e-07 9.120484618e-03 +4.518650000e-01 3.387570000e-07 1.876390000e-07 9.235822519e-03 +4.563830000e-01 4.358460000e-07 1.978260000e-07 9.352943995e-03 +4.609460000e-01 3.855790000e-07 1.761430000e-07 9.471933979e-03 +4.655550000e-01 3.834150000e-07 1.884540000e-07 9.592834938e-03 diff --git a/docs/src/tutorials/material_solvated.ipynb b/docs/src/tutorials/sample/material_solvated.ipynb similarity index 94% rename from docs/src/tutorials/material_solvated.ipynb rename to docs/src/tutorials/sample/material_solvated.ipynb index 358e894c..2cad6851 100644 --- a/docs/src/tutorials/material_solvated.ipynb +++ b/docs/src/tutorials/sample/material_solvated.ipynb @@ -7,12 +7,12 @@ "source": [ "# Using the MaterialSolvated\n", "\n", - "In the [first tutorial](./simple_fitting.rst), we looked at a straight forward example of a polymer film at the solid/liquid interface. \n", + "In the [first tutorial](../fitting/simple_fitting.rst), we looked at a straight forward example of a polymer film at the solid/liquid interface. \n", "To analyse this data, we constructed a model with two layers, one SiO2 and one of the polymer film, and when the analysis was performed, the scattering length density of the polymer film was allowed to vary to find an optimum value. \n", "However, it is likely that this scattering length density is in fact a compound value arising from the mixture of the polymer with some D2O intercalated. \n", "Therefore, if, for example, the surface covereage of the polymer was known, it may be possible to determine the scattering length density alone. \n", "Of course, this could be calculated from the optimal scattering length density for the film, but it is more intuitive to include this in our modelling approach. \n", - "Here, we will show how to use the `MaterialSolvated` [type](../sample/material_library.rst#materialsolvated) to perform this analysis. " + "Here, we will show how to use the `MaterialSolvated` [type](../../sample/material_library.rst#materialsolvated) to perform this analysis. " ] }, { @@ -43,7 +43,7 @@ "from easyreflectometry.sample import MaterialSolvated\n", "from easyreflectometry.sample import Multilayer\n", "from easyreflectometry.experiment import Model\n", - "from easyreflectometry.experiment import percentage_fhwm_resolution_function\n", + "from easyreflectometry.experiment import PercentageFhwm\n", "from easyreflectometry.calculators import CalculatorFactory\n", "from easyreflectometry.fitting import Fitter\n", "from easyreflectometry.plot import plot" @@ -75,8 +75,9 @@ "id": "3ac19f8b-099d-4b19-8d37-7dd651a25949", "metadata": {}, "source": [ - "For information about the data being read in and the details of the model see [the previous tutorial](./simple_fitting.rst). \n", - "We will gloss over these details here. " + "For information about the data being read in and the details of the model see [the previous tutorial](../fitting/simple_fitting.rst). \n", + "We will gloss over these details here.\n", + "Use link to [download](example.ort) the ort data." ] }, { @@ -86,7 +87,7 @@ "metadata": {}, "outputs": [], "source": [ - "data = load('_static/example.ort')" + "data = load('example.ort')" ] }, { @@ -182,7 +183,7 @@ "\n", "subphase = Layer(material=d2o, thickness=0, roughness=3, name='D2O Subphase')\n", "\n", - "resolution_function = percentage_fhwm_resolution_function(0.02)\n", + "resolution_function = PercentageFhwm(0.02)\n", "sample = Sample(superphase, solvated_film_layer, subphase, name='Film Structure')\n", "model = Model(\n", " sample=sample,\n", @@ -339,7 +340,7 @@ "id": "0e2fbca8-3717-4fee-8854-f081dd79c4c3", "metadata": {}, "source": [ - "The fit reproducing the measured reflectivity curve yields that the scattering length density (SLD) of the layer is 2.36E-6 Å-2. Remember this layer is composed of 75% of the polymer film layer (SLD of 1.026E-6 Å-2 fitted) and 25% of D2O (SLD of 6.36E-6 Å-2 known) making (0.75 * 1.026 + 0.25 * 6.36)E-6 = 2.36E-6 Å-2. This is the same as the result from the [previous tutorial](./simple_fitting.rst)." + "The fit reproducing the measured reflectivity curve yields that the scattering length density (SLD) of the layer is 2.36E-6 Å-2. Remember this layer is composed of 75% of the polymer film layer (SLD of 1.026E-6 Å-2 fitted) and 25% of D2O (SLD of 6.36E-6 Å-2 known) making (0.75 * 1.026 + 0.25 * 6.36)E-6 = 2.36E-6 Å-2. This is the same as the result from the [previous tutorial](../fitting/simple_fitting.rst)." ] } ], diff --git a/docs/src/tutorials/_static/resolution/mod_pointwise_two_layer_sample_dq-0.0.ort b/docs/src/tutorials/sample/mod_pointwise_two_layer_sample_dq-0.0.ort similarity index 100% rename from docs/src/tutorials/_static/resolution/mod_pointwise_two_layer_sample_dq-0.0.ort rename to docs/src/tutorials/sample/mod_pointwise_two_layer_sample_dq-0.0.ort diff --git a/docs/src/tutorials/_static/resolution/mod_pointwise_two_layer_sample_dq-1.0.ort b/docs/src/tutorials/sample/mod_pointwise_two_layer_sample_dq-1.0.ort similarity index 100% rename from docs/src/tutorials/_static/resolution/mod_pointwise_two_layer_sample_dq-1.0.ort rename to docs/src/tutorials/sample/mod_pointwise_two_layer_sample_dq-1.0.ort diff --git a/docs/src/tutorials/_static/resolution/mod_pointwise_two_layer_sample_dq-10.0.ort b/docs/src/tutorials/sample/mod_pointwise_two_layer_sample_dq-10.0.ort similarity index 100% rename from docs/src/tutorials/_static/resolution/mod_pointwise_two_layer_sample_dq-10.0.ort rename to docs/src/tutorials/sample/mod_pointwise_two_layer_sample_dq-10.0.ort diff --git a/docs/src/tutorials/monolayer.ipynb b/docs/src/tutorials/sample/monolayer.ipynb similarity index 95% rename from docs/src/tutorials/monolayer.ipynb rename to docs/src/tutorials/sample/monolayer.ipynb index 1ea063fd..837117e1 100644 --- a/docs/src/tutorials/monolayer.ipynb +++ b/docs/src/tutorials/sample/monolayer.ipynb @@ -8,7 +8,7 @@ "# Investigation of a surfactant monolayer\n", "\n", "A common system that is studied with neutron and X-ray reflectometry are surfactant monolayers. \n", - "In this tutorial, we will look at how the `easyreflectometry` assembly `SurfactantLayer` ([detailed here](../sample/assemblies_library.rst#surfactantlayer)) can be used to model a phospholipid bilayer. \n", + "In this tutorial, we will look at how the `easyreflectometry` assembly `SurfactantLayer` ([detailed here](../../sample/assemblies_library.rst#surfactantlayer)) can be used to model a phospholipid bilayer. \n", "First, we will import the relevant packages and functions." ] }, @@ -41,7 +41,7 @@ "from easyreflectometry.sample import Layer\n", "from easyreflectometry.sample import Sample\n", "from easyreflectometry.experiment import Model\n", - "from easyreflectometry.experiment import percentage_fhwm_resolution_function\n", + "from easyreflectometry.experiment import PercentageFhwm\n", "from easyreflectometry.fitting import Fitter\n", "from easyreflectometry.plot import plot\n", "\n" @@ -73,7 +73,7 @@ "source": [ "## Reading in experimental data\n", "\n", - "As has been [shown previously](./simple_fitting.rst), we use the `load` function to read in our experimental data. \n", + "As has been [shown previously](../fitting/simple_fitting.rst), we use the `load` function to read in our experimental data. \n", "For this tutorial we will be looking at [DSPC](https://en.wikipedia.org/wiki/Distearoylphosphatidylcholine), a phospholipid molecule that will self-assemble into a monolayer at the air-water interface. \n", "The data being used has kindly been shared by the authors of [previous work on the system](#hollinshead2009). " ] @@ -85,7 +85,7 @@ "metadata": {}, "outputs": [], "source": [ - "data = load('_static/d70d2o.ort')\n", + "data = load('d70d2o.ort')\n", "plot(data)" ] }, @@ -101,7 +101,7 @@ "A graphical representation of the slab model for a phosphoplipid monolayer is shown below.\n", "\n", "
\n", - " A slab model description for a phospholipid monolayer.\n", + " A slab model description for a phospholipid monolayer.\n", "
\n", "
\n", " A slab model description for a phospholipid monolayer, showing the head and tail layers.\n", @@ -143,7 +143,7 @@ "Now we can create the `SurfactantLayer` object, this takes a large number of parameters, that we will introduce gradually. \n", "\n", "
\n", - " The chemical structure for the DSPC molecule.\n", + " The chemical structure for the DSPC molecule.\n", "
\n", "
\n", " The chemical structure for the DSPC molecule. By Graeme Bartlett - Self Drawn, CC0\n", @@ -317,7 +317,7 @@ "metadata": {}, "outputs": [], "source": [ - "resolution_function = percentage_fhwm_resolution_function(5)\n", + "resolution_function = PercentageFhwm(5)\n", "sample = Sample(air_layer, dspc, d2o_layer)\n", "model = Model(\n", " sample=sample,\n", diff --git a/docs/src/tutorials/_static/monolayer.png b/docs/src/tutorials/sample/monolayer.png similarity index 100% rename from docs/src/tutorials/_static/monolayer.png rename to docs/src/tutorials/sample/monolayer.png diff --git a/docs/src/tutorials/_static/monolayer.svg b/docs/src/tutorials/sample/monolayer.svg similarity index 100% rename from docs/src/tutorials/_static/monolayer.svg rename to docs/src/tutorials/sample/monolayer.svg diff --git a/docs/src/tutorials/multi_contrast.ipynb b/docs/src/tutorials/sample/multi_contrast.ipynb similarity index 98% rename from docs/src/tutorials/multi_contrast.ipynb rename to docs/src/tutorials/sample/multi_contrast.ipynb index d15ce79b..72035055 100644 --- a/docs/src/tutorials/multi_contrast.ipynb +++ b/docs/src/tutorials/sample/multi_contrast.ipynb @@ -39,7 +39,7 @@ "from easyreflectometry.sample import LayerAreaPerMolecule\n", "from easyreflectometry.sample import Sample\n", "from easyreflectometry.experiment import Model\n", - "from easyreflectometry.experiment import percentage_fhwm_resolution_function\n", + "from easyreflectometry.experiment import PercentageFhwm\n", "from easyreflectometry.calculators import CalculatorFactory\n", "from easyreflectometry.fitting import Fitter\n", "print(f'easyreflectometry: {easyreflectometry.__version__}')\n", @@ -54,7 +54,8 @@ "## Reading in the experimental data\n", "\n", "We load in three different isotopic contrast that are stored in a single `.ort` file. \n", - "This `.ort` file uses the [mutliple data set syntax](https://github.com/reflectivity/file_format/blob/master/specification.md#multiple-data-sets) to indicate that different measurements are present in a single file. " + "This `.ort` file uses the [mutliple data set syntax](https://github.com/reflectivity/file_format/blob/master/specification.md#multiple-data-sets) to indicate that different measurements are present in a single file.\n", + "Use link to [download](multiple.ort) the ort data." ] }, { @@ -64,7 +65,7 @@ "metadata": {}, "outputs": [], "source": [ - "data = load('_static/multiple.ort')" + "data = load('multiple.ort')" ] }, { @@ -405,7 +406,7 @@ "metadata": {}, "outputs": [], "source": [ - "resolution_function = percentage_fhwm_resolution_function(5)\n", + "resolution_function = PercentageFhwm(5)\n", "\n", "d13d2o_sample = Sample(air_layer, d13d2o, d2o_layer)\n", "d70d2o_sample = Sample(air_layer, d70d2o, d2o_layer)\n", diff --git a/docs/src/tutorials/_static/multiple.ort b/docs/src/tutorials/sample/multiple.ort similarity index 100% rename from docs/src/tutorials/_static/multiple.ort rename to docs/src/tutorials/sample/multiple.ort diff --git a/docs/src/tutorials/resolution_functions.ipynb b/docs/src/tutorials/sample/resolution_functions.ipynb similarity index 92% rename from docs/src/tutorials/resolution_functions.ipynb rename to docs/src/tutorials/sample/resolution_functions.ipynb index b2d6d062..555f2aff 100644 --- a/docs/src/tutorials/resolution_functions.ipynb +++ b/docs/src/tutorials/sample/resolution_functions.ipynb @@ -44,8 +44,8 @@ "from easyreflectometry.calculators import CalculatorFactory\n", "from easyreflectometry.data import load\n", "from easyreflectometry.experiment import Model\n", - "from easyreflectometry.experiment import percentage_fhwm_resolution_function\n", - "from easyreflectometry.experiment import linear_spline_resolution_function\n", + "from easyreflectometry.experiment import LinearSpline\n", + "from easyreflectometry.experiment import PercentageFhwm\n", "from easyreflectometry.sample import Layer\n", "from easyreflectometry.sample import Material\n", "from easyreflectometry.sample import Multilayer\n", @@ -83,7 +83,8 @@ "\n", "The data that we will investigate in this tutorial was generated with `Refnx` and are stored in `.ort` [format file](https://github.com/reflectivity/file_format/blob/master/specification.md) files. In this tutorial we are investigation how we can include resolution effects when simulating and reproducing data measured in an experiment. For an `.ort` file the resoultion data for reflectivity is stored in the fourth column.\n", "\n", - "IMPORTANT when using `easyreflectometry` functionality for loading an `.ort` file we store the resolution data as a variance (squared value). As a consequence one needs to take the squareroot of the loaded data to recover the raw values (fourth column)." + "IMPORTANT when using `easyreflectometry` functionality for loading an `.ort` file we store the resolution data as a variance (squared value). As a consequence one needs to take the squareroot of the loaded data to recover the raw values (fourth column).\n", + "Use links to [download 0.0](mod_pointwise_two_layer_sample_dq-0.0.ort), [download 1.0](mod_pointwise_two_layer_sample_dq-1.0.ort), and [download 10.0](mod_pointwise_two_layer_sample_dq-10.0.ort) ort data." ] }, { @@ -94,9 +95,9 @@ "outputs": [], "source": [ "dict_reference = {}\n", - "dict_reference['0'] = load(\"_static/resolution/mod_pointwise_two_layer_sample_dq-0.0.ort\")\n", - "dict_reference['1'] = load(\"_static/resolution/mod_pointwise_two_layer_sample_dq-1.0.ort\")\n", - "dict_reference['10'] = load('_static/resolution/mod_pointwise_two_layer_sample_dq-10.0.ort')" + "dict_reference['0'] = load(\"mod_pointwise_two_layer_sample_dq-0.0.ort\")\n", + "dict_reference['1'] = load(\"mod_pointwise_two_layer_sample_dq-1.0.ort\")\n", + "dict_reference['10'] = load('mod_pointwise_two_layer_sample_dq-10.0.ort')" ] }, { @@ -130,7 +131,7 @@ "We show the model that will be used graphically below. \n", "\n", "
\n", - " A slab model description of the two_layers system.\n", + " A slab model description of the two_layers system.\n", "
\n", "
\n", " A slab model description of the two layer.\n", @@ -170,7 +171,7 @@ "id": "f63ec440-089f-46cf-8ff5-be5012ad8dc8", "metadata": {}, "source": [ - "Then, to produce the two layered structure, we use the `Multilayer` [assembly type](../sample/assemblies_library.rst#Multilayer)." + "Then, to produce the two layered structure, we use the `Multilayer` [assembly type](../../sample/assemblies_library.rst#Multilayer)." ] }, { @@ -248,17 +249,17 @@ "outputs": [], "source": [ "resolution_function_dict = {}\n", - "resolution_function_dict['0'] = linear_spline_resolution_function(\n", + "resolution_function_dict['0'] = LinearSpline(\n", " q_data_points=dict_reference['0']['coords']['Qz_0'].values,\n", " fwhm_values=np.sqrt(dict_reference['0']['coords']['Qz_0'].variances),\n", ")\n", "\n", - "resolution_function_dict['1'] = linear_spline_resolution_function(\n", + "resolution_function_dict['1'] = LinearSpline(\n", " q_data_points=dict_reference['1']['coords']['Qz_0'].values,\n", " fwhm_values=np.sqrt(dict_reference['1']['coords']['Qz_0'].variances),\n", ")\n", "\n", - "resolution_function_dict['10'] = linear_spline_resolution_function(\n", + "resolution_function_dict['10'] = LinearSpline(\n", " q_data_points=dict_reference['10']['coords']['Qz_0'].values,\n", " fwhm_values=np.sqrt(dict_reference['10']['coords']['Qz_0'].variances),\n", ")" @@ -346,7 +347,7 @@ ")\n", "plt.plot(model_coords, model_data, 'k-', label=f'Variable', linewidth=5)\n", "\n", - "model.resolution_function = percentage_fhwm_resolution_function(1.0)\n", + "model.resolution_function = PercentageFhwm(1.0)\n", "model_data = model.interface().fit_func(\n", " model_coords,\n", " model.uid,\n", @@ -378,7 +379,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.8" + "version": "3.11.9" } }, "nbformat": 4, diff --git a/docs/src/tutorials/_static/two_layers.png b/docs/src/tutorials/sample/two_layers.png similarity index 100% rename from docs/src/tutorials/_static/two_layers.png rename to docs/src/tutorials/sample/two_layers.png diff --git a/docs/src/tutorials/_static/two_layers.svg b/docs/src/tutorials/sample/two_layers.svg similarity index 100% rename from docs/src/tutorials/_static/two_layers.svg rename to docs/src/tutorials/sample/two_layers.svg diff --git a/docs/src/tutorials/tutorials.rst b/docs/src/tutorials/tutorials.rst index 36f030d2..84f651a3 100644 --- a/docs/src/tutorials/tutorials.rst +++ b/docs/src/tutorials/tutorials.rst @@ -6,9 +6,9 @@ The tutorials associated with using :py:mod:`easyreflectometry` are collected he .. toctree:: :maxdepth: 1 - simple_fitting - repeating - material_solvated - monolayer - multi_contrast - resolution_functions \ No newline at end of file + fitting/simple_fitting + fitting/repeating + sample/material_solvated + sample/monolayer + sample/multi_contrast + sample/resolution_functions \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 6aa08943..45ca59eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,8 +56,9 @@ dev = [ docs = [ "myst_parser", "nbsphinx", - "sphinx_book_theme", "sphinx_autodoc_typehints", + "sphinx_book_theme", + "sphinx-copybutton", "toml" ] From d06ba7afecc87794f308904329092513025676ca Mon Sep 17 00:00:00 2001 From: Andreas Pedersen Date: Fri, 17 May 2024 08:27:41 +0200 Subject: [PATCH 6/7] pr response --- src/easyreflectometry/experiment/model_collection.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/easyreflectometry/experiment/model_collection.py b/src/easyreflectometry/experiment/model_collection.py index b248979f..373bb90e 100644 --- a/src/easyreflectometry/experiment/model_collection.py +++ b/src/easyreflectometry/experiment/model_collection.py @@ -16,12 +16,12 @@ class ModelCollection(BaseElementCollection): def __init__( self, - *models: Optional[list[Model]], + *models: Optional[tuple[Model]], name: str = 'EasyModels', interface=None, **kwargs, ): - if models == (): + if not models: models = [Model(interface=interface) for _ in range(SIZE_DEFAULT_COLLECTION)] super().__init__(name, interface, *models, **kwargs) self.interface = interface From 2ae5fdcbdd67477c3270faa51b536bf6dff2719d Mon Sep 17 00:00:00 2001 From: Andreas Pedersen <48797331+andped10@users.noreply.github.com> Date: Fri, 17 May 2024 08:41:20 +0200 Subject: [PATCH 7/7] Update __version__.py now v1.0.2 --- src/easyreflectometry/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/easyreflectometry/__version__.py b/src/easyreflectometry/__version__.py index cd7ca498..a6221b3d 100644 --- a/src/easyreflectometry/__version__.py +++ b/src/easyreflectometry/__version__.py @@ -1 +1 @@ -__version__ = '1.0.1' +__version__ = '1.0.2'