如何用wdl编写生信流程

作者:童蒙
审稿:同尘
编辑:amethyst

引言

生信分析离不开各种各样的流程。一个好的流程可以帮我们快速的完成各种各样的分析。然而,如何让我们的流程有更高的复用性,可移植性,稳定性,对于流程的使用而言,也非常的重要。

现状

对于如何进行生信分析,相信是八仙过海,各显神通。如果实现一个简单文件的文件,可能执行某条语句或运行某个软件即可。如果满足一套复杂的要求,可能需要多条语句,用makefile,bash,或其他脚本语言串连成一个模块即可。如果减少一套分析方案的手动执行过程,则需要将多个模块串成pipeline或workflow…

workflow搭建就像将各个零件按设计图纸组装成机器一样,图纸不同,机器不同。但是如果各部分零件的规格和接口都不一样,图纸再简单,也是个复杂的工程,甚至只能一次次调整,耗时又耗力。目前生信分析的模块就是这样,没有统一的构建标准。

除了对流程进行定义缺乏标准外,如何调度和监控的任务,实现任务的并发、资源调度也是一件让人抓狂的事情。WDL是board推出的一套便于human readable and writable的流程编写规则,其主要的特点在于更适合于生信人员(而非纯IT人员)来书写流程。

例子

我们先看一个hello_world的案例

task hello {
  input {
    String pattern
    File in
  }

  command {
    egrep '${pattern}' '${in}'
  }

  runtime {
    docker: "broadinstitute/my_image"
  }

  output {
    Array[String] matches = read_lines(stdout())
  }
}

workflow wf {
  call hello
}

具体介绍前,从上面的例子我们可以总结WDL 的一些特点:

(1)分层清晰,即使不了解WDL也能明白每部分的作用;
(2)明确定义输入和输出,方便模块间引用。

WDL组件

WDL核心是两大部分,task 和 workflow,二者组成结构相似,具体如下:

1. task

task是对模块的定义,把通常用的一些命令组合到一起,形成一个复用程度高的集合。以下部分wdl中task包括的元素:

input
为该task的输入模块。如果该模块有外部输入,则是必须提供该部分。
在input内部,主要是进行变量的声明。变量的声明格式为 Type(?+) name=value ,value可以不存在,由外来传入。

其中Type的类型有String、Int、Float、Boolean、File、Array、Pair、Map,以及自定义的Struct类型。

?表示变量可不用传入信息,+只能跟在Aarry后面,表示数组至少有一个元素。

当定义为File类型时,会自动检查文件是否存在,不存在会报错。

有以下例子:

Int? i                     # An integer value, i is optional
Float f = 27.3             # A floating point number
Boolean b = true           # A boolean true/false
String s = "hello, world"  # A string value
File f = "path/to/file"    # A file
Array[Int] a1

声明内部也支持各种表达式的,例如“+-*/”等,这一块跟所有的编程语言很类似,不再赘述。

input之外的声明
input的声明是为了参数外传,对于task里的其他中间变量可以写在input外面。
这一部分是可选,写到input里面和外面好像效果都是一样的。

command
具体执行的命令,最基本的是shell,也支持其他语言的嵌套,软件的运行命令等。shell的所有语法,基本在这个代码块中都适用。例如hello_world中的

egrep '${pattern}' '${in}'

其中{pattern} 是变量的引用,也可以用~{pattern}来引用。官方建议用~{pattern}来引用。

runtime
配置该task的运行环境,一般有docker,memory,cpu等。这一块用来设置运行的环境、资源等,需要根据不同的运行平台进行设置。也可以是变量,由外部来导入。

output
输出模块,如果有输出,则一定要申明,其他模块在调用该模块的结果时可以直接引用,比如调用例子的结果方式是:hello.matches
声明的方式同input中一样,也支持表达式,例如“+-*/”等,如 ${name}+"txt"也支持变量的内插,例如${name}.txt”,当输出类型是File时,建议value值用双引号引起来,这样在下一个模块调用时才是绝对路径。
output中有个glob,可以glob某个pattern的文件,返回一个array。在某些情况下会很有用。
在output中还支持很多函数,例如read_int(),详情见3中函数部分。

meta
可选,例如存放作者和版本信息等。

parameter_meta
可选,相当于-h 里面的信息。可以使用wdl-aid来生成wdl的文档,方便分享。

2. workflow

将定义的task有机组合到一起,就形成了我们常说的流程。流程通常是DAG(有向无环图)的瀑布模式。
一个wdl里面只能有一个workflow定义,否则会报错。workflow的组成和task很相似,input,output,meta等定义方式一致,不再赘述。需要说明的是,workflow的output可以直接引用task的结果,比如:

output {
    File outfile1=task1.result
    File outfile2=task2.result
}

workflow与task最大的不同是没有command,而是有call,即调用task任务,同时为实现多样的DAG关系也存在特殊定义,比如scatter,if等,具体说明如下。

call
call是对task的直接调用,可以直接使用input的参数,也可以调用其他task的结果。正是因为call的顺序和输入输出的先后依赖关系,才构成了workflow的主要DAG关系。示例如下:

call my_task as my_task_alias2 {
    input: 
        threshold=threshold,
        file1=task1.output1,
        file2=task2.output1
  }

my_task是定义好的task名称,as后面是调用的时候的名称,如果同一个模块进行多次调用,需要给不同的别名,以便来区分每次调用后的输出。大括号里面的input,是将workflow的变量传参到task里, 在workflow里面变量直接调用即可,不需要$和双引号。

scatter
一个流程除了串联,还有并发,这个可以用scatter结合Array来实现。这个特性适用于我们有多个样品或多个文件,并发运行相同的分析,从而有效的节省时间,让DAG更简洁。示例如下:

scatter (i in integers) {
call task1{input: num=i}
call task2{input: num=task1.output}
}

scatter 和for循环不同,它是一种并发关系。在此例中,integers是一个array,调度器会对array里面的元素进行并发处理,而不是一个个循环处理。

if
对变量进行判断,选择性运行某个task。注意这个语法没有else。

if(number!=1) { call task1 {input: num=i} }

其他

import
使用import 可以导入task.wdl 或者sub-workflow.wdl,被workflow直接调用。

import "~/wdl/hello_word.wdl" as hello

sub-workflow
workflow本身可以被另一个workflow import进去,以sub-workflow的形式被调用,可以很方便地作为一个整体去复用。

函数
wdl提供了许多标准的函数来帮助实现简单的读写功能。常用有:

  • stdout():标准输出流
  • stderr():标准错误流
  • read_lines():按行读取,返回array
    其他的见说明

定义struct

struct Person {
    String name
    Int age
    File input1
}

声明:Person a
调用:a.name

使用

WDL可以用cromwell(java) 或者widdler(python)运行,在下载cromwell(https://github.com/broadinstitute/cromwell/releases)时,可以同时下载womtool。womtool可以根据WDL内需要的的input变量生成一个json版的输入文件模板。

输入文件
使用womtools 生成

java -jar womtool-48.jar inputs test.wdl 

即可生成json文件,根据提示的File,Int,Array输入不同的类型的数据:

{
  "task1.inputfile": "new.txt",
  "task1.age": "18",
  "task1.word": "Say hello"
  "task1.samples": ["jia","yi"],
  "task1.info": [{"name":"jia","math":"89"},{"name":"yi","math":"93"}]
}

cromwell简单运行

java -Dconfig.file=test.config -jar cromwell-48.jar run hello_world.wdl -i input.json -o workflow.json

各种配置具体可以查看cromwell官网(https://cromwell.readthedocs.io/en/develop/

-Dconfig.file 流程配置文件(可选)
可以设置一系列配置信息,比如打开断点续跑功能Call Cache。

call-caching {
  enabled = true
  invalidate-bad-cache-results = true
}

run *.wdl 一种运行模式
run模式用于本地测试一个独立的WDL, 不用配置任何信息,简单粗暴,直接运行WDL。另一种模式是server,服务器引擎模式,依赖于环境配置。

-i 输入文件
上面提到的WDL需要的各种参数形成的json文件。

-o workflow 配置文件
可以配置workflow的一下信息,比如最后的目录整理。

{
  "final_workflow_outputs_dir": ""~/Result",
  "use_relative_output_paths": true,
  "final_workflow_log_dir": "~/Log",
  "write_to_cache": true,
  "read_from_cache": true
}

输出结果
输出分为层级,里面包含输入输出,运行脚本,日志,等各种信息记录。

ref

https://github.com/openwdl/wdl/blob/master/versions/1.0/SPEC.md#arrayint-rangeint

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • 前言   一般生物信息分析流程都包含很多的分析步骤,这些步骤之间的联系也有很多情况。例如,流程的步骤中有不少是依赖...
    生信云笔记阅读 3,445评论 0 7
  • WDL (一个workflow description language)+ Cromwell(an execut...
    小七玩数据阅读 2,427评论 1 0
  • 欢迎关注"生信修炼手册"! 在GATK4的best practice中,不再像以前那样给出每个步骤对应的代码,而是...
    生信修炼手册阅读 8,974评论 5 24
  • 官网是用来学习的最好的地方(然而我也没怎么看...)! WDL是什么? WDL是由Broad Institute开...
    生信摆渡阅读 4,400评论 0 5
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,476评论 16 22