kuroの覚え書き

96の個人的覚え書き

CRISPRの編集を調べるプログラム

以前、CRISPRによって編集された遺伝子配列を解析するプログラムを書いたが、100%マッチするときしか検出できないのは不便だな、ということで、アライメントを取るツールを利用できないだろうかと考え中。

pairwise2 | BioPython の pairwise2 ライブラリーを利用したペアワイズアラインメント
こちらの情報を参考に、biopythonのpairwise2を使ってみる。

Python 3.6.5 (default, Apr 25 2018, 14:26:36) 
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from Bio import pairwise2
>>> from Bio.pairwise2 import format_alignment
>>> for a in pairwise2.align.localms("ACCGTCC", "ACG", 2, -1, -0.5, -0.1):
...     print(format_alignment(*a))
... 
ACCGTCC
| ||
A-CG---
  Score=5.5

ACCGTCC
|| |
AC-G---
  Score=5.5

なるほど。これで比べる2つ目の配列をregexで混合した配列から使えるとよいのだけれど

例えば

AACTCTGTTGTACTCTGGTCATAATTCCCTCGGCTAATTTAACCCGCT

こんな配列があったとして

シークエンス結果が

AACTCTGTTGTACTCTaatTCtTAccTCCgTCGatTtATT
AACTCTGTTGTACTCTGGGaaAtcATtcgCctaGCtAaac

こんなだったとする。
正解は

AACTCTGTTGTACTCTAGGTCATAATTCCCTCGGCTAATT
                ^
AACTCTGTTGTACTCTG    ATAATTCCCTCGGCTAATTTAAC

こういうふうになっているのだけれど

import regex
>>> w = 'AACTCTGTTGTACTCTGGTCATAATTCCCTCGGCTAATTTAACCCGCT'
>>> s1 = 'AACTCTGTTGTACTCTAATTCTTACCTCCGTCGATTTATT'
>>> s2 = 'AACTCTGTTGTACTCTGGGAAATCATTCGCCTAGCTAAAC'
>>> s = "".join('['+i+j+']' for i, j in zip(s1, s2))
>>> m = regex.finditer(s,w,overlapped=True)
>>> for match in m:
...     print(match.start(), match.group(), match.end())
... 
>>> 

こんなふうに以前作ったアプリではうまくヒットしない。一方はミスマッチのinsertionがあり、もう一方はそれとずれてdeletionが入っているからだ
とはいえpairwise2になんとなく組み込んでみても

>>> for a in pairwise2.align.localms(w, s, 2, -1, -0.5, -0.1):
...     print(format_alignment(*a))
... 
-----AA--C---T---C---T---G---TT------G---T---A---C---T---C---T----G---G--T-------CA--TAA--TT---C--C---CT----------CG--GC--T--------A--A-------TT--TA--A--------CCCGCT
     ||  |   |   |   |   |   ||      |   |   |   |   |   |   |    |   |  |       ||  | |  ||   |  |   ||          ||  ||  |        |  |       ||  ||  |        |
[AA][AA][CC][TT][CC][TT][GG][TT][TT][GG][TT][AA][CC][TT][CC][TT][AG][AG][TG][TA][CA][T-A][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]----
  Score=59.9
................

これじゃだめだね。
もうちょっと考えよう。

ちなみに

>>> s1 = 'ATTCTTACCTCCGTCGATTTATT'
>>> s2 = 'GGAAATCATTCGCCTAGCTAAAC'
>>> s = "".join('['+i+j+']' for i, j in zip(s1, s2))
>>> m = regex.finditer(s,w,overlapped=True)
>>> for match in m:
...     print(match.start(), match.group(), match.end())
... 
16 GGTCATAATTCCCTCGGCTAATT 39
20 ATAATTCCCTCGGCTAATTTAAC 43
>>> 

こういうふうに投げる配列をうまく調整すると答えにだいたいたどり着けるのだけど、どれくらいの位置にどれくらいdeletionが入っているのかというのが運次第というのではちょっとね。

>>> s1 = 'AACTCTGTTGTACTCTAATTCTTACCTCCGTCGATTTATT'
>>> s2 = 'AACTCTGTTGTACTCTGGGAAATCATTCGCCTAGCTAAAC'
>>> s = "".join('['+i+j+']' for i, j in zip(s1, s2))
>>> n = 1
>>> while s:
...     m = regex.finditer(s,w,overlapped=True)
...     print(str(n)+': '+s)
...     for match in m:
...             print(match.start(), match.group(), match.end())
...     s = s[4:]
...     n += 1
... 
1: [AA][AA][CC][TT][CC][TT][GG][TT][TT][GG][TT][AA][CC][TT][CC][TT][AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
2: [AA][CC][TT][CC][TT][GG][TT][TT][GG][TT][AA][CC][TT][CC][TT][AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
3: [CC][TT][CC][TT][GG][TT][TT][GG][TT][AA][CC][TT][CC][TT][AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
4: [TT][CC][TT][GG][TT][TT][GG][TT][AA][CC][TT][CC][TT][AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
5: [CC][TT][GG][TT][TT][GG][TT][AA][CC][TT][CC][TT][AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
6: [TT][GG][TT][TT][GG][TT][AA][CC][TT][CC][TT][AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
7: [GG][TT][TT][GG][TT][AA][CC][TT][CC][TT][AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
8: [TT][TT][GG][TT][AA][CC][TT][CC][TT][AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
9: [TT][GG][TT][AA][CC][TT][CC][TT][AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
10: [GG][TT][AA][CC][TT][CC][TT][AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
11: [TT][AA][CC][TT][CC][TT][AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
12: [AA][CC][TT][CC][TT][AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
13: [CC][TT][CC][TT][AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
14: [TT][CC][TT][AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
15: [CC][TT][AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
16: [TT][AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
17: [AG][AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
18: [AG][TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
16 GGTCATAATTCCCTCGGCTAATT 39
20 ATAATTCCCTCGGCTAATTTAAC 43
19: [TG][TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
17 GTCATAATTCCCTCGGCTAATT 39
21 TAATTCCCTCGGCTAATTTAAC 43
20: [TA][CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
18 TCATAATTCCCTCGGCTAATT 39
22 AATTCCCTCGGCTAATTTAAC 43
21: [CA][TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
19 CATAATTCCCTCGGCTAATT 39
23 ATTCCCTCGGCTAATTTAAC 43
22: [TA][TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
20 ATAATTCCCTCGGCTAATT 39
24 TTCCCTCGGCTAATTTAAC 43
23: [TT][AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
21 TAATTCCCTCGGCTAATT 39
25 TCCCTCGGCTAATTTAAC 43
24: [AC][CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
22 AATTCCCTCGGCTAATT 39
26 CCCTCGGCTAATTTAAC 43
25: [CA][CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
23 ATTCCCTCGGCTAATT 39
27 CCTCGGCTAATTTAAC 43
26: [CT][TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
24 TTCCCTCGGCTAATT 39
28 CTCGGCTAATTTAAC 43
27: [TT][CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
25 TCCCTCGGCTAATT 39
29 TCGGCTAATTTAAC 43
28: [CC][CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
26 CCCTCGGCTAATT 39
30 CGGCTAATTTAAC 43
29: [CG][GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
27 CCTCGGCTAATT 39
31 GGCTAATTTAAC 43
30: [GC][TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
28 CTCGGCTAATT 39
32 GCTAATTTAAC 43
31: [TC][CT][GA][AG][TC][TT][TA][AA][TA][TC]
29 TCGGCTAATT 39
33 CTAATTTAAC 43
32: [CT][GA][AG][TC][TT][TA][AA][TA][TC]
30 CGGCTAATT 39
34 TAATTTAAC 43
33: [GA][AG][TC][TT][TA][AA][TA][TC]
31 GGCTAATT 39
35 AATTTAAC 43
34: [AG][TC][TT][TA][AA][TA][TC]
32 GCTAATT 39
36 ATTTAAC 43
35: [TC][TT][TA][AA][TA][TC]
33 CTAATT 39
37 TTTAAC 43
36: [TT][TA][AA][TA][TC]
21 TAATT 26
34 TAATT 39
38 TTAAC 43
37: [TA][AA][TA][TC]
21 TAAT 25
22 AATT 26
34 TAAT 38
35 AATT 39
39 TAAC 43
38: [AA][TA][TC]
0 AAC 3
22 AAT 25
23 ATT 26
35 AAT 38
36 ATT 39
40 AAC 43
39: [TA][TC]
1 AC 3
3 TC 5
7 TT 9
11 AC 13
13 TC 15
18 TC 20
20 AT 22
23 AT 25
24 TT 26
25 TC 27
29 TC 31
36 AT 38
37 TT 39
38 TT 40
41 AC 43
40: [TC]
2 C 3
3 T 4
4 C 5
5 T 6
7 T 8
8 T 9
10 T 11
12 C 13
13 T 14
14 C 15
15 T 16
18 T 19
19 C 20
21 T 22
24 T 25
25 T 26
26 C 27
27 C 28
28 C 29
29 T 30
30 C 31
33 C 34
34 T 35
37 T 38
38 T 39
39 T 40
42 C 43
43 C 44
44 C 45
46 C 47
47 T 48

というわけでちょっと改良して、前から1文字分ずつ削っていって、合致する配列が現れるポイントを探る感じにしてみた。
下の方の数文字しかないところは全く意味がないので削る文字数の制限とかつけるともっと見やすい感じになるかも。


というわけでかなり作り込みました。
f:id:k-kuro:20190620125433p:plain

これはかなりいい感じじゃなかろうか

またまたサーバの構成をいじる

サーバ   CPU               メモリ            理論性能
RX1330M3 E3-1230v6(4C/8T, 3.50GHz)   2400 UDIMM 64GB  224.0GFLOPS
RX300S7  E5-2667(6C/12T, 2.90GHz)x2  1600 LV-RDIMM 32GB 278.4GFLOPS
RX300S7  E5-2643(4C/8T, 3.30GHz)x2  1600 LV-UDIMM 24GB    211.2GFLOPS
RX200S7  E5-2630(6C/12T, 2.30GHz)x2  1333 RDIMM 40GB  220.8GFLOPS
RX300S7  E5-2620(6C/12T, 2.00GHz)x2  1600 LV-RDIMM 24GB   192.0GFLOPS    

RX200S6  E5630(4C/8T, 2.50GHz)x2   1333 RDIMM 12GB     80.0GFLOPS         #GPU test機
RX200S6  E5630(4C/8T, 2.50GHz)x2   1333 UDIMM 4GB     80.0GFLOPS   #バックアップ機

ちょいとCPUとメモリを追加して、構成をいじってみた。

ヒートシンクを調達すればE5-2630L→E5-2620 x2 192.0GFLOPSにアップできるので、これもそのうち。
ただし、いまあんまり重いデータ解析をやってないので、ほぼ趣味の範疇に入るかも。
それよりはGPUのバージョンアップのほうが優先かも。
(それよりは深層学習をちゃんと理解できるレベルまで勉強するほうが先決)
(ていうか論文書けよ)


追記
ヒートシンクを調達し、RX300S7をE5-2620 x 2CPUにした。クラスタはこれで十分かな。RX200S6は基本テスト用途かな。
バックアップ機はファンの音が結構うるさいので連続通電運転は辛い。
現状余っている機材はE5-2630L、E5603

ディープラーニングちょっとずつ

なかなか先に進まないが、とりあえずちょとでもいじってみるか。
f:id:k-kuro:20190615223410p:plain
jupyter notebookの使い方を確かめながらmnistのデータを使った練習をやってみる。

いろいろわからないまま言われるままに入力し、その出力をまずは眺めてみる。

zeissのlsmファイルから画像を取り出して重ね合わせる

zeissの共焦点レーザー顕微鏡で撮影したマルチチャンネルな画像ファイルの各チャンネルをバラバラにしたファイルを出力し、それらをstackではなく1枚の画像にmergeしたものを作成したい。使うのはImageJ。
とりあえずImageメニューの中のツールでできることは確認したので、それをマクロ登録してちゃっちゃと連続で処理したい。

dir = getDirectory("image");
name = replace(getInfo("image.filename"), ".lsm", "");
run("Stack to Images");
run("Merge Channels...", "c2=Ch2 c4=ChD keep");
for (i=0;i<nImages;i++) {
        selectImage(i+1);
        title = getTitle;
        print(title);
        saveAs("png", dir+"/"+name+"_"+title+".png");
}
while (nImages>0) {
          selectImage(nImages);
          close();
} 

これでよし。

VNCとpyenv

deep learning machineの構成をあれこれいじっているうちに動作がおかしくなってきたので、一旦リセットしてOSインストールからやり直すことにした。

ここまでの手順では

CentOS7をデフォルトの最小構成でインストール
ネットワーク設定
一般ユーザー追加
gnome desktopインストール
vncサーバインストール
NVIDIAドライバインストール
CUDAインストール
pyenvインストール
anacondaインストール
python3.6にダウングレード
tensorflow-gpuインストール
kerasインストール

という感じであったのだが、今回最小構成ではなく最初からgnome desktop、開発環境付きでインストールしたところ、これがマズったらしく、かなりツボにはまり未だ脱出できていない。

問題はvncサーバのインストールを忘れていて最後にこれを入れようとして起こった。

どうやらpyenvとvncサーバの組み合わせには難があるらしく、pyenvの環境変数を.bashrcに加えるとvncサーバを起動しても画面が表示できないらしい。

現状解決策としては.bashrcに入るはずの

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
export PATH="$PYENV_ROOT/versions/anaconda3-5.3.1/bin/:$PATH"

コメントアウトし、systemctlでvncserverを起動してからログイン後にこれら環境変数をexportする、というものだが、メンドウクサス。

どうにかならないものか。

もう一回最初から手順通りにインストールしたほうが早そうだが、そのためにはサーバに直接でむかなくてはならず、これもまた面倒。

ここで気がついた。以前の環境じゃpyenvとvncが共存していたと思っていたが、単にインストールしたあと一回もrebootしてなかっただけなんじゃね?
どうインストールしてもpyenvとは両立しないのかも。


苦肉の解決策
まず、systemdによる自動起動は諦める。
.bashrcには上記環境変数を記載。
.bash_profileには

 User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH

vncserver :1 -geometry 1280x1024 -depth 24

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

のように.bashrcを読み込む前にvncserver起動を行うように順番を入れ替える。

ただ、この方法だとvncでアクセスする前にsshでログインをしておく必要があり、sshの方でログアウトしちゃうとvncも終了してしまうのでちょっとなあ。

Raspberry piで温度ロガー

ラズパイを温度監視用ロガーとして使えないかなと。

ここまでラズパイはマイクロLinuxボックスとしてしか使っておらず、IoT的な電子工作はやっていない。
で、どうなんよ、と今更ながらにIO関係を調べてみたところ、AD変換とかはない。
抵抗とコンデンサを使って、あとはソフトウェアでゴリ押しでなんとかするとかできなくもないだろうけど、今どきそんなことをするやつはおらず、みんな安いAD変換モジュールとかを買ってきてつなぐだけなんだ。つまんね。

とまあ、話はそれたが、結局ラズパイはただのミニPCなので、やはりセンサ関係をコントロールするならArduinoとかマイコンがまだまだ活躍するわけだ。
ラズパイにはユーザインターフェースに専念してもらうことになる。

で、そうなると結局10年ほど前にごにょごにょやっていたArduino温度計に戻っちゃう。あの頃はラズパイなんてなかったから改造FONルータにopen-WRTを入れて作ってた。
k-kuro.hatenadiary.jp

結局同じことをすることになる。

温度センサは
温室の温度警報装置 - kuroの覚え書き
これでも使ったLM-35DZが残っていたのでそれを利用。

Arduinoのスケッチはサンプルをちょいとだけいじって

#include <TimeLib.h>
// These constants won't change.  They're used to give names
// to the pins used:
const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
const int analogOutPin = 9; // Analog output pin that the LED is attached to

int sensorValue = 0;        // value read from the pot
int outputValue = 0;        // value output to the PWM (analog out)

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);
}

void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);
  // map it to the range of the analog out:
  outputValue = map(sensorValue, 0, 1023, 0, 500);
  // change the analog out value:
  analogWrite(analogOutPin, outputValue);

  // print the results to the serial monitor:
  Serial.print(now());
  Serial.print("\t sensor = " );
  Serial.print(sensorValue);
  Serial.print("\t temp = ");
  Serial.println(outputValue);

  // wait 2 milliseconds before the next loop
  // for the analog-to-digital converter to settle
  // after the last reading:
  delay(60000);
}

こんな感じ。
結局Arduinoは時計を持っていないのでリアルタイムは残せない。
なのでシリアルを受信した時間から換算して、ラズパイ側で日時を割り出す方式でお茶を濁す
RTCもいるな、やっぱり。そもそもラズパイにも時計入れたいし。

さて、ラズパイの側でシリアルを受信するプログラムであるがcuコマンドをインストールして利用する。

$ cu -l /dev/ttyUSB0 -s 9600

こんな感じでターミナル上にデータが送られてくることを確認。
f:id:k-kuro:20190522202019p:plain
これをpythonでファイルに落とし込むところを作る。

import datetime
import subprocess

date1 = datetime.datetime.now()
date2 = "{0:%Y%m%d_%H%M%S}".format(date1)
file1 = "./" + date2 + ".txt"
cmd = "cu -l /dev/ttyUSB0 -s 9600 > %s" % file1
subprocess.call(cmd, shell=True)

こんだけ。

このスクリプトをどうにかラズパイ起動と同時に走らせたいのだが、案外うまくいかない。

そういえばシリアルを受信するだけだったら

$ cat /dev/ttyUSB0 >> log.txt

みたいにするだけでできたような気がする。送信しないし、こっちのほうが簡潔かも。

f:id:k-kuro:20190522200859p:plain

#!/bin/sh
date1=`date +%Y%m%d_%H%M%S`
file1='./temp/'$date1'.txt'
cat /dev/ttyUSB0>>$file1

わざわざpython持ち出すよりこのほうがいいな。
これをcronに

crontab -e

@reboot /home/pi/temp.sh&

と追加してやったところ、問題なく記録が開始された。

primer設計でblast

適当に選んだ配列がoff targetを増幅しないか調べるためにblastnで検索するとき、普通にデフォルトでやっても何も引っかからない。
そんなときは

$ blastn -db ath -query ~/Desktop/act1_f.txt -word_size 7

のように-word_sizeオプションを付けると良い。

Deep learning マシンを変更

手持ちのサーバの構成を考え、Deep learningの環境テストを行うノードをPRIMERGY RX200S6に移した。

手順は

  • クラスタから切り離す。
  • 一般ユーザを作成。
  • グラボを移し替え。
  • NVIDIAのドライバインストール。
  • CUDAのインストール。
  • pyenvインストール。
  • anacondaインストール。
  • pythonのバージョンを3.6に落とす。
  • tensorflow-gpuインストール。
  • kerasインストール。

以上。
以前やったとおりで特に問題なく構築完了。
CPUが1世代前になって、理論速度では96GFLOPSから80GFLOPSに落ちたが、mnist_cnn.pyのテストで1EPOCHあたりにかかった時間は76秒と全く同じ。CPUの速度はほぼ関係ないということだろう。ということでRX300S7の方をクラスタに組み込むことにする。


EPOCH=1のトータルタイムは
GPUあり85.33秒
GPUなし138.65秒
sandy bridgeの96GFLOPSマシンで108秒だったのが80GFLOPSになったのでGPUなしは確実に遅くなったが、GPUありだとほとんど一緒だな。

multi FASTA (DNA)からmulti FASTA (Amino Acid)を機械的に作成する(その2)

ちょっと調べたらいけそうな気がしてきた。Biopythonを使うといろいろ簡単にできる模様。

まずはmultifastaを開いて配列を順番に読み込む

import sys
from Bio import SeqIO

fasta_file = sys.argv[1]

for record in SeqIO.parse(fasta_file, 'fasta'):
    ids = record.id
    desc = record.description
    seq = record.seq

    print('id:', ids)
    print('desc:', desc)
    print('seq:', seq)

とりあえずこんなスクリプトfasta_in.pyという名前で作れば

$ python3 fasta_in.py <fasta_file.fasta>

という感じに投げるとidと説明書きとシークエンスを取り出すことができる。

bioinformatics - Python find longest ORF in DNA sequence - Stack Overflow
そんでもって最長ORFはここに出ている例を使って取り出せるので

import sys
from Bio import SeqIO
import re

fasta_file = sys.argv[1]

for record in SeqIO.parse(fasta_file, 'fasta'):
    for strand, seq in (1, record.seq), (-1, record.seq.reverse_complement()):
        for frame in range(3):
            index = frame
            while index < len(record) - 6:
                match = re.match('(ATG(?:\S{3})*?T(?:AG|AA|GA))', str(seq[index:]))
                if match:
                    orf = match.group()
                    index += len(orf)
                    if len(orf) > 1300:
                        pos = str(record.seq).find(orf) + 1
                        print(">{}, pos {}, length {}, strand {}, frame {}".format\
                           (record.id, pos, len(orf), strand, frame ))
                        print(orf)
                else: index += 3

これでいいかな?と思ったが、なんかおかしい。

そもそもcDNAのfastaを見ているのでstrandは1方向固定でいいから

for strand, seq in (1, record.seq), (-1, record.seq.reverse_complement()):

このforループはいらないな。
matchじゃなくてfindallのほうがいいかな?
もうちょっと調べる。

import sys
from Bio import SeqIO
import re

fasta_file = sys.argv[1]

for record in SeqIO.parse(fasta_file, 'fasta'):
    match = max(re.findall('(ATG(?:\S{3})*?T(?:AG|AA|GA))', str(record.seq)), key = len,  default=0)
    if match:
        print(">" + record.id)
        print(match)

これで最長ORFを取り出せた。
あとはこれをアミノ酸に置き換える。

#!/usr/bin/python3
import sys, re
from Bio import SeqIO
from Bio.Alphabet import IUPAC
from Bio.Seq import Seq

fasta_file = sys.argv[1]

for record in SeqIO.parse(fasta_file, 'fasta'):
    match = max(re.findall('(ATG(?:\S{3})*?T(?:AG|AA|GA))', str(record.seq)), key = len,  default=0)
    if match:
        seq = Seq(match, IUPAC.ambiguous_dna)
        print(">" + record.id)
        print(seq.translate())

できた。これで一気に処理できる。
問題があるとすると、stopコドンがなくて尻切れトンボのORFを持つcDNAからはアミノ酸を読み出せないことかな。

pythonでABIのシークエンスデータをゴニョゴニョする

シークエンスファイルとかfastaファイルとかMacのApEとかで開いてどうにかするのがだんだん億劫になってきた。
pythonでどうにかあんなことやこんなことができないかと調査中

abifpy · PyPI

まあこんなモジュールでも使えばどうにかなりそうな感じ。
引き続き使い方を調査だ。

ところで企業再編の嵐が吹き荒れた結果、Applied BiosystemsもThermoFisherグループに組み込まれちゃったんだな。
キャピラリーシークエンサーが登場したときはすげーもんが出てきたもんだと・・・年がバレる。
そういえば昔は"ABI"って呼んでたよな。ABI Prism 310とかって。Iってなんだったんだ?Industory?
Incか。今どきの若者はABIとか呼ばないのかな。だってIncとしては存在してないからな。


さて、モジュールを早速使ってみよう。

$ python3
Python 3.6.1 (v3.6.1:69c0db5050, Mar 21 2017, 01:21:04) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from abifpy import Trace
>>> test = Trace('good_example_control.ab1')
>>> test.seq
'NNNNNNGGGGCATCCTGTGTTCTACCTGGCACCTGTCCCCATAGAAATGAGCGTGAGTGCCCGGGATCTGCTGCGGGGCTGTGCTGGGCTCTTTCTCAGCCTGGCCCGAAGTTTCCAGATCTGATTGAGCGAGAGAGCAGCAGGACCTGCCCCTCTGCTGGGCTCTTACCTTCGCGGCACTCGCCACTGCCCAGCAGCAGGTGAGGCCCAACACAACCAGTTGCAGGCGCCCCATGGTGAGCATCAGCCTCTGGGTGGCCCTCCCTCTGGGCCTCGGGTATTTATGGAGCTGGATCCAAGGTCACATGCTTGTTCATGAGCTCTCAGGCA'

なるほどabifpyからTraceを読み込んでおいてtestオブジェクトににab1ファイルのデータを並べて記述、という感じなのかな。

>>> test.qual
"&%&'''*+*11.4JKIP>_UOPABKYPRDA?P_\\__\\__L:W\\L\\_HAW\\R\\\\OW_\\\\\\\\_\\WWY\\M_\\\\\\\\WT\\___\\_________\\__WRRW_\\\\ORRRRK___\\_YS____\\\\Y_\\________\\___\\_\\_\\__\\___RBW______W___________KWWRW_RR_\\___\\_\\__\\__\\\\\\\\\\______\\__\\_\\_WWKW___\\_Y_\\\\W_\\_____\\\\_YS__W_\\\\_\\OW_Y_\\__\\CW_YWW__WY____\\Y833)2-_______\\\\YDW_____W__\\____W___\\_____\\_\\__WW____RLY>G<(2R\\_\\3A=3"

これの意味するところはなんだろか。
asciiコードなのか。

           51  3      71  G      91  [     111  o
           52  4      72  H      92  \     112  p
33  !      53  5      73  I      93  ]     113  q
34  "      54  6      74  J      94  ^     114  r
35  #      55  7      75  K      95  _     115  s
36  $      56  8      76  L      96  `     116  t
37  %      57  9      77  M      97  a     117  u
38  &      58  :      78  N      98  b     118  v
39  '      59  ;      79  O      99  c     119  w
40  (      60  <      80  P     100  d     120  x
41  )      61  =      81  Q     101  e     121  y
42  *      62  >      82  R     102  f     122  z
43  +      63  ?      83  S     103  g     123  {
44  ,      64  @      84  T     104  h     124  |
45  -      65  A      85  U     105  i     125  }
46  .      66  B      86  V     106  j     126  ~
47  /      67  C      87  W     107  k
48  0      68  D      88  X     108  l 
49  1      69  E      89  Y     109  m 
50  2      70  F      90  Z     110  n

で、ASCII code=Q+33なので、

>>> test.qual_val
[5, 4, 5, 6, 6, 6, 9, 10, 9, 16, 16, 13, 19, 41, 42, 40, 47, 29, 62, 52, 46, 47, 32, 33, 42, 56, 47, 49, 35, 32, 30, 47, 62, 59, 62, 62, 59, 62, 62, 43, 25, 54, 59, 43, 59, 62, 39, 32, 54, 59, 49, 59, 59, 46, 54, 62,・・・・

とこんな感じになるのだな。

>>> test.data['well']
'E10'
>>> test.data['model']
'3730'
>>> test.data['run start date']
datetime.date(2017, 9, 6)

この辺はシークエンサーの情報や、作業日時など