Distance between two specific atoms at current frame
Trajectory iteration
for ts in u.trajectory:
Iterate every frame — positions update automatically
for ts in u.trajectory[::5]:
Every 5th frame (stride) — faster for large trajectories
for ts in u.trajectory[50:]:
From frame 50 onward — skip equilibration
ts.frame, ts.time, ts.dimensions
Current frame index, time (ps), box dimensions [a,b,c,α,β,γ]
MDAnalysis — writing output
Command
What it does
protein.write(“protein_only.pdb”)
Write current frame of selection to PDB
with mda.Writer(“out.xtc”, n_atoms) as w: w.write(ag)
Write trajectory frames to XTC file
for ts in u.trajectory[::10]: w.write(protein)
Write every 10th frame — reduces file size
u.trajectory[50]; protein.write(“frame50.pdb”)
Write a specific frame as PDB for PyMOL
Cross-library workflows
AlphaFold pLDDT extraction (BioPython)
from Bio.PDB import PDBParser
parser = PDBParser(QUIET=True)
struct = parser.get_structure(“af”, “AF-P04637-F1-model_v4.pdb”)
plddt = {res.id[1]: res[“CA”].get_bfactor()
for res in struct[0][“A”].get_residues()
if res.id[0] == ” “and“CA”in res}
# plddt = {resid: score, …} — filter: {k: v for k, v in plddt.items() if v >= 70}
Standard MD analysis setup (MDAnalysis)
import MDAnalysis as mda
from MDAnalysis.analysis import align, rms
u = mda.Universe(“topology.gro”, “md_vis.xtc”)
align.AlignTraj(u, u, select=“backbone”, in_memory=True).run() # align first
rmsd_data = rms.RMSD(u, select=“backbone”).run().results.rmsd[:, 2]
rmsf_data = rms.RMSF(u.select_atoms(“backbone and name CA”)).run().results.rmsf
Interface residues — BioPython NeighborSearch
from Bio.PDB import NeighborSearch
ns_b = NeighborSearch(list(model[“B”].get_atoms()))
iface_a = {res_a for res_a in model[“A”].get_residues()
if res_a.id[0] == ” “for atom in res_a.get_atoms()
if ns_b.search(atom.get_coord(), 5.0, level=“R”)}
Protein-ligand contact occupancy — MDAnalysis
from MDAnalysis.lib.distances import distance_array
from collections import Counter
lig = u.select_atoms(“resname LIG”)
protein = u.select_atoms(“protein”)
counts = Counter()
for ts in u.trajectory:
mask = (distance_array(lig.positions, protein.positions) < 5.0).any(axis=0)
counts.update(protein.atoms[mask].resids)
# occupancy_pct = {r: c/len(u.trajectory)*100 for r, c in counts.items()}
RMSD comparison — BioPython Superimposer
from Bio.PDB import Superimposer
sup = Superimposer()
# Build equal-length lists of paired Cα atoms
ca_ref = [chain_ref[r][“CA”] for r in common_resids]
ca_mob = [chain_mob[r][“CA”] for r in common_resids]
sup.set_atoms(ca_ref, ca_mob)
print(f“RMSD: {sup.rms:.3f} Å over {len(ca_ref)} Cα atoms”)
sup.apply(mobile.get_atoms()) # move mobile to aligned position
Three checks before any analysis
(1) After every BioPython parse: print(len(list(structure.get_atoms()))) — confirm atoms loaded. (2) After every MDAnalysis selection: assert sel.n_atoms > 0, "Empty selection" — catch silent mismatches. (3) After alignment: check RMSD is physically reasonable (backbone RMSD < 5 Å for a stable protein) before running RMSF or H-bond analysis.
Common BioPython and MDAnalysis Mistakes and How to Fix Them 12 min read All levels Most BioPython and MDAnalysis errors are silent — the code runs without crashing but produces wrong residue counts, inflated RMSD values, or empty selections. These are the eight mistakes that appear most often in help threads, and the fixes that…
BioPython Tutorial for Beginners: Parsing PDB Files and Working with Protein Structures 12 min read Beginner — basic Python assumed BioPython’s structure module turns a PDB file — which is just a formatted text file — into a Python object you can query, iterate, and calculate with. This tutorial covers everything you need to go…
How to Calculate RMSD and Align Protein Structures with Python and BioPython 11 min read Intermediate — basic BioPython assumed RMSD is the standard metric for quantifying how similar two protein structures are. BioPython’s Superimposer class calculates it in three lines — but the lines before those three, where you select the right atoms to…
How to Parse AutoDock Vina Docking Results with Python: From PDBQT to Ranked Hit List 11 min read Intermediate — basic Python and pandas assumed A virtual screening run produces hundreds or thousands of PDBQT output files. Manually opening each one to copy binding affinities is impractical from the first compound. This tutorial builds a…
How to Automate GROMACS Analysis with Python: RMSD, RMSF and Energy Plots 12 min read Intermediate — basic Python and GROMACS assumed Every GROMACS analysis workflow involves the same sequence of terminal commands, interactive group selections, and XVG file parsing repeated across every simulation. Python’s subprocess module automates all of it — this tutorial builds…
How to Download and Parse AlphaFold Structures with Python and BioPython 11 min read Intermediate — basic BioPython assumed Every AlphaFold prediction is one API call away. Python makes it trivial to download hundreds of structures, extract their per-residue confidence scores, and filter out unreliable regions — automating what would otherwise be hours of manual…
Great content! Keep up the good work!