Repository navigation
Diffusion maps with adaptive anisotropic affinity kernels - #144
Merged
Merged
Conversation
Wraps scanpy/rapids_singlecell (tuned via back) Add `neighbors`, a wrapper around scanpy's/ rapids_singlcell's (set via the `backend` arg) `pp.neighbors` that can build Palantir's adaptive anisotropic affinity kernel (Setty et al., 2019) instead of the canonical fixed-bandwidth one, without taking on `palantir` as a dependency. With `adaptive=False` (default) the call passes through to the backend's own `pp.neighbors`. With `adaptive=True`, `_adaptive_kernel` derives a per-observation bandwidth from that observation's `floor(knn / 3)`-th nearest neighbor, scales and exponentiates the kNN distances, then symmetrizes; Coifman-Lafon density normalization is applied on top when `alpha > 0`. The kernel is stored under its own `key_added` prefix in `obsp`/`uns`, so it coexists with a plain neighbors graph rather than overwriting it. Checked against `palantir.utils.compute_kernel` on 300 synthetic observations: identical sparsity pattern, maximum elementwise difference 3.3e-16.
Add `diffmap`, which builds the adaptive anisotropic kernel via `neighbors(adata, adaptive=True, ...)` and hands it to `sc.tl.diffmap` through `neighbors_key`. The kernel is Palantir's; the eigendecomposition, the density normalization of the diffusion operator and the output keys remain scanpy's. Results land in the standard `obsm["X_diffmap"]` and `uns["diffmap_evals"]`, so downstream `sc.tl.dpt` and `sc.pl.embedding(basis="diffmap")` keep working unchanged. `backend="rapids"` routes both the kNN search and the eigendecomposition through `rapids_singlecell`. The cross-subpackage import carries `# noqa: TID252`: a sibling subpackage is only reachable relatively, and the absolute form is not valid Python while the package name is an unrendered Jinja token.
Alias both subpackages at the package root, the way `scanpy/__init__.py` aliases its own `preprocessing` and `tools`, so callers write `pp.neighbors(...)` and `tl.diffmap(...)` against a familiar surface.
A module inside the package can reach a sibling subpackage only through a parent-relative import, which ruff's TID252 rejects, while the absolute form is not valid Python before the package name is rendered. The template therefore writes the relative import with an explicit `# noqa: TID252`, and generation now rewrites it to the absolute form and drops the suppression, leaving the generated project canonical and its own hooks passing unmodified. This is the treatment `unquote_pixi_key` already gives the quoted pixi self-dependency key. Generation now also fails if such an import cannot be rewritten, rather than silently shipping a stale suppression. `_check_import_calls.py` reports that at commit time for free, since it runs the real rewrite over a disposable copy instead of reimplementing it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes
New
pp.neighborsfrom scanpy/rapids_singlecell to facilitate adaptive anisotropic affinity kernelstl.diffmapfrom scanpy/rapids_singlecell for palantir-style diffusion mapsRelated issues
Closes #143.