Skip to content

Commit

Permalink
Merge pull request #206 from EasyScience/develop
Browse files Browse the repository at this point in the history
Release 1.3.0
  • Loading branch information
andped10 authored Nov 27, 2024
2 parents edada37 + a22872c commit 62acfcc
Show file tree
Hide file tree
Showing 24 changed files with 113 additions and 211 deletions.
2 changes: 1 addition & 1 deletion docs/src/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
usage
sample/sample
calculators
experiment/experiment
model/model
tutorials/tutorials
dictionary
contributing
Expand Down
58 changes: 29 additions & 29 deletions docs/src/experiment/experiment.rst → docs/src/model/model.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Experiment
==========
Model
=====

The main component of an experiment in :py:mod:`easyreflectometry` is the :py:class:`Model`.
This is a description of the :py:class:`Sample` and the environment in which the experiment is performed.
Expand All @@ -14,19 +14,19 @@ To be able to compute reflectivities it is also necessary to have a :py:class:`C

.. code-block:: python
from easyreflectometry.calculators import CalculatorFactory
from easyreflectometry.experiment import Model
from easyreflectometry.sample import Sample
from easyreflectometry.calculators import CalculatorFactory
from easyreflectometry.model import Model
from easyreflectometry.sample import Sample
default_sample = Sample()
m = Model(
sample=default_sample,
scale=1.0,
background=1e-6
)
default_sample = Sample()
model = Model(
sample=default_sample,
scale=1.0,
background=1e-6
)
interface = CalculatorFactory()
model.interface = interface
interface = CalculatorFactory()
model.interface = interface
This will create a :py:class:`Model` instance with the :py:attr:`default_sample` and the environment variables :py:attr:`scale` factor set to 1.0 and a :py:attr:`background` of 1e-6.
Following the :py:attr:`interface` is set to the default calculator that is :py:class:`Refnx`.
Expand All @@ -39,42 +39,42 @@ In its essence the resolution function controls the smearing to apply when deter
For a given Q-point the smearing to apply is given as a weighted average of the neighboring Q-point, which weigths are by a normal distribution.
This normal distribution is then defined by a Q-point dependent Full Width at the Half Maximum (FWHM) that is given by the resolution function.

:py:func:`percentage_fhwm_resolution_function`
:py:class:`PercentageFwhm`
Often we rely on a resolution function that has a simple functional dependecy of the Q-point.
By this is understood that the applied smearing in an Q-point has a FWHM that is simply a percentage of the value of the Q-point.

.. code-block:: python
from easyreflectometry.experiment import Model
from easyreflectometry.experiment import percentage_fhwm_resolution_function
from easyreflectometry.model import Model
from easyreflectometry.model import PercentageFwhm
resolution_function = percentage_fhwm_resolution_function(1.1)
resolution_function = PercentageFwhm(1.1)
m = Model(
resolution_function=resolution_function
)
m = Model(
resolution_function=resolution_function
)
This will create a :py:class:`Model` instance where the resolution function is defined as 1.1% of the Q-point value, which again is the FWHM for the smearing.


:py:func:`linear_spline_resolution_function`
:py:func:`LinearSpline`
Alternatively the FWHM value might be determined and declared directly for each measured Q-point.
When this is the case the provided Q-points and the corresponding FWHM values can be used to declare a linear spline function
and thereby enable a determination of the reflectivity at an arbitrary point within the provided range of discrete Q-points.

.. code-block:: python
from easyreflectometry.experiment import Model
from easyreflectometry.experiment import linear_spline_resolution_function
from easyreflectometry.model import Model
from easyreflectometry.model import LinearSpline
m = Model()
m = Model()
resolution_function = linear_spline_resolution_function(
q_points=[0.01, 0.2, 0.31],
fwhm_values=[0.001, 0.043, 0.026]
)
resolution_function = LinearSpline(
q_data_points=[0.01, 0.2, 0.31],
fwhm_values=[0.001, 0.043, 0.026]
)
m.resolution_function = resolution_function
m.resolution_function = resolution_function
This will create a :py:class:`Model` instance where the resolution function defining the FWHM is determined from a linear interpolation.
In the present case the provided data Q-points are (`[0.01, 0.2, 0.31]`) and the corresponding FWHM function values are (`[0.001, 0.043, 0.026]`).
4 changes: 2 additions & 2 deletions docs/src/tutorials/fitting/repeating.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"from easyreflectometry.sample import RepeatingMultilayer\n",
"from easyreflectometry.sample import Multilayer\n",
"from easyreflectometry.model import Model\n",
"from easyreflectometry.model import PercentageFhwm\n",
"from easyreflectometry.model import PercentageFwhm\n",
"from easyreflectometry.calculators import CalculatorFactory\n",
"from easyreflectometry.fitting import Fitter\n",
"from easyreflectometry.plot import plot\n",
Expand Down Expand Up @@ -201,7 +201,7 @@
"metadata": {},
"outputs": [],
"source": [
"resolution_function = PercentageFhwm(0)\n",
"resolution_function = PercentageFwhm(0)\n",
"sample = Sample(Multilayer(superphase), rep_multilayer, Multilayer(subphase), name='Multilayer Structure')\n",
"model = Model(\n",
" sample=sample,\n",
Expand Down
4 changes: 2 additions & 2 deletions docs/src/tutorials/fitting/simple_fitting.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"from easyreflectometry.sample import Material\n",
"from easyreflectometry.sample import Multilayer\n",
"from easyreflectometry.model import Model\n",
"from easyreflectometry.model import PercentageFhwm\n",
"from easyreflectometry.model import PercentageFwhm\n",
"from easyreflectometry.calculators import CalculatorFactory\n",
"from easyreflectometry.fitting import Fitter\n",
"from easyreflectometry.plot import plot"
Expand Down Expand Up @@ -306,7 +306,7 @@
"metadata": {},
"outputs": [],
"source": [
"resolution_function = PercentageFhwm(0.02)\n",
"resolution_function = PercentageFwhm(0.02)\n",
"model = Model(\n",
" sample=sample,\n",
" scale=1,\n",
Expand Down
4 changes: 2 additions & 2 deletions docs/src/tutorials/magnetism.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"\n",
"from easyreflectometry.calculators import CalculatorFactory\n",
"from easyreflectometry.model import Model\n",
"from easyreflectometry.model import PercentageFhwm\n",
"from easyreflectometry.model import PercentageFwhm\n",
"from easyreflectometry.sample import Layer\n",
"from easyreflectometry.sample import Material\n",
"from easyreflectometry.sample import Multilayer\n",
Expand Down Expand Up @@ -245,7 +245,7 @@
"# EasyReflectometry\n",
"interface.switch('refl1d')\n",
"model.interface = interface\n",
"model.resolution_function = PercentageFhwm(0)\n",
"model.resolution_function = PercentageFwhm(0)\n",
"model_interface = model.interface()\n",
"model_interface.magnetism = False\n",
"model_data_no_magnetism_ref1d_easy = model.interface().reflectity_profile(\n",
Expand Down
4 changes: 2 additions & 2 deletions docs/src/tutorials/sample/material_solvated.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"from easyreflectometry.sample import MaterialSolvated\n",
"from easyreflectometry.sample import Multilayer\n",
"from easyreflectometry.model import Model\n",
"from easyreflectometry.model import PercentageFhwm\n",
"from easyreflectometry.model import PercentageFwhm\n",
"from easyreflectometry.calculators import CalculatorFactory\n",
"from easyreflectometry.fitting import Fitter\n",
"from easyreflectometry.plot import plot"
Expand Down Expand Up @@ -191,7 +191,7 @@
"\n",
"subphase = Layer(material=d2o, thickness=0, roughness=3, name='D2O Subphase')\n",
"\n",
"resolution_function = PercentageFhwm(0.02)\n",
"resolution_function = PercentageFwhm(0.02)\n",
"sample = Sample(superphase, Multilayer(solvated_film), Multilayer(subphase), name='Film Structure')\n",
"model = Model(\n",
" sample=sample,\n",
Expand Down
4 changes: 2 additions & 2 deletions docs/src/tutorials/sample/monolayer.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"from easyreflectometry.sample import Multilayer\n",
"from easyreflectometry.sample import Sample\n",
"from easyreflectometry.model import Model\n",
"from easyreflectometry.model import PercentageFhwm\n",
"from easyreflectometry.model import PercentageFwhm\n",
"from easyreflectometry.fitting import Fitter\n",
"from easyreflectometry.plot import plot\n",
"from easyscience.fitting import AvailableMinimizers\n"
Expand Down Expand Up @@ -325,7 +325,7 @@
"metadata": {},
"outputs": [],
"source": [
"resolution_function = PercentageFhwm(5)\n",
"resolution_function = PercentageFwhm(5)\n",
"sample = Sample(Multilayer(air_layer), dspc, Multilayer(d2o_layer))\n",
"model = Model(\n",
" sample=sample,\n",
Expand Down
4 changes: 2 additions & 2 deletions docs/src/tutorials/sample/multi_contrast.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"from easyreflectometry.sample import LayerAreaPerMolecule\n",
"from easyreflectometry.sample import Sample\n",
"from easyreflectometry.model import Model\n",
"from easyreflectometry.model import PercentageFhwm\n",
"from easyreflectometry.model import PercentageFwhm\n",
"from easyreflectometry.calculators import CalculatorFactory\n",
"from easyreflectometry.fitting import Fitter\n",
"from easyscience.fitting import AvailableMinimizers\n",
Expand Down Expand Up @@ -417,7 +417,7 @@
"metadata": {},
"outputs": [],
"source": [
"resolution_function = PercentageFhwm(5)\n",
"resolution_function = PercentageFwhm(5)\n",
"\n",
"d13d2o_sample = Sample(Multilayer(air_layer), d13d2o, Multilayer(d2o_layer))\n",
"d70d2o_sample = Sample(Multilayer(air_layer), d70d2o, Multilayer(d2o_layer))\n",
Expand Down
138 changes: 20 additions & 118 deletions docs/src/tutorials/sample/resolution_functions.ipynb

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/easyreflectometry/calculators/refl1d/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from refl1d import model
from refl1d import names

from easyreflectometry.model import PercentageFhwm
from easyreflectometry.model import PercentageFwhm

from ..wrapper_base import WrapperBase

Expand Down Expand Up @@ -157,7 +157,7 @@ def calculate(self, q_array: np.ndarray, model_name: str) -> np.ndarray:
sample = _build_sample(self.storage, model_name)
dq_array = self._resolution_function.smearing(q_array)

if isinstance(self._resolution_function, PercentageFhwm):
if isinstance(self._resolution_function, PercentageFwhm):
# Get percentage of Q and change from sigma to FWHM
dq_array = dq_array * q_array / 100 / (2 * np.sqrt(2 * np.log(2)))

Expand Down
4 changes: 2 additions & 2 deletions src/easyreflectometry/calculators/refnx/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import numpy as np
from refnx import reflect

from easyreflectometry.model import PercentageFhwm
from easyreflectometry.model import PercentageFwhm

from ..wrapper_base import WrapperBase

Expand Down Expand Up @@ -143,7 +143,7 @@ def calculate(self, q_array: np.ndarray, model_name: str) -> np.ndarray:
)

dq_vector = self._resolution_function.smearing(q_array)
if isinstance(self._resolution_function, PercentageFhwm):
if isinstance(self._resolution_function, PercentageFwhm):
# 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]
Expand Down
4 changes: 2 additions & 2 deletions src/easyreflectometry/calculators/wrapper_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import numpy as np

from easyreflectometry.model import PercentageFhwm
from easyreflectometry.model import PercentageFwhm
from easyreflectometry.model import ResolutionFunction


Expand All @@ -16,7 +16,7 @@ def __init__(self):
'item': {},
'model': {},
}
self._resolution_function = PercentageFhwm()
self._resolution_function = PercentageFwhm()

def reset_storage(self):
"""Reset the storage area to blank."""
Expand Down
4 changes: 2 additions & 2 deletions src/easyreflectometry/model/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from .model import Model
from .model_collection import ModelCollection
from .resolution_functions import LinearSpline
from .resolution_functions import PercentageFhwm
from .resolution_functions import PercentageFwhm
from .resolution_functions import ResolutionFunction

__all__ = (
LinearSpline,
PercentageFhwm,
PercentageFwhm,
ResolutionFunction,
Model,
ModelCollection,
Expand Down
8 changes: 4 additions & 4 deletions src/easyreflectometry/model/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from easyreflectometry.utils import get_as_parameter
from easyreflectometry.utils import yaml_dump

from .resolution_functions import PercentageFhwm
from .resolution_functions import PercentageFwhm
from .resolution_functions import ResolutionFunction

DEFAULTS = {
Expand Down Expand Up @@ -71,7 +71,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 PercentageFhwm.
:param resolution_function: Resolution function, defaults to PercentageFwhm.
:param interface: Calculator interface, defaults to `None`.
"""
Expand All @@ -81,7 +81,7 @@ def __init__(
if sample is None:
sample = Sample(interface=interface)
if resolution_function is None:
resolution_function = PercentageFhwm(DEFAULTS['resolution']['value'])
resolution_function = PercentageFwhm(DEFAULTS['resolution']['value'])

scale = get_as_parameter('scale', scale, DEFAULTS)
background = get_as_parameter('background', background, DEFAULTS)
Expand Down Expand Up @@ -168,7 +168,7 @@ def interface(self, new_interface) -> None:
@property
def _dict_repr(self) -> dict[str, dict[str, str]]:
"""A simplified dict representation."""
if isinstance(self._resolution_function, PercentageFhwm):
if isinstance(self._resolution_function, PercentageFwhm):
resolution_value = self._resolution_function.as_dict()['constant']
resolution = f'{resolution_value} %'
else:
Expand Down
8 changes: 4 additions & 4 deletions src/easyreflectometry/model/resolution_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ def as_dict(self, skip: Optional[List[str]] = None) -> dict: ...

@classmethod
def from_dict(cls, data: dict) -> ResolutionFunction:
if data['smearing'] == 'PercentageFhwm':
return PercentageFhwm(data['constant'])
if data['smearing'] == 'PercentageFwhm':
return PercentageFwhm(data['constant'])
if data['smearing'] == 'LinearSpline':
return LinearSpline(data['q_data_points'], data['fwhm_values'])
raise ValueError('Unknown resolution function type')


class PercentageFhwm(ResolutionFunction):
class PercentageFwhm(ResolutionFunction):
def __init__(self, constant: Union[None, float] = None):
if constant is None:
constant = DEFAULT_RESOLUTION_FWHM_PERCENTAGE
Expand All @@ -45,7 +45,7 @@ def smearing(self, q: Union[np.array, float]) -> np.array:
def as_dict(
self, skip: Optional[List[str]] = None
) -> dict[str, str]: # skip is kept for consistency of the as_dict signature
return {'smearing': 'PercentageFhwm', 'constant': self.constant}
return {'smearing': 'PercentageFwhm', 'constant': self.constant}


class LinearSpline(ResolutionFunction):
Expand Down
4 changes: 2 additions & 2 deletions src/easyreflectometry/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from easyreflectometry.model import LinearSpline
from easyreflectometry.model import Model
from easyreflectometry.model import ModelCollection
from easyreflectometry.model import PercentageFhwm
from easyreflectometry.model import PercentageFwhm
from easyreflectometry.sample import Layer
from easyreflectometry.sample import Material
from easyreflectometry.sample import MaterialCollection
Expand Down Expand Up @@ -266,7 +266,7 @@ def sld_data_for_model_at_index(self, index: int = 0) -> DataSet1D:

def sample_data_for_model_at_index(self, index: int = 0, q_range: Optional[np.array] = None) -> DataSet1D:
original_resolution_function = self.models[index].resolution_function
self.models[index].resolution_function = PercentageFhwm(0)
self.models[index].resolution_function = PercentageFwhm(0)
reflectivity_data = self.model_data_for_model_at_index(index, q_range)
self.models[index].resolution_function = original_resolution_function

Expand Down
2 changes: 1 addition & 1 deletion src/easyreflectometry/summary/summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def _experiments_section(self) -> str:
experiment_name = experiment.name
num_data_points = len(experiment.x)
resolution_function = self._project.models[idx].resolution_function.as_dict()['smearing']
if resolution_function == 'PercentageFhwm':
if resolution_function == 'PercentageFwhm':
precentage = self._project.models[idx].resolution_function.as_dict()['constant']
resolution_function = f'{resolution_function} {precentage}%'
range_min = min(experiment.y)
Expand Down
Loading

0 comments on commit 62acfcc

Please sign in to comment.