CDK使ったモジュールを書いてみた

Inline::JavaでCDKのニ次元構造立ち上げをperlでやれるようになったんだけど、やっぱuseして使いたいのでモジュール化してみた。

最初、Inlineでモジュールを書く方法の通りに書いてみたらエラーを吐いて動かないので、どうしたもんかと。
で、少し探してみたら、あまり深く考えなくて、普通にコンストラクタだけ用意してやればOKということらしい。

use 5.008008;
use strict;
use warnings;

our $VERSION = '0.01';

use Inline Java => "DATA";

sub new {
    my $class    = shift;
    return CDK::Simple::smi2mol->new();
}

1;

__DATA__
__Java__
import java.io.StringWriter;
import java.io.IOException;
後はjavaコードがジャヴァジャヴァと。

で、使ってみる。

my $parser = CDK::Simple->new;    
my $smiles_string = "C(=O)O";
print $parser->convert($smiles_string);

お~、モジュールだ。実行すると無駄にタメがあるのはjavaだから~。ところで、newでblessする必要はないのかな?とか気になる。

実際に作ってみて、Inline::Java使ったモジュールは意外に簡単だった。

Error.pm

Inline::Java使っていてjavaのtry-catchってコンパイラに強制されてる感が強くてやだけど構文自体は読みやすくてよいよなと思ってたらperlでもtry-catch構文風なものが使えるようになるモジュールがあるそうだ。

qootas.org/blog - Perlにおけるtry catch

perl についてくるモジュール Error.pm を使うとこんな感じで書けます。

下の記事もわかりやすい。

perl.com: Object Oriented Exception Handling in Perl

The main goal of this article is to discuss in detail about exception handling in Perl and how to implement it using Error.pm. On our way, we'll be touching upon the advantages of using exception-handling over traditional error-handling mechanisms, exception handling with eval {}, problems with eval {} and the functionalities available in Fatal.pm. But by and large, our focus we'll be on using Error.pm for exception handling.

Inline::JavaでCDKのニ次元構造立ち上げをperlから

_in house_でケモインフォ関連のプログラミングをするのに、二次元構造の立ち上げツール(またはライブラリ)と、構造描画ツールは必須だが、いまのとこCDKを使うという選択肢しかない。

実用PerlプログラミングにInline::Javaを使うとjavaのコードをperlに組み込めると書いてあったので、CDKを組み込んでみたヨ。

ProductName 実用 Perlプログラミング 第2版
Simon Cozens
オライリージャパン / 3360円 ( 2006-03-01 )


まぁ、要するに、
Q.そこまでしてperlで処理したいのか?
A. もちろんですヨ、奥さん
ということなんだが。

さて、インストールはj2sdkの場所を指定しないといけないのでcpan -iだとこける。そのため地道に、buildディレクトリで再インストール。

$ cd .cpan/build/Inline-Java-0.51
$ perl Makefile.PL J2SDK=/usr/java/jdk1.5.0_08/
$ make java
$ make
$ make test
$ make install

ただ、make javaで

:入力ファイルの操作のうち、未チェックまたは安全ではないものがあります。
注:詳細については、-Xlint:unchecked オプションを指定して再コンパイルしてください。

とかいう警告が出るが、testは通るのでまぁ気にしないということで。

で、コードを書いてみる。

参考にしたjavaのコード

:::java use Inline Java => <<'END_OF_JAVA_CODE' ; import java.io.StringWriter; import java.io.IOException; import org.openscience.cdk.Molecule; import org.openscience.cdk.exception.CDKException; import org.openscience.cdk.io.MDLWriter; import org.openscience.cdk.smiles.SmilesParser; import org.openscience.cdk.layout.StructureDiagramGenerator; import org.openscience.cdk.tools.HydrogenAdder;

class smi2mol{

    public smi2mol(){
    }

    public String convert(String smi){
    Molecule mol = null;

    try {
        SmilesParser sp = new SmilesParser();
        mol = sp.parseSmiles(smi);
    }catch (Exception ise){
        ise.printStackTrace();
    }

    StringWriter w = null;
    MDLWriter  mw = null;

    try {
        w = new StringWriter();
        mw = new MDLWriter(w);
    } catch (Exception e) {
        e.printStackTrace();
    }

    HydrogenAdder ha = new HydrogenAdder();
    try{
        ha.addExplicitHydrogensToSatisfyValency(mol);
    } catch (Exception e){
        e.printStackTrace();
    }

    StructureDiagramGenerator sdg = new StructureDiagramGenerator();
        try{
        sdg.setMolecule(mol);
        sdg.generateCoordinates();
        mol = sdg.getMolecule();
        mw.write(mol);  
    } catch (Exception e){
        e.printStackTrace();
    }

    return w.toString();
    }
}

END_OF_JAVA_CODE

my $alu = new smi2mol();    
my $smiles_string = shift;
print $alu->convert($smiles_string);

実行してみる

::: sh $ perl test.pl "C(=O)O"

  CDK

  5  4  0  0  0  0  0  0  0  0999 V2000
    1.2990   -0.7500    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    0.0000    0.0000    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
    2.5981   -0.0000    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
    1.2990   -2.2500    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
    3.8971   -0.7500    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
  2  1  2  0  0  0  0 
  3  1  1  0  0  0  0 
  1  4  1  0  0  0  0 
  3  5  1  0  0  0  0 
M  END

水素が付加されて、座標も計算されたMOLファイルが出力される。

javaって例外を返す可能性がある場合try,catch構文入れないと強制的にエラーになるのね。try,catch構文は読みやすいけど、強制されんのはちょっとやだナァと。単にフォーマットをコンバートするだけのコードなのに結構長くなっちゃったし。

::: perl use CDK; use Chemistry::Mol;

my $mol = CDK::smi2sdf($molecule);
print $mol;

みたいにモジュールにしてuseして使えばCDKを意識しなくてよくなる。

FC5のjavaではまる

Fedora core 5のjdkだとJchemPaintが立ち上がらないので、SUNのJDKをインストール

rpm -e jdk
rpm -ivh jdk-1_5_0_08-linux-i586.rpm

profileに環境変数書いておく

/etc/profile

#java
JAVA_HOME=/usr/java/jdk1.5.0_08
CLASSPATH=.:$JAVA_HOME/lib/tools.jar:/usr/local/javalib/cdk-20050826.jar:\
/usr/local/javalib/jchempaint-2.0.12.jar

クラスパスってcdkとかjchempaintのjarファイル指定する必要あるんだろうか?わからん。

/usr/bin/javac,java,jarのシンボリックリンクの張りなおしをして作業終了

jreコマンド

サーバーの入れ替え作業してて気がついたんだけど、昔のJREに含まれていたjreコマンドっていつの間にかなくなってたのね(1.2かららしい)

というわけでjreを要求するOracle8iのクライアントをFC5にインストールしたらはまった。上で書いたとおりに最近のJREにはコマンドがないので、古いBlackdown JRE引っ張り出してきたがsegmentation faultを起こしてインストーラーの起動に失敗する。FC2まで実績があるのに、、、、

ちょっと見てみると、jreって単なるシェルスクリプトだったので、頑張ればGUIインストーラーを起動させられそうな感じが。

DBD::Oracleがないと仕事にならん。

とか思ってたが、最近はClass::DBI::Oracleまでないと困る。

この勢いでDBICまで覚えたいとこだが、最近余裕がないなぁ。ヒトもmake testで回帰テストできたらいいのになぁ(しかも毎日一回cronで)って強く思う。

あと、口頭で教えたことを、メモッとけじゃなくてウィキッとけって言うことが多くなった。っていうか、ウィキるって言葉がチーム内で動詞として定着しているような気が。

気になって今調べたらウィキるってウィキで調べるってことなのね。でも僕としては、ウィキに書き込んで記録として残すって意味のほうがしっくりくるなぁ

Inline::Java

Inline::Javaおもろい。毎度コンパイルするので気持ち遅いが、Javaのコード扱えるのは便利。

正直Java使う必要あんの?と問われると

ケモインフォでは必要、それはCDKがあるからダ

化合物の二次元座標の発生なんかはPerlMolはまだまだだし、ChemRubyもサポートしとらん。というわけで、smi2molをやるにはCDKがいいし、構造の画像変換も楽。

という経緯もあってpythonのjava実装であるjythonなどに心惹かれた事もあったが、SWIG,XSとなにやら、グルーなノリで、Inline::Javaの方向で試してみることにしたヨ。モジュール化しとけば、Javaを気にせず使いまわせるし。クイックハックにちょうどいい。

さらに、Inline::Rubyも試してみたいし、、、、、

でも、結局Inlineなんだよなぁ

JavaでもRubyでもある程度のコード書けないとあかんのよね。

そういうわけで、ChemRubyの作者の方に教えてもらったプログラミングRubyなども読み読みせなあかん。今のとこ3章で止まってるナァ。

ProductName プログラミングRuby―達人プログラマーガイド
デビット トーマス
ピアソンエデュケーション / ?円 ( 2001-09 )


でも、Ruby学ぶと絶対Railsにはしりたくなっちゃう。

悩みは尽きない。

デザインパターンとJAVA

perlでモジュール作るときに、グダグダになってくることが多いので、いっちょデザインパターンの勉強を!

というわけで、購入したオライリーの本は言語がjavaだけど面白い。

ProductName Head Firstデザインパターン ―頭とからだで覚えるデザインパターンの基本
Eric Freeman
オライリージャパン / 4830円 ( 2005-12-02 )


買うときは4.6Kは費用対効果が、、、なんて思っていたが、コード自体は感覚的に理解できるのでなかなかためになる。

とはいえ実際にperlではどう書くんじゃとなったときに困るので、

ProductName Web+DB press (特別総集編)

技術評論社 / ?円 ( 2005-03 )


のデザインパターン特集を見ながら一緒に勉強した。

が、ちゃんとjavaを理解していないとオライリーの本がきちんと理解できんので、

近所の本屋で結城浩の本を買って、年始に読破。

ProductName 改訂第2版 Java言語プログラミングレッスン (上)
結城 浩
ソフトバンククリエイティブ / 2520円 ( 2005-10-26 )


ProductName 改訂第2版 Java言語プログラミングレッスン (下)
結城 浩
ソフトバンククリエイティブ / 2520円 ( 2005-10-26 )


上下巻ともに、すらすら読めてすごくわかりやすかった。特にインターフェースとかスレッドの部分はperlにはなかったような部分なのできちっと理解するように何度か読み返した(スレッドは5.8ではわからんけど)。上巻は基本的な部分でもともとある程度は理解していたのでほとんど斜め読みだったが、下巻はperlでoopを少しは理解していたという面もあるが、流れがスムーズでさらさら読み進めた。そして言語体系としてのjavaもちょっとは理解した(気がする)。

特に予約語とか慣習とかは知らないとオライリーの本はきつい部分があるので、これからオライリーのデザインパターン本は2週目読みますゾ。

CDKで構造描画

smilesから二次元座標を立ち上げるには、CDKを使う。openbabelとかperlmolはここらへんが未実装。

StructureDiagramGenerator sdg = newStructureDiagramGenerator(); sdg.setMolecule(someMolecule); sdg.generateCoordinates(); Molecule layedOutMol = sdg.getMolecule();

これで二次元座標が起こせる。

さらに、org.openscience.cdk.rendererで構造をpngやjpgに書き出せる。

dopamine

でもCDKでも画像サイズを小さくするとサイズにあわせてダブルボンドの幅を小さくしたりフォントも綺麗に見えるように小さくなったりというような親切設計ではないんだよね。

dopamine

こんな風になってしまうな。今回eclipse使ってjavaで書いたけど、今後はこれをjythonで書き直す予定ダ。

subclipse

株ロボのためにEclipseの勉強を始めたヨ。 手始めに、Eclipseでsubversionを扱うためにsubclipseをインストール。

EclipseWikiSubclipseプラグイン をみながら導入作業。

更新マネージャーから更新すればいいのでラク。ちなみにsubversionは構築済み

colinux(debian)にjavaとjythonを導入

colinuxの容量も増えたことだし、要領よくjavaをインストールだ。

debが用意されていないのでココみて自前で作成、インストール。

jythonはjythonからjarファイルをダウンロードしたら、

java -jar jython_Release_2_2alpha1.jar

でOK

jython使えれば、CDKとかjchempaintのjavaライブラリ使えるし、PyMOLみたいな立体構造いじり系に加えてbiopythonで配列処理も出来るから、結構よさげな感じだ。