단일세포 RNA-seq(scRNA-seq)는 세포 내 단백질 수준을 간접적으로 추정할 수 있으나, mRNA 발현과 단백질 발현 간의 상관관계는 제한적입니다. 따라서 세포 정체성과 기능을 보다 정확히 이해하기 위해서는 **표면 단백질(surface protein)**을 직접 측정하는 것이 중요합니다.
이를 위해 개발된 대표적인 기술이 다음과 같습니다:
- **CITE-seq (Cellular Indexing of Transcriptomes and Epitopes by Sequencing)**
- **REAP-seq (RNA Expression And Protein sequencing assay)**
이 기법들은 항체에 DNA 바코드(Antibody-Derived Tags; ADT)를 부착해 단백질을 정량화합니다.
### ADT 데이터가 중요한 이유
1. 전사 수준(mRNA)뿐 아니라 **단백질 수준의 세포 정체성 확보**
2. 세포 분화, 신호 전달, 질병 진행 이해
3. doublet(두 개 이상의 세포가 하나로 잡힌 경우) 탐지 가능
4. RNA에는 변화가 없지만 단백질만 변화하는 경우 탐지 가능
→ 예: ICOS는 단백질 수준에서만 증가, RNA는 변화 없음 (Peterson et al.)
---
## 1. CITE-seq 개요
### CITE-seq vs REAP-seq
|항목|CITE-seq|REAP-seq|
|---|---|---|
|항체-올리고 결합|Streptavidin-비오틴 비공유결합|공유결합|
|안정성|상대적으로 낮음|더 강함|
### 확장된 멀티모달 기법
- **DOGMA-seq**: RNA + ADT + ATAC 동시 측정
- **ASAP-seq**: scATAC-seq + ADT 통합 (세포 표면 + 내부 단백질 가능)
본 튜토리얼은 **ADT 데이터 단독 분석(unimodal)**에 초점을 둡니다.
---
## 3. 데이터 구성 및 환경 설정
### 데이터 출처
NeurIPS 2021 Single-cell integration challenge 데이터:
- 12명 건강한 기증자
- 4개 사이트에서 측정 → nested batch effects 존재
- 구성:
- RNA modality
- ADT modality (136 surface protein + 4 isotype control)
---
### 사용 라이브러리
`import mudata as md import muon as mu import scanpy as sc import seaborn as sns import numpy as np import pandas as pd from scipy.stats import median_abs_deviation`
---
## 4. MuData 객체 구성
Cell Ranger는 두 가지 출력을 제공합니다:
- **raw output**: 모든 droplet
- **filtered output**: 세포로 판별된 droplet
이를 RNA와 ADT modality로 분리하여 MuData 객체로 통합합니다.
### 예시
`rna = sc.read_10x_h5("rna_filtered_feature_bc_matrix.h5") prot = sc.read_10x_h5("prot_filtered_feature_bc_matrix.h5") mdata = mu.MuData({"rna": rna, "prot": prot})`
---
### 데이터 구조
#### Filtered dataset:
- 총 세포 수: 122,016
- RNA feature: 36,601
- ADT feature: 140
#### Raw dataset:
- 총 droplet 수: 24,807,643
- Empty droplet 포함
---
## 5. ADT 품질 관리 전략
ADT 데이터는 RNA와 전혀 다른 분포를 가지므로 QC 전략도 별도로 필요합니다.
### ADT 데이터 특성
- 희소하지 않음
- 비특이적 결합 → background noise 존재
- 음성 피크 + 양성 피크의 bimodal 분포
- empty droplet에도 ADT count 존재
---
### 5.1 기본 QC metric 계산
`sc.pp.calculate_qc_metrics(mdata["prot"], inplace=True) sc.pp.calculate_qc_metrics(mdata_raw["prot"], inplace=True)`
---
### 5.2 ADT 개수 기준 필터링
#### 기준 변수
- `n_genes_by_counts`: 검출된 ADT 개수
- 대부분 세포는 70–140개 ADT 발현
#### 하한 기준 결정:
- 분포 plot 상 valley ≈ 55
→ cutoff = 55
---
### 5.3 total counts 기준 필터링
높은 total ADT count는 doublet일 가능성 높음
- 초기 기준: `max_counts = 100000`
- upper tail에서 doublet 의심
---
### 5.4 Empty droplet 기반 배경 모델링 (dsb normalization용)
raw RNA에서 다음과 같은 peak 관찰됨:
- `10¹ ~ 10²` counts
→ empty droplet로 간주
→ ADT background 추정에 사용
---
## 6. 샘플 단위 QC (Sample-wise QC)
샘플 간 ADT 분포 차이가 매우 큼 → 글로벌 cutoff는 부적절
### 해결 방법
- 샘플별 median 및 MAD(Median Absolute Deviation) 기반 outlier 제거
### Outlier 함수
`def is_outlier(adata, metric: str, nmads: int): M = adata.obs[metric] return (M < np.median(M) - nmads * median_abs_deviation(M)) | \ (M > np.median(M) + nmads * median_abs_deviation(M))`
### 적용
- `log1p_total_counts`
- `log1p_n_genes_by_counts`
- threshold = 5 MAD
---
### 결과
- 제거된 세포 수: 약 1,500개
- 전체 대비 약 1%
- 비교적 완만한 필터링
---
## 7. 필터 적용 후 MuData 갱신
`mdata.update() mdata = mdata[mdata["prot"].obs["outliers"] == False]`
### 최종 데이터
- 세포 수: 118,563
- RNA + ADT 유지
---
## 8. 정리
### 핵심 포인트 요약
|항목|핵심|
|---|---|
|ADT 특성|RNA보다 노이즈 많고 sparsity 낮음|
|QC 기준|RNA 기준 그대로 쓰면 안 됨|
|주요 필터|ADT 수, total counts, sample-wise MAD|
|Empty droplet 활용|background / normalization 기준|
|MuData 사용 이유|멀티모달 통합 분석 구조|