Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/docs/tutorials/sample_model.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "easydynamics_newbase",
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
Expand All @@ -148,7 +148,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.12"
"version": "3.14.4"
}
},
"nbformat": 4,
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/tutorials/tutorial0_basics.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": null,
"id": "7121f9c8",
"metadata": {},
"outputs": [],
Expand Down
2 changes: 1 addition & 1 deletion src/easydynamics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"""EasyDynamics library."""

from easydynamics.analysis import Analysis
from easydynamics.convolution.convolution_settings import ConvolutionSettings
from easydynamics.experiment import Experiment
from easydynamics.settings.convolution_settings import ConvolutionSettings

__all__ = [
'Analysis',
Expand Down
9 changes: 8 additions & 1 deletion src/easydynamics/analysis/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@

from easydynamics.analysis.analysis1d import Analysis1d
from easydynamics.analysis.analysis_base import AnalysisBase
from easydynamics.convolution.convolution_settings import ConvolutionSettings
from easydynamics.experiment import Experiment
from easydynamics.sample_model import SampleModel
from easydynamics.sample_model.instrument_model import InstrumentModel
from easydynamics.settings.convolution_settings import ConvolutionSettings
from easydynamics.settings.detailed_balance_settings import DetailedBalanceSettings
from easydynamics.utils.utils import _in_notebook


Expand All @@ -35,6 +36,7 @@ def __init__(
sample_model: SampleModel | None = None,
instrument_model: InstrumentModel | None = None,
convolution_settings: ConvolutionSettings | None = None,
detailed_balance_settings: DetailedBalanceSettings | None = None,
extra_parameters: Parameter | list[Parameter] | None = None,
) -> None:
"""
Expand All @@ -56,6 +58,8 @@ def __init__(
is created.
convolution_settings : ConvolutionSettings | None, default=None
The settings for the convolution. If None, default settings will be used.
detailed_balance_settings : DetailedBalanceSettings | None, default=None
The settings for detailed balance. If None, default settings will be used.
extra_parameters : Parameter | list[Parameter] | None, default=None
Extra parameters to be included in the analysis for advanced users. If None, no extra
parameters are added.
Expand All @@ -71,6 +75,7 @@ def __init__(
sample_model=sample_model,
instrument_model=instrument_model,
convolution_settings=convolution_settings,
detailed_balance_settings=detailed_balance_settings,
extra_parameters=extra_parameters,
)

Expand Down Expand Up @@ -538,6 +543,8 @@ def _create_analysis_list(self) -> None:
experiment=self.experiment,
sample_model=self.sample_model,
instrument_model=self.instrument_model,
convolution_settings=self.convolution_settings,
detailed_balance_settings=self.detailed_balance_settings,
extra_parameters=self._extra_parameters,
Q_index=Q_index,
)
Expand Down
58 changes: 46 additions & 12 deletions src/easydynamics/analysis/analysis1d.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@

from easydynamics.analysis.analysis_base import AnalysisBase
from easydynamics.convolution.convolution import Convolution
from easydynamics.convolution.convolution_settings import ConvolutionSettings
from easydynamics.experiment import Experiment
from easydynamics.sample_model import InstrumentModel
from easydynamics.sample_model import SampleModel
from easydynamics.sample_model.component_collection import ComponentCollection
from easydynamics.sample_model.components.model_component import ModelComponent
from easydynamics.settings.convolution_settings import ConvolutionSettings
from easydynamics.settings.detailed_balance_settings import DetailedBalanceSettings
from easydynamics.utils.detailed_balance import detailed_balance_factor


class Analysis1d(AnalysisBase):
Expand All @@ -37,6 +39,7 @@ def __init__(
instrument_model: InstrumentModel | None = None,
Q_index: int | None = None,
convolution_settings: ConvolutionSettings | None = None,
detailed_balance_settings: DetailedBalanceSettings | None = None,
extra_parameters: Parameter | list[Parameter] | None = None,
) -> None:
"""
Expand All @@ -61,6 +64,8 @@ def __init__(
until a Q index is set.
convolution_settings : ConvolutionSettings | None, default=None
The settings for the convolution. If None, default settings will be used.
detailed_balance_settings : DetailedBalanceSettings | None, default=None
The settings for detailed balance. If None, default settings will be used.
extra_parameters : Parameter | list[Parameter] | None, default=None
Extra parameters to be included in the analysis for advanced users. If None, no extra
parameters are added.
Expand All @@ -72,6 +77,7 @@ def __init__(
sample_model=sample_model,
instrument_model=instrument_model,
convolution_settings=convolution_settings,
detailed_balance_settings=detailed_balance_settings,
extra_parameters=extra_parameters,
)

Expand Down Expand Up @@ -452,6 +458,7 @@ def _evaluate_components(
convolver: Convolution | None = None,
convolve: bool = True,
energy: sc.Variable | None = None,
apply_detailed_balance: bool = False,
) -> np.ndarray:
"""
Calculate the contribution of a set of components, optionally convolving with the
Expand All @@ -475,6 +482,9 @@ def _evaluate_components(
energy : sc.Variable | None, default=None
Optional energy grid to use for evaluation. If None, the energy grid from the
experiment is used.
apply_detailed_balance : bool, default=False
Whether to apply detailed balance correction.


Returns
-------
Expand All @@ -496,24 +506,42 @@ def _evaluate_components(
if isinstance(components, ComponentCollection) and components.is_empty:
return np.zeros_like(energy.values)

# No convolution
if not convolve:
return components.evaluate(energy_with_offset)

# If a convolver is provided, use it. This allows reusing the
# If a convolver is provided, we use it. This allows reusing the
# same convolver for multiple evaluations during fitting for
# performance reasons.
if convolver is not None:
return convolver.convolution()

# If no convolver is provided, create a new one. This is for
# evaluating individual components for plotting, where
# performance is not important.
# No convolution can happen for multiple reasons:
# Case 1: convolve=False, used for evaluating background components, where we don't want
# to convolve with the resolution. In this case, apply_detailed_balance is False,
# and we evaluate the components without DBF regardles of the settings
# Case 2: convolve=True but there is no resolution_model. In this case,
# apply_detailed_balance is True. We apply DBF if temperature is provided and
# the settings say to use detailed balance.

# We don't create a convolver if the resolution is empty.
resolution = self.instrument_model.resolution_model.get_component_collection(Q_index)
if resolution.is_empty:
return components.evaluate(energy_with_offset)
if not convolve or resolution.is_empty:
result_no_convolution = components.evaluate(energy_with_offset)
if (
apply_detailed_balance
and self.temperature is not None
and self.detailed_balance_settings.use_detailed_balance
):
DBF = detailed_balance_factor(
energy=energy_with_offset,
temperature=self.temperature,
divide_by_temperature=self.detailed_balance_settings.normalize_detailed_balance,
energy_unit=self.unit,
)
result_no_convolution *= DBF
return result_no_convolution

# If no convolver is provided, we create a new one. This is for
# evaluating individual components for plotting, where
# performance is not important. We already handled the case of
# background components above, so we know that this is for sample components,
# where detailed balance settings should be applied.

conv = Convolution(
energy=energy,
Expand All @@ -522,6 +550,7 @@ def _evaluate_components(
energy_offset=energy_offset,
convolution_settings=self.convolution_settings,
temperature=self.temperature,
detailed_balance_settings=self.detailed_balance_settings,
)
return conv.convolution()

Expand Down Expand Up @@ -552,6 +581,7 @@ def _evaluate_sample(
convolver=self._convolver,
convolve=True,
energy=energy,
apply_detailed_balance=True,
)

def _evaluate_sample_component(
Expand Down Expand Up @@ -580,6 +610,7 @@ def _evaluate_sample_component(
convolver=None,
convolve=True,
energy=energy,
apply_detailed_balance=True,
)

def _evaluate_background(self, energy: sc.Variable | None = None) -> np.ndarray:
Expand All @@ -606,6 +637,7 @@ def _evaluate_background(self, energy: sc.Variable | None = None) -> np.ndarray:
convolver=None,
convolve=False,
energy=energy,
apply_detailed_balance=False,
)

def _evaluate_background_component(
Expand Down Expand Up @@ -635,6 +667,7 @@ def _evaluate_background_component(
convolver=None,
convolve=False,
energy=energy,
apply_detailed_balance=False,
)

def _create_convolver(
Expand Down Expand Up @@ -678,6 +711,7 @@ def _create_convolver(
energy_offset=self.instrument_model.get_energy_offset(Q_index),
convolution_settings=self.convolution_settings,
temperature=self.temperature,
detailed_balance_settings=self.detailed_balance_settings,
)

#############
Expand Down
56 changes: 51 additions & 5 deletions src/easydynamics/analysis/analysis_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@

import numpy as np
import scipp as sc
from easyscience.base_classes.model_base import ModelBase as EasyScienceModelBase
from easyscience.variable import Parameter

from easydynamics.convolution.convolution_settings import ConvolutionSettings
from easydynamics.base_classes.easydynamics_modelbase import EasyDynamicsModelBase
from easydynamics.experiment import Experiment
from easydynamics.sample_model import InstrumentModel
from easydynamics.sample_model import SampleModel
from easydynamics.settings.convolution_settings import ConvolutionSettings
from easydynamics.settings.detailed_balance_settings import DetailedBalanceSettings


class AnalysisBase(EasyScienceModelBase):
class AnalysisBase(EasyDynamicsModelBase):
"""
Base class for analysis in EasyDynamics.

Expand All @@ -31,6 +32,7 @@ def __init__(
sample_model: SampleModel | None = None,
instrument_model: InstrumentModel | None = None,
convolution_settings: ConvolutionSettings | None = None,
detailed_balance_settings: DetailedBalanceSettings | None = None,
extra_parameters: Parameter | list[Parameter] | None = None,
) -> None:
"""
Expand All @@ -53,6 +55,8 @@ def __init__(
is created.
convolution_settings : ConvolutionSettings | None, default=None
The settings for the convolution. If None, default settings will be used.
detailed_balance_settings : DetailedBalanceSettings | None, default=None
The settings for detailed balance. If None, default settings will be used.
extra_parameters : Parameter | list[Parameter] | None, default=None
Extra parameters to be included in the analysis for advanced users. If None, no extra
parameters are added.
Expand All @@ -61,8 +65,10 @@ def __init__(
------
TypeError
If experiment is not an Experiment or None or if sample_model is not a SampleModel or
None or if instrument_model is not an InstrumentModel or None or if extra_parameters is
not a Parameter, a list of Parameters, or None.
None or if instrument_model is not an InstrumentModel or None or if
convolution_settings is not a ConvolutionSettings or None or if
detailed_balance_settings is not a DetailedBalanceSettings or None or if
extra_parameters is not a Parameter, a list of Parameters, or None.
"""

super().__init__(display_name=display_name, unique_name=unique_name)
Expand Down Expand Up @@ -109,6 +115,15 @@ def __init__(
else:
self._extra_parameters = []

if detailed_balance_settings is None:
self._detailed_balance_settings = DetailedBalanceSettings()
elif isinstance(detailed_balance_settings, DetailedBalanceSettings):
self._detailed_balance_settings = detailed_balance_settings
else:
raise TypeError(
'detailed_balance_settings must be an instance of DetailedBalanceSettings or None.'
)

self._on_experiment_changed()

#############
Expand Down Expand Up @@ -338,6 +353,37 @@ def convolution_settings(self, value: ConvolutionSettings) -> None:
self._convolution_settings = value
self._on_convolution_settings_changed()

@property
def detailed_balance_settings(self) -> DetailedBalanceSettings:
"""
Get the DetailedBalanceSettings of the SampleModel.

Returns
-------
DetailedBalanceSettings
The DetailedBalanceSettings of the SampleModel.
"""
return self._detailed_balance_settings

@detailed_balance_settings.setter
def detailed_balance_settings(self, value: DetailedBalanceSettings) -> None:
"""
Set the DetailedBalanceSettings of the SampleModel.

Parameters
----------
value : DetailedBalanceSettings
The DetailedBalanceSettings to set.

Raises
------
TypeError
If value is not a DetailedBalanceSettings.
"""
if not isinstance(value, DetailedBalanceSettings):
raise TypeError('detailed_balance_settings must be a DetailedBalanceSettings')
self._detailed_balance_settings = value

@property
def extra_parameters(self) -> list[Parameter]:
"""
Expand Down
3 changes: 1 addition & 2 deletions src/easydynamics/convolution/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@
# SPDX-License-Identifier: BSD-3-Clause

from easydynamics.convolution.convolution import Convolution
from easydynamics.convolution.convolution_settings import ConvolutionSettings

__all__ = ['Convolution', 'ConvolutionSettings']
__all__ = ['Convolution']
Loading
Loading