问题描述
我试图让一个仅在满足条件组合的情况下启动的进程,但是当检查通道是否具有文件的路径时,它总是将其返回为空。可能我做错了,在这种情况下,请更正我的代码。我尝试遵循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 ,我已经更新了代码,以反映出我在自己的管道中的实际情况:
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。