|
| 1 | +--- |
| 2 | +name: bindingdb-database |
| 3 | +description: Query BindingDB for measured drug-target binding affinities (Ki, Kd, IC50, EC50). Search by target (UniProt ID), compound (SMILES/name), or pathogen. Essential for drug discovery, lead optimization, polypharmacology analysis, and structure-activity relationship (SAR) studies. |
| 4 | +license: CC-BY-3.0 |
| 5 | +metadata: |
| 6 | + skill-author: Kuan-lin Huang |
| 7 | +--- |
| 8 | + |
| 9 | +# BindingDB Database |
| 10 | + |
| 11 | +## Overview |
| 12 | + |
| 13 | +BindingDB (https://www.bindingdb.org/) is the primary public database of measured drug-protein binding affinities. It contains over 3 million binding data records for ~1.4 million compounds tested against ~9,200 protein targets, curated from scientific literature and patent literature. BindingDB stores quantitative binding measurements (Ki, Kd, IC50, EC50) essential for drug discovery, pharmacology, and computational chemistry research. |
| 14 | + |
| 15 | +**Key resources:** |
| 16 | +- BindingDB website: https://www.bindingdb.org/ |
| 17 | +- REST API: https://www.bindingdb.org/axis2/services/BDBService |
| 18 | +- Downloads: https://www.bindingdb.org/bind/chemsearch/marvin/Download.jsp |
| 19 | +- GitHub: https://github.com/drugilsberg/bindingdb |
| 20 | + |
| 21 | +## When to Use This Skill |
| 22 | + |
| 23 | +Use BindingDB when: |
| 24 | + |
| 25 | +- **Target-based drug discovery**: What known compounds bind to a target protein? What are their affinities? |
| 26 | +- **SAR analysis**: How do structural modifications affect binding affinity for a series of analogs? |
| 27 | +- **Lead compound profiling**: What targets does a compound bind (selectivity/polypharmacology)? |
| 28 | +- **Benchmark datasets**: Obtain curated protein-ligand affinity data for ML model training |
| 29 | +- **Repurposing analysis**: Does an approved drug bind to an unintended target? |
| 30 | +- **Competitive analysis**: What is the best reported affinity for a target class? |
| 31 | +- **Fragment screening**: Find validated binding data for fragments against a target |
| 32 | + |
| 33 | +## Core Capabilities |
| 34 | + |
| 35 | +### 1. BindingDB REST API |
| 36 | + |
| 37 | +Base URL: `https://www.bindingdb.org/axis2/services/BDBService` |
| 38 | + |
| 39 | +```python |
| 40 | +import requests |
| 41 | + |
| 42 | +BASE_URL = "https://www.bindingdb.org/axis2/services/BDBService" |
| 43 | + |
| 44 | +def bindingdb_query(method, params): |
| 45 | + """Query the BindingDB REST API.""" |
| 46 | + url = f"{BASE_URL}/{method}" |
| 47 | + response = requests.get(url, params=params, headers={"Accept": "application/json"}) |
| 48 | + response.raise_for_status() |
| 49 | + return response.json() |
| 50 | +``` |
| 51 | + |
| 52 | +### 2. Query by Target (UniProt ID) |
| 53 | + |
| 54 | +```python |
| 55 | +def get_ligands_for_target(uniprot_id, affinity_type="Ki", cutoff=10000, unit="nM"): |
| 56 | + """ |
| 57 | + Get all ligands with measured affinity for a UniProt target. |
| 58 | +
|
| 59 | + Args: |
| 60 | + uniprot_id: UniProt accession (e.g., "P00519" for ABL1) |
| 61 | + affinity_type: "Ki", "Kd", "IC50", "EC50" |
| 62 | + cutoff: Maximum affinity value to return (in nM) |
| 63 | + unit: "nM" or "uM" |
| 64 | + """ |
| 65 | + params = { |
| 66 | + "uniprot_id": uniprot_id, |
| 67 | + "affinity_type": affinity_type, |
| 68 | + "affinity_cutoff": cutoff, |
| 69 | + "response": "json" |
| 70 | + } |
| 71 | + return bindingdb_query("getLigandsByUniprotID", params) |
| 72 | + |
| 73 | +# Example: Get all compounds binding ABL1 (imatinib target) |
| 74 | +ligands = get_ligands_for_target("P00519", affinity_type="Ki", cutoff=100) |
| 75 | +``` |
| 76 | + |
| 77 | +### 3. Query by Compound Name or SMILES |
| 78 | + |
| 79 | +```python |
| 80 | +def search_by_name(compound_name, limit=100): |
| 81 | + """Search BindingDB for compounds by name.""" |
| 82 | + params = { |
| 83 | + "compound_name": compound_name, |
| 84 | + "response": "json", |
| 85 | + "max_results": limit |
| 86 | + } |
| 87 | + return bindingdb_query("getAffinitiesByCompoundName", params) |
| 88 | + |
| 89 | +def search_by_smiles(smiles, similarity=100, limit=50): |
| 90 | + """ |
| 91 | + Search BindingDB by SMILES string. |
| 92 | +
|
| 93 | + Args: |
| 94 | + smiles: SMILES string of the compound |
| 95 | + similarity: Tanimoto similarity threshold (1-100, 100 = exact) |
| 96 | + """ |
| 97 | + params = { |
| 98 | + "SMILES": smiles, |
| 99 | + "similarity": similarity, |
| 100 | + "response": "json", |
| 101 | + "max_results": limit |
| 102 | + } |
| 103 | + return bindingdb_query("getAffinitiesByBEI", params) |
| 104 | + |
| 105 | +# Example: Search for imatinib binding data |
| 106 | +result = search_by_name("imatinib") |
| 107 | +``` |
| 108 | + |
| 109 | +### 4. Download-Based Analysis (Recommended for Large Queries) |
| 110 | + |
| 111 | +For comprehensive analyses, download BindingDB data directly: |
| 112 | + |
| 113 | +```python |
| 114 | +import pandas as pd |
| 115 | + |
| 116 | +def load_bindingdb(filepath="BindingDB_All.tsv"): |
| 117 | + """ |
| 118 | + Load BindingDB TSV file. |
| 119 | + Download from: https://www.bindingdb.org/bind/chemsearch/marvin/Download.jsp |
| 120 | + """ |
| 121 | + # Key columns |
| 122 | + usecols = [ |
| 123 | + "BindingDB Reactant_set_id", |
| 124 | + "Ligand SMILES", |
| 125 | + "Ligand InChI", |
| 126 | + "Ligand InChI Key", |
| 127 | + "BindingDB Target Chain Sequence", |
| 128 | + "PDB ID(s) for Ligand-Target Complex", |
| 129 | + "UniProt (SwissProt) Entry Name of Target Chain", |
| 130 | + "UniProt (SwissProt) Primary ID of Target Chain", |
| 131 | + "UniProt (TrEMBL) Primary ID of Target Chain", |
| 132 | + "Ki (nM)", |
| 133 | + "IC50 (nM)", |
| 134 | + "Kd (nM)", |
| 135 | + "EC50 (nM)", |
| 136 | + "kon (M-1-s-1)", |
| 137 | + "koff (s-1)", |
| 138 | + "Target Name", |
| 139 | + "Target Source Organism According to Curator or DataSource", |
| 140 | + "Number of Protein Chains in Target (>1 implies a multichain complex)", |
| 141 | + "PubChem CID", |
| 142 | + "PubChem SID", |
| 143 | + "ChEMBL ID of Ligand", |
| 144 | + "DrugBank ID of Ligand", |
| 145 | + ] |
| 146 | + |
| 147 | + df = pd.read_csv(filepath, sep="\t", usecols=[c for c in usecols if c], |
| 148 | + low_memory=False, on_bad_lines='skip') |
| 149 | + |
| 150 | + # Convert affinity columns to numeric |
| 151 | + for col in ["Ki (nM)", "IC50 (nM)", "Kd (nM)", "EC50 (nM)"]: |
| 152 | + if col in df.columns: |
| 153 | + df[col] = pd.to_numeric(df[col], errors='coerce') |
| 154 | + |
| 155 | + return df |
| 156 | + |
| 157 | +def query_target_affinity(df, uniprot_id, affinity_types=None, max_nm=10000): |
| 158 | + """Query loaded BindingDB for a specific target.""" |
| 159 | + if affinity_types is None: |
| 160 | + affinity_types = ["Ki (nM)", "IC50 (nM)", "Kd (nM)"] |
| 161 | + |
| 162 | + # Filter by UniProt ID |
| 163 | + mask = df["UniProt (SwissProt) Primary ID of Target Chain"] == uniprot_id |
| 164 | + target_df = df[mask].copy() |
| 165 | + |
| 166 | + # Filter by affinity cutoff |
| 167 | + has_affinity = pd.Series(False, index=target_df.index) |
| 168 | + for col in affinity_types: |
| 169 | + if col in target_df.columns: |
| 170 | + has_affinity |= target_df[col] <= max_nm |
| 171 | + |
| 172 | + result = target_df[has_affinity][["Ligand SMILES"] + affinity_types + |
| 173 | + ["PubChem CID", "ChEMBL ID of Ligand"]].dropna(how='all') |
| 174 | + return result.sort_values(affinity_types[0]) |
| 175 | +``` |
| 176 | + |
| 177 | +### 5. SAR Analysis |
| 178 | + |
| 179 | +```python |
| 180 | +import pandas as pd |
| 181 | + |
| 182 | +def sar_analysis(df, target_uniprot, affinity_col="IC50 (nM)"): |
| 183 | + """ |
| 184 | + Structure-activity relationship analysis for a target. |
| 185 | + Retrieves all compounds with affinity data and ranks by potency. |
| 186 | + """ |
| 187 | + target_data = query_target_affinity(df, target_uniprot, [affinity_col]) |
| 188 | + |
| 189 | + if target_data.empty: |
| 190 | + return target_data |
| 191 | + |
| 192 | + # Add pIC50 (negative log of IC50 in molar) |
| 193 | + if affinity_col in target_data.columns: |
| 194 | + target_data = target_data[target_data[affinity_col].notna()].copy() |
| 195 | + target_data["pAffinity"] = -((target_data[affinity_col] * 1e-9).apply( |
| 196 | + lambda x: __import__('math').log10(x) |
| 197 | + )) |
| 198 | + target_data = target_data.sort_values("pAffinity", ascending=False) |
| 199 | + |
| 200 | + return target_data |
| 201 | + |
| 202 | +# Most potent compounds against EGFR (P00533) |
| 203 | +# sar = sar_analysis(df, "P00533", "IC50 (nM)") |
| 204 | +# print(sar.head(20)) |
| 205 | +``` |
| 206 | + |
| 207 | +### 6. Polypharmacology Profile |
| 208 | + |
| 209 | +```python |
| 210 | +def polypharmacology_profile(df, ligand_smiles_or_name, affinity_cutoff_nM=1000): |
| 211 | + """ |
| 212 | + Find all targets a compound binds to. |
| 213 | + Uses PubChem CID or SMILES for matching. |
| 214 | + """ |
| 215 | + # Search by ligand SMILES (exact match) |
| 216 | + mask = df["Ligand SMILES"] == ligand_smiles_or_name |
| 217 | + |
| 218 | + ligand_data = df[mask].copy() |
| 219 | + |
| 220 | + # Filter by affinity |
| 221 | + aff_cols = ["Ki (nM)", "IC50 (nM)", "Kd (nM)"] |
| 222 | + has_aff = pd.Series(False, index=ligand_data.index) |
| 223 | + for col in aff_cols: |
| 224 | + if col in ligand_data.columns: |
| 225 | + has_aff |= ligand_data[col] <= affinity_cutoff_nM |
| 226 | + |
| 227 | + result = ligand_data[has_aff][ |
| 228 | + ["Target Name", "UniProt (SwissProt) Primary ID of Target Chain"] + aff_cols |
| 229 | + ].dropna(how='all') |
| 230 | + |
| 231 | + return result.sort_values("Ki (nM)") |
| 232 | +``` |
| 233 | + |
| 234 | +## Query Workflows |
| 235 | + |
| 236 | +### Workflow 1: Find Best Inhibitors for a Target |
| 237 | + |
| 238 | +```python |
| 239 | +import pandas as pd |
| 240 | + |
| 241 | +def find_best_inhibitors(uniprot_id, affinity_type="IC50 (nM)", top_n=20): |
| 242 | + """Find the most potent inhibitors for a target in BindingDB.""" |
| 243 | + df = load_bindingdb("BindingDB_All.tsv") # Load once and reuse |
| 244 | + result = query_target_affinity(df, uniprot_id, [affinity_type]) |
| 245 | + |
| 246 | + if result.empty: |
| 247 | + print(f"No data found for {uniprot_id}") |
| 248 | + return result |
| 249 | + |
| 250 | + result = result.sort_values(affinity_type).head(top_n) |
| 251 | + print(f"Top {top_n} inhibitors for {uniprot_id} by {affinity_type}:") |
| 252 | + for _, row in result.iterrows(): |
| 253 | + print(f" {row['PubChem CID']}: {row[affinity_type]:.1f} nM | SMILES: {row['Ligand SMILES'][:40]}...") |
| 254 | + return result |
| 255 | +``` |
| 256 | + |
| 257 | +### Workflow 2: Selectivity Profiling |
| 258 | + |
| 259 | +1. Get all affinity data for your compound across all targets |
| 260 | +2. Compare affinity ratios between on-target and off-targets |
| 261 | +3. Identify selectivity cliffs (structural changes that improve selectivity) |
| 262 | +4. Cross-reference with ChEMBL for additional selectivity data |
| 263 | + |
| 264 | +### Workflow 3: Machine Learning Dataset Preparation |
| 265 | + |
| 266 | +```python |
| 267 | +def prepare_ml_dataset(df, uniprot_ids, affinity_col="IC50 (nM)", |
| 268 | + max_affinity_nM=100000, min_count=50): |
| 269 | + """Prepare BindingDB data for ML model training.""" |
| 270 | + records = [] |
| 271 | + for uid in uniprot_ids: |
| 272 | + target_df = query_target_affinity(df, uid, [affinity_col], max_affinity_nM) |
| 273 | + if len(target_df) >= min_count: |
| 274 | + target_df = target_df.copy() |
| 275 | + target_df["target"] = uid |
| 276 | + records.append(target_df) |
| 277 | + |
| 278 | + if not records: |
| 279 | + return pd.DataFrame() |
| 280 | + |
| 281 | + combined = pd.concat(records) |
| 282 | + # Add pAffinity (normalized) |
| 283 | + combined["pAffinity"] = -((combined[affinity_col] * 1e-9).apply( |
| 284 | + lambda x: __import__('math').log10(max(x, 1e-12)) |
| 285 | + )) |
| 286 | + return combined[["Ligand SMILES", "target", "pAffinity", affinity_col]].dropna() |
| 287 | +``` |
| 288 | + |
| 289 | +## Key Data Fields |
| 290 | + |
| 291 | +| Field | Description | |
| 292 | +|-------|-------------| |
| 293 | +| `Ligand SMILES` | 2D structure of the compound | |
| 294 | +| `Ligand InChI Key` | Unique chemical identifier | |
| 295 | +| `Ki (nM)` | Inhibition constant (equilibrium, functional) | |
| 296 | +| `Kd (nM)` | Dissociation constant (thermodynamic, binding) | |
| 297 | +| `IC50 (nM)` | Half-maximal inhibitory concentration | |
| 298 | +| `EC50 (nM)` | Half-maximal effective concentration | |
| 299 | +| `kon (M-1-s-1)` | Association rate constant | |
| 300 | +| `koff (s-1)` | Dissociation rate constant | |
| 301 | +| `UniProt (SwissProt) Primary ID` | Target UniProt accession | |
| 302 | +| `Target Name` | Protein name | |
| 303 | +| `PDB ID(s) for Ligand-Target Complex` | Crystal structures | |
| 304 | +| `PubChem CID` | PubChem compound ID | |
| 305 | +| `ChEMBL ID of Ligand` | ChEMBL compound ID | |
| 306 | + |
| 307 | +## Affinity Interpretation |
| 308 | + |
| 309 | +| Affinity | Classification | Drug-likeness | |
| 310 | +|----------|---------------|---------------| |
| 311 | +| < 1 nM | Sub-nanomolar | Very potent (picomolar range) | |
| 312 | +| 1–10 nM | Nanomolar | Potent, typical for approved drugs | |
| 313 | +| 10–100 nM | Moderate | Common lead compounds | |
| 314 | +| 100–1000 nM | Weak | Fragment/starting point | |
| 315 | +| > 1000 nM | Very weak | Generally below drug-relevance threshold | |
| 316 | + |
| 317 | +## Best Practices |
| 318 | + |
| 319 | +- **Use Ki for direct binding**: Ki reflects true binding affinity independent of enzymatic mechanism |
| 320 | +- **IC50 context-dependency**: IC50 values depend on substrate concentration (Cheng-Prusoff equation) |
| 321 | +- **Normalize units**: BindingDB reports in nM; verify units when comparing across studies |
| 322 | +- **Filter by target organism**: Use `Target Source Organism` to ensure human protein data |
| 323 | +- **Handle missing values**: Not all compounds have all measurement types |
| 324 | +- **Cross-reference with ChEMBL**: ChEMBL has more curated activity data for medicinal chemistry |
| 325 | + |
| 326 | +## Additional Resources |
| 327 | + |
| 328 | +- **BindingDB website**: https://www.bindingdb.org/ |
| 329 | +- **Data downloads**: https://www.bindingdb.org/bind/chemsearch/marvin/Download.jsp |
| 330 | +- **API documentation**: https://www.bindingdb.org/bind/BindingDBRESTfulAPI.jsp |
| 331 | +- **Citation**: Gilson MK et al. (2016) Nucleic Acids Research. PMID: 26481362 |
| 332 | +- **Related resources**: ChEMBL (https://www.ebi.ac.uk/chembl/), PubChem BioAssay |
0 commit comments