ラベル Opsin の投稿を表示しています。 すべての投稿を表示
ラベル Opsin の投稿を表示しています。 すべての投稿を表示

2010年2月13日土曜日

IUPAC名からSmilesを起こす

ということで苦労しまくったIUPAC名からSmilesを起こすプロジェクトですが、最終的には以下のような流れになりました。

1)Opsin0.5.3でIUPAC名をCMLに変換
2)CDKでCMLをIMoleculeに変換
3)CDKでIMoleculeからMolファイル形式に変換
4)OpenBabelでMolファイルからSmilesに変換

フォームアプリケーション的はコードを書きます。Smilesにするだけなら2次元構造は必要なないのですが、忘記録的に入れときます。この流れがdelegateでも動いたらOkですな。




using System;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;


using org.openscience.cdk.io;
using org.openscience.cdk;
using org.openscience.cdk.interfaces;
using org.openscience.cdk.layout;
using java.io;


using uk.ac.cam.ch.wwmm.opsin;
using OpenBabel;



namespace OpsinTest
{
    public partial class Form1 : Form
    {
        NameToStructure nts = null;



        public Form1()
        {
            InitializeComponent();
            nts = new NameToStructure();
        }



        private void button3_Click(object sender, EventArgs e)
        {
            string IUPAC = textBox1.Text;


            try
            {
                textBox2.Text = "";
                Application.DoEvents();


                // Create CML from IUPAC name (Opsin)
                string cml = nts.parseToCML(IUPAC).toXML();
                
                // Convert CML to IMolecule (CDK)
                StringBufferInputStream str_stream  = new StringBufferInputStream(cml);
                
                CMLReader cmlr = new CMLReader();
                cmlr.setReader(str_stream);


                ChemFile chemFile = new ChemFile();
                ChemFile chem = (ChemFile)cmlr.read(chemFile);


                IMolecule mol = chem.getChemSequence(0).getChemModel(0).getMoleculeSet().getMolecule(0);


                // Convert from IMolecule to SD (CDK)
                java.io.StringWriter sww = new java.io.StringWriter();
                MDLWriter mw = new MDLWriter(sww);
                StructureDiagramGenerator sdg = new StructureDiagramGenerator();


                sdg.setMolecule(mol);
                sdg.generateCoordinates();
                mol = sdg.getMolecule();
                mw.write(mol);
                string sd = sww.toString();


                // Convert from SD to smiles (OpenBabel)
                OBMol obMol = new OBMol();
                OBConversion obConv = new OBConversion();
                if (!obConv.SetInAndOutFormats("mol", "can")) { return; }
                if (!obConv.ReadString(obMol, sd)) { return; }


                textBox2.Text = obConv.WriteString(obMol);


                obMol.Dispose();
                obConv.Dispose();
                obMol = null;
                obConv = null;
            }
            catch (Exception ex)
            {
                string mes = ex.Message;
                textBox2.Text = mes;


            }
        }

    }
}

OpsinをC#で使う

以前に.NETでCDKを使うで書いたように、JAVAの実行ファイル(.jarファイル)を.NETのclass library(dllファイル)にConvertする方法を使えば、いろいろなJavaの便利環境を.NETで使うことができます。

今回は私の心の師匠のkさんのhttp://blog.kzfmix.com/entry/1214827204で使っていたOpsinを.NETで使えるか試してみました。

Opsinは化合物のIUPAC名をCMLに変換するモジュールで、CMLからさらにSDやSmilesなどに変換することができます。これを使えば、論文や特許に記載されている化合物の文字列から構造を起こすことができるという優れものです。

使ったOpsinはOscar3に入っているOpsin-0.5.3.jar。実は最初に0.1.0を試したのですが、どうもIUPACの認識率が低く、使い物にならんなーと思って諦めかけたのですが、このバージョンになってだいぶ良くなったので使うことにしました。

いつもどおりにIKVMでjarをdllに変換します。このときkeyfileがあれば指定することもできます。keyfile付きで変換することで「厳格な名前」付きdllにすることができるというわけです。

出来上がったdllをVisualStudioのC#のプロジェクトにいれます。そして

using OpenBabel;
using uk.ac.cam.ch.wwmm.opsin;


NameToStructure nts = new NameToStructure();
string cml = nts.parseToCML("4-iodobenzoic acid").toXML();


OBMol obMol = new OBMol();
OBConversion conv = new OBConversion();
conv.SetInAndOutFormats("cml", "can");
conv.ReadString(obMol, cml);
string smiles = conv.WriteString(obMol);
string[] smile = smiles.Split(new string[] { "\t" }, StringSplitOptions.None);
string result = smile[0];

こんな流れのコードを使えばIUPAC名からSmiles文字列を作ることができます。

ただ、特許や論文のIUPAC名はけっこういい加減で、" ' - などの使い方、あるいは半角スペースの入り方でOpsinがエラーを吐くことが多いです。Opsinに渡す前にIUPAC名のCleanが必要なようです。

またここで書いたOBConversionクラスですが、どうもメモリーリークがありそうなので、CMLの変換には使わない方が良いでしょう。このあたりについては次に・・・・