🧪 The Virtual CD Lab: Circular Dichroism Spectroscopy¶
Welcome to the Virtual Circular Dichroism (CD) Lab!
Circular Dichroism is the premier biophysical tool for rapidly assessing the overall secondary structure and folding state of a protein. Unlike NMR or X-ray crystallography, which can take weeks to yield results, a CD spectrum can be recorded in minutes, making it the 'first-line' experiment in any structural biology project.
🎯 Learning Goals¶
- Understand the Amide Chromophore: How the peptide bond interacts with circularly polarized light.
- Recognize Spectral Signatures: Identify Alpha-helices, Beta-sheets, and Random Coils by their characteristic curves.
- Synthesis and Deconvolution: Learn how a complex protein spectrum is built from basic 'basis spectra'.
- Scientific Benchmarking: Compare synthetic models against the foundational standards of Greenfield & Fasman (1969).
# 🛠️ SETUP: Install dependencies (Auto-Restart Mode)
import os
import sys
if not os.path.exists("installed.marker"):
try:
import google.colab
IN_COLAB = True
except ImportError:
IN_COLAB = False
if IN_COLAB:
print("🛡️ Setting up environment...")
!pip install -q biotite numpy matplotlib ipywidgets py3Dmol synth-nmr
!pip install -q --no-deps git+https://github.com/elkins/synth-pdb.git@master
with open("installed.marker", "w") as f: f.write("done")
print("✅ Setup Complete. Please restart the runtime if this is your first run.")
else:
print("💻 Running in local environment.")
🎓 Part 1: The Physics of Chirality¶
Proteins are chiral molecules. This means they lack an internal plane of symmetry. In the far-UV region (190–250 nm), the chiral arrangement of peptide bonds leads to a phenomenon called Circular Dichroism: the differential absorption of Left-handed (L) and Right-handed (R) circularly polarized light.
The signal we measure is the Molar Ellipticity [θ]: $$ [θ] = 3298 (\epsilon_L - \epsilon_R) $$
Why Secondary Structure Matters¶
If a protein was just a string of independent amino acids, the CD signal would be weak. However, in an Alpha-helix or Beta-sheet, the transition dipoles of neighboring amide groups are coupled (excitonic coupling). This coupling creates the giant, characteristic 'valley' and 'peak' signatures we use to identify structure.
import numpy as np
import matplotlib.pyplot as plt
import ipywidgets as widgets
from IPython.display import display
from synth_pdb.cd_simulator import CDSimulator, BASIS_SPECTRA, WAVELENGTHS
from synth_pdb.generator import generate_pdb_content
from biotite.structure.io.pdb import PDBFile
import io
def simulate_protein_cd(helix_pct, sheet_pct):
coil_pct = 1.0 - helix_pct - sheet_pct
if coil_pct < 0:
print("⚠️ Error: Fractions must sum to 100% or less!")
return
# Combine basis spectra
total_spectrum = (helix_pct * BASIS_SPECTRA['H'] +
sheet_pct * BASIS_SPECTRA['E'] +
coil_pct * BASIS_SPECTRA['C'])
plt.figure(figsize=(10, 6))
plt.plot(WAVELENGTHS, total_spectrum, 'k-', linewidth=3, label='Total Spectrum')
plt.fill_between(WAVELENGTHS, helix_pct * BASIS_SPECTRA['H'], color='blue', alpha=0.1, label='Helix Contribution')
plt.fill_between(WAVELENGTHS, sheet_pct * BASIS_SPECTRA['E'], color='red', alpha=0.1, label='Sheet Contribution')
plt.axhline(0, color='black', linewidth=0.8)
plt.xlabel("Wavelength (nm)")
plt.ylabel(r"Molar Ellipticity [θ]")
plt.title(f"Synthetic CD Spectrum (Helix={helix_pct:.0%}, Sheet={sheet_pct:.0%}, Coil={coil_pct:.0%})")
plt.grid(alpha=0.3)
plt.legend()
plt.ylim(-45000, 80000)
plt.show()
widgets.interact(simulate_protein_cd,
helix_pct=widgets.FloatSlider(min=0, max=1.0, step=0.05, value=0.8, description='Helix %'),
sheet_pct=widgets.FloatSlider(min=0, max=1.0, step=0.05, value=0.0, description='Sheet %'))
🧬 Part 2: From 3D Structure to Spectrum¶
Now, let's use synth-pdb to generate real atomic models and calculate their 'experimental' CD spectra. We will see how the P-SEA algorithm identifies local geometry and maps it to the spectral signatures you saw above.
Experiment: The Helix-to-Sheet Transition¶
In the cell below, you can generate a synthetic peptide and choose its conformation. Notice how the CD curve dramatically flips as you move from a rigid Alpha Helix to an extended Beta Strand.
def run_3d_experiment(conformation):
print(f"🔨 Generating 3D model for conformation: {conformation}...")
# Generate model
pdb_text = generate_pdb_content(length=30, sequence_str="A"*30, conformation=conformation)
# Parse with Biotite
pdb_file = PDBFile.read(io.StringIO(pdb_text))
structure = pdb_file.get_structure(model=1)
# Run CD Simulator
sim = CDSimulator(structure)
print(f"📊 SSE Analysis Found: {sim.fractions}")
sim.plot()
widgets.interact(run_3d_experiment,
conformation=['alpha', 'beta', 'random'])
📖 Part 3: Scientific Validation¶
How do we know our synthetic spectrum is 'correct'? We compare it to ground truth experimental data.
Greenfield & Fasman (1969)¶
The basis spectra used here were first established in a seminal paper by Greenfield and Fasman. They studied synthetic poly-L-lysine in different conditions to capture 'pure' states.
Benchmark Values for Pure Helix:
- 222 nm: Minimum of ~ -36,000 to -40,000 $deg \cdot cm^2 / dmol$.
- 208 nm: Minimum of ~ -33,000 to -36,000 $deg \cdot cm^2 / dmol$.
- 192 nm: Maximum of ~ +70,000 to +80,000 $deg \cdot cm^2 / dmol$.
If your synthetic helix matches these values, it satisfies the 'Greenfield Test' for biophysical realism.
from synth_pdb.cd_simulator import validate_cd_against_literature
print("🧪 Running Automated Literature Validation for a 50-residue Helix...")
pdb_text = generate_pdb_content(length=50, sequence_str="A"*50, conformation="alpha")
structure = PDBFile.read(io.StringIO(pdb_text)).get_structure(model=1)
sim = CDSimulator(structure)
spectrum = sim.get_spectrum(noise_level=0)
findings = validate_cd_against_literature(sim.fractions, spectrum)
for f in findings:
print(f)
Congratulations! You have completed the Virtual CD Lab. You now have a high-performance tool for generating 'perfect' synthetic CD data to test your analysis pipelines or teach structural biology concepts.