Skip to content

Rework perturbation spaces around a perturbation-level API#1032

Merged
Zethson merged 2 commits into
mainfrom
feature/pert_spaces
Jul 6, 2026
Merged

Rework perturbation spaces around a perturbation-level API#1032
Zethson merged 2 commits into
mainfrom
feature/pert_spaces

Conversation

@Zethson

@Zethson Zethson commented Jul 6, 2026

Copy link
Copy Markdown
Member

Reworks pertpy's perturbation space module so that every space returns one observation per perturbation and the spaces compose with each other, and adds distance/embedding spaces plus combination and dose analyses.

  • MLPClassifierSpace averages its penultimate-layer activations per perturbation (was one embedding per cell).
  • Classifiers default to target_col="perturbation" and emit the label under target_col with perturbation-named obs_names, so classifier → distance/cluster/neighbors chains work.
  • Reproducible random_state accepting int | Generator | RandomState | None (new RandomStateLike in pertpy/_types.py).
  • Sparse-aware JAXDataset (per-batch densification), shared obs-carry helpers, and typing cleanup (str | None, dropped # type: ignores).
  • DistanceSpace — wraps Distance.pairwise into a perturbation space (matrix in .X and .obsp["distances"]), feeding clustering/neighbors directly.
  • PerturbationSpace.nearest_perturbations — rank perturbations by proximity (mechanism-of-action lookup).
  • PerturbationSpace.plot_similarity — clustered heatmap of perturbation distances.
  • EmbeddingSpace — ingest an external per-perturbation embedding (e.g. scGPT/Geneformer gene embeddings).
  • evaluate_combinations — score an additive model (effect(A)+effect(B)) against the measured combination effect.
  • dose_response — effect size of each perturbation versus dose.
  • DBSCANSpaceHDBSCANSpace (sklearn HDBSCAN).

Breaking changes (clean break, no shims)

  • Classifier target_col default "perturbations""perturbation"; output column follows target_col instead of the hardcoded "perturbations".
  • MLPClassifierSpace returns perturbation-level (not cell-level) embeddings.
  • DBSCANSpace removed in favor of HDBSCANSpace.

@github-actions github-actions Bot added chore enhancement New feature or request labels Jul 6, 2026
@codecov-commenter

codecov-commenter commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.24339% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.99%. Comparing base (31b2fe9) to head (28caf3e).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...y/tools/_perturbation_space/_perturbation_space.py 83.33% 15 Missing ⚠️
.../_perturbation_space/_discriminator_classifiers.py 85.41% 7 Missing ⚠️
pertpy/tools/_perturbation_space/_simple.py 91.83% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1032      +/-   ##
==========================================
- Coverage   78.00%   77.99%   -0.02%     
==========================================
  Files          50       50              
  Lines        6557     6694     +137     
==========================================
+ Hits         5115     5221     +106     
- Misses       1442     1473      +31     
Files with missing lines Coverage Δ
pertpy/_types.py 100.00% <100.00%> (ø)
pertpy/tools/__init__.py 78.37% <ø> (ø)
pertpy/tools/_perturbation_space/_simple.py 93.38% <91.83%> (+1.72%) ⬆️
.../_perturbation_space/_discriminator_classifiers.py 80.65% <85.41%> (-1.32%) ⬇️
...y/tools/_perturbation_space/_perturbation_space.py 87.67% <83.33%> (-3.17%) ⬇️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Every perturbation space now returns one observation per perturbation and
composes with the others, and the shared base class gains operations that act
directly on a perturbation space.

Phase 1 (consolidation):
- MLPClassifierSpace averages its penultimate-layer activations per perturbation
  instead of returning one embedding per cell.
- Classifiers default to target_col="perturbation" and emit the label under
  target_col with perturbation-named obs_names, so spaces chain cleanly.
- Reproducible random_state (int / Generator / RandomState / None via the new
  RandomStateLike type), sparse-aware JAXDataset, shared obs-carry helpers, and
  typing cleanup.

Phase 2 (distances + neighbors):
- DistanceSpace wraps Distance.pairwise into a perturbation space
  (matrix in .X and .obsp["distances"]).
- PerturbationSpace.nearest_perturbations and plot_similarity.

Phase 3 (new capabilities):
- EmbeddingSpace ingests external per-perturbation embeddings.
- evaluate_combinations scores an additive model against measured combinations.
- dose_response quantifies effect size versus dose.

Also upgrades DBSCANSpace to HDBSCANSpace and updates the tutorial (submodule).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Zethson
Zethson force-pushed the feature/pert_spaces branch 2 times, most recently from ce99aaf to 2adba76 Compare July 6, 2026 12:39
PerturbationSpace.plot_similarity references seaborn, but seaborn was not in the
intersphinx mapping, so the nitpicky RTD build failed. Add seaborn to
intersphinx and reference seaborn.clustermap (which has an inventory target) for
both the kwargs and the returned grid.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Zethson
Zethson force-pushed the feature/pert_spaces branch from 2adba76 to 28caf3e Compare July 6, 2026 12:40
@Zethson
Zethson merged commit a8a9810 into main Jul 6, 2026
19 checks passed
@Zethson
Zethson deleted the feature/pert_spaces branch July 6, 2026 13:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants