@pditommaso thank you for introducing this experimental feature.
In case anyone is also interested in recursing a subworkflow, here is a template based on the work-around as above thanks to all the help from @bentsherman. The key point is putting the list of inputs in one channel, then extract the elements using .map {it[n-1]}
in the subworkflow.
*Caution: if it runs with single loop but not with .recurse() and the next process in the subflow just don't start, it might be due to FUNCTION.out.collect()
. Removing .collect()
could solve the problem in my case.
*tested on nextflow version 22.10.2.5832
(1)1loop.nf (the subworkflow)
// Enable DSL2 functionality
nextflow.enable.dsl = 2
//nextflow.preview.recursion=true // does not help
// Workflow definition
workflow ONELOOP {
take:
inputs4
main:
a = inputs4.map { it[0] }.view{}
b = inputs4.map { it[1] }.view{}
c = inputs4.map { it[2] }.view{}
d = inputs4.map { it[3] }.view{}
FUNCTION(a, b, d)
FUNCTION2(FUNCTION.out.a, c)
//put them in the same tuple
a =FUNCTION.out.a
inputs4 = a.merge(FUNCTION.out.b, FUNCTION2.out.c2, d) //.view()
emit:
inputs4
}
//------------------------------------
// Process definition
process FUNCTION {
//publishDir params.taxonomy_cmd, mode: "copy"
input:
path a
val b
val d
output:
path a1, emit: a
env b1, emit: b
script:
"""
cat $a > out_a
echo "what" >> out_a
mv out_a a1
b1=\$(($b+$b))
"""
}
process FUNCTION2 {
input:
path a1
val c
output:
path a2, emit: a2
env c2, emit: c2
script:
"""
cat $a1 > out_a
echo "what2" >> out_a
mv out_a a2
c2="changed"$c
"""
}
(2) 2recur.nf (the main workflow)
// Enable DSL2 functionality and recurse
nextflow.enable.dsl = 2
nextflow.preview.recursion=true
// include the subworkflow
include {ONELOOP} from './1loop.nf'
workflow {
main:
a=Channel.of(params.a)
b=Channel.value(params.b)
c=Channel.value(params.c)
d=Channel.value(params.d)
inputs4 = a.merge(b, c, d)
// workflow =================
ONELOOP.recurse(inputs4.collect()).times(3)
//ONELOOP.recurse(inputs4.collect()).until{ inputs4 -> inputs4[1] == '16' } //until stops the loop from running if the input fits the condition
}
(3) nextflow.config
params {
a = ""
b = ""
c = ""
d = ""
}
Originally posted by @Amend-1634 in https://github.com/nextflow-io/nextflow/issues/2609#issuecomment-1474880001