あるケミストの独り言(winchemwinの日記)

ケミスト(化学者)の視点で、面白そうな情報(シミュレーション関係など)を発信

化学構造データ変換-Tips その2(sdfファイルの読み込み)

化学構造データ変換-Tips その2になります。
今回はsdfファイルの読み込みです。sdfファイルは、化学構造や物性データなどを記録するためのファイル形式のひとつです。
多くの化合物の化学構造とその物性データをひとつのファイルとして保存できるため、纏まったデータを扱う際にはよく利用される形式です。
一方で、化学構造を確認しながらデータ変換などを行う際にはひとつひとつの化合物を個別の分子として読み込む必要が出てきます。
PythonライブラリーのRdkitではsdfファイルを読み込み処理するモジュール(Chem.SDMolSupplier)が用意されています。
Chem.SDMolSupplierを使うことでsdfファイルを読み込んで、分子オブジェクトのリストを作成することができます。

この記事は以下の記事等を参考に書かせていただいています。

future-chem.com

qiita.com

magattaca.hatenablog.com

RDKitにはsdfファイルを読み込む方法としてSDMolSupplierとFowardSDMolSupplierの大きく二つの方法がありますが、今回はFowardSDMolSupplierを用いて紹介しています。
ForwardSDMolSupplierモジュールの特徴は、SDファイルを一度に全て読み込むのではなく、必要に応じて一つずつ読み込むということのようです。これにより、メモリの使用量を節約できるだけでなく、大きなファイルでも高速に処理できるという利点があります。

FowardSDMolSupplierの使用例として、sdfファイルを読み込み、ひとつひとつmolオブジェクトに変換するコードを紹介したいと思います。
(関連コードは記事の最後部分)
sdfファイルですが、今回はPubChemでNaphthalene-1,3-diolで検索した結果をsdfファイルとして保存したものを用いました。
FowardSDMolSupplierでファイル名を指定してsubとして読み込んでいます。この際水素原子の情報は省かれたくないので以下のオプション説明でも出てくるようにremoveHs=Falseとしています(デフォルトなので特に記載は不要かと思いますが)。
続いて読み込んだsubをそれぞれ化合物のmol形式のリスト(mols)に変換しています。この際空データをリスト化しないようにif 文以下のコードが入っています。
さらにRdkit内でそれぞれの化合物のmolオブジェクトとして扱うためにfor 文内でMolToMolFileで処理をしています。
以上のコードでsdfファイルで提供されたファイルからRdkit で扱うmolオブジェクトへの変換を行うことができます。

因みに、FowardSDMolSupplierはSDファイルを読み込む際に、いくつかのオプションを指定することができます。これらのオプションは、分子オブジェクトの生成やプロパティの取得に影響します。

  • sanitize: このオプションは、分子オブジェクトを生成する際に、化学的に正しい構造に修正するかどうかを指定します。デフォルトではTrueです。sanitizeをTrueにすると、分子の原子価や芳香性などが自動的に計算されます。sanitizeをFalseにすると、分子の構造はSDファイルに記載されたままになりますが、一部の機能が使えなくなる可能性があります。
  • removeHs: このオプションは、分子オブジェクトを生成する際に、水素原子を除去するかどうかを指定します。デフォルトではFalseです。removeHsをTrueにすると、分子のサイズや計算量が減りますが、水素情報が失われる可能性があります。
  • strictParsing: このオプションは、SDファイルの形式が正しいかどうかを厳密にチェックするかどうかを指定します。デフォルトではTrueです。strictParsingをTrueにすると、形式が不正なSDファイルはエラーとして扱われます。

 以上、今回はsdfファイルを読み込み、molオブジェクトに変換するコードについて紹介させていただきました。

from rdkit import Chem
from rdkit.Chem import AllChem, Draw

sup=Chem.ForwardSDMolSupplier('PubChem_compound_text_Naphthalene-1,3-diol_records.sdf',removeHs=False)

mols=[mol for mol in sup if mol is not None]

for i, mol in enumerate(mols):
    Chem.MolToMolFile(mol,f'molecule{i}.mol')
    print (i, mol) 
    
print ('File conversion was finished')