mcpField
A
alterlab-bindingdb

alterlab-bindingdb

github.com/alterlab-ieuデータ・データベース7867 回インストール5 週間前に更新
リポジトリ

alterlab-bindingdb について

alterlab-bindingdbは、創薬、薬理学、計算化学向けにBindingDBのデータを検索・分析するスキルです。REST APIまたはダウンロードデータからタンパク質と化合物の実測親和性を取得し、UniProtやSMILESによる検索、SAR、多標的分析、機械学習用データの準備を支援します。

主な機能

  1. 01REST APIによる結合データ検索
  2. 02UniProt IDによる標的リガンド検索
  3. 03SMILESによる構造類似検索
  4. 04大規模分析向けTSVダウンロード
  5. 05SARと多標的結合の分析

活用シーン

  1. 01タンパク質標的の既知リガンド検索
  2. 02類似化合物間の親和性比較
  3. 03化合物の選択性とオフターゲットの評価
  4. 04機械学習向け親和性データセットの準備

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/alterlab-ieu/alterlab-academic-skills --skill alterlab-bindingdb

インストール後、Claude Code で/alterlab-bindingdbを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

evals/
evals.json
references/
affinity_queries.md
scripts/
query_bindingdb.py

詳細

BindingDB データベース

概要

BindingDB(https://www.bindingdb.org/)は、測定された薬物とタンパク質の結合親和性を収録する主要な公開データベースです。科学文献および特許文献から精選された、約140万種類の化合物と約11,500種類のタンパク質標的についての約320万件の結合データレコードが含まれています(ホームページの数値、2026-09)。BindingDB には、創薬、薬理学、計算化学研究に不可欠な定量的結合測定値(Ki、Kd、IC50、EC50)が保存されています。

主なリソース:

このスキルを使用する場面

次のような場合に BindingDB を使用します。

  • 標的ベースの創薬:標的タンパク質に結合する既知の化合物と、その親和性を調べる場合
  • SAR 解析:類似体の系列で、構造修飾が結合親和性にどのような影響を与えるかを調べる場合
  • リード化合物のプロファイリング:化合物がどの標的に結合するか(選択性/ポリファーマコロジー)を調べる場合
  • ベンチマークデータセット:ML モデルのトレーニングに使用する、精選されたタンパク質とリガンドの親和性データを取得する場合
  • ドラッグリポジショニング解析:承認薬が意図しない標的に結合するかを調べる場合
  • 競合分析:標的クラスについて、報告されている最も高い親和性を調べる場合
  • フラグメントスクリーニング:標的に対するフラグメントの検証済み結合データを探す場合
該当しない場合
シナリオ代わりに使用
アッセイメタデータや薬物作用機序を含む、大規模な精選済み生物活性データのマイニングalterlab-chembl
名前または CID による化合物識別子/特性の検索、PubChem BioAssayalterlab-pubchem
購入可能な類似体またはドッキング対応の3Dライブラリalterlab-zinc-db
リガンドを受容体構造にドッキングする場合alterlab-diffdock

主な機能

1. BindingDB REST API

ベース URL:https://bindingdb.org/rest

import requests

BASE_URL = "https://bindingdb.org/rest"

def bindingdb_query(method, params):
    """Query the BindingDB REST API."""
    url = f"{BASE_URL}/{method}"
    response = requests.get(url, params=params, headers={"Accept": "application/json"})
    response.raise_for_status()
    return response.json()
2. 標的によるクエリ(UniProt ID)

getLigandsByUniprot エンドポイントは、<UniProt accession>;<cutoff in nM> 形式の単一の uniprot パラメーターを受け取ります。例:P00519;10000。

def get_ligands_for_target(uniprot_id, cutoff=10000):
    """
    Get all ligands with measured affinity for a UniProt target.

    Args:
        uniprot_id: UniProt accession (e.g., "P00519" for ABL1)
        cutoff: Maximum affinity value to return (in nM)
    """
    params = {
        "uniprot": f"{uniprot_id};{cutoff}",
        "response": "application/json",
    }
    return bindingdb_query("getLigandsByUniprot", params)

# Example: Get all compounds binding ABL1 (imatinib target) at <=100 nM
ligands = get_ligands_for_target("P00519", cutoff=100)

# Response shape (verified 2026-09): one top-level key, spelled
# "getLindsByUniprotResponse" (sic — getTargetByCompound uses the same key),
# holding "bdb.hit" (count, as a string) and "bdb.affinities": a list of
# {"bdb.monomerid", "bdb.smile", "bdb.affinity_type", "bdb.affinity"}.
# Affinities are strings, may carry leading spaces or ">"/"<" qualifiers.
resp = next(iter(ligands.values()))
rows = resp.get("bdb.affinities", [])
3. SMILES によるクエリ(構造類似性)
def search_by_smiles(smiles, cutoff=0.85):
    """
    Search BindingDB by SMILES string (structural-similarity search).

    Args:
        smiles: SMILES string of the compound
        cutoff: Tanimoto similarity threshold (0.0-1.0; e.g. 0.85)
    """
    params = {
        "smiles": smiles,
        "cutoff": cutoff,
        "response": "application/json",
    }
    return bindingdb_query("getTargetByCompound", params)

# Example: structural-similarity search for imatinib's binding targets
result = search_by_smiles("Cc1ccc(NC(=O)c2ccc(CN3CCN(C)CC3)cc2)cc1Nc1nccc(-c2cccnc2)n1")

PubChem CID でクエリするには、まず PubChem PUG-REST を使って CID を SMILES 文字列に変換し、その後 search_by_smiles に渡します。BindingDB REST には、名前または CID による検索エンドポイントはありません。

4. ダウンロードによる解析(大規模なクエリに推奨)

包括的な解析には、BindingDB のデータを直接ダウンロードします。

import pandas as pd

def load_bindingdb(filepath="BindingDB_All.tsv"):
    """
    Load BindingDB TSV file (the unzipped BindingDB_All_<YYYYMM>.tsv).
    Download the dated BindingDB_All_<YYYYMM>_tsv.zip from:
    https://www.bindingdb.org/rwd/bind/chemsearch/marvin/Download.jsp
    """
    # Key columns
    usecols = [
        "BindingDB Reactant_set_id",
        "Ligand SMILES",
        "Ligand InChI",
        "Ligand InChI Key",
        "BindingDB Target Chain  Sequence",
        "PDB ID(s) for Ligand-Target Complex",
        "UniProt (SwissProt) Entry Name of Target Chain",
        "UniProt (SwissProt) Primary ID of Target Chain",
        "UniProt (TrEMBL) Primary ID of Target Chain",
        "Ki (nM)",
        "IC50 (nM)",
        "Kd (nM)",
        "EC50 (nM)",
        "kon (M-1-s-1)",
        "koff (s-1)",
        "Target Name",
        "Target Source Organism According to Curator or DataSource",
        "Number of Protein Chains in Target (>1 implies a multichain complex)",
        "PubChem CID",
        "PubChem SID",
        "ChEMBL ID of Ligand",
        "DrugBank ID of Ligand",
    ]

    # Exact TSV headers drift between monthly releases (some contain double
    # spaces), so intersect with the actual header rather than hard-failing.
    header = pd.read_csv(filepath, sep="\t", nrows=0).columns
    keep = [c for c in usecols if c in header]
    df = pd.read_csv(filepath, sep="\t", usecols=keep,
                     low_memory=False, on_bad_lines='skip')

    # Convert affinity columns to numeric
    for col in ["Ki (nM)", "IC50 (nM)", "Kd (nM)", "EC50 (nM)"]:
        if col in df.columns:
            df[col] = pd.to_numeric(df[col], errors='coerce')

    return df

def query_target_affinity(df, uniprot_id, affinity_types=None, max_nm=10000):
    """Query loaded BindingDB for a specific target."""
    if affinity_types is None:
        affinity_types = ["Ki (nM)", "IC50 (nM)", "Kd (nM)"]

    # Filter by UniProt ID
    mask = df["UniProt (SwissProt) Primary ID of Target Chain"] == uniprot_id
    target_df = df[mask].copy()

    # Filter by affinity cutoff
    has_affinity = pd.Series(False, index=target_df.index)
    for col in affinity_types:
        if col in target_df.columns:
            has_affinity |= target_df[col] <= max_nm

    result = target_df[has_affinity][["Ligand SMILES"] + affinity_types +
                                      ["PubChem CID", "ChEMBL ID of Ligand"]].dropna(how='all')
    return result.sort_values(affinity_types[0])
5. SAR 解析
import pandas as pd

def sar_analysis(df, target_uniprot, affinity_col="IC50 (nM)"):
    """
    Structure-activity relationship analysis for a target.
    Retrieves all compounds with affinity data and ranks by potency.
    """
    target_data = query_target_affinity(df, target_uniprot, [affinity_col])

    if target_data.empty:
        return target_data

    # Add pIC50 (negative log of IC50 in molar)
    if affinity_col in target_data.columns:
        target_data = target_data[target_data[affinity_col].notna()].copy()
        target_data["pAffinity"] = -((target_data[affinity_col] * 1e-9).apply(
            lambda x: __import__('math').log10(x)
        ))
        target_data = target_data.sort_values("pAffinity", ascending=False)

    return target_data

# Most potent compounds against EGFR (P00533)
# sar = sar_analysis(df, "P00533", "IC50 (nM)")
# print(sar.head(20))
6. ポリファーマコロジーのプロファイル
def polypharmacology_profile(df, ligand_smiles, affinity_cutoff_nM=1000):
    """
    Find all targets a compound binds to, by exact SMILES match.
    For tolerance to tautomers/salts/charge states, match on the InChIKey
    skeleton (first 14 chars of "Ligand InChI Key") instead of raw SMILES.
    """
    # Search by ligand SMILES (exact string match)
    mask = df["Ligand SMILES"] == ligand_smiles

    ligand_data = df[mask].copy()

    # Filter by affinity
    aff_cols = ["Ki (nM)", "IC50 (nM)", "Kd (nM)"]
    has_aff = pd.Series(False, index=ligand_data.index)
    for col in aff_cols:
        if col in ligand_data.columns:
            has_aff |= ligand_data[col] <= affinity_cutoff_nM

    result = ligand_data[has_aff][
        ["Target Name", "UniProt (SwissProt) Primary ID of Target Chain"] + aff_cols
    ].dropna(how='all')

    # Rank by the tightest measured constant per row (NaNs ignored)
    result = result.assign(best_nM=result[aff_cols].min(axis=1))
    return result.sort_values("best_nM")

クエリのワークフロー

ワークフロー 1:標的に対する最良の阻害剤を探す
import pandas as pd

def find_best_inhibitors(uniprot_id, affinity_type="IC50 (nM)", top_n=20):
    """Find the most potent inhibitors for a target in BindingDB."""
    df = load_bindingdb("BindingDB_All.tsv")  # Load once and reuse
    result = query_target_affinity(df, uniprot_id, [affinity_type])

    if result.empty:
        print(f"No data found for {uniprot_id}")
        return result

    result = result.sort_values(affinity_type).head(top_n)
    print(f"Top {top_n} inhibitors for {uniprot_id} by {affinity_type}:")
    for _, row in result.iterrows():
        print(f"  {row['PubChem CID']}: {row[affinity_type]:.1f} nM | SMILES: {row['Ligand SMILES'][:40]}...")
    return result
ワークフロー 2:選択性のプロファイリング
  1. すべての標的にわたる化合物の親和性データを取得します
  2. オンターゲットとオフターゲットの親和性比を比較します
  3. 選択性のクリフ(選択性を向上させる構造変化)を特定します
  4. ChEMBL と照合して、選択性に関する追加データを確認します
ワークフロー 3:機械学習データセットの準備
def prepare_ml_dataset(df, uniprot_ids, affinity_col="IC50 (nM)",
                        max_affinity_nM=100000, min_count=50):
    """Prepare BindingDB data for ML model training."""
    records = []
    for uid in uniprot_ids:
        target_df = query_target_affinity(df, uid, [affinity_col], max_affinity_nM)
        if len(target_df) >= min_count:
            target_df = target_df.copy()
            target_df["target"] = uid
            records.append(target_df)

    if not records:
        return pd.DataFrame()

    combined = pd.concat(records)
    # Add pAffinity (normalized)
    combined["pAffinity"] = -((combined[affinity_col] * 1e-9).apply(
        lambda x: __import__('math').log10(max(x, 1e-12))
    ))
    return combined[["Ligand SMILES", "target", "pAffinity", affinity_col]].dropna()

主なデータフィールド

フィールド説明
Ligand SMILES化合物の2D構造
Ligand InChI Key一意の化学識別子
Ki (nM)阻害定数(平衡時、機能的)
Kd (nM)解離定数(熱力学的、結合)
IC50 (nM)50%阻害濃度
EC50 (nM)50%有効濃度
kon (M-1-s-1)結合速度定数
koff (s-1)解離速度定数
UniProt (SwissProt) Primary ID標的の UniProt アクセッション
Target Nameタンパク質名
PDB ID(s) for Ligand-Target Complex結晶構造
PubChem CIDPubChem 化合物 ID
ChEMBL ID of LigandChEMBL 化合物 ID

親和性の解釈

親和性分類薬物らしさ
< 1 nMサブナノモル非常に強力(ピコモル範囲)
1–10 nMナノモル強力で、承認薬に一般的な範囲
10–100 nM中程度一般的なリード化合物
100–1000 nM弱いフラグメント/出発点
> 1000 nM非常に弱い一般に薬物としての関連性の基準を下回る

ベストプラクティス

  • 直接結合にはKiを使用:Kiは酵素の作用機序に依存せず、真の結合親和性を反映します
  • IC50は状況に依存:IC50値は基質濃度によって変わります(Cheng-Prusoffの式)
  • 修飾子の接頭辞に注意:TSVの親和性セルには、打ち切り測定値を示す >、<、>= などの接頭辞が付いていることがよくあります(例:>10000)。pd.to_numeric(errors='coerce') を使うと、これらは警告なくNaNに変換されます。まず接頭辞を削除し(例:df[col].astype(str).str.lstrip("<>= "))、モデリングの前に打ち切り値を保持するか、除外するか、不等式として扱うかを明示的に決定してください
  • 単位を正規化:BindingDBの報告値はnMです。研究間で比較する際は単位を確認してください
  • 標的生物種でフィルタリング:Target Source Organism を使用して、ヒトタンパク質のデータを確保してください
  • 欠損値を処理:すべての化合物にすべての測定タイプの値があるわけではありません
  • ChEMBLとの相互参照:ChEMBLには、メディシナルケミストリー向けに、より多くのキュレーション済み活性データがあります

追加リソース

スクリプト

scripts/query_bindingdb.py — BindingDB REST API用の実行可能なヘルパー(キー不要):

python scripts/query_bindingdb.py uniprot P00519 --cutoff 10000
python scripts/query_bindingdb.py pdb 1Q0L,3ANM --cutoff 100 --identity 92
python scripts/query_bindingdb.py compound "<SMILES>" --cutoff 0.85

コメント