NextFlow:如果通道为空,如何失败(.ifEmpty())



如果特定的channel为空,我希望我的NextFlow管道失败,因为按原样,管道将继续运行,就像没有任何问题一样,但取决于通道的进程永远不会启动。一篇相关文章的答案是,我们通常不应该检查channel是否为空,但我不知道该如何处理。

在下面的例子中,我遇到的问题是它总是失败,但如果我注释掉.ifEmpty()语句,就会调用该过程。

这里有一个基本的例子:

/*
* There are .cram files in this folder
*/
params.input_sample_folder = 'path/to/folder/*' 
samples = Channel.fromPath(params.input_sample_folder, checkIfExists: true)
.filter( ~/.*(.sam|.bam|.cram)/ )
.ifEmpty( exit 1,
"ERROR: Did not find any samples in ${params.input_sample_folder})
workflow{
PROCESS_SAMPLES( samples )
}

终极问题

  1. 我的猜测是channel不会立即填充。这是真的吗?如果是,它什么时候填充
  2. 我应该如何处理这种情况?如果通道没有填充,我想失败。例如,我惊讶地发现,如果我只提供一个没有glob/通配符的文件夹路径(/path/to/folder/;没有**.cram等(,则通道仍然是空的。我认为我无法在进程本身中处理它,因为如果channel合法为空,则进程永远不会被调用

非常感谢您的帮助。

如果文件系统中不存在指定的文件,则设置checkIfExists: true实际上会为您抛出异常。诀窍是在创建通道时指定所需的文件,而不是在下游进行过滤。例如,您只需要:

params.input_sample_folder = 'path/to/folder'
samples = Channel.fromPath(
"${params.input_sample_folder}/*.{sam,bam,cram}",
checkIfExists: true,
)

或者可以说更好;因为这让用户可以完全控制输入文件:

params.input_sample_files = 'path/to/folder/*.{sam,bam,cram}'
samples = Channel.fromPath( params.input_sample_files, checkIfExists: true )

无论哪种方式,当不存在匹配的文件时,两者都会使您的管道失败,退出状态为1,并以红色显示以下消息:

No files match pattern `*.{sam,bam,cram}` at path: path/to/folder/

根据文档,ifEmpty操作符实际上只是用于在通道变空时发出默认值。为了避免检查通道是否为空,一般的解决方案是首先避免创建空通道。有很多方法可以做到这一点,但有一种方法可能看起来像:

import org.apache.log4j.Logger
nextflow.enable.dsl=2

def find_sample_files( input_dir ) {
def pattern = ~/.*(.sam|.bam|.cram)/
def results = []
input_dir.eachFileMatch(pattern) { item ->
results.add( item )
}
return results
}

params.input_sample_folder = 'path/to/folder'
workflow {
input_sample_folder = file( params.input_sample_folder )
input_sample_files = find_sample_files( input_sample_folder )
if ( !input_sample_files ) {
log.error("ERROR: Did not find any samples in ${params.input_sample_folder}")
System.exit(1)
}
sample_files = Channel.of( input_sample_files )
sample_files.view()
}

最新更新