频道即使有内容也检查为空

问题描述

我试图让一个仅在满足条件组合的情况下启动的进程,但是当检查通道是否具有文件的路径时,它总是将其返回为空。可能我做错了,在这种情况下,请更正我的代码。我尝试遵循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() != "",但这很脏

按照@Steve的要求,

更新2 ,我已经更新了代码,以反映出我在自己的管道中的实际情况:

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应该更了解不要启动该过程。但我认为在这种构造中,我必须这样做。

Marius

解决方法

我认为这里的部分问题是进程“一个”仅创建了optional outputs。这使得处理过程“三个”中的可选输入有些棘手。如果可能的话,我会尽量调和。如果无法对帐,那么您将需要处理过程“三”中的可选输入。为此,您基本上需要创建一个伪文件,使用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()将把所有值从通道发送到stdout。您可以忽略它返回的任何值。除非您启用DSL2,否则通道将为空。我认为您要在这里找到的是闭包:

_chProcessTwoView.view { "Found: $it" }

请确保将-ansi-log false附加到nextflow run命令中,以免造成输出混乱。 HTH。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...