WDL to Nextflow
Workflow general structure
WDL |
Nextflow |
|---|---|
version <VERSION>
#Processes imported from other diagrams
import “diagram_1” as ext_1
…
#Processes (or tasks) defined in diagram
task task_1 {
##Task body
}
…
#Main workflow
workflow mainWorkflow {
input {
<Type> p_1
…
}
#Workflow body
call task_1 as call_1 { input_1 = value_1, … }
…
expression_1
…
scatter_1 (element in array) {
#Scatter body
}
…
output{
<Type> p_1 = <Expression>
…
}
}
|
//Groovy functions defined in special nextflow document
include { basename; sub; length; ... } from './biouml_function.nf'
//Processes imported from other diagrams
include { ext_process_1 as ext_1 } from './diagram_1'
…
//Default Global workflow inputs
params.p_1
…
//Processes defined in diagram
process_1 {…}
…
//Main workflow
workflow mainWorkflow {
take:
p_1
…
main:
call_1 {…}
expression_1
…
emit:
result_1 = expression_1
…
}
//Entry point workflow
workflow {
mainWorkflow( params.p_1, …, params.p_k )
}
|
Task and Process general structure
WDL |
Nextflow |
|---|---|
task task_name {
input {
<Type> input_1
…
<Type> optional_input_1 = <Expression>
…
}
<Type> variable_1 = <Expression>
…
command {
<Executable script>
}
output {
<Type> output_1 = <Expression>
}
runtime {
<Runtime properties>
}
}
|
process p_1 {
input :
<Type> input_1
…
publishDir "p_1", mode: 'copy'
fair true
script:
variable_1 = <Expression>
…
"""
<Executable script>
"""
output:
path output_1, emit: out_1
…
}
|
Type mapping
# |
WDL |
Nextflow |
|---|---|---|
File, Array[File] |
path |
|
Boolean, String, Integer, Float, Array[Boolean], Array[String], Array[Integer], Array[Float] |
val |
|
Map, Struct, Object |
val |
Imports
# |
Description |
WDL |
Nextflow |
|---|---|---|---|
Import task from other script |
import “script” as ext
...
call ext.task1 as t { … }
|
include { task1 as t } from './script
...
t( … )
|
|
Call imported task twice |
import “script” as ext
…
call ext.task1 as t1 { … }
call ext.task1 as t2 { … }
|
include { task1 as t1 } from './script
include { task1 as t2 } from './script
…
t1( … )
t2( … )
|
|
Import external workflow |
import “script” as ext
call ext.mainWorkflow as alias { … }
|
include { mainWorkflow as alias } from './script
|
Expressions
# |
Description |
WDL |
Nextflow |
|---|---|---|---|
Workflow variable |
~{var_name}
|
${var_name}
|
|
Bash variable |
${var_name}
|
\${var_name}
|
|
Cycle in script |
for file in ~{sep=" " files}
|
for file in ${ files.join() }
|
|
Ternary operator |
~{ if ... then ... else ... }
if ... then ... else ...
|
... ? ... : ...
|
|
Default value |
~{ default="default_value" var }
|
${ var ?: "default_value" }
|
|
Glob in result |
glob("output/file_*.txt")
|
"output/file_*.txt"
|
|
Predefined functions |
basename( file )
sub( input, pattern, replacement )
length( array )
...
|
include { basename; sub; length; ... } from './biouml_function.nf'
basename( file )
sub( input, pattern, replacement )
length(array)
...
|
|
Array element access |
x = array[i]
|
//Use Groovy function, array can be channel
x = get( array, i )
|
Task elements
# |
Description |
WDL |
Nextflow |
|---|---|---|---|
Task metadata |
meta {
description: "text"
}
|
Not supported |
|
Parameters metadata |
parameter_meta {
input_vcf: {
help: “help text”
description: “text”
suggestions: [“v1”,”v2”]
}
}
|
Not supported |
|
Private declarations |
task task1 {
…
<Type> variable = <Value>
…
command { ...
|
process task_name
…
script
variable = <Value>
"""
…
|
|
Runtime options |
runtime {
maxRetries: 3
memory: "N GB"
preemptible: 1
disks: "local-disk ~{disk_size} HDD"
cpu: threads
docker: "image name"
} |
maxRetries 3
memory "4*4 GB"
cpus 4
container 'image_name'
|
|
Optional inputs |
input {
Sting mandatory
String opt = “Default”
}
|
input:
val mandatory
val opt
…
script:
opt = getDefault(opt, “Default”)
"""
…
"""
|
Workflow
# |
Description |
WDL |
Nextflow |
|---|---|---|---|
Two consequent steps |
call task1 as call1 {
input: arg1 = val1
}
call task2 as call2 {
input: arg1 = call1.result,
arg2 = val2
}
|
result_task1 = task1( val1 )
task2( result_task1.result, val2 )
|
|
Calling task with optional inputs |
call task1 {
mandatory = value
#optional = value2
}
|
task1( value , “NO_VALUE”)
|
|
Multiple calls of task defined in the same document |
task task1 {…}
call task1 as t1 { }
call task1 as t2 { }
|
Not supported |
|
Expressions inside if |
if (x > 2) {
Int y = x*2
}
|
y = x.map{ (it>2)? it*2 : null }
|
Cycles
# |
Description |
WDL |
Nextflow |
|---|---|---|---|
Simple cycle |
scatter ( file in files ) {
call task1 { input: arg1 = file }
}
|
file = files
task1( file )
|
|
Cycle in range |
scatter ( i in range(length(С)) ) {
call task1 {
input: arg1 = i }
}
|
//Use Groove functions
i = range( length(С) )
task1( i )
|
|
Expressions in cycle |
scatter ( i in array ) {
Int j = i*2
Int k = i*3
}
|
j = toChannel( array ).map { i -> i*2 }
k = toChannel( array ).map { i -> i*3 }
|
|
Nested cycles |
scatter ( i in array ) {
scatter ( j in array2 ) {
Array[Int] pair = [ i,j ]
}
}
|
pair = toChannel( array ).combine(toChannel(array2)).map{ i,j -> [i,j] }
|
Supplementary functions
# |
Function |
Description |
Code |
|---|---|---|---|
get(arr, i) |
Returns element of arr with index i, arr may be Array or Channel. |
TBA |
|
getDefault(var, Default) |
Returns var or Default if var is not defined. |
TBA |
|
toChannel(arr) |
Creates channel from arr, if arr is channel already does nothing. |
TBA |
WDL functions implemented in Groovy
# |
Function |
TBA |
|---|---|---|
basename(path) |
TBA |
|
sub(input, pattern, replacement) |
TBA |
|
ceil |
TBA |
|
length |
TBA |
|
range |
TBA |
|
select_first |
TBA |
|
select_all |
TBA |
|
defined |
TBA |
|
read_string |
TBA |
|
read_int |
TBA |
|
read_float |
TBA |
Not supported yet
# |
Name |
Description |
|---|---|---|
Comments |
Comments. |