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
2 changes: 1 addition & 1 deletion .copier-answers.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# WARNING: Do not edit this file manually.
# Any changes will be overwritten by Copier.
_commit: v0.10.1-23-g55e8e0e
_commit: v0.10.1-25-ga5301e9
_src_path: gh:easyscience/templates
app_docs_url: https://easyscience.github.io/dynamics-app
app_doi: 10.5281/zenodo.18877180
Expand Down
11 changes: 4 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04, macos-14, windows-2022]
os: [ubuntu-24.04, macos-15, windows-2022]

runs-on: ${{ matrix.os }}

Expand Down Expand Up @@ -163,7 +163,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04, macos-14, windows-2022]
os: [ubuntu-24.04, macos-15, windows-2022]

runs-on: ${{ matrix.os }}

Expand Down Expand Up @@ -202,11 +202,8 @@ jobs:
echo "Adding Python $py_ver"
pixi add "python=$py_ver"

echo "Adding Conda dependencies"
pixi add gsl

#echo "Adding PyPI dependencies"
#pixi add --pypi pytest pytest-xdist
echo "Setting macOS 14.0 as minimum required"
pixi project system-requirements add macos 14.0

echo "Looking for wheel in ../dist/py$py_ver/"
ls -l "../dist/py$py_ver/"
Expand Down
5 changes: 2 additions & 3 deletions docs/docs/tutorials/analysis1d.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@
")\n",
"\n",
"fit_result = my_analysis.fit()\n",
"fig = my_analysis.plot_data_and_model()\n",
"fig"
"my_analysis.plot_data_and_model()"
]
}
],
Expand All @@ -102,7 +101,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.13"
"version": "3.12.12"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this downgrade expected?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like I ran that notebook in a different environment.. I don't think it really matters?

}
},
"nbformat": 4,
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/tutorials/convolution.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"from easydynamics.sample_model import Gaussian\n",
"from easydynamics.sample_model import Lorentzian\n",
"from easydynamics.sample_model.component_collection import ComponentCollection\n",
"from easydynamics.utils import _detailed_balance_factor as detailed_balance_factor\n",
"from easydynamics.utils import detailed_balance_factor\n",
"\n",
"%matplotlib widget"
]
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/tutorials/detailed_balance.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n",
"from easydynamics.utils import _detailed_balance_factor as detailed_balance_factor\n",
"from easydynamics.utils import detailed_balance_factor\n",
"\n",
"%matplotlib widget"
]
Expand Down
1,392 changes: 641 additions & 751 deletions pixi.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ check = 'pre-commit run --hook-stage manual --all-files'
docs-format-fix = 'docformatter --in-place src/ docs/docs/tutorials/'
notebook-lint-fix = 'nbqa ruff --fix docs/docs/tutorials/'
py-lint-fix = 'ruff check --fix src/ tests/ docs/docs/tutorials/'
py-lint-fix-unsafe = 'ruff check --fix --unsafe-fixes src/ tests/ docs/docs/tutorials/'
py-format-fix = "ruff format src/ tests/ docs/docs/tutorials/"
nonpy-format-fix = 'npx prettier --write --list-different --config=prettierrc.toml --ignore-unknown .'
nonpy-format-fix-modified = "python tools/nonpy_prettier_modified.py --write"
Expand Down
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ select = [
#'PERF', # https://docs.astral.sh/ruff/rules/#perflint-perf
#'RUF', # https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf
#'TRY', # https://docs.astral.sh/ruff/rules/#tryceratops-try
#'UP', # https://docs.astral.sh/ruff/rules/#pyupgrade-up
'UP', # https://docs.astral.sh/ruff/rules/#pyupgrade-up
# pycodestyle (E, W) rules
'E', # https://docs.astral.sh/ruff/rules/#error-e
'W', # https://docs.astral.sh/ruff/rules/#warning-w
Expand All @@ -218,7 +218,7 @@ select = [
'ANN', # https://docs.astral.sh/ruff/rules/#flake8-annotations-ann
#'ARG', # https://docs.astral.sh/ruff/rules/#flake8-unused-arguments-arg
#'ASYNC', # https://docs.astral.sh/ruff/rules/#flake8-async-async
#'B', # https://docs.astral.sh/ruff/rules/#flake8-bugbear-b
'B', # https://docs.astral.sh/ruff/rules/#flake8-bugbear-b
#'BLE', # https://docs.astral.sh/ruff/rules/#flake8-blind-except-ble
#'C4', # https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4
#'COM', # https://docs.astral.sh/ruff/rules/#flake8-commas-com
Expand All @@ -238,8 +238,8 @@ select = [
#'PYI', # https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi
#'RET', # https://docs.astral.sh/ruff/rules/#flake8-return-ret
#'RSE', # https://docs.astral.sh/ruff/rules/#flake8-raise-rse
'S', # https://docs.astral.sh/ruff/rules/#flake8-bandit-s
#'SIM', # https://docs.astral.sh/ruff/rules/#flake8-simplify-sim
'S', # https://docs.astral.sh/ruff/rules/#flake8-bandit-s
'SIM', # https://docs.astral.sh/ruff/rules/#flake8-simplify-sim
#'SLF', # https://docs.astral.sh/ruff/rules/#flake8-self-slf
#'SLOT', # https://docs.astral.sh/ruff/rules/#flake8-slots-slot
#'T20', # https://docs.astral.sh/ruff/rules/#flake8-print-t20
Expand Down
4 changes: 2 additions & 2 deletions src/easydynamics/analysis/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ def plot_data_and_model(
components = self._create_components_dataset(
add_background=add_background, energy=energy
)
for key in components.keys():
for key in components:
data_and_model[key] = components[key]
plot_kwargs_defaults['linestyle'][key] = '--'
plot_kwargs_defaults['marker'][key] = None
Expand Down Expand Up @@ -362,7 +362,7 @@ def parameters_to_dataset(self) -> sc.Dataset:
dims=['Q'],
values=np.asarray(values[name], dtype=float),
variances=np.asarray(variances[name], dtype=float),
unit=units.get(name, None),
unit=units.get(name),
)

return ds
Expand Down
2 changes: 1 addition & 1 deletion src/easydynamics/analysis/analysis1d.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ def plot_data_and_model(
}

if plot_components:
for comp_name in component_dataset.keys():
for comp_name in component_dataset:
plot_kwargs_defaults['linestyle'][comp_name] = '--'
plot_kwargs_defaults['marker'][comp_name] = None

Expand Down
13 changes: 6 additions & 7 deletions src/easydynamics/analysis/analysis_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,13 +325,12 @@ def _verify_Q_index(self, Q_index: int | None) -> int | None:
Raises:
IndexError: If the Q index is not valid.
"""
if Q_index is not None:
if (
not isinstance(Q_index, int)
or Q_index < 0
or (self.Q is not None and Q_index >= len(self.Q))
):
raise IndexError('Q_index must be a valid index for the Q values.')
if Q_index is not None and (
not isinstance(Q_index, int)
or Q_index < 0
or (self.Q is not None and Q_index >= len(self.Q))
):
raise IndexError('Q_index must be a valid index for the Q values.')
return Q_index

#############
Expand Down
10 changes: 4 additions & 6 deletions src/easydynamics/convolution/convolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,10 @@ def _check_if_pair_is_analytic(
)

analytical_types = (Gaussian, Lorentzian, Voigt)
if isinstance(sample_component, analytical_types) and isinstance(
resolution_component, analytical_types
):
return True

return False
return bool(
isinstance(sample_component, analytical_types)
and isinstance(resolution_component, analytical_types)
)

def _build_convolution_plan(self) -> None:
"""Separate sample model components into analytical pairs, delta
Expand Down
12 changes: 4 additions & 8 deletions src/easydynamics/convolution/convolution_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ def __init__(
self._energy_offset = energy_offset

if sample_components is not None and not (
isinstance(sample_components, ComponentCollection)
or isinstance(sample_components, ModelComponent)
isinstance(sample_components, (ComponentCollection, ModelComponent))
):
raise TypeError(
f'`sample_components` is an instance of {type(sample_components).__name__}, but must be a ComponentCollection or ModelComponent.' # noqa: E501
Expand All @@ -81,8 +80,7 @@ def __init__(
self._sample_components = sample_components

if resolution_components is not None and not (
isinstance(resolution_components, ComponentCollection)
or isinstance(resolution_components, ModelComponent)
isinstance(resolution_components, (ComponentCollection, ModelComponent))
):
raise TypeError(
f'`resolution_components` is an instance of {type(resolution_components).__name__}, but must be a ComponentCollection or ModelComponent.' # noqa: E501
Expand Down Expand Up @@ -196,10 +194,8 @@ def energy_unit(self) -> str:
@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.'
)
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: str | sc.Unit) -> None:
Expand Down
2 changes: 1 addition & 1 deletion src/easydynamics/convolution/numerical_convolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from easydynamics.convolution.numerical_convolution_base import NumericalConvolutionBase
from easydynamics.sample_model.component_collection import ComponentCollection
from easydynamics.sample_model.components.model_component import ModelComponent
from easydynamics.utils.detailed_balance import _detailed_balance_factor as detailed_balance_factor
from easydynamics.utils.detailed_balance import detailed_balance_factor
from easydynamics.utils.utils import Numeric


Expand Down
18 changes: 6 additions & 12 deletions src/easydynamics/convolution/numerical_convolution_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
import warnings

# from dataclasses import dataclass
from typing import Optional

import numpy as np
import scipp as sc
from easyscience.variable import Parameter
Expand Down Expand Up @@ -194,11 +192,11 @@ def extension_factor(self, factor: Numeric) -> None:
self._energy_grid = self._create_energy_grid()

@property
def temperature(self) -> Optional[Parameter]:
def temperature(self) -> Parameter | None:
"""Get the temperature.

Returns:
Optional[Parameter]: The temperature parameter, or None if
Parameter | None: The temperature parameter, or None if
detailed balance correction is disabled.
"""

Expand Down Expand Up @@ -322,10 +320,7 @@ def _create_energy_grid(
# 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_dense_step
else:
energy_even_length_offset = 0.0
energy_even_length_offset = -0.5 * energy_dense_step if len(energy_dense) % 2 == 0 else 0.0

# Handle the case when energy_dense is not symmetric around 0.
# The resolution is still centered around zero (or close to it),
Expand Down Expand Up @@ -367,10 +362,7 @@ def _check_width_thresholds(
"""

# Handle ComponentCollection or ModelComponent
if isinstance(model, ComponentCollection):
components = model.components
else:
components = [model] # Treat single ModelComponent as a list
components = model.components if isinstance(model, ComponentCollection) else [model]

for comp in components:
if hasattr(comp, 'width'):
Expand All @@ -382,6 +374,7 @@ def _check_width_thresholds(
This may lead to inaccuracies in the convolution. \
Increase extension_factor to improve accuracy.',
UserWarning,
stacklevel=3,
)
if comp.width.value < SMALL_WIDTH_THRESHOLD * self._energy_grid.energy_dense_step:
warnings.warn(
Expand All @@ -391,6 +384,7 @@ def _check_width_thresholds(
This may lead to inaccuracies in the convolution. \
Increase upsample_factor to improve accuracy.',
UserWarning,
stacklevel=3,
)

def __repr__(self) -> str:
Expand Down
2 changes: 1 addition & 1 deletion src/easydynamics/experiment/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ def rebin(self, dimensions: dict[str, int | sc.Variable]) -> None:
# This line can be removed when scipp resize support
# resizing with coordinates
dimensions[dim] = value
if not (isinstance(value, int) or isinstance(value, sc.Variable)):
if not (isinstance(value, (int, sc.Variable))):
raise TypeError(
f'Dimension values must be integers or sc.Variable. '
f"Got {type(value)} for dimension '{dim}' instead."
Expand Down
16 changes: 7 additions & 9 deletions src/easydynamics/sample_model/component_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from __future__ import annotations

import warnings
from typing import List

import numpy as np
import scipp as sc
Expand Down Expand Up @@ -146,10 +145,8 @@ 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.'
)
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_unit(self, unit: str | sc.Unit) -> None:
Expand Down Expand Up @@ -187,7 +184,7 @@ def convert_unit(self, unit: str | sc.Unit) -> None:
# Component management
# ------------------------------------------------------------------

def append_component(self, component: ModelComponent | 'ComponentCollection') -> None:
def append_component(self, component: ModelComponent | ComponentCollection) -> None:
"""Append a model component or the components from another
ComponentCollection to this ComponentCollection.

Expand Down Expand Up @@ -302,11 +299,11 @@ def is_empty(self, value: bool) -> None:
'whether the collection has components.'
)

def list_component_names(self) -> List[str]:
def list_component_names(self) -> list[str]:
"""List the names of all components in the model.

Returns:
List[str]: List of unique names of the components in the
list[str]: List of unique names of the components in the
collection.
"""

Expand Down Expand Up @@ -340,6 +337,7 @@ def normalize_area(self) -> None:
f"Component '{component.unique_name}' does not have an 'area' attribute "
f'and will be skipped in normalization.',
UserWarning,
stacklevel=2,
)

if total_area.value == 0:
Expand Down Expand Up @@ -404,7 +402,7 @@ def evaluate_component(

if not isinstance(unique_name, str):
raise TypeError(
(f'Component unique name must be a string, got {type(unique_name)} instead.')
f'Component unique name must be a string, got {type(unique_name)} instead.'
)

matches = [comp for comp in self.components if comp.unique_name == unique_name]
Expand Down
4 changes: 2 additions & 2 deletions src/easydynamics/sample_model/components/delta_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,13 @@ def evaluate(self, x: Numeric | list | np.ndarray | sc.Variable | sc.DataArray)
i = np.argmin(np.abs(x - center))

# left half-width
if i == 0:
if i == 0: # noqa: SIM108
left = x[1] - x[0] if x.size > 1 else 0.5
else:
left = x[i] - x[i - 1]

# right half-width
if i == x.size - 1:
if i == x.size - 1: # noqa: SIM108
right = x[-1] - x[-2] if x.size > 1 else 0.5
else:
right = x[i + 1] - x[i]
Expand Down
4 changes: 3 additions & 1 deletion src/easydynamics/sample_model/components/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ def _create_area_parameter(

if area.value < 0:
warnings.warn(
f'The area of {name} is negative, which may not be physically meaningful.'
f'The area of {name} is negative, which may not be physically meaningful.',
UserWarning,
stacklevel=3,
)
else:
area.min = minimum_area
Expand Down
Loading
Loading