shellde 0.2.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.
- shellde-0.2.0/PKG-INFO +285 -0
- shellde-0.2.0/README.md +254 -0
- shellde-0.2.0/pyproject.toml +51 -0
- shellde-0.2.0/setup.cfg +4 -0
- shellde-0.2.0/src/shellde/__init__.py +36 -0
- shellde-0.2.0/src/shellde/acquisition.py +135 -0
- shellde-0.2.0/src/shellde/advisor.py +158 -0
- shellde-0.2.0/src/shellde/bench/__init__.py +17 -0
- shellde-0.2.0/src/shellde/bench/falsification.py +95 -0
- shellde-0.2.0/src/shellde/bench/harness.py +134 -0
- shellde-0.2.0/src/shellde/bench/stats.py +46 -0
- shellde-0.2.0/src/shellde/campaign.py +257 -0
- shellde-0.2.0/src/shellde/candidates.py +341 -0
- shellde-0.2.0/src/shellde/cli.py +1517 -0
- shellde-0.2.0/src/shellde/colab.py +257 -0
- shellde-0.2.0/src/shellde/conformal.py +160 -0
- shellde-0.2.0/src/shellde/consensus.py +52 -0
- shellde-0.2.0/src/shellde/design_space.py +141 -0
- shellde-0.2.0/src/shellde/embeddings/__init__.py +6 -0
- shellde-0.2.0/src/shellde/embeddings/esm2.py +76 -0
- shellde-0.2.0/src/shellde/embeddings/esmc.py +94 -0
- shellde-0.2.0/src/shellde/embeddings/provider.py +105 -0
- shellde-0.2.0/src/shellde/features/__init__.py +22 -0
- shellde-0.2.0/src/shellde/features/base.py +49 -0
- shellde-0.2.0/src/shellde/features/defaults.py +11 -0
- shellde-0.2.0/src/shellde/features/embedding.py +80 -0
- shellde-0.2.0/src/shellde/features/inverse_folding.py +66 -0
- shellde-0.2.0/src/shellde/features/matrix.py +50 -0
- shellde-0.2.0/src/shellde/features/naturalness.py +65 -0
- shellde-0.2.0/src/shellde/features/onehot.py +55 -0
- shellde-0.2.0/src/shellde/features/pairwise.py +64 -0
- shellde-0.2.0/src/shellde/funclib.py +331 -0
- shellde-0.2.0/src/shellde/gating.py +181 -0
- shellde-0.2.0/src/shellde/holo.py +175 -0
- shellde-0.2.0/src/shellde/hotspots.py +108 -0
- shellde-0.2.0/src/shellde/loop.py +161 -0
- shellde-0.2.0/src/shellde/msa.py +186 -0
- shellde-0.2.0/src/shellde/naturalness.py +142 -0
- shellde-0.2.0/src/shellde/oracle.py +94 -0
- shellde-0.2.0/src/shellde/plm.py +145 -0
- shellde-0.2.0/src/shellde/prereg.py +41 -0
- shellde-0.2.0/src/shellde/protocols.py +87 -0
- shellde-0.2.0/src/shellde/rank.py +103 -0
- shellde-0.2.0/src/shellde/report.py +132 -0
- shellde-0.2.0/src/shellde/selector.py +63 -0
- shellde-0.2.0/src/shellde/sitefinder.py +465 -0
- shellde-0.2.0/src/shellde/structure.py +356 -0
- shellde-0.2.0/src/shellde/surrogate.py +323 -0
- shellde-0.2.0/src/shellde/types.py +66 -0
- shellde-0.2.0/src/shellde/zero_shot.py +160 -0
- shellde-0.2.0/src/shellde.egg-info/PKG-INFO +285 -0
- shellde-0.2.0/src/shellde.egg-info/SOURCES.txt +87 -0
- shellde-0.2.0/src/shellde.egg-info/dependency_links.txt +1 -0
- shellde-0.2.0/src/shellde.egg-info/entry_points.txt +2 -0
- shellde-0.2.0/src/shellde.egg-info/requires.txt +17 -0
- shellde-0.2.0/src/shellde.egg-info/top_level.txt +1 -0
- shellde-0.2.0/tests/test_acquisition.py +77 -0
- shellde-0.2.0/tests/test_advisor.py +184 -0
- shellde-0.2.0/tests/test_anchor.py +58 -0
- shellde-0.2.0/tests/test_bench.py +51 -0
- shellde-0.2.0/tests/test_campaign.py +215 -0
- shellde-0.2.0/tests/test_candidates.py +83 -0
- shellde-0.2.0/tests/test_cli.py +326 -0
- shellde-0.2.0/tests/test_colab.py +133 -0
- shellde-0.2.0/tests/test_conformal.py +199 -0
- shellde-0.2.0/tests/test_consensus.py +33 -0
- shellde-0.2.0/tests/test_defaults.py +21 -0
- shellde-0.2.0/tests/test_design_space.py +56 -0
- shellde-0.2.0/tests/test_embeddings.py +149 -0
- shellde-0.2.0/tests/test_encode_fast.py +82 -0
- shellde-0.2.0/tests/test_falsification.py +58 -0
- shellde-0.2.0/tests/test_features.py +54 -0
- shellde-0.2.0/tests/test_funclib.py +285 -0
- shellde-0.2.0/tests/test_gating.py +161 -0
- shellde-0.2.0/tests/test_heldout.py +37 -0
- shellde-0.2.0/tests/test_holo.py +143 -0
- shellde-0.2.0/tests/test_hotspots.py +59 -0
- shellde-0.2.0/tests/test_msa.py +54 -0
- shellde-0.2.0/tests/test_naturalness.py +139 -0
- shellde-0.2.0/tests/test_oracle_loop.py +57 -0
- shellde-0.2.0/tests/test_pairwise.py +50 -0
- shellde-0.2.0/tests/test_plm.py +176 -0
- shellde-0.2.0/tests/test_prereg.py +20 -0
- shellde-0.2.0/tests/test_rank_report.py +120 -0
- shellde-0.2.0/tests/test_selector.py +43 -0
- shellde-0.2.0/tests/test_sitefinder.py +145 -0
- shellde-0.2.0/tests/test_structure.py +245 -0
- shellde-0.2.0/tests/test_surrogate.py +172 -0
- shellde-0.2.0/tests/test_zero_shot.py +100 -0
shellde-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: shellde
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Low-N, acquisition-driven protein mutation campaign planner: additive default, opt-in signals, honest abstention
|
|
5
|
+
Author: gyuminlee-repo
|
|
6
|
+
Keywords: directed-evolution,protein-engineering,active-learning,bayesian-optimization,epistasis,mutation-recommendation,uncertainty-calibration,active-site
|
|
7
|
+
Classifier: Development Status :: 4 - Beta
|
|
8
|
+
Classifier: Intended Audience :: Science/Research
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
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
|
+
Requires-Dist: numpy
|
|
18
|
+
Requires-Dist: scipy
|
|
19
|
+
Requires-Dist: scikit-learn
|
|
20
|
+
Requires-Dist: pandas
|
|
21
|
+
Provides-Extra: plm
|
|
22
|
+
Requires-Dist: torch; extra == "plm"
|
|
23
|
+
Requires-Dist: esm; extra == "plm"
|
|
24
|
+
Provides-Extra: plm2
|
|
25
|
+
Requires-Dist: fair-esm; extra == "plm2"
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest; extra == "dev"
|
|
28
|
+
Requires-Dist: pyright; extra == "dev"
|
|
29
|
+
Requires-Dist: build; extra == "dev"
|
|
30
|
+
Requires-Dist: twine; extra == "dev"
|
|
31
|
+
|
|
32
|
+
# ShellDE
|
|
33
|
+
|
|
34
|
+
Low-N, acquisition-driven protein mutation recommendation. The spine is one measurement campaign:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
R0 seed to measure -> fit surrogate on all measured data -> acquire next plate -> measure -> repeat
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
ShellDE is not a magic zero-shot "better protein" predictor. Zero-shot, MSA, inverse-folding,
|
|
41
|
+
structure, and ddG signals are used as priors, constraints, or features. The function-aligned signal
|
|
42
|
+
is still measurement. The tool's job is to spend a small measurement budget better.
|
|
43
|
+
|
|
44
|
+
> **Naming.** `ShellDE` in prose, `shellde` as the PyPI distribution, the import, and the command. Never
|
|
45
|
+
> `Shellde`, `shellDE`, or `SHELLDE`.
|
|
46
|
+
>
|
|
47
|
+
> **Renamed.** This project was `epiquire` through v0.1.46.00 and is `shellde` from v0.2.00.00. The name
|
|
48
|
+
> is the active-site contact SHELL that `resolve-site` computes (and the 2nd-shell ring that
|
|
49
|
+
> `--exclude-catalytic` designs over), plus DE for directed evolution.
|
|
50
|
+
>
|
|
51
|
+
> **PyPI status (checked 2026-08-28).** `shellde` is NOT on PyPI: the PyPI JSON API returns 404 for it.
|
|
52
|
+
> `epiquire` IS on PyPI at 0.1.21, and that wheel still installs the OLD pre-rename package, unchanged,
|
|
53
|
+
> which is why a pinned Colab install naming it keeps working. No deprecation shim exists, in this tree
|
|
54
|
+
> or on PyPI. Publishing `shellde`, and only then turning `epiquire` into a shim that points at it, are
|
|
55
|
+
> PLANNED owner actions tracked in `docs/RENAME_PLAN.md`, not things already done.
|
|
56
|
+
|
|
57
|
+
## Install
|
|
58
|
+
|
|
59
|
+
`shellde` is not on PyPI yet, so install it from a source checkout of this repository. Run this from
|
|
60
|
+
the repository root, the directory holding `pyproject.toml`:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install . # core deps: numpy/scipy/scikit-learn/pandas
|
|
64
|
+
pip install ".[plm]" # optional: adds torch + ESM-C (PLM re-rank / naturalness)
|
|
65
|
+
pip install -e . # editable, when working on the code itself
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Verified 2026-08-28 in a throwaway venv: `pip install .` builds `shellde-0.2.0` and the installed
|
|
69
|
+
`shellde` console script renders `usage: shellde`.
|
|
70
|
+
|
|
71
|
+
The short PyPI form stays here because it becomes the recommended path once the distribution is
|
|
72
|
+
published. It returns a 404 today, so do not run it yet:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pip install shellde # ONLY AFTER shellde is published to PyPI (not yet; 404 today)
|
|
76
|
+
pip install "shellde[plm]" # ONLY AFTER shellde is published to PyPI (not yet; 404 today)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Or run it in your browser with **no install** via the Colab notebook below.
|
|
80
|
+
|
|
81
|
+
## Easiest entry point: `shellde round`
|
|
82
|
+
|
|
83
|
+
One command per round. It auto-resolves the active-site design region (the `resolve-site` evidence
|
|
84
|
+
ladder: UniProt -> linked PDB cocrystal -> AlphaFold) and then runs the campaign round, so there is
|
|
85
|
+
no position bookkeeping by hand.
|
|
86
|
+
|
|
87
|
+
**Run it in your browser, no install:** open the notebook in Google Colab via its public gist (works
|
|
88
|
+
without repo access): [open in Colab](https://colab.research.google.com/gist/gyuminlee-repo/1a7a0b5dbf3919d652a6ba2dbdb3f49a/epiquire_round_colab.ipynb).
|
|
89
|
+
The notebook is a 3-line bootstrap over a `plate(...)` call: all logic lives in the pip package, so the
|
|
90
|
+
notebook file never needs re-uploading. That link opens the PRE-RENAME notebook. The published gist
|
|
91
|
+
still installs `epiquire` and imports `epiquire.colab.plate`, and that is exactly why it still runs
|
|
92
|
+
today. `notebooks/COLAB_GIST.md` records the resync order, which waits on the
|
|
93
|
+
PyPI publish.
|
|
94
|
+
|
|
95
|
+
Once `shellde` is published and the gist is resynced, any notebook can skip the form and call it
|
|
96
|
+
directly with the three lines below. They do not work yet, because the first one 404s:
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
%pip install -q -U shellde
|
|
100
|
+
from shellde.colab import plate
|
|
101
|
+
df = plate("...WT sequence...", uniprot="Q50L36", auto_msa=True) # R0 seed plate, MSA built for you
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The core loop is numpy/scikit-learn (seconds); only the optional PLM path is heavy (Colab's free GPU).
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# R0: no --measured -> the funclib seed plate to MEASURE. The seed needs a tolerance signal;
|
|
108
|
+
# supply --msa/--ddg/--if-logprobs, OR --auto-msa to build the MSA from the WT (ColabFold MMseqs2).
|
|
109
|
+
shellde round WT.fasta --uniprot Q50L36 --auto-msa --plate 95 --outdir outputs/round
|
|
110
|
+
|
|
111
|
+
# Rk: add each round's measured results -> the next AL plate over the full saturation universe
|
|
112
|
+
shellde round WT.fasta --uniprot Q50L36 --measured round0_measured.csv --plate 95 --outdir outputs/round
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Point at the design region with whatever you have: `--uniprot ACC` (or `--uniprot auto` to find the accession by
|
|
116
|
+
an EXACT match of your WT sequence against UniProt), `--query`/`--pdb` (auto ladder), a local
|
|
117
|
+
`--holo` structure, or explicit `--positions`. Give more than one and the most-specific wins,
|
|
118
|
+
resolved by a fixed priority `positions > holo > pdb+uniprot > pdb > uniprot/query` -- so you can just
|
|
119
|
+
pass whatever you have. Two special combinations: giving **both** `--pdb` and `--uniprot` designs over
|
|
120
|
+
the PDB contact shell while flagging (QC) the UniProt catalytic core that falls inside it, and adding
|
|
121
|
+
`--exclude-catalytic` then designs only the tunable 2nd-shell ring (shell minus the usually-lethal
|
|
122
|
+
catalytic core). If the ladder cannot map evidence onto your WT it abstains (supply `--positions` or
|
|
123
|
+
`--holo`) rather than guessing. `round` is a thin wrapper: `resolve-site` and `campaign` below remain
|
|
124
|
+
the explicit, fully-configurable commands it calls.
|
|
125
|
+
No cocrystal at all? `--find-holo` (on `round`/`resolve-site`) Foldseek-searches for a ligand-bound
|
|
126
|
+
(holo) structural homolog of your WT and, if a SIGNIFICANT one exists (E-value + coverage gated), uses
|
|
127
|
+
its ligand pose to define the shell; it abstains when only distant homologs are found so a mismatched
|
|
128
|
+
pocket is never silently borrowed. When several evidence types are available (e.g. `--pdb` + `--uniprot`)
|
|
129
|
+
ShellDE prints an evidence-consensus map: each position tagged with which independent lines support it
|
|
130
|
+
and a confidence tier (high = >=2 agree), so you can measure high-confidence positions first.
|
|
131
|
+
|
|
132
|
+
## The campaign engine (what `round` calls)
|
|
133
|
+
|
|
134
|
+
Use `campaign` when starting an active-site campaign. It combines the two validated pieces:
|
|
135
|
+
|
|
136
|
+
1. **R0 cold-start seed**: FuncLib-style active-site library construction. This proposes variants to
|
|
137
|
+
measure; it does not predict winners.
|
|
138
|
+
2. **R1+ active learning**: after measurements arrive, the AL loop searches the full saturation space
|
|
139
|
+
of the design positions, not just the R0 seed.
|
|
140
|
+
|
|
141
|
+
### R0: generate the seed plate
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
shellde campaign WT.fasta \
|
|
145
|
+
--holo holo_structure.pdb --ligand-resnames LIG \
|
|
146
|
+
--msa alignment.a3m \
|
|
147
|
+
--plate 95 \
|
|
148
|
+
--outdir outputs/campaign
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
This writes `outputs/campaign/round0_plate.csv` with `variant,mutations,n_mut,seed_score`. Measure
|
|
152
|
+
those variants and save a `variant,fitness` CSV.
|
|
153
|
+
|
|
154
|
+
You can use explicit design positions instead of a holo structure:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
shellde campaign WT.fasta \
|
|
158
|
+
--positions 183,184,227,228 \
|
|
159
|
+
--msa alignment.a3m \
|
|
160
|
+
--plate 95 \
|
|
161
|
+
--outdir outputs/campaign
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### R1+: propose the next plate from measured data
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
shellde campaign WT.fasta \
|
|
168
|
+
--positions 183,184,227,228 \
|
|
169
|
+
--measured round0_measured.csv \
|
|
170
|
+
--plate 95 \
|
|
171
|
+
--outdir outputs/campaign
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
With multiple rounds, pass all accumulated CSVs:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
shellde campaign WT.fasta \
|
|
178
|
+
--positions 183,184,227,228 \
|
|
179
|
+
--measured round0_measured.csv round1_measured.csv \
|
|
180
|
+
--plate 95 \
|
|
181
|
+
--outdir outputs/campaign
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
On later rounds, add `--plm esmc` to rerank the plate with an ESM-C surrogate refit on YOUR measured
|
|
185
|
+
data (EVOLVEpro-style; opt-in, GPU-recommended). Every Rk round also auto-prints an `advise` line --
|
|
186
|
+
held-out Spearman + a recommendation (`gather_more` / `model_reliable` / `open_epistasis`) -- so you
|
|
187
|
+
know each round whether to trust the surrogate or keep measuring broadly.
|
|
188
|
+
|
|
189
|
+
### Simulate against a complete landscape
|
|
190
|
+
|
|
191
|
+
For validation or retrospective benchmarks:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
shellde campaign WT.fasta \
|
|
195
|
+
--simulate data/trpb.csv \
|
|
196
|
+
--positions 183,184,227,228 \
|
|
197
|
+
--msa isps_run/msa_trpb.a3m \
|
|
198
|
+
--strategies funclib singles random \
|
|
199
|
+
--plate 95 --rounds 3 --seeds 20 --jobs 4 \
|
|
200
|
+
--model-class ridge \
|
|
201
|
+
--outdir artifacts/campaign_trpb
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
`--jobs` parallelizes independent seeds with spawn processes; serial output and parallel output are
|
|
205
|
+
byte-identical by test.
|
|
206
|
+
|
|
207
|
+
## Other commands
|
|
208
|
+
|
|
209
|
+
- `shellde recommend measured.csv`: rank next candidates from accumulated measurements. This is the
|
|
210
|
+
AL round engine exposed directly. If you pass `--if-logprobs`, ShellDE CV-gates that signal by
|
|
211
|
+
default and uses it only if it improves held-out performance on this protein. Use
|
|
212
|
+
`--no-auto-signals` only as an expert override. `--recombine` also adds recombinations of your
|
|
213
|
+
MEASURED beneficials (variants beating WT) to the candidate pool -- the strategy the real-data
|
|
214
|
+
evidence supports (measure broadly, then recombine confirmed wins).
|
|
215
|
+
- `shellde resolve-site WT.fasta --uniprot ACC` (or `--query`): resolve active-site/binding positions
|
|
216
|
+
from UniProt experimental curation, sequence-aligned onto YOUR WT numbering (handles transit-peptide
|
|
217
|
+
/ species offsets), with provenance + confidence per position. If UniProt features do not map it
|
|
218
|
+
falls back to a UniProt-linked PDB cocrystal (active-site shells); `--pdb ID` forces the structure
|
|
219
|
+
path. If neither maps, it fetches the AlphaFold model (predicted, apo). Optional `--apo-pocket`
|
|
220
|
+
(fpocket) guesses pocket positions but is LOW-confidence -- it missed the catalytic site on ispS,
|
|
221
|
+
so it is warned, not default. `--find-holo` instead Foldseek-finds a ligand-bound homolog (gated on
|
|
222
|
+
significance) to borrow a pose from; giving `--pdb` + `--uniprot` prints an evidence-consensus map
|
|
223
|
+
(per-position support + confidence tier). Abstains on positions rather than guessing -- then provide
|
|
224
|
+
`--holo`/`--positions`. Feed resolved positions to `campaign`.
|
|
225
|
+
- `shellde hotspots scan.csv`: rank hotspot positions from a whole-protein single-mutant scan
|
|
226
|
+
(`variant,activity`; CSV or Excel), then hand the top positions to `round --positions` for
|
|
227
|
+
combinatorial AL. Combinatorial means the CANDIDATE POOL spans multi-mutants; the fitted model is
|
|
228
|
+
additive by default (one-hot + bootstrap-ridge ensemble). Explicit pairwise epistasis is an opt-in
|
|
229
|
+
on `recommend`: `--auto-gate-pairwise` opens the block only if cross-validated evidence on your own
|
|
230
|
+
measured data supports it, while `--contacts-pdb` opens a contact-restricted pairwise block
|
|
231
|
+
unconditionally (no CV gate).
|
|
232
|
+
Honest: scan-based position selection is a coarse pre-filter,
|
|
233
|
+
reliable only on additive sites (see `artifacts/hotspots_backtest_evidence.md`).
|
|
234
|
+
- `shellde funclib WT.fasta ...`: build only the active-site R0 measurement library. Useful when you
|
|
235
|
+
want the seed plate without the campaign wrapper.
|
|
236
|
+
- `shellde advise measured.csv`: readiness check on measured data (held-out Spearman + pairwise gate
|
|
237
|
+
-> gather_more / model_reliable / open_epistasis). Also auto-printed at the end of every `round`/`campaign`
|
|
238
|
+
Rk round, so you are told each round whether to trust the surrogate or keep measuring.
|
|
239
|
+
- `shellde bench`: synthetic alpha-spectrum benchmark.
|
|
240
|
+
- `shellde report`: summarize a JSON report.
|
|
241
|
+
|
|
242
|
+
## What the opt-ins mean
|
|
243
|
+
|
|
244
|
+
Most optional flags are not feature clutter. They are either:
|
|
245
|
+
|
|
246
|
+
- **resources you must provide**: MSA, PDB, inverse-folding table, ddG table, PLM cache; or
|
|
247
|
+
- **expert overrides** for known regimes.
|
|
248
|
+
|
|
249
|
+
The default stays conservative because low-N model selection overfits. When ShellDE can decide from
|
|
250
|
+
this protein's measured data, it should decide itself -- and that is wired per command, not in general.
|
|
251
|
+
On `recommend`: a supplied `--if-logprobs` signal is CV-gated by default, and pairwise epistasis has
|
|
252
|
+
its own data gate (`--auto-gate-pairwise`). Not wired elsewhere: `--contacts-pdb` opens the pairwise
|
|
253
|
+
block with no CV gate, `campaign` and `round` add `--if-logprobs` unconditionally, and `--plm` /
|
|
254
|
+
`--naturalness` are never gated on any command. See `docs/OPTIN_AUDIT.md`.
|
|
255
|
+
|
|
256
|
+
## Honest scope
|
|
257
|
+
|
|
258
|
+
Evidence so far supports these claims:
|
|
259
|
+
|
|
260
|
+
- active-site FuncLib-style seeds enrich measurable libraries and improve low-budget discovery;
|
|
261
|
+
- the global activity winner can be outside the seed, so AL must search beyond the seed;
|
|
262
|
+
- stability/ddG signals are best used as constraints, while activity improvement is measurement-bound;
|
|
263
|
+
- high-order activity epistasis makes zero-shot winner prediction unreliable.
|
|
264
|
+
|
|
265
|
+
Evidence does **not** support: "ShellDE predicts the best protein from sequence/structure alone." It
|
|
266
|
+
increases the probability and efficiency of finding a better variant per measured plate, conditional on
|
|
267
|
+
the design space and assay.
|
|
268
|
+
|
|
269
|
+
## When NOT to use ShellDE
|
|
270
|
+
|
|
271
|
+
The focused active-site campaign helps only when the wins plausibly live in a region you can name
|
|
272
|
+
and measure combinatorially. Do NOT reach for it when:
|
|
273
|
+
|
|
274
|
+
- you do not know where beneficial mutations are (no mechanistic/structural prior on the target site);
|
|
275
|
+
- the wins are likely distal/distributed across the protein (use a broad whole-protein single-mutant
|
|
276
|
+
scan instead -- that is a different tool class; the ShellDE additive default cannot rank
|
|
277
|
+
whole-protein singles because one-hot has no cross-position transfer);
|
|
278
|
+
- you cannot measure a focused combinatorial library (no assay throughput at the chosen site).
|
|
279
|
+
|
|
280
|
+
Real-data caution (PtIspS, `artifacts/ispS_wetlab_validation.md`): a campaign run as a broad
|
|
281
|
+
single-mutant scan with the active site barely sampled and the global winner distal is exactly the
|
|
282
|
+
regime ShellDE is NOT for. Pick broad-vs-focused from your biology; ShellDE does not decide it.
|
|
283
|
+
|
|
284
|
+
More detail: `ARCHITECTURE.md`, `artifacts/DECISION_EVIDENCE.md`, and the Obsidian decision log named
|
|
285
|
+
there.
|
shellde-0.2.0/README.md
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# ShellDE
|
|
2
|
+
|
|
3
|
+
Low-N, acquisition-driven protein mutation recommendation. The spine is one measurement campaign:
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
R0 seed to measure -> fit surrogate on all measured data -> acquire next plate -> measure -> repeat
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
ShellDE is not a magic zero-shot "better protein" predictor. Zero-shot, MSA, inverse-folding,
|
|
10
|
+
structure, and ddG signals are used as priors, constraints, or features. The function-aligned signal
|
|
11
|
+
is still measurement. The tool's job is to spend a small measurement budget better.
|
|
12
|
+
|
|
13
|
+
> **Naming.** `ShellDE` in prose, `shellde` as the PyPI distribution, the import, and the command. Never
|
|
14
|
+
> `Shellde`, `shellDE`, or `SHELLDE`.
|
|
15
|
+
>
|
|
16
|
+
> **Renamed.** This project was `epiquire` through v0.1.46.00 and is `shellde` from v0.2.00.00. The name
|
|
17
|
+
> is the active-site contact SHELL that `resolve-site` computes (and the 2nd-shell ring that
|
|
18
|
+
> `--exclude-catalytic` designs over), plus DE for directed evolution.
|
|
19
|
+
>
|
|
20
|
+
> **PyPI status (checked 2026-08-28).** `shellde` is NOT on PyPI: the PyPI JSON API returns 404 for it.
|
|
21
|
+
> `epiquire` IS on PyPI at 0.1.21, and that wheel still installs the OLD pre-rename package, unchanged,
|
|
22
|
+
> which is why a pinned Colab install naming it keeps working. No deprecation shim exists, in this tree
|
|
23
|
+
> or on PyPI. Publishing `shellde`, and only then turning `epiquire` into a shim that points at it, are
|
|
24
|
+
> PLANNED owner actions tracked in `docs/RENAME_PLAN.md`, not things already done.
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
`shellde` is not on PyPI yet, so install it from a source checkout of this repository. Run this from
|
|
29
|
+
the repository root, the directory holding `pyproject.toml`:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install . # core deps: numpy/scipy/scikit-learn/pandas
|
|
33
|
+
pip install ".[plm]" # optional: adds torch + ESM-C (PLM re-rank / naturalness)
|
|
34
|
+
pip install -e . # editable, when working on the code itself
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Verified 2026-08-28 in a throwaway venv: `pip install .` builds `shellde-0.2.0` and the installed
|
|
38
|
+
`shellde` console script renders `usage: shellde`.
|
|
39
|
+
|
|
40
|
+
The short PyPI form stays here because it becomes the recommended path once the distribution is
|
|
41
|
+
published. It returns a 404 today, so do not run it yet:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install shellde # ONLY AFTER shellde is published to PyPI (not yet; 404 today)
|
|
45
|
+
pip install "shellde[plm]" # ONLY AFTER shellde is published to PyPI (not yet; 404 today)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Or run it in your browser with **no install** via the Colab notebook below.
|
|
49
|
+
|
|
50
|
+
## Easiest entry point: `shellde round`
|
|
51
|
+
|
|
52
|
+
One command per round. It auto-resolves the active-site design region (the `resolve-site` evidence
|
|
53
|
+
ladder: UniProt -> linked PDB cocrystal -> AlphaFold) and then runs the campaign round, so there is
|
|
54
|
+
no position bookkeeping by hand.
|
|
55
|
+
|
|
56
|
+
**Run it in your browser, no install:** open the notebook in Google Colab via its public gist (works
|
|
57
|
+
without repo access): [open in Colab](https://colab.research.google.com/gist/gyuminlee-repo/1a7a0b5dbf3919d652a6ba2dbdb3f49a/epiquire_round_colab.ipynb).
|
|
58
|
+
The notebook is a 3-line bootstrap over a `plate(...)` call: all logic lives in the pip package, so the
|
|
59
|
+
notebook file never needs re-uploading. That link opens the PRE-RENAME notebook. The published gist
|
|
60
|
+
still installs `epiquire` and imports `epiquire.colab.plate`, and that is exactly why it still runs
|
|
61
|
+
today. `notebooks/COLAB_GIST.md` records the resync order, which waits on the
|
|
62
|
+
PyPI publish.
|
|
63
|
+
|
|
64
|
+
Once `shellde` is published and the gist is resynced, any notebook can skip the form and call it
|
|
65
|
+
directly with the three lines below. They do not work yet, because the first one 404s:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
%pip install -q -U shellde
|
|
69
|
+
from shellde.colab import plate
|
|
70
|
+
df = plate("...WT sequence...", uniprot="Q50L36", auto_msa=True) # R0 seed plate, MSA built for you
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The core loop is numpy/scikit-learn (seconds); only the optional PLM path is heavy (Colab's free GPU).
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# R0: no --measured -> the funclib seed plate to MEASURE. The seed needs a tolerance signal;
|
|
77
|
+
# supply --msa/--ddg/--if-logprobs, OR --auto-msa to build the MSA from the WT (ColabFold MMseqs2).
|
|
78
|
+
shellde round WT.fasta --uniprot Q50L36 --auto-msa --plate 95 --outdir outputs/round
|
|
79
|
+
|
|
80
|
+
# Rk: add each round's measured results -> the next AL plate over the full saturation universe
|
|
81
|
+
shellde round WT.fasta --uniprot Q50L36 --measured round0_measured.csv --plate 95 --outdir outputs/round
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Point at the design region with whatever you have: `--uniprot ACC` (or `--uniprot auto` to find the accession by
|
|
85
|
+
an EXACT match of your WT sequence against UniProt), `--query`/`--pdb` (auto ladder), a local
|
|
86
|
+
`--holo` structure, or explicit `--positions`. Give more than one and the most-specific wins,
|
|
87
|
+
resolved by a fixed priority `positions > holo > pdb+uniprot > pdb > uniprot/query` -- so you can just
|
|
88
|
+
pass whatever you have. Two special combinations: giving **both** `--pdb` and `--uniprot` designs over
|
|
89
|
+
the PDB contact shell while flagging (QC) the UniProt catalytic core that falls inside it, and adding
|
|
90
|
+
`--exclude-catalytic` then designs only the tunable 2nd-shell ring (shell minus the usually-lethal
|
|
91
|
+
catalytic core). If the ladder cannot map evidence onto your WT it abstains (supply `--positions` or
|
|
92
|
+
`--holo`) rather than guessing. `round` is a thin wrapper: `resolve-site` and `campaign` below remain
|
|
93
|
+
the explicit, fully-configurable commands it calls.
|
|
94
|
+
No cocrystal at all? `--find-holo` (on `round`/`resolve-site`) Foldseek-searches for a ligand-bound
|
|
95
|
+
(holo) structural homolog of your WT and, if a SIGNIFICANT one exists (E-value + coverage gated), uses
|
|
96
|
+
its ligand pose to define the shell; it abstains when only distant homologs are found so a mismatched
|
|
97
|
+
pocket is never silently borrowed. When several evidence types are available (e.g. `--pdb` + `--uniprot`)
|
|
98
|
+
ShellDE prints an evidence-consensus map: each position tagged with which independent lines support it
|
|
99
|
+
and a confidence tier (high = >=2 agree), so you can measure high-confidence positions first.
|
|
100
|
+
|
|
101
|
+
## The campaign engine (what `round` calls)
|
|
102
|
+
|
|
103
|
+
Use `campaign` when starting an active-site campaign. It combines the two validated pieces:
|
|
104
|
+
|
|
105
|
+
1. **R0 cold-start seed**: FuncLib-style active-site library construction. This proposes variants to
|
|
106
|
+
measure; it does not predict winners.
|
|
107
|
+
2. **R1+ active learning**: after measurements arrive, the AL loop searches the full saturation space
|
|
108
|
+
of the design positions, not just the R0 seed.
|
|
109
|
+
|
|
110
|
+
### R0: generate the seed plate
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
shellde campaign WT.fasta \
|
|
114
|
+
--holo holo_structure.pdb --ligand-resnames LIG \
|
|
115
|
+
--msa alignment.a3m \
|
|
116
|
+
--plate 95 \
|
|
117
|
+
--outdir outputs/campaign
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
This writes `outputs/campaign/round0_plate.csv` with `variant,mutations,n_mut,seed_score`. Measure
|
|
121
|
+
those variants and save a `variant,fitness` CSV.
|
|
122
|
+
|
|
123
|
+
You can use explicit design positions instead of a holo structure:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
shellde campaign WT.fasta \
|
|
127
|
+
--positions 183,184,227,228 \
|
|
128
|
+
--msa alignment.a3m \
|
|
129
|
+
--plate 95 \
|
|
130
|
+
--outdir outputs/campaign
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### R1+: propose the next plate from measured data
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
shellde campaign WT.fasta \
|
|
137
|
+
--positions 183,184,227,228 \
|
|
138
|
+
--measured round0_measured.csv \
|
|
139
|
+
--plate 95 \
|
|
140
|
+
--outdir outputs/campaign
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
With multiple rounds, pass all accumulated CSVs:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
shellde campaign WT.fasta \
|
|
147
|
+
--positions 183,184,227,228 \
|
|
148
|
+
--measured round0_measured.csv round1_measured.csv \
|
|
149
|
+
--plate 95 \
|
|
150
|
+
--outdir outputs/campaign
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
On later rounds, add `--plm esmc` to rerank the plate with an ESM-C surrogate refit on YOUR measured
|
|
154
|
+
data (EVOLVEpro-style; opt-in, GPU-recommended). Every Rk round also auto-prints an `advise` line --
|
|
155
|
+
held-out Spearman + a recommendation (`gather_more` / `model_reliable` / `open_epistasis`) -- so you
|
|
156
|
+
know each round whether to trust the surrogate or keep measuring broadly.
|
|
157
|
+
|
|
158
|
+
### Simulate against a complete landscape
|
|
159
|
+
|
|
160
|
+
For validation or retrospective benchmarks:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
shellde campaign WT.fasta \
|
|
164
|
+
--simulate data/trpb.csv \
|
|
165
|
+
--positions 183,184,227,228 \
|
|
166
|
+
--msa isps_run/msa_trpb.a3m \
|
|
167
|
+
--strategies funclib singles random \
|
|
168
|
+
--plate 95 --rounds 3 --seeds 20 --jobs 4 \
|
|
169
|
+
--model-class ridge \
|
|
170
|
+
--outdir artifacts/campaign_trpb
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
`--jobs` parallelizes independent seeds with spawn processes; serial output and parallel output are
|
|
174
|
+
byte-identical by test.
|
|
175
|
+
|
|
176
|
+
## Other commands
|
|
177
|
+
|
|
178
|
+
- `shellde recommend measured.csv`: rank next candidates from accumulated measurements. This is the
|
|
179
|
+
AL round engine exposed directly. If you pass `--if-logprobs`, ShellDE CV-gates that signal by
|
|
180
|
+
default and uses it only if it improves held-out performance on this protein. Use
|
|
181
|
+
`--no-auto-signals` only as an expert override. `--recombine` also adds recombinations of your
|
|
182
|
+
MEASURED beneficials (variants beating WT) to the candidate pool -- the strategy the real-data
|
|
183
|
+
evidence supports (measure broadly, then recombine confirmed wins).
|
|
184
|
+
- `shellde resolve-site WT.fasta --uniprot ACC` (or `--query`): resolve active-site/binding positions
|
|
185
|
+
from UniProt experimental curation, sequence-aligned onto YOUR WT numbering (handles transit-peptide
|
|
186
|
+
/ species offsets), with provenance + confidence per position. If UniProt features do not map it
|
|
187
|
+
falls back to a UniProt-linked PDB cocrystal (active-site shells); `--pdb ID` forces the structure
|
|
188
|
+
path. If neither maps, it fetches the AlphaFold model (predicted, apo). Optional `--apo-pocket`
|
|
189
|
+
(fpocket) guesses pocket positions but is LOW-confidence -- it missed the catalytic site on ispS,
|
|
190
|
+
so it is warned, not default. `--find-holo` instead Foldseek-finds a ligand-bound homolog (gated on
|
|
191
|
+
significance) to borrow a pose from; giving `--pdb` + `--uniprot` prints an evidence-consensus map
|
|
192
|
+
(per-position support + confidence tier). Abstains on positions rather than guessing -- then provide
|
|
193
|
+
`--holo`/`--positions`. Feed resolved positions to `campaign`.
|
|
194
|
+
- `shellde hotspots scan.csv`: rank hotspot positions from a whole-protein single-mutant scan
|
|
195
|
+
(`variant,activity`; CSV or Excel), then hand the top positions to `round --positions` for
|
|
196
|
+
combinatorial AL. Combinatorial means the CANDIDATE POOL spans multi-mutants; the fitted model is
|
|
197
|
+
additive by default (one-hot + bootstrap-ridge ensemble). Explicit pairwise epistasis is an opt-in
|
|
198
|
+
on `recommend`: `--auto-gate-pairwise` opens the block only if cross-validated evidence on your own
|
|
199
|
+
measured data supports it, while `--contacts-pdb` opens a contact-restricted pairwise block
|
|
200
|
+
unconditionally (no CV gate).
|
|
201
|
+
Honest: scan-based position selection is a coarse pre-filter,
|
|
202
|
+
reliable only on additive sites (see `artifacts/hotspots_backtest_evidence.md`).
|
|
203
|
+
- `shellde funclib WT.fasta ...`: build only the active-site R0 measurement library. Useful when you
|
|
204
|
+
want the seed plate without the campaign wrapper.
|
|
205
|
+
- `shellde advise measured.csv`: readiness check on measured data (held-out Spearman + pairwise gate
|
|
206
|
+
-> gather_more / model_reliable / open_epistasis). Also auto-printed at the end of every `round`/`campaign`
|
|
207
|
+
Rk round, so you are told each round whether to trust the surrogate or keep measuring.
|
|
208
|
+
- `shellde bench`: synthetic alpha-spectrum benchmark.
|
|
209
|
+
- `shellde report`: summarize a JSON report.
|
|
210
|
+
|
|
211
|
+
## What the opt-ins mean
|
|
212
|
+
|
|
213
|
+
Most optional flags are not feature clutter. They are either:
|
|
214
|
+
|
|
215
|
+
- **resources you must provide**: MSA, PDB, inverse-folding table, ddG table, PLM cache; or
|
|
216
|
+
- **expert overrides** for known regimes.
|
|
217
|
+
|
|
218
|
+
The default stays conservative because low-N model selection overfits. When ShellDE can decide from
|
|
219
|
+
this protein's measured data, it should decide itself -- and that is wired per command, not in general.
|
|
220
|
+
On `recommend`: a supplied `--if-logprobs` signal is CV-gated by default, and pairwise epistasis has
|
|
221
|
+
its own data gate (`--auto-gate-pairwise`). Not wired elsewhere: `--contacts-pdb` opens the pairwise
|
|
222
|
+
block with no CV gate, `campaign` and `round` add `--if-logprobs` unconditionally, and `--plm` /
|
|
223
|
+
`--naturalness` are never gated on any command. See `docs/OPTIN_AUDIT.md`.
|
|
224
|
+
|
|
225
|
+
## Honest scope
|
|
226
|
+
|
|
227
|
+
Evidence so far supports these claims:
|
|
228
|
+
|
|
229
|
+
- active-site FuncLib-style seeds enrich measurable libraries and improve low-budget discovery;
|
|
230
|
+
- the global activity winner can be outside the seed, so AL must search beyond the seed;
|
|
231
|
+
- stability/ddG signals are best used as constraints, while activity improvement is measurement-bound;
|
|
232
|
+
- high-order activity epistasis makes zero-shot winner prediction unreliable.
|
|
233
|
+
|
|
234
|
+
Evidence does **not** support: "ShellDE predicts the best protein from sequence/structure alone." It
|
|
235
|
+
increases the probability and efficiency of finding a better variant per measured plate, conditional on
|
|
236
|
+
the design space and assay.
|
|
237
|
+
|
|
238
|
+
## When NOT to use ShellDE
|
|
239
|
+
|
|
240
|
+
The focused active-site campaign helps only when the wins plausibly live in a region you can name
|
|
241
|
+
and measure combinatorially. Do NOT reach for it when:
|
|
242
|
+
|
|
243
|
+
- you do not know where beneficial mutations are (no mechanistic/structural prior on the target site);
|
|
244
|
+
- the wins are likely distal/distributed across the protein (use a broad whole-protein single-mutant
|
|
245
|
+
scan instead -- that is a different tool class; the ShellDE additive default cannot rank
|
|
246
|
+
whole-protein singles because one-hot has no cross-position transfer);
|
|
247
|
+
- you cannot measure a focused combinatorial library (no assay throughput at the chosen site).
|
|
248
|
+
|
|
249
|
+
Real-data caution (PtIspS, `artifacts/ispS_wetlab_validation.md`): a campaign run as a broad
|
|
250
|
+
single-mutant scan with the active site barely sampled and the global winner distal is exactly the
|
|
251
|
+
regime ShellDE is NOT for. Pick broad-vs-focused from your biology; ShellDE does not decide it.
|
|
252
|
+
|
|
253
|
+
More detail: `ARCHITECTURE.md`, `artifacts/DECISION_EVIDENCE.md`, and the Obsidian decision log named
|
|
254
|
+
there.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "shellde"
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "Low-N, acquisition-driven protein mutation campaign planner: additive default, opt-in signals, honest abstention"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
authors = [{ name = "gyuminlee-repo" }]
|
|
12
|
+
keywords = [
|
|
13
|
+
"directed-evolution",
|
|
14
|
+
"protein-engineering",
|
|
15
|
+
"active-learning",
|
|
16
|
+
"bayesian-optimization",
|
|
17
|
+
"epistasis",
|
|
18
|
+
"mutation-recommendation",
|
|
19
|
+
"uncertainty-calibration",
|
|
20
|
+
"active-site",
|
|
21
|
+
]
|
|
22
|
+
classifiers = [
|
|
23
|
+
"Development Status :: 4 - Beta",
|
|
24
|
+
"Intended Audience :: Science/Research",
|
|
25
|
+
"Programming Language :: Python :: 3",
|
|
26
|
+
"Programming Language :: Python :: 3.10",
|
|
27
|
+
"Programming Language :: Python :: 3.11",
|
|
28
|
+
"Programming Language :: Python :: 3.12",
|
|
29
|
+
"Topic :: Scientific/Engineering :: Bio-Informatics",
|
|
30
|
+
"Operating System :: OS Independent",
|
|
31
|
+
]
|
|
32
|
+
dependencies = [
|
|
33
|
+
"numpy",
|
|
34
|
+
"scipy",
|
|
35
|
+
"scikit-learn",
|
|
36
|
+
"pandas",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[project.optional-dependencies]
|
|
40
|
+
plm = ["torch", "esm"] # ESM-C (EvolutionaryScale) + on-demand embeddings
|
|
41
|
+
plm2 = ["fair-esm"] # ESM-2 (Meta) alternative provider
|
|
42
|
+
dev = ["pytest", "pyright", "build", "twine"]
|
|
43
|
+
|
|
44
|
+
[project.scripts]
|
|
45
|
+
shellde = "shellde.cli:main"
|
|
46
|
+
|
|
47
|
+
[tool.setuptools.packages.find]
|
|
48
|
+
where = ["src"]
|
|
49
|
+
|
|
50
|
+
[tool.pytest.ini_options]
|
|
51
|
+
testpaths = ["tests"]
|
shellde-0.2.0/setup.cfg
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""ShellDE: low-N, acquisition-driven mutation recommendation for directed evolution.
|
|
2
|
+
|
|
3
|
+
The name states the scope. `shell` is the active-site contact shell that `resolve-site`
|
|
4
|
+
computes, and the second-shell ring that `--exclude-catalytic` designs over. `DE` is
|
|
5
|
+
directed evolution. Casing is fixed and does not vary: the distribution, the import name
|
|
6
|
+
and the CLI command are always lowercase `shellde`, while prose and citations use
|
|
7
|
+
`ShellDE`. Never `Shellde`, `shellDE` or `SHELLDE`.
|
|
8
|
+
|
|
9
|
+
The shipped default is calibrated-additive. On `recommend`, --auto-gate-pairwise and
|
|
10
|
+
--if-logprobs are CV-gated on your own held-out data (--no-auto-signals forces the latter
|
|
11
|
+
on), while --contacts-pdb opens the contact-restricted pairwise block unconditionally.
|
|
12
|
+
`campaign` and `round` offer neither pairwise flag and add --if-logprobs UNCONDITIONALLY,
|
|
13
|
+
with no gate. --plm and --naturalness are never gated on any command."""
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from importlib.metadata import PackageNotFoundError
|
|
17
|
+
from importlib.metadata import version as _pkg_version
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
__version__ = _pkg_version("shellde")
|
|
21
|
+
except PackageNotFoundError: # not installed (e.g. run from a source tree without install)
|
|
22
|
+
__version__ = "0.0.0+unknown"
|
|
23
|
+
|
|
24
|
+
from shellde.funclib import (
|
|
25
|
+
FuncLibLibrary,
|
|
26
|
+
combine_tolerances,
|
|
27
|
+
design_library,
|
|
28
|
+
tolerance_from_logprob_table,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
__all__ = [
|
|
32
|
+
"FuncLibLibrary",
|
|
33
|
+
"combine_tolerances",
|
|
34
|
+
"design_library",
|
|
35
|
+
"tolerance_from_logprob_table",
|
|
36
|
+
]
|