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.