1

我试图让一个进程仅在满足条件组合时启动,但是在检查通道是否具有文件路径时,它总是将其返回为空。可能我做错了什么,在这种情况下,请更正我的代码。我试图遵循这个问题中的一些建议,但没有成功。

考虑以下最小示例:

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 应该更好地知道不启动该过程。但我认为在这个结构中我将不得不这样做。

马吕斯

4

1 回答 1

1

我认为这里的部分问题是进程“一个”只创建可选输出。这使得处理“三”进程中的可选输入有点棘手。如果可能的话,我会尝试调和这一点。如果这无法协调,那么您将需要处理进程“三”中的可选输入。为此,您基本上需要创建一个虚拟文件,使用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()会将所有值从通道发送到标准输出。您可以忽略它返回的任何值。除非您启用 DSL2,否则该通道将为空。我认为你在这里寻找的是一个闭包:

_chProcessTwoView.view { "Found: $it" }

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

于 2020-10-01T12:41:51.387 回答