歡迎關(guān)注"生信修煉手冊(cè)"!
在GATK4的best practice中,不再像以前那樣給出每個(gè)步驟對(duì)應(yīng)的代碼,而是直接給出了官方使用的pipeline。這些pipeline采用WDL進(jìn)行編寫(xiě)。
WDL是一種流程編寫(xiě)語(yǔ)言,沒(méi)有太多復(fù)雜的邏輯和語(yǔ)法,入門(mén)簡(jiǎn)單。首先看一個(gè)hello world的例子
workflow myWorkflow {
? ?call myTask
}
task myTask {
? ?command {
? ? ? ?echo "hello world"
? ?}
? ?output {
? ? ? ?String out = read_string(stdout())
? ?}
}對(duì)于一個(gè)WDL腳本而言,有以下5個(gè)核心結(jié)構(gòu)
workflow
task
call
command
-
output
每個(gè)腳本包含1個(gè)workflow, workflow由多個(gè)task構(gòu)成。 在workflow中,通過(guò)call調(diào)用對(duì)應(yīng)的task。每個(gè)task在workflow代碼塊之外單獨(dú)定義。
task代表任務(wù),讀取輸入文件,執(zhí)行相應(yīng)命令,然后輸出。command中對(duì)應(yīng)的就是執(zhí)行的命令,比如一條具體的gatk的命令,output 指定task的輸出值。可以將task理解為編程語(yǔ)言中的函數(shù),每個(gè)函數(shù)讀取輸入的參數(shù),執(zhí)行代碼,然后返回,command對(duì)應(yīng)執(zhí)行的具體代碼,output對(duì)應(yīng)返回值。
在WDL中,也是可以傳遞參數(shù)的。task和workflow中的寫(xiě)法不同
1. task 中的參數(shù)
下面的示意圖中,task 有3個(gè)輸入的參數(shù),文件類型的ref,in 和字符串類型的id。 在command中,通過(guò)${ref}這種格式訪問(wèn)變量的值
2. workflow 中的參數(shù)
下面的示意圖中, workflow 有3個(gè)參數(shù),文件類型的my_ref,my_input 和字符串類型的name。傳遞這3個(gè)參數(shù)給task時(shí),直接傳變量名就可以了。
作為流程管理語(yǔ)言,需要對(duì)多個(gè)task統(tǒng)一管理。task之間具有多種關(guān)系
1. 一對(duì)一的依賴關(guān)系
前一個(gè)task的輸出,作為后一個(gè)task的輸入
示例如下
workflow LinearChain {
?File firstInput
?call stepA { input: in=firstInput }
?call stepB { input: in=stepA.out }
?call stepC { input: in=stepB.out }
}
task stepA {
?File in
?command { programA I=${in} O=outputA.ext }
?output { File out = "outputA.ext" }
}
task stepB {
?File in
?command { programB I=${in} O=outputB.ext }
?output { File out = "outputB.ext" }
}
task stepC {
?File in
?command { programC I=${in} O=outputC.ext }
?output { File out = "outputC.ext" }
}一個(gè)task的多個(gè)輸出作為下一個(gè)task的輸入
示例如下:
workflow MultiOutMultiIn {
?File firstInput
?call stepA { input: in=firstInput }
?call stepB { input: in=stepA.out }
?call stepC { input: in1=stepB.out1, in2=stepB.out2 }
}
task stepA {
?File in
?command { programA I=${in} O=outputA.ext }
?output { File out = "outputA.ext" }
}
task stepB {
?File in
?command { programB I=${in} O1=outputB1.ext O2=outputB2.ext }
?output {
? ?File out1 = "outputB1.ext"
? ?File out2 = "outputB2.ext" }
}
task stepC {
?File in1
?File in2
?command { programB I1=${in1} I2=${in2} O=outputC.ext }
?output { File out = "outputC.ext" }
}2. 多對(duì)多的依賴關(guān)系
一個(gè)task的輸出作為多個(gè)task的輸入,或者多個(gè)task的輸出作為1個(gè)task的輸入
示例如下:
workflow BranchAndMerge {
?File firstInput
?call stepA { input: in=firstInput }
?call stepB { input: in=stepA.out }
?call stepC { input: in=stepA.out }
?call stepD { input: in1=stepC.out, in2=stepB.out }
}
task stepA {
?File in
?command { programA I=${in} O=outputA.ext }
?output { File out = "outputA.ext" }
}
task stepB {
?File in
?command { programB I=${in} O=outputB.ext }
?output { File out = "outputB.ext" }
}
task stepC {
?File in
?command { programC I=${in} O=outputC.ext }
?output { File out = "outputC.ext" }
}
task stepD {
?File in1
?File in2
?command { programD I1=${in1} I2=${in2} O=outputD.ext }
?output { File out = "outputD.ext" }
}3. 平行關(guān)系
多個(gè)task之間完全平行,可以并行執(zhí)行
示例如下:
workflow ScatterGather {
?Array[File] inputFiles
?scatter (oneFile in inputFiles) {
? ?call stepA { input: in=oneFile }
?}
?call stepB { input: files=stepA.out }
}
task stepA {
?File in
?command { programA I=${in} O=outputA.ext }
?output { File out = "outputA.ext" }
}
task stepB {
?Array[File] files
?command { programB I=${files} O=outputB.ext }
?output { File out = "outputB.ext" }
}task和函數(shù)還是有一定的區(qū)別,函數(shù)可以在代碼中多次調(diào)用,但是task多次調(diào)用會(huì)有風(fēng)險(xiǎn)。下面的示意圖中,stepA 運(yùn)行兩次,一次作為stepB的輸入,一次作為stepC的輸入。如果stepA的兩次調(diào)用并行執(zhí)行,當(dāng)執(zhí)行完之后,在傳遞給下一個(gè)task時(shí),由于存在兩個(gè)同名的stepA, stepB和stepC 就會(huì)無(wú)法正確接受參數(shù)。
WDL中提供了解決方案,叫做task alias, 為task起一個(gè)別名,示例如下
workflow taskAlias {
?File firstInput
?File secondInput
?call stepA as firstSample { input: in=firstInput }
?call stepA as secondSample { input: in=secondInput }
?call stepB { input: in=firstSample.out }
?call stepC { input: in=secondSample.out }
}
task stepA {
?File in
?command { programA I=${in} O=outputA.ext }
?output { File out = "outputA.ext" }
}
task stepB {
?File in
?command { programB I=${in} O=outputB.ext }
?output { File out = "outputB.ext" }
}
task stepC {
?File in
?command { programC I=${in} O=outputC.ext }
?output { File out = "outputC.ext" }
}在WDL腳本中, 理論上每個(gè)task 只可以調(diào)用1次,如果希望多次調(diào)用,必須借助task alias。
掌握以上幾點(diǎn),就可以理解一個(gè)wdl腳本的整體框架了。在實(shí)際使用中,我們只要能理解整個(gè)workflow的流向,會(huì)使用wdl腳本就可以了。
運(yùn)行wdl腳本,需要兩個(gè)文件
cromwell.jar
-
womtools.jar
最新版的下載鏈接如下:
https://github.com/broadinstitute/cromwell/releases/tag/31
第一步是得到輸入?yún)?shù)的列表,用法如下
java -jar womtools.jar inputs myWorkflow.wdl > myWorkflow_inputs.json
用json格式存存儲(chǔ),這一步得到的只是一個(gè)模板,需要編輯這個(gè)文件,將對(duì)應(yīng)的參數(shù)替換成實(shí)際的參數(shù)
第二步運(yùn)行腳本,用法如下
java -jar Cromwell.jar run myWorkflow.wdl —inputs myWorkflow_inputs.json
總結(jié)
WDL是一種流程管理語(yǔ)言,語(yǔ)法簡(jiǎn)單,內(nèi)置的支持并行等特征,適合編寫(xiě)pipeline。運(yùn)行
wdl腳本只需兩步,第一步編輯參數(shù)列表對(duì)應(yīng)的json文件,第二步直接運(yùn)行即可。
掃描關(guān)注微信號(hào),更多精彩內(nèi)容等著你!