bsvae 0.3.2__tar.gz → 0.4.0__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.
- bsvae-0.4.0/PKG-INFO +353 -0
- bsvae-0.4.0/README.md +313 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/pyproject.toml +15 -2
- bsvae-0.4.0/src/bsvae/benchmark/__init__.py +2 -0
- bsvae-0.4.0/src/bsvae/benchmark/acorde.R +113 -0
- bsvae-0.4.0/src/bsvae/benchmark/edges.py +123 -0
- bsvae-0.4.0/src/bsvae/benchmark/harness.py +508 -0
- bsvae-0.4.0/src/bsvae/benchmark/methods.py +337 -0
- bsvae-0.4.0/src/bsvae/benchmark/runners.py +328 -0
- bsvae-0.4.0/src/bsvae/benchmark/twn.R +92 -0
- bsvae-0.4.0/src/bsvae/benchmark/wgcna.R +128 -0
- bsvae-0.4.0/src/bsvae/cli/_common.py +365 -0
- bsvae-0.4.0/src/bsvae/cli/benchmark.py +153 -0
- bsvae-0.4.0/src/bsvae/cli/networks.py +917 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/cli/simulate.py +52 -17
- bsvae-0.4.0/src/bsvae/cli/sweep_k.py +404 -0
- bsvae-0.4.0/src/bsvae/cli/train.py +119 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/latent/latent_analysis.py +2 -1
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/latent/latent_export.py +2 -1
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/models/encoder.py +87 -85
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/models/gmm_prior.py +152 -49
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/models/gmvae.py +5 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/models/losses.py +832 -632
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/networks/extract_networks.py +22 -34
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/networks/module_extraction.py +60 -62
- bsvae-0.4.0/src/bsvae/networks/postprocess.py +666 -0
- bsvae-0.4.0/src/bsvae/networks/quality.py +159 -0
- bsvae-0.4.0/src/bsvae/networks/targets.py +665 -0
- bsvae-0.4.0/src/bsvae/simulation/isoform.py +423 -0
- bsvae-0.4.0/src/bsvae/simulation/metrics.py +456 -0
- bsvae-0.4.0/src/bsvae/simulation/scenario.py +863 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/utils/datasets.py +62 -9
- bsvae-0.4.0/src/bsvae/utils/hierarchy.py +342 -0
- bsvae-0.4.0/src/bsvae/utils/isoform.py +519 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/utils/modelIO.py +3 -0
- bsvae-0.4.0/src/bsvae/utils/preprocess.py +131 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/utils/training.py +185 -77
- bsvae-0.3.2/PKG-INFO +0 -224
- bsvae-0.3.2/README.md +0 -192
- bsvae-0.3.2/src/bsvae/cli/networks.py +0 -346
- bsvae-0.3.2/src/bsvae/cli/sweep_k.py +0 -511
- bsvae-0.3.2/src/bsvae/cli/train.py +0 -312
- bsvae-0.3.2/src/bsvae/hyperparam.ini +0 -9
- bsvae-0.3.2/src/bsvae/main.py +0 -364
- bsvae-0.3.2/src/bsvae/networks/cli.py +0 -689
- bsvae-0.3.2/src/bsvae/simulation/metrics.py +0 -154
- bsvae-0.3.2/src/bsvae/simulation/scenario.py +0 -611
- bsvae-0.3.2/src/bsvae/utils/evaluate.py +0 -84
- bsvae-0.3.2/src/bsvae/utils/hierarchy.py +0 -172
- bsvae-0.3.2/src/bsvae/utils/initialization.py +0 -30
- {bsvae-0.3.2 → bsvae-0.4.0}/LICENSE +0 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/__init__.py +0 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/cli/__init__.py +0 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/latent/__init__.py +0 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/models/__init__.py +0 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/models/decoder.py +0 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/models/vae.py +0 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/networks/__init__.py +0 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/networks/utils.py +0 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/simulation/__init__.py +0 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/simulation/generate.py +0 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/utils/__init__.py +0 -0
- {bsvae-0.3.2 → bsvae-0.4.0}/src/bsvae/utils/helpers.py +0 -0
bsvae-0.4.0/PKG-INFO
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bsvae
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Gaussian Mixture VAE for multi-modal biological module discovery in omics data.
|
|
5
|
+
License: GPL-3.0-only
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: variational-autoencoder,gaussian-mixture-model,pytorch,bioinformatics,gene-expression,module-discovery,omics
|
|
8
|
+
Author: Kynon J Benjamin
|
|
9
|
+
Author-email: kj.benjamin90@gmail.com
|
|
10
|
+
Requires-Python: >=3.11,<3.14
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
21
|
+
Provides-Extra: anndata
|
|
22
|
+
Provides-Extra: yaml
|
|
23
|
+
Requires-Dist: anndata (>=0.10) ; extra == "anndata"
|
|
24
|
+
Requires-Dist: faiss-cpu (>=1.7)
|
|
25
|
+
Requires-Dist: h5py (>=3.0)
|
|
26
|
+
Requires-Dist: numpy (<2.3)
|
|
27
|
+
Requires-Dist: pandas (>=2.3.2,<3.0.0)
|
|
28
|
+
Requires-Dist: pyyaml (>=6.0) ; extra == "yaml"
|
|
29
|
+
Requires-Dist: scikit-learn (>=1.7.2,<2.0.0)
|
|
30
|
+
Requires-Dist: scipy (>=1.16.2,<2.0.0)
|
|
31
|
+
Requires-Dist: torch (>=2.8.0,<3.0.0)
|
|
32
|
+
Requires-Dist: tqdm (>=4.67.1,<5.0.0)
|
|
33
|
+
Project-URL: Bug Tracker, https://github.com/heart-gen/BSVAE/issues
|
|
34
|
+
Project-URL: Changelog, https://github.com/heart-gen/BSVAE/blob/main/CHANGELOG.md
|
|
35
|
+
Project-URL: documentation, https://bsvae.readthedocs.io/en/latest/
|
|
36
|
+
Project-URL: homepage, https://bsvae.readthedocs.io/en/latest/
|
|
37
|
+
Project-URL: repository, https://github.com/heart-gen/BSVAE
|
|
38
|
+
Description-Content-Type: text/markdown
|
|
39
|
+
|
|
40
|
+
# BSVAE: Gaussian Mixture VAE for Module Discovery
|
|
41
|
+
|
|
42
|
+
[](https://pypi.org/project/bsvae/)
|
|
43
|
+
[](https://pytorch.org/)
|
|
44
|
+
[](https://python.org/)
|
|
45
|
+
[](LICENSE)
|
|
46
|
+
[](https://bsvae.readthedocs.io/)
|
|
47
|
+
|
|
48
|
+
BSVAE is a PyTorch package for feature-level module discovery in omics data. The main model, `GMMModuleVAE`, learns latent structure across features such as genes, transcripts, or proteins, then supports downstream network extraction, module assignment, latent analysis, and simulation-based benchmarking.
|
|
49
|
+
|
|
50
|
+
## What The Package Provides
|
|
51
|
+
|
|
52
|
+
- `bsvae-train` for training a two-phase GMM-VAE
|
|
53
|
+
- `bsvae-sweep-k` for selecting the number of modules (`K`) with held-out validation and optional stability replicates
|
|
54
|
+
- `bsvae-networks` for post-training network extraction, module extraction (with gene coherence and an isoform-specific residual scan at transcript level), targeted-gene tests, latent export, and latent analysis
|
|
55
|
+
- `bsvae-simulate` for synthetic data generation, scenario-grid simulation, and module-recovery benchmarking
|
|
56
|
+
- `bsvae-benchmark` for head-to-head runs of BSVAE, WGCNA, acorde, usage networks, ICA/NMF and TWN on simulated scenario grids
|
|
57
|
+
|
|
58
|
+
## Installation
|
|
59
|
+
|
|
60
|
+
Install from PyPI:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install bsvae
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Install from source:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
git clone https://github.com/heart-gen/BSVAE.git
|
|
70
|
+
cd BSVAE
|
|
71
|
+
pip install -e .
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Optional dependencies:
|
|
75
|
+
|
|
76
|
+
- `anndata` is only needed for `.h5ad` input or `.h5ad` latent export helpers
|
|
77
|
+
- `pyyaml` is only needed to read YAML scenario configs (JSON configs need nothing)
|
|
78
|
+
- R with `WGCNA` (plus `glasso` for TWN) is only needed for the WGCNA, acorde and TWN methods of `bsvae-benchmark`; check with `bsvae-benchmark check-env`
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install "bsvae[anndata,yaml]"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
For development, use Poetry: `poetry install --with dev --extras "anndata yaml"`.
|
|
85
|
+
|
|
86
|
+
## Input Data Contract
|
|
87
|
+
|
|
88
|
+
Training and most downstream commands expect an expression matrix in `features x samples` orientation:
|
|
89
|
+
|
|
90
|
+
- rows are features such as genes, transcripts, or proteins
|
|
91
|
+
- columns are sample IDs
|
|
92
|
+
- the first column is the feature index when using CSV/TSV
|
|
93
|
+
|
|
94
|
+
Supported loaders:
|
|
95
|
+
|
|
96
|
+
- `.csv` / `.csv.gz`
|
|
97
|
+
- `.tsv` / `.tsv.gz`
|
|
98
|
+
- `.h5` / `.hdf5`
|
|
99
|
+
- `.h5ad` with optional `anndata`
|
|
100
|
+
|
|
101
|
+
## CLI Entry Points
|
|
102
|
+
|
|
103
|
+
- `bsvae-train`
|
|
104
|
+
- `bsvae-sweep-k`
|
|
105
|
+
- `bsvae-networks`
|
|
106
|
+
- `bsvae-simulate`
|
|
107
|
+
- `bsvae-benchmark` (BSVAE vs WGCNA, transcript-usage networks, ICA/NMF, acorde and TWN on simulated data; needs R with `WGCNA`, plus `glasso` for TWN)
|
|
108
|
+
|
|
109
|
+
At transcript level, `extract-modules` returns two independent outputs: coherent module assignments (the gene-coherence policy is the default whenever `--expr` and `--tx2gene` are given) and the isoform-specific residual scan over every multi-isoform transcript, so module membership and isoform-specific divergence are reported and validated separately. Further transcript-level commands in `bsvae-networks`: `consensus-modules` (majority vote over seeds with a per-feature stability score), `isoform-specific` (isoforms whose expression tracks a module other than their gene's), `target-genes` (calibrated membership tests for candidate genes or GWAS loci from a gene list, transcript list or BED file, with a case/control interaction test), `target-genes-combine` (pool those tests across cohorts or brain regions), `module-quality` (kME, enrichment, preservation in a second dataset) and `regress-covariates` (remove batch and other known covariates before training).
|
|
110
|
+
|
|
111
|
+
### `bsvae-networks` subcommands
|
|
112
|
+
|
|
113
|
+
| Subcommand | Purpose |
|
|
114
|
+
| --- | --- |
|
|
115
|
+
| `extract-networks` | feature-feature networks (`mu_cosine`, `gamma_knn`) |
|
|
116
|
+
| `extract-modules` | post-processed modules, eigengenes, kME; at transcript level also gene coherence and the isoform-specific scan |
|
|
117
|
+
| `consensus-modules` | majority vote over seeds with a per-feature stability score |
|
|
118
|
+
| `isoform-specific` | isoforms whose expression tracks a module other than their gene's, optionally cross-fitted (`--folds`) |
|
|
119
|
+
| `isoform-residuals` | the gene-programme-removed residual matrix |
|
|
120
|
+
| `target-genes`, `target-genes-combine` | calibrated tests for candidate genes or GWAS loci, and pooling across cohorts |
|
|
121
|
+
| `module-quality` | kME, GMT enrichment, preservation in a second dataset |
|
|
122
|
+
| `regress-covariates` | remove batch and other known covariates before training |
|
|
123
|
+
| `export-latents`, `latent-analysis` | latent arrays, clustering and embeddings |
|
|
124
|
+
|
|
125
|
+
Flags worth knowing at transcript level: `--tx2gene`, `--covariates`, `--loo-eigengene {approx,exact,off}`, `--max-target-corr`, `--samples` / `--exclude-samples` (train fold models for cross-fitting), `--aggregate-to-gene`, and `--amp` on `bsvae-train` for mixed precision. See the [CLI reference](https://bsvae.readthedocs.io/en/latest/cli.html) for every flag and default.
|
|
126
|
+
|
|
127
|
+
## Quickstart
|
|
128
|
+
|
|
129
|
+
Train a small model:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
bsvae-train pilot_run \
|
|
133
|
+
--dataset data/expression.csv \
|
|
134
|
+
--epochs 50 \
|
|
135
|
+
--n-modules 12 \
|
|
136
|
+
--latent-dim 16
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Recommended production flow: train with a generous number of GMM components, about three times the number of modules you expect (at least 20), and let `extract-modules` merge components whose eigengenes correlate (see [Choosing K](https://bsvae.readthedocs.io/en/latest/hyperparameters.html#choosing-k)). `bsvae-sweep-k` is an optional check of that component count by held-out ELBO and, with `--stability-reps`, by seed stability; it retrains the selected model so the steps below can start from it.
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
bsvae-sweep-k sweep1 \
|
|
143
|
+
--dataset data/expression.csv \
|
|
144
|
+
--k-grid 8,12,16,24,32 \
|
|
145
|
+
--sweep-epochs 60 \
|
|
146
|
+
--stability-reps 5 \
|
|
147
|
+
--val-frac 0.1
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
This writes sweep outputs under `results/sweep1/sweep_k/` and retrains the selected model under `results/sweep1/final_k<K>/`.
|
|
151
|
+
|
|
152
|
+
Extract module assignments from the final model (post-processing adds a grey class, a minimum module size and eigengene merging):
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
bsvae-networks extract-modules \
|
|
156
|
+
--model-path results/sweep1/final_k16 \
|
|
157
|
+
--dataset data/expression.csv \
|
|
158
|
+
--output-dir results/sweep1/final_k16/modules \
|
|
159
|
+
--expr data/expression.csv \
|
|
160
|
+
--soft-eigengenes
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
With transcript-level data, pass `--tx2gene` as well. `extract-modules` then produces two independent outputs: module assignments annotated by the gene-coherence policy (default; `--no-gene-coherence` to disable) and the isoform-specific residual scan (`--no-isoform-calls` to skip, `--loo-eigengene` to change the leave-one-gene-out eigengene correction). A transcript's module label never decides whether it is tested. For calibrated calls, pass technical covariates (`--covariates`) and, where modules were learned on the same samples, cross-fit over sample folds (`isoform-specific --folds`).
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
bsvae-networks extract-modules \
|
|
167
|
+
--model-path results/iso1 \
|
|
168
|
+
--dataset data/transcripts.tsv.gz \
|
|
169
|
+
--output-dir results/iso1/modules \
|
|
170
|
+
--expr data/transcripts.tsv.gz \
|
|
171
|
+
--tx2gene data/tx2gene.tsv
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
This adds `modules_raw.csv`, `gene_coherence.csv` and `isoform_specific.csv` next to `modules.csv`; see the [CLI reference](docs/cli.md) for the columns.
|
|
175
|
+
|
|
176
|
+
Export latents:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
bsvae-networks export-latents \
|
|
180
|
+
--model-path results/sweep1/final_k16 \
|
|
181
|
+
--dataset data/expression.csv \
|
|
182
|
+
--output results/sweep1/final_k16/latents
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
This command writes `results/sweep1/final_k16/latents.npz` containing `mu`, `logvar`, `gamma`, and `feature_ids`.
|
|
186
|
+
|
|
187
|
+
Extract feature-feature networks:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
bsvae-networks extract-networks \
|
|
191
|
+
--model-path results/sweep1/final_k16 \
|
|
192
|
+
--dataset data/expression.csv \
|
|
193
|
+
--output-dir results/sweep1/final_k16/networks \
|
|
194
|
+
--methods mu_cosine gamma_knn \
|
|
195
|
+
--top-k 50
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Run latent-space analysis:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
bsvae-networks latent-analysis \
|
|
202
|
+
--model-path results/sweep1/final_k16 \
|
|
203
|
+
--dataset data/expression.csv \
|
|
204
|
+
--output-dir results/sweep1/final_k16/latent_analysis \
|
|
205
|
+
--kmeans-k 16 \
|
|
206
|
+
--umap
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Worked Example: Transcript-Level Workflow On Simulated Data
|
|
210
|
+
|
|
211
|
+
This end-to-end example uses the same simulator as the [benchmark study](https://github.com/heart-gen/bsvae-benchmarking), so every file below has a known truth to compare against. It runs in minutes on a CPU. The real-data version of the same chain (residualise, `bsvae-sweep-k`, `extract-modules`, `extract-networks`, `export-latents`) is in the [tutorial](https://bsvae.readthedocs.io/en/latest/tutorial.html).
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# 1. simulate one transcript-level scenario (500 genes, 6 modules, 150 samples)
|
|
215
|
+
bsvae-simulate init-config --output iso.json --isoform # edit n_genes, n_modules, grid as needed
|
|
216
|
+
bsvae-simulate generate-grid --config iso.json --outdir sim --reps 1 --base-seed 13
|
|
217
|
+
SCEN=$(ls -d sim/scenarios/*/rep_000 | head -1)
|
|
218
|
+
|
|
219
|
+
# 2. choose K, then retrain the selected model (transcript-to-gene map enables the hierarchical loss)
|
|
220
|
+
bsvae-sweep-k iso1 --dataset $SCEN/expr/features_x_samples.tsv.gz \
|
|
221
|
+
--k-grid 12,18,24 --sweep-epochs 60 --stability-reps 2 --val-frac 0.1 \
|
|
222
|
+
--tx2gene $SCEN/truth/tx2gene.tsv --hier-strength 0.2 --isoform-stratified
|
|
223
|
+
|
|
224
|
+
# 3. two outputs: gene-coherent modules and the isoform-specific residual scan
|
|
225
|
+
bsvae-networks extract-modules --model-path results/iso1/final_k<K> \
|
|
226
|
+
--dataset $SCEN/expr/features_x_samples.tsv.gz --expr $SCEN/expr/features_x_samples.tsv.gz \
|
|
227
|
+
--tx2gene $SCEN/truth/tx2gene.tsv --covariates $SCEN/covariates.tsv.gz \
|
|
228
|
+
--loo-eigengene approx --max-target-corr 0.4 --soft-eigengenes \
|
|
229
|
+
--output-dir results/iso1/modules
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
`results/iso1/modules/` now holds `modules.csv` (gene-coherent assignments, grey is `-1`), `modules_raw.csv`, `gene_coherence.csv`, `isoform_specific.csv`, `eigengenes.csv`, `kME.csv` and `gamma.npz`. Score the modules against the simulator's truth:
|
|
233
|
+
|
|
234
|
+
```python
|
|
235
|
+
import pandas as pd
|
|
236
|
+
from sklearn.metrics import adjusted_rand_score
|
|
237
|
+
|
|
238
|
+
pred = pd.read_csv("results/iso1/modules/modules.csv", index_col="feature_id")["module"]
|
|
239
|
+
truth = pd.read_csv(f"{scen}/truth/modules_hard.csv", index_col="feature_id")["module"]
|
|
240
|
+
print(adjusted_rand_score(truth.loc[pred.index], pred)) # grey (-1) counted as its own label
|
|
241
|
+
|
|
242
|
+
calls = pd.read_csv("results/iso1/modules/isoform_specific.csv")
|
|
243
|
+
sw = pd.read_csv(f"{scen}/truth/switch_table.tsv.gz", sep="\t", index_col=0)
|
|
244
|
+
print(calls["called"].sum(), "calls;", sw["is_switched"].sum(), "truly switched isoforms")
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
For calibrated calls when modules were learned on the same samples, train one fold model per sample split and cross-fit:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
bsvae-networks isoform-specific --dataset $SCEN/expr/features_x_samples.tsv.gz \
|
|
251
|
+
--tx2gene $SCEN/truth/tx2gene.tsv --covariates $SCEN/covariates.tsv.gz \
|
|
252
|
+
--modules fold0/modules/modules_raw.csv fold1/modules/modules_raw.csv --folds folds.tsv \
|
|
253
|
+
--max-target-corr 0.4 --output results/iso1/isoform_specific_crossfit.tsv
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Then test candidate genes against the same modules, and pool several cohorts:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
bsvae-networks target-genes --dataset data/transcripts.tsv.gz --tx2gene data/tx2gene.tsv \
|
|
260
|
+
--modules results/iso1/modules/modules.csv --genes candidates.txt --output-dir results/iso1/targets
|
|
261
|
+
|
|
262
|
+
bsvae-networks target-genes-combine \
|
|
263
|
+
--inputs DLPFC=results/dlpfc/targets/target_isoforms.tsv HIPP=results/hipp/targets/target_isoforms.tsv \
|
|
264
|
+
--n-samples DLPFC=160 HIPP=150 --output results/targets_combined.tsv
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Training Outputs
|
|
268
|
+
|
|
269
|
+
`bsvae-train` writes to `results/<experiment>/` by default:
|
|
270
|
+
|
|
271
|
+
- `model.pt`
|
|
272
|
+
- `specs.json`
|
|
273
|
+
- `train_losses.csv`
|
|
274
|
+
- `model-<epoch>.pt` checkpoints when `--checkpoint-every` is greater than zero
|
|
275
|
+
|
|
276
|
+
`bsvae-sweep-k` writes:
|
|
277
|
+
|
|
278
|
+
- `results/<name>/sweep_k/sweep_results.csv`
|
|
279
|
+
- `results/<name>/sweep_k/sweep_summary.json`
|
|
280
|
+
- `results/<name>/sweep_k/k<K>/rep_<rep>/...` per-sweep run outputs
|
|
281
|
+
- `results/<name>/final_k<K>/...` for the final retrained model when `--train-final` is enabled
|
|
282
|
+
|
|
283
|
+
## Simulation and Benchmarking
|
|
284
|
+
|
|
285
|
+
Generate one synthetic dataset:
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
bsvae-simulate generate \
|
|
289
|
+
--output data/sim_expr.csv \
|
|
290
|
+
--save-ground-truth data/sim_truth.csv
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Generate a scenario grid:
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
bsvae-simulate init-config --output sim.yaml
|
|
297
|
+
|
|
298
|
+
bsvae-simulate generate-grid \
|
|
299
|
+
--config sim.yaml \
|
|
300
|
+
--outdir results/sim_pub_v1 \
|
|
301
|
+
--reps 30 \
|
|
302
|
+
--base-seed 13
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Validate the generated grid:
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
bsvae-simulate validate-grid --grid-dir results/sim_pub_v1
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Each scenario replicate writes method-ready files under `results/sim_pub_v1/scenarios/<scenario_id>/rep_<rep>/`, including:
|
|
312
|
+
|
|
313
|
+
- `expr/features_x_samples.tsv.gz`
|
|
314
|
+
- `expr/samples_x_features.tsv.gz`
|
|
315
|
+
- `truth/modules_hard.csv` (null features are `-1`)
|
|
316
|
+
- `truth/tx2gene.tsv` and `truth/modules_gene.csv` for the transcript-level family (`bsvae-simulate init-config --isoform`)
|
|
317
|
+
- `method_inputs.json`
|
|
318
|
+
|
|
319
|
+
Run BSVAE and WGCNA head-to-head on a grid and summarise grey-aware ARI/NMI, best-match Jaccard, and gene-level recovery:
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
bsvae-benchmark check-env # torch, Rscript, WGCNA
|
|
323
|
+
bsvae-benchmark run --config iso.json --outdir results/bench --methods bsvae,wgcna --seeds 0,1,2
|
|
324
|
+
bsvae-benchmark summarize --results results/bench/results.tsv --by scenario_id,method
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
`run` is resumable and can be split across a cluster with `--rep-ids` and `--scenario-ids`. Comparison methods are `bsvae_raw`, `bsvae_hier`, `bsvae_isoform`, `wgcna_raw`, `acorde`, `twn`, `usage_network`, `ica` and `nmf`. In the companion study (10 replicates, transcript-level scenarios, 150 samples), mean all-feature ARI was:
|
|
328
|
+
|
|
329
|
+
| Method | ARI (all features) | Unassigned |
|
|
330
|
+
| --- | --- | --- |
|
|
331
|
+
| `bsvae` (gene coherence) | 0.78 | 10% |
|
|
332
|
+
| `bsvae_raw` | 0.70 | 10% |
|
|
333
|
+
| `wgcna` (gene coherence) | 0.65 | 0.3% |
|
|
334
|
+
| `wgcna_raw` | 0.54 | 0.3% |
|
|
335
|
+
| `acorde` | 0.44 | 35% |
|
|
336
|
+
|
|
337
|
+
These are simulation results; see [Benchmarking](https://bsvae.readthedocs.io/en/latest/benchmarking.html) for the pipeline, output files, matched-coverage metrics and caveats, including that the residual-scan defaults were not validated in every simulated cell.
|
|
338
|
+
|
|
339
|
+
## Documentation
|
|
340
|
+
|
|
341
|
+
Full documentation is at [bsvae.readthedocs.io](https://bsvae.readthedocs.io/):
|
|
342
|
+
|
|
343
|
+
- [Installation](https://bsvae.readthedocs.io/en/latest/installation.html) and [Quick Start](https://bsvae.readthedocs.io/en/latest/quickstart.html)
|
|
344
|
+
- [Tutorial](https://bsvae.readthedocs.io/en/latest/tutorial.html) (real-data workflow and the simulated example)
|
|
345
|
+
- [CLI reference](https://bsvae.readthedocs.io/en/latest/cli.html), [network workflows](https://bsvae.readthedocs.io/en/latest/networks.html) and [hyperparameters](https://bsvae.readthedocs.io/en/latest/hyperparameters.html)
|
|
346
|
+
- [Benchmarking](https://bsvae.readthedocs.io/en/latest/benchmarking.html) and [HPC](https://bsvae.readthedocs.io/en/latest/hpc.html)
|
|
347
|
+
|
|
348
|
+
The same pages are in `docs/` in this repository. Release notes are in [CHANGELOG.md](CHANGELOG.md).
|
|
349
|
+
|
|
350
|
+
## License
|
|
351
|
+
|
|
352
|
+
This project is licensed under the [GNU General Public License v3.0](LICENSE).
|
|
353
|
+
|
bsvae-0.4.0/README.md
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
# BSVAE: Gaussian Mixture VAE for Module Discovery
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/bsvae/)
|
|
4
|
+
[](https://pytorch.org/)
|
|
5
|
+
[](https://python.org/)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://bsvae.readthedocs.io/)
|
|
8
|
+
|
|
9
|
+
BSVAE is a PyTorch package for feature-level module discovery in omics data. The main model, `GMMModuleVAE`, learns latent structure across features such as genes, transcripts, or proteins, then supports downstream network extraction, module assignment, latent analysis, and simulation-based benchmarking.
|
|
10
|
+
|
|
11
|
+
## What The Package Provides
|
|
12
|
+
|
|
13
|
+
- `bsvae-train` for training a two-phase GMM-VAE
|
|
14
|
+
- `bsvae-sweep-k` for selecting the number of modules (`K`) with held-out validation and optional stability replicates
|
|
15
|
+
- `bsvae-networks` for post-training network extraction, module extraction (with gene coherence and an isoform-specific residual scan at transcript level), targeted-gene tests, latent export, and latent analysis
|
|
16
|
+
- `bsvae-simulate` for synthetic data generation, scenario-grid simulation, and module-recovery benchmarking
|
|
17
|
+
- `bsvae-benchmark` for head-to-head runs of BSVAE, WGCNA, acorde, usage networks, ICA/NMF and TWN on simulated scenario grids
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
Install from PyPI:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install bsvae
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Install from source:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
git clone https://github.com/heart-gen/BSVAE.git
|
|
31
|
+
cd BSVAE
|
|
32
|
+
pip install -e .
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Optional dependencies:
|
|
36
|
+
|
|
37
|
+
- `anndata` is only needed for `.h5ad` input or `.h5ad` latent export helpers
|
|
38
|
+
- `pyyaml` is only needed to read YAML scenario configs (JSON configs need nothing)
|
|
39
|
+
- R with `WGCNA` (plus `glasso` for TWN) is only needed for the WGCNA, acorde and TWN methods of `bsvae-benchmark`; check with `bsvae-benchmark check-env`
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install "bsvae[anndata,yaml]"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
For development, use Poetry: `poetry install --with dev --extras "anndata yaml"`.
|
|
46
|
+
|
|
47
|
+
## Input Data Contract
|
|
48
|
+
|
|
49
|
+
Training and most downstream commands expect an expression matrix in `features x samples` orientation:
|
|
50
|
+
|
|
51
|
+
- rows are features such as genes, transcripts, or proteins
|
|
52
|
+
- columns are sample IDs
|
|
53
|
+
- the first column is the feature index when using CSV/TSV
|
|
54
|
+
|
|
55
|
+
Supported loaders:
|
|
56
|
+
|
|
57
|
+
- `.csv` / `.csv.gz`
|
|
58
|
+
- `.tsv` / `.tsv.gz`
|
|
59
|
+
- `.h5` / `.hdf5`
|
|
60
|
+
- `.h5ad` with optional `anndata`
|
|
61
|
+
|
|
62
|
+
## CLI Entry Points
|
|
63
|
+
|
|
64
|
+
- `bsvae-train`
|
|
65
|
+
- `bsvae-sweep-k`
|
|
66
|
+
- `bsvae-networks`
|
|
67
|
+
- `bsvae-simulate`
|
|
68
|
+
- `bsvae-benchmark` (BSVAE vs WGCNA, transcript-usage networks, ICA/NMF, acorde and TWN on simulated data; needs R with `WGCNA`, plus `glasso` for TWN)
|
|
69
|
+
|
|
70
|
+
At transcript level, `extract-modules` returns two independent outputs: coherent module assignments (the gene-coherence policy is the default whenever `--expr` and `--tx2gene` are given) and the isoform-specific residual scan over every multi-isoform transcript, so module membership and isoform-specific divergence are reported and validated separately. Further transcript-level commands in `bsvae-networks`: `consensus-modules` (majority vote over seeds with a per-feature stability score), `isoform-specific` (isoforms whose expression tracks a module other than their gene's), `target-genes` (calibrated membership tests for candidate genes or GWAS loci from a gene list, transcript list or BED file, with a case/control interaction test), `target-genes-combine` (pool those tests across cohorts or brain regions), `module-quality` (kME, enrichment, preservation in a second dataset) and `regress-covariates` (remove batch and other known covariates before training).
|
|
71
|
+
|
|
72
|
+
### `bsvae-networks` subcommands
|
|
73
|
+
|
|
74
|
+
| Subcommand | Purpose |
|
|
75
|
+
| --- | --- |
|
|
76
|
+
| `extract-networks` | feature-feature networks (`mu_cosine`, `gamma_knn`) |
|
|
77
|
+
| `extract-modules` | post-processed modules, eigengenes, kME; at transcript level also gene coherence and the isoform-specific scan |
|
|
78
|
+
| `consensus-modules` | majority vote over seeds with a per-feature stability score |
|
|
79
|
+
| `isoform-specific` | isoforms whose expression tracks a module other than their gene's, optionally cross-fitted (`--folds`) |
|
|
80
|
+
| `isoform-residuals` | the gene-programme-removed residual matrix |
|
|
81
|
+
| `target-genes`, `target-genes-combine` | calibrated tests for candidate genes or GWAS loci, and pooling across cohorts |
|
|
82
|
+
| `module-quality` | kME, GMT enrichment, preservation in a second dataset |
|
|
83
|
+
| `regress-covariates` | remove batch and other known covariates before training |
|
|
84
|
+
| `export-latents`, `latent-analysis` | latent arrays, clustering and embeddings |
|
|
85
|
+
|
|
86
|
+
Flags worth knowing at transcript level: `--tx2gene`, `--covariates`, `--loo-eigengene {approx,exact,off}`, `--max-target-corr`, `--samples` / `--exclude-samples` (train fold models for cross-fitting), `--aggregate-to-gene`, and `--amp` on `bsvae-train` for mixed precision. See the [CLI reference](https://bsvae.readthedocs.io/en/latest/cli.html) for every flag and default.
|
|
87
|
+
|
|
88
|
+
## Quickstart
|
|
89
|
+
|
|
90
|
+
Train a small model:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
bsvae-train pilot_run \
|
|
94
|
+
--dataset data/expression.csv \
|
|
95
|
+
--epochs 50 \
|
|
96
|
+
--n-modules 12 \
|
|
97
|
+
--latent-dim 16
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Recommended production flow: train with a generous number of GMM components, about three times the number of modules you expect (at least 20), and let `extract-modules` merge components whose eigengenes correlate (see [Choosing K](https://bsvae.readthedocs.io/en/latest/hyperparameters.html#choosing-k)). `bsvae-sweep-k` is an optional check of that component count by held-out ELBO and, with `--stability-reps`, by seed stability; it retrains the selected model so the steps below can start from it.
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
bsvae-sweep-k sweep1 \
|
|
104
|
+
--dataset data/expression.csv \
|
|
105
|
+
--k-grid 8,12,16,24,32 \
|
|
106
|
+
--sweep-epochs 60 \
|
|
107
|
+
--stability-reps 5 \
|
|
108
|
+
--val-frac 0.1
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
This writes sweep outputs under `results/sweep1/sweep_k/` and retrains the selected model under `results/sweep1/final_k<K>/`.
|
|
112
|
+
|
|
113
|
+
Extract module assignments from the final model (post-processing adds a grey class, a minimum module size and eigengene merging):
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
bsvae-networks extract-modules \
|
|
117
|
+
--model-path results/sweep1/final_k16 \
|
|
118
|
+
--dataset data/expression.csv \
|
|
119
|
+
--output-dir results/sweep1/final_k16/modules \
|
|
120
|
+
--expr data/expression.csv \
|
|
121
|
+
--soft-eigengenes
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
With transcript-level data, pass `--tx2gene` as well. `extract-modules` then produces two independent outputs: module assignments annotated by the gene-coherence policy (default; `--no-gene-coherence` to disable) and the isoform-specific residual scan (`--no-isoform-calls` to skip, `--loo-eigengene` to change the leave-one-gene-out eigengene correction). A transcript's module label never decides whether it is tested. For calibrated calls, pass technical covariates (`--covariates`) and, where modules were learned on the same samples, cross-fit over sample folds (`isoform-specific --folds`).
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
bsvae-networks extract-modules \
|
|
128
|
+
--model-path results/iso1 \
|
|
129
|
+
--dataset data/transcripts.tsv.gz \
|
|
130
|
+
--output-dir results/iso1/modules \
|
|
131
|
+
--expr data/transcripts.tsv.gz \
|
|
132
|
+
--tx2gene data/tx2gene.tsv
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
This adds `modules_raw.csv`, `gene_coherence.csv` and `isoform_specific.csv` next to `modules.csv`; see the [CLI reference](docs/cli.md) for the columns.
|
|
136
|
+
|
|
137
|
+
Export latents:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
bsvae-networks export-latents \
|
|
141
|
+
--model-path results/sweep1/final_k16 \
|
|
142
|
+
--dataset data/expression.csv \
|
|
143
|
+
--output results/sweep1/final_k16/latents
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
This command writes `results/sweep1/final_k16/latents.npz` containing `mu`, `logvar`, `gamma`, and `feature_ids`.
|
|
147
|
+
|
|
148
|
+
Extract feature-feature networks:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
bsvae-networks extract-networks \
|
|
152
|
+
--model-path results/sweep1/final_k16 \
|
|
153
|
+
--dataset data/expression.csv \
|
|
154
|
+
--output-dir results/sweep1/final_k16/networks \
|
|
155
|
+
--methods mu_cosine gamma_knn \
|
|
156
|
+
--top-k 50
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Run latent-space analysis:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
bsvae-networks latent-analysis \
|
|
163
|
+
--model-path results/sweep1/final_k16 \
|
|
164
|
+
--dataset data/expression.csv \
|
|
165
|
+
--output-dir results/sweep1/final_k16/latent_analysis \
|
|
166
|
+
--kmeans-k 16 \
|
|
167
|
+
--umap
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Worked Example: Transcript-Level Workflow On Simulated Data
|
|
171
|
+
|
|
172
|
+
This end-to-end example uses the same simulator as the [benchmark study](https://github.com/heart-gen/bsvae-benchmarking), so every file below has a known truth to compare against. It runs in minutes on a CPU. The real-data version of the same chain (residualise, `bsvae-sweep-k`, `extract-modules`, `extract-networks`, `export-latents`) is in the [tutorial](https://bsvae.readthedocs.io/en/latest/tutorial.html).
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
# 1. simulate one transcript-level scenario (500 genes, 6 modules, 150 samples)
|
|
176
|
+
bsvae-simulate init-config --output iso.json --isoform # edit n_genes, n_modules, grid as needed
|
|
177
|
+
bsvae-simulate generate-grid --config iso.json --outdir sim --reps 1 --base-seed 13
|
|
178
|
+
SCEN=$(ls -d sim/scenarios/*/rep_000 | head -1)
|
|
179
|
+
|
|
180
|
+
# 2. choose K, then retrain the selected model (transcript-to-gene map enables the hierarchical loss)
|
|
181
|
+
bsvae-sweep-k iso1 --dataset $SCEN/expr/features_x_samples.tsv.gz \
|
|
182
|
+
--k-grid 12,18,24 --sweep-epochs 60 --stability-reps 2 --val-frac 0.1 \
|
|
183
|
+
--tx2gene $SCEN/truth/tx2gene.tsv --hier-strength 0.2 --isoform-stratified
|
|
184
|
+
|
|
185
|
+
# 3. two outputs: gene-coherent modules and the isoform-specific residual scan
|
|
186
|
+
bsvae-networks extract-modules --model-path results/iso1/final_k<K> \
|
|
187
|
+
--dataset $SCEN/expr/features_x_samples.tsv.gz --expr $SCEN/expr/features_x_samples.tsv.gz \
|
|
188
|
+
--tx2gene $SCEN/truth/tx2gene.tsv --covariates $SCEN/covariates.tsv.gz \
|
|
189
|
+
--loo-eigengene approx --max-target-corr 0.4 --soft-eigengenes \
|
|
190
|
+
--output-dir results/iso1/modules
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
`results/iso1/modules/` now holds `modules.csv` (gene-coherent assignments, grey is `-1`), `modules_raw.csv`, `gene_coherence.csv`, `isoform_specific.csv`, `eigengenes.csv`, `kME.csv` and `gamma.npz`. Score the modules against the simulator's truth:
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
import pandas as pd
|
|
197
|
+
from sklearn.metrics import adjusted_rand_score
|
|
198
|
+
|
|
199
|
+
pred = pd.read_csv("results/iso1/modules/modules.csv", index_col="feature_id")["module"]
|
|
200
|
+
truth = pd.read_csv(f"{scen}/truth/modules_hard.csv", index_col="feature_id")["module"]
|
|
201
|
+
print(adjusted_rand_score(truth.loc[pred.index], pred)) # grey (-1) counted as its own label
|
|
202
|
+
|
|
203
|
+
calls = pd.read_csv("results/iso1/modules/isoform_specific.csv")
|
|
204
|
+
sw = pd.read_csv(f"{scen}/truth/switch_table.tsv.gz", sep="\t", index_col=0)
|
|
205
|
+
print(calls["called"].sum(), "calls;", sw["is_switched"].sum(), "truly switched isoforms")
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
For calibrated calls when modules were learned on the same samples, train one fold model per sample split and cross-fit:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
bsvae-networks isoform-specific --dataset $SCEN/expr/features_x_samples.tsv.gz \
|
|
212
|
+
--tx2gene $SCEN/truth/tx2gene.tsv --covariates $SCEN/covariates.tsv.gz \
|
|
213
|
+
--modules fold0/modules/modules_raw.csv fold1/modules/modules_raw.csv --folds folds.tsv \
|
|
214
|
+
--max-target-corr 0.4 --output results/iso1/isoform_specific_crossfit.tsv
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Then test candidate genes against the same modules, and pool several cohorts:
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
bsvae-networks target-genes --dataset data/transcripts.tsv.gz --tx2gene data/tx2gene.tsv \
|
|
221
|
+
--modules results/iso1/modules/modules.csv --genes candidates.txt --output-dir results/iso1/targets
|
|
222
|
+
|
|
223
|
+
bsvae-networks target-genes-combine \
|
|
224
|
+
--inputs DLPFC=results/dlpfc/targets/target_isoforms.tsv HIPP=results/hipp/targets/target_isoforms.tsv \
|
|
225
|
+
--n-samples DLPFC=160 HIPP=150 --output results/targets_combined.tsv
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Training Outputs
|
|
229
|
+
|
|
230
|
+
`bsvae-train` writes to `results/<experiment>/` by default:
|
|
231
|
+
|
|
232
|
+
- `model.pt`
|
|
233
|
+
- `specs.json`
|
|
234
|
+
- `train_losses.csv`
|
|
235
|
+
- `model-<epoch>.pt` checkpoints when `--checkpoint-every` is greater than zero
|
|
236
|
+
|
|
237
|
+
`bsvae-sweep-k` writes:
|
|
238
|
+
|
|
239
|
+
- `results/<name>/sweep_k/sweep_results.csv`
|
|
240
|
+
- `results/<name>/sweep_k/sweep_summary.json`
|
|
241
|
+
- `results/<name>/sweep_k/k<K>/rep_<rep>/...` per-sweep run outputs
|
|
242
|
+
- `results/<name>/final_k<K>/...` for the final retrained model when `--train-final` is enabled
|
|
243
|
+
|
|
244
|
+
## Simulation and Benchmarking
|
|
245
|
+
|
|
246
|
+
Generate one synthetic dataset:
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
bsvae-simulate generate \
|
|
250
|
+
--output data/sim_expr.csv \
|
|
251
|
+
--save-ground-truth data/sim_truth.csv
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Generate a scenario grid:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
bsvae-simulate init-config --output sim.yaml
|
|
258
|
+
|
|
259
|
+
bsvae-simulate generate-grid \
|
|
260
|
+
--config sim.yaml \
|
|
261
|
+
--outdir results/sim_pub_v1 \
|
|
262
|
+
--reps 30 \
|
|
263
|
+
--base-seed 13
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Validate the generated grid:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
bsvae-simulate validate-grid --grid-dir results/sim_pub_v1
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Each scenario replicate writes method-ready files under `results/sim_pub_v1/scenarios/<scenario_id>/rep_<rep>/`, including:
|
|
273
|
+
|
|
274
|
+
- `expr/features_x_samples.tsv.gz`
|
|
275
|
+
- `expr/samples_x_features.tsv.gz`
|
|
276
|
+
- `truth/modules_hard.csv` (null features are `-1`)
|
|
277
|
+
- `truth/tx2gene.tsv` and `truth/modules_gene.csv` for the transcript-level family (`bsvae-simulate init-config --isoform`)
|
|
278
|
+
- `method_inputs.json`
|
|
279
|
+
|
|
280
|
+
Run BSVAE and WGCNA head-to-head on a grid and summarise grey-aware ARI/NMI, best-match Jaccard, and gene-level recovery:
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
bsvae-benchmark check-env # torch, Rscript, WGCNA
|
|
284
|
+
bsvae-benchmark run --config iso.json --outdir results/bench --methods bsvae,wgcna --seeds 0,1,2
|
|
285
|
+
bsvae-benchmark summarize --results results/bench/results.tsv --by scenario_id,method
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
`run` is resumable and can be split across a cluster with `--rep-ids` and `--scenario-ids`. Comparison methods are `bsvae_raw`, `bsvae_hier`, `bsvae_isoform`, `wgcna_raw`, `acorde`, `twn`, `usage_network`, `ica` and `nmf`. In the companion study (10 replicates, transcript-level scenarios, 150 samples), mean all-feature ARI was:
|
|
289
|
+
|
|
290
|
+
| Method | ARI (all features) | Unassigned |
|
|
291
|
+
| --- | --- | --- |
|
|
292
|
+
| `bsvae` (gene coherence) | 0.78 | 10% |
|
|
293
|
+
| `bsvae_raw` | 0.70 | 10% |
|
|
294
|
+
| `wgcna` (gene coherence) | 0.65 | 0.3% |
|
|
295
|
+
| `wgcna_raw` | 0.54 | 0.3% |
|
|
296
|
+
| `acorde` | 0.44 | 35% |
|
|
297
|
+
|
|
298
|
+
These are simulation results; see [Benchmarking](https://bsvae.readthedocs.io/en/latest/benchmarking.html) for the pipeline, output files, matched-coverage metrics and caveats, including that the residual-scan defaults were not validated in every simulated cell.
|
|
299
|
+
|
|
300
|
+
## Documentation
|
|
301
|
+
|
|
302
|
+
Full documentation is at [bsvae.readthedocs.io](https://bsvae.readthedocs.io/):
|
|
303
|
+
|
|
304
|
+
- [Installation](https://bsvae.readthedocs.io/en/latest/installation.html) and [Quick Start](https://bsvae.readthedocs.io/en/latest/quickstart.html)
|
|
305
|
+
- [Tutorial](https://bsvae.readthedocs.io/en/latest/tutorial.html) (real-data workflow and the simulated example)
|
|
306
|
+
- [CLI reference](https://bsvae.readthedocs.io/en/latest/cli.html), [network workflows](https://bsvae.readthedocs.io/en/latest/networks.html) and [hyperparameters](https://bsvae.readthedocs.io/en/latest/hyperparameters.html)
|
|
307
|
+
- [Benchmarking](https://bsvae.readthedocs.io/en/latest/benchmarking.html) and [HPC](https://bsvae.readthedocs.io/en/latest/hpc.html)
|
|
308
|
+
|
|
309
|
+
The same pages are in `docs/` in this repository. Release notes are in [CHANGELOG.md](CHANGELOG.md).
|
|
310
|
+
|
|
311
|
+
## License
|
|
312
|
+
|
|
313
|
+
This project is licensed under the [GNU General Public License v3.0](LICENSE).
|