频道检查为空,即使它有内容

channel checks as empty even if it has content

我试图让一个只有在满足条件组合时才启动的进程,但是在检查通道是否有文件路径时,它总是 returns 它是空的。可能我做错了什么,在那种情况下请更正我的代码。我尝试遵循 this issue 中的一些建议,但没有成功。

考虑以下最小示例:

process one {

  output:
    file("test.txt") into _chProcessTwo

  script:
    """
    echo "Hello world" > "test.txt"
    """

}

// making a copy so I check first if something in the channel or not
// avoids raising exception of MultipleInputChannel
_chProcessTwo.into{
  _chProcessTwoView;
  _chProcessTwoCheck;
  _chProcessTwoUse
}

//print contents of channel
println "Channel contents: " + _chProcessTwoView.toList().view()

process two {

  input:
     file(myInput) from _chProcessTwoUse
  when:
     (!_chProcessTwoCheck.toList().isEmpty())

  script:
    def test = _chProcessTwoUse.toList().isEmpty() ? "I'm empty" : "I'm NOT empty"
    println "The outcome is: " + test

}

当且仅当 _chProcessTwo 通道中有一个文件时,我想处理两个 运行。 如果我运行上面的代码我得到:

marius@dev:~/pipeline$ ./bin/nextflow run test.nf 
N E X T F L O W  ~  version 19.09.0-edge
Launching `test.nf` [infallible_gutenberg] - revision: 9f57464dc1
[c8/bf38f5] process > one [100%] 1 of 1 ✔
[-        ] process > two -
[/home/marius/pipeline/work/c8/bf38f595d759686a497bb4a49e9778/test.txt]

最后一行实际上是_chProcessTwoView

的内容

如果我从第二个进程中删除 when 指令,我得到:

marius@mg-dev:~/pipeline$ ./bin/nextflow run test.nf 
N E X T F L O W  ~  version 19.09.0-edge
Launching `test.nf` [modest_descartes] - revision: 5b2bbfea6a
[57/1b7b97] process > one [100%] 1 of 1 ✔
[a9/e4b82d] process > two [100%] 1 of 1 ✔
[/home/marius/pipeline/work/57/1b7b979933ca9e936a3c0bb640c37e/test.txt]

第二个工人 .command.log 文件的内容是:The outcome is: I'm empty

我也试过没有toList()

我做错了什么?提前谢谢你

更新:解决方法是检查_chProcessTwoUse.view() != "",但这很脏

更新 2 根据@Steve 的要求,我更新了代码以更多地反映我自己管道中的实际情况:

def runProcessOne = true

process one {

  when:
    runProcessOne

  output:
    file("inputProcessTwo.txt") into _chProcessTwo optional true
    file("inputProcessThree.txt") into _chProcessThree optional true

  script:
    // this would replace the probability that output is not created
    def outputSomething = false
    """
    if ${outputSomething}; then
       echo "Hello world" > "inputProcessTwo.txt"
       echo "Goodbye world" > "inputProcessThree.txt"
    else
       echo "Sorry. Process one did not write to file."
    fi
    """

}


// making a copy so I check first if something in the channel or not
// avoids raising exception of MultipleInputChannel
_chProcessTwo.into{
  _chProcessTwoView;
  _chProcessTwoCheck;
  _chProcessTwoUse
}

//print contents of channel
println "Channel contents: " + _chProcessTwoView.view()
println _chProcessTwoView.view() ? "Me empty" : "NOT empty"

process two {

  input:
     file(myInput) from _chProcessTwoUse
  when:
     (runProcessOne) 

  script:
    """
    echo "The outcome is:  ${myInput}"
    """
}


process three {

   input:
       file(defaultInput) from _chUpstreamProcesses
       file(inputFromProcessTwo) from _chProcessThree

   script:
      def extra_parameters = _chProcessThree.isEmpty() ? "" : "--extra-input " + inputFromProcessTwo
      """
        echo "Hooray! We got: ${extra_parameters}"
      """
}

正如@Steve 提到的,我什至不应该检查通道是否为空,NextFlow 应该知道最好不要启动该过程。但我认为在这个结构中我将不得不这样做。

马吕斯

我认为这里的部分问题是进程 'one' 仅创建 optional outputs. This makes dealing with the optional inputs in process 'three' a bit tricky. I would try to reconcile this if possible. If this can't be reconciled, then you'll need to deal with the optional inputs in process 'three'. To do this, you'll basically need to create a dummy file, pass it into the channel using the ifEmpty 运算符,然后使用虚拟文件的名称来检查是否在参数的前缀前加上。这有点 hack,但效果很好。

第一步是实际创建虚拟文件。我喜欢可共享的管道,所以我会在您的 baseDir 中创建它,也许在名为 'assets':

的文件夹下
mkdir assets
touch assets/NO_FILE

如果您的“_chProcessThree”频道为空,则传入您的虚拟文件:

params.dummy_file = "${baseDir}/assets/NO_FILE"

dummy_file = file(params.dummy_file)


process three {

    input:
    file(defaultInput) from _chUpstreamProcesses
    file(optfile) from _chProcessThree.ifEmpty(dummy_file)

    script:
    def extra_parameters = optfile.name != 'NO_FILE' ? "--extra-input ${optfile}" : ''

    """
    echo "Hooray! We got: ${extra_parameters}"
    """
}

此外,这些行有问题:

//print contents of channel
println "Channel contents: " + _chProcessTwoView.view()
println _chProcessTwoView.view() ? "Me empty" : "NOT empty"

调用 view() 会将通道中的所有值发送到标准输出。您可以忽略它的任何值 returns。除非您启用 DSL2,否则频道将是空的。我认为您在这里寻找的是闭包:

_chProcessTwoView.view { "Found: $it" }

请务必将 -ansi-log false 附加到您的 nextflow run 命令,以免输出被破坏。 HTH.