OpenBabelでC++プログラミング 〜超入門 その1〜

Hello Aspirin

 OpenBabelを無事インストールできましたか?今回はOpenBabelを利用した超簡単なC++プログラムを紹介したいと思います。先ずは以下のプログラムをコンパイルしてみましょう。この例では”main1.cpp“というファイル名でプログラムを保存します。このプログラムは”Aspirin.mol“という分子のMOLファイルを読み込んでSMILES形式で出力するという簡単なプログラムです。2個のファイルのリンクをクリックしてダウンロードして下さい。

  1 #include <iostream>
  2 #include <fstream>
  3 #include <string>
  4
  5 #include <openbabel/mol.h>
  6 #include <openbabel/obconversion.h>
  7
  8 using namespace std;
  9 using namespace OpenBabel;
 10
 11 int main(int argc, char* argv[]) {
 12
 13   ifstream ifs("Aspirin.mol");
 14
 15   OBConversion conv;
 16   conv.SetInFormat("MOL");
 17   conv.SetOutFormat("SMI");
 18
 19   OBMol mol;
 20   conv.Read(&mol, &ifs);
 21   conv.Write(&mol, &cout);
 22 }

/usr/local/以下にOpenBabelをインストールしたとすると、以下のようなコマンドでコンパイル出来ます。

g++ main1.cpp -I/usr/local/include/openbabel-2.0 -L/usr/local/lib -lopenbabel

また/home/username/appの下にインストールした場合は/usr/localを置き換えれば良いだけです。

g++ main1.cpp -I/home/username/app/include/openbabel-2.0 -L/home/username/app/lib -lopenbabel

“a.out”という実行ファイルが出来るので、実行してみると以下のような出力が得られます。

$ ./a.out 
c1(c(cccc1)OC(=O)C)C(=O)O	Aspirin

これがOpenBabelを利用した一番単純で簡単なプログラムです

簡単に解説

 先ず、OpenBabelのライブラリの名前空間はそのまま”OpenBabel”です。私は面倒くさがりなので、”using namespace OpenBabel”としてしまいます。次に分子情報を扱うクラスは”OBMol”です。main1.cppの19行目に宣言していますが、このクラスのインスタンスが具体的な分子構造(この例ではAspirinになります)ということになり、OpenBabelを利用したプログラムではこのクラスを色々弄るわけです。

 分子構造ファイルなどの読み書きやフォーマット変換は”OBConversion”というクラスを使って行います。このプログラムの例ではMOLファイルを読み込んで、SMILESに変換してから標準出力していますが、取り扱いたい分子フォーマットは16, 17行目で入力と出力の分子フォーマットを指定できます。この例ではSMILESを”SMI”と記述していますが、Canonical SMILESにしたい場合は”CAN”とすれば良いです。OpenBabelで取り扱えるフォーマットはめちゃめちゃ多いので、マニュアルなどで確認してみてください。

 ファイルからの読み込みは20行目で行っており、標準出力は21行目で行っています。OBConversionのメソッドであるReadやWriteの引数に、OBMolとstreamのポインタを指定すれば良いだけなので簡単です。

逆にSMILESを読み込む

 さて逆にSMILESのファイルを読み込んでからMOLファイルで出力するプログラムを作ってみましょう。私が用意した”main2.cpp“と”Aspirin.smi“をダウンロードしてみて下さい。プログラムの内容は先程のものと本質的には変わらないので説明は省きます。ちなみにsmiファイルの書式は、1列目がSMILES文字列で2列目が分子名になり、区切りはタブとなります。ダウンロード出来たらコンパイルして実行してみましょう。以下のような警告が標準エラー出力されるはずです。あくまでも警告なので、プログラムは最後まで動作します。

==============================
*** Open Babel Warning  in WriteMolecule
  No 2D or 3D coordinates exist. Stereochemical information will be stored using an Open Babel extension. To generate 2D or 3D coordinates instead use --gen2D or --gen3D.

これは「2次元か3次元構造の座標値が無いよ」という警告ですね。SMILESには座標情報は無いので当たり前ですが、毎回表示されると少しウザいですよね。この出力を消すには2通りあり、1つは強制的に出力させない方法と2つ目は2次元か3次元の座標を生成する方法です。1つ目の強制的にログの出力を停止するには以下の1行をプログラムの最初の方に追加するだけです。

obErrorLog.StopLogging();                    

これは、あまりお勧めできる方法ではないですが、ピタッとウザいメッセージが止まるはずです。次に座標生成する方法ですが、3次元化は色々と面倒なので、2次元構造を生成する方法を説明します。以下の2行を”conv.Read(&mol, &ifs);” と”conv.Write(&mol, &cout);”の間に挿入してみて下さい。(プログラムは”main3.cpp“です。)

  generateDiagram(&mol);
  mol.SetDimension(2);

この2行の命令で2次元構造が生成されます。この命令の意味は、先ず1行目で2元構造を生成してから、2行目でこの分子は2次元構造であると設定しています。コンパイルして実行すると以下のようなMOL形式の出力が得られます。ちなみにMOL形式に関する詳しい資料はこちらから参照できます。

Aspirin
 OpenBabel07071912412D

 13 13  0  0  0  0  0  0  0  0999 V2000
   -0.8660   -0.5000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -1.7321   -0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -1.7321    1.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -0.8660    1.5000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -0.0000    1.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -0.0000   -0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -2.5981   -0.5000    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
   -3.4641   -0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -3.4641    1.0000    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
   -4.3301   -0.5000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -0.8660   -1.5000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -1.7321   -2.0000    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
   -0.0000   -2.0000    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
  1  6  1  0  0  0  0
  1  2  2  0  0  0  0
  1 11  1  0  0  0  0
  2  3  1  0  0  0  0
  2  7  1  0  0  0  0
  3  4  2  0  0  0  0
  4  5  1  0  0  0  0
  5  6  2  0  0  0  0
  7  8  1  0  0  0  0
  8  9  2  0  0  0  0
  8 10  1  0  0  0  0
 11 12  2  0  0  0  0
 11 13  1  0  0  0  0
M  END

実は、OpenBabelのドキュメントに書かれている2次元構造の生成方法は”gen2D”オプションをOBMolクラスに適用するというものなのですが、少し面倒なので今回は簡単な方法を紹介しました。”gen2D”オプションを適用する方法についてはOpenBabelのドキュメントを参照して下さい。

構造式の確認

 一応出力されたものがAspirinの構造かどうか確認してみましょう。とりあえず以下のように出力をリダイレクトしてファイルにします。ここではファイル名は”Aspirin2.mol”とします。

$ ./aout > Aspirin2.mol

そして、構造の確認はもちろん以下のコマンドです(笑)。

$ obabel Aspirin2.mol -oascii 

ちゃんとAspirinの構造が見えましたか?