바이오인포매틱스

BGZF (Blocked GNU Zip Format)

hongiiv 2015. 7. 1. 16:18
반응형

Random Access

BAM 파일의 경우에는 BGZF를 이용하기 때문에 원하는 곳으로 빠르게 access가 가능하다. 우리가 흔히 사용하는 GZIP (GNU ZIP) 보다는 압축효율 (압축했을때 용량)이 떨어지지만 random access가 가능하다는 잇점으로 인해 BAM 파일(BAM의 경우 재빠르게 자신이 원하는 position을 뷰잉하는데 많이 사용하기 때문)에서 사용하는 기술이다.


용량이 큰 텍스트 파일을 압축해 놓고 파일의 어느 부분이던지 랜덤하게 액세스 가능하기 때문에 그 활용도가 높은데 특히나 클러스터를 이용하는 경우 파일을 분할하는 등의 I/O 작업이 필요 없기 때문에 그 활용이 매우 높다고 할 수 있다. 여러 활용중 하나로 FASTQ 파일에 적용하여 사용하고 있다. 

FASTQ 응용

일루미나는 Base Call을 수행한 후 기본적으로 GZIP을 이용하여 압축하게 되는데 이를 다음과 같은 명령으로 BGZF로 변환한다. 뭐 언뜻 보기에는 BGZF가 GZIP과 호환되기 때문에 이게 BGZF인지 확인해 봐야 한다. grabix 툴의 check를 이용하면 간단하게 알 수 있다.


# zcat TN1506L0327_2.fq.gz |bgzip /dev/stdin -c > TN1506L0327_2.fastq.gz

# /BIO/app/grabix/grabix check TN1506L0327_2.fastq.gz

yes

# /BIO/app/grabix/grabix index TN1506L0327_2.fastq.gz

# /BIO/app/grabix/grabix grab TN1506L0327_2.fastq.gz 1 10

@HWI-ST840:481:HVKTWADXX:1:1101:1213:1943 2:N:0:ATTGGCTC

GGTACCAGTACCATGCTGTTTTGGTTACTGTAGCCTTGTAGCACAGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

+

BB@DFFFFFHHHHJJJJJIJJJJJIIJJJJIIJIJJJJJJJJIJJI#######################################################

@HWI-ST840:481:HVKTWADXX:1:1101:1986:1934 2:N:0:ATTGGCTC

ATATCTACACCACGCAAAGTGATGTGTAAGTGTGGGTGTTGCTCNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

+

@@CDDFFAHFFHHIIIIIIHHIHECDHIIEFHHHGI@DDGIIIG#########################################################

@HWI-ST840:481:HVKTWADXX:1:1101:1874:1947 2:N:0:ATTGGCTC

CCTAGGAATCCAACTTACAAGGGATGCGAAGGACCTCTTCAAGAAGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

BWA 활용

이렇게 BGZF 포맷의 FASTQ 파일은 굳이 압축을 풀지 않아도 원하는 라인을 바로 확인이 가능하게 된다. 이렇게 되면 우리는 클러스터 노드에 다음과 같이 직접 파일을 분할 할 필요 없이 "grabix grab 파일명 start_line end_line"을 통해 다수의 노드에 BWA 매핑 작업을 분할하여 수행할 수 있다.


# bwa mem -M -t 7  -R '@RG\tID:1\tPL:illumina\tPU:1_2014-08-13_dream-syn3\tSM:syn3-normal' -v 1 GRCh37.fa <(grabix grab normal-1.fq.gz 20000001 40000000) <(grabix grab normal-2.fq.gz 20000001 40000000)


많은 생물학 데이터 FASTQ, FASTA, SAM, BED, XML, Tab 구분 파일 등등 모두 적용이 가능하며 다양하게 활용이 가능하다. 물론 여러개의 BGZF 파일을 압축해제 과정이 필요없이 하나의 BGZF로 묶어주는 방법도 장혜식 박사의 블로그에 있으니 자신의 데이터에 적용해서 활용해 보기 바란다.

Python을 이용한 BGZF 헤더 다루기

RFC1952 문서에 정의된 GZIP에서 extra field를 활용하는 BGZF는 extra field의 두개의 subfield id에 각각 66, 67의 값을 가지며, EOF 마커로 "1f 8b 08 04 00 00 00 00 00 ff 06 00 42 43 02 00 1b 00 03 00 00 00 00 00 00 00 00 00"의 16진수를 가진다.

 


Python을 이용하여 파일을 읽고 BGZF 포맷이 맞는지 확인하는 코드를 작성해 보도록 하자. 대학원 시절 프로토콜 정의하고 구현하던게 갑자기 생각이 난다. 암튼 뭐 어쨌건간에 우선 파일의 첫번째 블록의 헤더 부분을 읽어오는데 기본 헤더와 함께 SI1,SI2의 extra subfield의 일부분을 읽는다. 읽어오는 부분은 총 14바이트 하나씩 출력해보면 위에 정의된 값들이 출력되는 것을 확인할 수 있으며, XLEN 부분은 총 6바이트가 extra subfield로 지정된 것을 확인 할 수 있다.


from struct import unpack


bgzf_file=open('TN1506L0327_1.fastq.gz')

header = bgzf_file.read(14)


id1, id2, cm, flg, time, xfl, os,extra_len, extra_id1, extra_id2 = unpack('<BBBBLBBHBB', header)


>>> from struct import unpack

>>>

>>> bgzf_file=open('TN1506L0327_1.fastq.gz')

>>> header = bgzf_file.read(14)

>>>

>>> id1, id2, cm, flg, time, xfl, os,extra_len, extra_id1, extra_id2 = unpack('<BBBBLBBHBB', header)

>>> id1

31

>>> id2

139

>>> cm

8

>>> flg

4

>>> extra_len

6

>>> extra_id1

66

>>> extra_id2

67


BGZF 파일의 EOF를 읽어들여 파일이 제대로 생성된 것인지를 확인해 본다. 이전에 언급했듯이 파일의 마지막 28바이트를 읽어들여 EOF 마커와 동일한지 확인한다. 왜 BGZF의 첫블록을 읽고 마지막 EOF를 확인하는지는 많은 데이터가 짤리는 경우가 많아서 확인 과정을 거친 후 진행하는게 건강에 좋아서랄까? ㅎ


>>> bgzf_file.seek(-28,2)

>>> eof=bgzf_file.read(28)

>> eof

'\x1f\x8b\x08\x04\x00\x00\x00\x00\x00\xff\x06\x00BC\x02\x00\x1b\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00'


반응형