agentsclimarketplace

Design interface analysis

Skill ANaka/claudemol/claude-plugin/skills/design-interface-analysis

Use when analyzing protein-protein or protein-ligand interfaces in designed complexes, computing buried surface area, identifying hotspot contacts, or characterizing binding interfaces through PyMOL.From its SKILL.md

Install
npx -y skills add ANaka/claudemol --skill design-interface-analysis

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

8.7 KB, as published. Nobody here has run it

Design Interface Analysis

Workflows for characterizing interfaces in designed protein complexes. Composes with @rfdiffusion-viz (binder outputs), @alphafold-validation (AF2-Multimer), and @binding-site-visualization (existing ligand analysis).

Send all cmd.* code via: ~/.pymol-agent-bridge/bin/pymol-agent-bridge exec "..." (or heredoc for multi-line). See @pymol-fundamentals for details.

Interface Identification

Define Interface Residues

# Standard: residues with any atom within 4A of the partner chain
cmd.select("interface_A", "byres (chain A within 4 of chain B)")
cmd.select("interface_B", "byres (chain B within 4 of chain A)")

# Tighter cutoff for direct contacts
cmd.select("contacts_A", "byres (chain A within 3.5 of chain B)")
cmd.select("contacts_B", "byres (chain B within 3.5 of chain A)")

Count Interface Residues

n_A = cmd.count_atoms("interface_A and name CA")
n_B = cmd.count_atoms("interface_B and name CA")
print("Interface residues: %d (chain A) + %d (chain B) = %d total" % (n_A, n_B, n_A + n_B))

Visualize Interface

# Standard interface view
cmd.color("gray80", "chain A")
cmd.color("marine", "chain B")
cmd.show("cartoon")

cmd.show("sticks", "interface_A or interface_B")
cmd.color("tv_red", "interface_A and elem C")
cmd.color("tv_blue", "interface_B and elem C")

Hydrogen Bonds

Detect Interface H-Bonds

cmd.distance("hbonds", "chain A", "chain B", mode=2)
cmd.set("dash_color", "yellow", "hbonds")
cmd.set("dash_width", 2.0, "hbonds")
cmd.set("dash_gap", 0.2, "hbonds")

Count H-Bonds

# Get H-bond distances
stored.hbond_list = []
cmd.iterate("hbonds", "stored.hbond_list.append(1)")
# Note: each H-bond creates multiple pseudoatoms in the distance object
# A more reliable count:
hbond_count = cmd.count_atoms("hbonds") // 2
print("Interface H-bonds: ~%d" % hbond_count)

Donor/Acceptor Annotation

# Highlight H-bond donors (N-H) and acceptors (O, N)
cmd.select("donors", "(interface_A or interface_B) and (elem N and neighbor elem H)")
cmd.select("acceptors", "(interface_A or interface_B) and (elem O or (elem N and not neighbor elem H))")
cmd.color("blue", "donors")
cmd.color("red", "acceptors")

Salt Bridges

# Identify charged residue pairs across the interface
cmd.select("pos_A", "chain A and (resn ARG+LYS) and name NZ+NH1+NH2")
cmd.select("neg_B", "chain B and (resn ASP+GLU) and name OD1+OD2+OE1+OE2")
cmd.select("neg_A", "chain A and (resn ASP+GLU) and name OD1+OD2+OE1+OE2")
cmd.select("pos_B", "chain B and (resn ARG+LYS) and name NZ+NH1+NH2")

# Salt bridges (< 4A between charged groups)
cmd.distance("salt_bridges_1", "pos_A", "neg_B", cutoff=4.0, mode=0)
cmd.distance("salt_bridges_2", "neg_A", "pos_B", cutoff=4.0, mode=0)
cmd.set("dash_color", "magenta", "salt_bridges_1")
cmd.set("dash_color", "magenta", "salt_bridges_2")

Hydrophobic Contacts

# Hydrophobic residues at the interface
cmd.select("hydrophobic_A", "interface_A and resn ALA+VAL+LEU+ILE+MET+PHE+TRP+PRO")
cmd.select("hydrophobic_B", "interface_B and resn ALA+VAL+LEU+ILE+MET+PHE+TRP+PRO")

n_hp_A = cmd.count_atoms("hydrophobic_A and name CA")
n_hp_B = cmd.count_atoms("hydrophobic_B and name CA")
print("Hydrophobic interface residues: %d (A) + %d (B)" % (n_hp_A, n_hp_B))

cmd.show("sticks", "hydrophobic_A or hydrophobic_B")
cmd.color("yellow", "(hydrophobic_A or hydrophobic_B) and elem C")

Buried Surface Area (BSA)

Compute BSA

# SASA of each chain alone vs. in complex
cmd.set("dot_solvent", 1)
cmd.set("dot_density", 3)

# Measure each chain in isolation by temporarily hiding the partner
cmd.disable("all")
cmd.create("tmp_A", "chain A")
cmd.create("tmp_B", "chain B")

sasa_A_alone = cmd.get_area("tmp_A")
sasa_B_alone = cmd.get_area("tmp_B")

cmd.delete("tmp_A")
cmd.delete("tmp_B")
cmd.enable("all")

sasa_complex = cmd.get_area("chain A or chain B")

bsa = (sasa_A_alone + sasa_B_alone - sasa_complex) / 2.0
print("Buried surface area: %.0f A^2" % bsa)

BSA Interpretation for Design

BSA (A^2)Interpretation
< 500Very small interface — likely weak/transient
500-1000Small interface — typical for designed mini-binders
1000-2000Medium interface — good for designed binders
> 2000Large interface — typical for natural complexes

Color by Burial

# Color interface residues by how buried they are
cmd.set("dot_solvent", 1)
stored.burial = {}

# Get per-residue SASA in complex
cmd.iterate("chain B and name CA", "stored.burial[int(resi)] = 0")
for resi in stored.burial:
    sasa_alone = cmd.get_area("chain B and resi %d" % resi)
    sasa_complex = cmd.get_area("chain B and resi %d and not (chain B and byres(chain B within 4 of chain A))" % resi)
    # Approximate: fully buried residues at interface

Hotspot Identification

Identify key interface residues that contribute most to binding.

By Contact Density

# Rank interface residues by number of cross-chain contacts
stored.contacts = {}
cmd.iterate("interface_B and name CA", "stored.contacts[int(resi)] = 0")
for resi in stored.contacts:
    n = cmd.count_atoms("chain A within 4 of (chain B and resi %d)" % resi)
    stored.contacts[resi] = n

# Sort by contact count
ranked = sorted(stored.contacts.items(), key=lambda x: -x[1])
print("Top hotspot residues (binder):")
for resi, n in ranked[:10]:
    stored.resn = []
    cmd.iterate("chain B and resi %d and name CA" % resi, "stored.resn.append(resn)")
    print("  %s%d: %d contacts" % (stored.resn[0] if stored.resn else "?", resi, n))

# Color top hotspots
top_resi = "+".join(str(r) for r, _ in ranked[:5])
cmd.select("hotspots", "chain B and resi %s" % top_resi)
cmd.show("spheres", "hotspots and name CA")
cmd.color("red", "hotspots")

From Known Complex (Binder Design Input)

# Identify target hotspots from a known binder-target complex
# These become RFdiffusion hotspot inputs
cmd.load("known_complex.pdb", "reference")
cmd.select("ref_interface", "byres (chain A within 4 of chain B)")

stored.ref_contacts = {}
cmd.iterate("ref_interface and name CA", "stored.ref_contacts[int(resi)] = 0")
for resi in stored.ref_contacts:
    n = cmd.count_atoms("chain B within 3.5 of (chain A and resi %d)" % resi)
    stored.ref_contacts[resi] = n

ranked = sorted(stored.ref_contacts.items(), key=lambda x: -x[1])
hotspot_resi = [str(r) for r, n in ranked[:10]]
print("Hotspot residues for RFdiffusion: %s" % ",".join(hotspot_resi))

cmd.select("hotspots", "chain A and resi %s" % "+".join(hotspot_resi))
cmd.show("spheres", "hotspots")
cmd.color("red", "hotspots")

Shape Complementarity

Visual Assessment

# Show surfaces at interface colored by electrostatics proxy
cmd.show("surface", "interface_A")
cmd.show("surface", "interface_B")

# Color by charge (crude electrostatics)
cmd.color("blue", "interface_A and resn ARG+LYS")
cmd.color("red", "interface_A and resn ASP+GLU")
cmd.color("white", "interface_A and not resn ARG+LYS+ASP+GLU")
cmd.color("blue", "interface_B and resn ARG+LYS")
cmd.color("red", "interface_B and resn ASP+GLU")
cmd.color("white", "interface_B and not resn ARG+LYS+ASP+GLU")

cmd.set("transparency", 0.4)

Gap Analysis

# Check for voids at the interface
# Show surface of one chain, cartoon of the other
cmd.show("surface", "chain A")
cmd.set("transparency", 0.3, "chain A")
cmd.show("cartoon", "chain B")
cmd.show("sticks", "interface_B")
# Visually inspect for gaps between the surface and sticks

Interface Comparison (Design vs. Reference)

# Compare designed interface to a natural complex
cmd.load("natural_complex.pdb", "natural")
cmd.load("designed_complex.pdb", "designed")

# Align on target chain
cmd.align("designed and chain A", "natural and chain A")

# Compare binder positioning
cmd.color("gray70", "chain A")
cmd.color("green", "natural and chain B")
cmd.color("marine", "designed and chain B")
cmd.show("cartoon")

Tips

  • Interface cutoff of 4A is standard; use 3.5A for stringent direct contacts
  • BSA > 1000 A^2 is a good target for designed binders
  • Hotspot residues with > 5 cross-chain contacts are strong anchors
  • Charge complementarity across the interface is a positive design signal
  • Always check H-bonds AND hydrophobic packing — good interfaces have both
  • For binder design, extract hotspots from known complexes to feed into RFdiffusion (see @rfd3)
  • See @binding-site-visualization for protein-ligand interface analysis (small molecule focus)

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.