From 607cf39da6bde3ecfc5987d06a4cc333164496a4 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Fri, 17 Dec 2021 17:13:25 +0000 Subject: [PATCH 01/36] Bump pipeline version to 3.6dev --- CHANGELOG.md | 8 ++++++-- nextflow.config | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fefe1818a..f7138b6ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unpublished Version / DEV] + +### Enhancements & fixes + +### Parameters + ## [[3.5](https://github.com/nf-core/rnaseq/releases/tag/3.5)] - 2021-12-17 ### Enhancements & fixes @@ -18,8 +24,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [[#727](https://github.com/nf-core/rnaseq/issues/727)] - Fix transcriptome staging issues on DNAnexus for rsem/prepareference * [[#728](https://github.com/nf-core/rnaseq/issues/728)] - Add RSeQC TIN.py as a quality metric for the pipeline -### Parameters - ## [[3.4](https://github.com/nf-core/rnaseq/releases/tag/3.4)] - 2021-10-05 ### Enhancements & fixes diff --git a/nextflow.config b/nextflow.config index 5964f6e51..77551e669 100644 --- a/nextflow.config +++ b/nextflow.config @@ -224,7 +224,7 @@ manifest { description = 'Nextflow RNA-Seq analysis pipeline, part of the nf-core community.' mainScript = 'main.nf' nextflowVersion = '!>=21.10.3' - version = '3.5' + version = '3.6dev' } // Load modules.config for DSL2 module specific options From 3fdd6641e9a6348a62c6055afb512192e81f8627 Mon Sep 17 00:00:00 2001 From: Mahesh Binzer-Panchal Date: Thu, 10 Feb 2022 09:25:00 +0000 Subject: [PATCH 02/36] Patch RSEM_PREPAREREFERENCE configuration --- conf/modules.config | 2 +- conf/test.config | 2 +- subworkflows/local/prepare_genome.nf | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 59b051fc4..88dbb4d26 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -94,7 +94,7 @@ process { ] } - withName: RSEM_PREPAREREFERENCE { + withName: RSEM_PREPAREREFERENCE_GENOME { ext.args = '--star' publishDir = [ path: { "${params.outdir}/genome/index" }, diff --git a/conf/test.config b/conf/test.config index 1b24f3c57..80f83f129 100644 --- a/conf/test.config +++ b/conf/test.config @@ -43,7 +43,7 @@ params { // When using RSEM, remove warning from STAR whilst building tiny indices process { - withName: 'RSEM_PREPAREREFERENCE' { + withName: 'RSEM_PREPAREREFERENCE_GENOME' { ext.args2 = "--genomeSAindexNbases 7" } } diff --git a/subworkflows/local/prepare_genome.nf b/subworkflows/local/prepare_genome.nf index 7574775fa..ca917c099 100644 --- a/subworkflows/local/prepare_genome.nf +++ b/subworkflows/local/prepare_genome.nf @@ -20,7 +20,7 @@ include { BBMAP_BBSPLIT } from '../../modules/nf-core/module include { HISAT2_EXTRACTSPLICESITES } from '../../modules/nf-core/modules/hisat2/extractsplicesites/main' include { HISAT2_BUILD } from '../../modules/nf-core/modules/hisat2/build/main' include { SALMON_INDEX } from '../../modules/nf-core/modules/salmon/index/main' -include { RSEM_PREPAREREFERENCE as RSEM_PREPAREREFERENCE } from '../../modules/nf-core/modules/rsem/preparereference/main' +include { RSEM_PREPAREREFERENCE as RSEM_PREPAREREFERENCE_GENOME } from '../../modules/nf-core/modules/rsem/preparereference/main' include { RSEM_PREPAREREFERENCE as RSEM_PREPAREREFERENCE_TRANSCRIPTS } from '../../modules/nf-core/modules/rsem/preparereference/main' include { GTF2BED } from '../../modules/local/gtf2bed' @@ -182,8 +182,8 @@ workflow PREPARE_GENOME { ch_rsem_index = file(params.rsem_index) } } else { - ch_rsem_index = RSEM_PREPAREREFERENCE ( ch_fasta, ch_gtf ).index - ch_versions = ch_versions.mix(RSEM_PREPAREREFERENCE.out.versions) + ch_rsem_index = RSEM_PREPAREREFERENCE_GENOME ( ch_fasta, ch_gtf ).index + ch_versions = ch_versions.mix(RSEM_PREPAREREFERENCE_GENOME.out.versions) } } From 7f14e06f7d066efbe6a0bc7509fdf7a1c31d6ce2 Mon Sep 17 00:00:00 2001 From: Mahesh Binzer-Panchal Date: Thu, 10 Feb 2022 12:01:07 +0100 Subject: [PATCH 03/36] Rename RSEM_PREPAREREFERENCE_TRANSCRIPTS to MAKE_TRANSCRIPTS_FASTA Co-authored-by: Harshil Patel --- conf/modules.config | 2 +- subworkflows/local/prepare_genome.nf | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 88dbb4d26..cfff06b0f 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -43,7 +43,7 @@ process { // process { - withName: 'GUNZIP_.*|RSEM_PREPAREREFERENCE_TRANSCRIPTS' { + withName: 'GUNZIP_.*|MAKE_TRANSCRIPTS_FASTA' { publishDir = [ path: { "${params.outdir}/genome" }, mode: 'copy', diff --git a/subworkflows/local/prepare_genome.nf b/subworkflows/local/prepare_genome.nf index ca917c099..2f08d2b40 100644 --- a/subworkflows/local/prepare_genome.nf +++ b/subworkflows/local/prepare_genome.nf @@ -21,7 +21,7 @@ include { HISAT2_EXTRACTSPLICESITES } from '../../modules/nf-core/module include { HISAT2_BUILD } from '../../modules/nf-core/modules/hisat2/build/main' include { SALMON_INDEX } from '../../modules/nf-core/modules/salmon/index/main' include { RSEM_PREPAREREFERENCE as RSEM_PREPAREREFERENCE_GENOME } from '../../modules/nf-core/modules/rsem/preparereference/main' -include { RSEM_PREPAREREFERENCE as RSEM_PREPAREREFERENCE_TRANSCRIPTS } from '../../modules/nf-core/modules/rsem/preparereference/main' +include { RSEM_PREPAREREFERENCE as MAKE_TRANSCRIPTS_FASTA } from '../../modules/nf-core/modules/rsem/preparereference/main' include { GTF2BED } from '../../modules/local/gtf2bed' include { CAT_ADDITIONAL_FASTA } from '../../modules/local/cat_additional_fasta' @@ -113,9 +113,9 @@ workflow PREPARE_GENOME { } } else { ch_filter_gtf = GTF_GENE_FILTER ( ch_fasta, ch_gtf ).gtf - ch_transcript_fasta = RSEM_PREPAREREFERENCE_TRANSCRIPTS ( ch_fasta, ch_filter_gtf ).transcript_fasta + ch_transcript_fasta = MAKE_TRANSCRIPTS_FASTA ( ch_fasta, ch_filter_gtf ).transcript_fasta ch_versions = ch_versions.mix(GTF_GENE_FILTER.out.versions) - ch_versions = ch_versions.mix(RSEM_PREPAREREFERENCE_TRANSCRIPTS.out.versions) + ch_versions = ch_versions.mix(MAKE_TRANSCRIPTS_FASTA.out.versions) } // From 4142ec80ce509e63ca3f6e22a441db49b2e90ca4 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 14 Feb 2022 16:49:57 +0000 Subject: [PATCH 04/36] Simplify process selectors in modules.config and quote everything --- conf/modules.config | 66 ++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index cfff06b0f..75d4ed984 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -21,7 +21,7 @@ process { saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] - withName: 'NFCORE_RNASEQ:RNASEQ:INPUT_CHECK:SAMPLESHEET_CHECK' { + withName: 'SAMPLESHEET_CHECK' { publishDir = [ path: { "${params.outdir}/pipeline_info" }, mode: 'copy', @@ -29,7 +29,7 @@ process { ] } - withName: CUSTOM_DUMPSOFTWAREVERSIONS { + withName: 'CUSTOM_DUMPSOFTWAREVERSIONS' { publishDir = [ path: { "${params.outdir}/pipeline_info" }, mode: 'copy', @@ -65,7 +65,7 @@ process { ] } - withName: GFFREAD { + withName: 'GFFREAD' { ext.args = '--keep-exon-attrs -F -T' publishDir = [ path: { "${params.outdir}/genome" }, @@ -75,7 +75,7 @@ process { ] } - withName: HISAT2_EXTRACTSPLICESITES { + withName: 'HISAT2_EXTRACTSPLICESITES' { publishDir = [ path: { "${params.outdir}/genome/index" }, mode: 'copy', @@ -84,7 +84,7 @@ process { ] } - withName: SALMON_INDEX { + withName: 'SALMON_INDEX' { ext.args = params.gencode ? '--gencode' : '' publishDir = [ path: { "${params.outdir}/genome/index" }, @@ -94,7 +94,7 @@ process { ] } - withName: RSEM_PREPAREREFERENCE_GENOME { + withName: 'RSEM_PREPAREREFERENCE_GENOME' { ext.args = '--star' publishDir = [ path: { "${params.outdir}/genome/index" }, @@ -104,7 +104,7 @@ process { ] } - withName: GTF2BED { + withName: 'GTF2BED' { publishDir = [ path: { "${params.outdir}/genome" }, mode: 'copy', @@ -113,7 +113,7 @@ process { ] } - withName: CAT_ADDITIONAL_FASTA { + withName: 'CAT_ADDITIONAL_FASTA' { publishDir = [ path: { "${params.outdir}/genome" }, mode: 'copy', @@ -122,7 +122,7 @@ process { ] } - withName: GTF_GENE_FILTER { + withName: 'GTF_GENE_FILTER' { publishDir = [ path: { "${params.outdir}/genome" }, mode: 'copy', @@ -131,7 +131,7 @@ process { ] } - withName: GET_CHROM_SIZES { + withName: 'GET_CHROM_SIZES' { publishDir = [ path: { "${params.outdir}/genome" }, mode: 'copy', @@ -140,7 +140,7 @@ process { ] } - withName: CAT_FASTQ { + withName: 'CAT_FASTQ' { publishDir = [ path: { "${params.outdir}/fastq" }, mode: 'copy', @@ -235,7 +235,7 @@ if (params.with_umi) { if (!params.skip_bbsplit) { process { - withName: 'NFCORE_RNASEQ:RNASEQ:BBMAP_BBSPLIT' { + withName: 'BBMAP_BBSPLIT' { ext.args = 'build=1 ambiguous2=all maxindel=150000' publishDir = [ [ @@ -256,7 +256,7 @@ if (!params.skip_bbsplit) { if (params.remove_ribo_rna) { process { - withName: SORTMERNA { + withName: 'SORTMERNA' { ext.args = '--num_alignments 1 --fastx -v' publishDir = [ [ @@ -281,7 +281,7 @@ if (params.remove_ribo_rna) { if (!params.skip_alignment) { process { - withName: 'NFCORE_RNASEQ:RNASEQ:.*:BAM_SORT_SAMTOOLS:BAM_STATS_SAMTOOLS:.*' { + withName: '.*:.*:.*:BAM_SORT_SAMTOOLS:BAM_STATS_SAMTOOLS:.*' { publishDir = [ path: { "${params.outdir}/${params.aligner}/samtools_stats" }, mode: 'copy', @@ -289,7 +289,7 @@ if (!params.skip_alignment) { ] } - withName: 'NFCORE_RNASEQ:RNASEQ:.*:BAM_SORT_SAMTOOLS:SAMTOOLS_SORT' { + withName: '.*:.*:.*:BAM_SORT_SAMTOOLS:SAMTOOLS_SORT' { ext.prefix = { "${meta.id}.sorted" } publishDir = [ path: { "${params.outdir}/${params.aligner}" }, @@ -303,7 +303,7 @@ if (!params.skip_alignment) { ] } - withName: 'NFCORE_RNASEQ:RNASEQ:.*:BAM_SORT_SAMTOOLS:SAMTOOLS_INDEX' { + withName: '.*:.*:.*:BAM_SORT_SAMTOOLS:SAMTOOLS_INDEX' { ext.args = params.bam_csi_index ? '-c' : '' publishDir = [ path: { "${params.outdir}/${params.aligner}" }, @@ -407,7 +407,7 @@ if (!params.skip_alignment) { if (!params.skip_bigwig) { process { - withName: BEDTOOLS_GENOMECOV { + withName: 'BEDTOOLS_GENOMECOV' { ext.args = '-split -du' publishDir = [ path: { "${params.outdir}/bedtools/${meta.id}" }, @@ -453,7 +453,7 @@ if (!params.skip_alignment) { if (!params.skip_stringtie) { process { - withName: STRINGTIE { + withName: 'STRINGTIE' { ext.args = [ '-v', params.stringtie_ignore_gtf ? '' : '-e' @@ -469,7 +469,7 @@ if (!params.skip_alignment) { if (params.aligner.contains('star')) { process { - withName: MULTIQC_TSV_FAIL_MAPPED { + withName: 'MULTIQC_TSV_FAIL_MAPPED' { publishDir = [ path: { "${params.outdir}/multiqc" }, enabled: false @@ -554,7 +554,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { if (params.with_umi) { process { - withName: 'NFCORE_RNASEQ:RNASEQ:SAMTOOLS_SORT' { + withName: '.*:.*:SAMTOOLS_SORT' { ext.args = '-n' ext.prefix = { "${meta.id}.umi_dedup.transcriptome" } publishDir = [ @@ -563,7 +563,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { ] } - withName: 'NFCORE_RNASEQ:RNASEQ:BAM_SORT_SAMTOOLS:SAMTOOLS_SORT' { + withName: '.*:.*:BAM_SORT_SAMTOOLS:SAMTOOLS_SORT' { ext.prefix = { "${meta.id}.transcriptome.sorted" } publishDir = [ path: { "${params.outdir}/${params.aligner}" }, @@ -571,14 +571,14 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { ] } - withName: 'NFCORE_RNASEQ:RNASEQ:BAM_SORT_SAMTOOLS:SAMTOOLS_INDEX' { + withName: '.*:.*:BAM_SORT_SAMTOOLS:SAMTOOLS_INDEX' { publishDir = [ path: { "${params.outdir}/${params.aligner}" }, enabled: false ] } - withName: 'NFCORE_RNASEQ:RNASEQ:BAM_SORT_SAMTOOLS:BAM_STATS_SAMTOOLS:.*' { + withName: '.*:.*:BAM_SORT_SAMTOOLS:BAM_STATS_SAMTOOLS:.*' { publishDir = [ path: { "${params.outdir}/${params.aligner}" }, enabled: false @@ -613,7 +613,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { if (!params.skip_qc & !params.skip_deseq2_qc) { process { - withName: DESEQ2_QC_STAR_SALMON { + withName: 'DESEQ2_QC_STAR_SALMON' { ext.args = [ "--id_col 1", "--sample_suffix ''", @@ -677,7 +677,7 @@ if (!params.skip_alignment && params.aligner == 'star_rsem') { if (!params.skip_qc & !params.skip_deseq2_qc) { process { - withName: DESEQ2_QC_RSEM { + withName: 'DESEQ2_QC_RSEM' { ext.args = [ "--id_col 1", "--sample_suffix ''", @@ -734,7 +734,7 @@ if (!params.skip_alignment && params.aligner == 'hisat2') { if (!params.skip_alignment && !params.skip_qc) { if (!params.skip_preseq) { process { - withName: PRESEQ_LCEXTRAP { + withName: 'PRESEQ_LCEXTRAP' { ext.args = '-verbose -bam -seed 1 -seg_len 100000000' publishDir = [ [ @@ -754,7 +754,7 @@ if (!params.skip_alignment && !params.skip_qc) { if (!params.skip_qualimap) { process { - withName: QUALIMAP_RNASEQ { + withName: 'QUALIMAP_RNASEQ' { publishDir = [ path: { "${params.outdir}/${params.aligner}/qualimap" }, mode: 'copy', @@ -766,7 +766,7 @@ if (!params.skip_alignment && !params.skip_qc) { if (!params.skip_dupradar) { process { - withName: DUPRADAR { + withName: 'DUPRADAR' { publishDir = [ [ path: { "${params.outdir}/${params.aligner}/dupradar/scatter_plot" }, @@ -800,7 +800,7 @@ if (!params.skip_alignment && !params.skip_qc) { if (!params.skip_biotype_qc && params.featurecounts_group_type) { process { - withName: SUBREAD_FEATURECOUNTS { + withName: 'SUBREAD_FEATURECOUNTS' { ext.args = [ '-B -C', params.gencode ? "-g gene_type" : "-g $params.featurecounts_group_type", @@ -813,7 +813,7 @@ if (!params.skip_alignment && !params.skip_qc) { ] } - withName: MULTIQC_CUSTOM_BIOTYPE { + withName: 'MULTIQC_CUSTOM_BIOTYPE' { publishDir = [ path: { "${params.outdir}/${params.aligner}/featurecounts" }, mode: 'copy', @@ -945,7 +945,7 @@ if (!params.skip_alignment && !params.skip_qc) { } } - withName: MULTIQC_TSV_STRAND_CHECK { + withName: 'MULTIQC_TSV_STRAND_CHECK' { publishDir = [ path: { "${params.outdir}/multiqc" }, enabled: false @@ -957,7 +957,7 @@ if (!params.skip_alignment && !params.skip_qc) { if (!params.skip_multiqc) { process { - withName: MULTIQC { + withName: 'MULTIQC' { ext.args = params.multiqc_title ? "--title \"$params.multiqc_title\"" : '' publishDir = [ path: { [ @@ -1012,7 +1012,7 @@ if (params.pseudo_aligner == 'salmon') { if (!params.skip_qc & !params.skip_deseq2_qc) { process { - withName: DESEQ2_QC_SALMON { + withName: 'DESEQ2_QC_SALMON' { ext.args = [ "--id_col 1", "--sample_suffix ''", From 684b4f4e8d31647e16a7ad98b2e8692457277ec9 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 14 Feb 2022 16:50:08 +0000 Subject: [PATCH 05/36] Adjust spacing --- subworkflows/local/prepare_genome.nf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subworkflows/local/prepare_genome.nf b/subworkflows/local/prepare_genome.nf index 2f08d2b40..710d891c0 100644 --- a/subworkflows/local/prepare_genome.nf +++ b/subworkflows/local/prepare_genome.nf @@ -20,8 +20,8 @@ include { BBMAP_BBSPLIT } from '../../modules/nf-core/module include { HISAT2_EXTRACTSPLICESITES } from '../../modules/nf-core/modules/hisat2/extractsplicesites/main' include { HISAT2_BUILD } from '../../modules/nf-core/modules/hisat2/build/main' include { SALMON_INDEX } from '../../modules/nf-core/modules/salmon/index/main' -include { RSEM_PREPAREREFERENCE as RSEM_PREPAREREFERENCE_GENOME } from '../../modules/nf-core/modules/rsem/preparereference/main' -include { RSEM_PREPAREREFERENCE as MAKE_TRANSCRIPTS_FASTA } from '../../modules/nf-core/modules/rsem/preparereference/main' +include { RSEM_PREPAREREFERENCE as RSEM_PREPAREREFERENCE_GENOME } from '../../modules/nf-core/modules/rsem/preparereference/main' +include { RSEM_PREPAREREFERENCE as MAKE_TRANSCRIPTS_FASTA } from '../../modules/nf-core/modules/rsem/preparereference/main' include { GTF2BED } from '../../modules/local/gtf2bed' include { CAT_ADDITIONAL_FASTA } from '../../modules/local/cat_additional_fasta' From 01de13e705a815301924b357faf89711f2e4a981 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 14 Feb 2022 16:53:57 +0000 Subject: [PATCH 06/36] Run nf-core modules update --- .nf-core.yml | 16 ++-- modules.json | 76 +++++++++---------- modules/nf-core/modules/bbmap/bbsplit/main.nf | 3 + modules/nf-core/modules/cat/fastq/main.nf | 3 + .../custom/dumpsoftwareversions/main.nf | 3 + modules/nf-core/modules/fastqc/main.nf | 3 + modules/nf-core/modules/gffread/main.nf | 3 + modules/nf-core/modules/gunzip/main.nf | 3 + modules/nf-core/modules/hisat2/align/main.nf | 3 + modules/nf-core/modules/hisat2/build/main.nf | 3 + .../modules/hisat2/extractsplicesites/main.nf | 3 + .../modules/picard/markduplicates/main.nf | 9 ++- .../nf-core/modules/preseq/lcextrap/main.nf | 3 + .../nf-core/modules/qualimap/rnaseq/main.nf | 3 + .../modules/rsem/calculateexpression/main.nf | 3 + .../modules/rsem/preparereference/main.nf | 3 + modules/nf-core/modules/rseqc/bamstat/main.nf | 3 + .../modules/rseqc/inferexperiment/main.nf | 3 + .../modules/rseqc/innerdistance/main.nf | 3 + .../modules/rseqc/junctionannotation/main.nf | 3 + .../modules/rseqc/junctionsaturation/main.nf | 3 + .../modules/rseqc/readdistribution/main.nf | 3 + .../modules/rseqc/readduplication/main.nf | 3 + modules/nf-core/modules/rseqc/tin/main.nf | 3 + modules/nf-core/modules/salmon/index/main.nf | 3 + modules/nf-core/modules/salmon/quant/main.nf | 3 + .../nf-core/modules/samtools/flagstat/main.nf | 10 ++- .../nf-core/modules/samtools/idxstats/main.nf | 9 ++- .../nf-core/modules/samtools/index/main.nf | 9 ++- modules/nf-core/modules/samtools/sort/main.nf | 4 + .../nf-core/modules/samtools/stats/main.nf | 10 ++- modules/nf-core/modules/sortmerna/main.nf | 3 + .../modules/stringtie/stringtie/main.nf | 3 + .../modules/subread/featurecounts/main.nf | 3 + modules/nf-core/modules/trimgalore/main.nf | 3 + modules/nf-core/modules/ucsc/bedclip/main.nf | 3 + .../modules/ucsc/bedgraphtobigwig/main.nf | 3 + .../nf-core/modules/umitools/dedup/main.nf | 3 + .../nf-core/modules/umitools/extract/main.nf | 3 + modules/nf-core/modules/untar/main.nf | 3 + 40 files changed, 186 insertions(+), 53 deletions(-) diff --git a/.nf-core.yml b/.nf-core.yml index 7eb1f1078..a794b875c 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -5,11 +5,11 @@ lint: - lib/NfcoreTemplate.groovy update: nf-core/modules: - rseqc/bamstat: "9d0cad583b9a71a6509b754fdf589cbfbed08961" - rseqc/inferexperiment: "9d0cad583b9a71a6509b754fdf589cbfbed08961" - rseqc/innerdistance: "9d0cad583b9a71a6509b754fdf589cbfbed08961" - rseqc/junctionannotation: "9d0cad583b9a71a6509b754fdf589cbfbed08961" - rseqc/junctionsaturation: "9d0cad583b9a71a6509b754fdf589cbfbed08961" - rseqc/readdistribution: "9d0cad583b9a71a6509b754fdf589cbfbed08961" - rseqc/readduplication: "9d0cad583b9a71a6509b754fdf589cbfbed08961" - rseqc/tin: "ce8c781bb494c2cc1f0a951c31c7b2f4af12e8af" + rseqc/bamstat: "e20e57f90b6787ac9a010a980cf6ea98bd990046" + rseqc/inferexperiment: "e20e57f90b6787ac9a010a980cf6ea98bd990046" + rseqc/innerdistance: "e20e57f90b6787ac9a010a980cf6ea98bd990046" + rseqc/junctionannotation: "e20e57f90b6787ac9a010a980cf6ea98bd990046" + rseqc/junctionsaturation: "e20e57f90b6787ac9a010a980cf6ea98bd990046" + rseqc/readdistribution: "e20e57f90b6787ac9a010a980cf6ea98bd990046" + rseqc/readduplication: "e20e57f90b6787ac9a010a980cf6ea98bd990046" + rseqc/tin: "e20e57f90b6787ac9a010a980cf6ea98bd990046" diff --git a/modules.json b/modules.json index 932aa105c..837b8daa7 100644 --- a/modules.json +++ b/modules.json @@ -4,118 +4,118 @@ "repos": { "nf-core/modules": { "bbmap/bbsplit": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "cat/fastq": { - "git_sha": "826a5603db5cf5b4f1e55cef9cc0b7c37d3c7e70" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "custom/dumpsoftwareversions": { - "git_sha": "20d8250d9f39ddb05dfb437603aaf99b5c0b2b41" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "fastqc": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "gffread": { - "git_sha": "d473a247d2e0c619b0df877ea19d9a5a98c8e3c8" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "gunzip": { - "git_sha": "20d8250d9f39ddb05dfb437603aaf99b5c0b2b41" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "hisat2/align": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "hisat2/build": { - "git_sha": "20d8250d9f39ddb05dfb437603aaf99b5c0b2b41" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "hisat2/extractsplicesites": { - "git_sha": "20d8250d9f39ddb05dfb437603aaf99b5c0b2b41" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "picard/markduplicates": { - "git_sha": "0d1e21686a586447b7592e40da9b3a7cdeedf03c" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "preseq/lcextrap": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "qualimap/rnaseq": { - "git_sha": "d473a247d2e0c619b0df877ea19d9a5a98c8e3c8" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "rsem/calculateexpression": { - "git_sha": "d473a247d2e0c619b0df877ea19d9a5a98c8e3c8" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "rsem/preparereference": { - "git_sha": "47a9cf8ecbe4de4dcb8b9cc6731fece82b934ab7" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "rseqc/bamstat": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "rseqc/inferexperiment": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "rseqc/innerdistance": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "rseqc/junctionannotation": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "rseqc/junctionsaturation": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "rseqc/readdistribution": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "rseqc/readduplication": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "rseqc/tin": { - "git_sha": "ce8c781bb494c2cc1f0a951c31c7b2f4af12e8af" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "salmon/index": { - "git_sha": "20d8250d9f39ddb05dfb437603aaf99b5c0b2b41" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "salmon/quant": { - "git_sha": "d473a247d2e0c619b0df877ea19d9a5a98c8e3c8" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "samtools/flagstat": { - "git_sha": "20d8250d9f39ddb05dfb437603aaf99b5c0b2b41" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "samtools/idxstats": { - "git_sha": "20d8250d9f39ddb05dfb437603aaf99b5c0b2b41" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "samtools/index": { - "git_sha": "0fafaeebf52cc5ab554b83297ed02a48d852a848" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "samtools/sort": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "samtools/stats": { - "git_sha": "20d8250d9f39ddb05dfb437603aaf99b5c0b2b41" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "sortmerna": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "stringtie/stringtie": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "subread/featurecounts": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "trimgalore": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "ucsc/bedclip": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "ucsc/bedgraphtobigwig": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "umitools/dedup": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "umitools/extract": { - "git_sha": "9d0cad583b9a71a6509b754fdf589cbfbed08961" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "untar": { - "git_sha": "20d8250d9f39ddb05dfb437603aaf99b5c0b2b41" + "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" } } } diff --git a/modules/nf-core/modules/bbmap/bbsplit/main.nf b/modules/nf-core/modules/bbmap/bbsplit/main.nf index 0c916dfe8..b55929ce9 100644 --- a/modules/nf-core/modules/bbmap/bbsplit/main.nf +++ b/modules/nf-core/modules/bbmap/bbsplit/main.nf @@ -20,6 +20,9 @@ process BBMAP_BBSPLIT { tuple val(meta), path('*txt') , optional:true, emit: stats path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/cat/fastq/main.nf b/modules/nf-core/modules/cat/fastq/main.nf index d02598e1f..bf0877c3e 100644 --- a/modules/nf-core/modules/cat/fastq/main.nf +++ b/modules/nf-core/modules/cat/fastq/main.nf @@ -14,6 +14,9 @@ process CAT_FASTQ { tuple val(meta), path("*.merged.fastq.gz"), emit: reads path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf b/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf index 934bb4672..327d51005 100644 --- a/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf +++ b/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf @@ -15,6 +15,9 @@ process CUSTOM_DUMPSOFTWAREVERSIONS { path "software_versions_mqc.yml", emit: mqc_yml path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' template 'dumpsoftwareversions.py' diff --git a/modules/nf-core/modules/fastqc/main.nf b/modules/nf-core/modules/fastqc/main.nf index d250eca07..ed6b8c50b 100644 --- a/modules/nf-core/modules/fastqc/main.nf +++ b/modules/nf-core/modules/fastqc/main.nf @@ -15,6 +15,9 @@ process FASTQC { tuple val(meta), path("*.zip") , emit: zip path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' // Add soft-links to original FastQs for consistent naming in pipeline diff --git a/modules/nf-core/modules/gffread/main.nf b/modules/nf-core/modules/gffread/main.nf index e7893f8ba..7c575c97f 100644 --- a/modules/nf-core/modules/gffread/main.nf +++ b/modules/nf-core/modules/gffread/main.nf @@ -14,6 +14,9 @@ process GFFREAD { path "*.gtf" , emit: gtf path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${gff.baseName}" diff --git a/modules/nf-core/modules/gunzip/main.nf b/modules/nf-core/modules/gunzip/main.nf index 77a4e546b..9d4b06669 100644 --- a/modules/nf-core/modules/gunzip/main.nf +++ b/modules/nf-core/modules/gunzip/main.nf @@ -14,6 +14,9 @@ process GUNZIP { tuple val(meta), path("$gunzip"), emit: gunzip path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' gunzip = archive.toString() - '.gz' diff --git a/modules/nf-core/modules/hisat2/align/main.nf b/modules/nf-core/modules/hisat2/align/main.nf index ae8886169..7f6800189 100644 --- a/modules/nf-core/modules/hisat2/align/main.nf +++ b/modules/nf-core/modules/hisat2/align/main.nf @@ -20,6 +20,9 @@ process HISAT2_ALIGN { tuple val(meta), path("*fastq.gz"), optional:true, emit: fastq path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/hisat2/build/main.nf b/modules/nf-core/modules/hisat2/build/main.nf index 4e8cd02bb..50f65e3a1 100644 --- a/modules/nf-core/modules/hisat2/build/main.nf +++ b/modules/nf-core/modules/hisat2/build/main.nf @@ -19,6 +19,9 @@ process HISAT2_BUILD { path "hisat2" , emit: index path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def avail_mem = 0 diff --git a/modules/nf-core/modules/hisat2/extractsplicesites/main.nf b/modules/nf-core/modules/hisat2/extractsplicesites/main.nf index 302c35f1f..941359779 100644 --- a/modules/nf-core/modules/hisat2/extractsplicesites/main.nf +++ b/modules/nf-core/modules/hisat2/extractsplicesites/main.nf @@ -16,6 +16,9 @@ process HISAT2_EXTRACTSPLICESITES { path "*.splice_sites.txt", emit: txt path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' """ diff --git a/modules/nf-core/modules/picard/markduplicates/main.nf b/modules/nf-core/modules/picard/markduplicates/main.nf index 3087bff4a..5196b6edf 100644 --- a/modules/nf-core/modules/picard/markduplicates/main.nf +++ b/modules/nf-core/modules/picard/markduplicates/main.nf @@ -2,10 +2,10 @@ process PICARD_MARKDUPLICATES { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::picard=2.26.7" : null) + conda (params.enable_conda ? "bioconda::picard=2.26.10" : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:2.26.7--hdfd78af_0' : - 'quay.io/biocontainers/picard:2.26.7--hdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/picard:2.26.10--hdfd78af_0' : + 'quay.io/biocontainers/picard:2.26.10--hdfd78af_0' }" input: tuple val(meta), path(bam) @@ -16,6 +16,9 @@ process PICARD_MARKDUPLICATES { tuple val(meta), path("*.metrics.txt"), emit: metrics path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/preseq/lcextrap/main.nf b/modules/nf-core/modules/preseq/lcextrap/main.nf index b5bd06206..d6dd19e23 100644 --- a/modules/nf-core/modules/preseq/lcextrap/main.nf +++ b/modules/nf-core/modules/preseq/lcextrap/main.nf @@ -16,6 +16,9 @@ process PRESEQ_LCEXTRAP { tuple val(meta), path("*.log") , emit: log path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/qualimap/rnaseq/main.nf b/modules/nf-core/modules/qualimap/rnaseq/main.nf index d83fcd999..3b2f88ade 100644 --- a/modules/nf-core/modules/qualimap/rnaseq/main.nf +++ b/modules/nf-core/modules/qualimap/rnaseq/main.nf @@ -15,6 +15,9 @@ process QUALIMAP_RNASEQ { tuple val(meta), path("${prefix}"), emit: results path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/rsem/calculateexpression/main.nf b/modules/nf-core/modules/rsem/calculateexpression/main.nf index 4b2ada47a..cf147a633 100644 --- a/modules/nf-core/modules/rsem/calculateexpression/main.nf +++ b/modules/nf-core/modules/rsem/calculateexpression/main.nf @@ -22,6 +22,9 @@ process RSEM_CALCULATEEXPRESSION { tuple val(meta), path("${prefix}.genome.bam") , optional:true, emit: bam_genome tuple val(meta), path("${prefix}.transcript.bam"), optional:true, emit: bam_transcript + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/rsem/preparereference/main.nf b/modules/nf-core/modules/rsem/preparereference/main.nf index a5b8922a0..2d2ca2056 100644 --- a/modules/nf-core/modules/rsem/preparereference/main.nf +++ b/modules/nf-core/modules/rsem/preparereference/main.nf @@ -16,6 +16,9 @@ process RSEM_PREPAREREFERENCE { path "*transcripts.fa", emit: transcript_fasta path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def args2 = task.ext.args2 ?: '' diff --git a/modules/nf-core/modules/rseqc/bamstat/main.nf b/modules/nf-core/modules/rseqc/bamstat/main.nf index 1141a13f2..958221fde 100644 --- a/modules/nf-core/modules/rseqc/bamstat/main.nf +++ b/modules/nf-core/modules/rseqc/bamstat/main.nf @@ -14,6 +14,9 @@ process RSEQC_BAMSTAT { tuple val(meta), path("*.bam_stat.txt"), emit: txt path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/rseqc/inferexperiment/main.nf b/modules/nf-core/modules/rseqc/inferexperiment/main.nf index 2243c43e1..23c1b6882 100644 --- a/modules/nf-core/modules/rseqc/inferexperiment/main.nf +++ b/modules/nf-core/modules/rseqc/inferexperiment/main.nf @@ -15,6 +15,9 @@ process RSEQC_INFEREXPERIMENT { tuple val(meta), path("*.infer_experiment.txt"), emit: txt path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/rseqc/innerdistance/main.nf b/modules/nf-core/modules/rseqc/innerdistance/main.nf index 425737d68..b05661de1 100644 --- a/modules/nf-core/modules/rseqc/innerdistance/main.nf +++ b/modules/nf-core/modules/rseqc/innerdistance/main.nf @@ -19,6 +19,9 @@ process RSEQC_INNERDISTANCE { tuple val(meta), path("*.r") , optional:true, emit: rscript path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/rseqc/junctionannotation/main.nf b/modules/nf-core/modules/rseqc/junctionannotation/main.nf index d2562e5cb..c3401dc51 100644 --- a/modules/nf-core/modules/rseqc/junctionannotation/main.nf +++ b/modules/nf-core/modules/rseqc/junctionannotation/main.nf @@ -21,6 +21,9 @@ process RSEQC_JUNCTIONANNOTATION { tuple val(meta), path("*events.pdf") , optional:true, emit: events_pdf path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/rseqc/junctionsaturation/main.nf b/modules/nf-core/modules/rseqc/junctionsaturation/main.nf index 695762b5c..11b629040 100644 --- a/modules/nf-core/modules/rseqc/junctionsaturation/main.nf +++ b/modules/nf-core/modules/rseqc/junctionsaturation/main.nf @@ -16,6 +16,9 @@ process RSEQC_JUNCTIONSATURATION { tuple val(meta), path("*.r") , emit: rscript path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/rseqc/readdistribution/main.nf b/modules/nf-core/modules/rseqc/readdistribution/main.nf index 333193e30..3198c5c66 100644 --- a/modules/nf-core/modules/rseqc/readdistribution/main.nf +++ b/modules/nf-core/modules/rseqc/readdistribution/main.nf @@ -15,6 +15,9 @@ process RSEQC_READDISTRIBUTION { tuple val(meta), path("*.read_distribution.txt"), emit: txt path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/rseqc/readduplication/main.nf b/modules/nf-core/modules/rseqc/readduplication/main.nf index 134f2e8db..cb989a5f2 100644 --- a/modules/nf-core/modules/rseqc/readduplication/main.nf +++ b/modules/nf-core/modules/rseqc/readduplication/main.nf @@ -17,6 +17,9 @@ process RSEQC_READDUPLICATION { tuple val(meta), path("*.r") , emit: rscript path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/rseqc/tin/main.nf b/modules/nf-core/modules/rseqc/tin/main.nf index b7bff0f31..da58fc06b 100644 --- a/modules/nf-core/modules/rseqc/tin/main.nf +++ b/modules/nf-core/modules/rseqc/tin/main.nf @@ -16,6 +16,9 @@ process RSEQC_TIN { tuple val(meta), path("*.xls"), emit: xls path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/salmon/index/main.nf b/modules/nf-core/modules/salmon/index/main.nf index b0a2f973c..737087f96 100644 --- a/modules/nf-core/modules/salmon/index/main.nf +++ b/modules/nf-core/modules/salmon/index/main.nf @@ -15,6 +15,9 @@ process SALMON_INDEX { path "salmon" , emit: index path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def get_decoy_ids = "grep '^>' $genome_fasta | cut -d ' ' -f 1 > decoys.txt" diff --git a/modules/nf-core/modules/salmon/quant/main.nf b/modules/nf-core/modules/salmon/quant/main.nf index 6cae4f72d..bd4792c52 100644 --- a/modules/nf-core/modules/salmon/quant/main.nf +++ b/modules/nf-core/modules/salmon/quant/main.nf @@ -19,6 +19,9 @@ process SALMON_QUANT { tuple val(meta), path("${prefix}"), emit: results path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/samtools/flagstat/main.nf b/modules/nf-core/modules/samtools/flagstat/main.nf index 03721d0b2..c267922b3 100644 --- a/modules/nf-core/modules/samtools/flagstat/main.nf +++ b/modules/nf-core/modules/samtools/flagstat/main.nf @@ -14,10 +14,18 @@ process SAMTOOLS_FLAGSTAT { tuple val(meta), path("*.flagstat"), emit: flagstat path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' """ - samtools flagstat --threads ${task.cpus-1} $bam > ${bam}.flagstat + samtools \\ + flagstat \\ + --threads ${task.cpus-1} \\ + $bam \\ + > ${bam}.flagstat + cat <<-END_VERSIONS > versions.yml "${task.process}": samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') diff --git a/modules/nf-core/modules/samtools/idxstats/main.nf b/modules/nf-core/modules/samtools/idxstats/main.nf index cd0686791..8a057413e 100644 --- a/modules/nf-core/modules/samtools/idxstats/main.nf +++ b/modules/nf-core/modules/samtools/idxstats/main.nf @@ -14,10 +14,17 @@ process SAMTOOLS_IDXSTATS { tuple val(meta), path("*.idxstats"), emit: idxstats path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' """ - samtools idxstats $bam > ${bam}.idxstats + samtools \\ + idxstats \\ + $bam \\ + > ${bam}.idxstats + cat <<-END_VERSIONS > versions.yml "${task.process}": samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') diff --git a/modules/nf-core/modules/samtools/index/main.nf b/modules/nf-core/modules/samtools/index/main.nf index db025a8f9..dfe0234f7 100644 --- a/modules/nf-core/modules/samtools/index/main.nf +++ b/modules/nf-core/modules/samtools/index/main.nf @@ -16,10 +16,17 @@ process SAMTOOLS_INDEX { tuple val(meta), path("*.crai"), optional:true, emit: crai path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' """ - samtools index -@ ${task.cpus-1} $args $input + samtools \\ + index \\ + -@ ${task.cpus-1} \\ + $args \\ + $input cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/modules/samtools/sort/main.nf b/modules/nf-core/modules/samtools/sort/main.nf index 0c2cf25e3..0f2237cc1 100644 --- a/modules/nf-core/modules/samtools/sort/main.nf +++ b/modules/nf-core/modules/samtools/sort/main.nf @@ -14,9 +14,13 @@ process SAMTOOLS_SORT { tuple val(meta), path("*.bam"), emit: bam path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" + if ("$bam" == "${prefix}.bam") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" """ samtools sort $args -@ $task.cpus -o ${prefix}.bam -T $prefix $bam cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/modules/samtools/stats/main.nf b/modules/nf-core/modules/samtools/stats/main.nf index 83c870025..f6fe3bfef 100644 --- a/modules/nf-core/modules/samtools/stats/main.nf +++ b/modules/nf-core/modules/samtools/stats/main.nf @@ -15,11 +15,19 @@ process SAMTOOLS_STATS { tuple val(meta), path("*.stats"), emit: stats path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def reference = fasta ? "--reference ${fasta}" : "" """ - samtools stats --threads ${task.cpus-1} ${reference} ${input} > ${input}.stats + samtools \\ + stats \\ + --threads ${task.cpus-1} \\ + ${reference} \\ + ${input} \\ + > ${input}.stats cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/modules/sortmerna/main.nf b/modules/nf-core/modules/sortmerna/main.nf index 5c0950d87..419d29149 100644 --- a/modules/nf-core/modules/sortmerna/main.nf +++ b/modules/nf-core/modules/sortmerna/main.nf @@ -16,6 +16,9 @@ process SORTMERNA { tuple val(meta), path("*.log") , emit: log path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/stringtie/stringtie/main.nf b/modules/nf-core/modules/stringtie/stringtie/main.nf index 9d62a966a..f37e347a5 100644 --- a/modules/nf-core/modules/stringtie/stringtie/main.nf +++ b/modules/nf-core/modules/stringtie/stringtie/main.nf @@ -18,6 +18,9 @@ process STRINGTIE { tuple val(meta), path("*.ballgown") , emit: ballgown path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/subread/featurecounts/main.nf b/modules/nf-core/modules/subread/featurecounts/main.nf index 53eb279e1..18e2a92bb 100644 --- a/modules/nf-core/modules/subread/featurecounts/main.nf +++ b/modules/nf-core/modules/subread/featurecounts/main.nf @@ -15,6 +15,9 @@ process SUBREAD_FEATURECOUNTS { tuple val(meta), path("*featureCounts.txt.summary"), emit: summary path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/trimgalore/main.nf b/modules/nf-core/modules/trimgalore/main.nf index ee40b780b..9487c7990 100644 --- a/modules/nf-core/modules/trimgalore/main.nf +++ b/modules/nf-core/modules/trimgalore/main.nf @@ -18,6 +18,9 @@ process TRIMGALORE { tuple val(meta), path("*.html"), emit: html optional true tuple val(meta), path("*.zip") , emit: zip optional true + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' // Calculate number of --cores for TrimGalore based on value of task.cpus diff --git a/modules/nf-core/modules/ucsc/bedclip/main.nf b/modules/nf-core/modules/ucsc/bedclip/main.nf index dacd72600..969a8f73e 100644 --- a/modules/nf-core/modules/ucsc/bedclip/main.nf +++ b/modules/nf-core/modules/ucsc/bedclip/main.nf @@ -17,6 +17,9 @@ process UCSC_BEDCLIP { tuple val(meta), path("*.bedGraph"), emit: bedgraph path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/ucsc/bedgraphtobigwig/main.nf b/modules/nf-core/modules/ucsc/bedgraphtobigwig/main.nf index 9ba306aba..ef0ca088f 100644 --- a/modules/nf-core/modules/ucsc/bedgraphtobigwig/main.nf +++ b/modules/nf-core/modules/ucsc/bedgraphtobigwig/main.nf @@ -17,6 +17,9 @@ process UCSC_BEDGRAPHTOBIGWIG { tuple val(meta), path("*.bigWig"), emit: bigwig path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/umitools/dedup/main.nf b/modules/nf-core/modules/umitools/dedup/main.nf index ce21437db..1e46a6129 100644 --- a/modules/nf-core/modules/umitools/dedup/main.nf +++ b/modules/nf-core/modules/umitools/dedup/main.nf @@ -14,6 +14,9 @@ process UMITOOLS_DEDUP { tuple val(meta), path("*.bam"), emit: bam path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/umitools/extract/main.nf b/modules/nf-core/modules/umitools/extract/main.nf index fba8f0540..22a405b97 100644 --- a/modules/nf-core/modules/umitools/extract/main.nf +++ b/modules/nf-core/modules/umitools/extract/main.nf @@ -15,6 +15,9 @@ process UMITOOLS_EXTRACT { tuple val(meta), path("*.log") , emit: log path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/modules/untar/main.nf b/modules/nf-core/modules/untar/main.nf index 6d1996e77..01205e60d 100644 --- a/modules/nf-core/modules/untar/main.nf +++ b/modules/nf-core/modules/untar/main.nf @@ -14,6 +14,9 @@ process UNTAR { path "$untar" , emit: untar path "versions.yml", emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def args2 = task.ext.args2 ?: '' From 3281aebc86def7273324a07a673445a7897bc893 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 14 Feb 2022 16:58:14 +0000 Subject: [PATCH 07/36] Add when statement to local modules --- modules/local/bedtools_genomecov.nf | 3 +++ modules/local/cat_additional_fasta.nf | 3 +++ modules/local/deseq2_qc.nf | 3 +++ modules/local/dupradar.nf | 3 +++ modules/local/get_chrom_sizes.nf | 3 +++ modules/local/gtf2bed.nf | 3 +++ modules/local/gtf_gene_filter.nf | 3 +++ modules/local/multiqc.nf | 3 +++ modules/local/multiqc_custom_biotype.nf | 3 +++ modules/local/multiqc_tsv_from_list.nf | 3 +++ modules/local/rsem_merge_counts.nf | 3 +++ modules/local/salmon_summarizedexperiment.nf | 3 +++ modules/local/salmon_tx2gene.nf | 3 +++ modules/local/salmon_tximport.nf | 3 +++ modules/local/samplesheet_check.nf | 3 +++ modules/local/star_align.nf | 3 +++ modules/local/star_genomegenerate.nf | 3 +++ 17 files changed, 51 insertions(+) diff --git a/modules/local/bedtools_genomecov.nf b/modules/local/bedtools_genomecov.nf index 23f887c29..26d149bf3 100644 --- a/modules/local/bedtools_genomecov.nf +++ b/modules/local/bedtools_genomecov.nf @@ -15,6 +15,9 @@ process BEDTOOLS_GENOMECOV { tuple val(meta), path("*.reverse.bedGraph"), emit: bedgraph_reverse path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/local/cat_additional_fasta.nf b/modules/local/cat_additional_fasta.nf index aeac8fd19..0c01ae985 100644 --- a/modules/local/cat_additional_fasta.nf +++ b/modules/local/cat_additional_fasta.nf @@ -17,6 +17,9 @@ process CAT_ADDITIONAL_FASTA { path "${name}.gtf" , emit: gtf path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def genome_name = params.genome ? params.genome : fasta.getBaseName() def biotype_name = biotype ? "-b $biotype" : '' diff --git a/modules/local/deseq2_qc.nf b/modules/local/deseq2_qc.nf index dcbdc4092..91fb8fee4 100644 --- a/modules/local/deseq2_qc.nf +++ b/modules/local/deseq2_qc.nf @@ -24,6 +24,9 @@ process DESEQ2_QC { path "size_factors" , optional:true, emit: size_factors path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def args2 = task.ext.args2 ?: '' diff --git a/modules/local/dupradar.nf b/modules/local/dupradar.nf index f47181735..4a6ce6af8 100644 --- a/modules/local/dupradar.nf +++ b/modules/local/dupradar.nf @@ -17,6 +17,9 @@ process DUPRADAR { tuple val(meta), path("*_mqc.txt"), emit: multiqc path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: // This script is bundled with the pipeline, in nf-core/rnaseq/bin/ def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/local/get_chrom_sizes.nf b/modules/local/get_chrom_sizes.nf index 1cb850211..92f071edc 100644 --- a/modules/local/get_chrom_sizes.nf +++ b/modules/local/get_chrom_sizes.nf @@ -14,6 +14,9 @@ process GET_CHROM_SIZES { path '*.fai' , emit: fai path "versions.yml", emit: versions + when: + task.ext.when == null || task.ext.when + script: """ samtools \\ diff --git a/modules/local/gtf2bed.nf b/modules/local/gtf2bed.nf index aa365c055..0130c97e6 100644 --- a/modules/local/gtf2bed.nf +++ b/modules/local/gtf2bed.nf @@ -14,6 +14,9 @@ process GTF2BED { path '*.bed' , emit: bed path "versions.yml", emit: versions + when: + task.ext.when == null || task.ext.when + script: // This script is bundled with the pipeline, in nf-core/rnaseq/bin/ """ gtf2bed \\ diff --git a/modules/local/gtf_gene_filter.nf b/modules/local/gtf_gene_filter.nf index 1edebe31c..f324ace2e 100644 --- a/modules/local/gtf_gene_filter.nf +++ b/modules/local/gtf_gene_filter.nf @@ -14,6 +14,9 @@ process GTF_GENE_FILTER { path "*.gtf" , emit: gtf path "versions.yml", emit: versions + when: + task.ext.when == null || task.ext.when + script: // filter_gtf_for_genes_in_genome.py is bundled with the pipeline, in nf-core/rnaseq/bin/ """ filter_gtf_for_genes_in_genome.py \\ diff --git a/modules/local/multiqc.nf b/modules/local/multiqc.nf index 0bfc233f2..00d0c8ff2 100644 --- a/modules/local/multiqc.nf +++ b/modules/local/multiqc.nf @@ -48,6 +48,9 @@ process MULTIQC { path "*_plots" , optional:true, emit: plots path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def custom_config = params.multiqc_config ? "--config $multiqc_custom_config" : '' diff --git a/modules/local/multiqc_custom_biotype.nf b/modules/local/multiqc_custom_biotype.nf index c6a08b1c3..e86b66c15 100644 --- a/modules/local/multiqc_custom_biotype.nf +++ b/modules/local/multiqc_custom_biotype.nf @@ -14,6 +14,9 @@ process MULTIQC_CUSTOM_BIOTYPE { tuple val(meta), path("*.tsv"), emit: tsv path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def prefix = task.ext.prefix ?: "${meta.id}" """ diff --git a/modules/local/multiqc_tsv_from_list.nf b/modules/local/multiqc_tsv_from_list.nf index 7f7b7c0a9..a53c8f73e 100644 --- a/modules/local/multiqc_tsv_from_list.nf +++ b/modules/local/multiqc_tsv_from_list.nf @@ -11,6 +11,9 @@ process MULTIQC_TSV_FROM_LIST { output: path "*.tsv" + when: + task.ext.when == null || task.ext.when + exec: // Generate file contents def contents = "" diff --git a/modules/local/rsem_merge_counts.nf b/modules/local/rsem_merge_counts.nf index 82e741d7d..f1f4684f4 100644 --- a/modules/local/rsem_merge_counts.nf +++ b/modules/local/rsem_merge_counts.nf @@ -17,6 +17,9 @@ process RSEM_MERGE_COUNTS { path "rsem.merged.transcript_tpm.tsv" , emit: tpm_transcript path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: """ mkdir -p tmp/genes diff --git a/modules/local/salmon_summarizedexperiment.nf b/modules/local/salmon_summarizedexperiment.nf index f41224ef1..2d4146872 100644 --- a/modules/local/salmon_summarizedexperiment.nf +++ b/modules/local/salmon_summarizedexperiment.nf @@ -16,6 +16,9 @@ process SALMON_SUMMARIZEDEXPERIMENT { path "*.rds" , emit: rds path "versions.yml", emit: versions + when: + task.ext.when == null || task.ext.when + script: // This script is bundled with the pipeline, in nf-core/rnaseq/bin/ """ salmon_summarizedexperiment.r \\ diff --git a/modules/local/salmon_tx2gene.nf b/modules/local/salmon_tx2gene.nf index 071eff3ff..aed21ed5d 100644 --- a/modules/local/salmon_tx2gene.nf +++ b/modules/local/salmon_tx2gene.nf @@ -15,6 +15,9 @@ process SALMON_TX2GENE { path "*.tsv" , emit: tsv path "versions.yml", emit: versions + when: + task.ext.when == null || task.ext.when + script: // This script is bundled with the pipeline, in nf-core/rnaseq/bin/ """ salmon_tx2gene.py \\ diff --git a/modules/local/salmon_tximport.nf b/modules/local/salmon_tximport.nf index 75481076a..0845d2d25 100644 --- a/modules/local/salmon_tximport.nf +++ b/modules/local/salmon_tximport.nf @@ -19,6 +19,9 @@ process SALMON_TXIMPORT { path "*transcript_counts.tsv" , emit: counts_transcript path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: // This script is bundled with the pipeline, in nf-core/rnaseq/bin/ """ salmon_tximport.r \\ diff --git a/modules/local/samplesheet_check.nf b/modules/local/samplesheet_check.nf index b0f192f91..cc8368e5d 100644 --- a/modules/local/samplesheet_check.nf +++ b/modules/local/samplesheet_check.nf @@ -13,6 +13,9 @@ process SAMPLESHEET_CHECK { path '*.csv' , emit: csv path "versions.yml", emit: versions + when: + task.ext.when == null || task.ext.when + script: // This script is bundled with the pipeline, in nf-core/rnaseq/bin/ """ check_samplesheet.py \\ diff --git a/modules/local/star_align.nf b/modules/local/star_align.nf index 5a67b1716..c6d845628 100644 --- a/modules/local/star_align.nf +++ b/modules/local/star_align.nf @@ -26,6 +26,9 @@ process STAR_ALIGN { tuple val(meta), path('*fastq.gz') , optional:true, emit: fastq tuple val(meta), path('*.tab') , optional:true, emit: tab + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/local/star_genomegenerate.nf b/modules/local/star_genomegenerate.nf index 27231ebbe..87279e60b 100644 --- a/modules/local/star_genomegenerate.nf +++ b/modules/local/star_genomegenerate.nf @@ -16,6 +16,9 @@ process STAR_GENOMEGENERATE { path "star" , emit: index path "versions.yml", emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = (task.ext.args ?: '').tokenize() def memory = task.memory ? "--limitGenomeGenerateRAM ${task.memory.toBytes() - 100000000}" : '' From f97169e238e5da61a4fa4c50f2ef8c12d35a2f55 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 14 Feb 2022 17:07:40 +0000 Subject: [PATCH 08/36] Bump MultiQC version --- modules/local/multiqc.nf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/local/multiqc.nf b/modules/local/multiqc.nf index 00d0c8ff2..4c6ab1319 100644 --- a/modules/local/multiqc.nf +++ b/modules/local/multiqc.nf @@ -1,10 +1,10 @@ process MULTIQC { label 'process_medium' - conda (params.enable_conda ? "bioconda::multiqc=1.11" : null) + conda (params.enable_conda ? "bioconda::multiqc=1.12" : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.11--pyhdfd78af_0' : - 'quay.io/biocontainers/multiqc:1.11--pyhdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/multiqc:1.12--pyhdfd78af_0' : + 'quay.io/biocontainers/multiqc:1.12--pyhdfd78af_0' }" input: path multiqc_config From 79b5c16c9d366e284a674977c583883415974840 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 14 Feb 2022 17:36:51 +0000 Subject: [PATCH 09/36] Revert MultiQC bump because something else broke --- modules/local/multiqc.nf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/local/multiqc.nf b/modules/local/multiqc.nf index 4c6ab1319..00d0c8ff2 100644 --- a/modules/local/multiqc.nf +++ b/modules/local/multiqc.nf @@ -1,10 +1,10 @@ process MULTIQC { label 'process_medium' - conda (params.enable_conda ? "bioconda::multiqc=1.12" : null) + conda (params.enable_conda ? "bioconda::multiqc=1.11" : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.12--pyhdfd78af_0' : - 'quay.io/biocontainers/multiqc:1.12--pyhdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/multiqc:1.11--pyhdfd78af_0' : + 'quay.io/biocontainers/multiqc:1.11--pyhdfd78af_0' }" input: path multiqc_config From 57792a6ed8cc07710207441284f2aff6b734b085 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 14 Feb 2022 22:21:30 +0000 Subject: [PATCH 10/36] Revert contentious process selectors in modules.config --- conf/modules.config | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 75d4ed984..71994f5ea 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -281,7 +281,7 @@ if (params.remove_ribo_rna) { if (!params.skip_alignment) { process { - withName: '.*:.*:.*:BAM_SORT_SAMTOOLS:BAM_STATS_SAMTOOLS:.*' { + withName: 'NFCORE_RNASEQ:RNASEQ:.*:BAM_SORT_SAMTOOLS:BAM_STATS_SAMTOOLS:.*' { publishDir = [ path: { "${params.outdir}/${params.aligner}/samtools_stats" }, mode: 'copy', @@ -289,7 +289,7 @@ if (!params.skip_alignment) { ] } - withName: '.*:.*:.*:BAM_SORT_SAMTOOLS:SAMTOOLS_SORT' { + withName: 'NFCORE_RNASEQ:RNASEQ:.*:BAM_SORT_SAMTOOLS:SAMTOOLS_SORT' { ext.prefix = { "${meta.id}.sorted" } publishDir = [ path: { "${params.outdir}/${params.aligner}" }, @@ -303,7 +303,7 @@ if (!params.skip_alignment) { ] } - withName: '.*:.*:.*:BAM_SORT_SAMTOOLS:SAMTOOLS_INDEX' { + withName: 'NFCORE_RNASEQ:RNASEQ:.*:BAM_SORT_SAMTOOLS:SAMTOOLS_INDEX' { ext.args = params.bam_csi_index ? '-c' : '' publishDir = [ path: { "${params.outdir}/${params.aligner}" }, @@ -554,7 +554,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { if (params.with_umi) { process { - withName: '.*:.*:SAMTOOLS_SORT' { + withName: 'NFCORE_RNASEQ:RNASEQ:SAMTOOLS_SORT' { ext.args = '-n' ext.prefix = { "${meta.id}.umi_dedup.transcriptome" } publishDir = [ @@ -563,7 +563,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { ] } - withName: '.*:.*:BAM_SORT_SAMTOOLS:SAMTOOLS_SORT' { + withName: 'NFCORE_RNASEQ:RNASEQ:BAM_SORT_SAMTOOLS:SAMTOOLS_SORT' { ext.prefix = { "${meta.id}.transcriptome.sorted" } publishDir = [ path: { "${params.outdir}/${params.aligner}" }, @@ -571,14 +571,14 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { ] } - withName: '.*:.*:BAM_SORT_SAMTOOLS:SAMTOOLS_INDEX' { + withName: 'NFCORE_RNASEQ:RNASEQ:BAM_SORT_SAMTOOLS:SAMTOOLS_INDEX' { publishDir = [ path: { "${params.outdir}/${params.aligner}" }, enabled: false ] } - withName: '.*:.*:BAM_SORT_SAMTOOLS:BAM_STATS_SAMTOOLS:.*' { + withName: 'NFCORE_RNASEQ:RNASEQ:BAM_SORT_SAMTOOLS:BAM_STATS_SAMTOOLS:.*' { publishDir = [ path: { "${params.outdir}/${params.aligner}" }, enabled: false From 96f6b72a628e40856fa41004d4dd1a355401be41 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 15 Feb 2022 16:47:05 +0000 Subject: [PATCH 11/36] Template update for nf-core/tools version 2.3.dev0 --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 - .github/workflows/awsfulltest.yml | 4 +- .github/workflows/awstest.yml | 4 +- .github/workflows/linting.yml | 16 ++--- .gitpod.yml | 14 ++++ .yamllint.yml | 5 ++ CHANGELOG.md | 2 +- README.md | 2 +- assets/nf-core-rnaseq_logo_light.png | Bin 519 -> 10453 bytes conf/base.config | 4 +- conf/igenomes.config | 80 +++++++++++----------- conf/modules.config | 4 +- conf/test.config | 4 +- conf/test_full.config | 4 +- docs/images/nf-core-rnaseq_logo_dark.png | Bin 519 -> 71322 bytes docs/images/nf-core-rnaseq_logo_light.png | Bin 0 -> 71212 bytes docs/usage.md | 11 ++- lib/NfcoreSchema.groovy | 4 +- lib/Utils.groovy | 4 +- lib/WorkflowRnaseq.groovy | 4 +- main.nf | 24 +++---- nextflow.config | 8 +-- workflows/rnaseq.nf | 28 ++++---- 23 files changed, 125 insertions(+), 102 deletions(-) create mode 100644 .gitpod.yml create mode 100644 .yamllint.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 38983e89f..9e343cfb6 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,4 +1,3 @@ - name: Bug report description: Report something that is broken or incorrect labels: bug diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index f04694a53..7c2f4b2b1 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -31,4 +31,6 @@ jobs: "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnaseq/results-${{ github.sha }}" } profiles: test_full,aws_tower - pre_run_script: 'export NXF_VER=21.10.3' + nextflow_config: | + process.errorStrategy = 'retry' + process.maxRetries = 3 diff --git a/.github/workflows/awstest.yml b/.github/workflows/awstest.yml index d59a95339..2eaf89a79 100644 --- a/.github/workflows/awstest.yml +++ b/.github/workflows/awstest.yml @@ -25,4 +25,6 @@ jobs: "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnaseq/results-test-${{ github.sha }}" } profiles: test,aws_tower - pre_run_script: 'export NXF_VER=21.10.3' + nextflow_config: | + process.errorStrategy = 'retry' + process.maxRetries = 3 diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 3b448773c..b7c3159c7 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -12,9 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 - with: - node-version: '10' + - uses: actions/setup-node@v2 - name: Install markdownlint run: npm install -g markdownlint-cli - name: Run Markdownlint @@ -51,9 +49,7 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 - with: - node-version: '10' + - uses: actions/setup-node@v2 - name: Install editorconfig-checker run: npm install -g editorconfig-checker @@ -65,13 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - - uses: actions/setup-node@v1 - with: - node-version: '10' + - uses: actions/setup-node@v2 - name: Install yaml-lint run: npm install -g yaml-lint - name: Run yaml-lint - run: yamllint $(find ${GITHUB_WORKSPACE} -type f -name "*.yml" -o -name "*.yaml") + run: yamllint $(find ${GITHUB_WORKSPACE} -type f -name "*.yml" -o -name "*.yaml") -c ${GITHUB_WORKSPACE}/.yamllint.yml # If the above check failed, post a comment on the PR explaining the failure - name: Post PR comment @@ -87,7 +81,7 @@ jobs: * Install `yaml-lint` * [Install `npm`](https://www.npmjs.com/get-npm) then [install `yaml-lint`](https://www.npmjs.com/package/yaml-lint) (`npm install -g yaml-lint`) * Fix the markdown errors - * Run the test locally: `yamllint $(find . -type f -name "*.yml" -o -name "*.yaml")` + * Run the test locally: `yamllint $(find . -type f -name "*.yml" -o -name "*.yaml") -c ./.yamllint.yml` * Fix any reported errors in your YAML files Once you push these changes the test should pass, and you can hide this comment :+1: diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 000000000..b7d4cee18 --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,14 @@ +image: nfcore/gitpod:latest + +vscode: + extensions: # based on nf-core.nf-core-extensionpack + - codezombiech.gitignore # Language support for .gitignore files + # - cssho.vscode-svgviewer # SVG viewer + - davidanson.vscode-markdownlint # Markdown/CommonMark linting and style checking for Visual Studio Code + - eamodio.gitlens # Quickly glimpse into whom, why, and when a line or code block was changed + - EditorConfig.EditorConfig # override user/workspace settings with settings found in .editorconfig files + - Gruntfuggly.todo-tree # Display TODO and FIXME in a tree view in the activity bar + - mechatroner.rainbow-csv # Highlight columns in csv files in different colors + # - nextflow.nextflow # Nextflow syntax highlighting + - oderwat.indent-rainbow # Highlight indentation level + - streetsidesoftware.code-spell-checker # Spelling checker for source code diff --git a/.yamllint.yml b/.yamllint.yml new file mode 100644 index 000000000..6889fa342 --- /dev/null +++ b/.yamllint.yml @@ -0,0 +1,5 @@ +extends: default + +rules: + document-start: disable + line-length: disable diff --git a/CHANGELOG.md b/CHANGELOG.md index f1dd9c7a6..bf25fc541 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## v3.5dev - [date] +## v3.6dev - [date] Initial release of nf-core/rnaseq, created with the [nf-core](https://nf-co.re/) template. diff --git a/README.md b/README.md index c790e30a4..e560c421c 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ On release, automated continuous integration tests run the pipeline on a full-si > * The pipeline comes with config profiles called `docker`, `singularity`, `podman`, `shifter`, `charliecloud` and `conda` which instruct the pipeline to use the named tool for software management. For example, `-profile test,docker`. > * Please check [nf-core/configs](https://github.com/nf-core/configs#documentation) to see if a custom config file to run nf-core pipelines already exists for your Institute. If so, you can simply use `-profile ` in your command. This will enable either `docker` or `singularity` and set the appropriate execution settings for your local compute environment. - > * If you are using `singularity` and are persistently observing issues downloading Singularity images directly due to timeout or network issues, then you can use the `--singularity_pull_docker_container` parameter to pull and convert the Docker image instead. Alternatively, you can use the [`nf-core download`](https://nf-co.re/tools/#downloading-pipelines-for-offline-use) command to download images first, before running the pipeline. Setting the [`NXF_SINGULARITY_CACHEDIR` or `singularity.cacheDir`](https://www.nextflow.io/docs/latest/singularity.html?#singularity-docker-hub) Nextflow options enables you to store and re-use the images from a central location for future pipeline runs. + > * If you are using `singularity`, please use the [`nf-core download`](https://nf-co.re/tools/#downloading-pipelines-for-offline-use) command to download images first, before running the pipeline. Setting the [`NXF_SINGULARITY_CACHEDIR` or `singularity.cacheDir`](https://www.nextflow.io/docs/latest/singularity.html?#singularity-docker-hub) Nextflow options enables you to store and re-use the images from a central location for future pipeline runs. > * If you are using `conda`, it is highly recommended to use the [`NXF_CONDA_CACHEDIR` or `conda.cacheDir`](https://www.nextflow.io/docs/latest/conda.html) settings to store the environments in a central location for future pipeline runs. 4. Start running your own analysis! diff --git a/assets/nf-core-rnaseq_logo_light.png b/assets/nf-core-rnaseq_logo_light.png index 1993002f28494136e88a278dbbfcb5170b757b3e..5362512d3fea881e5c2cb09e697dc4106e72363a 100644 GIT binary patch literal 10453 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 literal 519 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%0D6Aha9ZZvy3Owj0R@{kHIA1_W(q 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�ev`Q}H7y#R1zKkC5n?0_OP7^FqWWeXhX0t0pNK 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

)bNtXB<>| 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 **NB:** We specify just the process name i.e. `STAR_ALIGN` in the config file and not the full task name string that is printed to screen in the error message or on the terminal whilst the pipeline is running i.e. `RNASEQ:ALIGN_STAR:STAR_ALIGN`. You may get a warning suggesting that the process selector isn't recognised but you can ignore that if the process name has been specified correctly. This is something that needs to be fixed upstream in core Nextflow. +> **NB:** We specify just the process name i.e. `STAR_ALIGN` in the config file and not the full task name string that is printed to screen in the error message or on the terminal whilst the pipeline is running i.e. `RNASEQ:ALIGN_STAR:STAR_ALIGN`. +> You may get a warning suggesting that the process selector isn't recognised but you can ignore that if the process name has been specified correctly. This is something that needs to be fixed upstream in core Nextflow. ### Updating containers diff --git a/lib/NfcoreSchema.groovy b/lib/NfcoreSchema.groovy index 40ab65f20..b3d092f80 100755 --- a/lib/NfcoreSchema.groovy +++ b/lib/NfcoreSchema.groovy @@ -27,7 +27,7 @@ class NfcoreSchema { /* groovylint-disable-next-line UnusedPrivateMethodParameter */ public static void validateParameters(workflow, params, log, schema_filename='nextflow_schema.json') { def has_error = false - //=====================================================================// + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// // Check for nextflow core params and unexpected params def json = new File(getSchemaPath(workflow, schema_filename=schema_filename)).text def Map schemaParams = (Map) new JsonSlurper().parseText(json).get('definitions') @@ -135,7 +135,7 @@ class NfcoreSchema { } } - //=====================================================================// + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// // Validate parameters against the schema InputStream input_stream = new File(getSchemaPath(workflow, schema_filename=schema_filename)).newInputStream() JSONObject raw_schema = new JSONObject(new JSONTokener(input_stream)) diff --git a/lib/Utils.groovy b/lib/Utils.groovy index 1b88aec0e..28567bd70 100755 --- a/lib/Utils.groovy +++ b/lib/Utils.groovy @@ -29,12 +29,12 @@ class Utils { conda_check_failed |= !(channels.indexOf('bioconda') < channels.indexOf('defaults')) if (conda_check_failed) { - log.warn "=============================================================================\n" + + log.warn "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " There is a problem with your Conda configuration!\n\n" + " You will need to set-up the conda-forge and bioconda channels correctly.\n" + " Please refer to https://bioconda.github.io/user/install.html#set-up-channels\n" + " NB: The order of the channels matters!\n" + - "===================================================================================" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" } } } diff --git a/lib/WorkflowRnaseq.groovy b/lib/WorkflowRnaseq.groovy index 652860185..b4dd76326 100755 --- a/lib/WorkflowRnaseq.groovy +++ b/lib/WorkflowRnaseq.groovy @@ -48,11 +48,11 @@ class WorkflowRnaseq { // private static void genomeExistsError(params, log) { if (params.genomes && params.genome && !params.genomes.containsKey(params.genome)) { - log.error "=============================================================================\n" + + log.error "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " Genome '${params.genome}' not found in any config files provided to the pipeline.\n" + " Currently, the available genome keys are:\n" + " ${params.genomes.keySet().join(", ")}\n" + - "===================================================================================" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" System.exit(1) } } diff --git a/main.nf b/main.nf index 544835c93..92b516125 100644 --- a/main.nf +++ b/main.nf @@ -1,8 +1,8 @@ #!/usr/bin/env nextflow /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ nf-core/rnaseq -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Github : https://github.com/nf-core/rnaseq Website: https://nf-co.re/rnaseq Slack : https://nfcore.slack.com/channels/rnaseq @@ -12,25 +12,25 @@ nextflow.enable.dsl = 2 /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GENOME PARAMETER VALUES -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ params.fasta = WorkflowMain.getGenomeAttribute(params, 'fasta') /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ VALIDATE & PRINT PARAMETER SUMMARY -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ WorkflowMain.initialise(workflow, params, log) /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NAMED WORKFLOW FOR PIPELINE -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ include { RNASEQ } from './workflows/rnaseq' @@ -43,9 +43,9 @@ workflow NFCORE_RNASEQ { } /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN ALL WORKFLOWS -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ // @@ -57,7 +57,7 @@ workflow { } /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ THE END -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/nextflow.config b/nextflow.config index 15cf3afc5..7b45617db 100644 --- a/nextflow.config +++ b/nextflow.config @@ -1,7 +1,7 @@ /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ nf-core/rnaseq Nextflow config file -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Default config options for all compute environments ---------------------------------------------------------------------------------------- */ @@ -121,7 +121,7 @@ if (!params.igenomes_ignore) { } // Export these variables to prevent local Python/R libraries from conflicting with those in the container -// The JULIA depot path has been adjusted to a fixed path `/usr/local/share/julia` that needs to be used for packages in the container. +// The JULIA depot path has been adjusted to a fixed path `/usr/local/share/julia` that needs to be used for packages in the container. // See https://apeltzer.github.io/post/03-julia-lang-nextflow/ for details on that. Once we have a common agreement on where to keep Julia packages, this is adjustable. env { @@ -159,7 +159,7 @@ manifest { description = 'Nextflow RNA-Seq analysis pipeline, part of the nf-core community.' mainScript = 'main.nf' nextflowVersion = '!>=21.10.3' - version = '3.5dev' + version = '3.6dev' } // Load modules.config for DSL2 module specific options diff --git a/workflows/rnaseq.nf b/workflows/rnaseq.nf index 448df871e..fe83987dd 100644 --- a/workflows/rnaseq.nf +++ b/workflows/rnaseq.nf @@ -1,7 +1,7 @@ /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ VALIDATE INPUTS -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ def summary_params = NfcoreSchema.paramsSummaryMap(workflow, params) @@ -18,18 +18,18 @@ for (param in checkPathParamList) { if (param) { file(param, checkIfExists: true if (params.input) { ch_input = file(params.input) } else { exit 1, 'Input samplesheet not specified!' } /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CONFIG FILES -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ ch_multiqc_config = file("$projectDir/assets/multiqc_config.yaml", checkIfExists: true) ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath(params.multiqc_config) : Channel.empty() /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IMPORT LOCAL MODULES/SUBWORKFLOWS -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ // @@ -38,9 +38,9 @@ ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath(params.multi include { INPUT_CHECK } from '../subworkflows/local/input_check' /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IMPORT NF-CORE MODULES/SUBWORKFLOWS -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ // @@ -51,9 +51,9 @@ include { MULTIQC } from '../modules/nf-core/modules/multiqc include { CUSTOM_DUMPSOFTWAREVERSIONS } from '../modules/nf-core/modules/custom/dumpsoftwareversions/main' /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN MAIN WORKFLOW -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ // Info required for completion email and summary @@ -104,9 +104,9 @@ workflow RNASEQ { } /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ COMPLETION EMAIL AND SUMMARY -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ workflow.onComplete { @@ -117,7 +117,7 @@ workflow.onComplete { } /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ THE END -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ From 8fba44437892213858a9c4f86993e681b2fac4c3 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 15 Feb 2022 16:54:44 +0000 Subject: [PATCH 12/36] Sync pipeline with nf-core/tools dev to fix linting --- .github/workflows/branch.yml | 1 - .github/workflows/linting.yml | 1 - .github/workflows/linting_comment.yml | 2 - .nf-core.yml | 16 +-- modules.json | 70 ++++++------ .../nf-core/modules/bbmap/bbsplit/meta.yml | 2 +- modules/nf-core/modules/cat/fastq/meta.yml | 62 +++++------ .../custom/dumpsoftwareversions/meta.yml | 2 +- modules/nf-core/modules/fastqc/meta.yml | 90 +++++++-------- modules/nf-core/modules/gffread/meta.yml | 8 +- modules/nf-core/modules/gunzip/meta.yml | 54 ++++----- modules/nf-core/modules/hisat2/align/meta.yml | 22 ++-- modules/nf-core/modules/hisat2/build/meta.yml | 12 +- .../hisat2/extractsplicesites/meta.yml | 10 +- .../modules/picard/markduplicates/meta.yml | 2 +- .../nf-core/modules/preseq/lcextrap/meta.yml | 2 +- .../modules/rsem/calculateexpression/meta.yml | 2 +- .../modules/rsem/preparereference/meta.yml | 2 +- .../nf-core/modules/rseqc/bamstat/meta.yml | 2 +- .../modules/rseqc/inferexperiment/meta.yml | 2 +- .../modules/rseqc/innerdistance/meta.yml | 2 +- .../modules/rseqc/junctionannotation/meta.yml | 2 +- .../modules/rseqc/junctionsaturation/meta.yml | 2 +- .../modules/rseqc/readdistribution/meta.yml | 2 +- .../modules/rseqc/readduplication/meta.yml | 2 +- modules/nf-core/modules/rseqc/tin/meta.yml | 2 +- modules/nf-core/modules/salmon/index/meta.yml | 2 +- modules/nf-core/modules/salmon/quant/meta.yml | 2 +- .../modules/samtools/flagstat/meta.yml | 84 +++++++------- .../modules/samtools/idxstats/meta.yml | 86 +++++++-------- .../nf-core/modules/samtools/index/meta.yml | 92 ++++++++-------- .../nf-core/modules/samtools/sort/meta.yml | 74 ++++++------- .../nf-core/modules/samtools/stats/meta.yml | 90 +++++++-------- .../modules/stringtie/stringtie/meta.yml | 98 ++++++++--------- .../modules/subread/featurecounts/meta.yml | 18 +-- modules/nf-core/modules/trimgalore/meta.yml | 104 +++++++++--------- modules/nf-core/modules/ucsc/bedclip/meta.yml | 2 +- .../nf-core/modules/umitools/dedup/meta.yml | 78 ++++++------- .../nf-core/modules/umitools/extract/meta.yml | 77 ++++++------- modules/nf-core/modules/untar/meta.yml | 42 +++---- 40 files changed, 611 insertions(+), 614 deletions(-) diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml index 3f0ef0d76..8d737d65c 100644 --- a/.github/workflows/branch.yml +++ b/.github/workflows/branch.yml @@ -43,4 +43,3 @@ jobs: Thanks again for your contribution! repo-token: ${{ secrets.GITHUB_TOKEN }} allow-repeats: false - diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index b7c3159c7..0c9c55544 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -136,4 +136,3 @@ jobs: lint_log.txt lint_results.md PR_number.txt - diff --git a/.github/workflows/linting_comment.yml b/.github/workflows/linting_comment.yml index 44d72994b..04758f61e 100644 --- a/.github/workflows/linting_comment.yml +++ b/.github/workflows/linting_comment.yml @@ -1,4 +1,3 @@ - name: nf-core linting comment # This workflow is triggered after the linting action is complete # It posts an automated comment to the PR, even if the PR is coming from a fork @@ -27,4 +26,3 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} number: ${{ steps.pr_number.outputs.pr_number }} path: linting-logs/lint_results.md - diff --git a/.nf-core.yml b/.nf-core.yml index a794b875c..e04c0c3fd 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -5,11 +5,11 @@ lint: - lib/NfcoreTemplate.groovy update: nf-core/modules: - rseqc/bamstat: "e20e57f90b6787ac9a010a980cf6ea98bd990046" - rseqc/inferexperiment: "e20e57f90b6787ac9a010a980cf6ea98bd990046" - rseqc/innerdistance: "e20e57f90b6787ac9a010a980cf6ea98bd990046" - rseqc/junctionannotation: "e20e57f90b6787ac9a010a980cf6ea98bd990046" - rseqc/junctionsaturation: "e20e57f90b6787ac9a010a980cf6ea98bd990046" - rseqc/readdistribution: "e20e57f90b6787ac9a010a980cf6ea98bd990046" - rseqc/readduplication: "e20e57f90b6787ac9a010a980cf6ea98bd990046" - rseqc/tin: "e20e57f90b6787ac9a010a980cf6ea98bd990046" + rseqc/bamstat: "e745e167c1020928ef20ea1397b6b4d230681b4d" + rseqc/inferexperiment: "e745e167c1020928ef20ea1397b6b4d230681b4d" + rseqc/innerdistance: "e745e167c1020928ef20ea1397b6b4d230681b4d" + rseqc/junctionannotation: "e745e167c1020928ef20ea1397b6b4d230681b4d" + rseqc/junctionsaturation: "e745e167c1020928ef20ea1397b6b4d230681b4d" + rseqc/readdistribution: "e745e167c1020928ef20ea1397b6b4d230681b4d" + rseqc/readduplication: "e745e167c1020928ef20ea1397b6b4d230681b4d" + rseqc/tin: "e745e167c1020928ef20ea1397b6b4d230681b4d" diff --git a/modules.json b/modules.json index 837b8daa7..a31a984ff 100644 --- a/modules.json +++ b/modules.json @@ -4,118 +4,118 @@ "repos": { "nf-core/modules": { "bbmap/bbsplit": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "cat/fastq": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "custom/dumpsoftwareversions": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "fastqc": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "gffread": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "gunzip": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "hisat2/align": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "hisat2/build": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "hisat2/extractsplicesites": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "picard/markduplicates": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "preseq/lcextrap": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "qualimap/rnaseq": { "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "rsem/calculateexpression": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "rsem/preparereference": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "rseqc/bamstat": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "rseqc/inferexperiment": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "rseqc/innerdistance": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "rseqc/junctionannotation": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "rseqc/junctionsaturation": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "rseqc/readdistribution": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "rseqc/readduplication": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "rseqc/tin": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "salmon/index": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "salmon/quant": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "samtools/flagstat": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "samtools/idxstats": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "samtools/index": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "samtools/sort": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "samtools/stats": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "sortmerna": { "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "stringtie/stringtie": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "subread/featurecounts": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "trimgalore": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "ucsc/bedclip": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "ucsc/bedgraphtobigwig": { "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" }, "umitools/dedup": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "umitools/extract": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "untar": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" } } } diff --git a/modules/nf-core/modules/bbmap/bbsplit/meta.yml b/modules/nf-core/modules/bbmap/bbsplit/meta.yml index 2e3d07c01..9d9f10daf 100644 --- a/modules/nf-core/modules/bbmap/bbsplit/meta.yml +++ b/modules/nf-core/modules/bbmap/bbsplit/meta.yml @@ -12,7 +12,7 @@ tools: documentation: https://jgi.doe.gov/data-and-tools/bbtools/bb-tools-user-guide/ tool_dev_url: None doi: "" - licence: ['UC-LBL license (see package)'] + licence: ["UC-LBL license (see package)"] input: - meta: diff --git a/modules/nf-core/modules/cat/fastq/meta.yml b/modules/nf-core/modules/cat/fastq/meta.yml index 1992fa34e..c836598e4 100644 --- a/modules/nf-core/modules/cat/fastq/meta.yml +++ b/modules/nf-core/modules/cat/fastq/meta.yml @@ -1,39 +1,39 @@ name: cat_fastq description: Concatenates fastq files keywords: - - fastq - - concatenate + - fastq + - concatenate tools: - - cat: - description: | - The cat utility reads files sequentially, writing them to the standard output. - documentation: https://www.gnu.org/software/coreutils/manual/html_node/cat-invocation.html - licence: ['GPL-3.0-or-later'] + - cat: + description: | + The cat utility reads files sequentially, writing them to the standard output. + documentation: https://www.gnu.org/software/coreutils/manual/html_node/cat-invocation.html + licence: ["GPL-3.0-or-later"] input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - reads: - type: list - description: | - List of input FastQ files to be concatenated. + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: list + description: | + List of input FastQ files to be concatenated. output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - reads: - type: file - description: Merged fastq file - pattern: "*.{merged.fastq.gz}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: Merged fastq file + pattern: "*.{merged.fastq.gz}" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - - "@joseespinosa" - - "@drpatelh" + - "@joseespinosa" + - "@drpatelh" diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/meta.yml b/modules/nf-core/modules/custom/dumpsoftwareversions/meta.yml index 5b5b8a602..60b546a01 100644 --- a/modules/nf-core/modules/custom/dumpsoftwareversions/meta.yml +++ b/modules/nf-core/modules/custom/dumpsoftwareversions/meta.yml @@ -8,7 +8,7 @@ tools: description: Custom module used to dump software versions within the nf-core pipeline template homepage: https://github.com/nf-core/tools documentation: https://github.com/nf-core/tools - licence: ['MIT'] + licence: ["MIT"] input: - versions: type: file diff --git a/modules/nf-core/modules/fastqc/meta.yml b/modules/nf-core/modules/fastqc/meta.yml index b09553a3c..4da5bb5a0 100644 --- a/modules/nf-core/modules/fastqc/meta.yml +++ b/modules/nf-core/modules/fastqc/meta.yml @@ -1,52 +1,52 @@ name: fastqc description: Run FastQC on sequenced reads keywords: - - quality control - - qc - - adapters - - fastq + - quality control + - qc + - adapters + - fastq tools: - - fastqc: - description: | - FastQC gives general quality metrics about your reads. - It provides information about the quality score distribution - across your reads, the per base sequence content (%A/C/G/T). - You get information about adapter contamination and other - overrepresented sequences. - homepage: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/ - documentation: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/Help/ - licence: ['GPL-2.0-only'] + - fastqc: + description: | + FastQC gives general quality metrics about your reads. + It provides information about the quality score distribution + across your reads, the per base sequence content (%A/C/G/T). + You get information about adapter contamination and other + overrepresented sequences. + homepage: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/ + documentation: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/Help/ + licence: ["GPL-2.0-only"] input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - reads: - type: file - description: | - List of input FastQ files of size 1 and 2 for single-end and paired-end data, - respectively. + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: | + List of input FastQ files of size 1 and 2 for single-end and paired-end data, + respectively. output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - html: - type: file - description: FastQC report - pattern: "*_{fastqc.html}" - - zip: - type: file - description: FastQC report archive - pattern: "*_{fastqc.zip}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - html: + type: file + description: FastQC report + pattern: "*_{fastqc.html}" + - zip: + type: file + description: FastQC report archive + pattern: "*_{fastqc.zip}" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - - "@drpatelh" - - "@grst" - - "@ewels" - - "@FelixKrueger" + - "@drpatelh" + - "@grst" + - "@ewels" + - "@FelixKrueger" diff --git a/modules/nf-core/modules/gffread/meta.yml b/modules/nf-core/modules/gffread/meta.yml index bf1a15cba..203357477 100644 --- a/modules/nf-core/modules/gffread/meta.yml +++ b/modules/nf-core/modules/gffread/meta.yml @@ -11,13 +11,13 @@ tools: documentation: http://ccb.jhu.edu/software/stringtie/gff.shtml#gffread tool_dev_url: https://github.com/gpertea/gffread doi: 10.12688/f1000research.23297.1 - licence: ['MIT'] + licence: ["MIT"] input: - gff: - type: file - description: A reference file in either the GFF3, GFF2 or GTF format. - pattern: "*.{gff, gtf}" + type: file + description: A reference file in either the GFF3, GFF2 or GTF format. + pattern: "*.{gff, gtf}" output: - gtf: diff --git a/modules/nf-core/modules/gunzip/meta.yml b/modules/nf-core/modules/gunzip/meta.yml index ea1f15460..4d2ebc84e 100644 --- a/modules/nf-core/modules/gunzip/meta.yml +++ b/modules/nf-core/modules/gunzip/meta.yml @@ -1,34 +1,34 @@ name: gunzip description: Compresses and decompresses files. keywords: - - gunzip - - compression + - gunzip + - compression tools: - - gunzip: - description: | - gzip is a file format and a software application used for file compression and decompression. - documentation: https://www.gnu.org/software/gzip/manual/gzip.html - licence: ['GPL-3.0-or-later'] + - gunzip: + description: | + gzip is a file format and a software application used for file compression and decompression. + documentation: https://www.gnu.org/software/gzip/manual/gzip.html + licence: ["GPL-3.0-or-later"] input: - - meta: - type: map - description: | - Optional groovy Map containing meta information - e.g. [ id:'test', single_end:false ] - - archive: - type: file - description: File to be compressed/uncompressed - pattern: "*.*" + - meta: + type: map + description: | + Optional groovy Map containing meta information + e.g. [ id:'test', single_end:false ] + - archive: + type: file + description: File to be compressed/uncompressed + pattern: "*.*" output: - - gunzip: - type: file - description: Compressed/uncompressed file - pattern: "*.*" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + - gunzip: + type: file + description: Compressed/uncompressed file + pattern: "*.*" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - - "@joseespinosa" - - "@drpatelh" - - "@jfy133" + - "@joseespinosa" + - "@drpatelh" + - "@jfy133" diff --git a/modules/nf-core/modules/hisat2/align/meta.yml b/modules/nf-core/modules/hisat2/align/meta.yml index 6011cc342..7550aefab 100644 --- a/modules/nf-core/modules/hisat2/align/meta.yml +++ b/modules/nf-core/modules/hisat2/align/meta.yml @@ -1,10 +1,10 @@ name: hisat2_align description: Align RNA-Seq reads to a reference with HISAT2 keywords: - - align - - fasta - - genome - - reference + - align + - fasta + - genome + - reference tools: - hisat2: @@ -12,19 +12,19 @@ tools: homepage: https://daehwankimlab.github.io/hisat2/ documentation: https://daehwankimlab.github.io/hisat2/manual/ doi: "10.1038/s41587-019-0201-4" - licence: ['MIT'] + licence: ["MIT"] input: - meta: type: map description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] - reads: type: file description: | - List of input FastQ files of size 1 and 2 for single-end and paired-end data, - respectively. + List of input FastQ files of size 1 and 2 for single-end and paired-end data, + respectively. - index: type: file description: HISAT2 genome index file @@ -38,8 +38,8 @@ output: - meta: type: map description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] - bam: type: file description: Output BAM file containing read alignments diff --git a/modules/nf-core/modules/hisat2/build/meta.yml b/modules/nf-core/modules/hisat2/build/meta.yml index c08b296df..a2e1fd67e 100644 --- a/modules/nf-core/modules/hisat2/build/meta.yml +++ b/modules/nf-core/modules/hisat2/build/meta.yml @@ -1,18 +1,18 @@ name: hisat2_build description: Builds HISAT2 index for reference genome keywords: - - build - - index - - fasta - - genome - - reference + - build + - index + - fasta + - genome + - reference tools: - hisat2: description: HISAT2 is a fast and sensitive alignment program for mapping next-generation sequencing reads (both DNA and RNA) to a population of human genomes as well as to a single reference genome. homepage: https://daehwankimlab.github.io/hisat2/ documentation: https://daehwankimlab.github.io/hisat2/manual/ doi: "10.1038/s41587-019-0201-4" - licence: ['MIT'] + licence: ["MIT"] input: - fasta: diff --git a/modules/nf-core/modules/hisat2/extractsplicesites/meta.yml b/modules/nf-core/modules/hisat2/extractsplicesites/meta.yml index 97227faf1..7dc1bac81 100644 --- a/modules/nf-core/modules/hisat2/extractsplicesites/meta.yml +++ b/modules/nf-core/modules/hisat2/extractsplicesites/meta.yml @@ -1,10 +1,10 @@ name: hisat2_extractsplicesites description: Extracts splicing sites from a gtf files keywords: - - splicing - - gtf - - genome - - reference + - splicing + - gtf + - genome + - reference tools: - hisat2: @@ -12,7 +12,7 @@ tools: homepage: https://daehwankimlab.github.io/hisat2/ documentation: https://daehwankimlab.github.io/hisat2/manual/ doi: "10.1038/s41587-019-0201-4" - licence: ['MIT'] + licence: ["MIT"] input: - gtf: diff --git a/modules/nf-core/modules/picard/markduplicates/meta.yml b/modules/nf-core/modules/picard/markduplicates/meta.yml index c9a08b36f..842817bcd 100644 --- a/modules/nf-core/modules/picard/markduplicates/meta.yml +++ b/modules/nf-core/modules/picard/markduplicates/meta.yml @@ -14,7 +14,7 @@ tools: data and formats such as SAM/BAM/CRAM and VCF. homepage: https://broadinstitute.github.io/picard/ documentation: https://broadinstitute.github.io/picard/ - licence: ['MIT'] + licence: ["MIT"] input: - meta: type: map diff --git a/modules/nf-core/modules/preseq/lcextrap/meta.yml b/modules/nf-core/modules/preseq/lcextrap/meta.yml index bdc61228f..0e33df250 100644 --- a/modules/nf-core/modules/preseq/lcextrap/meta.yml +++ b/modules/nf-core/modules/preseq/lcextrap/meta.yml @@ -11,7 +11,7 @@ tools: documentation: None tool_dev_url: None doi: "" - licence: ['GPL'] + licence: ["GPL"] input: - meta: diff --git a/modules/nf-core/modules/rsem/calculateexpression/meta.yml b/modules/nf-core/modules/rsem/calculateexpression/meta.yml index fdfaa0c41..10b54b490 100644 --- a/modules/nf-core/modules/rsem/calculateexpression/meta.yml +++ b/modules/nf-core/modules/rsem/calculateexpression/meta.yml @@ -21,7 +21,7 @@ input: - reads: type: file description: Input reads for quantification - pattern: "*.fastq.gz"# + pattern: "*.fastq.gz" - index: type: file description: RSEM index diff --git a/modules/nf-core/modules/rsem/preparereference/meta.yml b/modules/nf-core/modules/rsem/preparereference/meta.yml index 062f0256a..fbe57b203 100644 --- a/modules/nf-core/modules/rsem/preparereference/meta.yml +++ b/modules/nf-core/modules/rsem/preparereference/meta.yml @@ -10,7 +10,7 @@ tools: homepage: https://github.com/deweylab/RSEM documentation: https://github.com/deweylab/RSEM doi: https://doi.org/10.1186/1471-2105-12-323 - licence: ['GPL-3.0-or-later'] + licence: ["GPL-3.0-or-later"] input: - fasta: type: file diff --git a/modules/nf-core/modules/rseqc/bamstat/meta.yml b/modules/nf-core/modules/rseqc/bamstat/meta.yml index 561ba1958..2d7fa7996 100644 --- a/modules/nf-core/modules/rseqc/bamstat/meta.yml +++ b/modules/nf-core/modules/rseqc/bamstat/meta.yml @@ -12,7 +12,7 @@ tools: homepage: http://rseqc.sourceforge.net/ documentation: http://rseqc.sourceforge.net/ doi: 10.1093/bioinformatics/bts356 - licence: ['GPL-3.0-or-later'] + licence: ["GPL-3.0-or-later"] input: - meta: type: map diff --git a/modules/nf-core/modules/rseqc/inferexperiment/meta.yml b/modules/nf-core/modules/rseqc/inferexperiment/meta.yml index 88eabc8a3..b4162059d 100644 --- a/modules/nf-core/modules/rseqc/inferexperiment/meta.yml +++ b/modules/nf-core/modules/rseqc/inferexperiment/meta.yml @@ -11,7 +11,7 @@ tools: homepage: http://rseqc.sourceforge.net/ documentation: http://rseqc.sourceforge.net/ doi: 10.1093/bioinformatics/bts356 - licence: ['GPL-3.0-or-later'] + licence: ["GPL-3.0-or-later"] input: - meta: type: map diff --git a/modules/nf-core/modules/rseqc/innerdistance/meta.yml b/modules/nf-core/modules/rseqc/innerdistance/meta.yml index 27bcf2424..d10a4c445 100644 --- a/modules/nf-core/modules/rseqc/innerdistance/meta.yml +++ b/modules/nf-core/modules/rseqc/innerdistance/meta.yml @@ -11,7 +11,7 @@ tools: homepage: http://rseqc.sourceforge.net/ documentation: http://rseqc.sourceforge.net/ doi: 10.1093/bioinformatics/bts356 - licence: ['GPL-3.0-or-later'] + licence: ["GPL-3.0-or-later"] input: - meta: type: map diff --git a/modules/nf-core/modules/rseqc/junctionannotation/meta.yml b/modules/nf-core/modules/rseqc/junctionannotation/meta.yml index 56364232f..a17b84e91 100644 --- a/modules/nf-core/modules/rseqc/junctionannotation/meta.yml +++ b/modules/nf-core/modules/rseqc/junctionannotation/meta.yml @@ -12,7 +12,7 @@ tools: homepage: http://rseqc.sourceforge.net/ documentation: http://rseqc.sourceforge.net/ doi: 10.1093/bioinformatics/bts356 - licence: ['GPL-3.0-or-later'] + licence: ["GPL-3.0-or-later"] input: - meta: type: map diff --git a/modules/nf-core/modules/rseqc/junctionsaturation/meta.yml b/modules/nf-core/modules/rseqc/junctionsaturation/meta.yml index 05d814ada..340fec0d0 100644 --- a/modules/nf-core/modules/rseqc/junctionsaturation/meta.yml +++ b/modules/nf-core/modules/rseqc/junctionsaturation/meta.yml @@ -12,7 +12,7 @@ tools: homepage: http://rseqc.sourceforge.net/ documentation: http://rseqc.sourceforge.net/ doi: 10.1093/bioinformatics/bts356 - licence: ['GPL-3.0-or-later'] + licence: ["GPL-3.0-or-later"] input: - meta: type: map diff --git a/modules/nf-core/modules/rseqc/readdistribution/meta.yml b/modules/nf-core/modules/rseqc/readdistribution/meta.yml index 4c7368789..94c647120 100644 --- a/modules/nf-core/modules/rseqc/readdistribution/meta.yml +++ b/modules/nf-core/modules/rseqc/readdistribution/meta.yml @@ -12,7 +12,7 @@ tools: homepage: http://rseqc.sourceforge.net/ documentation: http://rseqc.sourceforge.net/ doi: 10.1093/bioinformatics/bts356 - licence: ['GPL-3.0-or-later'] + licence: ["GPL-3.0-or-later"] input: - meta: type: map diff --git a/modules/nf-core/modules/rseqc/readduplication/meta.yml b/modules/nf-core/modules/rseqc/readduplication/meta.yml index 3623de804..5a8666435 100644 --- a/modules/nf-core/modules/rseqc/readduplication/meta.yml +++ b/modules/nf-core/modules/rseqc/readduplication/meta.yml @@ -11,7 +11,7 @@ tools: homepage: http://rseqc.sourceforge.net/ documentation: http://rseqc.sourceforge.net/ doi: 10.1093/bioinformatics/bts356 - licence: ['GPL-3.0-or-later'] + licence: ["GPL-3.0-or-later"] input: - meta: type: map diff --git a/modules/nf-core/modules/rseqc/tin/meta.yml b/modules/nf-core/modules/rseqc/tin/meta.yml index 158b4033c..6333ae14c 100644 --- a/modules/nf-core/modules/rseqc/tin/meta.yml +++ b/modules/nf-core/modules/rseqc/tin/meta.yml @@ -12,7 +12,7 @@ tools: homepage: http://rseqc.sourceforge.net/ documentation: http://rseqc.sourceforge.net/ doi: 10.1093/bioinformatics/bts356 - licence: ['GPL-3.0-or-later'] + licence: ["GPL-3.0-or-later"] input: - meta: type: map diff --git a/modules/nf-core/modules/salmon/index/meta.yml b/modules/nf-core/modules/salmon/index/meta.yml index 3b0cd853f..53c64152f 100644 --- a/modules/nf-core/modules/salmon/index/meta.yml +++ b/modules/nf-core/modules/salmon/index/meta.yml @@ -12,7 +12,7 @@ tools: homepage: https://salmon.readthedocs.io/en/latest/salmon.html manual: https://salmon.readthedocs.io/en/latest/salmon.html doi: 10.1038/nmeth.4197 - licence: ['GPL-3.0-or-later'] + licence: ["GPL-3.0-or-later"] input: - genome_fasta: type: file diff --git a/modules/nf-core/modules/salmon/quant/meta.yml b/modules/nf-core/modules/salmon/quant/meta.yml index 223ca82b6..109109d8f 100644 --- a/modules/nf-core/modules/salmon/quant/meta.yml +++ b/modules/nf-core/modules/salmon/quant/meta.yml @@ -12,7 +12,7 @@ tools: homepage: https://salmon.readthedocs.io/en/latest/salmon.html manual: https://salmon.readthedocs.io/en/latest/salmon.html doi: 10.1038/nmeth.4197 - licence: ['GPL-3.0-or-later'] + licence: ["GPL-3.0-or-later"] input: - meta: type: map diff --git a/modules/nf-core/modules/samtools/flagstat/meta.yml b/modules/nf-core/modules/samtools/flagstat/meta.yml index 9bd9ff891..952690639 100644 --- a/modules/nf-core/modules/samtools/flagstat/meta.yml +++ b/modules/nf-core/modules/samtools/flagstat/meta.yml @@ -1,49 +1,49 @@ name: samtools_flagstat description: Counts the number of alignments in a BAM/CRAM/SAM file for each FLAG type keywords: - - stats - - mapping - - counts - - bam - - sam - - cram + - stats + - mapping + - counts + - bam + - sam + - cram tools: - - samtools: - description: | - SAMtools is a set of utilities for interacting with and post-processing - short DNA sequence read alignments in the SAM, BAM and CRAM formats, written by Heng Li. - These files are generated as output by short read aligners like BWA. - homepage: http://www.htslib.org/ - documentation: hhttp://www.htslib.org/doc/samtools.html - doi: 10.1093/bioinformatics/btp352 - licence: ['MIT'] + - samtools: + description: | + SAMtools is a set of utilities for interacting with and post-processing + short DNA sequence read alignments in the SAM, BAM and CRAM formats, written by Heng Li. + These files are generated as output by short read aligners like BWA. + homepage: http://www.htslib.org/ + documentation: hhttp://www.htslib.org/doc/samtools.html + doi: 10.1093/bioinformatics/btp352 + licence: ["MIT"] input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: BAM/CRAM/SAM file - pattern: "*.{bam,cram,sam}" - - bai: - type: file - description: Index for BAM/CRAM/SAM file - pattern: "*.{bai,crai,sai}" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: BAM/CRAM/SAM file + pattern: "*.{bam,cram,sam}" + - bai: + type: file + description: Index for BAM/CRAM/SAM file + pattern: "*.{bai,crai,sai}" output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - flagstat: - type: file - description: File containing samtools flagstat output - pattern: "*.{flagstat}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - flagstat: + type: file + description: File containing samtools flagstat output + pattern: "*.{flagstat}" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - - "@drpatelh" + - "@drpatelh" diff --git a/modules/nf-core/modules/samtools/idxstats/meta.yml b/modules/nf-core/modules/samtools/idxstats/meta.yml index ec542f34b..3710ab882 100644 --- a/modules/nf-core/modules/samtools/idxstats/meta.yml +++ b/modules/nf-core/modules/samtools/idxstats/meta.yml @@ -1,50 +1,50 @@ name: samtools_idxstats description: Reports alignment summary statistics for a BAM/CRAM/SAM file keywords: - - stats - - mapping - - counts - - chromosome - - bam - - sam - - cram + - stats + - mapping + - counts + - chromosome + - bam + - sam + - cram tools: - - samtools: - description: | - SAMtools is a set of utilities for interacting with and post-processing - short DNA sequence read alignments in the SAM, BAM and CRAM formats, written by Heng Li. - These files are generated as output by short read aligners like BWA. - homepage: http://www.htslib.org/ - documentation: hhttp://www.htslib.org/doc/samtools.html - doi: 10.1093/bioinformatics/btp352 - licence: ['MIT'] + - samtools: + description: | + SAMtools is a set of utilities for interacting with and post-processing + short DNA sequence read alignments in the SAM, BAM and CRAM formats, written by Heng Li. + These files are generated as output by short read aligners like BWA. + homepage: http://www.htslib.org/ + documentation: hhttp://www.htslib.org/doc/samtools.html + doi: 10.1093/bioinformatics/btp352 + licence: ["MIT"] input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: BAM/CRAM/SAM file - pattern: "*.{bam,cram,sam}" - - bai: - type: file - description: Index for BAM/CRAM/SAM file - pattern: "*.{bai,crai,sai}" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: BAM/CRAM/SAM file + pattern: "*.{bam,cram,sam}" + - bai: + type: file + description: Index for BAM/CRAM/SAM file + pattern: "*.{bai,crai,sai}" output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - idxstats: - type: file - description: File containing samtools idxstats output - pattern: "*.{idxstats}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - idxstats: + type: file + description: File containing samtools idxstats output + pattern: "*.{idxstats}" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - - "@drpatelh" + - "@drpatelh" diff --git a/modules/nf-core/modules/samtools/index/meta.yml b/modules/nf-core/modules/samtools/index/meta.yml index 0905b3cd6..e5cadbc24 100644 --- a/modules/nf-core/modules/samtools/index/meta.yml +++ b/modules/nf-core/modules/samtools/index/meta.yml @@ -1,53 +1,53 @@ name: samtools_index description: Index SAM/BAM/CRAM file keywords: - - index - - bam - - sam - - cram + - index + - bam + - sam + - cram tools: - - samtools: - description: | - SAMtools is a set of utilities for interacting with and post-processing - short DNA sequence read alignments in the SAM, BAM and CRAM formats, written by Heng Li. - These files are generated as output by short read aligners like BWA. - homepage: http://www.htslib.org/ - documentation: hhttp://www.htslib.org/doc/samtools.html - doi: 10.1093/bioinformatics/btp352 - licence: ['MIT'] + - samtools: + description: | + SAMtools is a set of utilities for interacting with and post-processing + short DNA sequence read alignments in the SAM, BAM and CRAM formats, written by Heng Li. + These files are generated as output by short read aligners like BWA. + homepage: http://www.htslib.org/ + documentation: hhttp://www.htslib.org/doc/samtools.html + doi: 10.1093/bioinformatics/btp352 + licence: ["MIT"] input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: BAM/CRAM/SAM file - pattern: "*.{bam,cram,sam}" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: BAM/CRAM/SAM file + pattern: "*.{bam,cram,sam}" output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bai: - type: file - description: BAM/CRAM/SAM index file - pattern: "*.{bai,crai,sai}" - - crai: - type: file - description: BAM/CRAM/SAM index file - pattern: "*.{bai,crai,sai}" - - csi: - type: file - description: CSI index file - pattern: "*.{csi}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bai: + type: file + description: BAM/CRAM/SAM index file + pattern: "*.{bai,crai,sai}" + - crai: + type: file + description: BAM/CRAM/SAM index file + pattern: "*.{bai,crai,sai}" + - csi: + type: file + description: CSI index file + pattern: "*.{csi}" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - - "@drpatelh" - - "@ewels" - - "@maxulysse" + - "@drpatelh" + - "@ewels" + - "@maxulysse" diff --git a/modules/nf-core/modules/samtools/sort/meta.yml b/modules/nf-core/modules/samtools/sort/meta.yml index 3402a0680..a820c55a3 100644 --- a/modules/nf-core/modules/samtools/sort/meta.yml +++ b/modules/nf-core/modules/samtools/sort/meta.yml @@ -1,44 +1,44 @@ name: samtools_sort description: Sort SAM/BAM/CRAM file keywords: - - sort - - bam - - sam - - cram + - sort + - bam + - sam + - cram tools: - - samtools: - description: | - SAMtools is a set of utilities for interacting with and post-processing - short DNA sequence read alignments in the SAM, BAM and CRAM formats, written by Heng Li. - These files are generated as output by short read aligners like BWA. - homepage: http://www.htslib.org/ - documentation: hhttp://www.htslib.org/doc/samtools.html - doi: 10.1093/bioinformatics/btp352 - licence: ['MIT'] + - samtools: + description: | + SAMtools is a set of utilities for interacting with and post-processing + short DNA sequence read alignments in the SAM, BAM and CRAM formats, written by Heng Li. + These files are generated as output by short read aligners like BWA. + homepage: http://www.htslib.org/ + documentation: hhttp://www.htslib.org/doc/samtools.html + doi: 10.1093/bioinformatics/btp352 + licence: ["MIT"] input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: BAM/CRAM/SAM file - pattern: "*.{bam,cram,sam}" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: BAM/CRAM/SAM file + pattern: "*.{bam,cram,sam}" output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: Sorted BAM/CRAM/SAM file - pattern: "*.{bam,cram,sam}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: Sorted BAM/CRAM/SAM file + pattern: "*.{bam,cram,sam}" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - - "@drpatelh" - - "@ewels" + - "@drpatelh" + - "@ewels" diff --git a/modules/nf-core/modules/samtools/stats/meta.yml b/modules/nf-core/modules/samtools/stats/meta.yml index 869e62e37..cac50b1c0 100644 --- a/modules/nf-core/modules/samtools/stats/meta.yml +++ b/modules/nf-core/modules/samtools/stats/meta.yml @@ -1,53 +1,53 @@ name: samtools_stats description: Produces comprehensive statistics from SAM/BAM/CRAM file keywords: - - statistics - - counts - - bam - - sam - - cram + - statistics + - counts + - bam + - sam + - cram tools: - - samtools: - description: | - SAMtools is a set of utilities for interacting with and post-processing - short DNA sequence read alignments in the SAM, BAM and CRAM formats, written by Heng Li. - These files are generated as output by short read aligners like BWA. - homepage: http://www.htslib.org/ - documentation: hhttp://www.htslib.org/doc/samtools.html - doi: 10.1093/bioinformatics/btp352 - licence: ['MIT'] + - samtools: + description: | + SAMtools is a set of utilities for interacting with and post-processing + short DNA sequence read alignments in the SAM, BAM and CRAM formats, written by Heng Li. + These files are generated as output by short read aligners like BWA. + homepage: http://www.htslib.org/ + documentation: hhttp://www.htslib.org/doc/samtools.html + doi: 10.1093/bioinformatics/btp352 + licence: ["MIT"] input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - input: + type: file + description: BAM/CRAM file from alignment + pattern: "*.{bam,cram}" + - input_index: + type: file + description: BAI/CRAI file from alignment + pattern: "*.{bai,crai}" + - fasta: + type: optional file + description: Reference file the CRAM was created with + pattern: "*.{fasta,fa}" +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - stats: type: file - description: BAM/CRAM file from alignment - pattern: "*.{bam,cram}" - - input_index: + description: File containing samtools stats output + pattern: "*.{stats}" + - versions: type: file - description: BAI/CRAI file from alignment - pattern: "*.{bai,crai}" - - fasta: - type: optional file - description: Reference file the CRAM was created with - pattern: "*.{fasta,fa}" -output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - stats: - type: file - description: File containing samtools stats output - pattern: "*.{stats}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + description: File containing software versions + pattern: "versions.yml" authors: - - "@drpatelh" - - "@FriederikeHanssen" + - "@drpatelh" + - "@FriederikeHanssen" diff --git a/modules/nf-core/modules/stringtie/stringtie/meta.yml b/modules/nf-core/modules/stringtie/stringtie/meta.yml index 7e854caa4..a462c574e 100644 --- a/modules/nf-core/modules/stringtie/stringtie/meta.yml +++ b/modules/nf-core/modules/stringtie/stringtie/meta.yml @@ -1,57 +1,57 @@ name: stringtie description: Transcript assembly and quantification for RNA-Se keywords: - - transcript - - assembly - - quantification - - gtf + - transcript + - assembly + - quantification + - gtf tools: - - stringtie2: - description: | - Transcript assembly and quantification for RNA-Seq - homepage: https://ccb.jhu.edu/software/stringtie/index.shtml - documentation: https://ccb.jhu.edu/software/stringtie/index.shtml?t=manual - licence: ['MIT'] + - stringtie2: + description: | + Transcript assembly and quantification for RNA-Seq + homepage: https://ccb.jhu.edu/software/stringtie/index.shtml + documentation: https://ccb.jhu.edu/software/stringtie/index.shtml?t=manual + licence: ["MIT"] input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: | - Stringtie transcript gtf output(s). - - gtf: - type: file - description: | - Annotation gtf file. + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: | + Stringtie transcript gtf output(s). + - gtf: + type: file + description: | + Annotation gtf file. output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - transcript_gtf: - type: file - description: transcript gtf - pattern: "*.{transcripts.gtf}" - - coverage_gtf: - type: file - description: coverage gtf - pattern: "*.{coverage.gtf}" - - abudance: - type: file - description: abudance - pattern: "*.{abudance.txt}" - - ballgown: - type: file - description: for running ballgown - pattern: "*.{ballgown}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - transcript_gtf: + type: file + description: transcript gtf + pattern: "*.{transcripts.gtf}" + - coverage_gtf: + type: file + description: coverage gtf + pattern: "*.{coverage.gtf}" + - abudance: + type: file + description: abudance + pattern: "*.{abudance.txt}" + - ballgown: + type: file + description: for running ballgown + pattern: "*.{ballgown}" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - - "@drpatelh" + - "@drpatelh" diff --git a/modules/nf-core/modules/subread/featurecounts/meta.yml b/modules/nf-core/modules/subread/featurecounts/meta.yml index 1100a0914..cf02f1ea7 100644 --- a/modules/nf-core/modules/subread/featurecounts/meta.yml +++ b/modules/nf-core/modules/subread/featurecounts/meta.yml @@ -1,10 +1,10 @@ name: subread_featurecounts description: Count reads that map to genomic features keywords: - - counts - - fasta - - genome - - reference + - counts + - fasta + - genome + - reference tools: - featurecounts: @@ -12,14 +12,14 @@ tools: homepage: http://bioinf.wehi.edu.au/featureCounts/ documentation: http://bioinf.wehi.edu.au/subread-package/SubreadUsersGuide.pdf doi: "10.1093/bioinformatics/btt656" - licence: ['GPL v3'] + licence: ["GPL v3"] input: - meta: type: map description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] - bam: type: file description: BAM/SAM file containing read alignments @@ -33,8 +33,8 @@ output: - meta: type: map description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] - counts: type: file description: Counts of reads mapping to features diff --git a/modules/nf-core/modules/trimgalore/meta.yml b/modules/nf-core/modules/trimgalore/meta.yml index c7e1df1de..e99a88334 100644 --- a/modules/nf-core/modules/trimgalore/meta.yml +++ b/modules/nf-core/modules/trimgalore/meta.yml @@ -1,59 +1,59 @@ name: trimgalore description: Trim FastQ files using Trim Galore! keywords: - - trimming - - adapters - - sequencing adapters - - fastq + - trimming + - adapters + - sequencing adapters + - fastq tools: - - trimgalore: - description: | - A wrapper tool around Cutadapt and FastQC to consistently apply quality - and adapter trimming to FastQ files, with some extra functionality for - MspI-digested RRBS-type (Reduced Representation Bisufite-Seq) libraries. - homepage: https://www.bioinformatics.babraham.ac.uk/projects/trim_galore/ - documentation: https://github.com/FelixKrueger/TrimGalore/blob/master/Docs/Trim_Galore_User_Guide.md - licence: ['GPL-3.0-or-later'] + - trimgalore: + description: | + A wrapper tool around Cutadapt and FastQC to consistently apply quality + and adapter trimming to FastQ files, with some extra functionality for + MspI-digested RRBS-type (Reduced Representation Bisufite-Seq) libraries. + homepage: https://www.bioinformatics.babraham.ac.uk/projects/trim_galore/ + documentation: https://github.com/FelixKrueger/TrimGalore/blob/master/Docs/Trim_Galore_User_Guide.md + licence: ["GPL-3.0-or-later"] input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - reads: - type: file - description: | - List of input FastQ files of size 1 and 2 for single-end and paired-end data, - respectively. + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: | + List of input FastQ files of size 1 and 2 for single-end and paired-end data, + respectively. output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - reads: - type: file - description: | - List of input adapter trimmed FastQ files of size 1 and 2 for - single-end and paired-end data, respectively. - pattern: "*.{fq.gz}" - - html: - type: file - description: FastQC report (optional) - pattern: "*_{fastqc.html}" - - zip: - type: file - description: FastQC report archive (optional) - pattern: "*_{fastqc.zip}" - - log: - type: file - description: Trim Galore! trimming report - pattern: "*_{report.txt}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: | + List of input adapter trimmed FastQ files of size 1 and 2 for + single-end and paired-end data, respectively. + pattern: "*.{fq.gz}" + - html: + type: file + description: FastQC report (optional) + pattern: "*_{fastqc.html}" + - zip: + type: file + description: FastQC report archive (optional) + pattern: "*_{fastqc.zip}" + - log: + type: file + description: Trim Galore! trimming report + pattern: "*_{report.txt}" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - - "@drpatelh" - - "@ewels" - - "@FelixKrueger" + - "@drpatelh" + - "@ewels" + - "@FelixKrueger" diff --git a/modules/nf-core/modules/ucsc/bedclip/meta.yml b/modules/nf-core/modules/ucsc/bedclip/meta.yml index c73729257..e6dd8cebc 100644 --- a/modules/nf-core/modules/ucsc/bedclip/meta.yml +++ b/modules/nf-core/modules/ucsc/bedclip/meta.yml @@ -9,7 +9,7 @@ tools: documentation: None tool_dev_url: None doi: "" - licence: ['varies; see http://genome.ucsc.edu/license'] + licence: ["varies; see http://genome.ucsc.edu/license"] input: - meta: diff --git a/modules/nf-core/modules/umitools/dedup/meta.yml b/modules/nf-core/modules/umitools/dedup/meta.yml index f89cc1ea7..2038b40de 100644 --- a/modules/nf-core/modules/umitools/dedup/meta.yml +++ b/modules/nf-core/modules/umitools/dedup/meta.yml @@ -1,47 +1,47 @@ name: umitools_dedup description: Deduplicate reads based on the mapping co-ordinate and the UMI attached to the read. keywords: - - umitools - - deduplication + - umitools + - deduplication tools: - - umi_tools: - description: > - UMI-tools contains tools for dealing with Unique Molecular Identifiers (UMIs)/Random Molecular Tags (RMTs) - and single cell RNA-Seq cell barcodes - documentation: https://umi-tools.readthedocs.io/en/latest/ - license: ['MIT'] + - umi_tools: + description: > + UMI-tools contains tools for dealing with Unique Molecular Identifiers (UMIs)/Random Molecular Tags (RMTs) + and single cell RNA-Seq cell barcodes + documentation: https://umi-tools.readthedocs.io/en/latest/ + license: ["MIT"] input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: | - BAM file containing reads to be deduplicated via UMIs. - pattern: "*.{bam}" - - bai: - type: file - description: | - BAM index files corresponding to the input BAM file. - pattern: "*.{bai}" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: | + BAM file containing reads to be deduplicated via UMIs. + pattern: "*.{bam}" + - bai: + type: file + description: | + BAM index files corresponding to the input BAM file. + pattern: "*.{bai}" output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: BAM file with deduplicated UMIs. - pattern: "*.{bam}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: BAM file with deduplicated UMIs. + pattern: "*.{bam}" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - - "@drpatelh" - - "@grst" - - "@klkeys" + - "@drpatelh" + - "@grst" + - "@klkeys" diff --git a/modules/nf-core/modules/umitools/extract/meta.yml b/modules/nf-core/modules/umitools/extract/meta.yml index ae6f9feeb..7fc23f722 100644 --- a/modules/nf-core/modules/umitools/extract/meta.yml +++ b/modules/nf-core/modules/umitools/extract/meta.yml @@ -1,46 +1,47 @@ name: umitools_extract description: Extracts UMI barcode from a read and add it to the read name, leaving any sample barcode in place keywords: - - umitools - - extract + - umitools + - extract tools: - - umi_tools: - description: > - UMI-tools contains tools for dealing with Unique Molecular Identifiers (UMIs)/Random Molecular Tags (RMTs) - and single cell RNA-Seq cell barcodes - documentation: https://umi-tools.readthedocs.io/en/latest/ - license: ['MIT'] + - umi_tools: + description: > + UMI-tools contains tools for dealing with Unique Molecular Identifiers (UMIs)/Random Molecular Tags (RMTs) + and single cell RNA-Seq cell barcodes + documentation: https://umi-tools.readthedocs.io/en/latest/ + license: ["MIT"] input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - reads: - type: list - description: | - List of input FASTQ files whose UMIs will be extracted. + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: list + description: | + List of input FASTQ files whose UMIs will be extracted. output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - reads: - type: file - description: Extracted FASTQ files. | - For single-end reads, pattern is \${prefix}.umi_extract.fastq.gz. | - For paired-end reads, pattern is \${prefix}.umi_extract_{1,2}.fastq.gz. - pattern: "*.{fastq.gz}" - - log: - type: file - description: Logfile for umi_tools - pattern: "*.{log}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: > + Extracted FASTQ files. | + For single-end reads, pattern is \${prefix}.umi_extract.fastq.gz. | + For paired-end reads, pattern is \${prefix}.umi_extract_{1,2}.fastq.gz. + pattern: "*.{fastq.gz}" + - log: + type: file + description: Logfile for umi_tools + pattern: "*.{log}" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - - "@drpatelh" - - "@grst" + - "@drpatelh" + - "@grst" diff --git a/modules/nf-core/modules/untar/meta.yml b/modules/nf-core/modules/untar/meta.yml index 51f94995e..e877a97c1 100644 --- a/modules/nf-core/modules/untar/meta.yml +++ b/modules/nf-core/modules/untar/meta.yml @@ -1,28 +1,28 @@ name: untar description: Extract files. keywords: - - untar - - uncompress + - untar + - uncompress tools: - - untar: - description: | - Extract tar.gz files. - documentation: https://www.gnu.org/software/tar/manual/ - licence: ['GPL-3.0-or-later'] + - untar: + description: | + Extract tar.gz files. + documentation: https://www.gnu.org/software/tar/manual/ + licence: ["GPL-3.0-or-later"] input: - - archive: - type: file - description: File to be untar - pattern: "*.{tar}.{gz}" + - archive: + type: file + description: File to be untar + pattern: "*.{tar}.{gz}" output: - - untar: - type: file - description: - pattern: "*.*" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + - untar: + type: file + description: + pattern: "*.*" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - - "@joseespinosa" - - "@drpatelh" + - "@joseespinosa" + - "@drpatelh" From accb04ba95d98b28a1e682451215c6ed22bd2f50 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 15 Feb 2022 18:29:11 +0000 Subject: [PATCH 13/36] Fix linting --- .nf-core.yml | 5 +++++ CHANGELOG.md | 54 +++++++++++++++++++++++++------------------------- README.md | 4 ++-- docs/output.md | 12 +++++------ 4 files changed, 40 insertions(+), 35 deletions(-) diff --git a/.nf-core.yml b/.nf-core.yml index e04c0c3fd..b5ffb1547 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -3,6 +3,11 @@ lint: - assets/email_template.html - assets/email_template.txt - lib/NfcoreTemplate.groovy + - .github/ISSUE_TEMPLATE/bug_report.yml + - .github/workflows/branch.yml + - .github/workflows/linting_comment.yml + - .github/workflows/linting.yml + - lib/NfcoreSchema.groovy update: nf-core/modules: rseqc/bamstat: "e745e167c1020928ef20ea1397b6b4d230681b4d" diff --git a/CHANGELOG.md b/CHANGELOG.md index f7138b6ef..69656ae24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,9 +46,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | | `--save_bbsplit_reads` | | | `--skip_bbsplit` | -> **NB:** Parameter has been __updated__ if both old and new parameter information is present. -> **NB:** Parameter has been __added__ if just the new parameter information is present. -> **NB:** Parameter has been __removed__ if parameter information isn't present. +> **NB:** Parameter has been **updated** if both old and new parameter information is present. +> **NB:** Parameter has been **added** if just the new parameter information is present. +> **NB:** Parameter has been **removed** if parameter information isn't present. ### Software dependencies @@ -64,9 +64,9 @@ Note, since the pipeline is now using Nextflow DSL2, each process will be run wi | `sortmerna` | 4.2.0 | 4.3.4 | | `trim-galore` | 0.6.6 | 0.6.7 | -> **NB:** Dependency has been __updated__ if both old and new version information is present. -> **NB:** Dependency has been __added__ if just the new version information is present. -> **NB:** Dependency has been __removed__ if version information isn't present. +> **NB:** Dependency has been **updated** if both old and new version information is present. +> **NB:** Dependency has been **added** if just the new version information is present. +> **NB:** Dependency has been **removed** if version information isn't present. ## [[3.3](https://github.com/nf-core/rnaseq/releases/tag/3.3)] - 2021-07-29 @@ -87,9 +87,9 @@ Note, since the pipeline is now using Nextflow DSL2, each process will be run wi | `stringtie` | 2.1.4 | 2.1.7 | | `umi_tools` | 1.1.1 | 1.1.2 | -> **NB:** Dependency has been __updated__ if both old and new version information is present. -> **NB:** Dependency has been __added__ if just the new version information is present. -> **NB:** Dependency has been __removed__ if version information isn't present. +> **NB:** Dependency has been **updated** if both old and new version information is present. +> **NB:** Dependency has been **added** if just the new version information is present. +> **NB:** Dependency has been **removed** if version information isn't present. ## [[3.2](https://github.com/nf-core/rnaseq/releases/tag/3.2)] - 2021-06-18 @@ -112,9 +112,9 @@ Note, since the pipeline is now using Nextflow DSL2, each process will be run wi | `--skip_sra_fastq_download` | | | | `--salmon_quant_libtype` | -> **NB:** Parameter has been __updated__ if both old and new parameter information is present. -> **NB:** Parameter has been __added__ if just the new parameter information is present. -> **NB:** Parameter has been __removed__ if parameter information isn't present. +> **NB:** Parameter has been **updated** if both old and new parameter information is present. +> **NB:** Parameter has been **added** if just the new parameter information is present. +> **NB:** Parameter has been **removed** if parameter information isn't present. ## [[3.1](https://github.com/nf-core/rnaseq/releases/tag/3.1)] - 2021-05-13 @@ -165,9 +165,9 @@ Note, since the pipeline is now using Nextflow DSL2, each process will be run wi | | `--validate_params` | | `--clusterOptions` | | -> **NB:** Parameter has been __updated__ if both old and new parameter information is present. -> **NB:** Parameter has been __added__ if just the new parameter information is present. -> **NB:** Parameter has been __removed__ if parameter information isn't present. +> **NB:** Parameter has been **updated** if both old and new parameter information is present. +> **NB:** Parameter has been **added** if just the new parameter information is present. +> **NB:** Parameter has been **removed** if parameter information isn't present. ### Software dependencies @@ -179,9 +179,9 @@ Note, since the pipeline is now using Nextflow DSL2, each process will be run wi | `multiqc` | 1.9 | 1.10.1 | | `preseq` | 2.0.3 | 3.1.2 | -> **NB:** Dependency has been __updated__ if both old and new version information is present. -> **NB:** Dependency has been __added__ if just the new version information is present. -> **NB:** Dependency has been __removed__ if version information isn't present. +> **NB:** Dependency has been **updated** if both old and new version information is present. +> **NB:** Dependency has been **added** if just the new version information is present. +> **NB:** Dependency has been **removed** if version information isn't present. ## [[3.0](https://github.com/nf-core/rnaseq/releases/tag/3.0)] - 2020-12-15 @@ -223,9 +223,9 @@ Note, since the pipeline is now using Nextflow DSL2, each process will be run wi |  | `--singularity_pull_docker_container` | | `--skip_featurecounts` |  | -> **NB:** Parameter has been __updated__ if both old and new parameter information is present. -> **NB:** Parameter has been __added__ if just the new parameter information is present. -> **NB:** Parameter has been __removed__ if parameter information isn't present. +> **NB:** Parameter has been **updated** if both old and new parameter information is present. +> **NB:** Parameter has been **added** if just the new parameter information is present. +> **NB:** Parameter has been **removed** if parameter information isn't present. ### Software dependencies @@ -241,9 +241,9 @@ Note, since the pipeline is now using Nextflow DSL2, each process will be run wi | `ucsc-bedclip` | | 377 | | `umi_tools` | 1.0.1 | 1.1.1 | -> **NB:** Dependency has been __updated__ if both old and new version information is present. -> **NB:** Dependency has been __added__ if just the new version information is present. -> **NB:** Dependency has been __removed__ if version information isn't present. +> **NB:** Dependency has been **updated** if both old and new version information is present. +> **NB:** Dependency has been **added** if just the new version information is present. +> **NB:** Dependency has been **removed** if version information isn't present. ## [[2.0](https://github.com/nf-core/rnaseq/releases/tag/2.0)] - 2020-11-12 @@ -407,9 +407,9 @@ Note, since the pipeline is now using Nextflow DSL2, each process will be run wi | `r-gplots` | - | - | | `r-markdown` | - | - | -> **NB:** Dependency has been __updated__ if both old and new version information is present. -> **NB:** Dependency has been __added__ if just the new version information is present. -> **NB:** Dependency has been __removed__ if version information isn't present. +> **NB:** Dependency has been **updated** if both old and new version information is present. +> **NB:** Dependency has been **added** if just the new version information is present. +> **NB:** Dependency has been **removed** if version information isn't present. ## [[1.4.2](https://github.com/nf-core/rnaseq/releases/tag/1.4.2)] - 2019-10-18 diff --git a/README.md b/README.md index c21409d87..6013885ca 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ The SRA download functionality has been removed from the pipeline (`>=3.2`) and 1. Install [`Nextflow`](https://www.nextflow.io/docs/latest/getstarted.html#installation) (`>=21.10.3`) -2. Install any of [`Docker`](https://docs.docker.com/engine/installation/), [`Singularity`](https://www.sylabs.io/guides/3.0/user-guide/), [`Podman`](https://podman.io/), [`Shifter`](https://nersc.gitlab.io/development/shifter/how-to-use/) or [`Charliecloud`](https://hpc.github.io/charliecloud/) for full pipeline reproducibility _(please only use [`Conda`](https://conda.io/miniconda.html) as a last resort; see [docs](https://nf-co.re/usage/configuration#basic-configuration-profiles))_. Note: This pipeline does not currently support running with Conda on macOS if the `--remove_ribo_rna` parameter is used because the latest version of the SortMeRNA package is not available for this platform. +2. Install any of [`Docker`](https://docs.docker.com/engine/installation/), [`Singularity`](https://www.sylabs.io/guides/3.0/user-guide/), [`Podman`](https://podman.io/), [`Shifter`](https://nersc.gitlab.io/development/shifter/how-to-use/) or [`Charliecloud`](https://hpc.github.io/charliecloud/) for full pipeline reproducibility *(please only use [`Conda`](https://conda.io/miniconda.html) as a last resort; see [docs](https://nf-co.re/usage/configuration#basic-configuration-profiles))*. Note: This pipeline does not currently support running with Conda on macOS if the `--remove_ribo_rna` parameter is used because the latest version of the SortMeRNA package is not available for this platform. 3. Download the pipeline and test it on a minimal dataset with a single command: @@ -126,4 +126,4 @@ You can cite the `nf-core` publication as follows: > > Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen. > -> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x). +> *Nat Biotechnol.* 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x). diff --git a/docs/output.md b/docs/output.md index 8d932d6b0..a3d8707a6 100644 --- a/docs/output.md +++ b/docs/output.md @@ -177,7 +177,7 @@ When `--remove_ribo_rna` is specified, the pipeline uses [SortMeRNA](https://git [Salmon](https://salmon.readthedocs.io/en/latest/salmon.html) from [Ocean Genomics](https://oceangenomics.com/) is a tool for wicked-fast transcript quantification from RNA-seq data. It requires a set of target transcripts (either from a reference or de-novo assembly) in order to perform quantification. All you need to run Salmon is a FASTA file containing your reference transcripts and a set of FASTA/FASTQ/BAM file(s) containing your reads. The transcriptome-level BAM files generated by STAR are provided to Salmon for downstream quantification. You can of course also provide FASTQ files directly as input to Salmon in order to pseudo-align and quantify your data by providing the `--pseudo_aligner salmon` parameter. The results generated by the pipeline are exactly the same whether you provide BAM or FASTQ input so please see the [Salmon](#salmon) results section for more details. -The STAR section of the MultiQC report shows a bar plot with alignment rates: good samples should have most reads as _Uniquely mapped_ and few _Unmapped_ reads. +The STAR section of the MultiQC report shows a bar plot with alignment rates: good samples should have most reads as _Uniquely mapped_ and few *Unmapped* reads. ![MultiQC - STAR alignment scores plot](images/mqc_star.png) @@ -409,7 +409,7 @@ RSeQC documentation: [junction_annotation.py](http://rseqc.sourceforge.net/#junc The inner distance script tries to calculate the inner distance between two paired-end reads. It is the distance between the end of read 1 to the start of read 2, and it is sometimes confused with the insert size (see [this blog post](http://thegenomefactory.blogspot.com.au/2013/08/paired-end-read-confusion-library.html) for disambiguation): -This plot will not be generated for single-end data. Very short inner distances are often seen in old or degraded samples (_eg._ FFPE) and values can be negative if the reads overlap consistently. +This plot will not be generated for single-end data. Very short inner distances are often seen in old or degraded samples (*eg.* FFPE) and values can be negative if the reads overlap consistently. RSeQC documentation: [inner_distance.py](http://rseqc.sourceforge.net/#inner-distance-py) @@ -427,7 +427,7 @@ RSeQC documentation: [inner_distance.py](http://rseqc.sourceforge.net/#inner-dis -This script shows the number of splice sites detected within the data at various levels of subsampling. A sample that reaches a plateau before getting to 100% data indicates that all junctions in the library have been detected, and that further sequencing will not yield any more observations. A good sample should approach such a plateau of _Known junctions_, however, very deep sequencing is typically required to saturate all _Novel Junctions_ in a sample. +This script shows the number of splice sites detected within the data at various levels of subsampling. A sample that reaches a plateau before getting to 100% data indicates that all junctions in the library have been detected, and that further sequencing will not yield any more observations. A good sample should approach such a plateau of _Known junctions_, however, very deep sequencing is typically required to saturate all *Novel Junctions* in a sample. RSeQC documentation: [junction_saturation.py](http://rseqc.sourceforge.net/#junction-saturation-py) @@ -555,7 +555,7 @@ See [dupRadar docs](https://www.bioconductor.org/packages/devel/bioc/vignettes/d ![dupRadar - Example good and bad experiment plot](images/dupradar_example_plot.png) -> _Credit: [dupRadar documentation](https://www.bioconductor.org/packages/devel/bioc/vignettes/dupRadar/inst/doc/dupRadar.html)_ +> *Credit: [dupRadar documentation](https://www.bioconductor.org/packages/devel/bioc/vignettes/dupRadar/inst/doc/dupRadar.html)* ### Preseq @@ -669,8 +669,8 @@ Results generated by MultiQC collate pipeline QC from supported tools i.e. FastQ * `lib_format_counts.json`: Number of fragments assigned, unassigned and incompatible. * `libParams/`: Contains the file `flenDist.txt` for the fragment length distribution. * `logs/`: Contains the file `salmon_quant.log` giving a record of Salmon's quantification. - * `quant.genes.sf`: Salmon _gene_-level quantification of the sample, including feature length, effective length, TPM, and number of reads. - * `quant.sf`: Salmon _transcript_-level quantification of the sample, including feature length, effective length, TPM, and number of reads. + * `quant.genes.sf`: Salmon *gene*-level quantification of the sample, including feature length, effective length, TPM, and number of reads. + * `quant.sf`: Salmon *transcript*-level quantification of the sample, including feature length, effective length, TPM, and number of reads. From 41218aa75a7dbb13cee0b5fd217c045d2b754a08 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 15 Feb 2022 18:34:05 +0000 Subject: [PATCH 14/36] Fix linting again --- assets/multiqc_config.yaml | 16 ++++++++-------- docs/output.md | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/assets/multiqc_config.yaml b/assets/multiqc_config.yaml index 71a1273e7..d7d4a1f72 100644 --- a/assets/multiqc_config.yaml +++ b/assets/multiqc_config.yaml @@ -41,16 +41,16 @@ top_modules: module_order: - fastqc: - name: 'FastQC (raw)' - info: 'This section of the report shows FastQC results before adapter trimming.' - path_filters: - - './fastqc/*.zip' + name: 'FastQC (raw)' + info: 'This section of the report shows FastQC results before adapter trimming.' + path_filters: + - './fastqc/*.zip' - cutadapt - fastqc: - name: 'FastQC (trimmed)' - info: 'This section of the report shows FastQC results after adapter trimming.' - path_filters: - - './trimgalore/fastqc/*.zip' + name: 'FastQC (trimmed)' + info: 'This section of the report shows FastQC results after adapter trimming.' + path_filters: + - './trimgalore/fastqc/*.zip' # Don't show % Dups in the General Stats table (we have this from Picard) table_columns_visible: diff --git a/docs/output.md b/docs/output.md index a3d8707a6..e548495fe 100644 --- a/docs/output.md +++ b/docs/output.md @@ -177,7 +177,7 @@ When `--remove_ribo_rna` is specified, the pipeline uses [SortMeRNA](https://git [Salmon](https://salmon.readthedocs.io/en/latest/salmon.html) from [Ocean Genomics](https://oceangenomics.com/) is a tool for wicked-fast transcript quantification from RNA-seq data. It requires a set of target transcripts (either from a reference or de-novo assembly) in order to perform quantification. All you need to run Salmon is a FASTA file containing your reference transcripts and a set of FASTA/FASTQ/BAM file(s) containing your reads. The transcriptome-level BAM files generated by STAR are provided to Salmon for downstream quantification. You can of course also provide FASTQ files directly as input to Salmon in order to pseudo-align and quantify your data by providing the `--pseudo_aligner salmon` parameter. The results generated by the pipeline are exactly the same whether you provide BAM or FASTQ input so please see the [Salmon](#salmon) results section for more details. -The STAR section of the MultiQC report shows a bar plot with alignment rates: good samples should have most reads as _Uniquely mapped_ and few *Unmapped* reads. +The STAR section of the MultiQC report shows a bar plot with alignment rates: good samples should have most reads as *Uniquely mapped* and few *Unmapped* reads. ![MultiQC - STAR alignment scores plot](images/mqc_star.png) @@ -427,7 +427,7 @@ RSeQC documentation: [inner_distance.py](http://rseqc.sourceforge.net/#inner-dis -This script shows the number of splice sites detected within the data at various levels of subsampling. A sample that reaches a plateau before getting to 100% data indicates that all junctions in the library have been detected, and that further sequencing will not yield any more observations. A good sample should approach such a plateau of _Known junctions_, however, very deep sequencing is typically required to saturate all *Novel Junctions* in a sample. +This script shows the number of splice sites detected within the data at various levels of subsampling. A sample that reaches a plateau before getting to 100% data indicates that all junctions in the library have been detected, and that further sequencing will not yield any more observations. A good sample should approach such a plateau of *Known junctions*, however, very deep sequencing is typically required to saturate all *Novel Junctions* in a sample. RSeQC documentation: [junction_saturation.py](http://rseqc.sourceforge.net/#junction-saturation-py) From b7a34cb2392aa171bbf7b13177e1fe71aae29bc1 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Thu, 17 Feb 2022 12:15:47 +0000 Subject: [PATCH 15/36] Update usage docs --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index b1f1af06c..29506b5e6 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -193,7 +193,7 @@ Tip: you can replicate the issue by changing to the process work dir and enterin ``` To bypass this error you would need to find exactly which resources are set by the `STAR_ALIGN` process. The quickest way is to search for `process STAR_ALIGN` in the [nf-core/rnaseq Github repo](https://github.com/nf-core/rnaseq/search?q=process+STAR_ALIGN). -We have standardised the structure of Nextflow DSL2 pipelines such that all module files will be present in the `modules/` directory and so based on the search results the file we want is `modules/nf-core/software/star/align/main.nf`. +We have standardised the structure of Nextflow DSL2 pipelines such that all module files will be present in the `modules/` directory and so, based on the search results, the file we want is `modules/nf-core/software/star/align/main.nf`. If you click on the link to that file you will notice that there is a `label` directive at the top of the module that is set to [`label process_high`](https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/modules/nf-core/software/star/align/main.nf#L9). The [Nextflow `label`](https://www.nextflow.io/docs/latest/process.html#label) directive allows us to organise workflow processes in separate groups which can be referenced in a configuration file to select and configure subset of processes having similar computing requirements. The default values for the `process_high` label are set in the pipeline's [`base.config`](https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/conf/base.config#L33-L37) which in this case is defined as 72GB. From d04519cce8cbac89b76909247a6f8f2b115dfefe Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Thu, 17 Feb 2022 12:18:30 +0000 Subject: [PATCH 16/36] Update footnotes in usage docs --- docs/usage.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 29506b5e6..f8f9f58ee 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -202,14 +202,15 @@ The custom config below can then be provided to the pipeline via the [`-c`](#-c) ```nextflow process { - withName: STAR_ALIGN { + withName: 'NFCORE_RNASEQ:RNASEQ:ALIGN_STAR:STAR_ALIGN' { memory = 100.GB } } ``` -> **NB:** We specify just the process name i.e. `STAR_ALIGN` in the config file and not the full task name string that is printed to screen in the error message or on the terminal whilst the pipeline is running i.e. `RNASEQ:ALIGN_STAR:STAR_ALIGN`. -> You may get a warning suggesting that the process selector isn't recognised but you can ignore that if the process name has been specified correctly. This is something that needs to be fixed upstream in core Nextflow. +> **NB:** We specify the full process name i.e. `NFCORE_RNASEQ:RNASEQ:ALIGN_STAR:STAR_ALIGN` in the config file because this takes priority over the short name (`STAR_ALIGN`) and allows existing configuration using the full process name to be correctly overridden. +> +> If you get a warning suggesting that the process selector isn't recognised check that the process name has been specified correctly. ### Updating containers From b66f055d522d8df613d262106d239ef70a15ac6b Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Thu, 17 Feb 2022 12:24:31 +0000 Subject: [PATCH 17/36] Add NFCORE_RNASEQ prefix everywhere --- docs/usage.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index f8f9f58ee..9d58d30a9 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -164,11 +164,11 @@ Whilst the default requirements set within the pipeline will hopefully work for For example, if the nf-core/rnaseq pipeline is failing after multiple re-submissions of the `STAR_ALIGN` process due to an exit code of `137` this would indicate that there is an out of memory issue: ```console -[62/149eb0] NOTE: Process `RNASEQ:ALIGN_STAR:STAR_ALIGN (WT_REP1)` terminated with an error exit status (137) -- Execution is retried (1) -Error executing process > 'RNASEQ:ALIGN_STAR:STAR_ALIGN (WT_REP1)' +[62/149eb0] NOTE: Process `NFCORE_RNASEQ:RNASEQ:ALIGN_STAR:STAR_ALIGN (WT_REP1)` terminated with an error exit status (137) -- Execution is retried (1) +Error executing process > 'NFCORE_RNASEQ:RNASEQ:ALIGN_STAR:STAR_ALIGN (WT_REP1)' Caused by: - Process `RNASEQ:ALIGN_STAR:STAR_ALIGN (WT_REP1)` terminated with an error exit status (137) + Process `NFCORE_RNASEQ:RNASEQ:ALIGN_STAR:STAR_ALIGN (WT_REP1)` terminated with an error exit status (137) Command executed: STAR \ From df102cd03ffbcebce7ed11306376639394f2250b Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Sun, 20 Feb 2022 18:02:33 +0000 Subject: [PATCH 18/36] Add --publish_dir_mode back into pipeline #752 --- CHANGELOG.md | 14 ++++ conf/modules.config | 178 +++++++++++++++++++++---------------------- nextflow.config | 1 + nextflow_schema.json | 16 ++++ 4 files changed, 120 insertions(+), 89 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69656ae24..a99e8f2f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Enhancements & fixes +* [[#734](https://github.com/nf-core/rnaseq/issues/734)] - Is a vulnerable picard still used ? log4j vulnerability +* [[#752](https://github.com/nf-core/rnaseq/issues/752)] - How to set publishing mode for all processes? +* [[#755](https://github.com/nf-core/rnaseq/issues/755)] - Rename RSEM_PREPAREREFERENCE_TRANSCRIPTS process + ### Parameters +| Old parameter | New parameter | +|-------------------------------|---------------------------------------| +| | `--publish_dir_mode` | + +> **NB:** Parameter has been **updated** if both old and new parameter information is present. +> +> **NB:** Parameter has been **added** if just the new parameter information is present. +> +> **NB:** Parameter has been **removed** if new parameter information isn't present. + ## [[3.5](https://github.com/nf-core/rnaseq/releases/tag/3.5)] - 2021-12-17 ### Enhancements & fixes diff --git a/conf/modules.config b/conf/modules.config index 6ba191083..4ec359881 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -17,14 +17,14 @@ process { publishDir = [ path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] withName: 'SAMPLESHEET_CHECK' { publishDir = [ path: { "${params.outdir}/pipeline_info" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -32,7 +32,7 @@ process { withName: 'CUSTOM_DUMPSOFTWAREVERSIONS' { publishDir = [ path: { "${params.outdir}/pipeline_info" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*_versions.yml' ] } @@ -46,7 +46,7 @@ process { withName: 'GUNZIP_.*|MAKE_TRANSCRIPTS_FASTA' { publishDir = [ path: { "${params.outdir}/genome" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, enabled: params.save_reference ] @@ -59,7 +59,7 @@ process { withName: 'UNTAR_.*|STAR_GENOMEGENERATE|HISAT2_BUILD' { publishDir = [ path: { "${params.outdir}/genome/index" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, enabled: params.save_reference ] @@ -69,7 +69,7 @@ process { ext.args = '--keep-exon-attrs -F -T' publishDir = [ path: { "${params.outdir}/genome" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, enabled: params.save_reference ] @@ -78,7 +78,7 @@ process { withName: 'HISAT2_EXTRACTSPLICESITES' { publishDir = [ path: { "${params.outdir}/genome/index" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, enabled: params.save_reference ] @@ -88,7 +88,7 @@ process { ext.args = params.gencode ? '--gencode' : '' publishDir = [ path: { "${params.outdir}/genome/index" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, enabled: params.save_reference ] @@ -98,7 +98,7 @@ process { ext.args = '--star' publishDir = [ path: { "${params.outdir}/genome/index" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, enabled: params.save_reference ] @@ -107,7 +107,7 @@ process { withName: 'GTF2BED' { publishDir = [ path: { "${params.outdir}/genome" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, enabled: params.save_reference ] @@ -116,7 +116,7 @@ process { withName: 'CAT_ADDITIONAL_FASTA' { publishDir = [ path: { "${params.outdir}/genome" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, enabled: params.save_reference ] @@ -125,7 +125,7 @@ process { withName: 'GTF_GENE_FILTER' { publishDir = [ path: { "${params.outdir}/genome" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, enabled: params.save_reference ] @@ -134,7 +134,7 @@ process { withName: 'GET_CHROM_SIZES' { publishDir = [ path: { "${params.outdir}/genome" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, enabled: params.save_reference ] @@ -143,7 +143,7 @@ process { withName: 'CAT_FASTQ' { publishDir = [ path: { "${params.outdir}/fastq" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, enabled: params.save_merged_fastq ] @@ -156,7 +156,7 @@ if (!params.skip_bbsplit && params.bbsplit_fasta_list) { ext.args = 'build=1' publishDir = [ path: { "${params.outdir}/genome/index" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, enabled: params.save_reference ] @@ -186,18 +186,18 @@ if (!params.skip_trimming) { publishDir = [ [ path: { "${params.outdir}/trimgalore/fastqc" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*.{html,zip}" ], [ path: { "${params.outdir}/trimgalore" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*.fq.gz", enabled: params.save_trimmed ], [ path: { "${params.outdir}/trimgalore" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*.txt" ] ] @@ -215,12 +215,12 @@ if (params.with_umi) { publishDir = [ [ path: { "${params.outdir}/umitools" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*.log" ], [ path: { "${params.outdir}/umitools" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*.fastq.gz", enabled: params.save_umi_intermeds ] @@ -240,12 +240,12 @@ if (!params.skip_bbsplit) { publishDir = [ [ path: { "${params.outdir}/bbsplit" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.txt' ], [ path: { "${params.outdir}/bbsplit" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.fastq.gz', enabled: params.save_bbsplit_reads ] @@ -261,12 +261,12 @@ if (params.remove_ribo_rna) { publishDir = [ [ path: { "${params.outdir}/sortmerna" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*.log" ], [ path: { "${params.outdir}/sortmerna" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*.fastq.gz", enabled: params.save_non_ribo_reads ] @@ -284,7 +284,7 @@ if (!params.skip_alignment) { withName: 'NFCORE_RNASEQ:RNASEQ:.*:BAM_SORT_SAMTOOLS:BAM_STATS_SAMTOOLS:.*' { publishDir = [ path: { "${params.outdir}/${params.aligner}/samtools_stats" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*.{stats,flagstat,idxstats}" ] } @@ -293,7 +293,7 @@ if (!params.skip_alignment) { ext.prefix = { "${meta.id}.sorted" } publishDir = [ path: { "${params.outdir}/${params.aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*.bam", enabled: ( ['star_salmon','hisat2'].contains(params.aligner) && ( params.save_align_intermeds || @@ -307,7 +307,7 @@ if (!params.skip_alignment) { ext.args = params.bam_csi_index ? '-c' : '' publishDir = [ path: { "${params.outdir}/${params.aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*.{bam,csi}", enabled: ( ['star_salmon','hisat2'].contains(params.aligner) && ( params.save_align_intermeds || @@ -326,12 +326,12 @@ if (!params.skip_alignment) { publishDir = [ [ path: { "${params.outdir}/${params.aligner}/picard_metrics" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*metrics.txt' ], [ path: { "${params.outdir}/${params.aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.bam' ] ] @@ -342,7 +342,7 @@ if (!params.skip_alignment) { ext.prefix = { "${meta.id}.markdup.sorted" } publishDir = [ path: { "${params.outdir}/${params.aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.{bai,csi}' ] } @@ -350,7 +350,7 @@ if (!params.skip_alignment) { withName: '.*:MARK_DUPLICATES_PICARD:BAM_STATS_SAMTOOLS:.*' { publishDir = [ path: { "${params.outdir}/${params.aligner}/samtools_stats" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.{stats,flagstat,idxstats}' ] } @@ -364,12 +364,12 @@ if (!params.skip_alignment) { publishDir = [ [ path: { "${params.outdir}/${params.aligner}/umitools" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.tsv' ], [ path: { "${params.outdir}/${params.aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.bam', enabled: ( params.save_align_intermeds || @@ -385,7 +385,7 @@ if (!params.skip_alignment) { ext.prefix = { "${meta.id}.umi_dedup.sorted" } publishDir = [ path: { "${params.outdir}/${params.aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.{bai,csi}', enabled: ( params.save_align_intermeds || @@ -398,7 +398,7 @@ if (!params.skip_alignment) { withName: '.*:DEDUP_UMI_UMITOOLS_GENOME:BAM_STATS_SAMTOOLS:.*' { publishDir = [ path: { "${params.outdir}/${params.aligner}/samtools_stats" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.{stats,flagstat,idxstats}' ] } @@ -427,7 +427,7 @@ if (!params.skip_alignment) { ext.prefix = { "${meta.id}.forward" } publishDir = [ path: { "${params.outdir}/${params.aligner}/bigwig" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -444,7 +444,7 @@ if (!params.skip_alignment) { ext.prefix = { "${meta.id}.reverse" } publishDir = [ path: { "${params.outdir}/${params.aligner}/bigwig" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -460,7 +460,7 @@ if (!params.skip_alignment) { ].join(' ').trim() publishDir = [ path: { "${params.outdir}/${params.aligner}/stringtie" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -501,18 +501,18 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { publishDir = [ [ path: { "${params.outdir}/${params.aligner}/log" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.{out,tab}' ], [ path: { "${params.outdir}/${params.aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.bam', enabled: params.save_align_intermeds ], [ path: { "${params.outdir}/${params.aligner}/unmapped" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.fastq.gz', enabled: params.save_unaligned ] @@ -522,7 +522,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { withName: '.*:QUANTIFY_STAR_SALMON:SALMON_QUANT' { publishDir = [ path: { "${params.outdir}/${params.aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -530,7 +530,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { withName: '.*:QUANTIFY_STAR_SALMON:SALMON_TX2GENE' { publishDir = [ path: { "${params.outdir}/${params.aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -538,7 +538,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { withName: '.*:QUANTIFY_STAR_SALMON:SALMON_TXIMPORT' { publishDir = [ path: { "${params.outdir}/${params.aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -546,7 +546,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { withName: '.*:QUANTIFY_STAR_SALMON:SALMON_SE_.*' { publishDir = [ path: { "${params.outdir}/${params.aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -589,7 +589,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { ext.prefix = { "${meta.id}.umi_dedup.transcriptome.sorted" } publishDir = [ path: { "${params.outdir}/${params.aligner}/umitools" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.tsv' ] } @@ -604,7 +604,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { withName: '.*:DEDUP_UMI_UMITOOLS_TRANSCRIPTOME:BAM_STATS_SAMTOOLS:.*' { publishDir = [ path: { "${params.outdir}/${params.aligner}/samtools_stats" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.{stats,flagstat,idxstats}' ] } @@ -624,7 +624,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { ext.args2 = 'star_salmon' publishDir = [ path: { "${params.outdir}/${params.aligner}/deseq2_qc" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*{RData,pca.vals.txt,plots.pdf,sample.dists.txt,size_factors,log}" ] } @@ -649,18 +649,18 @@ if (!params.skip_alignment && params.aligner == 'star_rsem') { publishDir = [ [ path: { "${params.outdir}/${params.aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*.{stat,results}" ], [ path: { "${params.outdir}/${params.aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*.bam", enabled: params.save_align_intermeds ], [ path: { "${params.outdir}/${params.aligner}/log" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*.log" ] ] @@ -669,7 +669,7 @@ if (!params.skip_alignment && params.aligner == 'star_rsem') { withName: '.*:QUANTIFY_RSEM:RSEM_MERGE_COUNTS' { publishDir = [ path: { "${params.outdir}/${params.aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -688,7 +688,7 @@ if (!params.skip_alignment && params.aligner == 'star_rsem') { ext.args2 = 'star_rsem' publishDir = [ path: { "${params.outdir}/${params.aligner}/deseq2_qc" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*{RData,pca.vals.txt,plots.pdf,sample.dists.txt,size_factors,log}" ] } @@ -707,18 +707,18 @@ if (!params.skip_alignment && params.aligner == 'hisat2') { publishDir = [ [ path: { "${params.outdir}/${params.aligner}/log" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.log' ], [ path: { "${params.outdir}/${params.aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.bam', enabled: params.save_align_intermeds ], [ path: { "${params.outdir}/${params.aligner}/unmapped" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.fastq.gz', enabled: params.save_unaligned ] @@ -739,12 +739,12 @@ if (!params.skip_alignment && !params.skip_qc) { publishDir = [ [ path: { "${params.outdir}/${params.aligner}/preseq" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*.txt" ], [ path: { "${params.outdir}/${params.aligner}/preseq/log" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*.log" ] ] @@ -757,7 +757,7 @@ if (!params.skip_alignment && !params.skip_qc) { withName: 'QUALIMAP_RNASEQ' { publishDir = [ path: { "${params.outdir}/${params.aligner}/qualimap" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -770,27 +770,27 @@ if (!params.skip_alignment && !params.skip_qc) { publishDir = [ [ path: { "${params.outdir}/${params.aligner}/dupradar/scatter_plot" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*Dens.pdf" ], [ path: { "${params.outdir}/${params.aligner}/dupradar/box_plot" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*Boxplot.pdf" ], [ path: { "${params.outdir}/${params.aligner}/dupradar/histogram" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*Hist.pdf" ], [ path: { "${params.outdir}/${params.aligner}/dupradar/gene_data" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*Matrix.txt" ], [ path: { "${params.outdir}/${params.aligner}/dupradar/intercepts_slope" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*slope.txt" ] ] @@ -808,7 +808,7 @@ if (!params.skip_alignment && !params.skip_qc) { ].join(' ').trim() publishDir = [ path: { "${params.outdir}/${params.aligner}/featurecounts" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -816,7 +816,7 @@ if (!params.skip_alignment && !params.skip_qc) { withName: 'MULTIQC_CUSTOM_BIOTYPE' { publishDir = [ path: { "${params.outdir}/${params.aligner}/featurecounts" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -828,7 +828,7 @@ if (!params.skip_alignment && !params.skip_qc) { withName: '.*:RSEQC:RSEQC_BAMSTAT' { publishDir = [ path: { "${params.outdir}/${params.aligner}/rseqc/bam_stat" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -836,7 +836,7 @@ if (!params.skip_alignment && !params.skip_qc) { withName: '.*:RSEQC:RSEQC_INFEREXPERIMENT' { publishDir = [ path: { "${params.outdir}/${params.aligner}/rseqc/infer_experiment" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -845,27 +845,27 @@ if (!params.skip_alignment && !params.skip_qc) { publishDir = [ [ path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/pdf" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.pdf' ], [ path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/bed" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.bed' ], [ path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/xls" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.xls' ], [ path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/log" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.log' ], [ path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/rscript" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.r' ] ] @@ -875,12 +875,12 @@ if (!params.skip_alignment && !params.skip_qc) { publishDir = [ [ path: { "${params.outdir}/${params.aligner}/rseqc/junction_saturation/pdf" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.pdf' ], [ path: { "${params.outdir}/${params.aligner}/rseqc/junction_saturation/rscript" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.r' ] ] @@ -890,17 +890,17 @@ if (!params.skip_alignment && !params.skip_qc) { publishDir = [ [ path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/pdf" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.pdf' ], [ path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/xls" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.xls' ], [ path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/rscript" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.r' ] ] @@ -910,7 +910,7 @@ if (!params.skip_alignment && !params.skip_qc) { withName: '.*:RSEQC:RSEQC_READDISTRIBUTION' { publishDir = [ path: { "${params.outdir}/${params.aligner}/rseqc/read_distribution" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -919,18 +919,18 @@ if (!params.skip_alignment && !params.skip_qc) { publishDir = [ [ path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/txt" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.txt', saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ], [ path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/pdf" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.pdf' ], [ path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/rscript" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: '*.r' ] ] @@ -939,7 +939,7 @@ if (!params.skip_alignment && !params.skip_qc) { withName: '.*:RSEQC:RSEQC_TIN' { publishDir = [ path: { "${params.outdir}/${params.aligner}/rseqc/tin" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -964,7 +964,7 @@ if (!params.skip_multiqc) { "${params.outdir}/multiqc", params.skip_alignment? '' : "/${params.aligner}" ].join('') }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -980,7 +980,7 @@ if (params.pseudo_aligner == 'salmon') { withName: '.*:QUANTIFY_SALMON:SALMON_QUANT' { publishDir = [ path: { "${params.outdir}/${params.pseudo_aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -988,7 +988,7 @@ if (params.pseudo_aligner == 'salmon') { withName: '.*:QUANTIFY_SALMON:SALMON_TX2GENE' { publishDir = [ path: { "${params.outdir}/${params.pseudo_aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -996,7 +996,7 @@ if (params.pseudo_aligner == 'salmon') { withName: '.*:QUANTIFY_SALMON:SALMON_TXIMPORT' { publishDir = [ path: { "${params.outdir}/${params.pseudo_aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -1004,7 +1004,7 @@ if (params.pseudo_aligner == 'salmon') { withName: '.*:QUANTIFY_SALMON:SALMON_SE_.*' { publishDir = [ path: { "${params.outdir}/${params.pseudo_aligner}" }, - mode: 'copy', + mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } @@ -1023,7 +1023,7 @@ if (params.pseudo_aligner == 'salmon') { ext.args2 = 'salmon' publishDir = [ path: { "${params.outdir}/${params.pseudo_aligner}/deseq2_qc" }, - mode: 'copy', + mode: params.publish_dir_mode, pattern: "*{RData,pca.vals.txt,plots.pdf,sample.dists.txt,size_factors,log}" ] } diff --git a/nextflow.config b/nextflow.config index 147d01362..b3dc62909 100644 --- a/nextflow.config +++ b/nextflow.config @@ -92,6 +92,7 @@ params { help = false igenomes_base = 's3://ngi-igenomes/igenomes' tracedir = "${params.outdir}/pipeline_info" + publish_dir_mode = 'copy' igenomes_ignore = false validate_params = true show_hidden_params = false diff --git a/nextflow_schema.json b/nextflow_schema.json index beb5fe33a..f6281b2e9 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -585,6 +585,22 @@ "fa_icon": "fas fa-question-circle", "hidden": true }, + "publish_dir_mode": { + "type": "string", + "default": "copy", + "description": "Method used to save pipeline results to output directory.", + "help_text": "The Nextflow `publishDir` option specifies which intermediate files should be saved to the output directory. This option tells the pipeline what method should be used to move these files. See [Nextflow docs](https://www.nextflow.io/docs/latest/process.html#publishdir) for details.", + "fa_icon": "fas fa-copy", + "enum": [ + "symlink", + "rellink", + "link", + "copy", + "copyNoFollow", + "move" + ], + "hidden": true + }, "email_on_fail": { "type": "string", "description": "Email address for completion summary, only when pipeline fails.", From 71c0d380dc5db839a595812d1a0e070e625277d1 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Sun, 20 Feb 2022 18:25:19 +0000 Subject: [PATCH 19/36] Fix #759 --- CHANGELOG.md | 1 + bin/check_samplesheet.py | 129 ++++++++++++++++++++------------------- 2 files changed, 66 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a99e8f2f7..214ec15ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [[#734](https://github.com/nf-core/rnaseq/issues/734)] - Is a vulnerable picard still used ? log4j vulnerability * [[#752](https://github.com/nf-core/rnaseq/issues/752)] - How to set publishing mode for all processes? * [[#755](https://github.com/nf-core/rnaseq/issues/755)] - Rename RSEM_PREPAREREFERENCE_TRANSCRIPTS process +* [[#759](https://github.com/nf-core/rnaseq/issues/759)] - Empty lines in samplesheet.csv cause a crash ### Parameters diff --git a/bin/check_samplesheet.py b/bin/check_samplesheet.py index 91327e5c6..c633b6257 100755 --- a/bin/check_samplesheet.py +++ b/bin/check_samplesheet.py @@ -61,79 +61,80 @@ def check_samplesheet(file_in, file_out): ## Check sample entries for line in fin: - lspl = [x.strip().strip('"') for x in line.strip().split(",")] - - ## Check valid number of columns per row - if len(lspl) < len(HEADER): - print_error( - f"Invalid number of columns (minimum = {len(HEADER)})!", - "Line", - line, - ) - - num_cols = len([x for x in lspl if x]) - if num_cols < MIN_COLS: - print_error( - f"Invalid number of populated columns (minimum = {MIN_COLS})!", - "Line", - line, - ) - - ## Check sample name entries - sample, fastq_1, fastq_2, strandedness = lspl[: len(HEADER)] - if sample.find(" ") != -1: - print( - f"WARNING: Spaces have been replaced by underscores for sample: {sample}" - ) - sample = sample.replace(" ", "_") - if not sample: - print_error("Sample entry has not been specified!", "Line", line) - - ## Check FastQ file extension - for fastq in [fastq_1, fastq_2]: - if fastq: - if fastq.find(" ") != -1: - print_error("FastQ file contains spaces!", "Line", line) - if not fastq.endswith(".fastq.gz") and not fastq.endswith(".fq.gz"): + if line.strip(): + lspl = [x.strip().strip('"') for x in line.strip().split(",")] + + ## Check valid number of columns per row + if len(lspl) < len(HEADER): + print_error( + f"Invalid number of columns (minimum = {len(HEADER)})!", + "Line", + line, + ) + + num_cols = len([x for x in lspl if x]) + if num_cols < MIN_COLS: + print_error( + f"Invalid number of populated columns (minimum = {MIN_COLS})!", + "Line", + line, + ) + + ## Check sample name entries + sample, fastq_1, fastq_2, strandedness = lspl[: len(HEADER)] + if sample.find(" ") != -1: + print( + f"WARNING: Spaces have been replaced by underscores for sample: {sample}" + ) + sample = sample.replace(" ", "_") + if not sample: + print_error("Sample entry has not been specified!", "Line", line) + + ## Check FastQ file extension + for fastq in [fastq_1, fastq_2]: + if fastq: + if fastq.find(" ") != -1: + print_error("FastQ file contains spaces!", "Line", line) + if not fastq.endswith(".fastq.gz") and not fastq.endswith(".fq.gz"): + print_error( + "FastQ file does not have extension '.fastq.gz' or '.fq.gz'!", + "Line", + line, + ) + + ## Check strandedness + strandednesses = ["unstranded", "forward", "reverse"] + if strandedness: + if strandedness not in strandednesses: print_error( - "FastQ file does not have extension '.fastq.gz' or '.fq.gz'!", + f"Strandedness must be one of '{', '.join(strandednesses)}'!", "Line", line, ) - - ## Check strandedness - strandednesses = ["unstranded", "forward", "reverse"] - if strandedness: - if strandedness not in strandednesses: + else: print_error( - f"Strandedness must be one of '{', '.join(strandednesses)}'!", + f"Strandedness has not been specified! Must be one of {', '.join(strandednesses)}.", "Line", line, ) - else: - print_error( - f"Strandedness has not been specified! Must be one of {', '.join(strandednesses)}.", - "Line", - line, - ) - - ## Auto-detect paired-end/single-end - sample_info = [] ## [single_end, fastq_1, fastq_2, strandedness] - if sample and fastq_1 and fastq_2: ## Paired-end short reads - sample_info = ["0", fastq_1, fastq_2, strandedness] - elif sample and fastq_1 and not fastq_2: ## Single-end short reads - sample_info = ["1", fastq_1, fastq_2, strandedness] - else: - print_error("Invalid combination of columns provided!", "Line", line) - - ## Create sample mapping dictionary = {sample: [[ single_end, fastq_1, fastq_2, strandedness ]]} - if sample not in sample_mapping_dict: - sample_mapping_dict[sample] = [sample_info] - else: - if sample_info in sample_mapping_dict[sample]: - print_error("Samplesheet contains duplicate rows!", "Line", line) + + ## Auto-detect paired-end/single-end + sample_info = [] ## [single_end, fastq_1, fastq_2, strandedness] + if sample and fastq_1 and fastq_2: ## Paired-end short reads + sample_info = ["0", fastq_1, fastq_2, strandedness] + elif sample and fastq_1 and not fastq_2: ## Single-end short reads + sample_info = ["1", fastq_1, fastq_2, strandedness] + else: + print_error("Invalid combination of columns provided!", "Line", line) + + ## Create sample mapping dictionary = {sample: [[ single_end, fastq_1, fastq_2, strandedness ]]} + if sample not in sample_mapping_dict: + sample_mapping_dict[sample] = [sample_info] else: - sample_mapping_dict[sample].append(sample_info) + if sample_info in sample_mapping_dict[sample]: + print_error("Samplesheet contains duplicate rows!", "Line", line) + else: + sample_mapping_dict[sample].append(sample_info) ## Write validated samplesheet with appropriate columns if len(sample_mapping_dict) > 0: From d55892b6d04c73840c85f10b728ff4f63ae33c5a Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Sun, 20 Feb 2022 19:42:27 +0000 Subject: [PATCH 20/36] Fix #744 --- lib/WorkflowRnaseq.groovy | 22 +++++++++++ modules.json | 3 ++ .../modules/custom/getchromsizes/main.nf} | 17 ++++----- .../modules/custom/getchromsizes/meta.yml | 38 +++++++++++++++++++ subworkflows/local/prepare_genome.nf | 9 +++-- workflows/rnaseq.nf | 6 +++ 6 files changed, 83 insertions(+), 12 deletions(-) rename modules/{local/get_chrom_sizes.nf => nf-core/modules/custom/getchromsizes/main.nf} (64%) create mode 100644 modules/nf-core/modules/custom/getchromsizes/meta.yml diff --git a/lib/WorkflowRnaseq.groovy b/lib/WorkflowRnaseq.groovy index 13fea2760..fcbb86ab9 100755 --- a/lib/WorkflowRnaseq.groovy +++ b/lib/WorkflowRnaseq.groovy @@ -126,6 +126,28 @@ class WorkflowRnaseq { } } + // + // Function to generate an error if contigs in genome fasta file > 512 Mbp + // + public static void checkMaxContigSize(fai_file, log) { + def max_size = 512000000 + fai_file.eachLine { line -> + def lspl = line.split('\t') + def chrom = lspl[0] + def size = lspl[1] + if (size.toInteger() > max_size) { + log.error "=============================================================================\n" + + " Contig longer than ${max_size}bp found in reference genome!\n\n" + + " ${chrom}: ${size}\n\n" + + " Provide the '--bam_csi_index' parameter to use a CSI instead of BAI index.\n\n" + + " Please see:\n" + + " https://github.com/nf-core/rnaseq/issues/744\n" + + "=============================================================================" + System.exit(1) + } + } + } + // // Function that parses and returns the alignment rate from the STAR log output // diff --git a/modules.json b/modules.json index a31a984ff..9ecc513ce 100644 --- a/modules.json +++ b/modules.json @@ -12,6 +12,9 @@ "custom/dumpsoftwareversions": { "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, + "custom/getchromsizes": { + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" + }, "fastqc": { "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, diff --git a/modules/local/get_chrom_sizes.nf b/modules/nf-core/modules/custom/getchromsizes/main.nf similarity index 64% rename from modules/local/get_chrom_sizes.nf rename to modules/nf-core/modules/custom/getchromsizes/main.nf index 92f071edc..39da7d34e 100644 --- a/modules/local/get_chrom_sizes.nf +++ b/modules/nf-core/modules/custom/getchromsizes/main.nf @@ -1,5 +1,6 @@ -process GET_CHROM_SIZES { +process CUSTOM_GETCHROMSIZES { tag "$fasta" + label 'process_low' conda (params.enable_conda ? "bioconda::samtools=1.14" : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? @@ -10,24 +11,22 @@ process GET_CHROM_SIZES { path fasta output: - path '*.sizes' , emit: sizes - path '*.fai' , emit: fai - path "versions.yml", emit: versions + path '*.sizes' , emit: sizes + path '*.fai' , emit: fai + path "versions.yml", emit: versions when: task.ext.when == null || task.ext.when script: + def args = task.ext.args ?: '' """ - samtools \\ - faidx \\ - $fasta - + samtools faidx $fasta cut -f 1,2 ${fasta}.fai > ${fasta}.sizes cat <<-END_VERSIONS > versions.yml "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') + custom: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') END_VERSIONS """ } diff --git a/modules/nf-core/modules/custom/getchromsizes/meta.yml b/modules/nf-core/modules/custom/getchromsizes/meta.yml new file mode 100644 index 000000000..ee6c25718 --- /dev/null +++ b/modules/nf-core/modules/custom/getchromsizes/meta.yml @@ -0,0 +1,38 @@ +name: custom_getchromsizes +description: Generates a FASTA file of chromosome sizes and a fasta index file +keywords: + - fasta + - chromosome + - indexing +tools: + - samtools: + description: Tools for dealing with SAM, BAM and CRAM files + homepage: http://www.htslib.org/ + documentation: http://www.htslib.org/doc/samtools.html + tool_dev_url: https://github.com/samtools/samtools + doi: 10.1093/bioinformatics/btp352 + licence: ["MIT"] + +input: + - fasta: + type: file + description: FASTA file + pattern: "*.{fasta}" + +output: + - sizes: + type: file + description: File containing chromosome lengths + pattern: "*.{sizes}" + - fai: + type: file + description: FASTA index file + pattern: "*.{fai}" + - versions: + type: file + description: File containing software version + pattern: "versions.yml" + +authors: + - "@tamara-hodgetts" + - "@chris-cheshire" diff --git a/subworkflows/local/prepare_genome.nf b/subworkflows/local/prepare_genome.nf index 710d891c0..e98414288 100644 --- a/subworkflows/local/prepare_genome.nf +++ b/subworkflows/local/prepare_genome.nf @@ -15,6 +15,7 @@ include { UNTAR as UNTAR_RSEM_INDEX } from '../../modules/nf-core/module include { UNTAR as UNTAR_HISAT2_INDEX } from '../../modules/nf-core/modules/untar/main' include { UNTAR as UNTAR_SALMON_INDEX } from '../../modules/nf-core/modules/untar/main' +include { CUSTOM_GETCHROMSIZES } from '../../modules/nf-core/modules/custom/getchromsizes/main' include { GFFREAD } from '../../modules/nf-core/modules/gffread/main' include { BBMAP_BBSPLIT } from '../../modules/nf-core/modules/bbmap/bbsplit/main' include { HISAT2_EXTRACTSPLICESITES } from '../../modules/nf-core/modules/hisat2/extractsplicesites/main' @@ -26,7 +27,6 @@ include { RSEM_PREPAREREFERENCE as MAKE_TRANSCRIPTS_FASTA } from '../../mo include { GTF2BED } from '../../modules/local/gtf2bed' include { CAT_ADDITIONAL_FASTA } from '../../modules/local/cat_additional_fasta' include { GTF_GENE_FILTER } from '../../modules/local/gtf_gene_filter' -include { GET_CHROM_SIZES } from '../../modules/local/get_chrom_sizes' include { STAR_GENOMEGENERATE } from '../../modules/local/star_genomegenerate' workflow PREPARE_GENOME { @@ -121,8 +121,10 @@ workflow PREPARE_GENOME { // // Create chromosome sizes file // - ch_chrom_sizes = GET_CHROM_SIZES ( ch_fasta ).sizes - ch_versions = ch_versions.mix(GET_CHROM_SIZES.out.versions) + CUSTOM_GETCHROMSIZES ( ch_fasta ) + ch_fai = CUSTOM_GETCHROMSIZES.out.fai + ch_chrom_sizes = CUSTOM_GETCHROMSIZES.out.sizes + ch_versions = ch_versions.mix(CUSTOM_GETCHROMSIZES.out.versions) // // Uncompress BBSplit index or generate from scratch if required @@ -233,6 +235,7 @@ workflow PREPARE_GENOME { emit: fasta = ch_fasta // path: genome.fasta gtf = ch_gtf // path: genome.gtf + fai = ch_fai // path: genome.fai gene_bed = ch_gene_bed // path: gene.bed transcript_fasta = ch_transcript_fasta // path: transcript.fasta chrom_sizes = ch_chrom_sizes // path: genome.sizes diff --git a/workflows/rnaseq.nf b/workflows/rnaseq.nf index cfc40155d..4eca499e8 100755 --- a/workflows/rnaseq.nf +++ b/workflows/rnaseq.nf @@ -166,6 +166,12 @@ workflow RNASEQ { ) ch_versions = ch_versions.mix(PREPARE_GENOME.out.versions) + // Check if contigs in genome fasta file > 512 Mbp + PREPARE_GENOME + .out + .fai + .map { WorkflowRnaseq.checkMaxContigSize(it, log) } + // // SUBWORKFLOW: Read in samplesheet, validate and stage input files // From 24c69fba30b9a77f6d855ea4e335eb692b51937f Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Sun, 20 Feb 2022 19:42:37 +0000 Subject: [PATCH 21/36] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 214ec15ce..b13301a97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Enhancements & fixes * [[#734](https://github.com/nf-core/rnaseq/issues/734)] - Is a vulnerable picard still used ? log4j vulnerability +* [[#744](https://github.com/nf-core/rnaseq/issues/744)] - Auto-detect and raise error if CSI is required for BAM indexing * [[#752](https://github.com/nf-core/rnaseq/issues/752)] - How to set publishing mode for all processes? * [[#755](https://github.com/nf-core/rnaseq/issues/755)] - Rename RSEM_PREPAREREFERENCE_TRANSCRIPTS process * [[#759](https://github.com/nf-core/rnaseq/issues/759)] - Empty lines in samplesheet.csv cause a crash From 6775dc3831d51d6e2fe0afcf03dbf196777e18de Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Sun, 20 Feb 2022 19:50:26 +0000 Subject: [PATCH 22/36] Fix ECLint --- lib/WorkflowRnaseq.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/WorkflowRnaseq.groovy b/lib/WorkflowRnaseq.groovy index fcbb86ab9..804b932d0 100755 --- a/lib/WorkflowRnaseq.groovy +++ b/lib/WorkflowRnaseq.groovy @@ -140,7 +140,7 @@ class WorkflowRnaseq { " Contig longer than ${max_size}bp found in reference genome!\n\n" + " ${chrom}: ${size}\n\n" + " Provide the '--bam_csi_index' parameter to use a CSI instead of BAI index.\n\n" + - " Please see:\n" + + " Please see:\n" + " https://github.com/nf-core/rnaseq/issues/744\n" + "=============================================================================" System.exit(1) From 091f952e86cad952952cfaf8305f58be65a94c5f Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Sun, 20 Feb 2022 20:14:27 +0000 Subject: [PATCH 23/36] Fix process selector for CUSTOM_GETCHROMSIZES --- conf/modules.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/modules.config b/conf/modules.config index 4ec359881..dc7311fe6 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -131,7 +131,7 @@ process { ] } - withName: 'GET_CHROM_SIZES' { + withName: 'CUSTOM_GETCHROMSIZES' { publishDir = [ path: { "${params.outdir}/genome" }, mode: params.publish_dir_mode, From a7915a66676f320d914f98e618079854b0bc60e4 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Sun, 20 Feb 2022 20:14:45 +0000 Subject: [PATCH 24/36] Fix #753 --- lib/WorkflowRnaseq.groovy | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/WorkflowRnaseq.groovy b/lib/WorkflowRnaseq.groovy index 804b932d0..8c6eeeb52 100755 --- a/lib/WorkflowRnaseq.groovy +++ b/lib/WorkflowRnaseq.groovy @@ -32,6 +32,10 @@ class WorkflowRnaseq { } } + if (params.transcript_fasta) { + transcriptsFastaWarn(log) + } + if (!params.skip_bbsplit && !params.bbsplit_index && !params.bbsplit_fasta_list) { log.error "Please provide either --bbsplit_fasta_list / --bbsplit_index to run BBSplit." System.exit(1) @@ -273,6 +277,18 @@ class WorkflowRnaseq { "===================================================================================" } + // + // Print a warning if using '--transcript_fasta' + // + private static void transcriptsFastaWarn(log) { + log.warn "=============================================================================\n" + + " '--transcript_fasta' parameter has been provided.\n" + + " Make sure transcript names in this file match those in the GFF/GTF file.\n\n" + + " Please see:\n" + + " https://github.com/nf-core/rnaseq/issues/753\n" + + "===================================================================================" + } + // // Print a warning if --skip_alignment has been provided // From f1146a20505377fed3a83a4a1d7d38b0e8017f4a Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Sun, 20 Feb 2022 20:19:10 +0000 Subject: [PATCH 25/36] Fix ECLint --- CHANGELOG.md | 1 + lib/WorkflowRnaseq.groovy | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b13301a97..7d524b108 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [[#734](https://github.com/nf-core/rnaseq/issues/734)] - Is a vulnerable picard still used ? log4j vulnerability * [[#744](https://github.com/nf-core/rnaseq/issues/744)] - Auto-detect and raise error if CSI is required for BAM indexing * [[#752](https://github.com/nf-core/rnaseq/issues/752)] - How to set publishing mode for all processes? +* [[#753](https://github.com/nf-core/rnaseq/issues/753)] - Add warning when user provides `--transcript_fasta` * [[#755](https://github.com/nf-core/rnaseq/issues/755)] - Rename RSEM_PREPAREREFERENCE_TRANSCRIPTS process * [[#759](https://github.com/nf-core/rnaseq/issues/759)] - Empty lines in samplesheet.csv cause a crash diff --git a/lib/WorkflowRnaseq.groovy b/lib/WorkflowRnaseq.groovy index 8c6eeeb52..bc4af5b81 100755 --- a/lib/WorkflowRnaseq.groovy +++ b/lib/WorkflowRnaseq.groovy @@ -282,7 +282,7 @@ class WorkflowRnaseq { // private static void transcriptsFastaWarn(log) { log.warn "=============================================================================\n" + - " '--transcript_fasta' parameter has been provided.\n" + + " '--transcript_fasta' parameter has been provided.\n" + " Make sure transcript names in this file match those in the GFF/GTF file.\n\n" + " Please see:\n" + " https://github.com/nf-core/rnaseq/issues/753\n" + From 47814c91c792023713759dac97852e735582b32f Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Sun, 20 Feb 2022 20:33:56 +0000 Subject: [PATCH 26/36] Easy fix for #754 --- CHANGELOG.md | 1 + bin/deseq2_qc.r | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d524b108..d9e5a3e4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [[#744](https://github.com/nf-core/rnaseq/issues/744)] - Auto-detect and raise error if CSI is required for BAM indexing * [[#752](https://github.com/nf-core/rnaseq/issues/752)] - How to set publishing mode for all processes? * [[#753](https://github.com/nf-core/rnaseq/issues/753)] - Add warning when user provides `--transcript_fasta` +* [[#754](https://github.com/nf-core/rnaseq/issues/754)] - DESeq2 QC issue linked to `--count_col` parameter * [[#755](https://github.com/nf-core/rnaseq/issues/755)] - Rename RSEM_PREPAREREFERENCE_TRANSCRIPTS process * [[#759](https://github.com/nf-core/rnaseq/issues/759)] - Empty lines in samplesheet.csv cause a crash diff --git a/bin/deseq2_qc.r b/bin/deseq2_qc.r index edb487143..fa2e2c78a 100755 --- a/bin/deseq2_qc.r +++ b/bin/deseq2_qc.r @@ -30,7 +30,7 @@ library(pheatmap) option_list <- list( make_option(c("-i", "--count_file" ), type="character", default=NULL , metavar="path" , help="Count file matrix where rows are genes and columns are samples." ), - make_option(c("-f", "--count_col" ), type="integer" , default=2 , metavar="integer", help="First column containing sample count data." ), + make_option(c("-f", "--count_col" ), type="integer" , default=3 , metavar="integer", help="First column containing sample count data." ), make_option(c("-d", "--id_col" ), type="integer" , default=1 , metavar="integer", help="Column containing identifiers to be used." ), make_option(c("-r", "--sample_suffix" ), type="character", default='' , metavar="string" , help="Suffix to remove after sample name in columns e.g. '.rmDup.bam' if 'DRUG_R1.rmDup.bam'."), make_option(c("-o", "--outdir" ), type="character", default='./' , metavar="path" , help="Output directory." ), From 210069de56a063e940538ae860e4cce6170bda65 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 21 Feb 2022 14:20:54 +0000 Subject: [PATCH 27/36] Fix #769 --- .nf-core.yml | 2 +- CHANGELOG.md | 1 + docs/output.md | 2 +- modules.json | 2 +- modules/nf-core/modules/rseqc/tin/main.nf | 2 +- nextflow.config | 2 +- nextflow_schema.json | 2 +- 7 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.nf-core.yml b/.nf-core.yml index b5ffb1547..b809fec56 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -17,4 +17,4 @@ update: rseqc/junctionsaturation: "e745e167c1020928ef20ea1397b6b4d230681b4d" rseqc/readdistribution: "e745e167c1020928ef20ea1397b6b4d230681b4d" rseqc/readduplication: "e745e167c1020928ef20ea1397b6b4d230681b4d" - rseqc/tin: "e745e167c1020928ef20ea1397b6b4d230681b4d" + rseqc/tin: "4dbc166a7c30e963511fb5c9870fbcaa158a53a9" diff --git a/CHANGELOG.md b/CHANGELOG.md index d9e5a3e4a..423c62394 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [[#754](https://github.com/nf-core/rnaseq/issues/754)] - DESeq2 QC issue linked to `--count_col` parameter * [[#755](https://github.com/nf-core/rnaseq/issues/755)] - Rename RSEM_PREPAREREFERENCE_TRANSCRIPTS process * [[#759](https://github.com/nf-core/rnaseq/issues/759)] - Empty lines in samplesheet.csv cause a crash +* [[#769](https://github.com/nf-core/rnaseq/issues/769)] - Do not run RSeQC tin.py by default ### Parameters diff --git a/docs/output.md b/docs/output.md index e548495fe..32a9d9c7b 100644 --- a/docs/output.md +++ b/docs/output.md @@ -502,7 +502,7 @@ RSeQC documentation: [bam_stat.py](http://rseqc.sourceforge.net/#bam-stat-py) -This script is designed to evaluate RNA integrity at the transcript level. TIN (transcript integrity number) is named in analogous to RIN (RNA integrity number). RIN (RNA integrity number) is the most widely used metric to evaluate RNA integrity at sample (or transcriptome) level. It is a very useful preventive measure to ensure good RNA quality and robust, reproducible RNA sequencing. +This script is designed to evaluate RNA integrity at the transcript level. TIN (transcript integrity number) is named in analogous to RIN (RNA integrity number). RIN (RNA integrity number) is the most widely used metric to evaluate RNA integrity at sample (or transcriptome) level. It is a very useful preventive measure to ensure good RNA quality and robust, reproducible RNA sequencing. This process isn't run by default - please see [this issue](https://github.com/nf-core/rnaseq/issues/769). RSeQC documentation: [tin.py](http://rseqc.sourceforge.net/#tin-py) diff --git a/modules.json b/modules.json index 9ecc513ce..bcfa706f0 100644 --- a/modules.json +++ b/modules.json @@ -70,7 +70,7 @@ "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" }, "rseqc/tin": { - "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" + "git_sha": "4dbc166a7c30e963511fb5c9870fbcaa158a53a9" }, "salmon/index": { "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" diff --git a/modules/nf-core/modules/rseqc/tin/main.nf b/modules/nf-core/modules/rseqc/tin/main.nf index da58fc06b..67493371b 100644 --- a/modules/nf-core/modules/rseqc/tin/main.nf +++ b/modules/nf-core/modules/rseqc/tin/main.nf @@ -1,6 +1,6 @@ process RSEQC_TIN { tag "$meta.id" - label 'process_medium' + label 'process_high' conda (params.enable_conda ? "bioconda::rseqc=3.0.1 'conda-forge::r-base>=3.5'" : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? diff --git a/nextflow.config b/nextflow.config index b3dc62909..6653d3dbb 100644 --- a/nextflow.config +++ b/nextflow.config @@ -78,7 +78,7 @@ params { skip_deseq2_qc = false skip_multiqc = false deseq2_vst = false - rseqc_modules = 'bam_stat,inner_distance,infer_experiment,junction_annotation,junction_saturation,read_distribution,read_duplication,tin' + rseqc_modules = 'bam_stat,inner_distance,infer_experiment,junction_annotation,junction_saturation,read_distribution,read_duplication' // Boilerplate options outdir = './results' diff --git a/nextflow_schema.json b/nextflow_schema.json index f6281b2e9..363a0d755 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -422,7 +422,7 @@ "properties": { "rseqc_modules": { "type": "string", - "default": "bam_stat,inner_distance,infer_experiment,junction_annotation,junction_saturation,read_distribution,read_duplication,tin", + "default": "bam_stat,inner_distance,infer_experiment,junction_annotation,junction_saturation,read_distribution,read_duplication", "fa_icon": "fas fa-chart-pie", "description": "Specify the RSeQC modules to run." }, From 1f97e57cbed60da4ab7f08a9ce127310abd32334 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 21 Feb 2022 22:29:09 +0000 Subject: [PATCH 28/36] Fix #750 --- CHANGELOG.md | 1 + nextflow.config | 1 + nextflow_schema.json | 5 ++++ .../nf-core/fastqc_umitools_trimgalore.nf | 29 ++++++++++++++++--- workflows/rnaseq.nf | 3 +- 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 423c62394..1f8b11a7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [[#734](https://github.com/nf-core/rnaseq/issues/734)] - Is a vulnerable picard still used ? log4j vulnerability * [[#744](https://github.com/nf-core/rnaseq/issues/744)] - Auto-detect and raise error if CSI is required for BAM indexing +* [[#750](https://github.com/nf-core/rnaseq/issues/750)] - Optionally ignore R1 / R2 after UMI extraction process * [[#752](https://github.com/nf-core/rnaseq/issues/752)] - How to set publishing mode for all processes? * [[#753](https://github.com/nf-core/rnaseq/issues/753)] - Add warning when user provides `--transcript_fasta` * [[#754](https://github.com/nf-core/rnaseq/issues/754)] - DESeq2 QC issue linked to `--count_col` parameter diff --git a/nextflow.config b/nextflow.config index 6653d3dbb..e332c6809 100644 --- a/nextflow.config +++ b/nextflow.config @@ -28,6 +28,7 @@ params { with_umi = false umitools_extract_method = 'string' umitools_bc_pattern = null + umi_discard_read = null save_umi_intermeds = false // Trimming diff --git a/nextflow_schema.json b/nextflow_schema.json index 363a0d755..f31f58db8 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -70,6 +70,11 @@ "help_text": "More details can be found in the [UMI-tools documentation](https://umi-tools.readthedocs.io/en/latest/reference/extract.html#extract-method).", "description": "The UMI barcode pattern to use e.g. 'NNNNNN' indicates that the first 6 nucleotides of the read are from the UMI." }, + "umi_discard_read": { + "type": "integer", + "fa_icon": "fas fa-barcode", + "help_text": "After UMI barcode extraction discard either R1 or R2 by setting this parameter to 1 or 2, respectively.", + }, "save_umi_intermeds": { "type": "boolean", "fa_icon": "fas fa-save", diff --git a/subworkflows/nf-core/fastqc_umitools_trimgalore.nf b/subworkflows/nf-core/fastqc_umitools_trimgalore.nf index 2d3e93c7c..ac58fd893 100644 --- a/subworkflows/nf-core/fastqc_umitools_trimgalore.nf +++ b/subworkflows/nf-core/fastqc_umitools_trimgalore.nf @@ -8,10 +8,11 @@ include { TRIMGALORE } from '../../modules/nf-core/modules/trimgalore/main workflow FASTQC_UMITOOLS_TRIMGALORE { take: - reads // channel: [ val(meta), [ reads ] ] - skip_fastqc // boolean: true/false - with_umi // boolean: true/false - skip_trimming // boolean: true/false + reads // channel: [ val(meta), [ reads ] ] + skip_fastqc // boolean: true/false + with_umi // boolean: true/false + skip_trimming // boolean: true/false + umi_discard_read // integer: 0, 1 or 2 main: @@ -30,6 +31,26 @@ workflow FASTQC_UMITOOLS_TRIMGALORE { UMITOOLS_EXTRACT ( reads ).reads.set { umi_reads } umi_log = UMITOOLS_EXTRACT.out.log ch_versions = ch_versions.mix(UMITOOLS_EXTRACT.out.versions.first()) + + // Discard R1 / R2 if required + if ([1,2].contains(umi_discard_read)) { + def keep_idx = 1 + if (umi_discard_read == 2) { + keep_idx = 0 + } + + UMITOOLS_EXTRACT + .out + .reads + .map { meta, reads -> + if (!meta.single_end) { + meta['single_end'] = true + reads = reads[keep_idx] + } + return [ meta, reads ] + } + .set { umi_reads } + } } trim_reads = umi_reads diff --git a/workflows/rnaseq.nf b/workflows/rnaseq.nf index 4eca499e8..e6363235d 100755 --- a/workflows/rnaseq.nf +++ b/workflows/rnaseq.nf @@ -212,7 +212,8 @@ workflow RNASEQ { ch_cat_fastq, params.skip_fastqc || params.skip_qc, params.with_umi, - params.skip_trimming + params.skip_trimming, + params.umi_discard_read ) ch_versions = ch_versions.mix(FASTQC_UMITOOLS_TRIMGALORE.out.versions) From fb44c5e40967895a997ecc977cf5ad88e60dbec1 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 21 Feb 2022 22:45:13 +0000 Subject: [PATCH 29/36] Refactor modules.config for optional rseqc modules --- conf/modules.config | 222 +++++++++++++++++++++++++------------------- 1 file changed, 128 insertions(+), 94 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index dc7311fe6..867485047 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -3,13 +3,15 @@ Config file for defining DSL2 per module options and publishing paths ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Available keys to override module options: - ext.args = Additional arguments appended to command in module. - ext.args2 = Second set of arguments appended to command in module (multi-tool modules). - ext.args3 = Third set of arguments appended to command in module (multi-tool modules). - ext.prefix = File name prefix for output files. + ext.args = Additional arguments appended to command in module. + ext.args2 = Second set of arguments appended to command in module (multi-tool modules). + ext.args3 = Third set of arguments appended to command in module (multi-tool modules). + ext.prefix = File name prefix for output files. ---------------------------------------------------------------------------------------- */ +def rseqc_modules = params.rseqc_modules ? params.rseqc_modules.split(',').collect{ it.trim().toLowerCase() } : [] + // // General configuration options // @@ -824,127 +826,159 @@ if (!params.skip_alignment && !params.skip_qc) { } if (!params.skip_rseqc && params.rseqc_modules) { - process { - withName: '.*:RSEQC:RSEQC_BAMSTAT' { - publishDir = [ - path: { "${params.outdir}/${params.aligner}/rseqc/bam_stat" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } - - withName: '.*:RSEQC:RSEQC_INFEREXPERIMENT' { - publishDir = [ - path: { "${params.outdir}/${params.aligner}/rseqc/infer_experiment" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } - - withName: '.*:RSEQC:RSEQC_JUNCTIONANNOTATION' { - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/pdf" }, - mode: params.publish_dir_mode, - pattern: '*.pdf' - ], - [ - path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/bed" }, - mode: params.publish_dir_mode, - pattern: '*.bed' - ], - [ - path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/xls" }, - mode: params.publish_dir_mode, - pattern: '*.xls' - ], - [ - path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/log" }, - mode: params.publish_dir_mode, - pattern: '*.log' - ], - [ - path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/rscript" }, + if ('bam_stat' in rseqc_modules) { + process { + withName: '.*:RSEQC:RSEQC_BAMSTAT' { + publishDir = [ + path: { "${params.outdir}/${params.aligner}/rseqc/bam_stat" }, mode: params.publish_dir_mode, - pattern: '*.r' + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] - ] + } } + } - withName: '.*:RSEQC:RSEQC_JUNCTIONSATURATION' { - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/rseqc/junction_saturation/pdf" }, - mode: params.publish_dir_mode, - pattern: '*.pdf' - ], - [ - path: { "${params.outdir}/${params.aligner}/rseqc/junction_saturation/rscript" }, + if ('infer_experiment' in rseqc_modules) { + process { + withName: '.*:RSEQC:RSEQC_INFEREXPERIMENT' { + publishDir = [ + path: { "${params.outdir}/${params.aligner}/rseqc/infer_experiment" }, mode: params.publish_dir_mode, - pattern: '*.r' + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] - ] + } } + } - withName: '.*:RSEQC:RSEQC_READDUPLICATION' { - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/pdf" }, - mode: params.publish_dir_mode, - pattern: '*.pdf' - ], - [ - path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/xls" }, - mode: params.publish_dir_mode, - pattern: '*.xls' - ], - [ - path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/rscript" }, - mode: params.publish_dir_mode, - pattern: '*.r' + if ('junction_annotation' in rseqc_modules) { + process { + withName: '.*:RSEQC:RSEQC_JUNCTIONANNOTATION' { + publishDir = [ + [ + path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/pdf" }, + mode: params.publish_dir_mode, + pattern: '*.pdf' + ], + [ + path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/bed" }, + mode: params.publish_dir_mode, + pattern: '*.bed' + ], + [ + path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/xls" }, + mode: params.publish_dir_mode, + pattern: '*.xls' + ], + [ + path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/log" }, + mode: params.publish_dir_mode, + pattern: '*.log' + ], + [ + path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/rscript" }, + mode: params.publish_dir_mode, + pattern: '*.r' + ] ] - ] + } } + } - if (!params.bam_csi_index) { - withName: '.*:RSEQC:RSEQC_READDISTRIBUTION' { + if ('junction_saturation' in rseqc_modules) { + process { + withName: '.*:RSEQC:RSEQC_JUNCTIONSATURATION' { publishDir = [ - path: { "${params.outdir}/${params.aligner}/rseqc/read_distribution" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + [ + path: { "${params.outdir}/${params.aligner}/rseqc/junction_saturation/pdf" }, + mode: params.publish_dir_mode, + pattern: '*.pdf' + ], + [ + path: { "${params.outdir}/${params.aligner}/rseqc/junction_saturation/rscript" }, + mode: params.publish_dir_mode, + pattern: '*.r' + ] ] } - - withName: '.*:RSEQC:RSEQC_INNERDISTANCE' { + } + } + + if ('read_duplication' in rseqc_modules) { + process { + withName: '.*:RSEQC:RSEQC_READDUPLICATION' { publishDir = [ [ - path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/txt" }, + path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/pdf" }, mode: params.publish_dir_mode, - pattern: '*.txt', - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + pattern: '*.pdf' ], [ - path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/pdf" }, + path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/xls" }, mode: params.publish_dir_mode, - pattern: '*.pdf' + pattern: '*.xls' ], [ - path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/rscript" }, + path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/rscript" }, mode: params.publish_dir_mode, pattern: '*.r' ] ] } + } + } - withName: '.*:RSEQC:RSEQC_TIN' { - publishDir = [ - path: { "${params.outdir}/${params.aligner}/rseqc/tin" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] + if (!params.bam_csi_index) { + if ('read_distribution' in rseqc_modules) { + process { + withName: '.*:RSEQC:RSEQC_READDISTRIBUTION' { + publishDir = [ + path: { "${params.outdir}/${params.aligner}/rseqc/read_distribution" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } } } + if ('inner_distance' in rseqc_modules) { + process { + withName: '.*:RSEQC:RSEQC_INNERDISTANCE' { + publishDir = [ + [ + path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/txt" }, + mode: params.publish_dir_mode, + pattern: '*.txt', + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ], + [ + path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/pdf" }, + mode: params.publish_dir_mode, + pattern: '*.pdf' + ], + [ + path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/rscript" }, + mode: params.publish_dir_mode, + pattern: '*.r' + ] + ] + } + } + } + + if ('tin' in rseqc_modules) { + process { + withName: '.*:RSEQC:RSEQC_TIN' { + publishDir = [ + path: { "${params.outdir}/${params.aligner}/rseqc/tin" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + } + } + } + + process { withName: 'MULTIQC_TSV_STRAND_CHECK' { publishDir = [ path: { "${params.outdir}/multiqc" }, From c3313c0490f986ab0b37e9e3e250b31e655770b5 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 21 Feb 2022 23:14:56 +0000 Subject: [PATCH 30/36] Make --outdir mandatory --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .github/workflows/ci.yml | 10 +++++----- .nf-core.yml | 1 + CHANGELOG.md | 1 + README.md | 3 ++- conf/test.config | 2 +- conf/test_full.config | 2 +- docs/usage.md | 2 +- lib/WorkflowMain.groovy | 2 +- nextflow.config | 2 +- nextflow_schema.json | 7 +++++-- 11 files changed, 20 insertions(+), 14 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c6225f340..7a0935f41 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -19,7 +19,7 @@ Learn more about contributing: [CONTRIBUTING.md](https://github.com/nf-core/rnas - [ ] If you've added a new tool - have you followed the pipeline conventions in the [contribution docs](https://github.com/nf-core/rnaseq/tree/master/.github/CONTRIBUTING.md) - [ ] If necessary, also make a PR on the nf-core/rnaseq _branch_ on the [nf-core/test-datasets](https://github.com/nf-core/test-datasets) repository. - [ ] Make sure your code lints (`nf-core lint`). -- [ ] Ensure the test suite passes (`nextflow run . -profile test,docker`). +- [ ] Ensure the test suite passes (`nextflow run . -profile test,docker --outdir `). - [ ] Usage Documentation in `docs/usage.md` is updated. - [ ] Output Documentation in `docs/output.md` is updated. - [ ] `CHANGELOG.md` is updated. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf906f536..2f86e203a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,7 +44,7 @@ jobs: - name: Run pipeline with test data run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker + nextflow run ${GITHUB_WORKSPACE} -profile test,docker --outdir ./results star_salmon: name: Test STAR Salmon with workflow parameters @@ -76,7 +76,7 @@ jobs: - name: Run pipeline with STAR and various parameters run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker --aligner star_salmon ${{ matrix.parameters }} + nextflow run ${GITHUB_WORKSPACE} -profile test,docker --aligner star_salmon ${{ matrix.parameters }} --outdir ./results star_rsem: name: Test STAR RSEM with workflow parameters @@ -98,7 +98,7 @@ jobs: - name: Run pipeline with RSEM STAR and various parameters run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker --aligner star_rsem ${{ matrix.parameters }} + nextflow run ${GITHUB_WORKSPACE} -profile test,docker --aligner star_rsem ${{ matrix.parameters }} --outdir ./results hisat2: name: Test HISAT2 with workflow parameters @@ -120,7 +120,7 @@ jobs: - name: Run pipeline with HISAT2 and various parameters run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker --aligner hisat2 ${{ matrix.parameters }} + nextflow run ${GITHUB_WORKSPACE} -profile test,docker --aligner hisat2 ${{ matrix.parameters }} --outdir ./results salmon: name: Test Salmon with workflow parameters @@ -142,4 +142,4 @@ jobs: - name: Run pipeline with Salmon and various parameters run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker --pseudo_aligner salmon ${{ matrix.parameters }} + nextflow run ${GITHUB_WORKSPACE} -profile test,docker --pseudo_aligner salmon ${{ matrix.parameters }} --outdir ./results diff --git a/.nf-core.yml b/.nf-core.yml index b809fec56..7afb7dbcf 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -4,6 +4,7 @@ lint: - assets/email_template.txt - lib/NfcoreTemplate.groovy - .github/ISSUE_TEMPLATE/bug_report.yml + - .github/PULL_REQUEST_TEMPLATE.md - .github/workflows/branch.yml - .github/workflows/linting_comment.yml - .github/workflows/linting.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f8b11a7a..155353ae8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Enhancements & fixes +* [nf-core/tools#1415](https://github.com/nf-core/tools/issues/1415) - Make `--outdir` a mandatory parameter * [[#734](https://github.com/nf-core/rnaseq/issues/734)] - Is a vulnerable picard still used ? log4j vulnerability * [[#744](https://github.com/nf-core/rnaseq/issues/744)] - Auto-detect and raise error if CSI is required for BAM indexing * [[#750](https://github.com/nf-core/rnaseq/issues/750)] - Optionally ignore R1 / R2 after UMI extraction process diff --git a/README.md b/README.md index 6013885ca..7758d8083 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ The SRA download functionality has been removed from the pipeline (`>=3.2`) and 3. Download the pipeline and test it on a minimal dataset with a single command: ```console - nextflow run nf-core/rnaseq -profile test,YOURPROFILE + nextflow run nf-core/rnaseq -profile test,YOURPROFILE --outdir ``` Note that some form of configuration will be needed so that Nextflow knows how to fetch the required software. This is usually done in the form of a config profile (`YOURPROFILE` in the example command above). You can chain multiple config profiles in a comma-separated string. @@ -77,6 +77,7 @@ The SRA download functionality has been removed from the pipeline (`>=3.2`) and ```console nextflow run nf-core/rnaseq \ --input samplesheet.csv \ + --outdir \ --genome GRCh37 \ -profile ``` diff --git a/conf/test.config b/conf/test.config index df9b979f3..69fef77ef 100644 --- a/conf/test.config +++ b/conf/test.config @@ -5,7 +5,7 @@ Defines input files and everything required to run a fast and simple pipeline test. Use as follows: - nextflow run nf-core/rnaseq -profile test, + nextflow run nf-core/rnaseq -profile test, --outdir ---------------------------------------------------------------------------------------- */ diff --git a/conf/test_full.config b/conf/test_full.config index 265ec05a2..e15e50482 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -5,7 +5,7 @@ Defines input files and everything required to run a full size pipeline test. Use as follows: - nextflow run nf-core/rnaseq -profile test_full, + nextflow run nf-core/rnaseq -profile test_full, --outdir ---------------------------------------------------------------------------------------- */ diff --git a/docs/usage.md b/docs/usage.md index 9d58d30a9..b9143f5f0 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -80,7 +80,7 @@ If you are using [GENCODE](https://www.gencodegenes.org/) reference genome files The typical command for running the pipeline is as follows: ```console -nextflow run nf-core/rnaseq --input samplesheet.csv --genome GRCh37 -profile docker +nextflow run nf-core/rnaseq --input samplesheet.csv --outdir --genome GRCh37 -profile docker ``` This will launch the pipeline with the `docker` configuration profile. See below for more information about profiles. diff --git a/lib/WorkflowMain.groovy b/lib/WorkflowMain.groovy index f9369a3af..8d96f74c7 100755 --- a/lib/WorkflowMain.groovy +++ b/lib/WorkflowMain.groovy @@ -21,7 +21,7 @@ class WorkflowMain { // Print help to screen if required // public static String help(workflow, params, log) { - def command = "nextflow run ${workflow.manifest.name} --input samplesheet.csv --genome GRCh37 -profile docker" + def command = "nextflow run ${workflow.manifest.name} --input samplesheet.csv --outdir --genome GRCh37 -profile docker" def help_string = '' help_string += NfcoreTemplate.logo(workflow, params.monochrome_logs) help_string += NfcoreSchema.paramsHelp(workflow, params, command) diff --git a/nextflow.config b/nextflow.config index e332c6809..3fa9871aa 100644 --- a/nextflow.config +++ b/nextflow.config @@ -82,7 +82,7 @@ params { rseqc_modules = 'bam_stat,inner_distance,infer_experiment,junction_annotation,junction_saturation,read_distribution,read_duplication' // Boilerplate options - outdir = './results' + outdir = null multiqc_config = null multiqc_title = null email = null diff --git a/nextflow_schema.json b/nextflow_schema.json index f31f58db8..dcbd48dd0 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -10,6 +10,9 @@ "type": "object", "fa_icon": "fas fa-terminal", "description": "Define where the pipeline should find input data and save output data.", + "required": [ + "outdir" + ], "properties": { "input": { "type": "string", @@ -23,8 +26,8 @@ }, "outdir": { "type": "string", - "description": "Path to the output directory where the results will be saved.", - "default": "./results", + "format": "directory-path", + "description": "The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure.", "fa_icon": "fas fa-folder-open" }, "email": { From 03d17893618c44075e4c91d83dc0e72b58f6f0f7 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 21 Feb 2022 23:36:01 +0000 Subject: [PATCH 31/36] Fix linting --- CHANGELOG.md | 1 + conf/modules.config | 2 +- nextflow_schema.json | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 155353ae8..ecdbd2fe0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | Old parameter | New parameter | |-------------------------------|---------------------------------------| | | `--publish_dir_mode` | +| | `--umi_discard_read` | > **NB:** Parameter has been **updated** if both old and new parameter information is present. > diff --git a/conf/modules.config b/conf/modules.config index 867485047..e6eeea945 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -902,7 +902,7 @@ if (!params.skip_alignment && !params.skip_qc) { } } } - + if ('read_duplication' in rseqc_modules) { process { withName: '.*:RSEQC:RSEQC_READDUPLICATION' { diff --git a/nextflow_schema.json b/nextflow_schema.json index dcbd48dd0..e48ac2c85 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -76,7 +76,7 @@ "umi_discard_read": { "type": "integer", "fa_icon": "fas fa-barcode", - "help_text": "After UMI barcode extraction discard either R1 or R2 by setting this parameter to 1 or 2, respectively.", + "help_text": "After UMI barcode extraction discard either R1 or R2 by setting this parameter to 1 or 2, respectively." }, "save_umi_intermeds": { "type": "boolean", @@ -704,4 +704,4 @@ "$ref": "#/definitions/generic_options" } ] -} +} \ No newline at end of file From e09cde45a7151977d3e7c4880c55e070eb7b727d Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 22 Feb 2022 09:14:02 +0000 Subject: [PATCH 32/36] Use modulo operation instead to get read number --- subworkflows/nf-core/fastqc_umitools_trimgalore.nf | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/subworkflows/nf-core/fastqc_umitools_trimgalore.nf b/subworkflows/nf-core/fastqc_umitools_trimgalore.nf index ac58fd893..400867074 100644 --- a/subworkflows/nf-core/fastqc_umitools_trimgalore.nf +++ b/subworkflows/nf-core/fastqc_umitools_trimgalore.nf @@ -34,18 +34,13 @@ workflow FASTQC_UMITOOLS_TRIMGALORE { // Discard R1 / R2 if required if ([1,2].contains(umi_discard_read)) { - def keep_idx = 1 - if (umi_discard_read == 2) { - keep_idx = 0 - } - UMITOOLS_EXTRACT .out .reads .map { meta, reads -> if (!meta.single_end) { meta['single_end'] = true - reads = reads[keep_idx] + reads = reads[umi_discard_read % 2] } return [ meta, reads ] } From 738299ec23e6bcb8e5a4fe4c5e5c4ab9a7d6d9ef Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 22 Feb 2022 09:17:34 +0000 Subject: [PATCH 33/36] Tweak Groovy syntax --- subworkflows/nf-core/fastqc_umitools_trimgalore.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/nf-core/fastqc_umitools_trimgalore.nf b/subworkflows/nf-core/fastqc_umitools_trimgalore.nf index 400867074..31fdead3e 100644 --- a/subworkflows/nf-core/fastqc_umitools_trimgalore.nf +++ b/subworkflows/nf-core/fastqc_umitools_trimgalore.nf @@ -33,7 +33,7 @@ workflow FASTQC_UMITOOLS_TRIMGALORE { ch_versions = ch_versions.mix(UMITOOLS_EXTRACT.out.versions.first()) // Discard R1 / R2 if required - if ([1,2].contains(umi_discard_read)) { + if (umi_discard_read in [1,2]) { UMITOOLS_EXTRACT .out .reads From 3016c0bbe6256e198eea79d9dabe3aaf4648fe09 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 22 Feb 2022 09:27:17 +0000 Subject: [PATCH 34/36] Remove indentation for RSEQC logic in modules.config --- conf/modules.config | 254 ++++++++++++++++++++++---------------------- 1 file changed, 126 insertions(+), 128 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index e6eeea945..3e9fc6621 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -825,159 +825,157 @@ if (!params.skip_alignment && !params.skip_qc) { } } - if (!params.skip_rseqc && params.rseqc_modules) { - if ('bam_stat' in rseqc_modules) { - process { - withName: '.*:RSEQC:RSEQC_BAMSTAT' { - publishDir = [ - path: { "${params.outdir}/${params.aligner}/rseqc/bam_stat" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } + if (!params.skip_rseqc && 'bam_stat' in rseqc_modules) { + process { + withName: '.*:RSEQC:RSEQC_BAMSTAT' { + publishDir = [ + path: { "${params.outdir}/${params.aligner}/rseqc/bam_stat" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] } } + } - if ('infer_experiment' in rseqc_modules) { - process { - withName: '.*:RSEQC:RSEQC_INFEREXPERIMENT' { - publishDir = [ - path: { "${params.outdir}/${params.aligner}/rseqc/infer_experiment" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } + if (!params.skip_rseqc && 'infer_experiment' in rseqc_modules) { + process { + withName: '.*:RSEQC:RSEQC_INFEREXPERIMENT' { + publishDir = [ + path: { "${params.outdir}/${params.aligner}/rseqc/infer_experiment" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] } } + } - if ('junction_annotation' in rseqc_modules) { - process { - withName: '.*:RSEQC:RSEQC_JUNCTIONANNOTATION' { - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/pdf" }, - mode: params.publish_dir_mode, - pattern: '*.pdf' - ], - [ - path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/bed" }, - mode: params.publish_dir_mode, - pattern: '*.bed' - ], - [ - path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/xls" }, - mode: params.publish_dir_mode, - pattern: '*.xls' - ], - [ - path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/log" }, - mode: params.publish_dir_mode, - pattern: '*.log' - ], - [ - path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/rscript" }, - mode: params.publish_dir_mode, - pattern: '*.r' - ] + if (!params.skip_rseqc && 'junction_annotation' in rseqc_modules) { + process { + withName: '.*:RSEQC:RSEQC_JUNCTIONANNOTATION' { + publishDir = [ + [ + path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/pdf" }, + mode: params.publish_dir_mode, + pattern: '*.pdf' + ], + [ + path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/bed" }, + mode: params.publish_dir_mode, + pattern: '*.bed' + ], + [ + path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/xls" }, + mode: params.publish_dir_mode, + pattern: '*.xls' + ], + [ + path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/log" }, + mode: params.publish_dir_mode, + pattern: '*.log' + ], + [ + path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/rscript" }, + mode: params.publish_dir_mode, + pattern: '*.r' ] - } + ] } } + } - if ('junction_saturation' in rseqc_modules) { - process { - withName: '.*:RSEQC:RSEQC_JUNCTIONSATURATION' { - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/rseqc/junction_saturation/pdf" }, - mode: params.publish_dir_mode, - pattern: '*.pdf' - ], - [ - path: { "${params.outdir}/${params.aligner}/rseqc/junction_saturation/rscript" }, - mode: params.publish_dir_mode, - pattern: '*.r' - ] + if (!params.skip_rseqc && 'junction_saturation' in rseqc_modules) { + process { + withName: '.*:RSEQC:RSEQC_JUNCTIONSATURATION' { + publishDir = [ + [ + path: { "${params.outdir}/${params.aligner}/rseqc/junction_saturation/pdf" }, + mode: params.publish_dir_mode, + pattern: '*.pdf' + ], + [ + path: { "${params.outdir}/${params.aligner}/rseqc/junction_saturation/rscript" }, + mode: params.publish_dir_mode, + pattern: '*.r' ] - } + ] } } + } - if ('read_duplication' in rseqc_modules) { - process { - withName: '.*:RSEQC:RSEQC_READDUPLICATION' { - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/pdf" }, - mode: params.publish_dir_mode, - pattern: '*.pdf' - ], - [ - path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/xls" }, - mode: params.publish_dir_mode, - pattern: '*.xls' - ], - [ - path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/rscript" }, - mode: params.publish_dir_mode, - pattern: '*.r' - ] + if (!params.skip_rseqc && 'read_duplication' in rseqc_modules) { + process { + withName: '.*:RSEQC:RSEQC_READDUPLICATION' { + publishDir = [ + [ + path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/pdf" }, + mode: params.publish_dir_mode, + pattern: '*.pdf' + ], + [ + path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/xls" }, + mode: params.publish_dir_mode, + pattern: '*.xls' + ], + [ + path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/rscript" }, + mode: params.publish_dir_mode, + pattern: '*.r' ] - } + ] } } + } - if (!params.bam_csi_index) { - if ('read_distribution' in rseqc_modules) { - process { - withName: '.*:RSEQC:RSEQC_READDISTRIBUTION' { - publishDir = [ - path: { "${params.outdir}/${params.aligner}/rseqc/read_distribution" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } - } + if (!params.skip_rseqc && 'read_distribution' in rseqc_modules && !params.bam_csi_index) { + process { + withName: '.*:RSEQC:RSEQC_READDISTRIBUTION' { + publishDir = [ + path: { "${params.outdir}/${params.aligner}/rseqc/read_distribution" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] } + } + } - if ('inner_distance' in rseqc_modules) { - process { - withName: '.*:RSEQC:RSEQC_INNERDISTANCE' { - publishDir = [ - [ - path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/txt" }, - mode: params.publish_dir_mode, - pattern: '*.txt', - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ], - [ - path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/pdf" }, - mode: params.publish_dir_mode, - pattern: '*.pdf' - ], - [ - path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/rscript" }, - mode: params.publish_dir_mode, - pattern: '*.r' - ] - ] - } - } + if (!params.skip_rseqc && 'inner_distance' in rseqc_modules && !params.bam_csi_index) { + process { + withName: '.*:RSEQC:RSEQC_INNERDISTANCE' { + publishDir = [ + [ + path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/txt" }, + mode: params.publish_dir_mode, + pattern: '*.txt', + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ], + [ + path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/pdf" }, + mode: params.publish_dir_mode, + pattern: '*.pdf' + ], + [ + path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/rscript" }, + mode: params.publish_dir_mode, + pattern: '*.r' + ] + ] } + } + } - if ('tin' in rseqc_modules) { - process { - withName: '.*:RSEQC:RSEQC_TIN' { - publishDir = [ - path: { "${params.outdir}/${params.aligner}/rseqc/tin" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] - } - } + if (!params.skip_rseqc && 'tin' in rseqc_modules && !params.bam_csi_index) { + process { + withName: '.*:RSEQC:RSEQC_TIN' { + publishDir = [ + path: { "${params.outdir}/${params.aligner}/rseqc/tin" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] } } + } + if (!params.skip_rseqc && rseqc_modules) { process { withName: 'MULTIQC_TSV_STRAND_CHECK' { publishDir = [ From 9b1cc4bdd17266b7a9da708524f0f687913d95fe Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Fri, 25 Feb 2022 08:22:10 +0000 Subject: [PATCH 35/36] Bump pipeline version to 3.6 --- CHANGELOG.md | 2 +- nextflow.config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecdbd2fe0..bd1bb0822 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unpublished Version / DEV] +## [[3.6](https://github.com/nf-core/rnaseq/releases/tag/3.6)] - 2022-03-01 ### Enhancements & fixes diff --git a/nextflow.config b/nextflow.config index 3fa9871aa..1b723bb50 100644 --- a/nextflow.config +++ b/nextflow.config @@ -226,7 +226,7 @@ manifest { description = 'Nextflow RNA-Seq analysis pipeline, part of the nf-core community.' mainScript = 'main.nf' nextflowVersion = '!>=21.10.3' - version = '3.6dev' + version = '3.6' } // Load modules.config for DSL2 module specific options From f37d505b995df53986a143a47c6418b6a838281e Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Fri, 4 Mar 2022 13:17:25 +0000 Subject: [PATCH 36/36] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd1bb0822..2ea779811 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [[3.6](https://github.com/nf-core/rnaseq/releases/tag/3.6)] - 2022-03-01 +## [[3.6](https://github.com/nf-core/rnaseq/releases/tag/3.6)] - 2022-03-04 ### Enhancements & fixes