BLASTの結果をSAM形式に変換するスクリプト

BLAST(blastn)の結果を次世代シークエンサで使われるSAM形式に変換するスクリプトです.SAM toolsの中にも,blast2sam.plというperlスクリプトがあり,これのruby移植です.
少し拡張してあって,SAM toolsのblast2sam.plだと配列やquarity valueを出してくれないせいで,tabletなどのSAM/BAMを見られるviewerで読めないことがあります.以下のスクリプトだと,quarity scoreも(適当に)出力するので,tabletで読み込むことが可能です.
使い方は,blastn2sam.rb とすると

% blastn2sam.rb -t 1e-5 input_blast_result > output_sam_file

です.-t の後に示した値以下のE-valueを持つ結果だけsamに変換します.指定しないと全部変換します.
BLASTだとblastnしか対応していませんが,BLATのtblastx相当のオプションでBLAST出力した場合(-t=dnax -q=dnax -out=blast)もparseできます.

#!/usr/bin/env ruby

require 'optparse'

maxeval = 1.0
show_seq = true
opt = OptionParser.new
opt.on("-t", "--threshold [VALUE]", Float){|v| maxeval = v}
opt.parse!(ARGV)

def blast2sam(filename, maxeval, show_seq)
  fp = open(filename, "r")
  query_count = 1
  query_name = ""
  sam = {
    :qname=>'', :flag=>0x00, :rname=>'', :pos=>nil, 
    :mapq=>255, :cigar=>'', :nrnm=>'*', :mpos=>0, 
    :isize=>0, :seq=>'', :qual=>'', :as=>'', :ev=>''}
  cmaux = {:cur_op=>nil, :count=>0} # [0,0,0,'']
  cigar = Array.new
  qlen = 0
  qend = 0
  rname = ""
  query_next = false
  skip_size = 0  # number of spaces before alignment figure
  while line = fp.gets
    if cigar.size !=0 && (line =~ /^Query=/ || line =~ /Score =.*bits.*Expect/) 
      blast_print_sam(sam, cigar, cmaux, qlen - qend) if sam[:ev].to_f <= maxeval
      cigar = Array.new
    end
    if line =~ /^Query= (\S+)/
      query_name = $1
      query_count = 1
    elsif line =~ /\((\S+)\s+letters\)/
      qlen_str = $1
      qlen_str.gsub!(/,/, "")
      qlen = qlen_str.to_i
    elsif line =~ /^>(\S+)/
      rname = $1
    elsif line =~ /Length = (\d+)/
      slen = $1
    elsif line =~ /Score =\s+(\S+) bits.+Expect(\(\d+\))? = (\S+)/
      as = ($1.to_f + 0.499).to_i
      ev = $3
      ev = "1#{ev}" if ev =~ /^e/
      sam[:flag] = 0x49
      sam[:isize] = 0
      sam[:as] = as
      sam[:ev] = ev
      sam[:seq] = ""
      sam[:qual] = ""
      sam[:pos] = 0
      qbeg = 0
      cigar = Array.new
      cmaux = {:cur_op=>nil, :count=>0} # [0,0,0,'']  # @cmaux = (0, 0, 0, '');
      sam[:qname] = "#{query_name}_n#{query_count}" 
      sam[:rname] = rname
      query_count += 1
    elsif line =~ /Strand = (\S+) \/ (\S+)/
      sam[:flag] |= 0x10 if $2 == "Minus"
    elsif line =~ /Query\:\s(\d+)(\s*)(\S+)\s(\d+)/
      start = $1.to_i
      skip_size = 7 + $1.size + $2.size
      q = $3
      if qbeg == 0
        qbeg = start
        cigar << "#{(start-1)}H" if start > 1
      end
      qend = $4.to_i
      if show_seq == true
        sam[:seq] += q.gsub(/-/, "")
      end
      query_next = true
    elsif query_next == true
      query_next = false
      line.chomp!
      align = ""
      0.upto(q.size) do |i|
        align += line[skip_size+i,1] unless q[i,1] == "-"
      end
      align.gsub!(" ", ";")
      sam[:qual] += align
    elsif line =~ /Sbjct\:\s(\d+)\s*(\S+)\s(\d+)/
      s = $2
      if sam[:flag] & 0x10 != 0
        sam[:pos] = $3.to_i
      else
        sam[:pos] = $1.to_i if sam[:pos] == 0
      end
      cigar = aln2cm(cigar, q, s, cmaux)
    end
  end    
  blast_print_sam(sam, cigar, cmaux, qlen - qend) if sam[:ev].to_f <= maxeval
end

def blast_print_sam(sam, cigar, cmaux, qrest)
  cigar << cmaux[:count].to_s + cmaux[:cur_op].to_s
  if sam[:flag] & 0x10 != 0
    cigar = cigar.reverse
    sam[:seq] = sam[:seq].reverse unless sam[:seq].nil?
    sam[:seq].tr!("atgcrymkswATGCRYMKSW","tacgyrkmswTACGYRKMSW")
    sam[:qual] = sam[:qual].reverse unless sam[:qual] == "*"
  end
  sam[:seq] = "*" if sam[:seq].nil?
  sam[:cigar] = cigar.join("")

  puts [sam[:qname],sam[:flag],sam[:rname],sam[:pos], 
        sam[:mapq],sam[:cigar],sam[:nrnm],sam[:mpos], 
        sam[:isize], sam[:seq], sam[:qual], 
        "AS:i:#{sam[:as]}", "EV:Z:#{sam[:ev]}"].join("\t")
end

def aln2cm(cigar, q, s, cmaux)
  l = q.size
  op = nil
  0.upto(l-1) do |i|
    if q[i,1] == "-"
      op = :D
    elsif s[i,1] == "-"
      op = :I
    else
      op = :M
    end
    if cmaux[:cur_op] == op
      cmaux[:count] += 1
    else
      cigar << cmaux[:count].to_s + cmaux[:cur_op].to_s unless cmaux[:cur_op].nil?
      cmaux[:cur_op] = op
      cmaux[:count] = 1
    end
  end
  cigar
end

blast2sam(ARGV[0], maxeval, show_seq)

次世代シークエンサ(NGS)解析で使われるソフトの簡単なまとめ

  • 2010/5/25.EST assemblerのViewerに関して追記
  • 2010/6/9. ちょいちょい追記しています.
  • 2010/7/26. ちょいちょい編集しました.

少し調べたのでまとめを晒してみる.比較的よく使われて沿うなソフトをまとめてみました.既に解析をガシガシやられている先人の方から,こんなソフト使ってるよーとか,そんなん使わん,とか突っ込み歓迎です.あとソフトが見つからないところが有るので,補完コメントいただけると助かります.

主に2つの用途があると思います.

  1. ゲノム配列既知の種にNGSで読んだshort readをmapping
  2. ゲノム配列未知の種からNGSで読んだshort readのESTをアセンブル

(注)NGSの機材のメーカーIllumina/SOLiD/454によっても利用できるソフトウエアが変わります*1が,以下では一緒くたにして書いてあるので注意してください.454は配列が長いので従来のSanger法でのソフトが使えるケースがあります.SOLiDはcolor-space(http://seqanswers.com/forums/showthread.php?t=10 など参照)に対応しているか否かで使えるソフトが分かれます.(みゃー@ゲノムさん,ご指摘有り難うございます)

順に並べます(ソフトウエアはメーカ謹製のものではなく,アカデミアで自由に使えるものを中心に選んであります).

short readのassemblyが可能.マニュアルでは454対応と書いてあるが,ちょっときつそう.

  • Mapping以後の扱い(RNA-seq等)に関しては,上記では記述していません.

*1:454は400塩基位とSangar法に近い長さの配列を出力するのに対し,IlluminaやSOLiDは現状では100塩基以下の短い連続配列のみが読めます

2010年第1四半期の1言読書感想文

英語のバカヤロー! ~「英語の壁」に挑んだ12人の日本人~
古屋裕子
泰文堂
売り上げランキング: 213885

様々な分野の有名人にインタビューして,英語との関わりをインタビューしてまとめた本.この手の本は「英語を勉強しないと行けない」という煽りの本が多いのですが,「英語は諦めた」というタイプの人も含まれているのが面白い.但し,全般的に話が薄いので,英語の勉強法を詳しく知りたい人には向かない.

発売から1年以上経っているので,少し古い感じが否めないし,技術的にも浅いが,非常によくまとまっている.クラウドコンピューティングって何?と思っていて,技術には詳しくないけどコンピュータが好きという人には,今最適の本.

数学を利用して業務を行っている企業の話.中に数式は無く,主に企業トップが,数学が如何に重要かを説いている.インタビューの相手は製薬,鉄道,銀行,情報,工学と多岐にわたっていて面白い.人によって話の量や深さが異なっており・・・まぁ,経営者の理解度を反映しているのではないかと思う.数学という文化を根付かせ,中長期的に経済に反映していくドイツ文化の懐の深さが表れている.日本でも見習えるところは見習いたい.

大学教授という仕事
大学教授という仕事
posted with amazlet at 10.04.03
杉原 厚吉
水曜社
売り上げランキング: 3002

私が,大学生時代に講義を受けた事もあるし,学園祭用の冊子の為にインタビューをしたこともある先生の本.穏和だけど目線は鋭い杉原先生の性格が表れている.その一方で,あけすけに色々話を書いてあるので,今でさえ人気の出ない大学教員が,更に人気が無くなるのではないかと不安である位,正しい事が書いてある(企業は良いことしかパンフレットに書かないですからねぇ).研究所勤務か教員になるか迷っている人は利点と欠点も記されているので,見てみるとよいかも.ページ数と金額の割に内容は少なめ.

Webは黎明期に1度変化があり,今は黎明期から人々のインフラへと変化していく所なのだと思っている.そんな状況で,今の現状を切り取った本.森さんの鋭く,かつ,広角な視点が現れている.まとまった本というより,Web関連に関する現状や技術のサーベイに近い.Web関連の状況に興味ある人は,技術にくわしくなくても読めるので,今,見てみると良い本.新しい話題が多いので,1,2年後は古くなっているだろう.

データ整備・解析のためのインフラ整備について

この数ヶ月で,国内の複数の研究所の方々とお話しさせて頂く機会があったのですが,バイオインフォで重要と私が思っていている大量データを扱うためのインフラ整備が後手に回っている印象を受けました.色々な要因があるとは思うのですが,一つの側面についてのまとめと部外者視点の理想像で考えた問題提起です.
今後,当該分野が健全な発展を遂げられますように.

研究室配属診断の反省

研究室配属後のテーマ選びは基本的に学生の興味を最優先していますが,
そのテーマに潜む問題と,学生のスキルや本当の興味に不一致が毎年生じるので,
診断テストを用意してみました.その反省,という名の自分メモ.

  • 今年の問題
    • 文字列操作と数え上げ,散布図描画,DP, 探索問題, 説明書き,Webサーバ
    • 全般的に実装寄りになってしまった.
  • 来年以降入れるべきもの
    • 実行時間計測
    • 統計処理
    • 線形代数,最適化系の話題

遺伝子発現から見た様々な生体情報解析の繋がり

遺伝子発現を中心に,様々な生命情報の繋がりを書いて見ました.取捨選択したつもりですが,無計画にレイアウトしてしまったので,大分ごちゃごちゃしてます.

図の中は大ざっぱに言って

  • 矢印=情報の繋がり
  • 黄土色の文字=手法(遺伝子発現をクラスタリングすると遺伝子セットになる,とか.)
  • オレンジ=DB(DB名).DBを引けば辿れるところ
  • 赤=目的.

変なところの突っ込み歓迎,足りないところの情報,コメント絶賛募集です.
ゲノム配列中心版とか,立体構造中心版とか,誰か書いてくれないかなぁ.

生命情報学系論文誌の傾向と対策

幸せなバイオインフォマティクス研究生活を送るために、論文誌の傾向と対策です。

バイオインフォマティクス(生命情報学、生物情報学)分野は幅広い生命科学分野をカバーしているので雑誌によって傾向があります。その傾向をまとめてみました。円の大きさは、その雑誌に載ったときの社会的なインパクトの大きさです。バイオインフォ関係の論文が掲載される雑誌は数多ありますが、ここで選択したのは以下の基準で選びました。

  • 生物実験無しでコンピュータ及び数式的な解析だけで載る可能性が有る
  • 種や現象に偏りすぎていない(そのため遺伝学系の雑誌や植物など種を特定したものを省いてあります)

ざっくりとした傾向として、

ここでは主要な雑誌、少し特徴的な傾向のある雑誌のみを示しました。Wikipediaバイオインフォの論文誌一覧があるので、を参考にしてください(これでも足りていなくて、もっとマイナーな雑誌は数多くあります)。

傾向と対策をしっかりして、ハッピーなパブリッシュをしましょう!