Lesson 12 of 13 · 12 min
Structure Quality and Validation
A deposited structure is a model fitted to experimental data, not ground truth, so its coordinates carry error that varies across the molecule. Before docking, measuring distances, or training on a structure, quantify how well the model is supported by its data and whether its geometry is physically reasonable. This lesson covers the global refinement statistics and the per-residue geometry checks that catch problems early.
Resolution and R-factors
Resolution sets the level of detail the data can resolve; below roughly 2.0 A you can trust side-chain rotamers and ordered waters, while above 3.0 A only backbone and large features are reliable. R-work measures agreement between observed and calculated structure factors, and R-free is the same metric on a held-out set of reflections excluded from refinement. R-free is the honest estimate because it cannot be lowered by overfitting.
import gemmi
import numpy as np
st = gemmi.read_structure("6xyz.cif")
block = gemmi.cif.read("6xyz.cif").sole_block()
print(f"Resolution : {st.resolution:.2f} A")
print(f"R-work : {block.find_value('_refine.ls_R_factor_R_work')}")
print(f"R-free : {block.find_value('_refine.ls_R_factor_R_free')}")
b = np.array([a.b_iso for m in st for ch in m for r in ch for a in r])
print(f"B-factor : mean={b.mean():.1f} min={b.min():.1f} max={b.max():.1f}")Resolution : 1.80 A
R-work : 0.176
R-free : 0.208
B-factor : mean=28.4 min=8.1 max=92.7
Tip: R-free should sit a few percent above R-work; near 1.8 A expect a gap around 0.03 to 0.05. A gap wider than about 0.06 hints at overfitting or restraint problems, while R-free falling below R-work essentially never happens with a properly held-out test set and usually means test-set reflections leaked into refinement. Read B-factors as coordinate uncertainty: atoms far above the model mean are flexible or poorly ordered, so do not over-interpret their exact positions.
Geometry Validation Metrics
Ramachandran outliers are residues whose phi/psi backbone angles fall in disallowed regions; a well-refined model keeps outliers below about 0.2 percent and favored above 98 percent. Rotamer outliers are side chains in improbable chi-angle conformations, and clashscore counts serious all-atom steric overlaps (a van der Waals overlap of 0.4 A or more) per 1000 atoms. MolProbity combines these into a single score where lower is better and roughly matches the resolution in Angstroms for a sound structure.
phenix.molprobity model.pdb
# writes molprobity.out, a Coot validation script (molprobity_coot.py),
# and a probe kinemage; the console prints the summary below=================== Summary ===================
Ramachandran outliers = 0.42 %
favored = 97.51 %
Rotamer outliers = 1.28 %
C-beta deviations = 0
Clashscore = 4.83
RMS(bonds) = 0.0075
RMS(angles) = 0.98
MolProbity score = 1.45
MolProbity percentile = 87th (n=8611, 1.80 A +/- 0.25 A)
Warning: The wwPDB validation report flags more than global geometry. Check for missing atoms (incomplete side chains or unmodeled loops), alternate conformations (altloc A/B) that many analysis scripts silently collapse to a single state, and strained bonds or angles beyond about 4 sigma. Occupancies below 1.0 and RSRZ outliers pinpoint residues whose electron density does not actually support the modeled coordinates.
Try it yourself: Download 3 or 4 PDB entries spanning a wide resolution range, from ultra-high to low (for example 3NIR crambin at 0.48 A, 1UBQ ubiquitin at 1.8 A, and a 3 to 3.5 A entry). Run phenix.molprobity on each, then plot clashscore and Ramachandran outlier percentage against resolution. Confirm that lower-resolution models trend toward worse geometry, and identify one residue in the worst model that is both a rotamer outlier and has a B-factor above the 90th percentile.