diff --git a/.copier-answers.ess.yml b/.copier-answers.ess.yml
index c0b54ae9..d7d7e3b8 100644
--- a/.copier-answers.ess.yml
+++ b/.copier-answers.ess.yml
@@ -1,3 +1,3 @@
# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY
-_commit: 847e5e4
+_commit: 0951a4b
_src_path: https://github.com/scipp/ess_template
diff --git a/.copier-answers.yml b/.copier-answers.yml
index 33be7caf..e9f997f3 100644
--- a/.copier-answers.yml
+++ b/.copier-answers.yml
@@ -1,5 +1,5 @@
# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY
-_commit: afbe5c7
+_commit: 6848c57
_src_path: gh:scipp/copier_template
description: Diffraction data reduction for the European Spallation Source
max_python: '3.12'
diff --git a/.github/ISSUE_TEMPLATE/blank.md b/.github/ISSUE_TEMPLATE/blank.md
index 2fb131c1..22a75aeb 100644
--- a/.github/ISSUE_TEMPLATE/blank.md
+++ b/.github/ISSUE_TEMPLATE/blank.md
@@ -1,6 +1,6 @@
---
-name: blank
-about: A blank issue template
+name: Blank
+about: General issue that does not fit another category
title: ''
labels: ''
assignees: ''
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 7e5a7bc6..98aaf568 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -65,7 +65,7 @@ jobs:
name: docs_html
path: html/
- - uses: JamesIves/github-pages-deploy-action@v4.6.0
+ - uses: JamesIves/github-pages-deploy-action@v4.6.1
if: ${{ inputs.publish }}
with:
branch: gh-pages
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 508073fe..4442b1b9 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -21,7 +21,7 @@ repos:
args: [ "--drop-empty-cells",
"--extra-keys 'metadata.language_info.version cell.metadata.jp-MarkdownHeadingCollapsed cell.metadata.pycharm'" ]
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.4.1
+ rev: v0.4.3
hooks:
- id: ruff
args: [ --fix ]
diff --git a/conda/meta.yaml b/conda/meta.yaml
index 073e59d1..39a7a305 100644
--- a/conda/meta.yaml
+++ b/conda/meta.yaml
@@ -18,8 +18,9 @@ requirements:
run:
- python>=3.10
+ {# Conda does not allow spaces between package name and version, so remove them #}
{% for package in dependencies %}
- - {% if package == "graphviz" %}python-graphviz{% else %}{{ package }}{% endif %}
+ - {% if package == "graphviz" %}python-graphviz{% else %}{{ package|replace(" ", "") }}{% endif %}
{% endfor %}
diff --git a/docs/_templates/doc_version.html b/docs/_templates/doc_version.html
index 48f9aacf..35ee3b05 100644
--- a/docs/_templates/doc_version.html
+++ b/docs/_templates/doc_version.html
@@ -1,2 +1,2 @@
-Current {{ project }} version: {{ version }} (older versions).
+Current ESSdiffraction version: {{ version }} (older versions).
diff --git a/docs/conf.py b/docs/conf.py
index 92e52d92..288770a4 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,12 +1,15 @@
-# -*- coding: utf-8 -*-
-
import doctest
import os
import sys
+from importlib.metadata import PackageNotFoundError
from importlib.metadata import version as get_version
+from sphinx.util import logging
+
sys.path.insert(0, os.path.abspath("."))
+logger = logging.getLogger(__name__)
+
# General information about the project.
project = "ESSdiffraction"
copyright = "2024 Scipp contributors"
@@ -35,6 +38,8 @@
import sciline.sphinxext.domain_types # noqa: F401
extensions.append("sciline.sphinxext.domain_types")
+ # See https://github.com/tox-dev/sphinx-autodoc-typehints/issues/457
+ suppress_warnings = ["config.cache"]
except ModuleNotFoundError:
pass
@@ -111,9 +116,15 @@
# |version| and |release|, also used in various other places throughout the
# built documents.
#
-
-release = get_version("essdiffraction")
-version = ".".join(release.split(".")[:3]) # CalVer
+try:
+ release = get_version("essdiffraction")
+ version = ".".join(release.split('.')[:3]) # CalVer
+except PackageNotFoundError:
+ logger.info(
+ "Warning: determining version from package metadata failed, falling back to "
+ "a dummy version number."
+ )
+ release = version = "0.0.0-dev"
warning_is_error = True
diff --git a/pyproject.toml b/pyproject.toml
index 63c82a58..83cbb454 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -77,7 +77,7 @@ extend-exclude = [
[tool.ruff.lint]
# See https://docs.astral.sh/ruff/rules/
-select = ["B", "C4", "DTZ", "E", "F", "G", "I", "PERF", "PGH", "PT", "PYI", "RUF", "S", "T20", "W"]
+select = ["B", "C4", "DTZ", "E", "F", "G", "I", "PERF", "PGH", "PT", "PYI", "RUF", "S", "T20", "UP", "W"]
ignore = [
# Conflict with ruff format, see
# https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
diff --git a/requirements/make_base.py b/requirements/make_base.py
index 1e1f48e3..68a17e84 100644
--- a/requirements/make_base.py
+++ b/requirements/make_base.py
@@ -1,7 +1,6 @@
import sys
from argparse import ArgumentParser
from pathlib import Path
-from typing import List
import tomli
@@ -20,7 +19,7 @@
"""
-def write_dependencies(dependency_name: str, dependencies: List[str]) -> None:
+def write_dependencies(dependency_name: str, dependencies: list[str]) -> None:
path = Path(f"{dependency_name}.in")
if path.exists():
sections = path.read_text().split(CUSTOM_AUTO_SEPARATOR)
diff --git a/src/ess/dream/instrument_view.py b/src/ess/dream/instrument_view.py
index 0c7c529e..58f5e0f9 100644
--- a/src/ess/dream/instrument_view.py
+++ b/src/ess/dream/instrument_view.py
@@ -3,7 +3,7 @@
from __future__ import annotations
from html import escape
-from typing import TYPE_CHECKING, Any, Optional, Union
+from typing import TYPE_CHECKING, Any
import plopp as pp
import scipp as sc
@@ -16,9 +16,9 @@
def instrument_view(
- data: Union[sc.DataArray, sc.DataGroup, dict],
- dim: Optional[str] = None,
- pixel_size: Optional[Union[float, sc.Variable]] = None,
+ data: sc.DataArray | sc.DataGroup | dict,
+ dim: str | None = None,
+ pixel_size: float | sc.Variable | None = None,
**kwargs: Any,
) -> Box:
"""
@@ -48,7 +48,7 @@ def instrument_view(
return Box(view.children)
-def _to_data_group(data: Union[sc.DataArray, sc.DataGroup, dict]) -> sc.DataGroup:
+def _to_data_group(data: sc.DataArray | sc.DataGroup | dict) -> sc.DataGroup:
if isinstance(data, sc.DataArray):
data = sc.DataGroup({data.name or "data": data})
elif isinstance(data, dict):
@@ -71,9 +71,9 @@ class InstrumentView:
def __init__(
self,
- data: Union[sc.DataArray, sc.DataGroup, dict],
- dim: Optional[str] = None,
- pixel_size: Optional[Union[float, sc.Variable]] = None,
+ data: sc.DataArray | sc.DataGroup | dict,
+ dim: str | None = None,
+ pixel_size: float | sc.Variable | None = None,
**kwargs,
):
from plopp.widgets import SliceWidget, slice_dims
diff --git a/src/ess/dream/io/geant4.py b/src/ess/dream/io/geant4.py
index 50fb896b..d5060e4a 100644
--- a/src/ess/dream/io/geant4.py
+++ b/src/ess/dream/io/geant4.py
@@ -1,8 +1,6 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
-from typing import Dict, Optional
-
import numpy as np
import sciline
import scipp as sc
@@ -96,7 +94,7 @@ def _adjust_coords(da: sc.DataArray) -> None:
)
-def _group(detectors: Dict[str, sc.DataArray]) -> Dict[str, sc.DataGroup]:
+def _group(detectors: dict[str, sc.DataArray]) -> dict[str, sc.DataGroup]:
elements = ("module", "segment", "counter", "wire", "strip")
def group(key: str, da: sc.DataArray) -> sc.DataArray:
@@ -114,7 +112,7 @@ def group(key: str, da: sc.DataArray) -> sc.DataArray:
def _split_detectors(
data: sc.DataArray, detector_id_name: str = "det ID"
-) -> Dict[str, sc.DataArray]:
+) -> dict[str, sc.DataArray]:
groups = data.group(
sc.concat(
[
@@ -162,7 +160,7 @@ def _split_detectors(
def _extract_detector(
detector_groups: sc.DataArray, detector_id_name: str, detector_id: sc.Variable
-) -> Optional[sc.DataArray]:
+) -> sc.DataArray | None:
events = detector_groups[detector_id_name, detector_id].value
if len(events) == 0:
return None
@@ -191,10 +189,10 @@ def patch_detector_data(
def geant4_detector_dimensions(
data: RawDetectorData[SampleRun],
-) -> NeXusDetectorDimensions[NeXusDetectorName]:
+) -> NeXusDetectorDimensions:
# For geant4 data, we group by detector identifier, so the data already has
# logical dimensions, so we simply return the dimensions of the detector.
- return NeXusDetectorDimensions[NeXusDetectorName](data.sizes)
+ return NeXusDetectorDimensions(data.sizes)
def geant4_load_calibration(
diff --git a/src/ess/powder/correction.py b/src/ess/powder/correction.py
index 8e8fc4dd..38049bbe 100644
--- a/src/ess/powder/correction.py
+++ b/src/ess/powder/correction.py
@@ -2,7 +2,7 @@
# Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
"""Correction algorithms for powder diffraction."""
-from typing import Any, Dict, Optional
+from typing import Any
import scipp as sc
from scippneutron.conversion.graph import beamline, tof
@@ -30,8 +30,8 @@ def normalize_by_monitor(
data: sc.DataArray,
*,
monitor: sc.DataArray,
- wavelength_edges: Optional[sc.Variable] = None,
- smooth_args: Optional[Dict[str, Any]] = None,
+ wavelength_edges: sc.Variable | None = None,
+ smooth_args: dict[str, Any] | None = None,
) -> sc.DataArray:
"""
Normalize event data by a monitor.
diff --git a/src/ess/powder/masking.py b/src/ess/powder/masking.py
index 1e5305b3..1a4655d3 100644
--- a/src/ess/powder/masking.py
+++ b/src/ess/powder/masking.py
@@ -4,7 +4,7 @@
Masking functions for the powder workflow.
"""
-from typing import Iterable
+from collections.abc import Iterable
import numpy as np
import sciline
diff --git a/src/ess/powder/smoothing.py b/src/ess/powder/smoothing.py
index c1cd242d..4df44e7d 100644
--- a/src/ess/powder/smoothing.py
+++ b/src/ess/powder/smoothing.py
@@ -4,8 +4,6 @@
Smoothing arrays data.
"""
-from typing import Optional
-
import scipp as sc
from scipp.scipy.signal import butter
@@ -29,7 +27,7 @@ def _ensure_no_variances(var: sc.DataArray) -> sc.DataArray:
def lowpass(
- da: sc.DataArray, *, dim: str, N: int, Wn: sc.Variable, coord: Optional[str] = None
+ da: sc.DataArray, *, dim: str, N: int, Wn: sc.Variable, coord: str | None = None
) -> sc.DataArray:
"""
Smooth data using a lowpass frequency filter.
diff --git a/src/ess/powder/types.py b/src/ess/powder/types.py
index 93998698..e4006c5b 100644
--- a/src/ess/powder/types.py
+++ b/src/ess/powder/types.py
@@ -7,8 +7,9 @@
pipeline.
"""
+from collections.abc import Callable
from enum import Enum
-from typing import Any, Callable, Dict, NewType, TypeVar
+from typing import Any, NewType, TypeVar
import sciline
import scipp as sc
@@ -89,10 +90,8 @@ class DataWithScatteringCoordinates(sciline.Scope[RunType, sc.DataArray], sc.Dat
d-spacing."""
-class NeXusDetectorDimensions(
- sciline.Scope[NeXusDetectorName, Dict[str, int]], Dict[str, int]
-):
- """Logical detector dimensions."""
+NeXusDetectorDimensions = NewType("NeXusDetectorDimensions", dict[str, int])
+"""Logical detector dimensions."""
class DspacingData(sciline.Scope[RunType, sc.DataArray], sc.DataArray):
@@ -139,7 +138,7 @@ class MaskedData(sciline.Scope[RunType, sc.DataArray], sc.DataArray):
dspacing regions."""
-MaskedDetectorIDs = NewType("MaskedDetectorIDs", Dict[str, sc.Variable])
+MaskedDetectorIDs = NewType("MaskedDetectorIDs", dict[str, sc.Variable])
"""1-D variable listing all masked detector IDs."""
diff --git a/src/ess/snspowder/powgen/beamline.py b/src/ess/snspowder/powgen/beamline.py
index 7bd82dba..2b30ade9 100644
--- a/src/ess/snspowder/powgen/beamline.py
+++ b/src/ess/snspowder/powgen/beamline.py
@@ -55,11 +55,9 @@ def map_detector_to_spectrum(
def powgen_detector_dimensions(
detector_name: NeXusDetectorName,
-) -> NeXusDetectorDimensions[NeXusDetectorName]:
+) -> NeXusDetectorDimensions:
"""Dimensions used by POWGEN detectors."""
- return NeXusDetectorDimensions[NeXusDetectorName](
- DETECTOR_BANK_SIZES[detector_name]
- )
+ return NeXusDetectorDimensions(DETECTOR_BANK_SIZES[detector_name])
providers = (powgen_detector_dimensions,)
diff --git a/src/ess/snspowder/powgen/calibration.py b/src/ess/snspowder/powgen/calibration.py
index 6e2a47e3..82fa10f0 100644
--- a/src/ess/snspowder/powgen/calibration.py
+++ b/src/ess/snspowder/powgen/calibration.py
@@ -9,7 +9,6 @@
"""
from pathlib import Path
-from typing import Dict, Optional, Union
import numpy as np
import scipp as sc
@@ -28,11 +27,11 @@ def _as_boolean_mask(var: sc.Variable) -> sc.Variable:
def _parse_calibration_instrument_args(
- filename: Union[str, Path],
+ filename: str | Path,
*,
- instrument_filename: Optional[str] = None,
- instrument_name: Optional[str] = None,
-) -> Dict[str, str]:
+ instrument_filename: str | None = None,
+ instrument_name: str | None = None,
+) -> dict[str, str]:
if instrument_filename is not None:
if instrument_name is not None:
raise ValueError(
@@ -57,11 +56,11 @@ def _parse_calibration_instrument_args(
def load_calibration(
- filename: Union[str, Path],
+ filename: str | Path,
*,
- instrument_filename: Optional[str] = None,
- instrument_name: Optional[str] = None,
- mantid_args: Optional[dict] = None,
+ instrument_filename: str | None = None,
+ instrument_name: str | None = None,
+ mantid_args: dict | None = None,
) -> sc.Dataset:
"""
Load and return calibration data.
diff --git a/src/ess/snspowder/powgen/data.py b/src/ess/snspowder/powgen/data.py
index aea6e744..0ce636a0 100644
--- a/src/ess/snspowder/powgen/data.py
+++ b/src/ess/snspowder/powgen/data.py
@@ -11,7 +11,6 @@
CalibrationFilename,
Filename,
NeXusDetectorDimensions,
- NeXusDetectorName,
ProtonCharge,
RawDataAndMetadata,
ReducibleDetectorData,
@@ -104,7 +103,7 @@ def pooch_load(filename: Filename[RunType]) -> RawDataAndMetadata[RunType]:
def pooch_load_calibration(
filename: CalibrationFilename,
- detector_dimensions: NeXusDetectorDimensions[NeXusDetectorName],
+ detector_dimensions: NeXusDetectorDimensions,
) -> CalibrationData:
"""Load the calibration data for the POWGEN test data."""
if filename is None:
@@ -120,7 +119,7 @@ def pooch_load_calibration(
def extract_raw_data(
- dg: RawDataAndMetadata[RunType], sizes: NeXusDetectorDimensions[NeXusDetectorName]
+ dg: RawDataAndMetadata[RunType], sizes: NeXusDetectorDimensions
) -> ReducibleDetectorData[RunType]:
"""Return the events from a loaded data group."""
# Remove the tof binning and dimension, as it is not needed and it gets in the way
diff --git a/src/ess/snspowder/powgen/instrument_view.py b/src/ess/snspowder/powgen/instrument_view.py
index 15002c59..677c04f0 100644
--- a/src/ess/snspowder/powgen/instrument_view.py
+++ b/src/ess/snspowder/powgen/instrument_view.py
@@ -1,6 +1,5 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
-from typing import Optional
import scipp as sc
import scippneutron as scn
@@ -9,8 +8,8 @@
def instrument_view(
da: sc.DataArray,
positions: str = "position",
- pixel_size: Optional[float] = None,
- components: Optional[dict] = None,
+ pixel_size: float | None = None,
+ components: dict | None = None,
**kwargs,
):
"""
diff --git a/tests/dream/io/geant4_test.py b/tests/dream/io/geant4_test.py
index b2162a16..74522663 100644
--- a/tests/dream/io/geant4_test.py
+++ b/tests/dream/io/geant4_test.py
@@ -3,7 +3,6 @@
import zipfile
from io import BytesIO
-from typing import Optional, Set
import numpy as np
import pytest
@@ -49,9 +48,7 @@ def file_without_sans(load_file_without_sans):
return BytesIO(load_file_without_sans)
-def assert_index_coord(
- coord: sc.Variable, *, values: Optional[Set[int]] = None
-) -> None:
+def assert_index_coord(coord: sc.Variable, *, values: set[int] | None = None) -> None:
assert coord.ndim == 1
assert coord.unit is None
assert coord.dtype == "int64"
diff --git a/tests/powder/filtering_test.py b/tests/powder/filtering_test.py
index 3c4b9604..95661cae 100644
--- a/tests/powder/filtering_test.py
+++ b/tests/powder/filtering_test.py
@@ -2,8 +2,6 @@
# Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
# @author Jan-Lukas Wynen
-from typing import Tuple
-
import numpy as np
import scipp as sc
@@ -58,7 +56,7 @@ def test_make_data_with_pulse_time():
def make_data_with_pulse_time_and_proton_charge(
rng, n_event, n_proton_charge, bad_charge, bad_charge_indices
-) -> Tuple[sc.DataArray, sc.DataArray]:
+) -> tuple[sc.DataArray, sc.DataArray]:
data = make_data_with_pulse_time(rng, n_event)
start_time = data.bins.coords['pulse_time'].min()