From 910d98d3ee2839b2ba1e940fe27bcc13c28663e1 Mon Sep 17 00:00:00 2001 From: Matthias Zepper Date: Tue, 10 Jan 2023 17:53:52 +0100 Subject: [PATCH 001/124] Add further example parameters to the UMI section of the usage manual (Lexogen kits as examples for inline UMIs in R1). --- docs/usage.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 49d26a8e4..b9e741a1a 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -79,10 +79,14 @@ The `--umitools_grouping_method` parameter affects [how similar, but non-identic #### Examples: -| UMI type | Source | Pipeline parameters | -| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | -| In read name | [Illumina BCL convert >3.7.5](https://emea.support.illumina.com/content/dam/illumina-support/documents/documentation/software_documentation/bcl_convert/bcl-convert-v3-7-5-software-guide-1000000163594-00.pdf) | `--with_umi --skip_umi_extract --umitools_umi_separator ":"` | -| In sequence | [Takara Bio SMARTer® Stranded Total RNA-Seq Kit v3](https://www.takarabio.com/documents/User%20Manual/SMARTer%20Stranded%20Total%20RNA/SMARTer%20Stranded%20Total%20RNA-Seq%20Kit%20v3%20-%20Pico%20Input%20Mammalian%20User%20Manual-a_114949.pdf) | `--with_umi --umitools_extract_method "regex" --umitools_bc_pattern2 "^(?P.{8})(?P.{6}).*"` | +| UMI type | Source | Pipeline parameters | +| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| In read name | [Illumina BCL convert >3.7.5](https://emea.support.illumina.com/content/dam/illumina-support/documents/documentation/software_documentation/bcl_convert/bcl-convert-v3-7-5-software-guide-1000000163594-00.pdf) | `--with_umi --skip_umi_extract --umitools_umi_separator ":"` | +| In sequence | [Lexogen QuantSeq® 3’ mRNA-Seq V2 FWD](https://www.lexogen.com/quantseq-3mrna-sequencing) + [UMI Second Strand Synthesis Module](https://faqs.lexogen.com/faq/how-can-i-add-umis-to-my-quantseq-libraries) | `--with_umi --umitools_extract_method "regex" --umitools_bc_pattern "^(?P.{6})(?P.{4}).*"` | +| In sequence | [Lexogen CORALL® Total RNA-Seq V1](https://www.lexogen.com/corall-total-rna-seq/)
> _mind [Appendix H](https://www.lexogen.com/wp-content/uploads/2020/04/095UG190V0130_CORALL-Total-RNA-Seq_2020-03-31.pdf) regarding optional trimming_ | `--with_umi --umitools_extract_method "regex" --umitools_bc_pattern "^(?P.{12}).*"`
Optional: `--clip_r2 9 --three_prime_clip_r2 12` | +| In sequence | [Takara Bio SMARTer® Stranded Total RNA-Seq Kit v3](https://www.takarabio.com/documents/User%20Manual/SMARTer%20Stranded%20Total%20RNA/SMARTer%20Stranded%20Total%20RNA-Seq%20Kit%20v3%20-%20Pico%20Input%20Mammalian%20User%20Manual-a_114949.pdf) | `--with_umi --umitools_extract_method "regex" --umitools_bc_pattern2 "^(?P.{8})(?P.{6}).*"` | + +> _No warranty for the accuracy or completeness of the parameters is implied_ ## Reference genome files From da6233b250c2793139e2f7f6c8c12eb7f778401f Mon Sep 17 00:00:00 2001 From: Thomas Sandmann Date: Mon, 16 Jan 2023 14:26:06 -0800 Subject: [PATCH 002/124] =?UTF-8?q?Added=20=203=E2=80=B2=20digital=20gene?= =?UTF-8?q?=20expression=20assays=20section?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This proposed section provides parameters for the QuantSeq FWD 3' mRNA sequencing protocol. --- docs/usage.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/docs/usage.md b/docs/usage.md index 49d26a8e4..bcbec9358 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -84,6 +84,37 @@ The `--umitools_grouping_method` parameter affects [how similar, but non-identic | In read name | [Illumina BCL convert >3.7.5](https://emea.support.illumina.com/content/dam/illumina-support/documents/documentation/software_documentation/bcl_convert/bcl-convert-v3-7-5-software-guide-1000000163594-00.pdf) | `--with_umi --skip_umi_extract --umitools_umi_separator ":"` | | In sequence | [Takara Bio SMARTer® Stranded Total RNA-Seq Kit v3](https://www.takarabio.com/documents/User%20Manual/SMARTer%20Stranded%20Total%20RNA/SMARTer%20Stranded%20Total%20RNA-Seq%20Kit%20v3%20-%20Pico%20Input%20Mammalian%20User%20Manual-a_114949.pdf) | `--with_umi --umitools_extract_method "regex" --umitools_bc_pattern2 "^(?P.{8})(?P.{6}).*"` | +### 3′ digital gene expression assays + +Some bulk RNA-seq library preparation protocols capture only a 3' tag from each transcript, e.g. [3'Pool-seq](https://pubmed.ncbi.nlm.nih.gov/31959126/), [DRUG-seq](https://pubs.acs.org/doi/10.1021/acschembio.1c00920), [BRB-seq](https://genomebiology.biomedcentral.com/articles/10.1186/s13059-019-1671-x) or Lexogen's commercial [QuantSeq 3' mRNA-seq FWD](https://www.lexogen.com/quantseq-3mrna-sequencing/) protocol. The following parameters have been validated for `QuantSeq 3' mRNA-seq FWD` data, and provide useful starting points for other 3' RNA-seq protocols: + +#### Custom STAR parameters + +Lexogen provides an example analysis workflow [on their website](https://www.lexogen.com/quantseq-data-analysis/), which includes the _ENCODE standard options_ for the [STAR aligner]([https://github.com/alexdobin/STAR/blob/master/doc/STARmanual.pdf](https://github.com/alexdobin/STAR)). In addition, Lexogen also decreases the tolerance for mismatches and clips poly(A) tails. To apply these settings, add the following parameters to your `nextflow run` command (or provide them in a config file): + +``` +--extra_star_align_args "--alignIntronMax 1000000 --alignIntronMin 20 --alignMatesGapMax 1000000 --alignSJoverhangMin 8 --outFilterMismatchNmax 999 --outFilterMultimapNmax 20 --outFilterType BySJout --outFilterMismatchNoverLmax 0.1 --clip3pAdapterSeq AAAAAAAA" +``` + +#### Custom Salmon arguments + +[Salmon's default quantitation algorithm](https://www.nature.com/articles/nmeth.4197) takes into account transcript length. +Because 3' tag protocols do not capture full transcripts, this feature needs to be deactivated by specifying: + +``` +--extra_salmon_quant_args "--noLengthCorrection" +``` + +#### QuantSeq UMI module + +If unique molecular identifiers were used to prepare the library, add the following arguments as well, to extract the UMIs and deduplicated alignments: + +``` +--with_umi +--umitools_extract_method regex +--umitools_bc_pattern "^(?P.{6})(?P.{4}).*" +``` + ## Reference genome files Please refer to the [nf-core website](https://nf-co.re/usage/reference_genomes) for general usage docs and guidelines regarding reference genomes. From fb7117c65c0f9673a871ef906c1fd4837027421d Mon Sep 17 00:00:00 2001 From: Luca Beltrame Date: Wed, 18 Jan 2023 13:43:35 +0100 Subject: [PATCH 003/124] Fix typo preventing the use of UMI processing with HISAT2 BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS_GENOME was mistakenly written as BAM_DEDUP_STATS_SAMTOOLS_UMI_UMITOOLS_GENOME, causing the workflow to error out in case the UMI option was set when using HISAT2. Fixes #929. --- workflows/rnaseq.nf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/workflows/rnaseq.nf b/workflows/rnaseq.nf index c22c8688c..6dc57e72d 100755 --- a/workflows/rnaseq.nf +++ b/workflows/rnaseq.nf @@ -522,19 +522,19 @@ workflow RNASEQ { // SUBWORKFLOW: Remove duplicate reads from BAM file based on UMIs // if (params.with_umi) { - BAM_DEDUP_STATS_SAMTOOLS_UMI_UMITOOLS_GENOME ( + BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS_GENOME ( ch_genome_bam.join(ch_genome_bam_index, by: [0]), params.umitools_dedup_stats ) - ch_genome_bam = BAM_DEDUP_STATS_SAMTOOLS_UMI_UMITOOLS_GENOME.out.bam - ch_genome_bam_index = BAM_DEDUP_STATS_SAMTOOLS_UMI_UMITOOLS_GENOME.out.bai - ch_samtools_stats = BAM_DEDUP_STATS_SAMTOOLS_UMI_UMITOOLS_GENOME.out.stats - ch_samtools_flagstat = BAM_DEDUP_STATS_SAMTOOLS_UMI_UMITOOLS_GENOME.out.flagstat - ch_samtools_idxstats = BAM_DEDUP_STATS_SAMTOOLS_UMI_UMITOOLS_GENOME.out.idxstats + ch_genome_bam = BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS_GENOME.out.bam + ch_genome_bam_index = BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS_GENOME.out.bai + ch_samtools_stats = BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS_GENOME.out.stats + ch_samtools_flagstat = BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS_GENOME.out.flagstat + ch_samtools_idxstats = BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS_GENOME.out.idxstats if (params.bam_csi_index) { - ch_genome_bam_index = BAM_DEDUP_STATS_SAMTOOLS_UMI_UMITOOLS_GENOME.out.csi + ch_genome_bam_index = BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS_GENOME.out.csi } - ch_versions = ch_versions.mix(BAM_DEDUP_STATS_SAMTOOLS_UMI_UMITOOLS_GENOME.out.versions) + ch_versions = ch_versions.mix(BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS_GENOME.out.versions) } } From 59cbe7341843f4290008bcfa60d5686b24259b57 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Thu, 19 Jan 2023 13:26:51 +0000 Subject: [PATCH 004/124] Apply suggestions from code review --- docs/usage.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index bcbec9358..e9fb95dba 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -90,7 +90,7 @@ Some bulk RNA-seq library preparation protocols capture only a 3' tag from each #### Custom STAR parameters -Lexogen provides an example analysis workflow [on their website](https://www.lexogen.com/quantseq-data-analysis/), which includes the _ENCODE standard options_ for the [STAR aligner]([https://github.com/alexdobin/STAR/blob/master/doc/STARmanual.pdf](https://github.com/alexdobin/STAR)). In addition, Lexogen also decreases the tolerance for mismatches and clips poly(A) tails. To apply these settings, add the following parameters to your `nextflow run` command (or provide them in a config file): +Lexogen provides an example analysis workflow [on their website](https://www.lexogen.com/quantseq-data-analysis/), which includes the _ENCODE standard options_ for the [STAR aligner]([https://github.com/alexdobin/STAR/blob/master/doc/STARmanual.pdf](https://github.com/alexdobin/STAR)). In addition, Lexogen also decreases the tolerance for mismatches and clips poly(A) tails. To apply these settings, add the following parameters when running the pipeline: ``` --extra_star_align_args "--alignIntronMax 1000000 --alignIntronMin 20 --alignMatesGapMax 1000000 --alignSJoverhangMin 8 --outFilterMismatchNmax 999 --outFilterMultimapNmax 20 --outFilterType BySJout --outFilterMismatchNoverLmax 0.1 --clip3pAdapterSeq AAAAAAAA" @@ -105,7 +105,7 @@ Because 3' tag protocols do not capture full transcripts, this feature needs to --extra_salmon_quant_args "--noLengthCorrection" ``` -#### QuantSeq UMI module +#### QuantSeq analysis with UMIs If unique molecular identifiers were used to prepare the library, add the following arguments as well, to extract the UMIs and deduplicated alignments: From 8000e0c9779b25cd57416b87abddf71e67870515 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Thu, 19 Jan 2023 13:28:02 +0000 Subject: [PATCH 005/124] [automated] Fix linting with Prettier --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index e9fb95dba..69b6bdd99 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -90,7 +90,7 @@ Some bulk RNA-seq library preparation protocols capture only a 3' tag from each #### Custom STAR parameters -Lexogen provides an example analysis workflow [on their website](https://www.lexogen.com/quantseq-data-analysis/), which includes the _ENCODE standard options_ for the [STAR aligner]([https://github.com/alexdobin/STAR/blob/master/doc/STARmanual.pdf](https://github.com/alexdobin/STAR)). In addition, Lexogen also decreases the tolerance for mismatches and clips poly(A) tails. To apply these settings, add the following parameters when running the pipeline: +Lexogen provides an example analysis workflow [on their website](https://www.lexogen.com/quantseq-data-analysis/), which includes the _ENCODE standard options_ for the [STAR aligner](<[https://github.com/alexdobin/STAR/blob/master/doc/STARmanual.pdf](https://github.com/alexdobin/STAR)>). In addition, Lexogen also decreases the tolerance for mismatches and clips poly(A) tails. To apply these settings, add the following parameters when running the pipeline: ``` --extra_star_align_args "--alignIntronMax 1000000 --alignIntronMin 20 --alignMatesGapMax 1000000 --alignSJoverhangMin 8 --outFilterMismatchNmax 999 --outFilterMultimapNmax 20 --outFilterType BySJout --outFilterMismatchNoverLmax 0.1 --clip3pAdapterSeq AAAAAAAA" From ea237f4faa6c3663a48c0aecadf744ef059fee71 Mon Sep 17 00:00:00 2001 From: maxulysse Date: Fri, 27 Jan 2023 11:51:05 +0100 Subject: [PATCH 006/124] Add tests samplesheet in the main repo --- conf/test.config | 2 +- tests/csv/3.10/samplesheet_test.csv | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 tests/csv/3.10/samplesheet_test.csv diff --git a/conf/test.config b/conf/test.config index cb7fc562d..8aea33aa7 100644 --- a/conf/test.config +++ b/conf/test.config @@ -20,7 +20,7 @@ params { max_time = '6.h' // Input data - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_test.csv' + input = "${projectDir}/tests/csv/3.10/samplesheet_test.csv" // Genome references fasta = 'https://github.com/nf-core/test-datasets/raw/rnaseq/reference/genome.fasta' diff --git a/tests/csv/3.10/samplesheet_test.csv b/tests/csv/3.10/samplesheet_test.csv new file mode 100644 index 000000000..2c5976c29 --- /dev/null +++ b/tests/csv/3.10/samplesheet_test.csv @@ -0,0 +1,8 @@ +sample,fastq_1,fastq_2,strandedness +WT_REP1,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357070_1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357070_2.fastq.gz,auto +WT_REP1,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357071_1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357071_2.fastq.gz,auto +WT_REP2,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357072_1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357072_2.fastq.gz,reverse +RAP1_UNINDUCED_REP1,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357073_1.fastq.gz,,auto +RAP1_UNINDUCED_REP2,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357074_1.fastq.gz,,reverse +RAP1_UNINDUCED_REP2,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357075_1.fastq.gz,,reverse +RAP1_IAA_30M_REP1,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357076_1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357076_2.fastq.gz,reverse From ba1981426c356b64e493c55553b3dedf0c3884eb Mon Sep 17 00:00:00 2001 From: maxulysse Date: Fri, 27 Jan 2023 11:56:07 +0100 Subject: [PATCH 007/124] add params.test_data_base --- conf/test.config | 20 ++++++++++---------- nextflow.config | 1 + nextflow_schema.json | 10 ++++++++-- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/conf/test.config b/conf/test.config index 8aea33aa7..fe9575982 100644 --- a/conf/test.config +++ b/conf/test.config @@ -23,16 +23,16 @@ params { input = "${projectDir}/tests/csv/3.10/samplesheet_test.csv" // Genome references - fasta = 'https://github.com/nf-core/test-datasets/raw/rnaseq/reference/genome.fasta' - gtf = 'https://github.com/nf-core/test-datasets/raw/rnaseq/reference/genes.gtf.gz' - gff = 'https://github.com/nf-core/test-datasets/raw/rnaseq/reference/genes.gff.gz' - transcript_fasta = 'https://github.com/nf-core/test-datasets/raw/rnaseq/reference/transcriptome.fasta' - additional_fasta = 'https://github.com/nf-core/test-datasets/raw/rnaseq/reference/gfp.fa.gz' - - bbsplit_fasta_list = 'https://github.com/nf-core/test-datasets/raw/rnaseq/reference/bbsplit_fasta_list.txt' - hisat2_index = 'https://github.com/nf-core/test-datasets/raw/rnaseq/reference/hisat2.tar.gz' - salmon_index = 'https://github.com/nf-core/test-datasets/raw/rnaseq/reference/salmon.tar.gz' - rsem_index = 'https://github.com/nf-core/test-datasets/raw/rnaseq/reference/rsem.tar.gz' + fasta = "${params.test_data_base}/reference/genome.fasta" + gtf = "${params.test_data_base}/reference/genes.gtf.gz" + gff = "${params.test_data_base}/reference/genes.gff.gz" + transcript_fasta = "${params.test_data_base}/reference/transcriptome.fasta" + additional_fasta = "${params.test_data_base}/reference/gfp.fa.gz" + + bbsplit_fasta_list = "${params.test_data_base}/reference/bbsplit_fasta_list.txt" + hisat2_index = "${params.test_data_base}/reference/hisat2.tar.gz" + salmon_index = "${params.test_data_base}/reference/salmon.tar.gz" + rsem_index = "${params.test_data_base}/reference/rsem.tar.gz" // Other parameters skip_bbsplit = false diff --git a/nextflow.config b/nextflow.config index f94f87baf..e2faa2763 100644 --- a/nextflow.config +++ b/nextflow.config @@ -118,6 +118,7 @@ params { config_profile_contact = null config_profile_url = null config_profile_name = null + test_data_base = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq3' // Max resource options // Defaults only, expecting to be overwritten diff --git a/nextflow_schema.json b/nextflow_schema.json index 90a223cef..4aae538ae 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -580,8 +580,14 @@ "description": "Institutional config URL link.", "hidden": true, "fa_icon": "fas fa-users-cog" - } - } + }, + "test_data_base": { + "type": "string", + "default": "https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq3", + "description": "Base path / URL for data used in the test profiles", + "help_text": "Warning: The `-profile test` samplesheet file itself contains remote paths. Setting this parameter does not alter the contents of that file.", + "hidden": true + }, } }, "max_job_request_options": { "title": "Max job request options", From f1941ae5d7d719f8f590ab7b1c37b95532ea6610 Mon Sep 17 00:00:00 2001 From: maxulysse Date: Fri, 27 Jan 2023 12:01:07 +0100 Subject: [PATCH 008/124] this is why you should not edit JSON files --- nextflow_schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nextflow_schema.json b/nextflow_schema.json index 4aae538ae..de2c57ce7 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -587,7 +587,8 @@ "description": "Base path / URL for data used in the test profiles", "help_text": "Warning: The `-profile test` samplesheet file itself contains remote paths. Setting this parameter does not alter the contents of that file.", "hidden": true - }, } + } + } }, "max_job_request_options": { "title": "Max job request options", From e2e574a773d3c215218349ef23584401e59ebc78 Mon Sep 17 00:00:00 2001 From: maxulysse Date: Fri, 27 Jan 2023 12:03:17 +0100 Subject: [PATCH 009/124] trying to use local files --- .github/workflows/ci.yml | 130 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 125 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index afb8b2119..b390ff6b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,9 +35,33 @@ jobs: with: version: "${{ matrix.NXF_VER }}" + - name: Cache test data + id: cache-testdata + uses: actions/cache@v3 + with: + path: test-datasets/ + key: rnaseq3-test-data + + - name: Check out test data + if: steps.cache-testdata.outputs.cache-hit != 'true' + uses: actions/checkout@v3 + with: + repository: nf-core/test-datasets + ref: rnaseq3 + path: test-datasets/ + + - name: Replace remote paths in samplesheets + run: | + for f in tests/csv/3.10/*csv; do + sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f + echo "========== $f ============" + cat $f + echo "========================================" + done; + - name: Run pipeline with test data run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker --outdir ./results + nextflow run ${GITHUB_WORKSPACE} -profile test,docker --outdir ./results --test_data_base ${{ github.workspace }}/test-datasets/ star_salmon: name: Test STAR Salmon with workflow parameters @@ -62,6 +86,30 @@ jobs: - name: Check out pipeline code uses: actions/checkout@v2 + - name: Cache test data + id: cache-testdata + uses: actions/cache@v3 + with: + path: test-datasets/ + key: rnaseq3-test-data + + - name: Check out test data + if: steps.cache-testdata.outputs.cache-hit != 'true' + uses: actions/checkout@v3 + with: + repository: nf-core/test-datasets + ref: rnaseq3 + path: test-datasets/ + + - name: Replace remote paths in samplesheets + run: | + for f in tests/csv/3.10/*csv; do + sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f + echo "========== $f ============" + cat $f + echo "========================================" + done; + - name: Install Nextflow run: | wget -qO- get.nextflow.io | bash @@ -69,7 +117,7 @@ jobs: - name: Run pipeline with STAR and various parameters run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker --aligner star_salmon ${{ matrix.parameters }} --outdir ./results + nextflow run ${GITHUB_WORKSPACE} -profile test,docker --aligner star_salmon ${{ matrix.parameters }} --outdir ./results --test_data_base ${{ github.workspace }}/test-datasets/ star_rsem: name: Test STAR RSEM with workflow parameters @@ -84,6 +132,30 @@ jobs: - name: Check out pipeline code uses: actions/checkout@v2 + - name: Cache test data + id: cache-testdata + uses: actions/cache@v3 + with: + path: test-datasets/ + key: rnaseq3-test-data + + - name: Check out test data + if: steps.cache-testdata.outputs.cache-hit != 'true' + uses: actions/checkout@v3 + with: + repository: nf-core/test-datasets + ref: rnaseq3 + path: test-datasets/ + + - name: Replace remote paths in samplesheets + run: | + for f in tests/csv/3.10/*csv; do + sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f + echo "========== $f ============" + cat $f + echo "========================================" + done; + - name: Install Nextflow run: | wget -qO- get.nextflow.io | bash @@ -91,7 +163,7 @@ jobs: - name: Run pipeline with RSEM STAR and various parameters run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker --aligner star_rsem ${{ matrix.parameters }} --outdir ./results + nextflow run ${GITHUB_WORKSPACE} -profile test,docker --aligner star_rsem ${{ matrix.parameters }} --outdir ./results --test_data_base ${{ github.workspace }}/test-datasets/ hisat2: name: Test HISAT2 with workflow parameters @@ -106,6 +178,30 @@ jobs: - name: Check out pipeline code uses: actions/checkout@v2 + - name: Cache test data + id: cache-testdata + uses: actions/cache@v3 + with: + path: test-datasets/ + key: rnaseq3-test-data + + - name: Check out test data + if: steps.cache-testdata.outputs.cache-hit != 'true' + uses: actions/checkout@v3 + with: + repository: nf-core/test-datasets + ref: rnaseq3 + path: test-datasets/ + + - name: Replace remote paths in samplesheets + run: | + for f in tests/csv/3.10/*csv; do + sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f + echo "========== $f ============" + cat $f + echo "========================================" + done; + - name: Install Nextflow run: | wget -qO- get.nextflow.io | bash @@ -113,7 +209,7 @@ jobs: - name: Run pipeline with HISAT2 and various parameters run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker --aligner hisat2 ${{ matrix.parameters }} --outdir ./results + nextflow run ${GITHUB_WORKSPACE} -profile test,docker --aligner hisat2 ${{ matrix.parameters }} --outdir ./results --test_data_base ${{ github.workspace }}/test-datasets/ salmon: name: Test Salmon with workflow parameters @@ -128,6 +224,30 @@ jobs: - name: Check out pipeline code uses: actions/checkout@v2 + - name: Cache test data + id: cache-testdata + uses: actions/cache@v3 + with: + path: test-datasets/ + key: rnaseq3-test-data + + - name: Check out test data + if: steps.cache-testdata.outputs.cache-hit != 'true' + uses: actions/checkout@v3 + with: + repository: nf-core/test-datasets + ref: rnaseq3 + path: test-datasets/ + + - name: Replace remote paths in samplesheets + run: | + for f in tests/csv/3.10/*csv; do + sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f + echo "========== $f ============" + cat $f + echo "========================================" + done; + - name: Install Nextflow run: | wget -qO- get.nextflow.io | bash @@ -135,4 +255,4 @@ jobs: - name: Run pipeline with Salmon and various parameters run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker --pseudo_aligner salmon ${{ matrix.parameters }} --outdir ./results + nextflow run ${GITHUB_WORKSPACE} -profile test,docker --pseudo_aligner salmon ${{ matrix.parameters }} --outdir ./results --test_data_base ${{ github.workspace }}/test-datasets/ From 2d8c44cc61e0d81efc98e42bc04d576d7520363b Mon Sep 17 00:00:00 2001 From: maxulysse Date: Fri, 27 Jan 2023 12:47:00 +0100 Subject: [PATCH 010/124] use samplesheet in the test_data repo --- .github/workflows/ci.yml | 2 +- conf/test.config | 2 +- tests/csv/3.10/samplesheet_test.csv | 8 -------- 3 files changed, 2 insertions(+), 10 deletions(-) delete mode 100644 tests/csv/3.10/samplesheet_test.csv diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b390ff6b5..12e253294 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -241,7 +241,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in tests/csv/3.10/*csv; do + for f in ${{ github.workspace }}/samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f diff --git a/conf/test.config b/conf/test.config index fe9575982..57811683c 100644 --- a/conf/test.config +++ b/conf/test.config @@ -20,7 +20,7 @@ params { max_time = '6.h' // Input data - input = "${projectDir}/tests/csv/3.10/samplesheet_test.csv" + input = "${params.test_data_base}/samplesheet/v3.10/samplesheet_test.csv" // Genome references fasta = "${params.test_data_base}/reference/genome.fasta" diff --git a/tests/csv/3.10/samplesheet_test.csv b/tests/csv/3.10/samplesheet_test.csv deleted file mode 100644 index 2c5976c29..000000000 --- a/tests/csv/3.10/samplesheet_test.csv +++ /dev/null @@ -1,8 +0,0 @@ -sample,fastq_1,fastq_2,strandedness -WT_REP1,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357070_1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357070_2.fastq.gz,auto -WT_REP1,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357071_1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357071_2.fastq.gz,auto -WT_REP2,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357072_1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357072_2.fastq.gz,reverse -RAP1_UNINDUCED_REP1,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357073_1.fastq.gz,,auto -RAP1_UNINDUCED_REP2,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357074_1.fastq.gz,,reverse -RAP1_UNINDUCED_REP2,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357075_1.fastq.gz,,reverse -RAP1_IAA_30M_REP1,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357076_1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/testdata/GSE110004/SRR6357076_2.fastq.gz,reverse From 0b4b19b4e959d6a180377c3da4d81f940c938ef4 Mon Sep 17 00:00:00 2001 From: maxulysse Date: Fri, 27 Jan 2023 12:49:50 +0100 Subject: [PATCH 011/124] fix path --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12e253294..153a95cab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,7 +52,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in tests/csv/3.10/*csv; do + for f in ${{ github.workspace }}/samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f @@ -103,7 +103,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in tests/csv/3.10/*csv; do + for f in ${{ github.workspace }}/samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f @@ -149,7 +149,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in tests/csv/3.10/*csv; do + for f in ${{ github.workspace }}/samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f @@ -195,7 +195,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in tests/csv/3.10/*csv; do + for f in ${{ github.workspace }}/samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f From 423ba0b09284d6c31db2ec6fe280e132599bb436 Mon Sep 17 00:00:00 2001 From: maxulysse Date: Fri, 27 Jan 2023 12:53:55 +0100 Subject: [PATCH 012/124] fix path --- .github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 153a95cab..31efa3714 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,7 +52,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in ${{ github.workspace }}/samplesheet/v3.10/*.csv; do + for f in samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f @@ -103,7 +103,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in ${{ github.workspace }}/samplesheet/v3.10/*.csv; do + for f in samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f @@ -149,7 +149,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in ${{ github.workspace }}/samplesheet/v3.10/*.csv; do + for f in samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f @@ -195,7 +195,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in ${{ github.workspace }}/samplesheet/v3.10/*.csv; do + for f in samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f @@ -241,7 +241,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in ${{ github.workspace }}/samplesheet/v3.10/*.csv; do + for f in samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f From 785ea73fb6bd98e7ca05680963b3318e5272d9e5 Mon Sep 17 00:00:00 2001 From: maxulysse Date: Fri, 27 Jan 2023 12:57:43 +0100 Subject: [PATCH 013/124] fix path --- .github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 31efa3714..0ab2968f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,7 +52,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in samplesheet/v3.10/*.csv; do + for f in test-datasets/samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f @@ -103,7 +103,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in samplesheet/v3.10/*.csv; do + for f in test-datasets/samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f @@ -149,7 +149,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in samplesheet/v3.10/*.csv; do + for f in test-datasets/samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f @@ -195,7 +195,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in samplesheet/v3.10/*.csv; do + for f in test-datasets/samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f @@ -241,7 +241,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in samplesheet/v3.10/*.csv; do + for f in test-datasets/samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f From f9f467c81f0aed41d225dc0fa3d9cbd4cf082093 Mon Sep 17 00:00:00 2001 From: maxulysse Date: Fri, 27 Jan 2023 12:59:26 +0100 Subject: [PATCH 014/124] fix path --- .github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0ab2968f7..82764e128 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,7 +52,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in test-datasets/samplesheet/v3.10/*.csv; do + for f in ${{ github.workspace }}/test-datasets/samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f @@ -103,7 +103,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in test-datasets/samplesheet/v3.10/*.csv; do + for f in ${{ github.workspace }}/test-datasets/samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f @@ -149,7 +149,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in test-datasets/samplesheet/v3.10/*.csv; do + for f in ${{ github.workspace }}/test-datasets/samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f @@ -195,7 +195,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in test-datasets/samplesheet/v3.10/*.csv; do + for f in ${{ github.workspace }}/test-datasets/samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f @@ -241,7 +241,7 @@ jobs: - name: Replace remote paths in samplesheets run: | - for f in test-datasets/samplesheet/v3.10/*.csv; do + for f in ${{ github.workspace }}/test-datasets/samplesheet/v3.10/*.csv; do sed -i "s=https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/=${{ github.workspace }}/test-datasets/=g" $f echo "========== $f ============" cat $f From bd4f148e18dccb61691d6c083b8e827462e92aab Mon Sep 17 00:00:00 2001 From: maxulysse Date: Fri, 27 Jan 2023 13:02:18 +0100 Subject: [PATCH 015/124] uncache data --- .github/workflows/ci.yml | 60 ++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 82764e128..e05c0f692 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,12 +35,12 @@ jobs: with: version: "${{ matrix.NXF_VER }}" - - name: Cache test data - id: cache-testdata - uses: actions/cache@v3 - with: - path: test-datasets/ - key: rnaseq3-test-data + # - name: Cache test data + # id: cache-testdata + # uses: actions/cache@v3 + # with: + # path: test-datasets/ + # key: rnaseq3-test-data - name: Check out test data if: steps.cache-testdata.outputs.cache-hit != 'true' @@ -86,12 +86,12 @@ jobs: - name: Check out pipeline code uses: actions/checkout@v2 - - name: Cache test data - id: cache-testdata - uses: actions/cache@v3 - with: - path: test-datasets/ - key: rnaseq3-test-data + # - name: Cache test data + # id: cache-testdata + # uses: actions/cache@v3 + # with: + # path: test-datasets/ + # key: rnaseq3-test-data - name: Check out test data if: steps.cache-testdata.outputs.cache-hit != 'true' @@ -132,12 +132,12 @@ jobs: - name: Check out pipeline code uses: actions/checkout@v2 - - name: Cache test data - id: cache-testdata - uses: actions/cache@v3 - with: - path: test-datasets/ - key: rnaseq3-test-data + # - name: Cache test data + # id: cache-testdata + # uses: actions/cache@v3 + # with: + # path: test-datasets/ + # key: rnaseq3-test-data - name: Check out test data if: steps.cache-testdata.outputs.cache-hit != 'true' @@ -178,12 +178,12 @@ jobs: - name: Check out pipeline code uses: actions/checkout@v2 - - name: Cache test data - id: cache-testdata - uses: actions/cache@v3 - with: - path: test-datasets/ - key: rnaseq3-test-data + # - name: Cache test data + # id: cache-testdata + # uses: actions/cache@v3 + # with: + # path: test-datasets/ + # key: rnaseq3-test-data - name: Check out test data if: steps.cache-testdata.outputs.cache-hit != 'true' @@ -224,12 +224,12 @@ jobs: - name: Check out pipeline code uses: actions/checkout@v2 - - name: Cache test data - id: cache-testdata - uses: actions/cache@v3 - with: - path: test-datasets/ - key: rnaseq3-test-data + # - name: Cache test data + # id: cache-testdata + # uses: actions/cache@v3 + # with: + # path: test-datasets/ + # key: rnaseq3-test-data - name: Check out test data if: steps.cache-testdata.outputs.cache-hit != 'true' From 8770ee631e2f9be72e5a3bfb79099483a67d282c Mon Sep 17 00:00:00 2001 From: maxulysse Date: Fri, 27 Jan 2023 13:04:24 +0100 Subject: [PATCH 016/124] re-cache data --- .github/workflows/ci.yml | 60 ++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e05c0f692..82764e128 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,12 +35,12 @@ jobs: with: version: "${{ matrix.NXF_VER }}" - # - name: Cache test data - # id: cache-testdata - # uses: actions/cache@v3 - # with: - # path: test-datasets/ - # key: rnaseq3-test-data + - name: Cache test data + id: cache-testdata + uses: actions/cache@v3 + with: + path: test-datasets/ + key: rnaseq3-test-data - name: Check out test data if: steps.cache-testdata.outputs.cache-hit != 'true' @@ -86,12 +86,12 @@ jobs: - name: Check out pipeline code uses: actions/checkout@v2 - # - name: Cache test data - # id: cache-testdata - # uses: actions/cache@v3 - # with: - # path: test-datasets/ - # key: rnaseq3-test-data + - name: Cache test data + id: cache-testdata + uses: actions/cache@v3 + with: + path: test-datasets/ + key: rnaseq3-test-data - name: Check out test data if: steps.cache-testdata.outputs.cache-hit != 'true' @@ -132,12 +132,12 @@ jobs: - name: Check out pipeline code uses: actions/checkout@v2 - # - name: Cache test data - # id: cache-testdata - # uses: actions/cache@v3 - # with: - # path: test-datasets/ - # key: rnaseq3-test-data + - name: Cache test data + id: cache-testdata + uses: actions/cache@v3 + with: + path: test-datasets/ + key: rnaseq3-test-data - name: Check out test data if: steps.cache-testdata.outputs.cache-hit != 'true' @@ -178,12 +178,12 @@ jobs: - name: Check out pipeline code uses: actions/checkout@v2 - # - name: Cache test data - # id: cache-testdata - # uses: actions/cache@v3 - # with: - # path: test-datasets/ - # key: rnaseq3-test-data + - name: Cache test data + id: cache-testdata + uses: actions/cache@v3 + with: + path: test-datasets/ + key: rnaseq3-test-data - name: Check out test data if: steps.cache-testdata.outputs.cache-hit != 'true' @@ -224,12 +224,12 @@ jobs: - name: Check out pipeline code uses: actions/checkout@v2 - # - name: Cache test data - # id: cache-testdata - # uses: actions/cache@v3 - # with: - # path: test-datasets/ - # key: rnaseq3-test-data + - name: Cache test data + id: cache-testdata + uses: actions/cache@v3 + with: + path: test-datasets/ + key: rnaseq3-test-data - name: Check out test data if: steps.cache-testdata.outputs.cache-hit != 'true' From 1c3dcc178bf6ac8492b92cadce4a59f289543b21 Mon Sep 17 00:00:00 2001 From: maxulysse Date: Fri, 27 Jan 2023 13:07:24 +0100 Subject: [PATCH 017/124] should not have updated the data that is cached... --- .github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 82764e128..b3d0ae611 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: uses: actions/cache@v3 with: path: test-datasets/ - key: rnaseq3-test-data + key: rnaseq3_10-test-data - name: Check out test data if: steps.cache-testdata.outputs.cache-hit != 'true' @@ -91,7 +91,7 @@ jobs: uses: actions/cache@v3 with: path: test-datasets/ - key: rnaseq3-test-data + key: rnaseq3_10-test-data - name: Check out test data if: steps.cache-testdata.outputs.cache-hit != 'true' @@ -137,7 +137,7 @@ jobs: uses: actions/cache@v3 with: path: test-datasets/ - key: rnaseq3-test-data + key: rnaseq3_10-test-data - name: Check out test data if: steps.cache-testdata.outputs.cache-hit != 'true' @@ -183,7 +183,7 @@ jobs: uses: actions/cache@v3 with: path: test-datasets/ - key: rnaseq3-test-data + key: rnaseq3_10-test-data - name: Check out test data if: steps.cache-testdata.outputs.cache-hit != 'true' @@ -229,7 +229,7 @@ jobs: uses: actions/cache@v3 with: path: test-datasets/ - key: rnaseq3-test-data + key: rnaseq3_10-test-data - name: Check out test data if: steps.cache-testdata.outputs.cache-hit != 'true' From 6b86d7f450ef163536436a1e0a4ed09b5571f21a Mon Sep 17 00:00:00 2001 From: Matthias Zepper Date: Fri, 3 Feb 2023 13:49:41 +0100 Subject: [PATCH 018/124] Linting with the new version of Black 23.1' --- bin/check_samplesheet.py | 2 - bin/filter_gtf_for_genes_in_genome.py | 1 - bin/mqc_features_stat.py | 1 - bin/prepare-for-rsem.py | 7 - modules.json | 114 +++++----- nextflow_schema.json | 300 +++++++++++--------------- 6 files changed, 187 insertions(+), 238 deletions(-) diff --git a/bin/check_samplesheet.py b/bin/check_samplesheet.py index 69d67446f..05971a5d9 100755 --- a/bin/check_samplesheet.py +++ b/bin/check_samplesheet.py @@ -48,7 +48,6 @@ def check_samplesheet(file_in, file_out): sample_mapping_dict = {} with open(file_in, "r", encoding="utf-8-sig") as fin: - ## Check header MIN_COLS = 3 HEADER = ["sample", "fastq_1", "fastq_2", "strandedness"] @@ -142,7 +141,6 @@ def check_samplesheet(file_in, file_out): ",".join(["sample", "single_end", "fastq_1", "fastq_2", "strandedness"] + header[len(HEADER) :]) + "\n" ) for sample in sorted(sample_mapping_dict.keys()): - ## Check that multiple runs of the same sample are of the same datatype i.e. single-end / paired-end if not all(x[0] == sample_mapping_dict[sample][0][0] for x in sample_mapping_dict[sample]): print_error( diff --git a/bin/filter_gtf_for_genes_in_genome.py b/bin/filter_gtf_for_genes_in_genome.py index ef4c87cd4..9f876eaa0 100755 --- a/bin/filter_gtf_for_genes_in_genome.py +++ b/bin/filter_gtf_for_genes_in_genome.py @@ -46,7 +46,6 @@ def extract_genes_in_genome(fasta, gtf_in, gtf_out): n_lines_in_genome = 0 with open(gtf_out, "w") as f: with open(gtf_in) as g: - for line in g.readlines(): n_total_lines += 1 seq_name_gtf = line.split("\t")[0] diff --git a/bin/mqc_features_stat.py b/bin/mqc_features_stat.py index c0cb59dc9..689a3f215 100755 --- a/bin/mqc_features_stat.py +++ b/bin/mqc_features_stat.py @@ -24,7 +24,6 @@ def mqc_feature_stat(bfile, features, outfile, sname=None): - # If sample name not given use file name if not sname: sname = os.path.splitext(os.path.basename(bfile))[0] diff --git a/bin/prepare-for-rsem.py b/bin/prepare-for-rsem.py index 95ef24686..4a4009fa6 100755 --- a/bin/prepare-for-rsem.py +++ b/bin/prepare-for-rsem.py @@ -68,7 +68,6 @@ def chunk_bam(bamfile): output_buffer = list() for read in bamfile: - if last_query_name is not None and last_query_name != read.query_name: yield (output_buffer) output_buffer = list() @@ -84,7 +83,6 @@ def copy_tags(tags, read1, read2): to read2, if the tag is set""" for tag in tags: - try: read1_tag = read1.get_tag(tag, with_value_type=True) read2.set_tag(tag, value=read1_tag[0], value_type=read1_tag[1]) @@ -122,7 +120,6 @@ def pick_mate(read, template_dict, mate_key): def main(argv=None): - if argv is None: argv = sys.argv @@ -174,7 +171,6 @@ def main(argv=None): options.tags = options.tags.split(",") for template in chunk_bam(inbam): - assert len(set(r.query_name for r in template)) == 1 current_template = {True: defaultdict(list), False: defaultdict(list)} @@ -185,7 +181,6 @@ def main(argv=None): output = set() for read in template: - mate = None # if this read is a non_primary alignment, we first want to check if it has a mate @@ -231,7 +226,6 @@ def main(argv=None): # each pair twice - once when we scan read1 and once when we scan read2. Thus we need # to make sure we don't output something already output. if read.is_read1: - mate = copy_tags(options.tags, read, mate) output_key = str(read) + str(mate) @@ -242,7 +236,6 @@ def main(argv=None): skipped_stats["pairs_output"] += 1 elif read.is_read2: - read = copy_tags(options.tags, mate, read) output_key = str(mate) + str(read) diff --git a/modules.json b/modules.json index 0403e1f6a..38d19ec1d 100644 --- a/modules.json +++ b/modules.json @@ -8,143 +8,143 @@ "bbmap/bbsplit": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": ["modules"], }, "cat/fastq": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": ["modules"], }, "custom/dumpsoftwareversions": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": ["modules"], }, "custom/getchromsizes": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", "installed_by": ["modules"], - "patch": "modules/nf-core/custom/getchromsizes/custom-getchromsizes.diff" + "patch": "modules/nf-core/custom/getchromsizes/custom-getchromsizes.diff", }, "fastqc": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["fastq_fastqc_umitools_trimgalore"] + "installed_by": ["fastq_fastqc_umitools_trimgalore"], }, "fq/subsample": { "branch": "master", "git_sha": "ad462aa294faf9a8c42688a08daf81a580594f70", - "installed_by": ["modules", "fastq_subsample_fq_salmon"] + "installed_by": ["modules", "fastq_subsample_fq_salmon"], }, "gffread": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": ["modules"], }, "gunzip": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": ["modules"], }, "hisat2/align": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["fastq_align_hisat2"] + "installed_by": ["fastq_align_hisat2"], }, "hisat2/build": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": ["modules"], }, "hisat2/extractsplicesites": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": ["modules"], }, "picard/markduplicates": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_markduplicates_picard"] + "installed_by": ["bam_markduplicates_picard"], }, "preseq/lcextrap": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": ["modules"], }, "qualimap/rnaseq": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": ["modules"], }, "rsem/calculateexpression": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": ["modules"], }, "rsem/preparereference": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": ["modules"], }, "rseqc/bamstat": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_rseqc"] + "installed_by": ["bam_rseqc"], }, "rseqc/inferexperiment": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_rseqc"] + "installed_by": ["bam_rseqc"], }, "rseqc/innerdistance": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_rseqc"] + "installed_by": ["bam_rseqc"], }, "rseqc/junctionannotation": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_rseqc"] + "installed_by": ["bam_rseqc"], }, "rseqc/junctionsaturation": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_rseqc"] + "installed_by": ["bam_rseqc"], }, "rseqc/readdistribution": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_rseqc"] + "installed_by": ["bam_rseqc"], }, "rseqc/readduplication": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_rseqc"] + "installed_by": ["bam_rseqc"], }, "rseqc/tin": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_rseqc"] + "installed_by": ["bam_rseqc"], }, "salmon/index": { "branch": "master", "git_sha": "94b06f1683ddf893cf06525f6e7f0573ad8fbf83", - "installed_by": ["fastq_subsample_fq_salmon"] + "installed_by": ["fastq_subsample_fq_salmon"], }, "salmon/quant": { "branch": "master", "git_sha": "94b06f1683ddf893cf06525f6e7f0573ad8fbf83", - "installed_by": ["modules", "fastq_subsample_fq_salmon"] + "installed_by": ["modules", "fastq_subsample_fq_salmon"], }, "samtools/flagstat": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_stats_samtools"] + "installed_by": ["bam_stats_samtools"], }, "samtools/idxstats": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_stats_samtools"] + "installed_by": ["bam_stats_samtools"], }, "samtools/index": { "branch": "master", @@ -152,74 +152,74 @@ "installed_by": [ "bam_markduplicates_picard", "bam_sort_stats_samtools", - "bam_dedup_stats_samtools_umitools" - ] + "bam_dedup_stats_samtools_umitools", + ], }, "samtools/sort": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_sort_stats_samtools"] + "installed_by": ["bam_sort_stats_samtools"], }, "samtools/stats": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_stats_samtools"] + "installed_by": ["bam_stats_samtools"], }, "sortmerna": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": ["modules"], }, "star/align": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": ["modules"], }, "star/genomegenerate": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": ["modules"], }, "stringtie/stringtie": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": ["modules"], }, "subread/featurecounts": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": ["modules"], }, "trimgalore": { "branch": "master", "git_sha": "72ffbd7128015a1d4b65b95ff8d37be8fee2f981", - "installed_by": ["fastq_fastqc_umitools_trimgalore"] + "installed_by": ["fastq_fastqc_umitools_trimgalore"], }, "ucsc/bedclip": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bedgraph_bedclip_bedgraphtobigwig"] + "installed_by": ["bedgraph_bedclip_bedgraphtobigwig"], }, "ucsc/bedgraphtobigwig": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bedgraph_bedclip_bedgraphtobigwig"] + "installed_by": ["bedgraph_bedclip_bedgraphtobigwig"], }, "umitools/dedup": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_dedup_stats_samtools_umitools"] + "installed_by": ["bam_dedup_stats_samtools_umitools"], }, "umitools/extract": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["fastq_fastqc_umitools_trimgalore"] + "installed_by": ["fastq_fastqc_umitools_trimgalore"], }, "untar": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] - } + "installed_by": ["modules"], + }, } }, "subworkflows": { @@ -227,22 +227,22 @@ "bam_dedup_stats_samtools_umitools": { "branch": "master", "git_sha": "41891ec2c3704911cd68b9317f26545b95a1c48d", - "installed_by": ["subworkflows"] + "installed_by": ["subworkflows"], }, "bam_markduplicates_picard": { "branch": "master", "git_sha": "6daac2bc63f4847e0c7cc661f4f5b043ac13faaf", - "installed_by": ["subworkflows"] + "installed_by": ["subworkflows"], }, "bam_rseqc": { "branch": "master", "git_sha": "36a77f7c6decf2d1fb9f639ae982bc148d6828aa", - "installed_by": ["subworkflows"] + "installed_by": ["subworkflows"], }, "bam_sort_stats_samtools": { "branch": "master", "git_sha": "3911652a6b24249358f79e8b8466338d63efb2a2", - "installed_by": ["fastq_align_hisat2"] + "installed_by": ["fastq_align_hisat2"], }, "bam_stats_samtools": { "branch": "master", @@ -250,31 +250,31 @@ "installed_by": [ "bam_sort_stats_samtools", "bam_dedup_stats_samtools_umitools", - "bam_markduplicates_picard" - ] + "bam_markduplicates_picard", + ], }, "bedgraph_bedclip_bedgraphtobigwig": { "branch": "master", "git_sha": "b81a313d8fac0a82a8a4ff0de80590b2f97f11ad", - "installed_by": ["subworkflows"] + "installed_by": ["subworkflows"], }, "fastq_align_hisat2": { "branch": "master", "git_sha": "9057e75e8ac959373a72a9402130fdea2e2d1398", - "installed_by": ["subworkflows"] + "installed_by": ["subworkflows"], }, "fastq_fastqc_umitools_trimgalore": { "branch": "master", "git_sha": "72ffbd7128015a1d4b65b95ff8d37be8fee2f981", - "installed_by": ["subworkflows"] + "installed_by": ["subworkflows"], }, "fastq_subsample_fq_salmon": { "branch": "master", "git_sha": "82d60046b4519e9dbef4a934371a53fa7666eabc", - "installed_by": ["subworkflows"] - } + "installed_by": ["subworkflows"], + }, } - } + }, } - } + }, } diff --git a/nextflow_schema.json b/nextflow_schema.json index de2c57ce7..ccdcc8f05 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -20,32 +20,32 @@ "schema": "assets/schema_input.json", "description": "Path to comma-separated file containing information about the samples in the experiment.", "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 4 columns, and a header row. See [usage docs](https://nf-co.re/rnaseq/usage#samplesheet-input).", - "fa_icon": "fas fa-file-csv" + "fa_icon": "fas fa-file-csv", }, "outdir": { "type": "string", "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" + "fa_icon": "fas fa-folder-open", }, "email": { "type": "string", "description": "Email address for completion summary.", "fa_icon": "fas fa-envelope", "help_text": "Set this parameter to your e-mail address to get a summary e-mail with details of the run sent to you when the workflow exits. If set in your user config file (`~/.nextflow/config`) then you don't need to specify this on the command line for every run.", - "pattern": "^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$" + "pattern": "^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$", }, "multiqc_title": { "type": "string", "description": "MultiQC report title. Printed as page header, used for filename if not otherwise specified.", - "fa_icon": "fas fa-file-signature" + "fa_icon": "fas fa-file-signature", }, "save_merged_fastq": { "type": "boolean", "fa_icon": "fas fa-save", - "description": "Save FastQ files after merging re-sequenced libraries in the results directory." - } - } + "description": "Save FastQ files after merging re-sequenced libraries in the results directory.", + }, + }, }, "umi_options": { "title": "UMI options", @@ -56,61 +56,61 @@ "with_umi": { "type": "boolean", "fa_icon": "fas fa-barcode", - "description": "Enable UMI-based read deduplication." + "description": "Enable UMI-based read deduplication.", }, "umitools_extract_method": { "type": "string", "default": "string", "fa_icon": "fas fa-barcode", "description": "UMI pattern to use. Can be either 'string' (default) or 'regex'.", - "help_text": "More details can be found in the [UMI-tools documentation](https://umi-tools.readthedocs.io/en/latest/reference/extract.html#extract-method).\n" + "help_text": "More details can be found in the [UMI-tools documentation](https://umi-tools.readthedocs.io/en/latest/reference/extract.html#extract-method).\n", }, "skip_umi_extract": { "type": "boolean", "fa_icon": "fas fa-compress-alt", - "description": "Skip the UMI extraction from the read in case the UMIs have been moved to the headers in advance of the pipeline run." + "description": "Skip the UMI extraction from the read in case the UMIs have been moved to the headers in advance of the pipeline run.", }, "umitools_bc_pattern": { "type": "string", "fa_icon": "fas fa-barcode", "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." + "description": "The UMI barcode pattern to use e.g. 'NNNNNN' indicates that the first 6 nucleotides of the read are from the UMI.", }, "umitools_bc_pattern2": { "type": "string", "fa_icon": "fas fa-barcode", - "description": "The UMI barcode pattern to use if the UMI is located in read 2." + "description": "The UMI barcode pattern to use if the UMI is located in read 2.", }, "umi_discard_read": { "type": "integer", "fa_icon": "fas fa-barcode", - "description": "After UMI barcode extraction discard either R1 or R2 by setting this parameter to 1 or 2, respectively." + "description": "After UMI barcode extraction discard either R1 or R2 by setting this parameter to 1 or 2, respectively.", }, "umitools_umi_separator": { "type": "string", "fa_icon": "fas fa-star-half-alt", - "description": "The character that separates the UMI in the read name. Most likely a colon if you skipped the extraction with UMI-tools and used other software." + "description": "The character that separates the UMI in the read name. Most likely a colon if you skipped the extraction with UMI-tools and used other software.", }, "umitools_grouping_method": { "type": "string", "default": "directional", "fa_icon": "far fa-object-ungroup", "description": "Method to use to determine read groups by subsuming those with similar UMIs. All methods start by identifying the reads with the same mapping position, but treat similar yet nonidentical UMIs differently.", - "enum": ["unique", "percentile", "cluster", "adjacency", "directional"] + "enum": ["unique", "percentile", "cluster", "adjacency", "directional"], }, "umitools_dedup_stats": { "type": "boolean", "fa_icon": "fas fa-barcode", "help_text": "It can be quite time consuming generating these output stats - see [#827](https://github.com/nf-core/rnaseq/issues/827).", - "description": "Generate output stats when running \"umi_tools dedup\"." + "description": 'Generate output stats when running "umi_tools dedup".', }, "save_umi_intermeds": { "type": "boolean", "fa_icon": "fas fa-save", - "description": "If this option is specified, intermediate FastQ and BAM files produced by UMI-tools are also saved in the results directory." - } + "description": "If this option is specified, intermediate FastQ and BAM files produced by UMI-tools are also saved in the results directory.", + }, }, - "fa_icon": "fas fa-barcode" + "fa_icon": "fas fa-barcode", }, "read_filtering_options": { "title": "Read filtering options", @@ -122,45 +122,45 @@ "type": "string", "fa_icon": "fas fa-list-alt", "description": "Path to comma-separated file containing a list of reference genomes to filter reads against with BBSplit. You have to also explicitly set `--skip_bbsplit false` if you want to use BBSplit.", - "help_text": "The file should contain 2 columns: short name and full path to reference genome(s) e.g. \n```\nmm10,/path/to/mm10.fa\necoli,/path/to/ecoli.fa\n```" + "help_text": "The file should contain 2 columns: short name and full path to reference genome(s) e.g. \n```\nmm10,/path/to/mm10.fa\necoli,/path/to/ecoli.fa\n```", }, "bbsplit_index": { "type": "string", "fa_icon": "fas fa-bezier-curve", "description": "Path to directory or tar.gz archive for pre-built BBSplit index.", - "help_text": "The BBSplit index will have to be built at least once with this pipeline (see `--save_reference` to save index). It can then be provided via `--bbsplit_index` for future runs." + "help_text": "The BBSplit index will have to be built at least once with this pipeline (see `--save_reference` to save index). It can then be provided via `--bbsplit_index` for future runs.", }, "save_bbsplit_reads": { "type": "boolean", "fa_icon": "fas fa-save", - "description": "If this option is specified, FastQ files split by reference will be saved in the results directory." + "description": "If this option is specified, FastQ files split by reference will be saved in the results directory.", }, "skip_bbsplit": { "type": "boolean", "default": true, "fa_icon": "fas fa-fast-forward", - "description": "Skip BBSplit for removal of non-reference genome reads." + "description": "Skip BBSplit for removal of non-reference genome reads.", }, "remove_ribo_rna": { "type": "boolean", "fa_icon": "fas fa-trash-alt", "description": "Enable the removal of reads derived from ribosomal RNA using SortMeRNA.", - "help_text": "Any patterns found in the sequences defined by the '--ribo_database_manifest' parameter will be used." + "help_text": "Any patterns found in the sequences defined by the '--ribo_database_manifest' parameter will be used.", }, "ribo_database_manifest": { "type": "string", "default": "${projectDir}/assets/rrna-db-defaults.txt", "fa_icon": "fas fa-database", "description": "Text file containing paths to fasta files (one per line) that will be used to create the database for SortMeRNA.", - "help_text": "By default, [rRNA databases](https://github.com/biocore/sortmerna/tree/master/data/rRNA_databases) defined in the SortMeRNA GitHub repo are used. You can see an example in the pipeline Github repository in `assets/rrna-default-dbs.txt`.\nPlease note that commercial/non-academic entities require [`licensing for SILVA`](https://www.arb-silva.de/silva-license-information) for these default databases." + "help_text": "By default, [rRNA databases](https://github.com/biocore/sortmerna/tree/master/data/rRNA_databases) defined in the SortMeRNA GitHub repo are used. You can see an example in the pipeline Github repository in `assets/rrna-default-dbs.txt`.\nPlease note that commercial/non-academic entities require [`licensing for SILVA`](https://www.arb-silva.de/silva-license-information) for these default databases.", }, "save_non_ribo_reads": { "type": "boolean", "fa_icon": "fas fa-save", - "description": "If this option is specified, intermediate FastQ files containing non-rRNA reads will be saved in the results directory." - } + "description": "If this option is specified, intermediate FastQ files containing non-rRNA reads will be saved in the results directory.", + }, }, - "fa_icon": "fas fa-trash-alt" + "fa_icon": "fas fa-trash-alt", }, "reference_genome_options": { "title": "Reference genome options", @@ -172,7 +172,7 @@ "type": "string", "description": "Name of iGenomes reference.", "fa_icon": "fas fa-book", - "help_text": "If using a reference genome configured in the pipeline using iGenomes, use this parameter to give the ID for the reference. This is then used to build the full paths for all required reference genome files e.g. `--genome GRCh38`. \n\nSee the [nf-core website docs](https://nf-co.re/usage/reference_genomes) for more details." + "help_text": "If using a reference genome configured in the pipeline using iGenomes, use this parameter to give the ID for the reference. This is then used to build the full paths for all required reference genome files e.g. `--genome GRCh38`. \n\nSee the [nf-core website docs](https://nf-co.re/usage/reference_genomes) for more details.", }, "fasta": { "type": "string", @@ -181,7 +181,7 @@ "pattern": "^\\S+\\.fn?a(sta)?(\\.gz)?$", "description": "Path to FASTA genome file.", "help_text": "This parameter is *mandatory* if `--genome` is not specified. If you don't have the appropriate alignment index available this will be generated for you automatically. Combine with `--save_reference` to save alignment index for future runs.", - "fa_icon": "far fa-file-code" + "fa_icon": "far fa-file-code", }, "gtf": { "type": "string", @@ -190,7 +190,7 @@ "pattern": "^\\S+\\.gtf(\\.gz)?$", "description": "Path to GTF annotation file.", "fa_icon": "fas fa-code-branch", - "help_text": "This parameter is *mandatory* if `--genome` is not specified." + "help_text": "This parameter is *mandatory* if `--genome` is not specified.", }, "gff": { "type": "string", @@ -199,7 +199,7 @@ "pattern": "^\\S+\\.gff(\\.gz)?$", "fa_icon": "fas fa-code-branch", "description": "Path to GFF3 annotation file.", - "help_text": "This parameter must be specified if `--genome` or `--gtf` are not specified." + "help_text": "This parameter must be specified if `--genome` or `--gtf` are not specified.", }, "gene_bed": { "type": "string", @@ -207,7 +207,7 @@ "mimetype": "text/plain", "pattern": "^\\S+\\.bed(\\.gz)?$", "fa_icon": "fas fa-procedures", - "description": "Path to BED file containing gene intervals. This will be created from the GTF file if not specified." + "description": "Path to BED file containing gene intervals. This will be created from the GTF file if not specified.", }, "transcript_fasta": { "type": "string", @@ -215,7 +215,7 @@ "mimetype": "text/plain", "pattern": "^\\S+\\.fn?a(sta)?(\\.gz)?$", "fa_icon": "far fa-file-code", - "description": "Path to FASTA transcriptome file." + "description": "Path to FASTA transcriptome file.", }, "additional_fasta": { "type": "string", @@ -224,38 +224,38 @@ "pattern": "^\\S+\\.fn?a(sta)?(\\.gz)?$", "fa_icon": "far fa-file-code", "description": "FASTA file to concatenate to genome FASTA file e.g. containing spike-in sequences.", - "help_text": "If provided, the sequences in this file will get concatenated to the existing genome FASTA file, a GTF file will be automatically created using the entire sequence as the gene, transcript, and exon features, and any alignment index will get created from the combined FASTA and GTF. It is recommended to save the reference with `--save_reference` to re-use the index for future runs so you do not need to create it again." + "help_text": "If provided, the sequences in this file will get concatenated to the existing genome FASTA file, a GTF file will be automatically created using the entire sequence as the gene, transcript, and exon features, and any alignment index will get created from the combined FASTA and GTF. It is recommended to save the reference with `--save_reference` to re-use the index for future runs so you do not need to create it again.", }, "splicesites": { "type": "string", "format": "file-path", "mimetype": "text/plain", "fa_icon": "fas fa-hand-scissors", - "description": "Splice sites file required for HISAT2." + "description": "Splice sites file required for HISAT2.", }, "star_index": { "type": "string", "format": "path", "fa_icon": "fas fa-bezier-curve", - "description": "Path to directory or tar.gz archive for pre-built STAR index." + "description": "Path to directory or tar.gz archive for pre-built STAR index.", }, "hisat2_index": { "type": "string", "format": "path", "fa_icon": "fas fa-bezier-curve", - "description": "Path to directory or tar.gz archive for pre-built HISAT2 index." + "description": "Path to directory or tar.gz archive for pre-built HISAT2 index.", }, "rsem_index": { "type": "string", "format": "path", "fa_icon": "fas fa-bezier-curve", - "description": "Path to directory or tar.gz archive for pre-built RSEM index." + "description": "Path to directory or tar.gz archive for pre-built RSEM index.", }, "salmon_index": { "type": "string", "format": "path", "fa_icon": "fas fa-bezier-curve", - "description": "Path to directory or tar.gz archive for pre-built Salmon index." + "description": "Path to directory or tar.gz archive for pre-built Salmon index.", }, "hisat2_build_memory": { "type": "string", @@ -263,45 +263,45 @@ "fa_icon": "fas fa-memory", "pattern": "^\\d+(\\.\\d+)?\\.?\\s*(K|M|G|T)?B$", "description": "Minimum memory required to use splice sites and exons in the HiSAT2 index build process.", - "help_text": "HiSAT2 requires a huge amount of RAM to build a genome index for larger genomes, if including splice sites and exons e.g. the human genome might typically require 200GB. If you specify less than this threshold for the `HISAT2_BUILD` process then the splice sites and exons will be ignored, meaning that the process will require a lot less memory. If you are working with a small genome, set this parameter to a lower value to reduce the threshold for skipping this check. If using a larger genome, consider supplying more memory to the `HISAT2_BUILD` process." + "help_text": "HiSAT2 requires a huge amount of RAM to build a genome index for larger genomes, if including splice sites and exons e.g. the human genome might typically require 200GB. If you specify less than this threshold for the `HISAT2_BUILD` process then the splice sites and exons will be ignored, meaning that the process will require a lot less memory. If you are working with a small genome, set this parameter to a lower value to reduce the threshold for skipping this check. If using a larger genome, consider supplying more memory to the `HISAT2_BUILD` process.", }, "gencode": { "type": "boolean", "fa_icon": "fas fa-code-branch", "description": "Specify if your GTF annotation is in GENCODE format.", - "help_text": "If your GTF file is in GENCODE format and you would like to run Salmon i.e. `--pseudo_aligner salmon`, you will need to provide this parameter in order to build the Salmon index appropriately." + "help_text": "If your GTF file is in GENCODE format and you would like to run Salmon i.e. `--pseudo_aligner salmon`, you will need to provide this parameter in order to build the Salmon index appropriately.", }, "gtf_extra_attributes": { "type": "string", "default": "gene_name", "fa_icon": "fas fa-plus-square", "description": "By default, the pipeline uses the `gene_name` field to obtain additional gene identifiers from the input GTF file when running Salmon.", - "help_text": "This behaviour can be modified by specifying `--gtf_extra_attributes` when running the pipeline. Note that you can also specify more than one desired value, separated by a comma e.g. `--gtf_extra_attributes gene_id,...`.\n" + "help_text": "This behaviour can be modified by specifying `--gtf_extra_attributes` when running the pipeline. Note that you can also specify more than one desired value, separated by a comma e.g. `--gtf_extra_attributes gene_id,...`.\n", }, "gtf_group_features": { "type": "string", "default": "gene_id", "description": "Define the attribute type used to group features in the GTF file when running Salmon.", - "fa_icon": "fas fa-layer-group" + "fa_icon": "fas fa-layer-group", }, "featurecounts_group_type": { "type": "string", "default": "gene_biotype", "fa_icon": "fas fa-layer-group", - "description": "The attribute type used to group feature types in the GTF file when generating the biotype plot with featureCounts." + "description": "The attribute type used to group feature types in the GTF file when generating the biotype plot with featureCounts.", }, "featurecounts_feature_type": { "type": "string", "default": "exon", "description": "By default, the pipeline assigns reads based on the 'exon' attribute within the GTF file.", "fa_icon": "fas fa-indent", - "help_text": "The feature type used from the GTF file when generating the biotype plot with featureCounts." + "help_text": "The feature type used from the GTF file when generating the biotype plot with featureCounts.", }, "save_reference": { "type": "boolean", "description": "If generated by the pipeline save the STAR index in the results directory.", "help_text": "If an alignment index is generated by the pipeline use this parameter to save it to your results folder. These can then be used for future pipeline runs, reducing processing times.", - "fa_icon": "fas fa-save" + "fa_icon": "fas fa-save", }, "igenomes_base": { "type": "string", @@ -309,16 +309,16 @@ "description": "Directory / URL base for iGenomes references.", "default": "s3://ngi-igenomes/igenomes", "fa_icon": "fas fa-cloud-download-alt", - "hidden": true + "hidden": true, }, "igenomes_ignore": { "type": "boolean", "description": "Do not load the iGenomes reference config.", "fa_icon": "fas fa-ban", "hidden": true, - "help_text": "Do not load `igenomes.config` when running the pipeline. You may choose this option if you observe clashes between custom parameters and those supplied in `igenomes.config`." - } - } + "help_text": "Do not load `igenomes.config` when running the pipeline. You may choose this option if you observe clashes between custom parameters and those supplied in `igenomes.config`.", + }, + }, }, "read_trimming_options": { "title": "Read trimming options", @@ -329,48 +329,48 @@ "clip_r1": { "type": "integer", "description": "Instructs Trim Galore to remove bp from the 5' end of read 1 (or single-end reads).", - "fa_icon": "fas fa-cut" + "fa_icon": "fas fa-cut", }, "clip_r2": { "type": "integer", "description": "Instructs Trim Galore to remove bp from the 5' end of read 2 (paired-end reads only).", - "fa_icon": "fas fa-cut" + "fa_icon": "fas fa-cut", }, "three_prime_clip_r1": { "type": "integer", "description": "Instructs Trim Galore to remove bp from the 3' end of read 1 AFTER adapter/quality trimming has been performed.", - "fa_icon": "fas fa-cut" + "fa_icon": "fas fa-cut", }, "three_prime_clip_r2": { "type": "integer", "description": "Instructs Trim Galore to remove bp from the 3' end of read 2 AFTER adapter/quality trimming has been performed.", - "fa_icon": "fas fa-cut" + "fa_icon": "fas fa-cut", }, "trim_nextseq": { "type": "integer", "description": "Instructs Trim Galore to apply the --nextseq=X option, to trim based on quality after removing poly-G tails.", "help_text": "This enables the option Cutadapt `--nextseq-trim=3'CUTOFF` option via Trim Galore, which will set a quality cutoff (that is normally given with -q instead), but qualities of G bases are ignored. This trimming is in common for the NextSeq- and NovaSeq-platforms, where basecalls without any signal are called as high-quality G bases.", - "fa_icon": "fas fa-cut" + "fa_icon": "fas fa-cut", }, "min_trimmed_reads": { "type": "integer", "default": 10000, "fa_icon": "fas fa-hand-paper", - "description": "Minimum number of trimmed reads below which samples are removed from further processing. Some downstream steps in the pipeline will fail if this threshold is too low." + "description": "Minimum number of trimmed reads below which samples are removed from further processing. Some downstream steps in the pipeline will fail if this threshold is too low.", }, "skip_trimming": { "type": "boolean", "description": "Skip the adapter trimming step.", "help_text": "Use this if your input FastQ files have already been trimmed outside of the workflow or if you're very confident that there is no adapter contamination in your data.", - "fa_icon": "fas fa-fast-forward" + "fa_icon": "fas fa-fast-forward", }, "save_trimmed": { "type": "boolean", "description": "Save the trimmed FastQ files in the results directory.", "help_text": "By default, trimmed FastQ files will not be saved to the results directory. Specify this flag (or set to true in your config file) to copy these files to the results directory when complete.", - "fa_icon": "fas fa-save" - } - } + "fa_icon": "fas fa-save", + }, + }, }, "alignment_options": { "title": "Alignment options", @@ -383,80 +383,80 @@ "default": "star_salmon", "description": "Specifies the alignment algorithm to use - available options are 'star_salmon', 'star_rsem' and 'hisat2'.", "fa_icon": "fas fa-map-signs", - "enum": ["star_salmon", "star_rsem", "hisat2"] + "enum": ["star_salmon", "star_rsem", "hisat2"], }, "pseudo_aligner": { "type": "string", "description": "Specifies the pseudo aligner to use - available options are 'salmon'. Runs in addition to '--aligner'.", "fa_icon": "fas fa-hamburger", - "enum": ["salmon"] + "enum": ["salmon"], }, "bam_csi_index": { "type": "boolean", "description": "Create a CSI index for BAM files instead of the traditional BAI index. This will be required for genomes with larger chromosome sizes.", - "fa_icon": "fas fa-sort-alpha-down" + "fa_icon": "fas fa-sort-alpha-down", }, "star_ignore_sjdbgtf": { "type": "boolean", "fa_icon": "fas fa-ban", - "description": "When using pre-built STAR indices do not re-extract and use splice junctions from the GTF file." + "description": "When using pre-built STAR indices do not re-extract and use splice junctions from the GTF file.", }, "salmon_quant_libtype": { "type": "string", "fa_icon": "fas fa-fast-forward", "description": " Override Salmon library type inferred based on strandedness defined in meta object.", - "help_text": "See [Salmon docs](https://salmon.readthedocs.io/en/latest/library_type.html)." + "help_text": "See [Salmon docs](https://salmon.readthedocs.io/en/latest/library_type.html).", }, "min_mapped_reads": { "type": "number", "default": 5, "fa_icon": "fas fa-percentage", "description": "Minimum percentage of uniquely mapped reads below which samples are removed from further processing.", - "help_text": "Some downstream steps in the pipeline will fail if this threshold is too low." + "help_text": "Some downstream steps in the pipeline will fail if this threshold is too low.", }, "seq_center": { "type": "string", "description": "Sequencing center information to be added to read group of BAM files.", - "fa_icon": "fas fa-synagogue" + "fa_icon": "fas fa-synagogue", }, "stringtie_ignore_gtf": { "type": "boolean", "description": "Perform reference-guided de novo assembly of transcripts using StringTie i.e. dont restrict to those in GTF file.", - "fa_icon": "fas fa-ban" + "fa_icon": "fas fa-ban", }, "extra_star_align_args": { "type": "string", "description": "Extra arguments to pass to STAR alignment command in addition to defaults defined by the pipeline.", - "fa_icon": "fas fa-plus" + "fa_icon": "fas fa-plus", }, "extra_salmon_quant_args": { "type": "string", "description": "Extra arguments to pass to Salmon quant command in addition to defaults defined by the pipeline.", - "fa_icon": "fas fa-plus" + "fa_icon": "fas fa-plus", }, "save_unaligned": { "type": "boolean", "fa_icon": "fas fa-save", "description": "Where possible, save unaligned reads from either STAR, HISAT2 or Salmon to the results directory.", - "help_text": "This may either be in the form of FastQ or BAM files depending on the options available for that particular tool." + "help_text": "This may either be in the form of FastQ or BAM files depending on the options available for that particular tool.", }, "save_align_intermeds": { "type": "boolean", "description": "Save the intermediate BAM files from the alignment step.", "help_text": "By default, intermediate BAM files will not be saved. The final BAM files created after the appropriate filtering step are always saved to limit storage usage. Set this parameter to also save other intermediate BAM files.", - "fa_icon": "fas fa-save" + "fa_icon": "fas fa-save", }, "skip_markduplicates": { "type": "boolean", "fa_icon": "fas fa-fast-forward", - "description": "Skip picard MarkDuplicates step." + "description": "Skip picard MarkDuplicates step.", }, "skip_alignment": { "type": "boolean", "fa_icon": "fas fa-fast-forward", - "description": "Skip all of the alignment-based processes within the pipeline." - } - } + "description": "Skip all of the alignment-based processes within the pipeline.", + }, + }, }, "process_skipping_options": { "title": "Process skipping options", @@ -468,72 +468,52 @@ "type": "string", "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." + "description": "Specify the RSeQC modules to run.", }, "deseq2_vst": { "type": "boolean", "description": "Use vst transformation instead of rlog with DESeq2.", "help_text": "See [DESeq2 docs](http://bioconductor.org/packages/devel/bioc/vignettes/DESeq2/inst/doc/DESeq2.html#data-transformations-and-visualization).", "fa_icon": "fas fa-dolly", - "default": true + "default": true, }, "skip_bigwig": { "type": "boolean", "fa_icon": "fas fa-fast-forward", - "description": "Skip bigWig file creation." + "description": "Skip bigWig file creation.", }, "skip_stringtie": { "type": "boolean", "fa_icon": "fas fa-fast-forward", - "description": "Skip StringTie." - }, - "skip_fastqc": { - "type": "boolean", - "description": "Skip FastQC.", - "fa_icon": "fas fa-fast-forward" + "description": "Skip StringTie.", }, + "skip_fastqc": {"type": "boolean", "description": "Skip FastQC.", "fa_icon": "fas fa-fast-forward"}, "skip_preseq": { "type": "boolean", "description": "Skip Preseq.", "fa_icon": "fas fa-fast-forward", - "default": true - }, - "skip_dupradar": { - "type": "boolean", - "fa_icon": "fas fa-fast-forward", - "description": "Skip dupRadar." - }, - "skip_qualimap": { - "type": "boolean", - "fa_icon": "fas fa-fast-forward", - "description": "Skip Qualimap." - }, - "skip_rseqc": { - "type": "boolean", - "fa_icon": "fas fa-fast-forward", - "description": "Skip RSeQC." + "default": true, }, + "skip_dupradar": {"type": "boolean", "fa_icon": "fas fa-fast-forward", "description": "Skip dupRadar."}, + "skip_qualimap": {"type": "boolean", "fa_icon": "fas fa-fast-forward", "description": "Skip Qualimap."}, + "skip_rseqc": {"type": "boolean", "fa_icon": "fas fa-fast-forward", "description": "Skip RSeQC."}, "skip_biotype_qc": { "type": "boolean", "fa_icon": "fas fa-fast-forward", - "description": "Skip additional featureCounts process for biotype QC." + "description": "Skip additional featureCounts process for biotype QC.", }, "skip_deseq2_qc": { "type": "boolean", "fa_icon": "fas fa-fast-forward", - "description": "Skip DESeq2 PCA and heatmap plotting." - }, - "skip_multiqc": { - "type": "boolean", - "description": "Skip MultiQC.", - "fa_icon": "fas fa-fast-forward" + "description": "Skip DESeq2 PCA and heatmap plotting.", }, + "skip_multiqc": {"type": "boolean", "description": "Skip MultiQC.", "fa_icon": "fas fa-fast-forward"}, "skip_qc": { "type": "boolean", "fa_icon": "fas fa-fast-forward", - "description": "Skip all QC steps except for MultiQC." - } - } + "description": "Skip all QC steps except for MultiQC.", + }, + }, }, "institutional_config_options": { "title": "Institutional config options", @@ -547,7 +527,7 @@ "description": "Git commit id for Institutional configs.", "default": "master", "hidden": true, - "fa_icon": "fas fa-users-cog" + "fa_icon": "fas fa-users-cog", }, "custom_config_base": { "type": "string", @@ -555,25 +535,25 @@ "default": "https://raw.githubusercontent.com/nf-core/configs/master", "hidden": true, "help_text": "If you're running offline, Nextflow will not be able to fetch the institutional config files from the internet. If you don't need them, then this is not a problem. If you do need them, you should download the files from the repo and tell Nextflow where to find them with this parameter.", - "fa_icon": "fas fa-users-cog" + "fa_icon": "fas fa-users-cog", }, "config_profile_name": { "type": "string", "description": "Institutional config name.", "hidden": true, - "fa_icon": "fas fa-users-cog" + "fa_icon": "fas fa-users-cog", }, "config_profile_description": { "type": "string", "description": "Institutional config description.", "hidden": true, - "fa_icon": "fas fa-users-cog" + "fa_icon": "fas fa-users-cog", }, "config_profile_contact": { "type": "string", "description": "Institutional config contact information.", "hidden": true, - "fa_icon": "fas fa-users-cog" + "fa_icon": "fas fa-users-cog", }, "config_profile_url": { "type": "string", @@ -603,7 +583,7 @@ "default": 16, "fa_icon": "fas fa-microchip", "hidden": true, - "help_text": "Use to set an upper-limit for the CPU requirement for each process. Should be an integer e.g. `--max_cpus 1`" + "help_text": "Use to set an upper-limit for the CPU requirement for each process. Should be an integer e.g. `--max_cpus 1`", }, "max_memory": { "type": "string", @@ -612,7 +592,7 @@ "fa_icon": "fas fa-memory", "pattern": "^\\d+(\\.\\d+)?\\.?\\s*(K|M|G|T)?B$", "hidden": true, - "help_text": "Use to set an upper-limit for the memory requirement for each process. Should be a string in the format integer-unit e.g. `--max_memory '8.GB'`" + "help_text": "Use to set an upper-limit for the memory requirement for each process. Should be a string in the format integer-unit e.g. `--max_memory '8.GB'`", }, "max_time": { "type": "string", @@ -621,9 +601,9 @@ "fa_icon": "far fa-clock", "pattern": "^(\\d+\\.?\\s*(s|m|h|day)\\s*)+$", "hidden": true, - "help_text": "Use to set an upper-limit for the time requirement for each process. Should be a string in the format integer-unit e.g. `--max_time '2.h'`" - } - } + "help_text": "Use to set an upper-limit for the time requirement for each process. Should be a string in the format integer-unit e.g. `--max_time '2.h'`", + }, + }, }, "generic_options": { "title": "Generic options", @@ -636,13 +616,13 @@ "type": "boolean", "description": "Display help text.", "fa_icon": "fas fa-question-circle", - "hidden": true + "hidden": true, }, "version": { "type": "boolean", "description": "Display version and exit.", "fa_icon": "fas fa-question-circle", - "hidden": true + "hidden": true, }, "publish_dir_mode": { "type": "string", @@ -651,7 +631,7 @@ "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 + "hidden": true, }, "email_on_fail": { "type": "string", @@ -659,105 +639,85 @@ "fa_icon": "fas fa-exclamation-triangle", "pattern": "^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$", "help_text": "An email address to send a summary email to when the pipeline is completed - ONLY sent if the pipeline does not exit successfully.", - "hidden": true + "hidden": true, }, "plaintext_email": { "type": "boolean", "description": "Send plain-text email instead of HTML.", "fa_icon": "fas fa-remove-format", - "hidden": true + "hidden": true, }, "max_multiqc_email_size": { "type": "string", "description": "File size limit when attaching MultiQC reports to summary emails.", "default": "25.MB", "fa_icon": "fas fa-file-upload", - "hidden": true + "hidden": true, }, "monochrome_logs": { "type": "boolean", "description": "Do not use coloured log outputs.", "fa_icon": "fas fa-palette", - "hidden": true + "hidden": true, }, "hook_url": { "type": "string", "description": "Incoming hook URL for messaging service", "fa_icon": "fas fa-people-group", "help_text": "Incoming hook URL for messaging service. Currently, MS Teams and Slack are supported.", - "hidden": true + "hidden": true, }, "multiqc_config": { "type": "string", "description": "Custom config file to supply to MultiQC.", "fa_icon": "fas fa-cog", - "hidden": true + "hidden": true, }, "multiqc_logo": { "type": "string", "description": "Custom logo file to supply to MultiQC. File name must also be set in the MultiQC config file", "fa_icon": "fas fa-image", - "hidden": true + "hidden": true, }, "multiqc_methods_description": { "type": "string", "description": "Custom MultiQC yaml file containing HTML including a methods description.", - "fa_icon": "fas fa-cog" + "fa_icon": "fas fa-cog", }, "tracedir": { "type": "string", "description": "Directory to keep pipeline Nextflow logs and reports.", "default": "${params.outdir}/pipeline_info", "fa_icon": "fas fa-cogs", - "hidden": true + "hidden": true, }, "validate_params": { "type": "boolean", "description": "Boolean whether to validate parameters against the schema at runtime", "default": true, "fa_icon": "fas fa-check-square", - "hidden": true + "hidden": true, }, "show_hidden_params": { "type": "boolean", "fa_icon": "far fa-eye-slash", "description": "Show all params when using `--help`", "hidden": true, - "help_text": "By default, parameters set as _hidden_ in the schema are not shown on the command line when a user runs with `--help`. Specifying this option will tell the pipeline to show all parameters." - } - } - } + "help_text": "By default, parameters set as _hidden_ in the schema are not shown on the command line when a user runs with `--help`. Specifying this option will tell the pipeline to show all parameters.", + }, + }, + }, }, "allOf": [ - { - "$ref": "#/definitions/input_output_options" - }, - { - "$ref": "#/definitions/umi_options" - }, - { - "$ref": "#/definitions/read_filtering_options" - }, - { - "$ref": "#/definitions/reference_genome_options" - }, - { - "$ref": "#/definitions/read_trimming_options" - }, - { - "$ref": "#/definitions/alignment_options" - }, - { - "$ref": "#/definitions/process_skipping_options" - }, - { - "$ref": "#/definitions/institutional_config_options" - }, - { - "$ref": "#/definitions/max_job_request_options" - }, - { - "$ref": "#/definitions/generic_options" - } - ] + {"$ref": "#/definitions/input_output_options"}, + {"$ref": "#/definitions/umi_options"}, + {"$ref": "#/definitions/read_filtering_options"}, + {"$ref": "#/definitions/reference_genome_options"}, + {"$ref": "#/definitions/read_trimming_options"}, + {"$ref": "#/definitions/alignment_options"}, + {"$ref": "#/definitions/process_skipping_options"}, + {"$ref": "#/definitions/institutional_config_options"}, + {"$ref": "#/definitions/max_job_request_options"}, + {"$ref": "#/definitions/generic_options"}, + ], } From 3a833dcdfe7c2702d678d5a99225159c98b83f8b Mon Sep 17 00:00:00 2001 From: Matthias Zepper Date: Fri, 3 Feb 2023 14:12:51 +0100 Subject: [PATCH 019/124] Revert linting for JSON files. --- modules.json | 114 ++++++++-------- nextflow_schema.json | 300 ++++++++++++++++++++++++------------------- 2 files changed, 227 insertions(+), 187 deletions(-) diff --git a/modules.json b/modules.json index 38d19ec1d..0403e1f6a 100644 --- a/modules.json +++ b/modules.json @@ -8,143 +8,143 @@ "bbmap/bbsplit": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": ["modules"] }, "cat/fastq": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": ["modules"] }, "custom/dumpsoftwareversions": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": ["modules"] }, "custom/getchromsizes": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", "installed_by": ["modules"], - "patch": "modules/nf-core/custom/getchromsizes/custom-getchromsizes.diff", + "patch": "modules/nf-core/custom/getchromsizes/custom-getchromsizes.diff" }, "fastqc": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["fastq_fastqc_umitools_trimgalore"], + "installed_by": ["fastq_fastqc_umitools_trimgalore"] }, "fq/subsample": { "branch": "master", "git_sha": "ad462aa294faf9a8c42688a08daf81a580594f70", - "installed_by": ["modules", "fastq_subsample_fq_salmon"], + "installed_by": ["modules", "fastq_subsample_fq_salmon"] }, "gffread": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": ["modules"] }, "gunzip": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": ["modules"] }, "hisat2/align": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["fastq_align_hisat2"], + "installed_by": ["fastq_align_hisat2"] }, "hisat2/build": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": ["modules"] }, "hisat2/extractsplicesites": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": ["modules"] }, "picard/markduplicates": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_markduplicates_picard"], + "installed_by": ["bam_markduplicates_picard"] }, "preseq/lcextrap": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": ["modules"] }, "qualimap/rnaseq": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": ["modules"] }, "rsem/calculateexpression": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": ["modules"] }, "rsem/preparereference": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": ["modules"] }, "rseqc/bamstat": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_rseqc"], + "installed_by": ["bam_rseqc"] }, "rseqc/inferexperiment": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_rseqc"], + "installed_by": ["bam_rseqc"] }, "rseqc/innerdistance": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_rseqc"], + "installed_by": ["bam_rseqc"] }, "rseqc/junctionannotation": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_rseqc"], + "installed_by": ["bam_rseqc"] }, "rseqc/junctionsaturation": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_rseqc"], + "installed_by": ["bam_rseqc"] }, "rseqc/readdistribution": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_rseqc"], + "installed_by": ["bam_rseqc"] }, "rseqc/readduplication": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_rseqc"], + "installed_by": ["bam_rseqc"] }, "rseqc/tin": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_rseqc"], + "installed_by": ["bam_rseqc"] }, "salmon/index": { "branch": "master", "git_sha": "94b06f1683ddf893cf06525f6e7f0573ad8fbf83", - "installed_by": ["fastq_subsample_fq_salmon"], + "installed_by": ["fastq_subsample_fq_salmon"] }, "salmon/quant": { "branch": "master", "git_sha": "94b06f1683ddf893cf06525f6e7f0573ad8fbf83", - "installed_by": ["modules", "fastq_subsample_fq_salmon"], + "installed_by": ["modules", "fastq_subsample_fq_salmon"] }, "samtools/flagstat": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_stats_samtools"], + "installed_by": ["bam_stats_samtools"] }, "samtools/idxstats": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_stats_samtools"], + "installed_by": ["bam_stats_samtools"] }, "samtools/index": { "branch": "master", @@ -152,74 +152,74 @@ "installed_by": [ "bam_markduplicates_picard", "bam_sort_stats_samtools", - "bam_dedup_stats_samtools_umitools", - ], + "bam_dedup_stats_samtools_umitools" + ] }, "samtools/sort": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_sort_stats_samtools"], + "installed_by": ["bam_sort_stats_samtools"] }, "samtools/stats": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_stats_samtools"], + "installed_by": ["bam_stats_samtools"] }, "sortmerna": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": ["modules"] }, "star/align": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": ["modules"] }, "star/genomegenerate": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": ["modules"] }, "stringtie/stringtie": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": ["modules"] }, "subread/featurecounts": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": ["modules"] }, "trimgalore": { "branch": "master", "git_sha": "72ffbd7128015a1d4b65b95ff8d37be8fee2f981", - "installed_by": ["fastq_fastqc_umitools_trimgalore"], + "installed_by": ["fastq_fastqc_umitools_trimgalore"] }, "ucsc/bedclip": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bedgraph_bedclip_bedgraphtobigwig"], + "installed_by": ["bedgraph_bedclip_bedgraphtobigwig"] }, "ucsc/bedgraphtobigwig": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bedgraph_bedclip_bedgraphtobigwig"], + "installed_by": ["bedgraph_bedclip_bedgraphtobigwig"] }, "umitools/dedup": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["bam_dedup_stats_samtools_umitools"], + "installed_by": ["bam_dedup_stats_samtools_umitools"] }, "umitools/extract": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["fastq_fastqc_umitools_trimgalore"], + "installed_by": ["fastq_fastqc_umitools_trimgalore"] }, "untar": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], - }, + "installed_by": ["modules"] + } } }, "subworkflows": { @@ -227,22 +227,22 @@ "bam_dedup_stats_samtools_umitools": { "branch": "master", "git_sha": "41891ec2c3704911cd68b9317f26545b95a1c48d", - "installed_by": ["subworkflows"], + "installed_by": ["subworkflows"] }, "bam_markduplicates_picard": { "branch": "master", "git_sha": "6daac2bc63f4847e0c7cc661f4f5b043ac13faaf", - "installed_by": ["subworkflows"], + "installed_by": ["subworkflows"] }, "bam_rseqc": { "branch": "master", "git_sha": "36a77f7c6decf2d1fb9f639ae982bc148d6828aa", - "installed_by": ["subworkflows"], + "installed_by": ["subworkflows"] }, "bam_sort_stats_samtools": { "branch": "master", "git_sha": "3911652a6b24249358f79e8b8466338d63efb2a2", - "installed_by": ["fastq_align_hisat2"], + "installed_by": ["fastq_align_hisat2"] }, "bam_stats_samtools": { "branch": "master", @@ -250,31 +250,31 @@ "installed_by": [ "bam_sort_stats_samtools", "bam_dedup_stats_samtools_umitools", - "bam_markduplicates_picard", - ], + "bam_markduplicates_picard" + ] }, "bedgraph_bedclip_bedgraphtobigwig": { "branch": "master", "git_sha": "b81a313d8fac0a82a8a4ff0de80590b2f97f11ad", - "installed_by": ["subworkflows"], + "installed_by": ["subworkflows"] }, "fastq_align_hisat2": { "branch": "master", "git_sha": "9057e75e8ac959373a72a9402130fdea2e2d1398", - "installed_by": ["subworkflows"], + "installed_by": ["subworkflows"] }, "fastq_fastqc_umitools_trimgalore": { "branch": "master", "git_sha": "72ffbd7128015a1d4b65b95ff8d37be8fee2f981", - "installed_by": ["subworkflows"], + "installed_by": ["subworkflows"] }, "fastq_subsample_fq_salmon": { "branch": "master", "git_sha": "82d60046b4519e9dbef4a934371a53fa7666eabc", - "installed_by": ["subworkflows"], - }, + "installed_by": ["subworkflows"] + } } - }, + } } - }, + } } diff --git a/nextflow_schema.json b/nextflow_schema.json index ccdcc8f05..de2c57ce7 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -20,32 +20,32 @@ "schema": "assets/schema_input.json", "description": "Path to comma-separated file containing information about the samples in the experiment.", "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 4 columns, and a header row. See [usage docs](https://nf-co.re/rnaseq/usage#samplesheet-input).", - "fa_icon": "fas fa-file-csv", + "fa_icon": "fas fa-file-csv" }, "outdir": { "type": "string", "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", + "fa_icon": "fas fa-folder-open" }, "email": { "type": "string", "description": "Email address for completion summary.", "fa_icon": "fas fa-envelope", "help_text": "Set this parameter to your e-mail address to get a summary e-mail with details of the run sent to you when the workflow exits. If set in your user config file (`~/.nextflow/config`) then you don't need to specify this on the command line for every run.", - "pattern": "^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$", + "pattern": "^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$" }, "multiqc_title": { "type": "string", "description": "MultiQC report title. Printed as page header, used for filename if not otherwise specified.", - "fa_icon": "fas fa-file-signature", + "fa_icon": "fas fa-file-signature" }, "save_merged_fastq": { "type": "boolean", "fa_icon": "fas fa-save", - "description": "Save FastQ files after merging re-sequenced libraries in the results directory.", - }, - }, + "description": "Save FastQ files after merging re-sequenced libraries in the results directory." + } + } }, "umi_options": { "title": "UMI options", @@ -56,61 +56,61 @@ "with_umi": { "type": "boolean", "fa_icon": "fas fa-barcode", - "description": "Enable UMI-based read deduplication.", + "description": "Enable UMI-based read deduplication." }, "umitools_extract_method": { "type": "string", "default": "string", "fa_icon": "fas fa-barcode", "description": "UMI pattern to use. Can be either 'string' (default) or 'regex'.", - "help_text": "More details can be found in the [UMI-tools documentation](https://umi-tools.readthedocs.io/en/latest/reference/extract.html#extract-method).\n", + "help_text": "More details can be found in the [UMI-tools documentation](https://umi-tools.readthedocs.io/en/latest/reference/extract.html#extract-method).\n" }, "skip_umi_extract": { "type": "boolean", "fa_icon": "fas fa-compress-alt", - "description": "Skip the UMI extraction from the read in case the UMIs have been moved to the headers in advance of the pipeline run.", + "description": "Skip the UMI extraction from the read in case the UMIs have been moved to the headers in advance of the pipeline run." }, "umitools_bc_pattern": { "type": "string", "fa_icon": "fas fa-barcode", "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.", + "description": "The UMI barcode pattern to use e.g. 'NNNNNN' indicates that the first 6 nucleotides of the read are from the UMI." }, "umitools_bc_pattern2": { "type": "string", "fa_icon": "fas fa-barcode", - "description": "The UMI barcode pattern to use if the UMI is located in read 2.", + "description": "The UMI barcode pattern to use if the UMI is located in read 2." }, "umi_discard_read": { "type": "integer", "fa_icon": "fas fa-barcode", - "description": "After UMI barcode extraction discard either R1 or R2 by setting this parameter to 1 or 2, respectively.", + "description": "After UMI barcode extraction discard either R1 or R2 by setting this parameter to 1 or 2, respectively." }, "umitools_umi_separator": { "type": "string", "fa_icon": "fas fa-star-half-alt", - "description": "The character that separates the UMI in the read name. Most likely a colon if you skipped the extraction with UMI-tools and used other software.", + "description": "The character that separates the UMI in the read name. Most likely a colon if you skipped the extraction with UMI-tools and used other software." }, "umitools_grouping_method": { "type": "string", "default": "directional", "fa_icon": "far fa-object-ungroup", "description": "Method to use to determine read groups by subsuming those with similar UMIs. All methods start by identifying the reads with the same mapping position, but treat similar yet nonidentical UMIs differently.", - "enum": ["unique", "percentile", "cluster", "adjacency", "directional"], + "enum": ["unique", "percentile", "cluster", "adjacency", "directional"] }, "umitools_dedup_stats": { "type": "boolean", "fa_icon": "fas fa-barcode", "help_text": "It can be quite time consuming generating these output stats - see [#827](https://github.com/nf-core/rnaseq/issues/827).", - "description": 'Generate output stats when running "umi_tools dedup".', + "description": "Generate output stats when running \"umi_tools dedup\"." }, "save_umi_intermeds": { "type": "boolean", "fa_icon": "fas fa-save", - "description": "If this option is specified, intermediate FastQ and BAM files produced by UMI-tools are also saved in the results directory.", - }, + "description": "If this option is specified, intermediate FastQ and BAM files produced by UMI-tools are also saved in the results directory." + } }, - "fa_icon": "fas fa-barcode", + "fa_icon": "fas fa-barcode" }, "read_filtering_options": { "title": "Read filtering options", @@ -122,45 +122,45 @@ "type": "string", "fa_icon": "fas fa-list-alt", "description": "Path to comma-separated file containing a list of reference genomes to filter reads against with BBSplit. You have to also explicitly set `--skip_bbsplit false` if you want to use BBSplit.", - "help_text": "The file should contain 2 columns: short name and full path to reference genome(s) e.g. \n```\nmm10,/path/to/mm10.fa\necoli,/path/to/ecoli.fa\n```", + "help_text": "The file should contain 2 columns: short name and full path to reference genome(s) e.g. \n```\nmm10,/path/to/mm10.fa\necoli,/path/to/ecoli.fa\n```" }, "bbsplit_index": { "type": "string", "fa_icon": "fas fa-bezier-curve", "description": "Path to directory or tar.gz archive for pre-built BBSplit index.", - "help_text": "The BBSplit index will have to be built at least once with this pipeline (see `--save_reference` to save index). It can then be provided via `--bbsplit_index` for future runs.", + "help_text": "The BBSplit index will have to be built at least once with this pipeline (see `--save_reference` to save index). It can then be provided via `--bbsplit_index` for future runs." }, "save_bbsplit_reads": { "type": "boolean", "fa_icon": "fas fa-save", - "description": "If this option is specified, FastQ files split by reference will be saved in the results directory.", + "description": "If this option is specified, FastQ files split by reference will be saved in the results directory." }, "skip_bbsplit": { "type": "boolean", "default": true, "fa_icon": "fas fa-fast-forward", - "description": "Skip BBSplit for removal of non-reference genome reads.", + "description": "Skip BBSplit for removal of non-reference genome reads." }, "remove_ribo_rna": { "type": "boolean", "fa_icon": "fas fa-trash-alt", "description": "Enable the removal of reads derived from ribosomal RNA using SortMeRNA.", - "help_text": "Any patterns found in the sequences defined by the '--ribo_database_manifest' parameter will be used.", + "help_text": "Any patterns found in the sequences defined by the '--ribo_database_manifest' parameter will be used." }, "ribo_database_manifest": { "type": "string", "default": "${projectDir}/assets/rrna-db-defaults.txt", "fa_icon": "fas fa-database", "description": "Text file containing paths to fasta files (one per line) that will be used to create the database for SortMeRNA.", - "help_text": "By default, [rRNA databases](https://github.com/biocore/sortmerna/tree/master/data/rRNA_databases) defined in the SortMeRNA GitHub repo are used. You can see an example in the pipeline Github repository in `assets/rrna-default-dbs.txt`.\nPlease note that commercial/non-academic entities require [`licensing for SILVA`](https://www.arb-silva.de/silva-license-information) for these default databases.", + "help_text": "By default, [rRNA databases](https://github.com/biocore/sortmerna/tree/master/data/rRNA_databases) defined in the SortMeRNA GitHub repo are used. You can see an example in the pipeline Github repository in `assets/rrna-default-dbs.txt`.\nPlease note that commercial/non-academic entities require [`licensing for SILVA`](https://www.arb-silva.de/silva-license-information) for these default databases." }, "save_non_ribo_reads": { "type": "boolean", "fa_icon": "fas fa-save", - "description": "If this option is specified, intermediate FastQ files containing non-rRNA reads will be saved in the results directory.", - }, + "description": "If this option is specified, intermediate FastQ files containing non-rRNA reads will be saved in the results directory." + } }, - "fa_icon": "fas fa-trash-alt", + "fa_icon": "fas fa-trash-alt" }, "reference_genome_options": { "title": "Reference genome options", @@ -172,7 +172,7 @@ "type": "string", "description": "Name of iGenomes reference.", "fa_icon": "fas fa-book", - "help_text": "If using a reference genome configured in the pipeline using iGenomes, use this parameter to give the ID for the reference. This is then used to build the full paths for all required reference genome files e.g. `--genome GRCh38`. \n\nSee the [nf-core website docs](https://nf-co.re/usage/reference_genomes) for more details.", + "help_text": "If using a reference genome configured in the pipeline using iGenomes, use this parameter to give the ID for the reference. This is then used to build the full paths for all required reference genome files e.g. `--genome GRCh38`. \n\nSee the [nf-core website docs](https://nf-co.re/usage/reference_genomes) for more details." }, "fasta": { "type": "string", @@ -181,7 +181,7 @@ "pattern": "^\\S+\\.fn?a(sta)?(\\.gz)?$", "description": "Path to FASTA genome file.", "help_text": "This parameter is *mandatory* if `--genome` is not specified. If you don't have the appropriate alignment index available this will be generated for you automatically. Combine with `--save_reference` to save alignment index for future runs.", - "fa_icon": "far fa-file-code", + "fa_icon": "far fa-file-code" }, "gtf": { "type": "string", @@ -190,7 +190,7 @@ "pattern": "^\\S+\\.gtf(\\.gz)?$", "description": "Path to GTF annotation file.", "fa_icon": "fas fa-code-branch", - "help_text": "This parameter is *mandatory* if `--genome` is not specified.", + "help_text": "This parameter is *mandatory* if `--genome` is not specified." }, "gff": { "type": "string", @@ -199,7 +199,7 @@ "pattern": "^\\S+\\.gff(\\.gz)?$", "fa_icon": "fas fa-code-branch", "description": "Path to GFF3 annotation file.", - "help_text": "This parameter must be specified if `--genome` or `--gtf` are not specified.", + "help_text": "This parameter must be specified if `--genome` or `--gtf` are not specified." }, "gene_bed": { "type": "string", @@ -207,7 +207,7 @@ "mimetype": "text/plain", "pattern": "^\\S+\\.bed(\\.gz)?$", "fa_icon": "fas fa-procedures", - "description": "Path to BED file containing gene intervals. This will be created from the GTF file if not specified.", + "description": "Path to BED file containing gene intervals. This will be created from the GTF file if not specified." }, "transcript_fasta": { "type": "string", @@ -215,7 +215,7 @@ "mimetype": "text/plain", "pattern": "^\\S+\\.fn?a(sta)?(\\.gz)?$", "fa_icon": "far fa-file-code", - "description": "Path to FASTA transcriptome file.", + "description": "Path to FASTA transcriptome file." }, "additional_fasta": { "type": "string", @@ -224,38 +224,38 @@ "pattern": "^\\S+\\.fn?a(sta)?(\\.gz)?$", "fa_icon": "far fa-file-code", "description": "FASTA file to concatenate to genome FASTA file e.g. containing spike-in sequences.", - "help_text": "If provided, the sequences in this file will get concatenated to the existing genome FASTA file, a GTF file will be automatically created using the entire sequence as the gene, transcript, and exon features, and any alignment index will get created from the combined FASTA and GTF. It is recommended to save the reference with `--save_reference` to re-use the index for future runs so you do not need to create it again.", + "help_text": "If provided, the sequences in this file will get concatenated to the existing genome FASTA file, a GTF file will be automatically created using the entire sequence as the gene, transcript, and exon features, and any alignment index will get created from the combined FASTA and GTF. It is recommended to save the reference with `--save_reference` to re-use the index for future runs so you do not need to create it again." }, "splicesites": { "type": "string", "format": "file-path", "mimetype": "text/plain", "fa_icon": "fas fa-hand-scissors", - "description": "Splice sites file required for HISAT2.", + "description": "Splice sites file required for HISAT2." }, "star_index": { "type": "string", "format": "path", "fa_icon": "fas fa-bezier-curve", - "description": "Path to directory or tar.gz archive for pre-built STAR index.", + "description": "Path to directory or tar.gz archive for pre-built STAR index." }, "hisat2_index": { "type": "string", "format": "path", "fa_icon": "fas fa-bezier-curve", - "description": "Path to directory or tar.gz archive for pre-built HISAT2 index.", + "description": "Path to directory or tar.gz archive for pre-built HISAT2 index." }, "rsem_index": { "type": "string", "format": "path", "fa_icon": "fas fa-bezier-curve", - "description": "Path to directory or tar.gz archive for pre-built RSEM index.", + "description": "Path to directory or tar.gz archive for pre-built RSEM index." }, "salmon_index": { "type": "string", "format": "path", "fa_icon": "fas fa-bezier-curve", - "description": "Path to directory or tar.gz archive for pre-built Salmon index.", + "description": "Path to directory or tar.gz archive for pre-built Salmon index." }, "hisat2_build_memory": { "type": "string", @@ -263,45 +263,45 @@ "fa_icon": "fas fa-memory", "pattern": "^\\d+(\\.\\d+)?\\.?\\s*(K|M|G|T)?B$", "description": "Minimum memory required to use splice sites and exons in the HiSAT2 index build process.", - "help_text": "HiSAT2 requires a huge amount of RAM to build a genome index for larger genomes, if including splice sites and exons e.g. the human genome might typically require 200GB. If you specify less than this threshold for the `HISAT2_BUILD` process then the splice sites and exons will be ignored, meaning that the process will require a lot less memory. If you are working with a small genome, set this parameter to a lower value to reduce the threshold for skipping this check. If using a larger genome, consider supplying more memory to the `HISAT2_BUILD` process.", + "help_text": "HiSAT2 requires a huge amount of RAM to build a genome index for larger genomes, if including splice sites and exons e.g. the human genome might typically require 200GB. If you specify less than this threshold for the `HISAT2_BUILD` process then the splice sites and exons will be ignored, meaning that the process will require a lot less memory. If you are working with a small genome, set this parameter to a lower value to reduce the threshold for skipping this check. If using a larger genome, consider supplying more memory to the `HISAT2_BUILD` process." }, "gencode": { "type": "boolean", "fa_icon": "fas fa-code-branch", "description": "Specify if your GTF annotation is in GENCODE format.", - "help_text": "If your GTF file is in GENCODE format and you would like to run Salmon i.e. `--pseudo_aligner salmon`, you will need to provide this parameter in order to build the Salmon index appropriately.", + "help_text": "If your GTF file is in GENCODE format and you would like to run Salmon i.e. `--pseudo_aligner salmon`, you will need to provide this parameter in order to build the Salmon index appropriately." }, "gtf_extra_attributes": { "type": "string", "default": "gene_name", "fa_icon": "fas fa-plus-square", "description": "By default, the pipeline uses the `gene_name` field to obtain additional gene identifiers from the input GTF file when running Salmon.", - "help_text": "This behaviour can be modified by specifying `--gtf_extra_attributes` when running the pipeline. Note that you can also specify more than one desired value, separated by a comma e.g. `--gtf_extra_attributes gene_id,...`.\n", + "help_text": "This behaviour can be modified by specifying `--gtf_extra_attributes` when running the pipeline. Note that you can also specify more than one desired value, separated by a comma e.g. `--gtf_extra_attributes gene_id,...`.\n" }, "gtf_group_features": { "type": "string", "default": "gene_id", "description": "Define the attribute type used to group features in the GTF file when running Salmon.", - "fa_icon": "fas fa-layer-group", + "fa_icon": "fas fa-layer-group" }, "featurecounts_group_type": { "type": "string", "default": "gene_biotype", "fa_icon": "fas fa-layer-group", - "description": "The attribute type used to group feature types in the GTF file when generating the biotype plot with featureCounts.", + "description": "The attribute type used to group feature types in the GTF file when generating the biotype plot with featureCounts." }, "featurecounts_feature_type": { "type": "string", "default": "exon", "description": "By default, the pipeline assigns reads based on the 'exon' attribute within the GTF file.", "fa_icon": "fas fa-indent", - "help_text": "The feature type used from the GTF file when generating the biotype plot with featureCounts.", + "help_text": "The feature type used from the GTF file when generating the biotype plot with featureCounts." }, "save_reference": { "type": "boolean", "description": "If generated by the pipeline save the STAR index in the results directory.", "help_text": "If an alignment index is generated by the pipeline use this parameter to save it to your results folder. These can then be used for future pipeline runs, reducing processing times.", - "fa_icon": "fas fa-save", + "fa_icon": "fas fa-save" }, "igenomes_base": { "type": "string", @@ -309,16 +309,16 @@ "description": "Directory / URL base for iGenomes references.", "default": "s3://ngi-igenomes/igenomes", "fa_icon": "fas fa-cloud-download-alt", - "hidden": true, + "hidden": true }, "igenomes_ignore": { "type": "boolean", "description": "Do not load the iGenomes reference config.", "fa_icon": "fas fa-ban", "hidden": true, - "help_text": "Do not load `igenomes.config` when running the pipeline. You may choose this option if you observe clashes between custom parameters and those supplied in `igenomes.config`.", - }, - }, + "help_text": "Do not load `igenomes.config` when running the pipeline. You may choose this option if you observe clashes between custom parameters and those supplied in `igenomes.config`." + } + } }, "read_trimming_options": { "title": "Read trimming options", @@ -329,48 +329,48 @@ "clip_r1": { "type": "integer", "description": "Instructs Trim Galore to remove bp from the 5' end of read 1 (or single-end reads).", - "fa_icon": "fas fa-cut", + "fa_icon": "fas fa-cut" }, "clip_r2": { "type": "integer", "description": "Instructs Trim Galore to remove bp from the 5' end of read 2 (paired-end reads only).", - "fa_icon": "fas fa-cut", + "fa_icon": "fas fa-cut" }, "three_prime_clip_r1": { "type": "integer", "description": "Instructs Trim Galore to remove bp from the 3' end of read 1 AFTER adapter/quality trimming has been performed.", - "fa_icon": "fas fa-cut", + "fa_icon": "fas fa-cut" }, "three_prime_clip_r2": { "type": "integer", "description": "Instructs Trim Galore to remove bp from the 3' end of read 2 AFTER adapter/quality trimming has been performed.", - "fa_icon": "fas fa-cut", + "fa_icon": "fas fa-cut" }, "trim_nextseq": { "type": "integer", "description": "Instructs Trim Galore to apply the --nextseq=X option, to trim based on quality after removing poly-G tails.", "help_text": "This enables the option Cutadapt `--nextseq-trim=3'CUTOFF` option via Trim Galore, which will set a quality cutoff (that is normally given with -q instead), but qualities of G bases are ignored. This trimming is in common for the NextSeq- and NovaSeq-platforms, where basecalls without any signal are called as high-quality G bases.", - "fa_icon": "fas fa-cut", + "fa_icon": "fas fa-cut" }, "min_trimmed_reads": { "type": "integer", "default": 10000, "fa_icon": "fas fa-hand-paper", - "description": "Minimum number of trimmed reads below which samples are removed from further processing. Some downstream steps in the pipeline will fail if this threshold is too low.", + "description": "Minimum number of trimmed reads below which samples are removed from further processing. Some downstream steps in the pipeline will fail if this threshold is too low." }, "skip_trimming": { "type": "boolean", "description": "Skip the adapter trimming step.", "help_text": "Use this if your input FastQ files have already been trimmed outside of the workflow or if you're very confident that there is no adapter contamination in your data.", - "fa_icon": "fas fa-fast-forward", + "fa_icon": "fas fa-fast-forward" }, "save_trimmed": { "type": "boolean", "description": "Save the trimmed FastQ files in the results directory.", "help_text": "By default, trimmed FastQ files will not be saved to the results directory. Specify this flag (or set to true in your config file) to copy these files to the results directory when complete.", - "fa_icon": "fas fa-save", - }, - }, + "fa_icon": "fas fa-save" + } + } }, "alignment_options": { "title": "Alignment options", @@ -383,80 +383,80 @@ "default": "star_salmon", "description": "Specifies the alignment algorithm to use - available options are 'star_salmon', 'star_rsem' and 'hisat2'.", "fa_icon": "fas fa-map-signs", - "enum": ["star_salmon", "star_rsem", "hisat2"], + "enum": ["star_salmon", "star_rsem", "hisat2"] }, "pseudo_aligner": { "type": "string", "description": "Specifies the pseudo aligner to use - available options are 'salmon'. Runs in addition to '--aligner'.", "fa_icon": "fas fa-hamburger", - "enum": ["salmon"], + "enum": ["salmon"] }, "bam_csi_index": { "type": "boolean", "description": "Create a CSI index for BAM files instead of the traditional BAI index. This will be required for genomes with larger chromosome sizes.", - "fa_icon": "fas fa-sort-alpha-down", + "fa_icon": "fas fa-sort-alpha-down" }, "star_ignore_sjdbgtf": { "type": "boolean", "fa_icon": "fas fa-ban", - "description": "When using pre-built STAR indices do not re-extract and use splice junctions from the GTF file.", + "description": "When using pre-built STAR indices do not re-extract and use splice junctions from the GTF file." }, "salmon_quant_libtype": { "type": "string", "fa_icon": "fas fa-fast-forward", "description": " Override Salmon library type inferred based on strandedness defined in meta object.", - "help_text": "See [Salmon docs](https://salmon.readthedocs.io/en/latest/library_type.html).", + "help_text": "See [Salmon docs](https://salmon.readthedocs.io/en/latest/library_type.html)." }, "min_mapped_reads": { "type": "number", "default": 5, "fa_icon": "fas fa-percentage", "description": "Minimum percentage of uniquely mapped reads below which samples are removed from further processing.", - "help_text": "Some downstream steps in the pipeline will fail if this threshold is too low.", + "help_text": "Some downstream steps in the pipeline will fail if this threshold is too low." }, "seq_center": { "type": "string", "description": "Sequencing center information to be added to read group of BAM files.", - "fa_icon": "fas fa-synagogue", + "fa_icon": "fas fa-synagogue" }, "stringtie_ignore_gtf": { "type": "boolean", "description": "Perform reference-guided de novo assembly of transcripts using StringTie i.e. dont restrict to those in GTF file.", - "fa_icon": "fas fa-ban", + "fa_icon": "fas fa-ban" }, "extra_star_align_args": { "type": "string", "description": "Extra arguments to pass to STAR alignment command in addition to defaults defined by the pipeline.", - "fa_icon": "fas fa-plus", + "fa_icon": "fas fa-plus" }, "extra_salmon_quant_args": { "type": "string", "description": "Extra arguments to pass to Salmon quant command in addition to defaults defined by the pipeline.", - "fa_icon": "fas fa-plus", + "fa_icon": "fas fa-plus" }, "save_unaligned": { "type": "boolean", "fa_icon": "fas fa-save", "description": "Where possible, save unaligned reads from either STAR, HISAT2 or Salmon to the results directory.", - "help_text": "This may either be in the form of FastQ or BAM files depending on the options available for that particular tool.", + "help_text": "This may either be in the form of FastQ or BAM files depending on the options available for that particular tool." }, "save_align_intermeds": { "type": "boolean", "description": "Save the intermediate BAM files from the alignment step.", "help_text": "By default, intermediate BAM files will not be saved. The final BAM files created after the appropriate filtering step are always saved to limit storage usage. Set this parameter to also save other intermediate BAM files.", - "fa_icon": "fas fa-save", + "fa_icon": "fas fa-save" }, "skip_markduplicates": { "type": "boolean", "fa_icon": "fas fa-fast-forward", - "description": "Skip picard MarkDuplicates step.", + "description": "Skip picard MarkDuplicates step." }, "skip_alignment": { "type": "boolean", "fa_icon": "fas fa-fast-forward", - "description": "Skip all of the alignment-based processes within the pipeline.", - }, - }, + "description": "Skip all of the alignment-based processes within the pipeline." + } + } }, "process_skipping_options": { "title": "Process skipping options", @@ -468,52 +468,72 @@ "type": "string", "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.", + "description": "Specify the RSeQC modules to run." }, "deseq2_vst": { "type": "boolean", "description": "Use vst transformation instead of rlog with DESeq2.", "help_text": "See [DESeq2 docs](http://bioconductor.org/packages/devel/bioc/vignettes/DESeq2/inst/doc/DESeq2.html#data-transformations-and-visualization).", "fa_icon": "fas fa-dolly", - "default": true, + "default": true }, "skip_bigwig": { "type": "boolean", "fa_icon": "fas fa-fast-forward", - "description": "Skip bigWig file creation.", + "description": "Skip bigWig file creation." }, "skip_stringtie": { "type": "boolean", "fa_icon": "fas fa-fast-forward", - "description": "Skip StringTie.", + "description": "Skip StringTie." + }, + "skip_fastqc": { + "type": "boolean", + "description": "Skip FastQC.", + "fa_icon": "fas fa-fast-forward" }, - "skip_fastqc": {"type": "boolean", "description": "Skip FastQC.", "fa_icon": "fas fa-fast-forward"}, "skip_preseq": { "type": "boolean", "description": "Skip Preseq.", "fa_icon": "fas fa-fast-forward", - "default": true, + "default": true + }, + "skip_dupradar": { + "type": "boolean", + "fa_icon": "fas fa-fast-forward", + "description": "Skip dupRadar." + }, + "skip_qualimap": { + "type": "boolean", + "fa_icon": "fas fa-fast-forward", + "description": "Skip Qualimap." + }, + "skip_rseqc": { + "type": "boolean", + "fa_icon": "fas fa-fast-forward", + "description": "Skip RSeQC." }, - "skip_dupradar": {"type": "boolean", "fa_icon": "fas fa-fast-forward", "description": "Skip dupRadar."}, - "skip_qualimap": {"type": "boolean", "fa_icon": "fas fa-fast-forward", "description": "Skip Qualimap."}, - "skip_rseqc": {"type": "boolean", "fa_icon": "fas fa-fast-forward", "description": "Skip RSeQC."}, "skip_biotype_qc": { "type": "boolean", "fa_icon": "fas fa-fast-forward", - "description": "Skip additional featureCounts process for biotype QC.", + "description": "Skip additional featureCounts process for biotype QC." }, "skip_deseq2_qc": { "type": "boolean", "fa_icon": "fas fa-fast-forward", - "description": "Skip DESeq2 PCA and heatmap plotting.", + "description": "Skip DESeq2 PCA and heatmap plotting." + }, + "skip_multiqc": { + "type": "boolean", + "description": "Skip MultiQC.", + "fa_icon": "fas fa-fast-forward" }, - "skip_multiqc": {"type": "boolean", "description": "Skip MultiQC.", "fa_icon": "fas fa-fast-forward"}, "skip_qc": { "type": "boolean", "fa_icon": "fas fa-fast-forward", - "description": "Skip all QC steps except for MultiQC.", - }, - }, + "description": "Skip all QC steps except for MultiQC." + } + } }, "institutional_config_options": { "title": "Institutional config options", @@ -527,7 +547,7 @@ "description": "Git commit id for Institutional configs.", "default": "master", "hidden": true, - "fa_icon": "fas fa-users-cog", + "fa_icon": "fas fa-users-cog" }, "custom_config_base": { "type": "string", @@ -535,25 +555,25 @@ "default": "https://raw.githubusercontent.com/nf-core/configs/master", "hidden": true, "help_text": "If you're running offline, Nextflow will not be able to fetch the institutional config files from the internet. If you don't need them, then this is not a problem. If you do need them, you should download the files from the repo and tell Nextflow where to find them with this parameter.", - "fa_icon": "fas fa-users-cog", + "fa_icon": "fas fa-users-cog" }, "config_profile_name": { "type": "string", "description": "Institutional config name.", "hidden": true, - "fa_icon": "fas fa-users-cog", + "fa_icon": "fas fa-users-cog" }, "config_profile_description": { "type": "string", "description": "Institutional config description.", "hidden": true, - "fa_icon": "fas fa-users-cog", + "fa_icon": "fas fa-users-cog" }, "config_profile_contact": { "type": "string", "description": "Institutional config contact information.", "hidden": true, - "fa_icon": "fas fa-users-cog", + "fa_icon": "fas fa-users-cog" }, "config_profile_url": { "type": "string", @@ -583,7 +603,7 @@ "default": 16, "fa_icon": "fas fa-microchip", "hidden": true, - "help_text": "Use to set an upper-limit for the CPU requirement for each process. Should be an integer e.g. `--max_cpus 1`", + "help_text": "Use to set an upper-limit for the CPU requirement for each process. Should be an integer e.g. `--max_cpus 1`" }, "max_memory": { "type": "string", @@ -592,7 +612,7 @@ "fa_icon": "fas fa-memory", "pattern": "^\\d+(\\.\\d+)?\\.?\\s*(K|M|G|T)?B$", "hidden": true, - "help_text": "Use to set an upper-limit for the memory requirement for each process. Should be a string in the format integer-unit e.g. `--max_memory '8.GB'`", + "help_text": "Use to set an upper-limit for the memory requirement for each process. Should be a string in the format integer-unit e.g. `--max_memory '8.GB'`" }, "max_time": { "type": "string", @@ -601,9 +621,9 @@ "fa_icon": "far fa-clock", "pattern": "^(\\d+\\.?\\s*(s|m|h|day)\\s*)+$", "hidden": true, - "help_text": "Use to set an upper-limit for the time requirement for each process. Should be a string in the format integer-unit e.g. `--max_time '2.h'`", - }, - }, + "help_text": "Use to set an upper-limit for the time requirement for each process. Should be a string in the format integer-unit e.g. `--max_time '2.h'`" + } + } }, "generic_options": { "title": "Generic options", @@ -616,13 +636,13 @@ "type": "boolean", "description": "Display help text.", "fa_icon": "fas fa-question-circle", - "hidden": true, + "hidden": true }, "version": { "type": "boolean", "description": "Display version and exit.", "fa_icon": "fas fa-question-circle", - "hidden": true, + "hidden": true }, "publish_dir_mode": { "type": "string", @@ -631,7 +651,7 @@ "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, + "hidden": true }, "email_on_fail": { "type": "string", @@ -639,85 +659,105 @@ "fa_icon": "fas fa-exclamation-triangle", "pattern": "^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$", "help_text": "An email address to send a summary email to when the pipeline is completed - ONLY sent if the pipeline does not exit successfully.", - "hidden": true, + "hidden": true }, "plaintext_email": { "type": "boolean", "description": "Send plain-text email instead of HTML.", "fa_icon": "fas fa-remove-format", - "hidden": true, + "hidden": true }, "max_multiqc_email_size": { "type": "string", "description": "File size limit when attaching MultiQC reports to summary emails.", "default": "25.MB", "fa_icon": "fas fa-file-upload", - "hidden": true, + "hidden": true }, "monochrome_logs": { "type": "boolean", "description": "Do not use coloured log outputs.", "fa_icon": "fas fa-palette", - "hidden": true, + "hidden": true }, "hook_url": { "type": "string", "description": "Incoming hook URL for messaging service", "fa_icon": "fas fa-people-group", "help_text": "Incoming hook URL for messaging service. Currently, MS Teams and Slack are supported.", - "hidden": true, + "hidden": true }, "multiqc_config": { "type": "string", "description": "Custom config file to supply to MultiQC.", "fa_icon": "fas fa-cog", - "hidden": true, + "hidden": true }, "multiqc_logo": { "type": "string", "description": "Custom logo file to supply to MultiQC. File name must also be set in the MultiQC config file", "fa_icon": "fas fa-image", - "hidden": true, + "hidden": true }, "multiqc_methods_description": { "type": "string", "description": "Custom MultiQC yaml file containing HTML including a methods description.", - "fa_icon": "fas fa-cog", + "fa_icon": "fas fa-cog" }, "tracedir": { "type": "string", "description": "Directory to keep pipeline Nextflow logs and reports.", "default": "${params.outdir}/pipeline_info", "fa_icon": "fas fa-cogs", - "hidden": true, + "hidden": true }, "validate_params": { "type": "boolean", "description": "Boolean whether to validate parameters against the schema at runtime", "default": true, "fa_icon": "fas fa-check-square", - "hidden": true, + "hidden": true }, "show_hidden_params": { "type": "boolean", "fa_icon": "far fa-eye-slash", "description": "Show all params when using `--help`", "hidden": true, - "help_text": "By default, parameters set as _hidden_ in the schema are not shown on the command line when a user runs with `--help`. Specifying this option will tell the pipeline to show all parameters.", - }, - }, - }, + "help_text": "By default, parameters set as _hidden_ in the schema are not shown on the command line when a user runs with `--help`. Specifying this option will tell the pipeline to show all parameters." + } + } + } }, "allOf": [ - {"$ref": "#/definitions/input_output_options"}, - {"$ref": "#/definitions/umi_options"}, - {"$ref": "#/definitions/read_filtering_options"}, - {"$ref": "#/definitions/reference_genome_options"}, - {"$ref": "#/definitions/read_trimming_options"}, - {"$ref": "#/definitions/alignment_options"}, - {"$ref": "#/definitions/process_skipping_options"}, - {"$ref": "#/definitions/institutional_config_options"}, - {"$ref": "#/definitions/max_job_request_options"}, - {"$ref": "#/definitions/generic_options"}, - ], + { + "$ref": "#/definitions/input_output_options" + }, + { + "$ref": "#/definitions/umi_options" + }, + { + "$ref": "#/definitions/read_filtering_options" + }, + { + "$ref": "#/definitions/reference_genome_options" + }, + { + "$ref": "#/definitions/read_trimming_options" + }, + { + "$ref": "#/definitions/alignment_options" + }, + { + "$ref": "#/definitions/process_skipping_options" + }, + { + "$ref": "#/definitions/institutional_config_options" + }, + { + "$ref": "#/definitions/max_job_request_options" + }, + { + "$ref": "#/definitions/generic_options" + } + ] } From cbf4dbdaf5e09f74b9a7f7f0f101f3b8b57fdf0d Mon Sep 17 00:00:00 2001 From: Matthias Zepper Date: Wed, 1 Feb 2023 18:17:26 +0100 Subject: [PATCH 020/124] deduplication for the union of ext.args and params.extra_star_align_args in the STAR module. --- conf/modules.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 3d1a2c916..bfe5dea00 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -545,8 +545,8 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { '--quantTranscriptomeBan Singleend', '--outSAMstrandField intronMotif', params.save_unaligned ? '--outReadsUnmapped Fastx' : '', - params.extra_star_align_args ?: '' - ].join(' ').trim() + params.extra_star_align_args.split("\\s(?=--)") ?: '' + ].flatten().unique().join(' ').trim() publishDir = [ [ path: { "${params.outdir}/${params.aligner}/log" }, From 2586006533fe064258d57fc691aa6b57814effdd Mon Sep 17 00:00:00 2001 From: Matthias Zepper Date: Wed, 1 Feb 2023 18:41:39 +0100 Subject: [PATCH 021/124] .unique() modifies the original list and nukes all Nextflow params. unique(false) in contrast returns a new, deduplicated list and leaves the params intact. --- conf/modules.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/modules.config b/conf/modules.config index bfe5dea00..89b1bf61b 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -546,7 +546,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { '--outSAMstrandField intronMotif', params.save_unaligned ? '--outReadsUnmapped Fastx' : '', params.extra_star_align_args.split("\\s(?=--)") ?: '' - ].flatten().unique().join(' ').trim() + ].flatten().unique(false).join(' ').trim() publishDir = [ [ path: { "${params.outdir}/${params.aligner}/log" }, From 8051df979fd40d38711fff4e46a5c1241a4fb1cc Mon Sep 17 00:00:00 2001 From: Matthias Zepper Date: Wed, 1 Feb 2023 20:09:25 +0100 Subject: [PATCH 022/124] Changelog update with PR. --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 282a5e715..76d1d2182 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). +## [[Dev](https://github.com/nf-core/rnaseq/releases/tag/3.10.1)] - 2023-02-01 + +### Enhancements & fixes + +- [[#934](https://github.com/nf-core/rnaseq/pull/934)] - Union of `ext.args` and `params.extra_star_align_args` prevents parameter clashes in the STAR module + ## [[3.10.1](https://github.com/nf-core/rnaseq/releases/tag/3.10.1)] - 2023-01-05 ### Enhancements & fixes From 869fab49977b5d4e94688bf4dba08d4588574167 Mon Sep 17 00:00:00 2001 From: Matthias Zepper Date: Wed, 1 Feb 2023 20:31:13 +0100 Subject: [PATCH 023/124] .split() would be invoked on empty string with parameter is unset. --- conf/modules.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/modules.config b/conf/modules.config index 89b1bf61b..a73920f02 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -545,7 +545,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { '--quantTranscriptomeBan Singleend', '--outSAMstrandField intronMotif', params.save_unaligned ? '--outReadsUnmapped Fastx' : '', - params.extra_star_align_args.split("\\s(?=--)") ?: '' + "params.extra_star_align_args ?: ''".split("\\s(?=--)") ].flatten().unique(false).join(' ').trim() publishDir = [ [ From 595ca662a572001f69930fee31becb1f648e9534 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Wed, 8 Feb 2023 12:58:22 +0000 Subject: [PATCH 024/124] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76d1d2182..69f81751b 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). -## [[Dev](https://github.com/nf-core/rnaseq/releases/tag/3.10.1)] - 2023-02-01 +## [Unpublished Version / DEV] ### Enhancements & fixes From 2a7b009075d69a5068a9098444f4165ca1ee736d Mon Sep 17 00:00:00 2001 From: Matthias Zepper Date: Wed, 8 Feb 2023 13:22:42 +0100 Subject: [PATCH 025/124] Fix a bug in salmon_summarizedexperiment.r by ensuring that rbind() also works when there is no column named tx in rowdata. --- bin/salmon_summarizedexperiment.r | 69 +++++++++++++++++-------------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/bin/salmon_summarizedexperiment.r b/bin/salmon_summarizedexperiment.r index 32243ed7f..5ebdd317b 100755 --- a/bin/salmon_summarizedexperiment.r +++ b/bin/salmon_summarizedexperiment.r @@ -4,56 +4,65 @@ library(SummarizedExperiment) ## Create SummarizedExperiment (se) object from Salmon counts -args = commandArgs(trailingOnly=TRUE) +args <- commandArgs(trailingOnly = TRUE) if (length(args) < 2) { - stop("Usage: salmon_se.r ", call.=FALSE) + stop("Usage: salmon_se.r ", call. = FALSE) } -coldata = args[1] -counts_fn = args[2] -tpm_fn = args[3] +coldata <- args[1] +counts_fn <- args[2] +tpm_fn <- args[3] -tx2gene = "salmon_tx2gene.tsv" -info = file.info(tx2gene) +tx2gene <- "salmon_tx2gene.tsv" +info <- file.info(tx2gene) if (info$size == 0) { - tx2gene = NULL + tx2gene <- NULL } else { - rowdata = read.csv(tx2gene, sep="\t", header = FALSE) - colnames(rowdata) = c("tx", "gene_id", "gene_name") - tx2gene = rowdata[,1:2] + rowdata <- read.csv(tx2gene, sep = "\t", header = FALSE) + colnames(rowdata) <- c("tx", "gene_id", "gene_name") + tx2gene <- rowdata[, 1:2] } -counts = read.csv(counts_fn, row.names=1, sep="\t") -counts = counts[,2:ncol(counts),drop=FALSE] # remove gene_name column -tpm = read.csv(tpm_fn, row.names=1, sep="\t") -tpm = tpm[,2:ncol(tpm),drop=FALSE] # remove gene_name column +counts <- read.csv(counts_fn, row.names = 1, sep = "\t") +counts <- counts[, 2:ncol(counts), drop = FALSE] # remove gene_name column +tpm <- read.csv(tpm_fn, row.names = 1, sep = "\t") +tpm <- tpm[, 2:ncol(tpm), drop = FALSE] # remove gene_name column if (length(intersect(rownames(counts), rowdata[["tx"]])) > length(intersect(rownames(counts), rowdata[["gene_id"]]))) { - by_what = "tx" + by_what <- "tx" } else { - by_what = "gene_id" - rowdata = unique(rowdata[,2:3]) + by_what <- "gene_id" + rowdata <- unique(rowdata[, 2:3]) } if (file.exists(coldata)) { - coldata = read.csv(coldata, sep="\t") - coldata = coldata[match(colnames(counts), coldata[,1]),] - coldata = cbind(files = fns, coldata) + coldata <- read.csv(coldata, sep = "\t") + coldata <- coldata[match(colnames(counts), coldata[, 1]), ] + coldata <- cbind(files = fns, coldata) } else { message("ColData not avaliable ", coldata) - coldata = data.frame(files = colnames(counts), names = colnames(counts)) + coldata <- data.frame(files = colnames(counts), names = colnames(counts)) } -rownames(coldata) = coldata[["names"]] -extra = setdiff(rownames(counts), as.character(rowdata[[by_what]])) +rownames(coldata) <- coldata[["names"]] +extra <- setdiff(rownames(counts), as.character(rowdata[[by_what]])) if (length(extra) > 0) { - rowdata = rbind(rowdata, data.frame(tx=extra, gene_id=extra, gene_name=extra)) + rowdata <- rbind( + rowdata, + data.frame( + tx = extra, + gene_id = extra, + gene_name = extra + )[, colnames(rowdata)] + ) } -rowdata = rowdata[match(rownames(counts), as.character(rowdata[[by_what]])),] -rownames(rowdata) = rowdata[[by_what]] -se = SummarizedExperiment(assays = list(counts = counts, abundance = tpm), - colData = DataFrame(coldata), - rowData = rowdata) +rowdata <- rowdata[match(rownames(counts), as.character(rowdata[[by_what]])), ] +rownames(rowdata) <- rowdata[[by_what]] +se <- SummarizedExperiment( + assays = list(counts = counts, abundance = tpm), + colData = DataFrame(coldata), + rowData = rowdata +) saveRDS(se, file = paste0(tools::file_path_sans_ext(counts_fn), ".rds")) From 13b6051eca09d6bf982211a30883e767f671d789 Mon Sep 17 00:00:00 2001 From: Matthias Zepper Date: Wed, 8 Feb 2023 14:25:22 +0100 Subject: [PATCH 026/124] Changelog updates --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69f81751b..1e2aee18d 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 +- [[#940](https://github.com/nf-core/rnaseq/issues/940)] - Bugfix in `salmon_summarizedexperiment.r` to ensure `rbind` doesn't fail when `rowdata` has no `tx` column. See ([[#941](https://github.com/nf-core/rnaseq/pull/941)]) for details. - [[#934](https://github.com/nf-core/rnaseq/pull/934)] - Union of `ext.args` and `params.extra_star_align_args` prevents parameter clashes in the STAR module ## [[3.10.1](https://github.com/nf-core/rnaseq/releases/tag/3.10.1)] - 2023-01-05 From 83478b7e29385a59e3d945504f924a23699c2127 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Wed, 8 Feb 2023 20:06:11 +0000 Subject: [PATCH 027/124] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e2aee18d..56ce03801 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Enhancements & fixes -- [[#940](https://github.com/nf-core/rnaseq/issues/940)] - Bugfix in `salmon_summarizedexperiment.r` to ensure `rbind` doesn't fail when `rowdata` has no `tx` column. See ([[#941](https://github.com/nf-core/rnaseq/pull/941)]) for details. - [[#934](https://github.com/nf-core/rnaseq/pull/934)] - Union of `ext.args` and `params.extra_star_align_args` prevents parameter clashes in the STAR module +- [[#940](https://github.com/nf-core/rnaseq/issues/940)] - Bugfix in `salmon_summarizedexperiment.r` to ensure `rbind` doesn't fail when `rowdata` has no `tx` column. See ([[#941](https://github.com/nf-core/rnaseq/pull/941)]) for details. ## [[3.10.1](https://github.com/nf-core/rnaseq/releases/tag/3.10.1)] - 2023-01-05 From efc01cc3424dec6e67acdbc088fb4dc3ceec511b Mon Sep 17 00:00:00 2001 From: Gregor Sturm Date: Mon, 20 Feb 2023 14:25:51 +0100 Subject: [PATCH 028/124] Update README according to https://github.com/nf-core/tools/issues/2186 --- README.md | 75 ++++++++++++++++++++++++------------------------------- 1 file changed, 33 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 8b42c6fec..0e6018ffe 100644 --- a/README.md +++ b/README.md @@ -10,27 +10,11 @@ [![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23rnaseq-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/rnaseq)[![Follow on Twitter](http://img.shields.io/badge/twitter-%40nf__core-1DA1F2?labelColor=000000&logo=twitter)](https://twitter.com/nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core) -## Introduction - -**nf-core/rnaseq** is a bioinformatics pipeline that can be used to analyse RNA sequencing data obtained from organisms with a reference genome and annotation. - -On release, automated continuous integration tests run the pipeline on a [full-sized dataset](https://github.com/nf-core/test-datasets/tree/rnaseq#full-test-dataset-origin) obtained from the ENCODE Project Consortium on the AWS cloud infrastructure. This ensures that the pipeline runs on AWS, has sensible resource allocation defaults set to run on real-world datasets, and permits the persistent storage of results to benchmark between pipeline releases and other analysis sources. The results obtained from running the full-sized tests individually for each `--aligner` option can be viewed on the [nf-core website](https://nf-co.re/rnaseq/results) e.g. the results for running the pipeline with `--aligner star_salmon` will be in a folder called `aligner_star_salmon` and so on. - -The pipeline is built using [Nextflow](https://www.nextflow.io), a workflow tool to run tasks across multiple compute infrastructures in a very portable manner. It uses Docker/Singularity containers making installation trivial and results highly reproducible. The [Nextflow DSL2](https://www.nextflow.io/docs/latest/dsl2.html) implementation of this pipeline uses one container per process which makes it much easier to maintain and update software dependencies. Where possible, these processes have been submitted to and installed from [nf-core/modules](https://github.com/nf-core/modules) in order to make them available to all nf-core pipelines, and to everyone within the Nextflow community! - -## Online videos - -A short talk about the history, current status and functionality on offer in this pipeline was given by Harshil Patel ([@drpatelh](https://github.com/drpatelh)) on [8th February 2022](https://nf-co.re/events/2022/bytesize-32-nf-core-rnaseq) as part of the nf-core/bytesize series. - -You can find numerous talks on the [nf-core events page](https://nf-co.re/events) from various topics including writing pipelines/modules in Nextflow DSL2, using nf-core tooling, running nf-core pipelines as well as more generic content like contributing to Github. Please check them out! - ## Pipeline summary +**nf-core/rnaseq** is a bioinformatics pipeline that can be used to analyse RNA sequencing data obtained from organisms with a reference genome and annotation. It takes a samplesheet and FASTQ files as input, performs quality control (QC), trimming and (pseudo-)alignment, and produces a gene expression matrix and extensive QC report. ![nf-core/rnaseq metro map](docs/images/nf-core-rnaseq_metro_map_grey.png) -> **Note** -> The SRA download functionality has been removed from the pipeline (`>=3.2`) and ported to an independent workflow called [nf-core/fetchngs](https://nf-co.re/fetchngs). You can provide `--nf_core_pipeline rnaseq` when running nf-core/fetchngs to download and auto-create a samplesheet containing publicly available samples that can be accepted directly as input by this pipeline. - 1. Merge re-sequenced FastQ files ([`cat`](http://www.linfo.org/cat.html)) 2. Sub-sample FastQ files and auto-infer strandedness ([`fq`](https://github.com/stjude-rust-labs/fq), [`Salmon`](https://combine-lab.github.io/salmon/)) 3. Read QC ([`FastQC`](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/)) @@ -56,44 +40,49 @@ You can find numerous talks on the [nf-core events page](https://nf-co.re/events 15. Pseudo-alignment and quantification ([`Salmon`](https://combine-lab.github.io/salmon/); _optional_) 16. Present QC for raw read, alignment, gene biotype, sample similarity, and strand-specificity checks ([`MultiQC`](http://multiqc.info/), [`R`](https://www.r-project.org/)) +> **Note** +> The SRA download functionality has been removed from the pipeline (`>=3.2`) and ported to an independent workflow called [nf-core/fetchngs](https://nf-co.re/fetchngs). You can provide `--nf_core_pipeline rnaseq` when running nf-core/fetchngs to download and auto-create a samplesheet containing publicly available samples that can be accepted directly as input by this pipeline. + > **Warning** > Quantification isn't performed if using `--aligner hisat2` due to the lack of an appropriate option to calculate accurate expression estimates from HISAT2 derived genomic alignments. However, you can use this route if you have a preference for the alignment, QC and other types of downstream analysis compatible with the output of HISAT2. -## Quick Start - -1. Install [`Nextflow`](https://www.nextflow.io/docs/latest/getstarted.html#installation) (`>=22.10.1`) - -2. Install any of [`Docker`](https://docs.docker.com/engine/installation/), [`Singularity`](https://www.sylabs.io/guides/3.0/user-guide/) (you can follow [this tutorial](https://singularity-tutorial.github.io/01-installation/)), [`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 _(you can use [`Conda`](https://conda.io/miniconda.html) both to install Nextflow itself and also to manage software within pipelines. Please only use it within pipelines 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. +## Usage -3. Download the pipeline and test it on a minimal dataset with a single command: +> **Note** +> If you are new to nextflow and nf-core, please refer to [this page](https://nf-co.re/#TODO) on how to set-up nextflow. - ```bash - nextflow run nf-core/rnaseq -profile test,YOURPROFILE --outdir - ``` +First, you need to prepare a samplesheet with your input data that looks as follows: - 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. +**samplesheet.csv**: +```csv +sample,fastq_1,fastq_2,strandedness +CONTROL_REP1,AEG588A1_S1_L002_R1_001.fastq.gz,AEG588A1_S1_L002_R2_001.fastq.gz,auto +CONTROL_REP1,AEG588A1_S1_L003_R1_001.fastq.gz,AEG588A1_S1_L003_R2_001.fastq.gz,auto +CONTROL_REP1,AEG588A1_S1_L004_R1_001.fastq.gz,AEG588A1_S1_L004_R2_001.fastq.gz,auto +``` - > - 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`, 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. +Each row represents a fastq file (single-end) or a pair of fastq files (paired end). Rows with the same sample identifier are considered technical replicates and merged automatically. The strandedness refers to the library preparation and will be automatically inferred if set to `auto`. -4. Start running your own analysis! +Now, you can run the pipeline using: +```bash +nextflow run nf-core/rnaseq \ + --input samplesheet.csv \ + --outdir \ + --genome GRCh37 \ + -profile +``` - ```bash - nextflow run nf-core/rnaseq --input samplesheet.csv --outdir --genome GRCh37 -profile - ``` +For more details, please refer to the [usage documentation](https://nf-co.re/rnaseq/3.10.1/usage) and the [parameter documentation](https://nf-co.re/rnaseq/3.10.1/parameters). - - An executable Python script called [`fastq_dir_to_samplesheet.py`](https://github.com/nf-core/rnaseq/blob/master/bin/fastq_dir_to_samplesheet.py) has been provided if you would like to auto-create an input samplesheet based on a directory containing FastQ files **before** you run the pipeline (requires Python 3 installed locally) e.g. +## Pipeline output +The output of the pipeline applied to a [full-sized example dataset](https://github.com/nf-core/test-datasets/tree/rnaseq#full-test-dataset-origin) can be found [here](https://nf-co.re/rnaseq/results). +For more details, please refer to the [output documentation](https://nf-co.re/rnaseq/3.10.1/output). - ```bash - wget -L https://raw.githubusercontent.com/nf-core/rnaseq/master/bin/fastq_dir_to_samplesheet.py - ./fastq_dir_to_samplesheet.py samplesheet.csv --strandedness reverse - ``` +## Online videos -## Documentation +A short talk about the history, current status and functionality on offer in this pipeline was given by Harshil Patel ([@drpatelh](https://github.com/drpatelh)) on [8th February 2022](https://nf-co.re/events/2022/bytesize-32-nf-core-rnaseq) as part of the nf-core/bytesize series. -The nf-core/rnaseq pipeline comes with documentation about the pipeline [usage](https://nf-co.re/rnaseq/usage), [parameters](https://nf-co.re/rnaseq/parameters) and [output](https://nf-co.re/rnaseq/output). +You can find numerous talks on the [nf-core events page](https://nf-co.re/events) from various topics including writing pipelines/modules in Nextflow DSL2, using nf-core tooling, running nf-core pipelines as well as more generic content like contributing to Github. Please check them out! ## Credits @@ -117,6 +106,8 @@ Many thanks to other who have helped out along the way too, including (but not l [@olgabot](https://github.com/olgabot), [@jburos](https://github.com/jburos). + + ## Contributions and Support If you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md). From 0ec0febaffb44aca90c56946faa42b4569ded108 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Mon, 20 Feb 2023 13:33:01 +0000 Subject: [PATCH 029/124] [automated] Fix linting with Prettier --- README.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 0e6018ffe..f680425a3 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,8 @@ [![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23rnaseq-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/rnaseq)[![Follow on Twitter](http://img.shields.io/badge/twitter-%40nf__core-1DA1F2?labelColor=000000&logo=twitter)](https://twitter.com/nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core) ## Pipeline summary -**nf-core/rnaseq** is a bioinformatics pipeline that can be used to analyse RNA sequencing data obtained from organisms with a reference genome and annotation. It takes a samplesheet and FASTQ files as input, performs quality control (QC), trimming and (pseudo-)alignment, and produces a gene expression matrix and extensive QC report. + +**nf-core/rnaseq** is a bioinformatics pipeline that can be used to analyse RNA sequencing data obtained from organisms with a reference genome and annotation. It takes a samplesheet and FASTQ files as input, performs quality control (QC), trimming and (pseudo-)alignment, and produces a gene expression matrix and extensive QC report. ![nf-core/rnaseq metro map](docs/images/nf-core-rnaseq_metro_map_grey.png) @@ -54,6 +55,7 @@ First, you need to prepare a samplesheet with your input data that looks as follows: **samplesheet.csv**: + ```csv sample,fastq_1,fastq_2,strandedness CONTROL_REP1,AEG588A1_S1_L002_R1_001.fastq.gz,AEG588A1_S1_L002_R2_001.fastq.gz,auto @@ -61,22 +63,24 @@ CONTROL_REP1,AEG588A1_S1_L003_R1_001.fastq.gz,AEG588A1_S1_L003_R2_001.fastq.gz,a CONTROL_REP1,AEG588A1_S1_L004_R1_001.fastq.gz,AEG588A1_S1_L004_R2_001.fastq.gz,auto ``` -Each row represents a fastq file (single-end) or a pair of fastq files (paired end). Rows with the same sample identifier are considered technical replicates and merged automatically. The strandedness refers to the library preparation and will be automatically inferred if set to `auto`. +Each row represents a fastq file (single-end) or a pair of fastq files (paired end). Rows with the same sample identifier are considered technical replicates and merged automatically. The strandedness refers to the library preparation and will be automatically inferred if set to `auto`. Now, you can run the pipeline using: + ```bash nextflow run nf-core/rnaseq \ --input samplesheet.csv \ --outdir \ --genome GRCh37 \ - -profile + -profile ``` -For more details, please refer to the [usage documentation](https://nf-co.re/rnaseq/3.10.1/usage) and the [parameter documentation](https://nf-co.re/rnaseq/3.10.1/parameters). +For more details, please refer to the [usage documentation](https://nf-co.re/rnaseq/3.10.1/usage) and the [parameter documentation](https://nf-co.re/rnaseq/3.10.1/parameters). ## Pipeline output -The output of the pipeline applied to a [full-sized example dataset](https://github.com/nf-core/test-datasets/tree/rnaseq#full-test-dataset-origin) can be found [here](https://nf-co.re/rnaseq/results). -For more details, please refer to the [output documentation](https://nf-co.re/rnaseq/3.10.1/output). + +The output of the pipeline applied to a [full-sized example dataset](https://github.com/nf-core/test-datasets/tree/rnaseq#full-test-dataset-origin) can be found [here](https://nf-co.re/rnaseq/results). +For more details, please refer to the [output documentation](https://nf-co.re/rnaseq/3.10.1/output). ## Online videos @@ -106,8 +110,6 @@ Many thanks to other who have helped out along the way too, including (but not l [@olgabot](https://github.com/olgabot), [@jburos](https://github.com/jburos). - - ## Contributions and Support If you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md). From 04a206c2a4d5f72f0eb54aae135d350ca39582e9 Mon Sep 17 00:00:00 2001 From: Gregor Sturm Date: Mon, 20 Feb 2023 15:05:58 +0100 Subject: [PATCH 030/124] Update README.md Co-authored-by: James A. Fellows Yates --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f680425a3..582d60a1b 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ [![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23rnaseq-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/rnaseq)[![Follow on Twitter](http://img.shields.io/badge/twitter-%40nf__core-1DA1F2?labelColor=000000&logo=twitter)](https://twitter.com/nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core) -## Pipeline summary +## Introduction **nf-core/rnaseq** is a bioinformatics pipeline that can be used to analyse RNA sequencing data obtained from organisms with a reference genome and annotation. It takes a samplesheet and FASTQ files as input, performs quality control (QC), trimming and (pseudo-)alignment, and produces a gene expression matrix and extensive QC report. From 57bf3269f4b4e86c410a4238b23f56f9512f9dc2 Mon Sep 17 00:00:00 2001 From: Julie Lorent <5382593+jlorent@users.noreply.github.com> Date: Mon, 6 Mar 2023 14:01:28 +0100 Subject: [PATCH 031/124] Allow setting clipping parameters (only _r1 if unpaired) - Issue 944 --- CHANGELOG.md | 1 + conf/modules.config | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56ce03801..7c47d734b 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 - [[#934](https://github.com/nf-core/rnaseq/pull/934)] - Union of `ext.args` and `params.extra_star_align_args` prevents parameter clashes in the STAR module - [[#940](https://github.com/nf-core/rnaseq/issues/940)] - Bugfix in `salmon_summarizedexperiment.r` to ensure `rbind` doesn't fail when `rowdata` has no `tx` column. See ([[#941](https://github.com/nf-core/rnaseq/pull/941)]) for details. +- [[#944](https://github.com/nf-core/rnaseq/issues/944)] - Read clipping using clip_r1, clip_r2, three_prime_clip_r1, three_prime_clip_r2 disabled in 3.10 ## [[3.10.1](https://github.com/nf-core/rnaseq/releases/tag/3.10.1)] - 2023-01-05 diff --git a/conf/modules.config b/conf/modules.config index a73920f02..7e5e5d955 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -211,7 +211,11 @@ if (!params.skip_trimming) { ext.args = { [ "--fastqc_args '-t ${task.cpus}' ", - params.trim_nextseq > 0 ? "--nextseq ${params.trim_nextseq}" : '' + params.trim_nextseq > 0 ? "--nextseq ${params.trim_nextseq}" : '', + params.clip_r1 > 0 ? "--clip_r1 ${params.clip_r1}" : '', + params.clip_r2 > 0 && !meta.single_end ? "--clip_r2 ${params.clip_r2}" : '', + params.three_prime_clip_r1 > 0 ? "--three_prime_clip_r1 ${params.three_prime_clip_r1}" : '', + params.three_prime_clip_r2 > 0 && !meta.single_end ? "--three_prime_clip_r2 ${params.three_prime_clip_r2}" : '' ].join(' ').trim() } publishDir = [ From 6f998a4b6c0ae7bcf02518145fbb5cefa39a5eaf Mon Sep 17 00:00:00 2001 From: Gregor Sturm Date: Fri, 10 Mar 2023 16:49:24 +0100 Subject: [PATCH 032/124] Update README.md Co-authored-by: Harshil Patel --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 582d60a1b..d650b2ca7 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ nextflow run nf-core/rnaseq \ -profile ``` -For more details, please refer to the [usage documentation](https://nf-co.re/rnaseq/3.10.1/usage) and the [parameter documentation](https://nf-co.re/rnaseq/3.10.1/parameters). +For more details, please refer to the [usage documentation](https://nf-co.re/rnaseq/usage) and the [parameter documentation](https://nf-co.re/rnaseq/parameters). ## Pipeline output From 1fae451efb5f68c4f3c1c78183abf344e4f61252 Mon Sep 17 00:00:00 2001 From: Gregor Sturm Date: Fri, 10 Mar 2023 16:49:37 +0100 Subject: [PATCH 033/124] Update README.md Co-authored-by: Harshil Patel --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d650b2ca7..ebc111cc8 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ For more details, please refer to the [usage documentation](https://nf-co.re/rna ## Pipeline output The output of the pipeline applied to a [full-sized example dataset](https://github.com/nf-core/test-datasets/tree/rnaseq#full-test-dataset-origin) can be found [here](https://nf-co.re/rnaseq/results). -For more details, please refer to the [output documentation](https://nf-co.re/rnaseq/3.10.1/output). +For more details, please refer to the [output documentation](https://nf-co.re/rnaseq/output). ## Online videos From b9082d1efbfaf7d1c53f673d02c96336c224b0c9 Mon Sep 17 00:00:00 2001 From: ryanyord Date: Mon, 13 Mar 2023 22:17:18 -0400 Subject: [PATCH 034/124] add auto as argument and set as default --- bin/fastq_dir_to_samplesheet.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/fastq_dir_to_samplesheet.py b/bin/fastq_dir_to_samplesheet.py index 6c7931f4f..5b4d04be9 100755 --- a/bin/fastq_dir_to_samplesheet.py +++ b/bin/fastq_dir_to_samplesheet.py @@ -18,8 +18,8 @@ def parse_args(args=None): "--strandedness", type=str, dest="STRANDEDNESS", - default="unstranded", - help="Value for 'strandedness' in samplesheet. Must be one of 'unstranded', 'forward', 'reverse'.", + default="auto", + help="Value for 'strandedness' in samplesheet. Must be one of 'unstranded', 'forward', 'reverse', 'auto'.", ) parser.add_argument( "-r1", @@ -80,7 +80,7 @@ def parse_args(args=None): def fastq_dir_to_samplesheet( fastq_dir, samplesheet_file, - strandedness="unstranded", + strandedness="auto", read1_extension="_R1_001.fastq.gz", read2_extension="_R2_001.fastq.gz", single_end=False, @@ -154,8 +154,8 @@ def get_fastqs(extension, recursive=False): def main(args=None): args = parse_args(args) - strandedness = "unstranded" - if args.STRANDEDNESS in ["unstranded", "forward", "reverse"]: + strandedness = "auto" + if args.STRANDEDNESS in ["unstranded", "forward", "reverse", "auto"]: strandedness = args.STRANDEDNESS fastq_dir_to_samplesheet( @@ -173,4 +173,4 @@ def main(args=None): if __name__ == "__main__": - sys.exit(main()) + sys.exit(main()) \ No newline at end of file From 0d4c5f8fbf4bf1635949216c4be0843ab8007633 Mon Sep 17 00:00:00 2001 From: Ryan Yordanoff <85899130+ryanyord@users.noreply.github.com> Date: Tue, 14 Mar 2023 10:02:50 -0400 Subject: [PATCH 035/124] Include 'auto' in fastq_dir_to_samplesheet script --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c47d734b..de7fd47c9 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 - [[#934](https://github.com/nf-core/rnaseq/pull/934)] - Union of `ext.args` and `params.extra_star_align_args` prevents parameter clashes in the STAR module - [[#940](https://github.com/nf-core/rnaseq/issues/940)] - Bugfix in `salmon_summarizedexperiment.r` to ensure `rbind` doesn't fail when `rowdata` has no `tx` column. See ([[#941](https://github.com/nf-core/rnaseq/pull/941)]) for details. - [[#944](https://github.com/nf-core/rnaseq/issues/944)] - Read clipping using clip_r1, clip_r2, three_prime_clip_r1, three_prime_clip_r2 disabled in 3.10 +- [[#956](https://github.com/nf-core/rnaseq/pull/956)] - Implement 'auto' as default strandedness argument in `fastq_dir_to_samplesheet.py` script ## [[3.10.1](https://github.com/nf-core/rnaseq/releases/tag/3.10.1)] - 2023-01-05 From 78d4dc957a791617d07db151ef139d43d393faec Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 14 Mar 2023 19:12:30 +0000 Subject: [PATCH 036/124] Fix Python Black --- bin/fastq_dir_to_samplesheet.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/bin/fastq_dir_to_samplesheet.py b/bin/fastq_dir_to_samplesheet.py index 5b4d04be9..3766976a8 100755 --- a/bin/fastq_dir_to_samplesheet.py +++ b/bin/fastq_dir_to_samplesheet.py @@ -94,7 +94,9 @@ def sanitize_sample(path, extension): sample = os.path.basename(path).replace(extension, "") if sanitise_name: sample = sanitise_name_delimiter.join( - os.path.basename(path).split(sanitise_name_delimiter)[:sanitise_name_index] + os.path.basename(path).split(sanitise_name_delimiter)[ + :sanitise_name_index + ] ) return sample @@ -108,7 +110,9 @@ def get_fastqs(extension, recursive=False): search_path = f"*{extension}" if recursive: search_path = f"**/*{extension}" - return sorted(glob.glob(os.path.join(fastq_dir, search_path), recursive=recursive)) + return sorted( + glob.glob(os.path.join(fastq_dir, search_path), recursive=recursive) + ) read_dict = {} @@ -142,7 +146,9 @@ def get_fastqs(extension, recursive=False): sample_info = ",".join([sample, read_1, read_2, strandedness]) fout.write(f"{sample_info}\n") else: - error_str = "\nWARNING: No FastQ files found so samplesheet has not been created!\n\n" + error_str = ( + "\nWARNING: No FastQ files found so samplesheet has not been created!\n\n" + ) error_str += "Please check the values provided for the:\n" error_str += " - Path to the directory containing the FastQ files\n" error_str += " - '--read1_extension' parameter\n" @@ -173,4 +179,4 @@ def main(args=None): if __name__ == "__main__": - sys.exit(main()) \ No newline at end of file + sys.exit(main()) From d2dd1a7b4c0f3db60c7922c3d5428946a8dd868e Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 14 Mar 2023 21:30:48 +0000 Subject: [PATCH 037/124] Remove HISAT2 from full-sized AWS tests --- .github/workflows/awsfulltest.yml | 2 +- CHANGELOG.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 1718b42dd..ce5031274 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -15,7 +15,7 @@ jobs: # Do a full-scale run with each of the three aligners strategy: matrix: - aligner: ["star_salmon", "star_rsem", "hisat2"] + aligner: ["star_salmon", "star_rsem"] steps: - name: Launch workflow via tower uses: nf-core/tower-action@v3 diff --git a/CHANGELOG.md b/CHANGELOG.md index de7fd47c9..9faed6f94 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 - [[#940](https://github.com/nf-core/rnaseq/issues/940)] - Bugfix in `salmon_summarizedexperiment.r` to ensure `rbind` doesn't fail when `rowdata` has no `tx` column. See ([[#941](https://github.com/nf-core/rnaseq/pull/941)]) for details. - [[#944](https://github.com/nf-core/rnaseq/issues/944)] - Read clipping using clip_r1, clip_r2, three_prime_clip_r1, three_prime_clip_r2 disabled in 3.10 - [[#956](https://github.com/nf-core/rnaseq/pull/956)] - Implement 'auto' as default strandedness argument in `fastq_dir_to_samplesheet.py` script +- Remove HISAT2 from automated AWS full-sized tests ## [[3.10.1](https://github.com/nf-core/rnaseq/releases/tag/3.10.1)] - 2023-01-05 From e08bb722dfcfdf494d9b1173c5de11df881e2d20 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 14 Mar 2023 21:31:18 +0000 Subject: [PATCH 038/124] Fix Python Black --- bin/fastq_dir_to_samplesheet.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/bin/fastq_dir_to_samplesheet.py b/bin/fastq_dir_to_samplesheet.py index 3766976a8..1eb3657c6 100755 --- a/bin/fastq_dir_to_samplesheet.py +++ b/bin/fastq_dir_to_samplesheet.py @@ -94,9 +94,7 @@ def sanitize_sample(path, extension): sample = os.path.basename(path).replace(extension, "") if sanitise_name: sample = sanitise_name_delimiter.join( - os.path.basename(path).split(sanitise_name_delimiter)[ - :sanitise_name_index - ] + os.path.basename(path).split(sanitise_name_delimiter)[:sanitise_name_index] ) return sample @@ -110,9 +108,7 @@ def get_fastqs(extension, recursive=False): search_path = f"*{extension}" if recursive: search_path = f"**/*{extension}" - return sorted( - glob.glob(os.path.join(fastq_dir, search_path), recursive=recursive) - ) + return sorted(glob.glob(os.path.join(fastq_dir, search_path), recursive=recursive)) read_dict = {} @@ -146,9 +142,7 @@ def get_fastqs(extension, recursive=False): sample_info = ",".join([sample, read_1, read_2, strandedness]) fout.write(f"{sample_info}\n") else: - error_str = ( - "\nWARNING: No FastQ files found so samplesheet has not been created!\n\n" - ) + error_str = "\nWARNING: No FastQ files found so samplesheet has not been created!\n\n" error_str += "Please check the values provided for the:\n" error_str += " - Path to the directory containing the FastQ files\n" error_str += " - '--read1_extension' parameter\n" From 0dbeea5714acfa3e5211b080a28b93adb0ab3f86 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 14 Mar 2023 21:47:49 +0000 Subject: [PATCH 039/124] Update nf-core/modules and subworkflows --- CHANGELOG.md | 16 ++++ modules.json | 60 +++++++-------- modules/nf-core/bbmap/bbsplit/meta.yml | 3 +- .../custom/dumpsoftwareversions/main.nf | 6 +- modules/nf-core/fq/subsample/meta.yml | 2 +- modules/nf-core/gunzip/meta.yml | 34 ++++----- modules/nf-core/picard/markduplicates/main.nf | 6 +- modules/nf-core/preseq/lcextrap/meta.yml | 2 +- .../nf-core/rsem/calculateexpression/meta.yml | 2 +- .../nf-core/rsem/preparereference/meta.yml | 2 +- modules/nf-core/rseqc/tin/meta.yml | 6 +- modules/nf-core/salmon/quant/meta.yml | 10 +-- modules/nf-core/samtools/flagstat/meta.yml | 2 +- modules/nf-core/samtools/idxstats/meta.yml | 2 +- modules/nf-core/samtools/index/meta.yml | 2 +- modules/nf-core/samtools/sort/meta.yml | 2 +- modules/nf-core/samtools/stats/meta.yml | 14 ++-- modules/nf-core/ucsc/bedclip/meta.yml | 5 +- .../nf-core/ucsc/bedgraphtobigwig/meta.yml | 6 +- modules/nf-core/umitools/dedup/main.nf | 8 +- modules/nf-core/umitools/dedup/meta.yml | 74 +++++++++---------- modules/nf-core/umitools/extract/main.nf | 8 +- modules/nf-core/umitools/extract/meta.yml | 50 ++++++------- modules/nf-core/untar/main.nf | 29 ++++---- .../bam_dedup_stats_samtools_umitools/main.nf | 25 +++---- .../meta.yml | 53 ++++++------- .../nf-core/bam_markduplicates_picard/main.nf | 25 +++---- .../bam_markduplicates_picard/meta.yml | 65 ++++++++-------- subworkflows/nf-core/bam_rseqc/meta.yml | 6 +- .../nf-core/bam_stats_samtools/main.nf | 18 ++--- .../nf-core/bam_stats_samtools/meta.yml | 52 +++++-------- 31 files changed, 294 insertions(+), 301 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9faed6f94..8ef93afa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [[#956](https://github.com/nf-core/rnaseq/pull/956)] - Implement 'auto' as default strandedness argument in `fastq_dir_to_samplesheet.py` script - Remove HISAT2 from automated AWS full-sized tests +### Software dependencies + +Note, since the pipeline is now using Nextflow DSL2, each process will be run with its own [Biocontainer](https://biocontainers.pro/#/registry). This means that on occasion it is entirely possible for the pipeline to be using different versions of the same tool. However, the overall software dependency changes compared to the last release have been listed below for reference. + +| Dependency | Old version | New version | +| ----------- | ----------- | ----------- | +| `multiqc` | 1.13 | 1.14 | +| `picard` | 2.27.4 | 3.0.0 | +| `umi_tools` | 1.1.2 | 1.1.4 | + +> **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 new version information isn't present. + ## [[3.10.1](https://github.com/nf-core/rnaseq/releases/tag/3.10.1)] - 2023-01-05 ### Enhancements & fixes diff --git a/modules.json b/modules.json index 0403e1f6a..1549d2e29 100644 --- a/modules.json +++ b/modules.json @@ -7,7 +7,7 @@ "nf-core": { "bbmap/bbsplit": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["modules"] }, "cat/fastq": { @@ -17,7 +17,7 @@ }, "custom/dumpsoftwareversions": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "b6d4d476aee074311c89d82a69c1921bd70c8180", "installed_by": ["modules"] }, "custom/getchromsizes": { @@ -33,8 +33,8 @@ }, "fq/subsample": { "branch": "master", - "git_sha": "ad462aa294faf9a8c42688a08daf81a580594f70", - "installed_by": ["modules", "fastq_subsample_fq_salmon"] + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", + "installed_by": ["fastq_subsample_fq_salmon", "modules"] }, "gffread": { "branch": "master", @@ -43,7 +43,7 @@ }, "gunzip": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["modules"] }, "hisat2/align": { @@ -63,12 +63,12 @@ }, "picard/markduplicates": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "2f88b26e9804b99e98f7cd08e74c3f88288a3358", "installed_by": ["bam_markduplicates_picard"] }, "preseq/lcextrap": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["modules"] }, "qualimap/rnaseq": { @@ -78,12 +78,12 @@ }, "rsem/calculateexpression": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["modules"] }, "rsem/preparereference": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["modules"] }, "rseqc/bamstat": { @@ -123,7 +123,7 @@ }, "rseqc/tin": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["bam_rseqc"] }, "salmon/index": { @@ -133,36 +133,36 @@ }, "salmon/quant": { "branch": "master", - "git_sha": "94b06f1683ddf893cf06525f6e7f0573ad8fbf83", - "installed_by": ["modules", "fastq_subsample_fq_salmon"] + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", + "installed_by": ["fastq_subsample_fq_salmon", "modules"] }, "samtools/flagstat": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["bam_stats_samtools"] }, "samtools/idxstats": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["bam_stats_samtools"] }, "samtools/index": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": [ + "bam_dedup_stats_samtools_umitools", "bam_markduplicates_picard", - "bam_sort_stats_samtools", - "bam_dedup_stats_samtools_umitools" + "bam_sort_stats_samtools" ] }, "samtools/sort": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["bam_sort_stats_samtools"] }, "samtools/stats": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["bam_stats_samtools"] }, "sortmerna": { @@ -197,27 +197,27 @@ }, "ucsc/bedclip": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["bedgraph_bedclip_bedgraphtobigwig"] }, "ucsc/bedgraphtobigwig": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["bedgraph_bedclip_bedgraphtobigwig"] }, "umitools/dedup": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "6d9c7e43404e20a97d2f6f88548456afe78282e6", "installed_by": ["bam_dedup_stats_samtools_umitools"] }, "umitools/extract": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "6d9c7e43404e20a97d2f6f88548456afe78282e6", "installed_by": ["fastq_fastqc_umitools_trimgalore"] }, "untar": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "cc1f997fab6d8fde5dc0e6e2a310814df5b53ce7", "installed_by": ["modules"] } } @@ -226,17 +226,17 @@ "nf-core": { "bam_dedup_stats_samtools_umitools": { "branch": "master", - "git_sha": "41891ec2c3704911cd68b9317f26545b95a1c48d", + "git_sha": "901fab507683647b43e7032f3ae9e4c234eb68eb", "installed_by": ["subworkflows"] }, "bam_markduplicates_picard": { "branch": "master", - "git_sha": "6daac2bc63f4847e0c7cc661f4f5b043ac13faaf", + "git_sha": "6f1697c121719dedde9e0537b6ed6a9cb8c13583", "installed_by": ["subworkflows"] }, "bam_rseqc": { "branch": "master", - "git_sha": "36a77f7c6decf2d1fb9f639ae982bc148d6828aa", + "git_sha": "b8f7bdc6f0e37f2946c84c5ac676c6030ebbf8c4", "installed_by": ["subworkflows"] }, "bam_sort_stats_samtools": { @@ -246,11 +246,11 @@ }, "bam_stats_samtools": { "branch": "master", - "git_sha": "92eb5091ae5368a60cda58b3a0ced8b36d715b0f", + "git_sha": "b4b7f89e7fd6d2293f0c176213f710e0bcdaf19e", "installed_by": [ - "bam_sort_stats_samtools", "bam_dedup_stats_samtools_umitools", - "bam_markduplicates_picard" + "bam_markduplicates_picard", + "bam_sort_stats_samtools" ] }, "bedgraph_bedclip_bedgraphtobigwig": { diff --git a/modules/nf-core/bbmap/bbsplit/meta.yml b/modules/nf-core/bbmap/bbsplit/meta.yml index 2b9ab8cbb..4cdc31a87 100644 --- a/modules/nf-core/bbmap/bbsplit/meta.yml +++ b/modules/nf-core/bbmap/bbsplit/meta.yml @@ -11,8 +11,7 @@ tools: description: BBMap is a short read aligner, as well as various other bioinformatic tools. homepage: https://jgi.doe.gov/data-and-tools/bbtools/bb-tools-user-guide/ documentation: https://jgi.doe.gov/data-and-tools/bbtools/bb-tools-user-guide/ - tool_dev_url: None - doi: "" + licence: ["UC-LBL license (see package)"] input: diff --git a/modules/nf-core/custom/dumpsoftwareversions/main.nf b/modules/nf-core/custom/dumpsoftwareversions/main.nf index 3df21765b..800a60991 100644 --- a/modules/nf-core/custom/dumpsoftwareversions/main.nf +++ b/modules/nf-core/custom/dumpsoftwareversions/main.nf @@ -2,10 +2,10 @@ process CUSTOM_DUMPSOFTWAREVERSIONS { label 'process_single' // Requires `pyyaml` which does not have a dedicated container but is in the MultiQC container - conda "bioconda::multiqc=1.13" + conda "bioconda::multiqc=1.14" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.13--pyhdfd78af_0' : - 'quay.io/biocontainers/multiqc:1.13--pyhdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/multiqc:1.14--pyhdfd78af_0' : + 'quay.io/biocontainers/multiqc:1.14--pyhdfd78af_0' }" input: path versions diff --git a/modules/nf-core/fq/subsample/meta.yml b/modules/nf-core/fq/subsample/meta.yml index 0134c8a73..9d93f8df0 100644 --- a/modules/nf-core/fq/subsample/meta.yml +++ b/modules/nf-core/fq/subsample/meta.yml @@ -9,7 +9,7 @@ tools: homepage: "https://github.com/stjude-rust-labs/fq" documentation: "https://github.com/stjude-rust-labs/fq" tool_dev_url: "https://github.com/stjude-rust-labs/fq" - doi: "" + licence: "['MIT']" input: diff --git a/modules/nf-core/gunzip/meta.yml b/modules/nf-core/gunzip/meta.yml index 4d2ebc84e..2e0e4054d 100644 --- a/modules/nf-core/gunzip/meta.yml +++ b/modules/nf-core/gunzip/meta.yml @@ -5,29 +5,29 @@ keywords: - 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"] + 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 ] + 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: "*.*" + type: file + description: File to be compressed/uncompressed + pattern: "*.*" output: - gunzip: - type: file - description: Compressed/uncompressed file - pattern: "*.*" + type: file + description: Compressed/uncompressed file + pattern: "*.*" - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + type: file + description: File containing software versions + pattern: "versions.yml" authors: - "@joseespinosa" - "@drpatelh" diff --git a/modules/nf-core/picard/markduplicates/main.nf b/modules/nf-core/picard/markduplicates/main.nf index 148003928..be243a958 100644 --- a/modules/nf-core/picard/markduplicates/main.nf +++ b/modules/nf-core/picard/markduplicates/main.nf @@ -2,10 +2,10 @@ process PICARD_MARKDUPLICATES { tag "$meta.id" label 'process_medium' - conda "bioconda::picard=2.27.4" + conda "bioconda::picard=3.0.0" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:2.27.4--hdfd78af_0' : - 'quay.io/biocontainers/picard:2.27.4--hdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/picard:3.0.0--hdfd78af_1' : + 'quay.io/biocontainers/picard:3.0.0--hdfd78af_1' }" input: tuple val(meta), path(bam) diff --git a/modules/nf-core/preseq/lcextrap/meta.yml b/modules/nf-core/preseq/lcextrap/meta.yml index f1be05a2f..1391961c8 100755 --- a/modules/nf-core/preseq/lcextrap/meta.yml +++ b/modules/nf-core/preseq/lcextrap/meta.yml @@ -10,7 +10,7 @@ tools: homepage: http://smithlabresearch.org/software/preseq/ documentation: http://smithlabresearch.org/wp-content/uploads/manual.pdf tool_dev_url: https://github.com/smithlabcode/preseq - doi: "" + licence: ["GPL"] input: diff --git a/modules/nf-core/rsem/calculateexpression/meta.yml b/modules/nf-core/rsem/calculateexpression/meta.yml index 8b89c7d11..680ede2e2 100644 --- a/modules/nf-core/rsem/calculateexpression/meta.yml +++ b/modules/nf-core/rsem/calculateexpression/meta.yml @@ -10,7 +10,7 @@ tools: RSEM: accurate transcript quantification from RNA-Seq data with or without a reference genome homepage: https://github.com/deweylab/RSEM documentation: https://github.com/deweylab/RSEM - doi: https://doi.org/10.1186/1471-2105-12-323 + doi: 10.1186/1471-2105-12-323 licence: ["GPL-3.0-or-later"] input: - meta: diff --git a/modules/nf-core/rsem/preparereference/meta.yml b/modules/nf-core/rsem/preparereference/meta.yml index fbe57b203..b1d013b9c 100644 --- a/modules/nf-core/rsem/preparereference/meta.yml +++ b/modules/nf-core/rsem/preparereference/meta.yml @@ -9,7 +9,7 @@ tools: RSEM: accurate transcript quantification from RNA-Seq data with or without a reference genome homepage: https://github.com/deweylab/RSEM documentation: https://github.com/deweylab/RSEM - doi: https://doi.org/10.1186/1471-2105-12-323 + doi: 10.1186/1471-2105-12-323 licence: ["GPL-3.0-or-later"] input: - fasta: diff --git a/modules/nf-core/rseqc/tin/meta.yml b/modules/nf-core/rseqc/tin/meta.yml index 6333ae14c..381edfde0 100644 --- a/modules/nf-core/rseqc/tin/meta.yml +++ b/modules/nf-core/rseqc/tin/meta.yml @@ -24,9 +24,9 @@ input: description: Input BAM file pattern: "*.{bam}" - bai: - type: file - description: Index for input BAM file - pattern: "*.{bai}" + type: file + description: Index for input BAM file + pattern: "*.{bai}" - bed: type: file description: BED file containing the reference gene model diff --git a/modules/nf-core/salmon/quant/meta.yml b/modules/nf-core/salmon/quant/meta.yml index 877c719df..ea01e0df8 100644 --- a/modules/nf-core/salmon/quant/meta.yml +++ b/modules/nf-core/salmon/quant/meta.yml @@ -34,12 +34,12 @@ input: type: file description: Fasta file of the reference transcriptome - alignment_mode: - type: boolean - description: whether to run salmon in alignment mode + type: boolean + description: whether to run salmon in alignment mode - lib_type: - type: string - description: | - Override library type inferred based on strandedness defined in meta object + type: string + description: | + Override library type inferred based on strandedness defined in meta object output: - results: diff --git a/modules/nf-core/samtools/flagstat/meta.yml b/modules/nf-core/samtools/flagstat/meta.yml index 952690639..954225dfc 100644 --- a/modules/nf-core/samtools/flagstat/meta.yml +++ b/modules/nf-core/samtools/flagstat/meta.yml @@ -14,7 +14,7 @@ tools: 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 + documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 licence: ["MIT"] input: diff --git a/modules/nf-core/samtools/idxstats/meta.yml b/modules/nf-core/samtools/idxstats/meta.yml index 3710ab882..dda87e1ee 100644 --- a/modules/nf-core/samtools/idxstats/meta.yml +++ b/modules/nf-core/samtools/idxstats/meta.yml @@ -15,7 +15,7 @@ tools: 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 + documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 licence: ["MIT"] input: diff --git a/modules/nf-core/samtools/index/meta.yml b/modules/nf-core/samtools/index/meta.yml index e5cadbc24..8bd2fa6fb 100644 --- a/modules/nf-core/samtools/index/meta.yml +++ b/modules/nf-core/samtools/index/meta.yml @@ -12,7 +12,7 @@ tools: 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 + documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 licence: ["MIT"] input: diff --git a/modules/nf-core/samtools/sort/meta.yml b/modules/nf-core/samtools/sort/meta.yml index 092897512..073284316 100644 --- a/modules/nf-core/samtools/sort/meta.yml +++ b/modules/nf-core/samtools/sort/meta.yml @@ -12,7 +12,7 @@ tools: 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 + documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 licence: ["MIT"] input: diff --git a/modules/nf-core/samtools/stats/meta.yml b/modules/nf-core/samtools/stats/meta.yml index cac50b1c0..1d68a5d83 100644 --- a/modules/nf-core/samtools/stats/meta.yml +++ b/modules/nf-core/samtools/stats/meta.yml @@ -13,7 +13,7 @@ tools: 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 + documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 licence: ["MIT"] input: @@ -23,13 +23,13 @@ input: Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - input: - type: file - description: BAM/CRAM file from alignment - pattern: "*.{bam,cram}" + type: file + description: BAM/CRAM file from alignment + pattern: "*.{bam,cram}" - input_index: - type: file - description: BAI/CRAI file from alignment - pattern: "*.{bai,crai}" + type: file + description: BAI/CRAI file from alignment + pattern: "*.{bai,crai}" - fasta: type: optional file description: Reference file the CRAM was created with diff --git a/modules/nf-core/ucsc/bedclip/meta.yml b/modules/nf-core/ucsc/bedclip/meta.yml index e6dd8cebc..ca278552a 100755 --- a/modules/nf-core/ucsc/bedclip/meta.yml +++ b/modules/nf-core/ucsc/bedclip/meta.yml @@ -5,10 +5,7 @@ keywords: tools: - ucsc: description: Remove lines from bed file that refer to off-chromosome locations. - homepage: None - documentation: None - tool_dev_url: None - doi: "" + homepage: http://hgdownload.cse.ucsc.edu/admin/exe/ licence: ["varies; see http://genome.ucsc.edu/license"] input: diff --git a/modules/nf-core/ucsc/bedgraphtobigwig/meta.yml b/modules/nf-core/ucsc/bedgraphtobigwig/meta.yml index 1be1a3b7f..ba8915bed 100755 --- a/modules/nf-core/ucsc/bedgraphtobigwig/meta.yml +++ b/modules/nf-core/ucsc/bedgraphtobigwig/meta.yml @@ -6,10 +6,8 @@ keywords: tools: - ucsc: description: Convert a bedGraph file to bigWig format. - homepage: None - documentation: None - tool_dev_url: None - doi: "" + homepage: http://hgdownload.cse.ucsc.edu/admin/exe/ + documentation: https://genome.ucsc.edu/goldenPath/help/bigWig.html licence: ["varies; see http://genome.ucsc.edu/license"] input: diff --git a/modules/nf-core/umitools/dedup/main.nf b/modules/nf-core/umitools/dedup/main.nf index 642001389..68fc9b9e7 100644 --- a/modules/nf-core/umitools/dedup/main.nf +++ b/modules/nf-core/umitools/dedup/main.nf @@ -1,11 +1,11 @@ process UMITOOLS_DEDUP { tag "$meta.id" - label "process_medium" + label "process_single" - conda "bioconda::umi_tools=1.1.2" + conda "bioconda::umi_tools=1.1.4" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/umi_tools:1.1.2--py38h4a8c8d9_0' : - 'quay.io/biocontainers/umi_tools:1.1.2--py38h4a8c8d9_0' }" + 'https://depot.galaxyproject.org/singularity/umi_tools:1.1.4--py38hbff2b2d_1' : + 'quay.io/biocontainers/umi_tools:1.1.4--py38hbff2b2d_1' }" input: tuple val(meta), path(bam), path(bai) diff --git a/modules/nf-core/umitools/dedup/meta.yml b/modules/nf-core/umitools/dedup/meta.yml index 56888e5a6..0719a9552 100644 --- a/modules/nf-core/umitools/dedup/meta.yml +++ b/modules/nf-core/umitools/dedup/meta.yml @@ -5,57 +5,57 @@ keywords: - 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"] + 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 + 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}" + 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}" + type: file + description: | + BAM index files corresponding to the input BAM file. + pattern: "*.{bai}" - get_output_stats: - type: boolean - description: | - Whether or not to generate output stats. + type: boolean + description: | + Whether or not to generate output stats. output: - meta: - type: map - description: | - Groovy Map containing sample information + 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}" + type: file + description: BAM file with deduplicated UMIs. + pattern: "*.{bam}" - tsv_edit_distance: - type: file - description: Reports the (binned) average edit distance between the UMIs at each position. - pattern: "*edit_distance.tsv" + type: file + description: Reports the (binned) average edit distance between the UMIs at each position. + pattern: "*edit_distance.tsv" - tsv_per_umi: - type: file - description: UMI-level summary statistics. - pattern: "*per_umi.tsv" + type: file + description: UMI-level summary statistics. + pattern: "*per_umi.tsv" - tsv_umi_per_position: - type: file - description: Tabulates the counts for unique combinations of UMI and position. - pattern: "*per_position.tsv" + type: file + description: Tabulates the counts for unique combinations of UMI and position. + pattern: "*per_position.tsv" - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + type: file + description: File containing software versions + pattern: "versions.yml" authors: - "@drpatelh" diff --git a/modules/nf-core/umitools/extract/main.nf b/modules/nf-core/umitools/extract/main.nf index 731f164c2..ba2826e1f 100644 --- a/modules/nf-core/umitools/extract/main.nf +++ b/modules/nf-core/umitools/extract/main.nf @@ -1,11 +1,11 @@ process UMITOOLS_EXTRACT { tag "$meta.id" - label "process_low" + label "process_single" - conda "bioconda::umi_tools=1.1.2" + conda "bioconda::umi_tools=1.1.4" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/umi_tools:1.1.2--py38h4a8c8d9_0' : - 'quay.io/biocontainers/umi_tools:1.1.2--py38h4a8c8d9_0' }" + 'https://depot.galaxyproject.org/singularity/umi_tools:1.1.4--py38hbff2b2d_1' : + 'quay.io/biocontainers/umi_tools:1.1.4--py38hbff2b2d_1' }" input: tuple val(meta), path(reads) diff --git a/modules/nf-core/umitools/extract/meta.yml b/modules/nf-core/umitools/extract/meta.yml index 7fc23f722..db64a0f88 100644 --- a/modules/nf-core/umitools/extract/meta.yml +++ b/modules/nf-core/umitools/extract/meta.yml @@ -5,42 +5,42 @@ keywords: - 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"] + 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 + 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. + type: list + description: | + List of input FASTQ files whose UMIs will be extracted. output: - meta: - type: map - description: | - Groovy Map containing sample information + 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. | + 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}" + pattern: "*.{fastq.gz}" - log: - type: file - description: Logfile for umi_tools - pattern: "*.{log}" + type: file + description: Logfile for umi_tools + pattern: "*.{log}" - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + type: file + description: File containing software versions + pattern: "versions.yml" authors: - "@drpatelh" diff --git a/modules/nf-core/untar/main.nf b/modules/nf-core/untar/main.nf index 16bccc905..3384847aa 100644 --- a/modules/nf-core/untar/main.nf +++ b/modules/nf-core/untar/main.nf @@ -2,7 +2,7 @@ process UNTAR { tag "$archive" label 'process_single' - conda "conda-forge::sed=4.7" + conda "conda-forge::sed=4.7 bioconda::grep=3.4 conda-forge::tar=1.34" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/ubuntu:20.04' : 'ubuntu:20.04' }" @@ -11,8 +11,8 @@ process UNTAR { tuple val(meta), path(archive) output: - tuple val(meta), path("$untar"), emit: untar - path "versions.yml" , emit: versions + tuple val(meta), path("$prefix"), emit: untar + path "versions.yml" , emit: versions when: task.ext.when == null || task.ext.when @@ -20,31 +20,29 @@ process UNTAR { script: def args = task.ext.args ?: '' def args2 = task.ext.args2 ?: '' - untar = archive.toString() - '.tar.gz' + prefix = task.ext.prefix ?: ( meta.id ? "${meta.id}" : archive.baseName.toString().replaceFirst(/\.tar$/, "")) """ - mkdir output + mkdir $prefix ## Ensures --strip-components only applied when top level of tar contents is a directory - ## If just files or multiple directories, place all in output - if [[ \$(tar -tzf ${archive} | grep -o -P "^.*?\\/" | uniq | wc -l) -eq 1 ]]; then + ## If just files or multiple directories, place all in prefix + if [[ \$(tar -taf ${archive} | grep -o -P "^.*?\\/" | uniq | wc -l) -eq 1 ]]; then tar \\ - -C output --strip-components 1 \\ - -xzvf \\ + -C $prefix --strip-components 1 \\ + -xavf \\ $args \\ $archive \\ $args2 else tar \\ - -C output \\ - -xzvf \\ + -C $prefix \\ + -xavf \\ $args \\ $archive \\ $args2 fi - mv output ${untar} - cat <<-END_VERSIONS > versions.yml "${task.process}": untar: \$(echo \$(tar --version 2>&1) | sed 's/^.*(GNU tar) //; s/ Copyright.*\$//') @@ -52,9 +50,10 @@ process UNTAR { """ stub: - untar = archive.toString() - '.tar.gz' + prefix = task.ext.prefix ?: ( meta.id ? "${meta.id}" : archive.toString().replaceFirst(/\.[^\.]+(.gz)?$/, "")) """ - touch $untar + mkdir $prefix + touch ${prefix}/file.txt cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/main.nf b/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/main.nf index 9d4294f1c..6b9e2e7a0 100644 --- a/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/main.nf +++ b/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/main.nf @@ -8,8 +8,8 @@ include { BAM_STATS_SAMTOOLS } from '../bam_stats_samtools/main' workflow BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS { take: - bam_bai // channel: [ val(meta), [ bam ], [ bai/csi ] ] - get_dedup_stats // boolean: true/false + ch_bam_bai // channel: [ val(meta), path(bam), path(bai/csi) ] + val_get_dedup_stats // boolean: true/false main: @@ -18,7 +18,7 @@ workflow BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS { // // UMI-tools dedup // - UMITOOLS_DEDUP ( bam_bai, get_dedup_stats ) + UMITOOLS_DEDUP ( ch_bam_bai, val_get_dedup_stats ) ch_versions = ch_versions.mix(UMITOOLS_DEDUP.out.versions.first()) // @@ -27,7 +27,7 @@ workflow BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS { SAMTOOLS_INDEX ( UMITOOLS_DEDUP.out.bam ) ch_versions = ch_versions.mix(SAMTOOLS_INDEX.out.versions.first()) - UMITOOLS_DEDUP.out.bam + ch_bam_bai_dedup = UMITOOLS_DEDUP.out.bam .join(SAMTOOLS_INDEX.out.bai, by: [0], remainder: true) .join(SAMTOOLS_INDEX.out.csi, by: [0], remainder: true) .map { @@ -38,19 +38,18 @@ workflow BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS { [ meta, bam, csi ] } } - .set { ch_bam_bai } - BAM_STATS_SAMTOOLS ( ch_bam_bai, [] ) + BAM_STATS_SAMTOOLS ( ch_bam_bai_dedup, [] ) ch_versions = ch_versions.mix(BAM_STATS_SAMTOOLS.out.versions) emit: - bam = UMITOOLS_DEDUP.out.bam // channel: [ val(meta), [ bam ] ] + bam = UMITOOLS_DEDUP.out.bam // channel: [ val(meta), path(bam) ] - bai = SAMTOOLS_INDEX.out.bai // channel: [ val(meta), [ bai ] ] - csi = SAMTOOLS_INDEX.out.csi // channel: [ val(meta), [ csi ] ] - stats = BAM_STATS_SAMTOOLS.out.stats // channel: [ val(meta), [ stats ] ] - flagstat = BAM_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), [ flagstat ] ] - idxstats = BAM_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), [ idxstats ] ] + bai = SAMTOOLS_INDEX.out.bai // channel: [ val(meta), path(bai) ] + csi = SAMTOOLS_INDEX.out.csi // channel: [ val(meta), path(csi) ] + stats = BAM_STATS_SAMTOOLS.out.stats // channel: [ val(meta), path(stats) ] + flagstat = BAM_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), path(flagstat) ] + idxstats = BAM_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), path(idxstats) ] - versions = ch_versions // channel: [ versions.yml ] + versions = ch_versions // channel: [ path(versions.yml) ] } diff --git a/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/meta.yml b/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/meta.yml index a3b29479d..c5ecdb01a 100644 --- a/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/meta.yml +++ b/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/meta.yml @@ -14,43 +14,44 @@ modules: - samtools/idxstats - samtools/flagstat input: - - bam_bai: - type: file - description: BAM/CRAM/SAM file - pattern: "*.{bam,cram,sam}" - - get_dedup_stats: + - ch_bam_bai: + description: | + input BAM file + Structure: [ val(meta), path(bam), path(bai) ] + - val_get_dedup_stats: type: boolean description: | Generate output stats when running "umi_tools dedup" output: - bam: - type: file - description: Umi deduplicated BAM/CRAM/SAM file - pattern: "*.{bam,cram,sam}" + description: | + Umi deduplicated BAM/SAM file + Structure: [ val(meta), path(bam) ] - bai: - type: file - description: Umi deduplicated BAM/CRAM/SAM samtools index - pattern: "*.{bai,crai,sai}" + description: | + Umi deduplicated BAM/SAM samtools index + Structure: [ val(meta), path(bai) ] - csi: - type: file - description: CSI samtools index - pattern: "*.csi" + description: | + CSI samtools index + Structure: [ val(meta), path(csi) ] - stats: - type: file - description: File containing samtools stats output - pattern: "*.{stats}" + description: | + File containing samtools stats output + Structure: [ val(meta), path(stats) ] - flagstat: - type: file - description: File containing samtools flagstat output - pattern: "*.{flagstat}" + description: | + File containing samtools flagstat output + Structure: [ val(meta), path(flagstat) ] - idxstats: - type: file - description: File containing samtools idxstats output - pattern: "*.{idxstats}" + description: | + File containing samtools idxstats output + Structure: [ val(meta), path(idxstats) ] - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + description: | + Files containing software versions + Structure: [ path(versions.yml) ] + authors: - "@drpatelh" - "@KamilMaliszArdigen" diff --git a/subworkflows/nf-core/bam_markduplicates_picard/main.nf b/subworkflows/nf-core/bam_markduplicates_picard/main.nf index 9cb24cdc3..6e3df3320 100644 --- a/subworkflows/nf-core/bam_markduplicates_picard/main.nf +++ b/subworkflows/nf-core/bam_markduplicates_picard/main.nf @@ -9,9 +9,9 @@ include { BAM_STATS_SAMTOOLS } from '../bam_stats_samtools/main' workflow BAM_MARKDUPLICATES_PICARD { take: - ch_bam // channel: [ val(meta), [ bam ] ] - ch_fasta // channel: [ fasta ] - ch_fai // channel: [ fai ] + ch_bam // channel: [ val(meta), path(bam) ] + ch_fasta // channel: [ path(fasta) ] + ch_fai // channel: [ path(fai) ] main: @@ -23,7 +23,7 @@ workflow BAM_MARKDUPLICATES_PICARD { SAMTOOLS_INDEX ( PICARD_MARKDUPLICATES.out.bam ) ch_versions = ch_versions.mix(SAMTOOLS_INDEX.out.versions.first()) - PICARD_MARKDUPLICATES.out.bam + ch_bam_bai = PICARD_MARKDUPLICATES.out.bam .join(SAMTOOLS_INDEX.out.bai, by: [0], remainder: true) .join(SAMTOOLS_INDEX.out.csi, by: [0], remainder: true) .map { @@ -34,20 +34,19 @@ workflow BAM_MARKDUPLICATES_PICARD { [ meta, bam, csi ] } } - .set { ch_bam_bai } BAM_STATS_SAMTOOLS ( ch_bam_bai, ch_fasta ) ch_versions = ch_versions.mix(BAM_STATS_SAMTOOLS.out.versions) emit: - bam = PICARD_MARKDUPLICATES.out.bam // channel: [ val(meta), [ bam ] ] - metrics = PICARD_MARKDUPLICATES.out.metrics // channel: [ val(meta), [ bam ] ] - bai = SAMTOOLS_INDEX.out.bai // channel: [ val(meta), [ bai ] ] - csi = SAMTOOLS_INDEX.out.csi // channel: [ val(meta), [ csi ] ] - - stats = BAM_STATS_SAMTOOLS.out.stats // channel: [ val(meta), [ stats ] ] - flagstat = BAM_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), [ flagstat ] ] - idxstats = BAM_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), [ idxstats ] ] + bam = PICARD_MARKDUPLICATES.out.bam // channel: [ val(meta), path(bam) ] + metrics = PICARD_MARKDUPLICATES.out.metrics // channel: [ val(meta), path(bam) ] + bai = SAMTOOLS_INDEX.out.bai // channel: [ val(meta), path(bai) ] + csi = SAMTOOLS_INDEX.out.csi // channel: [ val(meta), path(csi) ] + + stats = BAM_STATS_SAMTOOLS.out.stats // channel: [ val(meta), path(stats) ] + flagstat = BAM_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), path(flagstat) ] + idxstats = BAM_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), path(idxstats) ] versions = ch_versions // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/bam_markduplicates_picard/meta.yml b/subworkflows/nf-core/bam_markduplicates_picard/meta.yml index fdd9f8d1c..822c61328 100644 --- a/subworkflows/nf-core/bam_markduplicates_picard/meta.yml +++ b/subworkflows/nf-core/bam_markduplicates_picard/meta.yml @@ -14,48 +14,47 @@ modules: - samtools/flagstat input: - - meta: - type: map + - ch_bam: description: | - Groovy Map containing sample information - e.g. [ id:'test' ] - - bam: - type: file - description: BAM/CRAM/SAM file - pattern: "*.{bam,cram,sam}" - - fasta: - type: file - description: Reference genome fasta file - pattern: "*.{fasta,fa}" - + BAM/CRAM/SAM file + Structure: [ val(meta), path(bam) ] + - ch_fasta: + description: | + Reference genome fasta file + Structure: [ path(fasta) ] + - ch_fasta: + description: | + Index of the reference genome fasta file + Structure: [ path(fai) ] output: - - meta: - type: map + - bam: description: | - Groovy Map containing sample information - e.g. [ id:'test' ] + processed BAM/CRAM/SAM file + Structure: [ val(meta), path(bam) ] - bai: - type: file - description: BAM/CRAM/SAM samtools index - pattern: "*.{bai,crai,sai}" + description: | + BAM/CRAM/SAM samtools index + Structure: [ val(meta), path(bai) ] - csi: - type: file - description: CSI samtools index - pattern: "*.csi" + description: | + CSI samtools index + Structure: [ val(meta), path(csi) ] - stats: - type: file - description: File containing samtools stats output + description: | + File containing samtools stats output + Structure: [ val(meta), path(stats) ] - flagstat: - type: file - description: File containing samtools flagstat output + description: | + File containing samtools flagstat output + Structure: [ val(meta), path(flagstat) ] - idxstats: - type: file - description: File containing samtools idxstats output - pattern: "*.{idxstats}" + description: | + File containing samtools idxstats output + Structure: [ val(meta), path(idxstats) ] - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + description: | + Files containing software versions + Structure: [ path(versions.yml) ] authors: - "@dmarron" - "@drpatelh" diff --git a/subworkflows/nf-core/bam_rseqc/meta.yml b/subworkflows/nf-core/bam_rseqc/meta.yml index 1e1fa18dc..cc074c21f 100644 --- a/subworkflows/nf-core/bam_rseqc/meta.yml +++ b/subworkflows/nf-core/bam_rseqc/meta.yml @@ -31,9 +31,9 @@ input: description: BAM file to calculate statistics pattern: "*.{bam}" - bai: - type: file - description: Index for input BAM file - pattern: "*.{bai}" + type: file + description: Index for input BAM file + pattern: "*.{bai}" - bed: type: file description: BED file for the reference gene model diff --git a/subworkflows/nf-core/bam_stats_samtools/main.nf b/subworkflows/nf-core/bam_stats_samtools/main.nf index cfcc48dd6..c9d7c8b75 100644 --- a/subworkflows/nf-core/bam_stats_samtools/main.nf +++ b/subworkflows/nf-core/bam_stats_samtools/main.nf @@ -8,25 +8,25 @@ include { SAMTOOLS_FLAGSTAT } from '../../../modules/nf-core/samtools/flagstat/m workflow BAM_STATS_SAMTOOLS { take: - bam_bai // channel: [ val(meta), [ bam/cram ], [bai/csi] ] - fasta // channel: [ fasta ] + ch_bam_bai // channel: [ val(meta), path(bam), path(bai) ] + ch_fasta // channel: [ path(fasta) ] main: ch_versions = Channel.empty() - SAMTOOLS_STATS ( bam_bai, fasta ) + SAMTOOLS_STATS ( ch_bam_bai, ch_fasta ) ch_versions = ch_versions.mix(SAMTOOLS_STATS.out.versions) - SAMTOOLS_FLAGSTAT ( bam_bai ) + SAMTOOLS_FLAGSTAT ( ch_bam_bai ) ch_versions = ch_versions.mix(SAMTOOLS_FLAGSTAT.out.versions) - SAMTOOLS_IDXSTATS ( bam_bai ) + SAMTOOLS_IDXSTATS ( ch_bam_bai ) ch_versions = ch_versions.mix(SAMTOOLS_IDXSTATS.out.versions) emit: - stats = SAMTOOLS_STATS.out.stats // channel: [ val(meta), [ stats ] ] - flagstat = SAMTOOLS_FLAGSTAT.out.flagstat // channel: [ val(meta), [ flagstat ] ] - idxstats = SAMTOOLS_IDXSTATS.out.idxstats // channel: [ val(meta), [ idxstats ] ] + stats = SAMTOOLS_STATS.out.stats // channel: [ val(meta), path(stats) ] + flagstat = SAMTOOLS_FLAGSTAT.out.flagstat // channel: [ val(meta), path(flagstat) ] + idxstats = SAMTOOLS_IDXSTATS.out.idxstats // channel: [ val(meta), path(idxstats) ] - versions = ch_versions // channel: [ versions.yml ] + versions = ch_versions // channel: [ path(versions.yml) ] } diff --git a/subworkflows/nf-core/bam_stats_samtools/meta.yml b/subworkflows/nf-core/bam_stats_samtools/meta.yml index 5252b0e42..b6072686e 100644 --- a/subworkflows/nf-core/bam_stats_samtools/meta.yml +++ b/subworkflows/nf-core/bam_stats_samtools/meta.yml @@ -11,44 +11,30 @@ modules: - samtools/idxstats - samtools/flagstat input: - - meta: - type: map + - ch_bam_bai: 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}" - - fasta: - type: file - description: Reference genome fasta file - pattern: "*.{fasta,fa}" -output: - - meta: - type: map + The input channel containing the BAM/CRAM and it's index + Structure: [ val(meta), path(bam), path(bai) ] + - ch_fasta: description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] + Reference genome fasta file + Structure: [ path(fasta) ] +output: - stats: - type: file - description: File containing samtools stats output - pattern: "*.{stats}" + description: | + File containing samtools stats output + Structure: [ val(meta), path(stats) ] - flagstat: - type: file - description: File containing samtools flagstat output - pattern: "*.{flagstat}" + description: | + File containing samtools flagstat output + Structure: [ val(meta), path(flagstat) ] - idxstats: - type: file - description: File containing samtools idxstats output - pattern: "*.{idxstats}" + description: | + File containing samtools idxstats output + Structure: [ val(meta), path(idxstats)] - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + description: | + Files containing software versions + Structure: [ path(versions.yml) ] authors: - "@drpatelh" From 54ef6f2aef6bcfd28e5f80d6947e28dd8cca4f1c Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 14 Mar 2023 21:54:13 +0000 Subject: [PATCH 040/124] Update local modules --- modules/local/multiqc.nf | 6 +++--- modules/local/umitools_prepareforrsem.nf | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/local/multiqc.nf b/modules/local/multiqc.nf index 4da19f3fc..b50d44c7d 100644 --- a/modules/local/multiqc.nf +++ b/modules/local/multiqc.nf @@ -1,10 +1,10 @@ process MULTIQC { label 'process_medium' - conda "bioconda::multiqc=1.13" + conda "bioconda::multiqc=1.14" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.13--pyhdfd78af_0' : - 'quay.io/biocontainers/multiqc:1.13--pyhdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/multiqc:1.14--pyhdfd78af_0' : + 'quay.io/biocontainers/multiqc:1.14--pyhdfd78af_0' }" input: path multiqc_config diff --git a/modules/local/umitools_prepareforrsem.nf b/modules/local/umitools_prepareforrsem.nf index 516e33266..416df567e 100644 --- a/modules/local/umitools_prepareforrsem.nf +++ b/modules/local/umitools_prepareforrsem.nf @@ -2,10 +2,10 @@ process UMITOOLS_PREPAREFORRSEM { tag "$meta.id" label 'process_medium' - conda "bioconda::umi_tools=1.1.2" + conda "bioconda::umi_tools=1.1.4" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/umi_tools:1.1.2--py38h4a8c8d9_0' : - 'quay.io/biocontainers/umi_tools:1.1.2--py38h4a8c8d9_0' }" + 'https://depot.galaxyproject.org/singularity/umi_tools:1.1.4--py38hbff2b2d_1' : + 'quay.io/biocontainers/umi_tools:1.1.4--py38hbff2b2d_1' }" input: tuple val(meta), path(bam) From 12a8027243d9aa01766aa89ebc3583ec99bba2a4 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Wed, 15 Mar 2023 10:37:27 +0000 Subject: [PATCH 041/124] Initialise as value channels in prepare_genome.nf --- subworkflows/local/prepare_genome.nf | 114 +++++++++++++++------------ workflows/rnaseq.nf | 19 ++++- 2 files changed, 80 insertions(+), 53 deletions(-) diff --git a/subworkflows/local/prepare_genome.nf b/subworkflows/local/prepare_genome.nf index 1b99df670..4f7562407 100644 --- a/subworkflows/local/prepare_genome.nf +++ b/subworkflows/local/prepare_genome.nf @@ -33,9 +33,23 @@ include { STAR_GENOMEGENERATE_IGENOMES } from '../../modules/local/star_ workflow PREPARE_GENOME { take: - prepare_tool_indices // list : tools to prepare indices for - biotype // string : if additional fasta file is provided biotype value to use when appending entries to GTF file - is_aws_igenome // boolean: whether the genome files are from AWS iGenomes + fasta // file: /path/to/genome.fasta + gtf // file: /path/to/genome.gtf + gff // file: /path/to/genome.gff + additional_fasta // file: /path/to/additional.fasta + transcript_fasta // file: /path/to/transcript.fasta + gene_bed // file: /path/to/gene.bed + splicesites // file: /path/to/splicesites.txt + bbsplit_fasta_list // file: /path/to/bbsplit_fasta_list.txt + star_index // directory: /path/to/star/index/ + rsem_index // directory: /path/to/rsem/index/ + salmon_index // directory: /path/to/salmon/index/ + hisat2_index // directory: /path/to/hisat2/index/ + bbsplit_index // directory: /path/to/rsem/index/ + gencode // boolean: whether the genome is from GENCODE + is_aws_igenome // boolean: whether the genome files are from AWS iGenomes + biotype // string: if additional fasta file is provided biotype value to use when appending entries to GTF file + prepare_tool_indices // list: tools to prepare indices for main: @@ -44,29 +58,29 @@ workflow PREPARE_GENOME { // // Uncompress genome fasta file if required // - if (params.fasta.endsWith('.gz')) { - ch_fasta = GUNZIP_FASTA ( [ [:], params.fasta ] ).gunzip.map { it[1] } + if (fasta.endsWith('.gz')) { + ch_fasta = GUNZIP_FASTA ( [ [:], fasta ] ).gunzip.map { it[1] } ch_versions = ch_versions.mix(GUNZIP_FASTA.out.versions) } else { - ch_fasta = file(params.fasta) + ch_fasta = Channel.value(file(fasta)) } // // Uncompress GTF annotation file or create from GFF3 if required // - if (params.gtf) { - if (params.gtf.endsWith('.gz')) { - ch_gtf = GUNZIP_GTF ( [ [:], params.gtf ] ).gunzip.map { it[1] } + if (gtf) { + if (gtf.endsWith('.gz')) { + ch_gtf = GUNZIP_GTF ( [ [:], gtf ] ).gunzip.map { it[1] } ch_versions = ch_versions.mix(GUNZIP_GTF.out.versions) } else { - ch_gtf = file(params.gtf) + ch_gtf = Channel.value(file(gtf)) } - } else if (params.gff) { - if (params.gff.endsWith('.gz')) { - ch_gff = GUNZIP_GFF ( [ [:], params.gff ] ).gunzip.map { it[1] } + } else if (gff) { + if (gff.endsWith('.gz')) { + ch_gff = GUNZIP_GFF ( [ [:], gff ] ).gunzip.map { it[1] } ch_versions = ch_versions.mix(GUNZIP_GFF.out.versions) } else { - ch_gff = file(params.gff) + ch_gff = Channel.value(file(gff)) } ch_gtf = GFFREAD ( ch_gff ).gtf ch_versions = ch_versions.mix(GFFREAD.out.versions) @@ -75,12 +89,12 @@ workflow PREPARE_GENOME { // // Uncompress additional fasta file and concatenate with reference fasta and gtf files // - if (params.additional_fasta) { - if (params.additional_fasta.endsWith('.gz')) { - ch_add_fasta = GUNZIP_ADDITIONAL_FASTA ( [ [:], params.additional_fasta ] ).gunzip.map { it[1] } + if (additional_fasta) { + if (additional_fasta.endsWith('.gz')) { + ch_add_fasta = GUNZIP_ADDITIONAL_FASTA ( [ [:], additional_fasta ] ).gunzip.map { it[1] } ch_versions = ch_versions.mix(GUNZIP_ADDITIONAL_FASTA.out.versions) } else { - ch_add_fasta = file(params.additional_fasta) + ch_add_fasta = Channel.value(file(additional_fasta)) } CAT_ADDITIONAL_FASTA ( ch_fasta, ch_gtf, ch_add_fasta, biotype ) ch_fasta = CAT_ADDITIONAL_FASTA.out.fasta @@ -91,12 +105,12 @@ workflow PREPARE_GENOME { // // Uncompress gene BED annotation file or create from GTF if required // - if (params.gene_bed) { - if (params.gene_bed.endsWith('.gz')) { - ch_gene_bed = GUNZIP_GENE_BED ( [ [:], params.gene_bed ] ).gunzip.map { it[1] } + if (gene_bed) { + if (gene_bed.endsWith('.gz')) { + ch_gene_bed = GUNZIP_GENE_BED ( [ [:], gene_bed ] ).gunzip.map { it[1] } ch_versions = ch_versions.mix(GUNZIP_GENE_BED.out.versions) } else { - ch_gene_bed = file(params.gene_bed) + ch_gene_bed = Channel.value(file(gene_bed)) } } else { ch_gene_bed = GTF2BED ( ch_gtf ).bed @@ -106,14 +120,14 @@ workflow PREPARE_GENOME { // // Uncompress transcript fasta file / create if required // - if (params.transcript_fasta) { - if (params.transcript_fasta.endsWith('.gz')) { - ch_transcript_fasta = GUNZIP_TRANSCRIPT_FASTA ( [ [:], params.transcript_fasta ] ).gunzip.map { it[1] } + if (transcript_fasta) { + if (transcript_fasta.endsWith('.gz')) { + ch_transcript_fasta = GUNZIP_TRANSCRIPT_FASTA ( [ [:], transcript_fasta ] ).gunzip.map { it[1] } ch_versions = ch_versions.mix(GUNZIP_TRANSCRIPT_FASTA.out.versions) } else { - ch_transcript_fasta = file(params.transcript_fasta) + ch_transcript_fasta = Channel.value(file(transcript_fasta)) } - if (params.gencode) { + if (gencode) { PREPROCESS_TRANSCRIPTS_FASTA_GENCODE ( ch_transcript_fasta ) ch_transcript_fasta = PREPROCESS_TRANSCRIPTS_FASTA_GENCODE.out.fasta ch_versions = ch_versions.mix(PREPROCESS_TRANSCRIPTS_FASTA_GENCODE.out.versions) @@ -138,16 +152,16 @@ workflow PREPARE_GENOME { // ch_bbsplit_index = Channel.empty() if ('bbsplit' in prepare_tool_indices) { - if (params.bbsplit_index) { - if (params.bbsplit_index.endsWith('.tar.gz')) { - ch_bbsplit_index = UNTAR_BBSPLIT_INDEX ( [ [:], params.bbsplit_index ] ).untar.map { it[1] } + if (bbsplit_index) { + if (bbsplit_index.endsWith('.tar.gz')) { + ch_bbsplit_index = UNTAR_BBSPLIT_INDEX ( [ [:], bbsplit_index ] ).untar.map { it[1] } ch_versions = ch_versions.mix(UNTAR_BBSPLIT_INDEX.out.versions) } else { - ch_bbsplit_index = file(params.bbsplit_index) + ch_bbsplit_index = Channel.value(file(bbsplit_index)) } } else { Channel - .from(file(params.bbsplit_fasta_list)) + .from(file(bbsplit_fasta_list)) .splitCsv() // Read in 2 column csv file: short_name,path_to_fasta .flatMap { id, fasta -> [ [ 'id', id ], [ 'fasta', file(fasta, checkIfExists: true) ] ] } // Flatten entries to be able to groupTuple by a common key .groupTuple() @@ -165,12 +179,12 @@ workflow PREPARE_GENOME { // ch_star_index = Channel.empty() if ('star_salmon' in prepare_tool_indices) { - if (params.star_index) { - if (params.star_index.endsWith('.tar.gz')) { - ch_star_index = UNTAR_STAR_INDEX ( [ [:], params.star_index ] ).untar.map { it[1] } + if (star_index) { + if (star_index.endsWith('.tar.gz')) { + ch_star_index = UNTAR_STAR_INDEX ( [ [:], star_index ] ).untar.map { it[1] } ch_versions = ch_versions.mix(UNTAR_STAR_INDEX.out.versions) } else { - ch_star_index = file(params.star_index) + ch_star_index = Channel.value(file(star_index)) } } else { if (is_aws_igenome) { @@ -188,12 +202,12 @@ workflow PREPARE_GENOME { // ch_rsem_index = Channel.empty() if ('star_rsem' in prepare_tool_indices) { - if (params.rsem_index) { - if (params.rsem_index.endsWith('.tar.gz')) { - ch_rsem_index = UNTAR_RSEM_INDEX ( [ [:], params.rsem_index ] ).untar.map { it[1] } + if (rsem_index) { + if (rsem_index.endsWith('.tar.gz')) { + ch_rsem_index = UNTAR_RSEM_INDEX ( [ [:], rsem_index ] ).untar.map { it[1] } ch_versions = ch_versions.mix(UNTAR_RSEM_INDEX.out.versions) } else { - ch_rsem_index = file(params.rsem_index) + ch_rsem_index = Channel.value(file(rsem_index)) } } else { ch_rsem_index = RSEM_PREPAREREFERENCE_GENOME ( ch_fasta, ch_gtf ).index @@ -207,18 +221,18 @@ workflow PREPARE_GENOME { ch_splicesites = Channel.empty() ch_hisat2_index = Channel.empty() if ('hisat2' in prepare_tool_indices) { - if (!params.splicesites) { + if (!splicesites) { ch_splicesites = HISAT2_EXTRACTSPLICESITES ( ch_gtf ).txt ch_versions = ch_versions.mix(HISAT2_EXTRACTSPLICESITES.out.versions) } else { - ch_splicesites = file(params.splicesites) + ch_splicesites = Channel.value(file(splicesites)) } - if (params.hisat2_index) { - if (params.hisat2_index.endsWith('.tar.gz')) { - ch_hisat2_index = UNTAR_HISAT2_INDEX ( [ [:], params.hisat2_index ] ).untar.map { it[1] } + if (hisat2_index) { + if (hisat2_index.endsWith('.tar.gz')) { + ch_hisat2_index = UNTAR_HISAT2_INDEX ( [ [:], hisat2_index ] ).untar.map { it[1] } ch_versions = ch_versions.mix(UNTAR_HISAT2_INDEX.out.versions) } else { - ch_hisat2_index = file(params.hisat2_index) + ch_hisat2_index = Channel.value(file(hisat2_index)) } } else { ch_hisat2_index = HISAT2_BUILD ( ch_fasta, ch_gtf, ch_splicesites ).index @@ -230,12 +244,12 @@ workflow PREPARE_GENOME { // Uncompress Salmon index or generate from scratch if required // ch_salmon_index = Channel.empty() - if (params.salmon_index) { - if (params.salmon_index.endsWith('.tar.gz')) { - ch_salmon_index = UNTAR_SALMON_INDEX ( [ [:], params.salmon_index ] ).untar.map { it[1] } + if (salmon_index) { + if (salmon_index.endsWith('.tar.gz')) { + ch_salmon_index = UNTAR_SALMON_INDEX ( [ [:], salmon_index ] ).untar.map { it[1] } ch_versions = ch_versions.mix(UNTAR_SALMON_INDEX.out.versions) } else { - ch_salmon_index = file(params.salmon_index) + ch_salmon_index = Channel.value(file(salmon_index)) } } else { if ('salmon' in prepare_tool_indices) { diff --git a/workflows/rnaseq.nf b/workflows/rnaseq.nf index 6dc57e72d..997a53c38 100755 --- a/workflows/rnaseq.nf +++ b/workflows/rnaseq.nf @@ -167,10 +167,23 @@ workflow RNASEQ { // def biotype = params.gencode ? "gene_type" : params.featurecounts_group_type PREPARE_GENOME ( - prepareToolIndices, + params.fasta, + params.gtf, + params.gff, + params.additional_fasta, + params.transcript_fasta, + params.gene_bed, + params.splicesites, + params.bbsplit_fasta_list, + params.star_index, + params.rsem_index, + params.salmon_index, + params.hisat2_index, + params.bbsplit_index, + params.gencode, + is_aws_igenome, biotype, - is_aws_igenome - + prepareToolIndices ) ch_versions = ch_versions.mix(PREPARE_GENOME.out.versions) From 9cda459524c8754b35cea3981f4cc9d2f86f687a Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Wed, 15 Mar 2023 10:41:05 +0000 Subject: [PATCH 042/124] Bump pipeline version to 3.11.0 --- CHANGELOG.md | 2 +- nextflow.config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ef93afa9..007129bd7 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.11.0](https://github.com/nf-core/rnaseq/releases/tag/3.11.0)] - 2023-03-24 ### Enhancements & fixes diff --git a/nextflow.config b/nextflow.config index e2faa2763..ec7c7bc7a 100644 --- a/nextflow.config +++ b/nextflow.config @@ -255,7 +255,7 @@ manifest { description = """RNA sequencing analysis pipeline for gene/isoform quantification and extensive quality control.""" mainScript = 'main.nf' nextflowVersion = '!>=22.10.1' - version = '3.10.1' + version = '3.11.0' doi = 'https://doi.org/10.5281/zenodo.1400710' } From b10efc894561400cad71b55d4f99478bfa846c5c Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Wed, 15 Mar 2023 10:47:42 +0000 Subject: [PATCH 043/124] Fix channel issue with CUSTOM_GETCHROMSIZES --- modules.json | 3 +- .../getchromsizes/custom-getchromsizes.diff | 24 --------------- modules/nf-core/custom/getchromsizes/main.nf | 10 +++---- subworkflows/local/prepare_genome.nf | 30 +++++++++---------- 4 files changed, 21 insertions(+), 46 deletions(-) delete mode 100644 modules/nf-core/custom/getchromsizes/custom-getchromsizes.diff diff --git a/modules.json b/modules.json index 1549d2e29..7c48ead35 100644 --- a/modules.json +++ b/modules.json @@ -23,8 +23,7 @@ "custom/getchromsizes": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], - "patch": "modules/nf-core/custom/getchromsizes/custom-getchromsizes.diff" + "installed_by": ["modules"] }, "fastqc": { "branch": "master", diff --git a/modules/nf-core/custom/getchromsizes/custom-getchromsizes.diff b/modules/nf-core/custom/getchromsizes/custom-getchromsizes.diff deleted file mode 100644 index cd8e585c8..000000000 --- a/modules/nf-core/custom/getchromsizes/custom-getchromsizes.diff +++ /dev/null @@ -1,24 +0,0 @@ -Changes in module 'nf-core/custom/getchromsizes' ---- modules/nf-core/custom/getchromsizes/main.nf -+++ modules/nf-core/custom/getchromsizes/main.nf -@@ -8,13 +8,13 @@ - 'quay.io/biocontainers/samtools:1.16.1--h6899075_1' }" - - input: -- tuple val(meta), path(fasta) -+ path fasta - - output: -- tuple val(meta), path ("*.sizes"), emit: sizes -- tuple val(meta), path ("*.fai") , emit: fai -- tuple val(meta), path ("*.gzi") , emit: gzi, optional: true -- path "versions.yml" , emit: versions -+ path "*.sizes" , emit: sizes -+ path "*.fai" , emit: fai -+ path "*.gzi" , emit: gzi, optional: true -+ path "versions.yml", emit: versions - - when: - task.ext.when == null || task.ext.when - -************************************************************ diff --git a/modules/nf-core/custom/getchromsizes/main.nf b/modules/nf-core/custom/getchromsizes/main.nf index 486bfbd78..580f87fea 100644 --- a/modules/nf-core/custom/getchromsizes/main.nf +++ b/modules/nf-core/custom/getchromsizes/main.nf @@ -8,13 +8,13 @@ process CUSTOM_GETCHROMSIZES { 'quay.io/biocontainers/samtools:1.16.1--h6899075_1' }" input: - path fasta + tuple val(meta), path(fasta) output: - path "*.sizes" , emit: sizes - path "*.fai" , emit: fai - path "*.gzi" , emit: gzi, optional: true - path "versions.yml", emit: versions + tuple val(meta), path ("*.sizes"), emit: sizes + tuple val(meta), path ("*.fai") , emit: fai + tuple val(meta), path ("*.gzi") , emit: gzi, optional: true + path "versions.yml" , emit: versions when: task.ext.when == null || task.ext.when diff --git a/subworkflows/local/prepare_genome.nf b/subworkflows/local/prepare_genome.nf index 4f7562407..52e09c774 100644 --- a/subworkflows/local/prepare_genome.nf +++ b/subworkflows/local/prepare_genome.nf @@ -142,9 +142,9 @@ workflow PREPARE_GENOME { // // Create chromosome sizes file // - CUSTOM_GETCHROMSIZES ( ch_fasta ) - ch_chrom_sizes = CUSTOM_GETCHROMSIZES.out.sizes - ch_fai = CUSTOM_GETCHROMSIZES.out.fai + CUSTOM_GETCHROMSIZES ( ch_fasta.map { [ [:], it ] } ) + ch_fai = CUSTOM_GETCHROMSIZES.out.fai.map { it[1] } + ch_chrom_sizes = CUSTOM_GETCHROMSIZES.out.sizes.map { it[1] } ch_versions = ch_versions.mix(CUSTOM_GETCHROMSIZES.out.versions) // @@ -259,18 +259,18 @@ 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 - splicesites = ch_splicesites // path: genome.splicesites.txt - bbsplit_index = ch_bbsplit_index // path: bbsplit/index/ - star_index = ch_star_index // path: star/index/ - rsem_index = ch_rsem_index // path: rsem/index/ - hisat2_index = ch_hisat2_index // path: hisat2/index/ - salmon_index = ch_salmon_index // path: salmon/index/ + fasta = ch_fasta // channel: path(genome.fasta) + gtf = ch_gtf // channel: path(genome.gtf) + fai = ch_fai // channel: path(genome.fai) + gene_bed = ch_gene_bed // channel: path(gene.bed) + transcript_fasta = ch_transcript_fasta // channel: path(transcript.fasta) + chrom_sizes = ch_chrom_sizes // channel: path(genome.sizes) + splicesites = ch_splicesites // channel: path(genome.splicesites.txt) + bbsplit_index = ch_bbsplit_index // channel: path(bbsplit/index/) + star_index = ch_star_index // channel: path(star/index/) + rsem_index = ch_rsem_index // channel: path(rsem/index/) + hisat2_index = ch_hisat2_index // channel: path(hisat2/index/) + salmon_index = ch_salmon_index // channel: path(salmon/index/) versions = ch_versions.ifEmpty(null) // channel: [ versions.yml ] } From 05288e16562944ba9ed47aa8246540cea3554a43 Mon Sep 17 00:00:00 2001 From: Gregor Sturm Date: Wed, 15 Mar 2023 12:26:06 +0100 Subject: [PATCH 044/124] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ebc111cc8..c3d87da8f 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ ## Usage > **Note** -> If you are new to nextflow and nf-core, please refer to [this page](https://nf-co.re/#TODO) on how to set-up nextflow. +> If you are new to nextflow and nf-core, please refer to [this page](https://nf-co.re/#TODO) on how to set-up nextflow. Make sure to [test your setup](https://nf-co.re/#TODO) with `-profile test` before running the workflow on actual data. First, you need to prepare a samplesheet with your input data that looks as follows: From 86da5f2e25ed2586e54321243ebb7de7009cdf2b Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Thu, 16 Mar 2023 11:52:41 +0000 Subject: [PATCH 045/124] Fix #878 --- CHANGELOG.md | 1 + modules.json | 2 +- modules/nf-core/salmon/index/main.nf | 9 +++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 007129bd7..923de45c5 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 +- [[#878](https://github.com/nf-core/rnaseq/pull/878)] - Allow tabs in fasta header when creating decoys for salmon index - [[#934](https://github.com/nf-core/rnaseq/pull/934)] - Union of `ext.args` and `params.extra_star_align_args` prevents parameter clashes in the STAR module - [[#940](https://github.com/nf-core/rnaseq/issues/940)] - Bugfix in `salmon_summarizedexperiment.r` to ensure `rbind` doesn't fail when `rowdata` has no `tx` column. See ([[#941](https://github.com/nf-core/rnaseq/pull/941)]) for details. - [[#944](https://github.com/nf-core/rnaseq/issues/944)] - Read clipping using clip_r1, clip_r2, three_prime_clip_r1, three_prime_clip_r2 disabled in 3.10 diff --git a/modules.json b/modules.json index 7c48ead35..03ba3b2db 100644 --- a/modules.json +++ b/modules.json @@ -127,7 +127,7 @@ }, "salmon/index": { "branch": "master", - "git_sha": "94b06f1683ddf893cf06525f6e7f0573ad8fbf83", + "git_sha": "cfef21995228c66af535b14c5efae1461ffb8981", "installed_by": ["fastq_subsample_fq_salmon"] }, "salmon/quant": { diff --git a/modules/nf-core/salmon/index/main.nf b/modules/nf-core/salmon/index/main.nf index 1a67bddc5..b850eccd5 100644 --- a/modules/nf-core/salmon/index/main.nf +++ b/modules/nf-core/salmon/index/main.nf @@ -12,18 +12,18 @@ process SALMON_INDEX { path transcript_fasta output: - path "salmon" , emit: index - path "versions.yml" , emit: versions + 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" + def get_decoy_ids = "grep '^>' $genome_fasta | cut -d ' ' -f 1 | cut -d \$'\\t' -f 1 > decoys.txt" def gentrome = "gentrome.fa" if (genome_fasta.endsWith('.gz')) { - get_decoy_ids = "grep '^>' <(gunzip -c $genome_fasta) | cut -d ' ' -f 1 > decoys.txt" + get_decoy_ids = "grep '^>' <(gunzip -c $genome_fasta) | cut -d ' ' -f 1 | cut -d \$'\\t' -f 1 > decoys.txt" gentrome = "gentrome.fa.gz" } """ @@ -38,6 +38,7 @@ process SALMON_INDEX { -d decoys.txt \\ $args \\ -i salmon + cat <<-END_VERSIONS > versions.yml "${task.process}": salmon: \$(echo \$(salmon --version) | sed -e "s/salmon //g") From a8f53becef7a63f434449b2e8528a517d14a16da Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Thu, 16 Mar 2023 13:15:05 +0000 Subject: [PATCH 046/124] Fix #960 --- CHANGELOG.md | 1 + conf/modules.config | 29 ---------- lib/WorkflowRnaseq.groovy | 16 +++++- modules/local/multiqc_tsv_from_list.nf | 28 ---------- workflows/rnaseq.nf | 73 ++++++++++++-------------- 5 files changed, 49 insertions(+), 98 deletions(-) delete mode 100644 modules/local/multiqc_tsv_from_list.nf diff --git a/CHANGELOG.md b/CHANGELOG.md index 923de45c5..f36b39b75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [[#940](https://github.com/nf-core/rnaseq/issues/940)] - Bugfix in `salmon_summarizedexperiment.r` to ensure `rbind` doesn't fail when `rowdata` has no `tx` column. See ([[#941](https://github.com/nf-core/rnaseq/pull/941)]) for details. - [[#944](https://github.com/nf-core/rnaseq/issues/944)] - Read clipping using clip_r1, clip_r2, three_prime_clip_r1, three_prime_clip_r2 disabled in 3.10 - [[#956](https://github.com/nf-core/rnaseq/pull/956)] - Implement 'auto' as default strandedness argument in `fastq_dir_to_samplesheet.py` script +- [[#960](https://github.com/nf-core/rnaseq/pull/960)] - Failure with awsbatch when running processes that are using `executor: local` - Remove HISAT2 from automated AWS full-sized tests ### Software dependencies diff --git a/conf/modules.config b/conf/modules.config index 7e5e5d955..1f46b71a2 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -237,13 +237,6 @@ if (!params.skip_trimming) { ] ] } - - withName: 'MULTIQC_TSV_FAIL_TRIMMED' { - publishDir = [ - path: { "${params.outdir}/multiqc" }, - enabled: false - ] - } } } @@ -517,17 +510,6 @@ if (!params.skip_alignment) { } } } - - if (params.aligner.contains('star')) { - process { - withName: 'MULTIQC_TSV_FAIL_MAPPED' { - publishDir = [ - path: { "${params.outdir}/multiqc" }, - enabled: false - ] - } - } - } } // @@ -1042,17 +1024,6 @@ if (!params.skip_alignment && !params.skip_qc) { } } } - - if (!params.skip_rseqc && rseqc_modules) { - process { - withName: 'MULTIQC_TSV_STRAND_CHECK' { - publishDir = [ - path: { "${params.outdir}/multiqc" }, - enabled: false - ] - } - } - } } if (!params.skip_multiqc) { diff --git a/lib/WorkflowRnaseq.groovy b/lib/WorkflowRnaseq.groovy index 09e324a2a..e22362a30 100755 --- a/lib/WorkflowRnaseq.groovy +++ b/lib/WorkflowRnaseq.groovy @@ -273,6 +273,18 @@ class WorkflowRnaseq { return yaml_file_text } + // + // Create MultiQC tsv custom content from a list of values + // + public static String multiqcTsvFromList(tsv_data, header) { + def tsv_string = "" + if (tsv_data.size() > 0) { + tsv_string += "${header.join('\t')}\n" + tsv_string += tsv_data.join('\n') + } + return tsv_string + } + public static String methodsDescriptionText(run_workflow, mqc_methods_yaml) { // Convert to a named map so can be used as with familar NXF ${workflow} variable syntax in the MultiQC YML file def meta = [:] @@ -288,7 +300,9 @@ class WorkflowRnaseq { def description_html = engine.createTemplate(methods_text).make(meta) return description_html - }// + } + + // // Exit pipeline if incorrect --genome key provided // private static void genomeExistsError(params, log) { diff --git a/modules/local/multiqc_tsv_from_list.nf b/modules/local/multiqc_tsv_from_list.nf deleted file mode 100644 index a53c8f73e..000000000 --- a/modules/local/multiqc_tsv_from_list.nf +++ /dev/null @@ -1,28 +0,0 @@ -process MULTIQC_TSV_FROM_LIST { - - executor 'local' - memory 100.MB - - input: - val tsv_data // [ ['foo', 1], ['bar', 1] ] - val header // [ 'name', 'number' ] - val out_prefix - - output: - path "*.tsv" - - when: - task.ext.when == null || task.ext.when - - exec: - // Generate file contents - def contents = "" - if (tsv_data.size() > 0) { - contents += "${header.join('\t')}\n" - contents += tsv_data.join('\n') - } - - // Write to file - def mqc_file = task.workDir.resolve("${out_prefix}_mqc.tsv") - mqc_file.text = contents -} diff --git a/workflows/rnaseq.nf b/workflows/rnaseq.nf index 997a53c38..0453ee633 100755 --- a/workflows/rnaseq.nf +++ b/workflows/rnaseq.nf @@ -100,9 +100,6 @@ include { DUPRADAR } from '../modules/local/dupradar' include { MULTIQC } from '../modules/local/multiqc' include { MULTIQC_CUSTOM_BIOTYPE } from '../modules/local/multiqc_custom_biotype' include { UMITOOLS_PREPAREFORRSEM as UMITOOLS_PREPAREFORSALMON } from '../modules/local/umitools_prepareforrsem.nf' -include { MULTIQC_TSV_FROM_LIST as MULTIQC_TSV_FAIL_MAPPED } from '../modules/local/multiqc_tsv_from_list' -include { MULTIQC_TSV_FROM_LIST as MULTIQC_TSV_FAIL_TRIMMED } from '../modules/local/multiqc_tsv_from_list' -include { MULTIQC_TSV_FROM_LIST as MULTIQC_TSV_STRAND_CHECK } from '../modules/local/multiqc_tsv_from_list' // // SUBWORKFLOW: Consisting of a mix of local and nf-core/modules @@ -309,14 +306,13 @@ workflow RNASEQ { return [ "$meta.id\t$num_reads" ] } } - .set { ch_num_trimmed_reads } - - MULTIQC_TSV_FAIL_TRIMMED ( - ch_num_trimmed_reads.collect(), - ["Sample", "Reads after trimming"], - 'fail_trimmed_samples' - ) - .set { ch_fail_trimming_multiqc } + .collect() + .map { + tsv_data -> + def header = ["Sample", "Reads after trimming"] + WorkflowRnaseq.multiqcTsvFromList(tsv_data, header) + } + .set { ch_fail_trimming_multiqc } } // @@ -581,16 +577,15 @@ workflow RNASEQ { } .set { ch_pass_fail_mapped } - def header = [ - "Sample", - "STAR uniquely mapped reads (%)" - ] - MULTIQC_TSV_FAIL_MAPPED ( - ch_pass_fail_mapped.fail.collect(), - header, - 'fail_mapped_samples' - ) - .set { ch_fail_mapping_multiqc } + ch_pass_fail_mapped + .fail + .collect() + .map { + tsv_data -> + def header = ["Sample", "STAR uniquely mapped reads (%)"] + WorkflowRnaseq.multiqcTsvFromList(tsv_data, header) + } + .set { ch_fail_mapping_multiqc } } // @@ -751,22 +746,20 @@ workflow RNASEQ { .map { meta, strandedness, sense, antisense, undetermined -> [ "$meta.id\t$meta.strandedness\t$strandedness\t$sense\t$antisense\t$undetermined" ] } - .set { ch_fail_strand } - - def header = [ - "Sample", - "Provided strandedness", - "Inferred strandedness", - "Sense (%)", - "Antisense (%)", - "Undetermined (%)" - ] - MULTIQC_TSV_STRAND_CHECK ( - ch_fail_strand.collect(), - header, - 'fail_strand_check' - ) - .set { ch_fail_strand_multiqc } + .collect() + .map { + tsv_data -> + def header = [ + "Sample", + "Provided strandedness", + "Inferred strandedness", + "Sense (%)", + "Antisense (%)", + "Undetermined (%)" + ] + WorkflowRnaseq.multiqcTsvFromList(tsv_data, header) + } + .set { ch_fail_strand_multiqc } } } @@ -824,9 +817,9 @@ workflow RNASEQ { ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml'), ch_methods_description.collectFile(name: 'methods_description_mqc.yaml'), ch_multiqc_logo.collect().ifEmpty([]), - ch_fail_trimming_multiqc.ifEmpty([]), - ch_fail_mapping_multiqc.ifEmpty([]), - ch_fail_strand_multiqc.ifEmpty([]), + ch_fail_trimming_multiqc.collectFile(name: 'fail_trimmed_samples_mqc.tsv').ifEmpty([]), + ch_fail_mapping_multiqc.collectFile(name: 'fail_mapped_samples_mqc.tsv').ifEmpty([]), + ch_fail_strand_multiqc.collectFile(name: 'fail_strand_check_mqc.tsv').ifEmpty([]), FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.fastqc_zip.collect{it[1]}.ifEmpty([]), FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.trim_zip.collect{it[1]}.ifEmpty([]), FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.trim_log.collect{it[1]}.ifEmpty([]), From 07ddd71401b951eb71f90be8915ccca76dfcd0b1 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Thu, 16 Mar 2023 14:54:03 +0000 Subject: [PATCH 047/124] Fix #931 --- CHANGELOG.md | 1 + conf/modules.config | 71 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f36b39b75..0aab5e3e0 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 - [[#878](https://github.com/nf-core/rnaseq/pull/878)] - Allow tabs in fasta header when creating decoys for salmon index +- [[#931](https://github.com/nf-core/rnaseq/pull/931)] - Save transcriptome BAM files when using `--save_umi_intermeds` / `--save_align_intermeds` - [[#934](https://github.com/nf-core/rnaseq/pull/934)] - Union of `ext.args` and `params.extra_star_align_args` prevents parameter clashes in the STAR module - [[#940](https://github.com/nf-core/rnaseq/issues/940)] - Bugfix in `salmon_summarizedexperiment.r` to ensure `rbind` doesn't fail when `rowdata` has no `tx` column. See ([[#941](https://github.com/nf-core/rnaseq/pull/941)]) for details. - [[#944](https://github.com/nf-core/rnaseq/issues/944)] - Read clipping using clip_r1, clip_r2, three_prime_clip_r1, three_prime_clip_r2 disabled in 3.10 diff --git a/conf/modules.config b/conf/modules.config index 1f46b71a2..ce83ef003 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -595,16 +595,32 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { ext.prefix = { "${meta.id}.umi_dedup.transcriptome" } publishDir = [ path: { "${params.outdir}/${params.aligner}" }, - enabled: false + mode: params.publish_dir_mode, + pattern: '*.bam', + enabled: ( + params.save_align_intermeds || + params.save_umi_intermeds + ) ] } withName: 'NFCORE_RNASEQ:RNASEQ:UMITOOLS_PREPAREFORSALMON' { ext.prefix = { "${meta.id}.umi_dedup.transcriptome.filtered" } publishDir = [ - path: { "${params.outdir}/${params.aligner}/umitools/log" }, - mode: params.publish_dir_mode, - pattern: '*.log' + [ + path: { "${params.outdir}/${params.aligner}/umitools/log" }, + mode: params.publish_dir_mode, + pattern: '*.log' + ], + [ + path: { "${params.outdir}/${params.aligner}" }, + mode: params.publish_dir_mode, + pattern: '*.bam', + enabled: ( + params.save_align_intermeds || + params.save_umi_intermeds + ) + ] ] } @@ -612,22 +628,37 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { ext.prefix = { "${meta.id}.transcriptome.sorted" } publishDir = [ path: { "${params.outdir}/${params.aligner}" }, - enabled: false + mode: params.publish_dir_mode, + pattern: '*.bam', + enabled: ( + params.save_align_intermeds || + params.save_umi_intermeds + ) ] } withName: 'NFCORE_RNASEQ:RNASEQ:BAM_SORT_STATS_SAMTOOLS:SAMTOOLS_INDEX' { publishDir = [ path: { "${params.outdir}/${params.aligner}" }, - enabled: false + mode: params.publish_dir_mode, + pattern: '*.bai', + enabled: ( + params.save_align_intermeds || + params.save_umi_intermeds + ) ] } withName: 'NFCORE_RNASEQ:RNASEQ:BAM_SORT_STATS_SAMTOOLS:BAM_STATS_SAMTOOLS:.*' { ext.prefix = { "${meta.id}.transcriptome.sorted.bam" } publishDir = [ - path: { "${params.outdir}/${params.aligner}" }, - enabled: false + path: { "${params.outdir}/${params.aligner}/samtools_stats" }, + mode: params.publish_dir_mode, + pattern: '*.{stats,flagstat,idxstats}', + enabled: ( + params.save_align_intermeds || + params.save_umi_intermeds + ) ] } @@ -639,16 +670,32 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { ].join(' ').trim() } ext.prefix = { "${meta.id}.umi_dedup.transcriptome.sorted" } publishDir = [ - path: { "${params.outdir}/${params.aligner}/umitools" }, - mode: params.publish_dir_mode, - pattern: '*.tsv' + [ + path: { "${params.outdir}/${params.aligner}/umitools" }, + mode: params.publish_dir_mode, + pattern: '*.tsv' + ], + [ + path: { "${params.outdir}/${params.aligner}" }, + mode: params.publish_dir_mode, + pattern: '*.bam', + enabled: ( + params.save_align_intermeds || + params.save_umi_intermeds + ) + ] ] } withName: '.*:BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS_TRANSCRIPTOME:SAMTOOLS_INDEX' { publishDir = [ path: { "${params.outdir}/${params.aligner}" }, - enabled: false + mode: params.publish_dir_mode, + pattern: '*.bai', + enabled: ( + params.save_align_intermeds || + params.save_umi_intermeds + ) ] } From 192dcb98ed26e46dc0c13f13e60614340e2ce5c0 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Thu, 16 Mar 2023 14:57:43 +0000 Subject: [PATCH 048/124] Fix ECLint --- lib/WorkflowRnaseq.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/WorkflowRnaseq.groovy b/lib/WorkflowRnaseq.groovy index e22362a30..33ce9ad72 100755 --- a/lib/WorkflowRnaseq.groovy +++ b/lib/WorkflowRnaseq.groovy @@ -301,7 +301,7 @@ class WorkflowRnaseq { return description_html } - + // // Exit pipeline if incorrect --genome key provided // From d79d22f8f0bfc8efb9d2d3c1467f77c5ae375356 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Fri, 17 Mar 2023 12:57:06 +0000 Subject: [PATCH 049/124] Fix #961 --- CHANGELOG.md | 1 + assets/email_template.html | 8 ++--- assets/email_template.txt | 8 ++--- lib/NfcoreTemplate.groovy | 61 +++++++++++++++++++------------------- workflows/rnaseq.nf | 35 +++++++++++++--------- 5 files changed, 57 insertions(+), 56 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0aab5e3e0..f4b155eda 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 - [[#944](https://github.com/nf-core/rnaseq/issues/944)] - Read clipping using clip_r1, clip_r2, three_prime_clip_r1, three_prime_clip_r2 disabled in 3.10 - [[#956](https://github.com/nf-core/rnaseq/pull/956)] - Implement 'auto' as default strandedness argument in `fastq_dir_to_samplesheet.py` script - [[#960](https://github.com/nf-core/rnaseq/pull/960)] - Failure with awsbatch when running processes that are using `executor: local` +- [[#961](https://github.com/nf-core/rnaseq/pull/961)] - Add warnings to STDOUT for all skipped and failed strandedness check samples - Remove HISAT2 from automated AWS full-sized tests ### Software dependencies diff --git a/assets/email_template.html b/assets/email_template.html index c73cfb931..0ef39b222 100644 --- a/assets/email_template.html +++ b/assets/email_template.html @@ -34,7 +34,7 @@

nf-core/rnaseq execution completed uns

The full error message was:

${errorReport}
- """ } else if(fail_percent_mapped.size() > 0) { out << """ + """ } else if(skip_sample_count > 0) { out << """
nf-core/rnaseq execution completed uns >

nf-core/rnaseq execution completed with warnings!

- The pipeline finished successfully, but the following samples were skipped due to very low alignment (< - ${min_mapped_reads}%): + The pipeline finished successfully, but samples were skipped. Please check warnings at the top of the MultiQC report.

-
    -
  • ${fail_percent_mapped.join('
  • ')}
  • -

diff --git a/assets/email_template.txt b/assets/email_template.txt index fd1ec9894..5440f887a 100644 --- a/assets/email_template.txt +++ b/assets/email_template.txt @@ -17,14 +17,12 @@ The full error message was: ${errorReport} """ -} else if (fail_percent_mapped.size() > 0) { +} else if (skip_sample_count > 0) { out << """################################################## ## nf-core/rnaseq execution completed with warnings ## ################################################## -The pipeline finished successfully, but the following samples were skipped, -due to very low alignment (less than ${min_mapped_reads}%): - - - ${fail_percent_mapped.join("\n - ")} +The pipeline finished successfully, but samples were skipped. +Please check warnings at the top of the MultiQC report. """ } else { out << "## nf-core/rnaseq execution completed successfully! ##" diff --git a/lib/NfcoreTemplate.groovy b/lib/NfcoreTemplate.groovy index bec83dfd2..6b755c42e 100755 --- a/lib/NfcoreTemplate.groovy +++ b/lib/NfcoreTemplate.groovy @@ -54,12 +54,16 @@ class NfcoreTemplate { // // Construct and send completion email // - public static void email(workflow, params, summary_params, projectDir, log, multiqc_report=[], fail_percent_mapped=[:]) { + public static void email(workflow, params, summary_params, projectDir, log, multiqc_report=[], pass_mapped_reads=[:], pass_trimmed_reads=[:], pass_strand_check=[:]) { // Set up the e-mail variables + def fail_mapped_count = pass_mapped_reads.count { key, value -> value == false } + def fail_trimmed_count = pass_trimmed_reads.count { key, value -> value == false } + def fail_strand_count = pass_strand_check.count { key, value -> value == false } + def subject = "[$workflow.manifest.name] Successful: $workflow.runName" - if (fail_percent_mapped.size() > 0) { - subject = "[$workflow.manifest.name] Partially successful (${fail_percent_mapped.size()} skipped): $workflow.runName" + if (fail_mapped_count + fail_trimmed_count + fail_strand_count > 0) { + subject = "[$workflow.manifest.name] Partially successful - samples skipped: $workflow.runName" } if (!workflow.success) { subject = "[$workflow.manifest.name] FAILED: $workflow.runName" @@ -94,8 +98,7 @@ class NfcoreTemplate { email_fields['commandLine'] = workflow.commandLine email_fields['projectDir'] = workflow.projectDir email_fields['summary'] = summary << misc_fields - email_fields['fail_percent_mapped'] = fail_percent_mapped.keySet() - email_fields['min_mapped_reads'] = params.min_mapped_reads + email_fields['skip_sample_count'] = fail_mapped_count + fail_trimmed_count + fail_strand_count // On success try attach the multiqc report def mqc_report = null @@ -230,36 +233,32 @@ class NfcoreTemplate { // // Print pipeline summary on completion // - public static void summary(workflow, params, log, fail_percent_mapped=[:], pass_percent_mapped=[:]) { + public static void summary(workflow, params, log, pass_mapped_reads=[:], pass_trimmed_reads=[:], pass_strand_check=[:]) { Map colors = logColours(params.monochrome_logs) - def total_aln_count = pass_percent_mapped.size() + fail_percent_mapped.size() - if (pass_percent_mapped.size() > 0) { - def idx = 0 - def samp_aln = '' - for (samp in pass_percent_mapped) { - samp_aln += " ${samp.value}%: ${samp.key}\n" - idx += 1 - if (idx > 5) { - samp_aln += " ..see pipeline reports for full list\n" - break; - } + def fail_mapped_count = pass_mapped_reads.count { key, value -> value == false } + def fail_trimmed_count = pass_trimmed_reads.count { key, value -> value == false } + def fail_strand_count = pass_strand_check.count { key, value -> value == false } + if (workflow.success) { + def color = colors.green + def status = [] + if (workflow.stats.ignoredCount != 0) { + color = colors.yellow + status += ['with errored process(es)'] + } + if (fail_mapped_count > 0 || fail_trimmed_count > 0 || fail_strand_count > 0) { + color = colors.yellow + status += ['with skipped sampl(es)'] } - log.info "-${colors.purple}[$workflow.manifest.name]${colors.green} ${pass_percent_mapped.size()}/$total_aln_count samples passed STAR ${params.min_mapped_reads}% mapped threshold:\n${samp_aln}${colors.reset}-" - } - if (fail_percent_mapped.size() > 0) { - def samp_aln = '' - for (samp in fail_percent_mapped) { - samp_aln += " ${samp.value}%: ${samp.key}\n" + log.info "-${colors.purple}[$workflow.manifest.name]${color} Pipeline completed successfully ${status.join(', ')}${colors.reset}-" + if (fail_trimmed_count > 0) { + log.info "-${colors.purple}[$workflow.manifest.name]${colors.red} Please check MultiQC report: ${fail_trimmed_count}/${pass_trimmed_reads.size()} samples skipped since they failed ${params.min_trimmed_reads} trimmed read threshold.${colors.reset}-" } - log.info "-${colors.purple}[$workflow.manifest.name]${colors.red} ${fail_percent_mapped.size()}/$total_aln_count samples skipped since they failed STAR ${params.min_mapped_reads}% mapped threshold:\n${samp_aln}${colors.reset}-" - } - - if (workflow.success) { - if (workflow.stats.ignoredCount == 0) { - log.info "-${colors.purple}[$workflow.manifest.name]${colors.green} Pipeline completed successfully${colors.reset}-" - } else { - log.info "-${colors.purple}[$workflow.manifest.name]${colors.yellow} Pipeline completed successfully, but with errored process(es) ${colors.reset}-" + if (fail_mapped_count > 0) { + log.info "-${colors.purple}[$workflow.manifest.name]${colors.red} Please check MultiQC report: ${fail_mapped_count}/${pass_mapped_reads.size()} samples skipped since they failed STAR ${params.min_mapped_reads}% mapped threshold.${colors.reset}-" + } + if (fail_strand_count > 0) { + log.info "-${colors.purple}[$workflow.manifest.name]${colors.red} Please check MultiQC report: ${fail_strand_count}/${pass_strand_check.size()} samples failed strandedness check.${colors.reset}-" } } else { log.info "-${colors.purple}[$workflow.manifest.name]${colors.red} Pipeline completed with errors${colors.reset}-" diff --git a/workflows/rnaseq.nf b/workflows/rnaseq.nf index 0453ee633..bb2fcf5ae 100755 --- a/workflows/rnaseq.nf +++ b/workflows/rnaseq.nf @@ -151,9 +151,10 @@ include { BEDGRAPH_BEDCLIP_BEDGRAPHTOBIGWIG as BEDGRAPH_BEDCLIP_BEDGRAPHTOBIGWIG */ // Info required for completion email and summary -def multiqc_report = [] -def pass_percent_mapped = [:] -def fail_percent_mapped = [:] +def multiqc_report = [] +def pass_mapped_reads = [:] +def pass_trimmed_reads = [:] +def pass_strand_check = [:] workflow RNASEQ { @@ -302,9 +303,11 @@ workflow RNASEQ { ch_num_trimmed_reads .map { meta, reads, num_reads -> - if (num_reads <= params.min_trimmed_reads) { - return [ "$meta.id\t$num_reads" ] - } + pass_trimmed_reads[meta.id] = true + if (num_reads <= params.min_trimmed_reads) { + pass_trimmed_reads[meta.id] = false + return [ "$meta.id\t$num_reads" ] + } } .collect() .map { @@ -569,10 +572,10 @@ workflow RNASEQ { ch_percent_mapped .branch { meta, mapped, pass -> pass: pass - pass_percent_mapped[meta.id] = mapped + pass_mapped_reads[meta.id] = true return [ "$meta.id\t$mapped" ] fail: !pass - fail_percent_mapped[meta.id] = mapped + pass_mapped_reads[meta.id] = false return [ "$meta.id\t$mapped" ] } .set { ch_pass_fail_mapped } @@ -741,10 +744,14 @@ workflow RNASEQ { ch_versions = ch_versions.mix(BAM_RSEQC.out.versions) ch_inferexperiment_multiqc - .map { meta, strand_log -> [ meta ] + WorkflowRnaseq.getInferexperimentStrandedness(strand_log, 30) } - .filter { it[0].strandedness != it[1] } - .map { meta, strandedness, sense, antisense, undetermined -> - [ "$meta.id\t$meta.strandedness\t$strandedness\t$sense\t$antisense\t$undetermined" ] + .map { + meta, strand_log -> + def inferred_strand = WorkflowRnaseq.getInferexperimentStrandedness(strand_log, 30) + pass_strand_check[meta.id] = true + if (meta.strandedness != inferred_strand[0]) { + pass_strand_check[meta.id] = false + return [ "$meta.id\t$meta.strandedness\t${inferred_strand.join('\t')}" ] + } } .collect() .map { @@ -861,14 +868,14 @@ workflow RNASEQ { workflow.onComplete { if (params.email || params.email_on_fail) { - NfcoreTemplate.email(workflow, params, summary_params, projectDir, log, multiqc_report, fail_percent_mapped) + NfcoreTemplate.email(workflow, params, summary_params, projectDir, log, multiqc_report, pass_mapped_reads, pass_trimmed_reads, pass_strand_check) } if (params.hook_url) { NfcoreTemplate.IM_notification(workflow, params, summary_params, projectDir, log) } - NfcoreTemplate.summary(workflow, params, log, fail_percent_mapped, pass_percent_mapped) + NfcoreTemplate.summary(workflow, params, log, pass_mapped_reads, pass_trimmed_reads, pass_strand_check) } /* From 6c63436bd4b3cb2dbd9746ecb4b68389d4cdb8f4 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Fri, 17 Mar 2023 13:23:39 +0000 Subject: [PATCH 050/124] Fix ECLint --- lib/NfcoreTemplate.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/NfcoreTemplate.groovy b/lib/NfcoreTemplate.groovy index 6b755c42e..e06d6cc2c 100755 --- a/lib/NfcoreTemplate.groovy +++ b/lib/NfcoreTemplate.groovy @@ -245,7 +245,7 @@ class NfcoreTemplate { if (workflow.stats.ignoredCount != 0) { color = colors.yellow status += ['with errored process(es)'] - } + } if (fail_mapped_count > 0 || fail_trimmed_count > 0 || fail_strand_count > 0) { color = colors.yellow status += ['with skipped sampl(es)'] From 0b23eb0c8075deeaadee764bf47426079c8318a4 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Fri, 17 Mar 2023 16:25:30 +0000 Subject: [PATCH 051/124] Remove --tracedir --- CHANGELOG.md | 10 ++++++++++ nextflow.config | 9 ++++----- nextflow_schema.json | 7 ------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4b155eda..37ebc0cd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [[#961](https://github.com/nf-core/rnaseq/pull/961)] - Add warnings to STDOUT for all skipped and failed strandedness check samples - Remove HISAT2 from automated AWS full-sized tests +### Parameters + +| Old parameter | New parameter | +| ------------- | ------------- | +| `--tracedir` | | + +> **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. + ### Software dependencies Note, since the pipeline is now using Nextflow DSL2, each process will be run with its own [Biocontainer](https://biocontainers.pro/#/registry). This means that on occasion it is entirely possible for the pipeline to be using different versions of the same tool. However, the overall software dependency changes compared to the last release have been listed below for reference. diff --git a/nextflow.config b/nextflow.config index ec7c7bc7a..bd16cf4fe 100644 --- a/nextflow.config +++ b/nextflow.config @@ -98,7 +98,6 @@ params { // Boilerplate options outdir = null - tracedir = "${params.outdir}/pipeline_info" publish_dir_mode = 'copy' email = null email_on_fail = null @@ -233,19 +232,19 @@ env { def trace_timestamp = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss') timeline { enabled = true - file = "${params.tracedir}/execution_timeline_${trace_timestamp}.html" + file = "${params.outdir}/pipeline_info/execution_timeline_${trace_timestamp}.html" } report { enabled = true - file = "${params.tracedir}/execution_report_${trace_timestamp}.html" + file = "${params.outdir}/pipeline_info/execution_report_${trace_timestamp}.html" } trace { enabled = true - file = "${params.tracedir}/execution_trace_${trace_timestamp}.txt" + file = "${params.outdir}/pipeline_info/execution_trace_${trace_timestamp}.txt" } dag { enabled = true - file = "${params.tracedir}/pipeline_dag_${trace_timestamp}.html" + file = "${params.outdir}/pipeline_info/pipeline_dag_${trace_timestamp}.html" } manifest { diff --git a/nextflow_schema.json b/nextflow_schema.json index de2c57ce7..66ce7c4a8 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -704,13 +704,6 @@ "description": "Custom MultiQC yaml file containing HTML including a methods description.", "fa_icon": "fas fa-cog" }, - "tracedir": { - "type": "string", - "description": "Directory to keep pipeline Nextflow logs and reports.", - "default": "${params.outdir}/pipeline_info", - "fa_icon": "fas fa-cogs", - "hidden": true - }, "validate_params": { "type": "boolean", "description": "Boolean whether to validate parameters against the schema at runtime", From 04e7a225bee6c675de034678b661fe8762cb7aa3 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 20 Mar 2023 10:56:11 +0000 Subject: [PATCH 052/124] Add credits to CHANGELOG --- CHANGELOG.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37ebc0cd4..79277e066 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,19 @@ 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.11.0](https://github.com/nf-core/rnaseq/releases/tag/3.11.0)] - 2023-03-24 +## [[3.11.0](https://github.com/nf-core/rnaseq/releases/tag/3.11.0)] - 2023-03-22 + +### Credits + +Special thanks to the following for their code contributions to the release: +- [J Lorent](https://github.com/jlorent) +- [Luca Beltrame](https://github.com/lbeltrame) +- [Matthias Zepper](https://github.com/MatthiasZepper) +- [Maxime Garcia](https://github.com/maxulysse) +- [Ryan Yordanoff](https://github.com/ryanyord) +- [Thomas Sandmann](https://github.com/tomsing1) + +Thank you to everyone else that has contributed by reporting bugs, enhancements or in any other way, shape or form. ### Enhancements & fixes From e745863c1226df4f48d04948215dc534e25eaaf1 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 20 Mar 2023 11:00:06 +0000 Subject: [PATCH 053/124] Fix prettier --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79277e066..cfc673a85 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 ### Credits Special thanks to the following for their code contributions to the release: + - [J Lorent](https://github.com/jlorent) - [Luca Beltrame](https://github.com/lbeltrame) - [Matthias Zepper](https://github.com/MatthiasZepper) From ec36cd89384ccfb63ade6ef7393328565308c3a4 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 21 Mar 2023 10:51:48 +0000 Subject: [PATCH 054/124] Re-install nf-core modules with java mem updates --- modules.json | 8 ++++---- modules/nf-core/bbmap/bbsplit/main.nf | 8 ++++---- modules/nf-core/picard/markduplicates/main.nf | 6 +++--- modules/nf-core/qualimap/rnaseq/main.nf | 2 +- modules/nf-core/rseqc/junctionannotation/meta.yml | 3 +++ 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/modules.json b/modules.json index 03ba3b2db..109df8bdf 100644 --- a/modules.json +++ b/modules.json @@ -7,7 +7,7 @@ "nf-core": { "bbmap/bbsplit": { "branch": "master", - "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", + "git_sha": "75027bf77472b1f4fd2cdd7e46f83119dfb0f2c6", "installed_by": ["modules"] }, "cat/fastq": { @@ -62,7 +62,7 @@ }, "picard/markduplicates": { "branch": "master", - "git_sha": "2f88b26e9804b99e98f7cd08e74c3f88288a3358", + "git_sha": "75027bf77472b1f4fd2cdd7e46f83119dfb0f2c6", "installed_by": ["bam_markduplicates_picard"] }, "preseq/lcextrap": { @@ -72,7 +72,7 @@ }, "qualimap/rnaseq": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "75027bf77472b1f4fd2cdd7e46f83119dfb0f2c6", "installed_by": ["modules"] }, "rsem/calculateexpression": { @@ -102,7 +102,7 @@ }, "rseqc/junctionannotation": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "2f398a6342db61e7ab0f4cb4d395eed74b65db7c", "installed_by": ["bam_rseqc"] }, "rseqc/junctionsaturation": { diff --git a/modules/nf-core/bbmap/bbsplit/main.nf b/modules/nf-core/bbmap/bbsplit/main.nf index 90f5104a1..2d9196871 100644 --- a/modules/nf-core/bbmap/bbsplit/main.nf +++ b/modules/nf-core/bbmap/bbsplit/main.nf @@ -27,11 +27,11 @@ process BBMAP_BBSPLIT { def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def avail_mem = 3 + def avail_mem = 3072 if (!task.memory) { log.info '[BBSplit] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' } else { - avail_mem = task.memory.giga + avail_mem = (task.memory.mega*0.8).intValue() } def other_refs = [] @@ -42,7 +42,7 @@ process BBMAP_BBSPLIT { if (primary_ref && other_ref_names && other_ref_paths) { """ bbsplit.sh \\ - -Xmx${avail_mem}g \\ + -Xmx${avail_mem}M \\ ref_primary=$primary_ref \\ ${other_refs.join(' ')} \\ path=bbsplit \\ @@ -70,7 +70,7 @@ process BBMAP_BBSPLIT { def fastq_out = meta.single_end ? "basename=${prefix}_%.fastq.gz" : "basename=${prefix}_%_#.fastq.gz" """ bbsplit.sh \\ - -Xmx${avail_mem}g \\ + -Xmx${avail_mem}M \\ $index_files \\ threads=$task.cpus \\ $fastq_in \\ diff --git a/modules/nf-core/picard/markduplicates/main.nf b/modules/nf-core/picard/markduplicates/main.nf index be243a958..1fe6ee2d2 100644 --- a/modules/nf-core/picard/markduplicates/main.nf +++ b/modules/nf-core/picard/markduplicates/main.nf @@ -24,15 +24,15 @@ process PICARD_MARKDUPLICATES { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def avail_mem = 3 + def avail_mem = 3072 if (!task.memory) { log.info '[Picard MarkDuplicates] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' } else { - avail_mem = task.memory.giga + avail_mem = (task.memory.mega*0.8).intValue() } """ picard \\ - -Xmx${avail_mem}g \\ + -Xmx${avail_mem}M \\ MarkDuplicates \\ $args \\ --INPUT $bam \\ diff --git a/modules/nf-core/qualimap/rnaseq/main.nf b/modules/nf-core/qualimap/rnaseq/main.nf index ad15ebc2a..c3cd5c06e 100644 --- a/modules/nf-core/qualimap/rnaseq/main.nf +++ b/modules/nf-core/qualimap/rnaseq/main.nf @@ -22,7 +22,7 @@ process QUALIMAP_RNASEQ { def args = task.ext.args ?: '' prefix = task.ext.prefix ?: "${meta.id}" def paired_end = meta.single_end ? '' : '-pe' - def memory = task.memory.toGiga() + "G" + def memory = (task.memory.mega*0.8).intValue() + 'M' def strandedness = 'non-strand-specific' if (meta.strandedness == 'forward') { diff --git a/modules/nf-core/rseqc/junctionannotation/meta.yml b/modules/nf-core/rseqc/junctionannotation/meta.yml index a17b84e91..48c43260e 100644 --- a/modules/nf-core/rseqc/junctionannotation/meta.yml +++ b/modules/nf-core/rseqc/junctionannotation/meta.yml @@ -53,6 +53,9 @@ output: description: Rscript to reproduce the plots pattern: "*.r" - log: + type: file + description: Log file of execution + pattern: "*.junction_annotation.log" - versions: type: file description: File containing software versions From 94c56cf14651608b16d6826a8d6d74f3426150af Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 21 Mar 2023 11:54:09 +0000 Subject: [PATCH 055/124] Re-install updated trimgalore subworkflow --- modules.json | 2 +- .../fastq_fastqc_umitools_trimgalore/main.nf | 69 ++++++++++--------- .../fastq_fastqc_umitools_trimgalore/meta.yml | 7 ++ 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/modules.json b/modules.json index 109df8bdf..58e99ffaa 100644 --- a/modules.json +++ b/modules.json @@ -264,7 +264,7 @@ }, "fastq_fastqc_umitools_trimgalore": { "branch": "master", - "git_sha": "72ffbd7128015a1d4b65b95ff8d37be8fee2f981", + "git_sha": "a1e1f3fc75c5fff7df88845a7f3d1b6145e0e649", "installed_by": ["subworkflows"] }, "fastq_subsample_fq_salmon": { diff --git a/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf b/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf index 36295a167..f50cb47bb 100644 --- a/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf +++ b/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf @@ -23,20 +23,21 @@ def getTrimGaloreReadsAfterFiltering(log_file) { workflow FASTQ_FASTQC_UMITOOLS_TRIMGALORE { take: - reads // channel: [ val(meta), [ reads ] ] - skip_fastqc // boolean: true/false - with_umi // boolean: true/false - skip_umi_extract // boolean: true/false - skip_trimming // boolean: true/false - umi_discard_read // integer: 0, 1 or 2 + reads // channel: [ val(meta), [ reads ] ] + skip_fastqc // boolean: true/false + with_umi // boolean: true/false + skip_umi_extract // boolean: true/false + skip_trimming // boolean: true/false + umi_discard_read // integer: 0, 1 or 2 + min_trimmed_reads // integer: > 0 main: - ch_versions = Channel.empty() fastqc_html = Channel.empty() fastqc_zip = Channel.empty() if (!skip_fastqc) { - FASTQC ( reads ).html.set { fastqc_html } + FASTQC (reads) + fastqc_html = FASTQC.out.html fastqc_zip = FASTQC.out.zip ch_versions = ch_versions.mix(FASTQC.out.versions.first()) } @@ -44,8 +45,8 @@ workflow FASTQ_FASTQC_UMITOOLS_TRIMGALORE { umi_reads = reads umi_log = Channel.empty() if (with_umi && !skip_umi_extract) { - - UMITOOLS_EXTRACT ( reads ).reads.set { umi_reads } + UMITOOLS_EXTRACT (reads) + umi_reads = UMITOOLS_EXTRACT.out.reads umi_log = UMITOOLS_EXTRACT.out.log ch_versions = ch_versions.mix(UMITOOLS_EXTRACT.out.versions.first()) @@ -54,24 +55,22 @@ workflow FASTQ_FASTQC_UMITOOLS_TRIMGALORE { UMITOOLS_EXTRACT .out .reads - .map { meta, reads -> - if (!meta.single_end) { - meta['single_end'] = true - reads = reads[umi_discard_read % 2] - } - return [ meta, reads ] + .map { + meta, reads -> + meta.single_end ? [ meta, reads ] : [ meta + ['single_end': true], reads[umi_discard_read % 2] ] } .set { umi_reads } } } - trim_reads = umi_reads - trim_unpaired = Channel.empty() - trim_html = Channel.empty() - trim_zip = Channel.empty() - trim_log = Channel.empty() + trim_reads = umi_reads + trim_unpaired = Channel.empty() + trim_html = Channel.empty() + trim_zip = Channel.empty() + trim_log = Channel.empty() + trim_read_count = Channel.empty() if (!skip_trimming) { - TRIMGALORE ( umi_reads ).reads.set { trim_reads } + TRIMGALORE (umi_reads) trim_unpaired = TRIMGALORE.out.unpaired trim_html = TRIMGALORE.out.html trim_zip = TRIMGALORE.out.zip @@ -79,24 +78,31 @@ workflow FASTQ_FASTQC_UMITOOLS_TRIMGALORE { ch_versions = ch_versions.mix(TRIMGALORE.out.versions.first()) // - // Filter empty FastQ files after adapter trimming + // Filter FastQ files based on minimum trimmed read count after adapter trimming // - trim_reads + TRIMGALORE + .out + .reads .join(trim_log, remainder: true) .map { meta, reads, trim_log -> if (trim_log) { - if (!meta.single_end) { - trim_log = trim_log[-1] - } - if (getTrimGaloreReadsAfterFiltering(trim_log) > 0) { - [ meta, reads ] - } + num_reads = getTrimGaloreReadsAfterFiltering(meta.single_end ? trim_log : trim_log[-1]) + [ meta, reads, num_reads ] } else { - [ meta, reads ] + [ meta, reads, min_trimmed_reads.toFloat() + 1 ] } } + .set { ch_num_trimmed_reads } + + ch_num_trimmed_reads + .filter { meta, reads, num_reads -> num_reads >= min_trimmed_reads.toFloat() } + .map { meta, reads, num_reads -> [ meta, num_reads ] } .set { trim_reads } + + ch_num_trimmed_reads + .map { meta, reads, num_reads -> [ meta, num_reads ] } + .set { trim_read_count } } emit: @@ -111,6 +117,7 @@ workflow FASTQ_FASTQC_UMITOOLS_TRIMGALORE { trim_html // channel: [ val(meta), [ html ] ] trim_zip // channel: [ val(meta), [ zip ] ] trim_log // channel: [ val(meta), [ txt ] ] + trim_read_count // channel: [ val(meta), val(count) ] versions = ch_versions.ifEmpty(null) // channel: [ versions.yml ] } diff --git a/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/meta.yml b/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/meta.yml index 02a02a6a1..b05004d45 100644 --- a/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/meta.yml +++ b/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/meta.yml @@ -42,6 +42,10 @@ input: type: integer description: | Discard R1 / R2 if required + - min_trimmed_reads: + type: integer + description: | + Inputs with fewer than this reads will be filtered out of the "reads" output channel output: - reads: @@ -80,6 +84,9 @@ output: type: file description: Trim Galore! trimming report pattern: "*_{report.txt}" + - trim_read_count: + type: integer + description: Number of reads remaining after trimming for all input samples - versions: type: file description: File containing software versions From 71a2ddf925dea62c6957d19b01187b9f8a6cccfa Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 21 Mar 2023 12:44:44 +0000 Subject: [PATCH 056/124] Re-install updated trimgalore subworkflow --- modules.json | 2 +- subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf | 2 +- workflows/rnaseq.nf | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules.json b/modules.json index 58e99ffaa..368dc57c2 100644 --- a/modules.json +++ b/modules.json @@ -264,7 +264,7 @@ }, "fastq_fastqc_umitools_trimgalore": { "branch": "master", - "git_sha": "a1e1f3fc75c5fff7df88845a7f3d1b6145e0e649", + "git_sha": "100caf3506850ffcc04953f724a97f422940c377", "installed_by": ["subworkflows"] }, "fastq_subsample_fq_salmon": { diff --git a/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf b/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf index f50cb47bb..db2e5b329 100644 --- a/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf +++ b/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf @@ -97,7 +97,7 @@ workflow FASTQ_FASTQC_UMITOOLS_TRIMGALORE { ch_num_trimmed_reads .filter { meta, reads, num_reads -> num_reads >= min_trimmed_reads.toFloat() } - .map { meta, reads, num_reads -> [ meta, num_reads ] } + .map { meta, reads, num_reads -> [ meta, reads ] } .set { trim_reads } ch_num_trimmed_reads diff --git a/workflows/rnaseq.nf b/workflows/rnaseq.nf index bb2fcf5ae..bdce3c597 100755 --- a/workflows/rnaseq.nf +++ b/workflows/rnaseq.nf @@ -270,7 +270,8 @@ workflow RNASEQ { params.with_umi, params.skip_umi_extract, params.skip_trimming, - params.umi_discard_read + params.umi_discard_read, + params.min_trimmed_reads ) ch_versions = ch_versions.mix(FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.versions) From a0370ade047f8c592080966c90aac087421173c2 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 20 Mar 2023 12:54:57 +0000 Subject: [PATCH 057/124] Tweak comments --- .github/workflows/awsfulltest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index ce5031274..030e950d1 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -12,7 +12,7 @@ jobs: name: Run AWS full tests if: github.repository == 'nf-core/rnaseq' runs-on: ubuntu-latest - # Do a full-scale run with each of the three aligners + # Do a full-scale run with different aligners strategy: matrix: aligner: ["star_salmon", "star_rsem"] From d9e038c4cf97681f77e1ae2fed68d03b09987453 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 20 Mar 2023 12:55:16 +0000 Subject: [PATCH 058/124] Add test for --trimmer fastp --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b3d0ae611..fc63a1509 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,6 +82,7 @@ jobs: - "--bam_csi_index" - "--save_align_intermeds --save_reference" - "--featurecounts_group_type false" + - "--trimmer fastp" steps: - name: Check out pipeline code uses: actions/checkout@v2 From e34697bb7e8862615526b1a9ebe7e1ce9eb4988f Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 20 Mar 2023 12:55:41 +0000 Subject: [PATCH 059/124] Initialise --trimmer fastp parameter --- CITATIONS.md | 4 ++++ nextflow.config | 1 + nextflow_schema.json | 7 +++++++ 3 files changed, 12 insertions(+) diff --git a/CITATIONS.md b/CITATIONS.md index 52f50cf87..5e9d106fd 100644 --- a/CITATIONS.md +++ b/CITATIONS.md @@ -16,6 +16,10 @@ > Quinlan AR, Hall IM. BEDTools: a flexible suite of utilities for comparing genomic features. Bioinformatics. 2010 Mar 15;26(6):841-2. doi: 10.1093/bioinformatics/btq033. Epub 2010 Jan 28. PubMed PMID: 20110278; PubMed Central PMCID: PMC2832824. +- [fastp](https://www.ncbi.nlm.nih.gov/pubmed/30423086/) + + > Chen S, Zhou Y, Chen Y, Gu J. fastp: an ultra-fast all-in-one FASTQ preprocessor. Bioinformatics. 2018 Sep 1;34(17):i884-i890. doi: 10.1093/bioinformatics/bty560. PubMed PMID: 30423086; PubMed Central PMCID: PMC6129281. + - [FastQC](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/) - [featureCounts](https://pubmed.ncbi.nlm.nih.gov/24227677/) diff --git a/nextflow.config b/nextflow.config index bd16cf4fe..1e3d5b2f8 100644 --- a/nextflow.config +++ b/nextflow.config @@ -37,6 +37,7 @@ params { save_umi_intermeds = false // Trimming + trimmer = 'trimgalore' min_trimmed_reads = 10000 clip_r1 = null clip_r2 = null diff --git a/nextflow_schema.json b/nextflow_schema.json index 66ce7c4a8..c679fc61a 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -326,6 +326,13 @@ "fa_icon": "fas fa-cut", "description": "Options to adjust read trimming criteria.", "properties": { + "trimmer": { + "type": "string", + "default": "trimgalore", + "description": "Specifies the trimming tool to use - available options are 'trimgalore' and 'fastp'.", + "fa_icon": "fas fa-cut", + "enum": ["trimgalore", "fastp"] + }, "clip_r1": { "type": "integer", "description": "Instructs Trim Galore to remove bp from the 5' end of read 1 (or single-end reads).", From f4e6abd188c2637cc36b844e978c21ac376be0bb Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 20 Mar 2023 12:56:40 +0000 Subject: [PATCH 060/124] Add output docs for --trimmer fastp --- CHANGELOG.md | 1 + docs/images/mqc_fastp_plot.png | Bin 0 -> 18563 bytes docs/output.md | 23 ++++++++++++++++++++++- 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100755 docs/images/mqc_fastp_plot.png diff --git a/CHANGELOG.md b/CHANGELOG.md index cfc673a85..0a6f76cec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ Thank you to everyone else that has contributed by reporting bugs, enhancements | Old parameter | New parameter | | ------------- | ------------- | | `--tracedir` | | +| | `--trimmer` | > **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. diff --git a/docs/images/mqc_fastp_plot.png b/docs/images/mqc_fastp_plot.png new file mode 100755 index 0000000000000000000000000000000000000000..798539ca31153fb1317c4393a9dfd7d089e3bf81 GIT binary patch literal 18563 zcmeIa2UL?=yDo~dl%kS<8CD!qmdfk144bWJEyv*-+Y6d(bT^WnemKkmQpf5zEkpR@PA_m0gNj4$8JS7v$U`#$e8-AU}bVA4S-kb~n9zs7^RhJn^A6FdnN#7G6Yb+#}}HUIHZEjV zt`+(8Fo=y?DL?xAPaOd2d1BxQ0}mWI-t>=k=arR7r0t(P4O}9VDYVox}79ÑqxqtYItldAn5%t-B!|!_Y`lG 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 -[Trim Galore!](https://www.bioinformatics.babraham.ac.uk/projects/trim_galore/) is a wrapper tool around Cutadapt and FastQC to peform quality and adapter trimming on FastQ files. By default, Trim Galore! will automatically detect and trim the appropriate adapter sequence. +[Trim Galore!](https://www.bioinformatics.babraham.ac.uk/projects/trim_galore/) is a wrapper tool around Cutadapt and FastQC to peform quality and adapter trimming on FastQ files. Trim Galore! will automatically detect and trim the appropriate adapter sequence. It is the default trimming tool used by this pipeline, however you can use fastp instead by specifying the `--trimmer fastp` parameter. > **NB:** TrimGalore! will only run using multiple cores if you are able to use more than > 5 and > 6 CPUs for single- and paired-end data, respectively. The total cores available to TrimGalore! will also be capped at 4 (7 and 8 CPUs in total for single- and paired-end data, respectively) because there is no longer a run-time benefit. See [release notes](https://github.com/FelixKrueger/TrimGalore/blob/master/Changelog.md#version-060-release-on-1-mar-2019) and [discussion whilst adding this logic to the nf-core/atacseq pipeline](https://github.com/nf-core/atacseq/pull/65). ![MultiQC - cutadapt trimmed sequence length plot](images/mqc_cutadapt_trimmed.png) +### fastp + +
+Output files + +- `fastp/` + - `*.fastp.html`: Trimming report in html format. + - `*.fastp.json`: Trimming report in json format. +- `fastp/log/` + - `*.fastp.log`: Trimming log file. +- `fastqc/trim/` + - `*_fastqc.html`: FastQC report of the trimmed reads. + - `*_fastqc.zip`: Zip archive containing the FastQC report, tab-delimited data file and plot images. + +
+ +[fastp](https://github.com/OpenGene/fastp) is a tool designed to provide fast, all-in-one preprocessing for FastQ files. It has been developed in C++ with multithreading support to achieve higher performance. fastp can be used in this pipeline for standard adapter trimming and quality filtering by setting the `--trimmer fastp` parameter. + +![MultiQC - fastp filtered reads plot](images/mqc_fastp_plot.png) + ### BBSplit
From 75b2690dd867101cfeea2bdd1aec216f63aa5bf8 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 20 Mar 2023 12:56:57 +0000 Subject: [PATCH 061/124] Install nf-core/module for fastp --- modules.json | 5 ++ modules/nf-core/fastp/main.nf | 102 +++++++++++++++++++++++++++++++++ modules/nf-core/fastp/meta.yml | 73 +++++++++++++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 modules/nf-core/fastp/main.nf create mode 100644 modules/nf-core/fastp/meta.yml diff --git a/modules.json b/modules.json index 368dc57c2..c6ddb2ce8 100644 --- a/modules.json +++ b/modules.json @@ -25,6 +25,11 @@ "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", "installed_by": ["modules"] }, + "fastp": { + "branch": "master", + "git_sha": "20a508676f40d0fd3f911ac595af91ec845704c4", + "installed_by": ["modules"] + }, "fastqc": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", diff --git a/modules/nf-core/fastp/main.nf b/modules/nf-core/fastp/main.nf new file mode 100644 index 000000000..5eeb9b09e --- /dev/null +++ b/modules/nf-core/fastp/main.nf @@ -0,0 +1,102 @@ +process FASTP { + tag "$meta.id" + label 'process_medium' + + conda "bioconda::fastp=0.23.2" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/fastp:0.23.2--h79da9fb_0' : + 'quay.io/biocontainers/fastp:0.23.2--h79da9fb_0' }" + + input: + tuple val(meta), path(reads) + path adapter_fasta + val save_trimmed_fail + val save_merged + + output: + tuple val(meta), path('*.fastp.fastq.gz') , optional:true, emit: reads + tuple val(meta), path('*.json') , emit: json + tuple val(meta), path('*.html') , emit: html + tuple val(meta), path('*.log') , emit: log + path "versions.yml" , emit: versions + tuple val(meta), path('*.fail.fastq.gz') , optional:true, emit: reads_fail + tuple val(meta), path('*.merged.fastq.gz'), optional:true, emit: reads_merged + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def adapter_list = adapter_fasta ? "--adapter_fasta ${adapter_fasta}" : "" + def fail_fastq = save_trimmed_fail && meta.single_end ? "--failed_out ${prefix}.fail.fastq.gz" : save_trimmed_fail && !meta.single_end ? "--unpaired1 ${prefix}_1.fail.fastq.gz --unpaired2 ${prefix}_2.fail.fastq.gz" : '' + // Added soft-links to original fastqs for consistent naming in MultiQC + // Use single ended for interleaved. Add --interleaved_in in config. + if ( task.ext.args?.contains('--interleaved_in') ) { + """ + [ ! -f ${prefix}.fastq.gz ] && ln -sf $reads ${prefix}.fastq.gz + + fastp \\ + --stdout \\ + --in1 ${prefix}.fastq.gz \\ + --thread $task.cpus \\ + --json ${prefix}.fastp.json \\ + --html ${prefix}.fastp.html \\ + $adapter_list \\ + $fail_fastq \\ + $args \\ + 2> ${prefix}.fastp.log \\ + | gzip -c > ${prefix}.fastp.fastq.gz + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fastp: \$(fastp --version 2>&1 | sed -e "s/fastp //g") + END_VERSIONS + """ + } else if (meta.single_end) { + """ + [ ! -f ${prefix}.fastq.gz ] && ln -sf $reads ${prefix}.fastq.gz + + fastp \\ + --in1 ${prefix}.fastq.gz \\ + --out1 ${prefix}.fastp.fastq.gz \\ + --thread $task.cpus \\ + --json ${prefix}.fastp.json \\ + --html ${prefix}.fastp.html \\ + $adapter_list \\ + $fail_fastq \\ + $args \\ + 2> ${prefix}.fastp.log + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fastp: \$(fastp --version 2>&1 | sed -e "s/fastp //g") + END_VERSIONS + """ + } else { + def merge_fastq = save_merged ? "-m --merged_out ${prefix}.merged.fastq.gz" : '' + """ + [ ! -f ${prefix}_1.fastq.gz ] && ln -sf ${reads[0]} ${prefix}_1.fastq.gz + [ ! -f ${prefix}_2.fastq.gz ] && ln -sf ${reads[1]} ${prefix}_2.fastq.gz + fastp \\ + --in1 ${prefix}_1.fastq.gz \\ + --in2 ${prefix}_2.fastq.gz \\ + --out1 ${prefix}_1.fastp.fastq.gz \\ + --out2 ${prefix}_2.fastp.fastq.gz \\ + --json ${prefix}.fastp.json \\ + --html ${prefix}.fastp.html \\ + $adapter_list \\ + $fail_fastq \\ + $merge_fastq \\ + --thread $task.cpus \\ + --detect_adapter_for_pe \\ + $args \\ + 2> ${prefix}.fastp.log + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fastp: \$(fastp --version 2>&1 | sed -e "s/fastp //g") + END_VERSIONS + """ + } +} diff --git a/modules/nf-core/fastp/meta.yml b/modules/nf-core/fastp/meta.yml new file mode 100644 index 000000000..197ea7ca6 --- /dev/null +++ b/modules/nf-core/fastp/meta.yml @@ -0,0 +1,73 @@ +name: fastp +description: Perform adapter/quality trimming on sequencing reads +keywords: + - trimming + - quality control + - fastq +tools: + - fastp: + description: | + A tool designed to provide fast all-in-one preprocessing for FastQ files. This tool is developed in C++ with multithreading supported to afford high performance. + documentation: https://github.com/OpenGene/fastp + doi: 10.1093/bioinformatics/bty560 + licence: ["MIT"] +input: + - meta: + type: map + description: | + Groovy Map containing sample information. Use 'single_end: true' to specify single ended or interleaved FASTQs. Use 'single_end: false' for paired-end reads. + 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. If you wish to run interleaved paired-end data, supply as single-end data + but with `--interleaved_in` in your `modules.conf`'s `ext.args` for the module. + - adapter_fasta: + type: file + description: File in FASTA format containing possible adapters to remove. + pattern: "*.{fasta,fna,fas,fa}" + - save_trimmed_fail: + type: boolean + description: Specify true to save files that failed to pass trimming thresholds ending in `*.fail.fastq.gz` + - save_merged: + type: boolean + description: Specify true to save all merged reads to the a file ending in `*.merged.fastq.gz` + +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: The trimmed/modified/unmerged fastq reads + pattern: "*fastp.fastq.gz" + - json: + type: file + description: Results in JSON format + pattern: "*.json" + - html: + type: file + description: Results in HTML format + pattern: "*.html" + - log: + type: file + description: fastq log file + pattern: "*.log" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + - reads_fail: + type: file + description: Reads the failed the preprocessing + pattern: "*fail.fastq.gz" + - reads_merged: + type: file + description: Reads that were successfully merged + pattern: "*.{merged.fastq.gz}" +authors: + - "@drpatelh" + - "@kevinmenden" From f51f86107699826f6f6d3aa919234f63c6464d3e Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 20 Mar 2023 12:57:19 +0000 Subject: [PATCH 062/124] Add check for valid --trimmer option to lib/ --- lib/WorkflowRnaseq.groovy | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/WorkflowRnaseq.groovy b/lib/WorkflowRnaseq.groovy index 33ce9ad72..4b4c247d3 100755 --- a/lib/WorkflowRnaseq.groovy +++ b/lib/WorkflowRnaseq.groovy @@ -58,6 +58,12 @@ class WorkflowRnaseq { } } + if (!params.skip_trimming) { + if (!valid_params['trimmers'].contains(params.trimmer)) { + log.error "Invalid option: '${params.trimmer}'. Valid options for '--trimmer': ${valid_params['trimmers'].join(', ')}." + System.exit(1) + } + } if (!params.skip_alignment) { if (!valid_params['aligners'].contains(params.aligner)) { From 1e50af1fa4e5c21baff93cb238bd551054ceb966 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 20 Mar 2023 12:57:40 +0000 Subject: [PATCH 063/124] Add subworkflow for fastp --- .../local/fastq_fastqc_umitools_fastp.nf | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 subworkflows/local/fastq_fastqc_umitools_fastp.nf diff --git a/subworkflows/local/fastq_fastqc_umitools_fastp.nf b/subworkflows/local/fastq_fastqc_umitools_fastp.nf new file mode 100644 index 000000000..37641d076 --- /dev/null +++ b/subworkflows/local/fastq_fastqc_umitools_fastp.nf @@ -0,0 +1,137 @@ +// +// Read QC, UMI extraction and trimming +// + +include { FASTQC as FASTQC_RAW } from '../../modules/nf-core/fastqc/main' +include { FASTQC as FASTQC_TRIM } from '../../modules/nf-core/fastqc/main' +include { UMITOOLS_EXTRACT } from '../../modules/nf-core/umitools/extract/main' +include { FASTP } from '../../modules/nf-core/fastp/main' + +// +// Function that parses fastp json output file to get total number of reads after trimming +// +import groovy.json.JsonSlurper + +def getFastpReadsAfterFiltering(json_file) { + def Map json = (Map) new JsonSlurper().parseText(json_file.text).get('summary') + return json['after_filtering']['total_reads'].toInteger() +} + +workflow FASTQ_FASTQC_UMITOOLS_FASTP { + take: + reads // channel: [ val(meta), [ reads ] ] + skip_fastqc // boolean: true/false + skip_umi_extract // boolean: true/false + umi_discard_read // integer: 0, 1 or 2 + skip_trimming // boolean: true/false + min_trimmed_reads // integer: >0 + adapter_fasta // file: adapter.fasta + save_trimmed_fail // boolean: true/false + save_merged // boolean: true/false + + main: + + ch_versions = Channel.empty() + + fastqc_raw_html = Channel.empty() + fastqc_raw_zip = Channel.empty() + if (!skip_fastqc) { + FASTQC_RAW ( + reads + ) + fastqc_raw_html = FASTQC_RAW.out.html + fastqc_raw_zip = FASTQC_RAW.out.zip + ch_versions = ch_versions.mix(FASTQC_RAW.out.versions.first()) + } + + umi_reads = reads + umi_log = Channel.empty() + if (!skip_umi_extract) { + UMITOOLS_EXTRACT ( + reads + ) + umi_reads = UMITOOLS_EXTRACT.out.reads + umi_log = UMITOOLS_EXTRACT.out.log + ch_versions = ch_versions.mix(UMITOOLS_EXTRACT.out.versions.first()) + + // Discard R1 / R2 if required + if (umi_discard_read in [1,2]) { + UMITOOLS_EXTRACT + .out + .reads + .map { meta, reads -> + if (!meta.single_end) { + meta['single_end'] = true + reads = reads[umi_discard_read % 2] + } + return [ meta, reads ] + } + .set { umi_reads } + } + } + + trim_reads = umi_reads + trim_json = Channel.empty() + trim_html = Channel.empty() + trim_log = Channel.empty() + trim_reads_fail = Channel.empty() + trim_reads_merged = Channel.empty() + fastqc_trim_html = Channel.empty() + fastqc_trim_zip = Channel.empty() + if (!skip_trimming) { + FASTP ( + reads, + adapter_fasta, + save_trimmed_fail, + save_merged + ) + trim_reads = FASTP.out.reads + trim_json = FASTP.out.json + trim_html = FASTP.out.html + trim_log = FASTP.out.log + trim_reads_fail = FASTP.out.reads_fail + trim_reads_merged = FASTP.out.reads_merged + ch_versions = ch_versions.mix(FASTP.out.versions.first()) + + // + // Filter empty FastQ files after adapter trimming so FastQC doesn't fail + // + trim_reads + .join(trim_json) + .map { + meta, reads, json -> + if (getFastpReadsAfterFiltering(json) > 0) { + [ meta, reads ] + } + } + .set { trim_reads } + + if (!skip_fastqc) { + FASTQC_TRIM ( + trim_reads + ) + fastqc_trim_html = FASTQC_TRIM.out.html + fastqc_trim_zip = FASTQC_TRIM.out.zip + ch_versions = ch_versions.mix(FASTQC_TRIM.out.versions.first()) + } + } + + emit: + reads = trim_reads // channel: [ val(meta), [ reads ] ] + + fastqc_raw_html // channel: [ val(meta), [ html ] ] + fastqc_raw_zip // channel: [ val(meta), [ zip ] ] + + umi_log // channel: [ val(meta), [ log ] ] + + trim_json // channel: [ val(meta), [ json ] ] + trim_html // channel: [ val(meta), [ html ] ] + trim_log // channel: [ val(meta), [ log ] ] + trim_reads_fail // channel: [ val(meta), [ fastq.gz ] ] + trim_reads_merged // channel: [ val(meta), [ fastq.gz ] ] + + fastqc_trim_html // channel: [ val(meta), [ html ] ] + fastqc_trim_zip // channel: [ val(meta), [ zip ] ] + + versions = ch_versions.ifEmpty(null) // channel: [ versions.yml ] +} From 2a2a1130c7f421a93190c5d6bde0b10b9fad01e9 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 20 Mar 2023 18:13:54 +0000 Subject: [PATCH 064/124] First pass implementation to add fastp to main workflow --- conf/modules.config | 113 +++++++++++++----- .../local/fastq_fastqc_umitools_fastp.nf | 25 +++- .../fastq_fastqc_umitools_trimgalore/main.nf | 1 + workflows/rnaseq.nf | 107 +++++++++-------- 4 files changed, 157 insertions(+), 89 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index ce83ef003..d46015f93 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -198,56 +198,103 @@ process { // if (!(params.skip_fastqc || params.skip_qc)) { - process { - withName: '.*:FASTQ_FASTQC_UMITOOLS_TRIMGALORE:FASTQC' { - ext.args = '--quiet' + if (params.trimmer == 'trimgalore') { + process { + withName: '.*:FASTQ_FASTQC_UMITOOLS_TRIMGALORE:FASTQC' { + ext.args = '--quiet' + } + } + } + + if (params.trimmer == 'fastp') { + process { + withName: '.*:FASTQ_FASTQC_UMITOOLS_FASTP:FASTQC_RAW' { + ext.args = '--quiet' + } + + withName: '.*:FASTQ_FASTQC_UMITOOLS_FASTP:FASTQC_TRIM' { + ext.args = '--quiet' + publishDir = [ + path: { "${params.outdir}/${params.trimmer}/fastqc" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } } } } if (!params.skip_trimming) { - process { - withName: '.*:FASTQ_FASTQC_UMITOOLS_TRIMGALORE:TRIMGALORE' { - ext.args = { - [ - "--fastqc_args '-t ${task.cpus}' ", - params.trim_nextseq > 0 ? "--nextseq ${params.trim_nextseq}" : '', - params.clip_r1 > 0 ? "--clip_r1 ${params.clip_r1}" : '', - params.clip_r2 > 0 && !meta.single_end ? "--clip_r2 ${params.clip_r2}" : '', - params.three_prime_clip_r1 > 0 ? "--three_prime_clip_r1 ${params.three_prime_clip_r1}" : '', - params.three_prime_clip_r2 > 0 && !meta.single_end ? "--three_prime_clip_r2 ${params.three_prime_clip_r2}" : '' - ].join(' ').trim() + if (params.trimmer == 'trimgalore') { + process { + withName: '.*:FASTQ_FASTQC_UMITOOLS_TRIMGALORE:TRIMGALORE' { + ext.args = { + [ + "--fastqc_args '-t ${task.cpus}' ", + params.trim_nextseq > 0 ? "--nextseq ${params.trim_nextseq}" : '', + params.clip_r1 > 0 ? "--clip_r1 ${params.clip_r1}" : '', + params.clip_r2 > 0 && !meta.single_end ? "--clip_r2 ${params.clip_r2}" : '', + params.three_prime_clip_r1 > 0 ? "--three_prime_clip_r1 ${params.three_prime_clip_r1}" : '', + params.three_prime_clip_r2 > 0 && !meta.single_end ? "--three_prime_clip_r2 ${params.three_prime_clip_r2}" : '' + ].join(' ').trim() + } + publishDir = [ + [ + path: { "${params.outdir}/${params.trimmer}/fastqc" }, + mode: params.publish_dir_mode, + pattern: "*.{html,zip}" + ], + [ + path: { "${params.outdir}/${params.trimmer}" }, + mode: params.publish_dir_mode, + pattern: "*.fq.gz", + enabled: params.save_trimmed + ], + [ + path: { "${params.outdir}/${params.trimmer}" }, + mode: params.publish_dir_mode, + pattern: "*.txt" + ] + ] } - publishDir = [ - [ - path: { "${params.outdir}/trimgalore/fastqc" }, - mode: params.publish_dir_mode, - pattern: "*.{html,zip}" - ], - [ - path: { "${params.outdir}/trimgalore" }, - mode: params.publish_dir_mode, - pattern: "*.fq.gz", - enabled: params.save_trimmed - ], - [ - path: { "${params.outdir}/trimgalore" }, - mode: params.publish_dir_mode, - pattern: "*.txt" + } + } + + if (params.trimmer == 'fastp') { + process { + withName: '.*:FASTQ_FASTQC_UMITOOLS_FASTP:FASTP' { + ext.args = '--trim_poly_x' + publishDir = [ + [ + path: { "${params.outdir}/${params.trimmer}" }, + mode: params.publish_dir_mode, + pattern: "*.{json,html}" + ], + [ + path: { "${params.outdir}/${params.trimmer}/log" }, + mode: params.publish_dir_mode, + pattern: "*.log" + ], + [ + path: { "${params.outdir}/${params.trimmer}" }, + mode: params.publish_dir_mode, + pattern: "*.fastq.gz", + enabled: params.save_trimmed + ] ] - ] + } } } } if (params.with_umi && !params.skip_umi_extract) { process { - withName: '.*:FASTQ_FASTQC_UMITOOLS_TRIMGALORE:UMITOOLS_EXTRACT' { + withName: 'UMITOOLS_EXTRACT' { ext.args = [ params.umitools_extract_method ? "--extract-method=${params.umitools_extract_method}" : '', params.umitools_bc_pattern ? "--bc-pattern='${params.umitools_bc_pattern}'" : '', params.umitools_bc_pattern2 ? "--bc-pattern2='${params.umitools_bc_pattern2}'" : '' - ].join(' ').trim() + ].join(' ').trim() publishDir = [ [ path: { "${params.outdir}/umitools" }, diff --git a/subworkflows/local/fastq_fastqc_umitools_fastp.nf b/subworkflows/local/fastq_fastqc_umitools_fastp.nf index 37641d076..dab317e0e 100644 --- a/subworkflows/local/fastq_fastqc_umitools_fastp.nf +++ b/subworkflows/local/fastq_fastqc_umitools_fastp.nf @@ -21,13 +21,14 @@ workflow FASTQ_FASTQC_UMITOOLS_FASTP { take: reads // channel: [ val(meta), [ reads ] ] skip_fastqc // boolean: true/false + with_umi // boolean: true/false skip_umi_extract // boolean: true/false umi_discard_read // integer: 0, 1 or 2 skip_trimming // boolean: true/false - min_trimmed_reads // integer: >0 adapter_fasta // file: adapter.fasta save_trimmed_fail // boolean: true/false save_merged // boolean: true/false + min_trimmed_reads // integer: > 0 main: @@ -46,7 +47,7 @@ workflow FASTQ_FASTQC_UMITOOLS_FASTP { umi_reads = reads umi_log = Channel.empty() - if (!skip_umi_extract) { + if (with_umi && !skip_umi_extract) { UMITOOLS_EXTRACT ( reads ) @@ -78,6 +79,7 @@ workflow FASTQ_FASTQC_UMITOOLS_FASTP { trim_reads_merged = Channel.empty() fastqc_trim_html = Channel.empty() fastqc_trim_zip = Channel.empty() + trim_read_count = Channel.empty() if (!skip_trimming) { FASTP ( reads, @@ -94,17 +96,29 @@ workflow FASTQ_FASTQC_UMITOOLS_FASTP { ch_versions = ch_versions.mix(FASTP.out.versions.first()) // - // Filter empty FastQ files after adapter trimming so FastQC doesn't fail + // Filter FastQ files based on minimum trimmed read count after adapter trimming // trim_reads .join(trim_json) .map { - meta, reads, json -> - if (getFastpReadsAfterFiltering(json) > 0) { + meta, reads, json -> [ meta, reads, getFastpReadsAfterFiltering(json) ] + } + .set { ch_num_trimmed_reads } + + ch_num_trimmed_reads + .map { + meta, reads, num_reads -> + if (num_reads >= min_trimmed_reads.toInteger()) { [ meta, reads ] } } .set { trim_reads } + + ch_num_trimmed_reads + .map { + meta, reads, num_reads -> [ meta, num_reads ] + } + .set { trim_read_count } if (!skip_fastqc) { FASTQC_TRIM ( @@ -129,6 +143,7 @@ workflow FASTQ_FASTQC_UMITOOLS_FASTP { trim_log // channel: [ val(meta), [ log ] ] trim_reads_fail // channel: [ val(meta), [ fastq.gz ] ] trim_reads_merged // channel: [ val(meta), [ fastq.gz ] ] + trim_read_count // channel: [ val(meta), val(count) ] fastqc_trim_html // channel: [ val(meta), [ html ] ] fastqc_trim_zip // channel: [ val(meta), [ zip ] ] diff --git a/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf b/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf index db2e5b329..f7f48d15b 100644 --- a/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf +++ b/subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main.nf @@ -33,6 +33,7 @@ workflow FASTQ_FASTQC_UMITOOLS_TRIMGALORE { main: ch_versions = Channel.empty() + fastqc_html = Channel.empty() fastqc_zip = Channel.empty() if (!skip_fastqc) { diff --git a/workflows/rnaseq.nf b/workflows/rnaseq.nf index bdce3c597..c74fb8e13 100755 --- a/workflows/rnaseq.nf +++ b/workflows/rnaseq.nf @@ -6,6 +6,7 @@ def valid_params = [ aligners : ['star_salmon', 'star_rsem', 'hisat2'], + trimmers : ['trimgalore', 'fastp'], pseudoaligners : ['salmon'], rseqc_modules : ['bam_stat', 'inner_distance', 'infer_experiment', 'junction_annotation', 'junction_saturation', 'read_distribution', 'read_duplication', 'tin'] ] @@ -108,6 +109,7 @@ include { INPUT_CHECK } from '../subworkflows/local/input_check' include { PREPARE_GENOME } from '../subworkflows/local/prepare_genome' include { ALIGN_STAR } from '../subworkflows/local/align_star' include { QUANTIFY_RSEM } from '../subworkflows/local/quantify_rsem' +include { FASTQ_FASTQC_UMITOOLS_FASTP } from '../subworkflows/local/fastq_fastqc_umitools_fastp' include { QUANTIFY_SALMON as QUANTIFY_STAR_SALMON } from '../subworkflows/local/quantify_salmon' include { QUANTIFY_SALMON as QUANTIFY_SALMON } from '../subworkflows/local/quantify_salmon' @@ -262,63 +264,66 @@ workflow RNASEQ { .set { ch_strand_inferred_fastq } // - // SUBWORKFLOW: Read QC, extract UMI and trim adapters + // SUBWORKFLOW: Read QC, extract UMI and trim adapters with TrimGalore! // - FASTQ_FASTQC_UMITOOLS_TRIMGALORE ( - ch_strand_inferred_fastq, - params.skip_fastqc || params.skip_qc, - params.with_umi, - params.skip_umi_extract, - params.skip_trimming, - params.umi_discard_read, - params.min_trimmed_reads - ) - ch_versions = ch_versions.mix(FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.versions) + ch_filtered_reads = Channel.empty() + ch_trim_read_count = Channel.empty() + if (params.trimmer == 'trimgalore') { + FASTQ_FASTQC_UMITOOLS_TRIMGALORE ( + ch_strand_inferred_fastq, + params.skip_fastqc || params.skip_qc, + params.with_umi, + params.skip_umi_extract, + params.skip_trimming, + params.umi_discard_read, + params.min_trimmed_reads + ) + ch_filtered_reads = FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.reads + ch_trim_read_count = FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.trim_read_count + ch_versions = ch_versions.mix(FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.versions) + } // - // Filter channels to get samples that passed minimum trimmed read count + // SUBWORKFLOW: Read QC, extract UMI and trim adapters with fastp // - ch_fail_trimming_multiqc = Channel.empty() - ch_filtered_reads = FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.reads - if (!params.skip_trimming) { - ch_filtered_reads - .join(FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.trim_log, remainder: true) - .map { - meta, reads, trim_log -> - if (trim_log) { - if (!meta.single_end) { - trim_log = trim_log[-1] - } - num_reads = WorkflowRnaseq.getTrimGaloreReadsAfterFiltering(trim_log) - [ meta, reads, num_reads ] - } else { - [ meta, reads, params.min_trimmed_reads + 1 ] - } - } - .set { ch_num_trimmed_reads } - - ch_num_trimmed_reads - .map { meta, reads, num_reads -> if (num_reads > params.min_trimmed_reads) [ meta, reads ] } - .set { ch_filtered_reads } - - ch_num_trimmed_reads - .map { - meta, reads, num_reads -> - pass_trimmed_reads[meta.id] = true - if (num_reads <= params.min_trimmed_reads) { - pass_trimmed_reads[meta.id] = false - return [ "$meta.id\t$num_reads" ] - } - } - .collect() - .map { - tsv_data -> - def header = ["Sample", "Reads after trimming"] - WorkflowRnaseq.multiqcTsvFromList(tsv_data, header) - } - .set { ch_fail_trimming_multiqc } + if (params.trimmer == 'fastp') { + FASTQ_FASTQC_UMITOOLS_FASTP ( + ch_strand_inferred_fastq, + params.skip_fastqc || params.skip_qc, + params.with_umi, + params.skip_umi_extract, + params.umi_discard_read, + params.skip_trimming, + [], + params.save_trimmed, + params.save_trimmed, + params.min_trimmed_reads + ) + ch_filtered_reads = FASTQ_FASTQC_UMITOOLS_FASTP.out.reads + ch_trim_read_count = FASTQ_FASTQC_UMITOOLS_FASTP.out.trim_read_count + ch_versions = ch_versions.mix(FASTQ_FASTQC_UMITOOLS_FASTP.out.versions) } + // + // Get list of samples that failed trimming threshold for MultiQC report + // + ch_trim_read_count + .map { + meta, num_reads -> + pass_trimmed_reads[meta.id] = true + if (num_reads <= params.min_trimmed_reads.toFloat()) { + pass_trimmed_reads[meta.id] = false + return [ "$meta.id\t$num_reads" ] + } + } + .collect() + .map { + tsv_data -> + def header = ["Sample", "Reads after trimming"] + WorkflowRnaseq.multiqcTsvFromList(tsv_data, header) + } + .set { ch_fail_trimming_multiqc } + // // MODULE: Remove genome contaminant reads // From 4ad2949a9ae394b02101891cedf3f69ec4f67ed9 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 21 Mar 2023 09:16:38 +0000 Subject: [PATCH 065/124] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a6f76cec..bca372944 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ Thank you to everyone else that has contributed by reporting bugs, enhancements ### Enhancements & fixes +- [[#663](https://github.com/nf-core/rnaseq/pull/663)] - Alternative trimming step for polyA/T removal +- [[#781](https://github.com/nf-core/rnaseq/pull/781)] - Add Warning for poly(A) libraries - [[#878](https://github.com/nf-core/rnaseq/pull/878)] - Allow tabs in fasta header when creating decoys for salmon index - [[#931](https://github.com/nf-core/rnaseq/pull/931)] - Save transcriptome BAM files when using `--save_umi_intermeds` / `--save_align_intermeds` - [[#934](https://github.com/nf-core/rnaseq/pull/934)] - Union of `ext.args` and `params.extra_star_align_args` prevents parameter clashes in the STAR module @@ -47,6 +49,7 @@ Note, since the pipeline is now using Nextflow DSL2, each process will be run wi | Dependency | Old version | New version | | ----------- | ----------- | ----------- | +| `fastp` | | 0.23.2 | | `multiqc` | 1.13 | 1.14 | | `picard` | 2.27.4 | 3.0.0 | | `umi_tools` | 1.1.2 | 1.1.4 | From 9fcc9647b32e8312297c1849058dae8ad220f9c7 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 21 Mar 2023 09:56:05 +0000 Subject: [PATCH 066/124] Add Fastp reports to MultiQC --- assets/multiqc_config.yml | 9 +++++++-- modules/local/multiqc.nf | 6 +++--- workflows/rnaseq.nf | 27 ++++++++++++++++++--------- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/assets/multiqc_config.yml b/assets/multiqc_config.yml index 09b6b262b..736156783 100644 --- a/assets/multiqc_config.yml +++ b/assets/multiqc_config.yml @@ -17,6 +17,7 @@ run_modules: - custom_content - fastqc - cutadapt + - fastp - sortmerna - star - hisat2 @@ -47,13 +48,14 @@ module_order: name: "FastQC (raw)" info: "This section of the report shows FastQC results before adapter trimming." path_filters: - - "./fastqc/*.zip" + - "./fastqc/raw/*.zip" - cutadapt + - fastp - fastqc: name: "FastQC (trimmed)" info: "This section of the report shows FastQC results after adapter trimming." path_filters: - - "./trimgalore/fastqc/*.zip" + - "./fastqc/trim/*.zip" # Don't show % Dups in the General Stats table (we have this from Picard) table_columns_visible: @@ -74,6 +76,9 @@ sp: cutadapt: fn: "*trimming_report.txt" + fastp: + fn: "*.fastp.json" + sortmerna: fn: "*.sortmerna.log" diff --git a/modules/local/multiqc.nf b/modules/local/multiqc.nf index b50d44c7d..802cebea9 100644 --- a/modules/local/multiqc.nf +++ b/modules/local/multiqc.nf @@ -16,9 +16,9 @@ process MULTIQC { path fail_trimming_summary path fail_mapping_summary path fail_strand_check - path ('fastqc/*') - path ('trimgalore/fastqc/*') - path ('trimgalore/*') + path ('fastqc/raw/*') + path ('fastqc/trim/*') + path ('trim_log/*') path ('sortmerna/*') path ('star/*') path ('hisat2/*') diff --git a/workflows/rnaseq.nf b/workflows/rnaseq.nf index c74fb8e13..6525b9269 100755 --- a/workflows/rnaseq.nf +++ b/workflows/rnaseq.nf @@ -266,8 +266,11 @@ workflow RNASEQ { // // SUBWORKFLOW: Read QC, extract UMI and trim adapters with TrimGalore! // - ch_filtered_reads = Channel.empty() - ch_trim_read_count = Channel.empty() + ch_filtered_reads = Channel.empty() + ch_fastqc_raw_multiqc = Channel.empty() + ch_fastqc_trim_multiqc = Channel.empty() + ch_trim_log_multiqc = Channel.empty() + ch_trim_read_count = Channel.empty() if (params.trimmer == 'trimgalore') { FASTQ_FASTQC_UMITOOLS_TRIMGALORE ( ch_strand_inferred_fastq, @@ -278,8 +281,11 @@ workflow RNASEQ { params.umi_discard_read, params.min_trimmed_reads ) - ch_filtered_reads = FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.reads - ch_trim_read_count = FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.trim_read_count + ch_filtered_reads = FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.reads + ch_fastqc_raw_multiqc = FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.fastqc_zip + ch_fastqc_trim_multiqc = FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.trim_zip + ch_trim_log_multiqc = FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.trim_log + ch_trim_read_count = FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.trim_read_count ch_versions = ch_versions.mix(FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.versions) } @@ -299,8 +305,11 @@ workflow RNASEQ { params.save_trimmed, params.min_trimmed_reads ) - ch_filtered_reads = FASTQ_FASTQC_UMITOOLS_FASTP.out.reads - ch_trim_read_count = FASTQ_FASTQC_UMITOOLS_FASTP.out.trim_read_count + ch_filtered_reads = FASTQ_FASTQC_UMITOOLS_FASTP.out.reads + ch_fastqc_raw_multiqc = FASTQ_FASTQC_UMITOOLS_FASTP.out.fastqc_raw_zip + ch_fastqc_trim_multiqc = FASTQ_FASTQC_UMITOOLS_FASTP.out.fastqc_trim_zip + ch_trim_log_multiqc = FASTQ_FASTQC_UMITOOLS_FASTP.out.trim_json + ch_trim_read_count = FASTQ_FASTQC_UMITOOLS_FASTP.out.trim_read_count ch_versions = ch_versions.mix(FASTQ_FASTQC_UMITOOLS_FASTP.out.versions) } @@ -833,9 +842,9 @@ workflow RNASEQ { ch_fail_trimming_multiqc.collectFile(name: 'fail_trimmed_samples_mqc.tsv').ifEmpty([]), ch_fail_mapping_multiqc.collectFile(name: 'fail_mapped_samples_mqc.tsv').ifEmpty([]), ch_fail_strand_multiqc.collectFile(name: 'fail_strand_check_mqc.tsv').ifEmpty([]), - FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.fastqc_zip.collect{it[1]}.ifEmpty([]), - FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.trim_zip.collect{it[1]}.ifEmpty([]), - FASTQ_FASTQC_UMITOOLS_TRIMGALORE.out.trim_log.collect{it[1]}.ifEmpty([]), + ch_fastqc_raw_multiqc.collect{it[1]}.ifEmpty([]), + ch_fastqc_trim_multiqc.collect{it[1]}.ifEmpty([]), + ch_trim_log_multiqc.collect{it[1]}.ifEmpty([]), ch_sortmerna_multiqc.collect{it[1]}.ifEmpty([]), ch_star_multiqc.collect{it[1]}.ifEmpty([]), ch_hisat2_multiqc.collect{it[1]}.ifEmpty([]), From 431107a3cc21cbdd6e726d1c228a2810739ba5b1 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 21 Mar 2023 17:00:26 +0000 Subject: [PATCH 067/124] Install fastq_fastqc_umitools_fastp.nf subworkflow from nf-core modules --- modules.json | 11 +- .../fastq_fastqc_umitools_fastp/main.nf} | 46 +++---- .../fastq_fastqc_umitools_fastp/meta.yml | 122 ++++++++++++++++++ workflows/rnaseq.nf | 2 +- 4 files changed, 148 insertions(+), 33 deletions(-) rename subworkflows/{local/fastq_fastqc_umitools_fastp.nf => nf-core/fastq_fastqc_umitools_fastp/main.nf} (78%) create mode 100644 subworkflows/nf-core/fastq_fastqc_umitools_fastp/meta.yml diff --git a/modules.json b/modules.json index c6ddb2ce8..d1eaf703c 100644 --- a/modules.json +++ b/modules.json @@ -28,12 +28,12 @@ "fastp": { "branch": "master", "git_sha": "20a508676f40d0fd3f911ac595af91ec845704c4", - "installed_by": ["modules"] + "installed_by": ["modules", "fastq_fastqc_umitools_fastp"] }, "fastqc": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["fastq_fastqc_umitools_trimgalore"] + "installed_by": ["fastq_fastqc_umitools_trimgalore", "fastq_fastqc_umitools_fastp"] }, "fq/subsample": { "branch": "master", @@ -217,7 +217,7 @@ "umitools/extract": { "branch": "master", "git_sha": "6d9c7e43404e20a97d2f6f88548456afe78282e6", - "installed_by": ["fastq_fastqc_umitools_trimgalore"] + "installed_by": ["fastq_fastqc_umitools_trimgalore", "fastq_fastqc_umitools_fastp"] }, "untar": { "branch": "master", @@ -267,6 +267,11 @@ "git_sha": "9057e75e8ac959373a72a9402130fdea2e2d1398", "installed_by": ["subworkflows"] }, + "fastq_fastqc_umitools_fastp": { + "branch": "master", + "git_sha": "4c8c5b5c084a99d9bf4f987040ebe88ec12b705d", + "installed_by": ["subworkflows"] + }, "fastq_fastqc_umitools_trimgalore": { "branch": "master", "git_sha": "100caf3506850ffcc04953f724a97f422940c377", diff --git a/subworkflows/local/fastq_fastqc_umitools_fastp.nf b/subworkflows/nf-core/fastq_fastqc_umitools_fastp/main.nf similarity index 78% rename from subworkflows/local/fastq_fastqc_umitools_fastp.nf rename to subworkflows/nf-core/fastq_fastqc_umitools_fastp/main.nf index dab317e0e..42638943d 100644 --- a/subworkflows/local/fastq_fastqc_umitools_fastp.nf +++ b/subworkflows/nf-core/fastq_fastqc_umitools_fastp/main.nf @@ -2,10 +2,10 @@ // Read QC, UMI extraction and trimming // -include { FASTQC as FASTQC_RAW } from '../../modules/nf-core/fastqc/main' -include { FASTQC as FASTQC_TRIM } from '../../modules/nf-core/fastqc/main' -include { UMITOOLS_EXTRACT } from '../../modules/nf-core/umitools/extract/main' -include { FASTP } from '../../modules/nf-core/fastp/main' +include { FASTQC as FASTQC_RAW } from '../../../modules/nf-core/fastqc/main' +include { FASTQC as FASTQC_TRIM } from '../../../modules/nf-core/fastqc/main' +include { UMITOOLS_EXTRACT } from '../../../modules/nf-core/umitools/extract/main' +include { FASTP } from '../../../modules/nf-core/fastp/main' // // Function that parses fastp json output file to get total number of reads after trimming @@ -31,9 +31,7 @@ workflow FASTQ_FASTQC_UMITOOLS_FASTP { min_trimmed_reads // integer: > 0 main: - ch_versions = Channel.empty() - fastqc_raw_html = Channel.empty() fastqc_raw_zip = Channel.empty() if (!skip_fastqc) { @@ -48,8 +46,8 @@ workflow FASTQ_FASTQC_UMITOOLS_FASTP { umi_reads = reads umi_log = Channel.empty() if (with_umi && !skip_umi_extract) { - UMITOOLS_EXTRACT ( - reads + UMITOOLS_EXTRACT ( + reads ) umi_reads = UMITOOLS_EXTRACT.out.reads umi_log = UMITOOLS_EXTRACT.out.log @@ -60,12 +58,9 @@ workflow FASTQ_FASTQC_UMITOOLS_FASTP { UMITOOLS_EXTRACT .out .reads - .map { meta, reads -> - if (!meta.single_end) { - meta['single_end'] = true - reads = reads[umi_discard_read % 2] - } - return [ meta, reads ] + .map { + meta, reads -> + meta.single_end ? [ meta, reads ] : [ meta + [single_end: true], reads[umi_discard_read % 2] ] } .set { umi_reads } } @@ -87,7 +82,6 @@ workflow FASTQ_FASTQC_UMITOOLS_FASTP { save_trimmed_fail, save_merged ) - trim_reads = FASTP.out.reads trim_json = FASTP.out.json trim_html = FASTP.out.html trim_log = FASTP.out.log @@ -98,26 +92,20 @@ workflow FASTQ_FASTQC_UMITOOLS_FASTP { // // Filter FastQ files based on minimum trimmed read count after adapter trimming // - trim_reads + FASTP + .out + .reads .join(trim_json) - .map { - meta, reads, json -> [ meta, reads, getFastpReadsAfterFiltering(json) ] - } + .map { meta, reads, json -> [ meta, reads, getFastpReadsAfterFiltering(json) ] } .set { ch_num_trimmed_reads } ch_num_trimmed_reads - .map { - meta, reads, num_reads -> - if (num_reads >= min_trimmed_reads.toInteger()) { - [ meta, reads ] - } - } + .filter { meta, reads, num_reads -> num_reads >= min_trimmed_reads.toInteger() } + .map { meta, reads, num_reads -> [ meta, reads ] } .set { trim_reads } - + ch_num_trimmed_reads - .map { - meta, reads, num_reads -> [ meta, num_reads ] - } + .map { meta, reads, num_reads -> [ meta, num_reads ] } .set { trim_read_count } if (!skip_fastqc) { diff --git a/subworkflows/nf-core/fastq_fastqc_umitools_fastp/meta.yml b/subworkflows/nf-core/fastq_fastqc_umitools_fastp/meta.yml new file mode 100644 index 000000000..d80ebc0a1 --- /dev/null +++ b/subworkflows/nf-core/fastq_fastqc_umitools_fastp/meta.yml @@ -0,0 +1,122 @@ +name: "fastq_fastqc_umitools_fastp" +description: Read QC, UMI extraction and trimming +keywords: + - fastq + - fastqc + - qc + - UMI + - trimming + - fastp +modules: + - fastqc + - umitools/extract + - fastp +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - reads: + type: file + description: | + List of input FastQ files of size 1 and 2 for single-end and paired-end data, + respectively. + - skip_fastqc: + type: boolean + description: | + Skip fastqc process + - with_umi: + type: boolean + description: | + With or without umi detection + - skip_umi_extract: + type: boolean + description: | + With or without umi extrection + - umi_discard_read: + type: integer + description: | + Discard R1 / R2 if required + - skip_trimming: + type: boolean + description: | + Allows to skip trimgalore execution + - adapter_fasta: + type: file + description: | + Fasta file of adapter sequences + - save_trimmed_fail: + type: boolean + description: | + Save trimmed fastqs of failed samples + - save_merged: + type: boolean + description: | + Save merged fastqs + - min_trimmed_reads: + type: integer + description: | + Inputs with fewer than this reads will be filtered out of the "reads" output channel +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - 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}" + - fastqc_html: + type: file + description: FastQC report + pattern: "*_{fastqc.html}" + - fastqc_zip: + type: file + description: FastQC report archive + pattern: "*_{fastqc.zip}" + - log: + type: file + description: Logfile for umi_tools + pattern: "*.{log}" + - trim_json: + type: file + description: FastP Trimming report + pattern: "*.{fastp.json}" + - trim_html: + type: file + description: FastP Trimming report + pattern: "*.{fastp.html}" + - log: + type: file + description: Logfile FastP + pattern: "*.{fastp.log}" + - trim_reads_fail: + type: file + description: Trimmed fastq files failing QC + pattern: "*.{fastq.gz}" + - trim_reads_merged: + type: file + description: Trimmed and merged fastq files + pattern: "*.{fastq.gz}" + - trim_read_count: + type: integer + description: Number of reads after trimming + - fastqc_trim_html: + type: file + description: FastQC report + pattern: "*_{fastqc.html}" + - fastqc_trim_zip: + type: file + description: FastQC report archive + pattern: "*_{fastqc.zip}" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" +authors: + - "@robsyme" diff --git a/workflows/rnaseq.nf b/workflows/rnaseq.nf index 6525b9269..45555593a 100755 --- a/workflows/rnaseq.nf +++ b/workflows/rnaseq.nf @@ -109,7 +109,6 @@ include { INPUT_CHECK } from '../subworkflows/local/input_check' include { PREPARE_GENOME } from '../subworkflows/local/prepare_genome' include { ALIGN_STAR } from '../subworkflows/local/align_star' include { QUANTIFY_RSEM } from '../subworkflows/local/quantify_rsem' -include { FASTQ_FASTQC_UMITOOLS_FASTP } from '../subworkflows/local/fastq_fastqc_umitools_fastp' include { QUANTIFY_SALMON as QUANTIFY_STAR_SALMON } from '../subworkflows/local/quantify_salmon' include { QUANTIFY_SALMON as QUANTIFY_SALMON } from '../subworkflows/local/quantify_salmon' @@ -137,6 +136,7 @@ include { CUSTOM_DUMPSOFTWAREVERSIONS } from '../modules/nf-core/custom/dumpsoft // include { FASTQ_SUBSAMPLE_FQ_SALMON } from '../subworkflows/nf-core/fastq_subsample_fq_salmon/main' include { FASTQ_FASTQC_UMITOOLS_TRIMGALORE } from '../subworkflows/nf-core/fastq_fastqc_umitools_trimgalore/main' +include { FASTQ_FASTQC_UMITOOLS_FASTP } from '../subworkflows/nf-core/fastq_fastqc_umitools_fastp/main' include { FASTQ_ALIGN_HISAT2 } from '../subworkflows/nf-core/fastq_align_hisat2/main' include { BAM_SORT_STATS_SAMTOOLS } from '../subworkflows/nf-core/bam_sort_stats_samtools/main' include { BAM_MARKDUPLICATES_PICARD } from '../subworkflows/nf-core/bam_markduplicates_picard/main' From 3ae9fbbcac2537dda316832d2fdd0be20bf103d4 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 21 Mar 2023 17:00:49 +0000 Subject: [PATCH 068/124] Update usage and output docs --- docs/output.md | 9 +++++---- docs/usage.md | 6 ++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/output.md b/docs/output.md index e856f93e6..5aafa7b15 100644 --- a/docs/output.md +++ b/docs/output.md @@ -111,7 +111,7 @@ To facilitate processing of input data which has the UMI barcode already embedde
-[Trim Galore!](https://www.bioinformatics.babraham.ac.uk/projects/trim_galore/) is a wrapper tool around Cutadapt and FastQC to peform quality and adapter trimming on FastQ files. Trim Galore! will automatically detect and trim the appropriate adapter sequence. It is the default trimming tool used by this pipeline, however you can use fastp instead by specifying the `--trimmer fastp` parameter. +[Trim Galore!](https://www.bioinformatics.babraham.ac.uk/projects/trim_galore/) is a wrapper tool around Cutadapt and FastQC to peform quality and adapter trimming on FastQ files. Trim Galore! will automatically detect and trim the appropriate adapter sequence. It is the default trimming tool used by this pipeline, however you can use fastp instead by specifying the `--trimmer fastp` parameter. You can specificy additional options for Trim Galore! via the `--extra_trimgalore_args` parameters. > **NB:** TrimGalore! will only run using multiple cores if you are able to use more than > 5 and > 6 CPUs for single- and paired-end data, respectively. The total cores available to TrimGalore! will also be capped at 4 (7 and 8 CPUs in total for single- and paired-end data, respectively) because there is no longer a run-time benefit. See [release notes](https://github.com/FelixKrueger/TrimGalore/blob/master/Changelog.md#version-060-release-on-1-mar-2019) and [discussion whilst adding this logic to the nf-core/atacseq pipeline](https://github.com/nf-core/atacseq/pull/65). @@ -123,17 +123,18 @@ To facilitate processing of input data which has the UMI barcode already embedde Output files - `fastp/` + - `*.fastq.gz`: If `--save_trimmed` is specified, FastQ files **after** adapter trimming will be placed in this directory. - `*.fastp.html`: Trimming report in html format. - `*.fastp.json`: Trimming report in json format. - `fastp/log/` - `*.fastp.log`: Trimming log file. -- `fastqc/trim/` - - `*_fastqc.html`: FastQC report of the trimmed reads. +- `fastp/fastqc/` + - `*_fastqc.html`: FastQC report containing quality metrics for read 1 (_and read2 if paired-end_) **after** adapter trimming. - `*_fastqc.zip`: Zip archive containing the FastQC report, tab-delimited data file and plot images. -[fastp](https://github.com/OpenGene/fastp) is a tool designed to provide fast, all-in-one preprocessing for FastQ files. It has been developed in C++ with multithreading support to achieve higher performance. fastp can be used in this pipeline for standard adapter trimming and quality filtering by setting the `--trimmer fastp` parameter. +[fastp](https://github.com/OpenGene/fastp) is a tool designed to provide fast, all-in-one preprocessing for FastQ files. It has been developed in C++ with multithreading support to achieve higher performance. fastp can be used in this pipeline for standard adapter trimming and quality filtering by setting the `--trimmer fastp` parameter. You can specificy additional options for fastp via the `--extra_fastp_args` parameter. ![MultiQC - fastp filtered reads plot](images/mqc_fastp_plot.png) diff --git a/docs/usage.md b/docs/usage.md index 355e1535e..5a8569e96 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -51,6 +51,12 @@ An [example samplesheet](../assets/samplesheet.csv) has been provided with the p > **NB:** The `group` and `replicate` columns were replaced with a single `sample` column as of v3.1 of the pipeline. The `sample` column is essentially a concatenation of the `group` and `replicate` columns, however it now also offers more flexibility in instances where replicate information is not required e.g. when sequencing clinical samples. If all values of `sample` have the same number of underscores, fields defined by these underscore-separated names may be used in the PCA plots produced by the pipeline, to regain the ability to represent different groupings. +## Adapter trimming options + +[Trim Galore!](https://www.bioinformatics.babraham.ac.uk/projects/trim_galore/) is a wrapper tool around Cutadapt and FastQC to peform quality and adapter trimming on FastQ files. Trim Galore! will automatically detect and trim the appropriate adapter sequence. It is the default trimming tool used by this pipeline, however you can use fastp instead by specifying the `--trimmer fastp` parameter. [fastp](https://github.com/OpenGene/fastp) is a tool designed to provide fast, all-in-one preprocessing for FastQ files. It has been developed in C++ with multithreading support to achieve higher performance. You can specificy additional options for Trim Galore! and fastp via the `--extra_trimgalore_args` and `--extra_fastp_args` parameters, respectively. + +> **NB:** TrimGalore! will only run using multiple cores if you are able to use more than > 5 and > 6 CPUs for single- and paired-end data, respectively. The total cores available to TrimGalore! will also be capped at 4 (7 and 8 CPUs in total for single- and paired-end data, respectively) because there is no longer a run-time benefit. See [release notes](https://github.com/FelixKrueger/TrimGalore/blob/master/Changelog.md#version-060-release-on-1-mar-2019) and [discussion whilst adding this logic to the nf-core/atacseq pipeline](https://github.com/nf-core/atacseq/pull/65). + ## Alignment options By default, the pipeline uses [STAR](https://github.com/alexdobin/STAR) (i.e. `--aligner star_salmon`) to map the raw FastQ reads to the reference genome, project the alignments onto the transcriptome and to perform the downstream BAM-level quantification with [Salmon](https://salmon.readthedocs.io/en/latest/salmon.html). STAR is fast but requires a lot of memory to run, typically around 38GB for the Human GRCh37 reference genome. Since the [RSEM](https://github.com/deweylab/RSEM) (i.e. `--aligner star_rsem`) workflow in the pipeline also uses STAR you should use the [HISAT2](https://ccb.jhu.edu/software/hisat2/index.shtml) aligner (i.e. `--aligner hisat2`) if you have memory limitations. From 4968f464aabd49f54c1eb12a92bc5b1592939e44 Mon Sep 17 00:00:00 2001 From: maxulysse Date: Wed, 22 Mar 2023 13:50:10 +0100 Subject: [PATCH 069/124] update subway map --- docs/images/nf-core-rnaseq_metro_map_grey.png | Bin 276997 -> 288117 bytes docs/images/nf-core-rnaseq_metro_map_grey.svg | 223 ++++++++++-------- 2 files changed, 125 insertions(+), 98 deletions(-) diff --git a/docs/images/nf-core-rnaseq_metro_map_grey.png b/docs/images/nf-core-rnaseq_metro_map_grey.png index 4df8c4822bf370cc389403cec319a2d272a7ff96..0a3645f811812936e51eb054e1ea77d12ce168b7 100644 GIT binary patch literal 288117 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
  • msqB1DpcIzhUM^e?CkA5nr1dT`3OJ` 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%0D%Qc>?swzJ8k`3emZ*f$D4l@k3VgJK3 zE8#NI^y*au4sAwpaWqb!Bf`$-&b(`#Q$pKLGGVZCAG?51UZxinu_CLIqlV91cvQ{G z%8Cl!z~@^m}%O*G?b2dcyMrX24SMt|HPjk6H@~7fhc3=;6RJ)yMkAa0-#$o z(|7AMAc@0ECXm%+dun)ic#!G=`WgbGb#!#3<8y$pLa;PMufhOGCtc>}=OLr4L)e%? zn1XSL*p@A;af9#;^)TNW0DSB1J-x4yVD_Xngl1G1sR8i0sjY0`YH8W@S8Z+V7;KO# z46qp>$8aeBb7b~o9R}RXoen;f_(>|K<9UuADpoE29~Z#GBby-bUH|xk-!77%7EYJ&+pCn=r~s_2=tJqa{}%nCiL#C^)$ia zi6EqeB2>pECf3!|(BS^XNxobch3tVAH3>_53Cf0*jm<&pw{4I*+nO(FL!*BB^l9=$ z!M7&ZA{3Ev2`uIQl6?1#nhY``MOD_TRSO4{{-RR(T*U{XA2P*LyVFAs)gvlsv^>+F>fyXy4sBP(3clT{y-w=up^VOMn{+THBKEEjz z9&OoOulgY#-==E#d8ILp!WPf;KLhCCECnuTdVTPHe9_ai^ha+{&(%ab*%ylheNKMW0A-QA`C zlw2UMC|r8O1}zMQ99LdsZvY_8&dt3{ledk7kFT$3?ff6!0|Jb1)4q#}7Y9{7Mxy== zwTnGgE>AvCKGxqP<@l^bh%M@%(JkBk`#ubEW?Bf39obDnm}qd!?(ovm&7iolfQANG zy%u%<*|Qa1iR_xzEcyp!kGcZ$4+SLOmDdX5FR@EV`j9Ua82 z?pIWcr)IH}nt@@{Cms1#Mbc(98Qg)qQ3bj}#x3!n?JFvH{ER#@3sg~2DcO?niPkB3;-tE^x&bLJ$>%l) zt7Z~F=@xP}@O_!gwy{+F`y0{W*Rw;TY+Kksl>` z>jD;z@Zh*JQoOvp_$qY`#9Yp|z{X4`rs2HAxoz7v$qgIkjyq1Jo=r=PX{9&7LN~s1 z?9CQ7HepC04MGh6{j&eQAL}mm#Qpa)`6-v2{l%L6h_j!^_r$Q_Ph=iN29T7Ja{Fq} zuC30Fbl-@o&-yLyn4Pn;)r9v-0Tp&+j=vtJUD{{8{2sR&U6%LHO;gJ|!2SRG0m2)k z1oi&=Xty^=OGk8Bp(e&Idh=KB;O6-&G+!RAsnke+u-_O#X$fxi@Bd<=dH=7rWB>65 zU+7p_Sy53v=o#mA48LTU$H>U3rl_4wM~o{=88!d+Mfl3Rv=q(MZShg_htf^_4GolX z#>U)6jYQb7I9Tyl4E~^>E>LllEExQyBjr{wzQJde8M1K)MI7*zl#*u79Yon4{`+nS z)&;Y^%yR;!72vAnegWP@gV)-vj6V`;~{gTxqZnkE0h1f zf&jB&ZabVg-8|Hfm~Xy+;vWG*C@x#aIaX0~^h83abXstoiuum%NFy6g!#q$^;dh2J z{*~b1Wxw=2_IzRF(q3mO!LQB4K|(wlHxY10VZPt;3vAn(wzd)u1O5L!K*`ZP%`SUz zPzb_oX{q$flsqvB{QTzTX48WQ+3@Rs9vf5s6|;j56cZ&Z5ku7+6$SSZt+mm)_NxB# z+^8}VtBMiZte^P#-gwpcamv)%x~XCVZ;|~Bz=o<6Dann0Cq6xb)x#f{0myCM?E7i@ z&Y`CV9rz7eM{l$m;DV5W`EURzo>#DbOVCgKki!QwSn9bVsi=bD68~;7%P%h8t#pz3 z|6YrndWdE!<`vzvym+9){+vw9NMV8b)CyMCjLgiA9-VoSZ@uM=XjJX{kg%DUnC$vs zK2Dq@3R)4W08reURnpBv{l~$@MMvS}o2xX9qAnz#(>)b4M%cBs!}^HSD4-P>3Qs&F zGqyN-t%UkW>NR2IB>^DmaYp^&A`s zHxd^#1EDYw1H}{M)3&azkgTk=Pz1zVtzH5}6Bb>Jh+y@HSv_W#I z%Un~!Z)q`p%Pv~yw+JF_ur$S}^7gJzXtQ}5q6C*;(5!xMKeWQLD}M6kI6gy~~i1(BtfJ1FDG9)-cE0-+-_s z-hYD0aXJEO+%zXS`gMD_Ty8f(J_EJdR<&wZy#+ z?*Q+U2Biw{k&nQ|K$4-T&*S4+s8GBbcOl5mp`8fDtt`L$WqiC25Enu_py`&sUCpF( zz?bH{yLbH1BcCa4*H2{p-E?WhvB{+l;myLLbKnh$MDHyT0FX!QU0iy4bml~WF|nbl z(gVVU2aVeC0xIm>yu1vwB%IUVl@QcP4+!9ig#7jE8Ih1M6~Bm57LLEoDSubRCnSV| zdM)=2NNja|{W7pv8W5=vQ7=Q_L@eVxy}ju!)#c3)Kb1PfiDczVbr&$^_(xCp23f0s zpdbwe{PP(mQ!&ZO%$i9>J}^r)o-_fi8|KW`{zZj_Nxy(lCfhmUffLt=UhHfk))6^s zfVcpD4gj|DS)5n;`SYh7pm8hTbxsf^#3i%#zJATcz`#&>lQf^Ck3@(-A4o$1M9@So zB4%HC%Wq%|a$@0^hpxW97$|3mTBeqkfEMU6pkG({0T|m9Mm^M3r{}oyWPNw{T{zGh zEuMMV+S-T-HP+scjO60(PC6Sz#DbZ*ore#vBd-i;Zqi4UmyfTuvy&SYa%gHQ|IeB6 z^M^bNvqGnrZ%==lzk@r$vhSuASwau ze`NhN@gW**Ox_}J(BWe2pFYE<1esp$*g^~m22@Qzp*eMdMR$R~&DXnrvuZ7h(8x(9Ne|_5zi8&9Tq{z*>q=N9H zRUg*m#~+(k*hDV6=!Q+3u%CzCNh6W4$}r+Iz{`g0;>4#{f)v@mdzj(g9~Aq%SozW4 z(S`H)44phC;Zmg&xE=&fO8y1P0D;CplL3s5a#UQps=&-$5~vP(BHQw(eZl2gagh1kF% z(|YXj7j(;V00PKA4IMcE;4WnO>LD0S$~X3-Fb(@)qPNxBZSC;wDBcI()|gL=uO5P- z$q~I;P_{@p=Ps4h_G)g^eIV@)W8W z0{gw6MgU6yn>T_7e@eKA$mblkqo0@^M}{F7TOZK%1|S?ZT&IC#V5#C7vJpIN39|)) zRKX288gzFuUqK^;0XQMroB%#FIroQQ%{hSaq~St#t$p>14OA0MJ8NMEV`^iwq5K2- z%FUpAk4kUb#s|E_y6iABS^>KwM=k+QCYIvn>-zu?Oo7=@gOMyqB%WSgwb));f+|g7 zk01$d>-=-Gvrq;OpWh{ce^g(`%`0^S=r$@3nt#6iD4l31OmpQI;t~?d)MvdP96;*O zG%<``}77p_tJ3dw#x* z_NW`2uzy|Lr<)oV7YsdH(+YHdHKIe_8erxWQv9I!g?a4-{+)zfq2?2!cn8rKvp)aB zU!0#`iz!nHDCJ@PWYr^m55jIuM+YYv@A0P@Nvr7=ehxZ#y7I`%t2_0$N`6o&C$0MK z<9(7+x#@^IE}OC33y?wCg@o8Nljcu=bx`OS3CI5V{npl4-LM?LnlA7#KxUDcVi0Rs zpC7}_)Bxs+Ng4s_TeQp?vbBL1F$Pb=o>#0c8Z_Bl5Yw>1jRI|`+m!2|}F1qyWt@S$`x z0G$5QKYpw=Tl zPoP=^jdoLcG%|q1uIrb<Wwl*R?eVTfo*Bd-GB1PNj{ryR zHxDByn7Hhl5LFplV>2cHnn-T0I-{F=bfSuyGZn}Yyw@@Zz)Ha7O~ ztKxn}U(6;3$_TnCp30Y5HpZua;KqKaVQ;5_$d-tvm zoSYp%1Ul8ExHdH;V_R*)No_lejpru=LIM<=jx5*@=F>Lp(!91YF#PPdMlS8cndm5R zmI1@JjDz+i(ZoPurndgx1VYCYq^u>GUuf+6no%_n@*5SbWW~kFNfbX+?M|Kc&p!zA zgkVEaI2)wxp<`H~dGO%PdL^_UuO8jW&v&5jg-%EiV7htZK3m(Dh8KDeJVC}Izb#H! z@SQswe|>)^J-Z-|Lt9e6S81nFKp_(=D=W~I>e^abq)doubdj7W`>KATqu3BWK8}g( zZ}6XNw624Fh*Hf?zDM=^A6^iJWl7u|uYZM);nY35>J;u5*nE+$?rv_i4Gj#aEWmN6 zL|U#Y08zsPzck2{^oT!%qb@SvUlJOKE?Vh6Lj>w zJK)y7<@em&AYK6#oa_p@vDCB=5>)@wfI|*Fj~A(vx~6H=JF(UnUf5&UYT;PWjD^BzhH#kIxIRU1ILcW!`0W7c&Hc%TmG9I{=&- zml!%bOAt!Ys~hpx^2iR_mhq~?E6<}p!mvB(G$e~tpq!O02|^SWNiOrBwnP0%E1sQ6XYUtvobT2MEJLF-#(iB0-4lCiy&uS0Reb)bDFBmyxr}*_YSRc zcvq*oOyfB%i;w2BzhyQBo|KwpdWf>hXaf7XS;``}MNqU^QwwCiA8e2U(+Ndif63myfI-zIHH9MiO=K!>AkI& zpVj?j?6&Gn(?<-vIPB;GmDX?kj>&Q1)i($l=WbK{nkojhBVNhWP$T^i8&QIkn*SC*!#++@YvXV zRNAuT60R)y;f+MUZL@B1a!{vR9c{tCy0ioW%=(4~2Ru2#QJdZ(BBW?>Na_IFd=I}^ zX(jWWs=u40S4MC8)4}t=Dup9PpGG-Yaycoco3`IS`GpgcUztk9ODa=wZ-|@#1ttxX zu;d*y@`NCZa$C-&O~mKixhyEo4EYOwGe)OagemQ-aG^mUXNbr}-(|kN{qMz8@R*nR zL15*GjR2gD3-j|1$h*c1Xj9Bv3$n9AP$|i2DWgC(Tyq>J?wZhQ_9yqcmX!m%a==}} z?2C)bf{&fu)IG)o;eHaM&2ovyphpMc`6?7VB~*lY8xQQh#oo?9jJHXyaVUFj`^d-4 zIVRFY?dZltX@#`{B(~(8OVs4oGUV`L5YV|6^W2cRg2UhLUsZ05$LmzifkPgF38@Ik zhSacgDNV4=j-1_TQJtNg`&w-=#2??Rlx#4jtys-KEzNxr25Tqp)hC+Z2v0pacRsf# z8P4{{Bdv<|mG*_JK6G&*Fu~o&k000i!@M~HDpN^r&8)(*EI=Xl2ag;+3{IWN_o*R` zkC0fb0s^Bz1%mB_OF_)E0elipKPW8_LmkY^?$0*=#PXC$l=UCvb}I_)C@B=tjEDIn z_G12B$QU>jJ7$z1qXl{Ch#PnITpJ1SCqT4}4i+ghQ z-xW-HWRz|)ld7G)tPeQm&P6{H(j~2sY|^hH$`c!Et@;s>Fjh9s;K9Sr!9n<_L^!9oQm@G%YAJ|W^i~w;QjIB;06+B`TPG9l< zx-DDo?fR1A=-@y~z5E54h~Jm~o{5i-f98hy_kp1#*qX@|qP?K$wm}k@H!3aY$;!(HNhO$8(7;l`!7BH!M^OH$E^#9RVyt;|tDC}|9FJ0hN83gGG#!X+vpyzpcz1Q1+hNwYjDSoyek1n=ld4{?E_43KP9UEWvvITk>7ssdHY59eJk7bTFq7~ zNq=;rmjR|tggL?NVwsz1J^1Da$t6v1fdFv2MKN%2!)!Pqxn2b&bI z?av#pva+%+f;M2^nQMl!D;cxY=YKYWZ$&m*&S2Q4w0K{>EfPPgRfj?_B_-uQ{-@LrBr2~)BaF@lyO!B@|3(!>QTWej zaDyNo?i7i`X~)1m)D_G#PDB~fY=co33EWBQz{Ea9_G}5YG8ujSuZ%7oV~z;0a>YuD zif*i#X6wA8KcAYJnE{ahW#7}`t_MrF8KFXW>Eu%Ru~}XeG~7-#t^nk?%hkAANlw(tJ57* z!^WuhjbjFW8#N#KV>Y~P)BU_?+z3~EqM`1@-2lwjLYXNIPdo~GAo%lPay}d6& za`<}HA@&8rsGh-z9FKcWTtSQ*hS0x!eS0su@+nfT`9c`OW(cf@07%HHnKq*H8a&p@2)b`AB?_RRC zgYzjr@Xz@9fFKA}0F+l(KoP^krvaQ=FB$0jtteuPb?bJ^^XD}Lfb2{pZbBOmK9aom z7wM%PgMur3N-P++7#DToG)Y9zi1^mYHuv?VblrscBAkPWMnuym>wvdTF2Fdz8JlY~ zz$+n~Qgk_FmZPEZw90P*kOf~gdUJxsk6!!@=ui&E>{c4z;`y^FwM^dbI>>y+8!C1E3OfY9FGey>llRe1vCB1;ei3uVj0EE4+^+v z+Dp^w3Vm&L&-*N`tQ^oX64KtaMXNYmV>Ex^c<@Hcbe@7My8Fx@1linY-|eYGOo(j#Do>&KWC4E z=i3gHGyTFdBgiV$R{$Xo-9FJ!Uq66~zMkkkK^8;WP*^~*>$fsz&qDI#z?IsmB{ z96@})0zj%R)Lh{y5{#gMsdvyze? ze&giRkU7UEBU^WfK!C`IwhcYP%V~*X zC!x0$s#N4qyRy$%wKjlQ*K!`1iB$|X&zJN+$gZx|wAycE6v13Z6Nsy`7G+t(ErEd4a|w~5vmIj-P~u-0DkMQC z2NWeKIoTc{rq@EmZXcf2s{vsuDk_$^bxFZ_*}iCqOS zjG_vZHo&ag2*`{Yf{l2J>=&B0CGrK!^RGev&HFbMBM=^`VmY%TG4g_TzZ4Nm|M@)p zTrNQ6u=yMA&YP4C)_5L>>c7!Gp8)O#b37xp@6cn$`W)|SZ?6F;Y(1@AiCucvn1-N) zCMyz1o=;vxH4hz0G^)j?iO=*ATi`Y>0QL)IY5BZ=CC)3!LNAZIy15Nu7S1W&Mo&va zLMkM%;OgmSjJKvJEr-DcMEE8}%Wu)xyWYl8%mi&yJ{shAoiug-b!GIYzV?_oXkE{R z50o9+MOY>=1YFoUrR z;2=85)LnI?nm2y`L0w|X-c5rZz{0w#h zQ>+$y>i*kTl&N$Fr*u>ORG^)sL3=$lKjThdAo!#N#l~^~Ylk43UX#~n zE#HnZgy4T8t;T21v;cr&9(p-C`chaJGirG8^Xfl3Rrm178swp&JbP1gejJ?OfUex1)~w`{D?OM{XSuPWaj6yfVbj#<_uWZcl*=gRRJ3oo@+(% z2N|~BSn2cU&k3djZ3pfhfDBr6WhcivcRI_NU?`2zUo65G=tG#zXoE3{Z}J<~q}(h& zIgYH7Un6inyWcU&D&KBj!gZM)uKMi#M>n0*2&UQX`X-@SEi`7<1SqIj#N4Gol3RoS z5u*GwffEr#2v!8~@oc?lo)4X$6JI4`O#w5vN&_fQYM>p4h7Nao!Li2mCaVPqXHb*( zFtA?1QheB*4W)EsNOX0OltO z%-AMB>HLja%5a+_BwBQo`0Rmy7oPsrLCX*Dm<4(RK*z!;(e#1u_CYiN3sO08gJ+HZ z{9CI|EysOt>+B4^aYGOV4Y75~TbT>X#Bd_usXaFcc*hRw=?UW)f04bf1bPJB_(g>Rz9howz=ZY~pMD3DR* zS8{6tenk(05G3i%W2ytGwm!JffTY?0;CF{tgvLP`1-1g>Z3cQ|!qU2JsfEnNlxM56 ztPc(#e$rNj)d0$An98~5!FC0&iDh;Is37{x5uuL|Rl|AD$T{7_Hs~mpKoCQb3w49l z&CTIF%f5g8dIj8c3#+Bsm|SExLO&lDz;h%k56idNUIzmLb>@cH5Knjj8e26Wlz|LG z2j4kI!MYJI!VyRoS4H(~i;wIpEZHEAe2bp(qy2+ ztz_t-YP()yIy#{Suni`SEYM+M(DLLSno>~wgP=mfTUrSn+CRpOHXr-#8~+9eNs>zk z4=v`fZ>5XMkP>}LWAN*X7a;P3Z{lW&15p1J<&Mt)SD{GwKbh(H`ORWt+L^lIAC-Je@>$K8@QYUb6=FTc{ezA?z>jc`Z6osW>loy zY#VK#*)BKV!gk=Yaj(LG_+q2FQ!_U)~5OY|`4F&%MtbJ#8+R^l(I&3SuS zJ5}b@xjdxE4MrOGIteBil)0)|3yKe`Dw%!~jqzCJ?=7Z_xyitYmv5AFtB72B`9 zXt_v5b<2Fiu-8@ydc>~4;z&$Zwn%kTQe;F(t5)QhvaCx|0=VkR?$+*_Q`V@K)M~n-I7YNus zr0;3B+=))74vfkY7_tFwkLX5i;sB*6F?ztMBc_Kpj$ntHR-OgR8 z7F>R1-@Z*pAzn-E(?CIH_7;O%)Pm12rhz7UaPZkp7@abp2dHrG$`|L`ZDPU`$;H88 zc^Vc3JmPtr9I;>Io`?ST^zr|OkzvX_SpNpS{u1HB!-MYvX5Y*_Hh6?`0ZV=`EMS^G z{;nzn-n7e6S&4ryvMPX#VY$2eVgc6|BeB>=6`R1EqM)u4NkP=fuiRC>NnQO(k3xh* z+m39R&rA8|&>W&h4#qHS`QC6#MPQmT)+H2_9uiyA{v88GiC!SE|NUi_9JjtbXY~0> zYJHvME?-*+#z>jN3lqEf*@dDVj-5kafaEsANmh0WVydouiVF4xvxke>{5OL#6eJgaiSc{VWTI97&sj9NZNBr zo4i+v+I9RuhX4CZs=Q31ufB3|jq>(T>U~!vdc$EvSeO^CB$H>;n9J;ff~?>cVFWEE zBV(*Mi?$xf(dv1iZ$Ayo+6!sn7~_6_wP`TGwp>Ae{(`PqAXV*t5q zC?bm|dC3A#5hW!|glx#ihMx>|=FBWh^hNTpjH7odli%;(Ultpkc2=0(9uaeFn~;0E zmHIqzbeQRoNx+{eMl$zx`Y$HB``mFi3ihsuif?I zi~9g;CF&96Ri=+{4^i}4p*vp{@K>E!nPyp?A-_&$b6EUQobf?)E5v_-s)px2!09*c zwy1;PvK@gO2r-u^Iln~l{CKwQl3{i&7DSU9*qLv+9QBhz&-?$LwXXOEBfV67IID_w zS+oie?N$R-G0oCvh3@_Tm~7nQ53%TP#po!#@N74>^0D$Mvft_1ipvixqYLmZ=zn}} zHNLWKyBSgB!Tax8+s&=s5(IMRQ*xsy?8c15U5#HjWteSF2G@jhK@m|aIx8)-1|0nS z((C#uV(ch)xGBafZKs70p(Vl>FdSbPcE@rp`Rw_T$1?o|sZ9*P)$_5iPH{j=8!3DFC=vHQPwSFg)oM>JT( z_y=Sn{TySW+={NcoS1x<@13Y~o#3yg5VKRe0 zFe$C!KmOwiMIhe2johS;8AtMDe#C@jgj_v->n18gLeF=VH9a0!c zkr_i#D00XO6Uat0z#7=MSsB~N(LPZ1dk@eAB0P8sQ4*hHwCL&SGf;Q^{+tzUEXYEF zqa_vA$GiG-N{n`frn&jmygHFgDg8W)TEuS%*cm9`-n^KiY&?OfCLgLRsS2nlFXQJh z3;S(VQPJF($glbyHZsdU$Pq`g;>iErvDihpk998`v3aIZy5sYo<(*p%7gv_t3+|2G zLbLa+yuS4*3||DmaYpH?4YHcOhey$yDl`b>R6+u=jmtu+02)Kgg9-Lu>DCp5(2=Jj z#>KR9rNQ5&MH-?!*TY?sR%HMe6E#Ue&k5)<2r~euI*OJIMuN=mB*QvE6wyzFfU{7-=k9kBCkvKEC&(hdHE(8H3Q5k^iHYLKgi*$M*Z z1zC28&u=n(e!;8f{J@5Q=hha;C14(hfvo!Fh8-QZg_mpp{VC~qgio&r0tipq_yb9H zI`JvydG(0)9IIA2kC~G1*wo}>%gqrh1lxWQ)u*@tn{GfQ83q*^Ed|1pt|MM$%#Njr zi_h@-UE}2#0znTZcHY=`q(`nbTgl9#{M{wgbn88aG5G7ZUi2UbAhD-;&glZEfwZ;-l$s}jXt7+i=fTt1Y?oxaM0SLW`?- z&;MiVJ>YWg_y6%vix$!l84Z;N8Y*N}iX>F7ilmK{>_|&eX{sbzXlPwYq7X$(DUp^E zDxs2$zS`DPS|gT28vC+*Qs+ny>BKHu{D5 zsjYAc5T9~ojPjEf(=|;gp1o4dyVh3;ga_aDgXS#~A+AC=_5K_y;eI3c!%l?MJ}rXN zA*#knOyarvIrn6j2yVU zuJ7OR>0PHJ3iQ?m+ksl;wwC>^Ueq;np5A?$Wj6i5W8bVxqMo^?od-BtvMQpsy&D%& zoDe--Rz~S29%u!?U_b_1?h5qLopg*-qtXVd^`aHkP={u5gF7z2l$)E|a4#e>QvCGYyLVB=N=xj3kv;qKrGkQhqHn*% zX0BYbM#UBnZscc_tm{j`S0xoj?mWk}XO3kboXWL3c3F6Mu;DgH?Kas=78l=AYDk~z zb~CjfEY7>3s#V4;oU!9igE1?-A-%R;NgLG_%oyVBII;ivy*Kx46xh6A)bZI3J&)&P zRZZjhz@p!}?-yB?QA(L8hb#<`& zoNrxHbuMTXec_BvHXlS~Qd<+RU%x&8jNh$bj|&E|F3e#mL5%^G_sYKOX!Wu`D@(ZI zsH+v1`g17cd$jsFt+dTrK5dk`nCC20$#8$8F@}dbn7VHp%R?uKh#bb!CbXEW%>+@! z#s=b=s(AQt5*?eMCr~*>npyVBjeKzSxvxz#urJXF2lS$t4?FL!E{k1jx?tYCbsqQX z>M9TZ8tOEAvmb%*Pak4A0bzb25JfKn4=PyJ&2{Ou6mdKIj4u*{DGFJO?F|w`_X2$e zEHsL4Nbo%apob|G4DW{V10sd**G+<680>MoQZXYdD;qa&_sHi-{opuqdg1ffZMGQT zIHQ+Rip>|X`zSQ5&vzHy?|@Qp@y}0d;pgH*^`isNVfN=HGxvNuabHB zn*ZgRMbgnPf90otw-aTZInDVY&e_ozZyUxs4$8!*R9=@tt2}r9Ku+kHsWGLdc>3}c zBfpE2b@A*_EM{B`Bz{0^%rKBZEJe9C#`h>>wu^^e&zWg`)ue9-(e@-KW#5v*={00sbigxe3I6rQfPf~n|^Mb4SMo?NzqcVwYr z&&$^Y%SUbQU8>oeG<@d!65~L2=QKm{?@QHFLrkA}P0ea?At9)?$TqfR-cj7G!ti7q z3JVK+@D(=~9EC%;VLcOS zM^pv#&JQ`vw+;P-8!T*)y2ou;E?dpRE)d z;*X9ojt1Vlg3E(**{zGwpI3tl z#e{nS)0?RKU?>$7RyLmsLxGO9by9YPDjTO3WbC(_?QzS63@qc8`T2fs9y+lLNTHz6 z2qv^7?cwp`MsmcULs-;&e&b}sDrJoQQ;%jnmUY~q!?svj*yZqY0=wBnGSvS&hE){i z9%AMuySW)|XlAUp;TU+vZOwyNE-oN)!h^`T;DmxMGoPN{FO?;?V)(_F z>0^{q0Q|5qxPQRVrrWc^uonNIKV5U@$<$B=beA*OEd#p0ho=r>urc*vD8-&&-Co zOl?8=-A4(t`^`|zj5BsfP)7if`1hk38!M9P{C2-txh$0xr_D)QGS%n^wa0n9;E4sN z%)3AGwrEwvA3wWtqg}mJ){=Rg3v;|J=Uei$w$w+fG!H2v7Uur$cdnZ@1wuhbDptMD zrS8IJQDeN;#d;m2-&ID&F(yHq`TdXhYieVZhI_!nLn%6~*D}VY8-*^tW?>6Co#4g& z=rIewJG5*a^)T`GQQEfdA6U+2k!G&l!H7zLzZe45ix)43zi*_ElqF2J>))S}1X(|)Z31zFgMKbg4YI~9 z=Wtm&da(b}{rCC1U`f#ZjKuSn{+z1F>})}dMGVFo<6@lDCw=(%k%K``Q;w4HFm?{L z6y;Mkk{1WDk53^)1>&Lyi3@#t#*d|R3o^>_6DKMp*~2#dx)%)?&?3hh`t(rQ0biR0 z{(hqICGFPRq<&`4*g1VXJNBu`84tm%IJdPHg|e5ee1IV}9cWp*6~MT0PM+55+7gxM z+3+^eQOVd5Bn$;I9o#rwIT_rNfki+_AU0YClq(u`CnWgs^Zmxz0%=|T{V`t}CJ{B< zDBzJWcJT88lXnN1!Dkw4mk-wN(sj?hLGljZ@Gm-sfM=v$78Rbi62G_#D^Y-Z^k^;y z*`EzaDZ|yUw66)~93G@kQGyv<_KPs(h6o>|A+h$h(I3YOp$hr$4|~Gg1%??{jyQRG zb@}o)Z%Iu#8a!G?INA4DmC{@}XT@EIrkpTbdi1_H%tm<5OXXu?4|Ia5(=X`Q&ByPR3)>d%+h)N+bUW4+{f6+#F z&5K9QMlX^LbPMDUz8jz|&t-TAwYSa*&f8nMSEaZx9c`Y|hR&ZB{Z7pjt}GfdS2uJo zaqc)mA#W^R>k{cr?=P7u`U)eYu==1Kh=-^$nL*xuY<*>4(6AGOR zU^7i^fk~+D{U&R;(YjVdY0{kok1XYDGJyG-D8+)|Sa~v)2AQ?@0(&PxGG+*c01#c17maW4QWb3#PP;Km?oHBn`?`gERjSp zFr9?*(ET>VK`YiLE~6id5Z%=wdxpQiQc3X~%XoNt$}C>o5oeEwRH6=t%VAtXC3}w| zV~O&|N#x!v3G4%?RKNRCG|_#FD0?qDD$3;b56r=|MRRaRY` zr0K%SuX%`>CAZFh92oFJD+ROFE}%o;qxjUYp(gWKOhr2<=X<9W;2_Y`@jvza=u~5Cp=m}|0k0dxP(;(?`sOr= znwMjdBOPtH_xu?^EDIMdH1gR_x0LH?IP_Fuho`J7MhO0Rz)aLR>gaZ_a&Sn!VDWL$ z4!ls9xMsHFj%^3i*L+|*gaDLN1@XbU4I3zjlVxfwGE2XDKw<4m8@%H%GI2ax@gK68kG8-8 z7T9GgF0Y4(lLUe(wUP4i#z6q5p|HE%)qA7=Y{uA;2TvagxaUpmKSCWzQJ8R5Q(@N) zQQ?9ekEY=ktb(o}-fra9!-f%2s%3b@wkVNy4FI}g0Y;TbTdy~_K~o4r1}_|jIRuL$ zZDbtDY_VT*^Ktc{urfh`&j8?ez^w>=F-6y57U_^6eY2$h2TvFszQm_Gwm%_pe}4>B zkl;eh*Rr|qB8HY~b)Wq{d)o9#^)1 zraP}#DloZ>v2a&qmHz-h`1Qjb6%J9B7oUK@QVfsr^XH#~TEz3^_Z>IBWwd?a1#O|+ zGBkSs{{3hXxrjE#nAvdyjW;iw7VrzvG|sK}rX&impz zs|GE5U@vqwBXl>EfLM^bF!K-*1vDB%we5g8-@$8tiePN4RI`s!^PbuY+payLYi+1;#aRzW zP@x(4`rf#ITHBo+g*6D>of<(ui-DgGoI7A}TwkUP9t&yNHipN1JD|0_=Vy(B zovz``E$ChIap&gdq)BKfd<$)B9k2Xf78>VdI*CdtU=UZ@EilR{ETup-+#HtOY`H)^ zY417H7*x(MLB5B$`57k1&9QgFR}sqt+3^(?D-H&HIR$dy^&Y|Wbh0UfY)0HH$T5Q^ zJO)7Cd3)+=YuT)P7%ISYt;bQYZxAj*sOU9_gzDaX`n{TR*jrqXZh!%CG6~|%?_(}#qQV0 zi)%ay&o|N`BJe96v7!-cJ|RL`l%H(sxRBF3uCpEG{>%T z&MNt7@FcUiF8AoTPm(?Vz;Er#^DH*6QY=4kLgyt1hadNC0q)X;lT`0Is_an@TVV|J zuuzI6uoW$m!l&#O7tGt?bGxe?r*Q@<)2P#@$D)}_Aw30p6+EYl@WvK~t!z^?Qi`P# zl~PNwAJ5|IqYMX8+qmjvS_aV&h|@B21S&Sr$>#n{W4GQdg}& z*LH28L@wFqoa5#k3Kq>8cT1<_g}P9ofZ;)>{tG;SEf3@OZAX>6Y!Sx83Ic!;8XP0J zxVY_GLd(`r8#Qwl?l}E7I5R@qq0TFJUt`b<2Pl6%-W=&=ash#=ppOh)lw$&#O#cnc zG$*SB8SpMvKERdBKv^_^ut-@mXP;83(eEaUUgqzg*d)E|s&k!b7ruX;^ZZ4Qk&TJM z0uGPeychOySa&jP^SL%r2DIiN=3)4S7m!>Ar(IYNeB)x*eX*!h&x)@?(f|@X;_u~y zS)=?a6j958&p4k0LymZWHThexDJ`=W@1a1F4VMM63dGNE!Y>v9&cnyxzF&sJHNZ6% zrh}(_eZe^50ZIv@s}T8&SqG($cHEp*0A0%=@HD)!-cYx2!-oNpdp8^faTw&NdIc-J z597S=dEh=B3#AJ5D$Lin*WZDNo6gP>5fYMOADe?P9}4qDJU+Q^rD7*EZ#nS!b$s9V z*-Ndn&0GGJ>WsY4EMc$c?9$-m4fEWUi(V%>-C|6yb6n~0i+G!JM3Azj%iuU&``QC< zDBxA--XeG)@*QhxZv9#hBuGk5&LHO|&TL|x>h6ZEi6xr{6o`KQIl0)3auS_L#|DEZ zUjWu}GU=izDkz&ppfV(c?80|wZ%lJ6W~I!EsTsICx3deBq96KqAOH%AnNc`vF{icQ ze4vu-$vbNJZm&B^CNojd(TC8HhV>A2kDVaaj=F)DpI;BCA3_`ut{x7x1(4k^wjkj9 zytXBotzvm$BU|pje_@|JHs|Bhn|=K&MYbg+CBZWpfu1ZCHH_XS;aRm)y54h0Jqw9W zZHcs=T@As?0A7)pWDWRnn@{|?Yt8F{&wl*g|vsDkq<1XAo!cAfJ@1V#fvG&0_YvE+Q7pZZcPiy3Iaa3vuYxEdE|0Qck& zeSd)dGHB7>EwU9q_YYt&vZz^nismli-@j?SU0B~JaS6X8B|u;?q=L~*%||lL57`Y`M@L0|qcY;2k~*3X>`B;$4#Q>ui2uP9=qpA#r9D%o-pa3s zn*flw-XnyppgCBMlfNNZm#gI2$r>k$(8Ij7FaYS_=)-IxHygz1p*yOgW)c!KYfQkx ziBBdPG%spUm7J9SEI3J>8=@UuIEqlY&}27ILuq(_9+)#`(6S>G=x{y+JPR?!3j?in zJUy>DKYsXdee+_7*ho-}$jWCB8xTkjRrKrEuL

    MTLq%`TgV8Xnjb@R!t3%2Gk01 zeZ02d-?yErRD<4UchO@hFUZ}d&zaLCnb7@a#o_|06G0 zHN~_Bil(mqetxFyhR*^Fe>a{iG|9Zd*6PIa&6_hGs2GIw4O+bVTa8Bo;W6RUL&Uy;^~>3*31Fi7xJ)?>kMmolZ_UsL$| zNq_%6)kt1?);Q&{OIrFR=WG^)*PP{m>Xt59SQDvs-}fReNmlB`<&<(c&shV?+<(qG z`dh3uTz$~pNf&^O`Dw&*N41xFaj5>rb;CRN#0Pnhy9`n+C_a9D_GbxIJBC84(1opE z7&Rc?b=&n&@TXh%3ho4P<`II$R9_@i6KG9YrCES2AN0lc|DnEnl%G{MCj+k5}HYf z%^O6S6d+}>?hc{!<>cZ5>)`mj?-q%nfOuH;#c!f;wh^hNxekJJ9Mb!W}Li8P?WG6434+_Kg z+Y9lOsi0Q?NJ_jZh9r;*0N@0Nt#T(sQ+%0D(5xb63{ikM(wR#=U2N5|ILt(#~vh#^w*o%*=#> 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 M)L8}>CtL0KADm@2D*ylh literal 276997 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�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�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 JYtj1s{|kLr<9Pr8 diff --git a/docs/images/nf-core-rnaseq_metro_map_grey.svg b/docs/images/nf-core-rnaseq_metro_map_grey.svg index 073b02098..2e2a07374 100644 --- a/docs/images/nf-core-rnaseq_metro_map_grey.svg +++ b/docs/images/nf-core-rnaseq_metro_map_grey.svg @@ -2,9 +2,9 @@ image/svg+xmlMultiQCFASTQ1catfastqsubsamplefastq(fq)METHODSTAGE2. Genome alignment & quantification3. Pseudo-alignment & quantification5. Final QC1. Pre-processing4. Post-processingUMI-toolsextractTrimGalore!FastQCSortMeRNAFastQCinferstrandedness(Salmon) + r="3.4699144" />UMI-toolsextractFastQCFastP From b648a63f79f60e0d764362892e60c4550cefad4d Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Wed, 22 Mar 2023 13:02:29 +0000 Subject: [PATCH 070/124] Add --extra_trimgalore_args and --extra_fastp_args parameters --- CHANGELOG.md | 12 ++++++++---- conf/modules.config | 11 ++++++----- docs/output.md | 4 ++-- docs/usage.md | 2 +- nextflow.config | 2 ++ nextflow_schema.json | 10 ++++++++++ 6 files changed, 29 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bca372944..af4f55336 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ Thank you to everyone else that has contributed by reporting bugs, enhancements ### Enhancements & fixes +- Added fastp support. Users can now select between `--trimmer trimgalore` (default) and `--trimmer fastp`. +Any additional options can now be specified via the `--extra_trimgalore_args` and `--extra_fastp_args` parameters, respectively. - [[#663](https://github.com/nf-core/rnaseq/pull/663)] - Alternative trimming step for polyA/T removal - [[#781](https://github.com/nf-core/rnaseq/pull/781)] - Add Warning for poly(A) libraries - [[#878](https://github.com/nf-core/rnaseq/pull/878)] - Allow tabs in fasta header when creating decoys for salmon index @@ -34,10 +36,12 @@ Thank you to everyone else that has contributed by reporting bugs, enhancements ### Parameters -| Old parameter | New parameter | -| ------------- | ------------- | -| `--tracedir` | | -| | `--trimmer` | +| Old parameter | New parameter | +| ------------- | ------------------------- | +| `--tracedir` | | +| | `--trimmer` | +| | `--extra_trimgalore_args` | +| | `--extra_fastp_args` | > **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. diff --git a/conf/modules.config b/conf/modules.config index d46015f93..5fce1a58c 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -230,13 +230,14 @@ if (!params.skip_trimming) { withName: '.*:FASTQ_FASTQC_UMITOOLS_TRIMGALORE:TRIMGALORE' { ext.args = { [ - "--fastqc_args '-t ${task.cpus}' ", + "--fastqc_args '-t ${task.cpus}'", params.trim_nextseq > 0 ? "--nextseq ${params.trim_nextseq}" : '', params.clip_r1 > 0 ? "--clip_r1 ${params.clip_r1}" : '', params.clip_r2 > 0 && !meta.single_end ? "--clip_r2 ${params.clip_r2}" : '', params.three_prime_clip_r1 > 0 ? "--three_prime_clip_r1 ${params.three_prime_clip_r1}" : '', - params.three_prime_clip_r2 > 0 && !meta.single_end ? "--three_prime_clip_r2 ${params.three_prime_clip_r2}" : '' - ].join(' ').trim() + params.three_prime_clip_r2 > 0 && !meta.single_end ? "--three_prime_clip_r2 ${params.three_prime_clip_r2}" : '', + params.extra_trimgalore_args ? params.extra_trimgalore_args.split("\\s(?=--)") : '' + ].flatten().unique(false).join(' ').trim() } publishDir = [ [ @@ -263,7 +264,7 @@ if (!params.skip_trimming) { if (params.trimmer == 'fastp') { process { withName: '.*:FASTQ_FASTQC_UMITOOLS_FASTP:FASTP' { - ext.args = '--trim_poly_x' + ext.args = params.extra_fastp_args ?: '' publishDir = [ [ path: { "${params.outdir}/${params.trimmer}" }, @@ -578,7 +579,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { '--quantTranscriptomeBan Singleend', '--outSAMstrandField intronMotif', params.save_unaligned ? '--outReadsUnmapped Fastx' : '', - "params.extra_star_align_args ?: ''".split("\\s(?=--)") + params.extra_star_align_args ? params.extra_star_align_args.split("\\s(?=--)") : '' ].flatten().unique(false).join(' ').trim() publishDir = [ [ diff --git a/docs/output.md b/docs/output.md index 5aafa7b15..aee68700f 100644 --- a/docs/output.md +++ b/docs/output.md @@ -111,7 +111,7 @@ To facilitate processing of input data which has the UMI barcode already embedde -[Trim Galore!](https://www.bioinformatics.babraham.ac.uk/projects/trim_galore/) is a wrapper tool around Cutadapt and FastQC to peform quality and adapter trimming on FastQ files. Trim Galore! will automatically detect and trim the appropriate adapter sequence. It is the default trimming tool used by this pipeline, however you can use fastp instead by specifying the `--trimmer fastp` parameter. You can specificy additional options for Trim Galore! via the `--extra_trimgalore_args` parameters. +[Trim Galore!](https://www.bioinformatics.babraham.ac.uk/projects/trim_galore/) is a wrapper tool around Cutadapt and FastQC to peform quality and adapter trimming on FastQ files. Trim Galore! will automatically detect and trim the appropriate adapter sequence. It is the default trimming tool used by this pipeline, however you can use fastp instead by specifying the `--trimmer fastp` parameter. You can specify additional options for Trim Galore! via the `--extra_trimgalore_args` parameters. > **NB:** TrimGalore! will only run using multiple cores if you are able to use more than > 5 and > 6 CPUs for single- and paired-end data, respectively. The total cores available to TrimGalore! will also be capped at 4 (7 and 8 CPUs in total for single- and paired-end data, respectively) because there is no longer a run-time benefit. See [release notes](https://github.com/FelixKrueger/TrimGalore/blob/master/Changelog.md#version-060-release-on-1-mar-2019) and [discussion whilst adding this logic to the nf-core/atacseq pipeline](https://github.com/nf-core/atacseq/pull/65). @@ -134,7 +134,7 @@ To facilitate processing of input data which has the UMI barcode already embedde -[fastp](https://github.com/OpenGene/fastp) is a tool designed to provide fast, all-in-one preprocessing for FastQ files. It has been developed in C++ with multithreading support to achieve higher performance. fastp can be used in this pipeline for standard adapter trimming and quality filtering by setting the `--trimmer fastp` parameter. You can specificy additional options for fastp via the `--extra_fastp_args` parameter. +[fastp](https://github.com/OpenGene/fastp) is a tool designed to provide fast, all-in-one preprocessing for FastQ files. It has been developed in C++ with multithreading support to achieve higher performance. fastp can be used in this pipeline for standard adapter trimming and quality filtering by setting the `--trimmer fastp` parameter. You can specify additional options for fastp via the `--extra_fastp_args` parameter. ![MultiQC - fastp filtered reads plot](images/mqc_fastp_plot.png) diff --git a/docs/usage.md b/docs/usage.md index 5a8569e96..a3f2c5f0c 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -53,7 +53,7 @@ An [example samplesheet](../assets/samplesheet.csv) has been provided with the p ## Adapter trimming options -[Trim Galore!](https://www.bioinformatics.babraham.ac.uk/projects/trim_galore/) is a wrapper tool around Cutadapt and FastQC to peform quality and adapter trimming on FastQ files. Trim Galore! will automatically detect and trim the appropriate adapter sequence. It is the default trimming tool used by this pipeline, however you can use fastp instead by specifying the `--trimmer fastp` parameter. [fastp](https://github.com/OpenGene/fastp) is a tool designed to provide fast, all-in-one preprocessing for FastQ files. It has been developed in C++ with multithreading support to achieve higher performance. You can specificy additional options for Trim Galore! and fastp via the `--extra_trimgalore_args` and `--extra_fastp_args` parameters, respectively. +[Trim Galore!](https://www.bioinformatics.babraham.ac.uk/projects/trim_galore/) is a wrapper tool around Cutadapt and FastQC to peform quality and adapter trimming on FastQ files. Trim Galore! will automatically detect and trim the appropriate adapter sequence. It is the default trimming tool used by this pipeline, however you can use fastp instead by specifying the `--trimmer fastp` parameter. [fastp](https://github.com/OpenGene/fastp) is a tool designed to provide fast, all-in-one preprocessing for FastQ files. It has been developed in C++ with multithreading support to achieve higher performance. You can specify additional options for Trim Galore! and fastp via the `--extra_trimgalore_args` and `--extra_fastp_args` parameters, respectively. > **NB:** TrimGalore! will only run using multiple cores if you are able to use more than > 5 and > 6 CPUs for single- and paired-end data, respectively. The total cores available to TrimGalore! will also be capped at 4 (7 and 8 CPUs in total for single- and paired-end data, respectively) because there is no longer a run-time benefit. See [release notes](https://github.com/FelixKrueger/TrimGalore/blob/master/Changelog.md#version-060-release-on-1-mar-2019) and [discussion whilst adding this logic to the nf-core/atacseq pipeline](https://github.com/nf-core/atacseq/pull/65). diff --git a/nextflow.config b/nextflow.config index 1e3d5b2f8..7e7cc8e31 100644 --- a/nextflow.config +++ b/nextflow.config @@ -39,6 +39,8 @@ params { // Trimming trimmer = 'trimgalore' min_trimmed_reads = 10000 + extra_trimgalore_args = null + extra_fastp_args = null clip_r1 = null clip_r2 = null three_prime_clip_r1 = null diff --git a/nextflow_schema.json b/nextflow_schema.json index c679fc61a..30aa3fc30 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -359,6 +359,16 @@ "help_text": "This enables the option Cutadapt `--nextseq-trim=3'CUTOFF` option via Trim Galore, which will set a quality cutoff (that is normally given with -q instead), but qualities of G bases are ignored. This trimming is in common for the NextSeq- and NovaSeq-platforms, where basecalls without any signal are called as high-quality G bases.", "fa_icon": "fas fa-cut" }, + "extra_trimgalore_args": { + "type": "string", + "description": "Extra arguments to pass to Trim Galore! command in addition to defaults defined by the pipeline.", + "fa_icon": "fas fa-plus" + }, + "extra_fastp_args": { + "type": "string", + "description": "Extra arguments to pass to fastp command in addition to defaults defined by the pipeline.", + "fa_icon": "fas fa-plus" + }, "min_trimmed_reads": { "type": "integer", "default": 10000, From cbfd7ee47da8914d93231388a522b5f62b974538 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Wed, 22 Mar 2023 16:12:02 +0000 Subject: [PATCH 071/124] Remove --clip* --three_prime_clip_* and --trim_nextseq parameters --- CHANGELOG.md | 22 ++++++++++++++-------- conf/modules.config | 5 ----- modules.json | 2 +- modules/nf-core/trimgalore/main.nf | 4 +++- nextflow.config | 5 ----- nextflow_schema.json | 26 -------------------------- 6 files changed, 18 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af4f55336..e768c5fde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,8 +20,10 @@ Thank you to everyone else that has contributed by reporting bugs, enhancements ### Enhancements & fixes -- Added fastp support. Users can now select between `--trimmer trimgalore` (default) and `--trimmer fastp`. -Any additional options can now be specified via the `--extra_trimgalore_args` and `--extra_fastp_args` parameters, respectively. +- Added fastp support. + - Users can now select between `--trimmer trimgalore` (default) and `--trimmer fastp`. + - Trim Galore! specific pipeline parameters have been deprecated: `--clip_r1`, `--clip_r2`, `--three_prime_clip_r1`, `--three_prime_clip_r2`, `--tracedir` and `--trim_nextseq` + - Any additional options can now be specified via the `--extra_trimgalore_args` and `--extra_fastp_args` parameters, respectively. - [[#663](https://github.com/nf-core/rnaseq/pull/663)] - Alternative trimming step for polyA/T removal - [[#781](https://github.com/nf-core/rnaseq/pull/781)] - Add Warning for poly(A) libraries - [[#878](https://github.com/nf-core/rnaseq/pull/878)] - Allow tabs in fasta header when creating decoys for salmon index @@ -36,12 +38,16 @@ Any additional options can now be specified via the `--extra_trimgalore_args` an ### Parameters -| Old parameter | New parameter | -| ------------- | ------------------------- | -| `--tracedir` | | -| | `--trimmer` | -| | `--extra_trimgalore_args` | -| | `--extra_fastp_args` | +| Old parameter | New parameter | +| ----------------------- | ------------------------- | +| | `--trimmer` | +| | `--extra_trimgalore_args` | +| `--clip_r1` | | +| `--clip_r2` | | +| `--three_prime_clip_r1` | | +| `--three_prime_clip_r2` | | +| `--tracedir` | | +| `--trim_nextseq` | | > **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. diff --git a/conf/modules.config b/conf/modules.config index 5fce1a58c..d8dd1183f 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -231,11 +231,6 @@ if (!params.skip_trimming) { ext.args = { [ "--fastqc_args '-t ${task.cpus}'", - params.trim_nextseq > 0 ? "--nextseq ${params.trim_nextseq}" : '', - params.clip_r1 > 0 ? "--clip_r1 ${params.clip_r1}" : '', - params.clip_r2 > 0 && !meta.single_end ? "--clip_r2 ${params.clip_r2}" : '', - params.three_prime_clip_r1 > 0 ? "--three_prime_clip_r1 ${params.three_prime_clip_r1}" : '', - params.three_prime_clip_r2 > 0 && !meta.single_end ? "--three_prime_clip_r2 ${params.three_prime_clip_r2}" : '', params.extra_trimgalore_args ? params.extra_trimgalore_args.split("\\s(?=--)") : '' ].flatten().unique(false).join(' ').trim() } diff --git a/modules.json b/modules.json index d1eaf703c..e60765a07 100644 --- a/modules.json +++ b/modules.json @@ -196,7 +196,7 @@ }, "trimgalore": { "branch": "master", - "git_sha": "72ffbd7128015a1d4b65b95ff8d37be8fee2f981", + "git_sha": "64a3dbc0a30a94cdaed7869d8e34fbb85e886614", "installed_by": ["fastq_fastqc_umitools_trimgalore"] }, "ucsc/bedclip": { diff --git a/modules/nf-core/trimgalore/main.nf b/modules/nf-core/trimgalore/main.nf index 37e88f586..dc2957846 100644 --- a/modules/nf-core/trimgalore/main.nf +++ b/modules/nf-core/trimgalore/main.nf @@ -37,10 +37,12 @@ process TRIMGALORE { // Added soft-links to original fastqs for consistent naming in MultiQC def prefix = task.ext.prefix ?: "${meta.id}" if (meta.single_end) { + def args_list = args.split("\\s(?=--)").toList() + args_list.removeAll { it.toLowerCase().contains('_r2 ') } """ [ ! -f ${prefix}.fastq.gz ] && ln -s $reads ${prefix}.fastq.gz trim_galore \\ - $args \\ + ${args_list.join(' ')} \\ --cores $cores \\ --gzip \\ ${prefix}.fastq.gz diff --git a/nextflow.config b/nextflow.config index 7e7cc8e31..eadc068a2 100644 --- a/nextflow.config +++ b/nextflow.config @@ -41,11 +41,6 @@ params { min_trimmed_reads = 10000 extra_trimgalore_args = null extra_fastp_args = null - clip_r1 = null - clip_r2 = null - three_prime_clip_r1 = null - three_prime_clip_r2 = null - trim_nextseq = null save_trimmed = false skip_trimming = false diff --git a/nextflow_schema.json b/nextflow_schema.json index 30aa3fc30..9f6d7529d 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -333,32 +333,6 @@ "fa_icon": "fas fa-cut", "enum": ["trimgalore", "fastp"] }, - "clip_r1": { - "type": "integer", - "description": "Instructs Trim Galore to remove bp from the 5' end of read 1 (or single-end reads).", - "fa_icon": "fas fa-cut" - }, - "clip_r2": { - "type": "integer", - "description": "Instructs Trim Galore to remove bp from the 5' end of read 2 (paired-end reads only).", - "fa_icon": "fas fa-cut" - }, - "three_prime_clip_r1": { - "type": "integer", - "description": "Instructs Trim Galore to remove bp from the 3' end of read 1 AFTER adapter/quality trimming has been performed.", - "fa_icon": "fas fa-cut" - }, - "three_prime_clip_r2": { - "type": "integer", - "description": "Instructs Trim Galore to remove bp from the 3' end of read 2 AFTER adapter/quality trimming has been performed.", - "fa_icon": "fas fa-cut" - }, - "trim_nextseq": { - "type": "integer", - "description": "Instructs Trim Galore to apply the --nextseq=X option, to trim based on quality after removing poly-G tails.", - "help_text": "This enables the option Cutadapt `--nextseq-trim=3'CUTOFF` option via Trim Galore, which will set a quality cutoff (that is normally given with -q instead), but qualities of G bases are ignored. This trimming is in common for the NextSeq- and NovaSeq-platforms, where basecalls without any signal are called as high-quality G bases.", - "fa_icon": "fas fa-cut" - }, "extra_trimgalore_args": { "type": "string", "description": "Extra arguments to pass to Trim Galore! command in addition to defaults defined by the pipeline.", From 044b3711b8a96988d3acc3e2a6a8033934ccd467 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Wed, 22 Mar 2023 16:59:16 +0000 Subject: [PATCH 072/124] Fix ECLint --- conf/modules.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/modules.config b/conf/modules.config index d8dd1183f..c65f9eb20 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -574,7 +574,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { '--quantTranscriptomeBan Singleend', '--outSAMstrandField intronMotif', params.save_unaligned ? '--outReadsUnmapped Fastx' : '', - params.extra_star_align_args ? params.extra_star_align_args.split("\\s(?=--)") : '' + params.extra_star_align_args ? params.extra_star_align_args.split("\\s(?=--)") : '' ].flatten().unique(false).join(' ').trim() publishDir = [ [ From 7be70bb0a20da0419c33fa867b5f111c1ac98221 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Wed, 22 Mar 2023 16:57:10 +0000 Subject: [PATCH 073/124] Update CHANGELOG --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e768c5fde..5771af6c2 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.11.0](https://github.com/nf-core/rnaseq/releases/tag/3.11.0)] - 2023-03-22 +## [[3.11.0](https://github.com/nf-core/rnaseq/releases/tag/3.11.0)] - 2023-03-24 ### Credits @@ -62,6 +62,7 @@ Note, since the pipeline is now using Nextflow DSL2, each process will be run wi | `fastp` | | 0.23.2 | | `multiqc` | 1.13 | 1.14 | | `picard` | 2.27.4 | 3.0.0 | +| `salmon` | 1.9.0 | 1.10.1 | | `umi_tools` | 1.1.2 | 1.1.4 | > **NB:** Dependency has been **updated** if both old and new version information is present. From 21a7b6ad085c1560cdb992e4114391980827a56b Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Wed, 22 Mar 2023 17:30:46 +0000 Subject: [PATCH 074/124] Bump Salmon modules from 1.9.0 to 1.10.1 --- modules.json | 6 +++--- modules/nf-core/salmon/index/main.nf | 6 +++--- modules/nf-core/salmon/quant/main.nf | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/modules.json b/modules.json index e60765a07..018c1ecae 100644 --- a/modules.json +++ b/modules.json @@ -132,13 +132,13 @@ }, "salmon/index": { "branch": "master", - "git_sha": "cfef21995228c66af535b14c5efae1461ffb8981", + "git_sha": "5d2c0dd6a8e2790e7ff511f7f4d761f4ed627a91", "installed_by": ["fastq_subsample_fq_salmon"] }, "salmon/quant": { "branch": "master", - "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", - "installed_by": ["fastq_subsample_fq_salmon", "modules"] + "git_sha": "5d2c0dd6a8e2790e7ff511f7f4d761f4ed627a91", + "installed_by": ["modules", "fastq_subsample_fq_salmon"] }, "samtools/flagstat": { "branch": "master", diff --git a/modules/nf-core/salmon/index/main.nf b/modules/nf-core/salmon/index/main.nf index b850eccd5..668b62287 100644 --- a/modules/nf-core/salmon/index/main.nf +++ b/modules/nf-core/salmon/index/main.nf @@ -2,10 +2,10 @@ process SALMON_INDEX { tag "$transcript_fasta" label "process_medium" - conda "bioconda::salmon=1.9.0" + conda "bioconda::salmon=1.10.1" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/salmon:1.9.0--h7e5ed60_1' : - 'quay.io/biocontainers/salmon:1.9.0--h7e5ed60_1' }" + 'https://depot.galaxyproject.org/singularity/salmon:1.10.1--h7e5ed60_0' : + 'quay.io/biocontainers/salmon:1.10.1--h7e5ed60_0' }" input: path genome_fasta diff --git a/modules/nf-core/salmon/quant/main.nf b/modules/nf-core/salmon/quant/main.nf index d70fbf584..978faf6c5 100644 --- a/modules/nf-core/salmon/quant/main.nf +++ b/modules/nf-core/salmon/quant/main.nf @@ -2,10 +2,10 @@ process SALMON_QUANT { tag "$meta.id" label "process_medium" - conda "bioconda::salmon=1.9.0" + conda "bioconda::salmon=1.10.1" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/salmon:1.9.0--h7e5ed60_1' : - 'quay.io/biocontainers/salmon:1.9.0--h7e5ed60_1' }" + 'https://depot.galaxyproject.org/singularity/salmon:1.10.1--h7e5ed60_0' : + 'quay.io/biocontainers/salmon:1.10.1--h7e5ed60_0' }" input: tuple val(meta), path(reads) From 64cf8c8a379022b5d84eb85ccf69dc80cafc2004 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Wed, 22 Mar 2023 22:28:21 +0000 Subject: [PATCH 075/124] Add more prominent warnings about using custom config to provide parameters --- README.md | 2 ++ docs/usage.md | 4 ++++ lib/NfcoreTemplate.groovy | 15 +++++++++++++++ lib/WorkflowMain.groovy | 3 +++ 4 files changed, 24 insertions(+) diff --git a/README.md b/README.md index 8b42c6fec..d245cb99c 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,8 @@ You can find numerous talks on the [nf-core events page](https://nf-co.re/events 4. Start running your own analysis! + > - Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration except for parameters; see [docs](https://nf-co.re/usage/configuration#custom-configuration-files). + ```bash nextflow run nf-core/rnaseq --input samplesheet.csv --outdir --genome GRCh37 -profile ``` diff --git a/docs/usage.md b/docs/usage.md index a3f2c5f0c..a008251dd 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -4,6 +4,10 @@ > _Documentation of pipeline parameters is generated automatically from the pipeline schema and can no longer be found in markdown files._ +## Pipeline parameters + +Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration except for parameters; see [docs](https://nf-co.re/usage/configuration#custom-configuration-files). + ## Samplesheet input You will need to create a samplesheet with information about the samples you would like to analyse before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 4 columns, and a header row as shown in the examples below. diff --git a/lib/NfcoreTemplate.groovy b/lib/NfcoreTemplate.groovy index e06d6cc2c..0c14a60af 100755 --- a/lib/NfcoreTemplate.groovy +++ b/lib/NfcoreTemplate.groovy @@ -32,6 +32,21 @@ class NfcoreTemplate { } } + // + // Warn if using custom configs to provide pipeline parameters + // + public static void warnParamsProvidedInConfig(workflow, log) { + if (workflow.configFiles.size() > 1) { + log.warn "=============================================================================\n" + + " Multiple config files detected!\n" + + " Please provide pipeline parameters via the CLI or Nextflow '-params-file' option.\n" + + " Custom config files including those provided by the '-c' Nextflow option can be\n" + + " used to provide any configuration except for parameters.\n\n" + + " Docs: https://nf-co.re/usage/configuration#custom-configuration-files\n" + + "===================================================================================" + } + } + // // Generate version string // diff --git a/lib/WorkflowMain.groovy b/lib/WorkflowMain.groovy index d665b356c..5dd03dd17 100755 --- a/lib/WorkflowMain.groovy +++ b/lib/WorkflowMain.groovy @@ -62,6 +62,9 @@ class WorkflowMain { // Print parameter summary log to screen log.info paramsSummaryLog(workflow, params, log) + // Warn about using custom configs to provide pipeline parameters + NfcoreTemplate.warnParamsProvidedInConfig(workflow, log) + // Validate workflow parameters via the JSON schema if (params.validate_params) { NfcoreSchema.validateParameters(workflow, params, log) From 9bde1f752270f9c7f1eb0984613fadc9f564f978 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Thu, 23 Mar 2023 10:20:27 +0000 Subject: [PATCH 076/124] Change = to ~ everywhere - thanks for opening Pandora's box @jfy133 --- bin/prepare-for-rsem.py | 8 ++++---- lib/NfcoreTemplate.groovy | 4 ++-- lib/WorkflowRnaseq.groovy | 40 +++++++++++++++++++-------------------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/bin/prepare-for-rsem.py b/bin/prepare-for-rsem.py index 4a4009fa6..f874af792 100755 --- a/bin/prepare-for-rsem.py +++ b/bin/prepare-for-rsem.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 """ -============================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Credits -============================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This script is a clone of the "prepare-for-rsem.py" script written by Ian Sudbury, Tom Smith and other contributors to the UMI-tools package: @@ -19,9 +19,9 @@ Commit: https://github.com/CGATOxford/UMI-tools/blob/bf8608d6a172c5ca0dcf33c126b4e23429177a72/umi_tools/prepare-for-rsem.py -============================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ prepare_for_rsem - make the output from dedup or group compatible with RSEM -=============================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The SAM format specification states that the mnext and mpos fields should point to the primary alignment of a read's mate. However, not all aligners adhere to this standard. In addition, the RSEM software requires that the mate of a read1 diff --git a/lib/NfcoreTemplate.groovy b/lib/NfcoreTemplate.groovy index 0c14a60af..bce1492b9 100755 --- a/lib/NfcoreTemplate.groovy +++ b/lib/NfcoreTemplate.groovy @@ -37,13 +37,13 @@ class NfcoreTemplate { // public static void warnParamsProvidedInConfig(workflow, log) { if (workflow.configFiles.size() > 1) { - log.warn "=============================================================================\n" + + log.warn "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " Multiple config files detected!\n" + " Please provide pipeline parameters via the CLI or Nextflow '-params-file' option.\n" + " Custom config files including those provided by the '-c' Nextflow option can be\n" + " used to provide any configuration except for parameters.\n\n" + " Docs: https://nf-co.re/usage/configuration#custom-configuration-files\n" + - "===================================================================================" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" } } diff --git a/lib/WorkflowRnaseq.groovy b/lib/WorkflowRnaseq.groovy index 4b4c247d3..64264ae37 100755 --- a/lib/WorkflowRnaseq.groovy +++ b/lib/WorkflowRnaseq.groovy @@ -139,12 +139,12 @@ class WorkflowRnaseq { if (hits) { return true } else { - log.warn "=============================================================================\n" + + log.warn "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " Biotype attribute '${biotype}' not found in the last column of the GTF file!\n\n" + " Biotype QC will be skipped to circumvent the issue below:\n" + " https://github.com/nf-core/rnaseq/issues/460\n\n" + " Amend '--featurecounts_group_type' to change this behaviour.\n" + - "===================================================================================" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" return false } } @@ -159,13 +159,13 @@ class WorkflowRnaseq { def chrom = lspl[0] def size = lspl[1] if (size.toInteger() > max_size) { - log.error "=============================================================================\n" + + 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) } } @@ -326,70 +326,70 @@ class WorkflowRnaseq { // Print a warning if using GRCh38 assembly from igenomes.config // private static void ncbiGenomeWarn(log) { - log.warn "=============================================================================\n" + + log.warn "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " When using '--genome GRCh38' the assembly is from the NCBI and NOT Ensembl.\n" + " Biotype QC will be skipped to circumvent the issue below:\n" + " https://github.com/nf-core/rnaseq/issues/460\n\n" + " If you would like to use the soft-masked Ensembl assembly instead please see:\n" + " https://github.com/nf-core/rnaseq/issues/159#issuecomment-501184312\n" + - "===================================================================================" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" } // // Print a warning if using a UCSC assembly from igenomes.config // private static void ucscGenomeWarn(log) { - log.warn "=============================================================================\n" + + log.warn "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " When using UCSC assemblies the 'gene_biotype' field is absent from the GTF file.\n" + " Biotype QC will be skipped to circumvent the issue below:\n" + " https://github.com/nf-core/rnaseq/issues/460\n\n" + " If you would like to use the soft-masked Ensembl assembly instead please see:\n" + " https://github.com/nf-core/rnaseq/issues/159#issuecomment-501184312\n" + - "===================================================================================" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" } // // Print a warning if both GTF and GFF have been provided // private static void gtfGffWarn(log) { - log.warn "=============================================================================\n" + + log.warn "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " Both '--gtf' and '--gff' parameters have been provided.\n" + " Using GTF file as priority.\n" + - "===================================================================================" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" } // // Print a warning if using '--transcript_fasta' // private static void transcriptsFastaWarn(log) { - log.warn "=============================================================================\n" + + 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 // private static void skipAlignmentWarn(log) { - log.warn "=============================================================================\n" + + log.warn "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " '--skip_alignment' parameter has been provided.\n" + " Skipping alignment, genome-based quantification and all downstream QC processes.\n" + - "===================================================================================" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" } // // Print a warning if using '--aligner star_rsem' and '--with_umi' // private static void rsemUmiError(log) { - log.error "=============================================================================\n" + + log.error "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " When using '--aligner star_rsem', STAR is run by RSEM itself and so it is\n" + " not possible to remove UMIs before the quantification.\n\n" + " If you would like to remove UMI barcodes using the '--with_umi' option\n" + " please use either '--aligner star_salmon' or '--aligner hisat2'.\n" + - "=============================================================================" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" System.exit(1) } @@ -397,21 +397,21 @@ class WorkflowRnaseq { // Print a warning if using '--aligner star_rsem' and providing both '--rsem_index' and '--star_index' // private static void rsemStarIndexWarn(log) { - log.warn "=============================================================================\n" + + log.warn "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " When using '--aligner star_rsem', both the STAR and RSEM indices should\n" + " be present in the path specified by '--rsem_index'.\n\n" + " This warning has been generated because you have provided both\n" + " '--rsem_index' and '--star_index'. The pipeline will ignore the latter.\n\n" + " Please see:\n" + " https://github.com/nf-core/rnaseq/issues/568\n" + - "===================================================================================" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" } // // Print a warning if using '--additional_fasta' and '--_index' // private static void additionaFastaIndexWarn(index, log) { - log.warn "=============================================================================\n" + + log.warn "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " When using '--additional_fasta ' the aligner index will not\n" + " be re-built with the transgenes incorporated by default since you have \n" + " already provided an index via '--${index}_index '.\n\n" + @@ -421,6 +421,6 @@ class WorkflowRnaseq { " Ignore this warning if you know that the index already contains transgenes.\n\n" + " Please see:\n" + " https://github.com/nf-core/rnaseq/issues/556\n" + - "===================================================================================" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" } } From f579681af651969a0a61ac18fb9fca2e505a757a Mon Sep 17 00:00:00 2001 From: Gregor Sturm Date: Thu, 23 Mar 2023 13:57:06 +0100 Subject: [PATCH 077/124] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c3d87da8f..8e0920f57 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ ## Usage > **Note** -> If you are new to nextflow and nf-core, please refer to [this page](https://nf-co.re/#TODO) on how to set-up nextflow. Make sure to [test your setup](https://nf-co.re/#TODO) with `-profile test` before running the workflow on actual data. +> If you are new to nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data. First, you need to prepare a samplesheet with your input data that looks as follows: From 78cbd4cda2bf89304e7899b042e7fb15c25572ca Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Thu, 23 Mar 2023 13:22:07 +0000 Subject: [PATCH 078/124] Final updates to README --- README.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 4c971e168..db29bf24b 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,9 @@ CONTROL_REP1,AEG588A1_S1_L004_R1_001.fastq.gz,AEG588A1_S1_L004_R2_001.fastq.gz,a Each row represents a fastq file (single-end) or a pair of fastq files (paired end). Rows with the same sample identifier are considered technical replicates and merged automatically. The strandedness refers to the library preparation and will be automatically inferred if set to `auto`. +> **Note** +> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration except for parameters; see [docs](https://nf-co.re/usage/configuration#custom-configuration-files). + Now, you can run the pipeline using: ```bash @@ -75,11 +78,7 @@ nextflow run nf-core/rnaseq \ -profile ``` -> - Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration except for parameters; see [docs](https://nf-co.re/usage/configuration#custom-configuration-files). - -```bash -nextflow run nf-core/rnaseq --input samplesheet.csv --outdir --genome GRCh37 -profile -``` +For more details, please refer to the [usage documentation](https://nf-co.re/rnaseq/usage) and the [parameter documentation](https://nf-co.re/rnaseq/parameters). ## Pipeline output @@ -101,18 +100,19 @@ The pipeline was re-written in Nextflow DSL2 and is primarily maintained by Hars The pipeline workflow diagram was designed by Sarah Guinchard ([@G-Sarah](https://github.com/G-Sarah)) and James Fellows Yates ([@jfy133](https://github.com/jfy133)). Many thanks to other who have helped out along the way too, including (but not limited to): -[@MatthiasZepper](https://github.com/MatthiasZepper), -[@Emiller88](https://github.com/Emiller88), -[@maxulysse](https://github.com/maxulysse), -[@robsyme](https://github.com/robsyme), -[@Galithil](https://github.com/Galithil), -[@pditommaso](https://github.com/pditommaso), -[@orzechoj](https://github.com/orzechoj), -[@apeltzer](https://github.com/apeltzer), -[@colindaven](https://github.com/colindaven), -[@lpantano](https://github.com/lpantano), -[@olgabot](https://github.com/olgabot), -[@jburos](https://github.com/jburos). +- [Alex Peltzer](https://github.com/apeltzer) +- [Colin Davenport](https://github.com/colindaven) +- [Denis Moreno](https://github.com/Galithil) +- [Edumnd Miller](https://github.com/Emiller88) +- [Gregor Sturm](https://github.com/grst) +- [Jacki Buros Novik](https://github.com/jburos) +- [Lorena Pantano](https://github.com/lpantano) +- [Matthias Zepper](https://github.com/MatthiasZepper) +- [Maxime Garcia](https://github.com/maxulysse) +- [Olga Botvinnik](https://github.com/olgabot) +- [@orzechoj](https://github.com/orzechoj) +- [Paolo Di Tommaso](https://github.com/pditommaso) +- [Rob Syme](https://github.com/robsyme) ## Contributions and Support From d8ae5ce63721a4807271eb0aca26f943b1bd57ae Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Thu, 23 Mar 2023 13:23:06 +0000 Subject: [PATCH 079/124] Make note a warning instead --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index db29bf24b..5b96ae0df 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ CONTROL_REP1,AEG588A1_S1_L004_R1_001.fastq.gz,AEG588A1_S1_L004_R2_001.fastq.gz,a Each row represents a fastq file (single-end) or a pair of fastq files (paired end). Rows with the same sample identifier are considered technical replicates and merged automatically. The strandedness refers to the library preparation and will be automatically inferred if set to `auto`. -> **Note** +> **Warning** > Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration except for parameters; see [docs](https://nf-co.re/usage/configuration#custom-configuration-files). Now, you can run the pipeline using: From 24a65a485a9509d9e465c80c7a2c8305b4e1e5c9 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Thu, 23 Mar 2023 13:23:38 +0000 Subject: [PATCH 080/124] Fix prettier --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b96ae0df..d4b166048 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ ## Usage > **Note** -> If you are new to nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data. +> If you are new to nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data. First, you need to prepare a samplesheet with your input data that looks as follows: @@ -100,6 +100,7 @@ The pipeline was re-written in Nextflow DSL2 and is primarily maintained by Hars The pipeline workflow diagram was designed by Sarah Guinchard ([@G-Sarah](https://github.com/G-Sarah)) and James Fellows Yates ([@jfy133](https://github.com/jfy133)). Many thanks to other who have helped out along the way too, including (but not limited to): + - [Alex Peltzer](https://github.com/apeltzer) - [Colin Davenport](https://github.com/colindaven) - [Denis Moreno](https://github.com/Galithil) From 735d3e9530ea3e3a36c3733278e9525c1056dd0b Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Thu, 23 Mar 2023 13:30:42 +0000 Subject: [PATCH 081/124] Update README.md Co-authored-by: Gregor Sturm --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d4b166048..7d64b451b 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ CONTROL_REP1,AEG588A1_S1_L004_R1_001.fastq.gz,AEG588A1_S1_L004_R2_001.fastq.gz,a Each row represents a fastq file (single-end) or a pair of fastq files (paired end). Rows with the same sample identifier are considered technical replicates and merged automatically. The strandedness refers to the library preparation and will be automatically inferred if set to `auto`. > **Warning** -> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration except for parameters; see [docs](https://nf-co.re/usage/configuration#custom-configuration-files). +> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration **except for parameters**; see [docs](https://nf-co.re/usage/configuration#custom-configuration-files). Now, you can run the pipeline using: From c6cb43d43c87293508c3493c2efcaa00c37abfdc Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Fri, 24 Mar 2023 11:35:55 +0000 Subject: [PATCH 082/124] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5771af6c2..607134408 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ Thank you to everyone else that has contributed by reporting bugs, enhancements - Added fastp support. - Users can now select between `--trimmer trimgalore` (default) and `--trimmer fastp`. - - Trim Galore! specific pipeline parameters have been deprecated: `--clip_r1`, `--clip_r2`, `--three_prime_clip_r1`, `--three_prime_clip_r2`, `--tracedir` and `--trim_nextseq` + - Trim Galore! specific pipeline parameters have been deprecated: `--clip_r1`, `--clip_r2`, `--three_prime_clip_r1`, `--three_prime_clip_r2` and `--trim_nextseq` - Any additional options can now be specified via the `--extra_trimgalore_args` and `--extra_fastp_args` parameters, respectively. - [[#663](https://github.com/nf-core/rnaseq/pull/663)] - Alternative trimming step for polyA/T removal - [[#781](https://github.com/nf-core/rnaseq/pull/781)] - Add Warning for poly(A) libraries From 336183751a5fd85cc6b8d92b7369882e7b860f2a Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Sat, 25 Mar 2023 10:01:15 +0000 Subject: [PATCH 083/124] Add --umitools_umi_separator option to umitools extract --- CHANGELOG.md | 2 +- conf/modules.config | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 607134408..13687f2a4 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.11.0](https://github.com/nf-core/rnaseq/releases/tag/3.11.0)] - 2023-03-24 +## [[3.11.0](https://github.com/nf-core/rnaseq/releases/tag/3.11.0)] - 2023-03-27 ### Credits diff --git a/conf/modules.config b/conf/modules.config index c65f9eb20..0513ef0c2 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -289,7 +289,8 @@ if (params.with_umi && !params.skip_umi_extract) { ext.args = [ params.umitools_extract_method ? "--extract-method=${params.umitools_extract_method}" : '', params.umitools_bc_pattern ? "--bc-pattern='${params.umitools_bc_pattern}'" : '', - params.umitools_bc_pattern2 ? "--bc-pattern2='${params.umitools_bc_pattern2}'" : '' + params.umitools_bc_pattern2 ? "--bc-pattern2='${params.umitools_bc_pattern2}'" : '', + params.umitools_umi_separator ? "--umi-separator='${params.umitools_umi_separator}'" : '' ].join(' ').trim() publishDir = [ [ @@ -709,7 +710,7 @@ if (!params.skip_alignment && params.aligner == 'star_salmon') { ext.args = { [ meta.single_end ? '' : '--unpaired-reads=discard --chimeric-pairs=discard', params.umitools_grouping_method ? "--method='${params.umitools_grouping_method}'" : '', - params.umitools_umi_separator ? "--umi-separator='${params.umitools_umi_separator}'" : '', + params.umitools_umi_separator ? "--umi-separator='${params.umitools_umi_separator}'" : '' ].join(' ').trim() } ext.prefix = { "${meta.id}.umi_dedup.transcriptome.sorted" } publishDir = [ From 30981b29b4c59c5e2163f533b2fdcd59ed1c2026 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 27 Mar 2023 15:28:22 +0100 Subject: [PATCH 084/124] Fix #975 --- CHANGELOG.md | 17 +++++++++-------- workflows/rnaseq.nf | 8 +++++++- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13687f2a4..5dc7f96b8 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.11.0](https://github.com/nf-core/rnaseq/releases/tag/3.11.0)] - 2023-03-27 +## [[3.11.0](https://github.com/nf-core/rnaseq/releases/tag/3.11.0)] - 2023-03-29 ### Credits @@ -24,16 +24,17 @@ Thank you to everyone else that has contributed by reporting bugs, enhancements - Users can now select between `--trimmer trimgalore` (default) and `--trimmer fastp`. - Trim Galore! specific pipeline parameters have been deprecated: `--clip_r1`, `--clip_r2`, `--three_prime_clip_r1`, `--three_prime_clip_r2` and `--trim_nextseq` - Any additional options can now be specified via the `--extra_trimgalore_args` and `--extra_fastp_args` parameters, respectively. -- [[#663](https://github.com/nf-core/rnaseq/pull/663)] - Alternative trimming step for polyA/T removal -- [[#781](https://github.com/nf-core/rnaseq/pull/781)] - Add Warning for poly(A) libraries -- [[#878](https://github.com/nf-core/rnaseq/pull/878)] - Allow tabs in fasta header when creating decoys for salmon index -- [[#931](https://github.com/nf-core/rnaseq/pull/931)] - Save transcriptome BAM files when using `--save_umi_intermeds` / `--save_align_intermeds` +- [[#663](https://github.com/nf-core/rnaseq/issues/663)] - Alternative trimming step for polyA/T removal +- [[#781](https://github.com/nf-core/rnaseq/issues/781)] - Add Warning for poly(A) libraries +- [[#878](https://github.com/nf-core/rnaseq/issues/878)] - Allow tabs in fasta header when creating decoys for salmon index +- [[#931](https://github.com/nf-core/rnaseq/issues/931)] - Save transcriptome BAM files when using `--save_umi_intermeds` / `--save_align_intermeds` - [[#934](https://github.com/nf-core/rnaseq/pull/934)] - Union of `ext.args` and `params.extra_star_align_args` prevents parameter clashes in the STAR module -- [[#940](https://github.com/nf-core/rnaseq/issues/940)] - Bugfix in `salmon_summarizedexperiment.r` to ensure `rbind` doesn't fail when `rowdata` has no `tx` column. See ([[#941](https://github.com/nf-core/rnaseq/pull/941)]) for details. +- [[#940](https://github.com/nf-core/rnaseq/issues/940)] - Bugfix in `salmon_summarizedexperiment.r` to ensure `rbind` doesn't fail when `rowdata` has no `tx` column. - [[#944](https://github.com/nf-core/rnaseq/issues/944)] - Read clipping using clip_r1, clip_r2, three_prime_clip_r1, three_prime_clip_r2 disabled in 3.10 - [[#956](https://github.com/nf-core/rnaseq/pull/956)] - Implement 'auto' as default strandedness argument in `fastq_dir_to_samplesheet.py` script -- [[#960](https://github.com/nf-core/rnaseq/pull/960)] - Failure with awsbatch when running processes that are using `executor: local` -- [[#961](https://github.com/nf-core/rnaseq/pull/961)] - Add warnings to STDOUT for all skipped and failed strandedness check samples +- [[#960](https://github.com/nf-core/rnaseq/issues/960)] - Failure with awsbatch when running processes that are using `executor: local` +- [[#961](https://github.com/nf-core/rnaseq/issues/961)] - Add warnings to STDOUT for all skipped and failed strandedness check samples +- [[#975](https://github.com/nf-core/rnaseq/issues/975)] - `SALMON_INDEX` runs when using `--aligner star_rsem` even if samples have explicit strandedness - Remove HISAT2 from automated AWS full-sized tests ### Parameters diff --git a/workflows/rnaseq.nf b/workflows/rnaseq.nf index 45555593a..87630bead 100755 --- a/workflows/rnaseq.nf +++ b/workflows/rnaseq.nf @@ -243,9 +243,15 @@ workflow RNASEQ { // // SUBWORKFLOW: Sub-sample FastQ files and pseudo-align with Salmon to auto-infer strandedness // + // Return empty channel if ch_strand_fastq.auto_strand is empty so salmon index isn't created + PREPARE_GENOME.out.fasta + .combine(ch_strand_fastq.auto_strand) + .map { it.first() } + .set { ch_genome_fasta } + FASTQ_SUBSAMPLE_FQ_SALMON ( ch_strand_fastq.auto_strand, - PREPARE_GENOME.out.fasta, + ch_genome_fasta, PREPARE_GENOME.out.transcript_fasta, PREPARE_GENOME.out.gtf, PREPARE_GENOME.out.salmon_index, From 9f0c3e83bd46eb53625d4c525b113d0194be047a Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 27 Mar 2023 16:35:59 +0100 Subject: [PATCH 085/124] Replace System.exit(1) calls in pipeline template --- lib/NfcoreSchema.groovy | 3 ++- lib/WorkflowMain.groovy | 5 +++-- lib/WorkflowRnaseq.groovy | 46 +++++++++++++++------------------------ 3 files changed, 23 insertions(+), 31 deletions(-) diff --git a/lib/NfcoreSchema.groovy b/lib/NfcoreSchema.groovy index 33cd4f6e8..4d2968143 100755 --- a/lib/NfcoreSchema.groovy +++ b/lib/NfcoreSchema.groovy @@ -2,6 +2,7 @@ // This file holds several functions used to perform JSON parameter validation, help and summary rendering for the nf-core pipeline template. // +import nextflow.Nextflow import org.everit.json.schema.Schema import org.everit.json.schema.loader.SchemaLoader import org.everit.json.schema.ValidationException @@ -177,7 +178,7 @@ class NfcoreSchema { } if (has_error) { - System.exit(1) + Nextflow.error('Exiting!') } } diff --git a/lib/WorkflowMain.groovy b/lib/WorkflowMain.groovy index 5dd03dd17..eaf9bce23 100755 --- a/lib/WorkflowMain.groovy +++ b/lib/WorkflowMain.groovy @@ -2,6 +2,8 @@ // This file holds several functions specific to the main.nf workflow in the nf-core/rnaseq pipeline // +import nextflow.Nextflow + class WorkflowMain { // @@ -83,8 +85,7 @@ class WorkflowMain { // Check input has been provided if (!params.input) { - log.error "Please provide an input samplesheet to the pipeline e.g. '--input samplesheet.csv'" - System.exit(1) + Nextflow.error("Please provide an input samplesheet to the pipeline e.g. '--input samplesheet.csv'") } } // diff --git a/lib/WorkflowRnaseq.groovy b/lib/WorkflowRnaseq.groovy index 64264ae37..ff577917b 100755 --- a/lib/WorkflowRnaseq.groovy +++ b/lib/WorkflowRnaseq.groovy @@ -2,6 +2,7 @@ // This file holds several functions specific to the workflow/rnaseq.nf in the nf-core/rnaseq pipeline // +import nextflow.Nextflow import groovy.json.JsonSlurper import groovy.text.SimpleTemplateEngine @@ -15,13 +16,11 @@ class WorkflowRnaseq { if (!params.fasta) { - log.error "Genome fasta file not specified with e.g. '--fasta genome.fa' or via a detectable config file." - System.exit(1) + Nextflow.error("Genome fasta file not specified with e.g. '--fasta genome.fa' or via a detectable config file.") } if (!params.gtf && !params.gff) { - log.error "No GTF or GFF3 annotation specified! The pipeline requires at least one of these files." - System.exit(1) + Nextflow.error("No GTF or GFF3 annotation specified! The pipeline requires at least one of these files.") } if (params.gtf) { @@ -41,51 +40,43 @@ class WorkflowRnaseq { } 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) + Nextflow.error("Please provide either --bbsplit_fasta_list / --bbsplit_index to run BBSplit.") } if (params.remove_ribo_rna && !params.ribo_database_manifest) { - log.error "Please provide --ribo_database_manifest to remove ribosomal RNA with SortMeRNA." - System.exit(1) + Nextflow.error("Please provide --ribo_database_manifest to remove ribosomal RNA with SortMeRNA.") } if (params.with_umi && !params.skip_umi_extract) { if (!params.umitools_bc_pattern && !params.umitools_bc_pattern2) { - log.error "UMI-tools requires a barcode pattern to extract barcodes from the reads." - System.exit(1) + Nextflow.error("UMI-tools requires a barcode pattern to extract barcodes from the reads.") } } if (!params.skip_trimming) { if (!valid_params['trimmers'].contains(params.trimmer)) { - log.error "Invalid option: '${params.trimmer}'. Valid options for '--trimmer': ${valid_params['trimmers'].join(', ')}." - System.exit(1) + Nextflow.error("Invalid option: '${params.trimmer}'. Valid options for '--trimmer': ${valid_params['trimmers'].join(', ')}.") } } if (!params.skip_alignment) { if (!valid_params['aligners'].contains(params.aligner)) { - log.error "Invalid option: '${params.aligner}'. Valid options for '--aligner': ${valid_params['aligners'].join(', ')}." - System.exit(1) + Nextflow.error("Invalid option: '${params.aligner}'. Valid options for '--aligner': ${valid_params['aligners'].join(', ')}.") } } else { if (!params.pseudo_aligner) { - log.error "--skip_alignment specified without --pseudo_aligner...please specify e.g. --pseudo_aligner ${valid_params['pseudoaligners'][0]}." - System.exit(1) + Nextflow.error("--skip_alignment specified without --pseudo_aligner...please specify e.g. --pseudo_aligner ${valid_params['pseudoaligners'][0]}.") } skipAlignmentWarn(log) } if (params.pseudo_aligner) { if (!valid_params['pseudoaligners'].contains(params.pseudo_aligner)) { - log.error "Invalid option: '${params.pseudo_aligner}'. Valid options for '--pseudo_aligner': ${valid_params['pseudoaligners'].join(', ')}." - System.exit(1) + Nextflow.error("Invalid option: '${params.pseudo_aligner}'. Valid options for '--pseudo_aligner': ${valid_params['pseudoaligners'].join(', ')}.") } else { if (!(params.salmon_index || params.transcript_fasta || (params.fasta && (params.gtf || params.gff)))) { - log.error "To use `--pseudo_aligner 'salmon'`, you must provide either --salmon_index or --transcript_fasta or both --fasta and --gtf / --gff." - System.exit(1) + Nextflow.error("To use `--pseudo_aligner 'salmon'`, you must provide either --salmon_index or --transcript_fasta or both --fasta and --gtf / --gff.") } } } @@ -120,8 +111,7 @@ class WorkflowRnaseq { // Check which RSeQC modules we are running def rseqc_modules = params.rseqc_modules ? params.rseqc_modules.split(',').collect{ it.trim().toLowerCase() } : [] if ((valid_params['rseqc_modules'] + rseqc_modules).unique().size() != valid_params['rseqc_modules'].size()) { - log.error "Invalid option: ${params.rseqc_modules}. Valid options for '--rseqc_modules': ${valid_params['rseqc_modules'].join(', ')}" - System.exit(1) + Nextflow.error("Invalid option: ${params.rseqc_modules}. Valid options for '--rseqc_modules': ${valid_params['rseqc_modules'].join(', ')}") } } @@ -159,14 +149,14 @@ class WorkflowRnaseq { def chrom = lspl[0] def size = lspl[1] if (size.toInteger() > max_size) { - log.error "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + + def error_string = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\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) + Nextflow.error(error_string) } } } @@ -313,12 +303,12 @@ class WorkflowRnaseq { // private static void genomeExistsError(params, log) { if (params.genomes && params.genome && !params.genomes.containsKey(params.genome)) { - log.error "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + + def error_string = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\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) + Nextflow.error(error_string) } } @@ -384,13 +374,13 @@ class WorkflowRnaseq { // Print a warning if using '--aligner star_rsem' and '--with_umi' // private static void rsemUmiError(log) { - log.error "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + + def error_string = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " When using '--aligner star_rsem', STAR is run by RSEM itself and so it is\n" + " not possible to remove UMIs before the quantification.\n\n" + " If you would like to remove UMI barcodes using the '--with_umi' option\n" + " please use either '--aligner star_salmon' or '--aligner hisat2'.\n" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" - System.exit(1) + Nextflow.error(error_string) } // From 7fd78ca78713796169af25ded7af8f1167ad4a3b Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 27 Mar 2023 16:48:53 +0100 Subject: [PATCH 086/124] Fix nf-core lint --- .nf-core.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.nf-core.yml b/.nf-core.yml index 40bcac74d..e6c9d79f0 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -3,4 +3,5 @@ lint: files_unchanged: - assets/email_template.html - assets/email_template.txt + - lib/NfcoreSchema.groovy - lib/NfcoreTemplate.groovy From 088979fbcdecc635e7924f2979b1dbb76f415e10 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 28 Mar 2023 15:03:13 +0100 Subject: [PATCH 087/124] Add explicit test_full profiles for all cloud providers --- nextflow.config | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/nextflow.config b/nextflow.config index eadc068a2..163b13d6b 100644 --- a/nextflow.config +++ b/nextflow.config @@ -205,8 +205,17 @@ profiles { executor.cpus = 16 executor.memory = 60.GB } - test { includeConfig 'conf/test.config' } - test_full { includeConfig 'conf/test_full.config' } + test { includeConfig 'conf/test.config' } + test_full { includeConfig 'conf/test_full.config' } + test_full_aws { includeConfig 'conf/test_full.config' } + test_full_gcp { + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_gcp.csv' + igenomes_base = 'gs://igenomes' + } + test_full_azure { + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_azure.csv' + igenomes_base = 'az://igenomes' + } } // Load igenomes.config if required From 0fb0648abd0ad3f0dc8f7808a21a6ae12f2dad4a Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Tue, 28 Mar 2023 16:05:16 +0100 Subject: [PATCH 088/124] First pass at a GitHub Actions workflow for Tower --- .github/workflows/submit-to-tower.yml | 43 +++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .github/workflows/submit-to-tower.yml diff --git a/.github/workflows/submit-to-tower.yml b/.github/workflows/submit-to-tower.yml new file mode 100644 index 000000000..695109dc2 --- /dev/null +++ b/.github/workflows/submit-to-tower.yml @@ -0,0 +1,43 @@ +name: learn-github-actions +run-name: ${{ github.actor }} is learning GitHub Actions +on: [workflow_dispatch] +jobs: + submit-test-full-to-tower: + strategy: + matrix: + compute-environment: + - name: AWS + outdir: ${{ secrets.TOWER_BUCKET_AWS }}/results/${{ github.sha }} + workdir: ${{ secrets.TOWER_BUCKET_AWS }}/work/${{ github.sha }} + compute_env: ${{ secrets.TOWER_CE_AWS_CPU }} + profile: test + - name: GCP + outdir: ${{ secrets.TOWER_BUCKET_GCP }}/results/${{ github.sha }} + workdir: ${{ secrets.TOWER_BUCKET_GCP }}/work/${{ github.sha }} + compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} + profile: test + - name: AZ + outdir: ${{ secrets.TOWER_BUCKET_AZ }}/results/${{ github.sha }} + workdir: ${{ secrets.TOWER_BUCKET_AZ }}/work/${{ github.sha }} + compute_env: ${{ secrets.TOWER_CE_AZURE_CPU }} + profile: test + runs-on: ubuntu-latest + steps: + - uses: seqeralabs/action-tower-launch@v1 + with: + workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} + access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} + compute_env: ${{ matrix.compute-environment.compute_env }} + workdir: ${{ matrix.compute-environment.workdir }} + run_name: ${{ matrix.compute-environment.name }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + wait: false + parameters: | + { + "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", + "outdir": "${{ matrix.compute-environment.outdir }}" + } + profiles: ${{ matrix.compute-environment.profile }} + - uses: actions/upload-artifact@v3 + with: + name: Tower debug log file + path: tower_action_*.log From 50ad95d03f68a766508500345ae24baa4bb3fcb2 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 28 Mar 2023 16:55:01 +0100 Subject: [PATCH 089/124] Update nextflow.config --- nextflow.config | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nextflow.config b/nextflow.config index 163b13d6b..63280bda5 100644 --- a/nextflow.config +++ b/nextflow.config @@ -209,10 +209,12 @@ profiles { test_full { includeConfig 'conf/test_full.config' } test_full_aws { includeConfig 'conf/test_full.config' } test_full_gcp { + includeConfig 'conf/test_full.config' input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_gcp.csv' igenomes_base = 'gs://igenomes' } - test_full_azure { + test_full_azure { + includeConfig 'conf/test_full.config' input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_azure.csv' igenomes_base = 'az://igenomes' } From 460ded5d5bc89230138c0c80b70ef3e78bba37a4 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 28 Mar 2023 16:57:25 +0100 Subject: [PATCH 090/124] Update nextflow.config --- nextflow.config | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nextflow.config b/nextflow.config index 63280bda5..5076234b1 100644 --- a/nextflow.config +++ b/nextflow.config @@ -210,13 +210,13 @@ profiles { test_full_aws { includeConfig 'conf/test_full.config' } test_full_gcp { includeConfig 'conf/test_full.config' - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_gcp.csv' - igenomes_base = 'gs://igenomes' + params.input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_gcp.csv' + params.igenomes_base = 'gs://igenomes' } test_full_azure { includeConfig 'conf/test_full.config' - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_azure.csv' - igenomes_base = 'az://igenomes' + params.input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_azure.csv' + params.igenomes_base = 'az://igenomes' } } From e9709e136ecf2db6448f4d5de651fd7300bc9ed6 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Wed, 29 Mar 2023 09:33:07 +0100 Subject: [PATCH 091/124] Update nextflow.config --- nextflow.config | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/nextflow.config b/nextflow.config index 5076234b1..c5ca21943 100644 --- a/nextflow.config +++ b/nextflow.config @@ -210,13 +210,11 @@ profiles { test_full_aws { includeConfig 'conf/test_full.config' } test_full_gcp { includeConfig 'conf/test_full.config' - params.input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_gcp.csv' - params.igenomes_base = 'gs://igenomes' + params.input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_gcp.csv' } test_full_azure { includeConfig 'conf/test_full.config' - params.input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_azure.csv' - params.igenomes_base = 'az://igenomes' + params.input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_azure.csv' } } From 04646378270b296fb5a06215c80d97064d9e9f03 Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 09:51:20 +0100 Subject: [PATCH 092/124] Minor fixes for JSON sent to Slack. The version already includes the "v" prefix, so no need to add it in the json. I also fixed the name, which was hardcoded to a different workflow. --- assets/slackreport.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/slackreport.json b/assets/slackreport.json index 043d02f27..fc84fa5e5 100644 --- a/assets/slackreport.json +++ b/assets/slackreport.json @@ -3,7 +3,7 @@ { "fallback": "Plain-text summary of the attachment.", "color": "<% if (success) { %>good<% } else { %>danger<%} %>", - "author_name": "sanger-tol/readmapping v${version} - ${runName}", + "author_name": "nf-core/rnaseq ${version} - ${runName}", "author_icon": "https://www.nextflow.io/docs/latest/_static/favicon.ico", "text": "<% if (success) { %>Pipeline completed successfully!<% } else { %>Pipeline completed with errors<% } %>", "fields": [ From ce0bb67faef8ea8097dec91695e185b325ac1567 Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Tue, 28 Mar 2023 16:31:15 +0100 Subject: [PATCH 093/124] Use add-wait branch of tower action --- .github/workflows/cloud_tests_small.yml | 84 +++++++++++++++++++++++++ .github/workflows/submit-to-tower.yml | 43 ------------- 2 files changed, 84 insertions(+), 43 deletions(-) create mode 100644 .github/workflows/cloud_tests_small.yml delete mode 100644 .github/workflows/submit-to-tower.yml diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml new file mode 100644 index 000000000..3e755d63d --- /dev/null +++ b/.github/workflows/cloud_tests_small.yml @@ -0,0 +1,84 @@ +name: Run small tests on cloud providers +run-name: Submitting workflow to all cloud providers +on: + pull_request: + workflow_dispatch: + inputs: + platform: + description: 'Platform to run test' + required: true + default: 'all' + type: choice + options: + - all + - aws + - azure + - gcp +jobs: + run-small-tests-on-aws: + if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} + runs-on: ubuntu-latest + steps: + - uses: seqeralabs/action-tower-launch@add-wait + with: + workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} + access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} + compute_env: ${{ secrets.TOWER_CE_AWS_CPU }} + workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/${{ github.sha }}" + run_name: AWS_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + profiles: ${{ matrix.compute-environment.profile }} + parameters: | + { + "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", + "outdir": "${{ secrets.TOWER_BUCKET_AWS }}/results/${{ github.sha }}" + } + wait: false + - uses: actions/upload-artifact@v3 + with: + name: Tower debug log file + path: tower_action_*.log + run-small-tests-on-gcp: + if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'gcp' }} + runs-on: ubuntu-latest + steps: + - uses: seqeralabs/action-tower-launch@add-wait + with: + workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} + access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} + compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} + workdir: "${{ secrets.TOWER_BUCKET_GCP }}/work/${{ github.sha }}" + run_name: GCP_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + profiles: ${{ matrix.compute-environment.profile }} + parameters: | + { + "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", + "outdir": "${{ secrets.TOWER_BUCKET_GCP }}/results/${{ github.sha }}" + } + wait: false + - uses: actions/upload-artifact@v3 + with: + name: Tower debug log file + path: tower_action_*.log + run-small-tests-on-azure: + if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'azure' }} + runs-on: ubuntu-latest + steps: + - uses: seqeralabs/action-tower-launch@add-wait + with: + workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} + access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} + compute_env: ${{ secrets.TOWER_CE_AZURE_CPU }} + workdir: "${{ secrets.TOWER_BUCKET_AZURE }}/work/${{ github.sha }}" + run_name: AZURE_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + profiles: ${{ matrix.compute-environment.profile }} + parameters: | + { + "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", + "outdir": "${{ secrets.TOWER_BUCKET_AZURE }}/results/${{ github.sha }}" + "igenomes_base": "${{ secrets.TOWER_IGENOMES_BASE_AZURE }}" + } + wait: false + - uses: actions/upload-artifact@v3 + with: + name: Tower debug log file + path: tower_action_*.log diff --git a/.github/workflows/submit-to-tower.yml b/.github/workflows/submit-to-tower.yml deleted file mode 100644 index 695109dc2..000000000 --- a/.github/workflows/submit-to-tower.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: learn-github-actions -run-name: ${{ github.actor }} is learning GitHub Actions -on: [workflow_dispatch] -jobs: - submit-test-full-to-tower: - strategy: - matrix: - compute-environment: - - name: AWS - outdir: ${{ secrets.TOWER_BUCKET_AWS }}/results/${{ github.sha }} - workdir: ${{ secrets.TOWER_BUCKET_AWS }}/work/${{ github.sha }} - compute_env: ${{ secrets.TOWER_CE_AWS_CPU }} - profile: test - - name: GCP - outdir: ${{ secrets.TOWER_BUCKET_GCP }}/results/${{ github.sha }} - workdir: ${{ secrets.TOWER_BUCKET_GCP }}/work/${{ github.sha }} - compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} - profile: test - - name: AZ - outdir: ${{ secrets.TOWER_BUCKET_AZ }}/results/${{ github.sha }} - workdir: ${{ secrets.TOWER_BUCKET_AZ }}/work/${{ github.sha }} - compute_env: ${{ secrets.TOWER_CE_AZURE_CPU }} - profile: test - runs-on: ubuntu-latest - steps: - - uses: seqeralabs/action-tower-launch@v1 - with: - workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} - access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} - compute_env: ${{ matrix.compute-environment.compute_env }} - workdir: ${{ matrix.compute-environment.workdir }} - run_name: ${{ matrix.compute-environment.name }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} - wait: false - parameters: | - { - "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", - "outdir": "${{ matrix.compute-environment.outdir }}" - } - profiles: ${{ matrix.compute-environment.profile }} - - uses: actions/upload-artifact@v3 - with: - name: Tower debug log file - path: tower_action_*.log From 881331813aa6be21a5997ebdbc3414c7fc64b99e Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 10:45:23 +0100 Subject: [PATCH 094/124] Remove if statements --- .github/workflows/cloud_tests_small.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index 3e755d63d..b6f7380c1 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -16,7 +16,7 @@ on: - gcp jobs: run-small-tests-on-aws: - if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} + # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} runs-on: ubuntu-latest steps: - uses: seqeralabs/action-tower-launch@add-wait @@ -38,7 +38,7 @@ jobs: name: Tower debug log file path: tower_action_*.log run-small-tests-on-gcp: - if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'gcp' }} + # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'gcp' }} runs-on: ubuntu-latest steps: - uses: seqeralabs/action-tower-launch@add-wait @@ -60,7 +60,7 @@ jobs: name: Tower debug log file path: tower_action_*.log run-small-tests-on-azure: - if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'azure' }} + # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'azure' }} runs-on: ubuntu-latest steps: - uses: seqeralabs/action-tower-launch@add-wait From 4c07497060e8d65b0c2851c32d168f69299c16e0 Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 11:19:52 +0100 Subject: [PATCH 095/124] Add full-sized cloud tests --- .github/workflows/cloud_tests_full.yml | 84 +++++++++++++++++++++++++ .github/workflows/cloud_tests_small.yml | 6 +- 2 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/cloud_tests_full.yml diff --git a/.github/workflows/cloud_tests_full.yml b/.github/workflows/cloud_tests_full.yml new file mode 100644 index 000000000..551de0c13 --- /dev/null +++ b/.github/workflows/cloud_tests_full.yml @@ -0,0 +1,84 @@ +name: Run full-sized tests on cloud providers +run-name: Submitting workflow to all cloud providers +on: + pull_request: + workflow_dispatch: + inputs: + platform: + description: 'Platform to run test' + required: true + default: 'all' + type: choice + options: + - all + - aws + - azure + - gcp +jobs: + run-full-tests-on-aws: + # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} + runs-on: ubuntu-latest + steps: + - uses: seqeralabs/action-tower-launch@add-wait + with: + workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} + access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} + compute_env: ${{ secrets.TOWER_CE_AWS_CPU }} + workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/${{ github.sha }}" + run_name: AWS_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + profiles: test_full + parameters: | + { + "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", + "outdir": "${{ secrets.TOWER_BUCKET_AWS }}/results/${{ github.sha }}" + } + wait: false + - uses: actions/upload-artifact@v3 + with: + name: Tower debug log file + path: tower_action_*.log + run-full-tests-on-gcp: + # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'gcp' }} + runs-on: ubuntu-latest + steps: + - uses: seqeralabs/action-tower-launch@add-wait + with: + workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} + access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} + compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} + workdir: "${{ secrets.TOWER_BUCKET_GCP }}/work/${{ github.sha }}" + run_name: GCP_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + profiles: test_full + parameters: | + { + "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", + "outdir": "${{ secrets.TOWER_BUCKET_GCP }}/results/${{ github.sha }}" + } + wait: false + - uses: actions/upload-artifact@v3 + with: + name: Tower debug log file + path: tower_action_*.log + run-full-tests-on-azure: + # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'azure' }} + runs-on: ubuntu-latest + steps: + - uses: seqeralabs/action-tower-launch@add-wait + with: + workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} + access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} + compute_env: ${{ secrets.TOWER_CE_AZURE_CPU }} + workdir: "${{ secrets.TOWER_BUCKET_AZURE }}/work/${{ github.sha }}" + run_name: AZURE_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + profiles: test_full + parameters: | + { + "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", + "outdir": "${{ secrets.TOWER_BUCKET_AZURE }}/results/${{ github.sha }}" + "igenomes_base": "${{ secrets.TOWER_IGENOMES_BASE_AZURE }}" + } + wait: false + - uses: actions/upload-artifact@v3 + with: + name: Tower debug log file + path: tower_action_*.log diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index b6f7380c1..8eaaa3f7a 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -26,7 +26,7 @@ jobs: compute_env: ${{ secrets.TOWER_CE_AWS_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/${{ github.sha }}" run_name: AWS_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} - profiles: ${{ matrix.compute-environment.profile }} + profiles: test parameters: | { "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", @@ -48,7 +48,7 @@ jobs: compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} workdir: "${{ secrets.TOWER_BUCKET_GCP }}/work/${{ github.sha }}" run_name: GCP_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} - profiles: ${{ matrix.compute-environment.profile }} + profiles: test parameters: | { "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", @@ -70,7 +70,7 @@ jobs: compute_env: ${{ secrets.TOWER_CE_AZURE_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AZURE }}/work/${{ github.sha }}" run_name: AZURE_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} - profiles: ${{ matrix.compute-environment.profile }} + profiles: test parameters: | { "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", From c513d2742f78b999676227545e1ae0aa2aaa6ea5 Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 11:21:15 +0100 Subject: [PATCH 096/124] Trailing commas are not allowed in YAML files. This commit removes the trailing comma from the cloud_tests_full.yml file. --- .github/workflows/cloud_tests_full.yml | 2 +- .github/workflows/cloud_tests_small.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cloud_tests_full.yml b/.github/workflows/cloud_tests_full.yml index 551de0c13..e63cf97f0 100644 --- a/.github/workflows/cloud_tests_full.yml +++ b/.github/workflows/cloud_tests_full.yml @@ -74,7 +74,7 @@ jobs: parameters: | { "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", - "outdir": "${{ secrets.TOWER_BUCKET_AZURE }}/results/${{ github.sha }}" + "outdir": "${{ secrets.TOWER_BUCKET_AZURE }}/results/${{ github.sha }}", "igenomes_base": "${{ secrets.TOWER_IGENOMES_BASE_AZURE }}" } wait: false diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index 8eaaa3f7a..00bad2dd6 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -74,7 +74,7 @@ jobs: parameters: | { "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", - "outdir": "${{ secrets.TOWER_BUCKET_AZURE }}/results/${{ github.sha }}" + "outdir": "${{ secrets.TOWER_BUCKET_AZURE }}/results/${{ github.sha }}", "igenomes_base": "${{ secrets.TOWER_IGENOMES_BASE_AZURE }}" } wait: false From bf8c05a3a5064624d5ec0e9c820b04354758e482 Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 11:23:51 +0100 Subject: [PATCH 097/124] Unset igenomes_base from small test workflow --- .github/workflows/cloud_tests_small.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index 00bad2dd6..fd152bc56 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -74,8 +74,7 @@ jobs: parameters: | { "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", - "outdir": "${{ secrets.TOWER_BUCKET_AZURE }}/results/${{ github.sha }}", - "igenomes_base": "${{ secrets.TOWER_IGENOMES_BASE_AZURE }}" + "outdir": "${{ secrets.TOWER_BUCKET_AZURE }}/results/${{ github.sha }}" } wait: false - uses: actions/upload-artifact@v3 From a759554da4d4e3053447eed9f3f56be71d6ec9a6 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Wed, 29 Mar 2023 12:06:18 +0100 Subject: [PATCH 098/124] Apply suggestions from code review --- .github/workflows/cloud_tests_full.yml | 6 +++--- .github/workflows/cloud_tests_small.yml | 9 +++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/.github/workflows/cloud_tests_full.yml b/.github/workflows/cloud_tests_full.yml index e63cf97f0..dc4c51a7d 100644 --- a/.github/workflows/cloud_tests_full.yml +++ b/.github/workflows/cloud_tests_full.yml @@ -30,7 +30,7 @@ jobs: parameters: | { "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", - "outdir": "${{ secrets.TOWER_BUCKET_AWS }}/results/${{ github.sha }}" + "outdir": "${{ secrets.TOWER_BUCKET_AWS }}/rnaseq/results-${{ github.sha }}/aligner_${{ matrix.aligner }}" } wait: false - uses: actions/upload-artifact@v3 @@ -52,7 +52,7 @@ jobs: parameters: | { "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", - "outdir": "${{ secrets.TOWER_BUCKET_GCP }}/results/${{ github.sha }}" + "outdir": "${{ secrets.TOWER_BUCKET_GCP }}/rnaseq/results-${{ github.sha }}/aligner_${{ matrix.aligner }}" } wait: false - uses: actions/upload-artifact@v3 @@ -74,7 +74,7 @@ jobs: parameters: | { "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", - "outdir": "${{ secrets.TOWER_BUCKET_AZURE }}/results/${{ github.sha }}", + "outdir": "${{ secrets.TOWER_BUCKET_AZURE }}/rnaseq/results-${{ github.sha }}/aligner_${{ matrix.aligner }}", "igenomes_base": "${{ secrets.TOWER_IGENOMES_BASE_AZURE }}" } wait: false diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index fd152bc56..5638cf2ce 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -29,8 +29,7 @@ jobs: profiles: test parameters: | { - "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", - "outdir": "${{ secrets.TOWER_BUCKET_AWS }}/results/${{ github.sha }}" + "outdir": "${{ secrets.TOWER_BUCKET_AWS }}/rnaseq/results-test-${{ github.sha }}" } wait: false - uses: actions/upload-artifact@v3 @@ -51,8 +50,7 @@ jobs: profiles: test parameters: | { - "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", - "outdir": "${{ secrets.TOWER_BUCKET_GCP }}/results/${{ github.sha }}" + "outdir": "${{ secrets.TOWER_BUCKET_GCP }}/rnaseq/results-test-${{ github.sha }}" } wait: false - uses: actions/upload-artifact@v3 @@ -73,8 +71,7 @@ jobs: profiles: test parameters: | { - "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", - "outdir": "${{ secrets.TOWER_BUCKET_AZURE }}/results/${{ github.sha }}" + "outdir": "${{ secrets.TOWER_BUCKET_AZURE }}/rnaseq/results-test-${{ github.sha }}" } wait: false - uses: actions/upload-artifact@v3 From d21abe655c0623432df4b5479b6d49b50561cd50 Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 11:58:25 +0100 Subject: [PATCH 099/124] Move to self-hosted runners --- .github/workflows/cloud_tests_full.yml | 9 ++++++--- .github/workflows/cloud_tests_small.yml | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cloud_tests_full.yml b/.github/workflows/cloud_tests_full.yml index dc4c51a7d..458052119 100644 --- a/.github/workflows/cloud_tests_full.yml +++ b/.github/workflows/cloud_tests_full.yml @@ -17,7 +17,8 @@ on: jobs: run-full-tests-on-aws: # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} - runs-on: ubuntu-latest + runs-on: + group: azure-runner-1 steps: - uses: seqeralabs/action-tower-launch@add-wait with: @@ -39,7 +40,8 @@ jobs: path: tower_action_*.log run-full-tests-on-gcp: # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'gcp' }} - runs-on: ubuntu-latest + runs-on: + group: azure-runner-1 steps: - uses: seqeralabs/action-tower-launch@add-wait with: @@ -61,7 +63,8 @@ jobs: path: tower_action_*.log run-full-tests-on-azure: # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'azure' }} - runs-on: ubuntu-latest + runs-on: + group: azure-runner-1 steps: - uses: seqeralabs/action-tower-launch@add-wait with: diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index 5638cf2ce..978d7055b 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -17,7 +17,8 @@ on: jobs: run-small-tests-on-aws: # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} - runs-on: ubuntu-latest + runs-on: + group: azure-runner-1 steps: - uses: seqeralabs/action-tower-launch@add-wait with: @@ -38,7 +39,8 @@ jobs: path: tower_action_*.log run-small-tests-on-gcp: # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'gcp' }} - runs-on: ubuntu-latest + runs-on: + group: azure-runner-1 steps: - uses: seqeralabs/action-tower-launch@add-wait with: @@ -59,7 +61,8 @@ jobs: path: tower_action_*.log run-small-tests-on-azure: # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'azure' }} - runs-on: ubuntu-latest + runs-on: + group: azure-runner-1 steps: - uses: seqeralabs/action-tower-launch@add-wait with: From 56bf2eda629166f170c2665c505c38380056dd71 Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 12:06:59 +0100 Subject: [PATCH 100/124] Add matrix --- .github/workflows/cloud_tests_full.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/cloud_tests_full.yml b/.github/workflows/cloud_tests_full.yml index 458052119..00bfe4264 100644 --- a/.github/workflows/cloud_tests_full.yml +++ b/.github/workflows/cloud_tests_full.yml @@ -19,6 +19,9 @@ jobs: # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} runs-on: group: azure-runner-1 + strategy: + matrix: + aligner: ["star_salmon", "star_rsem"] steps: - uses: seqeralabs/action-tower-launch@add-wait with: @@ -42,6 +45,9 @@ jobs: # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'gcp' }} runs-on: group: azure-runner-1 + strategy: + matrix: + aligner: ["star_salmon", "star_rsem"] steps: - uses: seqeralabs/action-tower-launch@add-wait with: @@ -65,6 +71,9 @@ jobs: # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'azure' }} runs-on: group: azure-runner-1 + strategy: + matrix: + aligner: ["star_salmon", "star_rsem"] steps: - uses: seqeralabs/action-tower-launch@add-wait with: From 053d16e6b14053c7ed37f5878fbda0141117b40f Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 12:12:12 +0100 Subject: [PATCH 101/124] Change to self-hosted runners --- .github/workflows/cloud_tests_full.yml | 9 +++------ .github/workflows/cloud_tests_small.yml | 9 +++------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/.github/workflows/cloud_tests_full.yml b/.github/workflows/cloud_tests_full.yml index 00bfe4264..fd6a07ced 100644 --- a/.github/workflows/cloud_tests_full.yml +++ b/.github/workflows/cloud_tests_full.yml @@ -17,8 +17,7 @@ on: jobs: run-full-tests-on-aws: # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} - runs-on: - group: azure-runner-1 + runs-on: self-hosted strategy: matrix: aligner: ["star_salmon", "star_rsem"] @@ -43,8 +42,7 @@ jobs: path: tower_action_*.log run-full-tests-on-gcp: # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'gcp' }} - runs-on: - group: azure-runner-1 + runs-on: self-hosted strategy: matrix: aligner: ["star_salmon", "star_rsem"] @@ -69,8 +67,7 @@ jobs: path: tower_action_*.log run-full-tests-on-azure: # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'azure' }} - runs-on: - group: azure-runner-1 + runs-on: self-hosted strategy: matrix: aligner: ["star_salmon", "star_rsem"] diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index 978d7055b..c6aa7a6b0 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -17,8 +17,7 @@ on: jobs: run-small-tests-on-aws: # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} - runs-on: - group: azure-runner-1 + runs-on: self-hosted steps: - uses: seqeralabs/action-tower-launch@add-wait with: @@ -39,8 +38,7 @@ jobs: path: tower_action_*.log run-small-tests-on-gcp: # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'gcp' }} - runs-on: - group: azure-runner-1 + runs-on: self-hosted steps: - uses: seqeralabs/action-tower-launch@add-wait with: @@ -61,8 +59,7 @@ jobs: path: tower_action_*.log run-small-tests-on-azure: # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'azure' }} - runs-on: - group: azure-runner-1 + runs-on: self-hosted steps: - uses: seqeralabs/action-tower-launch@add-wait with: From 7399f56c0e9668a3686d7429ec39dbcc7ba50386 Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 12:19:04 +0100 Subject: [PATCH 102/124] Include aligner in run names --- .github/workflows/cloud_tests_full.yml | 6 +++--- .github/workflows/cloud_tests_small.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cloud_tests_full.yml b/.github/workflows/cloud_tests_full.yml index fd6a07ced..fe22de074 100644 --- a/.github/workflows/cloud_tests_full.yml +++ b/.github/workflows/cloud_tests_full.yml @@ -28,7 +28,7 @@ jobs: access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AWS_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/${{ github.sha }}" - run_name: AWS_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + run_name: aws_rnaseq_full_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} profiles: test_full parameters: | { @@ -53,7 +53,7 @@ jobs: access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} workdir: "${{ secrets.TOWER_BUCKET_GCP }}/work/${{ github.sha }}" - run_name: GCP_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + run_name: gcp_rnaseq_full_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} profiles: test_full parameters: | { @@ -78,7 +78,7 @@ jobs: access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AZURE_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AZURE }}/work/${{ github.sha }}" - run_name: AZURE_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + run_name: azure_rnaseq_full_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} profiles: test_full parameters: | { diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index c6aa7a6b0..0e8e4a4c2 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -25,7 +25,7 @@ jobs: access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AWS_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/${{ github.sha }}" - run_name: AWS_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + run_name: aws_rnaseq_small_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} profiles: test parameters: | { @@ -46,7 +46,7 @@ jobs: access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} workdir: "${{ secrets.TOWER_BUCKET_GCP }}/work/${{ github.sha }}" - run_name: GCP_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + run_name: gcp_rnaseq_small_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} profiles: test parameters: | { @@ -67,7 +67,7 @@ jobs: access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AZURE_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AZURE }}/work/${{ github.sha }}" - run_name: AZURE_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + run_name: azure_rnaseq_small_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} profiles: test parameters: | { From 22db0142e1b397b166e841d90b4a4a1177b9898c Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 12:26:01 +0100 Subject: [PATCH 103/124] Update work directory to match old runners --- .github/workflows/cloud_tests_full.yml | 10 +++++----- .github/workflows/cloud_tests_small.yml | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/cloud_tests_full.yml b/.github/workflows/cloud_tests_full.yml index fe22de074..ad2020521 100644 --- a/.github/workflows/cloud_tests_full.yml +++ b/.github/workflows/cloud_tests_full.yml @@ -1,5 +1,5 @@ -name: Run full-sized tests on cloud providers -run-name: Submitting workflow to all cloud providers +name: full-sized tests on cloud providers +run-name: Submitting workflow to all cloud providers using full sized data on: pull_request: workflow_dispatch: @@ -27,7 +27,7 @@ jobs: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AWS_CPU }} - workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/${{ github.sha }}" + workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/rnaseq/work-${{ github.sha }}" run_name: aws_rnaseq_full_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} profiles: test_full parameters: | @@ -52,7 +52,7 @@ jobs: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} - workdir: "${{ secrets.TOWER_BUCKET_GCP }}/work/${{ github.sha }}" + workdir: "${{ secrets.TOWER_BUCKET_GCP }}/work/rnaseq/work-${{ github.sha }}" run_name: gcp_rnaseq_full_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} profiles: test_full parameters: | @@ -77,7 +77,7 @@ jobs: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AZURE_CPU }} - workdir: "${{ secrets.TOWER_BUCKET_AZURE }}/work/${{ github.sha }}" + workdir: "${{ secrets.TOWER_BUCKET_AZURE }}/work/rnaseq/work-${{ github.sha }}" run_name: azure_rnaseq_full_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} profiles: test_full parameters: | diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index 0e8e4a4c2..977534f4f 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -1,5 +1,5 @@ -name: Run small tests on cloud providers -run-name: Submitting workflow to all cloud providers +name: small-sized tests on cloud providers +run-name: Submitting workflow to all cloud providers using small sized data on: pull_request: workflow_dispatch: @@ -24,7 +24,7 @@ jobs: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AWS_CPU }} - workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/${{ github.sha }}" + workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/rnaseq/work-${{ github.sha }}" run_name: aws_rnaseq_small_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} profiles: test parameters: | @@ -45,7 +45,7 @@ jobs: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} - workdir: "${{ secrets.TOWER_BUCKET_GCP }}/work/${{ github.sha }}" + workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/rnaseq/work-${{ github.sha }}" run_name: gcp_rnaseq_small_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} profiles: test parameters: | @@ -66,7 +66,7 @@ jobs: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AZURE_CPU }} - workdir: "${{ secrets.TOWER_BUCKET_AZURE }}/work/${{ github.sha }}" + workdir: "${{ secrets.TOWER_BUCKET_AZURE }}/work/rnaseq/work-${{ github.sha }}" run_name: azure_rnaseq_small_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} profiles: test parameters: | From 3ee41abcff1060772377355d7898f9f33cd6eb84 Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 12:36:23 +0100 Subject: [PATCH 104/124] Use env for run name --- .github/workflows/cloud_tests_full.yml | 18 ++++++++++++------ .github/workflows/cloud_tests_small.yml | 12 +++++++++--- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/.github/workflows/cloud_tests_full.yml b/.github/workflows/cloud_tests_full.yml index ad2020521..e3493e517 100644 --- a/.github/workflows/cloud_tests_full.yml +++ b/.github/workflows/cloud_tests_full.yml @@ -23,13 +23,15 @@ jobs: aligner: ["star_salmon", "star_rsem"] steps: - uses: seqeralabs/action-tower-launch@add-wait + env: + LABEL: ${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AWS_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/rnaseq/work-${{ github.sha }}" - run_name: aws_rnaseq_full_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} - profiles: test_full + run_name: "aws_rnaseq_full_${LABEL/:/_}" + profiles: test_full_aws parameters: | { "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", @@ -48,13 +50,15 @@ jobs: aligner: ["star_salmon", "star_rsem"] steps: - uses: seqeralabs/action-tower-launch@add-wait + env: + LABEL: ${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} workdir: "${{ secrets.TOWER_BUCKET_GCP }}/work/rnaseq/work-${{ github.sha }}" - run_name: gcp_rnaseq_full_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} - profiles: test_full + run_name: "gcp_rnaseq_full_${LABEL/:/_}" + profiles: test_full_gcp parameters: | { "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", @@ -73,13 +77,15 @@ jobs: aligner: ["star_salmon", "star_rsem"] steps: - uses: seqeralabs/action-tower-launch@add-wait + env: + LABEL: ${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AZURE_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AZURE }}/work/rnaseq/work-${{ github.sha }}" - run_name: azure_rnaseq_full_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} - profiles: test_full + run_name: "azure_rnaseq_full_${LABEL/:/_}" + profiles: test_full_azure parameters: | { "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index 977534f4f..fa6d8dedf 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -20,12 +20,14 @@ jobs: runs-on: self-hosted steps: - uses: seqeralabs/action-tower-launch@add-wait + env: + LABEL: ${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AWS_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/rnaseq/work-${{ github.sha }}" - run_name: aws_rnaseq_small_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + run_name: "aws_rnaseq_small_${LABEL/:/_}" profiles: test parameters: | { @@ -41,12 +43,14 @@ jobs: runs-on: self-hosted steps: - uses: seqeralabs/action-tower-launch@add-wait + env: + LABEL: ${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/rnaseq/work-${{ github.sha }}" - run_name: gcp_rnaseq_small_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + run_name: "gcp_rnaseq_small_${LABEL/:/_}" profiles: test parameters: | { @@ -62,12 +66,14 @@ jobs: runs-on: self-hosted steps: - uses: seqeralabs/action-tower-launch@add-wait + env: + LABEL: ${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AZURE_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AZURE }}/work/rnaseq/work-${{ github.sha }}" - run_name: azure_rnaseq_small_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + run_name: "azure_rnaseq_small_${LABEL/:/_}" profiles: test parameters: | { From 29cf6abc7b8b09474b9ece45c56c00649e85416d Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 13:21:41 +0100 Subject: [PATCH 105/124] Remove github.event.pull_request.head.label --- .github/workflows/cloud_tests_full.yml | 1 - .github/workflows/cloud_tests_small.yml | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cloud_tests_full.yml b/.github/workflows/cloud_tests_full.yml index e3493e517..08c94ca47 100644 --- a/.github/workflows/cloud_tests_full.yml +++ b/.github/workflows/cloud_tests_full.yml @@ -1,7 +1,6 @@ name: full-sized tests on cloud providers run-name: Submitting workflow to all cloud providers using full sized data on: - pull_request: workflow_dispatch: inputs: platform: diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index fa6d8dedf..5a3b75291 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -21,7 +21,7 @@ jobs: steps: - uses: seqeralabs/action-tower-launch@add-wait env: - LABEL: ${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + LABEL: ${{ matrix.aligner }}_${{ github.head_ref || github.ref }} with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} @@ -44,7 +44,7 @@ jobs: steps: - uses: seqeralabs/action-tower-launch@add-wait env: - LABEL: ${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + LABEL: ${{ matrix.aligner }}_${{ github.head_ref || github.ref }} with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} @@ -67,7 +67,7 @@ jobs: steps: - uses: seqeralabs/action-tower-launch@add-wait env: - LABEL: ${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + LABEL: ${{ matrix.aligner }}_${{ github.head_ref || github.ref }} with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} From 79c354f6dfd7fe1e72c796ac3e6b976494e97c3c Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 13:26:29 +0100 Subject: [PATCH 106/124] Rely on action to remove colons from branch name --- .github/workflows/cloud_tests_small.yml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index 5a3b75291..f35394594 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -20,14 +20,12 @@ jobs: runs-on: self-hosted steps: - uses: seqeralabs/action-tower-launch@add-wait - env: - LABEL: ${{ matrix.aligner }}_${{ github.head_ref || github.ref }} with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AWS_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/rnaseq/work-${{ github.sha }}" - run_name: "aws_rnaseq_small_${LABEL/:/_}" + run_name: "aws_rnaseq_small_${{ matrix.aligner }}_${{ github.head_ref || github.ref }}" profiles: test parameters: | { @@ -43,14 +41,12 @@ jobs: runs-on: self-hosted steps: - uses: seqeralabs/action-tower-launch@add-wait - env: - LABEL: ${{ matrix.aligner }}_${{ github.head_ref || github.ref }} with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/rnaseq/work-${{ github.sha }}" - run_name: "gcp_rnaseq_small_${LABEL/:/_}" + run_name: "gcp_rnaseq_small_${{ matrix.aligner }}_${{ github.head_ref || github.ref }}" profiles: test parameters: | { @@ -66,14 +62,12 @@ jobs: runs-on: self-hosted steps: - uses: seqeralabs/action-tower-launch@add-wait - env: - LABEL: ${{ matrix.aligner }}_${{ github.head_ref || github.ref }} with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AZURE_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AZURE }}/work/rnaseq/work-${{ github.sha }}" - run_name: "azure_rnaseq_small_${LABEL/:/_}" + run_name: "azure_rnaseq_small_${{ matrix.aligner }}_${{ github.head_ref || github.ref }}" profiles: test parameters: | { From 8fab0d99595a32ae59a33f7d274cd6190da168fc Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 13:30:39 +0100 Subject: [PATCH 107/124] Remove double underscore --- .github/workflows/cloud_tests_small.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index f35394594..432c503aa 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -25,7 +25,7 @@ jobs: access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AWS_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/rnaseq/work-${{ github.sha }}" - run_name: "aws_rnaseq_small_${{ matrix.aligner }}_${{ github.head_ref || github.ref }}" + run_name: "aws_rnaseq_small_${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" profiles: test parameters: | { @@ -46,7 +46,7 @@ jobs: access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/rnaseq/work-${{ github.sha }}" - run_name: "gcp_rnaseq_small_${{ matrix.aligner }}_${{ github.head_ref || github.ref }}" + run_name: "gcp_rnaseq_small_${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" profiles: test parameters: | { @@ -67,7 +67,7 @@ jobs: access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AZURE_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AZURE }}/work/rnaseq/work-${{ github.sha }}" - run_name: "azure_rnaseq_small_${{ matrix.aligner }}_${{ github.head_ref || github.ref }}" + run_name: "azure_rnaseq_small_${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" profiles: test parameters: | { From 1a88aa829970a0f9a4a60f131efcc22f05b6374d Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 13:47:47 +0100 Subject: [PATCH 108/124] Bump actions versions --- .github/workflows/cloud_tests_full.yml | 24 +++++++++--------------- .github/workflows/cloud_tests_small.yml | 15 +++++++-------- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/.github/workflows/cloud_tests_full.yml b/.github/workflows/cloud_tests_full.yml index 08c94ca47..1f7663da8 100644 --- a/.github/workflows/cloud_tests_full.yml +++ b/.github/workflows/cloud_tests_full.yml @@ -15,21 +15,19 @@ on: - gcp jobs: run-full-tests-on-aws: - # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} + if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} runs-on: self-hosted strategy: matrix: aligner: ["star_salmon", "star_rsem"] steps: - - uses: seqeralabs/action-tower-launch@add-wait - env: - LABEL: ${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + - uses: seqeralabs/action-tower-launch@v1 with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AWS_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/rnaseq/work-${{ github.sha }}" - run_name: "aws_rnaseq_full_${LABEL/:/_}" + run_name: "aws_rnaseq_full_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" profiles: test_full_aws parameters: | { @@ -42,21 +40,19 @@ jobs: name: Tower debug log file path: tower_action_*.log run-full-tests-on-gcp: - # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'gcp' }} + if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'gcp' }} runs-on: self-hosted strategy: matrix: aligner: ["star_salmon", "star_rsem"] steps: - - uses: seqeralabs/action-tower-launch@add-wait - env: - LABEL: ${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + - uses: seqeralabs/action-tower-launch@v1 with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} workdir: "${{ secrets.TOWER_BUCKET_GCP }}/work/rnaseq/work-${{ github.sha }}" - run_name: "gcp_rnaseq_full_${LABEL/:/_}" + run_name: "gcp_rnaseq_full_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" profiles: test_full_gcp parameters: | { @@ -69,21 +65,19 @@ jobs: name: Tower debug log file path: tower_action_*.log run-full-tests-on-azure: - # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'azure' }} + if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'azure' }} runs-on: self-hosted strategy: matrix: aligner: ["star_salmon", "star_rsem"] steps: - - uses: seqeralabs/action-tower-launch@add-wait - env: - LABEL: ${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }} + - uses: seqeralabs/action-tower-launch@v1 with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AZURE_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AZURE }}/work/rnaseq/work-${{ github.sha }}" - run_name: "azure_rnaseq_full_${LABEL/:/_}" + run_name: "azure_rnaseq_full_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" profiles: test_full_azure parameters: | { diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index 432c503aa..109695474 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -1,7 +1,6 @@ name: small-sized tests on cloud providers run-name: Submitting workflow to all cloud providers using small sized data on: - pull_request: workflow_dispatch: inputs: platform: @@ -16,10 +15,10 @@ on: - gcp jobs: run-small-tests-on-aws: - # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} + if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} runs-on: self-hosted steps: - - uses: seqeralabs/action-tower-launch@add-wait + - uses: seqeralabs/action-tower-launch@v1 with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} @@ -37,15 +36,15 @@ jobs: name: Tower debug log file path: tower_action_*.log run-small-tests-on-gcp: - # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'gcp' }} + if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'gcp' }} runs-on: self-hosted steps: - - uses: seqeralabs/action-tower-launch@add-wait + - uses: seqeralabs/action-tower-launch@v1 with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} - workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/rnaseq/work-${{ github.sha }}" + workdir: "${{ secrets.TOWER_BUCKET_GCP }}/work/rnaseq/work-${{ github.sha }}" run_name: "gcp_rnaseq_small_${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" profiles: test parameters: | @@ -58,10 +57,10 @@ jobs: name: Tower debug log file path: tower_action_*.log run-small-tests-on-azure: - # if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'azure' }} + if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'azure' }} runs-on: self-hosted steps: - - uses: seqeralabs/action-tower-launch@add-wait + - uses: seqeralabs/action-tower-launch@v1 with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} From 795793354be731e30d1dafb8fc0e1b9815a3948b Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 13:52:45 +0100 Subject: [PATCH 109/124] Minimize run names to remove tag/branch/commit --- .github/workflows/cloud_tests_full.yml | 6 +++--- .github/workflows/cloud_tests_small.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cloud_tests_full.yml b/.github/workflows/cloud_tests_full.yml index 1f7663da8..88a03fa07 100644 --- a/.github/workflows/cloud_tests_full.yml +++ b/.github/workflows/cloud_tests_full.yml @@ -27,7 +27,7 @@ jobs: access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AWS_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/rnaseq/work-${{ github.sha }}" - run_name: "aws_rnaseq_full_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" + run_name: "aws_rnaseq_full_${{ matrix.aligner }}" profiles: test_full_aws parameters: | { @@ -52,7 +52,7 @@ jobs: access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} workdir: "${{ secrets.TOWER_BUCKET_GCP }}/work/rnaseq/work-${{ github.sha }}" - run_name: "gcp_rnaseq_full_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" + run_name: "gcp_rnaseq_full_${{ matrix.aligner }}" profiles: test_full_gcp parameters: | { @@ -77,7 +77,7 @@ jobs: access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AZURE_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AZURE }}/work/rnaseq/work-${{ github.sha }}" - run_name: "azure_rnaseq_full_${{ matrix.aligner }}_${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" + run_name: "azure_rnaseq_full_${{ matrix.aligner }}" profiles: test_full_azure parameters: | { diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index 109695474..b1bd5711d 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -24,7 +24,7 @@ jobs: access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AWS_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AWS }}/work/rnaseq/work-${{ github.sha }}" - run_name: "aws_rnaseq_small_${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" + run_name: "aws_rnaseq_small" profiles: test parameters: | { @@ -45,7 +45,7 @@ jobs: access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_GCP_CPU }} workdir: "${{ secrets.TOWER_BUCKET_GCP }}/work/rnaseq/work-${{ github.sha }}" - run_name: "gcp_rnaseq_small_${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" + run_name: "gcp_rnaseq_small" profiles: test parameters: | { @@ -66,7 +66,7 @@ jobs: access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_CE_AZURE_CPU }} workdir: "${{ secrets.TOWER_BUCKET_AZURE }}/work/rnaseq/work-${{ github.sha }}" - run_name: "azure_rnaseq_small_${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" + run_name: "azure_rnaseq_small" profiles: test parameters: | { From bb41bbc73bd9eb2613cf5f2e20137ffc876d564f Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 27 Mar 2023 15:28:22 +0100 Subject: [PATCH 110/124] Fix #975 --- CHANGELOG.md | 17 +++++++++-------- workflows/rnaseq.nf | 8 +++++++- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13687f2a4..5dc7f96b8 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.11.0](https://github.com/nf-core/rnaseq/releases/tag/3.11.0)] - 2023-03-27 +## [[3.11.0](https://github.com/nf-core/rnaseq/releases/tag/3.11.0)] - 2023-03-29 ### Credits @@ -24,16 +24,17 @@ Thank you to everyone else that has contributed by reporting bugs, enhancements - Users can now select between `--trimmer trimgalore` (default) and `--trimmer fastp`. - Trim Galore! specific pipeline parameters have been deprecated: `--clip_r1`, `--clip_r2`, `--three_prime_clip_r1`, `--three_prime_clip_r2` and `--trim_nextseq` - Any additional options can now be specified via the `--extra_trimgalore_args` and `--extra_fastp_args` parameters, respectively. -- [[#663](https://github.com/nf-core/rnaseq/pull/663)] - Alternative trimming step for polyA/T removal -- [[#781](https://github.com/nf-core/rnaseq/pull/781)] - Add Warning for poly(A) libraries -- [[#878](https://github.com/nf-core/rnaseq/pull/878)] - Allow tabs in fasta header when creating decoys for salmon index -- [[#931](https://github.com/nf-core/rnaseq/pull/931)] - Save transcriptome BAM files when using `--save_umi_intermeds` / `--save_align_intermeds` +- [[#663](https://github.com/nf-core/rnaseq/issues/663)] - Alternative trimming step for polyA/T removal +- [[#781](https://github.com/nf-core/rnaseq/issues/781)] - Add Warning for poly(A) libraries +- [[#878](https://github.com/nf-core/rnaseq/issues/878)] - Allow tabs in fasta header when creating decoys for salmon index +- [[#931](https://github.com/nf-core/rnaseq/issues/931)] - Save transcriptome BAM files when using `--save_umi_intermeds` / `--save_align_intermeds` - [[#934](https://github.com/nf-core/rnaseq/pull/934)] - Union of `ext.args` and `params.extra_star_align_args` prevents parameter clashes in the STAR module -- [[#940](https://github.com/nf-core/rnaseq/issues/940)] - Bugfix in `salmon_summarizedexperiment.r` to ensure `rbind` doesn't fail when `rowdata` has no `tx` column. See ([[#941](https://github.com/nf-core/rnaseq/pull/941)]) for details. +- [[#940](https://github.com/nf-core/rnaseq/issues/940)] - Bugfix in `salmon_summarizedexperiment.r` to ensure `rbind` doesn't fail when `rowdata` has no `tx` column. - [[#944](https://github.com/nf-core/rnaseq/issues/944)] - Read clipping using clip_r1, clip_r2, three_prime_clip_r1, three_prime_clip_r2 disabled in 3.10 - [[#956](https://github.com/nf-core/rnaseq/pull/956)] - Implement 'auto' as default strandedness argument in `fastq_dir_to_samplesheet.py` script -- [[#960](https://github.com/nf-core/rnaseq/pull/960)] - Failure with awsbatch when running processes that are using `executor: local` -- [[#961](https://github.com/nf-core/rnaseq/pull/961)] - Add warnings to STDOUT for all skipped and failed strandedness check samples +- [[#960](https://github.com/nf-core/rnaseq/issues/960)] - Failure with awsbatch when running processes that are using `executor: local` +- [[#961](https://github.com/nf-core/rnaseq/issues/961)] - Add warnings to STDOUT for all skipped and failed strandedness check samples +- [[#975](https://github.com/nf-core/rnaseq/issues/975)] - `SALMON_INDEX` runs when using `--aligner star_rsem` even if samples have explicit strandedness - Remove HISAT2 from automated AWS full-sized tests ### Parameters diff --git a/workflows/rnaseq.nf b/workflows/rnaseq.nf index 45555593a..87630bead 100755 --- a/workflows/rnaseq.nf +++ b/workflows/rnaseq.nf @@ -243,9 +243,15 @@ workflow RNASEQ { // // SUBWORKFLOW: Sub-sample FastQ files and pseudo-align with Salmon to auto-infer strandedness // + // Return empty channel if ch_strand_fastq.auto_strand is empty so salmon index isn't created + PREPARE_GENOME.out.fasta + .combine(ch_strand_fastq.auto_strand) + .map { it.first() } + .set { ch_genome_fasta } + FASTQ_SUBSAMPLE_FQ_SALMON ( ch_strand_fastq.auto_strand, - PREPARE_GENOME.out.fasta, + ch_genome_fasta, PREPARE_GENOME.out.transcript_fasta, PREPARE_GENOME.out.gtf, PREPARE_GENOME.out.salmon_index, From baa7aa3d44fff90ad8898ee68f30758481c15548 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 27 Mar 2023 16:35:59 +0100 Subject: [PATCH 111/124] Replace System.exit(1) calls in pipeline template --- lib/NfcoreSchema.groovy | 3 ++- lib/WorkflowMain.groovy | 5 +++-- lib/WorkflowRnaseq.groovy | 46 +++++++++++++++------------------------ 3 files changed, 23 insertions(+), 31 deletions(-) diff --git a/lib/NfcoreSchema.groovy b/lib/NfcoreSchema.groovy index 33cd4f6e8..4d2968143 100755 --- a/lib/NfcoreSchema.groovy +++ b/lib/NfcoreSchema.groovy @@ -2,6 +2,7 @@ // This file holds several functions used to perform JSON parameter validation, help and summary rendering for the nf-core pipeline template. // +import nextflow.Nextflow import org.everit.json.schema.Schema import org.everit.json.schema.loader.SchemaLoader import org.everit.json.schema.ValidationException @@ -177,7 +178,7 @@ class NfcoreSchema { } if (has_error) { - System.exit(1) + Nextflow.error('Exiting!') } } diff --git a/lib/WorkflowMain.groovy b/lib/WorkflowMain.groovy index 5dd03dd17..eaf9bce23 100755 --- a/lib/WorkflowMain.groovy +++ b/lib/WorkflowMain.groovy @@ -2,6 +2,8 @@ // This file holds several functions specific to the main.nf workflow in the nf-core/rnaseq pipeline // +import nextflow.Nextflow + class WorkflowMain { // @@ -83,8 +85,7 @@ class WorkflowMain { // Check input has been provided if (!params.input) { - log.error "Please provide an input samplesheet to the pipeline e.g. '--input samplesheet.csv'" - System.exit(1) + Nextflow.error("Please provide an input samplesheet to the pipeline e.g. '--input samplesheet.csv'") } } // diff --git a/lib/WorkflowRnaseq.groovy b/lib/WorkflowRnaseq.groovy index 64264ae37..ff577917b 100755 --- a/lib/WorkflowRnaseq.groovy +++ b/lib/WorkflowRnaseq.groovy @@ -2,6 +2,7 @@ // This file holds several functions specific to the workflow/rnaseq.nf in the nf-core/rnaseq pipeline // +import nextflow.Nextflow import groovy.json.JsonSlurper import groovy.text.SimpleTemplateEngine @@ -15,13 +16,11 @@ class WorkflowRnaseq { if (!params.fasta) { - log.error "Genome fasta file not specified with e.g. '--fasta genome.fa' or via a detectable config file." - System.exit(1) + Nextflow.error("Genome fasta file not specified with e.g. '--fasta genome.fa' or via a detectable config file.") } if (!params.gtf && !params.gff) { - log.error "No GTF or GFF3 annotation specified! The pipeline requires at least one of these files." - System.exit(1) + Nextflow.error("No GTF or GFF3 annotation specified! The pipeline requires at least one of these files.") } if (params.gtf) { @@ -41,51 +40,43 @@ class WorkflowRnaseq { } 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) + Nextflow.error("Please provide either --bbsplit_fasta_list / --bbsplit_index to run BBSplit.") } if (params.remove_ribo_rna && !params.ribo_database_manifest) { - log.error "Please provide --ribo_database_manifest to remove ribosomal RNA with SortMeRNA." - System.exit(1) + Nextflow.error("Please provide --ribo_database_manifest to remove ribosomal RNA with SortMeRNA.") } if (params.with_umi && !params.skip_umi_extract) { if (!params.umitools_bc_pattern && !params.umitools_bc_pattern2) { - log.error "UMI-tools requires a barcode pattern to extract barcodes from the reads." - System.exit(1) + Nextflow.error("UMI-tools requires a barcode pattern to extract barcodes from the reads.") } } if (!params.skip_trimming) { if (!valid_params['trimmers'].contains(params.trimmer)) { - log.error "Invalid option: '${params.trimmer}'. Valid options for '--trimmer': ${valid_params['trimmers'].join(', ')}." - System.exit(1) + Nextflow.error("Invalid option: '${params.trimmer}'. Valid options for '--trimmer': ${valid_params['trimmers'].join(', ')}.") } } if (!params.skip_alignment) { if (!valid_params['aligners'].contains(params.aligner)) { - log.error "Invalid option: '${params.aligner}'. Valid options for '--aligner': ${valid_params['aligners'].join(', ')}." - System.exit(1) + Nextflow.error("Invalid option: '${params.aligner}'. Valid options for '--aligner': ${valid_params['aligners'].join(', ')}.") } } else { if (!params.pseudo_aligner) { - log.error "--skip_alignment specified without --pseudo_aligner...please specify e.g. --pseudo_aligner ${valid_params['pseudoaligners'][0]}." - System.exit(1) + Nextflow.error("--skip_alignment specified without --pseudo_aligner...please specify e.g. --pseudo_aligner ${valid_params['pseudoaligners'][0]}.") } skipAlignmentWarn(log) } if (params.pseudo_aligner) { if (!valid_params['pseudoaligners'].contains(params.pseudo_aligner)) { - log.error "Invalid option: '${params.pseudo_aligner}'. Valid options for '--pseudo_aligner': ${valid_params['pseudoaligners'].join(', ')}." - System.exit(1) + Nextflow.error("Invalid option: '${params.pseudo_aligner}'. Valid options for '--pseudo_aligner': ${valid_params['pseudoaligners'].join(', ')}.") } else { if (!(params.salmon_index || params.transcript_fasta || (params.fasta && (params.gtf || params.gff)))) { - log.error "To use `--pseudo_aligner 'salmon'`, you must provide either --salmon_index or --transcript_fasta or both --fasta and --gtf / --gff." - System.exit(1) + Nextflow.error("To use `--pseudo_aligner 'salmon'`, you must provide either --salmon_index or --transcript_fasta or both --fasta and --gtf / --gff.") } } } @@ -120,8 +111,7 @@ class WorkflowRnaseq { // Check which RSeQC modules we are running def rseqc_modules = params.rseqc_modules ? params.rseqc_modules.split(',').collect{ it.trim().toLowerCase() } : [] if ((valid_params['rseqc_modules'] + rseqc_modules).unique().size() != valid_params['rseqc_modules'].size()) { - log.error "Invalid option: ${params.rseqc_modules}. Valid options for '--rseqc_modules': ${valid_params['rseqc_modules'].join(', ')}" - System.exit(1) + Nextflow.error("Invalid option: ${params.rseqc_modules}. Valid options for '--rseqc_modules': ${valid_params['rseqc_modules'].join(', ')}") } } @@ -159,14 +149,14 @@ class WorkflowRnaseq { def chrom = lspl[0] def size = lspl[1] if (size.toInteger() > max_size) { - log.error "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + + def error_string = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\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) + Nextflow.error(error_string) } } } @@ -313,12 +303,12 @@ class WorkflowRnaseq { // private static void genomeExistsError(params, log) { if (params.genomes && params.genome && !params.genomes.containsKey(params.genome)) { - log.error "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + + def error_string = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\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) + Nextflow.error(error_string) } } @@ -384,13 +374,13 @@ class WorkflowRnaseq { // Print a warning if using '--aligner star_rsem' and '--with_umi' // private static void rsemUmiError(log) { - log.error "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + + def error_string = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " When using '--aligner star_rsem', STAR is run by RSEM itself and so it is\n" + " not possible to remove UMIs before the quantification.\n\n" + " If you would like to remove UMI barcodes using the '--with_umi' option\n" + " please use either '--aligner star_salmon' or '--aligner hisat2'.\n" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" - System.exit(1) + Nextflow.error(error_string) } // From 7b8abfce13f535b84aaa8d4c5017c79a15f6b5c0 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Mon, 27 Mar 2023 16:48:53 +0100 Subject: [PATCH 112/124] Fix nf-core lint --- .nf-core.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.nf-core.yml b/.nf-core.yml index 40bcac74d..e6c9d79f0 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -3,4 +3,5 @@ lint: files_unchanged: - assets/email_template.html - assets/email_template.txt + - lib/NfcoreSchema.groovy - lib/NfcoreTemplate.groovy From aa407f456a35e0c33420e9e9086f9e78cef3cd13 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 28 Mar 2023 15:03:13 +0100 Subject: [PATCH 113/124] Add explicit test_full profiles for all cloud providers --- nextflow.config | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/nextflow.config b/nextflow.config index eadc068a2..163b13d6b 100644 --- a/nextflow.config +++ b/nextflow.config @@ -205,8 +205,17 @@ profiles { executor.cpus = 16 executor.memory = 60.GB } - test { includeConfig 'conf/test.config' } - test_full { includeConfig 'conf/test_full.config' } + test { includeConfig 'conf/test.config' } + test_full { includeConfig 'conf/test_full.config' } + test_full_aws { includeConfig 'conf/test_full.config' } + test_full_gcp { + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_gcp.csv' + igenomes_base = 'gs://igenomes' + } + test_full_azure { + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_azure.csv' + igenomes_base = 'az://igenomes' + } } // Load igenomes.config if required From 565e9708aa0ef49c89b4d0b8641b4e6436031951 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 28 Mar 2023 16:55:01 +0100 Subject: [PATCH 114/124] Update nextflow.config --- nextflow.config | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nextflow.config b/nextflow.config index 163b13d6b..63280bda5 100644 --- a/nextflow.config +++ b/nextflow.config @@ -209,10 +209,12 @@ profiles { test_full { includeConfig 'conf/test_full.config' } test_full_aws { includeConfig 'conf/test_full.config' } test_full_gcp { + includeConfig 'conf/test_full.config' input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_gcp.csv' igenomes_base = 'gs://igenomes' } - test_full_azure { + test_full_azure { + includeConfig 'conf/test_full.config' input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_azure.csv' igenomes_base = 'az://igenomes' } From 257fd7ea9e7cddb4e300fb43dff2821997849067 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Tue, 28 Mar 2023 16:57:25 +0100 Subject: [PATCH 115/124] Update nextflow.config --- nextflow.config | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nextflow.config b/nextflow.config index 63280bda5..5076234b1 100644 --- a/nextflow.config +++ b/nextflow.config @@ -210,13 +210,13 @@ profiles { test_full_aws { includeConfig 'conf/test_full.config' } test_full_gcp { includeConfig 'conf/test_full.config' - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_gcp.csv' - igenomes_base = 'gs://igenomes' + params.input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_gcp.csv' + params.igenomes_base = 'gs://igenomes' } test_full_azure { includeConfig 'conf/test_full.config' - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_azure.csv' - igenomes_base = 'az://igenomes' + params.input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_azure.csv' + params.igenomes_base = 'az://igenomes' } } From 530c813613619981086fa1811faa936ca85fac63 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Wed, 29 Mar 2023 09:33:07 +0100 Subject: [PATCH 116/124] Update nextflow.config --- nextflow.config | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/nextflow.config b/nextflow.config index 5076234b1..c5ca21943 100644 --- a/nextflow.config +++ b/nextflow.config @@ -210,13 +210,11 @@ profiles { test_full_aws { includeConfig 'conf/test_full.config' } test_full_gcp { includeConfig 'conf/test_full.config' - params.input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_gcp.csv' - params.igenomes_base = 'gs://igenomes' + params.input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_gcp.csv' } test_full_azure { includeConfig 'conf/test_full.config' - params.input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_azure.csv' - params.igenomes_base = 'az://igenomes' + params.input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/samplesheet/v3.10/samplesheet_full_azure.csv' } } From fe39f59aa5911075f5bfa2c7e4435fe6ddb6812d Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 29 Mar 2023 09:51:20 +0100 Subject: [PATCH 117/124] Minor fixes for JSON sent to Slack. The version already includes the "v" prefix, so no need to add it in the json. I also fixed the name, which was hardcoded to a different workflow. --- assets/slackreport.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/slackreport.json b/assets/slackreport.json index 043d02f27..fc84fa5e5 100644 --- a/assets/slackreport.json +++ b/assets/slackreport.json @@ -3,7 +3,7 @@ { "fallback": "Plain-text summary of the attachment.", "color": "<% if (success) { %>good<% } else { %>danger<%} %>", - "author_name": "sanger-tol/readmapping v${version} - ${runName}", + "author_name": "nf-core/rnaseq ${version} - ${runName}", "author_icon": "https://www.nextflow.io/docs/latest/_static/favicon.ico", "text": "<% if (success) { %>Pipeline completed successfully!<% } else { %>Pipeline completed with errors<% } %>", "fields": [ From 5c676f4970d9bf6c89b0ac647317cf1abee3e5cb Mon Sep 17 00:00:00 2001 From: Adam Talbot Date: Wed, 29 Mar 2023 13:40:49 +0100 Subject: [PATCH 118/124] fix: Switched all tests to run on self-hosted instead of Github hosted --- .github/workflows/awsfulltest.yml | 36 --------------------------- .github/workflows/awstest.yml | 29 --------------------- .github/workflows/branch.yml | 2 +- .github/workflows/ci.yml | 10 ++++---- .github/workflows/fix-linting.yml | 2 +- .github/workflows/linting.yml | 8 +++--- .github/workflows/linting_comment.yml | 2 +- 7 files changed, 12 insertions(+), 77 deletions(-) delete mode 100644 .github/workflows/awsfulltest.yml delete mode 100644 .github/workflows/awstest.yml diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml deleted file mode 100644 index 030e950d1..000000000 --- a/.github/workflows/awsfulltest.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: nf-core AWS full size tests -# This workflow is triggered on published releases. -# It can be additionally triggered manually with GitHub actions workflow dispatch button. -# It runs the -profile 'test_full' on AWS batch - -on: - release: - types: [published] - workflow_dispatch: -jobs: - run-tower: - name: Run AWS full tests - if: github.repository == 'nf-core/rnaseq' - runs-on: ubuntu-latest - # Do a full-scale run with different aligners - strategy: - matrix: - aligner: ["star_salmon", "star_rsem"] - steps: - - name: Launch workflow via tower - uses: nf-core/tower-action@v3 - with: - workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} - access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} - compute_env: ${{ secrets.TOWER_COMPUTE_ENV }} - workdir: s3://${{ secrets.AWS_S3_BUCKET }}/work/rnaseq/work-${{ github.sha }} - parameters: | - { - "outdir" : "s3://${{ secrets.AWS_S3_BUCKET }}/rnaseq/results-${{ github.sha }}/aligner_${{ matrix.aligner }}", - "aligner": "${{ matrix.aligner }}" - } - profiles: test_full,aws_tower - - uses: actions/upload-artifact@v3 - with: - name: Tower debug log file - path: tower_action_*.log diff --git a/.github/workflows/awstest.yml b/.github/workflows/awstest.yml deleted file mode 100644 index d2b1b704e..000000000 --- a/.github/workflows/awstest.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: nf-core AWS test -# This workflow can be triggered manually with the GitHub actions workflow dispatch button. -# It runs the -profile 'test' on AWS batch - -on: - workflow_dispatch: -jobs: - run-tower: - name: Run AWS tests - if: github.repository == 'nf-core/rnaseq' - runs-on: ubuntu-latest - steps: - # Launch workflow using Tower CLI tool action - - name: Launch workflow via tower - uses: nf-core/tower-action@v3 - with: - workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} - access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} - compute_env: ${{ secrets.TOWER_COMPUTE_ENV }} - workdir: s3://${{ secrets.AWS_S3_BUCKET }}/work/rnaseq/work-${{ github.sha }} - parameters: | - { - "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnaseq/results-test-${{ github.sha }}" - } - profiles: test,aws_tower - - uses: actions/upload-artifact@v3 - with: - name: Tower debug log file - path: tower_action_*.log diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml index fa15c1d59..ba92da3bc 100644 --- a/.github/workflows/branch.yml +++ b/.github/workflows/branch.yml @@ -7,7 +7,7 @@ on: jobs: test: - runs-on: ubuntu-latest + runs-on: self-hosted steps: # PRs to the nf-core repo master branch are only ok if coming from the nf-core repo `dev` or any `patch` branches - name: Check PRs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc63a1509..cff47dc2f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: name: Run pipeline with test data # Only run on push if this is the nf-core dev branch (merged PRs) if: "${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/rnaseq') }}" - runs-on: ubuntu-latest + runs-on: self-hosted strategy: matrix: NXF_VER: @@ -66,7 +66,7 @@ jobs: star_salmon: name: Test STAR Salmon with workflow parameters if: ${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/rnaseq') }} - runs-on: ubuntu-latest + runs-on: self-hosted strategy: matrix: parameters: @@ -123,7 +123,7 @@ jobs: star_rsem: name: Test STAR RSEM with workflow parameters if: ${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/rnaseq') }} - runs-on: ubuntu-latest + runs-on: self-hosted strategy: matrix: parameters: @@ -169,7 +169,7 @@ jobs: hisat2: name: Test HISAT2 with workflow parameters if: ${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/rnaseq') }} - runs-on: ubuntu-latest + runs-on: self-hosted strategy: matrix: parameters: @@ -215,7 +215,7 @@ jobs: salmon: name: Test Salmon with workflow parameters if: ${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/rnaseq') }} - runs-on: ubuntu-latest + runs-on: self-hosted strategy: matrix: parameters: diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml index 8b2617a2e..dcd363813 100644 --- a/.github/workflows/fix-linting.yml +++ b/.github/workflows/fix-linting.yml @@ -10,7 +10,7 @@ jobs: contains(github.event.comment.html_url, '/pull/') && contains(github.event.comment.body, '@nf-core-bot fix linting') && github.repository == 'nf-core/rnaseq' - runs-on: ubuntu-latest + runs-on: self-hosted steps: # Use the @nf-core-bot token to check out so we can push later - uses: actions/checkout@v3 diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 858d622ef..e214637cf 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -12,7 +12,7 @@ on: jobs: EditorConfig: - runs-on: ubuntu-latest + runs-on: self-hosted steps: - uses: actions/checkout@v3 @@ -25,7 +25,7 @@ jobs: run: editorconfig-checker -exclude README.md $(find .* -type f | grep -v '.git\|.py\|.md\|json\|yml\|yaml\|html\|css\|work\|.nextflow\|build\|nf_core.egg-info\|log.txt\|Makefile') Prettier: - runs-on: ubuntu-latest + runs-on: self-hosted steps: - uses: actions/checkout@v3 @@ -38,7 +38,7 @@ jobs: run: prettier --check ${GITHUB_WORKSPACE} PythonBlack: - runs-on: ubuntu-latest + runs-on: self-hosted steps: - uses: actions/checkout@v3 @@ -68,7 +68,7 @@ jobs: allow-repeats: false nf-core: - runs-on: ubuntu-latest + runs-on: self-hosted steps: - name: Check out pipeline code uses: actions/checkout@v3 diff --git a/.github/workflows/linting_comment.yml b/.github/workflows/linting_comment.yml index 0bbcd30f2..c3de71128 100644 --- a/.github/workflows/linting_comment.yml +++ b/.github/workflows/linting_comment.yml @@ -8,7 +8,7 @@ on: jobs: test: - runs-on: ubuntu-latest + runs-on: self-hosted steps: - name: Download lint results uses: dawidd6/action-download-artifact@v2 From 232cbf37fafe3374669729d2302e29b4820f022e Mon Sep 17 00:00:00 2001 From: Adam Talbot Date: Wed, 29 Mar 2023 13:53:45 +0100 Subject: [PATCH 119/124] Revert linting to use GHA hosted --- .github/workflows/branch.yml | 2 +- .github/workflows/fix-linting.yml | 2 +- .github/workflows/linting.yml | 8 ++++---- .github/workflows/linting_comment.yml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml index ba92da3bc..fa15c1d59 100644 --- a/.github/workflows/branch.yml +++ b/.github/workflows/branch.yml @@ -7,7 +7,7 @@ on: jobs: test: - runs-on: self-hosted + runs-on: ubuntu-latest steps: # PRs to the nf-core repo master branch are only ok if coming from the nf-core repo `dev` or any `patch` branches - name: Check PRs diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml index dcd363813..8b2617a2e 100644 --- a/.github/workflows/fix-linting.yml +++ b/.github/workflows/fix-linting.yml @@ -10,7 +10,7 @@ jobs: contains(github.event.comment.html_url, '/pull/') && contains(github.event.comment.body, '@nf-core-bot fix linting') && github.repository == 'nf-core/rnaseq' - runs-on: self-hosted + runs-on: ubuntu-latest steps: # Use the @nf-core-bot token to check out so we can push later - uses: actions/checkout@v3 diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index e214637cf..858d622ef 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -12,7 +12,7 @@ on: jobs: EditorConfig: - runs-on: self-hosted + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -25,7 +25,7 @@ jobs: run: editorconfig-checker -exclude README.md $(find .* -type f | grep -v '.git\|.py\|.md\|json\|yml\|yaml\|html\|css\|work\|.nextflow\|build\|nf_core.egg-info\|log.txt\|Makefile') Prettier: - runs-on: self-hosted + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -38,7 +38,7 @@ jobs: run: prettier --check ${GITHUB_WORKSPACE} PythonBlack: - runs-on: self-hosted + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -68,7 +68,7 @@ jobs: allow-repeats: false nf-core: - runs-on: self-hosted + runs-on: ubuntu-latest steps: - name: Check out pipeline code uses: actions/checkout@v3 diff --git a/.github/workflows/linting_comment.yml b/.github/workflows/linting_comment.yml index c3de71128..0bbcd30f2 100644 --- a/.github/workflows/linting_comment.yml +++ b/.github/workflows/linting_comment.yml @@ -8,7 +8,7 @@ on: jobs: test: - runs-on: self-hosted + runs-on: ubuntu-latest steps: - name: Download lint results uses: dawidd6/action-download-artifact@v2 From b4219efd682e3de601f71f440514a1f2c41c27a8 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Wed, 29 Mar 2023 14:53:29 +0100 Subject: [PATCH 120/124] Update CHANGELOG --- .github/workflows/cloud_tests_small.yml | 6 +++--- CHANGELOG.md | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index b1bd5711d..b36715856 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -16,7 +16,7 @@ on: jobs: run-small-tests-on-aws: if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} - runs-on: self-hosted + runs-on: ubuntu-latest steps: - uses: seqeralabs/action-tower-launch@v1 with: @@ -37,7 +37,7 @@ jobs: path: tower_action_*.log run-small-tests-on-gcp: if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'gcp' }} - runs-on: self-hosted + runs-on: ubuntu-latest steps: - uses: seqeralabs/action-tower-launch@v1 with: @@ -58,7 +58,7 @@ jobs: path: tower_action_*.log run-small-tests-on-azure: if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'azure' }} - runs-on: self-hosted + runs-on: ubuntu-latest steps: - uses: seqeralabs/action-tower-launch@v1 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dc7f96b8..42f7496ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ Thank you to everyone else that has contributed by reporting bugs, enhancements ### Enhancements & fixes +- Add infrastructure and CI for multi-cloud full-sized tests run via Nextflow Tower (see [#981](https://github.com/nf-core/rnaseq/pull/981)) - Added fastp support. - Users can now select between `--trimmer trimgalore` (default) and `--trimmer fastp`. - Trim Galore! specific pipeline parameters have been deprecated: `--clip_r1`, `--clip_r2`, `--three_prime_clip_r1`, `--three_prime_clip_r2` and `--trim_nextseq` From d50a30d8bbd1781a4126f429935207342977bd0e Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Wed, 29 Mar 2023 14:54:43 +0100 Subject: [PATCH 121/124] Update other CI tests --- .github/workflows/ci.yml | 10 +++++----- .github/workflows/cloud_tests_full.yml | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cff47dc2f..fc63a1509 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: name: Run pipeline with test data # Only run on push if this is the nf-core dev branch (merged PRs) if: "${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/rnaseq') }}" - runs-on: self-hosted + runs-on: ubuntu-latest strategy: matrix: NXF_VER: @@ -66,7 +66,7 @@ jobs: star_salmon: name: Test STAR Salmon with workflow parameters if: ${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/rnaseq') }} - runs-on: self-hosted + runs-on: ubuntu-latest strategy: matrix: parameters: @@ -123,7 +123,7 @@ jobs: star_rsem: name: Test STAR RSEM with workflow parameters if: ${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/rnaseq') }} - runs-on: self-hosted + runs-on: ubuntu-latest strategy: matrix: parameters: @@ -169,7 +169,7 @@ jobs: hisat2: name: Test HISAT2 with workflow parameters if: ${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/rnaseq') }} - runs-on: self-hosted + runs-on: ubuntu-latest strategy: matrix: parameters: @@ -215,7 +215,7 @@ jobs: salmon: name: Test Salmon with workflow parameters if: ${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/rnaseq') }} - runs-on: self-hosted + runs-on: ubuntu-latest strategy: matrix: parameters: diff --git a/.github/workflows/cloud_tests_full.yml b/.github/workflows/cloud_tests_full.yml index 88a03fa07..f17a53239 100644 --- a/.github/workflows/cloud_tests_full.yml +++ b/.github/workflows/cloud_tests_full.yml @@ -16,7 +16,7 @@ on: jobs: run-full-tests-on-aws: if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} - runs-on: self-hosted + runs-on: ubuntu-latest strategy: matrix: aligner: ["star_salmon", "star_rsem"] @@ -41,7 +41,7 @@ jobs: path: tower_action_*.log run-full-tests-on-gcp: if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'gcp' }} - runs-on: self-hosted + runs-on: ubuntu-latest strategy: matrix: aligner: ["star_salmon", "star_rsem"] @@ -66,7 +66,7 @@ jobs: path: tower_action_*.log run-full-tests-on-azure: if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'azure' }} - runs-on: self-hosted + runs-on: ubuntu-latest strategy: matrix: aligner: ["star_salmon", "star_rsem"] From 61c6050ec9f68c9e417892ac0f2057231e4694fb Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Wed, 29 Mar 2023 22:10:38 +0000 Subject: [PATCH 122/124] [automated] Fix linting with Prettier --- .github/workflows/cloud_tests_full.yml | 20 ++++++++++---------- .github/workflows/cloud_tests_small.yml | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/cloud_tests_full.yml b/.github/workflows/cloud_tests_full.yml index f17a53239..d5896515d 100644 --- a/.github/workflows/cloud_tests_full.yml +++ b/.github/workflows/cloud_tests_full.yml @@ -3,16 +3,16 @@ run-name: Submitting workflow to all cloud providers using full sized data on: workflow_dispatch: inputs: - platform: - description: 'Platform to run test' - required: true - default: 'all' - type: choice - options: - - all - - aws - - azure - - gcp + platform: + description: "Platform to run test" + required: true + default: "all" + type: choice + options: + - all + - aws + - azure + - gcp jobs: run-full-tests-on-aws: if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} diff --git a/.github/workflows/cloud_tests_small.yml b/.github/workflows/cloud_tests_small.yml index b36715856..318601912 100644 --- a/.github/workflows/cloud_tests_small.yml +++ b/.github/workflows/cloud_tests_small.yml @@ -3,16 +3,16 @@ run-name: Submitting workflow to all cloud providers using small sized data on: workflow_dispatch: inputs: - platform: - description: 'Platform to run test' - required: true - default: 'all' - type: choice - options: - - all - - aws - - azure - - gcp + platform: + description: "Platform to run test" + required: true + default: "all" + type: choice + options: + - all + - aws + - azure + - gcp jobs: run-small-tests-on-aws: if: ${{ github.event.inputs.platform == 'all' || github.event.inputs.platform == 'aws' }} From 0b206d25acdd49a5e41bd272f42a032f6e9d1d78 Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Thu, 30 Mar 2023 01:35:35 +0100 Subject: [PATCH 123/124] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42f7496ea..ecda50c86 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.11.0](https://github.com/nf-core/rnaseq/releases/tag/3.11.0)] - 2023-03-29 +## [[3.11.0](https://github.com/nf-core/rnaseq/releases/tag/3.11.0)] - 2023-03-30 ### Credits From fbffe8647e5da8d0f5dd4fff230b5bb2daf87f4e Mon Sep 17 00:00:00 2001 From: Harshil Patel Date: Thu, 30 Mar 2023 12:20:45 +0100 Subject: [PATCH 124/124] Update cloud_tests_full.yml --- .github/workflows/cloud_tests_full.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/cloud_tests_full.yml b/.github/workflows/cloud_tests_full.yml index d5896515d..92d784131 100644 --- a/.github/workflows/cloud_tests_full.yml +++ b/.github/workflows/cloud_tests_full.yml @@ -1,6 +1,8 @@ name: full-sized tests on cloud providers run-name: Submitting workflow to all cloud providers using full sized data on: + release: + types: [published] workflow_dispatch: inputs: platform: