easyreflectometry 1.0.0__tar.gz → 1.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of easyreflectometry might be problematic. Click here for more details.

Files changed (51) hide show
  1. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/PKG-INFO +3 -3
  2. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/README.md +1 -2
  3. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/pyproject.toml +2 -1
  4. easyreflectometry-1.0.2/src/easyreflectometry/__version__.py +1 -0
  5. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/calculators/refl1d/wrapper.py +3 -3
  6. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/calculators/refnx/wrapper.py +3 -3
  7. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/calculators/wrapper_base.py +4 -5
  8. easyreflectometry-1.0.2/src/easyreflectometry/experiment/__init__.py +13 -0
  9. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/experiment/model.py +20 -19
  10. easyreflectometry-1.0.2/src/easyreflectometry/experiment/model_collection.py +60 -0
  11. easyreflectometry-1.0.2/src/easyreflectometry/experiment/resolution_functions.py +56 -0
  12. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/base_element_collection.py +14 -0
  13. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/sample.py +1 -1
  14. easyreflectometry-1.0.0/src/easyreflectometry/__version__.py +0 -1
  15. easyreflectometry-1.0.0/src/easyreflectometry/experiment/__init__.py +0 -13
  16. easyreflectometry-1.0.0/src/easyreflectometry/experiment/model_collection.py +0 -35
  17. easyreflectometry-1.0.0/src/easyreflectometry/experiment/resolution_functions.py +0 -51
  18. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/.gitignore +0 -0
  19. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/AUTHORS.rst +0 -0
  20. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/LICENSE +0 -0
  21. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/__init__.py +0 -0
  22. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/calculators/__init__.py +0 -0
  23. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/calculators/bornagain/calculator.py +0 -0
  24. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/calculators/bornagain/wrapper.py +0 -0
  25. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/calculators/calculator_base.py +0 -0
  26. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/calculators/factory.py +0 -0
  27. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/calculators/refl1d/calculator.py +0 -0
  28. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/calculators/refnx/calculator.py +0 -0
  29. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/data.py +0 -0
  30. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/fitting.py +0 -0
  31. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/main.py +0 -0
  32. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/measurement/data.py +0 -0
  33. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/parameter_utils.py +0 -0
  34. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/plot.py +0 -0
  35. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/__init__.py +0 -0
  36. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/assemblies/base_assembly.py +0 -0
  37. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/assemblies/gradient_layer.py +0 -0
  38. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/assemblies/multilayer.py +0 -0
  39. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/assemblies/repeating_multilayer.py +0 -0
  40. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/assemblies/surfactant_layer.py +0 -0
  41. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/base_core.py +0 -0
  42. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/elements/layers/layer.py +0 -0
  43. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/elements/layers/layer_area_per_molecule.py +0 -0
  44. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/elements/layers/layer_collection.py +0 -0
  45. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/elements/materials/material.py +0 -0
  46. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/elements/materials/material_collection.py +0 -0
  47. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/elements/materials/material_density.py +0 -0
  48. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/elements/materials/material_mixture.py +0 -0
  49. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/sample/elements/materials/material_solvated.py +0 -0
  50. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/special/calculations.py +0 -0
  51. {easyreflectometry-1.0.0 → easyreflectometry-1.0.2}/src/easyreflectometry/special/parsing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: easyreflectometry
3
- Version: 1.0.0
3
+ Version: 1.0.2
4
4
  Summary: A reflectometry python package built on the EasyScience framework.
5
5
  Project-URL: homepage, https://docs.easyreflectometry.org
6
6
  Project-URL: documentation, https://docs.easyreflectometry.org
@@ -72,13 +72,13 @@ Requires-Dist: myst-parser; extra == 'docs'
72
72
  Requires-Dist: nbsphinx; extra == 'docs'
73
73
  Requires-Dist: sphinx-autodoc-typehints; extra == 'docs'
74
74
  Requires-Dist: sphinx-book-theme; extra == 'docs'
75
+ Requires-Dist: sphinx-copybutton; extra == 'docs'
75
76
  Requires-Dist: toml; extra == 'docs'
76
77
  Description-Content-Type: text/markdown
77
78
 
78
79
  ![Logo](https://github.com/easyScience/EasyReflectometryLib/raw/master/docs/src/_static/logo.png)
79
80
  [![CI badge](https://github.com/easyScience/EasyReflectometryLib/actions/workflows/python-ci.yml/badge.svg)](https://github.com/easyScience/easyReflectometryLib/actions/workflows/python-ci.yml)
80
- [![PyPI badge](http://img.shields.io/pypi/v/EasyReflectometryLib.svg)](https://pypi.python.org/pypi/EasyReflectometryLib)
81
- [![Coverage badge](https://codecov.io/gh/easyScience/EasyReflectometryLib/branch/master/graph/badge.svg?token=LcnB8AMGkw)](https://codecov.io/gh/easyScience/EasyReflectometryLib)
81
+ [![PyPI badge](https://img.shields.io/pypi/v/easyreflectometry.svg)](https://pypi.python.org/pypi/easyreflectometry)
82
82
  [![Quality badge](https://www.codefactor.io/repository/github/easyscience/easyreflectometrylib/badge)](https://www.codefactor.io/repository/github/easyscience/easyreflectometrylib)
83
83
  [![Docs badge](https://img.shields.io/badge/docs-built-blue)](http://docs.easyreflectometry.org)
84
84
 
@@ -1,7 +1,6 @@
1
1
  ![Logo](https://github.com/easyScience/EasyReflectometryLib/raw/master/docs/src/_static/logo.png)
2
2
  [![CI badge](https://github.com/easyScience/EasyReflectometryLib/actions/workflows/python-ci.yml/badge.svg)](https://github.com/easyScience/easyReflectometryLib/actions/workflows/python-ci.yml)
3
- [![PyPI badge](http://img.shields.io/pypi/v/EasyReflectometryLib.svg)](https://pypi.python.org/pypi/EasyReflectometryLib)
4
- [![Coverage badge](https://codecov.io/gh/easyScience/EasyReflectometryLib/branch/master/graph/badge.svg?token=LcnB8AMGkw)](https://codecov.io/gh/easyScience/EasyReflectometryLib)
3
+ [![PyPI badge](https://img.shields.io/pypi/v/easyreflectometry.svg)](https://pypi.python.org/pypi/easyreflectometry)
5
4
  [![Quality badge](https://www.codefactor.io/repository/github/easyscience/easyreflectometrylib/badge)](https://www.codefactor.io/repository/github/easyscience/easyreflectometrylib)
6
5
  [![Docs badge](https://img.shields.io/badge/docs-built-blue)](http://docs.easyreflectometry.org)
7
6
 
@@ -56,8 +56,9 @@ dev = [
56
56
  docs = [
57
57
  "myst_parser",
58
58
  "nbsphinx",
59
- "sphinx_book_theme",
60
59
  "sphinx_autodoc_typehints",
60
+ "sphinx_book_theme",
61
+ "sphinx-copybutton",
61
62
  "toml"
62
63
  ]
63
64
 
@@ -0,0 +1 @@
1
+ __version__ = '1.0.2'
@@ -3,7 +3,7 @@ __author__ = 'github.com/arm61'
3
3
  from typing import Tuple
4
4
 
5
5
  import numpy as np
6
- from easyreflectometry.experiment.resolution_functions import is_percentage_fhwm_resolution_function
6
+ from easyreflectometry.experiment.resolution_functions import PercentageFhwm
7
7
  from refl1d import model
8
8
  from refl1d import names
9
9
 
@@ -145,9 +145,9 @@ class Refl1dWrapper(WrapperBase):
145
145
  :return: reflectivity calculated at q
146
146
  """
147
147
  sample = _build_sample(self.storage, model_name)
148
- dq_array = self._resolution_function(q_array)
148
+ dq_array = self._resolution_function.smearing(q_array)
149
149
 
150
- if is_percentage_fhwm_resolution_function(self._resolution_function):
150
+ if isinstance(self._resolution_function, PercentageFhwm):
151
151
  # Get percentage of Q and change from sigma to FWHM
152
152
  dq_array = dq_array * q_array / 100 / (2 * np.sqrt(2 * np.log(2)))
153
153
 
@@ -3,7 +3,7 @@ __author__ = 'github.com/arm61'
3
3
  from typing import Tuple
4
4
 
5
5
  import numpy as np
6
- from easyreflectometry.experiment.resolution_functions import is_percentage_fhwm_resolution_function
6
+ from easyreflectometry.experiment.resolution_functions import PercentageFhwm
7
7
  from refnx import reflect
8
8
 
9
9
  from ..wrapper_base import WrapperBase
@@ -129,8 +129,8 @@ class RefnxWrapper(WrapperBase):
129
129
  dq_type='pointwise',
130
130
  )
131
131
 
132
- dq_vector = self._resolution_function(q_array)
133
- if is_percentage_fhwm_resolution_function(self._resolution_function):
132
+ dq_vector = self._resolution_function.smearing(q_array)
133
+ if isinstance(self._resolution_function, PercentageFhwm):
134
134
  # FWHM Percentage resolution is constant given as
135
135
  # For a constant resolution percentage refnx supports to pass a scalar value rather than a vector
136
136
  dq_vector = dq_vector[0]
@@ -1,10 +1,9 @@
1
1
  from abc import abstractmethod
2
- from typing import Callable
3
2
 
4
3
  import numpy as np
5
4
 
6
- from easyreflectometry.experiment import DEFAULT_RESOLUTION_FWHM_PERCENTAGE
7
- from easyreflectometry.experiment import percentage_fhwm_resolution_function
5
+ from easyreflectometry.experiment import PercentageFhwm
6
+ from easyreflectometry.experiment import ResolutionFunction
8
7
 
9
8
 
10
9
  class WrapperBase:
@@ -16,7 +15,7 @@ class WrapperBase:
16
15
  'item': {},
17
16
  'model': {},
18
17
  }
19
- self._resolution_function = percentage_fhwm_resolution_function(DEFAULT_RESOLUTION_FWHM_PERCENTAGE)
18
+ self._resolution_function = PercentageFhwm()
20
19
 
21
20
  def reset_storage(self):
22
21
  """Reset the storage area to blank."""
@@ -205,7 +204,7 @@ class WrapperBase:
205
204
  item = getattr(item, key)
206
205
  return getattr(item, 'value')
207
206
 
208
- def set_resolution_function(self, resolution_function: Callable[[np.array], np.array]) -> None:
207
+ def set_resolution_function(self, resolution_function: ResolutionFunction) -> None:
209
208
  """Set the resolution function for the calculator.
210
209
 
211
210
  :param resolution_function: The resolution function
@@ -0,0 +1,13 @@
1
+ from .model import Model
2
+ from .model_collection import ModelCollection
3
+ from .resolution_functions import LinearSpline
4
+ from .resolution_functions import PercentageFhwm
5
+ from .resolution_functions import ResolutionFunction
6
+
7
+ __all__ = (
8
+ LinearSpline,
9
+ PercentageFhwm,
10
+ ResolutionFunction,
11
+ Model,
12
+ ModelCollection,
13
+ )
@@ -3,7 +3,6 @@ from __future__ import annotations
3
3
  __author__ = 'github.com/arm61'
4
4
 
5
5
  from numbers import Number
6
- from typing import Callable
7
6
  from typing import Union
8
7
 
9
8
  import numpy as np
@@ -11,14 +10,14 @@ import yaml
11
10
  from easyscience.Objects.ObjectClasses import BaseObj
12
11
  from easyscience.Objects.ObjectClasses import Parameter
13
12
 
14
- from easyreflectometry.experiment.resolution_functions import is_percentage_fhwm_resolution_function
15
13
  from easyreflectometry.parameter_utils import get_as_parameter
16
14
  from easyreflectometry.sample import BaseAssembly
17
15
  from easyreflectometry.sample import Layer
18
16
  from easyreflectometry.sample import LayerCollection
19
17
  from easyreflectometry.sample import Sample
20
18
 
21
- from .resolution_functions import percentage_fhwm_resolution_function
19
+ from .resolution_functions import PercentageFhwm
20
+ from .resolution_functions import ResolutionFunction
22
21
 
23
22
  DEFAULTS = {
24
23
  'scale': {
@@ -59,7 +58,7 @@ class Model(BaseObj):
59
58
  sample: Union[Sample, None] = None,
60
59
  scale: Union[Parameter, Number, None] = None,
61
60
  background: Union[Parameter, Number, None] = None,
62
- resolution_function: Union[Callable[[np.array], float], None] = None,
61
+ resolution_function: Union[ResolutionFunction, None] = None,
63
62
  name: str = 'EasyModel',
64
63
  interface=None,
65
64
  ):
@@ -69,7 +68,7 @@ class Model(BaseObj):
69
68
  :param scale: Scaling factor of profile.
70
69
  :param background: Linear background magnitude.
71
70
  :param name: Name of the model, defaults to 'EasyModel'.
72
- :param resolution_function: Resolution function, defaults to percentage_fhwm_resolution_function.
71
+ :param resolution_function: Resolution function, defaults to PercentageFhwm.
73
72
  :param interface: Calculator interface, defaults to `None`.
74
73
 
75
74
  """
@@ -77,7 +76,7 @@ class Model(BaseObj):
77
76
  if sample is None:
78
77
  sample = Sample(interface=interface)
79
78
  if resolution_function is None:
80
- resolution_function = percentage_fhwm_resolution_function(DEFAULTS['resolution']['value'])
79
+ resolution_function = PercentageFhwm(DEFAULTS['resolution']['value'])
81
80
 
82
81
  scale = get_as_parameter('scale', scale, DEFAULTS)
83
82
  background = get_as_parameter('background', background, DEFAULTS)
@@ -88,8 +87,6 @@ class Model(BaseObj):
88
87
  scale=scale,
89
88
  background=background,
90
89
  )
91
- if not callable(resolution_function):
92
- raise ValueError('Resolution function must be a callable.')
93
90
  self.resolution_function = resolution_function
94
91
  # Must be set after resolution function
95
92
  self.interface = interface
@@ -140,12 +137,12 @@ class Model(BaseObj):
140
137
  del self.sample[idx]
141
138
 
142
139
  @property
143
- def resolution_function(self) -> Callable[[np.array], np.array]:
140
+ def resolution_function(self) -> ResolutionFunction:
144
141
  """Return the resolution function."""
145
142
  return self._resolution_function
146
143
 
147
144
  @resolution_function.setter
148
- def resolution_function(self, resolution_function: Callable[[np.array], np.array]) -> None:
145
+ def resolution_function(self, resolution_function: ResolutionFunction) -> None:
149
146
  """Set the resolution function for the model."""
150
147
  self._resolution_function = resolution_function
151
148
  if self.interface is not None:
@@ -176,8 +173,8 @@ class Model(BaseObj):
176
173
  @property
177
174
  def _dict_repr(self) -> dict[str, dict[str, str]]:
178
175
  """A simplified dict representation."""
179
- if is_percentage_fhwm_resolution_function(self._resolution_function):
180
- resolution_value = self._resolution_function([0])[0]
176
+ if isinstance(self._resolution_function, PercentageFhwm):
177
+ resolution_value = self._resolution_function.as_dict()['constant']
181
178
  resolution = f'{resolution_value} %'
182
179
  else:
183
180
  resolution = 'function of Q'
@@ -204,21 +201,25 @@ class Model(BaseObj):
204
201
  if skip is None:
205
202
  skip = []
206
203
  this_dict = super().as_dict(skip=skip)
207
- this_dict['sample'] = self.sample.as_dict()
204
+ this_dict['sample'] = self.sample.as_dict(skip=skip)
205
+ this_dict['resolution_function'] = self.resolution_function.as_dict()
208
206
  return this_dict
209
207
 
210
208
  @classmethod
211
- def from_dict(cls, data: dict) -> Model:
209
+ def from_dict(cls, this_dict: dict) -> Model:
212
210
  """
213
211
  Create a Model from a dictionary.
214
212
 
215
- :param data: dictionary of the Model
213
+ :param this_dict: dictionary of the Model
216
214
  :return: Model
217
215
  """
218
- model = super().from_dict(data)
216
+ resolution_function = ResolutionFunction.from_dict(this_dict['resolution_function'])
217
+ del this_dict['resolution_function']
218
+ sample = Sample.from_dict(this_dict['sample'])
219
+ del this_dict['sample']
219
220
 
220
- # Ensure that the sample is also converted
221
- # TODO Should probably be handled in easyscience
222
- model.sample = model.sample.__class__.from_dict(data['sample'])
221
+ model = super().from_dict(this_dict)
223
222
 
223
+ model.sample = sample
224
+ model.resolution_function = resolution_function
224
225
  return model
@@ -0,0 +1,60 @@
1
+ from __future__ import annotations
2
+
3
+ __author__ = 'github.com/arm61'
4
+
5
+ from typing import Optional
6
+
7
+ from easyreflectometry.sample.base_element_collection import SIZE_DEFAULT_COLLECTION
8
+ from easyreflectometry.sample.base_element_collection import BaseElementCollection
9
+
10
+ from .model import Model
11
+
12
+
13
+ class ModelCollection(BaseElementCollection):
14
+ # Added in super().__init__
15
+ models: list[Model]
16
+
17
+ def __init__(
18
+ self,
19
+ *models: Optional[tuple[Model]],
20
+ name: str = 'EasyModels',
21
+ interface=None,
22
+ **kwargs,
23
+ ):
24
+ if not models:
25
+ models = [Model(interface=interface) for _ in range(SIZE_DEFAULT_COLLECTION)]
26
+ super().__init__(name, interface, *models, **kwargs)
27
+ self.interface = interface
28
+
29
+ def add_model(self, new_model: Model):
30
+ """
31
+ Add a model to the models.
32
+
33
+ :param new_model: New model to be added.
34
+ """
35
+ self.append(new_model)
36
+
37
+ def remove_model(self, idx: int):
38
+ """
39
+ Remove an model from the models.
40
+
41
+ :param idx: Index of the model to remove
42
+ """
43
+ del self[idx]
44
+
45
+ @classmethod
46
+ def from_dict(cls, this_dict: dict) -> ModelCollection:
47
+ """
48
+ Create an instance of a collection from a dictionary.
49
+
50
+ :param data: The dictionary for the collection
51
+ :return: An instance of the collection
52
+ """
53
+ collection = super().from_dict(this_dict) # type: ModelCollection
54
+
55
+ if len(collection) != len(this_dict['data']):
56
+ raise ValueError(f"Expected {len(collection)} models, got {len(this_dict['data'])}")
57
+ for i, model_data in enumerate(this_dict['data']):
58
+ collection[i] = Model.from_dict(model_data)
59
+
60
+ return collection
@@ -0,0 +1,56 @@
1
+ """Resolution functions for the resolution of the experiment.
2
+ When a percentage is provided we assume that the resolution is a
3
+ Gaussian distribution with a FWHM of the percentage of the q value.
4
+ To convert from a sigma value to a FWHM value we use the formula
5
+ FWHM = 2.35 * sigma [2 * np.sqrt(2 * np.log(2)) * sigma].
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from abc import abstractmethod
11
+ from typing import Union
12
+
13
+ import numpy as np
14
+
15
+ DEFAULT_RESOLUTION_FWHM_PERCENTAGE = 5.0
16
+
17
+
18
+ class ResolutionFunction:
19
+ @abstractmethod
20
+ def smearing(q: Union[np.array, float]) -> np.array: ...
21
+
22
+ @abstractmethod
23
+ def as_dict() -> dict: ...
24
+
25
+ @classmethod
26
+ def from_dict(cls, data: dict) -> ResolutionFunction:
27
+ if data['smearing'] == 'PercentageFhwm':
28
+ return PercentageFhwm(data['constant'])
29
+ if data['smearing'] == 'LinearSpline':
30
+ return LinearSpline(data['q_data_points'], data['fwhm_values'])
31
+ raise ValueError('Unknown resolution function type')
32
+
33
+
34
+ class PercentageFhwm:
35
+ def __init__(self, constant: Union[None, float] = None):
36
+ if constant is None:
37
+ constant = DEFAULT_RESOLUTION_FWHM_PERCENTAGE
38
+ self.constant = constant
39
+
40
+ def smearing(self, q: Union[np.array, float]) -> np.array:
41
+ return np.ones(np.array(q).size) * self.constant
42
+
43
+ def as_dict(self) -> dict:
44
+ return {'smearing': 'PercentageFhwm', 'constant': self.constant}
45
+
46
+
47
+ class LinearSpline:
48
+ def __init__(self, q_data_points: np.array, fwhm_values: np.array):
49
+ self.q_data_points = q_data_points
50
+ self.fwhm_values = fwhm_values
51
+
52
+ def smearing(self, q: Union[np.array, float]) -> np.array:
53
+ return np.interp(q, self.q_data_points, self.fwhm_values)
54
+
55
+ def as_dict(self) -> dict:
56
+ return {'smearing': 'LinearSpline', 'q_data_points': self.q_data_points, 'fwhm_values': self.fwhm_values}
@@ -1,4 +1,6 @@
1
1
  from typing import Any
2
+ from typing import List
3
+ from typing import Optional
2
4
 
3
5
  import yaml
4
6
  from easyscience.Objects.Groups import BaseCollection
@@ -48,6 +50,18 @@ class BaseElementCollection(BaseCollection):
48
50
  """
49
51
  return {self.name: [i._dict_repr for i in self]}
50
52
 
53
+ def as_dict(self, skip: Optional[List[str]] = None) -> dict:
54
+ """
55
+ Create a dictionary representation of the collection.
56
+
57
+ :return: A dictionary representation of the collection
58
+ """
59
+ this_dict = super().as_dict(skip=skip)
60
+ this_dict['data'] = []
61
+ for collection_element in self:
62
+ this_dict['data'].append(collection_element.as_dict(skip=skip))
63
+ return this_dict
64
+
51
65
  @classmethod
52
66
  def from_dict(cls, data: dict) -> Any:
53
67
  """
@@ -69,7 +69,7 @@ class Sample(BaseCollection):
69
69
  skip = []
70
70
  this_dict = super().as_dict(skip=skip)
71
71
  for i, layer in enumerate(self.data):
72
- this_dict['data'][i] = layer.as_dict()
72
+ this_dict['data'][i] = layer.as_dict(skip=skip)
73
73
  return this_dict
74
74
 
75
75
  @classmethod
@@ -1 +0,0 @@
1
- __version__ = '1.0.0'
@@ -1,13 +0,0 @@
1
- from .model import Model
2
- from .model_collection import ModelCollection
3
- from .resolution_functions import DEFAULT_RESOLUTION_FWHM_PERCENTAGE
4
- from .resolution_functions import linear_spline_resolution_function
5
- from .resolution_functions import percentage_fhwm_resolution_function
6
-
7
- __all__ = (
8
- DEFAULT_RESOLUTION_FWHM_PERCENTAGE,
9
- percentage_fhwm_resolution_function,
10
- linear_spline_resolution_function,
11
- Model,
12
- ModelCollection,
13
- )
@@ -1,35 +0,0 @@
1
- __author__ = 'github.com/arm61'
2
-
3
- from typing import Optional
4
-
5
- from easyreflectometry.sample.base_element_collection import SIZE_DEFAULT_COLLECTION
6
- from easyreflectometry.sample.base_element_collection import BaseElementCollection
7
-
8
- from .model import Model
9
-
10
-
11
- class ModelCollection(BaseElementCollection):
12
- # Added in super().__init__
13
- models: list[Model]
14
-
15
- def __init__(self, *models: Optional[list[Model]], name: str = 'EasyModels', interface=None, **kwargs):
16
- if models is None:
17
- models = [Model(interface=interface) for _ in range(SIZE_DEFAULT_COLLECTION)]
18
- super().__init__(name, *models, **kwargs)
19
- self.interface = interface
20
-
21
- def add_model(self, new_model: Model):
22
- """
23
- Add a model to the models.
24
-
25
- :param new_model: New model to be added.
26
- """
27
- self.append(new_model)
28
-
29
- def remove_model(self, idx: int):
30
- """
31
- Remove an model from the models.
32
-
33
- :param idx: Index of the model to remove
34
- """
35
- del self[idx]
@@ -1,51 +0,0 @@
1
- """Resolution functions for the resolution of the experiment.
2
- When a percentage is provided we assume that the resolution is a
3
- Gaussian distribution with a FWHM of the percentage of the q value.
4
- To convert from a sigma value to a FWHM value we use the formula
5
- FWHM = 2.35 * sigma [2 * np.sqrt(2 * np.log(2)) * sigma].
6
- """
7
-
8
- from typing import Callable
9
- from typing import Union
10
-
11
- import numpy as np
12
-
13
- DEFAULT_RESOLUTION_FWHM_PERCENTAGE = 5.0
14
-
15
-
16
- def percentage_fhwm_resolution_function(constant: float) -> Callable[[np.array], np.array]:
17
- """Create a resolution function that is constant across the q range.
18
-
19
- :param constant: The constant resolution value.
20
- """
21
-
22
- def _constant(q: Union[np.array, float]) -> np.array:
23
- """Function that calculates the resolution at a given q value.
24
-
25
- The function uses the data points from the encapsulating function and produces a linearly interpolated between them.
26
- """
27
- return np.ones(np.array(q).size) * constant
28
-
29
- return _constant
30
-
31
-
32
- def linear_spline_resolution_function(q_data_points: np.array, fwhm_values: np.array) -> Callable[[np.array], np.array]:
33
- """Create a resolution function that is linearly interpolated between given data points.
34
-
35
- :param q_data_points: The q values at which the resolution is defined.
36
- :param fwhm_values: The resolution values at the given q values.
37
- """
38
-
39
- def _linear(q: np.array) -> np.array:
40
- """Function that calculates the resolution at a given q value.
41
-
42
- The function uses the data points from the encapsulating function and produces a linearly interpolated between them.
43
- """
44
- return np.interp(q, q_data_points, fwhm_values)
45
-
46
- return _linear
47
-
48
-
49
- def is_percentage_fhwm_resolution_function(resolution_function: Callable[[np.array], np.array]) -> bool:
50
- """Check if the resolution function is a constant."""
51
- return 'constant' in resolution_function.__name__