앞의 글에서 실습 과정동안 인덱스 생성 및 정렬을 하며 생성한 SRR062634.sam 파일을 사용하여 SAM 파일의 구조를 확인해보고자 함.
일반적인 SAM 파일 구조
1. 헤더 (@로 시작)
| 태그 | 의미 |
| @HD | SAM 파일 버전 정보 |
| @SQ | Reference 서열 정보 (이름, 길이) |
| @RG | Read group 정보 (샘플, 장비 등) |
| @PG | 사용한 프로그램 정보 |
2. 정렬 레코드 (11개 필수 필드, 탭 구분)
| 번호 | 필드명 | 의미 |
| 1 | QNAME | Read 이름 |
| 2 | FLAG | 정렬 상태 (비트 플래그) |
| 3 | RNAME | 정렬된 reference 이름 |
| 4 | POS | 정렬 시작 위치 |
| 5 | MAPQ | 매핑 품질 |
| 6 | CIGAR | 정렬 방식 |
| 7 | RNEXT | mate read reference |
| 8 | PNEXT | mate read 위치 |
| 9 | TLEN | insert size |
| 10 | SEQ | 염기서열 |
| 11 | QUAL | Quality score |
내 컴퓨터의 SAM 파일 열기
head -20 ~/bioinfo/bi_study/wgs_practice/aligned/SRR062634.sam
# 출력 결과
@SQ SN:chr20 LN:64444167
@PG ID:bwa-mem2 PN:bwa-mem2 VN:2.2.1 CL:bwa-mem2 mem -t 4 /Users/kofe/bioinfo/bi_study/wgs_practice/ref/chr20.fa /Users/kofe/bioinfo/bi_study/wgs_practice/trimmed/SRR062634_1_paired.fastq /Users/kofe/bioinfo/bi_study/wgs_practice/trimmed/SRR062634_2_paired.fastq
SRR062634.1 77 * 0 0 * * 0 0 GGGTTTTCCTGAAAAAGGGATTCAAGAAAGAAAACTTACATGAGGTGATTGT @C'@9:BB:?DCCB5CC?5C=?5@CADC?BDB)B@?-A@=:=:@CC'C>5AA AS:i:0 XS:i:0
SRR062634.1 141 * 0 0 * * 0 0 CAGAAGAATGTAAACTCCAGGGGGACAGGAGTGCGTG A>--?=C;C:=C=CC=D5D?C-:CAC:-5=;>?'6>@ AS:i:0 XS:i:0
SRR062634.2 69 chr20 2284335 0 * = 2284335 0 ACCGTGAGCAATCAGCTGCCATCAACGTGGAGGTAAGACTCTCCACCTGCAAAAACATTACAACTTGCTGAAGGCTGAGATA FDEFF?DFEFE?BEEEEED=DB:DCEAEEB,CC=@B=5?B?CC5C?B+A??=>:CC<9-B2=@>-?:-<A@@A?9>*0<:'0 MC:Z:7S67M26S AS:i:0 XS:i:0
SRR062634.2 137 chr20 2284335 12 7S67M26S = 2284335 0 CTGTCTCATAAAATAAAATAAAATAAAATAAATAAAATAAAATAAAATAAAATAAAATAAAATAAAATAAAATACCTTATTGCTAAAAAGGTGCTAACAA DEEDAEEEEE:EB>E<>CCEEEBEEE<EDEAEE;EC<CEACAE;A>EEE@EE@E8>CEDA?C8DA68>D3B:@EE=-AAC-CA5CDBDBE?:C@?BC?,? NM:i:0 MD:Z:67 AS:i:67 XS:i:62 XA:Z:chr20,+9852728,7S22M1D47M24S,1;chr20,+44349131,13S59M28S,0;chr20,+19923416,19S55M26S,0;chr20,-35946652,38S55M7S,0;
SRR062634.3 77 * 0 0 * * 0 0 TAGATATTTTTGTTTTAACTGCTGTAGAAAATTAAGACATAAACTAAGAAATATCCCATGAAGGAATGAGTATACTGT -?3-C22646@-@3@@3-=-====CBB@DB-A-=-AA@C-<AA7>D=ABDA;?CDDDD5D?DD55:>:AB>5?-CCCC AS:i:0 XS:i:0
SRR062634.3 141 * 0 0 * * 0 0 TCAGGTGAATAAATTGAGAACAAATCTTGGAATCATGGAGAATGGATAGTCCAGAAAGAAAGA :B5DDBDD:5DD6;:D:D5DBD6?ADD-DD=B5DAB=5@A5AC5A--=::-C:5>5A2+C-)9 AS:i:0 XS:i:0
SRR062634.4 77 * 0 0 * * 0 0 AGATGAGTTTCACAAAGTAAGCAACTTGATATCCAAATAATCAACACCCAACTCAAGAAAAAGATCATTACCAGAAACTAATAAACCAGCACA ??EEEDB?D-?AAA-AA?>->BC:ADB:--A55ACCA:D6C:?5@CADD6=C5:CD?D4;,::?,CC-5A@C-?D5@+-BB?BC*A-A?C:C@ AS:i:0 XS:i:0
SRR062634.4 141 * 0 0 * * 0 0 ATCATTCCACAGGGTGGATCCTGCTTCTTAGAAAGATAAGGTATGCTATAAGGAGTCTCATTTCTCGATATTATAAGATTACGAGTACTAATACA DD:??DD:5DA-5A5=6+?CC5=C-A<CA*.@<@@(5B=@D:B:D=-5AA:=:=,5A:B??::-4(9;<;:>'B5BD:BB5:C:@5:->?B5C:? AS:i:0 XS:i:0
SRR062634.5 77 * 0 0 * * 0 0 CTGTATCTAGGTTTTGTCCTTACATGTATATAACCTACACCCAC CC?-?BAAB?E:B@@A7A?5CCBBBB@B?ABB?B@BB=B-BB=AS:i:0 XS:i:0
SRR062634.5 141 * 0 0 * * 0 0 GGCAAGAACTGGGAAGGAACAAATTCAAGTGGGCTTTTAGCATAGTAAGAGAACACTGTCCTTCAGTCTGATCATTTCAGGGAGG B?D:C=5DDDDDDBBCC:DCCC3=DB55DDBBDBCD:A?D=-@==-8.@74):266;=<<:BAB,??B@@->==-??B5==>'@@ AS:i:0 XS:i:0
SRR062634.6 77 * 0 0 * * 0 0 TTAGGTTTTAATGTTTGGGAAACTAAATCTCTCCTCTATCCAAGTGTACATGCTTTCGTTTTATCCCTTTGTCTC C??=-C=ACCD?BD56DDD?DD5CD.=*;BC5-C:ACA??D=-A?C@:??5AC:==CC=C:A?>4:186?58C5C AS:i:0 XS:i:0
SRR062634.6 141 * 0 0 * * 0 0 ATCAGAGGTTTACAAACTCTAAGTCACAAAATCAGCTCACAGGCCACTATAAAATAGTCA :-D5=C=C=::AA>ABDD?=A-A?BC?55CDA?=?5BB?@-@C5CB=?B?:BC=AB?4AA AS:i:0 XS:i:0
SRR062634.7 99 chr20 30524085 15 3S57M1S = 30524220 171 GATGTGCAGGTTTGTTACACAGGTAAATGTGTGCCATGGTGGTTTGCTGCACCTATCAACC C?C6/AABAAFFDE=?>D@DA>5<?AC?C-C?BDBC-CA=C?A:AB@A5D??B?C5E?BBB NM:i:4 MD:Z:6A9T7C26G5 MC:Z:7M2D27M16S AS:i:37 XS:i:51
SRR062634.7 147 chr20 30524220 15 7M2D27M16S = 30524085 -171 AGGCCCCTGTATGTTGTTCCCCTTCCTGTGTCCACCATGTTTTTTTTTAA A5=::?=5?EE5;EEDD-:AF=5:FDDD:D6EADDEB@B>=86C5-C?AA NM:i:3 MD:Z:7^AA3G23 MC:Z:3S57M1S AS:i:23 XS:i:23 XA:Z:chr20,+54021690,16S27M2D7M,3;chr20,-24211133,14S21M15S,0;chr20,-56066716,14S21M15S,0;chr20,+25883553,15S21M14S,0;
SRR062634.8 77 * 0 0 * * 0 0 TATAATTTACGAAAATTCTTTAATGCTGAAAAAAAGATGAAAATTCATTAATCTGAATGTCAATTCGGTCTTGTTCCAAACAGTTTTTTTTTGTTTGT DCA5DCD5:DB-DD=C5AC-;AAA5C@@->AAA;)=(;A>-C:CCCB:B=:>A;A+==?;,@>@,BDCBDB5=B:@-5@'=@A>-C,A06;<>8<+3B AS:i:0 XS:i:0
SRR062634.8 141 * 0 0 * * 0 0 TTGAGAGAATAAACTTGCCTTTAGCCTCCTTTAATTTTTACCTTTTATCTTTGGCTGAGG ?BADDDDD5BDDD>DD:-DD:DB=C.@4>0>-;>>DDDDDCB-A:;44=@:CC?-;;>6@ AS:i:0 XS:i:0
SRR062634.9 77 * 0 0 * * 0 0 GTGAAAGCTTAATGATACCATATGTGCTAAATTGTAAATTAATCTATCTCACCCGTTTCAGGAATTTCT =FDFEDEDBCD@?BCCDECA6,;@<DAB=5@5?D?:5?DCBB5?:E:CEC?EE=4A>:=>C-A?A==CC AS:i:0 XS:i:0
SRR062634.9 141 * 0 0 * * 0 0 TCCTTTCCCTCAATTATATTAGTCAGGATTTATTCTTGGACCTATTAATACTGAAAAGACATTCCTGAAACGGGTGAGATAGATTAATTTACAATTTAGC EED-EC55ACC=:-DD:==?DD:D5?>@-?5?C;CBEED-CC=C-@@;.B==D?::-AA-4;C@=E5E??D7:D:DC?A5->-<ACB?=BBB-BB<--AC AS:i:0 XS:i:0
내 SAM 파일 헤더 섹션 (@로 시작하는 줄)
@SQ SN:chr20 LN:64444167
@PG ID:bwa-mem2 ~
- @SQ — reference 서열 정보. chr20 길이가 64,444,167bp 라고 하는 것.
- @PG — 어떤 툴로 만들었는지. bwa-mem2 명령어까지 기록됨.
정렬 레코드 (나머지 줄들)
한 줄이 read 하나.
탭으로 구분된 필드들인데,
밑이 실제로 chr20에 정렬된 read:
SRR062634.7 99 chr20 30524085 15 3S57M1S = 30524220 171 GATGTGCAG...
내 컴퓨터의 SAM 파일 구조 분석
SRR062634.7 99 chr20 30524085 15 3S57M1S = 30524220 171 GATGTGCAG... C?C6/AAB...
20번 염색체로 정렬된 SRR062634.7 read 를 두고 구조를 확인하려고 함.
| 필드 | 현재 필드값 | 의미 |
| QNAME | SRR062634.7 | read 이름(SRR062634번 read 그룹의 7번째 DNA 조각) |
| FLAG | 99 | 정렬 상태(밑에서 자세히 설명) |
| RNAME | chr20 | chr20에 정렬됨 |
| POS | 30524085 | chr20의 30,524,085번째 위치부터 시작 |
| MAPQ | 15 | 매핑 신뢰도 (0~60, 높을수록 좋음) |
| CIGAR | 3S57M1S | 정렬 방식 (밑에서 설명) |
| RNEXT | = | mate(짝)도 같은 chr20에 있음 |
| PNEXT | 30524220 | mate의 시작 위치 |
| TLEN | 171 | 이 read 쌍의 전체 DNA 조각 길이 |
| SEQ | GATGTGCAG... | 정렬된 염기서열 |
| QUAL | C?C6/AAB... | 염기별 품질 |
여기서 FLAG 99가 핵심.
FLAG 필드의 의미
FLAG는 2진수로 변환해서 각 자리가 다른 의미를 가짐.
99를 2진수로 바꾸면
99 = 64 + 32 + 2 + 1 = 1100011
| 비트값 | 의미 | 99에 해당히기 위한 비트값 여부 |
| 1 | read가 paired-end | ✅ |
| 2 | 정확하게 매핑된 쌍 (proper pair) | ✅ |
| 4 | read 자체가 매핑 안 됨 | ❌ |
| 8 | mate가 매핑 안 됨 | ❌ |
| 16 | read가 역방향(REVERSE) | ❌ |
| 32 | mate가 역방향(MREVERSE) | ✅ |
| 64 | 이 read가 쌍 중 첫 번째(_1) | ✅ |
| 128 | 이 read가 쌍 중 두 번째(_2) | ❌ |
즉 FLAG 99는 "paired-end고, 정확히 매핑됐고, 이 read는 정방향(forward)이고, 짝(mate)은 역방향이고, 이 read가 _1(첫 번째)이다" 라는 뜻.
FLAG 비트값은 매번 손으로 계산 안 해도 되고, samtools flags 명령어로 바로 해석할 수 있음.
samtools flags 99
# 출력
# 0x63 99 PAIRED,PROPER_PAIR,MREVERSE,READ1
여기서
PAIRED : paired-end read
PROPER_PAIR : 정확하게 매핑된 쌍
MREVERSE : mate(짝)가 역방향
READ1 : 이 read가 _1
CIGAR 필드의 의미
CIGAR는 read가 reference에 어떻게 매칭됐는지 패턴으로 보여줌.
3S57M1S
이걸 쪼개면 3S + 57M + 1S.
| 코드 | 의미 |
| M | Match/Mismatch — reference랑 매칭됨 (일치하든 불일치하든) |
| S | Soft clip — 정렬 안 되고 잘려나간 부분 |
| I | Insertion — read에는 있는데 reference엔 없는 염기 |
| D | Deletion — reference엔 있는데 read에는 없는 염기 |
3S57M1S 해석하면:
앞쪽 3bp → 정렬 안 됨 (soft clip)
중간 57bp → reference랑 매칭됨
뒤쪽 1bp → 정렬 안 됨 (soft clip)
총 61bp(3+57+1) read 중에 57bp만 실제로 chr20에 붙었다는 뜻.
앞뒤 끝부분은 매칭이 안 돼서 잘려나감.
read 길이가 100bp가 아니라 61bp인 것은 Trimming 때문이다.
SRR062634.7의 짝(mate) read 구조 분석
위에서 확인했으니 반대의 read도 해석.
SRR062634.7 147 chr20 30524220 15 7M2D27M16S ...
samtools flags 147 명령어를 통해 PAIRED,PROPER_PAIR,REVERSE,READ2 출력값을 받음.
해석하면 "paired-end고, 정확히 매핑됐고, 이 read는 역방향이고, 짝(mate)은 정방향이고, 이 read가 _2(두 번째)이다".
CIGAR는 7M2D27M16S인데, D(Deletion)가 새로 등장함.
read에는 없는데 reference에는 있는 염기 2개가 있다는 뜻.
즉 이 위치에 indel(결실)이 있을 가능성을 보여주며, 나중에 GATK가 이런 정보들을 모아서 변이를 호출함.
RNAME이 * 인 경우
SRR062634.1 77 * 0 0 * * 0 0 GGGTTTTCCTGAAA...
SRR062634.3 77 * 0 0 * * 0 0 TAGATATTTTTGTT...
위에서 볼 수 있듯이 SAM 파일에서 3번째 필드(RNAME)가 *로 되어있는 것을 확인 가능.
일부 read들은 chr20이라고 적혀있는데 다른 read는 * 인 이유를 알아보기 위해 FLAG 77을 확인해보면
samtools flags 77
# 0x4d 77 PAIRED,UNMAP,MUNMAP,READ1
PAIRED,UNMAP,MUNMAP,READ1 라는 출력을 확인할 수 있고, 여기서 UNMAP이 핵심.
이 read들은 chr20 어디에도 정렬이 안 됐다는 뜻.
그래서 RNAME, POS 같은 위치 정보가 다 *나 0으로 비어있는 것.
MUNMAP은 짝(mate)도 같이 정렬 안 됐다는 뜻.
즉 이 read 쌍 전체가 chr20에 못 붙은 것.
이런 경우가 발생하는 이유는, chr20 subset만 reference로 썼기 때문.
그런데 실제 DNA 조각은 다른 염색체에서 왔을 수도 있고, repeat 영역이라 매칭이 너무 애매하거나, 품질이 낮아서 정렬 실패했을 수도 있음.
지금은 100만 read를 전체 게놈이 아니라 chr20에만 정렬했으니까 이런 매핑 실패 read가 많이 나오는 게 정상.
SAM 파일 전체 정렬 통계
samtools flagstat ~/bioinfo/bi_study/wgs_practice/aligned/SRR062634.bam

전체 정렬 통계 출력값을 확인해보면,
1940268 + 0 primary
총 read 수. trimmed 후 970,134쌍 × 2 = 1,940,268개.
570849 + 0 mapped (29.17% : N/A)
chr20에 매핑된 read는 29.17%.
나머지 70%는 매핑 안 됨.
매핑된 read 비율이 낮은 이유는 reference로 chr20만 썼기 때문.
그런데 100만 read는 전체 게놈(WGS) 중 일부니까, 실제로는 chr1, chr2... 다른 염색체에서 나온 read들도 섞여있는 것.
chr20에만 정렬을 시도했으니 chr20 출신 read만 붙고 나머지는 다 매핑 실패로 떨어지기 때문에 비율이 낮음.
318870 + 0 properly paired (16.43% : N/A)
양쪽 read가 둘 다 정확하게 매핑된 비율.
이것도 위와 같은 이유로 낮음.
정리하면, 매핑률 29%는 데이터 품질 문제가 아니라 reference를 chr20만 써서 생기는 당연한 결과.
실제로 chr20 전체 게놈(hg38) 기준으로 정렬했다면 매핑률이 95% 이상 나왔을 것이라고 예상.
추가) mapped 비율 직접 검증
flagstat 안 쓰고 SAM에서 직접 세어볼 수 있음.
samtools view ~/bioinfo/bi_study/wgs_practice/aligned/SRR062634.bam | awk '$3 != "*"' | wc -l
#출력
# 638540
이 결과는 위의 flagstat에서 본 570,849 mapped랑 숫자가 다른데 이유는 직접 검증하는 코드가 secondary(0개)랑 supplementary(16,944개)까지 포함해서 세어서임.
570,849 (primary mapped) + 16,944 (supplementary) + 일부 secondary 처리 차이 = 638,540
MAPQ 분포 확인
samtools view ~/bioinfo/bi_study/wgs_practice/aligned/SRR062634.bam | awk '{print $5}' | sort -n | uniq -c
출력값
1589483 0
14031 1
9831 2
13388 3
11304 4
10343 5
13589 6
11741 7
7734 8
10205 9
7418 10
6230 11
8748 12
7228 13
4144 14
7605 15
5791 16
5734 17
8624 18
7791 19
5096 20
7262 21
5772 22
4465 23
7251 24
6053 25
2328 26
6181 27
2530 28
2473 29
5036 30
3386 31
1451 32
4073 33
1953 34
1940 35
4109 36
2890 37
849 38
3417 39
33856 40
1543 41
2154 42
1933 43
1729 44
2304 45
1682 46
1524 47
2355 48
1661 49
1084 50
1141 51
806 52
642 53
1572 54
1003 55
711 56
975 57
751 58
991 59
57318 60
MAPQ 0이 158만 개나 되는 게 핵심.
이건 바로 매핑 안 된 read들(* 표시된 것들)이 전부 MAPQ 0으로 기록되기 때문.
그래서 chr20 못 붙은 read들이 여기 다 몰려있음.
반대로 MAPQ 60(최고 품질)이 57,318개, MAPQ 40도 33,856개로 꽤 많음.
이건 chr20에 확실하게, 다른 위치랑 헷갈리지 않고 정확히 붙은 read들임.
'Bio Data Analysis > WGS(Whole Genome Seq)' 카테고리의 다른 글
| [WGS 분석] 변이 호출 (GATK HaplotypeCaller: Variant Calling) (0) | 2026.07.01 |
|---|---|
| [WGS 분석] BAM 파일 구조 이해하기 (0) | 2026.07.01 |
| [WGS 분석] 인덱스 생성 및 정렬 (SAM/BAM) (0) | 2026.06.30 |
| [WGS 분석] QC & Trimming (0) | 2026.06.30 |
| WGS 분석 실습을 위한 FASTQ 파일 구조 이해하기 (0) | 2026.06.29 |
