medchem について
medchem は、創薬で化合物ライブラリをフィルタリングし、優先順位を付ける Python ライブラリとスキルです。メディシナルケミストリーのルール、構造アラート、複雑度指標、クエリ言語を組み合わせた選別に対応します。
主な機能
- 01ドラッグライクネスルールの適用
- 02構造アラートとカタログによる選別
- 03分子複雑度の評価
- 04化学基の検出
- 05クエリ言語による条件の組み合わせ
活用シーン
- 01化合物ライブラリの初期選別
- 02ヒットからリードへの候補選定
- 03リード最適化候補の選別
- 04指定した官能基を持つ化合物の検索
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ kalarislabs/ research-agent-skills --skill medchemインストール後、Claude Code で/medchemを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/api_guide.mdrules_catalog.mdscripts/filter_molecules.py詳細
Medchem
概要
Medchem は、創薬における分子のフィルタリングと優先順位付けを行う datamol-io の Python ライブラリです。文献に基づくドラッグライクネスのルール、名前付きアラートカタログ、複雑さのしきい値、化学基の検出、カスタムクエリ言語を適用して、化合物ライブラリを大規模にトリアージできます。フィルターは状況に応じたガイドラインです。専門知識や標的に関する知見と組み合わせてください。
バージョンに関する注意: 例は medchem 2.0.5(PyPI の安定版、2024 年 11 月)を対象としています。Python ≥3.9 が必要です。datamol と RDKit に依存します(自動的にインストールされます)。RuleFilters と構造フィルターのクラスは pandas DataFrame を返します。Lilly demerits を使用するには、オプションのネイティブバイナリが必要です(mamba install lilly-medchem-rules)。
このスキルを使用する場面
以下の場合にこのスキルを使用してください。
- 化合物ライブラリにドラッグライクネスのルール(Lipinski、Veber、CNS、リードライクなど)を適用する
- 構造アラート、PAINS、NIBR スクリーニングデッキのルールで分子をフィルタリングする
- ヒットからリードへの移行やリード最適化のために化合物の優先順位を付ける
- ZINC 由来のしきい値と比較する複雑さの指標を計算する
- 官能基や名前付き部分構造カタログを検出する
- medchem クエリ言語で複数条件のフィルターを構築する
インストール
uv pip install medchem datamol
オプション — Eli Lilly の減点フィルター(conda-forge のネイティブバイナリが必要です)。
mamba install -c conda-forge lilly-medchem-rules
主な機能
1. メディシナルケミストリーのルール
medchem.rules を使用して、確立されたドラッグライクネスのルールを適用します。
利用可能なルールの一覧:
import medchem as mc
mc.rules.RuleFilters.list_available_rules_names()
# ['rule_of_five', 'rule_of_five_beyond', 'rule_of_four', 'rule_of_three', ...]
1 つの分子に単一のルールを適用する:
import datamol as dm
import medchem as mc
smiles = "CC(=O)OC1=CC=CC=C1C(=O)O" # aspirin
mc.rules.basic_rules.rule_of_five(smiles) # True
mc.rules.basic_rules.rule_of_cns(smiles) # True
mc.rules.basic_rules.rule_of_veber(smiles) # True
RuleFilters で複数のルールを適用する(DataFrame を返します):
import datamol as dm
import medchem as mc
mols = [dm.to_mol(s) for s in smiles_list]
rfilter = mc.rules.RuleFilters(
rule_list=["rule_of_five", "rule_of_oprea", "rule_of_cns", "rule_of_leadlike_soft"]
)
df = rfilter(mols=mols, n_jobs=-1, progress=True, keep_props=False)
# Columns: mol, pass_all, pass_any, rule_of_five, rule_of_oprea, ...
passing = df[df["pass_all"]]
keep_props=True を指定すると、計算された記述子(mw、clogp、tpsa など)を結果に含められます。
2. 構造アラートフィルター
medchem.structural を使用して問題のあるパターンを検出します。どちらのクラスも pass_filter、status、reasons 列を持つ DataFrame を返します。
一般的なアラート(ChEMBL 由来のルールセット):
import medchem as mc
alert_filter = mc.structural.CommonAlertsFilters()
df = alert_filter(mols=mol_list, n_jobs=-1, progress=True)
# df columns: mol, pass_filter, status, reasons
clean = df[df["pass_filter"]]
NIBR フィルター(Novartis のスクリーニングデッキのキュレーション):
nibr_filter = mc.structural.NIBRFilters()
df = nibr_filter(mols=mol_list, n_jobs=-1, progress=True)
# df columns: mol, pass_filter, status, severity, reasons, n_covalent_motif, special_mol
デフォルトでは、severity >= 10 の化合物は除外されます(NIBR の論文を参照)。
3. 名前付きカタログフィルター(PAINS、Brenk など)
RDKit の FilterCatalog インスタンスには medchem.catalogs.NamedCatalogs を使用するか、関数型 API を使用します。
import medchem as mc
# List available named catalogs
mc.catalogs.list_named_catalogs()
# ['tox', 'pains', 'pains_a', 'brenk', 'nibr', 'zinc', ...]
# Functional API — True means molecule passes (no alert match)
passes = mc.functional.alert_filter(mols=mol_list, alerts=["pains"], n_jobs=-1)
# Or via catalog objects
passes = mc.functional.catalog_filter(
mols=mol_list,
catalogs=[mc.catalogs.NamedCatalogs.pains()],
n_jobs=-1,
)
4. 関数型 API
medchem.functional は、ブール値のマスク(True = 合格)を返す、1 回の呼び出しで使えるラッパーを提供します。
import medchem as mc
mc.functional.rules_filter(mols=mol_list, rules=["rule_of_five", "rule_of_cns"], n_jobs=-1)
mc.functional.nibr_filter(mols=mol_list, max_severity=10, n_jobs=-1)
mc.functional.alert_filter(mols=mol_list, alerts=["pains", "brenk"], n_jobs=-1)
mc.functional.complexity_filter(mols=mol_list, complexity_metric="bertz", limit="99", n_jobs=-1)
その他のヘルパー:catalog_filter、chemical_group_filter、lilly_demerit_filter(オプションのバイナリが必要です)、macrocycle_filter、bredt_filter、protecting_groups_filter など。
5. 化学基
medchem.groups を使用して、官能基やキュレーション済みのパターンコレクションを検出します。
import medchem as mc
# Browse available group collections
mc.groups.list_default_chemical_groups()
# ['privileged_scaffolds', 'common_warhead_covalent_inhibitors', 'rings_in_drugs', ...]
group = mc.groups.ChemicalGroup(groups=["privileged_scaffolds"])
group.has_match(mol) # bool
group.get_matches(mol) # dict of group → atom indices
group.filter(mols) # molecules matching the group
# Returns molecules that do NOT match the group
mc.functional.chemical_group_filter(mols=mol_list, chemical_group=group, n_jobs=-1)
カスタムグループは groups_db を介してファイルから読み込めます(smiles/smarts、name、group 列を含む CSV)。
6. 分子の複雑さ
複雑さの指標を、事前計算された ZINC-15 のパーセンタイルしきい値と比較します。
import medchem as mc
# Single molecule
cf = mc.complexity.ComplexityFilter(limit="99", complexity_metric="bertz")
cf(mol) # True if below 99th-percentile threshold
# Batch via functional API
mc.functional.complexity_filter(
mols=mol_list,
complexity_metric="bertz", # also: sas, qed, whitlock, barone, smcm, twc
limit="99",
n_jobs=-1,
)
# Direct metric functions
mc.complexity.WhitlockCT(mol)
mc.complexity.BaroneCT(mol)
7. 骨格の制約
medchem.constraints.Constraints はコア骨格に一致する分子を見つけ、原子ごとの制約関数を適用します。単純な MW/LogP の範囲指定ではありません。特性の範囲を指定するには、RuleFilters、mc.rules.list_descriptors() による記述子、またはクエリ言語を使用してください。
import datamol as dm
import medchem as mc
core = dm.to_mol("c1ccccc1")
constraints = mc.constraints.Constraints(
core=core,
constraint_fns={"query": lambda mol, atom_idx, query: ...},
)
constraints(mol)
8. Medchem クエリ言語
medchem.query.QueryFilter を使用して、複数条件のフィルターを構築します。
import medchem as mc
# Rule + alert combination
qf = mc.query.QueryFilter('MATCHRULE("rule_of_five") AND NOT HASALERT("pains")')
mask = qf(mols=mol_list, n_jobs=-1) # list[bool]
# CNS-like with property bounds
qf = mc.query.QueryFilter('MATCHRULE("rule_of_cns") AND HASPROP("tpsa", <=, 90)')
mask = qf(mols=mol_list, n_jobs=-1)
クエリ構文:
MATCHRULE("rule_of_five")— 名前付きルールを適用するHASALERT("pains")— 名前付きカタログ(pains、brenk、nibr、toxなど)に一致するHASPROP("mw", <, 500)— 記述子を比較する(比較演算子は引用符で囲みません)HASGROUP("privileged_scaffolds")— 化学基に一致するHASSUBSTRUCTURE("c1ccccc1")— 部分構造に一致する- 演算子:
AND、OR、NOT
利用可能な記述子の一覧:mc.rules.list_descriptors()
ワークフローパターン
パターン 1:化合物ライブラリの初期トリアージ
import datamol as dm
import medchem as mc
import pandas as pd
df = pd.read_csv("compounds.csv")
mols = [dm.to_mol(s) for s in df["smiles"]]
# Drug-likeness rules
rules_df = mc.rules.RuleFilters(rule_list=["rule_of_five", "rule_of_veber"])(mols=mols, n_jobs=-1)
# PAINS + common alerts via query
qf = mc.query.QueryFilter('MATCHRULE("rule_of_five") AND NOT HASALERT("pains")')
pass_mask = qf(mols=mols, n_jobs=-1)
df["passes_rules"] = rules_df["pass_all"].values
df["drug_like"] = pass_mask
filtered_df = df[df["drug_like"]]
filtered_df.to_csv("filtered_compounds.csv", index=False)
パターン 2:リード最適化のフィルタリング
import medchem as mc
rules_df = mc.rules.RuleFilters(rule_list=["rule_of_leadlike_soft"])(mols=candidates, n_jobs=-1)
nibr_df = mc.structural.NIBRFilters()(mols=candidates, n_jobs=-1)
complex_mask = mc.functional.complexity_filter(
mols=candidates, complexity_metric="bertz", limit="95", n_jobs=-1
)
passes = (
rules_df["pass_all"]
& nibr_df["pass_filter"]
& complex_mask
)
パターン 3:官能基の検出
import medchem as mc
group = mc.groups.ChemicalGroup(groups=["common_warhead_covalent_inhibitors"])
matches = [group.has_match(mol) for mol in mol_list]
warhead_mols = [mol for mol, m in zip(mol_list, matches) if m]
ベストプラクティス
- コンテキストが重要です — 市販薬はしばしば Ro5 に違反します。プロドラッグや天然物はよくある例外です。
- フィルターを組み合わせます — ルール、アラートカタログ、複雑性のしきい値は、併用すると最も効果的です。
- 並列化を使用します — 分子数が 1000 を超えるライブラリでは、
n_jobs=-1を渡します。 - 戻り値の型を確認します —
RuleFiltersと構造クラスは DataFrame を返し、機能ヘルパーはブール配列を返します。 - Lilly の減点は任意です —
lilly-medchem-rulesを別途インストールします。機能 API のデフォルトの最大減点数は 160 です。 - 判断を記録します — 監査証跡として、
status、reasons、severityの各列を保持します。
リソース
references/api_guide.md
シグネチャ、戻り値の型、使用パターンを含む、モジュールごとの API リファレンスです。
references/rules_catalog.md
利用可能なルール、アラートセット、複雑性の指標、フィルター選択のガイドラインをまとめたカタログです。
scripts/filter_molecules.py
設定可能なルール、アラート、複雑性のしきい値を指定して、CSV/TSV/SDF/SMILES 入力を一括フィルタリングするスクリプトです。
uv run python scripts/filter_molecules.py input.csv \
--rules rule_of_five,rule_of_cns --pains --nibr --output filtered.csv
ドキュメント
- 公式ドキュメント: https://medchem-docs.datamol.io/
- GitHub: https://github.com/datamol-io/medchem
- PyPI: https://pypi.org/project/medchem/ (2.0.5)
エージェントの運用手順
- 環境を確認します。 ツールキットのバージョンと入力形式(SMILES、SDF、PDB、CIF)を確認し、計算前に分子をサニタイズします。
- 入力を明確にします。 データまたはユーザーに確認して、形式、識別子、パラメーターを特定します。結果に影響する値については、推測せずに質問します。
- まず小規模に実行します。 最初に少数の分子または 1 つのターゲットを処理し、出力を確認します。
- 上記の手順と参考資料を使用して、タスク全体を実行します。
- 結果を検証します。 無効な構造、単位の整合性、予測モデルの適用範囲を確認します。
- 報告します。 実行内容(バージョン、コマンド、パラメーター)、確認した項目、未確定事項を明記します。
| このような場合 | 対応方法 |
|---|---|
| 分子のパースまたはサニタイズに失敗する | 理由を示して報告し、スキップします。構造を黙って破棄または変更してはいけません。 |
| これらの手順に記載された関数、フラグ、エンドポイントがインストール済みのバージョンにない | インストール済みバージョンのドキュメント(help()、--help、公式ドキュメント)を確認して適宜対応し、ユーザーに伝えます。API を捏造してはいけません。 |
| 必須の入力、識別子、パラメーターが曖昧である | ユーザーに質問するか、実行前に仮定を明示します。 |
整合性に関するルール
- 結果、パラメーター、識別子、引用、統計を捏造してはいけません。実行または検証できないことは、明確に伝えます。
- 計算による予測は仮説であり、実験結果ではありません。そのように明記します。
- ここに記載されているバージョン固有の詳細は古くなっている可能性があります。インストール済みバージョンの公式ドキュメントで確認します。
- 費用が発生する操作、共有 GPU やクラウドのクォータを消費する操作、個人データや患者データに触れる操作、取り消せない操作を行う前に、必ず確認します。
関連スキル
datamol: datamol Python ライブラリ(import datamol as dm)を通じて RDKit をラップし、分子のケモインフォマティクスを行って、ネイティブの rdkit.Chem.Mol オブジェクトを返します…molfeat: calculators、scikit-learn…を提供する molfeat(0.11.0)を使って、SMILES 文字列または RDKit/datamol 分子を数値特徴量に変換します。rdkit: RDKit(Python)を使用した SMILES、MOL/SDF、InChI の読み書き、記述子(MW、LogP、TPSA)の計算、Morgan/…の生成を案内します