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",
- " \n",
+ " \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",
- " \n",
+ " \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",
- " \n",
+ " \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",
- " \n",
+ " \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",
- " \n",
+ " \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"
]
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'
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..22d9d0db 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'
@@ -204,21 +201,25 @@ 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
@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 = 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 fb0f8b04..373bb90e 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
@@ -14,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 is None:
+ if not models:
models = [Model(interface=interface) for _ in range(SIZE_DEFAULT_COLLECTION)]
super().__init__(name, interface, *models, **kwargs)
self.interface = interface
@@ -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/src/easyreflectometry/experiment/resolution_functions.py b/src/easyreflectometry/experiment/resolution_functions.py
index ce7598bf..f6bcc56b 100644
--- a/src/easyreflectometry/experiment/resolution_functions.py
+++ b/src/easyreflectometry/experiment/resolution_functions.py
@@ -5,7 +5,9 @@
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 Union
import numpy as np
@@ -13,39 +15,42 @@
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.
-
- :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.
+class ResolutionFunction:
+ @abstractmethod
+ def smearing(q: Union[np.array, float]) -> np.array: ...
- 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
+ @abstractmethod
+ def as_dict() -> dict: ...
- return _constant
+ @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')
-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.
+class PercentageFhwm:
+ def __init__(self, constant: Union[None, float] = None):
+ if constant is None:
+ constant = DEFAULT_RESOLUTION_FWHM_PERCENTAGE
+ self.constant = constant
- :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 smearing(self, q: Union[np.array, float]) -> np.array:
+ return np.ones(np.array(q).size) * self.constant
- def _linear(q: np.array) -> np.array:
- """Function that calculates the resolution at a given q value.
+ def as_dict(self) -> dict:
+ return {'smearing': 'PercentageFhwm', 'constant': self.constant}
- 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
+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 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 as_dict(self) -> dict:
+ return {'smearing': 'LinearSpline', 'q_data_points': self.q_data_points, 'fwhm_values': self.fwhm_values}
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/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_model_collection.py b/tests/experiment/test_model_collection.py
new file mode 100644
index 00000000..11c3ba71
--- /dev/null
+++ b/tests/experiment/test_model_collection.py
@@ -0,0 +1,92 @@
+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}
+
+ 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/experiment/test_resolution_functions.py b/tests/experiment/test_resolution_functions.py
index b8ccaf29..a34f95b4 100644
--- a/tests/experiment/test_resolution_functions.py
+++ b/tests/experiment/test_resolution_functions.py
@@ -1,17 +1,76 @@
+import unittest
+
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 ResolutionFunction
+
+
+class TestPercentageFhwm(unittest.TestCase):
+ def test_constructor(self):
+ # When
+ resolution_function = PercentageFhwm(1.0)
+
+ # 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()
+
+ # 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_as_dict(self):
+ # When
+ resolution_function = PercentageFhwm(1.0)
+
+ # Then Expect
+ resolution_function.as_dict() == {'smearing': 'PercentageFhwm', 'constant': 1.0}
+
+ def test_dict_round_trip(self):
+ # When
+ expected_resolution_function = PercentageFhwm(1.0)
+ res_dict = expected_resolution_function.as_dict()
+
+ # Then
+ resolution_function = ResolutionFunction.from_dict(res_dict)
+
+ # Expect
+ assert all(resolution_function.smearing([0, 2.5]) == expected_resolution_function.smearing([0, 2.5]))
+
+
+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_as_dict(self):
+ # 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]}
-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_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()
+ # Then
+ resolution_function = ResolutionFunction.from_dict(res_dict)
-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 all(resolution_function.smearing([0, 2.5]) == expected_resolution_function.smearing([0, 2.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 == {
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)