mcpField
M
medchem

medchem

github.com/kalarislabsデータ・データベース7940 回インストール6 日前に更新
リポジトリ

medchem について

medchem は、創薬で化合物ライブラリをフィルタリングし、優先順位を付ける Python ライブラリとスキルです。メディシナルケミストリーのルール、構造アラート、複雑度指標、クエリ言語を組み合わせた選別に対応します。

主な機能

  1. 01ドラッグライクネスルールの適用
  2. 02構造アラートとカタログによる選別
  3. 03分子複雑度の評価
  4. 04化学基の検出
  5. 05クエリ言語による条件の組み合わせ

活用シーン

  1. 01化合物ライブラリの初期選別
  2. 02ヒットからリードへの候補選定
  3. 03リード最適化候補の選別
  4. 04指定した官能基を持つ化合物の検索

インストール

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

$npx skills add https://github.com/kalarislabs/research-agent-skills --skill medchem

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

同梱ファイル

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

references/
api_guide.md
rules_catalog.md
scripts/
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]

ベストプラクティス

  1. コンテキストが重要です — 市販薬はしばしば Ro5 に違反します。プロドラッグや天然物はよくある例外です。
  2. フィルターを組み合わせます — ルール、アラートカタログ、複雑性のしきい値は、併用すると最も効果的です。
  3. 並列化を使用します — 分子数が 1000 を超えるライブラリでは、n_jobs=-1 を渡します。
  4. 戻り値の型を確認します — RuleFilters と構造クラスは DataFrame を返し、機能ヘルパーはブール配列を返します。
  5. Lilly の減点は任意です — lilly-medchem-rules を別途インストールします。機能 API のデフォルトの最大減点数は 160 です。
  6. 判断を記録します — 監査証跡として、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

ドキュメント

エージェントの運用手順

  1. 環境を確認します。 ツールキットのバージョンと入力形式(SMILES、SDF、PDB、CIF)を確認し、計算前に分子をサニタイズします。
  2. 入力を明確にします。 データまたはユーザーに確認して、形式、識別子、パラメーターを特定します。結果に影響する値については、推測せずに質問します。
  3. まず小規模に実行します。 最初に少数の分子または 1 つのターゲットを処理し、出力を確認します。
  4. 上記の手順と参考資料を使用して、タスク全体を実行します。
  5. 結果を検証します。 無効な構造、単位の整合性、予測モデルの適用範囲を確認します。
  6. 報告します。 実行内容(バージョン、コマンド、パラメーター)、確認した項目、未確定事項を明記します。
このような場合対応方法
分子のパースまたはサニタイズに失敗する理由を示して報告し、スキップします。構造を黙って破棄または変更してはいけません。
これらの手順に記載された関数、フラグ、エンドポイントがインストール済みのバージョンにないインストール済みバージョンのドキュメント(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/…の生成を案内します

コメント