はじめに
この記事は遊びです。
念のため書いておきますが、まじめな情報は期待しないでください。
すべてのファイルを塩基配列に変換することを考えよう
DNAは4つの塩基(A、C、G、T)から成り立っているので、2bitだと考えることができます。
そう考えると、たぶんすべてのファイルを簡単に塩基配列に変換することができます。なのでCrystalでやってみました。
binary → 塩基配列
適当なCrystalスクリプトでバイナリーストリングを2bitずつ取り出して、DNA塩基配列に変換するプログラムを記述します。
BIT2BASE = {
0 => { 0 => 'A', 1 => 'C' },
1 => { 0 => 'G', 1 => 'T' }
}
while b = ARGF.read_byte
4.times do |i|
x1 = b.bit(i * 2)
x2 = b.bit(i * 2 + 1)
print BIT2BASE[x1][x2]
end
end
塩基配列 → binary
逆に、塩基配列をバイナリ文字列に変換するCrystalのスクリプトも作ります。Crystal言語になれていないので、実は書くのにかなり時間がかかりました。
require "bit_array"
BASE2BIT = {
'A' => [false, false],
'C' => [false, true],
'G' => [true, false],
'T' => [true, true]
}
b_array = [] of Bool
while c = ARGF.read_char
b_array.concat BASE2BIT[c]
end
ba = BitArray.new(b_array.size)
b_array.each_with_index do |b, i|
ba[i] = b
end
STDOUT.write(ba.to_slice)
…かなり効率の悪い書き方をしている可能性があります。(一回Bool Arrayを作って、それをBitArrayに移し替えて、最終的にSliceにして、バイナリをファイルに書き込むということをやっています。Rubyにしておけばよかった、とか思いましたがなんとか最後まで書きました。)多分一回全部メモリにデータを乗せるので、大きなサイズのファイルを変換するのには向いていないかもしれません。もっとよいやり方ができる方はコメント欄で教えてください。
さて、これをビルドします。
crystal build --release b2dna.cr
crystal build --release dna2b.cr
Crystal言語の素晴らしいところは、実行時間が非常に速いことです。Heng Li氏もCrystalは速いと言ってます。
しかし、--release
をつけるとコンパイルにはかなり時間がかかります。
動作確認をします。
echo "吾輩はネコである。名前はまだない。" | ./b2dna
GGCTAAGCCTTCACCTATTCGCCCTACTGAACTTCCTACTTAACGTACTACTCAACTATCTACTGAACTGCCTACTGAACCAACTACTCAACTCACTACTAAACCAACGGCTAAGCGTACGGCTGCACGTACTACTGAACTTCCTACTGAACCTTCTACTGAACAACCTACTGAACCCCCTACTGAACAGACTACTAAACCAACCCAA
塩基配列が表示されました。
echo "吾輩はネコである。名前はまだない。" | ./b2dna | ./dna2b
とすると、
吾輩はネコである。名前はまだない。
と表示されます。
とりあえず私のPC上では、画像ファイルや動画ファイルなんかも、塩基配列に変換が成功するようです。(ひょっとしたら多少不具合の出るファイルがあるかもしれません。その場合はコメント欄で教えてください。)
cat 変換したいファイル | ./b2dna > hoge.seq
でOK。
いや、ちょっと待てよ、この記事は何の役に立つんだよ?
さあ? あまり役には立たないのではないでしょうか。
まあ面白いからいいじゃないですか。
この記事は以上です。