From 0c5cde344904b2dd78e775fbffcf93cfff9d1b3d Mon Sep 17 00:00:00 2001 From: Lukas Heumos Date: Mon, 25 May 2026 11:44:00 +0200 Subject: [PATCH 1/3] docs: refresh DE docstring pseudobulk examples (#615) The example code in EdgeR/PyDESeq2 docstrings still called PseudobulkSpace.compute() with the long-removed `min_cells` and `min_counts` parameters, so anyone copy-pasting the example hit a TypeError. Replace each example with the current PseudobulkSpace.compute(target_col=..., groups_col=..., layer_key=..., mode=...) call that actually runs. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../_differential_gene_expression/_base.py | 50 ++----------------- 1 file changed, 5 insertions(+), 45 deletions(-) diff --git a/pertpy/tools/_differential_gene_expression/_base.py b/pertpy/tools/_differential_gene_expression/_base.py index 61747968..003c6c39 100644 --- a/pertpy/tools/_differential_gene_expression/_base.py +++ b/pertpy/tools/_differential_gene_expression/_base.py @@ -83,15 +83,7 @@ def compare_groups( >>> adata = pt.dt.zhang_2021() >>> adata.layers["counts"] = adata.X.copy() >>> ps = pt.tl.PseudobulkSpace() - >>> pdata = ps.compute( - ... adata, - ... target_col="Patient", - ... groups_col="Cluster", - ... layer_key="counts", - ... mode="sum", - ... min_cells=10, - ... min_counts=1000, - ... ) + >>> pdata = ps.compute(adata, target_col="Patient", groups_col="Cluster", layer_key="counts", mode="sum") >>> edgr = pt.tl.EdgeR(pdata, design="~Efficacy+Treatment") >>> res_df = edgr.compare_groups(pdata, column="Efficacy", baseline="SD", groups_to_compare=["PR", "PD"]) """ @@ -163,15 +155,7 @@ def plot_volcano( # pragma: no cover # noqa: D417 >>> adata = pt.dt.zhang_2021() >>> adata.layers["counts"] = adata.X.copy() >>> ps = pt.tl.PseudobulkSpace() - >>> pdata = ps.compute( - ... adata, - ... target_col="Patient", - ... groups_col="Cluster", - ... layer_key="counts", - ... mode="sum", - ... min_cells=10, - ... min_counts=1000, - ... ) + >>> pdata = ps.compute(adata, target_col="Patient", groups_col="Cluster", layer_key="counts", mode="sum") >>> edgr = pt.tl.EdgeR(pdata, design="~Efficacy+Treatment") >>> edgr.fit() >>> res_df = edgr.test_contrasts( @@ -538,15 +522,7 @@ def plot_paired( # pragma: no cover # noqa: D417 >>> adata = pt.dt.zhang_2021() >>> adata.layers["counts"] = adata.X.copy() >>> ps = pt.tl.PseudobulkSpace() - >>> pdata = ps.compute( - ... adata, - ... target_col="Patient", - ... groups_col="Cluster", - ... layer_key="counts", - ... mode="sum", - ... min_cells=10, - ... min_counts=1000, - ... ) + >>> pdata = ps.compute(adata, target_col="Patient", groups_col="Cluster", layer_key="counts", mode="sum") >>> edgr = pt.tl.EdgeR(pdata, design="~Efficacy+Treatment") >>> edgr.fit() >>> res_df = edgr.test_contrasts( @@ -704,15 +680,7 @@ def plot_fold_change( # pragma: no cover # noqa: D417 >>> adata = pt.dt.zhang_2021() >>> adata.layers["counts"] = adata.X.copy() >>> ps = pt.tl.PseudobulkSpace() - >>> pdata = ps.compute( - ... adata, - ... target_col="Patient", - ... groups_col="Cluster", - ... layer_key="counts", - ... mode="sum", - ... min_cells=10, - ... min_counts=1000, - ... ) + >>> pdata = ps.compute(adata, target_col="Patient", groups_col="Cluster", layer_key="counts", mode="sum") >>> edgr = pt.tl.EdgeR(pdata, design="~Efficacy+Treatment") >>> edgr.fit() >>> res_df = edgr.test_contrasts( @@ -791,15 +759,7 @@ def plot_multicomparison_fc( # pragma: no cover # noqa: D417 >>> adata = pt.dt.zhang_2021() >>> adata.layers["counts"] = adata.X.copy() >>> ps = pt.tl.PseudobulkSpace() - >>> pdata = ps.compute( - ... adata, - ... target_col="Patient", - ... groups_col="Cluster", - ... layer_key="counts", - ... mode="sum", - ... min_cells=10, - ... min_counts=1000, - ... ) + >>> pdata = ps.compute(adata, target_col="Patient", groups_col="Cluster", layer_key="counts", mode="sum") >>> edgr = pt.tl.EdgeR(pdata, design="~Efficacy+Treatment") >>> res_df = edgr.compare_groups(pdata, column="Efficacy", baseline="SD", groups_to_compare=["PR", "PD"]) >>> edgr.plot_multicomparison_fc(res_df) From a169535e18f09ca9370921f52e9486bf161bee66 Mon Sep 17 00:00:00 2001 From: Lukas Heumos Date: Mon, 25 May 2026 12:08:55 +0200 Subject: [PATCH 2/3] docs: add decoupler to intersphinx_mapping Lets MyST/sphinx cross-references like {func}`~decoupler.op.collectri` in the DE tutorial resolve to decoupler's docs instead of dropping to plain text. decoupler publishes its objects.inv at decoupler.readthedocs.io (not decoupler-py.readthedocs.io, which has an empty inventory). Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/conf.py b/docs/conf.py index 23c2b713..eba90be8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -111,6 +111,7 @@ autodoc_mock_imports = ["ete4"] intersphinx_mapping = { "anndata": ("https://anndata.readthedocs.io/en/stable/", None), + "decoupler": ("https://decoupler.readthedocs.io/en/latest/", None), "mudata": ("https://mudata.readthedocs.io/stable/", None), "matplotlib": ("https://matplotlib.org/stable/", None), "numpy": ("https://numpy.org/doc/stable/", None), From 3df994646887370bcc466b8379cb7a6652203c00 Mon Sep 17 00:00:00 2001 From: Lukas Heumos Date: Mon, 25 May 2026 12:18:43 +0200 Subject: [PATCH 3/3] docs: bump tutorials submodule to pick up DE narrative + intersphinx sweep Points docs/tutorials/notebooks at scverse/pertpy-tutorials@7ae61d5 (merge commit of scverse/pertpy-tutorials#60), which contains the companion DE narrative additions and the intersphinx sweep that consumes the new decoupler entry added to docs/conf.py in this PR. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/tutorials/notebooks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/notebooks b/docs/tutorials/notebooks index 83cb3eef..7ae61d53 160000 --- a/docs/tutorials/notebooks +++ b/docs/tutorials/notebooks @@ -1 +1 @@ -Subproject commit 83cb3eef2ab399bf2448dec5c72f6ad442b02abb +Subproject commit 7ae61d535361c00e845c39217d513c049f340241