# Alphafold Structure Prediction

> Predict protein 3D structure with AlphaFold2/ColabFold/ESMFold, fetch precomputed models from the AlphaFold DB, and interpret pLDDT/PAE confidence metrics and Cα RMSD. Use when predicting a structure from sequence, asking "how confident is this AlphaFold model", downloading an AF-*.pdb from alphafold.ebi.ac.uk, comparing predicted vs crystal structures, or triaging RFdiffusion/ProteinMPNN design candidates by confidence.

- Skill: `pavel-kravchenko/alphafold-structure-prediction` (Agent Skill)
- Install (CLI): `npx skillmds@latest add pavel-kravchenko/alphafold-structure-prediction`
- Raw SKILL.md: https://api.skillmd.com/api/skills/pavel-kravchenko/alphafold-structure-prediction/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: pavel-kravchenko (https://skillmd.com/u/pavel-kravchenko)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/pavel-kravchenko/alphafold-structure-prediction

---


# AlphaFold Structure Prediction

## When to Use

- Predicting a protein's 3D structure from its amino acid sequence (ColabFold, AF2-Multimer, or ESMFold)
- Interpreting AlphaFold confidence outputs — per-residue pLDDT and pairwise PAE — from a `result_model_*.json`
- Fetching precomputed models from the AlphaFold Protein Structure Database by UniProt ID
- Comparing a predicted structure against an experimental (crystal/cryo-EM) structure via Cα RMSD
- Ranking RFdiffusion/ProteinMPNN design candidates by confidence before ordering synthesis

## Version Compatibility

- ColabFold ≥1.5 (MMseqs2 MSA), AlphaFold2 ≥2.3 / AlphaFold3 (complexes, ligands, nucleic acids)
- ESMFold via `fair-esm` ≥2.0 or the ESM Atlas REST API
- Biopython ≥1.83, NumPy ≥1.26, Python ≥3.10

## Prerequisites

- `pip install biopython numpy matplotlib requests`
- For local ColabFold/ESMFold inference: a CUDA GPU (T4 minimum, A100 for RFdiffusion-scale design)
- Familiarity with PDB format (see `structural-bioinformatics`) and basic sequence handling

## Fetching Structures from the AlphaFold DB

**Goal:** get a predicted structure for a UniProt accession without running inference.
**Approach:** the AlphaFold DB serves one static URL per accession per model version; batch-fetch with rate limiting and track failures (obsolete/withdrawn UniProt IDs return 404).

```python
import time
from pathlib import Path

import requests


def fetch_alphafold_pdbs(uniprot_ids, out_dir="af_structures", version=4):
    """Download AlphaFold predicted structures for a list of UniProt IDs.

    Returns (out_dir, failed_ids).
    """
    out_dir = Path(out_dir)
    out_dir.mkdir(exist_ok=True)
    failed = []
    for uid in uniprot_ids:
        url = f"https://alphafold.ebi.ac.uk/files/AF-{uid}-F1-model_v{version}.pdb"
        resp = requests.get(url, timeout=30)
        if resp.status_code == 200:
            (out_dir / f"{uid}.pdb").write_text(resp.text)
        else:
            failed.append(uid)
        time.sleep(0.2)  # be polite to the EBI endpoint
    if failed:
        print(f"Failed: {failed}")
    return out_dir, failed


fetch_alphafold_pdbs(["P00533", "P04637", "P01308"])  # EGFR, TP53, insulin
```

## Interpreting pLDDT and PAE

**Goal:** turn raw AF2 output JSON into an actionable confidence read.
**Approach:** plot the per-residue pLDDT trace and the N×N PAE matrix side by side; pLDDT is stored per-residue (0-100), PAE is a directional matrix in Angstroms (`pae[i, j]` = confidence in residue j's position if the model is aligned on residue i).

```python
import json

import matplotlib.pyplot as plt
import numpy as np


def plot_confidence(result_json_path):
    """Plot pLDDT profile and PAE heatmap from an AF2 result_model_*.json."""
    with open(result_json_path) as f:
        data = json.load(f)

    plddt = np.asarray(data["plddt"])  # per-residue confidence, 0-100
    pae = np.asarray(data["predicted_aligned_error"])  # N x N, Angstroms

    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))
    ax1.plot(plddt, color="steelblue")
    ax1.axhline(90, color="green", ls="--", label="Very high")
    ax1.axhline(70, color="orange", ls="--", label="Confident")
    ax1.axhline(50, color="red", ls="--", label="Low")
    ax1.set(xlabel="Residue", ylabel="pLDDT", title="Per-residue confidence")
    ax1.legend()

    im = ax2.imshow(pae, cmap="Greens_r", vmin=0, vmax=30)
    plt.colorbar(im, ax=ax2, label="Expected error (Å)")
    ax2.set(xlabel="Aligned residue", ylabel="Scored residue", title="PAE")
    plt.tight_layout()
    return plddt, pae
```

| pLDDT | Confidence | Typical region |
|-------|-----------|-----------------|
| > 90 | Very high | Well-folded structured domain |
| 70–90 | Confident | Structured, minor flexibility |
| 50–70 | Low | Could be disordered or a flexible loop |
| < 50 | Very low | Likely intrinsically disordered |

```python
from Bio.PDB import PDBParser


def get_disordered_regions(pdb_path, plddt_threshold=50):
    """Return residue ranges with pLDDT < threshold.

    AlphaFold DB models store per-residue pLDDT in the B-factor column.
    """
    parser = PDBParser(QUIET=True)
    structure = parser.get_structure("model", pdb_path)
    disordered = []
    run_start, prev_res = None, None
    for chain in structure.get_chains():
        for residue in chain:
            for atom in residue:
                if atom.name != "CA":
                    continue
                plddt = atom.bfactor  # AF2 stores pLDDT here, not thermal B-factor
                res_id = residue.get_id()[1]
                if plddt < plddt_threshold:
                    if run_start is None:
                        run_start = res_id
                elif run_start is not None:
                    disordered.append((run_start, prev_res))
                    run_start = None
                prev_res = res_id
    if run_start is not None:
        disordered.append((run_start, prev_res))
    return disordered
```

## Predicting Structure (ESMFold) and Comparing to a Reference

**Goal:** get a fast, MSA-free prediction and quantify agreement with a known structure.
**Approach:** ESMFold's REST API takes a raw sequence and returns PDB text directly — good for orphan sequences with no homologs, where AF2's MSA-dependent pipeline performs poorly. Align Cα atoms with Biopython's `Superimposer` for RMSD.

```python
import requests
from Bio.PDB import PDBParser, Superimposer


def esmfold_predict(sequence: str, out_path: str = "esmfold_pred.pdb") -> str:
    """Predict a structure with the ESM Atlas ESMFold API (no MSA required)."""
    resp = requests.post(
        "https://api.esmatlas.com/foldSequence/v1/pdb/",
        data=sequence,
        headers={"Content-Type": "application/x-www-form-urlencoded"},
        timeout=120,
    )
    resp.raise_for_status()
    with open(out_path, "w") as f:
        f.write(resp.text)
    return out_path


def compare_structures(pred_pdb: str, ref_pdb: str):
    """Compute Cα RMSD between a predicted and a reference structure."""
    parser = PDBParser(QUIET=True)
    pred = parser.get_structure("pred", pred_pdb)
    ref = parser.get_structure("ref", ref_pdb)

    ca_pred = [a for a in pred.get_atoms() if a.name == "CA"]
    ca_ref = [a for a in ref.get_atoms() if a.name == "CA"]
    n = min(len(ca_pred), len(ca_ref))
    if n == 0:
        raise ValueError("No CA atoms found in one of the structures")

    sup = Superimposer()
    sup.set_atoms(ca_ref[:n], ca_pred[:n])
    rmsd = sup.rms
    label = "Excellent" if rmsd < 1 else "Good" if rmsd < 2 else "Moderate" if rmsd < 4 else "Poor"
    print(f"Aligned residues: {n}, Cα RMSD: {rmsd:.2f} Å ({label})")
    return rmsd, sup
```

## Ranking Design Candidates

**Goal:** triage RFdiffusion/ProteinMPNN outputs before expensive downstream validation or synthesis.
**Approach:** combine mean pLDDT and interface PAE into a single confidence score, then weight in sequence novelty for design tasks that need to avoid re-deriving natural sequences.

```python
import numpy as np


def design_priority(mean_plddt: float, interface_pae: float, seq_novelty: float) -> float:
    """Score a design candidate from confidence metrics and sequence novelty.

    mean_plddt: 0-100 average pLDDT of the AF2 validation model
    interface_pae: mean PAE (Å) across the designed interface, lower is better
    seq_novelty: 0-1, e.g. 1 - max sequence identity to known proteins
    """
    conf = 0.7 * (mean_plddt / 100.0) + 0.3 * (1.0 - np.clip(interface_pae / 30.0, 0, 1))
    return float(0.8 * conf + 0.2 * seq_novelty)
```

```bash
# RFdiffusion: propose backbones binding a target's hotspot residues
python RFdiffusion/scripts/run_inference.py \
    inference.input_pdb=target.pdb \
    'contigmap.contigs=[A1-100/0 50-100]' \
    'ppi.hotspot_res=[A45,A67,A89]' \
    inference.num_designs=20 \
    inference.output_prefix=designs/binder

# ProteinMPNN: design sequences for the best backbone, then re-validate with AF2/ESMFold
python ProteinMPNN/protein_mpnn_run.py \
    --pdb_path designs/binder_0.pdb \
    --out_folder mpnn_seqs/ \
    --num_seq_per_target 8 \
    --sampling_temp 0.1
```

## Pitfalls

- **pLDDT ≠ correctness** — high pLDDT only means the model is internally self-consistent, not that it matches reality; always validate against experimental data when available.
- **AF2 predicts a single static conformation** — typically the most stable one; it does not model dynamics, alternate conformations, or ligand-induced changes.
- **PAE is directional, not symmetric** — `pae[i, j]` ("if i is placed correctly, how confident is j") differs from `pae[j, i]`; for multimers, low cross-chain PAE means the relative chain/domain orientation is reliable.
- **MSA depth matters** — AF2 performs poorly for orphan sequences with few homologs; ESMFold or a deeper custom MSA search is often better for these.
- **Disordered regions (pLDDT < 50)** should not be used for docking, RMSD comparison, or structural claims.
- **ColabFold vs full AF2** — ColabFold's MMseqs2 MSA search is faster but can give slightly lower accuracy than the official AF2 pipeline; usually adequate for exploratory work.
- **AF3 vs AF2** — use AF3 for anything involving nucleic acids, ligands, ions, or modified residues; AF2/AF2-Multimer is for protein-only monomers and complexes.
- **RFdiffusion compute** — full-size binder design wants an A100; designs under ~100 residues are feasible on a T4.

## See Also

- `structural-bioinformatics` — PDB format, secondary structure, molecular visualization
- `bio-core-protein-structure` — protein structure fundamentals and geometry
- `ai-science-alphafold-protein-design` — RFdiffusion/ProteinMPNN design loop in depth
- `protein-language-models` — ESM embeddings and language-model-based structure/function prediction

