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.
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…
How to Find and Analyze Protein-Protein Interfaces with BioPython 11 min read Intermediate — basic BioPython assumed Protein-protein interfaces determine binding specificity, drug targetability, and the functional logic of multi-subunit complexes. BioPython’s NeighborSearch class finds interface residues in milliseconds — and from there you can extract contact pairs, compute buried surface area, and produce a…
How to Calculate Protein Properties with BioPython: Molecular Weight, GRAVY and Secondary Structure 11 min read Beginner — basic BioPython assumed BioPython’s ProteinAnalysis class turns any protein sequence into a dashboard of physicochemical properties with a handful of method calls. This tutorial covers every property the class computes, what each value means biologically, and how…
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…
Python for Structural Biology: The Complete Guide to BioPython and MDAnalysis 30 min read Intermediate Python assumed Python is the language that connects every other tool in structural biology. It parses the PDB files you download, analyzes the trajectories you simulate, filters the docking results you generate, and automates the figure pipelines you build in…
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…
Great content! Keep up the good work!