| name | bio-pdb-structure-navigation |
| description | Navigate protein structure hierarchy using Biopython Bio.PDB SMCRA model. Use when accessing models, chains, residues, and atoms, iterating over structure levels, or extracting sequences from PDB files. |
| tool_type | python |
| primary_tool | Bio.PDB |
Structure Navigation
Navigate the Structure-Model-Chain-Residue-Atom (SMCRA) hierarchy to access and iterate over structure components.
Required Imports
from Bio.PDB import PDBParser, PPBuilder, Selection
from Bio.Data.PDBData import protein_letters_3to1
SMCRA Hierarchy
Structure
|
+-- Model (0, 1, ...) # NMR ensembles, crystal asymmetric unit
|
+-- Chain (A, B, ...) # Polypeptide chains, ligands
|
+-- Residue # Amino acids, nucleotides, hetero groups
|
+-- Atom # Individual atoms
Accessing Hierarchy Levels
from Bio.PDB import PDBParser
parser = PDBParser(QUIET=True)
structure = parser.get_structure('protein', 'protein.pdb')
model = structure[0]
chain = model['A']
residue = chain[100]
residue = chain[(' ', 100, ' ')]
atom = residue['CA']
Iterating Over Structure
for model in structure:
for chain in model:
for residue in chain:
for atom in residue:
print(f'{chain.id}:{residue.id[1]}:{atom.name}')
for chain in structure.get_chains():
print(f'Chain: {chain.id}')
for residue in structure.get_residues():
print(f'Residue: {residue.resname}')
for atom in structure.get_atoms():
print(f'Atom: {atom.name} at {atom.coord}')
Residue Identification
for residue in chain:
hetfield, resseq, icode = residue.id
print(f'Residue {resseq}{icode}: {residue.resname}')
standard_residues = [r for r in chain if r.id[0] == ' ']
waters = [r for r in chain if r.id[0] == 'W']
hetero = [r for r in chain if r.id[0].startswith('H_')]
Atom Properties
for atom in residue:
print(f'Name: {atom.name}')
print(f'Element: {atom.element}')
print(f'Coordinates: {atom.coord}')
print(f'B-factor: {atom.bfactor}')
print(f'Occupancy: {atom.occupancy}')
print(f'Full ID: {atom.full_id}')
print(f'Serial number: {atom.serial_number}')
Getting Full Identifiers
atom = structure[0]['A'][100]['CA']
print(atom.get_full_id())
Checking for Children
if chain.has_id(100):
residue = chain[100]
if residue.has_id('CA'):
ca = residue['CA']
chains = structure[0].get_list()
residues = chain.get_list()
atoms = residue.get_list()
Getting Parent Entity
atom = structure[0]['A'][100]['CA']
residue = atom.get_parent()
chain = residue.get_parent()
model = chain.get_parent()
structure = model.get_parent()
Extracting Polypeptide Sequences
from Bio.PDB import PDBParser, PPBuilder
parser = PDBParser(QUIET=True)
structure = parser.get_structure('protein', 'protein.pdb')
ppb = PPBuilder()
for pp in ppb.build_peptides(structure):
seq = pp.get_sequence()
print(f'Polypeptide: {seq}')
print(f'Length: {len(seq)}')
sequences = [pp.get_sequence() for pp in ppb.build_peptides(structure)]
Using CaPPBuilder for Broken Chains
from Bio.PDB import CaPPBuilder
ppb = CaPPBuilder()
for pp in ppb.build_peptides(structure):
print(f'Fragment: {pp.get_sequence()}')
Converting Residue Names
from Bio.Data.PDBData import protein_letters_3to1
three_letter = 'ALA'
one_letter = protein_letters_3to1.get(three_letter, 'X')
print(f'{three_letter} -> {one_letter}')
sequence = ''
for residue in chain:
if residue.id[0] == ' ':
code = protein_letters_3to1.get(residue.resname, 'X')
sequence += code
print(f'Sequence: {sequence}')
Using Selection.unfold_entities
from Bio.PDB import Selection
residues = Selection.unfold_entities(structure, 'R')
print(f'Total residues: {len(residues)}')
atoms = Selection.unfold_entities(chain, 'A')
print(f'Atoms in chain: {len(atoms)}')
chains = Selection.unfold_entities(model, 'C')
Handling Disordered Atoms
if atom.is_disordered():
print(f'Atom {atom.name} has multiple conformations')
print(f'Alt locations: {atom.disordered_get_id_list()}')
atom.disordered_select('A')
print(f'Coord for alt A: {atom.coord}')
for altloc in atom.disordered_get_id_list():
atom.disordered_select(altloc)
print(f' {altloc}: {atom.coord}')
all_atoms = atom.disordered_get_list()
Handling Disordered Residues
if residue.is_disordered():
print(f'Disordered residue at {residue.id}')
names = residue.disordered_get_id_list()
print(f'Alternative residues: {names}')
residue.disordered_select('ALA')
Finding Specific Atoms
backbone_names = ['N', 'CA', 'C', 'O']
for residue in chain:
backbone = [residue[name] for name in backbone_names if residue.has_id(name)]
ca_atoms = [r['CA'] for r in structure.get_residues() if r.has_id('CA')]
print(f'Found {len(ca_atoms)} CA atoms')
for residue in chain:
sidechain = [a for a in residue if a.name not in ['N', 'CA', 'C', 'O']]
Filtering by Residue Type
amino_acids = [r for r in chain if r.id[0] == ' ']
arginines = [r for r in chain if r.resname == 'ARG']
charged = [r for r in chain if r.resname in ['ARG', 'LYS', 'ASP', 'GLU']]
ligands = [r for r in chain if r.id[0].startswith('H_')]
for lig in ligands:
print(f'Ligand: {lig.resname} at position {lig.id[1]}')
Counting Entities
n_models = len(list(structure.get_models()))
n_chains = len(list(structure.get_chains()))
n_residues = len(list(structure.get_residues()))
n_atoms = len(list(structure.get_atoms()))
print(f'Models: {n_models}, Chains: {n_chains}')
print(f'Residues: {n_residues}, Atoms: {n_atoms}')
for chain in structure.get_chains():
n_res = len([r for r in chain if r.id[0] == ' '])
print(f'Chain {chain.id}: {n_res} amino acids')
Working with NMR Ensembles
parser = PDBParser(QUIET=True)
structure = parser.get_structure('nmr', 'nmr_structure.pdb')
n_models = len(list(structure.get_models()))
print(f'NMR ensemble with {n_models} conformers')
for model in structure:
ca_coords = [r['CA'].coord for r in model.get_residues() if r.has_id('CA')]
print(f'Model {model.id}: {len(ca_coords)} CA atoms')
Related Skills
- structure-io - Parse and write structure files
- geometric-analysis - Measure distances, angles, RMSD
- structure-modification - Modify coordinates and properties
- sequence-manipulation/seq-objects - Work with extracted sequences