samtools를 왜 익숙해져야 하나요
지난 두 편에서 BWA-MEM과 STAR/HISAT2로 정렬을 마쳤습니다. 이제 그 결과 BAM 파일을 다뤄야 합니다. GATK, IGV, 커스텀 파이썬 스크립트 — 이 모든 뒷단이 samtools의 명령들을 전제로 씁니다. samtools는 그 자체가 CLI 도구이자 htslib이라는 C 라이브러리의 얼굴입니다.
한 시간만 각 잡고 익히면 그 뒤 5년의 파이프라인 생활이 편해집니다. 서두르지 맙시다.
SAM · BAM · CRAM — 셋의 관계
세 포맷은 같은 정보를 다른 방식으로 저장합니다.
| 포맷 | 인코딩 | 크기 | 용도 |
|---|---|---|---|
| SAM | 텍스트 (탭 구분) | 원본, 매우 큼 | 사람이 볼 때·디버깅·파이프 스트리밍 |
| BAM | 이진 압축 (BGZF) | SAM의 25~30% | 표준 저장·인덱스 지원·거의 모든 도구가 소비 |
| CRAM | 레퍼런스 기반 압축 | BAM의 30~60% | 장기 저장·클라우드 아카이빙 |
전환은 자유롭습니다. samtools 하나로 세 방향 어디로든 갈 수 있습니다.
첫 명령 다섯 개면 충분합니다
실무에서 매일 부르는 명령은 다섯 개입니다.
1. samtools view — 파일을 열어봅시다
samtools view SAMPLE01.bam | head -3samtools view -h SAMPLE01.bam | head -20 # 헤더 포함samtools view -c SAMPLE01.bam # 총 리드 수samtools view -c -f 4 SAMPLE01.bam # unmapped 리드 수samtools view -c -F 256 SAMPLE01.bam # secondary 제외 리드 수-h: 헤더도 출력.-c: 개수만 세기.-f N: 이 플래그가 켜진 리드만 (예: 4 = unmapped).-F N: 이 플래그가 켜진 리드는 제외 (예: 256 = secondary).
2. samtools sort — 좌표 정렬 필수 관문
samtools sort -@ 4 -o SAMPLE01.sorted.bam SAMPLE01.bamBWA/STAR가 뱉는 SAM/BAM은 리드 순서 그대로입니다. GATK, IGV, bcftools — 대부분이 좌표 정렬(coordinate-sorted) BAM을 요구합니다. sort는 그 정렬을 수행합니다.
-@ 4: 스레드 4개.-o out.bam: 출력.- 이름순 정렬이 필요하면
-n(특정 상황: 페어 재통합, HTSeq).
3. samtools index — 랜덤 액세스의 열쇠
samtools index SAMPLE01.sorted.bam.bai 파일이 생기고, 이후 IGV/bcftools/samtools view가 특정 구간 쿼리를 즉시 할 수 있습니다.
samtools view SAMPLE01.sorted.bam chr17:41196312-41277500 # BRCA1 구간만인덱스가 없으면 이 명령은 파일 전체를 스캔해서 몇 분이 걸립니다. 있으면 밀리초에 끝납니다. Snakemake 워크플로우에서 sort 뒤에 index를 반드시 이어붙이는 게 관습입니다.
4. samtools flagstat — 파이프라인 첫 대시보드
samtools flagstat SAMPLE01.sorted.bam출력 예시(요약):
120,000,000 + 0 in total
115,200,000 + 0 mapped (96.00% : N/A)
119,800,000 + 0 paired in sequencing
114,900,000 + 0 properly paired (95.91% : N/A)
2,400,000 + 0 duplicates이 다섯 줄만 매일 봐도 파이프라인 건강 진단이 됩니다.
- mapped ratio: 90% 아래면 참조 게놈 불일치, 오염 의심.
- properly paired ratio: 85% 아래면 라이브러리 인서트 크기 문제 또는 어댑터 잔재.
- duplicates: 20% 이상이면 라이브러리 복잡도 저하.
5. samtools idxstats — 염색체별 리드 분포
samtools idxstats SAMPLE01.sorted.bam각 시퀀스(염색체·컨티그) 별로 리드가 몇 개 붙었는지 알려줍니다. 이 결과로 성별 판정(chrY 리드 비율)이나 미토콘드리아 이상치를 즉시 확인합니다.
CRAM — 왜 실무가 넘어가고 있나요
BAM은 서열을 리드마다 다 저장합니다. 그런데 리드 대부분이 참조 게놈과 거의 같습니다. 참조와 다른 부분만 저장하면 훨씬 줄어들지 않을까? 이 아이디어를 구현한 게 CRAM입니다.
- CRAM은 참조를 기준으로 각 리드가 어떤 차이가 있는지만 이진 인코딩.
- 인간 게놈 WGS BAM 파일 100GB가 CRAM으로 저장하면 30~50GB로 줄어듭니다.
- 참조가 필요: CRAM 파일을 다시 열려면 원본 참조 fasta가 있어야 합니다.
BAM ↔ CRAM 변환
# BAM → CRAM (참조 지정 필수)samtools view -T hg38.fa -C -o SAMPLE01.cram SAMPLE01.sorted.bamsamtools index SAMPLE01.cram # .crai 생성
# CRAM → BAM (다시 되돌리기)samtools view -T hg38.fa -b -o SAMPLE01.bam SAMPLE01.cram-T hg38.fa: 참조 지정. 반드시 정렬 때 쓴 그 참조여야 합니다. 그 밖에는 BAM 사용법과 동일합니다.
CRAM 실무 함정 세 가지
- 참조 유실 시 재현 불가: CRAM 파일만 남기고 참조를 지우면 리드 원본을 다시는 못 봅니다. 참조도 아카이빙 필수.
- 참조 버전 불일치: hg19로 정렬한 뒤 hg38로 열려 하면 각 위치 서열이 안 맞아 오류. 참조 SHA1을 CRAM 헤더에 기록해두는 게 원 규격.
- 일부 옛 도구가 CRAM 미지원: 새 파이프라인은 대개 지원. 그래도 참조 소스가 명확한 곳에만 CRAM 저장 원칙.
실무 파이프라인 흐름 — 한 장으로
BWA-MEM에서 GATK 진입 전까지 samtools 사용 순서를 한 장에 정리합니다.
# 1) 정렬 + 좌표 정렬 (스트리밍)bwa-mem2 mem -t 16 -R "$RG" hg38.fa R1.fq.gz R2.fq.gz \ | samtools sort -@ 4 -o S1.bam -
# 2) 인덱스samtools index S1.bam
# 3) 파이프라인 대시보드samtools flagstat S1.bam > S1.flagstat.txtsamtools idxstats S1.bam > S1.idxstats.tsv
# 4) 아카이빙용 CRAM 변환samtools view -T hg38.fa -C -o S1.cram S1.bamsamtools index S1.cram
# 5) 파이프라인 진입: MarkDuplicates(S07) 는 sorted BAM으로 넘김30개 샘플이라도 이 다섯 단계가 뼈대입니다.
손 계산 — CRAM이 왜 그렇게 작아지나
인간 WGS 커버리지 30배 리드가 3억 개, 각 리드 150bp라 하면 BAM에 인코딩된 서열만 45GB입니다. 그런데 리드 하나당 참조와 다른 염기는 평균 몇 개일까요.
- 인간 개인 게놈의 다형성: 약 4,000,000 SNP (게놈 30억 bp의 0.13%).
- 리드 150bp에 SNP는 통계적으로 0.2개.
- 즉 리드 하나에 참조와 다른 위치가 1개 미만입니다.
CRAM은 이 "1개 미만"만 저장하므로 서열 정보량이 원래의 1% 미만으로 줄어듭니다. 나머지 90% 감소분은 헤더 인코딩과 품질 문자열 손실 압축(옵션)에서 옵니다. 저장 공간을 아끼면서도 리드를 다시 복원할 수 있다는 것이 CRAM 설계의 아름다움입니다.
Colab에서 손을 움직여봅시다
!apt-get install -y samtools >/dev/null!wget -q https://sra-pub-src-1.s3.amazonaws.com/SRR1039508/SRR1039508_1.fastq.gz -O r1.fq.gz# 미리 정렬된 소형 BAM으로 명령 감각 잡기!wget -q https://github.com/samtools/samtools/raw/master/examples/toy.bam!samtools view -h toy.bam | head!samtools flagstat toy.bam!samtools index toy.bam!samtools view toy.bam ref:100-500이 소형 예제 하나로 view · flagstat · index · 구간 쿼리까지 5분 안에 감을 잡을 수 있습니다.
자주 쓰는 원라이너 다섯 개
파이프라인 로그에서 자주 조회하는 명령들입니다.
# 특정 유전자 영역만 뽑아 새 BAM으로samtools view -h -b in.bam chr17:41196312-41277500 > BRCA1.bam
# unmapped 리드만 FASTQ로 뽑기 (오염·크로스 종 확인용)samtools view -b -f 4 in.bam | samtools fastq - > unmapped.fq
# duplicate 표시 리드만 세기samtools view -c -f 1024 in.bam
# 리드 그룹별 커버리지 (샘플별 요약)samtools view -H in.bam | grep '^@RG'
# 두 BAM 병합samtools merge -@ 4 merged.bam S1.bam S2.bam S3.bam이 다섯 개는 매주 씁니다.
CS 매핑
- 레퍼런스 기반 압축: 원본 대신 차이만 저장. DryBench의 "레퍼런스 기반 압축" 편(
reference-based-compression) 참고. - BGZF (Block Gzip Format): BAM은 gzip 블록을 잘라서 저장 → 임의 위치 접근 가능. 인덱스는 이 블록 오프셋을 담습니다.
- 스트리밍 CLI: samtools의
-(stdin/stdout)로 파이프 연결 → Unix 철학의 정수.
마무리
이 다섯 명령이면 BAM 세계의 95%가 조작 가능합니다. 다음 편(S06)에서는 GATK4 Best Practices의 큰 그림을 잡고, S07에서 MarkDuplicates로 지금까지의 sorted BAM을 이어받습니다. samtools는 GATK 파이프라인에서도 앞뒤로 계속 얼굴을 내밉니다.
더 깊게 파고 싶다면
- Danecek P. et al. (2021), Twelve years of SAMtools and BCFtools. GigaScience 10:giab008. samtools 12년 개발사와 설계 결정 총정리.
- Hsi-Yang Fritz M. et al. (2011), Efficient storage of high throughput DNA sequencing data using reference-based compression. Genome Research 21:734. CRAM의 원 논문.
- htslib 공식 문서 (https://www.htslib.org/): API·CLI 규격 원전.
- EMBL-EBI Training — Working with BAM files 무료 튜토리얼. 각 명령의 use case 예시가 풍부합니다.
- Broad Institute BroadE — Working with SAM files 유튜브. samtools view의 실제 리드 조사 사례.
BAM 하나 열어 flagstat과 view를 눌러본 사람만이 다음 GATK 편의 옵션에 자신감을 가집니다. Colab에서 5분만 손을 움직여봅시다.