Step 19 - Use a closure
We mentioned that there are 2 ways to pass an output filename to a process
. There is a third one, using a closure or function to handle the naming for us.
Let us illustrate this with an example again:
// Step - 19
def out_from_in = { it -> it.baseName + "-out.txt" }
process process_step19 {
publishDir "output"
input:
tuple val(id), file(input), val(config)
output:
tuple val("${id}"), file("${out}"), val("${config}")
script:
out = out_from_in(input)
"""
a=`cat $input`
let result="\$a + ${config.term}"
echo "\$result" > ${out}
"""
}
workflow step19 {
Channel.fromPath( params.input ) \
| map{ el -> [
el.baseName.toString(),
el,
[
"id": el.baseName,
"operator" : "-",
"term" : 10
]
]} \
| process_step19 \
| view{ [ it[0], it[1] ] }
}
The result is as follows:
> nextflow -q run . -entry step19
WARN: DSL 2 IS AN EXPERIMENTAL FEATURE UNDER DEVELOPMENT -- SYNTAX MAY CHANGE IN FUTURE RELEASE
[input2, <...>/work/a3/2c69f0be071c1e2170a19f6f397dda/input2-out.txt]
[input3, <...>/work/0a/e2dc41121ad3b619348d3abc985839/input3-out.txt]
[input1, <...>/work/04/18d42a25a1923a3ff15cf5f6a7aae8/input1-out.txt]
We can even add the closure to the configuration map sent to the process
, but NextFlow complains that this is not serializable so you may miss some features and most importantly it may not work at all times:
WARN: Cannot serialize context map. Cause: java.lang.IllegalArgumentException: Unknown workflow parameter definition: map -- Resume will not work on this process
This approach may seem like completely over-engineered but for a lot of use-cases it turns out to be a good fit. Although, not in the way we introduced it here. We come back to that later…
A DiFlow module contains a function definition that takes the input file name as input and generates an output filename.