magattacaのブログ

日付以外誤報

Chemical Reactions part2 〜RDKit 直訳 Day18〜

(12/30追記)試訳をまとめたテストサイトを作成しました。よろしければご参照ください。

こちらはRDKit直訳 Advent Calendar 2018 - Adventar 18日目の記事です。基本的な進め方は1日目の記事をご覧ください。

本日の訳出に困った用語
dummy atom: ダミーアトム
generator object: ジェネレーターオブジェクト
valence: 原子価 generic function: ジェネリック関数
attachment point: 接着点
unsigned integer: 符号なし整数

以下、訳

BRICSの実装(BRICS Implemetation)

[Link] https://www.rdkit.org/docs/GettingStartedInPython.html#brics-implementation

RDKitはBRICSアルゴリズムの実装も提供しています[脚注9]。BRICSは合成的に利用可能な結合に沿って分子をフラグメント化するもう一つの方法です:

[脚注9] Degen, J.; Wegscheid-Gerlach, C.; Zaliani, A; Rarey, M. “On the Art of Compiling and Using ‘Drug-Like’ Chemical Fragment Spaces.” ChemMedChem 3:1503–7 (2008).

>>> from rdkit.Chem import BRICS
>>> cdk2mols = Chem.SDMolSupplier('data/cdk2.sdf')
>>> m1 = cdk2mols[0]
>>> sorted(BRICS.BRICSDecompose(m1))
['[14*]c1nc(N)nc2[nH]cnc12', '[3*]O[3*]', '[4*]CC(=O)C(C)C']
>>> m2 = cdk2mols[20]
>>> sorted(BRICS.BRICSDecompose(m2))
['[1*]C(=O)NN(C)C', '[14*]c1[nH]nc2c1C(=O)c1c([16*])cccc1-2', '[16*]c1ccc([16*])cc1', '[3*]OC', '[5*]N[5*]']

RDKitのBRICSの実装では、分子から作られたそれぞれのユニークなフラグメントを返します。また、ダミーアトムに、どのタイプの反応が適用されたかを示すタグがつけられたうえで返されます。

分子の集合に対して全てのフラグメントのリストを生成することがとても簡単にできます:

>>> allfrags=set()
>>> for m in cdk2mols:
...    pieces = BRICS.BRICSDecompose(m)
...    allfrags.update(pieces)
>>> len(allfrags)
90
>>> sorted(allfrags)[:5]
['NS(=O)(=O)c1ccc(N/N=C2\\C(=O)Nc3ccc(Br)cc32)cc1', '[1*]C(=O)C(C)C', '[1*]C(=O)NN(C)C', '[1*]C(=O)NN1CC[NH+](C)CC1', '[1*]C(C)=O']

BRICSモジュールは、フラグメントの集合にBRICSのルールを適用して新しい分子を生成するオプションも提供しています:

>>> import random
>>> random.seed(127)
>>> fragms = [Chem.MolFromSmiles(x) for x in sorted(allfrags)]
>>> ms = BRICS.BRICSBuild(fragms)

結果はジェネレーターオブジェクトです:

>>> ms
<generator object BRICSBuild at 0x...>

リクエストに応じて分子を返します:

>>> prods = [next(ms) for x in range(10)]
>>> prods[0]
<rdkit.Chem.rdchem.Mol object at 0x...>

返された分子はサニタイズされていないので、処理を続ける前に少なくとも原子価を更新した方が良いでしょう:

>>> for prod in prods:
...     prod.UpdatePropertyCache(strict=False)
...
>>> Chem.MolToSmiles(prods[0],True)
'COCCO'
>>> Chem.MolToSmiles(prods[1],True)
'O=C1Nc2ccc3ncsc3c2/C1=C/NCCO'
>>> Chem.MolToSmiles(prods[2],True)
'O=C1Nc2ccccc2/C1=C/NCCO'

他のフラグメント化手法(Other fragmentation approaches)

[Link] https://www.rdkit.org/docs/GettingStartedInPython.html#other-fragmentation-approaches

上述の方法に加えて、RDKitはユーザーが指定した結合に沿って分子をフラグメント化する非常に柔軟なジェネリック関数を提供しています。

ここでは、簡単なデモンストレーションとして、環構造の中に含まれる原子と含まれない原子との間の結合を全て切断するという場合を試してみましょう。まずはペアとなる原子の組み合わせをすべて見つけることから始めます。

>>> m = Chem.MolFromSmiles('CC1CC(O)C1CCC1CC1')
>>> bis = m.GetSubstructMatches(Chem.MolFromSmarts('[!R][R]'))
>>> bis
((0, 1), (4, 3), (6, 5), (7, 8))

次に、原子のペアに一致する結合のインデックスを取得します:

>>> bs = [m.GetBondBetweenAtoms(x,y).GetIdx() for x,y in bis]
>>> bs
[0, 3, 5, 7]

そして、これらの結合のインデックスをフラグメント化関数のインプットとして使います:

>>> nm = Chem.FragmentOnBonds(m,bs)

アウトプットは、結合が切断された場所を示すダミーアトムを有する分子です:

>>> Chem.MolToSmiles(nm,True)
'*C1CC([4*])C1[6*].[1*]C.[3*]O.[5*]CC[8*].[7*]C1CC1'

デフォルトでは、接着点は取り除かれた原子のインデックスとともに、(同位体[isotope]を使って)ラベルされています。独自の原子のラベルのセットを、符号なし整数のペアという形で設定することもできます。それぞれのペアの最初の値は、結合の出発点となる原子を置き換えるダミーのためのラベルとして使われ、ペアの2番目の値は、結合の終点となる原子を置き換えるダミーのためのラベルとして使われます。以下の例を見てみましょう。上述の解析を再度行い、接着点に関して、環構造に含まれない原子の場所は10とラベルをつけ、環構造の中の原子には1とラベルをつけています:

>>> bis = m.GetSubstructMatches(Chem.MolFromSmarts('[!R][R]'))
>>> bs = []
>>> labels=[]
>>> for bi in bis:
...    b = m.GetBondBetweenAtoms(bi[0],bi[1])
...    if b.GetBeginAtomIdx()==bi[0]:
...        labels.append((10,1))
...    else:
...        labels.append((1,10))
...    bs.append(b.GetIdx())
>>> nm = Chem.FragmentOnBonds(m,bs,dummyLabels=labels)
>>> Chem.MolToSmiles(nm,True)
'[1*]C.[1*]CC[1*].[1*]O.[10*]C1CC([10*])C1[10*].[10*]C1CC1'

12/18/2018

このブログ記事のライセンス

以上はRDKit Documentationの試訳です。
ライセンスはCC BY-SA 4.0で、Greg Landrum氏の功績の元に作成しています。
Creative Commons — Attribution-ShareAlike 4.0 International — CC BY-SA 4.0