Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ bench-selectivity:
--hemolysis-csv examples/validation/hemolysis_reference.csv
--out outputs/selectivity_benchmark_report.json


bench-triage:
PYTHONPATH=src $(PYTHON) -m openamp_foundry.cli bench triage \
--out outputs/triage_benchmark_report.json
validate-scoring-strict:
PYTHONPATH=src $(PYTHON) -m openamp_foundry.cli validate-scoring \
--amp-csv examples/validation/known_amps.csv \
Expand Down
66 changes: 65 additions & 1 deletion docs/METRICS_CURRENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
> **Purpose:** One authoritative table of current pipeline metrics. If any doc disagrees
> with this file, this file wins. Updated whenever benchmark/benchmark config changes.
>
> **Last updated:** 2026-07-01 (hemolysis benchmark expanded to 238 peptides)
> **Last updated:** 2026-07-01 (triage benchmark added)
> **Pipeline version:** v0.5.x
> **Branch:** main

Expand Down Expand Up @@ -375,6 +375,70 @@ hemolysis mechanism is not fully captured by 1D features.

---

## Multi-Class Triage Benchmark (v0.5.12 — added 2026-07-01)

> Tests the v1.1 ROADMAP item: "benchmark candidate triage against a reference
> panel that includes selective AMPs, hemolytic positives, inactive peptides,
> and random controls." Prior benchmarks tested two separate 2-class problems
> (AMP vs decoy, hemolytic vs selective). This benchmark tests the combined
> triage task the virtual assay layer must solve: rank selective AMPs above
> hemolytic AMPs above random decoys in a single panel.
>
> Run: `make bench-triage`

**Dataset:** 125 selective AMPs (HC50 >= 100 µg/mL) + 45 hemolytic AMPs (HC50 < 25 µg/mL)
+ 96 random background decoys = 266 total.

### Per-scorer pairwise AUROCs

A scorer that triages correctly should have all three AUROCs > 0.5:
- selective > decoy (identifies AMPs)
- hemolytic > decoy (identifies AMPs)
- selective > hemolytic (prefers safe AMPs)

| Scorer | sel > decoy | hem > decoy | sel > hem | Triages correctly? |
|--------|:-----------:|:-----------:|:---------:|:------------------:|
| ensemble | 0.848 | 0.891 | 0.466 | **NO** (anti-selective) |
| activity | 0.885 | 0.934 | 0.430 | NO |
| selectivity_proxy | 0.782 | 0.795 | 0.610 | **YES** |
| triage_score (activity × (1 - hemo_risk)) | 0.863 | 0.902 | 0.462 | NO |
| safe_weighted_ensemble | 0.849 | 0.890 | 0.483 | NO |
| safety | 0.344 | 0.300 | 0.538 | NO |
| synthesis | 0.590 | 0.634 | 0.469 | NO |
| hemolysis_risk (inverted) | 0.485 | 0.492 | 0.488 | NO |
| serum_stability | 0.217 | 0.160 | 0.569 | NO |

**Key findings:**

1. **The ensemble does NOT triage correctly.** It ranks hemolytic AMPs above
selective AMPs (sel_vs_hem AUROC = 0.466 < 0.5). This is the anti-selective
bias documented in the selectivity benchmark, now confirmed in the combined
triage context.

2. **Only selectivity_proxy triages correctly** (all three AUROCs > 0.5). It
sacrifices some decoy discrimination (0.782 vs ensemble's 0.848) but is the
only scorer that prefers selective AMPs over hemolytic ones.

3. **The naive triage_score (activity × (1 - hemolysis_risk)) does NOT fix the
anti-selective bias** (sel_vs_hem = 0.462). This is because hemolysis_risk
is too weak (detection AUROC 0.565, not significant on expanded benchmark).
A naive virtual-assay composite does not outperform the ensemble.

4. **Top-20 distribution shift:** The triage_score moves 2 more selective AMPs
into the top-20 (16 vs 14 for ensemble), removing 2 hemolytic AMPs (4 vs 6).
The shift is in the right direction but modest — the hemolysis_risk penalty
is weak.

**Implication for the virtual assay layer:** Any future virtual assay module
must beat this triage benchmark baseline. The minimum bar is: triage correctly
(all three AUROCs > 0.5) while maintaining ensemble-level decoy discrimination
(sel_vs_decoy > 0.80). The selectivity_proxy achieves correct triage but at
the cost of decoy discrimination. A successful virtual assay must achieve both.

**Honest limitation:** The benchmark uses literature HC50 values with high
inter-assay variability. The binary thresholds (25 / 100 µg/mL) are coarse.
The MODERATE class (HC50 25-100, n=68) is excluded from the binary task.

## Test Suite

| Metric | Value |
Expand Down
26 changes: 25 additions & 1 deletion docs/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,30 @@ Implemented during the pre-wet-lab improvement loop (PRs #31–#54):
- Blind spots: 14 hemolytic AMPs with safety >= 0.8 (melittin, indolicidin, protegrins, tachyplesins, piscidin-1, arenicin, polyphemusin, gramicidin-S-like, BMAP fragment)
- 18 new tests in `test_selectivity_benchmark.py`; 1453 total tests

## v0.5.12 — Multi-Class Triage Benchmark ✓ (2026-07-01)

- **Multi-class triage benchmark** (`benchmark/triage.py`): tests whether the
pipeline can rank selective AMPs > hemolytic AMPs > random decoys in a single
combined panel (125 selective + 45 hemolytic + 96 decoys = 266 total).
- Addresses the v1.1 ROADMAP item: "benchmark candidate triage against a
reference panel that includes selective AMPs, hemolytic positives, inactive
peptides, and random controls."
- **Key finding:** The ensemble does NOT triage correctly. It ranks hemolytic
AMPs above selective AMPs (AUROC 0.466 < 0.5) due to the activity scorer's
anti-selective bias. Hemolytic AMPs have stronger amphipathic helices, higher
hydrophobic moment, and higher charge — exactly the features the activity
scorer rewards.
- **Key finding:** Only `selectivity_proxy` triages correctly (all three pairwise
AUROCs > 0.5), but at the cost of decoy discrimination (0.782 vs ensemble 0.848).
- **Key finding:** The naive `triage_score` (activity × (1 - hemolysis_risk))
does NOT fix the anti-selective bias because hemolysis_risk is too weak
(detection AUROC 0.565, not significant on expanded benchmark).
- The `triage_score` does shift the top-20 distribution favorably (16 selective
vs 14 for ensemble; 4 hemolytic vs 6), but the pairwise AUROC remains < 0.5.
- CLI: `openamp-foundry bench triage --hemolysis-csv ... --decoy-csv ...`
- Makefile: `make bench-triage`
- 16 new tests (15 triage benchmark + 1 CLI integration); 1487 tests total.

## v1.0 — Validated dry-lab-to-wet-lab loop

- independently reviewed assay batch (expert_review.yml GitHub issue template);
Expand All @@ -197,7 +221,7 @@ Implemented during the pre-wet-lab improvement loop (PRs #31–#54):

- ~~write the first explicit simulator scope document: what OpenAMP will model and what it will not;~~
- ~~add membrane/selectivity/stability proxy interfaces with uncertainty fields;~~
- benchmark candidate triage against a reference panel that includes selective AMPs, hemolytic positives, inactive peptides, and random controls;
- ~~benchmark candidate triage against a reference panel that includes selective AMPs, hemolytic positives, inactive peptides, and random controls;~~ (v0.5.12: triage benchmark added — ensemble fails, selectivity_proxy only correct triager)
- require every proxy module to justify itself against cheap heuristic baselines before it affects selection.

## v2.x — Wet-lab compression engine
Expand Down
Loading
Loading