Amon2::Lite おさらい 3. bl2seq する Web Appli


[2.](http://qiita.com/bunzaemon/items/83dd11cbe48ca0fe9867)の続き

2.の例はあまりにも簡単過ぎて、 `Kolon` の活躍が殆ど無い。それではおさらいにならないので。

#### やること

`blastn` を利用して、1vs1 の相同性検索を行なって、それを表示するアプリを作成してみる。

html としては、

- sequence を投げるページ
	- 二種類のシーケンスを投げるから、二つのテキストエリアが必要
- 結果を表示するページ

の二つが必要。

で `perl` の方では、外部コマンドを実行して結果を取り込む事が必要。

前回の、最後の app.psgi を編集して行く。

##### `blastn` が入っていない場合。

[ここ](ftp://ftp.ncbi.nlm.nih.gov/blast/executables/blast+/LATEST/)から最新版をダウンロード

OSX の場合は、ncbi-blast-2.2.31+-universal-macosx.tar.gz を展開


```
$ wget -q ftp://ftp.ncbi.nlm.nih.gov/blast/executables/blast+/LATEST/ncbi-blast-2.2.31+-universal-macosx.tar.gz
$ tar zxf ncbi-blast-2.2.31+-universal-macosx.tar.gz 
$ mv ncbi-blast-2.2.31+ ~/cmd/bin
```

* `bl2seq` と言いながら、legacy の方にはリンクすら貼らない。


## perl コード部分

先に perl コード部分を。

`get /` 直前までは前のコードと全く同じ。それで、 `get /` は、index.tx を描画させるだけ。

```
get '/' => sub { return shift->render('index.tx'); };
```

その次に、 `index.tx` からポストされた内容を受け取るコントローラーを書く。とりあえず `/bl2seq` とする。

```
post '/bl2seq' => sub {
    my $c = shift;
    my ( $out_fh1, $seq1 ) = tempfile ;
    my ( $out_fh2, $seq2 ) = tempfile ;
    print { $out_fh1 } $c->req->param('seq1') ;
    print { $out_fh2 } $c->req->param('seq2') ;
    my $result = qx{/Users/bunzaemon/cmd/bin/ncbi-blast-2.2.31+/bin/blastn -query $seq1  -subject $seq2 } ;
    return $c->render('result.tx', { result => $result });
};
```

- `$c->req->param('')` で投げられたリクエストを受け取る事が出来るので、二つのシーケンスをそれぞれ、`seq1`, `seq2` とし、ファイルに保存。
- もちろん、`use File::Temp qw( tempfile ) ;`[^1] でテンポラリーファイルにして、後腐れ無くする。
- `blastn` の実行は、各人の環境に合せる。
- `IPC::Open3` を使いたい所だけど、`qx{}` で。
- で結果を `result.tx` へ。

これだけの非常に簡単なもの。


[^1]: `tmpfile` の戻り値は、ファイルハンドルとパス。


## html の編集

### sequence を投げるページ

```
@@ index.tx
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>BL2SEQ</title>
</head>
<body>
     <h1>input</h1>
     <form method="get" action="/">
     <textarea name="seq1" rows="4">input sequence1</textarea><br>
     <textarea name="seq2" rows="4">input sequence2'</textarea><br>
     <input type="submit" value="submit" /></br>
     <p>それぞれのテキストエリアにシーケンスを入力してください。</p>
</body>
</html>
```

- まあ、title と見出しくらいは付けとこうか。
- シーケンスをポストする枠を二つ作ろうか。
- コメントも必要だよね。
- じゃ charset の宣言もしとこうか。 => perl コード部分で `use utf8;` 必要。

### 結果を表示するページ
```
@@ result.tx
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>BL2SEQ</title>
</head>
<body>
     <h1>result</h1>
     <pre><: $result :></pre>
     <p>結果が出ました。</p>
     <form method="get" action="/">
     <input type="submit" value="了解" /></br>
     </form>
</body>
</html>
```

- んじゃ、変数 result に結果をそのまま入れて、`<pre>` でさっくり表示させますか。
- ついでに `/` に戻る事も考えときましょう。


## app.psgi
今回の app.psgi の全コード。
単純だが、 html 部分が冗長な感じがする。

```
use strict;
use warnings;
use Amon2::Lite;
use utf8 ;
use File::Temp qw( tempfile ) ;

sub load_config {
    +{
        'Text::Xslate' => +{
            syntax => 'Kolon',
            suffix => '.tx',
            module => undef,
            cache  => 0,
        },
    }
}

get '/' => sub { return shift->render('index.tx'); };

post '/bl2seq' => sub {
    my $c = shift;
    my ( $out_fh1, $seq1 ) = tempfile ;
    my ( $out_fh2, $seq2 ) = tempfile ;
    print { $out_fh1 } $c->req->param('seq1') ;
    print { $out_fh2 } $c->req->param('seq2') ;
    my $result = qx{${HOME}/cmd/bin/ncbi-blast-2.2.31+/bin/blastn -query $seq1  -subject $seq2 } ;
    return $c->render('result.tx', { result => $result }); 
} ;


__PACKAGE__->to_app(handle_static => 1);

__DATA__

@@ index.tx
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>BL2SEQ</title>
</head>
<body>
     <h1>input</h1>
     <form method="post" action="/bl2seq">
     <textarea name="seq1" rows="15">input sequence1</textarea><br>
     <textarea name="seq2" rows="15">input sequence2</textarea><br>
     <input type="submit" value="submit" /></br>
     <p>それぞれのテキストエリアにシーケンスを入力してください。</p>
</body>
</html>

@@ result.tx
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>BL2SEQ</title>
</head>
<body>
     <h1>result</h1>
     <pre><: $result :></pre>
     <p>結果が出ました。</p>
     <form method="get" action="/">
     <input type="submit" value="了解" /></br>
     </form>  
</body>
</html>
```

ブラウザをリロード[^2]する。

[^2]: `plackup -r` してる前提。


## 動かしてみる。

適当な配列を二つ持って来て、フォームにセット。
例えば、[これ](http://www.ncbi.nlm.nih.gov/nuccore/283483994?report=fasta)と[これ](http://www.ncbi.nlm.nih.gov/nuccore/480306395?report=fasta)[^3][^4]
![capt1.jpg](https://qiita-image-store.s3.amazonaws.com/0/64084/468cddc4-79bf-2b8c-b246-4b803f09697f.jpeg "capt1.jpg")

で、submit と。

![capt2.jpg](https://qiita-image-store.s3.amazonaws.com/0/64084/4497a6a9-9aa4-90de-cf2d-1f3d357da836.jpeg "capt2.jpg")

まあ、軽めのシーケンスの比較なら、コレで十分。後は、オプション類の ON/OFF を制御するラジオボタンあたりを実装して、、、
きりがないので、そこらへんは、言及せず。
後は、`Kolon` の機能のメモと、`launchctl` のメモ。

[^3]: 人間の肥満遺伝子とハツカネズミの対応する遺伝子
[^4]: bio 以外の人で、ここまでやった酔狂な人。`>` の行からをコピペしてください。