SMARTS記法とRDKitの化学反応で遊んだ話
前回の記事で、ビフェニル部分構造によるフィルタリングを行いましたが、オルト位に置換基の入ったビフェニルについてはうまく実行することができませんでした。@iwatobipen先生、@mojaie先生にSMARTSを使えば良いというご指摘をいただきました。ありがとうございました!
まずは前回失敗した処理を再掲します。
活性化合物のデータセット (共闘用シェアデータ )から取り出した以下の分子に対し、
RDKitの部分構造検索(HasSubstructMatch)を用い、オルト位に置換基の入った構造を取り出そうとしました。
from rdkit import rdBase, Chem from rdkit.Chem import AllChem, Draw ortho_biphenyl = Chem.MolFromSmiles('c1ccc(c(*)c1)c1ccccc1') Draw.MolToImage(ortho_biphenyl)
検索したい部分構造は上のものです。(* はワイルドカード)
test_mol.HasSubstructMatch(ortho_biphenyl)
# False
上記のようにFalseとなってしまうというのが前回の失敗でした。
まずは@iwatobipen先生に教えていただいたSMARTSを用いた方法を試します。
ortho_biphenyl_2 = Chem.MolFromSmarts('c1cccc([!H])c1-c1ccccc1')
Draw.MolToImage(ortho_biphenyl_2)
SMARTSから構築したMOlオブジェクトは、先に作成したものとは異なる形で認識されているようです。(見た感じ・・・)
こちらを使って部分構造の一致を検証します。
test_mol.HasSubstructMatch(ortho_biphenyl_2)
# True
True! うまく構造の一致を認識できました!
次に@mojaie先生にご指摘いただいた事項。
私が失敗したコードでは、Chem.MolFromSmiles()としてしまっているから上手くいかないのではないか、ということでした。「ワイルドカードの*は検索条件なので、本来はSMARTSの表記」のため、Chem.MolFromSmarts()とするのが適切、ということだそうです。
ortho_biphenyl_3 = Chem.MolFromSmarts('c1ccc(c(*)c1)c1ccccc1') test_mol.HasSubstructMatch(ortho_biphenyl_3) # True
True! こちらでもうまく認識できました!
先生方ありがとうございました!
今回失敗した原因は、SMILESとSMARTSの違いを理解せずに適当に使ってしまっていたことでした。
RDKitのドキュメンテーションsubstructure_searchingによると、部分構造検索のクエリ分子はSMILESからでもSMARTSからでも良いが、二つの記法で違いがあるから注意してください、といった指摘がなされていました。
そこで、両者の違いについて少し勉強してみることとしました。
SMILESとSMARTSの違い
SMARTSとは?
そもそもSMARTSって何の略なんだろう?と思っていたのですが、株式会社MOLSISさんのページにわかりやすくまとめられていたので転記させていただきます。 (同社はTwitterで何度かお見かけしたドッキングに使われていたソフト、MOEも製品として取り扱われているそうです)
SMILES(Simplified Molecular Input Line Entry System) : 分子記述言語
- 分子の二次元構造を文字列として記述
- 情報をコンパクトに保存
- 原子座標の羅列と違い、ユーザーにも理解しやすい
SMARTS(SMiles ARbitrary Target Specification): パターン記述言語
- SMILES言語を検索クエリ用に拡張したパターン記述言語
- ワイルドカードや条件指定といった構造検索条件を表記可能
つまり、SMILESを構造検索に用いるため発展させたもの、ということのようです。
Daylight社 の解説ページでSMILES / SMARTSを勉強
SMARTSの詳細については、SMILESの考案者Dr. David Weiningerの設立したDaylight C.I.S. 社のページ を参照してください、と「化学の新しいカタチ」さんのこちらの記事(SMILES記法は化学構造の線形表記法)でオススメされていたので早速眺めて見たいと思います。
部分構造検索とは?
- 分子(グラフ)から特定のパターン(サブグラフ)を見つけ出すプロセス
部分構造検索におけるSMILESの特徴
SMILESを直接拡張したSMARTSではさらに・・・・
- 論理演算子(logical operator)
- より一般的な原子、結合を表現するための特別な原子記号(atomic symbol)、結合記号(bond symbol)が使える
ようになっているそうです。
基本的にはSMILESの拡張のため、SMARTSでもSMILESの表現が使えるそうですが、SMILESは分子記述、SMARTSはパターン記述という違いから同じ文字列でも意味合いが異なってくることに注意が必要、とのこと。Daylight社のページでは以下の具体例が挙げられていました。
例1: 分子とパターン
例2: 原子を括弧 () を使わないで指定した場合
記法のルールを写経
具体的にはどのような記法になるのか、ざっくりテーブルを日本語にします。順番など少し入れ替えています。
SMILES記法同様、角括弧「」は原子の境界を、丸括弧「()」は分岐構造を示します。
原子
記号 | 意味 | デフォルト |
---|---|---|
* | ワイルドカード(どの原子でも良い) | |
a | 芳香属性原子 | |
A | 脂肪族原子 | |
D<数字> | 明示的な結合の数(級数:degree)が<数字> | ちょうど1 |
H<数字> | 結合している水素原子が<数字>個 | ちょうど1 |
h<数字> | 暗に示された水素原子が<数字>個 | 少なくとも1 |
R<数字> | <数字>のSSSR環構造に含まれる(ring membership) | 環の構成原子どれでも |
r<数字> | <数字>のサイズのSSSR環構造に含まれる(ring size) | 環の構成原子どれでも |
v<数字> | 結合次数の総数が<数字> | ちょうど1 |
X<数字> | 結合の総数が<数字> | ちょうど1 |
x<数字> | 環構造の結合の総数が<数字>(ring connectivity) | 少なくとも1 |
-<数字> | マイナス <数字> の電荷 | -1 電荷、--なら-2のチャージ |
+<数字> | プラス <数字> の形式電荷 | +1 電荷、++なら+2のチャージ |
#<数字> | 原子番号<数字> | |
@ | 不斉、反時計回り(@@は時計回り) | |
<数字> | 明示的な原子量 |
結合
記号 | 意味 |
---|---|
- | 単結合(脂肪族) |
= | 2重結合 |
# | 3重結合 |
: | 芳香族性結合 |
~ | ワイルドカード(どのような結合形式でも良い) |
@ | 環結合ならなんでもよい |
/ | 方向性のある結合 アップ |
|方向性性のある結合 ダウン | |
/? | アップあるいは指定されていない |
\? | ダウンあるいは指定されていない |
二重結合の幾何異性体は、例えば「 /C=C/ : trans型2重結合(E)」「/C=C\ : cis型2重結合(Z)」と言ったように表すことができるそうです(SMILES記法の場合)。
論理演算子
記号 | 意味 |
---|---|
! | not |
& | and |
, | or |
; | and |
andを意味するのに「&」と「;」の2つがありますが、「&」が優先されるそうです。
論理演算子を使って原子のパターンを記述するには、角括弧「[]」内部にその原子と条件指定全体を含めることに注意が必要とのことです。
Reaction SMILES / SMARTS
SMILESには他にも拡張として、化学反応を記述できるようにしたReaction SMILESというものもあるそうです。 どのような拡張がなされているのか、「化学の新しいカタチ」さんのこちらの記事RDKitで化学反応:ケモインフォマティクスにおける反応式の扱い方 にわかりやすく記載されているのでご参照ください。
折角なので遊んで見たいと思います。取り上げる反応はC-H結合活性化!(・・・私が学生の頃とても流行ってた)
Murai reaction
まずは村井眞二先生らによる世界初の実用的触媒的C-H結合活性化型反応から*1*2
「原料・試薬 >> 生成物」とのことなのでReaction SMILESは以下のようになります。*3
O=C-C1=CC=CC=C1.CCO[Si](OCC)(OCC)C=C>>CCO[Si](CCC1=C(C=O)C=CC=C1)(OCC)OCC
二つの原料はSMILES同士が「.」でつながれています。
肝心の触媒を忘れました。
RuH2(CO)(PPh3)3を二つの「>」の間に挿入しなければいけません。PubChemによるとこの触媒のSMILESは「[C-]#[O+].C1=CC=C(C=C1)P(C2=CC=CC=C2)C3=CC=CC=C3.C1=CC=C(C=C1)P(C2=CC=CC=C2)C3=CC=CC=C3.C1=CC=C(C=C1)P(C2=CC=CC=C2)C3=CC=CC=C3.[RhH2]」だそうです。長すぎる・・・
O=C-C1=CC=CC=C1.CCO[Si](OCC)(OCC)C=C>[C-]#[O+].C1=CC=C(C=C1)P(C2=CC=CC=C2)C3=CC=CC=C3.C1=CC=C(C=C1)P(C2=CC=CC=C2)C3=CC=CC=C3.C1=CC=C(C=C1)P(C2=CC=CC=C2)C3=CC=CC=C3.[RhH2]>CCO[Si](CCC1=C(C=O)C=CC=C1)(OCC)OCC
訳が分からなくなってしまいました。
RDKitの反応に使うにはReaction SMARTSにするとのことなので触媒を省略した上で以下のように書いてみました。
[O:1]=[C:2]-[c:3][c:4].[C:5]=[C:6]-[Si:7] >> [O:1]=[C:2]-[c:3][c:4]-[C:5]=[C:6]-[Si:7]
では実際に反応を試します。反応させるMolオブジェクト、反応パターン(Reaction SMARTS)を用意した上でRunReactantsを実行します。
reactant_1 = Chem.MolFromSmiles('O=C-C1=CC=CC=C1') reactant_2 = Chem.MolFromSmiles('CCO[Si](OCC)(OCC)C=C') reaction_pattern = '[O:1]=[C:2]-[c:3][c:4].[C:5]=[C:6]-[Si:7] >> [O:1]=[C:2]-[c:3][c:4]-[C:5]=[C:6]-[Si:7]' rxn = AllChem.ReactionFromSmarts(reaction_pattern) x = rxn.RunReactants([reactant_1, reactant_2]) print(x) # ((<rdkit.Chem.rdchem.Mol object at 0x115f19fa8>,), (<rdkit.Chem.rdchem.Mol object at 0x115f19e48>,))
結果はMolオブジェクトを要素とするタプルのタプルとして与えられるようです。外側のタプルはとりうる反応点の組み合わせに相当し、内部のタプルは一つの反応点の組み合わせあたりに複数の生成物ができる場合(加水分解など)に生成物を格納するためにあるようです。
今回は同一の分子が2つ生成されていました。一方を取り出して見ます。
x_0 = x[0][0] Draw.MolToImage(x_0)
アルデヒドの酸素原子が水になっています!どうしてこうなった。
RDKitオンラインドキュメンテーションのChemical-reactionsによると、生成される分子はサニタイゼーションされていないので、サニタイゼーションが必要とのことです。
Chem.SanitizeMol(x_0)
# rdkit.Chem.rdmolops.SanitizeFlags.SANITIZE_NONE と返ってきた
Draw.MolToImage(x_0)
今度は酸素原子がうまく認識されています。よかった。
Fagnouの添加剤
だいたい使い方がわかってきました。ちょっと添加剤にもこだわってみましょう。
Keith Fagnouらによって見出された条件、ピバル酸の添加を行ってみます*4
こちらの論文ではピパル酸を添加することで、触媒的C-H活性化反応が加速するということを見出しています。メカニズムとして、パラジウム触媒に配位し、協奏的メタル化-脱プロトン化反応機構を加速するのではないかということが提唱されています。
上記のReaction SMILESは以下のようになります。
C1=CC=CC=C1.CC1=CC=C(Br)C=C1>CC(C)(C)C(O)=O.[Pd]>CC1=CC=C(C=C1)C1=CC=CC=C1
手抜きして酢酸パラジウム(II)をパラジウム単体にしてしまっていますがご容赦ください。
reactant_1 = Chem.MolFromSmiles('C1=CC=CC=C1') reactant_2 = Chem.MolFromSmiles('CC1=CC=C(Br)C=C1') reaction_pattern = '[c:1].[c:2]-[Br:3] >CC(C)(C)C(O)=O.[Pd]> [c:1]-[c:2]' rxn = AllChem.ReactionFromSmarts(reaction_pattern) x = rxn.RunReactants([reactant_1, reactant_2]) len(x) # 6
・・・添加剤とか記載しなくても結果変わらなかった気がする。まあ、いいや。
ベンゼンを原料としてのC-H活性化反応なので6つの化合物が生成されました。重複を取り除きたいと思います。
手順としては、
- 空の辞書を作成
- サニタイゼーションしてからSMILESに変換(あとで描画したいのでサニタイゼーションもここで行なった)
- 辞書にSMILESをkeyとして、valueにMolオブジェクトを渡す。
これで重複した分子は、keyのSMILESが一致するため複数格納されることはなく、ユニークな分子のみとなります。
uniqps = {} for p in x: Chem.SanitizeMol(p[0]) smi = Chem.MolToSmiles(p[0]) uniqps[smi] = p[0] print(uniqps) # {'Cc1ccc(-c2ccccc2)cc1': <rdkit.Chem.rdchem.Mol object at 0x115f28138>}
分子一つだけが残りました。生成物を確認します。
Draw.MolToImage(uniqps['Cc1ccc(-c2ccccc2)cc1'])
団子・・・
Baranの溶媒
今度は溶媒にもこだわってみましょう。C-H活性化の溶媒と言えば・・・ウーロン茶ですよね!
- ウーロン茶の中でも医薬品の化学合成が可能に | Chem-Station (ケムステ)
- 【反応】Practical and innate carbon–hydrogen functionalization of heterocycles : ChemASAP
さまざまなインパクトのある全合成、反応開発を行い、近年では電気化学の合成反応への応用にも力を入れている様子のPhil S. Baranらにより2012年Natureに報告された反応です。*5
上記のReaction SMILESは以下のようになります。
CN1C=NC2=C1C(=O)N(C)C(=O)N2C.FC(F)(F)S(=O)O[Zn]OS(=O)C(F)(F)F>>CN1C(=NC2=C1C(=O)N(C)C(=O)N2C)C(F)(F)F
まずは溶媒を指定せずに行います。
reaction_pattern = '[n:1][cH1:2][n:3]>>[n:1][c:2](C(F)(F)F)[n:3]' reactant = Chem.MolFromSmiles('CN1C=NC2=C1C(=O)N(C)C(=O)N2C') rxn = AllChem.ReactionFromSmarts(reaction_pattern) x = rxn.RunReactants([reactant,]) uniqps = {} for p in x: Chem.SanitizeMol(p[0]) smi = Chem.MolToSmiles(p[0]) uniqps[smi] = p[0] print(uniqps) # {'Cc1ccc(-c2ccccc2)cc1': <rdkit.Chem.rdchem.Mol object at 0x115f28138>} Draw.MolToImage(uniqps['Cn1c(=O)c2c(nc(C(F)(F)F)n2C)n(C)c1=O'])
うまくカフェインのトリフルオロメチル化ができました。
それではウーロン茶(Oolong tea)を溶媒として反応を仕込みましょう。
reaction_pattern = '[n:1][cH1:2][n:3]>Oolong tea>[n:1][c:2](C(F)(F)F)[n:3]' rxn = AllChem.ReactionFromSmarts(reaction_pattern) x = rxn.RunReactants(reactant) --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-150-2ccb3852d288> in <module>() ----> 1 rxn = AllChem.ReactionFromSmarts(reaction_pattern) 2 x = rxn.RunReactants(reactant) ValueError: ChemicalReactionParserException: Problems constructing agent from SMARTS: Oolong tea
怒られました。そんなSMARTSは無い!!とのこと・・・ふざけてすみません。
MacMillanによるLate-Stage Trifluoromethylation
少し真面目な話に戻して、、、
C-H活性化反応ですが、合成終盤に分子の多様性を増加させるLate-Stage Functionalizationとしての使い方、とくに医薬品低分子への適用が、その有用性を示すデモンストレーションとして行われることが多いです。*6 「創薬化学で多用される部分構造であるトリフルオロメチル基を、医薬品分子そのものに1ステップで直接導入できれば、新しいプロファイルの有用な分子をできるのではないないか?それに複数の生成物を一回で作ることができれば、有望な分子のバリエーションを増やせて良いよね!」というのが、彼らの主張です。
反応形式としては芳香環のC-H結合のトリフルオロメチル基への変換です。
光触媒としてRu(phen)3Cl2が用いられていますが、SMILESに直すと大変そうなので省いてあります。
上記のReaction SMILESは以下の通り。
FC(F)(F)S(Cl)(=O)=O.C1=CC=CC=C1>>FC(F)(F)C1=CC=CC=C1
Reaction SMARTSは [c:1][cH1:2][c:3]>>[c:1][c:2](C(F)(F)F)[c:3] としておけば良さそうです。
論文中ではLipitor(Atrovastatin)を基質として反応を行い、トリフルオロメチル化されたCF3-Lipitorの合成を行なっています。
基質のLipitorを描くのが面倒なのでSMILESをPubChemから取得します。
import pubchempy as pcp import pandas as pd Lipitor_df = pcp.get_properties('canonical_smiles', 'Lipitor', 'name', as_dataframe=True)
Lipitorのフリー体はPubChemの「CID : 60823」のようなのでこちらのSMILESを使います。
Lipitor_smi = Lipitor_df.loc[60823, 'CanonicalSMILES'] Lipitor_mol = Chem.MolFromSmiles(Lipitor_smi) Draw.MolToImage(Lipitor_mol)
Lipitorの構造は上記のようなものです。
Lipitorには3つのベンゼン環があり、反応点としては多数ありますが、MacMillanらは3つの主要なトリフルオロメチル化生成物を、1:1:1の位置異性体混合物(収率74%)で取得しています。
反応させましょう。
CF3_reaction = '[c:1][cH1:2][c:3]>>[c:1][c:2](C(F)(F)F)[c:3]' rxn = AllChem.ReactionFromSmarts(CF3_reaction) x = rxn.RunReactants([Lipitor_mol,]) # ユニークな分子を取り出す CF3_Lipitors = {} for p in x: Chem.SanitizeMol(p[0]) smi = Chem.MolToSmiles(p[0]) CF3_Lipitors[smi] = p[0] print(len(CF3_Lipitors)) # 8個の分子が生成された # 辞書をリストに変換したうえで描画 CF3_Lipitor_list = list(CF3_Lipitors.values()) Draw.MolsToGridImage(CF3_Lipitor_list, molsPerRow=4, subImgSize=(200,200))
このままではどこにCF3が入ったか分からないので、Lipitorの骨格でアラインメントを取ります。
AllChem.Compute2DCoords(Lipitor_mol) for m in CF3_Lipitor_list: AllChem.GenerateDepictionMatching2DStructure(m, Lipitor_mol)
ついでにCF3をハイライトするため、部分構造検索と一致した原子の番号を取得します。
CF3_list = [] CF3_subst = Chem.MolFromSmarts('C(F)(F)F') for mol in CF3_Lipitor_list: matched_atoms = mol.GetSubstructMatches(CF3_subst) #取得した原子番号はタプルのタプルの型となっているのでindex[0]で最初のものを取り出す CF3_list.append(matched_atoms[0])
レジェンドをつけて描画します。
#レジェンドはintではダメだったのでstringに変換 legends = [str(i) for i in range(8)] Draw.MolsToGridImage(CF3_Lipitor_list, molsPerRow=4, subImgSize=(200,200), legends=legends, highlightAtomLists=CF3_list)
以上のようになりました。整列してハイライトするととてもわかりやすくなった気がします。
上の構造のうち、実際に論文中で生成が確認された3つの分子は4番(4'-CF3-Lipitor, 単離収率22%)、5番(2-CF3-Lipitor, 単離収率25%)、7(4-CF3-Lipitor, 単離収率27%)です。
フルオロフェニルで反応が進行していないこと、アニリンでの反応位置をみると、このトリフルオロメチル化の反応の選択性は、電子豊富な環、立体的に空いている位置が優先するとなりそうです。
まとめ
以上、今回はSMILESとSMARTSの違いを勉強するということから始めて、SMILESのもう一つの拡張、Reaction SMILES/SMARTS を用いたRDKitの化学反応を使用してみました。通常、有機合成反応では高い選択性かつクリーンな反応が好まれますが、Late-Stage Functionalizationの観点からはむしろ多様な分子を作り出すため、選択性があまりでないことが重要となっています。このような反応形式を検証するにあたって、生成物としてできうる構造をルールに従って全て書き出すことができる、というのはとても便利だなという印象を受けました。反応開発や副生成物の解析(不純物のプロファイリング)といった用途にも色々と応用できそうです。
*3:反応の構造式、Reaction SMILESともにMarvinSketch 18.24.0を用いて作成
*4:Lafrance, M. and Fagnou, K. J.Am.Chem.Soc.,2006,128,16496
*6:最近では、Late-Stage Diversificationともいうのでしょうか?(合成後期多様化法)))
そこで最後に2011年David W. C. MacMillanらがNature誌に報告した光酸化還元触媒(Photoredox Catalyst)を用いたトリフルオロメチル化反応を眺めて見たいと思います。((Nature volume2012(480)224