次世代シーケンサーの解析において、SAM/BAM形式のファイル操作は非常に重要となります。
そこで本記事では、SAM/BAMファイルの読み込みや変換ができるPythonのライブラリであるpysamを使い方を解説します。
SAMファイルとは
シーケンスのアライメント結果を扱う際に広く利用される形式がSAM(Sequence Alignment/Map)ファイルです。
SAMファイルは大きく「ヘッダー部」と「アライメント部」の2つのセクションに分かれています。
ヘッダー部
ヘッダー部はファイルの先頭にあり、各行が「@」で始まります。主なヘッダー行の種類は以下の通りです。
- @HD (Header): ファイル全体の情報(フォーマットバージョン、ソート順など)
- @SQ (Sequence): 参照配列の情報。各参照配列(例:染色体)の名前や長さを記述
- @PG (Program): 使用プログラム
アライメント部
ヘッダー部の後に続くのがアライメント部で、各行が1つのリードのアライメント情報を示します。
以下の表は、SAMファイルのアライメント部における必須11項目のフィールド名、説明、および例をまとめたものです。
フィールド | 説明 | 例 |
---|---|---|
QNAME | リードの名前。リードを一意に識別するために使用される。 | read0001 |
FLAG | リードの状態を示すビットフラグ。ペアエンド情報、マッピング状態、リードの向きなどの情報を含む。 | 99 |
RNAME | マッピング先の参照配列名。通常は染色体名などが記載される。 | chr1 |
POS | 1-basedのマッピング開始位置。リードが参照配列のどの位置からマッピングされるかを示す。 | 1000 |
MAPQ | マッピングの品質スコア。通常はPhredスケールで表され、値が高いほど信頼性が高い。 | 60 |
CIGAR | リードと参照配列のアライメント状態を表す文字列。マッチ(M)、挿入(I)、削除(D)などの情報を含む。 | 50M |
RNEXT | ペアエンドリードのもう一方の参照配列名。同じ参照配列の場合は”=”が用いられる。 | = |
PNEXT | ペアエンドリードのもう一方のマッピング開始位置。 | 1050 |
TLEN | テンプレートの長さ(挿入サイズ)。リード間の物理的な長さを示す。 | 100 |
SEQ | リードの塩基配列。アライメントに用いられるシーケンス情報。 | ACGTACGT… |
QUAL | 各塩基の品質スコア。ASCIIコードでエンコードされ、各塩基の信頼度を示す。 | !*8ADF+JA… |
1. FLAG値の解釈
ビット値 (16進数/10進数) | 意味 | 説明 |
---|---|---|
0x1 (1) | ペアエンド | リードがペアエンドシーケンシングであることを示す |
0x2 (2) | 適切なペア | 各リードが正しくペアになっている(properly paired) |
0x4 (4) | 未マッピング | リード自体がマッピングされていない |
0x8 (8) | 次リード未マッピング | ペアのもう一方のリードがマッピングされていない |
0x10 (16) | 逆方向マッピング | リードのシーケンスがリバースコンプリメントされている |
0x20 (32) | 次リード逆方向 | ペアのもう一方のリードがリバースコンプリメントされている |
0x40 (64) | 第一リード | テンプレート内で最初のリードであることを示す |
0x80 (128) | 第二リード | テンプレート内で2番目のリードであることを示す |
0x100 (256) | 二次的アライメント | セカンダリアライメントである(複数のマッピング候補がある場合) |
0x200 (512) | 品質フィルタ不合格 | QCフィルタに合格していないリード |
0x400 (1024) | 重複リード | PCRまたは光学的重複である |
0x800 (2048) | 補助的アライメント | 補助的アライメント(supplementary alignment) |
具体例を用いて、説明します。
例1: FLAG = 99
99 (10進数) は、次のビットの和として表されます。
-
0x1 (1)
-
0x2 (2)
-
0x20 (32)
-
0x40 (64)
つまり、FLAG=99 の場合、以下の情報が含まれています:
-
ペアエンドリードである(0x1)
-
正しくペアになっている(0x2)
-
このリードがテンプレート内の最初のリードである(0x40)
-
ペアのリードはリバースコンプリメントでマッピングされている(0x20)
また、FLAG 99 には 0x10 が立っていないため、このリード自体は正方向にマッピングされていると解釈されます。
例2: FLAG = 147
147 は次のビットの和です。
-
0x1 (1)
-
0x2 (2)
-
0x10 (16)
-
0x80 (128)
これにより、FLAG=147 の場合は:
-
ペアエンドリードである(0x1)
-
正しくペアになっている(0x2)
-
このリードがテンプレート内の最後のリードである(0x80)
-
このリードがリバースコンプリメントでマッピングされている(0x10)
このように、FLAG値は各ビットの組み合わせによって、リードの状態(マッピングの有無、向き、ペアの情報など)をコンパクトに表現しています。
2. CIGAR文字列の解釈
オペレーション | 説明 | SEQや参照配列への影響 |
---|---|---|
M | マッチまたはミスマッチ | リードと参照配列の整列部分。元々はマッチのみを示すが、現在はミスマッチも含む |
I | 挿入 | リード側にのみ存在する塩基。参照配列にはない |
D | 削除 | 参照配列側から欠失している塩基 |
N | 参照上のスキップ | 参照配列上で飛ばされた領域(例:イントロン) |
S | ソフトクリッピング | リードの一部が切り落とされるが、SEQには含まれている(整列には使用されない) |
H | ハードクリッピング | リードの一部が切り落とされ、SEQにも含まれない |
P | パディング | 参照配列に対する空白(パディング、あまり用いられない) |
= | 正確なマッチ | リードと参照配列が完全に一致する部分 |
X | ミスマッチ | リードと参照配列が一致しない部分 |
CIGER文字列についても、具体例をみながら解説していきます。
-
例: “10M1I39M”
-
意味:
-
最初の10塩基が参照と整列(マッチまたはミスマッチ)
-
続いて、リード側に1塩基の挿入がある(参照側には対応なし)
-
その後、39塩基が整列
-
-
解説: リードの長さは10 + 1 + 39 = 50塩基ですが、参照配列上では10 + 39 = 49塩基分の領域にマッピングされます。
-
-
例: “5S45M”
-
意味:
-
最初の5塩基はソフトクリッピングされ、整列には含まれないが、リードのSEQには含まれる
-
その後、45塩基が整列
-
-
解説: リード全体は50塩基ですが、アライメントとしては45塩基が参照に対してマッピングされます。ソフトクリップされた部分は整列から除外されるため、解析対象外となります。リードの両端など、整列に使われなかった部分を「ソフトクリップ」として扱います。この部分はリードのシーケンス(SEQフィールド)には残っており、後で品質チェックや再解析のために利用できる場合がありますが、アライメント解析時には無視されます。
-
これらの表を参照することで、SAMファイルのFLAG値やCIGAR文字列が示す情報を正確に解釈し、アライメントの状態やリードの特徴を理解することができます。
SAM/BAM/CRAMのファイルの違い
SAM, BAM, CRAMのファイルの違いについて、以下に示します。
-
SAM: テキスト形式で記述されているため、内容が直接確認できるが、可読性が高い反面、ファイルサイズが大きい。
-
BAM: バイナリ形式で、直接内容を確認するには専用ツール(例:samtools view)が必要。
-
CRAM: BAM同様のバイナリ形式ですが、参照ベースの圧縮を利用しており、さらに高い圧縮率を実現。
pysamとは
pysamは、HTSlibの機能をPythonから利用できるようにしたライブラリです。
- 主な機能
- SAM/BAM/CRAMファイルの読み込み、書き出し
- インデックスファイルの作成と利用
- アライメント情報やシーケンスデータの操作・抽出
これにより、独自のパイプライン構築や解析ツールの作成が容易になります。
pysamのインストール方法
pysamはpipを使って簡単にインストールできます。ターミナルで以下のコマンドを実行してください。
pip install pysam
これで、pysamをインストールできました。
ファイルの読み込み
UCSCからサンプルのBAMファイルをダウンロードします。
下記のコードをpythonで実行して、BAMファイルをダウンロードします。
import urllib src_file = "http://hgdownload.cse.ucsc.edu/goldenPath/hg19/encodeDCC/wgEncodeUwRepliSeq/wgEncodeUwRepliSeqBg02esG1bAlnRep1.bam" dest_file = "input.bam" urllib.request.urlretrieve(src_file, dest_file)
import pysam samfile = pysam.AlignmentFile("input.bam", "rb") num = 0 for read in samfile.fetch(until_eof=True): if num > 5: break print(read.query_name, read.reference_name, read.mapping_quality, read.flag) samfile.close()
SOLEXA-1GA-2_2_FC20EMB:5:251:979:328 chr1 25 0
SOLEXA-1GA-2_2_FC20EMB:5:102:214:278 chr1 25 0
SOLEXA-1GA-2_2_FC20EMB:5:195:284:685 chr1 25 16
SOLEXA-1GA-2_2_FC20EMB:5:35:583:827 chr1 25 0
SOLEXA-1GA-2_2_FC20EMB:5:248:130:724 chr1 25 0
SOLEXA-1GA-2_2_FC20EMB:5:236:644:107 chr1 25 16
SAM/BAMファイル変換
BAMファイルからSAMファイルに変換してファイルを出力します。
# BAM ファイルを読み込み (バイナリモード)
with pysam.AlignmentFile("input.bam", "rb") as bamfile:
# 同じヘッダー情報を使って SAM ファイルをテキストモードで書き出す
with pysam.AlignmentFile("output.sam", "w", header=bamfile.header) as samfile:
# ファイル内の全リードを反復して書き出す
for read in bamfile.fetch(until_eof=True):
samfile.write(read)
これで、output.samというSAMファイルに変換されました。SAMファイルはテキスト形式なので読むことができます。
先ほど、変換したSAMファイルをBAMファイルに変換します。
# SAM ファイルを読み込み
with pysam.AlignmentFile("output.sam", "r") as samfile:
# 同じヘッダー情報を使って SAM ファイルをテキストモードで書き出す
with pysam.AlignmentFile("output.bam", "wb", header=samfile.header) as bamfile:
# ファイル内の全リードを反復して書き出す
for read in samfile.fetch(until_eof=True):
bamfile.write(read)
うまくいけば、output.bamファイルが作成されます。
インデックスの作成
BAMファイルのインデックスを作成すると、より効率的にファイルを扱うことができます。
bam_path = "input.bam"
pysam.index(bam_path)
コマンドを実行すると、input.bam.baiというインデックスファイルが作成されます。
インデックスがあれば、下記のように特定の領域を効率よく取り出すことができます。
samfile = pysam.AlignmentFile("input.bam", "rb")
for read in samfile.fetch('chr1', 10000, 10200):
print(read)
samfile.close()
まとめ
本記事では、pysamの基本的な使い方から、特定領域のデータ抽出、インデックス作成、そしてファイルの書き出しまで、バイオインフォマティクスにおけるSAM/BAMファイルの操作に役立つ機能を解説しました。pysamはシンプルながらも強力なツールであり、独自の解析パイプライン構築に大いに役立ちます。ぜひ、実際のデータを用いて試してみてください。