# 트리밍: 어댑터와 저품질 구간 제거

> QC 진단에 따라 read에서 정렬을 방해하는 부분(어댑터·저품질 끝·polyX/N)을 잘라내는 단계. fastp 소프트웨어 소개·기술 스택, 왜 필요한지, 실제 before/after 결과와 대안 도구.

**트리밍**은 FASTQ에 저장된 read에서 어댑터와 품질이 낮은 부분을 잘라 내는 **전처리 단계**입니다. **fastp**는 이 작업에 사용하는 명령줄 소프트웨어입니다. [QC(FastQC)](/reference/fastqc/)가 문제를 진단한다면, 트리밍은 그 진단에 따라 실제 read를 바꿉니다.

파이프라인에서의 위치:

```text
FASTQ → QC(FastQC) → [② 트리밍(fastp)] → 정렬 → 정량(TPM) → 비교
```

FastQC와 달리 **데이터가 바뀌고 새 FASTQ가 생깁니다.**

## fastp 소프트웨어 소개

**fastp**는 FASTQ를 **한 번에 QC·트리밍·필터링**하는, 요즘 가장 널리 쓰이는 전처리 도구입니다. "ultra-fast all-in-one FASTQ preprocessor"를 표방합니다.

| 항목 | 내용 |
| --- | --- |
| 개발 | **OpenGene** 프로젝트, 주 저자 Shifu Chen |
| 라이선스 | **MIT**: 오픈소스, 자유 사용·수정·재배포 |
| 언어 | **C/C++** (네이티브 컴파일 → 빠름) |
| 실행 방식 | **CLI**(명령줄). GUI 없음 |
| 입력 | FASTQ(gz 포함), single/paired-end |
| 소스 | [github.com/OpenGene/fastp](https://github.com/OpenGene/fastp) |
| 논문 | Shifu Chen, *iMeta* (2025): "fastp 1.0: an ultra-fast all-round tool…" |

### 오픈소스 운영·저장소

- **저장소**: [github.com/OpenGene/fastp](https://github.com/OpenGene/fastp): **MIT** 라이선스. Bioconda·리눅스 배포판으로 널리 배포됩니다.
- **운영 형태**: 주 저자(Shifu Chen) 중심에 **39명 기여자**가 참여하는 **활발한** 프로젝트. 릴리스 58회, 최신 **v1.3.6 (2026-06)**. 이슈·PR도 많아, FastQC보다 **개발이 훨씬 왕성**합니다.
- FastQC가 "학술 코어 시설의 단일 메인테이너 도구"라면, fastp는 **커뮤니티 기여가 활발한 현역 프로젝트**에 가깝습니다.

### 기술 스택

| 구성 | 내용 |
| --- | --- |
| 주 언어 | **C++ 91.4%** (핵심 로직). 스크립트 Python 5.8%·Shell 1.8% |
| 빌드 | **Make / CMake** |
| 핵심 라이브러리 | **libisal**·**libdeflate**(초고속 gzip 압축/해제), **libhwy**(Google Highway: SIMD 가속) |
| 병렬 | **멀티스레드**(기본 3, `-w`로 조정) |

- C++ 네이티브 + SIMD·고속 압축 라이브러리 덕에 **매우 빠릅니다.** FastQC(Java)와 달리 처리와 QC를 한 번에 하면서도 속도가 납니다.

### 어떻게 동작하나

- FASTQ를 **한 번 스트리밍으로 읽으며** 품질 프로파일링(QC) + 어댑터·품질 트리밍 + 필터링을 **동시에** 수행합니다.
- FastQC(진단만)와 달리 fastp는 **진단 + 실제 수정**을 함께 합니다 → **정리된 새 FASTQ**를 내놓습니다.
- paired-end이면 두 read의 겹침(overlap)을 분석해 **어댑터를 자동 감지**하고(서열 몰라도 됨), 한쪽 mate 탈락 시 짝도 같이 처리해 **짝을 동기화**합니다.

### 산출물

- **정리된 FASTQ**(`out_R1.fastq.gz`, `out_R2.fastq.gz`): 다음 단계 정렬 입력.
- **HTML 리포트**: before/after 품질 곡선·어댑터·필터 통계를 인터랙티브 그래프로.
- **JSON 리포트**: 기계가 읽는 통계(자동화·MultiQC 취합용).

## 왜 필요한가: 정렬을 방해하는 것들 제거

정렬은 read를 게놈에 맞춰봅니다. read 안에 **게놈에 없는 서열**이나 **못 믿을 염기**가 섞여 있으면 잘못 붙거나 아예 안 붙습니다. 크게 세 가지를 정리합니다.

### ① 어댑터(adapter): 게놈에 없는 인공 서열

라이브러리를 만들 때 DNA 조각 양 끝에 **어댑터**(시퀀서가 잡는 손잡이)를 붙입니다. 원래는 어댑터 다음부터 읽지만, **조각(fragment)이 read 길이보다 짧으면** 조각을 다 읽고 **반대편 어댑터까지 넘어가서 읽어버립니다**(read-through). 아래 슬라이더로 fragment를 짧게 만들어 직접 확인해 보세요.



이 어댑터 조각은 게놈에 없으니 정렬을 방해 → **잘라내야 합니다.** fragment가 짧을수록 어댑터가 많이 섞입니다.

### ② 저품질 염기: 주로 read 끝

시퀀싱은 사이클이 진행될수록(끝으로 갈수록) 신호가 약해져 품질이 떨어지는 경향이 있습니다. 품질 낮은 염기는 틀렸을 가능성이 커서(→ 오정렬), 기준 이하로 떨어지는 끝부분을 잘라냅니다.

### ③ 기타 인공물: polyX, N, 너무 짧아진 read

아래에서 종류별로 자세히. 자르고 나서 **너무 짧아진 read**는 정렬에 도움이 안 되니 통째로 버립니다.

## polyX · polyG · N 자세히

세 인공물은 **생기는 원인이 서로 달라서**, 알아두면 QC 결과를 정확히 해석할 수 있습니다.

### polyA / polyT: 생물학에서 온 것

- mRNA는 3' 끝에 **polyA 꼬리**(AAAA…)가 달려 있습니다(mRNA의 표식). read가 이 꼬리를 읽으면 `AAAA…`, 반대 가닥을 읽으면 상보서열 `TTTT…`(polyT)로 나옵니다.
- 즉 polyA/T는 **오류가 아니라 진짜 mRNA에서 유래**한 서열입니다. 게놈 정렬엔 방해가 되니 끝에 붙은 꼬리는 잘라냅니다.

### polyG: 장비(2-color)의 가짜 신호

- 일부 Illumina 장비(**NextSeq · NovaSeq · iSeq**)는 **2가지 형광(2-color)** 조합으로 4염기를 구분하는데, 이 방식에서 **"신호 없음" = G** 로 해석합니다.
- 그래서 클러스터가 fragment 끝을 지나 더 읽을 게 없어지면(신호 소멸), 장비가 그걸 **G로 착각**해 read 끝에 가짜 `GGGG…`를 만듭니다: **실제 서열이 아닌 인공물**.
- 반면 **4-color 장비(HiSeq 2000/2500, MiSeq)** 는 염기마다 고유 형광이라 polyG 문제가 없습니다. fastp는 장비를 감지해 자동 처리하거나 `--trim_poly_g`로 명시합니다.

### N: 판독 실패(ambiguous base)

- 시퀀서가 그 자리 염기를 A/T/G/C 중 무엇인지 **결정 못 했을 때** 넣는 문자. 품질 점수도 최저로 붙습니다.
- N이 드문드문이면 무해하지만, 한 read에 너무 많으면 믿을 수 없어 통째로 버립니다.

> `polyX`의 **X는 "아무 염기나"** 라는 뜻: polyA·T·G·C를 통틀어 부릅니다. fastp의 `--trim_poly_x`는 read 끝의 이런 단일염기 반복을 종류 안 가리고 잘라줍니다.

## fastp 사용법

```bash
fastp \
  -i R1.fastq.gz -I R2.fastq.gz \          # 입력(두 파일 같이 = 짝 유지)
  -o out_R1.fastq.gz -O out_R2.fastq.gz \  # 출력
  --trim_poly_x \                          # polyA/T 꼬리 정리
  --html report.html --json report.json    # before/after 리포트
```

- 어댑터 자동 감지가 기본이라 대개 추가 옵션 없이도 잘 됩니다.
- 자주 쓰는 옵션: `-q`(품질 기준), `-l`(최소 길이), `--trim_poly_g`(2-color polyG), `-w`(스레드).

## 사례: 공개 샘플 하나의 결과

공개 human RNA-seq run `DRR024878`에 fastp(v1.3.6)를 실행하기 전과 후를 비교했습니다.

| 지표 | Before | After | 해석 |
| --- | --- | --- | --- |
| read 수 | 4,469,592 | 4,186,118 | ~93.7% 유지 (6.3% 제거) |
| Q30 비율 | 89.9% | **92.9%** | 나쁜 부분 제거 → 평균 품질↑ |
| 평균 길이 | 100 bp | 97 bp | 잘린 만큼 약간 짧아짐 |
| 짝(pair) | | 각 2,093,059 | **양쪽 동일 → 짝 유지** |

제거 내역: 어댑터 383,422 read(8.2M 염기), polyX 91,389 read, 저품질 265,342 read, 너무 짧음 17,288 read.

→ 데이터가 원래 좋아서 **가볍게** 정리됐습니다. "Q30↑ · 길이 약간↓"가 전형적인 트리밍 트레이드오프입니다.

### 트리밍이 됐는지 확인: FastQC 재실행

트리밍 후 **다시 FastQC**를 돌려 어댑터가 실제로 빠졌는지, 품질이 유지됐는지 확인합니다. 같은 샘플에서 **Adapter Content가 WARN → PASS**로 바뀌는 실제 before/after 그래프는 [FastQC 레퍼런스의 재검증 섹션](/reference/fastqc/#트리밍-후-다시--beforeafter-검증)에 있습니다.

## ⚠️ 주의: 과하게 자르지 말 것

- 품질 기준을 너무 빡세게 잡으면 **멀쩡한 read까지 버려** 발현량 정량이 왜곡될 수 있습니다. 데이터가 좋으면 가볍게.
- 요즘 정렬 도구(STAR·HISAT2)는 **soft-clipping**으로 안 맞는 끝부분을 알아서 무시하기도 해서, 과한 품질 트리밍의 효용이 예전보다 줄었습니다. **어댑터 제거는 여전히 확실히** 하는 게 좋습니다.

## 대안·보완 도구

| 도구 | 특징 |
| --- | --- |
| **Trim Galore** | cutadapt + FastQC를 감싼 래퍼(Perl). 어댑터 자동감지, RNA/bisulfite 등 프리셋. 오래 검증돼 널리 쓰임. |
| **Trimmomatic** | Java. `ILLUMINACLIP`·`SLIDINGWINDOW` 등 **단계를 세밀하게** 지정. 어댑터 파일을 직접 줘야 하지만 제어가 정밀. 레거시 파이프라인에 흔함. |
| **cutadapt** | Python. 어댑터 제거의 **핵심 엔진**(많은 래퍼가 내부적으로 사용). 어댑터 패턴 제어가 정밀. |
| **BBDuk** (BBTools) | Java. k-mer 기반으로 어댑터·오염·품질을 한 번에. 매우 다재다능. |
| **AfterQC** | fastp의 전신(같은 저자). |

### 어떻게 고르나

- **빠르게 QC와 트리밍을 함께** 처리하려면 → **fastp**.
- **단계별 정밀 제어**가 필요하면 → **Trimmomatic**.
- **어댑터 패턴을 직접** 다루려면 → **cutadapt**.
- **다목적**(오염 제거 등)까지 → **BBDuk**.

> 한 줄 요약: **트리밍 = 정렬을 방해하는 어댑터·저품질 끝·인공물을 잘라내 깨끗한 FASTQ를 만드는 단계.** fastp는 QC·트리밍·필터를 한 번에 하는 빠른 C++ 도구이며, 자른 뒤 FastQC로 다시 확인합니다.