RDkit を用いた分子構造の操作（骨格変換）

# 前準備

### モジュールのインストール

```
conda install -c conda-forge rdkit
```

### データの準備
1290分子の水溶解度（LogS）データ（sdfファイル形式）
（[金子研究室HPのデータセット](https://datachemeng.com/pythonassignment/)を利用）

# 分子構造の操作（コード）

### モジュールのインポート

```python
import pandas as pd
import numpy as np
from rdkit import Chem
from rdkit.Chem import AllChem, Draw
```

## (基礎知識）MolオブジェクトとSMILESの相互変換
- smilesからのMolオブジェクトの生成： MolFromSmile() 
- Molオブジェクトからのsmilesの生成： MolToSmiles()

```python
#SMILESからMolオブジェクトへの変換
mol = Chem.MolFromSmiles('c1ccccc1')
print(mol)
#<rdkit.Chem.rdchem.Mol object at 0x124e5b800>

#MolオブジェクトからSMILESへの変換
smiles = Chem.MolToSmiles(mol)
print(smiles)
#c1ccccc1
```
  

一度、Molオブジェクトにしてから、再度SMILESに変換しなおすとcanonical SMILES（化合物に固有のSMILES表記）となる。
データベース中の化合物検索をSMILESの文字列をキーにして行いた場合など、SMILESの表記方法を統一したい場合におすすめ。

```python
print(Chem.MolToSmiles(Chem.MolFromSmiles('C1=CC=CN=C1')))
# 'c1ccncc1'
print(Chem.MolToSmiles(Chem.MolFromSmiles('c1cccnc1')))
# 'c1ccncc1'
print(Chem.MolToSmiles(Chem.MolFromSmiles('n1ccccc1')))
# 'c1ccncc1'
```

## データの準備

```python
#金子研究室から取得したsdfファイル(logSdataset1290_2d.sdf)を使用
suppl = Chem.SDMolSupplier('logSdataset1290_2d.sdf')
mols_list = np.array([mol for mol in suppl if mol is not None])
```

## 部分構造検索
データセットの中から、ベンゼン環をもつ分子（6分子）を抜き出す。

```python
#ベンゼン環をもつ分子を抜き出す
query = Chem.MolFromSmiles('c1ccccc1')

#クエリにヒットした分子をリストに入れる。
aryl_mols = []
for mol in mols_list:
    if mol.HasSubstructMatch(query):
        aryl_mols.append(mol)

#表示用に6分子だけ選択する。
aryl_mols = aryl_mols[4:10]
smiles_list = [Chem.MolToSmiles(mol) for mol in aryl_mols]

img = Draw.MolsToGridImage(aryl_mols, molsPerRow=3, legends=smiles_list)
img.save('aryl_mols.png')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348376/c309a186-5403-b8e3-4d5b-28f5e01136f4.png)


ちなみに、デフォルトでは部分構造検索で立体化学に関する情報は使われないらしく、  
"useChirality=True" にすることで変更可能。  

非キラルなクエリがキラルなクエリにマッチするが、キラルクエリが非キラルクエリにマッチすることはないらしい。

## 部分構造の削除

```python
#削除する部分構造を定義
del_part = Chem.MolFromSmiles('c1ccccc1')
no_aryl_mols =  [AllChem.DeleteSubstructs(mol,del_part) for mol in aryl_mols]

#一度SMILESに変換してMolオブジェクトするときれいに描画できるっぽい
smiles_list = [Chem.MolToSmiles(mol) for mol in no_aryl_mols]
no_aryl_mols = [Chem.MolFromSmiles(smiles) for smiles in smiles_list]

img = Chem.Draw.MolsToGridImage(no_aryl_mols, molsPerRow=3,legends=smiles_list)
img.save('no_aryl_mols.png')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348376/188cef6b-d6a1-e154-1c14-3a1af08a860e.png)

## 部分構造の変換

```python
#ベンゼン環をシクロペンチル環に変換
replace_from = Chem.MolFromSmiles('c1ccccc1')
replace_to = Chem.MolFromSmarts('C1CCCC1')
cyclopentyl_mols =  [AllChem.ReplaceSubstructs(mol,replace_from,replace_to)[0] for mol in aryl_mols]

#一度SMILESに変換してMolオブジェクトする
smiles_list = [Chem.MolToSmiles(mol) for mol in cyclopentyl_mols]
cyclopentyl_mols = [Chem.MolFromSmiles(smiles) for smiles in smiles_list]

img = Chem.Draw.MolsToGridImage(cyclopentyl_mols, molsPerRow=3,legends=smiles_list)
img.save('cyclopentyl_mols.png')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348376/28bb0b0c-cab8-c2a5-1cd3-cd9bc5646476.png)

## 側鎖の削除処理

```python
core = Chem.MolFromSmiles('c1ccccc1')
core_mols =  [Chem.ReplaceSidechains(mol,core) for mol in aryl_mols]

#一度SMILESに変換してMolオブジェクトする
smiles_list = [Chem.MolToSmiles(mol) for mol in core_mols]
core_mols = [Chem.MolFromSmiles(smiles) for smiles in smiles_list]

#削除された部分にはダミーアトムが割り当てられている。
print(smiles_list[0])
# >>> [1*]c1ccccc1[2*]

img = Chem.Draw.MolsToGridImage(core_mols, molsPerRow=3, legends=smiles_list)
img.save('core_mols.png')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348376/115022f6-74e0-b720-ced5-c4daad92c441.png)

## 主骨格の削除処理

```python
core = Chem.MolFromSmiles('c1ccccc1')
side_chanes =  [Chem.ReplaceCore(mol,core) for mol in aryl_mols]

#一度SMILESに変換してMolオブジェクトする
smiles_list = [Chem.MolToSmiles(mol) for mol in side_chanes]
side_chanes = [Chem.MolFromSmiles(smiles) for smiles in smiles_list]

img = Chem.Draw.MolsToGridImage(side_chanes, molsPerRow=3, legends=smiles_list)
img.save('side_chanes.png')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348376/89f309b6-fb92-1790-4ebb-4d08f8986017.png)

# 参考
- [RDki非公式日本語版サイト](https://rdkit.org/docs_jp/index.html)
- [RDKitの分子Molオブジェクトを扱う(化学の新しいカタチ)](https://future-chem.com/rdkit-mol/)