Nextflow:publishDir、输出通道和输出子目录

Nextflow: publishDir, output channels, and output subdirectories

我一直在尝试学习如何使用 Nextflow 并遇到了将输出添加到通道的问题,因为我需要按顺序 运行 处理流程。我想将输出文件从工具 (ONT-Guppy) 创建的输出子目录之一传递到通道中,但似乎无法弄清楚如何。

这是有问题的下一个流程:

process GupcallBases {
    publishDir "$params.P1_outDir", mode: 'copy', pattern: "pass/*.bam"
    
    executor = 'pbspro'
    clusterOptions = "-lselect=1:ncpus=${params.P1_threads}:mem=${params.P1_memory}:ngpus=1:gpu_type=${params.P1_GPU} -lwalltime=${params.P1_walltime}:00:00"
     
    output:
    path "*.bam" into bams_ch
            
    script:
    """
    module load cuda/11.4.2
    singularity exec --nv $params.Gup_container \
            guppy_basecaller --config $params.P1_gupConf \
            --device "cuda:0" \
            --bam_out \
            --recursive \
            --compress \
            --align_ref $params.refGen \
            -i $params.P1_inDir \
            -s $params.P1_outDir \
            --gpu_runners_per_device $params.P1_GPU_runners \
            --num_callers $params.P1_callers
    """
}

过程的输出是这样的:

$params.P1_outDir/pass/(lots of bams and fastqs)
$params.P1_outDir/fail/(lots of bams and fastqs)
$params.P1_outDir/(a few txt and log files)

我只想将 bam 文件保留在 $params.P1_outDir/pass/ 中,因此尝试使用 pattern = "pass/*.bam,但我尝试了一些其他模式都无济于事。

选择输出语法是因为完成此过程后,将使用以下通道工作:

//    Channel
//      .fromPath("${params.P1_outDir}/pass/*.bam")
//      .ifEmpty { error "Cannot find any bam files in ${params.P1_outDir}" }
//      .set { bams_ch }

但问题是,如果我不将文件传递到第一个进程的输出通道,它们将 运行 并行。我可能只是在有关如何订购流程的大量文档中遗漏了一些内容,这将是一个替代解决方案。

编辑: 我放弃在此处添加错误消息:Missing output file(s) `*.bam` expected by process `GupcallBases` 并且 $params.P1_outDir/ 包含子目录和所有日志文件,尽管模式参数。

提前致谢。

Nextflow 进程被设计为 运行 彼此隔离,但是当使用 params 指定命令行输入 and/or 输出时,可以稍微规避这一点。像这样使用 params 可能会有问题,因为例如,如果 params 变量指定了绝对路径,但您的输出声明需要 Nextflow 工作目录中的文件(例如 ./work/fc/0249e72585c03d08e31ce154b6d873),您将得到 'Missing output file(s) expected by process' 错误你看到了。

解决方案是使用 input declaration block and that the outputs are also written to the work dir. Note that only files specified in the output declaration block can be published using the publishDir 指令确保您的输入在工作目录中本地化。

此外,最好避免调用 Singularity manually in your script block. Instead just add singularity.enabled = true to your nextflow.config. This should also work nicely with the beforeScript 进程指令来初始化您的环境:

params.publishDir = './results'

input_dir = file( params.input_dir )
guppy_config = file( params.guppy_config )
ref_genome = file( params.ref_genome )
process GuppyBasecaller {

    publishDir(
        path: "${params.publishDir}/GuppyBasecaller",
        mode: 'copy',
        saveAs: { fn -> fn.substring(fn.lastIndexOf('/')+1) },
    )
    beforeScript 'module load cuda/11.4.2; export SINGULARITY_NV=1'
    container '/path/to/guppy_basecaller.img'

    input:
    path input_dir
    path guppy_config
    path ref_genome

    output:
    path "outdir/pass/*.bam" into bams_ch

    """
    mkdir outdir
    guppy_basecaller \
        --config "${guppy_config}" \
        --device "cuda:0" \
        --bam_out \
        --recursive \
        --compress \
        --align_ref "${ref_genome}" \
        -i "${input_dir}" \
        -s outdir \
        --gpu_runners_per_device "${params.guppy_gpu_runners}" \
        --num_callers "${params.guppy_callers}"
    """
}