利用WDL語(yǔ)言書(shū)寫(xiě)數(shù)據(jù)處理流程


The Workflow Description Language (WDL) is a way to specify data processing workflows with a human-readable and -writeable syntax. WDL makes it straightforward to define analysis tasks, chain them together in workflows, and parallelize their execution. The language makes common patterns simple to express, while also admitting uncommon or complicated behavior; and strives to achieve portability not only across execution platforms, but also different types of users. Whether one is an analyst, a programmer, an operator of a production system, or any other sort of user, WDL should be accessible and understandable.
WDL的官方說(shuō)明文檔: Getting Started With WDL


目前在GATK4的流程中,基本都是以WDL的形式編寫(xiě)的。WDL沒(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)
1.workflow: 工作流定義

  1. task : 工作流包含的任務(wù)定義
  2. call: 調(diào)用或觸發(fā)工作流里面的 task 執(zhí)行
  3. command: task在計(jì)算節(jié)點(diǎn)上要執(zhí)行的命令行
  4. output: task 或 workflow 的輸出定義
  5. runtime: task在計(jì)算節(jié)點(diǎn)上的運(yùn)行時(shí)參數(shù),包括 CPU、內(nèi)存、docker 鏡像等
    image.png

每個(gè)腳本包含1個(gè)workflow, workflow由多個(gè)task構(gòu)成。 在workflow中,通過(guò)call調(diào)用對(duì)應(yīng)的task。每個(gè)taskworkflow代碼塊之外單獨(dú)定義。

task代表任務(wù),讀取輸入文件,執(zhí)行相應(yīng)命令,然后輸出。command中對(duì)應(yīng)的就是執(zhí)行的命令,比如一條具體的gatk的命令,output指定task的輸出值??梢詫?code>task理解為編程語(yǔ)言中的函數(shù),每個(gè)函數(shù)讀取輸入的參數(shù),執(zhí)行代碼,然后返回,command對(duì)應(yīng)執(zhí)行的具體代碼,output對(duì)應(yīng)返回值。

在WDL中,也是可以傳遞參數(shù)的。taskworkflow中的寫(xiě)法不同

變量利用

我們要把一個(gè)處理步驟構(gòu)造成一個(gè)task, 就要封裝計(jì)算軟件的命令行,那么命令行的參數(shù)如何傳入呢?輸出文件的名字如何指定呢?這些問(wèn)題在 WDL 中可以通過(guò)變量來(lái)解決。比如 Hello world 例子中的 String out 就是一個(gè)字符串類型的輸入,用于指定輸出文件的名字。WDL 中的變量可以定義在 workflow 中,也可以定義在 task中。在commandoutput 中可以通過(guò)${}的方式來(lái)引用變量。

變量的類型主要有以下幾種:

  1. String
  2. Int
  3. Float
  4. File
  5. Boolean
  6. Array[T]
  7. Map[K, V]
  8. Pair[X, Y]
  9. Object
workflow 中的參數(shù)

下面的示意圖中, workflow 有3個(gè)參數(shù),文件類型的my_ref,my_input 和字符串類型的name。傳遞這3個(gè)參數(shù)給task時(shí),直接傳變量名就可以了。


image.png
task 中的參數(shù)

下面的示意圖中,task 有3個(gè)輸入的參數(shù),文件類型的ref,in 和字符串類型的id。 在command中,通過(guò)${ref}這種格式訪問(wèn)變量的值。


image.png
Task 如何組成Workflow呢

作為流程管理語(yǔ)言,需要對(duì)多個(gè)task統(tǒng)一管理。task之間具有多種關(guān)系

1. 線性輸出關(guān)系:
image.png

第一種是最常見(jiàn)的場(chǎng)景,簡(jiǎn)單的線性串聯(lián),多個(gè) task 依次執(zhí)行,前面步驟的輸出作為后面步驟的輸入,最后一個(gè) task 的輸出作為整個(gè) workflow 的輸出。
示例如下:

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" }
}
2. 多對(duì)多的依賴關(guān)系

一個(gè)task的輸出作為多個(gè)task的輸入,或者多個(gè)task的輸出作為1個(gè)task的輸入
case1:


image.png
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" }
}

case2:


image.png

示例如下:

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. 平行執(zhí)行關(guān)系(并行計(jì)算)
image.png
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ù)。

image.png

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。

輸入?yún)?shù)如何傳入

workflow 的輸入,比如基因樣本的存儲(chǔ)位置、計(jì)算軟件的命令行參數(shù)、計(jì)算節(jié)點(diǎn)的資源配置等,可以通過(guò) json 文件的形式來(lái)指定。使用 wdltools 工具可以根據(jù) WDL 文件來(lái)生成輸入模板:


image.png

模板格式如下:


image.png

當(dāng)然,如果工作流不是很復(fù)雜,也可以按照上面的格式手寫(xiě) input 文件。下面是一個(gè) GATK 工作流的 input 文件的片段.


image.png
實(shí)際例子

使用 GATK 構(gòu)建的Jointcalling
workflow定義


image.png

image.png

image.png

image.png

掌握以上幾點(diǎn),就可以理解一個(gè)wdl腳本的整體框架了。在實(shí)際使用中,我們只要能理解整個(gè)workflow的流向,會(huì)使用wdl腳本就可以了。 運(yùn)行wdl腳本,需要兩個(gè)文件

  1. cromwell.jar
  2. 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

reference:

https://developer.aliyun.com/article/716546
https://cloud.tencent.com/developer/article/1626274

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容