diff --git a/.github/workflows_disabled b/.github/workflows/ci.yml similarity index 64% rename from .github/workflows_disabled rename to .github/workflows/ci.yml index 9292384..fca6f8f 100644 --- a/.github/workflows_disabled +++ b/.github/workflows/ci.yml @@ -6,12 +6,15 @@ on: pull_request: branches: [main, dev] +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v4 @@ -25,13 +28,10 @@ jobs: python -m pip install --upgrade pip pip install .[dev] - - name: Lint with flake8 + - name: Lint with ruff run: | - pip install flake8 - flake8 spinstep --count --select=E9,F63,F7,F82 --show-source --statistics - flake8 spinstep --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + ruff check spinstep/ - name: Test with pytest run: | - pip install pytest pytest tests/ diff --git a/dev-requirements.txt b/dev-requirements.txt index e6341fc..37eec1c 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,16 +1,7 @@ -# Optional scientific stack -matplotlib>=3.7 -numba>=0.57 -cython>=0.29 -cupy - -# Optional GPU tooling -pycuda - # Testing pytest -# Optional Code quality / tooling +# Code quality / tooling black ruff mypy diff --git a/spinstep/discrete.py b/spinstep/discrete.py index 3e6418d..48ab185 100644 --- a/spinstep/discrete.py +++ b/spinstep/discrete.py @@ -6,7 +6,7 @@ from __future__ import annotations -from typing import Any, Optional, Union +from typing import Any import numpy as np from numpy.typing import ArrayLike diff --git a/spinstep/node.py b/spinstep/node.py index e95182b..e4cbd6d 100644 --- a/spinstep/node.py +++ b/spinstep/node.py @@ -6,7 +6,7 @@ from __future__ import annotations -from typing import List, Optional, Sequence, Union +from typing import List, Optional, Sequence import numpy as np from numpy.typing import ArrayLike diff --git a/tests/test_utils.py b/tests/test_utils.py index d8c1102..650885a 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -210,3 +210,29 @@ def test_relative_spin_nonzero(self): q = get_relative_spin(n1, n2) # Should be a unit quaternion assert np.linalg.norm(q) == pytest.approx(1.0, abs=1e-6) + + +# ===== get_unique_relative_spins tests (requires healpy) ===== + + +class TestGetUniqueRelativeSpins: + def test_returns_list_of_unit_quaternions(self): + """Unique spins should be a list of unit quaternions.""" + hp = pytest.importorskip("healpy", reason="healpy not installed") + from spinstep.utils.quaternion_utils import get_unique_relative_spins + + nside = 1 + npix = hp.nside2npix(nside) + # Build nodes with orientations derived from HEALPix pixel directions + nodes = [] + for i in range(npix): + theta, phi = hp.pix2ang(nside, i, nest=True) + q = R.from_euler("yz", [theta, phi], degrees=False).as_quat() + nodes.append(Node(f"n{i}", q)) + + spins = get_unique_relative_spins(nodes, nside=nside, nest=True) + assert isinstance(spins, list) + assert len(spins) > 0 + for q in spins: + assert np.linalg.norm(q) == pytest.approx(1.0, abs=1e-6) + assert q[3] >= 0 # canonical form (w >= 0)