mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
231 lines
7.7 KiB
Python
231 lines
7.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
V4 Ablation Study
|
|
|
|
Re-runs the V4 simulation with three configurations:
|
|
1. Speed only (no pause, no exposure window, no contacts, no transient bias)
|
|
2. Speed + delay (pause and exposure window, but no contacts, no transient bias)
|
|
3. Speed + delay + transient bias + contacts (full V4)
|
|
|
|
This tests whether structural bias becomes significant in V4.
|
|
"""
|
|
|
|
import numpy as np
|
|
import json
|
|
from typing import List, Dict
|
|
from v4_cotranslational_simulator import (
|
|
V4CotranslationalSimulator, Codon, ExpertType, create_test_sequence
|
|
)
|
|
|
|
|
|
class V4AblationSimulator(V4CotranslationalSimulator):
|
|
"""Extended simulator with ablation modes"""
|
|
|
|
def __init__(
|
|
self,
|
|
sequence: List[Codon],
|
|
mode: str = "full", # "speed_only", "speed_delay", "full"
|
|
**kwargs
|
|
):
|
|
super().__init__(sequence, **kwargs)
|
|
self.mode = mode
|
|
|
|
def pause_field(self, t: float) -> float:
|
|
"""Override based on mode"""
|
|
if self.mode == "speed_only":
|
|
return 0.0 # No pause
|
|
return super().pause_field(t)
|
|
|
|
def exposed_segment(self, t: float):
|
|
"""Override based on mode"""
|
|
if self.mode == "speed_only":
|
|
# No exposure window - return all translated residues
|
|
m = self.visible_prefix_length(t)
|
|
return self.translated_residues[:m]
|
|
return super().exposed_segment(t)
|
|
|
|
def contact_probability(self, i: int, j: int, t: float) -> float:
|
|
"""Override based on mode"""
|
|
if self.mode in ["speed_only", "speed_delay"]:
|
|
return 0.0 # No contacts
|
|
return super().contact_probability(i, j, t)
|
|
|
|
def transient_bias(self, expert_type: ExpertType, t: float, window_size: int = 5) -> float:
|
|
"""Override based on mode"""
|
|
if self.mode in ["speed_only", "speed_delay"]:
|
|
return 0.0 # No transient bias
|
|
return super().transient_bias(expert_type, t, window_size)
|
|
|
|
def expert_weights(self, t: float) -> Dict[ExpertType, float]:
|
|
"""Override based on mode"""
|
|
if self.mode == "speed_only":
|
|
# Simplified: uniform weights
|
|
weights = {
|
|
ExpertType.HELIX: 0.33,
|
|
ExpertType.SHEET: 0.33,
|
|
ExpertType.LOOP: 0.34
|
|
}
|
|
return weights
|
|
return super().expert_weights(t)
|
|
|
|
|
|
def run_ablation_configuration(mode: str, sequence: List[Codon]) -> Dict:
|
|
"""Run simulation with specific ablation configuration"""
|
|
print(f"\n{'='*70}")
|
|
print(f"V4 ABLATION: {mode.upper()}")
|
|
print(f"{'='*70}")
|
|
|
|
sim = V4AblationSimulator(sequence, mode=mode, exposed_length=5)
|
|
|
|
# Run simulation
|
|
print(f"\nRunning simulation...")
|
|
print(f"{'Time':>8} | {'Translated':>10} | {'Exposed':>7} | {'Pause':>6} | {'Contact':>7} | {'Score':>6}")
|
|
print("-" * 70)
|
|
|
|
t = 0.0
|
|
dt = 0.5
|
|
max_time = 10.0
|
|
|
|
results = []
|
|
|
|
while t < max_time:
|
|
sim.step(dt)
|
|
|
|
m = sim.visible_prefix_length(t)
|
|
E = sim.exposed_segment(t)
|
|
P = sim.pause_field(t)
|
|
Pi = sim.get_contact_average(t)
|
|
score = sim.get_cds_score(t)
|
|
|
|
print(f"{t:8.2f} | {m:10d} | {len(E):7d} | {P:6.3f} | {Pi:7.3f} | {score:6.3f}")
|
|
|
|
results.append({
|
|
"time": t,
|
|
"translated": m,
|
|
"exposed": len(E),
|
|
"pause": P,
|
|
"contact": Pi,
|
|
"score": score
|
|
})
|
|
|
|
t += dt
|
|
|
|
# Summary statistics
|
|
final_score = results[-1]["score"]
|
|
avg_pause = np.mean([r["pause"] for r in results])
|
|
avg_contact = np.mean([r["contact"] for r in results])
|
|
score_std = np.std([r["score"] for r in results])
|
|
|
|
print(f"\nSummary for {mode}:")
|
|
print(f" Final CDS Score: {final_score:.4f}")
|
|
print(f" Average Pause Field: {avg_pause:.4f}")
|
|
print(f" Average Contact Probability: {avg_contact:.4f}")
|
|
print(f" Score Std Dev: {score_std:.4f}")
|
|
|
|
return {
|
|
"mode": mode,
|
|
"final_score": final_score,
|
|
"avg_pause": avg_pause,
|
|
"avg_contact": avg_contact,
|
|
"score_std": score_std,
|
|
"trajectory": results
|
|
}
|
|
|
|
|
|
def run_ablation_study():
|
|
"""Run full ablation study comparing all configurations"""
|
|
print("=" * 70)
|
|
print("V4 ABLATION STUDY")
|
|
print("=" * 70)
|
|
print("\nComparing three configurations:")
|
|
print("1. Speed only (baseline)")
|
|
print("2. Speed + delay (pause and exposure window)")
|
|
print("3. Speed + delay + transient bias + contacts (full V4)")
|
|
|
|
# Create test sequence
|
|
sequence = create_test_sequence()
|
|
print(f"\nCreated test sequence with {len(sequence)} codons")
|
|
|
|
# Run all configurations
|
|
results = {}
|
|
|
|
results["speed_only"] = run_ablation_configuration("speed_only", sequence)
|
|
results["speed_delay"] = run_ablation_configuration("speed_delay", sequence)
|
|
results["full"] = run_ablation_configuration("full", sequence)
|
|
|
|
# Compare results
|
|
print("\n" + "=" * 70)
|
|
print("ABLATION STUDY RESULTS")
|
|
print("=" * 70)
|
|
|
|
print(f"\n{'Configuration':>20} | {'Final Score':>12} | {'Avg Pause':>10} | {'Avg Contact':>13} | {'Score Std':>11}")
|
|
print("-" * 70)
|
|
|
|
for mode, data in results.items():
|
|
print(f"{mode:>20} | {data['final_score']:12.4f} | {data['avg_pause']:10.4f} | {data['avg_contact']:13.4f} | {data['score_std']:11.4f}")
|
|
|
|
# Analysis
|
|
print("\n" + "=" * 70)
|
|
print("ANALYSIS")
|
|
print("=" * 70)
|
|
|
|
speed_only_score = results["speed_only"]["final_score"]
|
|
speed_delay_score = results["speed_delay"]["final_score"]
|
|
full_score = results["full"]["final_score"]
|
|
|
|
speed_delay_delta = speed_delay_score - speed_only_score
|
|
full_delta = full_score - speed_only_score
|
|
|
|
print(f"\nScore Changes:")
|
|
print(f" Speed only → Speed+Delay: {speed_delay_delta:+.4f}")
|
|
print(f" Speed only → Full V4: {full_delta:+.4f}")
|
|
|
|
# Contact effect
|
|
contact_only_delta = full_score - speed_delay_score
|
|
print(f" Speed+Delay → Full V4: {contact_only_delta:+.4f} (contact + bias effect)")
|
|
|
|
# Interpretation
|
|
print("\nInterpretation:")
|
|
|
|
if abs(speed_delay_delta) < 0.01:
|
|
print(" - Pause/exposure window has minimal effect on score")
|
|
elif speed_delay_delta > 0:
|
|
print(" - Pause/exposure window improves score")
|
|
else:
|
|
print(" - Pause/exposure window reduces score")
|
|
|
|
if abs(contact_only_delta) < 0.01:
|
|
print(" - Contacts + transient bias have minimal effect")
|
|
elif contact_only_delta > 0:
|
|
print(" - Contacts + transient bias improve score")
|
|
print(" - This suggests structural bias is becoming significant in V4")
|
|
else:
|
|
print(" - Contacts + transient bias reduce score")
|
|
|
|
# Variance analysis
|
|
speed_only_std = results["speed_only"]["score_std"]
|
|
full_std = results["full"]["score_std"]
|
|
|
|
if full_std > speed_only_std:
|
|
print(f" - Full V4 increases score variance ({speed_only_std:.4f} → {full_std:.4f})")
|
|
print(" - This suggests cotranslational dynamics create more diverse trajectories")
|
|
else:
|
|
print(f" - Full V4 reduces score variance ({speed_only_std:.4f} → {full_std:.4f})")
|
|
print(" - This suggests cotranslational dynamics stabilize trajectories")
|
|
|
|
print("\n" + "=" * 70)
|
|
print("ABLATION STUDY COMPLETE")
|
|
print("=" * 70)
|
|
|
|
return results
|
|
|
|
|
|
if __name__ == "__main__":
|
|
results = run_ablation_study()
|
|
|
|
# Save results
|
|
output_path = "/home/allaun/Documents/Research Stack/data/v4_ablation_study_results.json"
|
|
with open(output_path, "w") as f:
|
|
json.dump(results, f, indent=2)
|
|
|
|
print(f"\nResults saved to: {output_path}")
|