Repository navigation
feat: add selectivity_proxy — cytotoxicity risk detector for Stage 2 (#47) - #47
Merged
Merged
Conversation
Addresses Stage 2 (Therapeutic Index) failure mode previously invisible to the pipeline. Peptides with charge <+2 or GRAVY >0.5 often fail mammalian cytotoxicity assays even when MIC is excellent. Changes: - physchem.py: new selectivity_proxy(charge, gravy) function [0,1]; added to compute_features() output dict - presynth_check.py: SynthQC gains selectivity_proxy float + cytotox_risk bool; HIGH_CYTOTOX_RISK informational flag (appended after difficulty is set) - order_generator.py: HIGH_CYTOTOX_RISK entry in _HANDLING_MAP with mammalian assay instructions (HC50/MTS) - Makefile: fix stale "814-test suite" comment to "1044-test suite" - docs/DISCOVERY_PREDICTION.md: Stage 2 updated to ~40-55% (+2-3 pp); combined probability updated to ~24-45% (up from ~22-43%) SEED-004 (temporin-like, GRAVY=+1.81, charge=+1.0) is correctly flagged HIGH_CYTOTOX_RISK — consistent with known hemolytic profile of hydrophobic short temporins (Carotenuto et al. 2008, J Med Chem). 37 new tests (1081 total). AUROC confirmed 0.811. Lint clean.
…y, imports, defaults - presynth_check.py: move selectivity_proxy imports to module level (was deferred; deferred imports are justified only to break circular dependencies, which do not exist here). Use physchem.net_charge_at_ph74() for consistency with compute_features() so the selectivity_proxy value is identical in both the feature dict and QC report. The old _net_charge_at_ph() included terminal groups/Cys/Tyr producing a ~0.2 offset that would give divergent cytotox verdicts for the same sequence. - SynthQC.selectivity_proxy default changed from 1.0 to 0.0 (conservative: assume cytotoxic until check_sequence() fills the field; 1.0 = safe default is misleading for a risk field) - physchem.py docstring: "optimum: +3 to +7" → "+2 to +7" (code awards full score starting at charge=2.0; the prior text contradicted the implementation and the test) - test_selectivity_proxy.py: add boundary test (selectivity_proxy=0.50 exactly must NOT trigger cytotox_risk since predicate is strict <0.5) - Makefile: update echo to "1081-test suite" → "1082-test suite" (38 new tests total)
This was referenced Jun 28, 2026
cschanhniem
added a commit
that referenced
this pull request
Jun 28, 2026
* docs: update METHODS.md to reflect all v0.2.x scoring changes - Section 4.1: expand activity-likeness formula to show all 7 terms (length, charge density at pH 7.4, hydrophobic fraction, aromatic bonus, amphipathicity, helix bonus weight 0.03, cross-term) with ceiling 0.97; note charge_density_ph74 preference - Section 4.2: add μH > 0.55 risk signal (Dathe 1999); update charge_density column to charge_density_ph74 with fallback note; tabulate all 6 risk signals with increments - Section 4.3: add proline penalty threshold (>15% → −0.10, DKP/Fmoc deprotection mechanism); tabulate aggregation penalty with ramp details - New Section 4.3b: serum stability score — protease site density model for trypsin (×2), chymotrypsin (×1), elastase (×0.5); score formula and literature basis - New Section 5.2: pilot panel selection — pilot_priority formula, cytotox_penalty for HIGH_CYTOTOX_RISK tier (proxy < 0.5), net selectivity swing +0.055 - Section 8: add retrospective AUROC 0.8164; table of v0.2.x PRs #47-54 with impact - Section 10: expand references from 4 to 17; add all citations used in scoring code * docs: fix 4 HIGH issues in synthesis feasibility table (code review PR #55) - Rename 'Long cysteine repeat run' → 'Long homo-repeat run (any AA)'; fix deduction from −0.15 to −0.10 flat (code: synthesis.py repeat_run >= 5 → score -= 0.10) - Fix cysteine fraction threshold from 0.15 to 0.20; fix deduction from scaled formula to −0.15 flat (code: cys > 0.20 → score -= 0.15) - Fix aggregation propensity trigger from >0.2 to >0.0; fix formula from 0.20×(prop−0.2)/0.8 to min(agg×0.25, 0.20) — linear ramp from zero, capped −0.20 - Add missing length penalties: length>30 (up to −0.40 ramp), length<8 (−0.30 flat) — the length>30 penalty is the largest single deduction possible; its absence from docs was a material omission - Fix 'five risk signals' → 'six' in safety score prose (μH signal added in PR #53) - Fix version header: 0.1.0 → 0.2.x with PR range note - Fix activity score ceiling: clarify it is the arithmetic maximum of weight sum (0.97), not an explicit min() cap — the code applies clamp01() which caps at 1.0
3 tasks done
cschanhniem
added a commit
that referenced
this pull request
Jun 28, 2026
* docs: update METHODS.md version tag and annotate 7-seed synthesis pool expansion The methods document was last updated for PRs #47-54. Since then the synthesis pool was expanded from 5 to 7 scaffold families (SEED-006 through SEED-009 in expansion PRs; SEED-001 re-entered in PR #72 via face_segregation_bonus). Changes: - Version line: "PRs #47-54" → "PRs #47-78" - Generation section: added blockquote note distinguishing the initial 5-seed benchmark run (383 variants, 87-candidate eval set, AUROC 0.8420) from the current 7-seed synthesis pool (100 candidates) - No scoring formulas or benchmark numbers changed * docs: fix AUROC attribution in METHODS.md 7-seed note AUROC 0.8420 was achieved in PR #72 (face_segregation_bonus), not in the initial 5-seed benchmark generation run. Clarify that the generation section describes the initial corpus and the AUROC figure reflects scoring improvements through PR #72. Also note that the 87-sequence eval set was finalized in PR #66.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
selectivity_proxyfeature incompute_features(): heuristic [0,1] score predicting likelihood of selective bacterial killing without mammalian cytotoxicity. Based on net charge (pH 7.4) and GRAVY — the two physicochemical axes most correlated with cytotoxicity in literature (Dathe & Wieprecht 1999 BBA; Shai 2002 BBA).HIGH_CYTOTOX_RISKinformational flag in presynth QC (SynthQC.cytotox_risk): fires whenselectivity_proxy < 0.5. Appended after synthesis difficulty is computed (does not inflate LOW→MODERATE→HIGH rating). Flag text includes specific assay instructions (HC50/MTS).order_generator.py_HANDLING_MAP: cytotox-flagged candidates get "Include mammalian cytotox assay (HC50/MTS); reduce MIC conc if cytotox" insynthesis_order.csv.FLPLIGRVLSGIL, temporin-like, GRAVY=+1.81, charge=+1.0) is correctly flagged — consistent with known hemolytic profile of hydrophobic short temporins (Carotenuto et al. 2008, J Med Chem 51:2279–2287). All other 7 seeds correctly pass (selective window).citarget comment corrected from "814-test suite" to "1044-test suite".import pytestintests/test_order_generator.py.Test plan
tests/test_selectivity_proxy.pycovering: charge edge cases (0, 1, 2, 7, 8, 12, negative), GRAVY edge cases (negative, 0, 0.5, 0.75, 1.0, >1.0), combined cases,compute_features()output key, presynth QC flag presence/absence,to_dict()fields, order generator handling mapmake validate-scoring→ 0.811 STRONG (confirmed before this PR)🤖 Generated with Claude Code