前言
??一般生物信息分析流程都包含很多的分析步驟啄枕,這些步驟之間的聯(lián)系也有很多情況膀值。例如桶唐,流程的步驟中有不少是依賴上一步的結(jié)果栅葡,同時(shí)也有些步驟之間沒有聯(lián)系可以同時(shí)進(jìn)行,還有的步驟需要滿足某種情況才運(yùn)行尤泽,也有的步驟需要匯總很多樣本的結(jié)果來進(jìn)行分析欣簇,等等這些情況。那么一個(gè)好的流程應(yīng)該要滿足沒有依賴的步驟可以并行分析坯约,需要上一步結(jié)果的步驟會(huì)自動(dòng)等待上一步驟執(zhí)行完畢并調(diào)用其結(jié)果熊咽,需要匯總很多步驟的結(jié)果時(shí)能夠自動(dòng)等待所有依賴步驟執(zhí)行完畢然后匯總他們的結(jié)果并調(diào)用,以及能夠處理一些其他的情況等闹丐。
??一個(gè)優(yōu)秀的流程工具應(yīng)該具備良好的組織性横殴、復(fù)用性、支持多種集群架構(gòu)卿拴,較低的上手及查錯(cuò)成本衫仑。那么有沒有這么好用的流程管理工具呢?答案是肯定的堕花。今天我們就來分享一個(gè)非常好用且強(qiáng)大的流程管理工具——WDL文狱。目前WDL就是這樣一個(gè)具備這種潛力的工具,WDL是Broad Institute開發(fā)的“human readable and writable”定義組織任務(wù)與工作流的一種語言缘挽。Cromwell(an execution engine that can run WDL scripts)是基于java編寫的可以很好地用來執(zhí)行WDL語言的引擎工具瞄崇。WDL+Cromwell就是一套很好的分析流程解決方案呻粹。
WDL介紹
結(jié)構(gòu)
- WDL:整體是由一個(gè)workflow構(gòu)成,一般寫在一個(gè)后綴為“.wdl”的文件里面苏研。
- workflow:整體有兩個(gè)部分構(gòu)成等浊,一是位于頭部的input,該部分定義workflow級(jí)別的變量楣富,所有的task都可以調(diào)用該部分的變量,如果很多步驟都需要使用的變量最好定義在這個(gè)部分方便使用伴榔;二是使用“call”關(guān)鍵字調(diào)用下面定義的task纹蝴,這個(gè)部分的task順序不代表執(zhí)行時(shí)的順序,task的執(zhí)行順序有任務(wù)之間是否有引用關(guān)系來決定踪少,如果任務(wù)之間沒有聯(lián)系就會(huì)平行執(zhí)行塘安,如果有一個(gè)任務(wù)需要用到另一個(gè)任務(wù)的結(jié)果時(shí),可以在寫流程的時(shí)候指定好援奢,這樣就在執(zhí)行的時(shí)候就會(huì)有先后順序兼犯。
- task:主要包含三個(gè)部分,一是位于頭部的input集漾,該部分定義的是task級(jí)別的變量切黔,也就直接給該task自己使用的變量;二是使用“command”關(guān)鍵字定義的具體命令部分具篇,在這里面可以書寫的命令就是Linux命令寫的一樣命令纬霞;三是使用“output”關(guān)鍵字定義的輸出部分,這樣別的任務(wù)就可以調(diào)用這樣輸出結(jié)果驱显,WDL也正是通過這個(gè)來定義任務(wù)間的執(zhí)行順序诗芜;主要是上面三個(gè)部分,還有一些可選部分埃疫,如可以通過runtime(使用集群時(shí)有效)伏恐、parameter_meta、meta等關(guān)鍵字來定義任務(wù)的運(yùn)行配置栓霜、參數(shù)信息翠桦、流程信息等。
- variable:定義變量的時(shí)候可以在類型關(guān)鍵字后面加一個(gè)“?”代表這個(gè)變量是可選的胳蛮,也就是可以不提供值的變量秤掌,也可以給變量賦一個(gè)默認(rèn)值,這樣沒有另外給值時(shí)就會(huì)使用默認(rèn)值鹰霍。由于執(zhí)行引擎Cromwell是基于java編寫的闻鉴,所以定義的變量是強(qiáng)類型的,也就是需要顯示地聲明變量的類型茂洒,變量類型主要包括以下幾種:
String: 字符串類型孟岛,
Float : 浮點(diǎn)型數(shù)字,
Int: 整型的數(shù)字,
Boolean : 布爾類型渠羞,只有true和false兩種情況斤贰,
File: 文件類型,
Array : 數(shù)組類型次询,
Map: 字典類型荧恍,
Object : 對(duì)象類型,這個(gè)很少用到屯吊。
完整WDL示例
上面介紹完WDL基本構(gòu)成送巡,大家現(xiàn)在知道一個(gè)WDL由哪些組件構(gòu)成的了,后面就是運(yùn)行這些組件來拼出自己需要的workflow盒卸,下面我給出一個(gè)盡量包含更多情況的示例骗爆,讓大家有一個(gè)直觀地感受,下面來看一下示例代碼:
workflow testwdl {
Int? thread = 6
String varwdl
String prefix
Array[Int] intarray = {1,2,3,4,5}
if(thread>5) {
call taska {
input:
vara = varwdl,
infile = taskb.outfile,
prefix = prefix
}
}
scatter (sample in intarray) {
call taskb {
input:
varb = 'testb',
thread = thread,
prefix = sample
}
}
}
task taska {
String vara
Array[File] infile
String prefix
command {
cat ${sep=" " infile} >${prefix}_${vara}.txt
}
}
task taskb {
String varb
Int thread
String prefix
command {
echo ${varb} ${thread} >${prefix}.txt
}
output {
File outfile = '${prefix}.txt'
}
}
上面的WDL描述了一個(gè)流程包含taska蔽介、taskb兩個(gè)任務(wù)摘投,taskb會(huì)打印一個(gè)文件里面包含“taskb”和threadb變量的值,taska會(huì)合并所有taskb的結(jié)果虹蓄,且taska依賴taskb犀呼,也就會(huì)先執(zhí)行taskb任務(wù)。同時(shí)由于taskb任務(wù)被包含在scatter循環(huán)結(jié)構(gòu)中會(huì)被執(zhí)行多次薇组,這里intarray長(zhǎng)度為5圆凰,也就是taskb會(huì)并行執(zhí)行五次。taska需要引用taskb的結(jié)果体箕,也就是需要等待所有taskb執(zhí)行完才會(huì)執(zhí)行专钉,這里還需要注意一點(diǎn),taska的執(zhí)行還需要thread變量的值大于5累铅,我這里默認(rèn)設(shè)置的是6跃须,如果不修改則taskb執(zhí)行完肯定會(huì)執(zhí)行taska,如提供一個(gè)小于5的thread值娃兽,則即使taskb全部執(zhí)行完taska也不會(huì)執(zhí)行菇民。
WDL執(zhí)行
流程寫好了,下面就可以執(zhí)行了投储,但是在執(zhí)行之前最好用工具檢驗(yàn)一下有沒有語法錯(cuò)誤(如果你相信自己寫的WDL沒有問題可以跳過這個(gè)步驟)第练,這一步并不怎么耗時(shí),個(gè)人覺得還是有必要檢測(cè)一下免得運(yùn)行了也是出錯(cuò)玛荞。
- 驗(yàn)證WDL的有效性
java -jar womtool-51.jar validate test.wdl
如果輸出結(jié)果是“Success!”娇掏,那么恭喜你寫的WDL沒有語法錯(cuò)誤,可以接著運(yùn)行了勋眯。
- 生成提供變量值的json文件
#生成json文件
java -jar ~/software/cromwell-51/womtool-51.jar inputs test.wdl >test.json
#查看json文件
cat test.json
{
"testwdl.varwdl": "String",
"testwdl.intarray": "Array[Int] (optional, default = [1, 2, 3, 4, 5])",
"testwdl.prefix": "String",
"testwdl.thread": "Int? (optional, default = 6)"
}
從上面的代碼可以看出婴梧,我這里寫的WDL需要四個(gè)輸入下梢,其中有兩個(gè)是有默認(rèn)值的變量,對(duì)于這兩個(gè)可以不用提供值塞蹭,另外兩個(gè)給予相應(yīng)的值即可孽江,例如,下面是我提供的名為“test.json”的json文件:
{
"testwdl.varwdl": "helloworld",
"testwdl.prefix": "test_wdl"
}
輸入的json文件也已備好番电,最后就可以執(zhí)行WDL了岗屏,具體執(zhí)行命令如下:
java -jar cromwell-51.jar run test.wdl --inputs test.json
流程執(zhí)行過程的細(xì)節(jié)都會(huì)被記錄在log文件中,如果成功地執(zhí)行了會(huì)在log文件中看到類似[2020-09-05 03:04:34,12] [info] SingleWorkflowRunnerActor workflow finished with status 'Succeeded'.
提示語句漱办。
WDL結(jié)果
流程執(zhí)行完畢默認(rèn)會(huì)在運(yùn)行流程的目錄下生成兩個(gè)目錄这刷,cromwell-executions和cromwell-workflow-logs分別是執(zhí)行步驟的文件夾和log文件夾。下面來看一下結(jié)果文件夾目錄機(jī)構(gòu)洼冻,如上面的WDL流程執(zhí)行完成后的結(jié)果目錄結(jié)構(gòu)如下所示:
├── cromwell-executions
│ └── testwdl
│ └── 91fd40bd-7a34-41b3-8540-3c9db7b6e580
│ ├── call-taska
│ │ ├── execution
│ │ ├── inputs
│ │ └── tmp.5fe66a06
│ └── call-taskb
│ ├── shard-0
│ ├── shard-1
│ ├── shard-2
│ ├── shard-3
│ └── shard-4
├── cromwell-workflow-logs
從上面的目錄結(jié)構(gòu)可以看出同一個(gè)WDL流程即使多次執(zhí)行最新的結(jié)果也不會(huì)覆蓋之前的結(jié)果崭歧,甚至在同一個(gè)目錄下運(yùn)行不同流程的WDL生成的結(jié)果也不會(huì)相互干擾隅很,這些都得益于WDL的目錄結(jié)構(gòu)包含一層隨機(jī)字符串目錄撞牢,如這里的“91fd40bd-7a34-41b3-8540-3c9db7b6e580”,所以大家就放心大膽的運(yùn)行吧叔营!最終每個(gè)task的運(yùn)行中間文件和結(jié)構(gòu)在相應(yīng)的execution文件下面屋彪。
如這里taska的結(jié)果在cromwell-executions/testwdl/91fd40bd-7a34-41b3-8540-3c9db7b6e580/call-taska/execution
下面,最終的結(jié)果文件為test_wdl_helloworld.txt
绒尊,內(nèi)容如下:
testb 6
testb 6
testb 6
testb 6
testb 6
現(xiàn)在是不是決定WDL很強(qiáng)大且容易上手畜挥,對(duì)于這么好的東西是不是有種相見恨晚的感覺,那還在等什么趕緊用起來吧婴谱!對(duì)于功能這里僅僅展示了一小部分蟹但,更多更強(qiáng)的功能留待大家自己在使用中摸索吧!
最后
??前面介紹了WDL的基本構(gòu)成和用法展示谭羔,這里給大家提供一下官網(wǎng)鏈接方便想深入學(xué)習(xí)的同學(xué)华糖,WDL官網(wǎng):https://support.terra.bio/hc/en-us/articles/360037117492-Getting-Started-with-WDL。順便附上執(zhí)行引擎Cromwell的下載地址瘟裸,方便需要的同學(xué)下載客叉,下載鏈接:https://github.com/broadinstitute/cromwell/releases。后續(xù)再更新如何配置集群的配置文件话告,讓W(xué)DL可以在集群上運(yùn)行兼搏,這樣就可以充分利用集群的資源提升流程整體的運(yùn)行速度,節(jié)省更多時(shí)間沙郭。emm佛呻,今天就先分享到這里吧。