antigen-model 0.1.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.
Files changed (37) hide show
  1. antigen_model-0.1.0/LICENSE +21 -0
  2. antigen_model-0.1.0/PKG-INFO +264 -0
  3. antigen_model-0.1.0/README.md +232 -0
  4. antigen_model-0.1.0/antiGen/__init__.py +1 -0
  5. antigen_model-0.1.0/antiGen/baselines/__init__.py +0 -0
  6. antigen_model-0.1.0/antiGen/baselines/covfit.py +259 -0
  7. antigen_model-0.1.0/antiGen/baselines/msa_transformer.py +428 -0
  8. antigen_model-0.1.0/antiGen/config.py +607 -0
  9. antigen_model-0.1.0/antiGen/configs/esm2_default.yaml +21 -0
  10. antigen_model-0.1.0/antiGen/configs/esm2_mutation_fitness.yaml +22 -0
  11. antigen_model-0.1.0/antiGen/configs/transformer_default.yaml +24 -0
  12. antigen_model-0.1.0/antiGen/datasets.py +86 -0
  13. antigen_model-0.1.0/antiGen/eval.py +760 -0
  14. antigen_model-0.1.0/antiGen/eval_utils.py +404 -0
  15. antigen_model-0.1.0/antiGen/infer.py +168 -0
  16. antigen_model-0.1.0/antiGen/load.py +175 -0
  17. antigen_model-0.1.0/antiGen/models/__init__.py +12 -0
  18. antigen_model-0.1.0/antiGen/models/base.py +84 -0
  19. antigen_model-0.1.0/antiGen/models/blosum62_fitness_predictor.py +78 -0
  20. antigen_model-0.1.0/antiGen/models/esm2_fitness_predictor.py +223 -0
  21. antigen_model-0.1.0/antiGen/models/evcouplings_fitness_predictor.py +310 -0
  22. antigen_model-0.1.0/antiGen/models/eve_fitness_predictor.py +439 -0
  23. antigen_model-0.1.0/antiGen/models/factory.py +230 -0
  24. antigen_model-0.1.0/antiGen/models/fitness_predictor.py +89 -0
  25. antigen_model-0.1.0/antiGen/models/gated_fitness_predictor.py +166 -0
  26. antigen_model-0.1.0/antiGen/models/pssm_fitness_predictor.py +69 -0
  27. antigen_model-0.1.0/antiGen/models/tranception_fitness_predictor.py +553 -0
  28. antigen_model-0.1.0/antiGen/train.py +561 -0
  29. antigen_model-0.1.0/antiGen/validate_examples.py +67 -0
  30. antigen_model-0.1.0/antigen_model.egg-info/PKG-INFO +264 -0
  31. antigen_model-0.1.0/antigen_model.egg-info/SOURCES.txt +35 -0
  32. antigen_model-0.1.0/antigen_model.egg-info/dependency_links.txt +1 -0
  33. antigen_model-0.1.0/antigen_model.egg-info/entry_points.txt +5 -0
  34. antigen_model-0.1.0/antigen_model.egg-info/requires.txt +17 -0
  35. antigen_model-0.1.0/antigen_model.egg-info/top_level.txt +1 -0
  36. antigen_model-0.1.0/pyproject.toml +63 -0
  37. antigen_model-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ivan Specht
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,264 @@
1
+ Metadata-Version: 2.4
2
+ Name: antigen-model
3
+ Version: 0.1.0
4
+ Summary: Train sequence models of viral fitness and score amino-acid substitutions for any query sequence.
5
+ Author: Ivan Specht
6
+ License: MIT
7
+ Project-URL: Repository, https://github.com/evo-design/antiGen
8
+ Project-URL: Issues, https://github.com/evo-design/antiGen/issues
9
+ Keywords: protein,fitness,viral evolution,transformer
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
14
+ Classifier: Operating System :: OS Independent
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: torch>=2.7
19
+ Requires-Dist: numpy
20
+ Requires-Dist: pandas
21
+ Requires-Dist: biopython
22
+ Requires-Dist: pyyaml
23
+ Provides-Extra: esm
24
+ Requires-Dist: transformers; extra == "esm"
25
+ Provides-Extra: dca
26
+ Requires-Dist: evcouplings; extra == "dca"
27
+ Provides-Extra: plot
28
+ Requires-Dist: matplotlib; extra == "plot"
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest; extra == "dev"
31
+ Dynamic: license-file
32
+
33
+ # antiGen
34
+
35
+ Welcome to antiGen, a model that predicts future mutations to viral proteins based on inferred phylogenetic trees. This repository is intended for (1) generating training data from phylogenetic trees, (2) training antiGen on said data, (3) querying substitution probabilities predicted by antiGen, (4) running the evaluations reported in the antiGen manuscript, and (5) reproducing the manuscript figures.
36
+
37
+ ## Install
38
+
39
+ Install the modeling package and its command-line tools from PyPI (Python ≥ 3.10):
40
+
41
+ ```bash
42
+ pip install antigen-model # core: from-scratch transformer + BLOSUM62 / PSSM / gated (no model downloads)
43
+ pip install "antigen-model[esm]" # + ESM-2 pretrained language model
44
+ pip install "antigen-model[dca]" # + EVcouplings (needs external `plmc`)
45
+ ```
46
+
47
+ The distribution is named `antigen-model`, but the import name and CLIs keep the
48
+ `antiGen` spelling (`import antiGen`; `antiGen-train`/`-infer`/`-eval`). This is
49
+ all you need to train antiGen and score substitutions (Parts 2–3). The
50
+ training-data generator (Part 1, C++/CUDA) and the figure-reproduction code
51
+ (Part 5, R) are not part of the wheel — clone the repo for those and, if you want
52
+ a source install of the package, `pip install` it from the clone:
53
+
54
+ ```bash
55
+ git clone git@github.com:evo-design/antiGen.git
56
+ cd antiGen
57
+ pip install ".[esm]" # editable/source install of the same package
58
+ ```
59
+
60
+ ## Quickstart (generate → train → infer, runs on CPU)
61
+
62
+ Runs the whole pipeline on a toy example: **generate** training data from a tiny
63
+ Nextstrain-format mutation-annotated tree and MSA using the included `antiGen-data` tool, then **train** a model and **score** substitutions.
64
+ No GPU is required for this example.
65
+
66
+ ```bash
67
+ # 1. build the data-generation tool (make auto-selects nvcc if present, else g++)
68
+ cd antiGen-data && make && cd ..
69
+
70
+ # 2. generate training data from the toy Nextstrain JSON + MSA (~ms; GPU if present, else CPU)
71
+ antiGen-data/antiGen-data antiGen-data/example/out 0.6 toy \
72
+ antiGen-data/example/ref.json antiGen-data/example/tree.json \
73
+ antiGen-data/example/metadata.tsv antiGen-data/example/seqs.fasta
74
+
75
+ # 3. (optional) sanity-check the generated examples file
76
+ antiGen-validate-examples antiGen-data/example/out/examples_cutoff_0.6.txt
77
+
78
+ # 4. train a small from-scratch transformer on it
79
+ antiGen-train --model-type transformer \
80
+ --examples antiGen-data/example/out/examples_cutoff_0.6.txt \
81
+ --d-model 32 --num-layers 1 --epochs 3 --batch-size 4 --output-dir ./checkpoints
82
+
83
+ # 5. score substitutions for the toy query sequences
84
+ antiGen-infer ./checkpoints/fitness_*.pt antiGen-data/example/seqs.fasta -o scores.csv
85
+ ```
86
+
87
+ ---
88
+
89
+ # 1. Generating training data
90
+
91
+ antiGen training data is produced by the included **[`antiGen-data/`](antiGen-data/)** tool, a
92
+ C++/CUDA application that grows a mutation-annotated phylogeny by parsimonious attachment and returns training/testing examples, as well as position-specific scoring matrices
93
+ (PSSMs) for the training window and at various cutoff times in the testing window. To build it, cd into the antiGen-data sub-directory and run `make` (needs a C++17 compiler; `nvcc` is optional, for GPU support).
94
+
95
+ Run it as:
96
+
97
+ ```bash
98
+ antiGen-data <output_dir> <cutoff> <dataset_type> <ref_json> <tree_json> <metadata_tsv> <alignment_files...> [max_seqs] [--cpu]
99
+ ```
100
+
101
+ - `output_dir` — where outputs are written (created if absent).
102
+ - `cutoff` — train/test split, in **years after the tree's root date**: examples dated before `root + cutoff` are labeled `TRAINING`, later ones `TESTING`.
103
+ - `dataset_type` — one of `sc2`, `h3n2`, `rsv_a`, `rsv_b`, `denv2`, or `toy`; selects the alphabet, segment layout, and evaluation region.
104
+ - `ref_json`, `tree_json`, `metadata_tsv` — the reference sequence, guide phylogeny, and per-strain dates (formats under **Input files** below).
105
+ - `alignment_files` — one or more MSA FASTAs of the sequences to attach, one per segment (1 for most datasets; 3 for H3N2 HA).
106
+ - `max_seqs` *(optional)* — cap on how many sequences to attach.
107
+ - `--cpu` *(optional)* — force the CPU path; a GPU is used automatically when present.
108
+
109
+ **Input files.** The three inputs follow the Nextstrain convention; see
110
+ [`antiGen-data/example/`](antiGen-data/example/) for a complete, runnable set.
111
+
112
+ - `ref_json` — root sequence per segment, e.g. `{"S": "MFVF…"}`.
113
+ - `tree_json` — a Nextstrain tree whose nodes carry `node_attrs.num_date.value` (decimal year) and `branch_attrs.mutations`, one list per segment of `<ref><pos><alt>` strings, 1-indexed (e.g. `"S": ["A222V", "D614G"]`).
114
+ - `metadata_tsv` — `strain`⇥`date` (ISO `YYYY-MM-DD`) for each sequence in the alignment(s).
115
+
116
+ Each run writes to `<output_dir>/`, formated as follows:
117
+
118
+ ```
119
+ output_<dataset>/
120
+ examples_cutoff_<value>.txt # training/testing examples (one entry per inferred ancestral genotype; see below)
121
+ pssms/root.csv # PSSM of all sequences in the training window
122
+ pssms/<variant>/time_*.csv # PSSM of all sequences in the testing window up through the cutoff time specified in the file name
123
+ ```
124
+
125
+ Each example within `examples_cutoff_*.txt` holds a sequence, its `TRAINING`/`TESTING` designation, whether it is the root example of or is descended from a supplied variant of interest, and the substitutions observed in that sequence's children (the training target).
126
+ `antiGen-validate-examples <file> [--variant V]` checks a file is well-formed (single consistent
127
+ sequence length, alphabet `ACDEFGHIKLMNPQRSTVWY*-`, in-range positions, ≥1 training example). The
128
+ Quickstart above generates a miniature example of this format from the toy inputs in
129
+ [`antiGen-data/example/`](antiGen-data/example/).
130
+
131
+ ---
132
+
133
+ # 2. Training antiGen
134
+
135
+ **Pointing antiGen at data.** Give an explicit file with `--examples <path>` (works for any
136
+ dataset with no code edits), or use a built-in dataset shortcut which resolves
137
+ `examples_cutoff_<cutoff>.txt` under `$FITNESS_DATA_ROOT` (or an explicit `--data-dir`). These
138
+ shortcuts only build a local path — the data is never downloaded, so you must have generated it
139
+ first (Part 1) and placed it under `$FITNESS_DATA_ROOT`:
140
+
141
+ | Flag | Dataset | Variant | `--cutoff` | Eval region |
142
+ |------|---------|---------|------------|-------------|
143
+ | *(default)* | SARS-CoV-2 spike | BA.2 (or `--variant`) | 1, 4, or 5 | RBD (330–530) |
144
+ | `--flu` | Influenza HA | J or K | 12 | full sequence |
145
+ | `--rsv-a` | RSV-A F | A.D.1.6 | 74 | full sequence |
146
+ | `--denv2` | Dengue 2 envelope | 2II_F.1.1.2_annotated | 191 | full sequence |
147
+
148
+ ```bash
149
+ # built-in dataset: resolve the file from $FITNESS_DATA_ROOT via a shortcut
150
+ export FITNESS_DATA_ROOT=/path/to/antiGen-data # holds output1/, output_flu_full_cutoff12/, ...
151
+ antiGen-train --flu --cutoff 12 --model-type transformer --output-dir ./checkpoints
152
+
153
+ # your own data: point --examples straight at a file you generated in Part 1
154
+ # (no $FITNESS_DATA_ROOT, no shortcut — works for any protein/pathogen). seq_len is read from
155
+ # the file (alphabet is the standard 22 AAs); add --variant <label> if it has a variant of interest.
156
+ antiGen-train --examples ./mydata/examples_cutoff_5.txt \
157
+ --model-type transformer --d-model 128 --num-layers 2 \
158
+ --epochs 64 --batch-size 64 --lr 1e-4 --output-dir ./checkpoints
159
+ ```
160
+
161
+ ## Model architectures (`--model-type`)
162
+
163
+ | Model | `--model-type` | Extra install | Description |
164
+ |-------|----------------|---------------|-------------|
165
+ | Transformer | `transformer` | — (core) | Small transformer trained from scratch. **Default; no downloads.** |
166
+ | ESM-2 | `esm2` | `.[esm]` | ESM-2 protein LM (default `esm2_t12_35M_UR50D`), frozen/partial/full finetune |
167
+ | BLOSUM62 | `blosum62` | — (core) | Static BLOSUM62 substitution matrix (no training, eval only) |
168
+ | PSSM | `pssm` | — (core) | Per-position `log(count+1)` from the root PSSM (no training, eval only) |
169
+ | Gated | `gated` | — (core) | Learnable per-position blend of two predictors (`--gate-partner-a/-b`, `--gate-variant`) |
170
+ | EVcouplings | `evcouplings` | `.[dca]` + `plmc` | Mean-field DCA Potts model fitted from a pandemic MSA (eval only) |
171
+ | EVE | `eve` | — (core) | EVE VAE (frozen or finetuned) trained on a pandemic MSA |
172
+ | Tranception | `tranception` | — (core) | Tranception autoregressive scorer (frozen or finetuned) |
173
+
174
+ For the pretrained ESM-2 backbone, three finetuning strategies: **frozen**
175
+ (`--freeze-backbone`, head only), **partial** (`--freeze-backbone --finetune-layers N`), and
176
+ **full** (no freeze flags). MSA models (`evcouplings`/`eve`/`tranception`) additionally need
177
+ `--msa` / `--metadata`; their date cutoff is derived from the dataset MRCA + `--cutoff` (or
178
+ `--date-cutoff`).
179
+
180
+ ```bash
181
+ # from-scratch transformer (the default)
182
+ antiGen-train --model-type transformer --d-model 128 --num-layers 2 \
183
+ --epochs 64 --batch-size 64 --lr 1e-4 --flu --output-dir ./checkpoints
184
+
185
+ # ESM-2, partial finetune of the last 4 layers
186
+ antiGen-train --model-type esm2 --freeze-backbone --finetune-layers 4 --lr 1e-4 --flu
187
+
188
+ # gated blend of a from-scratch transformer and the root PSSM
189
+ antiGen-train --model-type gated --gate-partner-a fitness_predictor --gate-partner-b pssm \
190
+ --gate-variant static --flu
191
+ ```
192
+
193
+ Checkpoints are written to `--output-dir` as `fitness_<run_prefix>.pt`, alongside a
194
+ `manifest.json` recording the full recipe. They are self-describing (they store the complete
195
+ `ModelConfig`), so `antiGen-infer` / `antiGen-eval` reload them standalone.
196
+
197
+ ---
198
+
199
+ # 3. Querying substitution probabilities
200
+
201
+ `antiGen-infer <checkpoint> <queries.fasta>` runs a forward pass on one or more query sequences
202
+ and writes the model's probability distribution over substitutions relative to each query.
203
+
204
+ ```bash
205
+ antiGen-infer ./checkpoints/fitness_*.pt my_queries.fasta -o scores.csv
206
+ ```
207
+
208
+ Default **long** output reports one row per candidate substitution:
209
+
210
+ ```
211
+ query_id,position,ref_aa,alt_aa,prob
212
+ toy_root,0,M,A,0.00148030
213
+ toy_root,0,M,C,0.00164760
214
+ ...
215
+ ```
216
+
217
+ `prob` is the inferred probability of each possible amino acid substitution relative to the
218
+ query (including premature stop codons `*` and gaps `-`, i.e. point indels). Use `--format wide`
219
+ for a position × amino-acid matrix, and `--drop-gap-stop` to exclude the `-`/`*` columns.
220
+
221
+ **Length / alignment.** antiGen operates on a **fixed, aligned coordinate frame**: provide
222
+ query sequences aligned to the training reference (same length and alignment).
223
+
224
+ ---
225
+
226
+ # 4. Running the manuscript evaluations
227
+
228
+ `antiGen-eval` scans a directory of checkpoints, groups them by model, and writes unified
229
+ per-variant comparison CSVs against a set of fixed baselines.
230
+
231
+ ```bash
232
+ antiGen-eval --dataset sc2 --data-dir $FITNESS_DATA_ROOT/output1 \
233
+ --checkpoint-dir ./checkpoints --output-dir ./evals_sc2
234
+ ```
235
+
236
+ It produces two metric families per variant: **quantile hit-rate** (how often observed mutations
237
+ fall in the model's top-q% predictions) and **variant-emergence** (across top-q quantiles
238
+ q = 0.1 … 1.0). These are termed next-mutation recall and PSSM precision in the paper, respectively. Baselines come from `data/baselines*/` plus two built from the root PSSM
239
+ (`pssm_root` and the position-only `pssm_root_position`). Ties at a top-q boundary are broken
240
+ **fractionally** (the expected value under random tie-breaking).
241
+
242
+ The SLURM scripts used for the manuscript runs are in [`examples/slurm/`](examples/slurm/); they
243
+ embed lab-specific paths/partitions and are meant to be copied and edited for your environment.
244
+
245
+ ---
246
+
247
+ # 5. Reproducing the paper figures
248
+
249
+ [`antiGen-figures/`](antiGen-figures/) is R code that plots the evaluation outputs into the
250
+ manuscript figures (it trains and evaluates nothing). From that directory, `Rscript run_all.R`
251
+ regenerates everything into `figs/` (PNG) and `figs_vector/` (PDF), or `Rscript figures/<script>.R`
252
+ runs a single figure; the inputs it reads live in `antiGen-figures/data/` and sibling directories.
253
+ Requires R with ggplot2, cowplot, reshape2, dplyr, tidyr, tibble, forcats, magick, ggtext,
254
+ jsonlite, and scales.
255
+
256
+ ---
257
+
258
+ ## Citing
259
+
260
+ See [CITATION.cff](CITATION.cff).
261
+
262
+ ## License
263
+
264
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,232 @@
1
+ # antiGen
2
+
3
+ Welcome to antiGen, a model that predicts future mutations to viral proteins based on inferred phylogenetic trees. This repository is intended for (1) generating training data from phylogenetic trees, (2) training antiGen on said data, (3) querying substitution probabilities predicted by antiGen, (4) running the evaluations reported in the antiGen manuscript, and (5) reproducing the manuscript figures.
4
+
5
+ ## Install
6
+
7
+ Install the modeling package and its command-line tools from PyPI (Python ≥ 3.10):
8
+
9
+ ```bash
10
+ pip install antigen-model # core: from-scratch transformer + BLOSUM62 / PSSM / gated (no model downloads)
11
+ pip install "antigen-model[esm]" # + ESM-2 pretrained language model
12
+ pip install "antigen-model[dca]" # + EVcouplings (needs external `plmc`)
13
+ ```
14
+
15
+ The distribution is named `antigen-model`, but the import name and CLIs keep the
16
+ `antiGen` spelling (`import antiGen`; `antiGen-train`/`-infer`/`-eval`). This is
17
+ all you need to train antiGen and score substitutions (Parts 2–3). The
18
+ training-data generator (Part 1, C++/CUDA) and the figure-reproduction code
19
+ (Part 5, R) are not part of the wheel — clone the repo for those and, if you want
20
+ a source install of the package, `pip install` it from the clone:
21
+
22
+ ```bash
23
+ git clone git@github.com:evo-design/antiGen.git
24
+ cd antiGen
25
+ pip install ".[esm]" # editable/source install of the same package
26
+ ```
27
+
28
+ ## Quickstart (generate → train → infer, runs on CPU)
29
+
30
+ Runs the whole pipeline on a toy example: **generate** training data from a tiny
31
+ Nextstrain-format mutation-annotated tree and MSA using the included `antiGen-data` tool, then **train** a model and **score** substitutions.
32
+ No GPU is required for this example.
33
+
34
+ ```bash
35
+ # 1. build the data-generation tool (make auto-selects nvcc if present, else g++)
36
+ cd antiGen-data && make && cd ..
37
+
38
+ # 2. generate training data from the toy Nextstrain JSON + MSA (~ms; GPU if present, else CPU)
39
+ antiGen-data/antiGen-data antiGen-data/example/out 0.6 toy \
40
+ antiGen-data/example/ref.json antiGen-data/example/tree.json \
41
+ antiGen-data/example/metadata.tsv antiGen-data/example/seqs.fasta
42
+
43
+ # 3. (optional) sanity-check the generated examples file
44
+ antiGen-validate-examples antiGen-data/example/out/examples_cutoff_0.6.txt
45
+
46
+ # 4. train a small from-scratch transformer on it
47
+ antiGen-train --model-type transformer \
48
+ --examples antiGen-data/example/out/examples_cutoff_0.6.txt \
49
+ --d-model 32 --num-layers 1 --epochs 3 --batch-size 4 --output-dir ./checkpoints
50
+
51
+ # 5. score substitutions for the toy query sequences
52
+ antiGen-infer ./checkpoints/fitness_*.pt antiGen-data/example/seqs.fasta -o scores.csv
53
+ ```
54
+
55
+ ---
56
+
57
+ # 1. Generating training data
58
+
59
+ antiGen training data is produced by the included **[`antiGen-data/`](antiGen-data/)** tool, a
60
+ C++/CUDA application that grows a mutation-annotated phylogeny by parsimonious attachment and returns training/testing examples, as well as position-specific scoring matrices
61
+ (PSSMs) for the training window and at various cutoff times in the testing window. To build it, cd into the antiGen-data sub-directory and run `make` (needs a C++17 compiler; `nvcc` is optional, for GPU support).
62
+
63
+ Run it as:
64
+
65
+ ```bash
66
+ antiGen-data <output_dir> <cutoff> <dataset_type> <ref_json> <tree_json> <metadata_tsv> <alignment_files...> [max_seqs] [--cpu]
67
+ ```
68
+
69
+ - `output_dir` — where outputs are written (created if absent).
70
+ - `cutoff` — train/test split, in **years after the tree's root date**: examples dated before `root + cutoff` are labeled `TRAINING`, later ones `TESTING`.
71
+ - `dataset_type` — one of `sc2`, `h3n2`, `rsv_a`, `rsv_b`, `denv2`, or `toy`; selects the alphabet, segment layout, and evaluation region.
72
+ - `ref_json`, `tree_json`, `metadata_tsv` — the reference sequence, guide phylogeny, and per-strain dates (formats under **Input files** below).
73
+ - `alignment_files` — one or more MSA FASTAs of the sequences to attach, one per segment (1 for most datasets; 3 for H3N2 HA).
74
+ - `max_seqs` *(optional)* — cap on how many sequences to attach.
75
+ - `--cpu` *(optional)* — force the CPU path; a GPU is used automatically when present.
76
+
77
+ **Input files.** The three inputs follow the Nextstrain convention; see
78
+ [`antiGen-data/example/`](antiGen-data/example/) for a complete, runnable set.
79
+
80
+ - `ref_json` — root sequence per segment, e.g. `{"S": "MFVF…"}`.
81
+ - `tree_json` — a Nextstrain tree whose nodes carry `node_attrs.num_date.value` (decimal year) and `branch_attrs.mutations`, one list per segment of `<ref><pos><alt>` strings, 1-indexed (e.g. `"S": ["A222V", "D614G"]`).
82
+ - `metadata_tsv` — `strain`⇥`date` (ISO `YYYY-MM-DD`) for each sequence in the alignment(s).
83
+
84
+ Each run writes to `<output_dir>/`, formated as follows:
85
+
86
+ ```
87
+ output_<dataset>/
88
+ examples_cutoff_<value>.txt # training/testing examples (one entry per inferred ancestral genotype; see below)
89
+ pssms/root.csv # PSSM of all sequences in the training window
90
+ pssms/<variant>/time_*.csv # PSSM of all sequences in the testing window up through the cutoff time specified in the file name
91
+ ```
92
+
93
+ Each example within `examples_cutoff_*.txt` holds a sequence, its `TRAINING`/`TESTING` designation, whether it is the root example of or is descended from a supplied variant of interest, and the substitutions observed in that sequence's children (the training target).
94
+ `antiGen-validate-examples <file> [--variant V]` checks a file is well-formed (single consistent
95
+ sequence length, alphabet `ACDEFGHIKLMNPQRSTVWY*-`, in-range positions, ≥1 training example). The
96
+ Quickstart above generates a miniature example of this format from the toy inputs in
97
+ [`antiGen-data/example/`](antiGen-data/example/).
98
+
99
+ ---
100
+
101
+ # 2. Training antiGen
102
+
103
+ **Pointing antiGen at data.** Give an explicit file with `--examples <path>` (works for any
104
+ dataset with no code edits), or use a built-in dataset shortcut which resolves
105
+ `examples_cutoff_<cutoff>.txt` under `$FITNESS_DATA_ROOT` (or an explicit `--data-dir`). These
106
+ shortcuts only build a local path — the data is never downloaded, so you must have generated it
107
+ first (Part 1) and placed it under `$FITNESS_DATA_ROOT`:
108
+
109
+ | Flag | Dataset | Variant | `--cutoff` | Eval region |
110
+ |------|---------|---------|------------|-------------|
111
+ | *(default)* | SARS-CoV-2 spike | BA.2 (or `--variant`) | 1, 4, or 5 | RBD (330–530) |
112
+ | `--flu` | Influenza HA | J or K | 12 | full sequence |
113
+ | `--rsv-a` | RSV-A F | A.D.1.6 | 74 | full sequence |
114
+ | `--denv2` | Dengue 2 envelope | 2II_F.1.1.2_annotated | 191 | full sequence |
115
+
116
+ ```bash
117
+ # built-in dataset: resolve the file from $FITNESS_DATA_ROOT via a shortcut
118
+ export FITNESS_DATA_ROOT=/path/to/antiGen-data # holds output1/, output_flu_full_cutoff12/, ...
119
+ antiGen-train --flu --cutoff 12 --model-type transformer --output-dir ./checkpoints
120
+
121
+ # your own data: point --examples straight at a file you generated in Part 1
122
+ # (no $FITNESS_DATA_ROOT, no shortcut — works for any protein/pathogen). seq_len is read from
123
+ # the file (alphabet is the standard 22 AAs); add --variant <label> if it has a variant of interest.
124
+ antiGen-train --examples ./mydata/examples_cutoff_5.txt \
125
+ --model-type transformer --d-model 128 --num-layers 2 \
126
+ --epochs 64 --batch-size 64 --lr 1e-4 --output-dir ./checkpoints
127
+ ```
128
+
129
+ ## Model architectures (`--model-type`)
130
+
131
+ | Model | `--model-type` | Extra install | Description |
132
+ |-------|----------------|---------------|-------------|
133
+ | Transformer | `transformer` | — (core) | Small transformer trained from scratch. **Default; no downloads.** |
134
+ | ESM-2 | `esm2` | `.[esm]` | ESM-2 protein LM (default `esm2_t12_35M_UR50D`), frozen/partial/full finetune |
135
+ | BLOSUM62 | `blosum62` | — (core) | Static BLOSUM62 substitution matrix (no training, eval only) |
136
+ | PSSM | `pssm` | — (core) | Per-position `log(count+1)` from the root PSSM (no training, eval only) |
137
+ | Gated | `gated` | — (core) | Learnable per-position blend of two predictors (`--gate-partner-a/-b`, `--gate-variant`) |
138
+ | EVcouplings | `evcouplings` | `.[dca]` + `plmc` | Mean-field DCA Potts model fitted from a pandemic MSA (eval only) |
139
+ | EVE | `eve` | — (core) | EVE VAE (frozen or finetuned) trained on a pandemic MSA |
140
+ | Tranception | `tranception` | — (core) | Tranception autoregressive scorer (frozen or finetuned) |
141
+
142
+ For the pretrained ESM-2 backbone, three finetuning strategies: **frozen**
143
+ (`--freeze-backbone`, head only), **partial** (`--freeze-backbone --finetune-layers N`), and
144
+ **full** (no freeze flags). MSA models (`evcouplings`/`eve`/`tranception`) additionally need
145
+ `--msa` / `--metadata`; their date cutoff is derived from the dataset MRCA + `--cutoff` (or
146
+ `--date-cutoff`).
147
+
148
+ ```bash
149
+ # from-scratch transformer (the default)
150
+ antiGen-train --model-type transformer --d-model 128 --num-layers 2 \
151
+ --epochs 64 --batch-size 64 --lr 1e-4 --flu --output-dir ./checkpoints
152
+
153
+ # ESM-2, partial finetune of the last 4 layers
154
+ antiGen-train --model-type esm2 --freeze-backbone --finetune-layers 4 --lr 1e-4 --flu
155
+
156
+ # gated blend of a from-scratch transformer and the root PSSM
157
+ antiGen-train --model-type gated --gate-partner-a fitness_predictor --gate-partner-b pssm \
158
+ --gate-variant static --flu
159
+ ```
160
+
161
+ Checkpoints are written to `--output-dir` as `fitness_<run_prefix>.pt`, alongside a
162
+ `manifest.json` recording the full recipe. They are self-describing (they store the complete
163
+ `ModelConfig`), so `antiGen-infer` / `antiGen-eval` reload them standalone.
164
+
165
+ ---
166
+
167
+ # 3. Querying substitution probabilities
168
+
169
+ `antiGen-infer <checkpoint> <queries.fasta>` runs a forward pass on one or more query sequences
170
+ and writes the model's probability distribution over substitutions relative to each query.
171
+
172
+ ```bash
173
+ antiGen-infer ./checkpoints/fitness_*.pt my_queries.fasta -o scores.csv
174
+ ```
175
+
176
+ Default **long** output reports one row per candidate substitution:
177
+
178
+ ```
179
+ query_id,position,ref_aa,alt_aa,prob
180
+ toy_root,0,M,A,0.00148030
181
+ toy_root,0,M,C,0.00164760
182
+ ...
183
+ ```
184
+
185
+ `prob` is the inferred probability of each possible amino acid substitution relative to the
186
+ query (including premature stop codons `*` and gaps `-`, i.e. point indels). Use `--format wide`
187
+ for a position × amino-acid matrix, and `--drop-gap-stop` to exclude the `-`/`*` columns.
188
+
189
+ **Length / alignment.** antiGen operates on a **fixed, aligned coordinate frame**: provide
190
+ query sequences aligned to the training reference (same length and alignment).
191
+
192
+ ---
193
+
194
+ # 4. Running the manuscript evaluations
195
+
196
+ `antiGen-eval` scans a directory of checkpoints, groups them by model, and writes unified
197
+ per-variant comparison CSVs against a set of fixed baselines.
198
+
199
+ ```bash
200
+ antiGen-eval --dataset sc2 --data-dir $FITNESS_DATA_ROOT/output1 \
201
+ --checkpoint-dir ./checkpoints --output-dir ./evals_sc2
202
+ ```
203
+
204
+ It produces two metric families per variant: **quantile hit-rate** (how often observed mutations
205
+ fall in the model's top-q% predictions) and **variant-emergence** (across top-q quantiles
206
+ q = 0.1 … 1.0). These are termed next-mutation recall and PSSM precision in the paper, respectively. Baselines come from `data/baselines*/` plus two built from the root PSSM
207
+ (`pssm_root` and the position-only `pssm_root_position`). Ties at a top-q boundary are broken
208
+ **fractionally** (the expected value under random tie-breaking).
209
+
210
+ The SLURM scripts used for the manuscript runs are in [`examples/slurm/`](examples/slurm/); they
211
+ embed lab-specific paths/partitions and are meant to be copied and edited for your environment.
212
+
213
+ ---
214
+
215
+ # 5. Reproducing the paper figures
216
+
217
+ [`antiGen-figures/`](antiGen-figures/) is R code that plots the evaluation outputs into the
218
+ manuscript figures (it trains and evaluates nothing). From that directory, `Rscript run_all.R`
219
+ regenerates everything into `figs/` (PNG) and `figs_vector/` (PDF), or `Rscript figures/<script>.R`
220
+ runs a single figure; the inputs it reads live in `antiGen-figures/data/` and sibling directories.
221
+ Requires R with ggplot2, cowplot, reshape2, dplyr, tidyr, tibble, forcats, magick, ggtext,
222
+ jsonlite, and scales.
223
+
224
+ ---
225
+
226
+ ## Citing
227
+
228
+ See [CITATION.cff](CITATION.cff).
229
+
230
+ ## License
231
+
232
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1 @@
1
+ """antiGen: viral fitness prediction — train models and score substitutions."""
File without changes