API documentation to be loaded at startup - when starting a Coot session, immediately call get_function_descriptions() with the functions listed in this skill.
Scanned 9/1/2026
Install to Claude Code
npx -y skills add pemsley/coot --skill essential-api --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Essential Api?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/pemsley-essential-api)More formats (shields.io, HTML) on the badges page.
---
name: coot-essential-api
description: "API documentation to be loaded at startup - when starting a Coot session, immediately call get_function_descriptions() with the functions listed in this skill."
---
# Coot Essential API Functions
This document contains the core Coot API functions needed for typical validation and model-building workflows.
Reading these function signatures at session start eliminates the need for searching.
## Setup & Configuration
```python
coot.set_refinement_immediate_replacement(1)
# CRITICAL: Call this before any refinement operations to make them synchronous
# Without this, refinement results may not be available immediately
coot.set_imol_refinement_map(imol_map)
# CRITICAL: Call this to tell Coot which map to use for refinement.
# Must be called once per session (or whenever the map changes).
# Without this, refine_residues_py() will fail silently.
# Example: coot.set_imol_refinement_map(1)
```
## Molecule Management
```python
coot.is_valid_model_molecule(imol) -> int # Returns 1 if valid model, 0 otherwise
coot.is_valid_map_molecule(imol) -> int # Returns 1 if valid map, 0 otherwise
coot.molecule_name(imol) -> str # Returns the molecule filename/description
coot.n_chains(imol) -> int # Returns number of chains
coot.coot_version() -> str # Returns Coot version string
coot.load_tutorial_model_and_data() # Loads tutorial RNase structure + maps
# Download structures and data from PDBe
coot.network_get_accession_code_entity(pdb_accession_code, mode)
# Downloads model and/or structure factors from PDBe
# Parameters:
# pdb_accession_code: str - PDB accession code (e.g., "4wa9")
# mode: int - 0 for coordinates (.pdb or .cif), 1 for structure factors (.mtz)
# Example - fetch both model and data:
# coot.network_get_accession_code_entity("4wa9", 0) # Get coordinates
# coot.network_get_accession_code_entity("4wa9", 1) # Get structure factors to make a map
```
## Checkpoints - Model State Management
When experimenting with the various model building tools available to
address a particular model-building problem it is useful to create
backup checkpoints. This allows you to return to a particular state,
so that you can try alternative model-building parameters or
functions, or combinations of functions.
```python
coot.make_backup_checkpoint(imol, description_string) -> int
# Creates a named checkpoint of the molecule's current state
# Returns: checkpoint index for later restoration
#
# Parameters:
# imol: Model molecule index
# description_string: Human-readable description (e.g., "before rotamer fix")
#
# CRITICAL: Always checkpoint before experimental or risky operations
#
# Example:
checkpoint_idx = coot.make_backup_checkpoint(0, "before rotamer fix")
coot.auto_fit_best_rotamer(0, "A", 42, "", "", 1, 1, 0.01)
# ... check if improvement worked ...
if not improved:
coot.restore_to_backup_checkpoint(0, checkpoint_idx)
coot.restore_to_backup_checkpoint(imol, checkpoint_index)
# Restores molecule to a previously saved checkpoint state
# Parameters:
# imol: Model molecule index
# checkpoint_index: Index returned by make_backup_checkpoint()
coot.compare_current_model_to_backup(imol, checkpoint_index) -> dict
# Compares current model state to a checkpoint to see what changed
# Parameters:
# imol: Model molecule index
# checkpoint_index: Index of checkpoint to compare against
```
## Chain and Residue Information
```python
# Requires: import coot_utils
coot_utils.chain_ids(imol) -> list # Returns list of chain IDs, e.g., ['A', 'B']
# Direct C++ functions (preferred when possible)
coot.chain_id_py(imol, chain_index) -> str # Get chain ID by index
```
## Secondary Structure Information
```python
coot.get_header_secondary_structure_info(imol) -> dict
# Returns secondary structure from PDB header
# Returns: {'helices': [...], 'strands': [...]}
#
# Each helix dict contains:
# serNum, helixID, initChainID, initSeqNum, endChainID, endSeqNum, length, comment
#
# Each strand dict contains:
# SheetID, strandNo, initChainID, initSeqNum, endChainID, endSeqNum
#
# Example - get beta barrel strands:
ss = coot.get_header_secondary_structure_info(0)
if 'strands' in ss:
for strand in ss['strands']:
print(f"Strand {strand['strandNo']}: {strand['initSeqNum']}-{strand['endSeqNum']}")
```
## Navigation
```python
coot.set_go_to_atom_chain_residue_atom_name(chain_id, resno, atom_name) -> int
# Centers view on specified atom. Returns 1 on success.
# Example: coot.set_go_to_atom_chain_residue_atom_name("A", 42, "CA")
coot.closest_atom_simple_py() -> list
# Returns: [imol, chain_id, resno, ins_code, atom_name, alt_conf]
# Gets the atom closest to screen center across all displayed molecules
coot.closest_atom_py(imol) -> list
# Same as above but for specific molecule
coot.active_atom_spec_py() -> list
# Returns the currently "active" atom specification (or False if none found)
# (found, (imol, atom_spec))
# found: Boolean indicating if an atom exists close to the center
# molecule_number: Integer molecule ID
# atom_spec: List [chain_id, resno, ins_code, atom_name, alt_conf]
```
## Residue Inspection
```python
coot.residue_info_py(imol, chain_id, resno, ins_code) -> list
# Returns detailed atom information for a residue
#
# Parameters:
# imol: Model molecule index
# chain_id: Chain identifier (e.g., "A")
# resno: Residue number
# ins_code: Insertion code (use "" if none)
#
# Returns: List of atom entries, each containing:
# [[atom_name, alt_conf], [occupancy, b_factor, element, ?], [x, y, z], atom_index]
#
# Example output for a complete CYS:
# [[' N ', ''], [1.0, 12.5, ' N', ''], [x, y, z], 100],
# [[' CA ', ''], [1.0, 11.2, ' C', ''], [x, y, z], 101],
# [[' CB ', ''], [1.0, 14.3, ' C', ''], [x, y, z], 102],
# [[' SG ', ''], [1.0, 18.1, ' S', ''], [x, y, z], 103], # Sulfur!
# [[' C ', ''], [1.0, 10.8, ' C', ''], [x, y, z], 104],
# [[' O ', ''], [1.0, 11.0, ' O', ''], [x, y, z], 105]
#
# NOTE: b_factor may be a list [b_iso, B11, B22, B33, B12, B13, B23] for anisotropic
# Always handle safely:
# def get_b(atom): b = atom[1][1]; return b[0] if isinstance(b, list) else b
# Check for missing atoms in a residue
atoms = coot.residue_info_py(0, "A", 72, "")
atom_names = [a[0][0].strip() for a in atoms]
print(f"Atoms present: {atom_names}")
# Expected atoms for common residues
expected_atoms = {
'CYS': ['N', 'CA', 'CB', 'SG', 'C', 'O'],
'ILE': ['N', 'CA', 'CB', 'CG1', 'CG2', 'CD1', 'C', 'O'],
'GLY': ['N', 'CA', 'C', 'O'],
'PHE': ['N', 'CA', 'CB', 'CG', 'CD1', 'CD2', 'CE1', 'CE2', 'CZ', 'C', 'O'],
}
# Find missing atoms
res_type = coot.residue_name_py(0, "A", 72, "")
if res_type in expected_atoms:
missing = [a for a in expected_atoms[res_type] if a not in atom_names]
if missing:
print(f"WARNING: Missing atoms in {res_type}: {missing}")
```
## Validation - Density Fit
```python
coot.map_to_model_correlation_stats_per_residue_range_py(
imol, # Model molecule number
chain_id, # Chain identifier (e.g., "A")
imol_map, # Map molecule number
n_per_range, # Residues per window (use 1 for per-residue)
exclude_NOC # 0=include all atoms, 1=exclude backbone N,O,C
) -> list
# Returns: [[all_atom_stats], [sidechain_stats]]
# Each stats list: [[residue_spec, [n_points, correlation]], ...]
# residue_spec = [chain_id, resno, ins_code]
# Example - find worst fitting residues:
stats = coot.map_to_model_correlation_stats_per_residue_range_py(0, "A", 1, 1, 0)
all_atom = stats[0]
worst = sorted(all_atom, key=lambda x: x[1][1])[:5] # 5 worst by correlatio
# Mainchain vs sidechain correlation for a single residue:
coot.map_to_model_correlation_py(imol, residue_specs, neighb_specs, atom_mask_mode, imol_map)
# atom_mask_mode: 0=all atoms, 1=mainchain only, 2=sidechain only
# Use to distinguish backbone problems from sidechain problems before choosing a fix
# Per-atom density probing — the most powerful backbone diagnostic:
sigma = coot.map_sigma_py(imol_map)
d = coot.density_at_point(imol_map, x, y, z) / sigma # value in sigma units
# Backbone atom < 0.5σ = problem; carbonyl O near 0σ with good CA = pepflip needed
```
## Validation - Geometry
```python
coot.all_molecule_ramachandran_score_py(imol) -> list
# Returns a list of exactly 6 elements (confirmed from C++ source):
# [0]: overall score (float)
# [1]: n_residues (int)
# [2]: score_non_sec_str (float)
# [3]: n_residues_non_sec_str (int)
# [4]: n_zeros (int)
# [5]: per-residue list (list of per-residue entries)
#
# Each per-residue entry: [[phi, psi], [chain_id, resno, ins_code], probability, [prev_resname, this_resname, next_resname]]
# NOTE: rama_data[5] and rama_data[-1] are equivalent and both correct.
# LOW probability = BAD (outlier). Outlier threshold: prob < 0.02
#
# Example:
# per_res = coot.all_molecule_ramachandran_score_py(imol)[5]
# outliers = [r for r in per_res if r[2] < 0.02]
# worst = min(per_res, key=lambda x: x[2])
coot.rotamer_graphs_py(imol) -> list
# Returns: [[chain_id, resno, ins_code, score_percentage, resname], ...]
# LOW score = BAD rotamer
coot.molecule_atom_overlaps_py(imol, n_pairs) -> list
# Returns worst n_pairs atom overlaps (use -1 for all)
# Each overlap: {
# 'atom-1-spec': [imol, chain, resno, ins, atom_name, alt],
# 'atom-2-spec': [imol, chain, resno, ins, atom_name, alt],
# 'overlap-volume': float # in ų, >5.0 is severe
# }
```
## Validation - Unmodeled Density
```python
coot.find_blobs_py(imol_model, imol_map, sigma_cutoff) -> list
# Finds unmodeled density blobs
# Returns: [[position, score], ...]
# position is a list or 3 floats, (for x, y, z)
# Use sigma_cutoff=3.0 for difference maps, 1.0 for 2mFo-DFc
# Higher score = larger/stronger blob
```
## Validation - Hydrogen Bonds
```python
coot.get_hydrogen_bonds_py(imol, selection_1, selection_2, mcdonald_and_thornton) -> list
# Find hydrogen bonds between two atom selections.
# selection_1, selection_2: MMDB selection strings (e.g. "//A/35", "//A")
# Note: selection_1 and selection_2 can be the same, e.g. "//A" for intra-chain H-bonds
# mcdonald_and_thornton: 0 if model has no H atoms, 1 if it does
# Returns list of H-bond candidates, each a list of 12 elements:
# [0] hydrogen atom (dict or None)
# [1] donor atom (dict)
# [2] acceptor atom (dict)
# [3] donor neighbour atom (dict or None)
# [4] acceptor neighbour atom (dict or None)
# [5] angle_1 (float, degrees)
# [6] angle_2 (float, degrees)
# [7] angle_3 (float, degrees)
# [8] distance (float, Å)
# [9] ligand_atom_is_donor (bool)
# [10] hydrogen_is_ligand_atom (bool)
# [11] bond_has_hydrogen_flag (bool)
# Atom dicts have keys: x, y, z, name, element, chain, residue_name, occ, b_iso, altLoc
#
# Example:
hbonds = coot.get_hydrogen_bonds_py(0, "//A/35", "//A", 0)
for hb in hbonds:
donor = hb[1]
acceptor = hb[2]
dist = hb[8]
d_str = donor['chain'] + " " + donor['residue_name'] + " " + donor['name'].strip()
a_str = acceptor['chain'] + " " + acceptor['residue_name'] + " " + acceptor['name'].strip()
print("H-bond: " + d_str + " -> " + a_str + " dist=" + str(dist))
```
## Refinement
```python
coot.refine_residues_py(imol, residue_specs) -> list
# Real-space refinement of specified residues
# residue_specs = [["A", 42, ""], ["A", 43, ""], ...] # [chain, resno, ins_code]
# Returns: ['', status, lights] where:
# status: 0=converged, -2=GSL_CONTINUE (call again), 27=no progress
# lights: list of [name, label, value] refinement statistics, or False
# CRITICAL: if status == -2, call refine_residues_py() again (up to 3 times total)
# Example robust call:
# for _ in range(3):
# result = coot.refine_residues_py(imol, specs)
# if result and result[1] != -2: break
# accepted = coot.accept_moving_atoms_py() # get traffic lights
```
## Model Building - Rotamers
```python
coot.auto_fit_best_rotamer(
imol, # Model molecule
chain_id, # Chain (e.g., "A")
resno, # Residue number
ins_code, # Insertion code (usually "")
altloc, # Alt conf (usually "")
imol_map, # Map for density scoring
clash_flag, # 1=check clashes, 0=ignore
lowest_probability # Minimum rotamer probability (e.g., 0.01)
) -> float
# Returns new rotamer score, or -99.9 if residue has no rotamers (GLY, ALA)
```
## Model Building - Backbone
```python
coot.pepflip(imol, chain_id, resno, ins_code, altloc)
# Flips the peptide bond at specified residue
# Use for fixing cis/trans peptide issues or Ramachandran outliers
# or other false minimum backbone conformations.
# Follow with refinement of surrounding residues
```
---
## CRITICAL: Always Render Validation Results as Interactive SVG Widgets
**When presenting validation results, geometry analysis, per-atom density data, or any
tabular data about multiple residues, ALWAYS render an interactive SVG widget using
`visualize:show_widget`. Never just print a wall of text.**
The user can click on each residue block to navigate directly to it in Coot or trigger
a fix. This is far more useful than stdout and makes results immediately actionable.
### When to render a widget — trigger situations:
- After running full validation (Ramachandran, rotamers, density fit, clashes, geometry)
- After a per-atom backbone density probe scan
- After any survey comparing multiple residues or chains
- After a before/after fix comparison showing improvement
- Any time there are more than ~5 residues worth of results to show
### Severity colour coding:
- `c-red` — severe issues (Rama score < 0.001, rotamer 0%, corr < 0.3, omega > 20° off)
- `c-amber` — moderate issues (Rama 0.001–0.01, rotamer < 5%, corr 0.3–0.65)
- `c-gray` — informational / OK residues
- `c-teal` — unmodelled density blobs / features to investigate
- `c-green` — successfully fixed residues (before/after comparisons)
### onclick patterns — make them actionable, not just informational:
```python
# Navigation
onclick="sendPrompt('Go to A/41 GLU and show me the density')"
# Investigation
onclick="sendPrompt('Go to B/257 GLU and investigate — negative correlation')"
# Fix requests
onclick="sendPrompt('Fix the clash between A/2 CA and A/89 CZ')"
onclick="sendPrompt('Try pepflip at B/262 and refine')"
onclick="sendPrompt('Fix rotamer A/32 GLN — 0% score')"
# Comparative
onclick="sendPrompt('Go to A/260 ALA — worst Ramachandran in chain A')"
```
The onclick prompt should describe the *action to take*, not just what the residue is.
A user clicking a red block should trigger the next useful step automatically.
### Minimal widget template for validation results:
```svg
<svg width="100%" viewBox="0 0 680 [H]">
<!-- Section header -->
<text class="th" x="40" y="28">Ramachandran outliers</text>
<!-- Severe issue -->
<g class="node c-red" onclick="sendPrompt('Go to A/41 GLU and investigate Ramachandran outlier')">
<rect x="40" y="38" width="280" height="50" rx="8" stroke-width="0.5"/>
<text class="th" x="180" y="57" text-anchor="middle" dominant-baseline="central">A/41 GLU</text>
<text class="ts" x="180" y="74" text-anchor="middle" dominant-baseline="central">score 0.00004 phi=112°</text>
</g>
<!-- Moderate issue -->
<g class="node c-amber" onclick="sendPrompt('Go to A/35 VAL and investigate')">
<rect x="340" y="38" width="280" height="50" rx="8" stroke-width="0.5"/>
<text class="th" x="480" y="57" text-anchor="middle" dominant-baseline="central">A/35 VAL</text>
<text class="ts" x="480" y="74" text-anchor="middle" dominant-baseline="central">score 0.006</text>
</g>
</svg>
```
### Geometry widget — always include ideal, actual, Z score:
For bond/angle/omega distortions, display as rows with severity colour. Omega torsion
outliers (|omega − 180°| > 15°) are the most sensitive backbone diagnostic and should
always be highlighted — they identify misplaced backbone immediately.
```svg
<g class="node c-red" onclick="sendPrompt('Go to A/259 SER and investigate distorted backbone')">
<rect x="36" y="50" width="600" height="22" rx="4" stroke-width="0.5"/>
<text class="ts" x="40" y="65">A/258→A/259 omega</text>
<text class="ts" x="380" y="65">60.0° (ideal 180°)</text>
<text class="ts" x="510" y="65" style="fill:#A32D2D">+24.0σ distorted!</text>
</g>
```
---
## Typical Validation & Fix Workflow
```python
# 1. Setup
coot.set_refinement_immediate_replacement(1)
# 2. Check what's loaded
for i in range(10):
if coot.is_valid_model_molecule(i):
print(f"Model {i}: {coot.molecule_name(i)}")
if coot.is_valid_map_molecule(i):
print(f"Map {i}: {coot.molecule_name(i)}")
# 3. Validate density fit
stats = coot.map_to_model_correlation_stats_per_residue_range_py(0, "A", 1, 1, 0)
worst = sorted(stats[0], key=lambda x: x[1][1])[:10]
# 4. Check for clashes
overlaps = coot.molecule_atom_overlaps_py(0, 30)
severe = [o for o in overlaps if o['overlap-volume'] > 5.0]
# 5. Fix bad rotamers
coot.auto_fit_best_rotamer(0, "A", 89, "", "", 1, 1, 0.01)
coot.refine_residues_py(0, [["A", 89, ""]])
# 6. Fix backbone issues
coot.pepflip(0, "A", 41, "", "")
coot.refine_residues_py(0, [["A", 40, ""], ["A", 41, ""], ["A", 42, ""]])
# 7. Re-validate
overlaps_after = coot.molecule_atom_overlaps_py(0, 10)
# 8. ALWAYS render results as an interactive SVG widget — see section above
```
## Important Notes
1. **Always call `set_refinement_immediate_replacement(1)` first** - makes refinement synchronous
3. **Use `coot.*_py()` functions directly** - faster than `coot_utils` wrappers
4. **Import coot_utils only when needed** - for convenience functions like `chain_ids()`
5. **The `coot` module is auto-imported** - no import statement needed
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!