Snakemake는 특정 Pipeline을 만들기 위한 Python package이다.
가령 Cellline들로 부터 얻은 isoform 발현값들의 비교를 하는 파이프 라인을 짠다고 해보자. 파이프 라인은 다음과 같을 것이다.
Raw fastq files(paired end) > Tophat2 > cufflinks > comparison
이러한 일련의 과정을 수행하는데 사람이 일일히 다 수행하는 것은 굉장히 번거로운 일이다. 각각의 작업이 언제 끝날지도 모르기 때문이다.
따라서 이러한 파이프라인을 자동화 하여 수행시켜줄 수 있다면, 매우 편리할 것이다.
Snakemake는 지정한 Rule에 따라서 파이프라인의 과정을 자동화 해 준다.
snakemake는 python3 기반의 프로그램이다. 설치는 간단히 pypi를 이용하여.
pip3 install snakemake
커맨드를 이용하여 설치할 수 있다.
스네이크 메이크는 Default하게 Snakefile
이라는 파일을 입력으로 받는다.
Snakefile
은 Rule들과 parameter들을 포함하고 있는 파일이다.
여기서 Rule이란 Pipeline에서 수행되는 각각의 과정들을 의미한다.
위에서 예시로 든 pipeline에서는
1. Tophat2로 fastq를 reference genome에 align하기
2. cufflinks로 FPKM값을 구하기
3. sample들간의 FPKM값의 차이를 구하기
등이 Rule이 될 수 있다.
Rule은 방금 언급했듯이 각각의 작업이다. Rule의 구조는 기본적으로
rule rule_name:
input: input_file
output: output_file
params: param1=param1, pram2=param2
shell: "command --option1 {params.param1} --option2 {params.param2} {input} {output}"
의 구조로 되어있다.
rule_name
은 rule의 이름을 지정한다input
은 input_file을 지칭한다. input_file이 존재하지 않을경우에는 일정시간(default:5seconds)를 기다린 후 없으면 pipeline의 수행을 abort시킨다.output
은 output_file을 지칭한다. 해당 작업(rule)을 수행함으로써 만들어지는 output_file을 지칭한다.params
는 해당 작업에 쓰일 parameter를 지칭한다. 뒤에서 언급하겠지만 Snakefile에서 설정하는 전역변수를 지정할 수 있다.shell
은 수행할 작업 명령이다.shell
대신run
을 쓸수 있는데 이때는 command라인 명령어 대신 python3 코드를 수행할 수 있다
Snakemake는 이렇게 정의된 rule들로 DAG(Directed Acyclic Graph)를 만든다 가령 rule tophat와 cufflinks를 살펴보자.
rule tophat:
input: fwd="samples/raw/{sample}_1.fastq.gz", rev="samples/raw/{sample}_2.fastq.gz"
params: GFF=GFF, BowtieIndex=BowtieIndex, LibraryType=LibraryType
output: "samples/bam/{sample}.bam"
shell:"""
mkdir -p samples/tophat/{wildcards.sample}
tophat -p 10 -o samples/tophat/{wildcards.sample} -G {params.GFF} --library-type {params.LibraryType} {params.BowtieIndex} {input.fwd} {input.rev}
mv samples/tophat/{wildcards.sample}/accepted_hits.bam samples/bam/{wildcards.sample}.bam
"""
rule tophat
의 경우 tophat으로 align을 시킨후 결과물인 samples/tophat/{sample}/accepted_hits.bam
을 samples/bam/{sample}.bam
으로 옮기는 것을 볼 수 있다.
rule cufflinks
는 다음과 같다.
rule cufflinks:
input: "samples/bam/{sample}.bam"
params: GFF=GFF
output: "samples/cufflinks/{sample}/isoforms.fpkm_tracking"
shell: "cufflinks -p 10 -G {params.GFF} --output-dir samples/cufflinks/{wildcards.sample} {input}"
rule tophat
의 output
과 rule cufflinks
의 input
이 동일함을 볼 수 있다.
DAG를 만들기 위하여 각각의 rule들의 input과 output이 명시적으로 같아야 한다
snakemake는이런 input과 output의 관계를 통하여 DAG를 만들고 DAG에 따라서 작업을 자동적으로 수행하게 된다.
즉 rule cufflinks
가 수행되기 위해서는 rule tophat
의 output이 존재해야 된다는 것이다.
수행하는 예제의 DAG는 다음과 같다.
각종 parameter들은 python변수가 지정되듯이 지정될 수 있다.
BASE_DIR = "~/snakemake_exercise/"
WDIR = BASE_DIR + "tutorial"
LibraryType = "fr-firststrand"
snakemake가 수행되는 working directory는 workdir
로 지정 될 수 있다.
workdir: WDIR
아무런 작업도 수행하지 않은 상태에서 sample 폴더의 file tree를 살펴보자.
내가 cufflinks
와 tophat
에 계속 사용하고 싶은 이름은 A,B 이다.
`-- samples
`-- raw
|-- A_1.fastq.gz
|-- A_2.fastq.gz
|-- B_1.fastq.gz
`-- B_2.fastq.gz
glob_wildcards(wildcard)
함수는 wildcard들을 파일로부터 추출해낸다
SAMPLES, = glob_wildcards(WDIR+"samples/raw/{sample}_1.fastq.gz")
이런식으로 내가 앞으로의 rule
들에 사용할 wildcard들을 뽑아낼 수 있다.
이 함수의 반환값인 SAMPLES
는 파이썬 리스트 객체이다. SAMPLES
의 내용을 살펴보면
['A','B']
임을 확인할 수 있다.
cufflinks의 결과물인 FPKM들을 비교하는 rule인 rule comparison
은 A와 B의 cufflinks의 수행결과가 모두 존재한 이후에 수행되어야 한다.
rule comparison:
input: expand("samples/cufflinks/{sample}/isoforms.fpkm_tracking", sample=SAMPLES)
output: "samples/comparison_result.csv"
run:
inputs = " ".join(input)
shell("python comprison.py "+inputs+" {output}")
이럴 경우에 expand(path_with_wildcards, wildcards)
함수를 쓰면 된다. 이 함수는 지정해준 path에 와일드카드들을 매칭시켜준 결과물을 파이썬 리스트로 반환시켜준다.
위의 예시에서 input은
['samples/cufflinks/A/isoforms.fpkm_tracking', 'samples/cufflinks/B/isoforms.fpkm_tracking']
이 될것이다. 따라서 rule comparison
은 A와 B의 output이 모두 나오고 나서야 수행될 것이다.
rule comparison
을 다시한번 살펴보자.
rule comparison:
input: expand("samples/cufflinks/{sample}/isoforms.fpkm_tracking", sample=SAMPLES)
expand()
함수는 python list object의 값들인 wildcard들을 rule comparison
에 맵핑해 줌과 동시에 여기에 연결되어있는 rule cufflinks
의 output: samples/cufflinks/{sample}/isoforms.fpkm_tracking
에도 매핑을 시켜준다.
이런 매핑은 연쇄적으로 rule cufflinks
의 input
과 rule tophat
의 output
,
그리고 input
으로까지 와일드카드를 매핑할 것이고, 실제 samples/raw/{sample}_1.fastq.gz, samples/raw/{sample}_2.fastq.gz
가 존재하는 것을 확인한후, 파이프라인을 실행할 것이다.
파이프 라인의 최종 목적은 rule all
의 input으로 지정할 수 있다. rule all
은 output
을 필요로 하지 않는다.
rule all:
input: "samples/comparison_result.csv"
rule all
으로 지정된 목적을 결과물로 만들어내기 위해서 snakemake를 수행하려면 Snakefile이 위치한 폴더에서
snakemake
커맨드를 입력하면 된다.
특정 rule만 실행하고 싶을 경우 output 파일 경로를 입력해 주면된다.
예를들어 rule tophat
만 실행하고 싶을 경우
snakemake samples/bam/{A,B}.bam
커맨드를 입력하면된다.
snakemake는 pipeline의 DAG를 dot
file로 만들어준다 graphviz
프로그램이 있으면 image파일로 만들 수 있다.
snakemake --dag | dot -Tpng > image_file_name.png
snakemake에서는 여러개의 잡이 병렬적으로 처리될 수 있도록 cluster 에서 잡을 수행할 수 있도록 할 수 있다.
cluster와 job management system이 있다는 가정하에(본 예제에서는 qsub을 사용한다)
snakemake --cluster "qsub --qsub-option arg" -j N
여기서 N은 한번에 최대 N개의 작업을 수행하도록 할 수 있게 만들겠다라는 의미이다.
더 고급 기능등을 사용하고 싶다면, 공식 Documentation을 참고하도록 하자
https://bitbucket.org/snakemake/snakemake/wiki/Documentation