WDL best practice for alternate tasks

myourshawmyourshaw University of ColoradoMember ✭✭

I want to do something like this, where a step involves calling one of two tasks, either of which will produce the same type of outputs for downstream processing:

workflow WF {
    String? illumina
    String? fastqs

    if(defined(illumina)) {
        call Illumina {
            inputs: ...

    if(defined(fastqs) && !defined(illumina)) {
        call Fastqs {
            inputs: ...

   # either Illumina.ubams or Fastqs.ubams will be [Array[Array[File]]
    scatter (ubams in if illumina then Illumina.ubams else Fastqs.ubams {
        call ProcesUbams {
                ubams = ubams,
                adapters = if defined(illumina) then Illumina.adapters else Fastqs.adapters,
    }  # scatter
}  # WF

Code like the above will give an error similar to:

Unable to build WOM node for Scatter '$scatter_0': Cannot scatter over a non-traversable type Array[Array[File]]?

What is the best way in WDL to implement this sort of logic?


Best Answers


  • Do you know exactly where your workflow fails? I often first make a minimal workflow if I run into a problem so I'm sure where the problem lies. If you are only having problems with the scatter, you can use select_first to assign both Illumina and Fastqs outputs to the same variable.

    Array[File] ubams = select_first([Illumina.ubams, Fastqs.ubams])

    Afterwards, you can scatter over ubams

  • myourshawmyourshaw University of ColoradoMember ✭✭

    Thanks! select_first was exactly what I needed.

Sign In or Register to comment.