콘텐츠로 이동

Rosie PoC: 종양 변이에서 신항원 후보까지

이 실습에서 답할 질문은 하나입니다.

종양에서 발견한 변이 가운데 정상에는 없고 실제로 발현되는 변이만 남기면, 어떤 mutant peptide 후보를 만들 수 있는가?

Rosie의 원본 시퀀싱 데이터와 최종 표적 7개는 공개되지 않았으므로 그 결과를 재현하지는 않습니다. 대신 공개 설명에서 확인되는 핵심 논리, 종양 DNA 변이 → 정상 DNA 제외 → 종양 RNA 확인 → mutant peptide 생성을 합성 데이터로 직접 실행합니다.

2026년 8월 16일에 공개 자료를 다시 확인했지만, Rosie의 FASTQ·VCF·DLA 유전형·7개 표적 서열로 이어지는 다운로드 링크는 찾지 못했습니다. 이름이 비슷한 별도 오픈소스 Project Rosie의 canine demo도 저장소 안에서 synthetic VCF, synthetic enriched candidates라고 밝힙니다. 따라서 그 demo를 Rosie의 실제 데이터로 바꿔 쓰지 않았습니다.

입력이 실습에서 묻는 질문
종양 DNA VAF종양 표본에서 변이가 충분히 관찰되는가?
정상 DNA VAF몸 전체가 가진 germline 변이는 아닌가?
종양 RNA의 mutant read변이 allele이 실제 전사물에서도 관찰되는가?
종양 TPM그 유전자가 종양에서 발현되는가?
변이 주변 단백질 서열변이 아미노산을 포함한 peptide는 무엇인가?

출력은 증거 필터를 통과한 변이와 그 변이를 포함하는 9-mer peptide 표입니다. 사람의 HLA에 해당하는 개의 유전자는 DLA(dog leukocyte antigen)1입니다. DLA 결합 예측은 이 PoC의 출력 뒤에 오는 단계이므로 여기서는 계산하지 않습니다.

변이가 어떻게 peptide 후보가 되나

섹션 제목: “변이가 어떻게 peptide 후보가 되나”

DNA의 단일 염기 변화가 단백질의 아미노산 하나를 바꾸면, 정상 단백질에는 없던 짧은 서열이 생길 수 있습니다. 세포가 그 단백질을 만들고 잘라 DLA에 올리면 T세포가 변이 peptide를 볼 가능성이 생깁니다. 이런 종양 특이 변이에서 유래한 항원을 신항원(neoantigen)이라고 부릅니다.

계산 파이프라인은 이 생물학적 과정을 거꾸로 확인합니다.

  1. 종양 DNA에서 변이를 관찰합니다.
  2. 같은 위치가 정상 DNA에도 있는지 확인합니다.
  3. 종양 RNA에서 변이 allele이 전사됐는지 확인합니다.
  4. 변이가 바꾼 단백질 서열을 계산합니다.
  5. 변이 아미노산을 포함하는 짧은 peptide를 만듭니다.
  6. 개체의 DLA에 결합하고 실제 제시될 가능성을 평가합니다.

이 실습은 1번부터 4번까지 끝난 작은 TSV를 입력으로 받아 5번까지 실행합니다. 6번을 하지 않으므로 출력은 신항원 후보를 예측하기 전의 peptide 후보입니다. 문서 제목의 신항원 후보는 전체 목적을 가리키며, 현재 파일만으로 검증된 신항원이라고 부르지는 않습니다.

종양 DNA, 정상 DNA와 종양 RNA는 같은 사실을 세 번 확인하는 중복 검사가 아닙니다.

증거통과하면 말할 수 있는 것이것만으로 말할 수 없는 것
종양 DNA종양 표본의 DNA read에서 변이 allele이 관찰됨몸 전체가 가진 변이인지, 발현되는지
정상 DNAmatched normal에서는 같은 변이 신호가 기준 이하임종양에서 단백질로 만들어지는지
종양 RNA mutant read종양 전사물에서 변이 allele이 직접 관찰됨DLA에 결합해 표면에 제시되는지
종양 TPM해당 유전자 전사물이 sample에 존재함그 TPM이 모두 mutant allele에서 왔는지

종양 RNA의 tumor_rna_alt_readstumor_tpm도 서로 다른 값입니다. TPM이 높아도 변이 위치를 직접 지지한 read가 0일 수 있고, mutant read가 몇 개 있어도 유전자 전체 발현량은 낮을 수 있습니다. 이 PoC는 두 조건을 모두 검사합니다.

이 실습의 범위는 후보 축소까지입니다. 합성 입력에 네 가지 필터를 적용하고 9-mer 후보를 만드는 단계까지만 다룹니다. DLA 유전형 판독, peptide-MHC 결합 예측, 정상 단백질 유사성 검사, 독성·자가면역 평가, 제조 서열 설계와 실험 검증은 포함하지 않습니다.

입력 TSV의 행 하나는 변이 후보 하나입니다. 실제 Rosie의 변이가 아니며, 유전자 이름, 단백질 변화와 수치는 필터의 동작을 보여 주기 위한 합성 예시입니다.

의미
variant_id합성 변이 식별자
wildtype_sequence, mutant_sequence변이 주변의 정상형과 변이형 단백질 서열
mutation_index주변 서열에서 바뀐 아미노산의 0부터 시작하는 위치
tumor_dna_vaf종양 DNA read 중 변이 allele의 비율
normal_dna_vaf정상 DNA read 중 같은 변이 allele의 비율
tumor_rna_alt_reads종양 RNA에서 변이를 직접 지지한 read 수
tumor_tpm종양에서 해당 유전자의 발현량

VAF가 0.42라면 그 위치를 읽은 종양 DNA read 100개 중 약 42개가 변이를 지지했다는 뜻입니다. VAF만으로 종양세포 비율이나 clonality를 확정할 수는 없습니다. copy number와 표본 순도도 VAF를 바꾸기 때문입니다.

서열을 제외한 실제 입력 다섯 행은 다음과 같습니다.

IDgene단백질 변화종양 DNA VAF정상 DNA VAF종양 RNA mutant read종양 TPM
SYN001KITp.K9V0.420.003138.0
SYN002TP53p.T10Q0.310.001812.4
SYN003PIK3CAp.I11R0.240.0018.1
SYN004KRASp.G10D0.360.182721.3
SYN005BRAFp.Q11E0.080.0094.2

p.K9V는 단백질 서열의 9번째 아미노산이 lysine을 뜻하는 K에서 valine을 뜻하는 V로 바뀌었다는 표기입니다. TSV의 mutation_index는 Python에서 쓰기 편하도록 0부터 세므로 이 변이는 8입니다. 사람에게 보여 주는 단백질 위치 9와 배열 index 8을 혼동하면 다른 아미노산을 peptide 중심에 놓게 됩니다.

표만 보면 SYN004는 강한 후보처럼 보입니다. 종양 DNA VAF가 0.36이고 RNA mutant read도 27개입니다. 그러나 정상 DNA VAF가 0.18이므로 종양 특이성 기준을 통과하지 못합니다. 반대로 SYN003은 종양 DNA VAF와 TPM은 충분하지만 변이를 직접 지지하는 RNA read가 1개뿐입니다. 각 열을 따로 두는 이유가 두 행에 드러납니다.

  1. TSV의 숫자와 단백질 서열이 코드가 기대하는 구조와 맞는가?
  2. 네 필터를 각 행에 적용하면 왜 통과하거나 탈락하는가?
  3. 통과한 변이의 증거 점수는 어떻게 계산되는가?
  4. 변이 아미노산 하나에서 왜 9개의 9-mer가 생기는가?
  5. 필터 하나를 완화하면 어떤 후보와 어떤 위험이 함께 들어오는가?
  6. 이 출력 뒤에 무엇을 더 해야 신항원과 백신 표적을 말할 수 있는가?

빈 작업 폴더에서 Codex CLI나 Claude Code를 실행한 뒤 아래 프롬프트를 전달합니다. 에이전트는 합성 입력과 스크립트를 별도 프로젝트 폴더에 내려받고 구조만 검사합니다. 아직 후보 필터는 실행하지 않습니다.

실습 환경 설정 프롬프트
Rosie 신항원 후보 축소 PoC 환경을 준비해줘.

요구사항:
1. 현재 폴더가 이미 rosie-neoantigen-poc 프로젝트인지 확인해. 아니라면 현재 폴더 아래에 rosie-neoantigen-poc를 만들고 그 안에서 작업해.
2. Python 3가 설치되어 있는지 확인하고 버전을 출력해. 후보 필터인 shortlist.py는 표준 라이브러리만 사용하므로 이 준비 단계에서는 외부 Python 패키지를 설치하지 마. 뒤의 결과 피겨 단계에서는 matplotlib만 사용해도 돼.
3. 아래 두 파일을 내려받아. 같은 이름의 파일이 이미 있다면 내용을 덮어쓰지 말고 크기와 내용을 먼저 검사해.
 - https://homegenomics.org/data/practice/rosie-neoantigen-poc/demo_variants.tsv
 - https://homegenomics.org/data/practice/rosie-neoantigen-poc/shortlist.py
4. demo_variants.tsv가 UTF-8 TSV인지, 헤더를 포함해 6행인지, 데이터 행의 열 수가 모두 같은지 검사해.
5. python3 -m py_compile shortlist.py로 문법을 검사해. 아직 shortlist.py를 실행하지 마.
6. outputs 디렉터리를 만들고 .gitignore에 __pycache__/를 추가해. 입력 TSV와 Python 스크립트는 Git에서 제외하지 마.
7. 생성하거나 확인한 파일, Python 버전, TSV 행과 열 수, 문법 검사 결과를 한국어로 보고하고 멈춰.

다운로드가 실패하면 임의의 대체 데이터를 만들지 말고 실패한 URL과 오류를 보고해. 기존 파일의 내용이 원격 파일과 다른지 확실하지 않다면 덮어쓰지 말고 멈춰.

준비 직후에는 다음 파일이 있습니다.

  • demo_variants.tsv: 합성 변이 5개의 DNA, RNA와 단백질 서열 증거
  • shortlist.py: 필터, 증거 점수와 9-mer 생성 로직
  • outputs/: 이후 결과와 민감도 분석표를 저장할 폴더

이 페이지에 표시한 표와 피겨는 2026년 8월 16일에 같은 파일을 별도 작업 폴더로 내려받아 다시 실행한 결과입니다. 실행 결과를 직접 대조하려면 다음 파일을 받을 수 있습니다.

아래 프롬프트를 한 번에 합치지 말고 위에서부터 하나씩 전달하세요. 각 단계의 실제 표와 코드 근거를 확인한 뒤 다음 단계로 넘어갑니다.

3. 프롬프트로 후보를 한 단계씩 줄이기

섹션 제목: “3. 프롬프트로 후보를 한 단계씩 줄이기”

3-1. 입력 표와 코드가 같은 언어를 쓰는지 확인

섹션 제목: “3-1. 입력 표와 코드가 같은 언어를 쓰는지 확인”

먼저 실행 없이 입력과 코드를 읽습니다. TSV의 열 이름이 코드가 요구하는 열 이름과 맞지 않으면 결과를 만들기 전에 멈춰야 합니다.

1단계 프롬프트: 입력과 필터 구조 확인
Rosie PoC의 입력 TSV와 shortlist.py를 읽고 구조만 설명해줘.

1. demo_variants.tsv를 csv 표준 라이브러리로 읽어 열 이름, 행 수, 각 열의 Python에서의 예상 자료형을 정리해.
2. 변이 5개를 variant_id, gene, protein_change, tumor_dna_vaf, normal_dna_vaf, tumor_rna_alt_reads, tumor_tpm 순서의 표로 보여줘.
3. 각 행에서 wildtype_sequence와 mutant_sequence의 길이가 같은지, mutation_index가 범위 안인지, 그 위치의 아미노산이 실제로 하나만 다른지 검사해.
4. shortlist.py의 rejection_reason(), evidence_score(), mutant_peptides()가 각각 어떤 입력 열을 읽고 무엇을 반환하는지 설명해.
5. 코드에 적힌 네 필터 기준과 검사 순서를 정확히 표로 정리해.
6. evidence_score의 세 구성 요소와 가중치를 식으로 풀어 쓰고, 면역원성 점수가 아니라는 근거를 코드에서 찾아 설명해.
7. 아직 shortlist.py를 실행하거나 파일을 수정하지 마. 입력과 코드 사이의 불일치가 있는지 한국어로 보고하고 멈춰.

기본 스크립트는 다음 네 조건을 모두 요구합니다.

normal DNA VAF ≤ 0.02
tumor DNA VAF ≥ 0.10
tumor RNA mutant read ≥ 3
tumor TPM ≥ 1.0

이 숫자는 다섯 행의 합성 입력에서 필터 역할을 눈으로 확인하기 위해 정한 값입니다. 다른 데이터에서는 sequencing depth, 오류 모델, variant caller의 품질값, 종양 순도와 연구 프로토콜에 따라 기준을 다시 정해야 합니다.

코드는 필터와 점수를 분리합니다. rejection_reason()은 후보가 최소 증거를 갖췄는지 판정하고, evidence_score()는 통과한 후보를 증거 강도 순으로 정렬합니다. 점수가 높아도 필터를 통과하지 못하면 출력 peptide가 되지 않습니다.

증거 점수는 세 입력을 먼저 0에서 1 사이로 제한합니다.

d=min(tumor DNA VAF0.5,1)d = \min\left(\frac{\text{tumor DNA VAF}}{0.5}, 1\right) r=min(tumor RNA mutant reads20,1)r = \min\left(\frac{\text{tumor RNA mutant reads}}{20}, 1\right) e=min(log2(tumor TPM+1)6,1)e = \min\left(\frac{\log_2(\text{tumor TPM}+1)}{6}, 1\right)

그다음 DNA와 RNA 직접 증거에 각각 40%, 유전자 전체 발현량에 20% 가중치를 둡니다.

evidence score=0.4d+0.4r+0.2e\text{evidence score} = 0.4d + 0.4r + 0.2e

가중치와 분모는 임상적으로 검증된 모델이 아니라 합성 PoC를 위한 규칙입니다. 점수의 0.9를 면역 반응 확률 90%로 읽어서는 안 됩니다.

3-2. 기본 필터 실행과 탈락 이유 확인

섹션 제목: “3-2. 기본 필터 실행과 탈락 이유 확인”

이 단계에서는 결과의 후보 수보다 각 행이 왜 남거나 탈락했는지를 먼저 봅니다.

2단계 프롬프트: 기본 후보 필터 실행
검증한 합성 입력에 기본 필터를 한 번 실행하고 결과를 감사해줘.

1. python3 shortlist.py demo_variants.tsv -o outputs/candidate_peptides.tsv를 실행해.
2. 표준 출력의 PASS, REJECT, WROTE 행을 보존해 보여줘.
3. 각 변이에 네 필터를 모두 적용한 감사표를 만들어. 열은 variant_id, normal DNA, tumor DNA, mutant RNA, tumor TPM, 최종 판정, 탈락 이유로 구성하고 outputs/filter_audit.tsv로 저장해.
4. 여러 조건을 동시에 위반하는 행이 있으면 모든 이유가 출력되는지 코드와 실제 결과를 대조해.
5. outputs/candidate_peptides.tsv가 생성됐는지 확인하고 행 수, 열 이름, variant별 peptide 수를 검사해.
6. 기본 데이터에서는 SYN001과 SYN002만 통과하고 총 18개 peptide가 나오는지 assert 성격으로 검증해. 다르면 원인을 조사하고 파일을 임의로 고치지 마.
7. SYN004가 tumor DNA와 RNA에서는 강하게 보여도 탈락하는 이유를 matched normal의 역할과 연결해 설명해.
8. 다섯 변이의 evidence_score를 가로 막대로 그려 outputs/evidence-score.png에 180 dpi로 저장해. PASS와 REJECT를 색뿐 아니라 텍스트로도 구분하고, SYN004의 탈락 이유를 막대 옆에 표시해. 그래프에 필요한 경우 이 단계에서만 matplotlib을 추가해.
9. 그림의 제목과 라벨이 잘리지 않는지 직접 확인해.
10. 실행 명령, 실제 출력, 검증 결과를 한국어로 보고하고 멈춰.

아직 필터 기준을 바꾸거나 DLA 결합을 예측하지 마.

정상 결과는 다음과 같습니다.

PASS SYN001 9 peptides
PASS SYN002 9 peptides
REJECT SYN003 mutant RNA read 부족
REJECT SYN004 normal DNA에도 보임
REJECT SYN005 tumor DNA VAF 부족
WROTE outputs/candidate_peptides.tsv 18 rows

SYN004는 종양 DNA와 RNA에서 강하게 보이지만 정상 DNA VAF도 0.18입니다. 이 열을 보지 않으면 정상세포도 가진 변이를 종양 특이 후보로 잘못 남길 수 있습니다.

다섯 행의 판정은 다음처럼 한 줄씩 읽습니다.

IDnormal DNAtumor DNAmutant RNATPM점수결과
SYN0010.00, 통과0.42, 통과31, 통과38.0, 통과0.912PASS
SYN0020.00, 통과0.31, 통과18, 통과12.4, 통과0.733PASS
SYN0030.00, 통과0.24, 통과1, 탈락8.1, 통과0.318REJECT
SYN0040.18, 탈락0.36, 통과27, 통과21.3, 통과0.837REJECT
SYN0050.00, 통과0.08, 탈락9, 통과4.2, 통과0.323REJECT

합성 변이 5개의 evidence score. SYN004는 점수가 두 번째로 높지만 normal DNA 필터에서 탈락한다.

현재 실험의 outputs/evidence-score.png. 청록색은 네 필터를 모두 통과한 변이, 회색은 하나 이상 실패한 변이입니다. 점수 0.837인 SYN004가 점수 0.733인 SYN002보다 높아도 정상 DNA 증거 때문에 제외됩니다.

SYN001의 점수를 실제 숫자로 계산해 보겠습니다. tumor DNA VAF 0.42는 0.42 ÷ 0.5 = 0.84가 됩니다. RNA mutant read 31개는 31 ÷ 20이 1보다 크므로 1로 제한됩니다. TPM 38은 log2(38 + 1) ÷ 6 ≈ 0.881입니다.

0.4(0.84)+0.4(1)+0.2(0.881)0.9120.4(0.84) + 0.4(1) + 0.2(0.881) \approx 0.912

이 계산에는 normal DNA VAF가 들어가지 않습니다. normal DNA는 통과 여부를 결정하는 안전 필터이고, 통과한 뒤의 증거 점수에는 종양 DNA, 종양 RNA와 TPM만 들어갑니다. 그래서 normal DNA에서도 보이는 SYN004의 점수가 0.837로 높아도 최종 결과에서는 제외됩니다.

점수 0.912가 붙는 단위는 peptide가 아니라 SYN001 변이입니다. 같은 변이에서 만든 9개 peptide는 아직 서열별 결합력을 평가하지 않았으므로 모두 같은 점수를 복사해 갖습니다.

3-3. 변이 하나에서 9-mer가 만들어지는 과정 추적

섹션 제목: “3-3. 변이 하나에서 9-mer가 만들어지는 과정 추적”

MHC class I은 세포 안 단백질에서 잘린 짧은 peptide를 세포 표면에 보여 줍니다. 이 PoC는 길이를 9로 고정하고, 변이 아미노산이 첫 칸부터 마지막 칸까지 한 번씩 들어오도록 창을 움직입니다. 서열 양쪽에 충분한 여유가 있으면 변이 하나에서 9개 후보가 나옵니다.

3단계 프롬프트: 9-mer 생성 로직 추적
기본 필터 결과를 유지하고 SYN001의 9-mer 생성 과정을 추적해줘.

1. demo_variants.tsv에서 SYN001의 wildtype_sequence, mutant_sequence와 mutation_index를 읽어. 파일은 수정하지 마.
2. mutation_index는 0부터 시작하고 출력의 peptide_start는 1부터 시작한다는 차이를 실제 숫자로 설명해.
3. shortlist.mutant_peptides()를 호출해 SYN001에서 생성되는 9개 window를 시작 위치 순서로 표로 보여줘.
4. 표에는 peptide_start, wildtype_peptide, mutant_peptide, peptide 안에서 변이 아미노산의 1부터 시작하는 위치를 넣어.
5. 모든 peptide 길이가 9인지, 정상형과 변이형이 정확히 한 아미노산만 다른지, 그 차이가 원래 mutation_index와 대응하는지 검증해.
6. 표를 outputs/syn001_peptide_windows.tsv로 저장하고, outputs/candidate_peptides.tsv의 SYN001 행과 함수의 직접 출력이 같은지 비교해.
7. 21개 아미노산 mutant sequence 위에 9개 window를 정렬한 그림을 만들어 outputs/syn001-peptide-windows.png에 180 dpi로 저장해. 변이 아미노산 V는 색과 검은 테두리로 함께 표시해.
8. evidence_score가 같은 변이에서 나온 9개 peptide에 모두 같은 이유를 설명해.
9. 그림의 서열, start와 peptide 안 변이 위치를 TSV와 대조해.
10. 검증 결과와 코드가 지원하지 않는 변이 유형을 한국어로 보고하고 멈춰.

새 peptide 예측 도구를 설치하거나 DLA 결합 점수를 만들지 마.

출력의 첫 세 행은 다음과 같은 모양입니다.

variant_id gene protein_change peptide_start wildtype_peptide mutant_peptide evidence_score
SYN001 KIT p.K9V 1 KPMYEVQWK KPMYEVQWV 0.912
SYN001 KIT p.K9V 2 PMYEVQWKV PMYEVQWVV 0.912
SYN001 KIT p.K9V 3 MYEVQWKVV MYEVQWVVV 0.912

SYN001의 9개 window를 모두 펼치면 변이 K → V가 peptide 안에서 오른쪽 끝부터 왼쪽 끝까지 한 칸씩 이동합니다.

peptide startwildtype 9-mermutant 9-merpeptide 안의 변이 위치
1KPMYEVQWKKPMYEVQWV9
2PMYEVQWKVPMYEVQWVV8
3MYEVQWKVVMYEVQWVVV7
4YEVQWKVVEYEVQWVVVE6
5EVQWKVVEEEVQWVVVEE5
6VQWKVVEEIVQWVVVEEI4
7QWKVVEEINQWVVVEEIN3
8WKVVEEINGWVVVEEING2
9KVVEEINGNVVVEEINGN1

SYN001의 mutant sequence 위에서 시작점을 한 칸씩 옮긴 9개 9-mer. 주황색 V가 peptide의 9번째 칸에서 1번째 칸으로 이동한다.

현재 실험의 outputs/syn001-peptide-windows.png. 맨 위는 21개 아미노산의 mutant sequence이고, 아래 행은 여기서 잘라 낸 9-mer입니다. 검은 테두리의 V는 모든 행에서 원래 단백질의 9번째 아미노산입니다.

첫 행의 window는 주변 서열의 1번째 아미노산에서 시작합니다. 원래 단백질의 9번째에 있던 변이는 이 9-mer의 마지막 칸에 놓입니다. 시작점을 한 칸 오른쪽으로 옮긴 두 번째 window에서는 같은 변이가 8번째 칸에 놓입니다. 시작점이 9가 되면 변이는 첫 칸에 놓입니다.

코드는 가능한 start의 범위를 계산할 때 서열의 양쪽 끝을 넘지 않게 제한합니다. 변이가 주변 서열의 맨 앞이나 끝에 가깝다면 9개보다 적은 9-mer만 나옵니다. 이 합성 입력은 모든 변이의 양쪽에 충분한 아미노산이 있어 각각 9개가 생성됩니다.

wildtype_peptidemutant_peptide의 한 아미노산 차이는 면역계가 종양과 정상을 구분할 후보 단서입니다. 모든 mutant peptide가 실제로 만들어지거나 세포 표면에 제시된다는 뜻은 아닙니다.

evidence_score는 종양 DNA VAF, mutant RNA read와 발현량을 0에서 1 사이로 합친 정렬용 점수입니다. 같은 변이에서 나온 9개 peptide가 같은 점수를 갖는 이유는 아직 peptide별 DLA 결합과 processing을 계산하지 않았기 때문입니다.

peptide의 변이 위치가 달라지면 DLA 결합력도 달라질 수 있습니다. DLA의 결합 홈은 peptide의 특정 위치를 강하게 읽기 때문입니다. 따라서 9개를 중복이라고 지우지 않고 다음 단계의 결합 예측에 각각 전달합니다. 이 PoC는 어느 위치가 더 좋다고 점수를 만들지 않습니다.

mutant_peptides()는 정상형과 변이형 서열 길이가 다르면 오류를 냅니다. 따라서 insertion, deletion과 frameshift처럼 단백질 길이를 바꾸는 변이는 현재 코드가 지원하지 않습니다. 실제 신항원 파이프라인에서는 변이 뒤로 완전히 새로운 서열이 생기는 frameshift 후보도 별도 로직으로 처리해야 합니다.

3-4. 필터를 완화했을 때의 대가 비교

섹션 제목: “3-4. 필터를 완화했을 때의 대가 비교”

필터는 정답을 찾는 스위치가 아니라, 놓치는 후보와 잘못 넣는 후보 사이의 선택입니다. 원본 스크립트를 직접 고쳐 결과를 덮어쓰지 않고 별도 임계값 민감도 분석으로 비교합니다.

4단계 프롬프트: 필터 민감도 실험
원본 demo_variants.tsv와 shortlist.py를 수정하지 않고 필터 민감도 분석을 추가해줘.

1. outputs/sensitivity.tsv를 만드는 별도 sensitivity.py를 작성해. 집계 로직은 표준 라이브러리만 사용하고, 그림에는 2단계에서 추가한 matplotlib만 재사용해.
2. 다음 네 시나리오를 같은 입력 5개에 적용해.
 - baseline: 원본 네 기준
 - rna_relaxed: mutant RNA read 최소값을 3에서 1로 완화
 - no_normal_filter: normal DNA 기준만 제거
 - tumor_vaf_relaxed: tumor DNA VAF 최소값을 0.10에서 0.05로 완화
3. 각 시나리오에서 통과한 variant_id, baseline에 새로 추가된 variant_id, 변이 수와 생성될 9-mer 수를 기록해.
4. 기준 하나 외에는 baseline과 완전히 같게 유지해. 원본 함수의 계산을 재사용할 수 있는 부분은 재사용하되, 원본 파일을 문자열 치환한 복사본으로 만들지 마.
5. 예상대로 rna_relaxed에는 SYN003, no_normal_filter에는 SYN004, tumor_vaf_relaxed에는 SYN005가 추가되는지 검증해.
6. 각 시나리오의 9-mer 수를 가로 막대로 그려 outputs/sensitivity.png에 180 dpi로 저장해. baseline과 완화 시나리오를 색뿐 아니라 라벨로 구분하고, 새로 들어온 variant_id를 막대 옆에 적어.
7. 각 완화가 늘리는 민감도와 함께 생기는 위양성 또는 안전 근거 손실을 입력 수치에 연결해 설명해.
8. python3 sensitivity.py로 재실행하고 그림의 숫자를 outputs/sensitivity.tsv와 대조해. 생성하거나 수정한 파일과 결과를 보고하고 멈춰.

이 다섯 행에서 관찰한 결과만 보고해. 시나리오 threshold를 다른 데이터셋의 권장 기준으로 바꾸지 말고, peptide-MHC 결합이나 치료 효과 점수를 임의로 추가하지 마.

RNA 기준을 3개 read에서 1개로 낮추면 SYN003이 추가됩니다. 후보 포함 범위가 넓어지지만 read 한 개의 sequencing error나 잘못된 정렬까지 받아들일 위험도 커집니다. 이 합성 입력에는 검증된 정답 라벨이 없으므로 분류 지표인 재현율 또는 민감도가 얼마나 높아졌는지는 계산할 수 없습니다.

normal DNA 필터를 제거하면 SYN004도 통과합니다. 후보 수는 늘지만 종양 특이성이라는 중요한 안전 근거를 잃습니다. 같은 방식으로 tumor DNA VAF 기준을 낮추면 약한 종양 DNA 신호를 더 받아들이는 대신 오류 신호가 들어올 여지가 커집니다.

예상되는 outputs/sensitivity.tsv의 핵심 내용은 다음과 같습니다.

시나리오통과 변이변이 수9-mer 수
baselineSYN001,SYN002218
rna_relaxedSYN001,SYN002,SYN003327
no_normal_filterSYN001,SYN002,SYN004327
tumor_vaf_relaxedSYN001,SYN002,SYN005327

기본 필터와 세 가지 완화 시나리오의 9-mer 수. 각 완화에서 변이 하나와 peptide 9개가 추가된다.

현재 실험의 outputs/sensitivity.png. 세 완화 시나리오는 모두 18개에서 27개로 늘지만 새로 받아들이는 변이와 잃는 증거는 서로 다릅니다.

모든 완화에서 후보가 하나씩 늘고 peptide는 9개씩 늘지만, 얻는 정보의 질은 같지 않습니다.

rna_relaxed는 DNA에서 확실해 보이지만 RNA 증거가 약한 변이를 살립니다. 낮은 RNA sequencing depth 때문에 실제 전사된 변이를 놓치는 상황에는 도움이 될 수 있지만, 한 개 read의 base-calling 오류와 alignment artifact를 구분할 근거가 약합니다.

no_normal_filter는 종양에서 관찰되는 신호만 보겠다는 선택입니다. SYN004의 normal DNA VAF 0.18을 무시하므로 germline 또는 정상세포에도 존재하는 변이를 종양 특이 후보로 부를 위험이 생깁니다. 세 시나리오 가운데 안전성 근거를 가장 직접적으로 잃는 변화입니다.

tumor_vaf_relaxed는 종양 DNA VAF 0.08인 SYN005를 살립니다. 종양 순도가 낮거나 subclone에만 있는 실제 변이를 더 잡을 수 있지만, 낮은 빈도의 sequencing noise도 함께 들어올 수 있습니다. 실제 분석에서는 VAF 하나가 아니라 해당 위치의 total depth, strand bias, base quality와 caller의 오류 모델을 함께 봅니다.

이 표는 threshold를 추천하지 않습니다. 다섯 행으로 만든 합성 데이터에서 어떤 기준이 어떤 실패를 막는지 분리해 보는 실험입니다. 실제 threshold는 assay의 오류율과 검증 비용을 근거로 정해야 합니다.

4. 실제 파이프라인에서 앞뒤로 붙는 단계

섹션 제목: “4. 실제 파이프라인에서 앞뒤로 붙는 단계”

이 PoC의 TSV는 여러 어려운 단계를 이미 끝낸 형태입니다. 실제 FASTQ에서 출발하면 다음 작업이 앞뒤에 붙습니다.

  1. 종양·정상 DNA와 종양 RNA의 QC와 reference genome 정렬
  2. matched tumor-normal somatic variant calling
  3. transcript와 coding consequence annotation
  4. RNA 발현량과 mutant allele support 계산
  5. 개체의 DLA 유전형 추정
  6. 변이 단백질 서열과 peptide 생성
  7. DLA 결합, processing, 정상 proteome 유사성으로 우선순위화
  8. 전문가 검토와 실험적 검증

TSV의 간단한 열 하나 뒤에는 다음과 같은 원본 증거가 숨어 있습니다.

TSV 열실제 파이프라인에서 함께 기록할 정보
tumor_dna_vaftumor alt read 수, total depth, base quality, strand bias, caller filter
normal_dna_vafmatched normal alt read 수와 depth, contamination 가능성
tumor_rna_alt_readsRNA reference/alt read 수, splice-aware alignment와 mapping quality
tumor_tpm사용한 transcript annotation, 정량 도구와 버전
protein_changegenome build, transcript ID, consequence annotation 버전
단백질 서열선택한 transcript와 정상·변이 allele 적용 방법

예를 들어 tumor DNA VAF 0.10은 1/10에서도 100/1000에서도 나올 수 있습니다. 비율은 같지만 두 번째가 훨씬 많은 read의 지지를 받습니다. 이 PoC에는 total depth가 없으므로 두 상황을 구분하지 못합니다.

normal_dna_vaf = 0.00도 정상세포에 변이가 절대 없다는 뜻은 아닙니다. 해당 위치의 depth가 충분한 상태에서 변이 read가 0개였는지 확인해야 합니다. depth가 0이면 관찰하지 못한 것이지 없음을 확인한 것이 아닙니다.

단백질 변화도 transcript에 따라 달라질 수 있습니다. 같은 genome variant가 어떤 transcript에서는 missense이고 다른 transcript에서는 coding region 밖일 수 있습니다. 실제 파이프라인에서는 TP53이라는 gene symbol만 기록하지 않고 transcript ID와 annotation 릴리스를 고정해야 같은 peptide를 다시 만들 수 있습니다.

Rosie의 공개 설명에 나온 “DNA의 손상 부위가 종양 RNA 명령에도 나타나는지 확인했다”는 말은 2번부터 4번까지를 압축한 표현입니다. 이 실습은 그 결과를 작은 표로 받아 6번까지 진행한 셈입니다.

DLA 결합 단계에서 새로 달라지는 것

섹션 제목: “DLA 결합 단계에서 새로 달라지는 것”

현재 결과에서는 SYN001의 9개 peptide가 모두 0.912입니다. DLA 결합 예측을 붙이면 peptide 서열과 DLA allele 조합마다 다른 affinity나 percentile rank가 생깁니다. 변이가 peptide의 어느 위치에 놓였는지도 이 단계에서 중요해집니다.

같은 peptide도 개체의 DLA allele에 따라 강하게 결합하거나 거의 결합하지 않을 수 있습니다. 따라서 Rosie의 DLA genotype이 없으면 peptide 서열만으로 어떤 후보가 제시될지 재현할 수 없습니다. 다른 개의 DLA 결과를 대신 넣는 것도 Rosie의 결과를 재현하는 방법이 아닙니다.

결합 예측을 통과해도 끝이 아닙니다. 세포가 해당 단백질을 실제로 자르고, peptide가 transporter와 processing 단계를 통과하며, 세포 표면의 DLA에 올라와야 합니다. 마지막으로 T세포가 peptide-DLA 복합체를 인식하는지 실험으로 확인해야 합니다.

이 실행으로 확인한 것은 작지만 분명합니다. 네 종류의 관측값을 기계적으로 검사해 부적절한 변이를 제외하고, 통과한 단백질 변이에서 mutant peptide 후보를 재현 가능하게 만들 수 있습니다.

아직 답하지 못한 질문은 다음과 같습니다.

  • 이 peptide가 Rosie의 DLA에 강하게 결합하는가
  • 세포 안에서 실제로 잘리고 표면에 제시되는가
  • 정상 canine proteome과 충분히 다른가
  • T세포가 인식하고 종양세포를 죽이는가
  • 여러 표적을 어떤 순서와 간격으로 mRNA construct에 넣어야 하는가

그래서 출력 파일의 이름은 vaccine.tsv가 아니라 candidate_peptides.tsv입니다. 계산은 후보를 줄였고 치료제를 만들지는 않았습니다.

결과 파일을 읽을 때 지켜야 할 경계

섹션 제목: “결과 파일을 읽을 때 지켜야 할 경계”
관찰한 결과말할 수 있는 문장아직 말할 수 없는 문장
SYN001이 PASS합성 기준 네 개를 모두 통과했다실제 종양의 검증된 somatic mutation이다
9개 mutant peptide 생성변이 아미노산을 포함한 9-mer를 열거했다세포에서 9개가 모두 만들어진다
evidence score 0.912이 PoC의 DNA·RNA 규칙에서 높은 순위다면역 반응 확률이 91.2%다
normal DNA VAF 0.00합성 표에서 normal alt 비율이 0이다충분한 depth로 germline 가능성을 완전히 배제했다
mutant RNA read 31합성 표에서 변이 전사물 증거가 있다단백질과 세포 표면 제시를 확인했다

이 경계를 지키면 계산 결과를 축소해서 말하는 것이 아니라, 현재 입력과 방법이 실제로 지지하는 범위만 정확하게 말하게 됩니다.

  1. 종양 DNA VAF가 높아도 normal DNA 필터를 통과해야 하는 이유는 무엇인가?
  2. DNA 변이가 있지만 mutant RNA read가 0이라면 우선순위를 낮추는 이유는 무엇인가?
  3. 한 변이에서 여러 9-mer를 만드는 이유는 무엇인가?
  4. evidence_score가 높은 peptide를 면역원성이 높다고 부를 수 없는 이유는 무엇인가?
  5. 실제 Rosie 분석을 재현하려면 현재 공개되지 않은 어떤 입력이 필요한가?
  1. DLA(dog leukocyte antigen): 개의 주조직적합복합체(MHC). 세포 안에서 잘린 peptide를 세포 표면에 제시하며, T세포는 이 peptide-DLA 결합체를 검사합니다. 개체마다 DLA allele이 달라 같은 peptide도 제시 여부가 달라질 수 있습니다.