GFF/GTF 다른 점과 변환하는 방법
두 파일이 무엇이고, 어떻게 서로 변환하는지 알아보자!
원글: Damian Kao, 번역: 김기태
소개
GFF 와 GTF 는 데이터 형식들로서 annotation 정보를 저장하는데 사용된다. 우리는 매우 자주 이 두 가지의 형식이 호환되어 사용되는 것을 볼 수 있다. 그러나 GFFs (general feature format)는 사실 모든 유전체 요소에 사용되는 반면, GTF (gene transfer format)은 오직 유전자에게만 한정되어 쓰인다.
두 가지의 형식은 서로 매우 비슷하여, 꽤 쉽게 전환이 가능하다. 하지만 단 한가지 변환할 때 문제점은 GFF 파일의 줄들이 특징적인 block들로 정리되어 있지 않다는 것이다. 이 글은 두 파일들이 어떻게 다르고 형식을 어떻게 변환하는지에 대해서 보여줄 것이다.
데이터 형식
GFF와 GTF 형식 둘 다 탭(Tab) 분리된 파일로 9개의 열로 이루어져있다. 두 파일들의 처음 8개 열은 몇 가지의 특정 버전 요구사항을 제외하고는 같다. 처음 8개 열에 대한 설명과 예제는 아래와 같다:
1. Reference sequence name (chromosome1, refContig1, sequence1)
2. Source of annotation (pfam, blast2go, interpro, est)
3. Type of feature (gene, exon, start_codon, cds, mRNA, zinc_finger, conserved_region)
4. 1-based, inclusive start coordinate (integer > 0), 시작 좌표
5. 1-based, inclusive end coordinate (integer > 0), 끝 좌표
6. Score
7. Strand (+,-,.)
8. Frame (0,1,2)
시작과 끝 좌표는 1-based로, 이것은 첫 번째 염기 위치가 1이라는 것을 뜻한다. 반면에 0-based는 위치가 0에서부터 시작한다. 포괄적인 좌표의 뜻은 하나의 유전체 요소가 시작과 끝 좌표를 포함하는 것을 의미한다. 예를 들어 어떤 요소가 10-15 라는 좌표를 가지고 있다면 처음과 끝인 10과 15를 포함한 10, 11, 12, 13, 14, 15 위치들로 정의할 수 있다. 반면에 같은 경우의 비포괄적 좌표는 11, 12, 13, 14 위치들로만 정의된다.
GFF 파일의 Score 열은 이 요소가 존재할 수 있는 확률 값을 나타낸다. 이것은 GTF 형식에서는 사용되지 않는다. Strand는 특정 유전체 요소의 reference sequence에 대한 상대적인 방향성이다. 이것은 정방향은 ‘+’, 역방향은 ‘-‘, 미상은 ’.’ 으로 나타낸다. Frame 열은 coding region 요소들로 open reading frame 1, 2, 3을 위해 0, 1, 2로 나타낸다.
GFF
GFF는 일반적인 형식으로 유전체의 모든 요소를 나타내는데 사용한다. 그러나 이 글은 GFF를 유전자 요소에 대한 것들만 다룰 것으로, 그 이유는 우리가 유전자 annotation 형식인 GTF의 변환을 원하기 때문이다. GFF 파일은 현재 version 3이다. GFF는 ‘#’으로 주석을 다는 것을 허용한다. 예를 들어 어떤 GFF 파일들은 version 정보와 파일이 언제 생성되었는지 알 수 있는 줄 정보가 있다.
##gff-version 2
##created 11/11/11
GFF의 열 1-8에 대한 내용은 위에서 알려줬다. 요소들의 종류(세 번째 열)는 제한이 없다는 것을 알아야 한다. 그 말은 우리가 원하는 대로 이름을 갖다 붙일 수 있다. 하지만 쉬운 변환을 위해서라도 gene, exon, transcript, mRNA와 같이 합리적인 이름들을 사용하는 것이 더욱 좋다.
마지막 9번째 열은 속성(attribute)에 대한 열이다. 이 속성 열은 해당 요소에 대한 정보를 가지고 있다. Version 2 와 그 이후의 이 열에 대한 형식은 ‘=’ 사인으로 분리된 tag/value pair이다. 다수의 특성은 세미콜론으로 분리된다. 예제:
ID=geneAExon1;Name=geneA;Parent=geneA;Organism=human
이 열의 문자열 끝에는 세미콜론이 들어가지 않는다.
가장 최근 버전의 GFF (version 3)의 세부사항은, 여기에서 찾을 수 있는 미리 정의된 특성들의 세트로 이루어져 있다. 일반적인 경험상으로는 ID attribute를 항상 포함하고, GFF 파일 안에서 특징 마다 고유의 ID를 갖게 하는 것이 좋다. 다른 중요한 속성 중 알아야 할 것은 ‘Parent’ 속성이다. ‘Parent’ 속성의 값은 현재 요소가 ‘Parent’의 하위 특징이라는 것을 알려준다. 예를 들면 고유 ID를 가지고 있는 다수의 exon은 parents로 하나의 유전자 요소를 가질 수 있다.
Contig01 PFAM gene 501 750 . + 0 ID=geneA;Name=geneA
Contig01 PFAM exon 501 650 . + 2 ID=exonA1;Parent=geneA
Contig01 PFAM exon 700 750 . + 2 ID=exonA2;Parent=geneA
GTF
GTF 형식은 현재 version 2이다. 이미 앞에서 말했듯이, 이것은 유전자 annotation에 대한 정보로 사용된다. GTF 파일은 오직 두 가지의 어려운 요구사항이 있다.
- CDS, start_codon, end_codon에 대한 정보가 필요하다. 사용할 소프트웨어에 따라, 특정 종류의 요소가 무조건 있어야 한다. 일반적인 종류의 요소들은 exon, transcript, cds, start_codon, end_codon 이 있다.
- 9번째 열인 attribute는 무조건 'gene_id'와 'transcript_id' attributes로 시작되어야 한다.
9번째 속성 열은 GFF 파일과 구조가 다르다. Tag/value pair가 space로 분리되어 있다. 각 속성은 세미콜론으로 끝나야 한다. 값이 텍스트인 경우에는 무조건 따옴표 안에 있어야 한다. 또한 지정된 것은 아니지만, tag 이름들에 space를 넣지 않는 것이 좋고, space 대신 underscore를 쓰는 것이 좋다.
예:
gene_id "geneA";transcript_id "geneA.1";database_id "0012";modified_by "Damian";duplicates 0;
이 줄의 끝에는 세미콜론이 있다. 그 이유는 각 속성이 끝나기 위해서는 세미콜론이 있어야 하기 때문이다. 이것이 GFF 파일과 다른 점이다.
GTF 파일에는 요소/하위 요소 관계도 없다. 만약 다수의 exon들이 있다면, 이것들은 같은 transcript_id를 갖는 그룹으로 묶여있다. 다수의 transcripts는 같은 gene_id를 가질 수 있다.
파헤쳐보기~
두 가지 형식과 버전의 다른 점을 파헤쳐 보는 표:
Columns |
GTF2 |
GFF3 |
1. reference sequence name |
동일 |
동일 |
2. annotation source |
동일 |
동일 |
3. feature type |
|
어떤 것이든 가능함. |
4. start coordinate |
동일 |
동일 |
5. end coordinate |
동일 |
동일 |
6. score |
사용되지 않음 |
임의 선택 가능 |
7. strand |
동일 |
동일 |
8. frame |
동일 |
동일 |
9. attributes |
|
|
변환 (Conversion)
앞서 말했듯이, 만약에 GFF 파일의 줄들이 하나의 요소와 관련되어 연속적으로 특정 block들에 배치가 되어있지 않다면, 파일을 파싱(parsing)하여 메모리에 데이터를 쓸 필요가 있다.
#geneA and geneB are both arranged in blocks of consecutive lines
Contig01 Twinscan gene 501 750 . + 0 ID=geneA;Name=geneA
Contig01 Twinscan exon 501 650 . + 2 ID=exonA1;Parent=geneA
Contig01 Twinscan exon 700 750 . + 2 ID=exonA2;Parent=geneA
Contig01 Twinscan gene 700 900 . + 2 ID=geneB;Name=geneB
Contig01 Twinscan exon 700 750 . + 0 ID=geneB1;Parent=geneB
Contig01 Twinscan exon 800 900 . + 0 ID=geneB2;Parent=geneB
#lines defining geneA and geneB are arranged randomly
Contig01 Twinscan gene 501 750 . + 0 ID=geneA;Name=geneA
Contig01 Twinscan gene 700 900 . + 2 ID=geneB;Name=geneB
Contig01 Twinscan exon 700 750 . + 2 ID=exonA2;Parent=geneA
Contig01 Twinscan exon 700 750 . + 0 ID=geneB1;Parent=geneB
Contig01 Twinscan exon 501 650 . + 2 ID=exonA1;Parent=geneA
Contig01 Twinscan exon 800 900 . + 0 ID=geneB2;Parent=geneB
이 이유는 가끔씩 GFF 파일이 요소 계층의 다중 레벨을 가질 수 있기 때문이다. 유전자는 transcript의 parent가 될 수 있고, exon은 유전자의 parent가 될 수 있고, domain은 exon의 parent가 될 수 있고… 이 글에서는 이런 생명현상에 대한 설명은 다루지 않을 것이다.
GTF/GFF 파일들을 상호변환 하는 데는 여러 가지 방법이 있다. BioPython과 BioPerl 둘 다 GTF/GFF parsing module들을 가지고 있다. GFF에서 GTF로 변환 할 때 항상 GFF 파일을 봐서 어떤 요소 종류(세 번째 열)와 속성(아홉 번째 열)이 사용되나 봐야 한다.
GTF에서 GFF로 변환
이 변환은 매우 간단하다. 우리는 GTF파일에서 transcript_id 값을 가지고 GFF 속성 형식으로 변환화면 된다. 그러나 gene_id와 transcript_id 사이의 계층 관계는 GFF에서 보존되지 않는다.
import sys
inFile = open(sys.argv[1],'r')
for line in inFile:
#skip comment lines that start with the '#' character
if line[0] != '#':
#split line into columns by tab
data = line.strip().split('\t')
#parse the transcript/gene ID. I suck at using regex, so I usually just do a series of splits.
transcriptID = data[-1].split('transcript_id')[-1].split(';')[0].strip()[1:-1]
geneID = data[-1].split('gene_id')[-1].split(';')[0].strip()[1:-1]
#replace the last column with a GFF formatted attributes columns
#I added a GID attribute just to conserve all the GTF data
data[-1] = "ID=" + transcriptID + ";GID=" + geneID
#print out this new GFF line
print '\t'.join(data)
이 스크립트를 저장해서 아래와 같이 사용한다.
python myScript.py myFile.gtf > myFile.gff
GFF에서 GTF로 변환하기
어떤 GFF에서 GTF로 완벽한 변환을 보장하는 간단한 스크립트 솔루션은 없다. 이것은 GFF 파일에 사용 된 요소 종류 및 속성에 따라 모두 달라진다. 이 예에서는 상위 요소의 유형이 "유전자"라고 가정하고, 다른 모든 요소의 종류는 "유전자"의 하위 특징들로 가정한다. 이 GFF 파일을 예로 들면:
Contig01 PFAM gene 501 750 . + . ID=geneA;Name=geneA
Contig01 PFAM exon 501 650 . + . ID=exonA1;Parent=geneA
Contig01 PFAM exon 700 750 . + . ID=exonA2;Parent=geneA
Contig01 PFAM cds 700 750 . + 2 ID=cdsA1;Parent=geneA
Contig01 PFAM start_codon 700 750 . + . ID=startA1;Parent=geneA
Contig01 PFAM domain 700 750 . + . ID=domainA1;Parent=geneA
위의 예에서 요소 종류 “유전자”는 다른 모두 하위 요소들(exon, cds, start_codon, domain)의 parent 요소이다.
이러한 데이터 구조를 알 때, 우리는 유전자 요소의 ID 속성, 다른 요소들의 Parent 속성을 가지고 GTF 속성의 gene_id와 transcript_id로 변환시킬 수 있다.
import sys
inFile = open(sys.argv[1],'r')
for line in inFile:
#skip comment lines that start with the '#' character
if line[0] != '#':
#split line into columns by tab
data = line.strip().split('\t')
ID = ''
#if the feature is a gene
if data[2] == "gene":
#get the id
ID = data[-1].split('ID=')[-1].split(';')[0]
#if the feature is anything else
else:
# get the parent as the ID
ID = data[-1].split('Parent=')[-1].split(';')[0]
#modify the last column
data[-1] = 'gene_id "' + ID + '"; transcript_id "' + ID
#print out this new GTF line
print '\t'.join(data)
요약
GFF는 좀 더 일반적인 유전체 annotation 형식인 반면 GTF는 엄격하게 유전자 annotation 형식이다. 더 일반적으로, GFF는 덜 제어됨으로 더 많은 변수를 필요로 한다. GTF에서 GFF로 변환하는 것은 상대적으로 매우 쉬운 것이, 필요한 gene/transcript_id 속성을 GFF 안의 ID 속성으로 변환만 하면 된다. 그러나 GFF에서 GTF 변환은 더 어려운 것이, 특성의 계층 구조, 사용된 요소의 종류 와 속성 등에 의해 결정이 되기 때문이다.
저자가 생각하기에 많은 생물정보학자들이 데이터 형식을 변환하고 파싱하는 일을 많이 한다고 말 할 수 있다 한다. 이 분야가 같이 시작되고 표준화된 형식이 나온 것이 오직 지난 십여 년 안에 일어났다. GTF와 GFF는 annotation을 위한 형식에 가장 많이 쓰여지고, 아마도 한동안은 계속 이 상태를 유지할 것이다.
원문: http://blog.nextgenetics.net/?e=27
'생물정보학 > Genomics' 카테고리의 다른 글
FASTQ format - Raw Data Read (0) | 2016.01.11 |
---|---|
FASTA format - Raw Data (0) | 2016.01.11 |
BED format (0) | 2016.01.11 |
BAM format (0) | 2016.01.07 |
SAM format (Sequence Alignment/MAP format) - Alignments (0) | 2016.01.07 |