From d1c20a4151ab04f5fb273144925302d99aa73e43 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Tue, 14 Oct 2025 19:54:57 +0200 Subject: [PATCH 01/71] Add basic sample_model and tests --- src/easydynamics/sample_model/sample_model.py | 473 ++++++++++++++++++ .../sample_model/test_sample_model.py | 261 ++++++++++ 2 files changed, 734 insertions(+) create mode 100644 src/easydynamics/sample_model/sample_model.py create mode 100644 tests/unit_tests/sample_model/test_sample_model.py diff --git a/src/easydynamics/sample_model/sample_model.py b/src/easydynamics/sample_model/sample_model.py new file mode 100644 index 0000000..60310cc --- /dev/null +++ b/src/easydynamics/sample_model/sample_model.py @@ -0,0 +1,473 @@ + +from typing import Dict, List, Union, Tuple + +import numpy as np + +from easyscience.variable import Parameter +from easyscience.base_classes import ObjBase + +from easydynamics.utils import detailed_balance_factor +from .components import ModelComponent + +import scipp as sc + + +class SampleModel(ObjBase): + """ + A model of the scattering from a sample, combining multiple model components. + Optionally applies detailed balancing. + + Attributes + ---------- + components : dict + Dictionary of model components keyed by name. + """ + def __init__(self, name: str = "MySampleModel", temperature: Union[float, None] = None): + """ + Initialize a new SampleModel. + + Parameters + ---------- + name : str + Name of the sample model. + temperature : float or None, optional + """ + + self.components: Dict[str, ModelComponent] = {} + super().__init__(name=name) + if temperature is not None: + self._temperature = Parameter(name="temperature", value=temperature, unit='K', fixed=True) + self._use_detailed_balance = True + else: + self._temperature=None + self._use_detailed_balance = False + + def add_component(self, component: ModelComponent): + """ + Add a model component to the SampleModel. Component names must be unique. + """ + if component.name in self.components: + raise ValueError(f"Component with name '{component.name}' already exists.") + self.components[component.name] = component + + def remove_component(self, name: str): + """ + Remove a model component by name. + + Parameters + ---------- + name : str + Name of the component to remove. + + """ + if name not in self.components: + raise KeyError(f"No component named '{name}' exists in the model.") + del self.components[name] + + def list_components(self) -> List[str]: + """ + List the names of all components in the model. + + Returns + ------- + List[str] + Component names. + """ + return list(self.components.keys()) + + def clear_components(self): + """ + Remove all components from the model. + """ + self.components.clear() + + def __getitem__(self, key: str) -> ModelComponent: + """ + Access a component by name. + + Parameters + ---------- + key : str + Name of the component. + + Returns + ------- + ModelComponent + """ + return self.components[key] + + def __setitem__(self, key: str, value: ModelComponent): + """ + Set or replace a component by name using dictionary-like syntax. + + Parameters + ---------- + key : str + Name of the component. + value : ModelComponent + The component to assign. + """ + self.components[key] = value + + def __contains__(self, name: str) -> bool: + """ + Check if a component exists in the model. + + Parameters + ---------- + name : str + Name of the component. + + Returns + ------- + bool + """ + return name in self.components + + def __repr__(self): + """ + Return a string representation of the SampleModel. + + Returns + ------- + str + """ + comp_names = ", ".join(self.components.keys()) or "No components" + temp_str = (f" | Temperature: {self._temperature.value} {self._temperature.unit}" + if self._use_detailed_balance else "") + return (f"") + + @property + def temperature(self) -> Parameter: + """ + Access the temperature parameter. + + Returns + ------- + Parameter + """ + return self._temperature + + @temperature.setter + def temperature(self, value: Union[float, None], unit: str = 'K'): + """ + Set the temperature and enables detailed balance if value is non-negative. + + Parameters + ---------- + value : float + Temperature value. + unit : str, default 'K' + Unit of the temperature. + """ + if value is None: + self._use_detailed_balance = False + self._temperature = None + return + + if value < 0: + raise ValueError("Temperature must be non-negative.") + + if isinstance(self._temperature, Parameter): + self._temperature.value = value + else: + self._temperature = Parameter(name="temperature", value=value, unit=unit, fixed=True) + + if not self.use_detailed_balance: + self.use_detailed_balance = value >= 0 + + @property + def use_detailed_balance(self) -> bool: + """ + Indicates whether detailed balance is enabled. + + Returns + ------- + bool + """ + return self._use_detailed_balance + + @use_detailed_balance.setter + def use_detailed_balance(self, value: bool): + """ + Enable or disable the use of detailed balance. + + Parameters + ---------- + value : bool + True to enable, False to disable. + """ + self._use_detailed_balance = value + + def evaluate(self, x: Union[float,np.ndarray,sc.Variable]) -> np.ndarray: + """ + Evaluate the sum of all components, optionally applying detailed balance. + + Parameters + ---------- + x : np.ndarray or scipp.array + + Returns + ------- + np.ndarray + Evaluated model values. + """ + result = np.zeros_like(x, dtype=float) + for component in self.components.values(): + result += component.evaluate(x) + + #TODO: handle units properly + if self.use_detailed_balance and self._temperature.value >= 0: + result *= detailed_balance_factor(x, self._temperature.value) + + return result + + def evaluate_component(self, name: str, x: Union[float,np.ndarray,sc.Variable]) -> np.ndarray: + """ + Evaluate a single component by name, optionally applying detailed balance. + + Parameters + ---------- + name : str + Component name. + x : np.ndarray + Energy axis. + + Returns + ------- + np.ndarray + Evaluated values for the specified component. + + Raises + ------ + KeyError + If the component is not found. + """ + if name not in self.components: + raise KeyError(f"No component named '{name}' exists.") + + result = self.components[name].evaluate(x) + if self._use_detailed_balance and self._temperature.value >= 0: + result *= detailed_balance_factor(x, self._temperature.value) + + return result + + def normalize_area(self): + """ + Normalize the areas of all components so they sum to 1. + """ + area_params = [] + total_area = 0.0 + + for component in self.components.values(): + for param in component.get_parameters(): + if 'area' in param.name.lower(): + area_params.append(param) + total_area += param.value + + if total_area == 0: + raise ValueError("Total area is zero; cannot normalize.") + + for param in area_params: + param.value /= total_area + + def get_parameters(self) -> List[Parameter]: + """ + Return all parameters from the model, including temperature. + + Returns + ------- + List[Parameter] + """ + if isinstance(self._temperature, Parameter): + params = [self._temperature] + else: + params = [] + for comp in self.components.values(): + params.extend(comp.get_parameters()) + return params + + def get_fit_parameters(self): + """ + Get all fit parameters, removing fixed and dependent parameters. + + Returns: + List[Parameter]: A list of fit parameters. + """ + + parameters = self.get_parameters() + fit_parameters = [] + + for parameter in parameters: + is_not_fixed = not getattr(parameter, 'fixed', False) + is_independent = getattr(parameter, '_independent', True) + + if is_not_fixed and is_independent: + fit_parameters.append(parameter) + + return fit_parameters + + + def fix_all_parameters(self): + """ + Fix all unfixed parameters in the model. + """ + for param in self.get_parameters(): + param.fixed = True + + def free_all_parameters(self): + """ + Free all fixed parameters in the model. + """ + for param in self.get_parameters(): + param.fixed = False + + def fix_all_component_parameters(self,component_name: str): + """ + Fix all unfixed parameters in the specified component. + """ + if component_name not in self.components: + raise ValueError(f"Component '{component_name}' not found.") + + self.components[component_name].fix_all_parameters() + + def free_all_component_parameters(self, component_name: str): + """ + Free all fixed parameters in the specified component. + """ + if component_name not in self.components: + raise ValueError(f"Component '{component_name}' not found.") + + self.components[component_name].free_all_parameters() + + def fix_component_parameter(self,component_name: str, parameter_name: str): + """ + Fix a specific parameter in the specified component. + """ + if component_name not in self.components: + raise ValueError(f"Component '{component_name}' not found.") + + component = self.components[component_name] + param = component.get_parameter(parameter_name) + if param is None: + raise ValueError(f"Parameter '{parameter_name}' not found in component '{component_name}'.") + + param.fixed = True + + def free_component_parameter(self, component_name: str, parameter_name: str): + """ + Free a specific parameter in the specified component. + """ + if component_name not in self.components: + raise ValueError(f"Component '{component_name}' not found.") + + component = self.components[component_name] + param = component.get_parameter(parameter_name) + if param is None: + raise ValueError(f"Parameter '{parameter_name}' not found in component '{component_name}'.") + + param.fixed = False + + def update_values_from( + self, + other: "SampleModel", + *, + only_free: bool = True, + )-> Dict[str, Tuple[float, float]]: + """ + Overwrite this model's Parameter.values from another SampleModel, matching by + component name and Parameter.name. This is used to copy fit results when doing sequential fitting. + + Parameters + ---------- + other : SampleModel + Source of values. + only_free : bool, default True + If True, skip Parameters in *self* that are fixed. + + Returns + ------- + Dict[str, Tuple[float, float]] + Mapping key -> (old_value, new_value), where key is + ".". + + """ + if not isinstance(other, SampleModel): + raise TypeError("other must be a SampleModel") + + report: Dict[str, Tuple[float, float]] = {} + + # Check that components are the same + self_names = set(self.components.keys()) + other_names = set(other.components.keys()) + + if self_names != other_names: + missing = self_names - other_names + extra = other_names - self_names + raise ValueError( + f"Component name mismatch.\n" + f" Missing in source: {missing or '{}'}\n" + f" Extra in source: {extra or '{}'}" + ) + + + # Go through components + for cname in self_names: + c_self = self.components[cname] + c_other = other.components[cname] + + # Check that parameters are the same + self_params = {p.name: p for p in c_self.get_parameters()} + other_params = {p.name: p for p in c_other.get_parameters()} + + if set(self_params) != set(other_params): + missing = set(self_params) - set(other_params) + extra = set(other_params) - set(self_params) + raise ValueError( + f"Parameter name mismatch in component '{cname}'.\n" + f" Missing in source: {missing or '{}'}\n" + f" Extra in source: {extra or '{}'}" + ) + + + for pname in set(self_params): + p_self = self_params[pname] + p_other = other_params[pname] + + if only_free and getattr(p_self, "fixed", False): + continue + + # Units: convert units to other's unit if they differ + u_self = getattr(p_self, "unit", None) + u_other = getattr(p_other, "unit", None) + if u_self != u_other: + p_self.convert_unit(u_other) + + # Update value, but save the old one. + old = p_self.value + p_self.value = p_other.value + report[f"{cname}.{pname}"] = (old, p_self.value) + + return report + + + + def copy(self) -> "SampleModel": + """ + Create a deep copy of the SampleModel with independent parameters. + + Returns + ------- + SampleModel + A new instance with copied components and parameters. + """ + + new_model = SampleModel(name=self.name, temperature=self._temperature.value if self._temperature else None) + + new_model.use_detailed_balance = self._use_detailed_balance + + for comp in self.components.values(): + new_model.add_component(comp.copy()) + + return new_model diff --git a/tests/unit_tests/sample_model/test_sample_model.py b/tests/unit_tests/sample_model/test_sample_model.py new file mode 100644 index 0000000..bd9a606 --- /dev/null +++ b/tests/unit_tests/sample_model/test_sample_model.py @@ -0,0 +1,261 @@ +import pytest +import numpy as np +from scipy.integrate import simpson + +from easyscience.variable import Parameter +from easydynamics.sample import SampleModel, Gaussian, Lorentzian +from easydynamics.sample.components import ModelComponent +from easydynamics.utils import detailed_balance_factor + +class TestSampleModel: + @pytest.fixture + def sample_model(self): + return SampleModel(name="TestSampleModel") + + # ───── Component Management ───── + + def test_add_component(self, sample_model): + #When + component = Gaussian(name="TestComponent", area=1.0, center=0.0, width=1.0, unit='meV') + #Then + sample_model.add_component(component) + #Expect + assert "TestComponent" in sample_model.components + + def test_add_duplicate_component_raises(self, sample_model): + #When + component = Gaussian(name="Dup", area=1.0, center=0.0, width=1.0, unit='meV') + #Then + sample_model.add_component(component) + #Expect + with pytest.raises(ValueError, match="already exists"): + sample_model.add_component(component) + + def test_remove_component(self, sample_model): + #When + component = Gaussian(name="TestComponent", area=1.0, center=0.0, width=1.0, unit='meV') + #Then + sample_model.add_component(component) + sample_model.remove_component("TestComponent") + #Expect + assert "TestComponent" not in sample_model.components + + def test_remove_nonexistent_component_raises(self, sample_model): + #When Then Expect + with pytest.raises(KeyError, match="No component named 'NonExistentComponent' exists"): + sample_model.remove_component("NonExistentComponent") + + def test_getitem(self, sample_model): + #When + component = Gaussian(name="TestComponent", area=1.0, center=0.0, width=1.0, unit='meV') + #Then + sample_model.add_component(component) + #Expect + assert sample_model["TestComponent"] is component + + def test_setitem(self, sample_model): + #When + component = ModelComponent(name="TestComponent") + #Then + sample_model["TestComponent"] = component + #Expect + assert sample_model["TestComponent"] is component + + def test_contains_component(self, sample_model): + #When + component = Gaussian(name="TestGaussian", area=1.0, center=0.0, width=1.0, unit='meV') + #Then + sample_model.add_component(component) + #Expect + assert "TestGaussian" in sample_model + assert "NonExistentComponent" not in sample_model + + def test_list_components(self, sample_model): + #When + component1 = Gaussian(name="TestGaussian1", area=2.0, center=0.0, width=1.0, unit='meV') + component2 = Gaussian(name="TestGaussian2", area=3.0, center=1.0, width=0.5, unit='meV') + sample_model.add_component(component1) + sample_model.add_component(component2) + #Then + components = sample_model.list_components() + #Expect + assert len(components) == 2 + assert components[0] == 'TestGaussian1' + assert components[1] == 'TestGaussian2' + + def test_clear_components(self, sample_model): + #when + component1 = Gaussian(name="TestGaussian1", area=2.0, center=0.0, width=1.0, unit='meV') + component2 = Gaussian(name="TestGaussian2", area=3.0, center=1.0, width=0.5, unit='meV') + sample_model.add_component(component1) + sample_model.add_component(component2) + #Then + sample_model.clear_components() + #Expect + assert len(sample_model.components) == 0 + + # ───── Temperature and Detailed Balance ───── + + def test_temperature_init(self, sample_model): + # When Then Expect + assert sample_model._temperature is None + assert sample_model._use_detailed_balance is False + # assert sample_model._temperature.unit == 'K' + + def test_set_temperature(self, sample_model): + # When Then + sample_model.temperature = 300 + # Expect + assert sample_model._temperature.value == 300 + assert sample_model._temperature.unit == 'K' + assert sample_model._use_detailed_balance is True + + def test_negative_temperature_throws(self, sample_model): + # When + sample_model.use_detailed_balance = True + # Then Expect + with pytest.raises(ValueError, match="Temperature must be non-negative"): + sample_model.temperature = -50 + + def test_use_detailed_balance(self, sample_model): + # When Then Expect + assert sample_model._use_detailed_balance is False + sample_model._use_detailed_balance = True + assert sample_model._use_detailed_balance is True + sample_model._use_detailed_balance = False + assert sample_model._use_detailed_balance is False + + # ───── Evaluation ───── + + def test_evaluate(self, sample_model): + # When + component1 = Gaussian(name="Gaussian1", area=1.0, center=0.0, width=1.0, unit='meV') + component2 = Lorentzian(name="Lorentzian1", area=2.0, center=1.0, width=0.5, unit='meV') + sample_model.add_component(component1) + sample_model.add_component(component2) + # Then + x = np.linspace(-5, 5, 100) + result = sample_model.evaluate(x) + # Expect + expected_result = component1.evaluate(x) + component2.evaluate(x) + np.testing.assert_allclose(result, expected_result, rtol=1e-5) + + def test_evaluate_with_detailed_balance(self, sample_model): + # When + sample_model.temperature = 300 + component1 = Gaussian(name="Gaussian1", area=1.0, center=0.0, width=1.0, unit='meV') + component2 = Lorentzian(name="Lorentzian1", area=2.0, center=1.0, width=0.5, unit='meV') + sample_model.add_component(component1) + sample_model.add_component(component2) + x = np.linspace(-5, 5, 100) + # Then + result = sample_model.evaluate(x) + # Expect + expected_result = component1.evaluate(x) + component2.evaluate(x) + expected_result *= detailed_balance_factor(x, sample_model._temperature.value) + np.testing.assert_allclose(result, expected_result, rtol=1e-5) + + def test_evaluate_component(self, sample_model): + # When + component1 = Gaussian(name="TestGaussian", area=1.0, center=0.0, width=1.0, unit='meV') + component2 = Lorentzian(name="TestLorentzian", area=2.0, center=1.0, width=0.5, unit='meV') + sample_model.add_component(component1) + sample_model.add_component(component2) + + # Then + x = np.linspace(-5, 5, 100) + result1 = sample_model.evaluate_component("TestGaussian", x) + result2 = sample_model.evaluate_component("TestLorentzian", x) + # Expect + expected_result1 = component1.evaluate(x) + expected_result2 = component2.evaluate(x) + np.testing.assert_allclose(result1, expected_result1, rtol=1e-5) + np.testing.assert_allclose(result2, expected_result2, rtol=1e-5) + + def test_evaluate_component_with_detailed_balance(self, sample_model): + # When + component1 = Gaussian(name="TestGaussian", area=1.0, center=0.0, width=1.0, unit='meV') + component2 = Lorentzian(name="TestLorentzian", area=2.0, center=1.0, width=0.5, unit='meV') + sample_model.add_component(component1) + sample_model.add_component(component2) + sample_model.temperature = 300 + # Then + x = np.linspace(-5, 5, 100) + result1 = sample_model.evaluate_component('TestGaussian', x) + result2 = sample_model.evaluate_component('TestLorentzian', x) + # Expect + expected_result1 = component1.evaluate(x) + expected_result2 = component2.evaluate(x) + expected_result1 *= detailed_balance_factor(x, sample_model._temperature.value) + expected_result2 *= detailed_balance_factor(x, sample_model._temperature.value) + np.testing.assert_allclose(result1, expected_result1, rtol=1e-5) + np.testing.assert_allclose(result2, expected_result2, rtol=1e-5) + + def test_evaluate_nonexistent_component_raises(self, sample_model): + # When Then Expect + x = np.linspace(-5, 5, 100) + with pytest.raises(KeyError, match="No component named 'NonExistentComponent' exists"): + sample_model.evaluate_component("NonExistentComponent", x) + + # ───── Utilities ───── + + def test_normalize_area(self, sample_model): + # When + component1 = Gaussian(name="TestGaussian1", area=2.0, center=0.0, width=1.0, unit='meV') + component2 = Gaussian(name="TestGaussian2", area=3.0, center=1.0, width=0.5, unit='meV') + sample_model.add_component(component1) + sample_model.add_component(component2) + # Then + sample_model.normalize_area() + # Expect + x = np.linspace(-10, 10, 1000) + result = sample_model.evaluate(x) + numerical_area = simpson(result, x) + assert np.isclose(numerical_area, 1.0) + + def test_get_parameters(self, sample_model): + # When + component = Gaussian(name="TestGaussian", area=1.0, center=0.0, width=1.0, unit='meV') + sample_model.add_component(component) + # Then + parameters = sample_model.get_parameters() + # Expect + assert len(parameters) == 3 + assert parameters[0].name == 'TestGaussian area' + assert parameters[1].name == 'TestGaussian center' + assert parameters[2].name == 'TestGaussian width' + assert all(isinstance(param, Parameter) for param in parameters) + + def test_get_parameters_no_components(self, sample_model): + # When Then + parameters = sample_model.get_parameters() + # Expect + assert len(parameters) == 0 + + def test_repr_contains_name_and_components(self, sample_model): + # When + component = Gaussian(name="TestGaussian", area=1.0, center=0.0, width=1.0, unit='meV') + sample_model.add_component(component) + # Then + rep = repr(sample_model) + # Expect + assert "SampleModel" in rep + assert "TestGaussian" in rep + + # def test_repr_no_components(self, sample_model): + # # When Then + # rep = repr(sample_model) + # # Expect + # assert "SampleModel" in rep + # assert "Components: None" in rep + + def test_str_contains_name_and_components(self, sample_model): + # When + component = Gaussian(name="TestGaussian", area=1.0, center=0.0, width=1.0, unit='meV') + sample_model.add_component(component) + # Then + str_repr = str(sample_model) + # Expect + assert "SampleModel" in str_repr + assert "TestGaussian" in str_repr + From a782693762cc6edbf3b0635d99ddd2e8be97b6e4 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 15 Oct 2025 12:00:09 +0200 Subject: [PATCH 02/71] Clean up, fix tests --- ...mponent_example.ipynb => components.ipynb} | 0 examples/sample_model.ipynb | 202 +++++++ src/easydynamics/sample_model/__init__.py | 1 + src/easydynamics/sample_model/sample_model.py | 505 +++++++++--------- .../sample_model/test_sample_model.py | 230 +++++--- 5 files changed, 621 insertions(+), 317 deletions(-) rename examples/{component_example.ipynb => components.ipynb} (100%) create mode 100644 examples/sample_model.ipynb diff --git a/examples/component_example.ipynb b/examples/components.ipynb similarity index 100% rename from examples/component_example.ipynb rename to examples/components.ipynb diff --git a/examples/sample_model.ipynb b/examples/sample_model.ipynb new file mode 100644 index 0000000..fa70738 --- /dev/null +++ b/examples/sample_model.ipynb @@ -0,0 +1,202 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "64deaa41", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "from easydynamics.sample_model import Gaussian\n", + "from easydynamics.sample_model import Lorentzian\n", + "from easydynamics.sample_model import DampedHarmonicOscillator\n", + "from easydynamics.sample_model import Polynomial\n", + "from easydynamics.sample_model import DeltaFunction\n", + "from easydynamics.sample_model import SampleModel\n", + "\n", + "\n", + "import matplotlib.pyplot as plt\n", + "\n", + "\n", + "%matplotlib widget" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "784d9e82", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "85c000d048fa447c92f106becdf27e5f", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "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", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sample_model=SampleModel(name='sample_model')\n", + "\n", + "# Creating components\n", + "gaussian=Gaussian(name='Gaussian',width=0.5,area=1)\n", + "dho = DampedHarmonicOscillator(name='DHO',center=1.0,width=0.3,area=2.0)\n", + "lorentzian = Lorentzian(name='Lorentzian',center=-1.0,width=0.2,area=1.0)\n", + "polynomial = Polynomial(name='Polynomial',coefficients=[0.1, 0, 0.5]) # y=0.1+0.5*x^2\n", + "\n", + "sample_model.add_component(gaussian)\n", + "sample_model.add_component(dho)\n", + "sample_model.add_component(lorentzian)\n", + "sample_model.add_component(polynomial)\n", + "\n", + "\n", + "x=np.linspace(-2, 2, 100)\n", + "\n", + "plt.figure()\n", + "y=sample_model.evaluate(x)\n", + "plt.plot(x, y, label='Sample Model')\n", + "\n", + "for component in sample_model.components.values():\n", + " y = component.evaluate(x)\n", + " plt.plot(x, y, label=component.name)\n", + "\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "ac7061fd", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "fbcf9802343e43e0a89319740a8bf595", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAmCJJREFUeJzt3QV4U+caB/B/29TdvaWFQnH34dtgTGBud+4bc9/d7uxuzN13527MGWzDhrs7pUCpe+qN3ef90oS0tNBSSdr8fzyHc3JiX5KTnjfvZy4mk8kEIiIiInIarvYuABERERF1LAaARERERE6GASARERGRk2EASERERORkGAASERERORkGgEREREROhgEgERERkZNhAEhERETkZBgAEhERETkZBoBEREREToYBIBEREZGTYQBIRERE5GQYABIRERE5GQaARERERE6GASARERGRk2EASERERORkGAASERERORkGgEREREROhgEgERERkZNhAEhERETkZBgAEhERETkZBoBEREREToYBIBEREZGTYQBIRERE5GQYABIRERE5GQaARERERE6GASARERGRk2EASERERORkGAASERERORkGgEREREROhgEgERERkZNhAEhERETkZBgAEhERETkZBoBEREREToYBIFETXFxc8Nhjj6GruPLKK9GtW7cTuu/EiRPVQs0nx44cQy25bUFBQZuWwZ6f2+LFi9VrknVbHINNkceTxz2WAwcOqLK88MILbfa8H3/8sXpMeWyizogBILWrrVu34rzzzkNiYiK8vLwQGxuLU045Ba+//rq9i0Z29NZbb6kTaEtO8nKybbjceOONzQ5Evv/++3r7a2trccYZZ8DV1RUffvghOsLTTz+Nn376CZ1BZyorEbWc5gTuQ9QsK1aswKRJk5CQkIDrrrsOUVFRyMjIwKpVq/Dqq6/i1ltvtXcRyY4BYFhY2HEzN7YGDRqEu+++u96+nj17ntDz63Q69cNk7ty5eP/993H11VejrT388MN44IEHjgqq5HlnzpwJR9faso4fPx5VVVXw8PBo87IRUesxAKR289RTTyEwMBBr165FUFBQvevy8vLsVi7qnCR7/K9//avVjyPB3wUXXIDffvsN7777Lq655hq0B41GoxZnJZlVyfoTkWNiFTC1m7S0NPTt2/eo4E9ERETUu/zRRx9h8uTJar+npyf6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X4SO5OLt3SaTbmdmZmL69OkqSPr000+xa9cuXHfddfDy8qoXrH3yySe46aabsHz5cnW5pKQEkydPxrXXXouXX34ZVVVVuP/++3HBBRdg4cKF9e531113YfXq1Vi5cqV6nrFjx+KUU07B2rVrERERgY8++gjTpk1T2T0h+yWwE7I+77zz4O7eeA8zo9GIuLg4fPfddyqwW7FiBa6//noV6ElZLBYtWqT2yXrfvn248MILMWjQIPVaiYjo+BbtMmf/JnQPQ/Zqc/u/+N4MAB2J0waAEixI0PL5558jJycHMTExKuB4+OGH2yRYaowEf7uHDEVH67VhPVx8zF3wW+Ott95S7ereeOMN9R6lpqYiKytLBXP/+c9/4OpqTiinpKTgueees97vv//9LwYPHoynn37auu/DDz9Uj7Vnzx707NlT7RswYAAeffRR62PI8yxYsEAFgOHh4Wp/UFCQyg5aWPaL22+/XbX5k6CwMRIYPv7449bLkgmUQPPbb7+tFwAGBwer55YgU17j6aefrsrBAJCIqGXDv4wO8EWRrgS+QZ4IifG1d7HIhtMGgM8++yzefvttlXXq27cv1q1bh6uuugqBgYGqKpKOtnPnTowePbpegCwZuvLychw+fBgJCQlq39Ch9YPczZs3q2yaVP82lJaWVi8AtCVZuLw88x+R43nvvffwwQcfqKyebVDY0JtvvqmCz0OHDqlMpLRRlOyeLTkeLBlGSzm2bt3arHIQETm7XG21mgFEThVh5SYUSfavT0i7JVfoxDhtACiBwowZM1R2x9KW7KuvvsKaNWvatSpWsnEdTZ63I/n61v+VJwHimWeeqYLuhiS4smhYdSt/LKTa9ngkuLz11lvV59cwiLT19ddf45577sGLL76oAll/f388//zzqsrZ1omWg4iIgMV12b8BcUEo2Geu/mX7P8fjtAHgmDFjVNbIUgUpWaply5bhpZdearfnVB0U2qAq1l569+6NH374QbVltPySk3Z+EkhJ27qmDBkyRN1PguzW9MiVwMzS3s9C2uhJu7+HHnoI55xzzjHvL2WVz/3mm2+ul4EkIqK2b/83OSEERVuzARfO/+uInLYXsPReveiii1QbLwkspI2a9Fy99NJLm7xPTU0NtFptvaWrKi0tVb1nbRfpMJGRkaGybdIB5Oeff1Zt9qTjhqX9X2OkF21RUREuvvhi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ldwxQSd1bU4fAJaXl+PSSy/F+++/j+DgYHsXh4jIqX2//jD251eoDhgyXy8B+loDttUN/SLZPw79Qm3B6QPAW265BaeffjpOPvlkexeFiMipyawbr/y9V23fMqmHGpOPoGb9qC7XqSnfkgeF2bs41EU4dRvAr7/+Ghs2bFBVwM1RU1OjFgutVtuOpSMici6frDiAHG216nV76Ui2c7MM/Lzpb3Pnj4FT4uHq5vR5G2ojTnskZWRkqA4fX3zxBby8mjco5+zZsxEYGGhd4uPj272cRETOQObJffef/Wr7jpNT4OXOMe4sAz+X5FbCw8sNvce03zR45HycNgBcv3498vLyMGTIEGg0GrUsWbIEr732mto2GI6eAFx6CZeWlloXCSKJiKj1vlx9CEUVtUgI8cHZgznGncWmvw+pdZ9xsfDwdupKO2pjTns0TZkyBVu3bq2376qrrkJqairuv/9+uLkd/evT09NTLURE1LZt/96ry/7dPLE7NKzmVPIPlSFzdwlcXF3UvL9EbclpA0B/f3/061d/YnFfX1+EhoYetZ+IiNrPt+sykFdWg5hAL5wzhIGOxYb5B9W6x9AI1QGEqC3xZxYREdlNrd6Idxanqe0bJ3aHh4anJSHt/tI25KntIVPZIYbantNmABuzePFiexeBiMipzNlwGFml1WrA5wuGsWOdxca/DsFkAhL7hSIszt/exaEuiD+1iIjIbrN+vFWX/bthfDJ7/tapKKnBrlXZanvItER7F4e6KAaARERkF79szsKhoko168clHPevXs9fo96E6B6BiOkRZO/iUBfFAJCIiDqcwWjCm4v2qe1rTkqCjwdbJInqCh22Lc1S20OmMvtH7YcBIBERdbg/tmUjLb8CAV4aXD6agY7F1sWHoa8xIDTOT7X/I2ovDACJiKhDGY0mvLHQnP27amwS5/yto6sxYMvCw2p76NREuLi42LtI1IUxACQiog71985c7Mopg5+nBlePTbJ3cRzGjmVZqgo4INwb3YeE27s41MUxACQiog5jMpnwel32T6p+A32Y/RMGnVEN/SKGnJoAV86GQu2MRxgREXWYJXvysTWzFN7ubqrzB5ntWJ6lhn/xDfJE6qhoexeHnAADQCIi6vDs36UjExDqx7nVLdm/9fPM074NnZYIN3eemqn98SgjIqIOsTKtEOsPFqvp3q4fn2zv4jhk9q/P2Bh7F4ecBANAIiLqEJbs30XD4xER4GXv4jgEZv/IXnikERFRu1t3oAgr9xfC3c0FN0zobu/iOGT2r/dYtv2jjsMAkIiI2t2rC/aq9blD4hAb5G3v4jhk9k/DuZCpAzEAJCKidrUmvQhL9xZA4+qCmyf2sHdxHAazf2RPDACJiKhde/6+MH+32j5/WDwSQn3sXSSHwOwf2RsDQCIiajfL9hVgzYEi1fP3tinM/lkw+0f2xgCQiIjaPfv3r5GJiA5k2z/LnL9r5x5Q28z+kb0wACQionbx9848bD5snvXjpons+WuxeWEGqrS1CAjzQp+TOO4f2QcDQCIianNGowkv/mnO/l01thvC/Tnrh6iu0GHjn+Y5f0ecmQw3DU/DZB888oiIqM39vjUbu3LK4O+p4awfNjb+eRC1VXqExvoiZXikvYtDTowBIBERtSm9wYiX/9qjtq8bn4wgHw97F8khSKePzQsPq+2RM7rD1dXF3kUiJ8YAkIiI2tR36w9jf0EFgn3ccfVJSfYujsOQjh8y/EtUciC69Q+1d3HIyTEAJCKiNqOt1ll7/t46OQV+nhp7F8khlORVYueyLLU9+uxkuLgw+0f2xQCQiIjazBsL96Gwohbdw31x2ehEexfHYaz5NV11jEnoG4KYlGB7F4eIASAREbWN9IIKfLQ8XW0/fEYfuLvxFCPyDmqxd22u2h41g8PhkGPgt5OIiNrEU7/vgM5gwsRe4ZjUK8LexXGYwbCXf79PbfccGYnwBH97F4lIYQBIRESttnRvvhr4WePqgodP72Pv4jiM9E0FyNpbAjd3V2b/yKEwACQiolYP+/LkbzvUtrT76xHhZ+8iOQSD3ogVc8zZv0Enx8M/xMveRSKyYgBIRESt8uWaQ9iTW66GfbljSk97F8dhbFuSidL8KngHeGDIVHaIIcfCAJCIiE5YnrbaOuzLXaf0RKCPu72L5DBTvq393dwhZuSZSfDw4nA45FgYABIR0Ql3cHj4p23QVuvRPzYQF49IsHeRHMa63w+gptI85VvvsTH2Lg7RURgAEhHRCc/3++eOXNXx47nzBkBjh2FfdEYdthdux0HtQTiKktxKbF1invJt7LkpnPKNHBJz0kRE1GJFFbV49OftavvmST3QOzqgQ57XaDJiVfYqrM9dj015m7C1YCuq9FXquknxk3DzoJuRGpIKe1r+wz4YDTLocyji+4TYtSxETWEASERELfb4r9vVjB+9Iv0xa1KPDnnOSl0l7v3nXvxz+J96+/3d/VGuK8eijEVqmRw/GTcNuskugeCBrQU4sKVAZf3Gntcx7wvRiWAASERELbJgZy5+3pQFqdmUql8PTftX/RZXF+OWBbeojJ+XmxdOSTwFgyMHY3D4YCQHJeOA9gDe3fwu/kj/AwszFqpl1qBZuGHgDegoep0BS7/dq7YHTolHSLRvhz03UUsxACQiombTVuvw7x+3qe3rxiVjYHxQuz/n4bLDuOnvm1SQF+gZiDenvImB4QPr3SY5MBnPjn8WNwy4Ae9seUcFgm9segORvpGY2WMmOsKmvzKgza+Cb6AHhp3erUOek+hEsRMIERE1u9fvg3O2IkdbjaQwX9x5SvuP+bezcCcu++MyFfzF+Mbg09M+PSr4syXZwOfGP4fr+l+nLj++4nHVZrC9aQursP6PA2p7zHk9OOwLOTwGgERE1CyfrzqI37dkq16/L14wEF7ubu36fBnaDFwz/xoUVBWgZ3BPfDb9M5Xpa45Zg2fhtKTToDfpcdeiu7Cv2DwjR3uR+X71OiNiUoKQMiyyXZ+LqC0wACQiouPacrgET/62U20/OL03hiQEt+vz6Qw63PfPfSjTlWFA+AB8PO1jRPhENPv+ri6u+O/Y/2JIxBD1GDcvuFkFku3h0I5C7N+YDxdXF4y/qCdcXDjsCzk+BoBERHRMpZU63PzFBtQajJjaNxJXj23/9m3Sfm9b4TYEeATgxQkvwt/Dv8WP4eHmgVcnvYrEgERkV2Rj1oJZqDHUtGk5DTojln5j7vjRf2IsQmM5DzJ1DgwAiYjomO3+7vl+Mw4XVyE+xBvPnTew3TNcK7NW4sNtH6rtx8c8jijfqBN+rCCvILw15S0EeQapAaM/3Gp+3Lay4c+DauBnb393jDizedXTRI6AASARETXpg2Xp+GtHLjzcXPHWJUMR6N2+c/0WVRfhoWUPqe0Lel6AkxNPbvVjJgQk4N+j/q2239/6fpvNGlKcU4F1dR0/xl3QE57e7PhBnQcDQCIiatTCXbmY/ccutf3ImX3QPy6w3bONjyx/RLXV6x7YHfcMv6fNHntq4lSMjRmrpo57ctWT6rlaVVajCYs+3wWj3oTEfqHoMaz57ROJHAEDQCIiarTTxy1fbITBaMJ5Q+Pwr5EJ7f6cX+36Ss3y4eHqgecmPAdvjXebPbZUW0sW0NPNE6uzV2Nu+txWPd6O5VnI3lcKjYcrxl/Mjh/U+TAAJCKieg4VVuLqj9eiSmfAuJQwzD6nf7sHOLkVuXh1w6tq++5hd6thX9pavH+8GihaPLf2OZTWlJ7Q41SU1mDFnDS1PfKsZASEtl2gStRRGAASEZFVcUUtrvxoDQrKa9EnOgBvXToE7m7tf6p4ft3zqNRXqkGeL0q9qN2e58q+V6qxBKWt4WsbXjuhx5Bev7VVeoQn+GPApLg2LyNRR2AASERESrXOgGs/XYf9BRWIDfLGR1cNh79X+3b6ECsyV2D+gflq7L5HRj2i1u3F3c1dPYf4bs932Jy/uUX3T99SgLQNeWrMv0n/SoVrBwTHRO2BRy4REang7/rP1mP9wWIEeGnw8VXDERng1e7PK+PyPbX6KbV9Seol6BXSq92fc1jUMMzoPgMmmPD06qdhNBmbdb/qCh2WfGHuFDNwSrzKABJ1VgwAiYicXGWtHld9tBb/7MmHt7sb/nfFcKREdkxw89G2j3Co7BDCvcNxy6Bb0FHuGnYXfN19saNwh8o+Nseyb/eiorQWgRHeGHFmUruXkag9MQAkInJiZdU6XPHhGqzcXwhfDzd8cvUIjEgK6ZDnlrl+39/yvtq+b/h98PPouFk0QrxCcFXfq9S2tAWUqeeOZf+mfOxenQPpC3PylX3g7tG+8yATtTcGgERETqq0SofLPliDtQeK4e+lwWfXjuyw4E/G4Zu9ZjZqjbUYFT0KU7tNRUe7rM9lKvN4uPwwvt3zbZO3qyqvxeK6qt9BpyQgKrl9x0Mk6ggMAImInFCethqX/m8VNmWUIMjHHV9eOwpDEoI77PkXZSzC0sylcHd1x79H/tsu4+j5uPvgpkE3qe13N7+L8tryRm/3z1d7UFWmQ3C0L6t+qctgAEhE5GS2ZZbirDeWY1umFiG+Hir4a+9ZPhp2/JBx+MQVfa9At8BusJeze5yNpMAkFNcUW+cftrV3XS72rTf3+j35yt7QuLPql7oGBoBERE5k3rZsnP/OSuRoq9E93BdzbhqDPjEBHVqGT7d/iszyTER4R+C6/tfBnjSuGtw+5Ha1/dmOz5BXmVdvwGfJ/omh0xIRkdix7xNRe2IASETkBKTN3ZuL9uHGzzdYZ/iYc/NYdAvz7dBy5FTk4P2t71t74ko1rL1Njp+MQeGDUG2oxlub3rLO9bvg4x1q6JeweD8Mm26/LCVRe2AASETkBJ09Zn25Ec/P360uXzmmGz66cjgCvdt/kOeGXlr/Eqr0VRgcMRjTk6bDEUj7QwlGxY/7fsT+kv3YtCADGTuLoXF3xSlX94WbhqdL6lqc+oiePXs2hg8fDn9/f0RERGDmzJnYvdv8B5KIqCtYf7AI019dit+3ZkPj6oInZ/bDY2f1hcYOM1hsyN2AP9L/gAtc8OCIB+3S8aMpEpBOip+kBoV+b8GnWPWTea7fky5IQUh0x2ZJiTqCUweAS5YswS233IJVq1bhr7/+gk6nw6mnnoqKigp7F42IqFUMRhPeWLgXF7y7CpklVUgI8cH3N43BZaMS7VQegxr2RZzb81z0Du0NRyNtAT2MXvBfmgqjwYTkweHoc1KMvYtF1C40cGLz5s2rd/njjz9WmcD169dj/PjxdisXEVFrZBRV4t7vN2PV/iJ1+ayBMXjq7H4dMq9vU+bsm4NdRbvg7+GPWwffCkfUPag7Liq4HT7VEaj1rsDES09yqCwlUVty6gCwodLSUrUOCemYgVCJiNo66/fR8nS8+Oce1dHDx8MNT8zoh3OHxNo1kCmuLsarG15V2zLdm8zC4YhkyBeftBiYYMQfSR9gRGkIxvqNtXexiNoFA8A6RqMRd9xxB8aOHYt+/fo1epuamhq1WGi12g4sIRFR03Zma/HAD1uw+bD5h+zIpBA8c+4AJHVwL9/GSPBXWlOKnsE9cWGvC+GISnIrsehz82wf+oG5yPZJwysbXsHomNFwdXHq1lLURfGoriNtAbdt24avv/76mJ1GAgMDrUt8fHyHlpGIqLG5fGf/sRNnvr5MBX8ypdsz5/THV9eNcojgb3P+Zvyw9we1/fCoh9W4e45GV2PAH+9uha7agOgegbj88unwc/dTVdbz0us3FSLqKhgAApg1axZ+++03LFq0CHFxcU3e7sEHH1TVxJYlIyOjQ8tJRGRhNJrw7doMTHphCd5dsh96ownT+kbh77sm4KIRCXB1tX/bNb1Rj/+u+q/antF9hupp64jjIy75cjeKsirgHeCBqdf1Q4hvMK7se6W6/vWNr0Nn0Nm7mERtzvF+inXwF//WW2/Fjz/+iMWLFyMp6dhzPHp6eqqFiMie1h4owuO/bldTuQnJ9D18em9M6R0JR/LN7m+sHT/uHHonHNH2pVnYvTpHTfU29dq+8A00/42/rM9l+GrXVzhcflhlMC9KvcjeRSVqUxpnr/b98ssv8fPPP6uxAHNyctR+qd719va2d/GIiOrZlaPFC/P34O+dueqyv6cGt5+cgstHd4OHgw1UnF+Zjzc2vqG27xhyB0K9Q+Fo8g5qsfRb81Rvo2YkI7ZnsPU6maHkxoE34qnVT+HtzW/jjOQz4OfhZ8fSErUtx/qL0cHefvttVZU7ceJEREdHW5dvvvnG3kUjIrI6VFiJO77eiNNeXaqCP6ndvXhEAhbdOxHXjkt2uOBPvLj+RZTrytE3tC/OTTkXjqa6XId5726DUW9C0sAwDD414ajbyHiF3QK6oai6CP/b+j+7lJOovWicvQqYiMhRHS6uxFuL01RbP2njJ07vH407T+mJHhGOm41alb0Kv+//Xc348cioR+Dm6gZHYjAYMe/9rSgrqkZAuDemXNG70WFy3F3dcdfQu3Dbotvw2Y7PcH6v8xHrF2uXMhO1NacOAImIHNHBwgq8tSgNP2w4bA38xvcMx72n9kL/uEA4skpdJR5b8ZjavqDXBegb1heOZtk3e5G5uwTunm6YfmN/ePo0PUD2xPiJGBk1EqtzVuOV9a/g+QnPd2hZidoLA0AiIgexL69MZfx+3pSlBnUWJ/UIw21TUjAiyTEHT27o5fUvI7M8EzG+MQ7Z8WPr4sPY9k8m4AKccnUfhMYeO5MqmcF7h9+L8389H/MOzMOlvS/FoIhBHVZeovbCAJCIyM7WHyzGO0vS8NcOc+cOMbFXOG6dnIKhiUc6Jji6tTlr8fVu81iqj455FL7u9h+H0NbhXUVY+u1etT16ZnckDQxv1v16hfTC2SlnY87eOXhu7XP4fPrnHByaOj0GgEREdhrHb8mefLy9JA1r0s1z9koztFP7ROLmiT0wMD4InYlU/T664lG1LZ0+xsSMgSMpyavEvPe2wWQ0oefIyEY7fRyLzF8sg0JvLdiKuelzVa9gos6MASARUQeq1hnw08ZM/G9ZOvbllat97m4uOHtwLK4f392hO3cciwyYnFGWgUifSNw97G44Wo/f39/cgppKPSKTAjDpX6ktnhs5zDsM1/a/Fq9tfE21BZySMAXeGg4XRp0XA0Aiog5QVFGLL1YdxCcrD6CgvFbt8/PU4OIR8bjmpGREBXqhs9qYtxFf7PxCbT825jE18LOj0Nca8PtbW9Rcv37Bnjjtxv7QuJ9Yr2QZHPq7Pd8huyJbDQsjWUGizooBIBFRO9qbW4YPl6djzoZM1OiNal9MoBeuGpuEC0fEI8Cr6R6onUF5bTkeXvYwTDBhZo+ZOCn2JDhSNftfH+5Azv5SePpocMatA60zfZwIL42X6hBy1+K78OG2DzE9aTq6B3Vv0zITdRQGgERE7TDG6NK9BfhgWbpq52fRLzYA141LxvT+0XB3c+0Sr/OJlU/gUNkhRPlGqeDIkcq27Nu92L8pH64aF0y/qT9CY1pfvX5ywsmYEDcBSw4vUa/9o2kfsUMIdUoMAImI2khlrV5l+j5eccDavs/SsUOqeYd3C25x2zNHJnPk/nHgD7i5uOH58c8jwCMAjmLjn4fUkC9quJer+iImpW16U8vn99DIh7AmZw025G3Aj3t/VDOGEHU2DACJiFops6QKn648gK/XZKC0Smdt33f+sDhcNSYJCaE+6Gr2FO/BM2ueUdu3DbnNocbG27UyGyt/TFPbJ52Xgh5DI9r08WP8YnDLoFvwwroX1JR3E+InqE4iRJ0JA0AiohOsYlx7oBgfr0jH/O251oGbE0J8cOWYbir48+/k7fuONeTLPUvuQY2hRrX5u7LvlXAUe9flYuGnO9X2oJPjMXBKfLs8jwwILdPd7SzaiefXPo9nxz/bLs9D1F4YABIRtXAYl9+2ZOOj5enYnqW17h+dHIqrT0rC5NQIuLl2nWrexjy1+imkl6YjwjsCT530lMO0gTuwpQB/f7gDMs17n7HRGHNuj3Z7Lo2rBo+OfhSXzL1EjQs4o/sMjIl1rLEPiY6FASARUTPkaqvx+aqD+HL1IRRWmIdx8dS4qvH7rhzbDalRjtP+rT19v+d7/JL2iwr6JOsV4uUYU9Rl7CxSAz1Lz9+U4ZGYcGnLx/prKZnn+OLUi9UQOE+segLfn/k9/Dw65ziO5HwYABIRHaOad8OhEnyy4gDmbs2Gvq6aNzrQC/8alYiLRyQgxNcDzmJl1ko8teoptT1r0CwMixoGR5C1rwRz394Cg96I5EHhOPnK3nDtoCysjAW46NAiNf/x06ufxtPjnu6Q5yVqLQaARERNVPNK4Lc1s9S6X3rxXjkmCaf2jewSw7i0xP6S/bh78d3Qm/Q4Pfl0NSuGowR/v72xGfpaIxL6huDUa/rCtQM/G5nvePa42bhq/lX4df+vqk3k9OTpHfb8RCeKASARUZ3s0ip8seoQvlpzpJrXQ+OKswbGqI4d/WID4YwKqwpx84KbUaYrw5CIIXhizBMOMZzN4V1FapYPCf5iewVh2g394ebe8YH5kMghuH7A9Xhn8zt4ctWTGBgxELF+sR1eDqKWYABIRHD2at5V+4vUMC5/7jjSm9dSzXvR8HiE+p347BGdnfT0vX3R7aqKM84vDq9MegUebvav9j60vRBz39kKg86IhD4h5inePE5sire2cMOAG1QV+eb8zXjgnwfUANHSUYTIUfHoJCKnVF6jx48bM/HZygPYk2setFmMSg7B5aO7qcGbNU5WzduQwWhQ07xJUCPz+7558psI9mqbAZVbI31LAea9txVGvQndBoRh6nV9T3h+37Yiwd4z457B+b+ej035m/D+lvdx06Cb7FomomNhAEhETmVPbpnqzSszdkgQKLzd3XD2kFhcPjrRaXrzHo/RZMSjKx7FvAPzoHHR4OWJLyM5MNkhxvmToV6kt2/3weE45Zq+cNM4RqAe5x+Hf4/6Nx5c+iDe2fIORkSPwNDIofYuFlGjGAASUZdXozeowZol8FuTXmTdnxzmi0tGJuD8YfEI9O6agzafaPD32IrH8HPaz2qat2fGP4OR0SPtXSxsXpCBZd/vBUxQQ72o3r4OlqU9I/kMLM9cjt/2/4a7Ft+Fr07/Ss0cQuRoGAASUZd1oKBCdej4bv1hFNV16pBBmk/pHYnLRidiTPdQh+jM4GjB3xMrn8CP+35UY/1JtebUblPtWiaT0YSVP6Wp+X1F/wmxOOnCnh021EtLPTLqEewr2YddRbswa+EsfHbaZ6q3MJEjcTFJC2g6IVqtFoGBgSgtLUVAAKuNiBxlCBfpzPHN2kNYvq/Quj8qwAsXDo/HRSPiER3obdcyOio5Hfx31X/x7Z5vVfD39ElPqyFf7EnG9lv42U7sWZ2rLo+amYwhUxMdPnDPqcjBRb9dhMLqQkyMn4hXJ73qMDOmEM/fggFgKzAAJHIcO7O1+GZthurYUVqlU/skRpjQMxyXjkzEpF7hTt+p41h0Rh0eX/G4qvZ1gYua4u3M7mfatUw1VXrMf28rMnYWw8XVBZP+lYreY6LRWUjnmavnXY1aYy2u7nc17hx6p72LRHW0PH+zCpiIOq/C8hr8vCkLP2w4XG9e3phAL9Wu7/xhcYgL9rFrGTuDstoy1V5tVfYqlaWScf7sHfyV5Faq2T2Kcyqh8XDFtOv7I7FfKDqTgeED8fjYx1WnkA+3fYjuQd1xVvez7F0sIoUBIBF1uireRbvy8MOGTCzenWedns3dzQWn9InEBcPiMS4lXLX1o+PLLs9WgzxLmzVvjTdemPACxseNt/u8vvPf34aaSj38gj3VGH8RiZ0zSyOdQmQWlfe3vq96VQd5Btn9/SUSDACJyOHpDUYsTyvEL5uy8Of2HJTVDd8iBsQF4twhcThzYIxTzcvbFnYW7sQtC25BflU+wr3D8eaUN9E7tLfdyiMtkrYtycTSb/eqjh+RSQEq+PMN7NwDcc8aPAsZZRlqSJ07Ft2B1ye/jrGxY+1dLHJyDACJyCHpDEasTCvEvO05mL8txzo1m6WK98xBMThvSBxSIv3tWs7O6ud9P+Op1U+hSl+FHkE98PbJbyPKN8pu5dHXGvDPN3uwc3m2utxrZBQm/quX3Qd4bguqQ824p1U7ywWHFqiZVd6Y8gZGRY+yd9HIibETSCuwESlR26qo0WP5vgIV9P29Ixfa6iOZPsnund4/GmcNisHQhGCHHQLE0VXqKlXg90vaL+rymJgxqtpXZvqwZ3u/ee9vQ+HhcsAFGD2zOwafmuDwPX1bSmfQqbaWiw8vhpebF946+S0Mjxpu72I5JS3P3wwAW4MHELWUfN0qag2ql2pppQ4lVbWorDEg2NcDkQGeiPD3goeDzGrQkWP1Ldqdh4W78rB6fxFqDUbrdWF+Hji1bxSm9o1SY/a5d9ZevLpqQJtpXioLgariI0ttBWCoBQy6I2uZQ1bjCcicu7J29wF8QgDvEMAn1LwdEAMExAJuzR/Aem/xXty95G6kl6arrNTNA2/Gtf2vhZur/bJs+9bnqWFedNUGePu7q5k94lND0FXVGmpVBnBZ5jLV5vKtKW9hWNQwexfL6Wh5/mYA2Bo8gKi5nRakKnO+ZLV25qKg/EhVZmNCfT0QF+ytpiTrHe2PPjGBSI32R4BX15ipIr+sBiv3F2LFvgKsSCvEoaLKetcnhPhgSu8InNYvGkMTgztPZw59LVC0H8jfBeTvNq+LDwClGUBFfvs8p4wr5x8NBMYDwd2A8J5AeG8gIhUISgTqAjsZ3PnrXV/jpfUvocZQgwjvCDW7hz2zT3r5XsxJw5ZFh9Xl6B6BmHptP/gGde72fs0hn8GtC27FyuyVcHd1V+MtTkuaZu9iORUtz98MAFuDBxAdy/qDRfhw2QHVU1WyfrY83FwR4O2OQG8NfD01apaKPG1NvexXQ91CfdA/LggD4wLRPzYQ/WID1X0dmczXmpZfjo2HSrDhUDHWHyzG3rzyerfRuLpgeLcQTE6NwKTUCHQP93X8qj/J0uVuB7I2AlkbzOu8nYDxSJX1USSLJxk73zDAO9iczfMOAjz9zVk8yfbJIkGb0QDoawBDjTmwlCxhVRFQWVS3LgS0WYC+uunn03gDkX2wL6InHqs9gM2VmWq3dD6QgCPEy35ZtoLD5fj7o+0ozKxQl4dMTcDIs5Idblq39lStr8YDSx9QbQLFHUPuUGMFOvyx30Voef5mANgaPICoMRlFlXhm3i78vsXcmN0yC8WpfSNxap8oDEkMgre721F/6OWrWFKpQ462GukFFWpg4x1ZWrXOKj36RC93Twr1RZ+YAPMSHYCekf6IDvSyy0lEMp378spVeXfllKn1tszSeu34LOWWskqV7pjuYRieFAI/Bw9kUVsJHF4LHFwBHFxu3m4s+PLwA8J7AeGp5nVIsjk7F5RgDvra8nORP92SWSw5ZF6K0oD8PUD+TqBgL2r11fhfUCDeDwqA3sUFvkYjbtdW48KQgXDtdhKQOBaIGQxoPDr0B8Gmvw9h9S/7YdSbVJXv5Mt7o1v/MDgjg9GAF9e/iM92fKYun9fzPPx75L+hkSYA1K60PH8zAGwNHkBkq7xGj7cX78P7S9NRqzeqc/0FQ+NxycgENVRJa4Ky4opabM0sVcvmjBJsOVyqAsXGSHCZFOaL7hF+SAr1QVSgtwoKIwO8EBXohSBv9xZ3oJA/E/L6pPpWLeU1yCqpwoHCShwqrMSBwgp1uW5IvqPKI69/cEIwhiQEqWyftHl0aJKBy94EpC0E0hYBGWsAo3l2ESuvQHMApZYhQMwgc7Bn5wyOfFZLMxbjhbXPIb3cXL060eSFf+dkIaq6/OgsYcIooPtkoMcUIKJPu5VfW1CFBZ/sRNbeEnW524AwNbOHT4CDHwsd4IudX+C5tc+pqvqxMWPV/MtBXkH2LlaXpuX5mwFga/AAIgvpuXrXt5uQq61Rl0cnh+KRM/qozFx7kUBMsmwyA8YOlS0sxcHCSuvAyE2R87ufhwZ+Xhr4e2ng46FR7exc6q6TQFWGYJHOKZU6vVpL8Fejb7p62iLQ2121W+wdHYDeUebMZK8o/87ReUOqV/f+BeyZB+xfZO6gYcs/Bug2FkgcY86ehfW0e7DX0PaC7SqjtDZnrboc6hWKB0c+iFMTT4WLBLV5249kMWUtVcm2pD2hBIMpp5oDQqmeboOs39ZFh7Hql/3Q1xig8XTDuAtS1JRurO48YtGhRbh/6f1qWJ4Inwg8O+5Zdg5pR1qevxkAtgYPIJJA6eW/9uDtJWmqRk7a6T00vbeakcIeJzcpj3Sq2J9fgf355ThYVInc0mqVLcwpra43lt6JkKracH9PhPt5IjLQS71e6bTRLcwXiSE+6rpOdVIvTAN2/Q7s/gPIWAWYbIJczwAgabw5EEqeCAQnOVzAZ3FIewhvbHwDfxz4Q132cPXAv/r8C9f0vwYBHk38bZIDVjqq7F8M7FsAHFgG6KuOXC/tEaWquOdpQK/TgKD4Fper4HAZFn22C3kHy6wdPaZc0RuB4ZyerzG7inbh3iX34oD2gOqlfePAG3F9/+vt2ku7q9Ly/M0AsDV4ADk3aet329cbVQcHIVW9j5zeB94ejvvHWqqmtdU6lFXrUVatQ3m1XnVQMZpMqupQ/hpIAlGmVZMOJvJafD0kS+iGUD8PlS3s1OQFSueNnb8AO38F8nbUvz6irznYSTkFiB0GuGkcPmD4YOsH+PPgn6r6UPK4MofvrEGzEO0X3fKhaiQIliyoBMTSptCWVHX3Psu8hPU49kPVGLBu7gFs/OuQmtHDw1uDMed0R5+xMXDpLL26HWScxmGRwzB73Gy7DtLdFWl5/mYA2Bo8gJzX3K3ZuP/7LWpKMqlGffbcAZjev4UnXOrAoG8bsG0OsOMn81AtFtLYvts4oNd0oNc0c2cNByd/stfnrscH2z5QY8lZjIsdh9uG3IbUkNS2eaKCvcDuueZg8NAqeeYj10lbwT4zgL7nmIeesSnb3nW5aniX8mJzc4juQ8Ix7sKenX46t472a9qv+O+q/6JSXwlfd1/cOvhWXNTrImYD24iW528GgK3BA8j51OgNmD13Fz5ecUBdlnHqXr1oEOKCWaXlcGRYFgn6ts8BCvcd2a/xArpPAXqfaQ76pHduJ1BeW47f9v+Gb/d8qwZ0FlJNODVxqqrq7RXSqx2fPM9cVS6Z0/R/6g93E9kP6DsTeUGnY9n8KmSnlard/qFeOOn8FCQPCm+/cnVxB7UH8dCyh7Alf4u63Ce0D/4z+j/oG9rX3kXr9LQ8fzMAbA0eQM5X5Tvryw3YfNh8grtxQnfcfWrPztHBwVnIwMvbfgC2/mDu8GDh5mmu1u13DpAyFfD0Q2cgf563FWzDD3t/wNz0uaqDgJBpxM7ofgau6nsVEgI6OGspnWMkK7j9R9VLWqsLxtryC7GrapKEpNBojBg6JQKDzujbJebxtTep2v9+z/d4Zf0rKNOVqaD/4tSLcdPAmxDoGWjv4nVaWp6/GQC2Bg8g5/HXjlzc/e0mNaad9HR9+cKBmJwaae9ikSU7JcHI1u/M4/NZuLqbO3D0O9fcrq8NerR2FJmqTQK+ufvn4lDZIev+5MBkXNDrApyRfIbdT/6V2lqs/3UXti3Ph9FobtfX02sJRvt/Cj+3YnNvaXnv+8wEfEPtWtauoKCqAM+tec7a0cff3R9X9bsKl/a+FD4yyDi1iJbnbwaArcEDqOurqNHj6bk78cVq80l4cEIQ3rhkCGKDvO1dNOdWrQV2/WYO+qQXq6X3rkyNJm36+p8HpJ5hnjO3E5A/w3uK92BxxmI1M8TOop3W62S+2Enxk3B+z/MxNHKo3XtZV1fosHlBBjYtyFDDuojYXkEYdWoooir/MmdfD62o385ShpbpJ5/J9E4ViDuiFZkr8ML6F6zNAGSonxsG3oDzUs6DewvmhXZ2Wp6/GQC2Bg+grm1NehHu+W6zda7aa05Kwv3TUuGhYZWvXUgv1b1/Atu+B3bPM0+TZiE9diXok04J/p0jMyvVuRtyN+Cfw/+owC+rIst6ncZFgzGxYzA9aboK/hwhw1NRWoNNf2dg+z+ZqpeviEj0x6iZ3RGXGlw/MC09bG5/KZ9V9ub6A09Lu8v+5wM9TgY07BhyotXCkiGWoX8yy81T/EX6ROKyPpfhnJRz4O/BIPt4tDx/MwBsDR5AXZNMafbin7vxv2XpqgOpZPueP28AxvRwzumq7MqgBw78Y84qSQeEGu2R60JTgAEXmAM/mXLNwemMOuws3IlV2avUsilvk9pnIe36RsWMwsS4iZicMBnBXo7ROaU0v0oN57JrRTYMdYOBh8b6YfgZ3VQHj+NmJKU38dbvzdla26FlZCYVGVJGPj/J2rJ3a4vpDDrVPvTdLe+qKmIhPYYlGyjjQHLomKZpef5mANgaPIC6FvkqzN+eg9l/7FIzaogLh8Xj4TN6w9+LVSsdxmg0j0cnnTm2/wRUmk9sSkCsuV2ZBA1RAxx2YGZRWlOqem9uzNuITfmbVGcOSycOCzlBj4kZo4I+Cf6kutdRvguHdxdjy8LDOLC1wDoCTFRyIIaelojEfqEtr4qWU03WRvPnKkvZkbmy4RthHlZGPtv4kYArs+wtUWOoUe1FP97+MfaXmoc5cnNxw7i4cTinxzlqzfmF69Py/M0AsDV4AHUdWw+X4snfd6hqXxHh74nZ5/THlN6dozqxSwR9mevMAZ+M1ac1V2sp3iHm4ECqDRNGO2RwUFxdjN3Fu7GjcId1ySjLOOp2MivHiKgRGBU9SgV8Cf4Jdm/TZ6u2Wo89a3KxZdFhFGdXWPcn9A3B0GmJiO4R1DbllWnpZCo6qSLe8QtQZf7eWYN8+byl80jccIf8vB25aljGhvxk+ydYk7PGuj/MOwwzus/AWT3OUh2JiOdvwQCwFRgAdn4yXdobi/ZhzgZzwOHl7orrxyXjhgnd1UwYraEvLETNnj0w6XQwGQwqyJG1JjgYnr16wc3ZjxlL0LfjZ3Pgpz1cfxo26cQhGaHkCYCDNG6XQE+m6TpQegD7Svaphvh7S/Zaq98akgBvUMQgDI4YrJakwCQ1jIcjkVNA9r5S7FyRhX3r86CvNVfzunu6IXVUFPpPikNwlG/7FcCgA/YvMWcFpWOPbTW/NRicAcSNYDDYAvtL9mPO3jn4df+vKKo+EmCnBKeouaFP7XaqUweDWp6/GQC2Bg+gzkkO+dXpRfjf0v34e2eedf85g2Nxz9ReiDnBHr663FxUrl6NyrXrULluHWrT0495e/eYGHimpsIrNRU+o0bCZ/BguLg7RqDTrm36Di43T8MmJ3vbakAPP/OMHH1nmgdqdvfq+OIZDcivylcN6w+XHcbh8sPILMtUQ7FI4CfVuk2J9YtVA/XKIgP1ytreQ7UcS2l+JfauzcOuldmqnZ9FUKQP+o2PReqYaHh6azq+o0/aAvMPAhlrsNY8h7DiF2k+PmQAb2kzqPHo2LJ14naCSw4vUcHgyqyV0Jv09YJBaX4gVcT9w/o7VTWxludvBoCtwQOoc5G5b+dty8EnKw9gW6Y5yyC1WVNSI3Hr5B4YGB/U4sc06fUo/+cfFH/9NSqWLjO3c7Lh0a0bXH18ADc3uEj2wtUV+txc6LKyjn4sXx+UDemOzH6R2JcagEJvPcp15WoGCJkOSqp3bEkbHy+Nl+o8IG3HZFsagEsPQLW4m9cShEjVo6xl8XP369jppGrKgH0LzCf0vfPNAwlbSG/FnlOBvmebx+xz9263wK60thRFVUUoqC5AfmU+CqsKVbCXV5mHnIoc5FTmqP0Gk7mHa1OifaPRLaAbkoOSkRKUok6i3YO6q/fe0ZUVVWPfujzsW5+LvINHgivJ9vUYFoHeY2IQlRzgGNXSKhhcaG4SIL2+bYNvCaxTTjYHhHLcdJLZXOxNfsAsPLRQzR29KmtVvWBQ/kaMjRmrep9LM4UYvxh0ZVqevxkAtgYPoM7Ro3fhrjz8sikLC3fnobauF6NU9Z47JE4N7ZIc3vJZIXR5eSj57juUfPc99Dk51v1e/fvDZ/hw+AwbBp8hg+EWVD+orNZXq7Ziuw+uR+6WtajZtQtBaXnov9+IAJv+AVLK3XHA2p6uWNvTBbnBbXdCdoEL/Dz81B98S2AogaJsS3Ao23K9BDRyWYYgkW0JMr3dvOHt7q2CTk+NpxqupNFgQebb3fs3sGcecGApYKg9cp1PaF0m5yxz9e5xhgLRG/Wqkbt0oKjSValgWLZlXaGrUAGyWuvKoa3VqpOcrLU1WpTUlKhqW1mbbOeyPQZ5TdI5I84/Ti2S2ZN1UkCSmnXDUTpqNIf8eS/MLEf65gIc2FJQL+iTjy22VzB6johE9yER8PBy4OyPvtbcG3znb+Yp6SqOZO7h4mYedFp+SPQ4BQjv5dCdgxyFfE9kCKKlmUuxPHO5+s7YkuN+eNRwDIscppovxPvHO8YPgzai5fmbAWBr8AByPHI4HyisxNK9+Vi6twAr9hWgovZIRqdHhB/OHhyLi0ckIMS35VVINWlpKPzwQ2h/+VW17RMS5AWeew6CL7gAHomJ9W5fa6hVPUGlQbYssm079IeFBzQYWRKK4ftd0XNXOUIOFtc//yXFQjd6IHQjB8DQJ1llFC2BkQSVKjiSoEhXqf6Ql9WWWQMiCYQk+yVrCZrakrRn83D1gIebBzxMJmgMOrjpq+Gu18ENJriZJOCUsYA9VNbG1TsIJncfFYpJQCZZTVnktajFpFfZulpjrXrvZDleRq4lJMiVBvHh3uEI8zGvZZGAz7LIwLodmiFtYzWVOmTuKUHGziLVg7e8yGa8RBcgpkcQUoZFIHlwBHwCOmE1qnQgObwO2POHOaucv6v+9YHx5qygBINJ48zDzdAxyXdPeqlLQLg6ZzW2F2w/6nsX7BmMAeED1NIvrB96h/R2mKGKToSW528GgK3BA8j+dAYjdueUYVNGiVpWphUis6T+UBsyjt+ZA2Nw1sAY9I72b/GvWPmKVK5di6IPP0L54sXW/d6DBiH40kvhf+opcPU8ksWS3p9LDy9Vv6zX5axDtaG63uOFeIVY24r1CemD3qG9VeBh2zlAl52NsgULUbbgb1SuWQtIJ5I6roGB8Bs7Fr7jx8F35Ei4R0e34P3SmbNkdQGhJWMmwaIEjZZFLktWzXaRANMSbDY3m9bWVBaybpHMpFRz22Yqbau7LWs5Scl7LtvuMj1cFyM9d3PTtcjcU4zDu4qRd0BbryWCxt0Vcb1DkDQgDIn9Q+Eb2MUGXy5KN2eaZZDwA8vrDxAu2cHYIUDSBCB5IhA/goNPN4N832WcyrU5a7Eud53q1d7YD1cZfFoCwdTQVPQM7qmaQkjHp87QllDL8zcDwNbgAdRx5DDNL6vB3rxy7Mktw57ccuzK0WJ7ltZarWvh7uaCoYnBGJcSjnEpYegXEwhX15ZXXRgrKlD6628o/vJL1ZtXcXGB/8lTEHLV1aqK1xJUrc9bb65OObxUdRawJcGHtKmR6pSR0SNbPPSHoaREtTMsX/IPypctg7G0fkcE94QE+IwYDt8RI+A9eDDc4+LavqpGquCyNqgOHKYDy1GbsQbV+grUugA1Li6olcU/Gvq4YdDHDYchuj/0Gk+VzTNZ/pnMa6mClvK5wtW8dnFVJwxp0ygBmmTfLFlFTzdPc3bRzUNVO3elKqgTIe+htqAaeQe1yE4rRU5aKQoyyho2PVUdOeJTgxHfN1TN0uHu0Xkzmi1SWwkcWAbs+wvY97e5KYItjZd5aBkZTkiqjSUg9HD8tpv2Jpn43UW7saVgCzbnbcb2wu315qi2Jd/hboHd0COwh1onBiSqNrOylqYljkLL8zcDwNbgAdR25DAsrdIhu7QaOaXVyCqtUlOwZRRVqrUMzFxWfaTBsq0AL43qwDEoPghDEoMxMikEPh4n/gu0Zu9eFH/3HUp//AnGMnObKRcvLwTOmIGQK6+AZ1KS6jQg7WYkyyc962yrViWQkTYz0rPupNiTVEeBtgpcpNNJ1ZYtKF+8BBWrVqF62zbzcCo2pEpa2iJ69+8Hr3794dmzJ9xjos2dUJqrLAfIWAMcXmteZABfff1MJryCgKTx5syKLDIbh5MHaG3JYDCiNLcKhVnlKMgoV0Ff/qEy1FQe/T3wD/FCdI9AxKWGqIBPLhOAkgwgfYl5vmgZasa27aCQTFVkP3MgKIFh3DAgOInHcTNI21tpz7yraJea4SatJA1ppWlHDXbe8MdwnF8cYv1j1Vra1kqnKrX4RasffB1Fy/M3A8DW4AF0nGrTWoMK6oora1FSqUNRhaxrUVhRi4LyGhSU1a3La5CjrUa1rn4g05Ak8RJDfZES4YeUSD/0jPRH/9hAdAv1PaEMn63aAweg/eMPaOfORc3efdb97okJCL74YnicMRXrq3arYG9l9kqkl9Yf4kXajUnANy52HEbHjO6wuTgN5eWoWr8eFWvWqKri6l27gLq2ibakJ7JHjx7wTOkBz+RklTX0SEiER0I8XA3lQPYmIGvTkbXtmHwWPmHmrEniWKDbWCCiD6fvagM1VXqU5lWiJLcSJXlVal2UVY7inEoYDUf/eXbVuCA0xk/NyiFBX3T3QPgFM+A7LjnVybR0h1aYB6GW6uJGj/NQIHoQED0QiJH1ICAogUFhM0h73qzyLGsweEh7SP2tPKg9iMLqwuPeXwJEqVaWJcInwrr0DeurqpjbkpbnbwaArdHVDiA5FGr0RtVzVoK3ylo9KmoMqKjVo7JuXV4j+2RtUGsZWkUyc7JfW61HWZVOBX3aKh30BhMkPJC8k3QGUGu4wNUka/Nl87aLdTvQS4MQbw+E+rgjzNcTYT6y7YEQb3cEe7vDzcVFnRSNRhNMRpPalnJb98laqhqt2+bXpS7LIpflfnoD9EXF0BcUQldQAGNZOUzqD7yLGqrFJSQY1WEBKPY0QFtbhkpdhXocM1WJqaozgjyDVBszaYemTg8uco31ZubMX93axWatbudqs99VLkt1qDnSda1bXCxrt7p9snYz73dzczVfX7fPzc1FXhyMudnQHzoA/UFZ0qHPOgxXXTVcjAa4mvTWtavRvLh71MDTpxbuPnq4+xjg7muAxtsITXQCND0GQpM6Fq7dxwBhKTwJtpBBZ0SFtgaVpbWoKKlBeUmNGoqlrPDIUl1xdMBu4e7lhtAYX4TE+iEiwR8RiQEIifGFm4YDIreJkkN1We515nX25vo91m2HnYnsY/7Ro9Z9zb2NfULsUepOSdoWy9iatmNsylpqU7Iqso6ZObyu/3W4bchtbVoebRc7f58IBoAOfADJR6MzSFBmUIGZJTirrjUvVdV6VNfqUV1tRE2tHjU1BtTUGlAr27VG1NYaoKs1QqczQKczr/V6E/Q6ozox6fVGGPVGVdVk0ksQZYSLyUUFZ262QdtR++ouWwK5uiCu3n3qwiTqPFzqAkJzkHgkQHQ16uDqYpKOx3DTuKhOBW7ubnDz1ECjFg+4ebtD4+UJdx9PaNTiBXc/b7j5eJlvr5H71K3V4nJku26/CmJluy7AdYT2fvKdkO+LzI6hqzFAV6OHrlrWBpW5k+pY6XVbW6VHdYUeVWW1qC7XoUqWstpGq2sbI71xpd1eYIQ3giJ8VJAni1TlOsL74DT0NUDONnMmXC2bgdwdQCMdIKxZ8bCe5h9Hod3N1cchSea1p+O0d+sUbVtrtSp7KONy5lbmqrVlmdljJqYlTWvT59QyAGQA+Oabb+L5559HTk4OBg4ciNdffx0jRoyw6wH0+nsbUbi50JopswZglsudNLiyzVaZM1bmk755sdl2bbCvYQZMrSX7hbrrXM1reUv0tTBqS2HSlqrOEobiIhjyc2HSauGiBlI2yUEPFxhR4+mC7BAgI9iAgxFGVHuYhyYxFxaq6iExMMHciDmwG4KkzduxqE4Olm3LmNDmrKP5smW7LhOpMpPmtSWjab1ssGQsG2Q3a6thrKmEsboSxpoq83ZtjXnR1cKo08Fo0sAAt7q1Rq0t2wZ4wAgPGNQ+R84imVQ2tG7s7LrP3LJ2tR4P1s++bq2yt5bgsS7jWu9PXN37Ls0m672/ajHCUPdDSP1IqjWq9721pMpWet6aFw/4hXohINRLBXf+atsbHh094wa1rANUwR4gbweQu9285O1svPrYlm+4ueo4MM48NI1sy9R2/tGAfxTgF+EwUxw6Iy0DQDj1X51vvvkGd911F9555x2MHDkSr7zyCqZOnYrdu3cjIiLCfgWrMSDc0PyTs5yijKrqEOZqTJWWk5NhXeBUd8KUrItrXdZFI4u7K9zdzWtPDzd41C1eHm5HsjaWzIysLVkbOdnKY7nZXn8kYKt3H5tAT07MJ0LmzzWWl8NQXAx9UZGaY9dQWARdQT6qsjJQnZWpZtdAbgFcKxt0VKgjoZ8Ee/ujXLAvxgVbklyQGWqpsnVRQZ4Mx2IZlkUWGUak3cczqy41L1VFQGVx3VqWAqA8D6goMDdcl+3y3KM7Ygg5VKQJmKUZmAxUHNzN3ClDshEqQ9HdvPaVF22mgh+9CQbJAtsuuiP79JI1LqtEbWEJdNpy81JWCV15FfQV1dBX18JQo4O+Rq+yZHIfFUjJ1McuGhhd6xa17V63uMFk3WdeTEcNz+Kiqu/lLYKh4dHeduMCtoQb9NC4GKyLu6sseni4GeHuZlBrT40enhojPN2N8JLFwwQPd6P6bkgEq74DWjeg3AUuGdIGwBXlqqrfvI162+ZgVkXALnXb5vYCR26nOvbUfdfV7equV6u6y5brzW0QjtzH9ja29zve7Sz7rPezWVQPbzS6v+n71O03bzT9eI1ebx5nsqnr2yR7KmNYRvUzL7ZqK4DCfeZ2hfm7zT2Oi9PNw9LI97gi37xkrm/igV3MQaCvLGF12+Hmbe8Qc/WyZS0/PmU8Q5kphxlhaiNOnQGUoG/48OF444031GWj0Yj4+HjceuuteOCBB+z2CyLjUCnycyrg6aGBl6cbvLzc4OkuQZnbkSDMpiqto6rL1KFiMKiATK31euuCurWhtga62mroa6qgr6lWl9V2dSX01VUwyCL7qyrVYqyqgrGqGsbKSpgqK4HKKqCqBq6VVXCrqIGmogbu1Tq4tOAozQ+QYM+c3csKccGBSBekRwKeAUGI8Y1RPc9kEnRZkgKTVHav3uwOkh6SKh+ZpF7aA8laLkv1kFqqzftlLdNVSdsVy1qGodBVmk8Oai1LGVBTbp4SrbYcqNaagz7beU5bQk4KkkUIiK7LLMSb15JpkKonmTO1JT1+24HKblZXq8BdPlu1VFSYF8tnXlUJk2W7Wo6JGhhqaqCv1qug0lirg75WD6POAEOtAUa9educqTOaM6LqeDSas3kSCUszSBUSmAMA86AzthlAc/ZXZYNl22TePtI20gAXk8Fc7W3Uwc0g61pVFV7vcajzaRgk2mw3GUQe1a736Ps2ehshAymr48yy2F42/4gxP29jZa1/rNV7bMsPBGvQXvdjwaWR/dZAvu7HguU6+V7Y/HiwtH22fG+s97W+Tks5bApre/1R71+D2ze8TaP3a/o+gWefjaCzZ6ItaZkBdN4MYG1tLdavX48HH3zQus/V1RUnn3wyVq5c2eh9ampq1GJ7ALWH/V/dgdpF683JDlEXo6uvg6mRvw8y20JddaNa182+IGkv833M+y33d7EupnqXXY1H9lsuq0X2Gc1V0G2h7s8RWlr5UekBaH2AUl9Zu6jtQn8XlPu7oDbAFYYAV7j5uyJY44ZwExBjdMFAWRuAmFoj/GXC+9w9gGmnObVk1Nus9UcCvQZz7rY7CT6tv/aD69ahRzIClrWqNoqSngFwdKpzi7c3XL07Zto0k9GoZmYx6fQw6SQ4l7XuyI8U2a+XIF6vfsCoHy2WHzE683Fg0kswWfdjxmA8sk+OEctagk2V3rT8EJLgUy6b05Xm+8k+o/nx5ViyXKf2mQMACVjr6qGP3MdyW7mffDEb3ka+r+p2lv3mdgbWy3KdquO2/IgxN3kwX1/XJsFym4aX65omWB633r56+2322Sz19jd224b3swfbcjS86nh3bfPCtLb3fN0felW30fX5dPMD2jgAJCcOAAsKCmAwGBAZGVlvv1zeJUNpNGL27Nl4/PHH271sFYcOIOlA0z0DHY1UP+tdAYMbIDXXOjdA39iiAQyyuAJ6d5PaNmpMMMra3QSTxgSTuwkusmhMcPUwQeNhgLu7CZ7uBvi6mOBvNCLJaFRrWYIMxiOBpCTUTjCpdlxuHuZBZC1rqRaSMaskGJMAzrL28AHcfcyDy0p1jaxlSBhpEO7pD8hAqJ4BgHddlY5sy2NRq0g2w0VmY1EzsnBg385ABaZNBIhHBZo2ly1taxu7vn57zyauP7qhbiO3a85tLNvW/45zmwa3a7Cud1trAWxeg6pNkJqEcrU21TaoaZBaCJl1qNZ2LTUWtTDJWldzpFZD/eCVH0q6Iz+Arc9oyWAe68NrsHnM2x6d4mz4dhzr8YVnKjvUtAenDQBPhGQLpc2gbQZQqozbWrczzkVmzOJ66XLbNjKyKd8plSq3aex+5Pr6+yztd2yritUJs26fXCfZT9lnbUjvIm33pNunK9xcpA2fXOdmbmwv+9zc4OrmBjc3DdxlW3oBy4wOLi7QyD8XuZ9smx/3KJZ2Qbbb1tdr226o4dq2GkO9kPrVHTL1U8N90ntA9tuuZQBYy1r2uclld/NlaZgt10mAJwGfuh/b3RC1JWt7wMau6/DSODnVvEeCw5q64FB/pBlMw5oSqb5Wl6VKu+HadKSqWzXgVeNu2ey3BLmWfeYs9ZGecnUZTctly7aMx0htzmkDwLCwMBXE5ErnARtyOSoqqtH7eHp6qqW99TltllqIiIjanQTiUhPB2gin4sjjQLQrDw8PDB06FAsWLLDuk04gcnn06NF2LRsRERFRe3LaDKCQ6twrrrgCw4YNU2P/yTAwFRUVuOqqq+xdNCIiIqJ249QB4IUXXoj8/Hz85z//UQNBDxo0CPPmzTuqYwgRERFRV+LU4wC2FscRIiIi6ny0PH87bxtAIiIiImfFAJCIiIjIyTAAJCIiInIyDACJiIiInAwDQCIiIiInwwCQiIiIyMkwACQiIiJyMgwAiYiIiJwMA0AiIiIiJ+PUU8G1lmUSFRlRnIiIiDoHbd1525knQ2MA2AplZWVqHR8fb++iEBER0QmcxwMDA+GMOBdwKxiNRmRlZcHf3x8uLi5t/utEAsuMjIwuOU8hX1/n19VfI19f59fVXyNf34kzmUwq+IuJiYGrq3O2hmMGsBXkoImLi2vX55CDvit+sS34+jq/rv4a+fo6v67+Gvn6Tkygk2b+LJwz7CUiIiJyYgwAiYiIiJwMA0AH5enpiUcffVStuyK+vs6vq79Gvr7Or6u/Rr4+ag12AiEiIiJyMswAEhERETkZBoBEREREToYBIBEREZGTYQBIRERE5GQYADqAAwcO4JprrkFSUhK8vb3RvXt31fOptrb2mPerrq7GLbfcgtDQUPj5+eHcc89Fbm4uHNVTTz2FMWPGwMfHB0FBQc26z5VXXqlmWbFdpk2bhq7y+qQP1n/+8x9ER0erz/7kk0/G3r174YiKiopw6aWXqgFZ5fXJMVteXn7M+0ycOPGoz+/GG2+Eo3jzzTfRrVs3eHl5YeTIkVizZs0xb//dd98hNTVV3b5///6YO3cuHFlLXt/HH3981Gcl93NU//zzD84880w1k4OU9aeffjrufRYvXowhQ4aoXqU9evRQr9mRtfQ1yutr+BnKkpOTA0c0e/ZsDB8+XM2mFRERgZkzZ2L37t3HvV9n+x46KgaADmDXrl1qWrl3330X27dvx8svv4x33nkHDz300DHvd+edd+LXX39VX4YlS5aoaenOOeccOCoJaM8//3zcdNNNLbqfBHzZ2dnW5auvvkJXeX3PPfccXnvtNfV5r169Gr6+vpg6daoK7h2NBH9yfP7111/47bff1Mnp+uuvP+79rrvuunqfn7xmR/DNN9/grrvuUj+2NmzYgIEDB6r3Pi8vr9Hbr1ixAhdffLEKfDdu3KhOVrJs27YNjqilr09IcG/7WR08eBCOqqKiQr0mCXKbIz09HaeffjomTZqETZs24Y477sC1116L+fPno6u8RgsJomw/RwmuHJGctySJsWrVKvV3RafT4dRTT1Wvuymd7Xvo0GQYGHI8zz33nCkpKanJ60tKSkzu7u6m7777zrpv586dMqSPaeXKlSZH9tFHH5kCAwObddsrrrjCNGPGDFNn0tzXZzQaTVFRUabnn3++3ufq6elp+uqrr0yOZMeOHerYWrt2rXXfH3/8YXJxcTFlZmY2eb8JEyaYbr/9dpMjGjFihOmWW26xXjYYDKaYmBjT7NmzG739BRdcYDr99NPr7Rs5cqTphhtuMHWF19eS76WjkWPzxx9/POZt7rvvPlPfvn3r7bvwwgtNU6dONXWV17ho0SJ1u+LiYlNnlJeXp8q/ZMmSJm/T2b6HjowZQAdVWlqKkJCQJq9fv369+rUkVYYWkhJPSEjAypUr0ZVItYb8gu3Vq5fKrhUWFqIrkIyEVM3YfoYyN6VU1TnaZyjlkWrfYcOGWfdJuWU+bMlcHssXX3yBsLAw9OvXDw8++CAqKyvhCNla+Q7ZvvfyWuRyU++97Le9vZCMmqN9Vif6+oRU6ScmJiI+Ph4zZsxQGd+uojN9fq01aNAg1azklFNOwfLly9GZznviWOc+Z/oc25um3Z+BWmzfvn14/fXX8cILLzR5GwkcPDw8jmprFhkZ6bDtPU6EVP9Ktba0j0xLS1PV4qeddpr6sru5uaEzs3xO8pk5+mco5WlYjaTRaNQf6mOV9ZJLLlEBhbRh2rJlC+6//35VPTVnzhzYU0FBAQwGQ6PvvTTJaIy8zs7wWZ3o65MfWB9++CEGDBigTsTy90fatEoQGBcXh86uqc9Pq9WiqqpKtcHt7CTok+Yk8kOtpqYG//vf/1Q7XPmRJm0fHZk0g5Jq+bFjx6ofi03pTN9DR8cMYDt64IEHGm2Qa7s0/GOcmZmpgh5pSyZtp7ria2yJiy66CGeddZZq6CvtPKTt2dq1a1VWsCu8Pntr79cnbQTl17l8ftKG8NNPP8WPP/6ognlyLKNHj8bll1+uskcTJkxQQXp4eLhqm0ydgwTxN9xwA4YOHaqCdwnoZS3tyh2dtAWUdnxff/21vYviNJgBbEd333236sV6LMnJydZt6cQhDZTlC/vee+8d835RUVGqmqekpKReFlB6Act1jvoaW0seS6oTJUs6ZcoUdObXZ/mc5DOTX+4WcllOwh2hua9Pytqw84Ber1c9g1tyvEn1tpDPT3q724scQ5JBbthr/ljfH9nfktvb04m8vobc3d0xePBg9Vl1BU19ftLxpStk/5oyYsQILFu2DI5s1qxZ1o5lx8s2d6bvoaNjANiO5NezLM0hmT8J/uSX20cffaTa6xyL3E7+QC9YsEAN/yKkau3QoUPql7wjvsa2cPjwYdUG0DZg6qyvT6q15Y+WfIaWgE+qo6S6pqU9pdv79ckxJT82pF2ZHHti4cKFqtrGEtQ1h/S+FB31+TVFmk/I65D3XjLLQl6LXJaTUVPvgVwv1VQW0nOxI79v7fn6GpIq5K1bt2L69OnoCuRzajhciKN+fm1JvnP2/r41Rfq23HrrrapWQGp15G/i8XSm76HDs3cvFDKZDh8+bOrRo4dpypQpajs7O9u62N6mV69eptWrV1v33XjjjaaEhATTwoULTevWrTONHj1aLY7q4MGDpo0bN5oef/xxk5+fn9qWpayszHobeY1z5sxR27L/nnvuUb2a09PTTX///bdpyJAhppSUFFN1dbWps78+8cwzz5iCgoJMP//8s2nLli2qx7P0/q6qqjI5mmnTppkGDx6sjsFly5apz+Hiiy9u8hjdt2+f6YknnlDHpnx+8hqTk5NN48ePNzmCr7/+WvW4/vjjj1Uv5+uvv159Fjk5Oer6yy67zPTAAw9Yb798+XKTRqMxvfDCC6rH/aOPPqp64m/dutXkiFr6+uS4nT9/viktLc20fv1600UXXWTy8vIybd++3eSI5Htl+Y7Jqeyll15S2/I9FPLa5DVa7N+/3+Tj42O699571ef35ptvmtzc3Ezz5s0zOaqWvsaXX37Z9NNPP5n27t2rjkvpge/q6qr+djqim266SfU8X7x4cb3zXmVlpfU2nf176MgYADoAGX5BvtyNLRZyApXL0s3fQoKEm2++2RQcHKz+sJ199tn1gkZHI0O6NPYabV+TXJb3Q8gfgVNPPdUUHh6uvuCJiYmm6667znoC6+yvzzIUzCOPPGKKjIxUJ2v5EbB7926TIyosLFQBnwS3AQEBpquuuqpecNvwGD106JAK9kJCQtRrkx85cvItLS01OYrXX39d/Yjy8PBQw6asWrWq3hA28pna+vbbb009e/ZUt5chRX7//XeTI2vJ67vjjjust5Xjcfr06aYNGzaYHJVlyJOGi+U1yVpeY8P7DBo0SL1G+TFi+110RC19jc8++6ype/fuKnCX793EiRNVgsBRNXXes/1cusL30FG5yH/2zkISERERUcdhL2AiIiIiJ8MAkIiIiMjJMAAkIiIicjIMAImIiIicDANAIiIiIifDAJCIiIjIyTAAJCIiInIyDACJiIiInAwDQCIiIiInwwCQiIiIyMkwACQiIiJyMgwAiYiIiJwMA0AiIiIiJ8MAkIiIiMjJMAAkIiIicjIMAImIiIicDANAIiIiIifDAJCIiIjIyTAAJCIiInIyDACJiIiInAwDQCIiIiInwwCQiIiIyMkwACQiIiJyMgwAiYiIiJwMA0AiIiIiJ8MAkIiIiMjJMAAkIiIicjIMAImIiIicDANAIiIiIifDAJCIiIjIyTAAJCIiIoJz+T+ch3coXPUIPQAAAABJRU5ErkJggg==", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sample_model=SampleModel(name='sample_model')\n", + "sample_model.temperature=5\n", + "sample_model.use_detailed_balance=True\n", + "sample_model.normalise_detailed_balance=True\n", + "\n", + "# Creating components\n", + "gaussian=Gaussian(name='Gaussian',width=0.5,area=1)\n", + "dho = DampedHarmonicOscillator(name='DHO',center=1.0,width=0.3,area=2.0)\n", + "lorentzian = Lorentzian(name='Lorentzian',center=-1.0,width=0.2,area=1.0)\n", + "polynomial = Polynomial(name='Polynomial',coefficients=[0.1, 0, 0.5]) # y=0.1+0.5*x^2\n", + "\n", + "sample_model.add_component(gaussian)\n", + "sample_model.add_component(dho)\n", + "sample_model.add_component(lorentzian)\n", + "sample_model.add_component(polynomial)\n", + "\n", + "\n", + "x=np.linspace(-2, 2, 100)\n", + "\n", + "plt.figure()\n", + "y=sample_model.evaluate(x)\n", + "plt.plot(x, y, label='Sample Model')\n", + "\n", + "for component in sample_model.values():\n", + " y=sample_model.evaluate_component(x,component.name)\n", + " plt.plot(x, y, label=component.name)\n", + "\n", + "plt.legend()\n", + "plt.title('Sample model at 5 K with detailed balance')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "bd1e57cd", + "metadata": {}, + "outputs": [], + "source": [ + "sample_model['Gaussian'].fix_all_parameters()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "115f672d", + "metadata": {}, + "outputs": [], + "source": [ + "sample_mode=SampleModel(name=\"TestSampleModel\")\n", + "component1 = Gaussian(\n", + " name=\"TestGaussian\", area=1.0, center=0.0, width=1.0, unit=\"meV\"\n", + ")\n", + "component2 = Lorentzian(\n", + " name=\"TestLorentzian\", area=2.0, center=1.0, width=0.5, unit=\"meV\"\n", + ")\n", + "sample_model.add_component(component1)\n", + "sample_model.add_component(component2)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "newdynamics", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/easydynamics/sample_model/__init__.py b/src/easydynamics/sample_model/__init__.py index a64ffd2..2b1274f 100644 --- a/src/easydynamics/sample_model/__init__.py +++ b/src/easydynamics/sample_model/__init__.py @@ -6,6 +6,7 @@ Polynomial, Voigt, ) +from .sample_model import SampleModel __all__ = [ "SampleModel", diff --git a/src/easydynamics/sample_model/sample_model.py b/src/easydynamics/sample_model/sample_model.py index 60310cc..1726be4 100644 --- a/src/easydynamics/sample_model/sample_model.py +++ b/src/easydynamics/sample_model/sample_model.py @@ -1,18 +1,22 @@ - -from typing import Dict, List, Union, Tuple +import warnings +from collections.abc import MutableMapping +from copy import copy +from typing import Dict, List, Optional, Union import numpy as np - -from easyscience.variable import Parameter +import scipp as sc from easyscience.base_classes import ObjBase +from easyscience.variable import Parameter +from scipp import UnitError -from easydynamics.utils import detailed_balance_factor -from .components import ModelComponent +from easydynamics.utils import _detailed_balance_factor as detailed_balance_factor -import scipp as sc +from .components.model_component import ModelComponent +Numeric = Union[float, int] -class SampleModel(ObjBase): + +class SampleModel(ObjBase, MutableMapping): """ A model of the scattering from a sample, combining multiple model components. Optionally applies detailed balancing. @@ -21,8 +25,22 @@ class SampleModel(ObjBase): ---------- components : dict Dictionary of model components keyed by name. + temperature : Parameter + Temperature parameter for detailed balance. + use_detailed_balance : bool + Whether to apply detailed balance. + normalise_detailed_balance : bool + Whether to normalise the detailed balance by temperature. + name : str + Name of the SampleModel. """ - def __init__(self, name: str = "MySampleModel", temperature: Union[float, None] = None): + + def __init__( + self, + name: str = "MySampleModel", + temperature: Optional[Union[Numeric, None]] = None, + temperature_unit: Optional[str] = "K", + ): """ Initialize a new SampleModel. @@ -30,25 +48,53 @@ def __init__(self, name: str = "MySampleModel", temperature: Union[float, None] ---------- name : str Name of the sample model. - temperature : float or None, optional + temperature : Number or None, optional + Temperature for detailed balance. + temperature_unit : str, default 'K' + Unit of the temperature. """ - + self.components: Dict[str, ModelComponent] = {} super().__init__(name=name) + # If temperature is given, create a Parameter and enable detailed balance. if temperature is not None: - self._temperature = Parameter(name="temperature", value=temperature, unit='K', fixed=True) + self._temperature = Parameter( + name="temperature", value=temperature, unit=temperature_unit, fixed=True + ) self._use_detailed_balance = True else: - self._temperature=None + self._temperature = None self._use_detailed_balance = False - def add_component(self, component: ModelComponent): + self._normalise_detailed_balance = ( + True # Whether to normalise by temperature when using detailed balance. + ) + + ############################################## + # Methods for managing components # + ############################################## + + def add_component( + self, component: ModelComponent, name: Optional[str] = None + ) -> None: """ Add a model component to the SampleModel. Component names must be unique. + Parameters + ---------- + component : ModelComponent + The model component to add. + name : str, optional + Name to assign to the component. If None, uses the component's own name. """ - if component.name in self.components: - raise ValueError(f"Component with name '{component.name}' already exists.") - self.components[component.name] = component + if name is None: + name = component.name + if name in self.components: + raise ValueError(f"Component with name '{name}' already exists.") + + if not isinstance(component, ModelComponent): + raise TypeError("component must be an instance of ModelComponent.") + + self.components[name] = component def remove_component(self, name: str): """ @@ -58,8 +104,8 @@ def remove_component(self, name: str): ---------- name : str Name of the component to remove. - """ + if name not in self.components: raise KeyError(f"No component named '{name}' exists in the model.") del self.components[name] @@ -73,75 +119,47 @@ def list_components(self) -> List[str]: List[str] Component names. """ + return list(self.components.keys()) def clear_components(self): """ Remove all components from the model. """ - self.components.clear() - - def __getitem__(self, key: str) -> ModelComponent: - """ - Access a component by name. - - Parameters - ---------- - key : str - Name of the component. - - Returns - ------- - ModelComponent - """ - return self.components[key] - def __setitem__(self, key: str, value: ModelComponent): - """ - Set or replace a component by name using dictionary-like syntax. + self.components.clear() - Parameters - ---------- - key : str - Name of the component. - value : ModelComponent - The component to assign. + def normalize_area(self) -> None: + # Useful for convolutions. """ - self.components[key] = value - - def __contains__(self, name: str) -> bool: + Normalize the areas of all components so they sum to 1. """ - Check if a component exists in the model. + area_params = [] + total_area = 0.0 - Parameters - ---------- - name : str - Name of the component. + for component in self.components.values(): + if hasattr(component, "area"): + area_params.append(component.area) + total_area += component.area.value + else: + warnings.warn( + f"Component '{component.name}' does not have an 'area' attribute and will be skipped in normalization." + ) - Returns - ------- - bool - """ - return name in self.components + if total_area == 0: + raise ValueError("Total area is zero; cannot normalize.") - def __repr__(self): - """ - Return a string representation of the SampleModel. + for param in area_params: + param.value /= total_area - Returns - ------- - str - """ - comp_names = ", ".join(self.components.keys()) or "No components" - temp_str = (f" | Temperature: {self._temperature.value} {self._temperature.unit}" - if self._use_detailed_balance else "") - return (f"") + ########################################################## + # Methods for temperature and detailed balance # + ########################################################## @property def temperature(self) -> Parameter: """ - Access the temperature parameter. + Get the temperature. Returns ------- @@ -150,37 +168,56 @@ def temperature(self) -> Parameter: return self._temperature @temperature.setter - def temperature(self, value: Union[float, None], unit: str = 'K'): + def temperature(self, value: Union[Numeric, None]): """ - Set the temperature and enables detailed balance if value is non-negative. + Set the temperature. Parameters ---------- - value : float - Temperature value. - unit : str, default 'K' - Unit of the temperature. + value : Number + Temperature value. If None, removes temperature and disables detailed balance. """ + # If None, disable detailed balance and remove temperature parameter. if value is None: self._use_detailed_balance = False self._temperature = None return + if not isinstance(value, Numeric): + raise TypeError("Temperature must be a number or None.") + value = float(value) + if value < 0: raise ValueError("Temperature must be non-negative.") if isinstance(self._temperature, Parameter): self._temperature.value = value else: - self._temperature = Parameter(name="temperature", value=value, unit=unit, fixed=True) + self._temperature = Parameter( + name="temperature", value=value, unit="K", fixed=True + ) + + def convert_temperature_unit(self, new_unit: Union[str, sc.Unit]): + """ + Convert the temperature parameter to a new unit. + + Parameters + ---------- + new_unit : str or sc.Unit + The new unit for the temperature. + """ + if self._temperature is None: + raise ValueError("Temperature is not set; cannot convert units.") - if not self.use_detailed_balance: - self.use_detailed_balance = value >= 0 + try: + self._temperature.convert_unit(new_unit) + except Exception as e: + raise UnitError(f"Failed to convert temperature to unit '{new_unit}': {e}") @property def use_detailed_balance(self) -> bool: """ - Indicates whether detailed balance is enabled. + True if detailed balance is enabled, otherwise False. Returns ------- @@ -189,9 +226,9 @@ def use_detailed_balance(self) -> bool: return self._use_detailed_balance @use_detailed_balance.setter - def use_detailed_balance(self, value: bool): + def use_detailed_balance(self, value: bool) -> None: """ - Enable or disable the use of detailed balance. + If True, enables the use of detailed balance. Otherwise disables it. Parameters ---------- @@ -200,81 +237,98 @@ def use_detailed_balance(self, value: bool): """ self._use_detailed_balance = value - def evaluate(self, x: Union[float,np.ndarray,sc.Variable]) -> np.ndarray: + @property + def normalise_detailed_balance(self) -> bool: + """ + If True, detailed balance will be normalised by temperature. If False, it will not be normalised. + + """ + return self._normalise_detailed_balance + + @normalise_detailed_balance.setter + def normalise_detailed_balance(self, value: bool) -> None: + """ + If True, normalises the detailed balance by temperature. + + Parameters + ---------- + value : bool + True to normalise, False otherwise. + """ + self._normalise_detailed_balance = value + + ########################################################## + # Evaluate # + ########################################################## + + def evaluate( + self, x: Union[Numeric, list, np.ndarray, sc.Variable, sc.DataArray] + ) -> np.ndarray: """ Evaluate the sum of all components, optionally applying detailed balance. Parameters ---------- - x : np.ndarray or scipp.array + x : Number, list, np.ndarray, sc.Variable, or sc.DataArray + Energy axis. Returns ------- np.ndarray Evaluated model values. """ - result = np.zeros_like(x, dtype=float) - for component in self.components.values(): - result += component.evaluate(x) - - #TODO: handle units properly + result = sum( + (component.evaluate(x) for component in self.components.values()), 0 + ) if self.use_detailed_balance and self._temperature.value >= 0: - result *= detailed_balance_factor(x, self._temperature.value) + result *= detailed_balance_factor( + energy=x, + temperature=self._temperature, + divide_by_temperature=self._normalise_detailed_balance, + ) return result - def evaluate_component(self, name: str, x: Union[float,np.ndarray,sc.Variable]) -> np.ndarray: + def evaluate_component( + self, + x: Union[Numeric, list, np.ndarray, sc.Variable, sc.DataArray], + name: str, + ) -> np.ndarray: """ Evaluate a single component by name, optionally applying detailed balance. Parameters ---------- + x : Number, list, np.ndarray, sc.Variable, or sc.DataArray + Energy axis. name : str Component name. - x : np.ndarray - Energy axis. Returns ------- np.ndarray Evaluated values for the specified component. - - Raises - ------ - KeyError - If the component is not found. """ if name not in self.components: raise KeyError(f"No component named '{name}' exists.") result = self.components[name].evaluate(x) - if self._use_detailed_balance and self._temperature.value >= 0: - result *= detailed_balance_factor(x, self._temperature.value) + if self.use_detailed_balance and self._temperature.value >= 0: + result *= detailed_balance_factor( + energy=x, + temperature=self._temperature, + divide_by_temperature=self._normalise_detailed_balance, + ) return result - def normalize_area(self): - """ - Normalize the areas of all components so they sum to 1. - """ - area_params = [] - total_area = 0.0 - - for component in self.components.values(): - for param in component.get_parameters(): - if 'area' in param.name.lower(): - area_params.append(param) - total_area += param.value - - if total_area == 0: - raise ValueError("Total area is zero; cannot normalize.") - - for param in area_params: - param.value /= total_area + ############################################## + # Methods for managing parameters # + ############################################## def get_parameters(self) -> List[Parameter]: """ - Return all parameters from the model, including temperature. + Return all parameters in the SampleModel. Returns ------- @@ -287,8 +341,8 @@ def get_parameters(self) -> List[Parameter]: for comp in self.components.values(): params.extend(comp.get_parameters()) return params - - def get_fit_parameters(self): + + def get_fit_parameters(self) -> List[Parameter]: """ Get all fit parameters, removing fixed and dependent parameters. @@ -298,176 +352,141 @@ def get_fit_parameters(self): parameters = self.get_parameters() fit_parameters = [] - + for parameter in parameters: - is_not_fixed = not getattr(parameter, 'fixed', False) - is_independent = getattr(parameter, '_independent', True) - + is_not_fixed = not getattr(parameter, "fixed", False) + is_independent = getattr(parameter, "_independent", True) + if is_not_fixed and is_independent: fit_parameters.append(parameter) - + return fit_parameters - - def fix_all_parameters(self): + def fix_all_parameters(self) -> None: """ - Fix all unfixed parameters in the model. + Fix all free parameters in the model. """ for param in self.get_parameters(): param.fixed = True - def free_all_parameters(self): + def free_all_parameters(self) -> None: """ Free all fixed parameters in the model. """ for param in self.get_parameters(): param.fixed = False - def fix_all_component_parameters(self,component_name: str): - """ - Fix all unfixed parameters in the specified component. - """ - if component_name not in self.components: - raise ValueError(f"Component '{component_name}' not found.") - - self.components[component_name].fix_all_parameters() + ############################################## + # dunder methods # + ############################################## - def free_all_component_parameters(self, component_name: str): + def __copy__(self) -> "SampleModel": """ - Free all fixed parameters in the specified component. - """ - if component_name not in self.components: - raise ValueError(f"Component '{component_name}' not found.") - - self.components[component_name].free_all_parameters() + Create a deep copy of the SampleModel with independent parameters. - def fix_component_parameter(self,component_name: str, parameter_name: str): - """ - Fix a specific parameter in the specified component. + Returns + ------- + SampleModel + A new instance with copied components and parameters. """ - if component_name not in self.components: - raise ValueError(f"Component '{component_name}' not found.") - component = self.components[component_name] - param = component.get_parameter(parameter_name) - if param is None: - raise ValueError(f"Parameter '{parameter_name}' not found in component '{component_name}'.") + new_model = SampleModel( + name=self.name, + temperature=self._temperature.value if self._temperature else None, + ) - param.fixed = True + new_model.use_detailed_balance = self._use_detailed_balance - def free_component_parameter(self, component_name: str, parameter_name: str): - """ - Free a specific parameter in the specified component. - """ - if component_name not in self.components: - raise ValueError(f"Component '{component_name}' not found.") + for comp in self.components.values(): + new_model.add_component(copy(comp)) - component = self.components[component_name] - param = component.get_parameter(parameter_name) - if param is None: - raise ValueError(f"Parameter '{parameter_name}' not found in component '{component_name}'.") + return new_model - param.fixed = False + ############################################## + # dict-like behaviour # + ############################################## - def update_values_from( - self, - other: "SampleModel", - *, - only_free: bool = True, - )-> Dict[str, Tuple[float, float]]: + def __getitem__(self, key: str) -> ModelComponent: """ - Overwrite this model's Parameter.values from another SampleModel, matching by - component name and Parameter.name. This is used to copy fit results when doing sequential fitting. + Access a component by name. Parameters ---------- - other : SampleModel - Source of values. - only_free : bool, default True - If True, skip Parameters in *self* that are fixed. + key : str + Name of the component. Returns ------- - Dict[str, Tuple[float, float]] - Mapping key -> (old_value, new_value), where key is - ".". - + ModelComponent """ - if not isinstance(other, SampleModel): - raise TypeError("other must be a SampleModel") - - report: Dict[str, Tuple[float, float]] = {} - - # Check that components are the same - self_names = set(self.components.keys()) - other_names = set(other.components.keys()) - - if self_names != other_names: - missing = self_names - other_names - extra = other_names - self_names - raise ValueError( - f"Component name mismatch.\n" - f" Missing in source: {missing or '{}'}\n" - f" Extra in source: {extra or '{}'}" - ) - + return self.components[key] - # Go through components - for cname in self_names: - c_self = self.components[cname] - c_other = other.components[cname] + def __setitem__(self, key: str, value: ModelComponent) -> None: + """ + Set or replace a component. - # Check that parameters are the same - self_params = {p.name: p for p in c_self.get_parameters()} - other_params = {p.name: p for p in c_other.get_parameters()} + Parameters + ---------- + key : str + Name of the component. + value : ModelComponent + The component to assign. + """ + if not isinstance(value, ModelComponent): + raise TypeError("Value must be an instance of ModelComponent.") + self.components[key] = value - if set(self_params) != set(other_params): - missing = set(self_params) - set(other_params) - extra = set(other_params) - set(self_params) - raise ValueError( - f"Parameter name mismatch in component '{cname}'.\n" - f" Missing in source: {missing or '{}'}\n" - f" Extra in source: {extra or '{}'}" - ) + def __delitem__(self, key: str) -> None: + """ + Remove a component by name. + Parameters + ---------- + key : str + Name of the component to remove. + """ + if not isinstance(key, str): + raise TypeError("Key must be a string.") + if key not in self.components: + raise KeyError(f"No component named '{key}' exists in the model.") - for pname in set(self_params): - p_self = self_params[pname] - p_other = other_params[pname] + self.remove_component(key) - if only_free and getattr(p_self, "fixed", False): - continue + def __contains__(self, name: str) -> bool: + """ + Check if a component exists in the model. - # Units: convert units to other's unit if they differ - u_self = getattr(p_self, "unit", None) - u_other = getattr(p_other, "unit", None) - if u_self != u_other: - p_self.convert_unit(u_other) + Parameters + ---------- + name : str + Name of the component. - # Update value, but save the old one. - old = p_self.value - p_self.value = p_other.value - report[f"{cname}.{pname}"] = (old, p_self.value) + Returns + ------- + bool + """ + return name in self.components - return report + def __iter__(self) -> iter: + """Iterate over component names.""" + return iter(self.components) + def __len__(self) -> int: + """Return the number of components in the model.""" + return len(self.components) - - def copy(self) -> "SampleModel": + def __repr__(self) -> str: """ - Create a deep copy of the SampleModel with independent parameters. + Return a string representation of the SampleModel. Returns ------- - SampleModel - A new instance with copied components and parameters. + str """ - - new_model = SampleModel(name=self.name, temperature=self._temperature.value if self._temperature else None) - - new_model.use_detailed_balance = self._use_detailed_balance - - for comp in self.components.values(): - new_model.add_component(comp.copy()) - - return new_model + comp_names = ", ".join(self.components.keys()) or "No components" + temp_str = ( + f" | Temperature: {self._temperature.value} {self._temperature.unit}" + if self._use_detailed_balance + else "" + ) + return f"" diff --git a/tests/unit_tests/sample_model/test_sample_model.py b/tests/unit_tests/sample_model/test_sample_model.py index bd9a606..7556533 100644 --- a/tests/unit_tests/sample_model/test_sample_model.py +++ b/tests/unit_tests/sample_model/test_sample_model.py @@ -1,11 +1,12 @@ -import pytest import numpy as np +import pytest +from easyscience.variable import Parameter from scipy.integrate import simpson -from easyscience.variable import Parameter -from easydynamics.sample import SampleModel, Gaussian, Lorentzian -from easydynamics.sample.components import ModelComponent -from easydynamics.utils import detailed_balance_factor +from easydynamics.sample_model import Gaussian, Lorentzian, SampleModel +from easydynamics.sample_model.components.model_component import ModelComponent +from easydynamics.utils import _detailed_balance_factor as detailed_balance_factor + class TestSampleModel: @pytest.fixture @@ -15,83 +16,101 @@ def sample_model(self): # ───── Component Management ───── def test_add_component(self, sample_model): - #When - component = Gaussian(name="TestComponent", area=1.0, center=0.0, width=1.0, unit='meV') - #Then + # When + component = Gaussian( + name="TestComponent", area=1.0, center=0.0, width=1.0, unit="meV" + ) + # Then sample_model.add_component(component) - #Expect + # Expect assert "TestComponent" in sample_model.components def test_add_duplicate_component_raises(self, sample_model): - #When - component = Gaussian(name="Dup", area=1.0, center=0.0, width=1.0, unit='meV') - #Then + # When + component = Gaussian(name="Dup", area=1.0, center=0.0, width=1.0, unit="meV") + # Then sample_model.add_component(component) - #Expect + # Expect with pytest.raises(ValueError, match="already exists"): sample_model.add_component(component) def test_remove_component(self, sample_model): - #When - component = Gaussian(name="TestComponent", area=1.0, center=0.0, width=1.0, unit='meV') - #Then + # When + component = Gaussian( + name="TestComponent", area=1.0, center=0.0, width=1.0, unit="meV" + ) + # Then sample_model.add_component(component) sample_model.remove_component("TestComponent") - #Expect + # Expect assert "TestComponent" not in sample_model.components def test_remove_nonexistent_component_raises(self, sample_model): - #When Then Expect - with pytest.raises(KeyError, match="No component named 'NonExistentComponent' exists"): + # When Then Expect + with pytest.raises( + KeyError, match="No component named 'NonExistentComponent' exists" + ): sample_model.remove_component("NonExistentComponent") def test_getitem(self, sample_model): - #When - component = Gaussian(name="TestComponent", area=1.0, center=0.0, width=1.0, unit='meV') - #Then + # When + component = Gaussian( + name="TestComponent", area=1.0, center=0.0, width=1.0, unit="meV" + ) + # Then sample_model.add_component(component) - #Expect + # Expect assert sample_model["TestComponent"] is component def test_setitem(self, sample_model): - #When + # When component = ModelComponent(name="TestComponent") - #Then + # Then sample_model["TestComponent"] = component - #Expect + # Expect assert sample_model["TestComponent"] is component def test_contains_component(self, sample_model): - #When - component = Gaussian(name="TestGaussian", area=1.0, center=0.0, width=1.0, unit='meV') - #Then + # When + component = Gaussian( + name="TestGaussian", area=1.0, center=0.0, width=1.0, unit="meV" + ) + # Then sample_model.add_component(component) - #Expect + # Expect assert "TestGaussian" in sample_model assert "NonExistentComponent" not in sample_model def test_list_components(self, sample_model): - #When - component1 = Gaussian(name="TestGaussian1", area=2.0, center=0.0, width=1.0, unit='meV') - component2 = Gaussian(name="TestGaussian2", area=3.0, center=1.0, width=0.5, unit='meV') + # When + component1 = Gaussian( + name="TestGaussian1", area=2.0, center=0.0, width=1.0, unit="meV" + ) + component2 = Gaussian( + name="TestGaussian2", area=3.0, center=1.0, width=0.5, unit="meV" + ) sample_model.add_component(component1) sample_model.add_component(component2) - #Then + # Then components = sample_model.list_components() - #Expect + # Expect assert len(components) == 2 - assert components[0] == 'TestGaussian1' - assert components[1] == 'TestGaussian2' + assert components[0] == "TestGaussian1" + assert components[1] == "TestGaussian2" def test_clear_components(self, sample_model): - #when - component1 = Gaussian(name="TestGaussian1", area=2.0, center=0.0, width=1.0, unit='meV') - component2 = Gaussian(name="TestGaussian2", area=3.0, center=1.0, width=0.5, unit='meV') + # when + component1 = Gaussian( + name="TestGaussian1", area=2.0, center=0.0, width=1.0, unit="meV" + ) + component2 = Gaussian( + name="TestGaussian2", area=3.0, center=1.0, width=0.5, unit="meV" + ) sample_model.add_component(component1) sample_model.add_component(component2) - #Then + # Then sample_model.clear_components() - #Expect + # Expect assert len(sample_model.components) == 0 # ───── Temperature and Detailed Balance ───── @@ -103,12 +122,11 @@ def test_temperature_init(self, sample_model): # assert sample_model._temperature.unit == 'K' def test_set_temperature(self, sample_model): - # When Then + # When Then sample_model.temperature = 300 # Expect assert sample_model._temperature.value == 300 - assert sample_model._temperature.unit == 'K' - assert sample_model._use_detailed_balance is True + assert sample_model._temperature.unit == "K" def test_negative_temperature_throws(self, sample_model): # When @@ -129,8 +147,12 @@ def test_use_detailed_balance(self, sample_model): def test_evaluate(self, sample_model): # When - component1 = Gaussian(name="Gaussian1", area=1.0, center=0.0, width=1.0, unit='meV') - component2 = Lorentzian(name="Lorentzian1", area=2.0, center=1.0, width=0.5, unit='meV') + component1 = Gaussian( + name="Gaussian1", area=1.0, center=0.0, width=1.0, unit="meV" + ) + component2 = Lorentzian( + name="Lorentzian1", area=2.0, center=1.0, width=0.5, unit="meV" + ) sample_model.add_component(component1) sample_model.add_component(component2) # Then @@ -140,69 +162,124 @@ def test_evaluate(self, sample_model): expected_result = component1.evaluate(x) + component2.evaluate(x) np.testing.assert_allclose(result, expected_result, rtol=1e-5) - def test_evaluate_with_detailed_balance(self, sample_model): + @pytest.mark.parametrize( + "normalise_db", [True, False], ids=["Normalise DB", "Don't normalise DB"] + ) + def test_evaluate_with_detailed_balance(self, sample_model, normalise_db): # When sample_model.temperature = 300 - component1 = Gaussian(name="Gaussian1", area=1.0, center=0.0, width=1.0, unit='meV') - component2 = Lorentzian(name="Lorentzian1", area=2.0, center=1.0, width=0.5, unit='meV') + component1 = Gaussian( + name="Gaussian1", area=1.0, center=0.0, width=1.0, unit="meV" + ) + component2 = Lorentzian( + name="Lorentzian1", area=2.0, center=1.0, width=0.5, unit="meV" + ) sample_model.add_component(component1) sample_model.add_component(component2) + sample_model.use_detailed_balance = True + sample_model.normalise_detailed_balance = normalise_db + x = np.linspace(-5, 5, 100) + # Then result = sample_model.evaluate(x) + # Expect expected_result = component1.evaluate(x) + component2.evaluate(x) - expected_result *= detailed_balance_factor(x, sample_model._temperature.value) + expected_result *= detailed_balance_factor( + energy=x, + temperature=sample_model._temperature, + divide_by_temperature=normalise_db, + ) np.testing.assert_allclose(result, expected_result, rtol=1e-5) def test_evaluate_component(self, sample_model): # When - component1 = Gaussian(name="TestGaussian", area=1.0, center=0.0, width=1.0, unit='meV') - component2 = Lorentzian(name="TestLorentzian", area=2.0, center=1.0, width=0.5, unit='meV') + component1 = Gaussian( + name="TestGaussian", area=1.0, center=0.0, width=1.0, unit="meV" + ) + component2 = Lorentzian( + name="TestLorentzian", area=2.0, center=1.0, width=0.5, unit="meV" + ) sample_model.add_component(component1) sample_model.add_component(component2) # Then x = np.linspace(-5, 5, 100) - result1 = sample_model.evaluate_component("TestGaussian", x) - result2 = sample_model.evaluate_component("TestLorentzian", x) + result1 = sample_model.evaluate_component(x, "TestGaussian") + result2 = sample_model.evaluate_component(x, "TestLorentzian") + # Expect expected_result1 = component1.evaluate(x) expected_result2 = component2.evaluate(x) np.testing.assert_allclose(result1, expected_result1, rtol=1e-5) np.testing.assert_allclose(result2, expected_result2, rtol=1e-5) - def test_evaluate_component_with_detailed_balance(self, sample_model): + @pytest.mark.parametrize( + "normalise_db", [True, False], ids=["Normalise DB", "Don't normalise DB"] + ) + def test_evaluate_component_with_detailed_balance(self, sample_model, normalise_db): # When - component1 = Gaussian(name="TestGaussian", area=1.0, center=0.0, width=1.0, unit='meV') - component2 = Lorentzian(name="TestLorentzian", area=2.0, center=1.0, width=0.5, unit='meV') + component1 = Gaussian( + name="TestGaussian", area=1.0, center=0.0, width=1.0, unit="meV" + ) + component2 = Lorentzian( + name="TestLorentzian", area=2.0, center=1.0, width=0.5, unit="meV" + ) sample_model.add_component(component1) sample_model.add_component(component2) sample_model.temperature = 300 + sample_model.use_detailed_balance = True + sample_model.normalise_detailed_balance = normalise_db + # Then x = np.linspace(-5, 5, 100) - result1 = sample_model.evaluate_component('TestGaussian', x) - result2 = sample_model.evaluate_component('TestLorentzian', x) + result1 = sample_model.evaluate_component(x, name="TestGaussian") + result2 = sample_model.evaluate_component(x, name="TestLorentzian") # Expect expected_result1 = component1.evaluate(x) expected_result2 = component2.evaluate(x) - expected_result1 *= detailed_balance_factor(x, sample_model._temperature.value) - expected_result2 *= detailed_balance_factor(x, sample_model._temperature.value) + expected_result1 *= detailed_balance_factor( + energy=x, + temperature=sample_model.temperature, + divide_by_temperature=normalise_db, + ) + expected_result2 *= detailed_balance_factor( + energy=x, + temperature=sample_model.temperature, + divide_by_temperature=normalise_db, + ) np.testing.assert_allclose(result1, expected_result1, rtol=1e-5) np.testing.assert_allclose(result2, expected_result2, rtol=1e-5) def test_evaluate_nonexistent_component_raises(self, sample_model): - # When Then Expect + # WHEN + component1 = Gaussian( + name="TestGaussian", area=1.0, center=0.0, width=1.0, unit="meV" + ) + component2 = Lorentzian( + name="TestLorentzian", area=2.0, center=1.0, width=0.5, unit="meV" + ) + sample_model.add_component(component1) + sample_model.add_component(component2) x = np.linspace(-5, 5, 100) - with pytest.raises(KeyError, match="No component named 'NonExistentComponent' exists"): - sample_model.evaluate_component("NonExistentComponent", x) + + # Then Expect + with pytest.raises( + KeyError, match="No component named 'NonExistentComponent' exists" + ): + sample_model.evaluate_component(x, "NonExistentComponent") # ───── Utilities ───── def test_normalize_area(self, sample_model): # When - component1 = Gaussian(name="TestGaussian1", area=2.0, center=0.0, width=1.0, unit='meV') - component2 = Gaussian(name="TestGaussian2", area=3.0, center=1.0, width=0.5, unit='meV') + component1 = Gaussian( + name="TestGaussian1", area=2.0, center=0.0, width=1.0, unit="meV" + ) + component2 = Gaussian( + name="TestGaussian2", area=3.0, center=1.0, width=0.5, unit="meV" + ) sample_model.add_component(component1) sample_model.add_component(component2) # Then @@ -215,15 +292,17 @@ def test_normalize_area(self, sample_model): def test_get_parameters(self, sample_model): # When - component = Gaussian(name="TestGaussian", area=1.0, center=0.0, width=1.0, unit='meV') + component = Gaussian( + name="TestGaussian", area=1.0, center=0.0, width=1.0, unit="meV" + ) sample_model.add_component(component) # Then parameters = sample_model.get_parameters() # Expect assert len(parameters) == 3 - assert parameters[0].name == 'TestGaussian area' - assert parameters[1].name == 'TestGaussian center' - assert parameters[2].name == 'TestGaussian width' + assert parameters[0].name == "TestGaussian area" + assert parameters[1].name == "TestGaussian center" + assert parameters[2].name == "TestGaussian width" assert all(isinstance(param, Parameter) for param in parameters) def test_get_parameters_no_components(self, sample_model): @@ -234,7 +313,9 @@ def test_get_parameters_no_components(self, sample_model): def test_repr_contains_name_and_components(self, sample_model): # When - component = Gaussian(name="TestGaussian", area=1.0, center=0.0, width=1.0, unit='meV') + component = Gaussian( + name="TestGaussian", area=1.0, center=0.0, width=1.0, unit="meV" + ) sample_model.add_component(component) # Then rep = repr(sample_model) @@ -251,11 +332,12 @@ def test_repr_contains_name_and_components(self, sample_model): def test_str_contains_name_and_components(self, sample_model): # When - component = Gaussian(name="TestGaussian", area=1.0, center=0.0, width=1.0, unit='meV') + component = Gaussian( + name="TestGaussian", area=1.0, center=0.0, width=1.0, unit="meV" + ) sample_model.add_component(component) # Then str_repr = str(sample_model) # Expect assert "SampleModel" in str_repr assert "TestGaussian" in str_repr - From 2fb844ba691ebb3bbedb201efe5b8d427633a5b2 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 17 Oct 2025 10:57:53 +0200 Subject: [PATCH 03/71] Improve tests --- examples/sample_model.ipynb | 106 +++- src/easydynamics/sample_model/sample_model.py | 52 +- .../sample_model/test_sample_model.py | 514 ++++++++++-------- 3 files changed, 433 insertions(+), 239 deletions(-) diff --git a/examples/sample_model.ipynb b/examples/sample_model.ipynb index fa70738..3875874 100644 --- a/examples/sample_model.ipynb +++ b/examples/sample_model.ipynb @@ -32,7 +32,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "85c000d048fa447c92f106becdf27e5f", + "model_id": "85227f7e718342749b433c8067629028", "version_major": 2, "version_minor": 0 }, @@ -93,7 +93,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "fbcf9802343e43e0a89319740a8bf595", + "model_id": "f1ca548a33f442258664aaff8e549814", "version_major": 2, "version_minor": 0 }, @@ -161,7 +161,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 5, "id": "115f672d", "metadata": {}, "outputs": [], @@ -176,6 +176,106 @@ "sample_model.add_component(component1)\n", "sample_model.add_component(component2)" ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "f4e1fb01", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sample_mode=SampleModel(name=\"TestSampleModel\")\n", + "not sample_mode.components" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "f8cec9a3", + "metadata": {}, + "outputs": [ + { + "ename": "AssertionError", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mAssertionError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[7]\u001b[39m\u001b[32m, line 26\u001b[39m\n\u001b[32m 24\u001b[39m copied_comp = model_copy.components[name]\n\u001b[32m 25\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m copied_comp \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m comp\n\u001b[32m---> \u001b[39m\u001b[32m26\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m copied_comp.name == comp.name\n\u001b[32m 27\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m param_orig, param_copy \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mzip\u001b[39m(\n\u001b[32m 28\u001b[39m comp.get_parameters(), copied_comp.get_parameters()\n\u001b[32m 29\u001b[39m ):\n\u001b[32m 30\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m param_copy \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m param_orig\n", + "\u001b[31mAssertionError\u001b[39m: " + ] + } + ], + "source": [ + "from copy import copy\n", + "model = SampleModel(name=\"TwoComponentModel\")\n", + "component1 = Gaussian(\n", + " name=\"TestGaussian1\", area=1.0, center=0.0, width=1.0, unit=\"meV\"\n", + ")\n", + "component2 = Lorentzian(\n", + " name=\"TestLorentzian1\", area=2.0, center=1.0, width=0.5, unit=\"meV\"\n", + ")\n", + "model.add_component(component1)\n", + "model.add_component(component2)\n", + "\n", + "sample_model_with_components=model\n", + "\n", + "model_copy = copy(sample_model_with_components)\n", + "\n", + "\n", + "\n", + "assert model_copy is not sample_model_with_components\n", + "assert model_copy.name == \"copy of \" + sample_model_with_components.name\n", + "assert len(model_copy.components) == len(\n", + " sample_model_with_components.components\n", + ")\n", + "for name, comp in sample_model_with_components.components.items():\n", + " copied_comp = model_copy.components[name]\n", + " assert copied_comp is not comp\n", + " assert copied_comp.name == comp.name\n", + " for param_orig, param_copy in zip(\n", + " comp.get_parameters(), copied_comp.get_parameters()\n", + " ):\n", + " assert param_copy is not param_orig\n", + " assert param_copy.name == param_orig.name\n", + " assert param_copy.value == param_orig.value\n", + " assert param_copy.fixed == param_orig.fixed" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "c660f129", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Gaussian(name = copy of TestGaussian1, unit = meV,\n", + " area = ,\n", + " center = ,\n", + " width = )" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model_copy['TestGaussian1']" + ] } ], "metadata": { diff --git a/src/easydynamics/sample_model/sample_model.py b/src/easydynamics/sample_model/sample_model.py index 1726be4..19bf4f1 100644 --- a/src/easydynamics/sample_model/sample_model.py +++ b/src/easydynamics/sample_model/sample_model.py @@ -134,6 +134,9 @@ def normalize_area(self) -> None: """ Normalize the areas of all components so they sum to 1. """ + if not self.components: + raise ValueError("No components in the model to normalize.") + area_params = [] total_area = 0.0 @@ -149,6 +152,9 @@ def normalize_area(self) -> None: if total_area == 0: raise ValueError("Total area is zero; cannot normalize.") + if not np.isfinite(total_area): + raise ValueError("Total area is not finite; cannot normalize.") + for param in area_params: param.value /= total_area @@ -157,7 +163,7 @@ def normalize_area(self) -> None: ########################################################## @property - def temperature(self) -> Parameter: + def temperature(self) -> Union[Parameter, None]: """ Get the temperature. @@ -168,7 +174,7 @@ def temperature(self) -> Parameter: return self._temperature @temperature.setter - def temperature(self, value: Union[Numeric, None]): + def temperature(self, value: Union[Numeric, None]) -> None: """ Set the temperature. @@ -197,7 +203,7 @@ def temperature(self, value: Union[Numeric, None]): name="temperature", value=value, unit="K", fixed=True ) - def convert_temperature_unit(self, new_unit: Union[str, sc.Unit]): + def convert_temperature_unit(self, new_unit: Union[str, sc.Unit]) -> None: """ Convert the temperature parameter to a new unit. @@ -211,8 +217,10 @@ def convert_temperature_unit(self, new_unit: Union[str, sc.Unit]): try: self._temperature.convert_unit(new_unit) - except Exception as e: + except UnitError as e: raise UnitError(f"Failed to convert temperature to unit '{new_unit}': {e}") + except Exception as e: + raise RuntimeError(f"An error occurred during unit conversion: {e}") @property def use_detailed_balance(self) -> bool: @@ -235,6 +243,8 @@ def use_detailed_balance(self, value: bool) -> None: value : bool True to enable, False to disable. """ + if self._temperature is None: + raise ValueError("Temperature must be set to use detailed balance.") self._use_detailed_balance = value @property @@ -277,10 +287,19 @@ def evaluate( np.ndarray Evaluated model values. """ - result = sum( - (component.evaluate(x) for component in self.components.values()), 0 - ) - if self.use_detailed_balance and self._temperature.value >= 0: + + if not self.components: + raise ValueError("No components in the model to evaluate.") + result = None + for component in self.components.values(): + value = component.evaluate(x) + result = value if result is None else result + value + + if ( + self.use_detailed_balance + and self._temperature is not None + and self._temperature.value >= 0 + ): result *= detailed_balance_factor( energy=x, temperature=self._temperature, @@ -313,7 +332,11 @@ def evaluate_component( raise KeyError(f"No component named '{name}' exists.") result = self.components[name].evaluate(x) - if self.use_detailed_balance and self._temperature.value >= 0: + if ( + self.use_detailed_balance + and self._temperature is not None + and self._temperature.value >= 0 + ): result *= detailed_balance_factor( energy=x, temperature=self._temperature, @@ -389,16 +412,21 @@ def __copy__(self) -> "SampleModel": SampleModel A new instance with copied components and parameters. """ + name = "copy of " + self.name new_model = SampleModel( - name=self.name, + name=name, temperature=self._temperature.value if self._temperature else None, ) - new_model.use_detailed_balance = self._use_detailed_balance + if self._temperature: + new_model.use_detailed_balance = self.use_detailed_balance for comp in self.components.values(): - new_model.add_component(copy(comp)) + new_model.add_component(component=copy(comp), name=comp.name) + new_model[comp.name].name = comp.name # Remove 'copy of ' prefix + for par in new_model[comp.name].get_parameters(): + par.name = par.name.removeprefix("copy of ") return new_model diff --git a/tests/unit_tests/sample_model/test_sample_model.py b/tests/unit_tests/sample_model/test_sample_model.py index 7556533..62c33f4 100644 --- a/tests/unit_tests/sample_model/test_sample_model.py +++ b/tests/unit_tests/sample_model/test_sample_model.py @@ -1,9 +1,11 @@ +from copy import copy + import numpy as np import pytest from easyscience.variable import Parameter from scipy.integrate import simpson -from easydynamics.sample_model import Gaussian, Lorentzian, SampleModel +from easydynamics.sample_model import Gaussian, Lorentzian, Polynomial, SampleModel from easydynamics.sample_model.components.model_component import ModelComponent from easydynamics.utils import _detailed_balance_factor as detailed_balance_factor @@ -13,331 +15,395 @@ class TestSampleModel: def sample_model(self): return SampleModel(name="TestSampleModel") + @pytest.fixture + def sample_model_with_components(self): + model = SampleModel(name="TwoComponentModel") + component1 = Gaussian( + name="TestGaussian1", area=1.0, center=0.0, width=1.0, unit="meV" + ) + component2 = Lorentzian( + name="TestLorentzian1", area=2.0, center=1.0, width=0.5, unit="meV" + ) + model.add_component(component1) + model.add_component(component2) + return model + + def test_init_no_temperature(self, sample_model): + # WHEN THEN EXPECT + assert sample_model.name == "TestSampleModel" + assert isinstance(sample_model.components, dict) + assert len(sample_model.components) == 0 + assert not sample_model.use_detailed_balance + + def test_init_with_temperature(self): + # WHEN THEN + sample_model = SampleModel(name="TempModel", temperature=100) + + # EXPECT + assert sample_model.name == "TempModel" + assert isinstance(sample_model.components, dict) + assert len(sample_model.components) == 0 + assert sample_model.use_detailed_balance + assert isinstance(sample_model.temperature, Parameter) + assert sample_model.temperature.value == 100 + # ───── Component Management ───── def test_add_component(self, sample_model): - # When + # WHEN component = Gaussian( name="TestComponent", area=1.0, center=0.0, width=1.0, unit="meV" ) - # Then + # THEN sample_model.add_component(component) - # Expect + # EXPECT assert "TestComponent" in sample_model.components - def test_add_duplicate_component_raises(self, sample_model): - # When - component = Gaussian(name="Dup", area=1.0, center=0.0, width=1.0, unit="meV") - # Then - sample_model.add_component(component) - # Expect - with pytest.raises(ValueError, match="already exists"): - sample_model.add_component(component) - - def test_remove_component(self, sample_model): - # When + def test_add_duplicate_component_raises(self, sample_model_with_components): + # WHEN THEN component = Gaussian( - name="TestComponent", area=1.0, center=0.0, width=1.0, unit="meV" + name="TestGaussian1", area=1.0, center=0.0, width=1.0, unit="meV" ) - # Then - sample_model.add_component(component) - sample_model.remove_component("TestComponent") - # Expect - assert "TestComponent" not in sample_model.components + # EXPECT + with pytest.raises(ValueError, match="already exists"): + sample_model_with_components.add_component(component) - def test_remove_nonexistent_component_raises(self, sample_model): - # When Then Expect + def test_remove_component(self, sample_model_with_components): + # WHEN THEN + sample_model_with_components.remove_component("TestGaussian1") + # EXPECT + assert "TestGaussian1" not in sample_model_with_components.components + + def test_remove_nonexistent_component_raises(self, sample_model_with_components): + # WHEN THEN EXPECT with pytest.raises( KeyError, match="No component named 'NonExistentComponent' exists" ): - sample_model.remove_component("NonExistentComponent") + sample_model_with_components.remove_component("NonExistentComponent") def test_getitem(self, sample_model): - # When + # WHEN component = Gaussian( name="TestComponent", area=1.0, center=0.0, width=1.0, unit="meV" ) - # Then + # THEN sample_model.add_component(component) - # Expect + # EXPECT assert sample_model["TestComponent"] is component def test_setitem(self, sample_model): - # When + # WHEN component = ModelComponent(name="TestComponent") - # Then + # THEN sample_model["TestComponent"] = component - # Expect + # EXPECT assert sample_model["TestComponent"] is component - def test_contains_component(self, sample_model): - # When - component = Gaussian( - name="TestGaussian", area=1.0, center=0.0, width=1.0, unit="meV" - ) - # Then - sample_model.add_component(component) - # Expect - assert "TestGaussian" in sample_model - assert "NonExistentComponent" not in sample_model + def test_contains_component(self, sample_model_with_components): + # WHEN THEN EXPECT + # EXPECT + assert "TestGaussian1" in sample_model_with_components + assert "NonExistentComponent" not in sample_model_with_components - def test_list_components(self, sample_model): - # When - component1 = Gaussian( - name="TestGaussian1", area=2.0, center=0.0, width=1.0, unit="meV" - ) - component2 = Gaussian( - name="TestGaussian2", area=3.0, center=1.0, width=0.5, unit="meV" - ) - sample_model.add_component(component1) - sample_model.add_component(component2) - # Then - components = sample_model.list_components() - # Expect + def test_list_components(self, sample_model_with_components): + # WHEN THEN + components = sample_model_with_components.list_components() + # EXPECT assert len(components) == 2 assert components[0] == "TestGaussian1" - assert components[1] == "TestGaussian2" + assert components[1] == "TestLorentzian1" - def test_clear_components(self, sample_model): - # when - component1 = Gaussian( - name="TestGaussian1", area=2.0, center=0.0, width=1.0, unit="meV" - ) - component2 = Gaussian( - name="TestGaussian2", area=3.0, center=1.0, width=0.5, unit="meV" - ) - sample_model.add_component(component1) - sample_model.add_component(component2) - # Then - sample_model.clear_components() - # Expect - assert len(sample_model.components) == 0 + def test_clear_components(self, sample_model_with_components): + # WHEN THEN + sample_model_with_components.clear_components() + # EXPECT + assert len(sample_model_with_components.components) == 0 # ───── Temperature and Detailed Balance ───── - def test_temperature_init(self, sample_model): - # When Then Expect - assert sample_model._temperature is None - assert sample_model._use_detailed_balance is False - # assert sample_model._temperature.unit == 'K' - def test_set_temperature(self, sample_model): - # When Then + # Set valid temperature + # WHEN THEN sample_model.temperature = 300 - # Expect - assert sample_model._temperature.value == 300 - assert sample_model._temperature.unit == "K" - - def test_negative_temperature_throws(self, sample_model): - # When - sample_model.use_detailed_balance = True - # Then Expect + # EXPECT + assert sample_model.temperature.value == 300 + assert sample_model.temperature.unit == "K" + + # Set temperature to None + # WHEN THEN + sample_model.temperature = None + # EXPECT + assert sample_model.temperature is None + assert not sample_model.use_detailed_balance + + def test_invalid_temperature_raises(self, sample_model): + # WHEN THEN EXPECT + with pytest.raises(TypeError, match="Temperature must be a number or None."): + sample_model.temperature = "invalid" + + def test_negative_temperature_raises(self, sample_model): + # WHEN THEN EXPECT with pytest.raises(ValueError, match="Temperature must be non-negative"): sample_model.temperature = -50 + def test_convert_temperature_unit(self, sample_model): + # WHEN + sample_model.temperature = 300 # Kelvin + # THEN + sample_model.convert_temperature_unit("mK") + # EXPECT + assert np.isclose(sample_model.temperature.value, 300000.0) + assert sample_model.temperature.unit == "mK" + def test_use_detailed_balance(self, sample_model): - # When Then Expect - assert sample_model._use_detailed_balance is False - sample_model._use_detailed_balance = True - assert sample_model._use_detailed_balance is True - sample_model._use_detailed_balance = False - assert sample_model._use_detailed_balance is False + sample_model.temperature = 300 + # WHEN THEN EXPECT + assert sample_model.use_detailed_balance is False + sample_model.use_detailed_balance = True + assert sample_model.use_detailed_balance is True + sample_model.use_detailed_balance = False + assert sample_model.use_detailed_balance is False # ───── Evaluation ───── - def test_evaluate(self, sample_model): - # When - component1 = Gaussian( - name="Gaussian1", area=1.0, center=0.0, width=1.0, unit="meV" - ) - component2 = Lorentzian( - name="Lorentzian1", area=2.0, center=1.0, width=0.5, unit="meV" - ) - sample_model.add_component(component1) - sample_model.add_component(component2) - # Then + def test_evaluate(self, sample_model_with_components): + # WHEN x = np.linspace(-5, 5, 100) - result = sample_model.evaluate(x) - # Expect - expected_result = component1.evaluate(x) + component2.evaluate(x) + result = sample_model_with_components.evaluate(x) + # EXPECT + expected_result = sample_model_with_components["TestGaussian1"].evaluate( + x + ) + sample_model_with_components["TestLorentzian1"].evaluate(x) np.testing.assert_allclose(result, expected_result, rtol=1e-5) @pytest.mark.parametrize( "normalise_db", [True, False], ids=["Normalise DB", "Don't normalise DB"] ) - def test_evaluate_with_detailed_balance(self, sample_model, normalise_db): - # When - sample_model.temperature = 300 - component1 = Gaussian( - name="Gaussian1", area=1.0, center=0.0, width=1.0, unit="meV" - ) - component2 = Lorentzian( - name="Lorentzian1", area=2.0, center=1.0, width=0.5, unit="meV" - ) - sample_model.add_component(component1) - sample_model.add_component(component2) - sample_model.use_detailed_balance = True - sample_model.normalise_detailed_balance = normalise_db + def test_evaluate_with_detailed_balance( + self, sample_model_with_components, normalise_db + ): + # WHEN + sample_model_with_components.temperature = 300 + sample_model_with_components.use_detailed_balance = True + sample_model_with_components.normalise_detailed_balance = normalise_db x = np.linspace(-5, 5, 100) - # Then - result = sample_model.evaluate(x) + # THEN + result = sample_model_with_components.evaluate(x) - # Expect - expected_result = component1.evaluate(x) + component2.evaluate(x) + # EXPECT + expected_result = sample_model_with_components["TestGaussian1"].evaluate( + x + ) + sample_model_with_components["TestLorentzian1"].evaluate(x) expected_result *= detailed_balance_factor( energy=x, - temperature=sample_model._temperature, + temperature=sample_model_with_components.temperature, divide_by_temperature=normalise_db, ) np.testing.assert_allclose(result, expected_result, rtol=1e-5) - def test_evaluate_component(self, sample_model): - # When - component1 = Gaussian( - name="TestGaussian", area=1.0, center=0.0, width=1.0, unit="meV" - ) - component2 = Lorentzian( - name="TestLorentzian", area=2.0, center=1.0, width=0.5, unit="meV" - ) - sample_model.add_component(component1) - sample_model.add_component(component2) - - # Then + def test_evaluate_component(self, sample_model_with_components): + # WHEN THEN x = np.linspace(-5, 5, 100) - result1 = sample_model.evaluate_component(x, "TestGaussian") - result2 = sample_model.evaluate_component(x, "TestLorentzian") + result1 = sample_model_with_components.evaluate_component(x, "TestGaussian1") + result2 = sample_model_with_components.evaluate_component(x, "TestLorentzian1") - # Expect - expected_result1 = component1.evaluate(x) - expected_result2 = component2.evaluate(x) + # EXPECT + expected_result1 = sample_model_with_components["TestGaussian1"].evaluate(x) + expected_result2 = sample_model_with_components["TestLorentzian1"].evaluate(x) np.testing.assert_allclose(result1, expected_result1, rtol=1e-5) np.testing.assert_allclose(result2, expected_result2, rtol=1e-5) @pytest.mark.parametrize( "normalise_db", [True, False], ids=["Normalise DB", "Don't normalise DB"] ) - def test_evaluate_component_with_detailed_balance(self, sample_model, normalise_db): - # When - component1 = Gaussian( - name="TestGaussian", area=1.0, center=0.0, width=1.0, unit="meV" + def test_evaluate_component_with_detailed_balance( + self, sample_model_with_components, normalise_db + ): + # WHEN + sample_model_with_components.temperature = 300 + sample_model_with_components.use_detailed_balance = True + sample_model_with_components.normalise_detailed_balance = normalise_db + + # THEN + x = np.linspace(-5, 5, 100) + result1 = sample_model_with_components.evaluate_component( + x, name="TestGaussian1" ) - component2 = Lorentzian( - name="TestLorentzian", area=2.0, center=1.0, width=0.5, unit="meV" + result2 = sample_model_with_components.evaluate_component( + x, name="TestLorentzian1" ) - sample_model.add_component(component1) - sample_model.add_component(component2) - sample_model.temperature = 300 - sample_model.use_detailed_balance = True - sample_model.normalise_detailed_balance = normalise_db - # Then - x = np.linspace(-5, 5, 100) - result1 = sample_model.evaluate_component(x, name="TestGaussian") - result2 = sample_model.evaluate_component(x, name="TestLorentzian") - # Expect - expected_result1 = component1.evaluate(x) - expected_result2 = component2.evaluate(x) + # EXPECT + expected_result1 = sample_model_with_components["TestGaussian1"].evaluate(x) + expected_result2 = sample_model_with_components["TestLorentzian1"].evaluate(x) expected_result1 *= detailed_balance_factor( energy=x, - temperature=sample_model.temperature, + temperature=sample_model_with_components.temperature, divide_by_temperature=normalise_db, ) expected_result2 *= detailed_balance_factor( energy=x, - temperature=sample_model.temperature, + temperature=sample_model_with_components.temperature, divide_by_temperature=normalise_db, ) np.testing.assert_allclose(result1, expected_result1, rtol=1e-5) np.testing.assert_allclose(result2, expected_result2, rtol=1e-5) - def test_evaluate_nonexistent_component_raises(self, sample_model): + def test_evaluate_nonexistent_component_raises(self, sample_model_with_components): # WHEN - component1 = Gaussian( - name="TestGaussian", area=1.0, center=0.0, width=1.0, unit="meV" - ) - component2 = Lorentzian( - name="TestLorentzian", area=2.0, center=1.0, width=0.5, unit="meV" - ) - sample_model.add_component(component1) - sample_model.add_component(component2) x = np.linspace(-5, 5, 100) - # Then Expect + # THEN EXPECT with pytest.raises( KeyError, match="No component named 'NonExistentComponent' exists" ): - sample_model.evaluate_component(x, "NonExistentComponent") + sample_model_with_components.evaluate_component(x, "NonExistentComponent") # ───── Utilities ───── - def test_normalize_area(self, sample_model): - # When - component1 = Gaussian( - name="TestGaussian1", area=2.0, center=0.0, width=1.0, unit="meV" - ) - component2 = Gaussian( - name="TestGaussian2", area=3.0, center=1.0, width=0.5, unit="meV" - ) - sample_model.add_component(component1) - sample_model.add_component(component2) - # Then - sample_model.normalize_area() - # Expect - x = np.linspace(-10, 10, 1000) - result = sample_model.evaluate(x) + def test_normalize_area(self, sample_model_with_components): + # WHEN THEN + sample_model_with_components.normalize_area() + # EXPECT + x = np.linspace(-10000, 10000, 1000000) # Lorentzians have long tails + result = sample_model_with_components.evaluate(x) numerical_area = simpson(result, x) - assert np.isclose(numerical_area, 1.0) + assert np.isclose(numerical_area, 1.0, rtol=1e-4) - def test_get_parameters(self, sample_model): - # When - component = Gaussian( - name="TestGaussian", area=1.0, center=0.0, width=1.0, unit="meV" + def test_normalize_area_no_components_raises(self, sample_model): + # WHEN THEN EXPECT + with pytest.raises( + ValueError, match="No components in the model to normalize." + ): + sample_model.normalize_area() + + def test_normalize_area_zero_total_raises(self, sample_model_with_components): + # WHEN THEN + sample_model_with_components["TestGaussian1"].area = 0.0 + sample_model_with_components["TestLorentzian1"].area = 0.0 + + # EXPECT + with pytest.raises(ValueError, match="Total area is zero; cannot normalize."): + sample_model_with_components.normalize_area() + + def test_normalize_area_non_area_component_warns( + self, sample_model_with_components + ): + # WHEN + component1 = Polynomial( + name="TestPolynomial", coefficients=[1, 2, 3], unit="meV" ) - sample_model.add_component(component) - # Then - parameters = sample_model.get_parameters() - # Expect - assert len(parameters) == 3 - assert parameters[0].name == "TestGaussian area" - assert parameters[1].name == "TestGaussian center" - assert parameters[2].name == "TestGaussian width" + sample_model_with_components.add_component(component1) + + # THEN EXPECT + with pytest.warns(UserWarning, match="does not have an 'area' "): + sample_model_with_components.normalize_area() + + def test_get_parameters(self, sample_model_with_components): + # WHEN THEN + parameters = sample_model_with_components.get_parameters() + # EXPECT + assert len(parameters) == 6 + + expected_names = { + "TestGaussian1 area", + "TestGaussian1 center", + "TestGaussian1 width", + "TestLorentzian1 area", + "TestLorentzian1 center", + "TestLorentzian1 width", + } + actual_names = {param.name for param in parameters} + assert actual_names == expected_names assert all(isinstance(param, Parameter) for param in parameters) + # WHEN + sample_model_with_components.temperature = 300 + # THEN + parameters = sample_model_with_components.get_parameters() + # EXPECT + assert len(parameters) == 7 + expected_names.add("temperature") + actual_names = {param.name for param in parameters} + assert actual_names == expected_names + def test_get_parameters_no_components(self, sample_model): - # When Then + # WHEN THEN parameters = sample_model.get_parameters() - # Expect + # EXPECT assert len(parameters) == 0 - def test_repr_contains_name_and_components(self, sample_model): - # When - component = Gaussian( - name="TestGaussian", area=1.0, center=0.0, width=1.0, unit="meV" + # WHEN THEN + sample_model.temperature = 300 + parameters = sample_model.get_parameters() + # EXPECT + assert len(parameters) == 1 + assert parameters[0].name == "temperature" + + def test_get_fit_parameters(self, sample_model_with_components): + # WHEN + + # Fix one parameter and make another dependent + sample_model_with_components["TestGaussian1"].area.fixed = True + sample_model_with_components["TestLorentzian1"].width.make_dependent_on( + "comp1_width", + {"comp1_width": sample_model_with_components["TestGaussian1"].width}, ) - sample_model.add_component(component) - # Then - rep = repr(sample_model) - # Expect + + # THEN + fit_parameters = sample_model_with_components.get_fit_parameters() + # EXPECT + assert len(fit_parameters) == 4 + + expected_names = { + "TestGaussian1 center", + "TestGaussian1 width", + "TestLorentzian1 area", + "TestLorentzian1 center", + } + actual_names = {param.name for param in fit_parameters} + assert actual_names == expected_names + assert all(isinstance(param, Parameter) for param in fit_parameters) + + def test_fix_and_free_all_parameters(self, sample_model_with_components): + # WHEN THEN + sample_model_with_components.fix_all_parameters() + # EXPECT + for param in sample_model_with_components.get_parameters(): + assert param.fixed is True + + # WHEN + sample_model_with_components.free_all_parameters() + # THEN + for param in sample_model_with_components.get_parameters(): + assert param.fixed is False + + def test_repr_contains_name_and_components(self, sample_model_with_components): + # WHEN THEN + rep = repr(sample_model_with_components) + # EXPECT assert "SampleModel" in rep assert "TestGaussian" in rep - # def test_repr_no_components(self, sample_model): - # # When Then - # rep = repr(sample_model) - # # Expect - # assert "SampleModel" in rep - # assert "Components: None" in rep - - def test_str_contains_name_and_components(self, sample_model): - # When - component = Gaussian( - name="TestGaussian", area=1.0, center=0.0, width=1.0, unit="meV" + def test_copy(self, sample_model_with_components): + # WHEN THEN + model_copy = copy(sample_model_with_components) + # EXPECT + assert model_copy is not sample_model_with_components + assert model_copy.name == "copy of " + sample_model_with_components.name + assert len(model_copy.components) == len( + sample_model_with_components.components ) - sample_model.add_component(component) - # Then - str_repr = str(sample_model) - # Expect - assert "SampleModel" in str_repr - assert "TestGaussian" in str_repr + for name, comp in sample_model_with_components.components.items(): + copied_comp = model_copy.components[name] + assert copied_comp is not comp + assert copied_comp.name == comp.name + for param_orig, param_copy in zip( + comp.get_parameters(), copied_comp.get_parameters() + ): + assert param_copy is not param_orig + assert param_copy.name == param_orig.name + assert param_copy.value == param_orig.value + assert param_copy.fixed == param_orig.fixed From d4309fc81a8b64503392346ff8a7e66217744192 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 17 Oct 2025 11:04:43 +0200 Subject: [PATCH 04/71] Update example and tests --- examples/sample_model.ipynb | 192 +----------------- .../sample_model/test_sample_model.py | 189 ++++++++--------- 2 files changed, 95 insertions(+), 286 deletions(-) diff --git a/examples/sample_model.ipynb b/examples/sample_model.ipynb index 3875874..1753444 100644 --- a/examples/sample_model.ipynb +++ b/examples/sample_model.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "64deaa41", "metadata": {}, "outputs": [], @@ -13,7 +13,7 @@ "from easydynamics.sample_model import Lorentzian\n", "from easydynamics.sample_model import DampedHarmonicOscillator\n", "from easydynamics.sample_model import Polynomial\n", - "from easydynamics.sample_model import DeltaFunction\n", + "\n", "from easydynamics.sample_model import SampleModel\n", "\n", "\n", @@ -25,36 +25,10 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "784d9e82", "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "85227f7e718342749b433c8067629028", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "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", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "sample_model=SampleModel(name='sample_model')\n", "\n", @@ -86,36 +60,10 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "ac7061fd", "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "f1ca548a33f442258664aaff8e549814", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAmCJJREFUeJzt3QV4U+caB/B/29TdvaWFQnH34dtgTGBud+4bc9/d7uxuzN13527MGWzDhrs7pUCpe+qN3ef90oS0tNBSSdr8fzyHc3JiX5KTnjfvZy4mk8kEIiIiInIarvYuABERERF1LAaARERERE6GASARERGRk2EASERERORkGAASERERORkGgEREREROhgEgERERkZNhAEhERETkZBgAEhERETkZBoBEREREToYBIBEREZGTYQBIRERE5GQYABIRERE5GQaARERERE6GASARERGRk2EASERERORkGAASERERORkGgEREREROhgEgERERkZNhAEhERETkZBgAEhERETkZBoBEREREToYBIBEREZGTYQBIRERE5GQYABIRERE5GQaARERERE6GASARERGRk2EASERERORkGAASERERORkGgEREREROhgEgERERkZNhAEhERETkZBgAEhERETkZBoBEREREToYBIFETXFxc8Nhjj6GruPLKK9GtW7cTuu/EiRPVQs0nx44cQy25bUFBQZuWwZ6f2+LFi9VrknVbHINNkceTxz2WAwcOqLK88MILbfa8H3/8sXpMeWyizogBILWrrVu34rzzzkNiYiK8vLwQGxuLU045Ba+//rq9i0Z29NZbb6kTaEtO8nKybbjceOONzQ5Evv/++3r7a2trccYZZ8DV1RUffvghOsLTTz+Nn376CZ1BZyorEbWc5gTuQ9QsK1aswKRJk5CQkIDrrrsOUVFRyMjIwKpVq/Dqq6/i1ltvtXcRyY4BYFhY2HEzN7YGDRqEu+++u96+nj17ntDz63Q69cNk7ty5eP/993H11VejrT388MN44IEHjgqq5HlnzpwJR9faso4fPx5VVVXw8PBo87IRUesxAKR289RTTyEwMBBr165FUFBQvevy8vLsVi7qnCR7/K9//avVjyPB3wUXXIDffvsN7777Lq655hq0B41GoxZnJZlVyfoTkWNiFTC1m7S0NPTt2/eo4E9ERETUu/zRRx9h8uTJar+npyf6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X4SO5OLt3SaTbmdmZmL69OkqSPr000+xa9cuXHfddfDy8qoXrH3yySe46aabsHz5cnW5pKQEkydPxrXXXouXX34ZVVVVuP/++3HBBRdg4cKF9e531113YfXq1Vi5cqV6nrFjx+KUU07B2rVrERERgY8++gjTpk1T2T0h+yWwE7I+77zz4O7eeA8zo9GIuLg4fPfddyqwW7FiBa6//noV6ElZLBYtWqT2yXrfvn248MILMWjQIPVaiYjo+BbtMmf/JnQPQ/Zqc/u/+N4MAB2J0waAEixI0PL5558jJycHMTExKuB4+OGH2yRYaowEf7uHDEVH67VhPVx8zF3wW+Ott95S7ereeOMN9R6lpqYiKytLBXP/+c9/4OpqTiinpKTgueees97vv//9LwYPHoynn37auu/DDz9Uj7Vnzx707NlT7RswYAAeffRR62PI8yxYsEAFgOHh4Wp/UFCQyg5aWPaL22+/XbX5k6CwMRIYPv7449bLkgmUQPPbb7+tFwAGBwer55YgU17j6aefrsrBAJCIqGXDv4wO8EWRrgS+QZ4IifG1d7HIhtMGgM8++yzefvttlXXq27cv1q1bh6uuugqBgYGqKpKOtnPnTowePbpegCwZuvLychw+fBgJCQlq39Ch9YPczZs3q2yaVP82lJaWVi8AtCVZuLw88x+R43nvvffwwQcfqKyebVDY0JtvvqmCz0OHDqlMpLRRlOyeLTkeLBlGSzm2bt3arHIQETm7XG21mgFEThVh5SYUSfavT0i7JVfoxDhtACiBwowZM1R2x9KW7KuvvsKaNWvatSpWsnEdTZ63I/n61v+VJwHimWeeqYLuhiS4smhYdSt/LKTa9ngkuLz11lvV59cwiLT19ddf45577sGLL76oAll/f388//zzqsrZ1omWg4iIgMV12b8BcUEo2Geu/mX7P8fjtAHgmDFjVNbIUgUpWaply5bhpZdearfnVB0U2qAq1l569+6NH374QbVltPySk3Z+EkhJ27qmDBkyRN1PguzW9MiVwMzS3s9C2uhJu7+HHnoI55xzzjHvL2WVz/3mm2+ul4EkIqK2b/83OSEERVuzARfO/+uInLYXsPReveiii1QbLwkspI2a9Fy99NJLm7xPTU0NtFptvaWrKi0tVb1nbRfpMJGRkaGybdIB5Oeff1Zt9qTjhqX9X2OkF21RUREuvvhi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ldwxQSd1bU4fAJaXl+PSSy/F+++/j+DgYHsXh4jIqX2//jD251eoDhgyXy8B+loDttUN/SLZPw79Qm3B6QPAW265BaeffjpOPvlkexeFiMipyawbr/y9V23fMqmHGpOPoGb9qC7XqSnfkgeF2bs41EU4dRvAr7/+Ghs2bFBVwM1RU1OjFgutVtuOpSMici6frDiAHG216nV76Ui2c7MM/Lzpb3Pnj4FT4uHq5vR5G2ojTnskZWRkqA4fX3zxBby8mjco5+zZsxEYGGhd4uPj272cRETOQObJffef/Wr7jpNT4OXOMe4sAz+X5FbCw8sNvce03zR45HycNgBcv3498vLyMGTIEGg0GrUsWbIEr732mto2GI6eAFx6CZeWlloXCSKJiKj1vlx9CEUVtUgI8cHZgznGncWmvw+pdZ9xsfDwdupKO2pjTns0TZkyBVu3bq2376qrrkJqairuv/9+uLkd/evT09NTLURE1LZt/96ry/7dPLE7NKzmVPIPlSFzdwlcXF3UvL9EbclpA0B/f3/061d/YnFfX1+EhoYetZ+IiNrPt+sykFdWg5hAL5wzhIGOxYb5B9W6x9AI1QGEqC3xZxYREdlNrd6Idxanqe0bJ3aHh4anJSHt/tI25KntIVPZIYbantNmABuzePFiexeBiMipzNlwGFml1WrA5wuGsWOdxca/DsFkAhL7hSIszt/exaEuiD+1iIjIbrN+vFWX/bthfDJ7/tapKKnBrlXZanvItER7F4e6KAaARERkF79szsKhoko168clHPevXs9fo96E6B6BiOkRZO/iUBfFAJCIiDqcwWjCm4v2qe1rTkqCjwdbJInqCh22Lc1S20OmMvtH7YcBIBERdbg/tmUjLb8CAV4aXD6agY7F1sWHoa8xIDTOT7X/I2ovDACJiKhDGY0mvLHQnP27amwS5/yto6sxYMvCw2p76NREuLi42LtI1IUxACQiog71985c7Mopg5+nBlePTbJ3cRzGjmVZqgo4INwb3YeE27s41MUxACQiog5jMpnwel32T6p+A32Y/RMGnVEN/SKGnJoAV86GQu2MRxgREXWYJXvysTWzFN7ubqrzB5ntWJ6lhn/xDfJE6qhoexeHnAADQCIi6vDs36UjExDqx7nVLdm/9fPM074NnZYIN3eemqn98SgjIqIOsTKtEOsPFqvp3q4fn2zv4jhk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", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "sample_model=SampleModel(name='sample_model')\n", "sample_model.temperature=5\n", @@ -148,134 +96,6 @@ "plt.title('Sample model at 5 K with detailed balance')\n", "plt.show()" ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "bd1e57cd", - "metadata": {}, - "outputs": [], - "source": [ - "sample_model['Gaussian'].fix_all_parameters()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "115f672d", - "metadata": {}, - "outputs": [], - "source": [ - "sample_mode=SampleModel(name=\"TestSampleModel\")\n", - "component1 = Gaussian(\n", - " name=\"TestGaussian\", area=1.0, center=0.0, width=1.0, unit=\"meV\"\n", - ")\n", - "component2 = Lorentzian(\n", - " name=\"TestLorentzian\", area=2.0, center=1.0, width=0.5, unit=\"meV\"\n", - ")\n", - "sample_model.add_component(component1)\n", - "sample_model.add_component(component2)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "f4e1fb01", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sample_mode=SampleModel(name=\"TestSampleModel\")\n", - "not sample_mode.components" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "f8cec9a3", - "metadata": {}, - "outputs": [ - { - "ename": "AssertionError", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mAssertionError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[7]\u001b[39m\u001b[32m, line 26\u001b[39m\n\u001b[32m 24\u001b[39m copied_comp = model_copy.components[name]\n\u001b[32m 25\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m copied_comp \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m comp\n\u001b[32m---> \u001b[39m\u001b[32m26\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m copied_comp.name == comp.name\n\u001b[32m 27\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m param_orig, param_copy \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mzip\u001b[39m(\n\u001b[32m 28\u001b[39m comp.get_parameters(), copied_comp.get_parameters()\n\u001b[32m 29\u001b[39m ):\n\u001b[32m 30\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m param_copy \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m param_orig\n", - "\u001b[31mAssertionError\u001b[39m: " - ] - } - ], - "source": [ - "from copy import copy\n", - "model = SampleModel(name=\"TwoComponentModel\")\n", - "component1 = Gaussian(\n", - " name=\"TestGaussian1\", area=1.0, center=0.0, width=1.0, unit=\"meV\"\n", - ")\n", - "component2 = Lorentzian(\n", - " name=\"TestLorentzian1\", area=2.0, center=1.0, width=0.5, unit=\"meV\"\n", - ")\n", - "model.add_component(component1)\n", - "model.add_component(component2)\n", - "\n", - "sample_model_with_components=model\n", - "\n", - "model_copy = copy(sample_model_with_components)\n", - "\n", - "\n", - "\n", - "assert model_copy is not sample_model_with_components\n", - "assert model_copy.name == \"copy of \" + sample_model_with_components.name\n", - "assert len(model_copy.components) == len(\n", - " sample_model_with_components.components\n", - ")\n", - "for name, comp in sample_model_with_components.components.items():\n", - " copied_comp = model_copy.components[name]\n", - " assert copied_comp is not comp\n", - " assert copied_comp.name == comp.name\n", - " for param_orig, param_copy in zip(\n", - " comp.get_parameters(), copied_comp.get_parameters()\n", - " ):\n", - " assert param_copy is not param_orig\n", - " assert param_copy.name == param_orig.name\n", - " assert param_copy.value == param_orig.value\n", - " assert param_copy.fixed == param_orig.fixed" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "c660f129", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Gaussian(name = copy of TestGaussian1, unit = meV,\n", - " area = ,\n", - " center = ,\n", - " width = )" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "model_copy['TestGaussian1']" - ] } ], "metadata": { diff --git a/tests/unit_tests/sample_model/test_sample_model.py b/tests/unit_tests/sample_model/test_sample_model.py index 62c33f4..a955e33 100644 --- a/tests/unit_tests/sample_model/test_sample_model.py +++ b/tests/unit_tests/sample_model/test_sample_model.py @@ -13,11 +13,7 @@ class TestSampleModel: @pytest.fixture def sample_model(self): - return SampleModel(name="TestSampleModel") - - @pytest.fixture - def sample_model_with_components(self): - model = SampleModel(name="TwoComponentModel") + model = SampleModel(name="TestSampleModel") component1 = Gaussian( name="TestGaussian1", area=1.0, center=0.0, width=1.0, unit="meV" ) @@ -32,7 +28,7 @@ def test_init_no_temperature(self, sample_model): # WHEN THEN EXPECT assert sample_model.name == "TestSampleModel" assert isinstance(sample_model.components, dict) - assert len(sample_model.components) == 0 + assert len(sample_model.components) == 2 assert not sample_model.use_detailed_balance def test_init_with_temperature(self): @@ -59,27 +55,27 @@ def test_add_component(self, sample_model): # EXPECT assert "TestComponent" in sample_model.components - def test_add_duplicate_component_raises(self, sample_model_with_components): + def test_add_duplicate_component_raises(self, sample_model): # WHEN THEN component = Gaussian( name="TestGaussian1", area=1.0, center=0.0, width=1.0, unit="meV" ) # EXPECT with pytest.raises(ValueError, match="already exists"): - sample_model_with_components.add_component(component) + sample_model.add_component(component) - def test_remove_component(self, sample_model_with_components): + def test_remove_component(self, sample_model): # WHEN THEN - sample_model_with_components.remove_component("TestGaussian1") + sample_model.remove_component("TestGaussian1") # EXPECT - assert "TestGaussian1" not in sample_model_with_components.components + assert "TestGaussian1" not in sample_model.components - def test_remove_nonexistent_component_raises(self, sample_model_with_components): + def test_remove_nonexistent_component_raises(self, sample_model): # WHEN THEN EXPECT with pytest.raises( KeyError, match="No component named 'NonExistentComponent' exists" ): - sample_model_with_components.remove_component("NonExistentComponent") + sample_model.remove_component("NonExistentComponent") def test_getitem(self, sample_model): # WHEN @@ -99,25 +95,24 @@ def test_setitem(self, sample_model): # EXPECT assert sample_model["TestComponent"] is component - def test_contains_component(self, sample_model_with_components): + def test_contains_component(self, sample_model): # WHEN THEN EXPECT - # EXPECT - assert "TestGaussian1" in sample_model_with_components - assert "NonExistentComponent" not in sample_model_with_components + assert "TestGaussian1" in sample_model + assert "NonExistentComponent" not in sample_model - def test_list_components(self, sample_model_with_components): + def test_list_components(self, sample_model): # WHEN THEN - components = sample_model_with_components.list_components() + components = sample_model.list_components() # EXPECT assert len(components) == 2 assert components[0] == "TestGaussian1" assert components[1] == "TestLorentzian1" - def test_clear_components(self, sample_model_with_components): + def test_clear_components(self, sample_model): # WHEN THEN - sample_model_with_components.clear_components() + sample_model.clear_components() # EXPECT - assert len(sample_model_with_components.components) == 0 + assert len(sample_model.components) == 0 # ───── Temperature and Detailed Balance ───── @@ -166,92 +161,84 @@ def test_use_detailed_balance(self, sample_model): # ───── Evaluation ───── - def test_evaluate(self, sample_model_with_components): + def test_evaluate(self, sample_model): # WHEN x = np.linspace(-5, 5, 100) - result = sample_model_with_components.evaluate(x) + result = sample_model.evaluate(x) # EXPECT - expected_result = sample_model_with_components["TestGaussian1"].evaluate( - x - ) + sample_model_with_components["TestLorentzian1"].evaluate(x) + expected_result = sample_model["TestGaussian1"].evaluate(x) + sample_model[ + "TestLorentzian1" + ].evaluate(x) np.testing.assert_allclose(result, expected_result, rtol=1e-5) @pytest.mark.parametrize( "normalise_db", [True, False], ids=["Normalise DB", "Don't normalise DB"] ) - def test_evaluate_with_detailed_balance( - self, sample_model_with_components, normalise_db - ): + def test_evaluate_with_detailed_balance(self, sample_model, normalise_db): # WHEN - sample_model_with_components.temperature = 300 - sample_model_with_components.use_detailed_balance = True - sample_model_with_components.normalise_detailed_balance = normalise_db + sample_model.temperature = 300 + sample_model.use_detailed_balance = True + sample_model.normalise_detailed_balance = normalise_db x = np.linspace(-5, 5, 100) # THEN - result = sample_model_with_components.evaluate(x) + result = sample_model.evaluate(x) # EXPECT - expected_result = sample_model_with_components["TestGaussian1"].evaluate( - x - ) + sample_model_with_components["TestLorentzian1"].evaluate(x) + expected_result = sample_model["TestGaussian1"].evaluate(x) + sample_model[ + "TestLorentzian1" + ].evaluate(x) expected_result *= detailed_balance_factor( energy=x, - temperature=sample_model_with_components.temperature, + temperature=sample_model.temperature, divide_by_temperature=normalise_db, ) np.testing.assert_allclose(result, expected_result, rtol=1e-5) - def test_evaluate_component(self, sample_model_with_components): + def test_evaluate_component(self, sample_model): # WHEN THEN x = np.linspace(-5, 5, 100) - result1 = sample_model_with_components.evaluate_component(x, "TestGaussian1") - result2 = sample_model_with_components.evaluate_component(x, "TestLorentzian1") + result1 = sample_model.evaluate_component(x, "TestGaussian1") + result2 = sample_model.evaluate_component(x, "TestLorentzian1") # EXPECT - expected_result1 = sample_model_with_components["TestGaussian1"].evaluate(x) - expected_result2 = sample_model_with_components["TestLorentzian1"].evaluate(x) + expected_result1 = sample_model["TestGaussian1"].evaluate(x) + expected_result2 = sample_model["TestLorentzian1"].evaluate(x) np.testing.assert_allclose(result1, expected_result1, rtol=1e-5) np.testing.assert_allclose(result2, expected_result2, rtol=1e-5) @pytest.mark.parametrize( "normalise_db", [True, False], ids=["Normalise DB", "Don't normalise DB"] ) - def test_evaluate_component_with_detailed_balance( - self, sample_model_with_components, normalise_db - ): + def test_evaluate_component_with_detailed_balance(self, sample_model, normalise_db): # WHEN - sample_model_with_components.temperature = 300 - sample_model_with_components.use_detailed_balance = True - sample_model_with_components.normalise_detailed_balance = normalise_db + sample_model.temperature = 300 + sample_model.use_detailed_balance = True + sample_model.normalise_detailed_balance = normalise_db # THEN x = np.linspace(-5, 5, 100) - result1 = sample_model_with_components.evaluate_component( - x, name="TestGaussian1" - ) - result2 = sample_model_with_components.evaluate_component( - x, name="TestLorentzian1" - ) + result1 = sample_model.evaluate_component(x, name="TestGaussian1") + result2 = sample_model.evaluate_component(x, name="TestLorentzian1") # EXPECT - expected_result1 = sample_model_with_components["TestGaussian1"].evaluate(x) - expected_result2 = sample_model_with_components["TestLorentzian1"].evaluate(x) + expected_result1 = sample_model["TestGaussian1"].evaluate(x) + expected_result2 = sample_model["TestLorentzian1"].evaluate(x) expected_result1 *= detailed_balance_factor( energy=x, - temperature=sample_model_with_components.temperature, + temperature=sample_model.temperature, divide_by_temperature=normalise_db, ) expected_result2 *= detailed_balance_factor( energy=x, - temperature=sample_model_with_components.temperature, + temperature=sample_model.temperature, divide_by_temperature=normalise_db, ) np.testing.assert_allclose(result1, expected_result1, rtol=1e-5) np.testing.assert_allclose(result2, expected_result2, rtol=1e-5) - def test_evaluate_nonexistent_component_raises(self, sample_model_with_components): + def test_evaluate_nonexistent_component_raises(self, sample_model): # WHEN x = np.linspace(-5, 5, 100) @@ -259,51 +246,51 @@ def test_evaluate_nonexistent_component_raises(self, sample_model_with_component with pytest.raises( KeyError, match="No component named 'NonExistentComponent' exists" ): - sample_model_with_components.evaluate_component(x, "NonExistentComponent") + sample_model.evaluate_component(x, "NonExistentComponent") # ───── Utilities ───── - def test_normalize_area(self, sample_model_with_components): + def test_normalize_area(self, sample_model): # WHEN THEN - sample_model_with_components.normalize_area() + sample_model.normalize_area() # EXPECT x = np.linspace(-10000, 10000, 1000000) # Lorentzians have long tails - result = sample_model_with_components.evaluate(x) + result = sample_model.evaluate(x) numerical_area = simpson(result, x) assert np.isclose(numerical_area, 1.0, rtol=1e-4) - def test_normalize_area_no_components_raises(self, sample_model): - # WHEN THEN EXPECT + def test_normalize_area_no_components_raises(self): + # WHEN THEN + sample_model = SampleModel(name="EmptyModel") + # EXPECT with pytest.raises( ValueError, match="No components in the model to normalize." ): sample_model.normalize_area() - def test_normalize_area_zero_total_raises(self, sample_model_with_components): + def test_normalize_area_zero_total_raises(self, sample_model): # WHEN THEN - sample_model_with_components["TestGaussian1"].area = 0.0 - sample_model_with_components["TestLorentzian1"].area = 0.0 + sample_model["TestGaussian1"].area = 0.0 + sample_model["TestLorentzian1"].area = 0.0 # EXPECT with pytest.raises(ValueError, match="Total area is zero; cannot normalize."): - sample_model_with_components.normalize_area() + sample_model.normalize_area() - def test_normalize_area_non_area_component_warns( - self, sample_model_with_components - ): + def test_normalize_area_non_area_component_warns(self, sample_model): # WHEN component1 = Polynomial( name="TestPolynomial", coefficients=[1, 2, 3], unit="meV" ) - sample_model_with_components.add_component(component1) + sample_model.add_component(component1) # THEN EXPECT with pytest.warns(UserWarning, match="does not have an 'area' "): - sample_model_with_components.normalize_area() + sample_model.normalize_area() - def test_get_parameters(self, sample_model_with_components): + def test_get_parameters(self, sample_model): # WHEN THEN - parameters = sample_model_with_components.get_parameters() + parameters = sample_model.get_parameters() # EXPECT assert len(parameters) == 6 @@ -320,16 +307,17 @@ def test_get_parameters(self, sample_model_with_components): assert all(isinstance(param, Parameter) for param in parameters) # WHEN - sample_model_with_components.temperature = 300 + sample_model.temperature = 300 # THEN - parameters = sample_model_with_components.get_parameters() + parameters = sample_model.get_parameters() # EXPECT assert len(parameters) == 7 expected_names.add("temperature") actual_names = {param.name for param in parameters} assert actual_names == expected_names - def test_get_parameters_no_components(self, sample_model): + def test_get_parameters_no_components(self): + sample_model = SampleModel(name="EmptyModel") # WHEN THEN parameters = sample_model.get_parameters() # EXPECT @@ -342,18 +330,19 @@ def test_get_parameters_no_components(self, sample_model): assert len(parameters) == 1 assert parameters[0].name == "temperature" - def test_get_fit_parameters(self, sample_model_with_components): + def test_get_fit_parameters(self, sample_model): # WHEN # Fix one parameter and make another dependent - sample_model_with_components["TestGaussian1"].area.fixed = True - sample_model_with_components["TestLorentzian1"].width.make_dependent_on( + sample_model["TestGaussian1"].area.fixed = True + sample_model["TestLorentzian1"].width.make_dependent_on( "comp1_width", - {"comp1_width": sample_model_with_components["TestGaussian1"].width}, + {"comp1_width": sample_model["TestGaussian1"].width}, ) # THEN - fit_parameters = sample_model_with_components.get_fit_parameters() + fit_parameters = sample_model.get_fit_parameters() + # EXPECT assert len(fit_parameters) == 4 @@ -367,36 +356,36 @@ def test_get_fit_parameters(self, sample_model_with_components): assert actual_names == expected_names assert all(isinstance(param, Parameter) for param in fit_parameters) - def test_fix_and_free_all_parameters(self, sample_model_with_components): + def test_fix_and_free_all_parameters(self, sample_model): # WHEN THEN - sample_model_with_components.fix_all_parameters() + sample_model.fix_all_parameters() + # EXPECT - for param in sample_model_with_components.get_parameters(): + for param in sample_model.get_parameters(): assert param.fixed is True # WHEN - sample_model_with_components.free_all_parameters() + sample_model.free_all_parameters() + # THEN - for param in sample_model_with_components.get_parameters(): + for param in sample_model.get_parameters(): assert param.fixed is False - def test_repr_contains_name_and_components(self, sample_model_with_components): + def test_repr_contains_name_and_components(self, sample_model): # WHEN THEN - rep = repr(sample_model_with_components) + rep = repr(sample_model) # EXPECT assert "SampleModel" in rep assert "TestGaussian" in rep - def test_copy(self, sample_model_with_components): + def test_copy(self, sample_model): # WHEN THEN - model_copy = copy(sample_model_with_components) + model_copy = copy(sample_model) # EXPECT - assert model_copy is not sample_model_with_components - assert model_copy.name == "copy of " + sample_model_with_components.name - assert len(model_copy.components) == len( - sample_model_with_components.components - ) - for name, comp in sample_model_with_components.components.items(): + assert model_copy is not sample_model + assert model_copy.name == "copy of " + sample_model.name + assert len(model_copy.components) == len(sample_model.components) + for name, comp in sample_model.components.items(): copied_comp = model_copy.components[name] assert copied_comp is not comp assert copied_comp.name == comp.name From cde9b4ba9ad54fea58187da9b05f6cb8ca98758c Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 17 Oct 2025 11:14:20 +0200 Subject: [PATCH 05/71] Add one more test --- tests/unit_tests/sample_model/test_sample_model.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/unit_tests/sample_model/test_sample_model.py b/tests/unit_tests/sample_model/test_sample_model.py index a955e33..315fe93 100644 --- a/tests/unit_tests/sample_model/test_sample_model.py +++ b/tests/unit_tests/sample_model/test_sample_model.py @@ -371,6 +371,12 @@ def test_fix_and_free_all_parameters(self, sample_model): for param in sample_model.get_parameters(): assert param.fixed is False + def test_delitem(self, sample_model): + # WHEN THEN + del sample_model["TestGaussian1"] + # EXPECT + assert "TestGaussian1" not in sample_model.components + def test_repr_contains_name_and_components(self, sample_model): # WHEN THEN rep = repr(sample_model) From 6f797f85aa61a8d5d08f1ac3c4b681f2b58053fd Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 17 Oct 2025 11:21:39 +0200 Subject: [PATCH 06/71] Added a few tests --- src/easydynamics/sample_model/sample_model.py | 28 +++++------ .../sample_model/test_sample_model.py | 50 ++++++++++++++----- 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/easydynamics/sample_model/sample_model.py b/src/easydynamics/sample_model/sample_model.py index 19bf4f1..5bd2d52 100644 --- a/src/easydynamics/sample_model/sample_model.py +++ b/src/easydynamics/sample_model/sample_model.py @@ -29,8 +29,8 @@ class SampleModel(ObjBase, MutableMapping): Temperature parameter for detailed balance. use_detailed_balance : bool Whether to apply detailed balance. - normalise_detailed_balance : bool - Whether to normalise the detailed balance by temperature. + normalize_detailed_balance : bool + Whether to normalize the detailed balance by temperature. name : str Name of the SampleModel. """ @@ -66,8 +66,8 @@ def __init__( self._temperature = None self._use_detailed_balance = False - self._normalise_detailed_balance = ( - True # Whether to normalise by temperature when using detailed balance. + self._normalize_detailed_balance = ( + True # Whether to normalize by temperature when using detailed balance. ) ############################################## @@ -248,24 +248,24 @@ def use_detailed_balance(self, value: bool) -> None: self._use_detailed_balance = value @property - def normalise_detailed_balance(self) -> bool: + def normalize_detailed_balance(self) -> bool: """ - If True, detailed balance will be normalised by temperature. If False, it will not be normalised. + If True, detailed balance will be normalized by temperature. If False, it will not be normalized. """ - return self._normalise_detailed_balance + return self._normalize_detailed_balance - @normalise_detailed_balance.setter - def normalise_detailed_balance(self, value: bool) -> None: + @normalize_detailed_balance.setter + def normalize_detailed_balance(self, value: bool) -> None: """ - If True, normalises the detailed balance by temperature. + If True, normalizes the detailed balance by temperature. Parameters ---------- value : bool - True to normalise, False otherwise. + True to normalize, False otherwise. """ - self._normalise_detailed_balance = value + self._normalize_detailed_balance = value ########################################################## # Evaluate # @@ -303,7 +303,7 @@ def evaluate( result *= detailed_balance_factor( energy=x, temperature=self._temperature, - divide_by_temperature=self._normalise_detailed_balance, + divide_by_temperature=self._normalize_detailed_balance, ) return result @@ -340,7 +340,7 @@ def evaluate_component( result *= detailed_balance_factor( energy=x, temperature=self._temperature, - divide_by_temperature=self._normalise_detailed_balance, + divide_by_temperature=self._normalize_detailed_balance, ) return result diff --git a/tests/unit_tests/sample_model/test_sample_model.py b/tests/unit_tests/sample_model/test_sample_model.py index 315fe93..5d0b377 100644 --- a/tests/unit_tests/sample_model/test_sample_model.py +++ b/tests/unit_tests/sample_model/test_sample_model.py @@ -124,6 +124,12 @@ def test_set_temperature(self, sample_model): assert sample_model.temperature.value == 300 assert sample_model.temperature.unit == "K" + # WHEN THEN + sample_model.temperature = 150.0 + # EXPECT + assert sample_model.temperature.value == 150.0 + assert sample_model.temperature.unit == "K" + # Set temperature to None # WHEN THEN sample_model.temperature = None @@ -150,6 +156,11 @@ def test_convert_temperature_unit(self, sample_model): assert np.isclose(sample_model.temperature.value, 300000.0) assert sample_model.temperature.unit == "mK" + def test_convert_temperature_unit_no_temperature_raises(self, sample_model): + # WHEN THEN EXPECT + with pytest.raises(ValueError, match="cannot convert units"): + sample_model.convert_temperature_unit("mK") + def test_use_detailed_balance(self, sample_model): sample_model.temperature = 300 # WHEN THEN EXPECT @@ -172,13 +183,13 @@ def test_evaluate(self, sample_model): np.testing.assert_allclose(result, expected_result, rtol=1e-5) @pytest.mark.parametrize( - "normalise_db", [True, False], ids=["Normalise DB", "Don't normalise DB"] + "normalize_db", [True, False], ids=["normalize DB", "Don't normalize DB"] ) - def test_evaluate_with_detailed_balance(self, sample_model, normalise_db): + def test_evaluate_with_detailed_balance(self, sample_model, normalize_db): # WHEN sample_model.temperature = 300 sample_model.use_detailed_balance = True - sample_model.normalise_detailed_balance = normalise_db + sample_model.normalize_detailed_balance = normalize_db x = np.linspace(-5, 5, 100) @@ -192,10 +203,18 @@ def test_evaluate_with_detailed_balance(self, sample_model, normalise_db): expected_result *= detailed_balance_factor( energy=x, temperature=sample_model.temperature, - divide_by_temperature=normalise_db, + divide_by_temperature=normalize_db, ) np.testing.assert_allclose(result, expected_result, rtol=1e-5) + def test_evaluate_no_components_raises(self): + # WHEN THEN + sample_model = SampleModel(name="EmptyModel") + x = np.linspace(-5, 5, 100) + # EXPECT + with pytest.raises(ValueError, match="No components in the model to evaluate."): + sample_model.evaluate(x) + def test_evaluate_component(self, sample_model): # WHEN THEN x = np.linspace(-5, 5, 100) @@ -209,13 +228,13 @@ def test_evaluate_component(self, sample_model): np.testing.assert_allclose(result2, expected_result2, rtol=1e-5) @pytest.mark.parametrize( - "normalise_db", [True, False], ids=["Normalise DB", "Don't normalise DB"] + "normalize_db", [True, False], ids=["normalize DB", "Don't normalize DB"] ) - def test_evaluate_component_with_detailed_balance(self, sample_model, normalise_db): + def test_evaluate_component_with_detailed_balance(self, sample_model, normalize_db): # WHEN sample_model.temperature = 300 sample_model.use_detailed_balance = True - sample_model.normalise_detailed_balance = normalise_db + sample_model.normalize_detailed_balance = normalize_db # THEN x = np.linspace(-5, 5, 100) @@ -228,12 +247,12 @@ def test_evaluate_component_with_detailed_balance(self, sample_model, normalise_ expected_result1 *= detailed_balance_factor( energy=x, temperature=sample_model.temperature, - divide_by_temperature=normalise_db, + divide_by_temperature=normalize_db, ) expected_result2 *= detailed_balance_factor( energy=x, temperature=sample_model.temperature, - divide_by_temperature=normalise_db, + divide_by_temperature=normalize_db, ) np.testing.assert_allclose(result1, expected_result1, rtol=1e-5) np.testing.assert_allclose(result2, expected_result2, rtol=1e-5) @@ -268,13 +287,18 @@ def test_normalize_area_no_components_raises(self): ): sample_model.normalize_area() - def test_normalize_area_zero_total_raises(self, sample_model): + @pytest.mark.parametrize( + "area_value", + [np.nan, 0.0, np.inf], + ids=["NaN area", "Zero area", "Infinite area"], + ) + def test_normalize_area_not_finite_area_raises(self, sample_model, area_value): # WHEN THEN - sample_model["TestGaussian1"].area = 0.0 - sample_model["TestLorentzian1"].area = 0.0 + sample_model["TestGaussian1"].area = area_value + sample_model["TestLorentzian1"].area = area_value # EXPECT - with pytest.raises(ValueError, match="Total area is zero; cannot normalize."): + with pytest.raises(ValueError, match="cannot normalize."): sample_model.normalize_area() def test_normalize_area_non_area_component_warns(self, sample_model): From 3435da56be1160f0ac527d62a681d77f06ec2896 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 17 Oct 2025 11:28:07 +0200 Subject: [PATCH 07/71] a few more tests --- .../sample_model/test_sample_model.py | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/unit_tests/sample_model/test_sample_model.py b/tests/unit_tests/sample_model/test_sample_model.py index 5d0b377..ba22154 100644 --- a/tests/unit_tests/sample_model/test_sample_model.py +++ b/tests/unit_tests/sample_model/test_sample_model.py @@ -64,6 +64,13 @@ def test_add_duplicate_component_raises(self, sample_model): with pytest.raises(ValueError, match="already exists"): sample_model.add_component(component) + def test_add_invalid_component_raises(self, sample_model): + # WHEN THEN EXPECT + with pytest.raises( + TypeError, match="component must be an instance of ModelComponent." + ): + sample_model.add_component("NotAComponent") + def test_remove_component(self, sample_model): # WHEN THEN sample_model.remove_component("TestGaussian1") @@ -156,6 +163,13 @@ def test_convert_temperature_unit(self, sample_model): assert np.isclose(sample_model.temperature.value, 300000.0) assert sample_model.temperature.unit == "mK" + def test_convert_temperature_unit_incompatible_unit_raises(self, sample_model): + # WHEN + sample_model.temperature = 300 # Kelvin + # THEN EXPECT + with pytest.raises(ValueError, match="Failed to convert temperature"): + sample_model.convert_temperature_unit("m") + def test_convert_temperature_unit_no_temperature_raises(self, sample_model): # WHEN THEN EXPECT with pytest.raises(ValueError, match="cannot convert units"): @@ -170,6 +184,14 @@ def test_use_detailed_balance(self, sample_model): sample_model.use_detailed_balance = False assert sample_model.use_detailed_balance is False + def test_use_detailed_balance_no_temperature_raises(self, sample_model): + # WHEN THEN EXPECT + with pytest.raises( + ValueError, + match="Temperature must be set to use detailed balance.", + ): + sample_model.use_detailed_balance = True + # ───── Evaluation ───── def test_evaluate(self, sample_model): @@ -410,11 +432,21 @@ def test_repr_contains_name_and_components(self, sample_model): def test_copy(self, sample_model): # WHEN THEN + sample_model.temperature = 300 model_copy = copy(sample_model) # EXPECT assert model_copy is not sample_model assert model_copy.name == "copy of " + sample_model.name assert len(model_copy.components) == len(sample_model.components) + assert model_copy.temperature is not sample_model.temperature + assert model_copy.temperature.name == sample_model.temperature.name + assert model_copy.temperature.value == sample_model.temperature.value + assert model_copy.temperature.unit == sample_model.temperature.unit + assert model_copy.use_detailed_balance == sample_model.use_detailed_balance + assert ( + model_copy.normalize_detailed_balance + == sample_model.normalize_detailed_balance + ) for name, comp in sample_model.components.items(): copied_comp = model_copy.components[name] assert copied_comp is not comp From c0a4f2c24c138fc5fe5fb7d19f2d85b1c41673b2 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 17 Oct 2025 11:31:18 +0200 Subject: [PATCH 08/71] fix a test --- src/easydynamics/sample_model/sample_model.py | 6 +++--- tests/unit_tests/sample_model/test_sample_model.py | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/easydynamics/sample_model/sample_model.py b/src/easydynamics/sample_model/sample_model.py index 5bd2d52..c49e508 100644 --- a/src/easydynamics/sample_model/sample_model.py +++ b/src/easydynamics/sample_model/sample_model.py @@ -86,14 +86,14 @@ def add_component( name : str, optional Name to assign to the component. If None, uses the component's own name. """ + if not isinstance(component, ModelComponent): + raise TypeError("component must be an instance of ModelComponent.") + if name is None: name = component.name if name in self.components: raise ValueError(f"Component with name '{name}' already exists.") - if not isinstance(component, ModelComponent): - raise TypeError("component must be an instance of ModelComponent.") - self.components[name] = component def remove_component(self, name: str): diff --git a/tests/unit_tests/sample_model/test_sample_model.py b/tests/unit_tests/sample_model/test_sample_model.py index ba22154..13e1924 100644 --- a/tests/unit_tests/sample_model/test_sample_model.py +++ b/tests/unit_tests/sample_model/test_sample_model.py @@ -3,6 +3,7 @@ import numpy as np import pytest from easyscience.variable import Parameter +from scipp import UnitError from scipy.integrate import simpson from easydynamics.sample_model import Gaussian, Lorentzian, Polynomial, SampleModel @@ -167,7 +168,7 @@ def test_convert_temperature_unit_incompatible_unit_raises(self, sample_model): # WHEN sample_model.temperature = 300 # Kelvin # THEN EXPECT - with pytest.raises(ValueError, match="Failed to convert temperature"): + with pytest.raises(UnitError, match="Failed to convert temperature"): sample_model.convert_temperature_unit("m") def test_convert_temperature_unit_no_temperature_raises(self, sample_model): From a4ba7945aa5bdc5cda721faa663f7c2a9e2d9641 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 17 Oct 2025 20:33:12 +0200 Subject: [PATCH 09/71] respond to PR comments --- src/easydynamics/sample_model/sample_model.py | 105 +++++++++++++----- .../sample_model/test_sample_model.py | 7 ++ 2 files changed, 87 insertions(+), 25 deletions(-) diff --git a/src/easydynamics/sample_model/sample_model.py b/src/easydynamics/sample_model/sample_model.py index c49e508..af8fcf2 100644 --- a/src/easydynamics/sample_model/sample_model.py +++ b/src/easydynamics/sample_model/sample_model.py @@ -1,11 +1,14 @@ import warnings from collections.abc import MutableMapping from copy import copy +from itertools import chain from typing import Dict, List, Optional, Union import numpy as np import scipp as sc -from easyscience.base_classes import ObjBase + +# from easyscience.base_classes import ObjBase +from easyscience.job.theoreticalmodel import TheoreticalModelBase from easyscience.variable import Parameter from scipp import UnitError @@ -16,7 +19,7 @@ Numeric = Union[float, int] -class SampleModel(ObjBase, MutableMapping): +class SampleModel(TheoreticalModelBase, MutableMapping): """ A model of the scattering from a sample, combining multiple model components. Optionally applies detailed balancing. @@ -38,7 +41,8 @@ class SampleModel(ObjBase, MutableMapping): def __init__( self, name: str = "MySampleModel", - temperature: Optional[Union[Numeric, None]] = None, + unit: Optional[Union[str, sc.Unit]] = "meV", + temperature: Optional[Union[Numeric, sc.Variable]] = None, temperature_unit: Optional[str] = "K", ): """ @@ -48,7 +52,7 @@ def __init__( ---------- name : str Name of the sample model. - temperature : Number or None, optional + temperature : Number, sc.Variable or None, optional Temperature for detailed balance. temperature_unit : str, default 'K' Unit of the temperature. @@ -57,18 +61,26 @@ def __init__( self.components: Dict[str, ModelComponent] = {} super().__init__(name=name) # If temperature is given, create a Parameter and enable detailed balance. - if temperature is not None: + if temperature is None: + self._temperature = None + self._use_detailed_balance = False + elif isinstance(temperature, sc.Variable): + self._temperature = Parameter( + name="temperature", + value=temperature.value, + unit=temperature.unit, + fixed=True, + ) + else: self._temperature = Parameter( name="temperature", value=temperature, unit=temperature_unit, fixed=True ) self._use_detailed_balance = True - else: - self._temperature = None - self._use_detailed_balance = False self._normalize_detailed_balance = ( True # Whether to normalize by temperature when using detailed balance. ) + self._unit = unit ############################################## # Methods for managing components # @@ -158,12 +170,40 @@ def normalize_area(self) -> None: for param in area_params: param.value /= total_area + def convert_unit(self, unit: Union[str, sc.Unit]): + """ + Convert the unit of the SampleModel and all its components. + """ + self._unit = unit + for component in self.components.values(): + component.convert_unit(unit) + + @property + def unit(self) -> Optional[Union[str, sc.Unit]]: + """ + Get the unit of the SampleModel. + + Returns + ------- + str or sc.Unit or None + """ + return self._unit + + @unit.setter + def unit(self, unit_str: str) -> None: + raise AttributeError( + ( + f"Unit is read-only. Use convert_unit to change the unit between allowed types " + f"or create a new {self.__class__.__name__} with the desired unit." + ) + ) # noqa: E501 + ########################################################## # Methods for temperature and detailed balance # ########################################################## @property - def temperature(self) -> Union[Parameter, None]: + def temperature(self) -> Optional[Parameter]: """ Get the temperature. @@ -174,7 +214,7 @@ def temperature(self) -> Union[Parameter, None]: return self._temperature @temperature.setter - def temperature(self, value: Union[Numeric, None]) -> None: + def temperature(self, value: Optional[Numeric]) -> None: """ Set the temperature. @@ -357,13 +397,18 @@ def get_parameters(self) -> List[Parameter]: ------- List[Parameter] """ - if isinstance(self._temperature, Parameter): - params = [self._temperature] - else: - params = [] - for comp in self.components.values(): - params.extend(comp.get_parameters()) - return params + # Create generator for temperature parameter + temp_params = (self._temperature,) if self._temperature is not None else () + + # Create generator for component parameters + comp_params = ( + param + for comp in self.components.values() + for param in comp.get_parameters() + ) + + # Chain them together and return as list + return list(chain(temp_params, comp_params)) def get_fit_parameters(self) -> List[Parameter]: """ @@ -373,17 +418,25 @@ def get_fit_parameters(self) -> List[Parameter]: List[Parameter]: A list of fit parameters. """ - parameters = self.get_parameters() - fit_parameters = [] + # parameters = self.get_parameters() + # fit_parameters = [] - for parameter in parameters: - is_not_fixed = not getattr(parameter, "fixed", False) - is_independent = getattr(parameter, "_independent", True) + # for parameter in parameters: + # is_not_fixed = not getattr(parameter, "fixed", False) + # is_independent = getattr(parameter, "_independent", True) + + # if is_not_fixed and is_independent: + # fit_parameters.append(parameter) + + def is_fit_parameter(param: Parameter) -> bool: + """Check if a parameter can be used for fitting.""" + return not getattr(param, "fixed", False) and getattr( + param, "_independent", True + ) - if is_not_fixed and is_independent: - fit_parameters.append(parameter) + return [param for param in self.get_parameters() if is_fit_parameter(param)] - return fit_parameters + # return fit_parameters def fix_all_parameters(self) -> None: """ @@ -417,10 +470,12 @@ def __copy__(self) -> "SampleModel": new_model = SampleModel( name=name, temperature=self._temperature.value if self._temperature else None, + unit=self.unit, ) if self._temperature: new_model.use_detailed_balance = self.use_detailed_balance + new_model.normalize_detailed_balance = self.normalize_detailed_balance for comp in self.components.values(): new_model.add_component(component=copy(comp), name=comp.name) diff --git a/tests/unit_tests/sample_model/test_sample_model.py b/tests/unit_tests/sample_model/test_sample_model.py index 13e1924..137707b 100644 --- a/tests/unit_tests/sample_model/test_sample_model.py +++ b/tests/unit_tests/sample_model/test_sample_model.py @@ -122,6 +122,13 @@ def test_clear_components(self, sample_model): # EXPECT assert len(sample_model.components) == 0 + def test_convert_unit(self, sample_model): + # WHEN THEN + sample_model.convert_unit("eV") + # EXPECT + for component in sample_model.components.values(): + assert component.unit == "eV" + # ───── Temperature and Detailed Balance ───── def test_set_temperature(self, sample_model): From d1d28d2097771b4fce0f4b9571e6678ccd1fa896 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Mon, 20 Oct 2025 12:56:35 +0200 Subject: [PATCH 10/71] Use CollectionBase --- examples/sample_model.ipynb | 148 +++++++++++++- src/easydynamics/sample_model/sample_model.py | 188 ++++++------------ .../sample_model/test_sample_model.py | 36 +--- 3 files changed, 214 insertions(+), 158 deletions(-) diff --git a/examples/sample_model.ipynb b/examples/sample_model.ipynb index 1753444..8534aec 100644 --- a/examples/sample_model.ipynb +++ b/examples/sample_model.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "id": "64deaa41", "metadata": {}, "outputs": [], @@ -25,10 +25,61 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, + "id": "07a18846", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "NotarizedDict({})" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sample_model=SampleModel(name='sample_model')\n", + "\n", + "\n", + "type(sample_model._kwargs)\n", + "sample_model._kwargs" + ] + }, + { + "cell_type": "code", + "execution_count": 11, "id": "784d9e82", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "ed6e6ebe1f3d415683cec11efc6c527f", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "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", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "sample_model=SampleModel(name='sample_model')\n", "\n", @@ -50,7 +101,7 @@ "y=sample_model.evaluate(x)\n", "plt.plot(x, y, label='Sample Model')\n", "\n", - "for component in sample_model.components.values():\n", + "for component in list(sample_model):\n", " y = component.evaluate(x)\n", " plt.plot(x, y, label=component.name)\n", "\n", @@ -63,7 +114,33 @@ "execution_count": null, "id": "ac7061fd", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "c248ebdeb8444ea6a3cd89a8e29b6f1a", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAmCJJREFUeJzt3QV4U+caB/B/29TdvaWFQnH34dtgTGBud+4bc9/d7uxuzN13527MGWzDhrs7pUCpe+qN3ef90oS0tNBSSdr8fzyHc3JiX5KTnjfvZy4mk8kEIiIiInIarvYuABERERF1LAaARERERE6GASARERGRk2EASERERORkGAASERERORkGgEREREROhgEgERERkZNhAEhERETkZBgAEhERETkZBoBEREREToYBIBEREZGTYQBIRERE5GQYABIRERE5GQaARERERE6GASARERGRk2EASERERORkGAASERERORkGgEREREROhgEgERERkZNhAEhERETkZBgAEhERETkZBoBEREREToYBIBEREZGTYQBIRERE5GQYABIRERE5GQaARERERE6GASARERGRk2EASERERORkGAASERERORkGgEREREROhgEgERERkZNhAEhERETkZBgAEhERETkZBoBEREREToYBIFETXFxc8Nhjj6GruPLKK9GtW7cTuu/EiRPVQs0nx44cQy25bUFBQZuWwZ6f2+LFi9VrknVbHINNkceTxz2WAwcOqLK88MILbfa8H3/8sXpMeWyizogBILWrrVu34rzzzkNiYiK8vLwQGxuLU045Ba+//rq9i0Z29NZbb6kTaEtO8nKybbjceOONzQ5Evv/++3r7a2trccYZZ8DV1RUffvghOsLTTz+Nn376CZ1BZyorEbWc5gTuQ9QsK1aswKRJk5CQkIDrrrsOUVFRyMjIwKpVq/Dqq6/i1ltvtXcRyY4BYFhY2HEzN7YGDRqEu+++u96+nj17ntDz63Q69cNk7ty5eP/993H11VejrT388MN44IEHjgqq5HlnzpwJR9faso4fPx5VVVXw8PBo87IRUesxAKR289RTTyEwMBBr165FUFBQvevy8vLsVi7qnCR7/K9//avVjyPB3wUXXIDffvsN7777Lq655hq0B41GoxZnJZlVyfoTkWNiFTC1m7S0NPTt2/eo4E9ERETUu/zRRx9h8uTJar+npyf6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X4SO5OLt3SaTbmdmZmL69OkqSPr000+xa9cuXHfddfDy8qoXrH3yySe46aabsHz5cnW5pKQEkydPxrXXXouXX34ZVVVVuP/++3HBBRdg4cKF9e531113YfXq1Vi5cqV6nrFjx+KUU07B2rVrERERgY8++gjTpk1T2T0h+yWwE7I+77zz4O7eeA8zo9GIuLg4fPfddyqwW7FiBa6//noV6ElZLBYtWqT2yXrfvn248MILMWjQIPVaiYjo+BbtMmf/JnQPQ/Zqc/u/+N4MAB2J0waAEixI0PL5558jJycHMTExKuB4+OGH2yRYaowEf7uHDEVH67VhPVx8zF3wW+Ott95S7ereeOMN9R6lpqYiKytLBXP/+c9/4OpqTiinpKTgueees97vv//9LwYPHoynn37auu/DDz9Uj7Vnzx707NlT7RswYAAeffRR62PI8yxYsEAFgOHh4Wp/UFCQyg5aWPaL22+/XbX5k6CwMRIYPv7449bLkgmUQPPbb7+tFwAGBwer55YgU17j6aefrsrBAJCIqGXDv4wO8EWRrgS+QZ4IifG1d7HIhtMGgM8++yzefvttlXXq27cv1q1bh6uuugqBgYGqKpKOtnPnTowePbpegCwZuvLychw+fBgJCQlq39Ch9YPczZs3q2yaVP82lJaWVi8AtCVZuLw88x+R43nvvffwwQcfqKyebVDY0JtvvqmCz0OHDqlMpLRRlOyeLTkeLBlGSzm2bt3arHIQETm7XG21mgFEThVh5SYUSfavT0i7JVfoxDhtACiBwowZM1R2x9KW7KuvvsKaNWvatSpWsnEdTZ63I/n61v+VJwHimWeeqYLuhiS4smhYdSt/LKTa9ngkuLz11lvV59cwiLT19ddf45577sGLL76oAll/f388//zzqsrZ1omWg4iIgMV12b8BcUEo2Geu/mX7P8fjtAHgmDFjVNbIUgUpWaply5bhpZdearfnVB0U2qAq1l569+6NH374QbVltPySk3Z+EkhJ27qmDBkyRN1PguzW9MiVwMzS3s9C2uhJu7+HHnoI55xzzjHvL2WVz/3mm2+ul4EkIqK2b/83OSEERVuzARfO/+uInLYXsPReveiii1QbLwkspI2a9Fy99NJLm7xPTU0NtFptvaWrKi0tVb1nbRfpMJGRkaGybdIB5Oeff1Zt9qTjhqX9X2OkF21RUREuvvhi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ldwxQSd1bU4fAJaXl+PSSy/F+++/j+DgYHsXh4jIqX2//jD251eoDhgyXy8B+loDttUN/SLZPw79Qm3B6QPAW265BaeffjpOPvlkexeFiMipyawbr/y9V23fMqmHGpOPoGb9qC7XqSnfkgeF2bs41EU4dRvAr7/+Ghs2bFBVwM1RU1OjFgutVtuOpSMici6frDiAHG216nV76Ui2c7MM/Lzpb3Pnj4FT4uHq5vR5G2ojTnskZWRkqA4fX3zxBby8mjco5+zZsxEYGGhd4uPj272cRETOQObJffef/Wr7jpNT4OXOMe4sAz+X5FbCw8sNvce03zR45HycNgBcv3498vLyMGTIEGg0GrUsWbIEr732mto2GI6eAFx6CZeWlloXCSKJiKj1vlx9CEUVtUgI8cHZgznGncWmvw+pdZ9xsfDwdupKO2pjTns0TZkyBVu3bq2376qrrkJqairuv/9+uLkd/evT09NTLURE1LZt/96ry/7dPLE7NKzmVPIPlSFzdwlcXF3UvL9EbclpA0B/f3/061d/YnFfX1+EhoYetZ+IiNrPt+sykFdWg5hAL5wzhIGOxYb5B9W6x9AI1QGEqC3xZxYREdlNrd6Idxanqe0bJ3aHh4anJSHt/tI25KntIVPZIYbantNmABuzePFiexeBiMipzNlwGFml1WrA5wuGsWOdxca/DsFkAhL7hSIszt/exaEuiD+1iIjIbrN+vFWX/bthfDJ7/tapKKnBrlXZanvItER7F4e6KAaARERkF79szsKhoko168clHPevXs9fo96E6B6BiOkRZO/iUBfFAJCIiDqcwWjCm4v2qe1rTkqCjwdbJInqCh22Lc1S20OmMvtH7YcBIBERdbg/tmUjLb8CAV4aXD6agY7F1sWHoa8xIDTOT7X/I2ovDACJiKhDGY0mvLHQnP27amwS5/yto6sxYMvCw2p76NREuLi42LtI1IUxACQiog71985c7Mopg5+nBlePTbJ3cRzGjmVZqgo4INwb3YeE27s41MUxACQiog5jMpnwel32T6p+A32Y/RMGnVEN/SKGnJoAV86GQu2MRxgREXWYJXvysTWzFN7ubqrzB5ntWJ6lhn/xDfJE6qhoexeHnAADQCIi6vDs36UjExDqx7nVLdm/9fPM074NnZYIN3eemqn98SgjIqIOsTKtEOsPFqvp3q4fn2zv4jhk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", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "sample_model=SampleModel(name='sample_model')\n", "sample_model.temperature=5\n", @@ -88,14 +165,71 @@ "y=sample_model.evaluate(x)\n", "plt.plot(x, y, label='Sample Model')\n", "\n", - "for component in sample_model.values():\n", - " y=sample_model.evaluate_component(x,component.name)\n", + "for component in list(sample_model):\n", + " y = sample_model.evaluate_component(x, component.name)\n", " plt.plot(x, y, label=component.name)\n", "\n", "plt.legend()\n", "plt.title('Sample model at 5 K with detailed balance')\n", "plt.show()" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3f43ec31", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Gaussian(name = Gaussian, unit = meV,\n", + " area = ,\n", + " center = ,\n", + " width = ),\n", + " DampedHarmonicOscillator(name = DHO, unit = meV,\n", + " area = ,\n", + " center = ,\n", + " width = ),\n", + " Lorentzian(name = Lorentzian, unit = meV,\n", + " area = ,\n", + " center = ,\n", + " width = ),\n", + " Polynomial(name = Polynomial, unit = meV,\n", + " coefficients = [Polynomial_c0=0.1, Polynomial_c1=0.0, Polynomial_c2=0.5])]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(sample_model)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "2e6c7f35", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "list" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# sample_model.remove_component('Polynomial')\n", + "type(list(sample_model))" + ] } ], "metadata": { diff --git a/src/easydynamics/sample_model/sample_model.py b/src/easydynamics/sample_model/sample_model.py index af8fcf2..b16dbd3 100644 --- a/src/easydynamics/sample_model/sample_model.py +++ b/src/easydynamics/sample_model/sample_model.py @@ -1,13 +1,12 @@ import warnings -from collections.abc import MutableMapping from copy import copy from itertools import chain -from typing import Dict, List, Optional, Union +from typing import List, Optional, Union import numpy as np import scipp as sc - -# from easyscience.base_classes import ObjBase +from easyscience.base_classes import CollectionBase +from easyscience.global_object.undo_redo import NotarizedDict from easyscience.job.theoreticalmodel import TheoreticalModelBase from easyscience.variable import Parameter from scipp import UnitError @@ -19,15 +18,13 @@ Numeric = Union[float, int] -class SampleModel(TheoreticalModelBase, MutableMapping): +class SampleModel(CollectionBase, TheoreticalModelBase): """ A model of the scattering from a sample, combining multiple model components. Optionally applies detailed balancing. Attributes ---------- - components : dict - Dictionary of model components keyed by name. temperature : Parameter Temperature parameter for detailed balance. use_detailed_balance : bool @@ -36,6 +33,11 @@ class SampleModel(TheoreticalModelBase, MutableMapping): Whether to normalize the detailed balance by temperature. name : str Name of the SampleModel. + unit : str or sc.Unit + Unit of the SampleModel. + components : List[ModelComponent] + List of model components in the SampleModel. + """ def __init__( @@ -58,8 +60,11 @@ def __init__( Unit of the temperature. """ - self.components: Dict[str, ModelComponent] = {} - super().__init__(name=name) + CollectionBase.__init__(self, name=name) + TheoreticalModelBase.__init__(self, name=name) + if not isinstance(self._kwargs, NotarizedDict): + self._kwargs = NotarizedDict() + # If temperature is given, create a Parameter and enable detailed balance. if temperature is None: self._temperature = None @@ -103,26 +108,24 @@ def add_component( if name is None: name = component.name - if name in self.components: + if name in self.list_component_names(): raise ValueError(f"Component with name '{name}' already exists.") - self.components[name] = component + component.name = name + + self.insert(index=len(self), value=component) def remove_component(self, name: str): """ Remove a model component by name. - - Parameters - ---------- - name : str - Name of the component to remove. """ - - if name not in self.components: + # Find index where item.name == name + indices = [i for i, item in enumerate(list(self)) if item.name == name] + if not indices: raise KeyError(f"No component named '{name}' exists in the model.") - del self.components[name] + del self[indices[0]] - def list_components(self) -> List[str]: + def list_component_names(self) -> List[str]: """ List the names of all components in the model. @@ -132,14 +135,15 @@ def list_components(self) -> List[str]: Component names. """ - return list(self.components.keys()) + return [item.name for item in list(self)] def clear_components(self): """ Remove all components from the model. """ - self.components.clear() + for _ in range(len(self)): + del self[0] def normalize_area(self) -> None: # Useful for convolutions. @@ -152,7 +156,7 @@ def normalize_area(self) -> None: area_params = [] total_area = 0.0 - for component in self.components.values(): + for component in list(self): if hasattr(component, "area"): area_params.append(component.area) total_area += component.area.value @@ -175,9 +179,21 @@ def convert_unit(self, unit: Union[str, sc.Unit]): Convert the unit of the SampleModel and all its components. """ self._unit = unit - for component in self.components.values(): + # for component in self.components.values(): + for component in list(self): component.convert_unit(unit) + @property + def components(self) -> List[ModelComponent]: + """ + Get the list of components in the SampleModel. + + Returns + ------- + List[ModelComponent] + """ + return list(self) + @property def unit(self) -> Optional[Union[str, sc.Unit]]: """ @@ -331,7 +347,7 @@ def evaluate( if not self.components: raise ValueError("No components in the model to evaluate.") result = None - for component in self.components.values(): + for component in list(self): value = component.evaluate(x) result = value if result is None else result + value @@ -368,10 +384,21 @@ def evaluate_component( np.ndarray Evaluated values for the specified component. """ - if name not in self.components: + if not self.components: + raise ValueError("No components in the model to evaluate.") + + if not isinstance(name, str): + raise TypeError( + (f"Component name must be a string, got {type(name)} instead.") + ) + + matches = [comp for comp in list(self) if comp.name == name] + if not matches: raise KeyError(f"No component named '{name}' exists.") - result = self.components[name].evaluate(x) + component = matches[0] + + result = component.evaluate(x) if ( self.use_detailed_balance and self._temperature is not None @@ -401,11 +428,7 @@ def get_parameters(self) -> List[Parameter]: temp_params = (self._temperature,) if self._temperature is not None else () # Create generator for component parameters - comp_params = ( - param - for comp in self.components.values() - for param in comp.get_parameters() - ) + comp_params = (param for comp in list(self) for param in comp.get_parameters()) # Chain them together and return as list return list(chain(temp_params, comp_params)) @@ -418,16 +441,6 @@ def get_fit_parameters(self) -> List[Parameter]: List[Parameter]: A list of fit parameters. """ - # parameters = self.get_parameters() - # fit_parameters = [] - - # for parameter in parameters: - # is_not_fixed = not getattr(parameter, "fixed", False) - # is_independent = getattr(parameter, "_independent", True) - - # if is_not_fixed and is_independent: - # fit_parameters.append(parameter) - def is_fit_parameter(param: Parameter) -> bool: """Check if a parameter can be used for fitting.""" return not getattr(param, "fixed", False) and getattr( @@ -477,7 +490,7 @@ def __copy__(self) -> "SampleModel": new_model.use_detailed_balance = self.use_detailed_balance new_model.normalize_detailed_balance = self.normalize_detailed_balance - for comp in self.components.values(): + for comp in list(self): new_model.add_component(component=copy(comp), name=comp.name) new_model[comp.name].name = comp.name # Remove 'copy of ' prefix for par in new_model[comp.name].get_parameters(): @@ -485,79 +498,6 @@ def __copy__(self) -> "SampleModel": return new_model - ############################################## - # dict-like behaviour # - ############################################## - - def __getitem__(self, key: str) -> ModelComponent: - """ - Access a component by name. - - Parameters - ---------- - key : str - Name of the component. - - Returns - ------- - ModelComponent - """ - return self.components[key] - - def __setitem__(self, key: str, value: ModelComponent) -> None: - """ - Set or replace a component. - - Parameters - ---------- - key : str - Name of the component. - value : ModelComponent - The component to assign. - """ - if not isinstance(value, ModelComponent): - raise TypeError("Value must be an instance of ModelComponent.") - self.components[key] = value - - def __delitem__(self, key: str) -> None: - """ - Remove a component by name. - Parameters - ---------- - key : str - Name of the component to remove. - """ - if not isinstance(key, str): - raise TypeError("Key must be a string.") - - if key not in self.components: - raise KeyError(f"No component named '{key}' exists in the model.") - - self.remove_component(key) - - def __contains__(self, name: str) -> bool: - """ - Check if a component exists in the model. - - Parameters - ---------- - name : str - Name of the component. - - Returns - ------- - bool - """ - return name in self.components - - def __iter__(self) -> iter: - """Iterate over component names.""" - return iter(self.components) - - def __len__(self) -> int: - """Return the number of components in the model.""" - return len(self.components) - def __repr__(self) -> str: """ Return a string representation of the SampleModel. @@ -566,10 +506,14 @@ def __repr__(self) -> str: ------- str """ - comp_names = ", ".join(self.components.keys()) or "No components" - temp_str = ( - f" | Temperature: {self._temperature.value} {self._temperature.unit}" - if self._use_detailed_balance - else "" - ) + comp_names = ", ".join(c.name for c in self) or "No components" + + temp_str = "" + if ( + getattr(self, "_use_detailed_balance", False) + and getattr(self, "_temperature", None) is not None + ): + temp = self._temperature + temp_str = f" | Temperature: {temp.value} {temp.unit}" + return f"" diff --git a/tests/unit_tests/sample_model/test_sample_model.py b/tests/unit_tests/sample_model/test_sample_model.py index 137707b..26a946a 100644 --- a/tests/unit_tests/sample_model/test_sample_model.py +++ b/tests/unit_tests/sample_model/test_sample_model.py @@ -7,7 +7,6 @@ from scipy.integrate import simpson from easydynamics.sample_model import Gaussian, Lorentzian, Polynomial, SampleModel -from easydynamics.sample_model.components.model_component import ModelComponent from easydynamics.utils import _detailed_balance_factor as detailed_balance_factor @@ -28,7 +27,6 @@ def sample_model(self): def test_init_no_temperature(self, sample_model): # WHEN THEN EXPECT assert sample_model.name == "TestSampleModel" - assert isinstance(sample_model.components, dict) assert len(sample_model.components) == 2 assert not sample_model.use_detailed_balance @@ -38,7 +36,6 @@ def test_init_with_temperature(self): # EXPECT assert sample_model.name == "TempModel" - assert isinstance(sample_model.components, dict) assert len(sample_model.components) == 0 assert sample_model.use_detailed_balance assert isinstance(sample_model.temperature, Parameter) @@ -54,7 +51,7 @@ def test_add_component(self, sample_model): # THEN sample_model.add_component(component) # EXPECT - assert "TestComponent" in sample_model.components + assert sample_model["TestComponent"] is component def test_add_duplicate_component_raises(self, sample_model): # WHEN THEN @@ -95,22 +92,9 @@ def test_getitem(self, sample_model): # EXPECT assert sample_model["TestComponent"] is component - def test_setitem(self, sample_model): - # WHEN - component = ModelComponent(name="TestComponent") - # THEN - sample_model["TestComponent"] = component - # EXPECT - assert sample_model["TestComponent"] is component - - def test_contains_component(self, sample_model): - # WHEN THEN EXPECT - assert "TestGaussian1" in sample_model - assert "NonExistentComponent" not in sample_model - - def test_list_components(self, sample_model): + def test_list_component_names(self, sample_model): # WHEN THEN - components = sample_model.list_components() + components = sample_model.list_component_names() # EXPECT assert len(components) == 2 assert components[0] == "TestGaussian1" @@ -126,7 +110,7 @@ def test_convert_unit(self, sample_model): # WHEN THEN sample_model.convert_unit("eV") # EXPECT - for component in sample_model.components.values(): + for component in list(sample_model): assert component.unit == "eV" # ───── Temperature and Detailed Balance ───── @@ -425,12 +409,6 @@ def test_fix_and_free_all_parameters(self, sample_model): for param in sample_model.get_parameters(): assert param.fixed is False - def test_delitem(self, sample_model): - # WHEN THEN - del sample_model["TestGaussian1"] - # EXPECT - assert "TestGaussian1" not in sample_model.components - def test_repr_contains_name_and_components(self, sample_model): # WHEN THEN rep = repr(sample_model) @@ -445,7 +423,7 @@ def test_copy(self, sample_model): # EXPECT assert model_copy is not sample_model assert model_copy.name == "copy of " + sample_model.name - assert len(model_copy.components) == len(sample_model.components) + assert len(list(model_copy)) == len(list(sample_model)) assert model_copy.temperature is not sample_model.temperature assert model_copy.temperature.name == sample_model.temperature.name assert model_copy.temperature.value == sample_model.temperature.value @@ -455,8 +433,8 @@ def test_copy(self, sample_model): model_copy.normalize_detailed_balance == sample_model.normalize_detailed_balance ) - for name, comp in sample_model.components.items(): - copied_comp = model_copy.components[name] + for comp in list(sample_model): + copied_comp = model_copy[comp.name] assert copied_comp is not comp assert copied_comp.name == comp.name for param_orig, param_copy in zip( From ce49f0527087b9fc7699e68934769b009d120254 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Mon, 20 Oct 2025 13:08:10 +0200 Subject: [PATCH 11/71] Update example --- examples/sample_model.ipynb | 142 +----------------------------------- 1 file changed, 4 insertions(+), 138 deletions(-) diff --git a/examples/sample_model.ipynb b/examples/sample_model.ipynb index 8534aec..5808e53 100644 --- a/examples/sample_model.ipynb +++ b/examples/sample_model.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "64deaa41", "metadata": {}, "outputs": [], @@ -25,61 +25,10 @@ }, { "cell_type": "code", - "execution_count": 10, - "id": "07a18846", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "NotarizedDict({})" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sample_model=SampleModel(name='sample_model')\n", - "\n", - "\n", - "type(sample_model._kwargs)\n", - "sample_model._kwargs" - ] - }, - { - "cell_type": "code", - "execution_count": 11, + "execution_count": null, "id": "784d9e82", "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "ed6e6ebe1f3d415683cec11efc6c527f", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAwG1JREFUeJzsnQV4U1cbx/91dzcqUEopFIq7uztsDAbb2AYT5hvfjClzNjZgYwIzGDB0wGC4W9FiRQp1t9T9e95zm9JCWypJY+/vee6TmzRNTpJ7z/nfV/XKysrKwDAMwzAMw+gM+qoeAMMwDMMwDNO0sABkGIZhGIbRMVgAMgzDMAzD6BgsABmGYRiGYXQMFoAMwzAMwzA6BgtAhmEYhmEYHYMFIMMwDMMwjI7BApBhGIZhGEbHYAHIMAzDMAyjY7AAZBiGYRiG0TFYADIMwzAMw+gYLAAZhmEYhmF0DBaADMMwDMMwOgYLQIZhGIZhGB2DBSDDMAzDMIyOwQKQYRiGYRhGx2AByDAMwzAMo2OwAGQYhmEYhtExWAAyDMMwDMPoGCwAGYZhGIZhdAwWgAzDMAzDMDoGC0CGYRiGYRgdgwUgwzAMwzCMjsECkGEYhmEYRsdgAcgwDMMwDKNjsABkGIZhGIbRMVgAMgzDMAzD6BgsABmGYRiGYXQMFoAMwzAMwzA6BgtAhmEYhmEYHYMFIMMwDMMwjI7BApBhGIZhGEbHYAHIMAzDMAyjY7AAZBiGYRiG0TFYADIMwzAMw+gYLAAZhmEYhmF0DBaADMMwDMMwOgYLQIZhGIZhGB2DBSDDMAzDMIyOwQKQYRiGYRhGx2AByDAMwzAMo2OwAGQYhmEYhtExWAAyDMMwDMPoGCwAGYZhGIZhdAwWgAzDMAzDMDoGC0CGYRiGYRgdgwUgwzAMwzCMjsECkGEYhmEYRsdgAcgwDMMwDKNjsABkGIZhGIbRMVgAMgzDMAzD6BgsABmGYRiGYXQMFoAMwzAMwzA6BgtAhmEYhmEYHYMFIMMwDMMwjI7BApBhGIZhGEbHMIQWsHz5crHduXNH3A8KCsI777yD4cOHV/v8VatWYfbs2VUeMzExQX5+fr3et7S0FHFxcbCysoKenl4jPgHDMAzDME1FWVkZsrKy4O7uDn193bSFaYUA9PT0xCeffAJ/f3/xo/76668YO3Yszp07J8RgdVhbWyM8PLzifkMEHIk/Ly+vRo2dYRiGYRjVEB0dLTSELqIVAnD06NFV7n/00UfCInjixIkaBSAJPldX10a9L1n+5AcQCUqGYRiGYdQfmUwmDDjydVwX0QoBWJmSkhKsX78eOTk56N69e43Py87Ohre3t3DjdujQAR9//HGNYrEm5FZDEn8sABmGYRhGs9DT4fAtrRGAYWFhQvBRHJ+lpSU2bdqE1q1bV/vcgIAA/PLLLwgODkZmZia++OIL9OjRA5cvX67VFFxQUCC2ylcQDMMwDMMwmoZeGQXNaQGFhYWIiooSgu7vv//GTz/9hIMHD9YoAitTVFSEwMBAPPTQQ/jggw9qfN7ChQvx3nvv3fc4vSdbABmGYRhGM5DJZLCxsdHp9VtrBOC9DBo0CM2bN8cPP/xQp+dPnjwZhoaGWLNmTb0sgBRDoMsHEMMwDMNoGiwAtcgFfC8U21dZrD0obpBcyCNGjKj1eVQqhjaGYRhGeZBdori4WMzNDNMQDAwMhFFHl2P8dEIALliwQNT8a9asmajrs3r1ahw4cAC7du0Sf585cyY8PDywaNEicf/9999Ht27d0KJFC2RkZODzzz9HZGQknnjiCRV/EoZhGN2Gwnni4+ORm5ur6qEwGo65uTnc3NxgbGys6qGoJVohAJOSkoTIo0mDTLqU3EHib/DgweLvFBtYudBjeno65syZg4SEBNjZ2aFjx444duxYneIFGYZhGOV5bm7fvi2sN1SglxZutuAwDbEg04VEcnKyOJ6oRrCuFnvWyRjApoBjCBiGYRQHVXGgBZtKdJH1hmEaA1mRybvn6+sLU1PTKn+T8frNvYAZhmEY9YKtNYwi4OOodvjbYRiGYRiG0TFYADIMwzCMFkNxlJs3b4a6069fP7zwwgt1fv6qVatga2ur1DFpMywAGYZhGKYRULLB3LlzRSUKKhVGfeaHDh2Ko0ePQhu4c+eOEJGUnBMbG1vlb5R8KS+3Qs9jNAcWgAzDMAzTCCZOnIhz587h119/xfXr17F161ZhzUpNTYU2QeXUfvvttyqP0WemxxnNgwUgwyiJ8IQsfLDtCuIz81Q9FIZhlATVkj18+DA+/fRT9O/fX2Qwd+nSRdSnHTNmTMXzvvrqK7Rt2xYWFhaig9S8efOQnZ19nztz27Ztol89ZUFPmjRJZLKSyPLx8RFly55//vkqBbLpcWphSq1M6bVJjC1durTWMUdHR2PKlCni/ezt7TF27Ng6We8effRRrFy5sspjdJ8evxdqxUrfA1lEqRbfG2+8IYp7y8nJyRHl2ywtLcXfv/zyy/teg5o5vPLKK+Iz0Wfr2rWrqPHLKAYWgAyjBKi60msbLuLnI7fxyE8nkZ5TqOohMYxGnke5hcUq2epaIY0EDG0UY1db9ynKSF2yZAkuX74sBN2+ffvw2muvVXkOiT16zl9//YWdO3cKsTN+/Hjs2LFDbL///rtob0r97itDzQzatWsnrJAktObPn4/du3dXO46ioiLhnrayshLCldzUNP5hw4aJ2nm1QYKW6ugeOXJE3Kdbuj969OgqzyM3MXXW6ty5My5cuIDly5fj559/xocffljxnFdffVWIxC1btuC///4Tn/Xs2bNVXufZZ5/F8ePHxfdx8eJF0bKVxnnjxo1ax8noUCFohlE3Tt1Ow4XoDLF/KzkHs1edxuo5XWFuzKccw9SVvKIStH5H6ujU1Fx5f2idzleKfyPrHTUX+P7779GhQwf07dsX06ZNE00J5FRObiCrHYmhp59+GsuWLasizkgsUR97giyAJPoSExOFSKNmBWRl3L9/P6ZOnVrxfz179hTCj2jZsqUQdYsXL65ohlCZtWvXioLbP/30U0WRbbLikTWQRNiQIUNq/KxGRkZ45JFH8Msvv6BXr17ilu7T45Whz0RWzu+++068R6tWrRAXF4fXX38d77zzjhC6JAj/+OMPDBw4UPwPiWJPT8+K16AGDjQuuqWi4ARZA0kY0+Mff/zxA38bpnbYAsgwSmDFoQhx2z/ACbbmRjgfnYF5f55FUUmpqofGMIwSYgBJ4FDsH1moSEiRECRhKGfPnj1C7JA7k6xvM2bMEDGClVvekdtXLv4IFxcXIRZJ/FV+jLpfVaZ79+733b969Wq1YyWL3M2bN8UY5NZLcgNTEe5bt2498LM+9thjWL9+veikRbd0/17ovWkMlbu4kEgll3dMTIx4H7I2kktXDo2BXN9ywsLChKubBK18nLSR1bAu42QeDJsjGEbB3EjMwt5rSaC5753RQUjLKcT0n07gQHgyXvv7Ir6c3A76+tzeimEehJmRgbDEqeq96wN1miCLG21vv/226C3/7rvvYtasWSK+btSoUSJT+KOPPhJih9ynjz/+uBBC8q4n91rSSEBV9xhZ8BoKiTBqf/rnn3/e9zcnJ6cH/j/FMZJFj2IOAwMD0aZNG5w/f77B46ltnJR1fObMGXFbmcqCmGk4LAAZRknWv2FBrvB1tBDb8ukd8cRvodh0LhbO1iZYMDxQ1cNkGLWHxI6mhk2Qu1Zee49EDIk2SnSQd6dYt26dwt7rxIkT990ncVYdZJkkN7Czs3ODW6CR1Y+SWMhdXR303hs2bBBxlHIrILmlyepIbl4SwCRsT548KUrnEBRLSBnU5D4nQkJChAWQrJ29e/du0DiZ2mEXMMMokITMfGw+L9XJerKPX8Xj/Vs54/NJwRUCkayCDMNoPuTGHTBggIhno0QF6mVMrtHPPvtMZNcSLVq0EPF93377LSIiIkRcH8ULKgoSV/R+JKAoA5jenxJBqmP69OlwdHQUY6MkEBovuawpu5jcs3WB4h2p9iFZOauDxCFlGj/33HO4du2aSPQga+hLL70kBDBZ8Mj6SYkglAxz6dIlYSmt3LqNXL80VsoU3rhxoxjnqVOnsGjRImzfvr2B3xRTGRaADKNAVh67jaKSMnTxtUdIM7sqf5vQwROtXK1AyYXHbqWobIwMwygOEjMUy0ZJF3369BEuUXIBk0iiJAiCMnSpDAyViqG/k/uVhIyiePnllxEaGiqsZpRcQu9Fmb7VQe7mQ4cOCcvbhAkThLWOxBjFANbVIkiJLyQi6bY6KM6RspZJsNFnp2QXeo+33nqrSuYyWfYog3jQoEEiqYRc05WhZA8SgPT5KD5w3LhxOH36dIXVkGkcemV1zXVn7kMmk8HGxgaZmZkNNqUz2kNWfhF6LNqHrIJi/PxoJwwMdLnvOR9uu4KfjtzGtM5e+GTi3QxBhmEgRAhZenx9fUVMHfNgKEmEMozr00JNV6jteJLx+s0WQIZRFGtORQnx18LZEv0DnKt9Tk9/R3F7+EZKneuMMQzDMIyiYQHIMAqgsLgUvxy5UxH7V1OWb1dfexgZ6CE2Iw+RqXfLPzAMwzBMU6KZ6VUMo2acjUpHgiwfDhbGGNteKlpaHZTR2KGZHU7eTsPhmynwcbRo0nEyDKNd1KWFG8NUB1sAGUYBhMVkitvOPvYwMay9fljvcjfwkRvJTTI2hmEYhrkXFoAMowAuxkoCsK2nzQOf28tfKrZ67FYqSko5DpBhGIZpelgAMowCuBgj9f0NroMAbOthA2tTQ2TlF1f8H8MwDMM0JSwAGaaRZOYWVSR0BHvYPvD5Bvp66NFc7gbmeoAMwzBM08MCkGEaSVi5+9fbwRw25lX7dtZEL3kc4E0WgAzDMEzTwwKQYRrJhXI3Lrl260qvFo4V2cM5BcVKGxvDMAzDVAcLQIZRUAZwO88Hu3/lkLXQ085MtI07dTtNiaNjGIaRWLVqFWxt6z5PMdoNC0CGUZALuC4ZwHL09PTuloNhNzDDaAUJCQmYP38+WrRoIVqPubi4oGfPnli+fDlyc1Vf+H3q1Km4fv26qofBqAlcCJphGkFKdoHo6qGnBwS516+fZM8WjlhzKpoTQRhGC4iIiBBijyxsH3/8Mdq2bQsTExOEhYVhxYoV8PDwwJgxY1Q6RjMzM7ExDMEWQIZRgPvXz9ECVqZ1SwCRQ5nAJBzDE7OQJMtX0ggZhmkK5s2bB0NDQ4SGhmLKlCkIDAyEn58fxo4di+3bt2P06NHieV999ZUQhxYWFvDy8hL/l52dXfE6CxcuRPv27au89tdffw0fH5+K+wcOHECXLl3Ea5DgJOEZGRkp/nbhwgX0798fVlZWsLa2RseOHcWYqnMB37p1S4yPLJWWlpbo3Lkz9uzZU+W96X1J0D722GPiNZs1ayYELaP5sABkmEZwsQHxf3LsLYwrrIZHb7EVkGHuo6wMKMxRzUbvXUdSU1Px33//4ZlnnhGirKawD0JfXx9LlizB5cuX8euvv2Lfvn147bXX6vxexcXFGDduHPr27YuLFy/i+PHjePLJJytef/r06fD09MTp06dx5swZvPHGGzAyqv7ilITniBEjsHfvXpw7dw7Dhg0TQjUqKqrK87788kt06tRJPIcE69y5cxEeHl7nMTPqCbuAGaYRyAs51yf+71438KVYGU5GpGF8iKeCR8cwGk5RLvBxzb21lcr/4gDjuvXqvnnzJsrKyhAQEFDlcUdHR+TnS9Z9EoeffvopXnjhhSrWtQ8//BBPP/00li1bVqf3kslkyMzMxKhRo9C8eXPxGFkb5ZB4e/XVV9GqVStx39/fv8bXateundjkfPDBB9i0aRO2bt2KZ599tuJxEokk/IjXX38dixcvxv79++/7vIxmwRZAhmkgNOHLW8DVpQNIdbQvtxxejpMpdGwMw6ieU6dO4fz58wgKCkJBQYF4jFysAwcOFDGB5FKdMWOGsCDWNUnE3t4es2bNwtChQ4W17ptvvkF8fHzF31966SU88cQTGDRoED755BPh5q0JsgC+8sorQkCSa5jcwFevXr3PAhgcHFyxT5ZGV1dXJCUlNeAbYdQJtgAyTANJlBUgOatAdPZo7dYwAdimvHZgeEIWCotLYWzI12QMU4GRuWSJU9V71xHK+iVhdK9blGIACXnixZ07d4TljlyoH330kRBzR44cweOPP47CwkKYm5sLFzFdXFamqKioyv2VK1fi+eefx86dO7F27Vq89dZb2L17N7p16yZiCB9++GERd/jvv//i3XffxV9//YXx48ffN24Sf/R/X3zxhfgMNM5JkyaJsVT5Ku5xIdNnLS0trfP3w6gnvNowTCMLQPs7W8LM2KBBr0G1AKkvcGFJKW4kZSl4hAyj4VBcG7lhVbGVx9TVBQcHBwwePBjfffcdcnJyanwexeSRcKKYOhJrLVu2RFxcVYHr5OQkyslUFoFkRbyXkJAQLFiwAMeOHUObNm2wevXqir/R67744osiLnHChAlCMFbH0aNHhTWRxCElppBlj0QqoxuwAGSYRmYAN9T9K7+SllsBL8eyG5hhNBWK4aMEDUqWIKscuVLJIvjHH3/g2rVrMDAwEFY2suZ9++23omzM77//ju+//77K6/Tr1w/Jycn47LPPhPt26dKlwpIn5/bt20L4UfIHZf6SyLtx44Zw4+bl5YnYPcoSpr+RwKNkkMoxgpWh+MCNGzcKgUnZw2Q5ZMue7sACkGEayN34v8ZV1pcLwEtx0usxDKN5UEIGZclS7B0JNEquIDFIYo9crZRgQY9RGRhKBiGr3Z9//olFixZVeR0SayQmSfjR8ymOkP5fDrmJSVBOnDhRWPooA5gSTJ566ikhMimecObMmeJvVI5m+PDheO+996odM43Fzs4OPXr0EPGEFFfYoUMHpX9XjHqgV3ZvsAFTZygby8bGRmRkUb0lRneg0ybkg93IyC3C1md7NkoEbjkfi/l/nUeHZrbYOK+nQsfJMJoEZcyShcvX11d00mAYZR1PMl6/2QLIMA0hJj1PiD8jAz0EuFo16rWC3CUL4JV4GUpK+XqMYRiGUT4sABmmEQWgA92sYWLYsAQQOb6OFjA3NkB+USkiku92BGAYhmEYZcECkGEaUwC6PH6vMUhlZCQXBMcBMgzDME0BC0CGaQByoaYIAVglEYQzgRmGYZgmQCsE4PLly0WlcgrkpK179+5V0uarY/369aJVDgWGUv2jHTt2NNl4Gc3neqLkqm1VbrlrLPKewJfKM4sZhmEYRplohQCkxtfU8oaKbIaGhmLAgAEYO3asaLZdHVQ486GHHhLV1yltnxpr03bp0qUmHzujeWTmFokOIERzp7r1Cq2rBfBKnAylnAjCMAzDKBmtEIBUv4iaVVNRS6p9RC12qKfhiRMnqn0+9U4cNmyYaJhNNZeoPhPVPqIq7gzzIG4mSx07XK1NYWVatUVSQ2nhbCnawGUVFCMqrW49QRmGYRhGpwVgZUpKSkTfQ2rHQ67g6qAK6lSsszJUAJMerw1q5k21gypvjO5xM0ly//q7WCrsNY0M9BFYXk6GE0EYhmEYZaM1AjAsLExY/UxMTPD0009j06ZNaN26dbXPpT6LLi4uVR6j+/R4bVDFdiocKd+8vLwU+hkYzRKAzZ0UJwCJIE4EYRiGYZoIrRGAAQEBop/hyZMnMXfuXDz66KO4cuWKQt+D2vtQ1XD5Fh0drdDXZzSDG0qwABJtygtCX2YLIMMwDKNktEYAGhsbi0bbHTt2FJY66qFIsX7V4erqisTExCqP0X16vDbIuijPNJZvjO5aAFso2ALYxuNuJjB3aGQYzWLWrFnQ09MTm5GRkfAqDR48GL/88gtKS0srnufj44Ovv/76vv9fuHAh2rdvX+WxtLQ0vPDCC/D29hZrnLu7Ox577DFERUU1yWditButEYD3QiccxexVB8UG7t27t8pju3fvrjFmkGHk5BYWizZw8sQNRdLSxQqG+npIzy1CXGa+Ql+bYRjlQ8mF8fHxuHPnjihF1r9/f8yfPx+jRo1CcXFxvV6LxF+3bt2wZ88efP/997h586aIb6fbzp07IyIiQmmfg9ENDKEFkGt2+PDhaNasGbKysrB69WocOHAAu3btEn+fOXMmPDw8hGWQoBOyb9+++PLLLzFy5EhxUlH5mBUrVqj4kzDqTkRyjri1tzCGg6WJQl/b1MgA/i5WuBovE1ZAD1szhb4+wzDKhbxEck8SrTlUXYJE3MCBA7Fq1So88cQTdX6tN998E3FxcULwyV+T1jha16jixTPPPPPAercMo/UCMCkpSYg8uvKi5AwqCk0nCZnfCTKX6+vfNXb26NFDiMS33noL//vf/8TJtHnzZrRp00aFn4LRZfevnDbu1kIAXo7NxNCg2kMSGEbboVCIvGLJ4t7UmBmaCXduY6G6tBSStHHjxjoLQPJgkWFi+vTp94UmmZmZYd68eWL9Iiuhvb19o8fI6CZaIQB//vnnWv9O1sB7mTx5stgYpj7cSJJqALZQcAJI5YLQ68/E4FIcZwIzDIm/rqu7quS9Tz58EuZG5gp5Leo6dfHixYr7r7/+uhBwlSksLKyoXJGcnIyMjAxRp7Y66HESx2Qd7NKli0LGyOgeWiEAGUZrLICVEkEYhtEOSKxVtiZSEwJKGqnMkiVLcOjQofv+j2GUBQtAhmlACRhFJ4DICXSzhr4ekJRVgKSsfDhbmSrlfRhGEyA3LFniVPXeiuLq1avw9fWtuO/o6CiqVlSmsivXyckJtra24v9qej0SlPe+BsPUBxaADFNHCotLEZmaq5QagHLMjQ3h42ghkk2uxmexAGR0GhI5inLDqop9+/aJRgUvvvhinf+HYtanTJmCP//8E++//36VOMC8vDwsW7ZMdK/i+D+mMWhtGRiGUTSRqTkoKS2DpYmh6AOsLMgKSFAyCMMwmgOVHqOOUrGxsTh79iw+/vhjjB07VpSBoUTF+kD/S8KPkhkp25caD5CLmIRfUVERli5dqrTPwegGLAAZpp7u3+bOlgrJDqyJ1uUC8BoLQIbRKHbu3Ak3NzdR7JlqAu7fv1/E9m3ZsgUGBgb1ei0HBwecOHFC1BJ86qmn0Lx5c2EVpNvTp0/Dz89PaZ+D0Q30yjjKtMHIZDJRdobawnFXEO1nyd4b+Gr3dUzs4Ikvp7RT2vvsvZqIx38NRYCLFXa92Edp78Mw6kZ+fj5u374t4uVMTTn8gVHe8STj9ZstgAyjLgkg97qAbyVno6C4RKnvxTAMw+gmLAAZpp4lYPyVLADdbExhY2aE4tIy3EiU3pNhGIZhFAkLQIapA5T8EZHcNBZAii8MdLMS+5wIwjAMwygDFoAMUwdi0nNRUFwKY0N9eNkrvyzF3UxgqfMIwzAMwygSFoAMUw/3r5+jBQyoUnMTCcBrCWwBZBiGYRQPC0CGUaMEEDmBrndrAXKiPsMwDKNoWAAyTL0SQKTYPGVDnUbI0pieW4REWUGTvCfDMAyjO7AAZBg1tACaGhkIdzPBiSAMwzCMomEByDAPgFywt+QWQCX1AK4tDvAKC0CGYRhGwbAAZJgHQC7Y7IJi4ZL1cZCsck0B9wRmGKapuXPnjihFdf78eVUPhVEyLAAZ5gHcSJJKsXjbm4syME2FvBbgtQQuBcMw6s6sWbMwbtw4qBsk5jZv3lzn53t5eSE+Ph5t2rRR6rgY1cMCkGHqmADSVPF/91oAqQB1fhG3hGMYXaGwsFBl721gYABXV1cYGhqqbAxM08ACkGHqmADSlPF/hLOVCewtjFFaBlxPZCsgw2gqBw8eRJcuXWBiYgI3Nze88cYbKC4urvh7v3798Oyzz+KFF16Ao6Mjhg4dKh6/dOkShg8fDktLS7i4uGDGjBlISUmp8n/PP/88XnvtNdjb2wvhtnDhwoq/+/j4iNvx48cLS6D8Pt3S/Xu36lzAJSUlePzxx+Hr6wszMzMEBATgm2++qdb6+cUXX4jP5+DggGeeeQZFRUVK/V6ZxsESn2EewM1E1VgA5S3hjt5MFXGAwZ62Tfr+DKMOCVhleXkqeW89M7MKUdQYYmNjMWLECCGSfvvtN1y7dg1z5syBqalpFbH266+/Yu7cuTh69Ki4n5GRgQEDBuCJJ57A4sWLkZeXh9dffx1TpkzBvn37qvzfSy+9hJMnT+L48ePifXr27InBgwfj9OnTcHZ2xsqVKzFs2DBh3SPocRJ2BN1OmjQJRkZG1Y6/tLQUnp6eWL9+vRB2x44dw5NPPimEHo1Fzv79+8VjdHvz5k1MnToV7du3F5+VUU9YADLMA7iZ3LQ1AO8tCC0JQLYAMroHib/wDh1V8t4BZ89Az7zxbR+XLVsm4uq+++47IShbtWqFuLg4Iebeeecd6OtLjjh/f3989tlnFf/34YcfIiQkBB9//HHFY7/88ot4revXr6Nly5biseDgYLz77rsVr0Hvs3fvXiEAnZycxOO2trbCOihH/jgxf/58EfNHorA6SBi+9957FffJEkhCc926dVUEoJ2dnXhvEpn0GUeOHCnGwQJQfWEByDC1kJpdgLScQpAhoLlT01oACc4EZhjN5urVq+jevXsVayJZ6LKzsxETE4NmzZqJxzp2rCp0L1y4IKxp5P69l1u3blURgJUhK1xSUlKdxrZixQr8/PPPwqpXWRTey9KlS4X4jIqKEpZIilEk615lgoKCKiyM8nGEhYXVaRyMamAByDB1SADxsDWDmfHdya2paFWeCSxvCacIlxTDaArkhiVLnKreuymxsKhaYooE4ujRo/Hpp5/e91wSV3Ludd3SHEFu2wdB4vK5557DmjVr7hORlfnrr7/wyiuv4MsvvxRC1srKCp9//rlwOVemoeNgVAcLQIapSwJIE8f/yaG4Q0N9PcjyixGXmS+EKMPoCiI5QQFuWFUSGBiIDRs2VLmAozg/ElIUW1cTHTp0EP9HCRuNycglYSaP95NDMXoU9/e///0PEyZMqPX/aaw9evTAvHnzqlggGc2Hs4AZpi49gF2aPv6PMDE0qEg+uRrHbmCGUWcyMzNF9mzljRImoqOjhbWNEkC2bNkiYvYocUMe/1cdlEWblpaGhx56SMTnkejatWsXZs+efZ+gqw0SkBSLl5CQgPT0dOHCJcsixRfS2Ohx+VYdFFcYGhoq3ptiD99+++0a4wUZzYIFIMPUpQagCuL/5HAcIMNoBgcOHBDCqvL2wQcfYMeOHTh16hTatWuHp59+WpRVeeutt2p9LXd3d2F9I7E3ZMgQtG3bVpSJoYSO2oTjvZDrdvfu3SJ5hMaTmJgohCiJQnoPcifLt+p46qmnhJWQsnq7du2K1NTUKtZARnPRKyO7NNMgZDIZbGxsxFWftbW0SDPaRdeP94hWcBvn9UCHZnYqGcOKQ7fw8Y5rGNHWFcumqyYjkmGagvz8fNy+fVtkmlKZFIZR1vEk4/WbLYAMUxOy/CIh/lRRA7Ayrd1sxO1ldgEzDMMwCoIFIMM8wP3ram0Ka9Pqi6Q2BUHu0tVpZGquEKUMwzAM01hYADKMmnUAuRc7C+OK7N8rbAVkGIZhFAALQIapgRtJWWohACtbAdkNzDAMwygCFoAM88ASMOogAMvjAGMzVT0UhmEYRgtgAcgwDygCrcoSMHLYAsgwDMMoEhaADFMNuYXFiEnPU2kR6Mq08ZAsgDeTs5FfVPcisAzDMAxTHSwAGaYaIpJzxK2DhTHsLYxVPRy4WJuIsZSUluFaghSbyDAMwzANhQUgw9SSANJcDRJACOoh2rrCDcxxgAzDMEzjYAHIMLUlgKiJAKzsBuY4QIbRLlatWiVavGkCCxcuRPv27et9Abt582aljYlpGCwAGaYabiSqnwCsSAThTGCGUTtmzZolhA5txsbGaNGiBd5//30UFxdDm3jllVdEH2FG8zFU9QAYRp0tgC2cVZ8Acm8pmKsJWSgqKYWRAV+/MYw6MWzYMKxcuRIFBQXYsWMHnnnmGRgZGWHBggXQFiwtLcXGaD5asYIsWrQInTt3hpWVFZydnTFu3DiEh4c/0OQuv1qTb9x8nCEKiksQmZarNjUA5Xjbm8PSxBCFxaW4lSwJVIZh1AcTExO4urrC29sbc+fOxaBBg7B161akp6dj5syZsLOzg7m5OYYPH44bN25U+xp37tyBvr4+QkNDqzz+9ddfi9ctLS3FgQMHxJpFlrhOnTqJ1+zRo8d9697y5cvRvHlzYZEMCAjA77//XuXv9Bo//PADRo0aJV4jMDAQx48fx82bN9GvXz9YWFiI171161aNLuDTp09j8ODBcHR0hI2NDfr27YuzZ88q6BtllIlWCMCDBw+KK60TJ05g9+7dKCoqwpAhQ5CTI2Vy1oS1tTXi4+MrtsjIyCYbM6O+3EnJFdm2VqaGcLYygbqgr6+H1m5yNzDHATLaT1lZGYoKSlSy0Xs3FjMzMxQWFgr3MAk6EoMksOi1R4wYIdaqe/Hx8RHCkSyJlaH79DokDuW8+eab+PLLL8VrGxoa4rHHHqv426ZNmzB//ny8/PLLuHTpEp566inMnj0b+/fvr/K6H3zwgRCn58+fR6tWrfDwww+L55LVkl6Xxvrss8/W+BmzsrLw6KOP4siRI2IN9vf3F5+NHmfUG61wAe/cufM+6x5ZAs+cOYM+ffrU+H909UNXawxTUws4OkbUCcoEPnUnTSSCTOyo6tEwjHIpLizFivkHVfLeT37TF0YmBg36XxJNZJ3btWuXsPZRAsTRo0eFNY34888/4eXlJR6fPHnyff//xBNP4Omnn8ZXX30lrIpkUQsLC8OWLVuqPO+jjz4SFjfijTfewMiRI5Gfny+8WV988YUQjPPmzRN/f+mll4RAo8f79+9f8RokCqdMmSL2X3/9dXTv3h1vv/02hg4dKh4jEUnPqYkBAwZUub9ixQqR0EKGGbIsMuqLVlgA7yUzUwqSt7e3r/V52dnZwqROJ+LYsWNx+fLlWp9PcR0ymazKxmgf6pgBfG8m8CUuBcMwase2bdtEfBwJMBJ+U6dOFSKMrHNdu3ateJ6Dg4NwyV69erXa16EwJgMDA2HFkxs1SLSRdbAywcHBFftubm7iNikpSdzSa/fs2bPK8+n+ve9Z+TVcXFzEbdu2bas8RqKypvUuMTERc+bMEZY/cgGTZ43W1qioqAd+X4xq0QoLYGUoPuKFF14QB3qbNm1qfB6dfL/88os4+Ekw0lURXZ2RCPT09Kwx1vC9995T4ugZdWoB569GCSD3ZgJfjZOhtLRMuIUZRlsxNNYXljhVvXd9IZFGcXcUc+fu7i6EH7l96wv9P7llye07YcIErF69Gt988819z6MEEzlybwWtgfWhuteoz+uS+zc1NVWMjwwqZLEkKyK5vhn1RusEIMUCUrwDxSPUBh2gtMkh8UcBsBQQSzER1UExEWRGl0NXRGQ9ZLSLm+UlYMgFrG7QmIwN9ZFVUIzo9Fx4O1ioekgMozRIfDTUDasKKGmCyr9UhtYVKgVz8uTJChcwCSZK2GjdunWNr0VuYDJiLFu2TPw/CcH6QO9LbmcSaHLofm3v2RDoNWmMFPdHREdHIyUlRaHvwSgHrRKAFKhKJvhDhw7VaMWrCbriCQkJEdlPNUFXNrQx2gv12ZVn2LZyUz8LIJV+aeVqhYsxmbgUK2MByDBqDrlGKcSI3KRkYKBqFRSv5+HhIR6vTcB169ZNxOVRcgcllNSHV199VcT20bpGSSX//PMPNm7ciD179kDRn4+yiykbmYwi9L71HSujGrQiBlCepUTxEvv27YOvr2+9X6OkpEQE2crjKBjdjf8rLi2DrbkRXK3VsyxQRUFojgNkGI2AXLkdO3YUSRHkeaI1i+oEVna1Vsfjjz8uXKmVs3vrCsURkluWwpuCgoKE+KRxUHkXRfLzzz+LMjcdOnTAjBkz8Pzzz4skTEb90StTRK67iqEsJ4qRoAwpiu2TQwGp8isRiqegKy6K4yOoQjtdXZG5PiMjA59//rnIyKLM4bqayOlqh96DYggp8JXRfNadjsZrGy6iR3MHrJ7TDerI7yci8fbmS+jT0gm/PdZF1cNhGIVByQa3b98WF/Fcl1Uq0bJ+/XpcvHhR1UPRuuNJxuu3driAKeiWuPfKRl43iaCMpMr1k+iKhUzyCQkJojgnXZ0dO3ZM4fERjGZxJV7KdJPX21NH2pRbAK/EZQpLgrqVqmEYpnFQFi0VhP7uu+/w4Ycfqno4jJaiFQKwLkZMqpxemcWLF4uNYaoVgOUiSx1p5WoNSv5NyS5EUlYBXNTUVc0wTMOgkKY1a9YIN25D3L8MozMxgAyjqAsJKq+i7gLQzNigIkP5QnSGqofDMIyCobp/VHd27dq1oh4gwygDFoAMU05Mep4or2JsoI/mTupXAqYy7b1sxe15FoAMwzBMA2AByDDlUHs1wt/FUpRbUWdCmtmJWxaADMMwTENQ71WOYZoQTUgAudcCSC7gklKNT+RnmCrUt5sFw1QHH0c6kATCMIrgigbE/8lp6WIFc2MD5BSWiNqFAa7qV7SaYRrSAo2qNcTFxcHJyUnc5yx3piHx3FQ/MTk5WRxPdBwx98MCkGHKuapBFkADfT0Ee9rgREQazkWlswBktAJarKlmW3x8vBCBDNMYzM3N0axZsyol4Ji7sABkGACZuUWIzcgT+4EaYAEk2nvZCQFIcYDTujRT9XAYRiGQtYYWbep/Sx2aGKYhUPa0oaEhW5BrgQUgw1SK//OyN4O1ae3tmdSFkGacCcxoJ7RoU5u0B7VKYxim4bBdlGEqCcBAV82w/hEh5Ykg4YlZyC4oVvVwGIZhGA2CBSDDaFgCiBxna1N42JqBGuFcjGErIMMwDFN3WAAyjIaVgKmuHMy5KBaADMMwTN1hAcjoPIXFpbiZlKVxFkCC4wAZhmGYhsACkNF5qI5eUUkZrE0NhUtVk6jcEo5qXzEMwzBMXWAByOg8Fe5fd2uNKxnQxsMGhvp6SM4qqChjwzAMwzAPggUgo/NUJIC42UDTMDUyQGB53CK7gRmGYZi6wgKQ0XmuxGeK20A3zeymwYkgDMMwTH1hAcjoNBQ3p4klYCrDiSAMwzBMfWEByOg0FDcnyy+GkYEe/J012wJ4KTZTZDQzDMMwzINgAcjoNFfjpfIvLZytYGyomaeDr6MFbMyMUFBcimsJkjWTYRiGYWpDM1c8hlEQ56PTxW2Qhrp/CcpcrlwOhmEYhmEeBAtARqcJvSMJwM4+dtBkOBGEYRiGqQ8sANWUklIu6qtsKF5ObjHr6G0PTaaDtyRgQyPTVD0UhmEYRgNgAaiGhN5Jw9CvD+FERKqqh6LVXI7LFHFzduZGaO5kAU2mo7cdDPT1EJ2Wh5j0XFUPh2EYhlFzWACqIRvOxor2ZAs2hiG/qETVw9F69y9Z/zStA8i9WJoYIthTKmR9IoKtgAzDMEztsABUQxaMaAVnKxPcTsnBN3tvqHo4WovcXdpJw+P/5HT3cxC3x2+x5ZhhGIapHRaAaoi1qRE+GNdG7K84FCHquzGKLwB9JlKyAHYqj5/TdLqVC0AKHaDPxzAMwzA1wQJQTRka5IoRbV1FMsgbGy+iuIQL/CqSO6m5SMkuFLX/2pa7TjUdsmQa6uuJ4tYx6XmqHg7DMAyjxrAAVGMWjgkSBX4vxcrw85Hbqh6O1iXaEMEeNjAxNIA2YG5siHbl5WDYDcwwjKaTml2AX47cRhEbQJQCC0A1xtnKFG+ODBT7X+2+jjspOaoektZQ4f710ezyLzXFAXIGOcMwms6nO6/h/W1X8Mr6C6oeilbCAlDNmdzREz1bOIhyJZQVzLFdiuF0uQVQW+L/5HRvXp4IwnGADMNoMGci07AuNEbsz+zuo+rhaCUsANUcKk+yaHwwTI30xaL+58koVQ9J40nPKcSt5JyK+nnaRIdmdjAy0EN8Zj4iU7keIMMwmgfFvL+9+bLYn9rJS+vmaXWBBaCakpNZgNLybiDNHMzx2tBWYv/jHVcRncYLuyLcvy2cLWFnYQxtwszYACFe0mTJbmCGYTQRMnRciZfB1tQIz/XwVfVwtBYWgGrIhb3R+OPt47h2LL7isVk9fNDFxx65hSV47e+LFeKQqT+n5fX/tPSqslslNzDDMIwmkZxVgC/+Cxf7z/u5YfunZ8WayCgeFoBqCMVuFReW4sSWWyjMKxaP6evr4bNJwTAzMhAL+x8nI1U9TI3lTEUHEC0VgH72FZnAHAfIMIwmsejfq8jKL0aIqzXKLmaguIC7YSkLFoBqSNt+nrB1MUdeVhHO7LxT8biPowXeGC65ghftuIYojvGqN9Ra72KMVFi7s5ZlAFeOA6T6hklZBaKbDMMwjCZw6nYaNp6NBXXmfNTOHvnZRWItbNPPQ9VD00pYAKohBob66Dmxhdg/vzcamcl3hd6Mbt7CwpNXVIJX/r7AruB6Ql1VCktK4WhpDG8Hc2gjpkYUB1heD5DdwAzDaEjixztbLon96UHuiD+dJPZ7TmoBAwOWKsqAv1U1xbutA7wC7VBaXIZjG29VPC5cwRPbwdzYQFwtrTp210LIPJjQyLvuX8qw1lbk5WBOREjxjgzDMOrMyqN3cC0hC7bmRuicqS/WPq/W9vBuI81ljOJhAaimkDjpOdlfmMIjziUjNlwSLvKs4AUjAisKZd5IzFLhSDWL0PL4P211/95bEJrjABmGUXeofSU1OyBebtcMMWGp0NPXE9Y/bb5QVzUsANUYB3dLBPWRYh+O/H2jirv3ka7N0LelkygQPf+v8ygs5lY5D4L6KoeWZwBrawKInPbNbGFiqI+U7ALcSs5W9XAYhmFq5N0tl0VYU2dvWxiFycRjbXq7izWQUR5aIQAXLVqEzp07w8rKCs7Ozhg3bhzCw6U08tpYv349WrVqBVNTU7Rt2xY7duyAutFltC+MzQyREp1dpSwMXRV9PikYduZGol7S4j3S1RNTM+ej05GRWwRrU0O08bCBNkP9jTv5SCL34PUUVQ+HYRimWv67nIA9VxNhqK+Huc3ckBqTDRNzQ3QezfX/lI1WCMCDBw/imWeewYkTJ7B7924UFRVhyJAhyMmpOQPy2LFjeOihh/D444/j3LlzQjTSdumSFISqLphZGqPzSKkNTuWyMISztSkWTWgr9r8/eAsnOeC/VnZfkYKK+7dyhpEOBBX3D3AWt3uvJqp6KAzDMPeRU1CMhVuljh9PdvfBnQOxYr/zSF+x9jHKRStWwZ07d2LWrFkICgpCu3btsGrVKkRFReHMmTM1/s8333yDYcOG4dVXX0VgYCA++OADdOjQAd999x3UuSzM6R1Vkz6GtXET/YIpzOuldRcgyy9S2TjVHbrKJAYGukAXGFT+OSlZiI8LhmHUjcW7ryMuMx9e9mbommco1jgu+9J0aIUAvJfMTKnOm719zYH+x48fx6BBg6o8NnToUPF4TRQUFEAmk1XZmqwszCSpLMzFfdHISKxa/+/dMUFoZm8uAmkXbpGuppiq3EnJwc2kbOFmoNhJXYDqRlK7u+LSMhwMT1b1cBiGYSq4HJeJleVVLN7s7Y8r5da/XpP9uexLE6F133JpaSleeOEF9OzZE23atKnxeQkJCXBxqWoJovv0eG2xhjY2NhWbl5cXmgqfto6iNExpSRmOrL9R5W+WJoZYPLUd9PWAjediseW8dCIx91v/uvjaw8bMCLrCwEDnKp+fYRhGHRLy/rcxTNyObOOKotBUkeTo09aBy740IVonACkWkOL4/vrrL4W/9oIFC4R1Ub5FRzdtf8Jek/yhb6CHyEupuBNWNbC/o7c9nhvgL/bpxOIOEFWRCyC5W1RXkH/eA+HJotAqwzCMqqH6tRdiMmFlaognWrgh6nKaWNt6TpLWMKZp0CoB+Oyzz2Lbtm3Yv38/PD09a32uq6srEhOrWkXoPj1eEyYmJrC2tq6yNSUUG9FugGR1JCtgyT2lX54b0EJYuHIKS/Ds6rMoKOYeikRmbhFOl9f/0zUBSG3hKFM8M6+oogg2wzCMqohOy8UXu6QqHQuGtsLl7VJf+3YDvcQaxzQdWiEAqdAtib9NmzZh37598PV9cPp49+7dsXfv3iqPUQYxPa7OdBrhAzNrY2Qm5eHCvqoWSEMDfSyZFiIW/MtxMtEvmAEOXE8SroaWLpaiiLYuYaCvJ7KeiT1X2A3MMIxq1+o3N18SNf+6+tojILMMmcl5MLc2Fmsb07Toa4vb948//sDq1atFLUCK46MtLy+v4jkzZ84ULlw58+fPF9nDX375Ja5du4aFCxciNDRUCEl1hmoC9hjfXOyHbr+DnMyCKn93tTHFl1PaVZjZd12uOaZRV9hdLnx0zfonR/65yQ3OXUEYhlEVm87F4tD1ZBgb6uPdwQE4869k/es+oTmMTQ1VPTydQysE4PLly0VMXr9+/eDm5laxrV27tuI5VBYmPv5uIeUePXoIwbhixQpROubvv//G5s2ba00cURcCurrC2ccaRQUlOL7pbp9gOQNauWBOb8kK+trfF0V2sK5CHVIOXk/WqfIv99KnpROMDfRxJzUXt5I5NpRhmKaHuhK9v+2K2J8/0B9xhxLEGubia42ALjWHXjHKQysEIFk1qtuoNqCcAwcOiPqAlZk8ebLoGELlXShxZMSIEdAEqEdin6ktxX74iQTE35LK3lTm1aGt0M7LVsR+6XI84Ok7acjKL4ajpTHae9lCF6Es8a5+UkkkLgrNMIwq+GDbFdGJqZWrFcZ4OIi1C3pA7yktxZrGND1aIQB1EbpqCuzpJvYP/RVepU8wQSb27x4KEW3PzkVliJNPl92/1BWD4uF0lcGtJevn3qtSNxSGYZimYt+1RGw5HydKlX0yvi2OlZcya93DTaxljGpgAajBdB/XXPRMpD7BVw7fX/vPy94cX09rL/b/OBGFv8/EQJcgK/Dea+Xxf+UCSFcZUJ4IEhqZhvScQlUPh2EYHYG8UAs2hon9x3r6wuB2jlizaO3qNk6KZ2dUAwtADcbMyhhdx/iJ/RNbIpCXXVhtPOALg6TaSm9uCsOl2PvdxdrK9cRsRKflCWtob39H6DKedubC9UKG4v3hbAVkGKZp+HDbFSTKCuDraIFnevji5NYI8TitXbSGMaqDBaCGE9TbHQ6elijILcaJzdKJdS/PD/AXFqCC4lI8/ccZnbEA7bwkZUD3bO4Ac2POMJO7gbkrCMMwTQFdbK4/EwM9PeCzScE4v/2OWKscvSwR1If7/aoaFoAajr6BPvpOkxJCrhyNQ+Kd+/sT6+vrYfGU9qJfcEx6HuavPS/q4mkz1PVi7ekosT+6nbuqh6N2XUFyCopVPRyGYbQYWX4RFmyQXL+ze/iiWZkhrhyTKnFQEiOtS4xqYQGoBbi1sBWlYVAGHFoTjrJqxJ2NuRF+mNERpkb6og7Tpzu1u0j0vmtJiMvMF0WxR7SVkmV0nWBPG/g4mCO3sKTCOsowDKMMPtp2FQmyfHg7mOOVwS1FsiKtUQHdXMWaxageFoBaAhXSNDI1QFJklrAEVkegmzU+myQViV5xKKLCQqaN/H5CKjA6pbMXTI0MVD0ctUBPTw8TOkgtEjee062EIIZhmg4yMqwNjRau388ntcPt04libTI2NUD38kYGjOphAaglWNiYoOtoKSGEikPnZVUf5zemnbsowkm8uekSjt9KhbZxOyUHh2+kiMlnehdvVQ9HrRgfIsXdHLuVijgdLhDOaCa5hcX48r9w9Pt8PyYtP4YFGy/ilyO3cfhGsnA5MuqR9fv6hoti/9HuPmjraFnRsKDLaD+xVjHqAQtALaJtPw84eEgJIdV1CJFDWcEUF1dcWiaSQkgwaRN/llv/+rV00rnevw+CSgNRD07qCEdtmRhGU0o6bT4XiwFfHMS3+26KrjahkelYcypadJeY8fMp9P50P07dTlP1UHWehVsvIz4zX4SbvDYsAMc23RJrEiUr0hrFqA8sALUtIeThALF/9Vg84m9m1OgK/HxSsOiMQVdrj686jYxc7cgMzi8qEVlnxIzubP2rjolyN/DZGO4NzKg9F2MyMHH5Mbyw9ryIKfOyN8Piqe3wzbT2eG5ACwwLcoW7jamYy2b8fBJ7you/M03PjrB4cWFJ+R1fTmmPjKhsXCtP/Oj3cIBYoxj1gX8NLcOtuU1Fh5CDa8JRWlJa7fMoLm7FzI7wsDVDREoOnvr9jBBPms4/F+LEQuBpZ4a+LaXix0xVhrd1FclA1Bf4Qozu1IVkNA8KUSHxdzYqA+bGBnh1aAB2v9gX40M8Mba9B14eEoDvZ3TE3pf7YWB5qaun/jiD9aHRqh66zpGUlS9qzRJz+zVHe08bHFwdLu637ukGVz8bFY+QuRcWgFoIBdmaWBgiNTYHF/fXHOzvbGWKnx7tJHrFnrydhvl/nRPlUzSZP8rdv9O7eut067fasDI1wtAg1worIMOoIzeTsvHU76EoKilD/wAn7H+lH57p36LapC4zYwMhBMm6TSWuXv37In44WHMYDKNYyJPwxoYwpOcWobWbNeYPbImw/TFIi8sRa1E3TvxQS1gAaiFmlsaiTRxx6p/byE4vqPG5lBlMlkBjA33supwoEkM01S14ITpDWLTos0zpJLk5meqRZwNvvRCHwmLNFv2M9pGSXYDZq05Bll+Mjt52WP5IR7hYm9b6P0YG+vhicjCe7CMlwy369xqLwCZi7eloUXqL5t7FU9ujMKtIrD1Ej/EtxJrEqB8sALWU1j3dRZPtooISHP1barxdEz2aO2LJQ+1F3Aal7n+6UzLba6r1b2SwGxwsOdOsNnq1cISzlQkycovExM0w6gKFosz5LVS0caTi9StE/dK6lXKi+Ob/jQgUyQfEF/+F41rC/cXxGcURlZqLD7ZdEfvkog9wtcKR9TfE2kNrUGAPrsOqrrAA1FL09PXQ96EAUQrl5pkkRF6uvdzLsDZuWDShrdj//uAt/Hio+rZy6kp8Zp6wZhGPdGum6uGoPeQel5eEYTcwoy6UlpbhpXXncS4qAzZmRlg5u3ODLubm9m0uOt+Q+/iV9RdQpOGhLeoKfa/P/3UOOYUl6OJrj8d6+SLyUipunU0Sa49YgzgUR21hAajFODWzQnB/L7FPHUKKCmtP8pjauRleH9ZK7H+04yr+PClZ1DSBj3dcEwHgnbzt0KGZnaqHo1FuYOrXmaYj/aEZ9eabvTewIywBRgZ6onNRcyfLBr0OWQI/Ht9GiMhLsTJ2BSuJJXtv4Hx0BqxMDYXrt7S4VCQfEsEDvMQaxKgvLAC1nC5jfGFpZwJZSj5Cd9x54POf7uuHp8pjaCge8NdjD/4fVXMiIlVk/9IV58IxQWLyZx4MuWraeFgLKwlbARlVExaTie/23xT7iyYEo5ufQ6Nez9naFAvHtK4QluwKVvy8e/f3aisqSoRuv4Os1Hyx5nQZ7avqITIPgAWglmNsaojeU1uK/fP/RSE1LrvW55N4emN4qwoR+O7Wy2rtDqasZSo8Skzv2gxtPLjUQH14qIvkLl959I7GZ4AzmgslIr369wWRwTuyrRsmdVRMEte49h7sClYCmblFeHHteVFQnhLuRgW7IzU2G+d3S+1Fac2htYdRb1gA6gB+7Z3gE+wo4muoLlNZaVmdRCAVWZW7g5eWX+mpY+LHtYQs2Job4eXBUuA3U3eobIaDhTFiM/KwPUwq2MowTQ1Zkug8trcwxntjgxT2uuwKVjxUJWLBpoui24evowXeHR0k1hRaW2iN8W3nKNYcRv1hAagj9JnWEoYmBoi/mYmrx+PrNHFSkdWXBkvWw893heOr/8LVqkQMlYr4cvd1sf/KkADYWXCpgfpC2ZWP9vAR+ysORajV78voBpfjMrGs/ALzvTFBcFRwBv+9ruCI5Nq9IEztrAuNrojTXDItBBYmhlLnqVuZYo2Re5wY9YcFoI5gZW+KruUxGcc23ESurG5B/88P9K9IDFmy7yZeXn8BBcXq0THk853hyMovRpC7dYUrk6k/M7p5w8zIAJfjZDh2q/ZscYZRJOSSfXX9RdGXnFq6jQpWTskQcgX3C3ASruBPd15TynvoAuEJWSIsSH7R3dbTRqwlxzZKAp7WGFprGM2ABaAOEdzfE45elqIx94NqA1aG2vp8OK6NKB2y8WwsZvx0SuVZo5R5tu6M1O7p/bFB3PWjEZDlVF44+wc1jvdktI/lB27hSrxMhHB8MK6N0hK46HXfHBEoap1SwfvTd9KU8j7aTE5BMeb9SS1DS9Hb3xFzektx4lTzj9YUWltojWE0BxaAOgQ14u43vZXIlr1+KhFRD6gNWJlHunlj5azOsDIxxKk7aRi/7Kho1aSqmn/z/jgjApAndPBAR297lYxDm3iit59YHA9dT8bVeM6WZJTPjcQsfLtPuhBdODoITlbKLd7u72KFqZ2lslgf77jK4Q71gL6rtzZfEv3DXa1N8fXU9tDX1xM1/26cThRrSv9HWok1htEc+NfSMVx8rCtqAx5YHS6qtdeVPi2dsHFeD3jZmyEyNVeIwL1XE9GUZOQWYubPpxCXmQ8/Rwu8PVKK7WEah5e9OYa3ldxv6pz1zWiXoCCX7MBWzhjb3r1J3vfFQS1hbmwgCk1THBtT91Zvm87FCk/Ltw+HiOLchfnFIvFDXvPP2dta1cNk6gkLQB2tDUhxGlSv6eQ/EfW+it48r6foz0nxd4//Gor/bQoT7gFlk1dYgid+DcWNpGy4WJvgt8e7cOKHApGX/qGOKnEZeaoeDqPFUCjJydtpMDXSb9LanZQQInddfrbrGvfBrgNX4mR4p1LcX2cfyeNCvX6z0vLFWsI1/zQTFoA6CNVn6vuwVDLl4t5oJEXWz+VHV3+r53TFE72kk371ySiMXHIYZ6PSoSyoRt1za84iNDId1qaG+O2xrvC0M1fa++kiwZ626OZnLwLyVx6VGrkzjDJqyJELVp5kRtbnpuTJPn7C3UxeDHn/cKZ6svKL8Mzqs0Io9w9wqrhITLwjw8V9Ugx23+kBXPNPQ2EBqKN4t3GAf2cXEUe3/49rKKlngVQTQwO8Nao1Vj/RFe42priTmovJ3x/HF7vCFW4NpMnnjY1h2HM1CSaG+vjp0c6iiwWjeJ7q07xC1Cdl5at6OIwWQpa31JxC+Dtb4olekqBoSqhsCbmCiSX7biAzr6jJx6AJUE0/Kp59OyVHzPFfTZHi/mitoDWD1g5aQ7yDGtexhVEdLAB1mF6T/WFiboiU6Gxc2CNdzdWXHi0c8e8LfTCuvbuo4k8FXft8th8/H7mN/KLGl4s5E5mGUd8ext9nYkSSwrcPhYim44xyoFIZwZ42orn7l7ukGosMo8js/dWnpG4RlPVrbKiaJYiy3ls4WyIjtwjLDqhnkXtVs/zgLZExbWygj6XTO1SE29BakRqTDRMLQ7GGMJoLC0AdxtzaGD0nSd0+Tm27jYzE3Aa9DlXZ/3paCJZP7wAfB3Nxdf/Btivo/8UBYUlqSN1AWX4R3tochknfH8f1xGzRIWDZ9A4YEuTaoDEydYNisd4ZJSXWUJmdS7GZqh4SoyXQBeKbm8Kk7P0Qj0b3+m0Mhgb6WDC8VUUbRI55rcr+8CR88V94RZmtkGZ2Yp/WCForiJ4T/cUawmguLAB1nFbd3eDZyg4lReVm/Qe0iasNyiLd/VJffDKhLdxsTEWrIEoQ6fjBHhFHsuV8rBB2tRWFPROZLtrODfryIP44ESUWi8kdPbH3pb4Y1kY5RWKZqnTyscfodu7iu39/2xUul8EohN+P3xHFximG938jA1U9HAxo5Sy8CRRisri8oxAD3EnJwfw158T5/3DXZphWXmSf1gYRLlRUKtaMVt35YlzT0Svj2b3ByGQy2NjYIDMzE9bWmpsCL0vJw5r3T6K4sFQkh7Tp49Ho1yT3L1n/qL1YguxuLBm1D2rrYSMselamRrAyNRRdKKgYLIm/3MK71kLqM/nR+Dbo0dyx0eNh6gf1Bh745QFR9JUsryPKS8QwTENIyMzHoK8OIrugWBSVp7qi6sC5qHSMX3ZMhJf8O7+PzscWU/w2lfcirwtVelgzp1uFm/7SwRgcXHNdtHt76O0usHY0gyYj05L1uzFw6g4jTuRuY5uLiu7U0ocSRBrbzod6zD7WyxezevjgYmwm/rucgP+uJIri0WejMmr8PztzI3T1dUBPf0dh+aPXYZoeD1szPNmnOZbsvSEyNslawr8F01De3XpJiL+QZrZ4WI3aNpJrc3gbV/x7KQGf77omEsx0Oenj1b8vCPHnbGUiQnrk4o/KvRzbeEvsdxvrp/Hij5FgAcgI2vb3xM0ziUiIkOHAn+EY9WywQmpzUdZYey9bsb02rJVoxE7WPqohSCUG6JYWhmb25uje3AEtna3E/zCq5+m+flh3Ohox6XkiqeeZ/lK8KMPUB7r4o2QCQ309LJrQVu3O71eGBoiLU6oycOp2ms4mmS3ec10UxyYvzfJHOoiaiQQ5CWlNoKYBrn42CO7H7d60BY4BZAQ0KfefEQh9Qz3RIo5axSkDPydLjAp2x0NdmgkL08tDAvDu6CDM7umLVq7Warc4NJSy0lKk/fYboh57HAW3pCtnTcPc2BBvlAfKU1xmYiVXPsPUBbrIe2fL5Yr6e3SOqxvNnSwrWsR98q9utojbcCYG3+6TsqE/Ht+2SnvN6ycTxJpgYKiPATNbQU9L5miGBSBTCXs3C3QeKRV3PrzuOnJlhaoekkZSFBeHqNmPIfHjRcg5dgyJH30MTYVadJHbjmIz39x0SScXR6bhfPnfdRED7O1gLoo+qysvDPQXscgUnkLWSl3iZEQq3th4Uew/0785JneSxDBBa8Dh9VK/5s6jfGDnaqGycTKKhwUgU4WQIc3g6GWJgpxiHPpLKgPA1A0SR5lbtiBizFjknjwJPTMzwNBQiMDcs2ehiVAYAAXtUy2wPVcT8dtx7pzA1L3m36/H74j9j8a1VesYUnJ3PtHbt6JQNXUe0gWoyPNTf5wRPZlHtnXDy4OlDlHy+ezgmnCxFtCa0H6w+sRuMoqBBSBTBQMDMvMHClfsrbPJuBGqW1fDjXH5xr36GuJefwOl2dkwa9cOfps2wnb8OPH3lO+WQlMJcrfBghGSK/ij7VdxOY5rAzK1QyWdFmy8W/Ovl7/6Z/KTi5qqE0Qk5+DPk1Kxam0mI7cQj606LYphU4z2l1PaVQnBuXkmCRHnksVjtCbQ2sBoF/yLMvfh5GWFDsOlMg2H/mJXcF3IOXIEsm3bhMXPaf7z8P7zDxj7+MDhqac03gpIUDb3oEBnFIqezOcU3u6P0S6W7b+Fq/EykdX/phrU/KsLVJbqpcFSizgqgpySXQBtJbewGI//GiosgJTx/+PMTlUstDTnH1oj1UbsONxbrAmM9qE1AvDQoUMYPXo03N3dhdtq8+bNtT7/wIED4nn3bgkJCU02ZnWm03AfOHhYIj+7iF3BdUD233/i1m7KZDjOnQs9QynB3tjTUyusgHRufD6pHVytTYWF5N2tUmA/w1Tn+qUeuwQleDlYmkBToOS0Nh7WojrBJ/9egzZCha/n/nFW1F2loty/zOoMJyuT+1y/+TlFcPC0RMfhPiodL6M8tEYA5uTkoF27dli6tH6LbHh4OOLj4ys2Z2dnpY1Rk6CMr4GPsiu4LpQVFyN7z16xbzVkyH1/1xYrIPUC/Xpae1E0l3ozbz4Xq+ohMWpoWXpx7XnR9m1UsJtIItIkDPT18P7YNmKfjnESSdpW6++V9Rdw8HoyTI30sXJ25/uKX1d2/dIaQGsBo51ozS87fPhwfPjhhxg/fny9/o8En6ura8Wmr681X0mjcWrGruC6kBsaipKMDBjY2sK8U6f7/q4tVkCC+rfKszmpzR9ZexhGDhUNJ7ciWYop8UMRtUSbmg7N7DClk1Tr7p0tl4SY1QbIsvfeP5ex9UKcqMm4/JGOVcq9EOz61S10Xu20b98ebm5uGDx4MI4eParq4ai3K3hNOJcBqYascvev5aCBFa5fbbUCEs8N8EevFo6iNMyjv5wSsV4Ms/9akujfTVBCgY25ETSV14e1Eu5R6l28+qR2ZL4v2XsTvx6PBGly+n36B1T1drHrV/fQWQFIou/777/Hhg0bxObl5YV+/frhbC2Lc0FBgegfWHnTKVfwOXYFV5f9m7V7j9i3rsb9q41WQHKT/TCjIzo0s0VmXhFm/HxSdHhhdJfU7AK8+rdUS+6xnr7o2UL9s35rg+IWXx0qlUT5fFe4+HyaDBVyp04fxMLRQRjb/v5+7zdOJ7LrV8fQ2V84ICAATz31FDp27IgePXrgl19+EbeLFy+u8X8WLVokmkfLNxKNuuIK7jhCuhok90BOhmZPhook7/x5FCcnQ9/SEhbdutX6XGEF1NMTVsCipCRoMhYmhlg5uwtau1kjJbsQ0386iei0XFUPi1FRXNnrG8JE1qy/syVeG3a3lpwm83BXbwS5W0OWX4yPd2huQsg3e24IEUuQqH20x/2Wvez0AhHmQ3Qa6cOuXx1BZwVgdXTp0gU3b0rtcKpjwYIFyMzMrNiio6OhK4h4kGZWKMgtxr7fdbNdUnVk7Sp3//bvDz1j41qfS1ZAk0Cpnl7uqdPQdGzMjPD7413Q3MkC8Zn5eOTnk9wuTgf5Zu8NUSScioUvntperQs+NyQhhFymG87GYPvFeGgSNEd/9V94heWPhHl1/bzpefv/uCrmdmdvK3QYJsV9M9oPC8BKnD9/XriGa8LExATW1tZVNl2BioAOmtVauAWiLqfhypE46Do0cWbt3i32rYYMrtP/WHSVrIQ5J45DGyBX2Z9PdIOXvRkiU3MxbulRXODEEJ3h37B4IQCJD8e3QRsPG2gTHb3tMLdvc7FP7dI0xcpNcxPVMlxS3t/3fyNaYV6/+8UfcflwnJjTRbgPzfFc8Fln0JpfOjs7Wwg42ojbt2+L/aioqArr3cyZMyue//XXX2PLli3C4nfp0iW88MIL2LdvH5555hmVfQZ1x97dAl3H+on9I3/fRGZyHnSZ/EuXRd9favlm2atXnf7HoltXcZt74iS0BVcbU6x+ohv8yi2Bk384jnWndcc6rqtciZPhpXUXKuL+plTqIatNvDi4peiHTbUBn//rnOhyou4u+Q+2XcXS/bfE/bdGBuLJPpKIvReaw49ukERit3F+oh88oztojQAMDQ1FSEiI2IiXXnpJ7L/zzjviPtX4k4tBorCwEC+//DLatm2Lvn374sKFC9izZw8GDhyoss+gCbQb6AW3FjYoLijBvt+uokxLSiQ0Kvu3Tx/oU9/fOmDWsROZU1EUE4PCmBhoC1725tjyTE8Mbu0iCs2+tuEi3tocJvYZ7YOSIub8Foq8ohL09ncUFiZtxchAH0umhcDK1BDnojKweLfkUlVH8otKMO/Ps/jl6G1x/93RrfFEb+mivTqhuPfXK2Iud/e3RbsB2ingmZrRK+NgrgZDWcCUDELxgLrkDqarxr8+PCUmjh4TWyBEB5uE02kTMWw4CiMj4f7lF7AZObLO/3tn2kMiecTtow9hO3EitAlaVL4rzzikmYUyhT+dGAx/Fw4q1xZI1FO856nbafBxIOHfS6NLvtQVigF8ZvVZERP4+2Nd1a6/MYnyJ34LFSKV4jE/nxxcbbavnHO7o3Bsw00YmRhg2ttdYO1Yt4tYbUGmo+u3VloAmabDxskMvSZJ8SQnttxCaqzulQApuH5DiD9K/LDs269e/2te7gbO0SI3sBwqIUGFon9+tJOwmJyNysCwbw7j/X+uQJZfpOrhMY2E3J8vrD0nxJ+liSF+erSTTog/YmSwm2gVRxc2L647jyQ1SniiMkwTlh8T4k+enFWb+EuJyRZzN9FzUgudE3+MBAtApkG07uUOn7YOKC0uw+5fLqOkqFQn3b8WPXvCwLJ+cTPycjG5J05obTb1gFYu2PF8bwxp7SI6KZBLasAXB7AuNFpYCRnNg8Tf82vOYUdYgrAwffdwCFo465Zl951RrdHSxRLJWQWi9BGVvlGHAtwk/igJy9PODBvm9kBXP4can19cVII9Ky+Ludsn2FHM5YxuwgKQaRDU4qn/jECYWRkhNTYHJ7ZGQJfIPnRI3FoNGlTv/zVr315YDql+YOFtKVZHG6G4wBUzO+G3x7qIBBGqF/ja3xcx5OtD+P34HWQXFKt6iEw9xd+/lyTxR4XA+93TSUIXMDM2wI8zO4lWdzeSsjH9x5NIyylUmSv+o+1XMHvVaWTkFqGdly02zeuJFs6Wtf7fyS0RYs6mubv/I600sl0foxhYADINxtzaWIhA4vyeKMSEa1fj9JoozctD/tWrYt+8q+TOrQ/6pqYwK09WyjlxAtpOn5ZO2Dm/D94cEQgrE0PcTMrG21suo/vHe7Fw62Xc4i4iai/+nltdVfz1b6V74k+Ot4MF1jzZDc5WJghPzMLDP55AehOLQCpHQ9n2Px6WLiBn9fDBuqe6wcnKpNb/i7mWhvN7pAz9ATMCxRzO6C4sAJlG4St3IZQBe1ddQUGu9sd55V0MA4qLYejsDCOPhrlPLLrL3cDaFwdYHcaG+pjTxw/HFgzAe2OChEUwq6AYq47dwcAvD2LI4oP45N9rOH0nDcVqXmZDlyAr7dw/zmLn5QTxG/4wU7fFnxxfR0kEkuC6lpAl3MEZucoXgRQysulcDEYsOSzqbVK8HwnyhWOCYGJYewFu6vG791fpwrV1b3fh/mV0m+o71zNMPaAg4tjwdJEdfHDNdQx5PAjaTN45qV+0WYcODXafyC2HuSdPin7Cevq6cS1mZWokWlHN6OaNo7dS8OuxO9gfnozridli+/7gLdiaG6Grrz2CPW3R1sNGbHYWbKloam4kZuHpP87gVnKOEH8rdNTtWxPNnSyxZk5XTFtxAlfiZZjyw3F8NaW90ophX4rNFBbz0Mj0iiLVSx4KgYdt3RI4qNUbtXyjJL6eE6svCs3oFiwAmUZjbGqIQbNbY+MXZ0VDce82Dgjo6gptJfesJADNO0hu3IZg1qYN9M3NUZKZiYLwcJgGSq50XYGyhXv7O4mNLCcHryeLYHYSgxTPtOtyotjk0CJHVpdmDubwtjeHt4M5PGzNhQXGwdJY1GpjFMc/F+Lw+oaLyC0sEfFuS6d3EIKDqQolwaye0w0P/3hSXMCMXXoU8/o1x7MDWjzQIlef8i5f/Hcdf52OEhnIZkYG4vWf7ONX5+M+/GSCmJv19PUw6LHWYs5mGD4KGIXg6meDziN9cOqf2zi4JlzcpytNbYOsdXnnpe4HZiEdGvw6ekZGMOvcCTkHD4lyMLomACtja24sSlbQRu7f89EZopxFWGym2G6n5CA2I09sqKFVt72FMZwsTYT1UGxmxuLW2sxIuMno1trUUNza0mZuLO4bsnC8L7Fg0b9XsfLoHXG/R3MHYWVytKw9tkyXaelihZ0v9Ma7Wy5je1g8vt13E/9dThR1+MiK3VAoVnb1ySisPxMtupAQY9u7443hreBmU/e5VfLMhIt9mqNdfbWrXR/TcFgAMgqj4zBvRF9JQ/ytTFEaZsIrHaCvZQtswc2bKJXJRPs301YBjXot6gtMApDKwTjMnqWwMWoyJMg6+diLTU5mXhGuxcsQmZaLqNRcRKXliv2EzDyRWUxlZigTsyHZmFSr0M7cWAhIR0vp1t7CRAT4U4s7F2va6L6pcINqKxRbtu9aEj7afhURKTniMbJkvTwkAAb6nCX6IEggk5V0ZFg83t58SSSHUF9sSoAaFeyOIUEusDY1qlMnj91XEvHnyUiciEireLy1mzXeGxuEzpXOi7pQUlIq5uKi/BLRwanjcJ8GfT5GO2EByCgMEnvkXlj74Wkk3pbh9PY76Dqm+jZEmkreOanXtFlwsLDiNYaKvsCnT6OsqKjRr6etkAWP6ppVV9uMagqm5xYiObsAKVmFyMgrFC5kciun5xZBllckBCQVoc7MK664Ly9BQ5YV2khU1gaFepIrlOqsedmZi9tmDhbwdTSHr6Ml7MyNNLacBsX6vb/tCg7fSBH3SQh/PL4thgRpbxiHshjR1g3d/Bzw7tbLwo1+IDxZbMYb9YUY7OZnL4SghYkhLE0NYWSgJyx9FN93KVaG64lZKC6vk0m6m+ppTu/WDH38nRokxEO33xFzsbGZFKZDoRcMI4cFIKNQrB3M0O/hAPz382Wc+fcOvALtRZ9JbSGvPP7PrBHxf3JMWrWCvo0NSjMzkX/5sqgPyNQPWtAcLCkO0ARwrV9pExKDGXlFooRHarkFkeKtyKpIhX4TZPlIyMxHUlY+ikrKEJ+ZL7bTd+4vd0TuZF8nSzR3soC/s5WoxUZbM3tztbWgXUuQ4bfjkVh7OlpYUanEy+xePni2fwuRrMM0DLIif/tQCOYP9Bft47ZdjBM1A/dcTRTbg6ALjSmdvTCtsxfc65jgUR1xN9LFHEz0mx4g5maGqQwLQEbh+Hd2QdSVVFw7niDcD1Pf6gJTC+1YUHLPnRO35h0aHv8nhzJ/Lbp0Qdbu3SIOkAVg00HB8xXC0an255KVkQRiTHouYtLzxBadnovI1BzcTs5BXGY+ZPnFoiwHbZUhtzFli1L3CIoVo83f2VIUyVaFMMwtLMa2C/FYczpKxFnKoY4tb44MFDXuGMVAFwDzB/mLLTwhS8QHUjxrTkExsvOLhRU6v7gEPg4WaONujSAPG5FB7G5j2mhrMpV82f3LFZE00qqHG/w7uSjsczHaAwtARin0ntoScTczIUvOw4E/r2HonDYa6yKTU5ySgqKoKOEPVJRYM+/cWQjA3PLSMox6Whkp25i2kGb3Z8LmFZYgMk0Sg+TOu5mcjRuJ2YhIyUZ+USmuxsvEVhmTcmHo70JWQ0v4OFrAz9FC3FKPXUVBlj2y9FHv3pMRaThyM6XC/W1IGaGBLpjV00e4LRnlEeBqJbamiuekOVde8qX3FP8meV9G82AByCgFKjNA9QA3fnYGt84m4/LhOLTpU3Nzck0q/2Li7w8DK8VM5mYhkpDMP39BTNyaLpJ1EWoP1srVWmz3Wg7JWkgJARTbRbF24SQMk7NRUFwqasfRVl1CgYedGdysTeFmawo3G1MhPq1MjETSCsWO0T5RVFqK4pIy4dImy1JcZh7iMvLLLZW5wiJJ1snK+DiYY2rnZpjU0fOBnSMYzYPmWppz9Q30MPjxIC75wtQIHxmM0nDxsUa38c1xbMNNHFl/A27NbeDgUXufSnUm7+w5hcX/yTENCICeiYmoB1h45w5MfH0V9tqM6i2HVLeQtsGtXapY5UickZXwelIWIpJzcCclB3dSc0T8YYqIQyyAVGyo8VgYG4is6i6+9sLSF+Jly8kAWkpKTDaOrLsh9ruPby7mYIapCRaAjFJpP9ALMdfSEXU5Fbt+vITJCzrDyEQxBVKbGrmbVhHxf3L0jI1hGhQkkkvyLlxgAagDUOwfxdrRNqiSMCQoWzkyJVdY8hLKk07k5W6odV5WflFF/JjcjUvxjPSaZIl0tzET1kNKHvCwNUWgm7UoIcL1DrWfooIS/PfTJZQUl4pi/O0GeKl6SIyawwKQUSqi8vysQPz14SmkJ+Ti8Lrrogm5plGan4/8K1crWsApErN27SQBeP48bMeNU+hrM5oFlQhp62kjNoapD4fXXhdzrIWNMQY+GijmXoapDb4sZJSOmZUxBj8WBOgBV4/G4/rpBGga+WFhQFERDJ2cYOSh2FhGeUJJ3oWLCn1dhmF0g+unEnD1WLyoV0lzLc25DPMgWAAyTYJngB06jZCq0B/4IxwZibUX3lU3civi/zooPFHDrH07cUs9gUtzpC4MDMMwdYHm0gN/Sq3eaI71COCezUzdYAHINBmdR/iIotAUq7Lrp0soLiyBphWANldgAogcIxcXGLq5Udoo8i5dVvjrMwyjndAcuvPHS2JOpblVfpHNMHWBBSDTpK3iqDSMmZURUqKzcXi9lK2m7pSVliL3/HmlxP9VjgMkKA6QYRimLhxedwOpMdliTqW5Vdt6rzPKhY8WpkmxsDXB4NlSPOCVw3EIP6n+8YCFERGiXZueqSlMW7VSynvI3cAsABmGqQs0d145EifmUor7o7mVYeoDC0CmyfFqbS/cwcSB1eFIi8/RiPZvZm3bQs/ISLkWwAtSQWiGYZiaSIvLEd0+iM4jfUXPdYapLywAGZXQaaQvPFvZoZjiActjWNQVuVVOmb16qRYgicuStDQURUcr7X0YhtFsaK6kuL/iwlIxh3LcH9NQWAAyKoE6EZDbwtzaWFzNHlwdrraWr7zzF6q0bVMG+sbGMGkdWGEFZBiGuReaI2muTI/PgbmNVF6Lu7owDYUFIKMySPwNeSJI1K6ieBbqYaluiBZtt25VcdMqC3N5PcBzHAfIMMz9XD4UK+ZKKvJMSR80hzJMQ+FOIIxK8Whph27jmuP4pluiS4iTlxVcfNWnf2XeRak4s5F3Mxg6OCj0tQtKCvD39b9xIPoAWtq1xFAfW1CEIVsAGeZ+SstKcTH5InZH7sb19Ovo79UfE1tOhImBbiQ/JNzOFFm/RLdxfmLuZJjGwAKQUTkhQ5oh8bYMEeeTsXNFGKa82RlmlupxZSu3xsmtc4qgsKQQG25swE9hPyEpN0k8diL+BLZnlmE5JZ1cu4LLMWcR5KmckjMMo0lcTrmMLbe2YG/kXiTlSeeL/Jz5+dLPmNN2Dib4T4CxgXrMGcogL6sQu1ZcQmlJGfxCnBAyuJmqh8RoAewCZlQOddYY8GggbJzNkJ1egP9+uozS0jKtTAD559Y/GLFxBD4++bEQfy7mLpjfYT5G+o1EvoMF0iwB/ZIyvL/qUWyP2K6Q92QYTWVbxDY8vONhrLm2Rog/CyMLca7QOUPnDp1DH538CCM3jRTnljZCc+F/P18Wc6OtizkGzgxUeDciRjdhCyCjFpiYGWL4U23x96ehiLmWjlP/RKDb2OYqLwAtdwErQgDuidyD/x35n9h3Nne+z3JBlsEr+2cBR86hRWypeG4ZyjDKb1Sj35thNA0SdG8dfUu4fvt59cPklpPRza1bxfkys/VMbLyxET9e/BEJOQnifDE3NMdA74HQJk5tjRBzoqGxPoY91QbGZrxsM4qBLYCM2uDgYYn+j0iFls/8G4nbF5JVOp6CmzdRmp0NPXNzmPj7N+q1YrJi8M7Rd8T+1ICp2DFhB6a1mlbFbUX7Xt0Hif1+mW5i4XvzyJtaa9lgmLqIv0ktJ+Gb/t+gj2ef+84XOod2TNwhzini7WNvIzY7FtoChcWc2Rkp9vvPaAUHd0tVD4nRIlgAMmpFyy6uaNvfU+zvXnkF6Qk5qnf/UgFow4ZfdReVFOHVg68iqygL7Zza4fUur9cYuC7vCOIdVYBJ/hPFAkgLIYtARlegY50ufOjYJ6vf293ehr5ezUsVnUt0TgU7BSOrMEuca3TOaTo09+1ZdUXsB/f3RMvOrqoeEqNlsABk1I6ek1qIxuZF+SXYsTwMBXnFqq3/10j37+Kzi3Ep9RKsja3xeZ/PYaRvVGtBaBgaoiQlBW80e1wsgHJL4M7bOxs1DoZRd+gYp2OdQh+mtJyCt7q9Vav4k0PnFJ1bdI6FpYTh67NfQ5OhOY/mPpoDaS7sMamFqofEaCEsABm1w8BAH0PntIGlnQkyEnOxZ+UVlKkgKeRuAkjD6//ti9qH36/8LvY/6vUR3Czdan2+PvUbbt1a7OefOy8WQBKBtCC+e+xd4UpmGG0kOitaHON0rNMx/2a3N+sk/uS4W7rjw54fiv3frvyG/VH7oYnQXEdzHs19NAfSXEhzIsMoGj6qGLWECpwOe6otDAz1cediCk7vuNOk71+SkYHCiIhGWQDjsuOE+1YesE6B7HXBvINU/iX3zBmxAL7Z9U10cO6A3OJcEeheUqq+bfMYpiHQMU2WPzrG6VinY74+4k9O/2b9MaP1DLFP5x6dg5rG6e23xZxHc9/wp9tysWdGabAAZNQWFx9r9H04QOyf3na7SZNC5Nm/xt7eMLRrWMHVT059ImKS2jq2xQsdXqjz/5l1lARg3pmz4tZA30BYD6kExrmkc1h5eWWDxsMw6sovl34RxzYd4x/3/lgc8w3lxQ4vinNOVigT56CmJX2c3i5d7NLc5+ytPkXxGe2DBSCj1gT2cEPbvh4VSSGpcdkaUf/vaupV7I/eL6wYH/b6EEYGNcf91WQBpCxkakVHeFp54o0ub4j9peeWitdnGG3gSuoVLDu/TOwv6LIAHpbS+d5Q6Fyjc04PeuIcvJZ2DZoAzW3k+iXa9vMUcx/DKBMWgIza03OK/92kkGUXkZ9d1HQCMKRhAvD7C9+L2+G+w+Fn41ev/6WWc2R5RFlZxTiIsc3HYlCzQSguK8Ybh99AfnF+g8bGMOoCHcMLDi8Qx/Rg78EY03yMQl6Xzjk69yqfi+oMzWk0txUVSEkfPSdz0gejfFgAMmoPBUBTAVQrB1PIUvKx88cwlJSUKu39ykpKkHeh4QWgyeKwL3qfsEA8Gfxkg8Zg1rGjuM0tdwMTVP3/ne7vwNHMERGZERqf6cgwi88sFseyk5kT3un2jkI7XDwV/JQ4B/dG7UV4WjjUFZrLaE6juc3a0VTMdZz0wTQFWnOUHTp0CKNHj4a7u7uYRDZv3vzA/zlw4AA6dOgAExMTtGjRAqtWrWqSsTL1h3oDj5wXDCMTA8SGZ+BoeVN0ZVBw8xZKc3Kg38AC0HKLwzDfYfW2/skxL48DzD17psrjdqZ2eL/H+2L/z6t/IjQhtEGvzzCqho7d1ddWi/33e74PW1Nbhb6+n60fhvkMU3sr4JF1N8ScRnPbiLnBatMHndF+tEYA5uTkoF27dli6dGmdnn/79m2MHDkS/fv3x/nz5/HCCy/giSeewK5du5Q+VqbhnUIGzW4N6AFhB2Nx6ZByKv7L3a6mwcHQM6hfMDpZGsjiQJaHp4OfbvAYzMrjAPPDLqG0sLDK33p79sZE/4lin/qgFpVqftFbRregY/bDE1LJFur00cujl1Le56l2khVwT9QetbQC0hx26WCsmNMGP9ZazHEM01RojQAcPnw4PvzwQ4wfP75Oz//+++/h6+uLL7/8EoGBgXj22WcxadIkLF68WOljZRqOX3sndB0jWdUO/3UdseHpCn+PvHPnGlz/r8L65zNMWCAairGPDwzs7VFWUID8y5fv+/uLHV+EnYkdbmbcxJ9X/mzw+zCMKvjjyh+4lXkL9qb29cqQry/NbZtjqM9Qsf/DxR+gTsSEp4s5jOg21g++7ZxUPSRGx9AaAVhfjh8/jkGDpL6rcoYOHSoeZ9SbjsO84d/ZBaWlZfj3hzBRMFU5ArB+8X9kYSBLA1kcyPLQGCiMwaxDiDSes3fjAOXYmNgIEUgsu7AMCTkJjXo/hmkq6FhdfmG52KdjmI5lZSKPBdwduRvX0yXBpWpoztr5Q5iYw2gu6zDUW9VDYnQQnRWACQkJcHFxqfIY3ZfJZMjLy6v2fwoKCsTfK29M00PiaMCMVnDxtUZBbjG2Lb2A/BzFuEGLEpNQGBlJb1JRjqWuyC0MZHEgy0NjMe9wfyJIZca2GIsQ5xDkFefhs9OfNfr9GKYp+PTUp+KYpYLPisr6rY0Wdi0wxGeI2sQCUsbvtu8uiLmL5rABM1spNPmFYeqKzgrAhrBo0SLY2NhUbF5eXqoeks5iaCwFTFvZmyIzKQ//fh+GkuLGZwbnnj4tbk0DA2FgXfcirJTJSBYGYf0Lbpz1T455JQtgWdn9rfDkXUIM9AzEex+OOayQ92UYZXEo5pCwktMxW99Wb41Bfk7SeULnqqqgOYq8FpnJeWLuojnM0KjhRa8ZpjHorAB0dXVFYmJilcfovrW1NczMzKr9nwULFiAzM7Nii46ObqLRMtVBLZJGPhMMI1MDxN3IwIHV4dUKpfqQe+qU9NpdutTr/9ZeWytuqd0bWRwUAfUE1jMxkdrS3b5d7XMC7AMwPXC62F90ahEKSgoU8t4Mo4yaf4tOLhL7jwQ+gpZ2LZvsvf3t/CtaMa4LXwdVQHPTgT+vibmK5iyau7jNG6NKdFYAdu/eHXv37q3y2O7du8XjNUHlYkggVt4Y1UJZc9QsnTwo147F4+yuyCYXgLlFudh6a6vYn9ZqGhSFnrExzIKDpfc4U7UcTGXmtZ8HZzNnRGdF4+ewnxX2/gyj6HZvMdkxcDZ3xtz2c5v8/R8KeEjcbrm5RZyzTQ3NTdeOJ4i5iuYszvhlVI3WCMDs7GxRzoU2eZkX2o+Kiqqw3s2cObPi+U8//TQiIiLw2muv4dq1a1i2bBnWrVuHF1+UAusZzcE7yAG9pkjWhBObI3AjtKplt17xf3fuSPF/naT4u7qwLWIbsouy4WPtg25u3aBIKvoCn5USU6qD+qe+1uU1sU8CkIQgw6gT0bK7FyevdX5NHLNNTTf3bvC29hbn6vbb25v0vW+cThRzE9F7aksxZzGMqtEaARgaGoqQkBCxES+99JLYf+edd8T9+Pj4CjFIUAmY7du3C6sf1Q+kcjA//fSTyARmNI/g/p5iI/asuiLcLE0R/0dunb/C/xL7UwKmKDymSZ6Icm9B6HsZ4j0EXd26orC0EJ+d4oQQRr349PSn4tikCyQ6VlUBnZtTWk4R+39d+6vR4SJ1Je5GOvb8KvX4DR7gKfr8Mow6oDUCsF+/fuKEvneTd/egW+r8ce//nDt3TmT33rp1C7NmzVLR6BlF0HOyP3zbOaK0uAw7ll9EekKO0t2/55LO4Ub6DZgamColo1GUotHTQ1FkFIqTk2t8HmUR/q/L/2CoZ4gDMQdEsD3DqAMHow/iYMxBcWwu6LpApRmvlDlP5yqVgzmffLfPtrJIi8/BjuVhYk6iGqY9J9W/sxDDKAutEYAMo6+vh8GPB1WUh/nn2wvIlVXtoqFoAUiWBGKk30il1DMjS6RJS8m9nVuLG5igwtOPtH5E7H9y6hNOCGFUDh2DdCwSM1rPaHBrREVB5+gIvxFif821NUp9r5zMgirlXgY91lrMUQyjLrAAZLQKI2MD0TPY2skMWan52L70AooKSpQS/5eSl4LdUbvF/tSAqVAW8r7AeQ9wAxNPt3u6IiHk18u/Km1MDFMXVl1aJSV+mDk3uji6opCfq1QShs5hZUBzzvalF8UcRHOR6GNuzOVeGPWCBSCjdZhZGWP0s+1gamGEpMgs7PrxEkpKSutk/atP/N+G6xtQXFqMdk7tEOgQCGVh1lESpDknTj7wuRRc/3Knl8X+jxd/RFx2nNLGxTC1QcfeT2E/if1XOr+iksSP6mjt0BrBTsHi3N14Y6PCX5/mGppzkqOyxBxEcxHNSQyjbrAAZLQSWxdzjJgXDAMjfUReSsWB36/VGvRdX/cvLR7rr69XuvWPsOjRQ1gmC8LDa40DlDPcdzg6uXRCfkk+vgj9QqljY5ia+Pz05+IYpGORemOrE9MCpHJNdA7TuazQWn+/XxNzjqGRvqj1R3MRw6gjLAAZrcWtuY1UI1BfD9dOJFSUYVCEAKTA9sTcRNiZ2FU0m1cWhnZ2oig0kVOHXtUiIaTr/yo6hByNParU8THMvRyJPVLR8YOORXVrdUat4ejcpb7ElKCiKE5sviXmGppzhsxpA1c/5fY5ZpjGwAKQ0Wp8gx3Rb3pARSHWC/vur5FXlJgo9f/V169z/N/acKnzxwT/CTA2UL57x6JnT3Gbc/RonTsfPBz4sNj/4MQHovcqwzQFdKx9eOJDsU/HIB2L6oaJgQnG+4+v0sWnsVzYG42zu6RSY/0fCRBzD8OoMywAGa2ndU93dB0jZR8eWX/jvkLRuafqV/+PEiyOxx8XfX8ntZyEpkAuALOPHqtz/bJn2j8DF3MXxGbHYsXFFUoeIcNI/HDhB3HMuVq44tn2z0JdmdxysrilczkmK6bRhZ5pbiG6jvVDYA93hYyRYZQJC0BGJ+g43Btt+3oAZcCelVcQdTm1we5feeB4D/ce8LRqmqKuZiHtoWdujpKUFBRcv16n/6Gge3K/ybMxb6bfVPIoGV2HamLKs8+pLqW5kfrGv9G5S+cw0ZhkEJpLqPg8QUWeOw7zVtgYGUaZsABkdAKKQeo1tSVadHRGaUkZ/v0hDPG3Mu8RgJ0f+DpFpUXYdGOT2J/YciKaCn1jY5h37iT2c47UPaZvQLMBGOA1AMVlxXj/xPsoLas9G5phGgodW+8ff18cawObDUT/Zv2h7kz0l87hTTc3iXO7vsTfzMC/34eJOYXmll5T/NUu3pFhaoIFIKMzUBHWQbNbo1mQPYoLS0WNwIQLkXfj/8rLrdTGoehDSM1PhYOpA/p59UNTYlnPOEA51H3B3NBcdC1RRtkLhiE23NggumvQsfZGlzegCfT36g97U3tRD7C+3XNSYrKwbelFFBeVijmF5hYu9MxoEiwAGZ3CwFAfw55sKzKEqUL/9p9vINfMqc7xf+tvSKVfxrUYByN9IzQl8jjA3NBQlObn1/n/RCxWiBSL9dWZr5RW/JbRXeiYWnxmsdh/LuQ5ccxpAkYGRuJcJv6+/ned/y8jMRdbvzmPwrxiMZcMe6qtmFsYRpPgI5bROYxMDER9LgdPS+QX6uN8u+eg17nPA/+PAtuPxR6r4jpqSoz9/GDo6oqywkLkhj64K0hlHmr1EALtA5FVmIXPTn2mtDEyugkdU3RsUZFlOtY0Cfm5TOWS6lI4PTs9X4i/vKwiOHpZirmEu3wwmggLQEYnMTE3wui5QTDPT0a+qQOOpAc/sG8wxf6VoQxd3brCy9oLTQ3FFln07NEgN7ChviHe7f4u9PX08e+df0V9QKYGCrKA3LSqGz3GVMt/d/4TxxQdW+90fwcG+polhppZN0NX167i3KZYwNqgOWLL1+eRlZYPG2czjH6uvZhLGEYTMVT1ABhGZdwIQ7tzS3Cu48vIzLTFlq/PYdxLITCzvL+uH3ULkCd/NFXpl5riADM3bKy3ACSCHIPwWJvHRHuuD45/gBDnEDia6WitsuJCICEMiDkFJF0BMmMBWax0W1iD2DO2Amw8AGsP6da5NeDZBXBtCxga66zrl+pMEo+3eRxBDkHQROicPplwUsTIPhX8lLhgupe8bBJ/54T719LeBGPmt4e5tW7+7ox2wAKQ0Vmy9++HWUEaejtexlG9/kiLyxGunXEvhtx3VX845jCS8pJEwPhAr4EqG7N59+5SW7jr11GUlAQjZ+d6/f/cdnNFsPv19OtCBH7d/2vdyFosLQViQ4Fr24Hok0DcOaC47nGUAhKGydekrTKGpoB7CODVFWg1EvDoJJKKtB2qR/ne8feQUZCBlnYtxbGlqVC2PHUGScpNEl1M7k3wys8pEnMDzRHmNsYY+0IIrB3MVDZehlEELAAZnYQWr6x9+8W+66CuGNs2BJu/OouU6Gz88+0FcXVvbGpYJcORGNN8jAgcVxWiLVxQEPIvXULOsWOwHScFsNcV6lryca+PMW37NOyL3od/Iv4Rn0lrRV/MaeDKZuDKFsnCVxkze8CrC+DWHrD1KrfseQLW7oDhPYs7dVKRxQGZMdLrZEQD8eclMZmXDkQdl7ajX0uv03os0Hoc4NlZa8Xg1ltbcSD6gLCW0TGlyvOisdB5QefBr1d+xYbrG6oIwML8Ymz77oKYG8ysjIT4s3VW3/qGDFNXWAAyOknhrVsoio6GnpGRcKvqW1gI0bf5q3NIvC3D9qUXMerZdiJhhPqFHo49rLLkj+qygYUAPFp/AUgE2AdgXrt5WHJuCT45+Qm6uHbRmKzNOpGXAZz/Ezi1Aki/U9WFGzAM8OsvWescmgtrap0wtgAc/aWtMtSVJfWWJAQj9gPhOyWBeGKZtNn5AF2eBEIeAUy1py8snROfnPqkouMMHVOaDtX1JAF4KPaQ+Hx0ThQVlAjxR3OCiYUhxswPgb2bhaqHyjAKQTsvTRnmAWTtl6x/5t26CfFHOHpalVv+DBB3I0PUCaQFgKx/VOS2s2tn+Nj4qIEALE8EOXYMZWTlagCz28xGsFMwsoqy8M7Rd+rcXk6tSbkBbH8F+Ko1sOt/kvgj0dd2CjBtDfDqTWDiT0DIdMCxRd3FX23Qa9Br0WvSa9N7TFstvSe9N42BxvJloDS2FM3vxkLnwttH30Z2UbY4hmYFzYI24Gvji04uncTno1hAufiLv5kp5oQxz7eHo6elqofJMAqDBSCjk2SXu3+tBlTtVuDsbY3Rz7eHkakBYq9n4J/vzmPT1S3ib1MDpkIdMG9f3hYuNRX5V6426DXIbfdRz49gamAqeqH+cfUPaLTwWz8L+K4TcPpHoCgHcAoERn8DvHIdmPgj0GoEYGSq/LHQe1AcIL0nvfeor6Wx0JhobN91lMZKY9ZQ/rz6J07EnxDHDh1D1SVMaCpTW0nnOJ3zdO7ThSDNBTQn0NzAMNoEC0BG5yhOS0Pe+fNi37Lf/d08XP1sxNU+TfzxNzLR5dxEuBi7iUBxdUDP2BiWvXqJ/axduxr8OmTNfKnTS2L/q9CvcD5J+k40BorD2/IMsLQLcJkytPWAgBHAzC3AvONAx1mAsQpjtei9O82WxkJjorHRGGmsS7sCW56VPoMGQccIHSvEy51eVguLuCKhBC8617ucmyDOfZoDaC6gOYFhtA0WgIzOkX3wkIjdMmkdCCM3t2qfIxeBJYaF8JD5Y/yN54Ai9TldrIcPE7eynTsb5b6dFjANQ32Giv6trxx8Ben56VB78jOBnf8Dvu0AnPsDoP7GJK7mHgUeWgP49VOMe1dR0FhoTDS2p49IYy0rAc79Ln0G+iz0mdSctPw0cYzQsTLMZ5jaWMQVSrE+xl1/Du4yf3Hus/hjtBn1WdEYponI3rdP3Fr1q71ZfbZdMra2WopCg3wgzkLEA1FGoDpg2bcv9MzMRCJL/qXLDX4dKgHzXo/34GPtg8TcRLxx+A2UlJZALSGhe3E98F1n4MRSoKQQ8OkNPL5HElcuGlCDzrWNNNbHd0tjp89An4U+U9jf0mdUQ+iYWHB4gThG6FhZ2GOh1pUPkmf76sVbiHN+S6vvkGPPbRMZ7YUFIKNTlBYUILu8iLJl/9oF4NrwtUi0uoOkfqHCFUTxQP8sOY+C3CKoGn1zc1j26yv2ZTv/bdRrWRhZ4Kt+X4mYrmNxx7AibAXUjuRw4NfRwMYngOxEwKEF8MgG4NF/AK/O0Dio/AyNnT4DfRb6TBselz4jfVY1Y8XFFeLYMDM0w+J+i8Uxo03QOU11/ugcp4SPxH6nkWQVKeYAhtFWWAAyOkXuqVMoy82FobMzTINa1/i8nKIcUSOPGNtriKj9ZWJuiIQImWgFlZ+tehFoPWy4uM36t3FuYMLfzl+08SKWn18uFnu16dix/2NgeU/gzmGp6PKAt4G5x4AWg9TL1VtfaOz0GeizDHhL+mz0Gemz7l8ElKj+GCOo//XyC8vF/tvd3kYLuxbQJuhcpnNalHoxN8TYF0MwtueQilqHuUW5qh4iwygFFoCMznX/kCd/6NVSoHd7xHYhAsndRX1CXXysRZs4U0sjJEdlYfPisw/sHaxsLPv0FtnARXFxyL94sdGvN7r5aFHnkHqivn7odUTKIqFSEi8DPw0EDn4KlBYBLYcDz5wE+rwCGJpAa6DP0udV6bO1HCZ91oOfAD8OABKvqHRodAy8fvh1cUxQuzQ6RrQJOoc3fXVWnNNU5JnOccr2pX7fdO7THLAtYpuqh8kwSoEFIKMzUM08efcPy3vKv1R5XlkZ/gr/S+xToLs81onqBI5/qYNoBZUam4NNX55Fdno924kpEH0zM1iVu7Fl/+5UyGsu6LoAbRzaiPZe8/bME4H/TQ7FIB5ZDKzoByRcBMzsgEm/AA//JRVW1lbosz28Vvqs9Jnps6/oK30XKojLpN9+7p654ligY+KNLm9Am6Bzl85heXu3cS91EOc4oa+njykBU8Q+uYG1ok4mw9wDC0BGp9y/xQkJ0LeygkW3bjU+71zSOdxIvyFi4sa0qNomzd7dQohASzsT0RR+w+dnxK3Ks4F37WpwUejKmBiY4NuB38LD0gNRWVF4bt9zyK9vz9zGQIWTfxkG7FkoJUiQ1W/eSaCN6juwNBn0WeeVWwPpO6Dvgr6T9KazyNJvTr99dFa0OBbomKBjQ1uofO5a2ptg/Msd7uvwQa3haA6gvtnnkzWsRBLD1AEWgIzOkLFxo7i1HjEC+qY1FwX+65pk/RvhNwLWxvcXf7V1Mcf4VzrAxtkM2WkF2PjFGSRHZ0EVWPTuLTqZFMfHI+/8BYW8pqOZI5YNXCY++8XkiyL7s0kyg6lf7/d9gJhTgIk1MG65lDFr5QKdgz7zQ38BY5dJ3wV9J9/3lr4jJUO/NWWD029Px8CyQcvEMaEtkLuXzlk6d8W5/HKHanv72pjYYLivFGe75toaFYyUYZQLC0BGJyjJykLWf7vFvu2E8TU+Lz47Hv9F/if2a6tzZu1ghgmvdISjlyXysoqw+cuziLuZoYSR146+iQksBw5QSDZwZfxs/fBN/29gpG+EPVF78OWZL6E0ivKBbS8B62YCBZmAZxeppl/7hzU7yaOx0GenFnP0XdB3Qt8NfUfbX5a+MyXxRegX2Bu1V/z2SwYsgZ+NH7QFyvLd/NVZcc7SuUvij87lmpjWapq43X1nt+gPzDDaBAtARicQBZPz82Hs5wfT4OAan/f71d9RUlaCLq5d0Nqh5ixhwtxaihtya2GDwvwS/PPNedwJS1FdNvBOxbiB5XRy7YQPe34o9n+/8jt+ufQLFA61RKNEj9Cfpfu9XgRm7wBsmyn+vTQV+i7oO+n5gnT/9E/AT4OU0k6OfmN5W8CPen2Eji4doS3Qubl1yXlxrtI5S+cuncO1QXMA9QCn4td0DjCMNsECkNEJMjduqrD+1VTANrMgE39f/1vsz24zu06va2JmKPqEerd1QHFRKXYsD8PVY/FoSix69RRxjcVJScg7e1ahr01u8Bc6SMJj8ZnFihWBV/8BVvQHEi8B5o5STbxBCwEDI8W9h7ZA38ng94DpG6TvKjFM+u6uKi5D9eewn8VvTLzY8cUK96c2cPVYnDg3S4pK4dPWQXT4oHO3LswOkuYCmhtkhTIlj5Rhmg4WgIzWUxBxG3nnzgEGBrAeUzWpozLrr69HXnGeqInX071nnV/fyNgAw59ui4CurigrLcO+364idMedJssc1Dc2htXAgWJftkNxbmA5j7d9HPPazRP7JBB+CvupcS9I8YR73gPWPgIUZgHePSU3J9XEY2rHf5DUTq5ZD+m7Wztd+i4bGaNJv+nXZ78W+/Paz8NjbR6DNkDnYOiO29j32zVxbtI5OuzptjA0Nqjza/Ty6IUWti2QW5yLdeHrlDpehmlKWAAyWk/mJsn6Z9mrF4ycnat9TkFJAf68+mfFFX9921wZGOhj4KxAdBjqLe6f3BqBQ39dR2lp04hA6xGStSZz+3aU5uUp/PXntp8rhAHxzdlvGi4Cc1KBPyYCR76S7nd7Bpi5BbByVeBotRxrN+DRrUA36fcQ3yV9p7kNK9nz48UfxW9KPNP+GcxtNxfaAJ17h9Zcx8mtt8X9DsO8xTlK52p9oLlA7hGgOaKQMrMZRgtgAchoNWUlJcjcImVO2oyvOflj261tSMlLgYu5C4b5SqVV6gstFN3HN0fvqS0BPeDSwVjs/CEMxYXKz6C16NkTRh4eKM3MROY25RSuJWHwbPtnxT4Jhh8u/FA/K2c81bXrB0TsB4zMgYk/A8M+ZpdvQ6DvbNgi6Tuk75K+0x/6St9xHaHf7vsL32PJuSXi/nMhz+Hpdk9DG6Bzjs69S4dixblI52T3cc0b3L94uM9wOJs7izmCC0Mz2gILQEaryTl2TMTGGdjY1Fj8ubSsFKsurxL7M1rPENmPjSG4vyeGPtEGBob6uH0hBZsXn1N61xA9AwPYPfyw2E//40+luZ+faveUEArEd+e/w0cnP0JxafGD/5HKl/wyFMiMAuz9gCf2AG0nKWWMOgV9h/Rd2vlK3y19x3UoFUO/2YcnPsTS80vF/edDnseTwU9CG6Bzjc45OvfoHBw2p404JxuDkYERZgTOEPs0V9CcwTCaDgtARjdq/40eLWLlquNA9AHckd2BlZGVaIWmCFp0dMaY+e1Eb1HqMfr3p6Gi44AysZ04AXqmpigID0deaKjS3oeEwqudXoUe9ESXhGf3Povswuzqn0xZydTXlsqXUE9Vv/7AnH2AS5DSxqdz0Hf55H7pu6XvmL7rA59I33010G9Fv9m66+vEb0i/5ZzgOdAG6Byjc0309bUwxJj57dG8Q/VhH/WFWuFZGlniduZtHIw+qJDXZBhVwgKQ0VpKMjKQvWfvA2v/ya1/kwMmw9LYUmHv7+5vh0mvd4KNkxmyUvNF54Hoa8prrWZgawub0VKv1rQ/pHhGZTEzaCYW918MM0MzHI07ihn/zkBcdlzVJxVkA+tnSn1t5fF+0/+W2pwxioW+U/pu5XGBBxYB6x8FCqtedNBvRL8V/Wb029FvSL+lNhB9NU2cY3Su0Tk36bVOcPe3Vdjr09xAc0TlOYNhNBkWgIzWkvnPNpQVFcGkVSuYtm5dY9s32sjtOz1wusLHQJ0GJr7eUaoVmFeMbUsu4MrRe4SSArF75BFxm7VnD4oSlFu4dmCzgVg5bCWczJxwM+MmHt7+MM4nlbfMyoyR2pdRqRdyqY/5rjzer26lN5gGQN8txQXSd03f+dWt5W73WPFn+m3oN6Lfin4z+u3oN9QG6Jza9u0FcY7RuUbnHJ17iuaRwEdgqG+Is0ln7x7rDKOhsABktBISfmkrV4p928nVx5pRnNx3574T+6ObjxZB3srAzNIYY+eHwL+zi8hM3P/7NRxZfwOlJYqPIzINaAnzzp2BkhKk/yW1tFMmQQ5BWD1yNVratURqfipm75yNn4++j9IfB0i16iycgFnbgA5S/BTTBNB3Td851QtMCBO/xU9H38esnbPEbxRgFyB+M/rtNB06h46suyHOKTq3WnZxEecanXPKgOYI6hFMyOcOhtFUtEoALl26FD4+PjA1NUXXrl1x6tSpGp+7atUqkRFWeaP/Y7SDzG3bURQXBwMHB9hOrD6u73j8cZxKOCWsf08FP6XU8RgY6WPwY63ReZSvuH9hbzS2Lb2I/JwipVkBM9atR2lBAZSNq4Urfhv+G4b5DBMdE76+uR5PW5YixaWVFO/XrJvSx8DcA33nc/aJ3+ApyxJ8c3O96HBD2ay/Dv9V/GaaDp072767gAv7osX9LqN9MWh2a3GuKROKgaU542TCSRyPO67U92IYZaI1AnDt2rV46aWX8O677+Ls2bNo164dhg4diqSkpBr/x9raGvHx8RVbZGRkk46ZUV7pl9QVK8S+/axHoV+NsCfr35KzSyp6/rpbuit9XHSR0WWUL4Y92QaGxvqIvpKGDZ+dQXqCYpNDrAYOgKGrK0rS0iD7V/GFoavDwtAcn8EZ7yWnwrS0FMfNzDDRzgRHc6TFmWl6jubGiN/ghJkZzEpL8X5yKj7Vcxa/laZD5wwle0RfTRfnEp1TnUf6NrjMS33wsPTAlIApYp/mkKYq+M4wikZrBOBXX32FOXPmYPbs2WjdujW+//57mJub45dfam5dRZOFq6trxebi4tKkY2aUQ9buPSi8fRv61tawe+ihap+zJ2oPLqdeFoHwT7R9oknHR1mJE17tCEt7E2Qk5uLvT0IV2kNYz9AQdtOmKb0kTAXFhcDmedDb/yEmZOdgrWM/tLT1R1pBOp7e8zTeOvIW0vPTlTsGpgL6ruk7p++efgP6Lf5y7Ifx2TnQ2/eB+K3Eb6ah0LlC50xmUp44hya+1lFhmb51ZU7bOWLuuJR6CXujpEQzhtE0tEIAFhYW4syZMxg06G4rKX19fXH/+PGaTfTZ2dnw9vaGl5cXxo4di8uXLzfRiBllQWInZcUPYt/+kekwsLSstgbat+e+FfszW8+Eg5lDk4/TycsKk9/oDLfmNqI5/fZlF3Fq223RrkoR2E6ZDD1jY+RfuiS1wVMW1H3i9/HAhdVUjBAY+SX8Ri/F6lFr8HArqS7hlltbMGbzGGy5uYWtJUqEvtvNNzdL3/WtLaLEC/0G9FvQb4IRX0i/Ef1W9Js1sHOIqqBz49Q/Edi+9KI4ZyjZg84hR0+rJh8LzRlUM5SguaSkka34GEYVaIUATElJQUlJyX0WPLqfUEMmZEBAgLAObtmyBX/88QdKS0vRo0cPxMTE1Pg+BQUFkMlkVTZGvcg5fBgFV65Cz9wcdjOqTzz459Y/opaXjYkNHg16FKrC3NoYY18MQZu+HkAZcHrbbWxfrpi4QEN7e9iMlYLVk79arBzhlXoL+GkQEHkEMLYCpq8DOkvWVBMDEyzougC/D/9d9FbOKMjAW0ffwuP/PY6b6TcVPxYdh77Tx3Y9hrePvi2+a/rOKS6TfgP6LQRd5gAPr5N+K/rNfh4s/YYaAJ0TdJF0evsdcZ/OmbEvhIhzSFXMCpol5pCIzAj8E/GPysbBMDotABtC9+7dMXPmTLRv3x59+/bFxo0b4eTkhB9+kKxH1bFo0SLY2NhUbGQ5ZNSLlB+k2D+7qVNhaGdXbc/fZReWVbhxrGgxVCHUqaDvQwEY+GigCF6PDEvF+kWnkRJTQ2HleuA4bx70TEyQGxqKnEOHoFAijwE/DQTSbgE2XsDju4AWdy3wcto7t8faUWvxYscXYWpgitMJpzHxn4l488ibiM2WypMwDYe+Q/ou6TsNTQwV3/FLHV8S3zl99/fhP0j6reg3S70p/Yb0W6oxKTFZ4pyIvJQqzhHq50vnDJ07qoTmjifaSBc8y84v4x7BjMahFQLQ0dERBgYGSExMrPI43afYvrpgZGSEkJAQ3LxZs3ViwYIFyKReq+VbdDQHuKsTuadPI+/MGegZGcF+1qxqn7MufB0SchJEOQdK/lAXWnV3w8RXO8LKwRSylHxs+DRU1DZrjOXOyM0N9jOkjOCkL78SyTEK4cJa4LexQF464N4BeGJvrZ09KGPysTaPYdPYTaLuHLXR2nprK0ZtGoVFJxeJ/qpM/aDvjL47+g7pu6TvlL7bzeM2Y3ab2bW3M6Tfin4z+u3oN6Tfkn5TNYOOfToHNnx6RpwTdG7QOdKqmxvUhWmtpom5JD4nXswtDKNJaIUANDY2RseOHbF3791gXHLp0n2y9NUFciGHhYXBza3mycXExERkDlfeGPWz/tlMnAAjl/uDwjPyM7DiovScue3mwtRQvcr+ODWzwpQFndEsyB7FRaWittneVVdRmF+HXrs14DBnjkiGKbh+HZn/NNJNRWJ030fApicBsnYEjgFmbQes6pY85Wnlia/7f43VI1ajq1tXEYu5+tpqjNg4Ah+f/BhRsqjGjU8HiJRF4qMTH4nvjL47+g7pu6TvlL5bylCtE/Sb0W8XOFr6Lek33f+x9BurAXTM07FP5wCdC3ROTPlfZ3GOqBM0hzzd7mmxT3NLZkGmqofEMHVGr0xLorKpDMyjjz4qXLhdunTB119/jXXr1uHatWsiFpDcvR4eHsKNS7z//vvo1q0bWrRogYyMDHz++efYvHmzSCahLOK6QDGA5AomayCLQdWSffQooh9/AjAwQPOd/8K4Gvf8u8fexcYbG9HCtgXWjV5Xu5VExcHuZ/+LxMktEWI9tnM1x9A5beDg0bA2dak//4ykz7+Aobsbmv/7L/RNymPC6kNRPrDlGeDS39L9Xi8CA96hbCs0lBPxJ/DNmW9EJiVBSQv9vPqJxJyOLh2bpKSHJkBTNLl3f7/yu+hbXUYBoxQH59AG8zvORze3RtRZpH7Be98Djn4t3W8zCRi7FDBS3cVRamw2dv14CekJudDT10PXMb7oMMRb7KsjRaVFmPLPFNFhhXqJL+yxUNVDYuqAjNdvaE1fpqlTpyI5ORnvvPOOSPyg2L6dO3dWJIZERUWJzGA56enpomwMPdfOzk5YEI8dO1Zn8ceoD6WFhUh8/wOxbzf94WrF35nEM0L8Ee92f1dtxR9BC13HYT4iQ/i/ny6LhZDKXvSe2hKBPd3qLYzspk9H2u9/oDguHumr18BhdvXu8RrJSQH+ehiIPgnoGwKjFgMdGt8/loRL15FdRUFdEjeHYg5hf/R+sZFIH9t8LEb6jYSTuRN0keTcZGyP2C4yeklcyOnj2UeI5C6uXRovkmlOHPweYO8HbH9JEvjUxm/an4CFI5rc5XskTnT2IKufha0JhjwepNB+vsqA5pJ3ur+Dmf/OxIYbG0RXIbqAYRh1R2ssgKqAryDUg5Tvv0fy19/A0MkJfv/uuK/0S1FJESb9M0lk601qOUkIQE0hL6sQe1ZeQdQVqWSHX4gT+j/SCqYW9ROwGRs2Iv7NN2FgY4Pmu/+DQV2P16SrwOqpQEYkYGoDTPkd8OsLZUC/z59X/hQxbfkl+eIxfT19dHfvjjF+Y9DXqy8sjCygzWQXZgshvDViq+gyQbF9BCV3UAuy6a2nw8/GTzlvHnEAWDsTIDemrbeUMezcCk1BfnYR9v9xDRHnk8V9cvkOmtUaZlaqy/KtLwuPLRQCsLlNc6wfvR5GBup7kcnw+k2wAGwELABVT2FMDCJGjkJZQQHcv/gCNqNG3vecHy/+iCXnlsDe1B5bx20VpRs0CXIJn9sTJVzCpSVlwjJCLa88A+zq/holJbg9bhwKbtwUcYHOL7/04H+6sQf4ezZQIAPsfCRB4BQAZUNxVLvu7BLles4nn69iaens2lm4ift59oObpfokAzSG+Ox4HIg5INy71JqQ4vrktHdqjzEtxmCI95CmOW6Tw4HVU4D0O4CJNTB5ZbXZ3Yok5loa9qy6ipyMAugb6KHrWD+EDGqmti7f2o5bqsGYlp+G+R3mN3mBeaZ+yHj9ZgHYGPgAUj3Rc+che/9+mHftimarVt7nEouWRWP81vGi/Mui3oswym8UNJWkSBl2/3JFdA+BHtBhSDN0GeVX596nWfv2I2bePEp5h+/f62EaUIuYO7kC2Pk6qU/Au6dk+bNwUEnSA1kESRDSfmXI0tLJtRM6uXQSLjdNcRWTa5di+igsITQhFLcyq9bi87b2xlCfocLiR/tNTk4qsPYRIOoYxSMAwz4Fuj6p8LcpKSrFyX8icG53lKiDaetiLly+6pboUR/oouV/R/4nai9uGrMJXtZcKkxdkfH6zQKwMfABpFqy9u1DzLxnhKDx27wJJs2bV/k7HdrUDutY3DERb7Zi8AqNTywoKijBkfU3RKwUQYkhVBeNOos8CPo+Yp59Dtl798KkVSv4rlsruoVUoaQI2PkGcPon6X77R6SYP0PVu+KoeDdZyWgjy6DcPSqnmVUzBDkEIcA+AIH2geJWFV1eKpOal4rwtHBcTbsqbqn9YFRW1WxncnOTpU9YNr36wdfGFyqnuADY9iJw/k/pPhX4HvYJoCC3ZnJ0FvauuoLUWKkPduve7ug1yR9GJgbQZOgcm7N7Dk7Gn0RP955YPmi5xs852oqM128WgI2BDyDVUZqXJ1y/RXFxNbo05VfjxvrGogZdM+tm0BYiziXjwOpryMsqgr6+HjqP8kGHod7QN6jdGlickoKI0WNQkp4Oh6efgvMLL9z9I7UGWzcTuHNY5ORi0EKg53xqmg11g0r6CAtauSXtWtq1iuzYypDb38vKS2wkEKkUDdVtczB1gKOZI6xNrIUAawgkQGUFMlGTLzU/FUm5SYjJihECLzorWmzkDrwXer8AuwBhtZRbL21N1TDRgZaGo98AeyirtQzw7QNM/hUwt2/wS5aUlOLszkiEbr+D0tIymFkZod/0VvBrrxnW27pAluoJWyagsLQQH/f6WCSFMOqHjNdvFoCNgQ8g1ZH46WdIW7lSKm2ybRv0zc3vm4SpNENucS6eC3kOTwYr3oWlanJlhTi4JlyIQcLZ2woDH20Ne/faEyVkO3chloSfvj581qyGWbt2QOIVYM00KdnD2BKYsAJodX88pbqSVZiFi8kXKyxtJAjpGKhOFFbGUM9QxNaZG5nDzNAM5obSrYF+VUsU9XrNK84Tx5O4LcoVMV/FZbXXaKTSNuTGbWXfqsIyGewUrPIONPXi2nZg45NAYbYUC/rQX4BzYL1fJi0uB3t/vYKkyKyKhKZ+DwdoVKJHXfnhwg/47vx34niiklMqceUztSLj9ZsFYGPgA0g1ZO3di5hnnhX7nsuWwWpA/yp/p3i/R3Y8IkQAWVh+GvLTfQu6tkCn7/VTiTi89joKcouhb6iHTsMla2BtrbJiX3kVsm3bYOzrC99PnoL+9nnSAk/Zn7TAu2h+OSQSaSQCK1vkyEJHFjvaZIWK6eVNAlJuUSQLY2WLIy38JC41nsTLwJqH7l4gTPwJCBhep38tKS7FmZ2ROPPvHZHEZGJuiD7TWsK/s4vWukcpkeeJ/54Q1mkS/b+P+P1uT2ZGLZDx+s0CsDHwAdT0FEZH4/aEiSjNyoL9o4/CZcEb9z3nwxMfYm34WtiZ2OHvMX8Ll5+2k51eIFzC1EuYICsglYtx9as+c7QkM1O4gouTkmDXMgeuHTIBn97AlN8a5eLTJKg8ELluyZJXYd0rkm7vjS8kt62wDhrdtRLKhZ/OlPug5JD1j94NEej/JtD75VqLgSdEZIryLmT9I3zaOgiXL2WyazuJOYmY/M9kpBekY1rANLzZ7U1VD4mphIzXbxaAjYEPoKaltKAAdx56CAVXrsIsJATev/0q+v5W5r87/+Hlgy+LfQrA7uXRC7oCnco3Q5NweN11ERtIa3RwP09RVsPY9J6a7/mZyP78YUT/GSHues3pDMsXflZYkD+jpdybJBQwEhi/XKoRWYnCvGKc3BqBiwdiRPggxfpRIfMWHZ211upXHUdij2Dunrli/6t+X2Gw92BVD4kpR8brNwvAxsAHUNMS/867yFi3DgZ2dvDdtBFGrq5V/k4uPor7yy7KxuNtHscLHSslOOgQVFT3yN83EH4iQdy3sDFGz8n+dxffpGvA2ulA6k3En7FHxg1T6FtainhAE39/VQ+f0QTO/gZsf1nqI+zQApj6pygaLS5CziSJTPXczELx1IBuriLD19RSNy8uFp9ZjF8u/QIrIyusHb1WhAcwqkfG6zcLwMbAB1DTkbF5M+LfWCAyUr1++hGWPXtW+Tu58GbtnIUrqVcQ4hyCX4b+AkNqW6bDRF1OxcG/rkOWnCfue7ayQ99O0bA9+DRQlANYe6J0/M+IfnspckNDYeTuDp91a2Ho2LQtwBgNJfYMsHYGIIsVcYHpfZfj0GkvxFxLF3+2djJD34daollr1ZbiUYdewY/tfEyULqIyRSuHrRQhBIxqkfH6zQKwMfAB1DTknj2HqMceQ1l+PhyfexZOzzxzX8D1i/tfFN0UKC7r79F/w9WiqnVQVykuKsHZXVE4u/MOSorLoI8ihFhsQYegBBhPXSH6vRanpyNy2kMojIyEaXAwvH9dBX0zXqCYOpCdjMK1T+LMFTeczxmLUhjBwFAPHYZRIlIzGBppZ/JVQ7q9TN42WcSbUq3Hxf0W6/wFqqqR8fqNhhXAYpgmIu/SZUQ/+aQQfxZ9+8BxrhRPI4euXyjpg8QfZdl9O+BbFn+VoAW4Sy8DPNTqOzQzPiMW6DM5k/DntZdw9UKRaDNnaGcHrx++F32C8y9eRNzrb6CstGoSBMPcCx07Vy8W48/wl3E2Z5I4trxNQsWxRscci7+7UNvCJf2XiDmKCpnTnMW2F0bVsAWwEfAVhHLJv34dUTNmioxV806d4PXjivssU0vPL8X3F74XWZoUZD2w2UCVjVctCf8X2PQ0kJ+BMhMb3A5egaMnbCrcwtR2q9cUf7i3sBVu4KjZj6GsqAj2jz0G51df0amAfabuxN3MwJF1N5AclVXh7u3ZLQO+F5+CXkEmQIWtx/8ABAxT9VDVir1Re/HSgZdElvncdnMxr/08VQ9JZ5Hx+s0CsDHwAaQ8Cm7fRiSJv5QU4ZZs9ssvMLCsWuB4Xfg6fHDiA7H/dre3MSVgiopGq4ZQK6+97wPHv5Pue3QEJq0E7LxFD9aL+2MQuuM2CvNLxJ+pEwNlCxuc3ou4114Xj1GZHec3XmcRyFSQFp+DE5tv4faFFHHf2NQAnUb6imxz0ZM6PRJYPwuIOyv9Q/dngYHvAIbaX/alrvC8pR7IeP1mAdgY+ABSDoUxsYh85BEUJySInrUUk0buycrsurMLrx16TVxJP93uaTzTvmpcoE5DWb4bngASw6T7XecCg9+/r58vdRI5+U8Erh6JE12/SOe16uGGlgXnkPWFtEDZTJwAt/ffh54Bu/N0may0fJzedhvXjsdXHCuBvdzRdbQfzK3v6eRRXAjsfgc4uVy679oWmPgz4BSgkrGrI9+d+w4/XPxBeC4+6/MZhvoMVfWQdA4Zr98sABsDH0CKJy/sEmLmzUNxcjKM/fzg/ftvMHSomkW44foGvH/ifSH+JvpPxLvd32UrFUGnMtVn++8toDgfMHcAxi59YMcGKtJ7Ystdqw5Zclp65MFhzUIYF8hgNXQo3D//DPrG2teyi6kdukg4918kwg7Eio4ehG87R3Qb1xz2brW3HMS1HcDWZ4HcVMDQFBj6EdDpcbXsLd3U0LK78PhCbLyxUYhAmsMm+E9Q9bB0Chmv3ywAGwMfQIpFtus/xL3+ukj4oHp0VO7FyMWlynN+DvsZX5/9WuyT+CMXira2easXWYnAP/OB6/9K95sPAMYtB6zqnhBDXRuObbyJ+JuZ4r6BQRk8IvehWeR/sOvaHp5Lvrmv5zKjvcLv/O4ohB2MQXGhJPzc/W3RfXzzGrvLVEtWArB5LnBrn3S/5XBg9DeAVdXzWheh/tJ0IUsikHix44t4rM1jqh6WziDj9ZsFYGPgA0gx0CGY+sMKJH8tCTuLPr3h8dVXMLC0rPIcKqi68vJKcZ8KPc/vMJ8tf3T6hv0N/PsqkJcOGBhL7t4uT9XaoqvmlytD5KVU4e5LipQC/PVLCuEZexAtjG7Db/EimPj5KuGDMOpATmYBLuyJriL8nL2t0HmUL7zbODTsfKOM8pPfA3velQpHm9kBI74A2kzUeWsgnW90QUuFoonZQbOFENT5ea0JkPH6zQKwMfAB1HhK8/KQsHAhMrdsFfftZs6Ay2uvQc/QsErPVrpS3nxzs7j/SqdX8GjQoyobs1pZ/ba/BFzbJt13DZasfq5tGv3S1QrB0iK4pYSi07QO8JxSu1uZ0SwyEnNxbk8Uwo8nVLh6Gy387iXhErD5aSChPDa11Shg5FdsDQSw6tIqfHnmS7E/vsV44dnQmR7TKkLG6zcLwMbAB1DjyLtwQdScK7xzh/yNcH37LdhNm1blOXHZcXjl4CsISwmDgZ4BFvZYiHEtxkGnoVP24lqpJytZ/fSNgL6vAb1eVHgv3wohuPUGkqKl0jEoK4WHWRq6PTMQrv663eVB00m8IxMxfrfOJYuevYSLrzU6jfBRnPC7t5fwkcXAwc+A0iLJGjjsUyB4is5bAzfd2CTiAim2OdgxGF/0/ULUD2SUg4zXbxaAjYEPoIZRVliI5OXLhduX3EOGzs5w/+xTWHTrVuV5h2MOY8GRBaJ6vrWxNRb1XoQ+nn2g06TcALa9CNw5rHCrX23QNBEXnooTPx5BQs7dY93Z1QjtR7aEXwcnGBhwXXlNoKSkFBFnk3FxfzQSImQVj3u3dUCHId5wa2GjfBeksAbOBRIuSvd9+0jWQEfd7kV9KOYQFhxeAFmhTHQ1WtRrEXp79lb1sLQSGa/fLAAbAx9A9Sc//DriFyxA/pUr4r716NFwfevNKmVeqLXbsvPL8GPYj+J+G4c2+KLfF/Cw9IDOUpQPHPlKsp5QHBVlVfZ5Feg5X+FWvwcRvfUgTv8RigTbtigrb2dlYW2ENv08EdjTHRY2XPNNXeP7rh6Nw6WDscjJLBSP6Rvowb+TC0KGNIODx92Y2yaBrIFHvwEOfS5lrVP8Klmxe70EGJlCV4nNjsXLB17G5dTL4v6ctnNEmStOdlMsMl6/WQA2Bj6A6k5xWhqSlyxBxrr1wupnYGsL14XvwnpY1U4BN9Jv4L3j7+FC8gVxf1rANLza+VUY0+Kgi9DpeX0nsOt/QFqE9FiLwcCIzwF71SVjFCUlIfLjr3D9ahFi3Xuh0EQS8Pr6evAJdkRgTzc0C3IQ9xnVUVpahqjLqbhyJA53wlJF+zaCave16euB1r3UQLCn3QZ2vALc3CPdt/cDhn4MtByms27hwpJCfHb6M6wNXyvut3Nqh4XdF6KFXQtVD01rkPH6zQKwMfAB9GBKCwuR/vvvSFn+PUqzs8VjVkOGwOWtN2Hk7FzxvIKSAvxw4QesvLQSxWXFsDCyELWxhvvqcLIBuclI+N0+KN23cgOGfwoEjlGbhTH70CHEvfchYotcEOPRFzIbv4q/WdqZoFV3NwR0dYWtC5ePaeqkjvCTCaJwc3Z6QcXjVMKlbT8PNO/gDANDNXLZ0zJ0ZYsU15oVLz3m108Sgi5B0FV2ROwQCXA5RTkw1DcUZWKeDH5S9BRmGoeM128WgI2BD6DahZ9s61ak/LACRdHR4jHT1q3hsuANmHfuXOW5pxNOC6tfpCxS3O/v1R//6/o/uFrUvYadVpGdDOz/EDj7m0i4EK6xbvOA3i8DptZqmcmdsmw5UleuRLaxE+LdeiDBqyeKcHeRcvaxRssuLsLdeF/nCEZhtftuhCbi+smEisxtwtTCCAHdXIVV1sG9id289SVfBhz+EjixTAp10NMHOswE+r8FWDpBF0nIScBHJz/CgegD4r63tbe4OO7sWnUeZeqHjNdvFoCNgQ+g+ynNyUH6uvVIW7kSxUlJ4jFK8nB68UXYjB0DvUq16cjdu+TckoqJzcnMSQi/gc0G6mYdLMroPfYdcGI5UJQjPdZ6HDD4PcDOB+pOYXQ0UpYuQ+bWrSgt00eyUzsktxmJ5DIXYeAh9PT14NHSFs1DnODb3kn17kctiOu7fT5ZZPHGXs+ocPHS9+wVaI9W3VxFn2fRp1eTILcw1Q0kqyBhZAF0mwv0eFbKHNYxaJneE7UHi04uQnJesnisn1c/PB/yPPztdDtxpqHIeP1mAdgY+ACquvhnrP8b6WvXojQzs0L42c+eDbupU6p0kIjOihZJHtsjtqMMZaIV0uSWk0VhZytjK+gcBVnAie+BY98CBdJ3B/cQyf3l3QOaRkFEBFK+WwrZjh3ifqGRFdLaj0Kie3ekZlYKZNcD3PxshBD0aesg3MQ6KfzrAU3X5N6leL6Ic8lIuJ1ZUb5FbmkN6OqCFh21xNIaeUwKg4g7J903tQF6PAd0fRow0b25grKDl5xdgvXX14tyMXrQwyi/UZjXfh48rTxVPTyNQsbrNwvAxqDrBxC5ebP37kXG+vXIOXa84nFjb284zHkC1mPGVOkfeyvjFn6/8ju23NoiMn2Jwd6D8WzIs/CrFDumUxY/6t1LFj/ql0o4twb6vwm0Gqk2cX6NyfhOW7UKsm3bUFZUJB4rcG8JWffJSDD2QXK8lIkqx8rBFN5BDmjWxkFYCY1N7xYD12UK84uFdS/qUioiL6ciKzW/yt+pbp9fiJOw9Nk6a2GsJS1R17YD+z8CkqTqAaLPNVkEOz+hkxbBiMwIfHfuO+yO3C3uU3zg2OZjMaP1DDS3ba7q4WkEMh1fvwkWgI1AFw+gspIS5J4OhWznv8ja9R9K0tOlP+jpwaJHD9hOnQKrgQOhZyBZeujwOhp3VAi/Y3HHKl6nh3sPPN/heQQ56GCAtywOOL4UOLMKKJQSY+DQAui3AAia0KAWbupMcWqquEhIX72mIiyAKGvTGbJOY5Fo4IW4yByUFt+diih72NnHCu4t7YQYpOQFXRGEJPgSbmUK0Rd7PR3JkVkim1eOvqEePPxtRbY1iT5LOx0pmVJaAlzeBOz/GEi7JT1mbAl0nAV0fwawdoeuQaViyCJYeW7t6d5TCEGaY9miXjMyHVy/74UFYCPQlQOILH15oaGQ7d6NrP92oyS13FpV7ua1mTgBthMnwdjzbp2+5Nxk7Li9QzQ6p6tVgly9A7wGYGbQTIQ4h0DnIDfWqR+Bi+ukLgiEcxDQ6wVJ+Blot8AhK2DW3n3I3LIF2YcPA8WSFZgEr1FIZ+R2GIIUS3/ERhdBllLVykUxbQ4eFnDxsRYWL3J12rtaiMc1GYrZS0vIQdIdGRJvy0RnjtTYnIpYPjnWjqairA5ZSD0C7GBkosM14UqKgUsbpBqCSVKtPNENh7qJdJkjhU/oGGcTz4qL7H3R+4RrmCCvygT/CRjpNxKOZo6qHqLaIdOR9bs2WAA2Am0+gApjYpBz+DCyDx1GzsmTKMvNrfgbFW22HDwI1kOHwaJ7t4q+vfnF+SKhg1y8dEUqn4iopAv1t5weOF334lSogPOVzZLwiw29+7h3T6nobYtBGu/qbWhdSNm//4qEkfwL5d0gyjH284Ne90GQeYUgpcQecRHZ97k9CUNjfdi7W8LRwwIOnpYiw9XW1VzEvqmb5YOmWcrSzUjIRWpcNlJjspESm4O0uGwUF0rnyb3ucLJ8erS0g7u/LawdzVQybrWGlq4bu4GjXwORR+8+7tFJEoKUQKVjBaUpvnr11dXYdHOTKB1DUAtNsgaOaT5GJI6YUhF5Btq8ftcVFoCNQFsOIDoEiqKikBsaKty7uadPoyg2tspzDJwcYdm3ryT6unWFnpHUfYLatB2OPYx9UftwJPYI8orL+8WWFy+lSWeE7whYkqtGl6CG9+fXABf/uhvfR1aKoHFAl6cALy7hIKcoLg5Z+/Yje98+5Jw6ddcySBgawqxdO+h17IVstyCk6zkiOTYPSZGyaoWT+BcTA9g4mcHWyUwIJwtbE1GTkG5pM7MygqGRYi1oxUUlyMsqQk5Ggdio9h7dylLykJGch8zkPBQXlNQ4XudmVlWsm1b2vEjXi+jTwKkfgMub71rXKU4weBrQ/iHAtS10iazCLPx7+19svbW1oqg+YWZohl4evTCg2QD09ugt2s3pKjItWb8bAwtAHTyASmQy5F+6hLyLYcgLC0PexQsoSU6p+iQDA5iFtIdl7z7/b+9MgKM4zjb8SXvpPkAHCCQOgcE2hzjMYTvGKQjY4BgnKQeTVEyo+IzjwnEu7IrtcqpSxFfsMiHluJLgP1UxOFTZ5DeJ7cLYxj/3IQi3AhhJCHQggW5pd7U7f709u6vdRSskkNDszvsUTc/09Ejbmpmdt7+v+2tJueNr4hg/XllVYNX776X/yq7zu2Tb+W2yv2q/CtzsZ2jyUDUrDcJvZLrxQ5f0Kc01Ioc36MKv+nBnedpwkenLRaYuM20ss57iaWrSLc87dkjrjp1KHIYQHy+OceMksahI3IVF0pJRII0dKVJX2Sp153RLYU++0ay2eElIsYkjCcmq9hEqxWq3qO1w1zJcsh1ur3S4POJB7vaKs7VDnK1uaW92q/0rAaMkLHtYcq0zJUt6ThJXTOnLZ7D4f0T2rRVpDOrE5k7UheDE+0VSOgPQm4HShlIlBDd9tUkqWyo7n4E4q0wbMk1uz7tdZuXNkhsyb1DDdMxCY5S+v/sSCsAYvoE0r1dZ8pwlJdJ+okScJSdU7g/MHILNJokTJ6ogzUnTp0vilCliSUkWj9cjpxtOy8Gag7Knao/sqdwjl5y+iR8+xmSMUcGbEb/vpsE3Gc791q80Vooc/1Dk+P/qbiif21sFbx53t8jkpfrSbTE+vq/fLNNnz0rLzl3Sunu3tB08eLkgxJdYQoIkjBsnjptuFNvYceLOHS1tyUOkqSVOmi62B6xxzfXt0lrvCplQ0ZdAxCVl2CUlIyFgdYQlLz0nUc3Ohfgz1OobsT5O8NRmkYPv6kspIqg0gMDB8IubFouMv0ckbaiY6Xk6VndMtpRvkc/Pfi6n6k+FHM90ZMrMoTNVgOminCIpTC+M6fWHGw3+/r4eUADGwA0Eq4mrrFzc5WXiLC0V1+mvVCw215kzorVfPnYK2PLzleBLmDRREidNUqt0xCckqMkbxy8el6O1R+XghYNy6MIhaXb7Zqr6SLImyfQh02XW0Flyx/A7VGR604DHpfqo/nIp+Ujk7O7Q4xh/BEsDJnUkDRqoTxmzuKurpe3AQWk7cEDajh4R57Hj4g0anxqMNTdXHIWFYh85UuyjRqncNnKEaJk54mr3SnuLW5wtHeJs61AuXLiUdeueJ6Dj/UA3wG2sWwnj1bYj0SqOZKtaacORbBN7gsVcnZ9oofWiPmnkP+tEzu0POhAnkj9D76iNna+HYDLR9cPKS19WfCm7Knep1ZiCh++AFFuKTMqeJEXZRXJz1s1y46AbJTspdjwYjQZ5fw8kFIBRcAN5mluko7pK3OcrlUXPn1znKsRdfrYzFEsXYKyevbBQt5CMHy8J4/Xck5YkZxrOqF4g4vOduHhCjtcdl7r2zhm+wYJvYvZEmZozVWbnzZYJWRPEhvFsZqGlTqRsm75Y/clPRZrCrFDDZ4jcdK++Rm+micSwQazcrrIyaT96TNqPHxPnqVPiPHlSOs53urouw2oV27A8sQ/PF9vw4WIbPkxseXliG5ontryhYs3ODoQxIjHGpVLdYo8VRir2hh5LzRMZO0+fmDXidpHkwWIW3F63HKk9IjvP75TimmLV8Q8XhGBwwmC5cfCNMn7QeBVvEN6fUemjonJt4kYKQApAI95ACJPR8OEmXfRVVom3OdQC1xWWrCyxFxSoIMyOwtFqJqVl5Aipy7TK2bZzUt5Yrnp85U3lakxIRXNFYJZuMBgDgvABeMAxiQOuADzkCDRqKrfu2V0ipdtFSreJXDgeetyaKDLqa7prFwGb0zvD3xBj4GluVkLQ9dUZcZUilfpSWSAodUQsFiUCrbk5YsvJEWtOrgp3ZM3KEmt2lsotg7PEOigzMBmKRCEN5/QA07Dmn0FYojDBA4sg3MUjbxMpmC2Sap61yRGoH8YBDP3BJBIYCBDOK9I7Iz81X3mCClIL9DytQG1jPXejvjsaKQApAI14A1344x+l9s3VIWXxaWliGzJEbMOGqWTNGyru7AxpyE6UC4MsUiUNUt1SrQb5nm8+r1J1a7V4tK5nHoI0e5oSd+jJYQAwenbIMVPMVO6h6iO6a0il4tDB48Evg1FzdAsBXgo2E/2NYiyQOYJRuysqxHW2QtwVZ1XIo45KdLYqxV1VFToL+QrEp6eLNTNTLIMHK0FoycjwJf92ugqbhOcXuSUtTY1ZpKvYYLjb9DG8sPCf2dq54kgwacNEhk3Vh3kgz51gqmEesAhiAiA8RcjhOYJIxPJ0kUAImtykXMlLyVMJkwRzk3NVmT9hJvJAPA+NFIAUgEa8gSqKt0n1gR3SkGGXulSRmhSPXJAm5Z6ta6tTi4HXttUGllPrDrhqEXtvRKreK/P3ziD8YM43zYsI6+3WnRKpPSlSc1wXfRjL15XYw4CvQO//dn093mQGUjWNQKytlY7qal0oIq+uUdtY0QTHPDiOYOjeK8/87RKbTSypqSopYZiaIvHJKRKfkiLxqSliQZ6cHJqSkCepNbXjExNVHodks5nnGb6etNTq6xDDAwBhCEHYhfVLiUIIwdybRXJuFMkaq6/qY5J1iiEf8F6CEAx4mZA3lUlFU4VyLV8JWAgRqDo7MVsGJw5W76VBCYMCKTMhU7mZYU3sSxopAGNLAK5Zs0ZeeeUVqaqqksmTJ8vq1atlxowZEetv2LBBnnvuOSktLZWxY8fKSy+9JAsXLhzwG+iN/W/IX478pUd18YCgF5WTlKP3qJJzZVjKMJXQ48KDZYqp/VgmCiEgGs6KXCoTqS/Vc4z5gfBr6mZMWEaBvnqA6tlPExk6WcRhsriFpNdCEeGUsCoOglp7Ll6Sjot14qmv70yX6sXT0CDehga9bmOjiCeyRf6qsFh0QZiYKHFJiRKfgJQgcYm+PCFB4h0OPffvJzgkzo4yh37MkSBxDrvE2e2+fYfE2fz7eh6SIDrNNkbS2SxS+R89mDs8BVjVp748cv3UoboQzBypjwvO8OXp+XoYmhieXesH7mIYKuCNOtd8TiV4qeCZqmmtUfnF9os9+lkPTXxIVkxd0aefr5ECUIzpnL8K3nvvPXn66aflrbfekpkzZ8obb7whCxYskJKSEsnJuTzu044dO2Tp0qWyatUqueeee+Tdd9+V++67T4qLi2XChAkykAxLHaYsdP7ejz9Hz8jfU0KO3pId4UZiWdS11Yu0XdRdta21ushruaDnzdW6sMPauk1VeCt3//OSs0WybtB76ei1Izgseu0J5g2GSq4OCCC4fpF6OvwdfW1vS4t4m5rE09gk3iaIwibxtjSrmfzeZv0Y9lHPg7oqtep5W6to2G5t7RzH6PGoMcI9GSfcp1gsnWKwu2S16uMkbXoeZ/WVqXKrmpDTWWbx7VslzqIfV6sMYdt/XG1bdAHq21afxb8db/Hl8fq5vjwO62ujjiUoR1217/t5wfuqftCsbnQIMRYQyU97g+5NQNB3eBTgXaj9r/79hO8lpNL/u/xvF2fRxxNi7WIIxZRcXRTi+wl5UpbuWk5EyohasQjDAwwTSBhL3hUuj0t5tSAU/Z4tWBQvtV9S4tCfw5hB+p6YsQBC9N1yyy3yhz/8Qe17vV7Jz8+XJ598UlauXHlZ/SVLlkhLS4ts2rQpUDZr1iwpKipSIrInmL4HgVsHbmjE2FLJLdLh9KX2zhzja9ytQXmriKtFd8siV9uNIu2NIs4G/YvVn3oDLJ2Yyad63CM6c79bBl+mhMQAEIDetjY9QRD6t9vbVegnbxty7Ds7c2e7b79dNJezc9vtEq/TJZoTdZzidTlFc7n1fZcrkEwJBGC4IPTvRyqLwz+PWpEkDkHy4QbFttelb8dpqKJyva4ekUZpTV+Z/1erfQssrjbEIdK3fbleDhFt9+1D2Oo5ygLbKvnq+pMSuzb980Jg4vdjGxuqLE5vF75TVR6nB0fXP1RnO8PqdJ7nr+c7N7xe4NzQupeV+eoinBNSX9Jo9vd3rFgAXS6X7N+/X5555plAWXx8vMybN0927tzZ5Tkoh8UwGFgMN27cGPH3OJ1OlYJvoH4BIQoQqiCgzX252g/bDsl95Wqsiha27e3cD0+wtMF6pnKtcxviTiX/tlsPsKpy/UvtuoDliiDe0ENWvWTkOXpvGT1ojMNBQFeUMeAyMQGwplmQrtOLS9kJIDohDN0+Ueju8G2jzK2Xdfi2fQkTavRtX479Dl85Es71eDrLUA85vmc6UK7v4ztIw74q99XDGExVF3EbPSLhZXC3d5V7vYHtK47jRLvx8/y71/yXvNpZ4/jNEOHmFOJZS+ZJ9ouhEyPJtRMTb8taDMz2eCQ3NzekHPsnTpzo8hyME+yqPsojAXfxiy++KP1O9TF9SbFoBPGgsNi41Z/bRWxJvpTYmcOlgvWB7cl6cqSJJKTpYg8uWWwrF0gmRR0hA4yyzNjtYrFjyEmyxApK2AYJQs2jd4jVPo75BONluf8cfx2cpwWVqeNBZVh9Jvy47+dgX9/21/GVezpEw9jD9iblPdFc8JzAgwILbqtIh0v3sridormdPg8MBLWvg97h0oWx+v0dgVzZH4PtCGoD/+nlajPc1uA3S3Z5HvaDJiJdVkc/FuJrDPu9gd8ZfH7Qts3RdbB3cm3wzdoLYGEMthrCAgg3c58zZq4ugEJ9ARG2g8oCeXyYCR0mfn+5b0KIMvvHByV9DIzaVjnG1sBFoLsL9OO6K6Ez97kiIPYwFhHlnJFICIkSAu5bs0xqCR62A/Ho9+SovKMzD/YCoSzgIQryGIV7kdTP95f5PEnBHqpgz1S410rfiLyNYPukz4kJAZiFwKwWi1RXV4eUY3/IkK6njqO8N/WBw+FQqd/B8kRIhBBCSF+hBK+v4w7PCzE1MREfxG63y7Rp02TLli2BMkwCwf7s2bO7PAflwfXB5s2bI9YnhBBCCIkVYsICCOCaXbZsmUyfPl3F/kMYGMzyXb58uTr+4IMPyrBhw9Q4PrBixQqZM2eOvPbaa7Jo0SJZv3697Nu3T95+++0BbgkhhBBCSP8SMwIQYV0uXLggzz//vJrIgXAuH3/8cWCiR3l5uZoZ7OfWW29Vsf9+/etfy7PPPqsCQWMG8EDHACSEEEII6W9iJg7gQMA4QoQQQkj00cj3d2yMASSEEEIIIT2HApAQQgghxGRQABJCCCGEmAwKQEIIIYQQk0EBSAghhBBiMigACSGEEEJMBgUgIYQQQojJoAAkhBBCCDEZFICEEEIIISYjZpaCGwj8i6ggojghhBBCooNG33vbzIuhUQBeA01NTSrPz88f6I9CCCGEkKt4j6enp4sZ4VrA14DX65Xz589LamqqxMXF9XnvBMLy7NmzMblOIdsX/cR6G9m+6CfW28j2XT2apinxl5eXJ/Hx5hwNRwvgNYCbZvjw4f36O3DTx+KD7Yfti35ivY1sX/QT621k+66OdJNa/vyYU/YSQgghhJgYCkBCCCGEEJNBAWhQHA6HvPDCCyqPRdi+6CfW28j2RT+x3ka2j1wLnARCCCGEEGIyaAEkhBBCCDEZFICEEEIIISaDApAQQgghxGRQABJCCCGEmAwKQANQWloqP/rRj2TUqFGSmJgohYWFauaTy+Xq9rz29nZ54oknZPDgwZKSkiLf+c53pLq6WozKb3/7W7n11lslKSlJMjIyenTOD3/4Q7XKSnC66667JFbahzlYzz//vAwdOlRd+3nz5snJkyfFiFy8eFG+//3vq4CsaB/u2ebm5m7PufPOOy+7fo899pgYhTVr1sjIkSMlISFBZs6cKXv27Om2/oYNG2T8+PGq/sSJE+Xf//63GJnetO+dd9657FrhPKPy5Zdfyje/+U21kgM+68aNG694zhdffCFTp05Vs0rHjBmj2mxkettGtC/8GiJVVVWJEVm1apXccsstajWtnJwcue+++6SkpOSK50Xbc2hUKAANwIkTJ9Sycn/605/k6NGj8vrrr8tbb70lzz77bLfn/fSnP5UPP/xQPQxbt25Vy9J9+9vfFqMCQXv//ffL448/3qvzIPgqKysDad26dRIr7Xv55ZflzTffVNd79+7dkpycLAsWLFDi3mhA/OH+3Lx5s2zatEm9nB555JErnvfwww+HXD+02Qi899578vTTT6vOVnFxsUyePFn97Wtqarqsv2PHDlm6dKkSvgcOHFAvK6QjR46IEelt+wDEffC1KisrE6PS0tKi2gSR2xPOnDkjixYtkq9//ety8OBBeeqpp+Shhx6STz75RGKljX4gooKvI8SVEcF7C0aMXbt2qe8Vt9st8+fPV+2ORLQ9h4YGYWCI8Xj55Ze1UaNGRTxeX1+v2Ww2bcOGDYGy48ePI6SPtnPnTs3IrF27VktPT+9R3WXLlmmLFy/Woomets/r9WpDhgzRXnnllZDr6nA4tHXr1mlG4tixY+re2rt3b6Dso48+0uLi4rRz585FPG/OnDnaihUrNCMyY8YM7YknngjsezweLS8vT1u1alWX9b/73e9qixYtCimbOXOm9uijj2qx0L7ePJdGA/fmBx980G2dX/7yl9rNN98cUrZkyRJtwYIFWqy08fPPP1f1Ll26pEUjNTU16vNv3bo1Yp1oew6NDC2ABqWhoUEGDRoU8fj+/ftVbwkuQz8wiRcUFMjOnTslloBbAz3YcePGKetaXV2dxAKwSMA1E3wNsTYlXHVGu4b4PHD7Tp8+PVCGz431sGG57I6///3vkpWVJRMmTJBnnnlGWltbxQjWWjxDwX97tAX7kf72KA+uD2BRM9q1utr2Abj0R4wYIfn5+bJ48WJl8Y0Voun6XStFRUVqWMk3vvEN2b59u0TTew909+4z03Xsb6z9/htIrzl16pSsXr1aXn311Yh1IBzsdvtlY81yc3MNO97jaoD7F25tjI88ffq0covffffd6mG3WCwSzfivE66Z0a8hPk+4G8lqtaov6u4+6/e+9z0lKDCG6dChQ/KrX/1Kuafef/99GUhqa2vF4/F0+bfHkIyuQDuj4VpdbfvQwfrrX/8qkyZNUi9ifP9gTCtE4PDhwyXaiXT9Ghsbpa2tTY3BjXYg+jCcBB01p9Mpf/7zn9U4XHTSMPbRyGAYFNzyt912m+osRiKankOjQwtgP7Jy5couB+QGp/Av43PnzinRg7FkGDsVi23sDQ888IDce++9aqAvxnlg7NnevXuVVTAW2jfQ9Hf7MEYQvXNcP4wh/Nvf/iYffPCBEvPEWMyePVsefPBBZT2aM2eOEunZ2dlqbDKJDiDiH330UZk2bZoS7xD0yDGu3OhgLCDG8a1fv36gP4ppoAWwH/nZz36mZrF2x+jRowPbmMSBAcp4YN9+++1uzxsyZIhy89TX14dYATELGMeM2sZrBT8L7kRYSefOnSvR3D7/dcI1Q8/dD/bxEr4e9LR9+Kzhkwc6OjrUzODe3G9wbwNcP8x2HyhwD8GCHD5rvrvnB+W9qT+QXE37wrHZbDJlyhR1rWKBSNcPE19iwfoXiRkzZsi2bdvEyPzkJz8JTCy7krU5mp5Do0MB2I+g94zUE2D5g/hDz23t2rVqvE53oB6+oLds2aLCvwC41srLy1VP3oht7AsqKirUGMBgwRSt7YNbG19auIZ+wQd3FNw1vZ0p3d/twz2FzgbGleHeA5999ply2/hFXU/A7Etwva5fJDB8Au3A3x6WZYC2YB8vo0h/AxyHm8oPZi5ez+etP9sXDlzIhw8floULF0osgOsUHi7EqNevL8EzN9DPWyQwt+XJJ59UXgF4dfCdeCWi6Tk0PAM9C4VoWkVFhTZmzBht7ty5aruysjKQguuMGzdO2717d6Dsscce0woKCrTPPvtM27dvnzZ79myVjEpZWZl24MAB7cUXX9RSUlLUNlJTU1OgDtr4/vvvq22U//znP1ezms+cOaN9+umn2tSpU7WxY8dq7e3tWrS3D/zud7/TMjIytH/+85/aoUOH1IxnzP5ua2vTjMZdd92lTZkyRd2D27ZtU9dh6dKlEe/RU6dOab/5zW/UvYnrhzaOHj1au+OOOzQjsH79ejXj+p133lGznB955BF1LaqqqtTxH/zgB9rKlSsD9bdv365ZrVbt1VdfVTPuX3jhBTUT//Dhw5oR6W37cN9+8skn2unTp7X9+/drDzzwgJaQkKAdPXpUMyJ4rvzPGF5lv//979U2nkOAtqGNfr766istKSlJ+8UvfqGu35o1azSLxaJ9/PHHmlHpbRtff/11bePGjdrJkyfVfYkZ+PHx8eq704g8/vjjaub5F198EfLea21tDdSJ9ufQyFAAGgCEX8DD3VXygxco9jHN3w9Ewo9//GMtMzNTfbF961vfChGNRgMhXbpqY3CbsI+/B8CXwPz587Xs7Gz1gI8YMUJ7+OGHAy+waG+fPxTMc889p+Xm5qqXNToBJSUlmhGpq6tTgg/iNi0tTVu+fHmIuA2/R8vLy5XYGzRokGobOjl4+TY0NGhGYfXq1aoTZbfbVdiUXbt2hYSwwTUN5h//+Id2ww03qPoIKfKvf/1LMzK9ad9TTz0VqIv7ceHChVpxcbFmVPwhT8KTv03I0cbwc4qKilQb0RkJfhaNSG/b+NJLL2mFhYVKuOO5u/POO5WBwKhEeu8FX5dYeA6NShz+G2grJCGEEEIIuX5wFjAhhBBCiMmgACSEEEIIMRkUgIQQQgghJoMCkBBCCCHEZFAAEkIIIYSYDApAQgghhBCTQQFICCGEEGIyKAAJIYQQQkwGBSAhhBBCiMmgACSEEEIIMRkUgIQQQgghJoMCkBBCCCHEZFAAEkIIIYSYDApAQgghhBCTQQFICCGEEGIyKAAJIYQQQkwGBSAhhBBCiMmgACSEEEIIMRkUgIQQQgghJoMCkBBCCCHEZFAAEkIIIYSYDApAQgghhBCTQQFICCGEEGIyKAAJIYQQQkwGBSAhhBBCiMmgACSEEEIIMRkUgIQQQgghJoMCkBBCCCHEZFAAEkIIIYSYDApAQgghhBCTQQFICCGEECLm4v8BcKdXHPT0xB0AAAAASUVORK5CYII=", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "sample_model=SampleModel(name='sample_model')\n", "\n", @@ -114,33 +63,7 @@ "execution_count": null, "id": "ac7061fd", "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "c248ebdeb8444ea6a3cd89a8e29b6f1a", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAmCJJREFUeJzt3QV4U+caB/B/29TdvaWFQnH34dtgTGBud+4bc9/d7uxuzN13527MGWzDhrs7pUCpe+qN3ef90oS0tNBSSdr8fzyHc3JiX5KTnjfvZy4mk8kEIiIiInIarvYuABERERF1LAaARERERE6GASARERGRk2EASERERORkGAASERERORkGgEREREROhgEgERERkZNhAEhERETkZBgAEhERETkZBoBEREREToYBIBEREZGTYQBIRERE5GQYABIRERE5GQaARERERE6GASARERGRk2EASERERORkGAASERERORkGgEREREROhgEgERERkZNhAEhERETkZBgAEhERETkZBoBEREREToYBIBEREZGTYQBIRERE5GQYABIRERE5GQaARERERE6GASARERGRk2EASERERORkGAASERERORkGgEREREROhgEgERERkZNhAEhERETkZBgAEhERETkZBoBEREREToYBIFETXFxc8Nhjj6GruPLKK9GtW7cTuu/EiRPVQs0nx44cQy25bUFBQZuWwZ6f2+LFi9VrknVbHINNkceTxz2WAwcOqLK88MILbfa8H3/8sXpMeWyizogBILWrrVu34rzzzkNiYiK8vLwQGxuLU045Ba+//rq9i0Z29NZbb6kTaEtO8nKybbjceOONzQ5Evv/++3r7a2trccYZZ8DV1RUffvghOsLTTz+Nn376CZ1BZyorEbWc5gTuQ9QsK1aswKRJk5CQkIDrrrsOUVFRyMjIwKpVq/Dqq6/i1ltvtXcRyY4BYFhY2HEzN7YGDRqEu+++u96+nj17ntDz63Q69cNk7ty5eP/993H11VejrT388MN44IEHjgqq5HlnzpwJR9faso4fPx5VVVXw8PBo87IRUesxAKR289RTTyEwMBBr165FUFBQvevy8vLsVi7qnCR7/K9//avVjyPB3wUXXIDffvsN7777Lq655hq0B41GoxZnJZlVyfoTkWNiFTC1m7S0NPTt2/eo4E9ERETUu/zRRx9h8uTJar+npyf6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X4SO5OLt3SaTbmdmZmL69OkqSPr000+xa9cuXHfddfDy8qoXrH3yySe46aabsHz5cnW5pKQEkydPxrXXXouXX34ZVVVVuP/++3HBBRdg4cKF9e531113YfXq1Vi5cqV6nrFjx+KUU07B2rVrERERgY8++gjTpk1T2T0h+yWwE7I+77zz4O7eeA8zo9GIuLg4fPfddyqwW7FiBa6//noV6ElZLBYtWqT2yXrfvn248MILMWjQIPVaiYjo+BbtMmf/JnQPQ/Zqc/u/+N4MAB2J0waAEixI0PL5558jJycHMTExKuB4+OGH2yRYaowEf7uHDEVH67VhPVx8zF3wW+Ott95S7ereeOMN9R6lpqYiKytLBXP/+c9/4OpqTiinpKTgueees97vv//9LwYPHoynn37auu/DDz9Uj7Vnzx707NlT7RswYAAeffRR62PI8yxYsEAFgOHh4Wp/UFCQyg5aWPaL22+/XbX5k6CwMRIYPv7449bLkgmUQPPbb7+tFwAGBwer55YgU17j6aefrsrBAJCIqGXDv4wO8EWRrgS+QZ4IifG1d7HIhtMGgM8++yzefvttlXXq27cv1q1bh6uuugqBgYGqKpKOtnPnTowePbpegCwZuvLychw+fBgJCQlq39Ch9YPczZs3q2yaVP82lJaWVi8AtCVZuLw88x+R43nvvffwwQcfqKyebVDY0JtvvqmCz0OHDqlMpLRRlOyeLTkeLBlGSzm2bt3arHIQETm7XG21mgFEThVh5SYUSfavT0i7JVfoxDhtACiBwowZM1R2x9KW7KuvvsKaNWvatSpWsnEdTZ63I/n61v+VJwHimWeeqYLuhiS4smhYdSt/LKTa9ngkuLz11lvV59cwiLT19ddf45577sGLL76oAll/f388//zzqsrZ1omWg4iIgMV12b8BcUEo2Geu/mX7P8fjtAHgmDFjVNbIUgUpWaply5bhpZdearfnVB0U2qAq1l569+6NH374QbVltPySk3Z+EkhJ27qmDBkyRN1PguzW9MiVwMzS3s9C2uhJu7+HHnoI55xzzjHvL2WVz/3mm2+ul4EkIqK2b/83OSEERVuzARfO/+uInLYXsPReveiii1QbLwkspI2a9Fy99NJLm7xPTU0NtFptvaWrKi0tVb1nbRfpMJGRkaGybdIB5Oeff1Zt9qTjhqX9X2OkF21RUREuvvhi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ldwxQSd1bU4fAJaXl+PSSy/F+++/j+DgYHsXh4jIqX2//jD251eoDhgyXy8B+loDttUN/SLZPw79Qm3B6QPAW265BaeffjpOPvlkexeFiMipyawbr/y9V23fMqmHGpOPoGb9qC7XqSnfkgeF2bs41EU4dRvAr7/+Ghs2bFBVwM1RU1OjFgutVtuOpSMici6frDiAHG216nV76Ui2c7MM/Lzpb3Pnj4FT4uHq5vR5G2ojTnskZWRkqA4fX3zxBby8mjco5+zZsxEYGGhd4uPj272cRETOQObJffef/Wr7jpNT4OXOMe4sAz+X5FbCw8sNvce03zR45HycNgBcv3498vLyMGTIEGg0GrUsWbIEr732mto2GI6eAFx6CZeWlloXCSKJiKj1vlx9CEUVtUgI8cHZgznGncWmvw+pdZ9xsfDwdupKO2pjTns0TZkyBVu3bq2376qrrkJqairuv/9+uLkd/evT09NTLURE1LZt/96ry/7dPLE7NKzmVPIPlSFzdwlcXF3UvL9EbclpA0B/f3/061d/YnFfX1+EhoYetZ+IiNrPt+sykFdWg5hAL5wzhIGOxYb5B9W6x9AI1QGEqC3xZxYREdlNrd6Idxanqe0bJ3aHh4anJSHt/tI25KntIVPZIYbantNmABuzePFiexeBiMipzNlwGFml1WrA5wuGsWOdxca/DsFkAhL7hSIszt/exaEuiD+1iIjIbrN+vFWX/bthfDJ7/tapKKnBrlXZanvItER7F4e6KAaARERkF79szsKhoko168clHPevXs9fo96E6B6BiOkRZO/iUBfFAJCIiDqcwWjCm4v2qe1rTkqCjwdbJInqCh22Lc1S20OmMvtH7YcBIBERdbg/tmUjLb8CAV4aXD6agY7F1sWHoa8xIDTOT7X/I2ovDACJiKhDGY0mvLHQnP27amwS5/yto6sxYMvCw2p76NREuLi42LtI1IUxACQiog71985c7Mopg5+nBlePTbJ3cRzGjmVZqgo4INwb3YeE27s41MUxACQiog5jMpnwel32T6p+A32Y/RMGnVEN/SKGnJoAV86GQu2MRxgREXWYJXvysTWzFN7ubqrzB5ntWJ6lhn/xDfJE6qhoexeHnAADQCIi6vDs36UjExDqx7nVLdm/9fPM074NnZYIN3eemqn98SgjIqIOsTKtEOsPFqvp3q4fn2zv4jhk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", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "sample_model=SampleModel(name='sample_model')\n", "sample_model.temperature=5\n", @@ -173,63 +96,6 @@ "plt.title('Sample model at 5 K with detailed balance')\n", "plt.show()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3f43ec31", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Gaussian(name = Gaussian, unit = meV,\n", - " area = ,\n", - " center = ,\n", - " width = ),\n", - " DampedHarmonicOscillator(name = DHO, unit = meV,\n", - " area = ,\n", - " center = ,\n", - " width = ),\n", - " Lorentzian(name = Lorentzian, unit = meV,\n", - " area = ,\n", - " center = ,\n", - " width = ),\n", - " Polynomial(name = Polynomial, unit = meV,\n", - " coefficients = [Polynomial_c0=0.1, Polynomial_c1=0.0, Polynomial_c2=0.5])]" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "list(sample_model)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "2e6c7f35", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "list" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# sample_model.remove_component('Polynomial')\n", - "type(list(sample_model))" - ] } ], "metadata": { From 07c070ae49823fb8ccb2a787f799937e38073441 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Tue, 28 Oct 2025 15:07:38 +0100 Subject: [PATCH 12/71] Update to new ModelComponent --- examples/sample_model.ipynb | 39 --- src/easydynamics/sample_model/sample_model.py | 281 ++-------------- .../sample_model/test_sample_model.py | 308 ++++++++---------- 3 files changed, 165 insertions(+), 463 deletions(-) diff --git a/examples/sample_model.ipynb b/examples/sample_model.ipynb index 5808e53..1b86e7d 100644 --- a/examples/sample_model.ipynb +++ b/examples/sample_model.ipynb @@ -57,45 +57,6 @@ "plt.legend()\n", "plt.show()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ac7061fd", - "metadata": {}, - "outputs": [], - "source": [ - "sample_model=SampleModel(name='sample_model')\n", - "sample_model.temperature=5\n", - "sample_model.use_detailed_balance=True\n", - "sample_model.normalise_detailed_balance=True\n", - "\n", - "# Creating components\n", - "gaussian=Gaussian(name='Gaussian',width=0.5,area=1)\n", - "dho = DampedHarmonicOscillator(name='DHO',center=1.0,width=0.3,area=2.0)\n", - "lorentzian = Lorentzian(name='Lorentzian',center=-1.0,width=0.2,area=1.0)\n", - "polynomial = Polynomial(name='Polynomial',coefficients=[0.1, 0, 0.5]) # y=0.1+0.5*x^2\n", - "\n", - "sample_model.add_component(gaussian)\n", - "sample_model.add_component(dho)\n", - "sample_model.add_component(lorentzian)\n", - "sample_model.add_component(polynomial)\n", - "\n", - "\n", - "x=np.linspace(-2, 2, 100)\n", - "\n", - "plt.figure()\n", - "y=sample_model.evaluate(x)\n", - "plt.plot(x, y, label='Sample Model')\n", - "\n", - "for component in list(sample_model):\n", - " y = sample_model.evaluate_component(x, component.name)\n", - " plt.plot(x, y, label=component.name)\n", - "\n", - "plt.legend()\n", - "plt.title('Sample model at 5 K with detailed balance')\n", - "plt.show()" - ] } ], "metadata": { diff --git a/src/easydynamics/sample_model/sample_model.py b/src/easydynamics/sample_model/sample_model.py index b16dbd3..aa8ba04 100644 --- a/src/easydynamics/sample_model/sample_model.py +++ b/src/easydynamics/sample_model/sample_model.py @@ -1,6 +1,4 @@ import warnings -from copy import copy -from itertools import chain from typing import List, Optional, Union import numpy as np @@ -8,10 +6,6 @@ from easyscience.base_classes import CollectionBase from easyscience.global_object.undo_redo import NotarizedDict from easyscience.job.theoreticalmodel import TheoreticalModelBase -from easyscience.variable import Parameter -from scipp import UnitError - -from easydynamics.utils import _detailed_balance_factor as detailed_balance_factor from .components.model_component import ModelComponent @@ -21,16 +15,9 @@ class SampleModel(CollectionBase, TheoreticalModelBase): """ A model of the scattering from a sample, combining multiple model components. - Optionally applies detailed balancing. Attributes ---------- - temperature : Parameter - Temperature parameter for detailed balance. - use_detailed_balance : bool - Whether to apply detailed balance. - normalize_detailed_balance : bool - Whether to normalize the detailed balance by temperature. name : str Name of the SampleModel. unit : str or sc.Unit @@ -44,8 +31,7 @@ def __init__( self, name: str = "MySampleModel", unit: Optional[Union[str, sc.Unit]] = "meV", - temperature: Optional[Union[Numeric, sc.Variable]] = None, - temperature_unit: Optional[str] = "K", + data: Optional[List] = None, ): """ Initialize a new SampleModel. @@ -54,10 +40,10 @@ def __init__( ---------- name : str Name of the sample model. - temperature : Number, sc.Variable or None, optional - Temperature for detailed balance. - temperature_unit : str, default 'K' - Unit of the temperature. + unit : str or sc.Unit, optional + Unit of the sample model. Defaults to "meV". + data : List[ModelComponent], optional + Initial list of model components to include in the sample model. """ CollectionBase.__init__(self, name=name) @@ -65,28 +51,17 @@ def __init__( if not isinstance(self._kwargs, NotarizedDict): self._kwargs = NotarizedDict() - # If temperature is given, create a Parameter and enable detailed balance. - if temperature is None: - self._temperature = None - self._use_detailed_balance = False - elif isinstance(temperature, sc.Variable): - self._temperature = Parameter( - name="temperature", - value=temperature.value, - unit=temperature.unit, - fixed=True, - ) - else: - self._temperature = Parameter( - name="temperature", value=temperature, unit=temperature_unit, fixed=True - ) - self._use_detailed_balance = True - - self._normalize_detailed_balance = ( - True # Whether to normalize by temperature when using detailed balance. - ) self._unit = unit + if data: + # clear any accidental pre-populated items (defensive) + self.clear_components() + for item in data: + # ensure item is a ModelComponent + if not isinstance(item, ModelComponent): + raise TypeError("Data items must be instances of ModelComponent.") + self.insert(index=len(self), value=item) + ############################################## # Methods for managing components # ############################################## @@ -174,15 +149,6 @@ def normalize_area(self) -> None: for param in area_params: param.value /= total_area - def convert_unit(self, unit: Union[str, sc.Unit]): - """ - Convert the unit of the SampleModel and all its components. - """ - self._unit = unit - # for component in self.components.values(): - for component in list(self): - component.convert_unit(unit) - @property def components(self) -> List[ModelComponent]: """ @@ -214,118 +180,14 @@ def unit(self, unit_str: str) -> None: ) ) # noqa: E501 - ########################################################## - # Methods for temperature and detailed balance # - ########################################################## - - @property - def temperature(self) -> Optional[Parameter]: - """ - Get the temperature. - - Returns - ------- - Parameter - """ - return self._temperature - - @temperature.setter - def temperature(self, value: Optional[Numeric]) -> None: - """ - Set the temperature. - - Parameters - ---------- - value : Number - Temperature value. If None, removes temperature and disables detailed balance. - """ - # If None, disable detailed balance and remove temperature parameter. - if value is None: - self._use_detailed_balance = False - self._temperature = None - return - - if not isinstance(value, Numeric): - raise TypeError("Temperature must be a number or None.") - value = float(value) - - if value < 0: - raise ValueError("Temperature must be non-negative.") - - if isinstance(self._temperature, Parameter): - self._temperature.value = value - else: - self._temperature = Parameter( - name="temperature", value=value, unit="K", fixed=True - ) - - def convert_temperature_unit(self, new_unit: Union[str, sc.Unit]) -> None: - """ - Convert the temperature parameter to a new unit. - - Parameters - ---------- - new_unit : str or sc.Unit - The new unit for the temperature. - """ - if self._temperature is None: - raise ValueError("Temperature is not set; cannot convert units.") - - try: - self._temperature.convert_unit(new_unit) - except UnitError as e: - raise UnitError(f"Failed to convert temperature to unit '{new_unit}': {e}") - except Exception as e: - raise RuntimeError(f"An error occurred during unit conversion: {e}") - - @property - def use_detailed_balance(self) -> bool: - """ - True if detailed balance is enabled, otherwise False. - - Returns - ------- - bool - """ - return self._use_detailed_balance - - @use_detailed_balance.setter - def use_detailed_balance(self, value: bool) -> None: - """ - If True, enables the use of detailed balance. Otherwise disables it. - - Parameters - ---------- - value : bool - True to enable, False to disable. - """ - if self._temperature is None: - raise ValueError("Temperature must be set to use detailed balance.") - self._use_detailed_balance = value - - @property - def normalize_detailed_balance(self) -> bool: - """ - If True, detailed balance will be normalized by temperature. If False, it will not be normalized. - - """ - return self._normalize_detailed_balance - - @normalize_detailed_balance.setter - def normalize_detailed_balance(self, value: bool) -> None: + def convert_unit(self, unit: Union[str, sc.Unit]) -> None: """ - If True, normalizes the detailed balance by temperature. - - Parameters - ---------- - value : bool - True to normalize, False otherwise. + Convert the unit of the SampleModel and all its components. """ - self._normalize_detailed_balance = value - - ########################################################## - # Evaluate # - ########################################################## + self._unit = unit + # for component in self.components.values(): + for component in list(self): + component.convert_unit(unit) def evaluate( self, x: Union[Numeric, list, np.ndarray, sc.Variable, sc.DataArray] @@ -351,17 +213,6 @@ def evaluate( value = component.evaluate(x) result = value if result is None else result + value - if ( - self.use_detailed_balance - and self._temperature is not None - and self._temperature.value >= 0 - ): - result *= detailed_balance_factor( - energy=x, - temperature=self._temperature, - divide_by_temperature=self._normalize_detailed_balance, - ) - return result def evaluate_component( @@ -399,58 +250,9 @@ def evaluate_component( component = matches[0] result = component.evaluate(x) - if ( - self.use_detailed_balance - and self._temperature is not None - and self._temperature.value >= 0 - ): - result *= detailed_balance_factor( - energy=x, - temperature=self._temperature, - divide_by_temperature=self._normalize_detailed_balance, - ) return result - ############################################## - # Methods for managing parameters # - ############################################## - - def get_parameters(self) -> List[Parameter]: - """ - Return all parameters in the SampleModel. - - Returns - ------- - List[Parameter] - """ - # Create generator for temperature parameter - temp_params = (self._temperature,) if self._temperature is not None else () - - # Create generator for component parameters - comp_params = (param for comp in list(self) for param in comp.get_parameters()) - - # Chain them together and return as list - return list(chain(temp_params, comp_params)) - - def get_fit_parameters(self) -> List[Parameter]: - """ - Get all fit parameters, removing fixed and dependent parameters. - - Returns: - List[Parameter]: A list of fit parameters. - """ - - def is_fit_parameter(param: Parameter) -> bool: - """Check if a parameter can be used for fitting.""" - return not getattr(param, "fixed", False) and getattr( - param, "_independent", True - ) - - return [param for param in self.get_parameters() if is_fit_parameter(param)] - - # return fit_parameters - def fix_all_parameters(self) -> None: """ Fix all free parameters in the model. @@ -465,39 +267,6 @@ def free_all_parameters(self) -> None: for param in self.get_parameters(): param.fixed = False - ############################################## - # dunder methods # - ############################################## - - def __copy__(self) -> "SampleModel": - """ - Create a deep copy of the SampleModel with independent parameters. - - Returns - ------- - SampleModel - A new instance with copied components and parameters. - """ - name = "copy of " + self.name - - new_model = SampleModel( - name=name, - temperature=self._temperature.value if self._temperature else None, - unit=self.unit, - ) - - if self._temperature: - new_model.use_detailed_balance = self.use_detailed_balance - new_model.normalize_detailed_balance = self.normalize_detailed_balance - - for comp in list(self): - new_model.add_component(component=copy(comp), name=comp.name) - new_model[comp.name].name = comp.name # Remove 'copy of ' prefix - for par in new_model[comp.name].get_parameters(): - par.name = par.name.removeprefix("copy of ") - - return new_model - def __repr__(self) -> str: """ Return a string representation of the SampleModel. @@ -508,12 +277,4 @@ def __repr__(self) -> str: """ comp_names = ", ".join(c.name for c in self) or "No components" - temp_str = "" - if ( - getattr(self, "_use_detailed_balance", False) - and getattr(self, "_temperature", None) is not None - ): - temp = self._temperature - temp_str = f" | Temperature: {temp.value} {temp.unit}" - - return f"" + return f"" diff --git a/tests/unit_tests/sample_model/test_sample_model.py b/tests/unit_tests/sample_model/test_sample_model.py index 26a946a..cfc1458 100644 --- a/tests/unit_tests/sample_model/test_sample_model.py +++ b/tests/unit_tests/sample_model/test_sample_model.py @@ -3,11 +3,9 @@ import numpy as np import pytest from easyscience.variable import Parameter -from scipp import UnitError from scipy.integrate import simpson from easydynamics.sample_model import Gaussian, Lorentzian, Polynomial, SampleModel -from easydynamics.utils import _detailed_balance_factor as detailed_balance_factor class TestSampleModel: @@ -24,22 +22,30 @@ def sample_model(self): model.add_component(component2) return model - def test_init_no_temperature(self, sample_model): - # WHEN THEN EXPECT - assert sample_model.name == "TestSampleModel" - assert len(sample_model.components) == 2 - assert not sample_model.use_detailed_balance - - def test_init_with_temperature(self): + def test_init(self): # WHEN THEN - sample_model = SampleModel(name="TempModel", temperature=100) + sample_model = SampleModel(name="InitModel") # EXPECT - assert sample_model.name == "TempModel" + assert sample_model.name == "InitModel" assert len(sample_model.components) == 0 - assert sample_model.use_detailed_balance - assert isinstance(sample_model.temperature, Parameter) - assert sample_model.temperature.value == 100 + + # def test_init_no_temperature(self, sample_model): + # # WHEN THEN EXPECT + # assert sample_model.name == "TestSampleModel" + # assert len(sample_model.components) == 2 + # assert not sample_model.use_detailed_balance + + # def test_init_with_temperature(self): + # # WHEN THEN + # sample_model = SampleModel(name="TempModel", temperature=100) + + # # EXPECT + # assert sample_model.name == "TempModel" + # assert len(sample_model.components) == 0 + # assert sample_model.use_detailed_balance + # assert isinstance(sample_model.temperature, Parameter) + # assert sample_model.temperature.value == 100 # ───── Component Management ───── @@ -113,76 +119,76 @@ def test_convert_unit(self, sample_model): for component in list(sample_model): assert component.unit == "eV" - # ───── Temperature and Detailed Balance ───── - - def test_set_temperature(self, sample_model): - # Set valid temperature - # WHEN THEN - sample_model.temperature = 300 - # EXPECT - assert sample_model.temperature.value == 300 - assert sample_model.temperature.unit == "K" - - # WHEN THEN - sample_model.temperature = 150.0 - # EXPECT - assert sample_model.temperature.value == 150.0 - assert sample_model.temperature.unit == "K" - - # Set temperature to None - # WHEN THEN - sample_model.temperature = None - # EXPECT - assert sample_model.temperature is None - assert not sample_model.use_detailed_balance - - def test_invalid_temperature_raises(self, sample_model): - # WHEN THEN EXPECT - with pytest.raises(TypeError, match="Temperature must be a number or None."): - sample_model.temperature = "invalid" - - def test_negative_temperature_raises(self, sample_model): - # WHEN THEN EXPECT - with pytest.raises(ValueError, match="Temperature must be non-negative"): - sample_model.temperature = -50 - - def test_convert_temperature_unit(self, sample_model): - # WHEN - sample_model.temperature = 300 # Kelvin - # THEN - sample_model.convert_temperature_unit("mK") - # EXPECT - assert np.isclose(sample_model.temperature.value, 300000.0) - assert sample_model.temperature.unit == "mK" - - def test_convert_temperature_unit_incompatible_unit_raises(self, sample_model): - # WHEN - sample_model.temperature = 300 # Kelvin - # THEN EXPECT - with pytest.raises(UnitError, match="Failed to convert temperature"): - sample_model.convert_temperature_unit("m") - - def test_convert_temperature_unit_no_temperature_raises(self, sample_model): - # WHEN THEN EXPECT - with pytest.raises(ValueError, match="cannot convert units"): - sample_model.convert_temperature_unit("mK") - - def test_use_detailed_balance(self, sample_model): - sample_model.temperature = 300 - # WHEN THEN EXPECT - assert sample_model.use_detailed_balance is False - sample_model.use_detailed_balance = True - assert sample_model.use_detailed_balance is True - sample_model.use_detailed_balance = False - assert sample_model.use_detailed_balance is False - - def test_use_detailed_balance_no_temperature_raises(self, sample_model): - # WHEN THEN EXPECT - with pytest.raises( - ValueError, - match="Temperature must be set to use detailed balance.", - ): - sample_model.use_detailed_balance = True + # # ───── Temperature and Detailed Balance ───── + + # def test_set_temperature(self, sample_model): + # # Set valid temperature + # # WHEN THEN + # sample_model.temperature = 300 + # # EXPECT + # assert sample_model.temperature.value == 300 + # assert sample_model.temperature.unit == "K" + + # # WHEN THEN + # sample_model.temperature = 150.0 + # # EXPECT + # assert sample_model.temperature.value == 150.0 + # assert sample_model.temperature.unit == "K" + + # # Set temperature to None + # # WHEN THEN + # sample_model.temperature = None + # # EXPECT + # assert sample_model.temperature is None + # assert not sample_model.use_detailed_balance + + # def test_invalid_temperature_raises(self, sample_model): + # # WHEN THEN EXPECT + # with pytest.raises(TypeError, match="Temperature must be a number or None."): + # sample_model.temperature = "invalid" + + # def test_negative_temperature_raises(self, sample_model): + # # WHEN THEN EXPECT + # with pytest.raises(ValueError, match="Temperature must be non-negative"): + # sample_model.temperature = -50 + + # def test_convert_temperature_unit(self, sample_model): + # # WHEN + # sample_model.temperature = 300 # Kelvin + # # THEN + # sample_model.convert_temperature_unit("mK") + # # EXPECT + # assert np.isclose(sample_model.temperature.value, 300000.0) + # assert sample_model.temperature.unit == "mK" + + # def test_convert_temperature_unit_incompatible_unit_raises(self, sample_model): + # # WHEN + # sample_model.temperature = 300 # Kelvin + # # THEN EXPECT + # with pytest.raises(UnitError, match="Failed to convert temperature"): + # sample_model.convert_temperature_unit("m") + + # def test_convert_temperature_unit_no_temperature_raises(self, sample_model): + # # WHEN THEN EXPECT + # with pytest.raises(ValueError, match="cannot convert units"): + # sample_model.convert_temperature_unit("mK") + + # def test_use_detailed_balance(self, sample_model): + # sample_model.temperature = 300 + # # WHEN THEN EXPECT + # assert sample_model.use_detailed_balance is False + # sample_model.use_detailed_balance = True + # assert sample_model.use_detailed_balance is True + # sample_model.use_detailed_balance = False + # assert sample_model.use_detailed_balance is False + + # def test_use_detailed_balance_no_temperature_raises(self, sample_model): + # # WHEN THEN EXPECT + # with pytest.raises( + # ValueError, + # match="Temperature must be set to use detailed balance.", + # ): + # sample_model.use_detailed_balance = True # ───── Evaluation ───── @@ -196,30 +202,30 @@ def test_evaluate(self, sample_model): ].evaluate(x) np.testing.assert_allclose(result, expected_result, rtol=1e-5) - @pytest.mark.parametrize( - "normalize_db", [True, False], ids=["normalize DB", "Don't normalize DB"] - ) - def test_evaluate_with_detailed_balance(self, sample_model, normalize_db): - # WHEN - sample_model.temperature = 300 - sample_model.use_detailed_balance = True - sample_model.normalize_detailed_balance = normalize_db - - x = np.linspace(-5, 5, 100) - - # THEN - result = sample_model.evaluate(x) - - # EXPECT - expected_result = sample_model["TestGaussian1"].evaluate(x) + sample_model[ - "TestLorentzian1" - ].evaluate(x) - expected_result *= detailed_balance_factor( - energy=x, - temperature=sample_model.temperature, - divide_by_temperature=normalize_db, - ) - np.testing.assert_allclose(result, expected_result, rtol=1e-5) + # @pytest.mark.parametrize( + # "normalize_db", [True, False], ids=["normalize DB", "Don't normalize DB"] + # ) + # def test_evaluate_with_detailed_balance(self, sample_model, normalize_db): + # # WHEN + # sample_model.temperature = 300 + # sample_model.use_detailed_balance = True + # sample_model.normalize_detailed_balance = normalize_db + + # x = np.linspace(-5, 5, 100) + + # # THEN + # result = sample_model.evaluate(x) + + # # EXPECT + # expected_result = sample_model["TestGaussian1"].evaluate(x) + sample_model[ + # "TestLorentzian1" + # ].evaluate(x) + # expected_result *= detailed_balance_factor( + # energy=x, + # temperature=sample_model.temperature, + # divide_by_temperature=normalize_db, + # ) + # np.testing.assert_allclose(result, expected_result, rtol=1e-5) def test_evaluate_no_components_raises(self): # WHEN THEN @@ -241,35 +247,35 @@ def test_evaluate_component(self, sample_model): np.testing.assert_allclose(result1, expected_result1, rtol=1e-5) np.testing.assert_allclose(result2, expected_result2, rtol=1e-5) - @pytest.mark.parametrize( - "normalize_db", [True, False], ids=["normalize DB", "Don't normalize DB"] - ) - def test_evaluate_component_with_detailed_balance(self, sample_model, normalize_db): - # WHEN - sample_model.temperature = 300 - sample_model.use_detailed_balance = True - sample_model.normalize_detailed_balance = normalize_db - - # THEN - x = np.linspace(-5, 5, 100) - result1 = sample_model.evaluate_component(x, name="TestGaussian1") - result2 = sample_model.evaluate_component(x, name="TestLorentzian1") - - # EXPECT - expected_result1 = sample_model["TestGaussian1"].evaluate(x) - expected_result2 = sample_model["TestLorentzian1"].evaluate(x) - expected_result1 *= detailed_balance_factor( - energy=x, - temperature=sample_model.temperature, - divide_by_temperature=normalize_db, - ) - expected_result2 *= detailed_balance_factor( - energy=x, - temperature=sample_model.temperature, - divide_by_temperature=normalize_db, - ) - np.testing.assert_allclose(result1, expected_result1, rtol=1e-5) - np.testing.assert_allclose(result2, expected_result2, rtol=1e-5) + # @pytest.mark.parametrize( + # "normalize_db", [True, False], ids=["normalize DB", "Don't normalize DB"] + # ) + # def test_evaluate_component_with_detailed_balance(self, sample_model, normalize_db): + # # WHEN + # sample_model.temperature = 300 + # sample_model.use_detailed_balance = True + # sample_model.normalize_detailed_balance = normalize_db + + # # THEN + # x = np.linspace(-5, 5, 100) + # result1 = sample_model.evaluate_component(x, name="TestGaussian1") + # result2 = sample_model.evaluate_component(x, name="TestLorentzian1") + + # # EXPECT + # expected_result1 = sample_model["TestGaussian1"].evaluate(x) + # expected_result2 = sample_model["TestLorentzian1"].evaluate(x) + # expected_result1 *= detailed_balance_factor( + # energy=x, + # temperature=sample_model.temperature, + # divide_by_temperature=normalize_db, + # ) + # expected_result2 *= detailed_balance_factor( + # energy=x, + # temperature=sample_model.temperature, + # divide_by_temperature=normalize_db, + # ) + # np.testing.assert_allclose(result1, expected_result1, rtol=1e-5) + # np.testing.assert_allclose(result2, expected_result2, rtol=1e-5) def test_evaluate_nonexistent_component_raises(self, sample_model): # WHEN @@ -344,16 +350,6 @@ def test_get_parameters(self, sample_model): assert actual_names == expected_names assert all(isinstance(param, Parameter) for param in parameters) - # WHEN - sample_model.temperature = 300 - # THEN - parameters = sample_model.get_parameters() - # EXPECT - assert len(parameters) == 7 - expected_names.add("temperature") - actual_names = {param.name for param in parameters} - assert actual_names == expected_names - def test_get_parameters_no_components(self): sample_model = SampleModel(name="EmptyModel") # WHEN THEN @@ -361,13 +357,6 @@ def test_get_parameters_no_components(self): # EXPECT assert len(parameters) == 0 - # WHEN THEN - sample_model.temperature = 300 - parameters = sample_model.get_parameters() - # EXPECT - assert len(parameters) == 1 - assert parameters[0].name == "temperature" - def test_get_fit_parameters(self, sample_model): # WHEN @@ -422,17 +411,8 @@ def test_copy(self, sample_model): model_copy = copy(sample_model) # EXPECT assert model_copy is not sample_model - assert model_copy.name == "copy of " + sample_model.name + assert model_copy.name == sample_model.name assert len(list(model_copy)) == len(list(sample_model)) - assert model_copy.temperature is not sample_model.temperature - assert model_copy.temperature.name == sample_model.temperature.name - assert model_copy.temperature.value == sample_model.temperature.value - assert model_copy.temperature.unit == sample_model.temperature.unit - assert model_copy.use_detailed_balance == sample_model.use_detailed_balance - assert ( - model_copy.normalize_detailed_balance - == sample_model.normalize_detailed_balance - ) for comp in list(sample_model): copied_comp = model_copy[comp.name] assert copied_comp is not comp From 3a7187c4df1bcf6ca15faa8cdefcf677db368e32 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Tue, 28 Oct 2025 20:19:56 +0100 Subject: [PATCH 13/71] Cleanup and a few tests --- examples/sample_model.ipynb | 65 ++++++- src/easydynamics/sample_model/sample_model.py | 9 +- .../sample_model/test_sample_model.py | 180 ++++-------------- 3 files changed, 102 insertions(+), 152 deletions(-) diff --git a/examples/sample_model.ipynb b/examples/sample_model.ipynb index 1b86e7d..732fa86 100644 --- a/examples/sample_model.ipynb +++ b/examples/sample_model.ipynb @@ -25,10 +25,36 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "784d9e82", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d473593b3aa14baf8f8c4dd432169d44", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "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", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "sample_model=SampleModel(name='sample_model')\n", "\n", @@ -57,6 +83,41 @@ "plt.legend()\n", "plt.show()" ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "d35179d8", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Gaussian(name = Gaussian, unit = meV,\n", + " area = ,\n", + " center = ,\n", + " width = ),\n", + " DampedHarmonicOscillator(name = DHO, unit = meV,\n", + " area = ,\n", + " center = ,\n", + " width = ),\n", + " Lorentzian(name = Lorentzian, unit = meV,\n", + " area = ,\n", + " center = ,\n", + " width = ),\n", + " Polynomial(name = Polynomial, unit = meV,\n", + " coefficients = [Polynomial_c0=0.1, Polynomial_c1=0.0, Polynomial_c2=0.5])]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# sample_model=SampleModel(name='sample_model')\n", + "sample_model.components" + ] } ], "metadata": { diff --git a/src/easydynamics/sample_model/sample_model.py b/src/easydynamics/sample_model/sample_model.py index aa8ba04..8a9dd13 100644 --- a/src/easydynamics/sample_model/sample_model.py +++ b/src/easydynamics/sample_model/sample_model.py @@ -53,8 +53,9 @@ def __init__( self._unit = unit + # Add initial components if provided. Mostly used for serialization. if data: - # clear any accidental pre-populated items (defensive) + # Just to be safe self.clear_components() for item in data: # ensure item is a ModelComponent @@ -62,10 +63,6 @@ def __init__( raise TypeError("Data items must be instances of ModelComponent.") self.insert(index=len(self), value=item) - ############################################## - # Methods for managing components # - ############################################## - def add_component( self, component: ModelComponent, name: Optional[str] = None ) -> None: @@ -221,7 +218,7 @@ def evaluate_component( name: str, ) -> np.ndarray: """ - Evaluate a single component by name, optionally applying detailed balance. + Evaluate a single component by name. Parameters ---------- diff --git a/tests/unit_tests/sample_model/test_sample_model.py b/tests/unit_tests/sample_model/test_sample_model.py index cfc1458..19d1042 100644 --- a/tests/unit_tests/sample_model/test_sample_model.py +++ b/tests/unit_tests/sample_model/test_sample_model.py @@ -30,22 +30,23 @@ def test_init(self): assert sample_model.name == "InitModel" assert len(sample_model.components) == 0 - # def test_init_no_temperature(self, sample_model): - # # WHEN THEN EXPECT - # assert sample_model.name == "TestSampleModel" - # assert len(sample_model.components) == 2 - # assert not sample_model.use_detailed_balance - - # def test_init_with_temperature(self): - # # WHEN THEN - # sample_model = SampleModel(name="TempModel", temperature=100) - - # # EXPECT - # assert sample_model.name == "TempModel" - # assert len(sample_model.components) == 0 - # assert sample_model.use_detailed_balance - # assert isinstance(sample_model.temperature, Parameter) - # assert sample_model.temperature.value == 100 + def test_initialization_with_components(self): + # WHEN THEN + component1 = Gaussian( + name="InitGaussian", area=1.0, center=0.0, width=1.0, unit="meV" + ) + component2 = Lorentzian( + name="InitLorentzian", area=2.0, center=1.0, width=0.5, unit="meV" + ) + sample_model = SampleModel( + name="InitModelWithComponents", data=[component1, component2] + ) + + # EXPECT + assert sample_model.name == "InitModelWithComponents" + assert len(sample_model.components) == 2 + assert sample_model["InitGaussian"] is component1 + assert sample_model["InitLorentzian"] is component2 # ───── Component Management ───── @@ -119,79 +120,6 @@ def test_convert_unit(self, sample_model): for component in list(sample_model): assert component.unit == "eV" - # # ───── Temperature and Detailed Balance ───── - - # def test_set_temperature(self, sample_model): - # # Set valid temperature - # # WHEN THEN - # sample_model.temperature = 300 - # # EXPECT - # assert sample_model.temperature.value == 300 - # assert sample_model.temperature.unit == "K" - - # # WHEN THEN - # sample_model.temperature = 150.0 - # # EXPECT - # assert sample_model.temperature.value == 150.0 - # assert sample_model.temperature.unit == "K" - - # # Set temperature to None - # # WHEN THEN - # sample_model.temperature = None - # # EXPECT - # assert sample_model.temperature is None - # assert not sample_model.use_detailed_balance - - # def test_invalid_temperature_raises(self, sample_model): - # # WHEN THEN EXPECT - # with pytest.raises(TypeError, match="Temperature must be a number or None."): - # sample_model.temperature = "invalid" - - # def test_negative_temperature_raises(self, sample_model): - # # WHEN THEN EXPECT - # with pytest.raises(ValueError, match="Temperature must be non-negative"): - # sample_model.temperature = -50 - - # def test_convert_temperature_unit(self, sample_model): - # # WHEN - # sample_model.temperature = 300 # Kelvin - # # THEN - # sample_model.convert_temperature_unit("mK") - # # EXPECT - # assert np.isclose(sample_model.temperature.value, 300000.0) - # assert sample_model.temperature.unit == "mK" - - # def test_convert_temperature_unit_incompatible_unit_raises(self, sample_model): - # # WHEN - # sample_model.temperature = 300 # Kelvin - # # THEN EXPECT - # with pytest.raises(UnitError, match="Failed to convert temperature"): - # sample_model.convert_temperature_unit("m") - - # def test_convert_temperature_unit_no_temperature_raises(self, sample_model): - # # WHEN THEN EXPECT - # with pytest.raises(ValueError, match="cannot convert units"): - # sample_model.convert_temperature_unit("mK") - - # def test_use_detailed_balance(self, sample_model): - # sample_model.temperature = 300 - # # WHEN THEN EXPECT - # assert sample_model.use_detailed_balance is False - # sample_model.use_detailed_balance = True - # assert sample_model.use_detailed_balance is True - # sample_model.use_detailed_balance = False - # assert sample_model.use_detailed_balance is False - - # def test_use_detailed_balance_no_temperature_raises(self, sample_model): - # # WHEN THEN EXPECT - # with pytest.raises( - # ValueError, - # match="Temperature must be set to use detailed balance.", - # ): - # sample_model.use_detailed_balance = True - - # ───── Evaluation ───── - def test_evaluate(self, sample_model): # WHEN x = np.linspace(-5, 5, 100) @@ -202,31 +130,6 @@ def test_evaluate(self, sample_model): ].evaluate(x) np.testing.assert_allclose(result, expected_result, rtol=1e-5) - # @pytest.mark.parametrize( - # "normalize_db", [True, False], ids=["normalize DB", "Don't normalize DB"] - # ) - # def test_evaluate_with_detailed_balance(self, sample_model, normalize_db): - # # WHEN - # sample_model.temperature = 300 - # sample_model.use_detailed_balance = True - # sample_model.normalize_detailed_balance = normalize_db - - # x = np.linspace(-5, 5, 100) - - # # THEN - # result = sample_model.evaluate(x) - - # # EXPECT - # expected_result = sample_model["TestGaussian1"].evaluate(x) + sample_model[ - # "TestLorentzian1" - # ].evaluate(x) - # expected_result *= detailed_balance_factor( - # energy=x, - # temperature=sample_model.temperature, - # divide_by_temperature=normalize_db, - # ) - # np.testing.assert_allclose(result, expected_result, rtol=1e-5) - def test_evaluate_no_components_raises(self): # WHEN THEN sample_model = SampleModel(name="EmptyModel") @@ -247,36 +150,6 @@ def test_evaluate_component(self, sample_model): np.testing.assert_allclose(result1, expected_result1, rtol=1e-5) np.testing.assert_allclose(result2, expected_result2, rtol=1e-5) - # @pytest.mark.parametrize( - # "normalize_db", [True, False], ids=["normalize DB", "Don't normalize DB"] - # ) - # def test_evaluate_component_with_detailed_balance(self, sample_model, normalize_db): - # # WHEN - # sample_model.temperature = 300 - # sample_model.use_detailed_balance = True - # sample_model.normalize_detailed_balance = normalize_db - - # # THEN - # x = np.linspace(-5, 5, 100) - # result1 = sample_model.evaluate_component(x, name="TestGaussian1") - # result2 = sample_model.evaluate_component(x, name="TestLorentzian1") - - # # EXPECT - # expected_result1 = sample_model["TestGaussian1"].evaluate(x) - # expected_result2 = sample_model["TestLorentzian1"].evaluate(x) - # expected_result1 *= detailed_balance_factor( - # energy=x, - # temperature=sample_model.temperature, - # divide_by_temperature=normalize_db, - # ) - # expected_result2 *= detailed_balance_factor( - # energy=x, - # temperature=sample_model.temperature, - # divide_by_temperature=normalize_db, - # ) - # np.testing.assert_allclose(result1, expected_result1, rtol=1e-5) - # np.testing.assert_allclose(result2, expected_result2, rtol=1e-5) - def test_evaluate_nonexistent_component_raises(self, sample_model): # WHEN x = np.linspace(-5, 5, 100) @@ -287,6 +160,25 @@ def test_evaluate_nonexistent_component_raises(self, sample_model): ): sample_model.evaluate_component(x, "NonExistentComponent") + def test_evaluate_component_no_components_raises(self): + # WHEN THEN + sample_model = SampleModel(name="EmptyModel") + x = np.linspace(-5, 5, 100) + # EXPECT + with pytest.raises(ValueError, match="No components in the model to evaluate."): + sample_model.evaluate_component(x, "AnyComponent") + + def test_evaluate_component_invalid_name_type_raises(self, sample_model): + # WHEN + x = np.linspace(-5, 5, 100) + + # THEN EXPECT + with pytest.raises( + TypeError, + match="Component name must be a string, got instead.", + ): + sample_model.evaluate_component(x, 123) + # ───── Utilities ───── def test_normalize_area(self, sample_model): From 77c11f68525bda878399ba1bbdee9e1077a2b692 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 29 Oct 2025 18:10:16 +0100 Subject: [PATCH 14/71] First implementation of convolution --- src/easydynamics/utils/__init__.py | 3 +- src/easydynamics/utils/convolution.py | 371 ++++++++++ tests/unit_tests/utils/test_convolution.py | 786 +++++++++++++++++++++ 3 files changed, 1159 insertions(+), 1 deletion(-) create mode 100644 src/easydynamics/utils/convolution.py create mode 100644 tests/unit_tests/utils/test_convolution.py diff --git a/src/easydynamics/utils/__init__.py b/src/easydynamics/utils/__init__.py index 9cf350f..a6bd0bf 100644 --- a/src/easydynamics/utils/__init__.py +++ b/src/easydynamics/utils/__init__.py @@ -1,3 +1,4 @@ +from .convolution import convolution from .detailed_balance import _detailed_balance_factor -__all__ = ["_detailed_balance_factor"] +__all__ = ["_detailed_balance_factor", "convolution"] diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py new file mode 100644 index 0000000..2cd13e4 --- /dev/null +++ b/src/easydynamics/utils/convolution.py @@ -0,0 +1,371 @@ +import warnings +from typing import Tuple, Union + +import numpy as np +from easyscience.variable import Parameter +from scipy.interpolate import interp1d +from scipy.signal import fftconvolve +from scipy.special import voigt_profile + +from easydynamics.sample_model import DeltaFunction, Gaussian, Lorentzian, SampleModel +from easydynamics.sample_model.components import ModelComponent + + +def convolution( + x: np.ndarray, + sample_model: Union[SampleModel, ModelComponent], + resolution_model: Union[SampleModel, ModelComponent], + offset: Union[Parameter, float, None] = None, + method: str = "analytical", + upsample_factor: int = 0, + extension_factor: float = 0.2, + temperature: Union[Parameter, float, None] = None, + normalize_detailed_balance: bool = True, +) -> np.ndarray: + """ + Calculate the convolution of a sample model with a resolution model using analytical expressions or numerical FFT. + Accepts SampleModel or ModelComponent for both sample and resolution. + The analytical method silently falls back to numerical convolution if no analytical expression is found. + """ + if not isinstance(x, np.ndarray): + raise TypeError( + f"`x` is an instance of {type(x).__name__}, but must be a numpy array." + ) + + x = np.asarray(x, dtype=float) + if x.ndim != 1 or not np.all(np.isfinite(x)): + raise ValueError("`x` must be a 1D finite array.") + + if not isinstance(sample_model, (SampleModel, ModelComponent)): + raise TypeError( + f"`sample_model` is an instance of {type(sample_model).__name__}, but must be SampleModel or ModelComponent." + ) + + if not isinstance(resolution_model, (SampleModel, ModelComponent)): + raise TypeError( + f"`resolution_model` is an instance of {type(resolution_model).__name__}, but must be SampleModel or ModelComponent." + ) + + if isinstance(sample_model, SampleModel): + if not sample_model.components: + raise ValueError("SampleModel must have at least one component.") + + if isinstance(resolution_model, SampleModel): + if not resolution_model.components: + raise ValueError("ResolutionModel must have at least one component.") + + if method == "analytical": + if isinstance(sample_model, SampleModel) and temperature is not None: + raise ValueError( + "Analytical convolution is not supported with detailed balance. Set method to 'numerical' instead or set the temperature to None." + ) + return _analytical_convolution( + x=x, + sample_model=sample_model, + resolution_model=resolution_model, + offset=offset, + upsample_factor=upsample_factor, + extension_factor=extension_factor, + ) + + if method == "numerical": + return _numerical_convolution( + x=x, + sample_model=sample_model, + resolution_model=resolution_model, + offset=offset, + upsample_factor=upsample_factor, + extension_factor=extension_factor, + temperature=temperature, + normalize_detailed_balance=normalize_detailed_balance, + ) + + if method not in ["analytical", "numerical"]: + raise ValueError( + f"Unknown convolution method: {method}. Choose from 'analytical', or 'numerical'." + ) + + +def _numerical_convolution( + x: np.ndarray, + sample_model: Union[SampleModel, ModelComponent, np.ndarray], + resolution_model: Union[SampleModel, ModelComponent, np.ndarray], + offset: Union[Parameter, np.ndarray, None] = None, + upsample_factor: int = 5, + extension_factor: float = 0.2, + temperature: Union[Parameter, float, None] = None, + normalize_detailed_balance: bool = True, +) -> np.ndarray: + """ + Numerical convolution using FFT with optional upsampling + extended range. + + sample_model / resolution_model may be: + - SampleModel + - ModelComponent + - Callable: f(x: np.ndarray) -> np.ndarray + offset: Union[Parameter, np.ndarray, None]: The offset on the x axis + upsample_factor: int: The factor by which to upsample the input array to improve resolution + extension_factor: float: The factor by which to extend the range of the input array to improve accuracy at the edges + selected_component_name: Union[str, None]: If provided, the name of the component to be selected for evaluation + """ + + def is_uniform(xarr, rtol=1e-5) -> bool: + """Check if the array is uniformly spaced.""" + dx = np.diff(xarr) + return np.allclose(dx, dx[0], rtol=rtol) + + # Build dense grid + if upsample_factor == 0: + if not is_uniform(x): + raise ValueError( + "Input array `x` must be uniformly spaced if upsample_factor = 0." + ) + x_dense = x + else: + # Create an extended and upsampled x grid + x_min, x_max = x.min(), x.max() + span = x_max - x_min + extra = extension_factor * span + extended_min = x_min - extra + extended_max = x_max + extra + num_points = len(x) * upsample_factor + x_dense = np.linspace(extended_min, extended_max, num_points) + if offset is None: + off = 0.0 + elif isinstance(offset, Parameter): + off = offset.value + elif isinstance(offset, float): + off = offset + else: + raise TypeError( + f"Expected offset to be Parameter, float, or None, got {type(offset)}" + ) + + dx = x_dense[1] - x_dense[0] + span = x_dense.max() - x_dense.min() + # Handle offset for even length of x in convolution + if len(x_dense) % 2 == 0: + off2 = -0.5 * dx + else: + off2 = 0.0 + + # Handle the case when x is not symmetric around zero. The resolution is still centered around zero (or close to it), so it needs to be evaluated there. + if not np.isclose(x_dense.mean(), 0.0): + x_dense_resolution = np.linspace(-0.5 * span, 0.5 * span, len(x_dense)) + else: + x_dense_resolution = x_dense + + # Give warnings if peaks are very wide or very narrow + _check_width_thresholds(sample_model, span, dx, "sample model") + _check_width_thresholds(resolution_model, span, dx, "resolution model") + + # Evaluate on dense grid + # sample_vals = _evaluate_any(sample_model, x_dense - off - off2) + # resolution_vals = _evaluate_any(resolution_model, x_dense_resolution) + sample_vals = sample_model.evaluate(x_dense - off - off2) + resolution_vals = resolution_model.evaluate(x_dense_resolution) + + # Convolution + convolved = fftconvolve(sample_vals, resolution_vals, mode="same") + convolved *= dx # normalize + + # Add delta contributions + if isinstance(sample_model, SampleModel): + for comp in sample_model.components.values(): + if isinstance(comp, DeltaFunction): + convolved += comp.area.value * resolution_model.evaluate( + x_dense - off - comp.center.value + ) + elif isinstance(sample_model, DeltaFunction): + convolved += sample_model.area.value * resolution_model.evaluate( + x_dense - off - sample_model.center.value + ) + + if isinstance(resolution_model, SampleModel): + for comp in resolution_model.components.values(): + if isinstance(comp, DeltaFunction): + convolved += comp.area.value * sample_model.evaluate( + x_dense - off - comp.center.value + ) + elif isinstance(resolution_model, DeltaFunction): + convolved += resolution_model.area.value * sample_model.evaluate( + x_dense - off - resolution_model.center.value + ) + + # TODO: if both resolution and sample are delta functions, we should let the user know that they are wrong. + + if upsample_factor > 0: + # interpolate back to original x grid + return interp1d( + x_dense, convolved, kind="linear", bounds_error=False, fill_value=0.0 + )(x) + else: + return convolved + + +def _analytical_convolution( + self, + x: np.ndarray, + sample_model: Union[SampleModel, ModelComponent], + resolution_model: Union[SampleModel, ModelComponent], + offset: Union[Parameter, float, None] = None, + upsample_factor: int = 5, + extension_factor: float = 0.2, +) -> np.ndarray: + """ + Convolve sample with resolution. Accepts SampleModel or single ModelComponent for each. + - Uses analytic registry for supported pairs. + - For non-analytic pairs, falls back to a single FFT per sample component + against the sum of its leftover resolution components using numerical_convolve + (passing a callable for the summed resolution). + - Handles delta functions analytically. + """ + + if offset is None: + off = 0.0 + elif isinstance(offset, Parameter): + off = offset.value + elif isinstance(offset, float): + off = offset + else: + raise TypeError( + f"Expected offset to be Parameter, float, or None, got {type(offset)}" + ) + + # prepare list of components + if isinstance(sample_model, SampleModel): + sample_components = sample_model.components + else: + sample_components = [sample_model] + + if isinstance(resolution_model, SampleModel): + resolution_components = resolution_model.components + else: + resolution_components = [resolution_model] + + total = np.zeros_like(x, dtype=float) + + # loop over sample components, making a list of components that cannot be handled analytically + for s in sample_components: + not_analytical_components = SampleModel(name="not_analytical") + + # Go through resolution components, adding analytical contributions where possible, making a list of those that cannot be handled analytically + for r in resolution_components: + handled, contrib = _try_analytic_pair(x, s, r, off) + if handled: + total += contrib + else: + not_analytical_components.add_component(r) + + if not_analytical_components: + total += _numerical_convolution( + x=x, + sample_model=s, # single component + resolution_model=not_analytical_components, # SampleModel with components that cannot be handled analytically + offset=offset, + upsample_factor=upsample_factor, + extension_factor=extension_factor, + ) + + return total + + +def _try_analytic_pair( + self, x: np.ndarray, s: ModelComponent, r: ModelComponent, off: float +) -> Tuple[bool, np.ndarray]: + """ + Attempt an analytic convolution for component pair (s, r). + Returns (True, contribution) if handled, else (False, zeros). + """ + # Delta functions + if isinstance(s, DeltaFunction): + return True, s.area.value * r.evaluate(x - s.center.value - off) + + if isinstance(r, DeltaFunction): + return True, r.area.value * s.evaluate(x - r.center.value - off) + + # Gaussian + Gaussian --> Gaussian + if isinstance(s, Gaussian) and isinstance(r, Gaussian): + width = np.sqrt(s.width.value**2 + r.width.value**2) + area = s.area.value * r.area.value + center = (s.center.value + r.center.value) + off + return True, self.gaussian_eval(x, center, width, area) + + # Lorentzian + Lorentzian --> Lorentzian + if isinstance(s, Lorentzian) and isinstance(r, Lorentzian): + width = s.width.value + r.width.value + area = s.area.value * r.area.value + center = (s.center.value + r.center.value) + off + return True, self.lorentzian_eval(x, center, width, area) + + # Gaussian + Lorentzian --> Voigt + if (isinstance(s, Gaussian) and isinstance(r, Lorentzian)) or ( + isinstance(s, Lorentzian) and isinstance(r, Gaussian) + ): + if isinstance(s, Gaussian): + G, L = s, r + else: + G, L = r, s + center = (G.center.value + L.center.value) + off + area = G.area.value * L.area.value + return True, self.voigt_eval(x, center, G.width.value, L.width.value, area) + + return False, np.zeros_like(x, dtype=float) + + +# ---------------------- helpers & evals ----------------------- + + +@staticmethod +def gaussian_eval(x, center, width, area): + return ( + area + * 1 + / (np.sqrt(2 * np.pi) * width) + * np.exp(-0.5 * ((x - center) / width) ** 2) + ) + + +@staticmethod +def lorentzian_eval(x, center, width, area): + return area * width / np.pi / ((x - center) ** 2 + width**2) + + +@staticmethod +def voigt_eval(x, center, g_width, l_width, area): + return area * voigt_profile(x - center, g_width, l_width) + + +@staticmethod +def _check_width_thresholds(model, span, dx, model_type): + """ + Helper function to check and warn about width thresholds for a given model or component. + Parameters: + - model: ModelComponent or SampleModel + - span: Range of the input data + - dx: Bin spacing of the input data + - model_type: 'sample model' or 'resolution model' for proper warning messages + """ + LARGE_WIDTH_THRESHOLD = 0.1 # Threshold for large widths compared to span + SMALL_WIDTH_THRESHOLD = 0.5 # Threshold for small widths compared to bin spacing + + # Handle SampleModel or ModelComponent + if isinstance(model, SampleModel): + components = model.components.values() + else: + components = [model] # Treat single ModelComponent as a list of one + + for comp in components: + if hasattr(comp, "width"): + if comp.width.value > LARGE_WIDTH_THRESHOLD * span: + warnings.warn( + f"The width of the {model_type} component '{comp.name}' ({comp.width.value}) is large compared to the span of the input " + f"array ({span}). This may lead to inaccuracies in the convolution.", + UserWarning, + ) + if comp.width.value < SMALL_WIDTH_THRESHOLD * dx: + warnings.warn( + f"The width of the {model_type} component '{comp.name}' ({comp.width.value}) is small compared to the spacing of the input " + f"array ({dx}). This may lead to inaccuracies in the convolution.", + UserWarning, + ) diff --git a/tests/unit_tests/utils/test_convolution.py b/tests/unit_tests/utils/test_convolution.py new file mode 100644 index 0000000..febd500 --- /dev/null +++ b/tests/unit_tests/utils/test_convolution.py @@ -0,0 +1,786 @@ +import numpy as np +import pytest +from easyscience.variable import Parameter +from scipy.special import voigt_profile + +from easydynamics.sample_model import DeltaFunction, Gaussian, Lorentzian, SampleModel +from easydynamics.utils import convolution as MyConvolutionFunction + +# Numerical convolutions are not very accurate +NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE = 1e-6 +NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE = 1e-5 + + +class TestConvolution: + @pytest.fixture + def sample_model(self): + test_sample_model = SampleModel(name="TestSampleModel") + test_sample_model.add_component(Lorentzian(center=0.1, width=0.2, area=2.0)) + return test_sample_model + + @pytest.fixture + def resolution_model(self): + test_resolution_model = SampleModel(name="TestResolutionModel") + test_resolution_model.add_component(Gaussian(center=0.2, width=0.3, area=3.0)) + return test_resolution_model + + @pytest.fixture + def x(self): + return np.linspace(-50, 50, 50001) + + # Test convolution of components + @pytest.mark.parametrize( + "offset_obj, expected_shift", + [ + (None, 0.0), + (0.4, 0.4), + (Parameter("off", 0.4), 0.4), + ], + ids=["none", "float", "parameter"], + ) + @pytest.mark.parametrize( + "method", ["analytical", "numerical"], ids=["analytical", "numerical"] + ) + def test_components_gauss_gauss(self, x, offset_obj, expected_shift, method): + # WHEN + sample_gauss = Gaussian(center=0.1, width=0.3, area=2) + resolution_gauss = Gaussian(center=0.2, width=0.4, area=3) + + # THEN + convolution = MyConvolutionFunction( + x=x, + sample_model=sample_gauss, + resolution_model=resolution_gauss, + offset=offset_obj, + method=method, + ) + + # EXPECT + expected_width = np.sqrt( + sample_gauss.width.value**2 + resolution_gauss.width.value**2 + ) + expected_area = sample_gauss.area.value * resolution_gauss.area.value + expected_center = ( + sample_gauss.center.value + resolution_gauss.center.value + expected_shift + ) + expected_result = ( + expected_area + * np.exp(-0.5 * ((x - expected_center) / expected_width) ** 2) + / (np.sqrt(2 * np.pi) * expected_width) + ) + + np.testing.assert_allclose(convolution, expected_result, atol=1e-10) + + @pytest.mark.parametrize( + "offset_obj, expected_shift", + [ + (None, 0.0), + (0.4, 0.4), + (Parameter("off", 0.4), 0.4), + ], + ids=["none", "float", "parameter"], + ) + @pytest.mark.parametrize( + "method", ["analytical", "numerical"], ids=["analytical", "numerical"] + ) + def test_components_lorentzian_lorentzian( + self, x, offset_obj, expected_shift, method + ): + # WHEN + sample_lorentzian = Lorentzian(center=0.1, width=0.3, area=2) + resolution_lorentzian = Lorentzian(center=0.2, width=0.4, area=3) + + # THEN + convolution = MyConvolutionFunction( + x=x, + sample_model=sample_lorentzian, + resolution_model=resolution_lorentzian, + offset=offset_obj, + method=method, + upsample_factor=5, + ) + + # EXPECT + expected_width = ( + sample_lorentzian.width.value + resolution_lorentzian.width.value + ) + expected_area = sample_lorentzian.area.value * resolution_lorentzian.area.value + expected_center = ( + sample_lorentzian.center.value + + resolution_lorentzian.center.value + + expected_shift + ) + expected_result = ( + expected_area + * expected_width + / np.pi + / ((x - expected_center) ** 2 + expected_width**2) + ) + + np.testing.assert_allclose( + convolution, + expected_result, + atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, + rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, + ) + + @pytest.mark.parametrize( + "offset_obj, expected_shift", + [ + (None, 0.0), + (0.4, 0.4), + (Parameter("off", 0.4), 0.4), + ], + ids=["none", "float", "parameter"], + ) + @pytest.mark.parametrize( + "method", ["analytical", "numerical"], ids=["analytical", "numerical"] + ) + def test_components_gauss_lorentzian(self, x, offset_obj, expected_shift, method): + # WHEN + sample_gauss = Gaussian(center=0.1, width=0.3, area=2) + resolution_lorentzian = Lorentzian(center=0.2, width=0.4, area=3) + + # THEN + convolution = MyConvolutionFunction( + x=x, + sample_model=sample_gauss, + resolution_model=resolution_lorentzian, + offset=offset_obj, + method=method, + upsample_factor=5, + ) + + # EXPECT + expected_center = ( + sample_gauss.center.value + + resolution_lorentzian.center.value + + expected_shift + ) + expected_area = sample_gauss.area.value * resolution_lorentzian.area.value + expected_result = expected_area * voigt_profile( + x - expected_center, + sample_gauss.width.value, + resolution_lorentzian.width.value, + ) + + np.testing.assert_allclose( + convolution, + expected_result, + atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, + rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, + ) + + @pytest.mark.parametrize( + "offset_obj, expected_shift", + [ + (None, 0.0), + (0.4, 0.4), + (Parameter("off", 0.4), 0.4), + ], + ids=["none", "float", "parameter"], + ) + @pytest.mark.parametrize( + "method", ["analytical", "numerical"], ids=["analytical", "numerical"] + ) + def test_components_lorentzian_gauss(self, x, offset_obj, expected_shift, method): + # WHEN + resolution_gauss = Gaussian(center=0.1, width=0.3, area=2) + sample_lorentzian = Lorentzian(center=0.2, width=0.4, area=3) + + # THEN + convolution = MyConvolutionFunction( + x=x, + sample_model=sample_lorentzian, + resolution_model=resolution_gauss, + offset=offset_obj, + method=method, + upsample_factor=5, + ) + + # EXPECT + expected_center = ( + sample_lorentzian.center.value + + resolution_gauss.center.value + + expected_shift + ) + expected_area = sample_lorentzian.area.value * resolution_gauss.area.value + expected_result = expected_area * voigt_profile( + x - expected_center, + resolution_gauss.width.value, + sample_lorentzian.width.value, + ) + + np.testing.assert_allclose( + convolution, + expected_result, + atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, + rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, + ) + + @pytest.mark.parametrize( + "offset_obj, expected_shift", + [ + (None, 0.0), + (0.4, 0.4), + (Parameter("off", 0.4), 0.4), + ], + ids=["none", "float", "parameter"], + ) + @pytest.mark.parametrize( + "method", ["analytical", "numerical"], ids=["analytical", "numerical"] + ) + def test_components_delta_gauss(self, x, offset_obj, expected_shift, method): + # WHEN + sample_delta = DeltaFunction(name="Delta", center=0.1, area=2) + resolution_gauss = Gaussian(center=0.2, width=0.3, area=3) + + # THEN + convolution = MyConvolutionFunction( + x=x, + sample_model=sample_delta, + resolution_model=resolution_gauss, + offset=offset_obj, + method=method, + ) + + # EXPECT + expected_center = ( + sample_delta.center.value + resolution_gauss.center.value + expected_shift + ) + expected_area = sample_delta.area.value * resolution_gauss.area.value + expected_result = ( + expected_area + * np.exp(-0.5 * ((x - expected_center) / resolution_gauss.width.value) ** 2) + / (np.sqrt(2 * np.pi) * resolution_gauss.width.value) + ) + + np.testing.assert_allclose(convolution, expected_result, atol=1e-10) + + @pytest.mark.parametrize( + "offset_obj, expected_shift", + [ + (None, 0.0), + (0.4, 0.4), + (Parameter("off", 0.4), 0.4), + ], + ids=["none", "float", "parameter"], + ) + @pytest.mark.parametrize( + "method", ["analytical", "numerical"], ids=["analytical", "numerical"] + ) + def test_components_gauss_delta(self, x, offset_obj, expected_shift, method): + # WHEN + sample_gauss = Gaussian(center=0.1, width=0.2, area=2) + resolution_delta = DeltaFunction(name="Delta", center=0.2, area=3) + + # THEN + convolution = MyConvolutionFunction( + x=x, + sample_model=sample_gauss, + resolution_model=resolution_delta, + offset=offset_obj, + method=method, + ) + + # EXPECT + expected_center = ( + sample_gauss.center.value + resolution_delta.center.value + expected_shift + ) + expected_area = sample_gauss.area.value * resolution_delta.area.value + expected_result = ( + expected_area + * np.exp(-0.5 * ((x - expected_center) / sample_gauss.width.value) ** 2) + / (np.sqrt(2 * np.pi) * sample_gauss.width.value) + ) + + np.testing.assert_allclose(convolution, expected_result, atol=1e-10) + + # Test convolution of SampleModel + @pytest.mark.parametrize( + "offset_obj, expected_shift", + [ + (None, 0.0), + (0.4, 0.4), + (Parameter("off", 0.4), 0.4), + ], + ids=["none", "float", "parameter"], + ) + @pytest.mark.parametrize( + "method", ["analytical", "numerical"], ids=["analytical", "numerical"] + ) + def test_model_gauss_gauss_resolution_gauss( + self, x, offset_obj, expected_shift, method + ): + # WHEN + sample_gauss1 = Gaussian(center=0.1, width=0.3, area=2, name="SampleGauss1") + sample_gauss2 = Gaussian(center=0.2, width=0.4, area=3, name="SampleGauss2") + resolution_gauss = Gaussian(center=0.3, width=0.5, area=4) + + sample = SampleModel(name="SampleModel") + sample.add_component(sample_gauss1) + sample.add_component(sample_gauss2) + + resolution = SampleModel(name="ResolutionModel") + resolution.add_component(resolution_gauss) + + # THEN + convolution = MyConvolutionFunction( + x=x, + sample_model=sample, + resolution_model=resolution, + offset=offset_obj, + method=method, + ) + + # EXPECT + expected_width1 = np.sqrt( + sample_gauss1.width.value**2 + resolution_gauss.width.value**2 + ) + expected_width2 = np.sqrt( + sample_gauss2.width.value**2 + resolution_gauss.width.value**2 + ) + expected_area1 = sample_gauss1.area.value * resolution_gauss.area.value + expected_area2 = sample_gauss2.area.value * resolution_gauss.area.value + expected_center1 = ( + sample_gauss1.center.value + resolution_gauss.center.value + expected_shift + ) + expected_center2 = ( + sample_gauss2.center.value + resolution_gauss.center.value + expected_shift + ) + + expected_result = expected_area1 * np.exp( + -0.5 * ((x - expected_center1) / expected_width1) ** 2 + ) / (np.sqrt(2 * np.pi) * expected_width1) + expected_area2 * np.exp( + -0.5 * ((x - expected_center2) / expected_width2) ** 2 + ) / (np.sqrt(2 * np.pi) * expected_width2) + np.testing.assert_allclose(convolution, expected_result, atol=1e-10) + + @pytest.mark.parametrize( + "method", ["analytical", "numerical"], ids=["analytical", "numerical"] + ) + def test_model_lorentzian_delta_resolution_gauss(self, x, method): + # WHEN + sample_lorentzian = Lorentzian( + center=0.1, width=0.3, area=2, name="SampleLorentzian" + ) + sample_delta = DeltaFunction(center=0.5, area=4, name="SampleDelta") + resolution_gauss = Gaussian( + center=-0.3, width=0.4, area=3, name="ResolutionGauss" + ) + sample = SampleModel(name="SampleModel") + sample.add_component(sample_lorentzian) + sample.add_component(sample_delta) + resolution = SampleModel(name="ResolutionModel") + resolution.add_component(resolution_gauss) + + # THEN + x = np.linspace(-10, 10, 20001) + convolution = MyConvolutionFunction( + x=x, + sample_model=sample, + resolution_model=resolution, + method=method, + upsample_factor=5, + ) + + # EXPECT: Combine Gaussian, Lorentzian, and Delta functions contributions + expected_voigt = 2 * 3 * voigt_profile(x - (0.1 - 0.3), 0.4, 0.3) + expected_gauss_center = -0.3 + 0.5 + expected_gauss = ( + 3 + * 4 + * np.exp(-0.5 * ((x - (expected_gauss_center)) / 0.4) ** 2) + / (np.sqrt(2 * np.pi) * 0.4) + ) + expected_result = expected_voigt + expected_gauss + np.testing.assert_allclose( + convolution, + expected_result, + atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, + rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, + ) + + # Test numerical convolution + @pytest.mark.parametrize( + "x", + [ + np.linspace(-10, 10, 5001), # Odd length + np.linspace(-10, 10, 5000), # Even length + ], + ids=["odd_length", "even_length"], + ) + def test_numerical_convolve_x_length_even_and_odd(self, x): + # WHEN + sample_model = SampleModel(name="SampleModel") + sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) + + resolution_model = SampleModel(name="ResolutionModel") + resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) + + # THEN + convolution = MyConvolutionFunction( + x=x, + sample_model=sample_model, + resolution_model=resolution_model, + method="numerical", + upsample_factor=0, + ) + + # EXPECT + expected_convolution = MyConvolutionFunction( + x=x, + sample_model=sample_model, + resolution_model=resolution_model, + method="analytical", + upsample_factor=0, + ) + + np.testing.assert_allclose(convolution, expected_convolution, atol=1e-10) + + @pytest.mark.parametrize( + "upsample_factor", + [0, 2, 5, 10], + ids=["no_upsample", "upsample_2", "upsample_5", "upsample_10"], + ) + def test_numerical_convolve_upsample_factor(self, x, upsample_factor): + # WHEN + sample_model = SampleModel(name="SampleModel") + sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) + + resolution_model = SampleModel(name="ResolutionModel") + resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) + + # THEN + convolution = MyConvolutionFunction( + x=x, + sample_model=sample_model, + resolution_model=resolution_model, + method="numerical", + upsample_factor=upsample_factor, + ) + + # EXPECT + expected_convolution = MyConvolutionFunction( + x=x, + sample_model=sample_model, + resolution_model=resolution_model, + method="analytical", + upsample_factor=0, + ) + + np.testing.assert_allclose( + convolution, + expected_convolution, + atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, + rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, + ) + + @pytest.mark.parametrize( + "x", + [np.linspace(-5, 15, 20000), np.linspace(5, 15, 20000)], + ids=["asymmetric", "only_positive"], + ) + @pytest.mark.parametrize( + "upsample_factor", [0, 2, 5], ids=["no_upsample", "upsample_2", "upsample_5"] + ) + def test_numerical_convolve_x_not_symmetric(self, x, upsample_factor): + # WHEN + sample_model = SampleModel(name="SampleModel") + sample_model.add_component(Gaussian(center=9, width=0.3, area=2)) + + resolution_model = SampleModel(name="ResolutionModel") + resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) + + # THEN + convolution = MyConvolutionFunction( + x=x, + sample_model=sample_model, + resolution_model=resolution_model, + method="numerical", + upsample_factor=upsample_factor, + ) + + # EXPECT + expected_convolution = MyConvolutionFunction( + x=x, + sample_model=sample_model, + resolution_model=resolution_model, + method="analytical", + upsample_factor=0, + ) + + np.testing.assert_allclose( + convolution, + expected_convolution, + atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, + rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, + ) + + def test_numerical_convolve_x_not_uniform(self): + # WHEN + sample_model = SampleModel(name="SampleModel") + sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) + resolution_model = SampleModel(name="ResolutionModel") + resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) + + x_1 = np.linspace(-2, 0, 1000) + x_2 = np.linspace(0.001, 2, 2000) + x_non_uniform = np.concatenate([x_1, x_2]) + # THEN + convolution = MyConvolutionFunction( + x=x_non_uniform, + sample_model=sample_model, + resolution_model=resolution_model, + method="numerical", + upsample_factor=5, + ) + + # EXPECT + expected_convolution = MyConvolutionFunction( + x=x_non_uniform, + sample_model=sample_model, + resolution_model=resolution_model, + method="analytical", + ) + + np.testing.assert_allclose( + convolution, + expected_convolution, + atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, + rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, + ) + + # Test error handling + + def test_analytical_convolution_fails_with_detailed_balance(self, x): + # WHEN + sample_model = SampleModel(name="SampleModel") + sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) + sample_model.temperature = 300 + + resolution_model = SampleModel(name="ResolutionModel") + resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) + + # THEN + with pytest.raises( + ValueError, + match="Analytical convolution is not supported with detailed balance.", + ): + MyConvolutionFunction( + x=x, + sample_model=sample_model, + resolution_model=resolution_model, + method="analytical", + ) + + def test_convolution_only_accepts_analytical_and_numerical_methods(self, x): + # WHEN + sample_model = SampleModel(name="SampleModel") + sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) + + resolution_model = SampleModel(name="ResolutionModel") + resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) + + # THEN + with pytest.raises( + ValueError, + match="Unknown convolution method: unknown_method. Choose from 'analytical', or 'numerical'.", + ): + MyConvolutionFunction( + x=x, + sample_model=sample_model, + resolution_model=resolution_model, + method="unknown_method", + ) + + def test_x_must_be_1d_finite_array(self): + # WHEN + sample_model = SampleModel(name="SampleModel") + sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) + + resolution_model = SampleModel(name="ResolutionModel") + resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) + + # THEN + with pytest.raises(ValueError, match="`x` must be a 1D finite array."): + MyConvolutionFunction( + x=np.array([[1, 2], [3, 4]]), + sample_model=sample_model, + resolution_model=resolution_model, + ) + + with pytest.raises(ValueError, match="`x` must be a 1D finite array."): + MyConvolutionFunction( + x=np.array([1, 2, np.nan]), + sample_model=sample_model, + resolution_model=resolution_model, + ) + + with pytest.raises(ValueError, match="`x` must be a 1D finite array."): + MyConvolutionFunction( + x=np.array([1, 2, np.inf]), + sample_model=sample_model, + resolution_model=resolution_model, + ) + + def test_numerical_convolve_requires_uniform_grid_if_no_upsample(self): + # WHEN + x = np.array([0, 1, 2, 4, 5]) # Non-uniform grid + sample_model = SampleModel(name="SampleModel") + sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) + resolution_model = SampleModel(name="ResolutionModel") + resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) + + # THEN + with pytest.raises( + ValueError, + match="Input array `x` must be uniformly spaced if upsample_factor = 0.", + ): + MyConvolutionFunction( + x=x, + sample_model=sample_model, + resolution_model=resolution_model, + method="numerical", + upsample_factor=0, + ) + + def test_sample_model_must_have_components(self): + # WHEN + sample_model = SampleModel(name="SampleModel") + resolution_model = SampleModel(name="ResolutionModel") + resolution_model.add_component(Gaussian(center=0.2, width=0.3, area=3)) + + # THEN + with pytest.raises( + ValueError, match="SampleModel must have at least one component." + ): + MyConvolutionFunction( + x=np.array([0, 1, 2]), + sample_model=sample_model, + resolution_model=resolution_model, + ) + + def test_resolution_model_must_have_components(self): + # WHEN + sample_model = SampleModel(name="SampleModel") + sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) + resolution_model = SampleModel(name="ResolutionModel") + + # THEN + with pytest.raises( + ValueError, match="ResolutionModel must have at least one component." + ): + MyConvolutionFunction( + x=np.array([0, 1, 2]), + sample_model=sample_model, + resolution_model=resolution_model, + ) + + def test_numerical_convolution_wide_sample_peak_gives_warning(self): + # WHEN + x = np.linspace(-2, 2, 20001) + + sample_gauss1 = Gaussian(center=0.1, width=1.9, area=2, name="SampleGauss") + resolution_gauss = Gaussian(center=0.3, width=0.5, area=4) + + sample = SampleModel(name="SampleModel") + sample.add_component(sample_gauss1) + + resolution = SampleModel(name="ResolutionModel") + resolution.add_component(resolution_gauss) + + # #THEN EXPECT + with pytest.warns( + UserWarning, + match=r"The width of the sample model component 'SampleGauss' \(1.9\) is large", + ): + MyConvolutionFunction( + x=x, + sample_model=sample, + resolution_model=resolution, + method="numerical", + upsample_factor=0, + ) + + def test_numerical_convolution_wide_resolution_peak_gives_warning(self): + # WHEN + x = np.linspace(-2, 2, 20001) + + sample_gauss1 = Gaussian(center=0.1, width=0.1, area=2, name="SampleGauss") + resolution_gauss = Gaussian( + center=0.3, width=1.9, area=4, name="ResolutionGauss" + ) + + sample = SampleModel(name="SampleModel") + sample.add_component(sample_gauss1) + + resolution = SampleModel(name="ResolutionModel") + resolution.add_component(resolution_gauss) + + # #THEN EXPECT + with pytest.warns( + UserWarning, + match=r"The width of the resolution model component 'ResolutionGauss' \(1.9\) is large", + ): + MyConvolutionFunction( + x=x, + sample_model=sample, + resolution_model=resolution, + method="numerical", + upsample_factor=0, + ) + + def test_numerical_convolution_narrow_sample_peak_gives_warning(self): + # WHEN + x = np.linspace(-2, 2, 201) + + sample_gauss1 = Gaussian(center=0.1, width=1e-3, area=2, name="SampleGauss") + resolution_gauss = Gaussian(center=0.3, width=0.5, area=4) + + sample = SampleModel(name="SampleModel") + sample.add_component(sample_gauss1) + + resolution = SampleModel(name="ResolutionModel") + resolution.add_component(resolution_gauss) + + # #THEN EXPECT + with pytest.warns( + UserWarning, + match=r"The width of the sample model component 'SampleGauss' \(0.001\) is small", + ): + MyConvolutionFunction( + x=x, + sample_model=sample, + resolution_model=resolution, + method="numerical", + upsample_factor=0, + ) + + def test_numerical_convolution_narrow_resolution_peak_gives_warning(self): + # WHEN + x = np.linspace(-2, 2, 201) + + sample_gauss1 = Gaussian(center=0.1, width=0.2, area=2, name="SampleGauss") + resolution_gauss = Gaussian( + center=0.3, width=1e-3, area=4, name="ResolutionGauss" + ) + + sample = SampleModel(name="SampleModel") + sample.add_component(sample_gauss1) + + resolution = SampleModel(name="ResolutionModel") + resolution.add_component(resolution_gauss) + + # #THEN EXPECT + with pytest.warns( + UserWarning, + match=r"The width of the resolution model component 'ResolutionGauss' \(0.001\) is small", + ): + MyConvolutionFunction( + x=x, + sample_model=sample, + resolution_model=resolution, + method="numerical", + upsample_factor=0, + ) From d7a95f210f34a935f623c1917cf409fdbe6b2981 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 29 Oct 2025 20:38:31 +0100 Subject: [PATCH 15/71] Update tests and convolution --- examples/convolution.ipynb | 122 +++++++++++++++ src/easydynamics/sample_model/sample_model.py | 31 +++- src/easydynamics/utils/convolution.py | 84 +++++++--- tests/unit_tests/utils/test_convolution.py | 147 +++++++++++++----- 4 files changed, 321 insertions(+), 63 deletions(-) create mode 100644 examples/convolution.ipynb diff --git a/examples/convolution.ipynb b/examples/convolution.ipynb new file mode 100644 index 0000000..bc203c3 --- /dev/null +++ b/examples/convolution.ipynb @@ -0,0 +1,122 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "f42e34d0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b0f508b8d2114e1b8c6bb386a9b32bbe", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "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zz33nLXbbrtZK1as6H/smGOOsaZPn26ee+qpp6xddtnFOvHEE61y8Y9//MNc/WVf7fpe9vuw349dd9vixYvNVcJz5861lixZYt1///3WTjvtZB122GFWuXn66afNFcD2tnrrrbesO+64w2yvU045ZdD3ZzvzzDOt8ePHW48++qh5nwcddJC5lRu77jvvvLN15JFHmunVq1f33yp1+919993mCsPbbrvNXEF/xhlnWA0NDf1X3p988snWpZde2j//v/71L8vv91s//vGPzd+vfRWqfRX3ggULrHJz1llnmStCH3/88U22VSKR6J/nve/P3hc99NBD5u933rx51he+8AUrHA5br776qlWOLrroIvP+7L8te9vMnDnTGjZsmLniudK338ArWu39wyWXXPK+5ypx+9nfb33fdfb3wDXXXGOm7e9D21VXXWU+g/a+4uWXX7aOP/5409NAT09P/zI++tGPWtdff/1Wf44xOAJgiZx66qnmA/De22OPPdY/zzvvvGMde+yxViQSMTs2e4eXyWT6n7fntV9j7wD7bNiwwQQ+O1TaXcacdtpp/aGyHNh1O/jggzf7nP0+Bv4bLFu2zISFpqYm8wG3A8jFF19sdXR0WOXG3uHaXUrYX7r2Tnfq1KnWD37wAyuZTA76/mz2ju3rX/+61djYaEWjUes//uM/NglV5cLuYmJzf68Df0NW4vazv0jsL9hgMGi6k3j22Wc36cLG/pwO9Lvf/c7addddzfzTpk2z/vrXv1rlaLBtZW/Hwd7fBRdc0P9vMXLkSOvjH/+49eKLL1rl6vOf/7w1evRoU98xY8aY+/aPjmrYfn3sQGdvt4ULF77vuUrcfn3fWe+99b0PuyuYyy67zNTf3mfYPzjf+97t7rbs8L61n2MMzmP/b2CLIAAAAKob/QACAAC4DAEQAADAZQiAAAAALkMABAAAcBkCIAAAgMsQAAEAAFyGAAgAAOAyBEAAAACXIQACAAC4DAEQAADAZQiAAAAALkMABAAAcBkCIAAAgMsQAAEAAFyGAAgAAOAyBEAAAACXIQACAAC4DAEQAADAZQiAAAAALkMABAAAcBkCIAAAgMsQAAEAAFyGAAgAAOAyBEAAAACXIQACAAC4DAEQAADAZQiAAAAALkMABAAAcBkCIAAAgMsQAAEAAFyGAAgAACB3+f8Mpeg/hrT37AAAAABJRU5ErkJggg==", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import numpy as np\n", + "from easyscience.variable import Parameter\n", + "from scipy.special import voigt_profile\n", + "\n", + "from easydynamics.sample_model import DeltaFunction, Gaussian, Lorentzian, SampleModel\n", + "from easydynamics.utils import convolution as convolution\n", + "\n", + "# Numerical convolutions are not very accurate\n", + "NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE = 1e-6\n", + "NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE = 1e-5\n", + "\n", + "\n", + "\n", + "# WHEN\n", + "sample_lorentzian = Lorentzian(\n", + " center=0.1, width=0.3, area=2, name=\"SampleLorentzian\"\n", + ")\n", + "sample_delta = DeltaFunction(center=0.5, area=4, name=\"SampleDelta\")\n", + "resolution_gauss = Gaussian(\n", + " center=-0.3, width=0.4, area=3, name=\"ResolutionGauss\"\n", + ")\n", + "sample = SampleModel(name=\"SampleModel\")\n", + "sample.add_component(sample_lorentzian)\n", + "sample.add_component(sample_delta)\n", + "resolution = SampleModel(name=\"ResolutionModel\")\n", + "resolution.add_component(resolution_gauss)\n", + "\n", + "# THEN\n", + "x = np.linspace(-10, 10, 20001)\n", + "convolution = convolution(\n", + " x=x,\n", + " sample_model=sample,\n", + " resolution_model=resolution,\n", + " method=\"numerical\",\n", + " upsample_factor=5,\n", + ")\n", + "\n", + "# EXPECT: Combine Gaussian, Lorentzian, and Delta functions contributions\n", + "expected_voigt = 2 * 3 * voigt_profile(x - (0.1 - 0.3), 0.4, 0.3)\n", + "expected_gauss_center = -0.3 + 0.5\n", + "expected_gauss = (\n", + " 3\n", + " * 4\n", + " * np.exp(-0.5 * ((x - (expected_gauss_center)) / 0.4) ** 2)\n", + " / (np.sqrt(2 * np.pi) * 0.4)\n", + ")\n", + "expected_result = expected_voigt + expected_gauss\n", + "\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib widget\n", + "plt.plot(x, convolution, label=\"Convolution Result\")\n", + "plt.plot(x, expected_result, label=\"Expected Result\", linestyle='dashed')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "newdynamics", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/easydynamics/sample_model/sample_model.py b/src/easydynamics/sample_model/sample_model.py index 8a9dd13..ff23f7c 100644 --- a/src/easydynamics/sample_model/sample_model.py +++ b/src/easydynamics/sample_model/sample_model.py @@ -7,6 +7,8 @@ from easyscience.global_object.undo_redo import NotarizedDict from easyscience.job.theoreticalmodel import TheoreticalModelBase +from easydynamics.sample_model.components import DeltaFunction + from .components.model_component import ModelComponent Numeric = Union[float, int] @@ -190,7 +192,7 @@ def evaluate( self, x: Union[Numeric, list, np.ndarray, sc.Variable, sc.DataArray] ) -> np.ndarray: """ - Evaluate the sum of all components, optionally applying detailed balance. + Evaluate the sum of all components. Parameters ---------- @@ -212,6 +214,33 @@ def evaluate( return result + def evaluate_without_delta( + self, x: Union[Numeric, list, np.ndarray, sc.Variable, sc.DataArray] + ) -> np.ndarray: + """ + Evaluate the sum of all components except delta functions. + + Parameters + ---------- + x : Number, list, np.ndarray, sc.Variable, or sc.DataArray + Energy axis. + + Returns + ------- + np.ndarray + Evaluated model values. + """ + + if not self.components: + raise ValueError("No components in the model to evaluate.") + result = None + for component in list(self): + if not isinstance(component, DeltaFunction): + value = component.evaluate(x) + result = value if result is None else result + value + + return result + def evaluate_component( self, x: Union[Numeric, list, np.ndarray, sc.Variable, sc.DataArray], diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py index 2cd13e4..8d8b880 100644 --- a/src/easydynamics/utils/convolution.py +++ b/src/easydynamics/utils/convolution.py @@ -1,26 +1,32 @@ import warnings -from typing import Tuple, Union +from typing import Optional, Tuple, Union import numpy as np +import scipp as sc from easyscience.variable import Parameter from scipy.interpolate import interp1d from scipy.signal import fftconvolve from scipy.special import voigt_profile from easydynamics.sample_model import DeltaFunction, Gaussian, Lorentzian, SampleModel -from easydynamics.sample_model.components import ModelComponent +from easydynamics.sample_model.components.model_component import ModelComponent +from easydynamics.utils.detailed_balance import ( + _detailed_balance_factor as detailed_balance_factor, +) def convolution( x: np.ndarray, sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], - offset: Union[Parameter, float, None] = None, - method: str = "analytical", - upsample_factor: int = 0, - extension_factor: float = 0.2, - temperature: Union[Parameter, float, None] = None, - normalize_detailed_balance: bool = True, + offset: Optional[Union[Parameter, float, None]] = None, + method: Optional[str] = "analytical", + upsample_factor: Optional[int] = 0, + extension_factor: Optional[float] = 0.2, + temperature: Optional[Union[Parameter, float, None]] = None, + temperature_unit: Union[str, sc.Unit] = "K", + x_unit: Optional[Union[str, sc.Unit]] = "meV", + normalize_detailed_balance: Optional[bool] = True, ) -> np.ndarray: """ Calculate the convolution of a sample model with a resolution model using analytical expressions or numerical FFT. @@ -77,6 +83,8 @@ def convolution( upsample_factor=upsample_factor, extension_factor=extension_factor, temperature=temperature, + temperature_unit=temperature_unit, + x_unit=x_unit, normalize_detailed_balance=normalize_detailed_balance, ) @@ -94,6 +102,8 @@ def _numerical_convolution( upsample_factor: int = 5, extension_factor: float = 0.2, temperature: Union[Parameter, float, None] = None, + temperature_unit: Union[str, sc.Unit] = "K", + x_unit: Optional[Union[str, sc.Unit]] = "meV", normalize_detailed_balance: bool = True, ) -> np.ndarray: """ @@ -160,10 +170,45 @@ def is_uniform(xarr, rtol=1e-5) -> bool: _check_width_thresholds(resolution_model, span, dx, "resolution model") # Evaluate on dense grid - # sample_vals = _evaluate_any(sample_model, x_dense - off - off2) - # resolution_vals = _evaluate_any(resolution_model, x_dense_resolution) - sample_vals = sample_model.evaluate(x_dense - off - off2) - resolution_vals = resolution_model.evaluate(x_dense_resolution) + if isinstance(sample_model, SampleModel): + sample_vals = sample_model.evaluate_without_delta(x_dense - off - off2) + elif isinstance(sample_model, DeltaFunction): + sample_vals = np.zeros_like(x_dense) + else: + sample_vals = sample_model.evaluate(x_dense - off - off2) + + # Detailed balance correction + if temperature is not None: + if isinstance(temperature, Parameter): + T = temperature.value + temperature_unit = temperature.unit + elif isinstance(temperature, float): + T = temperature + else: + raise TypeError( + f"Expected temperature to be Parameter, float, or None, got {type(temperature)}" + ) + + if x_unit is None: + raise ValueError("x_unit must be provided when temperature is specified.") + if not isinstance(x_unit, (str, sc.Unit)): + raise TypeError(f"Expected x_unit to be str or sc.Unit, got {type(x_unit)}") + + detailed_balance_factor_correction = detailed_balance_factor( + energy=x_dense, + temperature=T, + energy_unit=x_unit, + temperature_unit=temperature_unit, + divide_by_temperature=normalize_detailed_balance, + ) + sample_vals *= detailed_balance_factor_correction + + if isinstance(resolution_model, SampleModel): + resolution_vals = resolution_model.evaluate_without_delta(x_dense_resolution) + elif isinstance(resolution_model, DeltaFunction): + resolution_vals = np.zeros_like(x_dense_resolution) + else: + resolution_vals = resolution_model.evaluate(x_dense_resolution) # Convolution convolved = fftconvolve(sample_vals, resolution_vals, mode="same") @@ -171,7 +216,7 @@ def is_uniform(xarr, rtol=1e-5) -> bool: # Add delta contributions if isinstance(sample_model, SampleModel): - for comp in sample_model.components.values(): + for comp in sample_model.components: if isinstance(comp, DeltaFunction): convolved += comp.area.value * resolution_model.evaluate( x_dense - off - comp.center.value @@ -182,7 +227,7 @@ def is_uniform(xarr, rtol=1e-5) -> bool: ) if isinstance(resolution_model, SampleModel): - for comp in resolution_model.components.values(): + for comp in resolution_model.components: if isinstance(comp, DeltaFunction): convolved += comp.area.value * sample_model.evaluate( x_dense - off - comp.center.value @@ -204,7 +249,6 @@ def is_uniform(xarr, rtol=1e-5) -> bool: def _analytical_convolution( - self, x: np.ndarray, sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], @@ -271,7 +315,7 @@ def _analytical_convolution( def _try_analytic_pair( - self, x: np.ndarray, s: ModelComponent, r: ModelComponent, off: float + x: np.ndarray, s: ModelComponent, r: ModelComponent, off: float ) -> Tuple[bool, np.ndarray]: """ Attempt an analytic convolution for component pair (s, r). @@ -289,14 +333,14 @@ def _try_analytic_pair( width = np.sqrt(s.width.value**2 + r.width.value**2) area = s.area.value * r.area.value center = (s.center.value + r.center.value) + off - return True, self.gaussian_eval(x, center, width, area) + return True, gaussian_eval(x, center, width, area) # Lorentzian + Lorentzian --> Lorentzian if isinstance(s, Lorentzian) and isinstance(r, Lorentzian): width = s.width.value + r.width.value area = s.area.value * r.area.value center = (s.center.value + r.center.value) + off - return True, self.lorentzian_eval(x, center, width, area) + return True, lorentzian_eval(x, center, width, area) # Gaussian + Lorentzian --> Voigt if (isinstance(s, Gaussian) and isinstance(r, Lorentzian)) or ( @@ -308,7 +352,7 @@ def _try_analytic_pair( G, L = r, s center = (G.center.value + L.center.value) + off area = G.area.value * L.area.value - return True, self.voigt_eval(x, center, G.width.value, L.width.value, area) + return True, voigt_eval(x, center, G.width.value, L.width.value, area) return False, np.zeros_like(x, dtype=float) @@ -351,7 +395,7 @@ def _check_width_thresholds(model, span, dx, model_type): # Handle SampleModel or ModelComponent if isinstance(model, SampleModel): - components = model.components.values() + components = model.components else: components = [model] # Treat single ModelComponent as a list of one diff --git a/tests/unit_tests/utils/test_convolution.py b/tests/unit_tests/utils/test_convolution.py index febd500..ae8a49b 100644 --- a/tests/unit_tests/utils/test_convolution.py +++ b/tests/unit_tests/utils/test_convolution.py @@ -1,10 +1,14 @@ import numpy as np import pytest from easyscience.variable import Parameter +from scipy.signal import fftconvolve from scipy.special import voigt_profile from easydynamics.sample_model import DeltaFunction, Gaussian, Lorentzian, SampleModel -from easydynamics.utils import convolution as MyConvolutionFunction +from easydynamics.utils import convolution +from easydynamics.utils.detailed_balance import ( + _detailed_balance_factor as detailed_balance_factor, +) # Numerical convolutions are not very accurate NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE = 1e-6 @@ -42,12 +46,14 @@ def x(self): "method", ["analytical", "numerical"], ids=["analytical", "numerical"] ) def test_components_gauss_gauss(self, x, offset_obj, expected_shift, method): + "Test convolution of Gaussian sample and Gaussian resolution components without SampleModel." + "Test with different offset types and methods." # WHEN sample_gauss = Gaussian(center=0.1, width=0.3, area=2) resolution_gauss = Gaussian(center=0.2, width=0.4, area=3) # THEN - convolution = MyConvolutionFunction( + calculated_convolution = convolution( x=x, sample_model=sample_gauss, resolution_model=resolution_gauss, @@ -69,7 +75,7 @@ def test_components_gauss_gauss(self, x, offset_obj, expected_shift, method): / (np.sqrt(2 * np.pi) * expected_width) ) - np.testing.assert_allclose(convolution, expected_result, atol=1e-10) + np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) @pytest.mark.parametrize( "offset_obj, expected_shift", @@ -86,12 +92,14 @@ def test_components_gauss_gauss(self, x, offset_obj, expected_shift, method): def test_components_lorentzian_lorentzian( self, x, offset_obj, expected_shift, method ): + "Test convolution of Lorentzian sample and Lorentzian resolution components without SampleModel." + "Test with different offset types and methods." # WHEN sample_lorentzian = Lorentzian(center=0.1, width=0.3, area=2) resolution_lorentzian = Lorentzian(center=0.2, width=0.4, area=3) # THEN - convolution = MyConvolutionFunction( + calculated_convolution = convolution( x=x, sample_model=sample_lorentzian, resolution_model=resolution_lorentzian, @@ -118,7 +126,7 @@ def test_components_lorentzian_lorentzian( ) np.testing.assert_allclose( - convolution, + calculated_convolution, expected_result, atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, @@ -137,12 +145,14 @@ def test_components_lorentzian_lorentzian( "method", ["analytical", "numerical"], ids=["analytical", "numerical"] ) def test_components_gauss_lorentzian(self, x, offset_obj, expected_shift, method): + "Test convolution of Gaussian sample and Lorentzian resolution components without SampleModel." + "Test with different offset types and methods." # WHEN sample_gauss = Gaussian(center=0.1, width=0.3, area=2) resolution_lorentzian = Lorentzian(center=0.2, width=0.4, area=3) # THEN - convolution = MyConvolutionFunction( + calculated_convolution = convolution( x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, @@ -165,7 +175,7 @@ def test_components_gauss_lorentzian(self, x, offset_obj, expected_shift, method ) np.testing.assert_allclose( - convolution, + calculated_convolution, expected_result, atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, @@ -184,12 +194,14 @@ def test_components_gauss_lorentzian(self, x, offset_obj, expected_shift, method "method", ["analytical", "numerical"], ids=["analytical", "numerical"] ) def test_components_lorentzian_gauss(self, x, offset_obj, expected_shift, method): + "Test convolution of Lorentzian sample and Gaussian resolution components without SampleModel." + "Test with different offset types and methods." # WHEN resolution_gauss = Gaussian(center=0.1, width=0.3, area=2) sample_lorentzian = Lorentzian(center=0.2, width=0.4, area=3) # THEN - convolution = MyConvolutionFunction( + calculated_convolution = convolution( x=x, sample_model=sample_lorentzian, resolution_model=resolution_gauss, @@ -212,7 +224,7 @@ def test_components_lorentzian_gauss(self, x, offset_obj, expected_shift, method ) np.testing.assert_allclose( - convolution, + calculated_convolution, expected_result, atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, @@ -231,12 +243,14 @@ def test_components_lorentzian_gauss(self, x, offset_obj, expected_shift, method "method", ["analytical", "numerical"], ids=["analytical", "numerical"] ) def test_components_delta_gauss(self, x, offset_obj, expected_shift, method): + "Test convolution of Delta function sample and Gaussian resolution components without SampleModel." + "Test with different offset types and methods." # WHEN sample_delta = DeltaFunction(name="Delta", center=0.1, area=2) resolution_gauss = Gaussian(center=0.2, width=0.3, area=3) # THEN - convolution = MyConvolutionFunction( + calculated_convolution = convolution( x=x, sample_model=sample_delta, resolution_model=resolution_gauss, @@ -255,7 +269,7 @@ def test_components_delta_gauss(self, x, offset_obj, expected_shift, method): / (np.sqrt(2 * np.pi) * resolution_gauss.width.value) ) - np.testing.assert_allclose(convolution, expected_result, atol=1e-10) + np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) @pytest.mark.parametrize( "offset_obj, expected_shift", @@ -270,12 +284,14 @@ def test_components_delta_gauss(self, x, offset_obj, expected_shift, method): "method", ["analytical", "numerical"], ids=["analytical", "numerical"] ) def test_components_gauss_delta(self, x, offset_obj, expected_shift, method): + "Test convolution of Gaussian sample and Delta function resolution components without SampleModel." + "Test with different offset types and methods." # WHEN sample_gauss = Gaussian(center=0.1, width=0.2, area=2) resolution_delta = DeltaFunction(name="Delta", center=0.2, area=3) # THEN - convolution = MyConvolutionFunction( + calculated_convolution = convolution( x=x, sample_model=sample_gauss, resolution_model=resolution_delta, @@ -294,7 +310,7 @@ def test_components_gauss_delta(self, x, offset_obj, expected_shift, method): / (np.sqrt(2 * np.pi) * sample_gauss.width.value) ) - np.testing.assert_allclose(convolution, expected_result, atol=1e-10) + np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) # Test convolution of SampleModel @pytest.mark.parametrize( @@ -312,6 +328,9 @@ def test_components_gauss_delta(self, x, offset_obj, expected_shift, method): def test_model_gauss_gauss_resolution_gauss( self, x, offset_obj, expected_shift, method ): + "Test convolution of Gaussian sample components in SampleModel and Gaussian resolution components in SampleModel." + "Test with different offset types and methods." + # WHEN sample_gauss1 = Gaussian(center=0.1, width=0.3, area=2, name="SampleGauss1") sample_gauss2 = Gaussian(center=0.2, width=0.4, area=3, name="SampleGauss2") @@ -325,7 +344,7 @@ def test_model_gauss_gauss_resolution_gauss( resolution.add_component(resolution_gauss) # THEN - convolution = MyConvolutionFunction( + calculated_convolution = convolution( x=x, sample_model=sample, resolution_model=resolution, @@ -354,12 +373,13 @@ def test_model_gauss_gauss_resolution_gauss( ) / (np.sqrt(2 * np.pi) * expected_width1) + expected_area2 * np.exp( -0.5 * ((x - expected_center2) / expected_width2) ** 2 ) / (np.sqrt(2 * np.pi) * expected_width2) - np.testing.assert_allclose(convolution, expected_result, atol=1e-10) + np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) @pytest.mark.parametrize( "method", ["analytical", "numerical"], ids=["analytical", "numerical"] ) def test_model_lorentzian_delta_resolution_gauss(self, x, method): + "Test convolution of Lorentzian and Delta function sample components in SampleModel and Gaussian resolution components in SampleModel." # WHEN sample_lorentzian = Lorentzian( center=0.1, width=0.3, area=2, name="SampleLorentzian" @@ -376,7 +396,7 @@ def test_model_lorentzian_delta_resolution_gauss(self, x, method): # THEN x = np.linspace(-10, 10, 20001) - convolution = MyConvolutionFunction( + calculated_convolution = convolution( x=x, sample_model=sample, resolution_model=resolution, @@ -395,13 +415,50 @@ def test_model_lorentzian_delta_resolution_gauss(self, x, method): ) expected_result = expected_voigt + expected_gauss np.testing.assert_allclose( - convolution, + calculated_convolution, expected_result, atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, ) # Test numerical convolution + + def test_numerical_convolve_with_temperature(self, x): + "Test numerical convolution with detailed balance correction." + # WHEN + sample_model = SampleModel(name="SampleModel") + sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) + + resolution_model = SampleModel(name="ResolutionModel") + resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) + + temperature = 300.0 # Kelvin + + # THEN + calculated_convolution = convolution( + x=x, + sample_model=sample_model, + resolution_model=resolution_model, + method="numerical", + upsample_factor=5, + temperature=temperature, + ) + + sample_with_db = sample_model.evaluate(x) * detailed_balance_factor( + energy=x, temperature=temperature + ) + resolution = resolution_model.evaluate(x) + + expected_convolution = fftconvolve(sample_with_db, resolution, mode="same") + expected_convolution *= [x[1] - x[0]] # normalize + + np.testing.assert_allclose( + calculated_convolution, + expected_convolution, + atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, + rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, + ) + @pytest.mark.parametrize( "x", [ @@ -411,6 +468,7 @@ def test_model_lorentzian_delta_resolution_gauss(self, x, method): ids=["odd_length", "even_length"], ) def test_numerical_convolve_x_length_even_and_odd(self, x): + "Test numerical convolution with both even and odd length x arrays. With even length the FFT shifts the signal by half a bin." # WHEN sample_model = SampleModel(name="SampleModel") sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) @@ -419,7 +477,7 @@ def test_numerical_convolve_x_length_even_and_odd(self, x): resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) # THEN - convolution = MyConvolutionFunction( + calculated_convolution = convolution( x=x, sample_model=sample_model, resolution_model=resolution_model, @@ -428,7 +486,7 @@ def test_numerical_convolve_x_length_even_and_odd(self, x): ) # EXPECT - expected_convolution = MyConvolutionFunction( + expected_convolution = convolution( x=x, sample_model=sample_model, resolution_model=resolution_model, @@ -436,7 +494,9 @@ def test_numerical_convolve_x_length_even_and_odd(self, x): upsample_factor=0, ) - np.testing.assert_allclose(convolution, expected_convolution, atol=1e-10) + np.testing.assert_allclose( + calculated_convolution, expected_convolution, atol=1e-10 + ) @pytest.mark.parametrize( "upsample_factor", @@ -444,6 +504,7 @@ def test_numerical_convolve_x_length_even_and_odd(self, x): ids=["no_upsample", "upsample_2", "upsample_5", "upsample_10"], ) def test_numerical_convolve_upsample_factor(self, x, upsample_factor): + "Test numerical convolution with different upsample factors." # WHEN sample_model = SampleModel(name="SampleModel") sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) @@ -452,7 +513,7 @@ def test_numerical_convolve_upsample_factor(self, x, upsample_factor): resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) # THEN - convolution = MyConvolutionFunction( + calculated_convolution = convolution( x=x, sample_model=sample_model, resolution_model=resolution_model, @@ -461,7 +522,7 @@ def test_numerical_convolve_upsample_factor(self, x, upsample_factor): ) # EXPECT - expected_convolution = MyConvolutionFunction( + expected_convolution = convolution( x=x, sample_model=sample_model, resolution_model=resolution_model, @@ -470,7 +531,7 @@ def test_numerical_convolve_upsample_factor(self, x, upsample_factor): ) np.testing.assert_allclose( - convolution, + calculated_convolution, expected_convolution, atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, @@ -485,6 +546,7 @@ def test_numerical_convolve_upsample_factor(self, x, upsample_factor): "upsample_factor", [0, 2, 5], ids=["no_upsample", "upsample_2", "upsample_5"] ) def test_numerical_convolve_x_not_symmetric(self, x, upsample_factor): + "Test numerical convolution with asymmetric and only positive x arrays." # WHEN sample_model = SampleModel(name="SampleModel") sample_model.add_component(Gaussian(center=9, width=0.3, area=2)) @@ -493,7 +555,7 @@ def test_numerical_convolve_x_not_symmetric(self, x, upsample_factor): resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) # THEN - convolution = MyConvolutionFunction( + calculated_convolution = convolution( x=x, sample_model=sample_model, resolution_model=resolution_model, @@ -502,7 +564,7 @@ def test_numerical_convolve_x_not_symmetric(self, x, upsample_factor): ) # EXPECT - expected_convolution = MyConvolutionFunction( + expected_convolution = convolution( x=x, sample_model=sample_model, resolution_model=resolution_model, @@ -511,13 +573,14 @@ def test_numerical_convolve_x_not_symmetric(self, x, upsample_factor): ) np.testing.assert_allclose( - convolution, + calculated_convolution, expected_convolution, atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, ) def test_numerical_convolve_x_not_uniform(self): + "Test numerical convolution with non-uniform x arrays." # WHEN sample_model = SampleModel(name="SampleModel") sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) @@ -528,7 +591,7 @@ def test_numerical_convolve_x_not_uniform(self): x_2 = np.linspace(0.001, 2, 2000) x_non_uniform = np.concatenate([x_1, x_2]) # THEN - convolution = MyConvolutionFunction( + calculated_convolution = convolution( x=x_non_uniform, sample_model=sample_model, resolution_model=resolution_model, @@ -537,7 +600,7 @@ def test_numerical_convolve_x_not_uniform(self): ) # EXPECT - expected_convolution = MyConvolutionFunction( + expected_convolution = convolution( x=x_non_uniform, sample_model=sample_model, resolution_model=resolution_model, @@ -545,7 +608,7 @@ def test_numerical_convolve_x_not_uniform(self): ) np.testing.assert_allclose( - convolution, + calculated_convolution, expected_convolution, atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, @@ -557,7 +620,6 @@ def test_analytical_convolution_fails_with_detailed_balance(self, x): # WHEN sample_model = SampleModel(name="SampleModel") sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) - sample_model.temperature = 300 resolution_model = SampleModel(name="ResolutionModel") resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) @@ -567,11 +629,12 @@ def test_analytical_convolution_fails_with_detailed_balance(self, x): ValueError, match="Analytical convolution is not supported with detailed balance.", ): - MyConvolutionFunction( + convolution( x=x, sample_model=sample_model, resolution_model=resolution_model, method="analytical", + temperature=300, ) def test_convolution_only_accepts_analytical_and_numerical_methods(self, x): @@ -587,7 +650,7 @@ def test_convolution_only_accepts_analytical_and_numerical_methods(self, x): ValueError, match="Unknown convolution method: unknown_method. Choose from 'analytical', or 'numerical'.", ): - MyConvolutionFunction( + convolution( x=x, sample_model=sample_model, resolution_model=resolution_model, @@ -604,21 +667,21 @@ def test_x_must_be_1d_finite_array(self): # THEN with pytest.raises(ValueError, match="`x` must be a 1D finite array."): - MyConvolutionFunction( + convolution( x=np.array([[1, 2], [3, 4]]), sample_model=sample_model, resolution_model=resolution_model, ) with pytest.raises(ValueError, match="`x` must be a 1D finite array."): - MyConvolutionFunction( + convolution( x=np.array([1, 2, np.nan]), sample_model=sample_model, resolution_model=resolution_model, ) with pytest.raises(ValueError, match="`x` must be a 1D finite array."): - MyConvolutionFunction( + convolution( x=np.array([1, 2, np.inf]), sample_model=sample_model, resolution_model=resolution_model, @@ -637,7 +700,7 @@ def test_numerical_convolve_requires_uniform_grid_if_no_upsample(self): ValueError, match="Input array `x` must be uniformly spaced if upsample_factor = 0.", ): - MyConvolutionFunction( + convolution( x=x, sample_model=sample_model, resolution_model=resolution_model, @@ -655,7 +718,7 @@ def test_sample_model_must_have_components(self): with pytest.raises( ValueError, match="SampleModel must have at least one component." ): - MyConvolutionFunction( + convolution( x=np.array([0, 1, 2]), sample_model=sample_model, resolution_model=resolution_model, @@ -671,7 +734,7 @@ def test_resolution_model_must_have_components(self): with pytest.raises( ValueError, match="ResolutionModel must have at least one component." ): - MyConvolutionFunction( + convolution( x=np.array([0, 1, 2]), sample_model=sample_model, resolution_model=resolution_model, @@ -695,7 +758,7 @@ def test_numerical_convolution_wide_sample_peak_gives_warning(self): UserWarning, match=r"The width of the sample model component 'SampleGauss' \(1.9\) is large", ): - MyConvolutionFunction( + convolution( x=x, sample_model=sample, resolution_model=resolution, @@ -723,7 +786,7 @@ def test_numerical_convolution_wide_resolution_peak_gives_warning(self): UserWarning, match=r"The width of the resolution model component 'ResolutionGauss' \(1.9\) is large", ): - MyConvolutionFunction( + convolution( x=x, sample_model=sample, resolution_model=resolution, @@ -749,7 +812,7 @@ def test_numerical_convolution_narrow_sample_peak_gives_warning(self): UserWarning, match=r"The width of the sample model component 'SampleGauss' \(0.001\) is small", ): - MyConvolutionFunction( + convolution( x=x, sample_model=sample, resolution_model=resolution, @@ -777,7 +840,7 @@ def test_numerical_convolution_narrow_resolution_peak_gives_warning(self): UserWarning, match=r"The width of the resolution model component 'ResolutionGauss' \(0.001\) is small", ): - MyConvolutionFunction( + convolution( x=x, sample_model=sample, resolution_model=resolution, From 05b74652552aeb19c03394772b78faaf6e16f606 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 29 Oct 2025 20:57:53 +0100 Subject: [PATCH 16/71] Cleaning up --- src/easydynamics/utils/convolution.py | 126 +++++++++++++-------- tests/unit_tests/utils/test_convolution.py | 44 ++++++- 2 files changed, 120 insertions(+), 50 deletions(-) diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py index 8d8b880..4227e46 100644 --- a/src/easydynamics/utils/convolution.py +++ b/src/easydynamics/utils/convolution.py @@ -32,6 +32,30 @@ def convolution( Calculate the convolution of a sample model with a resolution model using analytical expressions or numerical FFT. Accepts SampleModel or ModelComponent for both sample and resolution. The analytical method silently falls back to numerical convolution if no analytical expression is found. + + Args: + x : np.ndarray + 1D array of x values where the convolution is evaluated. + sample_model : SampleModel or ModelComponent + The sample model to be convolved. + resolution_model : SampleModel or ModelComponent + The resolution model to convolve with. + offset : Parameter, float, or None, optional + The offset to apply to the x values before convolution. + method : str, optional + The convolution method to use: 'analytical' or 'numerical'. Default is 'analytical'. + upsample_factor : int, optional + The factor by which to upsample the input data before numerical convolution. Default is 0 (no upsampling). + extension_factor : float, optional + The factor by which to extend the input data range before numerical convolution. Default is 0.2. + temperature : Parameter, float, or None, optional + The temperature to use for detailed balance calculations. Default is None. + temperature_unit : str or sc.Unit, optional + The unit of the temperature parameter. Default is 'K'. + x_unit : str or sc.Unit, optional + The unit of the x parameter. Default is 'meV'. + normalize_detailed_balance : bool, optional + Whether to normalize the detailed balance factor. Default is True. """ if not isinstance(x, np.ndarray): raise TypeError( @@ -60,6 +84,17 @@ def convolution( if not resolution_model.components: raise ValueError("ResolutionModel must have at least one component.") + if offset is None: + off = 0.0 + elif isinstance(offset, Parameter): + off = offset.value + elif isinstance(offset, float): + off = offset + else: + raise TypeError( + f"Expected offset to be Parameter, float, or None, got {type(offset)}" + ) + if method == "analytical": if isinstance(sample_model, SampleModel) and temperature is not None: raise ValueError( @@ -69,7 +104,7 @@ def convolution( x=x, sample_model=sample_model, resolution_model=resolution_model, - offset=offset, + offset=off, upsample_factor=upsample_factor, extension_factor=extension_factor, ) @@ -79,7 +114,7 @@ def convolution( x=x, sample_model=sample_model, resolution_model=resolution_model, - offset=offset, + offset=off, upsample_factor=upsample_factor, extension_factor=extension_factor, temperature=temperature, @@ -96,8 +131,8 @@ def convolution( def _numerical_convolution( x: np.ndarray, - sample_model: Union[SampleModel, ModelComponent, np.ndarray], - resolution_model: Union[SampleModel, ModelComponent, np.ndarray], + sample_model: Union[SampleModel, ModelComponent], + resolution_model: Union[SampleModel, ModelComponent], offset: Union[Parameter, np.ndarray, None] = None, upsample_factor: int = 5, extension_factor: float = 0.2, @@ -108,25 +143,40 @@ def _numerical_convolution( ) -> np.ndarray: """ Numerical convolution using FFT with optional upsampling + extended range. - - sample_model / resolution_model may be: - - SampleModel - - ModelComponent - - Callable: f(x: np.ndarray) -> np.ndarray - offset: Union[Parameter, np.ndarray, None]: The offset on the x axis - upsample_factor: int: The factor by which to upsample the input array to improve resolution - extension_factor: float: The factor by which to extend the range of the input array to improve accuracy at the edges - selected_component_name: Union[str, None]: If provided, the name of the component to be selected for evaluation + Includes detailed balance correction if temperature is provided. + + Args: + x : np.ndarray + 1D array of x values where the convolution is evaluated. + sample_model : SampleModel or ModelComponent + The sample model to be convolved. + resolution_model : SampleModel or ModelComponent + The resolution model to convolve with. + offset : Parameter, float, or None, optional + The offset to apply to the input array. + upsample_factor : int, optional + The factor by which to upsample the input data before convolution. Default is 5. + extension_factor : float, optional + The factor by which to extend the input data range before convolution. Default is 0.2. + temperature : Parameter, float, or None, optional + The temperature to use for detailed balance correction. Default is None. + temperature_unit : str or sc.Unit, optional + The unit of the temperature parameter. Default is 'K'. + x_unit : str or sc.Unit, optional + The unit of the x parameter. Default is 'meV'. + normalize_detailed_balance : bool, optional + Whether to normalize the detailed balance factor. Default is True. + Returns: + np.ndarray + The convolved values evaluated at x. """ - def is_uniform(xarr, rtol=1e-5) -> bool: - """Check if the array is uniformly spaced.""" - dx = np.diff(xarr) - return np.allclose(dx, dx[0], rtol=rtol) - # Build dense grid if upsample_factor == 0: - if not is_uniform(x): + # Check if the array is uniformly spaced. + dx = np.diff(x) + is_uniform = np.allclose(dx, dx[0]) + if not is_uniform: raise ValueError( "Input array `x` must be uniformly spaced if upsample_factor = 0." ) @@ -140,22 +190,11 @@ def is_uniform(xarr, rtol=1e-5) -> bool: extended_max = x_max + extra num_points = len(x) * upsample_factor x_dense = np.linspace(extended_min, extended_max, num_points) - if offset is None: - off = 0.0 - elif isinstance(offset, Parameter): - off = offset.value - elif isinstance(offset, float): - off = offset - else: - raise TypeError( - f"Expected offset to be Parameter, float, or None, got {type(offset)}" - ) - dx = x_dense[1] - x_dense[0] span = x_dense.max() - x_dense.min() # Handle offset for even length of x in convolution if len(x_dense) % 2 == 0: - off2 = -0.5 * dx + off2 = -0.5 * (x_dense[1] - x_dense[0]) else: off2 = 0.0 @@ -171,11 +210,11 @@ def is_uniform(xarr, rtol=1e-5) -> bool: # Evaluate on dense grid if isinstance(sample_model, SampleModel): - sample_vals = sample_model.evaluate_without_delta(x_dense - off - off2) + sample_vals = sample_model.evaluate_without_delta(x_dense - offset - off2) elif isinstance(sample_model, DeltaFunction): sample_vals = np.zeros_like(x_dense) else: - sample_vals = sample_model.evaluate(x_dense - off - off2) + sample_vals = sample_model.evaluate(x_dense - offset - off2) # Detailed balance correction if temperature is not None: @@ -219,22 +258,22 @@ def is_uniform(xarr, rtol=1e-5) -> bool: for comp in sample_model.components: if isinstance(comp, DeltaFunction): convolved += comp.area.value * resolution_model.evaluate( - x_dense - off - comp.center.value + x_dense - offset - comp.center.value ) elif isinstance(sample_model, DeltaFunction): convolved += sample_model.area.value * resolution_model.evaluate( - x_dense - off - sample_model.center.value + x_dense - offset - sample_model.center.value ) if isinstance(resolution_model, SampleModel): for comp in resolution_model.components: if isinstance(comp, DeltaFunction): convolved += comp.area.value * sample_model.evaluate( - x_dense - off - comp.center.value + x_dense - offset - comp.center.value ) elif isinstance(resolution_model, DeltaFunction): convolved += resolution_model.area.value * sample_model.evaluate( - x_dense - off - resolution_model.center.value + x_dense - offset - resolution_model.center.value ) # TODO: if both resolution and sample are delta functions, we should let the user know that they are wrong. @@ -265,17 +304,6 @@ def _analytical_convolution( - Handles delta functions analytically. """ - if offset is None: - off = 0.0 - elif isinstance(offset, Parameter): - off = offset.value - elif isinstance(offset, float): - off = offset - else: - raise TypeError( - f"Expected offset to be Parameter, float, or None, got {type(offset)}" - ) - # prepare list of components if isinstance(sample_model, SampleModel): sample_components = sample_model.components @@ -295,7 +323,7 @@ def _analytical_convolution( # Go through resolution components, adding analytical contributions where possible, making a list of those that cannot be handled analytically for r in resolution_components: - handled, contrib = _try_analytic_pair(x, s, r, off) + handled, contrib = _try_analytic_pair(x, s, r, offset) if handled: total += contrib else: diff --git a/tests/unit_tests/utils/test_convolution.py b/tests/unit_tests/utils/test_convolution.py index ae8a49b..5fc586f 100644 --- a/tests/unit_tests/utils/test_convolution.py +++ b/tests/unit_tests/utils/test_convolution.py @@ -4,7 +4,13 @@ from scipy.signal import fftconvolve from scipy.special import voigt_profile -from easydynamics.sample_model import DeltaFunction, Gaussian, Lorentzian, SampleModel +from easydynamics.sample_model import ( + DampedHarmonicOscillator, + DeltaFunction, + Gaussian, + Lorentzian, + SampleModel, +) from easydynamics.utils import convolution from easydynamics.utils.detailed_balance import ( _detailed_balance_factor as detailed_balance_factor, @@ -77,6 +83,42 @@ def test_components_gauss_gauss(self, x, offset_obj, expected_shift, method): np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) + @pytest.mark.parametrize( + "offset_obj, expected_shift", + [ + (None, 0.0), + (0.4, 0.4), + (Parameter("off", 0.4), 0.4), + ], + ids=["none", "float", "parameter"], + ) + @pytest.mark.parametrize( + "method", ["analytical", "numerical"], ids=["analytical", "numerical"] + ) + def test_components_DHO_gauss(self, x, offset_obj, expected_shift, method): + "Test convolution of DHO sample and Gaussian resolution components without SampleModel." + "Test with different offset types and methods." + # WHEN + sample_dho = DampedHarmonicOscillator(center=1.5, width=0.3, area=2) + resolution_gauss = Gaussian(center=0.2, width=0.4, area=3) + + # THEN + calculated_convolution = convolution( + x=x, + sample_model=sample_dho, + resolution_model=resolution_gauss, + offset=offset_obj, + method=method, + ) + + # EXPECT + sample_values = sample_dho.evaluate(x - expected_shift) + resolution_values = resolution_gauss.evaluate(x) + expected_result = fftconvolve(sample_values, resolution_values, mode="same") + expected_result *= x[1] - x[0] # normalize + + np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) + @pytest.mark.parametrize( "offset_obj, expected_shift", [ From 6c59a053c8218e7feb464adeb2bda377298d64aa Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 29 Oct 2025 21:02:12 +0100 Subject: [PATCH 17/71] Fix test --- src/easydynamics/utils/convolution.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py index 4227e46..2f96cbd 100644 --- a/src/easydynamics/utils/convolution.py +++ b/src/easydynamics/utils/convolution.py @@ -96,7 +96,7 @@ def convolution( ) if method == "analytical": - if isinstance(sample_model, SampleModel) and temperature is not None: + if temperature is not None: raise ValueError( "Analytical convolution is not supported with detailed balance. Set method to 'numerical' instead or set the temperature to None." ) @@ -133,13 +133,13 @@ def _numerical_convolution( x: np.ndarray, sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], - offset: Union[Parameter, np.ndarray, None] = None, - upsample_factor: int = 5, - extension_factor: float = 0.2, - temperature: Union[Parameter, float, None] = None, - temperature_unit: Union[str, sc.Unit] = "K", + offset: Optional[Union[Parameter, np.ndarray]] = None, + upsample_factor: Optional[int] = 5, + extension_factor: Optional[float] = 0.2, + temperature: Optional[Union[Parameter, float]] = None, + temperature_unit: Optional[Union[str, sc.Unit]] = "K", x_unit: Optional[Union[str, sc.Unit]] = "meV", - normalize_detailed_balance: bool = True, + normalize_detailed_balance: Optional[bool] = True, ) -> np.ndarray: """ Numerical convolution using FFT with optional upsampling + extended range. @@ -174,8 +174,8 @@ def _numerical_convolution( # Build dense grid if upsample_factor == 0: # Check if the array is uniformly spaced. - dx = np.diff(x) - is_uniform = np.allclose(dx, dx[0]) + x_diff = np.diff(x) + is_uniform = np.allclose(x_diff, x_diff[0]) if not is_uniform: raise ValueError( "Input array `x` must be uniformly spaced if upsample_factor = 0." @@ -191,10 +191,11 @@ def _numerical_convolution( num_points = len(x) * upsample_factor x_dense = np.linspace(extended_min, extended_max, num_points) + dx = x_dense[1] - x_dense[0] span = x_dense.max() - x_dense.min() # Handle offset for even length of x in convolution if len(x_dense) % 2 == 0: - off2 = -0.5 * (x_dense[1] - x_dense[0]) + off2 = -0.5 * dx else: off2 = 0.0 From fd3eff67dbd9f007bf78f67d397f743594daed57 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 29 Oct 2025 21:39:45 +0100 Subject: [PATCH 18/71] make tests nicer --- src/easydynamics/utils/convolution.py | 2 + tests/unit_tests/utils/test_convolution.py | 200 +++++++++------------ 2 files changed, 91 insertions(+), 111 deletions(-) diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py index 2f96cbd..98c0776 100644 --- a/src/easydynamics/utils/convolution.py +++ b/src/easydynamics/utils/convolution.py @@ -57,6 +57,8 @@ def convolution( normalize_detailed_balance : bool, optional Whether to normalize the detailed balance factor. Default is True. """ + + # Input validation if not isinstance(x, np.ndarray): raise TypeError( f"`x` is an instance of {type(x).__name__}, but must be a numpy array." diff --git a/tests/unit_tests/utils/test_convolution.py b/tests/unit_tests/utils/test_convolution.py index 5fc586f..ef64046 100644 --- a/tests/unit_tests/utils/test_convolution.py +++ b/tests/unit_tests/utils/test_convolution.py @@ -34,6 +34,22 @@ def resolution_model(self): test_resolution_model.add_component(Gaussian(center=0.2, width=0.3, area=3.0)) return test_resolution_model + @pytest.fixture + def gaussian_component(self): + return Gaussian(center=0.1, width=0.3, area=2.0) + + @pytest.fixture + def other_gaussian_component(self): + return Gaussian(center=0.2, width=0.4, area=3.0) + + @pytest.fixture + def lorentzian_component(self): + return Lorentzian(center=0.1, width=0.3, area=2.0) + + @pytest.fixture + def other_lorentzian_component(self): + return Lorentzian(center=0.2, width=0.4, area=3.0) + @pytest.fixture def x(self): return np.linspace(-50, 50, 50001) @@ -51,12 +67,20 @@ def x(self): @pytest.mark.parametrize( "method", ["analytical", "numerical"], ids=["analytical", "numerical"] ) - def test_components_gauss_gauss(self, x, offset_obj, expected_shift, method): + def test_components_gauss_gauss( + self, + x, + gaussian_component, + other_gaussian_component, + offset_obj, + expected_shift, + method, + ): "Test convolution of Gaussian sample and Gaussian resolution components without SampleModel." "Test with different offset types and methods." # WHEN - sample_gauss = Gaussian(center=0.1, width=0.3, area=2) - resolution_gauss = Gaussian(center=0.2, width=0.4, area=3) + sample_gauss = gaussian_component + resolution_gauss = other_gaussian_component # THEN calculated_convolution = convolution( @@ -68,6 +92,7 @@ def test_components_gauss_gauss(self, x, offset_obj, expected_shift, method): ) # EXPECT + # Convolution of two Gaussians is another Gaussian with width = sqrt(w1^2 + w2^2) expected_width = np.sqrt( sample_gauss.width.value**2 + resolution_gauss.width.value**2 ) @@ -95,12 +120,14 @@ def test_components_gauss_gauss(self, x, offset_obj, expected_shift, method): @pytest.mark.parametrize( "method", ["analytical", "numerical"], ids=["analytical", "numerical"] ) - def test_components_DHO_gauss(self, x, offset_obj, expected_shift, method): + def test_components_DHO_gauss( + self, x, gaussian_component, offset_obj, expected_shift, method + ): "Test convolution of DHO sample and Gaussian resolution components without SampleModel." "Test with different offset types and methods." # WHEN sample_dho = DampedHarmonicOscillator(center=1.5, width=0.3, area=2) - resolution_gauss = Gaussian(center=0.2, width=0.4, area=3) + resolution_gauss = gaussian_component # THEN calculated_convolution = convolution( @@ -112,6 +139,7 @@ def test_components_DHO_gauss(self, x, offset_obj, expected_shift, method): ) # EXPECT + # no simple analytical form, so compute expected result via direct convolution sample_values = sample_dho.evaluate(x - expected_shift) resolution_values = resolution_gauss.evaluate(x) expected_result = fftconvolve(sample_values, resolution_values, mode="same") @@ -132,13 +160,19 @@ def test_components_DHO_gauss(self, x, offset_obj, expected_shift, method): "method", ["analytical", "numerical"], ids=["analytical", "numerical"] ) def test_components_lorentzian_lorentzian( - self, x, offset_obj, expected_shift, method + self, + x, + lorentzian_component, + other_lorentzian_component, + offset_obj, + expected_shift, + method, ): "Test convolution of Lorentzian sample and Lorentzian resolution components without SampleModel." "Test with different offset types and methods." # WHEN - sample_lorentzian = Lorentzian(center=0.1, width=0.3, area=2) - resolution_lorentzian = Lorentzian(center=0.2, width=0.4, area=3) + sample_lorentzian = lorentzian_component + resolution_lorentzian = other_lorentzian_component # THEN calculated_convolution = convolution( @@ -151,6 +185,7 @@ def test_components_lorentzian_lorentzian( ) # EXPECT + # Convolution of two Lorentzians is another Lorentzian with width = w1 + w2 expected_width = ( sample_lorentzian.width.value + resolution_lorentzian.width.value ) @@ -186,83 +221,56 @@ def test_components_lorentzian_lorentzian( @pytest.mark.parametrize( "method", ["analytical", "numerical"], ids=["analytical", "numerical"] ) - def test_components_gauss_lorentzian(self, x, offset_obj, expected_shift, method): - "Test convolution of Gaussian sample and Lorentzian resolution components without SampleModel." + @pytest.mark.parametrize( + "sample_is_gauss", + [True, False], + ids=["gauss_sample__lorentz_resolution", "lorentz_sample__gauss_resolution"], + ) + def test_components_gauss_lorentzian( + self, + x, + gaussian_component, + lorentzian_component, + offset_obj, + expected_shift, + method, + sample_is_gauss, + ): + "Test convolution of Gaussian and Lorentzian components without SampleModel." "Test with different offset types and methods." # WHEN - sample_gauss = Gaussian(center=0.1, width=0.3, area=2) - resolution_lorentzian = Lorentzian(center=0.2, width=0.4, area=3) + if sample_is_gauss: + sample = gaussian_component + resolution = lorentzian_component + else: + sample = lorentzian_component + resolution = gaussian_component # THEN calculated_convolution = convolution( x=x, - sample_model=sample_gauss, - resolution_model=resolution_lorentzian, + sample_model=sample, + resolution_model=resolution, offset=offset_obj, method=method, upsample_factor=5, ) # EXPECT - expected_center = ( - sample_gauss.center.value - + resolution_lorentzian.center.value - + expected_shift - ) - expected_area = sample_gauss.area.value * resolution_lorentzian.area.value - expected_result = expected_area * voigt_profile( - x - expected_center, - sample_gauss.width.value, - resolution_lorentzian.width.value, - ) + expected_center = sample.center.value + resolution.center.value + expected_shift + expected_area = sample.area.value * resolution.area.value - np.testing.assert_allclose( - calculated_convolution, - expected_result, - atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, - rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, + gaussian_width = ( + sample.width.value if sample_is_gauss else resolution.width.value ) - - @pytest.mark.parametrize( - "offset_obj, expected_shift", - [ - (None, 0.0), - (0.4, 0.4), - (Parameter("off", 0.4), 0.4), - ], - ids=["none", "float", "parameter"], - ) - @pytest.mark.parametrize( - "method", ["analytical", "numerical"], ids=["analytical", "numerical"] - ) - def test_components_lorentzian_gauss(self, x, offset_obj, expected_shift, method): - "Test convolution of Lorentzian sample and Gaussian resolution components without SampleModel." - "Test with different offset types and methods." - # WHEN - resolution_gauss = Gaussian(center=0.1, width=0.3, area=2) - sample_lorentzian = Lorentzian(center=0.2, width=0.4, area=3) - - # THEN - calculated_convolution = convolution( - x=x, - sample_model=sample_lorentzian, - resolution_model=resolution_gauss, - offset=offset_obj, - method=method, - upsample_factor=5, + lorentzian_width = ( + resolution.width.value if sample_is_gauss else sample.width.value ) - # EXPECT - expected_center = ( - sample_lorentzian.center.value - + resolution_gauss.center.value - + expected_shift - ) - expected_area = sample_lorentzian.area.value * resolution_gauss.area.value expected_result = expected_area * voigt_profile( x - expected_center, - resolution_gauss.width.value, - sample_lorentzian.width.value, + gaussian_width, + lorentzian_width, ) np.testing.assert_allclose( @@ -284,12 +292,23 @@ def test_components_lorentzian_gauss(self, x, offset_obj, expected_shift, method @pytest.mark.parametrize( "method", ["analytical", "numerical"], ids=["analytical", "numerical"] ) - def test_components_delta_gauss(self, x, offset_obj, expected_shift, method): + @pytest.mark.parametrize( + "sample_is_gauss", + [True, False], + ids=["gauss_sample__delta_resolution", "delta_sample__gauss_resolution"], + ) + def test_components_delta_gauss( + self, x, gaussian_component, offset_obj, expected_shift, method, sample_is_gauss + ): "Test convolution of Delta function sample and Gaussian resolution components without SampleModel." "Test with different offset types and methods." # WHEN - sample_delta = DeltaFunction(name="Delta", center=0.1, area=2) - resolution_gauss = Gaussian(center=0.2, width=0.3, area=3) + if sample_is_gauss: + sample_delta = DeltaFunction(name="Delta", center=0.1, area=2) + resolution_gauss = gaussian_component + else: + sample_delta = DeltaFunction(name="Delta", center=0.1, area=2) + resolution_gauss = gaussian_component # THEN calculated_convolution = convolution( @@ -313,47 +332,6 @@ def test_components_delta_gauss(self, x, offset_obj, expected_shift, method): np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) - @pytest.mark.parametrize( - "offset_obj, expected_shift", - [ - (None, 0.0), - (0.4, 0.4), - (Parameter("off", 0.4), 0.4), - ], - ids=["none", "float", "parameter"], - ) - @pytest.mark.parametrize( - "method", ["analytical", "numerical"], ids=["analytical", "numerical"] - ) - def test_components_gauss_delta(self, x, offset_obj, expected_shift, method): - "Test convolution of Gaussian sample and Delta function resolution components without SampleModel." - "Test with different offset types and methods." - # WHEN - sample_gauss = Gaussian(center=0.1, width=0.2, area=2) - resolution_delta = DeltaFunction(name="Delta", center=0.2, area=3) - - # THEN - calculated_convolution = convolution( - x=x, - sample_model=sample_gauss, - resolution_model=resolution_delta, - offset=offset_obj, - method=method, - ) - - # EXPECT - expected_center = ( - sample_gauss.center.value + resolution_delta.center.value + expected_shift - ) - expected_area = sample_gauss.area.value * resolution_delta.area.value - expected_result = ( - expected_area - * np.exp(-0.5 * ((x - expected_center) / sample_gauss.width.value) ** 2) - / (np.sqrt(2 * np.pi) * sample_gauss.width.value) - ) - - np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) - # Test convolution of SampleModel @pytest.mark.parametrize( "offset_obj, expected_shift", From 0d6d63a311742c380e2f29e47ad86740b3005c63 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 29 Oct 2025 22:30:12 +0100 Subject: [PATCH 19/71] fix test --- tests/unit_tests/utils/test_convolution.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/tests/unit_tests/utils/test_convolution.py b/tests/unit_tests/utils/test_convolution.py index ef64046..922f6f2 100644 --- a/tests/unit_tests/utils/test_convolution.py +++ b/tests/unit_tests/utils/test_convolution.py @@ -304,30 +304,28 @@ def test_components_delta_gauss( "Test with different offset types and methods." # WHEN if sample_is_gauss: - sample_delta = DeltaFunction(name="Delta", center=0.1, area=2) - resolution_gauss = gaussian_component + sample = DeltaFunction(name="Delta", center=0.1, area=2) + resolution = gaussian_component else: - sample_delta = DeltaFunction(name="Delta", center=0.1, area=2) - resolution_gauss = gaussian_component + resolution = DeltaFunction(name="Delta", center=0.1, area=2) + sample = gaussian_component # THEN calculated_convolution = convolution( x=x, - sample_model=sample_delta, - resolution_model=resolution_gauss, + sample_model=sample, + resolution_model=resolution, offset=offset_obj, method=method, ) # EXPECT - expected_center = ( - sample_delta.center.value + resolution_gauss.center.value + expected_shift - ) - expected_area = sample_delta.area.value * resolution_gauss.area.value + expected_center = sample.center.value + resolution.center.value + expected_shift + expected_area = sample.area.value * resolution.area.value expected_result = ( expected_area - * np.exp(-0.5 * ((x - expected_center) / resolution_gauss.width.value) ** 2) - / (np.sqrt(2 * np.pi) * resolution_gauss.width.value) + * np.exp(-0.5 * ((x - expected_center) / resolution.width.value) ** 2) + / (np.sqrt(2 * np.pi) * resolution.width.value) ) np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) From 5f7da95bd6bc0da5c91a18b281c0089103fbb860 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 29 Oct 2025 22:32:52 +0100 Subject: [PATCH 20/71] fix test --- tests/unit_tests/utils/test_convolution.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/unit_tests/utils/test_convolution.py b/tests/unit_tests/utils/test_convolution.py index 922f6f2..56372ee 100644 --- a/tests/unit_tests/utils/test_convolution.py +++ b/tests/unit_tests/utils/test_convolution.py @@ -304,11 +304,11 @@ def test_components_delta_gauss( "Test with different offset types and methods." # WHEN if sample_is_gauss: + sample = gaussian_component + resolution = DeltaFunction(name="Delta", center=0.1, area=2) + else: sample = DeltaFunction(name="Delta", center=0.1, area=2) resolution = gaussian_component - else: - resolution = DeltaFunction(name="Delta", center=0.1, area=2) - sample = gaussian_component # THEN calculated_convolution = convolution( @@ -322,10 +322,11 @@ def test_components_delta_gauss( # EXPECT expected_center = sample.center.value + resolution.center.value + expected_shift expected_area = sample.area.value * resolution.area.value + width = sample.width.value if sample_is_gauss else resolution.width.value expected_result = ( expected_area - * np.exp(-0.5 * ((x - expected_center) / resolution.width.value) ** 2) - / (np.sqrt(2 * np.pi) * resolution.width.value) + * np.exp(-0.5 * ((x - expected_center) / width) ** 2) + / (np.sqrt(2 * np.pi) * width) ) np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) From f8deef311e1e86cff118a4d98b3ec76951869d1e Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Thu, 30 Oct 2025 13:48:28 +0100 Subject: [PATCH 21/71] Small update --- examples/convolution.ipynb | 52 ++----- src/easydynamics/utils/convolution.py | 155 +++++++++++++-------- tests/unit_tests/utils/test_convolution.py | 1 - 3 files changed, 108 insertions(+), 100 deletions(-) diff --git a/examples/convolution.ipynb b/examples/convolution.ipynb index bc203c3..2e9a686 100644 --- a/examples/convolution.ipynb +++ b/examples/convolution.ipynb @@ -5,43 +5,7 @@ "execution_count": null, "id": "f42e34d0", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "b0f508b8d2114e1b8c6bb386a9b32bbe", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "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zz33nLXbbrtZK1as6H/smGOOsaZPn26ee+qpp6xddtnFOvHEE61y8Y9//MNc/WVf7fpe9vuw349dd9vixYvNVcJz5861lixZYt1///3WTjvtZB122GFWuXn66afNFcD2tnrrrbesO+64w2yvU045ZdD3ZzvzzDOt8ePHW48++qh5nwcddJC5lRu77jvvvLN15JFHmunVq1f33yp1+919993mCsPbbrvNXEF/xhlnWA0NDf1X3p988snWpZde2j//v/71L8vv91s//vGPzd+vfRWqfRX3ggULrHJz1llnmStCH3/88U22VSKR6J/nve/P3hc99NBD5u933rx51he+8AUrHA5br776qlWOLrroIvP+7L8te9vMnDnTGjZsmLniudK338ArWu39wyWXXPK+5ypx+9nfb33fdfb3wDXXXGOm7e9D21VXXWU+g/a+4uWXX7aOP/5409NAT09P/zI++tGPWtdff/1Wf44xOAJgiZx66qnmA/De22OPPdY/zzvvvGMde+yxViQSMTs2e4eXyWT6n7fntV9j7wD7bNiwwQQ+O1TaXcacdtpp/aGyHNh1O/jggzf7nP0+Bv4bLFu2zISFpqYm8wG3A8jFF19sdXR0WOXG3uHaXUrYX7r2Tnfq1KnWD37wAyuZTA76/mz2ju3rX/+61djYaEWjUes//uM/NglV5cLuYmJzf68Df0NW4vazv0jsL9hgMGi6k3j22Wc36cLG/pwO9Lvf/c7addddzfzTpk2z/vrXv1rlaLBtZW/Hwd7fBRdc0P9vMXLkSOvjH/+49eKLL1rl6vOf/7w1evRoU98xY8aY+/aPjmrYfn3sQGdvt4ULF77vuUrcfn3fWe+99b0PuyuYyy67zNTf3mfYPzjf+97t7rbs8L61n2MMzmP/b2CLIAAAAKob/QACAAC4DAEQAADAZQiAAAAALkMABAAAcBkCIAAAgMsQAAEAAFyGAAgAAOAyBEAAAACXIQACAAC4DAEQAADAZQiAAAAALkMABAAAcBkCIAAAgMsQAAEAAFyGAAgAAOAyBEAAAACXIQACAAC4DAEQAADAZQiAAAAALkMABAAAcBkCIAAAgMsQAAEAAFyGAAgAAOAyBEAAAACXIQACAAC4DAEQAADAZQiAAAAALkMABAAAcBkCIAAAgMsQAAEAAFyGAAgAACB3+f8Mpeg/hrT37AAAAABJRU5ErkJggg==", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "import numpy as np\n", "from easyscience.variable import Parameter\n", @@ -72,7 +36,7 @@ "\n", "# THEN\n", "x = np.linspace(-10, 10, 20001)\n", - "convolution = convolution(\n", + "calculated_convolution = convolution(\n", " x=x,\n", " sample_model=sample,\n", " resolution_model=resolution,\n", @@ -93,9 +57,19 @@ "\n", "import matplotlib.pyplot as plt\n", "%matplotlib widget\n", - "plt.plot(x, convolution, label=\"Convolution Result\")\n", + "plt.plot(x, calculated_convolution, label=\"Convolution Result\")\n", "plt.plot(x, expected_result, label=\"Expected Result\", linestyle='dashed')" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "600c0850", + "metadata": {}, + "outputs": [], + "source": [ + "print(calculated_convolution)" + ] } ], "metadata": { diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py index 98c0776..082ea11 100644 --- a/src/easydynamics/utils/convolution.py +++ b/src/easydynamics/utils/convolution.py @@ -1,10 +1,9 @@ import warnings -from typing import Optional, Tuple, Union +from typing import List, Optional, Tuple, Union import numpy as np import scipp as sc from easyscience.variable import Parameter -from scipy.interpolate import interp1d from scipy.signal import fftconvolve from scipy.special import voigt_profile @@ -14,6 +13,8 @@ _detailed_balance_factor as detailed_balance_factor, ) +Numerical = Union[float, int] + def convolution( x: np.ndarray, @@ -32,6 +33,7 @@ def convolution( Calculate the convolution of a sample model with a resolution model using analytical expressions or numerical FFT. Accepts SampleModel or ModelComponent for both sample and resolution. The analytical method silently falls back to numerical convolution if no analytical expression is found. + Detailed balancing is included if temperature is provided. This requires numerical convolution. Args: x : np.ndarray @@ -90,11 +92,11 @@ def convolution( off = 0.0 elif isinstance(offset, Parameter): off = offset.value - elif isinstance(offset, float): - off = offset + elif isinstance(offset, Numerical): + off = float(offset) else: raise TypeError( - f"Expected offset to be Parameter, float, or None, got {type(offset)}" + f"Expected offset to be Parameter, number, or None, got {type(offset)}" ) if method == "analytical": @@ -110,8 +112,7 @@ def convolution( upsample_factor=upsample_factor, extension_factor=extension_factor, ) - - if method == "numerical": + elif method == "numerical": return _numerical_convolution( x=x, sample_model=sample_model, @@ -124,8 +125,7 @@ def convolution( x_unit=x_unit, normalize_detailed_balance=normalize_detailed_balance, ) - - if method not in ["analytical", "numerical"]: + else: raise ValueError( f"Unknown convolution method: {method}. Choose from 'analytical', or 'numerical'." ) @@ -197,9 +197,9 @@ def _numerical_convolution( span = x_dense.max() - x_dense.min() # Handle offset for even length of x in convolution if len(x_dense) % 2 == 0: - off2 = -0.5 * dx + x_even_length_offset = -0.5 * dx else: - off2 = 0.0 + x_even_length_offset = 0.0 # Handle the case when x is not symmetric around zero. The resolution is still centered around zero (or close to it), so it needs to be evaluated there. if not np.isclose(x_dense.mean(), 0.0): @@ -211,13 +211,15 @@ def _numerical_convolution( _check_width_thresholds(sample_model, span, dx, "sample model") _check_width_thresholds(resolution_model, span, dx, "resolution model") - # Evaluate on dense grid + # Evaluate on dense grid and interpolate at the end if isinstance(sample_model, SampleModel): - sample_vals = sample_model.evaluate_without_delta(x_dense - offset - off2) + sample_vals = sample_model.evaluate_without_delta( + x_dense - offset - x_even_length_offset + ) elif isinstance(sample_model, DeltaFunction): sample_vals = np.zeros_like(x_dense) else: - sample_vals = sample_model.evaluate(x_dense - offset - off2) + sample_vals = sample_model.evaluate(x_dense - offset - x_even_length_offset) # Detailed balance correction if temperature is not None: @@ -245,6 +247,7 @@ def _numerical_convolution( ) sample_vals *= detailed_balance_factor_correction + # Delta functions are handled separately for accuracy if isinstance(resolution_model, SampleModel): resolution_vals = resolution_model.evaluate_without_delta(x_dense_resolution) elif isinstance(resolution_model, DeltaFunction): @@ -256,38 +259,35 @@ def _numerical_convolution( convolved = fftconvolve(sample_vals, resolution_vals, mode="same") convolved *= dx # normalize - # Add delta contributions - if isinstance(sample_model, SampleModel): - for comp in sample_model.components: - if isinstance(comp, DeltaFunction): - convolved += comp.area.value * resolution_model.evaluate( - x_dense - offset - comp.center.value - ) - elif isinstance(sample_model, DeltaFunction): - convolved += sample_model.area.value * resolution_model.evaluate( - x_dense - offset - sample_model.center.value + if upsample_factor > 0: + # interpolate back to original x grid + convolved = np.interp(x, x_dense, convolved, left=0.0, right=0.0) + + # Add delta contributions on original grid + # collect deltas + sample_deltas = _delta_components(sample_model) + resolution_deltas = _delta_components(resolution_model) + + # error if both contain delta(s) + if sample_deltas and resolution_deltas: + raise ValueError( + "Both sample_model and resolution_model contain delta functions. " + "Their convolution is not defined." ) - if isinstance(resolution_model, SampleModel): - for comp in resolution_model.components: - if isinstance(comp, DeltaFunction): - convolved += comp.area.value * sample_model.evaluate( - x_dense - offset - comp.center.value - ) - elif isinstance(resolution_model, DeltaFunction): - convolved += resolution_model.area.value * sample_model.evaluate( - x_dense - offset - resolution_model.center.value + # if sample has deltas, convolve each delta with the resolution_model + for delta in sample_deltas: + convolved += delta.area.value * resolution_model.evaluate( + x - offset - delta.center.value ) - # TODO: if both resolution and sample are delta functions, we should let the user know that they are wrong. + # if resolution has deltas, convolve each delta with the sample_model + for delta in resolution_deltas: + convolved += delta.area.value * sample_model.evaluate( + x - offset - delta.center.value + ) - if upsample_factor > 0: - # interpolate back to original x grid - return interp1d( - x_dense, convolved, kind="linear", bounds_error=False, fill_value=0.0 - )(x) - else: - return convolved + return convolved def _analytical_convolution( @@ -346,41 +346,67 @@ def _analytical_convolution( def _try_analytic_pair( - x: np.ndarray, s: ModelComponent, r: ModelComponent, off: float + x: np.ndarray, + sample_component: ModelComponent, + resolution_component: ModelComponent, + off: float, ) -> Tuple[bool, np.ndarray]: """ - Attempt an analytic convolution for component pair (s, r). + Attempt an analytic convolution for component pair (sample_component, resolution_component). Returns (True, contribution) if handled, else (False, zeros). """ # Delta functions - if isinstance(s, DeltaFunction): - return True, s.area.value * r.evaluate(x - s.center.value - off) + if isinstance(sample_component, DeltaFunction) and isinstance( + resolution_component, DeltaFunction + ): + raise ValueError("Convolution of two delta functions is not defined.") - if isinstance(r, DeltaFunction): - return True, r.area.value * s.evaluate(x - r.center.value - off) + if isinstance(sample_component, DeltaFunction): + return True, sample_component.area.value * resolution_component.evaluate( + x - sample_component.center.value - off + ) + + if isinstance(resolution_component, DeltaFunction): + return True, resolution_component.area.value * sample_component.evaluate( + x - resolution_component.center.value - off + ) # Gaussian + Gaussian --> Gaussian - if isinstance(s, Gaussian) and isinstance(r, Gaussian): - width = np.sqrt(s.width.value**2 + r.width.value**2) - area = s.area.value * r.area.value - center = (s.center.value + r.center.value) + off + if isinstance(sample_component, Gaussian) and isinstance( + resolution_component, Gaussian + ): + width = np.sqrt( + sample_component.width.value**2 + resolution_component.width.value**2 + ) + area = sample_component.area.value * resolution_component.area.value + center = ( + sample_component.center.value + resolution_component.center.value + ) + off return True, gaussian_eval(x, center, width, area) # Lorentzian + Lorentzian --> Lorentzian - if isinstance(s, Lorentzian) and isinstance(r, Lorentzian): - width = s.width.value + r.width.value - area = s.area.value * r.area.value - center = (s.center.value + r.center.value) + off + if isinstance(sample_component, Lorentzian) and isinstance( + resolution_component, Lorentzian + ): + width = sample_component.width.value + resolution_component.width.value + area = sample_component.area.value * resolution_component.area.value + center = ( + sample_component.center.value + resolution_component.center.value + ) + off return True, lorentzian_eval(x, center, width, area) # Gaussian + Lorentzian --> Voigt - if (isinstance(s, Gaussian) and isinstance(r, Lorentzian)) or ( - isinstance(s, Lorentzian) and isinstance(r, Gaussian) + if ( + isinstance(sample_component, Gaussian) + and isinstance(resolution_component, Lorentzian) + ) or ( + isinstance(sample_component, Lorentzian) + and isinstance(resolution_component, Gaussian) ): - if isinstance(s, Gaussian): - G, L = s, r + if isinstance(sample_component, Gaussian): + G, L = sample_component, resolution_component else: - G, L = r, s + G, L = resolution_component, sample_component center = (G.center.value + L.center.value) + off area = G.area.value * L.area.value return True, voigt_eval(x, center, G.width.value, L.width.value, area) @@ -444,3 +470,12 @@ def _check_width_thresholds(model, span, dx, model_type): f"array ({dx}). This may lead to inaccuracies in the convolution.", UserWarning, ) + + +def _delta_components(model: Union[SampleModel, ModelComponent]) -> List[DeltaFunction]: + """Return a list of DeltaFunction instances contained in `model`.""" + if isinstance(model, DeltaFunction): + return [model] + if isinstance(model, SampleModel): + return [c for c in model.components if isinstance(c, DeltaFunction)] + return [] diff --git a/tests/unit_tests/utils/test_convolution.py b/tests/unit_tests/utils/test_convolution.py index 56372ee..be83e16 100644 --- a/tests/unit_tests/utils/test_convolution.py +++ b/tests/unit_tests/utils/test_convolution.py @@ -588,7 +588,6 @@ def test_numerical_convolve_x_not_symmetric(self, x, upsample_factor): sample_model=sample_model, resolution_model=resolution_model, method="analytical", - upsample_factor=0, ) np.testing.assert_allclose( From 7707703e921ffb998dcd9f95e5b17c51a5a5ce7e Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 31 Oct 2025 11:31:42 +0100 Subject: [PATCH 22/71] Type hints and docstrings --- src/easydynamics/utils/convolution.py | 211 ++++++++++++++++++++------ 1 file changed, 162 insertions(+), 49 deletions(-) diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py index 082ea11..12ed08c 100644 --- a/src/easydynamics/utils/convolution.py +++ b/src/easydynamics/utils/convolution.py @@ -88,6 +88,7 @@ def convolution( if not resolution_model.components: raise ValueError("ResolutionModel must have at least one component.") + # Handle offset if offset is None: off = 0.0 elif isinstance(offset, Parameter): @@ -99,6 +100,23 @@ def convolution( f"Expected offset to be Parameter, number, or None, got {type(offset)}" ) + # Handle temperature + if temperature is not None: + if isinstance(temperature, Parameter): + T = temperature.value + temperature_unit = temperature.unit + elif isinstance(temperature, float): + T = temperature + else: + raise TypeError( + f"Expected temperature to be Parameter, float, or None, got {type(temperature)}" + ) + + if x_unit is None: + raise ValueError("x_unit must be provided when temperature is specified.") + if not isinstance(x_unit, (str, sc.Unit)): + raise TypeError(f"Expected x_unit to be str or sc.Unit, got {type(x_unit)}") + if method == "analytical": if temperature is not None: raise ValueError( @@ -120,7 +138,7 @@ def convolution( offset=off, upsample_factor=upsample_factor, extension_factor=extension_factor, - temperature=temperature, + temperature=T, temperature_unit=temperature_unit, x_unit=x_unit, normalize_detailed_balance=normalize_detailed_balance, @@ -223,24 +241,9 @@ def _numerical_convolution( # Detailed balance correction if temperature is not None: - if isinstance(temperature, Parameter): - T = temperature.value - temperature_unit = temperature.unit - elif isinstance(temperature, float): - T = temperature - else: - raise TypeError( - f"Expected temperature to be Parameter, float, or None, got {type(temperature)}" - ) - - if x_unit is None: - raise ValueError("x_unit must be provided when temperature is specified.") - if not isinstance(x_unit, (str, sc.Unit)): - raise TypeError(f"Expected x_unit to be str or sc.Unit, got {type(x_unit)}") - detailed_balance_factor_correction = detailed_balance_factor( energy=x_dense, - temperature=T, + temperature=temperature, energy_unit=x_unit, temperature_unit=temperature_unit, divide_by_temperature=normalize_detailed_balance, @@ -265,8 +268,8 @@ def _numerical_convolution( # Add delta contributions on original grid # collect deltas - sample_deltas = _delta_components(sample_model) - resolution_deltas = _delta_components(resolution_model) + sample_deltas = _find_delta_components(sample_model) + resolution_deltas = _find_delta_components(resolution_model) # error if both contain delta(s) if sample_deltas and resolution_deltas: @@ -299,12 +302,33 @@ def _analytical_convolution( extension_factor: float = 0.2, ) -> np.ndarray: """ - Convolve sample with resolution. Accepts SampleModel or single ModelComponent for each. - - Uses analytic registry for supported pairs. - - For non-analytic pairs, falls back to a single FFT per sample component - against the sum of its leftover resolution components using numerical_convolve - (passing a callable for the summed resolution). - - Handles delta functions analytically. + Convolve sample with resolution analytically if possible. Accepts SampleModel or single ModelComponent for each. + Possible analytical convolutions are any combination of delta functions, Gaussians, and Lorentzians. + Falls back to numerical convolution for other pairs of functions + + Most validation happens in the main `convolution` function. + + Args: + x : np.ndarray + 1D array of x values where the convolution is evaluated. + sample_model : SampleModel or ModelComponent + The sample model to be convolved. + resolution_model : SampleModel or ModelComponent + The resolution model to convolve with. + offset : Parameter, float, or None, optional + The offset to apply to the convolution. + upsample_factor : int, optional + The factor by which to upsample the input data before numerical convolution. Improves accuracy at the cost of speed. Default is 5 + extension_factor : float, optional + The factor by which to extend the input data range before numerical convolution. Improves accuracy at the edges of the data. Default is 0.2 + Returns: + np.ndarray + The convolved values evaluated at x. + + Raises: + ValueError + If both sample_model and resolution_model contain delta functions. + """ # prepare list of components @@ -336,7 +360,7 @@ def _analytical_convolution( total += _numerical_convolution( x=x, sample_model=s, # single component - resolution_model=not_analytical_components, # SampleModel with components that cannot be handled analytically + resolution_model=not_analytical_components, offset=offset, upsample_factor=upsample_factor, extension_factor=extension_factor, @@ -345,6 +369,7 @@ def _analytical_convolution( return total +# ---------------------- helpers & evals ----------------------- def _try_analytic_pair( x: np.ndarray, sample_component: ModelComponent, @@ -354,6 +379,16 @@ def _try_analytic_pair( """ Attempt an analytic convolution for component pair (sample_component, resolution_component). Returns (True, contribution) if handled, else (False, zeros). + + Args: + x : np.ndarray + 1D array of x values where the convolution is evaluated. + sample_component : ModelComponent + The sample component to be convolved. + resolution_component : ModelComponent + The resolution component to convolve with. + off : float + The offset to apply to the convolution. """ # Delta functions if isinstance(sample_component, DeltaFunction) and isinstance( @@ -371,7 +406,7 @@ def _try_analytic_pair( x - resolution_component.center.value - off ) - # Gaussian + Gaussian --> Gaussian + # Gaussian + Gaussian --> Gaussian with width sqrt(w1^2 + w2^2) if isinstance(sample_component, Gaussian) and isinstance( resolution_component, Gaussian ): @@ -382,9 +417,9 @@ def _try_analytic_pair( center = ( sample_component.center.value + resolution_component.center.value ) + off - return True, gaussian_eval(x, center, width, area) + return True, _gaussian_eval(x, center, width, area) - # Lorentzian + Lorentzian --> Lorentzian + # Lorentzian + Lorentzian --> Lorentzian with width w1 + w2 if isinstance(sample_component, Lorentzian) and isinstance( resolution_component, Lorentzian ): @@ -393,7 +428,7 @@ def _try_analytic_pair( center = ( sample_component.center.value + resolution_component.center.value ) + off - return True, lorentzian_eval(x, center, width, area) + return True, _lorentzian_eval(x, center, width, area) # Gaussian + Lorentzian --> Voigt if ( @@ -409,16 +444,32 @@ def _try_analytic_pair( G, L = resolution_component, sample_component center = (G.center.value + L.center.value) + off area = G.area.value * L.area.value - return True, voigt_eval(x, center, G.width.value, L.width.value, area) + return True, _voigt_eval(x, center, G.width.value, L.width.value, area) return False, np.zeros_like(x, dtype=float) -# ---------------------- helpers & evals ----------------------- - - @staticmethod -def gaussian_eval(x, center, width, area): +def _gaussian_eval( + x: np.ndarray, center: float, width: float, area: float +) -> np.ndarray: + """ + Evaluate a Gaussian function. y = (area / (sqrt(2pi) * width)) * exp(-0.5 * ((x - center) / width)^2) + All checks are handled in the calling function. + + args: + x : np.ndarray + 1D array of x values where the Gaussian is evaluated. + center : float + The center of the Gaussian. + width : float + The width (sigma) of the Gaussian. + area : float + The area under the Gaussian curve. + Returns: + np.ndarray + The evaluated Gaussian values at x. + """ return ( area * 1 @@ -428,24 +479,76 @@ def gaussian_eval(x, center, width, area): @staticmethod -def lorentzian_eval(x, center, width, area): +def _lorentzian_eval( + x: np.ndarray, center: float, width: float, area: float +) -> np.ndarray: + """ + Evaluate a Lorentzian function. y = (area * width / pi) / ((x - center)^2 + width^2). + All checks are handled in the calling function. + + args: + x : np.ndarray + 1D array of x values where the Lorentzian is evaluated. + center : float + The center of the Lorentzian. + width : float + The width (HWHM) of the Lorentzian. + area : float + The area under the Lorentzian. + Returns: + np.ndarray + The evaluated Lorentzian values at x. + """ return area * width / np.pi / ((x - center) ** 2 + width**2) @staticmethod -def voigt_eval(x, center, g_width, l_width, area): +def _voigt_eval( + x: np.ndarray, center: float, g_width: float, l_width: float, area: float +) -> np.ndarray: + """ + Evaluate a Voigt profile function using scipy's voigt_profile. + args: + x : np.ndarray + 1D array of x values where the Voigt profile is evaluated. + center : float + The center of the Voigt profile. + g_width : float + The Gaussian width (sigma) of the Voigt profile. + l_width : float + The Lorentzian width (HWHM) of the Voigt profile. + area : float + The area under the Voigt profile. + Returns: + np.ndarray + The evaluated Voigt profile values at x. + """ + return area * voigt_profile(x - center, g_width, l_width) @staticmethod -def _check_width_thresholds(model, span, dx, model_type): +def _check_width_thresholds( + model: Union[SampleModel, ModelComponent], span: float, dx: float, model_type: str +) -> None: """ - Helper function to check and warn about width thresholds for a given model or component. - Parameters: - - model: ModelComponent or SampleModel - - span: Range of the input data - - dx: Bin spacing of the input data - - model_type: 'sample model' or 'resolution model' for proper warning messages + Helper function to check and warn if components are wide compared to the span of the data, or narrow compared to the spacing. + In both cases, the convolution accuracy may be compromised. + args: + model : SampleModel or ModelComponent + The model to check. + dx : float + The bin spacing of the input x array. + span : float + The total span of the input x array. + model_type : str + A string indicating whether the model is a 'sample model' or 'resolution model' for warning messages. + returns: + None + warns: + UserWarning + If the component widths are not appropriate for the data span or bin spacing. + """ LARGE_WIDTH_THRESHOLD = 0.1 # Threshold for large widths compared to span SMALL_WIDTH_THRESHOLD = 0.5 # Threshold for small widths compared to bin spacing @@ -454,26 +557,36 @@ def _check_width_thresholds(model, span, dx, model_type): if isinstance(model, SampleModel): components = model.components else: - components = [model] # Treat single ModelComponent as a list of one + components = [model] # Treat single ModelComponent as a list for comp in components: if hasattr(comp, "width"): if comp.width.value > LARGE_WIDTH_THRESHOLD * span: warnings.warn( f"The width of the {model_type} component '{comp.name}' ({comp.width.value}) is large compared to the span of the input " - f"array ({span}). This may lead to inaccuracies in the convolution.", + f"array ({span}). This may lead to inaccuracies in the convolution. Increase extension_factor to improve accuracy.", UserWarning, ) if comp.width.value < SMALL_WIDTH_THRESHOLD * dx: warnings.warn( f"The width of the {model_type} component '{comp.name}' ({comp.width.value}) is small compared to the spacing of the input " - f"array ({dx}). This may lead to inaccuracies in the convolution.", + f"array ({dx}). This may lead to inaccuracies in the convolution. Increase upsample_factor to improve accuracy.", UserWarning, ) -def _delta_components(model: Union[SampleModel, ModelComponent]) -> List[DeltaFunction]: - """Return a list of DeltaFunction instances contained in `model`.""" +def _find_delta_components( + model: Union[SampleModel, ModelComponent], +) -> List[DeltaFunction]: + """Return a list of DeltaFunction instances contained in `model`. + + Args: + model : SampleModel or ModelComponent + The model to search for DeltaFunction components. + Returns: + List[DeltaFunction] + A list of DeltaFunction components found in the model. + """ if isinstance(model, DeltaFunction): return [model] if isinstance(model, SampleModel): From 885382fdaeb6b251be38d9d5d68cf03fb765e89d Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 31 Oct 2025 13:33:42 +0100 Subject: [PATCH 23/71] Add example and performance test --- examples/convolution.ipynb | 147 ++- .../convolution_and_detailed_balance.ipynb | 689 +++++++++++++ examples/convolution_example .ipynb | 959 ++++++++++++++++++ src/easydynamics/utils/convolution.py | 9 +- .../convolution_width_thresholds.ipynb | 126 +++ tests/unit_tests/utils/test_convolution.py | 2 +- 6 files changed, 1880 insertions(+), 52 deletions(-) create mode 100644 examples/convolution_and_detailed_balance.ipynb create mode 100644 examples/convolution_example .ipynb create mode 100644 tests/performance_tests/convolution/convolution_width_thresholds.ipynb diff --git a/examples/convolution.ipynb b/examples/convolution.ipynb index 2e9a686..7b9234d 100644 --- a/examples/convolution.ipynb +++ b/examples/convolution.ipynb @@ -11,54 +11,11 @@ "from easyscience.variable import Parameter\n", "from scipy.special import voigt_profile\n", "\n", - "from easydynamics.sample_model import DeltaFunction, Gaussian, Lorentzian, SampleModel\n", - "from easydynamics.utils import convolution as convolution\n", - "\n", - "# Numerical convolutions are not very accurate\n", - "NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE = 1e-6\n", - "NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE = 1e-5\n", - "\n", - "\n", - "\n", - "# WHEN\n", - "sample_lorentzian = Lorentzian(\n", - " center=0.1, width=0.3, area=2, name=\"SampleLorentzian\"\n", - ")\n", - "sample_delta = DeltaFunction(center=0.5, area=4, name=\"SampleDelta\")\n", - "resolution_gauss = Gaussian(\n", - " center=-0.3, width=0.4, area=3, name=\"ResolutionGauss\"\n", - ")\n", - "sample = SampleModel(name=\"SampleModel\")\n", - "sample.add_component(sample_lorentzian)\n", - "sample.add_component(sample_delta)\n", - "resolution = SampleModel(name=\"ResolutionModel\")\n", - "resolution.add_component(resolution_gauss)\n", - "\n", - "# THEN\n", - "x = np.linspace(-10, 10, 20001)\n", - "calculated_convolution = convolution(\n", - " x=x,\n", - " sample_model=sample,\n", - " resolution_model=resolution,\n", - " method=\"numerical\",\n", - " upsample_factor=5,\n", - ")\n", - "\n", - "# EXPECT: Combine Gaussian, Lorentzian, and Delta functions contributions\n", - "expected_voigt = 2 * 3 * voigt_profile(x - (0.1 - 0.3), 0.4, 0.3)\n", - "expected_gauss_center = -0.3 + 0.5\n", - "expected_gauss = (\n", - " 3\n", - " * 4\n", - " * np.exp(-0.5 * ((x - (expected_gauss_center)) / 0.4) ** 2)\n", - " / (np.sqrt(2 * np.pi) * 0.4)\n", - ")\n", - "expected_result = expected_voigt + expected_gauss\n", - "\n", - "import matplotlib.pyplot as plt\n", - "%matplotlib widget\n", - "plt.plot(x, calculated_convolution, label=\"Convolution Result\")\n", - "plt.plot(x, expected_result, label=\"Expected Result\", linestyle='dashed')" + "from easydynamics.sample_model import DeltaFunction, Gaussian, Lorentzian, SampleModel, DampedHarmonicOscillator\n", + "from easydynamics.utils import convolution \n", + "from easydynamics.utils import _detailed_balance_factor as detailed_balance_factor\n", + "\n", + "import matplotlib.pyplot as plt" ] }, { @@ -68,7 +25,99 @@ "metadata": {}, "outputs": [], "source": [ - "print(calculated_convolution)" + "# Standard example of convolution of a sample model with a resolution model\n", + "sample_model=SampleModel(name='sample_model')\n", + "gaussian=Gaussian(name='Gaussian',width=0.5,area=1)\n", + "dho = DampedHarmonicOscillator(name='DHO',center=1.0,width=0.3,area=2.0)\n", + "lorentzian = Lorentzian(name='Lorentzian',center=-1.0,width=0.2,area=1.0)\n", + "delta = DeltaFunction(name='Delta',center=0.4,area=0.5)\n", + "sample_model.add_component(gaussian)\n", + "sample_model.add_component(dho)\n", + "sample_model.add_component(lorentzian)\n", + "sample_model.add_component(delta)\n", + "\n", + "resolution_model = SampleModel(name='resolution_model')\n", + "resolution_gaussian=Gaussian(name='Resolution Gaussian',width=0.2,area=0.8)\n", + "resolution_lorentzian = Lorentzian(name='Resolution Lorentzian',width=0.2,area=0.2)\n", + "resolution_model.add_component(resolution_gaussian)\n", + "resolution_model.add_component(resolution_lorentzian)\n", + "\n", + "x=np.linspace(-2, 2, 100)\n", + "\n", + "\n", + "y = convolution(sample_model=sample_model,\n", + " resolution_model=resolution_model,\n", + " x=x,\n", + " )\n", + "\n", + "plt.plot(x, y, label='Convoluted Model')\n", + "plt.xlabel('Energy (meV)')\n", + "plt.ylabel('Intensity (arb. units)')\n", + "plt.title('Convolution of Sample Model with Resolution Model')\n", + "\n", + "plt.plot(x, sample_model.evaluate(x), label='Sample Model', linestyle='--')\n", + "plt.plot(x, resolution_model.evaluate(x), label='Resolution Model', linestyle=':')\n", + "\n", + "\n", + "plt.legend()\n", + "# set the limit on the y axis\n", + "plt.ylim(0,6)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fede1a58", + "metadata": {}, + "outputs": [], + "source": [ + "# Use some of the extra settings for the numerical convolution\n", + "sample_model=SampleModel(name='sample_model')\n", + "gaussian=Gaussian(name='Gaussian',width=0.5,area=1)\n", + "dho = DampedHarmonicOscillator(name='DHO',center=1.0,width=0.3,area=2.0)\n", + "lorentzian = Lorentzian(name='Lorentzian',center=-1.0,width=0.2,area=1.0)\n", + "delta = DeltaFunction(name='Delta',center=0.4,area=0.5)\n", + "sample_model.add_component(gaussian)\n", + "sample_model.add_component(dho)\n", + "sample_model.add_component(lorentzian)\n", + "\n", + "resolution_model = SampleModel(name='resolution_model')\n", + "resolution_gaussian=Gaussian(name='Resolution Gaussian',width=0.2,area=0.8)\n", + "resolution_lorentzian = Lorentzian(name='Resolution Lorentzian',width=0.2,area=0.2)\n", + "resolution_model.add_component(resolution_gaussian)\n", + "resolution_model.add_component(resolution_lorentzian)\n", + "\n", + "x=np.linspace(-2, 2, 100)\n", + "\n", + "\n", + "temperature = 15.0 # Temperature in Kelvin\n", + "offset = 0.3\n", + "upsample_factor = 5\n", + "extension_factor = 0.2\n", + "\n", + "plt.xlabel('Energy (meV)')\n", + "plt.ylabel('Intensity (arb. units)')\n", + "\n", + "y = convolution(sample_model=sample_model,\n", + " resolution_model=resolution_model,\n", + " x=x,\n", + " offset = offset,\n", + " method = \"numerical\",\n", + " upsample_factor = upsample_factor,\n", + " extension_factor = extension_factor,\n", + " temperature=temperature,\n", + " normalize_detailed_balance=True,\n", + " )\n", + "\n", + "plt.plot(x, y, label='Convoluted Model')\n", + "\n", + "plt.plot(x, sample_model.evaluate(x-offset)*detailed_balance_factor(x-offset, temperature), label='Sample Model with DB', linestyle='--')\n", + "\n", + "plt.plot(x, resolution_model.evaluate(x), label='Resolution Model', linestyle=':')\n", + "plt.title('Convolution of Sample Model with Resolution Model with detailed balancing')\n", + "\n", + "plt.legend()\n", + "plt.ylim(0,2.5)" ] } ], diff --git a/examples/convolution_and_detailed_balance.ipynb b/examples/convolution_and_detailed_balance.ipynb new file mode 100644 index 0000000..b3065f5 --- /dev/null +++ b/examples/convolution_and_detailed_balance.ipynb @@ -0,0 +1,689 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "64deaa41", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "from easydynamics.sample import Gaussian\n", + "from easydynamics.sample import Lorentzian\n", + "from easydynamics.sample import Voigt\n", + "from easydynamics.sample import DampedHarmonicOscillator\n", + "from easydynamics.sample import Polynomial\n", + "from easydynamics.sample import SampleModel\n", + "\n", + "from easydynamics.resolution import ResolutionHandler\n", + "\n", + "import matplotlib.pyplot as plt\n", + "\n", + "\n", + "from easydynamics.utils import detailed_balance_factor\n", + "\n", + "from easyscience.variable import Parameter\n", + "%matplotlib widget" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a49c5cda", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0, 0.5, 'Detailed Balance Factor')" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "bebf710b7fdf4dd78b073a8f6b08fcbb", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+gAAAJYCAYAAADxHswlAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAnuVJREFUeJzs3Qd0VEUbxvEnCRB671U6KE1RQHpTwAZi7xUVsSEKIoKIKAooiIKIvWH97AqKIKA0EaWJIB3pSAsthSTfeee6KRBa2t0k/985l+Teu7uZLST77My8ExIfHx8vAAAAAADgq1B/fzwAAAAAADAEdAAAAAAAggABHQAAAACAIEBABwAAAAAgCBDQAQAAAAAIAgR0AAAAAACCAAEdAAAAAIAgQEAHAAAAACAIENABAAAAAAgCBHQAAAAAAIIAAR0AAAAAgCBAQAcAAAAAIAgQ0AEAAAAACAIEdAAAAAAAggABHQAAAACAIEBABwAAAAAgCBDQAQAAAAAIAgR0AAAAAACCAAEdAAAAAIAgQEAHAAAAACAIENABAAAAAAgCBHQAAAAAAIIAAR0AAAAAgCBAQAcAAAAAIAgQ0AEAAAAACAIEdAAAAAAAggABHQAAAACAIEBABwAAAAAgCBDQAQAAAAAIAgR0AAAAAACCAAEdAAAAAIAgQEAHAAAAACAIENABAAAAAAgCBHQAAAAAAIIAAR0AAAAAgCBAQAcAAAAAIAgQ0AEAAAAACAIEdAAAAAAAggABHQAAAACAIEBABwAAAAAgCBDQAQAAAAAIAgR0AAAAAACCAAEdAAAAAIAgQEAHAAAAACAIENABAAAAAAgCBHQAAAAAAIIAAR0AAAAAgCBAQAcAAAAAIAgQ0AEAAAAACAIEdABAhrv55pt12mmnJTsWEhKiwYMHp9vPmD59urtN++oHu392PwEAAFKLgA4A2cBbb73lwmlgy5s3r8qXL69OnTppzJgx2rdvX6pve9myZS5Ir1u3TtnxsbKtdOnSateunSZNmqSc7sjHJrCVLVs23X/WuHHj3PORXdj/kWM9frY988wzfjcRABDkcvndAABA+hkyZIiqVq2qmJgYbd261fUmP/DAA3r++ef11VdfqUGDBqkK6E888YTatm17VC/4yXr11VcVFxenYHys4uPjtW3bNhcUL7jgAn399de66KKLlJOdd955uvHGG5Mdy5cvX4YE9JIlS2a7kQfXXHONey0d6cwzz/SlPQCArIOADgDZSJcuXXT22Wcn7Pfv31/Tpk1zgfOSSy7RX3/9lSFB60Ry586tYH+sbrvtNpUpU0YffPBBjg/otWrV0vXXX6+sKDIyUnny5FFoqH+DBM8666ygePwOHz7sPhizxwMAkDUwxB0Asrn27dtr4MCBWr9+vd57771k55YvX67LL79cxYsXd8PiLbBaT3uA9SpfccUV7nsbAh4YqhuY5/3ll1/qwgsvdMPpw8PDVb16dT355JOKjY094Rz0lGzatEm33nqrC8p2e2eccYbeeOONoy63ceNGdevWTQUKFHDD03v37q2oqCilRdGiRd2HF7lyJf/seuTIkWrevLlKlCjhzjdu3FiffvrpCW9v165deuihh1S/fn0VLFhQhQsXdh8KLFq0KMW58x9//LGeeuopVaxY0T0XHTp00KpVq4663Xnz5rne2WLFirn7b6MiXnjhhVN6XtPiVB4Pe701adJE+fPnd+1t3bq1fvjhB3fOXg9//vmnZsyYkfC6slEaAWvWrHGvPbsPdv1mzZrp22+/TfGx+/DDD/XYY4+pQoUK7rIRERFHtcVGldht3XLLLUeds8vb42TPV8CLL77oXn+BtttjOHHiRKUXu//2QdAvv/ziHiP7+dWqVdM777xz1GX37NnjRsJUqlTJ/b+oUaOGnn322WSjUgLD6+35GT16tPu/aJe1ETCBx8rug/0cO/fKK6+4qSt2nYA2bdqoYcOGKba3du3absoMACBj0YMOADnADTfcoEcffdSFox49erhjFo5atGjhQs0jjzziwp6FRAu+//vf/3TppZe6QHXfffe5eex2/bp167rrBr5agLfw+eCDD7qv1ls/aNAgF3hGjBhxSm20YeYWwiww3HPPPSpVqpSbE24923Z7FlDMoUOHXHjdsGGDa5t9OPDuu++6n30q9u7dq3///dcNcd++fbsLZPv37z+q59PCr40+uO666xQdHe3CoAXHb775xn04cSwWML/44gt3WRtKb/fPQpGFIAtN1u6kbH6y9fpaSLS2DR8+3P1MC+QBU6ZMcaGuXLlyuv/++928cBsVYW2x/ZN9Xk+mF9oem6QKFSrkAt/JPh42LcICoIV5m05gvbh2X+x5Ov/8812IvPfee93rZsCAAe469sGMscfKrnfw4EH3HNuHAW+//bb7ufZhwJH3wT4Ustu3x84+qEmpx9hGcdj1PvvsM/c8JL2MPU92vauvvjphSob9XPuQwx5XezwWL17s2n/ttdee8PGzdh/5+AU+BEr6AZB9AGM/w17jN910k/swyj7Msg897MOBwG3Za8Y+vLrzzjtVuXJlzZ49242O2bJli3sck3rzzTdde++44w73fNmHEn/88Yc6d+7sXjf2vNgHaPac2P+xI39P2O+HpUuXql69egnH58+fr7///tt9CAIAyGDxAIAs780334y3X+nz588/5mWKFCkSf+aZZybsd+jQIb5+/frxkZGRCcfi4uLimzdvHl+zZs2EY5988om77Z9++umo2zx48OBRx+688874/PnzJ7vdm266Kb5KlSrJLme3+fjjjyfs33bbbfHlypWL//fff5Nd7uqrr3ZtD/ys0aNHu+t+/PHHCZc5cOBAfI0aNY7ZzpQeqyO38PDw+LfeeuuE9zE6Ojq+Xr168e3bt0923O6f3c8Au/+xsbHJLrN27Vr3c4YMGZJwzNprP79u3brxUVFRCcdfeOEFd3zJkiVu//Dhw/FVq1Z1P2f37t3Jbteet1N9Xo8lpcfGNnvcTvbxWLlyZXxoaGj8pZdeetRjkLStZ5xxRnybNm2OasMDDzzgfubPP/+ccGzfvn3u/p922mkJtxl47KpVq5bia/FI33//vbv8119/nez4BRdc4G4joGvXrq5tp8qe32M9frbNmTMn4bL2PNqxmTNnJhzbvn27e3306dMn4diTTz4ZX6BAgfi///472c965JFH4sPCwuI3bNiQ7GcXLlzY3U5SF198sfs/uWnTpmTPUa5cudx1Avbs2ROfN2/e+H79+iW7/n333efasH///lN+TAAAp4Yh7gCQQ1hPZaCauw2/tp7MK6+80h2z3j7bdu7c6Yaxrly50vXYnUjS+eyB22nVqpXr9bNh1ifLcqH17l588cXu+0B7bLP2WI/y77//7i773XffuZ5A63kMsGHI1mN4KsaOHet6pG2zodg2hP/22293PazHuo+7d+92bbH7GGjPsVjvZWAetPVY2mNrz4ENFU7pujb0Ommvrv2MQE+8sV7QtWvXupEE1hObVGCYcno9r127dk14bAJbYHjzyTwe1iNtw69tNMWRc8GTDqk+FnuObdh3y5YtE47ZY2fPsQ3lDgzbDrDe55OprWDTPawo3UcffZTsPtj9u+qqqxKO2eNr0yis5zg1rJ1HPn62nX766ckuZ/uB59lYj7a9PgLPufnkk0/cZWyYfdL/Fx07dnSvq5kzZya7zcsuuyxZz7hd5scff3QjKJKO2rBh8jblIqkiRYq4597qMHif1XjXt8crMKUEAJCxGOIOADmEDd+2+dqBobX2BtzmptuWEhv2bcOkj8eGU9uwVwuFR877teB2snbs2OHm2U6YMMFtx2qPsbn0Fi6ODHoWbE6FBcCkReKs8rZV2bbh9TaMPBCWbej20KFDtXDhwmTz3E8UNC2g2nBwq1RuwTrpvHwbsn0kG7qclAWyQIA0q1evdl+TDj0+Uno9rzYP3gJgSk7m8bC2WjA/MpCeLHuOmzZtetTxwNQKO5/0cbApBCfDhpdbgLW55NZ2+xDFPpCx+elJA3q/fv1cqLXXiL3WbEi+DW23qQMno2bNmsd8/I73nAee98BzbuxDFRtef+Rw9CP/XxzrsbDzNi3E7seRUjpm1fstkP/8889uios9DjblwIa/AwAyHgEdAHIA6w20wBx4Qx4oLmVzdo9V+CmlN+9JWaC2ubFW/Mzms1rhKStAZT2pFnBOZVm1wGVt/rf1hqYkNUvEnQoLlNaLbqHaQpHNAbaQYvOeLahY0Laee5vLbPN8T1Qw7Omnn3Yh2Yre2RxpmwtsP8N6wFN6bMLCwlK8nUBP5slIj+f1eNLyeGSkU1mZwOaZ2xx0q29gvcI2P79OnTrJiqPZBwErVqxwH0ZMnjzZje6w+2sjAmwOd3o5mefcnlNb9q5v377HrLifVFpXabDXjdUCsFEl9jzbV6t1cDIfOAAA0o6ADgA5gBVRM4HQZtWijYWrE73xPlZPsVWFtqHT1gNpb+QDrLf4VFnvoBUhs17mE7WnSpUqroiVhZikbbNAlR7LUgVGGxgLZvahw/fff+96WwMskJ6IFTOzwP/6668f9cGGDbM+VfYBiLH7fqzH6FSe19Q42cfD2mrB0oaiN2rU6JRfW/Ycp/R8BqZN2PnUsteqfbBgvcQ2hN5GfwSK1CVlw7mtV902K4bXvXt3V2XfirPZY5BZ7LG012Nqn08bNWPtTWlFgJSO2YcGNlrACkBapXibrmCF4471YQIAIH0xBx0AsjkLINaDa0NfrfJ24E27LWllPYlWCTqlIecBgXmnFiyTCrxhT9rbZ0HGehpPld2WDT22AGgB9HjtsSXGNm/enGxpL5vzfqyh8SfLhjlblXsb2h4YSm3tshCZdHi6zYG20HIy9+nI3m+bT3wyc8CPtba2PYdWtfvI5yLwc07leU2Nk308rGfaRgvYyIojRwskfUzstXXkfQk8x7/++qvmzJmTcOzAgQPuObblyVI7dN5Yu6x+wddff+0+uLIPZZIObzf2wVNS9pqwn2ltt9dJZrJ6AvY42IciR7LHLvCh0vGeMwv39hzZ/5uk4dxGEaTEhrPbMHurGp/SygYAgIxDDzoAZCP2htt6Ge1Nu80btXBuxamsx9HWwU7a82dF0qwH0dbpth4y632161gYsCHxgfW6rQfU3uRbb5oNk7eeUyu2Zctg2XxZG5JuS1JZcLPAcypDso9cZuynn35yc4+tPRaIrOiZDZm3ebD2vbFzL730kpsru2DBAtcbaj/XCsWl5rEKzNO1Ido2tN2WJrNh+8aWDXv++efdElXWq2iXs8fNhonbvODjsXnsFlCt+Js9VkuWLNH777+f0MudmmD58ssvu0J69pzY7dp9t/tgtQACAe5kn9fUONnHw/atV9o+GLICZ9b7bK8bK7pmhcqGDRvmLmfLidl9sjntdh37gMFeW/YcWKEyK2Jmry2bHmDLrNnoDPsQ58jCc6fKArktq/f444+7xynwgUyAzTm3Yd0259yGe9tSdvaas/tvIz1OxF6zNjQ8pd7wc88995Ta+vDDD7v/u/Z6CizBZh9W2OvJPqSyD0hONCLDlruzD5/s/vTs2dN9wGL3x+bxWy2BI1ktBjtnHyjZY2MfDgEAMskpVn0HAAShI5cOy5MnT3zZsmXjzzvvPLdcV0RERIrXW716dfyNN97oLps7d+74ChUqxF900UXxn376abLLvfrqq24ZKlvWKelSZrNmzYpv1qxZfL58+eLLly8f37dv34SlrJIud3Yyy6yZbdu2xffq1Su+UqVKrj3WLls2bMKECckut379+vhLLrnELR1VsmTJ+Pvvvz9+8uTJqV5mzZaWatSoUfzLL7+cbBkw8/rrr7vlyWz5qzp16rjrW7uP/BOa0jJrtlyWLR1nj0+LFi3cMlu2rFjSpcUCS4XZcnZJBZbNCixvFvDLL7+457VQoUJu6asGDRrEv/jii6l6XlNiP9Oeg2M52cfDvPHGG25pP7tssWLF3P2eMmVKwvmtW7fGX3jhhe6+2PWTPi52Hy6//PL4okWLuuenSZMm8d98802y2z/WY3ci9hzba8yuO3To0KPOv/LKK/GtW7eOL1GihGt79erV4x9++OH4vXv3pmmZtaSvD3u92H0/0pGvj8ASc/3793dLCdr/bXvN27J5I0eOdMvcJf3ZI0aMSLFtU6dOdc+FXd/uz2uvveZen/bYpmT48OHu9p5++unj3mcAQPoKsX8y68MAAAAABAebimCjL2zkyJGsWGLv3r1dD31K1eYBABmDOegAAADZnC21lpSFcltv3moWHMn6bqy4oa3SQDgHgMzFHHQAAIBszmoR2Bx2+2rryNvcfyt+l3T5NpvbbvPdrRaEzXH/8ssvfW0zAOREDHEHAADI5qyooAXvrVu3uoJ9Vqzu6aefTlYAzoaz20oBRYsW1d133+2WlQMAZC4COgAAAAAAQYA56AAAAAAABAECOgAAAAAAQYAicTlMXFycNm/erEKFCikkJMTv5gAAAADwic123rdvn8qXL6/QUPpugwEBPYexcF6pUiW/mwEAAAAgSPzzzz+qWLGi380AAT3nsZ7zwH/CwoUL+90cAAAAAD6JiIhwnXeBjAD/EdBzmMCwdgvnBHQAAAAATH0NHkw0AAAAAAAgCBDQAQAAAAAIAgR0AAAAAACCAHPQkaLY2FjFxMT43QwcIU+ePCyBAQAAAGRTBHQctRbi1q1btWfPHr+bghRYOK9ataoL6gAAAACyFwI6kgmE89KlSyt//vxUdAwicXFxbh37LVu2qHLlyjw3AAAAQDZDQEeyYe2BcF6iRAm/m4MUlCpVyoX0w4cPK3fu3H43BwAAAEA6YjIrEgTmnFvPOYJTYGi7fZgCAAAAIHshoOMoDJ0OXjw3AAAAQPZFQAcAAAAAIAgQ0AEAAAAACAIEdGT5Id/H2wYPHpyq2/3kk09Up04d5c2bV/Xr19d3332X7Hzbtm31wAMPJDv2wgsvKDw8XB9++GGa7hMAAACAnIkq7sjSbMmxgI8++kiDBg3SihUrEo4VLFjwlG9z9uzZuuaaazRs2DBddNFFmjhxorp166bff/9d9erVS/E6jz/+uEaOHKkvv/xSnTt3TuW9AQAAAJCTEdCRpZUtWzbh+yJFirhe86THUsN6wi1kP/zww27/ySef1JQpU/TSSy9p/PjxyS4bHx+v++67T++99567TPPmzdP0swEAAADkXAR0HFd8vHTwYOb/XFvpLT0Llp+oJ/36669PCN9z5szRgw8+mOx8p06d9MUXXyQ7ZmuR2/WmTZumGTNmqEGDBunXYAAAAAA5DgEdx2XhPBWjxNNs/36pQIH0u72FCxce93zhwoUTvt+6davKlCmT7Lzt2/GkXn31Vfd10aJFbr46AAAAAKQFAR05Qo0aNdL9Nlu2bOmC/8CBA/XBBx8oVy7+OwEAAOAE9u6Vdu2Sqlb1uyUIQiQKnHCoufVm+/Fz09OpDHG3Oezbtm1Ldt72j5zbbtXdn3vuOXXs2FFXXXWVK1JHSAcAAECK80Z//VV65RXJVvzp2FH66iu/W4UgRJrAcdk88PQcau6XUxnifu6552rq1KnJllGzAnB2/EiNGjVyl7WQfuWVV7qQnjt37nRuPQAAALJsb/nEiV4wX7Qo8fj69VJUlBQe7mfrEIQI6MgRTmWI+/333682bdq43vELL7zQrWv+22+/acKECSlevmHDhq5QXIcOHVxI//jjjwnpAAAAOb233N47Wm95oOKyhfErr5TuvFOylX/SsyIyso1QvxsABBtbKs3WPrdAbuH7008/dRXcj7UGemC4u4V0W0P9iiuuUHR0dKa2GQAAAD7bs0d66SXrvZGaNZPeeMML56efLo0aJW3eLL3zjtSiBeEcxxQSbws5I8eIiIhw64Xv3bs32bBuExkZqbVr16pq1arKmzevb23EsfEcAQAABBGLUnPmeL3lH38sHTrkHbf3adZbfscdQd1bfrxsAH8wxB0AAAAAToVVYX/3XVt3V/rzz8TjNuLShrBfd51UrJifLUQWRUAHAAAAgJPpLf/lF6+3/JNPvCJvJl8+6eqrvd7ypk2DtrccWQMBHQAAAACOZedOb+64BfPlyxOPN2iQ2FtepIifLUQ2QkAHAAAAgCN7y2fM8EL5//4nBQoA588vXXON11t+zjn0liPdEdABAAAAwOzYIb39tje3/O+/E4+feabXW27hnGJqyEAEdAAAAAA5V1yc9NNPXij/7DMpJsY7XrCgdO21Xm9548Z+txI5BAEdAAAAQM6zbZv01lteMF+9OvH42Wd7odwKvxUq5GcLkQMR0AEAAADknN7yqVO9ueVffCEdPuwdtyB+/fVSjx7ecHbAJwR0AAAAANnbli2JveVr1yYet2XRrLf8yiu9Ie2Az0L9bgCQFiEhIcfdBg8efMq3+dZbbx11O3nz5k12mfj4eA0aNEjlypVTvnz51LFjR61cufKotn1hn8z+JyYmRtdcc40qVKigpUuXpuFeAwAA4IRiY6XvvpO6d5cqVZIefdQL51bkrVcvaeFCae5c6dZbCecIGvSgI0vbYp+G/uejjz5yoXnFihUJxwqm8pdt4cKFk92Ohe2khg8frjFjxujtt99W1apVNXDgQHXq1EnLli07KsybgwcP6rLLLnMh/pdffnHXAQAAQAZYt0564w3pzTeljRsTj597rtdbfsUVUoECfrYQOCYCOrK0smXLJnxfpEgRF6STHkut492O9Z6PHj1ajz32mLp27eqOvfPOOypTpozrMb/aCooksWfPHl144YXav3+/C+fp0T4AAAAkERUlffWV9Npr0pQp3jrmpnhx6YYbpNtuk+rX97uVwAkxxB05gvWkH2+76667kl3ewnSVKlVUqVIlF8L//PPPhHNr167V1q1b3bD2pB8ONG3aVHPmzEl2O3a5Nm3auO9nzJhBOAcAAEhPy5ZJffpIFSt688h/+MEL5x06SB98IG3aJI0eTThHlkEPOo7LeosPxhzM9J+bP3f+o4aVp8VCm2N0giHtAbVr19Ybb7yhBg0aaO/evRo5cqSaN2/uQnrFihVd6DbWY56U7QfOBdx///2qVq2apkyZovz586fb/QEAAMix9u+XPvnEK/iWtHOkfHnpllu8OeXVqvnZQiDVCOg4LgvnBYdlftGM/f33q0Ce9JsbVKNGjZO+7Lnnnuu2AAvndevW1SuvvKInn3zylH7uRRdd5Ia923V79+59StcFAADAf6xX/LffvCHs1jO+b593PCzM3nBJt98ude4s5SLeIGvjFYwc4UTF4q6//nqNHz8+xXO5c+fWmWeeqVWrVrn9wDD1bdu2uSruAbbfqFGjZNe94YYbdMkll+jWW291oxEefPDBdLg3AAAAOcSuXdL773vBfPHixOPVq3uh/KabpCTvx4CsjoAeRF5++WW3rbPKk5LOOOMMV5W8S5cubr9t27ZuHnNSd9555zGDZXoNNbfe7MxmPzc9ncoQ9yPFxsZqyZIluuCCC9y+VWC3kD516tSEQB4REaF58+apZ8+eR13/pptuUmhoqG655RbFxcXpoYceSvP9AQAAyLbi4qx4jxfK//c/rwCcCQ+XLr/cC+atW0uhlNNC9kNADyI2v/mZZ55RzZo1XW+rLeFlBcr++OMPF9ZNjx49NGTIkITrZPS8ZpsHnp5Dzf1yKkPc7fFt1qyZu45VYB8xYoTWr1+v2+2PwX+PyQMPPKChQ4e65yqwzFr58uXVrVu3FG/TetItpFtYt+f24YcfTrf7BgAAkC1s3iy9/bb0+uvS6tWJxxs0sDfB0nXXScWK+dlCIMMR0IPIxRdfnGz/qaeecj3qc+fOTQjoFsipBJ6xdu/e7T4IsYJvxYoVU+PGjTV79mydfvrpCZfp27evDhw4oDvuuMOF+JYtW2ry5MkproEecN1117mQbmHdetL79euXSfcIAAAgSB0+LE2a5PWWf/utDV30jhcqJF17rddb3rix9ZD43VIgU4TEW3cego4Nq/7kk09cj6v1oFs4tCHuVkncnjIL6Rboref2eL3oUVFRbguwodi2dJhVJz9yWHdkZKRbQsx6hI8XNOEfniMAAJAtWA/5G29Ib74pbdmSeLxFCy+UX3GFVCDrj+IMdpYNbLnglLIB/EEPepCxuc5WQdyCmBU2+/zzzxN6bq+99lq3NrcNpV68eLHrgV2xYoU+++yzY97esGHD9MQTT2TiPQAAAABSEBkpff6511s+bVri8ZIlvWJvt90m1a3rZwsB39GDHmSio6O1YcMG9ynWp59+qtdee80Vhks6vDpg2rRp6tChg6suXt0qWaaAHvTshecIAABkOUuWeKH83XdtLqF3zIasn3++11t+ySVSnjx+tzJHogc9+NCDHmTy5MmTUNDM5j7Pnz9fL7zwgltH+0hNmzZ1X48X0MPDw90GAAAAZJo9e6QPP/SGsc+fn3i8UiXp1lulW26RqlTxs4VAUCKgBzkrJpa0BzylpcOSrsUNAAAA+Lo8moXyTz/1hrSbXLmkrl293vLzzpPCwvxuKRC0COhBpH///m7N88qVK2vfvn2aOHGipk+fru+//16rV692+7YWd4kSJdwc9N69e6t169ZqYEtPAAAAAH7YsMFbHs0Kvq1dm3jcpmjavPLrr5dKl/azhUCWQUAPItu3b9eNN96oLVu2uLkgFrwtnJ933nn6559/9OOPP2r06NFueS+bR37ZZZfpscce87vZAAAAyGmsd/zLL73e8ilTpEBZK5vHfM013jD2c85heTTgFBHQg8jrr79+zHMWyK1YHAAAAOAbm2Jp71nffz+x4Jtp29YL5ZddJh1nCWAAx0dABwAAAHBsu3ZJEyd6veV//JF4vGJF6eabve0YBYsBnBoCOgAAAIDkYmOlqVO9UG5rl0dHe8dtObRu3bze8o4dKfgGpDMCOgAAAACPFXl76y1vs+JvAVaU2Aq+XXedVKKEny0EsrVQvxsApEVISMhxt8GDB5/ybX722Wc6++yzVbRoURUoUECNGjXSu+++m+wy8fHxGjRokFviLl++fOrYsaNWrlyZ7DK7du3Sddddp8KFC7vbuu2227R///6E81ah39q4x9YJ/c/mzZtVv359V51/7969qXpMAAAATsmhQ96c8g4dpGrVpCFDvHBetKjUq5e0YIE39/y++wjnQAajBx1ZmlW8D/joo49caF6xYkXCsYIFC57ybRYvXlwDBgxQnTp1lCdPHn3zzTe65ZZbVLp0aXXq1MldZvjw4RozZozefvttVa1aVQMHDnTnli1bprx587rLWDi39k2ZMkUxMTHuNu644w63XF5KbCk9q9h/+umn65NPPnHBHwAAIENY1fXffvOGsH/wgRToGLCq6xbUrbfchrL/974GQOYgoCNLK1u2bML3tjSd9UgnPZYaba0KaRL333+/C+K//PKLC+HWe27L3dkSd127dnWXeeedd1SmTBl98cUXuvrqq/XXX39p8uTJmj9/vuuNNy+++KJbx37kyJEqX758sp9h69rbbbdv3979rFy5+K8JAAAywI4dXm+5BfMlSxKPV6ki3XKLdNNN0mmn+dlCIEdjiDtyBOtJP9521113pXg9C+NTp051vfI27NysXbtWW7dudcPak3440LRpU82ZM8ft21cb1h4I58YuHxoaqnnz5iX7GbNnz1abNm3cuvbvvfce4RwAAKSvw4el776TLr9cqlBB6t3bC+fh4dK110o//iitWSM9/jjhHPAZSQAnHv508GDm/1xbP9OGWKWThTZv6jhsnnhSNv+7QoUKioqKUlhYmMaNG+eGnxsL58Z6zJOy/cA5+2pD4pOy4G3D5wOXCbj00kt11VVX6aWXXkrDPQQAADiCTft7+21v27w58bh1IFgV9quvlooV87OFAI5AQMfxWThPxTzuNLNiagUKpNvN1ahR45QuX6hQIRfqraib9aA/+OCDqlat2lHD39ODDZP//PPP9fPPP6tVq1bpfvsAACAHsbnkH38svfmm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", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Detailed balance vs energy, meV scale\n", + "x=np.linspace(-20, 20, 1000)\n", + "\n", + "T=0\n", + "DetailedBalanceT1=detailed_balance_factor(x,T)\n", + "plt.figure(figsize=(10, 6))\n", + "plt.plot(x, DetailedBalanceT1, label=f'T={T}K', color='blue')\n", + "\n", + "T=50\n", + "DetailedBalanceT2=detailed_balance_factor(x,T)\n", + "plt.plot(x, DetailedBalanceT2, label=f'T={T}K', color='green')\n", + "\n", + "\n", + "T=300\n", + "DetailedBalanceT3=detailed_balance_factor(x,T)\n", + "plt.plot(x, DetailedBalanceT3, label=f'T={T}K', color='red')\n", + "\n", + "plt.title('Detailed Balance Factor vs Energy')\n", + "plt.legend()\n", + "\n", + "plt.xlabel('Energy (meV)')\n", + "plt.ylabel('Detailed Balance Factor')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "26c85776", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0, 0.5, 'Detailed Balance Factor')" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "1e0a95a396bc462a950c363d920e2bea", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+gAAAJYCAYAAADxHswlAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAUaJJREFUeJzt3QecFPX9P/7PUQVpVhBFRSV2rLHHHmtU0CRq7D3GbmxEsSuxxFhijYkt9hKNmmgMFjRijy1GY6+AsQCCAgr7f7w/v//e9w4OOK6ws/B8Ph7r7c7OznxmZw7vNZ9WUyqVSgkAAACoqDaV3T0AAAAQBHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAWt3ee++dllxyyXrLampq0qmnntpi+3j00UfzNuNnJcTxxXECADSVgA4wB7j22mtzOC0/5plnntS7d++05ZZbposvvjh99dVXTd72a6+9loP0e++9l+bE7yoeCy+8cNpkk03S3/72tzS3m/q7KT969erV4vu67LLL8vmYU8TvyPS+v3j8+te/rnQRASi4dpUuAAAt5/TTT099+/ZN3377bRo5cmSuTT7yyCPTBRdckP7yl7+k/v37Nymgn3baaWnjjTeepha8sX7/+9+nKVOmpCJ+V6VSKY0aNSoHxW222Sbde++96Uc/+lGam/3whz9Me+65Z71lnTp1apWAvuCCC85xLQ923XXXfC1NbbXVVqtIeQCoHgI6wBxk6623TmuuuWbt60GDBqWHH344B87tt98+/ec//2mVoDUz7du3T0X/rvbbb7/Us2fPdPPNN8/1Af173/te2n333VM1mjBhQurQoUNq06ZyjQRXX331Qnx/3333Xb4xFt8HANVBE3eAOdymm26aBg8enN5///30pz/9qd57r7/+evrxj3+c5p9//twsPgJr1LSXRa3yT37yk/w8moCXm+qW+3nfc889adttt83N6Tt27JiWXnrpdMYZZ6TJkyfPtA96Qz7++OO077775qAc21txxRXTH//4x2nW++ijj9KAAQPSvPPOm5unH3XUUWnixImpOXr06JFvXrRrV//e9fnnn5/WW2+9tMACC+T311hjjXTHHXfMdHtffPFFOuaYY9LKK6+cunTpkrp165ZvCrz00ksN9p2/7bbb0llnnZUWW2yxfC4222yz9NZbb02z3aeffjrXzs4333z5+KNVxEUXXTRL57U5ZuX7iOttrbXWSp07d87l3XDDDdPf//73/F5cD//+97/TY489VntdRSuNsnfeeSdfe3EM8fl11lkn3X///Q1+d7fccks66aST0qKLLprXHTt27DRliVYlsa199tlnmvdi/fie4nyVXXLJJfn6K5c9vsObbroptZQ4/rgR9MQTT+TvKPa/1FJLpeuvv36adUePHp1bwvTp0yf/XiyzzDLpnHPOqdcqpdy8Ps7PhRdemH8XY91oAVP+ruIYYj/x3pVXXpm7rsRnyjbaaKO0yiqrNFjeZZddNneZAaB1qUEHmAvsscce6Ve/+lUORwcccEBeFuFo/fXXz6HmhBNOyGEvQmIE3zvvvDMNHDgwB6rDDz8892OPzy+//PL5s+WfEeAjfB599NH5Z9TWn3zyyTnwnHfeebNUxmhmHiEsAsOhhx6aFlpoodwnPGq2Y3sRUMI333yTw+sHH3yQyxY3B2644Ya871kxZsyY9Nlnn+Um7p9++mkOZOPGjZum5jPCb7Q+2G233dKkSZNyGIzgeN999+WbE9MTAfPuu+/O60ZT+ji+CEURgiI0Rbnriv7JUesbITHKdu655+Z9RiAve+ihh3KoW2SRRdIRRxyR+4VHq4goS7xu7HltTC10fDd1de3aNQe+xn4f0S0iAmCE+ehOELW4cSxxnrbYYoscIg877LB83Zx44on5M3FjJsR3FZ/7+uuv8zmOmwHXXXdd3m/cDJj6GOKmUGw/vru4UdNQjXG04ojP3XXXXfk81F0nzlN8bpdddqntkhH7jZsc8b3G9/Hyyy/n8v/sZz+b6fcX5Z76+yvfBKp7AyhuwMQ+4hrfa6+98s2ouJkVNz3i5kB5W3HNxM2rgw46KC2++OLpySefzK1jRowYkb/Huq655ppc3gMPPDCfr7gp8a9//StttdVW+bqJ8xI30OKcxO/Y1P9OxL8Pr776alpppZVqlz/77LPpv//9b74JAkArKwFQ9a655ppS/JP+7LPPTned7t27l1ZbbbXa15tttllp5ZVXLk2YMKF22ZQpU0rrrbdeqV+/frXLbr/99rztRx55ZJptfv3119MsO+igg0qdO3eut9299tqrtMQSS9RbL7Z5yimn1L7eb7/9Sossskjps88+q7feLrvskste3teFF16YP3vbbbfVrjN+/PjSMsssM91yNvRdTf3o2LFj6dprr53pMU6aNKm00korlTbddNN6y+P44jjL4vgnT55cb51333037+f000+vXRbljf0vv/zypYkTJ9Yuv+iii/LyV155Jb/+7rvvSn379s37+fLLL+ttN87brJ7X6Wnou4lHfG+N/T7efPPNUps2bUoDBw6c5juoW9YVV1yxtNFGG01ThiOPPDLv8/HHH69d9tVXX+XjX3LJJWu3Wf7ullpqqQavxak9+OCDef1777233vJtttkmb6Nshx12yGWbVXF+p/f9xWP48OG168Z5jGXDhg2rXfbpp5/m6+OXv/xl7bIzzjijNO+885b++9//1tvXCSecUGrbtm3pgw8+qLfvbt265e3Utd122+XfyY8//rjeOWrXrl3+TNno0aNL88wzT+n444+v9/nDDz88l2HcuHGz/J0AMGs0cQeYS0RNZXk092h+HTWZP/3pT/OyqO2Lx+eff56bsb755pu5xm5m6vZnL2/nBz/4Qa71i2bWjRW5MGp3t9tuu/y8XJ54RHmiRvmFF17I6/71r3/NNYFR81gWzZCjxnBWXHrppblGOh7RFDua8O+///65hnV6x/jll1/mssQxlsszPVF7We4HHTWW8d3GOYimwg19Nppe163VjX2Ua+JD1IK+++67uSVB1MTWVW6m3FLndYcddqj9bsqPcvPmxnwfUSMdza+jNcXUfcHrNqmenjjH0ex7gw02qF0W312c42jKXW62XRa1z40ZWyG6e8SgdLfeemu9Y4jj23nnnWuXxfcb3Sii5rgpopxTf3/xWGGFFeqtF6/L5zlEjXZcH+VzHm6//fa8TjSzr/t7sfnmm+fratiwYfW2udNOO9WrGY91/vGPf+QWFHVbbUQz+ehyUVf37t3zuY9xGP7fvZr/9/n4vspdSgBoXZq4A8wlovl29NcuN62NP8Cjb3o8GhLNvqOZ9IxEc+po9hqhcOp+vxHcGut///tf7md71VVX5cf0yhOiL32Ei6mDXgSbWREBsO4gcTHydoyyHc3roxl5OSxH0+0zzzwzvfjii/X6uc8saEZAjebgMVJ5BOu6/fKjyfbUoulyXRHIygEyvP322/ln3abHU2up8xr94CMANqQx30eUNYL51IG0seIcr7322tMsL3etiPfrfg/RhaAxonl5BNjoSx5lj5socUMm+qfXDejHH398DrVxjcS1Fk3yo2l7dB1ojH79+k33+5vROS+f9/I5D3FTJZrXT90cferfi+l9F/F+dAuJ45haQ8ti9P4I5I8//nju4hLfQ3Q5iObvALQ+AR1gLhC1gRGYy3+QlweXij670xv4qaE/3uuKQB19Y2Pws+jPGgNPxQBUUZMaAWdWplUrrxv9v6M2tCFNmSJuVkSgjFr0CNURiqIPcISU6PccQSWCdtTcR1/m6Oc7swHDzj777BySY9C76CMdfYFjH1ED3tB307Zt2wa3U67JbIyWOK8z0pzvozXNyswE0c88+qDH+AZRKxz985dbbrl6g6PFjYA33ngj34x44IEHcuuOON5oERB9uFtKY855nNOY9u64446b7oj7dTV3loa4bmIsgGhVEuc5fsZYB4254QBA8wnoAHOBGEQtlENbjBYdIlzN7A/v6dUUx6jQ0XQ6aiDjD/myqC2eVVE7GIOQRS3zzMqzxBJL5EGsIsTULVsEqpaYlqrc2iBEMIubDg8++GCubS2LQDozMZhZBP4//OEP09zYiGbWsypugIQ49ul9R7NyXpuisd9HlDWCZTRFX3XVVWf52opz3ND5LHebiPebKq7VuLEQtcTRhD5af5QHqasrmnNHrXo8YjC8HXfcMY+yH4OzxXcwu8R3GddjU89ntJqJ8jY0I0BDy+KmQbQWiAEgY6T46K4QA8dN72YCAC1LH3SAOVwEkKjBjaavMfJ2+Y/2mNIqahJjJOiGmpyXlfudRrCsq/wHe93avggyUdM4q2Jb0fQ4AmAE0BmVJ6YY++STT+pN7RV93qfXNL6xoplzjHIfTdvLTamjXBEi6zZPjz7QEVoac0xT135Hf+LG9AGf3tzacQ5j1O6pz0V5P7NyXpuisd9H1ExHa4FoWTF1a4G630lcW1MfS/kcP/PMM2n48OG1y8aPH5/PcUxP1tSm8yHKFeMX3HvvvfnGVdyUqdu8PcSNp7rimoh9RtnjOpmdYjyB+B7ipsjU4rsr31Sa0TmLcB/nKH5v6obzaEXQkGjOHs3sY9T4hmY2AKD1qEEHmIPEH9xRyxh/tEe/0QjnMThV1DjGPNh1a/5ikLSoQYx5uqOGLGpf4zMRBqJJfHm+7qgBjT/yozYtmslHzWkMthXTYEV/2WiSHlNSRXCLwDMrTbKnnmbskUceyX2PozwRiGLQs2gyH/1g43mI9373u9/lvrLPP/98rg2N/cZAcU35rsr9dKOJdjRtj6nJotl+iGnDLrjggjxFVdQqxnrxvUUz8egXPCPRjz0Cagz+Ft/VK6+8km688cbaWu6mBMvLL788D6QX5yS2G8cexxBjAZQDXGPPa1M09vuI11ErHTeGYoCzqH2O6yYGXYuByoYMGZLXi+nE4piiT3t8Jm4wxLUV5yAGKotBzOLaiu4BMc1atM6ImzhTDzw3qyKQx7R6p5xySv6eyjdkyqLPeTTrjj7n0dw7prKLay6OP1p6zExcs9E0vKHa8HXXXXeWynrsscfm3924nspTsMXNirie4iZV3CCZWYuMmO4ubj7F8Rx88MH5BkscT/Tjj7EEphZjMcR7cUMpvpu4OQTAbDKLo74DUEBTTx3WoUOHUq9evUo//OEP83RdY8eObfBzb7/9dmnPPffM67Zv37606KKLln70ox+V7rjjjnrr/f73v8/TUMW0TnWnMvvnP/9ZWmeddUqdOnUq9e7du3TcccfVTmVVd7qzxkyzFkaNGlU65JBDSn369MnliXLFtGFXXXVVvfXef//90vbbb5+njlpwwQVLRxxxROmBBx5o8jRrMbXUqquuWrr88svrTQMW/vCHP+TpyWL6q+WWWy5/Pso99f9CG5pmLabLiqnj4vtZf/318zRbMa1Y3anFylOFxXR2dZWnzSpPb1b2xBNP5PPatWvXPPVV//79S5dcckmTzmtDYp9xDqansd9H+OMf/5in9ot155tvvnzcDz30UO37I0eOLG277bb5WOLzdb+XOIYf//jHpR49euTzs9Zaa5Xuu+++etuf3nc3M3GO4xqLz5555pnTvH/llVeWNtxww9ICCyyQy7700kuXjj322NKYMWOaNc1a3esjrpc49qlNfX2Up5gbNGhQnkowfrfjmo9p884///w8zV3dfZ933nkNlm3o0KH5XMTn43iuvvrqfH3Gd9uQc889N2/v7LPPnuExA9CyauI/s+tmAAAAxRBdEaL1RbQcmVoMlnjUUUflGvqGRpsHoHXogw4AMIeLqdbqilAe883HmAVTi7qbGNwwZmkQzgFmL33QAQDmcDEWQfRhj58xj3z0/Y/B7+pO3xZ926O/e4wFEX3c77nnnoqWGWBupIk7AMAcLgYVjOA9cuTIPGBfDFZ39tln1xsALpqzx0wBPXr0SL/4xS/ytHIAzF4COgAAABSAPugAAABQAAI6AAAAFIBB4uYyU6ZMSZ988knq2rVrqqmpqXRxAACAConezl999VXq3bt3atNG3W0RCOhzmQjnffr0qXQxAACAgvjwww/TYostVuliIKDPfaLmvPxL2K1bt0oXBwAAqJCxY8fmyrtyRqDyBPS5TLlZe4RzAR0AAND1tTh0NAAAAIACENABAACgAAR0AAAAKAABHQAAAApAQAcAAIACENABAACgAAR0AAAAKAABHQAAAApAQAcAAIACENABAACgAAR0AAAAKAABHQAAAApAQAcAAIACENABAACgAAR0AAAAKAABHQAAAAqgXaULAAAA0GpKpYafN/W9lthGmzYpderUuPIzVxHQqZx//Sul8eOL+w+nbdiGbVR3eW3DNmyjmPuyDduYHdsoulVWSenFFytdCgpIQKdy9t47pZdfrnQpAAAACkFAp3KWWCKlb775v9c1NQ0/b+p7Lb1eUbYxp+6r2srru5lzyuu7Kca+qq28vpti7Kvayuu7Kca+ilDeqdeB/5+ATuX85S+VLgEAAEBhGMUdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABPQCGTJkSPr+97+funbtmhZeeOE0YMCA9MYbb9RbZ+ONN041NTX1Hj//+c8rVmYAAABahoBeII899lg65JBD0lNPPZUeeuih9O2336YtttgijR8/vt56BxxwQBoxYkTt49xzz61YmQEAAGgZ7VpoO7SABx54oN7ra6+9NtekP//882nDDTesXd65c+fUq1evCpQQAACA1qIGvcDG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AHEAAAC0BH3QW1A0RtAgAQAAgKYQ0FvA9ddfn1ZeeeXUqVOn/Ojfv3+64YYbKl0sAAAAqogm7s10wQUXpMGDB6dDDz00rb/++nnZE088kX7+85+nzz77LB111FGVLiIAAABVwCBxLTBI3GmnnZb23HPPesuvu+66dOqppxauj7qBIAAAgCAbFI8m7s00YsSItN56602zPJbFewAAANAYAnozLbPMMum2226bZvmtt96a50gHAACAxtAHvZmiefvOO++chg0bVtsH/Z///GcaOnRog8EdAAAAGqIGvZl22mmn9PTTT6cFF1ww3X333fkRz5955pk0cODAShcPAACAKmGQuLmMgSAAAIAgGxSPGvRmatu2bfr000+nWf7555/n9wAAAKAxBPRmml4DhIkTJ6YOHTrM9vIAAABQnQwS10QXX3xx/llTU5Ouvvrq1KVLl9r3Jk+enAeNW2655SpYQgAAAKqJgN5Ev/3tb2tr0K+44op6zdmj5nzJJZfMywEAAKAxBPQmevfdd/PPTTbZJN11111pvvnmq3SRAAAAqGICejM98sgjlS4CAAAAcwCDxLXAPOjnnHPONMvPPffc9JOf/KQiZQIAAKD6COjNFIPBbbPNNtMs33rrrfN7AAAA0BgCejONGzeuwenU2rdvn8aOHVuRMgEAAFB9BPRmWnnlldOtt946zfJbbrklrbDCChUpEwAAANXHIHHNNHjw4LTjjjumt99+O2266aZ52dChQ9PNN9+cbr/99koXDwAAgCohoDfTdtttl+6+++509tlnpzvuuCN16tQp9e/fP/3jH/9IG220UaWLBwAAQJWoKZVKpUoXgtkn+sV37949jRkzJnXr1q3SxQEAACpENigefdABAACgADRxb6bJkyen3/72t+m2225LH3zwQZo0aVK997/44ouKlQ0AAIDqoQa9mU477bR0wQUXpJ133jk3DTn66KPzoHFt2rRJp556aqWLBwAAQJUQ0JvpxhtvTL///e/TL3/5y9SuXbu06667pquvvjqdfPLJ6amnnqp08QAAAKgSAnozjRw5Ms+FHrp06ZJr0cOPfvSjdP/991e4dAAAAFQLAb2ZFltssTRixIj8fOmll05///vf8/Nnn302dezYscKlAwAAoFoI6M00cODANHTo0Pz8sMMOS4MHD079+vVLe+65Z9p3330rXTwAAACqhHnQm2jKlCl5ILipRb/zJ598Mof07bbbLhWNuQ4BAIAgGxSPadaaqH379rlp+8ILL5xfH3vssWnQoEFpnXXWyQ8AAACYFZq4N9HUDQ+uvPLKNHr06IqVBwAAgOomoLcQPQUAAABoDgEdAAAACkAf9GY4+eSTU+fOnfPzSZMmpbPOOisPslDXBRdcUKHSAQAAUE0E9CbacMMN0xtvvFH7er311kvvvPNOvXVqamoqUDIAAACqkYDeRI8++miliwAAAMAcRB90AAAAKAABvUCGDRuWtttuu9S7d+/cPP7uu++u9/7ee++dl9d9bLXVVhUrLwAAAC1HQC+Q8ePHp1VWWSVdeuml010nAvmIESNqHzfffPNsLSMAAACtQx/0Atl6663zY0Y6duyYevXqNdvKBAAAwOyhBr0KB6dbeOGF07LLLpsOPvjg9Pnnn1e6SAAAALQANegt4PHHH09XXnllevvtt9Mdd9yRFl100XTDDTekvn37pg022KDF9hPN23fccce83djXr371q1zjPnz48NS2bdsGPzNx4sT8KBs7dmyLlQcAAMLkyZPTt99+W+liMJXICO3atTP9cxUR0JvpzjvvTHvssUfabbfd0r/+9a/aMDxmzJh09tlnp7/+9a8ttq9ddtml9vnKK6+c+vfvn5Zeeulcq77ZZps1+JkhQ4ak0047rcXKAAAAdY0bNy599NFHqVQqVbooNKBz585pkUUWSR06dKh0UWgEAb2ZzjzzzHTFFVekPffcM91yyy21y9dff/38Xmtaaqml0oILLpjeeuut6Qb0QYMGpaOPPrpeDXqfPn1atVwAAMw9NecRziMELrTQQmpqCyRumEyaNCn973//S++++27q169fatNGD+eiE9Cb6Y033kgbbrjhNMu7d++eRo8e3ar7jn8Mow963BGb0aBy8QAAgJYWzdojCEY479SpU6WLw1TinLRv3z69//77OazPM888lS4SM+EWSjPFiOpRgz21J554Itdwz2rzoBdffDE/QtzpiucffPBBfu/YY49NTz31VHrvvffS0KFD0w477JCWWWaZtOWWW7bY8QAAwKxSc15cas2ri7PVTAcccEA64ogj0tNPP53/Yfrkk0/SjTfemI455pg8yvqseO6559Jqq62WHyGapsfzk08+OQ/w8PLLL6ftt98+fe9730v77bdfWmONNfIAdWrIAQAAqp8m7s10wgknpClTpuQ+4F9//XVu7h6BOQL6YYcdNkvb2njjjWc4uMaDDz7YAiUGAACgiNSgN1PUmp944onpiy++SK+++mpugh4DMZxxxhmVLhoAANDA3+8zepx66qlN2u7tt9+elltuudzPO2Zcmno2p6iMO/LII+stu+iii3LlXt3Bppm7qUFvpphOLUavnH/++dMKK6xQuzwCe8w52K1bt4qWDwAA+D8jRoyofX7rrbfm7qQx8HNZly5dZnmbTz75ZNp1113zFMc/+tGP0k033ZQGDBiQXnjhhbTSSis1+JlTTjklnX/++emee+5JW221VROPhjmNGvQWmJu8oTtet912W715ywEAgGIM8lx+xMxLUWted1lTAnrUhEfIjkGdl19++dyadvXVV0+/+93vplk3urRGV9iLL744PfTQQ8I59ahBb6YYHO6CCy6YZnk0YYmm7wAAMLeI4ZS+/roy++7cOZqvt9z2ZhbUd99993TFFVfk58OHD88DPNcVMy3dfffd9ZZ99913+XMPP/xweuyxx1L//v1brsDMEQT0Zpo4cWL+RWtoTshvvvmmImUCAIBKiHDehAroFjFuXErzztty2ytPfTw9dbuyjhw5MvXs2bPe+/E6ltf1+9//Pv986aWXcn91mJqA3kxrrbVWuuqqq9Ill1xSb3ncTYtp0AAAgOqzzDLLtPg2N9hggxz8Bw8enG6++eY8ZhXU5YpopjPPPDNtvvnm+S5YTLUWhg4dmp599tn097//vdLFAwCA2drMPGqyK7XvljQrTdyj7/qoUaPqvR+vY3ldMbr7b37zm5wfdt555zxInZBOXa6GZlp//fVzn5PzzjsvDwzXqVOn3JfkD3/4Q+rXr1+liwcAALNN9AFvyWbmlTQrTdzXXXfdXElXdxq1GAAulk9t1VVXzetGSP/pT3+aQ3r79u1buPRUKwG9BcQv2Y033ljpYgAAABVo4n7EEUekjTbaKNeOb7vttnmWp+eeey53hW3IKquskgeKixa4EdKjok9IJwjoLWDKlCnprbfeSp9++ml+XteGG25YsXIBAACtb7311stzn5900knpV7/6VW5JGyO4T28O9HJz93JI/8lPfpJDeocOHWZruSmemlJMxEeTPfXUU+lnP/tZev/99/OchnXFnIqTJ09ORTJ27Ng83+OYMWPqNcsBAIBZNWHChPTuu++mvn37pnnmmafSxWEWz5FsUDxq0Jvp5z//eVpzzTXT/fffnxZZZJEcygEAAGBWCejN9Oabb6Y77rijVaZhAAAAYO7RptIFqHZrr7127n8OAAAAzaEGvZkOO+yw9Mtf/jKNHDkyD/Qw9eiLMeUaAAAAzIyA3kw77bRT/rnvvvvWLot+6DFgXBEHiQMAAKCYBPRmihERAQAAoLkE9GZaYoklKl0EAAAA5gACegt57bXX0gcffJAmTZpUb/n2229fsTIBAABQPQT0ZnrnnXfSwIED0yuvvFLb9zyU50PXBx0AAIDGMM1aMx1xxBGpb9++6dNPP02dO3dO//73v9OwYcPSmmuumR599NFKFw8AAIAqIaA30/Dhw9Ppp5+eFlxwwdSmTZv82GCDDdKQIUPS4YcfXuniAQAAdURL1xk9Tj311Fne5rXXXjvNduaZZ55660RL25NPPjktssgiqVOnTmnzzTdPb7755jRlu/vuu2tff/vtt2nXXXdNiy66aHr11VebcdRUC03cmymasHft2jU/j5D+ySefpGWXXTYPHvfGG29UungAAEAdI0aMqH1+66235tBc9+/2Ll26NGm73bp1q7edcpfXsnPPPTddfPHF6brrrsstcAcPHpy23HLLPJbV1GE+fP3113lK5wjxTzzxRP4Mcz4BvZlWWmml9NJLL+VfmLXXXjv/4nXo0CFdddVVaamllqp08QAAgDp69epV+7x79+45SNdd1lQz2k7Unl944YXppJNOSjvssENedv3116eePXvmGvNddtml3vqjR49O2267bRo3blwO5y1RPqqDgN5M8Us2fvz4/Dyauv/oRz9KP/jBD9ICCyyQ78gBAMDcIoLo199+XZF9d27feZpa6+aYWU367rvvnq644ora1xGmoxXtlClT0uqrr57OPvvstOKKK+b33n333TRy5MjcrL3uzYGo4Isus3UDeqy30UYb5f0/9thjqUePHi12TBSfgN5M0SylbJlllkmvv/56+uKLL9J8883Xov9AAABA0UU47zKkaU3Em2vcoHFp3g7zttj2XnzxxZk2aS+LLq5//OMfU//+/dOYMWPS+eefn9Zbb708gPRiiy2WQ3eIGvO64nX5vbqDUEdL3IceeigPQs3cRUBvBfPPP3+liwAAADRDVL411rrrrpsfZRHOl19++XTllVemM844Y5b2Gy1yo9l7fPaoo46apc9S/QT0Jthxxx0bve5dd93VqmUBAICiiGbmUZNdqX23pFlt4l5X+/bt02qrrZbeeuut/Lrch3zUqFF5FPeyeL3qqqvW++wee+yRtt9++7TvvvvmLgNHH310CxwN1UJAb4LoLwIAANQXXTxbspl5Jc1KE/eGZnp65ZVX0jbbbJNfx4DSEdKHDh1aG8jHjh2bnn766XTwwQdP8/m99torT9+8zz775D7txxxzTLOPh+ogoDfBNddcU+kiAAAABWniHoNFr7POOvkzMQL7eeedl95///20//771964OPLII9OZZ56Z+vXrVzvNWu/evdOAAQMa3GbUpEdIj7AeNenHHntsix0bxSWgAwAANMOXX36ZDjjggDzgWwwWvcYaa6Qnn3wyrbDCCrXrHHfccXn2pwMPPDCH+A022CA98MADDc6BXrbbbrvlkB5hPWrSjz/++Nl0RFRKTSlux9Asd9xxR7rtttvSBx98kCZNmlTvvRdeeCEVSTSliSb6MbrkjJrlAADAzEyYMCFPIRY1wjMKmhTzHMkGxdOm0gWodhdffHHuGxJTJPzrX/9Ka621Vp4D/Z133klbb711pYsHAABAlRDQm+myyy5LV111VbrkkktShw4dctOVmLPw8MMPz3eiAAAAoDEE9GaKZu0xz2Ho1KlT+uqrr/Lz6Cdy8803V7h0AAAAVAsBvZliuoQvvvgiP1988cXTU089lZ9HPw/d+wEAAGgsAb2ZNt100/SXv/wlP4++6EcddVT64Q9/mHbeeec0cODAShcPAACAKmGatWaK/ucx5UE45JBD8gBxMaXC9ttvnw466KBKFw8AAIAqIaA3U8xLGI+yXXbZJT8AAABgVgjoLWj8+PHp1ltvTd98803aYostUr9+/SpdJAAAAKqEPujNGL19o402Sl27ds19zuP16quvnvbff/902GGHpVVXXTUNGzas0sUEAACgSgjoTXTMMcekSZMmpSuuuCJ17tw5bbnllrnGfMSIEWnUqFFp6623TqeeemqliwkAAECVENCbKGrHL7roorTbbrula665Jr3xxhvpxBNPTD179kwLLbRQGjx4cHr55ZcrXUwAAKCOmpqaGT6aUsl21113pTXXXDP16NEjzTvvvLk17Q033FBvnZiC+eSTT06LLLJI6tSpU9p8883Tm2++WW+dmL458kW3bt3ytvbbb780bty42vcfffTRXMbRo0fXLvvkk0/SyiuvnDbccMM0ZsyYJn0nFIeA3kSffvppWmKJJfLz+eefP9eiRzivOz/6l19+WcESAgAAU4sWr+XHhRdemMNw3WXRUnZWRR6Iyrrhw4fnSrqYfjkeDz74YO065557brr44otzC9ynn346B/lohTthwoTadSKc//vf/04PPfRQuu+++3Kl4IEHHjjd/b799ttpgw02yLkk9tW9e/cmfCMUiUHimiHuXjX0HAAAKKaoSCuLQBt/x9dd1hQbb7xxvddHHHFEuu6669ITTzyRQ3jUnsfNgJNOOintsMMOeZ3rr78+V/DdfffdeRao//znP+mBBx5Izz77bK6ND5dccknaZptt0vnnn5969+5dbx9xIyC2vemmm+Z9tWsn2s0JnMVmiCYqUXMeoj/6WWedVXvX6uuvv65w6QAAYDYrleIP4crsO/4ub8FKsy5duszw/d133z3Xhk8twvjDDz+cu8Cec845edm7776bRo4cmZu1l0VuWHvttXOtewT0+BnN2svhPMT6MaVz1LgPHDiwdvmTTz6Za9vjESFeZeGcQ0BvoujjEb90Zeutt1565513plkHAADmGhHOZxJsW0301Z533hbb3IsvvjjD96NpfF3R/3vRRRdNEydOTG3btk2XXXZZnu0pRDgPdbvEll+X34ufCy+8cL33o1Y8ms+X1ymLsL7zzjun3/3ud804QopIQG+iGKABAACYMy2zzDKztH5MvxyhPgZ1Gzp0aDr66KPTUkstNU3z95YQzeT//Oc/p8cffzz94Ac/aPHtUzkCOgAA0HLNzOuMOj7b992CZrWJezRFL4f6GMU9+pQPGTIkB/RyH/eYjjlGcS+L17FuiHViIOq6vvvuuzyy+9R95K+88sp03HHH5amd//rXv2q5OwcR0AEAgJYRfaFbsJl5Jc1qE/epTZkyJTd3D3379s0hO2rWy4F87NixuW/5wQcfnF+vu+66efq0559/Pq2xxhp5WfRlj+1EX/W6os/5VVddlW8KxCBy999/f9poo42adbwUg4AOAADQjCbuUVMeg7stvfTSOZRHrXbMg3755ZfXBuojjzwynXnmmalfv345sA8ePDiPzD5gwIC8zvLLL5+22mqrdMABB+Sa+W+//TYdeuiheQC5qUdwL28z1ov+7uWQ3hrN6Zm9BHQAAIBmGD9+fPrFL36RPvroo9SpU6e03HLLpT/96U95ILeyaJIe68W85lFTHvOXx7Rq88wzT+06N954Yw7lm222Wa4d32mnnfLc6dMTIf3SSy/N62677bZ57vRNNtmk1Y+X1lNTinkAmGtEU5qY0iFGmZxZsxwAAJiRCRMm5CnEoka4btCkOs6RbFA8atCb4OWXX270uv3792/VsgAAADBnENCbIAZ2iOYk0fggfs7I5MmTZ1u5AAAAqF5tKl2AahRNRN555538884778zNRS677LL0r3/9Kz/ieQwQEe8BAABAY6hBb4Illlii9vlPfvKTPHBDjJxYt1l7nz598siM5VEZAQAAYEbUoDfTK6+8kmvQpxbLXnvttYqUCQAAgOojoDdTzFcY8x5OmjSpdlk8j2XxHgAAzOlMDFVczk110cS9ma644oq03XbbpcUWW6x2xPYY5T0Gj7v33nsrXTwAAGg1bdu2ra2givm/KZ6vv/46/2zfvn2li0IjCOjNtNZaa+UB42688cb0+uuv52U777xz+tnPfpbmnXfeShcPAABaTbt27VLnzp3T//73vxwA27TRQLdINecRzj/99NPUo0eP2pspFFtNSZuHucrYsWNT9+7d05gxY1K3bt0qXRwAAKpc1J7H7EZTpkypdFFoQITzXr16NTg9tGxQPGrQW8ANN9yQrrzyylyTPnz48DzK+29/+9u01FJLpR122KHSxQMAgFbToUOH1K9fv3pjMlEM0apBzXl1EdCb6fLLL08nn3xyOvLII9OZZ56ZJk+enJfPN9986cILLxTQAQCY40XT9nnmmafSxYCqp5NIM11yySXp97//fTrxxBNzH5yyNddcM0/BBgAAAI0hoDdT9LdZbbXVplnesWPHNH78+IqUCQAAgOojoDdT375904svvjjN8gceeMA86AAAADSaPujNdPTRR6dDDjkkTZgwIU9l8Mwzz6Sbb745DRkyJF199dWVLh4AAABVQkBvpv333z916tQpnXTSSXmewZj/vHfv3umiiy5Ku+yyS6WLBwAAQJUwD3oLioA+bty4tPDCC6eiMtchAAAQZIPi0Qe9BXXu3LlZ4XzYsGFpu+22yzXwNTU16e677673ftxLiSndFllkkVxrv/nmm6c333yzBUoOAABApWni3gQxansE6MZ44YUXGr3dGPV9lVVWSfvuu2/a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64VZ5ZopPjXnxeI2CQAAABSAgA4AAAAFIKBDAXXs2DGdcsop+Sc0hmuGWeWaYVa4XphVrhloGoPEAQAAQAGoQQcAAIACENABAACgAAR0AAAAKAABHQAAAApAQIcK+OKLL9Juu+2WunXrlnr06JH222+/NG7cuBl+ZsKECemQQw5JCyywQOrSpUvaaaed0qhRoxpc9/PPP0+LLbZYqqmpSaNHj26lo6Dar5mXXnop7brrrqlPnz6pU6dOafnll08XXXTRbDgaWsOll16allxyyTTPPPOktddeOz3zzDMzXP/2229Pyy23XF5/5ZVXTn/961/rvR9jyJ588slpkUUWydfH5ptvnt58881WPgqq9Zr59ttv0/HHH5+XzzvvvKl3795pzz33TJ988slsOBKq9d+Zun7+85/nv1suvPDCVig5VA8BHSoggta///3v9NBDD6X77rsvDRs2LB144IEz/MxRRx2V7r333vw/u8ceeyz/0bPjjjs2uG6Et/79+7dS6ZlTrpnnn38+LbzwwulPf/pT3vaJJ56YBg0alH73u9/NhiOiJd16663p6KOPzlMavfDCC2mVVVZJW265Zfr0008bXP/JJ5/MN2fi34p//etfacCAAfnx6quv1q5z7rnnposvvjhdccUV6emnn86hK7YZN36ofi19zXz99dd5O4MHD84/77rrrvTGG2+k7bfffjYfGdX070zZn//85/TUU0/lGzsw14tp1oDZ57XXXoupDUvPPvts7bK//e1vpZqamtLHH3/c4GdGjx5dat++fen222+vXfaf//wnb2f48OH11r3ssstKG220UWno0KH5/S+//LIVj4Y54Zqp6xe/+EVpk002aeEjoLWttdZapUMOOaT29eTJk0u9e/cuDRkypMH1f/rTn5a23XbbesvWXnvt0kEHHZSfT5kypdSrV6/SeeedV++a6tixY+nmm29uteOgeq+ZhjzzzDP535z333+/BUvOnHbNfPTRR6VFF1209Oqrr5aWWGKJ0m9/+9tWOgKoDmrQYTYbPnx4bqK85ppr1i6LpqNt2rTJtVQNiZrOaD4Y65VFk7HFF188b6/stddeS6effnq6/vrr8/aYM7TmNTO1MWPGpPnnn7+Fj4DWNGnSpHy+657ruDbi9fTOdSyvu36ImrDy+u+++24aOXJkvXW6d++em7TO6Pph7r1mGhL/nkST5fj3i+rWWtfMlClT0h577JGOPfbYtOKKK7biEUD18Bc8zGbxR280K66rXbt2ORTFe9P7TIcOHab5I6dnz561n5k4cWJuSnbeeeflEMaco7WumYaaI0YTxpk1nadYPvvsszR58uR8bht7rmP5jNYv/5yVbTJ3XzNTi64Q0Sc9/r8UY2dQ3VrrmjnnnHPy/88OP/zwVio5VB8BHVrICSeckGsKZvR4/fXXW23/0Xc4BvnafffdW20fzFnXTF3RJ3CHHXbIfQu32GKL2bJPYM4UrXd++tOf5oEGL7/88koXh4KKGvkYmPTaa6/N/78D/p92//9PoJl++ctfpr333nuG6yy11FKpV69e0wyo8t133+VRuuO9hsTyaF4WI7LXrRGNEbnLn3n44YfTK6+8ku644478Ov4wCgsuuGAe/Ou0005r9jEyZ10zdbtGbLbZZrnm/KSTTmrWMTH7xe9427Ztp5nVoaFzXRbLZ7R++Wcsi1Hc666z6qqrtsJRUO3XzNTh/P3338//X1J7PmdojWvm8ccfz/9vq9vqL2rp4/+NMZL7e++91yrHAkWnBh1ayEILLZT7+M7oEU2O11133Rya4s5xWfwRE/2won9nQ9ZYY43Uvn37NHTo0NplMTruBx98kLcX7rzzzjxt1osvvpgfV199de3/AGOqLYqn0tdMiNHbN9lkk7TXXnuls846q5WPmNYQ10ic77rnOq6NeF33XNcVy+uuH2KGgPL6ffv2zX9E111n7NixecyD6W2TufuaqRvOYzq+f/zjH3mKR+YMrXHNRN/zl19+ufbvlnjEKO7RH/3BBx9s5SOCAqv0KHUwN9pqq61Kq622Wunpp58uPfHEE6V+/fqVdt1113ojmi677LL5/bKf//znpcUXX7z08MMPl5577rnSuuuumx/T88gjjxjFfQ7SGtfMK6+8UlpooYVKu+++e2nEiBG1j08//XS2Hx/Nc8stt+QR1q+99to86v+BBx5Y6tGjR2nkyJH5/T322KN0wgkn1K7/z3/+s9SuXbvS+eefn0f3P+WUU/Ko/3FNlP3617/O27jnnntKL7/8cmmHHXYo9e3bt/TNN99U5Bgp9jUzadKk0vbbb19abLHFSi+++GK9f1MmTpxYseOk2P/OTM0o7lAqCehQAZ9//nkOV126dCl169attM8++5S++uqr2vfffffdHK4jZJfFH8UxBdZ8881X6ty5c2ngwIH5D5/pEdDnLK1xzcQfS/GZqR/xBxLV55JLLsk3ZDp06JCnQ3rqqadq34upF/faa6966992222l733ve3n9FVdcsXT//ffXez+mWhs8eHCpZ8+e+Y/yzTbbrPTGG2/MtuOhuq6Z8r9BDT3q/rtEdWvpf2emJqBDqVQT/6l0LT4AAADM7fRBBwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAJjG559/nhZeeOH03nvvpSLYZZdd0m9+85tKFwMAWpWADgDNsPfee6eampppHltttVWqZmeddVbaYYcd0pJLLtlq+3j++efzd/XUU081+P5mm22Wdtxxx/z8pJNOymUaM2ZMq5UHACpNQAeAZoowPmLEiHqPm2++uVX3OWnSpFbb9tdff53+8Ic/pP322y+1pjXWWCOtssoq6Y9//OM070XN/SOPPFJbhpVWWiktvfTS6U9/+lOrlgkAKklAB4Bm6tixY+rVq1e9x3zzzVf7ftQSX3311WngwIGpc+fOqV+/fukvf/lLvW28+uqraeutt05dunRJPXv2THvssUf67LPPat/feOON06GHHpqOPPLItOCCC6Ytt9wyL4/txPbmmWeetMkmm6Trrrsu72/06NFp/PjxqVu3bumOO+6ot6+77747zTvvvOmrr75q8Hj++te/5mNaZ511apc9+uijebsPPvhgWm211VKnTp3Spptumj799NP0t7/9LS2//PJ5Xz/72c9ywC+bMmVKGjJkSOrbt2/+TATyuuWJAH7rrbfW+0y49tpr0yKLLFKvJcJ2222Xbrnlllk6NwBQTQR0AJgNTjvttPTTn/40vfzyy2mbbbZJu+22W/riiy/yexGmI+xG8H3uuefSAw88kEaNGpXXryvCd4cOHdI///nPdMUVV6R33303/fjHP04DBgxIL730UjrooIPSiSeeWLt+hPDou33NNdfU2068js917dq1wbI+/vjjuXa7Iaeeemr63e9+l5588sn04Ycf5jJeeOGF6aabbkr3339/+vvf/54uueSS2vUjnF9//fW5vP/+97/TUUcdlXbffff02GOP5ffje5g4cWK90F4qlfKxRveBtm3b1i5fa6210jPPPJPXB4A5UgkAaLK99tqr1LZt29K8885b73HWWWfVrhP/uz3ppJNqX48bNy4v+9vf/pZfn3HGGaUtttii3nY//PDDvM4bb7yRX2+00Ual1VZbrd46xx9/fGmllVaqt+zEE0/Mn/vyyy/z66effjqX75NPPsmvR40aVWrXrl3p0Ucfne4x7bDDDqV999233rJHHnkkb/cf//hH7bIhQ4bkZW+//XbtsoMOOqi05ZZb5ucTJkwode7cufTkk0/W29Z+++1X2nXXXWtf77LLLvn4yoYOHZq3++abb9b73EsvvZSXv/fee9MtOwBUs3aVvkEAANUumpZffvnl9ZbNP//89V7379+/Xs12NAeP5uEhar+jv3U0b5/a22+/nb73ve/l51PXar/xxhvp+9//fr1lUcs89esVV1wx10ifcMIJuQ/3EksskTbccMPpHs8333yTm8w3pO5xRFP8aLK/1FJL1VsWtdzhrbfeyk3Xf/jDH07Tfz5aC5Ttu+++ucl+HGv0M48+6RtttFFaZpll6n0umsiHqZvDA8CcQkAHgGaKwD11mJxa+/bt672O/tzRPzuMGzcu968+55xzpvlc9MOuu5+m2H///dOll16aA3o0b99nn33y/qcn+rh/+eWXMz2O2MbMjitE0/dFF1203nrRx73uaO2LL7547nd+7LHHprvuuitdeeWV0+y73CVgoYUWauSRA0B1EdABoMJWX331dOedd+Ypzdq1a/z/mpdddtk8oFtdzz777DTrRZ/v4447Ll188cXptddeS3vttdcMtxu12y0xWvoKK6yQg/gHH3yQa8Snp02bNvmmQYwcH0E++tlHH/mpxUB6iy22WL6BAABzIoPEAUAzxaBlI0eOrPeoOwL7zBxyyCG5dnjXXXfNATuaesdo6RFaJ0+ePN3PxaBwr7/+ejr++OPTf//733TbbbflWuhQt4Y8RpSP+cSjdnqLLbbIIXdGorl5DOg2vVr0xopB6I455pg8MFw0sY/jeuGFF/IgcvG6rjjWjz/+OP3qV7/K30O5OfvUg9dF+QFgTiWgA0Azxajr0RS97mODDTZo9Od79+6dR2aPMB4BdOWVV87TqfXo0SPXLk9PTF0Wo59Hk/DoGx794MujuNdtQl6eziz6fkd/75mJ/UetfgT+5jrjjDPS4MGD82juMRVbTJsWTd6j7HVFE/fNN9883xRoqIwTJkzI08MdcMABzS4TABRVTYwUV+lCAAAt46yzzspTmsUUaHXdcMMNuSb7k08+yU3IZyZCdNS4R7PyGd0kmF3i5sOf//znPI0bAMyp9EEHgCp22WWX5ZHcF1hggVwLf95556VDDz209v0Y8XzEiBHp17/+dW4S35hwHrbddtv05ptv5mbnffr0SZUWg9HVnV8dAOZEatABoIpFrfitt96a+7BHM/E99tgjDRo0qHawuVNPPTXXqse0avfcc0+DU7kBAMUgoAMAAEABVL5TGQAAACCgAwAAQBEI6AAAAFAAAjoAAAAUgIAOAAAABSCgAwAAQAEI6AAAAFAAAjoAAAAUgIAOAAAABSCgAwAAQAEI6AAAAFAAAjoAAAAUgIAOAAAABSCgAwAAQAEI6AAAAFAAAjoAAAAUgIAOAAAABSCgAwAAQAEI6AAAAFAAAjoAAAAUgIAOAAAABSCgAwAAQKq8/w+rOLDV/JmWgAAAAABJRU5ErkJggg==", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Detailed balance vs energy, meV scale\n", + "x=np.linspace(-0.05, 0.05, 10001)\n", + "\n", + "T=0\n", + "DetailedBalanceT1=detailed_balance_factor(x,T)\n", + "plt.figure(figsize=(10, 6))\n", + "plt.plot(x, DetailedBalanceT1, label=f'T={T}K', color='blue')\n", + "\n", + "T=50\n", + "DetailedBalanceT2=detailed_balance_factor(x,T)\n", + "plt.plot(x, DetailedBalanceT2, label=f'T={T}K', color='green')\n", + "\n", + "\n", + "T=300\n", + "DetailedBalanceT3=detailed_balance_factor(x,T)\n", + "plt.plot(x, DetailedBalanceT3, label=f'T={T}K', color='red')\n", + "\n", + "plt.title('Detailed Balance Factor vs Energy')\n", + "plt.legend()\n", + "\n", + "plt.xlabel('Energy (meV)')\n", + "plt.ylabel('Detailed Balance Factor')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "5e3efad9", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "4eccf8fc0f0f459ba4ebfb52b5ef9870", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAddxJREFUeJzt3Qd4U9X7B/BvZvempVDKLHsvGSpbpspQRHCgAipOwJ8iDpyIiLgHbhx/FzIcIKgIKEv23qsttLSM7pU2yf85J01oS0fSJs36fp7ncm9u7r05l7bJmzPeozAajUYQERERkddQOrsARERERFS7GAASEREReRkGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASEREReRkGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASEREReRkGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASEREReRkGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASEREReRkGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXUTu7AO7MYDAgKSkJQUFBUCgUzi4OERERWcFoNCIrKwv169eHUumddWEMAGtABH+xsbHOLgYRERFVQ2JiIho0aABvxACwBkTNn/kXKDg42NnFISIiIitkZmbKChzz57g3YgBYA+ZmXxH8MQAkIiJyLwov7r7lnQ3fRERERF6MASARERGRl2EASERERORl2AeQiIjITqlFioqKoNfrnV0Ur6dSqaBWq726j19VGAASERHVkE6nQ3JyMnJzc51dFCrm7++PevXqQavVOrsoLokBIBERUQ0nBTh16pSsdRKJhUXAwZon59bEioD8/Pnz8ufSvHlzr032XBkGgERERDUggg0RBIq8cqLWiZzPz88PGo0G8fHx8ufj6+vr7CK5HIbEREREdsBaJtfCn0fl+L9DRERE5GUYABIRERF5GQaAREREXkgMVKlsef7556t13cWLF6NVq1ay31379u2xcuXKSo9ftGgRQkNDS+07dOiQ7FM5duxY2YeP7I8BIBERkRcSaWvMy1tvvSXntC+573//+5/N19y0aRPGjx+PSZMmYdeuXRg1apRc9u/fb/U1tm3bhmuvvRZDhw7FDz/8wDQuDsIAkIiIyAtFR0dblpCQEFnrV3JfYGCgzdd8++23ZeD2+OOPo3Xr1njppZfQpUsXvPfee1ad//fff2PAgAEygPzkk084kMOBmAaGiKgCujNnoL94EX4dOzq7KOSGuejyCp0zI4ifRmXXPIRVBYK33347Fi5cKLc3b96MGTNmlHp+yJAhWL58eZWvs2zZMkyYMEE2Pc+cObOGpaaqMAAkIipH5h9/4Oyj0+DfvTsaffWls4tDbkYEf21mr3bKax98cQj8tfb7eN+9e3elz4umY7Nz586hbt26pZ4Xj8X+ymRnZ8v+fk899RSDv1rCAJCIqASjXo8L738AhY+PqMZB/v79cp9CpXJ20YicIi4urlYSN19zzTWy2Vf0IRTNx+RYDACJiErQnT6NCx98AIWvr1wMubnQnToFn1r4ECTPIZphRU2cs17bnmxpAhZ9B1NSUko9Lx6L/ZUR0+iJZuIxY8agf//+WLt2LYNAB2MASERUgi4xUa61TZtAoVAi/8AB6OLjGQCSTUQfPHs2wzqTLU3AvXr1wpo1azBt2jTLvj///FPur4qPjw+WLl2Km2++WQaBYkBImzZtalh6qohn/HYSEdlJ4dmzcq2NiYFCozUFgKfjnV0sIrdoAn700UfRt29fLFiwACNGjMD333+P7du34+OPP7bqfBEELlmyRPYHNAeBbdu2rUHpqSIcX01EVELh2SS51tSPgaZRQ7mtS0hwcqmI3EPv3r3x7bffyoCvY8eO+Omnn2TTbrt27ay+hsj7J84T1xJBoC05BMl6DACJiMqpAdTExEBTr57cLirTp4nI09x1111IT0+3y7VE7d2RI0dQUFAgg7fhw4fb/NoajUamhUlNTbUpeCTrsQmYiKi8ALBBDDT166POA1Ph07KVs4tFRGRXDACJiCqoAfRt2RK+rRj8EZHnYQBIRFRCw0WLZBCobWjq/0dE5IkYABIRleDbsoVczEQKmMKUFPi1awelv79Ty0ZEZC8cBEJEVIn42+9Awp0TUXDylLOLQkRkNwwAiYiKFRw/jouffYasdess+9RRUXJdlJrqxJIREdkXA0AiomJ5u3cjdf7rSPvuO8s+dWSkXBedP+/EkhER2ZdHBIAffvghOnToIKejEYuYcub333+v9JzFixejVatW8PX1Rfv27bFy5cpaKy8RuaaiS2lyrQ6PuLIGkAEgEXkQjwgAGzRogFdffRU7duyQU84MGDAAI0eOxIEDB8o9ftOmTRg/fjwmTZqEXbt2YdSoUXJhtnEi76a/eFGuVeFhln3mbf2lS04rFxGRvXlEAHjDDTfITOPNmzdHixYtMGfOHAQGBmLLli3lHv/2229j6NChePzxx9G6dWu89NJL6NKlC957771aLzsRuY6itEtX1ACqQkPlWm+nWRKIiFyBRwSAJen1ejn5dE5OjmwKLs/mzZsxaNCgUvuGDBki9xOR99JfNAWAqvBwyz4GgOSpFApFpcvzzz9v8zVFy9tNN92Exo0by2u89dZbVZ6zbt06eWzJ6eCSkpJk96w+ffogIyPD5nKQF+UB3Ldvnwz48vPzZe2fmEOwTZs25R577tw51K1bt9Q+8Vjsr4yY11AsZpmZmXYqPRG5VA1gxOUA0K9tW9R56CH4NGvqxJIR2V9ycrJl+4cffsDs2bPlHL5m4rPUVrm5uWjatKmcD3j69OnVKteJEydw3XXXyc9w0V/fz8+vWtchLwkAW7Zsid27d8tvCj/99BMmTpyI9evXVxgEVsfcuXPxwgsv2O16ROSiNYBhlwNAn+bNEdm8uRNLReQY0dHRlu2QkBBZC1dyX3V0795dLsKTTz5p8/l79+6VLXKiL/+XX34JtdpjwhSX4zH/s1qtFnFxcXK7a9eu2LZtm+zr99FHH11xrPgFT0lJKbVPPK7qF3/WrFmYMWNGqRrA2NhYu90DETlX7MIPUXThArRNmji7KOTujEagMNc5r63xF+27drtcVTWBt99+OxYuXFjj1xEDNG+77Ta5vPvuuzIgJcfxmACwLIPBUKq5tiTRVLxmzRpMmzbNsu/PP/+ssM+gmY+Pj1yIyDP5tm59xT6jwQDdyZOyD6Bfp05QsEaCrCGCv1fqO+e1n0oCtAF2u5xoXauMSL9mD6NHj8a4ceM4ILOWeMQ7maiZGzZsGBo2bIisrCx8++23slPp6tWr5fN33nknYmJiZBOu8Oijj6Jv375YsGABRowYIQeNiPQxH3/8sZPvhIhcjtGIkzfcKNfN//3HkhiayFuYW9ccTaRvE/33//33X1x77bW18prezCMCwNTUVBnkiQ6toh+DSAotgj/RiVRISEiAUnl5wHPv3r1lkPjMM8/gqaeekuljli9fjnbt2jnxLojImUSi54xffoE6qi5Cbrjesl+hUkEVHAx9RoasBWQASFY3w4qaOGe9th3VVhOw6LL1xBNPyAodMTmDGAFMjuMRAeBnn31W6fOiNrAsMUJJLEREgu70aTkNnLZx41IBoDkVjDkAJLKK6L9mx2ZYZ6qtJmDR50+0xIkKG5Hbd8WKFbK1jhzDIwJAIqKa0hendVKGXPlhJnMBxsejiAEgeSFbmoB1Oh0OHjxo2T579qwMIEUtojXXEUGgqE1UqVSWILBfv341Kj95SSJoIqLq0GeYAkBVcMgVzzEZNJF1RALnzp07y0V0y3r99dfl9uTJk62+hggC33//fdx9992yn/7atWsdWmZvxQCQiEjWAJpmGxD9/coy1woamPydPNRdd91VaiaO6hIzgBiNxiuW8rpimYkaPnFMaPEXLXMQKEYDi1m9+vfvX+Ny0ZUYABIRlQjuVOU1AQcGybU+K6vWy0VE5AjsA0hEVKIJWFlODWBg3z5QRYTDv5tphgMiInfHAJCIqMQgkPL6AAb27SsXIiJPwQCQiAhAnQemImTkSGgbN3J2UYiIHI4BIBGRmOqxSRO5lMeQm4vCs2dlR3XfFi1qvWxERPbGQSBERFXI3bFTTgeX9MRMZxeFiMguWANIRAQg7fvvAZUKwUOGXJEKRhVkmgrLwFHAROQhGAASEQFIeW0+jLm5COjZ84oAUBnENDBE5FnYBExEXs+o18vgT1CWM/G9OQA0ZGfLfoBERO6OASAReT0xyMNMGRBwxfOq4gAQBgMMOZePJSJyVwwAicjriZo9QaHRQKnVXvG8wtcXUJt6zBiy2QxMnkFMt1bZ8vzzz9t8zaVLl6Jbt25yWreAgAB06tQJX3/9daXnLFq0qNQ0cMKhQ4cQGxuLsWPHQqfT2VwOqhr7ABKR1zMHgOU1/wriw1DUAurT0kwDQaKja7mERPaXnJxs2f7hhx8we/ZsHDlyxLIvsIK/h8qEh4fj6aefRqtWraDVavHbb7/h7rvvRlRUFIYMGWLVNbZt24Zhw4Zh9OjR+Oijj6BUsq7KERgAEpHX05sDwHKaf83CJ94JY5EeynJmCiFyR9ElvsiEhITILzol91VHv379Sj1+9NFH8eWXX2LDhg1WBYB///03Ro4ciQceeADz5s2rUVmocgwAicjrGbJzKq0BFOrcf38tlojcnRgslFeU55TX9lP7yWDOXqqqCbz99tuxcOHCcv8PREAnahWtCeaWLVuGCRMmyKbnmTOZc9PRGAASkdfzbdcWsZ9+CkVxPz+imhLBX49vezjltf+b8B/8Nf52u97u3bsrfT64TNqkjIwMxMTEoKCgACqVCh988AGuu+66Sq+RnZ0t+/s99dRTDP5qCd/tiMjrqcPCEHjN1ZUeU5SWhqLz5+Wx6sjIWisbkbPFxcXZdHxQUJAMGkVQt2bNGsyYMQNNmza9onm4JD8/P1xzzTX45JNPMH78eLRu3doOJafKMAAkIrJC6mvzkbFsGSJnzECde6c4uzjk4kQzrKiJc9Zr25OtTcBi0IY5aBSjgMWI3rlz51YaAIqawuXLl2PMmDHo378/1q5dyyDQwRgAEpHXy9uzBwXHjsGnZSv4tW9X7jFKTgdHNhB98OzZDOtMtjYBl2UwGGRzcFV8fHxkGpmbb75ZBoGi/2CbNm1sLi9ZhwEgEXm9zNV/4NLnnyP8nnsqDABVQaYPOX1WZi2Xjsh9moBFTZ/IA9isWTMZ9K1cuVLmAfzwww+tOl8EgUuWLJH9Ac1BYNu2bWtQeqoIA0Ai8nqX8wBWnAbmcg2g6VgiulJOTo5M4XLmzBnZr0/kA/zmm28wbtw4q68h8gf+9NNPuOWWWyxBYLt25X8xo+pjdkUi8nrmAFBVSR5A83Rwes4EQh7orrvuQnp6eo2v8/LLL+PYsWPIy8vDpUuXsGnTpiqDv/JeW6PRyLQwqampDP4chAEgEXk9Q07VeQCVgaYA0JDJAJCI3B8DQCLyevoc80wgFQeAKnMTcHFtIRGRO2MfQCLyetbMBKKJjUX4XXdBU79eLZaMiMgxGAASkdezNAEHVJy2Qxsbi7pPcoYCIvIMDACJyOvVe+kl6NPT4NOkibOLQkRUKxgAEpHXC+hZ9ZytYmL7opQUWVuobdwYCpWqVspGROQIDACJiKxhNOJ4v/5ys/mmjVCHhzu7RERE1cZRwETk1Qx5eUhfsgSZq1ZXepxCqYTC39RHkCOBicjdsQaQiLxa0YULSH76GSj8/BA8dEilx4pE0UW5uZZBI0RE7oo1gETk1ayZBs5MWTxTCGsAicjdMQAkIq92eRq4inMAlg0A9awBJA8hpmFTKBR49dVXS+1fvny53F8TixYtktcQi0qlQlhYGHr06IEXX3wRGRkZ5ZbDvERERGDo0KHYu3dvqeNKHmNerrnmmhqV01sxACQir6a31ABaEQAWH2NOHE3kCXx9fTFv3jykpaXZ/drBwcFITk7GmTNn5LzA9957L7766it06tQJSUlJpY4VAZ84Vixr1qyBWq3G9ddff8U1v/jiC8txYvnll1/sXm5vwACQiLyaISfX+gDQ3ATMGkDyIIMGDUJ0dDTmzp1b6XFLlixB27Zt4ePjg8aNG2PBggVVXlvU0Ilr16tXD61bt8akSZNkIJidnY0nnnii1LHiuuJYsYgA8cknn0RiYiLOnz9f6rjQ0FDLcWIJ54j8auEgECLyapY+gMXBXWUC+/eDNrYBfJrH1ULJyBMYck1fMMqlUkHp42PdsUollL6+VR6rLB6pbgvRPPvKK69gwoQJeOSRR9CgQYMrjtmxYwduueUWPP/88xg3bpwM4h544AHZVCuab20RFRWF2267DZ9//jn0er18/bJEgPjNN98gLi5OvgbZHwNAIvJqhpziPoBWDAIJGzu2FkpEnuRIl64VPhfQtw8afvSR5fHRq6+BMS+v3GP9u3dHo6+/sjw+PnAQ9OU02bY+fKha5Rw9erSsdXvuuefw2WefXfH8G2+8gYEDB+LZZ5+Vj1u0aIGDBw9i/vz5NgeAQqtWrZCVlYWLFy/KgFD47bffEFhcE5+TkyNrDcU+pbJ0Y+X48eNLBY0iUBw1apTNZfB2DACJyKsFDhgATf36UNeNdnZRiJxK9AMcMGAA/ve//13x3KFDhzBy5MhS+66++mq89dZbFdbiVTWzjlByoEn//v3x4Ycfym3RH/GDDz7AsGHDsHXrVjRq1Mhy3Jtvvimbrc1EoEi2YwBIRF5NzP9r7RzAhoICWesipoFTR0Y6vGzk/lru3FHxk2WCphYbN1R8bJlasLg1f8He+vTpgyFDhmDWrFnVqtWzhQgoxQCRks27AQEBssnX7NNPP0VISAg++eQTvPzyy5b9ot9fyeOoehgAEhFZKf3HxUiZMwdBw4aiwZtvOrs45AZs6ZPnqGNtIdLBiKbgli1bltovBnBs3Lix1D7xWDQF21r7l5qaim+//VY225Zt3i1J1A6K5/MqaBanmvGIUcBi5FL37t0RFBQk+xKIX6ojR45YnZ/IvIih8ETkXXK2/CengSssk5KiPBwFTJ6uffv2coDGO++8U2r/Y489JlOzvPTSSzh69Ci+/PJLvPfee+U2F5dt6j137pxM1yJq/cTAj969e8uavbK5BwsKCuSxYhHHPvzww3IwyA033OCQe/V2HhEArl+/Hg8++CC2bNmCP//8E4WFhRg8eLDsRGpNfiLzEh8fX2tlJiLXcPGTT3B22jTkbttmw0wgDADJc4lEzQaDodS+Ll264Mcff8T333+Pdu3aYfbs2fK4qpqKMzMzZR+9mJgY9OrVCx999BEmTpyIXbt2XdF3b9WqVXKfWETC6G3btmHx4sXo16+fQ+7T23lEE7D4pSlbuydqAsWwddGnoar8RETkvQw2JYJmDSB5FvF5WZbI8Sdq48q66aab5GItERxa25dQlKO8slQ0eIRqziNqAMsyTzFTVXJIUbUsRhbFxsbK0U0HDhyo9HjxByG+zZRciMi9GXJzrM4DqOJcwETkITwuABTV1tOmTZPD00U1dUVEB1fRF+Hnn3+WOYTEeaJfgpiuprK+hqLfgnkRgSMRuTd9cXOu0oa5gFkDSETuzuMCQNEXcP/+/bKfQmVEX4Q777xTjnbq27cvli5disjISNk/oSJiaLyoXTQvYooaIvKemUDMzcR6BoBE5OY8og+g2UMPPSSzhv/zzz/lTmVTGY1Gg86dO+P48eMVHiPmKRQLEXkG0Z/IXJtn7t9XGVVwMEJuGiODRaNeL/MBEhG5I7WnvImL4eLLli3DunXr0MTKpK4liUzm+/btw/Dhwx1SRiJyPXLareLRjiprBoEEBKD+nDm1UDIiIsdSe0qzr0gqKfrziVyAIoeQIPrp+fn5yW3R3CuGoYt+fIIYvt6zZ0+ZTTw9PV3OZyjSwEyePNmp90JEtUitRswbC6DPzoai+L2CqLrKpk4h5+LPwwsCQPPcgWVzBX3xxReWIegJCQmlMo6LeQanTJkig8WwsDB07doVmzZtQps2bWq59ETkLEqtFsE21vqLJmMxcEQVGgIlu4QQAK1WKz9fkpKSZF9y8bjkHLdU+62COp0O58+flz8X8fOgKymMTKpTbSINjKhlFANCRFJpIvJ8J4YMhS4+Ho2++Rr+3bo5uzjkIkTAISYUyM3NdXZRqJi/v79MKl1eAJjJz2/PqAEkIqqOwpRU5O3eDXVUJPw7d7bqHMtIYOYCpBJEkNGwYUMUFRXJPuXkXGJ+YrVazZrYSjAAJCKvlb9vL84++ij8OnVC4++/s+oc5gKkiohgQ2SUEAuRq/O4PIBERNaypICxIgegGQNAIvIEDACJyGvpbZgH2Mx8rKF4BhEiInfEAJCIvJY5iLMmCbSZMsDfdC5rAInIjTEAJCJ4+zRw1iSBNjMfaz6XiMgdMQAkIq91uQ+g9QGgb/sOCBk9Gr4d2juwZEREjsVRwETktQw52TYPAgkeMlguRETujAEgEXmt0LFj4delK/w6dnB2UYiIahUDQCLyWmImD1tn8xCTJxnz8mAoKIA6LMxhZSMiciT2ASQiskHOxk040qUrEu6629lFISKqNtYAEpHXyt6wEQqlAr4dOkJlZSoY83FMA0NE7ow1gETktZJmPYmEeyahMDHB9plAmAaGiNwYA0Ai8lqXE0FXYyYQ1gASkRtjAEhEXsmo18vBHDYHgMU1gMbCQhh0OoeVj4jIkRgAEpFXKlmDZ0sewJLHshaQiNwVA0Ai8krmPnwKjQZKrdbq8xQqFRR+fqZrMAAkIjfFUcBE5N3TwNnQ/GsWPHwYoDfI4JGIyB0xACQir6QvrgGsTgBYf84cB5SIiKj2MAAkIq+kiYlB9PPPQ2FD8y8RkadwegCYkJCA+Ph45ObmIjIyEm3btoWPj4+zi0VEHk4TFYWwW8dV61w5HVx+PqBS2dR/kIjIqweBnD59GjNnzkSjRo3QpEkT9O3bF8OGDUO3bt0QEhKC6667DosXL4bBYHBG8YiIKnXmoYdxpHMXZCxf7uyiEBG5RwD4yCOPoGPHjjh16hRefvllHDx4EBkZGdDpdDh37hxWrlyJa665BrNnz0aHDh2wbdu22i4iEXkBXUICcjZvhi4+3uZzlZZRwLkOKBkRkQc2AQcEBODkyZOIiIi44rmoqCgMGDBALs899xxWrVqFxMREdO/evbaLSUQeLuPXX3Hh3fcQesstqPfiCzadq+R8wETk5mo9AJw7d67Vxw4dOtShZSEi71WdaeDMOB8wEbk7pyaCzsvLk4M/zMRgkLfeegurV692ZrGIyKvyAFo/C4iZivMBE5Gbc2oAOHLkSHz11VdyOz09HT169MCCBQswatQofPjhh84sGhF5OHPtncqGaeCuqAHMYQ0gEbknpwaAO3fuxLXXXiu3f/rpJ9StW1fWAoqg8J133nFm0YjIw+mLg7fqNQGbztGzBpCI3JRT8wCK5t+goCC5/ccff2DMmDFQKpXo2bOnDASJiBzeB7A4mLOFtlFDBF03CL5t2zmgZEREHh4AxsXFYfny5Rg9erTs9zd9+nS5PzU1FcHBwc4sGhF5uJrMBezfrZtciIjclVMDQJHrb8KECTLwGzhwIHr16mWpDezcubMzi0ZEHi5i8mQUpZyDT9Mmzi4KEVGtUxjFnEZOJJI/Jycny+TQovlX2Lp1q5wRpGXLlnBlmZmZspwikTVrLIm8i5wOrqAASl9fZxeFiGyUyc9v5w4Cueeee2RiaFHbZw7+BDEf8Lx585xZNCKiChUmJ+Nw+w442v0qZxeFiMj9AsAvv/xS5gIsS+wzp4chIrI3Y1ERcrZsQd6+/TBWY85xmQamqAjGwkIYdDqHlJGIyOP6AIqqV9l8YjQiKysLviWaUPR6vZwPWEwLR0TkCPqMDCTcdbfcbnXwQLXzAJrzCSrDw+1aPiIijwwAQ0NDoVAo5NKiRYsrnhf7X3jBtrk5iYhsTQItAjlFie4n1lKoVFD6+8OQmwtDVhbAAJCI3IxTAsC1a9fK2r8BAwZgyZIlCC/x5qnVatGoUSPUr1/fGUUjIi+gNweAxXlIq0OkjxEBoPlaRETuxCkBYN++feX61KlTaNiwoazxIyKqLYYs8ywgtk8DZybzB6amWhJKExG5k1oPAPfu3Yt27drJUb9i+PW+ffsqPLZDhw61WjYi8g7mOXxV1ZgFxMycQJrzARORO6r1ALBTp04y958Y5CG2Re1feakIxX4xIISIyGF9AKsxC4iZf/duUEdFQhUaaseSERF5aAAomn0jIyMt20REtU2fVfM+gHUff9yOJSIi8vAAUAzwKG+biKi2+HXuhMjHZkDL9yAi8lJOnQtYOHbsmBwVnCo6U5dJyCrmCrbG3LlzsXTpUhw+fBh+fn7o3bu3nEmkqqnkFi9ejGeffRanT59G8+bN5TnDhw+v0f0Qkevza9tWLjUlu6/o9VConf5WSkTkPjOBfPLJJ2jdurUM9H766ScsW7bMsixfvtzq66xfvx4PPvggtmzZgj///BOFhYUYPHgwcnIqHp23adMmjB8/HpMmTcKuXbswatQouezfv99Od0dEnuzCx5/gcIeOSHnlFWcXhYjIZgpjeSMwaoloAn7ggQcwc+ZMu173/PnzcpCJCAz79OlT7jHjxo2TAeJvv/1m2dezZ085MGXhwoVWvQ4nkyZyTwXHj8OQXwBtg5hqD+K4+MUipM6bh+AbbkDM/NfsXkYicpxMfn47twYwLS0NY8eOtft1xQ9UKJlguqzNmzdj0KBBpfYNGTJE7q9IQUGB/KUpuRCR+0l9fQFO33wzsv76q9rXMOcQNI8oJiJyJ04NAEXw98cff9j1mqIf4bRp03D11VfLfIMVEalo6tatW2qfeCz2V9bXUHxjMC+xsbF2LTsR1Q59dlaN08CozHkAGQASkRtyas/luLg4OQhD9N1r3749NBpNqecfeeQRm68p+gKKfnwbNmyAvc2aNQszZsywPBY1gAwCidyPefYOZY0SQZtSyOiZCJqI3JBTA8CPP/4YgYGBsq+eWMomgrY1AHzooYdkn75//vkHDRo0qPTY6OhopKSklNonHov9FfHx8ZELEXlKIuiAmjcBF+cUJCJyJ04NAO2VCFqMY3n44Yfl6OF169ahSZMmVZ7Tq1cvrFmzRjYXm4kRxGI/EXlHAKiqQSJoNgETkTvziORVotn322+/xc8//4ygoCBLPz7RT0/kBRTuvPNOxMTEyH58wqOPPoq+fftiwYIFGDFiBL7//nts375d1koSkecSXxj1xSmiatQHMDQU/j16QBUWZsfSERF5QQB4zz33VPr8559/btV1PvzwQ7nu169fqf1ffPEF7rrrLrmdkJAApfLymBeRLFoEjc888wyeeuopmQha5B6sbOAIEbk/o04HFBbWOABUR0ai0ZeL7FgyIiIvCQBFGpiSRAJnMYAjPT0dAwYMsPo61qQyFE3D5Y1CdkQaGiJybWIaONF3T+nv7+yiEBF5XwAo+uyVl8Zl6tSpaNasmVPKRESeTenjgzpTptjteuYvoGLgGhGRu3BqHsDyiGZakWrlzTffdHZRiIgqdfLGkXI6uPwDB51dFCIi9w4AhRMnTqCoqMjZxSAiD6TPyEDe/gMoTEqq8bWMer3sT8iRwETkbpzaBFwyqbK5KSU5ORkrVqzAxIkTnVYuIvJcudu24cxDD8OvY0c0/uH7Gl3LkgqGyaCJyM04NQDctWvXFc2/kZGRMjVLVSOEiYiqQ29OAl2DHIBm5lHErAEkInfj1ABw7dq1znx5IvJC5pk7apICxsx8DXNQSUTkLlyyDyARkaOYm2trMg2cGaeDIyJ3xQCQiLxzGriAmtcAqgJNzcjsA0hE7oYBIBF5FX2W/foAaps2hf9VV0ETE2OHkhER1R6PmAuYiMjWGkB7NAGHjbtFLkRE7oYBIBF5laDrBskaO78OHZ1dFCIip3HJAHD79u3Izc1Fnz59nF0UIvIwwUOHyoWIyJu5ZB/AO+64A/3793d2MYiIKpW7cyeO9uqNU2NucnZRiIjcvwZwzZo1KCwsdHYxiMgD5R85AqWfHzT16kGh0dToWgqNFvq0NCh8fe1WPiIirw0A69ev7+wiEJGHih8/AYbcXDT7YzW0DRvW6Fqq4OI0MJmZdiodEZGXBIB6vR7Lli3DoUOH5OPWrVtj1KhRUKudXjQi8jDGwkIZ/NltKrjgYLk25OTAWFQEBd+3iMhNOPXd6sCBA7jxxhtx7tw5tGzZUu6bN2+enA/4119/Rbt27ZxZPCLyMCWnbFPZIQBUlZhOTp+VBXVYWI2vSUTk8YNAJk+ejLZt2+LMmTPYuXOnXBITE9GhQwfce++9ziwaEXkgc1OtMiDALrV1og+h0t/fdO2srBpfj4jIK2oAd+/eLVO+hJX41iy258yZg+7duzuzaETkgfSZWaWabu1BXEs0K5uvTUTkDpxaA9iiRQukpKRcsT81NRVxcXFOKRMReS59Zobdmn/N/Dp2lNPBKdQqu12TiMjjagAzS4yWmzt3Lh555BE8//zz6Nmzp9y3ZcsWvPjii7IvIBGRPZmbaZXFo3ftocHbb9ntWkREtUVhNBqNtfZq4o1XqYRCobA8Nr+8eV/Jx2KEsCsTwWxISAgyMjIQbMcmJSJyjPzDh5G5YiU09eshbPx4ZxeHiJwkk5/ftV8DuHbt2tp+SSIiybdVK7kQEXm7Wg8A+/btK9dFRUV45ZVXcM8996BBgwa1XQwiIrs4/8EHSPv6G4RNmIDIhx9ydnGIiFx7EIhI9Dx//nwZCBIR1YbC5GToEhIsyaDtoqhITgenT7tkv2sSEXnyKOABAwZg/fr1ziwCEXmR1NcX4MTgIUhfvNhu11QGmfoPMQ0MEbkTp+YBHDZsGJ588kns27cPXbt2RUBAQKnnxSwhRET2os/KLBW02YOquAO5+dpERO7AqQHgAw88INdvvPHGFc+5wyhgInIvhgxTkKayYxoYc0oZA2sAiciNODUANBgMznx5IvIyYr5eu9cAWpqAWQNIRO7DqX0AiYhqk7mZ1p41gOZrmecZJiJyB06tARRycnLkQJCEhATodLpSz4lZQoiI7MXcTGvXGsDwcPi0bg11nTp2uyYRkUcHgLt27cLw4cORm5srA8Hw8HBcuHAB/v7+iIqKYgBIRHZjKCiAsaDA7jWAmuhoNF221G7XIyLy+Cbg6dOn44YbbkBaWhr8/PzkPMDx8fFyRPDrr7/uzKIRkacxGBAxZQpCbx0HZWCgs0tDRORdcwGXFBoaiv/++w8tW7aU25s3b0br1q3lvokTJ+Lw4cNwZZxLkIiIyP1k8vPbuTWAGo0GSqWpCKLJV/QDFMQPJTEx0ZlFIyKyWvzEu3C099XI27fP2UUhInL9PoCdO3fGtm3b0Lx5czlH8OzZs2UfwK+//hrt2rVzZtGIyMPos7Ohv3QJqtBQS/Jmu107M1NeW5+eYdfrEhF5ZA3gK6+8gnr16sntOXPmICwsDFOnTsX58+fx8ccfO7NoRORhstetl9PAnXnoYbtfWxVkGlSiz2QASETuwak1gN26dbNsiybgVatWObM4ROTBDOYcgCH27+9jmQ2kONE0EZGrYyJoIvIKegfkALxyNhAGgETkHmo9ABw6dKhM91KVrKwszJs3D++//36tlIuIPJu5eVYVZP8UMJdnA2ETMBG5h1pvAh47dixuuukmOdJX5AAUzcD169eHr6+vzAd48OBBbNiwAStXrsSIESMwf/782i4iEXkg81RtypAQu1/bfE19BgNAInIPtR4ATpo0CbfffjsWL16MH374QQ72EHl4BIVCgTZt2mDIkCFydLDICUhEZA/69HS5FqOA7U0bEwOfVq2gjoyy+7WJiDxmEIiPj48MAsUiiAAwLy8PERERMjdgdfzzzz+ytnDHjh1ITk7GsmXLMGrUqAqPX7duHfr373/FfnFudHR0tcpARK7LnKJF7YAAMGTkSLkQEbkLp44CNhPNwWKpCTGXcMeOHXHPPfdgzJgxVp935MiRUlnAxWhkIvI8QYMHQ9u0qVyIiLydSwSA9jBs2DC52EoEfGIaOiLybOF3mFociIiIaWDQqVMnmYz6uuuuw8aNGys9tqCgQM4fWHIhIiq6eBEnhg7DsWv7wInTqxMRWc1rA0AR9C1cuBBLliyRS2xsLPr164edO3dWeM7cuXMtzdViEecQkeszFhVBl5AgR+k6IkBT+vtDd/o0is6fhyEn1+7XJyKyN4XRA7+uitHEVQ0CKY+Yj7hhw4ZyLuKKagDFYiZqAEUQKAaxlOxHSESupTApCccHDIRCo0HLvXvke4S9He7YCcaCAjT76y9oG8TY/fpEZD+ZmZmyIsebP7+dWgM4ceJEOXrXVVx11VU4fvx4paOXxS9KyYWIXJ85P59IAeOI4M987ZLpZoiIXJlTA0AReQ8aNAjNmzfHK6+8grNnzzqzONi9e7dsGiYiT80BaP8k0GYMAInInTg1AFy+fLkM+qZOnSqTQjdu3FiO5P3pp59QWFho07Wys7NlACcW4dSpU3I7ISFBPp41axbuvPNOy/FvvfUWfv75Z1njt3//fkybNg1///03HnzwQTvfJRG5TAAY4rgR/wwAicidOH0QSGRkJGbMmIE9e/bgv//+Q1xcHO644w45Pdz06dNx7Ngxq66zfft2dO7cWS6CuKbYnj17tiXBszkYFHQ6HR577DG0b99e9v0Tr//XX39h4MCBDrpTInJ2E7CSNYBERK6VB1AEaH/++adcVCoVhg8fjn379smp4V577TUZDFZGjOCtbDzLokWLSj1+4okn5EJEns+R08CZaRs3hk/r1lAGBjjsNYiIPCIAFM28v/zyC7744gv88ccf6NChg2yKnTBhgmWAhRjNK2b3qCoAJCKqiD4t3WHTwJlFTZ8mFyIid+DUAFAMuDAYDBg/fjy2bt0qkzKXJebr5UwdRFQTfp07I7QgX66JiMjJeQBFvr2xY8fC19cX7oh5hIiIiNxPJj+/nTsIZO3ateWO9s3JyZHNvkRE7iJ3506cGDIUCXzvIiI34NQA8Msvv0ReXt4V+8W+r776yillIiLPnAlETgNnMDjuRRQK6OLjoYu/nG2AiMhVqZ1V9SpansWSlZVVqglYr9dj5cqViIqKckbRiMgDnRpzkxwJ3OSXn+HbooVDXoNpYIjInTglAAwtno5JLC3KeTMW+1944QVnFI2IPIxRr7fkAVSHhzvsdcwBoCEnB0adDgqt1mGvRUTklgGg6Psnav8GDBiAJUuWILzEm7JWq0WjRo1kImgiopqSNXLFY90cmQdQJTqSi3mGjUYZcKojIx32WkREbhkAipk3zNO1NWzY0GGTsxMRFV28aAn+FGrHveUpVCoZBIrgTwSdDACJyJXVegC4d+9etGvXDkqlUg6/FrN9VEQkhiYiqgn9pTS5Vjmw+ddMBJnmAJCIyJXVegAokj2fO3dODvIQ26L2r7xUhGK/GBBCRFQT+rRLDu//Z+bTojkU/v6A0unTrBMRuVYAKJp9I4ubRsQ2EZEjFV26VGs1gA3efdfhr0FE5JYBoBjgUd42EZEj+DSLQ+it4+Dbpo2zi0JE5DKcngh6xYoVlsdPPPGETBHTu3dvxMfHO7NoROQhAnr2QL3nn0fYLbc4uyhERC7DqQHgK6+8Aj8/P7m9efNmvPfee3jttddQp04dTJ8+3ZlFIyKyWeaqVXI6uKSnn3Z2UYiIXC8NjFliYiLi4uLk9vLly3HzzTfj3nvvxdVXX41+/fo5s2hE5CEKk5Oh9PODMjgYCgcPzhBJp8V0cOq6dR36OkREbl0DGBgYiIvFObr++OMPXHfddXJbTA1X3hzBRES2Spg8BUd79kLu1m0Ofy11RIRcF10yva8REbkqp9YAioBv8uTJ6Ny5M44ePYrhw4fL/QcOHEDjxo2dWTQi8hB6yyjgMIe/lnmksf6i6TWJiFyVU2sA33//ffTq1Qvnz5+XU8JFFH973rFjB8aPH+/MohGRp8wDXJyUuTbyAJprAMVrGouKHP56RERuWQMoRvyKgR9lvfDCC04pDxF5ltqaB9hMvoboZ2gwQJ+WxungiMhlOTUAFNLT07F161akpqbCYDCUmgnkjjvucGrZiMhDmn8dPA9wqfmAw8Kgv3hRJqBmAEhErsqpAeCvv/6K2267DdnZ2QgWI/QUCstzDACJqKaKanEeYDPfli2gT88AOJUlEbkwpwaAjz32GO655x6ZD9BfzJ9JRGRHRefPy7W6Tp1ae82Gn39ea69FROSWAeDZs2fxyCOPMPgjIofQNohB2ITx0DRs6OyiEBG5FKcGgEOGDMH27dvRtGlTZxaDiDyUX6dOciEiIhcKAEeMGIHHH38cBw8eRPv27aHRaEo9f+ONNzqtbERE1ZG+fDkufPghAq+5FtHPPuPs4hARuV4AOGXKFLl+8cUXr3hODALRsxM1EdVA4dmzUAYEQBkSUmqQmUMVFaEwPgG6xom183pERO6WCFqkfaloYfBHRDWVeP/9chq4nE2bau01zalfzANQiIhckVMDwJLy8/OdXQQi8jBF5y/IdW3m47MEgKkMAInIdTk1ABS1fC+99BJiYmIQGBiIkydPyv3PPvssPvvsM2cWjYjcnFGnuzwNXG0GgFFRci2SQXM6OCJyVU4NAOfMmYNFixbhtddeg1artexv164dPv30U2cWjYjcXNHFi6YNjQaqkJBae12ZdFqlklPQWcpARORinBoAfvXVV/j444/lbCAq8YZZrGPHjjh8+LAzi0ZEnpIEOiICCjE/by0Rr2VOPF2Umlprr0tE5FaJoOPi4q7YLwaBFBYWOqVMROQZii7Ufv8/M99WrVAkXrfE/OZERK7EqQFgmzZt8O+//6JRo0al9v/000/o3Lmz08pFRO7PPAijNqeBM4v9aGGtvyYRkdsEgLNnz8bEiRNlTaCo9Vu6dCmOHDkim4Z/++03ZxaNiNycT7OmCJswAT4tWji7KERELkdhNBqNziyAqAEUiaD37NmD7OxsdOnSRQaGgwcPhqvLzMxESEgIMjIyEBwc7OziEBERkRUy+fnt/ADQnfEXiIjKk7VuHVLmzoVvq9Zo8PZbzi4OEZWRyc9v544Cbtq0KS6WkyYhPT1dPkdEVF0Fp07JPIDO+I4rRgLL6eASE2r9tYmIXD4APH36dLlTvhUUFMh+gURE1RU/4TY5DVzB0aO1/tqcDYSIXJ1TBoH88ssvlu3Vq1fLalgzERCuWbMGjRs3dkbRiMgDGAoKoE9Lk9uaunVr/fVLzQZSWAiFRlPrZSAicrkAcNSoUXKtUCjkKOCSNBqNDP4WLFjgjKIRkQcoSkmRa4WvL5S1OAuImSosTM5AgsJCmZBaU79+rZeBiMjlmoBFyhexNGzYEKmpqZbHYhHNvyIVzPXXX2/TNf/55x/ccMMNqF+/vgwsly9fXuU569atk6OOfXx8ZEJqMS0dEbm/wnPn5FoTHS3fD5zRB9Bc82guCxGRK3FqH8BTp06hjp2StObk5Mgp5N5//32rX3vEiBHo378/du/ejWnTpmHy5MmySZqIPKMGUB0d7bQyiOBTKExKdloZiIhcMhG0IPr7icVcE1jS559/bvV1hg0bJhdrLVy4EE2aNLE0Nbdu3RobNmzAm2++iSFDhthwB0TkagqTzzmt/5+ZT6tWMOTnQ+GjdVoZiIhcMgB84YUXZBLobt26oV69erXaVLN582YMGjSo1D4R+ImaQCJyb0XFza7OrAGMfuZpp702EZFLB4CiFk70u7vjjjtq/bXPnTuHumVqB8RjkRwyLy8Pfn5+V5wj+ieKxUwcS0Sux79nD9O6W1dnF4WIyCU5NQDU6XTo3bs33MXcuXNlrSURubbgwYPl4gpEImpnDEQhInLZQSBi0MW3337rlNeOjo5GSnFHcTPxWEwJU17tnzBr1iw5bYx5SUxMrKXSEpG70Z05g+NDhuB4337OLgoRkWvVAObn5+Pjjz/GX3/9hQ4dOsgcgCW98cYbDnvtXr16YeXKlaX2/fnnn3J/RUS6GLEQkesSiZcLjh2DpkEDqJw4x6cqJEROBycYcnOh9Pd3WlmIiFwqANy7dy86deokt/fv31/qOVubTLKzs3H8+PFSaV5Eepfw8HCZb1DU3onp5b766iv5/P3334/33nsPTzzxBO655x78/fff+PHHH7FixQq73BsROYcu8QxOjblJBlwtdmx3WvOrKigIyoAAGHJyZC5AH85vTkQuxKkB4Nq1a+12re3bt8ucfmYzZsyQazHTiBhokpycjISEyxOzixQwItibPn063n77bTRo0ACffvopU8AQubnCs2fkWtQAOrvvnaZ+PRQcO47C5GQGgETkUpyeB9Be+vXrJztbV6S8WT7EObt27XJwyYioNhWeKQ4AY2KcXRSoo00BYFEyk0ETkWtxSgA4ZswYq45bunSpw8tCRJ6l8OxZSw2gs2liTHMA64rLRETk1QFgiBMmZyci76A7c7ZU8OVM2thYuS5MNNVKEhF5dQD4xRdfOONlicibagBdoAlY26wZfNu1gybW+bWRREQe2QeQiKhkH0CtCzQBB/XrJxciIlfDAJCIPIYYCBYxeZKsBdQUN78SEdGVGAASkccQaV8iJk2CqzEaDIDBAIWab7lE5BqcOhUcEZGnO/PoNBzp2AnZ69Y5uyhERBb8OkpEHkN3+jQMeXnQNmrkMlOvKVRKOT2dmKGEiMhVsAaQiDzGxS+/xKnRY3Bh4UdwFZoG5lQwic4uChGRBQNAIvIYhfHxci1qAF2FOQWM7gwDQCJyHQwAichj6E4XB4BNGtvlegcuHMDW5K0wGA3VvoY2tqGpbMXBKRGRK2AfQCLyCIaCAhQWz7lrjxrAD3d/iA/2fCC3+8X2w1v93oJKqbL5OtomTeS68MxZGHU6KLTaGpeNiKimWANIRB6hMCFBJAKEMigIqvDwGl3r0MVD+HDPh5bH6xLXYcmxJdW6ljoq0jQgRa+Hjv0AichFMAAkIo9gbmIVtX8iH2BNfHPoGxhhxJDGQzCz+0y5b9GBRdAb9DZfS5QlcMAABA0dWqMyERHZE5uAichjUsAI2sY16/+XUZCBVadWye072tyB5qHNZW1gYlYi/jnzD/o37G/zNWNen1+jMhER2RtrAInII/j36oWo/z2G4OHDanSdf8/+C51Bh7jQOHSo0wH+Gn+Mihsln/v99O92Ki0RkXMxACQij+DXti0iJk9G0IABNbrOv2f+tQz8MDclD248WK5FDaBOr6v2dHBFFy7UqGxERPbCAJCIqJjo47cxaaPcvjbmWsv+9nXaI8o/CjmFOdiSvMXm6xacPIUjXbri5Ijr7VpeIqLqYgBIRG5Pn5mJzFWrUHDiRI2ucyz9mOwDGKAJQIfIDpb9SoUSfRr0kdvVCQA19aJhzM+HPiMDRZcu1aiMRET2wACQiNxe3r59ODttOs48+FCNrrMrdZdcd4zsCLWy9Bi5HtE95Pq/5P9svq7Szw+aBqYZQQqOHa9RGYmI7IEBIBG5Pd1xU1Dl0zzOLgFgp6hOVzzXPbq7XB9NO4pL+bbX4vm0aCHXBUeP1qiMRET2wACQiNxewXFT0682rmYB4O7U3XLdOarzFc9F+EWgeVhzub313Fabr+3TwnQuA0AicgUMAInI7RWYawBrEACKWr3knGQooJCDPspjbgYW8wPbypc1gETkQhgAEpFbMxqNJQJAUy1bdRy5dESuGwY3lINAymNuBjY3FVerCfjYMZkShojImTgTCBG5taLkZBiysgC1GtomjWscALYIMwVq5RGDQ4Tj6ceRqctEsDbY6uuLGUqCrhsEbbNmMOp0UPj6VrusREQ1xQCQiNxa/sGDluZfpVZb7escTjss163CW1V4jOgH2Ci4EeIz47EndQ+ubXA5V2BVFGo1Grz7brXLR0RkTwwAicit+XXtiph33q7xdcw1gJUFgOZaQBEA7j6/26YAkIjIlbAPIBG5NXVYGIIHD5ZLdRXoC3Aq41SVTcAlU8SIGsDqKExJlXkLiYiciQEgEXk90adPb9Qj1CcUdf3rVnpsp0hTALj3wl4UGYpsep3cHTtwvG9fnHnk0RqVl4iophgAEpHb0qen48LChcj+558aXefoJVNqlpbhLaFQKCo9tlloMwRpgpBXlCeTQtvCp2VLQKGQA1eKLl6sUZmJiGqCASARua28/Qdw/q23kTLnlRpd5/Al0wCQlmEtqzxWzAvcIapDqcTR1lIFBsrRwEL+gQPVKisRkT0wACQit5W/f79c+7ZtY5cAsKoBIGWbgcVAEFv5tmsn1wwAiciZGAASkdvK22MaiOHX0ZSfr7qJpM1NuaIJ2BrmqeKqMxDEr11bS+0lEZGzMAAkIrckAre83btrHACezT6L7MJsaJQaNAlpYtU5Yqo40RSclJOElJyUatUA5u3dI++BiMgZGAASkVsqTEyEPi0NCo0GPm3a1Dj/X1xonAwCreGv8bf0F9x13rZp4XzbtgU0GujPX0DhmTPVKDERUc0xACQit27+9WnT2i4zgFSV/6+ifIC2DgRR+voi8pGHUX/+a1CFhtp0LhGRvTAAJCK3ZE6m7N/JFIg5egaQsrrU7SLXO1N22vyadaZMQcgNN0AVFGTzuURE9sCp4IjILdWdOROhN90ka9TsEQBaOwDErEuUKQA8knYE2bpsBGoDa1QOIqLaxBpAInJLCpUKvi1bQtuoUbWvkVGQIQdyVKcJOMo/Cg0CG8BgNGDP+T3VasK++NnnMpk1EVFtYwBIRF7LnP6lfkB9hPiE2Hy+uRl4R8oOm89NeupppM6fj9ydtg0iISKyBwaAROR2Lnz0MZJmzkTuTtv739mj+bdsM/CuVNuDOP8uplyCuTu2V+u1iYhqggEgEbmdzNWrkPHzLyhMTrbPFHDVDAA71zUFcfsu7INOr7PpXP/u3eU6d/OWar02EVFNeFQA+P7776Nx48bw9fVFjx49sHXr1gqPXbRokZz0veQiziMi1yb6zBUcOlwqiKqtKeDKahLcBOG+4SjQF+DgxYM2nRvQu7dc5x88iKKLF6v1+kRE8PYA8IcffsCMGTPw3HPPYefOnejYsSOGDBmC1NTUCs8JDg5GcnKyZYmPj6/VMhOR7XI2bxbTgEDbrBk0UVHVvk6hvhAnMk7UKAAUXxzN08LtTLWtOVpdpw58WreW2zmbNlXr9YmI4O0B4BtvvIEpU6bg7rvvRps2bbBw4UL4+/vj888/r/TNOzo62rLUrVu3VstMRLbL/udfuQ689toaXed4+nEUGYoQrA2Wg0CqyxwAbju3zeZzA6821QLmbNhQ7dcnIvLaAFCn02HHjh0YNGiQZZ9SqZSPN4vaggpkZ2ejUaNGiI2NxciRI3HgACdnJ3JlYu7c7A3FAWCfa+3W/Cu+DFZXz3o9LSOBRa2iLQKuuUauc4vnNCYiqi0eEQBeuHABer3+iho88fjcuXPlntOyZUtZO/jzzz/jm2++gcFgQO/evXGmkrk5CwoKkJmZWWohotpTcOSInENX4ecHv27dnDoAxKx5WHPZDzCvKM/mfIB+Xbqg4Vdfotmvv9aoDEREXhkAVkevXr1w5513olOnTujbty+WLl2KyMhIfPTRRxWeM3fuXISEhFgWUXNIRLXHkJMj+80F9OhRo/l/SwaArcNN/fCqS6lQoke9HnJ7S7JtI3rFPQRcdRUUNbwXIiKvDADr1KkDlUqFlJSUUvvFY9G3zxoajQadO3fG8ePHKzxm1qxZyMjIsCyJiYk1LjsRWc+/a1c0XbYUMW+9WaPriNk7xBRu9qgBFHrV6yXXm5Mr7nJiTfM2EVFt8YgAUKvVomvXrlizZo1ln2jSFY9FTZ81RBPyvn37UK9evQqP8fHxkSOHSy5EVPtqOv/vmawzyCnMgVapRZOQJjUuj7kf4P4L+5Gly7I58EuZPx8nBg6CrpIuKERE9uQRAaAgUsB88skn+PLLL3Ho0CFMnToVOTk5clSwIJp7RQ2e2Ysvvog//vgDJ0+elGljbr/9dpkGZvLkyU68CyKqSMGpU7IJ2B4OXTok13FhcdAoNTW+Xr3Aemgc3FjWLG49V3H+0fKIASj5+w+gMCkJWav/qHFZiIi8KgAcN24cXn/9dcyePVv269u9ezdWrVplGRiSkJAgc/2ZpaWlybQxrVu3xvDhw+WAjk2bNskUMkTkepKefBJHe1+N7PXra3ytAxdMI/7bRNjv771XfVNrw79nTKOUbRE0+Dq5zvqDASAR1Q6FkR1Pqk0EjWIwiOgPyOZgIscRU74d7z9AVJchbv26GiWAFu5adZdM2/Ji7xcxuvlou5RxU9Im3PfnfYjwjcDft/wtB4dYqzAlFcf79ZMJruPW/g1NJV1RiKjmMvn57Tk1gETkuTJ++dUyCKSmwZ9I/myetq1DZAfYS/e63RGoCcTF/IvYe36vTedq6kbBr2sXuZ3x6292KxMRUUUYABKRSxONFOlLl8jtkNE1r60TM4CInH0iWLPHABAzjUqDa2NMyanXJq61+fzQ4nvLWLKEI4KJyOEYABKRS8vbsQOF8QlQ+PsjeOiQGl/PXDvXrk47m5pprdG/Yf9qB4BBQ4bKe9TFxyNvp23zChMR2Upt8xlERLUofekyuQ4eNhTKgAC7BYDt67SHvV0Tcw3USjVOZZySiy01jKrAAISNHQtjURHUderYvWxERCWxBpCIXJZRp0NWcX7P0DFj7HLNfRf22b3/n1mQNsgyK8jvp363+fy6s55E9LPPQNuokd3LRkRUEgNAInJZYoq0pr/8gqjHH5fz5tZUpi4TJzNOOqwGULi+6fVy/dvJ39iXj4hcFgNAInJpYoRsxKR7ZMJkezX/xgTGIMIvAo4wIHYA/NR+SMxKxJ7ze6p1jdxdu5D8/POyOZiIyBEYABKRSzLk59v9mtvObZPr7tHd4Sj+Gn9c1+g6Sy2grQw6Hc488CDSv/8BWX9dnt6SiMieGAASkcsRTafxd05Ewj2TUHDylN2uu/3cdocHgMKIpiPketXpVSjQF9h0rlKrRdj4W+X2xc8/ZzMyETkEA0Aicjliurf8vXuRu3MnVMFBdrlmTmEODlw8YEna7Eg9onsgOiAaGQUZWH16tc3nh02YAIWvr/w/yPnnH4eUkYi8GwNAInIposbr/DvvyO2w2ybYLSXKzpSd0Bv1aBDYAPUCHTvVmkqpwriW4+T2/x36P5tr8cQ9iyBQOP/2O6wFJCK7YwBIRC4l688/UXDwEJT+/oiYPNlu1916bqtcd4vuhtpwU/OboFVq5bRz1RkMEjF5kkwMnX/wILL++sshZSQi78UAkIhchhgAcX7BG3I77M47oA4Ls9u1N5zdINe96/dGbQjzDcPwpsMttYC2UoeHI/zOO+S2+D8RORGJiOyFASARuYxLX34pp0JTRdaxa+1fUnaSnANYTP1WrQBQXwjkpYn2aZtOu631bXL9R/wfcmYQW4n/A58WLWRtINScuImI7IcBIBG5BKPBgKw//pTbUY89BlVgoN2u/e+Zf+W6U2QnhPiEWH9iUQGw+mlgXhNgXmPgzbbAxndMAaEVWoW3Qr8G/WAwGvDR3o9sLrf4P2jy83KE3nwzFEq+XROR/fAdhYhcgghwGn/7f6g/71WE3HijXa/971lTAHhtg2ttC/6+HgNsfg/QZZn2ZZ4F/nwW+Ho0kJdu1WUe6PSAXK88uRIn002zkNiiZAJsfXY2B4QQkV0wACQil6HQaBAycqRda7tE+pctyVvk9rUxNgSAvz8BxG8AfIKBcf8HzDoL3PguoA0CTv8LLBoB5F6q8jKtI1pjYMOBMMKId3e9W+37yFq3DieGDUPmr79W+xpERGYMAInIqQqTk3Hhww8dNshhfeJ6mYy5UXAjtAhrYd1J8ZuAHYtESAqMXQS0vh7wCQS63Anc8zsQWBdI2Q98dyugy63ycg91eggqhQp/JfyFTUmbqnUfBYcPQ3/+As69PEf+nxER1QQDQCJyGhH0nZ02Xea6S37hBYe8hjkR8+BGg62bT1hfBKz4n2lbBHxxA0s/H90euGM54BsCJP4HLL7LdE4l4sLiML7VeLk997+5KLSyD2HZASG+7dvDkJmJM9OmyRHTRETVxQCQiJwmZf7ryNuzB8rgYNSZOtXu18/WZVvSvwxpPMS6kw79DKQeAHxDgYHPlX9M3TbAhB8BtS9wbDWwYkaVI4RFX8AI3wiczjyNT/d/avO9KNRqxLz5BpQhIcjfsxcpc+fafA0iIjMGgETkFGnff4+0r7+W2/VffRXaBg0cUvunM+jQJKSJdc2/IogTo3yFnlOBgIiKj23YE7j5czF6Bdj5JfDP65VeOkgbhCe6PyG3P9rzEfad32fbzQDy/yjmtXliZAjSv/seaYsX23wNIiKBASAR1bqsv9fi3Isvye06Dz+EoAH9HfI6S44tkevRcaOta/6N3wgk7zbV7HW3Ig9hqxHAsNdM22tfBnZVnvB5WJNhGNZ4mJySbtaGWcgtrLr/YFmBffuizoMPyu1zz7+A3B07bL4GEREDQCKqVbnbt+PsjBmAwYCQm29CnQdMaVLs7cilI9h3YR/USjVubGZlWplNxaN0O00AAqycg/iqKcDV00zbvz4CHF9T4aEiCH2659Oo618X8ZnxeGrDUzJHoK3qPPgAQkaPRvCwYfBr397m84mIGAASUe0SKV6USgRcey3qPfecdTVz1fDjkR/lun9sf0T4VdKUa3b+CHB0lWnkb09TDZvVRF/B9rcAhiLgxzuBpN0VHioSUb/e93VolBqsSViDD3Z/YNtrFQeS9V56EfVfmweFVmvz+UREDACJqFb5d+mCRl9/hQbvviPz/jnCxbyL+PnEz3LbPPq2SiLhs7lZt06c7UHtyPeBJn0AXbYpUXQlQWCnqE54rpdpgImYIeT7w99Xa1CIOV+imEUl+bnnZa5AIiJrMAAkIoe79M3/IXfXLstjv7ZtofT1ddjr/d+h/5O5/9rXaY9udbtVfUJWCrCnOAjr/XD1XlStBcZ9A9TvAuRdAr68EUjcWuHhI+NGYkr7KXJ7zn9zsPz48uq9LoD0n35C+g8/4MyDD+HS//0fZwshoioxACQihzHk58uaqZSXX5bBSdGlqmfOqKmMggxLjdqkdpOsa2Le9gmg1wENugOxPar/4iI34J0/Aw17AQUZwFcjgYOmmsjyPNz5YdzW+ja5/ezGZ/HF/i+qFbyFjh4tZ1CBXo+Ul16Wg0OYJ5CIKsMAkIgcouD4cZy+ZZysmRIi7rkbqrAwh7/uJ3s/QVZhlkz70r+hFaOLdTnAtk8v1/7VtE+ibzBw+xKg2UBAjPIVfQLXzZODXsoSwenM7jNxR5s75OM3dryBuVvnotBgW6Jo0ZRe79W5iPrfY6YUMT/8IP/vxc+AiKg8DACJyK6Mej0uffUVTt08FgVHj0IVEYHYTz6RM1k4asCH2ZmsM/j28Ldye3rX6VCKHH1V2fkVkJcGhDUBWl1v0+vpDUbsiE/Dj9sSsWjjKSzfdRaHz2WiSOVnShTd437TgeteAb4ZA2ReOYWb+D8R+QH/1800+8h3h7/DpNWTcC7nnE1lEdcR/8exCz+UgbaYOu7UTTcjc5VpJhQiopIURnYWqbbMzEyEhIQgIyMDwcHBzi4OkdMZ8vIQf/sdyD9wQD4O6N0b9ee9CnVkpMNfW7yVTf1rKjYmbUSPej3wyXWfVB1wFumAdzoBmWeB698Eut1j9Wst330W81cdQVJG/hXPB/qo0a9lJIa0jcZ1BX/C94+ZQFEe4BcGDJkLdBhnGjhSxl/xf8mm4OzCbDla+KmrnpK5A20NnIvOn0fSrKeQs3kzmixdAt+WLW06n8jTZfLzmwFgTfAXiOhKZ594Atnr1iPqsccQOvZmy0hVR/v1xK8yr55WqcWSG5egcUjjqk/a+TXwy0NAYDTw6B5AU/XAFIPBiGd+3o9v/0uQj4N91egYG4pgXw3OZxXgQFIGcnR6y/E+aiXGN8vH9Mz5CEkzBcZocBUw/DWgfucrrp+YmYjH1j+GQ5cOycfXxFwjA8HY4Fgb/jdMI4Pzdu+Bf5fLr5G+ZCn8e/SAtkGMTdci8jSZ/PxmAFgT/AUib1d47hwufvY5wm+bAG1jU8BVlJYmByOo61iZSNkOEjITcMtvtyCnMEcOrLi3w71Vn6QvAt6/Crh0ArjuJeDqR6x6rTkrDuKTf0/JroLTBrbAfX2bwlejKhUg7j6Tjj8OpGD1gXM4dSFH7tegCFN9VuNB5VL4GPNMB7e+Eej7BBBdOplzob4Qn+3/DB/v/Vj2B1Qr1Li5xc24r+N9qONXvf/XgpOncPL66wGVCmFjb0bEffdBU7duta5F5O4y+fnNALAm+AtE3ir/4EFc/GIRMn//HSgqQvDw4Yh5Y4FTyiKmU5u4aiIOXzqMLlFd8NmQz+TsH1XasQj49VFTs+y0fYBPUJWn/HUwBZO/2i633xzXEaM7Vz5/sXh7PZCUiV/2JOHXPUlIzshHXVzCLM23GKXadPm4uMFQXDUZiBsEKC8Hk6cyTmHe1nmyWVvwU/thZLORuL3N7WgU3Ai2KDhxAilz5iBn02bTDo0GwcOGInziRJmWh8ibZPLzmwFgTfAXiLyJPjsbmStXImPJUuTt2WPZ79+9O+pMvV/296ttonbs4b8fxsazGxHmE4Yfb/gR0QHR1o38facLkH3O1CevV9XT0eXp9Oj/+jqcy8zH5Gua4Jnr29hUVlEzuD0+Db/sOYuV+86hTu4JPKRejuuVW6BUmN6GdYExUHe9A8p2NwGRLSznbk3eird2viWnthMUUKBvbF/c3Pxm9I7pLWcVsVbOlv9w/r13kbf98hzCfl26yL6a2ljbmpmJ3FUmP78ZANYEf4HIm5y4/nrojp8wPVCpEDx0KMLvvht+7ZxTeySCPzFgYsXJFfBV+cqavw6RHaw7+a/ngQ1vAqGNgIe2AWqfKk/5cN0JzFt1GDGhfljzWN9Szb42l11vwMbjF2TN4OEDuzFavxo3q/5BmCLbckxGUHOo2o1CYPvrgegOMCoU2JK8BV8f/Br/nv3Xcly4bziGNh6KwY0Ho2NkR+tqP0VAu2+/HK0tanFFUu7mG/61JOcWtYWamBiHJusmcqZMfn4zAKwJ/gKRJypMTUXu5s3IXr8e9V55xRIEnH/3PWSuWoXQMWMQcuMNtTKytyL5Rfl4fP3jWHdmHVQKFd7u/7asEbNK8l7g434iXw1w67emqd+qkJFXiGvm/Y2s/CIsGNsRN3WtvOnXFvmFeqw9nIqVu07D//hvGGr8F9co90OjuDyQJEcVgotRPeHTYiAi2w3AaY0Ki48uxspTK3Ep/3JybTFy+NqYa9GnQR90j+5uVX/BwpRUFBw9gsBrr5WPxUfCiaFDUZR6HoHXXI3AgQMReM01tdqnk8jRMvn5zQCwJvgLRJ5An5GB3B07ZcqQ3C2bUXDscvLgBh+8j6ABA+S2UcwsodE4PJdfVRKzEvHYOtMoWR+VD17v+zr6xfaz7mRdLvDpICD1ANBmJHDLV1ad9um/J/HyikNoHhWIVdP6QKV0zP+BrsiAnQlp2HroBAyHVqJdxnr0VB5EoKJ0qplsRSDOBbVFXt1OOFo3AltxFhvO70CmLrPUcY2DG6NbdDd0rdsVbSPayn6DVeVGFLO1nLr5ZhQllc5Z6NO8Ofx79kTQwIEI6FmD2VKIXEAmP78ZANYEf4HI3YggTiRqVvr5yccZK1Yg6TFTAmILhQK+rVsjoM+1srZP27AhXIF4q/r5xM94betrcqaPUJ9QvNX/LRncWHkBYPkDwJ5vgYAo4P4NQFBdq5I9i75/CZdyMXdMe4y/qvb+P9Jzddh9+jySDmyENuEfNM7chnY4AV/FlTOFZMAf64NjsSEoGAd8dEg0psOI0m/v/mp/tApvhTYRbeS6aUhTmS4nSBt0xf91waFDyPprDbLWrpXbZmETJiB69rNy25Cbi/Tly+HXvgN8W7aAQqt12P8FkT1l8vObAWBN8BeIXJXIAVd49iwKjh1DwdFjxeujKDh9GnVnzkT47ab5Z/OPHMWpkSOhbdRI1u4E9OoF/x5XQV0LU7bZ4sCFA1iwYwG2ndsmH3eK7IT5fedbN+DDbO1cYP2rgKgBE/P1Nulj1WlrDqVg0pfbZb6//54aBD9t9fv+1VSR3oDDSZeQfGQ7dPFbEXRhN+rnHUEjY3KpJmMhQ6nALh9fbPXzxQ6fABz3UUJXQcVlpF8kmoQ0kUvDoIaoH1gf9QLroX5AfRlo69PTkfvfVuT8twXB111nGfCTu327TPwtaTTwadxY1hT6tBBLC/h16MCmY3JJmfz8hnW9hYnI5Rh0OhSeOYvCxATZH8+3TRtLB/5TY26CsaCg3PMKjhy2bPvENUPzzZtcLuATxHfTXam7sOjAIqxNXCv3icEeUztNlXPnWj3yVXzHXfeqKfgThr1mdfAn/Lg9Ua5v6Rbr1OBPUKuUaBdbB+1ihwIYavl/OnsxA8kn9iEncR8U5w8hMOMYwgvOoGfuOfQT09whDUUirYxGg0M+WhzUanFEq8FpjQYX1Cqczzsvl63ntl7xmj4KDSK14Yj2j0a9vg0Q7bMdEYdOyf6FUemX4N+zK3DwGAyZmaYvGseOAStN50Y/Nxth48fL7fyjR5GxZAk0sQ2hbRgLTWwsNPXrQ+lT9QAcIrI/1gDWAL9BkCMYi4pkjYuYKkwdHm5Jrnz+jTdRmJqCopRUFKWkQC8SLhcLmzAe0bNnW9K1HO3WHQqNBtq4OPg0F0tzufg2bw51/fpO78dXGTEHrpgSbcmxJTiebuqPKPqtXd/0ejzQ6QHEBNowi0VeOrDiMWD/T6bHA54B+jxu9ekZuYXoPucv6PQGrJp2LVpFu9ffeb6uEEmJp5CedBQFqSeAS6egzj4L37xUhBSmIsJwEQalTgaCp2RAqEaCWo1ktRpJarUMDq1iNKJehgLNz6vQ+IIKsReA6At6bLyxKfJaNESIbwRa7kxB88/XXHGqMixUJqSOevxxBF59tdxXmJKCguPHoY6IgCosHOqwUDYvk11l8vObNYBEDg3ksrJgyM6GISsL+qxsqMPDZCBmHnyR8tpr0Kely2BOf+kSitLTYcjIkM+H3joO9Z5/Xm4r1GqkL158xWso/P1l7jZVRIRlnyowEM3++hOa6Gh5nqsr0BfIJl7RvCtq+g5cLJ4urTjxsZgLd2LbibK/mtXE99rDvwG/PwlknjE1+45YYPVcv2arDiTL4K9l3SC3C/4EX60GTZu1AMRSDr3egEtpF+CXkoAmFxJQ/9JZXJWVCuSchzLjEhS6i8g1piFbkY0sdT4y1EZcVKpkYHhRpcQFlVirkKNUIjkUSA7V45/mJZuijwEXj8mtZnojel+lQN10oG6aUa59CwFDWjoK0tLxyOr7cOKICr5GFa7eZ8TYVaUHvhT4KFEQoIEuwAeHh7ZATosY+GsCEJpWiIj4DKhDQqENDYNPeCT8wqMQGFUPQRHR8PcLlrXFrvylh8gZXP/TwQbvv/8+5s+fj3PnzqFjx4549913cdVVV1V4/OLFi/Hss8/i9OnTaN68OebNm4fhw4fXapnJ+UQluGguNeTlwZiXJ9fKwCBo6kbJ5/XZOcj6608Y8/NhyM2DIb/4uOLtgKuuQsjIkZYUKqdvulnWwoljygq5+SbUf/ll0wOVSiZVLpdCAUO2aQoxQRkYiMhHH4GqTh1ZW6IWS1QUVKGh5X6waRvYL02JvWftOJF+QtbsHU07iv0X9suAT+T0MxNJjjtFdZK57W5odsMVAxSqTPB88Gdg68dA0i7TvvCmwOiPgNiK3wsq8vPuJLke2bk+PJFKpURknSi5AN2q/DvJz81G1qVk5KSlIi8rDfnZ6SjKuYTcnAtIzz+PnMI05OuzkG/IQQFyUYAC5CsKkavUIyfEiP1XAxuUKmQrFchRKKDQKRGRBURkGnG0vkh3YxCdG5CkNSAhEgjOBYJyAZUR8CkwwEd0a7hUgLVZO7Hv0m5Zrv57DJi6UpxXWnbxsmC0EttaKqAxAh1OGzFsqwGFagV0GqBQq0CRGijSKuS+E001yAhXQw0VAvMUqJMOGLQqGDUaGNUqUy2kWiPXKpUWaqUGSqWmeK2WgaZKPFaZFnGMVj7WykWrFmsfaDVaaNTisY9cNBof+Kp9odH6wEfjB63GtN9H6yePr635tMm7eEwA+MMPP2DGjBlYuHAhevTogbfeegtDhgzBkSNHEBVl+iAvadOmTRg/fjzmzp2L66+/Ht9++y1GjRqFnTt3ol27dk65B08hexXo9bIGzFikB4oKofD1teSTEwFWYXIyjIVFcj5WMSrVsl1UJEediiS05qbPnI2bYCwqNF2zsMg0klVXIPvAieDLv5vpg0sMehC56uTzhTr5vNwuMK1DRo9C+G2mwQ+6+HicGntL8bV0YpqGUvcQftddqPvkTFN5szKR/OSsCu9XvDmbA0Axurbo/PnSz/v5yVo5ZVAQ1OGXa+qUAQGInDYNqrAwqMLDZD88lXkJCYFCdbn5TQR5daZOhSsTwV1aQRrS8tNkbrrU3FQkZSchKScJydnJci2ad8sT4RuBzlGdcXXM1TKli9Xz3Rr0wMUTQMIm4MRa4PgaQJdlek4TAPScClwzHfAJtPl+zmXkY/PJi3L7xo6eGQDaQvwO+gUEyQWx5dcoVqVIV4CcnCzkZWcgPycTuTnpyMpJQ1buBeQWZCC/IB25hVnIb5uNQy1zoDPkIl+fD0NeAdS5OmjyCqHJ1SMqCOiea0ChwoBgjRGHmwC+BYC2APArXkTtopDrAxgUChQogMAsI9qdEnvNPZ9K94B6I9yAPfVMJ/Y8acC45VcGlmbvj1BifQdTYNY23oApv4vAEnLRibXKFGTmqYE1HRXY18R0bN1LRgzcY4BeCRSpFChSoXjbtD7cQIHEKNOXuoA8I1qeMcKohGlRGWFUAHqV6XGWP5Dnr4S4skpvRICoNC1OUSSeF18kReW3EQooFQooxbr4S5bcNirkz9XyuHi5/Nj0SHTBMO0r3qMwreW/clsprw+5Vl0+RzxXvJZXVKiKH4sjVFAqi69YfJzlHKWq+JpK+f7apmEvXNP5+mr9zpEXBIBvvPEGpkyZgrvvvls+FoHgihUr8Pnnn+PJJ5+84vi3334bQ4cOxeOPm/oDvfTSS/jzzz/x3nvvyXOdLXfnLuRs3iRyUMBoNMi1+LAzGkzBVdhtEyzpOcTUTpkrVsAoPgzF8+I4ebxBjgaNmDLZMtdn9saNuLToS1MwZbmu6TixL3L6NAT07Gk69t8NSH1tnuU1yx4vAiQxG4Q8dv16nHl0mgzgxNywZUU//xzCbr1Vbuft3o2EuytuihN9gSImmZ4vjI9H0v/KpCkp6eGHLAGgqKnLWL68wkPF6FYLlUp2Wi9L9JsTzaoKjbpU7VvA1VdD6e8Hha+fDPKUfr4ysFP6+cO3davLxwYEoMnSJTLYE+eJwE9cszwyqLv/PtQGvUEPnUEna9p0eh2KDEVybX5cci0XfaH84M0typWBnVyKcpFTmGNZ5xXmybxz6QXpMugTx1tDBHvNw5ojLjROpiIRgV9sUGzpmkzxJaIwD8hPB/IzTH35xHZmEpCRCGScAS6dBFIOAkVlalrDGgOdbge63gUEVj9Z9W97k2QxujcOQ4Mw/2pfhy5Ta30QIpYwx40MNugN0OnykJeVibyLyXhR1EXq85Gvy4EuJBEX6p6EIddUQy++jCI/X3SWhKKgAL0iY9BS5YNCgw5RyvPIDj0Llc4AdaFBBljKEvFgU4Mf8vNVMMCAuEwd6qfpypTkcnB5tgGQ1sAA0Tje/KIRo7aUH4AKiwYqLQFgg4vAkz9VHIR+10eJZVebjm18AXjli9IjwUta0luBH/qavlSKJvi5i/QwKACDUgTIpuBTbOsVkIHtst6mgDUo14gnf9RbnhfBdMlzdjdV4PdupmN9dEbcv9Igg1SxGMqsj8YosLaj6VilwYg7/jbI1yt5vPnYM3UU2NTGdOwNlw4yAHQAjwgAdTodduzYgVmzLtfSiG8WgwYNwubNxROflyH2ixrDkkSN4fJKAoiCggK5lOxE6ggf//w0jL/9jj7/XtmEaLYw5yckNjQFFp12F2Dg3xUf+6XvP7JpQ2h7QIfhlVz3vcUP4MheU2frFkd1GHms4mM/WTkL+xKek9tNTxVirHgjrcDX61/Fjsw35Hb9JD3G+oo3E4XpTUR8m5Vr0+Pf9ryLvR+LINyI8EsGDI1Vmd58VMVvOurib80q4FjCpzj28SLxlRZ+eUZ0vFYLvWjSUSnk86bjTMen6b/DxU9+kGVQ6o0Ivcuv+FhApzF9WzfKb88igP0O+OS7y2/QPSt6uwZwpHip6HkLY4XHiLd4+QZYnLnN1BBW/GYIo+n54seGko/l2li8HyWOK30dce3aIJrZgg1KBBsUCNcrEGlQIVKvRJReKdfRRUqEGA1QnT4AtWE3VCiE2lCINGMh1EYdVMYiqM3bsuRV0yl8cMa3OY4EdMORgO6I920NY7IS+O0MALHYzlii+ffGTjYMOiGnU6qU8PULkEtYVL3ST3ap/Nz+VVxbtmqI7iI6HVqKL4DFrRqipUI34ZSpm0hBQXGrQ4FpO78AM3v2sPT9FaP00wMWw1hYWNxKUmRqsSgsksdPv+F6PNajG3S6fBQcOgjdf+9ZjkFxi4poWVEUFWFYbB9cHdcFer34ezlret+qwFV+rRAZ3BIGowG+OekIzP+nwmO75kdCpYiBwaiHry4fzZOPlPxfKHWsX6A/CgvD5HW1eXpcfSilwuvW06mR09JPXkFRZMCIbZenPizrYJwCac1U8v2tTghr4B3BIwLACxcuQK/Xo27d0kldxePDhy+nvChJ9BMs73ixvyKiufiFF16Ao52+dBCnYwqQ31lxxbci8c1LrP+NyEeKjykYTW1oRGofZannDSWWnfUKcN7H9O00obERp0YoLd/gDGXOOVFPhzQfUxPI0aZG7BmvLD6mdFnEciGkEFk+ptq+fc2MWPuAKVC7YpGBWxFQnKdsZxPgt+mV/eqJaxbXItYD/r5dYd2xWmDLNTb8R5tyIXsljdEIrdFYYm3ap8Hlxz5GI/wNBvgbjQgQa4MR/sbL6wCDEYEGA8L0BoQa9AjXm461Z6xZZFQiE/7IMAYgAwE4bwzDWWMEkowROGOMxBFjLE4Z68GQpxSZTopV/Ddsq6ggH4zsxA8fMhGDqsQiavpLEt03rE2l5NOsGerOurJVqlx1GwL9TK0sVeoDGO94xtRaU9yiI7rXmB+39PGxlFumkBp61tTtRrToiFabEutmkZEYWdzCJGpJc9pvMbUsiQBUtjBdvnajJk1wUxdTZG3Iz0d62E8iEampDOYWKbk2YHDzONw0cKA8VgTA5wveq/DYAa1a4qaxY627d/LeALC2iBrGkrWGogYwNjbW7q/Ts+n18FOvQ2azy/tKf6gqUGriK1FBEVP2mMtnDSz5WLS8lGh9ET0xSirZs8cYpICivP73ZQYdyEeiZcEyb3w5z5f53lj2dcs+rui1Kj+j/Ne19noVnnPF3srLbt3rXnmOpb9NiT44l9fmZ019di5vW7bKOU9smZqaRad2sRT3rKlkRGQl4Vs554jQOxUKpFZ8Url7DUo19Ao1DEot9MWLQaG+vK3UoFAVgEKVf7mvG1W8VFGhUyPi/6hfy0gE+1qZb5DIyeRgEaXp774ySq0WPk2bWHVN0eUlaEB/64719UX4HbdbdazoGhM1Y7pVx5JjeEQAWKdOHahUKqSklK56Fo+jo8ufKUDst+V4wcfHRy6OdmPfSbgRkxz+OkREROSdPGJsuVarRdeuXbFmzeUkowaDQT7u1atXueeI/SWPF8QgkIqOJyIiIvIUHlEDKIim2YkTJ6Jbt24y959IA5OTk2MZFXznnXciJiZG9uMTHn30UfTt2xcLFizAiBEj8P3332P79u34+OOPnXwnRERERI7lMQHguHHjcP78ecyePVsO5OjUqRNWrVplGeiRkJAgRwab9e7dW+b+e+aZZ/DUU0/JRNBiBDBzABIREZGn41zANcC5BImIiNxPJj+/PaMPIBERERFZjwEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF7GY6aCcwbzJCoiozgRERG5h8ziz21vngyNAWANZGVlyXVsbKyzi0JERETV+BwPCQmBN+JcwDVgMBiQlJSEoKAgKBQKu387EYFlYmKiR85TyPtzf55+j7w/9+fp98j7qz6j0SiDv/r160Op9M7ecKwBrAHxS9OgQQOHvob4pffEP2wz3p/78/R75P25P0+/R95f9YR4ac2fmXeGvURERERejAEgERERkZdhAOiifHx88Nxzz8m1J+L9uT9Pv0fen/vz9Hvk/VFNcBAIERERkZdhDSARERGRl2EASERERORlGAASEREReRkGgERERERehgGgCzh9+jQmTZqEJk2awM/PD82aNZMjn3Q6XaXn5efn48EHH0RERAQCAwNx0003ISUlBa5qzpw56N27N/z9/REaGmrVOXfddZecZaXkMnToUHjK/YkxWLNnz0a9evXkz37QoEE4duwYXNGlS5dw2223yYSs4v7E72x2dnal5/Tr1++Kn9/9998PV/H++++jcePG8PX1RY8ePbB169ZKj1+8eDFatWolj2/fvj1WrlwJV2bL/S1atOiKn5U4z1X9888/uOGGG+RMDqKsy5cvr/KcdevWoUuXLnJUaVxcnLxnV2brPYr7K/szFMu5c+fgiubOnYvu3bvL2bSioqIwatQoHDlypMrz3O3v0FUxAHQBhw8fltPKffTRRzhw4ADefPNNLFy4EE899VSl502fPh2//vqr/GNYv369nJZuzJgxcFUioB07diymTp1q03ki4EtOTrYs3333HTzl/l577TW888478uf933//ISAgAEOGDJHBvasRwZ/4/fzzzz/x22+/yQ+ne++9t8rzpkyZUurnJ+7ZFfzwww+YMWOG/LK1c+dOdOzYUf7fp6amlnv8pk2bMH78eBn47tq1S35YiWX//v1wRbbenyCC+5I/q/j4eLiqnJwceU8iyLXGqVOnMGLECPTv3x+7d+/GtGnTMHnyZKxevRqeco9mIogq+XMUwZUrEp9bohJjy5Yt8n2lsLAQgwcPlvddEXf7O3RpIg0MuZ7XXnvN2KRJkwqfT09PN2o0GuPixYst+w4dOiRS+hg3b95sdGVffPGFMSQkxKpjJ06caBw5cqTRnVh7fwaDwRgdHW2cP39+qZ+rj4+P8bvvvjO6koMHD8rfrW3btln2/f7770aFQmE8e/Zshef17dvX+Oijjxpd0VVXXWV88MEHLY/1er2xfv36xrlz55Z7/C233GIcMWJEqX09evQw3nfffUZPuD9b/i5djfjdXLZsWaXHPPHEE8a2bduW2jdu3DjjkCFDjJ5yj2vXrpXHpaWlGd1RamqqLP/69esrPMbd/g5dGWsAXVRGRgbCw8MrfH7Hjh3y25JoMjQTVeINGzbE5s2b4UlEs4b4BtuyZUtZu3bx4kV4AlEjIZpmSv4MxdyUoqnO1X6Gojyi2bdbt26WfaLcYj5sUXNZ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v3798NBDD2HatGmoU6cOhgwZIveL64jr+fr6on///vjyyy/l66WnpyMnJwfBwcH46aefSr3W8uXLERAQgKysrHLvZ+XKlfKeevbsadm3bt06ed3Vq1ejc+fO8PPzw4ABA5Camorff/8drVu3lq81YcIEGUCaGQwGzJ07F02aNJHniICvZHlEgPfDDz+UOkdYtGgR6tWrV6om9YYbbsD3339v08+GiLwTA0AicgkvvPACbrnlFuzduxfDhw/HbbfdhkuXLsnnRLAmgikRWG3fvh2rVq1CSkqKPL4kEdxptVps3LgRCxcuxKlTp3DzzTdj1KhR2LNnD+677z48/fTTluNFkCf6zn3xxRelriMei/OCgoLKLeu///4ra+fK8/zzz+O9997Dpk2bkJiYKMv41ltv4dtvv8WKFSvwxx9/4N1337UcL4K/r776Spb3wIEDmD59Om6//XasX79ePi/+HwoKCkoFhWIKd3GvonldpVJZ9l911VXYunWrPJ6IqFJGIiIHmjhxolGlUhkDAgJKLXPmzLEcI96KnnnmGcvj7Oxsue/333+Xj1966SXj4MGDS103MTFRHnPkyBH5uG/fvsbOnTuXOmbmzJnGdu3aldr39NNPy/PS0tLk4//++0+WLykpST5OSUkxqtVq47p16yq8p5EjRxrvueeeUvvWrl0rr/vXX39Z9s2dO1fuO3HihGXffffdZxwyZIjczs/PN/r7+xs3bdpU6lqTJk0yjh8/3vL41ltvlfdntmbNGnndY8eOlTpvz549cv/p06crLDsRkaCuPDwkIqo50fT64YcfltoXHh5e6nGHDh1K1cyJ5lLRfCqI2jvR3000/5Z14sQJtGjRQm6XrZU7cuQIunfvXmqfqCUr+7ht27ayRu3JJ5+UfegaNWqEPn36VHg/eXl5skm5PCXvQzRViybtpk2bltonaumE48ePy6bd66677or+i6K20+yee+6RTdriXkU/P9EnsG/fvoiLiyt1nmhCFso2FxMRlcUAkIgcTgR0ZYOVsjQaTanHoj+d6B8nZGdny/5t8+bNu+I80Q+u5OtUx+TJk/H+++/LAFA0/959993y9Ssi+himpaVVeR/iGlXdlyCahmNiYkodJ/oYlhzt27BhQ9nv7/HHH8fSpUvx0UcfXfHa5ibzyMhIK++ciLwVA0AicnldunTBkiVLZMoVtdr6t62WLVvKARslbdu27YrjRJ+7J554Au+88w4OHjyIiRMnVnpdUTtnj9G2bdq0kYFeQkKCrNGriFKplEGpGHksAkXRz1H0USxLDJRp0KCBDFCJiCrDQSBE5HBiUMK5c+dKLSVH8FblwQcflLVb48ePlwGcaAoVo21FUKTX6ys8Twz6OHz4MGbOnImjR4/ixx9/lLVoQskaPjEiWeTTE7VrgwcPlkFUZURzrBiwUVEtoLXEIJP//e9/cuCHaIIW97Vz5045SEQ8Lknc69mzZ/HUU0/J/wdzc2/ZwSmi/EREVWEASEQOJ0btiqbakss111xj9fn169eXI3tFsCcCnPbt28t0L6GhobJ2rCIitYoYPSuaTEXfPNEP0TwKuGQTqzndiuh7J/rbVUW8vqiVFAFlTb300kt49tln5WhgkSpGpHURTcKi7CWJJuBBgwbJoLO8Mubn58v0NVOmTKlxmYjI8ynESBBnF4KIqLaI2TJEyhWRoqWkr7/+WtbEJSUlySbWqoggTdQYimbXyoLQ2iKC22XLlsk0M0REVWEfQCLyaB988IEcCRwRESFrEefPny8TRpuJEbNiZpJXX31VNhlbE/wJI0aMwLFjx2SzbGxsLJxNDDYpmV+QiKgyrAEkIo8mavXETBqiD6FoRhUziMyaNcsymEQkbha1giLty88//1xuqhkiIk/DAJCIiIjIyzi/4woRERER1SoGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERHBu/w/pHnHlNSuAWMAAAAASUVORK5CYII=", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Example of using the detailed balance factor in easydynamics\n", + "\n", + "plt.figure()\n", + "\n", + "x=np.linspace(-2, 2, 1000)\n", + "Lorentzian=Lorentzian(center=0, width=0.1, area=1)\n", + "\n", + "DetailedBalanceT1=detailed_balance_factor(x,temperature=0.0)\n", + "plt.plot(x,Lorentzian.evaluate(x)*DetailedBalanceT1, label='T=0 K')\n", + "\n", + "DetailedBalanceT3=detailed_balance_factor(x,temperature=1)\n", + "plt.plot(x,Lorentzian.evaluate(x)*DetailedBalanceT3, label='T=1 K')\n", + "\n", + "DetailedBalanceT3=detailed_balance_factor(x,temperature=3)\n", + "plt.plot(x,Lorentzian.evaluate(x)*DetailedBalanceT3, label='T=3 K')\n", + "\n", + "plt.plot(x, Lorentzian.evaluate(x), label='No DBF', linestyle='--')\n", + "\n", + "plt.legend()\n", + "plt.xlabel('Energy (meV)')\n", + "plt.ylabel('Intensity (arb. units)')\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "220405f1", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "c8f3a85e975842358151b5ccfa2f5c51", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAApFdJREFUeJzt3Qd8k+X+BfCT3V1GKXsPERFEEbcoDtx7oSLue917Xa/7uvdAcW//7r0X7oGAIiAie48C3SP7/zlP+oYktKWFtqHN+d4b2yRvkjdvQ3Lye5YtHA6HISIiIiIpw57sHRARERGR5qUAKCIiIpJiFABFREREUowCoIiIiEiKUQAUERERSTEKgCIiIiIpRgFQREREJMUoAIqIiIikGAVAERERkRSjACgiIiKSYhQARURERFKMAqCIiIhIilEAFBEREUkxCoAiIiIiKUYBUERERCTFKACKiIiIpBgFQBEREZEUowAoIiIikmIUAEVERERSjAKgiIiISIpRABQRERFJMQqAIiIiIilGAVBEREQkxSgAioiIiKQYBUARERGRFKMAKCIiIpJiFABFREREUowCoIiIiEiKUQAUERERSTEKgCIiIiIpRgFQREREJMUoAIqIiIikGAVAERERkRSjACgiIiKSYhQARaTRfPPNN7DZbObnxuy1117mVB/cbvDgwWgOd999N/r06QOHw4HtttuuWR5TRKS5KQCKiPH666+b8PbOO+9scN3QoUPNdRMnTtzguh49emDXXXfd7Mdfvnw5brzxRvzxxx9Ils8//xxXXnkldtttNzz77LO47bbbat2W+8pjknhKS0tDSzN16lSz7//9739r3WbOnDlmm0svvbRZ901Emoazie5XRFqY3Xff3fz84YcfcOSRR0YvLykpwYwZM+B0OvHjjz9i7733jl63ZMkSczrhhBPM+T333BOVlZVwu92bFABvuukm9OrVK2mVt6+//hp2ux1PP/10vZ/DY489hqysrOh5Vg5bmu233x4DBw7E//3f/+F///tfjdu88sor5ufJJ5/czHsnIk1BAVBEjC5duqB3794mAMb6+eefEQ6Hceyxx25wnXXeCo8MTy2xAmZZvXo10tPTGxRgjznmGOTl5aGlO+mkk3Ddddfhl19+wc4777zB9QyHDIkMiyLS8qkJWESiGOR+//13U8WzsOq3zTbb4MADDzTh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w9stt9wS3YYhlsc6Fudpq828efNw8MEHo2fPntHLOnXqVOv2PEbBYNCEUBFJ8jQwlZWVZvCHhYNBuITbZ599lszdEpEUld8pH3kd88wKQgwfrOowVOR37ID8Dh2QkZnR6I/JYML3Pa5KxADHqt4LL7yA5cuX49133631dqy4HXTQQSYADhgwwKxilJWVhV9++aVej/vKK6/gqKOOMuGzoeGPMjIyzLFhEGVT7J133onHH38cTz75JL788su4bVlV47as0h1yyCHmeU6dOjVuG+tYx55YDa0Jt50yZYoJoPydlc3EKtw333xjzrMqyrXiWan84YcfTADde++9TcsTQyevmzx5stmewZRdkqwKJO+3PhjaiUuL8naskMZiaxaru+3bt8d5551ngrCFldDLL7/cVFEZirk0KfclsSrJz8Wtt97a/I0ZplntrMvMmTPNseZz5HNl33qGZgqFQubY8W/H42KtnGWxjiUrujxW/Fuz69bPP/8cnUSZf5vEijO/BPCxrM/16dOnm1Y9bsvnzr79ZWVlNe4vvzR06dLF7FssvlZOP/306Pn33nsP22+/vfli1KdPH9x0003mS4i0sADIPyzf6KioqMi88O+9917TJ4DNGyLS+virqhp8ip2Amb+by33x/fFqu21DhKr8yK5wwlERrHEtYNTSRPrvf//bfDDXdaoN+0Oz/zObfS0Mn3w/tD5wN4aVLQ6q4/rnbAremPHjx5uw88wzz+D8889HY+F67G3btq2xKdjyzz//4OuvvzbPb1Mx/LDKedlll5nfGaBqw+omK6XsVsRwfdJJJ5ngw/7lDJG83uVyYddddzVBnIGJ97mx+61prWAGX94u9vlPnDjRBC/+ZJWWgY4nC48//878+/3555+mIsuAF9sFgIGKIfLFF1/Ed999Z2bPqGvfuLzpnnvuacIdjzWfJ0OUFZQefPBB81nL++Rjstp82GGHbdDt4NprrzWPw1DNLxljxowx98FjxHDJLxGxXn75ZfP5zcDI1yLvl68HHus33njDHJ/aXm983mvXrjXHybJu3ToTTPk3s7ornHLKKbjoootMdZxfOHgstYTrpklqLZzfAO+//37z+5tvvmm+dbP54q233jLfSM8555xk7p6INIGHxh3T4NsccvHV2GqX3c3vcyb9jA8fuAPdBg3G8TfcEd3myfNPR2VpyQa3vey1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dMABB6Alu/XWW3H44YejV69eTfYYU6ZMMcfql19+qfH6ffbZB0cddZT5/b///a/Zp+Li4ibbHxFpPRQARaTJMeytWLEi7vR///d/TfqYPp+vye67oqICTz/9NM444ww0pR122AFDhw7FM888s8F1rDxOnDgxug+DBw9G37598dJLLzXpPolI66AAKCJNzuPxoFOnTnGntm3bRq9nleupp57CkUceiYyMDPTv3x/vv/9+3H3MmDEDBx54ILKystCxY0eMHTsWa9asiV6/11574fzzz8fFF1+MvLw8jB492lzO++H9paWlYe+998bzzz9vHq+oqAjl5eXIycnBm2++GfdY7777LjIzM1FaWlrj8/n444/Nc9p5552jl33zzTfmfj/77DMMGzYM6enpGDVqFFavXo1PPvkEW2+9tXmsE0880QRISygUwu23347evXub2zDwxe4PA95rr70Wdxt67rnn0Llz57hK6qGHHopXX321QX8bEUlNCoAiskW46aabcNxxx+HPP//EQQcdhJNOOgnr1q0z1zGsMUwxWE2ePBmffvopVq1aZbaPxXDndrvx448/YsKECViwYAGOOeYYHHHEEZg2bRr+9a9/4dprr41uz5DHvnPPPvts3P3wPG+XnZ1d475+//33pjpXkxtvvBGPPPIIfvrpJyxZssTs4wMPPIBXXnkFH330ET7//HM8/PDD0e0Z/l544QWzvzNnzsQll1yCk08+Gd9++625nsfB6/XGhUIu4c7nyuZ1h8MRvXzEiBGYNGmS2V5EpE5hEZEmNG7cuLDD4QhnZmbGnW699dboNnwr+u9//xs9X1ZWZi775JNPzPlbbrklvP/++8fd75IlS8w2s2fPNudHjhwZHjZsWNw2V111VXjw4MFxl1177bXmdoWFheb8r7/+avZv+fLl5vyqVavCTqcz/M0339T6nA4//PDw6aefHnfZxIkTzf1++eWX0ctuv/12c9m8efOil/3rX/8Kjx492vxeVVUVzsjICP/0009x93XGGWeEx4wZEz1/wgknmOdn+eqrr8z9zpkzJ+5206ZNM5cvXLiw1n0XESFn3fFQRGTzsen1sccei7usXbt2ceeHDBkSV5ljcymbT4nVO/Z3Y/Nvonnz5mHAgAHm98Sq3OzZs7HjjjvGXcYqWeL5bbbZxlTUrr76atOHrmfPnthzzz1rfT6VlZWmSbkmsc+DTdVs0u7Tp0/cZazS0dy5c03T7n777bdB/0VWOy2nn366adLmc2U/P/YJHDlyJPr16xd3OzYhU2JzsYhIIgVAEWlyDHSJYSWRy+WKO8/+dOwfR2VlZaZ/25133rnB7dgPLvZxNsWZZ56J8ePHmwDI5t/TTjvNPH5t2MewsLBwo8+D97Gx50VsGu7atWvcduxjGDvat0ePHqbf3xVXXIG3334bjz/++AaPbTWZd+jQoZ7PXERSlQKgiGzxtt9+e7z11ltmyhWns/5vW1tttZUZsBHrt99+22A79rm78sor8dBDD+Gvv/7CuHHj6rxfVucaY7TtoEGDTNBbvHixqejVxm63m1DKkccMiuznyD6KiThQplu3biagiojURYNARKTJcVDCypUr406xI3g35rzzzjPVrTFjxpgAx6ZQjrZlKAoGg7XejoM+/v77b1x11VX4559/8Prrr5sqGsVW+DgimfPpsbq2//77mxBVFzbHcsBGbVXA+uIgk8svv9wM/GATNJ/X1KlTzSARno/F57ps2TL85z//McfBau5NHJzC/RcR2RgFQBFpchy1y6ba2NPuu+9e79t36dLFjOxl2GPA2Xbbbc10L23atDHVsdpwahWOnmWTKfvmsR+iNQo4tonVmm6Ffe/Y325j+PisSjJQbq5bbrkF1113nRkNzKliOK0Lm4S577HYBLzvvvua0FnTPlZVVZnpa84666zN3icRaf1sHAmS7J0QEWkuXC2DU65wipZYL774oqnELV++3DSxbgxDGiuGbHatK4Q2F4bbd955x0wzIyKyMeoDKCKt2qOPPmpGArdv395UEe+++24zYbSFI2a5Mskdd9xhmozrE/7o4IMPxpw5c0yzbPfu3ZFsHGwSO7+giEhdVAEUkVaNVT2upME+hGxG5Qoi11xzTXQwCSduZlWQ07689957NU41IyLS2igAioiIiKSY5HdcEREREZFmpQAoIiIikmIUAEVERERSjAKgiIiISIpRABQRERFJMQqAIiIiIilGAVBEREQkxSgAioiIiKQYBUARERERpJb/B5Z2gQ8G3CxJAAAAAElFTkSuQmCC", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "\n", + "from scipy.signal import fftconvolve\n", + "\n", + "\n", + "# Example of DetailedBalance, up to 100 mueV. Res and peak is 5 mueV\n", + "\n", + "x=np.linspace(-0.5, 0.5, 1000)\n", + "\n", + "Gwidth=0.005 # 5 mueV\n", + "Lwidth=0.005 # 5 mueV\n", + "Lorentzian=Lorentzian(center=0, width=Lwidth, area=1)\n", + "Gaussian= Gaussian(center=0,width=Gwidth,area=1)\n", + "Voigt=Voigt(center=0, Gwidth=Gwidth, Lwidth=Lwidth, area=1)\n", + "\n", + "plt.figure()\n", + "DetailedBalanceT1=detailed_balance_factor(x,temperature=0.0)\n", + "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT1, label='T=0, first convolve, then DBF')\n", + "\n", + "DetailedBalanceT2=detailed_balance_factor(x,temperature=0.1)\n", + "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT2, label='T=0.1 K, first convolve, then DBF')\n", + " \n", + "DetailedBalanceT3=detailed_balance_factor(x,temperature=0.3)\n", + "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT3, label='T=0.3 K, first convolve, then DBF')\n", + "\n", + "\n", + "# Evaluate both models at the same points\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT1\n", + "model2 = Gaussian.evaluate(x)\n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "plt.plot(x, convolved, label='T= 0, DBF first, then convolve', linestyle='-.')\n", + "\n", + "\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT2\n", + "model2 = Gaussian.evaluate(x)\n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "plt.plot(x, convolved, label='T = 0.1 K, DBF first, then convolve', linestyle='-.')\n", + "\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT3\n", + "model2 = Gaussian.evaluate(x) \n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "plt.plot(x, convolved, label='T = 0.3 K, DBF first, then convolve', linestyle='-.')\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "plt.legend()\n", + "plt.xlabel('Energy (meV)')\n", + "plt.ylabel('Intensity (arb. units)')\n", + "plt.title('Width of 5 mueV')\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "5622c265", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "6de5042e87f84157b42ae34113a65559", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "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devW5l5XXnmlCSBdcnJyZOLEidK0aVPzHg34PMujAd5nn33m9R41efJkqVu3rlcmdfDgwfLpp5+W6GsDIDgRAAIoFyZMmCCXXXaZrFmzRgYOHChXXXWVHDlyxBzTYE2DKQ2sVqxYIbNmzZL9+/eb8z1pcBceHi6//vqrvPHGG7J161a55JJLZOjQofL777/LTTfdJP/5z3/c52uQp23n3n//fa/r6La+r3LlygWW9eeffzbZuYI88sgj8uqrr8qiRYtk586dpowvvfSSfPzxxzJjxgyZM2eOvPLKK+7zNfj78MMPTXnXr18vY8aMkauvvloWLlxojutzSE9P9woKdQp3/axavR4SEuLef/rpp8uyZcvM+QBQJAsAytCIESOskJAQKyYmxmt54okn3Ofoj6IHH3zQvZ2cnGz2ff/992b7sccesy644AKv6+7cudOcs3HjRrPds2dPq3Pnzl7njBs3zmrXrp3Xvv/85z/mffHx8WZ76dKlpnx79uwx2/v377dCQ0OtH3/8sdDPNGTIEOuGG27w2rdgwQJz3Xnz5rn3TZw40ezbsmWLe99NN91k9evXz6ynpaVZ0dHR1qJFi7yuNXLkSGv48OHu7SuuuMJ8Ppf58+eb627atMnrfb///rvZv23btkLLDgAqtOjwEAD+Oa16ff311732VatWzWu7Q4cOXpk5rS7V6lOl2Ttt76bVv762bNkirVq1Muu+WbmNGzdKt27dvPZplsx3u23btiajdt9995k2dI0bN5Zzzz230M+TmppqqpQL4vk5tKpaq7SbNWvmtU+zdGrz5s2mavf888/P135Rs50uN9xwg6nS1s+q7fy0TWDPnj2lRYsWXu/TKmTlW10MAL4IAAGUOQ3ofIMVX2FhYV7b2p5O28ep5ORk077t6aefzvc+bQfneZ+TceONN8qkSZNMAKjVv9dff725f2G0jWF8fPwJP4de40SfS2nVcP369b3O0zaGnr19GzVqZNr93XPPPTJ16lR58803893bVWVes2bNYn5yAMGKABBAuXfaaafJV199ZYZcCQ0t/o+tU045xXTY8LR8+fJ852mbu3vvvVdefvll2bBhg4wYMaLI62p2rjR627Zp08YEejt27DAZvcI4nU4TlGrPYw0UtZ2jtlH0pR1lGjRoYAJUACgKnUAAlDntlLBv3z6vxbMH74nceuutJrs1fPhwE8BpVaj2ttWgKDs7u9D3aaePP//8U8aNGyd//fWXfP755yaLpjwzfNojWcfT0+zaBRdcYIKoomh1rHbYKCwLWFzayeTuu+82HT+0Clo/16pVq0wnEd32pJ919+7d8sADD5jn4Kru9e2couUHgBMhAARQ5rTXrlbVei5nn312sd9fr14907NXgz0NcNq3b2+Ge6lSpYrJjhVGh1bR3rNaZapt87QdoqsXsGcVq2u4FW17p+3tTkTvr1lJDSj/qccee0weeugh0xtYh4rRYV20SljL7kmrgPv27WuCzoLKmJaWZoavGTVq1D8uEwD7c2hPkEAXAgD8RWfL0CFXdIgWTx999JHJxO3Zs8dUsZ6IBmmaMdRq16KCUH/R4HbatGlmmBkAOBHaAAKwtddee830BK5evbrJIj777LNmwGgX7TGrM5M89dRTpsq4OMGfGjRokGzatMlUyzZs2FACTTubeI4vCABFIQMIwNY0q6czaWgbQq1G1RlE7r//fndnEh24WbOCOuzLN998U+BQMwBgNwSAAAAAQSbwDVcAAADgVwSAAAAAQYYAEAAAIMgQAAIAAAQZAkAAAIAgQwAIAAAQZAgAAQAAggwBIAAAQJAhAAQAAJDg8v+Bs6/Q05JtywAAAABJRU5ErkJggg==", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "\n", + "from scipy.signal import fftconvolve\n", + "\n", + "\n", + "# Example of DetailedBalance, up to 100 mueV. Res and peak is 1 mueV\n", + "\n", + "x=np.linspace(-0.5, 0.5, 10001)\n", + "\n", + "Gwidth=0.001 \n", + "Lwidth=0.001 \n", + "Lorentzian=Lorentzian(center=0, width=Lwidth, area=1)\n", + "Gaussian= Gaussian(center=0,width=Gwidth,area=1)\n", + "Voigt=Voigt(center=0, Gwidth=Gwidth, Lwidth=Lwidth, area=1)\n", + "\n", + "plt.figure()\n", + "DetailedBalanceT1=detailed_balance_factor(x,temperature=10.0)\n", + "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT1, label='first convolve, then DBF')\n", + "\n", + "\n", + "# Evaluate both models at the same points\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT1\n", + "model2 = Gaussian.evaluate(x)\n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", + "\n", + "\n", + "\n", + "plt.legend()\n", + "plt.xlabel('Energy (meV)')\n", + "plt.ylabel('Intensity (arb. units)')\n", + "plt.title('Width of 1 mueV')\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "68d207ad", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b5d1fccf615c46f1a687ce1e5b228ba9", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAcEhJREFUeJzt3QeYE2XXBuAnffvSe2/Si4o0FUUU1E9BrOinYO8FrNhREbE37Arirx8qCjYEBQEF6QLSe+9le0ub/zpvMiHZxu6y2exmnttrnMnMZPJmdsmenLeZNE3TQERERESGYY50AYiIiIioYjEAJCIiIjIYBoBEREREBsMAkIiIiMhgGAASERERGQwDQCIiIiKDYQBIREREZDAMAImIiIgMhgEgERERkcEwACQiIiIyGAaARERERAbDAJCIiIjIYBgAEhERERkMA0AiIiIig2EASERERGQwDACJiIiIDIYBIBEREZHBMAAkIiIiMhgGgEREREQGwwCQiIiIyGAYABIREREZDANAIiIiIoNhAEhERERkMAwAiYiIiAyGASARERGRwTAAJCIiIjIYBoBEREREBsMAkIiIiMhgGAASERERGQwDQCIiIiKDYQBIREREZDAMAImIiIgMhgEgERERkcEwACQiIiIyGAaARFRu5s6dC5PJpNYncs4556ilJOS8jh07oiK88soraNGiBSwWC7p27Vohr0lEVNEYABKR8s0336jgberUqQWOdenSRR2bM2dOgWNNmjRB7969T/r19+3bh2effRYrV65EpPz222945JFH0KdPH0yYMAEvvvhikedKWeWe5F9iYmJQ1fzzzz+q7E8++WSR52zevFmdM3LkyAotGxGFhzVM1yWiKubMM89U6/nz5+Oyyy4L7E9PT8eaNWtgtVqxYMECnHvuuYFju3fvVss111yjHp999tnIycmB3W4vUwA4evRoNGvWLGKZtz/++ANmsxmffvppid/D+++/j4SEhMBjyRxWNaeeeiratm2L//3vf3jhhRcKPeerr75S6//+978VXDoiCgcGgESkNGjQAM2bN1cBYLCFCxdC0zRceeWVBY7pj/XgUYKnqpgB0x06dAixsbGlCmCvuOIK1KpVC1Xdddddh6eeegqLFi1Cz549CxyX4FCCRAkWiajqYxUwEQVIILdixQqVxdNJ1q9Dhw648MILVXDg9XpD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Hhe2yLnk884772hNmjRRAYdkUBYtWhQ4JplT+aOYfyidNm3aqPM7dOig/fLLLxEodXTf56ZNmxb6eysBN5Xv73MwBoDGY5L/RbYSmoiIiIgqEnsBExERERkMA0AiIiIig2EASERERGQwDACJiIiIDIYBIBEREZHBMAAkIiIiMhgGgEREREQGwwCQiKgMjh49ijp16qg5VSuDa665Bq+99lqki0FEVQQDQCIKq+HDh8NkMhVYBg4ciKpszJgxGDRoEJo1axa211i+fLm6V4sWLSr0+HnnnYchQ4ao7SeffFKVKS0tLWzlIaLowQCQiMJOgr39+/eHLP/73//C+ppOpzNs187Ozsann36Km2++GeF02mmnoUuXLvjss88KHJPM45w5cwJl6NixI1q2bIn/+7//C2uZiCg6MAAkorBzOByoV69eyFK9evXAcclyffLJJ7jssssQFxeH1q1b48cffwy5xpo1a3DhhRciISEBdevWxfXXX48jR44Ejp9zzjm455578MADD6BWrVoYMGCA2i/XkevFxMTg3HPPxeeff65eLzU1FVlZWUhKSsKUKVNCXmvatGmIj49HRkZGoe9n+vTp6j317NkzsG/u3LnqujNnzkS3bt0QGxuLfv364dChQ/j111/Rrl079VrXXnutCiB1Xq8XY8eORfPmzdVzJOALLo8EeF9//XXIc8TEiRNRv379kEzqJZdcgsmTJ5fqZ0NExsQAkIgqhdGjR+Oqq67Cv//+i4suugjXXXcdjh07po5JsCbBlARWy5Ytw4wZM3Dw4EF1fjAJ7ux2OxYsWIAPPvgA27dvxxVXXIHBgwdj1apVuP322/HEE08EzpcgT9rOTZgwIeQ68liel5iYWGhZ//rrL5WdK8yzzz6Ld999F3///Td2796tyvjmm2/iq6++wi+//ILffvsN77zzTuB8Cf4mTZqkyrt27VqMGDEC//3vfzFv3jx1XO5DXl5eSFAoU7jLe5XqdYvFEth/xhlnYMmSJep8IqJiaUREYTRs2DDNYrFo8fHxIcuYMWMC58hH0ZNPPhl4nJmZqfb9+uuv6vHzzz+vXXDBBSHX3b17tzpn48aN6nHfvn21bt26hZzz6KOPah07dgzZ98QTT6jnpaSkqMeLFy9W5du3b596fPDgQc1qtWpz584t8j0NGjRIu+mmm0L2zZkzR1131qxZgX1jx45V+7Zu3RrYd/vtt2sDBgxQ27m5uVpcXJz2999/h1zr5ptv1oYOHRp4fM0116j3p5s9e7a67ubNm0Oet2rVKrV/x44dRZadiEhYiw8PiYhOnlS9vv/++yH7atSoEfK4c+fOIZk5qS6V6lMh2Ttp7ybVv/lt3boVbdq0Udv5s3IbN25E9+7dQ/ZJliz/4w4dOqiM2mOPPaba0DVt2hRnn312ke8nJydHVSkXJvh9SFW1VGm3aNEiZJ9k6cSWLVtU1e75559foP2iZDt1N910k6rSlvcq7fykTWDfvn3RqlWrkOdJFbLIX11MRJQfA0AiCjsJ6PIHK/nZbLaQx9KeTtrHiczMTNW+bdy4cQWeJ+3ggl+nLG655RaMHz9eBYBS/XvjjTeq1y+KtDFMSUk54fuQa5zofQmpGm7YsGHIedLGMLi3b5MmTVS7v4cffhjff/89PvzwwwKvrVeZ165du4TvnIiMigEgEVV6p556Kr777js15IrVWvKPrVNOOUV12Ai2dOnSAudJm7tHHnkEb7/9NtatW4dhw4YVe13JzpVHb9v27durQG/Xrl0qo1cUs9msglLpeSyBorRzlDaK+UlHmUaNGqkAlYioOOwEQkRhJ50SDhw4ELIE9+A9kbvvvltlt4YOHaoCOKkKld62EhR5PJ4inyedPjZs2IBHH30UmzZtwjfffKOyaCI4wyc9kmU8PcmuXXDBBSqIKo5Ux0qHjaKygCUlnUweeugh1fFDqqDlff3zzz+qk4g8Dibvde/evXj88cfVfdCre/N3TpHyExGdCANAIgo76bUrVbXBy5lnnlni5zdo0ED17JVgTwKcTp06qeFeqlWrprJjRZGhVaT3rFSZSts8aYeo9wIOrmLVh1uRtnfS3u5E5PUlKykB5cl6/vnn8dRTT6newDJUjAzrIlXCUvZgUgXcv39/FXQWVsbc3Fw1fM2tt9560mUiouhnkp4gkS4EEVFFkdkyZMgVGaIl2BdffKEycfv27VNVrCciQZpkDKXatbggtKJIcDt16lQ1zAwR0YmwDSARRbX33ntP9QSuWbOmyiK+8sorasBonfSYlZlJXnrpJVVlXJLgT1x88cXYvHmzqpZt3LgxIk06mwSPL0hEVBxmAIkoqklWT2bSkDaEUo0qM4iMGjUq0JlEBm6WrKAM+/LDDz8UOtQMEVG0YQBIREREZDCRb7hCRERERBWKASARERGRwTAAJCIiIjIYBoBEREREBsMAkIiIiMhgGAASERERGQwDQCIiIiKDYQBIREREZDAMAImIiIhgLP8PiUdC/xI4J2MAAAAASUVORK5CYII=", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "\n", + "from scipy.signal import fftconvolve\n", + "\n", + "\n", + "# Example of DetailedBalance, up to 100 mueV. Res and peak is 5 mueV\n", + "\n", + "x=np.linspace(-0.5, 0.5, 1001)\n", + "\n", + "Gwidth=0.005 \n", + "Lwidth=0.005 \n", + "Lorentzian=Lorentzian(center=0, width=Lwidth, area=1)\n", + "Gaussian= Gaussian(center=0,width=Gwidth,area=1)\n", + "Voigt=Voigt(center=0, Gwidth=Gwidth, Lwidth=Lwidth, area=1)\n", + "\n", + "plt.figure()\n", + "DetailedBalanceT1=detailed_balance_factor(x,temperature=10.0)\n", + "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT1, label='first convolve, then DBF')\n", + "\n", + "\n", + "# Evaluate both models at the same points\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT1\n", + "model2 = Gaussian.evaluate(x)\n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", + "\n", + "\n", + "\n", + "plt.legend()\n", + "plt.xlabel('Energy (meV)')\n", + "plt.ylabel('Intensity (arb. units)')\n", + "plt.title('Width of 5 mueV')\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "0bfc6acc", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "345223aaa342478798b09f40f4477c6d", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "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n35S24oVK/Dcc8/ZjkvwJ4HsnDlzsH37dtx999245ppr1Hn2HnnkEbz00ktYt24dgoODcf3117ttT0FBgQp65WctQdvmzZvxwAMP2Lrn58+fr34m9957L7Zt24abb74ZU6dOxbJlyxweZ8aMGepnvGXLFowbNw5XX301srKyVJAnweXnn3/ucL4E2Keeeio6dOignkuCPzlfXstvv/2G/fv3Y+LEiS7bfNZZZ6mxnNp7IIxGowrg5Xm1n6W875deeqlqkxyTgPD222+v1ftEVZjphOXm5sonvLokIv9z1XurzB0e/Mn81drkWp1fVmE0d5n+s7pPSk5RtecWFxebd+zYoS6dPBFT923bd5X3l+uyb+44x8ed3cn1fetoypQp5vHjx7s8NnHiRHOvXr1stzt06GA2GAzmyMhIc1hYmPrMHD58uDk7O9t2zrJly9R+Ocd+y8jIcNsGeX5phz15jPnz56vrBw4cULdfffVVh3P69u1rfvLJJ10+ptYO+7bVlv1za5544glzRESEOS8vz7bv/vvvV69flJSUqOMrV650uN8NN9xgnjRpkkOblixZYjv+888/q30u/++YzeZ33nnHHB0dbc7MzHR5fMSIEeZp06Y57Lv88svN48ZV/n+Rx3/00UdttwsKCtS+X375Rd3euHGjOSgoyHzo0CF122g0mpOSksxvv/22uv3rr7+a9Xq9OTm58ndn+/bt6jHWrFlj+/n079/fdvzOO+80jx492nZ78eLF5tDQUNv7IT+Xm266yaHdf/75p1mn07n8WVT3O5bLv99mZgCJiBooAxii16F9vKVYZF9aYHZLSewg3Yf27r//flWsIVkb6coU559/vsrw2Pvzzz/VedomXbH1JV2f9qTL8JlnnlGZqieeeEK1qTFJ1690gWtat26NtLQ0dX3v3r0oKipSBTSShdQ2yQhKtstev379HB5DaI9TlfzsBg4cqLp/XZFsqLx+e3Jb9rt7TulGlm5c7TmlerdXr162LKBk+eTY5ZdfbnsOyarKpundu7fK8lV9Ho1k+qTLOyUlxZZRlP8nWpW3ZDJleIH9z0qyupJtPHDggMvHJPeCqzlGRBSwisoqkJpb4jC2rzakEEQCx71p+TitW8KJPfnDlj+AdaK3K37oeaHlMYKqfMe/aysam/xxl/Fs9hISEtC1a1d1XcaSvfrqqzjllFNU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IrNC+PP7J/9HJWiT90gL+GTMu4xfdzdbxon8HpMdu4IQakKHDh0yb9y40TxjxgxzVFSUui5bfn6+Ol5RUWHu06eP+ZxzzjFv2rTJvGjRIlU1O336dNtj/PPPP+YePXqYjxw5Ytt37rnnmgcOHKiO/fXXX+Zu3bqZJ02aZPYWS5YsUdVfUu1albwOeT3SdrF3715VJbxu3TrzgQMHzN9//725c+fO5tNPP93sbVauXKkqgOW92rdvn/l///ufer8mT57s9vWJ//znP+b27dubf//9d/U6TznlFLV5G2l7165dzWeddZa6npqaatt89f378ssvVYXhRx99pCrob7rpJnOzZs1slffXXnut+aGHHrKd//fff5uDg4PNL774ovr/K1WoUsW9detWs7e55ZZbVEXo8uXLHd6roqIi2zlVX598Fi1evFj9/12/fr35yiuvNIeFhZm3b99u9kb33nuven3yf0vemzFjxpgTEhJUxbOvv3/2Fa3y+fDggw86HfPF90/+vml/6+TvwMsvv6yuy99D8dxzz6nfQfms2LJli3n8+PFqpoHi4mLbY4wePdr8+uuv1/r3mNxjAOghU6ZMUb8AVbdly5bZzjl48KD5vPPOM4eHh6sPNvnAKy8vtx2Xc+U+8gGoyczMVAGfBJUyZczUqVNtQaU3kLaNGDHC5TF5HfY/g+TkZBUsNG/eXP2CSwBy//33m3Nzc83eRj5wZUoJ+aMrH7q9evUyP/vss+aSkhK3r0/IB9utt95qjouLM0dERJgvvvhih6DKW8gUE67+v9p/h/TF90/+kMgfWIPBoKaTWL16tcMUNvJ7au+rr74yd+/eXZ1/0kknmX/++WezN3L3Xsn76O713XXXXbafRcuWLc3jxo0zb9iwweytJk6caG7durVqb1JSkrotXzr84f3TSEAn79vu3budjvni+6f9zaq6aa9DpoJ57LHHVPvlM0O+cFZ97TLdlgTvtf09JveC5B/7jCARERER+TfOA0hEREQUYBgAEhEREQUYBoBEREREAYYBIBEREVGAYQBIREREFGAYABIREREFGAaARERERAGGASAR0QnIzMxUS3TJWs/e4Morr8RLL73k6WYQkY9gAEhEjeq6665DUFCQ03buuefCl8la3ePHj0fHjh0b7TlkXW/5Wa1evdrl8bPOOguXXHKJuv7oo4+qNuXm5jZae4jIfzAAJKJGJ8Feamqqw/bFF1806nOWlZU12mMXFRXhgw8+wA033IDGJAvd9+/fH3PnznU6JpnHZcuW2drQp08fdOnSBf/73/8atU1E5B8YABJRowsNDUWrVq0ctri4ONtxyXK9//77uPjiixEREYFu3brhhx9+cHiMbdu24bzzzkNUVBRatmyJa6+9FhkZGbbjZ5xxBm6//XbcddddSEhIwNixY9V+eRx5vLCwMJx55pn4+OOP1fPl5OSgsLAQMTEx+Oabbxyea8GCBYiMjER+fr7L17Nw4UL1mk4++WTbvuXLl6vHXbx4MQYOHIjw8HCMHj0aaWlp+OWXX9CrVy/1XFdddZUKIDUmkwmzZs1Cp06d1H0k4LNvjwR48+bNc7iP+Oijj9C6dWuHTOqFF16IL7/8sk7vDREFJgaAROQVZsyYgSuuuAJbtmzBuHHjcPXVVyMrK0sdk2BNgikJrNatW4dFixbh+PHj6nx7EtwZDAb8/fffmDNnDg4cOIDLLrsMEyZMwObNm3HzzTfjkUcesZ0vQZ6Mnfvwww8dHkduy/2io6NdtvXPP/9U2TlXnnzySbzxxhtYuXIlDh8+rNr46quv4vPPP8fPP/+MX3/9Fa+//rrtfAn+PvnkE9Xe7du34+6778Y111yDFStWqOPycygtLXUICmUJd3mt0r2u1+tt+4cNG4Y1a9ao84mIqmUmImpEU6ZMMev1enNkZKTDNnPmTNs58lH06KOP2m4XFBSofb/88ou6/fTTT5vPOecch8c9fPiwOmf37t3q9qhRo8wDBw50OOfBBx809+nTx2HfI488ou6XnZ2tbv/zzz+qfSkpKer28ePHzcHBwebly5e7fU3jx483X3/99Q77li1bph53yZIltn2zZs1S+/bt22fbd/PNN5vHjh2rrpeUlJgjIiLMK1eudHisG264wTxp0iTb7SuvvFK9Ps3SpUvV4+7Zs8fhfps3b1b7Dx486LbtREQiuPrwkIio/qTr9e2333bY17x5c4fb/fr1c8jMSXepdJ8Kyd7JeDfp/q1q37596N69u7peNSu3e/duDB061GGfZMmq3j7ppJNURu2hhx5SY+g6dOiA008/3e3rKS4uVl3Krti/Dumqli7tzp07O+yTLJ3Yu3ev6to9++yzncYvSrZTc/3116subXmtMs5PxgSOGjUKXbt2dbifdCGLqt3FRERVMQAkokYnAV3VYKWqkJAQh9synk7Gx4mCggI1vm327NlO95NxcPbPcyJuvPFGvPnmmyoAlO7fqVOnqud3R8YYZmdn1/g65DFqel1CuoaTkpIczpMxhvbVvu3bt1fj/u6//3589913eOedd5yeW+syT0xMrOUrJ6JAxQCQiLzeoEGD8O2336opV4KDa/+x1aNHD1WwYW/t2rVO58mYuwceeACvvfYaduzYgSlTplT7uJKda4hq2969e6tALzk5WWX03NHpdCoolcpjCRRlnKOMUaxKCmXatm2rAlQiouqwCISIGp0UJRw7dsxhs6/grcltt92msluTJk1SAZx0hUq1rQRFRqPR7f2k6GPXrl148MEH8e+//+Krr75SWTRhn+GTimSZT0+ya+ecc44Koqoj3bFSsOEuC1hbUmRy3333qcIP6YKW17VhwwZVJCK37clrPXr0KB5++GH1c9C6e6sWp0j7iYhqwgCQiBqdVO1KV639dtppp9X6/m3atFGVvRLsSYDTt29fNd1Ls2bNVHbMHZlaRapnpctUxubJOEStCti+i1WbbkXG3sl4u5rI80tWUgLK+nr66afx2GOPqWpgmSpGpnWRLmFpuz3pAh4zZowKOl21saSkRE1fM23atHq3iYj8X5BUgni6EURETUVWy5ApV2SKFnuffvqpysSlpKSoLtaaSJAmGUPpdq0uCG0qEtzOnz9fTTNDRFQTjgEkIr/21ltvqUrg+Ph4lUV84YUX1ITRGqmYlZVJnnvuOdVlXJvgT5x//vnYs2eP6pZt164dPE2KTeznFyQiqg4zgETk1ySrJytpyBhC6UaVFUSmT59uKyaRiZslKyjTvnz//fcup5ohIvI3DACJiIiIAoznB64QERERUZNiAEhEREQUYBgAEhEREQUYBoBEREREAYYBIBEREVGAYQBIREREFGAYABIREREFGAaARERERAGGASARERERAsv/A89aQ46q8Z7gAAAAAElFTkSuQmCC", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "\n", + "from scipy.signal import fftconvolve\n", + "\n", + "\n", + "# Example of DetailedBalance, up to 100 mueV. Res and peak is 5 mueV\n", + "\n", + "x = np.linspace(-10, 10, 20000)\n", + "\n", + "Gwidth=0.75\n", + "Lwidth=0.1\n", + "Lorentzian=Lorentzian(center=0, width=Lwidth, area=1)\n", + "Gaussian= Gaussian(center=0,width=Gwidth,area=1)\n", + "Voigt=Voigt(center=0, Gwidth=Gwidth, Lwidth=Lwidth, area=1)\n", + "\n", + "plt.figure()\n", + "DetailedBalanceT1=detailed_balance_factor(x,temperature=10.0)\n", + "# DetailedBalanceT1=1\n", + "\n", + "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT1, label='first convolve, then DBF')\n", + "\n", + "\n", + "# Evaluate both models at the same points\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT1\n", + "model2 = Gaussian.evaluate(x)\n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "# plt.plot(x,model1, label='Lorentzian * DBF', linestyle='--')\n", + "# plt.plot(x, model2, label='Gaussian', linestyle='--')\n", + "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", + "\n", + "\n", + "\n", + "plt.legend()\n", + "plt.xlabel('Energy (meV)')\n", + "plt.ylabel('Intensity (arb. units)')\n", + "# plt.title('Width of 5 mueV')\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "9caea085", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7f5b808311f041c8bce2180693810b07", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "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OIoAaBPrjbNbt2565JFHTvn9wsJCE/6s2/3888/66KOPzBPcenKciRX+Vq5cqRkzZmj69OnmCffQQw/JblbY3bVr10mXBx54wASK5s2bn/FnH3zwwZN+7uWXX5anGjJkyEm19unT54y379evn7744gvzxjRnzhxzasEuXbrI06xZs8ac+vC9994zj6+RI0fq3Xff1TPPPHPWn/XU4zd+/Hj179/fBNnFixerUaNGuv7667Vnz55T3t56Hvbo0cME4SVLlphQZV1WrFghT2M9lqygsGDBAvNakJ+fr7Zt2yorK+uMP2d9cDzxWG3dulWerEGDBifVO2/evNPe1puOn8X6YHzifbOOo8V63/DW42c9/qznmRXYTsV6bXjzzTfNa8svv/yiiIgI85y0PigX1fMYJ7C2gYF9PvjgA3dMTMyfrv/qq6/c/v7+7rS0tOPXjR492h0dHe3Ozc095e9atWqVtaWP+7fffjt+3ddff+328/Nz79y50+1J8vLy3PHx8e4hQ4ac8XZXXnml+/HHH3d7gypVqrhHjhx5zrc/dOiQOygoyD1x4sTj161evdocw/nz57s93csvv+yuVq2a1x6/Sy65xN2rV6/j7cLCQnfFihXdw4YNO+Xtb731VnfHjh1Puu7SSy919+zZ0+3p9uzZYx5Xc+bMOe/XIk/13HPPuRs1anTOt/fm42exnkc1atRwu1wunzh+1uNx8uTJx9vW/Spfvrz7lVdeOek1MiQkxD127Ngiex7jd/QAeqj58+ebIYpy5codv876VGOdHNvqgTndz1jDvif2qFld6NY5i61PU55k2rRp2r9/v+67776z3vbTTz9VmTJllJSUpEGDBik7O1ueyhrytYZzmzRpoldeeeWMQ/aLFi0yPTPWMTrGGp6qXLmyOZaeLj09XXFxcV55/Kyedevvf+Lf3nqeWO3T/e2t60+8/bHnpLccK8vZjpc1XaRKlSpKTExUp06dTvta4yms4UFrOLF69epm9MOaNnM63nz8rMfrJ598or/+9a9m6NRXjt+JNm/erLS0tJOOkXWuXmtI93TH6EKex/hd4An/hgexnggnhj/Lsbb1vdP9jDXf50SBgYHmRf90P2OXf//73+bFNyEh4Yy3u/32280LmvUiv2zZMg0cONDMZfr888/laR577DE1bdrU/L2t4SYr7FjDMK+99topb28dk+Dg4D/NAbWOs6cdrz/asGGDRo0apREjRnjl8du3b5+ZZnGq55g13H0+z0lPP1bW0H3fvn112WWXmRB+OnXq1NF//vMfJScnm8BoHVtr6oYVIs72PLWDFQysaTFW3dbzbPDgwbriiivMkK4199FXjp/Fmit36NAh3XvvvT5z/P7o2HE4n2N0Ic9j/I4AWISefvppvfTSS2e8zerVq886UdnX7/OOHTv07bffasKECWf9/SfOX7R6RK3Jwddcc402btxoFiJ40v2z5qEcY70IW+GuZ8+eZkK+p57K6EKO386dO9WuXTszF8ma3+fJxw8ycwGtUHSm+XGWli1bmssxVnioV6+emfc5dOhQeZr27duf9HyzAqH1YcN6XbHm+fkS6wOzdX+tD1K+cvxgPwJgEXriiSfO+AnNYg1VnIvy5cv/aSXTsdWh1vdO9zN/nPhqDUFaK4NP9zN23OcPPvjADJPedNNN5/3/s17kj/VAlUSAuJhjatVq/f2tFbTWp/M/so6JNYRhfbI/sRfQOs7Fdbwu9v5Zi1Suuuoq8+byz3/+0+OP3+lYQ9IBAQF/WnF9pr+9df353N4T9O7d+/hisPPtBQoKCjJTGaxj5Q2s51Dt2rVPW683Hj+LtZBj5syZ591r7m3H79hxsI6J9UHxGKvduHHjInse43cEwCIUHx9vLkXB+iRnbRVjBbpjw7rWKjBrlVf9+vVP+zNWmLDmRDRr1sxcN2vWLDMEdOyN1+77bM39tQLg3XffbV6gzldKSor5euILhKceU6tWaz7KH4flj7GOkfU3+P777832LxZreNSax3TiJ3lPuX9Wz58V/qy6rWNo3TdPP36nY/XOWvfD+ttbK0Et1vPEaluh6VSsY2J93xpOPcZ6TpbUsTof1vPMWoE+efJkswWTtdr+fFlDa8uXL1eHDh3kDaz5b1bP8l133eX1x+9E1nPNeg2xdoXw5eNnPUat0GYdo2OBz5rzbs1fP91uGRfyPMYJTlgQghK0detW95IlS9yDBw92R0ZGmn9bl8zMTPP9goICd1JSkrtt27bulJQU9zfffGNWzQ4aNOj47/jll1/cderUce/YseP4de3atXM3adLEfG/evHnuWrVquXv06OH2FDNnzjSrv6zVrn9k3Q/r/li1WzZs2GBWCS9cuNC9efNm99SpU93Vq1d3t27d2u1pfv75Z7MC2DpWGzdudH/yySfmeN19992nvX+Whx9+2F25cmX3rFmzzP1s2bKluXgaq/aaNWu6r7nmGvPvXbt2Hb946/EbN26cWWH44YcfmhX0Dz30kDs2Nvb4yvu77rrL/fTTTx+//U8//eQODAx0jxgxwjx+rVWo1iru5cuXuz3NI488YlaEzp49+6RjlZ2dffw2f7x/1mvRt99+ax6/ixYtct92223u0NBQ98qVK92e6IknnjD3z3psWcfm2muvdZcpU8asePb243fiilbr9WHgwIF/+p43Hj/r/e3Ye531PvDaa6+Zf1vvh5bhw4eb56D1WrFs2TJ3p06dzE4DR44cOf47rr76aveoUaPO+XmM0yMA2uSee+4xT4A/Xn744Yfjt9myZYu7ffv27rCwMPPCZr3g5efnH/++dVvrZ6wXwGP2799vAp8VKq0tY+67777jodITWLW1atXqlN+z7seJf4Nt27aZsBAXF2ee4FYAGTBggDs9Pd3taawXXGtLCetN13rRrVevnvvFF1905+TknPb+WawXtkcffdRdqlQpd3h4uPvmm28+KVR5CmuLiVM9Xk/8DOmNx896I7HeYIODg812EgsWLDhpCxvreXqiCRMmuGvXrm1u36BBA/eXX37p9kSnO1bWcTzd/evbt+/xv0W5cuXcHTp0cC9evNjtqbp37+6uUKGCqbdSpUqmbX3o8IXjd4wV6Kzjtnbt2j99zxuP37H3rD9ejt0PayuYZ5991tRvvWZYHzj/eN+t7bas8H6uz2Ocnp/1nxN7BAEAAODb2AcQAADAYQiAAAAADkMABAAAcBgCIAAAgMMQAAEAAByGAAgAAOAwBEAAAACHIQACAAA4DAEQAADAYQiAAAAADkMABAAAcBgCIAAAgMMQAAEAAByGAAgAAOAwBEAAAACHIQACAAA4DAEQAADAYQiAAAAADkMABAAAcBgCIAAAgMMQAAEAAByGAAgAAOAwBEAAAACHIQACAAA4DAEQAADAYQiAAAAADkMABAAAcBgCIAAAgMMQAAEAAByGAAgAAOAwBEAAAAA5y/8D6yuJBpv+RsMAAAAASUVORK5CYII=", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure()\n", + "DetailedBalanceT1=detailed_balance_factor(x,temperature=300.0)\n", + "\n", + "plt.plot(x,DetailedBalanceT1, label='Detailed Balance Factor at T=300 K')" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "47653f60", + "metadata": {}, + "outputs": [ + { + "ename": "TypeError", + "evalue": "detailed_balance_factor() got an unexpected keyword argument 'temperature_K'", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mTypeError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[8]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43mdetailed_balance_factor\u001b[49m\u001b[43m(\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43mtemperature_K\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m10.0\u001b[39;49m\u001b[43m)\u001b[49m\n", + "\u001b[31mTypeError\u001b[39m: detailed_balance_factor() got an unexpected keyword argument 'temperature_K'" + ] + } + ], + "source": [ + "detailed_balance_factor(0,temperature_K=10.0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2c0db4ac", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "91fab918d2644308a604cf7abf1918a9", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAbrJJREFUeJzt3Qd8E+UbB/Cnu8yyp2xkT0EQVBABEfgjOFlCmYqgoihLNspQkSEiCMgSkKGAAwSVjSxZsqfsPdvS0n3/z++lF5M0aVNocmny+34+gebyJnnvLrl78rzjfDRN04SIiIiIvIav0RUgIiIiItdiAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASEREReRkGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASEREReRkGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASeYhnnnlG3R6Ej4+PDB8+PN3rRERE7okBILmVOXPmqGDE3m379u3izQ4fPqwCtTNnzrj8vfGe9vbLE088ke7vN3r0aFmxYoV4ig0bNqT42V60aJHRVXQLX3/9tToOpKZTp04pbk/9hnIP4/fff5euXbtKpUqVxM/PT4oXL263bGJionz22WdSokQJCQ4OlipVqsj333/v0Pvge4363rhxw2L5+fPnpVSpUpIrVy7Zs2fPQ60LkTl/i3tEbmLkyJHqIGqtdOnS4u0B4IgRI1Smz/pEhBOVK7Rt21aaNWtmsSxv3rxOCQBfeeUVadWqlXiSd999Vx5//PFky+vUqWNIfdwxAMyTJ0+qgdubb74pjRo1Mt0/ffq0DB06VN544w15+umnTcsRPD2MhQsXyuLFi+Wxxx6TQoUKpVh20KBBMnbsWOnevbvaxz/99JO0a9dOBXZt2rRJ83tfvHhRGjRoILdu3ZI///xT1YEovTAAJLfUtGlTqVmzptHVyFACAwNd8j44Cb3++uuSEUVGRkqW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", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "k_B = 8.617333262145e-2 # meV/K\n", + "T=1\n", + "\n", + "E=np.linspace(-10, 10, 1000)\n", + "y=np.exp(E/2/k_B/T)\n", + "y2=detailed_balance_factor(E, temperature=T)\n", + "plt.figure()\n", + "plt.plot(E, y, label='Exponential Factor at T=10 K')\n", + "plt.plot(E, y2/k_B/T, label='Detailed Balance Factor at T=10 K', linestyle='--')\n", + "plt.xlabel('Energy (meV)')\n", + "plt.ylabel('Exponential Factor')\n", + "plt.title('Exponential Factor vs Energy at T=10 K')\n", + "plt.legend()\n", + "plt.show()\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "EasyQENSDev", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.11" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/convolution_example .ipynb b/examples/convolution_example .ipynb new file mode 100644 index 0000000..b182c87 --- /dev/null +++ b/examples/convolution_example .ipynb @@ -0,0 +1,959 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "64deaa41", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "from easydynamics.sample import Gaussian\n", + "from easydynamics.sample import Lorentzian\n", + "from easydynamics.sample import Voigt\n", + "from easydynamics.sample import DampedHarmonicOscillator\n", + "from easydynamics.sample import Polynomial\n", + "from easydynamics.sample import SampleModel\n", + "from easydynamics.sample import DeltaFunction\n", + "\n", + "from scipy.special import voigt_profile\n", + "\n", + "from easydynamics.resolution import ResolutionHandler\n", + "\n", + "import matplotlib.pyplot as plt\n", + "\n", + "\n", + "from easyscience.variable import Parameter\n", + "%matplotlib widget\n", + "plt.close('all')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "5c5b3e0a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0, 0.5, 'y')" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "41eccceef6364906b2871305aa7714ef", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAZtNJREFUeJzt3Qd8k3X+B/BPdpq06aK7pey9BAQBB7hwj/Nc50BPz3FuPQfnnetUPM91w/P0/iqOcytuHKCAgICykb2hg+4kTZv9/F+/X2hoSwstTZs0z+f9eqVP8uSX5/k9eZon3/ymRlEUBURERESkGtpoZ4CIiIiIuhYDQCIiIiKVYQBIREREpDIMAImIiIhUhgEgERERkcowACQiIiJSGQaARERERCrDAJCIiIhIZRgAEhEREakMA0AiIiIilWEASERERKQyDACJiIiIVIYBIBEREZHKMAAkIiIiUhkGgEREREQqwwCQiIiISGUYABIRERGpDANAIiIiIpVhAEhERESkMgwAiYiIiFSGASARERGRyjAAJCIiIlIZBoBEREREKsMAkIiIiEhlGAASERERqQwDQCIiIiKVYQBIREREpDIMAImIiIhUhgEgERERkcowACQiIiJSGQaARERERCrDAJCIiIhIZRgAEhEREakMA0AiIiIilWEASERERKQyDACJiIiIVIYBIBEREZHKMAAkIiIiUhkGgEREREQqwwCQiIiISGUYABIRERGpDANAIiIiIpVhAEhERESkMgwAiYiIiFSGASARERGRyjAAJCIiIlIZBoBEREREKsMAkIiIiEhlGAASERERqQwDQCIiIiKVYQBIREREpDIMAImIiIhUhgEgERERkcowACQiIiJSGVUHgA899BA0Gk2T26BBg6KdLSIiIqJOpYfKDR06FHPmzAk/1utV/5YQERFRnFN9tCMCvuzs7CN6bTAYRHFxMZKSkmTpIREREcU+RVHgdDqRm5sLrVadlaGqDwC3bNki/wHMZjMmTJiAGTNmoGfPni2m9Xg88tagqKgIQ4YM6cLcEhERUaTs2bMH+fn5UCONIsJglZo9ezZqa2sxcOBAlJSU4OGHH5ZB3bp162SpXkttBkWalv6BbDZbF+WaiIiIOsLhcKCgoAA1NTVITk6GGqk6AGxO/CMUFhbimWeewTXXXHPYEsCGfyC73c4AkIiIqJtwOBwy8FPz97fqq4AbS0lJwYABA7B169YWnzeZTPJGRERE1J2ps+VjK0R18LZt25CTkxPtrBARERF1GlUHgH/4wx8wf/587Ny5E4sXL8b5558PnU6HSy+9NNpZIyIiIuo0qq4C3rt3rwz2KisrkZGRgWOPPRZLliyR94mIYlUgEIDP54t2NohilijMEcO8cYi21qk6AHznnXeinQUionY3VRE/Xtl/j+jQLBaLbNJlNBqjnZWYpOoAkIiou5X8ieBPfLGJmgqWbhAdTPw48nq9KC8vx44dO9C/f3/VDvZ8KAwAiYi6CVHtK77cRPCXkJAQ7ewQxSzx+TAYDNi1a5cMBsVkD9QUQ2Iiom6GJX9Eh8dSv0Pju0NERESkMgwAiYgoLkyePBm33357h7YhhgUTJayrVq2KWL7E9j7++GN0Z5F8X+Lh/YgHDACJiEiVrrrqKpx33nlN1onpPcXc8MOGDYtavuLFQw89hFGjRh20Xry/p59+elTyRAewEwgREVGj8eOys7OjnY24xvc3NrAEkIjoCLjqnHj49Uvwp1cvQK3LHu3sxLSvvvpKDrQv5ltPT0/HWWedJafdbF69+NFHH2HKlClymJuRI0fixx9/DKcRA/aLgfvz8vLk88OHD8fbb7/d6j4feeSRFkvxRInUn//8Z1k69dprr+GTTz6R+xa3efPmtVjV+csvv8g822w2JCUl4bjjjgvn/6effsIpp5yCHj16IDk5GSeccAJWrFjRrvcnGAziySefRL9+/eR88z179sRjjz0Wfn7t2rU48cQTZc9W8f5dd911cjzI5iWZTz31lBz3TqS56aabwoOF//GPf8T48eMP2q94j8X71JAHcT8/P1/mQbxP4ry1ZubMmfJ8NiaqdRs6KInnH374YaxevTr8/op1LVUBd/T46MgwACQiOgIPv30JPlB+QbW9CE99sz0qeRBDwtR5/VG5tWcgapfLhTvvvBM///wz5s6dK3tniqk3RdDR2P333y+n6BTB14ABA2TA5/f75XNutxtjxozBF198gXXr1skg4YorrsCyZcta3Odvf/tbbNiwQQZoDVauXIk1a9bg6quvlvu56KKLcNppp8kqSXGbOHHiQdspKirC8ccfL4Oi7777DsuXL5fbbsiX0+nEtGnTsHDhQjmTlBhz7owzzpDr22r69Ol44oknZGC6fv16vPXWW8jKygq/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u91uxWKxKIsXL26y/pprrlEuvfTS8OP33ntPMZvNyn333ScDORHENWgIAEWw1qCyslJJSEhQ3n333fD2rrvuuib7+OGHHxStVivfLxHkiG18++23LeazYR+Ng7a25H369OnKkCFNz/W9997bpgDw9ttvb7LupJNOUh5//PEm69544w0lJydH3n/66aeVAQMGhIPelrbZ1gCwtWOOJwwAD41tAImIDiEYCOBnqwd+jQa3mg/faqYwdxjGfz4MHn8SvL4AjAYd1Gzr1q2oq6vDKaec0mS91+vFUUcdFX584YUXYtasWXjiiSdk1Wj//v0P2taECRPC99PS0jBw4EBs2LBBPl69ejXWrFmD//3vf+E0IiYSVbg7duzA2rVrodPpcMIJJ0Q072L/48ePbzWfhzJ27Ngmj8UxLFq0KFwdLAQCAbjdbpkP8R4999xzsmr4tNNOwxlnnIGzzz4bej2/yqn9+F9DRHQIztpqTK+shl2rRUFmv8Om75GahbmOyyHKY+xuPzK6IABc+pulcpmgTwivu3ro1bh88OXQa5te5uddNE8uzXpzeN0lgy7BBf0vgE7bNK9fXfDVQWnP7Xduu/JWW1srl6L9Xl5eXpPnRDu2BiLAWb58uQzStmzZ0q59NOzn+uuvb9ImroFoMyeCuSPZZlvyfqRE27/m+xNt/n71q18dlFa0CRRtFzdt2oQ5c+bg22+/xe9//3v87W9/w/z582UHEtGOr6EdZePOJUQtYQBIRHQIdTWVuMhZC49igDEx1MP3UHRaDWxmA+z1PtjrvchI6nigcDgWw8HzDht0BnlrU1qtQd7amrY9hgwZIoOl3bt3H7L07a677oJWq8Xs2bNlydaZZ56JE088sUmaJUuWyGBOqK6uxubNmzF48GD5WHScWL9+vezY0ZLhw4fL0kARLIlOJ80ZjcZwiVt78i72/+mnnx6UzyMhjkEEeK0dgyA6mohSP3G76aabMGjQIFm6KV6bkZGBkpKScFoRSIvAujUtHTOpBwNAIqJDcNWUy6Vdk4RMbdsGThiWuAxuwx4UlfZAv8ym1YNqk5SUhD/84Q+44447ZAB27LHHwm63y6pOm82GadOmyRK2V155BT/++KMMZO6++265XlTpih6qDR555BGkp6cjKysL999/P3r06IHzzjtPPid694qewTfffDOuvfZaWbomAkJRUvav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XXWu2kN8zkQP9FmzZskhmERv+/YSVWtr167FGWecge5AtH8TJctXXHFFtz9/jYnPmriGiFEh4vn8if9REbSJc9QQ8Ik276L9emujZRzJ55gaadQhhLrQrl27lJUrVyoPP/ywkpiYKO+Lm9PplM/7/X5l2LBhyqmnnqqsWrVK+eqrr2Sv2enTp4e3sXTpUmXgwIHK3r17w+tOO+005aijjpLPLVy4UOnfv79y6aWXKrFizpw5sveX6O3anDgOcTwi78LWrVtlL+Gff/5Z2bFjh/LJJ58offr0UY4//ngl1ixevFj2ABbnatu2bcqbb74pz9eVV17Z6vEJN9xwg9KzZ0/lu+++k8c5YcIEeYs1Iu/9+vVTTjrpJHm/pKQkfOuu5++dd96RPQxnzpwpe9Bfd911SkpKSrjn/RVXXKHcd9994fSLFi1S9Hq98tRTT8n/X9ELVfTiXrt2rRJrbrzxRtkjdN68eU3OVV1dXThN8+MT16Kvv/5a/v8uX75cueSSSxSz2az88ssvSiy666675PGJ/y1xbk4++WSlR48essdzdz9/jXu0iuvDvffee9Bz3fH8ie+3hu868T3wzDPPyPvi+1B44okn5GdQXCvWrFmjnHvuuXKkgfr6+vA2TjzxROWf//xnmz/H1DoGgFEybdo0+QFofvv+++/DaXbu3KmcfvrpSkJCgrywiQuez+cLPy/SiteIC2CDyspKGfCJoFIMGXP11VeHg8pYIPI2ceLEFp8Tx9H4Pdi9e7cMFtLS0uQHXAQgd999t2K325VYIy64YkgJ8aUrLrqDBw9WHn/8ccXtdrd6fIK4sP3+979XUlNTFYvFopx//vlNgqpYIYaYaOn/tfFvyO54/sQXifiCNRqNcjiJJUuWNBnCRnxOG3vvvfeUAQMGyPRDhw5VvvjiCyUWtXauxHls7fhuv/328HuRlZWlnHHGGcqKFSuUWHXxxRcrOTk5Mr95eXnysfjREQ/nr4EI6MR527Rp00HPdcfz1/Cd1fzWcBxiKJg///nPMv/imiF+cDY/djHclgje2/o5ptZpxJ/GJYJEREREFN84DiARERGRyjAAJCIiIlIZBoBEREREKsMAkIiIiEhlGAASERERqQwDQCIiIiKVYQBIREREpDIMAImIiIhUhgEgERERkcowACQiIiJSGQaARET7lZeXIzs7G48//nh43eLFi2E0GjF37tyo5o2IKJI4FzARUSNffvklzjvvPBn4DRw4EKNGjcK5556LZ555JtpZIyKKGAaARETN3HTTTZgzZw7Gjh2LtWvX4qeffoLJZIp2toiIIoYBIBFRM/X19Rg2bBj27NmD5cuXY/jw4dHOEhFRRLENIBFRM9u2bUNxcTGCwSB27twZ7ewQEUUcSwCJiBrxer0YN26cbPsn2gA+99xzsho4MzMz2lkjIooYBoBERI3cfffd+OCDD7B69WokJibihBNOQHJyMj7//PNoZ42IKGJYBUxEtN+8efNkid8bb7wBm80GrVYr7//www944YUXop09IqKIYQkgERERkcqwBJCIiIhIZRgAEhEREakMA0AiIiIilWEASERERKQyDACJiIiIVIYBIBEREZHKMAAkIiIiUhkGgEREREQqwwCQiIiISGUYABIRERGpDANAIiIiIpVhAEhEREQEdfl/OEEuQ/nSzWYAAAAASUVORK5CYII=", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "offset=Parameter('offset', 0.1)\n", + "\n", + "sample_gauss = Gaussian(center=0.1, width=0.3, area=2)\n", + "resolution_gauss = Gaussian(center=0.2, width=0.4, area=3)\n", + "\n", + "resolution_handler= ResolutionHandler()\n", + "\n", + "x = np.linspace(-10, 10, 10000)\n", + "\n", + "# THEN\n", + "analytical_convolution = resolution_handler.convolve(x=x,sample_model=sample_gauss, resolution_model=resolution_gauss,offset=offset,method='analytical')\n", + "numerical_convolution = resolution_handler.convolve(x=x,sample_model=sample_gauss, resolution_model=resolution_gauss,offset=offset,method='numerical')\n", + "\n", + "\n", + "\n", + "#EXPECT\n", + "expected_width = np.sqrt(sample_gauss.width.value**2 + resolution_gauss.width.value**2)\n", + "expected_area = sample_gauss.area.value * resolution_gauss.area.value\n", + "expected_center = sample_gauss.center.value + resolution_gauss.center.value + offset.value\n", + "expected_result = expected_area * np.exp(-0.5 * ((x - expected_center) / expected_width)**2) / (np.sqrt(2 * np.pi) * expected_width)\n", + "\n", + "\n", + "\n", + "plt.figure()\n", + "plt.plot(x, analytical_convolution, label='analytical convolution')\n", + "plt.plot(x, numerical_convolution, label='numerical convolution', linestyle='--')\n", + "plt.plot(x, expected_result, label='expected result', linestyle=':')\n", + "plt.legend()\n", + "plt.xlabel('x')\n", + "plt.ylabel('y')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "dd5c529e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "10eb3fc1fd864691b5a2e8d3425bbc99", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAa7hJREFUeJzt3Qd4FOXaBuBne3rvnRJ67x0RFBFRPPajAvb6K2LF3rEeGyp2bNgFFEUFpPfeCYSE9N57tsx/fRMTE0ggIWV2d577uobJzs7OvDMJu+9+VSNJkgQiIiIiUg2t0gEQERERUcdiAkhERESkMkwAiYiIiFSGCSARERGRyjABJCIiIlIZJoBEREREKsMEkIiIiEhlmAASERERqQwTQCIiIiKVYQJIREREpDJMAImIiIhUhgkgERERkcowASQiIiJSGSaARERERCrDBJCIiIhIZZgAEhEREakME0AiIiIilWECSERERKQyTACJiIiIVIYJIBEREZHKMAEkIiIiUhkmgEREREQqwwSQiIiISGWYABIRERGpDBNAIiIiIpVhAkhERESkMkwAiYiIiFSGCSARERGRyjABJCIiIlIZJoBEREREKsMEkIiIiEhlmAASERERqQwTQCIiIiKVYQJIREREpDJMAImIiIhUhgkgERERkcowASQiIiJSGSaARERERCrDBJCIiIhIZZgAEhEREakME0AiIiIilWECSERERKQyTACJiIiIVIYJIBEREZHKMAEkIiIiUhkmgEREREQqwwSQiIiISGWYABIRERGpDBNAIiIiIpVhAkhERESkMkwAiYiIiFSGCSARERGRyjABJCIiIlIZJoBEREREKsMEkIiIiEhlmAASERERqYxe6QAcmc1mQ3p6Ojw9PaHRaJQOh4iIiJpBkiSUlJQgLCwMWq06y8KYALaCSP4iIyOVDoOIiIjOQkpKCiIiIqBGTABbQZT81f4BeXl5KR0OERERNUNxcbFcgFP7Oa5GTABbobbaVyR/TACJiIgci0bFzbfUWfFNREREpGJMAImIiIhUhgkgERERkcqwDWAHdDW3WCywWq1Kh0JktwwGA3Q6ndJhEBGpBhPAdlRdXY2MjAyUl5crHQqR3TfEFkMxeHh4KB0KEZEqMAFsx0GiExMT5VINMdCk0WhUdW8jotOVkufk5CA1NRWxsbEsCSQi6gBMANux9E8k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M7JXr14NtvXs2RPJycmKxeSMRHWNKAW8+uqr5Z6Sogrnvvvuw7x585QOzamFhITI66ysrAbbxePa56jtk7+kpCSsWLGCpX9tbP369cjOzkZUVJRcCigWca/vv/9+xMTEKB0edTAmgNQqogew6K1Xn2inFh0drVhMzkj0ktRqG/53FVXBogSW2o8YdkckeqL9ZS1RFS96A48cOVLR2Jw1+RND7KxcuVIeVoralvjiuG/fPrkGoXYRtQjiC+aff/6pdHjUwVgFTK0iSqFEBwVRBSzevLdt24YPP/xQXqjtiHG9RJs/8c1dVAHv3r0b//vf/3DjjTcqHZrDKy0tRXx8fIOOH+KD0c/PT77foqr9+eefR2xsrJwQiqFKxIfm9OnTFY3bme6zqEm4/PLL5arJZcuWyW1ca9tYiudFm2Jqm7/nkxNrMYSX+JLTvXt3BaIlRSncC5mcwK+//ir16dNHHhqjR48e0ocffqh0SE6nuLhYuvfee6WoqCjJxcVF6ty5s/TYY49JVVVVSofm8FavXi0Pl3HyMnPmzLqhYJ544gkpODhY/hufOHGiFBcXp3TYTnWfExMTG31OLOJ11HZ/zyfjMDDqpRH/KJuCEhEREVFHYhtAIiIiIpVhAkhERESkMkwAiYiIiFSGCSARERGRyjABJCIiIlIZJoBEREREKsMEkIiIiEhlmAASERERqQwTQCIiIiKVYQJIREREpDJMAImIiIhUhgkgERERkcowASQiIiJSGSaARERERCrDBJCIiIhIZZgAEhEREakME0AiIiIilWECSERERKQyTACJiIiIVIYJIBEREZHKMAEkIiIiUhkmgEREREQqwwSQiIiISGWYABIRERGpDBNAIiIiIpVhAkhERESkMkwAiYiIiFSGCSARERGRyjABJCIiIlIZJoBEREREKsMEkIiIiAjq8v9JN1wQCfwNuQAAAABJRU5ErkJggg==", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "#WHEN\n", + "\n", + "x = np.linspace(5, 15, 1000)\n", + "\n", + "sample_gauss = Gaussian(center=10, width=0.3, area=2)\n", + "resolution_lorentzian = Lorentzian(center=0.2, width=0.4, area=3)\n", + "\n", + "resolution_handler = ResolutionHandler()\n", + "\n", + "# THEN\n", + "analytical_convolution = resolution_handler.convolve(x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, offset=0.4, method='analytical')\n", + "numerical_convolution = resolution_handler.convolve(x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, offset=0.4, method='numerical',upsample_factor=5)\n", + "\n", + "#EXPECT\n", + "expected_center = sample_gauss.center.value + resolution_lorentzian.center.value + 0.4\n", + "expected_area = sample_gauss.area.value * resolution_lorentzian.area.value\n", + "expected_result = expected_area * voigt_profile(\n", + " x - expected_center,\n", + " sample_gauss.width.value,\n", + " resolution_lorentzian.width.value\n", + ")\n", + "\n", + "plt.figure()\n", + "plt.plot(x, analytical_convolution, label='analytical convolution')\n", + "plt.plot(x, numerical_convolution, label='numerical convolution', linestyle='--')\n", + "plt.plot(x, expected_result, label='expected result', linestyle=':')\n", + "plt.legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "1dce52fc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "8979137297da45c583b39a41cde5a307", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "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NmlXr17Vjh49qvXv31+zs7PTzp49qxki8bnK/IyJr7Lvv/9eXhafQ0Hsm9jHTNeuXdMcHBy09957T75/06dP1ywtLbWNGzdqhiq/+zht2jRt1apV2uXLl+XvpRiBb2FhIf/vNESjRo2SI8937tyZ43svMTExaxtj/xwaMgZAAyBOvyA+3A9bMokvUHFdDPPPJELCa6+9prm5ucn/2J599tkcodHQiFO6PGwfs++TuC5eD0H8J9ChQwfN09NTfsADAgK0l19+OesLzNj3L/NUMJ988onm7e0tv6zFHwEXL17UDFFkZKQMfCLcOjs7a8OGDcsRbu//HQ0MDJRhz93dXe6b+CNHfPnGxMRohuLnn3+Wf0TZ2NjI06YcOHAgxylsxHua3V9//aVVrFhRbi9OKbJu3TrNkOVn/956662sbcXvY5cuXbRjx45phirzlCf3L5n7JH6Kfbz/PrVr15b7KP4Yyf5ZNET53cdvvvlGK1eunAzu4nPXunVr2UBgqHL73sv+vpjC59BQ6cQ/qlshiYiIiKjocBQwERERkZlhACQiIiIyMwyARERERGaGAZCIiIjIzDAAEhEREZkZBkAiIiIiM8MASERERGRmGACJiIiIzAwDIBEREZGZYQAkIiIiMjMMgERERERmhgGQiIiIyMwwABIRERGZGQZAIiIiIjPDAEhERERkZhgAiYiIiMwMAyARERGRmWEAJCIiIjIzDIBEREREZoYBkIiIiMjMMAASERERmRkGQCIiIiIzwwBIREREZGYYAImIiIjMDAMgERERkZlhACQiIiIyMwyARERERGaGAZCIiIjIzDAAEhEREZkZBkAiIiIiM8MASERERATz8n+8HiWD7S3gVgAAAABJRU5ErkJggg==", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "#WHEN\n", + "\n", + "x = np.linspace(-2, 2, 1000)\n", + "\n", + "sample_gauss = Gaussian(center=0, width=0.5, area=2)\n", + "resolution_lorentzian = Lorentzian(center=0.2, width=0.4, area=3)\n", + "\n", + "resolution_handler = ResolutionHandler()\n", + "\n", + "# THEN\n", + "analytical_convolution = resolution_handler.convolve(x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, offset=0.4, method='analytical')\n", + "numerical_convolution = resolution_handler.convolve(x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, offset=0.4, method='numerical',upsample_factor=5)\n", + "\n", + "#EXPECT\n", + "expected_center = sample_gauss.center.value + resolution_lorentzian.center.value + 0.4\n", + "expected_area = sample_gauss.area.value * resolution_lorentzian.area.value\n", + "expected_result = expected_area * voigt_profile(\n", + " x - expected_center,\n", + " sample_gauss.width.value,\n", + " resolution_lorentzian.width.value\n", + ")\n", + "\n", + "plt.figure()\n", + "plt.plot(x, analytical_convolution, label='analytical convolution')\n", + "plt.plot(x, numerical_convolution, label='numerical convolution', linestyle='--')\n", + "plt.plot(x, expected_result, label='expected result', linestyle=':')\n", + "plt.legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "640097cc", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.020000000000000018\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "5a377490c2b24fba87a8e1a11ad07c5a", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "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cUo2QhoNanU6oJkJIFG84omgKa5PHh0MBmG32+WFIsNiscgLqYkCr24MBrlqMCBnRLdHphQfAdOnxbhM8y2U5jJoohYjER0KtgBSN1OnTsVNN92EWbNmIT09Hbm5ubIrscP27duh0WiwatWqzm3Nzc1y24IFC+R9cS3uf/755xg3bpxMHo4//njU1tbis88+w7Bhw+Ti27/61a/Q1tbWWU4oFMLs2bPRr18/+ZwxY8bg3Xff7Xy8o1xRxvjx42EymfDtt9/usavzpZdewogRI+Q+eXl5uOGGGzof+9Of/oRRo0bBZrOhqKgI1113HVwuV49ep507d2LGjBnyNRLlTJgwAcuWLet8/Pnnn8eAAQNgNBoxZMgQvPrqq92eL47jH//4B8455xxYrVYMGjQI//nPfzpfh8LCQllGVytXroRWq8WOHTvk/bKyMpx11lky+RWv5/nnn4+ampp9vre33HJLt21nn302Lr300s7HRdm33nqrjE9c9tYFfCjHR3HAlonloVlYUX4/phWf3O2h/hlpcARy5JeHr4nrARPFKyaA0eBr3fvF7+nBvu7973sQ/vWvf8mkRiQ0TzzxBB5++GF88cUXPS5HJGbPPvssFi9ejPLycpmgiO7FN954A5988gn++9//4q9//Wvn/iL5e+WVV/D3v/8d69atk4nIxRdfjIULF3Yr9+6778Zjjz2GDRs2YPTo0bvVK5KT66+/HldddRXWrFkjE4+BA38+jYVIov7yl7/IOsSxfvXVVzLhPVAiWZwyZQoqKipk2T/++KN8vkjchPfffx8333wzbr/9dqxduxZXX301LrvsMnz99dfdynnooYfka7J69WqceuqpuOiii9DY2CjjE8mleJ26ev3113HUUUehT58+si6R/In9xesj3p9t27bJ7tqD9d5778nEU7zfVVVV8rInh3p8FB92NrX/OCtM6976azHq8LH5dIz3PI8tE38fpeiI6JApdNBaWlrEWkjyeldut1tZv369vN7NA8l7v7z2y+77PpK7931fOrX7vo/3232fHpoyZYpy9NFHd9s2ceJE5a677pK3S0tL5TGvXLmy8/Gmpia57euvv5b3xbW4P3/+/M59Zs+eLbdt3bq1c9vVV1+tTJ8+Xd72eDyK1WpVFi9e3K3uK664QpkxY0a3cj/44IPuL+cDDyhjxozpvJ+fn6/87ne/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AcriA/viiy/u83m5ubmym6e5ublbK6CYBSwei9VjPFSiLNGdKFpJp02bhng+vo73Sbxn4pd7B3FffAn3hgM9PhHrrpMHAoGAnBnck/9vontbEO+fmO0eLeL/kGhB3nXW/L4+P2J7T/aPpoM5vl0ZDAaMGzdOvleJYG/vn5j4kgitf3tz+OGH49tvv0Usu+GGGzonlu2vtTmePoexjglgBIlfz+JyIETLn0j+xC+3OXPmyPE6+yL2E3+gv/zyS3n6F0F0rZWVlclf8rF4jOGwc+dOOQawa8IUr8cnurXFHy3xHnYkfKI7SnTX9HSmdKSPT/yfEj82xLgy8X9P+Oqrr2S3TUdSdyDE7Euht96/vRHDJ8RxiNdetCwL4ljEffFltLfXQDwuuqk6iJmLvfl5i+Tx7Up0Ia9ZswannnoqEoF4n3Y9XUisvn/hJD5z0f687Y2Y23LjjTfKXgHRqyP+Ju5PPH0OY160Z6GQouzcuVMZOHCgMm3aNHm7qqqq89J1nyFDhijLli3r3HbNNdcoxcXFyldffaV8//33yuTJk+UlVu3YsUNZuXKl8tBDDyl2u13eFhen09m5jzjG9957T94W2++44w45q7m0tFSZP3++cthhhymDBg1SPB6PEu/HJzz22GNKamqq8uGHHyqrV6+WM57F7G+3263EmpNPPlkZN26c/D/47bffyvdhxowZe/0/WlJSojz88MPy/6Z4/8Qx9u/fXzn22GOVWPDWW2/JGdcvv/yynOV81VVXyfeiurpaPn7JJZcod999d+f+ixYtUvR6vfLkk0/KGfcPPPCAnIm/Zs0aJRb19PjE/9vPP/9c2bp1q/LDDz8oF154oWI2m5V169YpsUh8rjo+Y+Kr7E9/+pO8LT6Hgjg2cYwdtm3bplitVuXOO++U799zzz2n6HQ6Zd68eUqs6ukxPv3008oHH3ygbNmyRf6/FDPwtVqt/NsZi6699lo583zBggXdvvfa2to694n3z2EsYwIYA8TpF8SHe0+XDuILVNwX0/w7iCThuuuuU9LS0uQftnPOOadb0hhrxCld9nSMXY9J3BevhyD+CJx00klKVlaW/ID36dNHufLKKzu/wOL9+DpOBXPfffcpOTk58sta/AjYtGmTEosaGhpkwieS2+TkZOWyyy7rltzu+n+0rKxMJnvp6eny2MSPHPHl29LSosSKv/71r/JHlNFolKdNWbp0abdT2Ij3tKt33nlHGTx4sNxfnFLkk08+UWJZT47vlltu6dxX/H889dRTlRUrViixquOUJ7teOo5JXItj3PU5Y8eOlccofox0/SzGop4e4+OPP64MGDBAJu7iczd16lTZQBCr9va91/V9SYTPYazSiH+i3QpJRERERL2Hs4CJiIiIVIYJIBEREZHKMAEkIiIiUhkmgEREREQqwwSQiIiISGWYABIRERGpDBNAIiIiIpVhAkhERESkMkwAiYiIiFSGCSARERGRyjABJCIiIlIZJoBEREREKsMEkIiIiEhlmAASERERqQwTQCIiIiKVYQJIREREpDJMAImIiIhUhgkgERERkcowASQiIiJSGSaARERERCrDBJCIiIhIZZgAEhEREakME0AiIiIilWECSERERKQyTACJiIiIVIYJIBEREZHKMAEkIiIiUhkmgEREREQqwwSQiIiISGWYABIRERGpDBNAIiIiIqjL/wPLKw2hjVPlEAAAAABJRU5ErkJggg==", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "#WHEN\n", + "\n", + "x = np.linspace(-2, 2, 201)\n", + "\n", + "sample_gauss = Gaussian(center=0, width=0.1, area=2)\n", + "resolution_lorentzian = Lorentzian(center=0.2, width=0.004, area=3)\n", + "\n", + "resolution_handler = ResolutionHandler()\n", + "\n", + "# THEN\n", + "analytical_convolution = resolution_handler.convolve(x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, offset=0.4, method='analytical')\n", + "numerical_convolution = resolution_handler.convolve(x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, offset=0.4, method='numerical',upsample_factor=5)\n", + "\n", + "#EXPECT\n", + "expected_center = sample_gauss.center.value + resolution_lorentzian.center.value + 0.4\n", + "expected_area = sample_gauss.area.value * resolution_lorentzian.area.value\n", + "expected_result = expected_area * voigt_profile(\n", + " x - expected_center,\n", + " sample_gauss.width.value,\n", + " resolution_lorentzian.width.value\n", + ")\n", + "\n", + "print(x[1]-x[0])\n", + "\n", + "plt.figure()\n", + "plt.plot(x, analytical_convolution, label='analytical convolution')\n", + "plt.plot(x, numerical_convolution, label='numerical convolution', linestyle='--')\n", + "plt.plot(x, expected_result, label='expected result', linestyle=':')\n", + "plt.legend()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "3ae40370", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "ad31424efda34a789ed7532489989a85", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "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cUo2QhoNanU6oJkJIFG84omgKa5PHh0MBmG32+WFIsNiscgLqYkCr24MBrlqMCBnRLdHphQfAdOnxbhM8y2U5jJoohYjER0KtgBSN1OnTsVNN92EWbNmIT09Hbm5ubIrscP27duh0WiwatWqzm3Nzc1y24IFC+R9cS3uf/755xg3bpxMHo4//njU1tbis88+w7Bhw+Ti27/61a/Q1tbWWU4oFMLs2bPRr18/+ZwxY8bg3Xff7Xy8o1xRxvjx42EymfDtt9/usavzpZdewogRI+Q+eXl5uOGGGzof+9Of/oRRo0bBZrOhqKgI1113HVwuV49ep507d2LGjBnyNRLlTJgwAcuWLet8/Pnnn8eAAQNgNBoxZMgQvPrqq92eL47jH//4B8455xxYrVYMGjQI//nPfzpfh8LCQllGVytXroRWq8WOHTvk/bKyMpx11lky+RWv5/nnn4+ampp9vre33HJLt21nn302Lr300s7HRdm33nqrjE9c9tYFfCjHR3HAlonloVlYUX4/phWf3O2h/hlpcARy5JeHr4nrARPFKyaA0eBr3fvF7+nBvu7973sQ/vWvf8mkRiQ0TzzxBB5++GF88cUXPS5HJGbPPvssFi9ejPLycpmgiO7FN954A5988gn++9//4q9//Wvn/iL5e+WVV/D3v/8d69atk4nIxRdfjIULF3Yr9+6778Zjjz2GDRs2YPTo0bvVK5KT66+/HldddRXWrFkjE4+BA38+jYVIov7yl7/IOsSxfvXVVzLhPVAiWZwyZQoqKipk2T/++KN8vkjchPfffx8333wzbr/9dqxduxZXX301LrvsMnz99dfdynnooYfka7J69WqceuqpuOiii9DY2CjjE8mleJ26ev3113HUUUehT58+si6R/In9xesj3p9t27bJ7tqD9d5778nEU7zfVVVV8rInh3p8FB92NrX/OCtM6976azHq8LH5dIz3PI8tE38fpeiI6JApdNBaWlrEWkjyeldut1tZv369vN7NA8l7v7z2y+77PpK7931fOrX7vo/3232fHpoyZYpy9NFHd9s2ceJE5a677pK3S0tL5TGvXLmy8/Gmpia57euvv5b3xbW4P3/+/M59Zs+eLbdt3bq1c9vVV1+tTJ8+Xd72eDyK1WpVFi9e3K3uK664QpkxY0a3cj/44IPuL+cDDyhjxozpvJ+fn6/87ne/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AcriA/viiy/u83m5ubmym6e5ublbK6CYBSwei9VjPFSiLNGdKFpJp02bhng+vo73Sbxn4pd7B3FffAn3hgM9PhHrrpMHAoGAnBnck/9vontbEO+fmO0eLeL/kGhB3nXW/L4+P2J7T/aPpoM5vl0ZDAaMGzdOvleJYG/vn5j4kgitf3tz+OGH49tvv0Usu+GGGzonlu2vtTmePoexjglgBIlfz+JyIETLn0j+xC+3OXPmyPE6+yL2E3+gv/zyS3n6F0F0rZWVlclf8rF4jOGwc+dOOQawa8IUr8cnurXFHy3xHnYkfKI7SnTX9HSmdKSPT/yfEj82xLgy8X9P+Oqrr2S3TUdSdyDE7Euht96/vRHDJ8RxiNdetCwL4ljEffFltLfXQDwuuqk6iJmLvfl5i+Tx7Up0Ia9ZswannnoqEoF4n3Y9XUisvn/hJD5z0f687Y2Y23LjjTfKXgHRqyP+Ju5PPH0OY160Z6GQouzcuVMZOHCgMm3aNHm7qqqq89J1nyFDhijLli3r3HbNNdcoxcXFyldffaV8//33yuTJk+UlVu3YsUNZuXKl8tBDDyl2u13eFhen09m5jzjG9957T94W2++44w45q7m0tFSZP3++cthhhymDBg1SPB6PEu/HJzz22GNKamqq8uGHHyqrV6+WM57F7G+3263EmpNPPlkZN26c/D/47bffyvdhxowZe/0/WlJSojz88MPy/6Z4/8Qx9u/fXzn22GOVWPDWW2/JGdcvv/yynOV81VVXyfeiurpaPn7JJZcod999d+f+ixYtUvR6vfLkk0/KGfcPPPCAnIm/Zs0aJRb19PjE/9vPP/9c2bp1q/LDDz8oF154oWI2m5V169YpsUh8rjo+Y+Kr7E9/+pO8LT6Hgjg2cYwdtm3bplitVuXOO++U799zzz2n6HQ6Zd68eUqs6ukxPv3008oHH3ygbNmyRf6/FDPwtVqt/NsZi6699lo583zBggXdvvfa2to694n3z2EsYwIYA8TpF8SHe0+XDuILVNwX0/w7iCThuuuuU9LS0uQftnPOOadb0hhrxCld9nSMXY9J3BevhyD+CJx00klKVlaW/ID36dNHufLKKzu/wOL9+DpOBXPfffcpOTk58sta/AjYtGmTEosaGhpkwieS2+TkZOWyyy7rltzu+n+0rKxMJnvp6eny2MSPHPHl29LSosSKv/71r/JHlNFolKdNWbp0abdT2Ij3tKt33nlHGTx4sNxfnFLkk08+UWJZT47vlltu6dxX/H889dRTlRUrViixquOUJ7teOo5JXItj3PU5Y8eOlccofox0/SzGop4e4+OPP64MGDBAJu7iczd16lTZQBCr9va91/V9SYTPYazSiH+i3QpJRERERL2Hs4CJiIiIVIYJIBEREZHKMAEkIiIiUhkmgEREREQqwwSQiIiISGWYABIRERGpDBNAIiIiIpVhAkhERESkMkwAiYiIiFSGCSARERGRyjABJCIiIlIZJoBEREREKsMEkIiIiEhlmAASERERqQwTQCIiIiKVYQJIREREpDJMAImIiIhUhgkgERERkcowASQiIiJSGSaARERERCrDBJCIiIhIZZgAEhEREakME0AiIiIilWECSERERKQyTACJiIiIVIYJIBEREZHKMAEkIiIiUhkmgEREREQqwwSQiIiISGWYABIRERGpDBNAIiIiIqjL/wPLKw2hjVPlEAAAAABJRU5ErkJggg==", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "# THEN\n", + "analytical_convolution = resolution_handler.convolve(x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, offset=0.4, method='analytical')\n", + "numerical_convolution = resolution_handler.convolve(x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, offset=0.4, method='numerical',upsample_factor=5)\n", + "\n", + "#EXPECT\n", + "expected_center = sample_gauss.center.value + resolution_lorentzian.center.value + 0.4\n", + "expected_area = sample_gauss.area.value * resolution_lorentzian.area.value\n", + "expected_result = expected_area * voigt_profile(\n", + " x - expected_center,\n", + " sample_gauss.width.value,\n", + " resolution_lorentzian.width.value\n", + ")\n", + "\n", + "plt.figure()\n", + "plt.plot(x, analytical_convolution, label='analytical convolution')\n", + "plt.plot(x, numerical_convolution, label='numerical convolution', linestyle='--')\n", + "plt.plot(x, expected_result, label='expected result', linestyle=':')\n", + "plt.legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "c2d7bf2a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "np.float64(0.1)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hasattr(sample_gauss, 'width')\n", + "sample_gauss.width.value" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "5afa23b4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9982fb4ac7b4489e9b1c8c6fa66316b6", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAZ7FJREFUeJzt3Qd4U+X+B/BvkqZJuvcubSl776niYLjRv9c9cC8cuOVex0WvgtvruI6r4t4X3AKiDNl7Q6FQuveeSZOc//O+paVFCi20PUnO9/M86UlOTs75naRJfnmnTlEUBURERESkGXq1AyAiIiKirsUEkIiIiEhjmAASERERaQwTQCIiIiKNYQJIREREpDFMAImIiIg0hgkgERERkcYwASQiIiLSGCaARERERBrDBJCIiIhIY5gAEhEREWkME0AiIiIijWECSERERKQxTACJiIiINIYJIBEREZHGMAEkIiIi0hgmgEREREQawwSQiIiISGOYABIRERFpDBNAIiIiIo1hAkhERESkMUwAiYiIiDSGCSARERGRxjABJCIiItIYJoBEREREGsMEkIiIiEhjmAASERERaQwTQCIiIiKNYQJIREREpDFMAImIiIg0hgkgERERkcYwASQiIiLSGCaARERERBrDBJCIiIhIY5gAEhEREWkME0AiIiIijWECSERERKQxTACJiIiINIYJIBEREZHGMAEkIiIi0hgmgEREREQawwSQiIiISGOYABIRERFpDBNAIiIiIo1hAkhERESkMUwAiYiIiDSGCSARERGRxjABJCIiItIYJoBEREREGsMEkIiIiEhjmAASERERaQwTQCIiIiKNYQJIREREpDFMAImIiIg0hgkgERERkcYwASQiIiLSGC+1A3BnTqcTOTk58Pf3h06nUzscIiIiagNFUVBZWYmYmBjo9dosC2MCeBJE8hcfH692GERERHQCMjMzERcXBy1iAngSRMlf4z9QQECA2uEQERFRG1RUVMgCnMbvcS1iAngSGqt9RfLHBJCIiMi96DTcfEubFd9EREREGsYEkIiIiEhjmAASERERaQzbABIRuRmHw4H6+nq1wyByWQaDAV5eXppu43c8TACJiNxIVVUVsrKy5DhmRNQ6Hx8fREdHw9vbW+1QXBITQCIiNyr5E8mf+GILDw9n6QbRUYgfRzabDYWFhUhLS0PPnj01O9jzsTABJCJyE6LaV3y5ieTPYrGoHQ6RyxLvD6PRiPT0dJkMms1mtUNyOUyJiYjcDEv+iI6PpX7H5rHPzvLly3HBBRfIef7Eh+V3333X4lf0I488goEDB8LX11duc91118mp3YiIiIg8nccmgNXV1Rg8eDDefPPNv9xXU1ODTZs24fHHH5fLefPmISUlBRdeeKEqsRIR0ck7/fTTMWPGjJPax8GDB2WhwZYtWzosriMLIdxRRz4vnvB8eAKPbQN4zjnnyMvRBAYG4rfffmux7o033sCoUaOQkZGBbt26dVGURESkluuvvx5lZWUtkhExP2xubi7CwsJUjc0T/POf/5TP7ZFJo3h+g4ODVYuLPDwBbK/y8nL5qyQoKEjtUIiISMXx46KiotQOw6Px+XUNHlsF3B51dXWyTeCVV16JgICAVrezWq2oqKhocSEi+v6XV/DAe2djb/o2tUNxSQsWLMApp5wif2CHhobi/PPPx/79+/9SvSia45xxxhlymBvRhGf16tVN2xQXF8vP6NjYWHm/aMP9xRdftHrMp556CgMGDPjL+iFDhsjmP6J06qOPPsL3338vjy0uS5cuPWpV586dO2XM4vvB398fp556alP869evx6RJk2SJoahdmjBhgmxa1B5OpxPPP/88evToAZPJJGuhnnnmmab7t2/fjjPPPFP2bBXP36233irHg2xeknnRRRfhxRdflOPeiW2mT5/eNFj43//+d4wePfovxxXPsXieGmMQ1+Pi4mQM4nkSr1trPvzww78UmIjSvsYOSuL+WbNmYevWrU3Pr1h3tCrgkz0/OjGaTwDFP9Bll10mh1Z46623jrnt7Nmz5Ru88SKqCohIu+pqq7H29WmYtH4W9itpuGXxlfhl+edddnzxuVVjs6tyac9A1KJN9v33348NGzbg999/l70zL774Ypl0NPePf/wDDz74oEy+evXqJRM+u93e9EN9+PDh+Pnnn7Fjxw6ZJFx77bVYt27dUY954403Yvfu3TJBa7R582Zs27YNN9xwgzyO+Ow/++yzZZWkuIwbN+4v+8nOzsZpp50mk6I//vgDGzdulPtujKuyshLTpk3DihUrsGbNGjnm3LnnnivXt9XMmTMxZ84cmZju2rULn3/+OSIjI5ueuylTpsgqU3Eu33zzDRYvXoy77rqrxT6WLFkik1KxFImtSLYaE66rr75a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UFxVe8/xlVdeUb777jtl37598v9S9MDX6/Xys9MV3XHHHbLn+dKlS1t879XU1DRt4+7vQ1fGBNAFiOEXxJv7aJdG4gtU3Bbd/BuJJOHOO+9UgoOD5QfbxRdf3CJpdDViSJejnWPzcxK3xfMhiA+ByZMnK+Hh4fINnpCQoNxyyy1NX2Dufn6NQ8E8/vjjSmRkpPyyFj8CUlJSFFdUXFwsEz6R3AYEBCg33HBDi+T2yP/RjIwMmeyFhITIcxM/csSXb3l5ueIqXn/9dfkjytvbWw6bsmbNmhZD2IjXtLmvv/5a6dWrl9xeDCny888/K66sPec3Y8aMpm3F/+O5556rbNq0SXFVjUOeHHlpPCexFOd45GOGDBkiz1H8GGn+XnRF7T3H5557TklOTpaJu3jfnX766bKAwFW19r3X/HXxhPehq9KJP2qXQhIRERFR12EvYCIiIiKNYQJIREREpDFMAImIiIg0hgkgERERkcYwASQiIiLSGCaARERERBrDBJCIiIhIY5gAEhEREWkME0AiIiIijWECSERERKQxTACJiIiINIYJIBEREZHGMAEkIiIi0hgmgEREREQawwSQiIiISGOYABIRERFpDBNAIiIiIo1hAkhERESkMUwAiYiIiDSGCSARERGRxjABJCIiItIYJoBEREREGsMEkIiIiEhjmAASERERaQwTQCIiIiKNYQJIREREpDFMAImIiIg0hgkgERERkcYwASQiIiLSGCaARERERBrDBJCIiIgI2vL/+WSQD2ym6yoAAAAASUVORK5CYII=", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sample_gauss = Gaussian(center=-0.1, width=0.2, area=2)\n", + "resolution_delta = DeltaFunction(name=\"Delta\", center=0.2, area=3)\n", + "\n", + "resolution_handler = ResolutionHandler()\n", + "\n", + "# THEN\n", + "analytical_convolution = resolution_handler.convolve(x=x,sample_model=sample_gauss, resolution_model=resolution_delta,offset = 0.0, method='analytical')\n", + "numerical_convolution = resolution_handler.convolve(x=x,sample_model=sample_gauss, resolution_model=resolution_delta,offset = 0.0, method='numerical')\n", + "\n", + "#EXPECT\n", + "expected_center = sample_gauss.center.value + resolution_delta.center.value + 0.0\n", + "expected_area = sample_gauss.area.value * resolution_delta.area.value\n", + "expected_result = expected_area * np.exp(-0.5 * ((x - expected_center) / sample_gauss.width.value)**2) / (np.sqrt(2 * np.pi) * sample_gauss.width.value)\n", + "\n", + "plt.figure()\n", + "plt.plot(x, analytical_convolution, label='analytical convolution')\n", + "plt.plot(x, numerical_convolution, label='numerical convolution', linestyle='--')\n", + "plt.plot(x, expected_result, label='expected result', linestyle=':')\n", + "plt.legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "c35a6853", + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'ResolutionHandler' object has no attribute 'numerical_convolve'", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mAttributeError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[9]\u001b[39m\u001b[32m, line 22\u001b[39m\n\u001b[32m 19\u001b[39m MyResolutionHandler=ResolutionHandler()\n\u001b[32m 20\u001b[39m Convolution=MyResolutionHandler.convolve(x, Sample, Resolution)\n\u001b[32m---> \u001b[39m\u001b[32m22\u001b[39m NumConvolution=\u001b[43mMyResolutionHandler\u001b[49m\u001b[43m.\u001b[49m\u001b[43mnumerical_convolve\u001b[49m(x, Sample, Resolution,offset)\n\u001b[32m 23\u001b[39m NumConvolutionUpSample=MyResolutionHandler.numerical_convolve(x, Sample, Resolution,offset,\u001b[32m5\u001b[39m)\n\u001b[32m 25\u001b[39m plt.figure()\n", + "\u001b[31mAttributeError\u001b[39m: 'ResolutionHandler' object has no attribute 'numerical_convolve'" + ] + } + ], + "source": [ + "# Try out the resolution handler\n", + "\n", + "offset=Parameter('offset', 0.0)\n", + "\n", + "Gaussian= Gaussian(center=0,width=0.5,area=2)\n", + "Lorentzian=Lorentzian(center=0, width=0.5, area=3)\n", + "\n", + "Sample= SampleModel('MySample')\n", + "Sample.add_component(Gaussian)\n", + "\n", + "Resolution=SampleModel('MyRes')\n", + "Resolution.add_component(Lorentzian)\n", + "\n", + "Voigt=Voigt(center=0, Gwidth=0.5, Lwidth=0.5, area=6)\n", + "\n", + "\n", + "x=np.linspace(-4, 4, 1000)\n", + "\n", + "MyResolutionHandler=ResolutionHandler()\n", + "Convolution=MyResolutionHandler.convolve(x, Sample, Resolution)\n", + "\n", + "NumConvolution=MyResolutionHandler.numerical_convolve(x, Sample, Resolution,offset)\n", + "NumConvolutionUpSample=MyResolutionHandler.numerical_convolve(x, Sample, Resolution,offset,5)\n", + "\n", + "plt.figure()\n", + "plt.plot(x, Voigt.evaluate(x), label='Voigt')\n", + "plt.plot(x, Convolution, label='Convolution using ResolutionHandler',linestyle='--')\n", + "plt.plot(x, NumConvolution, label='Numerical Convolution', linestyle=':')\n", + "plt.plot(x, NumConvolutionUpSample, label='Numerical Convolution Upsampled', linestyle='-.')\n", + "plt.legend()\n", + "plt.xlabel('x')\n", + "plt.ylabel('y')\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5e3efad9", + "metadata": {}, + "outputs": [], + "source": [ + "Sample.components" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ce30691c", + "metadata": {}, + "outputs": [], + "source": [ + "from easydynamics.utils import detailed_balance_factor\n", + "\n", + "# Example of DetailedBalance\n", + "\n", + "x=np.linspace(-2, 2, 1000)\n", + "Lorentzian=Lorentzian(center=0, width=0.1, area=1)\n", + "\n", + "plt.figure()\n", + "DetailedBalanceT1=detailed_balance_factor(x,temperature=0.0)\n", + "plt.plot(x,Lorentzian.evaluate(x)*DetailedBalanceT1, label='T=0')\n", + "\n", + "DetailedBalanceT3=detailed_balance_factor(x,temperature=1)\n", + "plt.plot(x,Lorentzian.evaluate(x)*DetailedBalanceT3, label='T=1')\n", + "\n", + "DetailedBalanceT3=detailed_balance_factor(x,temperature=3)\n", + "plt.plot(x,Lorentzian.evaluate(x)*DetailedBalanceT3, label='T=3')\n", + "\n", + "plt.plot(x, Lorentzian.evaluate(x), label='No DBF', linestyle='--')\n", + "\n", + "plt.legend()\n", + "plt.xlabel('x')\n", + "plt.ylabel('y')\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31008bc4", + "metadata": {}, + "outputs": [], + "source": [ + "from easydynamics.utils import detailed_balance_factor\n", + "\n", + "from scipy.signal import fftconvolve\n", + "\n", + "Sample= SampleModel()\n", + "Sample.add_component(Gaussian)\n", + "\n", + "Resolution=SampleModel()\n", + "Resolution.add_component(Lorentzian)\n", + "\n", + "plt.figure()\n", + "\n", + "\n", + "# Example of DetailedBalance\n", + "\n", + "x=np.linspace(-2, 2, 1000)\n", + "Lorentzian=Lorentzian(center=0, width=0.1, area=1)\n", + "Gaussian= Gaussian(center=0,width=0.1,area=1)\n", + "Voigt=Voigt(center=0, Gwidth=0.1, Lwidth=0.1, area=1)\n", + "\n", + "DetailedBalanceT1=detailed_balance_factor(x,temperature=0.0)\n", + "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT1, label='T=0')\n", + "\n", + "DetailedBalanceT2=detailed_balance_factor(x,temperature=1)\n", + "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT2, label='T=1')\n", + "\n", + "DetailedBalanceT3=detailed_balance_factor(x,temperature=3)\n", + "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT3, label='T=3')\n", + "\n", + "# plt.plot(x, Voigt.evaluate(x), label='No DBF', linestyle='--')\n", + "\n", + "\n", + "\n", + "# Evaluate both models at the same points\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT1\n", + "model2 = Gaussian.evaluate(x)\n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", + "\n", + "\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT2\n", + "model2 = Gaussian.evaluate(x)\n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", + "\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT3\n", + "model2 = Gaussian.evaluate(x) \n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "plt.legend()\n", + "plt.xlabel('x')\n", + "plt.ylabel('y')\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "220405f1", + "metadata": {}, + "outputs": [], + "source": [ + "from easydynamics.sample.components import DetailedBalance\n", + "\n", + "from scipy.signal import fftconvolve\n", + "\n", + "Sample= SampleModel()\n", + "Sample.add_component(Gaussian)\n", + "\n", + "Resolution=SampleModel()\n", + "Resolution.add_component(Lorentzian)\n", + "\n", + "\n", + "\n", + "\n", + "# Example of DetailedBalance, up to 100 mueV. Res and peak is 5 mueV\n", + "\n", + "x=np.linspace(-0.1, 0.1, 1000)\n", + "Lorentzian=Lorentzian(center=0, width=0.005, area=1)\n", + "Gaussian= Gaussian(center=0,width=0.005,area=1)\n", + "Voigt=Voigt(center=0, Gwidth=0.005, Lwidth=0.005, area=1)\n", + "\n", + "DetailedBalanceT1=DetailedBalance(x,temperature_K=0.0)\n", + "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT1, label='T=0')\n", + "\n", + "DetailedBalanceT2=DetailedBalance(x,temperature_K=0.1)\n", + "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT2, label='T=0.1 K')\n", + " \n", + "DetailedBalanceT3=DetailedBalance(x,temperature_K=0.3)\n", + "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT3, label='T=0.3 K')\n", + "\n", + "# plt.plot(x, Voigt.evaluate(x), label='No DBF', linestyle='--')\n", + "\n", + "\n", + "\n", + "# Evaluate both models at the same points\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT1\n", + "model2 = Gaussian.evaluate(x)\n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", + "\n", + "\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT2\n", + "model2 = Gaussian.evaluate(x)\n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", + "\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT3\n", + "model2 = Gaussian.evaluate(x) \n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "plt.legend()\n", + "plt.xlabel('x')\n", + "plt.ylabel('y')\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "36d34acc", + "metadata": {}, + "outputs": [], + "source": [ + "from easydynamics.sample.components import DetailedBalance\n", + "\n", + "from scipy.signal import fftconvolve\n", + "\n", + "Sample= SampleModel()\n", + "Sample.add_component(Gaussian)\n", + "\n", + "Resolution=SampleModel()\n", + "Resolution.add_component(Lorentzian)\n", + "\n", + "\n", + "\n", + "\n", + "# Example of DetailedBalance, up to 2 meV. Res and peak is 100 mueV\n", + "\n", + "x=np.linspace(-2, 2, 1000)\n", + "Lorentzian=Lorentzian(center=0, width=0.1, area=1)\n", + "Gaussian= Gaussian(center=0,width=0.1,area=1)\n", + "Voigt=Voigt(center=0, Gwidth=0.1, Lwidth=0.1, area=1)\n", + "\n", + "DetailedBalanceT1=DetailedBalance(x,temperature_K=0.0)\n", + "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT1, label='T=0')\n", + "\n", + "DetailedBalanceT2=DetailedBalance(x,temperature_K=1)\n", + "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT2, label='T=1 K')\n", + " \n", + "DetailedBalanceT3=DetailedBalance(x,temperature_K=3)\n", + "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT3, label='T=3 K')\n", + "\n", + "# plt.plot(x, Voigt.evaluate(x), label='No DBF', linestyle='--')\n", + "\n", + "\n", + "\n", + "# Evaluate both models at the same points\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT1\n", + "model2 = Gaussian.evaluate(x)\n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", + "\n", + "\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT2\n", + "model2 = Gaussian.evaluate(x)\n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", + "\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT3\n", + "model2 = Gaussian.evaluate(x) \n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "plt.legend()\n", + "plt.xlabel('x')\n", + "plt.ylabel('y')\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c2798453", + "metadata": {}, + "outputs": [], + "source": [ + "from easydynamics.sample.components import DetailedBalance\n", + "\n", + "from scipy.signal import fftconvolve\n", + "\n", + "\n", + "x=np.linspace(-3, 3, 1000)\n", + "Lorentzian=Lorentzian(center=0, width=0.1, area=1)\n", + "Gaussian= Gaussian(center=0,width=0.1,area=1)\n", + "\n", + "\n", + "Sample= SampleModel()\n", + "Sample.add_component(Lorentzian)\n", + "\n", + "Resolution=SampleModel()\n", + "Resolution.add_component(Gaussian)\n", + "\n", + "\n", + "\n", + "\n", + "DetailedBalanceT3=DetailedBalance(x,temperature_K=3)\n", + "\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT3\n", + "model2 = Gaussian.evaluate(x) \n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "# Add Gaussian noise (adjust noise level as needed)\n", + "noise_level = 0.02 # Small relative noise\n", + "noisy_convolved = convolved + np.random.normal(scale=noise_level, size=convolved.shape)+0.05\n", + "\n", + "# Plot only every 10th point\n", + "# plt.plot(x[::10], noisy_convolved[::10], label='Example data, 3 K', linestyle='None', marker='o', markersize=6,markerfacecolor='w')\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "DetailedBalanceT3=DetailedBalance(x,temperature_K=5)\n", + "\n", + "model1 = Lorentzian.evaluate(x)*DetailedBalanceT3\n", + "model2 = Gaussian.evaluate(x) \n", + "\n", + "# Perform convolution\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "# Normalize the result to maintain the area under the curve\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "# Add Gaussian noise (adjust noise level as needed)\n", + "noise_level = 0.02 # Small relative noise\n", + "noisy_convolved = convolved + np.random.normal(scale=noise_level, size=convolved.shape)+0.05\n", + "\n", + "# Plot only every 10th point\n", + "plt.plot(x[::10], noisy_convolved[::10], label='Example data, 5 K', linestyle='None', marker='o', markersize=6,markerfacecolor='w')\n", + "\n", + "\n", + "\n", + "# One start guess\n", + "\n", + "# Lorentzian2=Lorentzian(center=0, width=0.15, amplitude=1)\n", + "# Lorentzian2=Lorentzian(center=0, width=0.15, amplitude=1*2.7)\n", + "Lorentzian2=Lorentzian(center=0, width=0.15, area=1*2.7)\n", + "Gaussian= Gaussian(center=0,width=0.1,area=1)\n", + "\n", + "model1 = Lorentzian2.evaluate(x)*DetailedBalanceT3\n", + "model2 = Gaussian.evaluate(x) \n", + "\n", + "convolved = fftconvolve(model1, model2, mode='same')\n", + "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "plt.plot(x, convolved+0.05, label='Guess', linestyle='-.', color='r')\n", + "\n", + "\n", + "# # Using area instead\n", + "\n", + "# # Lorentzian2=Lorentzian(center=0, width=0.15, area=0.5)\n", + "# # Lorentzian2=Lorentzian(center=0, width=0.15, area=0.5*2.5)\n", + "# Lorentzian2=Lorentzian(center=0, width=0.1, area=0.5*2.5)\n", + "\n", + "# Gaussian= Gaussian(center=0,width=0.1,area=1)\n", + "\n", + "# model1 = Lorentzian2.evaluate(x)*DetailedBalanceT3\n", + "# model2 = Gaussian.evaluate(x) \n", + "\n", + "# convolved = fftconvolve(model1, model2, mode='same')\n", + "# convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", + "\n", + "# plt.plot(x, convolved+0.05, label='Guess', linestyle='-.', color='r')\n", + "\n", + "\n", + "\n", + "plt.legend()\n", + "plt.xlabel('Energy (meV)')\n", + "plt.ylabel('Intensity (a.u.)')\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "47653f60", + "metadata": {}, + "outputs": [], + "source": [ + "Lorentzian.amplitude" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "EasyQENSDev", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.11" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py index 12ed08c..291c9cd 100644 --- a/src/easydynamics/utils/convolution.py +++ b/src/easydynamics/utils/convolution.py @@ -101,6 +101,7 @@ def convolution( ) # Handle temperature + T = None if temperature is not None: if isinstance(temperature, Parameter): T = temperature.value @@ -550,8 +551,12 @@ def _check_width_thresholds( If the component widths are not appropriate for the data span or bin spacing. """ - LARGE_WIDTH_THRESHOLD = 0.1 # Threshold for large widths compared to span - SMALL_WIDTH_THRESHOLD = 0.5 # Threshold for small widths compared to bin spacing + LARGE_WIDTH_THRESHOLD = ( + 0.1 # Threshold for large widths compared to span - warn if width > 10% of span + ) + SMALL_WIDTH_THRESHOLD = ( + 1.0 # Threshold for small widths compared to bin spacing - warn if width < dx + ) # Handle SampleModel or ModelComponent if isinstance(model, SampleModel): diff --git a/tests/performance_tests/convolution/convolution_width_thresholds.ipynb b/tests/performance_tests/convolution/convolution_width_thresholds.ipynb new file mode 100644 index 0000000..925b2ab --- /dev/null +++ b/tests/performance_tests/convolution/convolution_width_thresholds.ipynb @@ -0,0 +1,126 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "018fa173", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from easyscience.variable import Parameter\n", + "from scipy.special import voigt_profile\n", + "\n", + "from easydynamics.sample_model import DeltaFunction, Gaussian, Lorentzian, SampleModel, DampedHarmonicOscillator\n", + "from easydynamics.utils import convolution \n", + "\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cf69a4b9", + "metadata": {}, + "outputs": [], + "source": [ + "# When the width of the Gaussian is >~20% of the span, numerical issues arise. We set the limit to 10% to be safe.\n", + "gaussian_widths=[30, 20, 10, 5]\n", + "sample_model=SampleModel(name='sample_model')\n", + "gaussian=Gaussian(name='Gaussian',width=30,area=1)\n", + "sample_model.add_component(gaussian)\n", + "\n", + "resolution_model = SampleModel(name='resolution_model')\n", + "resolution_gaussian=Gaussian(name='Resolution Gaussian',width=5,area=1.0)\n", + "resolution_model.add_component(resolution_gaussian)\n", + "x=np.linspace(-50, 50, 101)\n", + "\n", + "for gwidth in gaussian_widths:\n", + " sample_model['Gaussian'].width=gwidth\n", + " y_analytical = convolution(sample_model=sample_model,\n", + " resolution_model=resolution_model,\n", + " x=x,\n", + " )\n", + "\n", + " y_numerical = convolution(sample_model=sample_model,\n", + " resolution_model=resolution_model,\n", + " x=x,\n", + " method='numerical',\n", + " upsample_factor=0\n", + " )\n", + "\n", + " plt.plot(x, y_analytical, label='Analytical, width = {}'.format(gwidth), color = plt.cm.viridis(gaussian_widths.index(gwidth)/len(gaussian_widths)))\n", + " plt.plot(x, y_numerical, label='Numerical, width = {}'.format(gwidth), color = plt.cm.viridis(gaussian_widths.index(gwidth)/len(gaussian_widths)), linestyle='--')\n", + " plt.xlabel('Energy (meV)')\n", + " plt.ylabel('Intensity (arb. units)')\n", + " plt.title('Convolution of Sample Model with Resolution Model with various widths')\n", + "\n", + "plt.legend()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0cb777e0", + "metadata": {}, + "outputs": [], + "source": [ + "# When the width of the Gaussian is <~50% of the bin spacing, numerical issues arise. We set the limit to 100% to be safe.\n", + "gaussian_widths=[5, 2, 1, 0.5, 0.25]\n", + "gaussian_centers=[-50, -25, 0, 25, 50]\n", + "sample_model=SampleModel(name='sample_model')\n", + "gaussian=Gaussian(name='Gaussian',width=0.5,area=1)\n", + "sample_model.add_component(gaussian)\n", + "\n", + "resolution_model = SampleModel(name='resolution_model')\n", + "resolution_gaussian=Gaussian(name='Resolution Gaussian',width=10,area=1.0)\n", + "resolution_model.add_component(resolution_gaussian)\n", + "x=np.linspace(-100, 100, 201)\n", + "\n", + "for gwidth, gcenter in zip(gaussian_widths, gaussian_centers):\n", + " sample_model['Gaussian'].width=gwidth\n", + " sample_model['Gaussian'].center=gcenter\n", + " y_analytical = convolution(sample_model=sample_model,\n", + " resolution_model=resolution_model,\n", + " x=x,\n", + " )\n", + "\n", + " y_numerical = convolution(sample_model=sample_model,\n", + " resolution_model=resolution_model,\n", + " x=x,\n", + " method='numerical',\n", + " upsample_factor=0\n", + " )\n", + "\n", + " plt.plot(x, y_analytical, label='Analytical, width = {}'.format(gwidth), color = plt.cm.viridis(gaussian_widths.index(gwidth)/len(gaussian_widths)))\n", + " plt.plot(x, y_numerical, label='Numerical, width = {}'.format(gwidth), color = plt.cm.viridis(gaussian_widths.index(gwidth)/len(gaussian_widths)), linestyle='--')\n", + " plt.xlabel('Energy (meV)')\n", + " plt.ylabel('Intensity (arb. units)')\n", + " plt.title('Convolution of Sample Model with Resolution Model with various widths')\n", + "\n", + "plt.legend()\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "newdynamics", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/tests/unit_tests/utils/test_convolution.py b/tests/unit_tests/utils/test_convolution.py index be83e16..9c641d8 100644 --- a/tests/unit_tests/utils/test_convolution.py +++ b/tests/unit_tests/utils/test_convolution.py @@ -652,7 +652,7 @@ def test_analytical_convolution_fails_with_detailed_balance(self, x): sample_model=sample_model, resolution_model=resolution_model, method="analytical", - temperature=300, + temperature=300.0, ) def test_convolution_only_accepts_analytical_and_numerical_methods(self, x): From 62f5ce252628c80662ee6f903064871cf0a3e9b0 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 31 Oct 2025 14:19:20 +0100 Subject: [PATCH 24/71] Update tests --- examples/convolution.ipynb | 153 +++++++++++- src/easydynamics/utils/convolution.py | 10 +- tests/unit_tests/utils/test_convolution.py | 271 ++++++++++----------- 3 files changed, 273 insertions(+), 161 deletions(-) diff --git a/examples/convolution.ipynb b/examples/convolution.ipynb index 7b9234d..e7cf84f 100644 --- a/examples/convolution.ipynb +++ b/examples/convolution.ipynb @@ -2,14 +2,12 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "id": "f42e34d0", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", - "from easyscience.variable import Parameter\n", - "from scipy.special import voigt_profile\n", "\n", "from easydynamics.sample_model import DeltaFunction, Gaussian, Lorentzian, SampleModel, DampedHarmonicOscillator\n", "from easydynamics.utils import convolution \n", @@ -20,10 +18,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "600c0850", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(0.0, 6.0)" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# Standard example of convolution of a sample model with a resolution model\n", "sample_model=SampleModel(name='sample_model')\n", @@ -66,10 +75,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "fede1a58", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(0.0, 2.5)" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# Use some of the extra settings for the numerical convolution\n", "sample_model=SampleModel(name='sample_model')\n", @@ -117,8 +137,125 @@ "plt.title('Convolution of Sample Model with Resolution Model with detailed balancing')\n", "\n", "plt.legend()\n", - "plt.ylim(0,2.5)" + "plt.ylim(0,2.5)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "8b9dbff2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "5bb238bc9e714fd79ae5139a921b8e4d", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAVr9JREFUeJzt3Qd8G+X9P/DPSbK8Je8Vjyw7eyeEMMIIEMKm7F3asmmhUAqBsn8QCi2lUMr6F8IIu+wSAgGSABlkkp04w/HetuSpef/XPWebbDJs3/q8W/Gc5dPdVzlL+up57p6vJMuyDCIiIiKyDJvWARARERFR72ICSERERGQxTACJiIiILIYJIBEREZHFMAEkIiIishgmgEREREQWwwSQiIiIyGKYABIRERFZDBNAIiIiIothAkhERERkMUwAiYiIiCyGCSARERGRxTABJCIiIrIYJoBEREREFsMEkIiIiMhimAASERERWQwTQCIiIiKLYQJIREREZDFMAImIiIgshgkgERERkcUwASQiIiKyGCaARERERBbDBJCIiIjIYpgAEhEREVkME0AiIiIii2ECSERERGQxTACJiIiILIYJIBEREZHFMAEkIiIishgmgEREREQWwwSQiIiIyGKYABIRERFZDBNAIiIiIothAkhERERkMUwAiYiIiCyGCSARERGRxTABJCIiIrIYJoBEREREFsMEkIiIiMhimAASERERWQwTQCIiIiKLYQJIREREZDFMAImIiIgshgkgERERkcUwASQiIiKyGCaARERERBbDBJCIiIjIYpgAEhEREVkME0AiIiIii2ECSERERGQxTACJiIiILIYJIBEREZHFMAEkIiIishgmgEREREQWwwSQiIiIyGKYABIRERFZjEPrAIwsHA6jvLwc8fHxkCRJ63CIiIjoAMiyjKamJmRlZcFms2ZfGBPAw6Akfzk5OVqHQURERIegpKQE2dnZsCImgIdB6fnr/ANyuVxah0NEREQHwOv1ig6czs9xK2ICeBg6h32V5I8JIBERkbFIFj59y5oD30REREQWxgSQiIiIyGKYABIRERFZDBNAIiIiIothAkhERERkMUwAiYiIiCyGCSARERGRxTABJCIiIrIYJoBEREREFmPpBLCsrAyXX345kpOTER0djREjRmDZsmVah0VERETUoyxbCq6hoQFHH300TjjhBMyePRupqakoLCxEYmKi1qERERER9SjLJoB//etfRSHoV155peu+fv36aRoTERERUW+w7BDwJ598gvHjx+OCCy5AWloaxowZg5deeknrsIiIqAfJ4TA+WbYd0z9Yg9lrKrQOh0gzlk0At23bhueeew75+fmYM2cObrjhBvzhD3/Aq6++us/H+Hw+eL3eXW5ERGQci/9zG1wfX4X3f9yGG2atwIsLtmodEpEmLJsAhsNhjB07Fo8++qjo/bv22mtxzTXX4Pnnn9/nY2bMmAG32911U4aQiYjIGApXLsDE0pk43v4TrskuFff9e84qFO/YpnVoRL3OsglgZmYmhg4dust9Q4YMQXFx8T4fM336dHg8nq5bSUlJL0RKRETdoWnu47BJMpa5TsIdN92IG3JLMMdxGyo/vEfr0Ih6nWUvAlGuAN60adMu923evBl5eXn7fExkZKS4ERGRsVSWbMGo5u8BCUiZNh2SJOHscf2RPrsR7oav4KmvgTspVeswiXqNZXsA//jHP2Lx4sViCHjLli1488038eKLL+Kmm27SOjQiIupmRQvehF2Ssd45An2HjBf3DZpwErbb8hAlBbBp/ttah0jUqyybAE6YMAEffvgh3nrrLQwfPhwPP/wwnnrqKVx22WVah0ZERN3MXfSFaL39pnXdJ9lsqMyeKpYjCj/XLDYiLVh2CFhxxhlniBsREZlXfXUZBvnXi+HfvkdfuMvvMiaeDxS/iKEtS9He2oyomDjN4iTqTZbtASQiImtYXtSAp4LnYbbzFGTk5u/yu75DJqAaSYiUAtiycp5mMRL1NiaARERkat9XAE+HfoXFw+7f43fKMHCxa6xYbtr4rQbREWnD0kPARERkfku214t2Yv/kvf6+Jf9s/HtJDEpaR2BSL8dGpBX2ABIRkWk1NtSib83XSIIXE/om7XWdnCN/hceDF+O/VenwB8O9HiORFpgAEhGRaRWvmofnI57Cx9EPITV+7/O49kuJRXyUQyR/m6uaej1GIi0wASQiItNq3bFCtNVxg/e5jjIp9FGZwPG2VShdv6gXoyPSDhNAIiIyLWftGtEG0kbsd71fS59hpvNxJG6Y1UuREWmLCSAREZlWeota8jOu77j9rheZq/4+2bOuV+Ii0hoTQCIiMiVPQy36yFViOWfokftdN2Owev1vXrAIfl97r8RHpCUmgEREZEql65eI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A1uoVf0hrI5oifRDDsPviENZxpSOQS4Zfcq/hDPgFb+vTRiB3CETMSK7e89d9HII2LoJoDIEHBMTg/fffx/nnHNO1/1XXXUVGhsb8fHHHx9QD6ByzqCV/4CIiIiMxssEsOtUKstxOp0YN24cvv7652FW5eIB5eedewR3FhkZKf5Qdr4RERERGY1lzwFU3HbbbaLHb/z48WLuP2UamJaWFlx9tXryPxEREZEZWToBvOiii1BTU4P77rtPTAQ9evRofPHFF3tcGEJERERkJpY9B7A78BwCIiIi4/Hy89u65wASERERWRUTQCIiIiKLYQJIREREZDFMAImIiIgshgkgERERkcUwASQiIiKyGCaARERERBbDBJCIiIjIYpgAEhEREVmMpUvBHa7OIirKjOJERERkDN6Oz20rF0NjAngYmpqaRJuTk6N1KERERHQIn+NutxtWxFrAhyEcDqO8vBzx8fGQJKnbv50oiWVJSYkp6xTy+Rmf2Z8jn5/xmf058vkdOlmWRfKXlZUFm82aZ8OxB/AwKH802dnZPboP5Y/ejC/sTnx+xmf258jnZ3xmf458fofGbdGev07WTHuJiIiILIwJIBEREZHFMAHUqcjISNx///2iNSM+P+Mz+3Pk8zM+sz9HPj86HLwIhIiIiMhi2ANIREREZDFMAImIiIgshgkgERERkcUwASQiIiKyGCaAGnnkkUdw1FFHISYmBgkJCXtdp7i4GKeffrpYJy0tDXfccQeCweB+t1tfX4/LLrtMTJqpbPe3v/0tmpubobV58+aJail7uy1dunSfjzv++OP3WP/666+HHvXt23ePWB977LH9Pqa9vR033XQTkpOTERcXh/POOw9VVVXQm6KiIvG31K9fP0RHR2PAgAHi6jy/37/fx+n9+D377LPiuEVFRWHixIn48ccf97v+e++9h8GDB4v1R4wYgc8//xx6NGPGDEyYMEFUKVLeO8455xxs2rRpv4+ZOXPmHsdKeZ569cADD+wRr3JszHD89vV+otyU9wujHr8FCxbgzDPPFNU3lPg++uijXX6vXJN63333ITMzU7zPnHTSSSgsLOz21zGpmABqRPngvOCCC3DDDTfs9fehUEgkf8p6CxcuxKuvvipe4MqLY3+U5G/dunX46quv8Nlnn4kX3LXXXgutKcluRUXFLrff/e53IqEYP378fh97zTXX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d911V9f6P/zwg+xwOOS//e1v4u9XuQpVuYp7zZo1st7ccMMN4orQefPm7XKsWltbu9bZ/fkp70Vz5swRf7/Lly+XL774YjkqKkpet26drEe33367eH7K35ZybE466SQ5JSVFXPFs9OO38xWtyvvDnXfeucfvjHj8lM+3zs865XPgySefFMvK56HiscceE69B5b1i9erV8tlnny1mGmhra+vaxoknnig/88wzB/w6pn1jAqiRq666SrwAdr99++23XesUFRXJ06ZNk6Ojo8Ubm/KGFwgEun6vrKs8RnkD7FRXVycSPiWpVKaMufrqq7uSSj1QYjvqqKP2+jvleez8b1BcXCyShaSkJPECVxKQO+64Q/Z4PLLeKG+4ypQSyoeu8qY7ZMgQ+dFHH5Xb29v3+fwUyhvbjTfeKCcmJsoxMTHyueeeu0tSpRfKFBN7+3vd+TukEY+f8kGifMA6nU4xncTixYt3mcJGeZ3u7N1335ULCgrE+sOGDZP/97//yXq0r2OlHMd9Pb9bb721698iPT1dPu200+QVK1bIenXRRRfJmZmZIt4+ffqIn5UvHWY4fp2UhE45bps2bdrjd0Y8fp2fWbvfOp+HMhXMvffeK+JX3jOUL5y7P3dlui0leT/Q1zHtm6T8Z+ceQSIiIiIyN84DSERERGQxTACJiIiILIYJIBEREZHFMAEkIiIishgmgEREREQWwwSQiIiIyGKYABIRERFZDBNAIiIiIothAkhERERkMUwAiYiIiCyGCSARERGRxTABJCIiIrIYJoBEREREFsMEkIiIiMhimAASERERWQwTQCIiIiKLYQJIREREZDFMAImIiIgshgkgERERkcUwASQiIiKyGCaARERERBbDBJCIiIjIYpgAEhEREVkME0AiIiIii2ECSERERGQxTACJiIiILIYJIBEREZHFMAEkIiIishgmgEREREQWwwSQiIiIyGKYABIRERHBWv4/QaxfG7YfoMUAAAAASUVORK5CYII=", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\"Test convolution of Lorentzian and Delta function sample components in SampleModel and Gaussian resolution components in SampleModel.\"\n", + "\" Result is a combination of Voigt profile and Gaussian.\"\n", + "%matplotlib widget\n", + "from scipy.special import voigt_profile\n", + "\n", + "lorentzian_component = Lorentzian(center=0.1, width=0.3, area=2.0)\n", + "offset_obj =0.0\n", + "method = 'analytical'\n", + "expected_shift = offset_obj\n", + "\n", + "resolution_model = SampleModel(name=\"TestResolutionModel\")\n", + "resolution_model.add_component(Gaussian(center=0.2, width=0.8, area=3.0))\n", + "\n", + "sample = SampleModel(name=\"SampleModel\")\n", + "sample.add_component(lorentzian_component)\n", + "sample_delta = DeltaFunction(center=5.1, area=4, name=\"SampleDelta\")\n", + "sample.add_component(sample_delta)\n", + "\n", + "# THEN\n", + "x = np.linspace(-10, 10, 20001)\n", + "calculated_convolution = convolution(\n", + " x=x,\n", + " sample_model=sample,\n", + " resolution_model=resolution_model,\n", + " offset=offset_obj,\n", + " method=method,\n", + " upsample_factor=5,\n", + ")\n", + "\n", + "# EXPECT: Combine Gaussian, Lorentzian, and Delta functions contributions\n", + "# \n", + "gaussian_component = resolution_model[\"Gaussian\"]\n", + "\n", + "expected_voigt_area = (\n", + " lorentzian_component.area.value * gaussian_component.area.value\n", + ")\n", + "expected_voigt_center = (\n", + " lorentzian_component.center.value\n", + " + gaussian_component.center.value\n", + " + expected_shift\n", + ")\n", + "expected_voigt = expected_voigt_area * voigt_profile(\n", + " x - expected_voigt_center,\n", + " gaussian_component.width.value,\n", + " lorentzian_component.width.value,\n", + ")\n", + "expected_gauss_area = sample_delta.area.value * gaussian_component.area.value\n", + "expected_gauss_center = (\n", + " sample_delta.center.value + gaussian_component.center.value + expected_shift\n", + ")\n", + "expected_gauss_width = gaussian_component.width.value\n", + "expected_gauss = (\n", + " expected_gauss_area\n", + " * np.exp(-0.5 * ((x - (expected_gauss_center)) / expected_gauss_width) ** 2)\n", + " / (np.sqrt(2 * np.pi) * expected_gauss_width)\n", + ")\n", + "expected_result = expected_voigt + expected_gauss\n", + "\n", + "plt.figure()\n", + "\n", + "plt.plot(x, calculated_convolution, label='Convoluted Model')\n", + "plt.plot(x, expected_result, '--', label='Expected Result')" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9d92cad4", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py index 291c9cd..84a4364 100644 --- a/src/easydynamics/utils/convolution.py +++ b/src/easydynamics/utils/convolution.py @@ -154,7 +154,7 @@ def _numerical_convolution( x: np.ndarray, sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], - offset: Optional[Union[Parameter, np.ndarray]] = None, + offset: Optional[float] = 0.0, upsample_factor: Optional[int] = 5, extension_factor: Optional[float] = 0.2, temperature: Optional[Union[Parameter, float]] = None, @@ -298,7 +298,7 @@ def _analytical_convolution( x: np.ndarray, sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], - offset: Union[Parameter, float, None] = None, + offset: float = 0.0, upsample_factor: int = 5, extension_factor: float = 0.2, ) -> np.ndarray: @@ -316,7 +316,7 @@ def _analytical_convolution( The sample model to be convolved. resolution_model : SampleModel or ModelComponent The resolution model to convolve with. - offset : Parameter, float, or None, optional + offset : float The offset to apply to the convolution. upsample_factor : int, optional The factor by which to upsample the input data before numerical convolution. Improves accuracy at the cost of speed. Default is 5 @@ -450,7 +450,6 @@ def _try_analytic_pair( return False, np.zeros_like(x, dtype=float) -@staticmethod def _gaussian_eval( x: np.ndarray, center: float, width: float, area: float ) -> np.ndarray: @@ -479,7 +478,6 @@ def _gaussian_eval( ) -@staticmethod def _lorentzian_eval( x: np.ndarray, center: float, width: float, area: float ) -> np.ndarray: @@ -503,7 +501,6 @@ def _lorentzian_eval( return area * width / np.pi / ((x - center) ** 2 + width**2) -@staticmethod def _voigt_eval( x: np.ndarray, center: float, g_width: float, l_width: float, area: float ) -> np.ndarray: @@ -528,7 +525,6 @@ def _voigt_eval( return area * voigt_profile(x - center, g_width, l_width) -@staticmethod def _check_width_thresholds( model: Union[SampleModel, ModelComponent], span: float, dx: float, model_type: str ) -> None: diff --git a/tests/unit_tests/utils/test_convolution.py b/tests/unit_tests/utils/test_convolution.py index 9c641d8..69957da 100644 --- a/tests/unit_tests/utils/test_convolution.py +++ b/tests/unit_tests/utils/test_convolution.py @@ -25,13 +25,13 @@ class TestConvolution: @pytest.fixture def sample_model(self): test_sample_model = SampleModel(name="TestSampleModel") - test_sample_model.add_component(Lorentzian(center=0.1, width=0.2, area=2.0)) + test_sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2.0)) return test_sample_model @pytest.fixture def resolution_model(self): test_resolution_model = SampleModel(name="TestResolutionModel") - test_resolution_model.add_component(Gaussian(center=0.2, width=0.3, area=3.0)) + test_resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3.0)) return test_resolution_model @pytest.fixture @@ -40,7 +40,7 @@ def gaussian_component(self): @pytest.fixture def other_gaussian_component(self): - return Gaussian(center=0.2, width=0.4, area=3.0) + return Gaussian(name="other Gaussian", center=0.2, width=0.4, area=3.0) @pytest.fixture def lorentzian_component(self): @@ -345,46 +345,46 @@ def test_components_delta_gauss( "method", ["analytical", "numerical"], ids=["analytical", "numerical"] ) def test_model_gauss_gauss_resolution_gauss( - self, x, offset_obj, expected_shift, method + self, + x, + sample_model, + resolution_model, + offset_obj, + expected_shift, + method, ): "Test convolution of Gaussian sample components in SampleModel and Gaussian resolution components in SampleModel." "Test with different offset types and methods." # WHEN - sample_gauss1 = Gaussian(center=0.1, width=0.3, area=2, name="SampleGauss1") - sample_gauss2 = Gaussian(center=0.2, width=0.4, area=3, name="SampleGauss2") - resolution_gauss = Gaussian(center=0.3, width=0.5, area=4) - - sample = SampleModel(name="SampleModel") - sample.add_component(sample_gauss1) - sample.add_component(sample_gauss2) - - resolution = SampleModel(name="ResolutionModel") - resolution.add_component(resolution_gauss) + sample_G2 = Gaussian(name="another Gaussian", center=0.3, width=0.5, area=4) + sample_model.add_component(sample_G2) # THEN calculated_convolution = convolution( x=x, - sample_model=sample, - resolution_model=resolution, + sample_model=sample_model, + resolution_model=resolution_model, offset=offset_obj, method=method, ) # EXPECT + sample_G1 = sample_model["Gaussian"] + resolution_G1 = resolution_model["Gaussian"] expected_width1 = np.sqrt( - sample_gauss1.width.value**2 + resolution_gauss.width.value**2 + sample_G1.width.value**2 + resolution_G1.width.value**2 ) expected_width2 = np.sqrt( - sample_gauss2.width.value**2 + resolution_gauss.width.value**2 + sample_G2.width.value**2 + resolution_G1.width.value**2 ) - expected_area1 = sample_gauss1.area.value * resolution_gauss.area.value - expected_area2 = sample_gauss2.area.value * resolution_gauss.area.value + expected_area1 = sample_G1.area.value * resolution_G1.area.value + expected_area2 = sample_G2.area.value * resolution_G1.area.value expected_center1 = ( - sample_gauss1.center.value + resolution_gauss.center.value + expected_shift + sample_G1.center.value + resolution_G1.center.value + expected_shift ) expected_center2 = ( - sample_gauss2.center.value + resolution_gauss.center.value + expected_shift + sample_G2.center.value + resolution_G1.center.value + expected_shift ) expected_result = expected_area1 * np.exp( @@ -394,43 +394,73 @@ def test_model_gauss_gauss_resolution_gauss( ) / (np.sqrt(2 * np.pi) * expected_width2) np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) + @pytest.mark.parametrize( + "offset_obj, expected_shift", + [ + (None, 0.0), + (0.4, 0.4), + (Parameter("off", 0.4), 0.4), + ], + ids=["none", "float", "parameter"], + ) @pytest.mark.parametrize( "method", ["analytical", "numerical"], ids=["analytical", "numerical"] ) - def test_model_lorentzian_delta_resolution_gauss(self, x, method): + def test_model_lorentzian_delta_resolution_gauss( + self, + x, + method, + lorentzian_component, + resolution_model, + offset_obj, + expected_shift, + ): "Test convolution of Lorentzian and Delta function sample components in SampleModel and Gaussian resolution components in SampleModel." + " Result is a combination of Voigt profile and Gaussian." # WHEN - sample_lorentzian = Lorentzian( - center=0.1, width=0.3, area=2, name="SampleLorentzian" - ) - sample_delta = DeltaFunction(center=0.5, area=4, name="SampleDelta") - resolution_gauss = Gaussian( - center=-0.3, width=0.4, area=3, name="ResolutionGauss" - ) + sample = SampleModel(name="SampleModel") - sample.add_component(sample_lorentzian) + sample.add_component(lorentzian_component) + sample_delta = DeltaFunction(center=0.5, area=4, name="SampleDelta") sample.add_component(sample_delta) - resolution = SampleModel(name="ResolutionModel") - resolution.add_component(resolution_gauss) # THEN x = np.linspace(-10, 10, 20001) calculated_convolution = convolution( x=x, sample_model=sample, - resolution_model=resolution, + resolution_model=resolution_model, + offset=offset_obj, method=method, upsample_factor=5, ) # EXPECT: Combine Gaussian, Lorentzian, and Delta functions contributions - expected_voigt = 2 * 3 * voigt_profile(x - (0.1 - 0.3), 0.4, 0.3) - expected_gauss_center = -0.3 + 0.5 + # + gaussian_component = resolution_model["Gaussian"] + + expected_voigt_area = ( + lorentzian_component.area.value * gaussian_component.area.value + ) + expected_voigt_center = ( + lorentzian_component.center.value + + gaussian_component.center.value + + expected_shift + ) + expected_voigt = expected_voigt_area * voigt_profile( + x - expected_voigt_center, + gaussian_component.width.value, + lorentzian_component.width.value, + ) + expected_gauss_area = sample_delta.area.value * gaussian_component.area.value + expected_gauss_center = ( + sample_delta.center.value + gaussian_component.center.value + expected_shift + ) + expected_gauss_width = gaussian_component.width.value expected_gauss = ( - 3 - * 4 - * np.exp(-0.5 * ((x - (expected_gauss_center)) / 0.4) ** 2) - / (np.sqrt(2 * np.pi) * 0.4) + expected_gauss_area + * np.exp(-0.5 * ((x - (expected_gauss_center)) / expected_gauss_width) ** 2) + / (np.sqrt(2 * np.pi) * expected_gauss_width) ) expected_result = expected_voigt + expected_gauss np.testing.assert_allclose( @@ -440,17 +470,11 @@ def test_model_lorentzian_delta_resolution_gauss(self, x, method): rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, ) - # Test numerical convolution - - def test_numerical_convolve_with_temperature(self, x): + def test_numerical_convolve_with_temperature( + self, x, sample_model, resolution_model + ): "Test numerical convolution with detailed balance correction." # WHEN - sample_model = SampleModel(name="SampleModel") - sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) - - resolution_model = SampleModel(name="ResolutionModel") - resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) - temperature = 300.0 # Kelvin # THEN @@ -486,16 +510,12 @@ def test_numerical_convolve_with_temperature(self, x): ], ids=["odd_length", "even_length"], ) - def test_numerical_convolve_x_length_even_and_odd(self, x): + def test_numerical_convolve_x_length_even_and_odd( + self, x, sample_model, resolution_model + ): "Test numerical convolution with both even and odd length x arrays. With even length the FFT shifts the signal by half a bin." - # WHEN - sample_model = SampleModel(name="SampleModel") - sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) - - resolution_model = SampleModel(name="ResolutionModel") - resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) - # THEN + # WHEN THEN calculated_convolution = convolution( x=x, sample_model=sample_model, @@ -522,16 +542,11 @@ def test_numerical_convolve_x_length_even_and_odd(self, x): [0, 2, 5, 10], ids=["no_upsample", "upsample_2", "upsample_5", "upsample_10"], ) - def test_numerical_convolve_upsample_factor(self, x, upsample_factor): + def test_numerical_convolve_upsample_factor( + self, x, upsample_factor, sample_model, resolution_model + ): "Test numerical convolution with different upsample factors." - # WHEN - sample_model = SampleModel(name="SampleModel") - sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) - - resolution_model = SampleModel(name="ResolutionModel") - resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) - - # THEN + # WHEN THEN calculated_convolution = convolution( x=x, sample_model=sample_model, @@ -564,15 +579,14 @@ def test_numerical_convolve_upsample_factor(self, x, upsample_factor): @pytest.mark.parametrize( "upsample_factor", [0, 2, 5], ids=["no_upsample", "upsample_2", "upsample_5"] ) - def test_numerical_convolve_x_not_symmetric(self, x, upsample_factor): + def test_numerical_convolve_x_not_symmetric( + self, x, upsample_factor, resolution_model + ): "Test numerical convolution with asymmetric and only positive x arrays." # WHEN sample_model = SampleModel(name="SampleModel") sample_model.add_component(Gaussian(center=9, width=0.3, area=2)) - resolution_model = SampleModel(name="ResolutionModel") - resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) - # THEN calculated_convolution = convolution( x=x, @@ -597,17 +611,13 @@ def test_numerical_convolve_x_not_symmetric(self, x, upsample_factor): rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, ) - def test_numerical_convolve_x_not_uniform(self): + def test_numerical_convolve_x_not_uniform(self, sample_model, resolution_model): "Test numerical convolution with non-uniform x arrays." # WHEN - sample_model = SampleModel(name="SampleModel") - sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) - resolution_model = SampleModel(name="ResolutionModel") - resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) - x_1 = np.linspace(-2, 0, 1000) x_2 = np.linspace(0.001, 2, 2000) x_non_uniform = np.concatenate([x_1, x_2]) + # THEN calculated_convolution = convolution( x=x_non_uniform, @@ -633,16 +643,12 @@ def test_numerical_convolve_x_not_uniform(self): ) # Test error handling - - def test_analytical_convolution_fails_with_detailed_balance(self, x): + def test_analytical_convolution_fails_with_detailed_balance( + self, x, sample_model, resolution_model + ): # WHEN - sample_model = SampleModel(name="SampleModel") - sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) - - resolution_model = SampleModel(name="ResolutionModel") - resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) - - # THEN + temperature = 300.0 + # THEN EXPECT with pytest.raises( ValueError, match="Analytical convolution is not supported with detailed balance.", @@ -652,18 +658,13 @@ def test_analytical_convolution_fails_with_detailed_balance(self, x): sample_model=sample_model, resolution_model=resolution_model, method="analytical", - temperature=300.0, + temperature=temperature, ) - def test_convolution_only_accepts_analytical_and_numerical_methods(self, x): - # WHEN - sample_model = SampleModel(name="SampleModel") - sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) - - resolution_model = SampleModel(name="ResolutionModel") - resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) - - # THEN + def test_convolution_only_accepts_analytical_and_numerical_methods( + self, x, sample_model, resolution_model + ): + # WHEN THEN EXPECT with pytest.raises( ValueError, match="Unknown convolution method: unknown_method. Choose from 'analytical', or 'numerical'.", @@ -675,15 +676,8 @@ def test_convolution_only_accepts_analytical_and_numerical_methods(self, x): method="unknown_method", ) - def test_x_must_be_1d_finite_array(self): - # WHEN - sample_model = SampleModel(name="SampleModel") - sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) - - resolution_model = SampleModel(name="ResolutionModel") - resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) - - # THEN + def test_x_must_be_1d_finite_array(self, sample_model, resolution_model): + # WHEN THEN EXPECT with pytest.raises(ValueError, match="`x` must be a 1D finite array."): convolution( x=np.array([[1, 2], [3, 4]]), @@ -705,15 +699,13 @@ def test_x_must_be_1d_finite_array(self): resolution_model=resolution_model, ) - def test_numerical_convolve_requires_uniform_grid_if_no_upsample(self): + def test_numerical_convolve_requires_uniform_grid_if_no_upsample( + self, sample_model, resolution_model + ): # WHEN x = np.array([0, 1, 2, 4, 5]) # Non-uniform grid - sample_model = SampleModel(name="SampleModel") - sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) - resolution_model = SampleModel(name="ResolutionModel") - resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3)) - # THEN + # THEN EXPECT with pytest.raises( ValueError, match="Input array `x` must be uniformly spaced if upsample_factor = 0.", @@ -726,13 +718,11 @@ def test_numerical_convolve_requires_uniform_grid_if_no_upsample(self): upsample_factor=0, ) - def test_sample_model_must_have_components(self): + def test_sample_model_must_have_components(self, resolution_model): # WHEN sample_model = SampleModel(name="SampleModel") - resolution_model = SampleModel(name="ResolutionModel") - resolution_model.add_component(Gaussian(center=0.2, width=0.3, area=3)) - # THEN + # THEN EXPECT with pytest.raises( ValueError, match="SampleModel must have at least one component." ): @@ -742,13 +732,11 @@ def test_sample_model_must_have_components(self): resolution_model=resolution_model, ) - def test_resolution_model_must_have_components(self): + def test_resolution_model_must_have_components(self, sample_model): # WHEN - sample_model = SampleModel(name="SampleModel") - sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2)) resolution_model = SampleModel(name="ResolutionModel") - # THEN + # THEN EXPECT with pytest.raises( ValueError, match="ResolutionModel must have at least one component." ): @@ -758,44 +746,39 @@ def test_resolution_model_must_have_components(self): resolution_model=resolution_model, ) - def test_numerical_convolution_wide_sample_peak_gives_warning(self): + def test_numerical_convolution_wide_sample_peak_gives_warning( + self, resolution_model + ): # WHEN x = np.linspace(-2, 2, 20001) - sample_gauss1 = Gaussian(center=0.1, width=1.9, area=2, name="SampleGauss") - resolution_gauss = Gaussian(center=0.3, width=0.5, area=4) - + sample_gauss = Gaussian(center=0.1, width=1.9, area=2, name="SampleGauss") sample = SampleModel(name="SampleModel") - sample.add_component(sample_gauss1) - - resolution = SampleModel(name="ResolutionModel") - resolution.add_component(resolution_gauss) + sample.add_component(sample_gauss) # #THEN EXPECT with pytest.warns( UserWarning, - match=r"The width of the sample model component 'SampleGauss' \(1.9\) is large", + match=r"The width of the sample model component ", ): convolution( x=x, sample_model=sample, - resolution_model=resolution, + resolution_model=resolution_model, method="numerical", upsample_factor=0, ) - def test_numerical_convolution_wide_resolution_peak_gives_warning(self): + def test_numerical_convolution_wide_resolution_peak_gives_warning( + self, sample_model + ): # WHEN x = np.linspace(-2, 2, 20001) - sample_gauss1 = Gaussian(center=0.1, width=0.1, area=2, name="SampleGauss") resolution_gauss = Gaussian( center=0.3, width=1.9, area=4, name="ResolutionGauss" ) - sample = SampleModel(name="SampleModel") - sample.add_component(sample_gauss1) - resolution = SampleModel(name="ResolutionModel") resolution.add_component(resolution_gauss) @@ -806,25 +789,23 @@ def test_numerical_convolution_wide_resolution_peak_gives_warning(self): ): convolution( x=x, - sample_model=sample, + sample_model=sample_model, resolution_model=resolution, method="numerical", upsample_factor=0, ) - def test_numerical_convolution_narrow_sample_peak_gives_warning(self): + def test_numerical_convolution_narrow_sample_peak_gives_warning( + self, resolution_model + ): # WHEN x = np.linspace(-2, 2, 201) sample_gauss1 = Gaussian(center=0.1, width=1e-3, area=2, name="SampleGauss") - resolution_gauss = Gaussian(center=0.3, width=0.5, area=4) sample = SampleModel(name="SampleModel") sample.add_component(sample_gauss1) - resolution = SampleModel(name="ResolutionModel") - resolution.add_component(resolution_gauss) - # #THEN EXPECT with pytest.warns( UserWarning, @@ -833,23 +814,21 @@ def test_numerical_convolution_narrow_sample_peak_gives_warning(self): convolution( x=x, sample_model=sample, - resolution_model=resolution, + resolution_model=resolution_model, method="numerical", upsample_factor=0, ) - def test_numerical_convolution_narrow_resolution_peak_gives_warning(self): + def test_numerical_convolution_narrow_resolution_peak_gives_warning( + self, sample_model + ): # WHEN x = np.linspace(-2, 2, 201) - sample_gauss1 = Gaussian(center=0.1, width=0.2, area=2, name="SampleGauss") resolution_gauss = Gaussian( center=0.3, width=1e-3, area=4, name="ResolutionGauss" ) - sample = SampleModel(name="SampleModel") - sample.add_component(sample_gauss1) - resolution = SampleModel(name="ResolutionModel") resolution.add_component(resolution_gauss) @@ -860,7 +839,7 @@ def test_numerical_convolution_narrow_resolution_peak_gives_warning(self): ): convolution( x=x, - sample_model=sample, + sample_model=sample_model, resolution_model=resolution, method="numerical", upsample_factor=0, From 0649310613494219580ddcb0f7a9c98e2227d2af Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 31 Oct 2025 14:20:53 +0100 Subject: [PATCH 25/71] Clear example notebook --- examples/convolution.ipynb | 147 ++----------------------------------- 1 file changed, 5 insertions(+), 142 deletions(-) diff --git a/examples/convolution.ipynb b/examples/convolution.ipynb index e7cf84f..7c55b22 100644 --- a/examples/convolution.ipynb +++ b/examples/convolution.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "f42e34d0", "metadata": {}, "outputs": [], @@ -18,21 +18,10 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "600c0850", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(0.0, 6.0)" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# Standard example of convolution of a sample model with a resolution model\n", "sample_model=SampleModel(name='sample_model')\n", @@ -75,21 +64,10 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "id": "fede1a58", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(0.0, 2.5)" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# Use some of the extra settings for the numerical convolution\n", "sample_model=SampleModel(name='sample_model')\n", @@ -141,121 +119,6 @@ "\n", "\n" ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "8b9dbff2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "5bb238bc9e714fd79ae5139a921b8e4d", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAVr9JREFUeJzt3Qd8G+X9P/DPSbK8Je8Vjyw7eyeEMMIIEMKm7F3asmmhUAqBsn8QCi2lUMr6F8IIu+wSAgGSABlkkp04w/HetuSpef/XPWebbDJs3/q8W/Gc5dPdVzlL+up57p6vJMuyDCIiIiKyDJvWARARERFR72ICSERERGQxTACJiIiILIYJIBEREZHFMAEkIiIishgmgEREREQWwwSQiIiIyGKYABIRERFZDBNAIiIiIothAkhERERkMUwAiYiIiCyGCSARERGRxTABJCIiIrIYJoBEREREFsMEkIiIiMhimAASERERWQwTQCIiIiKLYQJIREREZDFMAImIiIgshgkgERERkcUwASQiIiKyGCaARERERBbDBJCIiIjIYpgAEhEREVkME0AiIiIii2ECSERERGQxTACJiIiILIYJIBEREZHFMAEkIiIishgmgEREREQWwwSQiIiIyGKYABIRERFZDBNAIiIiIothAkhERERkMUwAiYiIiCyGCSARERGRxTABJCIiIrIYJoBEREREFsMEkIiIiMhimAASERERWQwTQCIiIiKLYQJIREREZDFMAImIiIgshgkgERERkcUwASQiIiKyGCaARERERBbDBJCIiIjIYpgAEhEREVkME0AiIiIii2ECSERERGQxTACJiIiILIYJIBEREZHFMAEkIiIishgmgEREREQWwwSQiIiIyGKYABIRERFZjEPrAIwsHA6jvLwc8fHxkCRJ63CIiIjoAMiyjKamJmRlZcFms2ZfGBPAw6Akfzk5OVqHQURERIegpKQE2dnZsCImgIdB6fnr/ANyuVxah0NEREQHwOv1ig6czs9xK2ICeBg6h32V5I8JIBERkbFIFj59y5oD30REREQWxgSQiIiIyGKYABIRERFZDBNAIiIiIothAkhERERkMUwAiYiIiCyGCSARERGRxTABJCIiIrIYJoBEREREFmPpBLCsrAyXX345kpOTER0djREjRmDZsmVah0VERETUoyxbCq6hoQFHH300TjjhBMyePRupqakoLCxEYmKi1qERERER9SjLJoB//etfRSHoV155peu+fv36aRoTERERUW+w7BDwJ598gvHjx+OCCy5AWloaxowZg5deeknrsIiIqAfJ4TA+WbYd0z9Yg9lrKrQOh0gzlk0At23bhueeew75+fmYM2cObrjhBvzhD3/Aq6++us/H+Hw+eL3eXW5ERGQci/9zG1wfX4X3f9yGG2atwIsLtmodEpEmLJsAhsNhjB07Fo8++qjo/bv22mtxzTXX4Pnnn9/nY2bMmAG32911U4aQiYjIGApXLsDE0pk43v4TrskuFff9e84qFO/YpnVoRL3OsglgZmYmhg4dust9Q4YMQXFx8T4fM336dHg8nq5bSUlJL0RKRETdoWnu47BJMpa5TsIdN92IG3JLMMdxGyo/vEfr0Ih6nWUvAlGuAN60adMu923evBl5eXn7fExkZKS4ERGRsVSWbMGo5u8BCUiZNh2SJOHscf2RPrsR7oav4KmvgTspVeswiXqNZXsA//jHP2Lx4sViCHjLli1488038eKLL+Kmm27SOjQiIupmRQvehF2Ssd45An2HjBf3DZpwErbb8hAlBbBp/ttah0jUqyybAE6YMAEffvgh3nrrLQwfPhwPP/wwnnrqKVx22WVah0ZERN3MXfSFaL39pnXdJ9lsqMyeKpYjCj/XLDYiLVh2CFhxxhlniBsREZlXfXUZBvnXi+HfvkdfuMvvMiaeDxS/iKEtS9He2oyomDjN4iTqTZbtASQiImtYXtSAp4LnYbbzFGTk5u/yu75DJqAaSYiUAtiycp5mMRL1NiaARERkat9XAE+HfoXFw+7f43fKMHCxa6xYbtr4rQbREWnD0kPARERkfku214t2Yv/kvf6+Jf9s/HtJDEpaR2BSL8dGpBX2ABIRkWk1NtSib83XSIIXE/om7XWdnCN/hceDF+O/VenwB8O9HiORFpgAEhGRaRWvmofnI57Cx9EPITV+7/O49kuJRXyUQyR/m6uaej1GIi0wASQiItNq3bFCtNVxg/e5jjIp9FGZwPG2VShdv6gXoyPSDhNAIiIyLWftGtEG0kbsd71fS59hpvNxJG6Y1UuREWmLCSAREZlWeota8jOu77j9rheZq/4+2bOuV+Ii0hoTQCIiMiVPQy36yFViOWfokftdN2Owev1vXrAIfl97r8RHpCUmgEREZEql65eI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A1uoVf0hrI5oifRDDsPviENZxpSOQS4Zfcq/hDPgFb+vTRiB3CETMSK7e89d9HII2LoJoDIEHBMTg/fffx/nnHNO1/1XXXUVGhsb8fHHHx9QD6ByzqCV/4CIiIiMxssEsOtUKstxOp0YN24cvv7652FW5eIB5eedewR3FhkZKf5Qdr4RERERGY1lzwFU3HbbbaLHb/z48WLuP2UamJaWFlx9tXryPxEREZEZWToBvOiii1BTU4P77rtPTAQ9evRofPHFF3tcGEJERERkJpY9B7A78BwCIiIi4/Hy89u65wASERERWRUTQCIiIiKLYQJIREREZDFMAImIiIgshgkgERERkcUwASQiIiKyGCaARERERBbDBJCIiIjIYpgAEhEREVmMpUvBHa7OIirKjOJERERkDN6Oz20rF0NjAngYmpqaRJuTk6N1KERERHQIn+NutxtWxFrAhyEcDqO8vBzx8fGQJKnbv50oiWVJSYkp6xTy+Rmf2Z8jn5/xmf058vkdOlmWRfKXlZUFm82aZ8OxB/AwKH802dnZPboP5Y/ejC/sTnx+xmf258jnZ3xmf458fofGbdGev07WTHuJiIiILIwJIBEREZHFMAHUqcjISNx///2iNSM+P+Mz+3Pk8zM+sz9HPj86HLwIhIiIiMhi2ANIREREZDFMAImIiIgshgkgERERkcUwASQiIiKyGCaAGnnkkUdw1FFHISYmBgkJCXtdp7i4GKeffrpYJy0tDXfccQeCweB+t1tfX4/LLrtMTJqpbPe3v/0tmpubobV58+aJail7uy1dunSfjzv++OP3WP/666+HHvXt23ePWB977LH9Pqa9vR033XQTkpOTERcXh/POOw9VVVXQm6KiIvG31K9fP0RHR2PAgAHi6jy/37/fx+n9+D377LPiuEVFRWHixIn48ccf97v+e++9h8GDB4v1R4wYgc8//xx6NGPGDEyYMEFUKVLeO8455xxs2rRpv4+ZOXPmHsdKeZ569cADD+wRr3JszHD89vV+otyU9wujHr8FCxbgzDPPFNU3lPg++uijXX6vXJN63333ITMzU7zPnHTSSSgsLOz21zGpmABqRPngvOCCC3DDDTfs9fehUEgkf8p6CxcuxKuvvipe4MqLY3+U5G/dunX46quv8Nlnn4kX3LXXXgutKcluRUXFLrff/e53IqEYP378fh97zTXX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d911V9f6P/zwg+xwOOS//e1v4u9XuQpVuYp7zZo1st7ccMMN4orQefPm7XKsWltbu9bZ/fkp70Vz5swRf7/Lly+XL774YjkqKkpet26drEe33367eH7K35ZybE466SQ5JSVFXPFs9OO38xWtyvvDnXfeucfvjHj8lM+3zs865XPgySefFMvK56HiscceE69B5b1i9erV8tlnny1mGmhra+vaxoknnig/88wzB/w6pn1jAqiRq666SrwAdr99++23XesUFRXJ06ZNk6Ojo8Ubm/KGFwgEun6vrKs8RnkD7FRXVycSPiWpVKaMufrqq7uSSj1QYjvqqKP2+jvleez8b1BcXCyShaSkJPECVxKQO+64Q/Z4PLLeKG+4ypQSyoeu8qY7ZMgQ+dFHH5Xb29v3+fwUyhvbjTfeKCcmJsoxMTHyueeeu0tSpRfKFBN7+3vd+TukEY+f8kGifMA6nU4xncTixYt3mcJGeZ3u7N1335ULCgrE+sOGDZP/97//yXq0r2OlHMd9Pb9bb721698iPT1dPu200+QVK1bIenXRRRfJmZmZIt4+ffqIn5UvHWY4fp2UhE45bps2bdrjd0Y8fp2fWbvfOp+HMhXMvffeK+JX3jOUL5y7P3dlui0leT/Q1zHtm6T8Z+ceQSIiIiIyN84DSERERGQxTACJiIiILIYJIBEREZHFMAEkIiIishgmgEREREQWwwSQiIiIyGKYABIRERFZDBNAIiIiIothAkhERERkMUwAiYiIiCyGCSARERGRxTABJCIiIrIYJoBEREREFsMEkIiIiMhimAASERERWQwTQCIiIiKLYQJIREREZDFMAImIiIgshgkgERERkcUwASQiIiKyGCaARERERBbDBJCIiIjIYpgAEhEREVkME0AiIiIii2ECSERERGQxTACJiIiILIYJIBEREZHFMAEkIiIishgmgEREREQWwwSQiIiIyGKYABIRERHBWv4/QaxfG7YfoMUAAAAASUVORK5CYII=", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "\"Test convolution of Lorentzian and Delta function sample components in SampleModel and Gaussian resolution components in SampleModel.\"\n", - "\" Result is a combination of Voigt profile and Gaussian.\"\n", - "%matplotlib widget\n", - "from scipy.special import voigt_profile\n", - "\n", - "lorentzian_component = Lorentzian(center=0.1, width=0.3, area=2.0)\n", - "offset_obj =0.0\n", - "method = 'analytical'\n", - "expected_shift = offset_obj\n", - "\n", - "resolution_model = SampleModel(name=\"TestResolutionModel\")\n", - "resolution_model.add_component(Gaussian(center=0.2, width=0.8, area=3.0))\n", - "\n", - "sample = SampleModel(name=\"SampleModel\")\n", - "sample.add_component(lorentzian_component)\n", - "sample_delta = DeltaFunction(center=5.1, area=4, name=\"SampleDelta\")\n", - "sample.add_component(sample_delta)\n", - "\n", - "# THEN\n", - "x = np.linspace(-10, 10, 20001)\n", - "calculated_convolution = convolution(\n", - " x=x,\n", - " sample_model=sample,\n", - " resolution_model=resolution_model,\n", - " offset=offset_obj,\n", - " method=method,\n", - " upsample_factor=5,\n", - ")\n", - "\n", - "# EXPECT: Combine Gaussian, Lorentzian, and Delta functions contributions\n", - "# \n", - "gaussian_component = resolution_model[\"Gaussian\"]\n", - "\n", - "expected_voigt_area = (\n", - " lorentzian_component.area.value * gaussian_component.area.value\n", - ")\n", - "expected_voigt_center = (\n", - " lorentzian_component.center.value\n", - " + gaussian_component.center.value\n", - " + expected_shift\n", - ")\n", - "expected_voigt = expected_voigt_area * voigt_profile(\n", - " x - expected_voigt_center,\n", - " gaussian_component.width.value,\n", - " lorentzian_component.width.value,\n", - ")\n", - "expected_gauss_area = sample_delta.area.value * gaussian_component.area.value\n", - "expected_gauss_center = (\n", - " sample_delta.center.value + gaussian_component.center.value + expected_shift\n", - ")\n", - "expected_gauss_width = gaussian_component.width.value\n", - "expected_gauss = (\n", - " expected_gauss_area\n", - " * np.exp(-0.5 * ((x - (expected_gauss_center)) / expected_gauss_width) ** 2)\n", - " / (np.sqrt(2 * np.pi) * expected_gauss_width)\n", - ")\n", - "expected_result = expected_voigt + expected_gauss\n", - "\n", - "plt.figure()\n", - "\n", - "plt.plot(x, calculated_convolution, label='Convoluted Model')\n", - "plt.plot(x, expected_result, '--', label='Expected Result')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9d92cad4", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { From 4adf07d52338091403afebd3f25072694f0d5b4e Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 31 Oct 2025 14:22:02 +0100 Subject: [PATCH 26/71] Add comment about thresholds --- src/easydynamics/utils/convolution.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py index 84a4364..29ef94a 100644 --- a/src/easydynamics/utils/convolution.py +++ b/src/easydynamics/utils/convolution.py @@ -547,6 +547,8 @@ def _check_width_thresholds( If the component widths are not appropriate for the data span or bin spacing. """ + + # The thresholds are illustrated in performance_tests/convolution/convolution_width_thresholds.ipynb LARGE_WIDTH_THRESHOLD = ( 0.1 # Threshold for large widths compared to span - warn if width > 10% of span ) From bc498ba602d0afdab64863dabb6ddd1982d5a977 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 31 Oct 2025 14:27:29 +0100 Subject: [PATCH 27/71] Delete old examples --- .../convolution_and_detailed_balance.ipynb | 689 ------------- examples/convolution_example .ipynb | 959 ------------------ 2 files changed, 1648 deletions(-) delete mode 100644 examples/convolution_and_detailed_balance.ipynb delete mode 100644 examples/convolution_example .ipynb diff --git a/examples/convolution_and_detailed_balance.ipynb b/examples/convolution_and_detailed_balance.ipynb deleted file mode 100644 index b3065f5..0000000 --- a/examples/convolution_and_detailed_balance.ipynb +++ /dev/null @@ -1,689 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "64deaa41", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "\n", - "from easydynamics.sample import Gaussian\n", - "from easydynamics.sample import Lorentzian\n", - "from easydynamics.sample import Voigt\n", - "from easydynamics.sample import DampedHarmonicOscillator\n", - "from easydynamics.sample import Polynomial\n", - "from easydynamics.sample import SampleModel\n", - "\n", - "from easydynamics.resolution import ResolutionHandler\n", - "\n", - "import matplotlib.pyplot as plt\n", - "\n", - "\n", - "from easydynamics.utils import detailed_balance_factor\n", - "\n", - "from easyscience.variable import Parameter\n", - "%matplotlib widget" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a49c5cda", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0, 0.5, 'Detailed Balance Factor')" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "bebf710b7fdf4dd78b073a8f6b08fcbb", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+gAAAJYCAYAAADxHswlAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAnuVJREFUeJzs3Qd0VEUbxvEnCRB671U6KE1RQHpTwAZi7xUVsSEKIoKIKAooiIKIvWH97AqKIKA0EaWJIB3pSAsthSTfeee6KRBa2t0k/985l+Teu7uZLST77My8ExIfHx8vAAAAAADgq1B/fzwAAAAAADAEdAAAAAAAggABHQAAAACAIEBABwAAAAAgCBDQAQAAAAAIAgR0AAAAAACCAAEdAAAAAIAgQEAHAAAAACAIENABAAAAAAgCBHQAAAAAAIIAAR0AAAAAgCBAQAcAAAAAIAgQ0AEAAAAACAIEdAAAAAAAggABHQAAAACAIEBABwAAAAAgCBDQAQAAAAAIAgR0AAAAAACCAAEdAAAAAIAgQEAHAAAAACAIENABAAAAAAgCBHQAAAAAAIIAAR0AAAAAgCBAQAcAAAAAIAgQ0AEAAAAACAIEdAAAAAAAggABHQAAAACAIEBABwAAAAAgCBDQAQAAAAAIAgR0AAAAAACCAAEdAAAAAIAgQEAHAAAAACAIENABAAAAAAgCBHQAAAAAAIIAAR0AAAAAgCBAQAcAAAAAIAgQ0AEAAAAACAIEdAAAAAAAggABHQAAAACAIEBABwAAAAAgCBDQAQAAAAAIAgR0AAAAAACCAAEdAAAAAIAgQEAHAAAAACAIENABAAAAAAgCBHQAAAAAAIIAAR0AAAAAgCBAQAcAAAAAIAgQ0AEAAAAACAIEdABAhrv55pt12mmnJTsWEhKiwYMHp9vPmD59urtN++oHu392PwEAAFKLgA4A2cBbb73lwmlgy5s3r8qXL69OnTppzJgx2rdvX6pve9myZS5Ir1u3TtnxsbKtdOnSateunSZNmqSc7sjHJrCVLVs23X/WuHHj3PORXdj/kWM9frY988wzfjcRABDkcvndAABA+hkyZIiqVq2qmJgYbd261fUmP/DAA3r++ef11VdfqUGDBqkK6E888YTatm17VC/4yXr11VcVFxenYHys4uPjtW3bNhcUL7jgAn399de66KKLlJOdd955uvHGG5Mdy5cvX4YE9JIlS2a7kQfXXHONey0d6cwzz/SlPQCArIOADgDZSJcuXXT22Wcn7Pfv31/Tpk1zgfOSSy7RX3/9lSFB60Ry586tYH+sbrvtNpUpU0YffPBBjg/otWrV0vXXX6+sKDIyUnny5FFoqH+DBM8666ygePwOHz7sPhizxwMAkDUwxB0Asrn27dtr4MCBWr9+vd57771k55YvX67LL79cxYsXd8PiLbBaT3uA9SpfccUV7nsbAh4YqhuY5/3ll1/qwgsvdMPpw8PDVb16dT355JOKjY094Rz0lGzatEm33nqrC8p2e2eccYbeeOONoy63ceNGdevWTQUKFHDD03v37q2oqCilRdGiRd2HF7lyJf/seuTIkWrevLlKlCjhzjdu3FiffvrpCW9v165deuihh1S/fn0VLFhQhQsXdh8KLFq0KMW58x9//LGeeuopVaxY0T0XHTp00KpVq4663Xnz5rne2WLFirn7b6MiXnjhhVN6XtPiVB4Pe701adJE+fPnd+1t3bq1fvjhB3fOXg9//vmnZsyYkfC6slEaAWvWrHGvPbsPdv1mzZrp22+/TfGx+/DDD/XYY4+pQoUK7rIRERFHtcVGldht3XLLLUeds8vb42TPV8CLL77oXn+BtttjOHHiRKUXu//2QdAvv/ziHiP7+dWqVdM777xz1GX37NnjRsJUqlTJ/b+oUaOGnn322WSjUgLD6+35GT16tPu/aJe1ETCBx8rug/0cO/fKK6+4qSt2nYA2bdqoYcOGKba3du3absoMACBj0YMOADnADTfcoEcffdSFox49erhjFo5atGjhQs0jjzziwp6FRAu+//vf/3TppZe6QHXfffe5eex2/bp167rrBr5agLfw+eCDD7qv1ls/aNAgF3hGjBhxSm20YeYWwiww3HPPPSpVqpSbE24923Z7FlDMoUOHXHjdsGGDa5t9OPDuu++6n30q9u7dq3///dcNcd++fbsLZPv37z+q59PCr40+uO666xQdHe3CoAXHb775xn04cSwWML/44gt3WRtKb/fPQpGFIAtN1u6kbH6y9fpaSLS2DR8+3P1MC+QBU6ZMcaGuXLlyuv/++928cBsVYW2x/ZN9Xk+mF9oem6QKFSrkAt/JPh42LcICoIV5m05gvbh2X+x5Ov/8812IvPfee93rZsCAAe469sGMscfKrnfw4EH3HNuHAW+//bb7ufZhwJH3wT4Ustu3x84+qEmpx9hGcdj1PvvsM/c8JL2MPU92vauvvjphSob9XPuQwx5XezwWL17s2n/ttdee8PGzdh/5+AU+BEr6AZB9AGM/w17jN910k/swyj7Msg897MOBwG3Za8Y+vLrzzjtVuXJlzZ49242O2bJli3sck3rzzTdde++44w73fNmHEn/88Yc6d+7sXjf2vNgHaPac2P+xI39P2O+HpUuXql69egnH58+fr7///tt9CAIAyGDxAIAs780334y3X+nz588/5mWKFCkSf+aZZybsd+jQIb5+/frxkZGRCcfi4uLimzdvHl+zZs2EY5988om77Z9++umo2zx48OBRx+688874/PnzJ7vdm266Kb5KlSrJLme3+fjjjyfs33bbbfHlypWL//fff5Nd7uqrr3ZtD/ys0aNHu+t+/PHHCZc5cOBAfI0aNY7ZzpQeqyO38PDw+LfeeuuE9zE6Ojq+Xr168e3bt0923O6f3c8Au/+xsbHJLrN27Vr3c4YMGZJwzNprP79u3brxUVFRCcdfeOEFd3zJkiVu//Dhw/FVq1Z1P2f37t3Jbteet1N9Xo8lpcfGNnvcTvbxWLlyZXxoaGj8pZdeetRjkLStZ5xxRnybNm2OasMDDzzgfubPP/+ccGzfvn3u/p922mkJtxl47KpVq5bia/FI33//vbv8119/nez4BRdc4G4joGvXrq5tp8qe32M9frbNmTMn4bL2PNqxmTNnJhzbvn27e3306dMn4diTTz4ZX6BAgfi///472c965JFH4sPCwuI3bNiQ7GcXLlzY3U5SF198sfs/uWnTpmTPUa5cudx1Avbs2ROfN2/e+H79+iW7/n333efasH///lN+TAAAp4Yh7gCQQ1hPZaCauw2/tp7MK6+80h2z3j7bdu7c6Yaxrly50vXYnUjS+eyB22nVqpXr9bNh1ifLcqH17l588cXu+0B7bLP2WI/y77//7i773XffuZ5A63kMsGHI1mN4KsaOHet6pG2zodg2hP/22293PazHuo+7d+92bbH7GGjPsVjvZWAetPVY2mNrz4ENFU7pujb0Ommvrv2MQE+8sV7QtWvXupEE1hObVGCYcno9r127dk14bAJbYHjzyTwe1iNtw69tNMWRc8GTDqk+FnuObdh3y5YtE47ZY2fPsQ3lDgzbDrDe55OprWDT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bgCQFiEhIcfdBg8efMq3+dZbbx11O3nz5k12mfj4eA0aNEjlypVTvnz51LFjR61cufKotn1hn8z+JyYmRtdcc40qVKigpUuXpuFeAwAA4IRiY6XvvpO6d5cqVZIefdQL51bkrVcvaeFCae5c6dZbCecIGvSgI0vbYp+G/uejjz5yoXnFihUJxwqm8pdt4cKFk92Ohe2khg8frjFjxujtt99W1apVNXDgQHXq1EnLli07KsybgwcP6rLLLnMh/pdffnHXAQAAQAZYt0564w3pzTeljRsTj597rtdbfsUVUoECfrYQOCYCOrK0smXLJnxfpEgRF6STHkut492O9Z6PHj1ajz32mLp27eqOvfPOOypTpozrMb/aCooksWfPHl144YXav3+/C+fp0T4AAAAkERUlffWV9Npr0pQp3jrmpnhx6YYbpNtuk+rX97uVwAkxxB05gvWkH2+76667kl3ewnSVKlVUqVIlF8L//PPPhHNr167V1q1b3bD2pB8ONG3aVHPmzEl2O3a5Nm3auO9nzJhBOAcAAEhPy5ZJffpIFSt688h/+MEL5x06SB98IG3aJI0eTThHlkEPOo7LeosPxhzM9J+bP3f+o4aVp8VCm2N0giHtAbVr19Ybb7yhBg0aaO/evRo5cqSaN2/uQnrFihVd6DbWY56U7QfOBdx///2qVq2apkyZovz586fb/QEAAMix9u+XPvnEK/iWtHOkfHnpllu8OeXVqvnZQiDVCOg4LgvnBYdlftGM/f33q0Ce9JsbVKNGjZO+7Lnnnuu2AAvndevW1SuvvKInn3zylH7uRRdd5Ia923V79+59StcFAADAf6xX/LffvCHs1jO+b593PCzM3nBJt98ude4s5SLeIGvjFYwc4UTF4q6//nqNHz8+xXO5c+fWmWeeqVWrVrn9wDD1bdu2uSruAbbfqFGjZNe94YYbdMkll+jWW291oxEefPDBdLg3AAAAOcSuXdL773vBfPHixOPVq3uh/KabpCTvx4CsjoAeRF5++WW3rbPKk5LOOOMMV5W8S5cubr9t27ZuHnNSd9555zGDZXoNNbfe7MxmPzc9ncoQ9yPFxsZqyZIluuCCC9y+VWC3kD516tSEQB4REaF58+apZ8+eR13/pptuUmhoqG655RbFxcXpoYceSvP9AQAAyLbi4qx4jxfK//c/rwCcCQ+XLr/cC+atW0uhlNNC9kNADyI2v/mZZ55RzZo1XW+rLeFlBcr++OMPF9ZNjx49NGTIkITrZPS8ZpsHnp5Dzf1yKkPc7fFt1qyZu45VYB8xYoTWr1+v2+2PwX+PyQMPPKChQ4e65yqwzFr58uXVrVu3FG/TetItpFtYt+f24YcfTrf7BgAAkC1s3iy9/bb0+uvS6tWJxxs0sDfB0nXXScWK+dlCIMMR0IPIxRdfnGz/qaeecj3qc+fOTQjoFsipBJ6xdu/e7T4IsYJvxYoVU+PGjTV79mydfvrpCZfp27evDhw4oDvuuMOF+JYtW2ry5MkproEecN1117mQbmHdetL79euXSfcIAAAgSB0+LE2a5PWWf/utDV30jhcqJF17rddb3rix9ZD43VIgU4TEW3cego4Nq/7kk09cj6v1oFs4tCHuVkncnjIL6Rboref2eL3oUVFRbguwodi2dJhVJz9yWHdkZKRbQsx6hI8XNOEfniMAAJAtWA/5G29Ib74pbdmSeLxFCy+UX3GFVCDrj+IMdpYNbLnglLIB/EEPepCxuc5WQdyCmBU2+/zzzxN6bq+99lq3NrcNpV68eLHrgV2xYoU+++yzY97esGHD9MQTT2TiPQAAAABSEBkpff6511s+bVri8ZIlvWJvt90m1a3rZwsB39GDHmSio6O1YcMG9ynWp59+qtdee80Vhks6vDpg2rRp6tChg6suXt0qWaaAHvTshecIAABkOUuWeKH83XdtLqF3zIasn3++11t+ySVSnjx+tzJHogc9+NCDHmTy5MmTUNDM5j7Pnz9fL7zwgltH+0hNmzZ1X48X0MPDw90GAAAAZJo9e6QPP/SGsc+fn3i8UiXp1lulW26RqlTxs4VAUCKgBzkrJpa0BzylpcOSrsUNAAAA+Lo8moXyTz/1hrSbXLmkrl293vLzzpPCwvxuKRC0COhBpH///m7N88qVK2vfvn2aOHGipk+fru+//16rV692+7YWd4kSJdwc9N69e6t169ZqYEtPAAAAAH7YsMFbHs0Kvq1dm3jcpmjavPLrr5dKl/azhUCWQUAPItu3b9eNN96oLVu2uLkgFrwtnJ933nn6559/9OOPP2r06NFueS+bR37ZZZfpscce87vZAAAAyGmsd/zLL73e8ilTpEBZK5vHfM013jD2c85heTTgFBHQg8jrr79+zHMWyK1YHAAAAOAbm2Jp71nffz+x4Jtp29YL5ZddJh1nCWAAx0dABwAAAHBsu3ZJEyd6veV//JF4vGJF6eabve0YBYsBnBoCOgAAAIDkYmOlqVO9UG5rl0dHe8dtObRu3bze8o4dKfgGpDMCOgAAAACPFXl76y1vs+JvAVaU2Aq+XXedVKKEny0EsrVQvxsApEVISMhxt8GDB5/ybX722Wc6++yzVbRoURUoUECNGjXSu+++m+wy8fHxGjRokFviLl++fOrYsaNWrlyZ7DK7du3Sddddp8KFC7vbuu2227R///6E81ah39q4x9YJ/c/mzZtVv359V51/7969qXpMAAAATsmhQ96c8g4dpGrVpCFDvHBetKjUq5e0YIE39/y++wjnQAajBx1ZmlW8D/joo49caF6xYkXCsYIFC57ybRYvXlwDBgxQnTp1lCdPHn3zzTe65ZZbVLp0aXXq1MldZvjw4RozZozefvttVa1aVQMHDnTnli1bprx587rLWDi39k2ZMkUxMTHuNu644w63XF5KbCk9q9h/+umn65NPPnHBHwAAIENY1fXffvOGsH/wgRToGLCq6xbUrbfchrL/974GQOYgoCNLK1u2bML3tjSd9UgnPZYaba0KaRL333+/C+K//PKLC+HWe27L3dkSd127dnWXeeedd1SmTBl98cUXuvrqq/XXX39p8uTJmj9/vuuNNy+++KJbx37kyJEqX758sp9h69rbbbdv3979rFy5+K8JAAAywI4dXm+5BfMlSxKPV6ki3XKLdNNN0mmn+dlCIEdjiDtyBOtJP9521113pXg9C+NTp051vfI27NysXbtWW7dudcPak3440LRpU82ZM8ft21cb1h4I58YuHxoaqnnz5iX7GbNnz1abNm3cuvbvvfce4RwAAKSvw4el776TLr9cqlBB6t3bC+fh4dK110o//iitWSM9/jjhHPAZSQAnHv508GDm/1xbP9OGWKWThTZv6jhsnnhSNv+7QoUKioqKUlhYmMaNG+eGnxsL58Z6zJOy/cA5+2pD4pOy4G3D5wOXCbj00kt11VVX6aWXXkrDPQQAADiCTft7+21v27w58bh1IFgV9quvlooV87OFAI5AQMfxWThPxTzuNLNiagUKpNvN1ahR45QuX6hQIRfqraib9aA/+OCDqlat2lHD39ODDZP//PPP9fPPP6tVq1bpfvsAACAHsbnkH38svfmm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", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Detailed balance vs energy, meV scale\n", - "x=np.linspace(-20, 20, 1000)\n", - "\n", - "T=0\n", - "DetailedBalanceT1=detailed_balance_factor(x,T)\n", - "plt.figure(figsize=(10, 6))\n", - "plt.plot(x, DetailedBalanceT1, label=f'T={T}K', color='blue')\n", - "\n", - "T=50\n", - "DetailedBalanceT2=detailed_balance_factor(x,T)\n", - "plt.plot(x, DetailedBalanceT2, label=f'T={T}K', color='green')\n", - "\n", - "\n", - "T=300\n", - "DetailedBalanceT3=detailed_balance_factor(x,T)\n", - "plt.plot(x, DetailedBalanceT3, label=f'T={T}K', color='red')\n", - "\n", - "plt.title('Detailed Balance Factor vs Energy')\n", - "plt.legend()\n", - "\n", - "plt.xlabel('Energy (meV)')\n", - "plt.ylabel('Detailed Balance Factor')\n" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "26c85776", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0, 0.5, 'Detailed Balance Factor')" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "1e0a95a396bc462a950c363d920e2bea", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+gAAAJYCAYAAADxHswlAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAUaJJREFUeJzt3QecFPX9P/7PUQVpVhBFRSV2rLHHHmtU0CRq7D3GbmxEsSuxxFhijYkt9hKNmmgMFjRijy1GY6+AsQCCAgr7f7w/v//e9w4OOK6ws/B8Ph7r7c7OznxmZw7vNZ9WUyqVSgkAAACoqDaV3T0AAAAQBHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAWt3ee++dllxyyXrLampq0qmnntpi+3j00UfzNuNnJcTxxXECADSVgA4wB7j22mtzOC0/5plnntS7d++05ZZbposvvjh99dVXTd72a6+9loP0e++9l+bE7yoeCy+8cNpkk03S3/72tzS3m/q7KT969erV4vu67LLL8vmYU8TvyPS+v3j8+te/rnQRASi4dpUuAAAt5/TTT099+/ZN3377bRo5cmSuTT7yyCPTBRdckP7yl7+k/v37Nymgn3baaWnjjTeepha8sX7/+9+nKVOmpCJ+V6VSKY0aNSoHxW222Sbde++96Uc/+lGam/3whz9Me+65Z71lnTp1apWAvuCCC85xLQ923XXXfC1NbbXVVqtIeQCoHgI6wBxk6623TmuuuWbt60GDBqWHH344B87tt98+/ec//2mVoDUz7du3T0X/rvbbb7/Us2fPdPPNN8/1Af173/te2n333VM1mjBhQurQoUNq06ZyjQRXX331Qnx/3333Xb4xFt8HANVBE3eAOdymm26aBg8enN5///30pz/9qd57r7/+evrxj3+c5p9//twsPgJr1LSXRa3yT37yk/w8moCXm+qW+3nfc889adttt83N6Tt27JiWXnrpdMYZZ6TJkyfPtA96Qz7++OO077775qAc21txxRXTH//4x2nW++ijj9KAAQPSvPPOm5unH3XUUWnixImpOXr06JFvXrRrV//e9fnnn5/WW2+9tMACC+T311hjjXTHHXfMdHtffPFFOuaYY9LKK6+cunTpkrp165ZvCrz00ksN9p2/7bbb0llnnZUWW2yxfC4222yz9NZbb02z3aeffjrXzs4333z5+KNVxEUXXTRL57U5ZuX7iOttrbXWSp07d87l3XDDDdPf//73/F5cD//+97/TY489VntdRSuNsnfeeSdfe3EM8fl11lkn3X///Q1+d7fccks66aST0qKLLprXHTt27DRliVYlsa199tlnmvdi/fie4nyVXXLJJfn6K5c9vsObbroptZQ4/rgR9MQTT+TvKPa/1FJLpeuvv36adUePHp1bwvTp0yf/XiyzzDLpnHPOqdcqpdy8Ps7PhRdemH8XY91oAVP+ruIYYj/x3pVXXpm7rsRnyjbaaKO0yiqrNFjeZZddNneZAaB1qUEHmAvsscce6Ve/+lUORwcccEBeFuFo/fXXz6HmhBNOyGEvQmIE3zvvvDMNHDgwB6rDDz8892OPzy+//PL5s+WfEeAjfB599NH5Z9TWn3zyyTnwnHfeebNUxmhmHiEsAsOhhx6aFlpoodwnPGq2Y3sRUMI333yTw+sHH3yQyxY3B2644Ya871kxZsyY9Nlnn+Um7p9++mkOZOPGjZum5jPCb7Q+2G233dKkSZNyGIzgeN999+WbE9MTAfPuu+/O60ZT+ji+CEURgiI0Rbnriv7JUesbITHKdu655+Z9RiAve+ihh3KoW2SRRdIRRxyR+4VHq4goS7xu7HltTC10fDd1de3aNQe+xn4f0S0iAmCE+ehOELW4cSxxnrbYYoscIg877LB83Zx44on5M3FjJsR3FZ/7+uuv8zmOmwHXXXdd3m/cDJj6GOKmUGw/vru4UdNQjXG04ojP3XXXXfk81F0nzlN8bpdddqntkhH7jZsc8b3G9/Hyyy/n8v/sZz+b6fcX5Z76+yvfBKp7AyhuwMQ+4hrfa6+98s2ouJkVNz3i5kB5W3HNxM2rgw46KC2++OLpySefzK1jRowYkb/Huq655ppc3gMPPDCfr7gp8a9//StttdVW+bqJ8xI30OKcxO/Y1P9OxL8Pr776alpppZVqlz/77LPpv//9b74JAkArKwFQ9a655ppS/JP+7LPPTned7t27l1ZbbbXa15tttllp5ZVXLk2YMKF22ZQpU0rrrbdeqV+/frXLbr/99rztRx55ZJptfv3119MsO+igg0qdO3eut9299tqrtMQSS9RbL7Z5yimn1L7eb7/9Sossskjps88+q7feLrvskste3teFF16YP3vbbbfVrjN+/PjSMsssM91yNvRdTf3o2LFj6dprr53pMU6aNKm00korlTbddNN6y+P44jjL4vgnT55cb51333037+f000+vXRbljf0vv/zypYkTJ9Yuv+iii/LyV155Jb/+7rvvSn379s37+fLLL+ttN87brJ7X6Wnou4lHfG+N/T7efPPNUps2bUoDBw6c5juoW9YVV1yxtNFGG01ThiOPPDLv8/HHH69d9tVXX+XjX3LJJWu3Wf7ullpqqQavxak9+OCDef1777233vJtttkmb6Nshx12yGWbVXF+p/f9xWP48OG168Z5jGXDhg2rXfbpp5/m6+OXv/xl7bIzzjijNO+885b++9//1tvXCSecUGrbtm3pgw8+qLfvbt265e3Utd122+XfyY8//rjeOWrXrl3+TNno0aNL88wzT+n444+v9/nDDz88l2HcuHGz/J0AMGs0cQeYS0RNZXk092h+HTWZP/3pT/OyqO2Lx+eff56bsb755pu5xm5m6vZnL2/nBz/4Qa71i2bWjRW5MGp3t9tuu/y8XJ54RHmiRvmFF17I6/71r3/NNYFR81gWzZCjxnBWXHrppblGOh7RFDua8O+///65hnV6x/jll1/mssQxlsszPVF7We4HHTWW8d3GOYimwg19Nppe163VjX2Ua+JD1IK+++67uSVB1MTWVW6m3FLndYcddqj9bsqPcvPmxnwfUSMdza+jNcXUfcHrNqmenjjH0ex7gw02qF0W312c42jKXW62XRa1z40ZWyG6e8SgdLfeemu9Y4jj23nnnWuXxfcb3Sii5rgpopxTf3/xWGGFFeqtF6/L5zlEjXZcH+VzHm6//fa8TjSzr/t7sfnmm+fratiwYfW2udNOO9WrGY91/vGPf+QWFHVbbUQz+ehyUVf37t3zuY9xGP7fvZr/9/n4vspdSgBoXZq4A8wlovl29NcuN62NP8Cjb3o8GhLNvqOZ9IxEc+po9hqhcOp+vxHcGut///tf7md71VVX5cf0yhOiL32Ei6mDXgSbWREBsO4gcTHydoyyHc3roxl5OSxH0+0zzzwzvfjii/X6uc8saEZAjebgMVJ5BOu6/fKjyfbUoulyXRHIygEyvP322/ln3abHU2up8xr94CMANqQx30eUNYL51IG0seIcr7322tMsL3etiPfrfg/RhaAxonl5BNjoSx5lj5socUMm+qfXDejHH398DrVxjcS1Fk3yo2l7dB1ojH79+k33+5vROS+f9/I5D3FTJZrXT90cferfi+l9F/F+dAuJ45haQ8ti9P4I5I8//nju4hLfQ3Q5iObvALQ+AR1gLhC1gRGYy3+QlweXij670xv4qaE/3uuKQB19Y2Pws+jPGgNPxQBUUZMaAWdWplUrrxv9v6M2tCFNmSJuVkSgjFr0CNURiqIPcISU6PccQSWCdtTcR1/m6Oc7swHDzj777BySY9C76CMdfYFjH1ED3tB307Zt2wa3U67JbIyWOK8z0pzvozXNyswE0c88+qDH+AZRKxz985dbbrl6g6PFjYA33ngj34x44IEHcuuOON5oERB9uFtKY855nNOY9u64446b7oj7dTV3loa4bmIsgGhVEuc5fsZYB4254QBA8wnoAHOBGEQtlENbjBYdIlzN7A/v6dUUx6jQ0XQ6aiDjD/myqC2eVVE7GIOQRS3zzMqzxBJL5EGsIsTULVsEqpaYlqrc2iBEMIubDg8++GCubS2LQDozMZhZBP4//OEP09zYiGbWsypugIQ49ul9R7NyXpuisd9HlDWCZTRFX3XVVWf52opz3ND5LHebiPebKq7VuLEQtcTRhD5af5QHqasrmnNHrXo8YjC8HXfcMY+yH4OzxXcwu8R3GddjU89ntJqJ8jY0I0BDy+KmQbQWiAEgY6T46K4QA8dN72YCAC1LH3SAOVwEkKjBjaavMfJ2+Y/2mNIqahJjJOiGmpyXlfudRrCsq/wHe93avggyUdM4q2Jb0fQ4AmAE0BmVJ6YY++STT+pN7RV93qfXNL6xoplzjHIfTdvLTamjXBEi6zZPjz7QEVoac0xT135Hf+LG9AGf3tzacQ5j1O6pz0V5P7NyXpuisd9H1ExHa4FoWTF1a4G630lcW1MfS/kcP/PMM2n48OG1y8aPH5/PcUxP1tSm8yHKFeMX3HvvvfnGVdyUqdu8PcSNp7rimoh9RtnjOpmdYjyB+B7ipsjU4rsr31Sa0TmLcB/nKH5v6obzaEXQkGjOHs3sY9T4hmY2AKD1qEEHmIPEH9xRyxh/tEe/0QjnMThV1DjGPNh1a/5ikLSoQYx5uqOGLGpf4zMRBqJJfHm+7qgBjT/yozYtmslHzWkMthXTYEV/2WiSHlNSRXCLwDMrTbKnnmbskUceyX2PozwRiGLQs2gyH/1g43mI9373u9/lvrLPP/98rg2N/cZAcU35rsr9dKOJdjRtj6nJotl+iGnDLrjggjxFVdQqxnrxvUUz8egXPCPRjz0Cagz+Ft/VK6+8km688cbaWu6mBMvLL788D6QX5yS2G8cexxBjAZQDXGPPa1M09vuI11ErHTeGYoCzqH2O6yYGXYuByoYMGZLXi+nE4piiT3t8Jm4wxLUV5yAGKotBzOLaiu4BMc1atM6ImzhTDzw3qyKQx7R6p5xySv6eyjdkyqLPeTTrjj7n0dw7prKLay6OP1p6zExcs9E0vKHa8HXXXXeWynrsscfm3924nspTsMXNirie4iZV3CCZWYuMmO4ubj7F8Rx88MH5BkscT/Tjj7EEphZjMcR7cUMpvpu4OQTAbDKLo74DUEBTTx3WoUOHUq9evUo//OEP83RdY8eObfBzb7/9dmnPPffM67Zv37606KKLln70ox+V7rjjjnrr/f73v8/TUMW0TnWnMvvnP/9ZWmeddUqdOnUq9e7du3TcccfVTmVVd7qzxkyzFkaNGlU65JBDSn369MnliXLFtGFXXXVVvfXef//90vbbb5+njlpwwQVLRxxxROmBBx5o8jRrMbXUqquuWrr88svrTQMW/vCHP+TpyWL6q+WWWy5/Pso99f9CG5pmLabLiqnj4vtZf/318zRbMa1Y3anFylOFxXR2dZWnzSpPb1b2xBNP5PPatWvXPPVV//79S5dcckmTzmtDYp9xDqansd9H+OMf/5in9ot155tvvnzcDz30UO37I0eOLG277bb5WOLzdb+XOIYf//jHpR49euTzs9Zaa5Xuu+++etuf3nc3M3GO4xqLz5555pnTvH/llVeWNtxww9ICCyyQy7700kuXjj322NKYMWOaNc1a3esjrpc49qlNfX2Up5gbNGhQnkowfrfjmo9p884///w8zV3dfZ933nkNlm3o0KH5XMTn43iuvvrqfH3Gd9uQc889N2/v7LPPnuExA9CyauI/s+tmAAAAxRBdEaL1RbQcmVoMlnjUUUflGvqGRpsHoHXogw4AMIeLqdbqilAe883HmAVTi7qbGNwwZmkQzgFmL33QAQDmcDEWQfRhj58xj3z0/Y/B7+pO3xZ926O/e4wFEX3c77nnnoqWGWBupIk7AMAcLgYVjOA9cuTIPGBfDFZ39tln1xsALpqzx0wBPXr0SL/4xS/ytHIAzF4COgAAABSAPugAAABQAAI6AAAAFIBB4uYyU6ZMSZ988knq2rVrqqmpqXRxAACAConezl999VXq3bt3atNG3W0RCOhzmQjnffr0qXQxAACAgvjwww/TYostVuliIKDPfaLmvPxL2K1bt0oXBwAAqJCxY8fmyrtyRqDyBPS5TLlZe4RzAR0AAND1tTh0NAAAAIACENABAACgAAR0AAAAKAABHQAAAApAQAcAAIACENABAACgAAR0AAAAKAABHQAAAApAQAcAAIACENABAACgAAR0AAAAKAABHQAAAApAQAcAAIACENABAACgAAR0AAAAKAABHQAAAAqgXaULAAAA0GpKpYafN/W9lthGmzYpderUuPIzVxHQqZx//Sul8eOL+w+nbdiGbVR3eW3DNmyjmPuyDduYHdsoulVWSenFFytdCgpIQKdy9t47pZdfrnQpAAAACkFAp3KWWCKlb775v9c1NQ0/b+p7Lb1eUbYxp+6r2srru5lzyuu7Kca+qq28vpti7Kvayuu7Kca+ilDeqdeB/5+ATuX85S+VLgEAAEBhGMUdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABPQCGTJkSPr+97+funbtmhZeeOE0YMCA9MYbb9RbZ+ONN041NTX1Hj//+c8rVmYAAABahoBeII899lg65JBD0lNPPZUeeuih9O2336YtttgijR8/vt56BxxwQBoxYkTt49xzz61YmQEAAGgZ7VpoO7SABx54oN7ra6+9NtekP//882nDDTesXd65c+fUq1evCpQQAACA1qIGvcDG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AHEAAAC0BH3QW1A0RtAgAQAAgKYQ0FvA9ddfn1ZeeeXUqVOn/Ojfv3+64YYbKl0sAAAAqogm7s10wQUXpMGDB6dDDz00rb/++nnZE088kX7+85+nzz77LB111FGVLiIAAABVwCBxLTBI3GmnnZb23HPPesuvu+66dOqppxauj7qBIAAAgCAbFI8m7s00YsSItN56602zPJbFewAAANAYAnozLbPMMum2226bZvmtt96a50gHAACAxtAHvZmiefvOO++chg0bVtsH/Z///GcaOnRog8EdAAAAGqIGvZl22mmn9PTTT6cFF1ww3X333fkRz5955pk0cODAShcPAACAKmGQuLmMgSAAAIAgGxSPGvRmatu2bfr000+nWf7555/n9wAAAKAxBPRmml4DhIkTJ6YOHTrM9vIAAABQnQwS10QXX3xx/llTU5Ouvvrq1KVLl9r3Jk+enAeNW2655SpYQgAAAKqJgN5Ev/3tb2tr0K+44op6zdmj5nzJJZfMywEAAKAxBPQmevfdd/PPTTbZJN11111pvvnmq3SRAAAAqGICejM98sgjlS4CAAAAcwCDxLXAPOjnnHPONMvPPffc9JOf/KQiZQIAAKD6COjNFIPBbbPNNtMs33rrrfN7AAAA0BgCejONGzeuwenU2rdvn8aOHVuRMgEAAFB9BPRmWnnlldOtt946zfJbbrklrbDCChUpEwAAANXHIHHNNHjw4LTjjjumt99+O2266aZ52dChQ9PNN9+cbr/99koXDwAAgCohoDfTdtttl+6+++509tlnpzvuuCN16tQp9e/fP/3jH/9IG220UaWLBwAAQJWoKZVKpUoXgtkn+sV37949jRkzJnXr1q3SxQEAACpENigefdABAACgADRxb6bJkyen3/72t+m2225LH3zwQZo0aVK997/44ouKlQ0AAIDqoQa9mU477bR0wQUXpJ133jk3DTn66KPzoHFt2rRJp556aqWLBwAAQJUQ0JvpxhtvTL///e/TL3/5y9SuXbu06667pquvvjqdfPLJ6amnnqp08QAAAKgSAnozjRw5Ms+FHrp06ZJr0cOPfvSjdP/991e4dAAAAFQLAb2ZFltssTRixIj8fOmll05///vf8/Nnn302dezYscKlAwAAoFoI6M00cODANHTo0Pz8sMMOS4MHD079+vVLe+65Z9p3330rXTwAAACqhHnQm2jKlCl5ILipRb/zJ598Mof07bbbLhWNuQ4BAIAgGxSPadaaqH379rlp+8ILL5xfH3vssWnQoEFpnXXWyQ8AAACYFZq4N9HUDQ+uvPLKNHr06IqVBwAAgOomoLcQPQUAAABoDgEdAAAACkAf9GY4+eSTU+fOnfPzSZMmpbPOOisPslDXBRdcUKHSAQAAUE0E9CbacMMN0xtvvFH7er311kvvvPNOvXVqamoqUDIAAACqkYDeRI8++miliwAAAMAcRB90AAAAKAABvUCGDRuWtttuu9S7d+/cPP7uu++u9/7ee++dl9d9bLXVVhUrLwAAAC1HQC+Q8ePHp1VWWSVdeuml010nAvmIESNqHzfffPNsLSMAAACtQx/0Atl6663zY0Y6duyYevXqNdvKBAAAwOyhBr0KB6dbeOGF07LLLpsOPvjg9Pnnn1e6SAAAALQANegt4PHHH09XXnllevvtt9Mdd9yRFl100XTDDTekvn37pg022KDF9hPN23fccce83djXr371q1zjPnz48NS2bdsGPzNx4sT8KBs7dmyLlQcAAMLkyZPTt99+W+liMJXICO3atTP9cxUR0JvpzjvvTHvssUfabbfd0r/+9a/aMDxmzJh09tlnp7/+9a8ttq9ddtml9vnKK6+c+vfvn5Zeeulcq77ZZps1+JkhQ4ak0047rcXKAAAAdY0bNy599NFHqVQqVbooNKBz585pkUUWSR06dKh0UWgEAb2ZzjzzzHTFFVekPffcM91yyy21y9dff/38Xmtaaqml0oILLpjeeuut6Qb0QYMGpaOPPrpeDXqfPn1atVwAAMw9NecRziMELrTQQmpqCyRumEyaNCn973//S++++27q169fatNGD+eiE9Cb6Y033kgbbrjhNMu7d++eRo8e3ar7jn8Mow963BGb0aBy8QAAgJYWzdojCEY479SpU6WLw1TinLRv3z69//77OazPM888lS4SM+EWSjPFiOpRgz21J554Itdwz2rzoBdffDE/QtzpiucffPBBfu/YY49NTz31VHrvvffS0KFD0w477JCWWWaZtOWWW7bY8QAAwKxSc15cas2ri7PVTAcccEA64ogj0tNPP53/Yfrkk0/SjTfemI455pg8yvqseO6559Jqq62WHyGapsfzk08+OQ/w8PLLL6ftt98+fe9730v77bdfWmONNfIAdWrIAQAAqp8m7s10wgknpClTpuQ+4F9//XVu7h6BOQL6YYcdNkvb2njjjWc4uMaDDz7YAiUGAACgiNSgN1PUmp944onpiy++SK+++mpugh4DMZxxxhmVLhoAANDA3+8zepx66qlN2u7tt9+elltuudzPO2Zcmno2p6iMO/LII+stu+iii3LlXt3Bppm7qUFvpphOLUavnH/++dMKK6xQuzwCe8w52K1bt4qWDwAA+D8jRoyofX7rrbfm7qQx8HNZly5dZnmbTz75ZNp1113zFMc/+tGP0k033ZQGDBiQXnjhhbTSSis1+JlTTjklnX/++emee+5JW221VROPhjmNGvQWmJu8oTtet912W715ywEAgGIM8lx+xMxLUWted1lTAnrUhEfIjkGdl19++dyadvXVV0+/+93vplk3urRGV9iLL744PfTQQ8I59ahBb6YYHO6CCy6YZnk0YYmm7wAAMLeI4ZS+/roy++7cOZqvt9z2ZhbUd99993TFFVfk58OHD88DPNcVMy3dfffd9ZZ99913+XMPP/xweuyxx1L//v1brsDMEQT0Zpo4cWL+RWtoTshvvvmmImUCAIBKiHDehAroFjFuXErzztty2ytPfTw9dbuyjhw5MvXs2bPe+/E6ltf1+9//Pv986aWXcn91mJqA3kxrrbVWuuqqq9Ill1xSb3ncTYtp0AAAgOqzzDLLtPg2N9hggxz8Bw8enG6++eY8ZhXU5YpopjPPPDNtvvnm+S5YTLUWhg4dmp599tn097//vdLFAwCA2drMPGqyK7XvljQrTdyj7/qoUaPqvR+vY3ldMbr7b37zm5wfdt555zxInZBOXa6GZlp//fVzn5PzzjsvDwzXqVOn3JfkD3/4Q+rXr1+liwcAALNN9AFvyWbmlTQrTdzXXXfdXElXdxq1GAAulk9t1VVXzetGSP/pT3+aQ3r79u1buPRUKwG9BcQv2Y033ljpYgAAABVo4n7EEUekjTbaKNeOb7vttnmWp+eeey53hW3IKquskgeKixa4EdKjok9IJwjoLWDKlCnprbfeSp9++ml+XteGG25YsXIBAACtb7311stzn5900knpV7/6VW5JGyO4T28O9HJz93JI/8lPfpJDeocOHWZruSmemlJMxEeTPfXUU+lnP/tZev/99/OchnXFnIqTJ09ORTJ27Ng83+OYMWPqNcsBAIBZNWHChPTuu++mvn37pnnmmafSxWEWz5FsUDxq0Jvp5z//eVpzzTXT/fffnxZZZJEcygEAAGBWCejN9Oabb6Y77rijVaZhAAAAYO7RptIFqHZrr7127n8OAAAAzaEGvZkOO+yw9Mtf/jKNHDkyD/Qw9eiLMeUaAAAAzIyA3kw77bRT/rnvvvvWLot+6DFgXBEHiQMAAKCYBPRmihERAQAAoLkE9GZaYoklKl0EAAAA5gACegt57bXX0gcffJAmTZpUb/n2229fsTIBAABQPQT0ZnrnnXfSwIED0yuvvFLb9zyU50PXBx0AAIDGMM1aMx1xxBGpb9++6dNPP02dO3dO//73v9OwYcPSmmuumR599NFKFw8AAIAqIaA30/Dhw9Ppp5+eFlxwwdSmTZv82GCDDdKQIUPS4YcfXuniAQAAdURL1xk9Tj311Fne5rXXXjvNduaZZ55660RL25NPPjktssgiqVOnTmnzzTdPb7755jRlu/vuu2tff/vtt2nXXXdNiy66aHr11VebcdRUC03cmymasHft2jU/j5D+ySefpGWXXTYPHvfGG29UungAAEAdI0aMqH1+66235tBc9+/2Ll26NGm73bp1q7edcpfXsnPPPTddfPHF6brrrsstcAcPHpy23HLLPJbV1GE+fP3113lK5wjxTzzxRP4Mcz4BvZlWWmml9NJLL+VfmLXXXjv/4nXo0CFdddVVaamllqp08QAAgDp69epV+7x79+45SNdd1lQz2k7Unl944YXppJNOSjvssENedv3116eePXvmGvNddtml3vqjR49O2267bRo3blwO5y1RPqqDgN5M8Us2fvz4/Dyauv/oRz9KP/jBD9ICCyyQ78gBAMDcIoLo199+XZF9d27feZpa6+aYWU367rvvnq644ora1xGmoxXtlClT0uqrr57OPvvstOKKK+b33n333TRy5MjcrL3uzYGo4Isus3UDeqy30UYb5f0/9thjqUePHi12TBSfgN5M0SylbJlllkmvv/56+uKLL9J8883Xov9AAABA0UU47zKkaU3Em2vcoHFp3g7zttj2XnzxxZk2aS+LLq5//OMfU//+/dOYMWPS+eefn9Zbb708gPRiiy2WQ3eIGvO64nX5vbqDUEdL3IceeigPQs3cRUBvBfPPP3+liwAAADRDVL411rrrrpsfZRHOl19++XTllVemM844Y5b2Gy1yo9l7fPaoo46apc9S/QT0Jthxxx0bve5dd93VqmUBAICiiGbmUZNdqX23pFlt4l5X+/bt02qrrZbeeuut/Lrch3zUqFF5FPeyeL3qqqvW++wee+yRtt9++7TvvvvmLgNHH310CxwN1UJAb4LoLwIAANQXXTxbspl5Jc1KE/eGZnp65ZVX0jbbbJNfx4DSEdKHDh1aG8jHjh2bnn766XTwwQdP8/m99torT9+8zz775D7txxxzTLOPh+ogoDfBNddcU+kiAAAABWniHoNFr7POOvkzMQL7eeedl95///20//771964OPLII9OZZ56Z+vXrVzvNWu/evdOAAQMa3GbUpEdIj7AeNenHHntsix0bxSWgAwAANMOXX36ZDjjggDzgWwwWvcYaa6Qnn3wyrbDCCrXrHHfccXn2pwMPPDCH+A022CA98MADDc6BXrbbbrvlkB5hPWrSjz/++Nl0RFRKTSlux9Asd9xxR7rtttvSBx98kCZNmlTvvRdeeCEVSTSliSb6MbrkjJrlAADAzEyYMCFPIRY1wjMKmhTzHMkGxdOm0gWodhdffHHuGxJTJPzrX/9Ka621Vp4D/Z133klbb711pYsHAABAlRDQm+myyy5LV111VbrkkktShw4dctOVmLPw8MMPz3eiAAAAoDEE9GaKZu0xz2Ho1KlT+uqrr/Lz6Cdy8803V7h0AAAAVAsBvZliuoQvvvgiP1988cXTU089lZ9HPw/d+wEAAGgsAb2ZNt100/SXv/wlP4++6EcddVT64Q9/mHbeeec0cODAShcPAACAKmGatWaK/ucx5UE45JBD8gBxMaXC9ttvnw466KBKFw8AAIAqIaA3U8xLGI+yXXbZJT8AAABgVgjoLWj8+PHp1ltvTd98803aYostUr9+/SpdJAAAAKqEPujNGL19o402Sl27ds19zuP16quvnvbff/902GGHpVVXXTUNGzas0sUEAACgSgjoTXTMMcekSZMmpSuuuCJ17tw5bbnllrnGfMSIEWnUqFFp6623TqeeemqliwkAAECVENCbKGrHL7roorTbbrula665Jr3xxhvpxBNPTD179kwLLbRQGjx4cHr55ZcrXUwAAKCOmpqaGT6aUsl21113pTXXXDP16NEjzTvvvLk17Q033FBvnZiC+eSTT06LLLJI6tSpU9p8883Tm2++WW+dmL458kW3bt3ytvbbb780bty42vcfffTRXMbRo0fXLvvkk0/SyiuvnDbccMM0ZsyYJn0nFIeA3kSffvppWmKJJfLz+eefP9eiRzivOz/6l19+WcESAgAAU4sWr+XHhRdemMNw3WXRUnZWRR6Iyrrhw4fnSrqYfjkeDz74YO065557brr44otzC9ynn346B/lohTthwoTadSKc//vf/04PPfRQuu+++3Kl4IEHHjjd/b799ttpgw02yLkk9tW9e/cmfCMUiUHimiHuXjX0HAAAKKaoSCuLQBt/x9dd1hQbb7xxvddHHHFEuu6669ITTzyRQ3jUnsfNgJNOOintsMMOeZ3rr78+V/DdfffdeRao//znP+mBBx5Izz77bK6ND5dccknaZptt0vnnn5969+5dbx9xIyC2vemmm+Z9tWsn2s0JnMVmiCYqUXMeoj/6WWedVXvX6uuvv65w6QAAYDYrleIP4crsO/4ub8FKsy5duszw/d133z3Xhk8twvjDDz+cu8Cec845edm7776bRo4cmZu1l0VuWHvttXOtewT0+BnN2svhPMT6MaVz1LgPHDiwdvmTTz6Za9vjESFeZeGcQ0BvoujjEb90Zeutt1565513plkHAADmGhHOZxJsW0301Z533hbb3IsvvjjD96NpfF3R/3vRRRdNEydOTG3btk2XXXZZnu0pRDgPdbvEll+X34ufCy+8cL33o1Y8ms+X1ymLsL7zzjun3/3ud804QopIQG+iGKABAACYMy2zzDKztH5MvxyhPgZ1Gzp0aDr66KPTUkstNU3z95YQzeT//Oc/p8cffzz94Ac/aPHtUzkCOgAA0HLNzOuMOj7b992CZrWJezRFL4f6GMU9+pQPGTIkB/RyH/eYjjlGcS+L17FuiHViIOq6vvvuuzyy+9R95K+88sp03HHH5amd//rXv2q5OwcR0AEAgJYRfaFbsJl5Jc1qE/epTZkyJTd3D3379s0hO2rWy4F87NixuW/5wQcfnF+vu+66efq0559/Pq2xxhp5WfRlj+1EX/W6os/5VVddlW8KxCBy999/f9poo42adbwUg4AOAADQjCbuUVMeg7stvfTSOZRHrXbMg3755ZfXBuojjzwynXnmmalfv345sA8ePDiPzD5gwIC8zvLLL5+22mqrdMABB+Sa+W+//TYdeuiheQC5qUdwL28z1ov+7uWQ3hrN6Zm9BHQAAIBmGD9+fPrFL36RPvroo9SpU6e03HLLpT/96U95ILeyaJIe68W85lFTHvOXx7Rq88wzT+06N954Yw7lm222Wa4d32mnnfLc6dMTIf3SSy/N62677bZ57vRNNtmk1Y+X1lNTinkAmGtEU5qY0iFGmZxZsxwAAJiRCRMm5CnEoka4btCkOs6RbFA8atCb4OWXX270uv3792/VsgAAADBnENCbIAZ2iOYk0fggfs7I5MmTZ1u5AAAAqF5tKl2AahRNRN555538884778zNRS677LL0r3/9Kz/ieQwQEe8BAABAY6hBb4Illlii9vlPfvKTPHBDjJxYt1l7nz598siM5VEZAQAAYEbUoDfTK6+8kmvQpxbLXnvttYqUCQAAgOojoDdTzFcY8x5OmjSpdlk8j2XxHgAAzOlMDFVczk110cS9ma644oq03XbbpcUWW6x2xPYY5T0Gj7v33nsrXTwAAGg1bdu2ra2givm/KZ6vv/46/2zfvn2li0IjCOjNtNZaa+UB42688cb0+uuv52U777xz+tnPfpbmnXfeShcPAABaTbt27VLnzp3T//73vxwA27TRQLdINecRzj/99NPUo0eP2pspFFtNSZuHucrYsWNT9+7d05gxY1K3bt0qXRwAAKpc1J7H7EZTpkypdFFoQITzXr16NTg9tGxQPGrQW8ANN9yQrrzyylyTPnz48DzK+29/+9u01FJLpR122KHSxQMAgFbToUOH1K9fv3pjMlEM0apBzXl1EdCb6fLLL08nn3xyOvLII9OZZ56ZJk+enJfPN9986cILLxTQAQCY40XT9nnmmafSxYCqp5NIM11yySXp97//fTrxxBNzH5yyNddcM0/BBgAAAI0hoDdT9LdZbbXVplnesWPHNH78+IqUCQAAgOojoDdT375904svvjjN8gceeMA86AAAADSaPujNdPTRR6dDDjkkTZgwIU9l8Mwzz6Sbb745DRkyJF199dWVLh4AAABVQkBvpv333z916tQpnXTSSXmewZj/vHfv3umiiy5Ku+yyS6WLBwAAQJUwD3oLioA+bty4tPDCC6eiMtchAAAQZIPi0Qe9BXXu3LlZ4XzYsGFpu+22yzXwNTU16e677673ftxLiSndFllkkVxrv/nmm6c333yzBUoOAABApWni3gQxansE6MZ44YUXGr3dGPV9lVVWSfvuu2/a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64VZ5ZopPjXnxeI2CQAAABSAgA4AAAAFIKBDAXXs2DGdcsop+Sc0hmuGWeWaYVa4XphVrhloGoPEAQAAQAGoQQcAAIACENABAACgAAR0AAAAKAABHQAAAApAQIcK+OKLL9Juu+2WunXrlnr06JH222+/NG7cuBl+ZsKECemQQw5JCyywQOrSpUvaaaed0qhRoxpc9/PPP0+LLbZYqqmpSaNHj26lo6Dar5mXXnop7brrrqlPnz6pU6dOafnll08XXXTRbDgaWsOll16allxyyTTPPPOktddeOz3zzDMzXP/2229Pyy23XF5/5ZVXTn/961/rvR9jyJ588slpkUUWydfH5ptvnt58881WPgqq9Zr59ttv0/HHH5+XzzvvvKl3795pzz33TJ988slsOBKq9d+Zun7+85/nv1suvPDCVig5VA8BHSoggta///3v9NBDD6X77rsvDRs2LB144IEz/MxRRx2V7r333vw/u8ceeyz/0bPjjjs2uG6Et/79+7dS6ZlTrpnnn38+LbzwwulPf/pT3vaJJ56YBg0alH73u9/NhiOiJd16663p6KOPzlMavfDCC2mVVVZJW265Zfr0008bXP/JJ5/MN2fi34p//etfacCAAfnx6quv1q5z7rnnposvvjhdccUV6emnn86hK7YZN36ofi19zXz99dd5O4MHD84/77rrrvTGG2+k7bfffjYfGdX070zZn//85/TUU0/lGzsw14tp1oDZ57XXXoupDUvPPvts7bK//e1vpZqamtLHH3/c4GdGjx5dat++fen222+vXfaf//wnb2f48OH11r3ssstKG220UWno0KH5/S+//LIVj4Y54Zqp6xe/+EVpk002aeEjoLWttdZapUMOOaT29eTJk0u9e/cuDRkypMH1f/rTn5a23XbbesvWXnvt0kEHHZSfT5kypdSrV6/SeeedV++a6tixY+nmm29uteOgeq+ZhjzzzDP535z333+/BUvOnHbNfPTRR6VFF1209Oqrr5aWWGKJ0m9/+9tWOgKoDmrQYTYbPnx4bqK85ppr1i6LpqNt2rTJtVQNiZrOaD4Y65VFk7HFF188b6/stddeS6effnq6/vrr8/aYM7TmNTO1MWPGpPnnn7+Fj4DWNGnSpHy+657ruDbi9fTOdSyvu36ImrDy+u+++24aOXJkvXW6d++em7TO6Pph7r1mGhL/nkST5fj3i+rWWtfMlClT0h577JGOPfbYtOKKK7biEUD18Bc8zGbxR280K66rXbt2ORTFe9P7TIcOHab5I6dnz561n5k4cWJuSnbeeeflEMaco7WumYaaI0YTxpk1nadYPvvsszR58uR8bht7rmP5jNYv/5yVbTJ3XzNTi64Q0Sc9/r8UY2dQ3VrrmjnnnHPy/88OP/zwVio5VB8BHVrICSeckGsKZvR4/fXXW23/0Xc4BvnafffdW20fzFnXTF3RJ3CHHXbIfQu32GKL2bJPYM4UrXd++tOf5oEGL7/88koXh4KKGvkYmPTaa6/N/78D/p92//9PoJl++ctfpr333nuG6yy11FKpV69e0wyo8t133+VRuuO9hsTyaF4WI7LXrRGNEbnLn3n44YfTK6+8ku644478Ov4wCgsuuGAe/Ou0005r9jEyZ10zdbtGbLbZZrnm/KSTTmrWMTH7xe9427Ztp5nVoaFzXRbLZ7R++Wcsi1Hc666z6qqrtsJRUO3XzNTh/P3338//X1J7PmdojWvm8ccfz/9vq9vqL2rp4/+NMZL7e++91yrHAkWnBh1ayEILLZT7+M7oEU2O11133Rya4s5xWfwRE/2won9nQ9ZYY43Uvn37NHTo0NplMTruBx98kLcX7rzzzjxt1osvvpgfV199de3/AGOqLYqn0tdMiNHbN9lkk7TXXnuls846q5WPmNYQ10ic77rnOq6NeF33XNcVy+uuH2KGgPL6ffv2zX9E111n7NixecyD6W2TufuaqRvOYzq+f/zjH3mKR+YMrXHNRN/zl19+ufbvlnjEKO7RH/3BBx9s5SOCAqv0KHUwN9pqq61Kq622Wunpp58uPfHEE6V+/fqVdt1113ojmi677LL5/bKf//znpcUXX7z08MMPl5577rnSuuuumx/T88gjjxjFfQ7SGtfMK6+8UlpooYVKu+++e2nEiBG1j08//XS2Hx/Nc8stt+QR1q+99to86v+BBx5Y6tGjR2nkyJH5/T322KN0wgkn1K7/z3/+s9SuXbvS+eefn0f3P+WUU/Ko/3FNlP3617/O27jnnntKL7/8cmmHHXYo9e3bt/TNN99U5Bgp9jUzadKk0vbbb19abLHFSi+++GK9f1MmTpxYseOk2P/OTM0o7lAqCehQAZ9//nkOV126dCl169attM8++5S++uqr2vfffffdHK4jZJfFH8UxBdZ8881X6ty5c2ngwIH5D5/pEdDnLK1xzcQfS/GZqR/xBxLV55JLLsk3ZDp06JCnQ3rqqadq34upF/faa6966992222l733ve3n9FVdcsXT//ffXez+mWhs8eHCpZ8+e+Y/yzTbbrPTGG2/MtuOhuq6Z8r9BDT3q/rtEdWvpf2emJqBDqVQT/6l0LT4AAADM7fRBBwAAgAIQ0AEAAKAABHQAAAAoAAEdAAAACkBABwAAgAIQ0AEAAKAABHQAAAAoAAEdAJjG559/nhZeeOH03nvvpSLYZZdd0m9+85tKFwMAWpWADgDNsPfee6eampppHltttVWqZmeddVbaYYcd0pJLLtlq+3j++efzd/XUU081+P5mm22Wdtxxx/z8pJNOymUaM2ZMq5UHACpNQAeAZoowPmLEiHqPm2++uVX3OWnSpFbb9tdff53+8Ic/pP322y+1pjXWWCOtssoq6Y9//OM070XN/SOPPFJbhpVWWiktvfTS6U9/+lOrlgkAKklAB4Bm6tixY+rVq1e9x3zzzVf7ftQSX3311WngwIGpc+fOqV+/fukvf/lLvW28+uqraeutt05dunRJPXv2THvssUf67LPPat/feOON06GHHpqOPPLItOCCC6Ytt9wyL4/txPbmmWeetMkmm6Trrrsu72/06NFp/PjxqVu3bumOO+6ot6+77747zTvvvOmrr75q8Hj++te/5mNaZ511apc9+uijebsPPvhgWm211VKnTp3Spptumj799NP0t7/9LS2//PJ5Xz/72c9ywC+bMmVKGjJkSOrbt2/+TATyuuWJAH7rrbfW+0y49tpr0yKLLFKvJcJ2222Xbrnlllk6NwBQTQR0AJgNTjvttPTTn/40vfzyy2mbbbZJu+22W/riiy/yexGmI+xG8H3uuefSAw88kEaNGpXXryvCd4cOHdI///nPdMUVV6R33303/fjHP04DBgxIL730UjrooIPSiSeeWLt+hPDou33NNdfU2068js917dq1wbI+/vjjuXa7Iaeeemr63e9+l5588sn04Ycf5jJeeOGF6aabbkr3339/+vvf/54uueSS2vUjnF9//fW5vP/+97/TUUcdlXbffff02GOP5ffje5g4cWK90F4qlfKxRveBtm3b1i5fa6210jPPPJPXB4A5UgkAaLK99tqr1LZt29K8885b73HWWWfVrhP/uz3ppJNqX48bNy4v+9vf/pZfn3HGGaUtttii3nY//PDDvM4bb7yRX2+00Ual1VZbrd46xx9/fGmllVaqt+zEE0/Mn/vyyy/z66effjqX75NPPsmvR40aVWrXrl3p0Ucfne4x7bDDDqV999233rJHHnkkb/cf//hH7bIhQ4bkZW+//XbtsoMOOqi05ZZb5ucTJkwode7cufTkk0/W29Z+++1X2nXXXWtf77LLLvn4yoYOHZq3++abb9b73EsvvZSXv/fee9MtOwBUs3aVvkEAANUumpZffvnl9ZbNP//89V7379+/Xs12NAeP5uEhar+jv3U0b5/a22+/nb73ve/l51PXar/xxhvp+9//fr1lUcs89esVV1wx10ifcMIJuQ/3EksskTbccMPpHs8333yTm8w3pO5xRFP8aLK/1FJL1VsWtdzhrbfeyk3Xf/jDH07Tfz5aC5Ttu+++ucl+HGv0M48+6RtttFFaZpll6n0umsiHqZvDA8CcQkAHgGaKwD11mJxa+/bt672O/tzRPzuMGzcu968+55xzpvlc9MOuu5+m2H///dOll16aA3o0b99nn33y/qcn+rh/+eWXMz2O2MbMjitE0/dFF1203nrRx73uaO2LL7547nd+7LHHprvuuitdeeWV0+y73CVgoYUWauSRA0B1EdABoMJWX331dOedd+Ypzdq1a/z/mpdddtk8oFtdzz777DTrRZ/v4447Ll188cXptddeS3vttdcMtxu12y0xWvoKK6yQg/gHH3yQa8Snp02bNvmmQYwcH0E++tlHH/mpxUB6iy22WL6BAABzIoPEAUAzxaBlI0eOrPeoOwL7zBxyyCG5dnjXXXfNATuaesdo6RFaJ0+ePN3PxaBwr7/+ejr++OPTf//733TbbbflWuhQt4Y8RpSP+cSjdnqLLbbIIXdGorl5DOg2vVr0xopB6I455pg8MFw0sY/jeuGFF/IgcvG6rjjWjz/+OP3qV7/K30O5OfvUg9dF+QFgTiWgA0Azxajr0RS97mODDTZo9Od79+6dR2aPMB4BdOWVV87TqfXo0SPXLk9PTF0Wo59Hk/DoGx794MujuNdtQl6eziz6fkd/75mJ/UetfgT+5jrjjDPS4MGD82juMRVbTJsWTd6j7HVFE/fNN9883xRoqIwTJkzI08MdcMABzS4TABRVTYwUV+lCAAAt46yzzspTmsUUaHXdcMMNuSb7k08+yU3IZyZCdNS4R7PyGd0kmF3i5sOf//znPI0bAMyp9EEHgCp22WWX5ZHcF1hggVwLf95556VDDz209v0Y8XzEiBHp17/+dW4S35hwHrbddtv05ptv5mbnffr0SZUWg9HVnV8dAOZEatABoIpFrfitt96a+7BHM/E99tgjDRo0qHawuVNPPTXXqse0avfcc0+DU7kBAMUgoAMAAEABVL5TGQAAACCgAwAAQBEI6AAAAFAAAjoAAAAUgIAOAAAABSCgAwAAQAEI6AAAAFAAAjoAAAAUgIAOAAAABSCgAwAAQAEI6AAAAFAAAjoAAAAUgIAOAAAABSCgAwAAQAEI6AAAAFAAAjoAAAAUgIAOAAAABSCgAwAAQAEI6AAAAFAAAjoAAAAUgIAOAAAABSCgAwAAQKq8/w+rOLDV/JmWgAAAAABJRU5ErkJggg==", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Detailed balance vs energy, meV scale\n", - "x=np.linspace(-0.05, 0.05, 10001)\n", - "\n", - "T=0\n", - "DetailedBalanceT1=detailed_balance_factor(x,T)\n", - "plt.figure(figsize=(10, 6))\n", - "plt.plot(x, DetailedBalanceT1, label=f'T={T}K', color='blue')\n", - "\n", - "T=50\n", - "DetailedBalanceT2=detailed_balance_factor(x,T)\n", - "plt.plot(x, DetailedBalanceT2, label=f'T={T}K', color='green')\n", - "\n", - "\n", - "T=300\n", - "DetailedBalanceT3=detailed_balance_factor(x,T)\n", - "plt.plot(x, DetailedBalanceT3, label=f'T={T}K', color='red')\n", - "\n", - "plt.title('Detailed Balance Factor vs Energy')\n", - "plt.legend()\n", - "\n", - "plt.xlabel('Energy (meV)')\n", - "plt.ylabel('Detailed Balance Factor')\n" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "5e3efad9", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "4eccf8fc0f0f459ba4ebfb52b5ef9870", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAddxJREFUeJzt3Qd4U9X7B/BvZvempVDKLHsvGSpbpspQRHCgAipOwJ8iDpyIiLgHbhx/FzIcIKgIKEv23qsttLSM7pU2yf85J01oS0fSJs36fp7ncm9u7r05l7bJmzPeozAajUYQERERkddQOrsARERERFS7GAASEREReRkGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASEREReRkGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASEREReRkGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASEREReRkGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASEREReRkGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXUTu7AO7MYDAgKSkJQUFBUCgUzi4OERERWcFoNCIrKwv169eHUumddWEMAGtABH+xsbHOLgYRERFVQ2JiIho0aABvxACwBkTNn/kXKDg42NnFISIiIitkZmbKChzz57g3YgBYA+ZmXxH8MQAkIiJyLwov7r7lnQ3fRERERF6MASARERGRl2EASERERORl2AeQiIjITqlFioqKoNfrnV0Ur6dSqaBWq726j19VGAASERHVkE6nQ3JyMnJzc51dFCrm7++PevXqQavVOrsoLokBIBERUQ0nBTh16pSsdRKJhUXAwZon59bE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cBAIERERkZdhDSARERGRl2EASERERORlGAASEREReRkGgERERERehgGgCzh9+jQmTZqEJk2awM/PD82aNZMjn3Q6XaXn5efn48EHH0RERAQCAwNx0003ISUlBa5qzpw56N27N/z9/REaGmrVOXfddZecZaXkMnToUHjK/YkxWLNnz0a9evXkz37QoEE4duwYXNGlS5dw2223yYSs4v7E72x2dnal5/Tr1++Kn9/9998PV/H++++jcePG8PX1RY8ePbB169ZKj1+8eDFatWolj2/fvj1WrlwJV2bL/S1atOiKn5U4z1X9888/uOGGG+RMDqKsy5cvr/KcdevWoUuXLnJUaVxcnLxnV2brPYr7K/szFMu5c+fgiubOnYvu3bvL2bSioqIwatQoHDlypMrz3O3v0FUxAHQBhw8fltPKffTRRzhw4ADefPNNLFy4EE899VSl502fPh2//vqr/GNYv369nJZuzJgxcFUioB07diymTp1q03ki4EtOTrYs3333HTzl/l577TW888478uf933//ISAgAEOGDJHBvasRwZ/4/fzzzz/x22+/yQ+ne++9t8rzpkyZUurnJ+7ZFfzwww+YMWOG/LK1c+dOdOzYUf7fp6amlnv8pk2bMH78eBn47tq1S35YiWX//v1wRbbenyCC+5I/q/j4eLiqnJwceU8iyLXGqVOnMGLECPTv3x+7d+/GtGnTMHnyZKxevRqeco9mIogq+XMUwZUrEp9bohJjy5Yt8n2lsLAQgwcPlvddEXf7O3RpIg0MuZ7XXnvN2KRJkwqfT09PN2o0GuPixYst+w4dOiRS+hg3b95sdGVffPGFMSQkxKpjJ06caBw5cqTRnVh7fwaDwRgdHW2cP39+qZ+rj4+P8bvvvjO6koMHD8rfrW3btln2/f7770aFQmE8e/Zshef17dvX+Oijjxpd0VVXXWV88MEHLY/1er2xfv36xrlz55Z7/C233GIcMWJEqX09evQw3nfffUZPuD9b/i5djfjdXLZsWaXHPPHEE8a2bduW2jdu3DjjkCFDjJ5yj2vXrpXHpaWlGd1RamqqLP/69esrPMbd/g5dGWsAXVRGRgbCw8MrfH7Hjh3y25JoMjQTVeINGzbE5s2b4UlEs4b4BtuyZUtZu3bx4kV4AlEjIZpmSv4MxdyUoqnO1X6Gojyi2bdbt26WfaLcYj5sUXNZ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v3798NBDD2HatGmoU6cOhgwZIveL64jr+fr6on///vjyyy/l66WnpyMnJwfBwcH46aefSr3W8uXLERAQgKysrHLvZ+XKlfKeevbsadm3bt06ed3Vq1ejc+fO8PPzw4ABA5Camorff/8drVu3lq81YcIEGUCaGQwGzJ07F02aNJHniICvZHlEgPfDDz+UOkdYtGgR6tWrV6om9YYbbsD3339v08+GiLwTA0AicgkvvPACbrnlFuzduxfDhw/HbbfdhkuXLsnnRLAmgikRWG3fvh2rVq1CSkqKPL4kEdxptVps3LgRCxcuxKlTp3DzzTdj1KhR2LNnD+677z48/fTTluNFkCf6zn3xxRelriMei/OCgoLKLeu///4ra+fK8/zzz+O9997Dpk2bkJiYKMv41ltv4dtvv8WKFSvwxx9/4N1337UcL4K/r776Spb3wIEDmD59Om6//XasX79ePi/+HwoKCkoFhWIKd3GvonldpVJZ9l911VXYunWrPJ6IqFJGIiIHmjhxolGlUhkDAgJKLXPmzLEcI96KnnnmGcvj7Oxsue/333+Xj1966SXj4MGDS103MTFRHnPkyBH5uG/fvsbOnTuXOmbmzJnGdu3aldr39NNPy/PS0tLk4//++0+WLykpST5OSUkxqtVq47p16yq8p5EjRxrvueeeUvvWrl0rr/vXX39Z9s2dO1fuO3HihGXffffdZxwyZIjczs/PN/r7+xs3bdpU6lqTJk0yjh8/3vL41ltvlfdntmbNGnndY8eOlTpvz549cv/p06crLDsRkaCuPDwkIqo50fT64YcfltoXHh5e6nGHDh1K1cyJ5lLRfCqI2jvR3000/5Z14sQJtGjRQm6XrZU7cuQIunfvXmqfqCUr+7ht27ayRu3JJ5+UfegaNWqEPn36VHg/eXl5skm5PCXvQzRViybtpk2bltonaumE48ePy6bd66677or+i6K20+yee+6RTdriXkU/P9EnsG/fvoiLiyt1nmhCFso2FxMRlcUAkIgcTgR0ZYOVsjQaTanHoj+d6B8nZGdny/5t8+bNu+I80Q+u5OtUx+TJk/H+++/LAFA0/959993y9Ssi+himpaVVeR/iGlXdlyCahmNiYkodJ/oYlhzt27BhQ9nv7/HHH8fSpUvx0UcfXfHa5ibzyMhIK++ciLwVA0AicnldunTBkiVLZMoVtdr6t62WLVvKARslbdu27YrjRJ+7J554Au+88w4OHjyIiRMnVnpdUTtnj9G2bdq0kYFeQkKCrNGriFKplEGpGHksAkXRz1H0USxLDJRp0KCBDFCJiCrDQSBE5HBiUMK5c+dKLSVH8FblwQcflLVb48ePlwGcaAoVo21FUKTX6ys8Twz6OHz4MGbOnImjR4/ixx9/lLVoQskaPjEiWeTTE7VrgwcPlkFUZURzrBiwUVEtoLXEIJP//e9/cuCHaIIW97Vz5045SEQ8Lknc69mzZ/HUU0/J/wdzc2/ZwSmi/EREVWEASEQOJ0btiqbakss111xj9fn169eXI3tFsCcCnPbt28t0L6GhobJ2rCIitYoYPSuaTEXfPNEP0TwKuGQTqzndiuh7J/rbVUW8vqiVFAFlTb300kt49tln5WhgkSpGpHURTcKi7CWJJuBBgwbJoLO8Mubn58v0NVOmTKlxmYjI8ynESBBnF4KIqLaI2TJEyhWRoqWkr7/+WtbEJSUlySbWqoggTdQYimbXyoLQ2iKC22XLlsk0M0REVWEfQCLyaB988IEcCRwRESFrEefPny8TRpuJEbNiZpJXX31VNhlbE/wJI0aMwLFjx2SzbGxsLJxNDDYpmV+QiKgyrAEkIo8mavXETBqiD6FoRhUziMyaNcsymEQkbha1giLty88//1xuqhkiIk/DAJCIiIjIyzi/4woRERER1SoGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERHBu/w/pHnHlNSuAWMAAAAASUVORK5CYII=", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Example of using the detailed balance factor in easydynamics\n", - "\n", - "plt.figure()\n", - "\n", - "x=np.linspace(-2, 2, 1000)\n", - "Lorentzian=Lorentzian(center=0, width=0.1, area=1)\n", - "\n", - "DetailedBalanceT1=detailed_balance_factor(x,temperature=0.0)\n", - "plt.plot(x,Lorentzian.evaluate(x)*DetailedBalanceT1, label='T=0 K')\n", - "\n", - "DetailedBalanceT3=detailed_balance_factor(x,temperature=1)\n", - "plt.plot(x,Lorentzian.evaluate(x)*DetailedBalanceT3, label='T=1 K')\n", - "\n", - "DetailedBalanceT3=detailed_balance_factor(x,temperature=3)\n", - "plt.plot(x,Lorentzian.evaluate(x)*DetailedBalanceT3, label='T=3 K')\n", - "\n", - "plt.plot(x, Lorentzian.evaluate(x), label='No DBF', linestyle='--')\n", - "\n", - "plt.legend()\n", - "plt.xlabel('Energy (meV)')\n", - "plt.ylabel('Intensity (arb. units)')\n", - "plt.show()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "220405f1", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "c8f3a85e975842358151b5ccfa2f5c51", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAApFdJREFUeJzt3Qd8k+X+BfCT3V1GKXsPERFEEbcoDtx7oSLue917Xa/7uvdAcW//7r0X7oGAIiAie48C3SP7/zlP+oYktKWFtqHN+d4b2yRvkjdvQ3Lye5YtHA6HISIiIiIpw57sHRARERGR5qUAKCIiIpJiFABFREREUowCoIiIiEiKUQAUERERSTEKgCIiIiIpRgFQREREJMUoAIqIiIikGAVAERERkRSjACgiIiKSYhQARURERFKMAqCIiIhIilEAFBEREUkxCoAiIiIiKUYBUERERCTFKACKiIiIpBgFQBEREZEUowAoIiIikmIUAEVERERSjAKgiIiISIpRABQRERFJMQqAIiIiIilGAVBEREQkxSgAioiIiKQYBUARERGRFKMAKCIiIpJiFABFREREUowCoIiIiEiKUQAUERERSTEKgCIiIiIpRgFQREREJMUoAIqIiIikGAVAERERkRSjACgiIiKSYhQARaTRfPPNN7DZbObnxuy1117mVB/cbvDgwWgOd999N/r06QOHw4HtttuuWR5TRKS5KQCKiPH666+b8PbOO+9scN3QoUPNdRMnTtzguh49emDXXXfd7Mdfvnw5brzxRvzxxx9Ils8//xxXXnkldtttNzz77LO47bbbat2W+8pjknhKS0tDSzN16lSz7//9739r3WbOnDlmm0svvbRZ901Emoazie5XRFqY3Xff3fz84YcfcOSRR0YvLykpwYwZM+B0OvHjjz9i7733jl63ZMkSczrhhBPM+T333BOVlZVwu92bFABvuukm9OrVK2mVt6+//hp2ux1PP/10vZ/DY489hqysrOh5Vg5bmu233x4DBw7E//3f/+F///tfjdu88sor5ufJJ5/czHsnIk1BAVBEjC5duqB3794mAMb6+eefEQ6Hceyxx25wnXXeCo8MTy2xAmZZvXo10tPTGxRgjznmGOTl5aGlO+mkk3Ddddfhl19+wc4777zB9QyHDIkMiyLS8qkJWESiGOR+//13U8WzsOq3zTbb4MADDzTh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w9stt9wS3YYhlsc6Fudpq828efNw8MEHo2fPntHLOnXqVOv2PEbBYNCEUBFJ8jQwlZWVZvCHhYNBuITbZ599lszdEpEUld8pH3kd88wKQgwfrOowVOR37ID8Dh2QkZnR6I/JYML3Pa5KxADHqt4LL7yA5cuX49133631dqy4HXTQQSYADhgwwKxilJWVhV9++aVej/vKK6/gqKOOMuGzoeGPMjIyzLFhEGVT7J133onHH38cTz75JL788su4bVlV47as0h1yyCHmeU6dOjVuG+tYx55YDa0Jt50yZYoJoPydlc3EKtw333xjzrMqyrXiWan84YcfTADde++9TcsTQyevmzx5stmewZRdkqwKJO+3PhjaiUuL8naskMZiaxaru+3bt8d5551ngrCFldDLL7/cVFEZirk0KfclsSrJz8Wtt97a/I0ZplntrMvMmTPNseZz5HNl33qGZgqFQubY8W/H42KtnGWxjiUrujxW/Fuz69bPP/8cnUSZf5vEijO/BPCxrM/16dOnm1Y9bsvnzr79ZWVlNe4vvzR06dLF7FssvlZOP/306Pn33nsP22+/vfli1KdPH9x0003mS4i0sADIPyzf6KioqMi88O+9917TJ4DNGyLS+virqhp8ip2Amb+by33x/fFqu21DhKr8yK5wwlERrHEtYNTSRPrvf//bfDDXdaoN+0Oz/zObfS0Mn3w/tD5wN4aVLQ6q4/rnbAremPHjx5uw88wzz+D8889HY+F67G3btq2xKdjyzz//4OuvvzbPb1Mx/LDKedlll5nfGaBqw+omK6XsVsRwfdJJJ5ngw/7lDJG83uVyYddddzVBnIGJ97mx+61prWAGX94u9vlPnDjRBC/+ZJWWgY4nC48//878+/3555+mIsuAF9sFgIGKIfLFF1/Ed999Z2bPqGvfuLzpnnvuacIdjzWfJ0OUFZQefPBB81nL++Rjstp82GGHbdDt4NprrzWPw1DNLxljxowx98FjxHDJLxGxXn75ZfP5zcDI1yLvl68HHus33njDHJ/aXm983mvXrjXHybJu3ToTTPk3s7ornHLKKbjoootMdZxfOHgstYTrpklqLZzfAO+//37z+5tvvmm+dbP54q233jLfSM8555xk7p6INIGHxh3T4NsccvHV2GqX3c3vcyb9jA8fuAPdBg3G8TfcEd3myfNPR2VpyQa3vey1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dMABB6Alu/XWW3H44YejV69eTfYYU6ZMMcfql19+qfH6ffbZB0cddZT5/b///a/Zp+Li4ibbHxFpPRQARaTJMeytWLEi7vR///d/TfqYPp+vye67oqICTz/9NM444ww0pR122AFDhw7FM888s8F1rDxOnDgxug+DBw9G37598dJLLzXpPolI66AAKCJNzuPxoFOnTnGntm3bRq9nleupp57CkUceiYyMDPTv3x/vv/9+3H3MmDEDBx54ILKystCxY0eMHTsWa9asiV6/11574fzzz8fFF1+MvLw8jB492lzO++H9paWlYe+998bzzz9vHq+oqAjl5eXIycnBm2++GfdY7777LjIzM1FaWlrj8/n444/Nc9p5552jl33zzTfmfj/77DMMGzYM6enpGDVqFFavXo1PPvkEW2+9tXmsE0880QRISygUwu23347evXub2zDwxe4PA95rr70Wdxt67rnn0Llz57hK6qGHHopXX321QX8bEUlNCoAiskW46aabcNxxx+HPP//EQQcdhJNOOgnr1q0z1zGsMUwxWE2ePBmffvopVq1aZbaPxXDndrvx448/YsKECViwYAGOOeYYHHHEEZg2bRr+9a9/4dprr41uz5DHvnPPPvts3P3wPG+XnZ1d475+//33pjpXkxtvvBGPPPIIfvrpJyxZssTs4wMPPIBXXnkFH330ET7//HM8/PDD0e0Z/l544QWzvzNnzsQll1yCk08+Gd9++625nsfB6/XGhUIu4c7nyuZ1h8MRvXzEiBGYNGmS2V5EpE5hEZEmNG7cuLDD4QhnZmbGnW699dboNnwr+u9//xs9X1ZWZi775JNPzPlbbrklvP/++8fd75IlS8w2s2fPNudHjhwZHjZsWNw2V111VXjw4MFxl1177bXmdoWFheb8r7/+avZv+fLl5vyqVavCTqcz/M0339T6nA4//PDw6aefHnfZxIkTzf1++eWX0ctuv/12c9m8efOil/3rX/8Kjx492vxeVVUVzsjICP/0009x93XGGWeEx4wZEz1/wgknmOdn+eqrr8z9zpkzJ+5206ZNM5cvXLiw1n0XESFn3fFQRGTzsen1sccei7usXbt2ceeHDBkSV5ljcymbT4nVO/Z3Y/Nvonnz5mHAgAHm98Sq3OzZs7HjjjvGXcYqWeL5bbbZxlTUrr76atOHrmfPnthzzz1rfT6VlZWmSbkmsc+DTdVs0u7Tp0/cZazS0dy5c03T7n777bdB/0VWOy2nn366adLmc2U/P/YJHDlyJPr16xd3OzYhU2JzsYhIIgVAEWlyDHSJYSWRy+WKO8/+dOwfR2VlZaZ/25133rnB7dgPLvZxNsWZZ56J8ePHmwDI5t/TTjvNPH5t2MewsLBwo8+D97Gx50VsGu7atWvcduxjGDvat0ePHqbf3xVXXIG3334bjz/++AaPbTWZd+jQoZ7PXERSlQKgiGzxtt9+e7z11ltmyhWns/5vW1tttZUZsBHrt99+22A79rm78sor8dBDD+Gvv/7CuHHj6rxfVucaY7TtoEGDTNBbvHixqejVxm63m1DKkccMiuznyD6KiThQplu3biagiojURYNARKTJcVDCypUr406xI3g35rzzzjPVrTFjxpgAx6ZQjrZlKAoGg7XejoM+/v77b1x11VX4559/8Prrr5sqGsVW+DgimfPpsbq2//77mxBVFzbHcsBGbVXA+uIgk8svv9wM/GATNJ/X1KlTzSARno/F57ps2TL85z//McfBau5NHJzC/RcR2RgFQBFpchy1y6ba2NPuu+9e79t36dLFjOxl2GPA2Xbbbc10L23atDHVsdpwahWOnmWTKfvmsR+iNQo4tonVmm6Ffe/Y325j+PisSjJQbq5bbrkF1113nRkNzKliOK0Lm4S577HYBLzvvvua0FnTPlZVVZnpa84666zN3icRaf1sHAmS7J0QEWkuXC2DU65wipZYL774oqnELV++3DSxbgxDGiuGbHatK4Q2F4bbd955x0wzIyKyMeoDKCKt2qOPPmpGArdv395UEe+++24zYbSFI2a5Mskdd9xhmozrE/7o4IMPxpw5c0yzbPfu3ZFsHGwSO7+giEhdVAEUkVaNVT2upME+hGxG5Qoi11xzTXQwCSduZlWQ07689957NU41IyLS2igAioiIiKSY5HdcEREREZFmpQAoIiIikmIUAEVERERSjAKgiIiISIpRABQRERFJMQqAIiIiIilGAVBEREQkxSgAioiIiKQYBUARERERpJb/B5Z2gQ8G3CxJAAAAAElFTkSuQmCC", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "\n", - "\n", - "from scipy.signal import fftconvolve\n", - "\n", - "\n", - "# Example of DetailedBalance, up to 100 mueV. Res and peak is 5 mueV\n", - "\n", - "x=np.linspace(-0.5, 0.5, 1000)\n", - "\n", - "Gwidth=0.005 # 5 mueV\n", - "Lwidth=0.005 # 5 mueV\n", - "Lorentzian=Lorentzian(center=0, width=Lwidth, area=1)\n", - "Gaussian= Gaussian(center=0,width=Gwidth,area=1)\n", - "Voigt=Voigt(center=0, Gwidth=Gwidth, Lwidth=Lwidth, area=1)\n", - "\n", - "plt.figure()\n", - "DetailedBalanceT1=detailed_balance_factor(x,temperature=0.0)\n", - "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT1, label='T=0, first convolve, then DBF')\n", - "\n", - "DetailedBalanceT2=detailed_balance_factor(x,temperature=0.1)\n", - "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT2, label='T=0.1 K, first convolve, then DBF')\n", - " \n", - "DetailedBalanceT3=detailed_balance_factor(x,temperature=0.3)\n", - "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT3, label='T=0.3 K, first convolve, then DBF')\n", - "\n", - "\n", - "# Evaluate both models at the same points\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT1\n", - "model2 = Gaussian.evaluate(x)\n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "plt.plot(x, convolved, label='T= 0, DBF first, then convolve', linestyle='-.')\n", - "\n", - "\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT2\n", - "model2 = Gaussian.evaluate(x)\n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "plt.plot(x, convolved, label='T = 0.1 K, DBF first, then convolve', linestyle='-.')\n", - "\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT3\n", - "model2 = Gaussian.evaluate(x) \n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "plt.plot(x, convolved, label='T = 0.3 K, DBF first, then convolve', linestyle='-.')\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "plt.legend()\n", - "plt.xlabel('Energy (meV)')\n", - "plt.ylabel('Intensity (arb. units)')\n", - "plt.title('Width of 5 mueV')\n", - "plt.show()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "5622c265", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "6de5042e87f84157b42ae34113a65559", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "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devW5l5XXnmlCSBdcnJyZOLEidK0aVPzHg34PMujAd5nn33m9R41efJkqVu3rlcmdfDgwfLpp5+W6GsDIDgRAAIoFyZMmCCXXXaZrFmzRgYOHChXXXWVHDlyxBzTYE2DKQ2sVqxYIbNmzZL9+/eb8z1pcBceHi6//vqrvPHGG7J161a55JJLZOjQofL777/LTTfdJP/5z3/c52uQp23n3n//fa/r6La+r3LlygWW9eeffzbZuYI88sgj8uqrr8qiRYtk586dpowvvfSSfPzxxzJjxgyZM2eOvPLKK+7zNfj78MMPTXnXr18vY8aMkauvvloWLlxojutzSE9P9woKdQp3/axavR4SEuLef/rpp8uyZcvM+QBQJAsAytCIESOskJAQKyYmxmt54okn3Ofoj6IHH3zQvZ2cnGz2ff/992b7sccesy644AKv6+7cudOcs3HjRrPds2dPq3Pnzl7njBs3zmrXrp3Xvv/85z/mffHx8WZ76dKlpnx79uwx2/v377dCQ0OtH3/8sdDPNGTIEOuGG27w2rdgwQJz3Xnz5rn3TZw40ezbsmWLe99NN91k9evXz6ynpaVZ0dHR1qJFi7yuNXLkSGv48OHu7SuuuMJ8Ppf58+eb627atMnrfb///rvZv23btkLLDgAqtOjwEAD+Oa16ff311732VatWzWu7Q4cOXpk5rS7V6lOl2Ttt76bVv762bNkirVq1Muu+WbmNGzdKt27dvPZplsx3u23btiajdt9995k2dI0bN5Zzzz230M+TmppqqpQL4vk5tKpaq7SbNWvmtU+zdGrz5s2mavf888/P135Rs50uN9xwg6nS1s+q7fy0TWDPnj2lRYsWXu/TKmTlW10MAL4IAAGUOQ3ofIMVX2FhYV7b2p5O28ep5ORk077t6aefzvc+bQfneZ+TceONN8qkSZNMAKjVv9dff725f2G0jWF8fPwJP4de40SfS2nVcP369b3O0zaGnr19GzVqZNr93XPPPTJ16lR58803893bVWVes2bNYn5yAMGKABBAuXfaaafJV199ZYZcCQ0t/o+tU045xXTY8LR8+fJ852mbu3vvvVdefvll2bBhg4wYMaLI62p2rjR627Zp08YEejt27DAZvcI4nU4TlGrPYw0UtZ2jtlH0pR1lGjRoYAJUACgKnUAAlDntlLBv3z6vxbMH74nceuutJrs1fPhwE8BpVaj2ttWgKDs7u9D3aaePP//8U8aNGyd//fWXfP755yaLpjwzfNojWcfT0+zaBRdcYIKoomh1rHbYKCwLWFzayeTuu+82HT+0Clo/16pVq0wnEd32pJ919+7d8sADD5jn4Kru9e2couUHgBMhAARQ5rTXrlbVei5nn312sd9fr14907NXgz0NcNq3b2+Ge6lSpYrJjhVGh1bR3rNaZapt87QdoqsXsGcVq2u4FW17p+3tTkTvr1lJDSj/qccee0weeugh0xtYh4rRYV20SljL7kmrgPv27WuCzoLKmJaWZoavGTVq1D8uEwD7c2hPkEAXAgD8RWfL0CFXdIgWTx999JHJxO3Zs8dUsZ6IBmmaMdRq16KCUH/R4HbatGlmmBkAOBHaAAKwtddee830BK5evbrJIj777LNmwGgX7TGrM5M89dRTpsq4OMGfGjRokGzatMlUyzZs2FACTTubeI4vCABFIQMIwNY0q6czaWgbQq1G1RlE7r//fndnEh24WbOCOuzLN998U+BQMwBgNwSAAAAAQSbwDVcAAADgVwSAAAAAQYYAEAAAIMgQAAIAAAQZAkAAAIAgQwAIAAAQZAgAAQAAggwBIAAAQJAhAAQAAJDg8v+Bs6/Q05JtywAAAABJRU5ErkJggg==", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "\n", - "\n", - "from scipy.signal import fftconvolve\n", - "\n", - "\n", - "# Example of DetailedBalance, up to 100 mueV. Res and peak is 1 mueV\n", - "\n", - "x=np.linspace(-0.5, 0.5, 10001)\n", - "\n", - "Gwidth=0.001 \n", - "Lwidth=0.001 \n", - "Lorentzian=Lorentzian(center=0, width=Lwidth, area=1)\n", - "Gaussian= Gaussian(center=0,width=Gwidth,area=1)\n", - "Voigt=Voigt(center=0, Gwidth=Gwidth, Lwidth=Lwidth, area=1)\n", - "\n", - "plt.figure()\n", - "DetailedBalanceT1=detailed_balance_factor(x,temperature=10.0)\n", - "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT1, label='first convolve, then DBF')\n", - "\n", - "\n", - "# Evaluate both models at the same points\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT1\n", - "model2 = Gaussian.evaluate(x)\n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", - "\n", - "\n", - "\n", - "plt.legend()\n", - "plt.xlabel('Energy (meV)')\n", - "plt.ylabel('Intensity (arb. units)')\n", - "plt.title('Width of 1 mueV')\n", - "plt.show()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "68d207ad", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "b5d1fccf615c46f1a687ce1e5b228ba9", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAcEhJREFUeJzt3QeYE2XXBuAnffvSe2/Si4o0FUUU1E9BrOinYO8FrNhREbE37Arirx8qCjYEBQEF6QLSe+9le0ub/zpvMiHZxu6y2exmnttrnMnMZPJmdsmenLeZNE3TQERERESGYY50AYiIiIioYjEAJCIiIjIYBoBEREREBsMAkIiIiMhgGAASERERGQwDQCIiIiKDYQBIREREZDAMAImIiIgMhgEgERERkcEwACQiIiIyGAaARERERAbDAJCIiIjIYBgAEhERERkMA0AiIiIig2EASERERGQwDACJiIiIDIYBIBEREZHBMAAkIiIiMhgGgEREREQGwwCQiIiIyGAYABIREREZDANAIiIiIoNhAEhERERkMAwAiYiIiAyGASARERGRwTAAJCIiIjIYBoBEREREBsMAkIiIiMhgGAASERERGQwDQCIiIiKDYQBIREREZDAMAImIiIgMhgEgERERkcEwACQiIiIyGAaARFRu5s6dC5PJpNYncs4556ilJOS8jh07oiK88soraNGiBSwWC7p27Vohr0lEVNEYABKR8s0336jgberUqQWOdenSRR2bM2dOgWNNmjRB7969T/r19+3bh2effRYrV65EpPz222945JFH0KdPH0yYMAEvvvhikedKWeWe5F9iYmJQ1fzzzz+q7E8++WSR52zevFmdM3LkyAotGxGFhzVM1yWiKubMM89U6/nz5+Oyyy4L7E9PT8eaNWtgtVqxYMECnHvuuYFju3fvVss111yjHp999tnIycmB3W4vUwA4evRoNGvWLGKZtz/++ANmsxmffvppid/D+++/j4SEhMBjyRxWNaeeeiratm2L//3vf3jhhRcKPeerr75S6//+978VXDoiCgcGgESkNGjQAM2bN1cBYLCFCxdC0zRceeWVBY7pj/XgUYKnqpgB0x06dAixsbGlCmCvuOIK1KpVC1Xdddddh6eeegqLFi1Cz549CxyX4FCCRAkWiajqYxUwEQVIILdixQqVxdNJ1q9Dhw648MILVXDg9XpD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Hhe2yLnk884772hNmjRRAYdkUBYtWhQ4JplT+aOYfyidNm3aqPM7dOig/fLLLxEodXTf56ZNmxb6eysBN5Xv73MwBoDGY5L/RbYSmoiIiIgqEnsBExERERkMA0AiIiIig2EASERERGQwDACJiIiIDIYBIBEREZHBMAAkIiIiMhgGgEREREQGwwCQiKgMjh49ijp16qg5VSuDa665Bq+99lqki0FEVQQDQCIKq+HDh8NkMhVYBg4ciKpszJgxGDRoEJo1axa211i+fLm6V4sWLSr0+HnnnYchQ4ao7SeffFKVKS0tLWzlIaLowQCQiMJOgr39+/eHLP/73//C+ppOpzNs187Ozsann36Km2++GeF02mmnoUuXLvjss88KHJPM45w5cwJl6NixI1q2bIn/+7//C2uZiCg6MAAkorBzOByoV69eyFK9evXAcclyffLJJ7jssssQFxeH1q1b48cffwy5xpo1a3DhhRciISEBdevWxfXXX48jR44Ejp9zzjm455578MADD6BWrVoYMGCA2i/XkevFxMTg3HPPxeeff65eLzU1FVlZWUhKSsKUKVNCXmvatGmIj49HRkZGoe9n+vTp6j317NkzsG/u3LnqujNnzkS3bt0QGxuLfv364dChQ/j111/Rrl079VrXXnutCiB1Xq8XY8eORfPmzdVzJOALLo8EeF9//XXIc8TEiRNRv379kEzqJZdcgsmTJ5fqZ0NExsQAkIgqhdGjR+Oqq67Cv//+i4suugjXXXcdjh07po5JsCbBlARWy5Ytw4wZM3Dw4EF1fjAJ7ux2OxYsWIAPPvgA27dvxxVXXIHBgwdj1apVuP322/HEE08EzpcgT9rOTZgwIeQ68liel5iYWGhZ//rrL5WdK8yzzz6Ld999F3///Td2796tyvjmm2/iq6++wi+//ILffvsN77zzTuB8Cf4mTZqkyrt27VqMGDEC//3vfzFv3jx1XO5DXl5eSFAoU7jLe5XqdYvFEth/xhlnYMmSJep8IqJiaUREYTRs2DDNYrFo8fHxIcuYMWMC58hH0ZNPPhl4nJmZqfb9+uuv6vHzzz+vXXDBBSHX3b17tzpn48aN6nHfvn21bt26hZzz6KOPah07dgzZ98QTT6jnpaSkqMeLFy9W5du3b596fPDgQc1qtWpz584t8j0NGjRIu+mmm0L2zZkzR1131qxZgX1jx45V+7Zu3RrYd/vtt2sDBgxQ27m5uVpcXJz2999/h1zr5ptv1oYOHRp4fM0116j3p5s9e7a67ubNm0Oet2rVKrV/x44dRZadiEhYiw8PiYhOnlS9vv/++yH7atSoEfK4c+fOIZk5qS6V6lMh2Ttp7ybVv/lt3boVbdq0Udv5s3IbN25E9+7dQ/ZJliz/4w4dOqiM2mOPPaba0DVt2hRnn312ke8nJydHVSkXJvh9SFW1VGm3aNEiZJ9k6cSWLVtU1e75559foP2iZDt1N910k6rSlvcq7fykTWDfvn3RqlWrkOdJFbLIX11MRJQfA0AiCjsJ6PIHK/nZbLaQx9KeTtrHiczMTNW+bdy4cQWeJ+3ggl+nLG655RaMHz9eBYBS/XvjjTeq1y+KtDFMSUk54fuQa5zofQmpGm7YsGHIedLGMLi3b5MmTVS7v4cffhjff/89PvzwwwKvrVeZ165du4TvnIiMigEgEVV6p556Kr777js15IrVWvKPrVNOOUV12Ai2dOnSAudJm7tHHnkEb7/9NtatW4dhw4YVe13JzpVHb9v27durQG/Xrl0qo1cUs9msglLpeSyBorRzlDaK+UlHmUaNGqkAlYioOOwEQkRhJ50SDhw4ELIE9+A9kbvvvltlt4YOHaoCOKkKld62EhR5PJ4inyedPjZs2IBHH30UmzZtwjfffKOyaCI4wyc9kmU8PcmuXXDBBSqIKo5Ux0qHjaKygCUlnUweeugh1fFDqqDlff3zzz+qk4g8Dibvde/evXj88cfVfdCre/N3TpHyExGdCANAIgo76bUrVbXBy5lnnlni5zdo0ED17JVgTwKcTp06qeFeqlWrprJjRZGhVaT3rFSZSts8aYeo9wIOrmLVh1uRtnfS3u5E5PUlKykB5cl6/vnn8dRTT6newDJUjAzrIlXCUvZgUgXcv39/FXQWVsbc3Fw1fM2tt9560mUiouhnkp4gkS4EEVFFkdkyZMgVGaIl2BdffKEycfv27VNVrCciQZpkDKXatbggtKJIcDt16lQ1zAwR0YmwDSARRbX33ntP9QSuWbOmyiK+8sorasBonfSYlZlJXnrpJVVlXJLgT1x88cXYvHmzqpZt3LgxIk06mwSPL0hEVBxmAIkoqklWT2bSkDaEUo0qM4iMGjUq0JlEBm6WrKAM+/LDDz8UOtQMEVG0YQBIREREZDCRb7hCRERERBWKASARERGRwTAAJCIiIjIYBoBEREREBsMAkIiIiMhgGAASERERGQwDQCIiIiKDYQBIREREZDAMAImIiIhgLP8PiUdC/xI4J2MAAAAASUVORK5CYII=", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "\n", - "\n", - "from scipy.signal import fftconvolve\n", - "\n", - "\n", - "# Example of DetailedBalance, up to 100 mueV. Res and peak is 5 mueV\n", - "\n", - "x=np.linspace(-0.5, 0.5, 1001)\n", - "\n", - "Gwidth=0.005 \n", - "Lwidth=0.005 \n", - "Lorentzian=Lorentzian(center=0, width=Lwidth, area=1)\n", - "Gaussian= Gaussian(center=0,width=Gwidth,area=1)\n", - "Voigt=Voigt(center=0, Gwidth=Gwidth, Lwidth=Lwidth, area=1)\n", - "\n", - "plt.figure()\n", - "DetailedBalanceT1=detailed_balance_factor(x,temperature=10.0)\n", - "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT1, label='first convolve, then DBF')\n", - "\n", - "\n", - "# Evaluate both models at the same points\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT1\n", - "model2 = Gaussian.evaluate(x)\n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", - "\n", - "\n", - "\n", - "plt.legend()\n", - "plt.xlabel('Energy (meV)')\n", - "plt.ylabel('Intensity (arb. units)')\n", - "plt.title('Width of 5 mueV')\n", - "plt.show()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "0bfc6acc", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "345223aaa342478798b09f40f4477c6d", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "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n35S24oVK/Dcc8/ZjkvwJ4HsnDlzsH37dtx999245ppr1Hn2HnnkEbz00ktYt24dgoODcf3117ttT0FBgQp65WctQdvmzZvxwAMP2Lrn58+fr34m9957L7Zt24abb74ZU6dOxbJlyxweZ8aMGepnvGXLFowbNw5XX301srKyVJAnweXnn3/ucL4E2Keeeio6dOignkuCPzlfXstvv/2G/fv3Y+LEiS7bfNZZZ6mxnNp7IIxGowrg5Xm1n6W875deeqlqkxyTgPD222+v1ftEVZjphOXm5sonvLokIv9z1XurzB0e/Mn81drkWp1fVmE0d5n+s7pPSk5RtecWFxebd+zYoS6dPBFT923bd5X3l+uyb+44x8ed3cn1fetoypQp5vHjx7s8NnHiRHOvXr1stzt06GA2GAzmyMhIc1hYmPrMHD58uDk7O9t2zrJly9R+Ocd+y8jIcNsGeX5phz15jPnz56vrBw4cULdfffVVh3P69u1rfvLJJ10+ptYO+7bVlv1za5544glzRESEOS8vz7bv/vvvV69flJSUqOMrV650uN8NN9xgnjRpkkOblixZYjv+888/q30u/++YzeZ33nnHHB0dbc7MzHR5fMSIEeZp06Y57Lv88svN48ZV/n+Rx3/00UdttwsKCtS+X375Rd3euHGjOSgoyHzo0CF122g0mpOSksxvv/22uv3rr7+a9Xq9OTm58ndn+/bt6jHWrFlj+/n079/fdvzOO+80jx492nZ78eLF5tDQUNv7IT+Xm266yaHdf/75p1mn07n8WVT3O5bLv99mZgCJiBooAxii16F9vKVYZF9aYHZLSewg3Yf27r//flWsIVkb6coU559/vsrw2Pvzzz/VedomXbH1JV2f9qTL8JlnnlGZqieeeEK1qTFJ1690gWtat26NtLQ0dX3v3r0oKipSBTSShdQ2yQhKtstev379HB5DaI9TlfzsBg4cqLp/XZFsqLx+e3Jb9rt7TulGlm5c7TmlerdXr162LKBk+eTY5ZdfbnsOyarKpundu7fK8lV9Ho1k+qTLOyUlxZZRlP8nWpW3ZDJleIH9z0qyupJtPHDggMvHJPeCqzlGRBSwisoqkJpb4jC2rzakEEQCx71p+TitW8KJPfnDlj+AdaK3K37oeaHlMYKqfMe/aysam/xxl/Fs9hISEtC1a1d1XcaSvfrqqzjllFNUl+OYMWNs58n9tD/2DUUCF3s33nijChp+/vlnNe5MumCla/W///0vGoNUSduT4FjripWuWiFtkfGR9qoWs9g/jhZgV6241sj4uMZuuxawSQAo3exyKd2z8fHxJ/x8Q4cOVeMSv/zyS9xyyy2qq9p+PKn8vKS72lUBUfv27U/4eQMVM4BERNVk/5pHGtAswv0awFV1TrAEHAczi078yQ2Rdd/0dt/n5brsC6kSCLi7bwP5/fff1bg6GaNVHZkORhQXVxmj2EQkK/Wf//xHjVWUcXDvvfee2i8FEaJqZrK2wVJd7ycZMQn0pFhCAmT7zT5zVleSuZMsoIy/c0Uyd3///bfDPrkt7amLq666So0hXL9+vSpc0cbqac9x+PBhtWl27Nihijyqex55DMn8yThRGWsoGUCNFBvJY1T9WcmmvXdUewwAiYhcSM4qsk0BUxdaF/Bh6/39lRRSyGTMUmggFb3PPvusGvQv08BMnjzZ4VypepVzpUBizZo1qks4MTFRVbM2tbvuuguLFy9WXYbSbslCSrAipHhBslxSrJGenm7L0NW2q1e6t+V12s9xWB3pGr7vvvtU4cfHH3+sun2lTa+//rq6faKkQEOqqCdMmKACOym+kOKKVatWqePy85fMmlTx7tmzBy+//LIKhqUtdSGvWd5DmddRgt+LLrrIdkwyu3379lUBnbwmed/l/4UUp1TtlrennT9z5kxcdtllDpnQBx98ECtXrlRFHxLgStul8pxFICeGASARkQtaANcuro4BoHXCaC2A9FeLFi1SY9EkCJCuPwmkXnvtNfUHWcvwaR5//HF1rkwCLQGidMtK92t9ugtPlAQqUgksQZ+0u3v37njrrbfUMemGlcpX6dKUya21wEKCparjGquSbmSpdJXMnYy/q62nn34ajz32mOqK1tokXcJVu9HrQrJh8vOVaXWkelcCMak81t4XCQylwvnFF19U0+C88847qoL5jDPOqPNzScAmY/Nkuhj7rmf5ecn/BRnHefrpp6uAsHPnzqpytzqSzRs2bJgam2mfUdQymzLWUCb+lqlg5Ocs/7fk/xXVXZBUgpzA/QhAXl6emtcpNzdXDY4lIv/x2IJt+HT1Idx2ZhfcP7Znre93KLMQo15YjtBgHXY9fa7bwKGkpERloeQPvcx/Rt5LikUk8JACBfId1f2O5fHvNzOAREROSgtwOKvwhDKAbZqFQxYNkSXk0vNLG6mB1JRkcuvnn3/e080galCsAiYiqurr6zAlpQj/4Aa0iwsH1rwHhEYD/a+s1VQwEgQeyS7G4ewitIhhds/Xyfg1In/DDCARkb3jO4C9v+HU8tVoE5SJ7lnLgYX3AUuedF5Zww0ta+jv4wCJyHcxACQisteyN7Ku/g1PVFyHA0hCswEXADFtgfxUYMf3dSsEyfTMNCdERDVhAEhEVMUBQzd8YTwLrWPDERIaDgy+znJgwyd1mgqGGUAi8lYMAImIqjiSbQnc2sr4PzHgKsvlob+BvNQa79+uee3nAuREDESNg79b1WMASESk+XYa8N1NKDiy3SGQQ2wSkGSdvHbP4gaZC1BbZkvWgiWihqf9blVd0o4sWAVMRCTKiixj/IylONb1AlmwzHEKmB7nAkfXAbt/qewSdqNNM0vlb1p+CcqNJlUZXJVMyivr3qalpanbERERNU42TES1y/xJ8Ce/W/I7VnVicvLDAPDNN9/ECy+8oJbi6d+/v1pOR2YUr4ksPC1L58gyRgsWLGiSthKRl5HuXWMpENsOG4oTAWShXXO7tXS7jQV+fwY48CdgrHBce7eKhMhQGPQ6lBlNOJ5XgrZu5hKU5bqEFgQSUcOR4E/7HSM/DgBleZl77rkHc+bMwfDhw/Hqq69i7Nix2L17t1oOx52DBw+q9Q9lWRkiCmD7ras8dDkTKf9aJnBOamYXALbsA4TFAiW5wLHNQNJgtw+l0wWhdbMwHMosQkqO+wBQMn6yRJp8RpWXlzfwCyIKXNLty8xfgASAspj1tGnTMHXqVHVbAkFZT3Hu3LlqXUd3a0LKWoOy9uOff/6JnJycJm41EXmNI2vVhbn9KUhda5m+RaqAbXQ6oP0I4N9fgEMrqw0ALffVAsCap4KRP1T8Y0VETckvikDKysqwfv16tdi0RqfTqdurVq1ye7+nnnpKffO+4YYbmqilROSVKsqAlE3qan7CQJSUm9T1FjGhjud1GGG5lACwBrIaiEjJ5VyAROR9/CIDmJGRobJ5LVu2dNgvt3ft2uXyPn/99Rc++OADbNpk+dCvjdLSUrXZLyZNRH7g2BbL+L/w5jgS1Eb6gxEfaUBYSJWsXPtTLJeH18hIc+nDdfuQWvdxbTKARERNzS8ygHWVn5+Pa6+9Fu+99x4SEhJqfb9Zs2YhNjbWtrVr165R20lETdv9i7ZDcSy/RF1tFetiDd9WfYAgPVCUAeQdrfYhte5jGQNIRORt/CIDKEGcjJ85fvy4w3657aoCaN++far448ILL7TtM5ksXT7BwcGqcKRLly5O95s+fboqNLHPADIIJPIDR9ZZLtsORWpuifP4P01IOHDWY0B0GyA0ulZTwTADSETeyC8CQIPBgMGDB2Pp0qWYMGGCLaCT27fffrvT+T179sTWrVsd9j366KMqM/h///d/boO60NBQtRGRnzm+zXLZZgBS92sBoIsMoDjt7lo9pG0MIANAIvJCfhEACsnMTZkyBUOGDFFz/8k0MIWFhbaq4MmTJyMpKUl144aFhaFPnz5O8wWJqvuJyM+VlwAZeyzXW56E1I3p7ruA60ALIPNKKpBfUo7oMK5GQETew28CwIkTJyI9PR2PP/64mgh6wIABWLRoka0wJDk5WVUGExE5yNgNmI1AeBwQ3RrH8pKrzwAayy1FIGk7gGHT3D6sBHwxYcEqAJRuZQaARORN/CYAFNLd66rLVyxfbp3k1Y2PPvqokVpFRF7t2LbKiZ6DgqofAyhMFcBH58uMgUDvCUCUrBrivhs471i+6gbu3rL6MYNERE3JrwJAIqI66zIauPQDwBCp1hBNtVbtus0ASiFIp9PV+SgvBFB9ALhLBYCsBCYi78IAkIgCW0xroO9l6mpeUTmKy401jwGc8kOtHloLIlM5GTQReRkOiiMiskrNswRqcREhzpNAn4BWMZYA8HgeM4BE5F0YABJR4CrJBVa9BexZom5q3b+t3I3/sycrgRRlVXtKS2sAeCyvcgUhIiJvwACQiAJX+m5g8XTgxzvUTa0ApE1NU8Bk7gNmdwReG2gJBN1oaX2cNGYAicjLcAwgEQUuvQHodZFlChjJ1FnH6tU4B2BMElCaB5hNQMFxINp5xSHRMsYycTy7gInI2zAAJKLA1WYAMPFT281j1kBN67p1KyQMiOsEZO0D0ne5DQC1MYDZReUoKTc2yLhCIqKGwC5gIiKrtHzLWL0W0bVY8jG+a2V3sBux4SEwBFs+ZtOtj01E5A0YABJR4CpIcxjDl2Yt1mhh7bqtVnwXy2XWfrenBAUF2bqBtewiEZE3YABIRIHJZARe6QM82wbIS6mSAazFOsDNO9eYARScCoaIvBEDQCIKTLmHAWOpJRCMagmjyYyswrp0AWsZwOoDwBa2AJBdwETkPRgAElFgythbmcnT6ZFZUAqTGdAFAfFRdRgDmH3QEkS6wQwgEXkjBoBEFJgy9zpk8rTuXwn+9BIF1iSmLaAPBYxllmyiG5wKhoi8EQNAIgpMkrmzG8uXll9S++5fodMBzTvVOA7QthqIdZJpIiJvwACQiAJTziHLZVwHxwrg2gaAonnNlcBaAKhlGImIvAEDQCIK7Axgs451rwDWxNdcCdzKLgNormbZOCKipsQAkIgCjwRi2VUygFoXcG3mAHTKALoPALXHKy43Ir+04sTbTETUgLgUHBEFnqJMoLzQcj223Yl3AXc/F7huYeWcgC5EGIIRHRaM/JIKpOWVICYspJ6NJyKqP2YAiSjwaNm/6DaWdX3tuoAT6xIAxrQGOp5quaxGZTcwxwESkXdgAEhEgSfnoEP3r/1avYl1GQNYS7ZKYE4FQ0ReggEgEQVwAYglAJTiDC0ArFMXsNj6DbDkycqJpasZB6g9BxGRp3EMIBEFnioFIDlF5SgzmureBSzWfgAkrwRa9gESrKuDVKE9JgNAIvIWDACJKPCc9QQw8BogMtFh/F9seAjCQvR1e6xeFwKt+gBxlulkXEm0Li2XXsAAkIi8AwNAIgo8kfGWzarOq4DYO+XWGk+pzAByDCAReQeOASSigGcb/1eXOQDrgF3ARORtGAASUWApSAMWPwKs+9C264RWAbFXnA2k7XR7WMssMgAkIm/BAJCIAkvGHmDVG8Df/2fbdUKTQGtykoHZHYF3TgdMlkKSqhKjLIFlXkkFSsqNJ9pyIqIGwzGARBRYpPDj5FuB0BinMYB1rgDWJpMO0gPGMiA/FYhNcjolJjwYBr1OVRpnFJSibVxE/V4DEVE9MQNIRIElsTtw7izgzOnOXcDWCZvrRB8MxLatzAa6EBQUxHGARORVGAASUcCTrJxIiDKc2AM0a2+5zLHOL+hCAgNAIvIiDACJKLBk7rMUgtiN18vQloGzztdXZ9YVRZBz2O0pnAuQiLwJA0AiCixfTQFe7AbsXaJullWYVHGGSDjRAFAb95d3xO0pXA6OiLwJA0AiCixakGYdt5dZaAnI9LogtRLICYmxBoC5R2vOADIAJCIvwACQiAJHWaFlzj67rF1mQZm6jI80QKcLqmcGsJoA0DoGUCs4ISLyJAaARBQ4tAydIRoIi3UYkxd/ot2/IqZtzRlAFoEQkRdhAEhEAdj9WzlXn5YBPOEKYPvHK80FSvJcnsIAkIi8CQNAIgocWoZOG7PnMAVMPTKAoZUZRXfdwPZVwGaz+cSfi4ioATAAJKLAoQVnDhnAes4BWMtuYC0DaF91TETkKQwAiShw5B5xDNZUBtBaBFKfDGAtpoIJC9EjOsyy+ia7gYnI0xgAElFAZwAbpAtYnDcbuHMLMOBqt6dwHCAReQsGgEQUOLTu2VhXGcB6dgE37wzEdQD07ucS5GogROQtGAASUWCQwgsXXcDaGMATXgauDpgBJCJvYRmQQkTk70pygPJCy/WYNurCZDIjs7CBMoB5qcCadwBjOTB2pstTGAASkbdgBpCIAqv7N7w5YIiw7Couh9FkmZIlPrKeGcCKYuCvV4C171uyjS4wACQib8EMIBEFhha9gXt2AUWZTgUgMWHBMATX8/uwzC047CbL+EJThcuxgC2iw9QlxwASkacxACSiwKDTATGtLVuVApAEa2auXoJDgXEvVHsKM4BE5C3YBUxEAcs2BUx9u39rSZtsOj2/pEmej4jIHWYAiSgwbPwMSN8J9LwQaD/ccRWQ6HoWgGhKcoHsQ5Zl4WRKGDcZwKzCMjX2UK8LapjnJSKqI2YAiSgw7F4IrHwdOL7VeQ7AhsoA/j4TeGcksP5Dl4ebRxgQFARI3YkEgUREnsIMIBEFht4TgLiOQJtBtl2ZhQ20CohGG18oU8K4EKzXIT7SoAJPGQeoZQSJiJoaA0AiCgz9LrdsdhpsFRBNtGV+QeSnuD1Fgk15Xm38IRFRQAaAycnJOHToEIqKipCYmIiTTjoJoaH8VkxEja/B1gHWRLeyXOYfc3uKZP12HctnJTARBV4AePDgQbz99tv48ssvceTIEZjtJk01GAwYOXIkbrrpJlx66aXQydQNRET1UV5iKQCJbl0ZpKkiEOs0MA2VAbSuMOKuC9g+2GQGkIg8qcmjqzvuuAP9+/fHgQMH8Mwzz2DHjh3Izc1FWVkZjh07hoULF+K0007D448/jn79+mHt2rVN3UQi8jdZ+4B3zwDeHtHIGUDrGMCyfKA03+UpnAuQiAIyAxgZGYn9+/cjPj7e6ViLFi0wevRotT3xxBNYtGgRDh8+jKFDhzZ1M4nIn2hdslGV2b+isgoUlRkbdgxgaBQQGgOU5lmygInRTqdo2UZmAIkooALAWbNm1frcc889t1HbQkQBFgC66P4NDdYhKrQBPwolCygBoBSCJHZ3nwFkAEhEHuTRAXbFxcWq+EMjxSCvvvoqFi9e7MlmEZG/KXAOAO27f4Nkcr6Goj2Hm3GAtjGA+ZwHkIgCNAAcP348PvnkE3U9JycHw4cPx0svvYQJEyaoIhEiogaRf9xyGdXSeR3ghur+rVoI4mYqGGYAiQiBHgBu2LBBVfyKb775Bi1btlRZQAkKX3vtNU82jYj8PAOoLQMX31AFIFULQdxMBaNlAGUlkHKjqWGfm4jIFwJA6f6NjrYMkv71119xySWXqGlfTj75ZBUIEhE1aAbQZRdwI2UA81xnAOMiDLY1gLkcHBEFZADYtWtXLFiwQFX6yri/c845R+1PS0tDTEyMJ5tGRP4kP9WpCriyC7ihM4DaZNCuxwBK8CfLwQlOBUNEARkAylx/9913Hzp27KjG/51yyim2bODAgQM92TQi8hcy0XyBlgG0HwPYSF3Anc8E7toGXO++mE0LOjkOkIgCcim4yy67TE36nJqaqiaH1px11lmqO5iIqN5KcoGKEqcMYIOvAuIwF2BUtaeoQpBUZgCJKEAzgNdff72aGFqyffZLvsl6wLNnz67z47355psqmxgWFqYyimvWrHF77nfffYchQ4agWbNmqg0DBgzAp59+esKvhYi8lJb9C2sGhIQ13iogdcDl4IgooAPAjz/+WM0FWJXs06aHqa158+bhnnvuUSuISHWxZBTHjh2rxhO60rx5czzyyCNYtWoVtmzZgqlTp6qNcxAS+RltLJ5dAYjItBZgNEoA+OfLwLfTgPR/XR7mcnBEFJABYF5enlr/12w2Iz8/X93WtuzsbLUesCwLVxcvv/wypk2bpoK43r17Y86cOYiIiMDcuXNdnn/GGWfg4osvRq9evdClSxfceeedau3hv/76q4FeJRF56xyAFUYTsovKGnYZOHs7fwS2fgVk7nF5uHI5OFYBE1EAjQGUbleZeV+27t2dl0qS/TNmzKj145WVlWH9+vWYPn26bZ90KY8ZM0Zl+Goigejvv/+O3bt3V9v1XFpaqjaNBKxE5OX6XAp0Oh0wVgZbWUVlqjZEZmORaVka3JCpQNF4IKFHDRlA69hEIqJACACXLVumgq7Ro0fj22+/Vd2xGoPBgA4dOqBNG+tcWrWQkZEBo9GoJpK2J7d37drl9n6ShUxKSlJBnV6vx1tvvYWzzz672nWM6xKYEpEX0AcDMdbJma20ZdiaR1bOydegBk2u9nCibQwgM4BEFEAB4KhRo9TlgQMH0L59+4Zdh7MOZBLqTZs2oaCgAEuXLlVjCDt37qy6h12RDKOcY58BbNeuXRO2mIgaQmah5wpABMcAElHABYBScNGnTx/VRSsZuK1bt7o9V8bk1UZCQoLK4B0/bh3rYyW3W7VyHPhtT9ogk1ELqQLeuXOnyvK5CwBDQ0PVRkQ+ZPlsoDQPGDQFSOxeZQ7ARuj+FWVFlvF/xnKg7RCnw1rgmVtcjtIKI0KD9Y3TDiIibwkAJdA6duyYKvKQ65L9k+7gqmS/dOvWhnQbDx48WGXxJkyYoPaZTCZ1+/bbb6912+Q+9mP8iMgPbPkSyNoP9BhnCwC1OQDjIxvpC93h1cCnFwOJPYHb/nE6HBseghB9EMqNZtWWNs3CG6cdRETeEgBKt29iYqLtekORrtkpU6aouf2GDRuGV199FYWFhaoqWEyePFmN95MMn5BLOVcqgCXok8pjmQfw7bffbrA2EZEXOPlWIOcQEN/Ftksbe9doGcBobT1g18vB6dRycKE4lleispEMAInI7wNAKfBwdb2+Jk6ciPT0dLW8nGQYJbu4aNEiW2FIcnKyw2TTEhzeeuutOHLkCMLDw9GzZ0/873//U49DRH5k2DSnXVmNPQZQKzopzQXKCgFDpMtxgBIAchwgEQXcUnBiz549qipYJmyWLlh7EszVhXT3uuvyXb58ucPtZ555Rm1EFHgqu4AbKQMYGgOERALlhZYsYIJlrLHruQAZABJRgAWA7733Hm655RZVxCHFGvbVwHK9rgEgEZGDwkwg5yAQ0xaIrpwmKsO6Ckh8Y2UA5bNMsoCZey0rkbgIAFkJTEQBGwBKBm7mzJl48MEHPdkMIvJX+5cB394AdBwJXPeTbXdmY1cBi2gtADxWw3rAnAuQiAJsLWBZ9u3yyy/3ZBOIyJ9pwZfdMnD2XcAJjVUFrAWAqg0pLg8zA0hEARsASvD366+/erIJROTPCqwBYHTlfKBFZRUoLjc2QQbQ+pw1ZADTOQaQiAKtC1gmYX7sscewevVq9O3bFyEhIQ7H77jjDo+1jYj8QP5xpwyglv0LC9EhwqBvggxgarUZwAxmAIko0ALAd999F1FRUVixYoXa7EkRCANAIqoXLfjSgjH7VUAiQxt3GUptKhg3cwEyA0hEARsANuRE0ERETgqsGUC7CmDbFDCN2f1bhwxgfkkFSsqNCAvhcnBEFCBjAImImqYLuHIMYKZ1EuhGmwPQKQA8BrhY7jImLBgGveUjmHMBElFAZQCvv/76ao/PnTu3ydpCRH6mrMiyEoewnwPQlgFsxApg9ZzWoNNYBhRnAxHNHQ5L97NkAY/mFKtK4LZxEY3bHiIibwkAZRoYe+Xl5di2bRtycnIwevRoj7WLiPyoAjgkwrIyh1WWbRLoRs4ABocC9+wEIhMBvWOBm/1qIBIAci5AIgqoAHD+/PlO+2Q5OFkdpEuXyoXbiYjqVQFsV+yhTQLdqHMAamLaVHuYcwESkad43RhAnU6He+65B6+88oqnm0JEfjYHoMhsqgxgLVSuBsIAkIgCPAAU+/btQ0VFhaebQUR+Ngdgk44BFNvnA99OAzbPc3mYGUAiCsguYMn02TObzUhNTcXPP/+MKVOmeKxdRORPGcDKOQAd1gFu7CpgcXw7sPUrIDQK6D/R6TAzgEQUkAHgxo0bnbp/ExMT8dJLL9VYIUxEVK3RjwHDbwGCKjs6TCazrQhEC74aVdezLQUoSYNdHmYGkIgCMgBctmyZJ5+eiPyZTu8w/YvIKylHhckyJ19cpOvK3AbVfrhlc4MZQCLyFK8cA0hE1Bi08X/RYcEIDfb8yhvMABKRpzAAJCL/9P1twKLpQFGW8xQwTdH9K0wmIGUjsPsXwGR0OQ+gKCwzoqiMhW9E1HQYABKR/6koBTb+D1j9luspYJqiAEQxA++dBXxxJVCQ5nQ0KjQYYSHW5eDyORk0ETUdBoBE5H/MJmDsLODUO4HwOM/NASjjELVpaPJTnA7LcnBaNjKd4wCJKFCKQIiIGkVIOHDKrU67bVPANFUXsIhpbQn+8q3T0rgYB3gk27IeMBFRQGcA161bhz/++MPTzSAiP5NpLQJJaLIuYLt5CPNTXR5mJTAReYJXZgCvvfZa/PvvvzAanQdNExHVKPsgUJgBNOsARCXadmcWeiADqC1Fl+c6AGQlMBF5gldmAJcuXYr9+/d7uhlE5Ks2fAq8fxaw4jmX08A090gG0HUXMMcAEpEneGUGsE2bNp5uAhH5wzJwUdbsm9MYQE8EgM5FIPYZwAxmAIkokAJA6eadP38+du7cqW736tULEyZMQHCwx5tGRL5Ky7Zp3a9VqoCbbB5A+za4KwKxBqPMABJRU/JolLV9+3ZcdNFFOHbsGHr06KH2zZ49W60H/OOPP6JPnz6ebB4R+ar8404BYLnRhJyi8iaeB1CqgNtUWwRiywAyACSiQBkDeOONN+Kkk07CkSNHsGHDBrUdPnwY/fr1w0033eTJphGRX3QBV64FnG3N/umCgGYRTdkFbA1Ci7OB8mL3YwDzS2E2W9YpJiLy6wzgpk2b1JQvcXGVE7XK9ZkzZ2Lo0KGebBoR+SpjuaUCuEoG0L4ARC9RYFMJawYEhwEVJZZu4OadXAaAJeUmtSScrA5CROTXGcDu3bvj+HFrV42dtLQ0dO3a1SNtIiIfp5ZcMwNBeiAiwXkKmMgmHP8ngoKqrQSODA1GhEGvrnMqGCLy2wAwLy/Pts2aNQt33HEHvvnmG9UNLJtcv+uuu9RYQCKienX/6io/4rKaehk4exIABumAokyXhzkOkIiaWpP3NTRr1kytf6mRMS9XXHGFbZ82BubCCy/kRNBEVI8CkMrxf/ZdwE06CbRm0heAIQrQu/7IlW7gQ5lFzAASkf8GgMuWLWvqpySiQFLTHIBNWQGsCW9W7eFELgdHRP4eAI4aNUpdVlRU4Nlnn8X111+Ptm3bNnUziCjQ5gDUMoCeCABrkBBtnQuQGUAi8vciEJno+YUXXlCBIBFR408C7YF1gDWpW4BvbgB+ecjl4cSoMHXJDCARBUQV8OjRo7FixQpPNoGI/E1hutMcgI5jAD2QASzNB7Z9A+xZ7PIwM4BE1NQ8OuHUeeedh4ceeghbt27F4MGDERkZ6XBcVgkhIqqTiZ9Zqm2DQ11mABM8EQAmdAfOmQk0a1ftGMB0a5BKROTXAeCtt96qLl9++WWnY1IVzCpgIqozmfolKtFpd+UYQA90AUt7Rtzu9nCCNg0MM4BEFAgBoMlk8uTTE1GAKCqrQFGZ0XNdwDWozABaloOznyqLiMjvxgASETWowkzgqynAoodlUlGn7J8hWOe5pdbSdgK7FgK5R9xOBF1WYUJeCQvjiKjxeXzRycLCQlUIkpycjLIyx/EvskoIEVGt5R4GdiywFICc+6zTKiAJkQbPZdcWTQf2LwMmzAEGTHI4FBaiR3RoMPJLK1QlcGx4iGfaSEQBw6MB4MaNGzFu3DgUFRWpQLB58+bIyMhAREQEWrRowQCQiOpGpn459zmn3VoBSHNPdv/a1gNOdTsOUAJAqQTukhjVtG0jooDj0S7gu+++Wy35lp2djfDwcKxevRqHDh1SFcEvvviiJ5tGRL4aAJ58i2VzNQWMJwpANDHVB4BcDYSIAiYA3LRpE+69917odDro9XqUlpaiXbt2eP755/Hwww97smlE5EdsFcBenAHUxgFyLkAi8vsAMCQkRAV/Qrp8ZRygiI2NxeHDhz3ZNCLyRbLixuE1QFGWy3WAEzyxCkjVADDPTRewNThlBpCI/D4AHDhwINauXWtbI/jxxx/HZ599hrvuugt9+vTxZNOIyBctfw744Gxg+3cOuzMLvWAdYFsG0LpUXRXMABJRwASAzz77LFq3tnwozpw5E3FxcbjllluQnp6Od99915NNIyJfVGANrqIc1wHWsmoeWQdYo61NLG10MQeqlp3UxisSEfltFfCQIUNs16ULeNGiRZ5sDhH5uvzjjsGW0yogHswAqrWJgwBTBVCUAUS1cDjMDCARNSVOBE1E/kGyaloGsEoAKCts2AdZHqEPrgz6XBSCVGYAGQASkR8GgOeee66a7qUm+fn5mD17Nt58880maRcR+bjiLEt2TURWZtdMJnPlRNCe7AK2D0xdFIJowWmGdTk4IiK/6gK+/PLLcemll6pKX5kDULqB27Rpg7CwMDUf4I4dO/DXX39h4cKFOP/88/HCCy80dROJyBdpxRURCUBwZVdvdlEZjCazd6wDHN0GSN3sMgOota3caEZucTmaRXjfmsVE5D+aPAC84YYbcM011+Drr7/GvHnzVLFHbm6uOiZLNPXu3Rtjx45V1cG9evVq6uYRka8HgFW6f7WiimYRIQjRe3jUi9Y2F5XAocF6tQScBH8yDpABIBH5XRFIaGioCgJlExIAFhcXIz4+Xs0NSERUZ1pWzSkAtI7/83T3r4hpAwTpgLICt3MBqgCwoBTdWkY3efOIKHB4tApYI93BshERNfQUMFpVrcfH/4kRdwAj7wV0epeHZRzgvvRCVgITUWAEgEREjdcFbA0APVkBrAkJq/Yw5wIkoqbCaWCIyK8DQG0KGG2pNW/GuQCJqKkwACQi/84A5nvJFDCivBj4eiow9zygwjnLx7kAiaipsAuYiPyDrK5hv+Zu1SIQb+gCDg4Ddv0EGMssYxabtXc4zAwgEQVEADhlyhQ1Lczpp5/uyWYQkT/470bLZNChMQ67tWDKK6qAg4KAcS8CodFAWDOnw1obmQEkIr/uApbpX8aMGYNu3brh2WefxdGjRz3ZHCLyZTodEOk4CbRDEYg3BIBi8BSgzyVAmGOgKpgBJKKACAAXLFiggr5bbrlFTQrdsWNHnHfeefjmm29QXl7uyaYRkR+QZeAytWXgor2/CEQLUqXN0nYiIr8tAklMTMQ999yDzZs3459//kHXrl1x7bXXquXh7r77buzZs8fTTSQib3dkHfDVZOCvVx125xSXVy4DF+klGcDsQ8DOn4DDa9wuBydtliXsiIj8NgDUpKam4rffflObXq/HuHHjsHXrVrU03CuvvOLp5hGRN0vfBez4Hjj4p+Nua1eqLANnCPaSj7vt84F5VwNr33c6JEvVxUVYVkPiXIBE1Jg8+oko3bzffvstLrjgAnTo0EGtD3zXXXchJSUFH3/8MZYsWYKvvvoKTz31VK0e780331TdyGFhYRg+fDjWrHH+hq157733MHLkSMTFxalNxiJWdz4RebG2w4DzXgAGTfbu8X/2Vcra0nVVcBwgEfl9FXDr1q1hMpkwadIkFXwNGDDA6ZwzzzwTzZo5V8tVJWMIpSt5zpw5Kvh79dVXMXbsWOzevRstWrRwOn/58uXqeUeMGKECxtmzZ+Occ87B9u3bkZSU1GCvkYiaQGJ3y1ZFZQDoReP/YqwBYJ7rAFCC1X+PFyC9oKRp20VEAcWjGUDp2pVsn2TuXAV/QoK/AwcO1PhYL7/8MqZNm4apU6eqbmMJBCMiIjB37lyX53/22We49dZb1fP27NkT77//vgpGly5dWu/XRUTewTYFTHT1S7B5JgNonbjaTQZQm8CaiMjvAsBly5a5rPYtLCzE9ddfX+vHKSsrw/r161U3rkan06nbq1atqtVjFBUVqbY0b97c7TmlpaXIy8tz2IjIC+xfDiT/A5QWOOzWxtF5VQZQW6mkLB8ozXc6rHVXa0vYERH5XQAo4/yKi4ud9su+Tz75pNaPk5GRAaPRiJYtWzrsl9vHjrn+ll3Vgw8+qCqP7YPIqmbNmoXY2Fjb1q5du1q3kYga0YLbgLnnWIpBXGQAvWoMoEwCbYh2mwWszAAyACQiPwsAJXMmk0CbzWbk5+c7ZNSys7OxcOFCl+P2Gstzzz2HL7/8EvPnz1fjAd2ZPn26are2HT58uMnaSERumExAwXHL9aiWrpeB86YA0D4L6KIQhBlAIvLbIhAZ1xcUFKS27t2dB27L/hkzZtT68RISEtTUMcePW/8IWMntVq0cF4av6sUXX1QBoFQc9+vXr9pzQ0ND1UZEXkSWfzOVVxsAet0k0FIIkrnHZSEIq4CJyG8DQBn7J9m/0aNHq2lg7MfdGQwGNSWMdMfWltxn8ODBqoBjwoQJap9W0HH77be7vd/zzz+PmTNnYvHixRgyZEg9XxUReYTWjRrhfhm4xCgvKgKpYSoYbbwi1wMmIr8LAEeNGqUupbq3ffv2KuNXXzIFzJQpU1QgN2zYMDUNjBSTSFWwmDx5spreRcbxCZn25fHHH8fnn3+u5g7UxgpGRUWpjYh8LADUulXtl4HTikC8LQNo6wJ2PwYwq7BMrQii19X/85GIyOMB4JYtW9CnTx9VpSvj6GS1D3dq6pK1N3HiRKSnp6ugToI5md5l0aJFtsKQ5ORk9Zyat99+W1UPX3bZZQ6P88QTT+DJJ588oddGRB5Q4DoAlGXgKrxtGThNtLWHIz/F6VDzCAPkO7E0PbOwFC28aQobIvIbTR4ASmAmAZoUech1yf5Jd3BVsl8qe+tCunvddfnKxM/2Dh48WMeWE5FX0rpRqwSAWhdqbLgXLQNXiwxgsF6H+EiDmsJG5gJkAEhEfhEASrdvYmKi7ToRUb1oQVRUlQDQNgm0l2X/REwbIEgPmE0uD0slsASArAQmIr8JAKXAw9V1IqKGHAOoBU9eNQm0Jmkw8Fg6oNO7PCxB665j+ZwLkIj8dyLon3/+2Xb7gQceUFPEyPq8hw4d8mTTiMjnAkBrZa3TKiBemAGUwM9N8Cc4FyAR+XUA+OyzzyI8PFxdlyXb3njjDTU1i8zrd/fdd3uyaUTkK7RJoKtkANPyS7y3C7gGXA2EiPxyGhiNrKTRtWtXdX3BggWqIvemm27CqaeeijPOOMOTTSMiX1kFxF0XcJ4leGoZ46VFFL89ASSvBs56DOh4msMhbeWSNAaAROSPGUCZby8zM1Nd//XXX3H22Wer67Icm6s1gomIHJTkyJQBluuRjstHasFTC2/NAKbtAA6vBrL2Ox1qEWNp87E8SxaTiMivMoAS8N14440YOHAg/v33X4wbN07t3759u5qcmYioWhHNgUfTgOJsp1VAjluDJ6+dRuXkW4EBVwFJzqsQtY4Nd3gNRER+lQF88803ccopp6gJnGVJuPj4eLV//fr1mDRpkiebRkS+QjKAEghWYcsAWrNpXqfLmcBJFwPN2jkdah1rCVpTc0tczpNKROTTGUCp+JXCj6pmzJjhkfYQkX8oKTcit7hcXW/prRnAamhBa1mFCTlF5YiL9MKpbIjIp3k0ABQ5OTlYs2YN0tLSYJIB3XYrgVx77bUebRsRebn1HwF7fgP6XAr0ucS2O92a/ZMVQGLCPf4x51ppPrB/BVCaZ+kKthMarFergWQWlqksIANAImpoHv1k/PHHH3H11VejoKAAMTExKujTMAAkohodXgvs+gloM8DlFDBSAGL/ueJVCtOBeVcDweFA/0mVxSxWUr0sAaCMA+zdJsZjzSQi/+TRMYD33nsvrr/+ehUASiYwOzvbtmVlZXmyaUTkCwZNBsa9CHQd47A7zdungBExSZbLimKgKKvacYBERH6VATx69CjuuOMOREREeLIZROSr2g+3bFV4/RQwIjgUiGppmcg69zAQaSmC07SyBoDHcjklFhH5WQZw7NixWLdunSebQER+qHIKGC8OAEVsW8tl3lGnQ62s2UvOBUhEfpcBPP/883H//fdjx44d6Nu3L0JCQhyOX3TRRR5rGxF5ufJiYPcvQEwboN1whzF0lVPAeHEXsBYAHl0P5B5xOqRlANkFTER+FwBOmzZNXT711FNOx2TgttFo9ECriMgn5BwGvpkKhMYC05N9rwtYxFrnAJQuYDcBICeDJiK/CwDtp30hIqoTrds0prXToTStC9gXMoDCRQaQRSBE5LdjAO2VlPBDjojqIC/FcildwFVoGcCW3roKSC0CwFbW5eDySypQWFrR1C0jIj/n0QBQuniffvppJCUlISoqCvv3WxZFf+yxx/DBBx94smlE5O3yXQeAsnpGVmGZd68DXHUqGBcBYFRosNoEC0GIyK8CwJkzZ+Kjjz7C888/D4Ohcqb7Pn364P333/dk04jIVzKA0Y4BYEaBJfsXog9CXIRjYZnXjgHMPwZUWIJW11PBMAAkIj8KAD/55BO8++67ajUQvV5v29+/f3/s2rXLk00jIm+Xl+oyA6gVTSRGefEqIJrIBEAv3dTmyoymq6lgGAASkT8FgDIRdNeuXV0Wh5SXWxZyJyKqvgjEMQD0mSlghASo1Y4D5FyAROSHAWDv3r3x559/Ou3/5ptvMHDgQI+0iYh8uwjEZ6aA0cR1BGLbA+UlbiuBmQEkIr+aBubxxx/HlClTVCZQsn7fffcddu/erbqGf/rpJ082jYi8WUUpUJThWEjhNAWMjwSA13zrMIm1PW0tY04FQ0R+lQEcP348fvzxRyxZsgSRkZEqINy5c6fad/bZZ3uyaUTkzfKt4/9k/Fx4nMOhtDzrFDDeXgGsqWacoi0DmMf1gInIjzKAYuTIkfjtt9883Qwi8tXu3yoBVFq+j2UAq6FlANkFTER+lQHs3LkzMjMznfbn5OSoY0RE1QeAjt2/4piWAfSFIhBxfAfwwVjgY+e1z9s0s0wGnVFQhpJyLo1JRH4SAB48eNDler+lpaVqXCARkUtlBUBwmMtl4I7lWrpLW1tX0vB6egNweDVwZB1gNjscknkMw0MsU2RxHCAR+XwX8A8//GC7vnjxYsTGxtpuS0C4dOlSdOzY0RNNIyJfMPg6YNAUSzGIHcmSZReVO0yh4vWatQMu+xBo1sHpkMxjmBQXjr1pBTiaXYxOCZEeaSIR+R+PBIATJkywfbhJFbC9kJAQFfy99NJLnmgaEfkKGfsX4hjkaWPlIgx6xIR5fIhz7QSHAn0ucXs4qZk1AMwpatJmEZF/88gnpEz5Ijp16oS1a9ciISHBE80gIj+jdZNK9s/rVwGpJckACskAEhE1FI9+RT5w4IAnn56IfNXHFwKhMcD5LwHRrWy7telStOlTfEbqZuDQSiCxJ9DlTKcMoDiSwwCQiBqOx/tIZLyfbGlpabbMoGbu3LkeaxcReamyQuDAH5brE95ymQH0mQpgza6fgRWzLeMaqwSAbZkBJCJ/CwBnzJiBp556CkOGDEHr1q39psuGiBqRLhi48gsgPwUIqywgsx8D6HMZQK0AJOeQ26lgUqzVzUREPh8AzpkzBx999BGuvfZaTzaDiHyJFE30HFfDGEAfmQJGE2cNALOdA0CtCzg1pwRGkxl6Hb8oE5GPzwNYVlaGESNGeLIJRORHbBlAX+sCjrNOe5V7GDA5zo0q3dnBuiBUmMy2VU6IiHw6ALzxxhvx+eefe7IJRORrpFhi6zdA1v5qq4B9SnRrQBcCmCqAPMdJ8CXjp70ejgMkoobi0S7gkpISvPvuu1iyZAn69eun5gC09/LLL3usbUTkpdZ/DGz5EjjrCWDkPbbdZRUmZBaW+uYYQJ3eMiG0BLXSDdysvVM38JHsYhzNKcYQjzWSiPyJRwPALVu2YMCAAer6tm3bHI6xIISIXMo9YrmMbeewW7pHZSU1g16H5pEG+BwpBJEAUBWCjHSeC/AAVBBIROTzAeCyZcs8+fRE5ItknJyQjJmL8X8+Owl0LQpBJANIROTzYwCJiOpECiTyUizXY9v6x/i/qlPBZB90GwCmMAAkIl/OAF5yift1L+199913jd4WIvIhBccBUzkQpAeiKlcA8ek5AKtWAruYC5DLwRGRXwSAsbGOk7cSEdVp/F9MG0Af7DoD6GtTwNSxC9hsNvtmFzcReRWPBIAffvihJ56WiPxl/F+VAhD7dYB9twvYmgEsOAaUFwMh4Q6rgUjMV1RmRFZhGeKjQj3XTiLyCxwDSEQ+WAHsOP5PHM3x8S7giOZAfDegw2lASZ7DobAQvS2zeSiryEMNJCJ/4tEqYCKiBgsArePjkppFwCdJiu+/69webt88QnVzH84qwqD2cU3aNCLyP8wAEpHvyEl2GQCWlBuRUWCZBLqttWDC30gAKA5lMgNIRPXHAJCIfIc2RYpWMWulTY8SYdCjWYTjikI+qcp6wKJDPANAImo4DACJyDfIMh9ahWyVAFCbIFmqZX26QnbvUuDlk4BPL3Y61D4+Ul1KFzARUX1xDCAR+YaSXEvXr4wDrFIFbBv/5+vdv6HRQJ6MczS77wLOKvRAw4jI3zAAJCLfEN7MUiRhMgE6ndsMoE9r2Qe44TegeRenQx2sAeDxvFI15lEqg4mIThS7gInIt1QJ/vwqA2iIANoNAyLjnQ7J2MboMMt3dnYDE1F9MQAkIp93xF8ygNWQsY0sBCGihsIAkIh8wy8PAe+MAnZ87zYD6BdTwOxfDiyaDmxfUM04QAaARFQ/DACJyDcc2wqkbgIqyhx2VxhNOJZX4tuTQNtLXg2sfgvY+5vTofbNWQlMRA2DRSBE5BsueAXI3Au0Geiw+3h+KYwmM0L0QWgR7Qdr5MZ3tVxm7nM6VNkFzEpgIqofBoBE5BsSu1s2N92/rWPDodP58ByAmuad3QeA7AImogbCLmAi8mlHc4r8qwAk3joFTGEaUJLncKi9NQN4JKtYZT2JiE4UA0Ai8n5pO4G/XrGslFGFBEN+MQWMJiwWiEy0XJcubzttYsMRGqxDmdGEI9nMAhLRiWMASETe79BKYMmTwJr3nA75zSTQ9hJ7Wi4z/nXYLV3cnRIshSD70zkOkIhOHANAIvJ+2QddrgFsPyeeNkWKX0jsYblM3+V0qEuLKHW5L72gqVtFRH6EASAReb/sA24DwGRrQYRWIetXGcD03U6HulgzgPuYASSievCrAPDNN99Ex44dERYWhuHDh2PNmjVuz92+fTsuvfRSdb7MsP/qq682aVuJqA60ilitQMKqtMKIlNxihwIJf88Adk5kBpCI6s9vAsB58+bhnnvuwRNPPIENGzagf//+GDt2LNLS0lyeX1RUhM6dO+O5555Dq1atmry9RFRLJhOQtd9lAHgkuxhmMxBh0CMxyg/mAKyaAZSu73JLgKvpYg0AOQaQiOrDbwLAl19+GdOmTcPUqVPRu3dvzJkzBxEREZg7d67L84cOHYoXXngBV155JUJD/egPB5G/yTsKVJQAuhAgtr3DoWS78X+SyfcbUgUcHgeYTU6VwJ0SLV3AGQWlyC0u91ADicjX+UUAWFZWhvXr12PMmDG2fTqdTt1etWqVR9tGRPWUta9y/J/ece56bUUMvyoAERLMuhkHGBUajFYxYer6fnYDE1EgrwSSkZEBo9GIli1bOuyX27t2OY+hOVGlpaVq0+TlOU7SSkSNQMuAaUuk2TnkjwUgmm7nAHGdgJg2Toc6J0aq9Y+lEGRg+ziPNI+IfJtfBIBNZdasWZgxY4anm0EUWNwUgDh0AcdbukX9ysh73B6SAHDlvkxmAIkosLuAExISoNfrcfz4cYf9crshCzymT5+O3Nxc23b48OEGe2wiqnsAaMsA+lsXcA20QhBWAhNRQAeABoMBgwcPxtKllctEmUwmdfuUU05psOeRYpGYmBiHjYiaqAu4uWMAaDKZ/XMOQHvGCuD4DsBY7jIA3JPGAJCIArwLWKaAmTJlCoYMGYJhw4apef0KCwtVVbCYPHkykpKSVDeuVjiyY8cO2/WjR49i06ZNiIqKQteuzmONiMgDJPDRVgGpMgYwLb8UZRUm6HVBaONPy8BpZH6bV04CCo4B//kLaNXXdqhnq2h1eTCjECXlRoSF6D3YUCLyRX4TAE6cOBHp6el4/PHHcezYMQwYMACLFi2yFYYkJyerymBNSkoKBg4caLv94osvqm3UqFFYvny5R14DEVVRmg90ORPIPQJEt3ZZASxrAIfo/aIzw7kSOKEbUFYI5KU4BICJ0aGIiwhBdlE59qYVoE9SrEebSkS+x28CQHH77berzZWqQZ2sAGKWb9hE5L0imgPXfOvykLYGsN92/4qJnwKhsTKvlcNumfOwR6torN6fhV3H8hkAElGd+eHXZiIKBPsyLOPfOlvXxvVLMhl0leBP07OVZQzy7mOcjoqI6o4BIBF5ryrLoNnbl2bpAu7SwlIQEWgkAygkA0hEVFcMAInIe30yHni+C7BvmdMhbQ68zgl+HADKMJXvbgJeHwzkJLsMAHczACSiE8AAkIi8N/jJ+BcoyrCsjWun3GiyTQHTpYUfdwFLIYhMAyNT4Rzb6nCoe8toWzV0dmGZhxpIRL6KASAReW/wc/d24KYVQEJ3pwKQCpMZEQa9bV1cv6VV/1YJAGVN4HbNLdPfsBuYiOqKASAReS9DJNBmABBscN39mxipKmIDMQAUPVpaCkF2sRCEiOqIASAR+Zx96YUOK2L4tVZ9LJepW5wO9W5t6QbekcIAkIjqhgEgEXmnlW8AP90NHF4TmAUgmtb9pT8cyE0GCtIdDmnz/209muuhxhGRr2IASETeaddPwLq5QPYhp0P7rAGgXxeAaMJiK8dAHl3vcKhf22a2NYGLy4yeaB0R+SgGgETknRXAaTst1xN7VDlktnUBB0QGULQdYrk8us5hd8uYULUsnNFkxo5UdgMTUe0xACQi71OQBpTkAEE6y3q4djIKypBbXK6KhDv58yog9pIGWS6POAaAUgDTT+sGPpLjiZYRkY9iAEhE3idtu+UyrhMQYpnqRKNNfNwxPhLhBj0CQpI1A5iyATCZHA71bWsJALdwHCAR1QEDQCLyPtqUJ9oUKHa0KU96WCdCDggtTwKCw4CSXCBrn8OhftYAcOsRBoBEVHsMAInIpwJALQOoLYUWEPQhQOsBLruBtUrgvekFKCyt8ETriMgHMQAkIi8OAPs5HdJWvegZSAGgSBrsshCkRXQYWseGqboZTgdDRLXFAJCIvEt5sWUNYBcZQKl2/fd4AGYARb/LgUveB0be53RoUPs4dbn+ULYHGkZEvogBIBF5l7QdgNkERCQA0a0cDh3KLERphQlhITp0iA+QCmBNm4GWIDCmtdOhIR0tAeDag1keaBgR+SIGgETknd2/rfvJPCcux/91axENvc7P1wCug6Edm9sygCaT2dPNISIfwACQiHyoAjhAu381WfuBv14B1n/ssFvGQ0YY9MgvqcC/aZafERFRdRgAEpHPFIDstK52EXAFIJqjG4AlTwJr33fYHazX2cYBrj3IcYBEVDMGgETkXQZfBwy8pnL1CzvbrFWufa1TnwScjqcBPS8ABlxtWS7PxTjAdRwHSES1EFybk4iImsyAqyxbFRkFpUjJLVHDAk8K1ABQimKu/KzacYBrDmSp9ZJlmTgiIneYASQin6DNcdc5IRJRofzuWpV0ARuCdUjNLcG+9EJPN4eIvBwDQCLyHgf+AFI2AcZyp0PaUmf92jbzQMO8TE4ysOkLh12yLvJQazfwX3vSPdQwIvIVDACJyHssvB94dxSwd4nToS3WAFBb+ixglRUCrw0CFvwHyHRcF/i0ronq8q+9GR5qHBH5CgaAROQdTEYgJgkIi61c9sxFAUi/tgEeABoigfYnW67v+c3h0MhuCepy1b5MlBtNnmgdEfkIBoBE5B10euDa74AHDwFRLRwOpeWX4FheCWTu596tYzzWRK/R7WzLZZVMqfxs4iMNKCwzYmNyjmfaRkQ+gQEgEXkXF9WrWjDTtUUUIlkAAnS1BoAH/wRKC2y7dbognNrVkgVctjvNU60jIh/AAJCIvEOR+/nrtLnthlinOgl4LXoBcZ2AihJgr2M38Fm9LNnTX7cf81DjiMgXMAAkIs+Tqt9X+gD/NwDIS3U6vO6QZXWLIR0sVa4BT7Kkvcdbrm9f4HDozJ4tEKIPUlPB7E2rzA4SEdljAEhEnpe6GSgvBEpygKiWDodKyo22ApAhHZgBtNECwD2/AmVFtt0xYSEY0cXSDbyYWUAicoMBIBF53sG/LJftR8hANodDmw/noNxoRmJ0KNo1D/dM+7xRm4FAs/ZAeZFTMcjYk1qpS3YDE5E7DACJyPMO/W257Hiq2+5fmeSYy5u56Qbe+rXDobN7t1SHNx/JRXJmZXaQiEjDAJCIPMtYASSvtlzvMMLpsKxtKwaz+9dZv4mWy92/AIWZtt2SLT3V2g08f+NRT7WOiLwYA0Ai8qyj64DSPCCsGdCqn8OhsgqTLQA8pXO8hxroxVr1BVoPAEzlwNavHA5dMihJXX638QjMZrOHGkhE3ooBIBF5ljZ+rctoy2TQdjYkZ6O43IiEKAN6tor2TPu83cBrLJcbPgXsAr1z+7RCpEGPQ5lFWG/tRici0jAAJCLvCAC11S3s/LXHsqatTG4skxyTC30vA/pdCZw7y2F3hCEY5/Vtra7PW3vYQ40jIm/FAJCIPKcgHUjZWJkBrOKvvZUBILkRHgdc8g7QeZTTKiqThrVTl99vTkFmQamHGkhE3ogBIBF5zr7fK8eyRVumLtHkFpdjyxHLEnAjuzEAPBGD2sehX9tYNZbyizXJnm4OEXkRBoBE5Dm7f7ZcdjvH6dDy3WkwmS3r/7aO5fx/NcpJBhY+ACx9yrZLps2ZempHdf3T1YdUIEhEJBgAEpFnyOoVe6zr2Pa60OnwrzuOq8tzejuuDEJuZOwB1rwDrHrTYUqY8/u2QYvoUBzPK8U36494tIlE5D0YABKRZ2QfBCITLatZyFQmdkorjFixO11dP8e6qgXVQMZQDr0RuPprILJyyhxDsA63nNFFXX/99z1qaT0iIgaAROQZLXsDd24GbvjNqXhh1b5MFJRWoGVMKPolxXqsiT5FfobnvwR0Ot3p0KRh7dE6NgypuSX4kmMBiYgBIBF5PGipUvwhFm2zrGE7pldLTv9yovJSbfMChoXocduZXdX1V5fuQVZhmYcbR0SexgCQiJpezmGgvMTlIemi/Hlrqrp+fj/LPHZURyvfAF4bAGz/zrbryqHt1GTaOUXleH7RLo82j4g8jwEgETW9728FXuoB/Pur06Hfd6Uhv6QCbWLDcHInLv92QsoKgIoS4JeHgII0tStYr8MzE/qo61+uPYzV+ysLRYgo8DAAJKKmVVYIZB0ESnKBFj2dDn+34ai6HD8wid2/J+q0u4HEXkBhGjD/ZsBkmf5lSMfmKhMo7p63CblF5R5uKBF5CgNAImpahkjgzk3AtKWWCmA7aXklav4/ccnAJA810A8EhwKXfwgEh1sm2/7zRduhxy7ojU4Jkaog5L5vNsMkky0SUcBhAEhETU+nB5IGO+3+7J9kVJjMGNwhDt1aRnukaX6jRS9g3POW68tmApu/VFcjQ4Px2pUDYdDr8NuO45jN8YBEAYkBIBE1nYy9QIXrNWlllQoJAMV1IyyrV1A9DZoMjPiv5fr3twG7LCuv9G0bi+cv66euv/PHfrz/535PtpKIPIABIBE1DZMR+GIi8Gpf4Mh6p8M/bUlBRkGpmvvv3D6c/LnBjHkK6HMZYKoA5l0LbJ6ndk8YmIT7zumurj/z80688fsemK3TxhCR/2MASERNY8s8IHMvYCwDEi2Bh6bCaMIbv+9V1yef0hEhen40NRidDrj4HaD/JMBsBObfBPz2BGCsUHMD3nO25b148dd/cf83W7hSCFGA4KcsETU+6fZdNquyQjXUcXzfD5tTsD+jEHERIZjC7t+Gpw8Gxr9V2R3896vAxxciKHMf7jirGx6/oDek4FrWCr7krZXYnpLr6RYTUSNjAEhEjW/Nu0BuMhDVChg6zeGQZJxeXbJHXZ92emdEhQZ7qJF+TjKB5zwDXP4RYIgCklcC+Snq0PWndcL/bhiO5pEG7EjNw0Vv/I1Zv+zkNDFEfowBIBE1/qofy561XB/9KGCIcDj87h/7kZxVpMb+TTmF2b9Gd9LFwC1/A+fOdlg3eAQ2Y/FNvXFen1Ywmsx4Z8V+jHz+d7y2dA8yC1wX7hCR7woyc9TvCcvLy0NsbCxyc3MRExPj6eYQeR/5ePl8IrBnMdB+BHDdz5ZMlNWhzEKc88ofKK0w4fVJA3Fh/zYebW7Ayj0KvDZQ3jDgjk1YmhKM5xftxu7j+eqwTBkzrm8rXDKoLU7pEs8xmuTz8vj3G+xrIaLG888cS/CnNwAXvOwQ/JUbTbjjy00q+Du1azwu4Lq/npOXYpk3UN6n2CScFQuc2aMFdnw3C78dqsBX6R2xYJMJCzalIDY8BGf3bomR3RJwSud4tIgJ83TriegEMANYD/wGQVSNw2uAD8cBpnLgvBeA4Tc5HJ61cKeagy4mLBi/3HU6kpqFe6ypZCXL84XFVl5/oaulahtApiEJ/5R3wfqy9thm6oQd5g7IRwQ6J0ZicPs49EmKVVvv1jEIN+g9+zqIapDHv9/MABJRI8jYA3x+hSX463kBMMyx8OPLNckq+BPPXdqPwZ+30II/rXL75FuAA38CqZsQX3YU43AU40IqTzlqTsD+nFY4kN0a+ze1xu/m1lhn7oEW8fHonBCplpzrnBilLjsmRKBFdBj0XN+ZyCswA1gP/AZB5ELaTuDTi4H8VKDNIOC6nyzr/1p9v+ko7vlqsyo0kClItHnoyIuV5AHJq1UgiNTNQOoWS1W3C2eWvoQDZkt3/pX633GmbhN+Mp6MH00jEKwLQttoPYZGpSOsWUvExLdGq7go1Y2cEGVAQlQo4qNCEWnQIyiIgSI1njz+/WYGkIga2L5lluAvsSdw1Ve24E++a879+yCe+XmHqg25Ykhb3D2mm6dbS7URFgN0P8eyaYqygIx/LZN7a1vGXsy78hLszTZhX0Yh+qz9HAMz1+FwWDcsLAxS6zwb8g7ghdIHgUz5vwJkm6OQaY5BBmKxzRyNXHMkCnVRMBpiYQ6LhS68GXQRcciKH4zIqGg1BlGGDcRGGNR1+y2YxSlEtcYMYD3wGwSRlXyMaBkbub72faDPpUBEc7Urq7AMjy3Yhp+3pqrbk0/pgCcvPAk6dgf6t8NrLVnDtkNgbDUAafklyNmzCp1+mwZDaRZ0MNX6oU4t+T8cRaK6/lDwF7havwTvVFyAN4wXq32JyMYLoR+gTB+Bcn0EKmQLiYQpOBJm+RISGoWg0GjoQ6MQHBoOQ1gkQsKjoItrj/DwCEQY9AgL1iEsJBhhBrnUIzxEz4pnP5XHv9/MABJRPUiwt30+8Pf/Add8C0QmWAJB65g/meT5q3WH8fJv/yKnqFx1AT48rhemntqRXXyBoN1QyyaLkQBoHRuO1kNGA0P2WdaGLs4GCtMtW0EaUJSJsoIslOZnoqwwG8bCbKAkB7rSXFw8uA/SSw3ILS5H99RyRBcVIzY8GNHlwcgvrUDzoHycEbQBKqaUTeawLqm5iWeXPo895rbq+p36b3Fr8Pf41Hg2nqm4Vu2L0xXi05BZKAsKRbnOslXowmDSGWDWV25BUkEdHAroZQvB/sQxKItsBUOwDs1LjyKheD/KIpNQHN9bTatj0AehWeE+6EMMCDaEITgkVF2GhIQhJFQuDTCE6BEarFNBKMdOUkPzqwDwzTffxAsvvIBjx46hf//+eP311zFs2DC353/99dd47LHHcPDgQXTr1g2zZ8/GuHHjmrTNRD5NgjhZ5UOyPH+9AoydqXYfyCjED5tS8OnqQ8iwTiLcs1W0KvgY0K6ZhxtNXkGnt3xhkA29bLsN1q2q++xvFL+jgsVpoTGYFpWo1pIuyE5Dxo5glBXlo6I4H6bSfJhLCwDZyguhKy+AvrwIwcYi6I0lCDGVIthUio6t4mGsiERJmRHNSisQigqH5w0zlaBPkKVgyRZc1sKle2Kx3txDXb9e/wseD/kU3xtH4M7y29W+YFRgb9hkt/c3mYNQjmCUIRhF0Kvrss0w34R/dANUUDgiaAuuN36DXcHd8X7YVATrdAjWB+H2orcQAiNMuhC1GYNCYNKHwBxksFzqrJsKXkMAnQHHo09CfkQ7hOiDEGkqQELJIRgN0ciP7qKCT9kiyrOgk/dNb4Au2ICgYIO6LV/sJJuvDwqCXm+91FVuOuttdV6VY/b3kVmi5DXYX7ftYwDc4PwmAJw3bx7uuecezJkzB8OHD8err76KsWPHYvfu3WjRooXT+StXrsSkSZMwa9YsXHDBBfj8888xYcIEbNiwAX369PHIayDySiYTkHfUMvg/eRVw6G/gik+BZu0sh0+7DwX7VmJ1i6uw6sftWLUvE7uOWSYQFm1iw/CfM7rgqmHtOUaLGkZ4M8tmJf+vmiW0Ak53rDavjffsb5QOA4pn4oaQcFxjiENpuQklxfk4vj8GFWVFqCgtRkVpEUxlRTCVl8BUXgpTRRnMFXJZqiqng4zlCDKVYWSr3uimb4OyChPaZbfH/uxeMId1xoioeDUHJsqLkJ3VDCHmcoTAsulkIm4rXZAZoShXm72K8nLkmSxBaqj+OAaG7EBuSQj25Rfazjk9dCkig+q2essD5dPwlfFMdX2UbjM+NszGVlNHXFhmXcUHwArDXeigS3O4X7lZC071Klgtk1ditgSrss01notvjKPUua2QiVuCf8BxcxzeMk6wPcagoH9VwFqAcOQhHAXmcDXFUIU1RLnzrG64m8ViDc5vxgBK0Dd06FC88cYb6rbJZEK7du3w3//+Fw899JDT+RMnTkRhYSF++ukn276TTz4ZAwYMUEFkbXAMAfkc+XWXrje93Xc/CeykyrOsAOaCNFTkHYcx7xjMBccRlH0IITl7oa8odniYxW1ux/eRl+BQZhH2pxeiuNzocFy+rZ/aNQGXDEzC+f1acxwVUW0YKyzzLhpLYa4oQ3lZKcrLS1FRVgpjWQkqKkpRGt0JZYYYVBjNCMo9BMPxzSg1xCGnxXBVZCPBZZsdc4GKEvVYZmOZCkrlMWENTlWQaiyDTq6bZF85VrW+Fnuih6tsavvcdZhweDZSQzvhvbYzVcW+yWzGUwcmIaHieJ1e0luGqfgyeLx6jF4Vu/B+xXQcQQtcoHsTRqMZRrMZ84Kmo6+WZbVTZA7FyxWXIfrMu3FnAxeM5fHvt39kAMvKyrB+/XpMnz7dtk+n02HMmDFYtWqVy/vIfskY2pOM4YIFC9w+T2lpqdrs/wM1hkXbUpG8+jsMyvu9cqeLOD3I7tuiKNDH4usWd9huX5jxPhLKU/Bb3JU4HGb59tS1aBNG5bh7jS6+C5gBY1Aw5rZ61LZrbNZnaF/6L1bEjMfuiEFqX7vS3RiX/T+XD2ffzqrP8G6Lx1AeZOnwOSv3O/Qs2YhVUedgQ+Rpal+L8iOYmDnH4b5VX7erds+Nvxd5eksBwsj8XzC46E+sjxiJP6LPU/tijNm4MeN5h/u4fVy73Z/G3YrUkPbq+rCiFTizYCG2hQ3GzzFXqLcoxFyGezMec9su9Twu3ssvY6Zir8HSDdavZB0uKpiHvYae+CLmets50zMeVlkCy2OYoIcROhih166bjdZ9Jtv19yJuwvKQ02A0mTC4bC2eLp6JHUHdcVPIs+qDVz6UFxmnoQWyrT8DQKZ5s5vqTSkz67Hf3AbrTd2xxtQDK/f3RjqO2Y5Lt1GXxCgM7dgcQzs1x2ldE9A80lVHHhG5JV/M1JezCPW76K473KZVH6CHix6rHs5Jj5p0cLglj3kd4gH8n8P+fy1fIFVAWVZls9tXUbn/1vguuDXOusZ3dhdgYzbaGiKx6TS7ivJ5nwFpekB12+cjqNySzYwIKsV9550EDO9c59dDARIAZmRkwGg0omXLlg775fauXbtc3kfGCbo6X/a7I93FM2bMQGOT7rOiA1sxJGRJne53xJyAn45dbrt9o2EVBuj2443MIVhmilb7LtXtxiDDijo9brHZgF8yKn8ul4esxyD9JnyR0wuLjJa1W8/Q7cdAw9+oq+W7UlEMy1JSY4O3YmDwSizK7YAlRkvA2i/oMJ4NXV3nx12/LxVHzJas1PDgf9E/eC1WF7TA8pQhal8S0vFa2Lo6P+7uQynYbI5Q13vp96NPyEbsLorCn8cz1L4wlKJP2MY6P+6RlKNYZbIMVWijO4yTDFuQVhyE1RlZtnO6hW5XH4h1kZGdhZ1GyxeVNrpSBBtMCDYW41hx5ej4A4aWqtulEGHIMMci3RyrpuTIDopDZnALHAtpj+zQNggLDVXztMk2MVouDUiKi0DXFlFoFxfO7l2iQCBjAGULOYElAOM6AKMfcd4/8VPb1SAtE1qap1ajCZPJyUO4skxj8Isu4JSUFCQlJalxfaeccopt/wMPPIAVK1bgn3/+cbqPwWDAxx9/rMYBat566y0V4B0/frzWGUDpZm7oFPKG5Gwc3vY3WuZUDSRcDIK1q6SUqQ/2Jk2wndXx2GKElWXhSOLpKAhPUlWXMYUH0Dqz8ufhXIjp/BzmIB32tL/CdrtN+p+ILE5FWvOhyIvqpPZFFKciKf0vF3evssPuCeXa/rbj1WBkkZi5FjFFyciK7YOcGMvg6dDSLCSluwpYqz5RkMOuI63PRkVwpNoVl7MNMfn7kBfdBdnNLN+WZSB4UqpjgB1UQ3vF8RanoTwsTl2PztuL2NxdKIpMQnZzSyY0yFSBNimLXdzV8XHMVW5nJQxBabglAAwvPIq47C0oDUtAVoKlglK0Ovpr5bQZQUEwBQXDHKSHWSeX9tf1CNLLFoKKyDYwh8epwdcy4D2sIhcIjYYuLMY2KNtyqVMDseW2LOMVEaJnQEdEfiuPXcD+kQFMSEiAXq93CtzkdqtWrVzeR/bX5XwRGhqqtsY2qH0cBrW/AIBsdTPS4dZ/XJwhqXjLQN+6OLmazoLKfY5n1YZjjbalaxVO+wbU83EtxQrOLEHmiZOpI85w3j3Ycc3bupOsamXgZ9P/OtRfUgM8BhER+Tq/+Iov2bzBgwdj6dKltn1SBCK37TOC9mS//fnit99+c3s+ERERkb/wiwygkIKOKVOmYMiQIWruP5kGRqp8p06dqo5PnjxZdRPLOD5x5513YtSoUXjppZdw/vnn48svv8S6devw7rvveviVEBERETUuvwkAZVqX9PR0PP7446qQQ6ZzWbRoka3QIzk5WVUGa0aMGKHm/nv00Ufx8MMPq4mgpQKYcwASERGRv/OLIhBP4SBSIiIi35PHv9/+MQaQiIiIiGqPASARERFRgGEASERERBRgGAASERERBRgGgEREREQBhgEgERERUYBhAEhEREQUYBgAEhEREQUYBoBEREREAcZvloLzBG0RFZlRnIiIiHxDnvXvdiAvhsYAsB7y8/PVZbt27TzdFCIiIjqBv+OxsbEIRFwLuB5MJhNSUlIQHR2NoKCgBv92IoHl4cOH/XKdQr4+3+fvr5Gvz/f5+2vk6ztxZrNZBX9t2rSBTheYo+GYAawH+U/Ttm3bRn0O+U/vj7/YGr4+3+fvr5Gvz/f5+2vk6zsxsQGa+dMEZthLREREFMAYABIREREFGAaAXio0NBRPPPGEuvRHfH2+z99fI1+f7/P318jXR/XBIhAiIiKiAMMMIBEREVGAYQBIREREFGAYABIREREFGAaARERERAGGAaCHzJw5EyNGjEBERASaNWvm8pzk5GScf/756pwWLVrg/vvvR0VFRbWPm5WVhauvvlpNmimPe8MNN6CgoACetnz5crVaiqtt7dq1bu93xhlnOJ3/n//8B96oY8eOTm197rnnqr1PSUkJbrvtNsTHxyMqKgqXXnopjh8/Dm9z8OBB9X+pU6dOCA8PR5cuXVR1XllZWbX38/b3780331TvW1hYGIYPH441a9ZUe/7XX3+Nnj17qvP79u2LhQsXwhvNmjULQ4cOVasUyWfHhAkTsHv37mrv89FHHzm9V/I6vdWTTz7p1F55b/zh/XP3eSKbfF746vv3xx9/4MILL1Srb0j7FixY4HBcalIff/xxtG7dWn3OjBkzBnv27Gnw32OyYADoIfKH8/LLL8ctt9zi8rjRaFTBn5y3cuVKfPzxx+oXXH45qiPB3/bt2/Hbb7/hp59+Ur9wN910EzxNgt3U1FSH7cYbb1QBxZAhQ6q977Rp0xzu9/zzz8NbPfXUUw5t/e9//1vt+XfffTd+/PFH9YdpxYoVamnBSy65BN5m165daunDd955R/3/euWVVzBnzhw8/PDDNd7XW9+/efPm4Z577lGB7IYNG9C/f3+MHTsWaWlpLs+X38NJkyapQHjjxo0qqJJt27Zt8Dbyf0kChdWrV6vPgvLycpxzzjkoLCys9n7yxdH+vTp06BC82UknneTQ3r/++svtub70/gn5Ymz/2uR9FPJ3w1ffP/n/J79nErC5Ip8Nr732mvps+eeffxAZGal+J+WLckP9HpMdmQaGPOfDDz80x8bGOu1fuHChWafTmY8dO2bb9/bbb5tjYmLMpaWlLh9rx44dMqWPee3atbZ9v/zyizkoKMh89OhRszcpKyszJyYmmp966qlqzxs1apT5zjvvNPuCDh06mF955ZVan5+Tk2MOCQkxf/3117Z9O3fuVO/hqlWrzN7u+eefN3fq1Mln379hw4aZb7vtNttto9FobtOmjXnWrFkuz7/iiivM559/vsO+4cOHm2+++Wazt0tLS1P/r1asWFHnzyJv9cQTT5j79+9f6/N9+f0T8nvUpUsXs8lk8ov3T/4/zp8/33ZbXlerVq3ML7zwgsNnZGhoqPmLL75osN9jqsQMoJdatWqV6qJo2bKlbZ98q5HFsSUD4+4+0u1rn1GTFLqsWSzfprzJDz/8gMzMTEydOrXGcz/77DMkJCSgT58+mD59OoqKiuCtpMtXunMHDhyIF154odou+/Xr16vMjLxHGumeat++vXovvV1ubi6aN2/uk++fZNbl52//s5ffE7nt7mcv++3P134nfeW9EjW9XzJcpEOHDmjXrh3Gjx/v9rPGW0j3oHQndu7cWfV+yLAZd3z5/ZP/r//73/9w/fXXq65Tf3n/7B04cADHjh1zeI9krV7p0nX3Hp3I7zFVCra7Tl5EfhHsgz+h3ZZj7u4j433sBQcHqw99d/fxlA8++EB9+LZt27ba86666ir1gSYf8lu2bMGDDz6oxjJ999138DZ33HEHBg0apH7e0t0kwY50w7z88ssuz5f3xGAwOI0BlffZ296vqvbu3YvXX38dL774ok++fxkZGWqYhavfMenursvvpLe/V9J1f9ddd+HUU09VQbg7PXr0wNy5c9GvXz8VMMp7K0M3JIio6ffUEyQwkGEx0m75PZsxYwZGjhypunRl7KO/vH9Cxsrl5OTguuuu85v3ryrtfajLe3Qiv8dUiQFgA3rooYcwe/bsas/ZuXNnjQOV/f01HzlyBIsXL8ZXX31V4+Pbj1+UjKgMDj7rrLOwb98+VYjgTa9PxqFo5ENYgrubb75ZDcj31qWMTuT9O3r0KM4991w1FknG93nz+0dQYwElKKpufJw45ZRT1KaR4KFXr15q3OfTTz8Nb3Peeec5/L5JQChfNuRzRcb5+RP5wiyvV75I+cv7R57HALAB3XvvvdV+QxPSVVEbrVq1cqpk0qpD5Zi7+1Qd+CpdkFIZ7O4+nnjNH374oeomveiii+r8fPIhr2WgmiKAqM97Km2Vn79U0Mq386rkPZEuDPlmb58FlPe5sd6v+r4+KVI588wz1R+Xd9991+vfP3ekS1qv1ztVXFf3s5f9dTnfG9x+++22YrC6ZoFCQkLUUAZ5r3yB/A51797dbXt98f0TUsixZMmSOmfNfe39094HeU/ki6JGbg8YMKDBfo+pEgPABpSYmKi2hiDf5GSqGAnotG5dqQKTKq/evXu7vY8EEzImYvDgwWrf77//rrqAtD+8nn7NMvZXAsDJkyerD6i62rRpk7q0/4Dw1vdU2irjUap2y2vkPZKfwdKlS9X0L0K6R2Uck/03eW95fZL5k+BP2i3vobw2b3//3JHsrLwO+dlLJaiQ3xO5LUGTK/KeyHHpTtXI72RTvVd1Ib9nUoE+f/58NQWTVNvXlXStbd26FePGjYMvkPFvklm+9tprff79sye/a/IZIrNC+PP7J/9HJWiT90gL+GTMu4xfdzdbxon8HpMdu4IQakKHDh0yb9y40TxjxgxzVFSUui5bfn6+Ol5RUWHu06eP+ZxzzjFv2rTJvGjRIlU1O336dNtj/PPPP+YePXqYjxw5Ytt37rnnmgcOHKiO/fXXX+Zu3bqZJ02aZPYWS5YsUdVfUu1albwOeT3SdrF3715VJbxu3TrzgQMHzN9//725c+fO5tNPP93sbVauXKkqgOW92rdvn/l///ufer8mT57s9vWJ//znP+b27dubf//9d/U6TznlFLV5G2l7165dzWeddZa6npqaatt89f378ssvVYXhRx99pCrob7rpJnOzZs1slffXXnut+aGHHrKd//fff5uDg4PNL774ovr/K1WoUsW9detWs7e55ZZbVEXo8uXLHd6roqIi2zlVX598Fi1evFj9/12/fr35yiuvNIeFhZm3b99u9kb33nuven3yf0vemzFjxpgTEhJUxbOvv3/2Fa3y+fDggw86HfPF90/+vml/6+TvwMsvv6yuy99D8dxzz6nfQfms2LJli3n8+PFqpoHi4mLbY4wePdr8+uuv1/r3mNxjAOghU6ZMUb8AVbdly5bZzjl48KD5vPPOM4eHh6sPNvnAKy8vtx2Xc+U+8gGoyczMVAGfBJUyZczUqVNtQaU3kLaNGDHC5TF5HfY/g+TkZBUsNG/eXP2CSwBy//33m3Nzc83eRj5wZUoJ+aMrH7q9evUyP/vss+aSkhK3r0/IB9utt95qjouLM0dERJgvvvhih6DKW8gUE67+v9p/h/TF90/+kMgfWIPBoKaTWL16tcMUNvJ7au+rr74yd+/eXZ1/0kknmX/++WezN3L3Xsn76O713XXXXbafRcuWLc3jxo0zb9iwweytJk6caG7durVqb1JSkrotXzr84f3TSEAn79vu3budjvni+6f9zaq6aa9DpoJ57LHHVPvlM0O+cFZ97TLdlgTvtf09JveC5B/7jCARERER+TfOA0hEREQUYBgAEhEREQUYBoBEREREAYYBIBEREVGAYQBIREREFGAYABIREREFGAaARERERAGGASAR0QnIzMxUS3TJWs/e4Morr8RLL73k6WYQkY9gAEhEjeq6665DUFCQ03buuefCl8la3ePHj0fHjh0b7TlkXW/5Wa1evdrl8bPOOguXXHKJuv7oo4+qNuXm5jZae4jIfzAAJKJGJ8Feamqqw/bFF1806nOWlZU12mMXFRXhgw8+wA033IDGJAvd9+/fH3PnznU6JpnHZcuW2drQp08fdOnSBf/73/8atU1E5B8YABJRowsNDUWrVq0ctri4ONtxyXK9//77uPjiixEREYFu3brhhx9+cHiMbdu24bzzzkNUVBRatmyJa6+9FhkZGbbjZ5xxBm6//XbcddddSEhIwNixY9V+eRx5vLCwMJx55pn4+OOP1fPl5OSgsLAQMTEx+Oabbxyea8GCBYiMjER+fr7L17Nw4UL1mk4++WTbvuXLl6vHXbx4MQYOHIjw8HCMHj0aaWlp+OWXX9CrVy/1XFdddZUKIDUmkwmzZs1Cp06d1H0k4LNvjwR48+bNc7iP+Oijj9C6dWuHTOqFF16IL7/8sk7vDREFJgaAROQVZsyYgSuuuAJbtmzBuHHjcPXVVyMrK0sdk2BNgikJrNatW4dFixbh+PHj6nx7EtwZDAb8/fffmDNnDg4cOIDLLrsMEyZMwObNm3HzzTfjkUcesZ0vQZ6Mnfvwww8dHkduy/2io6NdtvXPP/9U2TlXnnzySbzxxhtYuXIlDh8+rNr46quv4vPPP8fPP/+MX3/9Fa+//rrtfAn+PvnkE9Xe7du34+6778Y111yDFStWqOPycygtLXUICmUJd3mt0r2u1+tt+4cNG4Y1a9ao84mIqmUmImpEU6ZMMev1enNkZKTDNnPmTNs58lH06KOP2m4XFBSofb/88ou6/fTTT5vPOecch8c9fPiwOmf37t3q9qhRo8wDBw50OOfBBx809+nTx2HfI488ou6XnZ2tbv/zzz+qfSkpKer28ePHzcHBwebly5e7fU3jx483X3/99Q77li1bph53yZIltn2zZs1S+/bt22fbd/PNN5vHjh2rrpeUlJgjIiLMK1eudHisG264wTxp0iTb7SuvvFK9Ps3SpUvV4+7Zs8fhfps3b1b7Dx486LbtREQiuPrwkIio/qTr9e2333bY17x5c4fb/fr1c8jMSXepdJ8Kyd7JeDfp/q1q37596N69u7peNSu3e/duDB061GGfZMmq3j7ppJNURu2hhx5SY+g6dOiA008/3e3rKS4uVl3Krti/Dumqli7tzp07O+yTLJ3Yu3ev6to9++yzncYvSrZTc/3116subXmtMs5PxgSOGjUKXbt2dbifdCGLqt3FRERVMQAkokYnAV3VYKWqkJAQh9synk7Gx4mCggI1vm327NlO95NxcPbPcyJuvPFGvPnmmyoAlO7fqVOnqud3R8YYZmdn1/g65DFqel1CuoaTkpIczpMxhvbVvu3bt1fj/u6//3589913eOedd5yeW+syT0xMrOUrJ6JAxQCQiLzeoEGD8O2336opV4KDa/+x1aNHD1WwYW/t2rVO58mYuwceeACvvfYaduzYgSlTplT7uJKda4hq2969e6tALzk5WWX03NHpdCoolcpjCRRlnKOMUaxKCmXatm2rAlQiouqwCISIGp0UJRw7dsxhs6/grcltt92msluTJk1SAZx0hUq1rQRFRqPR7f2k6GPXrl148MEH8e+//+Krr75SWTRhn+GTimSZT0+ya+ecc44Koqoj3bFSsOEuC1hbUmRy3333qcIP6YKW17VhwwZVJCK37clrPXr0KB5++GH1c9C6e6sWp0j7iYhqwgCQiBqdVO1KV639dtppp9X6/m3atFGVvRLsSYDTt29fNd1Ls2bNVHbMHZlaRapnpctUxubJOEStCti+i1WbbkXG3sl4u5rI80tWUgLK+nr66afx2GOPqWpgmSpGpnWRLmFpuz3pAh4zZowKOl21saSkRE1fM23atHq3iYj8X5BUgni6EURETUVWy5ApV2SKFnuffvqpysSlpKSoLtaaSJAmGUPpdq0uCG0qEtzOnz9fTTNDRFQTjgEkIr/21ltvqUrg+Ph4lUV84YUX1ITRGqmYlZVJnnvuOdVlXJvgT5x//vnYs2eP6pZt164dPE2KTeznFyQiqg4zgETk1ySrJytpyBhC6UaVFUSmT59uKyaRiZslKyjTvnz//fcup5ohIvI3DACJiIiIAoznB64QERERUZNiAEhEREQUYBgAEhEREQUYBoBEREREAYYBIBEREVGAYQBIREREFGAYABIREREFGAaARERERAGGASARERERAsv/A89aQ46q8Z7gAAAAAElFTkSuQmCC", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "\n", - "\n", - "from scipy.signal import fftconvolve\n", - "\n", - "\n", - "# Example of DetailedBalance, up to 100 mueV. Res and peak is 5 mueV\n", - "\n", - "x = np.linspace(-10, 10, 20000)\n", - "\n", - "Gwidth=0.75\n", - "Lwidth=0.1\n", - "Lorentzian=Lorentzian(center=0, width=Lwidth, area=1)\n", - "Gaussian= Gaussian(center=0,width=Gwidth,area=1)\n", - "Voigt=Voigt(center=0, Gwidth=Gwidth, Lwidth=Lwidth, area=1)\n", - "\n", - "plt.figure()\n", - "DetailedBalanceT1=detailed_balance_factor(x,temperature=10.0)\n", - "# DetailedBalanceT1=1\n", - "\n", - "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT1, label='first convolve, then DBF')\n", - "\n", - "\n", - "# Evaluate both models at the same points\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT1\n", - "model2 = Gaussian.evaluate(x)\n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "# plt.plot(x,model1, label='Lorentzian * DBF', linestyle='--')\n", - "# plt.plot(x, model2, label='Gaussian', linestyle='--')\n", - "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", - "\n", - "\n", - "\n", - "plt.legend()\n", - "plt.xlabel('Energy (meV)')\n", - "plt.ylabel('Intensity (arb. units)')\n", - "# plt.title('Width of 5 mueV')\n", - "plt.show()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "9caea085", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "7f5b808311f041c8bce2180693810b07", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "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OIoAaBPrjbNbt2565JFHTvn9wsJCE/6s2/3888/66KOPzBPcenKciRX+Vq5cqRkzZmj69OnmCffQQw/JblbY3bVr10mXBx54wASK5s2bn/FnH3zwwZN+7uWXX5anGjJkyEm19unT54y379evn7744gvzxjRnzhxzasEuXbrI06xZs8ac+vC9994zj6+RI0fq3Xff1TPPPHPWn/XU4zd+/Hj179/fBNnFixerUaNGuv7667Vnz55T3t56Hvbo0cME4SVLlphQZV1WrFghT2M9lqygsGDBAvNakJ+fr7Zt2yorK+uMP2d9cDzxWG3dulWerEGDBifVO2/evNPe1puOn8X6YHzifbOOo8V63/DW42c9/qznmRXYTsV6bXjzzTfNa8svv/yiiIgI85y0PigX1fMYJ7C2gYF9PvjgA3dMTMyfrv/qq6/c/v7+7rS0tOPXjR492h0dHe3Ozc095e9atWqVtaWP+7fffjt+3ddff+328/Nz79y50+1J8vLy3PHx8e4hQ4ac8XZXXnml+/HHH3d7gypVqrhHjhx5zrc/dOiQOygoyD1x4sTj161evdocw/nz57s93csvv+yuVq2a1x6/Sy65xN2rV6/j7cLCQnfFihXdw4YNO+Xtb731VnfHjh1Puu7SSy919+zZ0+3p9uzZYx5Xc+bMOe/XIk/13HPPuRs1anTOt/fm42exnkc1atRwu1wunzh+1uNx8uTJx9vW/Spfvrz7lVdeOek1MiQkxD127Ngiex7jd/QAeqj58+ebIYpy5codv876VGOdHNvqgTndz1jDvif2qFld6NY5i61PU55k2rRp2r9/v+67776z3vbTTz9VmTJllJSUpEGDBik7O1ueyhrytYZzmzRpoldeeeWMQ/aLFi0yPTPWMTrGGp6qXLmyOZaeLj09XXFxcV55/Kyedevvf+Lf3nqeWO3T/e2t60+8/bHnpLccK8vZjpc1XaRKlSpKTExUp06dTvta4yms4UFrOLF69epm9MOaNnM63nz8rMfrJ598or/+9a9m6NRXjt+JNm/erLS0tJOOkXWuXmtI93TH6EKex/hd4An/hgexnggnhj/Lsbb1vdP9jDXf50SBgYHmRf90P2OXf//73+bFNyEh4Yy3u/32280LmvUiv2zZMg0cONDMZfr888/laR577DE1bdrU/L2t4SYr7FjDMK+99topb28dk+Dg4D/NAbWOs6cdrz/asGGDRo0apREjRnjl8du3b5+ZZnGq55g13H0+z0lPP1bW0H3fvn112WWXmRB+OnXq1NF//vMfJScnm8BoHVtr6oYVIs72PLWDFQysaTFW3dbzbPDgwbriiivMkK4199FXjp/Fmit36NAh3XvvvT5z/P7o2HE4n2N0Ic9j/I4AWISefvppvfTSS2e8zerVq886UdnX7/OOHTv07bffasKECWf9/SfOX7R6RK3Jwddcc402btxoFiJ40v2z5qEcY70IW+GuZ8+eZkK+p57K6EKO386dO9WuXTszF8ma3+fJxw8ycwGtUHSm+XGWli1bmssxVnioV6+emfc5dOhQeZr27duf9HyzAqH1YcN6XbHm+fkS6wOzdX+tD1K+cvxgPwJgEXriiSfO+AnNYg1VnIvy5cv/aSXTsdWh1vdO9zN/nPhqDUFaK4NP9zN23OcPPvjADJPedNNN5/3/s17kj/VAlUSAuJhjatVq/f2tFbTWp/M/so6JNYRhfbI/sRfQOs7Fdbwu9v5Zi1Suuuoq8+byz3/+0+OP3+lYQ9IBAQF/WnF9pr+9df353N4T9O7d+/hisPPtBQoKCjJTGaxj5Q2s51Dt2rVPW683Hj+LtZBj5syZ591r7m3H79hxsI6J9UHxGKvduHHjInse43cEwCIUHx9vLkXB+iRnbRVjBbpjw7rWKjBrlVf9+vVP+zNWmLDmRDRr1sxcN2vWLDMEdOyN1+77bM39tQLg3XffbV6gzldKSor5euILhKceU6tWaz7KH4flj7GOkfU3+P777832LxZreNSax3TiJ3lPuX9Wz58V/qy6rWNo3TdPP36nY/XOWvfD+ttbK0Et1vPEaluh6VSsY2J93xpOPcZ6TpbUsTof1vPMWoE+efJkswWTtdr+fFlDa8uXL1eHDh3kDaz5b1bP8l133eX1x+9E1nPNeg2xdoXw5eNnPUat0GYdo2OBz5rzbs1fP91uGRfyPMYJTlgQghK0detW95IlS9yDBw92R0ZGmn9bl8zMTPP9goICd1JSkrtt27bulJQU9zfffGNWzQ4aNOj47/jll1/cderUce/YseP4de3atXM3adLEfG/evHnuWrVquXv06OH2FDNnzjSrv6zVrn9k3Q/r/li1WzZs2GBWCS9cuNC9efNm99SpU93Vq1d3t27d2u1pfv75Z7MC2DpWGzdudH/yySfmeN19992nvX+Whx9+2F25cmX3rFmzzP1s2bKluXgaq/aaNWu6r7nmGvPvXbt2Hb946/EbN26cWWH44YcfmhX0Dz30kDs2Nvb4yvu77rrL/fTTTx+//U8//eQODAx0jxgxwjx+rVWo1iru5cuXuz3NI488YlaEzp49+6RjlZ2dffw2f7x/1mvRt99+ax6/ixYtct92223u0NBQ98qVK92e6IknnjD3z3psWcfm2muvdZcpU8asePb243fiilbr9WHgwIF/+p43Hj/r/e3Ye531PvDaa6+Zf1vvh5bhw4eb56D1WrFs2TJ3p06dzE4DR44cOf47rr76aveoUaPO+XmM0yMA2uSee+4xT4A/Xn744Yfjt9myZYu7ffv27rCwMPPCZr3g5efnH/++dVvrZ6wXwGP2799vAp8VKq0tY+67777jodITWLW1atXqlN+z7seJf4Nt27aZsBAXF2ee4FYAGTBggDs9Pd3taawXXGtLCetN13rRrVevnvvFF1905+TknPb+WawXtkcffdRdqlQpd3h4uPvmm28+KVR5CmuLiVM9Xk/8DOmNx896I7HeYIODg812EgsWLDhpCxvreXqiCRMmuGvXrm1u36BBA/eXX37p9kSnO1bWcTzd/evbt+/xv0W5cuXcHTp0cC9evNjtqbp37+6uUKGCqbdSpUqmbX3o8IXjd4wV6Kzjtnbt2j99zxuP37H3rD9ejt0PayuYZ5991tRvvWZYHzj/eN+t7bas8H6uz2Ocnp/1nxN7BAEAAODb2AcQAADAYQiAAAAADkMABAAAcBgCIAAAgMMQAAEAAByGAAgAAOAwBEAAAACHIQACAAA4DAEQAADAYQiAAAAADkMABAAAcBgCIAAAgMMQAAEAAByGAAgAAOAwBEAAAACHIQACAAA4DAEQAADAYQiAAAAADkMABAAAcBgCIAAAgMMQAAEAAByGAAgAAOAwBEAAAACHIQACAAA4DAEQAADAYQiAAAAADkMABAAAcBgCIAAAgMMQAAEAAByGAAgAAOAwBEAAAAA5y/8D6yuJBpv+RsMAAAAASUVORK5CYII=", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure()\n", - "DetailedBalanceT1=detailed_balance_factor(x,temperature=300.0)\n", - "\n", - "plt.plot(x,DetailedBalanceT1, label='Detailed Balance Factor at T=300 K')" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "47653f60", - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "detailed_balance_factor() got an unexpected keyword argument 'temperature_K'", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mTypeError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[8]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43mdetailed_balance_factor\u001b[49m\u001b[43m(\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43mtemperature_K\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m10.0\u001b[39;49m\u001b[43m)\u001b[49m\n", - "\u001b[31mTypeError\u001b[39m: detailed_balance_factor() got an unexpected keyword argument 'temperature_K'" - ] - } - ], - "source": [ - "detailed_balance_factor(0,temperature_K=10.0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2c0db4ac", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "91fab918d2644308a604cf7abf1918a9", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAbrJJREFUeJzt3Qd8E+UbB/Cnu8yyp2xkT0EQVBABEfgjOFlCmYqgoihLNspQkSEiCMgSkKGAAwSVjSxZsqfsPdvS0n3/z++lF5M0aVNocmny+34+gebyJnnvLrl78rzjfDRN04SIiIiIvIav0RUgIiIiItdiAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASEREReRkGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASEREReRkGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASeYhnnnlG3R6Ej4+PDB8+PN3rRERE7okBILmVOXPmqGDE3m379u3izQ4fPqwCtTNnzrj8vfGe9vbLE088ke7vN3r0aFmxYoV4ig0bNqT42V60aJHRVXQLX3/9tToOpKZTp04pbk/9hnIP4/fff5euXbtKpUqVxM/PT4oXL263bGJionz22WdSokQJCQ4OlipVqsj333/v0Pvge4363rhxw2L5+fPnpVSpUpIrVy7Zs2fPQ60LkTl/i3tEbmLkyJHqIGqtdOnS4u0B4IgRI1Smz/pEhBOVK7Rt21aaNWtmsSxv3rxOCQBfeeUVadWqlXiSd999Vx5//PFky+vUqWNIfdwxAMyTJ0+qgdubb74pjRo1Mt0/ffq0DB06VN544w15+umnTcsRPD2MhQsXyuLFi+Wxxx6TQoUKpVh20KBBMnbsWOnevbvaxz/99JO0a9dOBXZt2rRJ83tfvHhRGjRoILdu3ZI///xT1YEovTAAJLfUtGlTqVmzptHVyFACAwNd8j44Cb3++uuSEUVGRkqW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", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "k_B = 8.617333262145e-2 # meV/K\n", - "T=1\n", - "\n", - "E=np.linspace(-10, 10, 1000)\n", - "y=np.exp(E/2/k_B/T)\n", - "y2=detailed_balance_factor(E, temperature=T)\n", - "plt.figure()\n", - "plt.plot(E, y, label='Exponential Factor at T=10 K')\n", - "plt.plot(E, y2/k_B/T, label='Detailed Balance Factor at T=10 K', linestyle='--')\n", - "plt.xlabel('Energy (meV)')\n", - "plt.ylabel('Exponential Factor')\n", - "plt.title('Exponential Factor vs Energy at T=10 K')\n", - "plt.legend()\n", - "plt.show()\n", - "\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "EasyQENSDev", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.11" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/convolution_example .ipynb b/examples/convolution_example .ipynb deleted file mode 100644 index b182c87..0000000 --- a/examples/convolution_example .ipynb +++ /dev/null @@ -1,959 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "64deaa41", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "\n", - "from easydynamics.sample import Gaussian\n", - "from easydynamics.sample import Lorentzian\n", - "from easydynamics.sample import Voigt\n", - "from easydynamics.sample import DampedHarmonicOscillator\n", - "from easydynamics.sample import Polynomial\n", - "from easydynamics.sample import SampleModel\n", - "from easydynamics.sample import DeltaFunction\n", - "\n", - "from scipy.special import voigt_profile\n", - "\n", - "from easydynamics.resolution import ResolutionHandler\n", - "\n", - "import matplotlib.pyplot as plt\n", - "\n", - "\n", - "from easyscience.variable import Parameter\n", - "%matplotlib widget\n", - "plt.close('all')" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "5c5b3e0a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0, 0.5, 'y')" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "41eccceef6364906b2871305aa7714ef", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAZtNJREFUeJzt3Qd8k3X+B/BPdpq06aK7pey9BAQBB7hwj/Nc50BPz3FuPQfnnetUPM91w/P0/iqOcytuHKCAgICykb2hg+4kTZv9/F+/X2hoSwstTZs0z+f9eqVP8uSX5/k9eZon3/ymRlEUBURERESkGtpoZ4CIiIiIuhYDQCIiIiKVYQBIREREpDIMAImIiIhUhgEgERERkcowACQiIiJSGQaARERERCrDAJCIiIhIZRgAEhEREakMA0AiIiIilWEASERERKQyDACJiIiIVIYBIBEREZHKMAAkIiIiUhkGgEREREQqwwCQiIiISGUYABIRERGpDANAIiIiIpVhAEhERESkMgwAiYiIiFSGASARERGRyjAAJCIiIlIZBoBEREREKsMAkIiIiEhlGAASERERqQwDQCIiIiKVYQBIREREpDIMAImIiIhUhgEgERERkcowACQiIiJSGQaARERERCrDAJCIiIhIZRgAEhEREakMA0AiIiIilWEASERERKQyDACJiIiIVIYBIBEREZHKMAAkIiIiUhkGgEREREQqwwCQiIiISGUYABIRERGpDANAIiIiIpVhAEhERESkMgwAiYiIiFSGASARERGRyjAAJCIiIlIZBoBEREREKsMAkIiIiEhlGAASERERqQwDQCIiIiKVYQBIREREpDIMAImIiIhUhgEgERERkcowACQiIiJSGVUHgA899BA0Gk2T26BBg6KdLSIiIqJOpYfKDR06FHPmzAk/1utV/5YQERFRnFN9tCMCvuzs7CN6bTAYRHFxMZKSkmTpIREREcU+RVHgdDqRm5sLrVadlaGqDwC3bNki/wHMZjMmTJiAGTNmoGfPni2m9Xg88tagqKgIQ4YM6cLcEhERUaTs2bMH+fn5UCONIsJglZo9ezZqa2sxcOBAlJSU4OGHH5ZB3bp162SpXkttBkWalv6BbDZbF+WaiIiIOsLhcKCgoAA1NTVITk6GGqk6AGxO/CMUFhbimWeewTXXXHPYEsCGfyC73c4AkIiIqJtwOBwy8FPz97fqq4AbS0lJwYABA7B169YWnzeZTPJGRERE1J2ps+VjK0R18LZt25CTkxPtrBARERF1GlUHgH/4wx8wf/587Ny5E4sXL8b5558PnU6HSy+9NNpZIyIiIuo0qq4C3rt3rwz2KisrkZGRgWOPPRZLliyR94mIYlUgEIDP54t2NohilijMEcO8cYi21qk6AHznnXeinQUionY3VRE/Xtl/j+jQLBaLbNJlNBqjnZWYpOoAkIiou5X8ieBPfLGJmgqWbhAdTPw48nq9KC8vx44dO9C/f3/VDvZ8KAwAiYi6CVHtK77cRPCXkJAQ7ewQxSzx+TAYDNi1a5cMBsVkD9QUQ2Iiom6GJX9Eh8dSv0Pju0NERESkMgwAiYgoLkyePBm33357h7YhhgUTJayrVq2KWL7E9j7++GN0Z5F8X+Lh/YgHDACJiEiVrrrqKpx33nlN1onpPcXc8MOGDYtavuLFQw89hFGjRh20Xry/p59+elTyRAewEwgREVGj8eOys7OjnY24xvc3NrAEkIjoCLjqnHj49Uvwp1cvQK3LHu3sxLSvvvpKDrQv5ltPT0/HWWedJafdbF69+NFHH2HKlClymJuRI0fixx9/DKcRA/aLgfvz8vLk88OHD8fbb7/d6j4feeSRFkvxRInUn//8Z1k69dprr+GTTz6R+xa3efPmtVjV+csvv8g822w2JCUl4bjjjgvn/6effsIpp5yCHj16IDk5GSeccAJWrFjRrvcnGAziySefRL9+/eR88z179sRjjz0Wfn7t2rU48cQTZc9W8f5dd911cjzI5iWZTz31lBz3TqS56aabwoOF//GPf8T48eMP2q94j8X71JAHcT8/P1/mQbxP4ry1ZubMmfJ8NiaqdRs6KInnH374YaxevTr8/op1LVUBd/T46MgwACQiOgIPv30JPlB+QbW9CE99sz0qeRBDwtR5/VG5tWcgapfLhTvvvBM///wz5s6dK3tniqk3RdDR2P333y+n6BTB14ABA2TA5/f75XNutxtjxozBF198gXXr1skg4YorrsCyZcta3Odvf/tbbNiwQQZoDVauXIk1a9bg6quvlvu56KKLcNppp8kqSXGbOHHiQdspKirC8ccfL4Oi7777DsuXL5fbbsiX0+nEtGnTsHDhQjmTlBhz7owzzpDr22r69Ol44oknZGC6fv16vPXWW8jKygq/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u91uxWKxKIsXL26y/pprrlEuvfTS8OP33ntPMZvNyn333ScDORHENWgIAEWw1qCyslJJSEhQ3n333fD2rrvuuib7+OGHHxStVivfLxHkiG18++23LeazYR+Ng7a25H369OnKkCFNz/W9997bpgDw9ttvb7LupJNOUh5//PEm69544w0lJydH3n/66aeVAQMGhIPelrbZ1gCwtWOOJwwAD41tAImIDiEYCOBnqwd+jQa3mg/faqYwdxjGfz4MHn8SvL4AjAYd1Gzr1q2oq6vDKaec0mS91+vFUUcdFX584YUXYtasWXjiiSdk1Wj//v0P2taECRPC99PS0jBw4EBs2LBBPl69ejXWrFmD//3vf+E0IiYSVbg7duzA2rVrodPpcMIJJ0Q072L/48ePbzWfhzJ27Ngmj8UxLFq0KFwdLAQCAbjdbpkP8R4999xzsmr4tNNOwxlnnIGzzz4bej2/yqn9+F9DRHQIztpqTK+shl2rRUFmv8Om75GahbmOyyHKY+xuPzK6IABc+pulcpmgTwivu3ro1bh88OXQa5te5uddNE8uzXpzeN0lgy7BBf0vgE7bNK9fXfDVQWnP7Xduu/JWW1srl6L9Xl5eXpPnRDu2BiLAWb58uQzStmzZ0q59NOzn+uuvb9ImroFoMyeCuSPZZlvyfqRE27/m+xNt/n71q18dlFa0CRRtFzdt2oQ5c+bg22+/xe9//3v87W9/w/z582UHEtGOr6EdZePOJUQtYQBIRHQIdTWVuMhZC49igDEx1MP3UHRaDWxmA+z1PtjrvchI6nigcDgWw8HzDht0BnlrU1qtQd7amrY9hgwZIoOl3bt3H7L07a677oJWq8Xs2bNlydaZZ56JE088sUmaJUuWyGBOqK6uxubNmzF48GD5WHScWL9+vezY0ZLhw4fL0kARLIlOJ80ZjcZwiVt78i72/+mnnx6UzyMhjkEEeK0dgyA6mohSP3G76aabMGjQIFm6KV6bkZGBkpKScFoRSIvAujUtHTOpBwNAIqJDcNWUy6Vdk4RMbdsGThiWuAxuwx4UlfZAv8ym1YNqk5SUhD/84Q+44447ZAB27LHHwm63y6pOm82GadOmyRK2V155BT/++KMMZO6++265XlTpih6qDR555BGkp6cjKysL999/P3r06IHzzjtPPid694qewTfffDOuvfZaWbomAkJRUvav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XXWu2kN8zkQP9FmzZskhmERv+/YSVWtr167FGWecge5AtH8TJctXXHFFtz9/jYnPmriGiFEh4vn8if9REbSJc9QQ8Ik276L9emujZRzJ55gaadQhhLrQrl27lJUrVyoPP/ywkpiYKO+Lm9PplM/7/X5l2LBhyqmnnqqsWrVK+eqrr2Sv2enTp4e3sXTpUmXgwIHK3r17w+tOO+005aijjpLPLVy4UOnfv79y6aWXKrFizpw5sveX6O3anDgOcTwi78LWrVtlL+Gff/5Z2bFjh/LJJ58offr0UY4//ngl1ixevFj2ABbnatu2bcqbb74pz9eVV17Z6vEJN9xwg9KzZ0/lu+++k8c5YcIEeYs1Iu/9+vVTTjrpJHm/pKQkfOuu5++dd96RPQxnzpwpe9Bfd911SkpKSrjn/RVXXKHcd9994fSLFi1S9Hq98tRTT8n/X9ELVfTiXrt2rRJrbrzxRtkjdN68eU3OVV1dXThN8+MT16Kvv/5a/v8uX75cueSSSxSz2az88ssvSiy666675PGJ/y1xbk4++WSlR48essdzdz9/jXu0iuvDvffee9Bz3fH8ie+3hu868T3wzDPPyPvi+1B44okn5GdQXCvWrFmjnHvuuXKkgfr6+vA2TjzxROWf//xnmz/H1DoGgFEybdo0+QFofvv+++/DaXbu3KmcfvrpSkJCgrywiQuez+cLPy/SiteIC2CDyspKGfCJoFIMGXP11VeHg8pYIPI2ceLEFp8Tx9H4Pdi9e7cMFtLS0uQHXAQgd999t2K325VYIy64YkgJ8aUrLrqDBw9WHn/8ccXtdrd6fIK4sP3+979XUlNTFYvFopx//vlNgqpYIYaYaOn/tfFvyO54/sQXifiCNRqNcjiJJUuWNBnCRnxOG3vvvfeUAQMGyPRDhw5VvvjiCyUWtXauxHls7fhuv/328HuRlZWlnHHGGcqKFSuUWHXxxRcrOTk5Mr95eXnysfjREQ/nr4EI6MR527Rp00HPdcfz1/Cd1fzWcBxiKJg///nPMv/imiF+cDY/djHclgje2/o5ptZpxJ/GJYJEREREFN84DiARERGRyjAAJCIiIlIZBoBEREREKsMAkIiIiEhlGAASERERqQwDQCIiIiKVYQBIREREpDIMAImIiIhUhgEgERERkcowACQiIiJSGQaARET7lZeXIzs7G48//nh43eLFi2E0GjF37tyo5o2IKJI4FzARUSNffvklzjvvPBn4DRw4EKNGjcK5556LZ555JtpZIyKKGAaARETN3HTTTZgzZw7Gjh2LtWvX4qeffoLJZIp2toiIIoYBIBFRM/X19Rg2bBj27NmD5cuXY/jw4dHOEhFRRLENIBFRM9u2bUNxcTGCwSB27twZ7ewQEUUcSwCJiBrxer0YN26cbPsn2gA+99xzsho4MzMz2lkjIooYBoBERI3cfffd+OCDD7B69WokJibihBNOQHJyMj7//PNoZ42IKGJYBUxEtN+8efNkid8bb7wBm80GrVYr7//www944YUXop09IqKIYQkgERERkcqwBJCIiIhIZRgAEhEREakMA0AiIiIilWEASERERKQyDACJiIiIVIYBIBEREZHKMAAkIiIiUhkGgEREREQqwwCQiIiISGUYABIRERGpDANAIiIiIpVhAEhEREQEdfl/OEEuQ/nSzWYAAAAASUVORK5CYII=", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "\n", - "offset=Parameter('offset', 0.1)\n", - "\n", - "sample_gauss = Gaussian(center=0.1, width=0.3, area=2)\n", - "resolution_gauss = Gaussian(center=0.2, width=0.4, area=3)\n", - "\n", - "resolution_handler= ResolutionHandler()\n", - "\n", - "x = np.linspace(-10, 10, 10000)\n", - "\n", - "# THEN\n", - "analytical_convolution = resolution_handler.convolve(x=x,sample_model=sample_gauss, resolution_model=resolution_gauss,offset=offset,method='analytical')\n", - "numerical_convolution = resolution_handler.convolve(x=x,sample_model=sample_gauss, resolution_model=resolution_gauss,offset=offset,method='numerical')\n", - "\n", - "\n", - "\n", - "#EXPECT\n", - "expected_width = np.sqrt(sample_gauss.width.value**2 + resolution_gauss.width.value**2)\n", - "expected_area = sample_gauss.area.value * resolution_gauss.area.value\n", - "expected_center = sample_gauss.center.value + resolution_gauss.center.value + offset.value\n", - "expected_result = expected_area * np.exp(-0.5 * ((x - expected_center) / expected_width)**2) / (np.sqrt(2 * np.pi) * expected_width)\n", - "\n", - "\n", - "\n", - "plt.figure()\n", - "plt.plot(x, analytical_convolution, label='analytical convolution')\n", - "plt.plot(x, numerical_convolution, label='numerical convolution', linestyle='--')\n", - "plt.plot(x, expected_result, label='expected result', linestyle=':')\n", - "plt.legend()\n", - "plt.xlabel('x')\n", - "plt.ylabel('y')\n" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "dd5c529e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "10eb3fc1fd864691b5a2e8d3425bbc99", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAa7hJREFUeJzt3Qd4FOXaBuBne3rvnRJ67x0RFBFRPPajAvb6K2LF3rEeGyp2bNgFFEUFpPfeCYSE9N57tsx/fRMTE0ggIWV2d577uobJzs7OvDMJu+9+VSNJkgQiIiIiUg2t0gEQERERUcdiAkhERESkMkwAiYiIiFSGCSARERGRyjABJCIiIlIZJoBEREREKsMEkIiIiEhlmAASERERqQwTQCIiIiKVYQJIREREpDJMAImIiIhUhgkgERERkcowASQiIiJSGSaARERERCrDBJCIiIhIZZgAEhEREakME0AiIiIilWECSERERKQyTACJiIiIVIYJIBEREZHKMAEkIiIiUhkmgEREREQqwwSQiIiISGWYABIRERGpDBNAIiIiIpVhAkhERESkMkwAiYiIiFSGCSARERGRyjABJCIiIlIZJoBEREREKsMEkIiIiEhlmAASERERqQwTQCIiIiKVYQJIREREpDJMAImIiIhUhgkgERERkcowASQiIiJSGSaARERERCrDBJCIiIhIZZgAEhEREakME0AiIiIilWECSERERKQyTACJiIiIVIYJIBEREZHKMAEkIiIiUhkmgEREREQqwwSQiIiISGWYABIRERGpDBNAIiIiIpVhAkhERESkMkwAiYiIiFSGCSARERGRyjABJCIiIlIZJoBEREREKsMEkIiIiEhlmAASERERqYxe6QAcmc1mQ3p6Ojw9PaHRaJQOh4iIiJpBkiSUlJQgLCwMWq06y8KYALaCSP4iIyOVDoOIiIjOQkpKCiIiIqBGTABbQZT81f4BeXl5KR0OERERNUNxcbFcgFP7Oa5GTABbobbaVyR/TACJiIgci0bFzbfUWfFNREREpGJMAImIiIhUhgkgERERkcqwDWAHdDW3WCywWq1Kh0JktwwGA3Q6ndJhEBGpBhPAdlRdXY2MjAyUl5crHQqR3TfEFkMxeHh4KB0KEZEqMAFsx0GiExMT5VINMdCk0WhUdW8jotOVkufk5CA1NRWxsbEsCSQi6gBMANux9E8k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M7JXr14NtvXs2RPJycmKxeSMRHWNKAW8+uqr5Z6Sogrnvvvuw7x585QOzamFhITI66ysrAbbxePa56jtk7+kpCSsWLGCpX9tbP369cjOzkZUVJRcCigWca/vv/9+xMTEKB0edTAmgNQqogew6K1Xn2inFh0drVhMzkj0ktRqG/53FVXBogSW2o8YdkckeqL9ZS1RFS96A48cOVLR2Jw1+RND7KxcuVIeVoralvjiuG/fPrkGoXYRtQjiC+aff/6pdHjUwVgFTK0iSqFEBwVRBSzevLdt24YPP/xQXqjtiHG9RJs/8c1dVAHv3r0b//vf/3DjjTcqHZrDKy0tRXx8fIOOH+KD0c/PT77foqr9+eefR2xsrJwQiqFKxIfm9OnTFY3bme6zqEm4/PLL5arJZcuWyW1ca9tYiudFm2Jqm7/nkxNrMYSX+JLTvXt3BaIlRSncC5mcwK+//ir16dNHHhqjR48e0ocffqh0SE6nuLhYuvfee6WoqCjJxcVF6ty5s/TYY49JVVVVSofm8FavXi0Pl3HyMnPmzLqhYJ544gkpODhY/hufOHGiFBcXp3TYTnWfExMTG31OLOJ11HZ/zyfjMDDqpRH/KJuCEhEREVFHYhtAIiIiIpVhAkhERESkMkwAiYiIiFSGCSARERGRyjABJCIiIlIZJoBEREREKsMEkIiIiEhlmAASERERqQwTQCIiIiKVYQJIREREpDJMAImIiIhUhgkgERERkcowASQiIiJSGSaARERERCrDBJCIiIhIZZgAEhEREakME0AiIiIilWECSERERKQyTACJiIiIVIYJIBEREZHKMAEkIiIiUhkmgEREREQqwwSQiIiISGWYABIRERGpDBNAIiIiIpVhAkhERESkMkwAiYiIiFSGCSARERGRyjABJCIiIlIZJoBEREREKsMEkIiIiAjq8v9JN1wQCfwNuQAAAABJRU5ErkJggg==", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "#WHEN\n", - "\n", - "x = np.linspace(5, 15, 1000)\n", - "\n", - "sample_gauss = Gaussian(center=10, width=0.3, area=2)\n", - "resolution_lorentzian = Lorentzian(center=0.2, width=0.4, area=3)\n", - "\n", - "resolution_handler = ResolutionHandler()\n", - "\n", - "# THEN\n", - "analytical_convolution = resolution_handler.convolve(x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, offset=0.4, method='analytical')\n", - "numerical_convolution = resolution_handler.convolve(x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, offset=0.4, method='numerical',upsample_factor=5)\n", - "\n", - "#EXPECT\n", - "expected_center = sample_gauss.center.value + resolution_lorentzian.center.value + 0.4\n", - "expected_area = sample_gauss.area.value * resolution_lorentzian.area.value\n", - "expected_result = expected_area * voigt_profile(\n", - " x - expected_center,\n", - " sample_gauss.width.value,\n", - " resolution_lorentzian.width.value\n", - ")\n", - "\n", - "plt.figure()\n", - "plt.plot(x, analytical_convolution, label='analytical convolution')\n", - "plt.plot(x, numerical_convolution, label='numerical convolution', linestyle='--')\n", - "plt.plot(x, expected_result, label='expected result', linestyle=':')\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "1dce52fc", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "8979137297da45c583b39a41cde5a307", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "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NmlXr17Vjh49qvXv31+zs7PTzp49qxki8bnK/IyJr7Lvv/9eXhafQ0Hsm9jHTNeuXdMcHBy09957T75/06dP1ywtLbWNGzdqhiq/+zht2jRt1apV2uXLl+XvpRiBb2FhIf/vNESjRo2SI8937tyZ43svMTExaxtj/xwaMgZAAyBOvyA+3A9bMokvUHFdDPPPJELCa6+9prm5ucn/2J599tkcodHQiFO6PGwfs++TuC5eD0H8J9ChQwfN09NTfsADAgK0l19+OesLzNj3L/NUMJ988onm7e0tv6zFHwEXL17UDFFkZKQMfCLcOjs7a8OGDcsRbu//HQ0MDJRhz93dXe6b+CNHfPnGxMRohuLnn3+Wf0TZ2NjI06YcOHAgxylsxHua3V9//aVVrFhRbi9OKbJu3TrNkOVn/956662sbcXvY5cuXbRjx45phirzlCf3L5n7JH6Kfbz/PrVr15b7KP4Yyf5ZNET53cdvvvlGK1eunAzu4nPXunVr2UBgqHL73sv+vpjC59BQ6cQ/qlshiYiIiKjocBQwERERkZlhACQiIiIyMwyARERERGaGAZCIiIjIzDAAEhEREZkZBkAiIiIiM8MASERERGRmGACJiIiIzAwDIBEREZGZYQAkIiIiMjMMgERERERmhgGQiIiIyMwwABIRERGZGQZAIiIiIjPDAEhERERkZhgAiYiIiMwMAyARERGRmWEAJCIiIjIzDIBEREREZoYBkIiIiMjMMAASERERmRkGQCIiIiIzwwBIREREZGYYAImIiIjMDAMgERERkZlhACQiIiIyMwyARERERGaGAZCIiIjIzDAAEhEREZkZBkAiIiIiM8MASERERATz8n+8HiWD7S3gVgAAAABJRU5ErkJggg==", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "#WHEN\n", - "\n", - "x = np.linspace(-2, 2, 1000)\n", - "\n", - "sample_gauss = Gaussian(center=0, width=0.5, area=2)\n", - "resolution_lorentzian = Lorentzian(center=0.2, width=0.4, area=3)\n", - "\n", - "resolution_handler = ResolutionHandler()\n", - "\n", - "# THEN\n", - "analytical_convolution = resolution_handler.convolve(x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, offset=0.4, method='analytical')\n", - "numerical_convolution = resolution_handler.convolve(x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, offset=0.4, method='numerical',upsample_factor=5)\n", - "\n", - "#EXPECT\n", - "expected_center = sample_gauss.center.value + resolution_lorentzian.center.value + 0.4\n", - "expected_area = sample_gauss.area.value * resolution_lorentzian.area.value\n", - "expected_result = expected_area * voigt_profile(\n", - " x - expected_center,\n", - " sample_gauss.width.value,\n", - " resolution_lorentzian.width.value\n", - ")\n", - "\n", - "plt.figure()\n", - "plt.plot(x, analytical_convolution, label='analytical convolution')\n", - "plt.plot(x, numerical_convolution, label='numerical convolution', linestyle='--')\n", - "plt.plot(x, expected_result, label='expected result', linestyle=':')\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "640097cc", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.020000000000000018\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "5a377490c2b24fba87a8e1a11ad07c5a", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "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cUo2QhoNanU6oJkJIFG84omgKa5PHh0MBmG32+WFIsNiscgLqYkCr24MBrlqMCBnRLdHphQfAdOnxbhM8y2U5jJoohYjER0KtgBSN1OnTsVNN92EWbNmIT09Hbm5ubIrscP27duh0WiwatWqzm3Nzc1y24IFC+R9cS3uf/755xg3bpxMHo4//njU1tbis88+w7Bhw+Ti27/61a/Q1tbWWU4oFMLs2bPRr18/+ZwxY8bg3Xff7Xy8o1xRxvjx42EymfDtt9/usavzpZdewogRI+Q+eXl5uOGGGzof+9Of/oRRo0bBZrOhqKgI1113HVwuV49ep507d2LGjBnyNRLlTJgwAcuWLet8/Pnnn8eAAQNgNBoxZMgQvPrqq92eL47jH//4B8455xxYrVYMGjQI//nPfzpfh8LCQllGVytXroRWq8WOHTvk/bKyMpx11lky+RWv5/nnn4+ampp9vre33HJLt21nn302Lr300s7HRdm33nqrjE9c9tYFfCjHR3HAlonloVlYUX4/phWf3O2h/hlpcARy5JeHr4nrARPFKyaA0eBr3fvF7+nBvu7973sQ/vWvf8mkRiQ0TzzxBB5++GF88cUXPS5HJGbPPvssFi9ejPLycpmgiO7FN954A5988gn++9//4q9//Wvn/iL5e+WVV/D3v/8d69atk4nIxRdfjIULF3Yr9+6778Zjjz2GDRs2YPTo0bvVK5KT66+/HldddRXWrFkjE4+BA38+jYVIov7yl7/IOsSxfvXVVzLhPVAiWZwyZQoqKipk2T/++KN8vkjchPfffx8333wzbr/9dqxduxZXX301LrvsMnz99dfdynnooYfka7J69WqceuqpuOiii9DY2CjjE8mleJ26ev3113HUUUehT58+si6R/In9xesj3p9t27bJ7tqD9d5778nEU7zfVVVV8rInh3p8FB92NrX/OCtM6976azHq8LH5dIz3PI8tE38fpeiI6JApdNBaWlrEWkjyeldut1tZv369vN7NA8l7v7z2y+77PpK7931fOrX7vo/3232fHpoyZYpy9NFHd9s2ceJE5a677pK3S0tL5TGvXLmy8/Gmpia57euvv5b3xbW4P3/+/M59Zs+eLbdt3bq1c9vVV1+tTJ8+Xd72eDyK1WpVFi9e3K3uK664QpkxY0a3cj/44IPuL+cDDyhjxozpvJ+fn6/87ne/O+Bjnjt3rpKRkdF5f86cOUpKSspe93/hhReUpKQkpaGhYY+PH3nkkcqVV17Zbdt5552nnHrqz++XOI577723877L5ZLbPvvsM3lfvL4ajUbZsWOHvB8MBpWCggLl+eefl/f/+9//KjqdTikrK+ssY926dbKM5cuX7/F1Ee/tzTff3C2us846S5k5c2bn/T59+ihPP/10t312fT3CcXw9+rxQr3NVb1PG3/Wq0veu/ygtbt9ujx///J+UwX+6Snlh6VdRiY8okt/fasEWQNrNrq1qogtVdN8eSjk5OTmyK7B///7dtnWUW1JSIruDTzzxxM4xfeIiWgS3bt3arVzR3bo3orzKykpMmzZtr/vMnz9fPl5QUICkpCRccsklaGho6NYdvS+i+1t0bYvu3z0RLZOipa4rcV9s39vrI1pcRTdux+shurRFV3lHK6Bo5ROPnXfeeZ11iO5rcekwfPhw2VW7az3hFo7jo9hWMu8WaIbMRp9+jyPZbNjt8ZB1DYzpi7G6bnVU4iOiQ8dJINHw232cO0uj637/zpJ97LtL/n7LGoSDwWDYbTxXR/em6J4U2ht52vn9/v2WI8rYV7kdY/BE17BIzLoS4/i6EsnE3uxvsoIYw3j66afj2muvxaOPPiqTODGO8IorroDP55NJ6v6Ea0LEvl4PQXSZigRQdHmL65NPPhkZGRkHXZ9477q+b/t673rj+Ch2Vbuq4LFrYRIzffdgkG0S+pSV4gTHx0DrRXLMIBHFF7YARoPRtveLwdyDfXdJRPa0T5hlZWXJ667jw7pOCDlYovVKJHpiYoMYr9f10rWVa39Ei544lcneTgvzww8/yCTkqaeewhFHHIHBgwfLFsOeEC1b4pj3Np5NtNwtWrSo2zZxXxxjT4hJMmKMnYhZTIYRCWHXOsS4SnHpsH79ejkhZ2/1iPeu6/smZlCL8rsSkzrE9n0J1/FR7DqqpRaflldiIs7d4+NH50/H7ObtOLthOdBc1uvxEdGhYwsg9Yho/RKJk5iEIWbrii69e++995DLFYmbOJ+fmPghErSjjz4aLS0tMrEQXYczZ87s0eSTa665BtnZ2TjllFPgdDplOTfeeKNMKEWrl5h8csYZZ8jtYtJJT4gJGn/4wx/kDFoxcUV0kYsZuvn5+Zg8eTLuvPNOOflBdBOfcMIJ+Oijj+QEC9H13BMikT3yyCNl66RIys4888zOx0S5YiazSArFxJpAICBnM4vJKXvrIhczsW+77TbZyipm8IrZ0CJh3LXOb775BhdeeKFMyDMzd2/ZCdfxUYwKBWH1tcCOEArS9nwi8YJUCxqVJORpGuU5A4ko/rAFkHpMnGJFJBziVCzitCKPPPJIWMr9/e9/j/vuu08mVaKVSXR5imRFJJo9IZJFkRT97W9/k6eCEV2+W7ZskY+JU8uIxOfxxx/HyJEj5cxaUV9PiFYyMYNZJJhidqtIxERCrPupu0wkhn/+85/x5JNPyvpfeOEFzJkzR55mpadEgidmGYvTqXTtehbdqR9++CHS0tJw7LHHykRMjK98++2391rW5ZdfLl+bX//61zJRFPsfd9xx3fYRM4BFN7lIEDtae3cVzuOjGORpgRbtXfVpmTl73KUgzYI6xY4KvQ5oa+jlAIkoHDRiJkhYSlIhh8OBlJQU2VIlWqm68ng8KC0tlcmL2bxLty4RdcPPSwyp34K3/jUVPsUIy7RPcN643bv2a5wtOPHfR0PRAAv6zETG1DuiEipRJL6/1YItgERE9LPWeryYmow/ZtlhNDn3uEtOUgpMIS10ioIdjVwOjigeMQEkIqJOIWsm8lzZ6ONKxeDMvU/AurJ2IlZsL0d+2y4nryeiuMBJIERE1Mlp64tFVe0r4/RP3/MYQEFrzIbWAygcA0gUl9gCSEREnRpavfLabtLDJCZ57MWajFMxxvMi5o98ohejI6JwYQJIRESdHHXlyEYTsvZzTnSnZRs8OV/hh4Zveys0IgojdgETEVGnrcvvAYZsQYo/G8D0ve7n0W6Vy8GVuuy9Gh8RhQcTQCIi6uTwNcNt0iKk3ffXw1DbMFjL0zBZtxoQS/z9tEwkEcUHfmKJiKjTNKdPLgM3VbPvE3uPyToc/2j5EVc0Lgc83VeUIaLYxwSQiIg62X3NKAoEkGHrv8/9UpOT4FR+Wp2Gy8ERxR0mgKRqCxYskMuq7bombrSJ5dhEXKtWrYp2KKQyFn+LvNYnizGAe5duNaJGSUKdTsvl4IjiEBNAijuxmrRFkhqPmaIg6MdXlhDeTLLDY933KqEBbSPOGWDG9KIChFrrei1EIgoPJoBEPeT3+6MdAlFktDXi9eQk/CEzHS36ff/Y6JuaJa9FmtjUXNVLARJRuDABpG5CoRBmz56Nfv36wWKxYMyYMXj33XflY4qi4IQTTsD06dPlbaGxsRGFhYW4//77u7VUffLJJxg9ejTMZjOOOOIIrF27tls93377LY455hhZR1FREW666Sa0trZ2Pu71enHXXXfJx0wmEwYOHIh//vOfsmv0uOOOk/ukpaXJui699NL9xt7h008/xeDBg+XjohxR3v6IOp5//nmceeaZsNlsePTRR+X2Dz/8EIcddpg8xv79++Ohhx5CIBDofK0efPBBFBcXy/jz8/PlMXYt84MPPuhWT2pqKl5++eXd6t/XMROFlVaPFG8xBjvt6J/WZ5+7plnt+G1pkVwOTutkyzRR3FHooLW0tIgsSF7vyu12K+vXr5fXu2r1tcpLKBTq3OYL+OQ2b8C7x32DoeDP+wbb9/UEPPvdt6ceeeQRZejQocq8efOUrVu3KnPmzFFMJpOyYMEC+fjOnTuVtLQ05ZlnnpH3zzvvPOXwww9X/H6/vP/111/L12TYsGHKf//7X2X16tXK6aefrvTt21fx+Xxyn5KSEsVmsylPP/20snnzZmXRokXKuHHjlEsvvbQzjvPPP18pKipS3nvvPRnH/PnzlbfeeksJBALKv//9b1nHpk2blKqqKqW5ufmAYi8rK5P3b7vtNmXjxo3Ka6+9puTk5Miympqa9vqaiMezs7OVl156SZa7Y8cO5ZtvvlGSk5OVl19+WW4TxyqO8cEHH5TPmTt3rnz8008/lfsvW7ZMefHFF7uV+f7773erJyUlRcYslJaWyn1Wrly5z2NOFPv6vFDvGnH/PKXPXR8rW2ud+933jYcvVpQHkpXqd+/sldiIeuP7Wy2YAEYhARz58kh5aXA3dG574ccX5LYHFj3Qbd+Jr02U23c6d3Zue2XdK3LbrIWzuu17zJvHyO1bGrcc1PF4PB7FarUqixcv7rb9iiuuUGbMmNF5/5133lHMZrNy9913y0ROJHEdOhJAkax1aGhoUCwWi/L22293lnfVVVd1q+N///ufotVq5eslkhxRxhdffLHHODvq6Jq0HUjs99xzjzJ8+PBuj991110HlADecsst3bZNmzZN+cMf/tBt26uvvqrk5eXJ20899ZQyePDgzqR3T2UeaAK4t2NOJEwAY4PHH5DJn7g0tXb/Mbon5z/zqTLqrreUL9dX9kp8ROHSwgRQ4YmgqVNJSQna2tpw4okndtvu8/kwbty4zvvnnXce3n//fTz22GOya3TQoEG7lTV58uTO2+np6RgyZAg2bNgg7//4449YvXo1Xn/99c59RE4kunBLS0uxZs0a6HQ6TJkyJayxi/onTZq01zj3ZcKECd3ui2NYtGhRZ3ewEAwG4fF4ZBziNXrmmWdk1/DJJ5+MU089FWeccQb0en7kKHY111cjB41waJORbDbsd//WpC3whtZhZV0yjh+W1ysxElF48NsoCpb9apm8tuh/OocWgMtGXIaLh10M/S5n319w/gJ5bdabO7ddOPRCnDvoXOi03Rdqn3fuvN327QmXyyWvxfi9goKCbo+JcWwdRILzww8/yCRty5YtB1XP1Vdf3W1MXAcxZk4kc5GK/WCJsX+71ifG/P3iF7/YbV8xJlCMXdy0aRPmz5+PL774Atdddx3++Mc/YuHChTAYDHIcX8c4yg6cXELRtm3pUwgN+RzFfgu02rP2u7/XsE4uB1fSMhjAKb0SIxGFR8ImgGIywHvvvYeNGzfKAf9HHnkkHn/8cdkS1UG01tx+++1466235KQDMbnhb3/7G3JyciIam9Ww+yrrBp1BXg5oX61BXg5k354YPny4TJbKysr22fomXjOtVovPPvtMtmyddtppOP7447vts3TpUpnMCU1NTdi8eTOGDRsm74uJE+vXr5cTO/Zk1KhRsjVQJEti0smujEZjZ4tbT2IX9f/nP//ZLc6DIY5BJHh7OwZB/L8TrX7icv3112Po0KGydVM8NysrC1VVP8+cFIm0SKz3Zk/HTBRuja218Gi18B3gsm5DDQPRt2ojjvG0/6gloviRsAmgSB7El+7EiRPlzMzf/va3OOmkk2Ti0dGac+utt8oWo7lz5yIlJQU33HCDbNERXXtqlJSUhDvuuEO+LiIBO/roo9HS0iJfj+TkZMycOVO+Xi+99BKWLFkiE5k777xTbhddumKGaoeHH34YGRkZMpn+3e9+h8zMTJx99tnyMTG7V8wMFq/3b37zG/l+iPdFtJQ9++yz6Nu3ryzz8ssvx1/+8hc5m3fHjh2ora3F+eefjz59+sgWtI8//lgmoCLROpDYr7nmGjz11FMyZlGvaMXc06zbAyFmPZ9++ukyyf3lL38pE2LRLSxmOz/yyCOyXJGsiS5nq9WK1157TcYpYhdEwiyOVXRBi/3EayJaBvdmT8dst9sPKnaivRnmDuDT6grMtV9wQPtPso/FxS2PoM3J/4tEcUdRidraWjngc+HChfK+mEVpMBjkbM0OGzZskPssWbIkopNAYpmYmSxm+A4ZMkS+PllZWcr06dPl6yZeQzFrtuvkBzHJYfz48XLWbtfJCh999JEyYsQIxWg0ylnCP/74Y7d6li9frpx44omK3W6XE0lGjx6tPProo52Pi9ft1ltvlZMqRBkDBw6Us3A7PPzww0pubq6i0WiUmTNn7jf2DiIuUZaYDXzMMcfIMg9kEsiuEzYEMdv4yCOPlBNcxIxfcZwdM33F/pMmTZLbxfEdccQRciZzh4qKCuWkk06Sjw0aNEjOFt7XJJC9HXOiiNfPS6Kp+MtJclbvnL91n+C0N3O/WSn3l5fAnic8EcWiFk4CUTTiH6iAGFcmJiuILriRI0fiq6++wrRp02T3pDj/WteWlltuuUW2JO2Pw+GQLYeipUm0MnUlupfFhAZxTjoxJkwtxHkAxTnrdn1difZFrZ+XWFPzx8OR07oJ/+r3R8ycedV+9/9s9U5MfW8k3FoN0m/bBNj3vXwcUaxw7OP7Wy0Stgu4K9ElKJK6o446SiZ/QnV1tRxXtWuSIrosxWN7IsYJikvX/0BERIniB60DzUl2NFpCB7R/Q3ALDu9XhL4+Pz4S6wEzASSKG6pYCUSMBRRjs8Rkj0OdWCJ+MXRcxExPIqJEMd8SxOzMdFQYaw9o/4LkTHnt0GkBkQASUdxI+ARQTDQQA+e//vpruWRZh9zcXHmOuObm7ksY1dTUyMf25J577pHNxR2X8vLyiMcfb6ZOnSpPb8LuX6I4EwrCFBqEYS4rClPbZ+zvz/Cs/ni21IQFZRUIuuojHiIRhU/CJoAiCRHJnzhhsRjvJ8YWdTV+/Hg56/LLL7/s3CZO6yFOI7K3kwOL04yIsQJdL0RECUGrw8rA3Vhefj/GF0w9oKdk2CzwBpOhAeBurol4iEQUPvpE7vZ944038OGHH8pThHSM6xNdt+IUGuL6iiuuwG233SZXqhDJ3I033iiTP3GKEiIitWlo9cnrNGv7eSf3R6/T4g/663CHO4h3B0yHOB00EcWHhE0AxRJlHV2SXc2ZMweXXnqpvP3000/L87ede+653U4EHU4qmWRNdEj4OYk+xeuCsbUaZliRYT+wBFDwZm6A11eOtfUDMThvfERjJKLw0av5C0WcbuK5556Tl3DrOKmvWN1BtDgS0d6J8biCWF6QoqNu3cfwDZqNnKAWdtOpB/y8oGUFjPYSbG6aJgbXRDRGIgqfhE0Ao018kYmJEGL1CkGsBiFWciCi3U/TVFdXJz8jej3/JEVLVVOFXAZO/HRO6sG5GEeG+kLf0oBBhuUADmwFESKKPv61jaCO2cQdSSAR7ZkYiiGW1eOPpOhJ9QTwaXkl5ut61op3IvIxo+UllGl5Am+ieMIEMILEl1leXh6ys7Ph9/ujHQ5RzBInZRdJIEWR24GiQACZ2owePU1jTpHXep8zQoERUSQwAeyl7mCObSKiWBZsaz8nqt/Qs9Nb6Syp8Gg08Ae4MhJRPOFPbiIiwlZvJd5IsmOrNdCj563UrsfEvkV4MjUYsdiIKPzYAkhERPgxVI9/ZaZjdLBnY5btlkzAAbg1QXH6BTH2JWIxElH4sAWQiIigMQ7DMKcVmcahPXrexPwTsXR7Of6vuhbwt0UsPiIKL7YAEhERGlJvxPJNZbhl6KAePS8tKRPGkBYa0QLoaQGMtojFSEThwwSQiIjgcLefqSDF0n4S+wOVYjXiON+foDEn43/29lNfEVHsYwJIRETQuKphgQfJpp59LRgNQdRmrIJW50YIZ3NcEVGcYAJIRKR2wQDaQjejYJAe9e6HARQd8FOTzQaYsr6Ut+vaHMixp0YwUCIKF/5YIyJSO68DNXodavR6WG1pPXpqitmCPs3FmNyYBs+2JRELkYjCiy2ARERq52nGC9W1qNJYoJs2okdPFSu43NwcxInKj6iu2QLglIiFSUThwwSQiEjlFHczCgJBaBQjNEk978L16pMAP+BvbYpIfEQUfuwCJiJSOa+rUV47FJsc09dTPr1dLgfnaW2IQHREFAlMAImIVK6uqUouAzffboTV2PN1y19L3y6Xg1voLY1IfEQUfkwAiYhUrqKlHLMz0/F6ZgCag1jKzag1y2tXwBWB6IgoEpgAEhGpnNtcIJeBy/ce3ImcT9YcgyXby3FOK9cBJooXnARCRKRyoeyTsXxnJsYUphzU8+2WHNgVBU6fM+yxEVFksAWQiEjlWn5aBi65h8vAdWjOmYRjvE/jr8V/CnNkRBQpTACJiFTO42iAGd4eLwPXwaVrRE3Gaqz1LQ17bEQUGewCJiJSucqN16NgUAM0vnEA3ujx892oksvBVQcHRSQ+Igo/tgASEamcQ3GjVq9HQN/zU8AI/ZKLMaI5Ayc4HeKkgmGPj4jCjy2AREQqN8PhxwVN1fhuyOSDev7wzKE4p3ENTJoA4G4ETPawx0hE4cUWQCIilcv1uTDC50NWUv+Den6yxQgHbO13PC3hDY6IIoIJIBGRyllD7d22Jnv6QT1fzB52KFa5HBzXAyaKD+wCJiJSs4AXX1l1CMIKveXgxgDajBqc0M8Av7YInzbtRFHYgySicGMLIBGRmnkc+HNaKu7JzoRT13pQRZgMBnSkjg2O6rCGR0SRwRZAIiI102iQ7UmF2e9HQUreQRczqzIfpwSWoTlLCWt4RBQZTACJiFQsZMnA/yruhaIAgzOKD7ociyZNLgfX4G4Oa3xEFBnsAiYiUjGnJyCTPyHZfHBLwQkfpVwsl4Nb3+/X4QuOiCKGCSARkYo5XE65DJzFoIVRf/BfCfX2Krkc3JqWrWGNj4gig13AREQqtv2HZ1Ew6E2k+q0ATjnocpy6FTBlfYsSZwGAk8MaIxGFHxNAIiIVa2ytl8vAaTr6gQ/SUG0e0hsyMDrEFkCieMAEkIhIxQb49Xirohrfmo49pHKO0xfhnKaVqPQc3KlkiKh3cQwgEZGKmTxtchm4fG3OIZWjt6bIa0OgfVURIoptTACJiNTM65BXIWPSIRVjtKbKa12QLYBE8YAJIBGRipUE6/GxzYpqU+iQytmi7MBhfYtwY44lbLERUeRwDCARkYr9T9uEj7Izcaym6pDKsdvS4Ndo0CqaFfwewGAOW4xEFH5MAImIVEyvK8agtlKkZfY/pHJG5k7CvP9WIkUJtncrMwEkimlMAImIVKzGcg9WrKvBOeNGHlI5GfZkJAUNsGsCgNcJ2LPDFiMRhR8TQCIilS8FJySbD+3rIMmsx3m+B+CGCV8nF0EXpviIKDKYABIRqZjXLWbtKjKBOxR2kw7b0nZAo/Wgzu1BrsEYthiJKPw4C5iISK38HiQZr8HYAXegxb3+kIoyG/QwZX0OU9aX2OmoC1uIRBQZbAEkIlIrrwOlRgMadTpYbYd2HkChT2sx7MEWaKvWAYUDwhIiEUUGE0AiIrXyOvG36lpUay3om35os4CF25sDOD6wEjtqt4QlPCKKHCaAREQq5WttwgifH6lKMuxhaAH06exAAAi4W8ISHxFFDscAEhGplNvZJK9digV206G3BwQMdnkdbGs+5LKIKLKYABIRqVR9S7VcBm6p1QydVnPI5b2TUi6Xg5vn3xqW+IgoctgFTESkUjscZbgnOxNpgQBmhqNArUEuB9cWbAtHaUQUQWwBJCJSKZ8+A4PaDMj2p4elvBN1h+Pz8gqc1cq2BaJYx08pEZFa5Z6NFfOLML5PWliKSzHnIj8QRMAvTi5NRLGMLYBERCrl9PjldTgmgAjN2ZNwmvdRvJR3f1jKI6LIYQsgEZFKudo8YVkGrrM8oxub03ZCH1QAnByWMokoMtgCSESkUs0brpbLwBndT4WlvJZgGcw5n6Aq9FVYyiOiyGELIBGRSjUobdhqNKAAwbCUV2zLQR9HJvrCA4SCgFYXlnKJKPyYABIRqdQZLuC05hps7HtxWMobkTEUHzesaL/jdQKW1LCUS0ThxwSQiEilin1tyPN54bD1DUt5dpsdXsUAk8YPeB1MAIliGMcAEhGplCnYfroWgy08iVqyWQ8nLPK24nGEpUwiigy2ABIRqdQqow86mOEN0yxgoyGE04tT4NamYF5zNbJyR4alXCIKP7YAEhGpUSiIZ9JtuCE3G/Wa5rAUmWwyw6XTwKfVoMFRHZYyiSgyEjYB/Oabb3DGGWcgPz8fGo0GH3zwQbfHL730Urm96+Xkk3neKiJSiaAPaX47+ni0yE4tCkuRWq0W91dYMa+8AnZveGYWE1FkJGwXcGtrK8aMGYPLL78cv/jFL/a4j0j45syZ03nfZDL1YoRERFFksGB51SNw+4MY9svwddVmhlJQEAxiR5szbGUSUfglbAJ4yimnyMu+iIQvNze312IiIooVgWBIJn9CuFYCEV6zXYrH687EPXknoU/YSiWicEvYLuADsWDBAmRnZ2PIkCG49tpr0dDQsM/9vV4vHA5HtwsRUTxyyXWAxZJtgD2MCeDOJBc2p1ZgY1t92MokovBTbQIoun9feeUVfPnll3j88cexcOFC2WIYDO593Mrs2bORkpLSeSkqCs+4GSKi3lax5h25DNzEPvfCoAvfV4HT+D+Ycz/GppY1YSuTiMIvYbuA9+fCCy/svD1q1CiMHj0aAwYMkK2C06ZN2+Nz7rnnHtx2222d90ULIJNAIopHdc5quQxcija8kzUGIgt1jkz0Me0Ia7lEFF6qTQB31b9/f2RmZqKkpGSvCaAYM8iJIkSUCDJ9GrxQVYs1+iFhLfecQAbObFiBkpA9rOUSUXgxAfzJzp075RjAvLy8aIdCRBRxRq8HR3o8cJuywluwOVle6fycBUwUyxI2AXS5XLI1r0NpaSlWrVqF9PR0eXnooYdw7rnnylnAW7duxaxZszBw4EBMnz49qnETEfWGkLtFXgcNtrCWq7OkyGuD3xXWcokovBJ2Esj333+PcePGyYsgxu6J2/fffz90Oh1Wr16NM888E4MHD8YVV1yB8ePH43//+x+7eIlIFSo91fjGYkaFWRfWctdod2BKcQEeT3WHtVwiCq+EbQGcOnUqFKX9FAd78vnnn/dqPEREsWRpqBJv5mZjQqAal4WxXL3JikadDi1acZoZIopVCZsAEhHR3inaLBR765FsLghruWMyJ+PdFbNhD2kA8SNcowlr+UQUHkwAiYhUqDX9d1i3rAwnnjAorOVmphZgiP+n1r+ARy45R0SxhwkgEZEKOT0BeZ1kNoS1XFtSKmb4fgeNKQlv6IxhLZuIwocJIBGRCjnlUnDhXQdYMBoUfJfkhk7XjBA0iTvTkCjO8bNJRKRCmW2/xpF970Cr4+uwlms2Apb8d2HM+QgOL2cCE8UqJoBERGqjKCgxAmssemiM4W0BzLQmId2Vgz6OTDiqNoa1bCIKH3YBExGpTcCD++ob0aDTwjZpdFiL1ut0eKbOgXHYhOrarUD/8WEtn4jCgwkgEZHaeBwY7/UipGiwPb04/MVrbUAI8LW2rzZCRLGHXcBERCoT8jjktQtmJFnCv/qRV2eX1/625rCXTUThwQSQiEhlmh01chm4JSY77KbwLgUnzMlowtSiAix2cQwgUaxiFzARkcpUNVXg+txs6BUFKwzhTwDbdBo06HVw+NgFTBSr2AJIRKQyrqAOxV4tcnxmaCKwVNsp/uF4t6IKR3jNYS+biMKDLYBERCqjyzke67ZZ0DfDGpHys/S5GOLzYzPPA0gUs5gAEhGpdBk4e5hXAelQnn0cZmy34ajc0RgckRqI6FAxASQiUhlHxzJwpvCuA9yhyaqRy8GZg/URKZ+IDh3HABIRqUz9j7PkMnDZyuORKT+4Vi4HV+qdH5HyiejQMQEkIlKZWn+DXAauRdcWkfKLTenIbs3AULcrIuUT0aFjFzARkcoc4dXjsMY6bMuYGpHyD7cNwK21K+HWWCJSPhEdOrYAEhGpTJHHi+ltbvQ19YtI+eakVHltUdxAKBiROojo0DABJCJSGX2gvWtWa0mOSPnWpLSf73idEamDiA4Nu4CJiFRmh8aFJpMRXnP41wEWfDo3Ti/IR0ADzPM6AEt7iyARxQ62ABIRqcz/pQTx6/xcbNVUR6T8dKsNO4x6VBj0aHM1RKQOIjo0bAEkIlIZc9CKHL8Xafb8iJSfY0/BHyp8GIwGeJzNiMx6I0R0KJgAEhGpzEbnE9jZ5Mbok46MSPlGvR79vFYM0VSjppVjAIliERNAIiKVcXnbl4JLjtBScMJfDZfB2ebGfWmjkROxWojoYHEMIBGRiiiK0rkWcJI5MkvBCeuTzVie5MFWb2RONk1Eh4YtgEREKtJcvgKTim+HNmSEUb8kYvW47R/DklKKTY0jcTqGR6weIjo4TACJiFSkrmmnXAZOqwSRYjZHrJ5CJQOOVgeSm8ojVgcRHTwmgEREKqJ3e/FkTR22aXOg1UZuFNDVrTac0rgSG0yDI1YHER08JoBERCqicbfJZeC+1yZFtB7F1F6+RpwImohiDieBEBGpSKCtRV57dfbIVmRqX2ZO62tfdo6IYgsTQCIiFalvrcEqkxFVJmNE6/neUIkzCvLwmrEmovUQ0cFhAkhEpCLfe7bhkvxcvJvcGNF6/AYdthsNqNf6IloPER0cjgEkIlIRP2zI8QNWbWpE6xmXPB5nbnsDeiU9ovUQ0cFhAkhEpCa5s1DyVQkmH9EnotVkJ/fFRI8XDk1rROshooPDBJCISEUcnauARPbPvz69GNf4boE9NQNPRrQmIjoYTACJiFSkN5aBE3QWI+ZbbUjRcwwgUSziJBAiIhWx1V2J44tnIdDyYUTrCWocsBS9Cm/aWxGth4gODhNAIiIVKdW34jubFj5tW0TrybGnwe5OR7bbjoCzPqJ1EVHPsQuYiEhFLm1uQ7POC1P/ERGtpyA5E3OrdqJQUw9X7VbYkzIjWh8R9QwTQCIitVAUTHG3QI8gVqUPiWhVRr0WrbDK223ORkR43REi6iF2ARMRqYW/TSZ/giU5LeLVtWps8trrao54XUTUM2wBJCJSiZC7GatNRliCgNUW+Ta5v2YH0GDIw7VNG1AU8dqIqCeYABIRqYTTUSuXgRPmG9tbAiOpzgDsMBrQ6OYkEKJYwwSQiEglGtqcchm4Ni2QaU2KeH1nthZjXMO3QKEx4nURUc8wASQiUolQ2mEoKXkMKRYDdFpdxOsr0ubJ5eA2eN0Rr4uIeoYJIBGRSjg8fnmdbOmdP/2bMk7Eh9WZODrrCAzrlRqJ6EBxFjARkUo43D8lgBFeBq5DbXKKXA7uh1B7vUQUO9gCSESkElU/Pobjiz+HHQMAHBPx+mqCy2Apeh0bW6eIEYERr4+IDhxbAImIVKLaXS6Xgas3NPVKfQWGZCS501DY5uiV+ojowLEFkIhIJUb4DHjA0YCdtjG9Ut80az88XP0j6nVVvVIfER04JoBERCpR6PFhuLMVn6f075X6TLb21UYsIVev1EdEB45dwEREKqH3tXfFaiwpvVJfx3JzFsUNhEK9UicRHRi2ABIRqURtqAU6gx4+s7VX6mvV+3BRXo68/brXAVhSe6VeIto/tgASEanEP5PacHZhPtbpKnulvpSkFKw2m7DOZJTrEBNR7GALIBGRSmgUA5KCPiRZs3ulvsLkLPy+uhUFigtuZyNs6X17pV4i2j8mgEREKlHmfhqVO1wYN+WIXqkv2WzG6DYj+mu8aHA1w9YrtRLRgWACSESktpVAemkpOI1Gg7/qLoHb48Odtv7I6JVaiehAcAwgEZHa1gLupaXghOVJBXI5uO2+QK/VSUT7xxZAIiIVcNVswlF5d0AbNMJk/F+v1etJmQtLehnWNwzBNAzstXqJSKUtgN988w3OOOMM5Ofny26IDz74oNvjiqLg/vvvR15eHiwWC0444QRs2bIlavESEUVSXUMZltu0WJbkR5rF0mv1Zimpcjk4Y3NFr9VJRCpOAFtbWzFmzBg899xze3z8iSeewF/+8hf8/e9/x7Jly2Cz2TB9+nR4PJ5ej5WIKNKUtlY8UN+ASxsAg07Xa/Xe7rRicfWPOKZ6fa/VSUQq7gI+5ZRT5GVPROvfM888g3vvvRdnnXWW3PbKK68gJydHthReeOGFvRwtEVFkadva8EtnK37UFPVqvUHjT6uOiBNBE1HMSNgWwH0pLS1FdXW17PbtkJKSgkmTJmHJkiV7fZ7X64XD4eh2ISKKB77WJnnt0dl7tV6NOUlea5kAEsUUVSaAIvkTRItfV+J+x2N7Mnv2bJkodlyKinr3lzQR0cFqaq3BVoMeDcbeWQauw0pjg1wObq6hqlfrJaJ9U2UCeLDuuecetLS0dF7Ky8ujHRIR0QFZ2rZFLgP3ampjr9brNmjkcnCVWm+v1ktEKh0DuC+5ubnyuqamRs4C7iDujx07dq/PM5lM8kJEFG+8ig5JQQVmbe+uxzEqeQyO3fE2zEpar9ZLRPumyhbAfv36ySTwyy+/7NwmxvOJ2cCTJ0+OamxERJGgzb0PlZsfR5/sp3u13oKUgZjW5sYIT2uv1ktEKm0BdLlcKCkp6TbxY9WqVUhPT0dxcTFuueUWPPLIIxg0aJBMCO+77z55zsCzzz47qnETEUV2FZDe/bNvzCjGLP+VMCdl4OFerZmIVJkAfv/99zjuuOM67992223yeubMmXj55Zcxa9Ysea7Aq666Cs3NzTj66KMxb948mM3mKEZNRBTpdYB7bxk4QW+34d+mPkjWK0wAiWKIRhEnxaODIrqNxWxgMSEkOTk52uEQEe3VA88dhRrFifH9rsOVp13Ta/WuqtqOS/57BpSQDqtnroBWq8qRRxRjHPz+VucYQCIitdmsb8aiJAVeTe+ejy/XngqTNxnJ3mS0Omp7tW4iUmEXMBER/WxGSysaWwPIGTS0V+vNtqXg/YoaFGnq0FhdAqS2n4WBiKKLCSARUaILhXB6WzO0ULAhc1ivVq3VatCqEaeeqYPH1b4aCRFFH7uAiYgSnc8lkz/BmpLe69W7fzr3oJcJIFHMYAJIRJTgfK0N2GbQo0JrRJKtd9cCFuZkhHBxXg5+bN7Q63UT0Z6xC5iIKMHVNJTjrMJ8eXtZFBYz2mkIYYvJhCnuut6vnIj2iC2AREQJrrHNIZeBs4QAq6H3M8ATvMV4pqYOQ3y9ew5CIto7tgASESU4beYxchm4nOTorGXeX1ssl4Nb53FHpX4i2h0TQCKiBNfs9snrNKsxKvWXZx2DWZVajEibhBFRiYCIdsUuYCKiBNfc1r4MXEovLwPXoSmtUC4Ht0SJTgskEe2OLYBERAmubu2jOLnwf0hWxgGY3Ov1Vwe+h7XPi9jgOQzAmb1ePxHtji2AREQJrsJdIpeBa9RXR6X+PHOyXA4u09sWlfqJaHdsASQiSnCjPDoUOpvgSDkqKvVPTRmMOyvXog1bo1I/Ee2OCSARUYIb7vZicKsTX+QPj0r9tuRseW2FGwj6AR1PB0MUbewCJiJKcCZ/i7w2WHt/GTghKbVLve7mqMRARN0xASQiSnDNcKBOp4XOnhqV+s0WDa7MycVFeTloaa6MSgxE1B0TQCKiBHdflg7HFxdih64xKvVnWKxYbjFgtdmEmsayqMRARN1xDCARUSILhRCEFlpFQUZK+3rAvU2r1eK6Oj0GKdXQtnI1EKJYwASQiCiBKRoNtmx/Er5gACPP6v1zAHYY70nBhGAptrocUYuBiH7GLmAiogTm9gfhC4bkn/t0a/RW4vjcfhZm+a9EZfKoqMVARD9jAkhEpIJl4Aw6DaxGXdTiWJc6RC4HtyEQvRiI6GfsAiYiSmBlGz7AyYWzoQ1mQqM5NWpx1Ok/grXPIqxo9AGYELU4iKgdE0AiogRW0bBJLgOX72+IahzZuiQ0uZNhddZGNQ4iascEkIgogWV4Q7itsQnV2gFRjWOmkoOTKtdiU5I9qnEQUTsmgERECSzD48fUFicWJBVGNQ69NU1eG/ycBUwUCzgJhIgogSltTfI6aEyJahwGe6a8NgeYABLFArYAEhElMIevXi4D57ckRzWOWqMb1+ZkwRYK4MmoRkJEAlsAiYgS2Fx9uVwG7mtTRVTj0Nps+NZqwWqTFlCUqMZCRGwBJCJKaF5FI5eBsxnbx+BFy8DsEXh4QQMygkHA6wTM0W2RJFI7JoBERAmsWfs0WjbWY/SFY6MaR2FGIQY5fTBr/PC3NsLABJAoqpgAEhEl/EogWmTYzFGNI9liwAOBi+GDHncpVmRENRoiYgJIRJTAWtztS8GlWoxRjUOn1eBD6zi0BR242KswASSKMiaARESJyuvCePtt0FgN0GvfBxDdU8Foc+fAqm/A+oYxGF2QE9VYiNSOs4CJiBJUS3MVFiaHsCDVi2SbNdrhIFlJgcmbDF/TzmiHQqR6bAEkIkpQbc11uL2hCZVaK3KTUqMdDh5pMmFK61qsSd4U7VCIVI8JIBFRggq0OnCpw4mtSIFOq4t2OO2rkbQCirt9dRIiih52ARMRJSiPo0Fet2pj45QrIVN7K6SGCSBR1LEFkIgoQbU4qlCr08GpS0IsWGVx4N2cLPTDDoyKdjBEKscEkIgoQS1xrsFlxQUY4XXgqFhISI0aLIIFOrcr2qEQqR4TQCKiBNUW8EGnKDBrLIgFI5LGYPzG/8AWSo92KESqxwSQiChBhbLvR/PCEvQ5sgCxoF/WaEz6vhUODYefE0UbE0AiogTV6PLJuX45ybExCcSWVYzH/BfCb8nEfdEOhkjl+DOMiChBNbSKBBDIsEV3GbgOSampeFF/OF5DLkKhULTDIVI1tgASESWoHOcNOCMvCIP3QQDF0Q4HyWYtbP2fkberXRchP5ljAYmihS2ARESJSFHwg8Uhl4HTGNtbAqMtzWqD3p8EszcZNVVbox0OkaqxBZCIKBF5nbisxYEavQ4DckYiVsypVDA2tA7bKjcAQyZGOxwi1WICSESUgNwtNZjhdKFNMUHJ7Y9Y0apPB3yA11Eb7VCIVI1dwERECchRXyWvG5EMqzH66wB38JnS5HXAWRftUIhUjS2AREQJqLFhJxSdDg2hZBRqNIgV39q9eNuahRGe9VwOjiiKmAASESWgH+pX4PHiAvTxKfgYsaPBBCzSWJDsaYx2KESqxgSQiCgBNfta5TJwdsWEWDLGMgpTyxfBqrFHOxQiVWMCSESUgHS5d6B53qnIG5uFWDIwbQSO2dCKCr0z2qEQqRoTQCKiBNTg8sp5flnJKYglhpyh+IN/BmAtwm+jHQyRinEWMBFRAmqMsWXgOlgycvEP/UT8W5MZ7VCIVI0tgERECchedwvOyHPC7L4ZwADECp2+TS4H51W0CAR/A70udk5RQ6QmbAEkIkpAa421WJDqQ0DXgljSLy0b2oAFFp8dtXVl0Q6HSLXYAkhElGgUBRc6nKg0aDBwzAjEEpvJhPfKXRiAClRUbgJy+0U7JCJVYgJIRJRgFE8Lznc55O3KgjGINS5tKhCqQFtTTbRDIVItdgETESUYV3N7YtWqmJCemopY02ZoXw7Ox/WAiaKGCSARUYJprC1HtU6HGiTDbIi9SRafpwRxTU4WFjtXRzsUItVSdQL44IMPQqPRdLsMHTo02mERER2SNTWrcGJxAa4ssiAWVRmBRVYLdvrYAkgULaofAzhixAjMnz+/875er/qXhIjiXKO75adl4GLrHIAdJhgG49S61TAZC6MdCpFqqT7bEQlfbm5utMMgIgobQ96VaF4yCYcNTUYsGmQfjqmlrSgxu6IdCpFqqboLWNiyZQvy8/PRv39/XHTRRSgr43mpiCgRloHTINMeW8vAdQjmjsGj/l/hfcs50Q6FSLVUnQBOmjQJL7/8MubNm4fnn38epaWlOOaYY+B07nmRcq/XC4fD0e1CRBRr6l0/LQNnNyEW6bP64J/68fhI0z4bmIh6n6q7gE855ZTO26NHj5YJYZ8+ffDOO+/giiuu2G3/2bNn46GHHurlKImIeka/8zacnlcPu3smgNib2ObT1MLW/89oCtoAXBbtcIhUSdUtgLtKTU3F4MGDUVJSssfH77nnHrS0tHReysvLez1GIqL92aCrwMJUH3zaBsSi/um50AbMsPoNcDvrox0OkSoxAezC5XJh69atyMvL2+PjJpMJycnJ3S5ERLHmFw4nLm9uweDswxCL+qfn4OOyJiyrWg1n2dpoh0OkSqpOAO+44w4sXLgQ27dvx+LFi3HOOedAp9NhxowZ0Q6NiOigKB4Hzm1txq1NLRjVdzJikTjnaqMuU9521nLiHVE0qHoM4M6dO2Wy19DQgKysLBx99NFYunSpvE1EFI9cdTuRBMChWJCdmYFY5TJmAZ4N8DTujHYoRKqk6gTwrbfeinYIRERhVV21BU69Do5AOobG4DJwHb5MAV5OzcJYxwqMiHYwRCqk6i5gIqJE833VMkwvKsDtBbG5CkiHOrMeSy0WlPu5HBxRNKi6BZCIKNE0uB0wKAqSFTNi2WHWMTihfBnsGtFhTUS9jS2AREQJJJB5Exo3Poai9GcQy4ZkTcBZrlaMaIvNU9UQJTq2ABIRJZAah0cuA5efmo5YZi0Yij/4Z8BtLMDvox0MkQqxBZCIKIFUt4gEEMhLie0u4PTsXPxDPxHvKEkIBIPRDodIdZgAEhElkIzW63B63v2wBjcilmXaDbD2+zOMhf9EaRMnghD1NiaARESJIhjAUmubXAbOYo3tP+9WgwkmfzosnhRUVmyIdjhEqhPbfyGIiOiAuZsqcH1TCy5rcmB40VjEur/X6rC8ag2yuBwcUa/jJBAiogTRXFOGGU4XqpR05KbG7iogHdrMOYAfCDRXRDsUItVhCyARUYLoWFe3SZcp19uNdUFbbvsNZ1W0QyFSHbYAEhEliLqGEtj0OjTp42M987X2IN7MzUJ+aAtGRzsYIpVhCyARUYL42rkSJxcV4J8ZrYgHXqtVLge3TRcf8RIlErYAEhElCFcgCINBQYo+tk8C3WFMzhF4dNu/kOk3RDsUItVhAkhElCBaLA+icW0VRpw2CPFgYNFh6P/FT61/fg9giO2TVxMlEiaAREQJokquAqJBYVoK4kF2di4e8V+EWiUNf/AFYWdDIFGv4RhAIqKEWgcYyI3xZeA62M0GvG2ZhE8sGShpbol2OESqwhZAIqIE0NpYhqEpN+Ewqw2Ztv8iXujz3oBVX4nFOwdjbEF+tMMhUg22ABIRJYA1Wxbhe5sW3yW3IT81GfEiW5sLqycVnsp10Q6FSFXYAkhElAjqqnBffSM26wuh1cbPb/s7lD44seoDrPXEx7kLiRJF/PyVICKivTLXV+B8pwvHhgYjnhgzB8pre2v7KiZE1DuYABIRJQBdc6m8DqT2QzxJLmhPWDN9FYCiRDscItVgAkhElABqfNtRqddBn9kf8cSeX4CrcrIwoyAFnpbqaIdDpBpMAImI4p2i4I/pHkwvKkB1anz9We+XnY8fzGZsNxqwYeuSaIdDpBqcBEJEFOc8bQ5oFR30ioJR/Scjnuh1OlzdYMNhgVJoc9gCSNRbmAASEcW5ijYdNmx9DFYjMCRvAOLNUM0ATPBsxKra7dEOhUg1mAASEcW5HQ3t6+n2yUiOq1PAdCgtPAtzf+yHQZZjMTbawRCpRPz9pSAiom5K69vkdd8MK+JRoGgkPrWk42vXjmiHQqQabAEkIopzO9ddhWnFVeirnAZgPOKOcSesxS+jNJAN4KpoR0OkCmwBJCKKc1tRi+U2DTRmH+LR+IIhsHhSkO8G/K3N0Q6HSBXYAkhEFOd+09iMCmMAGUccg3g0OqcPPq4sR7amGdU71iN3+JHRDoko4bEFkIgojvmcjTjW24wZThfGDpmCeKTValCjz5e3G3duinY4RKrABJCIKI7V7lgnr+uUVGRlpCNeOSxF8tpTvTHaoRCpAhNAIqI4tnbzfCwxm7DR1BcajQbxalGGHacV5uFV9zfRDoVIFZgAEhHFsYUNi3BVXg5eyzYhnlmyBqLMYECZxhHtUIhUgQkgEVEcawtYkeNXUJw8HPHs+FHn4YWqWvyzuhK+ltpoh0OU8JgAEhHFKUVR8E3dDSgpeRynT34A8Wx48UDke9KQGgqhcuOyaIdDlPB4GhgiojhV0exGU5sfBp0GQ/OSEc/E+MU3Mm/G4ooAfh0ahr7RDogowbEFkIgoTm0oLYcOQQzOSYJJr0O8a+0zHJtSq/Bx2efRDoUo4bEFkIgoTi1ccRNGDNiBMZgIID5PAt2VNakC5tyPsL61D4Drox0OUUJjCyARUZwqC9ag1GiAOSm+u387TOs3ATmuTBzZ7IS/tSna4RAlNLYAEhHFISXox+yaKmw1AZoTzkIiOLxoEF6u3YlCTS22b1iGvhNOjnZIRAmLLYBERHGobvtaFIQ8OKwNmDjqOCQCsSRchWWQvN289btoh0OU0JgAEhHFoZqfTpWy3dAfZqMBicKdMRJ+kQDWfB/tUIgSGruAiYji0ILyD7E+yQ6raQhGInFsyc3AbYYiFPu3YKqiiPPDRDskooTEFkAionijKPivbgceyUzH9uLEOmPe8YdfiAAAp1ZB2aZF0Q6HKGExASQiijNl9U1IahmAAW49zj7ySiSSATl98GhtFuaXV6Jp5X+jHQ5RwmICSEQUZ77Z6sTi+mtgwHMoyixAorHlnQBF0aC5alu0QyFKWBwDSEQUZxZsqpXXU4dkIxFlHXkJJqzrD19LOlYGQzDo2FZBFG78VBERxRFHSw10FS8iEw2YOiQLiWhEvyKEclcjlP8kXlv1VbTDIUpITACJiOLIp4v+D4sLliJnwBMYnpcYK4Ds6XyA2ZnN0JmrMa/ky2iHQ5SQmAASEcWRurIlSA0GUYhsaBL4FCnn5x2L39SY8NDmfwOhULTDIUo4TACJiOKEx9mEy6u/x4KyClzU/zdIZOdNOA2XtlZiaLAGW5e8H+1wiBIOE0Aiojix4bPnYYMHZZpCHDnlAiSylJRkrMw4Xd72LXo+2uEQJRwmgEREcSAU8MOz9RV5u3zQr6HX65Dock+4AV9YrHgqeQfWb1wY7XCIEgoTQCKiOPDe/KdxVb4BV2fnYtQpiXXy570ZOnw0/p6Wj2UWM1779tFoh0OUUJgAEhHFgcXbv4NOUaAzFiMtLR1qcUr+efhNcwuurFoDd0tDtMMhShhMAImI4uDEz+9tvxT6kutx+TGzoSaXnTILpzWnol+wDUvfeSLa4RAlDCaAREQxrKXNj7v+vVrePv3wYzFhyASoiU6nRfNxj+Fh/yW4YtvR+HrzjmiHRJQQmAASEcUqRcEfXzkbWe6l6J9pw10nD4UaTTj2VDSNvQjGvLm45X8zUedyRDskorjHBJCIKAYpoSD++I8z8aGlDE393sSjp6TCYkz8mb97I5Jfo207gromfPTiRXA2VkU7JKK4xgSQiCjG+DxtWPXMebiy6lv09/lxovFwTB4xFmqWm5SG3018FJfUpuByxzdofvYE1JVtjnZYRHFL9Qngc889h759+8JsNmPSpElYvnx5tEMiIpUKBQN49f170fD4aIxzfAlrUIPbsm7EgxfPiXZoMeGC0cfgnNOeRjUyURTaifJXp+C+l85GQ1NltEMjijt6qNjbb7+N2267DX//+99l8vfMM89g+vTp2LRpE7Kzs6MdHhGpQIvbj3UVLViwuQ4ryy/ERnMIfcxOaNwZqDruSUyZ+otohxhTBo8YjwrbPKx97dd4NqMe3+m2IvtfR+Go0Fh4xl+L4tFHIT/FAq1W9e0bRPukURRFgUqJpG/ixIl49tln5f1QKISioiLceOONuPvuu/f7fIfDgZSUFLS0tCA5ObkXIiaiaAmGFPiDIQRCChzOarha62FQdDCG9AgGvPD5PdjmKIU/6EVO7knwa0zwBIKo3PERappWID9oRl+vHhpXDbyeKjyTUoUQgti47WF4YJZ1HJv7ODalNOAcjMGN570Amz0p2ocds4KBIP72n9/iw8ZP8HxNNQb5/ZjlvxL/NufBWvAOCnzFeKK5CR5LNoK2HCw2tyCo02OCZShSLVnw5oxFm9UGV6AO6VodiqGDTq+HVm+EI+iCVq9HmiUdZqMVepMNGr0eeq0Gep16x2EmEge/v9XbAujz+fDDDz/gnnvu6dwmfjGecMIJWLJkyR6f4/V65aXrf6BImLe2CguXPY364LcY7LfgOG8qNFDEhEDMsdfAixDyTNegxTQaInu3tb2H+uB89PebMd2TKoaPy3JesdWhVRtCrn4mms2Hy21W98doCHyK4oAJp7vFvu1et9WjRRtEvu5CNFqOldtsns9RH/gA+UEDftGW1rnvm9ZG1OsCKNCejQbLST/t+w0agm8hO6jHBa0/7zvX1oRqsS+mo856Zvu+vuVoDLyM9JAOlzh/3vc9WwvK9X4U4jjUWM5rj9f/I5oDf0dSSIcruuz7kdWBEoMPRcpk1FgukdssgU1oCTwDi6LFtS0/7/uJ1YWNRi+KQuNRbfmN3GYKlsEVmA0DgJubf973v9ZW/Gj0oTg0EpXm6+Q2Q6ge7sB98vYdTanQQiNvf2Vpw3dmL4qDg1FhvlVu0ymt8AXukLdvbUqB8adyF1o8WGLxoMjfD5XmWZ31BYPXyrfrpqYk2JT2chdbvFhg9aLIX4BK073inZfbtcEbENAEcV2THWmh9taN5WYfvrB5UODPQaXxQfl/RDCGboJX48fVzVZkB3WyhBUmPz5J8iDfn4YqQ/uqCmJ/q3Ir2rQeXNFsQUGg/cttjSmA95I8yAsko0r3eHuhCpCk3AGnrhW/bjajv799343GAN5M8SInYEGN9qnOY0tV7kKzzoGLWkwY4mvft8QQxL9SvcgIGlGPP3fum6n8Fg36JlzQYsQob/u+OwwhvJjmRVpQi7rgXxFSRAgK8rT3odrYgIuaNTjCLY5MwU69gkezNUgJAlWOv8rjCikKBtsexHZLAy5r8mO6yw8tQqjQa3BDvg22kILmisfRphjl63NYxu+x0d6EqxpbcZHDJd/lOh1wenEu9IqCwKb70Iz2hOyY/D9gVYoD1zU149rm9r8DLVotzulTKG/bP1ZQhfZehGNzX8XKtAZc3tyCC5ta5DavBtiSXSxH4QwybERz0mQcVpyG4/s9gWOHDkRaSmbna0N7ptPrcOMvHse1gUexacUCLPl+Lhrd46BXVgC6NoQCTRjt+Q7wAGgC7i3KR61ejzNK38Mwnx/X+m7GF0l6WPLnIt2VjYV133eWfWVhHsoMBrxSWY1xXh9u9V2Lj2wpsBS+gaS2LCyo/hEBtP8/vSI/HaVGHR6rcWKsJ4inNJfiY2seAhmvI9WXiveqN0CBBiFo8VC2CVuMGtzcEMA4D/C68Tx8bBkIZ9JrSAna8K/qbVCglf8fn09XsNmk4KJmPcZ5dfjMfBo+sw5Hnfl12INGvFBTJusXZb+W4sMGUwjnOAyY4NVjgfkEfGKbiBrjHJgVA16orujcd26SF+vMAZzsMmGSx4Dl5qPxkW0KKgz/gBFaPF9d89NfOOAjuwc/mv2Y2mbCUW4TVpkPx8dJJ2OH7kXoEMLfan4+Mfd8qxs/mHyY7DHhWLcVG8xj8EnKOdiq+Zv8/nqmph6Gn0r+xuzGcrMb471mTPXYUWoaio9Tf4UtaG+M+UNtPWzyj5kGS5JOQtGR5+OMMfm99n9LLVSbANbX1yMYDCInJ6fbdnF/48aNe3zO7Nmz8dBDD0U8to3VTuxsWo9VWU5k+6owwdHY+dhNaYVw6rQYtG0LVnjbvySOSt+A1TkuJAdqMd65onPfWantf/CGb9+CZe4iue2I1E1Yl9cKY1s9xrtWde77QGoedhgMGFO2Gd+2DpLbJiZvwcaCNox3e3CYa83Pr0NyLjaajMDOzfjaOVpuG5e0BSWFbRjh9eKw1rWd+z6dnINVZhO0lSX4srRGbhtp3YYdfdxycPu4tvWd+z6fnIUfzBYYq7bgi5/2HWLZjsq+IhEJYFzbhs59X7ZnYqXZClvNNszfXiu39TWVo6G/SBiCGOve1Lnvm/YMrDLbYK8rxVc72vfN01fANcgLcyiEMe4tnfu+b03Hj2Y7kuu3Y8GOOrktTVeFwGCfvD3G833nH8fPrKlYbU5GcmMZvilr39esccIwtH3f4d4VsP6UkS2wpGCNKQVJ7p3435b6zvqShvnl9SDfamSEQvL2UnMy1ppSkeSpxLclP++bNcQDj1aDfv51KAwE5bZVpiSsNaXB6qvG4q0//zEuGtyKZp0WRYFNGOhvr2OjyYb1pgyYA/VYuu3n/1MDBzpRY9AiL1CCEb722LcbrNhgyoQh2IjlpT/vO2xAC3YaNcgObcNwf/uPoWqDBRtNWdAoLfiutKlz3zH9mrHNBKSHdmCYX3wLA006MzaZsjHA68KqbT/vO75PMzabQkjCTgwNtMltHp0Rm025KPT7sGFHe+Ik2Iod2G4ETJp69A21ym1eGLDTkAePJogdDWJb+7tUbHOjTq+FTtOKbLjktlbo0axLQkATgsPtQ9tPQ6GDCKBNq4VGG4BZ0/6aGTU6BDXiyxswof01l5T254iUslUxIajRw6nokBEIybQgNc0Eq94mZ+2mavtijMcF6AZgeVqebI3SJuXhFnMbstKKMen0U5GTkftz2dQjer0eIw4/ATj8BEwWibjnHHy7YwZ8dTuxvGY7go4qaF3VGBooQWHAhxrdcGgMftiS8pFtdMEVTIEFZjTDDr0ShA5BmSgJHW19Yis07Z9PrSL+XwRgREDe92gVtGq1MMODVHjh93ng0Llh1bnggwlZIvv8iUOXgxqDCXZNCwoVN7yuZlT6W2BNq4ErkIq+ofakTmjUZ2Ob0YwkVGNQoA0fNFVikysXtn6lCASTMCTw89+4Fl0mNpussKISQ/2tmO8ejHWOfrD13wpPwIph/p+/01y6DGww2XCWaydG+FxY1laAlU3DYR+4GW1BA0b6tnbu+7Y2HWtNdkxrrcdIrwNrWtOwrH487IPXyx+Eoz0/x/uJNQ2rzUk4wl2H0Z4WbGs14Jvao5A0pP27Y5SnDKaffqB+ZU7BKnMKRnnrMLatGbVOH76smoakYSvl40PaqpCltH8GP23pA19d+2eXwku1XcCVlZUoKCjA4sWLMXmy+LPRbtasWVi4cCGWLVt2QC2Aoss43E3IK8qasHTl22hwfIs8TTJGavM6H1sQLEEAIRTmzETIOqA9rqYFaGj5GtmaJIzW/vwr6X/BrfAhiMKsC6DYh8ltvubFqGv6ApkaG8bq2lsrhCXBUrjhQ37mOdAkj2nft+V71DV8ilSNBYfpRGtFu++CO+BSPMjLOB3a1PFym9+5BrV1HyBJY8YEXZ/OfVcGy9CiuJGbdiL06Ue07+vahNqaubBojDhc30/+qRV/cFcHy9GktCE3dQr06cdAowECbdtRXfU6zBoDJun7txeq0WBdoAINigs5yZNhyDxObg56K1Bd8Qr00GGyYWDnvpsClahTnMhKmgBT1ont+/oaULXz/2Rr3pHGwZ3xbglUoybUgsykMbBkn9K+r9+JqvLn5e2jDIOhEYEB2BaoRVWoCRm24bDmniG3hYJeVGz/i8w/JhkGQq/5qTUrUIeKUCPSrYNgzz+7s77ykidlsjLROAAGTfvvsZ3BBpQH6pFi6YuUwl927rtz258RUoIYZ+wHs6a9bbEq2CTLTjHlI7nwgs7YKkv/hmDIi1GGvrBqTfI1rg02ozRQC7sxG2lFv+p4eVBV+g8Egq0YbiyGXWuR8TQEHdgaqIZdn470Phd37lu9/WX4Aw4MMRYiWWuV25tCrSjxV8KiT0FWn193xltb/ga8/kYMMuQjVWeX21qCbdgs9tVZkdX3ss5968rnwuuvQz9DHtJ17a1szpAbm33lMGstyBtwuaxfHF9j1Tx4PTUoMOYiw5giA/MqAZR6K2HUGVDQ91xAo4VWAzTVLYfXU4ssUwZSDSnQaMXXewCV3jrotTrk5h8LjU4PrUYDZ3MJfN4mJJuSkWSwyX1DCKHF74ROp0Nm2mAYjAYYdFpoEZTP17I7MGGJr8ZgIIBg0I8gtGgLhOD0uRDyeWAP+BH0++U+tZ5aeINepOtTYNKaELBkwKkzoKatCsZAAMVyv5Dcd0dbBdyBNuSZsmDXmOGxF6JJb0WZqwSmYAAjvV4ooqkbIZS4y+AMtqLYkINUrQ1tSf1Qb87ANtdamINBHOFp/y4SZW/1VaI51Io++mxk6lPgsvdFvS0PJY4VMCpBHNPW/gNMoyjY4q9EU9CFQl0WcvVpaLUXoS6pHzY5lkMXDOAEt7ez12Grrwp1IQeKdBko0KWjzVaEmpShWN+yCFD8OK1VxNDeO1UaqEZlsBmFunT00WWi1VqImvSxWN30ldzndKcTOo1WxlAarEN5sBEF2lT012Wj1ZyL6szJWNn8uaz3LEez/DsuNKSORtGwwzGqMCWs76+DXcDqTQBFF7DVasW7776Ls8/++Qt55syZaG5uxocffrjfMvgfiIiIKP44+P2t3tPAGI1GjB8/Hl9++WXnNjEJRNzv2iJIRERElGhUOwZQEKeAES1+EyZMwOGHHy5PA9Pa2orLLvu5a4qIiIgo0ag6AbzgggtQV1eH+++/H9XV1Rg7dizmzZu328QQIiIiokSi2jGA4cAxBERERPHHwe9v9Y4BJCIiIlIrJoBEREREKsMEkIiIiEhlmAASERERqQwTQCIiIiKVYQJIREREpDJMAImIiIhUhgkgERERkcowASQiIiJSGVUvBXeoOhZREWcUJyIiovjg+Ol7W82LoTEBPAROp1NeFxUVRTsUIiIiOojv8ZSUFKgR1wI+BKFQCJWVlUhKSoJGown7rxORWJaXlyfkOoU8vviX6MfI44t/iX6MPL6DpyiKTP7y8/Oh1apzNBxbAA+B+E9TWFgY0TrEf/pE/GB34PHFv0Q/Rh5f/Ev0Y+TxHZwUlbb8dVBn2ktERESkYkwAiYiIiFSGCWCMMplMeOCBB+R1IuLxxb9EP0YeX/xL9GPk8dGh4CQQIiIiIpVhCyARERGRyjABJCIiIlIZJoBEREREKsMEkIiIiEhlmADGgO3bt+OKK65Av379YLFYMGDAADnzyefz7fN5Ho8H119/PTIyMmC323HuueeipqYGserRRx/FkUceCavVitTU1AN6zqWXXipXWel6Ofnkk5EoxyfmYN1///3Iy8uT7/0JJ5yALVu2IBY1NjbioosukidkFccn/s+6XK59Pmfq1Km7vX/XXHMNYsVzzz2Hvn37wmw2Y9KkSVi+fPk+9587dy6GDh0q9x81ahQ+/fRTxLKeHN/LL7+823slnhervvnmG5xxxhlyJQcR6wcffLDf5yxYsACHHXaYnFU6cOBAecyxrKfHKI5v1/dQXKqrqxGLZs+ejYkTJ8rVtLKzs3H22Wdj06ZN+31evH0OYxUTwBiwceNGuazcCy+8gHXr1uHpp5/G3//+d/z2t7/d5/NuvfVWfPTRR/LDsHDhQrks3S9+8QvEKpHQnnfeebj22mt79DyR8FVVVXVe3nzzTSTK8T3xxBP4y1/+It/vZcuWwWazYfr06TK5jzUi+RP/P7/44gt8/PHH8svpqquu2u/zrrzyym7vnzjmWPD222/jtttukz+2VqxYgTFjxsjXvra2do/7L168GDNmzJCJ78qVK+WXlbisXbsWsainxyeI5L7re7Vjxw7EqtbWVnlMIsk9EKWlpTjttNNw3HHHYdWqVbjlllvwm9/8Bp9//jkS5Rg7iCSq6/sokqtYJL63RCPG0qVL5d8Vv9+Pk046SR733sTb5zCmidPAUOx54oknlH79+u318ebmZsVgMChz587t3LZhwwZxSh9lyZIlSiybM2eOkpKSckD7zpw5UznrrLOUeHKgxxcKhZTc3Fzlj3/8Y7f31WQyKW+++aYSS9avXy//b3333Xed2z777DNFo9EoFRUVe33elClTlJtvvlmJRYcffrhy/fXXd94PBoNKfn6+Mnv27D3uf/755yunnXZat22TJk1Srr76aiURjq8nn8tYI/5vvv/++/vcZ9asWcqIESO6bbvggguU6dOnK4lyjF9//bXcr6mpSYlHtbW1Mv6FCxfudZ94+xzGMrYAxqiWlhakp6fv9fEffvhB/loSXYYdRJN4cXExlixZgkQiujXEL9ghQ4bI1rWGhgYkAtEiIbpmur6HYm1K0VUXa++hiEd0+06YMKFzm4hbrIctWi735fXXX0dmZiZGjhyJe+65B21tbYiF1lrxGer62otjEff39tqL7V33F0SLWqy9Vwd7fILo0u/Tpw+Kiopw1llnyRbfRBFP79+hGjt2rBxWcuKJJ2LRokWIp+89YV/ffWp6HyNNH/EaqMdKSkrw17/+FU8++eRe9xGJg9Fo3G2sWU5OTsyO9zgYovtXdGuL8ZFbt26V3eKnnHKK/LDrdDrEs473Sbxnsf4einh27UbS6/XyD/W+Yv3Vr34lEwoxhmn16tW46667ZPfUe++9h2iqr69HMBjc42svhmTsiTjOeHivDvb4xA+sl156CaNHj5ZfxOLvjxjTKpLAwsJCxLu9vX8OhwNut1uOwY13IukTw0nEDzWv14t//OMfchyu+JEmxj7GMjEMSnTLH3XUUfLH4t7E0+cw1rEFMILuvvvuPQ7I7XrZ9Y9xRUWFTHrEWDIxdioRj7EnLrzwQpx55plyoK8Y5yHGnn333XeyVTARji/aIn18Yoyg+HUu3j8xhvCVV17B+++/L5N5ii2TJ0/Gr3/9a9l6NGXKFJmkZ2VlybHJFB9EEn/11Vdj/PjxMnkXCb24FuPKY50YCyjG8b311lvRDkU12AIYQbfffrucxbov/fv377wtJnGIAcriA/viiy/u83m5ubmym6e5ublbK6CYBSwei9VjPFSiLNGdKFpJp02bhng+vo73Sbxn4pd7B3FffAn3hgM9PhHrrpMHAoGAnBnck/9vontbEO+fmO0eLeL/kGhB3nXW/L4+P2J7T/aPpoM5vl0ZDAaMGzdOvleJYG/vn5j4kgitf3tz+OGH49tvv0Usu+GGGzonlu2vtTmePoexjglgBIlfz+JyIETLn0j+xC+3OXPmyPE6+yL2E3+gv/zyS3n6F0F0rZWVlclf8rF4jOGwc+dOOQawa8IUr8cnurXFHy3xHnYkfKI7SnTX9HSmdKSPT/yfEj82xLgy8X9P+Oqrr2S3TUdSdyDE7Euht96/vRHDJ8RxiNdetCwL4ljEffFltLfXQDwuuqk6iJmLvfl5i+Tx7Up0Ia9ZswannnoqEoF4n3Y9XUisvn/hJD5z0f687Y2Y23LjjTfKXgHRqyP+Ju5PPH0OY160Z6GQouzcuVMZOHCgMm3aNHm7qqqq89J1nyFDhijLli3r3HbNNdcoxcXFyldffaV8//33yuTJk+UlVu3YsUNZuXKl8tBDDyl2u13eFhen09m5jzjG9957T94W2++44w45q7m0tFSZP3++cthhhymDBg1SPB6PEu/HJzz22GNKamqq8uGHHyqrV6+WM57F7G+3263EmpNPPlkZN26c/D/47bffyvdhxowZe/0/WlJSojz88MPy/6Z4/8Qx9u/fXzn22GOVWPDWW2/JGdcvv/yynOV81VVXyfeiurpaPn7JJZcod999d+f+ixYtUvR6vfLkk0/KGfcPPPCAnIm/Zs0aJRb19PjE/9vPP/9c2bp1q/LDDz8oF154oWI2m5V169YpsUh8rjo+Y+Kr7E9/+pO8LT6Hgjg2cYwdtm3bplitVuXOO++U799zzz2n6HQ6Zd68eUqs6ukxPv3008oHH3ygbNmyRf6/FDPwtVqt/NsZi6699lo583zBggXdvvfa2to694n3z2EsYwIYA8TpF8SHe0+XDuILVNwX0/w7iCThuuuuU9LS0uQftnPOOadb0hhrxCld9nSMXY9J3BevhyD+CJx00klKVlaW/ID36dNHufLKKzu/wOL9+DpOBXPfffcpOTk58sta/AjYtGmTEosaGhpkwieS2+TkZOWyyy7rltzu+n+0rKxMJnvp6eny2MSPHPHl29LSosSKv/71r/JHlNFolKdNWbp0abdT2Ij3tKt33nlHGTx4sNxfnFLkk08+UWJZT47vlltu6dxX/H889dRTlRUrViixquOUJ7teOo5JXItj3PU5Y8eOlccofox0/SzGop4e4+OPP64MGDBAJu7iczd16lTZQBCr9va91/V9SYTPYazSiH+i3QpJRERERL2Hs4CJiIiIVIYJIBEREZHKMAEkIiIiUhkmgEREREQqwwSQiIiISGWYABIRERGpDBNAIiIiIpVhAkhERESkMkwAiYiIiFSGCSARERGRyjABJCIiIlIZJoBEREREKsMEkIiIiEhlmAASERERqQwTQCIiIiKVYQJIREREpDJMAImIiIhUhgkgERERkcowASQiIiJSGSaARERERCrDBJCIiIhIZZgAEhEREakME0AiIiIilWECSERERKQyTACJiIiIVIYJIBEREZHKMAEkIiIiUhkmgEREREQqwwSQiIiISGWYABIRERGpDBNAIiIiIqjL/wPLKw2hjVPlEAAAAABJRU5ErkJggg==", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "#WHEN\n", - "\n", - "x = np.linspace(-2, 2, 201)\n", - "\n", - "sample_gauss = Gaussian(center=0, width=0.1, area=2)\n", - "resolution_lorentzian = Lorentzian(center=0.2, width=0.004, area=3)\n", - "\n", - "resolution_handler = ResolutionHandler()\n", - "\n", - "# THEN\n", - "analytical_convolution = resolution_handler.convolve(x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, offset=0.4, method='analytical')\n", - "numerical_convolution = resolution_handler.convolve(x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, offset=0.4, method='numerical',upsample_factor=5)\n", - "\n", - "#EXPECT\n", - "expected_center = sample_gauss.center.value + resolution_lorentzian.center.value + 0.4\n", - "expected_area = sample_gauss.area.value * resolution_lorentzian.area.value\n", - "expected_result = expected_area * voigt_profile(\n", - " x - expected_center,\n", - " sample_gauss.width.value,\n", - " resolution_lorentzian.width.value\n", - ")\n", - "\n", - "print(x[1]-x[0])\n", - "\n", - "plt.figure()\n", - "plt.plot(x, analytical_convolution, label='analytical convolution')\n", - "plt.plot(x, numerical_convolution, label='numerical convolution', linestyle='--')\n", - "plt.plot(x, expected_result, label='expected result', linestyle=':')\n", - "plt.legend()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "3ae40370", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "ad31424efda34a789ed7532489989a85", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "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cUo2QhoNanU6oJkJIFG84omgKa5PHh0MBmG32+WFIsNiscgLqYkCr24MBrlqMCBnRLdHphQfAdOnxbhM8y2U5jJoohYjER0KtgBSN1OnTsVNN92EWbNmIT09Hbm5ubIrscP27duh0WiwatWqzm3Nzc1y24IFC+R9cS3uf/755xg3bpxMHo4//njU1tbis88+w7Bhw+Ti27/61a/Q1tbWWU4oFMLs2bPRr18/+ZwxY8bg3Xff7Xy8o1xRxvjx42EymfDtt9/usavzpZdewogRI+Q+eXl5uOGGGzof+9Of/oRRo0bBZrOhqKgI1113HVwuV49ep507d2LGjBnyNRLlTJgwAcuWLet8/Pnnn8eAAQNgNBoxZMgQvPrqq92eL47jH//4B8455xxYrVYMGjQI//nPfzpfh8LCQllGVytXroRWq8WOHTvk/bKyMpx11lky+RWv5/nnn4+ampp9vre33HJLt21nn302Lr300s7HRdm33nqrjE9c9tYFfCjHR3HAlonloVlYUX4/phWf3O2h/hlpcARy5JeHr4nrARPFKyaA0eBr3fvF7+nBvu7973sQ/vWvf8mkRiQ0TzzxBB5++GF88cUXPS5HJGbPPvssFi9ejPLycpmgiO7FN954A5988gn++9//4q9//Wvn/iL5e+WVV/D3v/8d69atk4nIxRdfjIULF3Yr9+6778Zjjz2GDRs2YPTo0bvVK5KT66+/HldddRXWrFkjE4+BA38+jYVIov7yl7/IOsSxfvXVVzLhPVAiWZwyZQoqKipk2T/++KN8vkjchPfffx8333wzbr/9dqxduxZXX301LrvsMnz99dfdynnooYfka7J69WqceuqpuOiii9DY2CjjE8mleJ26ev3113HUUUehT58+si6R/In9xesj3p9t27bJ7tqD9d5778nEU7zfVVVV8rInh3p8FB92NrX/OCtM6976azHq8LH5dIz3PI8tE38fpeiI6JApdNBaWlrEWkjyeldut1tZv369vN7NA8l7v7z2y+77PpK7931fOrX7vo/3232fHpoyZYpy9NFHd9s2ceJE5a677pK3S0tL5TGvXLmy8/Gmpia57euvv5b3xbW4P3/+/M59Zs+eLbdt3bq1c9vVV1+tTJ8+Xd72eDyK1WpVFi9e3K3uK664QpkxY0a3cj/44IPuL+cDDyhjxozpvJ+fn6/87ne/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AcriA/viiy/u83m5ubmym6e5ublbK6CYBSwei9VjPFSiLNGdKFpJp02bhng+vo73Sbxn4pd7B3FffAn3hgM9PhHrrpMHAoGAnBnck/9vontbEO+fmO0eLeL/kGhB3nXW/L4+P2J7T/aPpoM5vl0ZDAaMGzdOvleJYG/vn5j4kgitf3tz+OGH49tvv0Usu+GGGzonlu2vtTmePoexjglgBIlfz+JyIETLn0j+xC+3OXPmyPE6+yL2E3+gv/zyS3n6F0F0rZWVlclf8rF4jOGwc+dOOQawa8IUr8cnurXFHy3xHnYkfKI7SnTX9HSmdKSPT/yfEj82xLgy8X9P+Oqrr2S3TUdSdyDE7Euht96/vRHDJ8RxiNdetCwL4ljEffFltLfXQDwuuqk6iJmLvfl5i+Tx7Up0Ia9ZswannnoqEoF4n3Y9XUisvn/hJD5z0f687Y2Y23LjjTfKXgHRqyP+Ju5PPH0OY160Z6GQouzcuVMZOHCgMm3aNHm7qqqq89J1nyFDhijLli3r3HbNNdcoxcXFyldffaV8//33yuTJk+UlVu3YsUNZuXKl8tBDDyl2u13eFhen09m5jzjG9957T94W2++44w45q7m0tFSZP3++cthhhymDBg1SPB6PEu/HJzz22GNKamqq8uGHHyqrV6+WM57F7G+3263EmpNPPlkZN26c/D/47bffyvdhxowZe/0/WlJSojz88MPy/6Z4/8Qx9u/fXzn22GOVWPDWW2/JGdcvv/yynOV81VVXyfeiurpaPn7JJZcod999d+f+ixYtUvR6vfLkk0/KGfcPPPCAnIm/Zs0aJRb19PjE/9vPP/9c2bp1q/LDDz8oF154oWI2m5V169YpsUh8rjo+Y+Kr7E9/+pO8LT6Hgjg2cYwdtm3bplitVuXOO++U799zzz2n6HQ6Zd68eUqs6ukxPv3008oHH3ygbNmyRf6/FDPwtVqt/NsZi6699lo583zBggXdvvfa2to694n3z2EsYwIYA8TpF8SHe0+XDuILVNwX0/w7iCThuuuuU9LS0uQftnPOOadb0hhrxCld9nSMXY9J3BevhyD+CJx00klKVlaW/ID36dNHufLKKzu/wOL9+DpOBXPfffcpOTk58sta/AjYtGmTEosaGhpkwieS2+TkZOWyyy7rltzu+n+0rKxMJnvp6eny2MSPHPHl29LSosSKv/71r/JHlNFolKdNWbp0abdT2Ij3tKt33nlHGTx4sNxfnFLkk08+UWJZT47vlltu6dxX/H889dRTlRUrViixquOUJ7teOo5JXItj3PU5Y8eOlccofox0/SzGop4e4+OPP64MGDBAJu7iczd16lTZQBCr9va91/V9SYTPYazSiH+i3QpJRERERL2Hs4CJiIiIVIYJIBEREZHKMAEkIiIiUhkmgEREREQqwwSQiIiISGWYABIRERGpDBNAIiIiIpVhAkhERESkMkwAiYiIiFSGCSARERGRyjABJCIiIlIZJoBEREREKsMEkIiIiEhlmAASERERqQwTQCIiIiKVYQJIREREpDJMAImIiIhUhgkgERERkcowASQiIiJSGSaARERERCrDBJCIiIhIZZgAEhEREakME0AiIiIilWECSERERKQyTACJiIiIVIYJIBEREZHKMAEkIiIiUhkmgEREREQqwwSQiIiISGWYABIRERGpDBNAIiIiIqjL/wPLKw2hjVPlEAAAAABJRU5ErkJggg==", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "\n", - "# THEN\n", - "analytical_convolution = resolution_handler.convolve(x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, offset=0.4, method='analytical')\n", - "numerical_convolution = resolution_handler.convolve(x=x, sample_model=sample_gauss, resolution_model=resolution_lorentzian, offset=0.4, method='numerical',upsample_factor=5)\n", - "\n", - "#EXPECT\n", - "expected_center = sample_gauss.center.value + resolution_lorentzian.center.value + 0.4\n", - "expected_area = sample_gauss.area.value * resolution_lorentzian.area.value\n", - "expected_result = expected_area * voigt_profile(\n", - " x - expected_center,\n", - " sample_gauss.width.value,\n", - " resolution_lorentzian.width.value\n", - ")\n", - "\n", - "plt.figure()\n", - "plt.plot(x, analytical_convolution, label='analytical convolution')\n", - "plt.plot(x, numerical_convolution, label='numerical convolution', linestyle='--')\n", - "plt.plot(x, expected_result, label='expected result', linestyle=':')\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "c2d7bf2a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "np.float64(0.1)" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "hasattr(sample_gauss, 'width')\n", - "sample_gauss.width.value" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "5afa23b4", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "9982fb4ac7b4489e9b1c8c6fa66316b6", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAZ7FJREFUeJzt3Qd4U+X+B/BvkqZJuvcubSl776niYLjRv9c9cC8cuOVex0WvgtvruI6r4t4X3AKiDNl7Q6FQuveeSZOc//O+paVFCi20PUnO9/M86UlOTs75naRJfnmnTlEUBURERESkGXq1AyAiIiKirsUEkIiIiEhjmAASERERaQwTQCIiIiKNYQJIREREpDFMAImIiIg0hgkgERERkcYwASQiIiLSGCaARERERBrDBJCIiIhIY5gAEhEREWkME0AiIiIijWECSERERKQxTACJiIiINIYJIBEREZHGMAEkIiIi0hgmgEREREQawwSQiIiISGOYABIRERFpDBNAIiIiIo1hAkhERESkMUwAiYiIiDSGCSARERGRxjABJCIiItIYJoBEREREGsMEkIiIiEhjmAASERERaQwTQCIiIiKNYQJIREREpDFMAImIiIg0hgkgERERkcYwASQiIiLSGCaARERERBrDBJCIiIhIY5gAEhEREWkME0AiIiIijWECSERERKQxTACJiIiINIYJIBEREZHGMAEkIiIi0hgmgEREREQawwSQiIiISGOYABIRERFpDBNAIiIiIo1hAkhERESkMUwAiYiIiDSGCSARERGRxjABJCIiItIYJoBEREREGsMEkIiIiEhjmAASERERaQwTQCIiIiKNYQJIREREpDFMAImIiIg0hgkgERERkcYwASQiIiLSGC+1A3BnTqcTOTk58Pf3h06nUzscIiIiagNFUVBZWYmYmBjo9dosC2MCeBJE8hcfH692GERERHQCMjMzERcXBy1iAngSRMlf4z9QQECA2uEQERFRG1RUVMgCnMbvcS1iAngSGqt9RfLHBJCIiMi96DTcfEubFd9EREREGsYEkIiIiEhjmAASERERaQzbABIRuRmHw4H6+nq1wyByWQaDAV5eXppu43c8TACJiNxIVVUVsrKy5DhmRNQ6Hx8fREdHw9vbW+1QXBITQCIiNyr5E8mf+GILDw9n6QbRUYgfRzabDYWFhUhLS0PPnj01O9jzsTABJCJyE6LaV3y5ieTPYrGoHQ6RyxLvD6PRiPT0dJkMms1mtUNyOUyJiYjcDEv+iI6PpX7H5rHPzvLly3HBBRfIef7Eh+V3333X4lf0I488goEDB8LX11duc91118mp3YiIiIg8nccmgNXV1Rg8eDDefPPNv9xXU1ODTZs24fHHH5fLefPmISUlBRdeeKEqsRIR0ck7/fTTMWPGjJPax8GDB2WhwZYtWzosriMLIdxRRz4vnvB8eAKPbQN4zjnnyMvRBAYG4rfffmux7o033sCoUaOQkZGBbt26dVGURESkluuvvx5lZWUtkhExP2xubi7CwsJUjc0T/POf/5TP7ZFJo3h+g4ODVYuLPDwBbK/y8nL5qyQoKEjtUIiISMXx46KiotQOw6Px+XUNHlsF3B51dXWyTeCVV16JgICAVrezWq2oqKhocSEi+v6XV/DAe2djb/o2tUNxSQsWLMApp5wif2CHhobi/PPPx/79+/9SvSia45xxxhlymBvRhGf16tVN2xQXF8vP6NjYWHm/aMP9xRdftHrMp556CgMGDPjL+iFDhsjmP6J06qOPPsL3338vjy0uS5cuPWpV586dO2XM4vvB398fp556alP869evx6RJk2SJoahdmjBhgmxa1B5OpxPPP/88evToAZPJJGuhnnnmmab7t2/fjjPPPFP2bBXP36233irHg2xeknnRRRfhxRdflOPeiW2mT5/eNFj43//+d4wePfovxxXPsXieGmMQ1+Pi4mQM4nkSr1trPvzww78UmIjSvsYOSuL+WbNmYevWrU3Pr1h3tCrgkz0/OjGaTwDFP9Bll10mh1Z46623jrnt7Nmz5Ru88SKqCohIu+pqq7H29WmYtH4W9itpuGXxlfhl+edddnzxuVVjs6tyac9A1KJN9v33348NGzbg999/l70zL774Ypl0NPePf/wDDz74oEy+evXqJRM+u93e9EN9+PDh+Pnnn7Fjxw6ZJFx77bVYt27dUY954403Yvfu3TJBa7R582Zs27YNN9xwgzyO+Ow/++yzZZWkuIwbN+4v+8nOzsZpp50mk6I//vgDGzdulPtujKuyshLTpk3DihUrsGbNGjnm3LnnnivXt9XMmTMxZ84cmZju2rULn3/+OSIjI5ueuylTpsgqU3Eu33zzDRYvXoy77rqrxT6WLFkik1KxFImtSLYaE66rr75a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UFxVe8/xlVdeUb777jtl37598v9S9MDX6/Xys9MV3XHHHbLn+dKlS1t879XU1DRt4+7vQ1fGBNAFiOEXxJv7aJdG4gtU3Bbd/BuJJOHOO+9UgoOD5QfbxRdf3CJpdDViSJejnWPzcxK3xfMhiA+ByZMnK+Hh4fINnpCQoNxyyy1NX2Dufn6NQ8E8/vjjSmRkpPyyFj8CUlJSFFdUXFwsEz6R3AYEBCg33HBDi+T2yP/RjIwMmeyFhITIcxM/csSXb3l5ueIqXn/9dfkjytvbWw6bsmbNmhZD2IjXtLmvv/5a6dWrl9xeDCny888/K66sPec3Y8aMpm3F/+O5556rbNq0SXFVjUOeHHlpPCexFOd45GOGDBkiz1H8GGn+XnRF7T3H5557TklOTpaJu3jfnX766bKAwFW19r3X/HXxhPehq9KJP2qXQhIRERFR12EvYCIiIiKNYQJIREREpDFMAImIiIg0hgkgERERkcYwASQiIiLSGCaARERERBrDBJCIiIhIY5gAEhEREWkME0AiIiIijWECSERERKQxTACJiIiINIYJIBEREZHGMAEkIiIi0hgmgEREREQawwSQiIiISGOYABIRERFpDBNAIiIiIo1hAkhERESkMUwAiYiIiDSGCSARERGRxjABJCIiItIYJoBEREREGsMEkIiIiEhjmAASERERaQwTQCIiIiKNYQJIREREpDFMAImIiIg0hgkgERERkcYwASQiIiLSGCaARERERBrDBJCIiIgI2vL/+WSQD2ym6yoAAAAASUVORK5CYII=", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "sample_gauss = Gaussian(center=-0.1, width=0.2, area=2)\n", - "resolution_delta = DeltaFunction(name=\"Delta\", center=0.2, area=3)\n", - "\n", - "resolution_handler = ResolutionHandler()\n", - "\n", - "# THEN\n", - "analytical_convolution = resolution_handler.convolve(x=x,sample_model=sample_gauss, resolution_model=resolution_delta,offset = 0.0, method='analytical')\n", - "numerical_convolution = resolution_handler.convolve(x=x,sample_model=sample_gauss, resolution_model=resolution_delta,offset = 0.0, method='numerical')\n", - "\n", - "#EXPECT\n", - "expected_center = sample_gauss.center.value + resolution_delta.center.value + 0.0\n", - "expected_area = sample_gauss.area.value * resolution_delta.area.value\n", - "expected_result = expected_area * np.exp(-0.5 * ((x - expected_center) / sample_gauss.width.value)**2) / (np.sqrt(2 * np.pi) * sample_gauss.width.value)\n", - "\n", - "plt.figure()\n", - "plt.plot(x, analytical_convolution, label='analytical convolution')\n", - "plt.plot(x, numerical_convolution, label='numerical convolution', linestyle='--')\n", - "plt.plot(x, expected_result, label='expected result', linestyle=':')\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "c35a6853", - "metadata": {}, - "outputs": [ - { - "ename": "AttributeError", - "evalue": "'ResolutionHandler' object has no attribute 'numerical_convolve'", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mAttributeError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[9]\u001b[39m\u001b[32m, line 22\u001b[39m\n\u001b[32m 19\u001b[39m MyResolutionHandler=ResolutionHandler()\n\u001b[32m 20\u001b[39m Convolution=MyResolutionHandler.convolve(x, Sample, Resolution)\n\u001b[32m---> \u001b[39m\u001b[32m22\u001b[39m NumConvolution=\u001b[43mMyResolutionHandler\u001b[49m\u001b[43m.\u001b[49m\u001b[43mnumerical_convolve\u001b[49m(x, Sample, Resolution,offset)\n\u001b[32m 23\u001b[39m NumConvolutionUpSample=MyResolutionHandler.numerical_convolve(x, Sample, Resolution,offset,\u001b[32m5\u001b[39m)\n\u001b[32m 25\u001b[39m plt.figure()\n", - "\u001b[31mAttributeError\u001b[39m: 'ResolutionHandler' object has no attribute 'numerical_convolve'" - ] - } - ], - "source": [ - "# Try out the resolution handler\n", - "\n", - "offset=Parameter('offset', 0.0)\n", - "\n", - "Gaussian= Gaussian(center=0,width=0.5,area=2)\n", - "Lorentzian=Lorentzian(center=0, width=0.5, area=3)\n", - "\n", - "Sample= SampleModel('MySample')\n", - "Sample.add_component(Gaussian)\n", - "\n", - "Resolution=SampleModel('MyRes')\n", - "Resolution.add_component(Lorentzian)\n", - "\n", - "Voigt=Voigt(center=0, Gwidth=0.5, Lwidth=0.5, area=6)\n", - "\n", - "\n", - "x=np.linspace(-4, 4, 1000)\n", - "\n", - "MyResolutionHandler=ResolutionHandler()\n", - "Convolution=MyResolutionHandler.convolve(x, Sample, Resolution)\n", - "\n", - "NumConvolution=MyResolutionHandler.numerical_convolve(x, Sample, Resolution,offset)\n", - "NumConvolutionUpSample=MyResolutionHandler.numerical_convolve(x, Sample, Resolution,offset,5)\n", - "\n", - "plt.figure()\n", - "plt.plot(x, Voigt.evaluate(x), label='Voigt')\n", - "plt.plot(x, Convolution, label='Convolution using ResolutionHandler',linestyle='--')\n", - "plt.plot(x, NumConvolution, label='Numerical Convolution', linestyle=':')\n", - "plt.plot(x, NumConvolutionUpSample, label='Numerical Convolution Upsampled', linestyle='-.')\n", - "plt.legend()\n", - "plt.xlabel('x')\n", - "plt.ylabel('y')\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5e3efad9", - "metadata": {}, - "outputs": [], - "source": [ - "Sample.components" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ce30691c", - "metadata": {}, - "outputs": [], - "source": [ - "from easydynamics.utils import detailed_balance_factor\n", - "\n", - "# Example of DetailedBalance\n", - "\n", - "x=np.linspace(-2, 2, 1000)\n", - "Lorentzian=Lorentzian(center=0, width=0.1, area=1)\n", - "\n", - "plt.figure()\n", - "DetailedBalanceT1=detailed_balance_factor(x,temperature=0.0)\n", - "plt.plot(x,Lorentzian.evaluate(x)*DetailedBalanceT1, label='T=0')\n", - "\n", - "DetailedBalanceT3=detailed_balance_factor(x,temperature=1)\n", - "plt.plot(x,Lorentzian.evaluate(x)*DetailedBalanceT3, label='T=1')\n", - "\n", - "DetailedBalanceT3=detailed_balance_factor(x,temperature=3)\n", - "plt.plot(x,Lorentzian.evaluate(x)*DetailedBalanceT3, label='T=3')\n", - "\n", - "plt.plot(x, Lorentzian.evaluate(x), label='No DBF', linestyle='--')\n", - "\n", - "plt.legend()\n", - "plt.xlabel('x')\n", - "plt.ylabel('y')\n", - "plt.show()\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "31008bc4", - "metadata": {}, - "outputs": [], - "source": [ - "from easydynamics.utils import detailed_balance_factor\n", - "\n", - "from scipy.signal import fftconvolve\n", - "\n", - "Sample= SampleModel()\n", - "Sample.add_component(Gaussian)\n", - "\n", - "Resolution=SampleModel()\n", - "Resolution.add_component(Lorentzian)\n", - "\n", - "plt.figure()\n", - "\n", - "\n", - "# Example of DetailedBalance\n", - "\n", - "x=np.linspace(-2, 2, 1000)\n", - "Lorentzian=Lorentzian(center=0, width=0.1, area=1)\n", - "Gaussian= Gaussian(center=0,width=0.1,area=1)\n", - "Voigt=Voigt(center=0, Gwidth=0.1, Lwidth=0.1, area=1)\n", - "\n", - "DetailedBalanceT1=detailed_balance_factor(x,temperature=0.0)\n", - "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT1, label='T=0')\n", - "\n", - "DetailedBalanceT2=detailed_balance_factor(x,temperature=1)\n", - "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT2, label='T=1')\n", - "\n", - "DetailedBalanceT3=detailed_balance_factor(x,temperature=3)\n", - "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT3, label='T=3')\n", - "\n", - "# plt.plot(x, Voigt.evaluate(x), label='No DBF', linestyle='--')\n", - "\n", - "\n", - "\n", - "# Evaluate both models at the same points\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT1\n", - "model2 = Gaussian.evaluate(x)\n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", - "\n", - "\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT2\n", - "model2 = Gaussian.evaluate(x)\n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", - "\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT3\n", - "model2 = Gaussian.evaluate(x) \n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "plt.legend()\n", - "plt.xlabel('x')\n", - "plt.ylabel('y')\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "220405f1", - "metadata": {}, - "outputs": [], - "source": [ - "from easydynamics.sample.components import DetailedBalance\n", - "\n", - "from scipy.signal import fftconvolve\n", - "\n", - "Sample= SampleModel()\n", - "Sample.add_component(Gaussian)\n", - "\n", - "Resolution=SampleModel()\n", - "Resolution.add_component(Lorentzian)\n", - "\n", - "\n", - "\n", - "\n", - "# Example of DetailedBalance, up to 100 mueV. Res and peak is 5 mueV\n", - "\n", - "x=np.linspace(-0.1, 0.1, 1000)\n", - "Lorentzian=Lorentzian(center=0, width=0.005, area=1)\n", - "Gaussian= Gaussian(center=0,width=0.005,area=1)\n", - "Voigt=Voigt(center=0, Gwidth=0.005, Lwidth=0.005, area=1)\n", - "\n", - "DetailedBalanceT1=DetailedBalance(x,temperature_K=0.0)\n", - "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT1, label='T=0')\n", - "\n", - "DetailedBalanceT2=DetailedBalance(x,temperature_K=0.1)\n", - "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT2, label='T=0.1 K')\n", - " \n", - "DetailedBalanceT3=DetailedBalance(x,temperature_K=0.3)\n", - "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT3, label='T=0.3 K')\n", - "\n", - "# plt.plot(x, Voigt.evaluate(x), label='No DBF', linestyle='--')\n", - "\n", - "\n", - "\n", - "# Evaluate both models at the same points\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT1\n", - "model2 = Gaussian.evaluate(x)\n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", - "\n", - "\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT2\n", - "model2 = Gaussian.evaluate(x)\n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", - "\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT3\n", - "model2 = Gaussian.evaluate(x) \n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "plt.legend()\n", - "plt.xlabel('x')\n", - "plt.ylabel('y')\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "36d34acc", - "metadata": {}, - "outputs": [], - "source": [ - "from easydynamics.sample.components import DetailedBalance\n", - "\n", - "from scipy.signal import fftconvolve\n", - "\n", - "Sample= SampleModel()\n", - "Sample.add_component(Gaussian)\n", - "\n", - "Resolution=SampleModel()\n", - "Resolution.add_component(Lorentzian)\n", - "\n", - "\n", - "\n", - "\n", - "# Example of DetailedBalance, up to 2 meV. Res and peak is 100 mueV\n", - "\n", - "x=np.linspace(-2, 2, 1000)\n", - "Lorentzian=Lorentzian(center=0, width=0.1, area=1)\n", - "Gaussian= Gaussian(center=0,width=0.1,area=1)\n", - "Voigt=Voigt(center=0, Gwidth=0.1, Lwidth=0.1, area=1)\n", - "\n", - "DetailedBalanceT1=DetailedBalance(x,temperature_K=0.0)\n", - "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT1, label='T=0')\n", - "\n", - "DetailedBalanceT2=DetailedBalance(x,temperature_K=1)\n", - "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT2, label='T=1 K')\n", - " \n", - "DetailedBalanceT3=DetailedBalance(x,temperature_K=3)\n", - "plt.plot(x,Voigt.evaluate(x)*DetailedBalanceT3, label='T=3 K')\n", - "\n", - "# plt.plot(x, Voigt.evaluate(x), label='No DBF', linestyle='--')\n", - "\n", - "\n", - "\n", - "# Evaluate both models at the same points\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT1\n", - "model2 = Gaussian.evaluate(x)\n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", - "\n", - "\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT2\n", - "model2 = Gaussian.evaluate(x)\n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", - "\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT3\n", - "model2 = Gaussian.evaluate(x) \n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "plt.plot(x, convolved, label='DBF first, then convolve', linestyle='-.')\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "plt.legend()\n", - "plt.xlabel('x')\n", - "plt.ylabel('y')\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c2798453", - "metadata": {}, - "outputs": [], - "source": [ - "from easydynamics.sample.components import DetailedBalance\n", - "\n", - "from scipy.signal import fftconvolve\n", - "\n", - "\n", - "x=np.linspace(-3, 3, 1000)\n", - "Lorentzian=Lorentzian(center=0, width=0.1, area=1)\n", - "Gaussian= Gaussian(center=0,width=0.1,area=1)\n", - "\n", - "\n", - "Sample= SampleModel()\n", - "Sample.add_component(Lorentzian)\n", - "\n", - "Resolution=SampleModel()\n", - "Resolution.add_component(Gaussian)\n", - "\n", - "\n", - "\n", - "\n", - "DetailedBalanceT3=DetailedBalance(x,temperature_K=3)\n", - "\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT3\n", - "model2 = Gaussian.evaluate(x) \n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "# Add Gaussian noise (adjust noise level as needed)\n", - "noise_level = 0.02 # Small relative noise\n", - "noisy_convolved = convolved + np.random.normal(scale=noise_level, size=convolved.shape)+0.05\n", - "\n", - "# Plot only every 10th point\n", - "# plt.plot(x[::10], noisy_convolved[::10], label='Example data, 3 K', linestyle='None', marker='o', markersize=6,markerfacecolor='w')\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "DetailedBalanceT3=DetailedBalance(x,temperature_K=5)\n", - "\n", - "model1 = Lorentzian.evaluate(x)*DetailedBalanceT3\n", - "model2 = Gaussian.evaluate(x) \n", - "\n", - "# Perform convolution\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "# Normalize the result to maintain the area under the curve\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "# Add Gaussian noise (adjust noise level as needed)\n", - "noise_level = 0.02 # Small relative noise\n", - "noisy_convolved = convolved + np.random.normal(scale=noise_level, size=convolved.shape)+0.05\n", - "\n", - "# Plot only every 10th point\n", - "plt.plot(x[::10], noisy_convolved[::10], label='Example data, 5 K', linestyle='None', marker='o', markersize=6,markerfacecolor='w')\n", - "\n", - "\n", - "\n", - "# One start guess\n", - "\n", - "# Lorentzian2=Lorentzian(center=0, width=0.15, amplitude=1)\n", - "# Lorentzian2=Lorentzian(center=0, width=0.15, amplitude=1*2.7)\n", - "Lorentzian2=Lorentzian(center=0, width=0.15, area=1*2.7)\n", - "Gaussian= Gaussian(center=0,width=0.1,area=1)\n", - "\n", - "model1 = Lorentzian2.evaluate(x)*DetailedBalanceT3\n", - "model2 = Gaussian.evaluate(x) \n", - "\n", - "convolved = fftconvolve(model1, model2, mode='same')\n", - "convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "plt.plot(x, convolved+0.05, label='Guess', linestyle='-.', color='r')\n", - "\n", - "\n", - "# # Using area instead\n", - "\n", - "# # Lorentzian2=Lorentzian(center=0, width=0.15, area=0.5)\n", - "# # Lorentzian2=Lorentzian(center=0, width=0.15, area=0.5*2.5)\n", - "# Lorentzian2=Lorentzian(center=0, width=0.1, area=0.5*2.5)\n", - "\n", - "# Gaussian= Gaussian(center=0,width=0.1,area=1)\n", - "\n", - "# model1 = Lorentzian2.evaluate(x)*DetailedBalanceT3\n", - "# model2 = Gaussian.evaluate(x) \n", - "\n", - "# convolved = fftconvolve(model1, model2, mode='same')\n", - "# convolved*= (x[1] - x[0]) # Assuming uniform spacing in x\n", - "\n", - "# plt.plot(x, convolved+0.05, label='Guess', linestyle='-.', color='r')\n", - "\n", - "\n", - "\n", - "plt.legend()\n", - "plt.xlabel('Energy (meV)')\n", - "plt.ylabel('Intensity (a.u.)')\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "47653f60", - "metadata": {}, - "outputs": [], - "source": [ - "Lorentzian.amplitude" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "EasyQENSDev", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.11" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From 93c529922d059bea84879fbf7f16775098f7665d Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Mon, 3 Nov 2025 10:00:16 +0100 Subject: [PATCH 28/71] small update --- src/easydynamics/utils/convolution.py | 154 ++++++++++++++++---------- 1 file changed, 93 insertions(+), 61 deletions(-) diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py index 29ef94a..167a92e 100644 --- a/src/easydynamics/utils/convolution.py +++ b/src/easydynamics/utils/convolution.py @@ -90,29 +90,23 @@ def convolution( # Handle offset if offset is None: - off = 0.0 + offset_float = 0.0 elif isinstance(offset, Parameter): - off = offset.value + offset_float = offset.value elif isinstance(offset, Numerical): - off = float(offset) + offset_float = float(offset) else: raise TypeError( f"Expected offset to be Parameter, number, or None, got {type(offset)}" ) - # Handle temperature - T = None - if temperature is not None: - if isinstance(temperature, Parameter): - T = temperature.value - temperature_unit = temperature.unit - elif isinstance(temperature, float): - T = temperature - else: - raise TypeError( - f"Expected temperature to be Parameter, float, or None, got {type(temperature)}" - ) + if not isinstance(upsample_factor, int) or upsample_factor < 0: + raise ValueError("upsample_factor must be a non-negative integer.") + + if not isinstance(extension_factor, float) or extension_factor < 0.0: + raise ValueError("extension_factor must be a non-negative float.") + if temperature is not None: if x_unit is None: raise ValueError("x_unit must be provided when temperature is specified.") if not isinstance(x_unit, (str, sc.Unit)): @@ -127,7 +121,7 @@ def convolution( x=x, sample_model=sample_model, resolution_model=resolution_model, - offset=off, + offset_float=offset_float, upsample_factor=upsample_factor, extension_factor=extension_factor, ) @@ -136,10 +130,10 @@ def convolution( x=x, sample_model=sample_model, resolution_model=resolution_model, - offset=off, + offset_float=offset_float, upsample_factor=upsample_factor, extension_factor=extension_factor, - temperature=T, + temperature=temperature, temperature_unit=temperature_unit, x_unit=x_unit, normalize_detailed_balance=normalize_detailed_balance, @@ -154,7 +148,7 @@ def _numerical_convolution( x: np.ndarray, sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], - offset: Optional[float] = 0.0, + offset_float: Optional[float] = 0.0, upsample_factor: Optional[int] = 5, extension_factor: Optional[float] = 0.2, temperature: Optional[Union[Parameter, float]] = None, @@ -173,7 +167,7 @@ def _numerical_convolution( The sample model to be convolved. resolution_model : SampleModel or ModelComponent The resolution model to convolve with. - offset : Parameter, float, or None, optional + offset_float : float, or None, optional The offset to apply to the input array. upsample_factor : int, optional The factor by which to upsample the input data before convolution. Default is 5. @@ -193,28 +187,18 @@ def _numerical_convolution( """ # Build dense grid - if upsample_factor == 0: - # Check if the array is uniformly spaced. - x_diff = np.diff(x) - is_uniform = np.allclose(x_diff, x_diff[0]) - if not is_uniform: - raise ValueError( - "Input array `x` must be uniformly spaced if upsample_factor = 0." - ) - x_dense = x - else: - # Create an extended and upsampled x grid - x_min, x_max = x.min(), x.max() - span = x_max - x_min - extra = extension_factor * span - extended_min = x_min - extra - extended_max = x_max + extra - num_points = len(x) * upsample_factor - x_dense = np.linspace(extended_min, extended_max, num_points) + x_dense = _create_dense_grid( + x, upsample_factor=upsample_factor, extension_factor=extension_factor + ) dx = x_dense[1] - x_dense[0] span = x_dense.max() - x_dense.min() - # Handle offset for even length of x in convolution + # Handle offset for even length of x in convolution. + # The convolution of two arrays of length N is of length 2N-1. When using 'same' mode, only the central N points are kept, + # so the output has the same length as the input. + # However, if N is even, the center falls between two points, leading to a half-bin offset. + # For example, if N=4, the convolution has length 7, and when we select the 4 central points we either get + # indices [2,3,4,5] or [1,2,3,4], both of which are offset by 0.5*dx from the true center at index 3.5. if len(x_dense) % 2 == 0: x_even_length_offset = -0.5 * dx else: @@ -222,9 +206,9 @@ def _numerical_convolution( # Handle the case when x is not symmetric around zero. The resolution is still centered around zero (or close to it), so it needs to be evaluated there. if not np.isclose(x_dense.mean(), 0.0): - x_dense_resolution = np.linspace(-0.5 * span, 0.5 * span, len(x_dense)) + x_dense_centered = np.linspace(-0.5 * span, 0.5 * span, len(x_dense)) else: - x_dense_resolution = x_dense + x_dense_centered = x_dense # Give warnings if peaks are very wide or very narrow _check_width_thresholds(sample_model, span, dx, "sample model") @@ -233,12 +217,14 @@ def _numerical_convolution( # Evaluate on dense grid and interpolate at the end if isinstance(sample_model, SampleModel): sample_vals = sample_model.evaluate_without_delta( - x_dense - offset - x_even_length_offset + x_dense - offset_float - x_even_length_offset ) elif isinstance(sample_model, DeltaFunction): sample_vals = np.zeros_like(x_dense) else: - sample_vals = sample_model.evaluate(x_dense - offset - x_even_length_offset) + sample_vals = sample_model.evaluate( + x_dense - offset_float - x_even_length_offset + ) # Detailed balance correction if temperature is not None: @@ -253,11 +239,11 @@ def _numerical_convolution( # Delta functions are handled separately for accuracy if isinstance(resolution_model, SampleModel): - resolution_vals = resolution_model.evaluate_without_delta(x_dense_resolution) + resolution_vals = resolution_model.evaluate_without_delta(x_dense_centered) elif isinstance(resolution_model, DeltaFunction): - resolution_vals = np.zeros_like(x_dense_resolution) + resolution_vals = np.zeros_like(x_dense_centered) else: - resolution_vals = resolution_model.evaluate(x_dense_resolution) + resolution_vals = resolution_model.evaluate(x_dense_centered) # Convolution convolved = fftconvolve(sample_vals, resolution_vals, mode="same") @@ -282,13 +268,13 @@ def _numerical_convolution( # if sample has deltas, convolve each delta with the resolution_model for delta in sample_deltas: convolved += delta.area.value * resolution_model.evaluate( - x - offset - delta.center.value + x - offset_float - delta.center.value ) # if resolution has deltas, convolve each delta with the sample_model for delta in resolution_deltas: convolved += delta.area.value * sample_model.evaluate( - x - offset - delta.center.value + x - offset_float - delta.center.value ) return convolved @@ -298,7 +284,7 @@ def _analytical_convolution( x: np.ndarray, sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], - offset: float = 0.0, + offset_float: float = 0.0, upsample_factor: int = 5, extension_factor: float = 0.2, ) -> np.ndarray: @@ -316,7 +302,7 @@ def _analytical_convolution( The sample model to be convolved. resolution_model : SampleModel or ModelComponent The resolution model to convolve with. - offset : float + offset_float : float The offset to apply to the convolution. upsample_factor : int, optional The factor by which to upsample the input data before numerical convolution. Improves accuracy at the cost of speed. Default is 5 @@ -351,7 +337,7 @@ def _analytical_convolution( # Go through resolution components, adding analytical contributions where possible, making a list of those that cannot be handled analytically for r in resolution_components: - handled, contrib = _try_analytic_pair(x, s, r, offset) + handled, contrib = _try_analytic_pair(x, s, r, offset_float) if handled: total += contrib else: @@ -362,7 +348,7 @@ def _analytical_convolution( x=x, sample_model=s, # single component resolution_model=not_analytical_components, - offset=offset, + offset_float=offset_float, upsample_factor=upsample_factor, extension_factor=extension_factor, ) @@ -380,6 +366,11 @@ def _try_analytic_pair( """ Attempt an analytic convolution for component pair (sample_component, resolution_component). Returns (True, contribution) if handled, else (False, zeros). + The convolution of two gaussian components results in another gaussian component with width sqrt(w1^2 + w2^2). + The convolution of two lorentzian components results in another lorentzian component with width w1 + w2. + The convolution of a gaussian and a lorentzian results in a voigt profile. + The convolution of a delta function with any component results in the same component shifted by the delta center. + All areas are multiplied. Args: x : np.ndarray @@ -440,12 +431,14 @@ def _try_analytic_pair( and isinstance(resolution_component, Gaussian) ): if isinstance(sample_component, Gaussian): - G, L = sample_component, resolution_component + gaussian, lorentzian = sample_component, resolution_component else: - G, L = resolution_component, sample_component - center = (G.center.value + L.center.value) + off - area = G.area.value * L.area.value - return True, _voigt_eval(x, center, G.width.value, L.width.value, area) + gaussian, lorentzian = resolution_component, sample_component + center = (gaussian.center.value + lorentzian.center.value) + off + area = gaussian.area.value * lorentzian.area.value + return True, _voigt_eval( + x, center, gaussian.width.value, lorentzian.width.value, area + ) return False, np.zeros_like(x, dtype=float) @@ -457,7 +450,7 @@ def _gaussian_eval( Evaluate a Gaussian function. y = (area / (sqrt(2pi) * width)) * exp(-0.5 * ((x - center) / width)^2) All checks are handled in the calling function. - args: + Args: x : np.ndarray 1D array of x values where the Gaussian is evaluated. center : float @@ -485,7 +478,7 @@ def _lorentzian_eval( Evaluate a Lorentzian function. y = (area * width / pi) / ((x - center)^2 + width^2). All checks are handled in the calling function. - args: + Args: x : np.ndarray 1D array of x values where the Lorentzian is evaluated. center : float @@ -506,7 +499,7 @@ def _voigt_eval( ) -> np.ndarray: """ Evaluate a Voigt profile function using scipy's voigt_profile. - args: + Args: x : np.ndarray 1D array of x values where the Voigt profile is evaluated. center : float @@ -531,7 +524,7 @@ def _check_width_thresholds( """ Helper function to check and warn if components are wide compared to the span of the data, or narrow compared to the spacing. In both cases, the convolution accuracy may be compromised. - args: + Args: model : SampleModel or ModelComponent The model to check. dx : float @@ -595,3 +588,42 @@ def _find_delta_components( if isinstance(model, SampleModel): return [c for c in model.components if isinstance(c, DeltaFunction)] return [] + + +def _create_dense_grid( + x: np.ndarray, upsample_factor: int = 5, extension_factor: float = 0.2 +) -> np.ndarray: + """ + Create a dense grid by upsampling and extending the input x array. + + Args: + x : np.ndarray + 1D array of x values. + upsample_factor : int, optional + The factor by which to upsample the input data. Default is 5. + extension_factor : float, optional + The factor by which to extend the input data range. Default is 0.2. + Returns: + np.ndarray + The dense grid created by upsampling and extending x. + """ + if upsample_factor == 0: + # Check if the array is uniformly spaced. + x_diff = np.diff(x) + is_uniform = np.allclose(x_diff, x_diff[0]) + if not is_uniform: + raise ValueError( + "Input array `x` must be uniformly spaced if upsample_factor = 0." + ) + x_dense = x + else: + # Create an extended and upsampled x grid + x_min, x_max = x.min(), x.max() + span = x_max - x_min + extra = extension_factor * span + extended_min = x_min - extra + extended_max = x_max + extra + num_points = len(x) * upsample_factor + x_dense = np.linspace(extended_min, extended_max, num_points) + + return x_dense From df616b3d0ee0a668c262e9e13273f3e941e27e9e Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Tue, 4 Nov 2025 20:20:22 +0100 Subject: [PATCH 29/71] Rename x to energy, add auto method --- src/easydynamics/utils/convolution.py | 77 ++++++++++++++-------- tests/unit_tests/utils/test_convolution.py | 56 ++++++++-------- 2 files changed, 77 insertions(+), 56 deletions(-) diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py index 167a92e..d9b2d82 100644 --- a/src/easydynamics/utils/convolution.py +++ b/src/easydynamics/utils/convolution.py @@ -17,27 +17,28 @@ def convolution( - x: np.ndarray, + energy: np.ndarray, sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], offset: Optional[Union[Parameter, float, None]] = None, - method: Optional[str] = "analytical", + method: Optional[str] = "auto", upsample_factor: Optional[int] = 0, extension_factor: Optional[float] = 0.2, temperature: Optional[Union[Parameter, float, None]] = None, temperature_unit: Union[str, sc.Unit] = "K", - x_unit: Optional[Union[str, sc.Unit]] = "meV", + energy_unit: Optional[Union[str, sc.Unit]] = "meV", normalize_detailed_balance: Optional[bool] = True, ) -> np.ndarray: """ Calculate the convolution of a sample model with a resolution model using analytical expressions or numerical FFT. Accepts SampleModel or ModelComponent for both sample and resolution. - The analytical method silently falls back to numerical convolution if no analytical expression is found. + Analytical convolution is preferred when possible, otherwise numerical convolution is used. Detailed balancing is included if temperature is provided. This requires numerical convolution. + Args: - x : np.ndarray - 1D array of x values where the convolution is evaluated. + energy : np.ndarray + 1D array of energy transfer where the convolution is evaluated. sample_model : SampleModel or ModelComponent The sample model to be convolved. resolution_model : SampleModel or ModelComponent @@ -45,7 +46,7 @@ def convolution( offset : Parameter, float, or None, optional The offset to apply to the x values before convolution. method : str, optional - The convolution method to use: 'analytical' or 'numerical'. Default is 'analytical'. + The convolution method to use: 'auto', 'analytical' or 'numerical'. Default is 'auto'. upsample_factor : int, optional The factor by which to upsample the input data before numerical convolution. Default is 0 (no upsampling). extension_factor : float, optional @@ -54,20 +55,20 @@ def convolution( The temperature to use for detailed balance calculations. Default is None. temperature_unit : str or sc.Unit, optional The unit of the temperature parameter. Default is 'K'. - x_unit : str or sc.Unit, optional - The unit of the x parameter. Default is 'meV'. + energy_unit : str or sc.Unit, optional + The unit of the energy. Default is 'meV'. normalize_detailed_balance : bool, optional Whether to normalize the detailed balance factor. Default is True. """ # Input validation - if not isinstance(x, np.ndarray): + if not isinstance(energy, np.ndarray): raise TypeError( - f"`x` is an instance of {type(x).__name__}, but must be a numpy array." + f"`x` is an instance of {type(energy).__name__}, but must be a numpy array." ) - x = np.asarray(x, dtype=float) - if x.ndim != 1 or not np.all(np.isfinite(x)): + energy = np.asarray(energy, dtype=float) + if energy.ndim != 1 or not np.all(np.isfinite(energy)): raise ValueError("`x` must be a 1D finite array.") if not isinstance(sample_model, (SampleModel, ModelComponent)): @@ -107,10 +108,22 @@ def convolution( raise ValueError("extension_factor must be a non-negative float.") if temperature is not None: - if x_unit is None: - raise ValueError("x_unit must be provided when temperature is specified.") - if not isinstance(x_unit, (str, sc.Unit)): - raise TypeError(f"Expected x_unit to be str or sc.Unit, got {type(x_unit)}") + if energy_unit is None: + raise ValueError( + "energy_unit must be provided when temperature is specified." + ) + if not isinstance(energy_unit, (str, sc.Unit)): + raise TypeError( + f"Expected energy_unit to be str or sc.Unit, got {type(energy_unit)}" + ) + + use_numerical_convolution_as_fallback = False + if method == "auto": + if temperature is not None: + method = "numerical" + else: + method = "analytical" + use_numerical_convolution_as_fallback = True if method == "analytical": if temperature is not None: @@ -118,16 +131,17 @@ def convolution( "Analytical convolution is not supported with detailed balance. Set method to 'numerical' instead or set the temperature to None." ) return _analytical_convolution( - x=x, + x=energy, sample_model=sample_model, resolution_model=resolution_model, offset_float=offset_float, + use_numerical_convolution_as_fallback=use_numerical_convolution_as_fallback, upsample_factor=upsample_factor, extension_factor=extension_factor, ) elif method == "numerical": return _numerical_convolution( - x=x, + x=energy, sample_model=sample_model, resolution_model=resolution_model, offset_float=offset_float, @@ -135,7 +149,7 @@ def convolution( extension_factor=extension_factor, temperature=temperature, temperature_unit=temperature_unit, - x_unit=x_unit, + x_unit=energy_unit, normalize_detailed_balance=normalize_detailed_balance, ) else: @@ -285,6 +299,7 @@ def _analytical_convolution( sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], offset_float: float = 0.0, + use_numerical_convolution_as_fallback: bool = False, upsample_factor: int = 5, extension_factor: float = 0.2, ) -> np.ndarray: @@ -344,14 +359,20 @@ def _analytical_convolution( not_analytical_components.add_component(r) if not_analytical_components: - total += _numerical_convolution( - x=x, - sample_model=s, # single component - resolution_model=not_analytical_components, - offset_float=offset_float, - upsample_factor=upsample_factor, - extension_factor=extension_factor, - ) + if use_numerical_convolution_as_fallback: + total += _numerical_convolution( + x=x, + sample_model=s, # single component + resolution_model=not_analytical_components, + offset_float=offset_float, + upsample_factor=upsample_factor, + extension_factor=extension_factor, + ) + else: + raise ValueError( + f"Could not find analytical convolution for sample component '{s.name}' with resolution model '{not_analytical_components.name}'. " + "Set method to 'auto' or 'numerical'." + ) return total diff --git a/tests/unit_tests/utils/test_convolution.py b/tests/unit_tests/utils/test_convolution.py index 69957da..3424853 100644 --- a/tests/unit_tests/utils/test_convolution.py +++ b/tests/unit_tests/utils/test_convolution.py @@ -84,7 +84,7 @@ def test_components_gauss_gauss( # THEN calculated_convolution = convolution( - x=x, + energy=x, sample_model=sample_gauss, resolution_model=resolution_gauss, offset=offset_obj, @@ -131,7 +131,7 @@ def test_components_DHO_gauss( # THEN calculated_convolution = convolution( - x=x, + energy=x, sample_model=sample_dho, resolution_model=resolution_gauss, offset=offset_obj, @@ -176,7 +176,7 @@ def test_components_lorentzian_lorentzian( # THEN calculated_convolution = convolution( - x=x, + energy=x, sample_model=sample_lorentzian, resolution_model=resolution_lorentzian, offset=offset_obj, @@ -248,7 +248,7 @@ def test_components_gauss_lorentzian( # THEN calculated_convolution = convolution( - x=x, + energy=x, sample_model=sample, resolution_model=resolution, offset=offset_obj, @@ -312,7 +312,7 @@ def test_components_delta_gauss( # THEN calculated_convolution = convolution( - x=x, + energy=x, sample_model=sample, resolution_model=resolution, offset=offset_obj, @@ -362,7 +362,7 @@ def test_model_gauss_gauss_resolution_gauss( # THEN calculated_convolution = convolution( - x=x, + energy=x, sample_model=sample_model, resolution_model=resolution_model, offset=offset_obj, @@ -427,7 +427,7 @@ def test_model_lorentzian_delta_resolution_gauss( # THEN x = np.linspace(-10, 10, 20001) calculated_convolution = convolution( - x=x, + energy=x, sample_model=sample, resolution_model=resolution_model, offset=offset_obj, @@ -479,7 +479,7 @@ def test_numerical_convolve_with_temperature( # THEN calculated_convolution = convolution( - x=x, + energy=x, sample_model=sample_model, resolution_model=resolution_model, method="numerical", @@ -517,7 +517,7 @@ def test_numerical_convolve_x_length_even_and_odd( # WHEN THEN calculated_convolution = convolution( - x=x, + energy=x, sample_model=sample_model, resolution_model=resolution_model, method="numerical", @@ -526,7 +526,7 @@ def test_numerical_convolve_x_length_even_and_odd( # EXPECT expected_convolution = convolution( - x=x, + energy=x, sample_model=sample_model, resolution_model=resolution_model, method="analytical", @@ -548,7 +548,7 @@ def test_numerical_convolve_upsample_factor( "Test numerical convolution with different upsample factors." # WHEN THEN calculated_convolution = convolution( - x=x, + energy=x, sample_model=sample_model, resolution_model=resolution_model, method="numerical", @@ -557,7 +557,7 @@ def test_numerical_convolve_upsample_factor( # EXPECT expected_convolution = convolution( - x=x, + energy=x, sample_model=sample_model, resolution_model=resolution_model, method="analytical", @@ -589,7 +589,7 @@ def test_numerical_convolve_x_not_symmetric( # THEN calculated_convolution = convolution( - x=x, + energy=x, sample_model=sample_model, resolution_model=resolution_model, method="numerical", @@ -598,7 +598,7 @@ def test_numerical_convolve_x_not_symmetric( # EXPECT expected_convolution = convolution( - x=x, + energy=x, sample_model=sample_model, resolution_model=resolution_model, method="analytical", @@ -620,7 +620,7 @@ def test_numerical_convolve_x_not_uniform(self, sample_model, resolution_model): # THEN calculated_convolution = convolution( - x=x_non_uniform, + energy=x_non_uniform, sample_model=sample_model, resolution_model=resolution_model, method="numerical", @@ -629,7 +629,7 @@ def test_numerical_convolve_x_not_uniform(self, sample_model, resolution_model): # EXPECT expected_convolution = convolution( - x=x_non_uniform, + energy=x_non_uniform, sample_model=sample_model, resolution_model=resolution_model, method="analytical", @@ -654,7 +654,7 @@ def test_analytical_convolution_fails_with_detailed_balance( match="Analytical convolution is not supported with detailed balance.", ): convolution( - x=x, + energy=x, sample_model=sample_model, resolution_model=resolution_model, method="analytical", @@ -670,7 +670,7 @@ def test_convolution_only_accepts_analytical_and_numerical_methods( match="Unknown convolution method: unknown_method. Choose from 'analytical', or 'numerical'.", ): convolution( - x=x, + energy=x, sample_model=sample_model, resolution_model=resolution_model, method="unknown_method", @@ -680,21 +680,21 @@ def test_x_must_be_1d_finite_array(self, sample_model, resolution_model): # WHEN THEN EXPECT with pytest.raises(ValueError, match="`x` must be a 1D finite array."): convolution( - x=np.array([[1, 2], [3, 4]]), + energy=np.array([[1, 2], [3, 4]]), sample_model=sample_model, resolution_model=resolution_model, ) with pytest.raises(ValueError, match="`x` must be a 1D finite array."): convolution( - x=np.array([1, 2, np.nan]), + energy=np.array([1, 2, np.nan]), sample_model=sample_model, resolution_model=resolution_model, ) with pytest.raises(ValueError, match="`x` must be a 1D finite array."): convolution( - x=np.array([1, 2, np.inf]), + energy=np.array([1, 2, np.inf]), sample_model=sample_model, resolution_model=resolution_model, ) @@ -711,7 +711,7 @@ def test_numerical_convolve_requires_uniform_grid_if_no_upsample( match="Input array `x` must be uniformly spaced if upsample_factor = 0.", ): convolution( - x=x, + energy=x, sample_model=sample_model, resolution_model=resolution_model, method="numerical", @@ -727,7 +727,7 @@ def test_sample_model_must_have_components(self, resolution_model): ValueError, match="SampleModel must have at least one component." ): convolution( - x=np.array([0, 1, 2]), + energy=np.array([0, 1, 2]), sample_model=sample_model, resolution_model=resolution_model, ) @@ -741,7 +741,7 @@ def test_resolution_model_must_have_components(self, sample_model): ValueError, match="ResolutionModel must have at least one component." ): convolution( - x=np.array([0, 1, 2]), + energy=np.array([0, 1, 2]), sample_model=sample_model, resolution_model=resolution_model, ) @@ -762,7 +762,7 @@ def test_numerical_convolution_wide_sample_peak_gives_warning( match=r"The width of the sample model component ", ): convolution( - x=x, + energy=x, sample_model=sample, resolution_model=resolution_model, method="numerical", @@ -788,7 +788,7 @@ def test_numerical_convolution_wide_resolution_peak_gives_warning( match=r"The width of the resolution model component 'ResolutionGauss' \(1.9\) is large", ): convolution( - x=x, + energy=x, sample_model=sample_model, resolution_model=resolution, method="numerical", @@ -812,7 +812,7 @@ def test_numerical_convolution_narrow_sample_peak_gives_warning( match=r"The width of the sample model component 'SampleGauss' \(0.001\) is small", ): convolution( - x=x, + energy=x, sample_model=sample, resolution_model=resolution_model, method="numerical", @@ -838,7 +838,7 @@ def test_numerical_convolution_narrow_resolution_peak_gives_warning( match=r"The width of the resolution model component 'ResolutionGauss' \(0.001\) is small", ): convolution( - x=x, + energy=x, sample_model=sample_model, resolution_model=resolution, method="numerical", From 60b77b06519b8bee369632feb7249963e44e95fb Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Tue, 4 Nov 2025 20:33:40 +0100 Subject: [PATCH 30/71] Add example --- src/easydynamics/utils/convolution.py | 31 +++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py index d9b2d82..003b0df 100644 --- a/src/easydynamics/utils/convolution.py +++ b/src/easydynamics/utils/convolution.py @@ -32,8 +32,30 @@ def convolution( """ Calculate the convolution of a sample model with a resolution model using analytical expressions or numerical FFT. Accepts SampleModel or ModelComponent for both sample and resolution. - Analytical convolution is preferred when possible, otherwise numerical convolution is used. - Detailed balancing is included if temperature is provided. This requires numerical convolution. + If method is 'auto', analytical convolution is preferred when possible, otherwise numerical convolution is used. + Detailed balancing is included if temperature is provided. This requires numerical convolution and that the units + of energy and temperature are provided. An error will be raised if the units are not compatible. + The calculated model is shifted by the specified offset. + + Examples: + energy = np.linspace(-10, 10, 100) + sample = SampleModel() + sample.add_component(Gaussian(name="SampleGaussian", area=1.0, center=0.1, width=1.0)) + resolution = Gaussian(name="ResolutionGaussian", area=1.0, center=0.0, width=0.5) + result = convolution(energy, sample, resolution, offset=0.2) + + energy = np.linspace(-10, 10, 100) + sample = SampleModel() + sample.add_component(Gaussian(name="Gaussian", area=1.0, center=0.1, width=1.0)) + sample.add_component(DampedHarmonicOscillator(name="DHO", area=2.0, center=1.5, width=0.2)) + sample.add_component(DeltaFunction(name="Delta", area=0.5, center=0.0)) + + resolution = SampleModel() + resolution.add_component(Gaussian(name="ResolutionGaussian", area=0.8, center=0.0, width=0.5)) + resolution.add_component(Lorentzian(name="ResolutionLorentzian", area=0.2, center=0.1, width=0.3)) + + result_auto = convolution(energy, sample, resolution, offset=0.2, method='auto', upsample_factor=5, extension_factor=0.2) + result_numerical = convolution(energy, sample, resolution, offset=0.2, method='numerical', upsample_factor=5, extension_factor=0.2) Args: @@ -402,6 +424,11 @@ def _try_analytic_pair( The resolution component to convolve with. off : float The offset to apply to the convolution. + + Returns: + Tuple[bool, np.ndarray]: + - bool: True if analytical convolution was computed, False otherwise + - np.ndarray: The convolution result if computed, or zeros if not handled """ # Delta functions if isinstance(sample_component, DeltaFunction) and isinstance( From 040c8c6539c9a3644195e03c47bdedade4c66310 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Tue, 4 Nov 2025 20:36:35 +0100 Subject: [PATCH 31/71] Fix a test --- examples/convolution.ipynb | 29 ++++--- tests/unit_tests/utils/test_convolution.py | 92 ++++++++++++---------- 2 files changed, 63 insertions(+), 58 deletions(-) diff --git a/examples/convolution.ipynb b/examples/convolution.ipynb index 7c55b22..4fa9ea6 100644 --- a/examples/convolution.ipynb +++ b/examples/convolution.ipynb @@ -40,21 +40,21 @@ "resolution_model.add_component(resolution_gaussian)\n", "resolution_model.add_component(resolution_lorentzian)\n", "\n", - "x=np.linspace(-2, 2, 100)\n", + "energy=np.linspace(-2, 2, 100)\n", "\n", "\n", "y = convolution(sample_model=sample_model,\n", " resolution_model=resolution_model,\n", - " x=x,\n", + " energy=energy,\n", " )\n", "\n", - "plt.plot(x, y, label='Convoluted Model')\n", + "plt.plot(energy, y, label='Convoluted Model')\n", "plt.xlabel('Energy (meV)')\n", "plt.ylabel('Intensity (arb. units)')\n", "plt.title('Convolution of Sample Model with Resolution Model')\n", "\n", - "plt.plot(x, sample_model.evaluate(x), label='Sample Model', linestyle='--')\n", - "plt.plot(x, resolution_model.evaluate(x), label='Resolution Model', linestyle=':')\n", + "plt.plot(energy, sample_model.evaluate(energy), label='Sample Model', linestyle='--')\n", + "plt.plot(energy, resolution_model.evaluate(energy), label='Resolution Model', linestyle=':')\n", "\n", "\n", "plt.legend()\n", @@ -85,7 +85,7 @@ "resolution_model.add_component(resolution_gaussian)\n", "resolution_model.add_component(resolution_lorentzian)\n", "\n", - "x=np.linspace(-2, 2, 100)\n", + "energy=np.linspace(-2, 2, 100)\n", "\n", "\n", "temperature = 15.0 # Temperature in Kelvin\n", @@ -98,25 +98,24 @@ "\n", "y = convolution(sample_model=sample_model,\n", " resolution_model=resolution_model,\n", - " x=x,\n", - " offset = offset,\n", - " method = \"numerical\",\n", - " upsample_factor = upsample_factor,\n", - " extension_factor = extension_factor,\n", + " energy=energy,\n", + " offset=offset,\n", + " method=\"auto\",\n", + " upsample_factor=upsample_factor,\n", + " extension_factor=extension_factor,\n", " temperature=temperature,\n", " normalize_detailed_balance=True,\n", " )\n", "\n", - "plt.plot(x, y, label='Convoluted Model')\n", + "plt.plot(energy, y, label='Convoluted Model')\n", "\n", - "plt.plot(x, sample_model.evaluate(x-offset)*detailed_balance_factor(x-offset, temperature), label='Sample Model with DB', linestyle='--')\n", + "plt.plot(energy, sample_model.evaluate(energy-offset)*detailed_balance_factor(energy-offset, temperature), label='Sample Model with DB', linestyle='--')\n", "\n", - "plt.plot(x, resolution_model.evaluate(x), label='Resolution Model', linestyle=':')\n", + "plt.plot(energy, resolution_model.evaluate(energy ), label='Resolution Model', linestyle=':')\n", "plt.title('Convolution of Sample Model with Resolution Model with detailed balancing')\n", "\n", "plt.legend()\n", "plt.ylim(0,2.5)\n", - "\n", "\n" ] } diff --git a/tests/unit_tests/utils/test_convolution.py b/tests/unit_tests/utils/test_convolution.py index 3424853..f1d1c86 100644 --- a/tests/unit_tests/utils/test_convolution.py +++ b/tests/unit_tests/utils/test_convolution.py @@ -51,7 +51,7 @@ def other_lorentzian_component(self): return Lorentzian(center=0.2, width=0.4, area=3.0) @pytest.fixture - def x(self): + def energy(self): return np.linspace(-50, 50, 50001) # Test convolution of components @@ -69,7 +69,7 @@ def x(self): ) def test_components_gauss_gauss( self, - x, + energy, gaussian_component, other_gaussian_component, offset_obj, @@ -84,7 +84,7 @@ def test_components_gauss_gauss( # THEN calculated_convolution = convolution( - energy=x, + energy=energy, sample_model=sample_gauss, resolution_model=resolution_gauss, offset=offset_obj, @@ -102,7 +102,7 @@ def test_components_gauss_gauss( ) expected_result = ( expected_area - * np.exp(-0.5 * ((x - expected_center) / expected_width) ** 2) + * np.exp(-0.5 * ((energy - expected_center) / expected_width) ** 2) / (np.sqrt(2 * np.pi) * expected_width) ) @@ -117,11 +117,9 @@ def test_components_gauss_gauss( ], ids=["none", "float", "parameter"], ) - @pytest.mark.parametrize( - "method", ["analytical", "numerical"], ids=["analytical", "numerical"] - ) + @pytest.mark.parametrize("method", ["auto", "numerical"], ids=["auto", "numerical"]) def test_components_DHO_gauss( - self, x, gaussian_component, offset_obj, expected_shift, method + self, energy, gaussian_component, offset_obj, expected_shift, method ): "Test convolution of DHO sample and Gaussian resolution components without SampleModel." "Test with different offset types and methods." @@ -131,7 +129,7 @@ def test_components_DHO_gauss( # THEN calculated_convolution = convolution( - energy=x, + energy=energy, sample_model=sample_dho, resolution_model=resolution_gauss, offset=offset_obj, @@ -140,10 +138,10 @@ def test_components_DHO_gauss( # EXPECT # no simple analytical form, so compute expected result via direct convolution - sample_values = sample_dho.evaluate(x - expected_shift) - resolution_values = resolution_gauss.evaluate(x) + sample_values = sample_dho.evaluate(energy - expected_shift) + resolution_values = resolution_gauss.evaluate(energy) expected_result = fftconvolve(sample_values, resolution_values, mode="same") - expected_result *= x[1] - x[0] # normalize + expected_result *= energy[1] - energy[0] # normalize np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) @@ -161,7 +159,7 @@ def test_components_DHO_gauss( ) def test_components_lorentzian_lorentzian( self, - x, + energy, lorentzian_component, other_lorentzian_component, offset_obj, @@ -176,7 +174,7 @@ def test_components_lorentzian_lorentzian( # THEN calculated_convolution = convolution( - energy=x, + energy=energy, sample_model=sample_lorentzian, resolution_model=resolution_lorentzian, offset=offset_obj, @@ -199,7 +197,7 @@ def test_components_lorentzian_lorentzian( expected_area * expected_width / np.pi - / ((x - expected_center) ** 2 + expected_width**2) + / ((energy - expected_center) ** 2 + expected_width**2) ) np.testing.assert_allclose( @@ -228,7 +226,7 @@ def test_components_lorentzian_lorentzian( ) def test_components_gauss_lorentzian( self, - x, + energy, gaussian_component, lorentzian_component, offset_obj, @@ -248,7 +246,7 @@ def test_components_gauss_lorentzian( # THEN calculated_convolution = convolution( - energy=x, + energy=energy, sample_model=sample, resolution_model=resolution, offset=offset_obj, @@ -268,7 +266,7 @@ def test_components_gauss_lorentzian( ) expected_result = expected_area * voigt_profile( - x - expected_center, + energy - expected_center, gaussian_width, lorentzian_width, ) @@ -298,7 +296,13 @@ def test_components_gauss_lorentzian( ids=["gauss_sample__delta_resolution", "delta_sample__gauss_resolution"], ) def test_components_delta_gauss( - self, x, gaussian_component, offset_obj, expected_shift, method, sample_is_gauss + self, + energy, + gaussian_component, + offset_obj, + expected_shift, + method, + sample_is_gauss, ): "Test convolution of Delta function sample and Gaussian resolution components without SampleModel." "Test with different offset types and methods." @@ -312,7 +316,7 @@ def test_components_delta_gauss( # THEN calculated_convolution = convolution( - energy=x, + energy=energy, sample_model=sample, resolution_model=resolution, offset=offset_obj, @@ -325,7 +329,7 @@ def test_components_delta_gauss( width = sample.width.value if sample_is_gauss else resolution.width.value expected_result = ( expected_area - * np.exp(-0.5 * ((x - expected_center) / width) ** 2) + * np.exp(-0.5 * ((energy - expected_center) / width) ** 2) / (np.sqrt(2 * np.pi) * width) ) @@ -346,7 +350,7 @@ def test_components_delta_gauss( ) def test_model_gauss_gauss_resolution_gauss( self, - x, + energy, sample_model, resolution_model, offset_obj, @@ -362,7 +366,7 @@ def test_model_gauss_gauss_resolution_gauss( # THEN calculated_convolution = convolution( - energy=x, + energy=energy, sample_model=sample_model, resolution_model=resolution_model, offset=offset_obj, @@ -388,9 +392,9 @@ def test_model_gauss_gauss_resolution_gauss( ) expected_result = expected_area1 * np.exp( - -0.5 * ((x - expected_center1) / expected_width1) ** 2 + -0.5 * ((energy - expected_center1) / expected_width1) ** 2 ) / (np.sqrt(2 * np.pi) * expected_width1) + expected_area2 * np.exp( - -0.5 * ((x - expected_center2) / expected_width2) ** 2 + -0.5 * ((energy - expected_center2) / expected_width2) ** 2 ) / (np.sqrt(2 * np.pi) * expected_width2) np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) @@ -408,7 +412,7 @@ def test_model_gauss_gauss_resolution_gauss( ) def test_model_lorentzian_delta_resolution_gauss( self, - x, + energy, method, lorentzian_component, resolution_model, @@ -425,9 +429,9 @@ def test_model_lorentzian_delta_resolution_gauss( sample.add_component(sample_delta) # THEN - x = np.linspace(-10, 10, 20001) + energy = np.linspace(-10, 10, 20001) calculated_convolution = convolution( - energy=x, + energy=energy, sample_model=sample, resolution_model=resolution_model, offset=offset_obj, @@ -448,7 +452,7 @@ def test_model_lorentzian_delta_resolution_gauss( + expected_shift ) expected_voigt = expected_voigt_area * voigt_profile( - x - expected_voigt_center, + energy - expected_voigt_center, gaussian_component.width.value, lorentzian_component.width.value, ) @@ -459,7 +463,9 @@ def test_model_lorentzian_delta_resolution_gauss( expected_gauss_width = gaussian_component.width.value expected_gauss = ( expected_gauss_area - * np.exp(-0.5 * ((x - (expected_gauss_center)) / expected_gauss_width) ** 2) + * np.exp( + -0.5 * ((energy - (expected_gauss_center)) / expected_gauss_width) ** 2 + ) / (np.sqrt(2 * np.pi) * expected_gauss_width) ) expected_result = expected_voigt + expected_gauss @@ -471,7 +477,7 @@ def test_model_lorentzian_delta_resolution_gauss( ) def test_numerical_convolve_with_temperature( - self, x, sample_model, resolution_model + self, energy, sample_model, resolution_model ): "Test numerical convolution with detailed balance correction." # WHEN @@ -479,7 +485,7 @@ def test_numerical_convolve_with_temperature( # THEN calculated_convolution = convolution( - energy=x, + energy=energy, sample_model=sample_model, resolution_model=resolution_model, method="numerical", @@ -487,13 +493,13 @@ def test_numerical_convolve_with_temperature( temperature=temperature, ) - sample_with_db = sample_model.evaluate(x) * detailed_balance_factor( - energy=x, temperature=temperature + sample_with_db = sample_model.evaluate(energy) * detailed_balance_factor( + energy=energy, temperature=temperature ) - resolution = resolution_model.evaluate(x) + resolution = resolution_model.evaluate(energy) expected_convolution = fftconvolve(sample_with_db, resolution, mode="same") - expected_convolution *= [x[1] - x[0]] # normalize + expected_convolution *= [energy[1] - energy[0]] # normalize np.testing.assert_allclose( calculated_convolution, @@ -543,12 +549,12 @@ def test_numerical_convolve_x_length_even_and_odd( ids=["no_upsample", "upsample_2", "upsample_5", "upsample_10"], ) def test_numerical_convolve_upsample_factor( - self, x, upsample_factor, sample_model, resolution_model + self, energy, upsample_factor, sample_model, resolution_model ): "Test numerical convolution with different upsample factors." # WHEN THEN calculated_convolution = convolution( - energy=x, + energy=energy, sample_model=sample_model, resolution_model=resolution_model, method="numerical", @@ -557,7 +563,7 @@ def test_numerical_convolve_upsample_factor( # EXPECT expected_convolution = convolution( - energy=x, + energy=energy, sample_model=sample_model, resolution_model=resolution_model, method="analytical", @@ -644,7 +650,7 @@ def test_numerical_convolve_x_not_uniform(self, sample_model, resolution_model): # Test error handling def test_analytical_convolution_fails_with_detailed_balance( - self, x, sample_model, resolution_model + self, energy, sample_model, resolution_model ): # WHEN temperature = 300.0 @@ -654,7 +660,7 @@ def test_analytical_convolution_fails_with_detailed_balance( match="Analytical convolution is not supported with detailed balance.", ): convolution( - energy=x, + energy=energy, sample_model=sample_model, resolution_model=resolution_model, method="analytical", @@ -662,7 +668,7 @@ def test_analytical_convolution_fails_with_detailed_balance( ) def test_convolution_only_accepts_analytical_and_numerical_methods( - self, x, sample_model, resolution_model + self, energy, sample_model, resolution_model ): # WHEN THEN EXPECT with pytest.raises( @@ -670,7 +676,7 @@ def test_convolution_only_accepts_analytical_and_numerical_methods( match="Unknown convolution method: unknown_method. Choose from 'analytical', or 'numerical'.", ): convolution( - energy=x, + energy=energy, sample_model=sample_model, resolution_model=resolution_model, method="unknown_method", From 33729a7ee44bfd04311b4181f9f7677568395b92 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 5 Nov 2025 10:50:00 +0100 Subject: [PATCH 32/71] update numerical convolution --- src/easydynamics/utils/convolution.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py index 003b0df..bafaf5d 100644 --- a/src/easydynamics/utils/convolution.py +++ b/src/easydynamics/utils/convolution.py @@ -302,10 +302,19 @@ def _numerical_convolution( ) # if sample has deltas, convolve each delta with the resolution_model - for delta in sample_deltas: - convolved += delta.area.value * resolution_model.evaluate( - x - offset_float - delta.center.value - ) + # for delta in sample_deltas: + # convolved += delta.area.value * resolution_model.evaluate( + # x - offset_float - delta.center.value + # ) + + # for delta in sample_deltas: + + # _try_analytic_pair( + # x: np.ndarray, + # sample_component: ModelComponent, + # resolution_component: ModelComponent, + # off: float, + # ) -> Tuple[bool, np.ndarray]: # if resolution has deltas, convolve each delta with the sample_model for delta in resolution_deltas: From 176ce803a2bf53b7f3376621ccbf952563d473cb Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 5 Nov 2025 20:40:33 +0100 Subject: [PATCH 33/71] Polishing --- src/easydynamics/utils/convolution.py | 375 ++++++++++++--------- tests/unit_tests/utils/test_convolution.py | 14 +- 2 files changed, 226 insertions(+), 163 deletions(-) diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py index bafaf5d..a282be8 100644 --- a/src/easydynamics/utils/convolution.py +++ b/src/easydynamics/utils/convolution.py @@ -86,12 +86,12 @@ def convolution( # Input validation if not isinstance(energy, np.ndarray): raise TypeError( - f"`x` is an instance of {type(energy).__name__}, but must be a numpy array." + f"`energy` is an instance of {type(energy).__name__}, but must be a numpy array." ) energy = np.asarray(energy, dtype=float) if energy.ndim != 1 or not np.all(np.isfinite(energy)): - raise ValueError("`x` must be a 1D finite array.") + raise ValueError("`energy` must be a 1D finite array.") if not isinstance(sample_model, (SampleModel, ModelComponent)): raise TypeError( @@ -153,7 +153,7 @@ def convolution( "Analytical convolution is not supported with detailed balance. Set method to 'numerical' instead or set the temperature to None." ) return _analytical_convolution( - x=energy, + energy=energy, sample_model=sample_model, resolution_model=resolution_model, offset_float=offset_float, @@ -163,7 +163,7 @@ def convolution( ) elif method == "numerical": return _numerical_convolution( - x=energy, + energy=energy, sample_model=sample_model, resolution_model=resolution_model, offset_float=offset_float, @@ -171,17 +171,17 @@ def convolution( extension_factor=extension_factor, temperature=temperature, temperature_unit=temperature_unit, - x_unit=energy_unit, + energy_unit=energy_unit, normalize_detailed_balance=normalize_detailed_balance, ) else: raise ValueError( - f"Unknown convolution method: {method}. Choose from 'analytical', or 'numerical'." + f"Unknown convolution method: {method}. Choose from 'auto', 'analytical', or 'numerical'." ) def _numerical_convolution( - x: np.ndarray, + energy: np.ndarray, sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], offset_float: Optional[float] = 0.0, @@ -189,16 +189,17 @@ def _numerical_convolution( extension_factor: Optional[float] = 0.2, temperature: Optional[Union[Parameter, float]] = None, temperature_unit: Optional[Union[str, sc.Unit]] = "K", - x_unit: Optional[Union[str, sc.Unit]] = "meV", + energy_unit: Optional[Union[str, sc.Unit]] = "meV", normalize_detailed_balance: Optional[bool] = True, ) -> np.ndarray: """ Numerical convolution using FFT with optional upsampling + extended range. Includes detailed balance correction if temperature is provided. + Args: - x : np.ndarray - 1D array of x values where the convolution is evaluated. + energy : np.ndarray + 1D array of energy values where the convolution is evaluated. sample_model : SampleModel or ModelComponent The sample model to be convolved. resolution_model : SampleModel or ModelComponent @@ -213,120 +214,106 @@ def _numerical_convolution( The temperature to use for detailed balance correction. Default is None. temperature_unit : str or sc.Unit, optional The unit of the temperature parameter. Default is 'K'. - x_unit : str or sc.Unit, optional - The unit of the x parameter. Default is 'meV'. + energy_unit : str or sc.Unit, optional + The unit of the energy. Default is 'meV'. normalize_detailed_balance : bool, optional Whether to normalize the detailed balance factor. Default is True. Returns: np.ndarray - The convolved values evaluated at x. + The convolved values evaluated at energy. """ - # Build dense grid - x_dense = _create_dense_grid( - x, upsample_factor=upsample_factor, extension_factor=extension_factor + # Create a dense grid to improve accuracy. We evaluate on this grid and interpolate back to the original values at the end + energy_dense = _create_dense_grid( + energy, upsample_factor=upsample_factor, extension_factor=extension_factor ) - dx = x_dense[1] - x_dense[0] - span = x_dense.max() - x_dense.min() + energy_step = energy_dense[1] - energy_dense[0] + span = energy_dense.max() - energy_dense.min() # Handle offset for even length of x in convolution. # The convolution of two arrays of length N is of length 2N-1. When using 'same' mode, only the central N points are kept, # so the output has the same length as the input. # However, if N is even, the center falls between two points, leading to a half-bin offset. # For example, if N=4, the convolution has length 7, and when we select the 4 central points we either get # indices [2,3,4,5] or [1,2,3,4], both of which are offset by 0.5*dx from the true center at index 3.5. - if len(x_dense) % 2 == 0: - x_even_length_offset = -0.5 * dx + if len(energy_dense) % 2 == 0: + x_even_length_offset = -0.5 * energy_step else: x_even_length_offset = 0.0 # Handle the case when x is not symmetric around zero. The resolution is still centered around zero (or close to it), so it needs to be evaluated there. - if not np.isclose(x_dense.mean(), 0.0): - x_dense_centered = np.linspace(-0.5 * span, 0.5 * span, len(x_dense)) + if not np.isclose(energy_dense.mean(), 0.0): + energy_dense_centered = np.linspace(-0.5 * span, 0.5 * span, len(energy_dense)) else: - x_dense_centered = x_dense + energy_dense_centered = energy_dense # Give warnings if peaks are very wide or very narrow - _check_width_thresholds(sample_model, span, dx, "sample model") - _check_width_thresholds(resolution_model, span, dx, "resolution model") + _check_width_thresholds( + model=sample_model, + span=span, + energy_step=energy_step, + model_name="sample model", + ) + _check_width_thresholds( + model=resolution_model, + span=span, + energy_step=energy_step, + model_name="resolution model", + ) - # Evaluate on dense grid and interpolate at the end + # Evaluate sample model. Delta functions are handled separately for accuracy. if isinstance(sample_model, SampleModel): sample_vals = sample_model.evaluate_without_delta( - x_dense - offset_float - x_even_length_offset + energy_dense - offset_float - x_even_length_offset ) elif isinstance(sample_model, DeltaFunction): - sample_vals = np.zeros_like(x_dense) + sample_vals = np.zeros_like(energy_dense) else: sample_vals = sample_model.evaluate( - x_dense - offset_float - x_even_length_offset + energy_dense - offset_float - x_even_length_offset ) # Detailed balance correction if temperature is not None: detailed_balance_factor_correction = detailed_balance_factor( - energy=x_dense, + energy=energy_dense, temperature=temperature, - energy_unit=x_unit, + energy_unit=energy_unit, temperature_unit=temperature_unit, divide_by_temperature=normalize_detailed_balance, ) sample_vals *= detailed_balance_factor_correction - # Delta functions are handled separately for accuracy + # Evaluate resolution model if isinstance(resolution_model, SampleModel): - resolution_vals = resolution_model.evaluate_without_delta(x_dense_centered) + resolution_vals = resolution_model.evaluate_without_delta(energy_dense_centered) elif isinstance(resolution_model, DeltaFunction): - resolution_vals = np.zeros_like(x_dense_centered) + resolution_vals = np.zeros_like(energy_dense_centered) else: - resolution_vals = resolution_model.evaluate(x_dense_centered) + resolution_vals = resolution_model.evaluate(energy_dense_centered) # Convolution convolved = fftconvolve(sample_vals, resolution_vals, mode="same") - convolved *= dx # normalize + convolved *= energy_step # normalize if upsample_factor > 0: - # interpolate back to original x grid - convolved = np.interp(x, x_dense, convolved, left=0.0, right=0.0) - - # Add delta contributions on original grid - # collect deltas - sample_deltas = _find_delta_components(sample_model) - resolution_deltas = _find_delta_components(resolution_model) - - # error if both contain delta(s) - if sample_deltas and resolution_deltas: - raise ValueError( - "Both sample_model and resolution_model contain delta functions. " - "Their convolution is not defined." - ) - - # if sample has deltas, convolve each delta with the resolution_model - # for delta in sample_deltas: - # convolved += delta.area.value * resolution_model.evaluate( - # x - offset_float - delta.center.value - # ) - - # for delta in sample_deltas: - - # _try_analytic_pair( - # x: np.ndarray, - # sample_component: ModelComponent, - # resolution_component: ModelComponent, - # off: float, - # ) -> Tuple[bool, np.ndarray]: - - # if resolution has deltas, convolve each delta with the sample_model - for delta in resolution_deltas: - convolved += delta.area.value * sample_model.evaluate( - x - offset_float - delta.center.value - ) + # interpolate back to original energy grid + convolved = np.interp(energy, energy_dense, convolved, left=0.0, right=0.0) + + # Add delta function contributions + delta_contributions = _calculate_delta_contributions( + energy=energy, + sample_model=sample_model, + resolution_model=resolution_model, + offset_float=offset_float, + ) + convolved += delta_contributions return convolved def _analytical_convolution( - x: np.ndarray, + energy: np.ndarray, sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], offset_float: float = 0.0, @@ -350,6 +337,8 @@ def _analytical_convolution( The resolution model to convolve with. offset_float : float The offset to apply to the convolution. + use_numerical_convolution_as_fallback : bool + Whether to use numerical convolution as a fallback if analytical convolution is not possible. Default is False. Is True when method='auto'. upsample_factor : int, optional The factor by which to upsample the input data before numerical convolution. Improves accuracy at the cost of speed. Default is 5 extension_factor : float, optional @@ -375,25 +364,30 @@ def _analytical_convolution( else: resolution_components = [resolution_model] - total = np.zeros_like(x, dtype=float) + total = np.zeros_like(energy, dtype=float) - # loop over sample components, making a list of components that cannot be handled analytically - for s in sample_components: + # loop over sample components. Try to convolve each with all resolution components analytically + for sample_component in sample_components: not_analytical_components = SampleModel(name="not_analytical") # Go through resolution components, adding analytical contributions where possible, making a list of those that cannot be handled analytically - for r in resolution_components: - handled, contrib = _try_analytic_pair(x, s, r, offset_float) + for resolution_component in resolution_components: + handled, contrib = _try_analytic_pair( + energy=energy, + sample_component=sample_component, + resolution_component=resolution_component, + offset_float=offset_float, + ) if handled: total += contrib else: - not_analytical_components.add_component(r) + not_analytical_components.add_component(resolution_component) if not_analytical_components: if use_numerical_convolution_as_fallback: total += _numerical_convolution( - x=x, - sample_model=s, # single component + energy=energy, + sample_model=sample_component, resolution_model=not_analytical_components, offset_float=offset_float, upsample_factor=upsample_factor, @@ -401,7 +395,7 @@ def _analytical_convolution( ) else: raise ValueError( - f"Could not find analytical convolution for sample component '{s.name}' with resolution model '{not_analytical_components.name}'. " + f"Could not find analytical convolution for sample component '{sample_component.name}' with resolution model '{not_analytical_components.name}'. " "Set method to 'auto' or 'numerical'." ) @@ -409,11 +403,52 @@ def _analytical_convolution( # ---------------------- helpers & evals ----------------------- + + +def _create_dense_grid( + energy: np.ndarray, upsample_factor: int = 5, extension_factor: float = 0.2 +) -> np.ndarray: + """ + Create a dense grid by upsampling and extending the input energy array. + + Args: + energy : np.ndarray + 1D array of energy values. + upsample_factor : int, optional + The factor by which to upsample the input data. Default is 5. + extension_factor : float, optional + The factor by which to extend the input data range. Default is 0.2. + Returns: + np.ndarray + The dense grid created by upsampling and extending x. + """ + if upsample_factor == 0: + # Check if the array is uniformly spaced. + energy_diff = np.diff(energy) + is_uniform = np.allclose(energy_diff, energy_diff[0]) + if not is_uniform: + raise ValueError( + "Input array `energy` must be uniformly spaced if upsample_factor = 0." + ) + energy_dense = energy + else: + # Create an extended and upsampled energy grid + energy_min, energy_max = energy.min(), energy.max() + span = energy_max - energy_min + extra = extension_factor * span + extended_min = energy_min - extra + extended_max = energy_max + extra + num_points = len(energy) * upsample_factor + energy_dense = np.linspace(extended_min, extended_max, num_points) + + return energy_dense + + def _try_analytic_pair( - x: np.ndarray, - sample_component: ModelComponent, - resolution_component: ModelComponent, - off: float, + energy: np.ndarray, + sample_component: Union[ModelComponent, SampleModel], + resolution_component: Union[ModelComponent, SampleModel], + offset_float: float, ) -> Tuple[bool, np.ndarray]: """ Attempt an analytic convolution for component pair (sample_component, resolution_component). @@ -421,41 +456,43 @@ def _try_analytic_pair( The convolution of two gaussian components results in another gaussian component with width sqrt(w1^2 + w2^2). The convolution of two lorentzian components results in another lorentzian component with width w1 + w2. The convolution of a gaussian and a lorentzian results in a voigt profile. - The convolution of a delta function with any component results in the same component shifted by the delta center. + The convolution of a delta function with any component or SampleModel results in the same component or SampleModel shifted by the delta center. All areas are multiplied. + Args: - x : np.ndarray - 1D array of x values where the convolution is evaluated. - sample_component : ModelComponent + energy: np.ndarray + 1D array of energy values where the convolution is evaluated. + sample_component : Union[ModelComponent, SampleModel] The sample component to be convolved. - resolution_component : ModelComponent + resolution_component : Union[ModelComponent, SampleModel] The resolution component to convolve with. - off : float - The offset to apply to the convolution. + offset_float : float + The offset in energyto apply to the convolution. Returns: Tuple[bool, np.ndarray]: - bool: True if analytical convolution was computed, False otherwise - np.ndarray: The convolution result if computed, or zeros if not handled """ - # Delta functions + # Two delta functions is not meaningful if isinstance(sample_component, DeltaFunction) and isinstance( resolution_component, DeltaFunction ): raise ValueError("Convolution of two delta functions is not defined.") + # Delta function + anything --> anything, shifted by delta center with area A1 * A2 if isinstance(sample_component, DeltaFunction): return True, sample_component.area.value * resolution_component.evaluate( - x - sample_component.center.value - off + energy - sample_component.center.value - offset_float ) if isinstance(resolution_component, DeltaFunction): return True, resolution_component.area.value * sample_component.evaluate( - x - resolution_component.center.value - off + energy - resolution_component.center.value - offset_float ) - # Gaussian + Gaussian --> Gaussian with width sqrt(w1^2 + w2^2) + # Gaussian + Gaussian --> Gaussian with width sqrt(w1^2 + w2^2) and area A1 * A2 if isinstance(sample_component, Gaussian) and isinstance( resolution_component, Gaussian ): @@ -465,10 +502,10 @@ def _try_analytic_pair( area = sample_component.area.value * resolution_component.area.value center = ( sample_component.center.value + resolution_component.center.value - ) + off - return True, _gaussian_eval(x, center, width, area) + ) + offset_float + return True, _gaussian_eval(energy, center, width, area) - # Lorentzian + Lorentzian --> Lorentzian with width w1 + w2 + # Lorentzian + Lorentzian --> Lorentzian with width w1 + w2 and area A1 * A2 if isinstance(sample_component, Lorentzian) and isinstance( resolution_component, Lorentzian ): @@ -476,10 +513,10 @@ def _try_analytic_pair( area = sample_component.area.value * resolution_component.area.value center = ( sample_component.center.value + resolution_component.center.value - ) + off - return True, _lorentzian_eval(x, center, width, area) + ) + offset_float + return True, _lorentzian_eval(energy, center, width, area) - # Gaussian + Lorentzian --> Voigt + # Gaussian + Lorentzian --> Voigt with area A1 * A2 if ( isinstance(sample_component, Gaussian) and isinstance(resolution_component, Lorentzian) @@ -491,25 +528,25 @@ def _try_analytic_pair( gaussian, lorentzian = sample_component, resolution_component else: gaussian, lorentzian = resolution_component, sample_component - center = (gaussian.center.value + lorentzian.center.value) + off + center = (gaussian.center.value + lorentzian.center.value) + offset_float area = gaussian.area.value * lorentzian.area.value return True, _voigt_eval( - x, center, gaussian.width.value, lorentzian.width.value, area + energy, center, gaussian.width.value, lorentzian.width.value, area ) - return False, np.zeros_like(x, dtype=float) + return False, np.zeros_like(energy, dtype=float) def _gaussian_eval( - x: np.ndarray, center: float, width: float, area: float + energy: np.ndarray, center: float, width: float, area: float ) -> np.ndarray: """ Evaluate a Gaussian function. y = (area / (sqrt(2pi) * width)) * exp(-0.5 * ((x - center) / width)^2) All checks are handled in the calling function. Args: - x : np.ndarray - 1D array of x values where the Gaussian is evaluated. + energy : np.ndarray + 1D array of energy values where the Gaussian is evaluated. center : float The center of the Gaussian. width : float @@ -524,20 +561,20 @@ def _gaussian_eval( area * 1 / (np.sqrt(2 * np.pi) * width) - * np.exp(-0.5 * ((x - center) / width) ** 2) + * np.exp(-0.5 * ((energy - center) / width) ** 2) ) def _lorentzian_eval( - x: np.ndarray, center: float, width: float, area: float + energy: np.ndarray, center: float, width: float, area: float ) -> np.ndarray: """ Evaluate a Lorentzian function. y = (area * width / pi) / ((x - center)^2 + width^2). All checks are handled in the calling function. Args: - x : np.ndarray - 1D array of x values where the Lorentzian is evaluated. + energy : np.ndarray + 1D array of energy values where the Lorentzian is evaluated. center : float The center of the Lorentzian. width : float @@ -548,17 +585,17 @@ def _lorentzian_eval( np.ndarray The evaluated Lorentzian values at x. """ - return area * width / np.pi / ((x - center) ** 2 + width**2) + return area * width / np.pi / ((energy - center) ** 2 + width**2) def _voigt_eval( - x: np.ndarray, center: float, g_width: float, l_width: float, area: float + energy: np.ndarray, center: float, g_width: float, l_width: float, area: float ) -> np.ndarray: """ Evaluate a Voigt profile function using scipy's voigt_profile. Args: - x : np.ndarray - 1D array of x values where the Voigt profile is evaluated. + energy : np.ndarray + 1D array of energy values where the Voigt profile is evaluated. center : float The center of the Voigt profile. g_width : float @@ -572,11 +609,14 @@ def _voigt_eval( The evaluated Voigt profile values at x. """ - return area * voigt_profile(x - center, g_width, l_width) + return area * voigt_profile(energy - center, g_width, l_width) def _check_width_thresholds( - model: Union[SampleModel, ModelComponent], span: float, dx: float, model_type: str + model: Union[SampleModel, ModelComponent], + span: float, + energy_step: float, + model_name: str, ) -> None: """ Helper function to check and warn if components are wide compared to the span of the data, or narrow compared to the spacing. @@ -584,11 +624,11 @@ def _check_width_thresholds( Args: model : SampleModel or ModelComponent The model to check. - dx : float - The bin spacing of the input x array. + energy_step : float + The bin spacing of the energy array. span : float - The total span of the input x array. - model_type : str + The total span of the energy array. + model_name : str A string indicating whether the model is a 'sample model' or 'resolution model' for warning messages. returns: None @@ -616,14 +656,14 @@ def _check_width_thresholds( if hasattr(comp, "width"): if comp.width.value > LARGE_WIDTH_THRESHOLD * span: warnings.warn( - f"The width of the {model_type} component '{comp.name}' ({comp.width.value}) is large compared to the span of the input " + f"The width of the {model_name} component '{comp.name}' ({comp.width.value}) is large compared to the span of the input " f"array ({span}). This may lead to inaccuracies in the convolution. Increase extension_factor to improve accuracy.", UserWarning, ) - if comp.width.value < SMALL_WIDTH_THRESHOLD * dx: + if comp.width.value < SMALL_WIDTH_THRESHOLD * energy_step: warnings.warn( - f"The width of the {model_type} component '{comp.name}' ({comp.width.value}) is small compared to the spacing of the input " - f"array ({dx}). This may lead to inaccuracies in the convolution. Increase upsample_factor to improve accuracy.", + f"The width of the {model_name} component '{comp.name}' ({comp.width.value}) is small compared to the spacing of the input " + f"array ({energy_step}). This may lead to inaccuracies in the convolution. Increase upsample_factor to improve accuracy.", UserWarning, ) @@ -647,40 +687,63 @@ def _find_delta_components( return [] -def _create_dense_grid( - x: np.ndarray, upsample_factor: int = 5, extension_factor: float = 0.2 +def _calculate_delta_contributions( + energy: np.ndarray, + sample_model: Union[SampleModel, ModelComponent], + resolution_model: Union[SampleModel, ModelComponent], + offset_float: float, ) -> np.ndarray: """ - Create a dense grid by upsampling and extending the input x array. - + Calculate the contributions of delta functions in the convolution. Args: - x : np.ndarray - 1D array of x values. - upsample_factor : int, optional - The factor by which to upsample the input data. Default is 5. - extension_factor : float, optional - The factor by which to extend the input data range. Default is 0.2. + energy : np.ndarray + 1D array of energy values where the convolution is evaluated. + sample_model : SampleModel or ModelComponent + The sample model to be convolved. + resolution_model : SampleModel or ModelComponent + The resolution model to convolve with. + offset_float : float + The offset to apply to the convolution. Returns: np.ndarray - The dense grid created by upsampling and extending x. + The delta function contributions evaluated at energy. + + Raises: + ValueError + If both sample_model and resolution_model contain delta functions. """ - if upsample_factor == 0: - # Check if the array is uniformly spaced. - x_diff = np.diff(x) - is_uniform = np.allclose(x_diff, x_diff[0]) - if not is_uniform: - raise ValueError( - "Input array `x` must be uniformly spaced if upsample_factor = 0." - ) - x_dense = x - else: - # Create an extended and upsampled x grid - x_min, x_max = x.min(), x.max() - span = x_max - x_min - extra = extension_factor * span - extended_min = x_min - extra - extended_max = x_max + extra - num_points = len(x) * upsample_factor - x_dense = np.linspace(extended_min, extended_max, num_points) + delta_contributions = np.zeros_like(energy) + + # Add delta contributions on original grid + # collect deltas + sample_deltas = _find_delta_components(sample_model) + resolution_deltas = _find_delta_components(resolution_model) + + # error if both contain delta(s) + if sample_deltas and resolution_deltas: + raise ValueError( + "Both sample_model and resolution_model contain delta functions. " + "Their convolution is not defined." + ) + + # if sample has deltas, convolve each delta with the resolution_model + for delta in sample_deltas: + (_, delta_contribution) = _try_analytic_pair( + energy=energy, + sample_component=delta, + resolution_component=resolution_model, + offset_float=offset_float, + ) + delta_contributions += delta_contribution + + # if resolution has deltas, convolve each delta with the sample_model + for delta in resolution_deltas: + (_, delta_contribution) = _try_analytic_pair( + energy=energy, + sample_component=sample_model, + resolution_component=delta, + offset_float=offset_float, + ) + delta_contributions += delta_contribution - return x_dense + return delta_contributions diff --git a/tests/unit_tests/utils/test_convolution.py b/tests/unit_tests/utils/test_convolution.py index f1d1c86..70fb820 100644 --- a/tests/unit_tests/utils/test_convolution.py +++ b/tests/unit_tests/utils/test_convolution.py @@ -667,13 +667,13 @@ def test_analytical_convolution_fails_with_detailed_balance( temperature=temperature, ) - def test_convolution_only_accepts_analytical_and_numerical_methods( + def test_convolution_only_accepts_auto_analytical_and_numerical_methods( self, energy, sample_model, resolution_model ): # WHEN THEN EXPECT with pytest.raises( ValueError, - match="Unknown convolution method: unknown_method. Choose from 'analytical', or 'numerical'.", + match="Unknown convolution method: unknown_method. Choose from 'auto', 'analytical', or 'numerical'.", ): convolution( energy=energy, @@ -682,23 +682,23 @@ def test_convolution_only_accepts_analytical_and_numerical_methods( method="unknown_method", ) - def test_x_must_be_1d_finite_array(self, sample_model, resolution_model): + def test_energy_must_be_1d_finite_array(self, sample_model, resolution_model): # WHEN THEN EXPECT - with pytest.raises(ValueError, match="`x` must be a 1D finite array."): + with pytest.raises(ValueError, match="`energy` must be a 1D finite array."): convolution( energy=np.array([[1, 2], [3, 4]]), sample_model=sample_model, resolution_model=resolution_model, ) - with pytest.raises(ValueError, match="`x` must be a 1D finite array."): + with pytest.raises(ValueError, match="`energy` must be a 1D finite array."): convolution( energy=np.array([1, 2, np.nan]), sample_model=sample_model, resolution_model=resolution_model, ) - with pytest.raises(ValueError, match="`x` must be a 1D finite array."): + with pytest.raises(ValueError, match="`energy` must be a 1D finite array."): convolution( energy=np.array([1, 2, np.inf]), sample_model=sample_model, @@ -714,7 +714,7 @@ def test_numerical_convolve_requires_uniform_grid_if_no_upsample( # THEN EXPECT with pytest.raises( ValueError, - match="Input array `x` must be uniformly spaced if upsample_factor = 0.", + match="Input array `energy` must be uniformly spaced if upsample_factor = 0.", ): convolution( energy=x, From f24662fec6af10223713372b1b2d4d71f73a4105 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Thu, 13 Nov 2025 07:51:23 +0100 Subject: [PATCH 34/71] starting to refactor.... --- src/easydynamics/utils/convolution.py | 1444 +++++++++++++------------ 1 file changed, 733 insertions(+), 711 deletions(-) diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py index a282be8..6668fcd 100644 --- a/src/easydynamics/utils/convolution.py +++ b/src/easydynamics/utils/convolution.py @@ -1,5 +1,5 @@ import warnings -from typing import List, Optional, Tuple, Union +from typing import Optional, Union import numpy as np import scipp as sc @@ -7,7 +7,13 @@ from scipy.signal import fftconvolve from scipy.special import voigt_profile -from easydynamics.sample_model import DeltaFunction, Gaussian, Lorentzian, SampleModel +from easydynamics.sample_model import ( + DeltaFunction, + Gaussian, + Lorentzian, + SampleModel, + Voigt, +) from easydynamics.sample_model.components.model_component import ModelComponent from easydynamics.utils.detailed_balance import ( _detailed_balance_factor as detailed_balance_factor, @@ -16,734 +22,750 @@ Numerical = Union[float, int] -def convolution( - energy: np.ndarray, - sample_model: Union[SampleModel, ModelComponent], - resolution_model: Union[SampleModel, ModelComponent], - offset: Optional[Union[Parameter, float, None]] = None, - method: Optional[str] = "auto", - upsample_factor: Optional[int] = 0, - extension_factor: Optional[float] = 0.2, - temperature: Optional[Union[Parameter, float, None]] = None, - temperature_unit: Union[str, sc.Unit] = "K", - energy_unit: Optional[Union[str, sc.Unit]] = "meV", - normalize_detailed_balance: Optional[bool] = True, -) -> np.ndarray: - """ - Calculate the convolution of a sample model with a resolution model using analytical expressions or numerical FFT. - Accepts SampleModel or ModelComponent for both sample and resolution. - If method is 'auto', analytical convolution is preferred when possible, otherwise numerical convolution is used. - Detailed balancing is included if temperature is provided. This requires numerical convolution and that the units - of energy and temperature are provided. An error will be raised if the units are not compatible. - The calculated model is shifted by the specified offset. - - Examples: - energy = np.linspace(-10, 10, 100) - sample = SampleModel() - sample.add_component(Gaussian(name="SampleGaussian", area=1.0, center=0.1, width=1.0)) - resolution = Gaussian(name="ResolutionGaussian", area=1.0, center=0.0, width=0.5) - result = convolution(energy, sample, resolution, offset=0.2) - - energy = np.linspace(-10, 10, 100) - sample = SampleModel() - sample.add_component(Gaussian(name="Gaussian", area=1.0, center=0.1, width=1.0)) - sample.add_component(DampedHarmonicOscillator(name="DHO", area=2.0, center=1.5, width=0.2)) - sample.add_component(DeltaFunction(name="Delta", area=0.5, center=0.0)) - - resolution = SampleModel() - resolution.add_component(Gaussian(name="ResolutionGaussian", area=0.8, center=0.0, width=0.5)) - resolution.add_component(Lorentzian(name="ResolutionLorentzian", area=0.2, center=0.1, width=0.3)) - - result_auto = convolution(energy, sample, resolution, offset=0.2, method='auto', upsample_factor=5, extension_factor=0.2) - result_numerical = convolution(energy, sample, resolution, offset=0.2, method='numerical', upsample_factor=5, extension_factor=0.2) - - - Args: - energy : np.ndarray - 1D array of energy transfer where the convolution is evaluated. - sample_model : SampleModel or ModelComponent - The sample model to be convolved. - resolution_model : SampleModel or ModelComponent - The resolution model to convolve with. - offset : Parameter, float, or None, optional - The offset to apply to the x values before convolution. - method : str, optional - The convolution method to use: 'auto', 'analytical' or 'numerical'. Default is 'auto'. - upsample_factor : int, optional - The factor by which to upsample the input data before numerical convolution. Default is 0 (no upsampling). - extension_factor : float, optional - The factor by which to extend the input data range before numerical convolution. Default is 0.2. - temperature : Parameter, float, or None, optional - The temperature to use for detailed balance calculations. Default is None. - temperature_unit : str or sc.Unit, optional - The unit of the temperature parameter. Default is 'K'. - energy_unit : str or sc.Unit, optional - The unit of the energy. Default is 'meV'. - normalize_detailed_balance : bool, optional - Whether to normalize the detailed balance factor. Default is True. - """ - - # Input validation - if not isinstance(energy, np.ndarray): - raise TypeError( - f"`energy` is an instance of {type(energy).__name__}, but must be a numpy array." - ) - - energy = np.asarray(energy, dtype=float) - if energy.ndim != 1 or not np.all(np.isfinite(energy)): - raise ValueError("`energy` must be a 1D finite array.") +class Convolution: + def __init__(self): + pass + + # def _find_delta_components(self, + # model: Union[SampleModel, ModelComponent], + # ) -> List[DeltaFunction]: + # """Return a list of DeltaFunction instances contained in `model`. + + # Args: + # model : SampleModel or ModelComponent + # The model to search for DeltaFunction components. + # Returns: + # List[DeltaFunction] + # A list of DeltaFunction components found in the model. + # """ + # if isinstance(model, DeltaFunction): + # return [model] + # if isinstance(model, SampleModel): + # return [c for c in model.components if isinstance(c, DeltaFunction)] + # return [] + + # def _calculate_delta_contributions(self, + # energy: np.ndarray, + # sample_model: Union[SampleModel, ModelComponent], + # resolution_model: Union[SampleModel, ModelComponent], + # offset_float: float, + # ) -> np.ndarray: + # """ + # Calculate the contributions of delta functions in the convolution. + # Args: + # energy : np.ndarray + # 1D array of energy values where the convolution is evaluated. + # sample_model : SampleModel or ModelComponent + # The sample model to be convolved. + # resolution_model : SampleModel or ModelComponent + # The resolution model to convolve with. + # offset_float : float + # The offset to apply to the convolution. + # Returns: + # np.ndarray + # The delta function contributions evaluated at energy. + + # Raises: + # ValueError + # If both sample_model and resolution_model contain delta functions. + # """ + # delta_contributions = np.zeros_like(energy) + + # # Add delta contributions on original grid + # # collect deltas + # sample_deltas = self._find_delta_components(sample_model) + # resolution_deltas = self._find_delta_components(resolution_model) + + # # error if both contain delta(s) + # if sample_deltas and resolution_deltas: + # raise ValueError( + # "Both sample_model and resolution_model contain delta functions. " + # "Their convolution is not defined." + # ) + + # # if sample has deltas, convolve each delta with the resolution_model + # for delta in sample_deltas: + # (_, delta_contribution) = self.try_analytic_pair( + # energy=energy, + # sample_component=delta, + # resolution_component=resolution_model, + # offset_float=offset_float, + # ) + # delta_contributions += delta_contribution + + # # if resolution has deltas, convolve each delta with the sample_model + # for delta in resolution_deltas: + # (_, delta_contribution) = self.try_analytic_pair( + # energy=energy, + # sample_component=sample_model, + # resolution_component=delta, + # offset_float=offset_float, + # ) + # delta_contributions += delta_contribution + + # return delta_contributions + + +class AnalyticalConvolution: + def __init__(self): + pass + + def convolution( + self, + energy: np.ndarray, + sample_model: Union[SampleModel, ModelComponent], + resolution_model: Union[SampleModel, ModelComponent], + offset_float: float = 0.0, + ) -> np.ndarray: + """ + Convolve sample with resolution analytically if possible. Accepts SampleModel or single ModelComponent for each. + Possible analytical convolutions are any combination of delta functions, Gaussians, Lorentzians and Voigt profiles. + + Most validation happens in the main `convolution` function. + + Args: + x : np.ndarray + 1D array of x values where the convolution is evaluated. + sample_model : SampleModel or ModelComponent + The sample model to be convolved. + resolution_model : SampleModel or ModelComponent + The resolution model to convolve with. + offset_float : float + The offset to apply to the convolution. + Returns: + np.ndarray + The convolved values evaluated at x. + + Raises: + ValueError + If resolution_model contains delta functions. + ValueError + If component pair cannot be handled analytically. + + """ + + # prepare list of components + if isinstance(sample_model, SampleModel): + sample_components = sample_model.components + else: + sample_components = [sample_model] - if not isinstance(sample_model, (SampleModel, ModelComponent)): - raise TypeError( - f"`sample_model` is an instance of {type(sample_model).__name__}, but must be SampleModel or ModelComponent." - ) + if isinstance(resolution_model, SampleModel): + resolution_components = resolution_model.components + else: + resolution_components = [resolution_model] - if not isinstance(resolution_model, (SampleModel, ModelComponent)): - raise TypeError( - f"`resolution_model` is an instance of {type(resolution_model).__name__}, but must be SampleModel or ModelComponent." - ) + total = np.zeros_like(energy, dtype=float) - if isinstance(sample_model, SampleModel): - if not sample_model.components: - raise ValueError("SampleModel must have at least one component.") - - if isinstance(resolution_model, SampleModel): - if not resolution_model.components: - raise ValueError("ResolutionModel must have at least one component.") - - # Handle offset - if offset is None: - offset_float = 0.0 - elif isinstance(offset, Parameter): - offset_float = offset.value - elif isinstance(offset, Numerical): - offset_float = float(offset) - else: - raise TypeError( - f"Expected offset to be Parameter, number, or None, got {type(offset)}" - ) - - if not isinstance(upsample_factor, int) or upsample_factor < 0: - raise ValueError("upsample_factor must be a non-negative integer.") + for sample_component in sample_components: + # Go through resolution components, adding analytical contributions + for resolution_component in resolution_components: + contrib = self._try_analytic_pair( + energy=energy, + sample_component=sample_component, + resolution_component=resolution_component, + offset_float=offset_float, + ) + total += contrib - if not isinstance(extension_factor, float) or extension_factor < 0.0: - raise ValueError("extension_factor must be a non-negative float.") + return total + + def _try_analytic_pair( + self, + energy: np.ndarray, + sample_component: Union[ModelComponent, SampleModel], + resolution_component: ModelComponent, + offset_float: float, + ) -> np.ndarray: + """ + Attempt an analytic convolution for component pair (sample_component, resolution_component). + Returns (True, contribution) if handled, else (False, zeros). + The convolution of two gaussian components results in another gaussian component with width sqrt(w1^2 + w2^2). + The convolution of two lorentzian components results in another lorentzian component with width w1 + w2. + The convolution of a gaussian and a lorentzian results in a voigt profile. + The convolution of a delta function with any component or SampleModel results in the same component or SampleModel shifted by the delta center. + All areas are multiplied. + + + Args: + energy: np.ndarray + 1D array of energy values where the convolution is evaluated. + sample_component : Union[ModelComponent, SampleModel] + The sample component to be convolved. + resolution_component : Union[ModelComponent, SampleModel] + The resolution component to convolve with. + offset_float : float + The offset in energyto apply to the convolution. + + Returns: + np.ndarray: The convolution result + + Raises: + ValueError: If the component pair cannot be handled analytically. + """ + + # Delta function + anything --> anything, shifted by delta center with area A1 * A2 + if isinstance(sample_component, DeltaFunction): + return sample_component.area.value * resolution_component.evaluate( + energy - sample_component.center.value - offset_float + ) - if temperature is not None: - if energy_unit is None: - raise ValueError( - "energy_unit must be provided when temperature is specified." + # Gaussian + Gaussian --> Gaussian with width sqrt(w1^2 + w2^2) and area A1 * A2 + if isinstance(sample_component, Gaussian) and isinstance( + resolution_component, Gaussian + ): + width = np.sqrt( + sample_component.width.value**2 + resolution_component.width.value**2 ) - if not isinstance(energy_unit, (str, sc.Unit)): - raise TypeError( - f"Expected energy_unit to be str or sc.Unit, got {type(energy_unit)}" + area = sample_component.area.value * resolution_component.area.value + center = ( + sample_component.center.value + resolution_component.center.value + ) + offset_float + return self._gaussian_eval(energy, center, width, area) + + # Lorentzian + Lorentzian --> Lorentzian with width w1 + w2 and area A1 * A2 + if isinstance(sample_component, Lorentzian) and isinstance( + resolution_component, Lorentzian + ): + width = sample_component.width.value + resolution_component.width.value + area = sample_component.area.value * resolution_component.area.value + center = ( + sample_component.center.value + resolution_component.center.value + ) + offset_float + return self._lorentzian_eval(energy, center, width, area) + + # Gaussian + Lorentzian --> Voigt with area A1 * A2 + if ( + isinstance(sample_component, Gaussian) + and isinstance(resolution_component, Lorentzian) + ) or ( + isinstance(sample_component, Lorentzian) + and isinstance(resolution_component, Gaussian) + ): + if isinstance(sample_component, Gaussian): + gaussian, lorentzian = sample_component, resolution_component + else: + gaussian, lorentzian = resolution_component, sample_component + center = (gaussian.center.value + lorentzian.center.value) + offset_float + area = gaussian.area.value * lorentzian.area.value + return self._voigt_eval( + energy, center, gaussian.width.value, lorentzian.width.value, area ) - use_numerical_convolution_as_fallback = False - if method == "auto": - if temperature is not None: - method = "numerical" - else: - method = "analytical" - use_numerical_convolution_as_fallback = True - - if method == "analytical": - if temperature is not None: - raise ValueError( - "Analytical convolution is not supported with detailed balance. Set method to 'numerical' instead or set the temperature to None." - ) - return _analytical_convolution( - energy=energy, - sample_model=sample_model, - resolution_model=resolution_model, - offset_float=offset_float, - use_numerical_convolution_as_fallback=use_numerical_convolution_as_fallback, - upsample_factor=upsample_factor, - extension_factor=extension_factor, - ) - elif method == "numerical": - return _numerical_convolution( - energy=energy, - sample_model=sample_model, - resolution_model=resolution_model, - offset_float=offset_float, - upsample_factor=upsample_factor, - extension_factor=extension_factor, - temperature=temperature, - temperature_unit=temperature_unit, - energy_unit=energy_unit, - normalize_detailed_balance=normalize_detailed_balance, - ) - else: - raise ValueError( - f"Unknown convolution method: {method}. Choose from 'auto', 'analytical', or 'numerical'." + # Voigt + Lorentzian --> Voigt with area A1 * A2, Gaussian width unchanged, Lorentzian widths summed + if ( + isinstance(sample_component, Voigt) + and isinstance(resolution_component, Lorentzian) + ) or ( + isinstance(sample_component, Lorentzian) + and isinstance(resolution_component, Voigt) + ): + if isinstance(sample_component, Voigt): + voigt, lorentzian = sample_component, resolution_component + else: + voigt, lorentzian = resolution_component, sample_component + center = (voigt.center.value + lorentzian.center.value) + offset_float + area = voigt.area.value * lorentzian.area.value + g_width = voigt.g_width.value + l_width = voigt.l_width.value + lorentzian.width.value + return self._voigt_eval(energy, center, g_width, l_width, area) + + # Voigt + Gaussian --> Voigt with area A1 * A2, Lorentzian width unchanged, Gaussian widths summed in quadrature + if ( + isinstance(sample_component, Voigt) + and isinstance(resolution_component, Gaussian) + ) or ( + isinstance(sample_component, Gaussian) + and isinstance(resolution_component, Voigt) + ): + if isinstance(sample_component, Voigt): + voigt, gaussian = sample_component, resolution_component + else: + voigt, gaussian = resolution_component, sample_component + center = (voigt.center.value + gaussian.center.value) + offset_float + area = voigt.area.value * gaussian.area.value + l_width = voigt.l_width.value + g_width = np.sqrt(voigt.g_width.value**2 + gaussian.width.value**2) + return self._voigt_eval(energy, center, g_width, l_width, area) + + return ValueError( + f"Analytical convolution not implemented for component pair: {type(sample_component).__name__}, {type(resolution_component).__name__}" ) - -def _numerical_convolution( - energy: np.ndarray, - sample_model: Union[SampleModel, ModelComponent], - resolution_model: Union[SampleModel, ModelComponent], - offset_float: Optional[float] = 0.0, - upsample_factor: Optional[int] = 5, - extension_factor: Optional[float] = 0.2, - temperature: Optional[Union[Parameter, float]] = None, - temperature_unit: Optional[Union[str, sc.Unit]] = "K", - energy_unit: Optional[Union[str, sc.Unit]] = "meV", - normalize_detailed_balance: Optional[bool] = True, -) -> np.ndarray: - """ - Numerical convolution using FFT with optional upsampling + extended range. - Includes detailed balance correction if temperature is provided. - - - Args: - energy : np.ndarray - 1D array of energy values where the convolution is evaluated. - sample_model : SampleModel or ModelComponent - The sample model to be convolved. - resolution_model : SampleModel or ModelComponent - The resolution model to convolve with. - offset_float : float, or None, optional - The offset to apply to the input array. - upsample_factor : int, optional - The factor by which to upsample the input data before convolution. Default is 5. - extension_factor : float, optional - The factor by which to extend the input data range before convolution. Default is 0.2. - temperature : Parameter, float, or None, optional - The temperature to use for detailed balance correction. Default is None. - temperature_unit : str or sc.Unit, optional - The unit of the temperature parameter. Default is 'K'. - energy_unit : str or sc.Unit, optional - The unit of the energy. Default is 'meV'. - normalize_detailed_balance : bool, optional - Whether to normalize the detailed balance factor. Default is True. - Returns: - np.ndarray - The convolved values evaluated at energy. - """ - - # Create a dense grid to improve accuracy. We evaluate on this grid and interpolate back to the original values at the end - energy_dense = _create_dense_grid( - energy, upsample_factor=upsample_factor, extension_factor=extension_factor - ) - - energy_step = energy_dense[1] - energy_dense[0] - span = energy_dense.max() - energy_dense.min() - # Handle offset for even length of x in convolution. - # The convolution of two arrays of length N is of length 2N-1. When using 'same' mode, only the central N points are kept, - # so the output has the same length as the input. - # However, if N is even, the center falls between two points, leading to a half-bin offset. - # For example, if N=4, the convolution has length 7, and when we select the 4 central points we either get - # indices [2,3,4,5] or [1,2,3,4], both of which are offset by 0.5*dx from the true center at index 3.5. - if len(energy_dense) % 2 == 0: - x_even_length_offset = -0.5 * energy_step - else: - x_even_length_offset = 0.0 - - # Handle the case when x is not symmetric around zero. The resolution is still centered around zero (or close to it), so it needs to be evaluated there. - if not np.isclose(energy_dense.mean(), 0.0): - energy_dense_centered = np.linspace(-0.5 * span, 0.5 * span, len(energy_dense)) - else: - energy_dense_centered = energy_dense - - # Give warnings if peaks are very wide or very narrow - _check_width_thresholds( - model=sample_model, - span=span, - energy_step=energy_step, - model_name="sample model", - ) - _check_width_thresholds( - model=resolution_model, - span=span, - energy_step=energy_step, - model_name="resolution model", - ) - - # Evaluate sample model. Delta functions are handled separately for accuracy. - if isinstance(sample_model, SampleModel): - sample_vals = sample_model.evaluate_without_delta( - energy_dense - offset_float - x_even_length_offset - ) - elif isinstance(sample_model, DeltaFunction): - sample_vals = np.zeros_like(energy_dense) - else: - sample_vals = sample_model.evaluate( - energy_dense - offset_float - x_even_length_offset + def _gaussian_eval( + self, energy: np.ndarray, center: float, width: float, area: float + ) -> np.ndarray: + """ + Evaluate a Gaussian function. y = (area / (sqrt(2pi) * width)) * exp(-0.5 * ((x - center) / width)^2) + All checks are handled in the calling function. + + Args: + energy : np.ndarray + 1D array of energy values where the Gaussian is evaluated. + center : float + The center of the Gaussian. + width : float + The width (sigma) of the Gaussian. + area : float + The area under the Gaussian curve. + Returns: + np.ndarray + The evaluated Gaussian values at x. + """ + return ( + area + * 1 + / (np.sqrt(2 * np.pi) * width) + * np.exp(-0.5 * ((energy - center) / width) ** 2) ) - # Detailed balance correction - if temperature is not None: - detailed_balance_factor_correction = detailed_balance_factor( - energy=energy_dense, - temperature=temperature, - energy_unit=energy_unit, - temperature_unit=temperature_unit, - divide_by_temperature=normalize_detailed_balance, + def _lorentzian_eval( + self, energy: np.ndarray, center: float, width: float, area: float + ) -> np.ndarray: + """ + Evaluate a Lorentzian function. y = (area * width / pi) / ((x - center)^2 + width^2). + All checks are handled in the calling function. + + Args: + energy : np.ndarray + 1D array of energy values where the Lorentzian is evaluated. + center : float + The center of the Lorentzian. + width : float + The width (HWHM) of the Lorentzian. + area : float + The area under the Lorentzian. + Returns: + np.ndarray + The evaluated Lorentzian values at x. + """ + return area * width / np.pi / ((energy - center) ** 2 + width**2) + + def _voigt_eval( + self, + energy: np.ndarray, + center: float, + g_width: float, + l_width: float, + area: float, + ) -> np.ndarray: + """ + Evaluate a Voigt profile function using scipy's voigt_profile. + Args: + energy : np.ndarray + 1D array of energy values where the Voigt profile is evaluated. + center : float + The center of the Voigt profile. + g_width : float + The Gaussian width (sigma) of the Voigt profile. + l_width : float + The Lorentzian width (HWHM) of the Voigt profile. + area : float + The area under the Voigt profile. + Returns: + np.ndarray + The evaluated Voigt profile values at x. + """ + + return area * voigt_profile(energy - center, g_width, l_width) + + +class NumericalConvolution: + def __init__(self): + self._energy_dense = None + pass + + def convolution( + self, + energy: np.ndarray, + sample_model: Union[SampleModel, ModelComponent], + resolution_model: Union[SampleModel, ModelComponent], + offset_float: Optional[float] = 0.0, + upsample_factor: Optional[int] = 5, + extension_factor: Optional[float] = 0.2, + temperature: Optional[Union[Parameter, float]] = None, + temperature_unit: Optional[Union[str, sc.Unit]] = "K", + energy_unit: Optional[Union[str, sc.Unit]] = "meV", + normalize_detailed_balance: Optional[bool] = True, + ) -> np.ndarray: + """ + Numerical convolution using FFT with optional upsampling + extended range. + Includes detailed balance correction if temperature is provided. + + + Args: + energy : np.ndarray + 1D array of energy values where the convolution is evaluated. + sample_model : SampleModel or ModelComponent + The sample model to be convolved. + resolution_model : SampleModel or ModelComponent + The resolution model to convolve with. + offset_float : float, or None, optional + The offset to apply to the input array. + upsample_factor : int, optional + The factor by which to upsample the input data before convolution. Default is 5. + extension_factor : float, optional + The factor by which to extend the input data range before convolution. Default is 0.2. + temperature : Parameter, float, or None, optional + The temperature to use for detailed balance correction. Default is None. + temperature_unit : str or sc.Unit, optional + The unit of the temperature parameter. Default is 'K'. + energy_unit : str or sc.Unit, optional + The unit of the energy. Default is 'meV'. + normalize_detailed_balance : bool, optional + Whether to normalize the detailed balance factor. Default is True. + Returns: + np.ndarray + The convolved values evaluated at energy. + """ + + # Create a dense grid to improve accuracy. We evaluate on this grid and interpolate back to the original values at the end + energy_dense = self._create_dense_grid( + energy, upsample_factor=upsample_factor, extension_factor=extension_factor ) - sample_vals *= detailed_balance_factor_correction - - # Evaluate resolution model - if isinstance(resolution_model, SampleModel): - resolution_vals = resolution_model.evaluate_without_delta(energy_dense_centered) - elif isinstance(resolution_model, DeltaFunction): - resolution_vals = np.zeros_like(energy_dense_centered) - else: - resolution_vals = resolution_model.evaluate(energy_dense_centered) - - # Convolution - convolved = fftconvolve(sample_vals, resolution_vals, mode="same") - convolved *= energy_step # normalize - - if upsample_factor > 0: - # interpolate back to original energy grid - convolved = np.interp(energy, energy_dense, convolved, left=0.0, right=0.0) - - # Add delta function contributions - delta_contributions = _calculate_delta_contributions( - energy=energy, - sample_model=sample_model, - resolution_model=resolution_model, - offset_float=offset_float, - ) - convolved += delta_contributions - - return convolved - - -def _analytical_convolution( - energy: np.ndarray, - sample_model: Union[SampleModel, ModelComponent], - resolution_model: Union[SampleModel, ModelComponent], - offset_float: float = 0.0, - use_numerical_convolution_as_fallback: bool = False, - upsample_factor: int = 5, - extension_factor: float = 0.2, -) -> np.ndarray: - """ - Convolve sample with resolution analytically if possible. Accepts SampleModel or single ModelComponent for each. - Possible analytical convolutions are any combination of delta functions, Gaussians, and Lorentzians. - Falls back to numerical convolution for other pairs of functions - - Most validation happens in the main `convolution` function. - - Args: - x : np.ndarray - 1D array of x values where the convolution is evaluated. - sample_model : SampleModel or ModelComponent - The sample model to be convolved. - resolution_model : SampleModel or ModelComponent - The resolution model to convolve with. - offset_float : float - The offset to apply to the convolution. - use_numerical_convolution_as_fallback : bool - Whether to use numerical convolution as a fallback if analytical convolution is not possible. Default is False. Is True when method='auto'. - upsample_factor : int, optional - The factor by which to upsample the input data before numerical convolution. Improves accuracy at the cost of speed. Default is 5 - extension_factor : float, optional - The factor by which to extend the input data range before numerical convolution. Improves accuracy at the edges of the data. Default is 0.2 - Returns: - np.ndarray - The convolved values evaluated at x. - - Raises: - ValueError - If both sample_model and resolution_model contain delta functions. - - """ - - # prepare list of components - if isinstance(sample_model, SampleModel): - sample_components = sample_model.components - else: - sample_components = [sample_model] - - if isinstance(resolution_model, SampleModel): - resolution_components = resolution_model.components - else: - resolution_components = [resolution_model] - - total = np.zeros_like(energy, dtype=float) - - # loop over sample components. Try to convolve each with all resolution components analytically - for sample_component in sample_components: - not_analytical_components = SampleModel(name="not_analytical") - - # Go through resolution components, adding analytical contributions where possible, making a list of those that cannot be handled analytically - for resolution_component in resolution_components: - handled, contrib = _try_analytic_pair( - energy=energy, - sample_component=sample_component, - resolution_component=resolution_component, - offset_float=offset_float, - ) - if handled: - total += contrib - else: - not_analytical_components.add_component(resolution_component) - if not_analytical_components: - if use_numerical_convolution_as_fallback: - total += _numerical_convolution( - energy=energy, - sample_model=sample_component, - resolution_model=not_analytical_components, - offset_float=offset_float, - upsample_factor=upsample_factor, - extension_factor=extension_factor, - ) - else: - raise ValueError( - f"Could not find analytical convolution for sample component '{sample_component.name}' with resolution model '{not_analytical_components.name}'. " - "Set method to 'auto' or 'numerical'." - ) + energy_step = energy_dense[1] - energy_dense[0] + span = energy_dense.max() - energy_dense.min() + # Handle offset for even length of x in convolution. + # The convolution of two arrays of length N is of length 2N-1. When using 'same' mode, only the central N points are kept, + # so the output has the same length as the input. + # However, if N is even, the center falls between two points, leading to a half-bin offset. + # For example, if N=4, the convolution has length 7, and when we select the 4 central points we either get + # indices [2,3,4,5] or [1,2,3,4], both of which are offset by 0.5*dx from the true center at index 3.5. + if len(energy_dense) % 2 == 0: + x_even_length_offset = -0.5 * energy_step + else: + x_even_length_offset = 0.0 - return total - - -# ---------------------- helpers & evals ----------------------- - - -def _create_dense_grid( - energy: np.ndarray, upsample_factor: int = 5, extension_factor: float = 0.2 -) -> np.ndarray: - """ - Create a dense grid by upsampling and extending the input energy array. - - Args: - energy : np.ndarray - 1D array of energy values. - upsample_factor : int, optional - The factor by which to upsample the input data. Default is 5. - extension_factor : float, optional - The factor by which to extend the input data range. Default is 0.2. - Returns: - np.ndarray - The dense grid created by upsampling and extending x. - """ - if upsample_factor == 0: - # Check if the array is uniformly spaced. - energy_diff = np.diff(energy) - is_uniform = np.allclose(energy_diff, energy_diff[0]) - if not is_uniform: - raise ValueError( - "Input array `energy` must be uniformly spaced if upsample_factor = 0." + # Handle the case when x is not symmetric around zero. The resolution is still centered around zero (or close to it), so it needs to be evaluated there. + if not np.isclose(energy_dense.mean(), 0.0): + energy_dense_centered = np.linspace( + -0.5 * span, 0.5 * span, len(energy_dense) ) - energy_dense = energy - else: - # Create an extended and upsampled energy grid - energy_min, energy_max = energy.min(), energy.max() - span = energy_max - energy_min - extra = extension_factor * span - extended_min = energy_min - extra - extended_max = energy_max + extra - num_points = len(energy) * upsample_factor - energy_dense = np.linspace(extended_min, extended_max, num_points) - - return energy_dense - - -def _try_analytic_pair( - energy: np.ndarray, - sample_component: Union[ModelComponent, SampleModel], - resolution_component: Union[ModelComponent, SampleModel], - offset_float: float, -) -> Tuple[bool, np.ndarray]: - """ - Attempt an analytic convolution for component pair (sample_component, resolution_component). - Returns (True, contribution) if handled, else (False, zeros). - The convolution of two gaussian components results in another gaussian component with width sqrt(w1^2 + w2^2). - The convolution of two lorentzian components results in another lorentzian component with width w1 + w2. - The convolution of a gaussian and a lorentzian results in a voigt profile. - The convolution of a delta function with any component or SampleModel results in the same component or SampleModel shifted by the delta center. - All areas are multiplied. - - - Args: - energy: np.ndarray - 1D array of energy values where the convolution is evaluated. - sample_component : Union[ModelComponent, SampleModel] - The sample component to be convolved. - resolution_component : Union[ModelComponent, SampleModel] - The resolution component to convolve with. - offset_float : float - The offset in energyto apply to the convolution. - - Returns: - Tuple[bool, np.ndarray]: - - bool: True if analytical convolution was computed, False otherwise - - np.ndarray: The convolution result if computed, or zeros if not handled - """ - # Two delta functions is not meaningful - if isinstance(sample_component, DeltaFunction) and isinstance( - resolution_component, DeltaFunction - ): - raise ValueError("Convolution of two delta functions is not defined.") - - # Delta function + anything --> anything, shifted by delta center with area A1 * A2 - if isinstance(sample_component, DeltaFunction): - return True, sample_component.area.value * resolution_component.evaluate( - energy - sample_component.center.value - offset_float + else: + energy_dense_centered = energy_dense + + # Give warnings if peaks are very wide or very narrow + self._check_width_thresholds( + model=sample_model, + span=span, + energy_step=energy_step, + model_name="sample model", ) - - if isinstance(resolution_component, DeltaFunction): - return True, resolution_component.area.value * sample_component.evaluate( - energy - resolution_component.center.value - offset_float + self._check_width_thresholds( + model=resolution_model, + span=span, + energy_step=energy_step, + model_name="resolution model", ) - # Gaussian + Gaussian --> Gaussian with width sqrt(w1^2 + w2^2) and area A1 * A2 - if isinstance(sample_component, Gaussian) and isinstance( - resolution_component, Gaussian - ): - width = np.sqrt( - sample_component.width.value**2 + resolution_component.width.value**2 - ) - area = sample_component.area.value * resolution_component.area.value - center = ( - sample_component.center.value + resolution_component.center.value - ) + offset_float - return True, _gaussian_eval(energy, center, width, area) - - # Lorentzian + Lorentzian --> Lorentzian with width w1 + w2 and area A1 * A2 - if isinstance(sample_component, Lorentzian) and isinstance( - resolution_component, Lorentzian - ): - width = sample_component.width.value + resolution_component.width.value - area = sample_component.area.value * resolution_component.area.value - center = ( - sample_component.center.value + resolution_component.center.value - ) + offset_float - return True, _lorentzian_eval(energy, center, width, area) - - # Gaussian + Lorentzian --> Voigt with area A1 * A2 - if ( - isinstance(sample_component, Gaussian) - and isinstance(resolution_component, Lorentzian) - ) or ( - isinstance(sample_component, Lorentzian) - and isinstance(resolution_component, Gaussian) - ): - if isinstance(sample_component, Gaussian): - gaussian, lorentzian = sample_component, resolution_component + # Evaluate sample model. Delta functions are handled separately for accuracy. + if isinstance(sample_model, SampleModel): + sample_vals = sample_model.evaluate_without_delta( + energy_dense - offset_float - x_even_length_offset + ) + elif isinstance(sample_model, DeltaFunction): + sample_vals = np.zeros_like(energy_dense) else: - gaussian, lorentzian = resolution_component, sample_component - center = (gaussian.center.value + lorentzian.center.value) + offset_float - area = gaussian.area.value * lorentzian.area.value - return True, _voigt_eval( - energy, center, gaussian.width.value, lorentzian.width.value, area - ) - - return False, np.zeros_like(energy, dtype=float) - - -def _gaussian_eval( - energy: np.ndarray, center: float, width: float, area: float -) -> np.ndarray: - """ - Evaluate a Gaussian function. y = (area / (sqrt(2pi) * width)) * exp(-0.5 * ((x - center) / width)^2) - All checks are handled in the calling function. - - Args: - energy : np.ndarray - 1D array of energy values where the Gaussian is evaluated. - center : float - The center of the Gaussian. - width : float - The width (sigma) of the Gaussian. - area : float - The area under the Gaussian curve. - Returns: - np.ndarray - The evaluated Gaussian values at x. - """ - return ( - area - * 1 - / (np.sqrt(2 * np.pi) * width) - * np.exp(-0.5 * ((energy - center) / width) ** 2) - ) - - -def _lorentzian_eval( - energy: np.ndarray, center: float, width: float, area: float -) -> np.ndarray: - """ - Evaluate a Lorentzian function. y = (area * width / pi) / ((x - center)^2 + width^2). - All checks are handled in the calling function. - - Args: - energy : np.ndarray - 1D array of energy values where the Lorentzian is evaluated. - center : float - The center of the Lorentzian. - width : float - The width (HWHM) of the Lorentzian. - area : float - The area under the Lorentzian. - Returns: - np.ndarray - The evaluated Lorentzian values at x. - """ - return area * width / np.pi / ((energy - center) ** 2 + width**2) - - -def _voigt_eval( - energy: np.ndarray, center: float, g_width: float, l_width: float, area: float -) -> np.ndarray: - """ - Evaluate a Voigt profile function using scipy's voigt_profile. - Args: - energy : np.ndarray - 1D array of energy values where the Voigt profile is evaluated. - center : float - The center of the Voigt profile. - g_width : float - The Gaussian width (sigma) of the Voigt profile. - l_width : float - The Lorentzian width (HWHM) of the Voigt profile. - area : float - The area under the Voigt profile. - Returns: - np.ndarray - The evaluated Voigt profile values at x. - """ - - return area * voigt_profile(energy - center, g_width, l_width) - - -def _check_width_thresholds( - model: Union[SampleModel, ModelComponent], - span: float, - energy_step: float, - model_name: str, -) -> None: - """ - Helper function to check and warn if components are wide compared to the span of the data, or narrow compared to the spacing. - In both cases, the convolution accuracy may be compromised. - Args: - model : SampleModel or ModelComponent - The model to check. - energy_step : float - The bin spacing of the energy array. - span : float - The total span of the energy array. - model_name : str - A string indicating whether the model is a 'sample model' or 'resolution model' for warning messages. - returns: - None - warns: - UserWarning - If the component widths are not appropriate for the data span or bin spacing. - - """ - - # The thresholds are illustrated in performance_tests/convolution/convolution_width_thresholds.ipynb - LARGE_WIDTH_THRESHOLD = ( - 0.1 # Threshold for large widths compared to span - warn if width > 10% of span - ) - SMALL_WIDTH_THRESHOLD = ( - 1.0 # Threshold for small widths compared to bin spacing - warn if width < dx - ) - - # Handle SampleModel or ModelComponent - if isinstance(model, SampleModel): - components = model.components - else: - components = [model] # Treat single ModelComponent as a list - - for comp in components: - if hasattr(comp, "width"): - if comp.width.value > LARGE_WIDTH_THRESHOLD * span: - warnings.warn( - f"The width of the {model_name} component '{comp.name}' ({comp.width.value}) is large compared to the span of the input " - f"array ({span}). This may lead to inaccuracies in the convolution. Increase extension_factor to improve accuracy.", - UserWarning, - ) - if comp.width.value < SMALL_WIDTH_THRESHOLD * energy_step: - warnings.warn( - f"The width of the {model_name} component '{comp.name}' ({comp.width.value}) is small compared to the spacing of the input " - f"array ({energy_step}). This may lead to inaccuracies in the convolution. Increase upsample_factor to improve accuracy.", - UserWarning, - ) - - -def _find_delta_components( - model: Union[SampleModel, ModelComponent], -) -> List[DeltaFunction]: - """Return a list of DeltaFunction instances contained in `model`. - - Args: - model : SampleModel or ModelComponent - The model to search for DeltaFunction components. - Returns: - List[DeltaFunction] - A list of DeltaFunction components found in the model. - """ - if isinstance(model, DeltaFunction): - return [model] - if isinstance(model, SampleModel): - return [c for c in model.components if isinstance(c, DeltaFunction)] - return [] - - -def _calculate_delta_contributions( - energy: np.ndarray, - sample_model: Union[SampleModel, ModelComponent], - resolution_model: Union[SampleModel, ModelComponent], - offset_float: float, -) -> np.ndarray: - """ - Calculate the contributions of delta functions in the convolution. - Args: - energy : np.ndarray - 1D array of energy values where the convolution is evaluated. - sample_model : SampleModel or ModelComponent - The sample model to be convolved. - resolution_model : SampleModel or ModelComponent - The resolution model to convolve with. - offset_float : float - The offset to apply to the convolution. - Returns: - np.ndarray - The delta function contributions evaluated at energy. - - Raises: - ValueError - If both sample_model and resolution_model contain delta functions. - """ - delta_contributions = np.zeros_like(energy) - - # Add delta contributions on original grid - # collect deltas - sample_deltas = _find_delta_components(sample_model) - resolution_deltas = _find_delta_components(resolution_model) - - # error if both contain delta(s) - if sample_deltas and resolution_deltas: - raise ValueError( - "Both sample_model and resolution_model contain delta functions. " - "Their convolution is not defined." - ) + sample_vals = sample_model.evaluate( + energy_dense - offset_float - x_even_length_offset + ) - # if sample has deltas, convolve each delta with the resolution_model - for delta in sample_deltas: - (_, delta_contribution) = _try_analytic_pair( - energy=energy, - sample_component=delta, - resolution_component=resolution_model, - offset_float=offset_float, - ) - delta_contributions += delta_contribution - - # if resolution has deltas, convolve each delta with the sample_model - for delta in resolution_deltas: - (_, delta_contribution) = _try_analytic_pair( - energy=energy, - sample_component=sample_model, - resolution_component=delta, - offset_float=offset_float, - ) - delta_contributions += delta_contribution + # Detailed balance correction + if temperature is not None: + detailed_balance_factor_correction = detailed_balance_factor( + energy=energy_dense, + temperature=temperature, + energy_unit=energy_unit, + temperature_unit=temperature_unit, + divide_by_temperature=normalize_detailed_balance, + ) + sample_vals *= detailed_balance_factor_correction - return delta_contributions + # Evaluate resolution model + if isinstance(resolution_model, SampleModel): + resolution_vals = resolution_model.evaluate_without_delta( + energy_dense_centered + ) + elif isinstance(resolution_model, DeltaFunction): + resolution_vals = np.zeros_like(energy_dense_centered) + else: + resolution_vals = resolution_model.evaluate(energy_dense_centered) + + # Convolution + convolved = fftconvolve(sample_vals, resolution_vals, mode="same") + convolved *= energy_step # normalize + + if upsample_factor > 0: + # interpolate back to original energy grid + convolved = np.interp(energy, energy_dense, convolved, left=0.0, right=0.0) + + # # Add delta function contributions + # delta_contributions = _calculate_delta_contributions( + # energy=energy, + # sample_model=sample_model, + # resolution_model=resolution_model, + # offset_float=offset_float, + # ) + # convolved += delta_contributions + + return convolved + + # ---------------------- helpers & evals ----------------------- + + def _create_dense_grid( + self, + energy: np.ndarray, + upsample_factor: int = 5, + extension_factor: float = 0.2, + ) -> np.ndarray: + """ + Create a dense grid by upsampling and extending the input energy array. + + Args: + energy : np.ndarray + 1D array of energy values. + upsample_factor : int, optional + The factor by which to upsample the input data. Default is 5. + extension_factor : float, optional + The factor by which to extend the input data range. Default is 0.2. + Returns: + np.ndarray + The dense grid created by upsampling and extending x. + """ + if upsample_factor == 0: + # Check if the array is uniformly spaced. + energy_diff = np.diff(energy) + is_uniform = np.allclose(energy_diff, energy_diff[0]) + if not is_uniform: + raise ValueError( + "Input array `energy` must be uniformly spaced if upsample_factor = 0." + ) + energy_dense = energy + else: + # Create an extended and upsampled energy grid + energy_min, energy_max = energy.min(), energy.max() + span = energy_max - energy_min + extra = extension_factor * span + extended_min = energy_min - extra + extended_max = energy_max + extra + num_points = len(energy) * upsample_factor + energy_dense = np.linspace(extended_min, extended_max, num_points) + + self._energy_dense = energy_dense + + def _check_width_thresholds( + self, + model: Union[SampleModel, ModelComponent], + span: float, + energy_step: float, + model_name: str, + ) -> None: + """ + Helper function to check and warn if components are wide compared to the span of the data, or narrow compared to the spacing. + In both cases, the convolution accuracy may be compromised. + Args: + model : SampleModel or ModelComponent + The model to check. + energy_step : float + The bin spacing of the energy array. + span : float + The total span of the energy array. + model_name : str + A string indicating whether the model is a 'sample model' or 'resolution model' for warning messages. + returns: + None + warns: + UserWarning + If the component widths are not appropriate for the data span or bin spacing. + + """ + + # The thresholds are illustrated in performance_tests/convolution/convolution_width_thresholds.ipynb + LARGE_WIDTH_THRESHOLD = 0.1 # Threshold for large widths compared to span - warn if width > 10% of span + SMALL_WIDTH_THRESHOLD = 1.0 # Threshold for small widths compared to bin spacing - warn if width < dx + + # Handle SampleModel or ModelComponent + if isinstance(model, SampleModel): + components = model.components + else: + components = [model] # Treat single ModelComponent as a list + + for comp in components: + if hasattr(comp, "width"): + if comp.width.value > LARGE_WIDTH_THRESHOLD * span: + warnings.warn( + f"The width of the {model_name} component '{comp.name}' ({comp.width.value}) is large compared to the span of the input " + f"array ({span}). This may lead to inaccuracies in the convolution. Increase extension_factor to improve accuracy.", + UserWarning, + ) + if comp.width.value < SMALL_WIDTH_THRESHOLD * energy_step: + warnings.warn( + f"The width of the {model_name} component '{comp.name}' ({comp.width.value}) is small compared to the spacing of the input " + f"array ({energy_step}). This may lead to inaccuracies in the convolution. Increase upsample_factor to improve accuracy.", + UserWarning, + ) + + +# def convolution(self, +# energy: np.ndarray, +# sample_model: Union[SampleModel, ModelComponent], +# resolution_model: Union[SampleModel, ModelComponent], +# offset: Optional[Union[Parameter, float, None]] = None, +# method: Optional[str] = "auto", +# upsample_factor: Optional[int] = 0, +# extension_factor: Optional[float] = 0.2, +# temperature: Optional[Union[Parameter, float, None]] = None, +# temperature_unit: Union[str, sc.Unit] = "K", +# energy_unit: Optional[Union[str, sc.Unit]] = "meV", +# normalize_detailed_balance: Optional[bool] = True, +# ) -> np.ndarray: +# """ +# Calculate the convolution of a sample model with a resolution model using analytical expressions or numerical FFT. +# Accepts SampleModel or ModelComponent for both sample and resolution. +# If method is 'auto', analytical convolution is preferred when possible, otherwise numerical convolution is used. +# Detailed balancing is included if temperature is provided. This requires numerical convolution and that the units +# of energy and temperature are provided. An error will be raised if the units are not compatible. +# The calculated model is shifted by the specified offset. + +# Examples: +# energy = np.linspace(-10, 10, 100) +# sample = SampleModel() +# sample.add_component(Gaussian(name="SampleGaussian", area=1.0, center=0.1, width=1.0)) +# resolution = Gaussian(name="ResolutionGaussian", area=1.0, center=0.0, width=0.5) +# result = convolution(energy, sample, resolution, offset=0.2) + +# energy = np.linspace(-10, 10, 100) +# sample = SampleModel() +# sample.add_component(Gaussian(name="Gaussian", area=1.0, center=0.1, width=1.0)) +# sample.add_component(DampedHarmonicOscillator(name="DHO", area=2.0, center=1.5, width=0.2)) +# sample.add_component(DeltaFunction(name="Delta", area=0.5, center=0.0)) + +# resolution = SampleModel() +# resolution.add_component(Gaussian(name="ResolutionGaussian", area=0.8, center=0.0, width=0.5)) +# resolution.add_component(Lorentzian(name="ResolutionLorentzian", area=0.2, center=0.1, width=0.3)) + +# result_auto = convolution(energy, sample, resolution, offset=0.2, method='auto', upsample_factor=5, extension_factor=0.2) +# result_numerical = convolution(energy, sample, resolution, offset=0.2, method='numerical', upsample_factor=5, extension_factor=0.2) + + +# Args: +# energy : np.ndarray +# 1D array of energy transfer where the convolution is evaluated. +# sample_model : SampleModel or ModelComponent +# The sample model to be convolved. +# resolution_model : SampleModel or ModelComponent +# The resolution model to convolve with. +# offset : Parameter, float, or None, optional +# The offset to apply to the x values before convolution. +# method : str, optional +# The convolution method to use: 'auto', 'analytical' or 'numerical'. Default is 'auto'. +# upsample_factor : int, optional +# The factor by which to upsample the input data before numerical convolution. Default is 0 (no upsampling). +# extension_factor : float, optional +# The factor by which to extend the input data range before numerical convolution. Default is 0.2. +# temperature : Parameter, float, or None, optional +# The temperature to use for detailed balance calculations. Default is None. +# temperature_unit : str or sc.Unit, optional +# The unit of the temperature parameter. Default is 'K'. +# energy_unit : str or sc.Unit, optional +# The unit of the energy. Default is 'meV'. +# normalize_detailed_balance : bool, optional +# Whether to normalize the detailed balance factor. Default is True. +# """ + +# # Input validation +# if not isinstance(energy, np.ndarray): +# raise TypeError( +# f"`energy` is an instance of {type(energy).__name__}, but must be a numpy array." +# ) + +# energy = np.asarray(energy, dtype=float) +# if energy.ndim != 1 or not np.all(np.isfinite(energy)): +# raise ValueError("`energy` must be a 1D finite array.") + +# if not isinstance(sample_model, (SampleModel, ModelComponent)): +# raise TypeError( +# f"`sample_model` is an instance of {type(sample_model).__name__}, but must be SampleModel or ModelComponent." +# ) + +# if not isinstance(resolution_model, (SampleModel, ModelComponent)): +# raise TypeError( +# f"`resolution_model` is an instance of {type(resolution_model).__name__}, but must be SampleModel or ModelComponent." +# ) + +# if isinstance(sample_model, SampleModel): +# if not sample_model.components: +# raise ValueError("SampleModel must have at least one component.") + +# if isinstance(resolution_model, SampleModel): +# if not resolution_model.components: +# raise ValueError("ResolutionModel must have at least one component.") + +# # Handle offset +# if offset is None: +# offset_float = 0.0 +# elif isinstance(offset, Parameter): +# offset_float = offset.value +# elif isinstance(offset, Numerical): +# offset_float = float(offset) +# else: +# raise TypeError( +# f"Expected offset to be Parameter, number, or None, got {type(offset)}" +# ) + +# if not isinstance(upsample_factor, int) or upsample_factor < 0: +# raise ValueError("upsample_factor must be a non-negative integer.") + +# if not isinstance(extension_factor, float) or extension_factor < 0.0: +# raise ValueError("extension_factor must be a non-negative float.") + +# if temperature is not None: +# if energy_unit is None: +# raise ValueError( +# "energy_unit must be provided when temperature is specified." +# ) +# if not isinstance(energy_unit, (str, sc.Unit)): +# raise TypeError( +# f"Expected energy_unit to be str or sc.Unit, got {type(energy_unit)}" +# ) + +# use_numerical_convolution_as_fallback = False +# if method == "auto": +# if temperature is not None: +# method = "numerical" +# else: +# method = "analytical" +# use_numerical_convolution_as_fallback = True + +# if method == "analytical": +# if temperature is not None: +# raise ValueError( +# "Analytical convolution is not supported with detailed balance. Set method to 'numerical' instead or set the temperature to None." +# ) +# return _analytical_convolution( +# energy=energy, +# sample_model=sample_model, +# resolution_model=resolution_model, +# offset_float=offset_float, +# use_numerical_convolution_as_fallback=use_numerical_convolution_as_fallback, +# upsample_factor=upsample_factor, +# extension_factor=extension_factor, +# ) +# elif method == "numerical": +# return _numerical_convolution( +# energy=energy, +# sample_model=sample_model, +# resolution_model=resolution_model, +# offset_float=offset_float, +# upsample_factor=upsample_factor, +# extension_factor=extension_factor, +# temperature=temperature, +# temperature_unit=temperature_unit, +# energy_unit=energy_unit, +# normalize_detailed_balance=normalize_detailed_balance, +# ) +# else: +# raise ValueError( +# f"Unknown convolution method: {method}. Choose from 'auto', 'analytical', or 'numerical'." +# ) From 078ce87936b6305f0b2c9261675ec046714afab9 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 19 Nov 2025 11:37:04 +0100 Subject: [PATCH 35/71] Lots of refactoring --- src/easydynamics/convolution/__init__.py | 3 + .../convolution/analytical_convolution.py | 478 +++++++++++ src/easydynamics/convolution/convolution.py | 201 +++++ .../convolution/convolution_base.py | 66 ++ .../convolution/numerical_convolution.py | 141 ++++ .../convolution/numerical_convolution_base.py | 332 ++++++++ src/easydynamics/utils/__init__.py | 3 +- src/easydynamics/utils/convolution.py | 771 ------------------ .../test_convolution.py | 2 +- 9 files changed, 1223 insertions(+), 774 deletions(-) create mode 100644 src/easydynamics/convolution/__init__.py create mode 100644 src/easydynamics/convolution/analytical_convolution.py create mode 100644 src/easydynamics/convolution/convolution.py create mode 100644 src/easydynamics/convolution/convolution_base.py create mode 100644 src/easydynamics/convolution/numerical_convolution.py create mode 100644 src/easydynamics/convolution/numerical_convolution_base.py delete mode 100644 src/easydynamics/utils/convolution.py rename tests/unit_tests/{utils => convolution}/test_convolution.py (99%) diff --git a/src/easydynamics/convolution/__init__.py b/src/easydynamics/convolution/__init__.py new file mode 100644 index 0000000..4158f51 --- /dev/null +++ b/src/easydynamics/convolution/__init__.py @@ -0,0 +1,3 @@ +from .convolution import Convolution + +__all__ = ["Convolution"] diff --git a/src/easydynamics/convolution/analytical_convolution.py b/src/easydynamics/convolution/analytical_convolution.py new file mode 100644 index 0000000..49b97ac --- /dev/null +++ b/src/easydynamics/convolution/analytical_convolution.py @@ -0,0 +1,478 @@ +from typing import Optional, Union + +import numpy as np +from easyscience.variable import Parameter +from scipy.special import voigt_profile + +from easydynamics.convolution.convolution_base import ConvolutionBase +from easydynamics.sample_model import ( + DeltaFunction, + Gaussian, + Lorentzian, + SampleModel, + Voigt, +) +from easydynamics.sample_model.components.model_component import ModelComponent + +Numerical = Union[float, int] + +# TODO: update docstrings + + +class AnalyticalConvolution(ConvolutionBase): + def __init__( + self, + energy: np.ndarray, + energy_unit: str = "meV", + sample_model: SampleModel = None, + resolution_model: SampleModel = None, + offset: Optional[Union[Numerical, Parameter]] = 0.0, + ): + super().__init__( + energy=energy, + sample_model=sample_model, + resolution_model=resolution_model, + energy_unit=energy_unit, + offset=offset, + ) + + def convolution( + self, + ) -> np.ndarray: + """ + Convolve sample with resolution analytically if possible. Accepts SampleModel or single ModelComponent for each. + Possible analytical convolutions are any combination of delta functions, Gaussians, Lorentzians and Voigt profiles. + + Most validation happens in the main `convolution` function. + + Args: + x : np.ndarray + 1D array of x values where the convolution is evaluated. + sample_model : SampleModel or ModelComponent + The sample model to be convolved. + resolution_model : SampleModel or ModelComponent + The resolution model to convolve with. + self.offset.value : float + The offset to apply to the convolution. + Returns: + np.ndarray + The convolved values evaluated at x. + + Raises: + ValueError + If resolution_model contains delta functions. + ValueError + If component pair cannot be handled analytically. + + """ + + # prepare list of components + if isinstance(self.sample_model, SampleModel): + sample_components = self.sample_model.components + else: + sample_components = [self.sample_model] + + if isinstance(self.resolution_model, SampleModel): + resolution_components = self.resolution_model.components + else: + resolution_components = [self.resolution_model] + + total = np.zeros_like(self.energy, dtype=float) + + for sample_component in sample_components: + # Go through resolution components, adding analytical contributions + for resolution_component in resolution_components: + contrib = self._calculate_analytic_pair( + sample_component=sample_component, + resolution_component=resolution_component, + ) + total += contrib + + return total + + def _calculate_analytic_pair( + self, + sample_component: Union[ModelComponent, SampleModel], + resolution_component: ModelComponent, + ) -> np.ndarray: + """ + Analytic convolution for component pair (sample_component, resolution_component). + The convolution of two gaussian components results in another gaussian component with width sqrt(w1^2 + w2^2). + The convolution of two lorentzian components results in another lorentzian component with width w1 + w2. + The convolution of a gaussian and a lorentzian results in a voigt profile. + The convolution of a gaussian and a voigt profile results in another voigt profile, with the lorentzian width unchanged and the gaussian widths summed in quadrature. + The convolution of a lorentzian and a voigt profile results in another voigt profile, with the gaussian width unchanged and the lorentzian widths summed. + The convolution of two voigt profiles results in another voigt profile, with the gaussian widths summed in quadrature and the lorentzian widths summed. + The convolution of a delta function with any component or SampleModel results in the same component or SampleModel shifted by the delta center. + All areas are multiplied. + The output is shifted by self.offset.value. + + + Args: + sample_component : Union[ModelComponent, SampleModel] + The sample component to be convolved. + resolution_component : Union[ModelComponent, SampleModel] + The resolution component to convolve with. + + Returns: + np.ndarray: The convolution result + + Raises: + ValueError: If the component pair cannot be handled analytically. + """ + + # Delta function + anything --> anything, shifted by delta center with area A1 * A2 + if isinstance(sample_component, DeltaFunction): + return self._convolute_delta_any( + sample_component, + resolution_component, + ) + + # Gaussian + Gaussian --> Gaussian with width sqrt(w1^2 + w2^2) and area A1 * A2 + if isinstance(sample_component, Gaussian) and isinstance( + resolution_component, Gaussian + ): + return self._convolute_gauss_gauss( + sample_component, + resolution_component, + ) + + # Gaussian + Lorentzian --> Voigt with area A1 * A2 + if ( + isinstance(sample_component, Gaussian) + and isinstance(resolution_component, Lorentzian) + ) or ( + isinstance(sample_component, Lorentzian) + and isinstance(resolution_component, Gaussian) + ): + if isinstance(sample_component, Gaussian): + gaussian, lorentzian = sample_component, resolution_component + else: + gaussian, lorentzian = resolution_component, sample_component + return self._convolute_gauss_lorentz( + gaussian, + lorentzian, + ) + + # Gaussian + Voigt --> Voigt with area A1 * A2, Lorentzian width unchanged, Gaussian widths summed in quadrature + if ( + isinstance(sample_component, Gaussian) + and isinstance(resolution_component, Voigt) + ) or ( + isinstance(sample_component, Voigt) + and isinstance(resolution_component, Gaussian) + ): + if isinstance(sample_component, Gaussian): + gaussian, voigt = sample_component, resolution_component + else: + gaussian, voigt = resolution_component, sample_component + return self._convolute_gauss_voigt( + gaussian, + voigt, + ) + + # Lorentzian + Lorentzian --> Lorentzian with width w1 + w2 and area A1 * A2 + if isinstance(sample_component, Lorentzian) and isinstance( + resolution_component, Lorentzian + ): + return self._convolute_lorentz_lorentz( + sample_component, + resolution_component, + ) + + # Lorentzian + Voigt --> Voigt with area A1 * A2, Gaussian width unchanged, Lorentzian widths summed + if ( + isinstance(sample_component, Lorentzian) + and isinstance(resolution_component, Voigt) + ) or ( + isinstance(sample_component, Voigt) + and isinstance(resolution_component, Lorentzian) + ): + if isinstance(sample_component, Lorentzian): + lorentzian, voigt = sample_component, resolution_component + else: + lorentzian, voigt = resolution_component, sample_component + center = (voigt.center.value + lorentzian.center.value) + self.offset.value + area = voigt.area.value * lorentzian.area.value + g_width = voigt.g_width.value + l_width = voigt.l_width.value + lorentzian.width.value + return self._voigt_eval(self.energy, center, g_width, l_width, area) + + # Voigt + Voigt --> Voigt with area A1 * A2, Gaussian widths summed in quadrature, Lorentzian widths summed + if isinstance(sample_component, Voigt) and isinstance( + resolution_component, Voigt + ): + return self.convolute_voigt_voigt( + sample_component, + resolution_component, + ) + + return ValueError( + f"Analytical convolution not implemented for component pair: {type(sample_component).__name__}, {type(resolution_component).__name__}" + ) + + def _convolute_delta_any( + self, + sample_component: ModelComponent, + resolution_model: Union[SampleModel, ModelComponent], + ): + """ + Convolution of delta function with any component or SampleModel results in the same component or SampleModel shifted by the delta center. + The areas are multiplied. + + Args: + sample_component : ModelComponent + The sample component to be convolved. + resolution_component : ModelComponent + The resolution component to convolve with. + Returns: + np.ndarray + The evaluated convolution values at self.energy. + """ + return sample_component.area.value * resolution_model.evaluate( + self.energy - sample_component.center.value - self.offset.value + ) + + def _convolute_gauss_gauss( + self, + sample_component: Gaussian, + resolution_component: Gaussian, + ) -> np.ndarray: + """ + Convolution of two gaussian components results in another gaussian component with width sqrt(w1^2 + w2^2). + The areas are multiplied. + + Args: + sample_component : Gaussian + The sample Gaussian component to be convolved. + resolution_component : Gaussian + The resolution Gaussian component to convolve with. + + Returns: + np.ndarray + + The evaluated convolution values at self.energy. + """ + + width = np.sqrt( + sample_component.width.value**2 + resolution_component.width.value**2 + ) + area = sample_component.area.value * resolution_component.area.value + center = ( + sample_component.center.value + resolution_component.center.value + ) + self.offset.value + + return self._gaussian_eval(self.energy, center, width, area) + + def _convolute_gauss_lorentz( + self, + sample_component: Gaussian, + resolution_component: Lorentzian, + ) -> np.ndarray: + """ + Convolution of a Gaussian and a Lorentzian results in a Voigt profile. + The areas are multiplied. + + Args: + sample_component : Gaussian + The sample Gaussian component to be convolved. + resolution_component : Lorentzian + The resolution Lorentzian component to convolve with. + + Returns: + np.ndarray + The evaluated convolution values at self.energy. + """ + center = ( + sample_component.center.value + resolution_component.center.value + ) + self.offset.value + area = sample_component.area.value * resolution_component.area.value + + return self._voigt_eval( + self.energy, + center, + sample_component.width.value, + resolution_component.width.value, + area, + ) + + def _convolute_gauss_voigt( + self, + sample_component: Gaussian, + resolution_component: Voigt, + ) -> np.ndarray: + """ + Convolution of a Gaussian and a Voigt profile results in another Voigt profile. + The Lorentzian width remains unchanged, while the Gaussian widths are summed in quadrature. + The areas are multiplied. + + Args: + sample_component : Gaussian + The sample Gaussian component to be convolved. + resolution_component : Voigt + The resolution Voigt component to convolve with. + + Returns: + np.ndarray + The evaluated convolution values at self.energy. + """ + center = ( + sample_component.center.value + resolution_component.center.value + ) + self.offset.value + area = sample_component.area.value * resolution_component.area.value + g_width = np.sqrt( + sample_component.width.value**2 + resolution_component.g_width.value**2 + ) + l_width = resolution_component.l_width.value + return self._voigt_eval(self.energy, center, g_width, l_width, area) + + def _convolute_lorentz_lorentz( + self, + sample_component: Lorentzian, + resolution_component: Lorentzian, + ) -> np.ndarray: + """ + Convolution of two Lorentzian components results in another Lorentzian component with width w1 + w2. + The areas are multiplied. + + Args: + sample_component : Lorentzian + The sample Lorentzian component to be convolved. + resolution_component : Lorentzian + The resolution Lorentzian component to convolve with. + Returns: + np.ndarray + The evaluated convolution values at self.energy. + """ + width = sample_component.width.value + resolution_component.width.value + area = sample_component.area.value * resolution_component.area.value + center = ( + sample_component.center.value + resolution_component.center.value + ) + self.offset.value + return self._lorentzian_eval(self.energy, center, width, area) + + def _convolute_lorentz_voigt( + self, + sample_component: Lorentzian, + resolution_component: Voigt, + ) -> np.ndarray: + """ + Convolution of a Lorentzian and a Voigt profile results in another Voigt profile. + The Gaussian width remains unchanged, while the Lorentzian widths are summed. + The areas are multiplied. + Args: + sample_component : Lorentzian + The sample Lorentzian component to be convolved. + resolution_component : Voigt + The resolution Voigt component to convolve with. + Returns: + np.ndarray + The evaluated convolution values at self.energy. + """ + center = ( + sample_component.center.value + resolution_component.center.value + ) + self.offset.value + area = sample_component.area.value * resolution_component.area.value + g_width = resolution_component.g_width.value + l_width = sample_component.width.value + resolution_component.l_width.value + return self._voigt_eval(self.energy, center, g_width, l_width, area) + + def convolute_voigt_voigt( + self, + sample_component: Voigt, + resolution_component: Voigt, + ) -> np.ndarray: + """ + Convolution of two Voigt profiles results in another Voigt profile. + The Gaussian widths are summed in quadrature, while the Lorentzian widths are summed. + The areas are multiplied. + Args: + sample_component : Voigt + The sample Voigt component to be convolved. + resolution_component : Voigt + The resolution Voigt component to convolve with. + Returns: + np.ndarray + The evaluated convolution values at self.energy. + """ + center = ( + sample_component.center.value + resolution_component.center.value + ) + self.offset.value + area = sample_component.area.value * resolution_component.area.value + g_width = np.sqrt( + sample_component.g_width.value**2 + resolution_component.g_width.value**2 + ) + l_width = sample_component.l_width.value + resolution_component.l_width.value + return self._voigt_eval(self.energy, center, g_width, l_width, area) + + def _gaussian_eval(self, center: float, width: float, area: float) -> np.ndarray: + """ + Evaluate a Gaussian function. y = (area / (sqrt(2pi) * width)) * exp(-0.5 * ((x - center) / width)^2) + All checks are handled in the calling function. + + Args: + energy : np.ndarray + 1D array of energy values where the Gaussian is evaluated. + center : float + The center of the Gaussian. + width : float + The width (sigma) of the Gaussian. + area : float + The area under the Gaussian curve. + Returns: + np.ndarray + The evaluated Gaussian values at self.energy. + """ + return ( + area + * 1 + / (np.sqrt(2 * np.pi) * width) + * np.exp(-0.5 * ((self.energy - center) / width) ** 2) + ) + + def _lorentzian_eval(self, center: float, width: float, area: float) -> np.ndarray: + """ + Evaluate a Lorentzian function. y = (area * width / pi) / ((x - center)^2 + width^2). + All checks are handled in the calling function. + + Args: + energy : np.ndarray + 1D array of energy values where the Lorentzian is evaluated. + center : float + The center of the Lorentzian. + width : float + The width (HWHM) of the Lorentzian. + area : float + The area under the Lorentzian. + Returns: + np.ndarray + The evaluated Lorentzian values at self.energy. + """ + return area * width / np.pi / ((self.energy - center) ** 2 + width**2) + + def _voigt_eval( + self, + center: float, + g_width: float, + l_width: float, + area: float, + ) -> np.ndarray: + """ + Evaluate a Voigt profile function using scipy's voigt_profile. + Args: + energy : np.ndarray + 1D array of energy values where the Voigt profile is evaluated. + center : float + The center of the Voigt profile. + g_width : float + The Gaussian width (sigma) of the Voigt profile. + l_width : float + The Lorentzian width (HWHM) of the Voigt profile. + area : float + The area under the Voigt profile. + Returns: + np.ndarray + The evaluated Voigt profile values at self.energy. + """ + + return area * voigt_profile(self.energy - center, g_width, l_width) diff --git a/src/easydynamics/convolution/convolution.py b/src/easydynamics/convolution/convolution.py new file mode 100644 index 0000000..72111be --- /dev/null +++ b/src/easydynamics/convolution/convolution.py @@ -0,0 +1,201 @@ +from typing import Optional, Union + +import numpy as np +import scipp as sc +from easyscience.variable import Parameter + +from easydynamics.convolution.analytical_convolution import AnalyticalConvolution +from easydynamics.convolution.numerical_convolution import NumericalConvolution +from easydynamics.convolution.numerical_convolution_base import NumericalConvolutionBase +from easydynamics.sample_model import ( + DeltaFunction, + Gaussian, + Lorentzian, + SampleModel, + Voigt, +) +from easydynamics.sample_model.components.model_component import ModelComponent + +Numerical = Union[float, int] + + +class Convolution(NumericalConvolutionBase): + """ + Convolution class that combines analytical and numerical convolution methods based on sample model components. + + Args: + energy : np.ndarray + 1D array of energy values where the convolution is evaluated. + sample_model : SampleModel or ModelComponent + The sample model to be convolved. + resolution_model : SampleModel or ModelComponent + The resolution model to convolve with. + offset_float : float, or None, optional + The offset to apply to the input array. + upsample_factor : int, optional + The factor by which to upsample the input data before convolution. Default is 5. + extension_factor : float, optional + The factor by which to extend the input data range before convolution. Default is 0.2. + temperature : Parameter, float, or None, optional + The temperature to use for detailed balance correction. Default is None. + temperature_unit : str or sc.Unit, optional + The unit of the temperature parameter. Default is 'K'. + energy_unit : str or sc.Unit, optional + The unit of the energy. Default is 'meV'. + normalize_detailed_balance : bool, optional + Whether to normalize the detailed balance factor. Default is True. + """ + + def __init__( + self, + energy: np.ndarray, + sample_model: Union[SampleModel, ModelComponent], + resolution_model: Union[SampleModel, ModelComponent], + offset: Optional[Union[Numerical, Parameter]] = 0.0, + upsample_factor: Optional[Numerical] = 5, + extension_factor: Optional[float] = 0.2, + temperature: Optional[Union[Parameter, float]] = None, + temperature_unit: Optional[Union[str, sc.Unit]] = "K", + energy_unit: Optional[Union[str, sc.Unit]] = "meV", + normalize_detailed_balance: Optional[bool] = True, + ): + super().__init__( + energy=energy, + sample_model=sample_model, + resolution_model=resolution_model, + offset=offset, + upsample_factor=upsample_factor, + extension_factor=extension_factor, + temperature=temperature, + temperature_unit=temperature_unit, + energy_unit=energy_unit, + normalize_detailed_balance=normalize_detailed_balance, + ) + + # Separate sample model components into analytical pairs, delta functions, and the rest + self._set_sample_models() + # Initialize analytical and numerical convolvers based on sample model components + self._set_convolvers() + + def convolution( + self, + ) -> np.ndarray: + """ + Perform convolution using analytical method where possible, and numerical method for remaining components. + """ + + total = np.zeros_like(self.energy, dtype=float) + + # Analytical convolution + if self._analytical_convolver is not None: + total += self._analytical_convolver.convolution() + + # Numerical convolution + if self._numerical_convolver is not None: + total += self._numerical_convolver.convolution() + + # Delta function components (no convolution needed) + if self._delta_sample_model.components: + for sample_component in self._delta_sample_model.components: + total += sample_component.area.value * self._resolution_model.evaluate( + self.energy - sample_component.center.value - self.offset.value + ) + + return total + + def _check_if_pair_is_analytic( + self, + sample_component: ModelComponent, + resolution_component: ModelComponent, + ) -> bool: + """ + Check if the convolution of the given component pair can be handled analytically. + + Args: + sample_component : ModelComponent + The sample component to be convolved. + resolution_component : ModelComponent + The resolution component to convolve with. + Returns: + bool + True if the component pair can be handled analytically, False otherwise. + """ + + if not isinstance(sample_component, ModelComponent): + raise TypeError( + f"`sample_component` is an instance of {type(sample_component).__name__}, but must be ModelComponent." + ) + + if not isinstance(resolution_component, ModelComponent): + raise TypeError( + f"`resolution_component` is an instance of {type(resolution_component).__name__}, but must be ModelComponent." + ) + + if isinstance(resolution_component, DeltaFunction): + raise ValueError( + "Resolution model contains delta functions. This is not supported." + ) + + analytical_types = (Gaussian, Lorentzian, Voigt) + if isinstance(sample_component, analytical_types) and isinstance( + resolution_component, analytical_types + ): + return True + + return False + + def _set_convolvers(self) -> None: + """Initialize analytical and numerical convolvers based on sample model components.""" + + if self._analytical_sample_model.components: + self._analytical_convolver = AnalyticalConvolution( + energy=self.energy, + energy_unit=self._energy_unit, + sample_model=self._analytical_sample_model, + resolution_model=self._resolution_model, + offset=self.offset, + ) + else: + self._analytical_convolver = None + + if self._numerical_sample_model.components: + self._numerical_convolver = NumericalConvolution( + energy=self.energy, + energy_unit=self._energy_unit, + sample_model=self.numerical_sample_model, + resolution_model=self.resolution_model, + offset=self.offset, + upsample_factor=self.upsample_factor, + extension_factor=self.extension_factor, + temperature=self.temperature, + temperature_unit=self.temperature_unit, + normalize_detailed_balance=self.normalize_detailed_balance, + ) + else: + self._numerical_convolver = None + + def _set_sample_models(self) -> None: + """ " Separate sample model components into analytical pairs, delta functions, and the rest.""" + + analytical_sample_model = SampleModel() + delta_sample_model = SampleModel() + numerical_sample_model = SampleModel() + for sample_component in self._sample_model.components: + if isinstance(sample_component, DeltaFunction): + delta_sample_model.add_component(sample_component) + continue + pair_is_analytic = [] + for resolution_component in self.resolution_model.components: + pair_is_analytic.append( + self._check_if_pair_is_analytic( + sample_component, resolution_component + ) + ) + if all(pair_is_analytic) and self.temperature is None: + analytical_sample_model.add_component(sample_component) + else: + numerical_sample_model.add_component(sample_component) + + self._analytical_sample_model = analytical_sample_model + self._delta_sample_model = delta_sample_model + self._numerical_sample_model = numerical_sample_model diff --git a/src/easydynamics/convolution/convolution_base.py b/src/easydynamics/convolution/convolution_base.py new file mode 100644 index 0000000..a7d2f18 --- /dev/null +++ b/src/easydynamics/convolution/convolution_base.py @@ -0,0 +1,66 @@ +from typing import Optional, Union + +import numpy as np +from easyscience.variable import Parameter + +from easydynamics.sample_model import SampleModel +from easydynamics.sample_model.components.model_component import ModelComponent + +Numerical = Union[float, int] + + +class ConvolutionBase: + def __init__( + self, + energy: np.ndarray, + sample_model: Union[SampleModel, ModelComponent] = None, + resolution_model: Union[SampleModel, ModelComponent] = None, + energy_unit: str = "meV", + offset: Optional[Union[Numerical, Parameter]] = 0.0, + ): + self._energy = energy + self._sample_model = sample_model + self._resolution_model = resolution_model + self._energy_unit = energy_unit + + if not isinstance(sample_model, SampleModel): + raise TypeError( + f"`sample_model` is an instance of {type(sample_model).__name__}, but must be SampleModel." + ) + + if not isinstance(resolution_model, SampleModel): + raise TypeError( + f"`resolution_model` is an instance of {type(resolution_model).__name__}, but must be SampleModel." + ) + + if offset is None: + offset = 0.0 + + if isinstance(offset, Numerical): + offset = Parameter(value=offset, name="offset", unit=energy_unit) + + if not isinstance(offset, Parameter): + raise TypeError("Offset must be a Number or Parameter.") + + self.offset = offset + + @property + def energy(self) -> np.ndarray: + return self._energy + + @energy.setter + def energy(self, energy: np.ndarray) -> None: + self._energy = energy + + @property + def energy_unit(self) -> str: + return self._energy_unit + + @energy_unit.setter + def energy_unit(self, unit_str: str) -> None: + raise AttributeError( + ( + f"Unit is read-only. Use convert_unit to change the unit between allowed types " + f"or create a new {self.__class__.__name__} with the desired unit." + ) + ) diff --git a/src/easydynamics/convolution/numerical_convolution.py b/src/easydynamics/convolution/numerical_convolution.py new file mode 100644 index 0000000..ebd7006 --- /dev/null +++ b/src/easydynamics/convolution/numerical_convolution.py @@ -0,0 +1,141 @@ +from typing import Optional, Union + +import numpy as np +import scipp as sc +from easyscience.variable import Parameter +from scipy.signal import fftconvolve + +from easydynamics.convolution.numerical_convolution_base import NumericalConvolutionBase +from easydynamics.sample_model import ( + SampleModel, +) +from easydynamics.sample_model.components.model_component import ModelComponent +from easydynamics.utils.detailed_balance import ( + _detailed_balance_factor as detailed_balance_factor, +) + +Numerical = Union[float, int] + + +class NumericalConvolution(NumericalConvolutionBase): + """ " + Args: + energy : np.ndarray + 1D array of energy values where the convolution is evaluated. + sample_model : SampleModel or ModelComponent + The sample model to be convolved. + resolution_model : SampleModel or ModelComponent + The resolution model to convolve with. + offset_float : float, or None, optional + The offset to apply to the input array. + upsample_factor : int, optional + The factor by which to upsample the input data before convolution. Default is 5. + extension_factor : float, optional + The factor by which to extend the input data range before convolution. Default is 0.2. + temperature : Parameter, float, or None, optional + The temperature to use for detailed balance correction. Default is None. + temperature_unit : str or sc.Unit, optional + The unit of the temperature parameter. Default is 'K'. + energy_unit : str or sc.Unit, optional + The unit of the energy. Default is 'meV'. + normalize_detailed_balance : bool, optional + Whether to normalize the detailed balance factor. Default is True. + """ + + def __init__( + self, + energy: np.ndarray, + sample_model: Union[SampleModel, ModelComponent], + resolution_model: Union[SampleModel, ModelComponent], + offset: Optional[Union[Numerical, Parameter]] = 0.0, + upsample_factor: Optional[Numerical] = 5, + extension_factor: Optional[float] = 0.2, + temperature: Optional[Union[Parameter, float]] = None, + temperature_unit: Optional[Union[str, sc.Unit]] = "K", + energy_unit: Optional[Union[str, sc.Unit]] = "meV", + normalize_detailed_balance: Optional[bool] = True, + ): + super().__init__( + energy=energy, + sample_model=sample_model, + resolution_model=resolution_model, + offset=offset, + upsample_factor=upsample_factor, + extension_factor=extension_factor, + temperature=temperature, + temperature_unit=temperature_unit, + energy_unit=energy_unit, + normalize_detailed_balance=normalize_detailed_balance, + ) + + def convolution( + self, + ) -> np.ndarray: + """ + Numerical convolution using FFT with optional upsampling + extended range. + Includes detailed balance correction if temperature is provided. + + + + Returns: + np.ndarray + The convolved values evaluated at energy. + """ + + # Give warnings if peaks are very wide or very narrow + self._check_width_thresholds( + model=self.sample_model, + model_name="sample model", + ) + self._check_width_thresholds( + model=self.resolution_model, + model_name="resolution model", + ) + + # Evaluate sample model. Delta functions are already filtered out + sample_vals = self.sample_model.evaluate( + self.energy_grid.energy_dense + - self._offset.value + - self.energy_grid.energy_even_length_offset + ) + + # Detailed balance correction + if self.temperature is not None: + detailed_balance_factor_correction = detailed_balance_factor( + energy=self._energy_dense, + temperature=self.temperature, + energy_unit=self._energy_unit, + divide_by_temperature=self.normalize_detailed_balance, + ) + sample_vals *= detailed_balance_factor_correction + + # Evaluate resolution model + resolution_vals = self.resolution_model.evaluate( + self.energy_grid.energy_dense_centered + ) + + # Convolution + convolved = fftconvolve(sample_vals, resolution_vals, mode="same") + convolved *= self._energy_step # normalize + + if self.upsample_factor > 0: + # interpolate back to original energy grid + convolved = np.interp( + self.energy, + self.energy_grid.energy_dense, + convolved, + left=0.0, + right=0.0, + ) + + return convolved + + def __repr__(self) -> str: + return ( + f"NumericalConvolution(energy_unit={self._energy_unit}, " + f"offset={self.offset}, upsample_factor={self.upsample_factor}, " + f"extension_factor={self.extension_factor}, " + f"temperature={self.temperature}, " + f"temperature_unit={self.temperature_unit}, " + f"normalize_detailed_balance={self.normalize_detailed_balance})" + ) diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py new file mode 100644 index 0000000..f613815 --- /dev/null +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -0,0 +1,332 @@ +import warnings +from dataclasses import dataclass +from typing import Optional, Union + +import numpy as np +import scipp as sc +from easyscience.variable import Parameter + +from easydynamics.convolution.convolution_base import ConvolutionBase +from easydynamics.sample_model import ( + SampleModel, +) +from easydynamics.sample_model.components.model_component import ModelComponent + +Numerical = Union[float, int] + + +class NumericalConvolutionBase(ConvolutionBase): + """ " + Args: + energy : np.ndarray + 1D array of energy values where the convolution is evaluated. + sample_model : SampleModel or ModelComponent + The sample model to be convolved. + resolution_model : SampleModel or ModelComponent + The resolution model to convolve with. + offset_float : float, or None, optional + The offset to apply to the input array. + upsample_factor : int, optional + The factor by which to upsample the input data before convolution. Default is 5. + extension_factor : float, optional + The factor by which to extend the input data range before convolution. Default is 0.2. + temperature : Parameter, float, or None, optional + The temperature to use for detailed balance correction. Default is None. + temperature_unit : str or sc.Unit, optional + The unit of the temperature parameter. Default is 'K'. + energy_unit : str or sc.Unit, optional + The unit of the energy. Default is 'meV'. + normalize_detailed_balance : bool, optional + Whether to normalize the detailed balance factor. Default is True. + """ + + def __init__( + self, + energy: np.ndarray, + sample_model: Union[SampleModel, ModelComponent], + resolution_model: Union[SampleModel, ModelComponent], + offset: Optional[Union[Numerical, Parameter]] = 0.0, + upsample_factor: Optional[Numerical] = 5, + extension_factor: Optional[float] = 0.2, + temperature: Optional[Union[Parameter, float]] = None, + temperature_unit: Optional[Union[str, sc.Unit]] = "K", + energy_unit: Optional[Union[str, sc.Unit]] = "meV", + normalize_detailed_balance: Optional[bool] = True, + ): + super().__init__( + energy=energy, + sample_model=sample_model, + resolution_model=resolution_model, + energy_unit=energy_unit, + offset=offset, + ) + + if temperature is not None: + if isinstance(temperature, Numerical): + temperature = Parameter( + name="temperature", + value=float(temperature), + unit=temperature_unit, + fixed=True, + ) + elif not isinstance(temperature, Parameter): + raise TypeError("Temperature must be a float or Parameter.") + self._temperature = temperature + self._normalize_detailed_balance = normalize_detailed_balance + + self._upsample_factor = upsample_factor + self._extension_factor = extension_factor + + # Create a dense grid to improve accuracy. When upsample_factor>1, we evaluate on this grid and interpolate back to the original values at the end + self.energy_grid = self._create_dense_grid() + + # Properties for private attributes + + @ConvolutionBase.energy.setter + def energy(self, energy: np.ndarray) -> None: + super().energy = energy + # Recreate dense grid when energy is updated + self.energy_grid = self._create_dense_grid() + + @property + def upsample_factor(self) -> Numerical: + """ + Get the upsample factor. + """ + + return self._upsample_factor + + @upsample_factor.setter + def upsample_factor(self, factor: Numerical) -> None: + """ + Set the upsample factor and recreate the dense grid.""" + if not isinstance(factor, Numerical): + raise TypeError("Upsample factor must be a numerical value.") + factor = float(factor) + if factor < 1.0: + raise ValueError("Upsample factor must be greater than 1.") + + self._upsample_factor = factor + # Recreate dense grid when upsample factor is updated + self.energy_grid = self._create_dense_grid() + + @property + def extension_factor(self) -> float: + """ + Get the extension factor. + """ + + return self._extension_factor + + @extension_factor.setter + def extension_factor(self, factor: Numerical) -> None: + """ + Set the extension factor and recreate the dense grid.""" + if not isinstance(factor, Numerical): + raise TypeError("Extension factor must be a number.") + if factor < 0.0: + raise ValueError("Extension factor must be non-negative.") + + self._extension_factor = factor + # Recreate dense grid when extension factor is updated + self.energy_grid = self._create_dense_grid() + + @property + def temperature(self) -> Optional[Parameter]: + """ + Get the temperature. + """ + + return self._temperature + + @temperature.setter + def temperature(self, temp: Optional[Union[Parameter, float]]) -> None: + """ + Set the temperature. + """ + + if temp is None: + self._temperature = None + elif isinstance(temp, Numerical): + self._temperature.value = float(temp) + elif isinstance(temp, Parameter): + self._temperature = temp + else: + raise TypeError("Temperature must be a float or Parameter.") + + @property + def normalize_detailed_balance(self) -> bool: + """ + Get whether to normalize the detailed balance factor. + """ + + return self._normalize_detailed_balance + + @normalize_detailed_balance.setter + def normalize_detailed_balance(self, normalize: bool) -> None: + """ + Set whether to normalize the detailed balance factor. + """ + + if not isinstance(normalize, bool): + raise TypeError("normalize_detailed_balance must be True or False.") + + self._normalize_detailed_balance = normalize + + @dataclass(frozen=True) + class EnergyGrid: + """Container for the dense energy grid and related metadata. + + Attributes: + energy_dense: the (possibly extended & upsampled) energy grid (1D). + span_original: span of the original energy array (max-min). + span_dense: span of the dense grid (max-min). + energy_even_length_offset: -0.5*dE if length is even, else 0.0 — used to correct half-bin shift. + energy_dense_centered: energy_dense recentered around zero (same length as energy_dense). + energy_step: grid spacing (dE) of energy_dense (positive float). + """ + + energy_dense: np.ndarray + span_original: float + span_dense: float + energy_even_length_offset: float + energy_dense_centered: np.ndarray + energy_step: float + + def _create_dense_grid( + self, + ) -> EnergyGrid: + """ + Create a dense grid by upsampling and extending the input energy array. + + Args: + energy : np.ndarray + 1D array of energy values. + upsample_factor : int, optional + The factor by which to upsample the input data. Default is 5. + extension_factor : float, optional + The factor by which to extend the input data range. Default is 0.2. + Returns: + DenseGrid + The dense grid created by upsampling and extending x. + """ + if self.upsample_factor == 0: + # Check if the array is uniformly spaced. + energy_diff = np.diff(self.energy) + is_uniform = np.allclose(energy_diff, energy_diff[0]) + if not is_uniform: + raise ValueError( + "Input array `energy` must be uniformly spaced if upsample_factor = 0." + ) + energy_dense = self.energy + else: + # Create an extended and upsampled energy grid + energy_min, energy_max = self.energy.min(), self.energy.max() + span = energy_max - energy_min + extra = self.extension_factor * span + extended_min = energy_min - extra + extended_max = energy_max + extra + num_points = round(len(self.energy) * self.upsample_factor) + energy_dense = np.linspace(extended_min, extended_max, num_points) + + energy_step = energy_dense[1] - energy_dense[0] + + # Handle offset for even length of x in convolution. + # The convolution of two arrays of length N is of length 2N-1. When using 'same' mode, only the central N points are kept, + # so the output has the same length as the input. + # However, if N is even, the center falls between two points, leading to a half-bin offset. + # For example, if N=4, the convolution has length 7, and when we select the 4 central points we either get + # indices [2,3,4,5] or [1,2,3,4], both of which are offset by 0.5*dx from the true center at index 3.5. + if len(energy_dense) % 2 == 0: + x_even_length_offset = -0.5 * energy_step + else: + x_even_length_offset = 0.0 + + # Handle the case when x is not symmetric around zero. The resolution is still centered around zero (or close to it), so it needs to be evaluated there. + if not np.isclose(energy_dense.mean(), 0.0): + energy_dense_centered = np.linspace( + -0.5 * span, 0.5 * span, len(energy_dense) + ) + else: + energy_dense_centered = energy_dense + + energy_grid = self.EnergyGrid( + energy_dense=energy_dense, + span_original=span, + span_dense=span, + energy_even_length_offset=x_even_length_offset, + energy_dense_centered=energy_dense_centered, + energy_step=energy_step, + ) + + return energy_grid + + def _check_width_thresholds( + self, + model: Union[SampleModel, ModelComponent], + model_name: str, + ) -> None: + """ + Helper function to check and warn if components are wide compared to the span of the data, or narrow compared to the spacing. + In both cases, the convolution accuracy may be compromised. + Args: + model : SampleModel or ModelComponent + The model to check. + energy_step : float + The bin spacing of the energy array. + span : float + The total span of the energy array. + model_name : str + A string indicating whether the model is a 'sample model' or 'resolution model' for warning messages. + returns: + None + warns: + UserWarning + If the component widths are not appropriate for the data span or bin spacing. + + """ + + # The thresholds are illustrated in performance_tests/convolution/convolution_width_thresholds.ipynb + LARGE_WIDTH_THRESHOLD = 0.1 # Threshold for large widths compared to span - warn if width > 10% of span + SMALL_WIDTH_THRESHOLD = 1.0 # Threshold for small widths compared to bin spacing - warn if width < dx + + # Handle SampleModel or ModelComponent + if isinstance(model, SampleModel): + components = model.components + else: + components = [model] # Treat single ModelComponent as a list + + for comp in components: + if hasattr(comp, "width"): + if ( + comp.width.value + > LARGE_WIDTH_THRESHOLD * self.energy_grid.span_dense + ): + warnings.warn( + f"The width of the {model_name} component '{comp.name}' ({comp.width.value}) is large compared to the span of the input " + f"array ({self.energy_grid.span_dense}). This may lead to inaccuracies in the convolution. Increase extension_factor to improve accuracy.", + UserWarning, + ) + if ( + comp.width.value + < SMALL_WIDTH_THRESHOLD * self.energy_grid.energy_step + ): + warnings.warn( + f"The width of the {model_name} component '{comp.name}' ({comp.width.value}) is small compared to the spacing of the input " + f"array ({self.energy_grid.energy_step}). This may lead to inaccuracies in the convolution. Increase upsample_factor to improve accuracy.", + UserWarning, + ) + + def __repr__(self) -> str: + return ( + f"{self.__class__.__name__}(" + f"energy=array of shape {self.energy.shape}, " + f"sample_model={self.sample_model}, " + f"resolution_model={self.resolution_model}, " + f"energy_unit={self._energy_unit}, " + f"offset={self.offset}, " + f"upsample_factor={self.upsample_factor}, " + f"extension_factor={self.extension_factor}, " + f"temperature={self.temperature}, " + f"normalize_detailed_balance={self.normalize_detailed_balance})" + ) diff --git a/src/easydynamics/utils/__init__.py b/src/easydynamics/utils/__init__.py index a6bd0bf..9cf350f 100644 --- a/src/easydynamics/utils/__init__.py +++ b/src/easydynamics/utils/__init__.py @@ -1,4 +1,3 @@ -from .convolution import convolution from .detailed_balance import _detailed_balance_factor -__all__ = ["_detailed_balance_factor", "convolution"] +__all__ = ["_detailed_balance_factor"] diff --git a/src/easydynamics/utils/convolution.py b/src/easydynamics/utils/convolution.py deleted file mode 100644 index 6668fcd..0000000 --- a/src/easydynamics/utils/convolution.py +++ /dev/null @@ -1,771 +0,0 @@ -import warnings -from typing import Optional, Union - -import numpy as np -import scipp as sc -from easyscience.variable import Parameter -from scipy.signal import fftconvolve -from scipy.special import voigt_profile - -from easydynamics.sample_model import ( - DeltaFunction, - Gaussian, - Lorentzian, - SampleModel, - Voigt, -) -from easydynamics.sample_model.components.model_component import ModelComponent -from easydynamics.utils.detailed_balance import ( - _detailed_balance_factor as detailed_balance_factor, -) - -Numerical = Union[float, int] - - -class Convolution: - def __init__(self): - pass - - # def _find_delta_components(self, - # model: Union[SampleModel, ModelComponent], - # ) -> List[DeltaFunction]: - # """Return a list of DeltaFunction instances contained in `model`. - - # Args: - # model : SampleModel or ModelComponent - # The model to search for DeltaFunction components. - # Returns: - # List[DeltaFunction] - # A list of DeltaFunction components found in the model. - # """ - # if isinstance(model, DeltaFunction): - # return [model] - # if isinstance(model, SampleModel): - # return [c for c in model.components if isinstance(c, DeltaFunction)] - # return [] - - # def _calculate_delta_contributions(self, - # energy: np.ndarray, - # sample_model: Union[SampleModel, ModelComponent], - # resolution_model: Union[SampleModel, ModelComponent], - # offset_float: float, - # ) -> np.ndarray: - # """ - # Calculate the contributions of delta functions in the convolution. - # Args: - # energy : np.ndarray - # 1D array of energy values where the convolution is evaluated. - # sample_model : SampleModel or ModelComponent - # The sample model to be convolved. - # resolution_model : SampleModel or ModelComponent - # The resolution model to convolve with. - # offset_float : float - # The offset to apply to the convolution. - # Returns: - # np.ndarray - # The delta function contributions evaluated at energy. - - # Raises: - # ValueError - # If both sample_model and resolution_model contain delta functions. - # """ - # delta_contributions = np.zeros_like(energy) - - # # Add delta contributions on original grid - # # collect deltas - # sample_deltas = self._find_delta_components(sample_model) - # resolution_deltas = self._find_delta_components(resolution_model) - - # # error if both contain delta(s) - # if sample_deltas and resolution_deltas: - # raise ValueError( - # "Both sample_model and resolution_model contain delta functions. " - # "Their convolution is not defined." - # ) - - # # if sample has deltas, convolve each delta with the resolution_model - # for delta in sample_deltas: - # (_, delta_contribution) = self.try_analytic_pair( - # energy=energy, - # sample_component=delta, - # resolution_component=resolution_model, - # offset_float=offset_float, - # ) - # delta_contributions += delta_contribution - - # # if resolution has deltas, convolve each delta with the sample_model - # for delta in resolution_deltas: - # (_, delta_contribution) = self.try_analytic_pair( - # energy=energy, - # sample_component=sample_model, - # resolution_component=delta, - # offset_float=offset_float, - # ) - # delta_contributions += delta_contribution - - # return delta_contributions - - -class AnalyticalConvolution: - def __init__(self): - pass - - def convolution( - self, - energy: np.ndarray, - sample_model: Union[SampleModel, ModelComponent], - resolution_model: Union[SampleModel, ModelComponent], - offset_float: float = 0.0, - ) -> np.ndarray: - """ - Convolve sample with resolution analytically if possible. Accepts SampleModel or single ModelComponent for each. - Possible analytical convolutions are any combination of delta functions, Gaussians, Lorentzians and Voigt profiles. - - Most validation happens in the main `convolution` function. - - Args: - x : np.ndarray - 1D array of x values where the convolution is evaluated. - sample_model : SampleModel or ModelComponent - The sample model to be convolved. - resolution_model : SampleModel or ModelComponent - The resolution model to convolve with. - offset_float : float - The offset to apply to the convolution. - Returns: - np.ndarray - The convolved values evaluated at x. - - Raises: - ValueError - If resolution_model contains delta functions. - ValueError - If component pair cannot be handled analytically. - - """ - - # prepare list of components - if isinstance(sample_model, SampleModel): - sample_components = sample_model.components - else: - sample_components = [sample_model] - - if isinstance(resolution_model, SampleModel): - resolution_components = resolution_model.components - else: - resolution_components = [resolution_model] - - total = np.zeros_like(energy, dtype=float) - - for sample_component in sample_components: - # Go through resolution components, adding analytical contributions - for resolution_component in resolution_components: - contrib = self._try_analytic_pair( - energy=energy, - sample_component=sample_component, - resolution_component=resolution_component, - offset_float=offset_float, - ) - total += contrib - - return total - - def _try_analytic_pair( - self, - energy: np.ndarray, - sample_component: Union[ModelComponent, SampleModel], - resolution_component: ModelComponent, - offset_float: float, - ) -> np.ndarray: - """ - Attempt an analytic convolution for component pair (sample_component, resolution_component). - Returns (True, contribution) if handled, else (False, zeros). - The convolution of two gaussian components results in another gaussian component with width sqrt(w1^2 + w2^2). - The convolution of two lorentzian components results in another lorentzian component with width w1 + w2. - The convolution of a gaussian and a lorentzian results in a voigt profile. - The convolution of a delta function with any component or SampleModel results in the same component or SampleModel shifted by the delta center. - All areas are multiplied. - - - Args: - energy: np.ndarray - 1D array of energy values where the convolution is evaluated. - sample_component : Union[ModelComponent, SampleModel] - The sample component to be convolved. - resolution_component : Union[ModelComponent, SampleModel] - The resolution component to convolve with. - offset_float : float - The offset in energyto apply to the convolution. - - Returns: - np.ndarray: The convolution result - - Raises: - ValueError: If the component pair cannot be handled analytically. - """ - - # Delta function + anything --> anything, shifted by delta center with area A1 * A2 - if isinstance(sample_component, DeltaFunction): - return sample_component.area.value * resolution_component.evaluate( - energy - sample_component.center.value - offset_float - ) - - # Gaussian + Gaussian --> Gaussian with width sqrt(w1^2 + w2^2) and area A1 * A2 - if isinstance(sample_component, Gaussian) and isinstance( - resolution_component, Gaussian - ): - width = np.sqrt( - sample_component.width.value**2 + resolution_component.width.value**2 - ) - area = sample_component.area.value * resolution_component.area.value - center = ( - sample_component.center.value + resolution_component.center.value - ) + offset_float - return self._gaussian_eval(energy, center, width, area) - - # Lorentzian + Lorentzian --> Lorentzian with width w1 + w2 and area A1 * A2 - if isinstance(sample_component, Lorentzian) and isinstance( - resolution_component, Lorentzian - ): - width = sample_component.width.value + resolution_component.width.value - area = sample_component.area.value * resolution_component.area.value - center = ( - sample_component.center.value + resolution_component.center.value - ) + offset_float - return self._lorentzian_eval(energy, center, width, area) - - # Gaussian + Lorentzian --> Voigt with area A1 * A2 - if ( - isinstance(sample_component, Gaussian) - and isinstance(resolution_component, Lorentzian) - ) or ( - isinstance(sample_component, Lorentzian) - and isinstance(resolution_component, Gaussian) - ): - if isinstance(sample_component, Gaussian): - gaussian, lorentzian = sample_component, resolution_component - else: - gaussian, lorentzian = resolution_component, sample_component - center = (gaussian.center.value + lorentzian.center.value) + offset_float - area = gaussian.area.value * lorentzian.area.value - return self._voigt_eval( - energy, center, gaussian.width.value, lorentzian.width.value, area - ) - - # Voigt + Lorentzian --> Voigt with area A1 * A2, Gaussian width unchanged, Lorentzian widths summed - if ( - isinstance(sample_component, Voigt) - and isinstance(resolution_component, Lorentzian) - ) or ( - isinstance(sample_component, Lorentzian) - and isinstance(resolution_component, Voigt) - ): - if isinstance(sample_component, Voigt): - voigt, lorentzian = sample_component, resolution_component - else: - voigt, lorentzian = resolution_component, sample_component - center = (voigt.center.value + lorentzian.center.value) + offset_float - area = voigt.area.value * lorentzian.area.value - g_width = voigt.g_width.value - l_width = voigt.l_width.value + lorentzian.width.value - return self._voigt_eval(energy, center, g_width, l_width, area) - - # Voigt + Gaussian --> Voigt with area A1 * A2, Lorentzian width unchanged, Gaussian widths summed in quadrature - if ( - isinstance(sample_component, Voigt) - and isinstance(resolution_component, Gaussian) - ) or ( - isinstance(sample_component, Gaussian) - and isinstance(resolution_component, Voigt) - ): - if isinstance(sample_component, Voigt): - voigt, gaussian = sample_component, resolution_component - else: - voigt, gaussian = resolution_component, sample_component - center = (voigt.center.value + gaussian.center.value) + offset_float - area = voigt.area.value * gaussian.area.value - l_width = voigt.l_width.value - g_width = np.sqrt(voigt.g_width.value**2 + gaussian.width.value**2) - return self._voigt_eval(energy, center, g_width, l_width, area) - - return ValueError( - f"Analytical convolution not implemented for component pair: {type(sample_component).__name__}, {type(resolution_component).__name__}" - ) - - def _gaussian_eval( - self, energy: np.ndarray, center: float, width: float, area: float - ) -> np.ndarray: - """ - Evaluate a Gaussian function. y = (area / (sqrt(2pi) * width)) * exp(-0.5 * ((x - center) / width)^2) - All checks are handled in the calling function. - - Args: - energy : np.ndarray - 1D array of energy values where the Gaussian is evaluated. - center : float - The center of the Gaussian. - width : float - The width (sigma) of the Gaussian. - area : float - The area under the Gaussian curve. - Returns: - np.ndarray - The evaluated Gaussian values at x. - """ - return ( - area - * 1 - / (np.sqrt(2 * np.pi) * width) - * np.exp(-0.5 * ((energy - center) / width) ** 2) - ) - - def _lorentzian_eval( - self, energy: np.ndarray, center: float, width: float, area: float - ) -> np.ndarray: - """ - Evaluate a Lorentzian function. y = (area * width / pi) / ((x - center)^2 + width^2). - All checks are handled in the calling function. - - Args: - energy : np.ndarray - 1D array of energy values where the Lorentzian is evaluated. - center : float - The center of the Lorentzian. - width : float - The width (HWHM) of the Lorentzian. - area : float - The area under the Lorentzian. - Returns: - np.ndarray - The evaluated Lorentzian values at x. - """ - return area * width / np.pi / ((energy - center) ** 2 + width**2) - - def _voigt_eval( - self, - energy: np.ndarray, - center: float, - g_width: float, - l_width: float, - area: float, - ) -> np.ndarray: - """ - Evaluate a Voigt profile function using scipy's voigt_profile. - Args: - energy : np.ndarray - 1D array of energy values where the Voigt profile is evaluated. - center : float - The center of the Voigt profile. - g_width : float - The Gaussian width (sigma) of the Voigt profile. - l_width : float - The Lorentzian width (HWHM) of the Voigt profile. - area : float - The area under the Voigt profile. - Returns: - np.ndarray - The evaluated Voigt profile values at x. - """ - - return area * voigt_profile(energy - center, g_width, l_width) - - -class NumericalConvolution: - def __init__(self): - self._energy_dense = None - pass - - def convolution( - self, - energy: np.ndarray, - sample_model: Union[SampleModel, ModelComponent], - resolution_model: Union[SampleModel, ModelComponent], - offset_float: Optional[float] = 0.0, - upsample_factor: Optional[int] = 5, - extension_factor: Optional[float] = 0.2, - temperature: Optional[Union[Parameter, float]] = None, - temperature_unit: Optional[Union[str, sc.Unit]] = "K", - energy_unit: Optional[Union[str, sc.Unit]] = "meV", - normalize_detailed_balance: Optional[bool] = True, - ) -> np.ndarray: - """ - Numerical convolution using FFT with optional upsampling + extended range. - Includes detailed balance correction if temperature is provided. - - - Args: - energy : np.ndarray - 1D array of energy values where the convolution is evaluated. - sample_model : SampleModel or ModelComponent - The sample model to be convolved. - resolution_model : SampleModel or ModelComponent - The resolution model to convolve with. - offset_float : float, or None, optional - The offset to apply to the input array. - upsample_factor : int, optional - The factor by which to upsample the input data before convolution. Default is 5. - extension_factor : float, optional - The factor by which to extend the input data range before convolution. Default is 0.2. - temperature : Parameter, float, or None, optional - The temperature to use for detailed balance correction. Default is None. - temperature_unit : str or sc.Unit, optional - The unit of the temperature parameter. Default is 'K'. - energy_unit : str or sc.Unit, optional - The unit of the energy. Default is 'meV'. - normalize_detailed_balance : bool, optional - Whether to normalize the detailed balance factor. Default is True. - Returns: - np.ndarray - The convolved values evaluated at energy. - """ - - # Create a dense grid to improve accuracy. We evaluate on this grid and interpolate back to the original values at the end - energy_dense = self._create_dense_grid( - energy, upsample_factor=upsample_factor, extension_factor=extension_factor - ) - - energy_step = energy_dense[1] - energy_dense[0] - span = energy_dense.max() - energy_dense.min() - # Handle offset for even length of x in convolution. - # The convolution of two arrays of length N is of length 2N-1. When using 'same' mode, only the central N points are kept, - # so the output has the same length as the input. - # However, if N is even, the center falls between two points, leading to a half-bin offset. - # For example, if N=4, the convolution has length 7, and when we select the 4 central points we either get - # indices [2,3,4,5] or [1,2,3,4], both of which are offset by 0.5*dx from the true center at index 3.5. - if len(energy_dense) % 2 == 0: - x_even_length_offset = -0.5 * energy_step - else: - x_even_length_offset = 0.0 - - # Handle the case when x is not symmetric around zero. The resolution is still centered around zero (or close to it), so it needs to be evaluated there. - if not np.isclose(energy_dense.mean(), 0.0): - energy_dense_centered = np.linspace( - -0.5 * span, 0.5 * span, len(energy_dense) - ) - else: - energy_dense_centered = energy_dense - - # Give warnings if peaks are very wide or very narrow - self._check_width_thresholds( - model=sample_model, - span=span, - energy_step=energy_step, - model_name="sample model", - ) - self._check_width_thresholds( - model=resolution_model, - span=span, - energy_step=energy_step, - model_name="resolution model", - ) - - # Evaluate sample model. Delta functions are handled separately for accuracy. - if isinstance(sample_model, SampleModel): - sample_vals = sample_model.evaluate_without_delta( - energy_dense - offset_float - x_even_length_offset - ) - elif isinstance(sample_model, DeltaFunction): - sample_vals = np.zeros_like(energy_dense) - else: - sample_vals = sample_model.evaluate( - energy_dense - offset_float - x_even_length_offset - ) - - # Detailed balance correction - if temperature is not None: - detailed_balance_factor_correction = detailed_balance_factor( - energy=energy_dense, - temperature=temperature, - energy_unit=energy_unit, - temperature_unit=temperature_unit, - divide_by_temperature=normalize_detailed_balance, - ) - sample_vals *= detailed_balance_factor_correction - - # Evaluate resolution model - if isinstance(resolution_model, SampleModel): - resolution_vals = resolution_model.evaluate_without_delta( - energy_dense_centered - ) - elif isinstance(resolution_model, DeltaFunction): - resolution_vals = np.zeros_like(energy_dense_centered) - else: - resolution_vals = resolution_model.evaluate(energy_dense_centered) - - # Convolution - convolved = fftconvolve(sample_vals, resolution_vals, mode="same") - convolved *= energy_step # normalize - - if upsample_factor > 0: - # interpolate back to original energy grid - convolved = np.interp(energy, energy_dense, convolved, left=0.0, right=0.0) - - # # Add delta function contributions - # delta_contributions = _calculate_delta_contributions( - # energy=energy, - # sample_model=sample_model, - # resolution_model=resolution_model, - # offset_float=offset_float, - # ) - # convolved += delta_contributions - - return convolved - - # ---------------------- helpers & evals ----------------------- - - def _create_dense_grid( - self, - energy: np.ndarray, - upsample_factor: int = 5, - extension_factor: float = 0.2, - ) -> np.ndarray: - """ - Create a dense grid by upsampling and extending the input energy array. - - Args: - energy : np.ndarray - 1D array of energy values. - upsample_factor : int, optional - The factor by which to upsample the input data. Default is 5. - extension_factor : float, optional - The factor by which to extend the input data range. Default is 0.2. - Returns: - np.ndarray - The dense grid created by upsampling and extending x. - """ - if upsample_factor == 0: - # Check if the array is uniformly spaced. - energy_diff = np.diff(energy) - is_uniform = np.allclose(energy_diff, energy_diff[0]) - if not is_uniform: - raise ValueError( - "Input array `energy` must be uniformly spaced if upsample_factor = 0." - ) - energy_dense = energy - else: - # Create an extended and upsampled energy grid - energy_min, energy_max = energy.min(), energy.max() - span = energy_max - energy_min - extra = extension_factor * span - extended_min = energy_min - extra - extended_max = energy_max + extra - num_points = len(energy) * upsample_factor - energy_dense = np.linspace(extended_min, extended_max, num_points) - - self._energy_dense = energy_dense - - def _check_width_thresholds( - self, - model: Union[SampleModel, ModelComponent], - span: float, - energy_step: float, - model_name: str, - ) -> None: - """ - Helper function to check and warn if components are wide compared to the span of the data, or narrow compared to the spacing. - In both cases, the convolution accuracy may be compromised. - Args: - model : SampleModel or ModelComponent - The model to check. - energy_step : float - The bin spacing of the energy array. - span : float - The total span of the energy array. - model_name : str - A string indicating whether the model is a 'sample model' or 'resolution model' for warning messages. - returns: - None - warns: - UserWarning - If the component widths are not appropriate for the data span or bin spacing. - - """ - - # The thresholds are illustrated in performance_tests/convolution/convolution_width_thresholds.ipynb - LARGE_WIDTH_THRESHOLD = 0.1 # Threshold for large widths compared to span - warn if width > 10% of span - SMALL_WIDTH_THRESHOLD = 1.0 # Threshold for small widths compared to bin spacing - warn if width < dx - - # Handle SampleModel or ModelComponent - if isinstance(model, SampleModel): - components = model.components - else: - components = [model] # Treat single ModelComponent as a list - - for comp in components: - if hasattr(comp, "width"): - if comp.width.value > LARGE_WIDTH_THRESHOLD * span: - warnings.warn( - f"The width of the {model_name} component '{comp.name}' ({comp.width.value}) is large compared to the span of the input " - f"array ({span}). This may lead to inaccuracies in the convolution. Increase extension_factor to improve accuracy.", - UserWarning, - ) - if comp.width.value < SMALL_WIDTH_THRESHOLD * energy_step: - warnings.warn( - f"The width of the {model_name} component '{comp.name}' ({comp.width.value}) is small compared to the spacing of the input " - f"array ({energy_step}). This may lead to inaccuracies in the convolution. Increase upsample_factor to improve accuracy.", - UserWarning, - ) - - -# def convolution(self, -# energy: np.ndarray, -# sample_model: Union[SampleModel, ModelComponent], -# resolution_model: Union[SampleModel, ModelComponent], -# offset: Optional[Union[Parameter, float, None]] = None, -# method: Optional[str] = "auto", -# upsample_factor: Optional[int] = 0, -# extension_factor: Optional[float] = 0.2, -# temperature: Optional[Union[Parameter, float, None]] = None, -# temperature_unit: Union[str, sc.Unit] = "K", -# energy_unit: Optional[Union[str, sc.Unit]] = "meV", -# normalize_detailed_balance: Optional[bool] = True, -# ) -> np.ndarray: -# """ -# Calculate the convolution of a sample model with a resolution model using analytical expressions or numerical FFT. -# Accepts SampleModel or ModelComponent for both sample and resolution. -# If method is 'auto', analytical convolution is preferred when possible, otherwise numerical convolution is used. -# Detailed balancing is included if temperature is provided. This requires numerical convolution and that the units -# of energy and temperature are provided. An error will be raised if the units are not compatible. -# The calculated model is shifted by the specified offset. - -# Examples: -# energy = np.linspace(-10, 10, 100) -# sample = SampleModel() -# sample.add_component(Gaussian(name="SampleGaussian", area=1.0, center=0.1, width=1.0)) -# resolution = Gaussian(name="ResolutionGaussian", area=1.0, center=0.0, width=0.5) -# result = convolution(energy, sample, resolution, offset=0.2) - -# energy = np.linspace(-10, 10, 100) -# sample = SampleModel() -# sample.add_component(Gaussian(name="Gaussian", area=1.0, center=0.1, width=1.0)) -# sample.add_component(DampedHarmonicOscillator(name="DHO", area=2.0, center=1.5, width=0.2)) -# sample.add_component(DeltaFunction(name="Delta", area=0.5, center=0.0)) - -# resolution = SampleModel() -# resolution.add_component(Gaussian(name="ResolutionGaussian", area=0.8, center=0.0, width=0.5)) -# resolution.add_component(Lorentzian(name="ResolutionLorentzian", area=0.2, center=0.1, width=0.3)) - -# result_auto = convolution(energy, sample, resolution, offset=0.2, method='auto', upsample_factor=5, extension_factor=0.2) -# result_numerical = convolution(energy, sample, resolution, offset=0.2, method='numerical', upsample_factor=5, extension_factor=0.2) - - -# Args: -# energy : np.ndarray -# 1D array of energy transfer where the convolution is evaluated. -# sample_model : SampleModel or ModelComponent -# The sample model to be convolved. -# resolution_model : SampleModel or ModelComponent -# The resolution model to convolve with. -# offset : Parameter, float, or None, optional -# The offset to apply to the x values before convolution. -# method : str, optional -# The convolution method to use: 'auto', 'analytical' or 'numerical'. Default is 'auto'. -# upsample_factor : int, optional -# The factor by which to upsample the input data before numerical convolution. Default is 0 (no upsampling). -# extension_factor : float, optional -# The factor by which to extend the input data range before numerical convolution. Default is 0.2. -# temperature : Parameter, float, or None, optional -# The temperature to use for detailed balance calculations. Default is None. -# temperature_unit : str or sc.Unit, optional -# The unit of the temperature parameter. Default is 'K'. -# energy_unit : str or sc.Unit, optional -# The unit of the energy. Default is 'meV'. -# normalize_detailed_balance : bool, optional -# Whether to normalize the detailed balance factor. Default is True. -# """ - -# # Input validation -# if not isinstance(energy, np.ndarray): -# raise TypeError( -# f"`energy` is an instance of {type(energy).__name__}, but must be a numpy array." -# ) - -# energy = np.asarray(energy, dtype=float) -# if energy.ndim != 1 or not np.all(np.isfinite(energy)): -# raise ValueError("`energy` must be a 1D finite array.") - -# if not isinstance(sample_model, (SampleModel, ModelComponent)): -# raise TypeError( -# f"`sample_model` is an instance of {type(sample_model).__name__}, but must be SampleModel or ModelComponent." -# ) - -# if not isinstance(resolution_model, (SampleModel, ModelComponent)): -# raise TypeError( -# f"`resolution_model` is an instance of {type(resolution_model).__name__}, but must be SampleModel or ModelComponent." -# ) - -# if isinstance(sample_model, SampleModel): -# if not sample_model.components: -# raise ValueError("SampleModel must have at least one component.") - -# if isinstance(resolution_model, SampleModel): -# if not resolution_model.components: -# raise ValueError("ResolutionModel must have at least one component.") - -# # Handle offset -# if offset is None: -# offset_float = 0.0 -# elif isinstance(offset, Parameter): -# offset_float = offset.value -# elif isinstance(offset, Numerical): -# offset_float = float(offset) -# else: -# raise TypeError( -# f"Expected offset to be Parameter, number, or None, got {type(offset)}" -# ) - -# if not isinstance(upsample_factor, int) or upsample_factor < 0: -# raise ValueError("upsample_factor must be a non-negative integer.") - -# if not isinstance(extension_factor, float) or extension_factor < 0.0: -# raise ValueError("extension_factor must be a non-negative float.") - -# if temperature is not None: -# if energy_unit is None: -# raise ValueError( -# "energy_unit must be provided when temperature is specified." -# ) -# if not isinstance(energy_unit, (str, sc.Unit)): -# raise TypeError( -# f"Expected energy_unit to be str or sc.Unit, got {type(energy_unit)}" -# ) - -# use_numerical_convolution_as_fallback = False -# if method == "auto": -# if temperature is not None: -# method = "numerical" -# else: -# method = "analytical" -# use_numerical_convolution_as_fallback = True - -# if method == "analytical": -# if temperature is not None: -# raise ValueError( -# "Analytical convolution is not supported with detailed balance. Set method to 'numerical' instead or set the temperature to None." -# ) -# return _analytical_convolution( -# energy=energy, -# sample_model=sample_model, -# resolution_model=resolution_model, -# offset_float=offset_float, -# use_numerical_convolution_as_fallback=use_numerical_convolution_as_fallback, -# upsample_factor=upsample_factor, -# extension_factor=extension_factor, -# ) -# elif method == "numerical": -# return _numerical_convolution( -# energy=energy, -# sample_model=sample_model, -# resolution_model=resolution_model, -# offset_float=offset_float, -# upsample_factor=upsample_factor, -# extension_factor=extension_factor, -# temperature=temperature, -# temperature_unit=temperature_unit, -# energy_unit=energy_unit, -# normalize_detailed_balance=normalize_detailed_balance, -# ) -# else: -# raise ValueError( -# f"Unknown convolution method: {method}. Choose from 'auto', 'analytical', or 'numerical'." -# ) diff --git a/tests/unit_tests/utils/test_convolution.py b/tests/unit_tests/convolution/test_convolution.py similarity index 99% rename from tests/unit_tests/utils/test_convolution.py rename to tests/unit_tests/convolution/test_convolution.py index 70fb820..079e47d 100644 --- a/tests/unit_tests/utils/test_convolution.py +++ b/tests/unit_tests/convolution/test_convolution.py @@ -4,6 +4,7 @@ from scipy.signal import fftconvolve from scipy.special import voigt_profile +from easydynamics.convolution import convolution from easydynamics.sample_model import ( DampedHarmonicOscillator, DeltaFunction, @@ -11,7 +12,6 @@ Lorentzian, SampleModel, ) -from easydynamics.utils import convolution from easydynamics.utils.detailed_balance import ( _detailed_balance_factor as detailed_balance_factor, ) From f0d2c77d4a346ac9557380407e39616eadb383d2 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 19 Nov 2025 12:15:59 +0100 Subject: [PATCH 36/71] Update example, fix minor things --- examples/convolution.ipynb | 50 +++++++++---------- .../convolution/analytical_convolution.py | 24 ++++----- src/easydynamics/convolution/convolution.py | 18 +++---- .../convolution/convolution_base.py | 24 ++++++++- .../convolution/numerical_convolution.py | 12 ++--- .../convolution/numerical_convolution_base.py | 17 ++++--- src/easydynamics/sample_model/sample_model.py | 29 ----------- 7 files changed, 83 insertions(+), 91 deletions(-) diff --git a/examples/convolution.ipynb b/examples/convolution.ipynb index 4fa9ea6..f1f41ef 100644 --- a/examples/convolution.ipynb +++ b/examples/convolution.ipynb @@ -10,7 +10,7 @@ "import numpy as np\n", "\n", "from easydynamics.sample_model import DeltaFunction, Gaussian, Lorentzian, SampleModel, DampedHarmonicOscillator\n", - "from easydynamics.utils import convolution \n", + "from easydynamics.convolution import Convolution \n", "from easydynamics.utils import _detailed_balance_factor as detailed_balance_factor\n", "\n", "import matplotlib.pyplot as plt" @@ -30,24 +30,20 @@ "lorentzian = Lorentzian(name='Lorentzian',center=-1.0,width=0.2,area=1.0)\n", "delta = DeltaFunction(name='Delta',center=0.4,area=0.5)\n", "sample_model.add_component(gaussian)\n", - "sample_model.add_component(dho)\n", + "# sample_model.add_component(dho)\n", "sample_model.add_component(lorentzian)\n", "sample_model.add_component(delta)\n", "\n", "resolution_model = SampleModel(name='resolution_model')\n", - "resolution_gaussian=Gaussian(name='Resolution Gaussian',width=0.2,area=0.8)\n", - "resolution_lorentzian = Lorentzian(name='Resolution Lorentzian',width=0.2,area=0.2)\n", + "resolution_gaussian=Gaussian(name='Resolution Gaussian',width=0.015,area=0.8)\n", + "resolution_lorentzian = Lorentzian(name='Resolution Lorentzian',width=0.025,area=0.2)\n", "resolution_model.add_component(resolution_gaussian)\n", "resolution_model.add_component(resolution_lorentzian)\n", "\n", "energy=np.linspace(-2, 2, 100)\n", "\n", - "\n", - "y = convolution(sample_model=sample_model,\n", - " resolution_model=resolution_model,\n", - " energy=energy,\n", - " )\n", - "\n", + "convolver = Convolution(sample_model=sample_model, resolution_model=resolution_model, energy=energy)\n", + "y = convolver.convolution()\n", "plt.plot(energy, y, label='Convoluted Model')\n", "plt.xlabel('Energy (meV)')\n", "plt.ylabel('Intensity (arb. units)')\n", @@ -69,6 +65,7 @@ "metadata": {}, "outputs": [], "source": [ + "\n", "# Use some of the extra settings for the numerical convolution\n", "sample_model=SampleModel(name='sample_model')\n", "gaussian=Gaussian(name='Gaussian',width=0.5,area=1)\n", @@ -80,32 +77,33 @@ "sample_model.add_component(lorentzian)\n", "\n", "resolution_model = SampleModel(name='resolution_model')\n", - "resolution_gaussian=Gaussian(name='Resolution Gaussian',width=0.2,area=0.8)\n", - "resolution_lorentzian = Lorentzian(name='Resolution Lorentzian',width=0.2,area=0.2)\n", + "resolution_gaussian=Gaussian(name='Resolution Gaussian',width=0.15,area=0.8)\n", + "resolution_lorentzian = Lorentzian(name='Resolution Lorentzian',width=0.25,area=0.2)\n", "resolution_model.add_component(resolution_gaussian)\n", "resolution_model.add_component(resolution_lorentzian)\n", "\n", "energy=np.linspace(-2, 2, 100)\n", "\n", "\n", - "temperature = 15.0 # Temperature in Kelvin\n", - "offset = 0.3\n", - "upsample_factor = 5\n", - "extension_factor = 0.2\n", + "temperature = 5.0 # Temperature in Kelvin\n", + "offset = 0.5\n", + "upsample_factor = 15\n", + "extension_factor = 0.8\n", "\n", "plt.xlabel('Energy (meV)')\n", "plt.ylabel('Intensity (arb. units)')\n", "\n", - "y = convolution(sample_model=sample_model,\n", - " resolution_model=resolution_model,\n", - " energy=energy,\n", - " offset=offset,\n", - " method=\"auto\",\n", - " upsample_factor=upsample_factor,\n", - " extension_factor=extension_factor,\n", - " temperature=temperature,\n", - " normalize_detailed_balance=True,\n", - " )\n", + "convolver = Convolution(\n", + " sample_model=sample_model, \n", + " resolution_model=resolution_model, \n", + " energy=energy, \n", + " offset=offset,\n", + " upsample_factor=upsample_factor,\n", + " extension_factor=extension_factor,\n", + " temperature=temperature,\n", + " normalize_detailed_balance=True,)\n", + "y = convolver.convolution()\n", + "\n", "\n", "plt.plot(energy, y, label='Convoluted Model')\n", "\n", diff --git a/src/easydynamics/convolution/analytical_convolution.py b/src/easydynamics/convolution/analytical_convolution.py index 49b97ac..fc1adde 100644 --- a/src/easydynamics/convolution/analytical_convolution.py +++ b/src/easydynamics/convolution/analytical_convolution.py @@ -149,10 +149,11 @@ def _calculate_analytic_pair( gaussian, lorentzian = sample_component, resolution_component else: gaussian, lorentzian = resolution_component, sample_component - return self._convolute_gauss_lorentz( - gaussian, - lorentzian, - ) + + return self._convolute_gauss_lorentz( + gaussian, + lorentzian, + ) # Gaussian + Voigt --> Voigt with area A1 * A2, Lorentzian width unchanged, Gaussian widths summed in quadrature if ( @@ -196,7 +197,8 @@ def _calculate_analytic_pair( area = voigt.area.value * lorentzian.area.value g_width = voigt.g_width.value l_width = voigt.l_width.value + lorentzian.width.value - return self._voigt_eval(self.energy, center, g_width, l_width, area) + + return self._voigt_eval(center, g_width, l_width, area) # Voigt + Voigt --> Voigt with area A1 * A2, Gaussian widths summed in quadrature, Lorentzian widths summed if isinstance(sample_component, Voigt) and isinstance( @@ -206,7 +208,6 @@ def _calculate_analytic_pair( sample_component, resolution_component, ) - return ValueError( f"Analytical convolution not implemented for component pair: {type(sample_component).__name__}, {type(resolution_component).__name__}" ) @@ -262,7 +263,7 @@ def _convolute_gauss_gauss( sample_component.center.value + resolution_component.center.value ) + self.offset.value - return self._gaussian_eval(self.energy, center, width, area) + return self._gaussian_eval(center, width, area) def _convolute_gauss_lorentz( self, @@ -289,7 +290,6 @@ def _convolute_gauss_lorentz( area = sample_component.area.value * resolution_component.area.value return self._voigt_eval( - self.energy, center, sample_component.width.value, resolution_component.width.value, @@ -324,7 +324,7 @@ def _convolute_gauss_voigt( sample_component.width.value**2 + resolution_component.g_width.value**2 ) l_width = resolution_component.l_width.value - return self._voigt_eval(self.energy, center, g_width, l_width, area) + return self._voigt_eval(center, g_width, l_width, area) def _convolute_lorentz_lorentz( self, @@ -349,7 +349,7 @@ def _convolute_lorentz_lorentz( center = ( sample_component.center.value + resolution_component.center.value ) + self.offset.value - return self._lorentzian_eval(self.energy, center, width, area) + return self._lorentzian_eval(center, width, area) def _convolute_lorentz_voigt( self, @@ -375,7 +375,7 @@ def _convolute_lorentz_voigt( area = sample_component.area.value * resolution_component.area.value g_width = resolution_component.g_width.value l_width = sample_component.width.value + resolution_component.l_width.value - return self._voigt_eval(self.energy, center, g_width, l_width, area) + return self._voigt_eval(center, g_width, l_width, area) def convolute_voigt_voigt( self, @@ -403,7 +403,7 @@ def convolute_voigt_voigt( sample_component.g_width.value**2 + resolution_component.g_width.value**2 ) l_width = sample_component.l_width.value + resolution_component.l_width.value - return self._voigt_eval(self.energy, center, g_width, l_width, area) + return self._voigt_eval(center, g_width, l_width, area) def _gaussian_eval(self, center: float, width: float, area: float) -> np.ndarray: """ diff --git a/src/easydynamics/convolution/convolution.py b/src/easydynamics/convolution/convolution.py index 72111be..acecbcf 100644 --- a/src/easydynamics/convolution/convolution.py +++ b/src/easydynamics/convolution/convolution.py @@ -162,14 +162,14 @@ def _set_convolvers(self) -> None: self._numerical_convolver = NumericalConvolution( energy=self.energy, energy_unit=self._energy_unit, - sample_model=self.numerical_sample_model, - resolution_model=self.resolution_model, - offset=self.offset, - upsample_factor=self.upsample_factor, - extension_factor=self.extension_factor, - temperature=self.temperature, - temperature_unit=self.temperature_unit, - normalize_detailed_balance=self.normalize_detailed_balance, + sample_model=self._numerical_sample_model, + resolution_model=self._resolution_model, + offset=self._offset, + upsample_factor=self._upsample_factor, + extension_factor=self._extension_factor, + temperature=self._temperature, + temperature_unit=self._temperature_unit, + normalize_detailed_balance=self._normalize_detailed_balance, ) else: self._numerical_convolver = None @@ -185,7 +185,7 @@ def _set_sample_models(self) -> None: delta_sample_model.add_component(sample_component) continue pair_is_analytic = [] - for resolution_component in self.resolution_model.components: + for resolution_component in self._resolution_model.components: pair_is_analytic.append( self._check_if_pair_is_analytic( sample_component, resolution_component diff --git a/src/easydynamics/convolution/convolution_base.py b/src/easydynamics/convolution/convolution_base.py index a7d2f18..cb44b13 100644 --- a/src/easydynamics/convolution/convolution_base.py +++ b/src/easydynamics/convolution/convolution_base.py @@ -42,7 +42,7 @@ def __init__( if not isinstance(offset, Parameter): raise TypeError("Offset must be a Number or Parameter.") - self.offset = offset + self._offset = offset @property def energy(self) -> np.ndarray: @@ -64,3 +64,25 @@ def energy_unit(self, unit_str: str) -> None: f"or create a new {self.__class__.__name__} with the desired unit." ) ) + + @property + def offset(self) -> Parameter: + return self._offset + + @offset.setter + def offset(self, offset: Union[Numerical, Parameter]) -> None: + if not isinstance(offset, Parameter): + raise TypeError("Offset must be a Number or Parameter.") + + if isinstance(offset, Numerical): + self._offset.value = offset + else: + self._offset = offset + + @property + def sample_model(self) -> Union[SampleModel, ModelComponent]: + return self._sample_model + + @property + def resolution_model(self) -> Union[SampleModel, ModelComponent]: + return self._resolution_model diff --git a/src/easydynamics/convolution/numerical_convolution.py b/src/easydynamics/convolution/numerical_convolution.py index ebd7006..5cc2ae2 100644 --- a/src/easydynamics/convolution/numerical_convolution.py +++ b/src/easydynamics/convolution/numerical_convolution.py @@ -94,15 +94,15 @@ def convolution( # Evaluate sample model. Delta functions are already filtered out sample_vals = self.sample_model.evaluate( - self.energy_grid.energy_dense + self._energy_grid.energy_dense - self._offset.value - - self.energy_grid.energy_even_length_offset + - self._energy_grid.energy_even_length_offset ) # Detailed balance correction if self.temperature is not None: detailed_balance_factor_correction = detailed_balance_factor( - energy=self._energy_dense, + energy=self._energy_grid.energy_dense - self._offset.value, temperature=self.temperature, energy_unit=self._energy_unit, divide_by_temperature=self.normalize_detailed_balance, @@ -111,18 +111,18 @@ def convolution( # Evaluate resolution model resolution_vals = self.resolution_model.evaluate( - self.energy_grid.energy_dense_centered + self._energy_grid.energy_dense_centered ) # Convolution convolved = fftconvolve(sample_vals, resolution_vals, mode="same") - convolved *= self._energy_step # normalize + convolved *= self._energy_grid.energy_step # normalize if self.upsample_factor > 0: # interpolate back to original energy grid convolved = np.interp( self.energy, - self.energy_grid.energy_dense, + self._energy_grid.energy_dense, convolved, left=0.0, right=0.0, diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index f613815..44c012b 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -72,13 +72,14 @@ def __init__( elif not isinstance(temperature, Parameter): raise TypeError("Temperature must be a float or Parameter.") self._temperature = temperature + self._temperature_unit = temperature_unit self._normalize_detailed_balance = normalize_detailed_balance self._upsample_factor = upsample_factor self._extension_factor = extension_factor # Create a dense grid to improve accuracy. When upsample_factor>1, we evaluate on this grid and interpolate back to the original values at the end - self.energy_grid = self._create_dense_grid() + self._energy_grid = self._create_dense_grid() # Properties for private attributes @@ -86,7 +87,7 @@ def __init__( def energy(self, energy: np.ndarray) -> None: super().energy = energy # Recreate dense grid when energy is updated - self.energy_grid = self._create_dense_grid() + self._energy_grid = self._create_dense_grid() @property def upsample_factor(self) -> Numerical: @@ -108,7 +109,7 @@ def upsample_factor(self, factor: Numerical) -> None: self._upsample_factor = factor # Recreate dense grid when upsample factor is updated - self.energy_grid = self._create_dense_grid() + self._energy_grid = self._create_dense_grid() @property def extension_factor(self) -> float: @@ -129,7 +130,7 @@ def extension_factor(self, factor: Numerical) -> None: self._extension_factor = factor # Recreate dense grid when extension factor is updated - self.energy_grid = self._create_dense_grid() + self._energy_grid = self._create_dense_grid() @property def temperature(self) -> Optional[Parameter]: @@ -300,20 +301,20 @@ def _check_width_thresholds( if hasattr(comp, "width"): if ( comp.width.value - > LARGE_WIDTH_THRESHOLD * self.energy_grid.span_dense + > LARGE_WIDTH_THRESHOLD * self._energy_grid.span_dense ): warnings.warn( f"The width of the {model_name} component '{comp.name}' ({comp.width.value}) is large compared to the span of the input " - f"array ({self.energy_grid.span_dense}). This may lead to inaccuracies in the convolution. Increase extension_factor to improve accuracy.", + f"array ({self._energy_grid.span_dense}). This may lead to inaccuracies in the convolution. Increase extension_factor to improve accuracy.", UserWarning, ) if ( comp.width.value - < SMALL_WIDTH_THRESHOLD * self.energy_grid.energy_step + < SMALL_WIDTH_THRESHOLD * self._energy_grid.energy_step ): warnings.warn( f"The width of the {model_name} component '{comp.name}' ({comp.width.value}) is small compared to the spacing of the input " - f"array ({self.energy_grid.energy_step}). This may lead to inaccuracies in the convolution. Increase upsample_factor to improve accuracy.", + f"array ({self._energy_grid.energy_step}). This may lead to inaccuracies in the convolution. Increase upsample_factor to improve accuracy.", UserWarning, ) diff --git a/src/easydynamics/sample_model/sample_model.py b/src/easydynamics/sample_model/sample_model.py index ff23f7c..5dece61 100644 --- a/src/easydynamics/sample_model/sample_model.py +++ b/src/easydynamics/sample_model/sample_model.py @@ -7,8 +7,6 @@ from easyscience.global_object.undo_redo import NotarizedDict from easyscience.job.theoreticalmodel import TheoreticalModelBase -from easydynamics.sample_model.components import DeltaFunction - from .components.model_component import ModelComponent Numeric = Union[float, int] @@ -214,33 +212,6 @@ def evaluate( return result - def evaluate_without_delta( - self, x: Union[Numeric, list, np.ndarray, sc.Variable, sc.DataArray] - ) -> np.ndarray: - """ - Evaluate the sum of all components except delta functions. - - Parameters - ---------- - x : Number, list, np.ndarray, sc.Variable, or sc.DataArray - Energy axis. - - Returns - ------- - np.ndarray - Evaluated model values. - """ - - if not self.components: - raise ValueError("No components in the model to evaluate.") - result = None - for component in list(self): - if not isinstance(component, DeltaFunction): - value = component.evaluate(x) - result = value if result is None else result + value - - return result - def evaluate_component( self, x: Union[Numeric, list, np.ndarray, sc.Variable, sc.DataArray], From 2e1c826b63859e7c347ddbde95955f28da7b051f Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 19 Nov 2025 13:24:51 +0100 Subject: [PATCH 37/71] Allow energy to be a scipp variable --- .../convolution/analytical_convolution.py | 8 ++-- src/easydynamics/convolution/convolution.py | 10 ++--- .../convolution/convolution_base.py | 40 ++++++++++++------- .../convolution/numerical_convolution.py | 6 +-- .../convolution/numerical_convolution_base.py | 18 ++++----- 5 files changed, 46 insertions(+), 36 deletions(-) diff --git a/src/easydynamics/convolution/analytical_convolution.py b/src/easydynamics/convolution/analytical_convolution.py index fc1adde..c517ef0 100644 --- a/src/easydynamics/convolution/analytical_convolution.py +++ b/src/easydynamics/convolution/analytical_convolution.py @@ -231,7 +231,7 @@ def _convolute_delta_any( The evaluated convolution values at self.energy. """ return sample_component.area.value * resolution_model.evaluate( - self.energy - sample_component.center.value - self.offset.value + self.energy.values - sample_component.center.value - self.offset.value ) def _convolute_gauss_gauss( @@ -427,7 +427,7 @@ def _gaussian_eval(self, center: float, width: float, area: float) -> np.ndarray area * 1 / (np.sqrt(2 * np.pi) * width) - * np.exp(-0.5 * ((self.energy - center) / width) ** 2) + * np.exp(-0.5 * ((self.energy.values - center) / width) ** 2) ) def _lorentzian_eval(self, center: float, width: float, area: float) -> np.ndarray: @@ -448,7 +448,7 @@ def _lorentzian_eval(self, center: float, width: float, area: float) -> np.ndarr np.ndarray The evaluated Lorentzian values at self.energy. """ - return area * width / np.pi / ((self.energy - center) ** 2 + width**2) + return area * width / np.pi / ((self.energy.values - center) ** 2 + width**2) def _voigt_eval( self, @@ -475,4 +475,4 @@ def _voigt_eval( The evaluated Voigt profile values at self.energy. """ - return area * voigt_profile(self.energy - center, g_width, l_width) + return area * voigt_profile(self.energy.values - center, g_width, l_width) diff --git a/src/easydynamics/convolution/convolution.py b/src/easydynamics/convolution/convolution.py index acecbcf..6296a35 100644 --- a/src/easydynamics/convolution/convolution.py +++ b/src/easydynamics/convolution/convolution.py @@ -48,7 +48,7 @@ class Convolution(NumericalConvolutionBase): def __init__( self, - energy: np.ndarray, + energy: Union[np.ndarray, sc.Variable], sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], offset: Optional[Union[Numerical, Parameter]] = 0.0, @@ -84,7 +84,7 @@ def convolution( Perform convolution using analytical method where possible, and numerical method for remaining components. """ - total = np.zeros_like(self.energy, dtype=float) + total = np.zeros_like(self.energy.values, dtype=float) # Analytical convolution if self._analytical_convolver is not None: @@ -98,7 +98,9 @@ def convolution( if self._delta_sample_model.components: for sample_component in self._delta_sample_model.components: total += sample_component.area.value * self._resolution_model.evaluate( - self.energy - sample_component.center.value - self.offset.value + self.energy.values + - sample_component.center.value + - self.offset.value ) return total @@ -150,7 +152,6 @@ def _set_convolvers(self) -> None: if self._analytical_sample_model.components: self._analytical_convolver = AnalyticalConvolution( energy=self.energy, - energy_unit=self._energy_unit, sample_model=self._analytical_sample_model, resolution_model=self._resolution_model, offset=self.offset, @@ -161,7 +162,6 @@ def _set_convolvers(self) -> None: if self._numerical_sample_model.components: self._numerical_convolver = NumericalConvolution( energy=self.energy, - energy_unit=self._energy_unit, sample_model=self._numerical_sample_model, resolution_model=self._resolution_model, offset=self._offset, diff --git a/src/easydynamics/convolution/convolution_base.py b/src/easydynamics/convolution/convolution_base.py index cb44b13..8de14c8 100644 --- a/src/easydynamics/convolution/convolution_base.py +++ b/src/easydynamics/convolution/convolution_base.py @@ -1,6 +1,7 @@ from typing import Optional, Union import numpy as np +import scipp as sc from easyscience.variable import Parameter from easydynamics.sample_model import SampleModel @@ -10,18 +11,40 @@ class ConvolutionBase: + """ + Base class for convolutions of sample and resolution models. + Args: + energy : np.ndarray or scipp.Variable + 1D array of energy values where the convolution is evaluated. + sample_model : SampleModel or ModelComponent + The sample model to be convolved. + resolution_model : SampleModel or ModelComponent + The resolution model to convolve with. + energy_unit : str or sc.Unit, optional + The unit of the energy. Default is 'meV'. + offset_float : float, or None, optional + The offset to apply to the input array. + """ + def __init__( self, - energy: np.ndarray, + energy: Union[np.ndarray, sc.Variable], sample_model: Union[SampleModel, ModelComponent] = None, resolution_model: Union[SampleModel, ModelComponent] = None, energy_unit: str = "meV", offset: Optional[Union[Numerical, Parameter]] = 0.0, ): + if isinstance(energy, Numerical): + energy = np.array([energy]) + + if not isinstance(energy, (np.ndarray, sc.Variable)): + raise TypeError("Energy must be a numpy ndarray or a scipp Variable.") + if isinstance(energy, np.ndarray): + energy = sc.array(dims=["energy"], values=energy, unit=energy_unit) + self._energy = energy self._sample_model = sample_model self._resolution_model = resolution_model - self._energy_unit = energy_unit if not isinstance(sample_model, SampleModel): raise TypeError( @@ -52,19 +75,6 @@ def energy(self) -> np.ndarray: def energy(self, energy: np.ndarray) -> None: self._energy = energy - @property - def energy_unit(self) -> str: - return self._energy_unit - - @energy_unit.setter - def energy_unit(self, unit_str: str) -> None: - raise AttributeError( - ( - f"Unit is read-only. Use convert_unit to change the unit between allowed types " - f"or create a new {self.__class__.__name__} with the desired unit." - ) - ) - @property def offset(self) -> Parameter: return self._offset diff --git a/src/easydynamics/convolution/numerical_convolution.py b/src/easydynamics/convolution/numerical_convolution.py index 5cc2ae2..b4170f1 100644 --- a/src/easydynamics/convolution/numerical_convolution.py +++ b/src/easydynamics/convolution/numerical_convolution.py @@ -44,7 +44,7 @@ class NumericalConvolution(NumericalConvolutionBase): def __init__( self, - energy: np.ndarray, + energy: Union[np.ndarray, sc.Variable], sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], offset: Optional[Union[Numerical, Parameter]] = 0.0, @@ -104,7 +104,7 @@ def convolution( detailed_balance_factor_correction = detailed_balance_factor( energy=self._energy_grid.energy_dense - self._offset.value, temperature=self.temperature, - energy_unit=self._energy_unit, + energy_unit=self.energy.unit, divide_by_temperature=self.normalize_detailed_balance, ) sample_vals *= detailed_balance_factor_correction @@ -121,7 +121,7 @@ def convolution( if self.upsample_factor > 0: # interpolate back to original energy grid convolved = np.interp( - self.energy, + self.energy.values, self._energy_grid.energy_dense, convolved, left=0.0, diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index 44c012b..c2d7a34 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -42,7 +42,7 @@ class NumericalConvolutionBase(ConvolutionBase): def __init__( self, - energy: np.ndarray, + energy: Union[np.ndarray, sc.Variable], sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], offset: Optional[Union[Numerical, Parameter]] = 0.0, @@ -213,21 +213,21 @@ def _create_dense_grid( """ if self.upsample_factor == 0: # Check if the array is uniformly spaced. - energy_diff = np.diff(self.energy) + energy_diff = np.diff(self.energy.values) is_uniform = np.allclose(energy_diff, energy_diff[0]) if not is_uniform: raise ValueError( "Input array `energy` must be uniformly spaced if upsample_factor = 0." ) - energy_dense = self.energy + energy_dense = self.energy.values else: # Create an extended and upsampled energy grid - energy_min, energy_max = self.energy.min(), self.energy.max() + energy_min, energy_max = self.energy.values.min(), self.energy.values.max() span = energy_max - energy_min extra = self.extension_factor * span extended_min = energy_min - extra extended_max = energy_max + extra - num_points = round(len(self.energy) * self.upsample_factor) + num_points = round(len(self.energy.values) * self.upsample_factor) energy_dense = np.linspace(extended_min, extended_max, num_points) energy_step = energy_dense[1] - energy_dense[0] @@ -239,9 +239,9 @@ def _create_dense_grid( # For example, if N=4, the convolution has length 7, and when we select the 4 central points we either get # indices [2,3,4,5] or [1,2,3,4], both of which are offset by 0.5*dx from the true center at index 3.5. if len(energy_dense) % 2 == 0: - x_even_length_offset = -0.5 * energy_step + energy_even_length_offset = -0.5 * energy_step else: - x_even_length_offset = 0.0 + energy_even_length_offset = 0.0 # Handle the case when x is not symmetric around zero. The resolution is still centered around zero (or close to it), so it needs to be evaluated there. if not np.isclose(energy_dense.mean(), 0.0): @@ -255,7 +255,7 @@ def _create_dense_grid( energy_dense=energy_dense, span_original=span, span_dense=span, - energy_even_length_offset=x_even_length_offset, + energy_even_length_offset=energy_even_length_offset, energy_dense_centered=energy_dense_centered, energy_step=energy_step, ) @@ -321,7 +321,7 @@ def _check_width_thresholds( def __repr__(self) -> str: return ( f"{self.__class__.__name__}(" - f"energy=array of shape {self.energy.shape}, " + f"energy=array of shape {self.energy.values.shape}, " f"sample_model={self.sample_model}, " f"resolution_model={self.resolution_model}, " f"energy_unit={self._energy_unit}, " From 4d5fe405cf1aab4dceddfc163bfa3818218e767e Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 19 Nov 2025 13:33:35 +0100 Subject: [PATCH 38/71] Flesh out base class --- examples/convolution.ipynb | 3 +- .../convolution/convolution_base.py | 91 +++++++++++++++++-- 2 files changed, 82 insertions(+), 12 deletions(-) diff --git a/examples/convolution.ipynb b/examples/convolution.ipynb index f1f41ef..31a5506 100644 --- a/examples/convolution.ipynb +++ b/examples/convolution.ipynb @@ -113,8 +113,7 @@ "plt.title('Convolution of Sample Model with Resolution Model with detailed balancing')\n", "\n", "plt.legend()\n", - "plt.ylim(0,2.5)\n", - "\n" + "plt.ylim(0,2.5)\n" ] } ], diff --git a/src/easydynamics/convolution/convolution_base.py b/src/easydynamics/convolution/convolution_base.py index 8de14c8..4578ef6 100644 --- a/src/easydynamics/convolution/convolution_base.py +++ b/src/easydynamics/convolution/convolution_base.py @@ -39,6 +39,7 @@ def __init__( if not isinstance(energy, (np.ndarray, sc.Variable)): raise TypeError("Energy must be a numpy ndarray or a scipp Variable.") + if isinstance(energy, np.ndarray): energy = sc.array(dims=["energy"], values=energy, unit=energy_unit) @@ -68,19 +69,97 @@ def __init__( self._offset = offset @property - def energy(self) -> np.ndarray: + def energy(self) -> sc.Variable: + """Get the energy""" + return self._energy @energy.setter def energy(self, energy: np.ndarray) -> None: - self._energy = energy + """Set the energy. + Args: + energy : np.ndarray or scipp.Variable + 1D array of energy values where the convolution is evaluated. + + Raises: + TypeError: If energy is not a numpy ndarray or a scipp Variable. + """ + + if isinstance(energy, Numerical): + energy = np.array([energy]) + + if not isinstance(energy, (np.ndarray, sc.Variable)): + raise TypeError( + "Energy must be a Number, a numpy ndarray or a scipp Variable." + ) + + if isinstance(energy, np.ndarray): + self._energy = sc.array( + dims=["energy"], values=energy, unit=self._energy.unit + ) + + if isinstance(energy, sc.Variable): + self._energy = energy + + @property + def sample_model(self) -> Union[SampleModel, ModelComponent]: + """Get the sample model""" + return self._sample_model + + @sample_model.setter + def sample_model(self, sample_model: Union[SampleModel, ModelComponent]) -> None: + """Set the sample model. + Args: + sample_model : SampleModel or ModelComponent + The sample model to be convolved. + + Raises: + TypeError: If sample_model is not a SampleModel or ModelComponent. + """ + if not isinstance(sample_model, (SampleModel, ModelComponent)): + raise TypeError( + f"`sample_model` is an instance of {type(sample_model).__name__}, but must be a SampleModel or ModelComponent." + ) + self._sample_model = sample_model + + @property + def resolution_model(self) -> Union[SampleModel, ModelComponent]: + """Get the resolution model""" + return self._resolution_model + + @resolution_model.setter + def resolution_model( + self, resolution_model: Union[SampleModel, ModelComponent] + ) -> None: + """Set the resolution model. + Args: + resolution_model : SampleModel or ModelComponent + The resolution model to convolve with. + + Raises: + TypeError: If resolution_model is not a SampleModel or ModelComponent. + """ + if not isinstance(resolution_model, (SampleModel, ModelComponent)): + raise TypeError( + f"`resolution_model` is an instance of {type(resolution_model).__name__}, but must be a SampleModel or ModelComponent." + ) + self._resolution_model = resolution_model @property def offset(self) -> Parameter: + """Get the offset""" return self._offset @offset.setter def offset(self, offset: Union[Numerical, Parameter]) -> None: + """Set the offset. + Args: + offset : Number or Parameter + The offset to apply to the input array. + + Raises: + TypeError: If offset is not a Number or Parameter. + """ if not isinstance(offset, Parameter): raise TypeError("Offset must be a Number or Parameter.") @@ -88,11 +167,3 @@ def offset(self, offset: Union[Numerical, Parameter]) -> None: self._offset.value = offset else: self._offset = offset - - @property - def sample_model(self) -> Union[SampleModel, ModelComponent]: - return self._sample_model - - @property - def resolution_model(self) -> Union[SampleModel, ModelComponent]: - return self._resolution_model From aa271bdfdbae8bab3d94fc0cec98b296ff601905 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 19 Nov 2025 13:43:40 +0100 Subject: [PATCH 39/71] Update numerical convolution base --- .../convolution/convolution_base.py | 4 ++ .../convolution/numerical_convolution_base.py | 60 ++++++++++++++----- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/easydynamics/convolution/convolution_base.py b/src/easydynamics/convolution/convolution_base.py index 4578ef6..591cb14 100644 --- a/src/easydynamics/convolution/convolution_base.py +++ b/src/easydynamics/convolution/convolution_base.py @@ -13,6 +13,8 @@ class ConvolutionBase: """ Base class for convolutions of sample and resolution models. + This base class has no convolution functionality. + Args: energy : np.ndarray or scipp.Variable 1D array of energy values where the convolution is evaluated. @@ -44,6 +46,7 @@ def __init__( energy = sc.array(dims=["energy"], values=energy, unit=energy_unit) self._energy = energy + self._energy_unit = energy_unit self._sample_model = sample_model self._resolution_model = resolution_model @@ -100,6 +103,7 @@ def energy(self, energy: np.ndarray) -> None: if isinstance(energy, sc.Variable): self._energy = energy + self._energy_unit = energy.unit @property def sample_model(self) -> Union[SampleModel, ModelComponent]: diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index c2d7a34..c93e49c 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -16,9 +16,13 @@ class NumericalConvolutionBase(ConvolutionBase): - """ " + """ + Base class for numerical convolutions of sample and resolution models. + Provides methods to handle upsampling, extension, and detailed balance correction. + This base class has no convolution functionality. + Args: - energy : np.ndarray + energy : np.ndarray or scipp.Variable 1D array of energy values where the convolution is evaluated. sample_model : SampleModel or ModelComponent The sample model to be convolved. @@ -37,7 +41,7 @@ class NumericalConvolutionBase(ConvolutionBase): energy_unit : str or sc.Unit, optional The unit of the energy. Default is 'meV'. normalize_detailed_balance : bool, optional - Whether to normalize the detailed balance factor. Default is True. + Whether to normalize the detailed balance correction. Default is True. """ def __init__( @@ -73,6 +77,7 @@ def __init__( raise TypeError("Temperature must be a float or Parameter.") self._temperature = temperature self._temperature_unit = temperature_unit + self._normalize_detailed_balance = normalize_detailed_balance self._upsample_factor = upsample_factor @@ -81,8 +86,6 @@ def __init__( # Create a dense grid to improve accuracy. When upsample_factor>1, we evaluate on this grid and interpolate back to the original values at the end self._energy_grid = self._create_dense_grid() - # Properties for private attributes - @ConvolutionBase.energy.setter def energy(self, energy: np.ndarray) -> None: super().energy = energy @@ -108,6 +111,7 @@ def upsample_factor(self, factor: Numerical) -> None: raise ValueError("Upsample factor must be greater than 1.") self._upsample_factor = factor + # Recreate dense grid when upsample factor is updated self._energy_grid = self._create_dense_grid() @@ -115,6 +119,8 @@ def upsample_factor(self, factor: Numerical) -> None: def extension_factor(self) -> float: """ Get the extension factor. + The extension factor determines how much the energy range is extended on both sides before convolution. + 0.2 means extending by 20% of the original energy span on each side """ return self._extension_factor @@ -122,7 +128,17 @@ def extension_factor(self) -> float: @extension_factor.setter def extension_factor(self, factor: Numerical) -> None: """ - Set the extension factor and recreate the dense grid.""" + Set the extension factor and recreate the dense grid. + The extension factor determines how much the energy range is extended on both sides before convolution. + 0.2 means extending by 20% of the original energy span on each side. + + Args: + factor : float + The new extension factor. + + Raises: + TypeError: If factor is not a number. + """ if not isinstance(factor, Numerical): raise TypeError("Extension factor must be a number.") if factor < 0.0: @@ -143,17 +159,30 @@ def temperature(self) -> Optional[Parameter]: @temperature.setter def temperature(self, temp: Optional[Union[Parameter, float]]) -> None: """ - Set the temperature. + Set the temperature. If None, disables detailed balance correction and removes the temperature parameter. + Args: + temp : Parameter, float, or None + The temperature to set. The unit will be the same as the existing temperature parameter if it exists, otherwise 'K'. + Raises: + TypeError: If temp is not a float, Parameter, or None. """ if temp is None: self._temperature = None elif isinstance(temp, Numerical): - self._temperature.value = float(temp) + if self._temperature is not None: + self._temperature.value = float(temp) + else: + self._temperature = Parameter( + name="temperature", + value=float(temp), + unit=self._temperature_unit, + fixed=True, + ) elif isinstance(temp, Parameter): self._temperature = temp else: - raise TypeError("Temperature must be a float or Parameter.") + raise TypeError("Temperature must be None, a float or a Parameter.") @property def normalize_detailed_balance(self) -> bool: @@ -167,6 +196,12 @@ def normalize_detailed_balance(self) -> bool: def normalize_detailed_balance(self, normalize: bool) -> None: """ Set whether to normalize the detailed balance factor. + If True, the detailed balance factor is divided by temperature. + Args: + normalize : bool + Whether to normalize the detailed balance factor. + Raises: + TypeError: If normalize is not a bool. """ if not isinstance(normalize, bool): @@ -200,13 +235,6 @@ def _create_dense_grid( """ Create a dense grid by upsampling and extending the input energy array. - Args: - energy : np.ndarray - 1D array of energy values. - upsample_factor : int, optional - The factor by which to upsample the input data. Default is 5. - extension_factor : float, optional - The factor by which to extend the input data range. Default is 0.2. Returns: DenseGrid The dense grid created by upsampling and extending x. From 953279e25101753d1369c7088ce1b85d89ba4dab Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 19 Nov 2025 14:10:39 +0100 Subject: [PATCH 40/71] Clean up numerical convolution --- .../convolution/analytical_convolution.py | 184 +++++++++++------- .../convolution/convolution_base.py | 29 +++ .../convolution/numerical_convolution.py | 19 +- 3 files changed, 155 insertions(+), 77 deletions(-) diff --git a/src/easydynamics/convolution/analytical_convolution.py b/src/easydynamics/convolution/analytical_convolution.py index c517ef0..b9bd63a 100644 --- a/src/easydynamics/convolution/analytical_convolution.py +++ b/src/easydynamics/convolution/analytical_convolution.py @@ -1,6 +1,7 @@ from typing import Optional, Union import numpy as np +import scipp as sc from easyscience.variable import Parameter from scipy.special import voigt_profile @@ -16,16 +17,27 @@ Numerical = Union[float, int] -# TODO: update docstrings - class AnalyticalConvolution(ConvolutionBase): + """Analytical convolution of a SampleModel with a ResolutionModel. + Possible analytical convolutions are any combination of delta functions, Gaussians, Lorentzians and Voigt profiles. + Args: + energy : np.ndarray or scipp.Variable + 1D array of energy values where the convolution is evaluated. + sample_model : SampleModel or ModelComponent + The sample model to be convolved. + resolution_model : SampleModel or ModelComponent + The resolution model to convolve with. + offset : float, Parameter or None, optional + The offset in energy to apply to the convolution. + """ + def __init__( self, - energy: np.ndarray, - energy_unit: str = "meV", - sample_model: SampleModel = None, - resolution_model: SampleModel = None, + energy: Union[np.ndarray, sc.Variable], + energy_unit: Optional[Union[str, sc.Unit]] = "meV", + sample_model: Optional[SampleModel] = None, + resolution_model: Optional[SampleModel] = None, offset: Optional[Union[Numerical, Parameter]] = 0.0, ): super().__init__( @@ -43,20 +55,9 @@ def convolution( Convolve sample with resolution analytically if possible. Accepts SampleModel or single ModelComponent for each. Possible analytical convolutions are any combination of delta functions, Gaussians, Lorentzians and Voigt profiles. - Most validation happens in the main `convolution` function. - - Args: - x : np.ndarray - 1D array of x values where the convolution is evaluated. - sample_model : SampleModel or ModelComponent - The sample model to be convolved. - resolution_model : SampleModel or ModelComponent - The resolution model to convolve with. - self.offset.value : float - The offset to apply to the convolution. Returns: np.ndarray - The convolved values evaluated at x. + The convolution of the sample_model and resolution_model values evaluated at energy. Raises: ValueError @@ -121,6 +122,11 @@ def _calculate_analytic_pair( ValueError: If the component pair cannot be handled analytically. """ + if isinstance(resolution_component, DeltaFunction): + raise ValueError( + "Analytical convolution with delta function in resolution model is not supported." + ) + # Delta function + anything --> anything, shifted by delta center with area A1 * A2 if isinstance(sample_component, DeltaFunction): return self._convolute_delta_any( @@ -193,12 +199,11 @@ def _calculate_analytic_pair( lorentzian, voigt = sample_component, resolution_component else: lorentzian, voigt = resolution_component, sample_component - center = (voigt.center.value + lorentzian.center.value) + self.offset.value - area = voigt.area.value * lorentzian.area.value - g_width = voigt.g_width.value - l_width = voigt.l_width.value + lorentzian.width.value - return self._voigt_eval(center, g_width, l_width, area) + return self._convolute_lorentz_voigt( + lorentzian, + voigt, + ) # Voigt + Voigt --> Voigt with area A1 * A2, Gaussian widths summed in quadrature, Lorentzian widths summed if isinstance(sample_component, Voigt) and isinstance( @@ -258,12 +263,14 @@ def _convolute_gauss_gauss( width = np.sqrt( sample_component.width.value**2 + resolution_component.width.value**2 ) + area = sample_component.area.value * resolution_component.area.value + center = ( sample_component.center.value + resolution_component.center.value ) + self.offset.value - return self._gaussian_eval(center, width, area) + return self._gaussian_eval(area=area, center=center, width=width) def _convolute_gauss_lorentz( self, @@ -290,10 +297,10 @@ def _convolute_gauss_lorentz( area = sample_component.area.value * resolution_component.area.value return self._voigt_eval( - center, - sample_component.width.value, - resolution_component.width.value, - area, + area=area, + center=center, + gauss_width=sample_component.width.value, + lorentzian_width=resolution_component.width.value, ) def _convolute_gauss_voigt( @@ -316,15 +323,24 @@ def _convolute_gauss_voigt( np.ndarray The evaluated convolution values at self.energy. """ + area = sample_component.area.value * resolution_component.area.value + center = ( sample_component.center.value + resolution_component.center.value ) + self.offset.value - area = sample_component.area.value * resolution_component.area.value - g_width = np.sqrt( - sample_component.width.value**2 + resolution_component.g_width.value**2 + + gauss_width = np.sqrt( + sample_component.width.value**2 + resolution_component.width.value**2 + ) + + lorentzian_width = resolution_component.width.value + + return self._voigt_eval( + area=area, + center=center, + gauss_width=gauss_width, + lorentzian_width=lorentzian_width, ) - l_width = resolution_component.l_width.value - return self._voigt_eval(center, g_width, l_width, area) def _convolute_lorentz_lorentz( self, @@ -344,12 +360,15 @@ def _convolute_lorentz_lorentz( np.ndarray The evaluated convolution values at self.energy. """ - width = sample_component.width.value + resolution_component.width.value area = sample_component.area.value * resolution_component.area.value + center = ( sample_component.center.value + resolution_component.center.value ) + self.offset.value - return self._lorentzian_eval(center, width, area) + + width = sample_component.width.value + resolution_component.width.value + + return self._lorentzian_eval(area=area, center=center, width=width) def _convolute_lorentz_voigt( self, @@ -369,13 +388,24 @@ def _convolute_lorentz_voigt( np.ndarray The evaluated convolution values at self.energy. """ + area = sample_component.area.value * resolution_component.area.value + center = ( sample_component.center.value + resolution_component.center.value ) + self.offset.value - area = sample_component.area.value * resolution_component.area.value - g_width = resolution_component.g_width.value - l_width = sample_component.width.value + resolution_component.l_width.value - return self._voigt_eval(center, g_width, l_width, area) + + gauss_width = resolution_component.g_width.value + + lorentzian_width = ( + sample_component.width.value + resolution_component.l_width.value + ) + + return self._voigt_eval( + area=area, + center=center, + gauss_width=gauss_width, + lorentzian_width=lorentzian_width, + ) def convolute_voigt_voigt( self, @@ -395,84 +425,98 @@ def convolute_voigt_voigt( np.ndarray The evaluated convolution values at self.energy. """ + area = sample_component.area.value * resolution_component.area.value + center = ( sample_component.center.value + resolution_component.center.value ) + self.offset.value - area = sample_component.area.value * resolution_component.area.value - g_width = np.sqrt( + + gauss_width = np.sqrt( sample_component.g_width.value**2 + resolution_component.g_width.value**2 ) - l_width = sample_component.l_width.value + resolution_component.l_width.value - return self._voigt_eval(center, g_width, l_width, area) - def _gaussian_eval(self, center: float, width: float, area: float) -> np.ndarray: + lorentzian_width = ( + sample_component.l_width.value + resolution_component.l_width.value + ) + return self._voigt_eval( + area=area, + center=center, + gauss_width=gauss_width, + lorentzian_width=lorentzian_width, + ) + + def _gaussian_eval( + self, + area: float, + center: float, + width: float, + ) -> np.ndarray: """ Evaluate a Gaussian function. y = (area / (sqrt(2pi) * width)) * exp(-0.5 * ((x - center) / width)^2) All checks are handled in the calling function. Args: - energy : np.ndarray - 1D array of energy values where the Gaussian is evaluated. + area : float + The area under the Gaussian curve. center : float The center of the Gaussian. width : float The width (sigma) of the Gaussian. - area : float - The area under the Gaussian curve. Returns: np.ndarray The evaluated Gaussian values at self.energy. """ - return ( - area - * 1 - / (np.sqrt(2 * np.pi) * width) - * np.exp(-0.5 * ((self.energy.values - center) / width) ** 2) - ) - def _lorentzian_eval(self, center: float, width: float, area: float) -> np.ndarray: + normalization = 1 / (np.sqrt(2 * np.pi) * width) + exponent = -0.5 * ((self.energy.values - center) / width) ** 2 + + return area * normalization * np.exp(exponent) + + def _lorentzian_eval(self, area: float, center: float, width: float) -> np.ndarray: """ Evaluate a Lorentzian function. y = (area * width / pi) / ((x - center)^2 + width^2). All checks are handled in the calling function. Args: - energy : np.ndarray - 1D array of energy values where the Lorentzian is evaluated. + area : float + The area under the Lorentzian. center : float The center of the Lorentzian. width : float The width (HWHM) of the Lorentzian. - area : float - The area under the Lorentzian. Returns: np.ndarray The evaluated Lorentzian values at self.energy. """ - return area * width / np.pi / ((self.energy.values - center) ** 2 + width**2) + + normalization = width / np.pi + denominator = (self.energy.values - center) ** 2 + width**2 + + return area * normalization / denominator def _voigt_eval( self, - center: float, - g_width: float, - l_width: float, area: float, + center: float, + gauss_width: float, + lorentzian_width: float, ) -> np.ndarray: """ Evaluate a Voigt profile function using scipy's voigt_profile. Args: - energy : np.ndarray - 1D array of energy values where the Voigt profile is evaluated. + area : float + The area under the Voigt profile. center : float The center of the Voigt profile. - g_width : float + gauss_width : float The Gaussian width (sigma) of the Voigt profile. - l_width : float + lorentzian_width : float The Lorentzian width (HWHM) of the Voigt profile. - area : float - The area under the Voigt profile. Returns: np.ndarray The evaluated Voigt profile values at self.energy. """ - return area * voigt_profile(self.energy.values - center, g_width, l_width) + return area * voigt_profile( + self.energy.values - center, gauss_width, lorentzian_width + ) diff --git a/src/easydynamics/convolution/convolution_base.py b/src/easydynamics/convolution/convolution_base.py index 591cb14..614c1bd 100644 --- a/src/easydynamics/convolution/convolution_base.py +++ b/src/easydynamics/convolution/convolution_base.py @@ -105,6 +105,35 @@ def energy(self, energy: np.ndarray) -> None: self._energy = energy self._energy_unit = energy.unit + @property + def energy_unit(self) -> str: + """Get the energy unit""" + return self._energy_unit + + @energy_unit.setter + def energy_unit(self, unit_str: str) -> None: + raise AttributeError( + ( + f"Unit is read-only. Use convert_unit to change the unit between allowed types " + f"or create a new {self.__class__.__name__} with the desired unit." + ) + ) # noqa: E501 + + def convert_energy_unit(self, energy_unit: Union[str, sc.Unit]) -> None: + """Convert the energy to the specified unit + Args: + energy_unit : str or sc.Unit + The unit of the energy. + + Raises: + TypeError: If energy_unit is not a string or sc.Unit. + """ + if not isinstance(energy_unit, (str, sc.Unit)): + raise TypeError("Energy unit must be a string or sc.Unit.") + + self.energy = sc.to_unit(self.energy, energy_unit) + self._energy_unit = energy_unit + @property def sample_model(self) -> Union[SampleModel, ModelComponent]: """Get the sample model""" diff --git a/src/easydynamics/convolution/numerical_convolution.py b/src/easydynamics/convolution/numerical_convolution.py index b4170f1..12a33be 100644 --- a/src/easydynamics/convolution/numerical_convolution.py +++ b/src/easydynamics/convolution/numerical_convolution.py @@ -18,9 +18,13 @@ class NumericalConvolution(NumericalConvolutionBase): - """ " + """Numerical convolution of a SampleModel with a ResolutionModel using FFT. + Includes optional upsampling and extended range to improve accuracy. + Warns about very wide or very narrow peaks in the models. + If temperature is provided, detailed balance correction is applied to the sample model. + Args: - energy : np.ndarray + energy : np.ndarray or scipp.Variable 1D array of energy values where the convolution is evaluated. sample_model : SampleModel or ModelComponent The sample model to be convolved. @@ -39,7 +43,7 @@ class NumericalConvolution(NumericalConvolutionBase): energy_unit : str or sc.Unit, optional The unit of the energy. Default is 'meV'. normalize_detailed_balance : bool, optional - Whether to normalize the detailed balance factor. Default is True. + Whether to normalize the detailed balance correction. Default is True. """ def __init__( @@ -72,11 +76,10 @@ def convolution( self, ) -> np.ndarray: """ - Numerical convolution using FFT with optional upsampling + extended range. + Calculate the convolution of the sample and resolution models at the values + given in energy. Includes detailed balance correction if temperature is provided. - - Returns: np.ndarray The convolved values evaluated at energy. @@ -92,7 +95,7 @@ def convolution( model_name="resolution model", ) - # Evaluate sample model. Delta functions are already filtered out + # Evaluate sample model. If called via the Convolution class, delta functions are already filtered out. sample_vals = self.sample_model.evaluate( self._energy_grid.energy_dense - self._offset.value @@ -131,6 +134,8 @@ def convolution( return convolved def __repr__(self) -> str: + """String representation of the NumericalConvolution instance.""" + return ( f"NumericalConvolution(energy_unit={self._energy_unit}, " f"offset={self.offset}, upsample_factor={self.upsample_factor}, " From 40bc58a9dace5de648d948a9f85a04b087ee0834 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 19 Nov 2025 14:31:38 +0100 Subject: [PATCH 41/71] First draft of refactor done, time for tests --- examples/convolution.ipynb | 2 +- src/easydynamics/convolution/convolution.py | 92 +- .../test_analytical_convolution.py | 0 .../convolution/test_convolution.py | 852 ------------------ .../convolution/test_convolution_base.py | 0 .../convolution/test_convolution_old.py | 852 ++++++++++++++++++ .../convolution/test_numerical_convolution.py | 0 .../test_numerical_convolution_base.py | 0 8 files changed, 934 insertions(+), 864 deletions(-) create mode 100644 tests/unit_tests/convolution/test_analytical_convolution.py create mode 100644 tests/unit_tests/convolution/test_convolution_base.py create mode 100644 tests/unit_tests/convolution/test_convolution_old.py create mode 100644 tests/unit_tests/convolution/test_numerical_convolution.py create mode 100644 tests/unit_tests/convolution/test_numerical_convolution_base.py diff --git a/examples/convolution.ipynb b/examples/convolution.ipynb index 31a5506..f9ded02 100644 --- a/examples/convolution.ipynb +++ b/examples/convolution.ipynb @@ -85,7 +85,7 @@ "energy=np.linspace(-2, 2, 100)\n", "\n", "\n", - "temperature = 5.0 # Temperature in Kelvin\n", + "temperature = 15.0 # Temperature in Kelvin\n", "offset = 0.5\n", "upsample_factor = 15\n", "extension_factor = 0.8\n", diff --git a/src/easydynamics/convolution/convolution.py b/src/easydynamics/convolution/convolution.py index 6296a35..b298df2 100644 --- a/src/easydynamics/convolution/convolution.py +++ b/src/easydynamics/convolution/convolution.py @@ -21,10 +21,17 @@ class Convolution(NumericalConvolutionBase): """ - Convolution class that combines analytical and numerical convolution methods based on sample model components. + Convolution class that combines analytical and numerical convolution methods to efficiently perform convolutions + of SampleModels with ResolutionModels. + Supports analytical convolution for pairs of analytical model components (DeltaFunction, Gaussian, Lorentzian, Voigt), + while using numerical convolution for other components. + If temperature is provided, detailed balance correction is applied to the sample model. In this case, all convolutions + are handled numerically. + Includes optional upsampling and extended range to improve accuracy of the numerical convolutions. Also warns about + numerical instabilities if peaks are very wide or very narrow. Args: - energy : np.ndarray + energy : np.ndarray or scipp.Variable 1D array of energy values where the convolution is evaluated. sample_model : SampleModel or ModelComponent The sample model to be convolved. @@ -43,7 +50,7 @@ class Convolution(NumericalConvolutionBase): energy_unit : str or sc.Unit, optional The unit of the energy. Default is 'meV'. normalize_detailed_balance : bool, optional - Whether to normalize the detailed balance factor. Default is True. + Whether to normalize the detailed balance correction. Default is True. """ def __init__( @@ -72,16 +79,18 @@ def __init__( normalize_detailed_balance=normalize_detailed_balance, ) - # Separate sample model components into analytical pairs, delta functions, and the rest - self._set_sample_models() - # Initialize analytical and numerical convolvers based on sample model components - self._set_convolvers() + # Separate sample model components into pairs that can be handled analytically, delta functions, and the rest + # Also initialize analytical and numerical convolvers based on sample model component + self._separate_analytical_components() def convolution( self, ) -> np.ndarray: """ - Perform convolution using analytical method where possible, and numerical method for remaining components. + Perform convolution using analytical convolutions where possible, and numerical convolutions for the remaining components. + Returns: + np.ndarray + The convolved values evaluated at energy. """ total = np.zeros_like(self.energy.values, dtype=float) @@ -94,7 +103,7 @@ def convolution( if self._numerical_convolver is not None: total += self._numerical_convolver.convolution() - # Delta function components (no convolution needed) + # Delta function components (no convolution needed, and no detailed balancing) if self._delta_sample_model.components: for sample_component in self._delta_sample_model.components: total += sample_component.area.value * self._resolution_model.evaluate( @@ -174,16 +183,24 @@ def _set_convolvers(self) -> None: else: self._numerical_convolver = None - def _set_sample_models(self) -> None: + def _separate_analytical_components(self) -> None: """ " Separate sample model components into analytical pairs, delta functions, and the rest.""" analytical_sample_model = SampleModel() delta_sample_model = SampleModel() numerical_sample_model = SampleModel() + for sample_component in self._sample_model.components: + # If delta function, put in delta sample model and go to the next component if isinstance(sample_component, DeltaFunction): delta_sample_model.add_component(sample_component) continue + + # If temperature is set, all other components go to numerical sample model + if self.temperature is not None: + numerical_sample_model.add_component(sample_component) + continue + pair_is_analytic = [] for resolution_component in self._resolution_model.components: pair_is_analytic.append( @@ -191,7 +208,8 @@ def _set_sample_models(self) -> None: sample_component, resolution_component ) ) - if all(pair_is_analytic) and self.temperature is None: + # If all resolution components can be convolved analytically with this sample component, add it to analytical sample model + if all(pair_is_analytic): analytical_sample_model.add_component(sample_component) else: numerical_sample_model.add_component(sample_component) @@ -199,3 +217,55 @@ def _set_sample_models(self) -> None: self._analytical_sample_model = analytical_sample_model self._delta_sample_model = delta_sample_model self._numerical_sample_model = numerical_sample_model + + # Update convolvers + self._set_convolvers() + + # Update some setters so the internal sample models are updated accordingly + @NumericalConvolutionBase.sample_model.setter + def sample_model(self, sample_model: Union[SampleModel, ModelComponent]) -> None: + """Set the sample model and update internal sample models accordingly. + + Args: + sample_model : SampleModel or ModelComponent + The sample model to be convolved. + + Raises: + TypeError: If sample_model is not a SampleModel or ModelComponent. + """ + super(NumericalConvolutionBase).sample_model.sample_model = sample_model + + # Separate sample model components into pairs that can be handled analytically, delta functions, and the rest + self._separate_analytical_components() + + @NumericalConvolutionBase.resolution_model.setter + def resolution_model( + self, resolution_model: Union[SampleModel, ModelComponent] + ) -> None: + """Set the resolution model and update internal sample models accordingly. + + Args: + resolution_model : SampleModel or ModelComponent + The resolution model to convolve with. + Raises: + TypeError: If resolution_model is not a SampleModel or ModelComponent. + """ + super( + NumericalConvolutionBase + ).resolution_model.resolution_model = resolution_model + + # Separate sample model components into pairs that can be handled analytically, delta functions, and the rest + self._separate_analytical_components() + + @NumericalConvolutionBase.temperature.setter + def temperature(self, temperature: Optional[Union[Parameter, float]]) -> None: + """Set the temperature and update internal sample models accordingly. + + Args: + temperature : Parameter, float, or None + The temperature to use for detailed balance correction. + """ + super(NumericalConvolutionBase).temperature = temperature + + # Separate sample model components into pairs that can be handled analytically, delta functions, and the rest + self._separate_analytical_components() diff --git a/tests/unit_tests/convolution/test_analytical_convolution.py b/tests/unit_tests/convolution/test_analytical_convolution.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit_tests/convolution/test_convolution.py b/tests/unit_tests/convolution/test_convolution.py index 079e47d..e69de29 100644 --- a/tests/unit_tests/convolution/test_convolution.py +++ b/tests/unit_tests/convolution/test_convolution.py @@ -1,852 +0,0 @@ -import numpy as np -import pytest -from easyscience.variable import Parameter -from scipy.signal import fftconvolve -from scipy.special import voigt_profile - -from easydynamics.convolution import convolution -from easydynamics.sample_model import ( - DampedHarmonicOscillator, - DeltaFunction, - Gaussian, - Lorentzian, - SampleModel, -) -from easydynamics.utils.detailed_balance import ( - _detailed_balance_factor as detailed_balance_factor, -) - -# Numerical convolutions are not very accurate -NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE = 1e-6 -NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE = 1e-5 - - -class TestConvolution: - @pytest.fixture - def sample_model(self): - test_sample_model = SampleModel(name="TestSampleModel") - test_sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2.0)) - return test_sample_model - - @pytest.fixture - def resolution_model(self): - test_resolution_model = SampleModel(name="TestResolutionModel") - test_resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3.0)) - return test_resolution_model - - @pytest.fixture - def gaussian_component(self): - return Gaussian(center=0.1, width=0.3, area=2.0) - - @pytest.fixture - def other_gaussian_component(self): - return Gaussian(name="other Gaussian", center=0.2, width=0.4, area=3.0) - - @pytest.fixture - def lorentzian_component(self): - return Lorentzian(center=0.1, width=0.3, area=2.0) - - @pytest.fixture - def other_lorentzian_component(self): - return Lorentzian(center=0.2, width=0.4, area=3.0) - - @pytest.fixture - def energy(self): - return np.linspace(-50, 50, 50001) - - # Test convolution of components - @pytest.mark.parametrize( - "offset_obj, expected_shift", - [ - (None, 0.0), - (0.4, 0.4), - (Parameter("off", 0.4), 0.4), - ], - ids=["none", "float", "parameter"], - ) - @pytest.mark.parametrize( - "method", ["analytical", "numerical"], ids=["analytical", "numerical"] - ) - def test_components_gauss_gauss( - self, - energy, - gaussian_component, - other_gaussian_component, - offset_obj, - expected_shift, - method, - ): - "Test convolution of Gaussian sample and Gaussian resolution components without SampleModel." - "Test with different offset types and methods." - # WHEN - sample_gauss = gaussian_component - resolution_gauss = other_gaussian_component - - # THEN - calculated_convolution = convolution( - energy=energy, - sample_model=sample_gauss, - resolution_model=resolution_gauss, - offset=offset_obj, - method=method, - ) - - # EXPECT - # Convolution of two Gaussians is another Gaussian with width = sqrt(w1^2 + w2^2) - expected_width = np.sqrt( - sample_gauss.width.value**2 + resolution_gauss.width.value**2 - ) - expected_area = sample_gauss.area.value * resolution_gauss.area.value - expected_center = ( - sample_gauss.center.value + resolution_gauss.center.value + expected_shift - ) - expected_result = ( - expected_area - * np.exp(-0.5 * ((energy - expected_center) / expected_width) ** 2) - / (np.sqrt(2 * np.pi) * expected_width) - ) - - np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) - - @pytest.mark.parametrize( - "offset_obj, expected_shift", - [ - (None, 0.0), - (0.4, 0.4), - (Parameter("off", 0.4), 0.4), - ], - ids=["none", "float", "parameter"], - ) - @pytest.mark.parametrize("method", ["auto", "numerical"], ids=["auto", "numerical"]) - def test_components_DHO_gauss( - self, energy, gaussian_component, offset_obj, expected_shift, method - ): - "Test convolution of DHO sample and Gaussian resolution components without SampleModel." - "Test with different offset types and methods." - # WHEN - sample_dho = DampedHarmonicOscillator(center=1.5, width=0.3, area=2) - resolution_gauss = gaussian_component - - # THEN - calculated_convolution = convolution( - energy=energy, - sample_model=sample_dho, - resolution_model=resolution_gauss, - offset=offset_obj, - method=method, - ) - - # EXPECT - # no simple analytical form, so compute expected result via direct convolution - sample_values = sample_dho.evaluate(energy - expected_shift) - resolution_values = resolution_gauss.evaluate(energy) - expected_result = fftconvolve(sample_values, resolution_values, mode="same") - expected_result *= energy[1] - energy[0] # normalize - - np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) - - @pytest.mark.parametrize( - "offset_obj, expected_shift", - [ - (None, 0.0), - (0.4, 0.4), - (Parameter("off", 0.4), 0.4), - ], - ids=["none", "float", "parameter"], - ) - @pytest.mark.parametrize( - "method", ["analytical", "numerical"], ids=["analytical", "numerical"] - ) - def test_components_lorentzian_lorentzian( - self, - energy, - lorentzian_component, - other_lorentzian_component, - offset_obj, - expected_shift, - method, - ): - "Test convolution of Lorentzian sample and Lorentzian resolution components without SampleModel." - "Test with different offset types and methods." - # WHEN - sample_lorentzian = lorentzian_component - resolution_lorentzian = other_lorentzian_component - - # THEN - calculated_convolution = convolution( - energy=energy, - sample_model=sample_lorentzian, - resolution_model=resolution_lorentzian, - offset=offset_obj, - method=method, - upsample_factor=5, - ) - - # EXPECT - # Convolution of two Lorentzians is another Lorentzian with width = w1 + w2 - expected_width = ( - sample_lorentzian.width.value + resolution_lorentzian.width.value - ) - expected_area = sample_lorentzian.area.value * resolution_lorentzian.area.value - expected_center = ( - sample_lorentzian.center.value - + resolution_lorentzian.center.value - + expected_shift - ) - expected_result = ( - expected_area - * expected_width - / np.pi - / ((energy - expected_center) ** 2 + expected_width**2) - ) - - np.testing.assert_allclose( - calculated_convolution, - expected_result, - atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, - rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, - ) - - @pytest.mark.parametrize( - "offset_obj, expected_shift", - [ - (None, 0.0), - (0.4, 0.4), - (Parameter("off", 0.4), 0.4), - ], - ids=["none", "float", "parameter"], - ) - @pytest.mark.parametrize( - "method", ["analytical", "numerical"], ids=["analytical", "numerical"] - ) - @pytest.mark.parametrize( - "sample_is_gauss", - [True, False], - ids=["gauss_sample__lorentz_resolution", "lorentz_sample__gauss_resolution"], - ) - def test_components_gauss_lorentzian( - self, - energy, - gaussian_component, - lorentzian_component, - offset_obj, - expected_shift, - method, - sample_is_gauss, - ): - "Test convolution of Gaussian and Lorentzian components without SampleModel." - "Test with different offset types and methods." - # WHEN - if sample_is_gauss: - sample = gaussian_component - resolution = lorentzian_component - else: - sample = lorentzian_component - resolution = gaussian_component - - # THEN - calculated_convolution = convolution( - energy=energy, - sample_model=sample, - resolution_model=resolution, - offset=offset_obj, - method=method, - upsample_factor=5, - ) - - # EXPECT - expected_center = sample.center.value + resolution.center.value + expected_shift - expected_area = sample.area.value * resolution.area.value - - gaussian_width = ( - sample.width.value if sample_is_gauss else resolution.width.value - ) - lorentzian_width = ( - resolution.width.value if sample_is_gauss else sample.width.value - ) - - expected_result = expected_area * voigt_profile( - energy - expected_center, - gaussian_width, - lorentzian_width, - ) - - np.testing.assert_allclose( - calculated_convolution, - expected_result, - atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, - rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, - ) - - @pytest.mark.parametrize( - "offset_obj, expected_shift", - [ - (None, 0.0), - (0.4, 0.4), - (Parameter("off", 0.4), 0.4), - ], - ids=["none", "float", "parameter"], - ) - @pytest.mark.parametrize( - "method", ["analytical", "numerical"], ids=["analytical", "numerical"] - ) - @pytest.mark.parametrize( - "sample_is_gauss", - [True, False], - ids=["gauss_sample__delta_resolution", "delta_sample__gauss_resolution"], - ) - def test_components_delta_gauss( - self, - energy, - gaussian_component, - offset_obj, - expected_shift, - method, - sample_is_gauss, - ): - "Test convolution of Delta function sample and Gaussian resolution components without SampleModel." - "Test with different offset types and methods." - # WHEN - if sample_is_gauss: - sample = gaussian_component - resolution = DeltaFunction(name="Delta", center=0.1, area=2) - else: - sample = DeltaFunction(name="Delta", center=0.1, area=2) - resolution = gaussian_component - - # THEN - calculated_convolution = convolution( - energy=energy, - sample_model=sample, - resolution_model=resolution, - offset=offset_obj, - method=method, - ) - - # EXPECT - expected_center = sample.center.value + resolution.center.value + expected_shift - expected_area = sample.area.value * resolution.area.value - width = sample.width.value if sample_is_gauss else resolution.width.value - expected_result = ( - expected_area - * np.exp(-0.5 * ((energy - expected_center) / width) ** 2) - / (np.sqrt(2 * np.pi) * width) - ) - - np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) - - # Test convolution of SampleModel - @pytest.mark.parametrize( - "offset_obj, expected_shift", - [ - (None, 0.0), - (0.4, 0.4), - (Parameter("off", 0.4), 0.4), - ], - ids=["none", "float", "parameter"], - ) - @pytest.mark.parametrize( - "method", ["analytical", "numerical"], ids=["analytical", "numerical"] - ) - def test_model_gauss_gauss_resolution_gauss( - self, - energy, - sample_model, - resolution_model, - offset_obj, - expected_shift, - method, - ): - "Test convolution of Gaussian sample components in SampleModel and Gaussian resolution components in SampleModel." - "Test with different offset types and methods." - - # WHEN - sample_G2 = Gaussian(name="another Gaussian", center=0.3, width=0.5, area=4) - sample_model.add_component(sample_G2) - - # THEN - calculated_convolution = convolution( - energy=energy, - sample_model=sample_model, - resolution_model=resolution_model, - offset=offset_obj, - method=method, - ) - - # EXPECT - sample_G1 = sample_model["Gaussian"] - resolution_G1 = resolution_model["Gaussian"] - expected_width1 = np.sqrt( - sample_G1.width.value**2 + resolution_G1.width.value**2 - ) - expected_width2 = np.sqrt( - sample_G2.width.value**2 + resolution_G1.width.value**2 - ) - expected_area1 = sample_G1.area.value * resolution_G1.area.value - expected_area2 = sample_G2.area.value * resolution_G1.area.value - expected_center1 = ( - sample_G1.center.value + resolution_G1.center.value + expected_shift - ) - expected_center2 = ( - sample_G2.center.value + resolution_G1.center.value + expected_shift - ) - - expected_result = expected_area1 * np.exp( - -0.5 * ((energy - expected_center1) / expected_width1) ** 2 - ) / (np.sqrt(2 * np.pi) * expected_width1) + expected_area2 * np.exp( - -0.5 * ((energy - expected_center2) / expected_width2) ** 2 - ) / (np.sqrt(2 * np.pi) * expected_width2) - np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) - - @pytest.mark.parametrize( - "offset_obj, expected_shift", - [ - (None, 0.0), - (0.4, 0.4), - (Parameter("off", 0.4), 0.4), - ], - ids=["none", "float", "parameter"], - ) - @pytest.mark.parametrize( - "method", ["analytical", "numerical"], ids=["analytical", "numerical"] - ) - def test_model_lorentzian_delta_resolution_gauss( - self, - energy, - method, - lorentzian_component, - resolution_model, - offset_obj, - expected_shift, - ): - "Test convolution of Lorentzian and Delta function sample components in SampleModel and Gaussian resolution components in SampleModel." - " Result is a combination of Voigt profile and Gaussian." - # WHEN - - sample = SampleModel(name="SampleModel") - sample.add_component(lorentzian_component) - sample_delta = DeltaFunction(center=0.5, area=4, name="SampleDelta") - sample.add_component(sample_delta) - - # THEN - energy = np.linspace(-10, 10, 20001) - calculated_convolution = convolution( - energy=energy, - sample_model=sample, - resolution_model=resolution_model, - offset=offset_obj, - method=method, - upsample_factor=5, - ) - - # EXPECT: Combine Gaussian, Lorentzian, and Delta functions contributions - # - gaussian_component = resolution_model["Gaussian"] - - expected_voigt_area = ( - lorentzian_component.area.value * gaussian_component.area.value - ) - expected_voigt_center = ( - lorentzian_component.center.value - + gaussian_component.center.value - + expected_shift - ) - expected_voigt = expected_voigt_area * voigt_profile( - energy - expected_voigt_center, - gaussian_component.width.value, - lorentzian_component.width.value, - ) - expected_gauss_area = sample_delta.area.value * gaussian_component.area.value - expected_gauss_center = ( - sample_delta.center.value + gaussian_component.center.value + expected_shift - ) - expected_gauss_width = gaussian_component.width.value - expected_gauss = ( - expected_gauss_area - * np.exp( - -0.5 * ((energy - (expected_gauss_center)) / expected_gauss_width) ** 2 - ) - / (np.sqrt(2 * np.pi) * expected_gauss_width) - ) - expected_result = expected_voigt + expected_gauss - np.testing.assert_allclose( - calculated_convolution, - expected_result, - atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, - rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, - ) - - def test_numerical_convolve_with_temperature( - self, energy, sample_model, resolution_model - ): - "Test numerical convolution with detailed balance correction." - # WHEN - temperature = 300.0 # Kelvin - - # THEN - calculated_convolution = convolution( - energy=energy, - sample_model=sample_model, - resolution_model=resolution_model, - method="numerical", - upsample_factor=5, - temperature=temperature, - ) - - sample_with_db = sample_model.evaluate(energy) * detailed_balance_factor( - energy=energy, temperature=temperature - ) - resolution = resolution_model.evaluate(energy) - - expected_convolution = fftconvolve(sample_with_db, resolution, mode="same") - expected_convolution *= [energy[1] - energy[0]] # normalize - - np.testing.assert_allclose( - calculated_convolution, - expected_convolution, - atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, - rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, - ) - - @pytest.mark.parametrize( - "x", - [ - np.linspace(-10, 10, 5001), # Odd length - np.linspace(-10, 10, 5000), # Even length - ], - ids=["odd_length", "even_length"], - ) - def test_numerical_convolve_x_length_even_and_odd( - self, x, sample_model, resolution_model - ): - "Test numerical convolution with both even and odd length x arrays. With even length the FFT shifts the signal by half a bin." - - # WHEN THEN - calculated_convolution = convolution( - energy=x, - sample_model=sample_model, - resolution_model=resolution_model, - method="numerical", - upsample_factor=0, - ) - - # EXPECT - expected_convolution = convolution( - energy=x, - sample_model=sample_model, - resolution_model=resolution_model, - method="analytical", - upsample_factor=0, - ) - - np.testing.assert_allclose( - calculated_convolution, expected_convolution, atol=1e-10 - ) - - @pytest.mark.parametrize( - "upsample_factor", - [0, 2, 5, 10], - ids=["no_upsample", "upsample_2", "upsample_5", "upsample_10"], - ) - def test_numerical_convolve_upsample_factor( - self, energy, upsample_factor, sample_model, resolution_model - ): - "Test numerical convolution with different upsample factors." - # WHEN THEN - calculated_convolution = convolution( - energy=energy, - sample_model=sample_model, - resolution_model=resolution_model, - method="numerical", - upsample_factor=upsample_factor, - ) - - # EXPECT - expected_convolution = convolution( - energy=energy, - sample_model=sample_model, - resolution_model=resolution_model, - method="analytical", - upsample_factor=0, - ) - - np.testing.assert_allclose( - calculated_convolution, - expected_convolution, - atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, - rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, - ) - - @pytest.mark.parametrize( - "x", - [np.linspace(-5, 15, 20000), np.linspace(5, 15, 20000)], - ids=["asymmetric", "only_positive"], - ) - @pytest.mark.parametrize( - "upsample_factor", [0, 2, 5], ids=["no_upsample", "upsample_2", "upsample_5"] - ) - def test_numerical_convolve_x_not_symmetric( - self, x, upsample_factor, resolution_model - ): - "Test numerical convolution with asymmetric and only positive x arrays." - # WHEN - sample_model = SampleModel(name="SampleModel") - sample_model.add_component(Gaussian(center=9, width=0.3, area=2)) - - # THEN - calculated_convolution = convolution( - energy=x, - sample_model=sample_model, - resolution_model=resolution_model, - method="numerical", - upsample_factor=upsample_factor, - ) - - # EXPECT - expected_convolution = convolution( - energy=x, - sample_model=sample_model, - resolution_model=resolution_model, - method="analytical", - ) - - np.testing.assert_allclose( - calculated_convolution, - expected_convolution, - atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, - rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, - ) - - def test_numerical_convolve_x_not_uniform(self, sample_model, resolution_model): - "Test numerical convolution with non-uniform x arrays." - # WHEN - x_1 = np.linspace(-2, 0, 1000) - x_2 = np.linspace(0.001, 2, 2000) - x_non_uniform = np.concatenate([x_1, x_2]) - - # THEN - calculated_convolution = convolution( - energy=x_non_uniform, - sample_model=sample_model, - resolution_model=resolution_model, - method="numerical", - upsample_factor=5, - ) - - # EXPECT - expected_convolution = convolution( - energy=x_non_uniform, - sample_model=sample_model, - resolution_model=resolution_model, - method="analytical", - ) - - np.testing.assert_allclose( - calculated_convolution, - expected_convolution, - atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, - rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, - ) - - # Test error handling - def test_analytical_convolution_fails_with_detailed_balance( - self, energy, sample_model, resolution_model - ): - # WHEN - temperature = 300.0 - # THEN EXPECT - with pytest.raises( - ValueError, - match="Analytical convolution is not supported with detailed balance.", - ): - convolution( - energy=energy, - sample_model=sample_model, - resolution_model=resolution_model, - method="analytical", - temperature=temperature, - ) - - def test_convolution_only_accepts_auto_analytical_and_numerical_methods( - self, energy, sample_model, resolution_model - ): - # WHEN THEN EXPECT - with pytest.raises( - ValueError, - match="Unknown convolution method: unknown_method. Choose from 'auto', 'analytical', or 'numerical'.", - ): - convolution( - energy=energy, - sample_model=sample_model, - resolution_model=resolution_model, - method="unknown_method", - ) - - def test_energy_must_be_1d_finite_array(self, sample_model, resolution_model): - # WHEN THEN EXPECT - with pytest.raises(ValueError, match="`energy` must be a 1D finite array."): - convolution( - energy=np.array([[1, 2], [3, 4]]), - sample_model=sample_model, - resolution_model=resolution_model, - ) - - with pytest.raises(ValueError, match="`energy` must be a 1D finite array."): - convolution( - energy=np.array([1, 2, np.nan]), - sample_model=sample_model, - resolution_model=resolution_model, - ) - - with pytest.raises(ValueError, match="`energy` must be a 1D finite array."): - convolution( - energy=np.array([1, 2, np.inf]), - sample_model=sample_model, - resolution_model=resolution_model, - ) - - def test_numerical_convolve_requires_uniform_grid_if_no_upsample( - self, sample_model, resolution_model - ): - # WHEN - x = np.array([0, 1, 2, 4, 5]) # Non-uniform grid - - # THEN EXPECT - with pytest.raises( - ValueError, - match="Input array `energy` must be uniformly spaced if upsample_factor = 0.", - ): - convolution( - energy=x, - sample_model=sample_model, - resolution_model=resolution_model, - method="numerical", - upsample_factor=0, - ) - - def test_sample_model_must_have_components(self, resolution_model): - # WHEN - sample_model = SampleModel(name="SampleModel") - - # THEN EXPECT - with pytest.raises( - ValueError, match="SampleModel must have at least one component." - ): - convolution( - energy=np.array([0, 1, 2]), - sample_model=sample_model, - resolution_model=resolution_model, - ) - - def test_resolution_model_must_have_components(self, sample_model): - # WHEN - resolution_model = SampleModel(name="ResolutionModel") - - # THEN EXPECT - with pytest.raises( - ValueError, match="ResolutionModel must have at least one component." - ): - convolution( - energy=np.array([0, 1, 2]), - sample_model=sample_model, - resolution_model=resolution_model, - ) - - def test_numerical_convolution_wide_sample_peak_gives_warning( - self, resolution_model - ): - # WHEN - x = np.linspace(-2, 2, 20001) - - sample_gauss = Gaussian(center=0.1, width=1.9, area=2, name="SampleGauss") - sample = SampleModel(name="SampleModel") - sample.add_component(sample_gauss) - - # #THEN EXPECT - with pytest.warns( - UserWarning, - match=r"The width of the sample model component ", - ): - convolution( - energy=x, - sample_model=sample, - resolution_model=resolution_model, - method="numerical", - upsample_factor=0, - ) - - def test_numerical_convolution_wide_resolution_peak_gives_warning( - self, sample_model - ): - # WHEN - x = np.linspace(-2, 2, 20001) - - resolution_gauss = Gaussian( - center=0.3, width=1.9, area=4, name="ResolutionGauss" - ) - - resolution = SampleModel(name="ResolutionModel") - resolution.add_component(resolution_gauss) - - # #THEN EXPECT - with pytest.warns( - UserWarning, - match=r"The width of the resolution model component 'ResolutionGauss' \(1.9\) is large", - ): - convolution( - energy=x, - sample_model=sample_model, - resolution_model=resolution, - method="numerical", - upsample_factor=0, - ) - - def test_numerical_convolution_narrow_sample_peak_gives_warning( - self, resolution_model - ): - # WHEN - x = np.linspace(-2, 2, 201) - - sample_gauss1 = Gaussian(center=0.1, width=1e-3, area=2, name="SampleGauss") - - sample = SampleModel(name="SampleModel") - sample.add_component(sample_gauss1) - - # #THEN EXPECT - with pytest.warns( - UserWarning, - match=r"The width of the sample model component 'SampleGauss' \(0.001\) is small", - ): - convolution( - energy=x, - sample_model=sample, - resolution_model=resolution_model, - method="numerical", - upsample_factor=0, - ) - - def test_numerical_convolution_narrow_resolution_peak_gives_warning( - self, sample_model - ): - # WHEN - x = np.linspace(-2, 2, 201) - - resolution_gauss = Gaussian( - center=0.3, width=1e-3, area=4, name="ResolutionGauss" - ) - - resolution = SampleModel(name="ResolutionModel") - resolution.add_component(resolution_gauss) - - # #THEN EXPECT - with pytest.warns( - UserWarning, - match=r"The width of the resolution model component 'ResolutionGauss' \(0.001\) is small", - ): - convolution( - energy=x, - sample_model=sample_model, - resolution_model=resolution, - method="numerical", - upsample_factor=0, - ) diff --git a/tests/unit_tests/convolution/test_convolution_base.py b/tests/unit_tests/convolution/test_convolution_base.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit_tests/convolution/test_convolution_old.py b/tests/unit_tests/convolution/test_convolution_old.py new file mode 100644 index 0000000..98fc51e --- /dev/null +++ b/tests/unit_tests/convolution/test_convolution_old.py @@ -0,0 +1,852 @@ +# import numpy as np +# import pytest +# from easyscience.variable import Parameter +# from scipy.signal import fftconvolve +# from scipy.special import voigt_profile + +# from easydynamics.convolution import convolution +# from easydynamics.sample_model import ( +# DampedHarmonicOscillator, +# DeltaFunction, +# Gaussian, +# Lorentzian, +# SampleModel, +# ) +# from easydynamics.utils.detailed_balance import ( +# _detailed_balance_factor as detailed_balance_factor, +# ) + +# # Numerical convolutions are not very accurate +# NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE = 1e-6 +# NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE = 1e-5 + + +# class TestConvolution: +# @pytest.fixture +# def sample_model(self): +# test_sample_model = SampleModel(name="TestSampleModel") +# test_sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2.0)) +# return test_sample_model + +# @pytest.fixture +# def resolution_model(self): +# test_resolution_model = SampleModel(name="TestResolutionModel") +# test_resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3.0)) +# return test_resolution_model + +# @pytest.fixture +# def gaussian_component(self): +# return Gaussian(center=0.1, width=0.3, area=2.0) + +# @pytest.fixture +# def other_gaussian_component(self): +# return Gaussian(name="other Gaussian", center=0.2, width=0.4, area=3.0) + +# @pytest.fixture +# def lorentzian_component(self): +# return Lorentzian(center=0.1, width=0.3, area=2.0) + +# @pytest.fixture +# def other_lorentzian_component(self): +# return Lorentzian(center=0.2, width=0.4, area=3.0) + +# @pytest.fixture +# def energy(self): +# return np.linspace(-50, 50, 50001) + +# # Test convolution of components +# @pytest.mark.parametrize( +# "offset_obj, expected_shift", +# [ +# (None, 0.0), +# (0.4, 0.4), +# (Parameter("off", 0.4), 0.4), +# ], +# ids=["none", "float", "parameter"], +# ) +# @pytest.mark.parametrize( +# "method", ["analytical", "numerical"], ids=["analytical", "numerical"] +# ) +# def test_components_gauss_gauss( +# self, +# energy, +# gaussian_component, +# other_gaussian_component, +# offset_obj, +# expected_shift, +# method, +# ): +# "Test convolution of Gaussian sample and Gaussian resolution components without SampleModel." +# "Test with different offset types and methods." +# # WHEN +# sample_gauss = gaussian_component +# resolution_gauss = other_gaussian_component + +# # THEN +# calculated_convolution = convolution( +# energy=energy, +# sample_model=sample_gauss, +# resolution_model=resolution_gauss, +# offset=offset_obj, +# method=method, +# ) + +# # EXPECT +# # Convolution of two Gaussians is another Gaussian with width = sqrt(w1^2 + w2^2) +# expected_width = np.sqrt( +# sample_gauss.width.value**2 + resolution_gauss.width.value**2 +# ) +# expected_area = sample_gauss.area.value * resolution_gauss.area.value +# expected_center = ( +# sample_gauss.center.value + resolution_gauss.center.value + expected_shift +# ) +# expected_result = ( +# expected_area +# * np.exp(-0.5 * ((energy - expected_center) / expected_width) ** 2) +# / (np.sqrt(2 * np.pi) * expected_width) +# ) + +# np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) + +# @pytest.mark.parametrize( +# "offset_obj, expected_shift", +# [ +# (None, 0.0), +# (0.4, 0.4), +# (Parameter("off", 0.4), 0.4), +# ], +# ids=["none", "float", "parameter"], +# ) +# @pytest.mark.parametrize("method", ["auto", "numerical"], ids=["auto", "numerical"]) +# def test_components_DHO_gauss( +# self, energy, gaussian_component, offset_obj, expected_shift, method +# ): +# "Test convolution of DHO sample and Gaussian resolution components without SampleModel." +# "Test with different offset types and methods." +# # WHEN +# sample_dho = DampedHarmonicOscillator(center=1.5, width=0.3, area=2) +# resolution_gauss = gaussian_component + +# # THEN +# calculated_convolution = convolution( +# energy=energy, +# sample_model=sample_dho, +# resolution_model=resolution_gauss, +# offset=offset_obj, +# method=method, +# ) + +# # EXPECT +# # no simple analytical form, so compute expected result via direct convolution +# sample_values = sample_dho.evaluate(energy - expected_shift) +# resolution_values = resolution_gauss.evaluate(energy) +# expected_result = fftconvolve(sample_values, resolution_values, mode="same") +# expected_result *= energy[1] - energy[0] # normalize + +# np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) + +# @pytest.mark.parametrize( +# "offset_obj, expected_shift", +# [ +# (None, 0.0), +# (0.4, 0.4), +# (Parameter("off", 0.4), 0.4), +# ], +# ids=["none", "float", "parameter"], +# ) +# @pytest.mark.parametrize( +# "method", ["analytical", "numerical"], ids=["analytical", "numerical"] +# ) +# def test_components_lorentzian_lorentzian( +# self, +# energy, +# lorentzian_component, +# other_lorentzian_component, +# offset_obj, +# expected_shift, +# method, +# ): +# "Test convolution of Lorentzian sample and Lorentzian resolution components without SampleModel." +# "Test with different offset types and methods." +# # WHEN +# sample_lorentzian = lorentzian_component +# resolution_lorentzian = other_lorentzian_component + +# # THEN +# calculated_convolution = convolution( +# energy=energy, +# sample_model=sample_lorentzian, +# resolution_model=resolution_lorentzian, +# offset=offset_obj, +# method=method, +# upsample_factor=5, +# ) + +# # EXPECT +# # Convolution of two Lorentzians is another Lorentzian with width = w1 + w2 +# expected_width = ( +# sample_lorentzian.width.value + resolution_lorentzian.width.value +# ) +# expected_area = sample_lorentzian.area.value * resolution_lorentzian.area.value +# expected_center = ( +# sample_lorentzian.center.value +# + resolution_lorentzian.center.value +# + expected_shift +# ) +# expected_result = ( +# expected_area +# * expected_width +# / np.pi +# / ((energy - expected_center) ** 2 + expected_width**2) +# ) + +# np.testing.assert_allclose( +# calculated_convolution, +# expected_result, +# atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, +# rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, +# ) + +# @pytest.mark.parametrize( +# "offset_obj, expected_shift", +# [ +# (None, 0.0), +# (0.4, 0.4), +# (Parameter("off", 0.4), 0.4), +# ], +# ids=["none", "float", "parameter"], +# ) +# @pytest.mark.parametrize( +# "method", ["analytical", "numerical"], ids=["analytical", "numerical"] +# ) +# @pytest.mark.parametrize( +# "sample_is_gauss", +# [True, False], +# ids=["gauss_sample__lorentz_resolution", "lorentz_sample__gauss_resolution"], +# ) +# def test_components_gauss_lorentzian( +# self, +# energy, +# gaussian_component, +# lorentzian_component, +# offset_obj, +# expected_shift, +# method, +# sample_is_gauss, +# ): +# "Test convolution of Gaussian and Lorentzian components without SampleModel." +# "Test with different offset types and methods." +# # WHEN +# if sample_is_gauss: +# sample = gaussian_component +# resolution = lorentzian_component +# else: +# sample = lorentzian_component +# resolution = gaussian_component + +# # THEN +# calculated_convolution = convolution( +# energy=energy, +# sample_model=sample, +# resolution_model=resolution, +# offset=offset_obj, +# method=method, +# upsample_factor=5, +# ) + +# # EXPECT +# expected_center = sample.center.value + resolution.center.value + expected_shift +# expected_area = sample.area.value * resolution.area.value + +# gaussian_width = ( +# sample.width.value if sample_is_gauss else resolution.width.value +# ) +# lorentzian_width = ( +# resolution.width.value if sample_is_gauss else sample.width.value +# ) + +# expected_result = expected_area * voigt_profile( +# energy - expected_center, +# gaussian_width, +# lorentzian_width, +# ) + +# np.testing.assert_allclose( +# calculated_convolution, +# expected_result, +# atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, +# rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, +# ) + +# @pytest.mark.parametrize( +# "offset_obj, expected_shift", +# [ +# (None, 0.0), +# (0.4, 0.4), +# (Parameter("off", 0.4), 0.4), +# ], +# ids=["none", "float", "parameter"], +# ) +# @pytest.mark.parametrize( +# "method", ["analytical", "numerical"], ids=["analytical", "numerical"] +# ) +# @pytest.mark.parametrize( +# "sample_is_gauss", +# [True, False], +# ids=["gauss_sample__delta_resolution", "delta_sample__gauss_resolution"], +# ) +# def test_components_delta_gauss( +# self, +# energy, +# gaussian_component, +# offset_obj, +# expected_shift, +# method, +# sample_is_gauss, +# ): +# "Test convolution of Delta function sample and Gaussian resolution components without SampleModel." +# "Test with different offset types and methods." +# # WHEN +# if sample_is_gauss: +# sample = gaussian_component +# resolution = DeltaFunction(name="Delta", center=0.1, area=2) +# else: +# sample = DeltaFunction(name="Delta", center=0.1, area=2) +# resolution = gaussian_component + +# # THEN +# calculated_convolution = convolution( +# energy=energy, +# sample_model=sample, +# resolution_model=resolution, +# offset=offset_obj, +# method=method, +# ) + +# # EXPECT +# expected_center = sample.center.value + resolution.center.value + expected_shift +# expected_area = sample.area.value * resolution.area.value +# width = sample.width.value if sample_is_gauss else resolution.width.value +# expected_result = ( +# expected_area +# * np.exp(-0.5 * ((energy - expected_center) / width) ** 2) +# / (np.sqrt(2 * np.pi) * width) +# ) + +# np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) + +# # Test convolution of SampleModel +# @pytest.mark.parametrize( +# "offset_obj, expected_shift", +# [ +# (None, 0.0), +# (0.4, 0.4), +# (Parameter("off", 0.4), 0.4), +# ], +# ids=["none", "float", "parameter"], +# ) +# @pytest.mark.parametrize( +# "method", ["analytical", "numerical"], ids=["analytical", "numerical"] +# ) +# def test_model_gauss_gauss_resolution_gauss( +# self, +# energy, +# sample_model, +# resolution_model, +# offset_obj, +# expected_shift, +# method, +# ): +# "Test convolution of Gaussian sample components in SampleModel and Gaussian resolution components in SampleModel." +# "Test with different offset types and methods." + +# # WHEN +# sample_G2 = Gaussian(name="another Gaussian", center=0.3, width=0.5, area=4) +# sample_model.add_component(sample_G2) + +# # THEN +# calculated_convolution = convolution( +# energy=energy, +# sample_model=sample_model, +# resolution_model=resolution_model, +# offset=offset_obj, +# method=method, +# ) + +# # EXPECT +# sample_G1 = sample_model["Gaussian"] +# resolution_G1 = resolution_model["Gaussian"] +# expected_width1 = np.sqrt( +# sample_G1.width.value**2 + resolution_G1.width.value**2 +# ) +# expected_width2 = np.sqrt( +# sample_G2.width.value**2 + resolution_G1.width.value**2 +# ) +# expected_area1 = sample_G1.area.value * resolution_G1.area.value +# expected_area2 = sample_G2.area.value * resolution_G1.area.value +# expected_center1 = ( +# sample_G1.center.value + resolution_G1.center.value + expected_shift +# ) +# expected_center2 = ( +# sample_G2.center.value + resolution_G1.center.value + expected_shift +# ) + +# expected_result = expected_area1 * np.exp( +# -0.5 * ((energy - expected_center1) / expected_width1) ** 2 +# ) / (np.sqrt(2 * np.pi) * expected_width1) + expected_area2 * np.exp( +# -0.5 * ((energy - expected_center2) / expected_width2) ** 2 +# ) / (np.sqrt(2 * np.pi) * expected_width2) +# np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) + +# @pytest.mark.parametrize( +# "offset_obj, expected_shift", +# [ +# (None, 0.0), +# (0.4, 0.4), +# (Parameter("off", 0.4), 0.4), +# ], +# ids=["none", "float", "parameter"], +# ) +# @pytest.mark.parametrize( +# "method", ["analytical", "numerical"], ids=["analytical", "numerical"] +# ) +# def test_model_lorentzian_delta_resolution_gauss( +# self, +# energy, +# method, +# lorentzian_component, +# resolution_model, +# offset_obj, +# expected_shift, +# ): +# "Test convolution of Lorentzian and Delta function sample components in SampleModel and Gaussian resolution components in SampleModel." +# " Result is a combination of Voigt profile and Gaussian." +# # WHEN + +# sample = SampleModel(name="SampleModel") +# sample.add_component(lorentzian_component) +# sample_delta = DeltaFunction(center=0.5, area=4, name="SampleDelta") +# sample.add_component(sample_delta) + +# # THEN +# energy = np.linspace(-10, 10, 20001) +# calculated_convolution = convolution( +# energy=energy, +# sample_model=sample, +# resolution_model=resolution_model, +# offset=offset_obj, +# method=method, +# upsample_factor=5, +# ) + +# # EXPECT: Combine Gaussian, Lorentzian, and Delta functions contributions +# # +# gaussian_component = resolution_model["Gaussian"] + +# expected_voigt_area = ( +# lorentzian_component.area.value * gaussian_component.area.value +# ) +# expected_voigt_center = ( +# lorentzian_component.center.value +# + gaussian_component.center.value +# + expected_shift +# ) +# expected_voigt = expected_voigt_area * voigt_profile( +# energy - expected_voigt_center, +# gaussian_component.width.value, +# lorentzian_component.width.value, +# ) +# expected_gauss_area = sample_delta.area.value * gaussian_component.area.value +# expected_gauss_center = ( +# sample_delta.center.value + gaussian_component.center.value + expected_shift +# ) +# expected_gauss_width = gaussian_component.width.value +# expected_gauss = ( +# expected_gauss_area +# * np.exp( +# -0.5 * ((energy - (expected_gauss_center)) / expected_gauss_width) ** 2 +# ) +# / (np.sqrt(2 * np.pi) * expected_gauss_width) +# ) +# expected_result = expected_voigt + expected_gauss +# np.testing.assert_allclose( +# calculated_convolution, +# expected_result, +# atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, +# rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, +# ) + +# def test_numerical_convolve_with_temperature( +# self, energy, sample_model, resolution_model +# ): +# "Test numerical convolution with detailed balance correction." +# # WHEN +# temperature = 300.0 # Kelvin + +# # THEN +# calculated_convolution = convolution( +# energy=energy, +# sample_model=sample_model, +# resolution_model=resolution_model, +# method="numerical", +# upsample_factor=5, +# temperature=temperature, +# ) + +# sample_with_db = sample_model.evaluate(energy) * detailed_balance_factor( +# energy=energy, temperature=temperature +# ) +# resolution = resolution_model.evaluate(energy) + +# expected_convolution = fftconvolve(sample_with_db, resolution, mode="same") +# expected_convolution *= [energy[1] - energy[0]] # normalize + +# np.testing.assert_allclose( +# calculated_convolution, +# expected_convolution, +# atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, +# rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, +# ) + +# @pytest.mark.parametrize( +# "x", +# [ +# np.linspace(-10, 10, 5001), # Odd length +# np.linspace(-10, 10, 5000), # Even length +# ], +# ids=["odd_length", "even_length"], +# ) +# def test_numerical_convolve_x_length_even_and_odd( +# self, x, sample_model, resolution_model +# ): +# "Test numerical convolution with both even and odd length x arrays. With even length the FFT shifts the signal by half a bin." + +# # WHEN THEN +# calculated_convolution = convolution( +# energy=x, +# sample_model=sample_model, +# resolution_model=resolution_model, +# method="numerical", +# upsample_factor=0, +# ) + +# # EXPECT +# expected_convolution = convolution( +# energy=x, +# sample_model=sample_model, +# resolution_model=resolution_model, +# method="analytical", +# upsample_factor=0, +# ) + +# np.testing.assert_allclose( +# calculated_convolution, expected_convolution, atol=1e-10 +# ) + +# @pytest.mark.parametrize( +# "upsample_factor", +# [0, 2, 5, 10], +# ids=["no_upsample", "upsample_2", "upsample_5", "upsample_10"], +# ) +# def test_numerical_convolve_upsample_factor( +# self, energy, upsample_factor, sample_model, resolution_model +# ): +# "Test numerical convolution with different upsample factors." +# # WHEN THEN +# calculated_convolution = convolution( +# energy=energy, +# sample_model=sample_model, +# resolution_model=resolution_model, +# method="numerical", +# upsample_factor=upsample_factor, +# ) + +# # EXPECT +# expected_convolution = convolution( +# energy=energy, +# sample_model=sample_model, +# resolution_model=resolution_model, +# method="analytical", +# upsample_factor=0, +# ) + +# np.testing.assert_allclose( +# calculated_convolution, +# expected_convolution, +# atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, +# rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, +# ) + +# @pytest.mark.parametrize( +# "x", +# [np.linspace(-5, 15, 20000), np.linspace(5, 15, 20000)], +# ids=["asymmetric", "only_positive"], +# ) +# @pytest.mark.parametrize( +# "upsample_factor", [0, 2, 5], ids=["no_upsample", "upsample_2", "upsample_5"] +# ) +# def test_numerical_convolve_x_not_symmetric( +# self, x, upsample_factor, resolution_model +# ): +# "Test numerical convolution with asymmetric and only positive x arrays." +# # WHEN +# sample_model = SampleModel(name="SampleModel") +# sample_model.add_component(Gaussian(center=9, width=0.3, area=2)) + +# # THEN +# calculated_convolution = convolution( +# energy=x, +# sample_model=sample_model, +# resolution_model=resolution_model, +# method="numerical", +# upsample_factor=upsample_factor, +# ) + +# # EXPECT +# expected_convolution = convolution( +# energy=x, +# sample_model=sample_model, +# resolution_model=resolution_model, +# method="analytical", +# ) + +# np.testing.assert_allclose( +# calculated_convolution, +# expected_convolution, +# atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, +# rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, +# ) + +# def test_numerical_convolve_x_not_uniform(self, sample_model, resolution_model): +# "Test numerical convolution with non-uniform x arrays." +# # WHEN +# x_1 = np.linspace(-2, 0, 1000) +# x_2 = np.linspace(0.001, 2, 2000) +# x_non_uniform = np.concatenate([x_1, x_2]) + +# # THEN +# calculated_convolution = convolution( +# energy=x_non_uniform, +# sample_model=sample_model, +# resolution_model=resolution_model, +# method="numerical", +# upsample_factor=5, +# ) + +# # EXPECT +# expected_convolution = convolution( +# energy=x_non_uniform, +# sample_model=sample_model, +# resolution_model=resolution_model, +# method="analytical", +# ) + +# np.testing.assert_allclose( +# calculated_convolution, +# expected_convolution, +# atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, +# rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, +# ) + +# # Test error handling +# def test_analytical_convolution_fails_with_detailed_balance( +# self, energy, sample_model, resolution_model +# ): +# # WHEN +# temperature = 300.0 +# # THEN EXPECT +# with pytest.raises( +# ValueError, +# match="Analytical convolution is not supported with detailed balance.", +# ): +# convolution( +# energy=energy, +# sample_model=sample_model, +# resolution_model=resolution_model, +# method="analytical", +# temperature=temperature, +# ) + +# def test_convolution_only_accepts_auto_analytical_and_numerical_methods( +# self, energy, sample_model, resolution_model +# ): +# # WHEN THEN EXPECT +# with pytest.raises( +# ValueError, +# match="Unknown convolution method: unknown_method. Choose from 'auto', 'analytical', or 'numerical'.", +# ): +# convolution( +# energy=energy, +# sample_model=sample_model, +# resolution_model=resolution_model, +# method="unknown_method", +# ) + +# def test_energy_must_be_1d_finite_array(self, sample_model, resolution_model): +# # WHEN THEN EXPECT +# with pytest.raises(ValueError, match="`energy` must be a 1D finite array."): +# convolution( +# energy=np.array([[1, 2], [3, 4]]), +# sample_model=sample_model, +# resolution_model=resolution_model, +# ) + +# with pytest.raises(ValueError, match="`energy` must be a 1D finite array."): +# convolution( +# energy=np.array([1, 2, np.nan]), +# sample_model=sample_model, +# resolution_model=resolution_model, +# ) + +# with pytest.raises(ValueError, match="`energy` must be a 1D finite array."): +# convolution( +# energy=np.array([1, 2, np.inf]), +# sample_model=sample_model, +# resolution_model=resolution_model, +# ) + +# def test_numerical_convolve_requires_uniform_grid_if_no_upsample( +# self, sample_model, resolution_model +# ): +# # WHEN +# x = np.array([0, 1, 2, 4, 5]) # Non-uniform grid + +# # THEN EXPECT +# with pytest.raises( +# ValueError, +# match="Input array `energy` must be uniformly spaced if upsample_factor = 0.", +# ): +# convolution( +# energy=x, +# sample_model=sample_model, +# resolution_model=resolution_model, +# method="numerical", +# upsample_factor=0, +# ) + +# def test_sample_model_must_have_components(self, resolution_model): +# # WHEN +# sample_model = SampleModel(name="SampleModel") + +# # THEN EXPECT +# with pytest.raises( +# ValueError, match="SampleModel must have at least one component." +# ): +# convolution( +# energy=np.array([0, 1, 2]), +# sample_model=sample_model, +# resolution_model=resolution_model, +# ) + +# def test_resolution_model_must_have_components(self, sample_model): +# # WHEN +# resolution_model = SampleModel(name="ResolutionModel") + +# # THEN EXPECT +# with pytest.raises( +# ValueError, match="ResolutionModel must have at least one component." +# ): +# convolution( +# energy=np.array([0, 1, 2]), +# sample_model=sample_model, +# resolution_model=resolution_model, +# ) + +# def test_numerical_convolution_wide_sample_peak_gives_warning( +# self, resolution_model +# ): +# # WHEN +# x = np.linspace(-2, 2, 20001) + +# sample_gauss = Gaussian(center=0.1, width=1.9, area=2, name="SampleGauss") +# sample = SampleModel(name="SampleModel") +# sample.add_component(sample_gauss) + +# # #THEN EXPECT +# with pytest.warns( +# UserWarning, +# match=r"The width of the sample model component ", +# ): +# convolution( +# energy=x, +# sample_model=sample, +# resolution_model=resolution_model, +# method="numerical", +# upsample_factor=0, +# ) + +# def test_numerical_convolution_wide_resolution_peak_gives_warning( +# self, sample_model +# ): +# # WHEN +# x = np.linspace(-2, 2, 20001) + +# resolution_gauss = Gaussian( +# center=0.3, width=1.9, area=4, name="ResolutionGauss" +# ) + +# resolution = SampleModel(name="ResolutionModel") +# resolution.add_component(resolution_gauss) + +# # #THEN EXPECT +# with pytest.warns( +# UserWarning, +# match=r"The width of the resolution model component 'ResolutionGauss' \(1.9\) is large", +# ): +# convolution( +# energy=x, +# sample_model=sample_model, +# resolution_model=resolution, +# method="numerical", +# upsample_factor=0, +# ) + +# def test_numerical_convolution_narrow_sample_peak_gives_warning( +# self, resolution_model +# ): +# # WHEN +# x = np.linspace(-2, 2, 201) + +# sample_gauss1 = Gaussian(center=0.1, width=1e-3, area=2, name="SampleGauss") + +# sample = SampleModel(name="SampleModel") +# sample.add_component(sample_gauss1) + +# # #THEN EXPECT +# with pytest.warns( +# UserWarning, +# match=r"The width of the sample model component 'SampleGauss' \(0.001\) is small", +# ): +# convolution( +# energy=x, +# sample_model=sample, +# resolution_model=resolution_model, +# method="numerical", +# upsample_factor=0, +# ) + +# def test_numerical_convolution_narrow_resolution_peak_gives_warning( +# self, sample_model +# ): +# # WHEN +# x = np.linspace(-2, 2, 201) + +# resolution_gauss = Gaussian( +# center=0.3, width=1e-3, area=4, name="ResolutionGauss" +# ) + +# resolution = SampleModel(name="ResolutionModel") +# resolution.add_component(resolution_gauss) + +# # #THEN EXPECT +# with pytest.warns( +# UserWarning, +# match=r"The width of the resolution model component 'ResolutionGauss' \(0.001\) is small", +# ): +# convolution( +# energy=x, +# sample_model=sample_model, +# resolution_model=resolution, +# method="numerical", +# upsample_factor=0, +# ) diff --git a/tests/unit_tests/convolution/test_numerical_convolution.py b/tests/unit_tests/convolution/test_numerical_convolution.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit_tests/convolution/test_numerical_convolution_base.py b/tests/unit_tests/convolution/test_numerical_convolution_base.py new file mode 100644 index 0000000..e69de29 From 8646baaf3298e891145f76dedd73cdb5086d8f5b Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 19 Nov 2025 15:27:41 +0100 Subject: [PATCH 42/71] test convolution_base --- .../convolution/convolution_base.py | 15 +- .../convolution/test_convolution_base.py | 227 ++++++++++++++++++ 2 files changed, 236 insertions(+), 6 deletions(-) diff --git a/src/easydynamics/convolution/convolution_base.py b/src/easydynamics/convolution/convolution_base.py index 614c1bd..4639134 100644 --- a/src/easydynamics/convolution/convolution_base.py +++ b/src/easydynamics/convolution/convolution_base.py @@ -33,15 +33,18 @@ def __init__( energy: Union[np.ndarray, sc.Variable], sample_model: Union[SampleModel, ModelComponent] = None, resolution_model: Union[SampleModel, ModelComponent] = None, - energy_unit: str = "meV", + energy_unit: Union[str, sc.Unit] = "meV", offset: Optional[Union[Numerical, Parameter]] = 0.0, ): if isinstance(energy, Numerical): - energy = np.array([energy]) + energy = np.array([float(energy)]) if not isinstance(energy, (np.ndarray, sc.Variable)): raise TypeError("Energy must be a numpy ndarray or a scipp Variable.") + if not isinstance(energy_unit, (str, sc.Unit)): + raise TypeError("Energy_unit must be a string or sc.Unit.") + if isinstance(energy, np.ndarray): energy = sc.array(dims=["energy"], values=energy, unit=energy_unit) @@ -52,12 +55,12 @@ def __init__( if not isinstance(sample_model, SampleModel): raise TypeError( - f"`sample_model` is an instance of {type(sample_model).__name__}, but must be SampleModel." + f"`sample_model` is an instance of {type(sample_model).__name__}, but must be a SampleModel or ModelComponent." ) if not isinstance(resolution_model, SampleModel): raise TypeError( - f"`resolution_model` is an instance of {type(resolution_model).__name__}, but must be SampleModel." + f"`resolution_model` is an instance of {type(resolution_model).__name__}, but must be a SampleModel or ModelComponent." ) if offset is None: @@ -89,7 +92,7 @@ def energy(self, energy: np.ndarray) -> None: """ if isinstance(energy, Numerical): - energy = np.array([energy]) + energy = np.array([float(energy)]) if not isinstance(energy, (np.ndarray, sc.Variable)): raise TypeError( @@ -193,7 +196,7 @@ def offset(self, offset: Union[Numerical, Parameter]) -> None: Raises: TypeError: If offset is not a Number or Parameter. """ - if not isinstance(offset, Parameter): + if not isinstance(offset, (Numerical, Parameter)): raise TypeError("Offset must be a Number or Parameter.") if isinstance(offset, Numerical): diff --git a/tests/unit_tests/convolution/test_convolution_base.py b/tests/unit_tests/convolution/test_convolution_base.py index e69de29..655dc58 100644 --- a/tests/unit_tests/convolution/test_convolution_base.py +++ b/tests/unit_tests/convolution/test_convolution_base.py @@ -0,0 +1,227 @@ +import numpy as np +import pytest +import scipp as sc +from easyscience.variable import Parameter + +from easydynamics.convolution.convolution_base import ( + ConvolutionBase, +) +from easydynamics.sample_model import SampleModel + + +class TestConvolutionBase: + @pytest.fixture + def convolution_base(self): + energy = np.linspace(-10, 10, 100) + sample_model = SampleModel(name="SampleModel") + resolution_model = SampleModel(name="ResolutionModel") + offset = 0.0 + + return ConvolutionBase( + energy=energy, + sample_model=sample_model, + resolution_model=resolution_model, + offset=offset, + ) + + def test_init(self, convolution_base): + # WHEN THEN EXPECT + assert isinstance(convolution_base, ConvolutionBase) + assert isinstance(convolution_base.energy, sc.Variable) + assert np.allclose(convolution_base.energy.values, np.linspace(-10, 10, 100)) + assert isinstance(convolution_base._sample_model, SampleModel) + assert isinstance(convolution_base._resolution_model, SampleModel) + assert isinstance(convolution_base.offset, Parameter) + assert convolution_base.offset.value == 0.0 + + @pytest.mark.parametrize( + "kwargs, expected_message", + [ + ( + { + "energy": "invalid", + "sample_model": SampleModel(), + "resolution_model": SampleModel(), + "energy_unit": "meV", + "offset": 0.0, + }, + "Energy must be", + ), + ( + { + "energy": np.linspace(-10, 10, 100), + "sample_model": "invalid", + "resolution_model": SampleModel(), + "energy_unit": "meV", + "offset": 0.0, + }, + "`sample_model` is an instance of str, but must be a SampleModel or ModelComponent.", + ), + ( + { + "energy": np.linspace(-10, 10, 100), + "sample_model": SampleModel(), + "resolution_model": "invalid", + "energy_unit": "meV", + "offset": 0.0, + }, + "`resolution_model` is an instance of str, but must be a SampleModel or ModelComponent.", + ), + ( + { + "energy": np.linspace(-10, 10, 100), + "sample_model": SampleModel(), + "resolution_model": SampleModel(), + "energy_unit": 123, + "offset": 0.0, + }, + "Energy_unit must be ", + ), + ( + { + "energy": np.linspace(-10, 10, 100), + "sample_model": SampleModel(), + "resolution_model": SampleModel(), + "energy_unit": "meV", + "offset": "invalid", + }, + "Offset must be a Number or Parameter.", + ), + ], + ) + def test_input_type_validation_raises(self, kwargs, expected_message): + # WHEN THEN EXPECT + with pytest.raises(TypeError, match=expected_message): + ConvolutionBase(**kwargs) + + @pytest.mark.parametrize( + "energy, expected_energy", + [ + ( + 1, + sc.array(dims=["energy"], values=[1.0], unit="meV"), + ), + ( + 1.0, + sc.array(dims=["energy"], values=[1.0], unit="meV"), + ), + ( + np.linspace(-5, 5, 50), + sc.array(dims=["energy"], values=np.linspace(-5, 5, 50), unit="meV"), + ), + ( + sc.array(dims=["energy"], values=np.linspace(-5, 5, 50), unit="meV"), + sc.array(dims=["energy"], values=np.linspace(-5, 5, 50), unit="meV"), + ), + ], + ids=["int", "float", "np.ndarray", "scipp.Variable"], + ) + def test_energy_setter(self, convolution_base, energy, expected_energy): + # WHEN + convolution_base.energy = energy + + # THEN + assert sc.identical(convolution_base.energy, expected_energy) + + def test_energy_setter_invalid_type_raises(self, convolution_base): + # WHEN THEN EXPECT + with pytest.raises( + TypeError, + match="Energy must be a Number, a numpy ndarray or a scipp Variable.", + ): + convolution_base.energy = "invalid" + + def test_energy_unit_property(self, convolution_base): + # WHEN THEN EXPECT + assert convolution_base.energy.unit == "meV" + + def test_energy_unit_setter_raises(self, convolution_base): + # WHEN THEN EXPECT + with pytest.raises( + AttributeError, + match="Use convert_unit to change the unit between allowed types ", + ): + convolution_base.energy_unit = "K" + + def test_convert_energy_unit(self, convolution_base): + # WHEN THEN + convolution_base.convert_energy_unit("eV") + + # EXPECT + assert convolution_base.energy.unit == "eV" + assert convolution_base.energy_unit == "eV" + assert np.allclose( + convolution_base.energy.values, np.linspace(-0.01, 0.01, 100) + ) + + def test_sample_model_property(self, convolution_base): + # WHEN THEN EXPECT + assert isinstance(convolution_base.sample_model, SampleModel) + + def test_sample_model_setter(self, convolution_base): + # WHEN + new_sample_model = SampleModel(name="NewSampleModel") + + # THEN + convolution_base.sample_model = new_sample_model + + # EXPECT + assert convolution_base.sample_model == new_sample_model + + def test_sample_model_setter_invalid_type_raises(self, convolution_base): + # WHEN THEN EXPECT + with pytest.raises( + TypeError, + match="`sample_model` is an instance of str, but must be a SampleModel or ModelComponent.", + ): + convolution_base.sample_model = "invalid" + + def test_resolution_model_property(self, convolution_base): + # WHEN THEN EXPECT + assert isinstance(convolution_base.resolution_model, SampleModel) + + def test_resolution_model_setter(self, convolution_base): + # WHEN + new_resolution_model = SampleModel(name="NewResolutionModel") + + # THEN + convolution_base.resolution_model = new_resolution_model + + # EXPECT + assert convolution_base.resolution_model == new_resolution_model + + def test_resolution_model_setter_invalid_type_raises(self, convolution_base): + # WHEN THEN EXPECT + with pytest.raises( + TypeError, + match="`resolution_model` is an instance of str, but must be a SampleModel or ModelComponent.", + ): + convolution_base.resolution_model = "invalid" + + def test_offset_property(self, convolution_base): + # WHEN THEN EXPECT + assert isinstance(convolution_base.offset, Parameter) + assert convolution_base.offset.value == 0.0 + + def test_offset_setter_parameter(self, convolution_base): + # WHEN + new_offset = Parameter(value=2.5, name="offset", unit="meV") + + # THEN + convolution_base.offset = new_offset + + # EXPECT + assert convolution_base.offset == new_offset + + def test_offset_setter_numerical(self, convolution_base): + "Make sure the offset unique name remains the same when setting the numerical value" + # WHEN + convolution_base.offset = 3.5 + old_offset_unique_name = convolution_base.offset.unique_name + + # THEN + convolution_base.offset = 3.5 + + # EXPECT + assert convolution_base.offset.value == 3.5 + assert convolution_base.offset.unique_name == old_offset_unique_name From bbfff6c1712ccca847f33e545625c4445c1a16be Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 19 Nov 2025 15:37:22 +0100 Subject: [PATCH 43/71] Add edge case tests --- .../convolution/convolution_base.py | 18 +++++----- .../convolution/test_convolution_base.py | 36 +++++++++++++++++++ 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/easydynamics/convolution/convolution_base.py b/src/easydynamics/convolution/convolution_base.py index 4639134..5e38746 100644 --- a/src/easydynamics/convolution/convolution_base.py +++ b/src/easydynamics/convolution/convolution_base.py @@ -24,7 +24,7 @@ class ConvolutionBase: The resolution model to convolve with. energy_unit : str or sc.Unit, optional The unit of the energy. Default is 'meV'. - offset_float : float, or None, optional + offset : float, or None, optional The offset to apply to the input array. """ @@ -34,7 +34,7 @@ def __init__( sample_model: Union[SampleModel, ModelComponent] = None, resolution_model: Union[SampleModel, ModelComponent] = None, energy_unit: Union[str, sc.Unit] = "meV", - offset: Optional[Union[Numerical, Parameter]] = 0.0, + offset: Optional[Union[Numerical, Parameter]] = None, ): if isinstance(energy, Numerical): energy = np.array([float(energy)]) @@ -50,18 +50,20 @@ def __init__( self._energy = energy self._energy_unit = energy_unit - self._sample_model = sample_model - self._resolution_model = resolution_model - if not isinstance(sample_model, SampleModel): + if sample_model is not None and not isinstance(sample_model, SampleModel): raise TypeError( f"`sample_model` is an instance of {type(sample_model).__name__}, but must be a SampleModel or ModelComponent." ) + self._sample_model = sample_model - if not isinstance(resolution_model, SampleModel): + if resolution_model is not None and not isinstance( + resolution_model, SampleModel + ): raise TypeError( f"`resolution_model` is an instance of {type(resolution_model).__name__}, but must be a SampleModel or ModelComponent." ) + self._resolution_model = resolution_model if offset is None: offset = 0.0 @@ -129,10 +131,10 @@ def convert_energy_unit(self, energy_unit: Union[str, sc.Unit]) -> None: The unit of the energy. Raises: - TypeError: If energy_unit is not a string or sc.Unit. + TypeError: If energy_unit is not a string or scipp unit. """ if not isinstance(energy_unit, (str, sc.Unit)): - raise TypeError("Energy unit must be a string or sc.Unit.") + raise TypeError("Energy unit must be a string or scipp unit.") self.energy = sc.to_unit(self.energy, energy_unit) self._energy_unit = energy_unit diff --git a/tests/unit_tests/convolution/test_convolution_base.py b/tests/unit_tests/convolution/test_convolution_base.py index 655dc58..814affe 100644 --- a/tests/unit_tests/convolution/test_convolution_base.py +++ b/tests/unit_tests/convolution/test_convolution_base.py @@ -33,6 +33,26 @@ def test_init(self, convolution_base): assert isinstance(convolution_base._resolution_model, SampleModel) assert isinstance(convolution_base.offset, Parameter) assert convolution_base.offset.value == 0.0 + assert convolution_base.offset.unit == "meV" + + def test_init_energy_numerical_none_offset(self): + # WHEN + energy = 1 + + convolution_base = ConvolutionBase( + energy=energy, + offset=None, + ) + + # THEN EXPECT + assert isinstance(convolution_base, ConvolutionBase) + assert isinstance(convolution_base.energy, sc.Variable) + assert convolution_base.energy.values == np.array([1.0]) + assert convolution_base.energy.unit == "meV" + assert convolution_base._sample_model is None + assert convolution_base._resolution_model is None + assert convolution_base.offset.value == 0.0 + assert convolution_base.offset.unit == "meV" @pytest.mark.parametrize( "kwargs, expected_message", @@ -154,6 +174,14 @@ def test_convert_energy_unit(self, convolution_base): convolution_base.energy.values, np.linspace(-0.01, 0.01, 100) ) + def test_convert_energy_unit_invalid_type_raises(self, convolution_base): + # WHEN THEN EXPECT + with pytest.raises( + TypeError, + match="Energy unit must be a string or scipp unit.", + ): + convolution_base.convert_energy_unit(123) + def test_sample_model_property(self, convolution_base): # WHEN THEN EXPECT assert isinstance(convolution_base.sample_model, SampleModel) @@ -225,3 +253,11 @@ def test_offset_setter_numerical(self, convolution_base): # EXPECT assert convolution_base.offset.value == 3.5 assert convolution_base.offset.unique_name == old_offset_unique_name + + def test_offset_setter_invalid_type_raises(self, convolution_base): + # WHEN THEN EXPECT + with pytest.raises( + TypeError, + match="Offset must be a Number or Parameter.", + ): + convolution_base.offset = "invalid" From 134b35f5da8512757b9b94629f0dd85e40b239a9 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 19 Nov 2025 15:57:10 +0100 Subject: [PATCH 44/71] Update performance test --- .../convolution/numerical_convolution_base.py | 2 + .../convolution_width_thresholds.ipynb | 62 +++++++++++-------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index c93e49c..f74025a 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -248,6 +248,8 @@ def _create_dense_grid( "Input array `energy` must be uniformly spaced if upsample_factor = 0." ) energy_dense = self.energy.values + + span = self.energy.values.max() - self.energy.values.min() else: # Create an extended and upsampled energy grid energy_min, energy_max = self.energy.values.min(), self.energy.values.max() diff --git a/tests/performance_tests/convolution/convolution_width_thresholds.ipynb b/tests/performance_tests/convolution/convolution_width_thresholds.ipynb index 925b2ab..8682154 100644 --- a/tests/performance_tests/convolution/convolution_width_thresholds.ipynb +++ b/tests/performance_tests/convolution/convolution_width_thresholds.ipynb @@ -8,11 +8,10 @@ "outputs": [], "source": [ "import numpy as np\n", - "from easyscience.variable import Parameter\n", - "from scipy.special import voigt_profile\n", "\n", - "from easydynamics.sample_model import DeltaFunction, Gaussian, Lorentzian, SampleModel, DampedHarmonicOscillator\n", - "from easydynamics.utils import convolution \n", + "from easydynamics.sample_model import Gaussian, SampleModel\n", + "from easydynamics.convolution.analytical_convolution import AnalyticalConvolution \n", + "from easydynamics.convolution.numerical_convolution import NumericalConvolution \n", "\n", "import matplotlib.pyplot as plt" ] @@ -35,19 +34,24 @@ "resolution_model.add_component(resolution_gaussian)\n", "x=np.linspace(-50, 50, 101)\n", "\n", + "analytical_convolver = AnalyticalConvolution(\n", + " sample_model=sample_model,\n", + " resolution_model=resolution_model,\n", + " energy=x,\n", + ")\n", + "\n", + "numerical_convolver = NumericalConvolution(\n", + " sample_model=sample_model,\n", + " resolution_model=resolution_model,\n", + " energy=x,\n", + " upsample_factor=0\n", + ")\n", + "\n", "for gwidth in gaussian_widths:\n", " sample_model['Gaussian'].width=gwidth\n", - " y_analytical = convolution(sample_model=sample_model,\n", - " resolution_model=resolution_model,\n", - " x=x,\n", - " )\n", - "\n", - " y_numerical = convolution(sample_model=sample_model,\n", - " resolution_model=resolution_model,\n", - " x=x,\n", - " method='numerical',\n", - " upsample_factor=0\n", - " )\n", + " y_analytical = analytical_convolver.convolution()\n", + "\n", + " y_numerical = numerical_convolver.convolution()\n", "\n", " plt.plot(x, y_analytical, label='Analytical, width = {}'.format(gwidth), color = plt.cm.viridis(gaussian_widths.index(gwidth)/len(gaussian_widths)))\n", " plt.plot(x, y_numerical, label='Numerical, width = {}'.format(gwidth), color = plt.cm.viridis(gaussian_widths.index(gwidth)/len(gaussian_widths)), linestyle='--')\n", @@ -77,20 +81,26 @@ "resolution_model.add_component(resolution_gaussian)\n", "x=np.linspace(-100, 100, 201)\n", "\n", + "analytical_convolver = AnalyticalConvolution(\n", + " sample_model=sample_model,\n", + " resolution_model=resolution_model,\n", + " energy=x,\n", + ")\n", + "\n", + "numerical_convolver = NumericalConvolution(\n", + " sample_model=sample_model,\n", + " resolution_model=resolution_model,\n", + " energy=x,\n", + " upsample_factor=0\n", + ")\n", + "\n", "for gwidth, gcenter in zip(gaussian_widths, gaussian_centers):\n", " sample_model['Gaussian'].width=gwidth\n", " sample_model['Gaussian'].center=gcenter\n", - " y_analytical = convolution(sample_model=sample_model,\n", - " resolution_model=resolution_model,\n", - " x=x,\n", - " )\n", - "\n", - " y_numerical = convolution(sample_model=sample_model,\n", - " resolution_model=resolution_model,\n", - " x=x,\n", - " method='numerical',\n", - " upsample_factor=0\n", - " )\n", + " y_analytical = analytical_convolver.convolution()\n", + "\n", + " y_numerical = numerical_convolver.convolution()\n", + "\n", "\n", " plt.plot(x, y_analytical, label='Analytical, width = {}'.format(gwidth), color = plt.cm.viridis(gaussian_widths.index(gwidth)/len(gaussian_widths)))\n", " plt.plot(x, y_numerical, label='Numerical, width = {}'.format(gwidth), color = plt.cm.viridis(gaussian_widths.index(gwidth)/len(gaussian_widths)), linestyle='--')\n", From 1eea4c718fcb9675a9f59a26c1fafde802be316f Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 19 Nov 2025 16:04:52 +0100 Subject: [PATCH 45/71] Small updates --- src/easydynamics/convolution/numerical_convolution.py | 2 +- .../convolution/numerical_convolution_base.py | 9 +++++++-- .../convolution/convolution_width_thresholds.ipynb | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/easydynamics/convolution/numerical_convolution.py b/src/easydynamics/convolution/numerical_convolution.py index 12a33be..c590f6c 100644 --- a/src/easydynamics/convolution/numerical_convolution.py +++ b/src/easydynamics/convolution/numerical_convolution.py @@ -121,7 +121,7 @@ def convolution( convolved = fftconvolve(sample_vals, resolution_vals, mode="same") convolved *= self._energy_grid.energy_step # normalize - if self.upsample_factor > 0: + if self.upsample_factor is not None: # interpolate back to original energy grid convolved = np.interp( self.energy.values, diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index f74025a..fb11579 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -104,8 +104,13 @@ def upsample_factor(self) -> Numerical: def upsample_factor(self, factor: Numerical) -> None: """ Set the upsample factor and recreate the dense grid.""" + if factor is None: + self._upsample_factor = factor + self._energy_grid = self._create_dense_grid() + return + if not isinstance(factor, Numerical): - raise TypeError("Upsample factor must be a numerical value.") + raise TypeError("Upsample factor must be a numerical value or None.") factor = float(factor) if factor < 1.0: raise ValueError("Upsample factor must be greater than 1.") @@ -239,7 +244,7 @@ def _create_dense_grid( DenseGrid The dense grid created by upsampling and extending x. """ - if self.upsample_factor == 0: + if self.upsample_factor is None: # Check if the array is uniformly spaced. energy_diff = np.diff(self.energy.values) is_uniform = np.allclose(energy_diff, energy_diff[0]) diff --git a/tests/performance_tests/convolution/convolution_width_thresholds.ipynb b/tests/performance_tests/convolution/convolution_width_thresholds.ipynb index 8682154..a158762 100644 --- a/tests/performance_tests/convolution/convolution_width_thresholds.ipynb +++ b/tests/performance_tests/convolution/convolution_width_thresholds.ipynb @@ -44,7 +44,7 @@ " sample_model=sample_model,\n", " resolution_model=resolution_model,\n", " energy=x,\n", - " upsample_factor=0\n", + " upsample_factor=None\n", ")\n", "\n", "for gwidth in gaussian_widths:\n", @@ -91,7 +91,7 @@ " sample_model=sample_model,\n", " resolution_model=resolution_model,\n", " energy=x,\n", - " upsample_factor=0\n", + " upsample_factor=None\n", ")\n", "\n", "for gwidth, gcenter in zip(gaussian_widths, gaussian_centers):\n", From c935efca5fe36bf6888242edba1828d90cf91a10 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 19 Nov 2025 20:25:45 +0100 Subject: [PATCH 46/71] Begin test of numerical convolution base --- .../convolution/numerical_convolution_base.py | 12 ++--- .../test_numerical_convolution_base.py | 46 +++++++++++++++++++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index fb11579..6f91d68 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -84,13 +84,13 @@ def __init__( self._extension_factor = extension_factor # Create a dense grid to improve accuracy. When upsample_factor>1, we evaluate on this grid and interpolate back to the original values at the end - self._energy_grid = self._create_dense_grid() + self._energy_grid = self._create_energy_grid() @ConvolutionBase.energy.setter def energy(self, energy: np.ndarray) -> None: super().energy = energy # Recreate dense grid when energy is updated - self._energy_grid = self._create_dense_grid() + self._energy_grid = self._create_energy_grid() @property def upsample_factor(self) -> Numerical: @@ -106,7 +106,7 @@ def upsample_factor(self, factor: Numerical) -> None: Set the upsample factor and recreate the dense grid.""" if factor is None: self._upsample_factor = factor - self._energy_grid = self._create_dense_grid() + self._energy_grid = self._create_energy_grid() return if not isinstance(factor, Numerical): @@ -118,7 +118,7 @@ def upsample_factor(self, factor: Numerical) -> None: self._upsample_factor = factor # Recreate dense grid when upsample factor is updated - self._energy_grid = self._create_dense_grid() + self._energy_grid = self._create_energy_grid() @property def extension_factor(self) -> float: @@ -151,7 +151,7 @@ def extension_factor(self, factor: Numerical) -> None: self._extension_factor = factor # Recreate dense grid when extension factor is updated - self._energy_grid = self._create_dense_grid() + self._energy_grid = self._create_energy_grid() @property def temperature(self) -> Optional[Parameter]: @@ -234,7 +234,7 @@ class EnergyGrid: energy_dense_centered: np.ndarray energy_step: float - def _create_dense_grid( + def _create_energy_grid( self, ) -> EnergyGrid: """ diff --git a/tests/unit_tests/convolution/test_numerical_convolution_base.py b/tests/unit_tests/convolution/test_numerical_convolution_base.py index e69de29..fdafad6 100644 --- a/tests/unit_tests/convolution/test_numerical_convolution_base.py +++ b/tests/unit_tests/convolution/test_numerical_convolution_base.py @@ -0,0 +1,46 @@ +import numpy as np +import pytest +import scipp as sc +from easyscience.variable import Parameter + +from easydynamics.convolution.numerical_convolution_base import ( + NumericalConvolutionBase, +) +from easydynamics.sample_model import SampleModel + + +class TestNumericalConvolutionBase: + @pytest.fixture + def default_numerical_convolution_base(self): + energy = np.linspace(-10, 10, 100) + sample_model = SampleModel(name="SampleModel") + resolution_model = SampleModel(name="ResolutionModel") + + return NumericalConvolutionBase( + energy=energy, + sample_model=sample_model, + resolution_model=resolution_model, + ) + + def test_init(self, default_numerical_convolution_base): + # WHEN THEN EXPECT + assert isinstance(default_numerical_convolution_base, NumericalConvolutionBase) + assert isinstance(default_numerical_convolution_base.energy, sc.Variable) + assert np.allclose( + default_numerical_convolution_base.energy.values, np.linspace(-10, 10, 100) + ) + assert isinstance(default_numerical_convolution_base._sample_model, SampleModel) + assert isinstance( + default_numerical_convolution_base._resolution_model, SampleModel + ) + assert isinstance(default_numerical_convolution_base.offset, Parameter) + assert default_numerical_convolution_base.offset.value == 0.0 + assert default_numerical_convolution_base.offset.unit == "meV" + assert default_numerical_convolution_base.upsample_factor == 5 + assert default_numerical_convolution_base.extension_factor == 0.2 + assert default_numerical_convolution_base.temperature is None + assert default_numerical_convolution_base.temperature_unit == "K" + assert default_numerical_convolution_base.energy_unit == "meV" + assert default_numerical_convolution_base.normalize_detailed_balance is True + + # todo also check _energy_grid From 8e7c64c93f34f74ac1e3d5d605dee6e0c9cef2bd Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Thu, 20 Nov 2025 12:04:30 +0100 Subject: [PATCH 47/71] Update analytical convolution and some tests --- examples/convolution.ipynb | 4 +- .../convolution/analytical_convolution.py | 142 +++----- .../test_analytical_convolution.py | 339 ++++++++++++++++++ .../test_numerical_convolution_base.py | 2 +- 4 files changed, 391 insertions(+), 96 deletions(-) diff --git a/examples/convolution.ipynb b/examples/convolution.ipynb index f9ded02..8a2c8bc 100644 --- a/examples/convolution.ipynb +++ b/examples/convolution.ipynb @@ -68,7 +68,7 @@ "\n", "# Use some of the extra settings for the numerical convolution\n", "sample_model=SampleModel(name='sample_model')\n", - "gaussian=Gaussian(name='Gaussian',width=0.5,area=1)\n", + "gaussian=Gaussian(name='Gaussian',width=0.3,area=1)\n", "dho = DampedHarmonicOscillator(name='DHO',center=1.0,width=0.3,area=2.0)\n", "lorentzian = Lorentzian(name='Lorentzian',center=-1.0,width=0.2,area=1.0)\n", "delta = DeltaFunction(name='Delta',center=0.4,area=0.5)\n", @@ -85,7 +85,7 @@ "energy=np.linspace(-2, 2, 100)\n", "\n", "\n", - "temperature = 15.0 # Temperature in Kelvin\n", + "temperature = 10.0 # Temperature in Kelvin\n", "offset = 0.5\n", "upsample_factor = 15\n", "extension_factor = 0.8\n", diff --git a/src/easydynamics/convolution/analytical_convolution.py b/src/easydynamics/convolution/analytical_convolution.py index b9bd63a..48fb668 100644 --- a/src/easydynamics/convolution/analytical_convolution.py +++ b/src/easydynamics/convolution/analytical_convolution.py @@ -32,6 +32,17 @@ class AnalyticalConvolution(ConvolutionBase): The offset in energy to apply to the convolution. """ + # Mapping of supported component type pairs to convolution methods. + # Delta functions are handled separately. + _CONVOLUTIONS = { + ("Gaussian", "Gaussian"): "_convolute_gauss_gauss", + ("Gaussian", "Lorentzian"): "_convolute_gauss_lorentz", + ("Gaussian", "Voigt"): "_convolute_gauss_voigt", + ("Lorentzian", "Lorentzian"): "_convolute_lorentz_lorentz", + ("Lorentzian", "Voigt"): "_convolute_lorentz_voigt", + ("Voigt", "Voigt"): "_convolute_voigt_voigt", + } + def __init__( self, energy: Union[np.ndarray, sc.Variable], @@ -124,7 +135,7 @@ def _calculate_analytic_pair( if isinstance(resolution_component, DeltaFunction): raise ValueError( - "Analytical convolution with delta function in resolution model is not supported." + "Analytical convolution with a delta function in the resolution model is not supported." ) # Delta function + anything --> anything, shifted by delta center with area A1 * A2 @@ -134,88 +145,30 @@ def _calculate_analytic_pair( resolution_component, ) - # Gaussian + Gaussian --> Gaussian with width sqrt(w1^2 + w2^2) and area A1 * A2 - if isinstance(sample_component, Gaussian) and isinstance( - resolution_component, Gaussian - ): - return self._convolute_gauss_gauss( - sample_component, - resolution_component, - ) - - # Gaussian + Lorentzian --> Voigt with area A1 * A2 - if ( - isinstance(sample_component, Gaussian) - and isinstance(resolution_component, Lorentzian) - ) or ( - isinstance(sample_component, Lorentzian) - and isinstance(resolution_component, Gaussian) - ): - if isinstance(sample_component, Gaussian): - gaussian, lorentzian = sample_component, resolution_component - else: - gaussian, lorentzian = resolution_component, sample_component - - return self._convolute_gauss_lorentz( - gaussian, - lorentzian, - ) + pair = (type(sample_component).__name__, type(resolution_component).__name__) + swapped = False - # Gaussian + Voigt --> Voigt with area A1 * A2, Lorentzian width unchanged, Gaussian widths summed in quadrature - if ( - isinstance(sample_component, Gaussian) - and isinstance(resolution_component, Voigt) - ) or ( - isinstance(sample_component, Voigt) - and isinstance(resolution_component, Gaussian) - ): - if isinstance(sample_component, Gaussian): - gaussian, voigt = sample_component, resolution_component - else: - gaussian, voigt = resolution_component, sample_component - return self._convolute_gauss_voigt( - gaussian, - voigt, + if pair not in self._CONVOLUTIONS: + # Try reversing the pair + pair = ( + type(resolution_component).__name__, + type(sample_component).__name__, ) + swapped = True - # Lorentzian + Lorentzian --> Lorentzian with width w1 + w2 and area A1 * A2 - if isinstance(sample_component, Lorentzian) and isinstance( - resolution_component, Lorentzian - ): - return self._convolute_lorentz_lorentz( - sample_component, - resolution_component, - ) + func_name = self._CONVOLUTIONS.get(pair) - # Lorentzian + Voigt --> Voigt with area A1 * A2, Gaussian width unchanged, Lorentzian widths summed - if ( - isinstance(sample_component, Lorentzian) - and isinstance(resolution_component, Voigt) - ) or ( - isinstance(sample_component, Voigt) - and isinstance(resolution_component, Lorentzian) - ): - if isinstance(sample_component, Lorentzian): - lorentzian, voigt = sample_component, resolution_component - else: - lorentzian, voigt = resolution_component, sample_component - - return self._convolute_lorentz_voigt( - lorentzian, - voigt, + if func_name is None: + raise ValueError( + f"Analytical convolution not supported for component pair: " + f"{type(sample_component).__name__}, {type(resolution_component).__name__}" ) - # Voigt + Voigt --> Voigt with area A1 * A2, Gaussian widths summed in quadrature, Lorentzian widths summed - if isinstance(sample_component, Voigt) and isinstance( - resolution_component, Voigt - ): - return self.convolute_voigt_voigt( - sample_component, - resolution_component, - ) - return ValueError( - f"Analytical convolution not implemented for component pair: {type(sample_component).__name__}, {type(resolution_component).__name__}" - ) + # Call the corresponding method + if swapped: + return getattr(self, func_name)(resolution_component, sample_component) + else: + return getattr(self, func_name)(sample_component, resolution_component) def _convolute_delta_any( self, @@ -299,7 +252,7 @@ def _convolute_gauss_lorentz( return self._voigt_eval( area=area, center=center, - gauss_width=sample_component.width.value, + gaussian_width=sample_component.width.value, lorentzian_width=resolution_component.width.value, ) @@ -329,16 +282,17 @@ def _convolute_gauss_voigt( sample_component.center.value + resolution_component.center.value ) + self.offset.value - gauss_width = np.sqrt( - sample_component.width.value**2 + resolution_component.width.value**2 + gaussian_width = np.sqrt( + sample_component.width.value**2 + + resolution_component.gaussian_width.value**2 ) - lorentzian_width = resolution_component.width.value + lorentzian_width = resolution_component.lorentzian_width.value return self._voigt_eval( area=area, center=center, - gauss_width=gauss_width, + gaussian_width=gaussian_width, lorentzian_width=lorentzian_width, ) @@ -394,20 +348,20 @@ def _convolute_lorentz_voigt( sample_component.center.value + resolution_component.center.value ) + self.offset.value - gauss_width = resolution_component.g_width.value + gaussian_width = resolution_component.gaussian_width.value lorentzian_width = ( - sample_component.width.value + resolution_component.l_width.value + sample_component.width.value + resolution_component.lorentzian_width.value ) return self._voigt_eval( area=area, center=center, - gauss_width=gauss_width, + gaussian_width=gaussian_width, lorentzian_width=lorentzian_width, ) - def convolute_voigt_voigt( + def _convolute_voigt_voigt( self, sample_component: Voigt, resolution_component: Voigt, @@ -431,17 +385,19 @@ def convolute_voigt_voigt( sample_component.center.value + resolution_component.center.value ) + self.offset.value - gauss_width = np.sqrt( - sample_component.g_width.value**2 + resolution_component.g_width.value**2 + gaussian_width = np.sqrt( + sample_component.gaussian_width.value**2 + + resolution_component.gaussian_width.value**2 ) lorentzian_width = ( - sample_component.l_width.value + resolution_component.l_width.value + sample_component.lorentzian_width.value + + resolution_component.lorentzian_width.value ) return self._voigt_eval( area=area, center=center, - gauss_width=gauss_width, + gaussian_width=gaussian_width, lorentzian_width=lorentzian_width, ) @@ -498,7 +454,7 @@ def _voigt_eval( self, area: float, center: float, - gauss_width: float, + gaussian_width: float, lorentzian_width: float, ) -> np.ndarray: """ @@ -508,7 +464,7 @@ def _voigt_eval( The area under the Voigt profile. center : float The center of the Voigt profile. - gauss_width : float + gaussian_width : float The Gaussian width (sigma) of the Voigt profile. lorentzian_width : float The Lorentzian width (HWHM) of the Voigt profile. @@ -518,5 +474,5 @@ def _voigt_eval( """ return area * voigt_profile( - self.energy.values - center, gauss_width, lorentzian_width + self.energy.values - center, gaussian_width, lorentzian_width ) diff --git a/tests/unit_tests/convolution/test_analytical_convolution.py b/tests/unit_tests/convolution/test_analytical_convolution.py index e69de29..9c2f52d 100644 --- a/tests/unit_tests/convolution/test_analytical_convolution.py +++ b/tests/unit_tests/convolution/test_analytical_convolution.py @@ -0,0 +1,339 @@ +import numpy as np +import pytest +from scipy.signal import fftconvolve + +# from easyscience.variable import Parameter +from easydynamics.convolution.analytical_convolution import ( + AnalyticalConvolution, +) +from easydynamics.sample_model import ( + DampedHarmonicOscillator, + DeltaFunction, + Gaussian, + Lorentzian, + SampleModel, + Voigt, +) + +NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE = 1e-5 +NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE = 1e-6 + + +@pytest.fixture +def function1(request): + # request.param will be e.g. "gaussian1" + return request.getfixturevalue(request.param) + + +@pytest.fixture +def function2(request): + return request.getfixturevalue(request.param) + + +class TestAnalyticalConvolution: + @pytest.fixture + def default_analytical_convolution(self): + energy = np.linspace(-100, 100, 2**15 + 1) + sample_model = SampleModel(name="SampleModel") + resolution_model = SampleModel(name="ResolutionModel") + + return AnalyticalConvolution( + energy=energy, + sample_model=sample_model, + resolution_model=resolution_model, + ) + + @pytest.fixture + def gaussian1(self): + return Gaussian(area=2.0, center=1.0, width=0.5) + + @pytest.fixture + def gaussian2(self): + return Gaussian(area=3.0, center=-1.0, width=0.4) + + @pytest.fixture + def lorentzian1(self): + return Lorentzian(area=2.0, center=1.0, width=0.55) + + @pytest.fixture + def lorentzian2(self): + return Lorentzian(area=3.0, center=-1.0, width=0.45) + + @pytest.fixture + def voigt1(self): + return Voigt(area=2.0, center=1.0, gaussian_width=0.33, lorentzian_width=0.28) + + @pytest.fixture + def voigt2(self): + return Voigt(area=3.0, center=-1.0, gaussian_width=0.36, lorentzian_width=0.42) + + @pytest.fixture + def dho1(self): + return DampedHarmonicOscillator(area=2.0, center=2.0, width=0.2) + + # def test_init(self, default_analytical_convolution): + # # WHEN THEN EXPECT + # assert isinstance(default_analytical_convolution, AnalyticalConvolution) + # assert isinstance(default_analytical_convolution.energy, sc.Variable) + # assert np.allclose( + # default_analytical_convolution.energy.values, np.linspace(-10, 10, 100) + # ) + # assert isinstance(default_analytical_convolution._sample_model, SampleModel) + # assert isinstance( + # default_analytical_convolution._resolution_model, SampleModel + # ) + + @pytest.mark.parametrize( + "function1, function2", + [ + ("gaussian1", "gaussian2"), + ("gaussian1", "lorentzian1"), + ("gaussian1", "voigt1"), + ("lorentzian1", "gaussian1"), + ("lorentzian1", "lorentzian2"), + ("lorentzian1", "voigt1"), + ("voigt1", "gaussian1"), + ("voigt1", "lorentzian1"), + ("voigt1", "voigt2"), + ], + indirect=["function1", "function2"], + ids=[ + "gauss-gauss", + "gauss-lorentz", + "gauss-voigt", + "lorentz-gauss", + "lorentz-lorentz", + "lorentz-voigt", + "voigt-gauss", + "voigt-lorentz", + "voigt-voigt", + ], + ) + def test_calculate_analytic_pair( + self, default_analytical_convolution, function1, function2 + ): + """Test that the analytical convolution methods are correct by comparing to numerical convolution.""" + # WHEN THEN + convoluted = default_analytical_convolution._calculate_analytic_pair( + function1, function2 + ) + + # EXPECT + expected = fftconvolve( + function1.evaluate(default_analytical_convolution.energy.values), + function2.evaluate(default_analytical_convolution.energy.values), + mode="same", + ) * ( + default_analytical_convolution.energy.values[1] + - default_analytical_convolution.energy.values[0] + ) + + # Numerical convolution can be inaccurate at the edges, so only compare the central part + N = len(convoluted) + start = N // 4 + end = 3 * N // 4 + + assert np.allclose( + convoluted[start:end], + expected[start:end], + rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, + atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, + ) + + @pytest.mark.parametrize( + "function1", + ["gaussian1", "lorentzian1", "voigt1", "dho1"], + indirect=True, + ids=["gaussian", "lorentzian", "voigt", "dho"], + ) + def test_calculate_analytic_pair_delta( + self, default_analytical_convolution, function1 + ): + """Test that convolution with delta function returns the other function.""" + # WHEN THEN + delta_function = DeltaFunction(area=2.0, center=0.5) + function1 = Gaussian(area=3.0, center=-1.0, width=1.0) + + convoluted = default_analytical_convolution._calculate_analytic_pair( + delta_function, function1 + ) + + # EXPECT + expected = 2.0 * function1.evaluate( + default_analytical_convolution.energy.values - 0.5 + ) + + assert np.allclose( + convoluted, + expected, + rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, + atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, + ) + + def test_calculate_analytic_pair_resolution_delta_raises( + self, default_analytical_convolution + ): + """Test that an error is raised if the resolution function is a delta function.""" + # WHEN + sample_function = Gaussian(area=2.0, center=0.0, width=1.0) + resolution_function = DeltaFunction(area=1.0, center=0.0) + + # THEN EXPECT + with pytest.raises( + ValueError, + match="not supported", + ): + default_analytical_convolution._calculate_analytic_pair( + sample_function, resolution_function + ) + + def test_calculate_analytic_pair_non_analytical_pair_raises( + self, default_analytical_convolution, gaussian1, dho1 + ): + """Test that an error is raised if the function pair is not supported for analytical convolution.""" + # WHEN + sample_function = dho1 + resolution_function = gaussian1 + + # THEN EXPECT + with pytest.raises( + ValueError, + match="not supported", + ): + default_analytical_convolution._calculate_analytic_pair( + sample_function, resolution_function + ) + + @pytest.mark.parametrize( + "method_name, function1, function2", + [ + ("_convolute_gauss_gauss", "gaussian1", "gaussian2"), + ("_convolute_gauss_lorentz", "gaussian1", "lorentzian1"), + ("_convolute_gauss_voigt", "gaussian1", "voigt1"), + ("_convolute_lorentz_lorentz", "lorentzian1", "lorentzian2"), + ("_convolute_lorentz_voigt", "lorentzian1", "voigt1"), + ("_convolute_voigt_voigt", "voigt1", "voigt2"), + ], + indirect=["function1", "function2"], + ids=[ + "gauss-gauss", + "gauss-lorentz", + "gauss-voigt", + "lorentz-lorentz", + "lorentz-voigt", + "voigt-voigt", + ], + ) + def test_convolute_function1_function2( + self, default_analytical_convolution, function1, function2, method_name + ): + # This test is perhaps superfluous since the methods get tested indirectly above. + """Test that the analytical convolution methods are correct by comparing to numerical convolution.""" + # WHEN THEN + convoluted = getattr(default_analytical_convolution, method_name)( + function1, function2 + ) + + # EXPECT + expected = fftconvolve( + function1.evaluate(default_analytical_convolution.energy.values), + function2.evaluate(default_analytical_convolution.energy.values), + mode="same", + ) * ( + default_analytical_convolution.energy.values[1] + - default_analytical_convolution.energy.values[0] + ) + + # Numerical convolution can be inaccurate at the edges, so only compare the central part + N = len(convoluted) + start = N // 4 + end = 3 * N // 4 + + assert np.allclose( + convoluted[start:end], + expected[start:end], + rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, + atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, + ) + + @pytest.mark.parametrize( + "function1", + ["gaussian1", "lorentzian1", "voigt1", "dho1"], + indirect=True, + ids=["gaussian", "lorentzian", "voigt", "dho"], + ) + def test_convolute_delta_any(self, default_analytical_convolution, function1): + """Test that convolution with delta function returns the other function.""" + # WHEN THEN + delta_function = DeltaFunction(area=2.0, center=0.5) + convoluted = default_analytical_convolution._convolute_delta_any( + delta_function, function1 + ) + + # EXPECT + expected = 2.0 * function1.evaluate( + default_analytical_convolution.energy.values - 0.5 + ) + + assert np.allclose( + convoluted, + expected, + rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, + atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, + ) + + def test_gaussian_eval(self, default_analytical_convolution): + # WHEN + area = 2.0 + center = 0.0 + width = 1.0 + + # THEN + gaussian_eval = default_analytical_convolution._gaussian_eval( + area, center, width + ) + + # EXPECT + expected = Gaussian(area=area, center=center, width=width).evaluate( + default_analytical_convolution.energy.values + ) + assert np.allclose(gaussian_eval, expected) + + def test_lorentzian_eval(self, default_analytical_convolution): + # WHEN + area = 2.0 + center = 0.0 + width = 1.0 + + # THEN + lorentzian_eval = default_analytical_convolution._lorentzian_eval( + area, center, width + ) + + # EXPECT + expected = Lorentzian(area=area, center=center, width=width).evaluate( + default_analytical_convolution.energy.values + ) + assert np.allclose(lorentzian_eval, expected) + + def test_voigt_eval(self, default_analytical_convolution): + # WHEN + area = 2.0 + center = 0.0 + gaussian_width = 1.0 + lorentzian_width = 1.0 + + # THEN + voigt_eval = default_analytical_convolution._voigt_eval( + area, center, gaussian_width, lorentzian_width + ) + + # EXPECT + expected = Voigt( + area=area, + center=center, + gaussian_width=gaussian_width, + lorentzian_width=lorentzian_width, + ).evaluate(default_analytical_convolution.energy.values) + + assert np.allclose(voigt_eval, expected) diff --git a/tests/unit_tests/convolution/test_numerical_convolution_base.py b/tests/unit_tests/convolution/test_numerical_convolution_base.py index fdafad6..0f481cb 100644 --- a/tests/unit_tests/convolution/test_numerical_convolution_base.py +++ b/tests/unit_tests/convolution/test_numerical_convolution_base.py @@ -39,7 +39,7 @@ def test_init(self, default_numerical_convolution_base): assert default_numerical_convolution_base.upsample_factor == 5 assert default_numerical_convolution_base.extension_factor == 0.2 assert default_numerical_convolution_base.temperature is None - assert default_numerical_convolution_base.temperature_unit == "K" + # assert default_numerical_convolution_base.temperature_unit == "K" assert default_numerical_convolution_base.energy_unit == "meV" assert default_numerical_convolution_base.normalize_detailed_balance is True From d85d73b4fd0d9a0ffdee163f67bc03b4bdc90f82 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Thu, 20 Nov 2025 14:26:23 +0100 Subject: [PATCH 48/71] Finish test of analytical convolution --- .../convolution/analytical_convolution.py | 30 +- .../test_analytical_convolution.py | 262 +++++++++++++----- 2 files changed, 215 insertions(+), 77 deletions(-) diff --git a/src/easydynamics/convolution/analytical_convolution.py b/src/easydynamics/convolution/analytical_convolution.py index 48fb668..f5e0c52 100644 --- a/src/easydynamics/convolution/analytical_convolution.py +++ b/src/easydynamics/convolution/analytical_convolution.py @@ -35,11 +35,11 @@ class AnalyticalConvolution(ConvolutionBase): # Mapping of supported component type pairs to convolution methods. # Delta functions are handled separately. _CONVOLUTIONS = { - ("Gaussian", "Gaussian"): "_convolute_gauss_gauss", - ("Gaussian", "Lorentzian"): "_convolute_gauss_lorentz", - ("Gaussian", "Voigt"): "_convolute_gauss_voigt", - ("Lorentzian", "Lorentzian"): "_convolute_lorentz_lorentz", - ("Lorentzian", "Voigt"): "_convolute_lorentz_voigt", + ("Gaussian", "Gaussian"): "_convolute_gaussian_gaussian", + ("Gaussian", "Lorentzian"): "_convolute_gaussian_lorentzian", + ("Gaussian", "Voigt"): "_convolute_gaussian_voigt", + ("Lorentzian", "Lorentzian"): "_convolute_lorentzian_lorentzian", + ("Lorentzian", "Voigt"): "_convolute_lorentzian_voigt", ("Voigt", "Voigt"): "_convolute_voigt_voigt", } @@ -94,7 +94,7 @@ def convolution( for sample_component in sample_components: # Go through resolution components, adding analytical contributions for resolution_component in resolution_components: - contrib = self._calculate_analytic_pair( + contrib = self._convolute_analytic_pair( sample_component=sample_component, resolution_component=resolution_component, ) @@ -102,9 +102,9 @@ def convolution( return total - def _calculate_analytic_pair( + def _convolute_analytic_pair( self, - sample_component: Union[ModelComponent, SampleModel], + sample_component: ModelComponent, resolution_component: ModelComponent, ) -> np.ndarray: """ @@ -121,9 +121,9 @@ def _calculate_analytic_pair( Args: - sample_component : Union[ModelComponent, SampleModel] + sample_component : ModelComponent The sample component to be convolved. - resolution_component : Union[ModelComponent, SampleModel] + resolution_component : ModelComponent The resolution component to convolve with. Returns: @@ -192,7 +192,7 @@ def _convolute_delta_any( self.energy.values - sample_component.center.value - self.offset.value ) - def _convolute_gauss_gauss( + def _convolute_gaussian_gaussian( self, sample_component: Gaussian, resolution_component: Gaussian, @@ -225,7 +225,7 @@ def _convolute_gauss_gauss( return self._gaussian_eval(area=area, center=center, width=width) - def _convolute_gauss_lorentz( + def _convolute_gaussian_lorentzian( self, sample_component: Gaussian, resolution_component: Lorentzian, @@ -256,7 +256,7 @@ def _convolute_gauss_lorentz( lorentzian_width=resolution_component.width.value, ) - def _convolute_gauss_voigt( + def _convolute_gaussian_voigt( self, sample_component: Gaussian, resolution_component: Voigt, @@ -296,7 +296,7 @@ def _convolute_gauss_voigt( lorentzian_width=lorentzian_width, ) - def _convolute_lorentz_lorentz( + def _convolute_lorentzian_lorentzian( self, sample_component: Lorentzian, resolution_component: Lorentzian, @@ -324,7 +324,7 @@ def _convolute_lorentz_lorentz( return self._lorentzian_eval(area=area, center=center, width=width) - def _convolute_lorentz_voigt( + def _convolute_lorentzian_voigt( self, sample_component: Lorentzian, resolution_component: Voigt, diff --git a/tests/unit_tests/convolution/test_analytical_convolution.py b/tests/unit_tests/convolution/test_analytical_convolution.py index 9c2f52d..b69d705 100644 --- a/tests/unit_tests/convolution/test_analytical_convolution.py +++ b/tests/unit_tests/convolution/test_analytical_convolution.py @@ -1,5 +1,8 @@ +from unittest.mock import patch + import numpy as np import pytest +import scipp as sc from scipy.signal import fftconvolve # from easyscience.variable import Parameter @@ -71,74 +74,209 @@ def voigt2(self): def dho1(self): return DampedHarmonicOscillator(area=2.0, center=2.0, width=0.2) - # def test_init(self, default_analytical_convolution): - # # WHEN THEN EXPECT - # assert isinstance(default_analytical_convolution, AnalyticalConvolution) - # assert isinstance(default_analytical_convolution.energy, sc.Variable) - # assert np.allclose( - # default_analytical_convolution.energy.values, np.linspace(-10, 10, 100) - # ) - # assert isinstance(default_analytical_convolution._sample_model, SampleModel) - # assert isinstance( - # default_analytical_convolution._resolution_model, SampleModel - # ) + def test_init(self, default_analytical_convolution): + # WHEN THEN EXPECT + assert isinstance(default_analytical_convolution, AnalyticalConvolution) + assert isinstance(default_analytical_convolution.energy, sc.Variable) + assert np.allclose( + default_analytical_convolution.energy.values, + np.linspace(-100, 100, 2**15 + 1), + ) + assert isinstance(default_analytical_convolution._sample_model, SampleModel) + assert isinstance(default_analytical_convolution._resolution_model, SampleModel) + + def test_convolution( + self, + default_analytical_convolution, + gaussian1, + gaussian2, + lorentzian1, + lorentzian2, + ): + """Test that the convolute method calls _convolute_analytic_pair for all component pairs.""" + + # WHEN + sample_model = SampleModel(name="SampleModel") + sample_model.add_component(gaussian1) + sample_model.add_component(lorentzian1) + + resolution_model = SampleModel(name="ResolutionModel") + resolution_model.add_component(gaussian2) + resolution_model.add_component(lorentzian2) + default_analytical_convolution.sample_model = sample_model + default_analytical_convolution.resolution_model = resolution_model + + # THEN + # Mock _convolute_analytic_pair to return 1.0 for any input pair + def mock_convolute_analytic_pair(sample_component, resolution_component): + return np.full_like( + default_analytical_convolution.energy.values, fill_value=1.0 + ) + + with patch.object( + default_analytical_convolution, + "_convolute_analytic_pair", + side_effect=mock_convolute_analytic_pair, + ) as mocked_pair: + result = default_analytical_convolution.convolution() + + # EXPECT + # 2 sample components x 2 resolution components + assert np.all(result == 4.0) + assert mocked_pair.call_count == 4 + + # Gather the actual calls to verify correct pairs + calls = [] + for c in mocked_pair.call_args_list: + kwargs = c.kwargs + + # Ensure no accidental extra arguments + assert set(kwargs.keys()) == { + "sample_component", + "resolution_component", + } + + calls.append( + (kwargs["sample_component"], kwargs["resolution_component"]) + ) + + expected_calls = [ + (gaussian1, gaussian2), + (gaussian1, lorentzian2), + (lorentzian1, gaussian2), + (lorentzian1, lorentzian2), + ] + assert calls == expected_calls + + def test_convolution_components( + self, + default_analytical_convolution, + gaussian1, + lorentzian1, + ): + """Test that the convolute method also works for components.""" + + # WHEN + default_analytical_convolution.sample_model = gaussian1 + default_analytical_convolution.resolution_model = lorentzian1 + + # THEN + # Mock _convolute_analytic_pair to return 1.0 for any input pair + def mock_convolute_analytic_pair(sample_component, resolution_component): + return np.full_like( + default_analytical_convolution.energy.values, fill_value=1.0 + ) + + with patch.object( + default_analytical_convolution, + "_convolute_analytic_pair", + side_effect=mock_convolute_analytic_pair, + ) as mocked_pair: + result = default_analytical_convolution.convolution() + + # EXPECT + # 1 sample component x 1 resolution component + assert np.all(result == 1.0) + assert mocked_pair.call_count == 1 + + # Gather the actual calls to verify correct pairs + calls = [] + for c in mocked_pair.call_args_list: + kwargs = c.kwargs + + # Ensure no accidental extra arguments + assert set(kwargs.keys()) == { + "sample_component", + "resolution_component", + } + + calls.append( + (kwargs["sample_component"], kwargs["resolution_component"]) + ) + + expected_calls = [ + (gaussian1, lorentzian1), + ] + assert calls == expected_calls @pytest.mark.parametrize( - "function1, function2", + "function1, function2, expected_method, swapped", [ - ("gaussian1", "gaussian2"), - ("gaussian1", "lorentzian1"), - ("gaussian1", "voigt1"), - ("lorentzian1", "gaussian1"), - ("lorentzian1", "lorentzian2"), - ("lorentzian1", "voigt1"), - ("voigt1", "gaussian1"), - ("voigt1", "lorentzian1"), - ("voigt1", "voigt2"), + # Normal cases + ( + "gaussian1", + "gaussian2", + "_convolute_gaussian_gaussian", + False, + ), + ( + "gaussian1", + "lorentzian1", + "_convolute_gaussian_lorentzian", + False, + ), + ( + "gaussian1", + "voigt1", + "_convolute_gaussian_voigt", + False, + ), + ( + "lorentzian1", + "lorentzian2", + "_convolute_lorentzian_lorentzian", + False, + ), + ( + "lorentzian1", + "voigt1", + "_convolute_lorentzian_voigt", + False, + ), + ("voigt1", "voigt2", "_convolute_voigt_voigt", False), + # Swapped cases + ("lorentzian1", "gaussian1", "_convolute_gaussian_lorentzian", True), + ("voigt1", "gaussian1", "_convolute_gaussian_voigt", True), + ("voigt1", "lorentzian1", "_convolute_lorentzian_voigt", True), ], indirect=["function1", "function2"], ids=[ "gauss-gauss", "gauss-lorentz", "gauss-voigt", - "lorentz-gauss", "lorentz-lorentz", "lorentz-voigt", + "voigt-voigt", + "lorentz-gauss", "voigt-gauss", "voigt-lorentz", - "voigt-voigt", ], ) - def test_calculate_analytic_pair( - self, default_analytical_convolution, function1, function2 + def test_convolute_analytic_pair_calls_correct_helper( + self, + default_analytical_convolution, + function1, + function2, + expected_method, + swapped, ): - """Test that the analytical convolution methods are correct by comparing to numerical convolution.""" - # WHEN THEN - convoluted = default_analytical_convolution._calculate_analytic_pair( - function1, function2 - ) - - # EXPECT - expected = fftconvolve( - function1.evaluate(default_analytical_convolution.energy.values), - function2.evaluate(default_analytical_convolution.energy.values), - mode="same", - ) * ( - default_analytical_convolution.energy.values[1] - - default_analytical_convolution.energy.values[0] - ) - - # Numerical convolution can be inaccurate at the edges, so only compare the central part - N = len(convoluted) - start = N // 4 - end = 3 * N // 4 + """Test that _convolute_analytic_pair calls the correct internal helper with correct order.""" + + with patch.object( + default_analytical_convolution, + expected_method, + return_value="mocked_result", + ) as mocked_func: + result = default_analytical_convolution._convolute_analytic_pair( + function1, function2 + ) + if swapped: + expected_args = (function2, function1) + else: + expected_args = (function1, function2) - assert np.allclose( - convoluted[start:end], - expected[start:end], - rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, - atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, - ) + mocked_func.assert_called_once_with(*expected_args) + assert result == "mocked_result" @pytest.mark.parametrize( "function1", @@ -146,7 +284,7 @@ def test_calculate_analytic_pair( indirect=True, ids=["gaussian", "lorentzian", "voigt", "dho"], ) - def test_calculate_analytic_pair_delta( + def test_convolute_analytic_pair_delta( self, default_analytical_convolution, function1 ): """Test that convolution with delta function returns the other function.""" @@ -154,7 +292,7 @@ def test_calculate_analytic_pair_delta( delta_function = DeltaFunction(area=2.0, center=0.5) function1 = Gaussian(area=3.0, center=-1.0, width=1.0) - convoluted = default_analytical_convolution._calculate_analytic_pair( + convoluted = default_analytical_convolution._convolute_analytic_pair( delta_function, function1 ) @@ -170,7 +308,7 @@ def test_calculate_analytic_pair_delta( atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, ) - def test_calculate_analytic_pair_resolution_delta_raises( + def test_convolute_analytic_pair_resolution_delta_raises( self, default_analytical_convolution ): """Test that an error is raised if the resolution function is a delta function.""" @@ -183,11 +321,11 @@ def test_calculate_analytic_pair_resolution_delta_raises( ValueError, match="not supported", ): - default_analytical_convolution._calculate_analytic_pair( + default_analytical_convolution._convolute_analytic_pair( sample_function, resolution_function ) - def test_calculate_analytic_pair_non_analytical_pair_raises( + def test_convolute_analytic_pair_non_analytical_pair_raises( self, default_analytical_convolution, gaussian1, dho1 ): """Test that an error is raised if the function pair is not supported for analytical convolution.""" @@ -200,18 +338,18 @@ def test_calculate_analytic_pair_non_analytical_pair_raises( ValueError, match="not supported", ): - default_analytical_convolution._calculate_analytic_pair( + default_analytical_convolution._convolute_analytic_pair( sample_function, resolution_function ) @pytest.mark.parametrize( "method_name, function1, function2", [ - ("_convolute_gauss_gauss", "gaussian1", "gaussian2"), - ("_convolute_gauss_lorentz", "gaussian1", "lorentzian1"), - ("_convolute_gauss_voigt", "gaussian1", "voigt1"), - ("_convolute_lorentz_lorentz", "lorentzian1", "lorentzian2"), - ("_convolute_lorentz_voigt", "lorentzian1", "voigt1"), + ("_convolute_gaussian_gaussian", "gaussian1", "gaussian2"), + ("_convolute_gaussian_lorentzian", "gaussian1", "lorentzian1"), + ("_convolute_gaussian_voigt", "gaussian1", "voigt1"), + ("_convolute_lorentzian_lorentzian", "lorentzian1", "lorentzian2"), + ("_convolute_lorentzian_voigt", "lorentzian1", "voigt1"), ("_convolute_voigt_voigt", "voigt1", "voigt2"), ], indirect=["function1", "function2"], From efe6f8d290ca88be1b661f152c7f363394ce136c Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Thu, 20 Nov 2025 14:32:26 +0100 Subject: [PATCH 49/71] Add comment --- tests/unit_tests/convolution/test_analytical_convolution.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unit_tests/convolution/test_analytical_convolution.py b/tests/unit_tests/convolution/test_analytical_convolution.py index b69d705..e762048 100644 --- a/tests/unit_tests/convolution/test_analytical_convolution.py +++ b/tests/unit_tests/convolution/test_analytical_convolution.py @@ -36,6 +36,7 @@ def function2(request): class TestAnalyticalConvolution: @pytest.fixture def default_analytical_convolution(self): + # Energy needs to be odd to avoid issues with shifts in fftconvolve. energy = np.linspace(-100, 100, 2**15 + 1) sample_model = SampleModel(name="SampleModel") resolution_model = SampleModel(name="ResolutionModel") From 2c57726becec6c964626310ab8c47831bca6aa21 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 21 Nov 2025 10:49:32 +0100 Subject: [PATCH 50/71] test offset --- examples/convolution.ipynb | 129 ++++++++++++++++++ src/easydynamics/convolution/energy_grid.py | 24 ++++ .../convolution/numerical_convolution_base.py | 26 +--- .../convolution/test_energy_grid.py | 29 ++++ .../test_numerical_convolution_base.py | 4 +- 5 files changed, 188 insertions(+), 24 deletions(-) create mode 100644 src/easydynamics/convolution/energy_grid.py create mode 100644 tests/unit_tests/convolution/test_energy_grid.py diff --git a/examples/convolution.ipynb b/examples/convolution.ipynb index 8a2c8bc..017d06c 100644 --- a/examples/convolution.ipynb +++ b/examples/convolution.ipynb @@ -115,6 +115,135 @@ "plt.legend()\n", "plt.ylim(0,2.5)\n" ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "3b4cf569", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(0.0, 6.0)" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Standard example of convolution of a sample model with a resolution model\n", + "sample_model=SampleModel(name='sample_model')\n", + "gaussian=Gaussian(name='Gaussian',width=0.2,area=1)\n", + "lorentzian = Lorentzian(name='Lorentzian',center=-1.0,width=0.1,area=1.0)\n", + "delta = DeltaFunction(name='Delta',center=0.4,area=0.5)\n", + "sample_model.add_component(gaussian)\n", + "sample_model.add_component(lorentzian)\n", + "sample_model.add_component(delta)\n", + "\n", + "resolution_model = SampleModel(name='resolution_model')\n", + "resolution_gaussian=Gaussian(name='Resolution Gaussian',width=0.15,area=0.8)\n", + "resolution_lorentzian = Lorentzian(name='Resolution Lorentzian',width=0.25,area=0.2)\n", + "resolution_model.add_component(resolution_gaussian)\n", + "resolution_model.add_component(resolution_lorentzian)\n", + "\n", + "energy=np.linspace(-2, 2, 100)\n", + "\n", + "\n", + "offset =-1.0\n", + "convolver = Convolution(sample_model=sample_model, resolution_model=resolution_model, energy=energy-offset,offset=0)\n", + "y = convolver.convolution()\n", + "plt.plot(energy, y, label='Convoluted Model')\n", + "plt.xlabel('Energy (meV)')\n", + "plt.ylabel('Intensity (arb. units)')\n", + "plt.title('Convolution of Sample Model with Resolution Model')\n", + "\n", + "plt.plot(energy, sample_model.evaluate(energy-offset), label='Sample Model', linestyle='--')\n", + "plt.plot(energy, resolution_model.evaluate(energy-offset), label='Resolution Model', linestyle=':')\n", + "\n", + "\n", + "plt.legend()\n", + "# set the limit on the y axis\n", + "plt.ylim(0,6)" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "16619e7c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(0.0, 6.0)" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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XVOu3yz6ISIiIovFQIWIiIgsFuuoEBFRrsKBAHMX5qgQERGRxWKgQkRERBaLgQoRERFZLAYqREREZLEYqBAREZHFYqBCREREFouBChER5UoyVk7Xrl2f+3M+//xz1KhRA7nB5yauizT1lkEUs2I06PRioEJERFkSJMgFTiYZFVi6Uf/www9Vt+qWTNKrG+FZ5/3338e2bduypet/+f6lS5cme61KlSrqtYULFyKvsTZ3ZKc7kHVTxYoVzZkkIiLKJO3atcO9e/fU6MgyQOHcuXPViME5cZDFfPnyZct3yeCNMvCgoYMHDyIwMBAuLi7Ii8yeoyJRohzIumnv3r3mThIREWUCBwcHFCpUSF18pQimVatW2LJli/71xMRENWKy5LY4OTmpUYVXrlypfz04OBh9+/aFj4+Per1cuXJGF/EzZ86gRYsW6jUJJN588001+nBaORYzZ840mifFIHLTrHtddOvWTd04654nLS6RdH/xxRcoWrSoWkd5bePGjcmKS1atWoXmzZur0Zll3Q4cOPDMbSbru2vXLgQEBOjn/frrr2q+jNBs6NatW+jSpYsKpGRgv1deeQX37983WmbKlCkoWLCgGo1ZRmtOKUdr/vz5qFSpkho4UDILfvrpJ1gSswcqsuHlQNZNaQ2TTUREWpFxkWrSaDT6eXEJcWpebEJsissmahKfLpuoXTYmISZdyz6vs2fPYv/+/bC3t9fPkyBl0aJFmDNnDs6dO4dRo0bhtddeUxdq8emnn+L8+fP4999/ceHCBcyePVt/jYiIiEDbtm3h5eWFI0eOYMWKFdi6dSvefffdDKdRPkdIMCQ3zrrnSX333XeYPn06pk2bhtOnT6t0dO7cGf7+/kbLffzxx6rYSOp3lC9fHn369EF8fHyaaZCgQj7vt99+U88jIyOxbNkyDBw40Gg5CZYkSHn8+LHaXhIASs5Vr1699MssX75cBVlfffUVjh49isKFCycLQv744w989tlnmDRpktrGsqxsd933WwSNGY0fP17j7OysKVy4sKZUqVKaV199VXPz5s10vz80NFR+oeovEVFuFBUVpTl//rz6a6jqwqpqCooK0s+be2qumjd+33ijZev+XlfNvx1+Wz9v0blFat6Huz40WrbJn03UfP/H/vp5Ky6tMDnd/fv319jY2GhcXFw0Dg4O6lxtbW2tWblypXo9Ojpa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omeqVasW/vrrL9UU2NY2/aeNChUqqIqvho4cOZJsOakT8uGHH+L777/H+fPn0b9//zQ/V3I7MqN1TeXKlVVAcuvWLZVDkhpra2sVPElLIwlopB6O1KFJSiocFy1aVAVSRJQ5WJmWKA+Qyp2BgYFGk2GLnWcZNmyYyi3o06ePCjSkCERa18jFOyEhIdX3SeXZixcv4n//+x8uX76M5cuXq1wJYZhjIi2QpD8Sya1o06aNutinRYphpOJrarkq6SWVdd9//31VgVaKnmS9jh8/rirbynNDsq537tzBuHHj1HbQFfMkreQr6SeizMNAhSgPkFY6UkRjODVu3Djd7/f19VUteSQokQtxtWrVVDNkT09PlduQGmnyK61lpKhE6o5IPRldqx/DohVdM2CpGyL1QZ5Fvl9yeSTweV5ffvklPv30U9X6R5owS3NjKQqStBuSop9WrVqp4CilNEZHR6tm1UOGDHnuNBHRU1ZSo9bgORFRlpLeW6UpsDQdNrR48WKVs3H37l1VtPIsEkxIDowUt6QVLGUXCcJWr16tmj8TUeZhHRUiylI//fSTavmTL18+lSszdepU1TGcjrSQkZ5yp0yZooqK0hOkiI4dO8Lf318VxxQrVgzmJpV2DftnIaLMwRwVIspSkksiPbtKHRcpPpEebceOHauvlCsdtEkuizRHXrt2bYpNoIko72KgQkRERBbL/AW7RERERKlgoEJEREQWi4EKERERWSwGKkRERGSxGKgQERGRxWKgQkRERBaLgQoRERFZLAYqREREZLEYqBAREREs1f8BnjkRKRGpAVoAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Standard example of convolution of a sample model with a resolution model\n", + "sample_model=SampleModel(name='sample_model')\n", + "gaussian=Gaussian(name='Gaussian',width=0.2,area=1)\n", + "lorentzian = Lorentzian(name='Lorentzian',center=-1.0,width=0.1,area=1.0)\n", + "dho = DampedHarmonicOscillator(name='DHO',center=1.0,width=0.3,area=2.0)\n", + "\n", + "delta = DeltaFunction(name='Delta',center=0.4,area=0.5)\n", + "sample_model.add_component(gaussian)\n", + "sample_model.add_component(dho)\n", + "\n", + "\n", + "\n", + "resolution_model = SampleModel(name='resolution_model')\n", + "resolution_gaussian=Gaussian(name='Resolution Gaussian',width=0.15,area=0.8)\n", + "resolution_lorentzian = Lorentzian(name='Resolution Lorentzian',width=0.25,area=0.2)\n", + "resolution_model.add_component(resolution_gaussian)\n", + "# resolution_model.add_component(resolution_lorentzian)\n", + "\n", + "energy=np.linspace(-2, 2, 100)\n", + "\n", + "\n", + "offset =-1.0\n", + "convolver = Convolution(sample_model=sample_model, resolution_model=resolution_model, energy=energy-offset,offset=0)\n", + "y = convolver.convolution()\n", + "plt.plot(energy, y, label='Convoluted Model')\n", + "plt.xlabel('Energy (meV)')\n", + "plt.ylabel('Intensity (arb. units)')\n", + "plt.title('Convolution of Sample Model with Resolution Model')\n", + "\n", + "plt.plot(energy, sample_model.evaluate(energy-offset), label='Sample Model', linestyle='--')\n", + "plt.plot(energy, resolution_model.evaluate(energy-offset), label='Resolution Model', linestyle=':')\n", + "\n", + "\n", + "plt.legend()\n", + "# set the limit on the y axis\n", + "plt.ylim(0,6)" + ] } ], "metadata": { diff --git a/src/easydynamics/convolution/energy_grid.py b/src/easydynamics/convolution/energy_grid.py new file mode 100644 index 0000000..bab23b2 --- /dev/null +++ b/src/easydynamics/convolution/energy_grid.py @@ -0,0 +1,24 @@ +from dataclasses import dataclass + +import numpy as np + + +@dataclass(frozen=True) +class EnergyGrid: + """Container for the dense energy grid and related metadata. + + Attributes: + energy_dense: the (possibly extended & upsampled) energy grid (1D). + span_original: span of the original energy array (max-min). + span_dense: span of the dense grid (max-min). + energy_even_length_offset: -0.5*dE if length is even, else 0.0 — used to correct half-bin shift. + energy_dense_centered: energy_dense recentered around zero (same length as energy_dense). + energy_step: grid spacing (dE) of energy_dense (positive float). + """ + + energy_dense: np.ndarray + span_original: float + span_dense: float + energy_even_length_offset: float + energy_dense_centered: np.ndarray + energy_step: float diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index 6f91d68..d471f01 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -1,5 +1,6 @@ import warnings -from dataclasses import dataclass + +# from dataclasses import dataclass from typing import Optional, Union import numpy as np @@ -7,6 +8,7 @@ from easyscience.variable import Parameter from easydynamics.convolution.convolution_base import ConvolutionBase +from easydynamics.convolution.energy_grid import EnergyGrid from easydynamics.sample_model import ( SampleModel, ) @@ -214,26 +216,6 @@ def normalize_detailed_balance(self, normalize: bool) -> None: self._normalize_detailed_balance = normalize - @dataclass(frozen=True) - class EnergyGrid: - """Container for the dense energy grid and related metadata. - - Attributes: - energy_dense: the (possibly extended & upsampled) energy grid (1D). - span_original: span of the original energy array (max-min). - span_dense: span of the dense grid (max-min). - energy_even_length_offset: -0.5*dE if length is even, else 0.0 — used to correct half-bin shift. - energy_dense_centered: energy_dense recentered around zero (same length as energy_dense). - energy_step: grid spacing (dE) of energy_dense (positive float). - """ - - energy_dense: np.ndarray - span_original: float - span_dense: float - energy_even_length_offset: float - energy_dense_centered: np.ndarray - energy_step: float - def _create_energy_grid( self, ) -> EnergyGrid: @@ -286,7 +268,7 @@ def _create_energy_grid( else: energy_dense_centered = energy_dense - energy_grid = self.EnergyGrid( + energy_grid = EnergyGrid( energy_dense=energy_dense, span_original=span, span_dense=span, diff --git a/tests/unit_tests/convolution/test_energy_grid.py b/tests/unit_tests/convolution/test_energy_grid.py new file mode 100644 index 0000000..42beffa --- /dev/null +++ b/tests/unit_tests/convolution/test_energy_grid.py @@ -0,0 +1,29 @@ +import numpy as np + +from easydynamics.convolution.energy_grid import EnergyGrid + + +class TestEnergyGrid: + def test_energy_grid_attributes(self): + energy_dense = np.array([-1.0, 0.0, 1.0]) + span_original = 2.0 + span_dense = 2.0 + energy_even_length_offset = 0.0 + energy_dense_centered = np.array([-1.0, 0.0, 1.0]) + energy_step = 1.0 + + energy_grid = EnergyGrid( + energy_dense=energy_dense, + span_original=span_original, + span_dense=span_dense, + energy_even_length_offset=energy_even_length_offset, + energy_dense_centered=energy_dense_centered, + energy_step=energy_step, + ) + + assert np.array_equal(energy_grid.energy_dense, energy_dense) + assert energy_grid.span_original == span_original + assert energy_grid.span_dense == span_dense + assert energy_grid.energy_even_length_offset == energy_even_length_offset + assert np.array_equal(energy_grid.energy_dense_centered, energy_dense_centered) + assert energy_grid.energy_step == energy_step diff --git a/tests/unit_tests/convolution/test_numerical_convolution_base.py b/tests/unit_tests/convolution/test_numerical_convolution_base.py index 0f481cb..d399730 100644 --- a/tests/unit_tests/convolution/test_numerical_convolution_base.py +++ b/tests/unit_tests/convolution/test_numerical_convolution_base.py @@ -3,6 +3,7 @@ import scipp as sc from easyscience.variable import Parameter +from easydynamics.convolution.energy_grid import EnergyGrid from easydynamics.convolution.numerical_convolution_base import ( NumericalConvolutionBase, ) @@ -42,5 +43,4 @@ def test_init(self, default_numerical_convolution_base): # assert default_numerical_convolution_base.temperature_unit == "K" assert default_numerical_convolution_base.energy_unit == "meV" assert default_numerical_convolution_base.normalize_detailed_balance is True - - # todo also check _energy_grid + assert isinstance(default_numerical_convolution_base._energy_grid, EnergyGrid) From d9d2cf6caa28b9896f31922fef4bb0523be34c54 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 21 Nov 2025 10:56:59 +0100 Subject: [PATCH 51/71] Remove offset --- .../convolution/analytical_convolution.py | 32 +++------- src/easydynamics/convolution/convolution.py | 10 +--- .../convolution/convolution_base.py | 40 +------------ .../convolution/numerical_convolution.py | 11 +--- .../convolution/numerical_convolution_base.py | 5 -- .../convolution/test_convolution_base.py | 59 ------------------- 6 files changed, 11 insertions(+), 146 deletions(-) diff --git a/src/easydynamics/convolution/analytical_convolution.py b/src/easydynamics/convolution/analytical_convolution.py index f5e0c52..0f0aba3 100644 --- a/src/easydynamics/convolution/analytical_convolution.py +++ b/src/easydynamics/convolution/analytical_convolution.py @@ -2,7 +2,6 @@ import numpy as np import scipp as sc -from easyscience.variable import Parameter from scipy.special import voigt_profile from easydynamics.convolution.convolution_base import ConvolutionBase @@ -28,8 +27,6 @@ class AnalyticalConvolution(ConvolutionBase): The sample model to be convolved. resolution_model : SampleModel or ModelComponent The resolution model to convolve with. - offset : float, Parameter or None, optional - The offset in energy to apply to the convolution. """ # Mapping of supported component type pairs to convolution methods. @@ -49,14 +46,12 @@ def __init__( energy_unit: Optional[Union[str, sc.Unit]] = "meV", sample_model: Optional[SampleModel] = None, resolution_model: Optional[SampleModel] = None, - offset: Optional[Union[Numerical, Parameter]] = 0.0, ): super().__init__( energy=energy, sample_model=sample_model, resolution_model=resolution_model, energy_unit=energy_unit, - offset=offset, ) def convolution( @@ -117,7 +112,6 @@ def _convolute_analytic_pair( The convolution of two voigt profiles results in another voigt profile, with the gaussian widths summed in quadrature and the lorentzian widths summed. The convolution of a delta function with any component or SampleModel results in the same component or SampleModel shifted by the delta center. All areas are multiplied. - The output is shifted by self.offset.value. Args: @@ -189,7 +183,7 @@ def _convolute_delta_any( The evaluated convolution values at self.energy. """ return sample_component.area.value * resolution_model.evaluate( - self.energy.values - sample_component.center.value - self.offset.value + self.energy.values - sample_component.center.value ) def _convolute_gaussian_gaussian( @@ -219,9 +213,7 @@ def _convolute_gaussian_gaussian( area = sample_component.area.value * resolution_component.area.value - center = ( - sample_component.center.value + resolution_component.center.value - ) + self.offset.value + center = sample_component.center.value + resolution_component.center.value return self._gaussian_eval(area=area, center=center, width=width) @@ -244,9 +236,7 @@ def _convolute_gaussian_lorentzian( np.ndarray The evaluated convolution values at self.energy. """ - center = ( - sample_component.center.value + resolution_component.center.value - ) + self.offset.value + center = sample_component.center.value + resolution_component.center.value area = sample_component.area.value * resolution_component.area.value return self._voigt_eval( @@ -278,9 +268,7 @@ def _convolute_gaussian_voigt( """ area = sample_component.area.value * resolution_component.area.value - center = ( - sample_component.center.value + resolution_component.center.value - ) + self.offset.value + center = sample_component.center.value + resolution_component.center.value gaussian_width = np.sqrt( sample_component.width.value**2 @@ -316,9 +304,7 @@ def _convolute_lorentzian_lorentzian( """ area = sample_component.area.value * resolution_component.area.value - center = ( - sample_component.center.value + resolution_component.center.value - ) + self.offset.value + center = sample_component.center.value + resolution_component.center.value width = sample_component.width.value + resolution_component.width.value @@ -344,9 +330,7 @@ def _convolute_lorentzian_voigt( """ area = sample_component.area.value * resolution_component.area.value - center = ( - sample_component.center.value + resolution_component.center.value - ) + self.offset.value + center = sample_component.center.value + resolution_component.center.value gaussian_width = resolution_component.gaussian_width.value @@ -381,9 +365,7 @@ def _convolute_voigt_voigt( """ area = sample_component.area.value * resolution_component.area.value - center = ( - sample_component.center.value + resolution_component.center.value - ) + self.offset.value + center = sample_component.center.value + resolution_component.center.value gaussian_width = np.sqrt( sample_component.gaussian_width.value**2 diff --git a/src/easydynamics/convolution/convolution.py b/src/easydynamics/convolution/convolution.py index b298df2..813b4fc 100644 --- a/src/easydynamics/convolution/convolution.py +++ b/src/easydynamics/convolution/convolution.py @@ -37,8 +37,6 @@ class Convolution(NumericalConvolutionBase): The sample model to be convolved. resolution_model : SampleModel or ModelComponent The resolution model to convolve with. - offset_float : float, or None, optional - The offset to apply to the input array. upsample_factor : int, optional The factor by which to upsample the input data before convolution. Default is 5. extension_factor : float, optional @@ -58,7 +56,6 @@ def __init__( energy: Union[np.ndarray, sc.Variable], sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], - offset: Optional[Union[Numerical, Parameter]] = 0.0, upsample_factor: Optional[Numerical] = 5, extension_factor: Optional[float] = 0.2, temperature: Optional[Union[Parameter, float]] = None, @@ -70,7 +67,6 @@ def __init__( energy=energy, sample_model=sample_model, resolution_model=resolution_model, - offset=offset, upsample_factor=upsample_factor, extension_factor=extension_factor, temperature=temperature, @@ -107,9 +103,7 @@ def convolution( if self._delta_sample_model.components: for sample_component in self._delta_sample_model.components: total += sample_component.area.value * self._resolution_model.evaluate( - self.energy.values - - sample_component.center.value - - self.offset.value + self.energy.values - sample_component.center.value ) return total @@ -163,7 +157,6 @@ def _set_convolvers(self) -> None: energy=self.energy, sample_model=self._analytical_sample_model, resolution_model=self._resolution_model, - offset=self.offset, ) else: self._analytical_convolver = None @@ -173,7 +166,6 @@ def _set_convolvers(self) -> None: energy=self.energy, sample_model=self._numerical_sample_model, resolution_model=self._resolution_model, - offset=self._offset, upsample_factor=self._upsample_factor, extension_factor=self._extension_factor, temperature=self._temperature, diff --git a/src/easydynamics/convolution/convolution_base.py b/src/easydynamics/convolution/convolution_base.py index 5e38746..9914952 100644 --- a/src/easydynamics/convolution/convolution_base.py +++ b/src/easydynamics/convolution/convolution_base.py @@ -1,8 +1,7 @@ -from typing import Optional, Union +from typing import Union import numpy as np import scipp as sc -from easyscience.variable import Parameter from easydynamics.sample_model import SampleModel from easydynamics.sample_model.components.model_component import ModelComponent @@ -24,8 +23,6 @@ class ConvolutionBase: The resolution model to convolve with. energy_unit : str or sc.Unit, optional The unit of the energy. Default is 'meV'. - offset : float, or None, optional - The offset to apply to the input array. """ def __init__( @@ -34,7 +31,6 @@ def __init__( sample_model: Union[SampleModel, ModelComponent] = None, resolution_model: Union[SampleModel, ModelComponent] = None, energy_unit: Union[str, sc.Unit] = "meV", - offset: Optional[Union[Numerical, Parameter]] = None, ): if isinstance(energy, Numerical): energy = np.array([float(energy)]) @@ -65,17 +61,6 @@ def __init__( ) self._resolution_model = resolution_model - if offset is None: - offset = 0.0 - - if isinstance(offset, Numerical): - offset = Parameter(value=offset, name="offset", unit=energy_unit) - - if not isinstance(offset, Parameter): - raise TypeError("Offset must be a Number or Parameter.") - - self._offset = offset - @property def energy(self) -> sc.Variable: """Get the energy""" @@ -182,26 +167,3 @@ def resolution_model( f"`resolution_model` is an instance of {type(resolution_model).__name__}, but must be a SampleModel or ModelComponent." ) self._resolution_model = resolution_model - - @property - def offset(self) -> Parameter: - """Get the offset""" - return self._offset - - @offset.setter - def offset(self, offset: Union[Numerical, Parameter]) -> None: - """Set the offset. - Args: - offset : Number or Parameter - The offset to apply to the input array. - - Raises: - TypeError: If offset is not a Number or Parameter. - """ - if not isinstance(offset, (Numerical, Parameter)): - raise TypeError("Offset must be a Number or Parameter.") - - if isinstance(offset, Numerical): - self._offset.value = offset - else: - self._offset = offset diff --git a/src/easydynamics/convolution/numerical_convolution.py b/src/easydynamics/convolution/numerical_convolution.py index c590f6c..56b3ba0 100644 --- a/src/easydynamics/convolution/numerical_convolution.py +++ b/src/easydynamics/convolution/numerical_convolution.py @@ -30,8 +30,6 @@ class NumericalConvolution(NumericalConvolutionBase): The sample model to be convolved. resolution_model : SampleModel or ModelComponent The resolution model to convolve with. - offset_float : float, or None, optional - The offset to apply to the input array. upsample_factor : int, optional The factor by which to upsample the input data before convolution. Default is 5. extension_factor : float, optional @@ -51,7 +49,6 @@ def __init__( energy: Union[np.ndarray, sc.Variable], sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], - offset: Optional[Union[Numerical, Parameter]] = 0.0, upsample_factor: Optional[Numerical] = 5, extension_factor: Optional[float] = 0.2, temperature: Optional[Union[Parameter, float]] = None, @@ -63,7 +60,6 @@ def __init__( energy=energy, sample_model=sample_model, resolution_model=resolution_model, - offset=offset, upsample_factor=upsample_factor, extension_factor=extension_factor, temperature=temperature, @@ -97,15 +93,13 @@ def convolution( # Evaluate sample model. If called via the Convolution class, delta functions are already filtered out. sample_vals = self.sample_model.evaluate( - self._energy_grid.energy_dense - - self._offset.value - - self._energy_grid.energy_even_length_offset + self._energy_grid.energy_dense - self._energy_grid.energy_even_length_offset ) # Detailed balance correction if self.temperature is not None: detailed_balance_factor_correction = detailed_balance_factor( - energy=self._energy_grid.energy_dense - self._offset.value, + energy=self._energy_grid.energy_dense, temperature=self.temperature, energy_unit=self.energy.unit, divide_by_temperature=self.normalize_detailed_balance, @@ -138,7 +132,6 @@ def __repr__(self) -> str: return ( f"NumericalConvolution(energy_unit={self._energy_unit}, " - f"offset={self.offset}, upsample_factor={self.upsample_factor}, " f"extension_factor={self.extension_factor}, " f"temperature={self.temperature}, " f"temperature_unit={self.temperature_unit}, " diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index d471f01..d7db857 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -30,8 +30,6 @@ class NumericalConvolutionBase(ConvolutionBase): The sample model to be convolved. resolution_model : SampleModel or ModelComponent The resolution model to convolve with. - offset_float : float, or None, optional - The offset to apply to the input array. upsample_factor : int, optional The factor by which to upsample the input data before convolution. Default is 5. extension_factor : float, optional @@ -51,7 +49,6 @@ def __init__( energy: Union[np.ndarray, sc.Variable], sample_model: Union[SampleModel, ModelComponent], resolution_model: Union[SampleModel, ModelComponent], - offset: Optional[Union[Numerical, Parameter]] = 0.0, upsample_factor: Optional[Numerical] = 5, extension_factor: Optional[float] = 0.2, temperature: Optional[Union[Parameter, float]] = None, @@ -64,7 +61,6 @@ def __init__( sample_model=sample_model, resolution_model=resolution_model, energy_unit=energy_unit, - offset=offset, ) if temperature is not None: @@ -342,7 +338,6 @@ def __repr__(self) -> str: f"sample_model={self.sample_model}, " f"resolution_model={self.resolution_model}, " f"energy_unit={self._energy_unit}, " - f"offset={self.offset}, " f"upsample_factor={self.upsample_factor}, " f"extension_factor={self.extension_factor}, " f"temperature={self.temperature}, " diff --git a/tests/unit_tests/convolution/test_convolution_base.py b/tests/unit_tests/convolution/test_convolution_base.py index 814affe..ca1348f 100644 --- a/tests/unit_tests/convolution/test_convolution_base.py +++ b/tests/unit_tests/convolution/test_convolution_base.py @@ -1,7 +1,6 @@ import numpy as np import pytest import scipp as sc -from easyscience.variable import Parameter from easydynamics.convolution.convolution_base import ( ConvolutionBase, @@ -15,13 +14,11 @@ def convolution_base(self): energy = np.linspace(-10, 10, 100) sample_model = SampleModel(name="SampleModel") resolution_model = SampleModel(name="ResolutionModel") - offset = 0.0 return ConvolutionBase( energy=energy, sample_model=sample_model, resolution_model=resolution_model, - offset=offset, ) def test_init(self, convolution_base): @@ -31,9 +28,6 @@ def test_init(self, convolution_base): assert np.allclose(convolution_base.energy.values, np.linspace(-10, 10, 100)) assert isinstance(convolution_base._sample_model, SampleModel) assert isinstance(convolution_base._resolution_model, SampleModel) - assert isinstance(convolution_base.offset, Parameter) - assert convolution_base.offset.value == 0.0 - assert convolution_base.offset.unit == "meV" def test_init_energy_numerical_none_offset(self): # WHEN @@ -41,7 +35,6 @@ def test_init_energy_numerical_none_offset(self): convolution_base = ConvolutionBase( energy=energy, - offset=None, ) # THEN EXPECT @@ -51,8 +44,6 @@ def test_init_energy_numerical_none_offset(self): assert convolution_base.energy.unit == "meV" assert convolution_base._sample_model is None assert convolution_base._resolution_model is None - assert convolution_base.offset.value == 0.0 - assert convolution_base.offset.unit == "meV" @pytest.mark.parametrize( "kwargs, expected_message", @@ -63,7 +54,6 @@ def test_init_energy_numerical_none_offset(self): "sample_model": SampleModel(), "resolution_model": SampleModel(), "energy_unit": "meV", - "offset": 0.0, }, "Energy must be", ), @@ -73,7 +63,6 @@ def test_init_energy_numerical_none_offset(self): "sample_model": "invalid", "resolution_model": SampleModel(), "energy_unit": "meV", - "offset": 0.0, }, "`sample_model` is an instance of str, but must be a SampleModel or ModelComponent.", ), @@ -83,7 +72,6 @@ def test_init_energy_numerical_none_offset(self): "sample_model": SampleModel(), "resolution_model": "invalid", "energy_unit": "meV", - "offset": 0.0, }, "`resolution_model` is an instance of str, but must be a SampleModel or ModelComponent.", ), @@ -93,20 +81,9 @@ def test_init_energy_numerical_none_offset(self): "sample_model": SampleModel(), "resolution_model": SampleModel(), "energy_unit": 123, - "offset": 0.0, }, "Energy_unit must be ", ), - ( - { - "energy": np.linspace(-10, 10, 100), - "sample_model": SampleModel(), - "resolution_model": SampleModel(), - "energy_unit": "meV", - "offset": "invalid", - }, - "Offset must be a Number or Parameter.", - ), ], ) def test_input_type_validation_raises(self, kwargs, expected_message): @@ -225,39 +202,3 @@ def test_resolution_model_setter_invalid_type_raises(self, convolution_base): match="`resolution_model` is an instance of str, but must be a SampleModel or ModelComponent.", ): convolution_base.resolution_model = "invalid" - - def test_offset_property(self, convolution_base): - # WHEN THEN EXPECT - assert isinstance(convolution_base.offset, Parameter) - assert convolution_base.offset.value == 0.0 - - def test_offset_setter_parameter(self, convolution_base): - # WHEN - new_offset = Parameter(value=2.5, name="offset", unit="meV") - - # THEN - convolution_base.offset = new_offset - - # EXPECT - assert convolution_base.offset == new_offset - - def test_offset_setter_numerical(self, convolution_base): - "Make sure the offset unique name remains the same when setting the numerical value" - # WHEN - convolution_base.offset = 3.5 - old_offset_unique_name = convolution_base.offset.unique_name - - # THEN - convolution_base.offset = 3.5 - - # EXPECT - assert convolution_base.offset.value == 3.5 - assert convolution_base.offset.unique_name == old_offset_unique_name - - def test_offset_setter_invalid_type_raises(self, convolution_base): - # WHEN THEN EXPECT - with pytest.raises( - TypeError, - match="Offset must be a Number or Parameter.", - ): - convolution_base.offset = "invalid" From 8ae2364020c2241f26c14614245ec6d39d18ff16 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 21 Nov 2025 11:18:44 +0100 Subject: [PATCH 52/71] Update example and fix offset bug --- examples/convolution.ipynb | 137 +----------------- .../convolution/numerical_convolution_base.py | 16 +- .../test_numerical_convolution_base.py | 4 - 3 files changed, 13 insertions(+), 144 deletions(-) diff --git a/examples/convolution.ipynb b/examples/convolution.ipynb index 017d06c..1188a6b 100644 --- a/examples/convolution.ipynb +++ b/examples/convolution.ipynb @@ -87,8 +87,8 @@ "\n", "temperature = 10.0 # Temperature in Kelvin\n", "offset = 0.5\n", - "upsample_factor = 15\n", - "extension_factor = 0.8\n", + "upsample_factor = 5\n", + "extension_factor = 0.5\n", "\n", "plt.xlabel('Energy (meV)')\n", "plt.ylabel('Intensity (arb. units)')\n", @@ -96,8 +96,7 @@ "convolver = Convolution(\n", " sample_model=sample_model, \n", " resolution_model=resolution_model, \n", - " energy=energy, \n", - " offset=offset,\n", + " energy=energy-offset, \n", " upsample_factor=upsample_factor,\n", " extension_factor=extension_factor,\n", " temperature=temperature,\n", @@ -107,6 +106,7 @@ "\n", "plt.plot(energy, y, label='Convoluted Model')\n", "\n", + "# plt.plot(energy, sample_model.evaluate(energy-offset), label='Sample Model with DB', linestyle='--')\n", "plt.plot(energy, sample_model.evaluate(energy-offset)*detailed_balance_factor(energy-offset, temperature), label='Sample Model with DB', linestyle='--')\n", "\n", "plt.plot(energy, resolution_model.evaluate(energy ), label='Resolution Model', linestyle=':')\n", @@ -115,135 +115,6 @@ "plt.legend()\n", "plt.ylim(0,2.5)\n" ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "3b4cf569", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(0.0, 6.0)" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Standard example of convolution of a sample model with a resolution model\n", - "sample_model=SampleModel(name='sample_model')\n", - "gaussian=Gaussian(name='Gaussian',width=0.2,area=1)\n", - "lorentzian = Lorentzian(name='Lorentzian',center=-1.0,width=0.1,area=1.0)\n", - "delta = DeltaFunction(name='Delta',center=0.4,area=0.5)\n", - "sample_model.add_component(gaussian)\n", - "sample_model.add_component(lorentzian)\n", - "sample_model.add_component(delta)\n", - "\n", - "resolution_model = SampleModel(name='resolution_model')\n", - "resolution_gaussian=Gaussian(name='Resolution Gaussian',width=0.15,area=0.8)\n", - "resolution_lorentzian = Lorentzian(name='Resolution Lorentzian',width=0.25,area=0.2)\n", - "resolution_model.add_component(resolution_gaussian)\n", - "resolution_model.add_component(resolution_lorentzian)\n", - "\n", - "energy=np.linspace(-2, 2, 100)\n", - "\n", - "\n", - "offset =-1.0\n", - "convolver = Convolution(sample_model=sample_model, resolution_model=resolution_model, energy=energy-offset,offset=0)\n", - "y = convolver.convolution()\n", - "plt.plot(energy, y, label='Convoluted Model')\n", - "plt.xlabel('Energy (meV)')\n", - "plt.ylabel('Intensity (arb. units)')\n", - "plt.title('Convolution of Sample Model with Resolution Model')\n", - "\n", - "plt.plot(energy, sample_model.evaluate(energy-offset), label='Sample Model', linestyle='--')\n", - "plt.plot(energy, resolution_model.evaluate(energy-offset), label='Resolution Model', linestyle=':')\n", - "\n", - "\n", - "plt.legend()\n", - "# set the limit on the y axis\n", - "plt.ylim(0,6)" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "16619e7c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(0.0, 6.0)" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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XVOu3yz6ISIiIovFQIWIiIgsFuuoEBFRrsKBAHMX5qgQERGRxWKgQkRERBaLgQoRERFZLAYqREREZLEYqBAREZHFYqBCREREFouBChER5UoyVk7Xrl2f+3M+//xz1KhRA7nB5yauizT1lkEUs2I06PRioEJERFkSJMgFTiYZFVi6Uf/www9Vt+qWTNKrG+FZ5/3338e2bduypet/+f6lS5cme61KlSrqtYULFyKvsTZ3ZKc7kHVTxYoVzZkkIiLKJO3atcO9e/fU6MgyQOHcuXPViME5cZDFfPnyZct3yeCNMvCgoYMHDyIwMBAuLi7Ii8yeoyJRohzIumnv3r3mThIREWUCBwcHFCpUSF18pQimVatW2LJli/71xMRENWKy5LY4OTmpUYVXrlypfz04OBh9+/aFj4+Per1cuXJGF/EzZ86gRYsW6jUJJN588001+nBaORYzZ840mifFIHLTrHtddOvWTd04654nLS6RdH/xxRcoWrSoWkd5bePGjcmKS1atWoXmzZur0Zll3Q4cOPDMbSbru2vXLgQEBOjn/frrr2q+jNBs6NatW+jSpYsKpGRgv1deeQX37983WmbKlCkoWLCgGo1ZRmtOKUdr/vz5qFSpkho4UDILfvrpJ1gSswcqsuHlQNZNaQ2TTUREWpFxkWrSaDT6eXEJcWpebEJsissmahKfLpuoXTYmISZdyz6vs2fPYv/+/bC3t9fPkyBl0aJFmDNnDs6dO4dRo0bhtddeUxdq8emnn+L8+fP4999/ceHCBcyePVt/jYiIiEDbtm3h5eWFI0eOYMWKFdi6dSvefffdDKdRPkdIMCQ3zrrnSX333XeYPn06pk2bhtOnT6t0dO7cGf7+/kbLffzxx6rYSOp3lC9fHn369EF8fHyaaZCgQj7vt99+U88jIyOxbNkyDBw40Gg5CZYkSHn8+LHaXhIASs5Vr1699MssX75cBVlfffUVjh49isKFCycLQv744w989tlnmDRpktrGsqxsd933WwSNGY0fP17j7OysKVy4sKZUqVKaV199VXPz5s10vz80NFR+oeovEVFuFBUVpTl//rz6a6jqwqpqCooK0s+be2qumjd+33ijZev+XlfNvx1+Wz9v0blFat6Huz40WrbJn03UfP/H/vp5Ky6tMDnd/fv319jY2GhcXFw0Dg4O6lxtbW2tWblypXo9Ojpa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omeqVasW/vrrL9UU2NY2/aeNChUqqIqvho4cOZJsOakT8uGHH+L777/H+fPn0b9//zQ/V3I7MqN1TeXKlVVAcuvWLZVDkhpra2sVPElLIwlopB6O1KFJSiocFy1aVAVSRJQ5WJmWKA+Qyp2BgYFGk2GLnWcZNmyYyi3o06ePCjSkCERa18jFOyEhIdX3SeXZixcv4n//+x8uX76M5cuXq1wJYZhjIi2QpD8Sya1o06aNutinRYphpOJrarkq6SWVdd9//31VgVaKnmS9jh8/rirbynNDsq537tzBuHHj1HbQFfMkreQr6SeizMNAhSgPkFY6UkRjODVu3Djd7/f19VUteSQokQtxtWrVVDNkT09PlduQGmnyK61lpKhE6o5IPRldqx/DohVdM2CpGyL1QZ5Fvl9yeSTweV5ffvklPv30U9X6R5owS3NjKQqStBuSop9WrVqp4CilNEZHR6tm1UOGDHnuNBHRU1ZSo9bgORFRlpLeW6UpsDQdNrR48WKVs3H37l1VtPIsEkxIDowUt6QVLGUXCcJWr16tmj8TUeZhHRUiylI//fSTavmTL18+lSszdepU1TGcjrSQkZ5yp0yZooqK0hOkiI4dO8Lf318VxxQrVgzmJpV2DftnIaLMwRwVIspSkksiPbtKHRcpPpEebceOHauvlCsdtEkuizRHXrt2bYpNoIko72KgQkRERBbL/AW7RERERKlgoEJEREQWi4EKERERWSwGKkRERGSxGKgQERGRxWKgQkRERBaLgQoRERFZLAYqREREZLEYqBAREREs1f8BnjkRKRGpAVoAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Standard example of convolution of a sample model with a resolution model\n", - "sample_model=SampleModel(name='sample_model')\n", - "gaussian=Gaussian(name='Gaussian',width=0.2,area=1)\n", - "lorentzian = Lorentzian(name='Lorentzian',center=-1.0,width=0.1,area=1.0)\n", - "dho = DampedHarmonicOscillator(name='DHO',center=1.0,width=0.3,area=2.0)\n", - "\n", - "delta = DeltaFunction(name='Delta',center=0.4,area=0.5)\n", - "sample_model.add_component(gaussian)\n", - "sample_model.add_component(dho)\n", - "\n", - "\n", - "\n", - "resolution_model = SampleModel(name='resolution_model')\n", - "resolution_gaussian=Gaussian(name='Resolution Gaussian',width=0.15,area=0.8)\n", - "resolution_lorentzian = Lorentzian(name='Resolution Lorentzian',width=0.25,area=0.2)\n", - "resolution_model.add_component(resolution_gaussian)\n", - "# resolution_model.add_component(resolution_lorentzian)\n", - "\n", - "energy=np.linspace(-2, 2, 100)\n", - "\n", - "\n", - "offset =-1.0\n", - "convolver = Convolution(sample_model=sample_model, resolution_model=resolution_model, energy=energy-offset,offset=0)\n", - "y = convolver.convolution()\n", - "plt.plot(energy, y, label='Convoluted Model')\n", - "plt.xlabel('Energy (meV)')\n", - "plt.ylabel('Intensity (arb. units)')\n", - "plt.title('Convolution of Sample Model with Resolution Model')\n", - "\n", - "plt.plot(energy, sample_model.evaluate(energy-offset), label='Sample Model', linestyle='--')\n", - "plt.plot(energy, resolution_model.evaluate(energy-offset), label='Resolution Model', linestyle=':')\n", - "\n", - "\n", - "plt.legend()\n", - "# set the limit on the y axis\n", - "plt.ylim(0,6)" - ] } ], "metadata": { diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index d7db857..f0193e7 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -228,22 +228,24 @@ def _create_energy_grid( is_uniform = np.allclose(energy_diff, energy_diff[0]) if not is_uniform: raise ValueError( - "Input array `energy` must be uniformly spaced if upsample_factor = 0." + "Input array `energy` must be uniformly spaced if upsample_factor is not given." ) energy_dense = self.energy.values span = self.energy.values.max() - self.energy.values.min() + span_original = span else: # Create an extended and upsampled energy grid energy_min, energy_max = self.energy.values.min(), self.energy.values.max() - span = energy_max - energy_min - extra = self.extension_factor * span + span_original = energy_max - energy_min + extra = self.extension_factor * span_original extended_min = energy_min - extra extended_max = energy_max + extra num_points = round(len(self.energy.values) * self.upsample_factor) energy_dense = np.linspace(extended_min, extended_max, num_points) + span = extended_max - extended_min - energy_step = energy_dense[1] - energy_dense[0] + energy_dense_step = energy_dense[1] - energy_dense[0] # Handle offset for even length of x in convolution. # The convolution of two arrays of length N is of length 2N-1. When using 'same' mode, only the central N points are kept, @@ -252,7 +254,7 @@ def _create_energy_grid( # For example, if N=4, the convolution has length 7, and when we select the 4 central points we either get # indices [2,3,4,5] or [1,2,3,4], both of which are offset by 0.5*dx from the true center at index 3.5. if len(energy_dense) % 2 == 0: - energy_even_length_offset = -0.5 * energy_step + energy_even_length_offset = -0.5 * energy_dense_step else: energy_even_length_offset = 0.0 @@ -266,11 +268,11 @@ def _create_energy_grid( energy_grid = EnergyGrid( energy_dense=energy_dense, - span_original=span, + span_original=span_original, span_dense=span, energy_even_length_offset=energy_even_length_offset, energy_dense_centered=energy_dense_centered, - energy_step=energy_step, + energy_step=energy_dense_step, ) return energy_grid diff --git a/tests/unit_tests/convolution/test_numerical_convolution_base.py b/tests/unit_tests/convolution/test_numerical_convolution_base.py index d399730..f0d0fef 100644 --- a/tests/unit_tests/convolution/test_numerical_convolution_base.py +++ b/tests/unit_tests/convolution/test_numerical_convolution_base.py @@ -1,7 +1,6 @@ import numpy as np import pytest import scipp as sc -from easyscience.variable import Parameter from easydynamics.convolution.energy_grid import EnergyGrid from easydynamics.convolution.numerical_convolution_base import ( @@ -34,9 +33,6 @@ def test_init(self, default_numerical_convolution_base): assert isinstance( default_numerical_convolution_base._resolution_model, SampleModel ) - assert isinstance(default_numerical_convolution_base.offset, Parameter) - assert default_numerical_convolution_base.offset.value == 0.0 - assert default_numerical_convolution_base.offset.unit == "meV" assert default_numerical_convolution_base.upsample_factor == 5 assert default_numerical_convolution_base.extension_factor == 0.2 assert default_numerical_convolution_base.temperature is None From 5b69decc747ee2bdf52cc724943f5d3dc2f7cba3 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 21 Nov 2025 13:00:28 +0100 Subject: [PATCH 53/71] small changes --- examples/convolution.ipynb | 1 - src/easydynamics/convolution/energy_grid.py | 23 ++++++---- .../convolution/numerical_convolution_base.py | 46 ++++++++++++------- .../convolution/test_energy_grid.py | 25 +++++----- 4 files changed, 57 insertions(+), 38 deletions(-) diff --git a/examples/convolution.ipynb b/examples/convolution.ipynb index 1188a6b..0911d2e 100644 --- a/examples/convolution.ipynb +++ b/examples/convolution.ipynb @@ -106,7 +106,6 @@ "\n", "plt.plot(energy, y, label='Convoluted Model')\n", "\n", - "# plt.plot(energy, sample_model.evaluate(energy-offset), label='Sample Model with DB', linestyle='--')\n", "plt.plot(energy, sample_model.evaluate(energy-offset)*detailed_balance_factor(energy-offset, temperature), label='Sample Model with DB', linestyle='--')\n", "\n", "plt.plot(energy, resolution_model.evaluate(energy ), label='Resolution Model', linestyle=':')\n", diff --git a/src/easydynamics/convolution/energy_grid.py b/src/easydynamics/convolution/energy_grid.py index bab23b2..b2a2e0b 100644 --- a/src/easydynamics/convolution/energy_grid.py +++ b/src/easydynamics/convolution/energy_grid.py @@ -8,17 +8,20 @@ class EnergyGrid: """Container for the dense energy grid and related metadata. Attributes: - energy_dense: the (possibly extended & upsampled) energy grid (1D). - span_original: span of the original energy array (max-min). - span_dense: span of the dense grid (max-min). - energy_even_length_offset: -0.5*dE if length is even, else 0.0 — used to correct half-bin shift. - energy_dense_centered: energy_dense recentered around zero (same length as energy_dense). - energy_step: grid spacing (dE) of energy_dense (positive float). + energy_dense : np.ndarray + The upsampled and extended energy array. + energy_dense_centered : np.ndarray + The centered version of energy_dense (used for resolution evaluation). + energy_dense_step : float + The spacing of energy_dense (used for width checks and normalization). + energy_span_dense : float + The total span of energy_dense. (used for width checks). + energy_even_length_offset : float + The offset to apply if energy_dense has even length (used for convolution alignment). """ energy_dense: np.ndarray - span_original: float - span_dense: float - energy_even_length_offset: float energy_dense_centered: np.ndarray - energy_step: float + energy_dense_step: float + energy_span_dense: float + energy_even_length_offset: float diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index f0193e7..e0f5178 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -216,11 +216,27 @@ def _create_energy_grid( self, ) -> EnergyGrid: """ - Create a dense grid by upsampling and extending the input energy array. - + Create a dense grid by upsampling and extending the energy array. + # energy_dense=energy_dense, + # energy_dense_centered=energy_dense_centered, + # energy_dense_step=energy_dense_step, + # span_dense=span, + # span_original=span_original, + # energy_even_length_offset=energy_even_length_offset, Returns: - DenseGrid - The dense grid created by upsampling and extending x. + EnergyGrid + The dense grid created by upsampling and extending energy. + The EnergyGrid has the following attributes: + energy_dense : np.ndarray + The upsampled and extended energy array. + energy_dense_centered : np.ndarray + The centered version of energy_dense (used for resolution evaluation). + energy_dense_step : float + The spacing of energy_dense (used for width checks and normalization). + energy_span_dense : float + The total span of energy_dense. (used for width checks). + energy_even_length_offset : float + The offset to apply if energy_dense has even length (used for convolution alignment). """ if self.upsample_factor is None: # Check if the array is uniformly spaced. @@ -232,22 +248,21 @@ def _create_energy_grid( ) energy_dense = self.energy.values - span = self.energy.values.max() - self.energy.values.min() - span_original = span + energy_span_dense = self.energy.values.max() - self.energy.values.min() else: # Create an extended and upsampled energy grid energy_min, energy_max = self.energy.values.min(), self.energy.values.max() - span_original = energy_max - energy_min - extra = self.extension_factor * span_original + energy_span_original = energy_max - energy_min + extra = self.extension_factor * energy_span_original extended_min = energy_min - extra extended_max = energy_max + extra num_points = round(len(self.energy.values) * self.upsample_factor) energy_dense = np.linspace(extended_min, extended_max, num_points) - span = extended_max - extended_min + energy_span_dense = extended_max - extended_min energy_dense_step = energy_dense[1] - energy_dense[0] - # Handle offset for even length of x in convolution. + # Handle offset for even length of energy_dense in convolution. # The convolution of two arrays of length N is of length 2N-1. When using 'same' mode, only the central N points are kept, # so the output has the same length as the input. # However, if N is even, the center falls between two points, leading to a half-bin offset. @@ -258,21 +273,20 @@ def _create_energy_grid( else: energy_even_length_offset = 0.0 - # Handle the case when x is not symmetric around zero. The resolution is still centered around zero (or close to it), so it needs to be evaluated there. + # Handle the case when energy_dense is not symmetric around zero. The resolution is still centered around zero (or close to it), so it needs to be evaluated there. if not np.isclose(energy_dense.mean(), 0.0): energy_dense_centered = np.linspace( - -0.5 * span, 0.5 * span, len(energy_dense) + -0.5 * energy_span_dense, 0.5 * energy_span_dense, len(energy_dense) ) else: energy_dense_centered = energy_dense energy_grid = EnergyGrid( energy_dense=energy_dense, - span_original=span_original, - span_dense=span, - energy_even_length_offset=energy_even_length_offset, energy_dense_centered=energy_dense_centered, - energy_step=energy_dense_step, + energy_dense_step=energy_dense_step, + energy_span_dense=energy_span_dense, + energy_even_length_offset=energy_even_length_offset, ) return energy_grid diff --git a/tests/unit_tests/convolution/test_energy_grid.py b/tests/unit_tests/convolution/test_energy_grid.py index 42beffa..3b20e56 100644 --- a/tests/unit_tests/convolution/test_energy_grid.py +++ b/tests/unit_tests/convolution/test_energy_grid.py @@ -6,24 +6,27 @@ class TestEnergyGrid: def test_energy_grid_attributes(self): energy_dense = np.array([-1.0, 0.0, 1.0]) - span_original = 2.0 - span_dense = 2.0 - energy_even_length_offset = 0.0 energy_dense_centered = np.array([-1.0, 0.0, 1.0]) - energy_step = 1.0 + energy_dense_step = 1.0 + energy_span_dense = 2.0 + energy_even_length_offset = 0.0 energy_grid = EnergyGrid( energy_dense=energy_dense, - span_original=span_original, - span_dense=span_dense, + energy_span_dense=energy_span_dense, energy_even_length_offset=energy_even_length_offset, energy_dense_centered=energy_dense_centered, - energy_step=energy_step, + energy_dense_step=energy_dense_step, ) assert np.array_equal(energy_grid.energy_dense, energy_dense) - assert energy_grid.span_original == span_original - assert energy_grid.span_dense == span_dense - assert energy_grid.energy_even_length_offset == energy_even_length_offset assert np.array_equal(energy_grid.energy_dense_centered, energy_dense_centered) - assert energy_grid.energy_step == energy_step + assert energy_grid.energy_dense_step == energy_dense_step + assert energy_grid.energy_span_dense == energy_span_dense + assert energy_grid.energy_even_length_offset == energy_even_length_offset + + # energy_dense: np.ndarray + # energy_dense_centered: np.ndarray + # energy_dense_step: float + # span_dense: float + # energy_even_length_offset: float From 6ffe598b8fb9ae8d98802c15f162a2b162278cd0 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Wed, 10 Dec 2025 09:48:47 +0100 Subject: [PATCH 54/71] Small updates --- .../convolution/numerical_convolution_base.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index e0f5178..b8ed580 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -63,17 +63,12 @@ def __init__( energy_unit=energy_unit, ) - if temperature is not None: - if isinstance(temperature, Numerical): - temperature = Parameter( - name="temperature", - value=float(temperature), - unit=temperature_unit, - fixed=True, - ) - elif not isinstance(temperature, Parameter): - raise TypeError("Temperature must be a float or Parameter.") + if temperature is not None and not isinstance(temperature, Numerical): + raise TypeError("Temperature must be None or a number.") self._temperature = temperature + + if not isinstance(temperature_unit, (str, sc.Unit)): + raise TypeError("Temperature_unit must be a string or sc.Unit.") self._temperature_unit = temperature_unit self._normalize_detailed_balance = normalize_detailed_balance From 5fda58d7c797b126d8c75296b978b640ac1a052c Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 12 Dec 2025 11:14:48 +0100 Subject: [PATCH 55/71] More tests of numerical convolution --- .../convolution/numerical_convolution_base.py | 24 +- .../test_numerical_convolution_base.py | 329 +++++++++++++++++- 2 files changed, 337 insertions(+), 16 deletions(-) diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index b8ed580..8ca24c7 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -63,13 +63,16 @@ def __init__( energy_unit=energy_unit, ) - if temperature is not None and not isinstance(temperature, Numerical): - raise TypeError("Temperature must be None or a number.") - self._temperature = temperature + if temperature is not None and not isinstance( + temperature, (Numerical, Parameter) + ): + raise TypeError("Temperature must be None, a number or a Parameter.") if not isinstance(temperature_unit, (str, sc.Unit)): raise TypeError("Temperature_unit must be a string or sc.Unit.") self._temperature_unit = temperature_unit + self._temperature = None + self.temperature = temperature self._normalize_detailed_balance = normalize_detailed_balance @@ -81,7 +84,7 @@ def __init__( @ConvolutionBase.energy.setter def energy(self, energy: np.ndarray) -> None: - super().energy = energy + ConvolutionBase.energy.fset(self, energy) # Recreate dense grid when energy is updated self._energy_grid = self._create_energy_grid() @@ -105,7 +108,7 @@ def upsample_factor(self, factor: Numerical) -> None: if not isinstance(factor, Numerical): raise TypeError("Upsample factor must be a numerical value or None.") factor = float(factor) - if factor < 1.0: + if factor <= 1.0: raise ValueError("Upsample factor must be greater than 1.") self._upsample_factor = factor @@ -211,13 +214,8 @@ def _create_energy_grid( self, ) -> EnergyGrid: """ - Create a dense grid by upsampling and extending the energy array. - # energy_dense=energy_dense, - # energy_dense_centered=energy_dense_centered, - # energy_dense_step=energy_dense_step, - # span_dense=span, - # span_original=span_original, - # energy_even_length_offset=energy_even_length_offset, + Create a dense grid by upsampling and extending the energy array. If upsample_factor is None, no upsampling or extension is performed. + This dense grid is used for convolution to improve accuracy. Returns: EnergyGrid The dense grid created by upsampling and extending energy. @@ -248,7 +246,7 @@ def _create_energy_grid( # Create an extended and upsampled energy grid energy_min, energy_max = self.energy.values.min(), self.energy.values.max() energy_span_original = energy_max - energy_min - extra = self.extension_factor * energy_span_original + extra = self.extension_factor / 2 * energy_span_original extended_min = energy_min - extra extended_max = energy_max + extra num_points = round(len(self.energy.values) * self.upsample_factor) diff --git a/tests/unit_tests/convolution/test_numerical_convolution_base.py b/tests/unit_tests/convolution/test_numerical_convolution_base.py index f0d0fef..b8c908c 100644 --- a/tests/unit_tests/convolution/test_numerical_convolution_base.py +++ b/tests/unit_tests/convolution/test_numerical_convolution_base.py @@ -1,6 +1,7 @@ import numpy as np import pytest import scipp as sc +from easyscience.variable import Parameter from easydynamics.convolution.energy_grid import EnergyGrid from easydynamics.convolution.numerical_convolution_base import ( @@ -12,7 +13,7 @@ class TestNumericalConvolutionBase: @pytest.fixture def default_numerical_convolution_base(self): - energy = np.linspace(-10, 10, 100) + energy = np.linspace(-10, 10, 101) sample_model = SampleModel(name="SampleModel") resolution_model = SampleModel(name="ResolutionModel") @@ -23,11 +24,12 @@ def default_numerical_convolution_base(self): ) def test_init(self, default_numerical_convolution_base): + "Test initialization of NumericalConvolutionBase with default parameters." # WHEN THEN EXPECT assert isinstance(default_numerical_convolution_base, NumericalConvolutionBase) assert isinstance(default_numerical_convolution_base.energy, sc.Variable) assert np.allclose( - default_numerical_convolution_base.energy.values, np.linspace(-10, 10, 100) + default_numerical_convolution_base.energy.values, np.linspace(-10, 10, 101) ) assert isinstance(default_numerical_convolution_base._sample_model, SampleModel) assert isinstance( @@ -36,7 +38,328 @@ def test_init(self, default_numerical_convolution_base): assert default_numerical_convolution_base.upsample_factor == 5 assert default_numerical_convolution_base.extension_factor == 0.2 assert default_numerical_convolution_base.temperature is None - # assert default_numerical_convolution_base.temperature_unit == "K" assert default_numerical_convolution_base.energy_unit == "meV" assert default_numerical_convolution_base.normalize_detailed_balance is True assert isinstance(default_numerical_convolution_base._energy_grid, EnergyGrid) + + def test_init_with_custom_parameters(self): + "Test initialization of NumericalConvolutionBase with custom parameters." + # WHEN + energy = np.linspace(-5, 5, 50) + sample_model = SampleModel(name="SampleModel") + resolution_model = SampleModel(name="ResolutionModel") + upsample_factor = 10 + extension_factor = 0.5 + temperature = 300.0 + temperature_unit = "K" + energy_unit = "meV" + normalize_detailed_balance = False + + # THEN + numerical_convolution_base = NumericalConvolutionBase( + energy=energy, + sample_model=sample_model, + resolution_model=resolution_model, + upsample_factor=upsample_factor, + extension_factor=extension_factor, + temperature=temperature, + temperature_unit=temperature_unit, + energy_unit=energy_unit, + normalize_detailed_balance=normalize_detailed_balance, + ) + + # EXPECT + assert numerical_convolution_base.upsample_factor == upsample_factor + assert numerical_convolution_base.extension_factor == extension_factor + assert numerical_convolution_base.temperature.value == temperature + assert numerical_convolution_base.temperature.unit == temperature_unit + assert numerical_convolution_base.energy_unit == energy_unit + assert ( + numerical_convolution_base.normalize_detailed_balance + == normalize_detailed_balance + ) + assert isinstance(numerical_convolution_base._energy_grid, EnergyGrid) + + def test_init_raises_type_error_for_invalid_temperature(self): + "Test that initialization raises TypeError for invalid temperature." + # WHEN + energy = np.linspace(-5, 5, 50) + sample_model = SampleModel(name="SampleModel") + resolution_model = SampleModel(name="ResolutionModel") + invalid_temperature = "invalid_temperature" + + # THEN EXPECT + with pytest.raises( + TypeError, match="Temperature must be None, a number or a Parameter." + ): + NumericalConvolutionBase( + energy=energy, + sample_model=sample_model, + resolution_model=resolution_model, + temperature=invalid_temperature, + ) + + def test_init_raises_type_error_for_invalid_temperature_unit(self): + "Test that initialization raises TypeError for invalid temperature_unit." + # WHEN + energy = np.linspace(-5, 5, 50) + sample_model = SampleModel(name="SampleModel") + resolution_model = SampleModel(name="ResolutionModel") + invalid_temperature_unit = 123 # Not a string or sc.Unit + + # THEN EXPECT + with pytest.raises( + TypeError, match="Temperature_unit must be a string or sc.Unit." + ): + NumericalConvolutionBase( + energy=energy, + sample_model=sample_model, + resolution_model=resolution_model, + temperature_unit=invalid_temperature_unit, + ) + + def test_energy_setter(self, default_numerical_convolution_base): + "Test setting a new energy array updates the energy grid accordingly." + # WHEN + new_energy = np.linspace(-20, 20, 201) + default_numerical_convolution_base.energy = new_energy + + # THEN EXPECT + assert isinstance(default_numerical_convolution_base.energy, sc.Variable) + assert np.allclose(default_numerical_convolution_base.energy.values, new_energy) + assert default_numerical_convolution_base._energy_grid.energy_dense.shape[ + 0 + ] == round(201 * default_numerical_convolution_base.upsample_factor) + + def test_upsample_factor_setter(self, default_numerical_convolution_base): + "Test setting a new upsample factor updates the energy grid accordingly." + # WHEN + new_upsample_factor = 10 + default_numerical_convolution_base.upsample_factor = new_upsample_factor + + # THEN EXPECT + assert default_numerical_convolution_base.upsample_factor == new_upsample_factor + assert default_numerical_convolution_base._energy_grid.energy_dense.shape[ + 0 + ] == round(101 * new_upsample_factor) + + def test_upsample_factor_setter_none(self, default_numerical_convolution_base): + "Test setting upsample factor to None disables upsampling." + # WHEN + new_upsample_factor = None + default_numerical_convolution_base.upsample_factor = new_upsample_factor + + # THEN EXPECT + assert default_numerical_convolution_base.upsample_factor == new_upsample_factor + assert ( + default_numerical_convolution_base._energy_grid.energy_dense.shape[0] == 101 + ) + + @pytest.mark.parametrize( + "invalid_upsample_factor, expected_exception", + [ + (-1, ValueError), # numeric < 1 → ValueError + (0, ValueError), # numeric < 1 → ValueError + (1.0, ValueError), # numeric = 1 → ValueError + ("invalid", TypeError), # non-numeric → TypeError + ], + ids=["negative", "zero", "one", "string"], + ) + def test_upsample_setter_raises( + self, + default_numerical_convolution_base, + invalid_upsample_factor, + expected_exception, + ): + "Test that setting invalid upsample factors raises appropriate exceptions." + # WHEN THEN EXPECT + with pytest.raises( + expected_exception, + ): + default_numerical_convolution_base.upsample_factor = invalid_upsample_factor + + def test_extension_factor_setter(self, default_numerical_convolution_base): + "Test setting a new extension factor updates the energy grid accordingly." + # WHEN + new_extension_factor = 0.5 + default_numerical_convolution_base.extension_factor = new_extension_factor + + # THEN EXPECT + assert ( + default_numerical_convolution_base.extension_factor == new_extension_factor + ) + expected_span = 20 + 2 * (0.5 * 20) # original span + 2 * (extension) + assert np.isclose( + default_numerical_convolution_base._energy_grid.energy_span_dense, + expected_span, + ) + + @pytest.mark.parametrize( + "invalid_extension_factor, expected_exception", + [ + (-0.1, ValueError), # negative → ValueError + ("invalid", TypeError), # non-numeric → TypeError + ], + ids=["negative", "string"], + ) + def test_extension_factor_setter_raises( + self, + default_numerical_convolution_base, + invalid_extension_factor, + expected_exception, + ): + "Test that setting invalid extension factors raises appropriate exceptions." + + # WHEN THEN EXPECT + with pytest.raises( + expected_exception, + ): + default_numerical_convolution_base.extension_factor = ( + invalid_extension_factor + ) + + @pytest.mark.parametrize( + "temperature_input, expected_value", + [ + (1, 1.0), + (100.0, 100.0), + (Parameter(name="TempParam", value=250.0, unit="K"), 250.0), + ], + ids=["int", "float", "parameter"], + ) + def test_temperature_setter( + self, default_numerical_convolution_base, temperature_input, expected_value + ): + "Test setting various valid temperature inputs." + # WHEN + default_numerical_convolution_base.temperature = temperature_input + + # THEN EXPECT + assert default_numerical_convolution_base.temperature.value == expected_value + assert default_numerical_convolution_base.temperature.unit == "K" + + def test_temperature_setter_none(self, default_numerical_convolution_base): + "Test setting temperature to None." + # WHEN + default_numerical_convolution_base.temperature = None + + # THEN EXPECT + assert default_numerical_convolution_base.temperature is None + + def test_temperature_setter_raises(self, default_numerical_convolution_base): + "Test that setting an invalid temperature raises TypeError." + # WHEN THEN EXPECT + with pytest.raises(TypeError, match="Temperature must be"): + default_numerical_convolution_base.temperature = "invalid_temperature" + + def test_normalize_detailed_balance_setter( + self, default_numerical_convolution_base + ): + "Test setting normalize_detailed_balance to False." + # WHEN + default_numerical_convolution_base.normalize_detailed_balance = False + + # THEN EXPECT + assert default_numerical_convolution_base.normalize_detailed_balance is False + + def test_normalize_detailed_balance_setter_raises( + self, default_numerical_convolution_base + ): + "Test that setting an invalid normalize_detailed_balance raises TypeError." + # WHEN THEN EXPECT + with pytest.raises(TypeError, match="normalize_detailed_balance must be"): + default_numerical_convolution_base.normalize_detailed_balance = "invalid" + + def test_create_energy_grid_upsample_none(self, default_numerical_convolution_base): + "Test creating energy grid with upsample_factor set to None (no upsampling). In this case, the energy grid is equal to the input energy" + # WHEN + default_numerical_convolution_base.upsample_factor = None + energy_grid = default_numerical_convolution_base._create_energy_grid() + + # THEN EXPECT + assert isinstance(energy_grid, EnergyGrid) + assert np.allclose( + energy_grid.energy_dense, + np.linspace(-10, 10, 101), # no extension + ) + assert np.allclose(energy_grid.energy_dense_centered, np.linspace(-10, 10, 101)) + assert np.isclose(energy_grid.energy_dense_step, 0.2) + assert np.isclose(energy_grid.energy_span_dense, 20.0) + assert np.isclose(energy_grid.energy_even_length_offset, 0.0) + + def test_create_energy_grid_upsample_none_non_uniform_raises( + self, default_numerical_convolution_base + ): + "Test that creating energy grid with upsample_factor set to None and non-uniform energy raises ValueError (the energy grid must always be uniform)." + # WHEN + default_numerical_convolution_base.energy = np.array([0, 1, 3, 6, 10]) + with pytest.raises( + ValueError, + match="Input array `energy` must be uniformly spaced if upsample_factor is not given", + ): + default_numerical_convolution_base.upsample_factor = None + + @pytest.mark.parametrize("num_points", [100, 101], ids=["even", "odd"]) + def test_create_energy_grid_upsample_and_extension( + self, default_numerical_convolution_base, num_points + ): + "Test creating energy grid with upsampling and extension. TThe even_length_offset is tested for both even and odd number of input energy points." + # WHEN + default_numerical_convolution_base.energy = np.linspace(-10, 10, num_points) + + # THEN + energy_grid = default_numerical_convolution_base._create_energy_grid() + + # EXPECT + assert isinstance(energy_grid, EnergyGrid) + + expected_extended_energy = np.linspace( + -12, + 12, + round(num_points * default_numerical_convolution_base.upsample_factor), + ) + assert np.allclose(energy_grid.energy_dense, expected_extended_energy) + + expected_centered_energy = expected_extended_energy + assert np.allclose(energy_grid.energy_dense_centered, expected_centered_energy) + + expected_step = expected_extended_energy[1] - expected_extended_energy[0] + assert np.isclose(energy_grid.energy_dense_step, expected_step) + + expected_span = 24.0 # original span + extension + assert np.isclose(energy_grid.energy_span_dense, expected_span) + + if num_points % 2 == 0: + expected_offset = -expected_step / 2 + assert np.isclose(energy_grid.energy_even_length_offset, expected_offset) + else: + assert np.isclose(energy_grid.energy_even_length_offset, 0.0) + + def test_create_energy_grid_non_centered_energy( + self, default_numerical_convolution_base + ): + "Test creating energy grid when input energy is not centered around zero. The centered energy grid should be shifted accordingly." + # WHEN + default_numerical_convolution_base.energy = np.linspace(5, 25, 101) + energy_grid = default_numerical_convolution_base._create_energy_grid() + + # THEN EXPECT + assert isinstance(energy_grid, EnergyGrid) + + expected_extended_energy = np.linspace( + 3, + 27, + round(101 * default_numerical_convolution_base.upsample_factor), + ) + assert np.allclose(energy_grid.energy_dense, expected_extended_energy) + + expected_centered_energy = expected_extended_energy - 15.0 + assert np.allclose(energy_grid.energy_dense_centered, expected_centered_energy) + + expected_step = expected_extended_energy[1] - expected_extended_energy[0] + assert np.isclose(energy_grid.energy_dense_step, expected_step) + + expected_span = 24.0 # original span + extension + assert np.isclose(energy_grid.energy_span_dense, expected_span) + + assert np.isclose(energy_grid.energy_even_length_offset, 0.0) From cabd355559c6375a83298596a892b72c335c1d37 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 12 Dec 2025 11:17:25 +0100 Subject: [PATCH 56/71] fix small bug --- tests/unit_tests/convolution/test_numerical_convolution_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit_tests/convolution/test_numerical_convolution_base.py b/tests/unit_tests/convolution/test_numerical_convolution_base.py index b8c908c..bb852e0 100644 --- a/tests/unit_tests/convolution/test_numerical_convolution_base.py +++ b/tests/unit_tests/convolution/test_numerical_convolution_base.py @@ -188,7 +188,7 @@ def test_extension_factor_setter(self, default_numerical_convolution_base): assert ( default_numerical_convolution_base.extension_factor == new_extension_factor ) - expected_span = 20 + 2 * (0.5 * 20) # original span + 2 * (extension) + expected_span = 20 + (0.5 * 20) # original span + extension assert np.isclose( default_numerical_convolution_base._energy_grid.energy_span_dense, expected_span, From fe293bc3421265bdab90ce778e0ab069024a6872 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 12 Dec 2025 11:47:50 +0100 Subject: [PATCH 57/71] 100% coverage of numerical convolution? --- .../convolution/numerical_convolution_base.py | 23 +++-- .../test_numerical_convolution_base.py | 83 ++++++++++++++++++- 2 files changed, 93 insertions(+), 13 deletions(-) diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index 8ca24c7..a1b7159 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -286,7 +286,7 @@ def _create_energy_grid( def _check_width_thresholds( self, - model: Union[SampleModel, ModelComponent], + model: SampleModel | ModelComponent, model_name: str, ) -> None: """ @@ -295,10 +295,6 @@ def _check_width_thresholds( Args: model : SampleModel or ModelComponent The model to check. - energy_step : float - The bin spacing of the energy array. - span : float - The total span of the energy array. model_name : str A string indicating whether the model is a 'sample model' or 'resolution model' for warning messages. returns: @@ -323,32 +319,35 @@ def _check_width_thresholds( if hasattr(comp, "width"): if ( comp.width.value - > LARGE_WIDTH_THRESHOLD * self._energy_grid.span_dense + > LARGE_WIDTH_THRESHOLD * self._energy_grid.energy_span_dense ): warnings.warn( f"The width of the {model_name} component '{comp.name}' ({comp.width.value}) is large compared to the span of the input " - f"array ({self._energy_grid.span_dense}). This may lead to inaccuracies in the convolution. Increase extension_factor to improve accuracy.", + f"array ({self._energy_grid.energy_span_dense}). This may lead to inaccuracies in the convolution. Increase extension_factor to improve accuracy.", UserWarning, ) if ( comp.width.value - < SMALL_WIDTH_THRESHOLD * self._energy_grid.energy_step + < SMALL_WIDTH_THRESHOLD * self._energy_grid.energy_dense_step ): warnings.warn( f"The width of the {model_name} component '{comp.name}' ({comp.width.value}) is small compared to the spacing of the input " - f"array ({self._energy_grid.energy_step}). This may lead to inaccuracies in the convolution. Increase upsample_factor to improve accuracy.", + f"array ({self._energy_grid.energy_dense_step}). This may lead to inaccuracies in the convolution. Increase upsample_factor to improve accuracy.", UserWarning, ) def __repr__(self) -> str: return ( f"{self.__class__.__name__}(" - f"energy=array of shape {self.energy.values.shape}, " - f"sample_model={self.sample_model}, " - f"resolution_model={self.resolution_model}, " + f"energy=array of shape {self.energy.values.shape},\n " + f"sample_model={repr(self.sample_model)}, \n" + f"resolution_model={repr(self.resolution_model)},\n " f"energy_unit={self._energy_unit}, " f"upsample_factor={self.upsample_factor}, " f"extension_factor={self.extension_factor}, " f"temperature={self.temperature}, " f"normalize_detailed_balance={self.normalize_detailed_balance})" ) + + def __str__(self) -> str: + return self.__repr__() diff --git a/tests/unit_tests/convolution/test_numerical_convolution_base.py b/tests/unit_tests/convolution/test_numerical_convolution_base.py index bb852e0..71ec13a 100644 --- a/tests/unit_tests/convolution/test_numerical_convolution_base.py +++ b/tests/unit_tests/convolution/test_numerical_convolution_base.py @@ -7,7 +7,7 @@ from easydynamics.convolution.numerical_convolution_base import ( NumericalConvolutionBase, ) -from easydynamics.sample_model import SampleModel +from easydynamics.sample_model import Gaussian, SampleModel class TestNumericalConvolutionBase: @@ -246,6 +246,21 @@ def test_temperature_setter_none(self, default_numerical_convolution_base): # THEN EXPECT assert default_numerical_convolution_base.temperature is None + def test_temperature_setter_does_not_replace_parameter( + self, default_numerical_convolution_base + ): + "Test that if setting the temperature to a value when it already exists does not create a new Parameter" + # WHEN + temp_param = Parameter(name="TempParam", value=300.0, unit="K") + default_numerical_convolution_base.temperature = temp_param + + # THEN + default_numerical_convolution_base.temperature = 350.0 + + # EXPECT + assert default_numerical_convolution_base.temperature is temp_param + assert default_numerical_convolution_base.temperature.value == 350.0 + def test_temperature_setter_raises(self, default_numerical_convolution_base): "Test that setting an invalid temperature raises TypeError." # WHEN THEN EXPECT @@ -363,3 +378,69 @@ def test_create_energy_grid_non_centered_energy( assert np.isclose(energy_grid.energy_span_dense, expected_span) assert np.isclose(energy_grid.energy_even_length_offset, 0.0) + + def test_check_width_large_threshold(self, default_numerical_convolution_base): + "Test that _check_width_thresholds warns when model widths are too large compared to energy grid span." + # WHEN + wide_gaussian = Gaussian(name="SampleModel", area=1.0, center=0.0, width=15.0) + + # THEN EXPECT + with pytest.warns( + UserWarning, + match="Increase extension_factor to improve", + ): + default_numerical_convolution_base._check_width_thresholds( + model=wide_gaussian, + model_name="SampleModel", + ) + + def test_check_width_small_threshold(self, default_numerical_convolution_base): + "Test that _check_width_thresholds warns when model widths are too small compared to energy grid step." + # WHEN + narrow_gaussian = Gaussian(name="SampleModel", area=1.0, center=0.0, width=0.01) + + # THEN EXPECT + with pytest.warns( + UserWarning, + match="Increase upsample_factor to improve", + ): + default_numerical_convolution_base._check_width_thresholds( + model=narrow_gaussian, + model_name="SampleModel", + ) + + def test_check_width_no_warnings(self, default_numerical_convolution_base): + "Test that _check_width_thresholds does not warn when model widths are within acceptable range. Also tests that SampleModel components are checked correctly." + # WHEN + good_gaussian = Gaussian(name="SampleModel", area=1.0, center=0.0, width=1.0) + sample_model = SampleModel(name="SampleModel") + sample_model.add_component(good_gaussian) + + # THEN EXPECT + default_numerical_convolution_base._check_width_thresholds( + model=sample_model, + model_name="SampleModel", + ) + + def test_repr(self, default_numerical_convolution_base): + "Test the __repr__ method of NumericalConvolutionBase." + # WHEN + repr_str = repr(default_numerical_convolution_base) + + # THEN EXPECT + assert "NumericalConvolutionBase(" in repr_str + assert "energy=array of shape" in repr_str + assert "(101," in repr_str # correct shape + + # Sample and resolution models + assert "SampleModel" in repr_str + assert "Components: No components" in repr_str + assert "sample_model=" in repr_str + assert "resolution_model=" in repr_str + + # Important parameters + assert "energy_unit=meV" in repr_str + assert "upsample_factor=5" in repr_str + assert "extension_factor=0.2" in repr_str + assert "temperature=None" in repr_str + assert "normalize_detailed_balance=True" in repr_str From c2aa0485ef035482a27fce241185aca73d4b3d79 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 12 Dec 2025 11:54:21 +0100 Subject: [PATCH 58/71] 100%! --- src/easydynamics/convolution/numerical_convolution_base.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index a1b7159..77c25c1 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -348,6 +348,3 @@ def __repr__(self) -> str: f"temperature={self.temperature}, " f"normalize_detailed_balance={self.normalize_detailed_balance})" ) - - def __str__(self) -> str: - return self.__repr__() From 2a7e80479b7146b0ff7418b22ac656f0960547fd Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Fri, 12 Dec 2025 20:32:46 +0100 Subject: [PATCH 59/71] Test numerical convolution --- examples/convolution.ipynb | 3 +- .../convolution/numerical_convolution.py | 13 +-- .../convolution/numerical_convolution_base.py | 18 ++-- .../convolution/test_numerical_convolution.py | 102 ++++++++++++++++++ 4 files changed, 114 insertions(+), 22 deletions(-) diff --git a/examples/convolution.ipynb b/examples/convolution.ipynb index 0911d2e..92c386d 100644 --- a/examples/convolution.ipynb +++ b/examples/convolution.ipynb @@ -13,7 +13,8 @@ "from easydynamics.convolution import Convolution \n", "from easydynamics.utils import _detailed_balance_factor as detailed_balance_factor\n", "\n", - "import matplotlib.pyplot as plt" + "import matplotlib.pyplot as plt\n", + "%matplotlib widget\n" ] }, { diff --git a/src/easydynamics/convolution/numerical_convolution.py b/src/easydynamics/convolution/numerical_convolution.py index 56b3ba0..3ff5137 100644 --- a/src/easydynamics/convolution/numerical_convolution.py +++ b/src/easydynamics/convolution/numerical_convolution.py @@ -113,7 +113,7 @@ def convolution( # Convolution convolved = fftconvolve(sample_vals, resolution_vals, mode="same") - convolved *= self._energy_grid.energy_step # normalize + convolved *= self._energy_grid.energy_dense_step # normalize if self.upsample_factor is not None: # interpolate back to original energy grid @@ -126,14 +126,3 @@ def convolution( ) return convolved - - def __repr__(self) -> str: - """String representation of the NumericalConvolution instance.""" - - return ( - f"NumericalConvolution(energy_unit={self._energy_unit}, " - f"extension_factor={self.extension_factor}, " - f"temperature={self.temperature}, " - f"temperature_unit={self.temperature_unit}, " - f"normalize_detailed_balance={self.normalize_detailed_balance})" - ) diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index 77c25c1..a57eec5 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -46,15 +46,15 @@ class NumericalConvolutionBase(ConvolutionBase): def __init__( self, - energy: Union[np.ndarray, sc.Variable], - sample_model: Union[SampleModel, ModelComponent], - resolution_model: Union[SampleModel, ModelComponent], - upsample_factor: Optional[Numerical] = 5, - extension_factor: Optional[float] = 0.2, - temperature: Optional[Union[Parameter, float]] = None, - temperature_unit: Optional[Union[str, sc.Unit]] = "K", - energy_unit: Optional[Union[str, sc.Unit]] = "meV", - normalize_detailed_balance: Optional[bool] = True, + energy: np.ndarray | sc.Variable, + sample_model: SampleModel | ModelComponent, + resolution_model: SampleModel | ModelComponent, + upsample_factor: Numerical = 5, + extension_factor: float = 0.2, + temperature: Parameter | float | None = None, + temperature_unit: str | sc.Unit = "K", + energy_unit: str | sc.Unit = "meV", + normalize_detailed_balance: bool = True, ): super().__init__( energy=energy, diff --git a/tests/unit_tests/convolution/test_numerical_convolution.py b/tests/unit_tests/convolution/test_numerical_convolution.py index e69de29..eb98ca8 100644 --- a/tests/unit_tests/convolution/test_numerical_convolution.py +++ b/tests/unit_tests/convolution/test_numerical_convolution.py @@ -0,0 +1,102 @@ +import numpy as np +import pytest +import scipp as sc +from scipy.signal import fftconvolve + +from easydynamics.convolution.energy_grid import EnergyGrid +from easydynamics.convolution.numerical_convolution import ( + NumericalConvolution, +) +from easydynamics.sample_model import Gaussian, SampleModel +from easydynamics.utils.detailed_balance import ( + _detailed_balance_factor as detailed_balance_factor, +) + + +class TestNumericalConvolution: + @pytest.fixture + def default_numerical_convolution(self): + energy = np.linspace(-10, 10, 5001) + sample_model = SampleModel(name="SampleModel") + sample_model.add_component( + Gaussian(name="Gaussian1", area=2.0, center=0.1, width=0.4) + ) + resolution_model = SampleModel(name="ResolutionModel") + resolution_model.add_component( + Gaussian(name="GaussianRes", area=3.0, center=0.2, width=0.5) + ) + + return NumericalConvolution( + energy=energy, + sample_model=sample_model, + resolution_model=resolution_model, + ) + + def test_init(self, default_numerical_convolution): + "Test initialization of NumericalConvolution with default parameters." + # WHEN THEN EXPECT + assert isinstance(default_numerical_convolution, NumericalConvolution) + assert isinstance(default_numerical_convolution.energy, sc.Variable) + assert np.allclose( + default_numerical_convolution.energy.values, np.linspace(-10, 10, 5001) + ) + assert isinstance(default_numerical_convolution._sample_model, SampleModel) + assert isinstance(default_numerical_convolution._resolution_model, SampleModel) + assert default_numerical_convolution.upsample_factor == 5 + assert default_numerical_convolution.extension_factor == 0.2 + assert default_numerical_convolution.temperature is None + assert default_numerical_convolution.energy_unit == "meV" + assert default_numerical_convolution.normalize_detailed_balance is True + assert isinstance(default_numerical_convolution._energy_grid, EnergyGrid) + + @pytest.mark.parametrize("upsample_factor", [None, 5]) + def test_convolution(self, default_numerical_convolution, upsample_factor): + "Test that convolution of two Gaussians produces the expected result." + # WHEN THEN + default_numerical_convolution.upsample_factor = upsample_factor + result = default_numerical_convolution.convolution() + + # EXPECT + expected_area = 2.0 * 3.0 # area of sample_model * area of resolution_model + expected_center = ( + 0.1 + 0.2 + ) # center of sample_model + center of resolution_model + expected_width = np.sqrt(0.4**2 + 0.5**2) # sqrt(width_sample^2 + width_res^2) + expected_result = Gaussian( + name="ExpectedConvolution", + area=expected_area, + center=expected_center, + width=expected_width, + ).evaluate(default_numerical_convolution.energy) + assert np.allclose(result, expected_result, rtol=1e-4) + + def test_convolution_with_temperature( + self, + default_numerical_convolution, + ): + "Test that convolution includes detailed balance correction when temperature is provided." + + # WHEN + default_numerical_convolution.temperature = 5.0 # Kelvin + + # THEN + result = default_numerical_convolution.convolution() + + # EXPECT + sample_valds = default_numerical_convolution._sample_model.evaluate( + default_numerical_convolution.energy.values + ) + resolution_vals = default_numerical_convolution._resolution_model.evaluate( + default_numerical_convolution.energy.values + ) + DBF = detailed_balance_factor( + energy=default_numerical_convolution.energy, temperature=5.0 + ) + expected_result = fftconvolve( + sample_valds * DBF, resolution_vals, mode="same" + ) * ( + default_numerical_convolution.energy.values[1] + - default_numerical_convolution.energy.values[0] + ) + + assert np.allclose(result, expected_result, rtol=1e-4) From fe841e1877d16209e9d4b720c0769c15e4e7dbaf Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Mon, 15 Dec 2025 09:37:17 +0100 Subject: [PATCH 60/71] small update --- src/easydynamics/convolution/convolution.py | 37 ++++++----- .../convolution/test_convolution.py | 62 +++++++++++++++++++ 2 files changed, 80 insertions(+), 19 deletions(-) diff --git a/src/easydynamics/convolution/convolution.py b/src/easydynamics/convolution/convolution.py index 813b4fc..52cdf0f 100644 --- a/src/easydynamics/convolution/convolution.py +++ b/src/easydynamics/convolution/convolution.py @@ -53,15 +53,15 @@ class Convolution(NumericalConvolutionBase): def __init__( self, - energy: Union[np.ndarray, sc.Variable], - sample_model: Union[SampleModel, ModelComponent], - resolution_model: Union[SampleModel, ModelComponent], - upsample_factor: Optional[Numerical] = 5, - extension_factor: Optional[float] = 0.2, - temperature: Optional[Union[Parameter, float]] = None, - temperature_unit: Optional[Union[str, sc.Unit]] = "K", - energy_unit: Optional[Union[str, sc.Unit]] = "meV", - normalize_detailed_balance: Optional[bool] = True, + energy: np.ndarray | sc.Variable, + sample_model: SampleModel | ModelComponent, + resolution_model: SampleModel | ModelComponent, + upsample_factor: Numerical = 5, + extension_factor: Numerical = 0.2, + temperature: Parameter | Numerical | None = None, + temperature_unit: str | sc.Unit = "K", + energy_unit: str | sc.Unit = "meV", + normalize_detailed_balance: bool = True, ): super().__init__( energy=energy, @@ -166,11 +166,11 @@ def _set_convolvers(self) -> None: energy=self.energy, sample_model=self._numerical_sample_model, resolution_model=self._resolution_model, - upsample_factor=self._upsample_factor, - extension_factor=self._extension_factor, - temperature=self._temperature, - temperature_unit=self._temperature_unit, - normalize_detailed_balance=self._normalize_detailed_balance, + upsample_factor=self.upsample_factor, + extension_factor=self.extension_factor, + temperature=self.temperature, + temperature_unit=self.temperature_unit, + normalize_detailed_balance=self.normalize_detailed_balance, ) else: self._numerical_convolver = None @@ -225,7 +225,7 @@ def sample_model(self, sample_model: Union[SampleModel, ModelComponent]) -> None Raises: TypeError: If sample_model is not a SampleModel or ModelComponent. """ - super(NumericalConvolutionBase).sample_model.sample_model = sample_model + NumericalConvolutionBase.sample_model.fset(self, sample_model) # Separate sample model components into pairs that can be handled analytically, delta functions, and the rest self._separate_analytical_components() @@ -242,9 +242,7 @@ def resolution_model( Raises: TypeError: If resolution_model is not a SampleModel or ModelComponent. """ - super( - NumericalConvolutionBase - ).resolution_model.resolution_model = resolution_model + NumericalConvolutionBase.resolution_model.fset(self, resolution_model) # Separate sample model components into pairs that can be handled analytically, delta functions, and the rest self._separate_analytical_components() @@ -257,7 +255,8 @@ def temperature(self, temperature: Optional[Union[Parameter, float]]) -> None: temperature : Parameter, float, or None The temperature to use for detailed balance correction. """ - super(NumericalConvolutionBase).temperature = temperature + # super(NumericalConvolutionBase).temperature = temperature + NumericalConvolutionBase.temperature.fset(self, temperature) # Separate sample model components into pairs that can be handled analytically, delta functions, and the rest self._separate_analytical_components() diff --git a/tests/unit_tests/convolution/test_convolution.py b/tests/unit_tests/convolution/test_convolution.py index e69de29..976d595 100644 --- a/tests/unit_tests/convolution/test_convolution.py +++ b/tests/unit_tests/convolution/test_convolution.py @@ -0,0 +1,62 @@ +import numpy as np +import pytest +import scipp as sc + +from easydynamics.convolution.convolution import ( + Convolution, +) +from easydynamics.convolution.energy_grid import EnergyGrid +from easydynamics.sample_model import ( + DampedHarmonicOscillator, + DeltaFunction, + Gaussian, + SampleModel, +) + + +class TestConvolution: + @pytest.fixture + def default_convolution(self): + energy = np.linspace(-10, 10, 5001) + sample_model = SampleModel(name="SampleModel") + sample_model.add_component( + Gaussian(name="Gaussian1", area=2.0, center=0.1, width=0.4) + ) + sample_model.add_component( + DampedHarmonicOscillator(name="DHO1", area=2.0, center=1.0, width=0.1) + ) + sample_model.add_component(DeltaFunction(name="Delta1", area=2.0, center=0.3)) + + resolution_model = SampleModel(name="ResolutionModel") + resolution_model.add_component( + Gaussian(name="GaussianRes", area=3.0, center=0.2, width=0.5) + ) + + return Convolution( + energy=energy, + sample_model=sample_model, + resolution_model=resolution_model, + ) + + def test_init(self, default_convolution): + "Test initialization of Convolution with default parameters." + # WHEN THEN EXPECT + assert isinstance(default_convolution, Convolution) + assert isinstance(default_convolution.energy, sc.Variable) + assert np.allclose( + default_convolution.energy.values, np.linspace(-10, 10, 5001) + ) + assert isinstance(default_convolution._sample_model, SampleModel) + assert isinstance(default_convolution._resolution_model, SampleModel) + assert default_convolution.upsample_factor == 5 + assert default_convolution.extension_factor == 0.2 + assert default_convolution.temperature is None + assert default_convolution.energy_unit == "meV" + assert default_convolution.normalize_detailed_balance is True + assert isinstance(default_convolution._energy_grid, EnergyGrid) + + assert isinstance(default_convolution._analytical_sample_model, SampleModel) + assert ( + default_convolution._analytical_sample_model.components + is default_convolution.sample_model.components[2] + ) From 180c382e2a9688e77de8b4038fc60e691d59e506 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Mon, 15 Dec 2025 10:23:32 +0100 Subject: [PATCH 61/71] Make convolution plan logic more robust --- examples/convolution.ipynb | 19 ++- src/easydynamics/convolution/convolution.py | 137 ++++++++---------- .../convolution/test_convolution.py | 4 +- 3 files changed, 79 insertions(+), 81 deletions(-) diff --git a/examples/convolution.ipynb b/examples/convolution.ipynb index 92c386d..2d7cac6 100644 --- a/examples/convolution.ipynb +++ b/examples/convolution.ipynb @@ -45,6 +45,7 @@ "\n", "convolver = Convolution(sample_model=sample_model, resolution_model=resolution_model, energy=energy)\n", "y = convolver.convolution()\n", + "plt.figure()\n", "plt.plot(energy, y, label='Convoluted Model')\n", "plt.xlabel('Energy (meV)')\n", "plt.ylabel('Intensity (arb. units)')\n", @@ -56,7 +57,18 @@ "\n", "plt.legend()\n", "# set the limit on the y axis\n", - "plt.ylim(0,6)" + "plt.ylim(0,6)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7d49acae", + "metadata": {}, + "outputs": [], + "source": [ + "convolver.upsample_factor" ] }, { @@ -90,7 +102,7 @@ "offset = 0.5\n", "upsample_factor = 5\n", "extension_factor = 0.5\n", - "\n", + "plt.figure()\n", "plt.xlabel('Energy (meV)')\n", "plt.ylabel('Intensity (arb. units)')\n", "\n", @@ -113,7 +125,8 @@ "plt.title('Convolution of Sample Model with Resolution Model with detailed balancing')\n", "\n", "plt.legend()\n", - "plt.ylim(0,2.5)\n" + "plt.ylim(0,2.5)\n", + "plt.show()\n" ] } ], diff --git a/src/easydynamics/convolution/convolution.py b/src/easydynamics/convolution/convolution.py index 52cdf0f..b07bec7 100644 --- a/src/easydynamics/convolution/convolution.py +++ b/src/easydynamics/convolution/convolution.py @@ -1,4 +1,4 @@ -from typing import Optional, Union +from typing import Union import numpy as np import scipp as sc @@ -51,6 +51,20 @@ class Convolution(NumericalConvolutionBase): Whether to normalize the detailed balance correction. Default is True. """ + # When these attributes are changed, the convolution plan needs to be rebuilt + _invalidate_plan_on_change = { + "energy", + "_energy", + "_energy_grid", + "_sample_model", + "_resolution_model", + "_temperature", + "_upsample_factor", + "_extension_factor", + "_energy_unit", + "_normalize_detailed_balance", + } + def __init__( self, energy: np.ndarray | sc.Variable, @@ -63,6 +77,8 @@ def __init__( energy_unit: str | sc.Unit = "meV", normalize_detailed_balance: bool = True, ): + self._convolution_plan_is_valid = False + self._reactions_enabled = False super().__init__( energy=energy, sample_model=sample_model, @@ -75,9 +91,10 @@ def __init__( normalize_detailed_balance=normalize_detailed_balance, ) + self._reactions_enabled = True # Separate sample model components into pairs that can be handled analytically, delta functions, and the rest # Also initialize analytical and numerical convolvers based on sample model component - self._separate_analytical_components() + self._build_convolution_plan() def convolution( self, @@ -88,7 +105,8 @@ def convolution( np.ndarray The convolved values evaluated at energy. """ - + if not self._convolution_plan_is_valid: + self._build_convolution_plan() total = np.zeros_like(self.energy.values, dtype=float) # Analytical convolution @@ -149,34 +167,8 @@ def _check_if_pair_is_analytic( return False - def _set_convolvers(self) -> None: - """Initialize analytical and numerical convolvers based on sample model components.""" - - if self._analytical_sample_model.components: - self._analytical_convolver = AnalyticalConvolution( - energy=self.energy, - sample_model=self._analytical_sample_model, - resolution_model=self._resolution_model, - ) - else: - self._analytical_convolver = None - - if self._numerical_sample_model.components: - self._numerical_convolver = NumericalConvolution( - energy=self.energy, - sample_model=self._numerical_sample_model, - resolution_model=self._resolution_model, - upsample_factor=self.upsample_factor, - extension_factor=self.extension_factor, - temperature=self.temperature, - temperature_unit=self.temperature_unit, - normalize_detailed_balance=self.normalize_detailed_balance, - ) - else: - self._numerical_convolver = None - - def _separate_analytical_components(self) -> None: - """ " Separate sample model components into analytical pairs, delta functions, and the rest.""" + def _build_convolution_plan(self) -> None: + """Separate sample model components into analytical pairs, delta functions, and the rest.""" analytical_sample_model = SampleModel() delta_sample_model = SampleModel() @@ -193,6 +185,7 @@ def _separate_analytical_components(self) -> None: numerical_sample_model.add_component(sample_component) continue + # If temperature is not set, check if all resolution components can be convolved analytically with this sample component pair_is_analytic = [] for resolution_component in self._resolution_model.components: pair_is_analytic.append( @@ -200,7 +193,7 @@ def _separate_analytical_components(self) -> None: sample_component, resolution_component ) ) - # If all resolution components can be convolved analytically with this sample component, add it to analytical sample model + # If all resolution components can be convolved analytically with this sample component, add it to analytical sample model. If not, it goes to numerical sample model. if all(pair_is_analytic): analytical_sample_model.add_component(sample_component) else: @@ -209,54 +202,46 @@ def _separate_analytical_components(self) -> None: self._analytical_sample_model = analytical_sample_model self._delta_sample_model = delta_sample_model self._numerical_sample_model = numerical_sample_model + self._convolution_plan_is_valid = True # Update convolvers self._set_convolvers() - # Update some setters so the internal sample models are updated accordingly - @NumericalConvolutionBase.sample_model.setter - def sample_model(self, sample_model: Union[SampleModel, ModelComponent]) -> None: - """Set the sample model and update internal sample models accordingly. - - Args: - sample_model : SampleModel or ModelComponent - The sample model to be convolved. - - Raises: - TypeError: If sample_model is not a SampleModel or ModelComponent. - """ - NumericalConvolutionBase.sample_model.fset(self, sample_model) - - # Separate sample model components into pairs that can be handled analytically, delta functions, and the rest - self._separate_analytical_components() - - @NumericalConvolutionBase.resolution_model.setter - def resolution_model( - self, resolution_model: Union[SampleModel, ModelComponent] - ) -> None: - """Set the resolution model and update internal sample models accordingly. - - Args: - resolution_model : SampleModel or ModelComponent - The resolution model to convolve with. - Raises: - TypeError: If resolution_model is not a SampleModel or ModelComponent. - """ - NumericalConvolutionBase.resolution_model.fset(self, resolution_model) - - # Separate sample model components into pairs that can be handled analytically, delta functions, and the rest - self._separate_analytical_components() + def _set_convolvers(self) -> None: + """Initialize analytical and numerical convolvers based on sample model components. + There is no delta function convolver, as delta functions are handled directly in the convolution method.""" - @NumericalConvolutionBase.temperature.setter - def temperature(self, temperature: Optional[Union[Parameter, float]]) -> None: - """Set the temperature and update internal sample models accordingly. + if self._analytical_sample_model.components: + self._analytical_convolver = AnalyticalConvolution( + energy=self.energy, + sample_model=self._analytical_sample_model, + resolution_model=self._resolution_model, + ) + else: + self._analytical_convolver = None - Args: - temperature : Parameter, float, or None - The temperature to use for detailed balance correction. - """ - # super(NumericalConvolutionBase).temperature = temperature - NumericalConvolutionBase.temperature.fset(self, temperature) + if self._numerical_sample_model.components: + self._numerical_convolver = NumericalConvolution( + energy=self.energy, + sample_model=self._numerical_sample_model, + resolution_model=self._resolution_model, + upsample_factor=self.upsample_factor, + extension_factor=self.extension_factor, + temperature=self.temperature, + temperature_unit=self._temperature_unit, + normalize_detailed_balance=self.normalize_detailed_balance, + ) + else: + self._numerical_convolver = None - # Separate sample model components into pairs that can be handled analytically, delta functions, and the rest - self._separate_analytical_components() + # Update some setters so the internal sample models are updated accordingly + def __setattr__(self, name, value): + """Custom setattr to invalidate convolution plan on relevant attribute changes. + This only happens after initialization (when _reactions_enabled is True) to avoid issues during __init__.""" + super().__setattr__(name, value) + + if ( + getattr(self, "_reactions_enabled", False) + and name in self._invalidate_plan_on_change + ): + super().__setattr__("_convolution_plan_is_valid", False) diff --git a/tests/unit_tests/convolution/test_convolution.py b/tests/unit_tests/convolution/test_convolution.py index 976d595..b02498a 100644 --- a/tests/unit_tests/convolution/test_convolution.py +++ b/tests/unit_tests/convolution/test_convolution.py @@ -57,6 +57,6 @@ def test_init(self, default_convolution): assert isinstance(default_convolution._analytical_sample_model, SampleModel) assert ( - default_convolution._analytical_sample_model.components - is default_convolution.sample_model.components[2] + default_convolution._analytical_sample_model.components[0] + is default_convolution.sample_model.components[0] ) From 2fdea2bbcad379cd3a3d8385fdfab4318cd2697a Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Mon, 15 Dec 2025 10:36:57 +0100 Subject: [PATCH 62/71] update init test of convolution --- .../convolution/test_convolution.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/unit_tests/convolution/test_convolution.py b/tests/unit_tests/convolution/test_convolution.py index b02498a..92c6518 100644 --- a/tests/unit_tests/convolution/test_convolution.py +++ b/tests/unit_tests/convolution/test_convolution.py @@ -19,12 +19,15 @@ class TestConvolution: def default_convolution(self): energy = np.linspace(-10, 10, 5001) sample_model = SampleModel(name="SampleModel") + sample_model.add_component( Gaussian(name="Gaussian1", area=2.0, center=0.1, width=0.4) ) + sample_model.add_component( DampedHarmonicOscillator(name="DHO1", area=2.0, center=1.0, width=0.1) ) + sample_model.add_component(DeltaFunction(name="Delta1", area=2.0, center=0.3)) resolution_model = SampleModel(name="ResolutionModel") @@ -60,3 +63,26 @@ def test_init(self, default_convolution): default_convolution._analytical_sample_model.components[0] is default_convolution.sample_model.components[0] ) + assert isinstance(default_convolution._numerical_sample_model, SampleModel) + assert ( + default_convolution._numerical_sample_model.components[0] + is default_convolution.sample_model.components[1] + ) + + assert isinstance(default_convolution._delta_sample_model, SampleModel) + assert ( + default_convolution._delta_sample_model.components[0] + is default_convolution.sample_model.components[2] + ) + assert default_convolution._convolution_plan_is_valid is True + assert default_convolution._reactions_enabled is True + + def test_plan_is_built_when_invalid(mocker, default_convolution): + conv = default_convolution + conv._convolution_plan_is_valid = False + + build_plan = mocker.spy(conv, "_build_convolution_plan") + + conv.convolution() + + build_plan.assert_called_once() From fc8da9d7980815642de5a08c505a3dad0db713ee Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Mon, 15 Dec 2025 14:28:29 +0100 Subject: [PATCH 63/71] More tests --- src/easydynamics/convolution/convolution.py | 25 +- .../convolution/test_convolution.py | 268 +++++++++++++++++- 2 files changed, 279 insertions(+), 14 deletions(-) diff --git a/src/easydynamics/convolution/convolution.py b/src/easydynamics/convolution/convolution.py index b07bec7..6a6e214 100644 --- a/src/easydynamics/convolution/convolution.py +++ b/src/easydynamics/convolution/convolution.py @@ -117,15 +117,21 @@ def convolution( if self._numerical_convolver is not None: total += self._numerical_convolver.convolution() - # Delta function components (no convolution needed, and no detailed balancing) + # Delta function components if self._delta_sample_model.components: - for sample_component in self._delta_sample_model.components: - total += sample_component.area.value * self._resolution_model.evaluate( - self.energy.values - sample_component.center.value - ) + total += self._convolve_delta_functions() return total + def _convolve_delta_functions(self) -> np.ndarray: + "Convolve delta function components of the sample model with the resolution model." + "No detailed balance correction is applied to delta functions." + return sum( + delta.area.value + * self._resolution_model.evaluate(self.energy.values - delta.center.value) + for delta in self._delta_sample_model.components + ) + def _check_if_pair_is_analytic( self, sample_component: ModelComponent, @@ -146,16 +152,16 @@ def _check_if_pair_is_analytic( if not isinstance(sample_component, ModelComponent): raise TypeError( - f"`sample_component` is an instance of {type(sample_component).__name__}, but must be ModelComponent." + f"`sample_component` is an instance of {type(sample_component).__name__}, but must be a ModelComponent." ) if not isinstance(resolution_component, ModelComponent): raise TypeError( - f"`resolution_component` is an instance of {type(resolution_component).__name__}, but must be ModelComponent." + f"`resolution_component` is an instance of {type(resolution_component).__name__}, but must be a ModelComponent." ) if isinstance(resolution_component, DeltaFunction): - raise ValueError( + raise TypeError( "Resolution model contains delta functions. This is not supported." ) @@ -244,4 +250,5 @@ def __setattr__(self, name, value): getattr(self, "_reactions_enabled", False) and name in self._invalidate_plan_on_change ): - super().__setattr__("_convolution_plan_is_valid", False) + # super().__setattr__("_convolution_plan_is_valid", False) + self._build_convolution_plan() diff --git a/tests/unit_tests/convolution/test_convolution.py b/tests/unit_tests/convolution/test_convolution.py index 92c6518..ce3ba97 100644 --- a/tests/unit_tests/convolution/test_convolution.py +++ b/tests/unit_tests/convolution/test_convolution.py @@ -1,3 +1,6 @@ +from contextlib import nullcontext +from unittest.mock import patch + import numpy as np import pytest import scipp as sc @@ -10,7 +13,10 @@ DampedHarmonicOscillator, DeltaFunction, Gaussian, + Lorentzian, + Polynomial, SampleModel, + Voigt, ) @@ -35,11 +41,12 @@ def default_convolution(self): Gaussian(name="GaussianRes", area=3.0, center=0.2, width=0.5) ) - return Convolution( + conv = Convolution( energy=energy, sample_model=sample_model, resolution_model=resolution_model, ) + return conv def test_init(self, default_convolution): "Test initialization of Convolution with default parameters." @@ -77,12 +84,263 @@ def test_init(self, default_convolution): assert default_convolution._convolution_plan_is_valid is True assert default_convolution._reactions_enabled is True - def test_plan_is_built_when_invalid(mocker, default_convolution): + def test_convolution_plan_is_built_when_invalid(self, default_convolution): + "Test that convolution plan is built when invalid." + # WHEN conv = default_convolution conv._convolution_plan_is_valid = False - build_plan = mocker.spy(conv, "_build_convolution_plan") + # THEN EXPECT + with patch.object(conv, "_build_convolution_plan") as build_plan: + conv.convolution() + build_plan.assert_called_once() + + def test_convolution_calls_analytical_convolver(self, default_convolution): + "Test that convolution calls analytical convolver when analytical components are present." + # WHEN + conv = default_convolution + + # THEN EXPECT + with patch.object( + conv._analytical_convolver, "convolution", return_value=np.array([1.0]) + ) as analytical_conv: + conv.convolution() + analytical_conv.assert_called_once() + + def test_convolution_calls_numerical_convolver(self, default_convolution): + "Test that convolution calls numerical convolver when numerical components are present." + # WHEN + conv = default_convolution + + # THEN EXPECT + with patch.object( + conv._numerical_convolver, "convolution", return_value=np.array([1.0]) + ) as numerical_conv: + conv.convolution() + numerical_conv.assert_called_once() + + def test_convolution_calls_convolve_delta_functions(self, default_convolution): + "Test that convolution calls _convolve_delta_functions when delta components are present." + # WHEN + conv = default_convolution + + # THEN EXPECT + with patch.object( + conv, + "_convolve_delta_functions", + return_value=np.array([1.0]), + ) as delta_eval: + conv.convolution() + delta_eval.assert_called_once() + + @pytest.mark.parametrize( + "analytical_component", + [True, False], + ids=["with_analytical", "without_analytical"], + ) + @pytest.mark.parametrize( + "numerical_component", + [True, False], + ids=["with_numerical", "without_numerical"], + ) + @pytest.mark.parametrize( + "delta_component", [True, False], ids=["with_delta", "without_delta"] + ) + def test_convolution_calls_correct_methods( + self, + default_convolution, + analytical_component, + numerical_component, + delta_component, + ): + """ + Tests that convolution calls the correct methods depending on which component types are present. + """ + + # WHEN + conv = default_convolution + sample_model = SampleModel() + + if analytical_component: + sample_model.add_component( + Gaussian(name="Gaussian", area=1.0, center=0.0, width=0.1) + ) + + if numerical_component: + sample_model.add_component( + DampedHarmonicOscillator( + name="DampedHarmonicOscillator", area=1.0, center=1.0, width=0.1 + ) + ) + + if delta_component: + sample_model.add_component( + DeltaFunction(name="DeltaFunction", area=1.0, center=0.0) + ) + + conv.sample_model = sample_model # This updates the internal sample models + + # THEN + # Mock the methods to be tested. Use nullcontext if the component type is not present. + if analytical_component: + patch_analytical = patch.object( + conv._analytical_convolver, "convolution", return_value=np.array([1.0]) + ) + else: + patch_analytical = nullcontext() + + if numerical_component: + patch_numerical = patch.object( + conv._numerical_convolver, "convolution", return_value=np.array([1.0]) + ) + else: + patch_numerical = nullcontext() + + patch_delta = patch.object( + conv, + "_convolve_delta_functions", + return_value=np.array([1.0]), + ) + + # EXPECT + # Each method is called only if the corresponding component type is present. + with ( + patch_analytical as mock_analytical_method, + patch_numerical as mock_numerical_method, + patch_delta as mock_delta_method, + ): + conv._convolution_plan_is_valid = True + conv.convolution() + + if analytical_component: + mock_analytical_method.assert_called_once() + else: + assert conv._analytical_convolver is None + + if numerical_component: + mock_numerical_method.assert_called_once() + else: + assert conv._numerical_convolver is None + + if delta_component: + mock_delta_method.assert_called_once() + else: + mock_delta_method.assert_not_called() + + def test_convolve_delta_functions(self, default_convolution): + "Test that _convolve_delta_functions returns expected values." + # WHEN + conv = default_convolution + + # THEN + result = conv._convolve_delta_functions() + + # EXPECT + expected_area = 2.0 * 3.0 # Delta area * Resolution area + expected_center = 0.3 + 0.2 # Delta center + Resolution center + expected_width = 0.5 # Resolution width + expected_values = Gaussian( + name="ExpectedGaussian", + area=expected_area, + center=expected_center, + width=expected_width, + ).evaluate(conv.energy.values) + + assert np.allclose(result, expected_values) + + # List of analytic functions + analytic_functions = [ + Gaussian(name="G", area=1.0, center=0.0, width=0.1), + Lorentzian(name="L", area=1.0, center=0.0, width=0.1), + Voigt(name="V", area=1.0, center=0.0, gaussian_width=0.1, lorentzian_width=0.1), + ] + + # List of non-analytic functions + non_analytic_functions = [ + DampedHarmonicOscillator(name="DHO", area=1.0, center=1.0, width=0.1), + Polynomial(name="P", coefficients=[1.0, 0.0, 0.0]), + ] + + all_functions_except_delta = analytic_functions + non_analytic_functions + all_functions = all_functions_except_delta + [ + DeltaFunction(name="Delta", area=1.0, center=0.0) + ] + + @pytest.mark.parametrize( + "function1", all_functions, ids=lambda f: f.__class__.__name__ + ) + @pytest.mark.parametrize( + "function2", all_functions_except_delta, ids=lambda f: f.__class__.__name__ + ) + def test_check_if_pair_is_analytic(self, default_convolution, function1, function2): + """ + Test _check_if_pair_is_analytic for all combinations. + Analytic functions combined → True, otherwise False. + """ + # WHEN + conv = default_convolution + + # THEN + # skip delta function in resolution + result = conv._check_if_pair_is_analytic( + sample_component=function1, resolution_component=function2 + ) + + # EXPECT + # Determine expected result + is_analytic1 = isinstance(function1, (Gaussian, Lorentzian, Voigt)) + is_analytic2 = isinstance(function2, (Gaussian, Lorentzian, Voigt)) + expected = is_analytic1 and is_analytic2 + assert result == expected + + def test_check_if_pair_is_analytic_raises_with_delta_in_resolution( + self, default_convolution + ): + """ + Test that _check_if_pair_is_analytic raises TypeError when resolution component is DeltaFunction. + """ + # WHEN + conv = default_convolution + sample_component = Gaussian(name="G", area=1.0, center=0.0, width=0.1) + resolution_component = DeltaFunction(name="Delta", area=1.0, center=0.0) + + # THEN EXPECT + with pytest.raises( + TypeError, + match="This is not supported", + ): + conv._check_if_pair_is_analytic( + sample_component=sample_component, + resolution_component=resolution_component, + ) + + @pytest.mark.parametrize( + "sample_component,resolution_component", + [ + ("NotAModelComponent", Gaussian(name="G", area=1.0, center=0.0, width=0.1)), + (Gaussian(name="G", area=1.0, center=0.0, width=0.1), "NotAModelComponent"), + ], + ids=["invalid_sample_component", "invalid_resolution_component"], + ) + def test_check_if_pair_is_analytic_raises_with_invalid_types( + self, default_convolution, sample_component, resolution_component + ): + """ + Test that _check_if_pair_is_analytic raises TypeError when given invalid component types. + """ + # WHEN + conv = default_convolution + + # THEN EXPECT + with pytest.raises( + TypeError, + match="must be a ModelComponent", + ): + conv._check_if_pair_is_analytic( + sample_component=sample_component, + resolution_component=resolution_component, + ) - conv.convolution() + # def test_build_convolution_plan(self, default_convolution): - build_plan.assert_called_once() + # def test_set_convolvers(self, default_convolution): From 84717dc65289396531f0b18c0dbd5eef1aa6d328 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Mon, 15 Dec 2025 14:29:35 +0100 Subject: [PATCH 64/71] remove outdated test --- .../convolution/test_convolution_old.py | 852 ------------------ 1 file changed, 852 deletions(-) delete mode 100644 tests/unit_tests/convolution/test_convolution_old.py diff --git a/tests/unit_tests/convolution/test_convolution_old.py b/tests/unit_tests/convolution/test_convolution_old.py deleted file mode 100644 index 98fc51e..0000000 --- a/tests/unit_tests/convolution/test_convolution_old.py +++ /dev/null @@ -1,852 +0,0 @@ -# import numpy as np -# import pytest -# from easyscience.variable import Parameter -# from scipy.signal import fftconvolve -# from scipy.special import voigt_profile - -# from easydynamics.convolution import convolution -# from easydynamics.sample_model import ( -# DampedHarmonicOscillator, -# DeltaFunction, -# Gaussian, -# Lorentzian, -# SampleModel, -# ) -# from easydynamics.utils.detailed_balance import ( -# _detailed_balance_factor as detailed_balance_factor, -# ) - -# # Numerical convolutions are not very accurate -# NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE = 1e-6 -# NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE = 1e-5 - - -# class TestConvolution: -# @pytest.fixture -# def sample_model(self): -# test_sample_model = SampleModel(name="TestSampleModel") -# test_sample_model.add_component(Gaussian(center=0.1, width=0.3, area=2.0)) -# return test_sample_model - -# @pytest.fixture -# def resolution_model(self): -# test_resolution_model = SampleModel(name="TestResolutionModel") -# test_resolution_model.add_component(Gaussian(center=0.2, width=0.4, area=3.0)) -# return test_resolution_model - -# @pytest.fixture -# def gaussian_component(self): -# return Gaussian(center=0.1, width=0.3, area=2.0) - -# @pytest.fixture -# def other_gaussian_component(self): -# return Gaussian(name="other Gaussian", center=0.2, width=0.4, area=3.0) - -# @pytest.fixture -# def lorentzian_component(self): -# return Lorentzian(center=0.1, width=0.3, area=2.0) - -# @pytest.fixture -# def other_lorentzian_component(self): -# return Lorentzian(center=0.2, width=0.4, area=3.0) - -# @pytest.fixture -# def energy(self): -# return np.linspace(-50, 50, 50001) - -# # Test convolution of components -# @pytest.mark.parametrize( -# "offset_obj, expected_shift", -# [ -# (None, 0.0), -# (0.4, 0.4), -# (Parameter("off", 0.4), 0.4), -# ], -# ids=["none", "float", "parameter"], -# ) -# @pytest.mark.parametrize( -# "method", ["analytical", "numerical"], ids=["analytical", "numerical"] -# ) -# def test_components_gauss_gauss( -# self, -# energy, -# gaussian_component, -# other_gaussian_component, -# offset_obj, -# expected_shift, -# method, -# ): -# "Test convolution of Gaussian sample and Gaussian resolution components without SampleModel." -# "Test with different offset types and methods." -# # WHEN -# sample_gauss = gaussian_component -# resolution_gauss = other_gaussian_component - -# # THEN -# calculated_convolution = convolution( -# energy=energy, -# sample_model=sample_gauss, -# resolution_model=resolution_gauss, -# offset=offset_obj, -# method=method, -# ) - -# # EXPECT -# # Convolution of two Gaussians is another Gaussian with width = sqrt(w1^2 + w2^2) -# expected_width = np.sqrt( -# sample_gauss.width.value**2 + resolution_gauss.width.value**2 -# ) -# expected_area = sample_gauss.area.value * resolution_gauss.area.value -# expected_center = ( -# sample_gauss.center.value + resolution_gauss.center.value + expected_shift -# ) -# expected_result = ( -# expected_area -# * np.exp(-0.5 * ((energy - expected_center) / expected_width) ** 2) -# / (np.sqrt(2 * np.pi) * expected_width) -# ) - -# np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) - -# @pytest.mark.parametrize( -# "offset_obj, expected_shift", -# [ -# (None, 0.0), -# (0.4, 0.4), -# (Parameter("off", 0.4), 0.4), -# ], -# ids=["none", "float", "parameter"], -# ) -# @pytest.mark.parametrize("method", ["auto", "numerical"], ids=["auto", "numerical"]) -# def test_components_DHO_gauss( -# self, energy, gaussian_component, offset_obj, expected_shift, method -# ): -# "Test convolution of DHO sample and Gaussian resolution components without SampleModel." -# "Test with different offset types and methods." -# # WHEN -# sample_dho = DampedHarmonicOscillator(center=1.5, width=0.3, area=2) -# resolution_gauss = gaussian_component - -# # THEN -# calculated_convolution = convolution( -# energy=energy, -# sample_model=sample_dho, -# resolution_model=resolution_gauss, -# offset=offset_obj, -# method=method, -# ) - -# # EXPECT -# # no simple analytical form, so compute expected result via direct convolution -# sample_values = sample_dho.evaluate(energy - expected_shift) -# resolution_values = resolution_gauss.evaluate(energy) -# expected_result = fftconvolve(sample_values, resolution_values, mode="same") -# expected_result *= energy[1] - energy[0] # normalize - -# np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) - -# @pytest.mark.parametrize( -# "offset_obj, expected_shift", -# [ -# (None, 0.0), -# (0.4, 0.4), -# (Parameter("off", 0.4), 0.4), -# ], -# ids=["none", "float", "parameter"], -# ) -# @pytest.mark.parametrize( -# "method", ["analytical", "numerical"], ids=["analytical", "numerical"] -# ) -# def test_components_lorentzian_lorentzian( -# self, -# energy, -# lorentzian_component, -# other_lorentzian_component, -# offset_obj, -# expected_shift, -# method, -# ): -# "Test convolution of Lorentzian sample and Lorentzian resolution components without SampleModel." -# "Test with different offset types and methods." -# # WHEN -# sample_lorentzian = lorentzian_component -# resolution_lorentzian = other_lorentzian_component - -# # THEN -# calculated_convolution = convolution( -# energy=energy, -# sample_model=sample_lorentzian, -# resolution_model=resolution_lorentzian, -# offset=offset_obj, -# method=method, -# upsample_factor=5, -# ) - -# # EXPECT -# # Convolution of two Lorentzians is another Lorentzian with width = w1 + w2 -# expected_width = ( -# sample_lorentzian.width.value + resolution_lorentzian.width.value -# ) -# expected_area = sample_lorentzian.area.value * resolution_lorentzian.area.value -# expected_center = ( -# sample_lorentzian.center.value -# + resolution_lorentzian.center.value -# + expected_shift -# ) -# expected_result = ( -# expected_area -# * expected_width -# / np.pi -# / ((energy - expected_center) ** 2 + expected_width**2) -# ) - -# np.testing.assert_allclose( -# calculated_convolution, -# expected_result, -# atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, -# rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, -# ) - -# @pytest.mark.parametrize( -# "offset_obj, expected_shift", -# [ -# (None, 0.0), -# (0.4, 0.4), -# (Parameter("off", 0.4), 0.4), -# ], -# ids=["none", "float", "parameter"], -# ) -# @pytest.mark.parametrize( -# "method", ["analytical", "numerical"], ids=["analytical", "numerical"] -# ) -# @pytest.mark.parametrize( -# "sample_is_gauss", -# [True, False], -# ids=["gauss_sample__lorentz_resolution", "lorentz_sample__gauss_resolution"], -# ) -# def test_components_gauss_lorentzian( -# self, -# energy, -# gaussian_component, -# lorentzian_component, -# offset_obj, -# expected_shift, -# method, -# sample_is_gauss, -# ): -# "Test convolution of Gaussian and Lorentzian components without SampleModel." -# "Test with different offset types and methods." -# # WHEN -# if sample_is_gauss: -# sample = gaussian_component -# resolution = lorentzian_component -# else: -# sample = lorentzian_component -# resolution = gaussian_component - -# # THEN -# calculated_convolution = convolution( -# energy=energy, -# sample_model=sample, -# resolution_model=resolution, -# offset=offset_obj, -# method=method, -# upsample_factor=5, -# ) - -# # EXPECT -# expected_center = sample.center.value + resolution.center.value + expected_shift -# expected_area = sample.area.value * resolution.area.value - -# gaussian_width = ( -# sample.width.value if sample_is_gauss else resolution.width.value -# ) -# lorentzian_width = ( -# resolution.width.value if sample_is_gauss else sample.width.value -# ) - -# expected_result = expected_area * voigt_profile( -# energy - expected_center, -# gaussian_width, -# lorentzian_width, -# ) - -# np.testing.assert_allclose( -# calculated_convolution, -# expected_result, -# atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, -# rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, -# ) - -# @pytest.mark.parametrize( -# "offset_obj, expected_shift", -# [ -# (None, 0.0), -# (0.4, 0.4), -# (Parameter("off", 0.4), 0.4), -# ], -# ids=["none", "float", "parameter"], -# ) -# @pytest.mark.parametrize( -# "method", ["analytical", "numerical"], ids=["analytical", "numerical"] -# ) -# @pytest.mark.parametrize( -# "sample_is_gauss", -# [True, False], -# ids=["gauss_sample__delta_resolution", "delta_sample__gauss_resolution"], -# ) -# def test_components_delta_gauss( -# self, -# energy, -# gaussian_component, -# offset_obj, -# expected_shift, -# method, -# sample_is_gauss, -# ): -# "Test convolution of Delta function sample and Gaussian resolution components without SampleModel." -# "Test with different offset types and methods." -# # WHEN -# if sample_is_gauss: -# sample = gaussian_component -# resolution = DeltaFunction(name="Delta", center=0.1, area=2) -# else: -# sample = DeltaFunction(name="Delta", center=0.1, area=2) -# resolution = gaussian_component - -# # THEN -# calculated_convolution = convolution( -# energy=energy, -# sample_model=sample, -# resolution_model=resolution, -# offset=offset_obj, -# method=method, -# ) - -# # EXPECT -# expected_center = sample.center.value + resolution.center.value + expected_shift -# expected_area = sample.area.value * resolution.area.value -# width = sample.width.value if sample_is_gauss else resolution.width.value -# expected_result = ( -# expected_area -# * np.exp(-0.5 * ((energy - expected_center) / width) ** 2) -# / (np.sqrt(2 * np.pi) * width) -# ) - -# np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) - -# # Test convolution of SampleModel -# @pytest.mark.parametrize( -# "offset_obj, expected_shift", -# [ -# (None, 0.0), -# (0.4, 0.4), -# (Parameter("off", 0.4), 0.4), -# ], -# ids=["none", "float", "parameter"], -# ) -# @pytest.mark.parametrize( -# "method", ["analytical", "numerical"], ids=["analytical", "numerical"] -# ) -# def test_model_gauss_gauss_resolution_gauss( -# self, -# energy, -# sample_model, -# resolution_model, -# offset_obj, -# expected_shift, -# method, -# ): -# "Test convolution of Gaussian sample components in SampleModel and Gaussian resolution components in SampleModel." -# "Test with different offset types and methods." - -# # WHEN -# sample_G2 = Gaussian(name="another Gaussian", center=0.3, width=0.5, area=4) -# sample_model.add_component(sample_G2) - -# # THEN -# calculated_convolution = convolution( -# energy=energy, -# sample_model=sample_model, -# resolution_model=resolution_model, -# offset=offset_obj, -# method=method, -# ) - -# # EXPECT -# sample_G1 = sample_model["Gaussian"] -# resolution_G1 = resolution_model["Gaussian"] -# expected_width1 = np.sqrt( -# sample_G1.width.value**2 + resolution_G1.width.value**2 -# ) -# expected_width2 = np.sqrt( -# sample_G2.width.value**2 + resolution_G1.width.value**2 -# ) -# expected_area1 = sample_G1.area.value * resolution_G1.area.value -# expected_area2 = sample_G2.area.value * resolution_G1.area.value -# expected_center1 = ( -# sample_G1.center.value + resolution_G1.center.value + expected_shift -# ) -# expected_center2 = ( -# sample_G2.center.value + resolution_G1.center.value + expected_shift -# ) - -# expected_result = expected_area1 * np.exp( -# -0.5 * ((energy - expected_center1) / expected_width1) ** 2 -# ) / (np.sqrt(2 * np.pi) * expected_width1) + expected_area2 * np.exp( -# -0.5 * ((energy - expected_center2) / expected_width2) ** 2 -# ) / (np.sqrt(2 * np.pi) * expected_width2) -# np.testing.assert_allclose(calculated_convolution, expected_result, atol=1e-10) - -# @pytest.mark.parametrize( -# "offset_obj, expected_shift", -# [ -# (None, 0.0), -# (0.4, 0.4), -# (Parameter("off", 0.4), 0.4), -# ], -# ids=["none", "float", "parameter"], -# ) -# @pytest.mark.parametrize( -# "method", ["analytical", "numerical"], ids=["analytical", "numerical"] -# ) -# def test_model_lorentzian_delta_resolution_gauss( -# self, -# energy, -# method, -# lorentzian_component, -# resolution_model, -# offset_obj, -# expected_shift, -# ): -# "Test convolution of Lorentzian and Delta function sample components in SampleModel and Gaussian resolution components in SampleModel." -# " Result is a combination of Voigt profile and Gaussian." -# # WHEN - -# sample = SampleModel(name="SampleModel") -# sample.add_component(lorentzian_component) -# sample_delta = DeltaFunction(center=0.5, area=4, name="SampleDelta") -# sample.add_component(sample_delta) - -# # THEN -# energy = np.linspace(-10, 10, 20001) -# calculated_convolution = convolution( -# energy=energy, -# sample_model=sample, -# resolution_model=resolution_model, -# offset=offset_obj, -# method=method, -# upsample_factor=5, -# ) - -# # EXPECT: Combine Gaussian, Lorentzian, and Delta functions contributions -# # -# gaussian_component = resolution_model["Gaussian"] - -# expected_voigt_area = ( -# lorentzian_component.area.value * gaussian_component.area.value -# ) -# expected_voigt_center = ( -# lorentzian_component.center.value -# + gaussian_component.center.value -# + expected_shift -# ) -# expected_voigt = expected_voigt_area * voigt_profile( -# energy - expected_voigt_center, -# gaussian_component.width.value, -# lorentzian_component.width.value, -# ) -# expected_gauss_area = sample_delta.area.value * gaussian_component.area.value -# expected_gauss_center = ( -# sample_delta.center.value + gaussian_component.center.value + expected_shift -# ) -# expected_gauss_width = gaussian_component.width.value -# expected_gauss = ( -# expected_gauss_area -# * np.exp( -# -0.5 * ((energy - (expected_gauss_center)) / expected_gauss_width) ** 2 -# ) -# / (np.sqrt(2 * np.pi) * expected_gauss_width) -# ) -# expected_result = expected_voigt + expected_gauss -# np.testing.assert_allclose( -# calculated_convolution, -# expected_result, -# atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, -# rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, -# ) - -# def test_numerical_convolve_with_temperature( -# self, energy, sample_model, resolution_model -# ): -# "Test numerical convolution with detailed balance correction." -# # WHEN -# temperature = 300.0 # Kelvin - -# # THEN -# calculated_convolution = convolution( -# energy=energy, -# sample_model=sample_model, -# resolution_model=resolution_model, -# method="numerical", -# upsample_factor=5, -# temperature=temperature, -# ) - -# sample_with_db = sample_model.evaluate(energy) * detailed_balance_factor( -# energy=energy, temperature=temperature -# ) -# resolution = resolution_model.evaluate(energy) - -# expected_convolution = fftconvolve(sample_with_db, resolution, mode="same") -# expected_convolution *= [energy[1] - energy[0]] # normalize - -# np.testing.assert_allclose( -# calculated_convolution, -# expected_convolution, -# atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, -# rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, -# ) - -# @pytest.mark.parametrize( -# "x", -# [ -# np.linspace(-10, 10, 5001), # Odd length -# np.linspace(-10, 10, 5000), # Even length -# ], -# ids=["odd_length", "even_length"], -# ) -# def test_numerical_convolve_x_length_even_and_odd( -# self, x, sample_model, resolution_model -# ): -# "Test numerical convolution with both even and odd length x arrays. With even length the FFT shifts the signal by half a bin." - -# # WHEN THEN -# calculated_convolution = convolution( -# energy=x, -# sample_model=sample_model, -# resolution_model=resolution_model, -# method="numerical", -# upsample_factor=0, -# ) - -# # EXPECT -# expected_convolution = convolution( -# energy=x, -# sample_model=sample_model, -# resolution_model=resolution_model, -# method="analytical", -# upsample_factor=0, -# ) - -# np.testing.assert_allclose( -# calculated_convolution, expected_convolution, atol=1e-10 -# ) - -# @pytest.mark.parametrize( -# "upsample_factor", -# [0, 2, 5, 10], -# ids=["no_upsample", "upsample_2", "upsample_5", "upsample_10"], -# ) -# def test_numerical_convolve_upsample_factor( -# self, energy, upsample_factor, sample_model, resolution_model -# ): -# "Test numerical convolution with different upsample factors." -# # WHEN THEN -# calculated_convolution = convolution( -# energy=energy, -# sample_model=sample_model, -# resolution_model=resolution_model, -# method="numerical", -# upsample_factor=upsample_factor, -# ) - -# # EXPECT -# expected_convolution = convolution( -# energy=energy, -# sample_model=sample_model, -# resolution_model=resolution_model, -# method="analytical", -# upsample_factor=0, -# ) - -# np.testing.assert_allclose( -# calculated_convolution, -# expected_convolution, -# atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, -# rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, -# ) - -# @pytest.mark.parametrize( -# "x", -# [np.linspace(-5, 15, 20000), np.linspace(5, 15, 20000)], -# ids=["asymmetric", "only_positive"], -# ) -# @pytest.mark.parametrize( -# "upsample_factor", [0, 2, 5], ids=["no_upsample", "upsample_2", "upsample_5"] -# ) -# def test_numerical_convolve_x_not_symmetric( -# self, x, upsample_factor, resolution_model -# ): -# "Test numerical convolution with asymmetric and only positive x arrays." -# # WHEN -# sample_model = SampleModel(name="SampleModel") -# sample_model.add_component(Gaussian(center=9, width=0.3, area=2)) - -# # THEN -# calculated_convolution = convolution( -# energy=x, -# sample_model=sample_model, -# resolution_model=resolution_model, -# method="numerical", -# upsample_factor=upsample_factor, -# ) - -# # EXPECT -# expected_convolution = convolution( -# energy=x, -# sample_model=sample_model, -# resolution_model=resolution_model, -# method="analytical", -# ) - -# np.testing.assert_allclose( -# calculated_convolution, -# expected_convolution, -# atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, -# rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, -# ) - -# def test_numerical_convolve_x_not_uniform(self, sample_model, resolution_model): -# "Test numerical convolution with non-uniform x arrays." -# # WHEN -# x_1 = np.linspace(-2, 0, 1000) -# x_2 = np.linspace(0.001, 2, 2000) -# x_non_uniform = np.concatenate([x_1, x_2]) - -# # THEN -# calculated_convolution = convolution( -# energy=x_non_uniform, -# sample_model=sample_model, -# resolution_model=resolution_model, -# method="numerical", -# upsample_factor=5, -# ) - -# # EXPECT -# expected_convolution = convolution( -# energy=x_non_uniform, -# sample_model=sample_model, -# resolution_model=resolution_model, -# method="analytical", -# ) - -# np.testing.assert_allclose( -# calculated_convolution, -# expected_convolution, -# atol=NUMERICAL_CONVOLUTION_ABSOLUTE_TOLERANCE, -# rtol=NUMERICAL_CONVOLUTION_RELATIVE_TOLERANCE, -# ) - -# # Test error handling -# def test_analytical_convolution_fails_with_detailed_balance( -# self, energy, sample_model, resolution_model -# ): -# # WHEN -# temperature = 300.0 -# # THEN EXPECT -# with pytest.raises( -# ValueError, -# match="Analytical convolution is not supported with detailed balance.", -# ): -# convolution( -# energy=energy, -# sample_model=sample_model, -# resolution_model=resolution_model, -# method="analytical", -# temperature=temperature, -# ) - -# def test_convolution_only_accepts_auto_analytical_and_numerical_methods( -# self, energy, sample_model, resolution_model -# ): -# # WHEN THEN EXPECT -# with pytest.raises( -# ValueError, -# match="Unknown convolution method: unknown_method. Choose from 'auto', 'analytical', or 'numerical'.", -# ): -# convolution( -# energy=energy, -# sample_model=sample_model, -# resolution_model=resolution_model, -# method="unknown_method", -# ) - -# def test_energy_must_be_1d_finite_array(self, sample_model, resolution_model): -# # WHEN THEN EXPECT -# with pytest.raises(ValueError, match="`energy` must be a 1D finite array."): -# convolution( -# energy=np.array([[1, 2], [3, 4]]), -# sample_model=sample_model, -# resolution_model=resolution_model, -# ) - -# with pytest.raises(ValueError, match="`energy` must be a 1D finite array."): -# convolution( -# energy=np.array([1, 2, np.nan]), -# sample_model=sample_model, -# resolution_model=resolution_model, -# ) - -# with pytest.raises(ValueError, match="`energy` must be a 1D finite array."): -# convolution( -# energy=np.array([1, 2, np.inf]), -# sample_model=sample_model, -# resolution_model=resolution_model, -# ) - -# def test_numerical_convolve_requires_uniform_grid_if_no_upsample( -# self, sample_model, resolution_model -# ): -# # WHEN -# x = np.array([0, 1, 2, 4, 5]) # Non-uniform grid - -# # THEN EXPECT -# with pytest.raises( -# ValueError, -# match="Input array `energy` must be uniformly spaced if upsample_factor = 0.", -# ): -# convolution( -# energy=x, -# sample_model=sample_model, -# resolution_model=resolution_model, -# method="numerical", -# upsample_factor=0, -# ) - -# def test_sample_model_must_have_components(self, resolution_model): -# # WHEN -# sample_model = SampleModel(name="SampleModel") - -# # THEN EXPECT -# with pytest.raises( -# ValueError, match="SampleModel must have at least one component." -# ): -# convolution( -# energy=np.array([0, 1, 2]), -# sample_model=sample_model, -# resolution_model=resolution_model, -# ) - -# def test_resolution_model_must_have_components(self, sample_model): -# # WHEN -# resolution_model = SampleModel(name="ResolutionModel") - -# # THEN EXPECT -# with pytest.raises( -# ValueError, match="ResolutionModel must have at least one component." -# ): -# convolution( -# energy=np.array([0, 1, 2]), -# sample_model=sample_model, -# resolution_model=resolution_model, -# ) - -# def test_numerical_convolution_wide_sample_peak_gives_warning( -# self, resolution_model -# ): -# # WHEN -# x = np.linspace(-2, 2, 20001) - -# sample_gauss = Gaussian(center=0.1, width=1.9, area=2, name="SampleGauss") -# sample = SampleModel(name="SampleModel") -# sample.add_component(sample_gauss) - -# # #THEN EXPECT -# with pytest.warns( -# UserWarning, -# match=r"The width of the sample model component ", -# ): -# convolution( -# energy=x, -# sample_model=sample, -# resolution_model=resolution_model, -# method="numerical", -# upsample_factor=0, -# ) - -# def test_numerical_convolution_wide_resolution_peak_gives_warning( -# self, sample_model -# ): -# # WHEN -# x = np.linspace(-2, 2, 20001) - -# resolution_gauss = Gaussian( -# center=0.3, width=1.9, area=4, name="ResolutionGauss" -# ) - -# resolution = SampleModel(name="ResolutionModel") -# resolution.add_component(resolution_gauss) - -# # #THEN EXPECT -# with pytest.warns( -# UserWarning, -# match=r"The width of the resolution model component 'ResolutionGauss' \(1.9\) is large", -# ): -# convolution( -# energy=x, -# sample_model=sample_model, -# resolution_model=resolution, -# method="numerical", -# upsample_factor=0, -# ) - -# def test_numerical_convolution_narrow_sample_peak_gives_warning( -# self, resolution_model -# ): -# # WHEN -# x = np.linspace(-2, 2, 201) - -# sample_gauss1 = Gaussian(center=0.1, width=1e-3, area=2, name="SampleGauss") - -# sample = SampleModel(name="SampleModel") -# sample.add_component(sample_gauss1) - -# # #THEN EXPECT -# with pytest.warns( -# UserWarning, -# match=r"The width of the sample model component 'SampleGauss' \(0.001\) is small", -# ): -# convolution( -# energy=x, -# sample_model=sample, -# resolution_model=resolution_model, -# method="numerical", -# upsample_factor=0, -# ) - -# def test_numerical_convolution_narrow_resolution_peak_gives_warning( -# self, sample_model -# ): -# # WHEN -# x = np.linspace(-2, 2, 201) - -# resolution_gauss = Gaussian( -# center=0.3, width=1e-3, area=4, name="ResolutionGauss" -# ) - -# resolution = SampleModel(name="ResolutionModel") -# resolution.add_component(resolution_gauss) - -# # #THEN EXPECT -# with pytest.warns( -# UserWarning, -# match=r"The width of the resolution model component 'ResolutionGauss' \(0.001\) is small", -# ): -# convolution( -# energy=x, -# sample_model=sample_model, -# resolution_model=resolution, -# method="numerical", -# upsample_factor=0, -# ) From cc5ee142798e25d045fe78b1c45bc09d79767c84 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Mon, 15 Dec 2025 14:32:29 +0100 Subject: [PATCH 65/71] Remove comments --- tests/unit_tests/convolution/test_energy_grid.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/unit_tests/convolution/test_energy_grid.py b/tests/unit_tests/convolution/test_energy_grid.py index 3b20e56..a66b714 100644 --- a/tests/unit_tests/convolution/test_energy_grid.py +++ b/tests/unit_tests/convolution/test_energy_grid.py @@ -24,9 +24,3 @@ def test_energy_grid_attributes(self): assert energy_grid.energy_dense_step == energy_dense_step assert energy_grid.energy_span_dense == energy_span_dense assert energy_grid.energy_even_length_offset == energy_even_length_offset - - # energy_dense: np.ndarray - # energy_dense_centered: np.ndarray - # energy_dense_step: float - # span_dense: float - # energy_even_length_offset: float From ae313238155edb4e2776a863275d45235f2c6909 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Tue, 16 Dec 2025 09:07:10 +0100 Subject: [PATCH 66/71] Update type hints --- .../convolution/analytical_convolution.py | 10 ++++---- src/easydynamics/convolution/convolution.py | 4 +--- .../convolution/convolution_base.py | 24 ++++++++----------- .../convolution/numerical_convolution.py | 22 ++++++++--------- .../convolution/numerical_convolution_base.py | 6 ++--- 5 files changed, 29 insertions(+), 37 deletions(-) diff --git a/src/easydynamics/convolution/analytical_convolution.py b/src/easydynamics/convolution/analytical_convolution.py index 0f0aba3..b5f2032 100644 --- a/src/easydynamics/convolution/analytical_convolution.py +++ b/src/easydynamics/convolution/analytical_convolution.py @@ -1,4 +1,4 @@ -from typing import Optional, Union +from typing import Optional import numpy as np import scipp as sc @@ -14,7 +14,7 @@ ) from easydynamics.sample_model.components.model_component import ModelComponent -Numerical = Union[float, int] +Numerical = float | int class AnalyticalConvolution(ConvolutionBase): @@ -42,8 +42,8 @@ class AnalyticalConvolution(ConvolutionBase): def __init__( self, - energy: Union[np.ndarray, sc.Variable], - energy_unit: Optional[Union[str, sc.Unit]] = "meV", + energy: np.ndarray | sc.Variable, + energy_unit: str | sc.Unit = "meV", sample_model: Optional[SampleModel] = None, resolution_model: Optional[SampleModel] = None, ): @@ -167,7 +167,7 @@ def _convolute_analytic_pair( def _convolute_delta_any( self, sample_component: ModelComponent, - resolution_model: Union[SampleModel, ModelComponent], + resolution_model: SampleModel | ModelComponent, ): """ Convolution of delta function with any component or SampleModel results in the same component or SampleModel shifted by the delta center. diff --git a/src/easydynamics/convolution/convolution.py b/src/easydynamics/convolution/convolution.py index 6a6e214..94fc059 100644 --- a/src/easydynamics/convolution/convolution.py +++ b/src/easydynamics/convolution/convolution.py @@ -1,5 +1,3 @@ -from typing import Union - import numpy as np import scipp as sc from easyscience.variable import Parameter @@ -16,7 +14,7 @@ ) from easydynamics.sample_model.components.model_component import ModelComponent -Numerical = Union[float, int] +Numerical = float | int class Convolution(NumericalConvolutionBase): diff --git a/src/easydynamics/convolution/convolution_base.py b/src/easydynamics/convolution/convolution_base.py index 9914952..89de6e9 100644 --- a/src/easydynamics/convolution/convolution_base.py +++ b/src/easydynamics/convolution/convolution_base.py @@ -1,12 +1,10 @@ -from typing import Union - import numpy as np import scipp as sc from easydynamics.sample_model import SampleModel from easydynamics.sample_model.components.model_component import ModelComponent -Numerical = Union[float, int] +Numerical = float | int class ConvolutionBase: @@ -27,10 +25,10 @@ class ConvolutionBase: def __init__( self, - energy: Union[np.ndarray, sc.Variable], - sample_model: Union[SampleModel, ModelComponent] = None, - resolution_model: Union[SampleModel, ModelComponent] = None, - energy_unit: Union[str, sc.Unit] = "meV", + energy: np.ndarray | sc.Variable, + sample_model: SampleModel | ModelComponent = None, + resolution_model: SampleModel | ModelComponent = None, + energy_unit: str | sc.Unit = "meV", ): if isinstance(energy, Numerical): energy = np.array([float(energy)]) @@ -109,7 +107,7 @@ def energy_unit(self, unit_str: str) -> None: ) ) # noqa: E501 - def convert_energy_unit(self, energy_unit: Union[str, sc.Unit]) -> None: + def convert_energy_unit(self, energy_unit: str | sc.Unit) -> None: """Convert the energy to the specified unit Args: energy_unit : str or sc.Unit @@ -125,12 +123,12 @@ def convert_energy_unit(self, energy_unit: Union[str, sc.Unit]) -> None: self._energy_unit = energy_unit @property - def sample_model(self) -> Union[SampleModel, ModelComponent]: + def sample_model(self) -> SampleModel | ModelComponent: """Get the sample model""" return self._sample_model @sample_model.setter - def sample_model(self, sample_model: Union[SampleModel, ModelComponent]) -> None: + def sample_model(self, sample_model: SampleModel | ModelComponent) -> None: """Set the sample model. Args: sample_model : SampleModel or ModelComponent @@ -146,14 +144,12 @@ def sample_model(self, sample_model: Union[SampleModel, ModelComponent]) -> None self._sample_model = sample_model @property - def resolution_model(self) -> Union[SampleModel, ModelComponent]: + def resolution_model(self) -> SampleModel | ModelComponent: """Get the resolution model""" return self._resolution_model @resolution_model.setter - def resolution_model( - self, resolution_model: Union[SampleModel, ModelComponent] - ) -> None: + def resolution_model(self, resolution_model: SampleModel | ModelComponent) -> None: """Set the resolution model. Args: resolution_model : SampleModel or ModelComponent diff --git a/src/easydynamics/convolution/numerical_convolution.py b/src/easydynamics/convolution/numerical_convolution.py index 3ff5137..532e5df 100644 --- a/src/easydynamics/convolution/numerical_convolution.py +++ b/src/easydynamics/convolution/numerical_convolution.py @@ -1,5 +1,3 @@ -from typing import Optional, Union - import numpy as np import scipp as sc from easyscience.variable import Parameter @@ -14,7 +12,7 @@ _detailed_balance_factor as detailed_balance_factor, ) -Numerical = Union[float, int] +Numerical = float | int class NumericalConvolution(NumericalConvolutionBase): @@ -46,15 +44,15 @@ class NumericalConvolution(NumericalConvolutionBase): def __init__( self, - energy: Union[np.ndarray, sc.Variable], - sample_model: Union[SampleModel, ModelComponent], - resolution_model: Union[SampleModel, ModelComponent], - upsample_factor: Optional[Numerical] = 5, - extension_factor: Optional[float] = 0.2, - temperature: Optional[Union[Parameter, float]] = None, - temperature_unit: Optional[Union[str, sc.Unit]] = "K", - energy_unit: Optional[Union[str, sc.Unit]] = "meV", - normalize_detailed_balance: Optional[bool] = True, + energy: np.ndarray | sc.Variable, + sample_model: SampleModel | ModelComponent, + resolution_model: SampleModel | ModelComponent, + upsample_factor: Numerical = 5, + extension_factor: float = 0.2, + temperature: Parameter | float | None = None, + temperature_unit: str | sc.Unit = "K", + energy_unit: str | sc.Unit = "meV", + normalize_detailed_balance: bool = True, ): super().__init__( energy=energy, diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index a57eec5..ba56771 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -1,7 +1,7 @@ import warnings # from dataclasses import dataclass -from typing import Optional, Union +from typing import Optional import numpy as np import scipp as sc @@ -14,7 +14,7 @@ ) from easydynamics.sample_model.components.model_component import ModelComponent -Numerical = Union[float, int] +Numerical = float | int class NumericalConvolutionBase(ConvolutionBase): @@ -158,7 +158,7 @@ def temperature(self) -> Optional[Parameter]: return self._temperature @temperature.setter - def temperature(self, temp: Optional[Union[Parameter, float]]) -> None: + def temperature(self, temp: Parameter | float | None) -> None: """ Set the temperature. If None, disables detailed balance correction and removes the temperature parameter. Args: From b6e05902a472b4d9ff101a94c153197e51f0b0d8 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Tue, 16 Dec 2025 09:31:21 +0100 Subject: [PATCH 67/71] 100% coverage? --- .../convolution/test_convolution.py | 127 +++++++++++++++++- 1 file changed, 125 insertions(+), 2 deletions(-) diff --git a/tests/unit_tests/convolution/test_convolution.py b/tests/unit_tests/convolution/test_convolution.py index ce3ba97..63bc008 100644 --- a/tests/unit_tests/convolution/test_convolution.py +++ b/tests/unit_tests/convolution/test_convolution.py @@ -5,10 +5,12 @@ import pytest import scipp as sc +from easydynamics.convolution.analytical_convolution import AnalyticalConvolution from easydynamics.convolution.convolution import ( Convolution, ) from easydynamics.convolution.energy_grid import EnergyGrid +from easydynamics.convolution.numerical_convolution import NumericalConvolution from easydynamics.sample_model import ( DampedHarmonicOscillator, DeltaFunction, @@ -341,6 +343,127 @@ def test_check_if_pair_is_analytic_raises_with_invalid_types( resolution_component=resolution_component, ) - # def test_build_convolution_plan(self, default_convolution): + @pytest.mark.parametrize( + "analytical_component", + [True, False], + ids=["with_analytical", "without_analytical"], + ) + @pytest.mark.parametrize( + "numerical_component", + [True, False], + ids=["with_numerical", "without_numerical"], + ) + @pytest.mark.parametrize( + "delta_component", [True, False], ids=["with_delta", "without_delta"] + ) + def test_build_convolution_plan( + self, + default_convolution, + analytical_component, + numerical_component, + delta_component, + ): + """ + Tests that convolution calls the correct methods depending on which component types are present. + """ + + # WHEN + conv = default_convolution + sample_model = SampleModel() + + if analytical_component: + sample_model.add_component( + Gaussian(name="Gaussian", area=1.0, center=0.0, width=0.1) + ) + + if numerical_component: + sample_model.add_component( + DampedHarmonicOscillator( + name="DampedHarmonicOscillator", area=1.0, center=1.0, width=0.1 + ) + ) + + if delta_component: + sample_model.add_component( + DeltaFunction(name="DeltaFunction", area=1.0, center=0.0) + ) + + # THEN + conv.sample_model = sample_model # This updates the internal sample models + conv._build_convolution_plan() # It is already called by sample_model setter, but we now call it explicitly + + # EXPECT + assert isinstance(conv._analytical_sample_model, SampleModel) + if analytical_component: + assert len(conv._analytical_sample_model.components) == 1 + assert conv._analytical_sample_model.components[0].name == "Gaussian" + else: + assert len(conv._analytical_sample_model.components) == 0 - # def test_set_convolvers(self, default_convolution): + assert isinstance(conv._numerical_sample_model, SampleModel) + if numerical_component: + assert len(conv._numerical_sample_model.components) == 1 + assert ( + conv._numerical_sample_model.components[0].name + == "DampedHarmonicOscillator" + ) + else: + assert len(conv._numerical_sample_model.components) == 0 + + assert isinstance(conv._delta_sample_model, SampleModel) + if delta_component: + assert len(conv._delta_sample_model.components) == 1 + assert conv._delta_sample_model.components[0].name == "DeltaFunction" + + assert conv._convolution_plan_is_valid is True + + @pytest.mark.parametrize( + "analytical_component", + [True, False], + ids=["with_analytical", "without_analytical"], + ) + @pytest.mark.parametrize( + "numerical_component", + [True, False], + ids=["with_numerical", "without_numerical"], + ) + def test_set_convolvers( + self, + default_convolution, + analytical_component, + numerical_component, + ): + """ + Tests that convolution sets the correct methods depending on which component types are present. + """ + + # WHEN + conv = default_convolution + sample_model = SampleModel() + + if analytical_component: + sample_model.add_component( + Gaussian(name="Gaussian", area=1.0, center=0.0, width=0.1) + ) + + if numerical_component: + sample_model.add_component( + DampedHarmonicOscillator( + name="DampedHarmonicOscillator", area=1.0, center=1.0, width=0.1 + ) + ) + + # THEN + conv.sample_model = sample_model # This updates the internal sample models + conv._set_convolvers() # Should already have been called by sample_model setter, but we now call it explicitly + + # EXPECT + if analytical_component: + assert isinstance(conv._analytical_convolver, AnalyticalConvolution) + else: + assert conv._analytical_convolver is None + + if numerical_component: + assert isinstance(conv._numerical_convolver, NumericalConvolution) + else: + assert conv._numerical_convolver is None From ea3cbade3540c462842d48b22ab175efb8a212ab Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Tue, 16 Dec 2025 09:39:24 +0100 Subject: [PATCH 68/71] 100% coverage! --- .../convolution/test_convolution.py | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/tests/unit_tests/convolution/test_convolution.py b/tests/unit_tests/convolution/test_convolution.py index 63bc008..c3c4c77 100644 --- a/tests/unit_tests/convolution/test_convolution.py +++ b/tests/unit_tests/convolution/test_convolution.py @@ -356,12 +356,16 @@ def test_check_if_pair_is_analytic_raises_with_invalid_types( @pytest.mark.parametrize( "delta_component", [True, False], ids=["with_delta", "without_delta"] ) + @pytest.mark.parametrize( + "temperature", [None, 100], ids=["with_temperature", "without_temperature"] + ) def test_build_convolution_plan( self, default_convolution, analytical_component, numerical_component, delta_component, + temperature, ): """ Tests that convolution calls the correct methods depending on which component types are present. @@ -390,30 +394,46 @@ def test_build_convolution_plan( # THEN conv.sample_model = sample_model # This updates the internal sample models + if temperature is not None: + conv.temperature = temperature conv._build_convolution_plan() # It is already called by sample_model setter, but we now call it explicitly # EXPECT assert isinstance(conv._analytical_sample_model, SampleModel) - if analytical_component: + if analytical_component and not temperature: assert len(conv._analytical_sample_model.components) == 1 assert conv._analytical_sample_model.components[0].name == "Gaussian" else: assert len(conv._analytical_sample_model.components) == 0 - assert isinstance(conv._numerical_sample_model, SampleModel) - if numerical_component: - assert len(conv._numerical_sample_model.components) == 1 - assert ( - conv._numerical_sample_model.components[0].name - == "DampedHarmonicOscillator" - ) - else: - assert len(conv._numerical_sample_model.components) == 0 - assert isinstance(conv._delta_sample_model, SampleModel) if delta_component: assert len(conv._delta_sample_model.components) == 1 assert conv._delta_sample_model.components[0].name == "DeltaFunction" + else: + assert len(conv._delta_sample_model.components) == 0 + + assert isinstance(conv._numerical_sample_model, SampleModel) + + if not temperature: + if numerical_component: + assert len(conv._numerical_sample_model.components) == 1 + assert ( + conv._numerical_sample_model.components[0].name + == "DampedHarmonicOscillator" + ) + else: + assert len(conv._numerical_sample_model.components) == 0 + else: + # analytical and numerical components go to numerical when temperature is set + expected_numerical_count = 0 + if numerical_component: + expected_numerical_count += 1 + if analytical_component: + expected_numerical_count += 1 + assert ( + len(conv._numerical_sample_model.components) == expected_numerical_count + ) assert conv._convolution_plan_is_valid is True From 64cf5fd5cc62a92ee6f52f5f942af5623a680226 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Tue, 16 Dec 2025 09:45:16 +0100 Subject: [PATCH 69/71] Remove output from Jupyter notebook --- examples/detailed_balance.ipynb | 92 +++------------------------------ examples/sample_model.ipynb | 58 ++------------------- 2 files changed, 11 insertions(+), 139 deletions(-) diff --git a/examples/detailed_balance.ipynb b/examples/detailed_balance.ipynb index 172422f..b4ca072 100644 --- a/examples/detailed_balance.ipynb +++ b/examples/detailed_balance.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "97050b3e", "metadata": {}, "outputs": [], @@ -17,36 +17,10 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "c1654720", "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "7cfd67c54e984f0bbf333f80d81e1929", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAfQBJREFUeJzt3Qd8E+X/B/Bv96KlzLLKLLKnCKIMUWQpwwGoKIgD9QcOBBkqw4GooPJXURQVF6iIDCeIyFLZe++9V/du7v/6PO2FJE1L2qa9jM8bz14ul8tzI3ffe9b5aJqmCRERERF5DV+jE0BEREREJYsBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASEREReRkGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASEREReRkGgERERERehgEgERERkZdhAEhERETkZRgAEhEREXkZBoBEREREXoYBIBEREZGXYQBIRERE5GUYABIRERF5GQaARERERF6GASARERGRl2EASERERORlGAASEREReRkGgERERERehgEgERERkZdxSgC4YsUK8fHxUX/zM3HiRDXfxYsXxVluueUWNbi7zMxMGTVqlERHR4uvr6/06dNHPEFiYqI89thjUqlSJbXvn3vuOUPSge/G8af78ssv1bSjR49azTdlyhSpXbu2+Pn5SfPmzT163xB5AnvXn4cfflhq1qxZounAuQTpwLmFyB0wB9BFfPHFFyr4uPfee+Wrr76S4cOHO/07PvrooxI/Ob3xxhvqO5966in55ptv5KGHHhJX9eeff6pA7+abb5ZZs2aptJfUvnGW33//3SrQdcVjwh0kJyer7Xitm1qigtq9e7c6tmxvPp1xsz1hwgTp1q2blC1bttiC0f/++0+lPzY21unLppLlX8LfR3n4+++/pWrVqvLee+8V23fgYl++fHl1d1yS63XjjTeqE5MrQSB63333SVBQkFVakcP3+eefS2BgYInuG2cGgNOnT3c4CDTimHCXAPCVV15R455QwuBtZs6cKSaTSVw1AMSxhePKmbmUKFl79dVXpXr16tKsWbNiu3lBAIj045wRGRlZLN9BJYM5gC7i/PnzbvljSk1NzfdE6+z1QnFsenp6kZeDIt7g4GB1l2yZ1pCQEKvgrzjWQdM0SUlJcdryqOSOG09JR3FKSkoyOgkSEBBgdXPnDSpXrixnzpyRY8eOqRILb7pZ8yRaCV4fzAHgqVOn5JFHHpGoqCj1w2nUqJEq+rJ18uRJVQcqLCxMKlasqIrD0tLSCnyn0q9fP4mIiJBy5crJs88+qwIJSyiCu/XWW9V3ID0NGzaUjz/++JrLxsl1/Pjxcv3110vp0qVVOtu3by/Lly+3W19j6tSp8umnn0qdOnXU99xwww2yYcOGXMvdu3evSnOFChVUkFCvXj156aWXrOZxdBvaSwfSt2vXLjVuWZ8F6bvpppvUdsL3Yr3mzZtnd1nffvuttG7dWkJDQ6VMmTLSoUMHVawJuNPE8leuXGn+DsucjcOHD0vfvn1V0QE+j1y73377zW5dm++//15efvlllSuGeePj43OlRZ/3yJEjajn6d+rFHgiqHn30UbWtEIjhjhXFq3nto2nTppn3Ee6g84JjEcck9lN4eLj06tVLHbO2bOsAYhzHHC5eelr1efLaNwh8kS7sZ6wD1uWJJ56QK1euWH0Xtv2dd94pS5YskVatWqn9+Mknn6j3UIyCepGoX4h1i4mJkbfeessqqHb0WMUdOXL/9PXRh7xc65goaNrw3ag/iWOiS5cucuLECXUye+2116RatWpqvXv37i2XL1+2u31wrKLeJbYlfu/z58/PleaCpsn2uHHk/IDP4/gB5HTo20bPVc2r3rFtvbNrHb84p6BaAX5zWGccGz///LPVMjMyMlQa6tatq+bBeaBdu3aydOlSKQykZ9iwYbJw4UJp3Lix+Ty1ePHiXPNu2bJFunfvrs7TpUqVkttuu03Wrl1rNY/+G8Ex9L///U+dr7Gv9e2E79i+fbt07NhRHRfYX/r5C59p06aN+Xz6119/WS0bgQyWifcwD9Yd5yhHik5t9wXSYvmbsBwsi0kdOb70+fAdOIZwczho0CCHikTxXVgH6NSpU65zip4rj32C769SpYoMHTrUoWVjftS1LizsJ6wTfsM41rAsXM8uXbpknge/gRdeeEGN16pVK9d53d765rXdbX9DuH7hd4l9jd8ESmhwDrGkH1ObNm1S1zccUy+++KLD15T8/PHHH+pcgHMCrh133HGHOj9awvbBbwHXesRBGMe5YuTIkZKVlWU1rzOuD/gN4BpmGW9hPstjBqVruOG5cOFCrnUaMmSIOj5t4yurIuBz586pC75+csAKYWNgY+LirlfcR1SKk8Dx48flmWeeUQcn6nWhiKwgEEhhpSdPnqxOKO+//77aKF9//bV5HgR72HBYeX9/f/nll1/UyQAbFT+IvCC9n332mdx///3y+OOPS0JCgirS69q1q6xfv95csV83Z84cNQ92DNb/7bfflrvvvlsFRNio+g8DBwZeY4Mi7YcOHVJpmjRpkhRkG9rCfNiGWA7qcGCbQIMGDdTf//u//1PbYMCAAeriheALJ5Bff/1VHaA6XCTw40SwiGIA5GKtW7dO7RtcjHEgPv300+qA1QNXHJB62vE53Elhv+JEix8Ovhcn67vuussqzbigY/k46BFw2eaY6enHeuGAxQVhxIgR5vXFcYQf8sGDB9W2wonkxx9/VD8unOhwQ2AJgRkOYGx7nORwcsgLGpzgRPLAAw+odcL6W26nvCCtCK5wjOD4gRYtWuS7b3DM4AQ3ePBgtd0Q7H744Yfqwvnvv/+ajx/Yt2+fOibxGRyXuKhhe+PCiJMJpqPoBsUrY8eOVXfy2GcFOVYx/fTp0yo4QLqvJb9joqBpmz17tjo+sTwEeEgbfue4icOJavTo0Wp/f/DBB+q4sb0xOnDggPTv31+efPJJdTHFPsdxjsDk9ttvL1Sa7B03jpwfcIzi/IN6qzj2sY2hadOmUhj20oELC+qa4iZqzJgx6gQ/d+5cdVH56aefzL85/KZx3OG4xs0d0r9x40bZvHmzebsU1D///KOCa5xPcaHD+feee+5R53X89gHpwzkPwR/qxeL4wkUJv1s9cLOEZWG7Ibi2zAHEeR0XN1zMsT+xXTGO4wXnROxv/Fb1Ora44CNNgJsb7F/Mj3MIggx8HmlAEI2Lv6NwfGMbWsJ5AhdTXFgLcnzhpgY3MtiOSD/OBwsWLFDH7bUgaMG5AtscgYt+LtH/Yn/jXN65c2d1/OG8gXXGtrA9pzgbzhs4l+B8huAPxwDOifiL6zTOOfgt7N+/X7777jtVJQbVR0C/YbK3vrbnIgQ1yEDQtzvgHDtu3Dh1zsB+QjCDcwU+j/OpZQkMAlLcmOC4ePDBB9U5q6DXFFvffPON2n84DyDgx7GA7Y6bLXy/5c0EAj3Mh98Abu5w4/LOO++oGzzsM11Rrw/4HeH8iWMP6cc+wTXANjML1Zlwzf/hhx/UuutwPsb1G79tBKB2aZqmPfroo1rlypW1ixcvapbuu+8+rXTp0lpycrJ6PW3aNA0fmTt3rnmepKQkLSYmRk1fvny5lp8JEyao+Xr16mU1/X//+5+avm3bNvM0/Tstde3aVatdu7bVtI4dO6pBl5mZqaWlpVnNc+XKFS0qKkp75JFHzNOOHDmivrNcuXLa5cuXzdMXLVqkpv/yyy/maR06dNDCw8O1Y8eOWS3XZDKZxx3dhnnBOjRq1CjXdNvPpaena40bN9ZuvfVW87QDBw5ovr6+2l133aVlZWXlmUYs33Jb6Z577jm1zqtXrzZPS0hI0GrVqqXVrFnTvEzsX8yHfXCt9dHVqFFDu+OOO6ym6cfRt99+a7Vebdu21UqVKqXFx8db7aOIiAjt/Pnz1/yurVu3qvlxPFl64IEH1HQcf7pZs2apafgO3aBBg7SwsDCH9g22FT4/e/Zsq+mLFy/ONR3bANPwnqXXXntNfd/+/futpo8ZM0bz8/PTjh8/XuBjdejQoWqao/I6JgqatgoVKmixsbHm+caOHaumN2vWTMvIyDBPv//++7XAwEAtNTU11/b56aefzNPi4uLU76lFixaFTpO948bR88OFCxdyHTN5nXMsjx+siy6/dNx2221akyZNrLYDfqs33XSTVrduXfM0bD/b309RID3Y/gcPHjRPw3kX0z/44APztD59+qj5Dh06ZJ52+vRpdR7E+dD2d9SuXTu1bS1hG+G9OXPmmKft3btXTcP5au3atebpS5YsUdOxPJ29c8yaNWvUfF9//bV5mn5esrz+2O4LW//++68WEBBgtc8dPb4WLlyovu/tt982z4N1b9++fa51sOfHH3+0e73EMYJt3qVLF6vz+Icffqjm/+KLLzRHbdiwwaG0WLK3vb/77ju1nFWrVpmnTZkyJde501EpKSna9ddfr1WpUkU7c+aMmnb06FG1fSdNmmQ1744dOzR/f3+r6foxNWPGjEJdU+xJSEjQIiMjtccff9xq+tmzZ9W123I6jit8z6uvvmo1L85TWC9nXh/eeecdNR3Hm+X2q1+/fq7jB+vZpk0bq8/Pnz//mnGZL84JuOPs2bOnurNB8aw+IMqNi4tTd5t6BXPUM8Cdmg53YbizLQjbHDzkGujL1yEbVIc0ID24O8MdCl7nV7dLz5FCbiFyI1DvBlmr+npYQq4Dikt1uOsFfA/gTmTVqlUqKxx3hJb04rWCbMOCstwOuJvGspBGy+WhOAfrirtvNGKwl8b8YLsjdwF3OzrkCmG/4q7btsgVd0qW6SoofB/uZnDHo8PdEO6SkNOGHAZLuIPJ6w7TdrmA5Vgqjq5ncHeJ4h/kwljubxRhYNvZ3qXhjhTHgu0ysC9x/FkuA3f/uMvEcVeQY9XZ61eQtCF3B9tDp+cQ4Q4dOfiW03FnilwWSyhNsMxpRs7TwIED1d3y2bNnC5Ume8dNQc8PzmCbDnwncqaR24EcSH09kLOBYwS5ofr2Qc4HcmAwzVmwvZBboUPOJra3fhxhW6I4HrmRKA7U4dyP3DrkfNlW+0CuBbatLfwWkFOjQ84G1gk5Xpa5iPq45bFseY5BUTi2D4pk8fmi7CscT7iGIbcXxa06R48vnGdwTFvm9mDd9etYYSEnCb8NnK8sz+PYttg/tlVynM1yeyPHGuuOUi1w1m8DOcU7duxQ10u9uBq50fgt4vdgud3xPqo+2J5LkYuOXLWiXFNscz5jY2PVZy2/H/sUx6Xt9wNyfi3huLE8dp1xfUDpB0oIUBKnQ04ejgdbOFeixA8lkzrksqMqA+KmvPgjwMHKI6sXgz0oW9ezbvEDtA0q8KMuCOxUSzgZ4YC3rEeALFKUba9ZsyZXJU8EQZYXG1sovkSWLOrY4MRhuZFt2QZ1+gVWL6fXdyrqHeSlINuwoFDU+/rrr8vWrVut6lpa7gPsdGw/1JsqDOxX2yIdy2IJvG+5/va2Y0G/D8eAbbBq+X2WHP0+fA7LtLy4Feb4dAQuyDgOLYsx8tvf9tYBy0D1gryCW9tlXOtYdaaipk3/feIEZG+6bZrtnVeuu+469RfnBZzcC5qmvI6bgpwfnMF2uSimwo0iirww5LUuOPmjaAfFjdgW+A2iiw8U+RS2ONrevtKPJX2f4HyGc6693w1+o7hYo6gWVXTyWkcdim5t9yuOAUeOCxTrofgbRegIiLMzMLPllwmQHwT7CDQQ0CHwsGwo4ujxhfMMgmFcyJ15ntHPe7bLwQ0LAnHb86Kz4cYExc+oZmT7Wyrs9raEKgTYl/irB5b6dse+tY0LdLbF3vhd2FY7Kug1xdKBnJsrFLfag+DbEoIw22PE8vfjrOsD0oxrme3vB+dKW8gcwI0Dgj5kBOG7ETugClZ+mUD+euVW3KnnVYehKCcbR9gmEAEN6hrWr19f3n33XXWywA5HlI96B/m1OkW9DpT74+4VlVWxAxDJ40RiGR3r7N21guXJ5lqKaxuuXr1aRf+oB4E7VZx08GPAjwh1AYxSlNw/d/g+R/c5ji384OyxPUHYWwcsA3eIqGNljx4AOfNYdZSz0ubMNBc0Tfa2eUHPD3mdr+yl37YSeF7p0M8XqAtpe9dve5LHbx/pWrRokcqVQ/1FnANnzJiRq06bo4rjOMrrN1qU4wI5ajjX4cLWtm1bFSRi2yNHsbBdvGCfI1MBuW16Y5XCHl+eBoEx6jxiGyF3FAEutgluOorapQ7q16IeG45Z2xJDLBv7FXXm88pFLs7rgSln3VAP0F4jGssSjPyOXWdfHwoCASjq2uoBIOr+IcMIMUl+/PXWkjh5Ias7PzVq1JCdO3eqH6ll0IYKjAWB6Ngy4sUdMTaYXtESjSuQeLSIs7xbtZcVawsrjrsl3N1ZprGw/dDpRSBY77wUZBsWBLLJcbeBisqWd6o4KVrCXQK2H4pqbRu5WMrrTgD71d4+RA6J/r4zYXm400aaLe/Yivp9+ByWiQum5V10QY9PR2Cb4yKCivyF/fFiGSiecOYx40iRvyPzF0fa8qPnilmmB5XNQT8vOCNNjp4f8tuOONnaK3Z3NIdGP6fgZs6RdUGjERR5YcD6IyhEY4HCBoDXgvMZqvbkdU7Ab9Y2B684YF/hhhq5tZZFk4XtgBg5W2jIgcFesZijxxfOM8uWLVPzWgYnjp5n8jsP68uxLHpHsTAaEBTnbxG5V1gn5AAigNDZq3pQ0HMMcpT1Ine9lwLb7Y7fPmKCwgbZRbmm1MkpMULA5qxt7IzrA9KMa7rteRHnSntQDIzSAjQYQiCIRoyWufT2+CKaRR0VBBv2ghzLpsU9evRQrQwtuyFBUUFexZ55sT0I0NoH0LLHMsK2zfK3DXzssfdZlI3jrq+wJ0OccNFqEa3kLOnfUZBtWBBYLna8Zc4CisNQ588ScjNw0KO4yPZOzXI7oKWhvZMn9ivu0Cy3EVogYb/i4lvYouW84PtQDwetliyLZnAc4ISaX52F/OjHD1rYWbJtHeoMejESWkTbwro4cpHCMrDNEeDbwuexnILCPtY/7+j89uYtjrTlB+cVtKTUoY4ZegXARUO/K3dGmhw9P+gtTO1tG5zccWGx/F1v27ZNVVtxBC40aLGIojC08LNluVzLLjgAvw/kDha0662CwDZCzwHIdbSsloPeAlDygLrCtsVixZUO21xJnCPyymnND87LCJiRI5JXi1BHjy+cvzBu2S0Z0qRfxwr7G0XwgZIunL8s1xut1HH9c6Q3g8Ky97vI69xZkHMMtgtybBHE4vpor8cItCzG9yP4tP1+vLb9DTj7mtK1a1d1POPJT5ZVQopy/XbG9QHpQtUHy66hcAOETs7zuv6hVTZaMaPO47Vy/0Dlbb755psqdw31wFDBEBd81AdAxU9EsXq/XXgPzZgRaaIfHhRJItu0IM3xAXczKNpE1jJ+cHq3Hei3B3DywYGCRhVoFo07Law0Tpz2TpiWkA2Ku3tUKMcPBt+F4hKsE5ZTGPhB4qTXsmVLlX2NOxWcGFEpF3XzCrINCwLpRxE4thO2D+oNIHjGBQB3Ozq8RjcHONhQGRU/KOQY4k4Alev17ktQARUnLdQpxGewPVHvAd1QoFk/DiBUmkWOA+pJYdvhR2tbr6KosA1x8UNRHI4jBJm4qcAFFCccvRuIgkKwgIq8KC7HCRPdwOCuNq87pqLACQXHJrYtjgEcs8jRwR0zKgCj+x7LxlL2oKgFP24cs9gW2D8IvFFJGtsDx5jezYKjsAzAfsQJBCdWy0r49ua3d0wUR9rygzt/dJmEYxbdOuCGCwGH5U2fM9Lk6PkBd+2YhgsK0obfBOrgYUCDMPwusX2RZvwusQzcbdvrE9Me/I5xTmnSpIk6XyDHB+uL8yH6rURACUgDgkWsK9KALmCwrpbdPWC9cU5CbpmzHv2F4wGV45FGVNxHMRh+swg80cVPScC+wvUFRb/YDnrRrd5VTUHojQZwM4/rjSWcJ7D9HT2+cF1Czg7Om5im91npaD05nKfwu8SFGp/BuVrv8xZdziAQwjkf10jkBuJ8hj4/Hbmg4/qM4AI3VHppmt4PKorU86o7jwAI2wb7FkEQ6tmhygF+H3mdY3DNwbkF5z1sEz0wtITfBRo8odGEbQkefucocscNFY43rDu2JzI0cA3Ad+OmENcLVJcormtKRESEOgeibi2u8VgnZPwgwwfXeOxrbNeSvj7g8/heXNNw04J4Czl7epcutjmxWD7Sjs/g+LJsEJMnvTnwuXPnVBcS0dHRqnl8pUqVVFcFn376qVWzYXSFgm5cQkNDtfLly2vPPvusuWmzo93A7N69W7v33ntVlwJlypTRhg0bppo3W/r555+1pk2basHBwaorkrfeeks1g7dtfm7bJQO6UnjjjTdU0+qgoCDVPPvXX3/Ns4sGNGm3Za/7h507d6puVtBcHGmqV6+eNm7cOKt5HN2GBekG5vPPP1fdQmBd0Pwbzfr17WgL2wfri3mxXbHMpUuXWjVrR5cS2O74vOV2Q3cP2Cf6+rVu3VptN0t6dwvoxsBR9rqB0bfV4MGD1TGErg/QJYZtlwX57aO84Dh65plnVJcp6NKhZ8+e2okTJ5zeDYwO+xbN/0NCQtR2xXqMGjVKdZlxrW2gd0GALlPQlRK2A7YHugKZOnWq6sbgWtvBdr3QHcXTTz+tumXx8fG5Zpcw+R0TRUlbXseKvt3RTYXt9kFXIPjN68e6veOsqNvL0fMD/Pfff2rf4ntstzO6m0B3SHivefPmKu0FOcfov7mBAweq8wTOF1WrVtXuvPNObd68eeZ5Xn/9dfVbxO8Sxxi2C7rF0NdV7y4D34PuSq4F8+EcZQvpRvotbd68WXW9hW40cL7v1KmT2ibX2p/X+t3k9XuwTRu659HPEUgD0oJuZGzT6kg3MHpXG/YGy/OOI8cXXLp0SXvooYdUFz/oKgTjW7ZscbjrlZkzZ6rjB92f2KYd3b5gP+OYQPdETz31lNoWjshvPa/VbcvJkyfN1zisU9++fdV5zN71EF3m4HhFdz75LVu/VtkbbLtSQjdQ6E4I52AM2AY4Hvbt2+fQudiRa0p+li9fro4xrDuugXXq1NEefvhhbePGjde8RuR1TS7q9eHw4cPqPXwe5/QRI0ao7YTvsuxGSbd+/Xr1HroScoQP/leg0JaIyIlwt46cNbRao4JDDhEaLqDuq96RNxF5pmnTpqnWvcjZRU6tJZQcIIcZ1WeQo3ktfBYwEZEbQ9EaivwZ/BF5lhSbZwKjDiCKutHljW3wB6gqhzqP+tOLrsW6fTMREbkV1CkiIs9z9913q55QkKuH+qKov4oGaLbdy6CuJ1oMo+Em6gfbq49pDwNAIiIiIheDhmbo+xMBH1oVo8ERujNCx8+W0MAHjcjQGhqNiBzFOoBEREREXoZ1AImIiIi8DANAIiIiIi/DAJCIiIjIy7ARSBHgsWvocR29jBf0+YhERERkDE3TJCEhQT0ty9lPu3IbmodauXKl6lW/cuXKqmfsBQsWmN9Dj+7ojbtx48aqh3vMg57cT506VaDv0J8wwYEDBw4cOHBwv+HEiROat/LYHEA8wxHPFsZzO207RUxOTlbP6B03bpya58qVK+pZe3j2Ip616Sj9+YInTpwokYejExERUdHFx8dLdHR0oZ897wm8ohsYFM/iodJ4yHRe8BD61q1by7Fjx1THi44eQHi4NjpoZABIRETkHuJ5/WYjEB0OAgSKkZGRRieFiIiIqFh5bBFwQeD5eqNHj5b7778/3zuBtLQ0NVjeQRARERG5G6/PAczIyJB+/fqpFkEff/xxvvNOnjxZZRnrA+oPEBEREbkbr84B1IM/1Pv7+++/r1kPYOzYsfL888/nqkSaHwSWmZmZ6jl+5Nr8/PzE39+fXfoQEZHH8/f24O/AgQOyfPlyKVeu3DU/ExQUpAZHpaeny5kzZ1SrY3IPoaGhUrlyZQkMDDQ6KURERMXGYwPAxMREOXjwoPn1kSNHZOvWrVK2bFl1gb/33ntVVzC//vqryp07e/asmg/vO+Pij06i8Z3IVUJHk1gmc5ZcF3JqEbBfuHBB7be6det6b+egRETk8Ty2G5gVK1ZIp06dck0fNGiQTJw4UWrVqmX3c8gNvOWWW4rcjBwNSxBI1KhRQ+UqkXtAbi2qBOD4CA4ONjo5RERUDOLZDYzn5gAiiMsvti2puJe5SO6F+4uIiLwBr3ZEREREXoYBIBEREZGXYQBIZmikkt+AupMFtWvXLrnnnnukZs2aahnTpk1zqP4m5o2NjTVPO336tDRp0kQ6dOig6mwQERFR4XlsHUAqOHRZo/vhhx9k/Pjxsm/fPvO0UqVKFapRRe3ataVv374yfPjwQqXr0KFDcvvtt0vDhg3lxx9/lJCQkEIth4iI3Avq67MHjeLBAJDMKlWqZB5H6yj86CynFcYNN9ygBhgzZkyBP799+3bp2rWr3HrrrfLVV1+pjpqJiMjzbTl+RSb8vEveuqepNKjsnS11ixOvpiV8J5OSUfJPBAkJ8HPqHdS1cgIffPBBmTFjRpG/57///pMBAwao4YMPPuBdIBGRl0jNyJKRP26TQxeSZObqw/Juv+ZGJ8njMAAsQQj+Go5fUuLfu/vVrhIa6LxdjQ618+OsPpXuuusu6d+/v3z44YdOWR4REbmH95buV8FfhfAgGX9nQ6OT45EYAFKBxcTElMj39O7dWxYsWCCrV6+W9u3bl8h3EhGRsTYduyyfrj6sxiff1UQiQ/lozuLAALCEi2KRG2fE9zpTSRUBf/LJJzJq1Cjp3r27/P7776oFMBERea6UdBT9bhc8q+HullWlc8Moo5PksRgAliDUYXNmUaxRSqoIGNvr008/VU/n6NGjh/z222/SsWNHpyybiIhcz9Q/98mRi0kSFREkE+5sZHRyPJr7RyPk0kXA6enpsnv3bvP4qVOnVACJXERHloMgELmJfn5+5iDQ0Wc1ExGR+1h/5LJ88e8RNf7m3U2ldGiA0UnyaOwImooVOnBu0aKFGtDP4NSpU9X4Y4895vAyEAROnz5dBg8eLHfccYcsX768WNNMREQlKzk9U0bN26aKfvteX0061a9odJI8no+GvkmoUOLj41V/eXgyhW2xZ2pqqhw5ckRq1aolwcHBhqWRCob7jYio5E38eZd8+d9RqRQRLEuGd5DSIQGGXb+9BXMAiYiIyDBrD19SwR+8dW/TYg/+KBsDQCIiIjJEUlqmvDBvmxq/v3W0dLyugtFJ8hoMAImIiMgQby3eKycup0jVyBB5sUcDo5PjVRgAEhERUYn77+BF+XrNMTWO5/2GB7PotyQxACQiIqISlaiKfrer8QFtqku7uuWNTpLXYQBIREREJeqN3/fIqdgUqVYmRMay6NcQDACJiIioxKw+cEHmrDuuxt++t6mUCuIzKYzAAJCIiIhKREJqhozOKfod1LaG3FSHRb9GYQBIREREJWLSb3vkdFyqVC8bKqO71zc6OV6NASAREREVuxX7zsv3G06Ij4/I1L7NJDSQRb9GYgBIVs/czW+YOHFigZe5a9cuueeee6RmzZpqGdOmTbM7H571i3nw+LU2bdrI+vXr810u0tK8eXOraatXr5bIyEh57rnnhE84JCJyHXEpGTLmpx1q/OGbakrrWmWNTpLXYwBIZmfOnDEPCNTwfETLaSNHjizwMpOTk6V27dry5ptvSqVKlezO88MPP8jzzz8vEyZMkM2bN0uzZs2ka9eucv78eYe/57ffflOfwXKQdgSbRETkGl77dbecjU+VmuVCZVRXFv26Aua/kpllgIaHZCOIyitoc9QNN9ygBhgzZozded599115/PHHZfDgwer1jBkzVED3xRdf5PkZS3PmzFGffeedd2TYsGFFSi8RETnX33vPybxNJ81FvyGBfkYniRgAljAUS2Ykl/z3BoSifNdpiytVqlS+7z/44IMqiHNEenq6bNq0ScaOHWue5uvrK507d5Y1a9Zc8/MoOkauH4LFAQMGOPSdRERUMuKSrxb9PnpzLWlVk0W/roIBYElC8PdGlZL/3hdPiwSGOW1xW7duzfd9FB076uLFi5KVlSVRUVFW0/F67969+X52z549Ksfv888/Z/BHROSCXvlll5xPSJPaFcJkZNd6RieHLDAApAKLiYkRV1CtWjXV6GPKlCnSvXt3qVy5stFJIiKiHH/uOivzt5wS35yi3+AAFv26EgaAJV0Ui9w4I77XiZxZBFy+fHnx8/OTc+fOWU3H62vVPwwPD5e//vpLbr/9dunUqZMsX76cQSARkQu4kpQuLy7YqcYf71BbWlYvY3SSyAYDwJKEenhOLIo1ijOLgAMDA+X666+XZcuWSZ8+fdQ0k8mkXjvSoKNMmTIqCOzSpYvccsstKgisUsWAYnYiIjKb+MsuuZiYJjEVS8nwztcZnRyygwEgFWsRMBp57N692zx+6tQpFUAiF1FfDhpxDBo0SFq1aiWtW7dW3bgkJSWZWwVfC4qBly5dqrqBQRC4YsUKBoFERAZZvPOsLNp6Wvx8feQdFv26LPYDSMXq9OnT0qJFCzWgL8GpU6eq8ccee8w8T//+/dX08ePHq86dESAuXrw4V8OQ/KDbmj///FMVKXfs2FEFmkREVLIuJabJSwuyW/0+0aG2NIuONDpJlAcfjY9MKLT4+HgVeMTFxeUq9kxNTZUjR45IrVq11NMtyD1wvxERFd7QOZvlt+1n5LqoUvLL0+0kyN/P7a7f3oI5gERERFRkCPwwZBf9NnfZ4I+yMQAkIiKiIkGDj3GLslv9Dr2ljjSpVtroJNE1MAAkIiKiQkNNsnELd8rlpHSpXylcht1a1+gkkQMYABIREVGh/bL9jPyx86z4o+i3XzMJ9Gdo4Q64l4iIiKhQziekyvicot9ht8ZIoyos+nUXDACJiIioUEW/Ly3YKbHJGdKwcoQM7eQajwklxzAAJCIiogJbuPWULN19TgL8sot+A/wYUrgT7i0iIiIqkHPxqTLx5+ynPD17W11pUNk7+9JzZwwAiYiIqEBFvy/O3yFxKRnSpGppebJjHaOTRIXAAJCIiIgc9tPmU7Js73kJ9PNVRb/+LPp1S9xrZObj45PvMHHixAIvc9euXXLPPfdIzZo11TKmTZtmd77p06erefD4tTZt2sj69etzPaJt6NChUq5cOSlVqpRa5rlz5/L97ltuuUWee+45q2n/93//J0FBQfL9998XeF2IiLzdmbgUeeWXXWr8udvrynVR4UYniQqJASCZnTlzxjwgUMPzES2njRw5ssDLTE5Oltq1a8ubb74plSpVsjvPDz/8IM8//7xMmDBBNm/eLM2aNZOuXbvK+fPnzfMMHz5cfvnlF/nxxx9l5cqVcvr0abn77rsLlBYs/8UXX5RFixbJfffdV+B1ISLy9qLfMT/tkITUTGkWHSlD2tc2OklUBP5F+TB5FssADQ/JRo5dXkGbo2644QY1wJgxY+zO8+6778rjjz8ugwcPVq9nzJghv/32m3zxxRfqM3hY9+effy5z5syRW2+9Vc0za9YsadCggaxdu1ZuvPHGa560nnnmGfn2229l6dKlctNNNxVpnYiIvNHcjSdk5f4LqqPnd/o2ZdGvm/PYvbdq1Srp2bOnVKlSRQUyCxcuzBUUjB8/XipXriwhISHSuXNnOXDgQLGmCd+ZnJFc4gO+15lQBJvf8OSTTzq8rPT0dNm0aZPa/jpfX1/1es2aNeo13s/IyLCap379+lK9enXzPHnJzMyUBx98UObNm6dyDhn8EREV3KnYFHnt1z1qfGSX6ySmIot+3Z3H5gAmJSWposRHHnnEblHh22+/Le+//7589dVXUqtWLRk3bpwqdty9e7eqh1YcUjJTpM2cNlLS1j2wTkIDQp22vK1bt+b7PoqOHXXx4kXJysqSqKgoq+l4vXfvXjV+9uxZCQwMlMjIyFzz4L38zJw5U/3dtm2bChqJiKgwRb/bJTEtU1pWj5RH27Ho1xN4bADYvXt3NeR1MKOO28svvyy9e/dW077++msVUCCnkPXD8hcT4z69vbdr104FrAjwv/vuO/H399hDnoioWHy3/oSsPnBRgvx9ZWrfZuLn62N0ksgJvPJqeOTIEZVzZFmkiDpvaH2KIsXiCgBD/ENUblxJw/c6E4p584MiV9Tjc0T58uXFz88vV4tevNbrH+IviopjY2OtcgEt58lLkyZN5J133lH7un///qrBCYNAIiLHnLicLJN+y+7weVS3+lK7Qv7nf3IfXnkl1IsN7RU75lekmJaWpgZdfHx8gb4XdRGdWRRrFGcWAaNo9/rrr5dly5ZJnz591DSTyaReDxs2TL3G+wEBAWoaun+Bffv2yfHjx6Vt27bX/I7mzZurzyII7NevnwoCsTwiIsqbyaTJ6J+2S1J6ltxQs4wMvqmm0UkiJ/LKALCwJk+eLK+88op4u4IUASPnDvUq9fFTp06pABK5iPpy0AXMoEGDpFWrVtK6dWtVPI86nHqrYOTOPvroo2q+smXLqgDz6aefVsHftVoA61Af9O+//5bbbrtNBYFz585lEEhElI/Z647Jf4cuSXCAr0y5t5n4sujXo3hsK+D86MWG+RU72jN27FjVJYk+nDhxotjT6u7QX1+LFi3UgL4Ep06dqsYfe+wx8zwomsV0tMpGbh0CxMWLF1vl0L733nty5513qhzADh06qP00f/78AqUFxcEIAv/77z/p27evCkiJiCi345eS5Y3fsxvije5WX2qWDzM6SeRkPpqz+whxQSh6XbBggbmIEauM7mHQsfGIESPMxbkVK1aUL7/80uE6gPgMcqcQDNoWe+LJFahriBbGxdWqmJyP+42IvB2Kfu+fuVbWHbksbWqVle8ev9Hjcv/i87l+ewuPLQJOTEyUgwcPml/joo6cJRQhov84PCLs9ddfl7p165q7gUFQqAeJRERE3ujrNUdV8Bca6MeiXw/msQHgxo0bpVOnTubXqD8GqGuGXL5Ro0apemZDhgxRrUvRXQiKHZnrQ0RE3uroxSR5c3F20e/YHg2kejn3b7hIXhYA3nLLLfk+AQPFwq+++qoaiIiIvF2WSZORP26T1AyT3FSnnAxoXd3oJFEx8spGIERERGRt1r9HZOOxKxIW6Cdv3dOURb8ejgEgERGRlzt0IVGmLNmnxl+6o6FEl2XRr6djAFjMvKCRtUfh/iIibyz6feHHbZKWaZL2dcvL/a2jjU4SlQAGgMVE72Q4OTnZ6KRQAej7i51EE5G3+Pyfw7L5eKyEB/mrol/UkSfP57GNQIyG59viubXnz59Xr0NDQ/mjcvGcPwR/2F/Yb9h/RESe7uD5BJn65341Pu7OhlIl0rnPjifXxQCwGOlPFdGDQHJ9CP7yexoMEZGnyMwyyYgft0t6pkluqVdB+raqZnSSqAQxACxGyPGrXLmyesJIRkaG0cmha0CxL3P+iMhbfLr6sGw7ESvhwf7y5t0s+vU2DABLAIIKBhZEROQq9p1NkGlLD6jxCT0bSaXSfAiCt2EjECIiIi+SkWVSHT6nZ5nktvoV5Z6WVY1OEhmAASAREZEXmbHikOw4FSelQwLkjbubsOjXSzEAJCIi8hJ7zsTL+39nF/2+0quRREWw6NdbMQAkIiLykqLfEXO3SUaWJl0aRknv5lWMThIZiAEgERGRF5i+/KDsPhMvZUIDZNJdLPr1dgwAiYiIPNzOU3Hy4d8H1firvRtLhfAgo5NEBmMASERE5MHQ0TNa/WaaNOnRpJLc2bSy0UkiF8AAkIiIyIN98PcB2Xs2QcqGBarcPxb9EjAAJCIi8lDbT8bKRysOqfFJfRpL+VIs+qVsDACJiIg8UFpmlmr1m2XSpGezKtK9CYt+6SoGgERERB5o2l8H5MD5RJXr92qvRkYnh1wMA0AiIiIPs+X4FflkZU7R712NpUxYoNFJIhfDAJCIiMiDpGZkqVa/Jk2kT/Mq0rVRJaOTRC6IASAREZEHeXfpfjl0IUn19TeRRb+UBwaAREREHmLTscsyc/VhNT75riYSGcqiX7KPASAREZEHSElH0e920TSRe1pWk84No4xOErkwBoBEREQeYMqSfXLkYpJERQTJ+J4NjU4OuTgGgERERG5u3eFLMuu/I2r8zXuaSumQAKOTRC6OASAREZEbS07PlBfmZRf99m8VLZ3qVTQ6SeQGGAASERG5sbf+2CvHLydLldLB8tKdDYxODrkJBoBERERu6r9DF+WrNcfU+Fv3NpWIYBb9kmMYABIREbmhxLRMGTVvuxq/v3V1aV+3gtFJIjfCAJCIiMgNTf59j5y8kiJVI0PkpTtY9EsFwwCQiIjIzaw+cEFmrzuuxqfc21RKBfkbnSRyMwwAiYiI3EhCaoaMzin6Hdi2htwUU97oJJEbYgBIRETkRib9tkdOx6VK9bKhMrpbfaOTQ27KZQJATdPk+PHjkpqaanRSiIiIXNKKfefl+w0nzEW/YSz6JU8IAGNiYuTEiewDm4iIiK6KS8mQMT/tUOODb64pbWqXMzpJ5MZcJgD09fWVunXryqVLl4xOChERkct57dfdcjY+VWqWC5VRXVn0Sx4SAMKbb74pL7zwguzcudPopBAREbmMZXvOybxNJ8XHR2Rq32YSEuhndJLIzblU5YGBAwdKcnKyNGvWTAIDAyUkJMTq/cuXLxuWNiIiIiPEJqfL2PnZRb+PtaslrWqWNTpJ5AFcKgCcNm2a0UkgIiJyKa/8slvOJ6RJ7QphMqJLPaOTQx7CpQLAQYMGGZ0EIiIil7Fk11lZsOWU+OYU/QYHsOiXPDAAhKysLFm4cKHs2bNHvW7UqJH06tVL/Px40BMRkfe4nJQuLy3ILvod0qGOtKxexugkkQdxqQDw4MGD0qNHDzl16pTUq5edzT158mSJjo6W3377TerUqWN0EomIiErEhJ93ycXEdKlbsZQ817mu0ckhD+NSrYCfeeYZFeShL8DNmzerAZ1D16pVS71HRETkDX7fcUZ+2XZa/Hx9WPRLnp8DuHLlSlm7dq2ULXu1hVO5cuVU9zA333yzoWkjIiIqCRcT0+TlhdndoT3VsY40i440OknkgVwqBzAoKEgSEhJyTU9MTFTdwhAREXkyPBVr3MKdqv5f/Urh8vRtMUYniTyUSwWAd955pwwZMkTWrVunfgQYkCP45JNPqoYgREREnuyX7Wfkj51nxT+n6DfIn0W/5AUB4Pvvv6/qALZt21aCg4PVgKJfPCPY2X0EorXxuHHjVP1CdDiN733ttddU0ElERFTSziekyvhF2UW/QzvFSOOqpY1OEnkwl6oDGBkZKYsWLVKtgfVuYBo0aKACQGd766235OOPP5avvvpKdTWzceNGGTx4sJQuXZoNToiIqEQh8+GlBTslNjlDGlaOkGG3suiXvCgH8NVXX1WPgkPA17NnTzVgPCUlRb3nTP/995/07t1b7rjjDqlZs6bce++90qVLF1m/fr1Tv4eIiOhaFm49JUt3n5MAPx95p18zCfBzqcszeSCXOsJeeeUV1eDDFoJCvOdMN910kyxbtkz279+vXm/btk3++ecf6d69u1O/h4iIKD/n4lNlwqJdavzZ2+pKg8oRRieJvIC/q2WB+/j45JqO4MyyaxhnGDNmjMTHx0v9+vXVU0ZQJ3DSpEkyYMCAPD+TlpamBh0+T0REVJTr3piftkt8aqY0qVpanuzIBx6QFwWAZcqUUYEfhuuuu84qCERghlxBtAR2prlz58rs2bNlzpw5qg7g1q1b5bnnnpMqVark+UxiPJXE2TmRRETkvX7cdFKW77sggX6+qujXn0W/VEJ8NBdo9oqGGEjGI488olr7oiGGDv3/oY4eWgY7Ex4vh1zAoUOHmqe9/vrr8u2338revXsdzgHEcuLi4iQigln2RETkuNOxKdL1vVWSkJYpo7vVl6duYe5fSYmPj1exhjdfv10iB1DPcUOXLOj2xd+/+JOFeoW+vtZ3WigKNplM+XZUjYGIiKgokOkx+qftKvhrHh0pj7evZXSSyMu4VF5zUlKSaphha8mSJfLHH3849bvQwhh1/n777Tc5evSoLFiwQN5991256667nPo9REREtr7fcEJWH7goQf4s+iVjuNQRhyJZ1PmzW0l2zBinftcHH3ygun753//+p/oaHDlypDzxxBOqM2giIqLicuJysrz+6241PrJLPalToZTRSSIv5BJ1AHV4Igc6gEadP0vIoUNDDeQQuhLWISAiooIwmTR58PN18t+hS9KqRhn54Ym24uebu/cLKl7xvH67Vg4gdsbhw4dzTceTQcLCwgxJExERkbPMXndMBX/BAb4ypW8zBn9kGJcKAPFkDnTFcujQIavgb8SIEdKrVy9D00ZERFQUxy4lyRu/Z/cyMaZbfalVnhkbZByXCgDffvttldOHzpnRIhgD6ueVK1dOpk6danTyiIiICl30+8KP2yUlI0va1CorA9taV3Ui8spuYCyLgPGM3qVLl6qnf6BOYNOmTaVDhw5GJ42IiKjQvvzvqKw/ellCA/1kyr3NxJdFv2QwlwoAAU8B6dKlixqIiIjc3eELifL2kuyi3xd7NJDq5UKNThKR6wWAaOm7cuVKOX78uKSnp1u998wzzxiWLiIiooLKMmky8sdtkpphkptjysmANtWNThKR6wWAW7ZskR49eqindCAQLFu2rFy8eFFCQ0OlYsWKDACJiMitfP7PYdl8PFZKBfnL2/c2s3rWPZGRXKoRyPDhw9UTOq5cuaLq/61du1aOHTsm119/PRuBEBGRWzlwLkGm/rlfjY+7s4FUjQwxOklErhkAbt26VXX5gmf04rm8aWlpEh0drVoHv/jii0Ynj4iIyCGZWSZV9JueaZKO11WQfq2ijU4SkesGgAEBASr4AxT5oh6g3jr4xIkTBqeOiIjIMZ+sOizbTsZJeLC/vHlPExb9kstxqTqALVq0kA0bNkjdunWlY8eOMn78eFUH8JtvvpHGjRsbnTwiIqJr2ns2Xqb9lV30O7FnI6lcmkW/5HpcKgfwjTfekMqVK6vxSZMmSZkyZeSpp56SCxcuyKeffmp08oiIiPKVkWWSEXO3SUaWJp0bVJS7W1Y1OklErpkD+PPPP0v37t1V8W+rVq3M01EEvHjxYkPTRkREVBDTlx+UXafjpXRIgLxxF4t+yXUZngN41113SWxsrBpHw4/z588bnSQiIqIC23kqTj78+6Aaf7V3I6kYEWx0kohcNwCsUKGC6u4FNE3j3RIREbkdtPZFq99MkybdG1eSXs2qGJ0kItcuAn7yySeld+/eKvDDUKlSpTznzcrKKtG0EREROeL9ZQdk79kEKRsWKK/1aczMDHJ5hgeAEydOlPvuu08OHjwovXr1klmzZklkZKTRySIiInLIthOx8vHKQ2p8Up/GUr5UkNFJInL9ABDq16+vhgkTJkjfvn3Vo9+IiIhcXWpGlir6xTN/ezarIt2bZPdkQeTqXCIA1CEAJCIichfv/bVfDpxPVLl+r/ZqZHRyiNynEQgREZE72nTsisxcdViNT767iZQJCzQ6SUQOYwBIRERUQCnp2UW/Jk1UZ8+3N4wyOklEBcIAkIiIqIDeXrJXjlxMkqiIIJnQk0W/5H5cNgBMTU01OglERES5rD18SWb9e1SNv3VPU/XUDyJ341IBoMlkktdee02qVq0qpUqVksOHs+tWjBs3Tj7//HOjk0dERF4uKS1TXpi3TY3fd0O03FKvotFJInL/APD111+XL7/8Ut5++20JDLxambZx48by2WefGZo2IiKiyX/skROXU6RqZIi8dEcDo5ND5BkB4Ndffy2ffvqpDBgwQD0XWNesWTPZu3evoWkjIiLv9s+Bi/Lt2uNq/O17m0p4MIt+yX25VAB46tQpiYmJsVs0nJGRYUiaiIiI4lMzZFRO0e9DN9aQm2PKG50kIs8JABs2bCirV6/ONX3evHnSokULQ9JERET0+q+75XRcqlQvGypjutc3OjlEnvUkkPHjx8ugQYNUTiBy/ebPny/79u1TRcO//vqr0ckjIiIv9PfeczJ340nx8RGZ2reZhAW51KWTyP1zAHv37i2//PKL/PXXXxIWFqYCwj179qhpt99+u9HJIyIiLxObnC5jftqhxh+5uZa0rlXW6CQROYXL3ca0b99eli5danQyiIiIZOLPu+R8QprUrhAmL3StZ3RyiDwzB3DDhg2ybt26XNMxbePGjYakiYiIvNPinWdl4dbT4usj8k7fZhIccLV3CiJ351IB4NChQ+XEiRO5pqNOIN4jIiIqCZcS0+SlBdlFv0M61JEW1csYnSQizw0Ad+/eLS1btsw1HS2A8R4REVFx0zRNxi3aKZeS0qVeVLgMv72u0Uki8uwAMCgoSM6dO5dr+pkzZ8Tf3+WqKxIRkQf6ZfsZ+X3HWfH39ZF3+jWTIH8W/ZLncakAsEuXLjJ27FiJi4szT4uNjZUXX3yRrYCJiKjYnU9IlfGLdqrxYbfGSOOqpY1OElGxcKlstalTp0qHDh2kRo0a5o6ft27dKlFRUfLNN98YnTwiIvLwot8X5++Q2OQMaVw1QoZ2yv1kKiJP4VIBYNWqVWX79u0ye/Zs2bZtm4SEhMjgwYPl/vvvl4AAPnORiIiKz0+bT8lfe85LoJ+vvNO3uQT4uVQhGZHnBoCADqCHDBlidDKIiMiLnI5NkVd+3qXGn7u9rtSrFG50koi8KwA8cOCALF++XM6fP68eB2cJTwYhIiJydtHv6J+2S0JaprSoHilD2tc2OklE3hUAzpw5U5566ikpX768VKpUSXzw4MUcGGcASEREzjZn/XFZfeCiBPn7qmf9+rPol7yASwWAr7/+ukyaNElGjx5tdFKIiMgLHL+ULJN+26PGR3erL3UqlDI6SUQlwqVuc65cuSJ9+/Y1OhlEROQFTCZNRs7bJsnpWdKmVll5+KaaRieJyDsDQAR/f/75p9HJICIiLzDrv6Oy/shlCQ30U0W/vnjoL5GXcKki4JiYGBk3bpysXbtWmjRpkqvrl2eeecawtBERkec4dCFR3l68V42/dEcDiS4banSSiEqUj4bmTy6iVq1aeb6HRiCHDx8WVxIfHy+lS5dWTy6JiIgwOjlEROSAzCyT3DtjjWw9ESvt65aXrx9pbdXokDxfPK/frpUDeOTIEaOTQEREHu6TVYdV8Bce7C9v39uUwR95JZeqA1jSTp06JQ8++KCUK1dOPXUExc4bN240OllERFRM9pyJl2l/7VfjE3s2ksqlQ4xOEpEhXCoHEE6ePCk///yzHD9+XNLT063ee/fdd53a4vjmm2+WTp06yR9//CEVKlRQnVCXKVPGad9BRESuIz3TJCPmbpOMLE1ubxgld7esanSSiAzjUgHgsmXLpFevXlK7dm3Zu3evNG7cWI4ePap6aW/ZsqVTv+utt96S6OhomTVrlkN1EImIyL19+PcB2X0mXsqEBsgbdzVh0S95NZcqAh47dqyMHDlSduzYIcHBwfLTTz/JiRMnpGPHjk7vHxC5jK1atVLLrVixorRo0UI9iYSIiDzPthOxMn3FITX+ep8mUiE8yOgkERnKpQLAPXv2yMCBA9W4v7+/pKSkSKlSpeTVV19VOXbOhBbFH3/8sdStW1eWLFmiHkGHbma++uqrPD+TlpamWg5ZDkRE5NpSM7JkxI/bJMukSc9mVeSOppWNThKR4VwqAAwLCzPX+6tcubIcOpR9twYXL1506neZTCZVrPzGG2+o3L8hQ4bI448/LjNmzMjzM5MnT1bNxvUBRchEROTa3vlznxw8n6hy/V7t1cjo5BC5BJcKAG+88Ub5559/1HiPHj1kxIgR6tnAjzzyiHrPmRBgNmzY0GpagwYNVOOT/Iqo0WeQPqB4moiIXBee9PHZP9ldjL15dxMpExZodJKIXIJLNQJBK9/ExEQ1/sorr6jxH374QRXTOrMFMKAF8L59+6ym7d+/X2rUqJHnZ4KCgtRARESuLyktU0b+uE3wuIN+rarJbQ2ijE4SkctwqQAQrX8ti4PzK44tquHDh8tNN92kioD79esn69evl08//VQNRETk/t74fY8cv5wsVSNDZNyd1iU+RN7OpYqAS9INN9wgCxYskO+++051N/Paa6/JtGnTZMCAAUYnjYiIimjl/gsye112lZ4p9zaV8GDrZ8sTeTvDcwDR8bKjfTFdvnzZqd995513qoGIiDxHXEqGjJ63XY0/fFNNuSmmvNFJInI5hgeAyHUjIiJylld+3iVn41OlVvkwGd2tvtHJIXJJhgeAgwYNMjoJRETkIRbvPCvzt5wSXx+RqX2bSkign9FJInJJhgeAeUlNTc31LOCIiAjD0kNERK7tYmKavLRghxp/omMdub5GWaOTROSyXKoRSFJSkgwbNkw9mg2tgFE/0HIgIiKyB8+Mf3nBTrmUlC71K4XLc53rGp0kIpfmUgHgqFGj5O+//1aPaEN/e5999pnqD7BKlSry9ddfG508IiJyUQu3npLFu85KgJ+PvNOvmQT5s+iXyG2KgH/55RcV6N1yyy0yePBgad++vcTExKjOmWfPns0uWoiIKJczcSkyftEuNf7sbXWlUZXSRieJyOW5VA4gunnRO4NGfT+925d27drJqlWrDE4dERG5YtHvqHnbJSE1U5pFR8qTHesYnSQit+BSASCCvyNHsp/ZWL9+fZk7d645ZzAyMtLg1BERkatBZ8+rD1yUIH9feadvM/H3c6nLGpHLcqlfCop9t23bpsbHjBkj06dPl+DgYPXYthdeeMHo5BERkQs5ejFJJv22R42jv7+YiqWMThKR2/DRkH/uoo4ePSqbN29W9QCbNm0qriY+Pl5Kly4tcXFx7KKGiKgEZZk06ffJGtl07Iq0rV1OZj/WRnzR+R+RA+J5/XatRiC2atasqQYiIiJLn646rIK/UkH+MqVvUwZ/RO5cBAzLli1Tz+etU6eOGjD+119/GZ0sIiJyEXvPxst7S/er8fE9G0q1MqFGJ4nI7bhUAPjRRx9Jt27dJDw8XJ599lk1IGu2R48eqj4gERF5t/RMkwz/YZukZ5mkc4OK0vf6akYnicgtuVQdwGrVqqnGH3gaiCUEf2+88YacOnVKXAnrEBARlawpS/bK9OWHpExogCwZ3kEqhgcbnSRyQ/G8frtWDmBsbKzKAbTVpUsXtZOIiMh7oc7fxysOqfFJdzVh8EfkKQFgr169ZMGCBbmmL1q0SNUFJCIi75Scnikj5m4VkyZyV4uq0qNJZaOTROTWDG8F/P7775vHGzZsKJMmTZIVK1ZI27Zt1bS1a9fKv//+KyNGjDAwlUREZKTJv++Vo5eSpVJEsEzs1cjo5BC5PcPrANaqVcuh+Xx8fOTw4cPiSliHgIio+K3cf0EGfbFejX/zaGtpX7eC0UkiNxfP67fxOYD6o9+IiIhsxSVnyKh52U+IGtS2BoM/Ik+sA0hERGRp/M875Vx8mtQuHyZjujcwOjlEHoMBIBERuaRft5+WRVtPi5+vj7zbv7mEBPoZnSQij8EAkIiIXM65+FR5acFONT70ljrSPDrS6CQReRQGgERE5FLQNvGFedslLiVDmlQtLU/fVtfoJBF5HAaARETkUmavOy6r9l+QIH9fea9/Mwnw46WKyONaAW/fvt3heZs2bVqsaSEiImMduZgkk37bo8ZHd6svMRXDjU4SkUcyPABs3ry56uMPWf74m5+srKwSSxcREZWszCyTPD93q6RkZMnNMeXk4ZtqGp0kIo/l6wr9AKKDZ/z96aefVMfQH330kWzZskUNGK9Tp456j4iIPNeMlYdky/FYCQ/2lyn3NhNf3/wzBYjIjXMAa9SoYR7v27evejRcjx49rIp9o6OjZdy4cdKnTx+DUklERMVpx8k4mfbXATX+Sq9GUiUyxOgkEXk0w3MALe3YscPuo+Ewbffu3YakiYiIildqRpY898MWyTRpckeTynJXi6pGJ4nI47lUANigQQOZPHmypKenm6dhHNPwHhEReZ43/9grhy4kScXwIHm9T+Nr1gcnIg8oArY0Y8YM6dmzp1SrVs3c4hethHEy+OWXX4xOHhEROdnqAxfky/+OqvEpfZtJmbBAo5NE5BVcKgBs3bq1ahAye/Zs2bt3r5rWv39/eeCBByQsLMzo5BERkRPFJqfLyB+3qfGHbqwhHa+rYHSSiLyGSwWAgEBvyJAhRieDiIiK2bhFu+RcfJrULh8mY3vUNzo5RF7FpeoAwjfffCPt2rWTKlWqyLFjx9S09957TxYtWmR00oiIyEkWbT0lv2w7LX6+PvJu/+YSGuhy+RFEHs2lAsCPP/5Ynn/+eenevbtcuXLF3PFzmTJlZNq0aUYnj4iInOBUbIq8vHCnGn/61hhpHh1pdJKIvI5LBYAffPCBzJw5U1566SXx9796N9iqVSvVRQwREbk3k0mTkXO3SUJqpgr8hnWKMTpJRF7JpQJAPA2kRYsWuaYHBQVJUlKSIWkiIiLn+fyfI7Lm8CUJDfST9/o3F38/l7oMEXkNl/rlocPnrVu35pq+ePFi9gNIROTm9pyJlylL9qnxcXc2lFrl2bsDkVFcqtYt6v8NHTpUUlNTRdM0Wb9+vXz33XeqI+jPPvvM6OQREVERnvYx/Ietkp5lks4NouS+G6KNThKRV3OpAPCxxx6TkJAQefnllyU5OVn1/4fWwP/3f/8n9913n9HJIyKiQnrnz32y92yClC8VKG/e04RP+yAymI+GrDYXhAAwMTFRKlasKK4qPj5eSpcuLXFxcRIREWF0coiIXNK/By/KgM/WqfHPBraSzg2jjE4Sebl4Xr9dKwfQUmhoqBqIiMi9n/YxYm720z4GtKnO4I/IRRgeAKLVr6NFAZs3by729BARkXOggOmlBTvlbHyqetrHS3ewMR+RqzA8AOzTp4/RSSAiomLw0+ZT8tuOM+Lv6yPT7uPTPohcieG/xgkTJhidBCIicrLjl5JlwqLsp30Mv/06aVqNT/sgciUu1Q8gERG5v8wskzz3wxZJSs+S1jXLypMd6xidJCJytRzAsmXLyv79+6V8+fLqmb/51Qe8fPlyiaaNiIgKbvryQ7L5eKyEB/nLO/2aiZ8vu3whcjWGB4DvvfeehIeHq/Fp06YZlo4333xTxo4dK88++6yh6SAicmebjl2R9/8+oMZf7dNIosuyNwciV2R4ADho0CC74yVpw4YN8sknn0jTpk0N+X4iIk+QkJqhin6zTJr0bl5F7mpRzegkEZG71QHE4+DQUaPlUBzQ2fSAAQNk5syZqgiaiIgKZ8LPu+TE5RSpGhkir/VpbHRyiMhdAsCkpCQZNmyYevpHWFiYCsgsh+KAZw/fcccd0rlz52JZPhGRN/h522mZv/mUoLofunyJCA4wOklE5MpFwJZGjRoly5cvl48//lgeeughmT59upw6dUoVz6KOnrN9//33qnNpFAE7Ii0tTQ264sqVJCJyJ6diU+SlBTvU+LBOMXJDzbJGJ4mI3CkH8JdffpGPPvpI7rnnHvH395f27dvLyy+/LG+88YbMnj3bqd914sQJ1eADyw0ODnboM5MnT1bPDtSH6Ohop6aJiMjdoL7f8B+2SkJqpjSPjpSnb6trdJKIyN0CQHTzUrt2bTWOhzPr3b60a9dOVq1a5dTv2rRpk5w/f15atmypgk0MK1eulPfff1+NZ2Vl5foMWgnjwdH6gCCSiMibfbT8oKw/clnCAv1kWv/mEuDnUpcVInKHImAEf0eOHJHq1atL/fr1Ze7cudK6dWuVMxgZ6dxe5G+77TbZsSO7yEI3ePBg9b2jR48WPz+/XJ8JCgpSAxERZXf5Mm1ZTpcvvRtLzfJhRieJiNwxAEQAtm3bNunYsaOMGTNGevbsKR9++KFkZGTIu+++69TvQt+DjRtbt1JDw5Ny5crlmk5ERNbiUzPk2e+vdvlyd8uqRieJiNw1ABw+fLh5HK1y9+7dq4pqY2Ji2EcfEZGL0DRNXl6wU05eSZFqZbK7fMnvKU5E5HpcKgD8+uuvpX///uZi1ho1aqghPT1dvTdw4MBi/f4VK1YU6/KJiDwBuntBty94xNv/3deCXb4QuSFfVysCRuMKWwkJCeo9IiIy1tGLSTJ+0U41/txtdeX6GuxAn8gd+bpasYK9YoSTJ0+qbleIiMg46Zkmeeb7LZKUniWta5WV/3WKMTpJROTORcAtWrRQgR8GtM5FNyw6dMeClsHdunUzNI1ERN5u6p/7ZPvJOCkdEqC6fEERMBG5J5cIAPv06aP+bt26Vbp27SqlSpUyvxcYGCg1a9ZUnUMTEZExVuw7L5+uOqzGp9zbVKpEhhidJCJy9wBwwoQJ6i8CPTQCcfTJHEREVPzOJ6TKyB+3qfGBbWtIl0aVjE4SEXlSHcBBgwZJamqqfPbZZ+qpG/qTQPC8XjwTmIiISpbJpMnzP2yTi4npUr9SuLzYo4HRSSIiJ3CJHEDd9u3bVf9/aPBx9OhRefzxx6Vs2bIyf/58OX78uOoKhoiISs4nqw7LPwcvSnCAr3z4QAsJDsj9lCQicj++rtYR9MMPPywHDhywKgbu0aOH058FTERE137U2zt/7lPjE3s2kpiK4UYniYg8MQdw48aN8umnn+aaXrVqVTl79qwhaSIi8kZxyRnyzHdbJNOkyZ1NK0v/G6KNThIReWoOIJ4AEh8fn2v6/v37pUKFCoakiYjI26BP1lE/bZNTsSlSo1yoTL67CR/1RuRhXCoA7NWrl7z66quSkZGhXuOEg7p/o0ePZjcwREQl5Os1x2TJrnMS4OcjH97fUsL5qDcij+NSAeA777wjiYmJUrFiRUlJSZGOHTtKTEyMhIeHy6RJk4xOHhGRx9t5Kk4m/bZHjY/t3kCaVONTmIg8kUvVAUTr36VLl8o///yjWgQjGGzZsqVqGUxERMUrMS1Ths3ZLOlZJuncIEoG31zT6CQRkTcEgLp27dqpgYiISq7e34vzd8jRS8lSpXSwTO3blPX+iDyYywSAJpNJvvzyS9XnH/oAxImnVq1acu+998pDDz3EExERUTGas/64/LzttHq+7wcPtJDI0ECjk0REnl4HEHeeaADy2GOPqSd+NGnSRBo1aiTHjh1T/QLeddddRieRiMij6/298stuNT66Wz25vkZZo5NERN6QA4icP3T0vGzZMunUqZPVe3///bf06dNHPQVk4MCBhqWRiMgTJaRmZNf7yzTJbfUrymPtahudJCLylhzA7777Tl588cVcwR/ceuutMmbMGJk9e7YhaSMi8lQofRnzU3a9v6qRIfJOv2bi68vqNkTewCUCQLT47datW57vd+/eXbZt21aiaSIi8nTfrj0mv+04I/6s90fkdVwiALx8+bJERUXl+T7eu3LlSommiYjIk20/GSuv/Zrd39+Y7vWlZfUyRieJiLwtAMzKyhJ//7yrI/r5+UlmZmaJpomIyFNdSUqXp77N7u+vS8MoebRdLaOTRETe2AgE9VDQ2hfPArYnLS2txNNEROSJTCZNhs/dan7O75S+zdjNFpEXcokAcNCgQdechy2AiYiKbvryg7Ji3wUJ8veVjwdcL6VD+JxfIm/kEgHgrFmzjE4CEZHH++fARXn3r/1q/LU+jaVhlQijk0RE3lwHkIiIiteZuBR55vstomki/VtFS79W0UYniYgMxACQiMjDpWVmyf9mb5bLSenSsHKEvNK7kdFJIiKDMQAkIvJwr/26W7Ycj5WIYH/5+MGWEhzgZ3SSiMhgDACJiDzYjxtPyLdrjwsa+v7ffS2kRrkwo5NERC6AASARkYfaeSpOXlq4U40/d9t10ql+RaOTREQuggEgEZGHdvb8xDebJD3TJLfVryhP3xpjdJKIyIUwACQi8jBZJk21+NU7e363f3Px9WVnz0R0FQNAIiIPM2XJPll94KKEBPjJjAfZ2TMR5cYAkIjIg/y87bTMWHlIjb91b1NpUJmdPRNRbgwAiYg8xK7TcTJq3jY1/mTHOtKrWRWjk0RELooBIBGRB7iUmCZDvt4kqRkm6XhdBXmhaz2jk0RELowBIBGRm8vIMsmwOdmNPmqWC5X372shfmz0QUT5YABIROTmJv22R9YcviRhgX4yc2ArKR3KRh9ElD8GgEREbmz2umPy5X9H1Ti6e6kbFW50kojIDTAAJCJyU/8duigTFu1S4yO7XCddG1UyOklE5CYYABIRuaGjF5PkqW83S6ZJk97Nq8jQTnzSBxE5jgEgEZGbiUvJkEe/2qD+NouOlLfuaSo+Pmz0QUSOYwBIRORGMrNM8vR3W+TQhSSpXDpYZj50vQQH+BmdLCJyMwwAiYjchKZp8sovu2XV/gsSHOCrWvxWjAg2OllE5IYYABIRuYkv/j0q36w9Jijtnda/uTSuWtroJBGRm2IASETkBv7cdVZe/223Gn+xewPp1riy0UkiIjfGAJCIyMVtPxkrz36/VTRNZECb6vJY+1pGJ4mI3BwDQCIiF3bySrI8+tVGScnIUs/4faVXI7b4JaIi8+oAcPLkyXLDDTdIeHi4VKxYUfr06SP79u0zOllEREpccoY88uUGuZCQJvUrhcuHD7QQfz+vPm0TkZN49Zlk5cqVMnToUFm7dq0sXbpUMjIypEuXLpKUlGR00ojIy6VmZMnj32yU/ecSJSoiSL54+AYJD+YzfonIOfzFiy1evNjq9ZdffqlyAjdt2iQdOnQwLF1E5N2yTJo8P3errD9yWcKD/OWrR1pLlcgQo5NFRB7EqwNAW3Fxcepv2bJl7b6flpamBl18fHyJpY2IvKevv9d+3S2/7zgrgX6+8snA66V+pQijk0VEHsari4AtmUwmee655+Tmm2+Wxo0b51lnsHTp0uYhOjq6xNNJRJ7tk1WH5cv/jqrxd/o1k5vqlDc6SUTkgXw03G6SPPXUU/LHH3/IP//8I9WqVXM4BxBBIHIOIyJ4h05ERTNv00kZ+eM2NT7uzobyaDt290JUHOLj41VGjjdfv1kELCLDhg2TX3/9VVatWpVn8AdBQUFqICJytiW7zsron7ar8cfb12LwR0TFyqsDQGR+Pv3007JgwQJZsWKF1KrFEy4Rlbx/D16Up+dsUY0/+l5fTV7s0cDoJBGRh/PqABBdwMyZM0cWLVqk+gI8e/asmo5s4ZAQtrgjouK39USsPP71RknPMkm3RpVk8t1N2NEzERU7r64DmNdJdtasWfLwww9f8/OsQ0BERbH/XIL0+2SNxCZnSLuY8vL5w60kyN/P6GQRebx4Xr+9OwfQi2NfIjLYkYtJ8uBn61Tw1zw6Uj556HoGf0RUYtgNDBFRCTt+KVkemLlWziekSb2ocPly8A0SFuTV9+NEVMJ4xiEiKkEnryTL/TPXypm4VImpWEpmP95GIkMDjU4WkbFQIpdyRSThTM5w9urfet1FYjobnUKPwwCQiKiEnIlLkQdmrpNTsSlSu3yYzHmsjZQvxa6lyMMDu9RYkYRzVwO6xLPWAZ7+Nyvd/jJCyzEALAYMAImISsD5+FQV/B2/nCw1yoXKnMdvlIoRwUYni8g5gV2iRYBnHnKmZ6Y6vtyQsiIRVUTCK+UMlUVqti/ONfFaDACJiEoo5w8NP6qVCVHBX6XSDP7IBZlMIimXLXLqztn8zRkKGtgFR2YHc+bArpJIqUoiEZWvTi8VJeLPHPGSwgCQiKgYnbicLA98tlZOXE5Rwd93j98oVSPZzyiVsKxMkaTzV4M3lWNnJ6hLPC9iyihgYGcR0Om5duFR1oFdAI95V8MAkIiomBy9mKRa+56OSzUX+zL4I6dKT8oJ3s5b5NTpAZ5FsJd0EeW2ji8X9e5UQJcTyCGIswr0ohjYuTkGgERExeDg+UQZ8NlaORefJnUqhKngL4p1/sgRpqzsgE3PkUNgZ86xs5x2XiQ90fHl+viJlKp4NZhT45VyB3ZhFUX82TLd0zEAJCJysp2n4uThWevlYmK66ufv28faSIVw1m3yaqrRRFxO8IYcufNXx/W/eoCXfFFEMzm+7IDQ3EEd/trm1iFXz5edjVM2BoBERE609vAlefyrjZKQlimNqkTIN4+2kbJhzE3xWGmJFsGcHtxdyAns9L8507PSCrBgH5GwCjmBXU4AZw7uMF3PtasoEhRejCtInooBIBGRkyzZdVae/m6LpGeapE2tsjJzUCuJCA4wOllUmHp1ekCnB3fmoM5y/IJIRlLBlh1UOieAQ1FrBZtcu6irwR1y6/x4iabiw6OLiMgJfthwXMbO3yEmTaRLwyh5//4WEhzA4jaXKX5NS8gJ3GyDuvM20wsR1KEIVs+tU8Fcxex6dHp9O3065gkMLa61JCoQBoBEREWgaZpMX35Qpv65X73u3ypaJt3VWPz9+Kj1Ym8ogUeHWQZx+Y0XpM868A/Jzo0zB3KWQV1OYKcHfUGlimstiYoNA0AiokJCUe9LC3bIj5tOqtdPdqwjo7vVEx8fH6OT5p7Sk7MbQCAXLimPQX+voA0lICDMOqhTAZzlX4sAL7CUCPcjeTAGgEREhRCXkiFPfbtJ/jt0SXx9RF7p1UgealvT6GS5lqwMkeRL2V2aqABO/3vB+jWCOYwXpEsTXUiZ7MBNBXF6cIe/FWymo/g1rDjWksgtMQAkIirE0z0Gf7lB9fUXFugnHz7QUjrVryheUeyafNkiaEMQdynv1yiiLSi/IOugDYPqlDgnhy6sfM6QM+7HRjZEhcEAkIioADYcvaxy/tDHX6WIYPn84VbSqEppcfscOj0XLq/XCOpUQFeAp0mAj292AKcHcnpQp4ZyV3PpVFBXIbtLExa9EhU7BoBERA429pi97rhM/HmXZJo0aVA5Qr54uJVULh3iWt2X6EGbOZDDuB7I5YzrAR46Ji4MVeyKgE7PjSufPa5y6XLG9Vy6kEh2PkzkghgAEhFdQ1pmlkxYtEu+33BCvb6jaWWZcm9TCQ0sxlNoVqZIyuWrwZw5oLOcZhnYXRLJTCnEF/mIhJa9GrSZc+n0QK6cRUBXQSSkLPunI/IA/BUTEeXjXHyqPPntJtlyPFaVTI7qWl+e7Fi7YC19VZclsbkDOnMwZzv9kkhqbOES7BeYHbCpQM4ieMNrNS0nsNPHkZvHHDqvztnGP5NmshpXry3HNU1MYjHuwPv4Z3e8gMuuWbqm1C5d2+hN5XEYABIR5WH1gQsy/Ietqr5fRLC/6tz5lpiy2Tlx5mDusvV4rteXCld3TocATQVvehBX1iKQK2fxXtnsaQ50X2J9Uc4SU2aG1UVXhQE2F2tnX/ShqMvJFbBcK0ixmdfeew4FLIUIjKz+OrLOltu9CMHTtb4H87q6/zX/nzzV7Cmjk+FxGAASeaiC3tlf62Ka7wVSTCq+KcidPjhykSrIhdlqmZZBjL3PmEyiZaWJKSNFTJnJomWkiJaZql5nZaTKhdg4SUhKkpYR6RJSJlPC/E2y9O90WfJXBtZWXTbx1+Tjc3U8Z9tjmprHX8RU2k9MpStkz+PrLyYUn+Kvb4Aa13z8xOTnJyYfP9F8/bJf+/qK5uObvRyr/XJZtIxLYorbJ6bYvC/4loFcXtueqDB88M/HR3x9fEX98/G1eq2PYz41Led9/PPz8bs677XmsVh2VGiU0avtkRgAuqm87uRyXTzzuTt05MKa6641r5yBvL7D9u7V5jugKEFJXmlwpcDnWmm41sU6VxryWn83vLN3+bNjrsa9gTlDUWVmD1kWL12c5YXZ8iKuv8ag5sm5qKu/vhbv5wQOeS3H3ufwWn23r1+u4MIy6EA1RtsAwzK4sPyMs77fctmQ13IsX+f3/ZbbCd+X13bMa90sAyl7y8Y2wndbpdFmefYCNatl56wDeQYGgC7osx2fqcE26FCBBu/gqRjldcK3d1Gwveu3DQDMF8+cz+V1h48Lk/luXzTxMWWJnylL/fVVfzPFx5QhfviblSm+WRnqtW9Wuvhk5vzFe0g/Bk0zj6u/mmYex+Cn4a/FPLgo+gerIU0LlHN4GIUpUDJ9gqV6VDmpVK6s+PiHim9gmPgE4m8p9ZgwP78AuzkfeV3sc62rHhQV4YKvL8Ne4OLIcvR9nisosBNsEZFnYQDogjKyMiSpoA8jvwZ7FwyrC7nNBQzs3QXaXtzzvOu0uJu1nd+2+EC/M80rLfrda35FDPnehdvc6VpemO1dgHMFLnldzG3WP1cRh9i/4FsGRHkFDo7chec1T17rml+Og/45pzCZRNLicho9XMluzIC/+mvzNIvX+lDQ57Vawj4JjsyuC4d6c2itqurP6a/LWLwue/VvYJjEp2Wq7l3mbz6lFtWoSoTq3LlWeT45gog8EwNAF/RAgwfkztp35grILAMV2+Aq1wXfZh7ewVOBg7j0hOwgTQ/WbP/aBnLm99G3XBGKn338rAM2NUTmDuhUsGcR6AVFiPhm/1YK4t+DF+WFH7fJ6bhU9Ui3JzrWkec615Ugf7aMJSLPxQDQBZUOKq0GoiL3I5cWfzU4Q2BmFcjF2Qnucqbhb1GrGgSEZgdplkGcOWjLCeBsgzsVyJXMkyASUjNkypJ98vWaY+p1jXKh8k7fZtKqZtli/24iIqMxACRy9Vw4c+AWZzHYvLb3fnpi0dOA57JaBm+5/uoBnB7Q6eOlRfyDxFUt3nlWFfmejc8uch7Qprq82KOBhAXxlEhE3oFnO6LifM5qanx2MIacOBWY6X/j7E8zv5cz3RktedFowRy0lc49jr9WgZ3FPAEu9JgzJzgTl6Ke6PHn7nPmXL/X+zSW9nUrGJ00IqISxQCQKL/iUxWk2f7NCc70IM3ue/EiGcnOSYt/cHb9NnNwZjnYTLMK7DBEiPgFiLfDo9y+/PeofPD3QUlMyxR/Xx8Z0qG2PHNbXQkOYF0/IvI+DADJs2iaSEZKTvCWYBGc5Yzjrx6g2Q3unBy8mXPgSmcHcSo40//q0zDogVvOuB7w4W9AsPPS4mXQjRJy+974fY8cu5S9T1tWj5Q37m4i9StFGJ08IiLDMAAk16nvhq5v0hJzgjWLgM1qiM97XA/0NL13XSfwD8kOyvRAzeqvTRBnG+DhNQY8+YFK3J4z8fLar7vlv0OX1OsK4UEyqms9uadlNfFFc18iIi/GKxMVMbctOScAQ+AWn93wQA/i0IDB/B5e58yTa1rOfM58cgW6zkFr0sDwq8FZkD4ebhG0IVCzN0/OdH9nPPWBStLhC4ny3l8H5Nftp9UhGujvK4+1qyX/6xQjpdjIg4hI4dnQm+BqmJl2NehKT7oasKlgLdH+a8xnFazp0xOL3lWIvT7ggkpZBG7hFkOEzd9SFkFbTsCmvx8YViJdiZDrOHklWd5fdkB+2nxKskzZNxN3NKksY7rXl+iyoUYnj4jIpTAAdPVWpHoApgdrKhjTp1kEaObAzWK6vdfOLB61zG1DPTeV44a/luMWAZzta6tpOYEcWp0ycKMCOHIxST5ddUh+2nRK0rOyb0hurV9Rnr/9Omlclf1pEhHZwwDQFa18W2TVFJGs9OL7joCw7FwylduG8ZwcNT2Asw3orN63DN5KZXf4y6CNStj2k7EyY+Uh+WPnWZW5DW1rl5ORXa+T62uwM2ciovwwAHRFyFGzDP78ArODLRWo6X/1oZR1EGcO6izn04M5i8/7susLcj+ZWSb5a895+XrNUXPjDj3H78mOdaR1LQZ+RESOYADoilo9ItLsvuxADTl1bIhAXu5CQpr8sOG4zFl3XD2zF/x8faRXsyryRMfa7NKFiKiAGAC6IjzsXpiTQd4tI8skK/ddkPlbTsrS3eckIyu7nLdsWKD0vyFaPb6tWhk27iAiKgwGgETkUh037z4TL/M3n5JFW0/JxcSrVSGaR0fKwLY1pEeTynx6BxFRETEAJCLDg76dp+Ll951n5I8dZ+RozhM7oHypQOndvKrqvLlhFRbzEhE5CwNAIipxqRlZsu7IZVmx77wq3j15JcX8XpC/r9zWoKIK+jpcV0EC/HwNTSsRkSdiAEhEJZLLd+hComq5i3p9+JuScbVPypAAP9WSt3uTStKpXkUJ4xM7iIiKFc+yROR0JlN2wLf+6GVZc+iSrD18WS4mplnNExURpIK9W+pVlI7XVZCQQNbrIyIqKQwAiajIziekyq5T8bLl+BXZciJWth6PlYS0TKt5ULR7fY0ycnNMeZXbV79SuPiwA3EiIkMwACSiAtXdO3whSQ6cT5C9ZxNk9+l42XU6Plfunl6s2yy6tNxYu5x6Qkez6Ei23iUichEMAIko19M2zsSlytFLSapF7rGL+JskB88nyvHLyWLKeeyaJWTk1S4fpoK8FtXLSMvqkVIvKlz82YCDiMgleX0AOH36dJkyZYqcPXtWmjVrJh988IG0bt3a6GQRFVtwdykpXc7Fp8rZuFQ5l5Am5+JS5VRsipy6kqL+no1PlSx7UV6OiGB/uS4qXOpGhUujKhGqexYU54YGev3phIjIbXj1GfuHH36Q559/XmbMmCFt2rSRadOmSdeuXWXfvn1SsWJFo5NHlG+r2uT0LElIzZT41AyJT8lQf2OTM+RKMv6myxU1ZMilxDS5lJiuAj9M0/KO7cwC/XylerlQqVkuVGqUC5Ma5UIlpkIpiYkqJRVKBbHuHhGRm/PRcCXxUgj6brjhBvnwww/Va5PJJNHR0fL000/LmDFjrvn5+Ph4KV26tMTFxUlEBDup9caWrpkmTeWWZZhMkpWV/RePLENOm/prMkl6JsZNkqb+aup1WmaWpGVkT8N4aoZJ1a/TB3SRggAvJT37b3JGliSlZaohMedvPpl0+cIzdBHEoRVuVESwGqpEhkjVMiFSNTJYqkaGSoXwIDUfEZEniuf123tzANPT02XTpk0yduxY8zRfX1/p3LmzrFmzxu5n0tLS1GB5ABWHxTvPyOKdZ3NNL8z13pHw3t4stvcFdhdjZ6KWM1H/uJbHPOb3c81z9fPZ72Uv0Xp+y3myl6WPq6DIYrop5/OYjs+p15r1a4wjmMvSX5tEBXXqtSl7Gl5jPgR0WTmBnyvcOvn7+khESIAqlg0PDpDIUAyBEhkSIGVyxsuVCpTypYLUgOfoYmBwR0Tk3bw2ALx48aJkZWVJVFSU1XS83rt3r93PTJ48WV555ZViTxtaVy7cerrYv4ecDyWjeHJFgK+PagAR4OejilMD/H2z//r5SqC/r+oSJSjAT00LCvCVYH8/CQnM/ouWsugTD61oQ/E3EH/9JSzIT8KDAtTfUkH+UirYX83D4lgiIioorw0ACwO5hagzaJkDiCJjZ2tft4K6wDuisBd/2085shiffL7f8vO55tPnsfN9PjlTr762eS/7P/U9+ufxvhrwT583531f/LX8jE/2NN+cv/rykAN2dV4f9RoNVvEZPzW/j/j6Zs+nXiOgU/Pgr2/2ez5Xgzx9OnPWiIjIHXhtAFi+fHnx8/OTc+fOWU3H60qVKtn9TFBQkBqKGzrLxUBERERUHLy2k67AwEC5/vrrZdmyZeZpaASC123btjU0bURERETFyWtzAAHFuYMGDZJWrVqpvv/QDUxSUpIMHjzY6KQRERERFRuvDgD79+8vFy5ckPHjx6uOoJs3by6LFy/O1TCEiIiIyJN4dT+ARcV+hIiIiNxPPK/f3lsHkIiIiMhbMQAkIiIi8jIMAImIiIi8DANAIiIiIi/DAJCIiIjIyzAAJCIiIvIyDACJiIiIvAwDQCIiIiIvwwCQiIiIyMt49aPgikp/iAp6FCciIiL3EJ9z3fbmh6ExACyChIQE9Tc6OtropBAREVEhruOlS5cWb8RnAReByWSS06dPS3h4uPj4+Dj97gSB5YkTJzzyOYVcP/fn6evI9XN/nr6OXL/C0zRNBX9VqlQRX1/vrA3HHMAiwEFTrVq1Yv0OHPSe+MPWcf3cn6evI9fP/Xn6OnL9Cqe0l+b86bwz7CUiIiLyYgwAiYiIiLwMA0AXFRQUJBMmTFB/PRHXz/15+jpy/dyfp68j14+Kgo1AiIiIiLwMcwCJiIiIvAwDQCIiIiIvwwCQiIiIyMswACQiIiLyMgwADTJp0iS56aabJDQ0VCIjIx36DNrrjB8/XipXriwhISHSuXNnOXDggNU8ly9flgEDBqhOM7HcRx99VBITE6WkFTQdR48eVU9TsTf8+OOP5vnsvf/999+LEQqzrW+55ZZc6X/yySet5jl+/Ljccccd6tioWLGivPDCC5KZmSmuvn6Y/+mnn5Z69eqp47N69eryzDPPSFxcnNV8Ru7D6dOnS82aNSU4OFjatGkj69evz3d+HHv169dX8zdp0kR+//33Av8mS1JB1m/mzJnSvn17KVOmjBqQdtv5H3744Vz7qlu3buIO6/fll1/mSjs+58r7r6DraO98ggHnD1fch6tWrZKePXuqp28gHQsXLrzmZ1asWCEtW7ZULYFjYmLUfi3q75pyoBUwlbzx48dr7777rvb8889rpUuXdugzb775ppp34cKF2rZt27RevXpptWrV0lJSUszzdOvWTWvWrJm2du1abfXq1VpMTIx2//33ayWtoOnIzMzUzpw5YzW88sorWqlSpbSEhATzfDhkZ82aZTWf5fqXpMJs644dO2qPP/64Vfrj4uKstkPjxo21zp07a1u2bNF+//13rXz58trYsWM1V1+/HTt2aHfffbf2888/awcPHtSWLVum1a1bV7vnnnus5jNqH37//fdaYGCg9sUXX2i7du1S+yEyMlI7d+6c3fn//fdfzc/PT3v77be13bt3ay+//LIWEBCg1rMgv8mSUtD1e+CBB7Tp06er42zPnj3aww8/rNbl5MmT5nkGDRqkjgPLfXX58mXNCAVdPxxjERERVmk/e/as1TyutP8Ks46XLl2yWr+dO3eqYxbr7or7EOezl156SZs/f746DyxYsCDf+Q8fPqyFhoaq6yR+gx988IFav8WLFxd6m9FVDAANhh+qIwGgyWTSKlWqpE2ZMsU8LTY2VgsKCtK+++479Ro/EPyoNmzYYJ7njz/+0Hx8fLRTp05pJcVZ6WjevLn2yCOPWE1z5KThyuuIAPDZZ5/N9wTp6+trdaH6+OOP1YUsLS1Nc7d9OHfuXHVyzsjIMHwftm7dWhs6dKj5dVZWllalShVt8uTJdufv16+fdscdd1hNa9OmjfbEE084/Jt05fWz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", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "\n", "temperatures=[1, 10, 100]\n", @@ -68,36 +42,10 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "a64fbe7c", "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "16184f6dae4a40ea85c0c8ca1c716fd3", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAZQVJREFUeJzt3Qd8FGX+x/EnPSH0DoIU8ayo2PXsDUQBy9k9sZyeimJX8BRsWLGdp2IvJ6JYsPw9Uey9IlhBRBSUXgPpZf6v75PMMrvZJLvJJlvm8369Jrs7O5l9pv/maZPmOI5jAAAA4Bvp8U4AAAAAWhYBIAAAgM8QAAIAAPgMASAAAIDPEAACAAD4DAEgAACAzxAAAgAA+AwBIAAAgM8QAAIAAPgMASAAAIDPEAACAAD4DAEgAACAzxAAAgAA+AwBIAAAgM8QAAIAAPgMASAAAIDPEAACAAD4DAEgAACAzxAAAgAA+AwBIAAAgM8QAAIAAPgMASAAAIDPEAACAAD4DAEgAACAzxAAAgAA+AwBIAAAgM8QAAIAAPgMASAAAIDPEAACAAD4DAEgAACAzxAAAgAA+AwBIAAAgM8QAAIAAPgMASAAAIDPEADGwamnnmr69u0bNC4tLc1cc801MfuN9957z85Tr/XRb2q6lStXxuy399tvPzsku4qKCnP55Zeb3r17m/T0dHPEEUeYVLBhwwbzj3/8w3Tv3t1u+wsvvDAu6Qjd5x9//HE77rfffgua7rbbbjP9+/c3GRkZZocddkjpbQMgNnSN1bU22mtirCXy9TAlA0D3QuIOubm5pmfPnmbw4MHm3//+t1m/fn2j5/3jjz/ai1boRQqp59FHH7XBx9/+9jfzxBNPmIsuuijmv3HffffZ/bUl3XjjjfY3zznnHPPf//7X/P3vfzeJ6s0337SB3l//+lfz2GOP2bS31LaJlf/9739R3dzFY59IBkVFRXY9tvQFPNlwjUKkMk0Ku+6660y/fv1MeXm5Wbp0qT1xKLfjjjvuMK+88orZbrvtGnVwXXvttTaiD83Fi9RDDz1kqqqqGvW/aDnvvPOO2WSTTcydd97ZbL+hi33nzp2D7lRbYrl23313M378eJNIFIgef/zxJicnJyityuF75JFHTHZ2dotum1gGgPfee2/EQWA89olkCQB17pVEzVFJBLG4RqWiffbZxxQXFwedR/wupQPAQw891Oy8886Bz2PHjrUXjsMPP9wMHz7c/PTTTyYvL6/F05WVldXiv4noLV++3LRv394km5KSEnuSU+BU13JtvfXWMfs9FcfqhqapJ1YV8WoITauO0dB5x3rbOI5j11s8zgd+Fav9JlXSkcq0fsvKymxpXLzofBjP309EKVkEXJ8DDjjAXH311eb33383Tz31VNB3c+bMsUVKHTt2tDuKgkflFLpULHPMMcfY9/vvv3+giNktknj55ZfNYYcdZoublYux2Wabmeuvv95UVlY2WAcwnD///NOcfvrpplu3bnZ+22yzjS36CvXHH3/YOlD5+fmma9eutjistLQ0qvWiOoDHHnusadu2renUqZO54IIL7AXRS0VwWn/6DaVHQcT999/f4Lx14I8bN87stNNOpl27djade++9t3n33XeDplORhdbnxIkTzYMPPmjXn35nl112MV9++WWt+Wp7Kc1dunSxF+4tttjC/Otf/2rUOgyXDqXvhx9+qLWdlb4999zTrif9rpbr+eefDzsv7WO77rqradWqlenQoYO9C1Wxpmgf0Pzff//9wG94czZ+/fVXu79pf9T/K9futddeC5q/W6/lmWeeMVdddZXNFdO0BQUFtdLiTrtgwQI7H/c33aIiBVVnnHGGXVfa/7fffntbvFrXNrrrrrsC20i5DnXRvqh9UtupTZs29uZL+2yo0DqAeq99rrCwMJBWd5q6to0uNEqXtrOWQcvyz3/+06xZsybot7TudSP4xhtv2ONc2/GBBx6w361du9aWFKh+oZZtwIAB5pZbbgnKtY90X9Wxrtw/d3ncoS4N7RPRpk2/rfqT2icOOeQQs2jRIhvs6rzUq1cvu9wjRowwq1evDrt+tK+q3qXWpY73F198sVaao01T6H4TyflB/6/9R5S75a4bN1e1rnpWoefahvbfhq4BohIlpWHzzTe30+g8sNdee5kZM2aYxlB6zjvvPPPSSy+ZbbfdNnCemj59eq1pv/nmG5uxofN069atzYEHHmg+++yziK9R4WgdaV46V+o6ovda15deemmta5eOxUsuuSSwrXXO1brUPhVumSZPnmyXRdNqedzj96OPPjKjR4+2v6MbOR2j2g+0L51yyin2XKlB1T9C5x3N+dcrtA7g4yFVxbxD6L6k87h+R7+nfUMlFTqWQrnnAk2n8/6HH35oEllK5wDWV9R05ZVX2pPbmWeeacfppKt6RrqAjhkzxp6Epk6dag+IF154wRx55JH24q2dVvUI9f9bbbWV/V/3VTuUDp6LL77Yviq3USc2XYxVXykay5Ytsxd890DSgfL666/bC7Tm51bcV5a2TgILFy60aVPwqXpd+u1oKJDSifKmm26yJxQtoy6aTz75ZGAaBXs6mHUBz8zMNK+++qo599xz7Yl+1KhRdc5b6X344YfNCSecYNe36mCqSE91Mr/44otAxX7X008/bafRSUHLf+utt5qjjjrKBkRu7um3335rLxL6fNZZZ9m0z58/36ZpwoQJUa3DUJpO61DzUYMJrRPvdr777rvtOjjppJPsSUvBl066//d//2dvAFy6SOgCpZOVqiMoh+Hzzz+320YXY12Azj//fLuvuIGrAhY37fo/FXtpu+pkp2BMv6uTnfZHL13QNX+dtBVwhcvNUPq1XArGdPHXidxdXu1HOun98ssvdl2p6sRzzz1nLw46KeuGwEuBmW4QtO51ctdJsS5qcKIT6IknnmiXScvvXU91UVp1QtU+ov1HBg0aVO+20T6j4/C0006z603B7n/+8x974fz444+Dct/nzp1r90n9j/ZLXcy0vvfdd197MdT4TTfd1HzyySe29GDJkiV2m0Wzr2r84sWLbXCgdDekvn0i2rTp4qv9U/NTgKe06TjXTZwugldccYXd3vfcc4/db0JvjObNm2eOO+44c/bZZ5uRI0faba79XBfygw8+uFFpCrffRHJ+0D6q84/qrWrf1zqWxlTjqSsdkVwDRMe09jvt17rIK/1fffWVmTlzZmC9REsBkYJrnU91k6Tz79FHH23P6zr2RenTOU/BnwIj7V+6adFxqxuG3XbbrcFrVF0U6Gl9ax4KsN566y1z++2322BG61wUiOn8o8Bc51BtF91AXXbZZXb7h1bH0HGu9afziao06Bw9a9Ys+532STVC0zlS1xsd5woEte9oH1JdX1Wd0HVTQbGCQlek59+G7LPPPrWOSWUM6UZamRwunWuUaaRjR9t8xYoV9pjR/+u84pZEaJ/VMaBznK4tOgcondq3FDAnJCcFPfbYY7plcL788ss6p2nXrp0zaNCgwOcDDzzQGThwoFNSUhIYV1VV5ey5557O5ptvHhj33HPP2Xm/++67teZZVFRUa9w///lPp1WrVkHzHTlypNOnT5+g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AOXmm282l112mfn+++/jnRQAAICklOaoXDWJdOjQwRQVFZmKigqTnZ1t8vLygr5fvXp1i6WloKDAtGvXzqxbt860bdu2xX4XAAA0XgHXb5Npksxdd90V7yQAAAAktaQLAEeOHBnvJAAAACS1pAsApbKy0rz00kvmp59+sp+32WYbM3z4cJORkRHvpAEAACS8pAsAf/nlFzN06FDz559/mi222MKOu+mmm0zv3r3Na6+9ZjbbbLN4JxEAACChJV0r4NGjR9sgT30Bzpw50w7qHLpfv372OwAAAKRYDuD7779vPvvsM9OxY8fAuE6dOtnuYf7617/GNW0AAADJIOlyAHNycsz69etrjd+wYYPtFgYAAAApFgAefvjh5qyzzjKff/65fTScBuUInn322bYhCAAAAFIsAPz3v/9t6wDuscceJjc31w4q+tUzgukjEAAAIAXrALZv3968/PLLtjWw2w3MVlttZQNAAAAApGAO4HXXXWcfBaeAb9iwYXbQ++LiYvsdAAAAUuxZwOrsecmSJaZr165B41etWmXHqZPolsKzBAEASD4FXL+TLwdQ8WpaWlqt8bNnzw7qGgYAAABJXgewQ4cONvDT8Je//CUoCFSun7qBUUtgAAAApEgAqBa+yv07/fTTzbXXXmuzbl3q/69v3762ZTAAAABSJAAcOXKkfdUj39TtS2Zm0iQdAAAgoSRdHcDCwkLz9ttv1xr/xhtvmNdffz0uaQIAAEgmSRcAjhkzJmxLXxUP6zsAAACkWAA4b948s/XWW9cav+WWW9rOoQEAAJBiAaAaf/z666+1xiv4y8/Pj2pef/75pzn55JNNp06dTF5enhk4cKD56quvYphaAACAxJN0AeCIESPMhRdeaObPnx8U/F1yySVm+PDhEc9nzZo1tjFJVlaWrTv4448/mttvv912NwMAAJDKku5JIOq1e8iQITanrlevXnbcH3/8Yfbee2/z4osv2mcFR0L1BT/++GPz4YcfNjot9CQOAEDyKeD6nXwBoCjJM2bMsE//UNHtdtttZ/bZZ5+o5qF6hIMHD7bB4/vvv2822WQTc+6555ozzzwz4nmwAwEAkHwKuH4nZwAYC7m5ufb14osvNsccc4z58ssvzQUXXGAmTZoU6HMwVGlpqR28O1Dv3r19vQMBAJBsCggAkzMAVF+AyrVbuHChKSsrC/pu9OjR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hgTmvckmmzTLMvlVmpNk3WvrLuKKK64wU6dONatWrar1vVoftZSCggK7k65bt47AEwBSlDIbFixYYPr162efbIHk324FXL+T70kgl19+uXnnnXfM/fffb3JycszDDz9s+wNU9vCTTz4Z7+QBAAAkvKQrAn711VdtoKd6AapPsPfee9t6B3369DGTJ0+m7yAAAIBUywFUNy9uZ9DKtnW7fdlrr73MBx98EOfUAQAAJL6kCwAV/KlMX7bccktbF9DNGVTLIQAAAKRYAKhi39mzZ9v3eqi0nhuoyp0XXXSRueyyy+KdPAAAgISXdHUAFei59HBpPTtw5syZth7gdtttF9e0AQAAJIOkCwBD9e3b1w4AAABI0SJg0SNlDj/8cLPZZpvZQe/16BgAAACkYAB433332Z7B9dDoCy64wA5qDTx06FBbHxAAAAApVgR84403mjvvvDPoodKjR482f/3rX+13o0aNimv6AAAAEl3S5QCuXbvW5gCGOuSQQ+wjXQAAgDFpaWn1Dtdcc03U8/zhhx/M0Ucfbeveax533XVX2OlUIqdp1EvHbrvtZr744otaj2lThk2nTp1M69at7TyXLVtW72/rARAXXnhh0Li7777bPhXsmWeeiXpZ/C7pAsDhw4ebadOm1Rr/8ssv27qAAADAmCVLlgQGBWqqLuUdd+mll0Y9z6KiItsf780332y6d+8edppnn33WXHzxxWb8+PG2l47tt9/eDB482CxfvjyoRw/13/vcc8+Z999/3yxevNgcddRRUaVF87/yyivt9f/444+Peln8LimKgP/9738H3m+99dZmwoQJ5r333jN77LGHHffZZ5+Zjz/+2FxyySWN/g3tzGPHjrV1Cuu6owEAIFl4A7R27drZHLu6grZI7bLLLnZw++IN54477jBnnnmm7bdXJk2aZF577TXz6KOP2v9Rad0jjzxinn76aXPAAQfYaR577DGz1VZb2ev57rvvXm8aHMexVb+eeuopM2PGDLPnnns2aZn8KikCQNX58+rQoYP58ccf7eDSU0C0c1111VVRz//LL780DzzwAP0IAgAioiCkuKI4Lr+dl5lng7lYURFsfU4++WQbxEWirKzMfP311zZDxZWenm777f3000/tZ31fXl5ux7n0ZK9NN93UTlNfAFhRUWHT884779icQ67bKR4Auo9+aw4bNmwwJ510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zeuvv+6kpaU5f/75p9NSYpWOHXbYwTn99NODxkVy0kjkZVQAeMEFF9R7gkxPTw+6UN1///32QlZaWuok2zacOnWqPTmXl5fHfRvuuuuuzqhRowKfKysrnZ49ezo33XRT2OmPPfZY57DDDgsat9tuuzn//Oc/Iz4mE3n5Qunmo02bNs4TTzwRFDyMGDHCSQTRLl9D59ZE236x2IZ33nmn3YYbNmxIyG3oFcl54PLLL3e22WaboHHHHXecM3jw4JitMz+jCDhJLFiwwCxdutQWUXifY6js7k8//dR+1quK6nbeeefANJpezyz+/PPPWyytsUjH119/bWbNmmWLHUONGjXKdO7c2ey6667m0UcftcU4La0pyzh58mSb/m233daMHTvWFBUVBc1XRY3dunULjBs8eLB9KPoPP/xgWkqs9iUV/6oIOTMzM67bsKyszO5T3uNHy6LP7vETSuO907vbwp0+kmOypTRm+UJpPywvLzcdO3asVQSnqggq2j/nnHPMqlWrTEtr7PKpykKfPn1M7969zYgRI4KOoUTafrHaho888og5/vjjTX5+fsJtw8Zo6BiMxTrzs+CzMhKWTlTiDQzcz+53etVB7qULr07o7jQtldampkMnsq222srWk/S67rrrzAEHHGDrx7355pvm3HPPtSd51TVrSY1dxhNPPNFekFQH5ttvvzVXXHGFmTt3rnnxxRcD8w23jd3vkmkbrly50lx//fXmrLPOivs2VFoqKyvDrts5c+aE/Z+6toX3eHPH1TVNS2nM8oXSvqj90nsxVV2xo446yvTr18/Mnz/fXHnllebQQw+1F9eMjAyTyMunYEc3F9ttt529EZk4caI9nygI7NWrV0Jtv1hsQ9V7+/777+250ytRtmFj1HUM6oa4uLjYrFmzpsn7vZ8RAMbQmDFjzC233FLvND/99JOtVJ7Ky9dUOrCffvppc/XVV9f6zjtu0KBBprCw0Nx2220xCx6aexm9wZBy+lT5/MADD7Qn5s0228ykyjbUCVoV0bfeemtzzTXXtOg2RPRuvvlm2xBHOUXehhLKTfLurwqmtJ9qOu23iWyPPfawg0vBn24qH3jgAXtjkmoU+GkbKVfdK5m3IZoXAWAMXXLJJbbFVX369+/fqHl3797dvi5btswGDS593mGHHQLTLF++POj/1HpUrTPd/2+J5WtqOp5//nlbHHXKKac0OK2Ka3QyLy0tjcnzIltqGb3pl19++cWelPW/oS3YtI0lWbbh+vXrba5DmzZtzLRp00xWVlaLbsNwVNys3A53Xbr0ua7l0fj6po/kmGwpjVk+l3LGFAC+9dZbNjhoaN/Qb2l/bcngoSnL59J+qBsOpT3Rtl9Tl1E3UQrglbvekHhtw8ao6xhUtRK12tb6aup+4WvxroTod9E2Apk4cWJgnFqPhmsE8tVXXwWmeeONN+LWCKSx6VBDidCWo3W54YYbnA4dOjgtLVbr+qOPPrLzUQtEbyMQbwu2Bx54wDYCKSkpcRJ9+bRP7r777nYbFhYWJtQ2VGXx8847L6iy+CabbFJvI5DDDz88aNwee+xRqxFIfcdkS4p2+eSWW26x+9ann34a0W8sWrTI7gMvv/yykwzLF9rIZYsttnAuuuiihNx+TVlGXUeU7pUrVyb0NmxMIxD1iuClnghCG4E0Zb/wMwLAOPn9999t9wtuVyd6r8Hb5YlOVmou7+2yQM3bdeB+++23tmVXuG5gBg0a5Hz++ec2uFA3HPHqBqa+dKirCS2fvveaN2+ePTmpxWkodS/y0EMP2W44NN19991nuwhQlzrxEO0yqmuU6667zgZVCxYssNuxf//+zj777FOrG5hDDjnEmTVrlu3uoEuXLnHrBiaa5dPFU61kBw4caJfV2+2Elive21DdRegi+fjjj9sA96yzzrLHk9vi+u9//7szZsyYoG5gMjMzbYCgblLGjx8fthuYho7JlhLt8intaqH9/PPPB20r9xyk10svvdQGh9pf33rrLWfHHXe0+0FL3ow0dvl0btVNy/z5852vv/7aOf74453c3FzbVUgibr/GLKNrr732sq1jQyXaNlR63GudAkB1hab3uh6Klk3LGNoNzGWXXWaPQXVbFK4bmPrWGepGABgnapqvAyB0ePfdd2v1l+bSHevVV1/tdOvWze7wBx54oDN37txa/ULpIq2gUnf2p512WlBQ2VIaSodORqHLKwp0evfube/iQikoVNcwmmd+fr7to27SpElhp03EZVy4cKEN9jp27Gi3n/rV04nN2w+g/Pbbb86hhx7q5OXl2T4AL7nkkqBuVBJ1+fQabp/WoGkTYRuqH7FNN93UBj7KOVAfhy7lWuq4DO3G5i9/+YudXt1RvPbaa0HfR3JMtqRolq9Pnz5ht5UCXSkqKrI3IroBUeCr6dXHWjwvrNEs34UXXhiYVttn6NChzsyZMxN6+zVmH50zZ47dbm+++WateSXaNqzrHOEuk161jKH/o3OG1odumL3XxEjWGeqWpj/xLoYGAABAy6EfQAAAAJ8hAAQAAPAZAkAAAACfIQAEAADwGQJAAAAAnyEABAAA8BkCQAAAAJ8hAASAGFq6dKk5+OCDTX5+vmnfvn2z/Mbf//53c+ONN5pEMH36dPvs3KqqqngnBUAUCAABHzn11FNNWlparWHIkCEmWe23337mwgsvNInizjvvNEuWLDGzZs0yP//8c8znP3v2bPO///3PjB492jSngQMHmrPPPjvsd//9739NTk6OWblypd13srKyzOTJk5s1PQBiiwAQ8BldsBWgeIcpU6Y062+WlZWZeNIDjyoqKlrkt+bPn2922mkns/nmm5uuXbvGfH3dc8895phjjjGtW7c2zemMM84wzzzzjCkuLq713WOPPWaGDx9uOnfuHLix+Pe//92s6QEQWwSAgM8o56Z79+5BQ4cOHQLfK0fw4YcfNkceeaRp1aqVDWReeeWVoHl8//335tBDD7VBSLdu3WyRpHKDvLly5513ns2ZU5AwePBgO17z0fxyc3PN/vvvb5544gn7e2vXrjWFhYWmbdu25vnnnw/6rZdeeskWp65fv77WsijweP/9983dd98dyM387bffzHvvvWffv/766zYY0zJ/9NFHNjgbMWKETbPSvssuu5i33noraJ59+/a1xaunn366adOmjdl0003Ngw8+GBScadl69Ohhl6NPnz7mpptuCvzvCy+8YJ588kn7+0qfaPn+8Y9/mC5duthlPOCAA2xOnuuaa66xxaha7/369bPzDaeystKun2HDhtVK8w033GBOOeUUu1xKk9b1ihUr7PJq3HbbbWe++uqroP/TOtl7771NXl6e6d27t81V1HaQk08+2QZ/Wh6vBQsW2PWrANGl9GjeWr8AkkQ9zwkGkGL0sPURI0bUO41OC7169XKefvppZ968ec7o0aOd1q1bO6tWrbLfr1mzxj5cfuzYsc5PP/3kzJw50zn44IOd/fffPzAPPdBd/3PZZZfZh9Vr+PXXX+0D6S+99FL7ecqUKc4mm2xif0/zFD2ofujQoUHpGT58uHPKKaeETevatWudPfbYw/7fkiVL7FBRURF46Px2223nvPnmm84vv/xi0z9r1ixn0qRJznfffef8/PPPzlVXXeXk5uY6v//+e2Ceffr0cTp27Ojce++9dvlvuukmJz093aZZbrvtNqd3797OBx984Pz222/Ohx9+aNeVLF++3BkyZIhz7LHH2rQofXLQQQc5w4YNc7788kv7u5dcconTqVOnwDodP368k5+fb/9X63P27Nlhl1ffabmWLl0aNN5Ns5ZN8z/nnHOctm3b2vlNnTrVmTt3rnPEEUc4W221lVNVVWX/R+tEv3nnnXfa//n444+dQYMGOaeeempgvsccc0zQdpVx48bZ5a+srAwa361bN+exxx6rY68CkGgIAAGfBYAZGRn2wu8dJkyYEJhGAYYCI9eGDRvsuNdff91+vv76651DDjkkaL6LFi2y0yjQcANABRNeV1xxhbPtttsGjfvXv/4VFAB+/vnnNn2LFy+2n5ctW+ZkZmY67733Xp3LpN+64IILgsa5AeBLL73U4DrZZpttnHvuuScomDr55JMDnxUwde3a1bn//vvt5/PPP9854IADAoFUKAXYWs8uBYgKxkpKSoKm22yzzZwHHnggEAAqOFYAWZ9p06bZ9RP626FpVvCp5b/66qsD4z799FM7Tt/JGWec4Zx11llB81FaFewWFxfbz9OnT3fS0tJs8O6uC/2Wd/9waXtfc8019aYfQOKgCBjwGRW9qoGCdwit7K/iQpeKX1VsuXz5cvtZRZfvvvuuLVZ0hy233NJ+5y0CVNGr19y5c22Rq9euu+5a6/M222xji4blqaeessWZ++yzT6OWdeeddw76vGHDBnPppZearbbayrbQVdp/+ukns3DhwjqXX0W5KiZ3l1/FulpnW2yxhS0yffPNN+tNg9aXfrdTp05B60xFqd71peVUEXF9VCSr4mylKZQ3zSridhtyhI7zbsfHH388KE0qqldrXqVN1Jq5V69ets6fvP3223ZdnXbaabV+X8XIRUVF9aYfQOLIjHcCALQsBXQDBgyodxq16vRSwOF286FgRnW+brnlllr/p3px3t9pDNWVu/fee82YMWNs4KFgI1zAE4nQNCj4mzFjhpk4caJdBwpa/va3v9VqdFHf8u+44442QFL9QtUfPPbYY81BBx1Uq+6iS+tL60X15kJ5u4mJZH2pPqWCLKU3Ozu7zjS76yvcOO92/Oc//xm2NbHqPUp6eroNeBWQq56itoduIPr371/rf1avXt1gAAsgcRAAAoiKAiA1DFDDg8zMyE8hyjFT9yVeX375Za3p1Pjg8ssvt61Kf/zxRzNy5Mh656tASI0jIvHxxx/bgEYNXNwgSI1GoqUc0eOOO84OCiDVsloBUMeOHcOuL/UNqHWlddYUaigiWi/u+8ZSujSfhm4GFICrgcmLL75opk2bZhuqhCopKbG5mYMGDWpSmgC0HIqAAZ8pLS21AYl38LbgbcioUaNssHPCCSfYAE4X/jfeeMMGCvUFYsptmjNnjrniiits/3hTp061RZDizeFTi+SjjjrKXHbZZeaQQw6xRZD1UVD1+eef20BOy1Ffh8RqgaxARkW4KgI98cQTo+7A+I477rDd5mhZtBzPPfecLSKuq9Nn5Q7uscce5ogjjrDFxUrnJ598Yv71r3/VapXbEOWwKXBT692m0nZQOtSiWetj3rx55uWXX7afvdQqWa2WzzrrLFv8rG0T6rPPPrPfaTkBJAcCQMBn9OQGFUl6h7322ivi/+/Zs6fNSVOwpwBN9czU3YsCIBUZ1kWBhIpJFYCpvtr9999vgyBR8OClLkZUzKmuWBqiYt2MjAyz9dZb2wAptD5faPCmAHPPPfe0xdiq86aAKhrqGubWW2+19QtVp1EBnXI261p2Bbf6XvUYFST/5S9/Mccff7z5/fffA/Xyoi0ij0Wny9oG6kJHQay6glHu3bhx4+z2DaXtsWbNGhswh+uiRgHxSSedZLsNApAc0tQSJN6JAOBPEyZMMJMmTTKLFi2q9aSJiy66yCxevLhWXTe/U0MQFac/++yzCZHjplxXpUe5mQryASQH6gACaDH33XefzTVTi1jlIt52221BRY5q4KAnk9x88822yJjgrzY1XFFH09EU2zcn5YBquxL8AcmFHEAALUa5esq5Uh1CtTTVE0TGjh0baEyilqbKFVRxqeqjNffjzgDArwgAAQAAfIZGIAAAAD5DAAgAAOAzBIAAAAA+QwAIAADgMwSAAAAAPkMACAAA4DMEgAAAAD5DAAgAAOAzBIAAAADGX/4fCJ0j4Wf4CTIAAAAASUVORK5CYII=", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "\n", "temperatures=[1, 10, 100]\n", @@ -119,36 +67,10 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "ea1f36ac", "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "309863fb77bf4e798eecf4ceb72a9e96", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAZQVJREFUeJzt3Qd8FGX+x/EnPSH0DoIU8ayo2PXsDUQBy9k9sZyeimJX8BRsWLGdp2IvJ6JYsPw9Uey9IlhBRBSUXgPpZf6v75PMMrvZJLvJJlvm8369Jrs7O5l9pv/maZPmOI5jAAAA4Bvp8U4AAAAAWhYBIAAAgM8QAAIAAPgMASAAAIDPEAACAAD4DAEgAACAzxAAAgAA+AwBIAAAgM8QAAIAAPgMASAAAIDPEAACAAD4DAEgAACAzxAAAgAA+AwBIAAAgM8QAAIAAPgMASAAAIDPEAACAAD4DAEgAACAzxAAAgAA+AwBIAAAgM8QAAIAAPgMASAAAIDPEAACAAD4DAEgAACAzxAAAgAA+AwBIAAAgM8QAAIAAPgMASAAAIDPEAACAAD4DAEgAACAzxAAAgAA+AwBIAAAgM8QAAIAAPgMASAAAIDPEADGwamnnmr69u0bNC4tLc1cc801MfuN9957z85Tr/XRb2q6lStXxuy399tvPzsku4qKCnP55Zeb3r17m/T0dHPEEUeYVLBhwwbzj3/8w3Tv3t1u+wsvvDAu6Qjd5x9//HE77rfffgua7rbbbjP9+/c3GRkZZocddkjpbQMgNnSN1bU22mtirCXy9TAlA0D3QuIOubm5pmfPnmbw4MHm3//+t1m/fn2j5/3jjz/ai1boRQqp59FHH7XBx9/+9jfzxBNPmIsuuijmv3HffffZ/bUl3XjjjfY3zznnHPPf//7X/P3vfzeJ6s0337SB3l//+lfz2GOP2bS31LaJlf/9739R3dzFY59IBkVFRXY9tvQFPNlwjUKkMk0Ku+6660y/fv1MeXm5Wbp0qT1xKLfjjjvuMK+88orZbrvtGnVwXXvttTaiD83Fi9RDDz1kqqqqGvW/aDnvvPOO2WSTTcydd97ZbL+hi33nzp2D7lRbYrl23313M378eJNIFIgef/zxJicnJyityuF75JFHTHZ2dotum1gGgPfee2/EQWA89olkCQB17pVEzVFJBLG4RqWiffbZxxQXFwedR/wupQPAQw891Oy8886Bz2PHjrUXjsMPP9wMHz7c/PTTTyYvL6/F05WVldXiv4noLV++3LRv394km5KSEnuSU+BU13JtvfXWMfs9FcfqhqapJ1YV8WoITauO0dB5x3rbOI5j11s8zgd+Fav9JlXSkcq0fsvKymxpXLzofBjP309EKVkEXJ8DDjjAXH311eb33383Tz31VNB3c+bMsUVKHTt2tDuKgkflFLpULHPMMcfY9/vvv3+giNktknj55ZfNYYcdZoublYux2Wabmeuvv95UVlY2WAcwnD///NOcfvrpplu3bnZ+22yzjS36CvXHH3/YOlD5+fmma9eutjistLQ0qvWiOoDHHnusadu2renUqZO54IIL7AXRS0VwWn/6DaVHQcT999/f4Lx14I8bN87stNNOpl27djade++9t3n33XeDplORhdbnxIkTzYMPPmjXn35nl112MV9++WWt+Wp7Kc1dunSxF+4tttjC/Otf/2rUOgyXDqXvhx9+qLWdlb4999zTrif9rpbr+eefDzsv7WO77rqradWqlenQoYO9C1Wxpmgf0Pzff//9wG94czZ+/fVXu79pf9T/K9futddeC5q/W6/lmWeeMVdddZXNFdO0BQUFtdLiTrtgwQI7H/c33aIiBVVnnHGGXVfa/7fffntbvFrXNrrrrrsC20i5DnXRvqh9UtupTZs29uZL+2yo0DqAeq99rrCwMJBWd5q6to0uNEqXtrOWQcvyz3/+06xZsybot7TudSP4xhtv2ONc2/GBBx6w361du9aWFKh+oZZtwIAB5pZbbgnKtY90X9Wxrtw/d3ncoS4N7RPRpk2/rfqT2icOOeQQs2jRIhvs6rzUq1cvu9wjRowwq1evDrt+tK+q3qXWpY73F198sVaao01T6H4TyflB/6/9R5S75a4bN1e1rnpWoefahvbfhq4BohIlpWHzzTe30+g8sNdee5kZM2aYxlB6zjvvPPPSSy+ZbbfdNnCemj59eq1pv/nmG5uxofN069atzYEHHmg+++yziK9R4WgdaV46V+o6ovda15deemmta5eOxUsuuSSwrXXO1brUPhVumSZPnmyXRdNqedzj96OPPjKjR4+2v6MbOR2j2g+0L51yyin2XKlB1T9C5x3N+dcrtA7g4yFVxbxD6L6k87h+R7+nfUMlFTqWQrnnAk2n8/6HH35oEllK5wDWV9R05ZVX2pPbmWeeacfppKt6RrqAjhkzxp6Epk6dag+IF154wRx55JH24q2dVvUI9f9bbbWV/V/3VTuUDp6LL77Yviq3USc2XYxVXykay5Ytsxd890DSgfL666/bC7Tm51bcV5a2TgILFy60aVPwqXpd+u1oKJDSifKmm26yJxQtoy6aTz75ZGAaBXs6mHUBz8zMNK+++qo599xz7Yl+1KhRdc5b6X344YfNCSecYNe36mCqSE91Mr/44otAxX7X008/bafRSUHLf+utt5qjjjrKBkRu7um3335rLxL6fNZZZ9m0z58/36ZpwoQJUa3DUJpO61DzUYMJrRPvdr777rvtOjjppJPsSUvBl066//d//2dvAFy6SOgCpZOVqiMoh+Hzzz+320YXY12Azj//fLuvuIGrAhY37fo/FXtpu+pkp2BMv6uTnfZHL13QNX+dtBVwhcvNUPq1XArGdPHXidxdXu1HOun98ssvdl2p6sRzzz1nLw46KeuGwEuBmW4QtO51ctdJsS5qcKIT6IknnmiXScvvXU91UVp1QtU+ov1HBg0aVO+20T6j4/C0006z603B7n/+8x974fz444+Dct/nzp1r90n9j/ZLXcy0vvfdd197MdT4TTfd1HzyySe29GDJkiV2m0Wzr2r84sWLbXCgdDekvn0i2rTp4qv9U/NTgKe06TjXTZwugldccYXd3vfcc4/db0JvjObNm2eOO+44c/bZZ5uRI0faba79XBfygw8+uFFpCrffRHJ+0D6q84/qrWrf1zqWxlTjqSsdkVwDRMe09jvt17rIK/1fffWVmTlzZmC9REsBkYJrnU91k6Tz79FHH23P6zr2RenTOU/BnwIj7V+6adFxqxuG3XbbrcFrVF0U6Gl9ax4KsN566y1z++2322BG61wUiOn8o8Bc51BtF91AXXbZZXb7h1bH0HGu9afziao06Bw9a9Ys+532STVC0zlS1xsd5woEte9oH1JdX1Wd0HVTQbGCQlek59+G7LPPPrWOSWUM6UZamRwunWuUaaRjR9t8xYoV9pjR/+u84pZEaJ/VMaBznK4tOgcondq3FDAnJCcFPfbYY7plcL788ss6p2nXrp0zaNCgwOcDDzzQGThwoFNSUhIYV1VV5ey5557O5ptvHhj33HPP2Xm/++67teZZVFRUa9w///lPp1WrVkHzHTlypNOnT5+g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AOXmm282l112mfn+++/jnRQAAICklOaoXDWJdOjQwRQVFZmKigqTnZ1t8vLygr5fvXp1i6WloKDAtGvXzqxbt860bdu2xX4XAAA0XgHXb5Npksxdd90V7yQAAAAktaQLAEeOHBnvJAAAACS1pAsApbKy0rz00kvmp59+sp+32WYbM3z4cJORkRHvpAEAACS8pAsAf/nlFzN06FDz559/mi222MKOu+mmm0zv3r3Na6+9ZjbbbLN4JxEAACChJV0r4NGjR9sgT30Bzpw50w7qHLpfv372OwAAAKRYDuD7779vPvvsM9OxY8fAuE6dOtnuYf7617/GNW0AAADJIOlyAHNycsz69etrjd+wYYPtFgYAAAApFgAefvjh5qyzzjKff/65fTScBuUInn322bYhCAAAAFIsAPz3v/9t6wDuscceJjc31w4q+tUzgukjEAAAIAXrALZv3968/PLLtjWw2w3MVlttZQNAAAAApGAO4HXXXWcfBaeAb9iwYXbQ++LiYvsdAAAAUuxZwOrsecmSJaZr165B41etWmXHqZPolsKzBAEASD4FXL+TLwdQ8WpaWlqt8bNnzw7qGgYAAABJXgewQ4cONvDT8Je//CUoCFSun7qBUUtgAAAApEgAqBa+yv07/fTTzbXXXmuzbl3q/69v3762ZTAAAABSJAAcOXKkfdUj39TtS2Zm0iQdAAAgoSRdHcDCwkLz9ttv1xr/xhtvmNdffz0uaQIAAEgmSRcAjhkzJmxLXxUP6zsAAACkWAA4b948s/XWW9cav+WWW9rOoQEAAJBiAaAaf/z666+1xiv4y8/Pj2pef/75pzn55JNNp06dTF5enhk4cKD56quvYphaAACAxJN0AeCIESPMhRdeaObPnx8U/F1yySVm+PDhEc9nzZo1tjFJVlaWrTv4448/mttvv912NwMAAJDKku5JIOq1e8iQITanrlevXnbcH3/8Yfbee2/z4osv2mcFR0L1BT/++GPz4YcfNjot9CQOAEDyKeD6nXwBoCjJM2bMsE//UNHtdtttZ/bZZ5+o5qF6hIMHD7bB4/vvv2822WQTc+6555ozzzwz4nmwAwEAkHwKuH4nZwAYC7m5ufb14osvNsccc4z58ssvzQUXXGAmTZoU6HMwVGlpqR28O1Dv3r19vQMBAJBsCggAkzMAVF+AyrVbuHChKSsrC/pu9OjR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hgTmvckmmzTLMvlVmpNk3WvrLuKKK64wU6dONatWrar1vVoftZSCggK7k65bt47AEwBSlDIbFixYYPr162efbIHk324FXL+T70kgl19+uXnnnXfM/fffb3JycszDDz9s+wNU9vCTTz4Z7+QBAAAkvKQrAn711VdtoKd6AapPsPfee9t6B3369DGTJ0+m7yAAAIBUywFUNy9uZ9DKtnW7fdlrr73MBx98EOfUAQAAJL6kCwAV/KlMX7bccktbF9DNGVTLIQAAAKRYAKhi39mzZ9v3eqi0nhuoyp0XXXSRueyyy+KdPAAAgISXdHUAFei59HBpPTtw5syZth7gdtttF9e0AQAAJIOkCwBD9e3b1w4AAABI0SJg0SNlDj/8cLPZZpvZQe/16BgAAACkYAB433332Z7B9dDoCy64wA5qDTx06FBbHxAAAAApVgR84403mjvvvDPoodKjR482f/3rX+13o0aNimv6AAAAEl3S5QCuXbvW5gCGOuSQQ+wjXQAAgDFpaWn1Dtdcc03U8/zhhx/M0Ucfbeveax533XVX2OlUIqdp1EvHbrvtZr744otaj2lThk2nTp1M69at7TyXLVtW72/rARAXXnhh0Li7777bPhXsmWeeiXpZ/C7pAsDhw4ebadOm1Rr/8ssv27qAAADAmCVLlgQGBWqqLuUdd+mll0Y9z6KiItsf780332y6d+8edppnn33WXHzxxWb8+PG2l47tt9/eDB482CxfvjyoRw/13/vcc8+Z999/3yxevNgcddRRUaVF87/yyivt9f/444+Peln8LimKgP/9738H3m+99dZmwoQJ5r333jN77LGHHffZZ5+Zjz/+2FxyySWN/g3tzGPHjrV1Cuu6owEAIFl4A7R27drZHLu6grZI7bLLLnZw++IN54477jBnnnmm7bdXJk2aZF577TXz6KOP2v9Rad0jjzxinn76aXPAAQfYaR577DGz1VZb2ev57rvvXm8aHMexVb+eeuopM2PGDLPnnns2aZn8KikCQNX58+rQoYP58ccf7eDSU0C0c1111VVRz//LL780DzzwAP0IAgAioiCkuKI4Lr+dl5lng7lYURFsfU4++WQbxEWirKzMfP311zZDxZWenm777f3000/tZ31fXl5ux7n0ZK9NN93UTlNfAFhRUWHT884779icQ67bKR4Auo9+aw4bNmwwJ510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zeuvv+6kpaU5f/75p9NSYpWOHXbYwTn99NODxkVy0kjkZVQAeMEFF9R7gkxPTw+6UN1///32QlZaWuok2zacOnWqPTmXl5fHfRvuuuuuzqhRowKfKysrnZ49ezo33XRT2OmPPfZY57DDDgsat9tuuzn//Oc/Iz4mE3n5Qunmo02bNs4TTzwRFDyMGDHCSQTRLl9D59ZE236x2IZ33nmn3YYbNmxIyG3oFcl54PLLL3e22WaboHHHHXecM3jw4JitMz+jCDhJLFiwwCxdutQWUXifY6js7k8//dR+1quK6nbeeefANJpezyz+/PPPWyytsUjH119/bWbNmmWLHUONGjXKdO7c2ey6667m0UcftcU4La0pyzh58mSb/m233daMHTvWFBUVBc1XRY3dunULjBs8eLB9KPoPP/xgWkqs9iUV/6oIOTMzM67bsKyszO5T3uNHy6LP7vETSuO907vbwp0+kmOypTRm+UJpPywvLzcdO3asVQSnqggq2j/nnHPMqlWrTEtr7PKpykKfPn1M7969zYgRI4KOoUTafrHaho888og5/vjjTX5+fsJtw8Zo6BiMxTrzs+CzMhKWTlTiDQzcz+53etVB7qULr07o7jQtldampkMnsq222srWk/S67rrrzAEHHGDrx7355pvm3HPPtSd51TVrSY1dxhNPPNFekFQH5ttvvzVXXHGFmTt3rnnxxRcD8w23jd3vkmkbrly50lx//fXmrLPOivs2VFoqKyvDrts5c+aE/Z+6toX3eHPH1TVNS2nM8oXSvqj90nsxVV2xo446yvTr18/Mnz/fXHnllebQQw+1F9eMjAyTyMunYEc3F9ttt529EZk4caI9nygI7NWrV0Jtv1hsQ9V7+/777+250ytRtmFj1HUM6oa4uLjYrFmzpsn7vZ8RAMbQmDFjzC233FLvND/99JOtVJ7Ky9dUOrCffvppc/XVV9f6zjtu0KBBprCw0Nx2220xCx6aexm9wZBy+lT5/MADD7Qn5s0228ykyjbUCVoV0bfeemtzzTXXtOg2RPRuvvlm2xBHOUXehhLKTfLurwqmtJ9qOu23iWyPPfawg0vBn24qH3jgAXtjkmoU+GkbKVfdK5m3IZoXAWAMXXLJJbbFVX369+/fqHl3797dvi5btswGDS593mGHHQLTLF++POj/1HpUrTPd/2+J5WtqOp5//nlbHHXKKac0OK2Ka3QyLy0tjcnzIltqGb3pl19++cWelPW/oS3YtI0lWbbh+vXrba5DmzZtzLRp00xWVlaLbsNwVNys3A53Xbr0ua7l0fj6po/kmGwpjVk+l3LGFAC+9dZbNjhoaN/Qb2l/bcngoSnL59J+qBsOpT3Rtl9Tl1E3UQrglbvekHhtw8ao6xhUtRK12tb6aup+4WvxroTod9E2Apk4cWJgnFqPhmsE8tVXXwWmeeONN+LWCKSx6VBDidCWo3W54YYbnA4dOjgtLVbr+qOPPrLzUQtEbyMQbwu2Bx54wDYCKSkpcRJ9+bRP7r777nYbFhYWJtQ2VGXx8847L6iy+CabbFJvI5DDDz88aNwee+xRqxFIfcdkS4p2+eSWW26x+9ann34a0W8sWrTI7gMvv/yykwzLF9rIZYsttnAuuuiihNx+TVlGXUeU7pUrVyb0NmxMIxD1iuClnghCG4E0Zb/wMwLAOPn9999t9wtuVyd6r8Hb5YlOVmou7+2yQM3bdeB+++23tmVXuG5gBg0a5Hz++ec2uFA3HPHqBqa+dKirCS2fvveaN2+ePTmpxWkodS/y0EMP2W44NN19991nuwhQlzrxEO0yqmuU6667zgZVCxYssNuxf//+zj777FOrG5hDDjnEmTVrlu3uoEuXLnHrBiaa5dPFU61kBw4caJfV2+2Elive21DdRegi+fjjj9sA96yzzrLHk9vi+u9//7szZsyYoG5gMjMzbYCgblLGjx8fthuYho7JlhLt8intaqH9/PPPB20r9xyk10svvdQGh9pf33rrLWfHHXe0+0FL3ow0dvl0btVNy/z5852vv/7aOf74453c3FzbVUgibr/GLKNrr732sq1jQyXaNlR63GudAkB1hab3uh6Klk3LGNoNzGWXXWaPQXVbFK4bmPrWGepGABgnapqvAyB0ePfdd2v1l+bSHevVV1/tdOvWze7wBx54oDN37txa/ULpIq2gUnf2p512WlBQ2VIaSodORqHLKwp0evfube/iQikoVNcwmmd+fr7to27SpElhp03EZVy4cKEN9jp27Gi3n/rV04nN2w+g/Pbbb86hhx7q5OXl2T4AL7nkkqBuVBJ1+fQabp/WoGkTYRuqH7FNN93UBj7KOVAfhy7lWuq4DO3G5i9/+YudXt1RvPbaa0HfR3JMtqRolq9Pnz5ht5UCXSkqKrI3IroBUeCr6dXHWjwvrNEs34UXXhiYVttn6NChzsyZMxN6+zVmH50zZ47dbm+++WateSXaNqzrHOEuk161jKH/o3OG1odumL3XxEjWGeqWpj/xLoYGAABAy6EfQAAAAJ8hAAQAAPAZAkAAAACfIQAEAADwGQJAAAAAnyEABAAA8BkCQAAAAJ8hAASAGFq6dKk5+OCDTX5+vmnfvn2z/Mbf//53c+ONN5pEMH36dPvs3KqqqngnBUAUCAABHzn11FNNWlparWHIkCEmWe23337mwgsvNInizjvvNEuWLDGzZs0yP//8c8znP3v2bPO///3PjB492jSngQMHmrPPPjvsd//9739NTk6OWblypd13srKyzOTJk5s1PQBiiwAQ8BldsBWgeIcpU6Y062+WlZWZeNIDjyoqKlrkt+bPn2922mkns/nmm5uuXbvGfH3dc8895phjjjGtW7c2zemMM84wzzzzjCkuLq713WOPPWaGDx9uOnfuHLix+Pe//92s6QEQWwSAgM8o56Z79+5BQ4cOHQLfK0fw4YcfNkceeaRp1aqVDWReeeWVoHl8//335tBDD7VBSLdu3WyRpHKDvLly5513ns2ZU5AwePBgO17z0fxyc3PN/vvvb5544gn7e2vXrjWFhYWmbdu25vnnnw/6rZdeeskWp65fv77WsijweP/9983dd98dyM387bffzHvvvWffv/766zYY0zJ/9NFHNjgbMWKETbPSvssuu5i33noraJ59+/a1xaunn366adOmjdl0003Ngw8+GBScadl69Ohhl6NPnz7mpptuCvzvCy+8YJ588kn7+0qfaPn+8Y9/mC5duthlPOCAA2xOnuuaa66xxaha7/369bPzDaeystKun2HDhtVK8w033GBOOeUUu1xKk9b1ihUr7PJq3HbbbWe++uqroP/TOtl7771NXl6e6d27t81V1HaQk08+2QZ/Wh6vBQsW2PWrANGl9GjeWr8AkkQ9zwkGkGL0sPURI0bUO41OC7169XKefvppZ968ec7o0aOd1q1bO6tWrbLfr1mzxj5cfuzYsc5PP/3kzJw50zn44IOd/fffPzAPPdBd/3PZZZfZh9Vr+PXXX+0D6S+99FL7ecqUKc4mm2xif0/zFD2ofujQoUHpGT58uHPKKaeETevatWudPfbYw/7fkiVL7FBRURF46Px2223nvPnmm84vv/xi0z9r1ixn0qRJznfffef8/PPPzlVXXeXk5uY6v//+e2Ceffr0cTp27Ojce++9dvlvuukmJz093aZZbrvtNqd3797OBx984Pz222/Ohx9+aNeVLF++3BkyZIhz7LHH2rQofXLQQQc5w4YNc7788kv7u5dcconTqVOnwDodP368k5+fb/9X63P27Nlhl1ffabmWLl0aNN5Ns5ZN8z/nnHOctm3b2vlNnTrVmTt3rnPEEUc4W221lVNVVWX/R+tEv3nnnXfa//n444+dQYMGOaeeempgvsccc0zQdpVx48bZ5a+srAwa361bN+exxx6rY68CkGgIAAGfBYAZGRn2wu8dJkyYEJhGAYYCI9eGDRvsuNdff91+vv76651DDjkkaL6LFi2y0yjQcANABRNeV1xxhbPtttsGjfvXv/4VFAB+/vnnNn2LFy+2n5ctW+ZkZmY67733Xp3LpN+64IILgsa5AeBLL73U4DrZZpttnHvuuScomDr55JMDnxUwde3a1bn//vvt5/PPP9854IADAoFUKAXYWs8uBYgKxkpKSoKm22yzzZwHHnggEAAqOFYAWZ9p06bZ9RP626FpVvCp5b/66qsD4z799FM7Tt/JGWec4Zx11llB81FaFewWFxfbz9OnT3fS0tJs8O6uC/2Wd/9waXtfc8019aYfQOKgCBjwGRW9qoGCdwit7K/iQpeKX1VsuXz5cvtZRZfvvvuuLVZ0hy233NJ+5y0CVNGr19y5c22Rq9euu+5a6/M222xji4blqaeessWZ++yzT6OWdeeddw76vGHDBnPppZearbbayrbQVdp/+ukns3DhwjqXX0W5KiZ3l1/FulpnW2yxhS0yffPNN+tNg9aXfrdTp05B60xFqd71peVUEXF9VCSr4mylKZQ3zSridhtyhI7zbsfHH388KE0qqldrXqVN1Jq5V69ets6fvP3223ZdnXbaabV+X8XIRUVF9aYfQOLIjHcCALQsBXQDBgyodxq16vRSwOF286FgRnW+brnlllr/p3px3t9pDNWVu/fee82YMWNs4KFgI1zAE4nQNCj4mzFjhpk4caJdBwpa/va3v9VqdFHf8u+44442QFL9QtUfPPbYY81BBx1Uq+6iS+tL60X15kJ5u4mJZH2pPqWCLKU3Ozu7zjS76yvcOO92/Oc//xm2NbHqPUp6eroNeBWQq56itoduIPr371/rf1avXt1gAAsgcRAAAoiKAiA1DFDDg8zMyE8hyjFT9yVeX375Za3p1Pjg8ssvt61Kf/zxRzNy5Mh656tASI0jIvHxxx/bgEYNXNwgSI1GoqUc0eOOO84OCiDVsloBUMeOHcOuL/UNqHWlddYUaigiWi/u+8ZSujSfhm4GFICrgcmLL75opk2bZhuqhCopKbG5mYMGDWpSmgC0HIqAAZ8pLS21AYl38LbgbcioUaNssHPCCSfYAE4X/jfeeMMGCvUFYsptmjNnjrniiits/3hTp061RZDizeFTi+SjjjrKXHbZZeaQQw6xRZD1UVD1+eef20BOy1Ffh8RqgaxARkW4KgI98cQTo+7A+I477rDd5mhZtBzPPfecLSKuq9Nn5Q7uscce5ogjjrDFxUrnJ598Yv71r3/VapXbEOWwKXBT692m0nZQOtSiWetj3rx55uWXX7afvdQqWa2WzzrrLFv8rG0T6rPPPrPfaTkBJAcCQMBn9OQGFUl6h7322ivi/+/Zs6fNSVOwpwBN9czU3YsCIBUZ1kWBhIpJFYCpvtr9999vgyBR8OClLkZUzKmuWBqiYt2MjAyz9dZb2wAptD5faPCmAHPPPfe0xdiq86aAKhrqGubWW2+19QtVp1EBnXI261p2Bbf6XvUYFST/5S9/Mccff7z5/fffA/Xyoi0ij0Wny9oG6kJHQay6glHu3bhx4+z2DaXtsWbNGhswh+uiRgHxSSedZLsNApAc0tQSJN6JAOBPEyZMMJMmTTKLFi2q9aSJiy66yCxevLhWXTe/U0MQFac/++yzCZHjplxXpUe5mQryASQH6gACaDH33XefzTVTi1jlIt52221BRY5q4KAnk9x88822yJjgrzY1XFFH09EU2zcn5YBquxL8AcmFHEAALUa5esq5Uh1CtTTVE0TGjh0baEyilqbKFVRxqeqjNffjzgDArwgAAQAAfIZGIAAAAD5DAAgAAOAzBIAAAAA+QwAIAADgMwSAAAAAPkMACAAA4DMEgAAAAD5DAAgAAOAzBIAAAADGX/4fCJ0j4Wf4CTIAAAAASUVORK5CYII=", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "import scipp as sc\n", "temperatures=[1, 10, 100]\n", diff --git a/examples/sample_model.ipynb b/examples/sample_model.ipynb index 732fa86..1e7e9d9 100644 --- a/examples/sample_model.ipynb +++ b/examples/sample_model.ipynb @@ -25,36 +25,10 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "784d9e82", "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "d473593b3aa14baf8f8c4dd432169d44", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "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", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "sample_model=SampleModel(name='sample_model')\n", "\n", @@ -86,34 +60,10 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "d35179d8", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Gaussian(name = Gaussian, unit = meV,\n", - " area = ,\n", - " center = ,\n", - " width = ),\n", - " DampedHarmonicOscillator(name = DHO, unit = meV,\n", - " area = ,\n", - " center = ,\n", - " width = ),\n", - " Lorentzian(name = Lorentzian, unit = meV,\n", - " area = ,\n", - " center = ,\n", - " width = ),\n", - " Polynomial(name = Polynomial, unit = meV,\n", - " coefficients = [Polynomial_c0=0.1, Polynomial_c1=0.0, Polynomial_c2=0.5])]" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# sample_model=SampleModel(name='sample_model')\n", "sample_model.components" From 9ac4159e60fc9172e07710c3d03eab6b3d0cb835 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Tue, 16 Dec 2025 09:51:48 +0100 Subject: [PATCH 70/71] update notebook --- examples/components.ipynb | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/examples/components.ipynb b/examples/components.ipynb index bdda8cf..9183e30 100644 --- a/examples/components.ipynb +++ b/examples/components.ipynb @@ -74,18 +74,16 @@ "source": [ "delta = DeltaFunction(name='Delta', center=0.0, area=1.0)\n", "x1=np.linspace(-2, 2, 100)\n", - "y=delta.evaluate(x1)\n", + "y1=delta.evaluate(x1)\n", "x2=np.linspace(-2,2,51)\n", "y2=delta.evaluate(x2)\n", "plt.figure()\n", - "plt.plot(x1, y, label='Delta Function')\n", + "plt.plot(x1, y1, label='Delta Function')\n", "plt.plot(x2, y2, label='Delta Function (coarser)')\n", "plt.legend()\n", "plt.show()\n", "# The area under the Delta function is indeed equal to the area parameter.\n", - "xx=np.linspace(-2, 2, 10000)\n", - "yy=delta.evaluate(xx)\n", - "area= np.trapezoid(y, x1)\n", + "area= np.trapezoid(y1, x1)\n", "print(area)\n" ] }, @@ -114,7 +112,7 @@ ], "metadata": { "kernelspec": { - "display_name": "newdynamics", + "display_name": "easydynamics_newbase", "language": "python", "name": "python3" }, @@ -128,7 +126,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.13" + "version": "3.12.12" } }, "nbformat": 4, From f8620677f4171e3e532570eb939a43a8948f81d4 Mon Sep 17 00:00:00 2001 From: henrikjacobsenfys Date: Tue, 16 Dec 2025 10:46:00 +0100 Subject: [PATCH 71/71] Respond to PR comments --- .../convolution/analytical_convolution.py | 10 +++++----- src/easydynamics/convolution/convolution.py | 8 +++++--- src/easydynamics/convolution/convolution_base.py | 5 ++++- .../convolution/numerical_convolution_base.py | 14 ++++++++++---- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/easydynamics/convolution/analytical_convolution.py b/src/easydynamics/convolution/analytical_convolution.py index b5f2032..f05913f 100644 --- a/src/easydynamics/convolution/analytical_convolution.py +++ b/src/easydynamics/convolution/analytical_convolution.py @@ -84,7 +84,7 @@ def convolution( else: resolution_components = [self.resolution_model] - total = np.zeros_like(self.energy, dtype=float) + total = np.zeros_like(self.energy.values, dtype=float) for sample_component in sample_components: # Go through resolution components, adding analytical contributions @@ -166,7 +166,7 @@ def _convolute_analytic_pair( def _convolute_delta_any( self, - sample_component: ModelComponent, + sample_component: DeltaFunction, resolution_model: SampleModel | ModelComponent, ): """ @@ -174,10 +174,10 @@ def _convolute_delta_any( The areas are multiplied. Args: - sample_component : ModelComponent + sample_component : DeltaFunction The sample component to be convolved. - resolution_component : ModelComponent - The resolution component to convolve with. + resolution_model : SampleModel | ModelComponent + The resolution model to convolve with. Returns: np.ndarray The evaluated convolution values at self.energy. diff --git a/src/easydynamics/convolution/convolution.py b/src/easydynamics/convolution/convolution.py index 94fc059..d3b35a4 100644 --- a/src/easydynamics/convolution/convolution.py +++ b/src/easydynamics/convolution/convolution.py @@ -240,13 +240,15 @@ def _set_convolvers(self) -> None: # Update some setters so the internal sample models are updated accordingly def __setattr__(self, name, value): - """Custom setattr to invalidate convolution plan on relevant attribute changes. - This only happens after initialization (when _reactions_enabled is True) to avoid issues during __init__.""" + """Custom setattr to invalidate convolution plan on relevant attribute changes, and build a new plan. + The new plan is only built after initialization (when _reactions_enabled is True) to avoid issues during __init__.""" super().__setattr__(name, value) + if name in self._invalidate_plan_on_change: + self._convolution_plan_is_valid = False + if ( getattr(self, "_reactions_enabled", False) and name in self._invalidate_plan_on_change ): - # super().__setattr__("_convolution_plan_is_valid", False) self._build_convolution_plan() diff --git a/src/easydynamics/convolution/convolution_base.py b/src/easydynamics/convolution/convolution_base.py index 89de6e9..2af5d30 100644 --- a/src/easydynamics/convolution/convolution_base.py +++ b/src/easydynamics/convolution/convolution_base.py @@ -45,7 +45,10 @@ def __init__( self._energy = energy self._energy_unit = energy_unit - if sample_model is not None and not isinstance(sample_model, SampleModel): + if sample_model is not None and not ( + isinstance(sample_model, SampleModel) + or isinstance(sample_model, ModelComponent) + ): raise TypeError( f"`sample_model` is an instance of {type(sample_model).__name__}, but must be a SampleModel or ModelComponent." ) diff --git a/src/easydynamics/convolution/numerical_convolution_base.py b/src/easydynamics/convolution/numerical_convolution_base.py index ba56771..a1cd45b 100644 --- a/src/easydynamics/convolution/numerical_convolution_base.py +++ b/src/easydynamics/convolution/numerical_convolution_base.py @@ -16,6 +16,14 @@ Numerical = float | int +# The thresholds are illustrated in performance_tests/convolution/convolution_width_thresholds.ipynb +LARGE_WIDTH_THRESHOLD = ( + 0.1 # Threshold for large widths compared to span - warn if width > 10% of span +) +SMALL_WIDTH_THRESHOLD = ( + 1.0 # Threshold for small widths compared to bin spacing - warn if width < dx +) + class NumericalConvolutionBase(ConvolutionBase): """ @@ -253,6 +261,8 @@ def _create_energy_grid( energy_dense = np.linspace(extended_min, extended_max, num_points) energy_span_dense = extended_max - extended_min + if len(energy_dense) < 2: + raise ValueError("Energy array must have at least two points.") energy_dense_step = energy_dense[1] - energy_dense[0] # Handle offset for even length of energy_dense in convolution. @@ -305,10 +315,6 @@ def _check_width_thresholds( """ - # The thresholds are illustrated in performance_tests/convolution/convolution_width_thresholds.ipynb - LARGE_WIDTH_THRESHOLD = 0.1 # Threshold for large widths compared to span - warn if width > 10% of span - SMALL_WIDTH_THRESHOLD = 1.0 # Threshold for small widths compared to bin spacing - warn if width < dx - # Handle SampleModel or ModelComponent if isinstance(model, SampleModel): components = model.components