RDKit入門②：1分子の読み込みと部分構造検索

##はじめに
この記事は以下の記事の続きとなります。
[RDKit入門①：まずは環境構築][1]
[1]:https://qiita.com/Ru-PNP/items/ed5a8530611ef0d712b7
今回はRDKitを用いてSMILES構造式からmolオブジェクトを生成し、部分構造検索を行います。
###環境
- windows 10
- python 3.8.5
- RDKit 2020.09.4

---
##molオブジェクトの作成
まずはmolオブジェクトの作成を行います。
molオブジェクトの作成には<b>Chem.MolFromSmiles()</b>もしくは<b>Chem.MolFromSmarts()</b>を用います。
前者はSMILES記法を、後者はSMARTS記法を用いたmolオブジェクト作成を行います。
今回は前者を用い、アトルバスタチンのSMILES構造式からのmolオブジェクト作成を試しましょう。


```python
from rdkit import Chem
#パッケージの読み込み

Atorvastatin = Chem.MolFromSmiles("O=C(O)C[C@H](O)C[C@H](O)CCn2c(c(c(c2c1ccc(F)cc1)c3ccccc3)C(=O)Nc4ccccc4)C(C)C")
#アトルバスタチンのSMILES構造式からmolオブジェクトを生成し、Atorvastatinと定義した。
```

生成したmolオブジェクトを呼び出してみると以下の画像が出力されます。

```python
Atorvastatin
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1144410/402da04f-6fd7-3095-17f9-eea9f90c5fb1.png)
念の為、今回生成したAtorvastatinの型についても調べておきましょう。

```python
print(type(Atorvastatin))
#<class 'rdkit.Chem.rdchem.Mol'>
```



なお、RDKitが与えられたSMILES構造式をうまく解釈できない場合（価数や結合数が変な場合等）、
molオブジェクトが生成されずにNoneオブジェクトが返されることがあります。
試しに結合数が5本の炭素を含むSMILES構造式を与えてみましょう。

```python
test = Chem.MolFromSmiles("CC(C)(C)(C)C")
print(type(test))
#<class 'NoneType'>
```

---
##部分構造検索
部分構造検索の方法として以下の3つを紹介します。
> Mol.HasSubstructMatch(<i>query</i>)
> Mol.GetSubstructMatch(<i>query</i>)
> Mol.GetSubstructMatches(<i>query</i>)

Molの部分と<i>query</i>の部分にはいずれもmolオブジェクトを入れます。
###HasSubstructMatchについて
最初に紹介する<b>HasSubstructMatch</b>は、Molの中に<i>query</i>で指定した部分構造が含まれるか否かを調べるメソッドです。
含まれる場合はTrue, 含まれない場合はFalseが返ります。
先に生成したAtorvastatinの中にアミド(含まれる)とピリジン環(含まれない)があるかどうか調べてみましょう。

```python
amide = Chem.MolFromSmiles("C(=O)N")
Atorvastatin.HasSubstructMatch(amide)
#True

Atorvastatin.HasSubstructMatch(Chem.MolFromSmiles("n1ccccc1"))
#False
```

###GetSubstructMatchについて
次に紹介する<b>GetSubstructMatch</b>は、検索した部分構造のアトムインデックスを返す関数です。
molオブジェクトにはどの原子が何番という番号が振られており、その番号を取得することができます。
試しにAtorvastatinのカルボン酸部分のアトムインデックスのタプルを取得してみましょう。

```python
Atorvastatin.GetSubstructMatch(Chem.MolFromSmiles("C(=O)O"))
#(1, 0, 2)
```

部分構造として存在しない構造を検索すると空のタプルが得られます。

```python
Atorvastatin.GetSubstructMatch(Chem.MolFromSmiles("n1ccccc1"))
#()
```

ただし、GetSubstructMatch()関数は検索したい部分構造が複数含まれる場合でも1箇所分のアトムインデックスしか返してくれません。
試しにベンゼン環(Atorvastatin中に3つ含まれる)で検索してみましょう。

```python
Atorvastatin.GetSubstructMatch(Chem.MolFromSmiles("c1ccccc1"))
#(16, 17, 18, 19, 21, 22)
```

###GetSubstructMatchesについて
最後に紹介する<b>GetSubstructMatches</b>は、検索した部分構造に該当する全ての部分のアトムインデックスを返すメソッドです。
出力はタプルのタプルとして与えられます。
この関数を用いて再度ベンゼン環構造の検索を行いましょう。

```python
Atorvastatin.GetSubstructMatches(Chem.MolFromSmiles("c1ccccc1"))
#((16, 17, 18, 19, 21, 22), (23, 24, 25, 26, 27, 28), (32, 33, 34, 35, 36, 37))
```

len()関数と組み合わせれば該当する部分構造がいくつ含まれるかも分かります。

```python
len(Atorvastatin.GetSubstructMatches(Chem.MolFromSmiles("c1ccccc1")))
#3
```

---
##おわりに
今回はRDKitを用いて以下の内容を実施いたしました。

- SMILES構造式からのmolオブジェクトの生成
- molオブジェクトに対する部分構造検索の実施(3種類)

---
###参考
今回の記事を書くにあたっては[化学の新しいカタチ](https://future-chem.com/)さんの以下の記事を参考にいたしました。

- [RDKitでケモインフォマティクスに入門](https://future-chem.com/rdkit-intro/)
- [RDKitを用いた部分構造検索とMCSアルゴリズム](https://future-chem.com/substruct-search-mcs/)

また、関連する内容として以下の記事を紹介いたします。

- https://qiita.com/Mochimasa/items/4e34ceb8eb9519513a94
- https://qiita.com/DecaltingMs/items/e9f7d2d17b22b7419cef
- https://qiita.com/oki_kosuke/items/fbf4d34357b3b0edbab0