Repository navigation
feat: aggregation-safe mutation generation + balanced K/R charge variants - #50
Merged
Merged
Conversation
…ants + SynthQC continuous agg score Generator, scorer, and QC now use the same aggregation threshold (VILMFW run >= 4) consistently: - generate_aggregation_safe_double_variants(): filters double substitutions that would create hydrophobic runs >= 4 before they enter the candidate pool, preventing the generator from producing sequences immediately penalised by synthesis_feasibility_score() - generate_balanced_charge_variants(): generates both K and R replacements at each S/T/N/Q position, giving the pipeline twice as many charge-enhanced options to rank by selectivity (K KD=-3.9 vs R KD=-4.5 differ in GRAVY; scoring picks the best one per seed profile) - generate_all_variants() now uses both new functions; old functions preserved for compat - SynthQC.aggregation_propensity_score: float [0,1] field added to SynthQC dataclass and to_dict(), providing continuous gradient information alongside aggregation_risk boolean - _max_hydrophobic_run() helper; _AGG_HYDROPHOBIC constant matching physchem.py 33 new tests; 1124 -> 1157 total passing
HIGH: Single-substitution variants now filtered in generate_all_variants() with _max_hydrophobic_run(v) < 4, same as double-substitution path. A seed with run=3 and adjacent A/Y (conservative aliphatic group members) could produce run=4 singles; added test with KVLLAK borderline seed to verify the filter catches KVLLLK. MEDIUM: Import _AGG_HYDROPHOBIC from physchem.AGG_HYDROPHOBIC instead of duplicating the constant — single source of truth, cross-module consistency guaranteed by the import rather than a manual comment. Fixed aggregation_propensity() docstring: "Ramp: 0.0 at run=4" corrected to "0.20 at run=4" (formula (max_run-3)/5.0 gives 0.20, not 0.0). LOW: generate_balanced_charge_variants() n_samples parameter renamed to n_positions for API clarity (n_samples caps total output in other generators; here it caps positions targeted, yielding up to 2×n_positions sequences). Added deprecation note to generate_charge_enhanced_variants(). Fixed trivial test assertion in test_generates_both_k_and_r_per_position to use direct variant lookup rather than fallback any() clauses that always passed. 1157 → 1158 tests
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
Closes the divergence between generator, scorer, and QC layers — all three now use the same VILMFW-run-≥4 aggregation threshold:
generate_aggregation_safe_double_variants(): filters double substitutions that would create hydrophobic runs ≥4 residues. Previously, the generator could produce sequences thatsynthesis_feasibility_score()immediately penalised — now they're filtered at the source. Attempt budget raised to 50× to handle hydrophobic seeds.generate_balanced_charge_variants(): generates both K and R replacements at each polar (S/T/N/Q) position. Oldgenerate_charge_enhanced_variants()randomly picked one; now both are generated so the scoring pipeline can select the better GRAVY/selectivity profile automatically (K KD=−3.9, R KD=−4.5).generate_all_variants(): updated to use the new safe functions by default; old functions preserved for backward compatibility.SynthQC.aggregation_propensity_score: float: continuous [0,1] aggregation score added toSynthQCdataclass andto_dict(), fromphyschem.aggregation_propensity(). Provides gradient information alongside the existing booleanaggregation_riskflag — operators can now distinguish score 0.14 (one run-of-4) from 0.70 (run-of-8) rather than seeing both as a generic boolean True._max_hydrophobic_run()helper and_AGG_HYDROPHOBICconstant added totemplate_mutator.py, explicitly matchingAGG_HYDROPHOBICinphyschem.py.Test plan
tests/test_aggregation_safe_mutations.py: 33 new tests covering_max_hydrophobic_run(),generate_aggregation_safe_double_variants(),generate_balanced_charge_variants(),generate_all_variants()no-run guarantee, andSynthQC.aggregation_propensity_scoreruff check src tests: cleangenerate_double_substitution_variants()andgenerate_charge_enhanced_variants()still exported and tested🤖 Generated with Claude Code