Skip to content

Commit 7f94783

Browse files
committed
Add scVelo RNA velocity analysis workflow and IQ-TREE reference documentation
- Introduced a comprehensive RNA velocity analysis pipeline using scVelo, including data loading, preprocessing, velocity estimation, and visualization. - Added a script for running RNA velocity analysis with customizable parameters and output options. - Created detailed documentation for IQ-TREE 2 phylogenetic inference, covering command syntax, model selection, bootstrapping methods, and output interpretation. - Included references for velocity models and their mathematical framework, along with a comparison of different models. - Enhanced the scVelo skill documentation with installation instructions, use cases, and best practices for RNA velocity analysis.
1 parent b271271 commit 7f94783

27 files changed

Lines changed: 6961 additions & 0 deletions

File tree

Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
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

Comments
 (0)