Repository navigation
feat: Trp-weighted aromatic bonus + safety abs() fix + scoring accuracy - #65
Merged
Merged
Conversation
…racy Scoring changes (PR #65): - activity.py: Trp weighted 1.5× vs Phe/Tyr in aromatic_bonus; indole ring anchors at lipid-water interface (Wimley-White W=-1.85 kcal/mol) — uniquely membrane-favorable vs Phe's hydrophobic stacking. Differentiates puroindoline- a/indolicidin class from Phe-rich peptides. - safety.py: remove abs() from charge_density — negatively charged peptides are electrostatically repelled from membranes and pose no hemolysis risk; only positive charge_density > 0.55 should trigger the penalty - boman.py: move `import math` from inside function to module top level - physchem.py: fix Eisenberg scale comment (values are signed [-2.53..+1.38], NOT shifted to [0,1]; the signed values are required for μH calculation) - physchem.py: document N/C terminus charge omission in net_charge_at_ph74 Benchmark impact: - pipeline.yaml AUROC: 0.8164 → 0.8086 (within bootstrap CI; caused by random- background decoys containing Trp benefiting from the bonus — scientific trade-off) - phase3.yaml AUROC: 0.7936 → 0.7890; both still STRONG (> 0.70 gate) Synthesis pool update: - SEED-006: 11 → 10 selected; SEED-009: 18 → 19 selected (pool regenerated from make phase3 with updated scoring); same 6 scaffold families, 100 total Tests: 1185 passing; safety test updated to assert correct behavior (negative charge should not trigger hemolysis penalty)
- TestTrpWeightedAromaticBonus: 6 new tests covering the residue_counts code path - Trp-rich outscore Phe-rich at same aromatic fraction - 1.5x multiplier is quantitatively verified (delta ≈ 0.025 at 10% aromatic) - Ceiling still 0.10 regardless of how high Trp fraction goes - No residue_counts fallback produces same result as all-Phe (correct) - Mixed Trp/Phe scores between all-W and all-F - Documents saturation behaviour: bonus only differentiates below ~13% Trp - Update test_scoring_activity.py docstring to show Trp-weighted formula - Fix stale |cd| comment in test_scoring_safety.py (abs() removed)
cschanhniem
added a commit
that referenced
this pull request
Jun 28, 2026
cschanhniem
added a commit
that referenced
this pull request
Jun 28, 2026
* chore: update ROADMAP.md with current metrics, add coverage gate to make coverage - AUROC 0.8164→0.8420 (bootstrap CI₉₅: 0.76–0.91) in v0.4 milestone entry - Add v0.6.x section documenting PRs #61–#72 scoring improvements - Mark AUPRC gap as Done (PR #58, pipeline AUPRC=0.8627) - Update large-scale benchmark gap row with corrected n=87 and CI - coverage target: add --cov-fail-under=80 so make coverage exits non-zero below 80%; currently passes at 87.40% * docs: fix v0.6.x chain gap (add PR #65) and AUPRC attribution
cschanhniem
added a commit
that referenced
this pull request
Jun 28, 2026
…ocstring (#95) - presynth_check.py: His pKa corrected 6.0→6.5 (Bjellqvist 1993) to match physchem.py — divergent pI/charge estimates for His-rich peptides are now consistent across both modules - METHODS.md: remove stale claim that safety.py falls back to abs(charge_density); the abs() was removed in PR #65 — anionic peptides now correctly receive safety=1.0 (no hemolysis concern from electrostatically repelled sequences) - ensemble.py: add docstring to ensemble_score() documenting default and phase3 config weights so they are discoverable without reading YAML files
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
Deep scientific review identified three scoring issues and two documentation accuracy problems.
Scoring Fixes
Trp-weighted aromatic bonus (
activity.py): Trp is now weighted 1.5× vs Phe/Tyr in the aromatic_bonus calculation. Justification: Trp's indole ring preferentially anchors at the lipid-water interface (Wimley-White W=−1.85 kcal/mol vs Eisenberg W=+0.81), a mechanism distinct from and more membrane-favorable than Phe's hydrophobic stacking. Previously, indolicidin-class (5 Trp) scored the same as an equivalent Phe-rich sequence, which is scientifically incorrect. SEED-008 (puroindoline-a) benefits from this fix.Safety
abs()bug fix (safety.py): Removedabs()from the charge_density hemolysis check. Negatively charged peptides are electrostatically repelled from both bacterial and mammalian membranes — they cannot cause hemolysis. The comment claimed "charge magnitude drives hemolysis risk" which is wrong: only positive charge density > 0.55 drives hemolysis. The old code would incorrectly penalize a negatively charged peptide's safety score.import mathstyle fix (boman.py): Moved to module top level from insideboman_activity_score().Eisenberg scale comment fix (
physchem.py): Removed false claim that values are "shifted to 0..1 range." The values are raw signed (R=−2.53 to I=+1.38). The signed values are required for the hydrophobic moment calculation. A future developer reading "shifted to 0..1" might "fix" this by renormalizing and break μH.N/C terminus docstring (
physchem.py): Documented that terminal charges (−0.20 net/peptide) are excluded fromnet_charge_at_ph74, a known convention.Benchmark Impact
Synthesis Pool Update
Regenerated
make phase3with updated scoring: SEED-006: 11→10, SEED-009: 18→19. Same 6 scaffold families, 100 total candidates.Test plan
test_negative_charge_density_no_hemolysis_penalty— verifies corrected safety behaviortest_phase3_benchmark_passes_gate— AUROC=0.7890 passes ≥ 0.75 regression sentinelmake validate-scoring-phase3→ AUROC=0.7890 STRONGmake validate-scoring→ AUROC=0.8086 STRONGmake phase3regenerated pool with 100 candidates across 6 families🤖 Generated with Claude Code