Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
149 commits
Select commit Hold shift + click to select a range
5c08081
init
selmanozleyen Apr 2, 2026
5847d84
doc clarifications
selmanozleyen Apr 2, 2026
179ba06
don't expose the builders
selmanozleyen Apr 2, 2026
e187aba
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 2, 2026
cdb5699
deduplicate
selmanozleyen Apr 2, 2026
847a46b
Merge branch 'feat/spatial_neighbours' of https://github.com/selmanoz…
selmanozleyen Apr 2, 2026
69cda1a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 2, 2026
fddc027
arrange builders
selmanozleyen Apr 2, 2026
a30988a
Merge branch 'feat/spatial_neighbours' of https://github.com/selmanoz…
selmanozleyen Apr 2, 2026
f194b10
better behaviour
selmanozleyen Apr 2, 2026
ae1eba1
move classes
selmanozleyen Apr 2, 2026
a86572b
Merge branch 'main' into feat/spatial_neighbours
selmanozleyen Apr 2, 2026
039b852
cleanup
selmanozleyen Apr 2, 2026
4699993
Merge branch 'feat/spatial_neighbours' of https://github.com/selmanoz…
selmanozleyen Apr 2, 2026
b5dcf9f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 2, 2026
4c11adf
add docs
selmanozleyen Apr 2, 2026
2b937e9
Merge branch 'feat/spatial_neighbours' of https://github.com/selmanoz…
selmanozleyen Apr 2, 2026
ea1ce93
remove leftover
selmanozleyen Apr 2, 2026
ebb7fd5
resolution in reolve func
selmanozleyen Apr 2, 2026
69a9394
reduce dup code
selmanozleyen Apr 2, 2026
77755ed
deprecate invalid n_neighs
selmanozleyen Apr 2, 2026
d8a8145
expose new functions and deprecate the flat one
selmanozleyen Apr 2, 2026
2e75b3f
move branches to classes
selmanozleyen Apr 2, 2026
8c1c2ef
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 2, 2026
268d30c
remove radius abstraction
selmanozleyen Apr 2, 2026
3f41243
Merge branch 'feat/spatial_neighbours' of https://github.com/selmanoz…
selmanozleyen Apr 2, 2026
aa9734a
add extensibility page
selmanozleyen Apr 2, 2026
67bad43
unprivate methods and add extensibility page
selmanozleyen Apr 2, 2026
65fa245
give a better example
selmanozleyen Apr 2, 2026
85bfdeb
apply signature suggestion
selmanozleyen Apr 9, 2026
79f584f
reorganize abstractions
selmanozleyen Apr 9, 2026
43cdbb6
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 9, 2026
e632f74
remove unnecessary abstraction
selmanozleyen Apr 9, 2026
1f9da0e
Merge branch 'feat/spatial_neighbours' of https://github.com/selmanoz…
selmanozleyen Apr 9, 2026
c026860
put the warning in resolve graph builder code
selmanozleyen Apr 9, 2026
10cc2f0
remove n_neighs from RadiusBuilder
selmanozleyen Apr 9, 2026
6477f18
definition of Adj, Dst and rename to adj, dst
selmanozleyen Apr 9, 2026
516b3e0
Generalize the base class for extensibility
selmanozleyen Apr 10, 2026
141fdb6
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 10, 2026
1fe316b
update docs
selmanozleyen Apr 10, 2026
bc6746a
Merge branch 'feat/spatial_neighbours' of https://github.com/selmanoz…
selmanozleyen Apr 10, 2026
bb1ec50
clarify delauney vs grid
selmanozleyen Apr 10, 2026
84cbdc4
dtype rec
selmanozleyen Apr 10, 2026
6d942ec
be a bit more verbose on funcitons
selmanozleyen Apr 10, 2026
ae9a4e6
spatial_neighbours_from_builder
selmanozleyen Apr 10, 2026
cd3f6fd
update docs to refer to each other
selmanozleyen Apr 10, 2026
95012dc
refer to the classes properly
selmanozleyen Apr 10, 2026
5a02b59
mark as TODO's
selmanozleyen Apr 13, 2026
3af98cc
rename sugg
selmanozleyen Apr 13, 2026
e8a19d7
add combine into API
selmanozleyen Apr 13, 2026
ac682a3
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 13, 2026
0f3329c
update docs
selmanozleyen Apr 13, 2026
00ec2b0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 13, 2026
042f749
[pre-commit.ci] pre-commit autoupdate (#1149)
pre-commit-ci[bot] Apr 10, 2026
1a87841
Functions to QC histopathology images (#1036)
timtreis Apr 10, 2026
1cb6fde
remove coord_type abstraction
selmanozleyen Apr 13, 2026
8afcd03
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 13, 2026
3c4dffb
Merge branch 'main' into feat/spatial_neighbours
selmanozleyen Apr 13, 2026
21f02c3
make builder positional consistently
selmanozleyen Apr 13, 2026
744c757
make more abstractions
selmanozleyen Apr 13, 2026
dbc7f0d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 13, 2026
d7e5e5f
graphmatrixT exposure
selmanozleyen Apr 13, 2026
13768e2
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 13, 2026
ea3f3ca
Merge branch 'main' into feat/spatial_neighbours
selmanozleyen Apr 20, 2026
21f248e
add radius: float | int | tuple t
selmanozleyen May 12, 2026
3bbc535
4 or 6
selmanozleyen May 12, 2026
a0426e6
Merge branch 'main' into feat/spatial_neighbours
selmanozleyen May 12, 2026
f3eab97
Merge branch 'main' into feat/spatial_neighbours
selmanozleyen May 15, 2026
8436656
Merge branch 'main' into feat/spatial_neighbours
timtreis May 19, 2026
07d59bf
Merge branch 'main' into feat/spatial_neighbours
selmanozleyen May 19, 2026
3e9fc41
Merge branch 'main' into feat/spatial_neighbours
selmanozleyen May 21, 2026
77627dc
mark snn as ilustrative
selmanozleyen May 21, 2026
0afbe3c
add uns params
selmanozleyen May 21, 2026
1711a62
deprecation warnings alignment
selmanozleyen May 21, 2026
4632b74
set diag isnt defaulted to none
selmanozleyen May 21, 2026
f4805c1
fix
selmanozleyen May 21, 2026
f2b0fa0
radius is also positional
selmanozleyen May 21, 2026
0ed1604
n_neighs on grid mode
selmanozleyen May 21, 2026
c85ba43
make radius kw only
selmanozleyen May 26, 2026
d9264a8
put a working example
selmanozleyen May 27, 2026
9c89dc2
Merge branch 'main' into feat/spatial_neighbours
selmanozleyen May 27, 2026
52b4e79
fix api.md
selmanozleyen May 27, 2026
60e888f
Merge branch 'main' into feat/spatial_neighbours
selmanozleyen May 28, 2026
bfbb3e8
be more compatible with main
selmanozleyen May 28, 2026
7e4ddec
Merge branch 'main' into feat/spatial_neighbours
selmanozleyen May 28, 2026
9dd330e
align more to main
selmanozleyen May 28, 2026
cf38fe3
Merge branch 'feat/spatial_neighbours'
selmanozleyen May 28, 2026
6c61ddc
save state
selmanozleyen Jun 1, 2026
e2266de
save state
selmanozleyen Jun 1, 2026
b2d25cb
refactor
selmanozleyen Jun 1, 2026
14d36b0
undo lock file
selmanozleyen Jun 1, 2026
86c9d76
Merge remote-tracking branch 'origin/main' into feat/experimental-fit…
selmanozleyen Jun 1, 2026
8e4bb93
undo changes with main
selmanozleyen Jun 1, 2026
9a489f2
resuse resolve_labels_array
selmanozleyen Jun 1, 2026
1955bed
Merge branch 'main' into feat/experimental-fit-core
selmanozleyen Jun 1, 2026
068f3e7
Merge branch 'main' into feat/experimental-fit-core
selmanozleyen Jun 1, 2026
759e09e
Update api.md
selmanozleyen Jun 1, 2026
ad200ea
Update api.md
selmanozleyen Jun 1, 2026
0e9b8c1
Merge branch 'main' into feat/experimental-fit-core
selmanozleyen Jun 8, 2026
c9eb7e4
rename file and refactor
selmanozleyen Jun 8, 2026
77f3e7d
move files
selmanozleyen Jun 8, 2026
57f9d21
fix imports
selmanozleyen Jun 8, 2026
5d69264
fixes
selmanozleyen Jun 8, 2026
6587efe
remove bloat code
selmanozleyen Jun 8, 2026
e45e247
typr hints
selmanozleyen Jun 8, 2026
beb1476
add tests
selmanozleyen Jun 8, 2026
5eeb95d
reduce bloat
selmanozleyen Jun 8, 2026
3c2ed02
reduce bloat
selmanozleyen Jun 8, 2026
1ea9996
remove useless file
selmanozleyen Jun 8, 2026
ee741ab
fix
selmanozleyen Jun 8, 2026
ba91e4f
undo rasterize changes
selmanozleyen Jun 8, 2026
1d65f4a
doc landmark
selmanozleyen Jun 8, 2026
a3da05a
remove bloat
selmanozleyen Jun 8, 2026
373ca02
docs
selmanozleyen Jun 8, 2026
aaf48c7
doc debloatr
selmanozleyen Jun 8, 2026
4387a61
expose result classes
selmanozleyen Jun 8, 2026
85df8fc
refactoring, testing, typing and bug fix on copy mode
selmanozleyen Jun 11, 2026
599186f
landmark is positional only now
selmanozleyen Jun 11, 2026
8cfc770
expose api
selmanozleyen Jun 11, 2026
96bc445
Merge branch 'main' into feat/experimental-fit-core
selmanozleyen Jun 11, 2026
30e14cf
Merge branch 'main' into feat/experimental-fit-core
selmanozleyen Jun 16, 2026
d617b45
Merge branch 'main' into feat/experimental-fit-core
selmanozleyen Jun 19, 2026
f0868c1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 19, 2026
e6b4075
lower bound jax
selmanozleyen Jun 19, 2026
bff9092
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 19, 2026
81a16f2
align expose
selmanozleyen Jun 19, 2026
f5ccd46
api refactor
selmanozleyen Jun 20, 2026
461f5ee
expose methods in a nice place
selmanozleyen Jun 20, 2026
f6b907e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 20, 2026
265ad0b
reduce bloat
selmanozleyen Jun 20, 2026
9740f5d
Merge branch 'main' into feat/experimental-fit-core
selmanozleyen Jun 20, 2026
035e6e9
format
selmanozleyen Jun 20, 2026
6e12e46
cleanup
selmanozleyen Jun 22, 2026
cbe72b5
file orga
selmanozleyen Jun 22, 2026
4e5909c
file orga
selmanozleyen Jun 22, 2026
3f9ab34
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 22, 2026
5646282
fix tests and imports
selmanozleyen Jun 22, 2026
f0415af
Merge branch 'feat/experimental-fit-core' of https://github.com/selma…
selmanozleyen Jun 22, 2026
4a6e6ff
fix merge error
selmanozleyen Jun 22, 2026
bb20bc0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 22, 2026
44a5a22
fix merge error
selmanozleyen Jun 22, 2026
62ec52f
Merge branch 'feat/experimental-fit-core' of https://github.com/selma…
selmanozleyen Jun 22, 2026
6ed6344
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 22, 2026
6a0b106
autodoc mock jax
selmanozleyen Jun 22, 2026
21cd780
remove casting
selmanozleyen Jun 22, 2026
9236ac3
strict=True
selmanozleyen Jun 22, 2026
5c663a2
add jax docs
selmanozleyen Jun 22, 2026
c07a707
speed up rasterize by avoiding loop
selmanozleyen Jun 22, 2026
f41aeb1
apply suggestion
selmanozleyen Jun 22, 2026
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
21 changes: 21 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,24 @@ See the {doc}`extensibility guide </extensibility>` for how to implement a custo
gr.neighbors.GridBuilder
```

The ``method=`` argument of {func}`~squidpy.experimental.tl.align` and
{func}`~squidpy.experimental.tl.align_by_landmarks` dispatches to a registered
fitting function. The method-specific arguments are documented on each function
below; the fitted maps are returned (with ``output_mode="object"``) as the
result types listed alongside.

```{eval-rst}
.. currentmodule:: squidpy
.. autosummary::
:toctree: api

experimental.methods.align_samples._stalign.fit_stalign
experimental.methods.align_landmarks._landmark.fit_similarity
experimental.methods.align_landmarks._landmark.fit_affine
experimental.methods.align_samples._stalign.StalignResult
experimental.methods.align_landmarks._landmark.AffineFitResult
```

## Experimental
```{eval-rst}
.. module:: squidpy.experimental
Expand All @@ -150,6 +168,9 @@ See the {doc}`extensibility guide </extensibility>` for how to implement a custo
experimental.im.calculate_image_features
experimental.tl.calculate_tiling_qc
experimental.tl.TilingQCParams
experimental.tl.align
experimental.tl.align_by_landmarks
experimental.tl.AlignResult
experimental.tl.assign_stitch_groups
experimental.tl.StitchParams
experimental.pl.tiling_qc
Expand Down
3 changes: 3 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
autodoc_member_order = "groupwise"
autodoc_typehints = "signature"
autodoc_docstring_signature = True
autodoc_mock_imports = ["jax"]
napoleon_google_docstring = False
napoleon_numpy_docstring = True
napoleon_include_init_with_doc = False
Expand Down Expand Up @@ -147,6 +148,8 @@
("py:class", "NDArray"),
("py:class", "np.number"),
("py:class", "csr_matrix"),
# optional dep mocked at build time (see autodoc_mock_imports), so no resolvable target
("py:class", "jax.Array"),
# no idea why those aren’t exported
("py:class", "squidpy._constants._constants.SpatialAutocorr"),
("py:class", "squidpy._constants._constants.CoordType"),
Expand Down
4 changes: 4 additions & 0 deletions hatch.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ extra-dependencies = ["diff-cover"]
matrix = [
{ deps = ["stable"], python = ["3.12", "3.13", "3.14"] },
{ deps = ["pre"], python = ["3.14"] },
{ deps = ["stable"], python = ["3.13"], extras = ["jax"] },
]
overrides.matrix.deps.env-vars = [
{ key = "UV_PRERELEASE", value = "allow", if = ["pre"] },
]
overrides.matrix.extras.features = [
{ value = "jax", if = ["jax"] },
]
# default commands (only `cov-report` is overridden)
scripts.run = "pytest{env:HATCH_TEST_ARGS:} -p no:cov {args}"
scripts.run-cov = "coverage run -m pytest{env:HATCH_TEST_ARGS:} -p no:cov {args}"
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ dependencies = [
"xarray>=2024.10",
"zarr>=3",
]
optional-dependencies.jax = [
"jax>=0.4",
]
optional-dependencies.leiden = [
"leidenalg",
"spatialleiden>=0.4",
Expand Down
32 changes: 32 additions & 0 deletions src/squidpy/experimental/methods/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""In-memory model-fitting core for experimental methods.

The :mod:`.registry` subpackage holds the registry machinery and the family
registries; each family subpackage (e.g. :mod:`.align_samples`,
:mod:`.align_landmarks`) holds the estimator implementations. Importing this
package imports those subpackages so the estimators register themselves into the
(public) family registries. Each subpackage stays cheap to import -- heavy or
optional dependencies (e.g. JAX) are pulled in lazily, only when an estimator
actually runs.
"""

from __future__ import annotations

# Import for side effects: populates ALIGN_SAMPLES / ALIGN_LANDMARKS.
from squidpy.experimental.methods import align_landmarks, align_samples # noqa: F401
from squidpy.experimental.methods.registry import (
ALIGN_LANDMARKS,
ALIGN_SAMPLES,
AlignLandmarksFn,
AlignResult,
AlignSamplesFn,
Registry,
)

__all__ = [
"Registry",
"AlignResult",
"AlignSamplesFn",
"AlignLandmarksFn",
"ALIGN_SAMPLES",
"ALIGN_LANDMARKS",
]
21 changes: 21 additions & 0 deletions src/squidpy/experimental/methods/align_landmarks/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""``align_landmarks`` family: closed-form alignment from paired landmarks.

Importing this package registers the family's estimators into
:data:`~squidpy.experimental.methods.registry.ALIGN_LANDMARKS`. Only the
implementations are re-exported here; the registry itself lives in (and is public
from) :mod:`squidpy.experimental.methods`.
"""

from __future__ import annotations

from squidpy.experimental.methods.align_landmarks._landmark import (
AffineFitResult,
fit_affine,
fit_similarity,
)

__all__ = [
"AffineFitResult",
"fit_affine",
"fit_similarity",
]
155 changes: 155 additions & 0 deletions src/squidpy/experimental/methods/align_landmarks/_landmark.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
"""Closed-form landmark alignment estimators."""

from __future__ import annotations

from collections.abc import Callable
from dataclasses import dataclass, field
from typing import Any

import numpy as np
import numpy.typing as npt

from squidpy._utils import NDArrayA
from squidpy.experimental.methods.registry import ALIGN_LANDMARKS


@dataclass
class AffineFitResult:
"""A fitted ``(3, 3)`` homogeneous affine mapping query onto ref, in ``(x, y)``."""

matrix: np.ndarray
source_cs: str | None = None
target_cs: str | None = None
metadata: dict[str, Any] = field(default_factory=dict)

def __post_init__(self) -> None:
if self.matrix.shape != (3, 3):
raise ValueError(f"Expected a (3, 3) homogeneous matrix, found shape {self.matrix.shape}.")

def transform(self, x: npt.ArrayLike) -> NDArrayA:
"""Apply the affine to an ``(N, 2)`` ``(x, y)`` coordinate array."""
coords = np.asarray(x, dtype=float)
if coords.ndim != 2 or coords.shape[1] != 2:
raise ValueError(f"Expected an (N, 2) coordinate array, found shape {coords.shape}.")
return coords @ self.matrix[:2, :2].T + self.matrix[:2, 2]


def _fit_landmark_relation(
ref: np.ndarray,
query: np.ndarray,
*,
method: str,
solve_fn: Callable[[np.ndarray, np.ndarray], np.ndarray],
source_cs: str | None = None,
target_cs: str | None = None,
) -> AffineFitResult:
ref = _validate_landmarks(ref, name="ref")
query = _validate_landmarks(query, name="query")
if ref.shape != query.shape:
raise ValueError(f"`ref` and `query` must have the same shape; got {ref.shape} and {query.shape}.")
if ref.shape[0] < 3:
raise ValueError(f"`{method}` needs at least 3 landmark pairs, got {ref.shape[0]}.")

matrix = solve_fn(ref, query)
return AffineFitResult(
matrix=matrix,
source_cs=source_cs,
target_cs=target_cs,
metadata={"method": method},
)


@ALIGN_LANDMARKS.register("similarity")
def fit_similarity(
ref: np.ndarray,
query: np.ndarray,
*,
source_cs: str | None = None,
target_cs: str | None = None,
) -> AffineFitResult:
"""4-DOF similarity fit (rotation + uniform scale + translation), via spatialdata.

Parameters
----------
ref, query
Pre-paired ``(N, 2)`` ``(x, y)`` landmark arrays (``N >= 3``).
source_cs, target_cs
Optional coordinate-system labels stamped onto the result for
traceability; they do not affect the fit.
"""
return _fit_landmark_relation(
ref,
query,
method="similarity",
solve_fn=_fit_similarity,
source_cs=source_cs,
target_cs=target_cs,
)


@ALIGN_LANDMARKS.register("affine")
def fit_affine(
ref: np.ndarray,
query: np.ndarray,
*,
source_cs: str | None = None,
target_cs: str | None = None,
) -> AffineFitResult:
"""6-DOF affine fit (rotation + non-uniform scale + shear + translation), via skimage.

Parameters
----------
ref, query
Pre-paired ``(N, 2)`` ``(x, y)`` landmark arrays (``N >= 3``).
source_cs, target_cs
Optional coordinate-system labels stamped onto the result for
traceability; they do not affect the fit.
"""
return _fit_landmark_relation(
ref,
query,
method="affine",
solve_fn=_fit_affine,
source_cs=source_cs,
target_cs=target_cs,
)


def _validate_landmarks(points: np.ndarray, *, name: str) -> np.ndarray:
arr = np.asarray(points, dtype=float)
if arr.ndim != 2 or arr.shape[1] != 2:
raise ValueError(f"`{name}` must be a sequence of (x, y) pairs, got shape {arr.shape}.")
if not np.all(np.isfinite(arr)):
raise ValueError(f"`{name}` must contain only finite values.")
return arr


def _fit_similarity(ref_xy: np.ndarray, query_xy: np.ndarray) -> np.ndarray:
"""4-DOF similarity fit, delegated to spatialdata."""
from spatialdata.models import PointsModel
from spatialdata.transformations import get_transformation_between_landmarks

refs_pts = PointsModel.parse(ref_xy)
moving_pts = PointsModel.parse(query_xy)
sd_transform = get_transformation_between_landmarks(refs_pts, moving_pts)
return _extract_affine_matrix(sd_transform)


def _fit_affine(ref_xy: np.ndarray, query_xy: np.ndarray) -> np.ndarray:
"""Full 6-DOF affine fit, delegated to skimage's least-squares estimator."""
from skimage.transform import estimate_transform

model_obj = estimate_transform("affine", src=query_xy, dst=ref_xy)
return np.asarray(model_obj.params)


def _extract_affine_matrix(sd_transform: object) -> np.ndarray:
"""Pull a ``(3, 3)`` homogeneous matrix out of a spatialdata transformation."""
from spatialdata.transformations import Affine as SDAffine
from spatialdata.transformations import Sequence as SDSequence

if isinstance(sd_transform, SDAffine):
return np.asarray(sd_transform.matrix)
if isinstance(sd_transform, SDSequence):
return np.asarray(sd_transform.to_affine_matrix(input_axes=("x", "y"), output_axes=("x", "y")))
raise TypeError(f"Unexpected transformation type from spatialdata: {type(sd_transform).__name__}.")
14 changes: 14 additions & 0 deletions src/squidpy/experimental/methods/align_samples/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""``align_samples`` family: align two samples' point clouds (STalign).

Importing this package registers the family's estimators into
:data:`~squidpy.experimental.methods.registry.ALIGN_SAMPLES`. It stays
cheap -- JAX is pulled in lazily, only when an estimator's ``fit`` runs. Only the
implementations are re-exported here; the registry itself lives in (and is public
from) :mod:`squidpy.experimental.methods`.
"""

from __future__ import annotations

from squidpy.experimental.methods.align_samples._stalign import StalignResult, fit_stalign

__all__ = ["fit_stalign", "StalignResult"]
Loading
Loading