# SAM/BAM 한 줄 읽기

> 정렬 결과인 SAM/BAM이 무엇을 기록하는지, 11개 필수 컬럼과 FLAG·CIGAR·optional tag를 실제 read 한 쌍으로 읽는다.

**SAM과 BAM은 시퀀서가 읽은 짧은 서열(read)의 정렬 결과를 저장하는 파일 형식**입니다. SAM은 사람이 읽을 수 있는 텍스트 형식이고, BAM은 같은 정보를 압축한 바이너리 형식입니다. 두 형식의 레코드 한 줄에는 read 하나가 게놈 어디에, 어떤 상태로 붙었는지가 기록됩니다.

발현량이 이상할 때 최종 숫자만 보지 않고 정렬 결과까지 거슬러 올라가려면 이 기록을 읽을 수 있어야 합니다.

> **이 레퍼런스의 질문**: SAM 한 줄의 위치·방향·정렬 상태를 어떻게 해석하는가?

## 1. 정렬 결과: SAM/BAM 포맷

정렬 도구(STAR 등)는 각 read가 게놈 어디에 어떻게 붙었는지를 계산한 뒤 SAM 또는 BAM으로 기록합니다. 포맷 전체의 개요는 [데이터 형식 레퍼런스](/reference/data-formats/)를 참고하세요.

paired-end read의 SAM 레코드를 이해하려면 **insert size**와 방향을 알아야 합니다. 한 fragment의 양 끝에서 나온 두 read는 정렬 후 보통 서로 마주 보는 방향으로 놓이고, 두 read가 덮는 전체 범위가 insert size입니다. 이 관계는 아래 FLAG와 TLEN에 기록됩니다.

SAM 파일은 **두 부분**으로 나뉩니다.

- **Header**(`@`로 시작): 정렬에 쓴 참조유전체 등 메타정보.
- **Alignment lines**: read 하나가 한 줄. **Tab으로 구분되는 11개 필수 컬럼** + 이후 추가 컬럼.

### 11개 필수 컬럼

| # | 컬럼 | 뜻 |
| --- | --- | --- |
| 1 | **QNAME** | read id (query 이름) |
| 2 | **FLAG** | 정렬 상태를 담은 비트값 (아래) |
| 3 | **RNAME** | 붙은 참조서열 이름 (예: chromosome) |
| 4 | **POS** | 붙은 시작 위치 (1-based, 가장 왼쪽) |
| 5 | **MAPQ** | 정렬 품질 (이 위치가 맞을 확신도) |
| 6 | **CIGAR** | 서열 수준 정렬 상태 문자열 (아래) |
| 7 | **RNEXT** | 짝(mate) read가 붙은 참조 이름 (`=`면 같은 곳) |
| 8 | **PNEXT** | 짝 read가 붙은 위치 |
| 9 | **TLEN** | insert size (양쪽 read POS로 추정한 fragment 길이) |
| 10 | **SEQ** | read 서열 (FASTQ에서 옴) |
| 11 | **QUAL** | read의 염기별 품질 (FASTQ에서 옴, Phred+33) |

10·11번(SEQ·QUAL)은 [FASTQ](/reference/data-formats/)에서 그대로 넘어온 값입니다. 즉 SAM은 **"FASTQ의 read 정보 + 그게 게놈 어디에 어떻게 붙었나"** 를 한 줄에 합친 것입니다.

### 실제 한 줄 읽어보기

paired-end read 한 쌍의 예시입니다(공백은 tab).

```text
A01055:...:7607   99    chr21   33426891   255   76M   =   33426961   145    CGGGCCTCC…   FFFF…   NH:i:1 HI:i:1 AS:i:149 nM:i:0 NM:i:0 RG:Z:boston
A01055:...:7607   147   chr21   33426961   255   75M   =   33426891   -145   GACATCGCT…   FFFF…   NH:i:1 HI:i:1 AS:i:149 nM:i:0 NM:i:0 RG:Z:tempus
```

- 같은 **QNAME**(같은 read id)인 두 줄 = 한 fragment의 양 끝(paired-end).
- 둘 다 `chr21`에 붙었고(RNEXT `=`), POS는 각각 33,426,891과 33,426,961.
- **TLEN**이 `+145` / `-145`: 이 fragment는 길이 **145 bp**이고, 부호로 어느 쪽이 왼쪽인지 표시.
- 앞 read FLAG=**99**, 짝 FLAG=**147** (아래에서 해석).

### FLAG: 정렬 상태를 담은 비트

FLAG는 **12가지 상태를 켜고 끈 비트값**을 하나의 정수로 합친 것입니다. 하나하나 외울 필요 없이, [Broad의 explain-flags 도구](https://broadinstitute.github.io/picard/explain-flags.html)에 숫자를 넣으면 풀어줍니다.

예시의 **99**를 풀면: `read paired`(0x1) + `proper pair`(0x2) + `mate reverse strand`(0x20) + `first in pair`(0x40). 짝인 **147**은 `read paired` + `proper pair` + `read reverse strand`(0x10) + `second in pair`(0x80).

> 🧩 **proper pair**(제대로 짝지어진 정렬)의 조건: ① 두 read가 **같은 chromosome**에, ② 하나는 forward·하나는 reverse로, ③ **insert size가 적절한 범위**여야 합니다. 위 예시는 chr21 · forward+reverse · 145 bp라 ✅.

특히 알아두면 좋은 FLAG 몇 가지:

- **PCR/optical duplicate**: 실험 증폭 과정에서 생긴 중복 read(시작·끝이 완전히 같음) 표시. 정량에서 보통 제외.
- **not primary alignment**(secondary): 한 read가 여러 곳에 붙을 때 **주 정렬(primary) 외의** 차순위 정렬.
- **supplementary alignment**: read가 **쪼개져** 여러 위치에 나뉘어 붙은 경우(예: splice, 구조변이).

### CIGAR: 서열 수준의 정렬 상태

CIGAR는 read가 참조와 **어떻게** 맞았는지를 문자열로 적습니다.

- `76M`: 76 길이만큼 정렬됨. 단 **M은 "자리를 맞췄다"일 뿐, 염기가 실제로 같은지는 보장하지 않습니다**(match든 mismatch든 M).
- `76=`: 76 길이만큼 정렬됐고 **모든 염기가 참조와 동일**(`=`).
- `40M1523N36M`: 중간에 **N**(참조 건너뛰기, 보통 intron)이 있으면 splice read. RNA-seq에서 흔합니다.
- 연산자: **M**(정렬), **I**(삽입), **D**(결실), **N**(intron 건너뛰기), **S**(soft clip, 안 맞아 접힌 끝), **=**(일치), **X**(불일치). 이 중 SEQ를 소비하는 연산자(**M/I/S/=/X**)의 길이 합 = SEQ 길이.

CIGAR 하나만 자세히 읽는 법(연산자 9개, splice·indel·clip, 참조 구간 길이 계산)은 [CIGAR 스트링 레퍼런스](/reference/cigar/)에 따로 정리했습니다.

### 추가 컬럼 (optional fields)

12번째부터는 `TAG:Type:Value` 형태로 **무한히** 붙습니다. Type은 데이터 형(`i`=정수, `Z`=문자열 등). 자주 보는 것:

| 태그 | 뜻 |
| --- | --- |
| **NM** | 참조와 다른 글자 수 (mismatch + indel) |
| **AS** | alignment score (정렬 점수) |
| **NH** | number of hits (이 read가 붙은 곳 개수) |
| **HI** | hit index (중복 자리 중 순위) |
| **nM** | mismatch 개수 (STAR가 붙이는 값) |
| **SA** | supplementary alignment 정보 (쪼개진 정렬이 있을 때) |
| **RG** | read group (예시의 `boston`·`tempus`처럼 샘플/배치 표시) |

> 💡 **왜 SAM을 읽을 줄 알아야 하나**: 발현량이 이상하게 나오거나 특정 유전자만 튈 때, "이 read들이 **제대로**(proper pair, 낮은 mismatch, primary) 붙은 건가"를 SAM에서 직접 확인해야 합니다. `samtools view`로 특정 위치의 정렬을 열어 FLAG·CIGAR·NM을 보는 것이 디버깅의 기본입니다.


## 정리

SAM은 FASTQ의 read 정보에 게놈 위치와 정렬 상태를 붙인 기록입니다. 처음에는 모든 FLAG 값을 외우기보다 다음 세 가지를 확인하면 됩니다.

1. read와 mate가 기대한 위치와 방향에 붙었는가?
2. CIGAR가 일치·삽입·결실·클리핑을 어떻게 기록했는가?
3. NM·NH 같은 tag가 mismatch와 multi-mapping을 무엇이라고 말하는가?

개념 흐름은 [splice를 고려해 read 위치 찾기](/lessons/rna-seq-alignment/)에서 이어집니다.