scatrans 0.9.9.dev1__tar.gz → 0.9.10.dev0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/.gitignore +1 -0
  2. scatrans-0.9.10.dev0/.readthedocs.yaml +20 -0
  3. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/CHANGELOG.md +70 -63
  4. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/CITATION.cff +2 -2
  5. scatrans-0.9.10.dev0/PKG-INFO +128 -0
  6. scatrans-0.9.10.dev0/README.md +75 -0
  7. scatrans-0.9.10.dev0/SECURITY.md +34 -0
  8. scatrans-0.9.10.dev0/docs/_static/css/custom.css +8 -0
  9. scatrans-0.9.10.dev0/docs/api/index.md +176 -0
  10. scatrans-0.9.10.dev0/docs/changelog.md +2 -0
  11. scatrans-0.9.10.dev0/docs/conf.py +132 -0
  12. scatrans-0.9.10.dev0/docs/faq.md +96 -0
  13. scatrans-0.9.10.dev0/docs/index.md +129 -0
  14. scatrans-0.9.10.dev0/docs/installation.md +49 -0
  15. scatrans-0.9.10.dev0/docs/license.md +17 -0
  16. scatrans-0.9.10.dev0/docs/quickstart.md +151 -0
  17. scatrans-0.9.10.dev0/docs/references.md +51 -0
  18. scatrans-0.9.10.dev0/docs/requirements.txt +5 -0
  19. scatrans-0.9.10.dev0/docs/statistical_guidance.md +147 -0
  20. scatrans-0.9.10.dev0/docs/tutorials/index.md +37 -0
  21. scatrans-0.9.10.dev0/docs/tutorials/t_ec_active_transcription.ipynb +2142 -0
  22. scatrans-0.9.10.dev0/docs/tutorials/t_ec_standalone_de_enrichment.ipynb +2584 -0
  23. scatrans-0.9.10.dev0/docs/tutorials/t_ga_active_transcription.ipynb +1039 -0
  24. scatrans-0.9.10.dev0/docs/user_guide/advanced.md +200 -0
  25. scatrans-0.9.10.dev0/docs/user_guide/enrichment.md +287 -0
  26. scatrans-0.9.10.dev0/docs/user_guide/gene_features.md +72 -0
  27. scatrans-0.9.10.dev0/docs/user_guide/index.md +22 -0
  28. scatrans-0.9.10.dev0/docs/user_guide/plotting.md +106 -0
  29. scatrans-0.9.10.dev0/docs/user_guide/standalone_de.md +96 -0
  30. scatrans-0.9.10.dev0/docs/user_guide/workflow.md +177 -0
  31. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/pyproject.toml +3 -1
  32. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/scatrans.egg-info/SOURCES.txt +25 -0
  33. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/setup.cfg +5 -5
  34. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/_version.py +24 -24
  35. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/enrich.py +45 -3
  36. scatrans-0.9.9.dev1/PKG-INFO +0 -1330
  37. scatrans-0.9.9.dev1/README.md +0 -1279
  38. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/.github/workflows/ci.yml +0 -0
  39. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/.github/workflows/publish.yml +0 -0
  40. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/.pre-commit-config.yaml +0 -0
  41. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/LICENSE +0 -0
  42. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/MANIFEST.in +0 -0
  43. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/conftest.py +0 -0
  44. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/conftest_fixtures.py +0 -0
  45. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/examples/memento_de_example.py +0 -0
  46. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/examples/real_data_template.py +0 -0
  47. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/examples/synthetic_active_transcription.py +0 -0
  48. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/__init__.py +0 -0
  49. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/_de.py +0 -0
  50. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/_permutation.py +0 -0
  51. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/_utils.py +0 -0
  52. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/_velocity.py +0 -0
  53. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/data/DATA_LICENSES.md +0 -0
  54. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/data/Hs_GO_Biological_Process_2026.txt +0 -0
  55. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/data/Hs_KEGG_2026.txt +0 -0
  56. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/data/Mm_GO_Biological_Process_2026.txt +0 -0
  57. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/data/Mm_KEGG_2026.txt +0 -0
  58. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/data/Mus_musculus.GRCm39.115_gene_features.parquet +0 -0
  59. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/data/README.md +0 -0
  60. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/data/human_GRCh38_2024A_gene_features.parquet +0 -0
  61. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/data/mouse_2020A_gene_features.parquet +0 -0
  62. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/generate_gene_features.py +0 -0
  63. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/pl.py +0 -0
  64. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/pp_bias.py +0 -0
  65. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/qc.py +0 -0
  66. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/src/scatrans/tl.py +0 -0
  67. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/tests/__init__.py +0 -0
  68. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/tests/conftest.py +0 -0
  69. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/tests/test_basic.py +0 -0
  70. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/tests/test_de_backends.py +0 -0
  71. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/tests/test_de_edge_cases.py +0 -0
  72. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/tests/test_enrich_api.py +0 -0
  73. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/tests/test_enrich_go.py +0 -0
  74. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/tests/test_pl_coverage.py +0 -0
  75. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/tests/test_pl_extended.py +0 -0
  76. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/tests/test_pp_bias_cli.py +0 -0
  77. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/tests/test_public_api.py +0 -0
  78. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/tests/test_regression_bugs.py +0 -0
  79. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/tests/test_small_sample_edges.py +0 -0
  80. {scatrans-0.9.9.dev1 → scatrans-0.9.10.dev0}/tests/test_tl_coverage.py +0 -0
@@ -69,6 +69,7 @@ instance/
69
69
 
70
70
  # Sphinx documentation
71
71
  docs/_build/
72
+ docs/api/generated/
72
73
 
73
74
  # PyBuilder
74
75
  .pybuilder/
@@ -0,0 +1,20 @@
1
+ # .readthedocs.yaml
2
+ # Read the Docs configuration file
3
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4
+
5
+ version: 2
6
+
7
+ build:
8
+ os: ubuntu-22.04
9
+ tools:
10
+ python: "3.11"
11
+
12
+ sphinx:
13
+ configuration: docs/conf.py
14
+ fail_on_warning: false
15
+
16
+ python:
17
+ install:
18
+ - requirements: docs/requirements.txt
19
+ - method: pip
20
+ path: .
@@ -2,10 +2,29 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
7
6
 
8
- ## [0.9.9] - 2026-07-04
7
+ ## 2026-07-05
8
+
9
+ ### Fixed
10
+ - **`run_gsea` made downstream `DataFrame` operations pathologically slow**: the
11
+ per-term running-enrichment-score curves stored in `res_df.attrs["gsea_details"]`
12
+ (tens of millions of floats for a genome-wide ranked list against thousands of
13
+ gene sets) were deep-copied by pandas' `NDFrame.__finalize__` on essentially
14
+ every subsequent `DataFrame` operation (`.head()`, `.copy()`, slicing, column
15
+ assignment), including inside `scat.pl.enrich_dotplot` and `scat.pl.gseaplot`.
16
+ This made those two plotting functions appear to hang indefinitely (in practice:
17
+ several minutes) on real GSEA results, and made even a plain `gsea_res.head()`
18
+ slow. `gsea_details` and `ranking` are now wrapped in a small dict subclass
19
+ whose `__deepcopy__` is an O(1) identity return (safe: these payloads are
20
+ write-once/read-only after `run_gsea` returns). `enrich_dotplot`/`gseaplot`
21
+ on a real ~3700-term result went from indefinite/minutes to <0.1s / ~6s.
22
+ - **`run_gsea` returned several numeric columns (`ES`, `NES`, `pvalue`, `p.adjust`,
23
+ `FWER_pval`, `Tag_percent`, `Gene_percent`) as `object` dtype** instead of
24
+ `float`, inherited as-is from `gseapy`'s `res2d`. Now coerced explicitly via
25
+ `pd.to_numeric`. Contributed to (but was not the root cause of) the hang above.
26
+
27
+ ## 2026-07-04
9
28
 
10
29
  ### Added
11
30
  - **`scat.pl.volcano_plot(style=...)`**: ggVolcano-inspired styles from
@@ -29,10 +48,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
29
48
  - **MixedLM**: NaN neutral-fill on degenerate fits; composite ``condition::sample``
30
49
  random-effect groups when replicate labels are reused across conditions (``paired_replicates=True``
31
50
  for paired designs).
32
-
33
- ## [0.9.8 bugfix 2026-07-04]
34
-
35
- ### Fixed
36
51
  - **CI pytest failure on matrix legs without `pydeseq2`**: two new pseudobulk regression tests
37
52
  (`test_strict_pydeseq2_counts_rejects_log_normalized_*`) now use the same
38
53
  `@pytest.mark.skipif(importlib.util.find_spec("pydeseq2") is None, ...)` guard as
@@ -60,20 +75,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
60
75
  - README: noted that `anndata.concat()` drops `uns['log1p']` and recommends re-setting the marker
61
76
  or passing `de_preprocess="none"` explicitly after combining pre-normalized samples.
62
77
 
63
- ## [0.9.8] - 2026-07-03
78
+ ## 2026-07-03
64
79
 
65
80
  ### Changed (user-visible default behavior)
66
81
  - **`active_score()` built-in `significant` list** now uses the same default thresholds as
67
82
  `filter_active_genes(preset="heuristic")`: `logFC > 0.35`, `unspliced_excess_residual > 1.0`,
68
83
  `active_score >= 55`, `active_score_fdr < 0.25`, plus `p_adj` / `unspliced_excess_fdr` cutoffs.
69
- Re-running analyses with defaults may return a **different** significant gene set than 0.9.2
70
- (typically more genes when signal is present; aligns with the documented post-hoc workflow).
84
+ Re-running analyses with defaults may return a **different** significant gene set than the
85
+ 2026-06-20 release (typically more genes when signal is present; aligns with the documented
86
+ post-hoc workflow).
71
87
  - **`active_score(logfc_cutoff=...)` default** lowered from `0.5` to `0.35` to match the heuristic
72
88
  preset (only affects the built-in significant mask and metadata; ranking in `all_results` unchanged).
73
89
  - **`gamma_method="empirical_bayes"` + `prior_weight`**: fixed a numeric floor so `prior_weight` in
74
90
  the usual tuning range (0.5–5.0, including the default 5.0) now changes `count_pseudocount` and
75
- shrinkage weights instead of being pinned at 1.0. EB gamma values may differ from 0.9.2 at the
76
- same `prior_weight`.
91
+ shrinkage weights instead of being pinned at 1.0. EB gamma values may differ from the 2026-06-20
92
+ release at the same `prior_weight`.
77
93
 
78
94
  ### Fixed
79
95
  - **`scat.pl.gseaplot`**: RES curve / hit ticks and the bottom ranked-metric bar now share the same
@@ -104,7 +120,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
104
120
  ### Documentation
105
121
  - README built-in `significant` section updated to match `HEURISTIC_FILTER_DEFAULTS`.
106
122
 
107
- ## [0.9.2 bugfix 2026-07-02]
123
+ ## 2026-07-02
108
124
 
109
125
  ### Fixed
110
126
  - **compare_enrichment / concat_compare_results metadata**: `attrs["clusters"]` now lists only clusters that contributed rows to the combined table (skipped, failed, and empty per-cluster runs remain in `per_cluster` diagnostics only). Fixes ghost cluster names in both the main compare API and the concat wrapper.
@@ -122,7 +138,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
122
138
  ### Added
123
139
  - Regression test `test_filter_active_genes_permissive_keeps_padj_one`.
124
140
 
125
- ## [Unreleased / Review 2026-06-27]
141
+ ## 2026-06-27
142
+
126
143
  ### Added / Improved
127
144
  - Clarified and documented the `gamma_method="empirical_bayes"` implementation as **hierarchical (分层) gamma estimation** for the reference U/S ratio (README keeps the CN term; source now English-only).
128
145
  - Stronger emphasis on "always pass explicit target_group/reference_group".
@@ -142,7 +159,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
142
159
  - Reduced anndata category storage log noise during internal DE/perm (narrow logger level bump).
143
160
  - All tests + targeted EB/perm/explicit-norm cases pass after fixes.
144
161
 
145
- ### Additional fixes (2026-06-27 round 2)
162
+ ### Additional fixes (round 2)
146
163
  - **Scientific Error 3**: `generate_gene_features_from_gtf()` now computes **true exon union length per gene** (merge overlapping intervals) instead of naively summing all exons across all transcripts. Prevents ~N_transcript-fold overestimation of gene_length for multi-isoform genes (affects only users who generate their own tables; bundled .parquet files are unaffected).
147
164
  - **Scientific Error 4**: `logFC` is now normalized toward consistent **log2 scale** across backends inside `_run_de_wrapper`:
148
165
  - wilcoxon, mixedlm, memento: divided by ln(2)
@@ -155,7 +172,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
155
172
  - **Design 8**: Made the "max > 50" heuristic in `_prepare_log_normalized_expression` (mixed model prep) more robust: checks for negatives, uses lower threshold (20), better warning message.
156
173
  - **Design 9**: `valid_expr` is now **explicitly passed** from `tl.py` into `run_permutation_test` (no more hidden reliance on adata.var after the fact).
157
174
 
158
- ### Post-review hardening (2026-06-27)
175
+ ### Post-review hardening
159
176
  - **Fragility fix (high)**: Added explicit schema validation + safe column access + clear warning in `_run_memento_de` for expected 'de_coef'/'de_pval' from memento.binary_test_1d. Prevents silent fallback (or crash) if upstream memento-de changes column names/structure. Updated optional dep pin to "memento-de>=0.1.0,<0.3.0".
160
177
  - **Cleanup + consistency (high)**: `run_permutation_test` now owns the small-space FDR decision (use_fdr=False + disabled_reason="small_permutation_space" when n_perm < 100). Removed vestigial dead `if not perm_use_fdr` and useless max_perm check/assign in tl.py. `disabled_reason` (and `perm_disabled_reason`) now properly returned and stored in adata.uns["scatrans"] metadata.
161
178
  - **Diagnostics improvement**: MixedLM per-gene fits now count genes hitting the neutral-except fallback (`n_genes_failed_fit`). Recorded in diagnostics["mixed_model"] (active_score) and DE metadata (differential_expression). Warning emitted when >0 so users are not unaware of silent neutral (delta_var=0, p=1) genes.
@@ -163,7 +180,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
163
180
 
164
181
  All new issues addressed. Full test suite green.
165
182
 
166
- ## [0.9.2] - 2026-06-20
183
+ ## 2026-06-20
167
184
 
168
185
  ### Added / Changed
169
186
  - `filter_active_genes` now accepts `logfc_direction="up"|"down"|"both"` (default remains `"up"` for backward compatibility and "active" semantics).
@@ -174,7 +191,7 @@ All new issues addressed. Full test suite green.
174
191
  - This directly supports the common request for downregulated candidates in standalone DE workflows.
175
192
  - Updated docstrings, tests, and examples.
176
193
 
177
- ## [0.9.0] - 2026-06-19
194
+ ## 2026-06-19
178
195
 
179
196
  ### Added
180
197
  - `run_gsea(ranked_genes, gene_sets=..., nperm=..., ...)` — pre-ranked GSEA (via gseapy.prerank wrapper).
@@ -190,32 +207,7 @@ All new issues addressed. Full test suite green.
190
207
  - Minor internal cleanups and test coverage for the new GSEA path.
191
208
  - All new functions follow the existing consistent signatures (`ax=`, `use_style=`, `save_path=`, etc.).
192
209
 
193
- ## [0.8.0] - 2026-06-14
194
-
195
- ### Added (enrichment module — major paper-readiness upgrade)
196
- - `run_go(ontology="BP"|"CC"|"MF"|"ALL", ...)` — direct wrapper analogous to clusterProfiler `enrichGO`. Supports `adjust_across_all=True` for a single BH correction across all GO terms when using "ALL".
197
- - `save_enrichment_report(res, prefix=..., save_excel=True, save_csv=True, save_tsv=True, save_metadata=True, save_term_gene_table=True)` — one-call export of main table, term-gene long table (via `expand_enrichment_genes`), and rich `metadata.json` + xlsx sheet. Auto-creates parent directories. List columns (e.g. `Genes_list`) are sanitized to `;` strings for clean export.
198
- - `expand_enrichment_genes(res)` — expands the `Genes` (semicolon) column into a long-format Term–Gene table (one row per gene). Preserves `Ontology` column when input came from `run_go(..., "ALL")`.
199
- - Rich provenance in every result `.attrs` (success and empty):
200
- - `analysis_info`: package, version, timestamp, module
201
- - `gene_set_info`: `requested`/`resolved`, `requested_source` vs `actual_source` ("bundled", "gseapy", "gmt", "dict"), `library_name`, `n_terms`, `n_unique_genes`
202
- - `universe_info`: full details of background handling (provided size, restricted, dropped_by_annotation, force_universe, mapping counts)
203
- - Empty results now carry `reason` ("gene_list_empty", "universe_empty", "no_term_overlap_after_filters", ...) + the above fields so users can diagnose why nothing came back.
204
- - New `run_enrichment` / `run_kegg` / `run_go` parameters: `padj_cutoff` (preferred modern name), `include_gene_list` (adds `Genes_list` python-list column), `adjust_across_all`.
205
- - `list_bundled_gene_sets()` now clearly documents the 2026 organism-specific defaults.
206
- - Improved low-mapping-rate warning (includes input examples + gene-set examples).
207
- - `background` is now a documented deprecated alias of `universe`; passing both raises immediately.
208
- - All empty-result DataFrames preserve consistent columns (including optional `Genes_list` when requested) and full diagnostic attrs.
209
-
210
- ### Changed / Improved
211
- - `_load_gene_sets` now returns `(term_to_genes, term_to_desc, load_info)` so `actual_source` is always recorded accurately (even on gseapy fallback after bundled attempt).
212
- - `run_kegg` fully synchronized with new parameters (`padj_cutoff`, `include_gene_list`, etc.).
213
- - `enrich_dotplot` (pl.py) and various tl.py flows updated for new columns/attrs.
214
- - Version unified to 0.8.0 for this release.
215
- - README and docstrings extensively updated with manuscript-export examples, `run_go`, provenance details, and `adjust_across_all` guidance.
216
- - Full test coverage for new paths (per-ontology attrs, within_ontology p.adjust, save+tsv+dir creation, expand with Ontology, dual-cutoff warning, etc.). All tests pass.
217
-
218
- ## [0.9.0] - 2026-06-18
210
+ ## 2026-06-18
219
211
 
220
212
  ### Added
221
213
  - **Independent permutation statistics for unspliced excess**: `unspliced_excess_pval` and `unspliced_excess_fdr` (one-sided test on bias-corrected `unspliced_excess_residual`). Computed alongside existing `active_score_pval` / `active_score_fdr` when `use_permutation=True`.
@@ -239,33 +231,52 @@ All new issues addressed. Full test suite green.
239
231
  - `active_fdr_cutoff` (no longer used for built-in significance; use `unspliced_excess_fdr_cutoff`).
240
232
  - `velocity_residual_cutoff` in `filter_active_genes` (use `unspliced_excess_residual_cutoff`).
241
233
 
242
- ## [Unreleased]
234
+ ## 2026-06-14
235
+
236
+ ### Added (enrichment module — major paper-readiness upgrade)
237
+ - `run_go(ontology="BP"|"CC"|"MF"|"ALL", ...)` — direct wrapper analogous to clusterProfiler `enrichGO`. Supports `adjust_across_all=True` for a single BH correction across all GO terms when using "ALL".
238
+ - `save_enrichment_report(res, prefix=..., save_excel=True, save_csv=True, save_tsv=True, save_metadata=True, save_term_gene_table=True)` — one-call export of main table, term-gene long table (via `expand_enrichment_genes`), and rich `metadata.json` + xlsx sheet. Auto-creates parent directories. List columns (e.g. `Genes_list`) are sanitized to `;` strings for clean export.
239
+ - `expand_enrichment_genes(res)` — expands the `Genes` (semicolon) column into a long-format Term–Gene table (one row per gene). Preserves `Ontology` column when input came from `run_go(..., "ALL")`.
240
+ - Rich provenance in every result `.attrs` (success and empty):
241
+ - `analysis_info`: package, version, timestamp, module
242
+ - `gene_set_info`: `requested`/`resolved`, `requested_source` vs `actual_source` ("bundled", "gseapy", "gmt", "dict"), `library_name`, `n_terms`, `n_unique_genes`
243
+ - `universe_info`: full details of background handling (provided size, restricted, dropped_by_annotation, force_universe, mapping counts)
244
+ - Empty results now carry `reason` ("gene_list_empty", "universe_empty", "no_term_overlap_after_filters", ...) + the above fields so users can diagnose why nothing came back.
245
+ - New `run_enrichment` / `run_kegg` / `run_go` parameters: `padj_cutoff` (preferred modern name), `include_gene_list` (adds `Genes_list` python-list column), `adjust_across_all`.
246
+ - `list_bundled_gene_sets()` now clearly documents the 2026 organism-specific defaults.
247
+ - Improved low-mapping-rate warning (includes input examples + gene-set examples).
248
+ - `background` is now a documented deprecated alias of `universe`; passing both raises immediately.
249
+ - All empty-result DataFrames preserve consistent columns (including optional `Genes_list` when requested) and full diagnostic attrs.
250
+
251
+ ### Changed / Improved
252
+ - `_load_gene_sets` now returns `(term_to_genes, term_to_desc, load_info)` so `actual_source` is always recorded accurately (even on gseapy fallback after bundled attempt).
253
+ - `run_kegg` fully synchronized with new parameters (`padj_cutoff`, `include_gene_list`, etc.).
254
+ - `enrich_dotplot` (pl.py) and various tl.py flows updated for new columns/attrs.
255
+ - README and docstrings extensively updated with manuscript-export examples, `run_go`, provenance details, and `adjust_across_all` guidance.
256
+ - Full test coverage for new paths (per-ontology attrs, within_ontology p.adjust, save+tsv+dir creation, expand with Ontology, dual-cutoff warning, etc.). All tests pass.
257
+
258
+ ## 2026-06-09
243
259
 
244
260
  ### Added
245
- - **Rich runtime diagnostics** (high priority improvement): `active_score` now automatically computes global unspliced fraction (via integrated `qc.unspliced_global`), captures detailed bias-correction fit results (coefficients, n_genes_used, fallback status), stores per-gene `effective_gamma`, and records everything under `adata.uns["scatrans"]["diagnostics"]`. A concise run summary is logged at completion.
246
- - New public helper `scat.pl.velocity_phase_portraits(adata, genes, groupby=...)` for quick visual inspection of U vs S relationships on top hits (lower-priority diagnostic aid).
261
+ - **Rich runtime diagnostics**: `active_score` now automatically computes global unspliced fraction (via integrated `qc.unspliced_global`), captures detailed bias-correction fit results (coefficients, n_genes_used, fallback status), stores per-gene `effective_gamma`, and records everything under `adata.uns["scatrans"]["diagnostics"]`. A concise run summary is logged at completion.
262
+ - New public helper `scat.pl.velocity_phase_portraits(adata, genes, groupby=...)` for quick visual inspection of U vs S relationships on top hits.
247
263
  - `examples/real_data_template.py` — heavily commented, non-runnable but copy-adaptable template demonstrating the full recommended real-data workflow, QC, diagnostics inspection, and publication plotting.
248
264
  - Explicit documentation of the permutation approximation (velocity layers fixed from original data; only labels shuffled) in code metadata, logs, and the new "Choosing mode" section of the README.
249
265
  - `effective_gamma` column is now added to `adata.var` (and included in result tables when present) for transparency of the gamma used in the delta calculation.
250
-
251
- ### Changed / Improved
252
- - Major usability & paper-readiness upgrade to diagnostics, metadata, and user guidance.
253
- - `qc.unspliced_global` is now called automatically inside `active_score` (result stored); the function remains directly usable as a pre-flight check (`scat.qc.unspliced_global(adata)`).
254
- - Added prominent "Choosing `mode`: heuristic vs advanced (and common pitfalls)" section + decision guide to README.
255
-
256
- ### Added (0609 refactor)
257
266
  - Mixed model support (`use_mixed_model=True` + `sample_col`): statsmodels LMM (~ condition + (1 | sample)) as cell-level replicate-aware DE backend (lightweight Python analogue to dreamlet/variancePartition/dreampy LMM + Libra mixed options). Replaces scanpy/pydeseq2 p/logFC when enabled.
258
267
  - Delta Variance: `delta_variance` (condition-attributable variance fraction, 0-1, variancePartition-style) and `delta_var_pval` (LRT) computed during mixed fit; always surfaced in `all_results` / adata.var / diagnostics when mixed used.
259
268
  - New `active_score` options: `use_delta_variance_pval` (bool) + `delta_var_pval_cutoff` to optionally include the delta LRT pval as supplementary filter in significant gene selection.
260
269
  - Full backward compat; mixed path documented vs. pseudobulk; guidance + references to Libra, dreampy, NEBULA, dreamlet in README.
261
- - Existing package backed up to `backup/backup0609/`.
262
270
  - Tests + direct verification cover mixed, delta col, filter option, incompatibility with pseudobulk, and no regression on legacy paths. All tests pass.
263
271
  - Enhanced `README.md` with real-data workflow pointers and stronger emphasis on inspecting diagnostics.
264
272
  - `scat.pl` now documents the new phase-portrait helper; all existing `ax=` support preserved.
265
273
  - Internal: `_fit_huber_bias_correction` and velocity helpers now return extra fit/quality information (used for the new diagnostics) while preserving full backward compatibility of public results.
266
274
 
267
- ### Changed
268
- - **Major internal refactor** (2025): Core logic in `tl.py` (`active_score`) was extracted into private supporting modules (`_utils.py`, `_de.py`, `_velocity.py`, `_bias.py`, `_permutation.py`). The public `active_score` function is now a thin, readable orchestrator while preserving 100% identical behavior, return values, and side effects on `adata`.
275
+ ### Changed / Improved
276
+ - Major usability & paper-readiness upgrade to diagnostics, metadata, and user guidance.
277
+ - `qc.unspliced_global` is now called automatically inside `active_score` (result stored); the function remains directly usable as a pre-flight check (`scat.qc.unspliced_global(adata)`).
278
+ - Added prominent "Choosing `mode`: heuristic vs advanced (and common pitfalls)" section + decision guide to README.
279
+ - **Major internal refactor** (2026-06-09): Core logic in `tl.py` (`active_score`) was extracted into private supporting modules (`_utils.py`, `_de.py`, `_velocity.py`, `_permutation.py`, plus bias correction in `pp_bias.py`). The public `active_score` function is now a thin, readable orchestrator while preserving 100% identical behavior, return values, and side effects on `adata`.
269
280
  - Logging discipline: Library code in `pp_bias.py` and the gene-features generator now uses the `scatrans` logger instead of direct `print()` calls with emojis. CLI entrypoint configures basic logging for user-friendly output.
270
281
  - Package data access (`add_gene_features`, etc.) now uses `importlib.resources` (with backport for Python < 3.9) for robustness across wheel, sdist, and editable installs.
271
282
  - Plotting module docstrings and a few source comments cleaned of exaggerated language.
@@ -280,11 +291,7 @@ All new issues addressed. Full test suite green.
280
291
 
281
292
  ### Deprecated / Notes
282
293
  - The previous "review fixes applied" comment in `tl.py` was removed as part of the refactor.
283
- - Old code is preserved in the `backup/` directory for reference.
284
-
285
- ## [0.7.0] - Previous release (pre-refactor baseline)
286
294
 
287
- See git history and the original README for prior changes. The 0.7 series introduced the dual-track (heuristic/advanced) engine, kb_python layer support, permutation testing, and the current public API surface.
295
+ ## Earlier
288
296
 
289
- [Unreleased]: https://github.com/scATrans/scatrans/compare/v0.7.0...HEAD
290
- [0.7.0]: https://github.com/scATrans/scatrans/releases/tag/v0.7.0
297
+ Pre-refactor baseline introduced the dual-track (heuristic/advanced) engine, kb_python layer support, permutation testing, and the current public API surface. See git history and the original README for prior changes.
@@ -5,8 +5,8 @@ message: >-
5
5
  type: software
6
6
  authors:
7
7
  - name: "scATrans Developers"
8
- repository-code: "https://github.com/scATrans/scatrans"
9
- url: "https://github.com/scATrans/scatrans"
8
+ repository-code: "https://github.com/leelieber2025/scATrans"
9
+ url: "https://github.com/leelieber2025/scATrans"
10
10
  license: Apache-2.0
11
11
  version: 0.9.9
12
12
  keywords:
@@ -0,0 +1,128 @@
1
+ Metadata-Version: 2.4
2
+ Name: scatrans
3
+ Version: 0.9.10.dev0
4
+ Summary: Single-cell Active Transcription Analysis
5
+ Author: scATrans Developers
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/leelieber2025/scATrans
8
+ Project-URL: Documentation, https://scatrans.readthedocs.io
9
+ Project-URL: Changelog, https://scatrans.readthedocs.io/en/latest/changelog.html
10
+ Keywords: single-cell,RNA-seq,unspliced,nascent RNA,active transcription,bioinformatics
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: License :: OSI Approved :: Apache Software License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: scanpy>=1.9
24
+ Requires-Dist: anndata>=0.8
25
+ Requires-Dist: numpy>=1.21
26
+ Requires-Dist: pandas>=1.3
27
+ Requires-Dist: pyarrow>=10.0
28
+ Requires-Dist: scipy>=1.7
29
+ Requires-Dist: scikit-learn>=1.0
30
+ Requires-Dist: joblib>=1.2
31
+ Requires-Dist: statsmodels>=0.13
32
+ Requires-Dist: matplotlib>=3.5
33
+ Requires-Dist: seaborn>=0.12
34
+ Requires-Dist: adjustText>=0.7
35
+ Requires-Dist: importlib_resources>=5.0; python_version < "3.10"
36
+ Provides-Extra: advanced
37
+ Requires-Dist: scvelo>=0.3.0; extra == "advanced"
38
+ Provides-Extra: pseudobulk
39
+ Requires-Dist: pydeseq2>=0.4.0; extra == "pseudobulk"
40
+ Provides-Extra: gene-features
41
+ Requires-Dist: gtfparse>=1.3.0; extra == "gene-features"
42
+ Provides-Extra: memento
43
+ Requires-Dist: memento-de<0.3.0,>=0.1.0; extra == "memento"
44
+ Provides-Extra: gsea
45
+ Requires-Dist: gseapy>=1.1; extra == "gsea"
46
+ Provides-Extra: dev
47
+ Requires-Dist: pytest>=7.0; extra == "dev"
48
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
49
+ Requires-Dist: ruff>=0.4.0; extra == "dev"
50
+ Requires-Dist: pre-commit>=3.5; extra == "dev"
51
+ Requires-Dist: mypy>=1.10; extra == "dev"
52
+ Dynamic: license-file
53
+
54
+ # scATrans
55
+
56
+ [![PyPI version](https://img.shields.io/pypi/v/scatrans.svg)](https://pypi.org/project/scatrans/)
57
+ [![Python versions](https://img.shields.io/pypi/pyversions/scatrans.svg)](https://pypi.org/project/scatrans/)
58
+ [![Documentation Status](https://readthedocs.org/projects/scatrans/badge/?version=latest)](https://scatrans.readthedocs.io/en/latest/?badge=latest)
59
+ [![CI](https://github.com/leelieber2025/scATrans/actions/workflows/ci.yml/badge.svg)](https://github.com/leelieber2025/scATrans/actions/workflows/ci.yml)
60
+ [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
61
+
62
+ scATrans is a Python toolkit for single-cell differential analysis. It is
63
+ primarily designed for datasets that contain spliced/unspliced (or
64
+ mature/nascent) RNA layers. In this setting it computes a composite active
65
+ transcription score that integrates differential expression with
66
+ reference-based excess unspliced RNA to rank genes.
67
+
68
+ It also supports conventional differential expression workflows (no
69
+ velocity data required) using scanpy, PyDESeq2 pseudobulk, linear mixed
70
+ models, or optional Memento. Functional enrichment (ORA, GSEA, GO, KEGG)
71
+ uses bundled gene sets with consistent universe handling, and a set of
72
+ visualization functions is provided.
73
+
74
+ **📚 Full documentation, tutorials, and the complete API reference are on
75
+ Read the Docs: https://scatrans.readthedocs.io**
76
+
77
+ ## Installation
78
+
79
+ ```bash
80
+ pip install scatrans
81
+
82
+ # Optional extras: advanced (scVelo) mode, pseudobulk DE (PyDESeq2), Memento, GSEA
83
+ pip install "scatrans[advanced,gene_features,pseudobulk]" gseapy
84
+ ```
85
+
86
+ See [Installation](https://scatrans.readthedocs.io/en/latest/installation.html)
87
+ for extras, source installs, and logging setup.
88
+
89
+ ## Quickstart
90
+
91
+ ```python
92
+ import scatrans as scat
93
+
94
+ # One-liner pipeline: score → filter → GO enrichment
95
+ result = scat.run_default_pipeline(
96
+ adata,
97
+ groupby="condition",
98
+ target_group="Disease",
99
+ reference_group="Control",
100
+ sample_col="sample", # optional; auto-selects pseudobulk when >=3 replicates/group
101
+ organism="mouse",
102
+ )
103
+ print(result["candidates"].head())
104
+ print(result["enrichment"].head())
105
+ ```
106
+
107
+ See the [Quickstart](https://scatrans.readthedocs.io/en/latest/quickstart.html)
108
+ for a complete end-to-end walkthrough, the
109
+ [Tutorials](https://scatrans.readthedocs.io/en/latest/tutorials/index.html)
110
+ for fully worked, real-data notebooks (with and without RNA-velocity
111
+ layers), and the
112
+ [User Guide](https://scatrans.readthedocs.io/en/latest/user_guide/index.html)
113
+ for DE backends, enrichment, plotting, and advanced options.
114
+
115
+ ## Before reporting results in a paper
116
+
117
+ `active_score` is a **composite heuristic rank**, not a p-value or FDR on
118
+ its own. See
119
+ [Statistical Guidance](https://scatrans.readthedocs.io/en/latest/statistical_guidance.html)
120
+ for what each output column means, safe vs. unsafe uses, and a reporting
121
+ checklist before you cite scATrans results in a manuscript or supplement.
122
+
123
+ ## License
124
+
125
+ Software (Python source) is licensed under [Apache License 2.0](LICENSE).
126
+ Bundled gene-set data (GO, KEGG) carries its own licensing terms — see
127
+ [License](https://scatrans.readthedocs.io/en/latest/license.html) before
128
+ commercial use.
@@ -0,0 +1,75 @@
1
+ # scATrans
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/scatrans.svg)](https://pypi.org/project/scatrans/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/scatrans.svg)](https://pypi.org/project/scatrans/)
5
+ [![Documentation Status](https://readthedocs.org/projects/scatrans/badge/?version=latest)](https://scatrans.readthedocs.io/en/latest/?badge=latest)
6
+ [![CI](https://github.com/leelieber2025/scATrans/actions/workflows/ci.yml/badge.svg)](https://github.com/leelieber2025/scATrans/actions/workflows/ci.yml)
7
+ [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
8
+
9
+ scATrans is a Python toolkit for single-cell differential analysis. It is
10
+ primarily designed for datasets that contain spliced/unspliced (or
11
+ mature/nascent) RNA layers. In this setting it computes a composite active
12
+ transcription score that integrates differential expression with
13
+ reference-based excess unspliced RNA to rank genes.
14
+
15
+ It also supports conventional differential expression workflows (no
16
+ velocity data required) using scanpy, PyDESeq2 pseudobulk, linear mixed
17
+ models, or optional Memento. Functional enrichment (ORA, GSEA, GO, KEGG)
18
+ uses bundled gene sets with consistent universe handling, and a set of
19
+ visualization functions is provided.
20
+
21
+ **📚 Full documentation, tutorials, and the complete API reference are on
22
+ Read the Docs: https://scatrans.readthedocs.io**
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ pip install scatrans
28
+
29
+ # Optional extras: advanced (scVelo) mode, pseudobulk DE (PyDESeq2), Memento, GSEA
30
+ pip install "scatrans[advanced,gene_features,pseudobulk]" gseapy
31
+ ```
32
+
33
+ See [Installation](https://scatrans.readthedocs.io/en/latest/installation.html)
34
+ for extras, source installs, and logging setup.
35
+
36
+ ## Quickstart
37
+
38
+ ```python
39
+ import scatrans as scat
40
+
41
+ # One-liner pipeline: score → filter → GO enrichment
42
+ result = scat.run_default_pipeline(
43
+ adata,
44
+ groupby="condition",
45
+ target_group="Disease",
46
+ reference_group="Control",
47
+ sample_col="sample", # optional; auto-selects pseudobulk when >=3 replicates/group
48
+ organism="mouse",
49
+ )
50
+ print(result["candidates"].head())
51
+ print(result["enrichment"].head())
52
+ ```
53
+
54
+ See the [Quickstart](https://scatrans.readthedocs.io/en/latest/quickstart.html)
55
+ for a complete end-to-end walkthrough, the
56
+ [Tutorials](https://scatrans.readthedocs.io/en/latest/tutorials/index.html)
57
+ for fully worked, real-data notebooks (with and without RNA-velocity
58
+ layers), and the
59
+ [User Guide](https://scatrans.readthedocs.io/en/latest/user_guide/index.html)
60
+ for DE backends, enrichment, plotting, and advanced options.
61
+
62
+ ## Before reporting results in a paper
63
+
64
+ `active_score` is a **composite heuristic rank**, not a p-value or FDR on
65
+ its own. See
66
+ [Statistical Guidance](https://scatrans.readthedocs.io/en/latest/statistical_guidance.html)
67
+ for what each output column means, safe vs. unsafe uses, and a reporting
68
+ checklist before you cite scATrans results in a manuscript or supplement.
69
+
70
+ ## License
71
+
72
+ Software (Python source) is licensed under [Apache License 2.0](LICENSE).
73
+ Bundled gene-set data (GO, KEGG) carries its own licensing terms — see
74
+ [License](https://scatrans.readthedocs.io/en/latest/license.html) before
75
+ commercial use.
@@ -0,0 +1,34 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ scATrans is under active development. Security fixes are applied to the
6
+ latest released version on [PyPI](https://pypi.org/project/scatrans/); we do
7
+ not maintain long-term security support for older releases.
8
+
9
+ | Version | Supported |
10
+ | ------- | --------- |
11
+ | Latest release | :white_check_mark: |
12
+ | Older releases | :x: |
13
+
14
+ ## Reporting a Vulnerability
15
+
16
+ Please **do not** open a public GitHub issue for security vulnerabilities.
17
+
18
+ Instead, use GitHub's private vulnerability reporting:
19
+ [Report a vulnerability](https://github.com/leelieber2025/scATrans/security/advisories/new)
20
+ (repository → **Security** tab → **Report a vulnerability**).
21
+
22
+ Include a description of the issue, steps to reproduce, and the affected
23
+ version. We will acknowledge reports and follow up with a timeline for a fix
24
+ once the report is triaged.
25
+
26
+ ## Scope
27
+
28
+ scATrans is a local single-cell analysis library (no network services, no
29
+ telemetry, no remote code execution by design). Relevant concerns include:
30
+ unsafe deserialization of untrusted input files, path traversal in file I/O
31
+ helpers (e.g. `save_enrichment_report`, gene-feature generation), and
32
+ dependency vulnerabilities in the packages it relies on (scanpy, anndata,
33
+ PyDESeq2, gseapy, etc.) — for the latter, please also check whether the
34
+ issue originates upstream.
@@ -0,0 +1,8 @@
1
+ /* Minor spacing tweaks on top of sphinx_book_theme defaults. */
2
+ .bd-main .bd-content {
3
+ max-width: 88rem;
4
+ }
5
+
6
+ .bd-article {
7
+ font-size: 15px;
8
+ }