Structural Bioinformatics

Lesson 8 of 13 · 11 min

Secondary Structure Assignment with DSSP

DSSP (Define Secondary Structure of Proteins) is the Kabsch-Sander algorithm that assigns secondary structure directly from backbone atom coordinates rather than from author annotations in the file. Biopython's Bio.PDB.DSSP class is a thin wrapper around the external mkdssp executable, so you must have DSSP installed and on your PATH before you can run it. It returns a per-residue map holding the 8-state assignment, the relative solvent accessibility, the phi and psi torsions, and the backbone hydrogen-bond partners together with their energies.

Running DSSP

python
from Bio.PDB import PDBParser
from Bio.PDB.DSSP import DSSP

parser = PDBParser(QUIET=True)
structure = parser.get_structure("1UBQ", "1ubq.pdb")
model = structure[0]                      # DSSP runs on a single model

# The `dssp` argument names the executable; use "mkdssp" for DSSP 4.x.
dssp = DSSP(model, "1ubq.pdb", dssp="mkdssp")

The DSSP object behaves like a dictionary keyed by (chain_id, residue_id), where residue_id is the standard Bio.PDB tuple of hetero-flag, sequence number, and insertion code. Each value is a 14-element tuple: index 0 is the DSSP serial number, then index 1 (one-letter amino acid), index 2 (8-state secondary structure), index 3 (relative solvent accessibility), indices 4 and 5 (phi and psi), and indices 6 through 13, which store four backbone hydrogen bonds as (relative-offset, energy) pairs -- the two best NH-->O bonds this residue donates and the two best O-->NH bonds it accepts. The accessibility at index 3 is already normalized by a residue-type maximum, using the Sander scale by default or Wilke or Miller via the acc_array argument.

python
# Keyed by (chain_id, residue_id); residue_id = (hetflag, seqnum, icode)
key = ("A", (" ", 26, " "))
res = dssp[key]

print("amino acid   :", res[1])
print("ss (8-state) :", res[2])
print("rel. ASA     :", res[3])
print("phi / psi    :", res[4], "/", res[5])
print("NH-->O bond  : relidx", res[6], "energy", res[7], "kcal/mol")
amino acid   : V
ss (8-state) : H
rel. ASA     : 0.0
phi / psi    : -63.5 / -42.1
NH-->O bond  : relidx -4 energy -2.5 kcal/mol

Hydrogen-Bond Energy Criterion

DSSP does not use a simple distance cutoff; it assigns a backbone hydrogen bond from an electrostatic energy E = q1q2(1/r(ON) + 1/r(CH) - 1/r(OH) - 1/r(CN))*f between a donor N-H and an acceptor C=O, with partial charges q1 = 0.42e and q2 = 0.20e and f = 332, giving E in kcal/mol for distances in angstroms. A bond is accepted when E is below -0.5 kcal/mol, which is why the partner energy printed above is negative. Repetitive bonds then define structure: an n-turn is a bond from CO(i) to NH(i+n), two consecutive 4-turns give alpha helix H, 3-turns give 3-10 helix G and 5-turns give pi helix I, bridge ladders between distant residues give strand E and an isolated bridge gives B, while T marks a lone turn and S a geometric bend.

Eight-State to Three-State

python
reduce = {"H": "H", "G": "H", "I": "H",
          "E": "E", "B": "E",
          "T": "C", "S": "C", "P": "C", "-": "C"}

keys = list(dssp.keys())
seq = "".join(dssp[k][1] for k in keys)
ss8 = "".join(dssp[k][2] for k in keys)
ss3 = "".join(reduce[dssp[k][2]] for k in keys)
rsa = [dssp[k][3] for k in keys]

print(seq)
print(ss8)
print(ss3)

buried = sum(1 for a in rsa if a < 0.20)
print(f"{buried}/{len(rsa)} residues buried (RSA < 0.20)")
MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTLHLVLRLRGG
-EEEEEETTS-EEEEEE--S-THHHHHHHHHHHTT---S-EEEEEETEE--STT-GGGT-EEEE-EEEEEE-----
CEEEEEECCCCEEEEEECCCCCHHHHHHHHHHHCCCCCCCEEEEEECEECCCCCCHHHCCEEEECEEEEEECCCCC
34/76 residues buried (RSA < 0.20)

Try it yourself: Run DSSP on 1UBQ, which carries a short 3-10 helix near residues 56-58, and separately on an all-alpha protein such as myoglobin (1MBN). Build the 8-state and 3-state strings as above, count how many residues DSSP labels G or I, and compare the 3-state helix fraction against the H-only fraction. Then print every residue with relative ASA above 0.5 and confirm that they cluster in loops and turns rather than in the buried hydrophobic core.