arc-pie 0.1.6__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.
- arc_pie-0.1.6/.github/workflows/release.yml +42 -0
- arc_pie-0.1.6/.gitignore +23 -0
- arc_pie-0.1.6/.python-version +1 -0
- arc_pie-0.1.6/AGENTS.md +211 -0
- arc_pie-0.1.6/LICENSE.md +429 -0
- arc_pie-0.1.6/PKG-INFO +174 -0
- arc_pie-0.1.6/README.md +131 -0
- arc_pie-0.1.6/common.sh.example +10 -0
- arc_pie-0.1.6/pyproject.toml +103 -0
- arc_pie-0.1.6/src/pie/__init__.py +8 -0
- arc_pie-0.1.6/src/pie/assets.py +301 -0
- arc_pie-0.1.6/src/pie/cli.py +229 -0
- arc_pie-0.1.6/src/pie/config.py +267 -0
- arc_pie-0.1.6/src/pie/configs/eval.yaml +14 -0
- arc_pie-0.1.6/src/pie/configs/experiment/replogle_wdataset.yaml +40 -0
- arc_pie-0.1.6/src/pie/configs/experiment/replogle_xdataset.yaml +48 -0
- arc_pie-0.1.6/src/pie/configs/infer.yaml +14 -0
- arc_pie-0.1.6/src/pie/configs/prep/dataset/arc_vcc_25.yaml +14 -0
- arc_pie-0.1.6/src/pie/configs/prep/dataset/jiang.yaml +7 -0
- arc_pie-0.1.6/src/pie/configs/prep/dataset/orion.yaml +7 -0
- arc_pie-0.1.6/src/pie/configs/prep/dataset/replogle.yaml +12 -0
- arc_pie-0.1.6/src/pie/configs/prep/dataset/tahoe.yaml +10 -0
- arc_pie-0.1.6/src/pie/configs/prep/label_format/pie_process.yaml +10 -0
- arc_pie-0.1.6/src/pie/configs/prep/label_format/table.yaml +10 -0
- arc_pie-0.1.6/src/pie/configs/prep.yaml +39 -0
- arc_pie-0.1.6/src/pie/configs/process/dataset/arc_vcc_25.yaml +13 -0
- arc_pie-0.1.6/src/pie/configs/process/dataset/jiang.yaml +12 -0
- arc_pie-0.1.6/src/pie/configs/process/dataset/orion.yaml +11 -0
- arc_pie-0.1.6/src/pie/configs/process/dataset/replogle.yaml +9 -0
- arc_pie-0.1.6/src/pie/configs/process/dataset/tahoe.yaml +8 -0
- arc_pie-0.1.6/src/pie/configs/process.yaml +37 -0
- arc_pie-0.1.6/src/pie/configs/sources.yaml +25 -0
- arc_pie-0.1.6/src/pie/configs/train.yaml +80 -0
- arc_pie-0.1.6/src/pie/data/__init__.py +0 -0
- arc_pie-0.1.6/src/pie/data/datamodule.py +474 -0
- arc_pie-0.1.6/src/pie/data/dataset.py +269 -0
- arc_pie-0.1.6/src/pie/data/delta_p.py +119 -0
- arc_pie-0.1.6/src/pie/data/evidence.py +1057 -0
- arc_pie-0.1.6/src/pie/data/preprocessed.py +298 -0
- arc_pie-0.1.6/src/pie/data/samplers.py +170 -0
- arc_pie-0.1.6/src/pie/data/splits.py +126 -0
- arc_pie-0.1.6/src/pie/evaluate.py +124 -0
- arc_pie-0.1.6/src/pie/infer.py +33 -0
- arc_pie-0.1.6/src/pie/metrics.py +439 -0
- arc_pie-0.1.6/src/pie/model/__init__.py +17 -0
- arc_pie-0.1.6/src/pie/model/evidence.py +86 -0
- arc_pie-0.1.6/src/pie/model/heads.py +36 -0
- arc_pie-0.1.6/src/pie/model/layers.py +52 -0
- arc_pie-0.1.6/src/pie/model/losses.py +151 -0
- arc_pie-0.1.6/src/pie/model/pie.py +304 -0
- arc_pie-0.1.6/src/pie/model/trunk.py +103 -0
- arc_pie-0.1.6/src/pie/predict.py +311 -0
- arc_pie-0.1.6/src/pie/prep/__init__.py +0 -0
- arc_pie-0.1.6/src/pie/prep/config.py +83 -0
- arc_pie-0.1.6/src/pie/prep/labels.py +738 -0
- arc_pie-0.1.6/src/pie/process/__init__.py +0 -0
- arc_pie-0.1.6/src/pie/process/config.py +88 -0
- arc_pie-0.1.6/src/pie/process/de.py +148 -0
- arc_pie-0.1.6/src/pie/process/io.py +113 -0
- arc_pie-0.1.6/src/pie/process/knockdown.py +290 -0
- arc_pie-0.1.6/src/pie/process/normalize.py +174 -0
- arc_pie-0.1.6/src/pie/process/run.py +76 -0
- arc_pie-0.1.6/src/pie/sources/__init__.py +0 -0
- arc_pie-0.1.6/src/pie/sources/chem_profiles.py +483 -0
- arc_pie-0.1.6/src/pie/sources/common.py +146 -0
- arc_pie-0.1.6/src/pie/sources/config.py +76 -0
- arc_pie-0.1.6/src/pie/sources/contract.py +323 -0
- arc_pie-0.1.6/src/pie/sources/curated_aliases.yaml +38 -0
- arc_pie-0.1.6/src/pie/sources/depmap.py +91 -0
- arc_pie-0.1.6/src/pie/sources/embed/__init__.py +0 -0
- arc_pie-0.1.6/src/pie/sources/embed/chemberta.py +152 -0
- arc_pie-0.1.6/src/pie/sources/embed/esm2.py +140 -0
- arc_pie-0.1.6/src/pie/sources/embed/openai.py +120 -0
- arc_pie-0.1.6/src/pie/sources/embed/qwen.py +135 -0
- arc_pie-0.1.6/src/pie/sources/registry.py +248 -0
- arc_pie-0.1.6/src/pie/sources/string.py +101 -0
- arc_pie-0.1.6/src/pie/sources/text/__init__.py +0 -0
- arc_pie-0.1.6/src/pie/sources/text/_http.py +67 -0
- arc_pie-0.1.6/src/pie/sources/text/context_file.py +50 -0
- arc_pie-0.1.6/src/pie/sources/text/contexts.py +650 -0
- arc_pie-0.1.6/src/pie/sources/text/drugs.py +541 -0
- arc_pie-0.1.6/src/pie/sources/text/genes.py +586 -0
- arc_pie-0.1.6/src/pie/sources/text/ncbi.py +510 -0
- arc_pie-0.1.6/src/pie/sources/text/tools.py +243 -0
- arc_pie-0.1.6/src/pie/sources/uniprot.py +140 -0
- arc_pie-0.1.6/src/pie/sources/verify.py +160 -0
- arc_pie-0.1.6/src/pie/train.py +506 -0
- arc_pie-0.1.6/src/pie/utils.py +333 -0
- arc_pie-0.1.6/tests/__init__.py +0 -0
- arc_pie-0.1.6/tests/conftest.py +40 -0
- arc_pie-0.1.6/tests/data/__init__.py +0 -0
- arc_pie-0.1.6/tests/data/test_datamodule.py +330 -0
- arc_pie-0.1.6/tests/data/test_dataset.py +193 -0
- arc_pie-0.1.6/tests/data/test_delta_p.py +165 -0
- arc_pie-0.1.6/tests/data/test_evidence.py +247 -0
- arc_pie-0.1.6/tests/data/test_preprocessed.py +230 -0
- arc_pie-0.1.6/tests/data/test_samplers.py +277 -0
- arc_pie-0.1.6/tests/data/test_splits.py +194 -0
- arc_pie-0.1.6/tests/fixtures/metrics/de_metrics_oracle.json +1 -0
- arc_pie-0.1.6/tests/fixtures/metrics/l1_parity.json +1 -0
- arc_pie-0.1.6/tests/fixtures.py +346 -0
- arc_pie-0.1.6/tests/model/__init__.py +0 -0
- arc_pie-0.1.6/tests/model/helpers.py +132 -0
- arc_pie-0.1.6/tests/model/test_evidence.py +83 -0
- arc_pie-0.1.6/tests/model/test_heads.py +59 -0
- arc_pie-0.1.6/tests/model/test_layers.py +78 -0
- arc_pie-0.1.6/tests/model/test_losses.py +193 -0
- arc_pie-0.1.6/tests/model/test_pie.py +285 -0
- arc_pie-0.1.6/tests/model/test_trunk.py +79 -0
- arc_pie-0.1.6/tests/pipeline.py +106 -0
- arc_pie-0.1.6/tests/prep/__init__.py +0 -0
- arc_pie-0.1.6/tests/prep/test_config.py +144 -0
- arc_pie-0.1.6/tests/prep/test_labels.py +634 -0
- arc_pie-0.1.6/tests/process/__init__.py +0 -0
- arc_pie-0.1.6/tests/process/conftest.py +64 -0
- arc_pie-0.1.6/tests/process/helpers.py +102 -0
- arc_pie-0.1.6/tests/process/test_cli.py +84 -0
- arc_pie-0.1.6/tests/process/test_config.py +202 -0
- arc_pie-0.1.6/tests/process/test_de.py +198 -0
- arc_pie-0.1.6/tests/process/test_io.py +110 -0
- arc_pie-0.1.6/tests/process/test_knockdown.py +216 -0
- arc_pie-0.1.6/tests/process/test_normalize.py +190 -0
- arc_pie-0.1.6/tests/process/test_run.py +147 -0
- arc_pie-0.1.6/tests/sources/embed/test_chemberta.py +63 -0
- arc_pie-0.1.6/tests/sources/embed/test_esm2.py +132 -0
- arc_pie-0.1.6/tests/sources/embed/test_openai.py +134 -0
- arc_pie-0.1.6/tests/sources/embed/test_qwen.py +91 -0
- arc_pie-0.1.6/tests/sources/helpers.py +15 -0
- arc_pie-0.1.6/tests/sources/inputs.py +430 -0
- arc_pie-0.1.6/tests/sources/test_chem_profiles.py +141 -0
- arc_pie-0.1.6/tests/sources/test_cli.py +114 -0
- arc_pie-0.1.6/tests/sources/test_common.py +116 -0
- arc_pie-0.1.6/tests/sources/test_config.py +46 -0
- arc_pie-0.1.6/tests/sources/test_contract.py +458 -0
- arc_pie-0.1.6/tests/sources/test_depmap.py +27 -0
- arc_pie-0.1.6/tests/sources/test_registry.py +361 -0
- arc_pie-0.1.6/tests/sources/test_registry_tools.py +209 -0
- arc_pie-0.1.6/tests/sources/test_string.py +35 -0
- arc_pie-0.1.6/tests/sources/test_uniprot.py +72 -0
- arc_pie-0.1.6/tests/sources/test_verify.py +152 -0
- arc_pie-0.1.6/tests/sources/text/fakes.py +56 -0
- arc_pie-0.1.6/tests/sources/text/fixtures/cellosaurus/56.0/CVCL_0186.json +1 -0
- arc_pie-0.1.6/tests/sources/text/fixtures/cellosaurus/56.0/CVCL_9771.json +1 -0
- arc_pie-0.1.6/tests/sources/text/fixtures/cellosaurus/56.0/CVCL_Y001.json +1 -0
- arc_pie-0.1.6/tests/sources/text/fixtures/cellosaurus/56.0/CVCL_Y002.json +1 -0
- arc_pie-0.1.6/tests/sources/text/fixtures/cellosaurus/56.0/CVCL_Y003.json +1 -0
- arc_pie-0.1.6/tests/sources/text/fixtures/cellosaurus/release-info.json +1 -0
- arc_pie-0.1.6/tests/sources/text/test_contexts.py +380 -0
- arc_pie-0.1.6/tests/sources/text/test_drugs.py +268 -0
- arc_pie-0.1.6/tests/sources/text/test_genes.py +393 -0
- arc_pie-0.1.6/tests/sources/text/test_http.py +87 -0
- arc_pie-0.1.6/tests/sources/text/test_ncbi.py +258 -0
- arc_pie-0.1.6/tests/test_assets.py +425 -0
- arc_pie-0.1.6/tests/test_cli.py +135 -0
- arc_pie-0.1.6/tests/test_config.py +668 -0
- arc_pie-0.1.6/tests/test_evaluate.py +188 -0
- arc_pie-0.1.6/tests/test_infer.py +84 -0
- arc_pie-0.1.6/tests/test_metrics.py +576 -0
- arc_pie-0.1.6/tests/test_package.py +36 -0
- arc_pie-0.1.6/tests/test_predict.py +199 -0
- arc_pie-0.1.6/tests/test_train.py +492 -0
- arc_pie-0.1.6/tests/test_utils.py +434 -0
- arc_pie-0.1.6/uv.lock +1957 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
- uses: astral-sh/setup-uv@v6
|
|
13
|
+
- name: Check that the tag matches the package version
|
|
14
|
+
run: |
|
|
15
|
+
version=$(python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
|
|
16
|
+
test "v$version" = "$GITHUB_REF_NAME"
|
|
17
|
+
- run: uv build
|
|
18
|
+
- name: Smoke-test the wheel outside the source tree
|
|
19
|
+
run: |
|
|
20
|
+
uv venv /tmp/smoke --python 3.12
|
|
21
|
+
uv pip install --python /tmp/smoke/bin/python dist/*.whl
|
|
22
|
+
cd /tmp
|
|
23
|
+
/tmp/smoke/bin/pie --version
|
|
24
|
+
/tmp/smoke/bin/pie train --help
|
|
25
|
+
/tmp/smoke/bin/pie eval --help
|
|
26
|
+
- uses: actions/upload-artifact@v4
|
|
27
|
+
with:
|
|
28
|
+
name: dist
|
|
29
|
+
path: dist/
|
|
30
|
+
|
|
31
|
+
pypi:
|
|
32
|
+
needs: build
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
environment: pypi
|
|
35
|
+
permissions:
|
|
36
|
+
id-token: write
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/download-artifact@v4
|
|
39
|
+
with:
|
|
40
|
+
name: dist
|
|
41
|
+
path: dist/
|
|
42
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
arc_pie-0.1.6/.gitignore
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Local environment
|
|
2
|
+
common.sh
|
|
3
|
+
.venv/
|
|
4
|
+
|
|
5
|
+
# Python
|
|
6
|
+
__pycache__/
|
|
7
|
+
*.py[oc]
|
|
8
|
+
build/
|
|
9
|
+
dist/
|
|
10
|
+
*.egg-info/
|
|
11
|
+
|
|
12
|
+
# Tool caches
|
|
13
|
+
.pytest_cache/
|
|
14
|
+
.ruff_cache/
|
|
15
|
+
.mypy_cache/
|
|
16
|
+
|
|
17
|
+
# Training and evaluation outputs
|
|
18
|
+
*.ckpt
|
|
19
|
+
wandb/
|
|
20
|
+
lightning_logs/
|
|
21
|
+
outputs/
|
|
22
|
+
multirun/
|
|
23
|
+
.hydra/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
arc_pie-0.1.6/AGENTS.md
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# PIE
|
|
2
|
+
|
|
3
|
+
PIE predicts how a perturbation changes gene expression in a cell context. For each (context,
|
|
4
|
+
perturbation) pair and every measured gene it outputs the probability of differential expression
|
|
5
|
+
(`p_de`), the log2 fold change (`lfc_pred`) and the expression-level shift (`delta_p_pred`), from
|
|
6
|
+
knowledge-source embeddings of the perturbation, context and genes plus pooled training evidence.
|
|
7
|
+
|
|
8
|
+
## Repository map
|
|
9
|
+
|
|
10
|
+
- `src/pie/configs/`: Hydra configs shipped in the package, one per command (`process.yaml`, `prep.yaml`, `sources.yaml`, `train.yaml`,
|
|
11
|
+
`eval.yaml`, `infer.yaml`), overlays in `process/dataset/`, `prep/dataset/`, `prep/label_format/`
|
|
12
|
+
and `experiment/` (the two canonical experiments).
|
|
13
|
+
- `src/pie/cli.py`: the `pie <command>` entry point (`process`, `prep`, `sources`, `train`, `eval`,
|
|
14
|
+
`infer`); the old `pie-<command>` scripts remain as deprecated aliases.
|
|
15
|
+
- On HF, not in the repo: split files in `arcinstitute/PIE_splits`
|
|
16
|
+
(`{"<dataset>.<context>": [perturbation, ...]}`), each dataset's context map in
|
|
17
|
+
`preprocessed/contexts.yaml` (context to Cellosaurus accession, Jiang stimulations) and
|
|
18
|
+
per-source perturbation aliases in `PIE_sources/<name>/aliases.yaml` (used only when a key is
|
|
19
|
+
missing). `src/pie/sources/curated_aliases.yaml` is the reviewed table: `pie sources` writes
|
|
20
|
+
each source's entries into its output dir, and runs saved before aliases moved read it.
|
|
21
|
+
- `src/pie/config.py`: strict schema of train/eval/infer (unknown keys are errors); `utils.py`:
|
|
22
|
+
`common.sh` loading, env checks, config composition, logging, determinism, hashing, atomic writes.
|
|
23
|
+
- `src/pie/assets.py`: local/HF asset resolver, revision pinning, selective downloads,
|
|
24
|
+
repository locks and completion manifests under `PIE_DATA_ROOT/hf/`.
|
|
25
|
+
- `src/pie/process/`: raw count h5ads to log1p expression h5ads and per-context DE parquets.
|
|
26
|
+
- `src/pie/prep/`: labels and expression h5ads to a preprocessed dir (`config.py` is its schema).
|
|
27
|
+
- `src/pie/sources/`: source format (`contract.py`), tool registry (`registry.py`), config schema
|
|
28
|
+
(`config.py`), text renderers (`text/`), embedders (`embed/`) and the UniProt, STRING, DepMap and
|
|
29
|
+
chemical-profile builders.
|
|
30
|
+
- `src/pie/data/`: preprocessed reader, splits, delta-p grid, evidence cache, samplers, datamodule.
|
|
31
|
+
- `src/pie/model/`: `PieModel` (Perceiver trunk, evidence module, heads) and the losses.
|
|
32
|
+
- `src/pie/metrics.py` (the scorer for validation and evaluation), `train.py` (Lightning module,
|
|
33
|
+
trainer, checkpoints), `predict.py` (shared by `evaluate.py` and `infer.py`).
|
|
34
|
+
- `tests/`: mirrors `src/pie/`.
|
|
35
|
+
|
|
36
|
+
## Setup
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
uv sync --frozen # runtime and dev tools
|
|
40
|
+
uv sync --frozen --extra sources # also the source-building tools
|
|
41
|
+
uv sync --frozen --extra process # also the dataset-processing DE stage
|
|
42
|
+
cp common.sh.example common.sh # then fill it in; common.sh is gitignored
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`common.sh` sets `WANDB_ENTITY`, `WANDB_PROJECT`, `PIE_DATA_ROOT`, `PIE_RUNS_ROOT`, `PIE_CACHE_DIR`
|
|
46
|
+
and, optionally, `NCBI_API_KEY` and `NCBI_EMAIL`. Values are literal (no `$VAR` or `~` expansion, no
|
|
47
|
+
inline comments). Every command loads the first of `$PIE_ENV_FILE`, `./common.sh` and
|
|
48
|
+
`~/.config/pie/common.sh`; variables already set in the environment win,
|
|
49
|
+
and a CLI stops at once when a variable it needs is missing. The text-embedding steps also need
|
|
50
|
+
`OPENAI_API_KEY`: export it in your own environment, never in `common.sh`.
|
|
51
|
+
|
|
52
|
+
## CLI tools
|
|
53
|
+
|
|
54
|
+
Every command takes Hydra-style `key=value` overrides on its config in `src/pie/configs/`
|
|
55
|
+
(`pie process` → `process.yaml`, `pie prep` → `prep.yaml`, `pie sources` → `sources.yaml`,
|
|
56
|
+
`pie train` → `train.yaml`, `pie eval` → `eval.yaml`, `pie infer` → `infer.yaml`); `pie` lists the
|
|
57
|
+
commands and `pie <command> --help` prints the usage. Overlays are
|
|
58
|
+
picked with `dataset=<name>`, `label_format=<name>` or `experiment=<name>`, unknown keys are errors,
|
|
59
|
+
relative paths are relative to the current directory, and an existing output is an error unless you pass
|
|
60
|
+
`overwrite=true`.
|
|
61
|
+
|
|
62
|
+
Preprocessed dataset inputs (`data.preprocessed_dirs` in train; `preprocessed_dirs` in
|
|
63
|
+
eval/infer/sources) and model source inputs (`data.source_dirs`, `data.gene_text_dir`) accept
|
|
64
|
+
local paths or `hf://datasets/<owner>/<repo>[@revision]/<directory>` references. Bare repo IDs
|
|
65
|
+
are local paths; use the explicit URI for HF. The canonical experiment overlays pin full HF
|
|
66
|
+
commits for every dataset and source, including gene text. Dataset repos use `preprocessed/`;
|
|
67
|
+
`arcinstitute/PIE_sources` uses one directory per source name.
|
|
68
|
+
|
|
69
|
+
HF assets download only the selected directory to
|
|
70
|
+
`$PIE_DATA_ROOT/hf/datasets/<owner>/<repo>/<commit>/<directory>/`; download metadata, locks,
|
|
71
|
+
revision records, completion manifests and the Xet transfer cache also stay under this root.
|
|
72
|
+
Do not resolve HF references through `resolve_path` or turn them into `Path` before resolution:
|
|
73
|
+
use `resolve_asset(value, kind="preprocessed"|"source")`. Config composition and checkpoint
|
|
74
|
+
loading must stay free of network/download side effects. Training pins remote references before
|
|
75
|
+
saving config/checkpoints; resume replays the previous run's commits. An unpinned revision resolves
|
|
76
|
+
once per data root; use a new explicit commit for an update. Fully downloaded assets need no
|
|
77
|
+
network. `HF_HUB_OFFLINE=1` refuses missing/incomplete assets. Authenticate when needed with
|
|
78
|
+
`uv run hf auth login` or `HF_TOKEN` in the environment; never store tokens in configs/common.sh.
|
|
79
|
+
|
|
80
|
+
`pie process` turns raw count h5ads into the log1p expression h5ads and per-context DE parquets
|
|
81
|
+
that `pie prep` consumes: `dataset=<name>` selects a per-dataset overlay enabling the stages it
|
|
82
|
+
needs among `filter` (on-target knockdown removal), `normalize` (CP10k plus natural log1p) and `de`
|
|
83
|
+
(needs a GPU and the `process` extra).
|
|
84
|
+
|
|
85
|
+
`pie prep` builds one preprocessed dir per dataset from DE label tables and expression h5ads: give
|
|
86
|
+
`labels` (glob), `h5ad` (glob) and `output_dir`. `dataset=<name>` sets the h5ad obs columns (`obs.*`)
|
|
87
|
+
and the label rewrites; `label_format=table` (default) reads PIE label tables and
|
|
88
|
+
`label_format=pie_process` reads `pie process` DE parquets. `obs.pert_id_col` records each
|
|
89
|
+
perturbation's Ensembl id in `meta.json` (Replogle: `gene_id`), which `pie sources` uses. A label
|
|
90
|
+
context without h5ad or control cells is an error; `genes=<file>` fixes the gene axis;
|
|
91
|
+
`controls_only=true` writes only the gene axis, vocab and control means (inference on new
|
|
92
|
+
contexts). Without `genes` the derived axis can differ from a canonical one (Tahoe: 17845 vs. 18151
|
|
93
|
+
genes), so reproducing a canonical dir needs the gene list shipped with it. `contexts=<file>`
|
|
94
|
+
copies a context map into the dir as `contexts.yaml`; `pie sources` needs it for `context_text`.
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
uv run pie prep dataset=replogle label_format=pie_process \
|
|
98
|
+
labels="$PIE_DATA_ROOT/replogle/de/*.parquet" \
|
|
99
|
+
h5ad="$PIE_DATA_ROOT/replogle/expression/*.h5ad" \
|
|
100
|
+
output_dir="$PIE_DATA_ROOT/replogle/preprocessed"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`pie sources` builds knowledge sources into `<output_root>/<name>/` for the datasets in
|
|
104
|
+
`preprocessed_dirs`. `tools=[...]` adds and orders dependencies (`with_deps=false` builds only the
|
|
105
|
+
named tools); builder settings live under `options.*`; `mode=verify` reports per-dataset coverage
|
|
106
|
+
and, with `verify.reference=<dir>`, the difference to published sources. `prior_root` extends
|
|
107
|
+
earlier text sources instead of re-embedding them. `depmap_gene_effect` needs a manual download
|
|
108
|
+
(`options.depmap_csv`), the chemical sources need `options.drug_metadata`, and `ncbi_text` and
|
|
109
|
+
`esm2` need a GPU (`options.device`, default `cuda`). Context text reads
|
|
110
|
+
`<preprocessed dir>/contexts.yaml`; aliases come from `<source dir>/aliases.yaml`, plus an optional
|
|
111
|
+
multi-source file that you pass in the config (`verify.aliases`, `data.aliases_path`), loaded as
|
|
112
|
+
given.
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
uv run pie sources \
|
|
116
|
+
"tools=[esm2,ncbi_text,string_space,depmap_gene_effect,context_text,perturbation_text,gene_text]" \
|
|
117
|
+
"preprocessed_dirs=[$PIE_DATA_ROOT/replogle/preprocessed]" \
|
|
118
|
+
options.depmap_csv=CRISPRGeneEffect.csv output_root="$PIE_DATA_ROOT/sources"
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`pie train` trains from `train.yaml` plus Hydra overrides (for example
|
|
122
|
+
`experiment=replogle_wdataset vars.fold=k562`). At setup it fits the delta-p grid on the training
|
|
123
|
+
rows, loads or builds the evidence cache and writes `data_stats.json`. A non-empty run dir is an
|
|
124
|
+
error unless you pass `resume=true` (continue from `last.ckpt`) or `overwrite=true`; resume keeps
|
|
125
|
+
the run's saved data paths (datasets, sources, splits) and logs any requested path it ignores.
|
|
126
|
+
`data.split_dir=<dir>` (local or `hf://`, holding `train.json` and `val.json`) trains on your own
|
|
127
|
+
splits. `logger.enabled=false` trains without wandb.
|
|
128
|
+
|
|
129
|
+
`pie eval` scores a checkpoint on a split file and writes `<run_dir>/eval/<row_set>/metrics_<ckpt>.csv`
|
|
130
|
+
(one row per context plus an `all` row) and `granular_<ckpt>.csv` (one row per pair);
|
|
131
|
+
`save_predictions=true` also writes the predictions.
|
|
132
|
+
|
|
133
|
+
`pie infer` predicts without labels and writes one parquet row per pair (`p_de`, `lfc_pred`,
|
|
134
|
+
`delta_p_pred`; the gene axis is in the file metadata). For new contexts, build a
|
|
135
|
+
`controls_only=true` dir with `pie prep` and pass a query file in split format.
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
uv run pie infer experiment_name=replogle_wdataset/k562 ckpt=best_auprc \
|
|
139
|
+
rows_kind=query rows_path=query.json \
|
|
140
|
+
"preprocessed_dirs=[$PIE_DATA_ROOT/my_screen/preprocessed]" output_path=predictions.parquet
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## End-to-end flow
|
|
144
|
+
|
|
145
|
+
raw count h5ads → `pie process` (optional: knockdown filter, log1p normalize, DE) → labels + h5ad
|
|
146
|
+
→ `pie prep` → `pie sources tools=[…]` → `pie train` (grid and evidence built at setup)
|
|
147
|
+
→ `pie eval` / `pie infer`.
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
$PIE_DATA_ROOT/<dataset>/counts/ count h5ads (knockdown-filtered when pie process filters)
|
|
151
|
+
$PIE_DATA_ROOT/<dataset>/expression/ log1p expression h5ads
|
|
152
|
+
$PIE_DATA_ROOT/<dataset>/de/ per-context DE parquets
|
|
153
|
+
$PIE_DATA_ROOT/<dataset>/preprocessed/ meta.json and the .npy arrays
|
|
154
|
+
$PIE_DATA_ROOT/sources/<name>/ meta.json, embeddings.npy [offsets.npy, descriptions.json]
|
|
155
|
+
$PIE_RUNS_ROOT/<experiment_name>/ config.yaml, data_stats.json, best_auprc.ckpt, last.ckpt,
|
|
156
|
+
eval/<row_set>/
|
|
157
|
+
$PIE_CACHE_DIR/evidence/<key>/ evidence, keyed by the data, train split and settings
|
|
158
|
+
$PIE_CACHE_DIR/http/, embed/ downloads and resumable embedding progress
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Experiments
|
|
162
|
+
|
|
163
|
+
Evaluate `best_auprc.ckpt` (maximum `val/binary_auprc`) on every test set.
|
|
164
|
+
Both recipes fetch their pinned preprocessed datasets and knowledge sources automatically at
|
|
165
|
+
runtime; `uv sync --frozen` is sufficient to use them. For distributed runs, a shared
|
|
166
|
+
`PIE_DATA_ROOT` lets repository locks coordinate downloads across ranks and nodes. With local
|
|
167
|
+
data roots, each node downloads its own assets. Run directories must still use shared storage.
|
|
168
|
+
|
|
169
|
+
**replogle_wdataset**: Replogle only, four folds (hepg2, jurkat, k562, rpe1). A fold trains and
|
|
170
|
+
validates on the other three cell lines and is tested in three settings: `unseen_ctx` (held-out
|
|
171
|
+
line, seen perturbations), `unseen_pert` (seen lines, unseen perturbations) and `unseen_ctx_pert`.
|
|
172
|
+
Hardware: 2 GPUs per fold (H100 80GB: about 1.2 h and 20 GiB per GPU); eval on 1 GPU.
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
SPLITS=hf://datasets/arcinstitute/PIE_splits@396ab9563175ee887750c9eed7ccaea6f5fdbf50
|
|
176
|
+
for fold in hepg2 jurkat k562 rpe1; do
|
|
177
|
+
uv run pie train experiment=replogle_wdataset vars.fold=$fold
|
|
178
|
+
for setting in unseen_ctx unseen_pert unseen_ctx_pert; do
|
|
179
|
+
uv run pie eval experiment_name=replogle_wdataset/$fold ckpt=best_auprc \
|
|
180
|
+
split_path=$SPLITS/replogle_wdataset/$setting/$fold/test.json row_set=$setting
|
|
181
|
+
done
|
|
182
|
+
done
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**replogle_xdataset**: trains on Tahoe, Jiang, ARC VCC 25 and Orion (weights 0.68, 0.01, 0.01, 0.3)
|
|
186
|
+
and is tested zero-shot on Replogle, which stays in the config with weight 0 to fix the gene axis.
|
|
187
|
+
`test_seen` holds the pairs whose perturbation is in `train.json`, `test_unseen` the rest; the
|
|
188
|
+
per-context rows of each metrics file are the per-cell-line results. Hardware: 2 nodes × 4 GPUs
|
|
189
|
+
(H100 80GB: about 4.5 h, peak 78.5 GiB per GPU, about 46 GiB host RAM per rank), a run dir on
|
|
190
|
+
shared storage; eval on 1 GPU. Run `torchrun` on each node with its rank and one fresh `RDZV_ID`
|
|
191
|
+
shared by both nodes:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
SPLITS=hf://datasets/arcinstitute/PIE_splits@396ab9563175ee887750c9eed7ccaea6f5fdbf50
|
|
195
|
+
uv run torchrun --nnodes=2 --nproc-per-node=4 --node-rank=<0|1> \
|
|
196
|
+
--master-addr=<node-0 host> --master-port=29500 --rdzv-id="$RDZV_ID" \
|
|
197
|
+
--no-python pie train experiment=replogle_xdataset
|
|
198
|
+
for rows in test_seen test_unseen; do
|
|
199
|
+
uv run pie eval experiment_name=replogle_xdataset ckpt=best_auprc \
|
|
200
|
+
split_path=$SPLITS/replogle_xdataset/$rows.json row_set=$rows
|
|
201
|
+
done
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Conventions
|
|
205
|
+
|
|
206
|
+
- `tests/` mirrors `src/pie/`; tests run on CPU with synthetic fixtures: `uv run pytest -q`.
|
|
207
|
+
- Lint with `uv run ruff check .` (100 columns); type-check with `uv run mypy src`.
|
|
208
|
+
- Direct dependencies use version ranges in `pyproject.toml` (lower bound = the tested version);
|
|
209
|
+
`uv.lock` holds the exact versions and is committed (`uv lock`).
|
|
210
|
+
- Configs are strict: each value lives once in YAML, and a new key needs a schema field.
|
|
211
|
+
- Never commit machine-specific paths, `common.sh`, API keys or other secrets.
|