Research-Stack/5-Applications/scripts/codon_peptide_coupling_toy.py

468 lines
16 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
Codon-Peptide Coupling Toy Run
This script couples:
- codon RL over synonymous choices
- codon → amino acid translation
- amino-acid-implied peptide expert field
- peptide scoring at the CDS level
Demonstrates the integration between CodonOTOM efficiency functional
and the PeptideMoE system at the peptide level.
"""
import numpy as np
import matplotlib.pyplot as plt
from typing import List, Tuple, Dict
from dataclasses import dataclass
from collections import defaultdict
# ============================================================================
# Genetic Code (Simplified)
# ============================================================================
# Simplified genetic code mapping (codon → amino acid)
GENETIC_CODE = {
# Phenylalanine (2-fold degenerate)
'UUU': 'F', 'UUC': 'F',
# Leucine (6-fold degenerate)
'UUA': 'L', 'UUG': 'L', 'CUU': 'L', 'CUC': 'L', 'CUA': 'L', 'CUG': 'L',
# Isoleucine (3-fold degenerate)
'AUU': 'I', 'AUC': 'I', 'AUA': 'I',
# Methionine (1-fold degenerate - start)
'AUG': 'M',
# Valine (4-fold degenerate)
'GUU': 'V', 'GUC': 'V', 'GUA': 'V', 'GUG': 'V',
# Serine (6-fold degenerate)
'UCU': 'S', 'UCC': 'S', 'UCA': 'S', 'UCG': 'S', 'AGU': 'S', 'AGC': 'S',
# Proline (4-fold degenerate)
'CCU': 'P', 'CCC': 'P', 'CCA': 'P', 'CCG': 'P',
# Threonine (4-fold degenerate)
'ACU': 'T', 'ACC': 'T', 'ACA': 'T', 'ACG': 'T',
# Alanine (4-fold degenerate)
'GCU': 'A', 'GCC': 'A', 'GCA': 'A', 'GCG': 'A',
# Tyrosine (2-fold degenerate)
'UAU': 'Y', 'UAC': 'Y',
# Histidine (2-fold degenerate)
'CAU': 'H', 'CAC': 'H',
# Glutamine (2-fold degenerate)
'CAA': 'Q', 'CAG': 'Q',
# Asparagine (2-fold degenerate)
'AAU': 'N', 'AAC': 'N',
# Lysine (2-fold degenerate)
'AAA': 'K', 'AAG': 'K',
# Aspartic acid (2-fold degenerate)
'GAU': 'D', 'GAC': 'D',
# Glutamic acid (2-fold degenerate)
'GAA': 'E', 'GAG': 'E',
# Cysteine (2-fold degenerate)
'UGU': 'C', 'UGC': 'C',
# Tryptophan (1-fold degenerate)
'UGG': 'W',
# Arginine (6-fold degenerate)
'CGU': 'R', 'CGC': 'R', 'CGA': 'R', 'CGG': 'R', 'AGA': 'R', 'AGG': 'R',
# Glycine (4-fold degenerate)
'GGU': 'G', 'GGC': 'G', 'GGA': 'G', 'GGG': 'G',
# Stop codons (3-fold)
'UAA': '*', 'UAG': '*', 'UGA': '*'
}
# Degeneracy mapping (number of codons per amino acid)
DEGENERACY = {
'F': 2, 'L': 6, 'I': 3, 'M': 1, 'V': 4, 'S': 6, 'P': 4, 'T': 4, 'A': 4,
'Y': 2, 'H': 2, 'Q': 2, 'N': 2, 'K': 2, 'D': 2, 'E': 2, 'C': 2, 'W': 1,
'R': 6, 'G': 4, '*': 3
}
# ============================================================================
# Codon Efficiency Functional (CodonOTOM)
# ============================================================================
@dataclass
class CodonFeatures:
"""Local feature signals for a codon."""
rho: float # triplet consistency [0,1]
q: float # conservation [0,1]
tau: float # translation efficiency [0,1]
H: float # entropy [0,1]
eps: float # mutation penalty [0,1]
@dataclass
class CodonWeights:
"""Weight parameters for codon efficiency."""
w_rho: float
w_q: float
w_tau: float
w_H: float
w_eps: float
lambda_: float
C0: float
def phi_codon(w: CodonWeights, f: CodonFeatures, codon: str) -> float:
"""
Codon efficiency functional Φ_codon(c).
Φ_codon(c) = (w_ρ·ρ̂ + w_q·q̂ + w_τ·τ̂ - w_H·Ĥ - w_ε·ε̂) / (ln 64 + λ ln d(c) + C_0)
"""
aa = GENETIC_CODE.get(codon, 'X')
d = DEGENERACY.get(aa, 1)
numerator = (
w.w_rho * f.rho +
w.w_q * f.q +
w.w_tau * f.tau -
w.w_H * f.H -
w.w_eps * f.eps
)
denominator = np.log(64) + w.lambda_ * np.log(d) + w.C0
return numerator / denominator
# ============================================================================
# Peptide-Level Properties (Simplified PeptideMoE)
# ============================================================================
@dataclass
class PeptideState:
"""Simplified peptide state for toy run."""
sequence: str # amino acid sequence
structural_coherence: float # [0,1]
free_energy: float # kcal/mol
def peptide_efficiency(peptide: PeptideState, c0: float = 1.0) -> float:
"""
Peptide efficiency (simplified from PeptideMoE).
Φ_peptide = structural_coherence / (free_energy + c0)
"""
return peptide.structural_coherence / (peptide.free_energy + c0)
# ============================================================================
# Codon RL over Synonymous Choices
# ============================================================================
def get_synonymous_codons(codon: str) -> List[str]:
"""Get all synonymous codons for a given codon."""
aa = GENETIC_CODE.get(codon, 'X')
if aa == 'X':
return [codon]
return [c for c, a in GENETIC_CODE.items() if a == aa]
def codon_rl_step(current_codon: str, w: CodonWeights, f: CodonFeatures) -> Tuple[str, float]:
"""
RL step: select best synonymous codon based on Φ_codon.
Returns: (best_codon, delta_efficiency)
"""
current_phi = phi_codon(w, f, current_codon)
synonymous = get_synonymous_codons(current_codon)
best_codon = current_codon
best_phi = current_phi
for codon in synonymous:
phi = phi_codon(w, f, codon)
if phi > best_phi:
best_codon = codon
best_phi = phi
delta_phi = best_phi - current_phi
return best_codon, delta_phi
# ============================================================================
# Amino Acid → Peptide Expert Field
# ============================================================================
def amino_acid_to_expert_field(aa: str) -> Dict[str, float]:
"""
Map amino acid to simplified expert field properties.
This represents the amino-acid-implied peptide expert field
that influences peptide-level properties.
"""
# Simplified physicochemical properties
properties = {
'hydrophobicity': 0.0,
'charge': 0.0,
'size': 0.0,
'flexibility': 0.0
}
# Hydrophobicity (Kyte-Doolittle scale, normalized)
hydrophobicity = {
'I': 0.9, 'V': 0.8, 'L': 0.8, 'F': 0.7, 'C': 0.6,
'M': 0.5, 'A': 0.4, 'G': 0.3, 'T': 0.2, 'S': 0.2,
'W': 0.2, 'Y': 0.1, 'P': 0.0, 'H': 0.0, 'E': -0.1,
'Q': -0.1, 'D': -0.2, 'N': -0.2, 'K': -0.3, 'R': -0.3
}
# Charge at pH 7
charge = {
'R': 1.0, 'K': 1.0, 'H': 0.5, 'D': -1.0, 'E': -1.0,
'C': 0.0, 'M': 0.0, 'F': 0.0, 'I': 0.0, 'L': 0.0,
'V': 0.0, 'W': 0.0, 'Y': 0.0, 'A': 0.0, 'G': 0.0,
'T': 0.0, 'S': 0.0, 'P': 0.0, 'Q': 0.0, 'N': 0.0
}
# Size (normalized)
size = {
'W': 1.0, 'R': 0.9, 'Y': 0.8, 'F': 0.8, 'K': 0.7,
'E': 0.7, 'Q': 0.7, 'M': 0.6, 'H': 0.6, 'L': 0.6,
'I': 0.6, 'D': 0.5, 'N': 0.5, 'T': 0.5, 'V': 0.5,
'S': 0.4, 'C': 0.4, 'A': 0.3, 'G': 0.2, 'P': 0.5
}
# Flexibility (normalized)
flexibility = {
'G': 1.0, 'S': 0.9, 'A': 0.8, 'P': 0.7, 'D': 0.6,
'N': 0.6, 'T': 0.5, 'K': 0.5, 'E': 0.5, 'Q': 0.5,
'R': 0.4, 'H': 0.4, 'M': 0.4, 'L': 0.4, 'I': 0.3,
'V': 0.3, 'F': 0.3, 'Y': 0.3, 'W': 0.2, 'C': 0.2
}
properties['hydrophobicity'] = hydrophobicity.get(aa, 0.0)
properties['charge'] = charge.get(aa, 0.0)
properties['size'] = size.get(aa, 0.0)
properties['flexibility'] = flexibility.get(aa, 0.0)
return properties
# ============================================================================
# CDS-Level Scoring
# ============================================================================
def cds_to_peptide(cds_sequence: str) -> str:
"""Translate CDS (codon sequence) to peptide."""
peptide = []
for i in range(0, len(cds_sequence), 3):
codon = cds_sequence[i:i+3]
aa = GENETIC_CODE.get(codon, 'X')
if aa == '*':
break # Stop codon
peptide.append(aa)
return ''.join(peptide)
def compute_peptide_properties(peptide: str) -> PeptideState:
"""
Compute peptide-level properties from amino acid sequence.
This aggregates the amino acid expert fields to produce
peptide-level structural_coherence and free_energy.
"""
if not peptide:
return PeptideState("", 0.0, 100.0)
# Aggregate amino acid properties
total_hydro = 0.0
total_charge = 0.0
total_size = 0.0
total_flex = 0.0
for aa in peptide:
props = amino_acid_to_expert_field(aa)
total_hydro += props['hydrophobicity']
total_charge += props['charge']
total_size += props['size']
total_flex += props['flexibility']
n = len(peptide)
avg_hydro = total_hydro / n
avg_charge = abs(total_charge) / n # Magnitude of charge
avg_size = total_size / n
avg_flex = total_flex / n
# Simplified peptide efficiency model
# Structural coherence: higher with balanced hydrophobicity and flexibility
structural_coherence = 0.5 * (1.0 - abs(avg_hydro)) + 0.3 * avg_flex + 0.2 * (1.0 - avg_charge)
structural_coherence = np.clip(structural_coherence, 0.0, 1.0)
# Free energy: higher with unbalanced properties
free_energy = 10.0 + 5.0 * abs(avg_hydro) + 3.0 * avg_charge + 2.0 * avg_size
return PeptideState(peptide, structural_coherence, free_energy)
# ============================================================================
# Toy Run
# ============================================================================
def run_toy_simulation():
"""Run toy simulation of codon RL coupling with peptide scoring."""
print("=" * 70)
print("CODON-PEPTIDE COUPLING TOY RUN")
print("=" * 70)
# Toy parameters
w = CodonWeights(
w_rho=0.3,
w_q=0.25,
w_tau=0.25,
w_H=0.1,
w_eps=0.1,
lambda_=0.5,
C0=1.0
)
# Initial CDS sequence (toy example)
initial_cds = "AUGUUUUAACUUUGGAAAUU" # MFLFGN (partial)
print(f"\nInitial CDS: {initial_cds}")
print(f"Initial peptide: {cds_to_peptide(initial_cds)}")
# Compute initial peptide properties
initial_peptide = compute_peptide_properties(cds_to_peptide(initial_cds))
initial_peptide_phi = peptide_efficiency(initial_peptide)
print(f"\nInitial peptide properties:")
print(f" Structural coherence: {initial_peptide.structural_coherence:.3f}")
print(f" Free energy: {initial_peptide.free_energy:.3f} kcal/mol")
print(f" Peptide efficiency: {initial_peptide_phi:.3f}")
# Codon RL optimization
print("\n" + "=" * 70)
print("CODON RL OPTIMIZATION")
print("=" * 70)
optimized_cds = initial_cds
total_delta_phi_codon = 0.0
for i in range(0, len(initial_cds), 3):
codon = initial_cds[i:i+3]
if len(codon) < 3:
break
# Toy features (would be computed from actual data)
f = CodonFeatures(
rho=0.7, # high triplet consistency
q=0.6, # moderate conservation
tau=0.8, # high translation efficiency
H=0.3, # low entropy
eps=0.1 # low mutation penalty
)
best_codon, delta_phi = codon_rl_step(codon, w, f)
if best_codon != codon:
print(f" Codon {i//3+1}: {codon}{best_codon} (ΔΦ_codon = {delta_phi:+.4f})")
optimized_cds = optimized_cds[:i] + best_codon + optimized_cds[i+3:]
total_delta_phi_codon += delta_phi
else:
print(f" Codon {i//3+1}: {codon} (already optimal)")
print(f"\nTotal ΔΦ_codon improvement: {total_delta_phi_codon:+.4f}")
# Compute optimized peptide properties
optimized_peptide = compute_peptide_properties(cds_to_peptide(optimized_cds))
optimized_peptide_phi = peptide_efficiency(optimized_peptide)
print("\n" + "=" * 70)
print("OPTIMIZED PEPTIDE PROPERTIES")
print("=" * 70)
print(f"\nOptimized CDS: {optimized_cds}")
print(f"Optimized peptide: {cds_to_peptide(optimized_cds)}")
print(f"\nOptimized peptide properties:")
print(f" Structural coherence: {optimized_peptide.structural_coherence:.3f}")
print(f" Free energy: {optimized_peptide.free_energy:.3f} kcal/mol")
print(f" Peptide efficiency: {optimized_peptide_phi:.3f}")
# Compare
peptide_delta_phi = optimized_peptide_phi - initial_peptide_phi
print("\n" + "=" * 70)
print("SUMMARY")
print("=" * 70)
print(f"\nCodon-level improvement: ΔΦ_codon = {total_delta_phi_codon:+.4f}")
print(f"Peptide-level improvement: ΔΦ_peptide = {peptide_delta_phi:+.4f}")
if peptide_delta_phi > 0:
print(f"\n✅ Codon optimization improved peptide efficiency by {peptide_delta_phi:.2%}")
elif peptide_delta_phi < 0:
print(f"\n⚠️ Codon optimization decreased peptide efficiency by {abs(peptide_delta_phi):.2%}")
else:
print(f"\n→ Codon optimization had no effect on peptide efficiency")
return {
'initial_cds': initial_cds,
'optimized_cds': optimized_cds,
'initial_peptide_phi': initial_peptide_phi,
'optimized_peptide_phi': optimized_peptide_phi,
'codon_delta_phi': total_delta_phi_codon,
'peptide_delta_phi': peptide_delta_phi
}
def visualize_results(results: Dict):
"""Visualize the toy run results."""
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
fig.suptitle('Codon-Peptide Coupling Toy Run Results', fontsize=16)
# Plot 1: Efficiency comparison
ax1 = axes[0, 0]
efficiencies = [results['initial_peptide_phi'], results['optimized_peptide_phi']]
labels = ['Initial', 'Optimized']
colors = ['lightcoral', 'lightblue']
ax1.bar(labels, efficiencies, color=colors)
ax1.set_ylabel('Peptide Efficiency Φ_peptide')
ax1.set_title('Peptide Efficiency Comparison')
ax1.set_ylim([0, max(efficiencies) * 1.2])
for i, v in enumerate(efficiencies):
ax1.text(i, v + 0.01, f'{v:.3f}', ha='center')
# Plot 2: Delta efficiency
ax2 = axes[0, 1]
deltas = [results['codon_delta_phi'], results['peptide_delta_phi']]
labels = ['Codon Level', 'Peptide Level']
colors = ['green' if d > 0 else 'red' for d in deltas]
ax2.bar(labels, deltas, color=colors)
ax2.set_ylabel('ΔΦ')
ax2.set_title('Efficiency Improvement')
ax2.axhline(y=0, color='black', linestyle='--', linewidth=0.5)
for i, v in enumerate(deltas):
ax2.text(i, v + (0.01 if v > 0 else -0.02), f'{v:+.4f}', ha='center')
# Plot 3: Codon optimization steps
ax3 = axes[1, 0]
initial_peptide = cds_to_peptide(results['initial_cds'])
optimized_peptide = cds_to_peptide(results['optimized_cds'])
# Show amino acid sequence
ax3.text(0.5, 0.7, f'Initial: {initial_peptide}', ha='center', fontsize=12,
bbox=dict(boxstyle='round', facecolor='lightcoral', alpha=0.5))
ax3.text(0.5, 0.3, f'Optimized: {optimized_peptide}', ha='center', fontsize=12,
bbox=dict(boxstyle='round', facecolor='lightblue', alpha=0.5))
ax3.set_xlim([0, 1])
ax3.set_ylim([0, 1])
ax3.axis('off')
ax3.set_title('Amino Acid Sequences')
# Plot 4: Coupling diagram
ax4 = axes[1, 1]
ax4.text(0.5, 0.8, 'Codon RL', ha='center', fontsize=10, fontweight='bold',
bbox=dict(boxstyle='round', facecolor='lightgreen', alpha=0.7))
ax4.text(0.5, 0.6, '', ha='center', fontsize=20)
ax4.text(0.5, 0.4, 'Codon → AA Translation', ha='center', fontsize=10, fontweight='bold',
bbox=dict(boxstyle='round', facecolor='lightyellow', alpha=0.7))
ax4.text(0.5, 0.2, '', ha='center', fontsize=20)
ax4.text(0.5, 0.0, 'Peptide Scoring', ha='center', fontsize=10, fontweight='bold',
bbox=dict(boxstyle='round', facecolor='lightblue', alpha=0.7))
ax4.set_xlim([0, 1])
ax4.set_ylim([-0.1, 0.9])
ax4.axis('off')
ax4.set_title('Coupling Flow')
plt.tight_layout()
# Save figure
output_file = '/home/allaun/Documents/Research Stack/data/codon_peptide_coupling_toy.png'
plt.savefig(output_file, dpi=150, bbox_inches='tight')
print(f"\nVisualization saved to: {output_file}")
plt.show()
if __name__ == "__main__":
results = run_toy_simulation()
visualize_results(results)