SBDDに限らず、創薬にあたってポジコンやツール化合物があるかどうかは評価系構築の確度に関わる部分です。
ここをしっかりしてもらうことが、我々ケミストの成功の第一歩になります。
若い子「おじさん、すみません。共結晶が報告されてるリガンドを調べてもらうことってできますか?」 おじさん「いいよ。」
数分後...
おじさん「結構な数があるね。」
若い子「これって買うか作るか出来ますか?」
おじさん「うーん調べるならちょっと時間ください」
よく知られてる標的だと結構な数の共結晶が報告されてますよね。
調べるだけで半日(~1日)かかっちゃいそうです。
そんなわけでpythonのスクリプトを書きました (>3日かかった)。
Contents
conda create -n bi -c conda-forge -y python=3.10 pymol-open-source=2.5 BioPython=1.81 pandas=2.0.3 requests=2.31 pypdb=2.3 biopandas=0.4.1 rdkit=2022.09.1 以降のスクリプトは 色んな方法が報告されています。例えば, 下記のスクリプト実行してキーワード検索の結果をリストにすることができます。 jupyterで実行すると 今回は@くろたんくさんの記事を参考にさせてもらいました。 添加剤やイオンなんかも結果に含まれてしまうので、必要に応じてフィルタリングが必要です。 あーやっとスッキリしました。環境構築
miniconda
がインストールされているものとします。ちなみにMacでもWinでも動作確認済みです。
今回のスクリプトは下記の仮想環境で動作確認済みです。conda activate bi
で仮想環境をactivateする必要があります。
すでにinstallされてたら問題ないです。今回は使わないものも入っています。標的のPDBリストを作る
from pypdb import *
q = input('keywords? ')
pdb_ids = Query(q).search()
print('the number of PDB IDs are ' + str(len(pdb_ids)))
input
の入力を求められます。 今回は有名どころでCRBN
と入力したところ、2023.9.4
現在で81個のPDBがヒットしました。
他にも方法はあるので気が向いた時にでも公開します。PDBに含まれるリガンドをリストアップして、PubChemのSupplierリンクをつける
私の拙いcodingでは例外処理がめんどうで目的を達成できませんでした。感謝です。
早速ズバリ結論を書くと、上述のPDBリストを作った状態で下記を実行します。import requests
import pubchempy as pcp
import pandas as pd
# Ligandの有無を判定してdfを作成する関数
def PDB2L(entry_id):
ligand_list = []
query = '''
{
entry(entry_id:"''' + entry_id + '''") {
rcsb_id
struct {
title
}
nonpolymer_entities {
rcsb_nonpolymer_entity_container_identifiers {
entry_id
}
nonpolymer_comp {
chem_comp {
id
type
}
pdbx_chem_comp_descriptor {
descriptor
type
program
}
}
}
}
}
'''
url = "https://data.rcsb.org/graphql?query=" + query
response = requests.get(url)
json_data = response.json()
# dfの作成
# Ligandがある場合だけrun
if json_data['data']['entry']['nonpolymer_entities'] != None:
# LigandがUNLやUNKではない時はrun
if json_data['data']['entry']['nonpolymer_entities'][0]['nonpolymer_comp']['pdbx_chem_comp_descriptor'] != None:
# 複数のリガンドをdfに代入
for i in json_data.get('data').get('entry').get('nonpolymer_entities'):
entry_id = i.get('rcsb_nonpolymer_entity_container_identifiers')
nonpolymer_comp = i.get('nonpolymer_comp')
ligand_id = nonpolymer_comp.get('chem_comp').get('id')
for data in nonpolymer_comp.get('pdbx_chem_comp_descriptor'):
if (data.get('type') == "InChI") and (data.get('program') == "InChI"):
inchi = [data.get('descriptor')]
type = [data.get('type')]
program = [data.get('program')]
d = {'Ligand_ID':ligand_id, 'InChI':inchi}
ligand_list.append(d)
df = pd.DataFrame(ligand_list)
df['Title'] = json_data['data']['entry']['struct']['title']
return(df)
# ここからfor文
# pdb_ids = ['5UT2', '4FVR'] # for test
cols = ['Ligand_ID', 'SMILES', 'InChI', 'CID', 'MW', 'PDB_ID', 'Title', 'Supplier', 'RCSB_URL', 'Ligand_URL']
Sup_List = pd.DataFrame(columns = cols)
for pdb_id in pdb_ids:
# Ligandがない場合の例外処理
if judge(pdb_id) != None:
if UNL_UNK(pdb_id) != None:
# DataFrameの作成
df = pd.DataFrame(entry_to_ligand(pdb_id))
df['PDB_ID'] = pdb_id
df['CID'] = df['InChI'].map(lambda x : pcp.get_properties('MolecularWeight', x, 'inchi')[0]['CID']).astype(str)
df['MW'] = df['InChI'].map(lambda x : pcp.get_properties('MolecularWeight', x, 'inchi')[0]['MolecularWeight']).astype(float)
df['SMILES'] = df['InChI'].map(lambda x : pcp.get_properties('IsomericSMILES', x, 'inchi')[0]['IsomericSMILES'])
df['Title'] = df['PDB_ID'].map(lambda x : title(x))
# リンクの作成
df['Supplier'] = df['CID'].map(lambda x : 'https://pubchem.ncbi.nlm.nih.gov/compound/' + x + '#section=Chemical-Vendors&fullscreen=true')
df['RCSB_URL'] = df['PDB_ID'].map(lambda x : 'https://www.rcsb.org/structure/' + x)
df['Ligand_URL'] = df['Ligand_ID'].map(lambda x : 'https://www.rcsb.org/ligand/' + x)
# df['Title'] = json_data['data']['entry']['struct']['title']
# df結合
Sup_List = pd.concat([Sup_List, df])
else:
df = pd.DataFrame(columns=cols)
empty = []
empty.append(pdb_id)
df['PDB_ID'] = empty
df['RCSB_URL'].iloc[0] = 'https://www.rcsb.org/structure/' + pdb_id
Sup_List = pd.concat([Sup_List, df])
else:
df = pd.DataFrame(columns=cols)
empty = []
empty.append(pdb_id)
df['PDB_ID'] = empty
df['RCSB_URL'].iloc[0] = 'https://www.rcsb.org/structure/' + pdb_id
Sup_List = pd.concat([Sup_List, df])
Sup_List = Sup_List.reset_index(drop=True)
重複も除いてあげると親切ですね。# MW>150
Sup_List_150 = Sup_List[Sup_List['MW']>150].reset_index(drop=True)
#remove duplicates
Sup_List_Dup = Sup_List[Sup_List['MW']>150].drop_duplicates('Ligand_ID').reset_index(drop=True)