Skip to content

About

Six-dimensional PDB structure scoring for structure-based virtual screening (SBVS) — zero-dependency Python CLI + agent skill.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PDB Select

Pick the right PDB entry for structure-based virtual screening (SBVS) — with a score you can drill into, not just "the one with the best resolution".

Python Dependencies License

pdb-select pulls every experimental structure of a target from RCSB PDB, ranks them with a six-dimensional, fully explainable heuristic score, and hands the shortlist to an AI/human review step that fixes what heuristics can't judge. The output is a ranked table plus a JSON file where every number traces back to its evidence (per-ligand classification, coverage source, resolution basis, quality flags).


Why this exists

Selecting a starting structure by resolution alone is a trap. Real failures this tool was built to catch, all found in actual runs:

Failure What happens without a structured score
A 102 Da crystallisation additive outranks a confirmed drug. Malonate (MLI) is not a drug, but "any unlisted organic molecule < 500 Da" scores the same as a validated drug. Your top hit is a structure with a buffer molecule in a surface pocket.
Cryo-EM entries get scored on the X-ray curve. RCSB returns ELECTRON MICROSCOPY as the method string — a naive "em" in method test never fires, so 3 Å cryo-EM silently loses to 3 Å X-ray. Cryo-EM structures (often the only ones for large complexes) are systematically under-ranked.
A single page request truncates the structure list. KRAS has 568 structures; a rows=200 query silently drops 368 of them before scoring even starts. The best structure may never be considered.
A vague gene query resolves to the wrong protein. Fuzzy gene→UniProt lookup returns an empty gene name and nobody notices. You rank the wrong target.

Every one of those is fixed and verified against live endpoints in this version (there is no automated test suite yet — that is on the roadmap, and the examples/ output is a real run).


Requirements

  • Python ≥ 3.9
  • Zero third-party dependencies. Standard library only (urllib, json, argparse).
  • Network access to search.rcsb.org, data.rcsb.org, rest.uniprot.org. No API key needed — only public, unauthenticated endpoints are used.

Quick start

git clone https://github.com/<you>/pdb-select.git
cd pdb-select

# rank every structure of a target by gene symbol (human by default)
python scripts/pdb_scorer.py --gene MYH7 --top 10

# by UniProt accession, straight to a JSON file
python scripts/pdb_scorer.py --uniprot P12883 --output myh7_result.json

# clean JSON on stdout, safe to pipe
python scripts/pdb_scorer.py --gene SOD1 --no-table | jq '.results[0]'

Options

Flag Meaning
--gene Gene symbol (e.g. MYH7). Resolved with gene_exact + species filter, so it won't drift to the wrong protein.
--uniprot UniProt accession (e.g. P12883). Skips gene resolution.
--taxon NCBI taxonomy id used with --gene. Default 9606 (human).
--top How many rows to print in the terminal table. Default 20. The JSON always contains all scored structures.
--output Write the JSON result to a file.
--no-table Suppress the table; JSON goes to stdout instead (pipe-friendly).

Real output (MYH7, trimmed to 8 rows)

  排名 PDB      分辨率      方法             配体      特异性    覆盖    分辨    质量     总分  标题
------------------------------------------------------------------------------------------------------
   1 4PA0     2.25Å    X-RAY DIFF  +1000     +300  +350   +90     0  +1740  Omecamtiv Mercarbil binding site on the Human Beta
   2 9GZ2     2.90Å    ELECTRON M  +1000     -100  +350   +82     0  +1332  Beta-cardiac heavy meromyosin motor domain in the
   3 9YP9     3.00Å    ELECTRON M  +1000     -100  +350   +80     0  +1330  Cryo-EM structure of human beta-cardiac myosin bou
   4 9YR7     3.00Å    ELECTRON M  +1000     -100  +350   +80     0  +1330  Cryo-EM structure of human beta-cardiac myosin bou
   5 9YRH     3.80Å    ELECTRON M  +1000     -100  +350   +60     0  +1310  (…)
   6 9YP4     4.50Å    ELECTRON M  +1000     -100  +350   +42     0  +1292  (…)
   7 9GZ1     3.70Å    ELECTRON M  +1000     -500  +350   +62     0   +912  Beta-cardiac myosin interacting heads motif comple
   8 9HTF     2.48Å    X-RAY DIFF   +400     +200  +200   +81     0   +881  (…)

It also catches what the eye misses — rank 7 (9GZ1) is a valid, well-resolved cryo-EM structure that is correctly pushed down as an interacting heads motif assembly (specificity −500), i.e. a different biological state than a screening-ready motor domain.

The full JSON behind this run is in examples/myh7_result.json.


The scoring model

Total score = sum of six dimensions.

Dimension Rule
Ligand Known drug (explicit table) +1000 · Drug-like small molecule (150–600 Da) +700 · Large organic (>600 Da) +500 · Nucleotide/cofactor (ADP, ATP, NAD, FAD, HEM, SAM, …) +400 · Additive/metabolite (<150 Da, e.g. malonate, acetate, DMSO) +200 · Detergent/glycan +200 · None 0
Specificity Monomer with ligand +300 · Monomer without ligand +200 · Native dimer +100 · Mid-size complex −100 · Large complex −500 · Very large assembly −2000
Coverage ≥80% +500 · ≥50% +350 · ≥30% +200 · <30% 0
Resolution X-ray: 100 − (res − 2.0) × 40 · Cryo-EM: 80 − (res − 3.0) × 25 · clamped to [20, 100]
Structural quality R-free > 0.3 −50 · Ramachandran outliers > 5% −50
Ligand placement Not computed by the script (always 0) — requires 3D geometry + functional-site annotation, so it is explicitly deferred to AI/human review

Why these weights

  • Known drug and "drug-like" are scored separately, on purpose. The single most dangerous scoring bug is letting any unlisted small molecule take the full drug bonus — a 102 Da crystallisation additive then ties with a validated drug, and the whole ranking becomes untrustworthy. Drug evidence must come from an explicit table; molecular weight is only a fallback tier, one step below. Cofactors (nucleotides, hemes, SAM…) get their own tier because they usefully define a pocket without being drug evidence.
  • Exclusion lists can never be exhaustive, so they are not the primary mechanism. They only remove things that are definitely not drug evidence (ions, buffers, cryoprotectants); everything else falls through to the molecular-weight + chemistry-type tiering.
  • "Has a real ligand" is bound to the tier (≥ drug-like), and it simultaneously drives the specificity branch (+300 vs +200). One definition, no drift.
  • Complexity is a negative signal for SBVS. A ligand bound in a very large assembly is weak evidence of a druggable isolated pocket, hence −500 / −2000.
  • The two resolution curves are empirical, not physical. They encode "what is good enough for docking", with cryo-EM offset by 1 Å because its nominal resolution overstates local pocket quality. ELECTRON CRYSTALLOGRAPHY intentionally stays on the X-ray curve.

Two-stage design: script coarse ranking → AI review

The script is deliberately not the final authority. SKILL.md defines the review pass that every run should go through:

  1. Specificity mis-classification — title keywords and chain counts misread domain-only constructs, HMM fragments, interacting-heads motifs and actin-containing filaments.
  2. Ligand curation — promote unlisted real drugs into KNOWN_DRUG_LIGANDS, demote additives/buffers, and handle covalent/peptide ligands outside the small-molecule tiers.
  3. Coverage correction — fusions and truncated constructs under-estimate coverage; chains that only resolve part of the protein over-estimate it.
  4. Ligand placement — the dimension the script deliberately leaves at 0: check that the ligand sits within ~5 Å of a functional-site residue rather than on an irrelevant surface patch.

Output contract

Stream Content
stdout The ranking table (suppressed by --no-table)
stderr Progress and diagnostics
JSON Written to --output FILE; with no --output it goes to stdout only when --no-table is set

The table and the JSON never share stdout, so | jq is always safe. Each JSON result carries scores (per-dimension), ligand_hits (every ligand with its tier and score), specificity, coverage_pct, resolution_basis (xray/cryoem) and quality_detail.

The script makes no assumption about downstream format — read the JSON and do whatever you want with it (write a database, fill your own shortlist tables, batch over many targets).


Extending it

Add your own drugs and exclusion rules at the top of scripts/pdb_scorer.py:

KNOWN_DRUG_LIGANDS = {
    "XB2": "mavacamten",
    "MY1": "my-own-inhibitor",   # comp_id -> name, scored +1000
}

RCSB comp_ids are the PDB chemical component codes (the same ones you see in HETATM records).


Use it as an agent skill

The repo root is also a valid Agent Skill: SKILL.md describes when to use it, how to run the scorer, and the mandatory review pass. Install it into your agent's skills directory (e.g. ~/.claude/skills/, ~/.hermes/skills/) and the agent will pick the script up automatically. The script works perfectly well as a plain CLI too — the skill is an add-on, not a requirement.


Roadmap

  • Externalise scoring weights (--weights / config file) so the model can be tuned without editing code
  • Automated smoke test across a few targets
  • Optional PDB entry download + ligand-pocket distance check (implements the deferred dimension)

Provenance

Extracted from the structure-selection step of an internal rare-disease-target virtual screening workflow, cleaned up and released as a standalone tool. Built and tested against live RCSB and UniProt endpoints, not against mocks.


中文速览

干什么用的: 给定靶点,把 RCSB PDB 上全部相关结构按六维评分排序,挑出最适合做基于结构的 虚拟筛选(SBVS)的起始结构——不只是"分辨率最高的那个",而是一份每个分数都能下钻到依据的排名。

为什么需要它: 按分辨率盲选有三个真坑:① 丙二酸(丙二酸根,MW 102 的结晶添加剂)会和 mavacamten 这种确证药物同分;② RCSB 的冷冻电镜方法字符串是 ELECTRON MICROSCOPY,按 em 子串判断永远不命中,导致 cryo-EM 结构被按 X 光曲线低估;③ 单页查询会把 KRAS 的 568 个结构 截断到 200 个。这三个坑本版本全部修掉并有回归验证。

怎么用: python scripts/pdb_scorer.py --gene MYH7 --top 10,零第三方依赖,只要 Python ≥ 3.9。

设计要点: 脚本只做启发式粗筛,必须再走一遍 SKILL.md 里的 AI 复审(特异性分类修正、 配体补充、覆盖度修正、以及脚本故意不做的配体定位判断——配体是否占据功能位点)。


License

MIT — see LICENSE.

About

Six-dimensional PDB structure scoring for structure-based virtual screening (SBVS) — zero-dependency Python CLI + agent skill.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages