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
23 changes: 23 additions & 0 deletions examples/toy_pipeline_output/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Toy Pipeline Output Examples

This directory contains **pre-generated toy examples** showing what OpenAMP Foundry pipeline outputs look like.

**IMPORTANT**: All candidate IDs use the `TOY-` prefix. All sequences are made up and do NOT represent real antimicrobial peptide candidates. These files exist solely to show output format and structure.

## Files

| File | Description |
|------|-------------|
| `toy_ranked_example.jsonl` | 3 toy ranked candidates (one JSON object per line) |
| `toy_certificate_example.json` | Example evidence certificate for a toy candidate |

## What These Show

- Field names and value ranges in ranked output
- Evidence certificate structure and required fields
- The claim boundary notice format
- How dry-lab-only status is encoded

## What These Are NOT

These are NOT real candidates. They are NOT nominations for synthesis. They exist only to illustrate output format.
27 changes: 27 additions & 0 deletions examples/toy_pipeline_output/toy_certificate_example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"cert_id": "TOY-CERT-0001",
"candidate_id": "TOY-0001",
"sequence": "KWKLFKKIEK",
"dry_lab_only": true,
"claim_class": "computational_nomination",
"proof_ladder_level": "multi_signal_candidate_evidence",
"unsupported_claims": ["in_vitro_activity", "in_vivo_efficacy", "toxicity_cleared", "clinical_relevance"],
"scores": {
"activity": 0.82,
"safety": 0.91,
"novelty": 0.75,
"hemolysis_risk": 0.12,
"ensemble": 0.85
},
"baseline_caveat": "Charge, length, and hydrophobicity baselines all pass. Method advantage over cheap heuristics is not yet demonstrated.",
"selection_reason": ["High activity-likeness score", "Low predicted safety risk"],
"known_failure_modes": [
"No wet-lab antimicrobial activity assay has been run.",
"Scores are heuristics, not validated biological predictors.",
"Cheap baselines (charge, length, hydrophobicity) are not excluded as explanations."
],
"run_id": "TOY-RUN-0001",
"run_manifest_hash": "0000000000000000000000000000000000000000000000000000000000000000",
"human_review_required": false,
"issued_by": "openamp_foundry_toy_example"
}
3 changes: 3 additions & 0 deletions examples/toy_pipeline_output/toy_ranked_example.jsonl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{"candidate_id": "TOY-0001", "sequence": "KWKLFKKIEK", "source": "toy", "valid": true, "selected": true, "scores": {"activity": 0.82, "safety": 0.91, "novelty": 0.75, "hemolysis_risk": 0.12, "ensemble": 0.85, "selectivity_proxy": 0.88}, "selection_reason": ["High activity-likeness score", "Low predicted safety risk"], "known_failure_modes": ["No wet-lab antimicrobial activity assay has been run.", "Scores are heuristics, not validated biological predictors."], "dry_lab_only": true}
{"candidate_id": "TOY-0002", "sequence": "FLPKLKKLLK", "source": "toy", "valid": true, "selected": true, "scores": {"activity": 0.71, "safety": 0.88, "novelty": 0.62, "hemolysis_risk": 0.19, "ensemble": 0.78, "selectivity_proxy": 0.81}, "selection_reason": ["Moderate activity-likeness score", "Acceptable safety profile"], "known_failure_modes": ["No wet-lab antimicrobial activity assay has been run.", "Scores are heuristics, not validated biological predictors."], "dry_lab_only": true}
{"candidate_id": "TOY-0003", "sequence": "GIKCKILKKLR", "source": "toy", "valid": true, "selected": false, "scores": {"activity": 0.48, "safety": 0.72, "novelty": 0.55, "hemolysis_risk": 0.38, "ensemble": 0.52, "selectivity_proxy": 0.61}, "selection_reason": [], "known_failure_modes": ["Insufficient activity score", "No wet-lab antimicrobial activity assay has been run.", "Scores are heuristics, not validated biological predictors."], "dry_lab_only": true}
2 changes: 1 addition & 1 deletion tests/test_test_count_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import subprocess
import math

BASELINE = 8536
BASELINE = 8585


def test_test_count_regression():
Expand Down
260 changes: 260 additions & 0 deletions tests/test_toy_examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
"""Tests for A8 toy pipeline output examples (tests/test_toy_examples.py)."""

from __future__ import annotations

import json
from pathlib import Path

import pytest


_TOY_DIR = Path(__file__).parent.parent / "examples" / "toy_pipeline_output"
_RANKED_FILE = _TOY_DIR / "toy_ranked_example.jsonl"
_CERT_FILE = _TOY_DIR / "toy_certificate_example.json"
_README_FILE = _TOY_DIR / "README.md"


class TestToyDirectoryExists:
def test_toy_dir_exists(self):
assert _TOY_DIR.is_dir()

def test_ranked_file_exists(self):
assert _RANKED_FILE.exists()

def test_cert_file_exists(self):
assert _CERT_FILE.exists()

def test_readme_exists(self):
assert _README_FILE.exists()

def test_toy_dir_has_files(self):
files = list(_TOY_DIR.iterdir())
assert len(files) >= 3


class TestToyReadme:
def test_readme_nonempty(self):
content = _README_FILE.read_text()
assert len(content) > 0

def test_readme_mentions_toy(self):
content = _README_FILE.read_text().lower()
assert "toy" in content

def test_readme_mentions_not_real(self):
content = _README_FILE.read_text()
assert "NOT" in content or "not real" in content.lower()

def test_readme_mentions_toy_ranked(self):
content = _README_FILE.read_text()
assert "toy_ranked_example" in content

def test_readme_mentions_toy_certificate(self):
content = _README_FILE.read_text()
assert "toy_certificate_example" in content

def test_readme_dry_lab_mentioned(self):
content = _README_FILE.read_text().lower()
assert "dry-lab" in content or "dry_lab" in content


class TestToyRankedFile:
def _load_lines(self):
lines = []
with _RANKED_FILE.open() as f:
for line in f:
line = line.strip()
if line:
lines.append(json.loads(line))
return lines

def test_file_is_valid_jsonl(self):
lines = self._load_lines()
assert len(lines) > 0

def test_has_multiple_candidates(self):
lines = self._load_lines()
assert len(lines) >= 2

def test_all_ids_have_toy_prefix(self):
lines = self._load_lines()
for obj in lines:
assert obj["candidate_id"].startswith("TOY-"), \
f"Expected TOY- prefix, got {obj['candidate_id']}"

def test_all_have_sequence_field(self):
lines = self._load_lines()
for obj in lines:
assert "sequence" in obj

def test_sequences_are_uppercase(self):
lines = self._load_lines()
for obj in lines:
assert obj["sequence"] == obj["sequence"].upper()

def test_sequences_are_nonempty(self):
lines = self._load_lines()
for obj in lines:
assert len(obj["sequence"]) > 0

def test_all_have_scores_field(self):
lines = self._load_lines()
for obj in lines:
assert "scores" in obj

def test_all_have_valid_field(self):
lines = self._load_lines()
for obj in lines:
assert "valid" in obj

def test_all_have_selected_field(self):
lines = self._load_lines()
for obj in lines:
assert "selected" in obj

def test_all_have_dry_lab_only_true(self):
lines = self._load_lines()
for obj in lines:
assert obj.get("dry_lab_only") is True

def test_all_have_known_failure_modes(self):
lines = self._load_lines()
for obj in lines:
assert "known_failure_modes" in obj
assert len(obj["known_failure_modes"]) > 0

def test_activity_score_in_range(self):
lines = self._load_lines()
for obj in lines:
score = obj["scores"]["activity"]
assert 0.0 <= score <= 1.0

def test_safety_score_in_range(self):
lines = self._load_lines()
for obj in lines:
score = obj["scores"]["safety"]
assert 0.0 <= score <= 1.0

def test_novelty_score_in_range(self):
lines = self._load_lines()
for obj in lines:
score = obj["scores"]["novelty"]
assert 0.0 <= score <= 1.0

def test_hemolysis_risk_in_range(self):
lines = self._load_lines()
for obj in lines:
score = obj["scores"]["hemolysis_risk"]
assert 0.0 <= score <= 1.0

def test_source_is_toy(self):
lines = self._load_lines()
for obj in lines:
assert obj.get("source") == "toy"

def test_no_real_ampf_ids(self):
lines = self._load_lines()
for obj in lines:
assert not obj["candidate_id"].startswith("AMPF-")

def test_selected_candidates_have_selection_reason(self):
lines = self._load_lines()
for obj in lines:
if obj["selected"]:
assert len(obj.get("selection_reason", [])) > 0

def test_failure_modes_mention_no_wet_lab(self):
lines = self._load_lines()
for obj in lines:
modes_text = " ".join(obj["known_failure_modes"]).lower()
assert "wet-lab" in modes_text or "assay" in modes_text


class TestToyCertificate:
def _load(self):
with _CERT_FILE.open() as f:
return json.load(f)

def test_cert_is_valid_json(self):
cert = self._load()
assert isinstance(cert, dict)

def test_cert_id_has_toy_prefix(self):
cert = self._load()
assert cert["cert_id"].startswith("TOY-")

def test_candidate_id_has_toy_prefix(self):
cert = self._load()
assert cert["candidate_id"].startswith("TOY-")

def test_dry_lab_only_is_true(self):
cert = self._load()
assert cert["dry_lab_only"] is True

def test_has_unsupported_claims(self):
cert = self._load()
assert "unsupported_claims" in cert
assert len(cert["unsupported_claims"]) > 0

def test_in_vitro_in_unsupported(self):
cert = self._load()
assert "in_vitro_activity" in cert["unsupported_claims"]

def test_in_vivo_in_unsupported(self):
cert = self._load()
assert "in_vivo_efficacy" in cert["unsupported_claims"]

def test_proof_ladder_level_present(self):
cert = self._load()
assert "proof_ladder_level" in cert

def test_proof_ladder_not_validated(self):
cert = self._load()
level = cert["proof_ladder_level"]
assert "clinical" not in level
assert "validated" not in level

def test_has_baseline_caveat(self):
cert = self._load()
assert "baseline_caveat" in cert
assert len(cert["baseline_caveat"]) > 0

def test_has_known_failure_modes(self):
cert = self._load()
assert "known_failure_modes" in cert
assert len(cert["known_failure_modes"]) > 0

def test_has_scores(self):
cert = self._load()
assert "scores" in cert

def test_has_sequence(self):
cert = self._load()
assert "sequence" in cert

def test_sequence_uppercase(self):
cert = self._load()
assert cert["sequence"] == cert["sequence"].upper()

def test_has_run_id(self):
cert = self._load()
assert "run_id" in cert

def test_run_id_toy_prefix(self):
cert = self._load()
assert cert["run_id"].startswith("TOY-")

def test_claim_class_present(self):
cert = self._load()
assert "claim_class" in cert

def test_claim_class_not_biological_proof(self):
cert = self._load()
claim = cert["claim_class"]
assert "biological_proof" not in claim
assert "validated" not in claim

def test_no_real_candidate_ids(self):
cert = self._load()
assert not cert["candidate_id"].startswith("AMPF-")
assert not cert["cert_id"].startswith("AMPF-")
Loading