@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

0
© 2022 pullanswer.com - All rights reserved.