From e5dbadeb337684b81cf8bedbe95c437ba3ed78f3 Mon Sep 17 00:00:00 2001 From: Ben Sherman Date: Mon, 22 Dec 2025 20:18:16 -0600 Subject: [PATCH 1/6] Migrate to Nextflow 25.10 --- main.nf | 13 ++-- modules/nf-core/bedtools/intersect/main.nf | 2 +- modules/nf-core/bismark/align/main.nf | 2 +- .../nf-core/bismark/coverage2cytosine/main.nf | 2 +- modules/nf-core/bismark/deduplicate/main.nf | 2 +- .../nf-core/bismark/genomepreparation/main.nf | 2 +- .../bismark/methylationextractor/main.nf | 2 +- modules/nf-core/bismark/report/main.nf | 2 +- modules/nf-core/bismark/summary/main.nf | 2 +- modules/nf-core/bwameth/align/main.nf | 2 +- modules/nf-core/bwameth/index/main.nf | 2 +- modules/nf-core/cat/fastq/main.nf | 2 +- modules/nf-core/fastqc/main.nf | 2 +- modules/nf-core/gunzip/main.nf | 2 +- modules/nf-core/methyldackel/extract/main.nf | 2 +- modules/nf-core/methyldackel/mbias/main.nf | 2 +- modules/nf-core/multiqc/main.nf | 2 +- modules/nf-core/parabricks/fq2bammeth/main.nf | 2 +- .../nf-core/picard/bedtointervallist/main.nf | 2 +- .../nf-core/picard/collecthsmetrics/main.nf | 2 +- .../picard/createsequencedictionary/main.nf | 2 +- modules/nf-core/picard/markduplicates/main.nf | 2 +- modules/nf-core/preseq/lcextrap/main.nf | 2 +- modules/nf-core/qualimap/bamqc/main.nf | 2 +- modules/nf-core/qualimap/bamqccram/main.nf | 2 +- modules/nf-core/samtools/faidx/main.nf | 2 +- modules/nf-core/samtools/flagstat/main.nf | 2 +- modules/nf-core/samtools/index/main.nf | 2 +- modules/nf-core/samtools/sort/main.nf | 2 +- modules/nf-core/samtools/stats/main.nf | 2 +- modules/nf-core/trimgalore/main.nf | 2 +- modules/nf-core/untar/main.nf | 2 +- nextflow.config | 2 +- .../local/targeted_sequencing/main.nf | 8 +-- .../utils_nfcore_methylseq_pipeline/main.nf | 2 - .../fasta_index_bismark_bwameth/main.nf | 16 ++--- .../nf-core/fastq_align_dedup_bismark/main.nf | 36 ++++------- .../nf-core/fastq_align_dedup_bwameth/main.nf | 30 +++------- .../nf-core/utils_nfcore_pipeline/main.nf | 2 +- workflows/methylseq/main.nf | 60 ++++++++----------- 40 files changed, 89 insertions(+), 142 deletions(-) diff --git a/main.nf b/main.nf index 85bb57734..123d734b2 100644 --- a/main.nf +++ b/main.nf @@ -47,15 +47,14 @@ workflow NFCORE_METHYLSEQ { main: - ch_versions = Channel.empty() // // Initialize file channels or values based on params // - ch_fasta = params.fasta ? Channel.fromPath(params.fasta).map{ it -> [ [id:it.baseName], it ] } : Channel.empty() - ch_or_val_fasta_index = params.fasta_index ? Channel.fromPath(params.fasta_index).map{ it -> [ [id:it.baseName], it ] } : [] - ch_or_val_bismark_index = params.bismark_index ? Channel.fromPath(params.bismark_index).map{ it -> [ [id:it.baseName], it ] } : [] - ch_or_val_bwameth_index = params.bwameth_index ? Channel.fromPath(params.bwameth_index).map{ it -> [ [id:it.baseName], it ] } : [] + ch_fasta = params.fasta ? channel.fromPath(params.fasta).map{ it -> [ [id:it.baseName], it ] } : channel.empty() + ch_or_val_fasta_index = params.fasta_index ? channel.fromPath(params.fasta_index).map{ it -> [ [id:it.baseName], it ] } : [] + ch_or_val_bismark_index = params.bismark_index ? channel.fromPath(params.bismark_index).map{ it -> [ [id:it.baseName], it ] } : [] + ch_or_val_bwameth_index = params.bwameth_index ? channel.fromPath(params.bwameth_index).map{ it -> [ [id:it.baseName], it ] } : [] // // SUBWORKFLOW: Prepare any required reference genome indices @@ -69,7 +68,6 @@ workflow NFCORE_METHYLSEQ { params.collecthsmetrics, params.use_mem2 ) - ch_versions = ch_versions.mix(FASTA_INDEX_BISMARK_BWAMETH.out.versions) // // WORKFLOW: Run pipeline @@ -77,17 +75,14 @@ workflow NFCORE_METHYLSEQ { METHYLSEQ ( samplesheet, - ch_versions, FASTA_INDEX_BISMARK_BWAMETH.out.fasta, FASTA_INDEX_BISMARK_BWAMETH.out.fasta_index, FASTA_INDEX_BISMARK_BWAMETH.out.bismark_index, FASTA_INDEX_BISMARK_BWAMETH.out.bwameth_index, ) - ch_versions = ch_versions.mix(METHYLSEQ.out.versions) emit: multiqc_report = METHYLSEQ.out.multiqc_report // channel: [ path(multiqc_report.html ) ] - versions = ch_versions // channel: [ path(versions.yml) ] } /* diff --git a/modules/nf-core/bedtools/intersect/main.nf b/modules/nf-core/bedtools/intersect/main.nf index d9e79e7fa..c8cde91f9 100644 --- a/modules/nf-core/bedtools/intersect/main.nf +++ b/modules/nf-core/bedtools/intersect/main.nf @@ -13,7 +13,7 @@ process BEDTOOLS_INTERSECT { output: tuple val(meta), path("*.${extension}"), emit: intersect - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/bismark/align/main.nf b/modules/nf-core/bismark/align/main.nf index b367a0719..f035bcd40 100644 --- a/modules/nf-core/bismark/align/main.nf +++ b/modules/nf-core/bismark/align/main.nf @@ -16,7 +16,7 @@ process BISMARK_ALIGN { tuple val(meta), path("*bam") , emit: bam tuple val(meta), path("*report.txt"), emit: report tuple val(meta), path("*fq.gz") , emit: unmapped, optional: true - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/bismark/coverage2cytosine/main.nf b/modules/nf-core/bismark/coverage2cytosine/main.nf index c1e3a7b48..65ce57179 100644 --- a/modules/nf-core/bismark/coverage2cytosine/main.nf +++ b/modules/nf-core/bismark/coverage2cytosine/main.nf @@ -16,7 +16,7 @@ process BISMARK_COVERAGE2CYTOSINE { tuple val(meta), path("*.cov.gz") , emit: coverage, optional: true tuple val(meta), path("*report.txt.gz") , emit: report tuple val(meta), path("*cytosine_context_summary.txt") , emit: summary - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/bismark/deduplicate/main.nf b/modules/nf-core/bismark/deduplicate/main.nf index 436291711..3671ea7f0 100644 --- a/modules/nf-core/bismark/deduplicate/main.nf +++ b/modules/nf-core/bismark/deduplicate/main.nf @@ -13,7 +13,7 @@ process BISMARK_DEDUPLICATE { output: tuple val(meta), path("*.deduplicated.bam") , emit: bam tuple val(meta), path("*.deduplication_report.txt"), emit: report - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/bismark/genomepreparation/main.nf b/modules/nf-core/bismark/genomepreparation/main.nf index 9794084ea..c0efd03c1 100644 --- a/modules/nf-core/bismark/genomepreparation/main.nf +++ b/modules/nf-core/bismark/genomepreparation/main.nf @@ -12,7 +12,7 @@ process BISMARK_GENOMEPREPARATION { output: tuple val(meta), path("BismarkIndex"), emit: index - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/bismark/methylationextractor/main.nf b/modules/nf-core/bismark/methylationextractor/main.nf index 94c9e1349..574953b2f 100644 --- a/modules/nf-core/bismark/methylationextractor/main.nf +++ b/modules/nf-core/bismark/methylationextractor/main.nf @@ -17,7 +17,7 @@ process BISMARK_METHYLATIONEXTRACTOR { tuple val(meta), path("*.cov.gz") , emit: coverage tuple val(meta), path("*_splitting_report.txt"), emit: report tuple val(meta), path("*.M-bias.txt") , emit: mbias - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/bismark/report/main.nf b/modules/nf-core/bismark/report/main.nf index c95bae995..92dda5349 100644 --- a/modules/nf-core/bismark/report/main.nf +++ b/modules/nf-core/bismark/report/main.nf @@ -12,7 +12,7 @@ process BISMARK_REPORT { output: tuple val(meta), path("*report.{html,txt}"), emit: report - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/bismark/summary/main.nf b/modules/nf-core/bismark/summary/main.nf index a8a0a83e2..1855a0b61 100644 --- a/modules/nf-core/bismark/summary/main.nf +++ b/modules/nf-core/bismark/summary/main.nf @@ -15,7 +15,7 @@ process BISMARK_SUMMARY { output: path("*report.{html,txt}"), emit: summary - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/bwameth/align/main.nf b/modules/nf-core/bwameth/align/main.nf index d63061fc7..b318c2da2 100644 --- a/modules/nf-core/bwameth/align/main.nf +++ b/modules/nf-core/bwameth/align/main.nf @@ -14,7 +14,7 @@ process BWAMETH_ALIGN { output: tuple val(meta), path("*.bam"), emit: bam - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/bwameth/index/main.nf b/modules/nf-core/bwameth/index/main.nf index 314a8874f..41bd9c829 100644 --- a/modules/nf-core/bwameth/index/main.nf +++ b/modules/nf-core/bwameth/index/main.nf @@ -13,7 +13,7 @@ process BWAMETH_INDEX { output: tuple val(meta), path("BwamethIndex"), emit: index - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/cat/fastq/main.nf b/modules/nf-core/cat/fastq/main.nf index acfb6d0e6..7cd75ff80 100644 --- a/modules/nf-core/cat/fastq/main.nf +++ b/modules/nf-core/cat/fastq/main.nf @@ -12,7 +12,7 @@ process CAT_FASTQ { output: tuple val(meta), path("*.merged.fastq.gz"), emit: reads - path "versions.yml", emit: versions + path "versions.yml", topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/fastqc/main.nf b/modules/nf-core/fastqc/main.nf index 23e16634c..31fbeb3b9 100644 --- a/modules/nf-core/fastqc/main.nf +++ b/modules/nf-core/fastqc/main.nf @@ -13,7 +13,7 @@ process FASTQC { output: tuple val(meta), path("*.html"), emit: html tuple val(meta), path("*.zip") , emit: zip - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/gunzip/main.nf b/modules/nf-core/gunzip/main.nf index 3ffc8e926..7f6296bf9 100644 --- a/modules/nf-core/gunzip/main.nf +++ b/modules/nf-core/gunzip/main.nf @@ -12,7 +12,7 @@ process GUNZIP { output: tuple val(meta), path("${gunzip}"), emit: gunzip - path "versions.yml", emit: versions + path "versions.yml", topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/methyldackel/extract/main.nf b/modules/nf-core/methyldackel/extract/main.nf index 66b2745a6..8ea814a6a 100644 --- a/modules/nf-core/methyldackel/extract/main.nf +++ b/modules/nf-core/methyldackel/extract/main.nf @@ -15,7 +15,7 @@ process METHYLDACKEL_EXTRACT { output: tuple val(meta), path("*.bedGraph") , optional: true, emit: bedgraph tuple val(meta), path("*.methylKit"), optional: true, emit: methylkit - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/methyldackel/mbias/main.nf b/modules/nf-core/methyldackel/mbias/main.nf index f0c48a34a..b452e155f 100644 --- a/modules/nf-core/methyldackel/mbias/main.nf +++ b/modules/nf-core/methyldackel/mbias/main.nf @@ -14,7 +14,7 @@ process METHYLDACKEL_MBIAS { output: tuple val(meta), path("*.mbias.txt"), emit: txt - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index a508541ba..fc7be46c8 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -18,7 +18,7 @@ process MULTIQC { path "*multiqc_report.html", emit: report path "*_data" , emit: data path "*_plots" , optional:true, emit: plots - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/parabricks/fq2bammeth/main.nf b/modules/nf-core/parabricks/fq2bammeth/main.nf index 456413af3..eb0fab1d0 100644 --- a/modules/nf-core/parabricks/fq2bammeth/main.nf +++ b/modules/nf-core/parabricks/fq2bammeth/main.nf @@ -17,7 +17,7 @@ process PARABRICKS_FQ2BAMMETH { path("qc_metrics") , emit: qc_metrics, optional:true path("*.table") , emit: bqsr_table, optional:true path("duplicate-metrics.txt") , emit: duplicate_metrics, optional:true - path("versions.yml") , emit: versions + path("versions.yml") , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/picard/bedtointervallist/main.nf b/modules/nf-core/picard/bedtointervallist/main.nf index 38c2eee7e..0be1f08d8 100644 --- a/modules/nf-core/picard/bedtointervallist/main.nf +++ b/modules/nf-core/picard/bedtointervallist/main.nf @@ -14,7 +14,7 @@ process PICARD_BEDTOINTERVALLIST { output: tuple val(meta), path('*.intervallist'), emit: intervallist - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/picard/collecthsmetrics/main.nf b/modules/nf-core/picard/collecthsmetrics/main.nf index 1d017ef8d..63571a716 100644 --- a/modules/nf-core/picard/collecthsmetrics/main.nf +++ b/modules/nf-core/picard/collecthsmetrics/main.nf @@ -15,7 +15,7 @@ process PICARD_COLLECTHSMETRICS { output: tuple val(meta), path("*_metrics") , emit: metrics - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/picard/createsequencedictionary/main.nf b/modules/nf-core/picard/createsequencedictionary/main.nf index 49637d184..8ec627cb9 100644 --- a/modules/nf-core/picard/createsequencedictionary/main.nf +++ b/modules/nf-core/picard/createsequencedictionary/main.nf @@ -12,7 +12,7 @@ process PICARD_CREATESEQUENCEDICTIONARY { output: tuple val(meta), path("*.dict"), emit: reference_dict - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/picard/markduplicates/main.nf b/modules/nf-core/picard/markduplicates/main.nf index 8a2ed64e6..04aac47d3 100644 --- a/modules/nf-core/picard/markduplicates/main.nf +++ b/modules/nf-core/picard/markduplicates/main.nf @@ -17,7 +17,7 @@ process PICARD_MARKDUPLICATES { tuple val(meta), path("*.bai") , emit: bai, optional: true tuple val(meta), path("*.cram"), emit: cram, optional: true tuple val(meta), path("*.metrics.txt"), emit: metrics - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/preseq/lcextrap/main.nf b/modules/nf-core/preseq/lcextrap/main.nf index 540a5fb27..b91770833 100644 --- a/modules/nf-core/preseq/lcextrap/main.nf +++ b/modules/nf-core/preseq/lcextrap/main.nf @@ -14,7 +14,7 @@ process PRESEQ_LCEXTRAP { output: tuple val(meta), path("*.lc_extrap.txt"), emit: lc_extrap tuple val(meta), path("*.log") , emit: log - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/qualimap/bamqc/main.nf b/modules/nf-core/qualimap/bamqc/main.nf index 8140e143e..98dffcdbe 100644 --- a/modules/nf-core/qualimap/bamqc/main.nf +++ b/modules/nf-core/qualimap/bamqc/main.nf @@ -13,7 +13,7 @@ process QUALIMAP_BAMQC { output: tuple val(meta), path("${prefix}"), emit: results - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/qualimap/bamqccram/main.nf b/modules/nf-core/qualimap/bamqccram/main.nf index 81e1a485e..9ace6faa7 100644 --- a/modules/nf-core/qualimap/bamqccram/main.nf +++ b/modules/nf-core/qualimap/bamqccram/main.nf @@ -15,7 +15,7 @@ process QUALIMAP_BAMQCCRAM { output: tuple val(meta), path("${prefix}"), emit: results - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/samtools/faidx/main.nf b/modules/nf-core/samtools/faidx/main.nf index 6de0095d8..db58d63ab 100644 --- a/modules/nf-core/samtools/faidx/main.nf +++ b/modules/nf-core/samtools/faidx/main.nf @@ -17,7 +17,7 @@ process SAMTOOLS_FAIDX { tuple val(meta), path ("*.sizes") , emit: sizes, optional: true tuple val(meta), path ("*.fai") , emit: fai, optional: true tuple val(meta), path ("*.gzi") , emit: gzi, optional: true - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/samtools/flagstat/main.nf b/modules/nf-core/samtools/flagstat/main.nf index c23f3a5cf..f79d01c48 100644 --- a/modules/nf-core/samtools/flagstat/main.nf +++ b/modules/nf-core/samtools/flagstat/main.nf @@ -12,7 +12,7 @@ process SAMTOOLS_FLAGSTAT { output: tuple val(meta), path("*.flagstat"), emit: flagstat - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/samtools/index/main.nf b/modules/nf-core/samtools/index/main.nf index 7019a72e4..310c3db55 100644 --- a/modules/nf-core/samtools/index/main.nf +++ b/modules/nf-core/samtools/index/main.nf @@ -14,7 +14,7 @@ process SAMTOOLS_INDEX { tuple val(meta), path("*.bai") , optional:true, emit: bai tuple val(meta), path("*.csi") , optional:true, emit: csi tuple val(meta), path("*.crai"), optional:true, emit: crai - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/samtools/sort/main.nf b/modules/nf-core/samtools/sort/main.nf index caf3c61a8..f26b3d460 100644 --- a/modules/nf-core/samtools/sort/main.nf +++ b/modules/nf-core/samtools/sort/main.nf @@ -16,7 +16,7 @@ process SAMTOOLS_SORT { tuple val(meta), path("*.cram"), emit: cram, optional: true tuple val(meta), path("*.crai"), emit: crai, optional: true tuple val(meta), path("*.csi"), emit: csi, optional: true - path "versions.yml", emit: versions + path "versions.yml", topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/samtools/stats/main.nf b/modules/nf-core/samtools/stats/main.nf index 4443948b7..157244b8e 100644 --- a/modules/nf-core/samtools/stats/main.nf +++ b/modules/nf-core/samtools/stats/main.nf @@ -13,7 +13,7 @@ process SAMTOOLS_STATS { output: tuple val(meta), path("*.stats"), emit: stats - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/trimgalore/main.nf b/modules/nf-core/trimgalore/main.nf index 5fe53669f..cc6a5d00e 100644 --- a/modules/nf-core/trimgalore/main.nf +++ b/modules/nf-core/trimgalore/main.nf @@ -16,7 +16,7 @@ process TRIMGALORE { tuple val(meta), path("*unpaired{,_1,_2}.fq.gz") , emit: unpaired, optional: true tuple val(meta), path("*.html") , emit: html, optional: true tuple val(meta), path("*.zip") , emit: zip, optional: true - path "versions.yml" , emit: versions + path "versions.yml" , topic: versions when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/untar/main.nf b/modules/nf-core/untar/main.nf index e712ebe63..1ea3945c1 100644 --- a/modules/nf-core/untar/main.nf +++ b/modules/nf-core/untar/main.nf @@ -12,7 +12,7 @@ process UNTAR { output: tuple val(meta), path("${prefix}"), emit: untar - path "versions.yml", emit: versions + path "versions.yml", topic: versions when: task.ext.when == null || task.ext.when diff --git a/nextflow.config b/nextflow.config index 2bf94045f..4436e6c9e 100644 --- a/nextflow.config +++ b/nextflow.config @@ -396,7 +396,7 @@ manifest { // Nextflow plugins plugins { - id 'nf-schema@2.4.2' // Validation of pipeline parameters and creation of an input channel from a sample sheet + id 'nf-schema@2.6.1' // Validation of pipeline parameters and creation of an input channel from a sample sheet } validation { diff --git a/subworkflows/local/targeted_sequencing/main.nf b/subworkflows/local/targeted_sequencing/main.nf index 78bbf72a2..dee16932f 100644 --- a/subworkflows/local/targeted_sequencing/main.nf +++ b/subworkflows/local/targeted_sequencing/main.nf @@ -24,8 +24,7 @@ workflow TARGETED_SEQUENCING { main: - ch_versions = Channel.empty() - ch_picard_metrics = Channel.empty() + ch_picard_metrics = channel.empty() /* * Intersect bedGraph files with target regions @@ -40,7 +39,6 @@ workflow TARGETED_SEQUENCING { ch_bedgraphs_target, [[:], []] ) - ch_versions = ch_versions.mix(BEDTOOLS_INTERSECT.out.versions) /* * Run Picard CollectHSMetrics @@ -56,7 +54,6 @@ workflow TARGETED_SEQUENCING { */ PICARD_CREATESEQUENCEDICTIONARY(ch_fasta) ch_sequence_dictionary = PICARD_CREATESEQUENCEDICTIONARY.out.reference_dict - ch_versions = ch_versions.mix(PICARD_CREATESEQUENCEDICTIONARY.out.versions) /* * Conversion of the covered targets BED file to an interval list @@ -67,7 +64,6 @@ workflow TARGETED_SEQUENCING { [] ) ch_intervals = PICARD_BEDTOINTERVALLIST.out.intervallist.map { it[1] } - ch_versions = ch_versions.mix(PICARD_BEDTOINTERVALLIST.out.versions) /* * Generation of the metrics @@ -94,11 +90,9 @@ workflow TARGETED_SEQUENCING { ch_picard_inputs.dict ) ch_picard_metrics = PICARD_COLLECTHSMETRICS.out.metrics - ch_versions = ch_versions.mix(PICARD_COLLECTHSMETRICS.out.versions) } emit: bedgraph_filtered = BEDTOOLS_INTERSECT.out.intersect // channel: [ val(meta), path("*.bedGraph") ] picard_metrics = ch_picard_metrics // channel: [ val(meta), path("*_metrics") ] - versions = ch_versions // channel: path("*.version.txt") } diff --git a/subworkflows/local/utils_nfcore_methylseq_pipeline/main.nf b/subworkflows/local/utils_nfcore_methylseq_pipeline/main.nf index 36f545f83..254e07dfd 100644 --- a/subworkflows/local/utils_nfcore_methylseq_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_methylseq_pipeline/main.nf @@ -34,7 +34,6 @@ workflow PIPELINE_INITIALISATION { main: - ch_versions = Channel.empty() // // Print version and exit if required and dump pipeline parameters to JSON file @@ -92,7 +91,6 @@ workflow PIPELINE_INITIALISATION { emit: samplesheet = ch_samplesheet - versions = ch_versions } /* diff --git a/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf b/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf index 5ba0e0b1a..728ad148f 100644 --- a/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf +++ b/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf @@ -17,11 +17,10 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { main: - ch_fasta = Channel.empty() - ch_fasta_index = Channel.empty() - ch_bismark_index = Channel.empty() - ch_bwameth_index = Channel.empty() - ch_versions = Channel.empty() + ch_fasta = channel.empty() + ch_fasta_index = channel.empty() + ch_bismark_index = channel.empty() + ch_bwameth_index = channel.empty() // Check if fasta file is gzipped and decompress if needed fasta @@ -36,7 +35,6 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { ) ch_fasta = ch_fasta_branched.unzipped.mix(GUNZIP.out.gunzip) - ch_versions = ch_versions.mix(GUNZIP.out.versions) // Aligner: bismark or bismark_hisat if( aligner =~ /bismark/ ){ @@ -57,13 +55,11 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { ) ch_bismark_index = ch_bismark_index_branched.unzipped.mix(UNTAR.out.untar) - ch_versions = ch_versions.mix(UNTAR.out.versions) } else { BISMARK_GENOMEPREPARATION ( ch_fasta ) ch_bismark_index = BISMARK_GENOMEPREPARATION.out.index - ch_versions = ch_versions.mix(BISMARK_GENOMEPREPARATION.out.versions) } } @@ -86,7 +82,6 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { ) ch_bwameth_index = ch_bwameth_index_branched.unzipped.mix(UNTAR.out.untar) - ch_versions = ch_versions.mix(UNTAR.out.versions) } else { if (use_mem2) { BWAMETH_INDEX ( @@ -100,7 +95,6 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { ) } ch_bwameth_index = BWAMETH_INDEX.out.index - ch_versions = ch_versions.mix(BWAMETH_INDEX.out.versions) } } @@ -118,7 +112,6 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { false ) ch_fasta_index = SAMTOOLS_FAIDX.out.fai - ch_versions = ch_versions.mix(SAMTOOLS_FAIDX.out.versions) } } @@ -127,5 +120,4 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { fasta_index = ch_fasta_index // channel: [ val(meta), [ fasta index ] ] bismark_index = ch_bismark_index // channel: [ val(meta), [ bismark index ] ] bwameth_index = ch_bwameth_index // channel: [ val(meta), [ bwameth index ] ] - versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf b/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf index e5f2ffe5a..82576c302 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf +++ b/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf @@ -17,20 +17,19 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { cytosine_report // boolean: whether the run coverage2cytosine main: - ch_alignments = Channel.empty() - ch_alignment_reports = Channel.empty() - ch_methylation_bedgraph = Channel.empty() - ch_methylation_calls = Channel.empty() - ch_methylation_coverage = Channel.empty() - ch_methylation_report = Channel.empty() - ch_methylation_mbias = Channel.empty() - ch_coverage2cytosine_coverage = Channel.empty() - ch_coverage2cytosine_report = Channel.empty() - ch_coverage2cytosine_summary = Channel.empty() - ch_bismark_report = Channel.empty() - ch_bismark_summary = Channel.empty() - ch_multiqc_files = Channel.empty() - ch_versions = Channel.empty() + ch_alignments = channel.empty() + ch_alignment_reports = channel.empty() + ch_methylation_bedgraph = channel.empty() + ch_methylation_calls = channel.empty() + ch_methylation_coverage = channel.empty() + ch_methylation_report = channel.empty() + ch_methylation_mbias = channel.empty() + ch_coverage2cytosine_coverage = channel.empty() + ch_coverage2cytosine_report = channel.empty() + ch_coverage2cytosine_summary = channel.empty() + ch_bismark_report = channel.empty() + ch_bismark_summary = channel.empty() + ch_multiqc_files = channel.empty() /* * Align with bismark @@ -42,7 +41,6 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { ) ch_alignments = BISMARK_ALIGN.out.bam ch_alignment_reports = BISMARK_ALIGN.out.report.map{ meta, report -> [ meta, report, [] ] } - ch_versions = ch_versions.mix(BISMARK_ALIGN.out.versions) if (!skip_deduplication) { /* @@ -53,7 +51,6 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { ) ch_alignments = BISMARK_DEDUPLICATE.out.bam ch_alignment_reports = BISMARK_ALIGN.out.report.join(BISMARK_DEDUPLICATE.out.report) - ch_versions = ch_versions.mix(BISMARK_DEDUPLICATE.out.versions) } /* @@ -63,7 +60,6 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { ch_alignments, [[:],[]] // [ [meta], [fasta]] ) - ch_versions = ch_versions.mix(SAMTOOLS_SORT.out.versions) /* * MODULE: Run samtools index on aligned or deduplicated bam @@ -71,7 +67,6 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { SAMTOOLS_INDEX ( SAMTOOLS_SORT.out.bam ) - ch_versions = ch_versions.mix(SAMTOOLS_INDEX.out.versions) /* * Run bismark_methylation_extractor @@ -85,7 +80,6 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { ch_methylation_coverage = BISMARK_METHYLATIONEXTRACTOR.out.coverage ch_methylation_report = BISMARK_METHYLATIONEXTRACTOR.out.report ch_methylation_mbias = BISMARK_METHYLATIONEXTRACTOR.out.mbias - ch_versions = ch_versions.mix(BISMARK_METHYLATIONEXTRACTOR.out.versions) /* * Run bismark coverage2cytosine @@ -99,7 +93,6 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { ch_coverage2cytosine_coverage = BISMARK_COVERAGE2CYTOSINE.out.coverage ch_coverage2cytosine_report = BISMARK_COVERAGE2CYTOSINE.out.report ch_coverage2cytosine_summary = BISMARK_COVERAGE2CYTOSINE.out.summary - ch_versions = ch_versions.mix(BISMARK_COVERAGE2CYTOSINE.out.versions) } /* @@ -111,7 +104,6 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { .join(ch_methylation_mbias) ) ch_bismark_report = BISMARK_REPORT.out.report - ch_versions = ch_versions.mix(BISMARK_REPORT.out.versions) /* * Generate bismark summary report @@ -124,7 +116,6 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { ch_methylation_mbias.collect{ meta, mbias -> mbias } ) ch_bismark_summary = BISMARK_SUMMARY.out.summary - ch_versions = ch_versions.mix(BISMARK_SUMMARY.out.versions) /* * Collect MultiQC inputs @@ -150,5 +141,4 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { bismark_report = ch_bismark_report // channel: [ val(meta), [ report ] ] bismark_summary = ch_bismark_summary // channel: [ val(meta), [ summary ] ] multiqc = ch_multiqc_files // path: *{html,txt} - versions = ch_versions // path: *.version.txt } diff --git a/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf b/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf index 904882506..2bf4b09ad 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf +++ b/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf @@ -21,16 +21,15 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { main: - ch_alignment = Channel.empty() - ch_alignment_index = Channel.empty() - ch_samtools_flagstat = Channel.empty() - ch_samtools_stats = Channel.empty() - ch_methydackel_extract_bedgraph = Channel.empty() - ch_methydackel_extract_methylkit = Channel.empty() - ch_methydackel_mbias = Channel.empty() - ch_picard_metrics = Channel.empty() - ch_multiqc_files = Channel.empty() - ch_versions = Channel.empty() + ch_alignment = channel.empty() + ch_alignment_index = channel.empty() + ch_samtools_flagstat = channel.empty() + ch_samtools_stats = channel.empty() + ch_methydackel_extract_bedgraph = channel.empty() + ch_methydackel_extract_methylkit = channel.empty() + ch_methydackel_mbias = channel.empty() + ch_picard_metrics = channel.empty() + ch_multiqc_files = channel.empty() /* * Align with bwameth @@ -46,7 +45,6 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { [] // known sites ) ch_alignment = PARABRICKS_FQ2BAMMETH.out.bam - ch_versions = ch_versions.mix(PARABRICKS_FQ2BAMMETH.out.versions) } else { /* * Align with CPU version of bwameth @@ -57,7 +55,6 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { ch_bwameth_index ) ch_alignment = BWAMETH_ALIGN.out.bam - ch_versions = BWAMETH_ALIGN.out.versions } /* @@ -68,7 +65,6 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { [[:],[]] // [ [meta], [fasta]] ) ch_alignment = SAMTOOLS_SORT.out.bam - ch_versions = ch_versions.mix(SAMTOOLS_SORT.out.versions) /* * Run samtools index on alignment @@ -77,7 +73,6 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { ch_alignment ) ch_alignment_index = SAMTOOLS_INDEX_ALIGNMENTS.out.bai - ch_versions = ch_versions.mix(SAMTOOLS_INDEX_ALIGNMENTS.out.versions) /* * Run samtools flagstat @@ -86,7 +81,6 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { ch_alignment.join(ch_alignment_index) ) ch_samtools_flagstat = SAMTOOLS_FLAGSTAT.out.flagstat - ch_versions = ch_versions.mix(SAMTOOLS_FLAGSTAT.out.versions) /* * Run samtools stats @@ -96,7 +90,6 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { [[:],[]] // [ [meta], [fasta]] ) ch_samtools_stats = SAMTOOLS_STATS.out.stats - ch_versions = ch_versions.mix(SAMTOOLS_STATS.out.versions) if (!skip_deduplication) { /* @@ -116,8 +109,6 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { ch_alignment = PICARD_MARKDUPLICATES.out.bam ch_alignment_index = SAMTOOLS_INDEX_DEDUPLICATED.out.bai ch_picard_metrics = PICARD_MARKDUPLICATES.out.metrics - ch_versions = ch_versions.mix(PICARD_MARKDUPLICATES.out.versions) - ch_versions = ch_versions.mix(SAMTOOLS_INDEX_DEDUPLICATED.out.versions) } /* @@ -131,7 +122,6 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { ) ch_methydackel_extract_bedgraph = METHYLDACKEL_EXTRACT.out.bedgraph ch_methydackel_extract_methylkit = METHYLDACKEL_EXTRACT.out.methylkit - ch_versions = ch_versions.mix(METHYLDACKEL_EXTRACT.out.versions) METHYLDACKEL_MBIAS ( ch_alignment.join(ch_alignment_index), @@ -139,7 +129,6 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { ch_fasta_index.map{ meta, fasta_index -> fasta_index } ) ch_methydackel_mbias = METHYLDACKEL_MBIAS.out.txt - ch_versions = ch_versions.mix(METHYLDACKEL_MBIAS.out.versions) /* * Collect MultiQC inputs @@ -160,5 +149,4 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { methydackel_mbias = ch_methydackel_mbias // channel: [ val(meta), [ mbias ] ] picard_metrics = ch_picard_metrics // channel: [ val(meta), [ metrics ] ] multiqc = ch_multiqc_files // channel: [ *{html,txt} ] - versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf index bfd258760..2f30e9a46 100644 --- a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf @@ -98,7 +98,7 @@ def workflowVersionToYAML() { // Get channel of software versions used in pipeline in YAML format // def softwareVersionsToYAML(ch_versions) { - return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(Channel.of(workflowVersionToYAML())) + return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(channel.of(workflowVersionToYAML())) } // diff --git a/workflows/methylseq/main.nf b/workflows/methylseq/main.nf index 67e7fafff..f278b7c12 100644 --- a/workflows/methylseq/main.nf +++ b/workflows/methylseq/main.nf @@ -29,7 +29,6 @@ workflow METHYLSEQ { take: samplesheet // channel: [ path(samplesheet.csv) ] - ch_versions // channel: [ path(versions.yml) ] ch_fasta // channel: [ path(fasta) ] ch_fasta_index // channel: [ path(fasta index) ] ch_bismark_index // channel: [ path(bismark index) ] @@ -37,17 +36,17 @@ workflow METHYLSEQ { main: - ch_fastq = Channel.empty() - ch_fastqc_html = Channel.empty() - ch_fastqc_zip = Channel.empty() - ch_reads = Channel.empty() - ch_bam = Channel.empty() - ch_bai = Channel.empty() - ch_bedgraph = Channel.empty() - ch_aligner_mqc = Channel.empty() - ch_qualimap = Channel.empty() - ch_preseq = Channel.empty() - ch_multiqc_files = Channel.empty() + ch_fastq = channel.empty() + ch_fastqc_html = channel.empty() + ch_fastqc_zip = channel.empty() + ch_reads = channel.empty() + ch_bam = channel.empty() + ch_bai = channel.empty() + ch_bedgraph = channel.empty() + ch_aligner_mqc = channel.empty() + ch_qualimap = channel.empty() + ch_preseq = channel.empty() + ch_multiqc_files = channel.empty() // // Branch channels from input samplesheet channel @@ -66,8 +65,7 @@ workflow METHYLSEQ { CAT_FASTQ ( ch_samplesheet.multiple ) - ch_fastq = CAT_FASTQ.out.reads.mix(ch_samplesheet.single) - ch_versions = ch_versions.mix(CAT_FASTQ.out.versions) + ch_fastq = CAT_FASTQ.out.reads.mix(ch_samplesheet.single) // // MODULE: Run FastQC @@ -78,10 +76,9 @@ workflow METHYLSEQ { ) ch_fastqc_html = FASTQC.out.html ch_fastqc_zip = FASTQC.out.zip - ch_versions = ch_versions.mix(FASTQC.out.versions) } else { - ch_fastqc_html = Channel.empty() - ch_fastqc_zip = Channel.empty() + ch_fastqc_html = channel.empty() + ch_fastqc_zip = channel.empty() } // @@ -92,7 +89,6 @@ workflow METHYLSEQ { ch_fastq ) ch_reads = TRIMGALORE.out.reads - ch_versions = ch_versions.mix(TRIMGALORE.out.versions) } else { ch_reads = ch_fastq } @@ -126,7 +122,6 @@ workflow METHYLSEQ { ch_bai = FASTQ_ALIGN_DEDUP_BISMARK.out.bai ch_bedgraph = FASTQ_ALIGN_DEDUP_BISMARK.out.methylation_bedgraph ch_aligner_mqc = FASTQ_ALIGN_DEDUP_BISMARK.out.multiqc - ch_versions = ch_versions.mix(FASTQ_ALIGN_DEDUP_BISMARK.out.versions) } // Aligner: bwameth else if ( params.aligner == 'bwameth' ){ @@ -154,7 +149,6 @@ workflow METHYLSEQ { ch_bai = FASTQ_ALIGN_DEDUP_BWAMETH.out.bai ch_bedgraph = FASTQ_ALIGN_DEDUP_BWAMETH.out.methydackel_extract_bedgraph ch_aligner_mqc = FASTQ_ALIGN_DEDUP_BWAMETH.out.multiqc - ch_versions = ch_versions.mix(FASTQ_ALIGN_DEDUP_BWAMETH.out.versions) } else { error "ERROR: Invalid aligner '${params.aligner}'. Valid options are: 'bismark', 'bismark_hisat', or 'bwameth'" @@ -167,10 +161,9 @@ workflow METHYLSEQ { if(params.run_qualimap) { QUALIMAP_BAMQC ( ch_bam, - params.bamqc_regions_file ? Channel.fromPath( params.bamqc_regions_file, checkIfExists: true ).toList() : [] + params.bamqc_regions_file ? channel.fromPath( params.bamqc_regions_file, checkIfExists: true ).toList() : [] ) ch_qualimap = QUALIMAP_BAMQC.out.results - ch_versions = ch_versions.mix(QUALIMAP_BAMQC.out.versions) } // @@ -183,14 +176,13 @@ workflow METHYLSEQ { } TARGETED_SEQUENCING ( ch_bedgraph, - Channel.fromPath(params.target_regions_file, checkIfExists: true), + channel.fromPath(params.target_regions_file, checkIfExists: true), ch_fasta, ch_fasta_index, ch_bam, ch_bai, params.collecthsmetrics ) - ch_versions = ch_versions.mix(TARGETED_SEQUENCING.out.versions) } // @@ -202,13 +194,12 @@ workflow METHYLSEQ { ch_bam ) ch_preseq = PRESEQ_LCEXTRAP.out.lc_extrap - ch_versions = ch_versions.mix(PRESEQ_LCEXTRAP.out.versions) } // // Collate and save software versions // - ch_collated_versions = softwareVersionsToYAML(ch_versions) + ch_collated_versions = softwareVersionsToYAML( channel.topic('versions') ) .collectFile( storeDir: "${params.outdir}/pipeline_info", name: 'nf_core_' + 'methylseq_software_' + 'mqc_' + 'versions.yml', @@ -220,21 +211,21 @@ workflow METHYLSEQ { // MODULE: MultiQC // if (!params.skip_multiqc) { - ch_multiqc_config = Channel.fromPath("$projectDir/assets/multiqc_config.yml", checkIfExists: true) + ch_multiqc_config = channel.fromPath("$projectDir/assets/multiqc_config.yml", checkIfExists: true) ch_multiqc_custom_config = params.multiqc_config ? - Channel.fromPath(params.multiqc_config, checkIfExists: true) : - Channel.empty() + channel.fromPath(params.multiqc_config, checkIfExists: true) : + channel.empty() ch_multiqc_logo = params.multiqc_logo ? - Channel.fromPath(params.multiqc_logo, checkIfExists: true) : - Channel.empty() + channel.fromPath(params.multiqc_logo, checkIfExists: true) : + channel.empty() summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") - ch_workflow_summary = Channel.value(paramsSummaryMultiqc(summary_params)) + ch_workflow_summary = channel.value(paramsSummaryMultiqc(summary_params)) ch_multiqc_custom_methods_description = params.multiqc_methods_description ? file(params.multiqc_methods_description, checkIfExists: true) : file("$projectDir/assets/methods_description_template.yml", checkIfExists: true) - ch_methods_description = Channel.value(methodsDescriptionText(ch_multiqc_custom_methods_description)) + ch_methods_description = channel.value(methodsDescriptionText(ch_multiqc_custom_methods_description)) ch_multiqc_files = ch_multiqc_files.mix(ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) ch_multiqc_files = ch_multiqc_files.mix(ch_collated_versions) @@ -274,7 +265,7 @@ workflow METHYLSEQ { ) ch_multiqc_report = MULTIQC.out.report.toList() } else { - ch_multiqc_report = Channel.empty() + ch_multiqc_report = channel.empty() } emit: @@ -283,7 +274,6 @@ workflow METHYLSEQ { qualimap = ch_qualimap // channel: [ val(meta), path(qualimap) ] preseq = ch_preseq // channel: [ val(meta), path(preseq) ] multiqc_report = ch_multiqc_report // channel: [ path(multiqc_report.html ) ] - versions = ch_versions // channel: [ path(versions.yml) ] } /* From 135b918b85d242593a19276a974e545b62bddac3 Mon Sep 17 00:00:00 2001 From: Ben Sherman Date: Mon, 12 Jan 2026 21:33:11 -0600 Subject: [PATCH 2/6] Record types --- conf/modules/bismark_align.config | 4 +- .../bismark_methylationextractor.config | 6 +- conf/modules/picard_markduplicates.config | 2 +- conf/modules/samtools_sort.config | 2 +- conf/modules/trimgalore.config | 4 +- main.nf | 273 +++++++++++++++-- modules/nf-core/bedtools/intersect/main.nf | 48 +-- .../bedtools/intersect/tests/nextflow.config | 2 +- modules/nf-core/bismark/align/main.nf | 54 ++-- .../nf-core/bismark/coverage2cytosine/main.nf | 43 ++- modules/nf-core/bismark/deduplicate/main.nf | 35 ++- .../nf-core/bismark/genomepreparation/main.nf | 23 +- .../bismark/methylationextractor/main.nf | 45 +-- modules/nf-core/bismark/report/main.nf | 26 +- modules/nf-core/bismark/summary/main.nf | 26 +- modules/nf-core/bwameth/align/main.nf | 39 ++- modules/nf-core/bwameth/index/main.nf | 29 +- modules/nf-core/cat/fastq/main.nf | 47 ++- modules/nf-core/fastqc/main.nf | 35 ++- modules/nf-core/gunzip/main.nf | 10 +- modules/nf-core/gunzip/tests/nextflow.config | 2 +- modules/nf-core/methyldackel/extract/main.nf | 37 ++- modules/nf-core/methyldackel/mbias/main.nf | 41 ++- modules/nf-core/multiqc/main.nf | 60 ++-- modules/nf-core/parabricks/fq2bammeth/main.nf | 70 +++-- .../nf-core/picard/bedtointervallist/main.nf | 49 +-- .../nf-core/picard/collecthsmetrics/main.nf | 67 +++-- .../picard/createsequencedictionary/main.nf | 34 ++- modules/nf-core/picard/markduplicates/main.nf | 63 ++-- .../markduplicates/tests/nextflow.config | 2 +- modules/nf-core/preseq/lcextrap/main.nf | 42 ++- modules/nf-core/qualimap/bamqc/main.nf | 71 +++-- modules/nf-core/qualimap/bamqccram/main.nf | 2 +- modules/nf-core/samtools/faidx/main.nf | 34 ++- modules/nf-core/samtools/flagstat/main.nf | 31 +- modules/nf-core/samtools/index/main.nf | 34 ++- modules/nf-core/samtools/sort/main.nf | 60 ++-- .../samtools/sort/tests/nextflow.config | 2 +- .../samtools/sort/tests/nextflow_cram.config | 2 +- modules/nf-core/samtools/stats/main.nf | 31 +- modules/nf-core/trimgalore/main.nf | 40 ++- modules/nf-core/untar/main.nf | 14 +- nextflow.config | 119 -------- .../local/targeted_sequencing/main.nf | 95 +++--- .../utils_nfcore_methylseq_pipeline/main.nf | 27 +- .../fasta_index_bismark_bwameth/main.nf | 108 +++---- .../nf-core/fastq_align_dedup_bismark/main.nf | 164 +++++----- .../tests/nextflow.config | 2 +- .../nf-core/fastq_align_dedup_bwameth/main.nf | 139 ++++----- .../tests/nextflow.config | 4 +- .../nf-core/utils_nfschema_plugin/main.nf | 12 - utils/ops.nf | 27 ++ utils/types.nf | 6 + workflows/methylseq/main.nf | 284 ++++++++++-------- 54 files changed, 1457 insertions(+), 1071 deletions(-) create mode 100644 utils/ops.nf create mode 100644 utils/types.nf diff --git a/conf/modules/bismark_align.config b/conf/modules/bismark_align.config index 5bd12ffef..f5306cc87 100644 --- a/conf/modules/bismark_align.config +++ b/conf/modules/bismark_align.config @@ -8,8 +8,8 @@ process { params.unmapped ? ' --unmapped' : '', params.relax_mismatches ? " --score_min L,0,-${params.num_mismatches}" : '', params.local_alignment ? " --local" : '', - !meta.single_end && params.minins ? " --minins ${params.minins}" : '', - meta.single_end ? '' : ( + !single_end && params.minins ? " --minins ${params.minins}" : '', + single_end ? '' : ( params.maxins ? " --maxins ${params.maxins}" : ( params.em_seq ? " --maxins 1000" : '' ) diff --git a/conf/modules/bismark_methylationextractor.config b/conf/modules/bismark_methylationextractor.config index 5f57a4030..9a3295daa 100644 --- a/conf/modules/bismark_methylationextractor.config +++ b/conf/modules/bismark_methylationextractor.config @@ -6,9 +6,9 @@ process { params.nomeseq ? '--CX' : '', params.ignore_r1 > 0 ? "--ignore ${params.ignore_r1}" : '', params.ignore_3prime_r1 > 0 ? "--ignore_3prime ${params.ignore_3prime_r1}" : '', - meta.single_end ? '' : (params.no_overlap ? ' --no_overlap' : '--include_overlap'), - meta.single_end ? '' : (params.ignore_r2 > 0 ? "--ignore_r2 ${params.ignore_r2}" : ""), - meta.single_end ? '' : (params.ignore_3prime_r2 > 0 ? "--ignore_3prime_r2 ${params.ignore_3prime_r2}": "") + single_end ? '' : (params.no_overlap ? ' --no_overlap' : '--include_overlap'), + single_end ? '' : (params.ignore_r2 > 0 ? "--ignore_r2 ${params.ignore_r2}" : ""), + single_end ? '' : (params.ignore_3prime_r2 > 0 ? "--ignore_3prime_r2 ${params.ignore_3prime_r2}": "") ].join(' ').trim() } publishDir = [ [ diff --git a/conf/modules/picard_markduplicates.config b/conf/modules/picard_markduplicates.config index ea2368dcf..cbd3adcde 100644 --- a/conf/modules/picard_markduplicates.config +++ b/conf/modules/picard_markduplicates.config @@ -1,7 +1,7 @@ process { withName: PICARD_MARKDUPLICATES { ext.args = "--ASSUME_SORTED true --REMOVE_DUPLICATES false --VALIDATION_STRINGENCY LENIENT --PROGRAM_RECORD_ID 'null' --TMP_DIR tmp" - ext.prefix = { "${meta.id}.markdup.sorted" } + ext.prefix = { "${id}.markdup.sorted" } publishDir = [ [ path: { "${params.outdir}/${params.aligner}/deduplicated/picard_metrics" }, diff --git a/conf/modules/samtools_sort.config b/conf/modules/samtools_sort.config index 95c78bd0c..beeb7735b 100644 --- a/conf/modules/samtools_sort.config +++ b/conf/modules/samtools_sort.config @@ -1,6 +1,6 @@ process { withName: SAMTOOLS_SORT { - ext.prefix = params.skip_deduplication ? { "${meta.id}.sorted" } : { "${meta.id}.deduplicated.sorted" } + ext.prefix = { params.skip_deduplication ? "${id}.sorted" : "${id}.deduplicated.sorted" } publishDir = [ [ path: { "${params.outdir}/${params.aligner}/deduplicated/" }, diff --git a/conf/modules/trimgalore.config b/conf/modules/trimgalore.config index 465f4c082..f55fd4be4 100644 --- a/conf/modules/trimgalore.config +++ b/conf/modules/trimgalore.config @@ -21,7 +21,7 @@ process { ), // Trimming - R2 - meta.single_end ? '' : ( + single_end ? '' : ( params.clip_r2 > 0 ? "--clip_r2 ${params.clip_r2}" : ( params.skip_trimming_presets ? '' : ( params.pbat ? "--clip_r2 8" : ( @@ -47,7 +47,7 @@ process { ), // Trimming - 3' R2 - meta.single_end ? '' : ( + single_end ? '' : ( params.three_prime_clip_r2 > 0 ? "--three_prime_clip_r2 ${params.three_prime_clip_r2}" : ( params.skip_trimming_presets ? '' : ( params.pbat ? "--three_prime_clip_r2 8" : ( diff --git a/main.nf b/main.nf index 123d734b2..a7bbf7536 100644 --- a/main.nf +++ b/main.nf @@ -21,15 +21,251 @@ include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_ include { getGenomeAttribute } from './subworkflows/local/utils_nfcore_methylseq_pipeline' include { METHYLSEQ } from './workflows/methylseq/' +include { Sample } from './utils/types.nf' +include { MethylseqParams } from './workflows/methylseq/' + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GENOME PARAMETER VALUES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -params.fasta = getGenomeAttribute('fasta') -params.fasta_index = getGenomeAttribute('fasta_index') -params.bwameth_index = getGenomeAttribute('bwameth') -params.bismark_index = params.aligner == 'bismark_hisat' ? getGenomeAttribute('bismark_hisat2') : getGenomeAttribute('bismark') + +params { + + // Path to comma-separated file containing information about the samples in the experiment. + input : String + + // The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure. + outdir : String + + /// MultiQC options + + // Custom config file to supply to MultiQC. + multiqc_config : String? + + // MultiQC report title. Printed as page header, used for filename if not otherwise specified. + multiqc_title : String? + + // Custom logo file to supply to MultiQC. File name must also be set in the MultiQC config file + multiqc_logo : String? + + // File size limit when attaching MultiQC reports to summary emails. + max_multiqc_email_size : String = '25.MB' + + // Custom MultiQC yaml file containing HTML including a methods description. + multiqc_methods_description : String? + + /// Intermediate files + + // Save reference(s) to results directory + save_reference : Boolean + + // Save aligned intermediates to results directory + save_align_intermeds : Boolean + + // Bismark only - Save unmapped reads to FastQ files + unmapped : Boolean + + // Save trimmed reads to results directory. + save_trimmed : Boolean + + /// Reference options + + // Name of iGenomes reference. + genome : String? + + // Path to FASTA genome file + fasta : Path? = getGenomeAttribute('fasta') + + // Path to Fasta index file. + fasta_index : Path? = getGenomeAttribute('fasta_index') + + // Path to a directory containing a Bismark reference index. + bismark_index : Path? = params.aligner == 'bismark_hisat' ? getGenomeAttribute('bismark_hisat2') : getGenomeAttribute('bismark') + + // bwameth index filename base + bwameth_index : Path? = getGenomeAttribute('bwameth') + + /// Alignment options + + // Alignment tool to use. + aligner : String = 'bismark' + + // Use BWA-MEM2 algorithm for BWA-Meth indexing and alignment. + use_mem2 : Boolean + + /// Library presets + + // Preset for working with PBAT libraries. + pbat : Boolean + + // Turn on if dealing with MspI digested material. + rrbs : Boolean + + // Run bismark in SLAM-seq mode. + slamseq : Boolean + + // Preset for EM-seq libraries. + em_seq : Boolean + + // Trimming preset for single-cell bisulfite libraries. + single_cell : Boolean + + // Trimming preset for the Accel kit. + accel : Boolean + + // Trimming preset for the Zymo kit. + zymo : Boolean + + /// Trimming options + + // Trim bases from the 5' end of read 1 (or single-end reads). + clip_r1 : Integer = 0 + + // Trim bases from the 5' end of read 2 (paired-end only). + clip_r2 : Integer = 0 + + // Trim bases from the 3' end of read 1 AFTER adapter/quality trimming. + three_prime_clip_r1 : Integer = 0 + + // Trim bases from the 3' end of read 2 AFTER adapter/quality trimming + three_prime_clip_r2 : Integer = 0 + + // Trim bases below this quality value from the 3' end of the read, ignoring high-quality G bases + nextseq_trim : Integer = 0 + + // Discard reads that become shorter than INT because of either quality or adapter trimming. + length_trim : Integer? + + // Skip presetting trimming parameters entirely + skip_trimming_presets : Boolean + + /// Bismark options + + // Run alignment against all four possible strands. + non_directional : Boolean + + // Output stranded cytosine report, following Bismark's bismark_methylation_extractor step. + cytosine_report : Boolean + + // Turn on to relax stringency for alignment (set allowed penalty with --num_mismatches). + relax_mismatches : Boolean + + // 0.6 will allow a penalty of bp * -0.6 - for 100bp reads (bismark default is 0.2) + num_mismatches : Float = 0.6 + + // Specify a minimum read coverage to report a methylation call + meth_cutoff : Integer? + + // Ignore read 2 methylation when it overlaps read 1 + no_overlap : Boolean = true + + // Ignore methylation in first n bases of 5' end of R1 + ignore_r1 : Integer = 0 + + // Ignore methylation in first n bases of 5' end of R2 + ignore_r2 : Integer = 2 + + // Ignore methylation in last n bases of 3' end of R1 + ignore_3prime_r1 : Integer = 0 + + // Ignore methylation in last n bases of 3' end of R2 + ignore_3prime_r2 : Integer = 2 + + // Supply a .gtf file containing known splice sites (bismark_hisat only). + known_splices : String? + + // Allow soft-clipping of reads (potentially useful for single-cell experiments). + local_alignment : Boolean + + // The minimum insert size for valid paired-end alignments. + minins : Integer? + + // The maximum insert size for valid paired-end alignments. + maxins : Integer? + + // Sample is NOMe-seq or NMT-seq. Runs coverage2cytosine. + nomeseq : Boolean + + // Merges methylation calls for every strand into a single, context dependent file. + comprehensive : Boolean + + /// bwa-meth options + + // Call methylation in all three CpG, CHG and CHH contexts. + all_contexts : Boolean + + // Merges methylation metrics of the Cytosines in a given context. + merge_context : Boolean + + // Specify a minimum read coverage for MethylDackel to report a methylation call. + min_depth : Integer = 0 + + // MethylDackel - ignore SAM flags + ignore_flags : Boolean + + // Save files for use with methylKit + methyl_kit : Boolean + + /// Qualimap options + + // A GFF or BED file containing the target regions which will be passed to Qualimap/Bamqc. + bamqc_regions_file : String? + + /// Targeted sequencing options + + // A BED file containing the target regions + target_regions_file : String? + + // Run Picard CollectHsMetrics in the targeted analysis + collecthsmetrics : Boolean + + /// Skipping options + + // Skip read trimming. + skip_trimming : Boolean + + // Skip deduplication step after alignment. + skip_deduplication : Boolean + + // Skip FastQC + skip_fastqc : Boolean + + // Skip MultiQC + skip_multiqc : Boolean + + /// Run options + + // Run preseq/lcextrap tool + run_preseq : Boolean + + // Run qualimap/bamqc tool + run_qualimap : Boolean + + // Run advanced analysis for targeted methylation kits with enrichment of specific regions + run_targeted_sequencing : Boolean + + // Email address for completion summary. + email : String? + + // Email address for completion summary, only when pipeline fails. + email_on_fail : String? + + // Send plain-text email instead of HTML. + plaintext_email : Boolean + + // Do not use coloured log outputs. + monochrome_logs : Boolean + + // Incoming hook URL for messaging service + hook_url : String? + + // Display version and exit. + version : Boolean + + // Boolean whether to validate parameters against the schema at runtime + validate_params : Boolean = true +} /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -43,27 +279,19 @@ params.bismark_index = params.aligner == 'bismark_hisat' ? getGenomeAttribute('b workflow NFCORE_METHYLSEQ { take: - samplesheet // channel: samplesheet read in from --input + ch_samples: Channel + params: MethylseqParams main: - - // - // Initialize file channels or values based on params - // - ch_fasta = params.fasta ? channel.fromPath(params.fasta).map{ it -> [ [id:it.baseName], it ] } : channel.empty() - ch_or_val_fasta_index = params.fasta_index ? channel.fromPath(params.fasta_index).map{ it -> [ [id:it.baseName], it ] } : [] - ch_or_val_bismark_index = params.bismark_index ? channel.fromPath(params.bismark_index).map{ it -> [ [id:it.baseName], it ] } : [] - ch_or_val_bwameth_index = params.bwameth_index ? channel.fromPath(params.bwameth_index).map{ it -> [ [id:it.baseName], it ] } : [] - // // SUBWORKFLOW: Prepare any required reference genome indices // FASTA_INDEX_BISMARK_BWAMETH( - ch_fasta, - ch_or_val_fasta_index, - ch_or_val_bismark_index, - ch_or_val_bwameth_index, + params.fasta, + params.fasta_index, + params.bismark_index, + params.bwameth_index, params.aligner, params.collecthsmetrics, params.use_mem2 @@ -74,15 +302,16 @@ workflow NFCORE_METHYLSEQ { // METHYLSEQ ( - samplesheet, + ch_samples, FASTA_INDEX_BISMARK_BWAMETH.out.fasta, FASTA_INDEX_BISMARK_BWAMETH.out.fasta_index, FASTA_INDEX_BISMARK_BWAMETH.out.bismark_index, FASTA_INDEX_BISMARK_BWAMETH.out.bwameth_index, + params ) emit: - multiqc_report = METHYLSEQ.out.multiqc_report // channel: [ path(multiqc_report.html ) ] + multiqc_report = METHYLSEQ.out.multiqc_report } /* @@ -98,6 +327,7 @@ workflow { // SUBWORKFLOW: Run initialisation tasks // PIPELINE_INITIALISATION ( + params.input, params.version, params.validate_params, params.monochrome_logs, @@ -109,7 +339,8 @@ workflow { // WORKFLOW: Run main workflow // NFCORE_METHYLSEQ ( - PIPELINE_INITIALISATION.out.samplesheet + PIPELINE_INITIALISATION.out.samplesheet, + params ) // // SUBWORKFLOW: Run completion tasks diff --git a/modules/nf-core/bedtools/intersect/main.nf b/modules/nf-core/bedtools/intersect/main.nf index c8cde91f9..58bc0efcb 100644 --- a/modules/nf-core/bedtools/intersect/main.nf +++ b/modules/nf-core/bedtools/intersect/main.nf @@ -1,39 +1,47 @@ +nextflow.preview.types = true + process BEDTOOLS_INTERSECT { - tag "$meta.id" + tag id label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bedtools:2.31.1--hf5e1c6e_0' : - 'biocontainers/bedtools:2.31.1--hf5e1c6e_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/bedtools:2.31.1--hf5e1c6e_0' + : 'biocontainers/bedtools:2.31.1--hf5e1c6e_0'}" input: - tuple val(meta), path(intervals1), path(intervals2) - tuple val(meta2), path(chrom_sizes) + ( + id: String, + intervals1: Path, + intervals2: Path, + chrom_sizes: Path? + ): Record output: - tuple val(meta), path("*.${extension}"), emit: intersect - path "versions.yml" , topic: versions + record(id: id, bedgraph_intersect: file("*.${extension}")) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id //Extension of the output file. It is set by the user via "ext.suffix" in the config. Corresponds to the file format which depends on arguments (e. g., ".bed", ".bam", ".txt", etc.). extension = task.ext.suffix ?: "${intervals1.extension}" def sizes = chrom_sizes ? "-g ${chrom_sizes}" : '' - if ("$intervals1" == "${prefix}.${extension}" || - "$intervals2" == "${prefix}.${extension}") - error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + if ("${intervals1}" == "${prefix}.${extension}" || "${intervals2}" == "${prefix}.${extension}") { + error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + } """ bedtools \\ intersect \\ - -a $intervals1 \\ - -b $intervals2 \\ - $args \\ - $sizes \\ + -a ${intervals1} \\ + -b ${intervals2} \\ + ${args} \\ + ${sizes} \\ > ${prefix}.${extension} cat <<-END_VERSIONS > versions.yml @@ -43,11 +51,11 @@ process BEDTOOLS_INTERSECT { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id extension = task.ext.suffix ?: "bed" - if ("$intervals1" == "${prefix}.${extension}" || - "$intervals2" == "${prefix}.${extension}") - error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + if ("${intervals1}" == "${prefix}.${extension}" || "${intervals2}" == "${prefix}.${extension}") { + error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + } """ touch ${prefix}.${extension} diff --git a/modules/nf-core/bedtools/intersect/tests/nextflow.config b/modules/nf-core/bedtools/intersect/tests/nextflow.config index f1f9e6937..1defe384b 100644 --- a/modules/nf-core/bedtools/intersect/tests/nextflow.config +++ b/modules/nf-core/bedtools/intersect/tests/nextflow.config @@ -1,5 +1,5 @@ process { withName: BEDTOOLS_INTERSECT { - ext.prefix = { "${meta.id}_out" } + ext.prefix = { "${id}_out" } } } diff --git a/modules/nf-core/bismark/align/main.nf b/modules/nf-core/bismark/align/main.nf index f035bcd40..2696dea6f 100644 --- a/modules/nf-core/bismark/align/main.nf +++ b/modules/nf-core/bismark/align/main.nf @@ -1,5 +1,7 @@ +nextflow.preview.types = true + process BISMARK_ALIGN { - tag "$meta.id" + tag id label 'process_high' conda "${moduleDir}/environment.yml" @@ -8,36 +10,49 @@ process BISMARK_ALIGN { 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47' }" input: - tuple val(meta), path(reads) - tuple val(meta2), path(fasta, stageAs: 'tmp/*') // This change mounts as directory containing the FASTA file to prevent nested symlinks - tuple val(meta3), path(index) + ( + id: String, + single_end: Boolean, + reads: List, + fasta: Path, + bismark_index: Path + ): Record + + stage: + stageAs 'tmp/*', fasta // This change mounts as directory containing the FASTA file to prevent nested symlinks output: - tuple val(meta), path("*bam") , emit: bam - tuple val(meta), path("*report.txt"), emit: report - tuple val(meta), path("*fq.gz") , emit: unmapped, optional: true - path "versions.yml" , topic: versions + record( + id: id, + single_end: single_end, + bam: file("*bam"), + align_report: file("*report.txt"), + unmapped: file("*fq.gz", optional: true) + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - if(task.ext.prefix){ + if (task.ext.prefix) { args += " --prefix ${task.ext.prefix}" } - def fastq = meta.single_end ? reads : "-1 ${reads[0]} -2 ${reads[1]}" + def fastq = single_end ? "${reads[0]}" : "-1 ${reads[0]} -2 ${reads[1]}" // Try to assign sensible bismark --multicore if not already set - if(!args.contains('--multicore') && task.cpus){ + if (!args.contains('--multicore') && task.cpus) { // Numbers based on recommendation by Felix for a typical mouse genome def ccore = 1 def cpu_per_multicore = 3 - def mem_per_multicore = (13.GB).toBytes() - if(args.contains('--non_directional')){ + def mem_per_multicore = 13.GB.toBytes() + if (args.contains('--non_directional')) { cpu_per_multicore = 5 - mem_per_multicore = (18.GB).toBytes() + mem_per_multicore = 18.GB.toBytes() } // How many multicore splits can we afford with the cpus we have? @@ -48,17 +63,18 @@ process BISMARK_ALIGN { def tmem = (task.memory as MemoryUnit).toBytes() def mcore = (tmem / mem_per_multicore) as int ccore = Math.min(ccore, mcore) - } catch (all) { - log.warn "Not able to define bismark align multicore based on available memory" } - if(ccore > 1){ + catch (all) { + log.warn("Not able to define bismark align multicore based on available memory") + } + if (ccore > 1) { args += " --multicore ${ccore}" } } """ bismark \\ ${fastq} \\ - --genome ${index} \\ + --genome ${bismark_index} \\ --bam \\ ${args} @@ -70,7 +86,7 @@ process BISMARK_ALIGN { stub: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ touch ${prefix}.bam touch ${prefix}.report.txt diff --git a/modules/nf-core/bismark/coverage2cytosine/main.nf b/modules/nf-core/bismark/coverage2cytosine/main.nf index 65ce57179..e87bb87d2 100644 --- a/modules/nf-core/bismark/coverage2cytosine/main.nf +++ b/modules/nf-core/bismark/coverage2cytosine/main.nf @@ -1,33 +1,46 @@ +nextflow.preview.types = true + process BISMARK_COVERAGE2CYTOSINE { - tag "$meta.id" + tag id label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/38/38e61d14ccaed82f60c967132963eb467d0fa4bccb7a21404c49b4f377735f03/data' : - 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/38/38e61d14ccaed82f60c967132963eb467d0fa4bccb7a21404c49b4f377735f03/data' + : 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47'}" input: - tuple val(meta), path(coverage_file) - tuple val(meta2), path(fasta, stageAs: 'tmp/*') // This change mounts as directory containing the FASTA file to prevent nested symlinks - tuple val(meta3), path(index) + ( + id: String, + methylation_coverage: Path, + fasta: Path, + bismark_index: Path + ): Record + + stage: + stageAs 'tmp/*', fasta // This change mounts as directory containing the FASTA file to prevent nested symlinks output: - tuple val(meta), path("*.cov.gz") , emit: coverage, optional: true - tuple val(meta), path("*report.txt.gz") , emit: report - tuple val(meta), path("*cytosine_context_summary.txt") , emit: summary - path "versions.yml" , topic: versions + record( + id : id, + coverage2cytosine_coverage : file("*.cov.gz", optional: true), + coverage2cytosine_report : file("*report.txt.gz"), + coverage2cytosine_summary : file("*cytosine_context_summary.txt") + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ coverage2cytosine \\ - ${coverage_file} \\ - --genome ${index} \\ + ${methylation_coverage} \\ + --genome ${bismark_index} \\ --output ${prefix} \\ --gzip \\ ${args} @@ -40,7 +53,7 @@ process BISMARK_COVERAGE2CYTOSINE { stub: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ echo | gzip > ${prefix}.cov.gz echo | gzip > ${prefix}.report.txt.gz diff --git a/modules/nf-core/bismark/deduplicate/main.nf b/modules/nf-core/bismark/deduplicate/main.nf index 3671ea7f0..9ee420c6f 100644 --- a/modules/nf-core/bismark/deduplicate/main.nf +++ b/modules/nf-core/bismark/deduplicate/main.nf @@ -1,27 +1,38 @@ +nextflow.preview.types = true + process BISMARK_DEDUPLICATE { - tag "$meta.id" + tag id label 'process_high' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/38/38e61d14ccaed82f60c967132963eb467d0fa4bccb7a21404c49b4f377735f03/data' : - 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/38/38e61d14ccaed82f60c967132963eb467d0fa4bccb7a21404c49b4f377735f03/data' + : 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47'}" input: - tuple val(meta), path(bam) + ( + id: String, + single_end: Boolean, + bam: Path + ): Record output: - tuple val(meta), path("*.deduplicated.bam") , emit: bam - tuple val(meta), path("*.deduplication_report.txt"), emit: report - path "versions.yml" , topic: versions + record( + id : id, + bam : file("*.deduplicated.bam"), + dedup_report : file("*.deduplication_report.txt") + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def seqtype = meta.single_end ? '-s' : '-p' + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: id + def seqtype = single_end ? '-s' : '-p' """ deduplicate_bismark \\ ${args} \\ @@ -36,7 +47,7 @@ process BISMARK_DEDUPLICATE { stub: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ touch ${prefix}.deduplicated.bam touch ${prefix}.deduplication_report.txt diff --git a/modules/nf-core/bismark/genomepreparation/main.nf b/modules/nf-core/bismark/genomepreparation/main.nf index c0efd03c1..e8f3c5750 100644 --- a/modules/nf-core/bismark/genomepreparation/main.nf +++ b/modules/nf-core/bismark/genomepreparation/main.nf @@ -1,18 +1,25 @@ +nextflow.preview.types = true + process BISMARK_GENOMEPREPARATION { - tag "$fasta" + tag "${fasta}" label 'process_high' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/38/38e61d14ccaed82f60c967132963eb467d0fa4bccb7a21404c49b4f377735f03/data' : - 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/38/38e61d14ccaed82f60c967132963eb467d0fa4bccb7a21404c49b4f377735f03/data' + : 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47'}" input: - tuple val(meta), path(fasta, name:"BismarkIndex/") + fasta: Path + + stage: + stageAs "BismarkIndex/", fasta output: - tuple val(meta), path("BismarkIndex"), emit: index - path "versions.yml" , topic: versions + file("BismarkIndex") + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when @@ -33,7 +40,7 @@ process BISMARK_GENOMEPREPARATION { stub: def args = task.ext.args ?: '' """ - rm $fasta + rm ${fasta} mkdir -p BismarkIndex/Bisulfite_Genome/CT_conversion touch BismarkIndex/Bisulfite_Genome/CT_conversion/BS_CT.1.bt2 diff --git a/modules/nf-core/bismark/methylationextractor/main.nf b/modules/nf-core/bismark/methylationextractor/main.nf index 574953b2f..18f5e5dd0 100644 --- a/modules/nf-core/bismark/methylationextractor/main.nf +++ b/modules/nf-core/bismark/methylationextractor/main.nf @@ -1,23 +1,34 @@ +nextflow.preview.types = true + process BISMARK_METHYLATIONEXTRACTOR { - tag "$meta.id" + tag id label 'process_high' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/38/38e61d14ccaed82f60c967132963eb467d0fa4bccb7a21404c49b4f377735f03/data' : - 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/38/38e61d14ccaed82f60c967132963eb467d0fa4bccb7a21404c49b4f377735f03/data' + : 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47'}" input: - tuple val(meta), path(bam) - tuple val(meta2), path(index) + ( + id: String, + single_end: Boolean, + bam: Path, + bismark_index: Path + ): Record output: - tuple val(meta), path("*.bedGraph.gz") , emit: bedgraph - tuple val(meta), path("*.txt.gz") , emit: methylation_calls - tuple val(meta), path("*.cov.gz") , emit: coverage - tuple val(meta), path("*_splitting_report.txt"), emit: report - tuple val(meta), path("*.M-bias.txt") , emit: mbias - path "versions.yml" , topic: versions + record( + id : id, + methylation_bedgraph : file("*.bedGraph.gz"), + methylation_calls : files("*.txt.gz"), + methylation_coverage : file("*.cov.gz"), + methylation_report : file("*_splitting_report.txt"), + methylation_mbias : file("*.M-bias.txt"), + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when @@ -25,15 +36,15 @@ process BISMARK_METHYLATIONEXTRACTOR { script: def args = task.ext.args ?: '' // Assign sensible numbers for multicore and buffer_size based on bismark docs - if(!args.contains('--multicore') && task.cpus >= 6){ + if (!args.contains('--multicore') && task.cpus >= 6) { args += " --multicore ${(task.cpus / 3) as int}" } // Only set buffer_size when there are more than 6.GB of memory available - if(!args.contains('--buffer_size') && task.memory?.giga > 6){ - args += " --buffer_size ${task.memory.giga - 2}G" + if (!args.contains('--buffer_size') && task.memory?.toGiga() > 6) { + args += " --buffer_size ${task.memory.toGiga() - 2}G" } - def seqtype = meta.single_end ? '-s' : '-p' + def seqtype = single_end ? '-s' : '-p' """ bismark_methylation_extractor \\ ${bam} \\ @@ -52,7 +63,7 @@ process BISMARK_METHYLATIONEXTRACTOR { stub: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ echo | gzip > ${prefix}.bedGraph.gz echo | gzip > ${prefix}.txt.gz diff --git a/modules/nf-core/bismark/report/main.nf b/modules/nf-core/bismark/report/main.nf index 92dda5349..a58f0e832 100644 --- a/modules/nf-core/bismark/report/main.nf +++ b/modules/nf-core/bismark/report/main.nf @@ -1,18 +1,28 @@ +nextflow.preview.types = true + process BISMARK_REPORT { - tag "$meta.id" + tag id label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/38/38e61d14ccaed82f60c967132963eb467d0fa4bccb7a21404c49b4f377735f03/data' : - 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/38/38e61d14ccaed82f60c967132963eb467d0fa4bccb7a21404c49b4f377735f03/data' + : 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47'}" input: - tuple val(meta), path(align_report), path(dedup_report), path(splitting_report), path(mbias) + ( + id: String, + align_report: Path, + dedup_report: Path, + methylation_report: Path, + methylation_mbias: Path + ): Record output: - tuple val(meta), path("*report.{html,txt}"), emit: report - path "versions.yml" , topic: versions + record(id: id, bismark_report: file("*report.{html,txt}")) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when @@ -30,7 +40,7 @@ process BISMARK_REPORT { stub: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ touch ${prefix}.report.txt touch ${prefix}.report.html diff --git a/modules/nf-core/bismark/summary/main.nf b/modules/nf-core/bismark/summary/main.nf index 1855a0b61..aa0783cd1 100644 --- a/modules/nf-core/bismark/summary/main.nf +++ b/modules/nf-core/bismark/summary/main.nf @@ -1,21 +1,27 @@ +nextflow.preview.types = true + process BISMARK_SUMMARY { label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/38/38e61d14ccaed82f60c967132963eb467d0fa4bccb7a21404c49b4f377735f03/data' : - 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/38/38e61d14ccaed82f60c967132963eb467d0fa4bccb7a21404c49b4f377735f03/data' + : 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47'}" input: - val(bam) - path(align_report) - path(dedup_report) - path(splitting_report) - path(mbias) + ( + bam: Set, + align_report: Set, + dedup_report: Set, + methylation_report: Set, + methylation_mbias: Set + ): Record output: - path("*report.{html,txt}"), emit: summary - path "versions.yml" , topic: versions + files("*report.{html,txt}") + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/bwameth/align/main.nf b/modules/nf-core/bwameth/align/main.nf index b318c2da2..fbabe0bd3 100644 --- a/modules/nf-core/bwameth/align/main.nf +++ b/modules/nf-core/bwameth/align/main.nf @@ -1,29 +1,40 @@ +nextflow.preview.types = true + process BWAMETH_ALIGN { - tag "${meta.id}" + tag id label 'process_high' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bwameth:0.2.9--pyh7e72e81_0' : - 'biocontainers/bwameth:0.2.9--pyh7e72e81_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/bwameth:0.2.9--pyh7e72e81_0' + : 'biocontainers/bwameth:0.2.9--pyh7e72e81_0'}" input: - tuple val(meta), path(reads) - tuple val(meta2), path(fasta) - tuple val(meta3), path(index) + ( + id: String, + read_group: String?, + reads: Path, + fasta: Path, + index: Path + ): Record output: - tuple val(meta), path("*.bam"), emit: bam - path "versions.yml" , topic: versions + record( + id: id, + bam: file("*.bam") + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def args2 = task.ext.args2 ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def read_group = meta.read_group ? "-R ${meta.read_group}" : "" + def args = task.ext.args ?: '' + def args2 = task.ext.args2 ?: '' + def prefix = task.ext.prefix ?: id + read_group = read_group ? "-R ${read_group}" : "" """ export BWA_METH_SKIP_TIME_CHECKS=1 ln -sf \$(readlink ${fasta}) ${index}/${fasta} @@ -43,7 +54,7 @@ process BWAMETH_ALIGN { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ touch ${prefix}.bam diff --git a/modules/nf-core/bwameth/index/main.nf b/modules/nf-core/bwameth/index/main.nf index 41bd9c829..7e6be3947 100644 --- a/modules/nf-core/bwameth/index/main.nf +++ b/modules/nf-core/bwameth/index/main.nf @@ -1,19 +1,26 @@ +nextflow.preview.types = true + process BWAMETH_INDEX { - tag "$fasta" + tag "${fasta}" label 'process_high' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bwameth:0.2.9--pyh7e72e81_0' : - 'biocontainers/bwameth:0.2.9--pyh7e72e81_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/bwameth:0.2.9--pyh7e72e81_0' + : 'biocontainers/bwameth:0.2.9--pyh7e72e81_0'}" input: - tuple val(meta), path(fasta, name:"BwamethIndex/") - val use_mem2 + fasta: Path + use_mem2: Boolean + + stage: + stageAs "BwamethIndex/", fasta output: - tuple val(meta), path("BwamethIndex"), emit: index - path "versions.yml" , topic: versions + file("BwamethIndex") + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when @@ -23,9 +30,9 @@ process BWAMETH_INDEX { def index_cmd = use_mem2 ? "index-mem2" : "index" """ - bwameth.py ${index_cmd} $fasta + bwameth.py ${index_cmd} ${fasta} - rm $fasta + rm ${fasta} cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -36,7 +43,7 @@ process BWAMETH_INDEX { stub: def args = task.ext.args ?: '' """ - rm $fasta + rm ${fasta} mkdir -p BwamethIndex/ touch BwamethIndex/genome.fasta.bwameth.c2t diff --git a/modules/nf-core/cat/fastq/main.nf b/modules/nf-core/cat/fastq/main.nf index 7cd75ff80..7a9b21994 100644 --- a/modules/nf-core/cat/fastq/main.nf +++ b/modules/nf-core/cat/fastq/main.nf @@ -1,5 +1,7 @@ +nextflow.preview.types = true + process CAT_FASTQ { - tag "${meta.id}" + tag "${id}" label 'process_single' conda "${moduleDir}/environment.yml" @@ -8,19 +10,32 @@ process CAT_FASTQ { : 'community.wave.seqera.io/library/coreutils_grep_gzip_lbzip2_pruned:838ba80435a629f8'}" input: - tuple val(meta), path(reads, stageAs: "input*/*") + ( + id: String, + single_end: Boolean, + reads: List + ): Record + + stage: + stageAs "input*/*", reads output: - tuple val(meta), path("*.merged.fastq.gz"), emit: reads - path "versions.yml", topic: versions + record( + id: id, + single_end: single_end, + reads: files("*.merged.fastq.gz").toSorted() + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: - def prefix = task.ext.prefix ?: "${meta.id}" - def readList = reads instanceof List ? reads.collect { it.toString() } : [reads.toString()] - if (meta.single_end) { + def prefix = task.ext.prefix ?: "${id}" + def readList = reads.collect { it.toString() } + if (single_end) { if (readList.size >= 1) { """ cat ${readList.join(' ')} > ${prefix}.merged.fastq.gz @@ -30,7 +45,8 @@ process CAT_FASTQ { cat: \$(echo \$(cat --version 2>&1) | sed 's/^.*coreutils) //; s/ .*\$//') END_VERSIONS """ - } else { + } + else { error("Could not find any FASTQ files to concatenate in the process input") } } @@ -48,15 +64,16 @@ process CAT_FASTQ { cat: \$(echo \$(cat --version 2>&1) | sed 's/^.*coreutils) //; s/ .*\$//') END_VERSIONS """ - } else { + } + else { error("Could not find any FASTQ file pairs to concatenate in the process input") } } stub: - def prefix = task.ext.prefix ?: "${meta.id}" - def readList = reads instanceof List ? reads.collect { it.toString() } : [reads.toString()] - if (meta.single_end) { + def prefix = task.ext.prefix ?: "${id}" + def readList = reads.collect { it.toString() } + if (single_end) { if (readList.size >= 1) { """ echo '' | gzip > ${prefix}.merged.fastq.gz @@ -66,7 +83,8 @@ process CAT_FASTQ { cat: \$(echo \$(cat --version 2>&1) | sed 's/^.*coreutils) //; s/ .*\$//') END_VERSIONS """ - } else { + } + else { error("Could not find any FASTQ files to concatenate in the process input") } } @@ -81,7 +99,8 @@ process CAT_FASTQ { cat: \$(echo \$(cat --version 2>&1) | sed 's/^.*coreutils) //; s/ .*\$//') END_VERSIONS """ - } else { + } + else { error("Could not find any FASTQ file pairs to concatenate in the process input") } } diff --git a/modules/nf-core/fastqc/main.nf b/modules/nf-core/fastqc/main.nf index 31fbeb3b9..bd23d5640 100644 --- a/modules/nf-core/fastqc/main.nf +++ b/modules/nf-core/fastqc/main.nf @@ -1,30 +1,37 @@ +nextflow.preview.types = true + process FASTQC { - tag "${meta.id}" + tag id label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/fastqc:0.12.1--hdfd78af_0' : - 'biocontainers/fastqc:0.12.1--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/fastqc:0.12.1--hdfd78af_0' + : 'biocontainers/fastqc:0.12.1--hdfd78af_0'}" input: - tuple val(meta), path(reads) + (id: String, reads: List): Record output: - tuple val(meta), path("*.html"), emit: html - tuple val(meta), path("*.zip") , emit: zip - path "versions.yml" , topic: versions + record( + id: id, + fastqc_html: files("*.html"), + fastqc_zip: files("*.zip") + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: id // Make list of old name and new name pairs to use for renaming in the bash while loop - def old_new_pairs = reads instanceof Path || reads.size() == 1 ? [[ reads, "${prefix}.${reads.extension}" ]] : reads.withIndex().collect { entry, index -> [ entry, "${prefix}_${index + 1}.${entry.extension}" ] } - def rename_to = old_new_pairs*.join(' ').join(' ') - def renamed_files = old_new_pairs.collect{ _old_name, new_name -> new_name }.join(' ') + def old_new_pairs = reads.withIndex().collect { entry, index -> [entry, "${prefix}_${index + 1}.${entry.extension}"] } + def rename_to = old_new_pairs*.join(' ').join(' ') + def renamed_files = old_new_pairs.collect { _old_name, new_name -> new_name }.join(' ') // The total amount of allocated RAM by FastQC is equal to the number of threads defined (--threads) time the amount of RAM defined (--memory) // https://github.com/s-andrews/FastQC/blob/1faeea0412093224d7f6a07f777fad60a5650795/fastqc#L211-L222 @@ -51,7 +58,7 @@ process FASTQC { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ touch ${prefix}.html touch ${prefix}.zip diff --git a/modules/nf-core/gunzip/main.nf b/modules/nf-core/gunzip/main.nf index 7f6296bf9..c87040065 100644 --- a/modules/nf-core/gunzip/main.nf +++ b/modules/nf-core/gunzip/main.nf @@ -1,3 +1,5 @@ +nextflow.preview.types = true + process GUNZIP { tag "${archive}" label 'process_single' @@ -8,11 +10,13 @@ process GUNZIP { : 'community.wave.seqera.io/library/coreutils_grep_gzip_lbzip2_pruned:838ba80435a629f8'}" input: - tuple val(meta), path(archive) + archive: Path output: - tuple val(meta), path("${gunzip}"), emit: gunzip - path "versions.yml", topic: versions + file(gunzip) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when diff --git a/modules/nf-core/gunzip/tests/nextflow.config b/modules/nf-core/gunzip/tests/nextflow.config index dec776425..76e48cbc4 100644 --- a/modules/nf-core/gunzip/tests/nextflow.config +++ b/modules/nf-core/gunzip/tests/nextflow.config @@ -1,5 +1,5 @@ process { withName: GUNZIP { - ext.prefix = { "${meta.id}.xyz" } + ext.prefix = { "${id}.xyz" } } } diff --git a/modules/nf-core/methyldackel/extract/main.nf b/modules/nf-core/methyldackel/extract/main.nf index 8ea814a6a..a2b77acd0 100644 --- a/modules/nf-core/methyldackel/extract/main.nf +++ b/modules/nf-core/methyldackel/extract/main.nf @@ -1,21 +1,32 @@ +nextflow.preview.types = true + process METHYLDACKEL_EXTRACT { - tag "$meta.id" + tag id label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/methyldackel:0.6.1--he4a0461_7' : - 'biocontainers/methyldackel:0.6.1--he4a0461_7' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/methyldackel:0.6.1--he4a0461_7' + : 'biocontainers/methyldackel:0.6.1--he4a0461_7'}" input: - tuple val(meta), path(bam), path(bai) - path fasta - path fai + ( + id: String, + bam: Path, + bai: Path, + fasta: Path, + fai: Path + ): Record output: - tuple val(meta), path("*.bedGraph") , optional: true, emit: bedgraph - tuple val(meta), path("*.methylKit"), optional: true, emit: methylkit - path "versions.yml" , topic: versions + record( + id : id, + methydackel_bedgraph : file("*.bedGraph", optional: true), + methydackel_methylkit : file("*.methylKit", optional: true) + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when @@ -24,9 +35,9 @@ process METHYLDACKEL_EXTRACT { def args = task.ext.args ?: '' """ MethylDackel extract \\ - $args \\ - $fasta \\ - $bam + ${args} \\ + ${fasta} \\ + ${bam} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/methyldackel/mbias/main.nf b/modules/nf-core/methyldackel/mbias/main.nf index b452e155f..30a45c7dd 100644 --- a/modules/nf-core/methyldackel/mbias/main.nf +++ b/modules/nf-core/methyldackel/mbias/main.nf @@ -1,33 +1,44 @@ +nextflow.preview.types = true + process METHYLDACKEL_MBIAS { - tag "$meta.id" + tag id label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/methyldackel:0.6.1--he4a0461_7' : - 'biocontainers/methyldackel:0.6.1--he4a0461_7' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/methyldackel:0.6.1--he4a0461_7' + : 'biocontainers/methyldackel:0.6.1--he4a0461_7'}" input: - tuple val(meta), path(bam), path(bai) - path fasta - path fai + ( + id: String, + bam: Path, + bai: Path, + fasta: Path, + fai: Path + ): Record output: - tuple val(meta), path("*.mbias.txt"), emit: txt - path "versions.yml" , topic: versions + record( + id: id, + methydackel_mbias: file("*.mbias.txt") + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ MethylDackel mbias \\ - $args \\ - $fasta \\ - $bam \\ - $prefix \\ + ${args} \\ + ${fasta} \\ + ${bam} \\ + ${prefix} \\ --txt \\ > ${prefix}.mbias.txt @@ -38,7 +49,7 @@ process METHYLDACKEL_MBIAS { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ touch ${prefix}.mbias.txt diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index fc7be46c8..037ac921e 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -1,24 +1,30 @@ +nextflow.preview.types = true + process MULTIQC { label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.30--pyhdfd78af_0' : - 'biocontainers/multiqc:1.30--pyhdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/multiqc:1.30--pyhdfd78af_0' + : 'biocontainers/multiqc:1.30--pyhdfd78af_0'}" input: - path multiqc_files, stageAs: "?/*" - path(multiqc_config) - path(extra_multiqc_config) - path(multiqc_logo) - path(replace_names) - path(sample_names) + multiqc_files : Set + multiqc_config : Path + extra_multiqc_config : Path? + multiqc_logo : Path? + replace_names : Path? + sample_names : Path? + + stage: + stageAs "?/*", multiqc_files output: - path "*multiqc_report.html", emit: report - path "*_data" , emit: data - path "*_plots" , optional:true, emit: plots - path "versions.yml" , topic: versions + record( + report: file("*multiqc_report.html"), + data: file("*_data"), + plots: file("*_plots", optional: true) + ) when: task.ext.when == null || task.ext.when @@ -26,27 +32,22 @@ process MULTIQC { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ? "--filename ${task.ext.prefix}.html" : '' - def config = multiqc_config ? "--config $multiqc_config" : '' - def extra_config = extra_multiqc_config ? "--config $extra_multiqc_config" : '' + def config = multiqc_config ? "--config ${multiqc_config}" : '' + def extra_config = extra_multiqc_config ? "--config ${extra_multiqc_config}" : '' def logo = multiqc_logo ? "--cl-config 'custom_logo: \"${multiqc_logo}\"'" : '' def replace = replace_names ? "--replace-names ${replace_names}" : '' def samples = sample_names ? "--sample-names ${sample_names}" : '' """ multiqc \\ --force \\ - $args \\ - $config \\ - $prefix \\ - $extra_config \\ - $logo \\ - $replace \\ - $samples \\ + ${args} \\ + ${config} \\ + ${prefix} \\ + ${extra_config} \\ + ${logo} \\ + ${replace} \\ + ${samples} \\ . - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" ) - END_VERSIONS """ stub: @@ -54,10 +55,5 @@ process MULTIQC { mkdir multiqc_data mkdir multiqc_plots touch multiqc_report.html - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" ) - END_VERSIONS """ } diff --git a/modules/nf-core/parabricks/fq2bammeth/main.nf b/modules/nf-core/parabricks/fq2bammeth/main.nf index eb0fab1d0..242507a3a 100644 --- a/modules/nf-core/parabricks/fq2bammeth/main.nf +++ b/modules/nf-core/parabricks/fq2bammeth/main.nf @@ -1,23 +1,35 @@ +nextflow.preview.types = true + process PARABRICKS_FQ2BAMMETH { - tag "$meta.id" + tag id label 'process_high' label 'process_gpu' container "nvcr.io/nvidia/clara/clara-parabricks:4.3.2-1" input: - tuple val(meta), path(reads) - tuple val(meta2), path(fasta) - tuple val(meta3), path(index) - path(known_sites) + ( + id: String, + single_end: Boolean, + reads: Path, + fasta: Path, + bwameth_index: Path, + known_sites: Path? + ): Record output: - tuple val(meta), path("*.bam") , emit: bam - tuple val(meta), path("*.bai") , emit: bai - path("qc_metrics") , emit: qc_metrics, optional:true - path("*.table") , emit: bqsr_table, optional:true - path("duplicate-metrics.txt") , emit: duplicate_metrics, optional:true - path("versions.yml") , topic: versions + record( + id : id, + single_end : single_end, + bam : file("*.bam"), + bai : file("*.bai"), + qc_metrics : file(("qc_metrics"), optional: true), + bqsr_table : file(("*.table"), optional: true), + duplicate_metrics : file(("duplicate-metrics.txt"), optional: true), + ) + + topic: + file(("versions.yml")) >> 'versions' when: task.ext.when == null || task.ext.when @@ -25,30 +37,30 @@ process PARABRICKS_FQ2BAMMETH { script: // Exit if running this module with -profile conda / -profile mamba if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "Parabricks module does not support Conda. Please use Docker / Singularity / Podman instead." + error("Parabricks module does not support Conda. Please use Docker / Singularity / Podman instead.") } - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def in_fq_command = meta.single_end ? "--in-se-fq $reads" : "--in-fq $reads" - def known_sites_command = known_sites ? known_sites.collect{"--knownSites $it"}.join(' ') : "" - def known_sites_output = known_sites ? "--out-recal-file ${prefix}.table" : "" - def num_gpus = task.accelerator ? "--num-gpus $task.accelerator.request" : '' + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: id + def in_fq_command = single_end ? "--in-se-fq ${reads}" : "--in-fq ${reads}" + def known_sites_command = known_sites ? known_sites.collect { "--knownSites ${it}" }.join(' ') : "" + def known_sites_output = known_sites ? "--out-recal-file ${prefix}.table" : "" + def num_gpus = task.accelerator ? "--num-gpus ${task.accelerator.request}" : '' """ - if [ -L $fasta ]; then - ln -sf \$(readlink $fasta) $index/$fasta + if [ -L ${fasta} ]; then + ln -sf \$(readlink ${fasta}) ${bwameth_index}/${fasta} else - ln -sf ../$fasta $index/$fasta + ln -sf ../${fasta} ${bwameth_index}/${fasta} fi pbrun \\ fq2bam_meth \\ - --ref $index/$fasta \\ - $in_fq_command \\ + --ref ${bwameth_index}/${fasta} \\ + ${in_fq_command} \\ --out-bam ${prefix}.bam \\ - $known_sites_command \\ - $known_sites_output \\ - $num_gpus \\ - $args + ${known_sites_command} \\ + ${known_sites_output} \\ + ${num_gpus} \\ + ${args} cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -59,9 +71,9 @@ process PARABRICKS_FQ2BAMMETH { stub: // Exit if running this module with -profile conda / -profile mamba if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "Parabricks module does not support Conda. Please use Docker / Singularity / Podman instead." + error("Parabricks module does not support Conda. Please use Docker / Singularity / Podman instead.") } - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ touch ${prefix}.bam touch ${prefix}.bam.bai diff --git a/modules/nf-core/picard/bedtointervallist/main.nf b/modules/nf-core/picard/bedtointervallist/main.nf index 0be1f08d8..652488b3d 100644 --- a/modules/nf-core/picard/bedtointervallist/main.nf +++ b/modules/nf-core/picard/bedtointervallist/main.nf @@ -1,33 +1,41 @@ +nextflow.preview.types = true + process PICARD_BEDTOINTERVALLIST { - tag "$meta.id" + tag id label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : - 'biocontainers/picard:3.3.0--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' + : 'biocontainers/picard:3.3.0--hdfd78af_0'}" input: - tuple val(meta) , path(bed) - tuple val(meta2), path(dict) - file arguments_file + ( + id: String, + bed: Path, + reference_dict: Path, + arguments_file: Path? + ): Record output: - tuple val(meta), path('*.intervallist'), emit: intervallist - path "versions.yml" , topic: versions + record(id: id, intervallist: file('*.intervallist')) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: id def args_file = arguments_file ? "--arguments_file ${arguments_file}" : "" def avail_mem = 3072 if (!task.memory) { - log.info '[Picard BedToIntervalList] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[Picard BedToIntervalList] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.toMega() * 0.8).intValue() } """ picard \\ @@ -35,7 +43,7 @@ process PICARD_BEDTOINTERVALLIST { BedToIntervalList \\ --INPUT ${bed} \\ --OUTPUT ${prefix}.intervallist \\ - --SEQUENCE_DICTIONARY ${dict} \\ + --SEQUENCE_DICTIONARY ${reference_dict} \\ --TMP_DIR . \\ ${args_file} \\ ${args} @@ -47,12 +55,13 @@ process PICARD_BEDTOINTERVALLIST { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id def avail_mem = 3072 if (!task.memory) { - log.info '[Picard BedToIntervalList] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[Picard BedToIntervalList] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.toMega() * 0.8).intValue() } def args_file = arguments_file ? "--arguments_file ${arguments_file}" : "" """ @@ -61,7 +70,7 @@ process PICARD_BEDTOINTERVALLIST { BedToIntervalList \\ --INPUT ${bed} \\ --OUTPUT ${prefix}.intervallist \\ - --SEQUENCE_DICTIONARY ${dict} \\ + --SEQUENCE_DICTIONARY ${reference_dict} \\ --TMP_DIR . \\ ${args_file} \\ ${args}" diff --git a/modules/nf-core/picard/collecthsmetrics/main.nf b/modules/nf-core/picard/collecthsmetrics/main.nf index 63571a716..c5b55d7a4 100644 --- a/modules/nf-core/picard/collecthsmetrics/main.nf +++ b/modules/nf-core/picard/collecthsmetrics/main.nf @@ -1,65 +1,80 @@ +nextflow.preview.types = true + process PICARD_COLLECTHSMETRICS { - tag "$meta.id" + tag id label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : - 'biocontainers/picard:3.3.0--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' + : 'biocontainers/picard:3.3.0--hdfd78af_0'}" input: - tuple val(meta), path(bam), path(bai), path(bait_intervals, stageAs: "baits/*"), path(target_intervals, stageAs: 'targets/*') - tuple val(meta2), path(fasta) - tuple val(meta3), path(fai) - tuple val(meta4), path(dict) + ( + id: String, + bam: Path, + bai: Path, + bait_intervals: Set, + target_intervals: Set, + fasta: Path, + fai: Path, + reference_dict: Path + ): Record + + stage: + stageAs "baits/*", bait_intervals + stageAs 'targets/*', target_intervals output: - tuple val(meta), path("*_metrics") , emit: metrics - path "versions.yml" , topic: versions + record(id: id, picard_hsmetrics: file("*_metrics")) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" def avail_mem = 3072 if (!task.memory) { - log.info '[Picard CollectHsMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[Picard CollectHsMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.toMega() * 0.8).intValue() } def bait_interval_list = bait_intervals def bait_intervallist_cmd = "" - if (bait_intervals =~ /.(bed|bed.gz)$/){ + if (bait_intervals =~ /.(bed|bed.gz)$/) { bait_interval_list = bait_intervals.toString().replaceAll(/.(bed|bed.gz)$/, ".interval_list") - bait_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${bait_intervals} --OUTPUT ${bait_interval_list} --SEQUENCE_DICTIONARY ${dict} --TMP_DIR ." + bait_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${bait_intervals} --OUTPUT ${bait_interval_list} --SEQUENCE_DICTIONARY ${reference_dict} --TMP_DIR ." } def target_interval_list = target_intervals def target_intervallist_cmd = "" - if (target_intervals =~ /.(bed|bed.gz)$/){ + if (target_intervals =~ /.(bed|bed.gz)$/) { target_interval_list = target_intervals.toString().replaceAll(/.(bed|bed.gz)$/, ".interval_list") - target_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${target_intervals} --OUTPUT ${target_interval_list} --SEQUENCE_DICTIONARY ${dict} --TMP_DIR ." + target_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${target_intervals} --OUTPUT ${target_interval_list} --SEQUENCE_DICTIONARY ${reference_dict} --TMP_DIR ." } """ - $bait_intervallist_cmd - $target_intervallist_cmd + ${bait_intervallist_cmd} + ${target_intervallist_cmd} picard \\ -Xmx${avail_mem}M \\ CollectHsMetrics \\ - $args \\ - $reference \\ - --BAIT_INTERVALS $bait_interval_list \\ - --TARGET_INTERVALS $target_interval_list \\ - --INPUT $bam \\ + ${args} \\ + ${reference} \\ + --BAIT_INTERVALS ${bait_interval_list} \\ + --TARGET_INTERVALS ${target_interval_list} \\ + --INPUT ${bam} \\ --OUTPUT ${prefix}.CollectHsMetrics.coverage_metrics @@ -70,7 +85,7 @@ process PICARD_COLLECTHSMETRICS { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ touch ${prefix}.CollectHsMetrics.coverage_metrics diff --git a/modules/nf-core/picard/createsequencedictionary/main.nf b/modules/nf-core/picard/createsequencedictionary/main.nf index 8ec627cb9..7667833fb 100644 --- a/modules/nf-core/picard/createsequencedictionary/main.nf +++ b/modules/nf-core/picard/createsequencedictionary/main.nf @@ -1,37 +1,42 @@ +nextflow.preview.types = true + process PICARD_CREATESEQUENCEDICTIONARY { - tag "$meta.id" + tag id label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : - 'biocontainers/picard:3.3.0--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' + : 'biocontainers/picard:3.3.0--hdfd78af_0'}" input: - tuple val(meta), path(fasta) + (id: String, fasta: Path): Record output: - tuple val(meta), path("*.dict"), emit: reference_dict - path "versions.yml" , topic: versions + record(id: id, reference_dict: file("*.dict")) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id def avail_mem = 3072 if (!task.memory) { - log.info '[Picard CreateSequenceDictionary] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[Picard CreateSequenceDictionary] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.toMega() * 0.8).intValue() } """ picard \\ -Xmx${avail_mem}M \\ CreateSequenceDictionary \\ - $args \\ - --REFERENCE $fasta \\ + ${args} \\ + --REFERENCE ${fasta} \\ --OUTPUT ${prefix}.dict cat <<-END_VERSIONS > versions.yml @@ -41,7 +46,7 @@ process PICARD_CREATESEQUENCEDICTIONARY { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ touch ${prefix}.dict @@ -50,5 +55,4 @@ process PICARD_CREATESEQUENCEDICTIONARY { picard: \$(echo \$(picard CreateSequenceDictionary --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:) END_VERSIONS """ - } diff --git a/modules/nf-core/picard/markduplicates/main.nf b/modules/nf-core/picard/markduplicates/main.nf index 04aac47d3..fab57da79 100644 --- a/modules/nf-core/picard/markduplicates/main.nf +++ b/modules/nf-core/picard/markduplicates/main.nf @@ -1,49 +1,62 @@ +nextflow.preview.types = true + process PICARD_MARKDUPLICATES { - tag "$meta.id" + tag id label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : - 'biocontainers/picard:3.3.0--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' + : 'biocontainers/picard:3.3.0--hdfd78af_0'}" input: - tuple val(meta), path(reads) - tuple val(meta2), path(fasta) - tuple val(meta3), path(fai) + ( + id: String, + reads: Path, + fasta: Path, + fai: Path + ): Record output: - tuple val(meta), path("*.bam") , emit: bam, optional: true - tuple val(meta), path("*.bai") , emit: bai, optional: true - tuple val(meta), path("*.cram"), emit: cram, optional: true - tuple val(meta), path("*.metrics.txt"), emit: metrics - path "versions.yml" , topic: versions + record( + id : id, + bam : file("*.bam", optional: true), + bai : file("*.bai", optional: true), + cram : file("*.cram", optional: true), + picard_metrics : file("*.metrics.txt"), + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def suffix = task.ext.suffix ?: "${reads.getExtension()}" + def prefix = task.ext.prefix ?: id + def suffix = task.ext.suffix ?: "${reads.getExtension()}" def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" def avail_mem = 3072 if (!task.memory) { - log.info '[Picard MarkDuplicates] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[Picard MarkDuplicates] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.toMega() * 0.8).intValue() } - if ("$reads" == "${prefix}.${suffix}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + if ("${reads}" == "${prefix}.${suffix}") { + error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + } """ picard \\ -Xmx${avail_mem}M \\ MarkDuplicates \\ - $args \\ - --INPUT $reads \\ + ${args} \\ + --INPUT ${reads} \\ --OUTPUT ${prefix}.${suffix} \\ - $reference \\ + ${reference} \\ --METRICS_FILE ${prefix}.MarkDuplicates.metrics.txt cat <<-END_VERSIONS > versions.yml @@ -53,9 +66,11 @@ process PICARD_MARKDUPLICATES { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" - def suffix = task.ext.suffix ?: "${reads.getExtension()}" - if ("$reads" == "${prefix}.${suffix}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + def prefix = task.ext.prefix ?: id + def suffix = task.ext.suffix ?: "${reads.getExtension()}" + if ("${reads}" == "${prefix}.${suffix}") { + error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + } """ touch ${prefix}.${suffix} touch ${prefix}.MarkDuplicates.metrics.txt diff --git a/modules/nf-core/picard/markduplicates/tests/nextflow.config b/modules/nf-core/picard/markduplicates/tests/nextflow.config index 02818dd6e..012c34636 100644 --- a/modules/nf-core/picard/markduplicates/tests/nextflow.config +++ b/modules/nf-core/picard/markduplicates/tests/nextflow.config @@ -1,6 +1,6 @@ process { withName: PICARD_MARKDUPLICATES { - ext.prefix = { "${meta.id}.marked" } + ext.prefix = { "${id}.marked" } ext.args = '--ASSUME_SORT_ORDER queryname' } } diff --git a/modules/nf-core/preseq/lcextrap/main.nf b/modules/nf-core/preseq/lcextrap/main.nf index b91770833..9c8c08d2b 100644 --- a/modules/nf-core/preseq/lcextrap/main.nf +++ b/modules/nf-core/preseq/lcextrap/main.nf @@ -1,36 +1,48 @@ +nextflow.preview.types = true + process PRESEQ_LCEXTRAP { - tag "$meta.id" + tag id label 'process_single' label 'error_retry' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/preseq:3.2.0--hdcf5f25_6': - 'biocontainers/preseq:3.2.0--hdcf5f25_6' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/preseq:3.2.0--hdcf5f25_6' + : 'biocontainers/preseq:3.2.0--hdcf5f25_6'}" input: - tuple val(meta), path(bam) + ( + id: String, + single_end: Boolean, + bam: Path + ): Record output: - tuple val(meta), path("*.lc_extrap.txt"), emit: lc_extrap - tuple val(meta), path("*.log") , emit: log - path "versions.yml" , topic: versions + record( + id: id, + lc_extrap: file("*.lc_extrap.txt"), + lc_log: file("*.log") + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - args = task.attempt > 1 ? args.join(' -defects') : args // Disable testing for defects - def prefix = task.ext.prefix ?: "${meta.id}" - def paired_end = meta.single_end ? '' : '-pe' + args = task.attempt > 1 ? args.join(' -defects') : args + // Disable testing for defects + def prefix = task.ext.prefix ?: id + def paired_end = single_end ? '' : '-pe' """ preseq \\ lc_extrap \\ - $args \\ - $paired_end \\ + ${args} \\ + ${paired_end} \\ -output ${prefix}.lc_extrap.txt \\ - $bam + ${bam} cp .command.err ${prefix}.command.log cat <<-END_VERSIONS > versions.yml @@ -40,7 +52,7 @@ process PRESEQ_LCEXTRAP { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ touch ${prefix}.lc_extrap.txt touch ${prefix}.command.log diff --git a/modules/nf-core/qualimap/bamqc/main.nf b/modules/nf-core/qualimap/bamqc/main.nf index 98dffcdbe..690682125 100644 --- a/modules/nf-core/qualimap/bamqc/main.nf +++ b/modules/nf-core/qualimap/bamqc/main.nf @@ -1,51 +1,58 @@ +nextflow.preview.types = true + process QUALIMAP_BAMQC { - tag "$meta.id" + tag id label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/qualimap:2.3--hdfd78af_0' : - 'biocontainers/qualimap:2.3--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/qualimap:2.3--hdfd78af_0' + : 'biocontainers/qualimap:2.3--hdfd78af_0'}" input: - tuple val(meta), path(bam) - path gff + ( + id: String, + single_end: Boolean, + strandedness: String?, + bam: Path + ): Record + gff: Path output: - tuple val(meta), path("${prefix}"), emit: results - path "versions.yml" , topic: versions + record(id: id, qualimap_bamqc: file("${prefix}")) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: id + + def collect_pairs = single_end ? '' : '--collect-overlap-pairs' + def memory = (task.memory.toMega() * 0.8).intValue() + 'M' + def regions = gff ? "--gff ${gff}" : '' - def collect_pairs = meta.single_end ? '' : '--collect-overlap-pairs' - def memory = (task.memory.mega*0.8).intValue() + 'M' - def regions = gff ? "--gff $gff" : '' + strandedness = strandedness + ? "strand-specific-${strandedness}" + : 'non-strand-specific' - def strandedness = 'non-strand-specific' - if (meta.strandedness == 'forward') { - strandedness = 'strand-specific-forward' - } else if (meta.strandedness == 'reverse') { - strandedness = 'strand-specific-reverse' - } """ unset DISPLAY mkdir -p tmp export _JAVA_OPTIONS=-Djava.io.tmpdir=./tmp qualimap \\ - --java-mem-size=$memory \\ + --java-mem-size=${memory} \\ bamqc \\ - $args \\ - -bam $bam \\ - $regions \\ - -p $strandedness \\ - $collect_pairs \\ - -outdir $prefix \\ - -nt $task.cpus + ${args} \\ + -bam ${bam} \\ + ${regions} \\ + -p ${strandedness} \\ + ${collect_pairs} \\ + -outdir ${prefix} \\ + -nt ${task.cpus} cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -54,12 +61,12 @@ process QUALIMAP_BAMQC { """ stub: - prefix = task.ext.suffix ? "${meta.id}${task.ext.suffix}" : "${meta.id}" + prefix = task.ext.suffix ? "${id}${task.ext.suffix}" : id """ - mkdir -p $prefix/css - mkdir $prefix/images_qualimapReport - mkdir $prefix/raw_data_qualimapReport - cd $prefix/css + mkdir -p ${prefix}/css + mkdir ${prefix}/images_qualimapReport + mkdir ${prefix}/raw_data_qualimapReport + cd ${prefix}/css touch agogo.css touch basic.css touch bgtop.png diff --git a/modules/nf-core/qualimap/bamqccram/main.nf b/modules/nf-core/qualimap/bamqccram/main.nf index 9ace6faa7..61a83c1e9 100644 --- a/modules/nf-core/qualimap/bamqccram/main.nf +++ b/modules/nf-core/qualimap/bamqccram/main.nf @@ -25,7 +25,7 @@ process QUALIMAP_BAMQCCRAM { prefix = task.ext.prefix ?: "${meta.id}" def collect_pairs = meta.single_end ? '' : '--collect-overlap-pairs' - def memory = (task.memory.mega*0.8).intValue() + 'M' + def memory = (task.memory.toMega()*0.8).intValue() + 'M' def regions = gff ? "--gff $gff" : '' def strandedness = 'non-strand-specific' diff --git a/modules/nf-core/samtools/faidx/main.nf b/modules/nf-core/samtools/faidx/main.nf index db58d63ab..027ace3f3 100644 --- a/modules/nf-core/samtools/faidx/main.nf +++ b/modules/nf-core/samtools/faidx/main.nf @@ -1,23 +1,29 @@ +nextflow.preview.types = true + process SAMTOOLS_FAIDX { - tag "$fasta" + tag "${fasta}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' + : 'biocontainers/samtools:1.21--h50ea8bc_0'}" input: - tuple val(meta), path(fasta) - tuple val(meta2), path(fai) - val get_sizes + fasta: Path + fai: Path? + get_sizes: Boolean output: - tuple val(meta), path ("*.{fa,fasta}") , emit: fa, optional: true - tuple val(meta), path ("*.sizes") , emit: sizes, optional: true - tuple val(meta), path ("*.fai") , emit: fai, optional: true - tuple val(meta), path ("*.gzi") , emit: gzi, optional: true - path "versions.yml" , topic: versions + record( + fa : file("*.{fa,fasta}", optional: true), + sizes : file("*.sizes", optional: true), + fai : file("*.fai", optional: true), + gzi : file("*.gzi", optional: true) + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when @@ -28,8 +34,8 @@ process SAMTOOLS_FAIDX { """ samtools \\ faidx \\ - $fasta \\ - $args + ${fasta} \\ + ${args} ${get_sizes_command} diff --git a/modules/nf-core/samtools/flagstat/main.nf b/modules/nf-core/samtools/flagstat/main.nf index f79d01c48..42caa5dfa 100644 --- a/modules/nf-core/samtools/flagstat/main.nf +++ b/modules/nf-core/samtools/flagstat/main.nf @@ -1,29 +1,40 @@ +nextflow.preview.types = true + process SAMTOOLS_FLAGSTAT { - tag "$meta.id" + tag id label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' + : 'biocontainers/samtools:1.21--h50ea8bc_0'}" input: - tuple val(meta), path(bam), path(bai) + ( + id: String, + bam: Path, + bai: Path + ): Record output: - tuple val(meta), path("*.flagstat"), emit: flagstat - path "versions.yml" , topic: versions + record( + id: id, + samtools_flagstat: file("*.flagstat") + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ samtools \\ flagstat \\ --threads ${task.cpus} \\ - $bam \\ + ${bam} \\ > ${prefix}.flagstat cat <<-END_VERSIONS > versions.yml @@ -33,7 +44,7 @@ process SAMTOOLS_FLAGSTAT { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ touch ${prefix}.flagstat diff --git a/modules/nf-core/samtools/index/main.nf b/modules/nf-core/samtools/index/main.nf index 310c3db55..0701779ea 100644 --- a/modules/nf-core/samtools/index/main.nf +++ b/modules/nf-core/samtools/index/main.nf @@ -1,20 +1,27 @@ +nextflow.preview.types = true + process SAMTOOLS_INDEX { - tag "$meta.id" + tag id label 'process_low' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' + : 'biocontainers/samtools:1.21--h50ea8bc_0'}" input: - tuple val(meta), path(input) + (id: String, input: Path): Record output: - tuple val(meta), path("*.bai") , optional:true, emit: bai - tuple val(meta), path("*.csi") , optional:true, emit: csi - tuple val(meta), path("*.crai"), optional:true, emit: crai - path "versions.yml" , topic: versions + record( + id : id, + bai : file("*.bai", optional: true), + csi : file("*.csi", optional: true), + crai : file("*.crai", optional: true), + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when @@ -25,8 +32,8 @@ process SAMTOOLS_INDEX { samtools \\ index \\ -@ ${task.cpus} \\ - $args \\ - $input + ${args} \\ + ${input} cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -36,8 +43,9 @@ process SAMTOOLS_INDEX { stub: def args = task.ext.args ?: '' - def extension = file(input).getExtension() == 'cram' ? - "crai" : args.contains("-c") ? "csi" : "bai" + def extension = input.getExtension() == 'cram' + ? "crai" + : args.contains("-c") ? "csi" : "bai" """ touch ${input}.${extension} diff --git a/modules/nf-core/samtools/sort/main.nf b/modules/nf-core/samtools/sort/main.nf index f26b3d460..c9ce00170 100644 --- a/modules/nf-core/samtools/sort/main.nf +++ b/modules/nf-core/samtools/sort/main.nf @@ -1,43 +1,57 @@ +nextflow.preview.types = true + process SAMTOOLS_SORT { - tag "$meta.id" + tag id label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' + : 'biocontainers/samtools:1.21--h50ea8bc_0'}" input: - tuple val(meta) , path(bam) - tuple val(meta2), path(fasta) + ( + id: String, + bam: Path, + fasta: Path? + ): Record output: - tuple val(meta), path("*.bam"), emit: bam, optional: true - tuple val(meta), path("*.cram"), emit: cram, optional: true - tuple val(meta), path("*.crai"), emit: crai, optional: true - tuple val(meta), path("*.csi"), emit: csi, optional: true - path "versions.yml", topic: versions + record( + id : id, + bam : file("*.bam", optional: true), + cram : file("*.cram", optional: true), + crai : file("*.crai", optional: true), + csi : file("*.csi", optional: true), + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def extension = args.contains("--output-fmt sam") ? "sam" : - args.contains("--output-fmt cram") ? "cram" : - "bam" + def prefix = task.ext.prefix ?: id + def extension = args.contains("--output-fmt sam") + ? "sam" + : args.contains("--output-fmt cram") + ? "cram" + : "bam" def reference = fasta ? "--reference ${fasta}" : "" - if ("$bam" == "${prefix}.bam") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + if ("${bam}" == "${prefix}.bam") { + error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + } """ samtools cat \\ ${bam} \\ | \\ samtools sort \\ - $args \\ + ${args} \\ -T ${prefix} \\ - --threads $task.cpus \\ + --threads ${task.cpus} \\ ${reference} \\ -o ${prefix}.${extension} \\ - @@ -50,10 +64,12 @@ process SAMTOOLS_SORT { stub: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def extension = args.contains("--output-fmt sam") ? "sam" : - args.contains("--output-fmt cram") ? "cram" : - "bam" + def prefix = task.ext.prefix ?: id + def extension = args.contains("--output-fmt sam") + ? "sam" + : args.contains("--output-fmt cram") + ? "cram" + : "bam" """ touch ${prefix}.${extension} if [ "${extension}" == "bam" ]; diff --git a/modules/nf-core/samtools/sort/tests/nextflow.config b/modules/nf-core/samtools/sort/tests/nextflow.config index f642771f5..abf760964 100644 --- a/modules/nf-core/samtools/sort/tests/nextflow.config +++ b/modules/nf-core/samtools/sort/tests/nextflow.config @@ -1,7 +1,7 @@ process { withName: SAMTOOLS_SORT { - ext.prefix = { "${meta.id}.sorted" } + ext.prefix = { "${id}.sorted" } ext.args = "--write-index" } diff --git a/modules/nf-core/samtools/sort/tests/nextflow_cram.config b/modules/nf-core/samtools/sort/tests/nextflow_cram.config index 3a8c0188b..5e8f909e4 100644 --- a/modules/nf-core/samtools/sort/tests/nextflow_cram.config +++ b/modules/nf-core/samtools/sort/tests/nextflow_cram.config @@ -1,7 +1,7 @@ process { withName: SAMTOOLS_SORT { - ext.prefix = { "${meta.id}.sorted" } + ext.prefix = { "${id}.sorted" } ext.args = "--write-index --output-fmt cram" } diff --git a/modules/nf-core/samtools/stats/main.nf b/modules/nf-core/samtools/stats/main.nf index 157244b8e..600d3e811 100644 --- a/modules/nf-core/samtools/stats/main.nf +++ b/modules/nf-core/samtools/stats/main.nf @@ -1,25 +1,36 @@ +nextflow.preview.types = true + process SAMTOOLS_STATS { - tag "$meta.id" + tag id label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' + : 'biocontainers/samtools:1.21--h50ea8bc_0'}" input: - tuple val(meta), path(input), path(input_index) - tuple val(meta2), path(fasta) + ( + id: String, + input: Path, + input_index: Path, + fasta: Path? + ): Record output: - tuple val(meta), path("*.stats"), emit: stats - path "versions.yml" , topic: versions + record( + id: id, + samtools_stats: file("*.stats") + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when script: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id def reference = fasta ? "--reference ${fasta}" : "" """ samtools \\ @@ -36,7 +47,7 @@ process SAMTOOLS_STATS { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: id """ touch ${prefix}.stats diff --git a/modules/nf-core/trimgalore/main.nf b/modules/nf-core/trimgalore/main.nf index cc6a5d00e..f5574aa6f 100644 --- a/modules/nf-core/trimgalore/main.nf +++ b/modules/nf-core/trimgalore/main.nf @@ -1,5 +1,7 @@ +nextflow.preview.types = true + process TRIMGALORE { - tag "${meta.id}" + tag id label 'process_high' conda "${moduleDir}/environment.yml" @@ -8,15 +10,25 @@ process TRIMGALORE { : 'community.wave.seqera.io/library/cutadapt_trim-galore_pigz:a98edd405b34582d'}" input: - tuple val(meta), path(reads) + ( + id: String, + single_end: Boolean, + reads: List + ): Record output: - tuple val(meta), path("*{3prime,5prime,trimmed,val}{,_1,_2}.fq.gz"), emit: reads - tuple val(meta), path("*report.txt") , emit: log, optional: true - tuple val(meta), path("*unpaired{,_1,_2}.fq.gz") , emit: unpaired, optional: true - tuple val(meta), path("*.html") , emit: html, optional: true - tuple val(meta), path("*.zip") , emit: zip, optional: true - path "versions.yml" , topic: versions + record( + id: id, + single_end: single_end, + trim_reads : files("*{3prime,5prime,trimmed,val}{,_1,_2}.fq.gz").toSorted(), + trim_log : files("*report.txt", optional: true).toSorted(), + trim_unpaired : files("*unpaired{,_1,_2}.fq.gz", optional: true).toSorted(), + trim_html : files("*.html", optional: true).toSorted(), + trim_zip : files("*.zip", optional: true).toSorted(), + ) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when @@ -29,7 +41,7 @@ process TRIMGALORE { def cores = 1 if (task.cpus) { cores = (task.cpus as int) - 4 - if (meta.single_end) { + if (single_end) { cores = (task.cpus as int) - 3 } if (cores < 1) { @@ -41,12 +53,12 @@ process TRIMGALORE { } // Added soft-links to original fastqs for consistent naming in MultiQC - def prefix = task.ext.prefix ?: "${meta.id}" - if (meta.single_end) { + def prefix = task.ext.prefix ?: id + if (single_end) { def args_list = args.split("\\s(?=--)").toList() args_list.removeAll { it.toLowerCase().contains('_r2 ') } """ - [ ! -f ${prefix}.fastq.gz ] && ln -s ${reads} ${prefix}.fastq.gz + [ ! -f ${prefix}.fastq.gz ] && ln -s ${reads[0]} ${prefix}.fastq.gz trim_galore \\ ${args_list.join(' ')} \\ --cores ${cores} \\ @@ -83,8 +95,8 @@ process TRIMGALORE { } stub: - def prefix = task.ext.prefix ?: "${meta.id}" - if (meta.single_end) { + def prefix = task.ext.prefix ?: id + if (single_end) { output_command = "echo '' | gzip > ${prefix}_trimmed.fq.gz ;" output_command += "touch ${prefix}.fastq.gz_trimming_report.txt" } diff --git a/modules/nf-core/untar/main.nf b/modules/nf-core/untar/main.nf index 1ea3945c1..7aef57319 100644 --- a/modules/nf-core/untar/main.nf +++ b/modules/nf-core/untar/main.nf @@ -1,3 +1,5 @@ +nextflow.preview.types = true + process UNTAR { tag "${archive}" label 'process_single' @@ -8,11 +10,13 @@ process UNTAR { : 'community.wave.seqera.io/library/coreutils_grep_gzip_lbzip2_pruned:838ba80435a629f8'}" input: - tuple val(meta), path(archive) + archive: Path output: - tuple val(meta), path("${prefix}"), emit: untar - path "versions.yml", topic: versions + file(prefix) + + topic: + file("versions.yml") >> 'versions' when: task.ext.when == null || task.ext.when @@ -20,7 +24,7 @@ process UNTAR { script: def args = task.ext.args ?: '' def args2 = task.ext.args2 ?: '' - prefix = task.ext.prefix ?: (meta.id ? "${meta.id}" : archive.baseName.toString().replaceFirst(/\.tar$/, "")) + prefix = task.ext.prefix ?: archive.baseName.toString().replaceFirst(/\.tar$/, "") """ mkdir ${prefix} @@ -50,7 +54,7 @@ process UNTAR { """ stub: - prefix = task.ext.prefix ?: (meta.id ? "${meta.id}" : archive.toString().replaceFirst(/\.[^\.]+(.gz)?$/, "")) + prefix = task.ext.prefix ?: archive.toString().replaceFirst(/\.[^\.]+(.gz)?$/, "") """ mkdir ${prefix} ## Dry-run untaring the archive to get the files and place all in prefix diff --git a/nextflow.config b/nextflow.config index 4436e6c9e..fe74584cb 100644 --- a/nextflow.config +++ b/nextflow.config @@ -9,109 +9,15 @@ // Global default params, used in configs params { - // Input options - input = null - // References - genome = null igenomes_base = 's3://ngi-igenomes/igenomes/' igenomes_ignore = false - // MultiQC options - multiqc_config = null - multiqc_title = null - multiqc_logo = null - max_multiqc_email_size = '25.MB' - multiqc_methods_description = null - - // Intermediate files - save_reference = false - save_align_intermeds = false - unmapped = false - save_trimmed = false - - // Alignment options - aligner = 'bismark' - use_mem2 = false - - // Library presets - pbat = false - rrbs = false - slamseq = false - em_seq = false - single_cell = false - accel = false - zymo = false - - // Trimming options - clip_r1 = 0 - clip_r2 = 0 - three_prime_clip_r1 = 0 - three_prime_clip_r2 = 0 - nextseq_trim = 0 - length_trim = null - skip_trimming_presets = false - - // Bismark options - non_directional = false - cytosine_report = false - relax_mismatches = false - num_mismatches = 0.6 - // 0.6 will allow a penalty of bp * -0.6 - // For 100bp reads, this is -60. Mismatches cost -6, gap opening -5 and gap extension -2 - // So -60 would allow 10 mismatches or ~ 8 x 1-2bp indels - // Bismark default is 0.2 (L,0,-0.2), Bowtie2 default is 0.6 (L,0,-0.6) - meth_cutoff = null - no_overlap = true - ignore_r1 = 0 - ignore_r2 = 2 - ignore_3prime_r1 = 0 - ignore_3prime_r2 = 2 - known_splices = null - local_alignment = false - minins = null - maxins = null - nomeseq = false - comprehensive = false - - // bwa-meth options - all_contexts = false - merge_context = false - min_depth = 0 - ignore_flags = false - methyl_kit = false - - - // Skipping options - skip_trimming = false - skip_deduplication = false - skip_fastqc = false - skip_multiqc = false - - // Run options - run_preseq = false - run_qualimap = false - run_targeted_sequencing = false - - // Qualimap options - bamqc_regions_file = null - - // Targeted sequencing options - target_regions_file = null - collecthsmetrics = false - // Boilerplate options - outdir = null publish_dir_mode = 'copy' - email = null - email_on_fail = null - plaintext_email = false - monochrome_logs = false - hook_url = null help = false help_full = false show_hidden = false - version = false pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/methylseq/' trace_report_suffix = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss')// Config options config_profile_name = null @@ -121,9 +27,6 @@ params { custom_config_base = "https://raw.githubusercontent.com/nf-core/configs/${params.custom_config_version}" config_profile_contact = null config_profile_url = null - - // Schema validation default options - validate_params = true } // Load base.config by default for all pipelines @@ -134,7 +37,6 @@ profiles { dumpHashes = true process.beforeScript = 'echo $HOSTNAME' cleanup = false - nextflow.enable.configProcessNamesValidation = true } conda { conda.enabled = true @@ -407,27 +309,6 @@ validation { command = "nextflow run nf-core/methylseq -profile --input samplesheet.csv --outdir " fullParameter = "help_full" showHiddenParameter = "show_hidden" - beforeText = """ --\033[2m----------------------------------------------------\033[0m- - \033[0;32m,--.\033[0;30m/\033[0;32m,-.\033[0m -\033[0;34m ___ __ __ __ ___ \033[0;32m/,-._.--~\'\033[0m -\033[0;34m |\\ | |__ __ / ` / \\ |__) |__ \033[0;33m} {\033[0m -\033[0;34m | \\| | \\__, \\__/ | \\ |___ \033[0;32m\\`-._,-`-,\033[0m - \033[0;32m`._,._,\'\033[0m -\033[0;35m nf-core/methylseq ${manifest.version}\033[0m --\033[2m----------------------------------------------------\033[0m- -""" - afterText = """${manifest.doi ? "* The pipeline\n" : ""}${manifest.doi.tokenize(",").collect { " https://doi.org/${it.trim().replace('https://doi.org/','')}"}.join("\n")}${manifest.doi ? "\n" : ""} -* The nf-core framework - https://doi.org/10.1038/s41587-020-0439-x - -* Software dependencies - https://github.com/nf-core/methylseq/blob/master/CITATIONS.md -""" - } - summary { - beforeText = validation.help.beforeText - afterText = validation.help.afterText } } diff --git a/subworkflows/local/targeted_sequencing/main.nf b/subworkflows/local/targeted_sequencing/main.nf index dee16932f..f1e7c3720 100644 --- a/subworkflows/local/targeted_sequencing/main.nf +++ b/subworkflows/local/targeted_sequencing/main.nf @@ -11,88 +11,83 @@ include { PICARD_CREATESEQUENCEDICTIONARY } from '../../../modules/nf-core/picar include { PICARD_BEDTOINTERVALLIST } from '../../../modules/nf-core/picard/bedtointervallist/main' include { PICARD_COLLECTHSMETRICS } from '../../../modules/nf-core/picard/collecthsmetrics/main' +include { combineWith ; joinById } from '../../../utils/ops.nf' + workflow TARGETED_SEQUENCING { take: - ch_bedgraph // channel: [ val(meta), [ bedGraph(s) ]] when bwameth, [ val(meta), bedGraph ] when bismark - ch_target_regions // channel: path(target_regions.bed) - ch_fasta // channel: [ [:], /path/to/genome.fa] - ch_fasta_index // channel: [ val(meta), /path/to/genome.fa.fai] - ch_bam // channel: [ val(meta), [ bam ] ] ## BAM from alignment - ch_bai // channel: [ val(meta), [ bai ] ] ## BAI from alignment - collecthsmetrics // boolean: whether to run Picard CollectHsMetrics + ch_inputs: Channel + val_target_regions: Value + val_fasta: Value + val_fasta_index: Value + collecthsmetrics: Boolean main: - ch_picard_metrics = channel.empty() - /* * Intersect bedGraph files with target regions * Ensure ch_bedgraph contains the bedGraph file(s) in an array and split into individual bedGraphs */ - ch_bedgraphs_target = ch_bedgraph - .map { meta, bedgraphs -> tuple(meta, bedgraphs instanceof List ? bedgraphs : [bedgraphs]) } - .flatMap { meta, bedgraphs -> bedgraphs.collect { bedgraph -> [meta, bedgraph] } } - .combine(ch_target_regions) + ch_intersect_inputs = ch_inputs.map { r -> record(id: r.id, intervals1: r.bedgraph) } + ch_intersect_inputs = combineWith(ch_intersect_inputs, intervals2: val_target_regions) - BEDTOOLS_INTERSECT( - ch_bedgraphs_target, - [[:], []] - ) + ch_results = BEDTOOLS_INTERSECT( ch_intersect_inputs ) /* * Run Picard CollectHSMetrics */ if (collecthsmetrics) { - // Create target regions with meta for Picard tools - target_regions_with_meta = ch_target_regions.map { target_file -> - tuple(["id": file(target_file).baseName], target_file) - } /* * Creation of a dictionary for the reference genome */ - PICARD_CREATESEQUENCEDICTIONARY(ch_fasta) - ch_sequence_dictionary = PICARD_CREATESEQUENCEDICTIONARY.out.reference_dict + val_reference_dict_inputs = val_fasta.map { fa -> record(id: fa.baseName, fasta: fa) } + val_reference_dict = PICARD_CREATESEQUENCEDICTIONARY( val_reference_dict_inputs ).map { r -> r.reference_dict } /* * Conversion of the covered targets BED file to an interval list */ - PICARD_BEDTOINTERVALLIST( - target_regions_with_meta, - ch_sequence_dictionary, - [] - ) - ch_intervals = PICARD_BEDTOINTERVALLIST.out.intervallist.map { it[1] } + val_intervallist_inputs = val_target_regions.map { tr -> record(id: tr.baseName, bed: tr) } + val_intervallist_inputs = combineWith(val_intervallist_inputs, reference_dict: val_reference_dict) + val_intervallist = PICARD_BEDTOINTERVALLIST( val_intervallist_inputs ).map { r -> r.intervallist } /* * Generation of the metrics * Note: Using the same intervals for both target and bait as they are typically * the same for targeted methylation sequencing experiments */ - ch_picard_inputs = ch_bam.join(ch_bai) - .combine(ch_intervals) - .combine(ch_intervals) - .combine(ch_fasta) - .combine(ch_fasta_index) - .combine(ch_sequence_dictionary) - .multiMap { meta, bam, bai, intervals1, intervals2, meta_fasta, fasta, meta_fasta_index, fasta_index, meta_dict, dict -> - bam_etc: [ meta, bam, bai, intervals1, intervals2 ] // intervals: baits, targets - fasta: [ meta_fasta, fasta ] - fasta_index: [ meta_fasta_index, fasta_index ] - dict: [ meta_dict, dict ] - } - - PICARD_COLLECTHSMETRICS( - ch_picard_inputs.bam_etc, - ch_picard_inputs.fasta, - ch_picard_inputs.fasta_index, - ch_picard_inputs.dict + ch_picard_inputs = combineWith( + ch_inputs, + bait_intervals: val_intervallist, + target_intervals: val_intervallist, + fasta: val_fasta, + fai: val_fasta_index, + reference_dict: val_reference_dict ) - ch_picard_metrics = PICARD_COLLECTHSMETRICS.out.metrics + + ch_picard_hsmetrics = PICARD_COLLECTHSMETRICS( ch_picard_inputs ) + ch_results = joinById(ch_results, ch_picard_hsmetrics) + } else { + val_reference_dict = null + val_intervallist = null } emit: - bedgraph_filtered = BEDTOOLS_INTERSECT.out.intersect // channel: [ val(meta), path("*.bedGraph") ] - picard_metrics = ch_picard_metrics // channel: [ val(meta), path("*_metrics") ] + results : Channel = ch_results + reference_dict : Value? = val_reference_dict + intervallist : Value? = val_intervallist +} + + +record AlignedSample { + id: String + bedgraph: Path + bam: Path + bai: Path +} + +record TargetedSequencingResult { + id: String + bedgraph_intersect: Path + picard_hsmetrics: Path? } diff --git a/subworkflows/local/utils_nfcore_methylseq_pipeline/main.nf b/subworkflows/local/utils_nfcore_methylseq_pipeline/main.nf index 254e07dfd..bd1b23ce9 100644 --- a/subworkflows/local/utils_nfcore_methylseq_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_methylseq_pipeline/main.nf @@ -26,6 +26,7 @@ include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' workflow PIPELINE_INITIALISATION { take: + input: String version // boolean: Display version and exit validate_params // boolean: Boolean whether to validate parameters against the schema at runtime monochrome_logs // boolean: Do not use coloured log outputs @@ -72,19 +73,17 @@ workflow PIPELINE_INITIALISATION { // Create channel from input file provided through params.input // - Channel - .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + channel.fromList(samplesheetToList(input, "${projectDir}/assets/schema_input.json")) .map { meta, fastq_1, fastq_2, genome -> - if (!fastq_2) { - return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] - } else { - return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] - } + def single_end = !fastq_2 + def reads = single_end ? [ fastq_1 ] : [ fastq_1, fastq_2 ] + def sample = record(id: meta.id, single_end: single_end, reads: reads) + tuple(sample.id, sample) } .groupTuple() - .map { samplesheet -> - validateInputSamplesheet(samplesheet) + .map { id, samples -> + validateInputSamplesheet(samples) } .set { ch_samplesheet } ch_samplesheet.dump(tag: "ch_samplesheet") @@ -157,16 +156,16 @@ def validateInputParameters() { // // Validate channels from input samplesheet // -def validateInputSamplesheet(input) { - def (metas, fastqs) = input[1..2] +def validateInputSamplesheet(samples) { // Check that multiple runs of the same sample are of the same datatype i.e. single-end / paired-end - def endedness_ok = metas.collect{ meta -> meta.single_end }.unique().size == 1 + def endedness_ok = samples.collect{ r -> r.single_end }.unique().size == 1 if (!endedness_ok) { - error("Please check input samplesheet -> Multiple runs of a sample must be of the same datatype i.e. single-end or paired-end: ${metas[0].id}") + error("Please check input samplesheet -> Multiple runs of a sample must be of the same datatype i.e. single-end or paired-end: ${samples[0].id}") } - return [ metas[0], fastqs ] + def reads = samples.collectMany { r -> r.reads } + return samples[0] + record(reads: reads) } // // Get attribute from genome config file e.g. fasta diff --git a/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf b/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf index 728ad148f..c4ee7d979 100644 --- a/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf +++ b/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf @@ -4,37 +4,34 @@ include { BISMARK_GENOMEPREPARATION } from '../../../modules/nf-core/bismark/gen include { BWAMETH_INDEX } from '../../../modules/nf-core/bwameth/index/main' include { SAMTOOLS_FAIDX } from '../../../modules/nf-core/samtools/faidx/main' +def isGzipped(file: Path) -> Boolean { + return file.name.endsWith('.gz') +} + workflow FASTA_INDEX_BISMARK_BWAMETH { take: - fasta // channel: [ val(meta), [ fasta ] ] - fasta_index // channel: [ val(meta), [ fasta index ] ] - bismark_index // channel: [ val(meta), [ bismark index ] ] - bwameth_index // channel: [ val(meta), [ bwameth index ] ] - aligner // string: bismark, bismark_hisat or bwameth - collecthsmetrics // boolean: whether to run picard collecthsmetrics - use_mem2 // boolean: generate mem2 index if no index provided, and bwameth is selected + fasta: Path? + fasta_index: Path? + bismark_index: Path? + bwameth_index: Path? + aligner: String // bismark, bismark_hisat or bwameth + collecthsmetrics: Boolean // whether to run picard collecthsmetrics + use_mem2: Boolean // generate mem2 index if no index provided, and bwameth is selected main: - ch_fasta = channel.empty() - ch_fasta_index = channel.empty() - ch_bismark_index = channel.empty() - ch_bwameth_index = channel.empty() + val_fasta = null + val_fasta_index = null + val_bismark_index = null + val_bwameth_index = null // Check if fasta file is gzipped and decompress if needed - fasta - .branch { - gzipped: it[1].toString().endsWith('.gz') - unzipped: true - } - .set { ch_fasta_branched } - - GUNZIP ( - ch_fasta_branched.gzipped - ) - - ch_fasta = ch_fasta_branched.unzipped.mix(GUNZIP.out.gunzip) + if( fasta ) { + val_fasta = isGzipped(fasta) + ? GUNZIP( fasta ) + : channel.value(fasta) + } // Aligner: bismark or bismark_hisat if( aligner =~ /bismark/ ){ @@ -43,23 +40,11 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { */ if (bismark_index) { // Handle channel-based bismark index - bismark_index - .branch { - gzipped: it[1].toString().endsWith('.gz') - unzipped: true - } - .set { ch_bismark_index_branched } - - UNTAR ( - ch_bismark_index_branched.gzipped - ) - - ch_bismark_index = ch_bismark_index_branched.unzipped.mix(UNTAR.out.untar) + val_bismark_index = isGzipped(bismark_index) + ? UNTAR( bismark_index ) + : channel.value(bismark_index) } else { - BISMARK_GENOMEPREPARATION ( - ch_fasta - ) - ch_bismark_index = BISMARK_GENOMEPREPARATION.out.index + val_bismark_index = BISMARK_GENOMEPREPARATION( val_fasta ) } } @@ -70,31 +55,11 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { */ if (bwameth_index) { // Handle channel-based bwameth index - bwameth_index - .branch { - gzipped: it[1].toString().endsWith('.gz') - unzipped: true - } - .set { ch_bwameth_index_branched } - - UNTAR ( - ch_bwameth_index_branched.gzipped - ) - - ch_bwameth_index = ch_bwameth_index_branched.unzipped.mix(UNTAR.out.untar) + val_bwameth_index = isGzipped(bwameth_index) + ? UNTAR( bwameth_index ) + : channel.value(bwameth_index) } else { - if (use_mem2) { - BWAMETH_INDEX ( - ch_fasta, - true - ) - } else { - BWAMETH_INDEX ( - ch_fasta, - false - ) - } - ch_bwameth_index = BWAMETH_INDEX.out.index + val_bwameth_index = BWAMETH_INDEX( val_fasta, use_mem2 ) } } @@ -104,20 +69,15 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { if (aligner == 'bwameth' || collecthsmetrics) { // already exising fasta index if (fasta_index) { - ch_fasta_index = fasta_index + val_fasta_index = channel.value(fasta_index) } else { - SAMTOOLS_FAIDX( - ch_fasta, - [[:], []], - false - ) - ch_fasta_index = SAMTOOLS_FAIDX.out.fai + val_fasta_index = SAMTOOLS_FAIDX( val_fasta, null, false ).map { r -> r.fai } } } emit: - fasta = ch_fasta // channel: [ val(meta), [ fasta ] ] - fasta_index = ch_fasta_index // channel: [ val(meta), [ fasta index ] ] - bismark_index = ch_bismark_index // channel: [ val(meta), [ bismark index ] ] - bwameth_index = ch_bwameth_index // channel: [ val(meta), [ bwameth index ] ] + fasta : Value? = val_fasta + fasta_index : Value? = val_fasta_index + bismark_index : Value? = val_bismark_index + bwameth_index : Value? = val_bwameth_index } diff --git a/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf b/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf index 82576c302..ea54e04f9 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf +++ b/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf @@ -7,138 +7,132 @@ include { BISMARK_COVERAGE2CYTOSINE } from '../../../modules/nf-core/bismark/ include { BISMARK_REPORT } from '../../../modules/nf-core/bismark/report/main' include { BISMARK_SUMMARY } from '../../../modules/nf-core/bismark/summary/main' +include { Sample } from '../../../utils/types.nf' +include { combineWith ; joinById } from '../../../utils/ops.nf' + workflow FASTQ_ALIGN_DEDUP_BISMARK { take: - ch_reads // channel: [ val(meta), [ reads ] ] - ch_fasta // channel: [ val(meta), [ fasta ] ] - ch_bismark_index // channel: [ val(meta), [ bismark index ] ] - skip_deduplication // boolean: whether to deduplicate alignments - cytosine_report // boolean: whether the run coverage2cytosine + ch_reads: Channel + val_fasta: Value + val_bismark_index: Value + skip_deduplication: Boolean + cytosine_report: Boolean main: - ch_alignments = channel.empty() - ch_alignment_reports = channel.empty() - ch_methylation_bedgraph = channel.empty() - ch_methylation_calls = channel.empty() - ch_methylation_coverage = channel.empty() - ch_methylation_report = channel.empty() - ch_methylation_mbias = channel.empty() - ch_coverage2cytosine_coverage = channel.empty() - ch_coverage2cytosine_report = channel.empty() - ch_coverage2cytosine_summary = channel.empty() - ch_bismark_report = channel.empty() - ch_bismark_summary = channel.empty() - ch_multiqc_files = channel.empty() /* * Align with bismark */ - BISMARK_ALIGN ( - ch_reads, - ch_fasta, - ch_bismark_index - ) - ch_alignments = BISMARK_ALIGN.out.bam - ch_alignment_reports = BISMARK_ALIGN.out.report.map{ meta, report -> [ meta, report, [] ] } + ch_alignment_inputs = combineWith( ch_reads, fasta: val_fasta, bismark_index: val_bismark_index ) + ch_alignment = BISMARK_ALIGN( ch_alignment_inputs ) if (!skip_deduplication) { /* * Run deduplicate_bismark */ - BISMARK_DEDUPLICATE ( - BISMARK_ALIGN.out.bam - ) - ch_alignments = BISMARK_DEDUPLICATE.out.bam - ch_alignment_reports = BISMARK_ALIGN.out.report.join(BISMARK_DEDUPLICATE.out.report) + ch_alignment_dedup = BISMARK_DEDUPLICATE( ch_alignment ) + ch_alignment_dedup = joinById(ch_alignment, ch_alignment_dedup) + } else { + ch_alignment_dedup = ch_alignment } /* * MODULE: Run samtools sort on aligned or deduplicated bam */ - SAMTOOLS_SORT ( - ch_alignments, - [[:],[]] // [ [meta], [fasta]] - ) + ch_bam = SAMTOOLS_SORT( ch_alignment_dedup ) /* * MODULE: Run samtools index on aligned or deduplicated bam */ - SAMTOOLS_INDEX ( - SAMTOOLS_SORT.out.bam + ch_bai = SAMTOOLS_INDEX( + ch_bam.map { r -> record(id: r.id, input: r.bam) } ) /* * Run bismark_methylation_extractor */ - BISMARK_METHYLATIONEXTRACTOR ( - ch_alignments, - ch_bismark_index - ) - ch_methylation_bedgraph = BISMARK_METHYLATIONEXTRACTOR.out.bedgraph - ch_methylation_calls = BISMARK_METHYLATIONEXTRACTOR.out.methylation_calls - ch_methylation_coverage = BISMARK_METHYLATIONEXTRACTOR.out.coverage - ch_methylation_report = BISMARK_METHYLATIONEXTRACTOR.out.report - ch_methylation_mbias = BISMARK_METHYLATIONEXTRACTOR.out.mbias + ch_methylation_inputs = combineWith(ch_alignment_dedup, bismark_index: val_bismark_index) + ch_methylation = BISMARK_METHYLATIONEXTRACTOR( ch_methylation_inputs ) /* * Run bismark coverage2cytosine */ if (cytosine_report) { - BISMARK_COVERAGE2CYTOSINE ( - ch_methylation_coverage, - ch_fasta, - ch_bismark_index - ) - ch_coverage2cytosine_coverage = BISMARK_COVERAGE2CYTOSINE.out.coverage - ch_coverage2cytosine_report = BISMARK_COVERAGE2CYTOSINE.out.report - ch_coverage2cytosine_summary = BISMARK_COVERAGE2CYTOSINE.out.summary + ch_coverage2cytosine_inputs = combineWith(ch_methylation, fasta: val_fasta, bismark_index: val_bismark_index) + ch_coverage2cytosine = BISMARK_COVERAGE2CYTOSINE( ch_coverage2cytosine_inputs ) + } else { + ch_coverage2cytosine = channel.empty() } /* * Generate bismark sample reports */ - BISMARK_REPORT ( - ch_alignment_reports - .join(ch_methylation_report) - .join(ch_methylation_mbias) + ch_bismark_report = BISMARK_REPORT( + joinById(ch_alignment_dedup, ch_methylation) ) - ch_bismark_report = BISMARK_REPORT.out.report + + /* + * Collect per-sample results + */ + ch_results = ch_alignment_dedup + ch_results = joinById(ch_results, ch_bam) + ch_results = joinById(ch_results, ch_bai) + ch_results = joinById(ch_results, ch_coverage2cytosine) + ch_results = joinById(ch_results, ch_methylation) + ch_results = joinById(ch_results, ch_bismark_report) /* * Generate bismark summary report */ - BISMARK_SUMMARY ( - BISMARK_ALIGN.out.bam.collect{ meta, bam -> bam.name }, - ch_alignment_reports.collect{ meta, align_report, dedup_report -> align_report }, - ch_alignment_reports.collect{ meta, align_report, dedup_report -> dedup_report }.ifEmpty([]), - ch_methylation_report.collect{ meta, report -> report }, - ch_methylation_mbias.collect{ meta, mbias -> mbias } - ) - ch_bismark_summary = BISMARK_SUMMARY.out.summary + ch_bam_name = ch_alignment.map { r -> record(id: r.id, bam_name: r.bam.name) } + + ch_bismark_summary_inputs = joinById(ch_alignment_dedup, ch_methylation) + ch_bismark_summary_inputs = joinById(ch_bismark_summary_inputs, ch_bam_name) + .collect() + .map { rs -> + record( + bam: rs*.bam_name.toSet(), + align_report: rs*.align_report.toSet(), + dedup_report: rs*.dedup_report.findAll { v -> v != null }.toSet(), + methylation_report: rs*.methylation_report.toSet(), + methylation_mbias: rs*.methylation_mbias.toSet() + ) + } + + val_bismark_summary = BISMARK_SUMMARY( ch_bismark_summary_inputs ) /* * Collect MultiQC inputs */ - ch_multiqc_files = ch_bismark_summary - .mix(ch_alignment_reports.collect{ meta, align_report, dedup_report -> align_report }) - .mix(ch_alignment_reports.collect{ meta, align_report, dedup_report -> dedup_report }) - .mix(ch_methylation_report.collect{ meta, report -> report }) - .mix(ch_methylation_mbias.collect{ meta, mbias -> mbias }) - .mix(ch_bismark_report.collect{ meta, report -> report }) + ch_multiqc_files = channel.empty() + .mix( val_bismark_summary.flatMap() ) + .mix( ch_alignment_dedup.flatMap { r -> [r.align_report, r.dedup_report] }.filter { v -> v != null } ) + .mix( ch_methylation.flatMap { r -> [r.methylation_report, r.methylation_mbias] } ) + .mix( ch_bismark_report.map { r -> r.bismark_report } ) emit: - bam = SAMTOOLS_SORT.out.bam // channel: [ val(meta), [ bam ] ] - bai = SAMTOOLS_INDEX.out.bai // channel: [ val(meta), [ bai ] ] - coverage2cytosine_coverage = ch_coverage2cytosine_coverage // channel: [ val(meta), [ coverage ] ] - coverage2cytosine_report = ch_coverage2cytosine_report // channel: [ val(meta), [ report ] ] - coverage2cytosine_summary = ch_coverage2cytosine_summary // channel: [ val(meta), [ summary ] ] - methylation_bedgraph = ch_methylation_bedgraph // channel: [ val(meta), [ bedgraph ] ] - methylation_calls = ch_methylation_calls // channel: [ val(meta), [ methylation_calls ] ] - methylation_coverage = ch_methylation_coverage // channel: [ val(meta), [ coverage ] ] - methylation_report = ch_methylation_report // channel: [ val(meta), [ report ] ] - methylation_mbias = ch_methylation_mbias // channel: [ val(meta), [ mbias ] ] - bismark_report = ch_bismark_report // channel: [ val(meta), [ report ] ] - bismark_summary = ch_bismark_summary // channel: [ val(meta), [ summary ] ] - multiqc = ch_multiqc_files // path: *{html,txt} + results : Channel = ch_results + bismark_summary : Value> = val_bismark_summary + multiqc : Channel = ch_multiqc_files +} + + +record BismarkResult { + id : String + single_end : Boolean + bam : Path + bai : Path + align_report : Path + unmapped : Path? + dedup_report : Path + coverage2cytosine_coverage : Path + coverage2cytosine_report : Path + coverage2cytosine_summary : Path + methylation_bedgraph : Path + methylation_calls : Path + methylation_coverage : Path + methylation_report : Path + methylation_mbias : Path + bismark_report : Path } diff --git a/subworkflows/nf-core/fastq_align_dedup_bismark/tests/nextflow.config b/subworkflows/nf-core/fastq_align_dedup_bismark/tests/nextflow.config index 8d94d8ff3..ad2e742d4 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bismark/tests/nextflow.config +++ b/subworkflows/nf-core/fastq_align_dedup_bismark/tests/nextflow.config @@ -10,6 +10,6 @@ process { } withName: 'SAMTOOLS_SORT' { - ext.prefix = { "${meta.id}.sorted" } + ext.prefix = { "${id}.sorted" } } } diff --git a/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf b/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf index 2bf4b09ad..e1547ed20 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf +++ b/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf @@ -9,144 +9,117 @@ include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_DEDUPLICATED } from '../../../modules include { METHYLDACKEL_EXTRACT } from '../../../modules/nf-core/methyldackel/extract/main' include { METHYLDACKEL_MBIAS } from '../../../modules/nf-core/methyldackel/mbias/main' +include { Sample } from '../../../utils/types.nf' +include { combineWith ; joinById } from '../../../utils/ops.nf' + workflow FASTQ_ALIGN_DEDUP_BWAMETH { take: - ch_reads // channel: [ val(meta), [ reads ] ] - ch_fasta // channel: [ val(meta), [ fasta ] ] - ch_fasta_index // channel: [ val(meta), [ fasta index ] ] - ch_bwameth_index // channel: [ val(meta), [ bwameth index ] ] - skip_deduplication // boolean: whether to deduplicate alignments - use_gpu // boolean: whether to use GPU or CPU for bwameth alignment + ch_reads: Channel + val_fasta: Value + val_fasta_index: Value + val_bwameth_index: Value + skip_deduplication: Boolean + use_gpu: Boolean main: - ch_alignment = channel.empty() - ch_alignment_index = channel.empty() - ch_samtools_flagstat = channel.empty() - ch_samtools_stats = channel.empty() - ch_methydackel_extract_bedgraph = channel.empty() - ch_methydackel_extract_methylkit = channel.empty() - ch_methydackel_mbias = channel.empty() - ch_picard_metrics = channel.empty() - ch_multiqc_files = channel.empty() - /* * Align with bwameth */ + ch_bwameth_inputs = combineWith(ch_reads, fasta: val_fasta, bwameth_index: val_bwameth_index) + if (use_gpu) { /* * Align with parabricks GPU enabled fq2bammeth implementation of bwameth */ - PARABRICKS_FQ2BAMMETH ( - ch_reads, - ch_fasta, - ch_bwameth_index, - [] // known sites - ) - ch_alignment = PARABRICKS_FQ2BAMMETH.out.bam + ch_alignment = PARABRICKS_FQ2BAMMETH ( ch_bwameth_inputs ) } else { /* * Align with CPU version of bwameth */ - BWAMETH_ALIGN ( - ch_reads, - ch_fasta, - ch_bwameth_index - ) - ch_alignment = BWAMETH_ALIGN.out.bam + ch_alignment = BWAMETH_ALIGN ( ch_bwameth_inputs ) } /* * Sort raw output BAM */ - SAMTOOLS_SORT ( - ch_alignment, - [[:],[]] // [ [meta], [fasta]] - ) - ch_alignment = SAMTOOLS_SORT.out.bam + ch_alignment = SAMTOOLS_SORT( ch_alignment ) /* * Run samtools index on alignment */ - SAMTOOLS_INDEX_ALIGNMENTS ( - ch_alignment - ) - ch_alignment_index = SAMTOOLS_INDEX_ALIGNMENTS.out.bai + ch_alignment_index = SAMTOOLS_INDEX_ALIGNMENTS( ch_alignment ) + ch_alignment = joinById(ch_alignment, ch_alignment_index) /* * Run samtools flagstat */ - SAMTOOLS_FLAGSTAT ( - ch_alignment.join(ch_alignment_index) - ) - ch_samtools_flagstat = SAMTOOLS_FLAGSTAT.out.flagstat + ch_samtools_flagstat = SAMTOOLS_FLAGSTAT( ch_alignment ) /* * Run samtools stats */ - SAMTOOLS_STATS ( - ch_alignment.join(ch_alignment_index), - [[:],[]] // [ [meta], [fasta]] + ch_samtools_stats = SAMTOOLS_STATS( + ch_alignment.map { r -> record(id: r.id, input: r.bam, input_index: r.bai) } ) - ch_samtools_stats = SAMTOOLS_STATS.out.stats + + ch_alignment_fasta = combineWith(ch_alignment, fasta: val_fasta, fasta_index: val_fasta_index) if (!skip_deduplication) { /* * Run Picard MarkDuplicates */ - PICARD_MARKDUPLICATES ( - ch_alignment, - ch_fasta, - ch_fasta_index - ) + ch_picard = PICARD_MARKDUPLICATES( ch_alignment_fasta ) /* * Run samtools index on deduplicated alignment */ - SAMTOOLS_INDEX_DEDUPLICATED ( - PICARD_MARKDUPLICATES.out.bam + ch_alignment_index_dedup = SAMTOOLS_INDEX_DEDUPLICATED( + ch_picard.map { r -> record(id: r.id, input: r.bam) } ) - ch_alignment = PICARD_MARKDUPLICATES.out.bam - ch_alignment_index = SAMTOOLS_INDEX_DEDUPLICATED.out.bai - ch_picard_metrics = PICARD_MARKDUPLICATES.out.metrics + ch_alignment = joinById(ch_alignment_fasta, ch_picard) + ch_alignment = joinById(ch_alignment, ch_alignment_index_dedup) } /* * Extract per-base methylation and plot methylation bias */ - METHYLDACKEL_EXTRACT ( - ch_alignment.join(ch_alignment_index), - ch_fasta.map{ meta, fasta_file -> fasta_file }, - ch_fasta_index.map{ meta, fasta_index -> fasta_index } - ) - ch_methydackel_extract_bedgraph = METHYLDACKEL_EXTRACT.out.bedgraph - ch_methydackel_extract_methylkit = METHYLDACKEL_EXTRACT.out.methylkit + ch_methydackel_extract = METHYLDACKEL_EXTRACT ( ch_alignment_fasta ) - METHYLDACKEL_MBIAS ( - ch_alignment.join(ch_alignment_index), - ch_fasta.map{ meta, fasta_file -> fasta_file }, - ch_fasta_index.map{ meta, fasta_index -> fasta_index } - ) - ch_methydackel_mbias = METHYLDACKEL_MBIAS.out.txt + ch_methydackel_mbias = METHYLDACKEL_MBIAS ( ch_alignment_fasta ) + + ch_results = joinById(ch_alignment, ch_samtools_flagstat) + ch_results = joinById(ch_results, ch_samtools_stats) + ch_results = joinById(ch_results, ch_methydackel_extract) + ch_results = joinById(ch_results, ch_methydackel_mbias) + ch_results = joinById(ch_results, ch_picard) /* * Collect MultiQC inputs */ - ch_multiqc_files = ch_picard_metrics.collect{ meta, metrics -> metrics } - .mix(ch_samtools_flagstat.collect{ meta, flagstat -> flagstat }) - .mix(ch_samtools_stats.collect{ meta, stats -> stats }) - .mix(ch_methydackel_extract_bedgraph.collect{ meta, bedgraph -> bedgraph }) - .mix(ch_methydackel_mbias.collect{ meta, txt -> txt }) + ch_multiqc_files = channel.empty() + .mix( ch_picard.map { r -> r.picard_metrics } ) + .mix( ch_samtools_flagstat.map { r -> r.samtools_flagstat } ) + .mix( ch_samtools_stats.map { r -> r.samtools_stats } ) + .mix( ch_methydackel_extract.map { r -> r.methydackel_bedgraph } ) + .mix( ch_methydackel_mbias.map { r -> r.methydackel_mbias } ) emit: - bam = ch_alignment // channel: [ val(meta), [ bam ] ] - bai = ch_alignment_index // channel: [ val(meta), [ bai ] ] - samtools_flagstat = ch_samtools_flagstat // channel: [ val(meta), [ flagstat ] ] - samtools_stats = ch_samtools_stats // channel: [ val(meta), [ stats ] ] - methydackel_extract_bedgraph = ch_methydackel_extract_bedgraph // channel: [ val(meta), [ bedgraph ] ] - methydackel_extract_methylkit = ch_methydackel_extract_methylkit // channel: [ val(meta), [ methylkit ] ] - methydackel_mbias = ch_methydackel_mbias // channel: [ val(meta), [ mbias ] ] - picard_metrics = ch_picard_metrics // channel: [ val(meta), [ metrics ] ] - multiqc = ch_multiqc_files // channel: [ *{html,txt} ] + results: Channel = ch_results + multiqc: Channel = ch_multiqc_files +} + + +record BwamethResult { + id : String + single_end : Boolean + bam : Path + bai : Path + samtools_flagstat : Path + samtools_stats : Path + methydackel_extract_bedgraph : Path + methydackel_extract_methylkit : Path + methydackel_mbias : Path + picard_metrics : Path } diff --git a/subworkflows/nf-core/fastq_align_dedup_bwameth/tests/nextflow.config b/subworkflows/nf-core/fastq_align_dedup_bwameth/tests/nextflow.config index 55385ec06..7537fb6e0 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bwameth/tests/nextflow.config +++ b/subworkflows/nf-core/fastq_align_dedup_bwameth/tests/nextflow.config @@ -4,11 +4,11 @@ process { } withName: 'SAMTOOLS_SORT' { - ext.prefix = { "${meta.id}.sorted" } + ext.prefix = { "${id}.sorted" } } withName: 'PICARD_MARKDUPLICATES' { ext.args = "--ASSUME_SORTED true --REMOVE_DUPLICATES false --VALIDATION_STRINGENCY LENIENT --PROGRAM_RECORD_ID 'null' --TMP_DIR tmp" - ext.prefix = { "${meta.id}.markdup.sorted" } + ext.prefix = { "${id}.markdup.sorted" } } } diff --git a/subworkflows/nf-core/utils_nfschema_plugin/main.nf b/subworkflows/nf-core/utils_nfschema_plugin/main.nf index 4994303ea..223e584ab 100644 --- a/subworkflows/nf-core/utils_nfschema_plugin/main.nf +++ b/subworkflows/nf-core/utils_nfschema_plugin/main.nf @@ -28,18 +28,6 @@ workflow UTILS_NFSCHEMA_PLUGIN { log.info paramsSummaryLog(input_workflow) } - // - // Validate the parameters using nextflow_schema.json or the schema - // given via the validation.parametersSchema configuration option - // - if(validate_params) { - if(parameters_schema) { - validateParameters(parameters_schema:parameters_schema) - } else { - validateParameters() - } - } - emit: dummy_emit = true } diff --git a/utils/ops.nf b/utils/ops.nf new file mode 100644 index 000000000..3d90346e8 --- /dev/null +++ b/utils/ops.nf @@ -0,0 +1,27 @@ + +// Utility functions for common dataflow operations with records +// Will be replaced by v2 operators + +def combineWith(opts, source) { + def result = source + opts.each { name, value -> + result = result + .combine(value) + .map { r, v -> r + record([(name): v]) } + } + return result +} + +def groupById(source) { + tupleWithId(source).groupTuple() +} + +def joinById(left, right) { + tupleWithId(left) + .join( tupleWithId(right) ) + .map { _id, r1, r2 -> r1 + r2 } +} + +def tupleWithId(source) { + source.map { r -> tuple(r.id, r) } +} diff --git a/utils/types.nf b/utils/types.nf new file mode 100644 index 000000000..3fe4ac834 --- /dev/null +++ b/utils/types.nf @@ -0,0 +1,6 @@ + +record Sample { + id: String + single_end: Boolean + reads: List +} diff --git a/workflows/methylseq/main.nf b/workflows/methylseq/main.nf index f278b7c12..e91990d54 100644 --- a/workflows/methylseq/main.nf +++ b/workflows/methylseq/main.nf @@ -19,6 +19,9 @@ include { TARGETED_SEQUENCING } from '../../subworkflows/local/targeted_s include { methodsDescriptionText } from '../../subworkflows/local/utils_nfcore_methylseq_pipeline' include { validateInputSamplesheet } from '../../subworkflows/local/utils_nfcore_methylseq_pipeline' +include { Sample } from '../../utils/types.nf' +include { joinById } from '../../utils/ops.nf' + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN MAIN WORKFLOW @@ -28,142 +31,107 @@ include { validateInputSamplesheet } from '../../subworkflows/local/utils_nfco workflow METHYLSEQ { take: - samplesheet // channel: [ path(samplesheet.csv) ] - ch_fasta // channel: [ path(fasta) ] - ch_fasta_index // channel: [ path(fasta index) ] - ch_bismark_index // channel: [ path(bismark index) ] - ch_bwameth_index // channel: [ path(bwameth index) ] + ch_samples: Channel + val_fasta: Value? + val_fasta_index: Value? + val_bismark_index: Value? + val_bwameth_index: Value? + params: MethylseqParams main: - ch_fastq = channel.empty() - ch_fastqc_html = channel.empty() - ch_fastqc_zip = channel.empty() - ch_reads = channel.empty() - ch_bam = channel.empty() - ch_bai = channel.empty() - ch_bedgraph = channel.empty() - ch_aligner_mqc = channel.empty() - ch_qualimap = channel.empty() - ch_preseq = channel.empty() ch_multiqc_files = channel.empty() - // - // Branch channels from input samplesheet channel - // - ch_samplesheet = samplesheet - .branch { meta, fastqs -> - single : fastqs.size() == 1 - return [ meta, fastqs.flatten() ] - multiple: fastqs.size() > 1 - return [ meta, fastqs.flatten() ] - } - // // MODULE: Concatenate FastQ files from same sample if required // - CAT_FASTQ ( - ch_samplesheet.multiple + ch_samples_merged = CAT_FASTQ ( + ch_samples.filter { r -> !r.single_end } ) - ch_fastq = CAT_FASTQ.out.reads.mix(ch_samplesheet.single) + ch_samples_single = ch_samples.filter { r -> r.single_end } + + ch_fastq = ch_samples_merged.mix(ch_samples_single) // // MODULE: Run FastQC // if (!params.skip_fastqc) { - FASTQC ( - ch_fastq - ) - ch_fastqc_html = FASTQC.out.html - ch_fastqc_zip = FASTQC.out.zip + ch_fastqc = FASTQC( ch_fastq ) } else { - ch_fastqc_html = channel.empty() - ch_fastqc_zip = channel.empty() + ch_fastqc = channel.empty() } // // MODULE: Run TrimGalore! // if (!params.skip_trimming) { - TRIMGALORE( - ch_fastq - ) - ch_reads = TRIMGALORE.out.reads + ch_trimmed_fastq = TRIMGALORE( ch_fastq ) + ch_reads = ch_trimmed_fastq.map { r -> r + record(reads: r.trim_reads) } } else { - ch_reads = ch_fastq + ch_trimmed_fastq = channel.empty() + ch_reads = ch_fastq } // // SUBWORKFLOW: Align reads, deduplicate and extract methylation with Bismark // + val_bismark_summary = null + // Aligner: bismark or bismark_hisat - if ( params.aligner =~ /bismark/ ) { + if ( params.aligner =~ /bismark/ && val_fasta && val_bismark_index ) { // // Run Bismark alignment + downstream processing // - ch_bismark_inputs = ch_reads - .combine(ch_fasta) - .combine(ch_bismark_index) - .multiMap { meta, reads, meta_fasta, fasta, meta_bismark, bismark_index -> - reads: [ meta, reads ] - fasta: [ meta_fasta, fasta ] - bismark_index: [ meta_bismark, bismark_index ] - } - FASTQ_ALIGN_DEDUP_BISMARK ( - ch_bismark_inputs.reads, - ch_bismark_inputs.fasta, - ch_bismark_inputs.bismark_index, + ch_reads, + val_fasta, + val_bismark_index, params.skip_deduplication || params.rrbs, params.cytosine_report || params.nomeseq ) - ch_bam = FASTQ_ALIGN_DEDUP_BISMARK.out.bam - ch_bai = FASTQ_ALIGN_DEDUP_BISMARK.out.bai - ch_bedgraph = FASTQ_ALIGN_DEDUP_BISMARK.out.methylation_bedgraph + ch_alignment = FASTQ_ALIGN_DEDUP_BISMARK.out.results + val_bismark_summary = FASTQ_ALIGN_DEDUP_BISMARK.out.bismark_summary ch_aligner_mqc = FASTQ_ALIGN_DEDUP_BISMARK.out.multiqc } // Aligner: bwameth - else if ( params.aligner == 'bwameth' ){ - - ch_bwameth_inputs = ch_reads - .combine(ch_fasta) - .combine(ch_fasta_index) - .combine(ch_bwameth_index) - .multiMap { meta, reads, meta_fasta, fasta, meta_fasta_index, fasta_index, meta_bwameth, bwameth_index -> - reads: [ meta, reads ] - fasta: [ meta_fasta, fasta ] - fasta_index: [ meta_fasta_index, fasta_index ] - bwameth_index: [ meta_bwameth, bwameth_index ] - } + else if ( params.aligner == 'bwameth' && val_fasta && val_fasta_index && val_bwameth_index ) { FASTQ_ALIGN_DEDUP_BWAMETH ( - ch_bwameth_inputs.reads, - ch_bwameth_inputs.fasta, - ch_bwameth_inputs.fasta_index, - ch_bwameth_inputs.bwameth_index, + ch_reads, + val_fasta, + val_fasta_index, + val_bwameth_index, params.skip_deduplication || params.rrbs, workflow.profile.tokenize(',').intersect(['gpu']).size() >= 1 ) - ch_bam = FASTQ_ALIGN_DEDUP_BWAMETH.out.bam - ch_bai = FASTQ_ALIGN_DEDUP_BWAMETH.out.bai - ch_bedgraph = FASTQ_ALIGN_DEDUP_BWAMETH.out.methydackel_extract_bedgraph + ch_alignment = FASTQ_ALIGN_DEDUP_BWAMETH.out.results ch_aligner_mqc = FASTQ_ALIGN_DEDUP_BWAMETH.out.multiqc } else { error "ERROR: Invalid aligner '${params.aligner}'. Valid options are: 'bismark', 'bismark_hisat', or 'bwameth'" } + ch_results = ch_alignment + if (params.skip_fastqc) { + ch_results = joinById(ch_results, ch_fastqc) + } + if (params.skip_trimming) { + ch_results = joinById(ch_results, ch_trimmed_fastq) + } + // // MODULE: Qualimap BamQC // skipped by default. to use run with `--run_qualimap` param. // if(params.run_qualimap) { - QUALIMAP_BAMQC ( - ch_bam, - params.bamqc_regions_file ? channel.fromPath( params.bamqc_regions_file, checkIfExists: true ).toList() : [] + ch_qualimap = QUALIMAP_BAMQC ( + ch_alignment, + params.bamqc_regions_file ? file( params.bamqc_regions_file, checkIfExists: true ) : null ) - ch_qualimap = QUALIMAP_BAMQC.out.results + ch_results = joinById(ch_results, ch_qualimap) + } else { + ch_qualimap = channel.empty() } // @@ -175,14 +143,20 @@ workflow METHYLSEQ { error "ERROR: --target_regions_file must be specified when using --run_targeted_sequencing" } TARGETED_SEQUENCING ( - ch_bedgraph, - channel.fromPath(params.target_regions_file, checkIfExists: true), - ch_fasta, - ch_fasta_index, - ch_bam, - ch_bai, + ch_alignment, + channel.value(file(params.target_regions_file, checkIfExists: true)), + val_fasta, + val_fasta_index, params.collecthsmetrics ) + ch_targeted_sequencing = TARGETED_SEQUENCING.out.results + val_reference_dict = TARGETED_SEQUENCING.out.reference_dict + val_intervallist = TARGETED_SEQUENCING.out.intervallist + ch_results = joinById(ch_results, ch_targeted_sequencing) + } else { + ch_targeted_sequencing = channel.empty() + val_reference_dict = null + val_intervallist = null } // @@ -190,10 +164,10 @@ workflow METHYLSEQ { // skipped by default. to use run with `--run_preseq` param. // if(params.run_preseq) { - PRESEQ_LCEXTRAP ( - ch_bam - ) - ch_preseq = PRESEQ_LCEXTRAP.out.lc_extrap + ch_preseq = PRESEQ_LCEXTRAP (ch_alignment) + ch_results = joinById(ch_results, ch_preseq) + } else { + ch_preseq = channel.empty() } // @@ -211,13 +185,9 @@ workflow METHYLSEQ { // MODULE: MultiQC // if (!params.skip_multiqc) { - ch_multiqc_config = channel.fromPath("$projectDir/assets/multiqc_config.yml", checkIfExists: true) - ch_multiqc_custom_config = params.multiqc_config ? - channel.fromPath(params.multiqc_config, checkIfExists: true) : - channel.empty() - ch_multiqc_logo = params.multiqc_logo ? - channel.fromPath(params.multiqc_logo, checkIfExists: true) : - channel.empty() + multiqc_config = file("$projectDir/assets/multiqc_config.yml", checkIfExists: true) + multiqc_custom_config = params.multiqc_config ? file(params.multiqc_config, checkIfExists: true) : null + multiqc_logo = params.multiqc_logo ? file(params.multiqc_logo, checkIfExists: true) : null summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") ch_workflow_summary = channel.value(paramsSummaryMultiqc(summary_params)) @@ -237,43 +207,115 @@ workflow METHYLSEQ { ) if(params.run_qualimap) { - ch_multiqc_files = ch_multiqc_files.mix(QUALIMAP_BAMQC.out.results.collect{ it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(ch_qualimap.map { r -> r.qualimap_bamqc }) } if (params.run_preseq) { - ch_multiqc_files = ch_multiqc_files.mix(PRESEQ_LCEXTRAP.out.log.collect{ it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(ch_preseq.map { r -> r.log }) } - ch_multiqc_files = ch_multiqc_files.mix(ch_aligner_mqc.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(ch_aligner_mqc) if (!params.skip_trimming) { - ch_multiqc_files = ch_multiqc_files.mix(TRIMGALORE.out.log.collect{ it[1] }) + ch_multiqc_files = ch_multiqc_files.mix(ch_reads.map { r -> r.log }) } - if (params.run_targeted_sequencing) { - if (params.collecthsmetrics) { - ch_multiqc_files = ch_multiqc_files.mix(TARGETED_SEQUENCING.out.picard_metrics.collect{ it[1] }.ifEmpty([])) - } + if (params.run_targeted_sequencing && params.collecthsmetrics) { + ch_multiqc_files = ch_multiqc_files.mix(ch_targeted_sequencing.map { r -> r.picard_hsmetrics }) } if (!params.skip_fastqc) { - ch_multiqc_files = ch_multiqc_files.mix(FASTQC.out.zip.collect{ it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(ch_fastqc.map { r -> r.fastqc_zip }) } - MULTIQC ( - ch_multiqc_files.collect(), - ch_multiqc_config.toList(), - ch_multiqc_custom_config.toList(), - ch_multiqc_logo.toList(), - [], - [] - ) - ch_multiqc_report = MULTIQC.out.report.toList() + val_multiqc_report = MULTIQC ( + ch_multiqc_files.flatMap().collect().map { v -> v.toSet() }, + multiqc_config, + multiqc_custom_config, + multiqc_logo, + null, + null + ).map { r -> r.report } } else { - ch_multiqc_report = channel.empty() + val_multiqc_report = channel.empty() } emit: - bam = ch_bam // channel: [ val(meta), path(bam) ] - bai = ch_bai // channel: [ val(meta), path(bai) ] - qualimap = ch_qualimap // channel: [ val(meta), path(qualimap) ] - preseq = ch_preseq // channel: [ val(meta), path(preseq) ] - multiqc_report = ch_multiqc_report // channel: [ path(multiqc_report.html ) ] + results : Channel = ch_results + bismark_summary : Value>? = val_bismark_summary + reference_dict : Value? = val_reference_dict + intervallist : Value? = val_intervallist + multiqc_report : Value = val_multiqc_report +} + +record MethylseqParams { + skip_fastqc: Boolean + skip_trimming: Boolean + aligner: String + skip_deduplication: Boolean + rrbs: Boolean + cytosine_report: Boolean + nomeseq: Boolean + run_qualimap: Boolean + bamqc_regions_file: String + run_targeted_sequencing: Boolean + target_regions_file: String + collecthsmetrics: Boolean + run_preseq: Boolean + outdir: String + skip_multiqc: Boolean + multiqc_config: String + multiqc_logo: String + multiqc_methods_description: String +} + +record MethylseqResult { + id : String + single_end : Boolean + + // fastqc + fastqc_html : Path + fastqc_zip : Path + + // trimgalore + trim_reads : List + trim_log : List + trim_unpaired : List + trim_html : List + trim_zip : List + + // alignment (bismark / bwameth) + bam : Path + bai : Path + + // bismark + align_report: Path + unmapped: Path? + dedup_report: Path + coverage2cytosine_coverage : Path + coverage2cytosine_report : Path + coverage2cytosine_summary : Path + methylation_bedgraph : Path + methylation_calls : Path + methylation_coverage : Path + methylation_report : Path + methylation_mbias : Path + bismark_report : Path + + // bwameth + samtools_flagstat : Path + samtools_stats : Path + methydackel_extract_bedgraph : Path + methydackel_extract_methylkit : Path + methydackel_mbias : Path + picard_metrics : Path + + // qualimap + qualimap_bamqc : Path? + + // targeted sequencing + bedgraph_intersect : Path + picard_hsmetrics : Path + + // preseq + lc_extrap : Path? + lc_log : Path? + } /* From 98d65ce2e22034d1ae4b071dfbe746fa3b7d7a1c Mon Sep 17 00:00:00 2001 From: Ben Sherman Date: Wed, 11 Feb 2026 18:20:30 -0600 Subject: [PATCH 3/6] Workflow outputs [wip] --- conf/modules/bedtools_intersect.config | 7 -- conf/modules/bismark_align.config | 19 ---- conf/modules/bismark_coverage2cytosine.config | 17 ---- conf/modules/bismark_deduplicate.config | 7 -- conf/modules/bismark_genomepreparation.config | 6 -- .../bismark_methylationextractor.config | 27 ------ conf/modules/bismark_report.config | 5 - conf/modules/bismark_summary.config | 5 - conf/modules/bwameth_align.config | 6 -- conf/modules/bwameth_index.config | 6 -- conf/modules/fastqc.config | 12 --- conf/modules/gunzip.config | 12 --- conf/modules/methyldackel_extract.config | 12 --- conf/modules/methyldackel_mbias.config | 7 -- conf/modules/multiqc.config | 5 - conf/modules/parabricks_fq2bammeth.config | 6 -- conf/modules/picard_bedtointervallist.config | 5 - conf/modules/picard_collecthsmetrics.config | 5 - .../picard_createsequencedictionary.config | 6 -- conf/modules/picard_markduplicates.config | 12 --- conf/modules/preseq_lcextrap.config | 14 --- conf/modules/qualimap_bamqc.config | 8 -- conf/modules/samtools_faidx.config | 6 -- conf/modules/samtools_flagstat.config | 11 --- conf/modules/samtools_index.config | 14 --- conf/modules/samtools_sort.config | 25 ----- conf/modules/samtools_stats.config | 11 --- conf/modules/trimgalore.config | 23 ----- .../fasta_index_bismark_bwameth.config | 1 - .../fastq_align_dedup_bwameth.config | 29 ------ main.nf | 95 +++++++++++++++++++ nextflow.config | 3 + workflows/methylseq/nextflow.config | 10 -- 33 files changed, 98 insertions(+), 339 deletions(-) delete mode 100644 conf/modules/gunzip.config delete mode 100644 conf/modules/samtools_flagstat.config delete mode 100644 conf/modules/samtools_stats.config diff --git a/conf/modules/bedtools_intersect.config b/conf/modules/bedtools_intersect.config index 629d072b5..ee8287e12 100644 --- a/conf/modules/bedtools_intersect.config +++ b/conf/modules/bedtools_intersect.config @@ -3,12 +3,5 @@ process { ext.args = '' ext.prefix = { "${intervals1.baseName}" } ext.suffix = 'targeted.bedGraph' - publishDir = [ - [ - path: { params.aligner == 'bismark' ? "${params.outdir}/bismark/methylation_calls/bedGraph" : "${params.outdir}/methyldackel" }, - mode: params.publish_dir_mode, - pattern: "*targeted.bedGraph" - ] - ] } } diff --git a/conf/modules/bismark_align.config b/conf/modules/bismark_align.config index f5306cc87..fb456ba3b 100644 --- a/conf/modules/bismark_align.config +++ b/conf/modules/bismark_align.config @@ -15,24 +15,5 @@ process { ) ) ].join(' ').trim() } - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/alignments/unmapped" }, - mode: params.publish_dir_mode, - pattern: "*.fq.gz", - enabled: params.unmapped - ], - [ - path: { "${params.outdir}/${params.aligner}/alignments" }, - mode: params.publish_dir_mode, - pattern: "*.bam", - enabled: (params.save_align_intermeds || params.skip_deduplication || params.rrbs) - ], - [ - path: { "${params.outdir}/${params.aligner}/alignments/logs" }, - mode: params.publish_dir_mode, - pattern: "*.txt" - ] - ] } } diff --git a/conf/modules/bismark_coverage2cytosine.config b/conf/modules/bismark_coverage2cytosine.config index 8737c561d..500f43c68 100644 --- a/conf/modules/bismark_coverage2cytosine.config +++ b/conf/modules/bismark_coverage2cytosine.config @@ -1,22 +1,5 @@ process { withName: BISMARK_COVERAGE2CYTOSINE { ext.args = params.nomeseq ? '--nome-seq' : '' - publishDir = [ - [ - path: { "${params.outdir}/bismark/coverage2cytosine/summaries" }, - mode: params.publish_dir_mode, - pattern: "*_summary.txt" - ], - [ - path: { "${params.outdir}/bismark/coverage2cytosine/reports" }, - mode: params.publish_dir_mode, - pattern: "*_report.txt.gz" - ], - [ - path: { "${params.outdir}/bismark/coverage2cytosine/coverage" }, - mode: params.publish_dir_mode, - pattern: "*cov.gz" - ] - ] } } diff --git a/conf/modules/bismark_deduplicate.config b/conf/modules/bismark_deduplicate.config index be770f44a..3bde9e1c0 100644 --- a/conf/modules/bismark_deduplicate.config +++ b/conf/modules/bismark_deduplicate.config @@ -1,12 +1,5 @@ process { withName: BISMARK_DEDUPLICATE { ext.args = '' - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/deduplicated/logs" }, - mode: params.publish_dir_mode, - pattern: "*.txt" - ] - ] } } diff --git a/conf/modules/bismark_genomepreparation.config b/conf/modules/bismark_genomepreparation.config index af001049e..5a618c091 100644 --- a/conf/modules/bismark_genomepreparation.config +++ b/conf/modules/bismark_genomepreparation.config @@ -4,11 +4,5 @@ process { (params.aligner == 'bismark_hisat') ? ' --hisat2' : ' --bowtie2', params.slamseq ? ' --slam' : '' ].join(' ').trim() - publishDir = [ - path: { "${params.outdir}/${params.aligner}/reference_genome" }, - saveAs: { it =~ /.*\.yml/ ? null : it }, - mode: params.publish_dir_mode, - enabled: params.save_reference - ] } } diff --git a/conf/modules/bismark_methylationextractor.config b/conf/modules/bismark_methylationextractor.config index 9a3295daa..e077821b5 100644 --- a/conf/modules/bismark_methylationextractor.config +++ b/conf/modules/bismark_methylationextractor.config @@ -10,32 +10,5 @@ process { single_end ? '' : (params.ignore_r2 > 0 ? "--ignore_r2 ${params.ignore_r2}" : ""), single_end ? '' : (params.ignore_3prime_r2 > 0 ? "--ignore_3prime_r2 ${params.ignore_3prime_r2}": "") ].join(' ').trim() } - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/methylation_calls/mbias" }, - mode: params.publish_dir_mode, - pattern: "*M-bias.txt" - ], - [ - path: { "${params.outdir}/${params.aligner}/methylation_calls/methylation_coverage" }, - mode: params.publish_dir_mode, - pattern: "*cov.gz" - ], - [ - path: { "${params.outdir}/${params.aligner}/methylation_calls/bedGraph" }, - mode: params.publish_dir_mode, - pattern: "*bedGraph.gz" - ], - [ - path: { "${params.outdir}/${params.aligner}/methylation_calls/splitting_report" }, - mode: params.publish_dir_mode, - pattern: "*splitting_report.txt" - ], - [ - path: { "${params.outdir}/${params.aligner}/methylation_calls/methylation_calls" }, - mode: params.publish_dir_mode, - pattern: "*txt.gz" - ] - ] } } diff --git a/conf/modules/bismark_report.config b/conf/modules/bismark_report.config index 27e988217..74667a41f 100644 --- a/conf/modules/bismark_report.config +++ b/conf/modules/bismark_report.config @@ -1,10 +1,5 @@ process { withName: BISMARK_REPORT { ext.args = '' - publishDir = [ - path: "${params.outdir}/${params.aligner}/reports", - mode: params.publish_dir_mode, - pattern: "*.html" - ] } } diff --git a/conf/modules/bismark_summary.config b/conf/modules/bismark_summary.config index 92a5d4c08..4cdfe69b5 100644 --- a/conf/modules/bismark_summary.config +++ b/conf/modules/bismark_summary.config @@ -1,10 +1,5 @@ process { withName: BISMARK_SUMMARY { ext.args = '' - publishDir = [ - path: "${params.outdir}/${params.aligner}/summary", - mode: params.publish_dir_mode, - pattern: "*.{html,txt}" - ] } } diff --git a/conf/modules/bwameth_align.config b/conf/modules/bwameth_align.config index bc4ab7580..3467d4a8e 100644 --- a/conf/modules/bwameth_align.config +++ b/conf/modules/bwameth_align.config @@ -2,11 +2,5 @@ process { withName: BWAMETH_ALIGN { cache = 'lenient' // This is set because in the module command the index files are touched so as to have bwameth not complain ext.args = '' - publishDir = [ - path: { "${params.outdir}/${params.aligner}/alignments" }, - pattern: "*.bam", - mode: params.publish_dir_mode, - enabled: params.save_align_intermeds - ] } } diff --git a/conf/modules/bwameth_index.config b/conf/modules/bwameth_index.config index 74559b063..b5883cdce 100644 --- a/conf/modules/bwameth_index.config +++ b/conf/modules/bwameth_index.config @@ -1,11 +1,5 @@ process { withName: BWAMETH_INDEX { ext.args = '' - publishDir = [ - path: { "${params.outdir}/${params.aligner}/reference_genome" }, - mode: params.publish_dir_mode, - saveAs: { it.equals('versions.yml') ? null : it.tokenize("/").last() }, - enabled: params.save_reference - ] } } diff --git a/conf/modules/fastqc.config b/conf/modules/fastqc.config index f611d0325..64bd58798 100644 --- a/conf/modules/fastqc.config +++ b/conf/modules/fastqc.config @@ -1,17 +1,5 @@ process { withName: FASTQC { ext.args = '--quiet' - publishDir = [ - [ - path: { "${params.outdir}/fastqc" }, - mode: params.publish_dir_mode, - pattern: "*.html" - ], - [ - path: { "${params.outdir}/fastqc/zips" }, - mode: params.publish_dir_mode, - pattern: "*.zip" - ] - ] } } diff --git a/conf/modules/gunzip.config b/conf/modules/gunzip.config deleted file mode 100644 index 3a03a67b4..000000000 --- a/conf/modules/gunzip.config +++ /dev/null @@ -1,12 +0,0 @@ -process { - withName: GUNZIP { - publishDir = [ - [ - path: { "${params.outdir}/gunzip/" }, - mode: params.publish_dir_mode, - pattern: "*.{fa,fasta}", - enabled: false - ] - ] - } -} diff --git a/conf/modules/methyldackel_extract.config b/conf/modules/methyldackel_extract.config index 651fecc06..3e045e052 100644 --- a/conf/modules/methyldackel_extract.config +++ b/conf/modules/methyldackel_extract.config @@ -7,17 +7,5 @@ process { params.methyl_kit ? " --methylKit" : '', params.min_depth > 0 ? " --minDepth ${params.min_depth}" : '' ].join(" ").trim() - publishDir = [ - [ - path: { "${params.outdir}/methyldackel" }, - mode: params.publish_dir_mode, - pattern: "*.bedGraph" - ], - [ - path: { "${params.outdir}/methyldackel" }, - mode: params.publish_dir_mode, - pattern: "*.methylKit" - ] - ] } } diff --git a/conf/modules/methyldackel_mbias.config b/conf/modules/methyldackel_mbias.config index b16e38b32..24a5547d9 100644 --- a/conf/modules/methyldackel_mbias.config +++ b/conf/modules/methyldackel_mbias.config @@ -4,12 +4,5 @@ process { params.all_contexts ? ' --CHG --CHH' : '', params.ignore_flags ? " --ignoreFlags" : '' ].join(" ").trim() - publishDir = [ - [ - path: { "${params.outdir}/methyldackel/mbias" }, - mode: params.publish_dir_mode, - pattern: "*mbias.txt" - ] - ] } } diff --git a/conf/modules/multiqc.config b/conf/modules/multiqc.config index 3334a8ec2..a1ba09bf1 100644 --- a/conf/modules/multiqc.config +++ b/conf/modules/multiqc.config @@ -1,10 +1,5 @@ process { withName: 'MULTIQC' { ext.args = { params.multiqc_title ? "--title \"$params.multiqc_title\"" : '' } - publishDir = [ - path: { "${params.outdir}/multiqc/${params.aligner}" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] } } diff --git a/conf/modules/parabricks_fq2bammeth.config b/conf/modules/parabricks_fq2bammeth.config index 71e2596a9..401272941 100644 --- a/conf/modules/parabricks_fq2bammeth.config +++ b/conf/modules/parabricks_fq2bammeth.config @@ -2,11 +2,5 @@ process { withName: PARABRICKS_FQ2BAMMETH { cache = 'lenient' // This is set because in the module command the index files are touched so as to have bwameth not complain ext.args = '--low-memory' - publishDir = [ - path: { "${params.outdir}/${params.aligner}/alignments" }, - pattern: "*.bam", - mode: params.publish_dir_mode, - enabled: params.save_align_intermeds - ] } } diff --git a/conf/modules/picard_bedtointervallist.config b/conf/modules/picard_bedtointervallist.config index a9528349b..1728bc936 100644 --- a/conf/modules/picard_bedtointervallist.config +++ b/conf/modules/picard_bedtointervallist.config @@ -1,10 +1,5 @@ process { withName: PICARD_BEDTOINTERVALLIST { ext.args = "" - publishDir = [ - path: { "${params.outdir}/enrichment_metrics" }, - mode: params.publish_dir_mode, - pattern: "*.intervallist" - ] } } diff --git a/conf/modules/picard_collecthsmetrics.config b/conf/modules/picard_collecthsmetrics.config index 7dbcac6b6..4f02cfa06 100644 --- a/conf/modules/picard_collecthsmetrics.config +++ b/conf/modules/picard_collecthsmetrics.config @@ -1,10 +1,5 @@ process { withName: PICARD_COLLECTHSMETRICS { ext.args = "--MINIMUM_MAPPING_QUALITY 20 --COVERAGE_CAP 1000 --NEAR_DISTANCE 500" - publishDir = [ - path: { "${params.outdir}/enrichment_metrics" }, - mode: params.publish_dir_mode, - pattern: "*_metrics" - ] } } diff --git a/conf/modules/picard_createsequencedictionary.config b/conf/modules/picard_createsequencedictionary.config index 4c8990a68..9e3a913c1 100644 --- a/conf/modules/picard_createsequencedictionary.config +++ b/conf/modules/picard_createsequencedictionary.config @@ -1,11 +1,5 @@ process { withName: PICARD_CREATESEQUENCEDICTIONARY { ext.args = "" - publishDir = [ - path: { "${params.outdir}/${params.aligner}/reference_genome" }, - mode: params.publish_dir_mode, - enabled: params.save_reference, - pattern: "*.dict" - ] } } diff --git a/conf/modules/picard_markduplicates.config b/conf/modules/picard_markduplicates.config index cbd3adcde..c6bb30977 100644 --- a/conf/modules/picard_markduplicates.config +++ b/conf/modules/picard_markduplicates.config @@ -2,17 +2,5 @@ process { withName: PICARD_MARKDUPLICATES { ext.args = "--ASSUME_SORTED true --REMOVE_DUPLICATES false --VALIDATION_STRINGENCY LENIENT --PROGRAM_RECORD_ID 'null' --TMP_DIR tmp" ext.prefix = { "${id}.markdup.sorted" } - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/deduplicated/picard_metrics" }, - pattern: "*.metrics.txt", - mode: params.publish_dir_mode - ], - [ - path: { "${params.outdir}/${params.aligner}/deduplicated" }, - pattern: "*.bam", - mode: params.publish_dir_mode - ] - ] } } diff --git a/conf/modules/preseq_lcextrap.config b/conf/modules/preseq_lcextrap.config index efc2a8880..454037c00 100644 --- a/conf/modules/preseq_lcextrap.config +++ b/conf/modules/preseq_lcextrap.config @@ -1,19 +1,5 @@ process { withName: PRESEQ_LCEXTRAP { ext.args = " -verbose -bam" - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/preseq" }, - mode: params.publish_dir_mode, - pattern: "*.txt", - enabled: params.run_preseq - ], - [ - path: { "${params.outdir}/${params.aligner}/preseq/log" }, - mode: params.publish_dir_mode, - pattern: "*.log", - enabled: params.run_preseq - ] - ] } } diff --git a/conf/modules/qualimap_bamqc.config b/conf/modules/qualimap_bamqc.config index 2cc878712..ad9688bac 100644 --- a/conf/modules/qualimap_bamqc.config +++ b/conf/modules/qualimap_bamqc.config @@ -4,13 +4,5 @@ process { params.genome.toString().startsWith('GRCh') ? '-gd HUMAN' : '', params.genome.toString().startsWith('GRCm') ? '-gd MOUSE' : '' ].join(" ").trim() - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/qualimap/bamqc/" }, - mode: params.publish_dir_mode, - pattern: "*", - enabled: params.run_qualimap - ] - ] } } diff --git a/conf/modules/samtools_faidx.config b/conf/modules/samtools_faidx.config index 26bb23f9d..c4d1dce38 100644 --- a/conf/modules/samtools_faidx.config +++ b/conf/modules/samtools_faidx.config @@ -1,11 +1,5 @@ process { withName: SAMTOOLS_FAIDX { ext.args = "" - publishDir = [ - path: { "${params.outdir}/${params.aligner}/reference_genome" }, - mode: params.publish_dir_mode, - enabled: params.save_reference, - pattern: "*.fai" - ] } } diff --git a/conf/modules/samtools_flagstat.config b/conf/modules/samtools_flagstat.config deleted file mode 100644 index 4b79875c5..000000000 --- a/conf/modules/samtools_flagstat.config +++ /dev/null @@ -1,11 +0,0 @@ -process { - withName: SAMTOOLS_FLAGSTAT { - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/alignments/samtools_stats/" }, - mode: params.publish_dir_mode, - pattern: "*.flagstat" - ] - ] - } -} diff --git a/conf/modules/samtools_index.config b/conf/modules/samtools_index.config index 76cf0fd7d..dd0f6f90b 100644 --- a/conf/modules/samtools_index.config +++ b/conf/modules/samtools_index.config @@ -1,19 +1,5 @@ process { withName: SAMTOOLS_INDEX { ext.prefix = "" - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/deduplicated/" }, - mode: params.publish_dir_mode, - pattern: "*.bai", - enabled: !params.skip_deduplication - ], - [ - path: { "${params.outdir}/${params.aligner}/alignments/" }, - mode: params.publish_dir_mode, - pattern: "*.bai", - enabled: params.skip_deduplication - ] - ] } } diff --git a/conf/modules/samtools_sort.config b/conf/modules/samtools_sort.config index beeb7735b..ed1317db7 100644 --- a/conf/modules/samtools_sort.config +++ b/conf/modules/samtools_sort.config @@ -1,30 +1,5 @@ process { withName: SAMTOOLS_SORT { ext.prefix = { params.skip_deduplication ? "${id}.sorted" : "${id}.deduplicated.sorted" } - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/deduplicated/" }, - mode: params.publish_dir_mode, - pattern: "*.deduplicated.sorted.bam" - ], - [ - path: { "${params.outdir}/${params.aligner}/alignments/" }, - mode: params.publish_dir_mode, - pattern: "*.sorted.bam", - enabled: params.skip_deduplication - ], - [ - path: { "${params.outdir}/${params.aligner}/deduplicated/" }, - mode: params.publish_dir_mode, - pattern: "*markdup*.bam", - enabled: params.save_align_intermeds - ], - [ - path: { "${params.outdir}/${params.aligner}/alignments/" }, - mode: params.publish_dir_mode, - pattern: "*.bam", - enabled: params.save_align_intermeds - ] - ] } } diff --git a/conf/modules/samtools_stats.config b/conf/modules/samtools_stats.config deleted file mode 100644 index 7574f62fc..000000000 --- a/conf/modules/samtools_stats.config +++ /dev/null @@ -1,11 +0,0 @@ -process { - withName: SAMTOOLS_STATS { - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/alignments/samtools_stats/" }, - mode: params.publish_dir_mode, - pattern: "*.stats" - ] - ] - } -} diff --git a/conf/modules/trimgalore.config b/conf/modules/trimgalore.config index f55fd4be4..8e32f6d5d 100644 --- a/conf/modules/trimgalore.config +++ b/conf/modules/trimgalore.config @@ -59,28 +59,5 @@ process { ) ), ].join(' ').trim() } - publishDir = [ - [ - path: { "${params.outdir}/trimgalore/fastqc" }, - mode: params.publish_dir_mode, - pattern: "*.html" - ], - [ - path: { "${params.outdir}/trimgalore/fastqc/zips" }, - mode: params.publish_dir_mode, - pattern: "*.zip" - ], - [ - path: { "${params.outdir}/trimgalore" }, - mode: params.publish_dir_mode, - pattern: "*.fq.gz", - enabled: params.save_trimmed - ], - [ - path: { "${params.outdir}/trimgalore/logs" }, - mode: params.publish_dir_mode, - pattern: "*.txt" - ] - ] } } diff --git a/conf/subworkflows/fasta_index_bismark_bwameth.config b/conf/subworkflows/fasta_index_bismark_bwameth.config index b170b48d6..5c79b1b8b 100644 --- a/conf/subworkflows/fasta_index_bismark_bwameth.config +++ b/conf/subworkflows/fasta_index_bismark_bwameth.config @@ -1,4 +1,3 @@ -includeConfig "../modules/gunzip.config" includeConfig "../modules/bismark_genomepreparation.config" includeConfig "../modules/samtools_faidx.config" includeConfig "../modules/bwameth_index.config" diff --git a/conf/subworkflows/fastq_align_dedup_bwameth.config b/conf/subworkflows/fastq_align_dedup_bwameth.config index fec290d85..b4a73c51a 100644 --- a/conf/subworkflows/fastq_align_dedup_bwameth.config +++ b/conf/subworkflows/fastq_align_dedup_bwameth.config @@ -2,35 +2,6 @@ includeConfig "../modules/bwameth_align.config" includeConfig "../modules/parabricks_fq2bammeth.config" includeConfig "../modules/samtools_sort.config" -includeConfig "../modules/samtools_flagstat.config" -includeConfig "../modules/samtools_stats.config" includeConfig "../modules/picard_markduplicates.config" includeConfig "../modules/methyldackel_extract.config" includeConfig "../modules/methyldackel_mbias.config" - -process { - - withName: SAMTOOLS_INDEX_ALIGNMENTS { - ext.args = "" - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/alignments/" }, - mode: params.publish_dir_mode, - pattern: "*.bam.bai", - enabled: params.save_align_intermeds - ] - ] - } - - withName: SAMTOOLS_INDEX_DEDUPLICATED { - ext.args = "" - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/deduplicated/" }, - mode: params.publish_dir_mode, - pattern: "*.bam.bai" - ] - ] - } - -} diff --git a/main.nf b/main.nf index a7bbf7536..9c3dc2cbd 100644 --- a/main.nf +++ b/main.nf @@ -311,6 +311,13 @@ workflow NFCORE_METHYLSEQ { ) emit: + fasta_index = FASTA_INDEX_BISMARK_BWAMETH.out.fasta_index + bismark_index = FASTA_INDEX_BISMARK_BWAMETH.out.bismark_index + bwameth_index = FASTA_INDEX_BISMARK_BWAMETH.out.bwameth_index + results = METHYLSEQ.out.results + bismark_summary = METHYLSEQ.out.bismark_summary + reference_dict = METHYLSEQ.out.reference_dict + intervallist = METHYLSEQ.out.intervallist multiqc_report = METHYLSEQ.out.multiqc_report } @@ -354,6 +361,94 @@ workflow { params.hook_url, NFCORE_METHYLSEQ.out.multiqc_report ) + + publish: + fasta_index = NFCORE_METHYLSEQ.out.fasta_index + bismark_index = NFCORE_METHYLSEQ.out.bismark_index + bwameth_index = NFCORE_METHYLSEQ.out.bwameth_index + samples = NFCORE_METHYLSEQ.out.results + bismark_summary = NFCORE_METHYLSEQ.out.bismark_summary + reference_dict = NFCORE_METHYLSEQ.out.reference_dict + intervallist = NFCORE_METHYLSEQ.out.intervallist + multiqc_report = NFCORE_METHYLSEQ.out.multiqc_report +} + +output { + fasta_index { + path "${params.aligner}/reference_genome" + enabled params.save_reference + } + + bismark_index { + path "${params.aligner}/reference_genome" + enabled params.save_reference + } + + bwameth_index { + path "${params.aligner}/reference_genome" + enabled params.save_reference + } + + samples { + path { r -> + r.fastqc_html >> "fastqc" + r.fastqc_zip >> "fastqc/zips" + + r.trim_reads >> (params.save_trimmed ? "trimgalore" : null) + r.trim_log >> "trimgalore/logs" + r.trim_unpaired >> (params.save_trimmed ? "trimgalore" : null) + r.trim_html >> "trimgalore/fastqc" + r.trim_zip >> "trimgalore/fastqc/zips" + + r.bam >> (params.save_align_intermeds ? "${params.aligner}/alignments" : null) + r.bai >> (params.skip_deduplication ? "${params.aligner}/alignments/" : "${params.aligner}/deduplicated/") + + r.align_report >> "${params.aligner}/alignments/logs" + r.unmapped >> "${params.aligner}/alignments/unmapped" + r.dedup_report >> "${params.aligner}/deduplicated/logs" + r.coverage2cytosine_coverage >> "bismark/coverage2cytosine/coverage" + r.coverage2cytosine_report >> "bismark/coverage2cytosine/reports" + r.coverage2cytosine_summary >> "bismark/coverage2cytosine/summaries" + r.methylation_bedgraph >> "${params.aligner}/methylation_calls/bedGraph" + r.methylation_calls >> "${params.aligner}/methylation_calls/methylation_calls" + r.methylation_coverage >> "${params.aligner}/methylation_calls/methylation_coverage" + r.methylation_report >> "${params.aligner}/methylation_calls/splitting_report" + r.methylation_mbias >> "${params.aligner}/methylation_calls/mbias" + r.bismark_report >> "${params.aligner}/reports" + + r.samtools_flagstat >> "${params.aligner}/alignments/samtools_stats/" + r.samtools_stats >> "${params.aligner}/alignments/samtools_stats/" + r.methydackel_extract_bedgraph >> "methyldackel" + r.methydackel_extract_methylkit >> "methyldackel" + r.methyldackel_mbias >> "methyldackel/mbias" + r.picard_metrics >> "${params.aligner}/deduplicated/picard_metrics" + + r.qualimap_bamqc >> "${params.aligner}/qualimap/bamqc/" + + r.bedgraph_intersect >> (params.aligner == 'bismark' ? "bismark/methylation_calls/bedGraph" : "methyldackel") + r.picard_hsmetrics >> "enrichment_metrics" + + r.lc_extrap >> "${params.aligner}/preseq" + r.lc_log >> "${params.aligner}/preseq/log" + } + } + + bismark_summary { + path "${params.aligner}/summary" + } + + reference_dict { + path "${params.aligner}/reference_genome" + enabled params.save_reference + } + + intervallist { + path "enrichment_metrics" + } + + multiqc_report { + path "multiqc/${params.aligner}" + } } /* diff --git a/nextflow.config b/nextflow.config index fe74584cb..4220fe5af 100644 --- a/nextflow.config +++ b/nextflow.config @@ -29,6 +29,9 @@ params { config_profile_url = null } +outputDir = params.outdir +workflow.output.mode = params.publish_dir_mode + // Load base.config by default for all pipelines includeConfig 'conf/base.config' diff --git a/workflows/methylseq/nextflow.config b/workflows/methylseq/nextflow.config index b286800ee..67d77b356 100644 --- a/workflows/methylseq/nextflow.config +++ b/workflows/methylseq/nextflow.config @@ -10,13 +10,3 @@ includeConfig "../../conf/subworkflows/fasta_index_bismark_bwameth.config" includeConfig "../../conf/subworkflows/fastq_align_dedup_bismark.config" includeConfig "../../conf/subworkflows/fastq_align_dedup_bwameth.config" includeConfig "../../conf/subworkflows/targeted_sequencing.config" - -process { - - publishDir = [ - path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - -} From 9602210d179b7588f48160e4c726674d16293cf6 Mon Sep 17 00:00:00 2001 From: Ben Sherman Date: Fri, 13 Feb 2026 01:18:46 -0600 Subject: [PATCH 4/6] Move ext settings into pipeline code --- conf/modules/bedtools_intersect.config | 7 -- conf/modules/bismark_align.config | 19 --- conf/modules/bismark_coverage2cytosine.config | 5 - conf/modules/bismark_deduplicate.config | 5 - conf/modules/bismark_genomepreparation.config | 8 -- .../bismark_methylationextractor.config | 14 --- conf/modules/bismark_report.config | 5 - conf/modules/bismark_summary.config | 5 - conf/modules/bwameth_align.config | 1 - conf/modules/bwameth_index.config | 5 - conf/modules/fastqc.config | 5 - conf/modules/methyldackel_extract.config | 11 -- conf/modules/methyldackel_mbias.config | 8 -- conf/modules/multiqc.config | 5 - conf/modules/parabricks_fq2bammeth.config | 1 - conf/modules/picard_bedtointervallist.config | 5 - conf/modules/picard_collecthsmetrics.config | 5 - .../picard_createsequencedictionary.config | 5 - conf/modules/picard_markduplicates.config | 6 - conf/modules/preseq_lcextrap.config | 5 - conf/modules/qualimap_bamqc.config | 8 -- conf/modules/samtools_faidx.config | 5 - conf/modules/samtools_index.config | 5 - conf/modules/samtools_sort.config | 5 - conf/modules/trimgalore.config | 63 ---------- .../fasta_index_bismark_bwameth.config | 3 - .../fastq_align_dedup_bismark.config | 8 -- .../fastq_align_dedup_bwameth.config | 4 - conf/subworkflows/targeted_sequencing.config | 4 - modules/nf-core/bedtools/intersect/main.nf | 29 ++--- modules/nf-core/bismark/align/main.nf | 13 ++- .../nf-core/bismark/coverage2cytosine/main.nf | 12 +- modules/nf-core/bismark/deduplicate/main.nf | 12 +- .../nf-core/bismark/genomepreparation/main.nf | 9 +- .../bismark/methylationextractor/main.nf | 18 +-- modules/nf-core/bismark/report/main.nf | 12 +- modules/nf-core/bismark/summary/main.nf | 2 - modules/nf-core/bwameth/align/main.nf | 17 +-- modules/nf-core/bwameth/index/main.nf | 2 - modules/nf-core/fastqc/main.nf | 13 ++- modules/nf-core/methyldackel/extract/main.nf | 7 +- modules/nf-core/multiqc/main.nf | 20 ++-- modules/nf-core/parabricks/fq2bammeth/main.nf | 10 +- .../nf-core/picard/bedtointervallist/main.nf | 11 +- .../nf-core/picard/collecthsmetrics/main.nf | 10 +- .../picard/createsequencedictionary/main.nf | 14 ++- modules/nf-core/picard/markduplicates/main.nf | 19 +-- modules/nf-core/preseq/lcextrap/main.nf | 10 +- modules/nf-core/qualimap/bamqc/main.nf | 12 +- modules/nf-core/samtools/faidx/main.nf | 13 ++- modules/nf-core/samtools/index/main.nf | 10 +- modules/nf-core/samtools/sort/main.nf | 14 ++- modules/nf-core/trimgalore/main.nf | 10 +- .../local/targeted_sequencing/main.nf | 12 +- .../fasta_index_bismark_bwameth/main.nf | 16 ++- .../nf-core/fastq_align_dedup_bismark/main.nf | 52 ++++++++- .../nf-core/fastq_align_dedup_bwameth/main.nf | 37 +++++- workflows/methylseq/main.nf | 108 +++++++++++++++--- workflows/methylseq/nextflow.config | 10 -- 59 files changed, 378 insertions(+), 391 deletions(-) delete mode 100644 conf/modules/bedtools_intersect.config delete mode 100644 conf/modules/bismark_align.config delete mode 100644 conf/modules/bismark_coverage2cytosine.config delete mode 100644 conf/modules/bismark_deduplicate.config delete mode 100644 conf/modules/bismark_genomepreparation.config delete mode 100644 conf/modules/bismark_methylationextractor.config delete mode 100644 conf/modules/bismark_report.config delete mode 100644 conf/modules/bismark_summary.config delete mode 100644 conf/modules/bwameth_index.config delete mode 100644 conf/modules/fastqc.config delete mode 100644 conf/modules/methyldackel_extract.config delete mode 100644 conf/modules/methyldackel_mbias.config delete mode 100644 conf/modules/multiqc.config delete mode 100644 conf/modules/picard_bedtointervallist.config delete mode 100644 conf/modules/picard_collecthsmetrics.config delete mode 100644 conf/modules/picard_createsequencedictionary.config delete mode 100644 conf/modules/picard_markduplicates.config delete mode 100644 conf/modules/preseq_lcextrap.config delete mode 100644 conf/modules/qualimap_bamqc.config delete mode 100644 conf/modules/samtools_faidx.config delete mode 100644 conf/modules/samtools_index.config delete mode 100644 conf/modules/samtools_sort.config delete mode 100644 conf/modules/trimgalore.config delete mode 100644 conf/subworkflows/fasta_index_bismark_bwameth.config delete mode 100644 conf/subworkflows/fastq_align_dedup_bismark.config delete mode 100644 conf/subworkflows/targeted_sequencing.config diff --git a/conf/modules/bedtools_intersect.config b/conf/modules/bedtools_intersect.config deleted file mode 100644 index ee8287e12..000000000 --- a/conf/modules/bedtools_intersect.config +++ /dev/null @@ -1,7 +0,0 @@ -process { - withName: BEDTOOLS_INTERSECT { - ext.args = '' - ext.prefix = { "${intervals1.baseName}" } - ext.suffix = 'targeted.bedGraph' - } -} diff --git a/conf/modules/bismark_align.config b/conf/modules/bismark_align.config deleted file mode 100644 index fb456ba3b..000000000 --- a/conf/modules/bismark_align.config +++ /dev/null @@ -1,19 +0,0 @@ -process { - withName: BISMARK_ALIGN { - ext.args = { [ - (params.aligner == 'bismark_hisat') ? ' --hisat2' : ' --bowtie2', - (params.aligner == 'bismark_hisat' && params.known_splices) ? " --known-splicesite-infile <(hisat2_extract_splice_sites.py ${params.known_splices})" : '', - params.pbat ? ' --pbat' : '', - ( params.single_cell || params.non_directional || params.zymo ) ? ' --non_directional' : '', - params.unmapped ? ' --unmapped' : '', - params.relax_mismatches ? " --score_min L,0,-${params.num_mismatches}" : '', - params.local_alignment ? " --local" : '', - !single_end && params.minins ? " --minins ${params.minins}" : '', - single_end ? '' : ( - params.maxins ? " --maxins ${params.maxins}" : ( - params.em_seq ? " --maxins 1000" : '' - ) - ) - ].join(' ').trim() } - } -} diff --git a/conf/modules/bismark_coverage2cytosine.config b/conf/modules/bismark_coverage2cytosine.config deleted file mode 100644 index 500f43c68..000000000 --- a/conf/modules/bismark_coverage2cytosine.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: BISMARK_COVERAGE2CYTOSINE { - ext.args = params.nomeseq ? '--nome-seq' : '' - } -} diff --git a/conf/modules/bismark_deduplicate.config b/conf/modules/bismark_deduplicate.config deleted file mode 100644 index 3bde9e1c0..000000000 --- a/conf/modules/bismark_deduplicate.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: BISMARK_DEDUPLICATE { - ext.args = '' - } -} diff --git a/conf/modules/bismark_genomepreparation.config b/conf/modules/bismark_genomepreparation.config deleted file mode 100644 index 5a618c091..000000000 --- a/conf/modules/bismark_genomepreparation.config +++ /dev/null @@ -1,8 +0,0 @@ -process { - withName: BISMARK_GENOMEPREPARATION { - ext.args = [ - (params.aligner == 'bismark_hisat') ? ' --hisat2' : ' --bowtie2', - params.slamseq ? ' --slam' : '' - ].join(' ').trim() - } -} diff --git a/conf/modules/bismark_methylationextractor.config b/conf/modules/bismark_methylationextractor.config deleted file mode 100644 index e077821b5..000000000 --- a/conf/modules/bismark_methylationextractor.config +++ /dev/null @@ -1,14 +0,0 @@ -process { - withName: BISMARK_METHYLATIONEXTRACTOR { - ext.args = { [ - params.comprehensive ? ' --comprehensive' : '', - params.meth_cutoff ? " --cutoff ${params.meth_cutoff}" : '', - params.nomeseq ? '--CX' : '', - params.ignore_r1 > 0 ? "--ignore ${params.ignore_r1}" : '', - params.ignore_3prime_r1 > 0 ? "--ignore_3prime ${params.ignore_3prime_r1}" : '', - single_end ? '' : (params.no_overlap ? ' --no_overlap' : '--include_overlap'), - single_end ? '' : (params.ignore_r2 > 0 ? "--ignore_r2 ${params.ignore_r2}" : ""), - single_end ? '' : (params.ignore_3prime_r2 > 0 ? "--ignore_3prime_r2 ${params.ignore_3prime_r2}": "") - ].join(' ').trim() } - } -} diff --git a/conf/modules/bismark_report.config b/conf/modules/bismark_report.config deleted file mode 100644 index 74667a41f..000000000 --- a/conf/modules/bismark_report.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: BISMARK_REPORT { - ext.args = '' - } -} diff --git a/conf/modules/bismark_summary.config b/conf/modules/bismark_summary.config deleted file mode 100644 index 4cdfe69b5..000000000 --- a/conf/modules/bismark_summary.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: BISMARK_SUMMARY { - ext.args = '' - } -} diff --git a/conf/modules/bwameth_align.config b/conf/modules/bwameth_align.config index 3467d4a8e..f221b40da 100644 --- a/conf/modules/bwameth_align.config +++ b/conf/modules/bwameth_align.config @@ -1,6 +1,5 @@ process { withName: BWAMETH_ALIGN { cache = 'lenient' // This is set because in the module command the index files are touched so as to have bwameth not complain - ext.args = '' } } diff --git a/conf/modules/bwameth_index.config b/conf/modules/bwameth_index.config deleted file mode 100644 index b5883cdce..000000000 --- a/conf/modules/bwameth_index.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: BWAMETH_INDEX { - ext.args = '' - } -} diff --git a/conf/modules/fastqc.config b/conf/modules/fastqc.config deleted file mode 100644 index 64bd58798..000000000 --- a/conf/modules/fastqc.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: FASTQC { - ext.args = '--quiet' - } -} diff --git a/conf/modules/methyldackel_extract.config b/conf/modules/methyldackel_extract.config deleted file mode 100644 index 3e045e052..000000000 --- a/conf/modules/methyldackel_extract.config +++ /dev/null @@ -1,11 +0,0 @@ -process { - withName: METHYLDACKEL_EXTRACT { - ext.args = [ - params.all_contexts ? ' --CHG --CHH' : '', - params.merge_context ? ' --mergeContext' : '', - params.ignore_flags ? " --ignoreFlags" : '', - params.methyl_kit ? " --methylKit" : '', - params.min_depth > 0 ? " --minDepth ${params.min_depth}" : '' - ].join(" ").trim() - } -} diff --git a/conf/modules/methyldackel_mbias.config b/conf/modules/methyldackel_mbias.config deleted file mode 100644 index 24a5547d9..000000000 --- a/conf/modules/methyldackel_mbias.config +++ /dev/null @@ -1,8 +0,0 @@ -process { - withName: METHYLDACKEL_MBIAS { - ext.args = [ - params.all_contexts ? ' --CHG --CHH' : '', - params.ignore_flags ? " --ignoreFlags" : '' - ].join(" ").trim() - } -} diff --git a/conf/modules/multiqc.config b/conf/modules/multiqc.config deleted file mode 100644 index a1ba09bf1..000000000 --- a/conf/modules/multiqc.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: 'MULTIQC' { - ext.args = { params.multiqc_title ? "--title \"$params.multiqc_title\"" : '' } - } -} diff --git a/conf/modules/parabricks_fq2bammeth.config b/conf/modules/parabricks_fq2bammeth.config index 401272941..742903692 100644 --- a/conf/modules/parabricks_fq2bammeth.config +++ b/conf/modules/parabricks_fq2bammeth.config @@ -1,6 +1,5 @@ process { withName: PARABRICKS_FQ2BAMMETH { cache = 'lenient' // This is set because in the module command the index files are touched so as to have bwameth not complain - ext.args = '--low-memory' } } diff --git a/conf/modules/picard_bedtointervallist.config b/conf/modules/picard_bedtointervallist.config deleted file mode 100644 index 1728bc936..000000000 --- a/conf/modules/picard_bedtointervallist.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: PICARD_BEDTOINTERVALLIST { - ext.args = "" - } -} diff --git a/conf/modules/picard_collecthsmetrics.config b/conf/modules/picard_collecthsmetrics.config deleted file mode 100644 index 4f02cfa06..000000000 --- a/conf/modules/picard_collecthsmetrics.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: PICARD_COLLECTHSMETRICS { - ext.args = "--MINIMUM_MAPPING_QUALITY 20 --COVERAGE_CAP 1000 --NEAR_DISTANCE 500" - } -} diff --git a/conf/modules/picard_createsequencedictionary.config b/conf/modules/picard_createsequencedictionary.config deleted file mode 100644 index 9e3a913c1..000000000 --- a/conf/modules/picard_createsequencedictionary.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: PICARD_CREATESEQUENCEDICTIONARY { - ext.args = "" - } -} diff --git a/conf/modules/picard_markduplicates.config b/conf/modules/picard_markduplicates.config deleted file mode 100644 index c6bb30977..000000000 --- a/conf/modules/picard_markduplicates.config +++ /dev/null @@ -1,6 +0,0 @@ -process { - withName: PICARD_MARKDUPLICATES { - ext.args = "--ASSUME_SORTED true --REMOVE_DUPLICATES false --VALIDATION_STRINGENCY LENIENT --PROGRAM_RECORD_ID 'null' --TMP_DIR tmp" - ext.prefix = { "${id}.markdup.sorted" } - } -} diff --git a/conf/modules/preseq_lcextrap.config b/conf/modules/preseq_lcextrap.config deleted file mode 100644 index 454037c00..000000000 --- a/conf/modules/preseq_lcextrap.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: PRESEQ_LCEXTRAP { - ext.args = " -verbose -bam" - } -} diff --git a/conf/modules/qualimap_bamqc.config b/conf/modules/qualimap_bamqc.config deleted file mode 100644 index ad9688bac..000000000 --- a/conf/modules/qualimap_bamqc.config +++ /dev/null @@ -1,8 +0,0 @@ -process { - withName: QUALIMAP_BAMQC { - ext.args = [ - params.genome.toString().startsWith('GRCh') ? '-gd HUMAN' : '', - params.genome.toString().startsWith('GRCm') ? '-gd MOUSE' : '' - ].join(" ").trim() - } -} diff --git a/conf/modules/samtools_faidx.config b/conf/modules/samtools_faidx.config deleted file mode 100644 index c4d1dce38..000000000 --- a/conf/modules/samtools_faidx.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: SAMTOOLS_FAIDX { - ext.args = "" - } -} diff --git a/conf/modules/samtools_index.config b/conf/modules/samtools_index.config deleted file mode 100644 index dd0f6f90b..000000000 --- a/conf/modules/samtools_index.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: SAMTOOLS_INDEX { - ext.prefix = "" - } -} diff --git a/conf/modules/samtools_sort.config b/conf/modules/samtools_sort.config deleted file mode 100644 index ed1317db7..000000000 --- a/conf/modules/samtools_sort.config +++ /dev/null @@ -1,5 +0,0 @@ -process { - withName: SAMTOOLS_SORT { - ext.prefix = { params.skip_deduplication ? "${id}.sorted" : "${id}.deduplicated.sorted" } - } -} diff --git a/conf/modules/trimgalore.config b/conf/modules/trimgalore.config deleted file mode 100644 index 8e32f6d5d..000000000 --- a/conf/modules/trimgalore.config +++ /dev/null @@ -1,63 +0,0 @@ -process { - withName: TRIMGALORE { - ext.args = { [ - // Static args - '--fastqc', - - // Special flags - params.rrbs ? '--rrbs' : '', - params.nextseq_trim > 0 ? "--nextseq ${params.nextseq_trim}" : '', - params.length_trim ? "--length ${params.length_trim}" : '', - - // Trimming - R1 - params.clip_r1 > 0 ? "--clip_r1 ${params.clip_r1}" : ( - params.skip_trimming_presets ? '' : ( - params.pbat ? "--clip_r1 8" : ( - params.single_cell ? "--clip_r1 6" : ( - (params.accel || params.zymo || params.em_seq) ? "--clip_r1 10" : '' - ) - ) - ) - ), - - // Trimming - R2 - single_end ? '' : ( - params.clip_r2 > 0 ? "--clip_r2 ${params.clip_r2}" : ( - params.skip_trimming_presets ? '' : ( - params.pbat ? "--clip_r2 8" : ( - params.single_cell ? "--clip_r2 6" : ( - (params.zymo || params.em_seq) ? "--clip_r2 10" : ( - params.accel ? "--clip_r2 15" : '' - ) - ) - ) - ) - ) - ), - - // Trimming - 3' R1 - params.three_prime_clip_r1 > 0 ? "--three_prime_clip_r1 ${params.three_prime_clip_r1}" : ( - params.skip_trimming_presets ? '' : ( - params.pbat ? "--three_prime_clip_r1 8" : ( - params.single_cell ? "--three_prime_clip_r1 6" : ( - (params.accel || params.zymo || params.em_seq) ? "--three_prime_clip_r1 10" : '' - ) - ) - ) - ), - - // Trimming - 3' R2 - single_end ? '' : ( - params.three_prime_clip_r2 > 0 ? "--three_prime_clip_r2 ${params.three_prime_clip_r2}" : ( - params.skip_trimming_presets ? '' : ( - params.pbat ? "--three_prime_clip_r2 8" : ( - params.single_cell ? "--three_prime_clip_r2 6" : ( - (params.accel || params.zymo || params.em_seq) ? "--three_prime_clip_r2 10" : '' - ) - ) - ) - ) - ), - ].join(' ').trim() } - } -} diff --git a/conf/subworkflows/fasta_index_bismark_bwameth.config b/conf/subworkflows/fasta_index_bismark_bwameth.config deleted file mode 100644 index 5c79b1b8b..000000000 --- a/conf/subworkflows/fasta_index_bismark_bwameth.config +++ /dev/null @@ -1,3 +0,0 @@ -includeConfig "../modules/bismark_genomepreparation.config" -includeConfig "../modules/samtools_faidx.config" -includeConfig "../modules/bwameth_index.config" diff --git a/conf/subworkflows/fastq_align_dedup_bismark.config b/conf/subworkflows/fastq_align_dedup_bismark.config deleted file mode 100644 index 7531de5a9..000000000 --- a/conf/subworkflows/fastq_align_dedup_bismark.config +++ /dev/null @@ -1,8 +0,0 @@ -includeConfig "../modules/bismark_align.config" -includeConfig "../modules/bismark_deduplicate.config" -includeConfig "../modules/samtools_sort.config" -includeConfig "../modules/samtools_index.config" -includeConfig "../modules/bismark_methylationextractor.config" -includeConfig "../modules/bismark_coverage2cytosine.config" -includeConfig "../modules/bismark_report.config" -includeConfig "../modules/bismark_summary.config" diff --git a/conf/subworkflows/fastq_align_dedup_bwameth.config b/conf/subworkflows/fastq_align_dedup_bwameth.config index b4a73c51a..b79737da8 100644 --- a/conf/subworkflows/fastq_align_dedup_bwameth.config +++ b/conf/subworkflows/fastq_align_dedup_bwameth.config @@ -1,7 +1,3 @@ includeConfig "../modules/bwameth_align.config" includeConfig "../modules/parabricks_fq2bammeth.config" -includeConfig "../modules/samtools_sort.config" -includeConfig "../modules/picard_markduplicates.config" -includeConfig "../modules/methyldackel_extract.config" -includeConfig "../modules/methyldackel_mbias.config" diff --git a/conf/subworkflows/targeted_sequencing.config b/conf/subworkflows/targeted_sequencing.config deleted file mode 100644 index 666eb0d78..000000000 --- a/conf/subworkflows/targeted_sequencing.config +++ /dev/null @@ -1,4 +0,0 @@ -includeConfig "../modules/bedtools_intersect.config" -includeConfig "../modules/picard_bedtointervallist.config" -includeConfig "../modules/picard_createsequencedictionary.config" -includeConfig "../modules/picard_collecthsmetrics.config" diff --git a/modules/nf-core/bedtools/intersect/main.nf b/modules/nf-core/bedtools/intersect/main.nf index 58bc0efcb..95a457b88 100644 --- a/modules/nf-core/bedtools/intersect/main.nf +++ b/modules/nf-core/bedtools/intersect/main.nf @@ -14,11 +14,14 @@ process BEDTOOLS_INTERSECT { id: String, intervals1: Path, intervals2: Path, - chrom_sizes: Path? + chrom_sizes: Path?, + args: String?, + prefix: String?, + suffix: String? ): Record output: - record(id: id, bedgraph_intersect: file("*.${extension}")) + record(id: id, bedgraph_intersect: file("*.${suffix}")) topic: file("versions.yml") >> 'versions' @@ -27,13 +30,13 @@ process BEDTOOLS_INTERSECT { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id + args = args ?: '' + prefix = prefix ?: id //Extension of the output file. It is set by the user via "ext.suffix" in the config. Corresponds to the file format which depends on arguments (e. g., ".bed", ".bam", ".txt", etc.). - extension = task.ext.suffix ?: "${intervals1.extension}" + suffix = suffix ?: "${intervals1.extension}" def sizes = chrom_sizes ? "-g ${chrom_sizes}" : '' - if ("${intervals1}" == "${prefix}.${extension}" || "${intervals2}" == "${prefix}.${extension}") { - error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + if ("${intervals1}" == "${prefix}.${suffix}" || "${intervals2}" == "${prefix}.${suffix}") { + error("Input and output names are the same, use \"prefix\" to disambiguate!") } """ bedtools \\ @@ -42,7 +45,7 @@ process BEDTOOLS_INTERSECT { -b ${intervals2} \\ ${args} \\ ${sizes} \\ - > ${prefix}.${extension} + > ${prefix}.${suffix} cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -51,13 +54,13 @@ process BEDTOOLS_INTERSECT { """ stub: - def prefix = task.ext.prefix ?: id - extension = task.ext.suffix ?: "bed" - if ("${intervals1}" == "${prefix}.${extension}" || "${intervals2}" == "${prefix}.${extension}") { - error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + prefix = prefix ?: id + suffix = suffix ?: "bed" + if ("${intervals1}" == "${prefix}.${suffix}" || "${intervals2}" == "${prefix}.${suffix}") { + error("Input and output names are the same, use \"prefix\" to disambiguate!") } """ - touch ${prefix}.${extension} + touch ${prefix}.${suffix} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/bismark/align/main.nf b/modules/nf-core/bismark/align/main.nf index 2696dea6f..fc5fb5c32 100644 --- a/modules/nf-core/bismark/align/main.nf +++ b/modules/nf-core/bismark/align/main.nf @@ -15,7 +15,9 @@ process BISMARK_ALIGN { single_end: Boolean, reads: List, fasta: Path, - bismark_index: Path + bismark_index: Path, + args: String?, + prefix: String? ): Record stage: @@ -37,9 +39,9 @@ process BISMARK_ALIGN { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - if (task.ext.prefix) { - args += " --prefix ${task.ext.prefix}" + args = args ?: '' + if (prefix) { + args += " --prefix ${prefix}" } def fastq = single_end ? "${reads[0]}" : "-1 ${reads[0]} -2 ${reads[1]}" @@ -85,8 +87,7 @@ process BISMARK_ALIGN { """ stub: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id + prefix = prefix ?: id """ touch ${prefix}.bam touch ${prefix}.report.txt diff --git a/modules/nf-core/bismark/coverage2cytosine/main.nf b/modules/nf-core/bismark/coverage2cytosine/main.nf index e87bb87d2..99842638e 100644 --- a/modules/nf-core/bismark/coverage2cytosine/main.nf +++ b/modules/nf-core/bismark/coverage2cytosine/main.nf @@ -14,7 +14,9 @@ process BISMARK_COVERAGE2CYTOSINE { id: String, methylation_coverage: Path, fasta: Path, - bismark_index: Path + bismark_index: Path, + args: String?, + prefix: String? ): Record stage: @@ -35,8 +37,8 @@ process BISMARK_COVERAGE2CYTOSINE { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id + args = args ?: '' + prefix = prefix ?: id """ coverage2cytosine \\ ${methylation_coverage} \\ @@ -52,8 +54,8 @@ process BISMARK_COVERAGE2CYTOSINE { """ stub: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id + args = args ?: '' + prefix = prefix ?: id """ echo | gzip > ${prefix}.cov.gz echo | gzip > ${prefix}.report.txt.gz diff --git a/modules/nf-core/bismark/deduplicate/main.nf b/modules/nf-core/bismark/deduplicate/main.nf index 9ee420c6f..11d7df965 100644 --- a/modules/nf-core/bismark/deduplicate/main.nf +++ b/modules/nf-core/bismark/deduplicate/main.nf @@ -13,7 +13,9 @@ process BISMARK_DEDUPLICATE { ( id: String, single_end: Boolean, - bam: Path + bam: Path, + args: String?, + prefix: String? ): Record output: @@ -30,8 +32,8 @@ process BISMARK_DEDUPLICATE { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id + args = args ?: '' + prefix = prefix ?: id def seqtype = single_end ? '-s' : '-p' """ deduplicate_bismark \\ @@ -46,8 +48,8 @@ process BISMARK_DEDUPLICATE { """ stub: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id + args = args ?: '' + prefix = prefix ?: id """ touch ${prefix}.deduplicated.bam touch ${prefix}.deduplication_report.txt diff --git a/modules/nf-core/bismark/genomepreparation/main.nf b/modules/nf-core/bismark/genomepreparation/main.nf index e8f3c5750..768372c73 100644 --- a/modules/nf-core/bismark/genomepreparation/main.nf +++ b/modules/nf-core/bismark/genomepreparation/main.nf @@ -10,7 +10,10 @@ process BISMARK_GENOMEPREPARATION { : 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47'}" input: - fasta: Path + ( + fasta: Path, + args: String? + ): Record stage: stageAs "BismarkIndex/", fasta @@ -25,7 +28,7 @@ process BISMARK_GENOMEPREPARATION { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + args = args ?: '' """ bismark_genome_preparation \\ ${args} \\ @@ -38,7 +41,7 @@ process BISMARK_GENOMEPREPARATION { """ stub: - def args = task.ext.args ?: '' + args = args ?: '' """ rm ${fasta} diff --git a/modules/nf-core/bismark/methylationextractor/main.nf b/modules/nf-core/bismark/methylationextractor/main.nf index 18f5e5dd0..6984ead77 100644 --- a/modules/nf-core/bismark/methylationextractor/main.nf +++ b/modules/nf-core/bismark/methylationextractor/main.nf @@ -14,7 +14,8 @@ process BISMARK_METHYLATIONEXTRACTOR { id: String, single_end: Boolean, bam: Path, - bismark_index: Path + bismark_index: Path, + args: String? ): Record output: @@ -34,7 +35,7 @@ process BISMARK_METHYLATIONEXTRACTOR { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + args = args ?: '' // Assign sensible numbers for multicore and buffer_size based on bismark docs if (!args.contains('--multicore') && task.cpus >= 6) { args += " --multicore ${(task.cpus / 3) as int}" @@ -62,14 +63,13 @@ process BISMARK_METHYLATIONEXTRACTOR { """ stub: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id + args = args ?: '' """ - echo | gzip > ${prefix}.bedGraph.gz - echo | gzip > ${prefix}.txt.gz - echo | gzip > ${prefix}.cov.gz - touch ${prefix}_splitting_report.txt - touch ${prefix}.M-bias.txt + echo | gzip > ${id}.bedGraph.gz + echo | gzip > ${id}.txt.gz + echo | gzip > ${id}.cov.gz + touch ${id}_splitting_report.txt + touch ${id}.M-bias.txt cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/bismark/report/main.nf b/modules/nf-core/bismark/report/main.nf index a58f0e832..e3a898608 100644 --- a/modules/nf-core/bismark/report/main.nf +++ b/modules/nf-core/bismark/report/main.nf @@ -15,7 +15,8 @@ process BISMARK_REPORT { align_report: Path, dedup_report: Path, methylation_report: Path, - methylation_mbias: Path + methylation_mbias: Path, + args: String? ): Record output: @@ -28,7 +29,7 @@ process BISMARK_REPORT { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + args = args ?: '' """ bismark2report ${args} @@ -39,11 +40,10 @@ process BISMARK_REPORT { """ stub: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id + args = args ?: '' """ - touch ${prefix}.report.txt - touch ${prefix}.report.html + touch ${id}.report.txt + touch ${id}.report.html cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/bismark/summary/main.nf b/modules/nf-core/bismark/summary/main.nf index aa0783cd1..265c51670 100644 --- a/modules/nf-core/bismark/summary/main.nf +++ b/modules/nf-core/bismark/summary/main.nf @@ -27,7 +27,6 @@ process BISMARK_SUMMARY { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' """ bismark2summary ${bam.join(' ')} @@ -38,7 +37,6 @@ process BISMARK_SUMMARY { """ stub: - def args = task.ext.args ?: '' """ touch bismark_summary_report.txt touch bismark_summary_report.html diff --git a/modules/nf-core/bwameth/align/main.nf b/modules/nf-core/bwameth/align/main.nf index fbabe0bd3..3759b4f07 100644 --- a/modules/nf-core/bwameth/align/main.nf +++ b/modules/nf-core/bwameth/align/main.nf @@ -15,7 +15,10 @@ process BWAMETH_ALIGN { read_group: String?, reads: Path, fasta: Path, - index: Path + index: Path, + args_bwameth: String?, + args_samtools: String?, + prefix: String? ): Record output: @@ -31,21 +34,21 @@ process BWAMETH_ALIGN { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def args2 = task.ext.args2 ?: '' - def prefix = task.ext.prefix ?: id + args_bwameth = args_bwameth ?: '' + args_samtools = args_samtools ?: '' + prefix = prefix ?: id read_group = read_group ? "-R ${read_group}" : "" """ export BWA_METH_SKIP_TIME_CHECKS=1 ln -sf \$(readlink ${fasta}) ${index}/${fasta} bwameth.py \\ - ${args} \\ + ${args_bwameth} \\ ${read_group} \\ -t ${task.cpus} \\ --reference ${index}/${fasta} \\ ${reads} \\ - | samtools view ${args2} -@ ${task.cpus} -bhS -o ${prefix}.bam - + | samtools view ${args_samtools} -@ ${task.cpus} -bhS -o ${prefix}.bam - cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -54,7 +57,7 @@ process BWAMETH_ALIGN { """ stub: - def prefix = task.ext.prefix ?: id + prefix = prefix ?: id """ touch ${prefix}.bam diff --git a/modules/nf-core/bwameth/index/main.nf b/modules/nf-core/bwameth/index/main.nf index 7e6be3947..a15f8f79e 100644 --- a/modules/nf-core/bwameth/index/main.nf +++ b/modules/nf-core/bwameth/index/main.nf @@ -26,7 +26,6 @@ process BWAMETH_INDEX { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' def index_cmd = use_mem2 ? "index-mem2" : "index" """ @@ -41,7 +40,6 @@ process BWAMETH_INDEX { """ stub: - def args = task.ext.args ?: '' """ rm ${fasta} diff --git a/modules/nf-core/fastqc/main.nf b/modules/nf-core/fastqc/main.nf index bd23d5640..12a716d17 100644 --- a/modules/nf-core/fastqc/main.nf +++ b/modules/nf-core/fastqc/main.nf @@ -10,7 +10,12 @@ process FASTQC { : 'biocontainers/fastqc:0.12.1--hdfd78af_0'}" input: - (id: String, reads: List): Record + ( + id: String, + reads: List, + args: String?, + prefix: String? + ): Record output: record( @@ -26,8 +31,8 @@ process FASTQC { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id + args = args ?: '--quiet' + prefix = prefix ?: id // Make list of old name and new name pairs to use for renaming in the bash while loop def old_new_pairs = reads.withIndex().collect { entry, index -> [entry, "${prefix}_${index + 1}.${entry.extension}"] } def rename_to = old_new_pairs*.join(' ').join(' ') @@ -58,7 +63,7 @@ process FASTQC { """ stub: - def prefix = task.ext.prefix ?: id + prefix = prefix ?: id """ touch ${prefix}.html touch ${prefix}.zip diff --git a/modules/nf-core/methyldackel/extract/main.nf b/modules/nf-core/methyldackel/extract/main.nf index a2b77acd0..263eb74bb 100644 --- a/modules/nf-core/methyldackel/extract/main.nf +++ b/modules/nf-core/methyldackel/extract/main.nf @@ -15,7 +15,8 @@ process METHYLDACKEL_EXTRACT { bam: Path, bai: Path, fasta: Path, - fai: Path + fai: Path, + args: String? ): Record output: @@ -32,7 +33,7 @@ process METHYLDACKEL_EXTRACT { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + args = args ?: '' """ MethylDackel extract \\ ${args} \\ @@ -46,7 +47,7 @@ process METHYLDACKEL_EXTRACT { """ stub: - def args = task.ext.args ?: '' + args = args ?: '' def out_extension = args.contains('--methylKit') ? 'methylKit' : 'bedGraph' """ touch ${bam.baseName}_CpG.${out_extension} diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index 037ac921e..0db989859 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -9,12 +9,16 @@ process MULTIQC { : 'biocontainers/multiqc:1.30--pyhdfd78af_0'}" input: - multiqc_files : Set - multiqc_config : Path - extra_multiqc_config : Path? - multiqc_logo : Path? - replace_names : Path? - sample_names : Path? + ( + multiqc_files : Set, + multiqc_config : Path, + extra_multiqc_config : Path?, + multiqc_logo : Path?, + replace_names : Path?, + sample_names : Path?, + args : String?, + prefix : String? + ): Record stage: stageAs "?/*", multiqc_files @@ -30,8 +34,8 @@ process MULTIQC { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ? "--filename ${task.ext.prefix}.html" : '' + args = args ?: '' + prefix = prefix ? "--filename ${prefix}.html" : '' def config = multiqc_config ? "--config ${multiqc_config}" : '' def extra_config = extra_multiqc_config ? "--config ${extra_multiqc_config}" : '' def logo = multiqc_logo ? "--cl-config 'custom_logo: \"${multiqc_logo}\"'" : '' diff --git a/modules/nf-core/parabricks/fq2bammeth/main.nf b/modules/nf-core/parabricks/fq2bammeth/main.nf index 242507a3a..c0c3428f2 100644 --- a/modules/nf-core/parabricks/fq2bammeth/main.nf +++ b/modules/nf-core/parabricks/fq2bammeth/main.nf @@ -14,7 +14,9 @@ process PARABRICKS_FQ2BAMMETH { reads: Path, fasta: Path, bwameth_index: Path, - known_sites: Path? + known_sites: Path?, + args: String?, + prefix: String? ): Record output: @@ -39,8 +41,8 @@ process PARABRICKS_FQ2BAMMETH { if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { error("Parabricks module does not support Conda. Please use Docker / Singularity / Podman instead.") } - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id + args = args ?: '' + prefix = prefix ?: id def in_fq_command = single_end ? "--in-se-fq ${reads}" : "--in-fq ${reads}" def known_sites_command = known_sites ? known_sites.collect { "--knownSites ${it}" }.join(' ') : "" def known_sites_output = known_sites ? "--out-recal-file ${prefix}.table" : "" @@ -73,7 +75,7 @@ process PARABRICKS_FQ2BAMMETH { if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { error("Parabricks module does not support Conda. Please use Docker / Singularity / Podman instead.") } - def prefix = task.ext.prefix ?: id + prefix = prefix ?: id """ touch ${prefix}.bam touch ${prefix}.bam.bai diff --git a/modules/nf-core/picard/bedtointervallist/main.nf b/modules/nf-core/picard/bedtointervallist/main.nf index 652488b3d..fa7332f0a 100644 --- a/modules/nf-core/picard/bedtointervallist/main.nf +++ b/modules/nf-core/picard/bedtointervallist/main.nf @@ -14,7 +14,9 @@ process PICARD_BEDTOINTERVALLIST { id: String, bed: Path, reference_dict: Path, - arguments_file: Path? + arguments_file: Path?, + args: String?, + prefix: String? ): Record output: @@ -27,8 +29,8 @@ process PICARD_BEDTOINTERVALLIST { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id + args = args ?: '' + prefix = prefix ?: id def args_file = arguments_file ? "--arguments_file ${arguments_file}" : "" def avail_mem = 3072 if (!task.memory) { @@ -55,7 +57,8 @@ process PICARD_BEDTOINTERVALLIST { """ stub: - def prefix = task.ext.prefix ?: id + args = args ?: '' + prefix = prefix ?: id def avail_mem = 3072 if (!task.memory) { log.info('[Picard BedToIntervalList] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') diff --git a/modules/nf-core/picard/collecthsmetrics/main.nf b/modules/nf-core/picard/collecthsmetrics/main.nf index c5b55d7a4..b26ff2bf1 100644 --- a/modules/nf-core/picard/collecthsmetrics/main.nf +++ b/modules/nf-core/picard/collecthsmetrics/main.nf @@ -18,7 +18,9 @@ process PICARD_COLLECTHSMETRICS { target_intervals: Set, fasta: Path, fai: Path, - reference_dict: Path + reference_dict: Path, + args: String?, + prefix: String? ): Record stage: @@ -35,8 +37,8 @@ process PICARD_COLLECTHSMETRICS { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id + args = args ?: '' + prefix = prefix ?: id def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" def avail_mem = 3072 @@ -85,7 +87,7 @@ process PICARD_COLLECTHSMETRICS { """ stub: - def prefix = task.ext.prefix ?: id + prefix = prefix ?: id """ touch ${prefix}.CollectHsMetrics.coverage_metrics diff --git a/modules/nf-core/picard/createsequencedictionary/main.nf b/modules/nf-core/picard/createsequencedictionary/main.nf index 7667833fb..f5b40eac0 100644 --- a/modules/nf-core/picard/createsequencedictionary/main.nf +++ b/modules/nf-core/picard/createsequencedictionary/main.nf @@ -10,7 +10,12 @@ process PICARD_CREATESEQUENCEDICTIONARY { : 'biocontainers/picard:3.3.0--hdfd78af_0'}" input: - (id: String, fasta: Path): Record + ( + id: String, + fasta: Path, + args: String?, + prefix: String? + ): Record output: record(id: id, reference_dict: file("*.dict")) @@ -22,8 +27,8 @@ process PICARD_CREATESEQUENCEDICTIONARY { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id + args = args ?: '' + prefix = prefix ?: id def avail_mem = 3072 if (!task.memory) { log.info('[Picard CreateSequenceDictionary] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') @@ -46,7 +51,8 @@ process PICARD_CREATESEQUENCEDICTIONARY { """ stub: - def prefix = task.ext.prefix ?: id + args = args ?: '' + prefix = prefix ?: id """ touch ${prefix}.dict diff --git a/modules/nf-core/picard/markduplicates/main.nf b/modules/nf-core/picard/markduplicates/main.nf index fab57da79..1fcf14a6f 100644 --- a/modules/nf-core/picard/markduplicates/main.nf +++ b/modules/nf-core/picard/markduplicates/main.nf @@ -14,7 +14,10 @@ process PICARD_MARKDUPLICATES { id: String, reads: Path, fasta: Path, - fai: Path + fai: Path, + args: String?, + prefix: String?, + suffix: String? ): Record output: @@ -33,9 +36,9 @@ process PICARD_MARKDUPLICATES { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id - def suffix = task.ext.suffix ?: "${reads.getExtension()}" + args = args ?: '' + prefix = prefix ?: id + suffix = suffix ?: "${reads.getExtension()}" def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" def avail_mem = 3072 if (!task.memory) { @@ -46,7 +49,7 @@ process PICARD_MARKDUPLICATES { } if ("${reads}" == "${prefix}.${suffix}") { - error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + error("Input and output names are the same, use \"prefix\" to disambiguate!") } """ @@ -66,10 +69,10 @@ process PICARD_MARKDUPLICATES { """ stub: - def prefix = task.ext.prefix ?: id - def suffix = task.ext.suffix ?: "${reads.getExtension()}" + prefix = prefix ?: id + suffix = suffix ?: "${reads.getExtension()}" if ("${reads}" == "${prefix}.${suffix}") { - error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + error("Input and output names are the same, use \"prefix\" to disambiguate!") } """ touch ${prefix}.${suffix} diff --git a/modules/nf-core/preseq/lcextrap/main.nf b/modules/nf-core/preseq/lcextrap/main.nf index 9c8c08d2b..383d9a51f 100644 --- a/modules/nf-core/preseq/lcextrap/main.nf +++ b/modules/nf-core/preseq/lcextrap/main.nf @@ -14,7 +14,9 @@ process PRESEQ_LCEXTRAP { ( id: String, single_end: Boolean, - bam: Path + bam: Path, + args: String?, + prefix: String? ): Record output: @@ -31,10 +33,10 @@ process PRESEQ_LCEXTRAP { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + args = args ?: '' args = task.attempt > 1 ? args.join(' -defects') : args // Disable testing for defects - def prefix = task.ext.prefix ?: id + prefix = prefix ?: id def paired_end = single_end ? '' : '-pe' """ preseq \\ @@ -52,7 +54,7 @@ process PRESEQ_LCEXTRAP { """ stub: - def prefix = task.ext.prefix ?: id + prefix = prefix ?: id """ touch ${prefix}.lc_extrap.txt touch ${prefix}.command.log diff --git a/modules/nf-core/qualimap/bamqc/main.nf b/modules/nf-core/qualimap/bamqc/main.nf index 690682125..31750beb5 100644 --- a/modules/nf-core/qualimap/bamqc/main.nf +++ b/modules/nf-core/qualimap/bamqc/main.nf @@ -14,9 +14,11 @@ process QUALIMAP_BAMQC { id: String, single_end: Boolean, strandedness: String?, - bam: Path + bam: Path, + gff: Path, + args: String?, + prefix: String? ): Record - gff: Path output: record(id: id, qualimap_bamqc: file("${prefix}")) @@ -28,8 +30,8 @@ process QUALIMAP_BAMQC { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - prefix = task.ext.prefix ?: id + args = args ?: '' + prefix = prefix ?: id def collect_pairs = single_end ? '' : '--collect-overlap-pairs' def memory = (task.memory.toMega() * 0.8).intValue() + 'M' @@ -61,7 +63,7 @@ process QUALIMAP_BAMQC { """ stub: - prefix = task.ext.suffix ? "${id}${task.ext.suffix}" : id + prefix = prefix ? "${id}${prefix}" : id """ mkdir -p ${prefix}/css mkdir ${prefix}/images_qualimapReport diff --git a/modules/nf-core/samtools/faidx/main.nf b/modules/nf-core/samtools/faidx/main.nf index 027ace3f3..cbcd3d121 100644 --- a/modules/nf-core/samtools/faidx/main.nf +++ b/modules/nf-core/samtools/faidx/main.nf @@ -10,9 +10,12 @@ process SAMTOOLS_FAIDX { : 'biocontainers/samtools:1.21--h50ea8bc_0'}" input: - fasta: Path - fai: Path? - get_sizes: Boolean + ( + fasta: Path, + fai: Path?, + get_sizes: Boolean, + args: String? + ): Record output: record( @@ -29,7 +32,7 @@ process SAMTOOLS_FAIDX { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + args = args ?: '' def get_sizes_command = get_sizes ? "cut -f 1,2 ${fasta}.fai > ${fasta}.sizes" : '' """ samtools \\ @@ -46,7 +49,7 @@ process SAMTOOLS_FAIDX { """ stub: - def match = (task.ext.args =~ /-o(?:utput)?\s(.*)\s?/).findAll() + def match = (args =~ /-o(?:utput)?\s(.*)\s?/).findAll() def fastacmd = match[0] ? "touch ${match[0][1]}" : '' def get_sizes_command = get_sizes ? "touch ${fasta}.sizes" : '' """ diff --git a/modules/nf-core/samtools/index/main.nf b/modules/nf-core/samtools/index/main.nf index 0701779ea..cd8876b27 100644 --- a/modules/nf-core/samtools/index/main.nf +++ b/modules/nf-core/samtools/index/main.nf @@ -10,7 +10,11 @@ process SAMTOOLS_INDEX { : 'biocontainers/samtools:1.21--h50ea8bc_0'}" input: - (id: String, input: Path): Record + ( + id: String, + input: Path, + args: String? + ): Record output: record( @@ -27,7 +31,7 @@ process SAMTOOLS_INDEX { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + args = args ?: '' """ samtools \\ index \\ @@ -42,7 +46,7 @@ process SAMTOOLS_INDEX { """ stub: - def args = task.ext.args ?: '' + args = args ?: '' def extension = input.getExtension() == 'cram' ? "crai" : args.contains("-c") ? "csi" : "bai" diff --git a/modules/nf-core/samtools/sort/main.nf b/modules/nf-core/samtools/sort/main.nf index c9ce00170..ddf05d954 100644 --- a/modules/nf-core/samtools/sort/main.nf +++ b/modules/nf-core/samtools/sort/main.nf @@ -13,7 +13,9 @@ process SAMTOOLS_SORT { ( id: String, bam: Path, - fasta: Path? + fasta: Path?, + args: String?, + prefix: String? ): Record output: @@ -32,8 +34,8 @@ process SAMTOOLS_SORT { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id + args = args ?: '' + prefix = prefix ?: id def extension = args.contains("--output-fmt sam") ? "sam" : args.contains("--output-fmt cram") @@ -41,7 +43,7 @@ process SAMTOOLS_SORT { : "bam" def reference = fasta ? "--reference ${fasta}" : "" if ("${bam}" == "${prefix}.bam") { - error("Input and output names are the same, use \"task.ext.prefix\" to disambiguate!") + error("Input and output names are the same, use \"prefix\" to disambiguate!") } """ @@ -63,8 +65,8 @@ process SAMTOOLS_SORT { """ stub: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id + args = args ?: '' + prefix = prefix ?: id def extension = args.contains("--output-fmt sam") ? "sam" : args.contains("--output-fmt cram") diff --git a/modules/nf-core/trimgalore/main.nf b/modules/nf-core/trimgalore/main.nf index f5574aa6f..a31966da5 100644 --- a/modules/nf-core/trimgalore/main.nf +++ b/modules/nf-core/trimgalore/main.nf @@ -13,7 +13,9 @@ process TRIMGALORE { ( id: String, single_end: Boolean, - reads: List + reads: List, + args: String?, + prefix: String? ): Record output: @@ -34,7 +36,7 @@ process TRIMGALORE { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + args = args ?: '' // Calculate number of --cores for TrimGalore based on value of task.cpus // See: https://github.com/FelixKrueger/TrimGalore/blob/master/CHANGELOG.md#version-060-release-on-1-mar-2019 // See: https://github.com/nf-core/atacseq/pull/65 @@ -53,7 +55,7 @@ process TRIMGALORE { } // Added soft-links to original fastqs for consistent naming in MultiQC - def prefix = task.ext.prefix ?: id + prefix = prefix ?: id if (single_end) { def args_list = args.split("\\s(?=--)").toList() args_list.removeAll { it.toLowerCase().contains('_r2 ') } @@ -95,7 +97,7 @@ process TRIMGALORE { } stub: - def prefix = task.ext.prefix ?: id + prefix = prefix ?: id if (single_end) { output_command = "echo '' | gzip > ${prefix}_trimmed.fq.gz ;" output_command += "touch ${prefix}.fastq.gz_trimming_report.txt" diff --git a/subworkflows/local/targeted_sequencing/main.nf b/subworkflows/local/targeted_sequencing/main.nf index f1e7c3720..65852a92d 100644 --- a/subworkflows/local/targeted_sequencing/main.nf +++ b/subworkflows/local/targeted_sequencing/main.nf @@ -28,7 +28,14 @@ workflow TARGETED_SEQUENCING { * Intersect bedGraph files with target regions * Ensure ch_bedgraph contains the bedGraph file(s) in an array and split into individual bedGraphs */ - ch_intersect_inputs = ch_inputs.map { r -> record(id: r.id, intervals1: r.bedgraph) } + ch_intersect_inputs = ch_inputs.map { r -> + record( + id: r.id, + intervals1: r.bedgraph, + prefix: r.bedgraph.baseName, + suffix: 'targeted.bedGraph' + ) + } ch_intersect_inputs = combineWith(ch_intersect_inputs, intervals2: val_target_regions) ch_results = BEDTOOLS_INTERSECT( ch_intersect_inputs ) @@ -62,7 +69,8 @@ workflow TARGETED_SEQUENCING { target_intervals: val_intervallist, fasta: val_fasta, fai: val_fasta_index, - reference_dict: val_reference_dict + reference_dict: val_reference_dict, + args: "--MINIMUM_MAPPING_QUALITY 20 --COVERAGE_CAP 1000 --NEAR_DISTANCE 500" ) ch_picard_hsmetrics = PICARD_COLLECTHSMETRICS( ch_picard_inputs ) diff --git a/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf b/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf index c4ee7d979..c0c151d4c 100644 --- a/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf +++ b/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf @@ -4,6 +4,8 @@ include { BISMARK_GENOMEPREPARATION } from '../../../modules/nf-core/bismark/gen include { BWAMETH_INDEX } from '../../../modules/nf-core/bwameth/index/main' include { SAMTOOLS_FAIDX } from '../../../modules/nf-core/samtools/faidx/main' +include { combineWith } from '../../../utils/ops.nf' + def isGzipped(file: Path) -> Boolean { return file.name.endsWith('.gz') } @@ -44,7 +46,8 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { ? UNTAR( bismark_index ) : channel.value(bismark_index) } else { - val_bismark_index = BISMARK_GENOMEPREPARATION( val_fasta ) + val_bismark_inputs = val_fasta.map { fa -> record(fasta: fa, args: bismarkGenomePreparationArgs()) } + val_bismark_index = BISMARK_GENOMEPREPARATION( val_bismark_inputs ) } } @@ -71,7 +74,8 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { if (fasta_index) { val_fasta_index = channel.value(fasta_index) } else { - val_fasta_index = SAMTOOLS_FAIDX( val_fasta, null, false ).map { r -> r.fai } + val_faidx_inputs = val_fasta.map { fa -> record(fasta: fa, get_sizes: false) } + val_fasta_index = SAMTOOLS_FAIDX( val_faidx_inputs ).map { r -> r.fai } } } @@ -81,3 +85,11 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { bismark_index : Value? = val_bismark_index bwameth_index : Value? = val_bwameth_index } + + +def bismarkGenomePreparationArgs() { + [ + params.aligner == 'bismark_hisat' ? ' --hisat2' : ' --bowtie2', + params.slamseq ? ' --slam' : '' + ].join(' ').trim() +} diff --git a/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf b/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf index ea54e04f9..3ff96ae9c 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf +++ b/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf @@ -25,6 +25,9 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { * Align with bismark */ ch_alignment_inputs = combineWith( ch_reads, fasta: val_fasta, bismark_index: val_bismark_index ) + ch_alignment_inputs = ch_alignment_inputs.map { r -> + r + record(args: bismarkAlignArgs(r)) + } ch_alignment = BISMARK_ALIGN( ch_alignment_inputs ) if (!skip_deduplication) { @@ -40,7 +43,11 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { /* * MODULE: Run samtools sort on aligned or deduplicated bam */ - ch_bam = SAMTOOLS_SORT( ch_alignment_dedup ) + ch_samtools_sort_inputs = ch_alignment_dedup.map { r -> + def prefix = params.skip_deduplication ? "${r.id}.sorted" : "${r.id}.deduplicated.sorted" + r + record(prefix: prefix) + } + ch_bam = SAMTOOLS_SORT( ch_samtools_sort_inputs ) /* * MODULE: Run samtools index on aligned or deduplicated bam @@ -53,13 +60,21 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { * Run bismark_methylation_extractor */ ch_methylation_inputs = combineWith(ch_alignment_dedup, bismark_index: val_bismark_index) + ch_methylation_inputs = ch_methylation_inputs.map { r -> + r + record(args: bismarkMethylationExtractorArgs(r)) + } ch_methylation = BISMARK_METHYLATIONEXTRACTOR( ch_methylation_inputs ) /* * Run bismark coverage2cytosine */ if (cytosine_report) { - ch_coverage2cytosine_inputs = combineWith(ch_methylation, fasta: val_fasta, bismark_index: val_bismark_index) + ch_coverage2cytosine_inputs = combineWith( + ch_methylation, + fasta: val_fasta, + bismark_index: val_bismark_index, + args: params.nomeseq ? '--nome-seq' : '' + ) ch_coverage2cytosine = BISMARK_COVERAGE2CYTOSINE( ch_coverage2cytosine_inputs ) } else { ch_coverage2cytosine = channel.empty() @@ -118,6 +133,39 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { } +def bismarkAlignArgs(r: Record) { + [ + params.aligner == 'bismark_hisat' ? ' --hisat2' : ' --bowtie2', + params.aligner == 'bismark_hisat' && params.known_splices ? " --known-splicesite-infile <(hisat2_extract_splice_sites.py ${params.known_splices})" : '', + params.pbat ? ' --pbat' : '', + params.single_cell || params.non_directional || params.zymo ? ' --non_directional' : '', + params.unmapped ? ' --unmapped' : '', + params.relax_mismatches ? " --score_min L,0,-${params.num_mismatches}" : '', + params.local_alignment ? " --local" : '', + !r.single_end && params.minins ? " --minins ${params.minins}" : '', + r.single_end ? '' : ( + params.maxins ? " --maxins ${params.maxins}" : ( + params.em_seq ? " --maxins 1000" : '' + ) + ) + ].join(' ').trim() +} + + +def bismarkMethylationExtractorArgs(r: Record) { + [ + params.comprehensive ? ' --comprehensive' : '', + params.meth_cutoff ? " --cutoff ${params.meth_cutoff}" : '', + params.nomeseq ? '--CX' : '', + params.ignore_r1 > 0 ? "--ignore ${params.ignore_r1}" : '', + params.ignore_3prime_r1 > 0 ? "--ignore_3prime ${params.ignore_3prime_r1}" : '', + r.single_end ? '' : (params.no_overlap ? ' --no_overlap' : '--include_overlap'), + r.single_end ? '' : (params.ignore_r2 > 0 ? "--ignore_r2 ${params.ignore_r2}" : ""), + r.single_end ? '' : (params.ignore_3prime_r2 > 0 ? "--ignore_3prime_r2 ${params.ignore_3prime_r2}": "") + ].join(' ').trim() +} + + record BismarkResult { id : String single_end : Boolean diff --git a/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf b/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf index e1547ed20..be65a4295 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf +++ b/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf @@ -33,6 +33,7 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { /* * Align with parabricks GPU enabled fq2bammeth implementation of bwameth */ + ch_bwameth_inputs = combineWith(ch_bwameth_inputs, args: '--low-memory') ch_alignment = PARABRICKS_FQ2BAMMETH ( ch_bwameth_inputs ) } else { /* @@ -44,7 +45,11 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { /* * Sort raw output BAM */ - ch_alignment = SAMTOOLS_SORT( ch_alignment ) + ch_samtools_sort_inputs = ch_alignment.map { r -> + def prefix = params.skip_deduplication ? "${r.id}.sorted" : "${r.id}.deduplicated.sorted" + r + record(prefix: prefix) + } + ch_alignment = SAMTOOLS_SORT( ch_samtools_sort_inputs ) /* * Run samtools index on alignment @@ -70,6 +75,11 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { /* * Run Picard MarkDuplicates */ + ch_picard_inputs = ch_alignment_fasta.map { r -> + def args = "--ASSUME_SORTED true --REMOVE_DUPLICATES false --VALIDATION_STRINGENCY LENIENT --PROGRAM_RECORD_ID 'null' --TMP_DIR tmp" + def prefix = "${r.id}.markdup.sorted" + r + record(args: args, prefix: prefix) + } ch_picard = PICARD_MARKDUPLICATES( ch_alignment_fasta ) /* * Run samtools index on deduplicated alignment @@ -85,9 +95,11 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { * Extract per-base methylation and plot methylation bias */ - ch_methydackel_extract = METHYLDACKEL_EXTRACT ( ch_alignment_fasta ) + ch_methydackel_extract_inputs = combineWith(ch_alignment_fasta, args: methyldackelExtractArgs()) + ch_methydackel_extract = METHYLDACKEL_EXTRACT ( ch_methydackel_extract_inputs ) - ch_methydackel_mbias = METHYLDACKEL_MBIAS ( ch_alignment_fasta ) + ch_methydackel_mbias_inputs = combineWith(ch_alignment_fasta, args: methyldackelMbiasArgs()) + ch_methydackel_mbias = METHYLDACKEL_MBIAS ( ch_methydackel_mbias_inputs ) ch_results = joinById(ch_alignment, ch_samtools_flagstat) ch_results = joinById(ch_results, ch_samtools_stats) @@ -111,6 +123,25 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { } +def methyldackelExtractArgs() { + [ + params.all_contexts ? ' --CHG --CHH' : '', + params.merge_context ? ' --mergeContext' : '', + params.ignore_flags ? " --ignoreFlags" : '', + params.methyl_kit ? " --methylKit" : '', + params.min_depth > 0 ? " --minDepth ${params.min_depth}" : '' + ].join(" ").trim() +} + + +def methyldackelMbiasArgs() { + [ + params.all_contexts ? ' --CHG --CHH' : '', + params.ignore_flags ? " --ignoreFlags" : '' + ].join(" ").trim() +} + + record BwamethResult { id : String single_end : Boolean diff --git a/workflows/methylseq/main.nf b/workflows/methylseq/main.nf index e91990d54..6ef200179 100644 --- a/workflows/methylseq/main.nf +++ b/workflows/methylseq/main.nf @@ -20,7 +20,7 @@ include { methodsDescriptionText } from '../../subworkflows/local/utils_nfco include { validateInputSamplesheet } from '../../subworkflows/local/utils_nfcore_methylseq_pipeline' include { Sample } from '../../utils/types.nf' -include { joinById } from '../../utils/ops.nf' +include { combineWith ; joinById } from '../../utils/ops.nf' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -65,7 +65,8 @@ workflow METHYLSEQ { // MODULE: Run TrimGalore! // if (!params.skip_trimming) { - ch_trimmed_fastq = TRIMGALORE( ch_fastq ) + ch_trimgalore_inputs = ch_fastq.map { r -> r + record(args: trimgaloreArgs(r, params)) } + ch_trimmed_fastq = TRIMGALORE( ch_trimgalore_inputs ) ch_reads = ch_trimmed_fastq.map { r -> r + record(reads: r.trim_reads) } } else { ch_trimmed_fastq = channel.empty() @@ -125,10 +126,12 @@ workflow METHYLSEQ { // skipped by default. to use run with `--run_qualimap` param. // if(params.run_qualimap) { - ch_qualimap = QUALIMAP_BAMQC ( + ch_qualimap_inputs = combineWith( ch_alignment, - params.bamqc_regions_file ? file( params.bamqc_regions_file, checkIfExists: true ) : null + gff: params.bamqc_regions_file ? file( params.bamqc_regions_file, checkIfExists: true ) : null, + args: qualimapArgs(params) ) + ch_qualimap = QUALIMAP_BAMQC ( ch_qualimap_inputs ) ch_results = joinById(ch_results, ch_qualimap) } else { ch_qualimap = channel.empty() @@ -164,7 +167,8 @@ workflow METHYLSEQ { // skipped by default. to use run with `--run_preseq` param. // if(params.run_preseq) { - ch_preseq = PRESEQ_LCEXTRAP (ch_alignment) + ch_preseq_inputs = combineWith(ch_alignment, args: " -verbose -bam") + ch_preseq = PRESEQ_LCEXTRAP (ch_preseq_inputs) ch_results = joinById(ch_results, ch_preseq) } else { ch_preseq = channel.empty() @@ -223,14 +227,19 @@ workflow METHYLSEQ { ch_multiqc_files = ch_multiqc_files.mix(ch_fastqc.map { r -> r.fastqc_zip }) } - val_multiqc_report = MULTIQC ( - ch_multiqc_files.flatMap().collect().map { v -> v.toSet() }, - multiqc_config, - multiqc_custom_config, - multiqc_logo, - null, - null - ).map { r -> r.report } + val_multiqc_inputs = ch_multiqc_files + .flatMap() + .collect() + .map { multiqc_files -> + record( + multiqc_files: multiqc_files.toSet(), + multiqc_config: multiqc_config, + extra_multiqc_config: multiqc_custom_config, + multiqc_logo: multiqc_logo, + args: multiqcArgs(params) + ) + } + val_multiqc_report = MULTIQC ( val_multiqc_inputs ).map { r -> r.report } } else { val_multiqc_report = channel.empty() } @@ -243,6 +252,79 @@ workflow METHYLSEQ { multiqc_report : Value = val_multiqc_report } +def trimgaloreArgs(r: Record, params: Record) { + [ + // Static args + '--fastqc', + + // Special flags + params.rrbs ? '--rrbs' : '', + params.nextseq_trim > 0 ? "--nextseq ${params.nextseq_trim}" : '', + params.length_trim ? "--length ${params.length_trim}" : '', + + // Trimming - R1 + params.clip_r1 > 0 ? "--clip_r1 ${params.clip_r1}" : ( + params.skip_trimming_presets ? '' : ( + params.pbat ? "--clip_r1 8" : ( + params.single_cell ? "--clip_r1 6" : ( + (params.accel || params.zymo || params.em_seq) ? "--clip_r1 10" : '' + ) + ) + ) + ), + + // Trimming - R2 + r.single_end ? '' : ( + params.clip_r2 > 0 ? "--clip_r2 ${params.clip_r2}" : ( + params.skip_trimming_presets ? '' : ( + params.pbat ? "--clip_r2 8" : ( + params.single_cell ? "--clip_r2 6" : ( + (params.zymo || params.em_seq) ? "--clip_r2 10" : ( + params.accel ? "--clip_r2 15" : '' + ) + ) + ) + ) + ) + ), + + // Trimming - 3' R1 + params.three_prime_clip_r1 > 0 ? "--three_prime_clip_r1 ${params.three_prime_clip_r1}" : ( + params.skip_trimming_presets ? '' : ( + params.pbat ? "--three_prime_clip_r1 8" : ( + params.single_cell ? "--three_prime_clip_r1 6" : ( + (params.accel || params.zymo || params.em_seq) ? "--three_prime_clip_r1 10" : '' + ) + ) + ) + ), + + // Trimming - 3' R2 + r.single_end ? '' : ( + params.three_prime_clip_r2 > 0 ? "--three_prime_clip_r2 ${params.three_prime_clip_r2}" : ( + params.skip_trimming_presets ? '' : ( + params.pbat ? "--three_prime_clip_r2 8" : ( + params.single_cell ? "--three_prime_clip_r2 6" : ( + (params.accel || params.zymo || params.em_seq) ? "--three_prime_clip_r2 10" : '' + ) + ) + ) + ) + ), + ].join(' ').trim() +} + +def qualimapArgs(params: Record) { + [ + params.genome.startsWith('GRCh') ? '-gd HUMAN' : '', + params.genome.startsWith('GRCm') ? '-gd MOUSE' : '' + ].join(" ").trim() +} + +def multiqcArgs(params: Record) { + params.multiqc_title ? "--title \"$params.multiqc_title\"" : '' +} + record MethylseqParams { skip_fastqc: Boolean skip_trimming: Boolean diff --git a/workflows/methylseq/nextflow.config b/workflows/methylseq/nextflow.config index 67d77b356..64e60e04b 100644 --- a/workflows/methylseq/nextflow.config +++ b/workflows/methylseq/nextflow.config @@ -1,12 +1,2 @@ -// module configs -includeConfig "../../conf/modules/fastqc.config" -includeConfig "../../conf/modules/trimgalore.config" -includeConfig "../../conf/modules/multiqc.config" -includeConfig "../../conf/modules/preseq_lcextrap.config" -includeConfig "../../conf/modules/qualimap_bamqc.config" - // subworkflow configs -includeConfig "../../conf/subworkflows/fasta_index_bismark_bwameth.config" -includeConfig "../../conf/subworkflows/fastq_align_dedup_bismark.config" includeConfig "../../conf/subworkflows/fastq_align_dedup_bwameth.config" -includeConfig "../../conf/subworkflows/targeted_sequencing.config" From b6c98b03360eb0da395d13faec98766334c3fbce Mon Sep 17 00:00:00 2001 From: Ben Sherman Date: Mon, 16 Feb 2026 09:28:25 -0600 Subject: [PATCH 5/6] wip --- main.nf | 48 ++++++++++++++----- .../utils_nfcore_methylseq_pipeline/main.nf | 2 +- .../fasta_index_bismark_bwameth/main.nf | 15 +++--- 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/main.nf b/main.nf index 9c3dc2cbd..5c0d11be5 100644 --- a/main.nf +++ b/main.nf @@ -75,16 +75,16 @@ params { genome : String? // Path to FASTA genome file - fasta : Path? = getGenomeAttribute('fasta') + fasta : Path? // Path to Fasta index file. - fasta_index : Path? = getGenomeAttribute('fasta_index') + fasta_index : Path? // Path to a directory containing a Bismark reference index. - bismark_index : Path? = params.aligner == 'bismark_hisat' ? getGenomeAttribute('bismark_hisat2') : getGenomeAttribute('bismark') + bismark_index : Path? // bwameth index filename base - bwameth_index : Path? = getGenomeAttribute('bwameth') + bwameth_index : Path? /// Alignment options @@ -280,21 +280,26 @@ workflow NFCORE_METHYLSEQ { take: ch_samples: Channel - params: MethylseqParams + params_index: IndexParams + params_methylseq: MethylseqParams main: // // SUBWORKFLOW: Prepare any required reference genome indices // + fasta = params_index.fasta ?: file(getGenomeAttribute('fasta', params)) + fasta_index = params_index.fasta_index ?: file(getGenomeAttribute('fasta_index', params)) + bismark_index = params_index.bismark_index ?: bismarkIndex(params_methylseq.aligner) + bwameth_index = params_index.bwameth_index ?: (getGenomeAttribute('bwameth', params) ? file(getGenomeAttribute('bwameth', params)) : null) + FASTA_INDEX_BISMARK_BWAMETH( - params.fasta, - params.fasta_index, - params.bismark_index, - params.bwameth_index, - params.aligner, - params.collecthsmetrics, - params.use_mem2 + fasta, + fasta_index, + bismark_index, + bwameth_index, + params_index.use_mem2, + params_methylseq ) // @@ -307,7 +312,7 @@ workflow NFCORE_METHYLSEQ { FASTA_INDEX_BISMARK_BWAMETH.out.fasta_index, FASTA_INDEX_BISMARK_BWAMETH.out.bismark_index, FASTA_INDEX_BISMARK_BWAMETH.out.bwameth_index, - params + params_methylseq ) emit: @@ -321,6 +326,22 @@ workflow NFCORE_METHYLSEQ { multiqc_report = METHYLSEQ.out.multiqc_report } + +record IndexParams { + fasta: Path? + fasta_index: Path? + bismark_index: Path? + bwameth_index: Path? + use_mem2: Boolean +} + +def bismarkIndex(aligner: String) -> Path? { + def indexPath = aligner == 'bismark_hisat' + ? getGenomeAttribute('bismark_hisat2', params) + : getGenomeAttribute('bismark', params) + return indexPath ? file(indexPath) : null +} + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN MAIN WORKFLOW @@ -347,6 +368,7 @@ workflow { // NFCORE_METHYLSEQ ( PIPELINE_INITIALISATION.out.samplesheet, + params, params ) // diff --git a/subworkflows/local/utils_nfcore_methylseq_pipeline/main.nf b/subworkflows/local/utils_nfcore_methylseq_pipeline/main.nf index bd1b23ce9..929ebf13d 100644 --- a/subworkflows/local/utils_nfcore_methylseq_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_methylseq_pipeline/main.nf @@ -170,7 +170,7 @@ def validateInputSamplesheet(samples) { // // Get attribute from genome config file e.g. fasta // -def getGenomeAttribute(attribute) { +def getGenomeAttribute(attribute: String, params: Record) -> String? { if (params.genomes && params.genome && params.genomes.containsKey(params.genome)) { if (params.genomes[ params.genome ].containsKey(attribute)) { return params.genomes[ params.genome ][ attribute ] diff --git a/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf b/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf index c0c151d4c..b245cd91b 100644 --- a/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf +++ b/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf @@ -6,6 +6,8 @@ include { SAMTOOLS_FAIDX } from '../../../modules/nf-core/samtools/fa include { combineWith } from '../../../utils/ops.nf' +include { MethylseqParams } from '../../../workflows/methylseq/main' + def isGzipped(file: Path) -> Boolean { return file.name.endsWith('.gz') } @@ -17,9 +19,8 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { fasta_index: Path? bismark_index: Path? bwameth_index: Path? - aligner: String // bismark, bismark_hisat or bwameth - collecthsmetrics: Boolean // whether to run picard collecthsmetrics use_mem2: Boolean // generate mem2 index if no index provided, and bwameth is selected + params: MethylseqParams main: @@ -36,7 +37,7 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { } // Aligner: bismark or bismark_hisat - if( aligner =~ /bismark/ ){ + if( params.aligner =~ /bismark/ ){ /* * Generate bismark index if not supplied */ @@ -46,13 +47,13 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { ? UNTAR( bismark_index ) : channel.value(bismark_index) } else { - val_bismark_inputs = val_fasta.map { fa -> record(fasta: fa, args: bismarkGenomePreparationArgs()) } + val_bismark_inputs = val_fasta.map { fa -> record(fasta: fa, args: bismarkGenomePreparationArgs(params)) } val_bismark_index = BISMARK_GENOMEPREPARATION( val_bismark_inputs ) } } // Aligner: bwameth - else if ( aligner == 'bwameth' ){ + else if ( params.aligner == 'bwameth' ){ /* * Generate bwameth index if not supplied */ @@ -69,7 +70,7 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { /* * Generate fasta index if not supplied for bwameth workflow or picard collecthsmetrics tool */ - if (aligner == 'bwameth' || collecthsmetrics) { + if (params.aligner == 'bwameth' || params.collecthsmetrics) { // already exising fasta index if (fasta_index) { val_fasta_index = channel.value(fasta_index) @@ -87,7 +88,7 @@ workflow FASTA_INDEX_BISMARK_BWAMETH { } -def bismarkGenomePreparationArgs() { +def bismarkGenomePreparationArgs(params: Record) { [ params.aligner == 'bismark_hisat' ? ' --hisat2' : ' --bowtie2', params.slamseq ? ' --slam' : '' From 1e1678fa4438fc07cfd26a71451f0cb622b4387e Mon Sep 17 00:00:00 2001 From: Ben Sherman Date: Tue, 17 Mar 2026 13:38:27 -0500 Subject: [PATCH 6/6] Preview build 2 --- main.nf | 127 +++++++++--------- modules/nf-core/bedtools/intersect/main.nf | 40 +++--- modules/nf-core/bismark/align/main.nf | 36 ++--- .../nf-core/bismark/coverage2cytosine/main.nf | 32 ++--- modules/nf-core/bismark/deduplicate/main.nf | 28 ++-- .../nf-core/bismark/genomepreparation/main.nf | 16 +-- .../bismark/methylationextractor/main.nf | 34 ++--- modules/nf-core/bismark/report/main.nf | 26 ++-- modules/nf-core/bismark/summary/main.nf | 14 +- modules/nf-core/bwameth/align/main.nf | 38 +++--- modules/nf-core/bwameth/index/main.nf | 2 +- modules/nf-core/cat/fastq/main.nf | 28 ++-- modules/nf-core/fastqc/main.nf | 22 +-- modules/nf-core/methyldackel/extract/main.nf | 28 ++-- modules/nf-core/methyldackel/mbias/main.nf | 24 ++-- modules/nf-core/multiqc/main.nf | 34 ++--- modules/nf-core/parabricks/fq2bammeth/main.nf | 44 +++--- .../nf-core/picard/bedtointervallist/main.nf | 38 +++--- .../nf-core/picard/collecthsmetrics/main.nf | 56 ++++---- .../picard/createsequencedictionary/main.nf | 24 ++-- modules/nf-core/picard/markduplicates/main.nf | 38 +++--- modules/nf-core/preseq/lcextrap/main.nf | 26 ++-- modules/nf-core/qualimap/bamqc/main.nf | 36 ++--- modules/nf-core/samtools/faidx/main.nf | 28 ++-- modules/nf-core/samtools/flagstat/main.nf | 18 +-- modules/nf-core/samtools/index/main.nf | 22 +-- modules/nf-core/samtools/sort/main.nf | 30 ++--- modules/nf-core/samtools/stats/main.nf | 22 +-- modules/nf-core/trimgalore/main.nf | 36 ++--- .../local/targeted_sequencing/main.nf | 31 ++--- .../utils_nfcore_methylseq_pipeline/main.nf | 13 +- .../fasta_index_bismark_bwameth/main.nf | 4 +- .../nf-core/fastq_align_dedup_bismark/main.nf | 55 ++++---- .../nf-core/fastq_align_dedup_bwameth/main.nf | 59 ++++---- .../nf-core/utils_nfcore_pipeline/main.nf | 2 + .../tests/nextflow.config | 2 +- utils/ops.nf | 27 ---- workflows/methylseq/main.nf | 102 +++++++------- 38 files changed, 615 insertions(+), 627 deletions(-) delete mode 100644 utils/ops.nf diff --git a/main.nf b/main.nf index 5c0d11be5..1f9d8a1f3 100644 --- a/main.nf +++ b/main.nf @@ -15,6 +15,8 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +nextflow.preview.types = true + include { FASTA_INDEX_BISMARK_BWAMETH } from './subworkflows/nf-core/fasta_index_bismark_bwameth/main' include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_methylseq_pipeline' include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_methylseq_pipeline' @@ -23,6 +25,7 @@ include { METHYLSEQ } from './workflows/methylseq/' include { Sample } from './utils/types.nf' include { MethylseqParams } from './workflows/methylseq/' +include { MethylseqResult } from './workflows/methylseq/' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -293,7 +296,7 @@ workflow NFCORE_METHYLSEQ { bismark_index = params_index.bismark_index ?: bismarkIndex(params_methylseq.aligner) bwameth_index = params_index.bwameth_index ?: (getGenomeAttribute('bwameth', params) ? file(getGenomeAttribute('bwameth', params)) : null) - FASTA_INDEX_BISMARK_BWAMETH( + indices = FASTA_INDEX_BISMARK_BWAMETH( fasta, fasta_index, bismark_index, @@ -306,24 +309,24 @@ workflow NFCORE_METHYLSEQ { // WORKFLOW: Run pipeline // - METHYLSEQ ( + methylseq = METHYLSEQ ( ch_samples, - FASTA_INDEX_BISMARK_BWAMETH.out.fasta, - FASTA_INDEX_BISMARK_BWAMETH.out.fasta_index, - FASTA_INDEX_BISMARK_BWAMETH.out.bismark_index, - FASTA_INDEX_BISMARK_BWAMETH.out.bwameth_index, + indices.fasta, + indices.fasta_index, + indices.bismark_index, + indices.bwameth_index, params_methylseq ) emit: - fasta_index = FASTA_INDEX_BISMARK_BWAMETH.out.fasta_index - bismark_index = FASTA_INDEX_BISMARK_BWAMETH.out.bismark_index - bwameth_index = FASTA_INDEX_BISMARK_BWAMETH.out.bwameth_index - results = METHYLSEQ.out.results - bismark_summary = METHYLSEQ.out.bismark_summary - reference_dict = METHYLSEQ.out.reference_dict - intervallist = METHYLSEQ.out.intervallist - multiqc_report = METHYLSEQ.out.multiqc_report + fasta_index = indices.fasta_index + bismark_index = indices.bismark_index + bwameth_index = indices.bwameth_index + results = methylseq.results + bismark_summary = methylseq.bismark_summary + reference_dict = methylseq.reference_dict + intervallist = methylseq.intervallist + multiqc_report = methylseq.multiqc_report } @@ -354,7 +357,7 @@ workflow { // // SUBWORKFLOW: Run initialisation tasks // - PIPELINE_INITIALISATION ( + ch_samples = PIPELINE_INITIALISATION ( params.input, params.version, params.validate_params, @@ -366,8 +369,8 @@ workflow { // // WORKFLOW: Run main workflow // - NFCORE_METHYLSEQ ( - PIPELINE_INITIALISATION.out.samplesheet, + methylseq = NFCORE_METHYLSEQ ( + ch_samples, params, params ) @@ -381,94 +384,94 @@ workflow { params.outdir, params.monochrome_logs, params.hook_url, - NFCORE_METHYLSEQ.out.multiqc_report + methylseq.multiqc_report ) publish: - fasta_index = NFCORE_METHYLSEQ.out.fasta_index - bismark_index = NFCORE_METHYLSEQ.out.bismark_index - bwameth_index = NFCORE_METHYLSEQ.out.bwameth_index - samples = NFCORE_METHYLSEQ.out.results - bismark_summary = NFCORE_METHYLSEQ.out.bismark_summary - reference_dict = NFCORE_METHYLSEQ.out.reference_dict - intervallist = NFCORE_METHYLSEQ.out.intervallist - multiqc_report = NFCORE_METHYLSEQ.out.multiqc_report + fasta_index = methylseq.fasta_index + bismark_index = methylseq.bismark_index + bwameth_index = methylseq.bwameth_index + samples = methylseq.results + bismark_summary = methylseq.bismark_summary + reference_dict = methylseq.reference_dict + intervallist = methylseq.intervallist + multiqc_report = methylseq.multiqc_report } output { - fasta_index { + fasta_index: Path { path "${params.aligner}/reference_genome" enabled params.save_reference } - bismark_index { + bismark_index: Path { path "${params.aligner}/reference_genome" enabled params.save_reference } - bwameth_index { + bwameth_index: Path { path "${params.aligner}/reference_genome" enabled params.save_reference } - samples { + samples: Channel { path { r -> - r.fastqc_html >> "fastqc" - r.fastqc_zip >> "fastqc/zips" + r.fastqc_html >> "fastqc/" + r.fastqc_zip >> "fastqc/zips/" - r.trim_reads >> (params.save_trimmed ? "trimgalore" : null) - r.trim_log >> "trimgalore/logs" - r.trim_unpaired >> (params.save_trimmed ? "trimgalore" : null) - r.trim_html >> "trimgalore/fastqc" - r.trim_zip >> "trimgalore/fastqc/zips" + r.trim_reads >> (params.save_trimmed ? "trimgalore/" : null) + r.trim_log >> "trimgalore/logs/" + r.trim_unpaired >> (params.save_trimmed ? "trimgalore/" : null) + r.trim_html >> "trimgalore/fastqc/" + r.trim_zip >> "trimgalore/fastqc/zips/" - r.bam >> (params.save_align_intermeds ? "${params.aligner}/alignments" : null) + r.bam >> (params.save_align_intermeds ? "${params.aligner}/alignments/" : null) r.bai >> (params.skip_deduplication ? "${params.aligner}/alignments/" : "${params.aligner}/deduplicated/") - r.align_report >> "${params.aligner}/alignments/logs" - r.unmapped >> "${params.aligner}/alignments/unmapped" - r.dedup_report >> "${params.aligner}/deduplicated/logs" - r.coverage2cytosine_coverage >> "bismark/coverage2cytosine/coverage" - r.coverage2cytosine_report >> "bismark/coverage2cytosine/reports" - r.coverage2cytosine_summary >> "bismark/coverage2cytosine/summaries" - r.methylation_bedgraph >> "${params.aligner}/methylation_calls/bedGraph" - r.methylation_calls >> "${params.aligner}/methylation_calls/methylation_calls" - r.methylation_coverage >> "${params.aligner}/methylation_calls/methylation_coverage" - r.methylation_report >> "${params.aligner}/methylation_calls/splitting_report" - r.methylation_mbias >> "${params.aligner}/methylation_calls/mbias" - r.bismark_report >> "${params.aligner}/reports" + r.align_report >> "${params.aligner}/alignments/logs/" + r.unmapped >> "${params.aligner}/alignments/unmapped/" + r.dedup_report >> "${params.aligner}/deduplicated/logs/" + r.coverage2cytosine_coverage >> "bismark/coverage2cytosine/coverage/" + r.coverage2cytosine_report >> "bismark/coverage2cytosine/reports/" + r.coverage2cytosine_summary >> "bismark/coverage2cytosine/summaries/" + r.methylation_bedgraph >> "${params.aligner}/methylation_calls/bedGraph/" + r.methylation_calls >> "${params.aligner}/methylation_calls/methylation_calls/" + r.methylation_coverage >> "${params.aligner}/methylation_calls/methylation_coverage/" + r.methylation_report >> "${params.aligner}/methylation_calls/splitting_report/" + r.methylation_mbias >> "${params.aligner}/methylation_calls/mbias/" + r.bismark_report >> "${params.aligner}/reports/" r.samtools_flagstat >> "${params.aligner}/alignments/samtools_stats/" r.samtools_stats >> "${params.aligner}/alignments/samtools_stats/" - r.methydackel_extract_bedgraph >> "methyldackel" - r.methydackel_extract_methylkit >> "methyldackel" - r.methyldackel_mbias >> "methyldackel/mbias" - r.picard_metrics >> "${params.aligner}/deduplicated/picard_metrics" + r.methydackel_extract_bedgraph >> "methyldackel/" + r.methydackel_extract_methylkit >> "methyldackel/" + r.methyldackel_mbias >> "methyldackel/mbias/" + r.picard_metrics >> "${params.aligner}/deduplicated/picard_metrics/" r.qualimap_bamqc >> "${params.aligner}/qualimap/bamqc/" - r.bedgraph_intersect >> (params.aligner == 'bismark' ? "bismark/methylation_calls/bedGraph" : "methyldackel") - r.picard_hsmetrics >> "enrichment_metrics" + r.bedgraph_intersect >> (params.aligner == 'bismark' ? "bismark/methylation_calls/bedGraph/" : "methyldackel/") + r.picard_hsmetrics >> "enrichment_metrics/" - r.lc_extrap >> "${params.aligner}/preseq" - r.lc_log >> "${params.aligner}/preseq/log" + r.lc_extrap >> "${params.aligner}/preseq/" + r.lc_log >> "${params.aligner}/preseq/log/" } } - bismark_summary { + bismark_summary: Set { path "${params.aligner}/summary" } - reference_dict { + reference_dict: Record { path "${params.aligner}/reference_genome" enabled params.save_reference } - intervallist { + intervallist: Record { path "enrichment_metrics" } - multiqc_report { + multiqc_report: Path { path "multiqc/${params.aligner}" } } diff --git a/modules/nf-core/bedtools/intersect/main.nf b/modules/nf-core/bedtools/intersect/main.nf index 95a457b88..8ac53fb05 100644 --- a/modules/nf-core/bedtools/intersect/main.nf +++ b/modules/nf-core/bedtools/intersect/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process BEDTOOLS_INTERSECT { - tag id + tag in.id label 'process_single' conda "${moduleDir}/environment.yml" @@ -10,18 +10,18 @@ process BEDTOOLS_INTERSECT { : 'biocontainers/bedtools:2.31.1--hf5e1c6e_0'}" input: - ( - id: String, - intervals1: Path, - intervals2: Path, - chrom_sizes: Path?, - args: String?, - prefix: String?, + in: Record { + id: String + intervals1: Path + intervals2: Path + chrom_sizes: Path? + args: String? + prefix: String? suffix: String? - ): Record + } output: - record(id: id, bedgraph_intersect: file("*.${suffix}")) + record(id: in.id, bedgraph_intersect: file("*.${suffix}")) topic: file("versions.yml") >> 'versions' @@ -30,19 +30,19 @@ process BEDTOOLS_INTERSECT { task.ext.when == null || task.ext.when script: - args = args ?: '' - prefix = prefix ?: id + args = in.args ?: '' + prefix = in.prefix ?: in.id //Extension of the output file. It is set by the user via "ext.suffix" in the config. Corresponds to the file format which depends on arguments (e. g., ".bed", ".bam", ".txt", etc.). - suffix = suffix ?: "${intervals1.extension}" - def sizes = chrom_sizes ? "-g ${chrom_sizes}" : '' - if ("${intervals1}" == "${prefix}.${suffix}" || "${intervals2}" == "${prefix}.${suffix}") { + suffix = in.suffix ?: "${in.intervals1.extension}" + def sizes = in.chrom_sizes ? "-g ${in.chrom_sizes}" : '' + if ("${in.intervals1}" == "${prefix}.${suffix}" || "${in.intervals2}" == "${prefix}.${suffix}") { error("Input and output names are the same, use \"prefix\" to disambiguate!") } """ bedtools \\ intersect \\ - -a ${intervals1} \\ - -b ${intervals2} \\ + -a ${in.intervals1} \\ + -b ${in.intervals2} \\ ${args} \\ ${sizes} \\ > ${prefix}.${suffix} @@ -54,9 +54,9 @@ process BEDTOOLS_INTERSECT { """ stub: - prefix = prefix ?: id - suffix = suffix ?: "bed" - if ("${intervals1}" == "${prefix}.${suffix}" || "${intervals2}" == "${prefix}.${suffix}") { + prefix = in.prefix ?: in.id + suffix = in.suffix ?: "bed" + if ("${in.intervals1}" == "${prefix}.${suffix}" || "${in.intervals2}" == "${prefix}.${suffix}") { error("Input and output names are the same, use \"prefix\" to disambiguate!") } """ diff --git a/modules/nf-core/bismark/align/main.nf b/modules/nf-core/bismark/align/main.nf index fc5fb5c32..a11bc4f38 100644 --- a/modules/nf-core/bismark/align/main.nf +++ b/modules/nf-core/bismark/align/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process BISMARK_ALIGN { - tag id + tag in.id label 'process_high' conda "${moduleDir}/environment.yml" @@ -10,23 +10,23 @@ process BISMARK_ALIGN { 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47' }" input: - ( - id: String, - single_end: Boolean, - reads: List, - fasta: Path, - bismark_index: Path, - args: String?, + in: Record { + id: String + single_end: Boolean + reads: List + fasta: Path + bismark_index: Path + args: String? prefix: String? - ): Record + } stage: - stageAs 'tmp/*', fasta // This change mounts as directory containing the FASTA file to prevent nested symlinks + stageAs in.fasta, 'tmp/*' // This change mounts as directory containing the FASTA file to prevent nested symlinks output: record( - id: id, - single_end: single_end, + id: in.id, + single_end: in.single_end, bam: file("*bam"), align_report: file("*report.txt"), unmapped: file("*fq.gz", optional: true) @@ -39,11 +39,11 @@ process BISMARK_ALIGN { task.ext.when == null || task.ext.when script: - args = args ?: '' - if (prefix) { - args += " --prefix ${prefix}" + args = in.args ?: '' + if (in.prefix) { + args += " --prefix ${in.prefix}" } - def fastq = single_end ? "${reads[0]}" : "-1 ${reads[0]} -2 ${reads[1]}" + def fastq = in.single_end ? "${in.reads[0]}" : "-1 ${in.reads[0]} -2 ${in.reads[1]}" // Try to assign sensible bismark --multicore if not already set if (!args.contains('--multicore') && task.cpus) { @@ -76,7 +76,7 @@ process BISMARK_ALIGN { """ bismark \\ ${fastq} \\ - --genome ${bismark_index} \\ + --genome ${in.bismark_index} \\ --bam \\ ${args} @@ -87,7 +87,7 @@ process BISMARK_ALIGN { """ stub: - prefix = prefix ?: id + prefix = in.prefix ?: in.id """ touch ${prefix}.bam touch ${prefix}.report.txt diff --git a/modules/nf-core/bismark/coverage2cytosine/main.nf b/modules/nf-core/bismark/coverage2cytosine/main.nf index 99842638e..d4991cf91 100644 --- a/modules/nf-core/bismark/coverage2cytosine/main.nf +++ b/modules/nf-core/bismark/coverage2cytosine/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process BISMARK_COVERAGE2CYTOSINE { - tag id + tag in.id label 'process_low' conda "${moduleDir}/environment.yml" @@ -10,21 +10,21 @@ process BISMARK_COVERAGE2CYTOSINE { : 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47'}" input: - ( - id: String, - methylation_coverage: Path, - fasta: Path, - bismark_index: Path, - args: String?, + in: Record { + id: String + methylation_coverage: Path + fasta: Path + bismark_index: Path + args: String? prefix: String? - ): Record + } stage: - stageAs 'tmp/*', fasta // This change mounts as directory containing the FASTA file to prevent nested symlinks + stageAs in.fasta, 'tmp/*' // This change mounts as directory containing the FASTA file to prevent nested symlinks output: record( - id : id, + id : in.id, coverage2cytosine_coverage : file("*.cov.gz", optional: true), coverage2cytosine_report : file("*report.txt.gz"), coverage2cytosine_summary : file("*cytosine_context_summary.txt") @@ -37,12 +37,12 @@ process BISMARK_COVERAGE2CYTOSINE { task.ext.when == null || task.ext.when script: - args = args ?: '' - prefix = prefix ?: id + args = in.args ?: '' + prefix = in.prefix ?: in.id """ coverage2cytosine \\ - ${methylation_coverage} \\ - --genome ${bismark_index} \\ + ${in.methylation_coverage} \\ + --genome ${in.bismark_index} \\ --output ${prefix} \\ --gzip \\ ${args} @@ -54,8 +54,8 @@ process BISMARK_COVERAGE2CYTOSINE { """ stub: - args = args ?: '' - prefix = prefix ?: id + args = in.args ?: '' + prefix = in.prefix ?: in.id """ echo | gzip > ${prefix}.cov.gz echo | gzip > ${prefix}.report.txt.gz diff --git a/modules/nf-core/bismark/deduplicate/main.nf b/modules/nf-core/bismark/deduplicate/main.nf index 11d7df965..5aab7ce2d 100644 --- a/modules/nf-core/bismark/deduplicate/main.nf +++ b/modules/nf-core/bismark/deduplicate/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process BISMARK_DEDUPLICATE { - tag id + tag in.id label 'process_high' conda "${moduleDir}/environment.yml" @@ -10,17 +10,17 @@ process BISMARK_DEDUPLICATE { : 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47'}" input: - ( - id: String, - single_end: Boolean, - bam: Path, - args: String?, + in: Record { + id: String + single_end: Boolean + bam: Path + args: String? prefix: String? - ): Record + } output: record( - id : id, + id : in.id, bam : file("*.deduplicated.bam"), dedup_report : file("*.deduplication_report.txt") ) @@ -32,14 +32,14 @@ process BISMARK_DEDUPLICATE { task.ext.when == null || task.ext.when script: - args = args ?: '' - prefix = prefix ?: id - def seqtype = single_end ? '-s' : '-p' + args = in.args ?: '' + prefix = in.prefix ?: in.id + def seqtype = in.single_end ? '-s' : '-p' """ deduplicate_bismark \\ ${args} \\ ${seqtype} \\ - --bam ${bam} + --bam ${in.bam} cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -48,8 +48,8 @@ process BISMARK_DEDUPLICATE { """ stub: - args = args ?: '' - prefix = prefix ?: id + args = in.args ?: '' + prefix = in.prefix ?: in.id """ touch ${prefix}.deduplicated.bam touch ${prefix}.deduplication_report.txt diff --git a/modules/nf-core/bismark/genomepreparation/main.nf b/modules/nf-core/bismark/genomepreparation/main.nf index 768372c73..bfef1e388 100644 --- a/modules/nf-core/bismark/genomepreparation/main.nf +++ b/modules/nf-core/bismark/genomepreparation/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process BISMARK_GENOMEPREPARATION { - tag "${fasta}" + tag "${in.fasta}" label 'process_high' conda "${moduleDir}/environment.yml" @@ -10,13 +10,13 @@ process BISMARK_GENOMEPREPARATION { : 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47'}" input: - ( - fasta: Path, + in: Record { + fasta: Path args: String? - ): Record + } stage: - stageAs "BismarkIndex/", fasta + stageAs in.fasta, "BismarkIndex/" output: file("BismarkIndex") @@ -28,7 +28,7 @@ process BISMARK_GENOMEPREPARATION { task.ext.when == null || task.ext.when script: - args = args ?: '' + args = in.args ?: '' """ bismark_genome_preparation \\ ${args} \\ @@ -41,9 +41,9 @@ process BISMARK_GENOMEPREPARATION { """ stub: - args = args ?: '' + args = in.args ?: '' """ - rm ${fasta} + rm ${in.fasta} mkdir -p BismarkIndex/Bisulfite_Genome/CT_conversion touch BismarkIndex/Bisulfite_Genome/CT_conversion/BS_CT.1.bt2 diff --git a/modules/nf-core/bismark/methylationextractor/main.nf b/modules/nf-core/bismark/methylationextractor/main.nf index 6984ead77..568bb65f1 100644 --- a/modules/nf-core/bismark/methylationextractor/main.nf +++ b/modules/nf-core/bismark/methylationextractor/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process BISMARK_METHYLATIONEXTRACTOR { - tag id + tag in.id label 'process_high' conda "${moduleDir}/environment.yml" @@ -10,17 +10,17 @@ process BISMARK_METHYLATIONEXTRACTOR { : 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47'}" input: - ( - id: String, - single_end: Boolean, - bam: Path, - bismark_index: Path, + in: Record { + id: String + single_end: Boolean + bam: Path + bismark_index: Path args: String? - ): Record + } output: record( - id : id, + id : in.id, methylation_bedgraph : file("*.bedGraph.gz"), methylation_calls : files("*.txt.gz"), methylation_coverage : file("*.cov.gz"), @@ -35,7 +35,7 @@ process BISMARK_METHYLATIONEXTRACTOR { task.ext.when == null || task.ext.when script: - args = args ?: '' + args = in.args ?: '' // Assign sensible numbers for multicore and buffer_size based on bismark docs if (!args.contains('--multicore') && task.cpus >= 6) { args += " --multicore ${(task.cpus / 3) as int}" @@ -45,10 +45,10 @@ process BISMARK_METHYLATIONEXTRACTOR { args += " --buffer_size ${task.memory.toGiga() - 2}G" } - def seqtype = single_end ? '-s' : '-p' + def seqtype = in.single_end ? '-s' : '-p' """ bismark_methylation_extractor \\ - ${bam} \\ + ${in.bam} \\ --bedGraph \\ --counts \\ --gzip \\ @@ -63,13 +63,13 @@ process BISMARK_METHYLATIONEXTRACTOR { """ stub: - args = args ?: '' + args = in.args ?: '' """ - echo | gzip > ${id}.bedGraph.gz - echo | gzip > ${id}.txt.gz - echo | gzip > ${id}.cov.gz - touch ${id}_splitting_report.txt - touch ${id}.M-bias.txt + echo | gzip > ${in.id}.bedGraph.gz + echo | gzip > ${in.id}.txt.gz + echo | gzip > ${in.id}.cov.gz + touch ${in.id}_splitting_report.txt + touch ${in.id}.M-bias.txt cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/bismark/report/main.nf b/modules/nf-core/bismark/report/main.nf index e3a898608..62c57c496 100644 --- a/modules/nf-core/bismark/report/main.nf +++ b/modules/nf-core/bismark/report/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process BISMARK_REPORT { - tag id + tag in.id label 'process_low' conda "${moduleDir}/environment.yml" @@ -10,17 +10,17 @@ process BISMARK_REPORT { : 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47'}" input: - ( - id: String, - align_report: Path, - dedup_report: Path, - methylation_report: Path, - methylation_mbias: Path, + in: Record { + id: String + align_report: Path + dedup_report: Path + methylation_report: Path + methylation_mbias: Path args: String? - ): Record + } output: - record(id: id, bismark_report: file("*report.{html,txt}")) + record(id: in.id, bismark_report: file("*report.{html,txt}")) topic: file("versions.yml") >> 'versions' @@ -29,7 +29,7 @@ process BISMARK_REPORT { task.ext.when == null || task.ext.when script: - args = args ?: '' + args = in.args ?: '' """ bismark2report ${args} @@ -40,10 +40,10 @@ process BISMARK_REPORT { """ stub: - args = args ?: '' + args = in.args ?: '' """ - touch ${id}.report.txt - touch ${id}.report.html + touch ${in.id}.report.txt + touch ${in.id}.report.html cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/bismark/summary/main.nf b/modules/nf-core/bismark/summary/main.nf index 265c51670..0d7c7c4e7 100644 --- a/modules/nf-core/bismark/summary/main.nf +++ b/modules/nf-core/bismark/summary/main.nf @@ -9,13 +9,13 @@ process BISMARK_SUMMARY { : 'community.wave.seqera.io/library/bismark:0.25.1--1f50935de5d79c47'}" input: - ( - bam: Set, - align_report: Set, - dedup_report: Set, - methylation_report: Set, + in: Record { + bam: Set + align_report: Set + dedup_report: Set + methylation_report: Set methylation_mbias: Set - ): Record + } output: files("*report.{html,txt}") @@ -28,7 +28,7 @@ process BISMARK_SUMMARY { script: """ - bismark2summary ${bam.join(' ')} + bismark2summary ${in.bam.join(' ')} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/bwameth/align/main.nf b/modules/nf-core/bwameth/align/main.nf index 3759b4f07..37e55f997 100644 --- a/modules/nf-core/bwameth/align/main.nf +++ b/modules/nf-core/bwameth/align/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process BWAMETH_ALIGN { - tag id + tag in.id label 'process_high' conda "${moduleDir}/environment.yml" @@ -10,20 +10,20 @@ process BWAMETH_ALIGN { : 'biocontainers/bwameth:0.2.9--pyh7e72e81_0'}" input: - ( - id: String, - read_group: String?, - reads: Path, - fasta: Path, - index: Path, - args_bwameth: String?, - args_samtools: String?, + in: Record { + id: String + read_group: String? + reads: Path + fasta: Path + index: Path + args_bwameth: String? + args_samtools: String? prefix: String? - ): Record + } output: record( - id: id, + id: in.id, bam: file("*.bam") ) @@ -34,20 +34,20 @@ process BWAMETH_ALIGN { task.ext.when == null || task.ext.when script: - args_bwameth = args_bwameth ?: '' - args_samtools = args_samtools ?: '' - prefix = prefix ?: id - read_group = read_group ? "-R ${read_group}" : "" + args_bwameth = in.args_bwameth ?: '' + args_samtools = in.args_samtools ?: '' + prefix = in.prefix ?: in.id + read_group = in.read_group ? "-R ${in.read_group}" : "" """ export BWA_METH_SKIP_TIME_CHECKS=1 - ln -sf \$(readlink ${fasta}) ${index}/${fasta} + ln -sf \$(readlink ${in.fasta}) ${in.index}/${in.fasta} bwameth.py \\ ${args_bwameth} \\ ${read_group} \\ -t ${task.cpus} \\ - --reference ${index}/${fasta} \\ - ${reads} \\ + --reference ${in.index}/${in.fasta} \\ + ${in.reads} \\ | samtools view ${args_samtools} -@ ${task.cpus} -bhS -o ${prefix}.bam - cat <<-END_VERSIONS > versions.yml @@ -57,7 +57,7 @@ process BWAMETH_ALIGN { """ stub: - prefix = prefix ?: id + prefix = in.prefix ?: in.id """ touch ${prefix}.bam diff --git a/modules/nf-core/bwameth/index/main.nf b/modules/nf-core/bwameth/index/main.nf index a15f8f79e..a6434a4eb 100644 --- a/modules/nf-core/bwameth/index/main.nf +++ b/modules/nf-core/bwameth/index/main.nf @@ -14,7 +14,7 @@ process BWAMETH_INDEX { use_mem2: Boolean stage: - stageAs "BwamethIndex/", fasta + stageAs fasta, "BwamethIndex/" output: file("BwamethIndex") diff --git a/modules/nf-core/cat/fastq/main.nf b/modules/nf-core/cat/fastq/main.nf index 7a9b21994..05382f40f 100644 --- a/modules/nf-core/cat/fastq/main.nf +++ b/modules/nf-core/cat/fastq/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process CAT_FASTQ { - tag "${id}" + tag "${in.id}" label 'process_single' conda "${moduleDir}/environment.yml" @@ -10,19 +10,19 @@ process CAT_FASTQ { : 'community.wave.seqera.io/library/coreutils_grep_gzip_lbzip2_pruned:838ba80435a629f8'}" input: - ( - id: String, - single_end: Boolean, + in: Record { + id: String + single_end: Boolean reads: List - ): Record + } stage: - stageAs "input*/*", reads + stageAs in.reads, "input*/*" output: record( - id: id, - single_end: single_end, + id: in.id, + single_end: in.single_end, reads: files("*.merged.fastq.gz").toSorted() ) @@ -33,9 +33,9 @@ process CAT_FASTQ { task.ext.when == null || task.ext.when script: - def prefix = task.ext.prefix ?: "${id}" - def readList = reads.collect { it.toString() } - if (single_end) { + def prefix = task.ext.prefix ?: "${in.id}" + def readList = in.reads.collect { it.toString() } + if (in.single_end) { if (readList.size >= 1) { """ cat ${readList.join(' ')} > ${prefix}.merged.fastq.gz @@ -71,9 +71,9 @@ process CAT_FASTQ { } stub: - def prefix = task.ext.prefix ?: "${id}" - def readList = reads.collect { it.toString() } - if (single_end) { + def prefix = task.ext.prefix ?: "${in.id}" + def readList = in.reads.collect { it.toString() } + if (in.single_end) { if (readList.size >= 1) { """ echo '' | gzip > ${prefix}.merged.fastq.gz diff --git a/modules/nf-core/fastqc/main.nf b/modules/nf-core/fastqc/main.nf index 12a716d17..2486fd9cc 100644 --- a/modules/nf-core/fastqc/main.nf +++ b/modules/nf-core/fastqc/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process FASTQC { - tag id + tag in.id label 'process_medium' conda "${moduleDir}/environment.yml" @@ -10,16 +10,16 @@ process FASTQC { : 'biocontainers/fastqc:0.12.1--hdfd78af_0'}" input: - ( - id: String, - reads: List, - args: String?, + in: Record { + id: String + reads: List + args: String? prefix: String? - ): Record + } output: record( - id: id, + id: in.id, fastqc_html: files("*.html"), fastqc_zip: files("*.zip") ) @@ -31,10 +31,10 @@ process FASTQC { task.ext.when == null || task.ext.when script: - args = args ?: '--quiet' - prefix = prefix ?: id + args = in.args ?: '--quiet' + prefix = in.prefix ?: in.id // Make list of old name and new name pairs to use for renaming in the bash while loop - def old_new_pairs = reads.withIndex().collect { entry, index -> [entry, "${prefix}_${index + 1}.${entry.extension}"] } + def old_new_pairs = in.reads.withIndex().collect { entry, index -> [entry, "${prefix}_${index + 1}.${entry.extension}"] } def rename_to = old_new_pairs*.join(' ').join(' ') def renamed_files = old_new_pairs.collect { _old_name, new_name -> new_name }.join(' ') @@ -63,7 +63,7 @@ process FASTQC { """ stub: - prefix = prefix ?: id + prefix = in.prefix ?: in.id """ touch ${prefix}.html touch ${prefix}.zip diff --git a/modules/nf-core/methyldackel/extract/main.nf b/modules/nf-core/methyldackel/extract/main.nf index 263eb74bb..848ebcc43 100644 --- a/modules/nf-core/methyldackel/extract/main.nf +++ b/modules/nf-core/methyldackel/extract/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process METHYLDACKEL_EXTRACT { - tag id + tag in.id label 'process_medium' conda "${moduleDir}/environment.yml" @@ -10,18 +10,18 @@ process METHYLDACKEL_EXTRACT { : 'biocontainers/methyldackel:0.6.1--he4a0461_7'}" input: - ( - id: String, - bam: Path, - bai: Path, - fasta: Path, - fai: Path, + in: Record { + id: String + bam: Path + bai: Path + fasta: Path + fai: Path args: String? - ): Record + } output: record( - id : id, + id : in.id, methydackel_bedgraph : file("*.bedGraph", optional: true), methydackel_methylkit : file("*.methylKit", optional: true) ) @@ -33,12 +33,12 @@ process METHYLDACKEL_EXTRACT { task.ext.when == null || task.ext.when script: - args = args ?: '' + args = in.args ?: '' """ MethylDackel extract \\ ${args} \\ - ${fasta} \\ - ${bam} + ${in.fasta} \\ + ${in.bam} cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -47,10 +47,10 @@ process METHYLDACKEL_EXTRACT { """ stub: - args = args ?: '' + args = in.args ?: '' def out_extension = args.contains('--methylKit') ? 'methylKit' : 'bedGraph' """ - touch ${bam.baseName}_CpG.${out_extension} + touch ${in.bam.baseName}_CpG.${out_extension} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/methyldackel/mbias/main.nf b/modules/nf-core/methyldackel/mbias/main.nf index 30a45c7dd..8e66dcd85 100644 --- a/modules/nf-core/methyldackel/mbias/main.nf +++ b/modules/nf-core/methyldackel/mbias/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process METHYLDACKEL_MBIAS { - tag id + tag in.id label 'process_low' conda "${moduleDir}/environment.yml" @@ -10,17 +10,17 @@ process METHYLDACKEL_MBIAS { : 'biocontainers/methyldackel:0.6.1--he4a0461_7'}" input: - ( - id: String, - bam: Path, - bai: Path, - fasta: Path, + in: Record { + id: String + bam: Path + bai: Path + fasta: Path fai: Path - ): Record + } output: record( - id: id, + id: in.id, methydackel_mbias: file("*.mbias.txt") ) @@ -32,12 +32,12 @@ process METHYLDACKEL_MBIAS { script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: id + def prefix = task.ext.prefix ?: in.id """ MethylDackel mbias \\ ${args} \\ - ${fasta} \\ - ${bam} \\ + ${in.fasta} \\ + ${in.bam} \\ ${prefix} \\ --txt \\ > ${prefix}.mbias.txt @@ -49,7 +49,7 @@ process METHYLDACKEL_MBIAS { """ stub: - def prefix = task.ext.prefix ?: id + def prefix = task.ext.prefix ?: in.id """ touch ${prefix}.mbias.txt diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index 0db989859..318c2e6e0 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -9,19 +9,19 @@ process MULTIQC { : 'biocontainers/multiqc:1.30--pyhdfd78af_0'}" input: - ( - multiqc_files : Set, - multiqc_config : Path, - extra_multiqc_config : Path?, - multiqc_logo : Path?, - replace_names : Path?, - sample_names : Path?, - args : String?, + in: Record { + multiqc_files : Set + multiqc_config : Path + extra_multiqc_config : Path? + multiqc_logo : Path? + replace_names : Path? + sample_names : Path? + args : String? prefix : String? - ): Record + } stage: - stageAs "?/*", multiqc_files + stageAs in.multiqc_files, "?/*" output: record( @@ -34,13 +34,13 @@ process MULTIQC { task.ext.when == null || task.ext.when script: - args = args ?: '' - prefix = prefix ? "--filename ${prefix}.html" : '' - def config = multiqc_config ? "--config ${multiqc_config}" : '' - def extra_config = extra_multiqc_config ? "--config ${extra_multiqc_config}" : '' - def logo = multiqc_logo ? "--cl-config 'custom_logo: \"${multiqc_logo}\"'" : '' - def replace = replace_names ? "--replace-names ${replace_names}" : '' - def samples = sample_names ? "--sample-names ${sample_names}" : '' + args = in.args ?: '' + prefix = in.prefix ? "--filename ${in.prefix}.html" : '' + def config = in.multiqc_config ? "--config ${in.multiqc_config}" : '' + def extra_config = in.extra_multiqc_config ? "--config ${in.extra_multiqc_config}" : '' + def logo = in.multiqc_logo ? "--cl-config 'custom_logo: \"${in.multiqc_logo}\"'" : '' + def replace = in.replace_names ? "--replace-names ${in.replace_names}" : '' + def samples = in.sample_names ? "--sample-names ${in.sample_names}" : '' """ multiqc \\ --force \\ diff --git a/modules/nf-core/parabricks/fq2bammeth/main.nf b/modules/nf-core/parabricks/fq2bammeth/main.nf index c0c3428f2..9c2369fa6 100644 --- a/modules/nf-core/parabricks/fq2bammeth/main.nf +++ b/modules/nf-core/parabricks/fq2bammeth/main.nf @@ -1,28 +1,28 @@ nextflow.preview.types = true process PARABRICKS_FQ2BAMMETH { - tag id + tag in.id label 'process_high' label 'process_gpu' container "nvcr.io/nvidia/clara/clara-parabricks:4.3.2-1" input: - ( - id: String, - single_end: Boolean, - reads: Path, - fasta: Path, - bwameth_index: Path, - known_sites: Path?, - args: String?, + in: Record { + id: String + single_end: Boolean + reads: Path + fasta: Path + bwameth_index: Path + known_sites: Path? + args: String? prefix: String? - ): Record + } output: record( - id : id, - single_end : single_end, + id : in.id, + single_end : in.single_end, bam : file("*.bam"), bai : file("*.bai"), qc_metrics : file(("qc_metrics"), optional: true), @@ -41,22 +41,22 @@ process PARABRICKS_FQ2BAMMETH { if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { error("Parabricks module does not support Conda. Please use Docker / Singularity / Podman instead.") } - args = args ?: '' - prefix = prefix ?: id - def in_fq_command = single_end ? "--in-se-fq ${reads}" : "--in-fq ${reads}" - def known_sites_command = known_sites ? known_sites.collect { "--knownSites ${it}" }.join(' ') : "" - def known_sites_output = known_sites ? "--out-recal-file ${prefix}.table" : "" + args = in.args ?: '' + prefix = in.prefix ?: in.id + def in_fq_command = in.single_end ? "--in-se-fq ${in.reads}" : "--in-fq ${in.reads}" + def known_sites_command = in.known_sites ? in.known_sites.collect { "--knownSites ${it}" }.join(' ') : "" + def known_sites_output = in.known_sites ? "--out-recal-file ${prefix}.table" : "" def num_gpus = task.accelerator ? "--num-gpus ${task.accelerator.request}" : '' """ - if [ -L ${fasta} ]; then - ln -sf \$(readlink ${fasta}) ${bwameth_index}/${fasta} + if [ -L ${in.fasta} ]; then + ln -sf \$(readlink ${in.fasta}) ${in.bwameth_index}/${in.fasta} else - ln -sf ../${fasta} ${bwameth_index}/${fasta} + ln -sf ../${in.fasta} ${in.bwameth_index}/${in.fasta} fi pbrun \\ fq2bam_meth \\ - --ref ${bwameth_index}/${fasta} \\ + --ref ${in.bwameth_index}/${in.fasta} \\ ${in_fq_command} \\ --out-bam ${prefix}.bam \\ ${known_sites_command} \\ @@ -75,7 +75,7 @@ process PARABRICKS_FQ2BAMMETH { if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { error("Parabricks module does not support Conda. Please use Docker / Singularity / Podman instead.") } - prefix = prefix ?: id + prefix = in.prefix ?: in.id """ touch ${prefix}.bam touch ${prefix}.bam.bai diff --git a/modules/nf-core/picard/bedtointervallist/main.nf b/modules/nf-core/picard/bedtointervallist/main.nf index fa7332f0a..06b73e499 100644 --- a/modules/nf-core/picard/bedtointervallist/main.nf +++ b/modules/nf-core/picard/bedtointervallist/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process PICARD_BEDTOINTERVALLIST { - tag id + tag in.id label 'process_low' conda "${moduleDir}/environment.yml" @@ -10,17 +10,17 @@ process PICARD_BEDTOINTERVALLIST { : 'biocontainers/picard:3.3.0--hdfd78af_0'}" input: - ( - id: String, - bed: Path, - reference_dict: Path, - arguments_file: Path?, - args: String?, + in: Record { + id: String + bed: Path + reference_dict: Path + arguments_file: Path? + args: String? prefix: String? - ): Record + } output: - record(id: id, intervallist: file('*.intervallist')) + record(id: in.id, intervallist: file('*.intervallist')) topic: file("versions.yml") >> 'versions' @@ -29,9 +29,9 @@ process PICARD_BEDTOINTERVALLIST { task.ext.when == null || task.ext.when script: - args = args ?: '' - prefix = prefix ?: id - def args_file = arguments_file ? "--arguments_file ${arguments_file}" : "" + args = in.args ?: '' + prefix = in.prefix ?: in.id + def args_file = in.arguments_file ? "--arguments_file ${in.arguments_file}" : "" def avail_mem = 3072 if (!task.memory) { log.info('[Picard BedToIntervalList] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') @@ -43,9 +43,9 @@ process PICARD_BEDTOINTERVALLIST { picard \\ -Xmx${avail_mem}M \\ BedToIntervalList \\ - --INPUT ${bed} \\ + --INPUT ${in.bed} \\ --OUTPUT ${prefix}.intervallist \\ - --SEQUENCE_DICTIONARY ${reference_dict} \\ + --SEQUENCE_DICTIONARY ${in.reference_dict} \\ --TMP_DIR . \\ ${args_file} \\ ${args} @@ -57,8 +57,8 @@ process PICARD_BEDTOINTERVALLIST { """ stub: - args = args ?: '' - prefix = prefix ?: id + args = in.args ?: '' + prefix = in.prefix ?: in.id def avail_mem = 3072 if (!task.memory) { log.info('[Picard BedToIntervalList] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') @@ -66,14 +66,14 @@ process PICARD_BEDTOINTERVALLIST { else { avail_mem = (task.memory.toMega() * 0.8).intValue() } - def args_file = arguments_file ? "--arguments_file ${arguments_file}" : "" + def args_file = in.arguments_file ? "--arguments_file ${in.arguments_file}" : "" """ echo "picard \\ -Xmx${avail_mem}M \\ BedToIntervalList \\ - --INPUT ${bed} \\ + --INPUT ${in.bed} \\ --OUTPUT ${prefix}.intervallist \\ - --SEQUENCE_DICTIONARY ${reference_dict} \\ + --SEQUENCE_DICTIONARY ${in.reference_dict} \\ --TMP_DIR . \\ ${args_file} \\ ${args}" diff --git a/modules/nf-core/picard/collecthsmetrics/main.nf b/modules/nf-core/picard/collecthsmetrics/main.nf index b26ff2bf1..e359f9989 100644 --- a/modules/nf-core/picard/collecthsmetrics/main.nf +++ b/modules/nf-core/picard/collecthsmetrics/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process PICARD_COLLECTHSMETRICS { - tag id + tag in.id label 'process_single' conda "${moduleDir}/environment.yml" @@ -10,25 +10,25 @@ process PICARD_COLLECTHSMETRICS { : 'biocontainers/picard:3.3.0--hdfd78af_0'}" input: - ( - id: String, - bam: Path, - bai: Path, - bait_intervals: Set, - target_intervals: Set, - fasta: Path, - fai: Path, - reference_dict: Path, - args: String?, + in: Record { + id: String + bam: Path + bai: Path + bait_intervals: Set + target_intervals: Set + fasta: Path + fai: Path + reference_dict: Path + args: String? prefix: String? - ): Record + } stage: - stageAs "baits/*", bait_intervals - stageAs 'targets/*', target_intervals + stageAs in.bait_intervals, "baits/*" + stageAs in.target_intervals, 'targets/*' output: - record(id: id, picard_hsmetrics: file("*_metrics")) + record(id: in.id, picard_hsmetrics: file("*_metrics")) topic: file("versions.yml") >> 'versions' @@ -37,9 +37,9 @@ process PICARD_COLLECTHSMETRICS { task.ext.when == null || task.ext.when script: - args = args ?: '' - prefix = prefix ?: id - def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" + args = in.args ?: '' + prefix = in.prefix ?: in.id + def reference = in.fasta ? "--REFERENCE_SEQUENCE ${in.fasta}" : "" def avail_mem = 3072 if (!task.memory) { @@ -49,18 +49,18 @@ process PICARD_COLLECTHSMETRICS { avail_mem = (task.memory.toMega() * 0.8).intValue() } - def bait_interval_list = bait_intervals + def bait_interval_list = in.bait_intervals def bait_intervallist_cmd = "" - if (bait_intervals =~ /.(bed|bed.gz)$/) { - bait_interval_list = bait_intervals.toString().replaceAll(/.(bed|bed.gz)$/, ".interval_list") - bait_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${bait_intervals} --OUTPUT ${bait_interval_list} --SEQUENCE_DICTIONARY ${reference_dict} --TMP_DIR ." + if (in.bait_intervals =~ /.(bed|bed.gz)$/) { + bait_interval_list = in.bait_intervals.toString().replaceAll(/.(bed|bed.gz)$/, ".interval_list") + bait_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${in.bait_intervals} --OUTPUT ${bait_interval_list} --SEQUENCE_DICTIONARY ${in.reference_dict} --TMP_DIR ." } - def target_interval_list = target_intervals + def target_interval_list = in.target_intervals def target_intervallist_cmd = "" - if (target_intervals =~ /.(bed|bed.gz)$/) { - target_interval_list = target_intervals.toString().replaceAll(/.(bed|bed.gz)$/, ".interval_list") - target_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${target_intervals} --OUTPUT ${target_interval_list} --SEQUENCE_DICTIONARY ${reference_dict} --TMP_DIR ." + if (in.target_intervals =~ /.(bed|bed.gz)$/) { + target_interval_list = in.target_intervals.toString().replaceAll(/.(bed|bed.gz)$/, ".interval_list") + target_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${in.target_intervals} --OUTPUT ${target_interval_list} --SEQUENCE_DICTIONARY ${in.reference_dict} --TMP_DIR ." } @@ -76,7 +76,7 @@ process PICARD_COLLECTHSMETRICS { ${reference} \\ --BAIT_INTERVALS ${bait_interval_list} \\ --TARGET_INTERVALS ${target_interval_list} \\ - --INPUT ${bam} \\ + --INPUT ${in.bam} \\ --OUTPUT ${prefix}.CollectHsMetrics.coverage_metrics @@ -87,7 +87,7 @@ process PICARD_COLLECTHSMETRICS { """ stub: - prefix = prefix ?: id + prefix = in.prefix ?: in.id """ touch ${prefix}.CollectHsMetrics.coverage_metrics diff --git a/modules/nf-core/picard/createsequencedictionary/main.nf b/modules/nf-core/picard/createsequencedictionary/main.nf index f5b40eac0..c54d7bddb 100644 --- a/modules/nf-core/picard/createsequencedictionary/main.nf +++ b/modules/nf-core/picard/createsequencedictionary/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process PICARD_CREATESEQUENCEDICTIONARY { - tag id + tag in.id label 'process_medium' conda "${moduleDir}/environment.yml" @@ -10,15 +10,15 @@ process PICARD_CREATESEQUENCEDICTIONARY { : 'biocontainers/picard:3.3.0--hdfd78af_0'}" input: - ( - id: String, - fasta: Path, - args: String?, + in: Record { + id: String + fasta: Path + args: String? prefix: String? - ): Record + } output: - record(id: id, reference_dict: file("*.dict")) + record(id: in.id, reference_dict: file("*.dict")) topic: file("versions.yml") >> 'versions' @@ -27,8 +27,8 @@ process PICARD_CREATESEQUENCEDICTIONARY { task.ext.when == null || task.ext.when script: - args = args ?: '' - prefix = prefix ?: id + args = in.args ?: '' + prefix = in.prefix ?: in.id def avail_mem = 3072 if (!task.memory) { log.info('[Picard CreateSequenceDictionary] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') @@ -41,7 +41,7 @@ process PICARD_CREATESEQUENCEDICTIONARY { -Xmx${avail_mem}M \\ CreateSequenceDictionary \\ ${args} \\ - --REFERENCE ${fasta} \\ + --REFERENCE ${in.fasta} \\ --OUTPUT ${prefix}.dict cat <<-END_VERSIONS > versions.yml @@ -51,8 +51,8 @@ process PICARD_CREATESEQUENCEDICTIONARY { """ stub: - args = args ?: '' - prefix = prefix ?: id + args = in.args ?: '' + prefix = in.prefix ?: in.id """ touch ${prefix}.dict diff --git a/modules/nf-core/picard/markduplicates/main.nf b/modules/nf-core/picard/markduplicates/main.nf index 1fcf14a6f..80aa00c5a 100644 --- a/modules/nf-core/picard/markduplicates/main.nf +++ b/modules/nf-core/picard/markduplicates/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process PICARD_MARKDUPLICATES { - tag id + tag in.id label 'process_medium' conda "${moduleDir}/environment.yml" @@ -10,19 +10,19 @@ process PICARD_MARKDUPLICATES { : 'biocontainers/picard:3.3.0--hdfd78af_0'}" input: - ( - id: String, - reads: Path, - fasta: Path, - fai: Path, - args: String?, - prefix: String?, + in: Record { + id: String + reads: Path + fasta: Path + fai: Path + args: String? + prefix: String? suffix: String? - ): Record + } output: record( - id : id, + id : in.id, bam : file("*.bam", optional: true), bai : file("*.bai", optional: true), cram : file("*.cram", optional: true), @@ -36,10 +36,10 @@ process PICARD_MARKDUPLICATES { task.ext.when == null || task.ext.when script: - args = args ?: '' - prefix = prefix ?: id - suffix = suffix ?: "${reads.getExtension()}" - def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" + args = in.args ?: '' + prefix = in.prefix ?: in.id + suffix = in.suffix ?: "${in.reads.getExtension()}" + def reference = in.fasta ? "--REFERENCE_SEQUENCE ${in.fasta}" : "" def avail_mem = 3072 if (!task.memory) { log.info('[Picard MarkDuplicates] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') @@ -48,7 +48,7 @@ process PICARD_MARKDUPLICATES { avail_mem = (task.memory.toMega() * 0.8).intValue() } - if ("${reads}" == "${prefix}.${suffix}") { + if ("${in.reads}" == "${prefix}.${suffix}") { error("Input and output names are the same, use \"prefix\" to disambiguate!") } @@ -57,7 +57,7 @@ process PICARD_MARKDUPLICATES { -Xmx${avail_mem}M \\ MarkDuplicates \\ ${args} \\ - --INPUT ${reads} \\ + --INPUT ${in.reads} \\ --OUTPUT ${prefix}.${suffix} \\ ${reference} \\ --METRICS_FILE ${prefix}.MarkDuplicates.metrics.txt @@ -69,9 +69,9 @@ process PICARD_MARKDUPLICATES { """ stub: - prefix = prefix ?: id - suffix = suffix ?: "${reads.getExtension()}" - if ("${reads}" == "${prefix}.${suffix}") { + prefix = in.prefix ?: in.id + suffix = in.suffix ?: "${in.reads.getExtension()}" + if ("${in.reads}" == "${prefix}.${suffix}") { error("Input and output names are the same, use \"prefix\" to disambiguate!") } """ diff --git a/modules/nf-core/preseq/lcextrap/main.nf b/modules/nf-core/preseq/lcextrap/main.nf index 383d9a51f..5e43646ce 100644 --- a/modules/nf-core/preseq/lcextrap/main.nf +++ b/modules/nf-core/preseq/lcextrap/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process PRESEQ_LCEXTRAP { - tag id + tag in.id label 'process_single' label 'error_retry' @@ -11,17 +11,17 @@ process PRESEQ_LCEXTRAP { : 'biocontainers/preseq:3.2.0--hdcf5f25_6'}" input: - ( - id: String, - single_end: Boolean, - bam: Path, - args: String?, + in: Record { + id: String + single_end: Boolean + bam: Path + args: String? prefix: String? - ): Record + } output: record( - id: id, + id: in.id, lc_extrap: file("*.lc_extrap.txt"), lc_log: file("*.log") ) @@ -33,18 +33,18 @@ process PRESEQ_LCEXTRAP { task.ext.when == null || task.ext.when script: - args = args ?: '' + args = in.args ?: '' args = task.attempt > 1 ? args.join(' -defects') : args // Disable testing for defects - prefix = prefix ?: id - def paired_end = single_end ? '' : '-pe' + prefix = in.prefix ?: in.id + def paired_end = in.single_end ? '' : '-pe' """ preseq \\ lc_extrap \\ ${args} \\ ${paired_end} \\ -output ${prefix}.lc_extrap.txt \\ - ${bam} + ${in.bam} cp .command.err ${prefix}.command.log cat <<-END_VERSIONS > versions.yml @@ -54,7 +54,7 @@ process PRESEQ_LCEXTRAP { """ stub: - prefix = prefix ?: id + prefix = in.prefix ?: in.id """ touch ${prefix}.lc_extrap.txt touch ${prefix}.command.log diff --git a/modules/nf-core/qualimap/bamqc/main.nf b/modules/nf-core/qualimap/bamqc/main.nf index 31750beb5..80870677e 100644 --- a/modules/nf-core/qualimap/bamqc/main.nf +++ b/modules/nf-core/qualimap/bamqc/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process QUALIMAP_BAMQC { - tag id + tag in.id label 'process_medium' conda "${moduleDir}/environment.yml" @@ -10,18 +10,18 @@ process QUALIMAP_BAMQC { : 'biocontainers/qualimap:2.3--hdfd78af_0'}" input: - ( - id: String, - single_end: Boolean, - strandedness: String?, - bam: Path, - gff: Path, - args: String?, + in: Record { + id: String + single_end: Boolean + strandedness: String? + bam: Path + gff: Path + args: String? prefix: String? - ): Record + } output: - record(id: id, qualimap_bamqc: file("${prefix}")) + record(id: in.id, qualimap_bamqc: file("${prefix}")) topic: file("versions.yml") >> 'versions' @@ -30,15 +30,15 @@ process QUALIMAP_BAMQC { task.ext.when == null || task.ext.when script: - args = args ?: '' - prefix = prefix ?: id + args = in.args ?: '' + prefix = in.prefix ?: in.id - def collect_pairs = single_end ? '' : '--collect-overlap-pairs' + def collect_pairs = in.single_end ? '' : '--collect-overlap-pairs' def memory = (task.memory.toMega() * 0.8).intValue() + 'M' - def regions = gff ? "--gff ${gff}" : '' + def regions = in.gff ? "--gff ${in.gff}" : '' - strandedness = strandedness - ? "strand-specific-${strandedness}" + strandedness = in.strandedness + ? "strand-specific-${in.strandedness}" : 'non-strand-specific' """ @@ -49,7 +49,7 @@ process QUALIMAP_BAMQC { --java-mem-size=${memory} \\ bamqc \\ ${args} \\ - -bam ${bam} \\ + -bam ${in.bam} \\ ${regions} \\ -p ${strandedness} \\ ${collect_pairs} \\ @@ -63,7 +63,7 @@ process QUALIMAP_BAMQC { """ stub: - prefix = prefix ? "${id}${prefix}" : id + prefix = in.prefix ? "${in.id}${in.prefix}" : in.id """ mkdir -p ${prefix}/css mkdir ${prefix}/images_qualimapReport diff --git a/modules/nf-core/samtools/faidx/main.nf b/modules/nf-core/samtools/faidx/main.nf index cbcd3d121..e644009b5 100644 --- a/modules/nf-core/samtools/faidx/main.nf +++ b/modules/nf-core/samtools/faidx/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process SAMTOOLS_FAIDX { - tag "${fasta}" + tag "${in.fasta}" label 'process_single' conda "${moduleDir}/environment.yml" @@ -10,12 +10,12 @@ process SAMTOOLS_FAIDX { : 'biocontainers/samtools:1.21--h50ea8bc_0'}" input: - ( - fasta: Path, - fai: Path?, - get_sizes: Boolean, + in: Record { + fasta: Path + fai: Path? + get_sizes: Boolean args: String? - ): Record + } output: record( @@ -32,12 +32,12 @@ process SAMTOOLS_FAIDX { task.ext.when == null || task.ext.when script: - args = args ?: '' - def get_sizes_command = get_sizes ? "cut -f 1,2 ${fasta}.fai > ${fasta}.sizes" : '' + args = in.args ?: '' + def get_sizes_command = in.get_sizes ? "cut -f 1,2 ${in.fasta}.fai > ${in.fasta}.sizes" : '' """ samtools \\ faidx \\ - ${fasta} \\ + ${in.fasta} \\ ${args} ${get_sizes_command} @@ -49,14 +49,14 @@ process SAMTOOLS_FAIDX { """ stub: - def match = (args =~ /-o(?:utput)?\s(.*)\s?/).findAll() + def match = (in.args =~ /-o(?:utput)?\s(.*)\s?/).findAll() def fastacmd = match[0] ? "touch ${match[0][1]}" : '' - def get_sizes_command = get_sizes ? "touch ${fasta}.sizes" : '' + def get_sizes_command = in.get_sizes ? "touch ${in.fasta}.sizes" : '' """ ${fastacmd} - touch ${fasta}.fai - if [[ "${fasta.extension}" == "gz" ]]; then - touch ${fasta}.gzi + touch ${in.fasta}.fai + if [[ "${in.fasta.extension}" == "gz" ]]; then + touch ${in.fasta}.gzi fi ${get_sizes_command} diff --git a/modules/nf-core/samtools/flagstat/main.nf b/modules/nf-core/samtools/flagstat/main.nf index 42caa5dfa..a5928f898 100644 --- a/modules/nf-core/samtools/flagstat/main.nf +++ b/modules/nf-core/samtools/flagstat/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process SAMTOOLS_FLAGSTAT { - tag id + tag in.id label 'process_single' conda "${moduleDir}/environment.yml" @@ -10,15 +10,15 @@ process SAMTOOLS_FLAGSTAT { : 'biocontainers/samtools:1.21--h50ea8bc_0'}" input: - ( - id: String, - bam: Path, + in: Record { + id: String + bam: Path bai: Path - ): Record + } output: record( - id: id, + id: in.id, samtools_flagstat: file("*.flagstat") ) @@ -29,12 +29,12 @@ process SAMTOOLS_FLAGSTAT { task.ext.when == null || task.ext.when script: - def prefix = task.ext.prefix ?: id + def prefix = task.ext.prefix ?: in.id """ samtools \\ flagstat \\ --threads ${task.cpus} \\ - ${bam} \\ + ${in.bam} \\ > ${prefix}.flagstat cat <<-END_VERSIONS > versions.yml @@ -44,7 +44,7 @@ process SAMTOOLS_FLAGSTAT { """ stub: - def prefix = task.ext.prefix ?: id + def prefix = task.ext.prefix ?: in.id """ touch ${prefix}.flagstat diff --git a/modules/nf-core/samtools/index/main.nf b/modules/nf-core/samtools/index/main.nf index cd8876b27..844a04dd4 100644 --- a/modules/nf-core/samtools/index/main.nf +++ b/modules/nf-core/samtools/index/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process SAMTOOLS_INDEX { - tag id + tag in.id label 'process_low' conda "${moduleDir}/environment.yml" @@ -10,15 +10,15 @@ process SAMTOOLS_INDEX { : 'biocontainers/samtools:1.21--h50ea8bc_0'}" input: - ( - id: String, - input: Path, + in: Record { + id: String + input: Path args: String? - ): Record + } output: record( - id : id, + id : in.id, bai : file("*.bai", optional: true), csi : file("*.csi", optional: true), crai : file("*.crai", optional: true), @@ -31,13 +31,13 @@ process SAMTOOLS_INDEX { task.ext.when == null || task.ext.when script: - args = args ?: '' + args = in.args ?: '' """ samtools \\ index \\ -@ ${task.cpus} \\ ${args} \\ - ${input} + ${in.input} cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -46,12 +46,12 @@ process SAMTOOLS_INDEX { """ stub: - args = args ?: '' - def extension = input.getExtension() == 'cram' + args = in.args ?: '' + def extension = in.input.getExtension() == 'cram' ? "crai" : args.contains("-c") ? "csi" : "bai" """ - touch ${input}.${extension} + touch ${in.input}.${extension} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/samtools/sort/main.nf b/modules/nf-core/samtools/sort/main.nf index ddf05d954..2c1cacae1 100644 --- a/modules/nf-core/samtools/sort/main.nf +++ b/modules/nf-core/samtools/sort/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process SAMTOOLS_SORT { - tag id + tag in.id label 'process_medium' conda "${moduleDir}/environment.yml" @@ -10,17 +10,17 @@ process SAMTOOLS_SORT { : 'biocontainers/samtools:1.21--h50ea8bc_0'}" input: - ( - id: String, - bam: Path, - fasta: Path?, - args: String?, + in: Record { + id: String + bam: Path + fasta: Path? + args: String? prefix: String? - ): Record + } output: record( - id : id, + id : in.id, bam : file("*.bam", optional: true), cram : file("*.cram", optional: true), crai : file("*.crai", optional: true), @@ -34,21 +34,21 @@ process SAMTOOLS_SORT { task.ext.when == null || task.ext.when script: - args = args ?: '' - prefix = prefix ?: id + args = in.args ?: '' + prefix = in.prefix ?: in.id def extension = args.contains("--output-fmt sam") ? "sam" : args.contains("--output-fmt cram") ? "cram" : "bam" - def reference = fasta ? "--reference ${fasta}" : "" - if ("${bam}" == "${prefix}.bam") { + def reference = in.fasta ? "--reference ${in.fasta}" : "" + if ("${in.bam}" == "${prefix}.bam") { error("Input and output names are the same, use \"prefix\" to disambiguate!") } """ samtools cat \\ - ${bam} \\ + ${in.bam} \\ | \\ samtools sort \\ ${args} \\ @@ -65,8 +65,8 @@ process SAMTOOLS_SORT { """ stub: - args = args ?: '' - prefix = prefix ?: id + args = in.args ?: '' + prefix = in.prefix ?: in.id def extension = args.contains("--output-fmt sam") ? "sam" : args.contains("--output-fmt cram") diff --git a/modules/nf-core/samtools/stats/main.nf b/modules/nf-core/samtools/stats/main.nf index 600d3e811..81872aa35 100644 --- a/modules/nf-core/samtools/stats/main.nf +++ b/modules/nf-core/samtools/stats/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process SAMTOOLS_STATS { - tag id + tag in.id label 'process_single' conda "${moduleDir}/environment.yml" @@ -10,16 +10,16 @@ process SAMTOOLS_STATS { : 'biocontainers/samtools:1.21--h50ea8bc_0'}" input: - ( - id: String, - input: Path, - input_index: Path, + in: Record { + id: String + input: Path + input_index: Path fasta: Path? - ): Record + } output: record( - id: id, + id: in.id, samtools_stats: file("*.stats") ) @@ -30,14 +30,14 @@ process SAMTOOLS_STATS { task.ext.when == null || task.ext.when script: - def prefix = task.ext.prefix ?: id - def reference = fasta ? "--reference ${fasta}" : "" + def prefix = task.ext.prefix ?: in.id + def reference = in.fasta ? "--reference ${in.fasta}" : "" """ samtools \\ stats \\ --threads ${task.cpus} \\ ${reference} \\ - ${input} \\ + ${in.input} \\ > ${prefix}.stats cat <<-END_VERSIONS > versions.yml @@ -47,7 +47,7 @@ process SAMTOOLS_STATS { """ stub: - def prefix = task.ext.prefix ?: id + def prefix = task.ext.prefix ?: in.id """ touch ${prefix}.stats diff --git a/modules/nf-core/trimgalore/main.nf b/modules/nf-core/trimgalore/main.nf index a31966da5..20964b1d6 100644 --- a/modules/nf-core/trimgalore/main.nf +++ b/modules/nf-core/trimgalore/main.nf @@ -1,7 +1,7 @@ nextflow.preview.types = true process TRIMGALORE { - tag id + tag in.id label 'process_high' conda "${moduleDir}/environment.yml" @@ -10,18 +10,18 @@ process TRIMGALORE { : 'community.wave.seqera.io/library/cutadapt_trim-galore_pigz:a98edd405b34582d'}" input: - ( - id: String, - single_end: Boolean, - reads: List, - args: String?, + in: Record { + id: String + single_end: Boolean + reads: List + args: String? prefix: String? - ): Record + } output: record( - id: id, - single_end: single_end, + id: in.id, + single_end: in.single_end, trim_reads : files("*{3prime,5prime,trimmed,val}{,_1,_2}.fq.gz").toSorted(), trim_log : files("*report.txt", optional: true).toSorted(), trim_unpaired : files("*unpaired{,_1,_2}.fq.gz", optional: true).toSorted(), @@ -36,14 +36,14 @@ process TRIMGALORE { task.ext.when == null || task.ext.when script: - args = args ?: '' + args = in.args ?: '' // Calculate number of --cores for TrimGalore based on value of task.cpus // See: https://github.com/FelixKrueger/TrimGalore/blob/master/CHANGELOG.md#version-060-release-on-1-mar-2019 // See: https://github.com/nf-core/atacseq/pull/65 def cores = 1 if (task.cpus) { cores = (task.cpus as int) - 4 - if (single_end) { + if (in.single_end) { cores = (task.cpus as int) - 3 } if (cores < 1) { @@ -55,12 +55,12 @@ process TRIMGALORE { } // Added soft-links to original fastqs for consistent naming in MultiQC - prefix = prefix ?: id - if (single_end) { + prefix = in.prefix ?: in.id + if (in.single_end) { def args_list = args.split("\\s(?=--)").toList() args_list.removeAll { it.toLowerCase().contains('_r2 ') } """ - [ ! -f ${prefix}.fastq.gz ] && ln -s ${reads[0]} ${prefix}.fastq.gz + [ ! -f ${prefix}.fastq.gz ] && ln -s ${in.reads[0]} ${prefix}.fastq.gz trim_galore \\ ${args_list.join(' ')} \\ --cores ${cores} \\ @@ -77,8 +77,8 @@ process TRIMGALORE { } else { """ - [ ! -f ${prefix}_1.fastq.gz ] && ln -s ${reads[0]} ${prefix}_1.fastq.gz - [ ! -f ${prefix}_2.fastq.gz ] && ln -s ${reads[1]} ${prefix}_2.fastq.gz + [ ! -f ${prefix}_1.fastq.gz ] && ln -s ${in.reads[0]} ${prefix}_1.fastq.gz + [ ! -f ${prefix}_2.fastq.gz ] && ln -s ${in.reads[1]} ${prefix}_2.fastq.gz trim_galore \\ ${args} \\ --cores ${cores} \\ @@ -97,8 +97,8 @@ process TRIMGALORE { } stub: - prefix = prefix ?: id - if (single_end) { + prefix = in.prefix ?: in.id + if (in.single_end) { output_command = "echo '' | gzip > ${prefix}_trimmed.fq.gz ;" output_command += "touch ${prefix}.fastq.gz_trimming_report.txt" } diff --git a/subworkflows/local/targeted_sequencing/main.nf b/subworkflows/local/targeted_sequencing/main.nf index 65852a92d..4ea7c47c9 100644 --- a/subworkflows/local/targeted_sequencing/main.nf +++ b/subworkflows/local/targeted_sequencing/main.nf @@ -6,13 +6,13 @@ * HS Library Size, Percent Duplicates, and Percent Off Bait. This is relevant for methylome experiments with targeted seq. */ +nextflow.preview.types = true + include { BEDTOOLS_INTERSECT } from '../../../modules/nf-core/bedtools/intersect/main' include { PICARD_CREATESEQUENCEDICTIONARY } from '../../../modules/nf-core/picard/createsequencedictionary/main' include { PICARD_BEDTOINTERVALLIST } from '../../../modules/nf-core/picard/bedtointervallist/main' include { PICARD_COLLECTHSMETRICS } from '../../../modules/nf-core/picard/collecthsmetrics/main' -include { combineWith ; joinById } from '../../../utils/ops.nf' - workflow TARGETED_SEQUENCING { take: @@ -36,9 +36,8 @@ workflow TARGETED_SEQUENCING { suffix: 'targeted.bedGraph' ) } - ch_intersect_inputs = combineWith(ch_intersect_inputs, intervals2: val_target_regions) - ch_results = BEDTOOLS_INTERSECT( ch_intersect_inputs ) + ch_results = BEDTOOLS_INTERSECT( ch_intersect_inputs.cross(intervals2: val_target_regions) ) /* * Run Picard CollectHSMetrics @@ -55,26 +54,24 @@ workflow TARGETED_SEQUENCING { * Conversion of the covered targets BED file to an interval list */ val_intervallist_inputs = val_target_regions.map { tr -> record(id: tr.baseName, bed: tr) } - val_intervallist_inputs = combineWith(val_intervallist_inputs, reference_dict: val_reference_dict) - val_intervallist = PICARD_BEDTOINTERVALLIST( val_intervallist_inputs ).map { r -> r.intervallist } + val_intervallist = PICARD_BEDTOINTERVALLIST( val_intervallist_inputs.cross(reference_dict: val_reference_dict) ).map { r -> r.intervallist } /* * Generation of the metrics * Note: Using the same intervals for both target and bait as they are typically * the same for targeted methylation sequencing experiments */ - ch_picard_inputs = combineWith( - ch_inputs, - bait_intervals: val_intervallist, - target_intervals: val_intervallist, - fasta: val_fasta, - fai: val_fasta_index, - reference_dict: val_reference_dict, - args: "--MINIMUM_MAPPING_QUALITY 20 --COVERAGE_CAP 1000 --NEAR_DISTANCE 500" + ch_picard_hsmetrics = PICARD_COLLECTHSMETRICS( + ch_inputs.cross( + bait_intervals: val_intervallist, + target_intervals: val_intervallist, + fasta: val_fasta, + fai: val_fasta_index, + reference_dict: val_reference_dict, + args: "--MINIMUM_MAPPING_QUALITY 20 --COVERAGE_CAP 1000 --NEAR_DISTANCE 500" + ) ) - - ch_picard_hsmetrics = PICARD_COLLECTHSMETRICS( ch_picard_inputs ) - ch_results = joinById(ch_results, ch_picard_hsmetrics) + ch_results = ch_results.join(ch_picard_hsmetrics, by: 'id') } else { val_reference_dict = null val_intervallist = null diff --git a/subworkflows/local/utils_nfcore_methylseq_pipeline/main.nf b/subworkflows/local/utils_nfcore_methylseq_pipeline/main.nf index 929ebf13d..fa162bdbc 100644 --- a/subworkflows/local/utils_nfcore_methylseq_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_methylseq_pipeline/main.nf @@ -2,6 +2,8 @@ // Subworkflow with functionality specific to the nf-core/methylseq pipeline // +nextflow.preview.types = true + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS @@ -73,7 +75,7 @@ workflow PIPELINE_INITIALISATION { // Create channel from input file provided through params.input // - channel.fromList(samplesheetToList(input, "${projectDir}/assets/schema_input.json")) + ch_samplesheet = channel.fromList(samplesheetToList(input, "${projectDir}/assets/schema_input.json")) .map { meta, fastq_1, fastq_2, genome -> def single_end = !fastq_2 @@ -81,12 +83,12 @@ workflow PIPELINE_INITIALISATION { def sample = record(id: meta.id, single_end: single_end, reads: reads) tuple(sample.id, sample) } - .groupTuple() + .groupBy() .map { id, samples -> validateInputSamplesheet(samples) } - .set { ch_samplesheet } - ch_samplesheet.dump(tag: "ch_samplesheet") + + ch_samplesheet.view(tag: "ch_samplesheet") emit: samplesheet = ch_samplesheet @@ -112,7 +114,6 @@ workflow PIPELINE_COMPLETION { main: summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") - def multiqc_reports = multiqc_report.toList() // // Completion email and summary @@ -126,7 +127,7 @@ workflow PIPELINE_COMPLETION { plaintext_email, outdir, monochrome_logs, - multiqc_reports.getVal(), + multiqc_report.getVal(), ) } diff --git a/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf b/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf index b245cd91b..68388fcaa 100644 --- a/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf +++ b/subworkflows/nf-core/fasta_index_bismark_bwameth/main.nf @@ -1,11 +1,11 @@ +nextflow.preview.types = true + include { UNTAR } from '../../../modules/nf-core/untar/main' include { GUNZIP } from '../../../modules/nf-core/gunzip/main' include { BISMARK_GENOMEPREPARATION } from '../../../modules/nf-core/bismark/genomepreparation/main' include { BWAMETH_INDEX } from '../../../modules/nf-core/bwameth/index/main' include { SAMTOOLS_FAIDX } from '../../../modules/nf-core/samtools/faidx/main' -include { combineWith } from '../../../utils/ops.nf' - include { MethylseqParams } from '../../../workflows/methylseq/main' def isGzipped(file: Path) -> Boolean { diff --git a/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf b/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf index 3ff96ae9c..19ea03e7d 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf +++ b/subworkflows/nf-core/fastq_align_dedup_bismark/main.nf @@ -1,3 +1,5 @@ +nextflow.preview.types = true + include { BISMARK_ALIGN } from '../../../modules/nf-core/bismark/align/main' include { BISMARK_DEDUPLICATE } from '../../../modules/nf-core/bismark/deduplicate/main' include { SAMTOOLS_SORT } from '../../../modules/nf-core/samtools/sort/main' @@ -8,7 +10,6 @@ include { BISMARK_REPORT } from '../../../modules/nf-core/bismark/ include { BISMARK_SUMMARY } from '../../../modules/nf-core/bismark/summary/main' include { Sample } from '../../../utils/types.nf' -include { combineWith ; joinById } from '../../../utils/ops.nf' workflow FASTQ_ALIGN_DEDUP_BISMARK { @@ -18,24 +19,24 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { val_bismark_index: Value skip_deduplication: Boolean cytosine_report: Boolean + params: Record main: /* * Align with bismark */ - ch_alignment_inputs = combineWith( ch_reads, fasta: val_fasta, bismark_index: val_bismark_index ) - ch_alignment_inputs = ch_alignment_inputs.map { r -> - r + record(args: bismarkAlignArgs(r)) + ch_alignment_inputs = ch_reads.map { r -> + r + record(args: bismarkAlignArgs(r, params)) } - ch_alignment = BISMARK_ALIGN( ch_alignment_inputs ) + ch_alignment = BISMARK_ALIGN( ch_alignment_inputs.cross(fasta: val_fasta, bismark_index: val_bismark_index) ) if (!skip_deduplication) { /* * Run deduplicate_bismark */ - ch_alignment_dedup = BISMARK_DEDUPLICATE( ch_alignment ) - ch_alignment_dedup = joinById(ch_alignment, ch_alignment_dedup) + ch_alignment_dedup = ch_alignment + .join( BISMARK_DEDUPLICATE( ch_alignment ) , by: 'id') } else { ch_alignment_dedup = ch_alignment } @@ -59,23 +60,22 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { /* * Run bismark_methylation_extractor */ - ch_methylation_inputs = combineWith(ch_alignment_dedup, bismark_index: val_bismark_index) - ch_methylation_inputs = ch_methylation_inputs.map { r -> - r + record(args: bismarkMethylationExtractorArgs(r)) + ch_methylation_inputs = ch_alignment_dedup.map { r -> + r + record(args: bismarkMethylationExtractorArgs(r, params)) } - ch_methylation = BISMARK_METHYLATIONEXTRACTOR( ch_methylation_inputs ) + ch_methylation = BISMARK_METHYLATIONEXTRACTOR( ch_methylation_inputs.cross(bismark_index: val_bismark_index) ) /* * Run bismark coverage2cytosine */ if (cytosine_report) { - ch_coverage2cytosine_inputs = combineWith( - ch_methylation, - fasta: val_fasta, - bismark_index: val_bismark_index, - args: params.nomeseq ? '--nome-seq' : '' + ch_coverage2cytosine = BISMARK_COVERAGE2CYTOSINE( + ch_methylation.cross( + fasta: val_fasta, + bismark_index: val_bismark_index, + args: params.nomeseq ? '--nome-seq' : '' + ) ) - ch_coverage2cytosine = BISMARK_COVERAGE2CYTOSINE( ch_coverage2cytosine_inputs ) } else { ch_coverage2cytosine = channel.empty() } @@ -84,26 +84,27 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { * Generate bismark sample reports */ ch_bismark_report = BISMARK_REPORT( - joinById(ch_alignment_dedup, ch_methylation) + ch_alignment_dedup.join(ch_methylation, by: 'id') ) /* * Collect per-sample results */ ch_results = ch_alignment_dedup - ch_results = joinById(ch_results, ch_bam) - ch_results = joinById(ch_results, ch_bai) - ch_results = joinById(ch_results, ch_coverage2cytosine) - ch_results = joinById(ch_results, ch_methylation) - ch_results = joinById(ch_results, ch_bismark_report) + .join(ch_bam, by: 'id') + .join(ch_bai, by: 'id') + .join(ch_coverage2cytosine, by: 'id', remainder: true) + .join(ch_methylation, by: 'id') + .join(ch_bismark_report, by: 'id') /* * Generate bismark summary report */ ch_bam_name = ch_alignment.map { r -> record(id: r.id, bam_name: r.bam.name) } - ch_bismark_summary_inputs = joinById(ch_alignment_dedup, ch_methylation) - ch_bismark_summary_inputs = joinById(ch_bismark_summary_inputs, ch_bam_name) + ch_bismark_summary_inputs = ch_alignment_dedup + .join(ch_methylation, by: 'id') + .join(ch_bam_name, by: 'id') .collect() .map { rs -> record( @@ -133,7 +134,7 @@ workflow FASTQ_ALIGN_DEDUP_BISMARK { } -def bismarkAlignArgs(r: Record) { +def bismarkAlignArgs(r: Record, params: Record) { [ params.aligner == 'bismark_hisat' ? ' --hisat2' : ' --bowtie2', params.aligner == 'bismark_hisat' && params.known_splices ? " --known-splicesite-infile <(hisat2_extract_splice_sites.py ${params.known_splices})" : '', @@ -152,7 +153,7 @@ def bismarkAlignArgs(r: Record) { } -def bismarkMethylationExtractorArgs(r: Record) { +def bismarkMethylationExtractorArgs(r: Record, params: Record) { [ params.comprehensive ? ' --comprehensive' : '', params.meth_cutoff ? " --cutoff ${params.meth_cutoff}" : '', diff --git a/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf b/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf index be65a4295..ce7582036 100644 --- a/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf +++ b/subworkflows/nf-core/fastq_align_dedup_bwameth/main.nf @@ -1,3 +1,6 @@ + +nextflow.preview.types = true + include { BWAMETH_ALIGN } from '../../../modules/nf-core/bwameth/align/main' include { PARABRICKS_FQ2BAMMETH } from '../../../modules/nf-core/parabricks/fq2bammeth/main' include { SAMTOOLS_SORT } from '../../../modules/nf-core/samtools/sort/main' @@ -10,7 +13,6 @@ include { METHYLDACKEL_EXTRACT } from '../../../modules include { METHYLDACKEL_MBIAS } from '../../../modules/nf-core/methyldackel/mbias/main' include { Sample } from '../../../utils/types.nf' -include { combineWith ; joinById } from '../../../utils/ops.nf' workflow FASTQ_ALIGN_DEDUP_BWAMETH { @@ -21,25 +23,28 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { val_bwameth_index: Value skip_deduplication: Boolean use_gpu: Boolean + params: Record main: /* * Align with bwameth */ - ch_bwameth_inputs = combineWith(ch_reads, fasta: val_fasta, bwameth_index: val_bwameth_index) if (use_gpu) { /* * Align with parabricks GPU enabled fq2bammeth implementation of bwameth */ - ch_bwameth_inputs = combineWith(ch_bwameth_inputs, args: '--low-memory') - ch_alignment = PARABRICKS_FQ2BAMMETH ( ch_bwameth_inputs ) + ch_alignment = PARABRICKS_FQ2BAMMETH ( + ch_reads.cross(fasta: val_fasta, bwameth_index: val_bwameth_index, args: '--low-memory') + ) } else { /* * Align with CPU version of bwameth */ - ch_alignment = BWAMETH_ALIGN ( ch_bwameth_inputs ) + ch_alignment = BWAMETH_ALIGN ( + ch_reads.cross(fasta: val_fasta, bwameth_index: val_bwameth_index) + ) } /* @@ -54,8 +59,10 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { /* * Run samtools index on alignment */ - ch_alignment_index = SAMTOOLS_INDEX_ALIGNMENTS( ch_alignment ) - ch_alignment = joinById(ch_alignment, ch_alignment_index) + ch_alignment_index = SAMTOOLS_INDEX_ALIGNMENTS( + ch_alignment.map { r -> record(id: r.id, input: r.bam) } + ) + ch_alignment = ch_alignment.join(ch_alignment_index, by: 'id') /* * Run samtools flagstat @@ -69,43 +76,47 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { ch_alignment.map { r -> record(id: r.id, input: r.bam, input_index: r.bai) } ) - ch_alignment_fasta = combineWith(ch_alignment, fasta: val_fasta, fasta_index: val_fasta_index) - if (!skip_deduplication) { /* * Run Picard MarkDuplicates */ - ch_picard_inputs = ch_alignment_fasta.map { r -> + ch_picard_inputs = ch_alignment.map { r -> def args = "--ASSUME_SORTED true --REMOVE_DUPLICATES false --VALIDATION_STRINGENCY LENIENT --PROGRAM_RECORD_ID 'null' --TMP_DIR tmp" def prefix = "${r.id}.markdup.sorted" r + record(args: args, prefix: prefix) } - ch_picard = PICARD_MARKDUPLICATES( ch_alignment_fasta ) + ch_picard = PICARD_MARKDUPLICATES( + ch_picard_inputs.cross(fasta: val_fasta, fasta_index: val_fasta_index) + ) /* * Run samtools index on deduplicated alignment */ ch_alignment_index_dedup = SAMTOOLS_INDEX_DEDUPLICATED( ch_picard.map { r -> record(id: r.id, input: r.bam) } ) - ch_alignment = joinById(ch_alignment_fasta, ch_picard) - ch_alignment = joinById(ch_alignment, ch_alignment_index_dedup) + ch_alignment = ch_alignment + .join(ch_picard, by: 'id') + .join(ch_alignment_index_dedup, by: 'id') } /* * Extract per-base methylation and plot methylation bias */ - ch_methydackel_extract_inputs = combineWith(ch_alignment_fasta, args: methyldackelExtractArgs()) - ch_methydackel_extract = METHYLDACKEL_EXTRACT ( ch_methydackel_extract_inputs ) + ch_methydackel_extract = METHYLDACKEL_EXTRACT ( + ch_alignment.cross(fasta: val_fasta, fasta_index: val_fasta_index, args: methyldackelExtractArgs(params)) + ) - ch_methydackel_mbias_inputs = combineWith(ch_alignment_fasta, args: methyldackelMbiasArgs()) - ch_methydackel_mbias = METHYLDACKEL_MBIAS ( ch_methydackel_mbias_inputs ) + ch_methydackel_mbias = METHYLDACKEL_MBIAS ( + ch_alignment.cross(fasta: val_fasta, fasta_index: val_fasta_index, args: methyldackelMbiasArgs(params)) + ) - ch_results = joinById(ch_alignment, ch_samtools_flagstat) - ch_results = joinById(ch_results, ch_samtools_stats) - ch_results = joinById(ch_results, ch_methydackel_extract) - ch_results = joinById(ch_results, ch_methydackel_mbias) - ch_results = joinById(ch_results, ch_picard) + ch_results = ch_alignment + .join(ch_samtools_flagstat, by: 'id') + .join(ch_samtools_stats, by: 'id') + .join(ch_methydackel_extract, by: 'id') + .join(ch_methydackel_mbias, by: 'id') + .join(ch_picard, by: 'id', remainder: true) /* * Collect MultiQC inputs @@ -123,7 +134,7 @@ workflow FASTQ_ALIGN_DEDUP_BWAMETH { } -def methyldackelExtractArgs() { +def methyldackelExtractArgs(params: Record) { [ params.all_contexts ? ' --CHG --CHH' : '', params.merge_context ? ' --mergeContext' : '', @@ -134,7 +145,7 @@ def methyldackelExtractArgs() { } -def methyldackelMbiasArgs() { +def methyldackelMbiasArgs(params: Record) { [ params.all_contexts ? ' --CHG --CHH' : '', params.ignore_flags ? " --ignoreFlags" : '' diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf index 2f30e9a46..28d6286a7 100644 --- a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf @@ -2,6 +2,8 @@ // Subworkflow with utility functions specific to the nf-core pipeline template // +nextflow.preview.types = true + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SUBWORKFLOW DEFINITION diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config index 09ef842ae..d1713539c 100644 --- a/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config @@ -1,5 +1,5 @@ plugins { - id "nf-schema@2.4.2" + id "nf-schema@2.6.1" } validation { diff --git a/utils/ops.nf b/utils/ops.nf deleted file mode 100644 index 3d90346e8..000000000 --- a/utils/ops.nf +++ /dev/null @@ -1,27 +0,0 @@ - -// Utility functions for common dataflow operations with records -// Will be replaced by v2 operators - -def combineWith(opts, source) { - def result = source - opts.each { name, value -> - result = result - .combine(value) - .map { r, v -> r + record([(name): v]) } - } - return result -} - -def groupById(source) { - tupleWithId(source).groupTuple() -} - -def joinById(left, right) { - tupleWithId(left) - .join( tupleWithId(right) ) - .map { _id, r1, r2 -> r1 + r2 } -} - -def tupleWithId(source) { - source.map { r -> tuple(r.id, r) } -} diff --git a/workflows/methylseq/main.nf b/workflows/methylseq/main.nf index 6ef200179..d9f3f2216 100644 --- a/workflows/methylseq/main.nf +++ b/workflows/methylseq/main.nf @@ -4,6 +4,8 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +nextflow.preview.types = true + include { paramsSummaryMap } from 'plugin/nf-schema' include { FASTQC } from '../../modules/nf-core/fastqc/main' include { TRIMGALORE } from '../../modules/nf-core/trimgalore/main' @@ -20,7 +22,6 @@ include { methodsDescriptionText } from '../../subworkflows/local/utils_nfco include { validateInputSamplesheet } from '../../subworkflows/local/utils_nfcore_methylseq_pipeline' include { Sample } from '../../utils/types.nf' -include { combineWith ; joinById } from '../../utils/ops.nf' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -84,55 +85,48 @@ workflow METHYLSEQ { // // Run Bismark alignment + downstream processing // - FASTQ_ALIGN_DEDUP_BISMARK ( + bismark = FASTQ_ALIGN_DEDUP_BISMARK ( ch_reads, val_fasta, val_bismark_index, params.skip_deduplication || params.rrbs, - params.cytosine_report || params.nomeseq + params.cytosine_report || params.nomeseq, + params ) - ch_alignment = FASTQ_ALIGN_DEDUP_BISMARK.out.results - val_bismark_summary = FASTQ_ALIGN_DEDUP_BISMARK.out.bismark_summary - ch_aligner_mqc = FASTQ_ALIGN_DEDUP_BISMARK.out.multiqc + ch_alignment = bismark.results + val_bismark_summary = bismark.bismark_summary + ch_aligner_mqc = bismark.multiqc } // Aligner: bwameth else if ( params.aligner == 'bwameth' && val_fasta && val_fasta_index && val_bwameth_index ) { - FASTQ_ALIGN_DEDUP_BWAMETH ( + bwameth = FASTQ_ALIGN_DEDUP_BWAMETH ( ch_reads, val_fasta, val_fasta_index, val_bwameth_index, params.skip_deduplication || params.rrbs, - workflow.profile.tokenize(',').intersect(['gpu']).size() >= 1 + workflow.profile.tokenize(',').intersect(['gpu']).size() >= 1, + params ) - ch_alignment = FASTQ_ALIGN_DEDUP_BWAMETH.out.results - ch_aligner_mqc = FASTQ_ALIGN_DEDUP_BWAMETH.out.multiqc + ch_alignment = bwameth.results + ch_aligner_mqc = bwameth.multiqc } else { error "ERROR: Invalid aligner '${params.aligner}'. Valid options are: 'bismark', 'bismark_hisat', or 'bwameth'" } - ch_results = ch_alignment - if (params.skip_fastqc) { - ch_results = joinById(ch_results, ch_fastqc) - } - if (params.skip_trimming) { - ch_results = joinById(ch_results, ch_trimmed_fastq) - } - // // MODULE: Qualimap BamQC // skipped by default. to use run with `--run_qualimap` param. // if(params.run_qualimap) { - ch_qualimap_inputs = combineWith( - ch_alignment, - gff: params.bamqc_regions_file ? file( params.bamqc_regions_file, checkIfExists: true ) : null, - args: qualimapArgs(params) + ch_qualimap = QUALIMAP_BAMQC ( + ch_alignment.cross( + gff: params.bamqc_regions_file ? file( params.bamqc_regions_file, checkIfExists: true ) : null, + args: qualimapArgs(params) + ) ) - ch_qualimap = QUALIMAP_BAMQC ( ch_qualimap_inputs ) - ch_results = joinById(ch_results, ch_qualimap) } else { ch_qualimap = channel.empty() } @@ -145,17 +139,16 @@ workflow METHYLSEQ { if (!params.target_regions_file) { error "ERROR: --target_regions_file must be specified when using --run_targeted_sequencing" } - TARGETED_SEQUENCING ( + targeted_sequencing = TARGETED_SEQUENCING ( ch_alignment, channel.value(file(params.target_regions_file, checkIfExists: true)), val_fasta, val_fasta_index, params.collecthsmetrics ) - ch_targeted_sequencing = TARGETED_SEQUENCING.out.results - val_reference_dict = TARGETED_SEQUENCING.out.reference_dict - val_intervallist = TARGETED_SEQUENCING.out.intervallist - ch_results = joinById(ch_results, ch_targeted_sequencing) + ch_targeted_sequencing = targeted_sequencing.results + val_reference_dict = targeted_sequencing.reference_dict + val_intervallist = targeted_sequencing.intervallist } else { ch_targeted_sequencing = channel.empty() val_reference_dict = null @@ -167,23 +160,29 @@ workflow METHYLSEQ { // skipped by default. to use run with `--run_preseq` param. // if(params.run_preseq) { - ch_preseq_inputs = combineWith(ch_alignment, args: " -verbose -bam") - ch_preseq = PRESEQ_LCEXTRAP (ch_preseq_inputs) - ch_results = joinById(ch_results, ch_preseq) + ch_preseq = PRESEQ_LCEXTRAP ( ch_alignment.cross(args: " -verbose -bam") ) } else { ch_preseq = channel.empty() } + ch_results = ch_alignment + .join(ch_fastqc, by: 'id', remainder: true) + .join(ch_trimmed_fastq, by: 'id', remainder: true) + .join(ch_qualimap, by: 'id', remainder: true) + .join(ch_targeted_sequencing, by: 'id', remainder: true) + .join(ch_preseq, by: 'id', remainder: true) + // // Collate and save software versions // - ch_collated_versions = softwareVersionsToYAML( channel.topic('versions') ) - .collectFile( - storeDir: "${params.outdir}/pipeline_info", - name: 'nf_core_' + 'methylseq_software_' + 'mqc_' + 'versions.yml', - sort: true, - newLine: true - ) + // TODO + // ch_collated_versions = softwareVersionsToYAML( channel.topic('versions') ) + // .collectFile( + // storeDir: "${params.outdir}/pipeline_info", + // name: 'nf_core_' + 'methylseq_software_' + 'mqc_' + 'versions.yml', + // sort: true, + // newLine: true + // ) // // MODULE: MultiQC @@ -201,24 +200,25 @@ workflow METHYLSEQ { file("$projectDir/assets/methods_description_template.yml", checkIfExists: true) ch_methods_description = channel.value(methodsDescriptionText(ch_multiqc_custom_methods_description)) - ch_multiqc_files = ch_multiqc_files.mix(ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) - ch_multiqc_files = ch_multiqc_files.mix(ch_collated_versions) - ch_multiqc_files = ch_multiqc_files.mix( - ch_methods_description.collectFile( - name: 'methods_description_mqc.yaml', - sort: true - ) - ) + // TODO + // ch_multiqc_files = ch_multiqc_files.mix(ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) + // ch_multiqc_files = ch_multiqc_files.mix(ch_collated_versions) + // ch_multiqc_files = ch_multiqc_files.mix( + // ch_methods_description.collectFile( + // name: 'methods_description_mqc.yaml', + // sort: true + // ) + // ) if(params.run_qualimap) { ch_multiqc_files = ch_multiqc_files.mix(ch_qualimap.map { r -> r.qualimap_bamqc }) } if (params.run_preseq) { - ch_multiqc_files = ch_multiqc_files.mix(ch_preseq.map { r -> r.log }) + ch_multiqc_files = ch_multiqc_files.mix(ch_preseq.map { r -> r.lc_log }) } ch_multiqc_files = ch_multiqc_files.mix(ch_aligner_mqc) if (!params.skip_trimming) { - ch_multiqc_files = ch_multiqc_files.mix(ch_reads.map { r -> r.log }) + ch_multiqc_files = ch_multiqc_files.mix(ch_reads.map { r -> r.trim_log }) } if (params.run_targeted_sequencing && params.collecthsmetrics) { ch_multiqc_files = ch_multiqc_files.mix(ch_targeted_sequencing.map { r -> r.picard_hsmetrics }) @@ -351,8 +351,8 @@ record MethylseqResult { single_end : Boolean // fastqc - fastqc_html : Path - fastqc_zip : Path + fastqc_html : Set + fastqc_zip : Set // trimgalore trim_reads : List