From 0b61e28840a7882e59c3318dd9af86cd021c8b65 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 12 Jul 2022 16:20:24 +0200 Subject: [PATCH 001/176] bump dev version --- CHANGELOG.md | 10 ++++++++++ nextflow.config | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ef2ce97..80e45033 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,16 @@ 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). +## [2.2.0dev] + +### Added + +### Changed + +### Fixed + +### Removed + ## [2.1.0] nfcore/rnafusion - 2022/07/12 ### Added diff --git a/nextflow.config b/nextflow.config index 50d68c39..4bcf1277 100644 --- a/nextflow.config +++ b/nextflow.config @@ -220,7 +220,7 @@ manifest { description = 'Nextflow rnafusion analysis pipeline, part of the nf-core community.' mainScript = 'main.nf' nextflowVersion = '!>=21.10.3' - version = '2.1.0' + version = '2.2.0dev' } // Load modules.config for DSL2 module specific options From b5fdc4c76906582c4d349425a2a53caa41a95482 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 25 Jul 2022 17:25:28 +0200 Subject: [PATCH 002/176] update arriba visualisation to 2.3.0 --- CHANGELOG.md | 4 +++- modules/local/arriba/visualisation/main.nf | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80e45033..b79fea86 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). -## [2.2.0dev] +## [2.1.1dev] ### Added @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- `Arriba` visualisation now running with `Arriba` v2.3.0 + ### Removed ## [2.1.0] nfcore/rnafusion - 2022/07/12 diff --git a/modules/local/arriba/visualisation/main.nf b/modules/local/arriba/visualisation/main.nf index d7eeaab4..ea8aae06 100644 --- a/modules/local/arriba/visualisation/main.nf +++ b/modules/local/arriba/visualisation/main.nf @@ -2,10 +2,10 @@ process ARRIBA_VISUALISATION { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::arriba=2.1.0" : null) + conda (params.enable_conda ? "bioconda::arriba=2.3.0" : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/arriba:2.1.0--h3198e80_1' : - 'quay.io/biocontainers/arriba:2.1.0--h3198e80_1' }" + 'https://depot.galaxyproject.org/singularity/arriba:2.3.0--haa8aa89_0' : + 'quay.io/biocontainers/arriba:2.3.0--haa8aa89_0' }" input: tuple val(meta), path(bam), path(bai), path(fusions) From f6b853e1ad1c02b6129d7ad21469e58df2a8f93a Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 25 Jul 2022 17:26:26 +0200 Subject: [PATCH 003/176] add instruction for usage on S3 with new arriba references in container -> not reachable with S3 so manual input --- docs/usage.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index 51aa908c..4d74f197 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -26,7 +26,7 @@ First register for a free account at COSMIC at [https://cancer.sanger.ac.uk/cosm Download the references as shown below including your COSMIC credentials. -> Note that this step takes about 24 hours to complete on. +> Note that this step takes about 24 hours to complete on HPC. ```bash nextflow run nf-core/rnafusion \ @@ -46,6 +46,23 @@ nextflow run nf-core/rnafusion \ --outdir ``` +> For S3 usage: references for arriba are taken from the container image, which is not in the bound path with S3. Therefore arriba references have to be manually downloaded in this case and fed to rnafusion. Follow the steps below: + +- Download arriba tar.gz file from https://github.com/suhrig/arriba/releases/latest +- Extract +- Start rnafusion pipeline with: + +```bash +nextflow run nf-core/rnafusion \ + -- (-- ... OR --all) \ + --input \ + --genomes_base \ + --outdir \ + --arriba_ref_blacklist \ + --arriba_protein_domain \ + --arriba_ref +``` + #### References directory tree ```text From 6b75a91fb19dbf2bcbda53edc03efd3da25baf94 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 25 Jul 2022 17:30:19 +0200 Subject: [PATCH 004/176] add 140 to error strategy: retry --- conf/base.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/base.config b/conf/base.config index 7d3fa627..91e6643d 100644 --- a/conf/base.config +++ b/conf/base.config @@ -14,7 +14,7 @@ process { memory = { check_max( 6.GB * task.attempt, 'memory' ) } time = { check_max( 4.h * task.attempt, 'time' ) } - errorStrategy = { task.exitStatus in [143,137,104,134,139] ? 'retry' : 'finish' } + errorStrategy = { task.exitStatus in [140,143,137,104,134,139] ? 'retry' : 'finish' } maxRetries = 1 maxErrors = '-1' From 000c5d1fec856229ebe915bac27139bf498009b9 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 25 Jul 2022 17:30:46 +0200 Subject: [PATCH 005/176] bump version to 2.1.1dev (patch instead of minor) --- nextflow.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nextflow.config b/nextflow.config index 4bcf1277..11e69b29 100644 --- a/nextflow.config +++ b/nextflow.config @@ -220,7 +220,7 @@ manifest { description = 'Nextflow rnafusion analysis pipeline, part of the nf-core community.' mainScript = 'main.nf' nextflowVersion = '!>=21.10.3' - version = '2.2.0dev' + version = '2.1.1dev' } // Load modules.config for DSL2 module specific options From cc37fa159f4dbc14dac708c5c62a9ce99fd1e978 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 25 Jul 2022 17:31:21 +0200 Subject: [PATCH 006/176] modify awsfulltest --- .github/workflows/awsfulltest.yml | 14 ++++++++++++-- conf/test_full_build.config | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 780ae9f8..1574e956 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -24,7 +24,13 @@ jobs: { "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}" } - profiles: test_full_build,aws_tower + run: | + nextflow run ${GITHUB_WORKSPACE} -profile test_full_build,aws_tower \ + --all \ + --build_references --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ + --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} + + test_full_build,aws_tower nextflow_config: | process.errorStrategy = 'retry' process.maxRetries = 3 @@ -39,4 +45,8 @@ jobs: { "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}" } - profiles: test_full,aws_tower + run: | + nextflow run ${GITHUB_WORKSPACE} -profile test_full,aws_tower \ + --all \ + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + diff --git a/conf/test_full_build.config b/conf/test_full_build.config index 6243a1e1..8b1640ef 100644 --- a/conf/test_full_build.config +++ b/conf/test_full_build.config @@ -16,7 +16,7 @@ params { // Input data - genome = 'GRCh38' + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' build_references = true all = true genomes_base = "${params.outdir}/references" From c783d36a880d0ea0737987a8cced74d89814caed Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 25 Jul 2022 17:31:40 +0200 Subject: [PATCH 007/176] update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b79fea86..5401aab0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Instructions to run `Arriba` on S3 with manually downloaded references as with the `Arriba` now uses the references from the docker/singularity containers +- exitStatus 140 now part of the retry strategy + ### Changed ### Fixed - `Arriba` visualisation now running with `Arriba` v2.3.0 +- AWS megatest to display on nf-core website ### Removed From 7541f7ce380eb8555036c5f370d5707ae70abeb7 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 25 Jul 2022 17:36:21 +0200 Subject: [PATCH 008/176] fix typo --- .github/workflows/awsfulltest.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 1574e956..caa94377 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -29,8 +29,6 @@ jobs: --all \ --build_references --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} - - test_full_build,aws_tower nextflow_config: | process.errorStrategy = 'retry' process.maxRetries = 3 From fb931052bfeed1423200a972b72cc32adf4a76f1 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 25 Jul 2022 17:39:09 +0200 Subject: [PATCH 009/176] update CUSTOM_DUMPSOFTWAREVERSIONS --- CHANGELOG.md | 2 ++ modules.json | 2 +- modules/nf-core/modules/custom/dumpsoftwareversions/main.nf | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5401aab0..0f575186 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Update CUSTOM_DUMPSOFTWAREVERSIONS to use multiqc version 1.13 + ### Fixed - `Arriba` visualisation now running with `Arriba` v2.3.0 diff --git a/modules.json b/modules.json index cc6c8178..d6d01a9a 100644 --- a/modules.json +++ b/modules.json @@ -10,7 +10,7 @@ "git_sha": "9aadd9a6d3f5964476582319b3a1c54a3e3fe7c9" }, "custom/dumpsoftwareversions": { - "git_sha": "682f789f93070bd047868300dd018faf3d434e7c" + "git_sha": "e5b44499efcf6f7fb24874886bac60591c5d94dd" }, "fastqc": { "git_sha": "49b18b1639f4f7104187058866a8fab33332bdfe" diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf b/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf index 12293efc..203e485a 100644 --- a/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf +++ b/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf @@ -2,10 +2,10 @@ process CUSTOM_DUMPSOFTWAREVERSIONS { label 'process_low' // Requires `pyyaml` which does not have a dedicated container but is in the MultiQC container - conda (params.enable_conda ? "bioconda::multiqc=1.12" : null) + conda (params.enable_conda ? 'bioconda::multiqc=1.13a' : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.12--pyhdfd78af_0' : - 'quay.io/biocontainers/multiqc:1.12--pyhdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/multiqc:1.13a--pyhdfd78af_1' : + 'quay.io/biocontainers/multiqc:1.13a--pyhdfd78af_1' }" input: path versions From 3abe23541034fe1aa44b866489346a3e9aa62075 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 25 Jul 2022 17:41:15 +0200 Subject: [PATCH 010/176] prettier --- .github/workflows/awsfulltest.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index caa94377..473464e4 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -47,4 +47,3 @@ jobs: nextflow run ${GITHUB_WORKSPACE} -profile test_full,aws_tower \ --all \ --genomes_base /home/runner/work/rnafusion/rnafusion/results/references - From d52cc9f53cb1683267413ff4f2b99c928f5ac521 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 26 Jul 2022 10:06:59 +0200 Subject: [PATCH 011/176] modify AWS full test --- .github/workflows/awsfulltest.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 473464e4..57e2fcc3 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -22,12 +22,13 @@ jobs: workdir: s3://${{ secrets.AWS_S3_BUCKET }}/work/rnafusion/work-${{ github.sha }} parameters: | { - "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}" + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "build_references": "True" } run: | nextflow run ${GITHUB_WORKSPACE} -profile test_full_build,aws_tower \ --all \ - --build_references --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} nextflow_config: | process.errorStrategy = 'retry' From 32fbabd1479a2ce2c38d32322bc6dd123ca7a6cc Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 26 Jul 2022 10:12:28 +0200 Subject: [PATCH 012/176] modify AWS full test --- .github/workflows/awsfulltest.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 57e2fcc3..3948dad2 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -26,13 +26,13 @@ jobs: "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", "build_references": "True" } - run: | - nextflow run ${GITHUB_WORKSPACE} -profile test_full_build,aws_tower \ - --all \ - --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} nextflow_config: | process.errorStrategy = 'retry' process.maxRetries = 3 + run: | + nextflow run ${GITHUB_WORKSPACE} -profile test_full_build,aws_tower \ + --all \ + --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} - name: Launch workflow via tower uses: nf-core/tower-action@v3 with: @@ -44,7 +44,7 @@ jobs: { "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}" } - run: | + run: | nextflow run ${GITHUB_WORKSPACE} -profile test_full,aws_tower \ --all \ --genomes_base /home/runner/work/rnafusion/rnafusion/results/references From 456faf49249db101c113e163a2c9d149b35eab59 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 26 Jul 2022 10:13:47 +0200 Subject: [PATCH 013/176] modify AWS full test --- .github/workflows/awsfulltest.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 3948dad2..c444d2f9 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -30,9 +30,9 @@ jobs: process.errorStrategy = 'retry' process.maxRetries = 3 run: | - nextflow run ${GITHUB_WORKSPACE} -profile test_full_build,aws_tower \ - --all \ - --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} + nextflow run ${GITHUB_WORKSPACE} -profile test_full_build,aws_tower \ + --all \ + --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} - name: Launch workflow via tower uses: nf-core/tower-action@v3 with: @@ -45,6 +45,6 @@ jobs: "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}" } run: | - nextflow run ${GITHUB_WORKSPACE} -profile test_full,aws_tower \ - --all \ - --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + nextflow run ${GITHUB_WORKSPACE} -profile test_full,aws_tower \ + --all \ + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references From d0ef82aecb8c40ec47a58754a5058595bb0f08f5 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 26 Jul 2022 10:34:39 +0200 Subject: [PATCH 014/176] modify AWS full test --- .github/workflows/awsfulltest.yml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index c444d2f9..0e3740aa 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -24,15 +24,15 @@ jobs: { "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", - "build_references": "True" + "build_references": "True", + "all": "True", + "cosmic_username": "${{ secrets.COSMIC_USERNAME }}", + "cosmic_passwd": "${{ secrets.COSMIC_PASSWD }}" } nextflow_config: | process.errorStrategy = 'retry' process.maxRetries = 3 - run: | - nextflow run ${GITHUB_WORKSPACE} -profile test_full_build,aws_tower \ - --all \ - --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} + profiles: test_full_build,aws_tower - name: Launch workflow via tower uses: nf-core/tower-action@v3 with: @@ -42,9 +42,8 @@ jobs: workdir: s3://${{ secrets.AWS_S3_BUCKET }}/work/rnafusion/work-${{ github.sha }} parameters: | { - "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}" + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "all": "True" } - run: | - nextflow run ${GITHUB_WORKSPACE} -profile test_full,aws_tower \ - --all \ - --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + profiles: test_full_build,aws_tower From eb25b6434670318da1ac41e7d65dc486a5c8a62a Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 26 Jul 2022 14:34:58 +0200 Subject: [PATCH 015/176] re-add arriba download for AWS megatest purposes, change awsfulltest syntax --- .github/workflows/awsfulltest.yml | 7 +---- conf/test_full.config | 2 -- conf/test_full_build.config | 1 - modules/local/arriba/download/main.nf | 37 ++++++++++++++++++++++++++ modules/local/arriba/download/meta.yml | 26 ++++++++++++++++++ nextflow.config | 7 +++-- 6 files changed, 67 insertions(+), 13 deletions(-) create mode 100644 modules/local/arriba/download/main.nf create mode 100644 modules/local/arriba/download/meta.yml diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 0e3740aa..a55acead 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -24,10 +24,6 @@ jobs: { "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", - "build_references": "True", - "all": "True", - "cosmic_username": "${{ secrets.COSMIC_USERNAME }}", - "cosmic_passwd": "${{ secrets.COSMIC_PASSWD }}" } nextflow_config: | process.errorStrategy = 'retry' @@ -44,6 +40,5 @@ jobs: { "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", - "all": "True" } - profiles: test_full_build,aws_tower + profiles: test_full,aws_tower diff --git a/conf/test_full.config b/conf/test_full.config index 5525cad2..2b215ab6 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -15,9 +15,7 @@ params { config_profile_description = 'Full test dataset to check pipeline function' // Input data - genome = 'GRCh38' input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' - genomes_base = "${params.outdir}/references" all = true } diff --git a/conf/test_full_build.config b/conf/test_full_build.config index 8b1640ef..d7b44e82 100644 --- a/conf/test_full_build.config +++ b/conf/test_full_build.config @@ -19,7 +19,6 @@ params { input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' build_references = true all = true - genomes_base = "${params.outdir}/references" cosmic_username = "${{ secrets.cosmic_username }}" cosmic_passwd = "${{ secrets.cosmic_passwd }}" } diff --git a/modules/local/arriba/download/main.nf b/modules/local/arriba/download/main.nf new file mode 100644 index 00000000..695617ec --- /dev/null +++ b/modules/local/arriba/download/main.nf @@ -0,0 +1,37 @@ +process ARRIBA_DOWNLOAD { + tag "arriba" + label 'process_low' + + conda (params.enable_conda ? "bioconda::gnu-wget=1.18" : null) + if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { + container "https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h5bf99c6_5" + } else { + container "quay.io/biocontainers/gnu-wget:1.18--h5bf99c6_5" + } + + output: + path "versions.yml" , emit: versions + path "*" , emit: reference + + script: + """ + wget https://github.com/suhrig/arriba/releases/download/v2.3.0/arriba_v2.3.0.tar.gz -O arriba_v2.3.0.tar.gz + tar -xzvf arriba_v2.3.0.tar.gz + rm arriba_v2.3.0.tar.gz + mv arriba_v2.3.0/database/* . + rm -r arriba_v2.3.0 + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fusion_report: \$(echo \$(wget -V 2>&1) | grep "GNU Wget" | cut -d" " -f3) + END_VERSIONS + """ + + stub: + """ + mkdir -p arriba_v2.3.0/database/ + touch arriba_v2.3.0/database/arriba.test + + touch versions.yml + """ +} diff --git a/modules/local/arriba/download/meta.yml b/modules/local/arriba/download/meta.yml new file mode 100644 index 00000000..55e50b11 --- /dev/null +++ b/modules/local/arriba/download/meta.yml @@ -0,0 +1,26 @@ +name: arriba_download +description: Arriba is a command-line tool for the detection of gene fusions from RNA-Seq data. +keywords: + - fusion + - arriba +tools: + - arriba: + description: Fast and accurate gene fusion detection from RNA-Seq data + homepage: https://github.com/suhrig/arriba + documentation: https://arriba.readthedocs.io/en/latest/ + tool_dev_url: https://github.com/suhrig/arriba + doi: "10.1101/gr.257246.119" + licence: ["MIT"] + +output: + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + - reference: + type: directory + description: Folder with arriba references + pattern: "*" + +authors: + - "@praveenraj2018, @rannick" diff --git a/nextflow.config b/nextflow.config index 11e69b29..6893299e 100644 --- a/nextflow.config +++ b/nextflow.config @@ -58,10 +58,9 @@ params { // Path to references ensembl_ref = "${params.genomes_base}/ensembl" - arriba_ref = "/usr/local/var/lib/arriba" - arriba_ref_blacklist = "/usr/local/var/lib/arriba/blacklist_hg38_GRCh38_v2.3.0.tsv.gz" - arriba_ref_protein_domain = "/usr/local/var/lib/arriba/protein_domains_hg38_GRCh38_v2.3.0.gff3" - // arriba paths only valid for singularity and docker containers, ok as conda not supported in rnafusion + arriba_ref = "${params.genomes_base}/arriba" + arriba_ref_blacklist = "${params.genomes_base}/arriba/blacklist_hg38_GRCh38_v2.3.0.tsv.gz" + arriba_ref_protein_domain = "${params.genomes_base}/arriba/protein_domains_hg38_GRCh38_v2.3.0.gff3" fusioncatcher_ref = "${params.genomes_base}/fusioncatcher/human_v102" pizzly_ref = "${params.genomes_base}/pizzly/kallisto" squid_ref = "${params.genomes_base}/squid" From 199d7883277322016e7b02bd82714cd820721ea3 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 26 Jul 2022 14:47:44 +0200 Subject: [PATCH 016/176] change AWS test to small arriba test --- .github/workflows/awsfulltest.yml | 2 ++ .github/workflows/awstest.yml | 18 +++++++++++++++++- conf/test.config | 1 + conf/test_build.config | 24 ++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 conf/test_build.config diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index a55acead..e2225b2a 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -24,6 +24,8 @@ jobs: { "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}" } nextflow_config: | process.errorStrategy = 'retry' diff --git a/.github/workflows/awstest.yml b/.github/workflows/awstest.yml index 5a04305d..02ba8afa 100644 --- a/.github/workflows/awstest.yml +++ b/.github/workflows/awstest.yml @@ -11,6 +11,21 @@ jobs: runs-on: ubuntu-latest steps: # Launch workflow using Tower CLI tool action + - name: Launch build 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}" + } + profiles: test_build,aws_tower - name: Launch workflow via tower uses: nf-core/tower-action@v3 with: @@ -20,6 +35,7 @@ jobs: workdir: s3://${{ secrets.AWS_S3_BUCKET }}/work/rnafusion/work-${{ github.sha }} parameters: | { - "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-test-${{ github.sha }}" + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", } profiles: test,aws_tower diff --git a/conf/test.config b/conf/test.config index 35910107..53ccc5c2 100644 --- a/conf/test.config +++ b/conf/test.config @@ -21,5 +21,6 @@ params { // Input data input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' + arriba = true } diff --git a/conf/test_build.config b/conf/test_build.config new file mode 100644 index 00000000..69047a54 --- /dev/null +++ b/conf/test_build.config @@ -0,0 +1,24 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/rnafusion -profile test, --outdir + +---------------------------------------------------------------------------------------- +*/ + +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Limit resources so that this can run on GitHub Actions + max_cpus = 2 + max_memory = 6.GB + max_time = 6.h + + build_references = true + arriba = true +} From e020939d29d9716753e0f5bbb24f52b11ea8280f Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 26 Jul 2022 15:00:04 +0200 Subject: [PATCH 017/176] include test_build in config --- nextflow.config | 1 + 1 file changed, 1 insertion(+) diff --git a/nextflow.config b/nextflow.config index 6893299e..e60b3e5a 100644 --- a/nextflow.config +++ b/nextflow.config @@ -175,6 +175,7 @@ profiles { shifter.enabled = false } test { includeConfig 'conf/test.config' } + test_build { includeConfig 'conf/test_build.config' } test_full { includeConfig 'conf/test_full.config' } test_full_build { includeConfig 'conf/test_full_build.config' } From a8f2310110a930ade9101c412d16c6faa4aea1a3 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 26 Jul 2022 17:20:23 +0200 Subject: [PATCH 018/176] modify workflow to run aws test in only one step --- .github/workflows/awstest.yml | 13 ------------- conf/test_build.config | 4 +++- main.nf | 6 +----- workflows/build_references.nf | 5 +++++ 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/.github/workflows/awstest.yml b/.github/workflows/awstest.yml index 02ba8afa..365a4fa1 100644 --- a/.github/workflows/awstest.yml +++ b/.github/workflows/awstest.yml @@ -26,16 +26,3 @@ jobs: "cosmic_passwd": "${{ secrets.cosmic_passwd }}" } profiles: test_build,aws_tower - - 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/rnafusion/work-${{ github.sha }} - parameters: | - { - "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", - "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", - } - profiles: test,aws_tower diff --git a/conf/test_build.config b/conf/test_build.config index 69047a54..a0b51273 100644 --- a/conf/test_build.config +++ b/conf/test_build.config @@ -16,9 +16,11 @@ params { // Limit resources so that this can run on GitHub Actions max_cpus = 2 - max_memory = 6.GB + max_memory = 12.GB max_time = 6.h build_references = true arriba = true + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' + } diff --git a/main.nf b/main.nf index 2408022e..52292259 100644 --- a/main.nf +++ b/main.nf @@ -54,15 +54,11 @@ include { RNAFUSION } from './workflows/rnafusion' workflow NFCORE_RNAFUSION { if (params.build_references) { - BUILD_REFERENCES () - } else { - + if (file(params.input).exists()) RNAFUSION() - } - } /* diff --git a/workflows/build_references.nf b/workflows/build_references.nf index 5910c15c..03f67e2e 100644 --- a/workflows/build_references.nf +++ b/workflows/build_references.nf @@ -4,6 +4,7 @@ ======================================================================================== */ +include { ARRIBA_DOWNLOAD } from '../modules/local/arriba/main' include { ENSEMBL_DOWNLOAD } from '../modules/local/ensembl/main' include { FUSIONCATCHER_DOWNLOAD } from '../modules/local/fusioncatcher/download/main' include { FUSIONREPORT_DOWNLOAD } from '../modules/local/fusionreport/download/main' @@ -34,6 +35,10 @@ workflow BUILD_REFERENCES { STAR_GENOMEGENERATE( ENSEMBL_DOWNLOAD.out.fasta, ENSEMBL_DOWNLOAD.out.gtf ) } + if (params.arriba || params.all) { + ARRIBA_DOWNLOAD() + } + if (params.fusioncatcher || params.all) { FUSIONCATCHER_DOWNLOAD() } From c64d7b23dcefb9dc66300f7e01bdff3e93cf1782 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 26 Jul 2022 17:23:58 +0200 Subject: [PATCH 019/176] fix syntax --- main.nf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main.nf b/main.nf index 52292259..a02811a1 100644 --- a/main.nf +++ b/main.nf @@ -55,9 +55,11 @@ workflow NFCORE_RNAFUSION { if (params.build_references) { BUILD_REFERENCES () + } - if (file(params.input).exists()) + if (file(params.input).exists()) { RNAFUSION() + } } From 7baec294a1aabf4de489bd2f60bf65e71333f97d Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 26 Jul 2022 17:27:03 +0200 Subject: [PATCH 020/176] fix path arriba download --- workflows/build_references.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/build_references.nf b/workflows/build_references.nf index 03f67e2e..0e2eeacc 100644 --- a/workflows/build_references.nf +++ b/workflows/build_references.nf @@ -4,7 +4,7 @@ ======================================================================================== */ -include { ARRIBA_DOWNLOAD } from '../modules/local/arriba/main' +include { ARRIBA_DOWNLOAD } from '../modules/local/arriba/download/main' include { ENSEMBL_DOWNLOAD } from '../modules/local/ensembl/main' include { FUSIONCATCHER_DOWNLOAD } from '../modules/local/fusioncatcher/download/main' include { FUSIONREPORT_DOWNLOAD } from '../modules/local/fusionreport/download/main' From a35aa848bf86e041d631d995ac441f0c6e628e34 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Thu, 4 Aug 2022 11:09:28 +0200 Subject: [PATCH 021/176] fix typo --- .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 e2225b2a..df978319 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -41,6 +41,6 @@ jobs: parameters: | { "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", - "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references" } profiles: test_full,aws_tower From a1b6061ed2d6fe1648f416edda949cb8b2d632a1 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Thu, 4 Aug 2022 11:28:25 +0200 Subject: [PATCH 022/176] fix ci test --- conf/test.config | 2 -- 1 file changed, 2 deletions(-) diff --git a/conf/test.config b/conf/test.config index 53ccc5c2..d8e7bcc4 100644 --- a/conf/test.config +++ b/conf/test.config @@ -21,6 +21,4 @@ params { // Input data input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' - arriba = true - } From 0a23befea635b951b08cd09e1db5a1e0df3e19c1 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Thu, 4 Aug 2022 13:49:56 +0200 Subject: [PATCH 023/176] build stub for local modules --- modules/local/arriba/download/main.nf | 11 +++++++---- modules/local/arriba/visualisation/main.nf | 11 +++++++++++ modules/local/ensembl/main.nf | 5 ++++- modules/local/fusioncatcher/detect/main.nf | 14 ++++++++++++++ modules/local/fusioncatcher/download/main.nf | 10 ++++++++++ modules/local/fusioninspector/main.nf | 6 +++++- modules/local/fusioninspector_dev/main.nf | 6 +++++- modules/local/fusionreport/detect/main.nf | 12 ++++++++++++ modules/local/fusionreport/download/main.nf | 13 +++++++++++++ modules/local/getmeta/main.nf | 4 ++++ modules/local/getpath/main.nf | 4 ++++ modules/local/kallisto/quant/main.nf | 11 +++++++++++ .../local/picard/collectrnaseqmetrics/main.nf | 12 ++++++++++++ modules/local/pizzly/detect/main.nf | 11 +++++++++++ modules/local/pizzly/download/main.nf | 14 +++++++++++++- modules/local/reformat/main.nf | 13 ++++++++++++- modules/local/squid/annotate/main.nf | 11 +++++++++++ modules/local/squid/detect/main.nf | 11 +++++++++++ modules/local/starfusion/build/main.nf | 16 ++++++++++++++++ modules/local/starfusion/detect/main.nf | 6 +++++- modules/local/starfusion/download/main.nf | 11 +++++++++++ modules/local/uscs/custom_gtftogenepred/main.nf | 10 ++++++++++ 22 files changed, 212 insertions(+), 10 deletions(-) diff --git a/modules/local/arriba/download/main.nf b/modules/local/arriba/download/main.nf index 695617ec..66692b1e 100644 --- a/modules/local/arriba/download/main.nf +++ b/modules/local/arriba/download/main.nf @@ -23,15 +23,18 @@ process ARRIBA_DOWNLOAD { cat <<-END_VERSIONS > versions.yml "${task.process}": - fusion_report: \$(echo \$(wget -V 2>&1) | grep "GNU Wget" | cut -d" " -f3) + wget: \$(echo wget -V 2>&1 | grep "GNU Wget" | cut -d" " -f3 > versions.yml) END_VERSIONS """ stub: """ - mkdir -p arriba_v2.3.0/database/ - touch arriba_v2.3.0/database/arriba.test + touch blacklist_hg38_GRCh38_v2.3.0.tsv.gz + touch protein_domains_hg38_GRCh38_v2.3.0.gff3 - touch versions.yml + cat <<-END_VERSIONS > versions.yml + "${task.process}": + wget: \$(echo wget -V 2>&1 | grep "GNU Wget" | cut -d" " -f3 > versions.yml) + END_VERSIONS """ } diff --git a/modules/local/arriba/visualisation/main.nf b/modules/local/arriba/visualisation/main.nf index ea8aae06..e7497df8 100644 --- a/modules/local/arriba/visualisation/main.nf +++ b/modules/local/arriba/visualisation/main.nf @@ -37,4 +37,15 @@ process ARRIBA_VISUALISATION { arriba: \$(arriba -h | grep 'Version:' 2>&1 | sed 's/Version:\s//') END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.pdf + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + arriba: \$(arriba -h | grep 'Version:' 2>&1 | sed 's/Version:\s//') + END_VERSIONS + """ } diff --git a/modules/local/ensembl/main.nf b/modules/local/ensembl/main.nf index 1b689f40..cd143eef 100644 --- a/modules/local/ensembl/main.nf +++ b/modules/local/ensembl/main.nf @@ -45,7 +45,10 @@ process ENSEMBL_DOWNLOAD { touch "Homo_sapiens.${params.genome}.${ensembl_version}.chr.gtf" touch "Homo_sapiens.${params.genome}.${ensembl_version}.cdna.all.fa.gz" - touch versions.yml + cat <<-END_VERSIONS > versions.yml + "${task.process}": + wget: \$(echo wget -V 2>&1 | grep "GNU Wget" | cut -d" " -f3 > versions.yml) + END_VERSIONS """ } diff --git a/modules/local/fusioncatcher/detect/main.nf b/modules/local/fusioncatcher/detect/main.nf index 12018c42..23424cc4 100644 --- a/modules/local/fusioncatcher/detect/main.nf +++ b/modules/local/fusioncatcher/detect/main.nf @@ -46,4 +46,18 @@ process FUSIONCATCHER { fusioncatcher: \$(echo \$(fusioncatcher --version 2>&1)| sed 's/fusioncatcher.py //') END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + + """ + touch ${prefix}.fusioncatcher.fusion-genes.txt + touch ${prefix}.fusioncatcher.summary.txt + touch ${prefix}.fusioncatcher.log + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fusioncatcher: \$(echo \$(fusioncatcher --version 2>&1)| sed 's/fusioncatcher.py //') + END_VERSIONS + """ } diff --git a/modules/local/fusioncatcher/download/main.nf b/modules/local/fusioncatcher/download/main.nf index 119f2523..9daa0191 100644 --- a/modules/local/fusioncatcher/download/main.nf +++ b/modules/local/fusioncatcher/download/main.nf @@ -40,4 +40,14 @@ process FUSIONCATCHER_DOWNLOAD { fusioncatcher: \$(echo \$(fusioncatcher --version 2>&1)) END_VERSIONS """ + + stub: + """ + mkdir human_${human_version} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fusioncatcher: \$(echo \$(fusioncatcher --version 2>&1)) + END_VERSIONS + """ } diff --git a/modules/local/fusioninspector/main.nf b/modules/local/fusioninspector/main.nf index 9039bbfc..28c107ed 100644 --- a/modules/local/fusioninspector/main.nf +++ b/modules/local/fusioninspector/main.nf @@ -42,7 +42,11 @@ process FUSIONINSPECTOR { stub: """ - touch versions.yml touch FusionInspector.log + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') + END_VERSIONS """ } diff --git a/modules/local/fusioninspector_dev/main.nf b/modules/local/fusioninspector_dev/main.nf index f8c28a86..dce04e4a 100644 --- a/modules/local/fusioninspector_dev/main.nf +++ b/modules/local/fusioninspector_dev/main.nf @@ -41,7 +41,11 @@ process FUSIONINSPECTOR_DEV { stub: """ - touch versions.yml touch FusionInspector.log + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') + END_VERSIONS """ } diff --git a/modules/local/fusionreport/detect/main.nf b/modules/local/fusionreport/detect/main.nf index c1c77452..da25c49a 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/local/fusionreport/detect/main.nf @@ -35,6 +35,18 @@ process FUSIONREPORT { mv fusion_list.tsv ${prefix}.fusionreport.tsv mv fusion_list_filtered.tsv ${prefix}.fusionreport_filtered.tsv + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fusion_report: \$(fusion_report --version | sed 's/fusion-report //') + END_VERSIONS + """ + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.fusionreport_filtered.tsv + touch ${prefix}.fusionreport.tsv + touch index.html + cat <<-END_VERSIONS > versions.yml "${task.process}": fusion_report: \$(fusion_report --version | sed 's/fusion-report //') diff --git a/modules/local/fusionreport/download/main.nf b/modules/local/fusionreport/download/main.nf index 415a8b36..f5898c57 100644 --- a/modules/local/fusionreport/download/main.nf +++ b/modules/local/fusionreport/download/main.nf @@ -26,4 +26,17 @@ process FUSIONREPORT_DOWNLOAD { fusion_report: \$(fusion_report --version | sed 's/fusion-report //') END_VERSIONS """ + + stub: + """ + touch cosmic.db + touch fusiongdb2.db + touch fusiongdb.db + touch mitelman.db + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fusion_report: \$(fusion_report --version | sed 's/fusion-report //') + END_VERSIONS + """ } diff --git a/modules/local/getmeta/main.nf b/modules/local/getmeta/main.nf index c52b16dc..3326e7df 100644 --- a/modules/local/getmeta/main.nf +++ b/modules/local/getmeta/main.nf @@ -17,4 +17,8 @@ process GET_META { script: """ """ + + stub: + """ + """ } diff --git a/modules/local/getpath/main.nf b/modules/local/getpath/main.nf index 5f159287..0ef00264 100644 --- a/modules/local/getpath/main.nf +++ b/modules/local/getpath/main.nf @@ -16,4 +16,8 @@ process GET_PATH { script: """ """ + + stub: + """ + """ } diff --git a/modules/local/kallisto/quant/main.nf b/modules/local/kallisto/quant/main.nf index bc0f3511..04f64227 100644 --- a/modules/local/kallisto/quant/main.nf +++ b/modules/local/kallisto/quant/main.nf @@ -33,5 +33,16 @@ process KALLISTO_QUANT { kallisto: \$(echo \$(kallisto 2>&1) | sed 's/^kallisto //; s/Usage.*\$//') END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.kallisto_quant.fusions.txt + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + kallisto: \$(echo \$(kallisto 2>&1) | sed 's/^kallisto //; s/Usage.*\$//') + END_VERSIONS + """ } diff --git a/modules/local/picard/collectrnaseqmetrics/main.nf b/modules/local/picard/collectrnaseqmetrics/main.nf index d01c6534..0305844d 100644 --- a/modules/local/picard/collectrnaseqmetrics/main.nf +++ b/modules/local/picard/collectrnaseqmetrics/main.nf @@ -55,4 +55,16 @@ process PICARD_COLLECTRNASEQMETRICS { picard: \$(picard CollectRnaMetrics --version 2>&1 | grep -o 'Version.*' | cut -f2- -d:) END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}_rna_metrics.txt + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + picard: \$(picard CollectRnaMetrics --version 2>&1 | grep -o 'Version.*' | cut -f2- -d:) + END_VERSIONS + """ + } diff --git a/modules/local/pizzly/detect/main.nf b/modules/local/pizzly/detect/main.nf index 6222d3ba..f5e4b6e5 100644 --- a/modules/local/pizzly/detect/main.nf +++ b/modules/local/pizzly/detect/main.nf @@ -34,5 +34,16 @@ process PIZZLY { pizzly: \$(pizzly --version | grep pizzly | sed -e "s/pizzly version: //g") END_VERSIONS """ + + stub: + """ + touch ${prefix}.pizzly.txt + touch ${prefix}.pizzly.unfiltered.json + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + pizzly: \$(pizzly --version | grep pizzly | sed -e "s/pizzly version: //g") + END_VERSIONS + """ } diff --git a/modules/local/pizzly/download/main.nf b/modules/local/pizzly/download/main.nf index d3be739b..66b8c9d9 100644 --- a/modules/local/pizzly/download/main.nf +++ b/modules/local/pizzly/download/main.nf @@ -24,6 +24,18 @@ process PIZZLY_DOWNLOAD { $args \\ $transcript - echo \$(kallisto 2>&1) | sed 's/^kallisto //; s/Usage.*\$//' > versions.yml + cat <<-END_VERSIONS > versions.yml + "${task.process}": + kallisto: \$(echo \$(kallisto 2>&1) | sed 's/^kallisto //; s/Usage.*\$//') + END_VERSIONS """ + + stub: + """ + touch index.idx + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + kallisto: \$(echo \$(kallisto 2>&1) | sed 's/^kallisto //; s/Usage.*\$//') + END_VERSIONS """ } diff --git a/modules/local/reformat/main.nf b/modules/local/reformat/main.nf index a4a8046f..74b5072f 100644 --- a/modules/local/reformat/main.nf +++ b/modules/local/reformat/main.nf @@ -32,8 +32,19 @@ process REFORMAT { reformat.sh $in1 $out1 $args reformat.sh $in2 $out2 $args2 + cat <<-END_VERSIONS > versions.yml + "${task.process}": + reformat.sh: \$(echo \$(reformat.sh --version 2>&1)| sed -e "s/BBMap version //g" ) + END_VERSIONS + """ - + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + def out1 ="out=${prefix}_R1_trimmed.fq.gz" + def out2 =meta.single_end ? "" : "out=${prefix}_R2_trimmed.fq.gz" + """ + touch $out1 + touch $out2 cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/local/squid/annotate/main.nf b/modules/local/squid/annotate/main.nf index 585b082d..48d6ef6d 100644 --- a/modules/local/squid/annotate/main.nf +++ b/modules/local/squid/annotate/main.nf @@ -30,4 +30,15 @@ process SQUID_ANNOTATE { squid: \$(echo \$(squid --version 2>&1) | sed 's/v//') END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.squid.fusions.annotated.txt + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + squid: \$(echo \$(squid --version 2>&1) | sed 's/v//') + END_VERSIONS + """ } diff --git a/modules/local/squid/detect/main.nf b/modules/local/squid/detect/main.nf index 80106c0f..f4fe0d4d 100644 --- a/modules/local/squid/detect/main.nf +++ b/modules/local/squid/detect/main.nf @@ -29,4 +29,15 @@ process SQUID { squid: \$(echo \$(squid --version 2>&1) | sed 's/v//') END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.squid.fusions_sv.txt + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + squid: \$(echo \$(squid --version 2>&1) | sed 's/v//') + END_VERSIONS + """ } diff --git a/modules/local/starfusion/build/main.nf b/modules/local/starfusion/build/main.nf index f50aaa79..c66ed8fa 100644 --- a/modules/local/starfusion/build/main.nf +++ b/modules/local/starfusion/build/main.nf @@ -37,5 +37,21 @@ process STARFUSION_BUILD { --dfam_db homo_sapiens_dfam.hmm \\ --max_readlength $params.read_length \\ --CPU $task.cpus + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') + END_VERSIONS + """ + + stub: + """ + mkdir ctat_genome_lib_build_dir + touch ref_annot.cdna.fa + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') + END_VERSIONS """ } diff --git a/modules/local/starfusion/detect/main.nf b/modules/local/starfusion/detect/main.nf index 279b3e4e..3d48f375 100644 --- a/modules/local/starfusion/detect/main.nf +++ b/modules/local/starfusion/detect/main.nf @@ -49,7 +49,11 @@ process STARFUSION { touch ${prefix}.starfusion.fusion_predictions.tsv touch ${prefix}.starfusion.abridged.tsv touch ${prefix}.starfusion.abridged.coding_effect.tsv - touch versions.yml + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') + END_VERSIONS """ } diff --git a/modules/local/starfusion/download/main.nf b/modules/local/starfusion/download/main.nf index 88fb1312..f6c6ab5d 100644 --- a/modules/local/starfusion/download/main.nf +++ b/modules/local/starfusion/download/main.nf @@ -23,4 +23,15 @@ process STARFUSION_DOWNLOAD { mv */ctat_genome_lib_build_dir . """ + + stub: + """ + mkdir ctat_genome_lib_build_dir + touch ref_annot.cdna.fa + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') + END_VERSIONS + """ } diff --git a/modules/local/uscs/custom_gtftogenepred/main.nf b/modules/local/uscs/custom_gtftogenepred/main.nf index 74e4c6f3..9b7ce4cf 100644 --- a/modules/local/uscs/custom_gtftogenepred/main.nf +++ b/modules/local/uscs/custom_gtftogenepred/main.nf @@ -19,6 +19,16 @@ process GTF_TO_REFFLAT { gtfToGenePred -genePredExt -geneNameAsName2 ${gtf} ${genepred} paste ${genepred} ${genepred} | cut -f12,16-25 > ${refflat} + cat <<-END_VERSIONS > versions.yml + "${task.process}": + gtfToGenePred: 377 + END_VERSIONS + """ + stub: + def refflat = gtf + '.refflat' + """ + touch ${refflat} + cat <<-END_VERSIONS > versions.yml "${task.process}": gtfToGenePred: 377 From ec780475aa1ac14e005748d7cd1928dc273a481f Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Thu, 4 Aug 2022 13:50:07 +0200 Subject: [PATCH 024/176] change ci test to stub --- .github/workflows/ci.yml | 6 ------ conf/test.config | 1 + 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 750af29d..42be6cc5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,9 +48,3 @@ jobs: --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly --fusionreport \ --build_references --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} - - - name: Test running pizzly references - run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker \ - --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly \ - --genomes_base /home/runner/work/rnafusion/rnafusion/results/references -stub diff --git a/conf/test.config b/conf/test.config index d8e7bcc4..83dba5e8 100644 --- a/conf/test.config +++ b/conf/test.config @@ -21,4 +21,5 @@ params { // Input data input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' + stub = true } From 4fb4a560c171406a6ac1f0dfcfcdadb4752e2039 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Thu, 4 Aug 2022 13:50:38 +0200 Subject: [PATCH 025/176] remove ericscript --- modules/local/ericscript/detect/main.nf | 44 ----------------------- modules/local/ericscript/download/main.nf | 24 ------------- 2 files changed, 68 deletions(-) delete mode 100644 modules/local/ericscript/detect/main.nf delete mode 100644 modules/local/ericscript/download/main.nf diff --git a/modules/local/ericscript/detect/main.nf b/modules/local/ericscript/detect/main.nf deleted file mode 100644 index baeb5a62..00000000 --- a/modules/local/ericscript/detect/main.nf +++ /dev/null @@ -1,44 +0,0 @@ -process ERICSCRIPT { - tag "eriscript" - label 'process_low' - - conda (params.enable_conda ? "bioconda::ericscript=0.5.5 conda-forge::ncurses=6.1" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "docker.io/nfcore/rnafusion:ericscript_0.5.5" - } else { - container "docker.io/nfcore/rnafusion:ericscript_0.5.5" - } - - input: - tuple val(meta), path(reads) - path reference - - output: - tuple val(meta), path("*.results.filtered.tsv"), emit: fusions - tuple val(meta), path("*.results.total.tsv") , emit: fusions_total - path "versions.yml" , emit: versions - - script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - """ - - ericscript.pl \\ - -db $reference \\ - -name ${prefix} \\ - -p $task.cpus \\ - -o . \\ - $reads \\ - $args - - echo \$(wget -V 2>&1) | grep "GNU Wget" | cut -d" " -f3 > versions.yml - - """ - - stub: - """ - touch ${prefix}.results.filtered.tsv - touch ${prefix}.results.total.tsv - touch versions.yml - """ -} diff --git a/modules/local/ericscript/download/main.nf b/modules/local/ericscript/download/main.nf deleted file mode 100644 index 95510c15..00000000 --- a/modules/local/ericscript/download/main.nf +++ /dev/null @@ -1,24 +0,0 @@ -process ERICSCRIPT_DOWNLOAD { - tag "eriscript" - label 'process_low' - - conda (params.enable_conda ? "bioconda::gnu-wget=1.18" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h5bf99c6_5" - } else { - container "quay.io/biocontainers/gnu-wget:1.18--h5bf99c6_5" - } - - output: - path "versions.yml" , emit: versions - path "*" , emit: reference - - script: - """ - wget http://ngi-igenomes.s3.amazonaws.com/igenomes/Homo_sapiens/Ensembl/GRCh38/Sequence/ericscript_db_homosapiens_ensembl84.tar.bz2 - tar jxf ericscript_db_homosapiens_ensembl84.tar.bz2 --strip-components=2 - rm ericscript_db_homosapiens_ensembl84.tar.bz2 - - echo \$(wget -V 2>&1) | grep "GNU Wget" | cut -d" " -f3 > versions.yml - """ -} From 6f570b2455695d8bcc6a048be46f8d571e85ba1f Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Thu, 4 Aug 2022 13:55:48 +0200 Subject: [PATCH 026/176] stub into yml and not conf --- .github/workflows/ci.yml | 4 ++-- conf/test.config | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 42be6cc5..714f3f7e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,9 +42,9 @@ jobs: wget -qO- get.nextflow.io | bash sudo mv nextflow /usr/local/bin/ - - name: Test building pizzly references + - name: Test pizzly run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker \ - --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly --fusionreport \ + --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly --fusionreport -stub \ --build_references --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} diff --git a/conf/test.config b/conf/test.config index 83dba5e8..d8e7bcc4 100644 --- a/conf/test.config +++ b/conf/test.config @@ -21,5 +21,4 @@ params { // Input data input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' - stub = true } From c48c697fa7337f8a5d89f240148d52ca0e68a691 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Thu, 4 Aug 2022 14:01:54 +0200 Subject: [PATCH 027/176] fix prefix absence in stub --- modules/local/pizzly/detect/main.nf | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/local/pizzly/detect/main.nf b/modules/local/pizzly/detect/main.nf index f5e4b6e5..ebcf6a8f 100644 --- a/modules/local/pizzly/detect/main.nf +++ b/modules/local/pizzly/detect/main.nf @@ -36,6 +36,7 @@ process PIZZLY { """ stub: + def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.pizzly.txt touch ${prefix}.pizzly.unfiltered.json From d479eca725b169af84c7b15bdd9b1b91d4775cd6 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Thu, 4 Aug 2022 14:12:40 +0200 Subject: [PATCH 028/176] AWS test without fusioninspector as fusioninspector needs starfusion references --- conf/test_build.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/test_build.config b/conf/test_build.config index a0b51273..82742169 100644 --- a/conf/test_build.config +++ b/conf/test_build.config @@ -21,6 +21,6 @@ params { build_references = true arriba = true - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' - + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' + skip_vis = true } From 9385b434610fbce57f4f76a543f6320152c119a5 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Thu, 4 Aug 2022 14:37:47 +0200 Subject: [PATCH 029/176] no build+run workflow needed in awsfulltest any more --- .github/workflows/awsfulltest.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index df978319..148230b7 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -31,16 +31,3 @@ jobs: process.errorStrategy = 'retry' process.maxRetries = 3 profiles: test_full_build,aws_tower - - 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/rnafusion/work-${{ github.sha }} - parameters: | - { - "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", - "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references" - } - profiles: test_full,aws_tower From a5ef47a346bb1dacecd006cdfa22da334bd45765 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Thu, 4 Aug 2022 14:39:17 +0200 Subject: [PATCH 030/176] fix profile position --- .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 148230b7..b12bafc8 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -27,7 +27,7 @@ jobs: "cosmic_username": "${{ secrets.cosmic_username }}", "cosmic_passwd": "${{ secrets.cosmic_passwd }}" } + profiles: test_full_build,aws_tower nextflow_config: | process.errorStrategy = 'retry' process.maxRetries = 3 - profiles: test_full_build,aws_tower From 23766512810aba0f5245174ecd9d3893d3f566b9 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 9 Aug 2022 11:42:47 +0200 Subject: [PATCH 031/176] add stringtie modules --- modules.json | 6 ++ .../nf-core/modules/stringtie/merge/main.nf | 34 +++++++++++ .../nf-core/modules/stringtie/merge/meta.yml | 37 ++++++++++++ .../modules/stringtie/stringtie/main.nf | 51 +++++++++++++++++ .../modules/stringtie/stringtie/meta.yml | 57 +++++++++++++++++++ 5 files changed, 185 insertions(+) create mode 100644 modules/nf-core/modules/stringtie/merge/main.nf create mode 100644 modules/nf-core/modules/stringtie/merge/meta.yml create mode 100644 modules/nf-core/modules/stringtie/stringtie/main.nf create mode 100644 modules/nf-core/modules/stringtie/stringtie/meta.yml diff --git a/modules.json b/modules.json index cc6c8178..3b98b357 100644 --- a/modules.json +++ b/modules.json @@ -47,6 +47,12 @@ }, "star/genomegenerate": { "git_sha": "fb6c7bca3d55c19a793372513395e3a567bdd7ba" + }, + "stringtie/merge": { + "git_sha": "6d88f2da8cc5d586456e801b535cc4213e0fa2f7" + }, + "stringtie/stringtie": { + "git_sha": "6d88f2da8cc5d586456e801b535cc4213e0fa2f7" } } } diff --git a/modules/nf-core/modules/stringtie/merge/main.nf b/modules/nf-core/modules/stringtie/merge/main.nf new file mode 100644 index 00000000..c8460c94 --- /dev/null +++ b/modules/nf-core/modules/stringtie/merge/main.nf @@ -0,0 +1,34 @@ +process STRINGTIE_MERGE { + label 'process_medium' + + // Note: 2.7X indices incompatible with AWS iGenomes. + conda (params.enable_conda ? "bioconda::stringtie=2.2.1" : null) + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/stringtie:2.2.1--hecb563c_2' : + 'quay.io/biocontainers/stringtie:2.2.1--hecb563c_2' }" + + input: + path stringtie_gtf + path annotation_gtf + + output: + path "stringtie.merged.gtf", emit: gtf + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + """ + stringtie \\ + --merge $stringtie_gtf \\ + -G $annotation_gtf \\ + -o stringtie.merged.gtf + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + stringtie: \$(stringtie --version 2>&1) + END_VERSIONS + """ +} diff --git a/modules/nf-core/modules/stringtie/merge/meta.yml b/modules/nf-core/modules/stringtie/merge/meta.yml new file mode 100644 index 00000000..df66696f --- /dev/null +++ b/modules/nf-core/modules/stringtie/merge/meta.yml @@ -0,0 +1,37 @@ +name: stringtie_merge +description: Merges the annotation gtf file and the stringtie output gtf files +keywords: + - merge + - gtf + - reference +tools: + - stringtie2: + description: | + Transcript assembly and quantification for RNA-Seq + homepage: https://ccb.jhu.edu/software/stringtie/index.shtml + documentation: https://ccb.jhu.edu/software/stringtie/index.shtml?t=manual + licence: ["MIT"] +input: + - stringtie_gtf: + type: file + description: | + Stringtie transcript gtf output(s). + pattern: "*.gtf" + - annotation_gtf: + type: file + description: | + Annotation gtf file. + pattern: "*.gtf" +output: + - merged_gtf: + type: map + description: | + Merged gtf from annotation and stringtie output gtfs. + pattern: "*.gtf" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + +authors: + - "@yuukiiwa" diff --git a/modules/nf-core/modules/stringtie/stringtie/main.nf b/modules/nf-core/modules/stringtie/stringtie/main.nf new file mode 100644 index 00000000..c70c9819 --- /dev/null +++ b/modules/nf-core/modules/stringtie/stringtie/main.nf @@ -0,0 +1,51 @@ +process STRINGTIE_STRINGTIE { + tag "$meta.id" + label 'process_medium' + + conda (params.enable_conda ? "bioconda::stringtie=2.2.1" : null) + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/stringtie:2.2.1--hecb563c_2' : + 'quay.io/biocontainers/stringtie:2.2.1--hecb563c_2' }" + + input: + tuple val(meta), path(bam) + path gtf + + output: + tuple val(meta), path("*.coverage.gtf") , emit: coverage_gtf + tuple val(meta), path("*.transcripts.gtf"), emit: transcript_gtf + tuple val(meta), path("*.abundance.txt") , emit: abundance + tuple val(meta), path("*.ballgown") , emit: ballgown + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + + def strandedness = '' + if (meta.strandedness == 'forward') { + strandedness = '--fr' + } else if (meta.strandedness == 'reverse') { + strandedness = '--rf' + } + """ + stringtie \\ + $bam \\ + $strandedness \\ + -G $gtf \\ + -o ${prefix}.transcripts.gtf \\ + -A ${prefix}.gene.abundance.txt \\ + -C ${prefix}.coverage.gtf \\ + -b ${prefix}.ballgown \\ + -p $task.cpus \\ + $args + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + stringtie: \$(stringtie --version 2>&1) + END_VERSIONS + """ +} diff --git a/modules/nf-core/modules/stringtie/stringtie/meta.yml b/modules/nf-core/modules/stringtie/stringtie/meta.yml new file mode 100644 index 00000000..0dda84d0 --- /dev/null +++ b/modules/nf-core/modules/stringtie/stringtie/meta.yml @@ -0,0 +1,57 @@ +name: stringtie_stringtie +description: Transcript assembly and quantification for RNA-Se +keywords: + - transcript + - assembly + - quantification + - gtf + +tools: + - stringtie2: + description: | + Transcript assembly and quantification for RNA-Seq + homepage: https://ccb.jhu.edu/software/stringtie/index.shtml + documentation: https://ccb.jhu.edu/software/stringtie/index.shtml?t=manual + licence: ["MIT"] +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: | + Stringtie transcript gtf output(s). + - gtf: + type: file + description: | + Annotation gtf file. +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - transcript_gtf: + type: file + description: transcript gtf + pattern: "*.{transcripts.gtf}" + - coverage_gtf: + type: file + description: coverage gtf + pattern: "*.{coverage.gtf}" + - abudance: + type: file + description: abudance + pattern: "*.{abudance.txt}" + - ballgown: + type: file + description: for running ballgown + pattern: "*.{ballgown}" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" +authors: + - "@drpatelh" From 06f986ad4e422bda8f33d7210347424db21d54d2 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 9 Aug 2022 11:44:32 +0200 Subject: [PATCH 032/176] publish dir of stringtie merge with sample id --- conf/modules.config | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/conf/modules.config b/conf/modules.config index 07bf44f8..bea3a805 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -304,4 +304,12 @@ process { saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] } + + withName: STRINGTIE_MERGE { + publishDir = [ + path: { "${params.outdir}/stringtie/${meta.id}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } } From 377546fee08916665b046bcd89cc115023720a12 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 9 Aug 2022 11:46:12 +0200 Subject: [PATCH 033/176] add parameter to trigger stringtie analysis --- nextflow.config | 1 + nextflow_schema.json | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/nextflow.config b/nextflow.config index 50d68c39..562d113c 100644 --- a/nextflow.config +++ b/nextflow.config @@ -49,6 +49,7 @@ params { squid = false starindex = false starfusion = false + stringtie = false fusionreport = false fusioninspector_only = false diff --git a/nextflow_schema.json b/nextflow_schema.json index 36977579..3f0d712d 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -224,6 +224,11 @@ "fa_icon": "far fa-file-code", "description": "Path to starindex references" }, + "stringtie": { + "type": "boolean", + "fa_icon": "far fa-file-code", + "description": "Run stringtie analysis" + }, "cosmic_username": { "type": "string", "fa_icon": "far fa-file-code", From c3830b63de544542e00d5391c991533f6722bd76 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 9 Aug 2022 11:46:47 +0200 Subject: [PATCH 034/176] run starfusion if stringtie parameter is set to true --- subworkflows/local/starfusion_workflow.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/local/starfusion_workflow.nf b/subworkflows/local/starfusion_workflow.nf index 5f4e4a16..20f4de92 100644 --- a/subworkflows/local/starfusion_workflow.nf +++ b/subworkflows/local/starfusion_workflow.nf @@ -13,7 +13,7 @@ workflow STARFUSION_WORKFLOW { ch_align = Channel.empty() ch_dummy_file = file("$baseDir/assets/dummy_file_starfusion.txt", checkIfExists: true) - if ((params.starfusion || params.all) && !params.fusioninspector_only) { + if ((params.starfusion || params.all || params.stringtie) && !params.fusioninspector_only) { if (params.starfusion_fusions){ ch_starfusion_fusions = GET_META(reads, params.starfusion_fusions) } else { From b9792ec037f7c865e03e0a44a6214f6bfb9e99ec Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 9 Aug 2022 11:47:15 +0200 Subject: [PATCH 035/176] add stringtie workflow --- subworkflows/local/stringtie_workflow.nf | 34 ++++++++++++++++++++++++ workflows/rnafusion.nf | 9 +++++++ 2 files changed, 43 insertions(+) create mode 100644 subworkflows/local/stringtie_workflow.nf diff --git a/subworkflows/local/stringtie_workflow.nf b/subworkflows/local/stringtie_workflow.nf new file mode 100644 index 00000000..cfe2202a --- /dev/null +++ b/subworkflows/local/stringtie_workflow.nf @@ -0,0 +1,34 @@ +include { STRINGTIE_STRINGTIE } from '../../modules/nf-core/modules/stringtie/stringtie/main' +include { STRINGTIE_MERGE } from '../../modules/nf-core/modules/stringtie/merge/main' + + +workflow STRINGTIE_WORKFLOW { + take: + bam_sorted + ch_chrgtf + + main: + ch_versions = Channel.empty() + ch_stringtie_gtf = Channel.empty() + + if ((params.stringtie || params.all) && !params.fusioninspector_only) { + STRINGTIE_STRINGTIE(bam_sorted, ch_chrgtf) + ch_versions = ch_versions.mix(STRINGTIE_STRINGTIE.out.versions) + + STRINGTIE_STRINGTIE + .out + .transcript_gtf + .map { it -> it[1] } + .set { stringtie_gtf } + + STRINGTIE_MERGE ( stringtie_gtf, ch_chrgtf ) + ch_versions = ch_versions.mix(STRINGTIE_MERGE.out.versions) + ch_stringtie_gtf = STRINGTIE_MERGE.out.gtf + } + + emit: + stringtie_gtf = ch_stringtie_gtf.ifEmpty(null) + versions = ch_versions.ifEmpty(null) + + } + diff --git a/workflows/rnafusion.nf b/workflows/rnafusion.nf index ad7c6a41..e837942f 100644 --- a/workflows/rnafusion.nf +++ b/workflows/rnafusion.nf @@ -67,6 +67,7 @@ include { PIZZLY_WORKFLOW } from '../subworkflows/local/pizzly_w include { QC_WORKFLOW } from '../subworkflows/local/qc_workflow' include { SQUID_WORKFLOW } from '../subworkflows/local/squid_workflow' include { STARFUSION_WORKFLOW } from '../subworkflows/local/starfusion_workflow' +include { STRINGTIE_WORKFLOW } from '../subworkflows/local/stringtie_workflow' include { FUSIONCATCHER_WORKFLOW } from '../subworkflows/local/fusioncatcher_workflow' include { FUSIONINSPECTOR_WORKFLOW } from '../subworkflows/local/fusioninspector_workflow' include { FUSIONREPORT_WORKFLOW } from '../subworkflows/local/fusionreport_workflow' @@ -191,6 +192,14 @@ workflow RNAFUSION { ch_versions = ch_versions.mix(FUSIONCATCHER_WORKFLOW.out.versions.first().ifEmpty(null)) +//Run stringtie + STRINGTIE_WORKFLOW ( + STARFUSION_WORKFLOW.out.bam_sorted, + ch_chrgtf + ) + ch_versions = ch_versions.mix(STRINGTIE_WORKFLOW.out.versions.first().ifEmpty(null)) + + //Run fusion-report FUSIONREPORT_WORKFLOW ( ch_cat_fastq, From e7a7e71833dc23f3ed874fbd418b1227137cb64d Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 10 Aug 2022 10:44:46 +0200 Subject: [PATCH 036/176] update modules --- modules.json | 16 +++++----- modules/nf-core/modules/cat/fastq/main.nf | 29 +++++++++++++++++++ .../custom/dumpsoftwareversions/main.nf | 6 ++-- .../nf-core/modules/kallisto/index/main.nf | 10 +++++++ .../modules/picard/collectwgsmetrics/main.nf | 13 ++++++++- .../nf-core/modules/qualimap/rnaseq/main.nf | 13 ++++++++- .../nf-core/modules/samtools/faidx/main.nf | 1 + modules/nf-core/modules/star/align/main.nf | 24 +++++++++++++++ .../modules/star/genomegenerate/main.nf | 28 ++++++++++++++++++ 9 files changed, 127 insertions(+), 13 deletions(-) diff --git a/modules.json b/modules.json index cc6c8178..4410a3cb 100644 --- a/modules.json +++ b/modules.json @@ -7,31 +7,31 @@ "git_sha": "80746895e214a4d55570f90554164b19476f4114" }, "cat/fastq": { - "git_sha": "9aadd9a6d3f5964476582319b3a1c54a3e3fe7c9" + "git_sha": "b034029b59b1198075da8019074bc02051a6100e" }, "custom/dumpsoftwareversions": { - "git_sha": "682f789f93070bd047868300dd018faf3d434e7c" + "git_sha": "e5b44499efcf6f7fb24874886bac60591c5d94dd" }, "fastqc": { "git_sha": "49b18b1639f4f7104187058866a8fab33332bdfe" }, "kallisto/index": { - "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" + "git_sha": "479e0638d14a3e9e9dd96a5b74b3b5682e8a8b43" }, "multiqc": { "git_sha": "5138acca0985ca01c38a1c4fba917d83772b1106" }, "picard/collectwgsmetrics": { - "git_sha": "682f789f93070bd047868300dd018faf3d434e7c" + "git_sha": "ac1c6ad7104c7863842a322a8cf74f4fee1d20b4" }, "picard/markduplicates": { "git_sha": "682f789f93070bd047868300dd018faf3d434e7c" }, "qualimap/rnaseq": { - "git_sha": "e20e57f90b6787ac9a010a980cf6ea98bd990046" + "git_sha": "53108b6b51d4e968e5b1cc9b07ddb6559cb6d43d" }, "samtools/faidx": { - "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773" + "git_sha": "ce06694af8ca2f7453206aa974c2c9a2b99ec093" }, "samtools/index": { "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773" @@ -43,10 +43,10 @@ "git_sha": "6b64f9cb6c3dd3577931cc3cd032d6fb730000ce" }, "star/align": { - "git_sha": "fb6c7bca3d55c19a793372513395e3a567bdd7ba" + "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba" }, "star/genomegenerate": { - "git_sha": "fb6c7bca3d55c19a793372513395e3a567bdd7ba" + "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba" } } } diff --git a/modules/nf-core/modules/cat/fastq/main.nf b/modules/nf-core/modules/cat/fastq/main.nf index b6854895..d275f19c 100644 --- a/modules/nf-core/modules/cat/fastq/main.nf +++ b/modules/nf-core/modules/cat/fastq/main.nf @@ -48,4 +48,33 @@ process CAT_FASTQ { """ } } + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + def readList = reads.collect{ it.toString() } + if (meta.single_end) { + if (readList.size > 1) { + """ + touch ${prefix}.merged.fastq.gz + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + cat: \$(echo \$(cat --version 2>&1) | sed 's/^.*coreutils) //; s/ .*\$//') + END_VERSIONS + """ + } + } else { + if (readList.size > 2) { + """ + touch ${prefix}_1.merged.fastq.gz + touch ${prefix}_2.merged.fastq.gz + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + cat: \$(echo \$(cat --version 2>&1) | sed 's/^.*coreutils) //; s/ .*\$//') + END_VERSIONS + """ + } + } + } diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf b/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf index 12293efc..203e485a 100644 --- a/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf +++ b/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf @@ -2,10 +2,10 @@ process CUSTOM_DUMPSOFTWAREVERSIONS { label 'process_low' // Requires `pyyaml` which does not have a dedicated container but is in the MultiQC container - conda (params.enable_conda ? "bioconda::multiqc=1.12" : null) + conda (params.enable_conda ? 'bioconda::multiqc=1.13a' : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.12--pyhdfd78af_0' : - 'quay.io/biocontainers/multiqc:1.12--pyhdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/multiqc:1.13a--pyhdfd78af_1' : + 'quay.io/biocontainers/multiqc:1.13a--pyhdfd78af_1' }" input: path versions diff --git a/modules/nf-core/modules/kallisto/index/main.nf b/modules/nf-core/modules/kallisto/index/main.nf index 0f10e564..8b25b7e2 100644 --- a/modules/nf-core/modules/kallisto/index/main.nf +++ b/modules/nf-core/modules/kallisto/index/main.nf @@ -31,4 +31,14 @@ process KALLISTO_INDEX { kallisto: \$(echo \$(kallisto 2>&1) | sed 's/^kallisto //; s/Usage.*\$//') END_VERSIONS """ + + stub: + """ + touch kallisto + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + kallisto: \$(echo \$(kallisto 2>&1) | sed 's/^kallisto //; s/Usage.*\$//') + END_VERSIONS + """ } diff --git a/modules/nf-core/modules/picard/collectwgsmetrics/main.nf b/modules/nf-core/modules/picard/collectwgsmetrics/main.nf index d3153eed..2b0aeefe 100644 --- a/modules/nf-core/modules/picard/collectwgsmetrics/main.nf +++ b/modules/nf-core/modules/picard/collectwgsmetrics/main.nf @@ -2,7 +2,7 @@ process PICARD_COLLECTWGSMETRICS { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::picard=2.27.4" : null) + conda (params.enable_conda ? "bioconda::picard=2.27.4 r::r-base" : null) 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' }" @@ -37,6 +37,17 @@ process PICARD_COLLECTWGSMETRICS { --REFERENCE_SEQUENCE ${fasta} + cat <<-END_VERSIONS > versions.yml + "${task.process}": + picard: \$(picard CollectWgsMetrics --version 2>&1 | grep -o 'Version.*' | cut -f2- -d:) + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.CollectWgsMetrics.coverage_metrics + cat <<-END_VERSIONS > versions.yml "${task.process}": picard: \$(picard CollectWgsMetrics --version 2>&1 | grep -o 'Version.*' | cut -f2- -d:) diff --git a/modules/nf-core/modules/qualimap/rnaseq/main.nf b/modules/nf-core/modules/qualimap/rnaseq/main.nf index 3b2f88ad..bd4503b2 100644 --- a/modules/nf-core/modules/qualimap/rnaseq/main.nf +++ b/modules/nf-core/modules/qualimap/rnaseq/main.nf @@ -20,7 +20,7 @@ process QUALIMAP_RNASEQ { script: def args = task.ext.args ?: '' - prefix = task.ext.prefix ?: "${meta.id}" + def prefix = task.ext.prefix ?: "${meta.id}" def paired_end = meta.single_end ? '' : '-pe' def memory = task.memory.toGiga() + "G" @@ -49,4 +49,15 @@ process QUALIMAP_RNASEQ { qualimap: \$(echo \$(qualimap 2>&1) | sed 's/^.*QualiMap v.//; s/Built.*\$//') END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + mkdir ${prefix} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + qualimap: \$(echo \$(qualimap 2>&1) | sed 's/^.*QualiMap v.//; s/Built.*\$//') + END_VERSIONS + """ } diff --git a/modules/nf-core/modules/samtools/faidx/main.nf b/modules/nf-core/modules/samtools/faidx/main.nf index fdce7d9b..11e688b3 100644 --- a/modules/nf-core/modules/samtools/faidx/main.nf +++ b/modules/nf-core/modules/samtools/faidx/main.nf @@ -22,6 +22,7 @@ process SAMTOOLS_FAIDX { """ samtools \\ faidx \\ + $args \\ $fasta cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/modules/star/align/main.nf b/modules/nf-core/modules/star/align/main.nf index e5aa36f5..47c58eb0 100644 --- a/modules/nf-core/modules/star/align/main.nf +++ b/modules/nf-core/modules/star/align/main.nf @@ -70,4 +70,28 @@ process STAR_ALIGN { gawk: \$(echo \$(gawk --version 2>&1) | sed 's/^.*GNU Awk //; s/, .*\$//') END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}Xd.out.bam + touch ${prefix}.Log.final.out + touch ${prefix}.Log.out + touch ${prefix}.Log.progress.out + touch ${prefix}.sortedByCoord.out.bam + touch ${prefix}.toTranscriptome.out.bam + touch ${prefix}.Aligned.unsort.out.bam + touch ${prefix}.unmapped_1.fastq.gz + touch ${prefix}.unmapped_2.fastq.gz + touch ${prefix}.tab + touch ${prefix}.Chimeric.out.junction + touch ${prefix}.out.sam + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + star: \$(STAR --version | sed -e "s/STAR_//g") + samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') + gawk: \$(echo \$(gawk --version 2>&1) | sed 's/^.*GNU Awk //; s/, .*\$//') + END_VERSIONS + """ } diff --git a/modules/nf-core/modules/star/genomegenerate/main.nf b/modules/nf-core/modules/star/genomegenerate/main.nf index 3c298016..6ec634a1 100644 --- a/modules/nf-core/modules/star/genomegenerate/main.nf +++ b/modules/nf-core/modules/star/genomegenerate/main.nf @@ -65,4 +65,32 @@ process STAR_GENOMEGENERATE { END_VERSIONS """ } + + stub: + """ + mkdir star + touch star/Genome + touch star/Log.out + touch star/SA + touch star/SAindex + touch star/chrLength.txt + touch star/chrName.txt + touch star/chrNameLength.txt + touch star/chrStart.txt + touch star/exonGeTrInfo.tab + touch star/exonInfo.tab + touch star/geneInfo.tab + touch star/genomeParameters.txt + touch star/sjdbInfo.txt + touch star/sjdbList.fromGTF.out.tab + touch star/sjdbList.out.tab + touch star/transcriptInfo.tab + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + star: \$(STAR --version | sed -e "s/STAR_//g") + samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') + gawk: \$(echo \$(gawk --version 2>&1) | sed 's/^.*GNU Awk //; s/, .*\$//') + END_VERSIONS + """ } From e52a00132f5ac686c19e792c6753ad5c0724811a Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 10 Aug 2022 11:23:28 +0200 Subject: [PATCH 037/176] update changelog --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ef2ce97..692dd244 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +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). +## [2.2.0dev] nfcore/rnafusion + +### Added + +### Changed + +- multiQC updated to 1.13a in process dumpsoftwareversion +- Updated nf-core and local modules with stub options + +### Fixed + +### Removed + ## [2.1.0] nfcore/rnafusion - 2022/07/12 ### Added From 88fff3c3ad780fd4384a18bd5de1baf247c849b9 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 15 Aug 2022 15:17:05 +0200 Subject: [PATCH 038/176] update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80e45033..a5f7fefc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- `stringtie` v2.2.1 added to detect splicing events. Not included in `fusion-report` or `fusionInspector` summaries + ### Changed ### Fixed From 5fd8971857984e4c7aba331cce2669b6b25dc7ba Mon Sep 17 00:00:00 2001 From: Z_Wael Date: Wed, 17 Aug 2022 15:34:13 +0200 Subject: [PATCH 039/176] Update usage.md correcting some typo in the "--fusioninspector_only" workflow command --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index 51aa908c..593b45a7 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -129,7 +129,7 @@ FusionInspector can be run standalone with: ```bash nextflow run nf-core/rnafusion \ --fusioninspector_only \ - --fusioninspector_fusion + --fusioninspector_fusions \ --input \ --outdir ``` From 008f862a1d00ce2c76605ed81846520d08fb621e Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Fri, 19 Aug 2022 16:14:36 +0200 Subject: [PATCH 040/176] use patched fusion-report version that fixes mitelman --- modules/local/fusionreport/detect/main.nf | 4 ++-- modules/local/fusionreport/download/main.nf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/local/fusionreport/detect/main.nf b/modules/local/fusionreport/detect/main.nf index c1c77452..f76d180e 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/local/fusionreport/detect/main.nf @@ -5,8 +5,8 @@ process FUSIONREPORT { // Note: 2.7X indices incompatible with AWS iGenomes. conda (params.enable_conda ? 'bioconda::star=2.7.9a' : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/rannickscilifelab/fusion-report:2.1.5updated' : - 'docker.io/rannickscilifelab/fusion-report:2.1.5updated' }" + 'docker.io/rannickscilifelab/fusion-report:2.1.5patched' : + 'docker.io/rannickscilifelab/fusion-report:2.1.5patched' }" input: diff --git a/modules/local/fusionreport/download/main.nf b/modules/local/fusionreport/download/main.nf index 415a8b36..439d6e6b 100644 --- a/modules/local/fusionreport/download/main.nf +++ b/modules/local/fusionreport/download/main.nf @@ -5,8 +5,8 @@ process FUSIONREPORT_DOWNLOAD { // Note: 2.7X indices incompatible with AWS iGenomes. conda (params.enable_conda ? 'bioconda::star=2.7.9a' : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/rannickscilifelab/fusion-report:2.1.5updated' : - 'docker.io/rannickscilifelab/fusion-report:2.1.5updated' }" + 'docker.io/rannickscilifelab/fusion-report:2.1.5patched' : + 'docker.io/rannickscilifelab/fusion-report:2.1.5patched' }" input: From 1043318732134c5cb7c4650681ba619179da8663 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 30 Aug 2022 10:04:17 +0200 Subject: [PATCH 041/176] use clinical genomics fork for docker image of fusion-report --- modules/local/fusionreport/detect/main.nf | 4 ++-- modules/local/fusionreport/download/main.nf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/local/fusionreport/detect/main.nf b/modules/local/fusionreport/detect/main.nf index f76d180e..da795696 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/local/fusionreport/detect/main.nf @@ -5,8 +5,8 @@ process FUSIONREPORT { // Note: 2.7X indices incompatible with AWS iGenomes. conda (params.enable_conda ? 'bioconda::star=2.7.9a' : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/rannickscilifelab/fusion-report:2.1.5patched' : - 'docker.io/rannickscilifelab/fusion-report:2.1.5patched' }" + 'docker.io/clinicalgenomics/fusion-report:2.1.5patched' : + 'docker.io/clinicalgenomics/fusion-report:2.1.5patched' }" input: diff --git a/modules/local/fusionreport/download/main.nf b/modules/local/fusionreport/download/main.nf index 439d6e6b..166f0f3e 100644 --- a/modules/local/fusionreport/download/main.nf +++ b/modules/local/fusionreport/download/main.nf @@ -5,8 +5,8 @@ process FUSIONREPORT_DOWNLOAD { // Note: 2.7X indices incompatible with AWS iGenomes. conda (params.enable_conda ? 'bioconda::star=2.7.9a' : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/rannickscilifelab/fusion-report:2.1.5patched' : - 'docker.io/rannickscilifelab/fusion-report:2.1.5patched' }" + 'docker.io/clinicalgenomics/fusion-report:2.1.5patched' : + 'docker.io/clinicalgenomics/fusion-report:2.1.5patched' }" input: From 3c11b5873cdf72fec2517ee5156c7c6bdb392dd0 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 30 Aug 2022 10:14:44 +0200 Subject: [PATCH 042/176] add DB retrieval date to versions.yml --- modules/local/fusionreport/detect/main.nf | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/local/fusionreport/detect/main.nf b/modules/local/fusionreport/detect/main.nf index da795696..9cafa4a3 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/local/fusionreport/detect/main.nf @@ -38,6 +38,7 @@ process FUSIONREPORT { cat <<-END_VERSIONS > versions.yml "${task.process}": fusion_report: \$(fusion_report --version | sed 's/fusion-report //') + fusion_report DB retrieval: \$(cat $fusionreport_ref/DB-timestamp.txt) END_VERSIONS """ } From c58e05a0af5a755c2a2b605095a00b3866e6edd1 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Tue, 30 Aug 2022 13:36:08 +0000 Subject: [PATCH 043/176] Template update for nf-core/tools version 2.5 --- .editorconfig | 2 +- .github/PULL_REQUEST_TEMPLATE.md | 3 +- .github/workflows/ci.yml | 23 ++------ .github/workflows/linting.yml | 38 +++++++++++-- CHANGELOG.md | 2 +- CITATION.cff | 56 +++++++++++++++++++ LICENSE | 2 +- README.md | 23 +++----- assets/email_template.txt | 1 - bin/check_samplesheet.py | 41 +++++++------- conf/base.config | 5 ++ docs/usage.md | 12 ++-- lib/WorkflowMain.groovy | 9 ++- lib/WorkflowRnafusion.groovy | 5 +- main.nf | 2 +- modules.json | 22 +++++--- .../templates/dumpsoftwareversions.py | 14 +++-- nextflow.config | 25 ++++++++- 18 files changed, 189 insertions(+), 96 deletions(-) create mode 100644 CITATION.cff diff --git a/.editorconfig b/.editorconfig index b6b31907..b78de6e6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,7 +8,7 @@ trim_trailing_whitespace = true indent_size = 4 indent_style = space -[*.{md,yml,yaml,html,css,scss,js}] +[*.{md,yml,yaml,html,css,scss,js,cff}] indent_size = 2 # These files are edited and tested upstream in nf-core/modules diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index bc52a0a2..6f604f38 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -15,8 +15,7 @@ Learn more about contributing: [CONTRIBUTING.md](https://github.com/nf-core/rnaf - [ ] This comment contains a description of changes (with reason). - [ ] If you've fixed a bug or added code that should be tested, add tests! - - [ ] If you've added a new tool - have you followed the pipeline conventions in the [contribution docs](https://github.com/nf-core/rnafusion/tree/master/.github/CONTRIBUTING.md) - - [ ] If necessary, also make a PR on the nf-core/rnafusion _branch_ on the [nf-core/test-datasets](https://github.com/nf-core/test-datasets) repository. +- [ ] If you've added a new tool - have you followed the pipeline conventions in the [contribution docs](https://github.com/nf-core/rnafusion/tree/master/.github/CONTRIBUTING.md)- [ ] If necessary, also make a PR on the nf-core/rnafusion _branch_ on the [nf-core/test-datasets](https://github.com/nf-core/test-datasets) repository. - [ ] Make sure your code lints (`nf-core lint`). - [ ] Ensure the test suite passes (`nextflow run . -profile test,docker --outdir `). - [ ] Usage Documentation in `docs/usage.md` is updated. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f54bb8b7..4e611505 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,6 @@ on: env: NXF_ANSI_LOG: false - CAPSULE_LOG: none jobs: test: @@ -20,27 +19,17 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - # Nextflow versions - include: - # Test pipeline minimum Nextflow version - - NXF_VER: "21.10.3" - NXF_EDGE: "" - # Test latest edge release of Nextflow - - NXF_VER: "" - NXF_EDGE: "1" + NXF_VER: + - "21.10.3" + - "latest-everything" steps: - name: Check out pipeline code uses: actions/checkout@v2 - name: Install Nextflow - env: - NXF_VER: ${{ matrix.NXF_VER }} - # Uncomment only if the edge release is more recent than the latest stable release - # See https://github.com/nextflow-io/nextflow/issues/2467 - # NXF_EDGE: ${{ matrix.NXF_EDGE }} - run: | - wget -qO- get.nextflow.io | bash - sudo mv nextflow /usr/local/bin/ + uses: nf-core/setup-nextflow@v1 + with: + version: "${{ matrix.NXF_VER }}" - name: Run pipeline with test data # TODO nf-core: You can customise CI pipeline run tests as required diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 77358dee..8a5ce69b 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -35,6 +35,36 @@ jobs: - name: Run Prettier --check run: prettier --check ${GITHUB_WORKSPACE} + PythonBlack: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Check code lints with Black + uses: psf/black@stable + + # If the above check failed, post a comment on the PR explaining the failure + - name: Post PR comment + if: failure() + uses: mshick/add-pr-comment@v1 + with: + message: | + ## Python linting (`black`) is failing + + To keep the code consistent with lots of contributors, we run automated code consistency checks. + To fix this CI test, please run: + + * Install [`black`](https://black.readthedocs.io/en/stable/): `pip install black` + * Fix formatting errors in your pipeline: `black .` + + Once you push these changes the test should pass, and you can hide this comment :+1: + + We highly recommend setting up Black in your code editor so that this formatting is done automatically on save. Ask about it on Slack for help! + + Thanks again for your contribution! + repo-token: ${{ secrets.GITHUB_TOKEN }} + allow-repeats: false + nf-core: runs-on: ubuntu-latest steps: @@ -42,15 +72,11 @@ jobs: uses: actions/checkout@v2 - name: Install Nextflow - env: - CAPSULE_LOG: none - run: | - wget -qO- get.nextflow.io | bash - sudo mv nextflow /usr/local/bin/ + uses: nf-core/setup-nextflow@v1 - uses: actions/setup-python@v3 with: - python-version: "3.6" + python-version: "3.7" architecture: "x64" - name: Install dependencies diff --git a/CHANGELOG.md b/CHANGELOG.md index b104b216..5bb898b7 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). -## v2.0.0dev - [date] +## v2.2.0dev - [date] Initial release of nf-core/rnafusion, created with the [nf-core](https://nf-co.re/) template. diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 00000000..4533e2f2 --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,56 @@ +cff-version: 1.2.0 +message: "If you use `nf-core tools` in your work, please cite the `nf-core` publication" +authors: + - family-names: Ewels + given-names: Philip + - family-names: Peltzer + given-names: Alexander + - family-names: Fillinger + given-names: Sven + - family-names: Patel + given-names: Harshil + - family-names: Alneberg + given-names: Johannes + - family-names: Wilm + given-names: Andreas + - family-names: Ulysse Garcia + given-names: Maxime + - family-names: Di Tommaso + given-names: Paolo + - family-names: Nahnsen + given-names: Sven +title: "The nf-core framework for community-curated bioinformatics pipelines." +version: 2.4.1 +doi: 10.1038/s41587-020-0439-x +date-released: 2022-05-16 +url: https://github.com/nf-core/tools +prefered-citation: + type: article + authors: + - family-names: Ewels + given-names: Philip + - family-names: Peltzer + given-names: Alexander + - family-names: Fillinger + given-names: Sven + - family-names: Patel + given-names: Harshil + - family-names: Alneberg + given-names: Johannes + - family-names: Wilm + given-names: Andreas + - family-names: Ulysse Garcia + given-names: Maxime + - family-names: Di Tommaso + given-names: Paolo + - family-names: Nahnsen + given-names: Sven + doi: 10.1038/s41587-020-0439-x + journal: nature biotechnology + start: 276 + end: 278 + title: "The nf-core framework for community-curated bioinformatics pipelines." + issue: 3 + volume: 38 + year: 2020 + url: https://dx.doi.org/10.1038/s41587-020-0439-x diff --git a/LICENSE b/LICENSE index 8a50c49d..86e71fe1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) Martin Proks, @praveenraj2018 +Copyright (c) Martin Proks, Annick Renevey Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 733c34e9..979d1dc5 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,14 @@ # ![nf-core/rnafusion](docs/images/nf-core-rnafusion_logo_light.png#gh-light-mode-only) ![nf-core/rnafusion](docs/images/nf-core-rnafusion_logo_dark.png#gh-dark-mode-only) -[![GitHub Actions CI Status](https://github.com/nf-core/rnafusion/workflows/nf-core%20CI/badge.svg)](https://github.com/nf-core/rnafusion/actions?query=workflow%3A%22nf-core+CI%22) -[![GitHub Actions Linting Status](https://github.com/nf-core/rnafusion/workflows/nf-core%20linting/badge.svg)](https://github.com/nf-core/rnafusion/actions?query=workflow%3A%22nf-core+linting%22) -[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?logo=Amazon%20AWS)](https://nf-co.re/rnafusion/results) -[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8)](https://doi.org/10.5281/zenodo.XXXXXXX) +[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/rnafusion/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX) [![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A521.10.3-23aa62.svg)](https://www.nextflow.io/) -[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?logo=anaconda)](https://docs.conda.io/en/latest/) -[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?logo=docker)](https://www.docker.com/) -[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg)](https://sylabs.io/docs/) +[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/) +[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/) +[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/) [![Launch on Nextflow Tower](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Nextflow%20Tower-%234256e7)](https://tower.nf/launch?pipeline=https://github.com/nf-core/rnafusion) -[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23rnafusion-4A154B?logo=slack)](https://nfcore.slack.com/channels/rnafusion) -[![Follow on Twitter](http://img.shields.io/badge/twitter-%40nf__core-1DA1F2?logo=twitter)](https://twitter.com/nf_core) -[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?logo=youtube)](https://www.youtube.com/c/nf-core) +[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23rnafusion-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/rnafusion)[![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 @@ -25,7 +20,7 @@ The pipeline is built using [Nextflow](https://www.nextflow.io), a workflow tool -On release, automated continuous integration tests run the pipeline on a full-sized dataset 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 the full-sized test can be viewed on the [nf-core website](https://nf-co.re/rnafusion/results). +On release, automated continuous integration tests run the pipeline on a full-sized dataset 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 the full-sized test can be viewed on the [nf-core website](https://nf-co.re/rnafusion/results). ## Pipeline summary @@ -42,7 +37,7 @@ On release, automated continuous integration tests run the pipeline on a full-si 3. Download the pipeline and test it on a minimal dataset with a single command: - ```console + ```bash nextflow run nf-core/rnafusion -profile test,YOURPROFILE --outdir ``` @@ -57,7 +52,7 @@ On release, automated continuous integration tests run the pipeline on a full-si - ```console + ```bash nextflow run nf-core/rnafusion --input samplesheet.csv --outdir --genome GRCh37 -profile ``` @@ -67,7 +62,7 @@ The nf-core/rnafusion pipeline comes with documentation about the pipeline [usag ## Credits -nf-core/rnafusion was originally written by Martin Proks, @praveenraj2018. +nf-core/rnafusion was originally written by Martin Proks, Annick Renevey. We thank the following people for their extensive assistance in the development of this pipeline: diff --git a/assets/email_template.txt b/assets/email_template.txt index f717ee9f..e1cabd80 100644 --- a/assets/email_template.txt +++ b/assets/email_template.txt @@ -6,7 +6,6 @@ `._,._,' nf-core/rnafusion v${version} ---------------------------------------------------- - Run Name: $runName <% if (success){ diff --git a/bin/check_samplesheet.py b/bin/check_samplesheet.py index 3652c63c..9a8b8962 100755 --- a/bin/check_samplesheet.py +++ b/bin/check_samplesheet.py @@ -11,7 +11,6 @@ from collections import Counter from pathlib import Path - logger = logging.getLogger() @@ -79,13 +78,15 @@ def validate_and_transform(self, row): def _validate_sample(self, row): """Assert that the sample name exists and convert spaces to underscores.""" - assert len(row[self._sample_col]) > 0, "Sample input is required." + if len(row[self._sample_col]) <= 0: + raise AssertionError("Sample input is required.") # Sanitize samples slightly. row[self._sample_col] = row[self._sample_col].replace(" ", "_") def _validate_first(self, row): """Assert that the first FASTQ entry is non-empty and has the right format.""" - assert len(row[self._first_col]) > 0, "At least the first FASTQ file is required." + if len(row[self._first_col]) <= 0: + raise AssertionError("At least the first FASTQ file is required.") self._validate_fastq_format(row[self._first_col]) def _validate_second(self, row): @@ -97,36 +98,34 @@ def _validate_pair(self, row): """Assert that read pairs have the same file extension. Report pair status.""" if row[self._first_col] and row[self._second_col]: row[self._single_col] = False - assert ( - Path(row[self._first_col]).suffixes[-2:] == Path(row[self._second_col]).suffixes[-2:] - ), "FASTQ pairs must have the same file extensions." + if Path(row[self._first_col]).suffixes[-2:] != Path(row[self._second_col]).suffixes[-2:]: + raise AssertionError("FASTQ pairs must have the same file extensions.") else: row[self._single_col] = True def _validate_fastq_format(self, filename): """Assert that a given filename has one of the expected FASTQ extensions.""" - assert any(filename.endswith(extension) for extension in self.VALID_FORMATS), ( - f"The FASTQ file has an unrecognized extension: {filename}\n" - f"It should be one of: {', '.join(self.VALID_FORMATS)}" - ) + if not any(filename.endswith(extension) for extension in self.VALID_FORMATS): + raise AssertionError( + f"The FASTQ file has an unrecognized extension: {filename}\n" + f"It should be one of: {', '.join(self.VALID_FORMATS)}" + ) def validate_unique_samples(self): """ Assert that the combination of sample name and FASTQ filename is unique. - In addition to the validation, also rename the sample if more than one sample, - FASTQ file combination exists. + In addition to the validation, also rename all samples to have a suffix of _T{n}, where n is the + number of times the same sample exist, but with different FASTQ files, e.g., multiple runs per experiment. """ - assert len(self._seen) == len(self.modified), "The pair of sample name and FASTQ must be unique." - if len({pair[0] for pair in self._seen}) < len(self._seen): - counts = Counter(pair[0] for pair in self._seen) - seen = Counter() - for row in self.modified: - sample = row[self._sample_col] - seen[sample] += 1 - if counts[sample] > 1: - row[self._sample_col] = f"{sample}_T{seen[sample]}" + if len(self._seen) != len(self.modified): + raise AssertionError("The pair of sample name and FASTQ must be unique.") + seen = Counter() + for row in self.modified: + sample = row[self._sample_col] + seen[sample] += 1 + row[self._sample_col] = f"{sample}_T{seen[sample]}" def read_head(handle, num_lines=10): diff --git a/conf/base.config b/conf/base.config index 906b4d28..d9c546a1 100644 --- a/conf/base.config +++ b/conf/base.config @@ -26,6 +26,11 @@ process { // adding in your local modules too. // TODO nf-core: Customise requirements for specific processes. // See https://www.nextflow.io/docs/latest/config.html#config-process-selectors + withLabel:process_single { + cpus = { check_max( 1 , 'cpus' ) } + memory = { check_max( 6.GB * task.attempt, 'memory' ) } + time = { check_max( 4.h * task.attempt, 'time' ) } + } withLabel:process_low { cpus = { check_max( 2 * task.attempt, 'cpus' ) } memory = { check_max( 12.GB * task.attempt, 'memory' ) } diff --git a/docs/usage.md b/docs/usage.md index f398e3b4..04a7c6b7 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -12,7 +12,7 @@ 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 3 columns, and a header row as shown in the examples below. -```console +```bash --input '[path to samplesheet file]' ``` @@ -56,7 +56,7 @@ An [example samplesheet](../assets/samplesheet.csv) has been provided with the p The typical command for running the pipeline is as follows: -```console +```bash nextflow run nf-core/rnafusion --input samplesheet.csv --outdir --genome GRCh37 -profile docker ``` @@ -64,9 +64,9 @@ This will launch the pipeline with the `docker` configuration profile. See below Note that the pipeline will create the following files in your working directory: -```console +```bash work # Directory containing the nextflow working files - # Finished results in specified location (defined with --outdir) + # Finished results in specified location (defined with --outdir) .nextflow_log # Log file from Nextflow # Other nextflow hidden files, eg. history of pipeline runs and old logs. ``` @@ -75,7 +75,7 @@ work # Directory containing the nextflow working files When you run the above command, Nextflow automatically pulls the pipeline code from GitHub and stores it as a cached version. When running the pipeline after this, it will always use the cached version if available - even if the pipeline has been updated since. To make sure that you're running the latest version of the pipeline, make sure that you regularly update the cached version of the pipeline: -```console +```bash nextflow pull nf-core/rnafusion ``` @@ -251,6 +251,6 @@ Some HPC setups also allow you to run nextflow within a cluster job submitted yo In some cases, the Nextflow Java virtual machines can start to request a large amount of memory. We recommend adding the following line to your environment to limit this (typically in `~/.bashrc` or `~./bash_profile`): -```console +```bash NXF_OPTS='-Xms1g -Xmx4g' ``` diff --git a/lib/WorkflowMain.groovy b/lib/WorkflowMain.groovy index 6f431e59..014fdc9e 100755 --- a/lib/WorkflowMain.groovy +++ b/lib/WorkflowMain.groovy @@ -59,6 +59,7 @@ class WorkflowMain { } // Print parameter summary log to screen + log.info paramsSummaryLog(workflow, params, log) // Check that a -profile or Nextflow config has been provided to run the pipeline @@ -78,17 +79,15 @@ class WorkflowMain { System.exit(1) } } - // // Get attribute from genome config file e.g. fasta // - public static String getGenomeAttribute(params, attribute) { - def val = '' + public static Object getGenomeAttribute(params, attribute) { if (params.genomes && params.genome && params.genomes.containsKey(params.genome)) { if (params.genomes[ params.genome ].containsKey(attribute)) { - val = params.genomes[ params.genome ][ attribute ] + return params.genomes[ params.genome ][ attribute ] } } - return val + return null } } diff --git a/lib/WorkflowRnafusion.groovy b/lib/WorkflowRnafusion.groovy index 74705064..5692372c 100755 --- a/lib/WorkflowRnafusion.groovy +++ b/lib/WorkflowRnafusion.groovy @@ -10,6 +10,7 @@ class WorkflowRnafusion { public static void initialise(params, log) { genomeExistsError(params, log) + 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) @@ -41,9 +42,7 @@ class WorkflowRnafusion { yaml_file_text += "data: |\n" yaml_file_text += "${summary_section}" return yaml_file_text - } - - // + }// // Exit pipeline if incorrect --genome key provided // private static void genomeExistsError(params, log) { diff --git a/main.nf b/main.nf index b2c34856..42199120 100644 --- a/main.nf +++ b/main.nf @@ -4,7 +4,7 @@ nf-core/rnafusion ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Github : https://github.com/nf-core/rnafusion - Website: https://nf-co.re/rnafusion +Website: https://nf-co.re/rnafusion Slack : https://nfcore.slack.com/channels/rnafusion ---------------------------------------------------------------------------------------- */ diff --git a/modules.json b/modules.json index a7159f29..6342963d 100644 --- a/modules.json +++ b/modules.json @@ -3,14 +3,20 @@ "homePage": "https://github.com/nf-core/rnafusion", "repos": { "nf-core/modules": { - "custom/dumpsoftwareversions": { - "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" - }, - "fastqc": { - "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" - }, - "multiqc": { - "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d" + "git_url": "https://github.com/nf-core/modules.git", + "modules": { + "custom/dumpsoftwareversions": { + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d", + "branch": "master" + }, + "fastqc": { + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d", + "branch": "master" + }, + "multiqc": { + "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d", + "branch": "master" + } } } } diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py b/modules/nf-core/modules/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py index d1390392..787bdb7b 100644 --- a/modules/nf-core/modules/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py +++ b/modules/nf-core/modules/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py @@ -1,9 +1,10 @@ #!/usr/bin/env python -import yaml import platform from textwrap import dedent +import yaml + def _make_versions_html(versions): html = [ @@ -58,11 +59,12 @@ def _make_versions_html(versions): for process, process_versions in versions_by_process.items(): module = process.split(":")[-1] try: - assert versions_by_module[module] == process_versions, ( - "We assume that software versions are the same between all modules. " - "If you see this error-message it means you discovered an edge-case " - "and should open an issue in nf-core/tools. " - ) + if versions_by_module[module] != process_versions: + raise AssertionError( + "We assume that software versions are the same between all modules. " + "If you see this error-message it means you discovered an edge-case " + "and should open an issue in nf-core/tools. " + ) except KeyError: versions_by_module[module] = process_versions diff --git a/nextflow.config b/nextflow.config index 86dd3752..10d15673 100644 --- a/nextflow.config +++ b/nextflow.config @@ -13,11 +13,11 @@ params { // Input options input = null + // References genome = null igenomes_base = 's3://ngi-igenomes/igenomes' igenomes_ignore = false - // MultiQC options multiqc_config = null multiqc_title = null @@ -37,6 +37,7 @@ params { schema_ignore_params = 'genomes' enable_conda = false + // Config options custom_config_version = 'master' custom_config_base = "https://raw.githubusercontent.com/nf-core/configs/${params.custom_config_version}" @@ -45,6 +46,7 @@ params { config_profile_url = null config_profile_name = null + // Max resource options // Defaults only, expecting to be overwritten max_memory = '128.GB' @@ -72,6 +74,7 @@ try { // } + profiles { debug { process.beforeScript = 'echo $HOSTNAME' } conda { @@ -82,6 +85,15 @@ profiles { shifter.enabled = false charliecloud.enabled = false } + mamba { + params.enable_conda = true + conda.useMamba = true + docker.enabled = false + singularity.enabled = false + podman.enabled = false + shifter.enabled = false + charliecloud.enabled = false + } docker { docker.enabled = true docker.userEmulation = true @@ -119,10 +131,16 @@ profiles { podman.enabled = false shifter.enabled = false } + gitpod { + executor.name = 'local' + executor.cpus = 16 + executor.memory = 60.GB + } test { includeConfig 'conf/test.config' } test_full { includeConfig 'conf/test_full.config' } } + // Load igenomes.config if required if (!params.igenomes_ignore) { includeConfig 'conf/igenomes.config' @@ -130,6 +148,7 @@ if (!params.igenomes_ignore) { params.genomes = [:] } + // Export these variables to prevent local Python/R libraries from conflicting with those in the container // The JULIA depot path has been adjusted to a fixed path `/usr/local/share/julia` that needs to be used for packages in the container. // See https://apeltzer.github.io/post/03-julia-lang-nextflow/ for details on that. Once we have a common agreement on where to keep Julia packages, this is adjustable. @@ -164,12 +183,12 @@ dag { manifest { name = 'nf-core/rnafusion' - author = 'Martin Proks, @praveenraj2018' + author = 'Martin Proks, Annick Renevey' homePage = 'https://github.com/nf-core/rnafusion' description = 'Nextflow rnafusion analysis pipeline, part of the nf-core community.' mainScript = 'main.nf' nextflowVersion = '!>=21.10.3' - version = '2.0.0dev' + version = '2.2.0dev' } // Load modules.config for DSL2 module specific options From 23b54f08c8852044035a1aa857d3e1bfc5964c4a Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 30 Aug 2022 16:31:55 +0200 Subject: [PATCH 044/176] black linting --- bin/check_samplesheet.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/bin/check_samplesheet.py b/bin/check_samplesheet.py index f9d5bac7..d0141b78 100755 --- a/bin/check_samplesheet.py +++ b/bin/check_samplesheet.py @@ -45,7 +45,7 @@ def check_samplesheet(file_in, file_out): """ sample_mapping_dict = {} - with open(file_in, "r", encoding='utf-8-sig') as fin: + with open(file_in, "r", encoding="utf-8-sig") as fin: ## Check header MIN_COLS = 3 @@ -93,7 +93,9 @@ def check_samplesheet(file_in, file_out): if fastq: if fastq.find(" ") != -1: print_error("FastQ file contains spaces!", "Line", line) - if not fastq.endswith(".fastq.gz") and not fastq.endswith(".fq.gz"): + if not fastq.endswith(".fastq.gz") and not fastq.endswith( + ".fq.gz" + ): print_error( "FastQ file does not have extension '.fastq.gz' or '.fq.gz'!", "Line", @@ -123,14 +125,18 @@ def check_samplesheet(file_in, file_out): elif sample and fastq_1 and not fastq_2: ## Single-end short reads sample_info = ["1", fastq_1, fastq_2, strandedness] else: - print_error("Invalid combination of columns provided!", "Line", line) + print_error( + "Invalid combination of columns provided!", "Line", line + ) ## Create sample mapping dictionary = {sample: [[ single_end, fastq_1, fastq_2, strandedness ]]} if sample not in sample_mapping_dict: sample_mapping_dict[sample] = [sample_info] else: if sample_info in sample_mapping_dict[sample]: - print_error("Samplesheet contains duplicate rows!", "Line", line) + print_error( + "Samplesheet contains duplicate rows!", "Line", line + ) else: sample_mapping_dict[sample].append(sample_info) From ca9a600800849c65beebc22dba3e49b01da6c610 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Thu, 1 Sep 2022 13:31:44 +0000 Subject: [PATCH 045/176] Template update for nf-core/tools version 2.5.1 --- bin/check_samplesheet.py | 9 ++++++--- pyproject.toml | 10 ++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 pyproject.toml diff --git a/bin/check_samplesheet.py b/bin/check_samplesheet.py index 9a8b8962..11b15572 100755 --- a/bin/check_samplesheet.py +++ b/bin/check_samplesheet.py @@ -98,7 +98,9 @@ def _validate_pair(self, row): """Assert that read pairs have the same file extension. Report pair status.""" if row[self._first_col] and row[self._second_col]: row[self._single_col] = False - if Path(row[self._first_col]).suffixes[-2:] != Path(row[self._second_col]).suffixes[-2:]: + first_col_suffix = Path(row[self._first_col]).suffixes[-2:] + second_col_suffix = Path(row[self._second_col]).suffixes[-2:] + if first_col_suffix != second_col_suffix: raise AssertionError("FASTQ pairs must have the same file extensions.") else: row[self._single_col] = True @@ -157,7 +159,7 @@ def sniff_format(handle): handle.seek(0) sniffer = csv.Sniffer() if not sniffer.has_header(peek): - logger.critical(f"The given sample sheet does not appear to contain a header.") + logger.critical("The given sample sheet does not appear to contain a header.") sys.exit(1) dialect = sniffer.sniff(peek) return dialect @@ -195,7 +197,8 @@ def check_samplesheet(file_in, file_out): reader = csv.DictReader(in_handle, dialect=sniff_format(in_handle)) # Validate the existence of the expected header columns. if not required_columns.issubset(reader.fieldnames): - logger.critical(f"The sample sheet **must** contain the column headers: {', '.join(required_columns)}.") + req_cols = ", ".join(required_columns) + logger.critical(f"The sample sheet **must** contain these column headers: {req_cols}.") sys.exit(1) # Validate each row. checker = RowChecker() diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..0d62beb6 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,10 @@ +# Config file for Python. Mostly used to configure linting of bin/check_samplesheet.py with Black. +# Should be kept the same as nf-core/tools to avoid fighting with template synchronisation. +[tool.black] +line-length = 120 +target_version = ["py37", "py38", "py39", "py310"] + +[tool.isort] +profile = "black" +known_first_party = ["nf_core"] +multi_line_output = 3 From e705feadaf12d9752e4c1eafa52761b913daacc0 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Fri, 2 Sep 2022 10:37:44 +0200 Subject: [PATCH 046/176] prettier and black linting --- README.md | 7 ++-- bin/check_samplesheet.py | 14 ++----- modules.json | 88 ++++++++++++++++++++-------------------- 3 files changed, 51 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 25e3d64b..cc445df9 100644 --- a/README.md +++ b/README.md @@ -110,9 +110,10 @@ In rnafusion the full-sized test includes reference building and fusion detectio nextflow run nf-core/rnafusion --input samplesheet.csv --outdir --genome GRCh38 --all -profile ``` - ```bash - nextflow run nf-core/rnafusion --input samplesheet.csv --outdir --genome GRCh37 -profile - ``` +```bash +nextflow run nf-core/rnafusion --input samplesheet.csv --outdir --genome GRCh37 -profile +``` + > Note that paths need to be absolute and that runs with conda are not supported. ## Documentation diff --git a/bin/check_samplesheet.py b/bin/check_samplesheet.py index d7be795b..c3060ef9 100755 --- a/bin/check_samplesheet.py +++ b/bin/check_samplesheet.py @@ -105,10 +105,7 @@ def _validate_pair(self, row): """Assert that read pairs have the same file extension. Report pair status.""" if row[self._first_col] and row[self._second_col]: row[self._single_col] = False - if ( - Path(row[self._first_col]).suffixes[-2:] - != Path(row[self._second_col]).suffixes[-2:] - ): + if Path(row[self._first_col]).suffixes[-2:] != Path(row[self._second_col]).suffixes[-2:]: raise AssertionError("FASTQ pairs must have the same file extensions.") else: row[self._single_col] = True @@ -124,9 +121,7 @@ def _validate_fastq_format(self, filename): def _validate_strandedness(self, row): """Assert that the strandedness given is one of unstranded/forward/reverse""" if row[self._strandedness] not in self.VALID_STRANDEDNESSES: - raise AssertionError( - f"Strandedness must be one of {', '.join(self.VALID_STRANDEDNESSES)}" - ) + raise AssertionError(f"Strandedness must be one of {', '.join(self.VALID_STRANDEDNESSES)}") def validate_unique_samples(self): """ @@ -203,9 +198,7 @@ def check_samplesheet(file_in, file_out): reader = csv.DictReader(in_handle, dialect=sniff_format(in_handle)) # Validate the existence of the expected header columns. if not required_columns.issubset(reader.fieldnames): - logger.critical( - f"The sample sheet **must** contain the column headers: {', '.join(required_columns)}." - ) + logger.critical(f"The sample sheet **must** contain the column headers: {', '.join(required_columns)}.") sys.exit(1) # Validate each row. checker = RowChecker() @@ -267,4 +260,3 @@ def main(argv=None): if __name__ == "__main__": sys.exit(main()) - diff --git a/modules.json b/modules.json index d744a791..6b10c5f9 100644 --- a/modules.json +++ b/modules.json @@ -5,50 +5,50 @@ "nf-core/modules": { "git_url": "https://github.com/nf-core/modules.git", "modules": { - "arriba": { - "git_sha": "80746895e214a4d55570f90554164b19476f4114" - }, - "cat/fastq": { - "git_sha": "b034029b59b1198075da8019074bc02051a6100e" - }, - "custom/dumpsoftwareversions": { - "git_sha": "e5b44499efcf6f7fb24874886bac60591c5d94dd" - }, - "fastqc": { - "git_sha": "49b18b1639f4f7104187058866a8fab33332bdfe" - }, - "kallisto/index": { - "git_sha": "479e0638d14a3e9e9dd96a5b74b3b5682e8a8b43" - }, - "multiqc": { - "git_sha": "5138acca0985ca01c38a1c4fba917d83772b1106" - }, - "picard/collectwgsmetrics": { - "git_sha": "ac1c6ad7104c7863842a322a8cf74f4fee1d20b4" - }, - "picard/markduplicates": { - "git_sha": "682f789f93070bd047868300dd018faf3d434e7c" - }, - "qualimap/rnaseq": { - "git_sha": "53108b6b51d4e968e5b1cc9b07ddb6559cb6d43d" - }, - "samtools/faidx": { - "git_sha": "ce06694af8ca2f7453206aa974c2c9a2b99ec093" - }, - "samtools/index": { - "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773" - }, - "samtools/sort": { - "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773" - }, - "samtools/view": { - "git_sha": "6b64f9cb6c3dd3577931cc3cd032d6fb730000ce" - }, - "star/align": { - "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba" - }, - "star/genomegenerate": { - "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba" + "arriba": { + "git_sha": "80746895e214a4d55570f90554164b19476f4114" + }, + "cat/fastq": { + "git_sha": "b034029b59b1198075da8019074bc02051a6100e" + }, + "custom/dumpsoftwareversions": { + "git_sha": "e5b44499efcf6f7fb24874886bac60591c5d94dd" + }, + "fastqc": { + "git_sha": "49b18b1639f4f7104187058866a8fab33332bdfe" + }, + "kallisto/index": { + "git_sha": "479e0638d14a3e9e9dd96a5b74b3b5682e8a8b43" + }, + "multiqc": { + "git_sha": "5138acca0985ca01c38a1c4fba917d83772b1106" + }, + "picard/collectwgsmetrics": { + "git_sha": "ac1c6ad7104c7863842a322a8cf74f4fee1d20b4" + }, + "picard/markduplicates": { + "git_sha": "682f789f93070bd047868300dd018faf3d434e7c" + }, + "qualimap/rnaseq": { + "git_sha": "53108b6b51d4e968e5b1cc9b07ddb6559cb6d43d" + }, + "samtools/faidx": { + "git_sha": "ce06694af8ca2f7453206aa974c2c9a2b99ec093" + }, + "samtools/index": { + "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773" + }, + "samtools/sort": { + "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773" + }, + "samtools/view": { + "git_sha": "6b64f9cb6c3dd3577931cc3cd032d6fb730000ce" + }, + "star/align": { + "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba" + }, + "star/genomegenerate": { + "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba" } } } From 4c1913e1e64a57aceed3d755e951a47082397c79 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Fri, 2 Sep 2022 10:50:07 +0200 Subject: [PATCH 047/176] add branch master to modules.json --- modules.json | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/modules.json b/modules.json index 6b10c5f9..6c9dafbd 100644 --- a/modules.json +++ b/modules.json @@ -6,49 +6,64 @@ "git_url": "https://github.com/nf-core/modules.git", "modules": { "arriba": { - "git_sha": "80746895e214a4d55570f90554164b19476f4114" + "git_sha": "80746895e214a4d55570f90554164b19476f4114", + "branch": "master" }, "cat/fastq": { - "git_sha": "b034029b59b1198075da8019074bc02051a6100e" + "git_sha": "b034029b59b1198075da8019074bc02051a6100e", + "branch": "master" }, "custom/dumpsoftwareversions": { - "git_sha": "e5b44499efcf6f7fb24874886bac60591c5d94dd" + "git_sha": "e5b44499efcf6f7fb24874886bac60591c5d94dd", + "branch": "master" }, "fastqc": { - "git_sha": "49b18b1639f4f7104187058866a8fab33332bdfe" + "git_sha": "49b18b1639f4f7104187058866a8fab33332bdfe", + "branch": "master" }, "kallisto/index": { - "git_sha": "479e0638d14a3e9e9dd96a5b74b3b5682e8a8b43" + "git_sha": "479e0638d14a3e9e9dd96a5b74b3b5682e8a8b43", + "branch": "master" }, "multiqc": { - "git_sha": "5138acca0985ca01c38a1c4fba917d83772b1106" + "git_sha": "5138acca0985ca01c38a1c4fba917d83772b1106", + "branch": "master" }, "picard/collectwgsmetrics": { - "git_sha": "ac1c6ad7104c7863842a322a8cf74f4fee1d20b4" + "git_sha": "ac1c6ad7104c7863842a322a8cf74f4fee1d20b4", + "branch": "master" }, "picard/markduplicates": { - "git_sha": "682f789f93070bd047868300dd018faf3d434e7c" + "git_sha": "682f789f93070bd047868300dd018faf3d434e7c", + "branch": "master" }, "qualimap/rnaseq": { - "git_sha": "53108b6b51d4e968e5b1cc9b07ddb6559cb6d43d" + "git_sha": "53108b6b51d4e968e5b1cc9b07ddb6559cb6d43d", + "branch": "master" }, "samtools/faidx": { - "git_sha": "ce06694af8ca2f7453206aa974c2c9a2b99ec093" + "git_sha": "ce06694af8ca2f7453206aa974c2c9a2b99ec093", + "branch": "master" }, "samtools/index": { - "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773" + "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773", + "branch": "master" }, "samtools/sort": { "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773" + "branch": "master" }, "samtools/view": { "git_sha": "6b64f9cb6c3dd3577931cc3cd032d6fb730000ce" + "branch": "master" }, "star/align": { "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba" + "branch": "master" }, "star/genomegenerate": { - "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba" + "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba", + "branch": "master" } } } From ca9ebc83c99827d3ba9cff11c0a490c84e4bede7 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Fri, 2 Sep 2022 10:55:27 +0200 Subject: [PATCH 048/176] fix typo --- modules.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules.json b/modules.json index 6c9dafbd..8f3d1a0d 100644 --- a/modules.json +++ b/modules.json @@ -50,15 +50,15 @@ "branch": "master" }, "samtools/sort": { - "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773" + "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773", "branch": "master" }, "samtools/view": { - "git_sha": "6b64f9cb6c3dd3577931cc3cd032d6fb730000ce" + "git_sha": "6b64f9cb6c3dd3577931cc3cd032d6fb730000ce", "branch": "master" }, "star/align": { - "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba" + "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba", "branch": "master" }, "star/genomegenerate": { From ebe2626e74c1cc9e2e7a9e9cce0e452428bd52da Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Fri, 2 Sep 2022 11:23:27 +0200 Subject: [PATCH 049/176] fix linting --- modules.json | 60 +++++++++++++++--------------- modules/local/samplesheet_check.nf | 4 ++ nextflow_schema.json | 15 ++++++++ 3 files changed, 49 insertions(+), 30 deletions(-) diff --git a/modules.json b/modules.json index 8f3d1a0d..d68356da 100644 --- a/modules.json +++ b/modules.json @@ -6,64 +6,64 @@ "git_url": "https://github.com/nf-core/modules.git", "modules": { "arriba": { - "git_sha": "80746895e214a4d55570f90554164b19476f4114", - "branch": "master" + "branch": "master", + "git_sha": "80746895e214a4d55570f90554164b19476f4114" }, "cat/fastq": { - "git_sha": "b034029b59b1198075da8019074bc02051a6100e", - "branch": "master" + "branch": "master", + "git_sha": "b034029b59b1198075da8019074bc02051a6100e" }, "custom/dumpsoftwareversions": { - "git_sha": "e5b44499efcf6f7fb24874886bac60591c5d94dd", - "branch": "master" + "branch": "master", + "git_sha": "e5b44499efcf6f7fb24874886bac60591c5d94dd" }, "fastqc": { - "git_sha": "49b18b1639f4f7104187058866a8fab33332bdfe", - "branch": "master" + "branch": "master", + "git_sha": "49b18b1639f4f7104187058866a8fab33332bdfe" }, "kallisto/index": { - "git_sha": "479e0638d14a3e9e9dd96a5b74b3b5682e8a8b43", - "branch": "master" + "branch": "master", + "git_sha": "479e0638d14a3e9e9dd96a5b74b3b5682e8a8b43" }, "multiqc": { - "git_sha": "5138acca0985ca01c38a1c4fba917d83772b1106", - "branch": "master" + "branch": "master", + "git_sha": "5138acca0985ca01c38a1c4fba917d83772b1106" }, "picard/collectwgsmetrics": { - "git_sha": "ac1c6ad7104c7863842a322a8cf74f4fee1d20b4", - "branch": "master" + "branch": "master", + "git_sha": "ac1c6ad7104c7863842a322a8cf74f4fee1d20b4" }, "picard/markduplicates": { - "git_sha": "682f789f93070bd047868300dd018faf3d434e7c", - "branch": "master" + "branch": "master", + "git_sha": "682f789f93070bd047868300dd018faf3d434e7c" }, "qualimap/rnaseq": { - "git_sha": "53108b6b51d4e968e5b1cc9b07ddb6559cb6d43d", - "branch": "master" + "branch": "master", + "git_sha": "53108b6b51d4e968e5b1cc9b07ddb6559cb6d43d" }, "samtools/faidx": { - "git_sha": "ce06694af8ca2f7453206aa974c2c9a2b99ec093", - "branch": "master" + "branch": "master", + "git_sha": "ce06694af8ca2f7453206aa974c2c9a2b99ec093" }, "samtools/index": { - "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773", - "branch": "master" + "branch": "master", + "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773" }, "samtools/sort": { - "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773", - "branch": "master" + "branch": "master", + "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773" }, "samtools/view": { - "git_sha": "6b64f9cb6c3dd3577931cc3cd032d6fb730000ce", - "branch": "master" + "branch": "master", + "git_sha": "6b64f9cb6c3dd3577931cc3cd032d6fb730000ce" }, "star/align": { - "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba", - "branch": "master" + "branch": "master", + "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba" }, "star/genomegenerate": { - "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba", - "branch": "master" + "branch": "master", + "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba" } } } diff --git a/modules/local/samplesheet_check.nf b/modules/local/samplesheet_check.nf index fe14e2ee..e8737886 100644 --- a/modules/local/samplesheet_check.nf +++ b/modules/local/samplesheet_check.nf @@ -1,5 +1,6 @@ process SAMPLESHEET_CHECK { tag "$samplesheet" + label 'process_low' conda (params.enable_conda ? "conda-forge::python=3.8.3" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { @@ -15,6 +16,9 @@ process SAMPLESHEET_CHECK { path '*.csv' , emit: csv path "versions.yml", emit: versions + when: + task.ext.when == null || task.ext.when + script: // This script is bundled with the pipeline, in nf-core/rnafusion/bin/ """ check_samplesheet.py \\ diff --git a/nextflow_schema.json b/nextflow_schema.json index 36977579..352f0e5f 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -270,6 +270,21 @@ "help_text": "This parameter is *mandatory* if `--genome` is not specified. If you don't have a BWA index available this will be generated for you automatically. Combine with `--save_reference` to save BWA index for future runs.", "fa_icon": "far fa-file-code" }, + "igenomes_base": { + "type": "string", + "format": "directory-path", + "description": "Directory / URL base for iGenomes references.", + "default": "s3://ngi-igenomes/igenomes", + "fa_icon": "fas fa-cloud-download-alt", + "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`." + }, "gtf": { "type": "string", "format": "file-path", From e9ab9b68e0193c46711a203d26af72649dc39a0a Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Fri, 2 Sep 2022 11:28:24 +0200 Subject: [PATCH 050/176] update check_samplesheet script to 2.5.1 template --- bin/check_samplesheet.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/bin/check_samplesheet.py b/bin/check_samplesheet.py index c3060ef9..da160e68 100755 --- a/bin/check_samplesheet.py +++ b/bin/check_samplesheet.py @@ -105,7 +105,9 @@ def _validate_pair(self, row): """Assert that read pairs have the same file extension. Report pair status.""" if row[self._first_col] and row[self._second_col]: row[self._single_col] = False - if Path(row[self._first_col]).suffixes[-2:] != Path(row[self._second_col]).suffixes[-2:]: + first_col_suffix = Path(row[self._first_col]).suffixes[-2:] + second_col_suffix = Path(row[self._second_col]).suffixes[-2:] + if first_col_suffix != second_col_suffix: raise AssertionError("FASTQ pairs must have the same file extensions.") else: row[self._single_col] = True @@ -165,7 +167,7 @@ def sniff_format(handle): handle.seek(0) sniffer = csv.Sniffer() if not sniffer.has_header(peek): - logger.critical(f"The given sample sheet does not appear to contain a header.") + logger.critical("The given sample sheet does not appear to contain a header.") sys.exit(1) dialect = sniffer.sniff(peek) return dialect @@ -198,7 +200,8 @@ def check_samplesheet(file_in, file_out): reader = csv.DictReader(in_handle, dialect=sniff_format(in_handle)) # Validate the existence of the expected header columns. if not required_columns.issubset(reader.fieldnames): - logger.critical(f"The sample sheet **must** contain the column headers: {', '.join(required_columns)}.") + req_cols = ", ".join(required_columns) + logger.critical(f"The sample sheet **must** contain these column headers: {req_cols}.") sys.exit(1) # Validate each row. checker = RowChecker() From cca657f748f4b9843cde457f0db9b9d23ad7d2ce Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 5 Sep 2022 10:57:45 +0200 Subject: [PATCH 051/176] load genomes.conf after igenomes so the correct genome path for rnafusion are loaded --- nextflow.config | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/nextflow.config b/nextflow.config index 8f553988..effae9c6 100644 --- a/nextflow.config +++ b/nextflow.config @@ -19,8 +19,8 @@ params { // References genome = null igenomes_base = 's3://ngi-igenomes/igenomes' - igenomes_ignore = false - + igenomes_ignore = true + // MultiQC options multiqc_config = null multiqc_title = null @@ -116,6 +116,13 @@ params { max_time = '240.h' } +// Load igenomes.config if required +if (!params.igenomes_ignore) { + includeConfig 'conf/igenomes.config' +} else { + params.genomes = [:] +} + // Load base.config by default for all pipelines includeConfig 'conf/base.config' @@ -202,15 +209,6 @@ profiles { test_full { includeConfig 'conf/test_full.config' } } - -// Load igenomes.config if required -if (!params.igenomes_ignore) { - includeConfig 'conf/igenomes.config' -} else { - params.genomes = [:] -} - - // Export these variables to prevent local Python/R libraries from conflicting with those in the container // The JULIA depot path has been adjusted to a fixed path `/usr/local/share/julia` that needs to be used for packages in the container. // See https://apeltzer.github.io/post/03-julia-lang-nextflow/ for details on that. Once we have a common agreement on where to keep Julia packages, this is adjustable. From 751fff9cf10f17318d7caf9dd57f1efcef8359fe Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 5 Sep 2022 11:06:34 +0200 Subject: [PATCH 052/176] fix problem with fusioninspector refs not present for ci test --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a2fb0948..bb7391c5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,5 +41,5 @@ jobs: - name: Test running pizzly references run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker \ - --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly \ - --genomes_base /home/runner/work/rnafusion/rnafusion/results/references -stub + --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly --skip_vis \ + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references From 642b494f40603f7942808a1bb7a05afee40a0fc6 Mon Sep 17 00:00:00 2001 From: Simon Pearce <24893913+SPPearce@users.noreply.github.com> Date: Mon, 5 Sep 2022 10:45:57 +0100 Subject: [PATCH 053/176] Update usage.md Change typo "nf-nore" to nf-core (took me an embarrassingly long time to spot this was the issue when copying the code). --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index 51aa908c..7044dae0 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -65,7 +65,7 @@ references/ If process `FUSIONREPORT_DOWNLOAD` times out, it could be due to network restriction (e.g. if trying to run on HPC). As this process is lightweight in compute, storage and time, it is recommended to run on local machines with: ```bash -nextflow run nf-nore/rnafusion \ +nextflow run nf-core/rnafusion \ --build_references \ --cosmic_username --cosmic_passwd \ --fusionreport \ From 5f862c024a9de00fd0a66e7df04cc43dd0ac78c0 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 14 Sep 2022 10:47:08 +0200 Subject: [PATCH 054/176] Update changelok --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f161457..189a6d26 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 - multiQC updated to 1.13a in process dumpsoftwareversion - Updated nf-core and local modules with stub options +- Patch fusion-report version with fixed mittelman DB and DB extraction date written into software_version.yaml ### Fixed From df50ea350b6bd2c771c3ed90bdf8e4218b2e16c3 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Tue, 4 Oct 2022 22:03:22 +0000 Subject: [PATCH 055/176] Template update for nf-core/tools version 2.6 --- .github/workflows/awsfulltest.yml | 4 ++ .github/workflows/awstest.yml | 4 ++ .prettierignore | 1 + CITATION.cff | 8 +-- assets/adaptivecard.json | 67 +++++++++++++++++++ assets/methods_description_template.yml | 25 +++++++ assets/multiqc_config.yml | 6 +- docs/usage.md | 8 +++ lib/NfcoreTemplate.groovy | 55 +++++++++++++++ lib/Utils.groovy | 21 ++++-- lib/WorkflowRnafusion.groovy | 19 ++++++ main.nf | 3 +- modules.json | 27 ++++---- .../custom/dumpsoftwareversions/main.nf | 8 +-- .../custom/dumpsoftwareversions/meta.yml | 0 .../templates/dumpsoftwareversions.py | 0 modules/nf-core/{modules => }/fastqc/main.nf | 12 ++++ modules/nf-core/{modules => }/fastqc/meta.yml | 0 modules/nf-core/modules/multiqc/main.nf | 31 --------- modules/nf-core/multiqc/main.nf | 53 +++++++++++++++ .../nf-core/{modules => }/multiqc/meta.yml | 15 +++++ nextflow.config | 5 +- nextflow_schema.json | 18 +++++ workflows/rnafusion.nf | 26 ++++--- 24 files changed, 345 insertions(+), 71 deletions(-) create mode 100644 assets/adaptivecard.json create mode 100644 assets/methods_description_template.yml mode change 100755 => 100644 lib/Utils.groovy rename modules/nf-core/{modules => }/custom/dumpsoftwareversions/main.nf (79%) rename modules/nf-core/{modules => }/custom/dumpsoftwareversions/meta.yml (100%) rename modules/nf-core/{modules => }/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py (100%) rename modules/nf-core/{modules => }/fastqc/main.nf (85%) rename modules/nf-core/{modules => }/fastqc/meta.yml (100%) delete mode 100644 modules/nf-core/modules/multiqc/main.nf create mode 100644 modules/nf-core/multiqc/main.nf rename modules/nf-core/{modules => }/multiqc/meta.yml (73%) diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index c0a06786..a2fbe1e2 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -28,3 +28,7 @@ jobs: "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}" } 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 index 5a04305d..14762177 100644 --- a/.github/workflows/awstest.yml +++ b/.github/workflows/awstest.yml @@ -23,3 +23,7 @@ jobs: "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/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/.prettierignore b/.prettierignore index d0e7ae58..eb74a574 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,5 @@ email_template.html +adaptivecard.json .nextflow* work/ data/ diff --git a/CITATION.cff b/CITATION.cff index 4533e2f2..017666c0 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -13,8 +13,8 @@ authors: given-names: Johannes - family-names: Wilm given-names: Andreas - - family-names: Ulysse Garcia - given-names: Maxime + - family-names: Garcia + given-names: Maxime Ulysse - family-names: Di Tommaso given-names: Paolo - family-names: Nahnsen @@ -39,8 +39,8 @@ prefered-citation: given-names: Johannes - family-names: Wilm given-names: Andreas - - family-names: Ulysse Garcia - given-names: Maxime + - family-names: Garcia + given-names: Maxime Ulysse - family-names: Di Tommaso given-names: Paolo - family-names: Nahnsen diff --git a/assets/adaptivecard.json b/assets/adaptivecard.json new file mode 100644 index 00000000..3ae96b42 --- /dev/null +++ b/assets/adaptivecard.json @@ -0,0 +1,67 @@ +{ + "type": "message", + "attachments": [ + { + "contentType": "application/vnd.microsoft.card.adaptive", + "contentUrl": null, + "content": { + "\$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "msteams": { + "width": "Full" + }, + "type": "AdaptiveCard", + "version": "1.2", + "body": [ + { + "type": "TextBlock", + "size": "Large", + "weight": "Bolder", + "color": "<% if (success) { %>Good<% } else { %>Attention<%} %>", + "text": "nf-core/rnafusion v${version} - ${runName}", + "wrap": true + }, + { + "type": "TextBlock", + "spacing": "None", + "text": "Completed at ${dateComplete} (duration: ${duration})", + "isSubtle": true, + "wrap": true + }, + { + "type": "TextBlock", + "text": "<% if (success) { %>Pipeline completed successfully!<% } else { %>Pipeline completed with errors. The full error message was: ${errorReport}.<% } %>", + "wrap": true + }, + { + "type": "TextBlock", + "text": "The command used to launch the workflow was as follows:", + "wrap": true + }, + { + "type": "TextBlock", + "text": "${commandLine}", + "isSubtle": true, + "wrap": true + } + ], + "actions": [ + { + "type": "Action.ShowCard", + "title": "Pipeline Configuration", + "card": { + "type": "AdaptiveCard", + "\$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "body": [ + { + "type": "FactSet", + "facts": [<% out << summary.collect{ k,v -> "{\"title\": \"$k\", \"value\" : \"$v\"}"}.join(",\n") %> + ] + } + ] + } + } + ] + } + } + ] +} diff --git a/assets/methods_description_template.yml b/assets/methods_description_template.yml new file mode 100644 index 00000000..016b3d45 --- /dev/null +++ b/assets/methods_description_template.yml @@ -0,0 +1,25 @@ +id: "nf-core-rnafusion-methods-description" +description: "Suggested text and references to use when describing pipeline usage within the methods section of a publication." +section_name: "nf-core/rnafusion Methods Description" +section_href: "https://github.com/nf-core/rnafusion" +plot_type: "html" +## TODO nf-core: Update the HTML below to your prefered methods description, e.g. add publication citation for this pipeline +## You inject any metadata in the Nextflow '${workflow}' object +data: | +

Methods

+

Data was processed using nf-core/rnafusion v${workflow.manifest.version} ${doi_text} of the nf-core collection of workflows (Ewels et al., 2020).

+

The pipeline was executed with Nextflow v${workflow.nextflow.version} (Di Tommaso et al., 2017) with the following command:

+
${workflow.commandLine}
+

References

+
    +
  • Di Tommaso, P., Chatzou, M., Floden, E. W., Barja, P. P., Palumbo, E., & Notredame, C. (2017). Nextflow enables reproducible computational workflows. Nature Biotechnology, 35(4), 316-319. https://doi.org/10.1038/nbt.3820
  • +
  • Ewels, P. A., Peltzer, A., Fillinger, S., Patel, H., Alneberg, J., Wilm, A., Garcia, M. U., Di Tommaso, P., & Nahnsen, S. (2020). The nf-core framework for community-curated bioinformatics pipelines. Nature Biotechnology, 38(3), 276-278. https://doi.org/10.1038/s41587-020-0439-x
  • +
+
+
Notes:
+
    + ${nodoi_text} +
  • The command above does not include parameters contained in any configs or profiles that may have been used. Ensure the config file is also uploaded with your publication!
  • +
  • You should also cite all software used within this run. Check the "Software Versions" of this report to get version information.
  • +
+
diff --git a/assets/multiqc_config.yml b/assets/multiqc_config.yml index 0ffd3e5e..5c8a20b2 100644 --- a/assets/multiqc_config.yml +++ b/assets/multiqc_config.yml @@ -3,9 +3,11 @@ report_comment: > analysis pipeline. For information about how to interpret these results, please see the documentation. report_section_order: - software_versions: + "nf-core-rnafusion-methods-description": order: -1000 - "nf-core-rnafusion-summary": + software_versions: order: -1001 + "nf-core-rnafusion-summary": + order: -1002 export_plots: true diff --git a/docs/usage.md b/docs/usage.md index 04a7c6b7..8a6d9909 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -237,6 +237,14 @@ See the main [Nextflow documentation](https://www.nextflow.io/docs/latest/config If you have any questions or issues please send us a message on [Slack](https://nf-co.re/join/slack) on the [`#configs` channel](https://nfcore.slack.com/channels/configs). +## Azure Resource Requests + +To be used with the `azurebatch` profile by specifying the `-profile azurebatch`. +We recommend providing a compute `params.vm_type` of `Standard_D16_v3` VMs by default but these options can be changed if required. + +Note that the choice of VM size depends on your quota and the overall workload during the analysis. +For a thorough list, please refer the [Azure Sizes for virtual machines in Azure](https://docs.microsoft.com/en-us/azure/virtual-machines/sizes). + ## Running in the background Nextflow handles job submissions and supervises the running jobs. The Nextflow process must run until the pipeline is finished. diff --git a/lib/NfcoreTemplate.groovy b/lib/NfcoreTemplate.groovy index 2fc0a9b9..27feb009 100755 --- a/lib/NfcoreTemplate.groovy +++ b/lib/NfcoreTemplate.groovy @@ -145,6 +145,61 @@ class NfcoreTemplate { output_tf.withWriter { w -> w << email_txt } } + // + // Construct and send adaptive card + // https://adaptivecards.io + // + public static void adaptivecard(workflow, params, summary_params, projectDir, log) { + def hook_url = params.hook_url + + def summary = [:] + for (group in summary_params.keySet()) { + summary << summary_params[group] + } + + def misc_fields = [:] + misc_fields['start'] = workflow.start + misc_fields['complete'] = workflow.complete + misc_fields['scriptfile'] = workflow.scriptFile + misc_fields['scriptid'] = workflow.scriptId + if (workflow.repository) misc_fields['repository'] = workflow.repository + if (workflow.commitId) misc_fields['commitid'] = workflow.commitId + if (workflow.revision) misc_fields['revision'] = workflow.revision + misc_fields['nxf_version'] = workflow.nextflow.version + misc_fields['nxf_build'] = workflow.nextflow.build + misc_fields['nxf_timestamp'] = workflow.nextflow.timestamp + + def msg_fields = [:] + msg_fields['version'] = workflow.manifest.version + msg_fields['runName'] = workflow.runName + msg_fields['success'] = workflow.success + msg_fields['dateComplete'] = workflow.complete + msg_fields['duration'] = workflow.duration + msg_fields['exitStatus'] = workflow.exitStatus + msg_fields['errorMessage'] = (workflow.errorMessage ?: 'None') + msg_fields['errorReport'] = (workflow.errorReport ?: 'None') + msg_fields['commandLine'] = workflow.commandLine + msg_fields['projectDir'] = workflow.projectDir + msg_fields['summary'] = summary << misc_fields + + // Render the JSON template + def engine = new groovy.text.GStringTemplateEngine() + def hf = new File("$projectDir/assets/adaptivecard.json") + def json_template = engine.createTemplate(hf).make(msg_fields) + def json_message = json_template.toString() + + // POST + def post = new URL(hook_url).openConnection(); + post.setRequestMethod("POST") + post.setDoOutput(true) + post.setRequestProperty("Content-Type", "application/json") + post.getOutputStream().write(json_message.getBytes("UTF-8")); + def postRC = post.getResponseCode(); + if (! postRC.equals(200)) { + log.warn(post.getErrorStream().getText()); + } + } + // // Print pipeline summary on completion // diff --git a/lib/Utils.groovy b/lib/Utils.groovy old mode 100755 new mode 100644 index 28567bd7..8d030f4e --- a/lib/Utils.groovy +++ b/lib/Utils.groovy @@ -21,19 +21,26 @@ class Utils { } // Check that all channels are present - def required_channels = ['conda-forge', 'bioconda', 'defaults'] - def conda_check_failed = !required_channels.every { ch -> ch in channels } + // This channel list is ordered by required channel priority. + def required_channels_in_order = ['conda-forge', 'bioconda', 'defaults'] + def channels_missing = ((required_channels_in_order as Set) - (channels as Set)) as Boolean // Check that they are in the right order - conda_check_failed |= !(channels.indexOf('conda-forge') < channels.indexOf('bioconda')) - conda_check_failed |= !(channels.indexOf('bioconda') < channels.indexOf('defaults')) + def channel_priority_violation = false + def n = required_channels_in_order.size() + for (int i = 0; i < n - 1; i++) { + channel_priority_violation |= !(channels.indexOf(required_channels_in_order[i]) < channels.indexOf(required_channels_in_order[i+1])) + } - if (conda_check_failed) { + if (channels_missing | channel_priority_violation) { log.warn "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " There is a problem with your Conda configuration!\n\n" + " You will need to set-up the conda-forge and bioconda channels correctly.\n" + - " Please refer to https://bioconda.github.io/user/install.html#set-up-channels\n" + - " NB: The order of the channels matters!\n" + + " Please refer to https://bioconda.github.io/\n" + + " The observed channel order is \n" + + " ${channels}\n" + + " but the following channel order is required:\n" + + " ${required_channels_in_order}\n" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" } } diff --git a/lib/WorkflowRnafusion.groovy b/lib/WorkflowRnafusion.groovy index 5692372c..f31abbf7 100755 --- a/lib/WorkflowRnafusion.groovy +++ b/lib/WorkflowRnafusion.groovy @@ -2,6 +2,8 @@ // This file holds several functions specific to the workflow/rnafusion.nf in the nf-core/rnafusion pipeline // +import groovy.text.SimpleTemplateEngine + class WorkflowRnafusion { // @@ -42,6 +44,23 @@ class WorkflowRnafusion { yaml_file_text += "data: |\n" yaml_file_text += "${summary_section}" return yaml_file_text + } + + 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 = [:] + meta.workflow = run_workflow.toMap() + meta["manifest_map"] = run_workflow.manifest.toMap() + + meta["doi_text"] = meta.manifest_map.doi ? "(doi: ${meta.manifest_map.doi})" : "" + meta["nodoi_text"] = meta.manifest_map.doi ? "": "
  • If available, make sure to update the text to include the Zenodo DOI of version of the pipeline used.
  • " + + def methods_text = mqc_methods_yaml.text + + def engine = new SimpleTemplateEngine() + def description_html = engine.createTemplate(methods_text).make(meta) + + return description_html }// // Exit pipeline if incorrect --genome key provided // diff --git a/main.nf b/main.nf index 42199120..8cb0a641 100644 --- a/main.nf +++ b/main.nf @@ -4,7 +4,8 @@ nf-core/rnafusion ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Github : https://github.com/nf-core/rnafusion -Website: https://nf-co.re/rnafusion + + Website: https://nf-co.re/rnafusion Slack : https://nfcore.slack.com/channels/rnafusion ---------------------------------------------------------------------------------------- */ diff --git a/modules.json b/modules.json index 6342963d..c4862659 100644 --- a/modules.json +++ b/modules.json @@ -2,20 +2,21 @@ "name": "nf-core/rnafusion", "homePage": "https://github.com/nf-core/rnafusion", "repos": { - "nf-core/modules": { - "git_url": "https://github.com/nf-core/modules.git", + "https://github.com/nf-core/modules.git": { "modules": { - "custom/dumpsoftwareversions": { - "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d", - "branch": "master" - }, - "fastqc": { - "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d", - "branch": "master" - }, - "multiqc": { - "git_sha": "e745e167c1020928ef20ea1397b6b4d230681b4d", - "branch": "master" + "nf-core": { + "custom/dumpsoftwareversions": { + "branch": "master", + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + }, + "fastqc": { + "branch": "master", + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + }, + "multiqc": { + "branch": "master", + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + } } } } diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf b/modules/nf-core/custom/dumpsoftwareversions/main.nf similarity index 79% rename from modules/nf-core/modules/custom/dumpsoftwareversions/main.nf rename to modules/nf-core/custom/dumpsoftwareversions/main.nf index 327d5100..cebb6e05 100644 --- a/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf +++ b/modules/nf-core/custom/dumpsoftwareversions/main.nf @@ -1,11 +1,11 @@ process CUSTOM_DUMPSOFTWAREVERSIONS { - label 'process_low' + label 'process_single' // Requires `pyyaml` which does not have a dedicated container but is in the MultiQC container - conda (params.enable_conda ? "bioconda::multiqc=1.11" : null) + conda (params.enable_conda ? 'bioconda::multiqc=1.13' : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.11--pyhdfd78af_0' : - 'quay.io/biocontainers/multiqc:1.11--pyhdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/multiqc:1.13--pyhdfd78af_0' : + 'quay.io/biocontainers/multiqc:1.13--pyhdfd78af_0' }" input: path versions diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/meta.yml b/modules/nf-core/custom/dumpsoftwareversions/meta.yml similarity index 100% rename from modules/nf-core/modules/custom/dumpsoftwareversions/meta.yml rename to modules/nf-core/custom/dumpsoftwareversions/meta.yml diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py b/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py similarity index 100% rename from modules/nf-core/modules/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py rename to modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py diff --git a/modules/nf-core/modules/fastqc/main.nf b/modules/nf-core/fastqc/main.nf similarity index 85% rename from modules/nf-core/modules/fastqc/main.nf rename to modules/nf-core/fastqc/main.nf index ed6b8c50..05730368 100644 --- a/modules/nf-core/modules/fastqc/main.nf +++ b/modules/nf-core/fastqc/main.nf @@ -44,4 +44,16 @@ process FASTQC { END_VERSIONS """ } + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.html + touch ${prefix}.zip + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fastqc: \$( fastqc --version | sed -e "s/FastQC v//g" ) + END_VERSIONS + """ } diff --git a/modules/nf-core/modules/fastqc/meta.yml b/modules/nf-core/fastqc/meta.yml similarity index 100% rename from modules/nf-core/modules/fastqc/meta.yml rename to modules/nf-core/fastqc/meta.yml diff --git a/modules/nf-core/modules/multiqc/main.nf b/modules/nf-core/modules/multiqc/main.nf deleted file mode 100644 index 1264aac1..00000000 --- a/modules/nf-core/modules/multiqc/main.nf +++ /dev/null @@ -1,31 +0,0 @@ -process MULTIQC { - label 'process_medium' - - conda (params.enable_conda ? 'bioconda::multiqc=1.12' : null) - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.12--pyhdfd78af_0' : - 'quay.io/biocontainers/multiqc:1.12--pyhdfd78af_0' }" - - input: - path multiqc_files - - output: - path "*multiqc_report.html", emit: report - path "*_data" , emit: data - path "*_plots" , optional:true, emit: plots - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def args = task.ext.args ?: '' - """ - multiqc -f $args . - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" ) - END_VERSIONS - """ -} diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf new file mode 100644 index 00000000..a8159a57 --- /dev/null +++ b/modules/nf-core/multiqc/main.nf @@ -0,0 +1,53 @@ +process MULTIQC { + label 'process_single' + + conda (params.enable_conda ? 'bioconda::multiqc=1.13' : null) + 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' }" + + input: + path multiqc_files, stageAs: "?/*" + path(multiqc_config) + path(extra_multiqc_config) + path(multiqc_logo) + + output: + path "*multiqc_report.html", emit: report + path "*_data" , emit: data + path "*_plots" , optional:true, emit: plots + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def config = multiqc_config ? "--config $multiqc_config" : '' + def extra_config = extra_multiqc_config ? "--config $extra_multiqc_config" : '' + """ + multiqc \\ + --force \\ + $args \\ + $config \\ + $extra_config \\ + . + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" ) + END_VERSIONS + """ + + stub: + """ + touch multiqc_data + touch multiqc_plots + touch multiqc_report.html + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" ) + END_VERSIONS + """ +} diff --git a/modules/nf-core/modules/multiqc/meta.yml b/modules/nf-core/multiqc/meta.yml similarity index 73% rename from modules/nf-core/modules/multiqc/meta.yml rename to modules/nf-core/multiqc/meta.yml index 6fa891ef..ebc29b27 100644 --- a/modules/nf-core/modules/multiqc/meta.yml +++ b/modules/nf-core/multiqc/meta.yml @@ -12,11 +12,25 @@ tools: homepage: https://multiqc.info/ documentation: https://multiqc.info/docs/ licence: ["GPL-3.0-or-later"] + input: - multiqc_files: type: file description: | List of reports / files recognised by MultiQC, for example the html and zip output of FastQC + - multiqc_config: + type: file + description: Optional config yml for MultiQC + pattern: "*.{yml,yaml}" + - extra_multiqc_config: + type: file + description: Second optional config yml for MultiQC. Will override common sections in multiqc_config. + pattern: "*.{yml,yaml}" + - multiqc_logo: + type: file + description: Optional logo file for MultiQC + pattern: "*.{png}" + output: - report: type: file @@ -38,3 +52,4 @@ authors: - "@abhi18av" - "@bunop" - "@drpatelh" + - "@jfy133" diff --git a/nextflow.config b/nextflow.config index 10d15673..1b90c951 100644 --- a/nextflow.config +++ b/nextflow.config @@ -21,7 +21,9 @@ params { // MultiQC options multiqc_config = null multiqc_title = null + multiqc_logo = null max_multiqc_email_size = '25.MB' + multiqc_methods_description = null // Boilerplate options outdir = null @@ -31,6 +33,7 @@ params { email_on_fail = null plaintext_email = false monochrome_logs = false + hook_url = null help = false validate_params = true show_hidden_params = false @@ -74,7 +77,6 @@ try { // } - profiles { debug { process.beforeScript = 'echo $HOSTNAME' } conda { @@ -189,6 +191,7 @@ manifest { mainScript = 'main.nf' nextflowVersion = '!>=21.10.3' version = '2.2.0dev' + doi = '' } // Load modules.config for DSL2 module specific options diff --git a/nextflow_schema.json b/nextflow_schema.json index e91cc322..2247b45f 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -213,12 +213,30 @@ "fa_icon": "fas fa-palette", "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, only MS Teams is supported.", + "hidden": true + }, "multiqc_config": { "type": "string", "description": "Custom config file to supply to MultiQC.", "fa_icon": "fas fa-cog", "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 + }, + "multiqc_methods_description": { + "type": "string", + "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.", diff --git a/workflows/rnafusion.nf b/workflows/rnafusion.nf index 8914d885..b33a3041 100644 --- a/workflows/rnafusion.nf +++ b/workflows/rnafusion.nf @@ -23,8 +23,10 @@ if (params.input) { ch_input = file(params.input) } else { exit 1, 'Input sample ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -ch_multiqc_config = file("$projectDir/assets/multiqc_config.yml", checkIfExists: true) -ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath(params.multiqc_config) : Channel.empty() +ch_multiqc_config = Channel.fromPath("$projectDir/assets/multiqc_config.yml", checkIfExists: true) +ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath( params.multiqc_config, checkIfExists: true ) : Channel.empty() +ch_multiqc_logo = params.multiqc_logo ? Channel.fromPath( params.multiqc_logo, checkIfExists: true ) : Channel.empty() +ch_multiqc_custom_methods_description = params.multiqc_methods_description ? file(params.multiqc_methods_description, checkIfExists: true) : file("$projectDir/assets/methods_description_template.yml", checkIfExists: true) /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -46,9 +48,9 @@ include { INPUT_CHECK } from '../subworkflows/local/input_check' // // MODULE: Installed directly from nf-core/modules // -include { FASTQC } from '../modules/nf-core/modules/fastqc/main' -include { MULTIQC } from '../modules/nf-core/modules/multiqc/main' -include { CUSTOM_DUMPSOFTWAREVERSIONS } from '../modules/nf-core/modules/custom/dumpsoftwareversions/main' +include { FASTQC } from '../modules/nf-core/fastqc/main' +include { MULTIQC } from '../modules/nf-core/multiqc/main' +include { CUSTOM_DUMPSOFTWAREVERSIONS } from '../modules/nf-core/custom/dumpsoftwareversions/main' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -89,15 +91,20 @@ workflow RNAFUSION { workflow_summary = WorkflowRnafusion.paramsSummaryMultiqc(workflow, summary_params) ch_workflow_summary = Channel.value(workflow_summary) + methods_description = WorkflowRnafusion.methodsDescriptionText(workflow, ch_multiqc_custom_methods_description) + ch_methods_description = Channel.value(methods_description) + ch_multiqc_files = Channel.empty() - ch_multiqc_files = ch_multiqc_files.mix(Channel.from(ch_multiqc_config)) - ch_multiqc_files = ch_multiqc_files.mix(ch_multiqc_custom_config.collect().ifEmpty([])) ch_multiqc_files = ch_multiqc_files.mix(ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) + ch_multiqc_files = ch_multiqc_files.mix(ch_methods_description.collectFile(name: 'methods_description_mqc.yaml')) ch_multiqc_files = ch_multiqc_files.mix(CUSTOM_DUMPSOFTWAREVERSIONS.out.mqc_yml.collect()) ch_multiqc_files = ch_multiqc_files.mix(FASTQC.out.zip.collect{it[1]}.ifEmpty([])) MULTIQC ( - ch_multiqc_files.collect() + ch_multiqc_files.collect(), + ch_multiqc_config.collect().ifEmpty([]), + ch_multiqc_custom_config.collect().ifEmpty([]), + ch_multiqc_logo.collect().ifEmpty([]) ) multiqc_report = MULTIQC.out.report.toList() ch_versions = ch_versions.mix(MULTIQC.out.versions) @@ -114,6 +121,9 @@ workflow.onComplete { NfcoreTemplate.email(workflow, params, summary_params, projectDir, log, multiqc_report) } NfcoreTemplate.summary(workflow, params, log) + if (params.hook_url) { + NfcoreTemplate.adaptivecard(workflow, params, summary_params, projectDir, log) + } } /* From 2241ccce13195400166ce85a0e54af800c2cadb2 Mon Sep 17 00:00:00 2001 From: Matthias De Smet <11850640+matthdsm@users.noreply.github.com> Date: Fri, 28 Oct 2022 10:40:14 +0200 Subject: [PATCH 056/176] drop GET_META and GET_FILE modules --- modules/local/getmeta/main.nf | 20 -------------------- modules/local/getpath/main.nf | 19 ------------------- subworkflows/local/arriba_workflow.nf | 13 +++++-------- subworkflows/local/fusioncatcher_workflow.nf | 6 +++--- subworkflows/local/fusionreport_workflow.nf | 3 +-- subworkflows/local/pizzly_workflow.nf | 5 ++--- subworkflows/local/squid_workflow.nf | 5 ++--- subworkflows/local/starfusion_workflow.nf | 5 ++--- 8 files changed, 15 insertions(+), 61 deletions(-) delete mode 100644 modules/local/getmeta/main.nf delete mode 100644 modules/local/getpath/main.nf diff --git a/modules/local/getmeta/main.nf b/modules/local/getmeta/main.nf deleted file mode 100644 index c52b16dc..00000000 --- a/modules/local/getmeta/main.nf +++ /dev/null @@ -1,20 +0,0 @@ -process GET_META { - tag 'getmeta' - label 'process_low' - - conda (params.enable_conda ? "conda-forge::sed=4.7" : null) - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://containers.biocontainers.pro/s3/SingImgsRepo/biocontainers/v1.2.0_cv1/biocontainers_v1.2.0_cv1.img' : - 'biocontainers/biocontainers:v1.2.0_cv1' }" - - input: - tuple val(meta), path(reads) - path file - - output: - tuple val(meta), path(file) , emit: file - - script: - """ - """ -} diff --git a/modules/local/getpath/main.nf b/modules/local/getpath/main.nf deleted file mode 100644 index 5f159287..00000000 --- a/modules/local/getpath/main.nf +++ /dev/null @@ -1,19 +0,0 @@ -process GET_PATH { - tag 'getpath' - label 'process_low' - - conda (params.enable_conda ? "conda-forge::sed=4.7" : null) - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://containers.biocontainers.pro/s3/SingImgsRepo/biocontainers/v1.2.0_cv1/biocontainers_v1.2.0_cv1.img' : - 'biocontainers/biocontainers:v1.2.0_cv1' }" - - input: - tuple val(meta), path(file) - - output: - path file , emit: file - - script: - """ - """ -} diff --git a/subworkflows/local/arriba_workflow.nf b/subworkflows/local/arriba_workflow.nf index 789ef179..ab9c7748 100644 --- a/subworkflows/local/arriba_workflow.nf +++ b/subworkflows/local/arriba_workflow.nf @@ -1,7 +1,5 @@ include { ARRIBA } from '../../modules/nf-core/modules/arriba/main' include { ARRIBA_VISUALISATION } from '../../modules/local/arriba/visualisation/main' -include { GET_META } from '../../modules/local/getmeta/main' -include { GET_PATH as GET_PATH_ARRIBA_FAIL } from '../../modules/local/getpath/main' include { SAMTOOLS_SORT as SAMTOOLS_SORT_FOR_ARRIBA } from '../../modules/nf-core/modules/samtools/sort/main' include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_ARRIBA} from '../../modules/nf-core/modules/samtools/index/main' include { STAR_ALIGN as STAR_FOR_ARRIBA } from '../../modules/nf-core/modules/star/align/main' @@ -32,16 +30,15 @@ workflow ARRIBA_WORKFLOW { bam_indexed = SAMTOOLS_SORT_FOR_ARRIBA.out.bam.join(SAMTOOLS_INDEX_FOR_ARRIBA.out.bai) if (params.arriba_fusions) { - ch_arriba_fusions = GET_META(reads, params.arriba_fusions) + // [meta, reads], fusions -> [meta, fusions] + ch_arriba_fusions = reads.merge(Channel.fromPath(params.arriba_fusions, checkIfExists:true)) ch_arriba_fusion_fail = ch_dummy_file } else { ARRIBA ( STAR_FOR_ARRIBA.out.bam, ch_fasta, ch_gtf, params.arriba_ref_blacklist, [], [], [], params.arriba_ref_protein_domain ) ch_versions = ch_versions.mix(ARRIBA.out.versions) - ch_arriba_fusions = ARRIBA.out.fusions - - GET_PATH_ARRIBA_FAIL(ARRIBA.out.fusions_fail) - ch_arriba_fusion_fail = GET_PATH_ARRIBA_FAIL.out.file + ch_arriba_fusions = ARRIBA.out.fusions + ch_arriba_fusion_fail = ARRIBA.out.fusions_fail.map{ meta, file -> return file} } bam_indexed_arriba_fusions = bam_indexed.join(ch_arriba_fusions) ARRIBA_VISUALISATION(bam_indexed_arriba_fusions, params.arriba_ref, ch_gtf) @@ -51,7 +48,7 @@ workflow ARRIBA_WORKFLOW { } else { - ch_arriba_fusions = GET_META(reads, ch_dummy_file) + ch_arriba_fusions = reads.merge(ch_dummy_file) ch_arriba_fusion_fail = ch_dummy_file ch_arriba_visualisation = ch_dummy_file } diff --git a/subworkflows/local/fusioncatcher_workflow.nf b/subworkflows/local/fusioncatcher_workflow.nf index c4a0c344..cb4e9026 100644 --- a/subworkflows/local/fusioncatcher_workflow.nf +++ b/subworkflows/local/fusioncatcher_workflow.nf @@ -1,5 +1,4 @@ include { FUSIONCATCHER } from '../../modules/local/fusioncatcher/detect/main' -include { GET_META } from '../../modules/local/getmeta/main' workflow FUSIONCATCHER_WORKFLOW { @@ -12,7 +11,8 @@ workflow FUSIONCATCHER_WORKFLOW { if ((params.fusioncatcher || params.all) && !params.fusioninspector_only) { if (params.fusioncatcher_fusions){ - ch_fusioncatcher_fusions = GET_META(reads, params.fusioncatcher_fusions) + ch_fusioncatcher_fusions = reads.merge(Channel.fromPath(params.fusioncatcher_fusions, checkIfExists:true)) + } else { FUSIONCATCHER ( reads, @@ -22,7 +22,7 @@ workflow FUSIONCATCHER_WORKFLOW { } } else { - ch_fusioncatcher_fusions = GET_META(reads, ch_dummy_file) + ch_fusioncatcher_fusions = reads.merge(ch_dummy_file) } emit: diff --git a/subworkflows/local/fusionreport_workflow.nf b/subworkflows/local/fusionreport_workflow.nf index 13f1796e..3d1be49f 100644 --- a/subworkflows/local/fusionreport_workflow.nf +++ b/subworkflows/local/fusionreport_workflow.nf @@ -1,5 +1,4 @@ include { FUSIONREPORT } from '../../modules/local/fusionreport/detect/main' -include { GET_META } from '../../modules/local/getmeta/main' workflow FUSIONREPORT_WORKFLOW { @@ -28,7 +27,7 @@ workflow FUSIONREPORT_WORKFLOW { ch_fusion_list_filtered = FUSIONREPORT.out.fusion_list_filtered ch_versions = ch_versions.mix(FUSIONREPORT.out.versions) } else { - ch_fusion_list = GET_META(reads, params.fusioninspector_fusions) + ch_fusion_list = reads.merge(Channel.fromPath(params.fusioninspector_fusions, checkIfExists:true)) ch_fusion_list_filtered = ch_fusion_list } diff --git a/subworkflows/local/pizzly_workflow.nf b/subworkflows/local/pizzly_workflow.nf index 676ab2b2..b3ef7db6 100644 --- a/subworkflows/local/pizzly_workflow.nf +++ b/subworkflows/local/pizzly_workflow.nf @@ -1,6 +1,5 @@ include { KALLISTO_QUANT } from '../../modules/local/kallisto/quant/main' include { PIZZLY } from '../../modules/local/pizzly/detect/main' -include { GET_META } from '../../modules/local/getmeta/main' workflow PIZZLY_WORKFLOW { take: @@ -14,7 +13,7 @@ workflow PIZZLY_WORKFLOW { if ((params.pizzly || params.all) && !params.fusioninspector_only) { if (params.pizzly_fusions) { - ch_pizzly_fusions = GET_META(reads, params.pizzly_fusions) + ch_pizzly_fusions = reads.merge(Channel.fromPath(params.pizzly_fusions, checkIfExists:true)) } else { KALLISTO_QUANT(reads, params.pizzly_ref ) ch_versions = ch_versions.mix(KALLISTO_QUANT.out.versions) @@ -26,7 +25,7 @@ workflow PIZZLY_WORKFLOW { } } else { - ch_pizzly_fusions = GET_META(reads, ch_dummy_file) + ch_pizzly_fusions = reads.merge(ch_dummy_file) } diff --git a/subworkflows/local/squid_workflow.nf b/subworkflows/local/squid_workflow.nf index 03e540d1..4d4485e7 100644 --- a/subworkflows/local/squid_workflow.nf +++ b/subworkflows/local/squid_workflow.nf @@ -1,4 +1,3 @@ -include { GET_META } from '../../modules/local/getmeta/main' include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_SQUID} from '../../modules/nf-core/modules/samtools/index/main' include { SAMTOOLS_SORT as SAMTOOLS_SORT_FOR_SQUID } from '../../modules/nf-core/modules/samtools/sort/main' include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_SQUID } from '../../modules/nf-core/modules/samtools/view/main' @@ -19,7 +18,7 @@ workflow SQUID_WORKFLOW { if ((params.squid || params.all) && !params.fusioninspector_only) { if (params.squid_fusions){ - ch_squid_fusions = GET_META(reads, params.squid_fusions) + ch_squid_fusions = reads.merge(Channel.fromPath(params.squid_fusions, checkIfExists:true)) } else { STAR_FOR_SQUID( reads, ch_starindex_ensembl_ref, ch_gtf, params.star_ignore_sjdbgtf, '', params.seq_center ?: '') @@ -48,7 +47,7 @@ workflow SQUID_WORKFLOW { } } else { - ch_squid_fusions = GET_META(reads, ch_dummy_file) + ch_squid_fusions = reads.merge(ch_dummy_file) } emit: diff --git a/subworkflows/local/starfusion_workflow.nf b/subworkflows/local/starfusion_workflow.nf index 5f4e4a16..46102f82 100644 --- a/subworkflows/local/starfusion_workflow.nf +++ b/subworkflows/local/starfusion_workflow.nf @@ -1,6 +1,5 @@ include { STAR_ALIGN as STAR_FOR_STARFUSION } from '../../modules/nf-core/modules/star/align/main' include { STARFUSION } from '../../modules/local/starfusion/detect/main' -include { GET_META } from '../../modules/local/getmeta/main' workflow STARFUSION_WORKFLOW { take: @@ -15,7 +14,7 @@ workflow STARFUSION_WORKFLOW { if ((params.starfusion || params.all) && !params.fusioninspector_only) { if (params.starfusion_fusions){ - ch_starfusion_fusions = GET_META(reads, params.starfusion_fusions) + ch_starfusion_fusions = reads.merge(Channel.fromPath(params.starfusion_fusions, checkIfExists:true)) } else { STAR_FOR_STARFUSION( reads, ch_starindex_ref, ch_chrgtf, params.star_ignore_sjdbgtf, '', params.seq_center ?: '') ch_versions = ch_versions.mix(STAR_FOR_STARFUSION.out.versions) @@ -31,7 +30,7 @@ workflow STARFUSION_WORKFLOW { } } else { - ch_starfusion_fusions = GET_META(reads, ch_dummy_file) + ch_starfusion_fusions = reads.merge(ch_dummy_file) ch_star_stats = Channel.empty() } emit: From f056b1f05aea3085d95be284280a781aa9d35315 Mon Sep 17 00:00:00 2001 From: Matthias De Smet Date: Fri, 28 Oct 2022 08:47:55 +0000 Subject: [PATCH 057/176] modules restructure --- modules.json | 123 +++++++++--------- modules/nf-core/{modules => }/arriba/main.nf | 0 modules/nf-core/{modules => }/arriba/meta.yml | 0 .../nf-core/{modules => }/cat/fastq/main.nf | 0 .../nf-core/{modules => }/cat/fastq/meta.yml | 0 .../custom/dumpsoftwareversions/main.nf | 0 .../custom/dumpsoftwareversions/meta.yml | 0 .../templates/dumpsoftwareversions.py | 0 modules/nf-core/{modules => }/fastqc/main.nf | 0 modules/nf-core/{modules => }/fastqc/meta.yml | 0 .../{modules => }/kallisto/index/main.nf | 0 .../{modules => }/kallisto/index/meta.yml | 0 modules/nf-core/{modules => }/multiqc/main.nf | 0 .../nf-core/{modules => }/multiqc/meta.yml | 0 .../picard/collectwgsmetrics/main.nf | 0 .../picard/collectwgsmetrics/meta.yml | 0 .../picard/markduplicates/main.nf | 0 .../picard/markduplicates/meta.yml | 0 .../{modules => }/qualimap/rnaseq/main.nf | 0 .../{modules => }/samtools/faidx/main.nf | 0 .../{modules => }/samtools/faidx/meta.yml | 0 .../{modules => }/samtools/index/main.nf | 0 .../{modules => }/samtools/index/meta.yml | 0 .../{modules => }/samtools/sort/main.nf | 0 .../{modules => }/samtools/sort/meta.yml | 0 .../{modules => }/samtools/view/main.nf | 0 .../{modules => }/samtools/view/meta.yml | 0 .../nf-core/{modules => }/star/align/main.nf | 0 .../nf-core/{modules => }/star/align/meta.yml | 0 .../{modules => }/star/genomegenerate/main.nf | 0 .../star/genomegenerate/meta.yml | 0 31 files changed, 62 insertions(+), 61 deletions(-) rename modules/nf-core/{modules => }/arriba/main.nf (100%) rename modules/nf-core/{modules => }/arriba/meta.yml (100%) rename modules/nf-core/{modules => }/cat/fastq/main.nf (100%) rename modules/nf-core/{modules => }/cat/fastq/meta.yml (100%) rename modules/nf-core/{modules => }/custom/dumpsoftwareversions/main.nf (100%) rename modules/nf-core/{modules => }/custom/dumpsoftwareversions/meta.yml (100%) rename modules/nf-core/{modules => }/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py (100%) rename modules/nf-core/{modules => }/fastqc/main.nf (100%) rename modules/nf-core/{modules => }/fastqc/meta.yml (100%) rename modules/nf-core/{modules => }/kallisto/index/main.nf (100%) rename modules/nf-core/{modules => }/kallisto/index/meta.yml (100%) rename modules/nf-core/{modules => }/multiqc/main.nf (100%) rename modules/nf-core/{modules => }/multiqc/meta.yml (100%) rename modules/nf-core/{modules => }/picard/collectwgsmetrics/main.nf (100%) rename modules/nf-core/{modules => }/picard/collectwgsmetrics/meta.yml (100%) rename modules/nf-core/{modules => }/picard/markduplicates/main.nf (100%) rename modules/nf-core/{modules => }/picard/markduplicates/meta.yml (100%) rename modules/nf-core/{modules => }/qualimap/rnaseq/main.nf (100%) rename modules/nf-core/{modules => }/samtools/faidx/main.nf (100%) rename modules/nf-core/{modules => }/samtools/faidx/meta.yml (100%) rename modules/nf-core/{modules => }/samtools/index/main.nf (100%) rename modules/nf-core/{modules => }/samtools/index/meta.yml (100%) rename modules/nf-core/{modules => }/samtools/sort/main.nf (100%) rename modules/nf-core/{modules => }/samtools/sort/meta.yml (100%) rename modules/nf-core/{modules => }/samtools/view/main.nf (100%) rename modules/nf-core/{modules => }/samtools/view/meta.yml (100%) rename modules/nf-core/{modules => }/star/align/main.nf (100%) rename modules/nf-core/{modules => }/star/align/meta.yml (100%) rename modules/nf-core/{modules => }/star/genomegenerate/main.nf (100%) rename modules/nf-core/{modules => }/star/genomegenerate/meta.yml (100%) diff --git a/modules.json b/modules.json index d68356da..71dc41b4 100644 --- a/modules.json +++ b/modules.json @@ -2,68 +2,69 @@ "name": "nf-core/rnafusion", "homePage": "https://github.com/nf-core/rnafusion", "repos": { - "nf-core/modules": { - "git_url": "https://github.com/nf-core/modules.git", + "https://github.com/nf-core/modules.git": { "modules": { - "arriba": { - "branch": "master", - "git_sha": "80746895e214a4d55570f90554164b19476f4114" - }, - "cat/fastq": { - "branch": "master", - "git_sha": "b034029b59b1198075da8019074bc02051a6100e" - }, - "custom/dumpsoftwareversions": { - "branch": "master", - "git_sha": "e5b44499efcf6f7fb24874886bac60591c5d94dd" - }, - "fastqc": { - "branch": "master", - "git_sha": "49b18b1639f4f7104187058866a8fab33332bdfe" - }, - "kallisto/index": { - "branch": "master", - "git_sha": "479e0638d14a3e9e9dd96a5b74b3b5682e8a8b43" - }, - "multiqc": { - "branch": "master", - "git_sha": "5138acca0985ca01c38a1c4fba917d83772b1106" - }, - "picard/collectwgsmetrics": { - "branch": "master", - "git_sha": "ac1c6ad7104c7863842a322a8cf74f4fee1d20b4" - }, - "picard/markduplicates": { - "branch": "master", - "git_sha": "682f789f93070bd047868300dd018faf3d434e7c" - }, - "qualimap/rnaseq": { - "branch": "master", - "git_sha": "53108b6b51d4e968e5b1cc9b07ddb6559cb6d43d" - }, - "samtools/faidx": { - "branch": "master", - "git_sha": "ce06694af8ca2f7453206aa974c2c9a2b99ec093" - }, - "samtools/index": { - "branch": "master", - "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773" - }, - "samtools/sort": { - "branch": "master", - "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773" - }, - "samtools/view": { - "branch": "master", - "git_sha": "6b64f9cb6c3dd3577931cc3cd032d6fb730000ce" - }, - "star/align": { - "branch": "master", - "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba" - }, - "star/genomegenerate": { - "branch": "master", - "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba" + "nf-core": { + "arriba": { + "branch": "master", + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + }, + "cat/fastq": { + "branch": "master", + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + }, + "custom/dumpsoftwareversions": { + "branch": "master", + "git_sha": "8022c68e7403eecbd8ba9c49496f69f8c49d50f0" + }, + "fastqc": { + "branch": "master", + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + }, + "kallisto/index": { + "branch": "master", + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + }, + "multiqc": { + "branch": "master", + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + }, + "picard/collectwgsmetrics": { + "branch": "master", + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + }, + "picard/markduplicates": { + "branch": "master", + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + }, + "qualimap/rnaseq": { + "branch": "master", + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + }, + "samtools/faidx": { + "branch": "master", + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + }, + "samtools/index": { + "branch": "master", + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + }, + "samtools/sort": { + "branch": "master", + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + }, + "samtools/view": { + "branch": "master", + "git_sha": "202683bfc98ddecdd456ea73268e330bca2e5c5a" + }, + "star/align": { + "branch": "master", + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + }, + "star/genomegenerate": { + "branch": "master", + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + } } } } diff --git a/modules/nf-core/modules/arriba/main.nf b/modules/nf-core/arriba/main.nf similarity index 100% rename from modules/nf-core/modules/arriba/main.nf rename to modules/nf-core/arriba/main.nf diff --git a/modules/nf-core/modules/arriba/meta.yml b/modules/nf-core/arriba/meta.yml similarity index 100% rename from modules/nf-core/modules/arriba/meta.yml rename to modules/nf-core/arriba/meta.yml diff --git a/modules/nf-core/modules/cat/fastq/main.nf b/modules/nf-core/cat/fastq/main.nf similarity index 100% rename from modules/nf-core/modules/cat/fastq/main.nf rename to modules/nf-core/cat/fastq/main.nf diff --git a/modules/nf-core/modules/cat/fastq/meta.yml b/modules/nf-core/cat/fastq/meta.yml similarity index 100% rename from modules/nf-core/modules/cat/fastq/meta.yml rename to modules/nf-core/cat/fastq/meta.yml diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf b/modules/nf-core/custom/dumpsoftwareversions/main.nf similarity index 100% rename from modules/nf-core/modules/custom/dumpsoftwareversions/main.nf rename to modules/nf-core/custom/dumpsoftwareversions/main.nf diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/meta.yml b/modules/nf-core/custom/dumpsoftwareversions/meta.yml similarity index 100% rename from modules/nf-core/modules/custom/dumpsoftwareversions/meta.yml rename to modules/nf-core/custom/dumpsoftwareversions/meta.yml diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py b/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py similarity index 100% rename from modules/nf-core/modules/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py rename to modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py diff --git a/modules/nf-core/modules/fastqc/main.nf b/modules/nf-core/fastqc/main.nf similarity index 100% rename from modules/nf-core/modules/fastqc/main.nf rename to modules/nf-core/fastqc/main.nf diff --git a/modules/nf-core/modules/fastqc/meta.yml b/modules/nf-core/fastqc/meta.yml similarity index 100% rename from modules/nf-core/modules/fastqc/meta.yml rename to modules/nf-core/fastqc/meta.yml diff --git a/modules/nf-core/modules/kallisto/index/main.nf b/modules/nf-core/kallisto/index/main.nf similarity index 100% rename from modules/nf-core/modules/kallisto/index/main.nf rename to modules/nf-core/kallisto/index/main.nf diff --git a/modules/nf-core/modules/kallisto/index/meta.yml b/modules/nf-core/kallisto/index/meta.yml similarity index 100% rename from modules/nf-core/modules/kallisto/index/meta.yml rename to modules/nf-core/kallisto/index/meta.yml diff --git a/modules/nf-core/modules/multiqc/main.nf b/modules/nf-core/multiqc/main.nf similarity index 100% rename from modules/nf-core/modules/multiqc/main.nf rename to modules/nf-core/multiqc/main.nf diff --git a/modules/nf-core/modules/multiqc/meta.yml b/modules/nf-core/multiqc/meta.yml similarity index 100% rename from modules/nf-core/modules/multiqc/meta.yml rename to modules/nf-core/multiqc/meta.yml diff --git a/modules/nf-core/modules/picard/collectwgsmetrics/main.nf b/modules/nf-core/picard/collectwgsmetrics/main.nf similarity index 100% rename from modules/nf-core/modules/picard/collectwgsmetrics/main.nf rename to modules/nf-core/picard/collectwgsmetrics/main.nf diff --git a/modules/nf-core/modules/picard/collectwgsmetrics/meta.yml b/modules/nf-core/picard/collectwgsmetrics/meta.yml similarity index 100% rename from modules/nf-core/modules/picard/collectwgsmetrics/meta.yml rename to modules/nf-core/picard/collectwgsmetrics/meta.yml diff --git a/modules/nf-core/modules/picard/markduplicates/main.nf b/modules/nf-core/picard/markduplicates/main.nf similarity index 100% rename from modules/nf-core/modules/picard/markduplicates/main.nf rename to modules/nf-core/picard/markduplicates/main.nf diff --git a/modules/nf-core/modules/picard/markduplicates/meta.yml b/modules/nf-core/picard/markduplicates/meta.yml similarity index 100% rename from modules/nf-core/modules/picard/markduplicates/meta.yml rename to modules/nf-core/picard/markduplicates/meta.yml diff --git a/modules/nf-core/modules/qualimap/rnaseq/main.nf b/modules/nf-core/qualimap/rnaseq/main.nf similarity index 100% rename from modules/nf-core/modules/qualimap/rnaseq/main.nf rename to modules/nf-core/qualimap/rnaseq/main.nf diff --git a/modules/nf-core/modules/samtools/faidx/main.nf b/modules/nf-core/samtools/faidx/main.nf similarity index 100% rename from modules/nf-core/modules/samtools/faidx/main.nf rename to modules/nf-core/samtools/faidx/main.nf diff --git a/modules/nf-core/modules/samtools/faidx/meta.yml b/modules/nf-core/samtools/faidx/meta.yml similarity index 100% rename from modules/nf-core/modules/samtools/faidx/meta.yml rename to modules/nf-core/samtools/faidx/meta.yml diff --git a/modules/nf-core/modules/samtools/index/main.nf b/modules/nf-core/samtools/index/main.nf similarity index 100% rename from modules/nf-core/modules/samtools/index/main.nf rename to modules/nf-core/samtools/index/main.nf diff --git a/modules/nf-core/modules/samtools/index/meta.yml b/modules/nf-core/samtools/index/meta.yml similarity index 100% rename from modules/nf-core/modules/samtools/index/meta.yml rename to modules/nf-core/samtools/index/meta.yml diff --git a/modules/nf-core/modules/samtools/sort/main.nf b/modules/nf-core/samtools/sort/main.nf similarity index 100% rename from modules/nf-core/modules/samtools/sort/main.nf rename to modules/nf-core/samtools/sort/main.nf diff --git a/modules/nf-core/modules/samtools/sort/meta.yml b/modules/nf-core/samtools/sort/meta.yml similarity index 100% rename from modules/nf-core/modules/samtools/sort/meta.yml rename to modules/nf-core/samtools/sort/meta.yml diff --git a/modules/nf-core/modules/samtools/view/main.nf b/modules/nf-core/samtools/view/main.nf similarity index 100% rename from modules/nf-core/modules/samtools/view/main.nf rename to modules/nf-core/samtools/view/main.nf diff --git a/modules/nf-core/modules/samtools/view/meta.yml b/modules/nf-core/samtools/view/meta.yml similarity index 100% rename from modules/nf-core/modules/samtools/view/meta.yml rename to modules/nf-core/samtools/view/meta.yml diff --git a/modules/nf-core/modules/star/align/main.nf b/modules/nf-core/star/align/main.nf similarity index 100% rename from modules/nf-core/modules/star/align/main.nf rename to modules/nf-core/star/align/main.nf diff --git a/modules/nf-core/modules/star/align/meta.yml b/modules/nf-core/star/align/meta.yml similarity index 100% rename from modules/nf-core/modules/star/align/meta.yml rename to modules/nf-core/star/align/meta.yml diff --git a/modules/nf-core/modules/star/genomegenerate/main.nf b/modules/nf-core/star/genomegenerate/main.nf similarity index 100% rename from modules/nf-core/modules/star/genomegenerate/main.nf rename to modules/nf-core/star/genomegenerate/main.nf diff --git a/modules/nf-core/modules/star/genomegenerate/meta.yml b/modules/nf-core/star/genomegenerate/meta.yml similarity index 100% rename from modules/nf-core/modules/star/genomegenerate/meta.yml rename to modules/nf-core/star/genomegenerate/meta.yml From 3ace21f5a868a6b39a7596fad64fc6a85d91fff6 Mon Sep 17 00:00:00 2001 From: Matthias De Smet Date: Fri, 28 Oct 2022 08:48:28 +0000 Subject: [PATCH 058/176] nf-core lint --- .prettierignore | 1 + lib/NfcoreTemplate.groovy | 55 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/.prettierignore b/.prettierignore index d0e7ae58..eb74a574 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,5 @@ email_template.html +adaptivecard.json .nextflow* work/ data/ diff --git a/lib/NfcoreTemplate.groovy b/lib/NfcoreTemplate.groovy index 2fc0a9b9..27feb009 100755 --- a/lib/NfcoreTemplate.groovy +++ b/lib/NfcoreTemplate.groovy @@ -145,6 +145,61 @@ class NfcoreTemplate { output_tf.withWriter { w -> w << email_txt } } + // + // Construct and send adaptive card + // https://adaptivecards.io + // + public static void adaptivecard(workflow, params, summary_params, projectDir, log) { + def hook_url = params.hook_url + + def summary = [:] + for (group in summary_params.keySet()) { + summary << summary_params[group] + } + + def misc_fields = [:] + misc_fields['start'] = workflow.start + misc_fields['complete'] = workflow.complete + misc_fields['scriptfile'] = workflow.scriptFile + misc_fields['scriptid'] = workflow.scriptId + if (workflow.repository) misc_fields['repository'] = workflow.repository + if (workflow.commitId) misc_fields['commitid'] = workflow.commitId + if (workflow.revision) misc_fields['revision'] = workflow.revision + misc_fields['nxf_version'] = workflow.nextflow.version + misc_fields['nxf_build'] = workflow.nextflow.build + misc_fields['nxf_timestamp'] = workflow.nextflow.timestamp + + def msg_fields = [:] + msg_fields['version'] = workflow.manifest.version + msg_fields['runName'] = workflow.runName + msg_fields['success'] = workflow.success + msg_fields['dateComplete'] = workflow.complete + msg_fields['duration'] = workflow.duration + msg_fields['exitStatus'] = workflow.exitStatus + msg_fields['errorMessage'] = (workflow.errorMessage ?: 'None') + msg_fields['errorReport'] = (workflow.errorReport ?: 'None') + msg_fields['commandLine'] = workflow.commandLine + msg_fields['projectDir'] = workflow.projectDir + msg_fields['summary'] = summary << misc_fields + + // Render the JSON template + def engine = new groovy.text.GStringTemplateEngine() + def hf = new File("$projectDir/assets/adaptivecard.json") + def json_template = engine.createTemplate(hf).make(msg_fields) + def json_message = json_template.toString() + + // POST + def post = new URL(hook_url).openConnection(); + post.setRequestMethod("POST") + post.setDoOutput(true) + post.setRequestProperty("Content-Type", "application/json") + post.getOutputStream().write(json_message.getBytes("UTF-8")); + def postRC = post.getResponseCode(); + if (! postRC.equals(200)) { + log.warn(post.getErrorStream().getText()); + } + } + // // Print pipeline summary on completion // From 74337203b548dd72eeac06d0063d39a42bd233c3 Mon Sep 17 00:00:00 2001 From: Matthias De Smet Date: Fri, 28 Oct 2022 08:54:50 +0000 Subject: [PATCH 059/176] update modules to fix linting --- modules.json | 4 +- modules/local/samplesheet_check.nf | 8 +- modules/nf-core/cat/fastq/main.nf | 10 +- .../custom/dumpsoftwareversions/main.nf | 8 +- .../templates/dumpsoftwareversions.py | 102 ++++++++++-------- modules/nf-core/fastqc/main.nf | 34 ++---- modules/nf-core/multiqc/main.nf | 16 +-- modules/nf-core/multiqc/meta.yml | 11 +- modules/nf-core/picard/markduplicates/main.nf | 3 + .../nf-core/picard/markduplicates/meta.yml | 10 +- modules/nf-core/qualimap/rnaseq/main.nf | 4 +- modules/nf-core/samtools/faidx/main.nf | 3 +- modules/nf-core/samtools/faidx/meta.yml | 4 + modules/nf-core/samtools/sort/main.nf | 1 + modules/nf-core/samtools/sort/meta.yml | 4 + modules/nf-core/samtools/view/main.nf | 26 +++-- modules/nf-core/samtools/view/meta.yml | 30 +++++- 17 files changed, 168 insertions(+), 110 deletions(-) mode change 100644 => 100755 modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py diff --git a/modules.json b/modules.json index 71dc41b4..0243832a 100644 --- a/modules.json +++ b/modules.json @@ -19,7 +19,7 @@ }, "fastqc": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "f6a11408536fbee6cbea1f5977605011873de3ca" }, "kallisto/index": { "branch": "master", @@ -35,7 +35,7 @@ }, "picard/markduplicates": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "eca65aa4a5e2e192ac44d6962c8f9260f314ffb8" }, "qualimap/rnaseq": { "branch": "master", diff --git a/modules/local/samplesheet_check.nf b/modules/local/samplesheet_check.nf index e8737886..cb4ee7fb 100644 --- a/modules/local/samplesheet_check.nf +++ b/modules/local/samplesheet_check.nf @@ -3,11 +3,9 @@ process SAMPLESHEET_CHECK { label 'process_low' conda (params.enable_conda ? "conda-forge::python=3.8.3" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/python:3.8.3" - } else { - container "quay.io/biocontainers/python:3.8.3" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/python:3.8.3' : + 'quay.io/biocontainers/python:3.8.3' }" input: path samplesheet diff --git a/modules/nf-core/cat/fastq/main.nf b/modules/nf-core/cat/fastq/main.nf index d275f19c..4fa365d3 100644 --- a/modules/nf-core/cat/fastq/main.nf +++ b/modules/nf-core/cat/fastq/main.nf @@ -1,6 +1,6 @@ process CAT_FASTQ { tag "$meta.id" - label 'process_low' + label 'process_single' conda (params.enable_conda ? "conda-forge::sed=4.7" : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? @@ -20,9 +20,9 @@ process CAT_FASTQ { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def readList = reads.collect{ it.toString() } + def readList = reads instanceof List ? reads.collect{ it.toString() } : [reads.toString()] if (meta.single_end) { - if (readList.size > 1) { + if (readList.size >= 1) { """ cat ${readList.join(' ')} > ${prefix}.merged.fastq.gz @@ -33,7 +33,7 @@ process CAT_FASTQ { """ } } else { - if (readList.size > 2) { + if (readList.size >= 2) { def read1 = [] def read2 = [] readList.eachWithIndex{ v, ix -> ( ix & 1 ? read2 : read1 ) << v } @@ -51,7 +51,7 @@ process CAT_FASTQ { stub: def prefix = task.ext.prefix ?: "${meta.id}" - def readList = reads.collect{ it.toString() } + def readList = reads instanceof List ? reads.collect{ it.toString() } : [reads.toString()] if (meta.single_end) { if (readList.size > 1) { """ diff --git a/modules/nf-core/custom/dumpsoftwareversions/main.nf b/modules/nf-core/custom/dumpsoftwareversions/main.nf index 203e485a..cebb6e05 100644 --- a/modules/nf-core/custom/dumpsoftwareversions/main.nf +++ b/modules/nf-core/custom/dumpsoftwareversions/main.nf @@ -1,11 +1,11 @@ process CUSTOM_DUMPSOFTWAREVERSIONS { - label 'process_low' + label 'process_single' // Requires `pyyaml` which does not have a dedicated container but is in the MultiQC container - conda (params.enable_conda ? 'bioconda::multiqc=1.13a' : null) + conda (params.enable_conda ? 'bioconda::multiqc=1.13' : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.13a--pyhdfd78af_1' : - 'quay.io/biocontainers/multiqc:1.13a--pyhdfd78af_1' }" + 'https://depot.galaxyproject.org/singularity/multiqc:1.13--pyhdfd78af_0' : + 'quay.io/biocontainers/multiqc:1.13--pyhdfd78af_0' }" input: path versions diff --git a/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py b/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py old mode 100644 new mode 100755 index 787bdb7b..da033408 --- a/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py +++ b/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py @@ -1,12 +1,16 @@ #!/usr/bin/env python -import platform -from textwrap import dedent + +"""Provide functions to merge multiple versions.yml files.""" + import yaml +import platform +from textwrap import dedent def _make_versions_html(versions): + """Generate a tabular HTML output of all versions for MultiQC.""" html = [ dedent( """\\ @@ -45,47 +49,53 @@ def _make_versions_html(versions): return "\\n".join(html) -versions_this_module = {} -versions_this_module["${task.process}"] = { - "python": platform.python_version(), - "yaml": yaml.__version__, -} - -with open("$versions") as f: - versions_by_process = yaml.load(f, Loader=yaml.BaseLoader) | versions_this_module - -# aggregate versions by the module name (derived from fully-qualified process name) -versions_by_module = {} -for process, process_versions in versions_by_process.items(): - module = process.split(":")[-1] - try: - if versions_by_module[module] != process_versions: - raise AssertionError( - "We assume that software versions are the same between all modules. " - "If you see this error-message it means you discovered an edge-case " - "and should open an issue in nf-core/tools. " - ) - except KeyError: - versions_by_module[module] = process_versions - -versions_by_module["Workflow"] = { - "Nextflow": "$workflow.nextflow.version", - "$workflow.manifest.name": "$workflow.manifest.version", -} - -versions_mqc = { - "id": "software_versions", - "section_name": "${workflow.manifest.name} Software Versions", - "section_href": "https://github.com/${workflow.manifest.name}", - "plot_type": "html", - "description": "are collected at run time from the software output.", - "data": _make_versions_html(versions_by_module), -} - -with open("software_versions.yml", "w") as f: - yaml.dump(versions_by_module, f, default_flow_style=False) -with open("software_versions_mqc.yml", "w") as f: - yaml.dump(versions_mqc, f, default_flow_style=False) - -with open("versions.yml", "w") as f: - yaml.dump(versions_this_module, f, default_flow_style=False) +def main(): + """Load all version files and generate merged output.""" + versions_this_module = {} + versions_this_module["${task.process}"] = { + "python": platform.python_version(), + "yaml": yaml.__version__, + } + + with open("$versions") as f: + versions_by_process = yaml.load(f, Loader=yaml.BaseLoader) | versions_this_module + + # aggregate versions by the module name (derived from fully-qualified process name) + versions_by_module = {} + for process, process_versions in versions_by_process.items(): + module = process.split(":")[-1] + try: + if versions_by_module[module] != process_versions: + raise AssertionError( + "We assume that software versions are the same between all modules. " + "If you see this error-message it means you discovered an edge-case " + "and should open an issue in nf-core/tools. " + ) + except KeyError: + versions_by_module[module] = process_versions + + versions_by_module["Workflow"] = { + "Nextflow": "$workflow.nextflow.version", + "$workflow.manifest.name": "$workflow.manifest.version", + } + + versions_mqc = { + "id": "software_versions", + "section_name": "${workflow.manifest.name} Software Versions", + "section_href": "https://github.com/${workflow.manifest.name}", + "plot_type": "html", + "description": "are collected at run time from the software output.", + "data": _make_versions_html(versions_by_module), + } + + with open("software_versions.yml", "w") as f: + yaml.dump(versions_by_module, f, default_flow_style=False) + with open("software_versions_mqc.yml", "w") as f: + yaml.dump(versions_mqc, f, default_flow_style=False) + + with open("versions.yml", "w") as f: + yaml.dump(versions_this_module, f, default_flow_style=False) + + +if __name__ == "__main__": + main() diff --git a/modules/nf-core/fastqc/main.nf b/modules/nf-core/fastqc/main.nf index 05730368..55c50c87 100644 --- a/modules/nf-core/fastqc/main.nf +++ b/modules/nf-core/fastqc/main.nf @@ -8,7 +8,7 @@ process FASTQC { 'quay.io/biocontainers/fastqc:0.11.9--0' }" input: - tuple val(meta), path(reads) + tuple val(meta), path(reads, stageAs: "?/*") output: tuple val(meta), path("*.html"), emit: html @@ -20,30 +20,16 @@ process FASTQC { script: def args = task.ext.args ?: '' - // Add soft-links to original FastQs for consistent naming in pipeline def prefix = task.ext.prefix ?: "${meta.id}" - if (meta.single_end) { - """ - [ ! -f ${prefix}.fastq.gz ] && ln -s $reads ${prefix}.fastq.gz - fastqc $args --threads $task.cpus ${prefix}.fastq.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fastqc: \$( fastqc --version | sed -e "s/FastQC v//g" ) - END_VERSIONS - """ - } else { - """ - [ ! -f ${prefix}_1.fastq.gz ] && ln -s ${reads[0]} ${prefix}_1.fastq.gz - [ ! -f ${prefix}_2.fastq.gz ] && ln -s ${reads[1]} ${prefix}_2.fastq.gz - fastqc $args --threads $task.cpus ${prefix}_1.fastq.gz ${prefix}_2.fastq.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fastqc: \$( fastqc --version | sed -e "s/FastQC v//g" ) - END_VERSIONS - """ - } + """ + printf "%s\\n" $reads | while read f; do ln -s \$f ${prefix}_\$(basename \$f) ; done + fastqc $args --threads $task.cpus ${prefix}_* + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fastqc: \$( fastqc --version | sed -e "s/FastQC v//g" ) + END_VERSIONS + """ stub: def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index 1e7d6afe..a8159a57 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -1,14 +1,16 @@ process MULTIQC { - label 'process_medium' + label 'process_single' - conda (params.enable_conda ? 'bioconda::multiqc=1.13a' : null) + conda (params.enable_conda ? 'bioconda::multiqc=1.13' : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.13a--pyhdfd78af_1' : - 'quay.io/biocontainers/multiqc:1.13a--pyhdfd78af_1' }" + 'https://depot.galaxyproject.org/singularity/multiqc:1.13--pyhdfd78af_0' : + 'quay.io/biocontainers/multiqc:1.13--pyhdfd78af_0' }" input: path multiqc_files, stageAs: "?/*" - tuple path(multiqc_config), path(multiqc_logo) + path(multiqc_config) + path(extra_multiqc_config) + path(multiqc_logo) output: path "*multiqc_report.html", emit: report @@ -22,11 +24,13 @@ process MULTIQC { script: def args = task.ext.args ?: '' def config = multiqc_config ? "--config $multiqc_config" : '' + def extra_config = extra_multiqc_config ? "--config $extra_multiqc_config" : '' """ multiqc \\ --force \\ - $config \\ $args \\ + $config \\ + $extra_config \\ . cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/multiqc/meta.yml b/modules/nf-core/multiqc/meta.yml index bf3a27fe..ebc29b27 100644 --- a/modules/nf-core/multiqc/meta.yml +++ b/modules/nf-core/multiqc/meta.yml @@ -12,6 +12,7 @@ tools: homepage: https://multiqc.info/ documentation: https://multiqc.info/docs/ licence: ["GPL-3.0-or-later"] + input: - multiqc_files: type: file @@ -19,12 +20,17 @@ input: List of reports / files recognised by MultiQC, for example the html and zip output of FastQC - multiqc_config: type: file - description: Config yml for MultiQC + description: Optional config yml for MultiQC + pattern: "*.{yml,yaml}" + - extra_multiqc_config: + type: file + description: Second optional config yml for MultiQC. Will override common sections in multiqc_config. pattern: "*.{yml,yaml}" - multiqc_logo: type: file - description: Logo file for MultiQC + description: Optional logo file for MultiQC pattern: "*.{png}" + output: - report: type: file @@ -46,3 +52,4 @@ authors: - "@abhi18av" - "@bunop" - "@drpatelh" + - "@jfy133" diff --git a/modules/nf-core/picard/markduplicates/main.nf b/modules/nf-core/picard/markduplicates/main.nf index 4e559fea..d1f3aaa1 100644 --- a/modules/nf-core/picard/markduplicates/main.nf +++ b/modules/nf-core/picard/markduplicates/main.nf @@ -9,6 +9,8 @@ process PICARD_MARKDUPLICATES { input: tuple val(meta), path(bam) + path fasta + path fai output: tuple val(meta), path("*.bam") , emit: bam @@ -35,6 +37,7 @@ process PICARD_MARKDUPLICATES { $args \\ --INPUT $bam \\ --OUTPUT ${prefix}.bam \\ + --REFERENCE_SEQUENCE $fasta \\ --METRICS_FILE ${prefix}.MarkDuplicates.metrics.txt cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/picard/markduplicates/meta.yml b/modules/nf-core/picard/markduplicates/meta.yml index 842817bc..3f2357bb 100644 --- a/modules/nf-core/picard/markduplicates/meta.yml +++ b/modules/nf-core/picard/markduplicates/meta.yml @@ -24,7 +24,15 @@ input: - bam: type: file description: BAM file - pattern: "*.{bam}" + pattern: "*.{bam,cram,sam}" + - fasta: + type: file + description: Reference genome fasta file + pattern: "*.{fasta,fa}" + - fai: + type: file + description: Reference genome fasta index + pattern: "*.{fai}" output: - meta: type: map diff --git a/modules/nf-core/qualimap/rnaseq/main.nf b/modules/nf-core/qualimap/rnaseq/main.nf index bd4503b2..38293d27 100644 --- a/modules/nf-core/qualimap/rnaseq/main.nf +++ b/modules/nf-core/qualimap/rnaseq/main.nf @@ -20,7 +20,7 @@ process QUALIMAP_RNASEQ { script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + prefix = task.ext.prefix ?: "${meta.id}" def paired_end = meta.single_end ? '' : '-pe' def memory = task.memory.toGiga() + "G" @@ -51,7 +51,7 @@ process QUALIMAP_RNASEQ { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + prefix = task.ext.prefix ?: "${meta.id}" """ mkdir ${prefix} diff --git a/modules/nf-core/samtools/faidx/main.nf b/modules/nf-core/samtools/faidx/main.nf index 11e688b3..ef940db2 100644 --- a/modules/nf-core/samtools/faidx/main.nf +++ b/modules/nf-core/samtools/faidx/main.nf @@ -1,6 +1,6 @@ process SAMTOOLS_FAIDX { tag "$fasta" - label 'process_low' + label 'process_single' conda (params.enable_conda ? "bioconda::samtools=1.15.1" : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? @@ -12,6 +12,7 @@ process SAMTOOLS_FAIDX { output: tuple val(meta), path ("*.fai"), emit: fai + tuple val(meta), path ("*.gzi"), emit: gzi, optional: true path "versions.yml" , emit: versions when: diff --git a/modules/nf-core/samtools/faidx/meta.yml b/modules/nf-core/samtools/faidx/meta.yml index e9767764..fe2fe9a1 100644 --- a/modules/nf-core/samtools/faidx/meta.yml +++ b/modules/nf-core/samtools/faidx/meta.yml @@ -33,6 +33,10 @@ output: type: file description: FASTA index file pattern: "*.{fai}" + - gzi: + type: file + description: Optional gzip index file for compressed inputs + pattern: "*.gzi" - versions: type: file description: File containing software versions diff --git a/modules/nf-core/samtools/sort/main.nf b/modules/nf-core/samtools/sort/main.nf index b4fc1cbe..ab7f1cca 100644 --- a/modules/nf-core/samtools/sort/main.nf +++ b/modules/nf-core/samtools/sort/main.nf @@ -12,6 +12,7 @@ process SAMTOOLS_SORT { output: tuple val(meta), path("*.bam"), emit: bam + tuple val(meta), path("*.csi"), emit: csi, optional: true path "versions.yml" , emit: versions when: diff --git a/modules/nf-core/samtools/sort/meta.yml b/modules/nf-core/samtools/sort/meta.yml index a820c55a..09289751 100644 --- a/modules/nf-core/samtools/sort/meta.yml +++ b/modules/nf-core/samtools/sort/meta.yml @@ -39,6 +39,10 @@ output: type: file description: File containing software versions pattern: "versions.yml" + - csi: + type: file + description: BAM index file (optional) + pattern: "*.csi" authors: - "@drpatelh" - "@ewels" diff --git a/modules/nf-core/samtools/view/main.nf b/modules/nf-core/samtools/view/main.nf index 55194e88..b2f5c678 100644 --- a/modules/nf-core/samtools/view/main.nf +++ b/modules/nf-core/samtools/view/main.nf @@ -1,6 +1,6 @@ process SAMTOOLS_VIEW { tag "$meta.id" - label 'process_medium' + label 'process_low' conda (params.enable_conda ? "bioconda::samtools=1.15.1" : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? @@ -10,11 +10,16 @@ process SAMTOOLS_VIEW { input: tuple val(meta), path(input), path(index) path fasta + path qname output: - tuple val(meta), path("*.bam") , emit: bam , optional: true - tuple val(meta), path("*.cram"), emit: cram, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*.bam"), emit: bam, optional: true + tuple val(meta), path("*.cram"), emit: cram, optional: true + tuple val(meta), path("*.sam"), emit: sam, optional: true + tuple val(meta), path("*.bai"), emit: bai, optional: true + tuple val(meta), path("*.csi"), emit: csi, optional: true + tuple val(meta), path("*.crai"), emit: crai, optional: true + path "versions.yml", emit: versions when: task.ext.when == null || task.ext.when @@ -23,18 +28,23 @@ process SAMTOOLS_VIEW { def args = task.ext.args ?: '' def args2 = task.ext.args2 ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def reference = fasta ? "--reference ${fasta} -C" : "" - def file_type = input.getExtension() + def reference = fasta ? "--reference ${fasta}" : "" + def readnames = qname ? "--qname-file ${qname}": "" + def file_type = args.contains("--output-fmt sam") ? "sam" : + args.contains("--output-fmt bam") ? "bam" : + args.contains("--output-fmt cram") ? "cram" : + input.getExtension() if ("$input" == "${prefix}.${file_type}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" """ samtools \\ view \\ --threads ${task.cpus-1} \\ ${reference} \\ + ${readnames} \\ $args \\ + -o ${prefix}.${file_type} \\ $input \\ - $args2 \\ - > ${prefix}.${file_type} + $args2 cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/samtools/view/meta.yml b/modules/nf-core/samtools/view/meta.yml index a8b43ecc..a52e4f8d 100644 --- a/modules/nf-core/samtools/view/meta.yml +++ b/modules/nf-core/samtools/view/meta.yml @@ -33,6 +33,10 @@ input: type: optional file description: Reference file the CRAM was created with pattern: "*.{fasta,fa}" + - qname: + type: file + description: Optional file with read names to output only select alignments + pattern: "*.{txt,list}" output: - meta: type: map @@ -41,12 +45,29 @@ output: e.g. [ id:'test', single_end:false ] - bam: type: file - description: filtered/converted BAM/SAM file - pattern: "*.{bam,sam}" + description: optional filtered/converted BAM file + pattern: "*.{bam}" - cram: type: file - description: filtered/converted CRAM file - pattern: "*.cram" + description: optional filtered/converted CRAM file + pattern: "*.{cram}" + - sam: + type: file + description: optional filtered/converted SAM file + pattern: "*.{sam}" + # bai, csi, and crai are created with `--write-index` + - bai: + type: file + description: optional BAM file index + pattern: "*.{bai}" + - csi: + type: file + description: optional tabix BAM file index + pattern: "*.{csi}" + - crai: + type: file + description: optional CRAM file index + pattern: "*.{crai}" - versions: type: file description: File containing software versions @@ -55,3 +76,4 @@ authors: - "@drpatelh" - "@joseespinosa" - "@FriederikeHanssen" + - "@priyanka-surana" From 95bd452bf7b06602334ae599a8abc644158b82da Mon Sep 17 00:00:00 2001 From: Matthias De Smet Date: Fri, 28 Oct 2022 08:57:39 +0000 Subject: [PATCH 060/176] fix module imports --- subworkflows/local/arriba_workflow.nf | 8 ++++---- subworkflows/local/qc_workflow.nf | 6 +++--- subworkflows/local/squid_workflow.nf | 8 ++++---- subworkflows/local/starfusion_workflow.nf | 2 +- subworkflows/local/trim_workflow.nf | 2 +- workflows/build_references.nf | 4 ++-- workflows/rnafusion.nf | 8 ++++---- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/subworkflows/local/arriba_workflow.nf b/subworkflows/local/arriba_workflow.nf index ab9c7748..4eb23ff3 100644 --- a/subworkflows/local/arriba_workflow.nf +++ b/subworkflows/local/arriba_workflow.nf @@ -1,8 +1,8 @@ -include { ARRIBA } from '../../modules/nf-core/modules/arriba/main' +include { ARRIBA } from '../../modules/nf-core/arriba/main' include { ARRIBA_VISUALISATION } from '../../modules/local/arriba/visualisation/main' -include { SAMTOOLS_SORT as SAMTOOLS_SORT_FOR_ARRIBA } from '../../modules/nf-core/modules/samtools/sort/main' -include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_ARRIBA} from '../../modules/nf-core/modules/samtools/index/main' -include { STAR_ALIGN as STAR_FOR_ARRIBA } from '../../modules/nf-core/modules/star/align/main' +include { SAMTOOLS_SORT as SAMTOOLS_SORT_FOR_ARRIBA } from '../../modules/nf-core/samtools/sort/main' +include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_ARRIBA} from '../../modules/nf-core/samtools/index/main' +include { STAR_ALIGN as STAR_FOR_ARRIBA } from '../../modules/nf-core/star/align/main' workflow ARRIBA_WORKFLOW { diff --git a/subworkflows/local/qc_workflow.nf b/subworkflows/local/qc_workflow.nf index e637f2f2..1349c5f2 100644 --- a/subworkflows/local/qc_workflow.nf +++ b/subworkflows/local/qc_workflow.nf @@ -2,10 +2,10 @@ // Check input samplesheet and get read channels // -include { QUALIMAP_RNASEQ } from '../../modules/nf-core/modules/qualimap/rnaseq/main' -include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_QC } from '../../modules/nf-core/modules/samtools/index/main' +include { QUALIMAP_RNASEQ } from '../../modules/nf-core/qualimap/rnaseq/main' +include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_QC } from '../../modules/nf-core/samtools/index/main' include { PICARD_COLLECTRNASEQMETRICS } from '../../modules/local/picard/collectrnaseqmetrics/main' -include { PICARD_MARKDUPLICATES } from '../../modules/nf-core/modules/picard/markduplicates/main' +include { PICARD_MARKDUPLICATES } from '../../modules/nf-core/picard/markduplicates/main' workflow QC_WORKFLOW { take: diff --git a/subworkflows/local/squid_workflow.nf b/subworkflows/local/squid_workflow.nf index 4d4485e7..e73a6d9c 100644 --- a/subworkflows/local/squid_workflow.nf +++ b/subworkflows/local/squid_workflow.nf @@ -1,9 +1,9 @@ -include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_SQUID} from '../../modules/nf-core/modules/samtools/index/main' -include { SAMTOOLS_SORT as SAMTOOLS_SORT_FOR_SQUID } from '../../modules/nf-core/modules/samtools/sort/main' -include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_SQUID } from '../../modules/nf-core/modules/samtools/view/main' +include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_SQUID} from '../../modules/nf-core/samtools/index/main' +include { SAMTOOLS_SORT as SAMTOOLS_SORT_FOR_SQUID } from '../../modules/nf-core/samtools/sort/main' +include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_SQUID } from '../../modules/nf-core/samtools/view/main' include { SQUID } from '../../modules/local/squid/detect/main' include { SQUID_ANNOTATE } from '../../modules/local/squid/annotate/main' -include { STAR_ALIGN as STAR_FOR_SQUID } from '../../modules/nf-core/modules/star/align/main' +include { STAR_ALIGN as STAR_FOR_SQUID } from '../../modules/nf-core/star/align/main' workflow SQUID_WORKFLOW { diff --git a/subworkflows/local/starfusion_workflow.nf b/subworkflows/local/starfusion_workflow.nf index 46102f82..69cf16b2 100644 --- a/subworkflows/local/starfusion_workflow.nf +++ b/subworkflows/local/starfusion_workflow.nf @@ -1,4 +1,4 @@ -include { STAR_ALIGN as STAR_FOR_STARFUSION } from '../../modules/nf-core/modules/star/align/main' +include { STAR_ALIGN as STAR_FOR_STARFUSION } from '../../modules/nf-core/star/align/main' include { STARFUSION } from '../../modules/local/starfusion/detect/main' workflow STARFUSION_WORKFLOW { diff --git a/subworkflows/local/trim_workflow.nf b/subworkflows/local/trim_workflow.nf index 97835853..c4a01971 100644 --- a/subworkflows/local/trim_workflow.nf +++ b/subworkflows/local/trim_workflow.nf @@ -1,5 +1,5 @@ include { REFORMAT } from '../../modules/local/reformat/main' -include { FASTQC as FASTQC_FOR_TRIM } from '../../modules/nf-core/modules/fastqc/main' +include { FASTQC as FASTQC_FOR_TRIM } from '../../modules/nf-core/fastqc/main' workflow TRIM_WORKFLOW { take: diff --git a/workflows/build_references.nf b/workflows/build_references.nf index 5910c15c..3f55e2aa 100644 --- a/workflows/build_references.nf +++ b/workflows/build_references.nf @@ -17,8 +17,8 @@ include { GTF_TO_REFFLAT } from '../modules/local/uscs/custom_g ======================================================================================== */ -include { STAR_GENOMEGENERATE } from '../modules/nf-core/modules/star/genomegenerate/main' -include { KALLISTO_INDEX as PIZZLY_INDEX } from '../modules/nf-core/modules/kallisto/index/main' +include { STAR_GENOMEGENERATE } from '../modules/nf-core/star/genomegenerate/main' +include { KALLISTO_INDEX as PIZZLY_INDEX } from '../modules/nf-core/kallisto/index/main' /* ======================================================================================== diff --git a/workflows/rnafusion.nf b/workflows/rnafusion.nf index ad7c6a41..01da727b 100644 --- a/workflows/rnafusion.nf +++ b/workflows/rnafusion.nf @@ -80,10 +80,10 @@ include { FUSIONREPORT_WORKFLOW } from '../subworkflows/local/fusionre // // MODULE: Installed directly from nf-core/modules // -include { CAT_FASTQ } from '../modules/nf-core/modules/cat/fastq/main' -include { FASTQC } from '../modules/nf-core/modules/fastqc/main' -include { MULTIQC } from '../modules/nf-core/modules/multiqc/main' -include { CUSTOM_DUMPSOFTWAREVERSIONS } from '../modules/nf-core/modules/custom/dumpsoftwareversions/main' +include { CAT_FASTQ } from '../modules/nf-core/cat/fastq/main' +include { FASTQC } from '../modules/nf-core/fastqc/main' +include { MULTIQC } from '../modules/nf-core/multiqc/main' +include { CUSTOM_DUMPSOFTWAREVERSIONS } from '../modules/nf-core/custom/dumpsoftwareversions/main' From c3488279061fc5e321b4c975b22bfa72e99394bb Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Sun, 30 Oct 2022 09:19:02 +0100 Subject: [PATCH 061/176] solving merge conflicts --- modules/nf-core/custom/dumpsoftwareversions/main.nf | 7 ------- modules/nf-core/multiqc/meta.yml | 9 --------- nextflow_schema.json | 6 ------ subworkflows/local/arriba_workflow.nf | 8 ++++---- subworkflows/local/qc_workflow.nf | 6 +++--- subworkflows/local/squid_workflow.nf | 8 ++++---- subworkflows/local/starfusion_workflow.nf | 2 +- subworkflows/local/trim_workflow.nf | 2 +- workflows/build_references.nf | 4 ++-- workflows/rnafusion.nf | 9 +-------- 10 files changed, 16 insertions(+), 45 deletions(-) diff --git a/modules/nf-core/custom/dumpsoftwareversions/main.nf b/modules/nf-core/custom/dumpsoftwareversions/main.nf index df549560..cebb6e05 100644 --- a/modules/nf-core/custom/dumpsoftwareversions/main.nf +++ b/modules/nf-core/custom/dumpsoftwareversions/main.nf @@ -2,17 +2,10 @@ process CUSTOM_DUMPSOFTWAREVERSIONS { label 'process_single' // Requires `pyyaml` which does not have a dedicated container but is in the MultiQC container -<<<<<<< HEAD:modules/nf-core/custom/dumpsoftwareversions/main.nf conda (params.enable_conda ? 'bioconda::multiqc=1.13' : null) 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' }" -======= - conda (params.enable_conda ? 'bioconda::multiqc=1.13a' : null) - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.13a--pyhdfd78af_1' : - 'quay.io/biocontainers/multiqc:1.13a--pyhdfd78af_1' }" ->>>>>>> dev:modules/nf-core/modules/custom/dumpsoftwareversions/main.nf input: path versions diff --git a/modules/nf-core/multiqc/meta.yml b/modules/nf-core/multiqc/meta.yml index 36345712..ebc29b27 100644 --- a/modules/nf-core/multiqc/meta.yml +++ b/modules/nf-core/multiqc/meta.yml @@ -20,7 +20,6 @@ input: List of reports / files recognised by MultiQC, for example the html and zip output of FastQC - multiqc_config: type: file -<<<<<<< HEAD:modules/nf-core/multiqc/meta.yml description: Optional config yml for MultiQC pattern: "*.{yml,yaml}" - extra_multiqc_config: @@ -32,14 +31,6 @@ input: description: Optional logo file for MultiQC pattern: "*.{png}" -======= - description: Config yml for MultiQC - pattern: "*.{yml,yaml}" - - multiqc_logo: - type: file - description: Logo file for MultiQC - pattern: "*.{png}" ->>>>>>> dev:modules/nf-core/modules/multiqc/meta.yml output: - report: type: file diff --git a/nextflow_schema.json b/nextflow_schema.json index d8c3f342..cae74fd8 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -503,12 +503,6 @@ "hidden": true, "fa_icon": "fas fa-bacon" }, - "singularity_pull_docker_container": { - "type": "boolean", - "description": "Use to pull docker containers to run with singularity", - "hidden": true, - "fa_icon": "fas fa-bacon" - }, "seq_center": { "type": "string", "description": "Sequencing center", diff --git a/subworkflows/local/arriba_workflow.nf b/subworkflows/local/arriba_workflow.nf index 789ef179..a4472d7d 100644 --- a/subworkflows/local/arriba_workflow.nf +++ b/subworkflows/local/arriba_workflow.nf @@ -1,10 +1,10 @@ -include { ARRIBA } from '../../modules/nf-core/modules/arriba/main' +include { ARRIBA } from '../../modules/nf-core/arriba/main' include { ARRIBA_VISUALISATION } from '../../modules/local/arriba/visualisation/main' include { GET_META } from '../../modules/local/getmeta/main' include { GET_PATH as GET_PATH_ARRIBA_FAIL } from '../../modules/local/getpath/main' -include { SAMTOOLS_SORT as SAMTOOLS_SORT_FOR_ARRIBA } from '../../modules/nf-core/modules/samtools/sort/main' -include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_ARRIBA} from '../../modules/nf-core/modules/samtools/index/main' -include { STAR_ALIGN as STAR_FOR_ARRIBA } from '../../modules/nf-core/modules/star/align/main' +include { SAMTOOLS_SORT as SAMTOOLS_SORT_FOR_ARRIBA } from '../../modules/nf-core/samtools/sort/main' +include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_ARRIBA} from '../../modules/nf-core/samtools/index/main' +include { STAR_ALIGN as STAR_FOR_ARRIBA } from '../../modules/nf-core/star/align/main' workflow ARRIBA_WORKFLOW { diff --git a/subworkflows/local/qc_workflow.nf b/subworkflows/local/qc_workflow.nf index e637f2f2..1349c5f2 100644 --- a/subworkflows/local/qc_workflow.nf +++ b/subworkflows/local/qc_workflow.nf @@ -2,10 +2,10 @@ // Check input samplesheet and get read channels // -include { QUALIMAP_RNASEQ } from '../../modules/nf-core/modules/qualimap/rnaseq/main' -include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_QC } from '../../modules/nf-core/modules/samtools/index/main' +include { QUALIMAP_RNASEQ } from '../../modules/nf-core/qualimap/rnaseq/main' +include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_QC } from '../../modules/nf-core/samtools/index/main' include { PICARD_COLLECTRNASEQMETRICS } from '../../modules/local/picard/collectrnaseqmetrics/main' -include { PICARD_MARKDUPLICATES } from '../../modules/nf-core/modules/picard/markduplicates/main' +include { PICARD_MARKDUPLICATES } from '../../modules/nf-core/picard/markduplicates/main' workflow QC_WORKFLOW { take: diff --git a/subworkflows/local/squid_workflow.nf b/subworkflows/local/squid_workflow.nf index 03e540d1..35ac89c8 100644 --- a/subworkflows/local/squid_workflow.nf +++ b/subworkflows/local/squid_workflow.nf @@ -1,10 +1,10 @@ include { GET_META } from '../../modules/local/getmeta/main' -include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_SQUID} from '../../modules/nf-core/modules/samtools/index/main' -include { SAMTOOLS_SORT as SAMTOOLS_SORT_FOR_SQUID } from '../../modules/nf-core/modules/samtools/sort/main' -include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_SQUID } from '../../modules/nf-core/modules/samtools/view/main' +include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_SQUID} from '../../modules/nf-core/samtools/index/main' +include { SAMTOOLS_SORT as SAMTOOLS_SORT_FOR_SQUID } from '../../modules/nf-core/samtools/sort/main' +include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_SQUID } from '../../modules/nf-core/samtools/view/main' include { SQUID } from '../../modules/local/squid/detect/main' include { SQUID_ANNOTATE } from '../../modules/local/squid/annotate/main' -include { STAR_ALIGN as STAR_FOR_SQUID } from '../../modules/nf-core/modules/star/align/main' +include { STAR_ALIGN as STAR_FOR_SQUID } from '../../modules/nf-core/star/align/main' workflow SQUID_WORKFLOW { diff --git a/subworkflows/local/starfusion_workflow.nf b/subworkflows/local/starfusion_workflow.nf index 5f4e4a16..a24195ce 100644 --- a/subworkflows/local/starfusion_workflow.nf +++ b/subworkflows/local/starfusion_workflow.nf @@ -1,4 +1,4 @@ -include { STAR_ALIGN as STAR_FOR_STARFUSION } from '../../modules/nf-core/modules/star/align/main' +include { STAR_ALIGN as STAR_FOR_STARFUSION } from '../../modules/nf-core/star/align/main' include { STARFUSION } from '../../modules/local/starfusion/detect/main' include { GET_META } from '../../modules/local/getmeta/main' diff --git a/subworkflows/local/trim_workflow.nf b/subworkflows/local/trim_workflow.nf index 97835853..c4a01971 100644 --- a/subworkflows/local/trim_workflow.nf +++ b/subworkflows/local/trim_workflow.nf @@ -1,5 +1,5 @@ include { REFORMAT } from '../../modules/local/reformat/main' -include { FASTQC as FASTQC_FOR_TRIM } from '../../modules/nf-core/modules/fastqc/main' +include { FASTQC as FASTQC_FOR_TRIM } from '../../modules/nf-core/fastqc/main' workflow TRIM_WORKFLOW { take: diff --git a/workflows/build_references.nf b/workflows/build_references.nf index 5910c15c..3f55e2aa 100644 --- a/workflows/build_references.nf +++ b/workflows/build_references.nf @@ -17,8 +17,8 @@ include { GTF_TO_REFFLAT } from '../modules/local/uscs/custom_g ======================================================================================== */ -include { STAR_GENOMEGENERATE } from '../modules/nf-core/modules/star/genomegenerate/main' -include { KALLISTO_INDEX as PIZZLY_INDEX } from '../modules/nf-core/modules/kallisto/index/main' +include { STAR_GENOMEGENERATE } from '../modules/nf-core/star/genomegenerate/main' +include { KALLISTO_INDEX as PIZZLY_INDEX } from '../modules/nf-core/kallisto/index/main' /* ======================================================================================== diff --git a/workflows/rnafusion.nf b/workflows/rnafusion.nf index 0421624f..73736eb1 100644 --- a/workflows/rnafusion.nf +++ b/workflows/rnafusion.nf @@ -82,17 +82,10 @@ include { FUSIONREPORT_WORKFLOW } from '../subworkflows/local/fusionre // // MODULE: Installed directly from nf-core/modules // -<<<<<<< HEAD +include { CAT_FASTQ } from '../modules/nf-core/cat/fastq/main' include { FASTQC } from '../modules/nf-core/fastqc/main' include { MULTIQC } from '../modules/nf-core/multiqc/main' include { CUSTOM_DUMPSOFTWAREVERSIONS } from '../modules/nf-core/custom/dumpsoftwareversions/main' -======= -include { CAT_FASTQ } from '../modules/nf-core/modules/cat/fastq/main' -include { FASTQC } from '../modules/nf-core/modules/fastqc/main' -include { MULTIQC } from '../modules/nf-core/modules/multiqc/main' -include { CUSTOM_DUMPSOFTWAREVERSIONS } from '../modules/nf-core/modules/custom/dumpsoftwareversions/main' ->>>>>>> dev - From 4dcfa91f181cbb45bd05e8593c93c5e3bda0bfd8 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Sun, 30 Oct 2022 09:41:55 +0100 Subject: [PATCH 062/176] update modules --- assets/methods_description_template.yml | 2 - modules.json | 28 ++--- modules/local/samplesheet_check.nf | 10 +- modules/nf-core/cat/fastq/main.nf | 10 +- .../templates/dumpsoftwareversions.py | 102 ++++++++++-------- modules/nf-core/fastqc/main.nf | 34 ++---- modules/nf-core/picard/markduplicates/main.nf | 3 + .../nf-core/picard/markduplicates/meta.yml | 10 +- modules/nf-core/qualimap/rnaseq/main.nf | 4 +- modules/nf-core/samtools/faidx/main.nf | 3 +- modules/nf-core/samtools/faidx/meta.yml | 4 + modules/nf-core/samtools/sort/main.nf | 1 + modules/nf-core/samtools/sort/meta.yml | 4 + modules/nf-core/samtools/view/main.nf | 26 +++-- modules/nf-core/samtools/view/meta.yml | 30 +++++- 15 files changed, 158 insertions(+), 113 deletions(-) mode change 100644 => 100755 modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py diff --git a/assets/methods_description_template.yml b/assets/methods_description_template.yml index 016b3d45..8efa2896 100644 --- a/assets/methods_description_template.yml +++ b/assets/methods_description_template.yml @@ -3,8 +3,6 @@ description: "Suggested text and references to use when describing pipeline usag section_name: "nf-core/rnafusion Methods Description" section_href: "https://github.com/nf-core/rnafusion" plot_type: "html" -## TODO nf-core: Update the HTML below to your prefered methods description, e.g. add publication citation for this pipeline -## You inject any metadata in the Nextflow '${workflow}' object data: |

    Methods

    Data was processed using nf-core/rnafusion v${workflow.manifest.version} ${doi_text} of the nf-core collection of workflows (Ewels et al., 2020).

    diff --git a/modules.json b/modules.json index 0c48aa3a..0243832a 100644 --- a/modules.json +++ b/modules.json @@ -7,23 +7,23 @@ "nf-core": { "arriba": { "branch": "master", - "git_sha": "80746895e214a4d55570f90554164b19476f4114" + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" }, "cat/fastq": { "branch": "master", - "git_sha": "b034029b59b1198075da8019074bc02051a6100e" + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" }, "custom/dumpsoftwareversions": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "8022c68e7403eecbd8ba9c49496f69f8c49d50f0" }, "fastqc": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "f6a11408536fbee6cbea1f5977605011873de3ca" }, "kallisto/index": { "branch": "master", - "git_sha": "479e0638d14a3e9e9dd96a5b74b3b5682e8a8b43" + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" }, "multiqc": { "branch": "master", @@ -31,39 +31,39 @@ }, "picard/collectwgsmetrics": { "branch": "master", - "git_sha": "ac1c6ad7104c7863842a322a8cf74f4fee1d20b4" + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" }, "picard/markduplicates": { "branch": "master", - "git_sha": "682f789f93070bd047868300dd018faf3d434e7c" + "git_sha": "eca65aa4a5e2e192ac44d6962c8f9260f314ffb8" }, "qualimap/rnaseq": { "branch": "master", - "git_sha": "53108b6b51d4e968e5b1cc9b07ddb6559cb6d43d" + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" }, "samtools/faidx": { "branch": "master", - "git_sha": "ce06694af8ca2f7453206aa974c2c9a2b99ec093" + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" }, "samtools/index": { "branch": "master", - "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773" + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" }, "samtools/sort": { "branch": "master", - "git_sha": "897c33d5da084b61109500ee44c01da2d3e4e773" + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" }, "samtools/view": { "branch": "master", - "git_sha": "6b64f9cb6c3dd3577931cc3cd032d6fb730000ce" + "git_sha": "202683bfc98ddecdd456ea73268e330bca2e5c5a" }, "star/align": { "branch": "master", - "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba" + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" }, "star/genomegenerate": { "branch": "master", - "git_sha": "cd22a76c78b09f7837a5a75642774a4bf48c92ba" + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" } } } diff --git a/modules/local/samplesheet_check.nf b/modules/local/samplesheet_check.nf index e8737886..92b8ec63 100644 --- a/modules/local/samplesheet_check.nf +++ b/modules/local/samplesheet_check.nf @@ -2,12 +2,10 @@ process SAMPLESHEET_CHECK { tag "$samplesheet" label 'process_low' - conda (params.enable_conda ? "conda-forge::python=3.8.3" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/python:3.8.3" - } else { - container "quay.io/biocontainers/python:3.8.3" - } + conda (params.enable_conda ? "conda-forge::python=3.9.5" : null) + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/python:3.9--1' : + 'quay.io/biocontainers/python:3.9--1' }" input: path samplesheet diff --git a/modules/nf-core/cat/fastq/main.nf b/modules/nf-core/cat/fastq/main.nf index d275f19c..4fa365d3 100644 --- a/modules/nf-core/cat/fastq/main.nf +++ b/modules/nf-core/cat/fastq/main.nf @@ -1,6 +1,6 @@ process CAT_FASTQ { tag "$meta.id" - label 'process_low' + label 'process_single' conda (params.enable_conda ? "conda-forge::sed=4.7" : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? @@ -20,9 +20,9 @@ process CAT_FASTQ { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def readList = reads.collect{ it.toString() } + def readList = reads instanceof List ? reads.collect{ it.toString() } : [reads.toString()] if (meta.single_end) { - if (readList.size > 1) { + if (readList.size >= 1) { """ cat ${readList.join(' ')} > ${prefix}.merged.fastq.gz @@ -33,7 +33,7 @@ process CAT_FASTQ { """ } } else { - if (readList.size > 2) { + if (readList.size >= 2) { def read1 = [] def read2 = [] readList.eachWithIndex{ v, ix -> ( ix & 1 ? read2 : read1 ) << v } @@ -51,7 +51,7 @@ process CAT_FASTQ { stub: def prefix = task.ext.prefix ?: "${meta.id}" - def readList = reads.collect{ it.toString() } + def readList = reads instanceof List ? reads.collect{ it.toString() } : [reads.toString()] if (meta.single_end) { if (readList.size > 1) { """ diff --git a/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py b/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py old mode 100644 new mode 100755 index 787bdb7b..da033408 --- a/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py +++ b/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py @@ -1,12 +1,16 @@ #!/usr/bin/env python -import platform -from textwrap import dedent + +"""Provide functions to merge multiple versions.yml files.""" + import yaml +import platform +from textwrap import dedent def _make_versions_html(versions): + """Generate a tabular HTML output of all versions for MultiQC.""" html = [ dedent( """\\ @@ -45,47 +49,53 @@ def _make_versions_html(versions): return "\\n".join(html) -versions_this_module = {} -versions_this_module["${task.process}"] = { - "python": platform.python_version(), - "yaml": yaml.__version__, -} - -with open("$versions") as f: - versions_by_process = yaml.load(f, Loader=yaml.BaseLoader) | versions_this_module - -# aggregate versions by the module name (derived from fully-qualified process name) -versions_by_module = {} -for process, process_versions in versions_by_process.items(): - module = process.split(":")[-1] - try: - if versions_by_module[module] != process_versions: - raise AssertionError( - "We assume that software versions are the same between all modules. " - "If you see this error-message it means you discovered an edge-case " - "and should open an issue in nf-core/tools. " - ) - except KeyError: - versions_by_module[module] = process_versions - -versions_by_module["Workflow"] = { - "Nextflow": "$workflow.nextflow.version", - "$workflow.manifest.name": "$workflow.manifest.version", -} - -versions_mqc = { - "id": "software_versions", - "section_name": "${workflow.manifest.name} Software Versions", - "section_href": "https://github.com/${workflow.manifest.name}", - "plot_type": "html", - "description": "are collected at run time from the software output.", - "data": _make_versions_html(versions_by_module), -} - -with open("software_versions.yml", "w") as f: - yaml.dump(versions_by_module, f, default_flow_style=False) -with open("software_versions_mqc.yml", "w") as f: - yaml.dump(versions_mqc, f, default_flow_style=False) - -with open("versions.yml", "w") as f: - yaml.dump(versions_this_module, f, default_flow_style=False) +def main(): + """Load all version files and generate merged output.""" + versions_this_module = {} + versions_this_module["${task.process}"] = { + "python": platform.python_version(), + "yaml": yaml.__version__, + } + + with open("$versions") as f: + versions_by_process = yaml.load(f, Loader=yaml.BaseLoader) | versions_this_module + + # aggregate versions by the module name (derived from fully-qualified process name) + versions_by_module = {} + for process, process_versions in versions_by_process.items(): + module = process.split(":")[-1] + try: + if versions_by_module[module] != process_versions: + raise AssertionError( + "We assume that software versions are the same between all modules. " + "If you see this error-message it means you discovered an edge-case " + "and should open an issue in nf-core/tools. " + ) + except KeyError: + versions_by_module[module] = process_versions + + versions_by_module["Workflow"] = { + "Nextflow": "$workflow.nextflow.version", + "$workflow.manifest.name": "$workflow.manifest.version", + } + + versions_mqc = { + "id": "software_versions", + "section_name": "${workflow.manifest.name} Software Versions", + "section_href": "https://github.com/${workflow.manifest.name}", + "plot_type": "html", + "description": "are collected at run time from the software output.", + "data": _make_versions_html(versions_by_module), + } + + with open("software_versions.yml", "w") as f: + yaml.dump(versions_by_module, f, default_flow_style=False) + with open("software_versions_mqc.yml", "w") as f: + yaml.dump(versions_mqc, f, default_flow_style=False) + + with open("versions.yml", "w") as f: + yaml.dump(versions_this_module, f, default_flow_style=False) + + +if __name__ == "__main__": + main() diff --git a/modules/nf-core/fastqc/main.nf b/modules/nf-core/fastqc/main.nf index 05730368..55c50c87 100644 --- a/modules/nf-core/fastqc/main.nf +++ b/modules/nf-core/fastqc/main.nf @@ -8,7 +8,7 @@ process FASTQC { 'quay.io/biocontainers/fastqc:0.11.9--0' }" input: - tuple val(meta), path(reads) + tuple val(meta), path(reads, stageAs: "?/*") output: tuple val(meta), path("*.html"), emit: html @@ -20,30 +20,16 @@ process FASTQC { script: def args = task.ext.args ?: '' - // Add soft-links to original FastQs for consistent naming in pipeline def prefix = task.ext.prefix ?: "${meta.id}" - if (meta.single_end) { - """ - [ ! -f ${prefix}.fastq.gz ] && ln -s $reads ${prefix}.fastq.gz - fastqc $args --threads $task.cpus ${prefix}.fastq.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fastqc: \$( fastqc --version | sed -e "s/FastQC v//g" ) - END_VERSIONS - """ - } else { - """ - [ ! -f ${prefix}_1.fastq.gz ] && ln -s ${reads[0]} ${prefix}_1.fastq.gz - [ ! -f ${prefix}_2.fastq.gz ] && ln -s ${reads[1]} ${prefix}_2.fastq.gz - fastqc $args --threads $task.cpus ${prefix}_1.fastq.gz ${prefix}_2.fastq.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fastqc: \$( fastqc --version | sed -e "s/FastQC v//g" ) - END_VERSIONS - """ - } + """ + printf "%s\\n" $reads | while read f; do ln -s \$f ${prefix}_\$(basename \$f) ; done + fastqc $args --threads $task.cpus ${prefix}_* + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fastqc: \$( fastqc --version | sed -e "s/FastQC v//g" ) + END_VERSIONS + """ stub: def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/picard/markduplicates/main.nf b/modules/nf-core/picard/markduplicates/main.nf index 4e559fea..d1f3aaa1 100644 --- a/modules/nf-core/picard/markduplicates/main.nf +++ b/modules/nf-core/picard/markduplicates/main.nf @@ -9,6 +9,8 @@ process PICARD_MARKDUPLICATES { input: tuple val(meta), path(bam) + path fasta + path fai output: tuple val(meta), path("*.bam") , emit: bam @@ -35,6 +37,7 @@ process PICARD_MARKDUPLICATES { $args \\ --INPUT $bam \\ --OUTPUT ${prefix}.bam \\ + --REFERENCE_SEQUENCE $fasta \\ --METRICS_FILE ${prefix}.MarkDuplicates.metrics.txt cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/picard/markduplicates/meta.yml b/modules/nf-core/picard/markduplicates/meta.yml index 842817bc..3f2357bb 100644 --- a/modules/nf-core/picard/markduplicates/meta.yml +++ b/modules/nf-core/picard/markduplicates/meta.yml @@ -24,7 +24,15 @@ input: - bam: type: file description: BAM file - pattern: "*.{bam}" + pattern: "*.{bam,cram,sam}" + - fasta: + type: file + description: Reference genome fasta file + pattern: "*.{fasta,fa}" + - fai: + type: file + description: Reference genome fasta index + pattern: "*.{fai}" output: - meta: type: map diff --git a/modules/nf-core/qualimap/rnaseq/main.nf b/modules/nf-core/qualimap/rnaseq/main.nf index bd4503b2..38293d27 100644 --- a/modules/nf-core/qualimap/rnaseq/main.nf +++ b/modules/nf-core/qualimap/rnaseq/main.nf @@ -20,7 +20,7 @@ process QUALIMAP_RNASEQ { script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + prefix = task.ext.prefix ?: "${meta.id}" def paired_end = meta.single_end ? '' : '-pe' def memory = task.memory.toGiga() + "G" @@ -51,7 +51,7 @@ process QUALIMAP_RNASEQ { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + prefix = task.ext.prefix ?: "${meta.id}" """ mkdir ${prefix} diff --git a/modules/nf-core/samtools/faidx/main.nf b/modules/nf-core/samtools/faidx/main.nf index 11e688b3..ef940db2 100644 --- a/modules/nf-core/samtools/faidx/main.nf +++ b/modules/nf-core/samtools/faidx/main.nf @@ -1,6 +1,6 @@ process SAMTOOLS_FAIDX { tag "$fasta" - label 'process_low' + label 'process_single' conda (params.enable_conda ? "bioconda::samtools=1.15.1" : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? @@ -12,6 +12,7 @@ process SAMTOOLS_FAIDX { output: tuple val(meta), path ("*.fai"), emit: fai + tuple val(meta), path ("*.gzi"), emit: gzi, optional: true path "versions.yml" , emit: versions when: diff --git a/modules/nf-core/samtools/faidx/meta.yml b/modules/nf-core/samtools/faidx/meta.yml index e9767764..fe2fe9a1 100644 --- a/modules/nf-core/samtools/faidx/meta.yml +++ b/modules/nf-core/samtools/faidx/meta.yml @@ -33,6 +33,10 @@ output: type: file description: FASTA index file pattern: "*.{fai}" + - gzi: + type: file + description: Optional gzip index file for compressed inputs + pattern: "*.gzi" - versions: type: file description: File containing software versions diff --git a/modules/nf-core/samtools/sort/main.nf b/modules/nf-core/samtools/sort/main.nf index b4fc1cbe..ab7f1cca 100644 --- a/modules/nf-core/samtools/sort/main.nf +++ b/modules/nf-core/samtools/sort/main.nf @@ -12,6 +12,7 @@ process SAMTOOLS_SORT { output: tuple val(meta), path("*.bam"), emit: bam + tuple val(meta), path("*.csi"), emit: csi, optional: true path "versions.yml" , emit: versions when: diff --git a/modules/nf-core/samtools/sort/meta.yml b/modules/nf-core/samtools/sort/meta.yml index a820c55a..09289751 100644 --- a/modules/nf-core/samtools/sort/meta.yml +++ b/modules/nf-core/samtools/sort/meta.yml @@ -39,6 +39,10 @@ output: type: file description: File containing software versions pattern: "versions.yml" + - csi: + type: file + description: BAM index file (optional) + pattern: "*.csi" authors: - "@drpatelh" - "@ewels" diff --git a/modules/nf-core/samtools/view/main.nf b/modules/nf-core/samtools/view/main.nf index 55194e88..b2f5c678 100644 --- a/modules/nf-core/samtools/view/main.nf +++ b/modules/nf-core/samtools/view/main.nf @@ -1,6 +1,6 @@ process SAMTOOLS_VIEW { tag "$meta.id" - label 'process_medium' + label 'process_low' conda (params.enable_conda ? "bioconda::samtools=1.15.1" : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? @@ -10,11 +10,16 @@ process SAMTOOLS_VIEW { input: tuple val(meta), path(input), path(index) path fasta + path qname output: - tuple val(meta), path("*.bam") , emit: bam , optional: true - tuple val(meta), path("*.cram"), emit: cram, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*.bam"), emit: bam, optional: true + tuple val(meta), path("*.cram"), emit: cram, optional: true + tuple val(meta), path("*.sam"), emit: sam, optional: true + tuple val(meta), path("*.bai"), emit: bai, optional: true + tuple val(meta), path("*.csi"), emit: csi, optional: true + tuple val(meta), path("*.crai"), emit: crai, optional: true + path "versions.yml", emit: versions when: task.ext.when == null || task.ext.when @@ -23,18 +28,23 @@ process SAMTOOLS_VIEW { def args = task.ext.args ?: '' def args2 = task.ext.args2 ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def reference = fasta ? "--reference ${fasta} -C" : "" - def file_type = input.getExtension() + def reference = fasta ? "--reference ${fasta}" : "" + def readnames = qname ? "--qname-file ${qname}": "" + def file_type = args.contains("--output-fmt sam") ? "sam" : + args.contains("--output-fmt bam") ? "bam" : + args.contains("--output-fmt cram") ? "cram" : + input.getExtension() if ("$input" == "${prefix}.${file_type}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" """ samtools \\ view \\ --threads ${task.cpus-1} \\ ${reference} \\ + ${readnames} \\ $args \\ + -o ${prefix}.${file_type} \\ $input \\ - $args2 \\ - > ${prefix}.${file_type} + $args2 cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/samtools/view/meta.yml b/modules/nf-core/samtools/view/meta.yml index a8b43ecc..a52e4f8d 100644 --- a/modules/nf-core/samtools/view/meta.yml +++ b/modules/nf-core/samtools/view/meta.yml @@ -33,6 +33,10 @@ input: type: optional file description: Reference file the CRAM was created with pattern: "*.{fasta,fa}" + - qname: + type: file + description: Optional file with read names to output only select alignments + pattern: "*.{txt,list}" output: - meta: type: map @@ -41,12 +45,29 @@ output: e.g. [ id:'test', single_end:false ] - bam: type: file - description: filtered/converted BAM/SAM file - pattern: "*.{bam,sam}" + description: optional filtered/converted BAM file + pattern: "*.{bam}" - cram: type: file - description: filtered/converted CRAM file - pattern: "*.cram" + description: optional filtered/converted CRAM file + pattern: "*.{cram}" + - sam: + type: file + description: optional filtered/converted SAM file + pattern: "*.{sam}" + # bai, csi, and crai are created with `--write-index` + - bai: + type: file + description: optional BAM file index + pattern: "*.{bai}" + - csi: + type: file + description: optional tabix BAM file index + pattern: "*.{csi}" + - crai: + type: file + description: optional CRAM file index + pattern: "*.{crai}" - versions: type: file description: File containing software versions @@ -55,3 +76,4 @@ authors: - "@drpatelh" - "@joseespinosa" - "@FriederikeHanssen" + - "@priyanka-surana" From 99975f26d97ec0e61821a667dfeb81219092194b Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Sun, 30 Oct 2022 12:09:14 +0100 Subject: [PATCH 063/176] update picard inputs with fasta and fai --- conf/genomes.config | 1 + conf/modules.config | 8 ++++++++ modules/local/ensembl/main.nf | 2 ++ subworkflows/local/qc_workflow.nf | 4 +++- workflows/build_references.nf | 3 +++ workflows/rnafusion.nf | 8 +++++++- 6 files changed, 24 insertions(+), 2 deletions(-) diff --git a/conf/genomes.config b/conf/genomes.config index 845445a2..64343922 100644 --- a/conf/genomes.config +++ b/conf/genomes.config @@ -12,6 +12,7 @@ params { genomes { 'GRCh38' { fasta = "${params.genomes_base}/ensembl/Homo_sapiens.${params.genome}.${params.ensembl_version}.all.fa" + fai = "${params.genomes_base}/ensembl/Homo_sapiens.${params.genome}.${params.ensembl_version}.all.fa.fai" gtf = "${params.genomes_base}/ensembl/Homo_sapiens.${params.genome}.${params.ensembl_version}.gtf" chrgtf = "${params.genomes_base}/ensembl/Homo_sapiens.${params.genome}.${params.ensembl_version}.chr.gtf" transcript = "${params.genomes_base}/ensembl/Homo_sapiens.${params.genome}.${params.ensembl_version}.cdna.all.fa.gz" diff --git a/conf/modules.config b/conf/modules.config index 07bf44f8..a8b4c4d2 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -180,6 +180,14 @@ process { ] } + withName: SAMTOOLS_FAIDX { + publishDir = [ + path: { "${params.genomes_base}/ensembl" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, + ] + } + withName: SAMTOOLS_SORT_FOR_ARRIBA { ext.prefix = { "${meta.id}_sorted" } publishDir = [ diff --git a/modules/local/ensembl/main.nf b/modules/local/ensembl/main.nf index 1b689f40..66a4aeac 100644 --- a/modules/local/ensembl/main.nf +++ b/modules/local/ensembl/main.nf @@ -32,6 +32,8 @@ process ENSEMBL_DOWNLOAD { gunzip Homo_sapiens.${params.genome}.${ensembl_version}.gtf.gz gunzip Homo_sapiens.${params.genome}.${ensembl_version}.chr.gtf.gz + + cat <<-END_VERSIONS > versions.yml "${task.process}": wget: \$(echo wget -V 2>&1 | grep "GNU Wget" | cut -d" " -f3 > versions.yml) diff --git a/subworkflows/local/qc_workflow.nf b/subworkflows/local/qc_workflow.nf index 1349c5f2..8cb8008a 100644 --- a/subworkflows/local/qc_workflow.nf +++ b/subworkflows/local/qc_workflow.nf @@ -12,6 +12,8 @@ workflow QC_WORKFLOW { bam_sorted ch_chrgtf ch_refflat + ch_fasta + ch_fai main: ch_versions = Channel.empty() @@ -29,7 +31,7 @@ workflow QC_WORKFLOW { ch_versions = ch_versions.mix(PICARD_COLLECTRNASEQMETRICS.out.versions) ch_rnaseq_metrics = Channel.empty().mix(PICARD_COLLECTRNASEQMETRICS.out.metrics) - PICARD_MARKDUPLICATES(bam_sorted) + PICARD_MARKDUPLICATES(bam_sorted, ch_fasta, ch_fai) ch_versions = ch_versions.mix(PICARD_MARKDUPLICATES.out.versions) ch_duplicate_metrics = Channel.empty().mix(PICARD_MARKDUPLICATES.out.metrics) diff --git a/workflows/build_references.nf b/workflows/build_references.nf index 3f55e2aa..6100008c 100644 --- a/workflows/build_references.nf +++ b/workflows/build_references.nf @@ -17,6 +17,7 @@ include { GTF_TO_REFFLAT } from '../modules/local/uscs/custom_g ======================================================================================== */ +include { SAMTOOLS_FAIDX } from '../modules/nf-core/samtools/faidx/main' include { STAR_GENOMEGENERATE } from '../modules/nf-core/star/genomegenerate/main' include { KALLISTO_INDEX as PIZZLY_INDEX } from '../modules/nf-core/kallisto/index/main' @@ -29,6 +30,8 @@ include { KALLISTO_INDEX as PIZZLY_INDEX } from '../modules/nf-core/kallisto/in workflow BUILD_REFERENCES { ENSEMBL_DOWNLOAD( params.ensembl_version ) + SAMTOOLS_FAIDX( ENSEMBL_DOWNLOAD.out.fasta ) + if (params.starindex || params.all || params.starfusion || params.arriba || params.squid ) { STAR_GENOMEGENERATE( ENSEMBL_DOWNLOAD.out.fasta, ENSEMBL_DOWNLOAD.out.gtf ) diff --git a/workflows/rnafusion.nf b/workflows/rnafusion.nf index 73736eb1..792e110c 100644 --- a/workflows/rnafusion.nf +++ b/workflows/rnafusion.nf @@ -11,6 +11,7 @@ WorkflowRnafusion.initialise(params, log) // Check mandatory parameters +// TODO if (file(params.input).exists() || params.build_references) { ch_input = file(params.input) } else { exit 1, 'Input samplesheet does not exist or was not specified!' } if (params.fusioninspector_only && !params.fusioninspector_fusions) { exit 1, 'Parameter --fusioninspector_fusions PATH_TO_FUSION_LIST expected with parameter --fusioninspector_only'} @@ -19,8 +20,10 @@ ch_starindex_ref = params.starfusion_build ? params.starindex_ref : "${params.st ch_starindex_ensembl_ref = params.starindex_ref ch_refflat = params.starfusion_build ? file(params.refflat) : "${params.ensembl_ref}/ref_annot.gtf.refflat" + def checkPathParamList = [ params.fasta, + params.fai, params.gtf, ch_chrgtf, params.transcript, @@ -40,6 +43,7 @@ if ((params.squid || params.all) && params.ensembl_version == 105) { exit 1, 'En ch_fasta = file(params.fasta) ch_gtf = file(params.gtf) ch_transcript = file(params.transcript) +ch_fai = file(params.fai) /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -218,7 +222,9 @@ workflow RNAFUSION { QC_WORKFLOW ( STARFUSION_WORKFLOW.out.bam_sorted, ch_chrgtf, - ch_refflat + ch_refflat, + ch_fasta, + ch_fai ) ch_versions = ch_versions.mix(QC_WORKFLOW.out.versions.first().ifEmpty(null)) From 23d5bd48c8598b23575f719e2ee1d9c3b4a77576 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Sun, 30 Oct 2022 18:13:05 +0100 Subject: [PATCH 064/176] add fai default param --- main.nf | 1 + 1 file changed, 1 insertion(+) diff --git a/main.nf b/main.nf index ece37f58..fec3cad9 100644 --- a/main.nf +++ b/main.nf @@ -19,6 +19,7 @@ nextflow.enable.dsl = 2 */ params.fasta = WorkflowMain.getGenomeAttribute(params, 'fasta') +params.fai = WorkflowMain.getGenomeAttribute(params, 'fai') params.gtf = WorkflowMain.getGenomeAttribute(params, 'gtf') params.chrgtf = WorkflowMain.getGenomeAttribute(params, 'chrgtf') params.transcript = WorkflowMain.getGenomeAttribute(params, 'transcript') From 496657616f0b0c81836f53e5c72d0e0c37237baa Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Sun, 30 Oct 2022 18:31:44 +0100 Subject: [PATCH 065/176] add emtpy meta in build references --- workflows/build_references.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/build_references.nf b/workflows/build_references.nf index 6100008c..82b098f8 100644 --- a/workflows/build_references.nf +++ b/workflows/build_references.nf @@ -30,7 +30,7 @@ include { KALLISTO_INDEX as PIZZLY_INDEX } from '../modules/nf-core/kallisto/in workflow BUILD_REFERENCES { ENSEMBL_DOWNLOAD( params.ensembl_version ) - SAMTOOLS_FAIDX( ENSEMBL_DOWNLOAD.out.fasta ) + SAMTOOLS_FAIDX(([], ENSEMBL_DOWNLOAD.out.fasta )) if (params.starindex || params.all || params.starfusion || params.arriba || params.squid ) { From 3465ee342114ec85dcd197e9b364d4d4f256cde8 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Sun, 30 Oct 2022 18:46:57 +0100 Subject: [PATCH 066/176] change empty meta declaration --- workflows/build_references.nf | 4 +++- workflows/rnafusion.nf | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/workflows/build_references.nf b/workflows/build_references.nf index 82b098f8..f8c1935b 100644 --- a/workflows/build_references.nf +++ b/workflows/build_references.nf @@ -30,7 +30,9 @@ include { KALLISTO_INDEX as PIZZLY_INDEX } from '../modules/nf-core/kallisto/in workflow BUILD_REFERENCES { ENSEMBL_DOWNLOAD( params.ensembl_version ) - SAMTOOLS_FAIDX(([], ENSEMBL_DOWNLOAD.out.fasta )) + ch_meta_empty = Channel.empty() + + SAMTOOLS_FAIDX(ch_meta_empty.merge(Channel.fromPath(ch_fasta, checkIfExists:true))) if (params.starindex || params.all || params.starfusion || params.arriba || params.squid ) { diff --git a/workflows/rnafusion.nf b/workflows/rnafusion.nf index 792e110c..4c33502a 100644 --- a/workflows/rnafusion.nf +++ b/workflows/rnafusion.nf @@ -11,7 +11,6 @@ WorkflowRnafusion.initialise(params, log) // Check mandatory parameters -// TODO if (file(params.input).exists() || params.build_references) { ch_input = file(params.input) } else { exit 1, 'Input samplesheet does not exist or was not specified!' } if (params.fusioninspector_only && !params.fusioninspector_fusions) { exit 1, 'Parameter --fusioninspector_fusions PATH_TO_FUSION_LIST expected with parameter --fusioninspector_only'} From f010859e6e3077600bb85152589a2a89ff69c0aa Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 31 Oct 2022 16:43:33 +0100 Subject: [PATCH 067/176] update build references to include fasta.fai --- workflows/build_references.nf | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/workflows/build_references.nf b/workflows/build_references.nf index f8c1935b..f53825a4 100644 --- a/workflows/build_references.nf +++ b/workflows/build_references.nf @@ -30,9 +30,12 @@ include { KALLISTO_INDEX as PIZZLY_INDEX } from '../modules/nf-core/kallisto/in workflow BUILD_REFERENCES { ENSEMBL_DOWNLOAD( params.ensembl_version ) - ch_meta_empty = Channel.empty() + // ch_meta_empty = Channel.value([[:]) - SAMTOOLS_FAIDX(ch_meta_empty.merge(Channel.fromPath(ch_fasta, checkIfExists:true))) + // ch_fasta_path = Channel.from(ENSEMBL_DOWNLOAD.out.fasta) + // ch_meta_empty = Channel.value([:]).view() + ch_fasta_w_meta = ENSEMBL_DOWNLOAD.out.fasta.map{ it -> [[id:it[0].baseName], it] } + SAMTOOLS_FAIDX(ch_fasta_w_meta) if (params.starindex || params.all || params.starfusion || params.arriba || params.squid ) { From 0ac1642935f322fcd2ca3ad42f5b467a920afc86 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 31 Oct 2022 20:07:37 +0100 Subject: [PATCH 068/176] Update workflows/build_references.nf remove comments Co-authored-by: Maxime U. Garcia --- workflows/build_references.nf | 4 ---- 1 file changed, 4 deletions(-) diff --git a/workflows/build_references.nf b/workflows/build_references.nf index f53825a4..331a46dc 100644 --- a/workflows/build_references.nf +++ b/workflows/build_references.nf @@ -30,10 +30,6 @@ include { KALLISTO_INDEX as PIZZLY_INDEX } from '../modules/nf-core/kallisto/in workflow BUILD_REFERENCES { ENSEMBL_DOWNLOAD( params.ensembl_version ) - // ch_meta_empty = Channel.value([[:]) - - // ch_fasta_path = Channel.from(ENSEMBL_DOWNLOAD.out.fasta) - // ch_meta_empty = Channel.value([:]).view() ch_fasta_w_meta = ENSEMBL_DOWNLOAD.out.fasta.map{ it -> [[id:it[0].baseName], it] } SAMTOOLS_FAIDX(ch_fasta_w_meta) From 7195c9c0233f7a5a65a9d409787802093c066826 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 31 Oct 2022 20:11:28 +0100 Subject: [PATCH 069/176] add fai to nextflow schema --- nextflow_schema.json | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/nextflow_schema.json b/nextflow_schema.json index cae74fd8..24305568 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -259,7 +259,6 @@ "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." }, "fasta": { "type": "string", @@ -267,7 +266,14 @@ "mimetype": "text/plain", "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 a BWA index available this will be generated for you automatically. Combine with `--save_reference` to save BWA index for future runs.", + "fa_icon": "far fa-file-code" + }, + "fai": { + "type": "string", + "format": "file-path", + "mimetype": "text/plain", + "pattern": "^\\S+\\.fn?ai(\\.gz)?$", + "description": "Path to FASTA genome index file.", "fa_icon": "far fa-file-code" }, "igenomes_base": { From ece60e3dd5dce34bae6b5344e87a1fae64e4a124 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 31 Oct 2022 20:15:11 +0100 Subject: [PATCH 070/176] fix typo --- nextflow_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nextflow_schema.json b/nextflow_schema.json index 24305568..2ef1095f 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -258,7 +258,7 @@ "genome": { "type": "string", "description": "Name of iGenomes reference.", - "fa_icon": "fas fa-book", + "fa_icon": "fas fa-book" }, "fasta": { "type": "string", From 10a57061f454be71b6b200dcdd90a51b5db91c6a Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 31 Oct 2022 20:16:28 +0100 Subject: [PATCH 071/176] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 189a6d26..395284d9 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 ### Changed +- Updated to nf-core template 2.6, with all module updates - multiQC updated to 1.13a in process dumpsoftwareversion - Updated nf-core and local modules with stub options - Patch fusion-report version with fixed mittelman DB and DB extraction date written into software_version.yaml From d225fbdfa39bb4b61db3ad9a6f3df8dc88e9ca88 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 1 Nov 2022 16:54:17 +0100 Subject: [PATCH 072/176] change channel for dummy arriba input --- subworkflows/local/arriba_workflow.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/local/arriba_workflow.nf b/subworkflows/local/arriba_workflow.nf index 4eb23ff3..921fcdea 100644 --- a/subworkflows/local/arriba_workflow.nf +++ b/subworkflows/local/arriba_workflow.nf @@ -48,7 +48,7 @@ workflow ARRIBA_WORKFLOW { } else { - ch_arriba_fusions = reads.merge(ch_dummy_file) + ch_arriba_fusions = reads.merge(Channel.fromPath(ch_dummy_file, checkIfExists:true)) ch_arriba_fusion_fail = ch_dummy_file ch_arriba_visualisation = ch_dummy_file } From 139118b32467ab16f085ad7942153302ad0b34fb Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 1 Nov 2022 17:11:06 +0100 Subject: [PATCH 073/176] change channel for all dummy input --- subworkflows/local/fusioncatcher_workflow.nf | 4 ++-- subworkflows/local/pizzly_workflow.nf | 3 ++- subworkflows/local/squid_workflow.nf | 2 +- subworkflows/local/starfusion_workflow.nf | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/subworkflows/local/fusioncatcher_workflow.nf b/subworkflows/local/fusioncatcher_workflow.nf index cb4e9026..cf52c681 100644 --- a/subworkflows/local/fusioncatcher_workflow.nf +++ b/subworkflows/local/fusioncatcher_workflow.nf @@ -12,7 +12,7 @@ workflow FUSIONCATCHER_WORKFLOW { if ((params.fusioncatcher || params.all) && !params.fusioninspector_only) { if (params.fusioncatcher_fusions){ ch_fusioncatcher_fusions = reads.merge(Channel.fromPath(params.fusioncatcher_fusions, checkIfExists:true)) - + } else { FUSIONCATCHER ( reads, @@ -22,7 +22,7 @@ workflow FUSIONCATCHER_WORKFLOW { } } else { - ch_fusioncatcher_fusions = reads.merge(ch_dummy_file) + ch_fusioncatcher_fusions = reads.merge(Channel.fromPath(ch_dummy_file, checkIfExists:true)) } emit: diff --git a/subworkflows/local/pizzly_workflow.nf b/subworkflows/local/pizzly_workflow.nf index b3ef7db6..3b921532 100644 --- a/subworkflows/local/pizzly_workflow.nf +++ b/subworkflows/local/pizzly_workflow.nf @@ -25,7 +25,8 @@ workflow PIZZLY_WORKFLOW { } } else { - ch_pizzly_fusions = reads.merge(ch_dummy_file) + ch_pizzly_fusions = reads.merge(Channel.fromPath(ch_dummy_file, checkIfExists:true)) + } diff --git a/subworkflows/local/squid_workflow.nf b/subworkflows/local/squid_workflow.nf index e73a6d9c..84167103 100644 --- a/subworkflows/local/squid_workflow.nf +++ b/subworkflows/local/squid_workflow.nf @@ -47,7 +47,7 @@ workflow SQUID_WORKFLOW { } } else { - ch_squid_fusions = reads.merge(ch_dummy_file) + ch_squid_fusions = reads.merge(Channel.fromPath(ch_dummy_file, checkIfExists:true)) } emit: diff --git a/subworkflows/local/starfusion_workflow.nf b/subworkflows/local/starfusion_workflow.nf index 69cf16b2..90dd0e31 100644 --- a/subworkflows/local/starfusion_workflow.nf +++ b/subworkflows/local/starfusion_workflow.nf @@ -30,7 +30,7 @@ workflow STARFUSION_WORKFLOW { } } else { - ch_starfusion_fusions = reads.merge(ch_dummy_file) + ch_starfusion_fusions = reads.merge(Channel.fromPath(ch_dummy_file, checkIfExists:true)) ch_star_stats = Channel.empty() } emit: From e0645e20fad783ac6672a33fccfe402ca29c8f3a Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 1 Nov 2022 17:44:36 +0100 Subject: [PATCH 074/176] update directory structure of modules --- modules/nf-core/{modules => }/stringtie/merge/main.nf | 0 modules/nf-core/{modules => }/stringtie/merge/meta.yml | 0 modules/nf-core/{modules => }/stringtie/stringtie/main.nf | 0 modules/nf-core/{modules => }/stringtie/stringtie/meta.yml | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename modules/nf-core/{modules => }/stringtie/merge/main.nf (100%) rename modules/nf-core/{modules => }/stringtie/merge/meta.yml (100%) rename modules/nf-core/{modules => }/stringtie/stringtie/main.nf (100%) rename modules/nf-core/{modules => }/stringtie/stringtie/meta.yml (100%) diff --git a/modules/nf-core/modules/stringtie/merge/main.nf b/modules/nf-core/stringtie/merge/main.nf similarity index 100% rename from modules/nf-core/modules/stringtie/merge/main.nf rename to modules/nf-core/stringtie/merge/main.nf diff --git a/modules/nf-core/modules/stringtie/merge/meta.yml b/modules/nf-core/stringtie/merge/meta.yml similarity index 100% rename from modules/nf-core/modules/stringtie/merge/meta.yml rename to modules/nf-core/stringtie/merge/meta.yml diff --git a/modules/nf-core/modules/stringtie/stringtie/main.nf b/modules/nf-core/stringtie/stringtie/main.nf similarity index 100% rename from modules/nf-core/modules/stringtie/stringtie/main.nf rename to modules/nf-core/stringtie/stringtie/main.nf diff --git a/modules/nf-core/modules/stringtie/stringtie/meta.yml b/modules/nf-core/stringtie/stringtie/meta.yml similarity index 100% rename from modules/nf-core/modules/stringtie/stringtie/meta.yml rename to modules/nf-core/stringtie/stringtie/meta.yml From 44c4a066b510e616e4edb217e22e81d3d3509b8b Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 1 Nov 2022 17:45:53 +0100 Subject: [PATCH 075/176] update module path --- subworkflows/local/stringtie_workflow.nf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subworkflows/local/stringtie_workflow.nf b/subworkflows/local/stringtie_workflow.nf index cfe2202a..d9e1c6c3 100644 --- a/subworkflows/local/stringtie_workflow.nf +++ b/subworkflows/local/stringtie_workflow.nf @@ -1,5 +1,5 @@ -include { STRINGTIE_STRINGTIE } from '../../modules/nf-core/modules/stringtie/stringtie/main' -include { STRINGTIE_MERGE } from '../../modules/nf-core/modules/stringtie/merge/main' +include { STRINGTIE_STRINGTIE } from '../../modules/nf-core/stringtie/stringtie/main' +include { STRINGTIE_MERGE } from '../../modules/nf-core/stringtie/merge/main' workflow STRINGTIE_WORKFLOW { From 992f41821db953b956e29c251cca2f735ddc7d8f Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 1 Nov 2022 17:53:32 +0100 Subject: [PATCH 076/176] add stringtie citation --- CITATIONS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CITATIONS.md b/CITATIONS.md index 629f86ad..ffe10310 100644 --- a/CITATIONS.md +++ b/CITATIONS.md @@ -51,6 +51,9 @@ - [STAR-Fusion](https://github.com/STAR-Fusion/STAR-Fusion) > Haas BJ, Dobin A, Li B, Stransky N, Pochet N, Regev A. Accuracy assessment of fusion transcript detection via read-mapping and de novo fusion transcript assembly-based methods. Genome Biology 2019 Oct;20,213. doi: 10.1186/s13059-019-1842-9 +- [StringTie](https://ccb.jhu.edu/software/stringtie/index.shtml) + > Shumate A, Wong B, Pertea G, Pertea M. Improved transcriptome assembly using a hybrid of long and short reads with StringTie. PLOS Computational Biology 18, 6 (2022), doi.org/10.1371/journal.pcbi.1009730 + ## Software packaging/containerisation tools - [Anaconda](https://anaconda.com) From 2308c1fae6b1b25d71cb0acb52fbfe8dbae282ea Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 7 Nov 2022 18:23:45 +0100 Subject: [PATCH 077/176] update documentation --- CHANGELOG.md | 2 +- README.md | 26 +++++++++++++++----------- docs/output.md | 9 +++++++++ docs/usage.md | 4 ++-- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a5e71fd..d8939cdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- `stringtie` v2.2.1 added to detect splicing events. Not included in `fusion-report` or `fusionInspector` summaries +- `--stringtie` option added with StringTie v2.2.1 to detect splicing events. Not included in `fusion-report` or `fusionInspector` summaries. Included in the `--all` workflow ### Changed diff --git a/README.md b/README.md index cc445df9..b3f60825 100644 --- a/README.md +++ b/README.md @@ -20,13 +20,15 @@ The pipeline is built using [Nextflow](https://www.nextflow.io), a workflow tool > GRCh38 is the only supported reference -| Tool | Single-end reads | Version | -| --------------------------------------------------------- | :----------------: | :------: | -| [Arriba](https://github.com/suhrig/arriba) | :x: | `2.3.0` | -| [FusionCatcher](https://github.com/ndaniel/fusioncatcher) | :white_check_mark: | `1.33` | -| [Pizzly](https://github.com/pmelsted/pizzly) | :x: | `0.37.3` | -| [Squid](https://github.com/Kingsford-Group/squid) | :x: | `1.5` | -| [STAR-Fusion](https://github.com/STAR-Fusion/STAR-Fusion) | :white_check_mark: | `1.10.1` | +| Tool | Version | +| --------------------------------------------------------- | :------: | +| [Arriba](https://github.com/suhrig/arriba) | `2.3.0` | +| [FusionCatcher](https://github.com/ndaniel/fusioncatcher) | `1.33` | +| [Pizzly](https://github.com/pmelsted/pizzly) | `0.37.3` | +| [Squid](https://github.com/Kingsford-Group/squid) | `1.5` | +| [STAR-Fusion](https://github.com/STAR-Fusion/STAR-Fusion) | `1.10.1` | +| [StringTie](https://github.com/gpertea/stringtie) | `2.2.1` | + > Single-end reads are to be use as last-resort. Paired-end reads are recommended. FusionCatcher cannot be used with single-end reads shorter than 130 bp. @@ -80,10 +82,12 @@ In rnafusion the full-sized test includes reference building and fusion detectio - [Fusion-report](https://github.com/matq007/fusion-report) 10. FusionInspector subworkflow - [FusionInspector](https://github.com/FusionInspector/FusionInspector) -11. Present QC for raw reads ([`MultiQC`](http://multiqc.info/)) -12. QC for mapped reads ([`QualiMap: BAM QC`](https://kokonech.github.io/qualimap/HG00096.chr20_bamqc/qualimapReport.html)) -13. Index mapped reads ([samtools index](http://www.htslib.org/)) -14. Collect metrics ([`picard CollectRnaSeqMetrics`](https://gatk.broadinstitute.org/hc/en-us/articles/360037057492-CollectRnaSeqMetrics-Picard-) and ([`picard MarkDuplicates`](https://gatk.broadinstitute.org/hc/en-us/articles/360037052812-MarkDuplicates-Picard-)) +11. Stringtie subworkflow + - [StringTie](https://ccb.jhu.edu/software/stringtie/index.shtml) +12. Present QC for raw reads ([`MultiQC`](http://multiqc.info/)) +13. QC for mapped reads ([`QualiMap: BAM QC`](https://kokonech.github.io/qualimap/HG00096.chr20_bamqc/qualimapReport.html)) +14. Index mapped reads ([samtools index](http://www.htslib.org/)) +15. Collect metrics ([`picard CollectRnaSeqMetrics`](https://gatk.broadinstitute.org/hc/en-us/articles/360037057492-CollectRnaSeqMetrics-Picard-) and ([`picard MarkDuplicates`](https://gatk.broadinstitute.org/hc/en-us/articles/360037052812-MarkDuplicates-Picard-)) ## Quick Start diff --git a/docs/output.md b/docs/output.md index b9d64d87..c9c709f1 100644 --- a/docs/output.md +++ b/docs/output.md @@ -17,6 +17,7 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d - [Pizzly](#pizzly) - Pizzly fusion detection - [Squid](#squid) - Squid fusion detection - [STAR-fusion](#starfusion) - STAR-fusion fusion detection +- [StringTie](#stringtie) - StringTie assembly - [FusionCatcher](#fusioncatcher) - Fusion catcher fusion detection - [Samtools](#samtools) - SAM/BAM file manipulation - [Arriba visualisation](#arriba-visualisation) - Arriba visualisation report @@ -251,6 +252,14 @@ Squid is run in two steps: i) fusion detection and ii) fusion annotation but the +### StringTie + +
    +Output files + +- `stringtie//stringtie.merged.gtf` - merged gtf from annotation and stringtie output gtfs +
    + ### FusionCatcher
    diff --git a/docs/usage.md b/docs/usage.md index b32d7929..3f7efb86 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -13,7 +13,7 @@ The pipeline is divided into two parts: - required only once before running the pipeline - **Important**: rerun with each new release 2. Detecting fusions - - Supported tools: `Arriba`, `FusionCatcher`, `pizzly`, `SQUID` and `STAR-Fusion` + - Supported tools: `Arriba`, `FusionCatcher`, `pizzly`, `SQUID`, `STAR-Fusion` and `StringTie` - QC: `Fastqc` and `MultiQC` - Fusion visualization: `Arriba` (only fusion detected with Arriba), `fusion-report` and `FusionInspector` @@ -98,7 +98,7 @@ By default STAR-Fusion references are **built**. You can also download them from ### 2. Detecting fusions -This step can either be run using all fusion detection tools or specifying individual tools. Visualisation tools will be run on all fusions detected. To run all tools (`arriba`, `fusioncatcher`, `pizzly`, `squid`, `starfusion`) use the `--all` parameter: +This step can either be run using all fusion detection tools or specifying individual tools. Visualisation tools will be run on all fusions detected. To run all tools (`arriba`, `fusioncatcher`, `pizzly`, `squid`, `starfusion`, `stringtie`) use the `--all` parameter: ```bash nextflow run nf-core/rnafusion \ From 1175c56d394852a993ef97a392063d773462618e Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 7 Nov 2022 18:27:15 +0100 Subject: [PATCH 078/176] prettier --- CITATIONS.md | 1 + README.md | 17 ++++++++--------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CITATIONS.md b/CITATIONS.md index ffe10310..1a3482ac 100644 --- a/CITATIONS.md +++ b/CITATIONS.md @@ -49,6 +49,7 @@ > Dobin A, Davis CA, Schlesinger F, Drenkow J, Zaleski C, Jha S, Batut P, Chaisson M, Gingeras TR. STAR: ultrafast universal RNA-seq aligner Bioinformatics. 2013 Jan 1;29(1):15-21. doi: 10.1093/bioinformatics/bts635. Epub 2012 Oct 25. PubMed PMID: 23104886; PubMed Central PMCID: PMC3530905. - [STAR-Fusion](https://github.com/STAR-Fusion/STAR-Fusion) + > Haas BJ, Dobin A, Li B, Stransky N, Pochet N, Regev A. Accuracy assessment of fusion transcript detection via read-mapping and de novo fusion transcript assembly-based methods. Genome Biology 2019 Oct;20,213. doi: 10.1186/s13059-019-1842-9 - [StringTie](https://ccb.jhu.edu/software/stringtie/index.shtml) diff --git a/README.md b/README.md index b3f60825..de754185 100644 --- a/README.md +++ b/README.md @@ -20,15 +20,14 @@ The pipeline is built using [Nextflow](https://www.nextflow.io), a workflow tool > GRCh38 is the only supported reference -| Tool | Version | -| --------------------------------------------------------- | :------: | -| [Arriba](https://github.com/suhrig/arriba) | `2.3.0` | -| [FusionCatcher](https://github.com/ndaniel/fusioncatcher) | `1.33` | -| [Pizzly](https://github.com/pmelsted/pizzly) | `0.37.3` | -| [Squid](https://github.com/Kingsford-Group/squid) | `1.5` | -| [STAR-Fusion](https://github.com/STAR-Fusion/STAR-Fusion) | `1.10.1` | -| [StringTie](https://github.com/gpertea/stringtie) | `2.2.1` | - +| Tool | Version | +| --------------------------------------------------------- | :------: | +| [Arriba](https://github.com/suhrig/arriba) | `2.3.0` | +| [FusionCatcher](https://github.com/ndaniel/fusioncatcher) | `1.33` | +| [Pizzly](https://github.com/pmelsted/pizzly) | `0.37.3` | +| [Squid](https://github.com/Kingsford-Group/squid) | `1.5` | +| [STAR-Fusion](https://github.com/STAR-Fusion/STAR-Fusion) | `1.10.1` | +| [StringTie](https://github.com/gpertea/stringtie) | `2.2.1` | > Single-end reads are to be use as last-resort. Paired-end reads are recommended. FusionCatcher cannot be used with single-end reads shorter than 130 bp. From fa0263679fe95269f1c32160a91bebf28dc33be1 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 8 Nov 2022 08:55:57 +0100 Subject: [PATCH 079/176] update metro map --- docs/images/nf-core-rnafusion_metro_map.png | Bin 239156 -> 226822 bytes docs/images/nf-core-rnafusion_metro_map.svg | 637 +++++++++++--------- 2 files changed, 343 insertions(+), 294 deletions(-) diff --git a/docs/images/nf-core-rnafusion_metro_map.png b/docs/images/nf-core-rnafusion_metro_map.png index 805aad691cfb8c3a66db452033364aa2cca9ba78..c477719c0021f6e4dcbd17f5ca7aaab587ea5cc5 100644 GIT binary patch literal 226822 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�#MC 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⪻^aLd-e|o2FWFq2m{3PZi_gsdrCrRIq~Y!3rZ_%4 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%0A;1%CudFpg8iw6y-y!uEr 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

    5{^p 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

    vI2ocg^IzVO#5?|Rk7Lzfr`C3ya4U>XB|J0 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

    e>?wZTN7dtCHZ?%a9rHeKKDg9LcLgN|1C+ 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 ep8x0cbWe&sOze?j#D(n @@ -46,51 +46,44 @@ inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1"> + + id="g14717"> - fastq + style="stroke-width:0.32789" /> - - + style="fill:#ffffff;stroke-width:0.32789" /> + style="stroke-width:0.32789" /> fastq + + align + x="92.045135" + y="30.610683">align Arriba + x="116.77547" + y="30.893871">Arriba SQUID + x="117.46586" + y="48.143513">SQUID pizzly + x="144.47179" + y="65.475723">pizzly align + x="92.045135" + y="48.143513">align kallisto + x="89.031456" + y="65.99041">kallisto FusionCatcher + x="107.64942" + y="82.737106">FusionCatcher align + x="92.045135" + y="100.24001">align ArribaArribavisualisation STAR-Fusion + x="134.22189" + y="99.785919">STAR-Fusion FastQC + x="90.589928" + y="133.89124">FastQC Qualimap + x="126.84258" + y="134.05916">Qualimap MultiQC + x="214.23581" + y="133.83154">MultiQC FusionInspector + x="237.72295" + y="72.795616">FusionInspector fusion-report + x="207.94273" + y="93.459595">fusion-report PicardPicardCollectRnaSeqMetrics+PicardCollectWgsMetrics SQUID annotate - - - - - - - arriba - squid - pizzly - fusioncatcher - starfusion - qc + + + + + fusioncatcher + starfusion + qc + Workflows: + x="23.380251" + y="142.20734">Workflows: + + StringTie + + + + + + arriba + squid + pizzly + stringtie + + From 5be79d5b56b7b72dfd43970fdbe7883a2c9ec8b4 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 9 Nov 2022 20:54:58 +0100 Subject: [PATCH 080/176] change merge to combine as deprecation will happen --- subworkflows/local/arriba_workflow.nf | 7 +++++-- subworkflows/local/fusioncatcher_workflow.nf | 7 ++++--- subworkflows/local/fusionreport_workflow.nf | 4 +++- subworkflows/local/pizzly_workflow.nf | 8 ++++---- subworkflows/local/squid_workflow.nf | 6 ++++-- subworkflows/local/starfusion_workflow.nf | 6 ++++-- 6 files changed, 24 insertions(+), 14 deletions(-) diff --git a/subworkflows/local/arriba_workflow.nf b/subworkflows/local/arriba_workflow.nf index 921fcdea..9c4db9da 100644 --- a/subworkflows/local/arriba_workflow.nf +++ b/subworkflows/local/arriba_workflow.nf @@ -31,7 +31,8 @@ workflow ARRIBA_WORKFLOW { if (params.arriba_fusions) { // [meta, reads], fusions -> [meta, fusions] - ch_arriba_fusions = reads.merge(Channel.fromPath(params.arriba_fusions, checkIfExists:true)) + ch_arriba_fusions = reads.combine( Channel.value( file( params.arriba_fusions, checkIfExists: true ) ) ) + .map { meta, reads, fusions -> [ meta, fusions ] } ch_arriba_fusion_fail = ch_dummy_file } else { ARRIBA ( STAR_FOR_ARRIBA.out.bam, ch_fasta, ch_gtf, params.arriba_ref_blacklist, [], [], [], params.arriba_ref_protein_domain ) @@ -48,7 +49,9 @@ workflow ARRIBA_WORKFLOW { } else { - ch_arriba_fusions = reads.merge(Channel.fromPath(ch_dummy_file, checkIfExists:true)) + ch_arriba_fusions = reads.combine(Channel.value( file(ch_dummy_file, checkIfExists:true ) ) ) + .map { meta, reads, fusions -> [ meta, fusions ] } + ch_arriba_fusion_fail = ch_dummy_file ch_arriba_visualisation = ch_dummy_file } diff --git a/subworkflows/local/fusioncatcher_workflow.nf b/subworkflows/local/fusioncatcher_workflow.nf index cf52c681..a9058dc6 100644 --- a/subworkflows/local/fusioncatcher_workflow.nf +++ b/subworkflows/local/fusioncatcher_workflow.nf @@ -11,8 +11,8 @@ workflow FUSIONCATCHER_WORKFLOW { if ((params.fusioncatcher || params.all) && !params.fusioninspector_only) { if (params.fusioncatcher_fusions){ - ch_fusioncatcher_fusions = reads.merge(Channel.fromPath(params.fusioncatcher_fusions, checkIfExists:true)) - + ch_fusioncatcher_fusions = reads.combine(Channel.value(file(params.fusioncatcher_fusions, checkIfExists:true))) + .map { meta, reads, fusions -> [ meta, fusions ] } } else { FUSIONCATCHER ( reads, @@ -22,7 +22,8 @@ workflow FUSIONCATCHER_WORKFLOW { } } else { - ch_fusioncatcher_fusions = reads.merge(Channel.fromPath(ch_dummy_file, checkIfExists:true)) + ch_fusioncatcher_fusions = reads.combine(Channel.value(file(ch_dummy_file, checkIfExists:true))) + .map { meta, reads, fusions -> [ meta, fusions ] } } emit: diff --git a/subworkflows/local/fusionreport_workflow.nf b/subworkflows/local/fusionreport_workflow.nf index 3d1be49f..748b8ab1 100644 --- a/subworkflows/local/fusionreport_workflow.nf +++ b/subworkflows/local/fusionreport_workflow.nf @@ -27,7 +27,9 @@ workflow FUSIONREPORT_WORKFLOW { ch_fusion_list_filtered = FUSIONREPORT.out.fusion_list_filtered ch_versions = ch_versions.mix(FUSIONREPORT.out.versions) } else { - ch_fusion_list = reads.merge(Channel.fromPath(params.fusioninspector_fusions, checkIfExists:true)) + ch_fusion_list = reads.combine(Channel.value(file(params.fusioninspector_fusions, checkIfExists:true))) + .map { meta, reads, fusions -> [ meta, fusions ] } + ch_fusion_list_filtered = ch_fusion_list } diff --git a/subworkflows/local/pizzly_workflow.nf b/subworkflows/local/pizzly_workflow.nf index 3b921532..7675432b 100644 --- a/subworkflows/local/pizzly_workflow.nf +++ b/subworkflows/local/pizzly_workflow.nf @@ -13,7 +13,8 @@ workflow PIZZLY_WORKFLOW { if ((params.pizzly || params.all) && !params.fusioninspector_only) { if (params.pizzly_fusions) { - ch_pizzly_fusions = reads.merge(Channel.fromPath(params.pizzly_fusions, checkIfExists:true)) + ch_pizzly_fusions = reads.combine(Channel.value(file(params.pizzly_fusions, checkIfExists:true))) + .map { meta, reads, fusions -> [ meta, fusions ] } } else { KALLISTO_QUANT(reads, params.pizzly_ref ) ch_versions = ch_versions.mix(KALLISTO_QUANT.out.versions) @@ -25,9 +26,8 @@ workflow PIZZLY_WORKFLOW { } } else { - ch_pizzly_fusions = reads.merge(Channel.fromPath(ch_dummy_file, checkIfExists:true)) - - + ch_pizzly_fusions = reads.combine(Channel.value(file(ch_dummy_file, checkIfExists:true))) + .map { meta, reads, fusions -> [ meta, fusions ] } } emit: diff --git a/subworkflows/local/squid_workflow.nf b/subworkflows/local/squid_workflow.nf index 84167103..14f81158 100644 --- a/subworkflows/local/squid_workflow.nf +++ b/subworkflows/local/squid_workflow.nf @@ -18,7 +18,8 @@ workflow SQUID_WORKFLOW { if ((params.squid || params.all) && !params.fusioninspector_only) { if (params.squid_fusions){ - ch_squid_fusions = reads.merge(Channel.fromPath(params.squid_fusions, checkIfExists:true)) + ch_squid_fusions = reads.combine(Channel.value(file(params.squid_fusions, checkIfExists:true))) + .map { meta, reads, fusions -> [ meta, fusions ] } } else { STAR_FOR_SQUID( reads, ch_starindex_ensembl_ref, ch_gtf, params.star_ignore_sjdbgtf, '', params.seq_center ?: '') @@ -47,7 +48,8 @@ workflow SQUID_WORKFLOW { } } else { - ch_squid_fusions = reads.merge(Channel.fromPath(ch_dummy_file, checkIfExists:true)) + ch_squid_fusions = reads.combine(Channel.value(file(ch_dummy_file, checkIfExists:true))) + .map { meta, reads, fusions -> [ meta, fusions ] } } emit: diff --git a/subworkflows/local/starfusion_workflow.nf b/subworkflows/local/starfusion_workflow.nf index 90dd0e31..87ebdc6b 100644 --- a/subworkflows/local/starfusion_workflow.nf +++ b/subworkflows/local/starfusion_workflow.nf @@ -14,7 +14,8 @@ workflow STARFUSION_WORKFLOW { if ((params.starfusion || params.all) && !params.fusioninspector_only) { if (params.starfusion_fusions){ - ch_starfusion_fusions = reads.merge(Channel.fromPath(params.starfusion_fusions, checkIfExists:true)) + ch_starfusion_fusions = reads.combine(Channel.value(file(params.starfusion_fusions, checkIfExists:true))) + .map { meta, reads, fusions -> [ meta, fusions ] } } else { STAR_FOR_STARFUSION( reads, ch_starindex_ref, ch_chrgtf, params.star_ignore_sjdbgtf, '', params.seq_center ?: '') ch_versions = ch_versions.mix(STAR_FOR_STARFUSION.out.versions) @@ -30,7 +31,8 @@ workflow STARFUSION_WORKFLOW { } } else { - ch_starfusion_fusions = reads.merge(Channel.fromPath(ch_dummy_file, checkIfExists:true)) + ch_starfusion_fusions = reads.combine(Channel.value(file(ch_dummy_file, checkIfExists:true))) + .map { meta, reads, fusions -> [ meta, fusions ] } ch_star_stats = Channel.empty() } emit: From e3ab36cee462224584a2353566043d4c63eb66f6 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Sat, 12 Nov 2022 14:20:12 +0100 Subject: [PATCH 081/176] remove get files --- modules/local/getmeta/main.nf | 24 ------------------------ modules/local/getpath/main.nf | 23 ----------------------- 2 files changed, 47 deletions(-) delete mode 100644 modules/local/getmeta/main.nf delete mode 100644 modules/local/getpath/main.nf diff --git a/modules/local/getmeta/main.nf b/modules/local/getmeta/main.nf deleted file mode 100644 index 3326e7df..00000000 --- a/modules/local/getmeta/main.nf +++ /dev/null @@ -1,24 +0,0 @@ -process GET_META { - tag 'getmeta' - label 'process_low' - - conda (params.enable_conda ? "conda-forge::sed=4.7" : null) - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://containers.biocontainers.pro/s3/SingImgsRepo/biocontainers/v1.2.0_cv1/biocontainers_v1.2.0_cv1.img' : - 'biocontainers/biocontainers:v1.2.0_cv1' }" - - input: - tuple val(meta), path(reads) - path file - - output: - tuple val(meta), path(file) , emit: file - - script: - """ - """ - - stub: - """ - """ -} diff --git a/modules/local/getpath/main.nf b/modules/local/getpath/main.nf deleted file mode 100644 index 0ef00264..00000000 --- a/modules/local/getpath/main.nf +++ /dev/null @@ -1,23 +0,0 @@ -process GET_PATH { - tag 'getpath' - label 'process_low' - - conda (params.enable_conda ? "conda-forge::sed=4.7" : null) - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://containers.biocontainers.pro/s3/SingImgsRepo/biocontainers/v1.2.0_cv1/biocontainers_v1.2.0_cv1.img' : - 'biocontainers/biocontainers:v1.2.0_cv1' }" - - input: - tuple val(meta), path(file) - - output: - path file , emit: file - - script: - """ - """ - - stub: - """ - """ -} From 4d8c7075760d42fbc26df8c369409bc673c5f5b3 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Sun, 13 Nov 2022 17:46:23 +0100 Subject: [PATCH 082/176] change documentations and run all tools with stub in ci --- .github/workflows/ci.yml | 2 +- CHANGELOG.md | 6 ++++-- docs/usage.md | 21 +++------------------ 3 files changed, 8 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 44364678..bc0d26e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,6 +34,6 @@ jobs: - name: Test pizzly run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker \ - --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly --fusionreport -stub \ + --outdir /home/runner/work/rnafusion/rnafusion/results --all -stub \ --build_references --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a2abf8d..b188cecd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,16 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Instructions to run `Arriba` on S3 with manually downloaded references as with the `Arriba` now uses the references from the docker/singularity containers - exitStatus 140 now part of the retry strategy +- stubs to all local modules ### Changed +- UPDATE IN USAGE: in order to make AWS tests work, now the analysis part of the pipeline will run after downloading the references with `build_references` if an `input` parameter is provided - Update CUSTOM_DUMPSOFTWAREVERSIONS to use multiqc version 1.13 - Updated to nf-core template 2.6, with all module updates -- multiQC updated to 1.13a in process dumpsoftwareversion +- `MultiQC` updated to 1.13a in process dumpsoftwareversion - Updated nf-core and local modules with stub options - Patch fusion-report version with fixed mittelman DB and DB extraction date written into software_version.yaml +- `Arriba` references back to downloading with `build_references` instead of taking from container ### Fixed diff --git a/docs/usage.md b/docs/usage.md index fe3f9d5e..9b6b215e 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -28,6 +28,8 @@ Download the references as shown below including your COSMIC credentials. > Note that this step takes about 24 hours to complete on HPC. +> Do not provide a samplesheet via the `input` parameter, otherwise the pipeline will run the analysis directly after downloading the references (except if that is what you want). + ```bash nextflow run nf-core/rnafusion \ --build_references --all \ @@ -46,23 +48,6 @@ nextflow run nf-core/rnafusion \ --outdir ``` -> For S3 usage: references for arriba are taken from the container image, which is not in the bound path with S3. Therefore arriba references have to be manually downloaded in this case and fed to rnafusion. Follow the steps below: - -- Download arriba tar.gz file from https://github.com/suhrig/arriba/releases/latest -- Extract -- Start rnafusion pipeline with: - -```bash -nextflow run nf-core/rnafusion \ - -- (-- ... OR --all) \ - --input \ - --genomes_base \ - --outdir \ - --arriba_ref_blacklist \ - --arriba_protein_domain \ - --arriba_ref -``` - #### References directory tree ```text @@ -79,7 +64,7 @@ references/ #### Issues with building references -If process `FUSIONREPORT_DOWNLOAD` times out, it could be due to network restriction (e.g. if trying to run on HPC). As this process is lightweight in compute, storage and time, it is recommended to run on local machines with: +If process `FUSIONREPORT_DOWNLOAD` times out, it could be due to network restriction (e.g. if trying to run on HPC). As this process is lightweight in compute, storage and time, running on local machines with the following options might solve the issue: ```bash nextflow run nf-core/rnafusion \ From 1c1f931943062050370f9398adc63c29d83c68c5 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Sun, 13 Nov 2022 19:23:10 +0100 Subject: [PATCH 083/176] unify the test profile, fix i/o channel error in samtools view, document usage change --- .github/workflows/awstest.yml | 1 + .github/workflows/ci.yml | 6 ++--- CHANGELOG.md | 1 + conf/test.config | 6 +++-- conf/test_build.config | 26 -------------------- conf/test_full.config | 21 ---------------- conf/test_full_build.config | 24 ------------------ docs/usage.md | 1 + modules/local/fusioncatcher/download/main.nf | 1 + nextflow.config | 7 +++--- subworkflows/local/squid_workflow.nf | 3 ++- workflows/rnafusion.nf | 3 ++- 12 files changed, 17 insertions(+), 83 deletions(-) delete mode 100644 conf/test_build.config delete mode 100644 conf/test_full.config delete mode 100644 conf/test_full_build.config diff --git a/.github/workflows/awstest.yml b/.github/workflows/awstest.yml index 365a4fa1..8184cfd7 100644 --- a/.github/workflows/awstest.yml +++ b/.github/workflows/awstest.yml @@ -24,5 +24,6 @@ jobs: "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", "cosmic_username": "${{ secrets.cosmic_username }}", "cosmic_passwd": "${{ secrets.cosmic_passwd }}" + "stub": true } profiles: test_build,aws_tower diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc0d26e2..72f7c2ab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,9 +31,7 @@ jobs: with: version: "${{ matrix.NXF_VER }}" - - name: Test pizzly + - name: Test dry run run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker \ - --outdir /home/runner/work/rnafusion/rnafusion/results --all -stub \ - --build_references --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ + nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} diff --git a/CHANGELOG.md b/CHANGELOG.md index b188cecd..02576247 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 ### Changed +- Test profiles unified under 'test' but if the references do not all need to be downloaded, run with `-stub` - UPDATE IN USAGE: in order to make AWS tests work, now the analysis part of the pipeline will run after downloading the references with `build_references` if an `input` parameter is provided - Update CUSTOM_DUMPSOFTWAREVERSIONS to use multiqc version 1.13 - Updated to nf-core template 2.6, with all module updates diff --git a/conf/test.config b/conf/test.config index d8e7bcc4..726f1cf3 100644 --- a/conf/test.config +++ b/conf/test.config @@ -5,7 +5,7 @@ Defines input files and everything required to run a fast and simple pipeline test. Use as follows: - nextflow run nf-core/rnafusion -profile test, --outdir + nextflow run nf-core/rnafusion -profile test, --outdir -stub ---------------------------------------------------------------------------------------- */ @@ -20,5 +20,7 @@ params { max_time = 6.h // Input data - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' + build_references = true + all = true + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' } diff --git a/conf/test_build.config b/conf/test_build.config deleted file mode 100644 index 82742169..00000000 --- a/conf/test_build.config +++ /dev/null @@ -1,26 +0,0 @@ -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Nextflow config file for running minimal tests -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Defines input files and everything required to run a fast and simple pipeline test. - - Use as follows: - nextflow run nf-core/rnafusion -profile test, --outdir - ----------------------------------------------------------------------------------------- -*/ - -params { - config_profile_name = 'Test profile' - config_profile_description = 'Minimal test dataset to check pipeline function' - - // Limit resources so that this can run on GitHub Actions - max_cpus = 2 - max_memory = 12.GB - max_time = 6.h - - build_references = true - arriba = true - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' - skip_vis = true -} diff --git a/conf/test_full.config b/conf/test_full.config deleted file mode 100644 index 2b215ab6..00000000 --- a/conf/test_full.config +++ /dev/null @@ -1,21 +0,0 @@ -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Nextflow config file for running full-size tests -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Defines input files and everything required to run a full size pipeline test. - - Use as follows: - nextflow run nf-core/rnafusion -profile test_full, --outdir - ----------------------------------------------------------------------------------------- -*/ - -params { - config_profile_name = 'Full test profile' - config_profile_description = 'Full test dataset to check pipeline function' - - // Input data - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' - all = true - -} diff --git a/conf/test_full_build.config b/conf/test_full_build.config deleted file mode 100644 index d7b44e82..00000000 --- a/conf/test_full_build.config +++ /dev/null @@ -1,24 +0,0 @@ -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Nextflow config file for running full-size tests -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Defines input files and everything required to run a full size pipeline test. - - Use as follows: - nextflow run nf-core/rnafusion -profile test_full_build, --outdir - ----------------------------------------------------------------------------------------- -*/ - -params { - config_profile_name = 'Full build test profile' - config_profile_description = 'Full build test dataset to check pipeline function' - - - // Input data - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' - build_references = true - all = true - cosmic_username = "${{ secrets.cosmic_username }}" - cosmic_passwd = "${{ secrets.cosmic_passwd }}" -} diff --git a/docs/usage.md b/docs/usage.md index 9b6b215e..d4e08d63 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -259,6 +259,7 @@ If `-profile` is not specified, the pipeline will run locally and expect all sof - `test` - A profile with a complete configuration for automated testing - Includes links to test data so needs no other parameters + - !!!! Run with `-stub` as all references need to be downloaded otherwise !!!! ### `-resume` diff --git a/modules/local/fusioncatcher/download/main.nf b/modules/local/fusioncatcher/download/main.nf index 9daa0191..4116e4a4 100644 --- a/modules/local/fusioncatcher/download/main.nf +++ b/modules/local/fusioncatcher/download/main.nf @@ -42,6 +42,7 @@ process FUSIONCATCHER_DOWNLOAD { """ stub: + def human_version = "v102" """ mkdir human_${human_version} diff --git a/nextflow.config b/nextflow.config index c3f37c05..16ab7b01 100644 --- a/nextflow.config +++ b/nextflow.config @@ -201,10 +201,9 @@ profiles { podman.enabled = false shifter.enabled = false } - test { includeConfig 'conf/test.config' } - test_build { includeConfig 'conf/test_build.config' } - test_full { includeConfig 'conf/test_full.config' } - test_full_build { includeConfig 'conf/test_full_build.config' } + test { + includeConfig 'conf/test.config' + } gitpod { executor.name = 'local' diff --git a/subworkflows/local/squid_workflow.nf b/subworkflows/local/squid_workflow.nf index 14f81158..1e08c916 100644 --- a/subworkflows/local/squid_workflow.nf +++ b/subworkflows/local/squid_workflow.nf @@ -11,6 +11,7 @@ workflow SQUID_WORKFLOW { reads ch_gtf ch_starindex_ensembl_ref + ch_fasta main: ch_versions = Channel.empty() @@ -30,7 +31,7 @@ workflow SQUID_WORKFLOW { return [meta, sam, []] }.set { sam_indexed } - SAMTOOLS_VIEW_FOR_SQUID ( sam_indexed, [] ) + SAMTOOLS_VIEW_FOR_SQUID ( sam_indexed, ch_fasta, [] ) ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_SQUID.out.versions ) SAMTOOLS_SORT_FOR_SQUID ( SAMTOOLS_VIEW_FOR_SQUID.out.bam ) diff --git a/workflows/rnafusion.nf b/workflows/rnafusion.nf index 4c33502a..e0f4ea08 100644 --- a/workflows/rnafusion.nf +++ b/workflows/rnafusion.nf @@ -174,7 +174,8 @@ workflow RNAFUSION { SQUID_WORKFLOW ( ch_cat_fastq, ch_gtf, - ch_starindex_ensembl_ref + ch_starindex_ensembl_ref, + ch_fasta ) ch_versions = ch_versions.mix(SQUID_WORKFLOW.out.versions.first().ifEmpty(null)) From ce3288a99131fe7b7ad17fab4b1a82b04473f35d Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Thu, 8 Dec 2022 13:13:41 +0000 Subject: [PATCH 084/176] Template update for nf-core/tools version 2.7.1 --- .devcontainer/devcontainer.json | 27 +++++++++++++ .gitattributes | 1 + .github/CONTRIBUTING.md | 16 ++++++++ .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/workflows/ci.yml | 8 +++- .github/workflows/fix-linting.yml | 6 +-- .github/workflows/linting.yml | 18 +++++---- .github/workflows/linting_comment.yml | 2 +- .prettierignore | 2 + CITATION.cff | 56 --------------------------- README.md | 4 +- assets/slackreport.json | 34 ++++++++++++++++ docs/usage.md | 24 +++++++----- lib/NfcoreSchema.groovy | 1 - lib/NfcoreTemplate.groovy | 41 +++++++++++++++----- lib/WorkflowMain.groovy | 18 ++++++--- modules.json | 9 +++-- modules/local/samplesheet_check.nf | 4 ++ nextflow.config | 12 ++++-- nextflow_schema.json | 8 +++- workflows/rnafusion.nf | 11 +++--- 21 files changed, 193 insertions(+), 111 deletions(-) create mode 100644 .devcontainer/devcontainer.json delete mode 100644 CITATION.cff create mode 100644 assets/slackreport.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..ea27a584 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,27 @@ +{ + "name": "nfcore", + "image": "nfcore/gitpod:latest", + "remoteUser": "gitpod", + + // Configure tool-specific properties. + "customizations": { + // Configure properties specific to VS Code. + "vscode": { + // Set *default* container specific settings.json values on container create. + "settings": { + "python.defaultInterpreterPath": "/opt/conda/bin/python", + "python.linting.enabled": true, + "python.linting.pylintEnabled": true, + "python.formatting.autopep8Path": "/opt/conda/bin/autopep8", + "python.formatting.yapfPath": "/opt/conda/bin/yapf", + "python.linting.flake8Path": "/opt/conda/bin/flake8", + "python.linting.pycodestylePath": "/opt/conda/bin/pycodestyle", + "python.linting.pydocstylePath": "/opt/conda/bin/pydocstyle", + "python.linting.pylintPath": "/opt/conda/bin/pylint" + }, + + // Add the IDs of extensions you want installed when the container is created. + "extensions": ["ms-python.python", "ms-python.vscode-pylance", "nf-core.nf-core-extensionpack"] + } + } +} diff --git a/.gitattributes b/.gitattributes index 050bb120..7a2dabc2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ *.config linguist-language=nextflow +*.nf.test linguist-language=nextflow modules/nf-core/** linguist-generated subworkflows/nf-core/** linguist-generated diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 9ae9e986..d4b48eae 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -101,3 +101,19 @@ If you are using a new feature from core Nextflow, you may bump the minimum requ ### Images and figures For overview images and other documents we follow the nf-core [style guidelines and examples](https://nf-co.re/developers/design_guidelines). + +## GitHub Codespaces + +This repo includes a devcontainer configuration which will create a GitHub Codespaces for Nextflow development! This is an online developer environment that runs in your browser, complete with VSCode and a terminal. + +To get started: + +- Open the repo in [Codespaces](https://github.com/nf-core/rnafusion/codespaces) +- Tools installed + - nf-core + - Nextflow + +Devcontainer specs: + +- [DevContainer config](.devcontainer/devcontainer.json) +- [Dockerfile](.devcontainer/Dockerfile) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index a172d421..8ed5ffe6 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -42,7 +42,7 @@ body: attributes: label: System information description: | - * Nextflow version _(eg. 21.10.3)_ + * Nextflow version _(eg. 22.10.1)_ * Hardware _(eg. HPC, Desktop, Cloud)_ * Executor _(eg. slurm, local, awsbatch)_ * Container engine: _(e.g. Docker, Singularity, Conda, Podman, Shifter or Charliecloud)_ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e611505..ff58f38e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,10 @@ on: env: NXF_ANSI_LOG: false +concurrency: + group: "${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}" + cancel-in-progress: true + jobs: test: name: Run pipeline with test data @@ -20,11 +24,11 @@ jobs: strategy: matrix: NXF_VER: - - "21.10.3" + - "22.10.1" - "latest-everything" steps: - name: Check out pipeline code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install Nextflow uses: nf-core/setup-nextflow@v1 diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml index 2ffbb6ea..f3754dfa 100644 --- a/.github/workflows/fix-linting.yml +++ b/.github/workflows/fix-linting.yml @@ -24,7 +24,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.nf_core_bot_auth_token }} - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 - name: Install Prettier run: npm install -g prettier @prettier/plugin-php @@ -34,9 +34,9 @@ jobs: id: prettier_status run: | if prettier --check ${GITHUB_WORKSPACE}; then - echo "::set-output name=result::pass" + echo "name=result::pass" >> $GITHUB_OUTPUT else - echo "::set-output name=result::fail" + echo "name=result::fail" >> $GITHUB_OUTPUT fi - name: Run 'prettier --write' diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 8a5ce69b..858d622e 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -4,6 +4,8 @@ name: nf-core linting # that the code meets the nf-core guidelines. on: push: + branches: + - dev pull_request: release: types: [published] @@ -12,9 +14,9 @@ jobs: EditorConfig: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 - name: Install editorconfig-checker run: npm install -g editorconfig-checker @@ -25,9 +27,9 @@ jobs: Prettier: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 - name: Install Prettier run: npm install -g prettier @@ -38,7 +40,7 @@ jobs: PythonBlack: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Check code lints with Black uses: psf/black@stable @@ -69,12 +71,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out pipeline code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install Nextflow uses: nf-core/setup-nextflow@v1 - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 with: python-version: "3.7" architecture: "x64" @@ -97,7 +99,7 @@ jobs: - name: Upload linting log file artifact if: ${{ always() }} - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: linting-logs path: | diff --git a/.github/workflows/linting_comment.yml b/.github/workflows/linting_comment.yml index 04758f61..39635186 100644 --- a/.github/workflows/linting_comment.yml +++ b/.github/workflows/linting_comment.yml @@ -18,7 +18,7 @@ jobs: - name: Get PR number id: pr_number - run: echo "::set-output name=pr_number::$(cat linting-logs/PR_number.txt)" + run: echo "name=pr_number::$(cat linting-logs/PR_number.txt)" >> $GITHUB_OUTPUT - name: Post PR comment uses: marocchino/sticky-pull-request-comment@v2 diff --git a/.prettierignore b/.prettierignore index eb74a574..437d763d 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,6 @@ email_template.html adaptivecard.json +slackreport.json .nextflow* work/ data/ @@ -8,3 +9,4 @@ results/ testing/ testing* *.pyc +bin/ diff --git a/CITATION.cff b/CITATION.cff deleted file mode 100644 index 017666c0..00000000 --- a/CITATION.cff +++ /dev/null @@ -1,56 +0,0 @@ -cff-version: 1.2.0 -message: "If you use `nf-core tools` in your work, please cite the `nf-core` publication" -authors: - - family-names: Ewels - given-names: Philip - - family-names: Peltzer - given-names: Alexander - - family-names: Fillinger - given-names: Sven - - family-names: Patel - given-names: Harshil - - family-names: Alneberg - given-names: Johannes - - family-names: Wilm - given-names: Andreas - - family-names: Garcia - given-names: Maxime Ulysse - - family-names: Di Tommaso - given-names: Paolo - - family-names: Nahnsen - given-names: Sven -title: "The nf-core framework for community-curated bioinformatics pipelines." -version: 2.4.1 -doi: 10.1038/s41587-020-0439-x -date-released: 2022-05-16 -url: https://github.com/nf-core/tools -prefered-citation: - type: article - authors: - - family-names: Ewels - given-names: Philip - - family-names: Peltzer - given-names: Alexander - - family-names: Fillinger - given-names: Sven - - family-names: Patel - given-names: Harshil - - family-names: Alneberg - given-names: Johannes - - family-names: Wilm - given-names: Andreas - - family-names: Garcia - given-names: Maxime Ulysse - - family-names: Di Tommaso - given-names: Paolo - - family-names: Nahnsen - given-names: Sven - doi: 10.1038/s41587-020-0439-x - journal: nature biotechnology - start: 276 - end: 278 - title: "The nf-core framework for community-curated bioinformatics pipelines." - issue: 3 - volume: 38 - year: 2020 - url: https://dx.doi.org/10.1038/s41587-020-0439-x diff --git a/README.md b/README.md index 979d1dc5..aa92b95d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/rnafusion/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX) -[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A521.10.3-23aa62.svg)](https://www.nextflow.io/) +[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A522.10.1-23aa62.svg)](https://www.nextflow.io/) [![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/) [![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/) [![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/) @@ -31,7 +31,7 @@ On release, automated continuous integration tests run the pipeline on a full-si ## Quick Start -1. Install [`Nextflow`](https://www.nextflow.io/docs/latest/getstarted.html#installation) (`>=21.10.3`) +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))_. diff --git a/assets/slackreport.json b/assets/slackreport.json new file mode 100644 index 00000000..043d02f2 --- /dev/null +++ b/assets/slackreport.json @@ -0,0 +1,34 @@ +{ + "attachments": [ + { + "fallback": "Plain-text summary of the attachment.", + "color": "<% if (success) { %>good<% } else { %>danger<%} %>", + "author_name": "sanger-tol/readmapping v${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": [ + { + "title": "Command used to launch the workflow", + "value": "```${commandLine}```", + "short": false + } + <% + if (!success) { %> + , + { + "title": "Full error message", + "value": "```${errorReport}```", + "short": false + }, + { + "title": "Pipeline configuration", + "value": "<% out << summary.collect{ k,v -> k == "hook_url" ? "_${k}_: (_hidden_)" : ( ( v.class.toString().contains('Path') || ( v.class.toString().contains('String') && v.contains('/') ) ) ? "_${k}_: `${v}`" : (v.class.toString().contains('DateTime') ? ("_${k}_: " + v.format(java.time.format.DateTimeFormatter.ofLocalizedDateTime(java.time.format.FormatStyle.MEDIUM))) : "_${k}_: ${v}") ) }.join(",\n") %>", + "short": false + } + <% } + %> + ], + "footer": "Completed at <% out << dateComplete.format(java.time.format.DateTimeFormatter.ofLocalizedDateTime(java.time.format.FormatStyle.MEDIUM)) %> (duration: ${duration})" + } + ] +} diff --git a/docs/usage.md b/docs/usage.md index 8a6d9909..977e4b38 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -83,9 +83,9 @@ nextflow pull nf-core/rnafusion It is a good idea to specify a pipeline version when running the pipeline on your data. This ensures that a specific version of the pipeline code and software are used when you run your pipeline. If you keep using the same tag, you'll be running the same version of the pipeline, even if there have been changes to the code since. -First, go to the [nf-core/rnafusion releases page](https://github.com/nf-core/rnafusion/releases) and find the latest version number - numeric only (eg. `1.3.1`). Then specify this when running the pipeline with `-r` (one hyphen) - eg. `-r 1.3.1`. +First, go to the [nf-core/rnafusion releases page](https://github.com/nf-core/rnafusion/releases) and find the latest pipeline version - numeric only (eg. `1.3.1`). Then specify this when running the pipeline with `-r` (one hyphen) - eg. `-r 1.3.1`. Of course, you can switch to another version by changing the number after the `-r` flag. -This version number will be logged in reports when you run the pipeline, so that you'll know what you used when you look back in the future. +This version number will be logged in reports when you run the pipeline, so that you'll know what you used when you look back in the future. For example, at the bottom of the MultiQC reports. ## Core Nextflow arguments @@ -95,7 +95,7 @@ This version number will be logged in reports when you run the pipeline, so that Use this parameter to choose a configuration profile. Profiles can give configuration presets for different compute environments. -Several generic profiles are bundled with the pipeline which instruct the pipeline to use software packaged using different methods (Docker, Singularity, Podman, Shifter, Charliecloud, Conda) - see below. When using Biocontainers, most of these software packaging methods pull Docker containers from quay.io e.g [FastQC](https://quay.io/repository/biocontainers/fastqc) except for Singularity which directly downloads Singularity images via https hosted by the [Galaxy project](https://depot.galaxyproject.org/singularity/) and Conda which downloads and installs software locally from [Bioconda](https://bioconda.github.io/). +Several generic profiles are bundled with the pipeline which instruct the pipeline to use software packaged using different methods (Docker, Singularity, Podman, Shifter, Charliecloud, Conda) - see below. > We highly recommend the use of Docker or Singularity containers for full pipeline reproducibility, however when this is not possible, Conda is also supported. @@ -104,8 +104,11 @@ The pipeline also dynamically loads configurations from [https://github.com/nf-c Note that multiple profiles can be loaded, for example: `-profile test,docker` - the order of arguments is important! They are loaded in sequence, so later profiles can overwrite earlier profiles. -If `-profile` is not specified, the pipeline will run locally and expect all software to be installed and available on the `PATH`. This is _not_ recommended. +If `-profile` is not specified, the pipeline will run locally and expect all software to be installed and available on the `PATH`. This is _not_ recommended, since it can lead to different results on different machines dependent on the computer enviroment. +- `test` + - A profile with a complete configuration for automated testing + - Includes links to test data so needs no other parameters - `docker` - A generic configuration profile to be used with [Docker](https://docker.com/) - `singularity` @@ -118,9 +121,6 @@ If `-profile` is not specified, the pipeline will run locally and expect all sof - A generic configuration profile to be used with [Charliecloud](https://hpc.github.io/charliecloud/) - `conda` - A generic configuration profile to be used with [Conda](https://conda.io/docs/). Please only use Conda as a last resort i.e. when it's not possible to run the pipeline with Docker, Singularity, Podman, Shifter or Charliecloud. -- `test` - - A profile with a complete configuration for automated testing - - Includes links to test data so needs no other parameters ### `-resume` @@ -169,8 +169,14 @@ Work dir: Tip: you can replicate the issue by changing to the process work dir and entering the command `bash .command.run` ``` +#### For beginners + +A first step to bypass this error, you could try to increase the amount of CPUs, memory, and time for the whole pipeline. Therefor you can try to increase the resource for the parameters `--max_cpus`, `--max_memory`, and `--max_time`. Based on the error above, you have to increase the amount of memory. Therefore you can go to the [parameter documentation of rnaseq](https://nf-co.re/rnaseq/3.9/parameters) and scroll down to the `show hidden parameter` button to get the default value for `--max_memory`. In this case 128GB, you than can try to run your pipeline again with `--max_memory 200GB -resume` to skip all process, that were already calculated. If you can not increase the resource of the complete pipeline, you can try to adapt the resource for a single process as mentioned below. + +#### Advanced option on process level + To bypass this error you would need to find exactly which resources are set by the `STAR_ALIGN` process. The quickest way is to search for `process STAR_ALIGN` in the [nf-core/rnaseq Github repo](https://github.com/nf-core/rnaseq/search?q=process+STAR_ALIGN). -We have standardised the structure of Nextflow DSL2 pipelines such that all module files will be present in the `modules/` directory and so, based on the search results, the file we want is `modules/nf-core/software/star/align/main.nf`. +We have standardised the structure of Nextflow DSL2 pipelines such that all module files will be present in the `modules/` directory and so, based on the search results, the file we want is `modules/nf-core/star/align/main.nf`. If you click on the link to that file you will notice that there is a `label` directive at the top of the module that is set to [`label process_high`](https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/modules/nf-core/software/star/align/main.nf#L9). The [Nextflow `label`](https://www.nextflow.io/docs/latest/process.html#label) directive allows us to organise workflow processes in separate groups which can be referenced in a configuration file to select and configure subset of processes having similar computing requirements. The default values for the `process_high` label are set in the pipeline's [`base.config`](https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/conf/base.config#L33-L37) which in this case is defined as 72GB. @@ -189,7 +195,7 @@ process { > > If you get a warning suggesting that the process selector isn't recognised check that the process name has been specified correctly. -### Updating containers +### Updating containers (advanced users) 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. If for some reason you need to use a different version of a particular tool with the pipeline then you just need to identify the `process` name and override the Nextflow `container` definition for that process using the `withName` declaration. For example, in the [nf-core/viralrecon](https://nf-co.re/viralrecon) pipeline a tool called [Pangolin](https://github.com/cov-lineages/pangolin) has been used during the COVID-19 pandemic to assign lineages to SARS-CoV-2 genome sequenced samples. Given that the lineage assignments change quite frequently it doesn't make sense to re-release the nf-core/viralrecon everytime a new version of Pangolin has been released. However, you can override the default container used by the pipeline by creating a custom config file and passing it as a command-line argument via `-c custom.config`. diff --git a/lib/NfcoreSchema.groovy b/lib/NfcoreSchema.groovy index b3d092f8..33cd4f6e 100755 --- a/lib/NfcoreSchema.groovy +++ b/lib/NfcoreSchema.groovy @@ -46,7 +46,6 @@ class NfcoreSchema { 'quiet', 'syslog', 'v', - 'version', // Options for `nextflow run` command 'ansi', diff --git a/lib/NfcoreTemplate.groovy b/lib/NfcoreTemplate.groovy index 27feb009..25a0a74a 100755 --- a/lib/NfcoreTemplate.groovy +++ b/lib/NfcoreTemplate.groovy @@ -32,6 +32,25 @@ class NfcoreTemplate { } } + // + // Generate version string + // + public static String version(workflow) { + String version_string = "" + + if (workflow.manifest.version) { + def prefix_v = workflow.manifest.version[0] != 'v' ? 'v' : '' + version_string += "${prefix_v}${workflow.manifest.version}" + } + + if (workflow.commitId) { + def git_shortsha = workflow.commitId.substring(0, 7) + version_string += "-g${git_shortsha}" + } + + return version_string + } + // // Construct and send completion email // @@ -61,7 +80,7 @@ class NfcoreTemplate { misc_fields['Nextflow Compile Timestamp'] = workflow.nextflow.timestamp def email_fields = [:] - email_fields['version'] = workflow.manifest.version + email_fields['version'] = NfcoreTemplate.version(workflow) email_fields['runName'] = workflow.runName email_fields['success'] = workflow.success email_fields['dateComplete'] = workflow.complete @@ -146,10 +165,10 @@ class NfcoreTemplate { } // - // Construct and send adaptive card - // https://adaptivecards.io + // Construct and send a notification to a web server as JSON + // e.g. Microsoft Teams and Slack // - public static void adaptivecard(workflow, params, summary_params, projectDir, log) { + public static void IM_notification(workflow, params, summary_params, projectDir, log) { def hook_url = params.hook_url def summary = [:] @@ -170,7 +189,7 @@ class NfcoreTemplate { misc_fields['nxf_timestamp'] = workflow.nextflow.timestamp def msg_fields = [:] - msg_fields['version'] = workflow.manifest.version + msg_fields['version'] = NfcoreTemplate.version(workflow) msg_fields['runName'] = workflow.runName msg_fields['success'] = workflow.success msg_fields['dateComplete'] = workflow.complete @@ -178,13 +197,16 @@ class NfcoreTemplate { msg_fields['exitStatus'] = workflow.exitStatus msg_fields['errorMessage'] = (workflow.errorMessage ?: 'None') msg_fields['errorReport'] = (workflow.errorReport ?: 'None') - msg_fields['commandLine'] = workflow.commandLine + msg_fields['commandLine'] = workflow.commandLine.replaceFirst(/ +--hook_url +[^ ]+/, "") msg_fields['projectDir'] = workflow.projectDir msg_fields['summary'] = summary << misc_fields // Render the JSON template def engine = new groovy.text.GStringTemplateEngine() - def hf = new File("$projectDir/assets/adaptivecard.json") + // Different JSON depending on the service provider + // Defaults to "Adaptive Cards" (https://adaptivecards.io), except Slack which has its own format + def json_path = hook_url.contains("hooks.slack.com") ? "slackreport.json" : "adaptivecard.json" + def hf = new File("$projectDir/assets/${json_path}") def json_template = engine.createTemplate(hf).make(msg_fields) def json_message = json_template.toString() @@ -209,7 +231,7 @@ class NfcoreTemplate { 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.red} Pipeline completed successfully, but with errored process(es) ${colors.reset}-" + log.info "-${colors.purple}[$workflow.manifest.name]${colors.yellow} Pipeline completed successfully, but with errored process(es) ${colors.reset}-" } } else { log.info "-${colors.purple}[$workflow.manifest.name]${colors.red} Pipeline completed with errors${colors.reset}-" @@ -297,6 +319,7 @@ class NfcoreTemplate { // public static String logo(workflow, monochrome_logs) { Map colors = logColours(monochrome_logs) + String workflow_version = NfcoreTemplate.version(workflow) String.format( """\n ${dashedLine(monochrome_logs)} @@ -305,7 +328,7 @@ class NfcoreTemplate { ${colors.blue} |\\ | |__ __ / ` / \\ |__) |__ ${colors.yellow}} {${colors.reset} ${colors.blue} | \\| | \\__, \\__/ | \\ |___ ${colors.green}\\`-._,-`-,${colors.reset} ${colors.green}`._,._,\'${colors.reset} - ${colors.purple} ${workflow.manifest.name} v${workflow.manifest.version}${colors.reset} + ${colors.purple} ${workflow.manifest.name} ${workflow_version}${colors.reset} ${dashedLine(monochrome_logs)} """.stripIndent() ) diff --git a/lib/WorkflowMain.groovy b/lib/WorkflowMain.groovy index 014fdc9e..88aeb026 100755 --- a/lib/WorkflowMain.groovy +++ b/lib/WorkflowMain.groovy @@ -19,7 +19,7 @@ class WorkflowMain { } // - // Print help to screen if required + // Generate help string // public static String help(workflow, params, log) { def command = "nextflow run ${workflow.manifest.name} --input samplesheet.csv --genome GRCh37 -profile docker" @@ -32,7 +32,7 @@ class WorkflowMain { } // - // Print parameter summary log to screen + // Generate parameter summary log string // public static String paramsSummaryLog(workflow, params, log) { def summary_log = '' @@ -53,15 +53,21 @@ class WorkflowMain { System.exit(0) } - // Validate workflow parameters via the JSON schema - if (params.validate_params) { - NfcoreSchema.validateParameters(workflow, params, log) + // Print workflow version and exit on --version + if (params.version) { + String workflow_version = NfcoreTemplate.version(workflow) + log.info "${workflow.manifest.name} ${workflow_version}" + System.exit(0) } // Print parameter summary log to screen - log.info paramsSummaryLog(workflow, params, log) + // Validate workflow parameters via the JSON schema + if (params.validate_params) { + NfcoreSchema.validateParameters(workflow, params, log) + } + // Check that a -profile or Nextflow config has been provided to run the pipeline NfcoreTemplate.checkConfigProvided(workflow, log) diff --git a/modules.json b/modules.json index c4862659..8e6d1061 100644 --- a/modules.json +++ b/modules.json @@ -7,15 +7,18 @@ "nf-core": { "custom/dumpsoftwareversions": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905", + "installed_by": ["modules"] }, "fastqc": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905", + "installed_by": ["modules"] }, "multiqc": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905", + "installed_by": ["modules"] } } } diff --git a/modules/local/samplesheet_check.nf b/modules/local/samplesheet_check.nf index 9ed59266..4a961526 100644 --- a/modules/local/samplesheet_check.nf +++ b/modules/local/samplesheet_check.nf @@ -1,5 +1,6 @@ process SAMPLESHEET_CHECK { tag "$samplesheet" + label 'process_single' conda (params.enable_conda ? "conda-forge::python=3.8.3" : null) container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? @@ -13,6 +14,9 @@ process SAMPLESHEET_CHECK { path '*.csv' , emit: csv path "versions.yml", emit: versions + when: + task.ext.when == null || task.ext.when + script: // This script is bundled with the pipeline, in nf-core/rnafusion/bin/ """ check_samplesheet.py \\ diff --git a/nextflow.config b/nextflow.config index 1b90c951..2e85b0ae 100644 --- a/nextflow.config +++ b/nextflow.config @@ -35,6 +35,7 @@ params { monochrome_logs = false hook_url = null help = false + version = false validate_params = true show_hidden_params = false schema_ignore_params = 'genomes' @@ -81,6 +82,7 @@ profiles { debug { process.beforeScript = 'echo $HOSTNAME' } conda { params.enable_conda = true + conda.enabled = true docker.enabled = false singularity.enabled = false podman.enabled = false @@ -89,6 +91,7 @@ profiles { } mamba { params.enable_conda = true + conda.enabled = true conda.useMamba = true docker.enabled = false singularity.enabled = false @@ -104,6 +107,9 @@ profiles { shifter.enabled = false charliecloud.enabled = false } + arm { + docker.runOptions = '-u $(id -u):$(id -g) --platform=linux/amd64' + } singularity { singularity.enabled = true singularity.autoMounts = true @@ -185,11 +191,11 @@ dag { manifest { name = 'nf-core/rnafusion' - author = 'Martin Proks, Annick Renevey' + author = """Martin Proks, Annick Renevey""" homePage = 'https://github.com/nf-core/rnafusion' - description = 'Nextflow rnafusion analysis pipeline, part of the nf-core community.' + description = """Nextflow rnafusion analysis pipeline, part of the nf-core community.""" mainScript = 'main.nf' - nextflowVersion = '!>=21.10.3' + nextflowVersion = '!>=22.10.1' version = '2.2.0dev' doi = '' } diff --git a/nextflow_schema.json b/nextflow_schema.json index 2247b45f..ab8aed9d 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -176,6 +176,12 @@ "fa_icon": "fas fa-question-circle", "hidden": true }, + "version": { + "type": "boolean", + "description": "Display version and exit.", + "fa_icon": "fas fa-question-circle", + "hidden": true + }, "publish_dir_mode": { "type": "string", "default": "copy", @@ -217,7 +223,7 @@ "type": "string", "description": "Incoming hook URL for messaging service", "fa_icon": "fas fa-people-group", - "help_text": "Incoming hook URL for messaging service. Currently, only MS Teams is supported.", + "help_text": "Incoming hook URL for messaging service. Currently, MS Teams and Slack are supported.", "hidden": true }, "multiqc_config": { diff --git a/workflows/rnafusion.nf b/workflows/rnafusion.nf index b33a3041..a17a425d 100644 --- a/workflows/rnafusion.nf +++ b/workflows/rnafusion.nf @@ -82,7 +82,7 @@ workflow RNAFUSION { ch_versions = ch_versions.mix(FASTQC.out.versions.first()) CUSTOM_DUMPSOFTWAREVERSIONS ( - ch_versions.unique().collectFile(name: 'collated_versions.yml') + ch_versions.unique{ it.text }.collectFile(name: 'collated_versions.yml') ) // @@ -102,12 +102,11 @@ workflow RNAFUSION { MULTIQC ( ch_multiqc_files.collect(), - ch_multiqc_config.collect().ifEmpty([]), - ch_multiqc_custom_config.collect().ifEmpty([]), - ch_multiqc_logo.collect().ifEmpty([]) + ch_multiqc_config.toList(), + ch_multiqc_custom_config.toList(), + ch_multiqc_logo.toList() ) multiqc_report = MULTIQC.out.report.toList() - ch_versions = ch_versions.mix(MULTIQC.out.versions) } /* @@ -122,7 +121,7 @@ workflow.onComplete { } NfcoreTemplate.summary(workflow, params, log) if (params.hook_url) { - NfcoreTemplate.adaptivecard(workflow, params, summary_params, projectDir, log) + NfcoreTemplate.IM_notification(workflow, params, summary_params, projectDir, log) } } From a8fce95e6fb9d5c758b39ccce93baa78bb147117 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Mon, 19 Dec 2022 12:08:08 +0000 Subject: [PATCH 085/176] Template update for nf-core/tools version 2.7.2 --- .github/workflows/fix-linting.yml | 4 +- .github/workflows/linting_comment.yml | 2 +- lib/WorkflowMain.groovy | 2 +- modules.json | 6 +- modules/local/samplesheet_check.nf | 2 +- .../custom/dumpsoftwareversions/main.nf | 2 +- .../templates/dumpsoftwareversions.py | 99 ++++++++++--------- modules/nf-core/fastqc/main.nf | 40 +++----- modules/nf-core/multiqc/main.nf | 2 +- nextflow.config | 3 - nextflow_schema.json | 6 -- workflows/rnafusion.nf | 2 +- 12 files changed, 82 insertions(+), 88 deletions(-) mode change 100644 => 100755 modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml index f3754dfa..14c6c08a 100644 --- a/.github/workflows/fix-linting.yml +++ b/.github/workflows/fix-linting.yml @@ -34,9 +34,9 @@ jobs: id: prettier_status run: | if prettier --check ${GITHUB_WORKSPACE}; then - echo "name=result::pass" >> $GITHUB_OUTPUT + echo "result=pass" >> $GITHUB_OUTPUT else - echo "name=result::fail" >> $GITHUB_OUTPUT + echo "result=fail" >> $GITHUB_OUTPUT fi - name: Run 'prettier --write' diff --git a/.github/workflows/linting_comment.yml b/.github/workflows/linting_comment.yml index 39635186..0bbcd30f 100644 --- a/.github/workflows/linting_comment.yml +++ b/.github/workflows/linting_comment.yml @@ -18,7 +18,7 @@ jobs: - name: Get PR number id: pr_number - run: echo "name=pr_number::$(cat linting-logs/PR_number.txt)" >> $GITHUB_OUTPUT + run: echo "pr_number=$(cat linting-logs/PR_number.txt)" >> $GITHUB_OUTPUT - name: Post PR comment uses: marocchino/sticky-pull-request-comment@v2 diff --git a/lib/WorkflowMain.groovy b/lib/WorkflowMain.groovy index 88aeb026..83ded3a4 100755 --- a/lib/WorkflowMain.groovy +++ b/lib/WorkflowMain.groovy @@ -72,7 +72,7 @@ class WorkflowMain { NfcoreTemplate.checkConfigProvided(workflow, log) // Check that conda channels are set-up correctly - if (params.enable_conda) { + if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { Utils.checkCondaChannels(log) } diff --git a/modules.json b/modules.json index 8e6d1061..d7bc9b18 100644 --- a/modules.json +++ b/modules.json @@ -7,17 +7,17 @@ "nf-core": { "custom/dumpsoftwareversions": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905", + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", "installed_by": ["modules"] }, "fastqc": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905", + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", "installed_by": ["modules"] }, "multiqc": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905", + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", "installed_by": ["modules"] } } diff --git a/modules/local/samplesheet_check.nf b/modules/local/samplesheet_check.nf index 4a961526..695bcdb3 100644 --- a/modules/local/samplesheet_check.nf +++ b/modules/local/samplesheet_check.nf @@ -2,7 +2,7 @@ process SAMPLESHEET_CHECK { tag "$samplesheet" label 'process_single' - conda (params.enable_conda ? "conda-forge::python=3.8.3" : null) + conda "conda-forge::python=3.8.3" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/python:3.8.3' : 'quay.io/biocontainers/python:3.8.3' }" diff --git a/modules/nf-core/custom/dumpsoftwareversions/main.nf b/modules/nf-core/custom/dumpsoftwareversions/main.nf index cebb6e05..3df21765 100644 --- a/modules/nf-core/custom/dumpsoftwareversions/main.nf +++ b/modules/nf-core/custom/dumpsoftwareversions/main.nf @@ -2,7 +2,7 @@ process CUSTOM_DUMPSOFTWAREVERSIONS { label 'process_single' // Requires `pyyaml` which does not have a dedicated container but is in the MultiQC container - conda (params.enable_conda ? 'bioconda::multiqc=1.13' : null) + conda "bioconda::multiqc=1.13" 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' }" diff --git a/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py b/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py old mode 100644 new mode 100755 index 787bdb7b..e55b8d43 --- a/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py +++ b/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py @@ -1,5 +1,9 @@ #!/usr/bin/env python + +"""Provide functions to merge multiple versions.yml files.""" + + import platform from textwrap import dedent @@ -7,6 +11,7 @@ def _make_versions_html(versions): + """Generate a tabular HTML output of all versions for MultiQC.""" html = [ dedent( """\\ @@ -45,47 +50,53 @@ def _make_versions_html(versions): return "\\n".join(html) -versions_this_module = {} -versions_this_module["${task.process}"] = { - "python": platform.python_version(), - "yaml": yaml.__version__, -} - -with open("$versions") as f: - versions_by_process = yaml.load(f, Loader=yaml.BaseLoader) | versions_this_module - -# aggregate versions by the module name (derived from fully-qualified process name) -versions_by_module = {} -for process, process_versions in versions_by_process.items(): - module = process.split(":")[-1] - try: - if versions_by_module[module] != process_versions: - raise AssertionError( - "We assume that software versions are the same between all modules. " - "If you see this error-message it means you discovered an edge-case " - "and should open an issue in nf-core/tools. " - ) - except KeyError: - versions_by_module[module] = process_versions - -versions_by_module["Workflow"] = { - "Nextflow": "$workflow.nextflow.version", - "$workflow.manifest.name": "$workflow.manifest.version", -} - -versions_mqc = { - "id": "software_versions", - "section_name": "${workflow.manifest.name} Software Versions", - "section_href": "https://github.com/${workflow.manifest.name}", - "plot_type": "html", - "description": "are collected at run time from the software output.", - "data": _make_versions_html(versions_by_module), -} - -with open("software_versions.yml", "w") as f: - yaml.dump(versions_by_module, f, default_flow_style=False) -with open("software_versions_mqc.yml", "w") as f: - yaml.dump(versions_mqc, f, default_flow_style=False) - -with open("versions.yml", "w") as f: - yaml.dump(versions_this_module, f, default_flow_style=False) +def main(): + """Load all version files and generate merged output.""" + versions_this_module = {} + versions_this_module["${task.process}"] = { + "python": platform.python_version(), + "yaml": yaml.__version__, + } + + with open("$versions") as f: + versions_by_process = yaml.load(f, Loader=yaml.BaseLoader) | versions_this_module + + # aggregate versions by the module name (derived from fully-qualified process name) + versions_by_module = {} + for process, process_versions in versions_by_process.items(): + module = process.split(":")[-1] + try: + if versions_by_module[module] != process_versions: + raise AssertionError( + "We assume that software versions are the same between all modules. " + "If you see this error-message it means you discovered an edge-case " + "and should open an issue in nf-core/tools. " + ) + except KeyError: + versions_by_module[module] = process_versions + + versions_by_module["Workflow"] = { + "Nextflow": "$workflow.nextflow.version", + "$workflow.manifest.name": "$workflow.manifest.version", + } + + versions_mqc = { + "id": "software_versions", + "section_name": "${workflow.manifest.name} Software Versions", + "section_href": "https://github.com/${workflow.manifest.name}", + "plot_type": "html", + "description": "are collected at run time from the software output.", + "data": _make_versions_html(versions_by_module), + } + + with open("software_versions.yml", "w") as f: + yaml.dump(versions_by_module, f, default_flow_style=False) + with open("software_versions_mqc.yml", "w") as f: + yaml.dump(versions_mqc, f, default_flow_style=False) + + with open("versions.yml", "w") as f: + yaml.dump(versions_this_module, f, default_flow_style=False) + + +if __name__ == "__main__": + main() diff --git a/modules/nf-core/fastqc/main.nf b/modules/nf-core/fastqc/main.nf index 05730368..9ae58381 100644 --- a/modules/nf-core/fastqc/main.nf +++ b/modules/nf-core/fastqc/main.nf @@ -2,7 +2,7 @@ process FASTQC { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::fastqc=0.11.9" : null) + conda "bioconda::fastqc=0.11.9" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/fastqc:0.11.9--0' : 'quay.io/biocontainers/fastqc:0.11.9--0' }" @@ -20,30 +20,22 @@ process FASTQC { script: def args = task.ext.args ?: '' - // Add soft-links to original FastQs for consistent naming in pipeline def prefix = task.ext.prefix ?: "${meta.id}" - if (meta.single_end) { - """ - [ ! -f ${prefix}.fastq.gz ] && ln -s $reads ${prefix}.fastq.gz - fastqc $args --threads $task.cpus ${prefix}.fastq.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fastqc: \$( fastqc --version | sed -e "s/FastQC v//g" ) - END_VERSIONS - """ - } else { - """ - [ ! -f ${prefix}_1.fastq.gz ] && ln -s ${reads[0]} ${prefix}_1.fastq.gz - [ ! -f ${prefix}_2.fastq.gz ] && ln -s ${reads[1]} ${prefix}_2.fastq.gz - fastqc $args --threads $task.cpus ${prefix}_1.fastq.gz ${prefix}_2.fastq.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fastqc: \$( fastqc --version | sed -e "s/FastQC v//g" ) - END_VERSIONS - """ - } + // Make list of old name and new name pairs to use for renaming in the bash while loop + def old_new_pairs = reads instanceof Path || reads.size() == 1 ? [[ reads, "${prefix}.${reads.extension}" ]] : reads.withIndex().collect { entry, index -> [ entry, "${prefix}_${index + 1}.${entry.extension}" ] } + def rename_to = old_new_pairs*.join(' ').join(' ') + def renamed_files = old_new_pairs.collect{ old_name, new_name -> new_name }.join(' ') + """ + printf "%s %s\\n" $rename_to | while read old_name new_name; do + [ -f "\${new_name}" ] || ln -s \$old_name \$new_name + done + fastqc $args --threads $task.cpus $renamed_files + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fastqc: \$( fastqc --version | sed -e "s/FastQC v//g" ) + END_VERSIONS + """ stub: def prefix = task.ext.prefix ?: "${meta.id}" diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index a8159a57..68f66bea 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -1,7 +1,7 @@ process MULTIQC { label 'process_single' - conda (params.enable_conda ? 'bioconda::multiqc=1.13' : null) + conda "bioconda::multiqc=1.13" 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' }" diff --git a/nextflow.config b/nextflow.config index 2e85b0ae..eba99080 100644 --- a/nextflow.config +++ b/nextflow.config @@ -39,7 +39,6 @@ params { validate_params = true show_hidden_params = false schema_ignore_params = 'genomes' - enable_conda = false // Config options @@ -81,7 +80,6 @@ try { profiles { debug { process.beforeScript = 'echo $HOSTNAME' } conda { - params.enable_conda = true conda.enabled = true docker.enabled = false singularity.enabled = false @@ -90,7 +88,6 @@ profiles { charliecloud.enabled = false } mamba { - params.enable_conda = true conda.enabled = true conda.useMamba = true docker.enabled = false diff --git a/nextflow_schema.json b/nextflow_schema.json index ab8aed9d..31308425 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -263,12 +263,6 @@ "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." - }, - "enable_conda": { - "type": "boolean", - "description": "Run this workflow with Conda. You can also use '-profile conda' instead of providing this parameter.", - "hidden": true, - "fa_icon": "fas fa-bacon" } } } diff --git a/workflows/rnafusion.nf b/workflows/rnafusion.nf index a17a425d..71b63738 100644 --- a/workflows/rnafusion.nf +++ b/workflows/rnafusion.nf @@ -82,7 +82,7 @@ workflow RNAFUSION { ch_versions = ch_versions.mix(FASTQC.out.versions.first()) CUSTOM_DUMPSOFTWAREVERSIONS ( - ch_versions.unique{ it.text }.collectFile(name: 'collated_versions.yml') + ch_versions.unique().collectFile(name: 'collated_versions.yml') ) // From 08ba0b32ab71a9a2cf03be484b613a58e455bba8 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 30 Jan 2023 18:33:44 +0100 Subject: [PATCH 086/176] solve linting and update modules --- modules.json | 52 +++++++++++++------ modules/nf-core/arriba/main.nf | 2 +- modules/nf-core/cat/fastq/main.nf | 2 +- .../templates/dumpsoftwareversions.py | 2 - modules/nf-core/fastqc/main.nf | 2 +- modules/nf-core/kallisto/index/main.nf | 2 +- modules/nf-core/multiqc/main.nf | 6 +-- .../nf-core/picard/collectwgsmetrics/main.nf | 18 ++++--- .../nf-core/picard/collectwgsmetrics/meta.yml | 24 ++++++++- modules/nf-core/picard/markduplicates/main.nf | 2 +- modules/nf-core/qualimap/rnaseq/main.nf | 2 +- modules/nf-core/samtools/faidx/main.nf | 6 +-- modules/nf-core/samtools/index/main.nf | 6 +-- modules/nf-core/samtools/sort/main.nf | 6 +-- modules/nf-core/samtools/view/main.nf | 6 +-- modules/nf-core/star/align/main.nf | 6 +-- modules/nf-core/star/genomegenerate/main.nf | 6 +-- modules/nf-core/stringtie/merge/main.nf | 20 +++++-- modules/nf-core/stringtie/merge/meta.yml | 2 +- modules/nf-core/stringtie/stringtie/main.nf | 35 +++++++++---- modules/nf-core/stringtie/stringtie/meta.yml | 4 +- nextflow_schema.json | 6 --- 22 files changed, 140 insertions(+), 77 deletions(-) mode change 100644 => 100755 modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py diff --git a/modules.json b/modules.json index 312d3558..3bd594a3 100644 --- a/modules.json +++ b/modules.json @@ -12,65 +12,83 @@ }, "cat/fastq": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "installed_by": ["modules"] }, "custom/dumpsoftwareversions": { - "branch": "master", - "git_sha": "8022c68e7403eecbd8ba9c49496f69f8c49d50f0" - }, - "fastqc": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", "installed_by": ["modules"] }, - "multiqc": { + "fastqc": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", "installed_by": ["modules"] }, "kallisto/index": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "installed_by": ["modules"] }, "multiqc": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "ee80d14721e76e2e079103b8dcd5d57129e584ba", + "installed_by": ["modules"] }, "picard/collectwgsmetrics": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "installed_by": ["modules"] }, "picard/markduplicates": { "branch": "master", - "git_sha": "eca65aa4a5e2e192ac44d6962c8f9260f314ffb8" + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "installed_by": ["modules"] }, "qualimap/rnaseq": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "installed_by": ["modules"] }, "samtools/faidx": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "installed_by": ["modules"] }, "samtools/index": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "installed_by": ["modules"] }, "samtools/sort": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "installed_by": ["modules"] }, "samtools/view": { "branch": "master", - "git_sha": "202683bfc98ddecdd456ea73268e330bca2e5c5a" + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "installed_by": ["modules"] }, "star/align": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "installed_by": ["modules"] }, "star/genomegenerate": { "branch": "master", - "git_sha": "5e34754d42cd2d5d248ca8673c0a53cdf5624905" + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "installed_by": ["modules"] + }, + "stringtie/merge": { + "branch": "master", + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "installed_by": ["modules"] + }, + "stringtie/stringtie": { + "branch": "master", + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "installed_by": ["modules"] } } } diff --git a/modules/nf-core/arriba/main.nf b/modules/nf-core/arriba/main.nf index 8c4dfcb2..e4b48be2 100644 --- a/modules/nf-core/arriba/main.nf +++ b/modules/nf-core/arriba/main.nf @@ -2,7 +2,7 @@ process ARRIBA { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::arriba=2.3.0" : null) + conda "bioconda::arriba=2.3.0" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/arriba:2.3.0--haa8aa89_0' : 'quay.io/biocontainers/arriba:2.3.0--haa8aa89_0' }" diff --git a/modules/nf-core/cat/fastq/main.nf b/modules/nf-core/cat/fastq/main.nf index 4fa365d3..8a0b5600 100644 --- a/modules/nf-core/cat/fastq/main.nf +++ b/modules/nf-core/cat/fastq/main.nf @@ -2,7 +2,7 @@ process CAT_FASTQ { tag "$meta.id" label 'process_single' - conda (params.enable_conda ? "conda-forge::sed=4.7" : null) + conda "conda-forge::sed=4.7" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/ubuntu:20.04' : 'ubuntu:20.04' }" diff --git a/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py b/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py old mode 100644 new mode 100755 index eec72b77..da033408 --- a/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py +++ b/modules/nf-core/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py @@ -3,8 +3,6 @@ """Provide functions to merge multiple versions.yml files.""" -import platform -from textwrap import dedent import yaml import platform diff --git a/modules/nf-core/fastqc/main.nf b/modules/nf-core/fastqc/main.nf index deeb8b18..9ae58381 100644 --- a/modules/nf-core/fastqc/main.nf +++ b/modules/nf-core/fastqc/main.nf @@ -8,7 +8,7 @@ process FASTQC { 'quay.io/biocontainers/fastqc:0.11.9--0' }" input: - tuple val(meta), path(reads, stageAs: "?/*") + tuple val(meta), path(reads) output: tuple val(meta), path("*.html"), emit: html diff --git a/modules/nf-core/kallisto/index/main.nf b/modules/nf-core/kallisto/index/main.nf index 8b25b7e2..a24024b4 100644 --- a/modules/nf-core/kallisto/index/main.nf +++ b/modules/nf-core/kallisto/index/main.nf @@ -2,7 +2,7 @@ process KALLISTO_INDEX { tag "$fasta" label 'process_medium' - conda (params.enable_conda ? "bioconda::kallisto=0.46.2" : null) + conda "bioconda::kallisto=0.46.2" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/kallisto:0.46.2--h4f7b962_1' : 'quay.io/biocontainers/kallisto:0.46.2--h4f7b962_1' }" diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index 68f66bea..4b604749 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -1,10 +1,10 @@ process MULTIQC { label 'process_single' - 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_files, stageAs: "?/*" diff --git a/modules/nf-core/picard/collectwgsmetrics/main.nf b/modules/nf-core/picard/collectwgsmetrics/main.nf index 2b0aeefe..b767b99c 100644 --- a/modules/nf-core/picard/collectwgsmetrics/main.nf +++ b/modules/nf-core/picard/collectwgsmetrics/main.nf @@ -1,15 +1,17 @@ process PICARD_COLLECTWGSMETRICS { tag "$meta.id" - label 'process_medium' + label 'process_single' - conda (params.enable_conda ? "bioconda::picard=2.27.4 r::r-base" : null) + conda "bioconda::picard=2.27.4 r::r-base" 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' }" input: - tuple val(meta), path(bam) - path fasta + tuple val(meta), path(bam), path(bai) + tuple val(meta2), path(fasta) + tuple val(meta2), path(fai) + path intervallist output: tuple val(meta), path("*_metrics"), emit: metrics @@ -19,9 +21,10 @@ process PICARD_COLLECTWGSMETRICS { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" def avail_mem = 3 + def interval = intervallist ? "--INTERVALS ${intervallist}" : '' if (!task.memory) { log.info '[Picard CollectWgsMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' } else { @@ -34,7 +37,8 @@ process PICARD_COLLECTWGSMETRICS { $args \\ --INPUT $bam \\ --OUTPUT ${prefix}.CollectWgsMetrics.coverage_metrics \\ - --REFERENCE_SEQUENCE ${fasta} + --REFERENCE_SEQUENCE ${fasta} \\ + $interval cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/picard/collectwgsmetrics/meta.yml b/modules/nf-core/picard/collectwgsmetrics/meta.yml index d6c3d012..57ab9cfe 100644 --- a/modules/nf-core/picard/collectwgsmetrics/meta.yml +++ b/modules/nf-core/picard/collectwgsmetrics/meta.yml @@ -22,11 +22,31 @@ input: e.g. [ id:'test', single_end:false ] - bam: type: file - description: BAM file - pattern: "*.{bam}" + description: Aligned reads file + pattern: "*.{bam, cram}" + - bai: + type: file + description: (Optional) Aligned reads file index + pattern: "*.{bai,crai}" + - meta2: + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] - fasta: type: file description: Genome fasta file + pattern: "*.{fa,fasta,fna}" + - meta2: + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fai: + type: file + description: Genome fasta file index + pattern: "*.{fai}" + - intervallist: + type: file + description: Picard Interval List. Defines which contigs to include. Can be generated from a BED file with GATK BedToIntervalList. output: - meta: type: map diff --git a/modules/nf-core/picard/markduplicates/main.nf b/modules/nf-core/picard/markduplicates/main.nf index d1f3aaa1..14800392 100644 --- a/modules/nf-core/picard/markduplicates/main.nf +++ b/modules/nf-core/picard/markduplicates/main.nf @@ -2,7 +2,7 @@ process PICARD_MARKDUPLICATES { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::picard=2.27.4" : null) + conda "bioconda::picard=2.27.4" 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' }" diff --git a/modules/nf-core/qualimap/rnaseq/main.nf b/modules/nf-core/qualimap/rnaseq/main.nf index 38293d27..ad15ebc2 100644 --- a/modules/nf-core/qualimap/rnaseq/main.nf +++ b/modules/nf-core/qualimap/rnaseq/main.nf @@ -2,7 +2,7 @@ process QUALIMAP_RNASEQ { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::qualimap=2.2.2d" : null) + conda "bioconda::qualimap=2.2.2d" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/qualimap:2.2.2d--1' : 'quay.io/biocontainers/qualimap:2.2.2d--1' }" diff --git a/modules/nf-core/samtools/faidx/main.nf b/modules/nf-core/samtools/faidx/main.nf index ef940db2..ce6580d2 100644 --- a/modules/nf-core/samtools/faidx/main.nf +++ b/modules/nf-core/samtools/faidx/main.nf @@ -2,10 +2,10 @@ process SAMTOOLS_FAIDX { tag "$fasta" label 'process_single' - conda (params.enable_conda ? "bioconda::samtools=1.15.1" : null) + conda "bioconda::samtools=1.16.1" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.15.1--h1170115_0' : - 'quay.io/biocontainers/samtools:1.15.1--h1170115_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.16.1--h6899075_1' : + 'quay.io/biocontainers/samtools:1.16.1--h6899075_1' }" input: tuple val(meta), path(fasta) diff --git a/modules/nf-core/samtools/index/main.nf b/modules/nf-core/samtools/index/main.nf index e04e63e8..8b95687a 100644 --- a/modules/nf-core/samtools/index/main.nf +++ b/modules/nf-core/samtools/index/main.nf @@ -2,10 +2,10 @@ process SAMTOOLS_INDEX { tag "$meta.id" label 'process_low' - conda (params.enable_conda ? "bioconda::samtools=1.15.1" : null) + conda "bioconda::samtools=1.16.1" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.15.1--h1170115_0' : - 'quay.io/biocontainers/samtools:1.15.1--h1170115_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.16.1--h6899075_1' : + 'quay.io/biocontainers/samtools:1.16.1--h6899075_1' }" input: tuple val(meta), path(input) diff --git a/modules/nf-core/samtools/sort/main.nf b/modules/nf-core/samtools/sort/main.nf index ab7f1cca..84c167cd 100644 --- a/modules/nf-core/samtools/sort/main.nf +++ b/modules/nf-core/samtools/sort/main.nf @@ -2,10 +2,10 @@ process SAMTOOLS_SORT { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::samtools=1.15.1" : null) + conda "bioconda::samtools=1.16.1" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.15.1--h1170115_0' : - 'quay.io/biocontainers/samtools:1.15.1--h1170115_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.16.1--h6899075_1' : + 'quay.io/biocontainers/samtools:1.16.1--h6899075_1' }" input: tuple val(meta), path(bam) diff --git a/modules/nf-core/samtools/view/main.nf b/modules/nf-core/samtools/view/main.nf index b2f5c678..729c85e5 100644 --- a/modules/nf-core/samtools/view/main.nf +++ b/modules/nf-core/samtools/view/main.nf @@ -2,10 +2,10 @@ process SAMTOOLS_VIEW { tag "$meta.id" label 'process_low' - conda (params.enable_conda ? "bioconda::samtools=1.15.1" : null) + conda "bioconda::samtools=1.16.1" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.15.1--h1170115_0' : - 'quay.io/biocontainers/samtools:1.15.1--h1170115_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.16.1--h6899075_1' : + 'quay.io/biocontainers/samtools:1.16.1--h6899075_1' }" input: tuple val(meta), path(input), path(index) diff --git a/modules/nf-core/star/align/main.nf b/modules/nf-core/star/align/main.nf index 47c58eb0..0e3bd713 100644 --- a/modules/nf-core/star/align/main.nf +++ b/modules/nf-core/star/align/main.nf @@ -2,10 +2,10 @@ process STAR_ALIGN { tag "$meta.id" label 'process_high' - conda (params.enable_conda ? "bioconda::star=2.7.10a bioconda::samtools=1.15.1 conda-forge::gawk=5.1.0" : null) + conda "bioconda::star=2.7.10a bioconda::samtools=1.16.1 conda-forge::gawk=5.1.0" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/mulled-v2-1fa26d1ce03c295fe2fdcf85831a92fbcbd7e8c2:afaaa4c6f5b308b4b6aa2dd8e99e1466b2a6b0cd-0' : - 'quay.io/biocontainers/mulled-v2-1fa26d1ce03c295fe2fdcf85831a92fbcbd7e8c2:afaaa4c6f5b308b4b6aa2dd8e99e1466b2a6b0cd-0' }" + 'https://depot.galaxyproject.org/singularity/mulled-v2-1fa26d1ce03c295fe2fdcf85831a92fbcbd7e8c2:1df389393721fc66f3fd8778ad938ac711951107-0' : + 'quay.io/biocontainers/mulled-v2-1fa26d1ce03c295fe2fdcf85831a92fbcbd7e8c2:1df389393721fc66f3fd8778ad938ac711951107-0' }" input: tuple val(meta), path(reads) diff --git a/modules/nf-core/star/genomegenerate/main.nf b/modules/nf-core/star/genomegenerate/main.nf index 6ec634a1..91462489 100644 --- a/modules/nf-core/star/genomegenerate/main.nf +++ b/modules/nf-core/star/genomegenerate/main.nf @@ -2,10 +2,10 @@ process STAR_GENOMEGENERATE { tag "$fasta" label 'process_high' - conda (params.enable_conda ? "bioconda::star=2.7.10a bioconda::samtools=1.15.1 conda-forge::gawk=5.1.0" : null) + conda "bioconda::star=2.7.10a bioconda::samtools=1.16.1 conda-forge::gawk=5.1.0" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/mulled-v2-1fa26d1ce03c295fe2fdcf85831a92fbcbd7e8c2:afaaa4c6f5b308b4b6aa2dd8e99e1466b2a6b0cd-0' : - 'quay.io/biocontainers/mulled-v2-1fa26d1ce03c295fe2fdcf85831a92fbcbd7e8c2:afaaa4c6f5b308b4b6aa2dd8e99e1466b2a6b0cd-0' }" + 'https://depot.galaxyproject.org/singularity/mulled-v2-1fa26d1ce03c295fe2fdcf85831a92fbcbd7e8c2:1df389393721fc66f3fd8778ad938ac711951107-0' : + 'quay.io/biocontainers/mulled-v2-1fa26d1ce03c295fe2fdcf85831a92fbcbd7e8c2:1df389393721fc66f3fd8778ad938ac711951107-0' }" input: path fasta diff --git a/modules/nf-core/stringtie/merge/main.nf b/modules/nf-core/stringtie/merge/main.nf index c8460c94..f1635afc 100644 --- a/modules/nf-core/stringtie/merge/main.nf +++ b/modules/nf-core/stringtie/merge/main.nf @@ -2,7 +2,7 @@ process STRINGTIE_MERGE { label 'process_medium' // Note: 2.7X indices incompatible with AWS iGenomes. - conda (params.enable_conda ? "bioconda::stringtie=2.2.1" : null) + conda "bioconda::stringtie=2.2.1" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/stringtie:2.2.1--hecb563c_2' : 'quay.io/biocontainers/stringtie:2.2.1--hecb563c_2' }" @@ -19,12 +19,24 @@ process STRINGTIE_MERGE { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + def args = task.ext.args ?: '' + def reference = annotation_gtf ? "-G $annotation_gtf" : "" """ stringtie \\ --merge $stringtie_gtf \\ - -G $annotation_gtf \\ - -o stringtie.merged.gtf + $reference \\ + -o stringtie.merged.gtf \\ + $args + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + stringtie: \$(stringtie --version 2>&1) + END_VERSIONS + """ + + stub: + """ + touch stringtie.merged.gtf cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/stringtie/merge/meta.yml b/modules/nf-core/stringtie/merge/meta.yml index df66696f..2e9784fe 100644 --- a/modules/nf-core/stringtie/merge/meta.yml +++ b/modules/nf-core/stringtie/merge/meta.yml @@ -20,7 +20,7 @@ input: - annotation_gtf: type: file description: | - Annotation gtf file. + Annotation gtf file (optional). pattern: "*.gtf" output: - merged_gtf: diff --git a/modules/nf-core/stringtie/stringtie/main.nf b/modules/nf-core/stringtie/stringtie/main.nf index c70c9819..2d5b035f 100644 --- a/modules/nf-core/stringtie/stringtie/main.nf +++ b/modules/nf-core/stringtie/stringtie/main.nf @@ -2,28 +2,31 @@ process STRINGTIE_STRINGTIE { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::stringtie=2.2.1" : null) + conda "bioconda::stringtie=2.2.1" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/stringtie:2.2.1--hecb563c_2' : 'quay.io/biocontainers/stringtie:2.2.1--hecb563c_2' }" input: tuple val(meta), path(bam) - path gtf + path annotation_gtf output: - tuple val(meta), path("*.coverage.gtf") , emit: coverage_gtf tuple val(meta), path("*.transcripts.gtf"), emit: transcript_gtf tuple val(meta), path("*.abundance.txt") , emit: abundance - tuple val(meta), path("*.ballgown") , emit: ballgown + tuple val(meta), path("*.coverage.gtf") , optional: true, emit: coverage_gtf + tuple val(meta), path("*.ballgown") , optional: true, emit: ballgown path "versions.yml" , emit: versions when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def reference = annotation_gtf ? "-G $annotation_gtf" : "" + def ballgown = annotation_gtf ? "-b ${prefix}.ballgown" : "" + def coverage = annotation_gtf ? "-C ${prefix}.coverage.gtf" : "" def strandedness = '' if (meta.strandedness == 'forward') { @@ -35,11 +38,11 @@ process STRINGTIE_STRINGTIE { stringtie \\ $bam \\ $strandedness \\ - -G $gtf \\ + $reference \\ -o ${prefix}.transcripts.gtf \\ -A ${prefix}.gene.abundance.txt \\ - -C ${prefix}.coverage.gtf \\ - -b ${prefix}.ballgown \\ + $coverage \\ + $ballgown \\ -p $task.cpus \\ $args @@ -48,4 +51,18 @@ process STRINGTIE_STRINGTIE { stringtie: \$(stringtie --version 2>&1) END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.transcripts.gtf + touch ${prefix}.gene.abundance.txt + touch ${prefix}.coverage.gtf + touch ${prefix}.ballgown + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + stringtie: \$(stringtie --version 2>&1) + END_VERSIONS + """ } diff --git a/modules/nf-core/stringtie/stringtie/meta.yml b/modules/nf-core/stringtie/stringtie/meta.yml index 0dda84d0..75518470 100644 --- a/modules/nf-core/stringtie/stringtie/meta.yml +++ b/modules/nf-core/stringtie/stringtie/meta.yml @@ -23,10 +23,10 @@ input: type: file description: | Stringtie transcript gtf output(s). - - gtf: + - annotation_gtf: type: file description: | - Annotation gtf file. + Annotation gtf file (optional). output: - meta: type: map diff --git a/nextflow_schema.json b/nextflow_schema.json index b9353817..66d19be1 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -514,12 +514,6 @@ "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." }, - "enable_conda": { - "type": "boolean", - "description": "Run this workflow with Conda. You can also use '-profile conda' instead of providing this parameter.", - "hidden": true, - "fa_icon": "fas fa-bacon" - }, "seq_center": { "type": "string", "description": "Sequencing center", From 7bbe95fabca6b9a53a70dfecf6f313bbadcc3aa9 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 6 Feb 2023 18:46:50 +0100 Subject: [PATCH 087/176] add stub ci test --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fbbe07b6..045096a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,3 +47,8 @@ jobs: nextflow run ${GITHUB_WORKSPACE} -profile test,docker \ --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly --skip_vis \ --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + + - name: Test with stubs + nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ + --outdir /home/runner/work/rnafusion/rnafusion/results --all \ + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references From bb484582bd732f263001f7cd26a50017fc0bebaf Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 6 Feb 2023 18:50:25 +0100 Subject: [PATCH 088/176] add stub ci test --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 045096a5..af4e33bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,6 +49,7 @@ jobs: --genomes_base /home/runner/work/rnafusion/rnafusion/results/references - name: Test with stubs + run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ --outdir /home/runner/work/rnafusion/rnafusion/results --all \ --genomes_base /home/runner/work/rnafusion/rnafusion/results/references From 089708f155547761ecad61b5dd8a4e54a0a9395d Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 14:14:11 +0100 Subject: [PATCH 089/176] adapt syntax for conda and containers --- CHANGELOG.md | 1 + modules/local/arriba/visualisation/main.nf | 6 +-- modules/local/ensembl/main.nf | 10 ++--- modules/local/ericscript/detect/main.nf | 44 ------------------- modules/local/ericscript/download/main.nf | 24 ---------- modules/local/fusioncatcher/detect/main.nf | 10 ++--- modules/local/fusioncatcher/download/main.nf | 9 ++-- modules/local/fusioninspector/main.nf | 10 ++--- modules/local/fusioninspector_dev/main.nf | 8 ++-- modules/local/fusionreport/detect/main.nf | 2 +- modules/local/fusionreport/download/main.nf | 2 +- modules/local/kallisto/quant/main.nf | 2 +- .../local/picard/collectrnaseqmetrics/main.nf | 2 +- modules/local/pizzly/detect/main.nf | 2 +- modules/local/pizzly/download/main.nf | 10 ++--- modules/local/reformat/main.nf | 2 +- modules/local/squid/annotate/main.nf | 2 +- modules/local/squid/detect/main.nf | 2 +- modules/local/starfusion/build/main.nf | 14 +++--- modules/local/starfusion/detect/main.nf | 10 ++--- modules/local/starfusion/download/main.nf | 11 +++-- .../local/uscs/custom_gtftogenepred/main.nf | 2 +- 22 files changed, 51 insertions(+), 134 deletions(-) delete mode 100644 modules/local/ericscript/detect/main.nf delete mode 100644 modules/local/ericscript/download/main.nf diff --git a/CHANGELOG.md b/CHANGELOG.md index d8939cdb..fdb7262e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - multiQC updated to 1.13a in process dumpsoftwareversion - Updated nf-core and local modules with stub options - Patch fusion-report version with fixed mittelman DB and DB extraction date written into software_version.yaml +- arriba visualisation updated to 2.3.0 ### Fixed diff --git a/modules/local/arriba/visualisation/main.nf b/modules/local/arriba/visualisation/main.nf index d7eeaab4..c2898be7 100644 --- a/modules/local/arriba/visualisation/main.nf +++ b/modules/local/arriba/visualisation/main.nf @@ -2,10 +2,10 @@ process ARRIBA_VISUALISATION { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::arriba=2.1.0" : null) + conda "bioconda::arriba=2.3.0" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/arriba:2.1.0--h3198e80_1' : - 'quay.io/biocontainers/arriba:2.1.0--h3198e80_1' }" + 'https://depot.galaxyproject.org/singularity/arriba:2.3.0--haa8aa89_0' : + 'quay.io/biocontainers/arriba:2.3.0--haa8aa89_0' }" input: tuple val(meta), path(bam), path(bai), path(fusions) diff --git a/modules/local/ensembl/main.nf b/modules/local/ensembl/main.nf index 66a4aeac..5c336745 100644 --- a/modules/local/ensembl/main.nf +++ b/modules/local/ensembl/main.nf @@ -2,12 +2,10 @@ process ENSEMBL_DOWNLOAD { tag "ensembl" label 'process_low' - conda (params.enable_conda ? "bioconda::gnu-wget=1.18" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h5bf99c6_5" - } else { - container "quay.io/biocontainers/gnu-wget:1.18--h5bf99c6_5" - } + conda "bioconda::gnu-wget=1.18" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h5bf99c6_5' + 'quay.io/biocontainers/gnu-wget:1.18--h5bf99c6_5' }" input: val ensembl_version diff --git a/modules/local/ericscript/detect/main.nf b/modules/local/ericscript/detect/main.nf deleted file mode 100644 index baeb5a62..00000000 --- a/modules/local/ericscript/detect/main.nf +++ /dev/null @@ -1,44 +0,0 @@ -process ERICSCRIPT { - tag "eriscript" - label 'process_low' - - conda (params.enable_conda ? "bioconda::ericscript=0.5.5 conda-forge::ncurses=6.1" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "docker.io/nfcore/rnafusion:ericscript_0.5.5" - } else { - container "docker.io/nfcore/rnafusion:ericscript_0.5.5" - } - - input: - tuple val(meta), path(reads) - path reference - - output: - tuple val(meta), path("*.results.filtered.tsv"), emit: fusions - tuple val(meta), path("*.results.total.tsv") , emit: fusions_total - path "versions.yml" , emit: versions - - script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - """ - - ericscript.pl \\ - -db $reference \\ - -name ${prefix} \\ - -p $task.cpus \\ - -o . \\ - $reads \\ - $args - - echo \$(wget -V 2>&1) | grep "GNU Wget" | cut -d" " -f3 > versions.yml - - """ - - stub: - """ - touch ${prefix}.results.filtered.tsv - touch ${prefix}.results.total.tsv - touch versions.yml - """ -} diff --git a/modules/local/ericscript/download/main.nf b/modules/local/ericscript/download/main.nf deleted file mode 100644 index 95510c15..00000000 --- a/modules/local/ericscript/download/main.nf +++ /dev/null @@ -1,24 +0,0 @@ -process ERICSCRIPT_DOWNLOAD { - tag "eriscript" - label 'process_low' - - conda (params.enable_conda ? "bioconda::gnu-wget=1.18" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h5bf99c6_5" - } else { - container "quay.io/biocontainers/gnu-wget:1.18--h5bf99c6_5" - } - - output: - path "versions.yml" , emit: versions - path "*" , emit: reference - - script: - """ - wget http://ngi-igenomes.s3.amazonaws.com/igenomes/Homo_sapiens/Ensembl/GRCh38/Sequence/ericscript_db_homosapiens_ensembl84.tar.bz2 - tar jxf ericscript_db_homosapiens_ensembl84.tar.bz2 --strip-components=2 - rm ericscript_db_homosapiens_ensembl84.tar.bz2 - - echo \$(wget -V 2>&1) | grep "GNU Wget" | cut -d" " -f3 > versions.yml - """ -} diff --git a/modules/local/fusioncatcher/detect/main.nf b/modules/local/fusioncatcher/detect/main.nf index 12018c42..24504212 100644 --- a/modules/local/fusioncatcher/detect/main.nf +++ b/modules/local/fusioncatcher/detect/main.nf @@ -2,12 +2,10 @@ process FUSIONCATCHER { tag "$meta.id" label 'process_high' - conda (params.enable_conda ? "bioconda::fusioncatcher=1.33" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "docker.io/clinicalgenomics/fusioncatcher:1.33" - } else { - container "docker.io/clinicalgenomics/fusioncatcher:1.33" - } + conda "bioconda::fusioncatcher=1.33" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'docker.io/clinicalgenomics/fusioncatcher:1.33' + 'docker.io/clinicalgenomics/fusioncatcher:1.33' }" input: tuple val(meta), path(fasta) diff --git a/modules/local/fusioncatcher/download/main.nf b/modules/local/fusioncatcher/download/main.nf index 119f2523..cfec0847 100644 --- a/modules/local/fusioncatcher/download/main.nf +++ b/modules/local/fusioncatcher/download/main.nf @@ -2,13 +2,10 @@ process FUSIONCATCHER_DOWNLOAD { tag "fusioncatcher_download" label 'process_medium' - conda (params.enable_conda ? "bioconda::fusioncatcher=1.33" : null) + conda "bioconda::fusioncatcher=1.33" if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - - container "docker.io/clinicalgenomics/fusioncatcher:1.33" - } else { - container "docker.io/clinicalgenomics/fusioncatcher:1.33" - } + 'docker.io/clinicalgenomics/fusioncatcher:1.33' + 'docker.io/clinicalgenomics/fusioncatcher:1.33' }" output: path "*" , emit: reference diff --git a/modules/local/fusioninspector/main.nf b/modules/local/fusioninspector/main.nf index 9039bbfc..99d62dff 100644 --- a/modules/local/fusioninspector/main.nf +++ b/modules/local/fusioninspector/main.nf @@ -2,12 +2,10 @@ process FUSIONINSPECTOR { tag "$meta.id" label 'process_high' - conda (params.enable_conda ? "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity=date.2011_11_2 bioconda::samtools=1.9 bioconda::star=2.7.8a" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "docker.io/trinityctat/starfusion:1.10.1" - } else { - container "docker.io/trinityctat/starfusion:1.10.1" - } + conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity=date.2011_11_2 bioconda::samtools=1.9 bioconda::star=2.7.8a" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'docker.io/trinityctat/starfusion:1.10.1' + 'docker.io/trinityctat/starfusion:1.10.1' }" input: tuple val(meta), path(reads), path(fusion_list) diff --git a/modules/local/fusioninspector_dev/main.nf b/modules/local/fusioninspector_dev/main.nf index f8c28a86..ea23ff3e 100644 --- a/modules/local/fusioninspector_dev/main.nf +++ b/modules/local/fusioninspector_dev/main.nf @@ -2,11 +2,9 @@ process FUSIONINSPECTOR_DEV { tag "$meta.id" label 'process_high' - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "docker.io/trinityctat/fusioninspector:2.8.0-dev1" - } else { - container "docker.io/trinityctat/fusioninspector:2.8.0-dev1" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'docker.io/trinityctat/fusioninspector:2.8.0-dev1' + 'docker.io/trinityctat/fusioninspector:2.8.0-dev1' }" input: tuple val(meta), path(reads), path(fusion_list) diff --git a/modules/local/fusionreport/detect/main.nf b/modules/local/fusionreport/detect/main.nf index 9cafa4a3..c98e00f3 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/local/fusionreport/detect/main.nf @@ -3,7 +3,7 @@ process FUSIONREPORT { label 'process_medium' // Note: 2.7X indices incompatible with AWS iGenomes. - conda (params.enable_conda ? 'bioconda::star=2.7.9a' : null) + conda "bioconda::star=2.7.9a" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'docker.io/clinicalgenomics/fusion-report:2.1.5patched' : 'docker.io/clinicalgenomics/fusion-report:2.1.5patched' }" diff --git a/modules/local/fusionreport/download/main.nf b/modules/local/fusionreport/download/main.nf index 166f0f3e..c4d96afc 100644 --- a/modules/local/fusionreport/download/main.nf +++ b/modules/local/fusionreport/download/main.nf @@ -3,7 +3,7 @@ process FUSIONREPORT_DOWNLOAD { label 'process_medium' // Note: 2.7X indices incompatible with AWS iGenomes. - conda (params.enable_conda ? 'bioconda::star=2.7.9a' : null) + conda "bioconda::star=2.7.9a" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'docker.io/clinicalgenomics/fusion-report:2.1.5patched' : 'docker.io/clinicalgenomics/fusion-report:2.1.5patched' }" diff --git a/modules/local/kallisto/quant/main.nf b/modules/local/kallisto/quant/main.nf index bc0f3511..4269a4aa 100644 --- a/modules/local/kallisto/quant/main.nf +++ b/modules/local/kallisto/quant/main.nf @@ -2,7 +2,7 @@ process KALLISTO_QUANT { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::kallisto=0.46.2" : null) + conda "bioconda::kallisto=0.46.2" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/kallisto:0.46.2--h4f7b962_1' : 'quay.io/biocontainers/kallisto:0.46.2--h4f7b962_1' }" diff --git a/modules/local/picard/collectrnaseqmetrics/main.nf b/modules/local/picard/collectrnaseqmetrics/main.nf index d01c6534..ea04c07b 100644 --- a/modules/local/picard/collectrnaseqmetrics/main.nf +++ b/modules/local/picard/collectrnaseqmetrics/main.nf @@ -2,7 +2,7 @@ process PICARD_COLLECTRNASEQMETRICS { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::picard=2.26.10" : null) + conda "bioconda::picard=2.26.10" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/picard:2.26.10--hdfd78af_0' : 'quay.io/biocontainers/picard:2.26.10--hdfd78af_0' }" diff --git a/modules/local/pizzly/detect/main.nf b/modules/local/pizzly/detect/main.nf index 6222d3ba..422b4a83 100644 --- a/modules/local/pizzly/detect/main.nf +++ b/modules/local/pizzly/detect/main.nf @@ -2,7 +2,7 @@ process PIZZLY { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::kallisto=0.46.2 bioconda::pizzly==0.37.3" : null) + conda "bioconda::kallisto=0.46.2 bioconda::pizzly==0.37.3" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/pizzly:0.37.3--py36_2' : 'quay.io/biocontainers/pizzly:0.37.3--h470a237_3' }" diff --git a/modules/local/pizzly/download/main.nf b/modules/local/pizzly/download/main.nf index d3be739b..be82aed5 100644 --- a/modules/local/pizzly/download/main.nf +++ b/modules/local/pizzly/download/main.nf @@ -2,12 +2,10 @@ process PIZZLY_DOWNLOAD { tag "pizzly" label 'process_medium' - conda (params.enable_conda ? "bioconda::kallisto=0.46.2" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/kallisto:0.46.2--h4f7b962_1" - } else { - container "quay.io/biocontainers/kallisto:0.46.2--h4f7b962_1" - } + conda "bioconda::kallisto=0.46.2" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/kallisto:0.46.2--h4f7b962_1' + 'quay.io/biocontainers/kallisto:0.46.2--h4f7b962_1' }" input: path transcript diff --git a/modules/local/reformat/main.nf b/modules/local/reformat/main.nf index a4a8046f..531bbefa 100644 --- a/modules/local/reformat/main.nf +++ b/modules/local/reformat/main.nf @@ -2,7 +2,7 @@ process REFORMAT { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::bbmap=38.90" : null) + conda "bioconda::bbmap=38.90" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/bbmap:38.90--he522d1c_1' : 'quay.io/biocontainers/bbmap:38.90--he522d1c_1' }" diff --git a/modules/local/squid/annotate/main.nf b/modules/local/squid/annotate/main.nf index 585b082d..18f833cf 100644 --- a/modules/local/squid/annotate/main.nf +++ b/modules/local/squid/annotate/main.nf @@ -3,7 +3,7 @@ process SQUID_ANNOTATE { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::squid=1.5" : null) + conda "bioconda::squid=1.5" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'docker.io/nfcore/rnafusion:squid_1.5-star2.7.1a' : 'docker.io/nfcore/rnafusion:squid_1.5-star2.7.1a' }" diff --git a/modules/local/squid/detect/main.nf b/modules/local/squid/detect/main.nf index 80106c0f..dba86725 100644 --- a/modules/local/squid/detect/main.nf +++ b/modules/local/squid/detect/main.nf @@ -3,7 +3,7 @@ process SQUID { tag "squid" label 'process_medium' - conda (params.enable_conda ? "bioconda::squid=1.5" : null) + conda "bioconda::squid=1.5" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'docker.io/nfcore/rnafusion:squid_1.5-star2.7.1a' : 'docker.io/nfcore/rnafusion:squid_1.5-star2.7.1a' }" diff --git a/modules/local/starfusion/build/main.nf b/modules/local/starfusion/build/main.nf index f50aaa79..ae378b19 100644 --- a/modules/local/starfusion/build/main.nf +++ b/modules/local/starfusion/build/main.nf @@ -1,12 +1,8 @@ process STARFUSION_BUILD { tag 'star-fusion' - conda (params.enable_conda ? "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity=date.2011_11_2 bioconda::samtools=1.9 bioconda::star=2.7.8a" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "docker.io/trinityctat/starfusion:1.10.1" - } else { - container "docker.io/trinityctat/starfusion:1.10.1" - } + conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity=date.2011_11_2 bioconda::samtools=1.9 bioconda::star=2.7.8a" + container "docker.io/trinityctat/starfusion:1.10.1" input: path fasta @@ -16,7 +12,7 @@ process STARFUSION_BUILD { path "*" , emit: reference script: - def binPath = ( params.enable_conda ? "prep_genome_lib.pl" : "/usr/local/src/STAR-Fusion/ctat-genome-lib-builder/prep_genome_lib.pl" ) + def binPath = ( workflow.conda.enabled = true ? "prep_genome_lib.pl" : "/usr/local/src/STAR-Fusion/ctat-genome-lib-builder/prep_genome_lib.pl" ) """ export TMPDIR=/tmp wget http://ftp.ebi.ac.uk/pub/databases/Pfam/releases/Pfam34.0/Pfam-A.hmm.gz --no-check-certificate @@ -38,4 +34,8 @@ process STARFUSION_BUILD { --max_readlength $params.read_length \\ --CPU $task.cpus """ + + stub: + touch + } diff --git a/modules/local/starfusion/detect/main.nf b/modules/local/starfusion/detect/main.nf index 279b3e4e..5863cf6b 100644 --- a/modules/local/starfusion/detect/main.nf +++ b/modules/local/starfusion/detect/main.nf @@ -2,12 +2,10 @@ process STARFUSION { tag "$meta.id" label 'process_high' - conda (params.enable_conda ? "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity=date.2011_11_2 bioconda::samtools=1.9 bioconda::star=2.7.8a" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "docker.io/trinityctat/starfusion:1.10.1" - } else { - container "docker.io/trinityctat/starfusion:1.10.1" - } + conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity=date.2011_11_2 bioconda::samtools=1.9 bioconda::star=2.7.8a" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'docker.io/trinityctat/starfusion:1.10.1' + 'docker.io/trinityctat/starfusion:1.10.1' }" input: tuple val(meta), path(reads), path(junction) diff --git a/modules/local/starfusion/download/main.nf b/modules/local/starfusion/download/main.nf index 88fb1312..75786de8 100644 --- a/modules/local/starfusion/download/main.nf +++ b/modules/local/starfusion/download/main.nf @@ -1,12 +1,11 @@ process STARFUSION_DOWNLOAD { tag 'star-fusion' - conda (params.enable_conda ? "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity=date.2011_11_2 bioconda::samtools=1.9 bioconda::star=2.7.8a" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "docker.io/trinityctat/starfusion:1.10.1" - } else { - container "docker.io/trinityctat/starfusion:1.10.1" - } + conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity=date.2011_11_2 bioconda::samtools=1.9 bioconda::star=2.7.8a" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'docker.io/trinityctat/starfusion:1.10.1' + 'docker.io/trinityctat/starfusion:1.10.1' }" + output: path "ctat_genome_lib_build_dir/*" , emit: reference diff --git a/modules/local/uscs/custom_gtftogenepred/main.nf b/modules/local/uscs/custom_gtftogenepred/main.nf index 74e4c6f3..be852154 100644 --- a/modules/local/uscs/custom_gtftogenepred/main.nf +++ b/modules/local/uscs/custom_gtftogenepred/main.nf @@ -1,7 +1,7 @@ process GTF_TO_REFFLAT { label 'process_low' - conda (params.enable_conda ? "bioconda::ucsc-gtftogenepred=377" : null) + conda "bioconda::ucsc-gtftogenepred=377" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/ucsc-gtftogenepred:377--ha8a8165_5' : 'quay.io/biocontainers/ucsc-gtftogenepred:377--ha8a8165_5' }" From 33b16655a162e689eec170082fa19b939a00f0e6 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 14:18:24 +0100 Subject: [PATCH 090/176] fix i/o for samtools view --- subworkflows/local/squid_workflow.nf | 3 ++- workflows/rnafusion.nf | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/subworkflows/local/squid_workflow.nf b/subworkflows/local/squid_workflow.nf index 14f81158..1e08c916 100644 --- a/subworkflows/local/squid_workflow.nf +++ b/subworkflows/local/squid_workflow.nf @@ -11,6 +11,7 @@ workflow SQUID_WORKFLOW { reads ch_gtf ch_starindex_ensembl_ref + ch_fasta main: ch_versions = Channel.empty() @@ -30,7 +31,7 @@ workflow SQUID_WORKFLOW { return [meta, sam, []] }.set { sam_indexed } - SAMTOOLS_VIEW_FOR_SQUID ( sam_indexed, [] ) + SAMTOOLS_VIEW_FOR_SQUID ( sam_indexed, ch_fasta, [] ) ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_SQUID.out.versions ) SAMTOOLS_SORT_FOR_SQUID ( SAMTOOLS_VIEW_FOR_SQUID.out.bam ) diff --git a/workflows/rnafusion.nf b/workflows/rnafusion.nf index 4403470f..1feba931 100644 --- a/workflows/rnafusion.nf +++ b/workflows/rnafusion.nf @@ -175,7 +175,8 @@ workflow RNAFUSION { SQUID_WORKFLOW ( ch_cat_fastq, ch_gtf, - ch_starindex_ensembl_ref + ch_starindex_ensembl_ref, + ch_fasta ) ch_versions = ch_versions.mix(SQUID_WORKFLOW.out.versions.first().ifEmpty(null)) From 5971c5477aecf515bec9b81bef43d81480523c08 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 15:42:08 +0100 Subject: [PATCH 091/176] fix typos and add stubs --- modules/local/arriba/visualisation/main.nf | 10 ++++++++++ modules/local/ensembl/main.nf | 2 +- modules/local/fusioncatcher/detect/main.nf | 15 ++++++++++++++- modules/local/fusioncatcher/download/main.nf | 17 +++++++++++++++-- modules/local/fusioninspector/main.nf | 4 ++-- modules/local/fusioninspector_dev/main.nf | 2 +- modules/local/fusionreport/detect/main.nf | 12 ++++++++++++ modules/local/fusionreport/download/main.nf | 13 +++++++++++++ modules/local/kallisto/quant/main.nf | 10 ++++++++++ .../local/picard/collectrnaseqmetrics/main.nf | 10 ++++++++++ modules/local/pizzly/detect/main.nf | 11 +++++++++++ modules/local/pizzly/download/main.nf | 11 ++++++++++- modules/local/reformat/main.nf | 13 +++++++++++++ modules/local/squid/annotate/main.nf | 10 ++++++++++ modules/local/squid/detect/main.nf | 10 ++++++++++ modules/local/starfusion/build/main.nf | 12 +++++++++--- modules/local/starfusion/detect/main.nf | 9 ++++++--- modules/local/starfusion/download/main.nf | 14 ++++++++++++-- modules/local/uscs/custom_gtftogenepred/main.nf | 10 ++++++++++ 19 files changed, 179 insertions(+), 16 deletions(-) diff --git a/modules/local/arriba/visualisation/main.nf b/modules/local/arriba/visualisation/main.nf index c2898be7..d31cf9a7 100644 --- a/modules/local/arriba/visualisation/main.nf +++ b/modules/local/arriba/visualisation/main.nf @@ -37,4 +37,14 @@ process ARRIBA_VISUALISATION { arriba: \$(arriba -h | grep 'Version:' 2>&1 | sed 's/Version:\s//') END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.pdf + cat <<-END_VERSIONS > versions.yml + "${task.process}": + arriba: \$(arriba -h | grep 'Version:' 2>&1 | sed 's/Version:\s//') + END_VERSIONS + """ } diff --git a/modules/local/ensembl/main.nf b/modules/local/ensembl/main.nf index 5c336745..22e2043a 100644 --- a/modules/local/ensembl/main.nf +++ b/modules/local/ensembl/main.nf @@ -4,7 +4,7 @@ process ENSEMBL_DOWNLOAD { conda "bioconda::gnu-wget=1.18" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h5bf99c6_5' + 'https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h5bf99c6_5' : 'quay.io/biocontainers/gnu-wget:1.18--h5bf99c6_5' }" input: diff --git a/modules/local/fusioncatcher/detect/main.nf b/modules/local/fusioncatcher/detect/main.nf index 24504212..f668c84a 100644 --- a/modules/local/fusioncatcher/detect/main.nf +++ b/modules/local/fusioncatcher/detect/main.nf @@ -4,7 +4,7 @@ process FUSIONCATCHER { conda "bioconda::fusioncatcher=1.33" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/clinicalgenomics/fusioncatcher:1.33' + 'docker.io/clinicalgenomics/fusioncatcher:1.33' : 'docker.io/clinicalgenomics/fusioncatcher:1.33' }" input: @@ -44,4 +44,17 @@ process FUSIONCATCHER { fusioncatcher: \$(echo \$(fusioncatcher --version 2>&1)| sed 's/fusioncatcher.py //') END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + + """ + touch ${prefix}.fusioncatcher.fusion-genes.txt + touch ${prefix}.fusioncatcher.summary.txt + touch ${prefix}.fusioncatcher.log + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fusioncatcher: \$(echo \$(fusioncatcher --version 2>&1)| sed 's/fusioncatcher.py //') + END_VERSIONS + """ } diff --git a/modules/local/fusioncatcher/download/main.nf b/modules/local/fusioncatcher/download/main.nf index cfec0847..1153d6a4 100644 --- a/modules/local/fusioncatcher/download/main.nf +++ b/modules/local/fusioncatcher/download/main.nf @@ -3,14 +3,17 @@ process FUSIONCATCHER_DOWNLOAD { label 'process_medium' conda "bioconda::fusioncatcher=1.33" - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - 'docker.io/clinicalgenomics/fusioncatcher:1.33' + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'docker.io/clinicalgenomics/fusioncatcher:1.33' : 'docker.io/clinicalgenomics/fusioncatcher:1.33' }" output: path "*" , emit: reference path "versions.yml" , emit: versions + when: + task.ext.when == null || task.ext.when + script: def args = task.ext.args ?: '' @@ -37,4 +40,14 @@ process FUSIONCATCHER_DOWNLOAD { fusioncatcher: \$(echo \$(fusioncatcher --version 2>&1)) END_VERSIONS """ + + stub: + def human_version = "v102" + """ + mkdir human_${human_version} + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fusioncatcher: \$(echo \$(fusioncatcher --version 2>&1)) + END_VERSIONS + """ } diff --git a/modules/local/fusioninspector/main.nf b/modules/local/fusioninspector/main.nf index 99d62dff..acf31b8f 100644 --- a/modules/local/fusioninspector/main.nf +++ b/modules/local/fusioninspector/main.nf @@ -2,9 +2,9 @@ process FUSIONINSPECTOR { tag "$meta.id" label 'process_high' - conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity=date.2011_11_2 bioconda::samtools=1.9 bioconda::star=2.7.8a" + conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/trinityctat/starfusion:1.10.1' + 'docker.io/trinityctat/starfusion:1.10.1' : 'docker.io/trinityctat/starfusion:1.10.1' }" input: diff --git a/modules/local/fusioninspector_dev/main.nf b/modules/local/fusioninspector_dev/main.nf index ea23ff3e..9a8b0f96 100644 --- a/modules/local/fusioninspector_dev/main.nf +++ b/modules/local/fusioninspector_dev/main.nf @@ -3,7 +3,7 @@ process FUSIONINSPECTOR_DEV { label 'process_high' container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/trinityctat/fusioninspector:2.8.0-dev1' + 'docker.io/trinityctat/fusioninspector:2.8.0-dev1' : 'docker.io/trinityctat/fusioninspector:2.8.0-dev1' }" input: diff --git a/modules/local/fusionreport/detect/main.nf b/modules/local/fusionreport/detect/main.nf index c98e00f3..049a8503 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/local/fusionreport/detect/main.nf @@ -41,4 +41,16 @@ process FUSIONREPORT { fusion_report DB retrieval: \$(cat $fusionreport_ref/DB-timestamp.txt) END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.fusionreport_filtered.tsv + touch ${prefix}.fusionreport.tsv + touch index.html + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fusion_report: \$(fusion_report --version | sed 's/fusion-report //') + END_VERSIONS + """ } diff --git a/modules/local/fusionreport/download/main.nf b/modules/local/fusionreport/download/main.nf index c4d96afc..c5b804a7 100644 --- a/modules/local/fusionreport/download/main.nf +++ b/modules/local/fusionreport/download/main.nf @@ -26,4 +26,17 @@ process FUSIONREPORT_DOWNLOAD { fusion_report: \$(fusion_report --version | sed 's/fusion-report //') END_VERSIONS """ + + stub: + """ + touch cosmic.db + touch fusiongdb2.db + touch fusiongdb.db + touch mitelman.db + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fusion_report: \$(fusion_report --version | sed 's/fusion-report //') + END_VERSIONS + """ + } diff --git a/modules/local/kallisto/quant/main.nf b/modules/local/kallisto/quant/main.nf index 4269a4aa..7d3e5dfb 100644 --- a/modules/local/kallisto/quant/main.nf +++ b/modules/local/kallisto/quant/main.nf @@ -33,5 +33,15 @@ process KALLISTO_QUANT { kallisto: \$(echo \$(kallisto 2>&1) | sed 's/^kallisto //; s/Usage.*\$//') END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.kallisto_quant.fusions.txt + cat <<-END_VERSIONS > versions.yml + "${task.process}": + kallisto: \$(echo \$(kallisto 2>&1) | sed 's/^kallisto //; s/Usage.*\$//') + END_VERSIONS + """ } diff --git a/modules/local/picard/collectrnaseqmetrics/main.nf b/modules/local/picard/collectrnaseqmetrics/main.nf index ea04c07b..5203269e 100644 --- a/modules/local/picard/collectrnaseqmetrics/main.nf +++ b/modules/local/picard/collectrnaseqmetrics/main.nf @@ -55,4 +55,14 @@ process PICARD_COLLECTRNASEQMETRICS { picard: \$(picard CollectRnaMetrics --version 2>&1 | grep -o 'Version.*' | cut -f2- -d:) END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}_rna_metrics.txt + cat <<-END_VERSIONS > versions.yml + "${task.process}": + picard: \$(picard CollectRnaMetrics --version 2>&1 | grep -o 'Version.*' | cut -f2- -d:) + END_VERSIONS + """ } diff --git a/modules/local/pizzly/detect/main.nf b/modules/local/pizzly/detect/main.nf index 422b4a83..9f10caf8 100644 --- a/modules/local/pizzly/detect/main.nf +++ b/modules/local/pizzly/detect/main.nf @@ -34,5 +34,16 @@ process PIZZLY { pizzly: \$(pizzly --version | grep pizzly | sed -e "s/pizzly version: //g") END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.pizzly.txt + touch ${prefix}.pizzly.unfiltered.json + cat <<-END_VERSIONS > versions.yml + "${task.process}": + pizzly: \$(pizzly --version | grep pizzly | sed -e "s/pizzly version: //g") + END_VERSIONS + """ } diff --git a/modules/local/pizzly/download/main.nf b/modules/local/pizzly/download/main.nf index be82aed5..e605d422 100644 --- a/modules/local/pizzly/download/main.nf +++ b/modules/local/pizzly/download/main.nf @@ -4,7 +4,7 @@ process PIZZLY_DOWNLOAD { conda "bioconda::kallisto=0.46.2" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/kallisto:0.46.2--h4f7b962_1' + 'https://depot.galaxyproject.org/singularity/kallisto:0.46.2--h4f7b962_1' : 'quay.io/biocontainers/kallisto:0.46.2--h4f7b962_1' }" input: @@ -24,4 +24,13 @@ process PIZZLY_DOWNLOAD { echo \$(kallisto 2>&1) | sed 's/^kallisto //; s/Usage.*\$//' > versions.yml """ + + stub: + """ + touch index.idx + cat <<-END_VERSIONS > versions.yml + "${task.process}": + kallisto: \$(echo \$(kallisto 2>&1) | sed 's/^kallisto //; s/Usage.*\$//') + END_VERSIONS + """ } diff --git a/modules/local/reformat/main.nf b/modules/local/reformat/main.nf index 531bbefa..06325b27 100644 --- a/modules/local/reformat/main.nf +++ b/modules/local/reformat/main.nf @@ -35,6 +35,19 @@ process REFORMAT { + cat <<-END_VERSIONS > versions.yml + "${task.process}": + reformat.sh: \$(echo \$(reformat.sh --version 2>&1)| sed -e "s/BBMap version //g" ) + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + def out1 ="out=${prefix}_R1_trimmed.fq.gz" + def out2 =meta.single_end ? "" : "out=${prefix}_R2_trimmed.fq.gz" + """ + touch $out1 + touch $out2 cat <<-END_VERSIONS > versions.yml "${task.process}": reformat.sh: \$(echo \$(reformat.sh --version 2>&1)| sed -e "s/BBMap version //g" ) diff --git a/modules/local/squid/annotate/main.nf b/modules/local/squid/annotate/main.nf index 18f833cf..37d372df 100644 --- a/modules/local/squid/annotate/main.nf +++ b/modules/local/squid/annotate/main.nf @@ -30,4 +30,14 @@ process SQUID_ANNOTATE { squid: \$(echo \$(squid --version 2>&1) | sed 's/v//') END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.squid.fusions.annotated.txt + cat <<-END_VERSIONS > versions.yml + "${task.process}": + squid: \$(echo \$(squid --version 2>&1) | sed 's/v//') + END_VERSIONS + """ } diff --git a/modules/local/squid/detect/main.nf b/modules/local/squid/detect/main.nf index dba86725..f6f3642c 100644 --- a/modules/local/squid/detect/main.nf +++ b/modules/local/squid/detect/main.nf @@ -29,4 +29,14 @@ process SQUID { squid: \$(echo \$(squid --version 2>&1) | sed 's/v//') END_VERSIONS """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.squid.fusions_sv.txt + cat <<-END_VERSIONS > versions.yml + "${task.process}": + squid: \$(echo \$(squid --version 2>&1) | sed 's/v//') + END_VERSIONS + """ } diff --git a/modules/local/starfusion/build/main.nf b/modules/local/starfusion/build/main.nf index ae378b19..5cbff7bf 100644 --- a/modules/local/starfusion/build/main.nf +++ b/modules/local/starfusion/build/main.nf @@ -1,7 +1,7 @@ process STARFUSION_BUILD { tag 'star-fusion' - conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity=date.2011_11_2 bioconda::samtools=1.9 bioconda::star=2.7.8a" + conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" container "docker.io/trinityctat/starfusion:1.10.1" input: @@ -36,6 +36,12 @@ process STARFUSION_BUILD { """ stub: - touch - + """ + mkdir ctat_genome_lib_build_dir + touch ref_annot.cdna.fa + cat <<-END_VERSIONS > versions.yml + "${task.process}": + STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') + END_VERSIONS + """ } diff --git a/modules/local/starfusion/detect/main.nf b/modules/local/starfusion/detect/main.nf index 5863cf6b..7cd06feb 100644 --- a/modules/local/starfusion/detect/main.nf +++ b/modules/local/starfusion/detect/main.nf @@ -2,9 +2,9 @@ process STARFUSION { tag "$meta.id" label 'process_high' - conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity=date.2011_11_2 bioconda::samtools=1.9 bioconda::star=2.7.8a" + conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/trinityctat/starfusion:1.10.1' + 'docker.io/trinityctat/starfusion:1.10.1' : 'docker.io/trinityctat/starfusion:1.10.1' }" input: @@ -47,7 +47,10 @@ process STARFUSION { touch ${prefix}.starfusion.fusion_predictions.tsv touch ${prefix}.starfusion.abridged.tsv touch ${prefix}.starfusion.abridged.coding_effect.tsv - touch versions.yml + cat <<-END_VERSIONS > versions.yml + "${task.process}": + STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') + END_VERSIONS """ } diff --git a/modules/local/starfusion/download/main.nf b/modules/local/starfusion/download/main.nf index 75786de8..235ca0d1 100644 --- a/modules/local/starfusion/download/main.nf +++ b/modules/local/starfusion/download/main.nf @@ -1,9 +1,9 @@ process STARFUSION_DOWNLOAD { tag 'star-fusion' - conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity=date.2011_11_2 bioconda::samtools=1.9 bioconda::star=2.7.8a" + conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/trinityctat/starfusion:1.10.1' + 'docker.io/trinityctat/starfusion:1.10.1' : 'docker.io/trinityctat/starfusion:1.10.1' }" @@ -22,4 +22,14 @@ process STARFUSION_DOWNLOAD { mv */ctat_genome_lib_build_dir . """ + + stub: + """ + mkdir ctat_genome_lib_build_dir + touch ref_annot.cdna.fa + cat <<-END_VERSIONS > versions.yml + "${task.process}": + STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') + END_VERSIONS + """ } diff --git a/modules/local/uscs/custom_gtftogenepred/main.nf b/modules/local/uscs/custom_gtftogenepred/main.nf index be852154..46052b5a 100644 --- a/modules/local/uscs/custom_gtftogenepred/main.nf +++ b/modules/local/uscs/custom_gtftogenepred/main.nf @@ -24,4 +24,14 @@ process GTF_TO_REFFLAT { gtfToGenePred: 377 END_VERSIONS """ + + stub: + def refflat = gtf + '.refflat' + """ + touch ${refflat} + cat <<-END_VERSIONS > versions.yml + "${task.process}": + gtfToGenePred: 377 + END_VERSIONS + """ } From 3ba0f625fa0bb39d2674ccf308baff631a77300f Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 16:06:36 +0100 Subject: [PATCH 092/176] update picard --- modules/local/picard/collectrnaseqmetrics/main.nf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/local/picard/collectrnaseqmetrics/main.nf b/modules/local/picard/collectrnaseqmetrics/main.nf index 5203269e..f1b2fff5 100644 --- a/modules/local/picard/collectrnaseqmetrics/main.nf +++ b/modules/local/picard/collectrnaseqmetrics/main.nf @@ -2,10 +2,10 @@ process PICARD_COLLECTRNASEQMETRICS { tag "$meta.id" label 'process_medium' - conda "bioconda::picard=2.26.10" + conda "bioconda::picard=2.27.4" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:2.26.10--hdfd78af_0' : - 'quay.io/biocontainers/picard:2.26.10--hdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/picard:2.27.4--hdfd78af_0' : + 'quay.io/biocontainers/picard:2.27.4--hdfd78af_0' }" input: tuple val(meta), path(bam), path(bai) From 63e1b923ffc6c89f9c46d1090f9f9bee825a5c61 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 16:39:01 +0100 Subject: [PATCH 093/176] add dry tests for each tool --- .github/workflows/ci.yml | 44 +++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index af4e33bf..44968328 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,21 +35,45 @@ jobs: with: version: "${{ matrix.NXF_VER }}" - - name: Test building pizzly references + # - name: Test building pizzly references + # run: | + # nextflow run ${GITHUB_WORKSPACE} -profile test,docker \ + # --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly --fusionreport \ + # --build_references --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ + # --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} + + # - name: Test running pizzly references + # run: | + # nextflow run ${GITHUB_WORKSPACE} -profile test,docker \ + # --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly --skip_vis \ + # --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + + - name: Dry test arriba run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker \ - --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly --fusionreport \ - --build_references --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ - --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} + nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ + --outdir /home/runner/work/rnafusion/rnafusion/results --arriba \ + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references - - name: Test running pizzly references + - name: Dry test squid run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker \ - --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly --skip_vis \ + nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ + --outdir /home/runner/work/rnafusion/rnafusion/results --squid \ + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + + - name: Dry test pizzly + run: | + nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ + --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly \ + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + + - name: Dry test fusioncatcher + run: | + nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ + --outdir /home/runner/work/rnafusion/rnafusion/results --fusioncatcher \ --genomes_base /home/runner/work/rnafusion/rnafusion/results/references - - name: Test with stubs + - name: Dry test starfusion run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ - --outdir /home/runner/work/rnafusion/rnafusion/results --all \ + --outdir /home/runner/work/rnafusion/rnafusion/results --starfusion \ --genomes_base /home/runner/work/rnafusion/rnafusion/results/references From 7a9ef33346d201635453e202614dd49732c92263 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 16:43:27 +0100 Subject: [PATCH 094/176] add dry tests for each tool --- .github/workflows/ci.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 44968328..37013383 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,30 +48,63 @@ jobs: # --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly --skip_vis \ # --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + - name: Dry test arriba build + run: | + nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub --build_references \ + --outdir /home/runner/work/rnafusion/rnafusion/results --arriba \ + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + - name: Dry test arriba run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ --outdir /home/runner/work/rnafusion/rnafusion/results --arriba \ --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + - name: Dry test squid build + run: | + nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub --build_references \ + --outdir /home/runner/work/rnafusion/rnafusion/results --squid \ + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + - name: Dry test squid run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ --outdir /home/runner/work/rnafusion/rnafusion/results --squid \ --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + - name: Dry test pizzly build + run: | + nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub --build_references \ + --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly \ + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + + - name: Dry test pizzly run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly \ --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + - name: Dry test fusioncatcher build + run: | + nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub --build_references \ + --outdir /home/runner/work/rnafusion/rnafusion/results --fusioncatcher \ + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + + - name: Dry test fusioncatcher run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ --outdir /home/runner/work/rnafusion/rnafusion/results --fusioncatcher \ --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + - name: Dry test starfusion build + run: | + nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub build_references \ + --outdir /home/runner/work/rnafusion/rnafusion/results --starfusion \ + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + + - name: Dry test starfusion run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ From aea0cabae25645e49f56d99231feeb2d85cef054 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 16:46:41 +0100 Subject: [PATCH 095/176] prettier --- .github/workflows/ci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 37013383..412f8eb4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,7 +78,6 @@ jobs: --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly \ --genomes_base /home/runner/work/rnafusion/rnafusion/results/references - - name: Dry test pizzly run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ @@ -91,7 +90,6 @@ jobs: --outdir /home/runner/work/rnafusion/rnafusion/results --fusioncatcher \ --genomes_base /home/runner/work/rnafusion/rnafusion/results/references - - name: Dry test fusioncatcher run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ @@ -104,7 +102,6 @@ jobs: --outdir /home/runner/work/rnafusion/rnafusion/results --starfusion \ --genomes_base /home/runner/work/rnafusion/rnafusion/results/references - - name: Dry test starfusion run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ From 01807b4c6e5abb8192eeda8e0685f5b03d43f5b9 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 17:33:56 +0100 Subject: [PATCH 096/176] update starfusion --- conf/modules.config | 2 +- modules/local/fusioninspector/main.nf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 39ec4c33..6b45ea32 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -83,7 +83,7 @@ process { } withName: FUSIONINSPECTOR_DEV { ext.when = { !params.skip_vis } - ext.args = '--STAR_xtra_params "--limitSjdbInsertNsj ${params.fusioninspector_limitSjdbInsertNsj"' + ext.args = '--STAR_xtra_params "--limitSjdbInsertNsj ${params.fusioninspector_limitSjdbInsertNsj}"' } withName: FUSIONREPORT { diff --git a/modules/local/fusioninspector/main.nf b/modules/local/fusioninspector/main.nf index acf31b8f..bb9ab8cb 100644 --- a/modules/local/fusioninspector/main.nf +++ b/modules/local/fusioninspector/main.nf @@ -4,8 +4,8 @@ process FUSIONINSPECTOR { conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/trinityctat/starfusion:1.10.1' : - 'docker.io/trinityctat/starfusion:1.10.1' }" + 'docker.io/trinityctat/starfusion:1.12.0' : + 'docker.io/trinityctat/starfusion:1.12.0' }" input: tuple val(meta), path(reads), path(fusion_list) From 1b6ad6859a06371bf0361c5425e48de8d2dee305 Mon Sep 17 00:00:00 2001 From: rannick Date: Tue, 7 Feb 2023 18:30:26 +0100 Subject: [PATCH 097/176] fix wrong syntax for fusioninspector_limitSjdbInsertNsj --- conf/modules.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/modules.config b/conf/modules.config index 6b45ea32..de409294 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -83,7 +83,7 @@ process { } withName: FUSIONINSPECTOR_DEV { ext.when = { !params.skip_vis } - ext.args = '--STAR_xtra_params "--limitSjdbInsertNsj ${params.fusioninspector_limitSjdbInsertNsj}"' + ext.args = "--STAR_xtra_params \"--limitSjdbInsertNsj ${params.fusioninspector_limitSjdbInsertNsj}\"" } withName: FUSIONREPORT { From 4593b356896e156ffd9a5f3a6dcb81845d470aee Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 18:37:22 +0100 Subject: [PATCH 098/176] remove fusioninspector_dev as the option fusioninspector_limitSjdbInsertNsj is part of the main starfusion release --- conf/modules.config | 6 +-- modules/local/fusioninspector_dev/main.nf | 45 ------------------- modules/local/fusioninspector_dev/meta.yml | 40 ----------------- .../local/fusioninspector_workflow.nf | 12 +---- 4 files changed, 4 insertions(+), 99 deletions(-) delete mode 100644 modules/local/fusioninspector_dev/main.nf delete mode 100644 modules/local/fusioninspector_dev/meta.yml diff --git a/conf/modules.config b/conf/modules.config index de409294..1768b2c5 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -80,10 +80,8 @@ process { withName: FUSIONINSPECTOR { ext.when = { !params.skip_vis } - } - withName: FUSIONINSPECTOR_DEV { - ext.when = { !params.skip_vis } - ext.args = "--STAR_xtra_params \"--limitSjdbInsertNsj ${params.fusioninspector_limitSjdbInsertNsj}\"" + ext.args = { params.fusioninspector_limitSjdbInsertNsj != 1000000 ? "--STAR_xtra_params \"--limitSjdbInsertNsj ${params.fusioninspector_limitSjdbInsertNsj}\"" : '' } + } withName: FUSIONREPORT { diff --git a/modules/local/fusioninspector_dev/main.nf b/modules/local/fusioninspector_dev/main.nf deleted file mode 100644 index 9a8b0f96..00000000 --- a/modules/local/fusioninspector_dev/main.nf +++ /dev/null @@ -1,45 +0,0 @@ -process FUSIONINSPECTOR_DEV { - tag "$meta.id" - label 'process_high' - - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/trinityctat/fusioninspector:2.8.0-dev1' : - 'docker.io/trinityctat/fusioninspector:2.8.0-dev1' }" - - input: - tuple val(meta), path(reads), path(fusion_list) - path reference - - output: - path "*" , emit: output - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def prefix = task.ext.prefix ?: "${meta.id}" - def fasta = meta.single_end ? "--left_fq ${reads[0]}" : "--left_fq ${reads[0]} --right_fq ${reads[1]}" - def args = task.ext.args ?: '' - """ - FusionInspector \\ - --fusions $fusion_list \\ - --genome_lib ${reference} \\ - $fasta \\ - --CPU ${task.cpus} \\ - -O . \\ - --out_prefix $prefix \\ - --vis $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - STAR-Fusion: \$(echo STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') - END_VERSIONS - """ - - stub: - """ - touch versions.yml - touch FusionInspector.log - """ -} diff --git a/modules/local/fusioninspector_dev/meta.yml b/modules/local/fusioninspector_dev/meta.yml deleted file mode 100644 index cc03239b..00000000 --- a/modules/local/fusioninspector_dev/meta.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: fusioninspector -description: Validation of Fusion Transcript Predictions -keywords: - - fusioninspector -tools: - - fusioninspector: - description: Validation of Fusion Transcript Predictions - homepage: https://github.com/FusionInspector/FusionInspector - documentation: https://github.com/FusionInspector/FusionInspector/wiki - tool_dev_url: https://github.com/FusionInspector/FusionInspector - doi: 10.1101/2021.08.02.454639" - licence: https://github.com/FusionInspector/FusionInspector/blob/master/LICENSE.txt - -input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - reads: - type: file - description: FASTQ file - pattern: "*.{fastq*}" - - reference: - type: directory - description: Path to ctat references - pattern: "*" - -output: - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - reference: - type: directory - description: Genome resource path - pattern: "*" - -authors: - - "@rannick" diff --git a/subworkflows/local/fusioninspector_workflow.nf b/subworkflows/local/fusioninspector_workflow.nf index 40de4f51..9ff00327 100644 --- a/subworkflows/local/fusioninspector_workflow.nf +++ b/subworkflows/local/fusioninspector_workflow.nf @@ -1,6 +1,4 @@ include { FUSIONINSPECTOR } from '../../modules/local/fusioninspector/main' -include { FUSIONINSPECTOR_DEV } from '../../modules/local/fusioninspector_dev/main' - workflow FUSIONINSPECTOR_WORKFLOW { take: @@ -14,14 +12,8 @@ workflow FUSIONINSPECTOR_WORKFLOW { ch_fusion_list = params.fusioninspector_filter ? fusion_list_filtered : fusion_list reads_fusion = reads.join(ch_fusion_list ) - if (params.fusioninspector_limitSjdbInsertNsj != 1000000) { - FUSIONINSPECTOR_DEV( reads_fusion, index) - ch_versions = ch_versions.mix(FUSIONINSPECTOR_DEV.out.versions) - } - else { - FUSIONINSPECTOR( reads_fusion, index) - ch_versions = ch_versions.mix(FUSIONINSPECTOR.out.versions) - } + FUSIONINSPECTOR( reads_fusion, index) + ch_versions = ch_versions.mix(FUSIONINSPECTOR.out.versions) emit: versions = ch_versions.ifEmpty(null) From 54556d5202c4cdd96dc147479c53f34ab6fdd99e Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 18:49:40 +0100 Subject: [PATCH 099/176] update all starfusion containers --- CHANGELOG.md | 3 +++ modules/local/fusioninspector/main.nf | 4 +--- modules/local/starfusion/detect/main.nf | 4 +--- modules/local/starfusion/download/main.nf | 5 +---- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdb7262e..2ad2c8d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,11 +16,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated nf-core and local modules with stub options - Patch fusion-report version with fixed mittelman DB and DB extraction date written into software_version.yaml - arriba visualisation updated to 2.3.0 +- Updated starfusion to 1.12.0 ### Fixed ### Removed +- FUSIONINSPECTOR_DEV process as the option fusioninspector_limitSjdbInsertNsj is part of the main starfusion release + ## [2.1.0] nfcore/rnafusion - 2022/07/12 ### Added diff --git a/modules/local/fusioninspector/main.nf b/modules/local/fusioninspector/main.nf index bb9ab8cb..9c00c70c 100644 --- a/modules/local/fusioninspector/main.nf +++ b/modules/local/fusioninspector/main.nf @@ -3,9 +3,7 @@ process FUSIONINSPECTOR { label 'process_high' conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/trinityctat/starfusion:1.12.0' : - 'docker.io/trinityctat/starfusion:1.12.0' }" + container 'docker.io/trinityctat/starfusion:1.12.0' input: tuple val(meta), path(reads), path(fusion_list) diff --git a/modules/local/starfusion/detect/main.nf b/modules/local/starfusion/detect/main.nf index 7cd06feb..2d4ea703 100644 --- a/modules/local/starfusion/detect/main.nf +++ b/modules/local/starfusion/detect/main.nf @@ -3,9 +3,7 @@ process STARFUSION { label 'process_high' conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/trinityctat/starfusion:1.10.1' : - 'docker.io/trinityctat/starfusion:1.10.1' }" + container 'docker.io/trinityctat/starfusion:1.12.0' input: tuple val(meta), path(reads), path(junction) diff --git a/modules/local/starfusion/download/main.nf b/modules/local/starfusion/download/main.nf index 235ca0d1..1338cb01 100644 --- a/modules/local/starfusion/download/main.nf +++ b/modules/local/starfusion/download/main.nf @@ -2,10 +2,7 @@ process STARFUSION_DOWNLOAD { tag 'star-fusion' conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/trinityctat/starfusion:1.10.1' : - 'docker.io/trinityctat/starfusion:1.10.1' }" - + container 'docker.io/trinityctat/starfusion:1.12.0' output: path "ctat_genome_lib_build_dir/*" , emit: reference From e70b7b53045901b53dd33491d7e787626cfb4e8b Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 19:01:46 +0100 Subject: [PATCH 100/176] complete update of starfusion --- modules/local/fusioninspector/main.nf | 2 +- modules/local/starfusion/build/main.nf | 4 ++-- modules/local/starfusion/detect/main.nf | 2 +- modules/local/starfusion/download/main.nf | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/local/fusioninspector/main.nf b/modules/local/fusioninspector/main.nf index 9c00c70c..9967117d 100644 --- a/modules/local/fusioninspector/main.nf +++ b/modules/local/fusioninspector/main.nf @@ -2,7 +2,7 @@ process FUSIONINSPECTOR { tag "$meta.id" label 'process_high' - conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" + conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.12.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" container 'docker.io/trinityctat/starfusion:1.12.0' input: diff --git a/modules/local/starfusion/build/main.nf b/modules/local/starfusion/build/main.nf index 5cbff7bf..61b3f905 100644 --- a/modules/local/starfusion/build/main.nf +++ b/modules/local/starfusion/build/main.nf @@ -1,8 +1,8 @@ process STARFUSION_BUILD { tag 'star-fusion' - conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" - container "docker.io/trinityctat/starfusion:1.10.1" + conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.12.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" + container "docker.io/trinityctat/starfusion:1.12.0" input: path fasta diff --git a/modules/local/starfusion/detect/main.nf b/modules/local/starfusion/detect/main.nf index 2d4ea703..cae20049 100644 --- a/modules/local/starfusion/detect/main.nf +++ b/modules/local/starfusion/detect/main.nf @@ -2,7 +2,7 @@ process STARFUSION { tag "$meta.id" label 'process_high' - conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" + conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.12.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" container 'docker.io/trinityctat/starfusion:1.12.0' input: diff --git a/modules/local/starfusion/download/main.nf b/modules/local/starfusion/download/main.nf index 1338cb01..f48511be 100644 --- a/modules/local/starfusion/download/main.nf +++ b/modules/local/starfusion/download/main.nf @@ -1,7 +1,7 @@ process STARFUSION_DOWNLOAD { tag 'star-fusion' - conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.10.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" + conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.12.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" container 'docker.io/trinityctat/starfusion:1.12.0' output: From ad3cad5945745c7e71236d2331cefcdfa733bf5b Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 19:18:46 +0100 Subject: [PATCH 101/176] remove extra stub in reformat --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- modules/local/reformat/main.nf | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 6f604f38..51297243 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -17,7 +17,7 @@ Learn more about contributing: [CONTRIBUTING.md](https://github.com/nf-core/rnaf - [ ] If you've fixed a bug or added code that should be tested, add tests! - [ ] If you've added a new tool - have you followed the pipeline conventions in the [contribution docs](https://github.com/nf-core/rnafusion/tree/master/.github/CONTRIBUTING.md)- [ ] If necessary, also make a PR on the nf-core/rnafusion _branch_ on the [nf-core/test-datasets](https://github.com/nf-core/test-datasets) repository. - [ ] Make sure your code lints (`nf-core lint`). -- [ ] Ensure the test suite passes (`nextflow run . -profile test,docker --outdir `). +- [ ] Ensure the test suite passes (`nextflow run . -stub -profile test,docker --outdir --`). - [ ] Usage Documentation in `docs/usage.md` is updated. - [ ] Output Documentation in `docs/output.md` is updated. - [ ] `CHANGELOG.md` is updated. diff --git a/modules/local/reformat/main.nf b/modules/local/reformat/main.nf index 45200583..969b0e34 100644 --- a/modules/local/reformat/main.nf +++ b/modules/local/reformat/main.nf @@ -38,20 +38,6 @@ process REFORMAT { END_VERSIONS """ - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - def out1 ="out=${prefix}_R1_trimmed.fq.gz" - def out2 =meta.single_end ? "" : "out=${prefix}_R2_trimmed.fq.gz" - """ - touch $out1 - touch $out2 - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - reformat.sh: \$(echo \$(reformat.sh --version 2>&1)| sed -e "s/BBMap version //g" ) - END_VERSIONS - """ - stub: def prefix = task.ext.prefix ?: "${meta.id}" def out1 ="out=${prefix}_R1_trimmed.fq.gz" From 8c83e8f0f2bdd272fd01459b5003f0ca78ca2198 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 19:26:26 +0100 Subject: [PATCH 102/176] add empty conf/test_full.config --- conf/test_full.config | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 conf/test_full.config diff --git a/conf/test_full.config b/conf/test_full.config new file mode 100644 index 00000000..e69de29b From e2f3e66505c350e888d62566315245591ef8966f Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 19:32:36 +0100 Subject: [PATCH 103/176] add cosmic login to ci tests --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .github/workflows/ci.yml | 39 ++++++++++++++++++++------- modules/local/arriba/download/main.nf | 11 ++++---- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 51297243..6f604f38 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -17,7 +17,7 @@ Learn more about contributing: [CONTRIBUTING.md](https://github.com/nf-core/rnaf - [ ] If you've fixed a bug or added code that should be tested, add tests! - [ ] If you've added a new tool - have you followed the pipeline conventions in the [contribution docs](https://github.com/nf-core/rnafusion/tree/master/.github/CONTRIBUTING.md)- [ ] If necessary, also make a PR on the nf-core/rnafusion _branch_ on the [nf-core/test-datasets](https://github.com/nf-core/test-datasets) repository. - [ ] Make sure your code lints (`nf-core lint`). -- [ ] Ensure the test suite passes (`nextflow run . -stub -profile test,docker --outdir --`). +- [ ] Ensure the test suite passes (`nextflow run . -profile test,docker --outdir `). - [ ] Usage Documentation in `docs/usage.md` is updated. - [ ] Output Documentation in `docs/output.md` is updated. - [ ] `CHANGELOG.md` is updated. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6a3515a1..73d7fbfe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,58 +39,77 @@ jobs: run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub --build_references \ --outdir /home/runner/work/rnafusion/rnafusion/results --arriba \ - --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ + --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} - name: Dry test arriba run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ --outdir /home/runner/work/rnafusion/rnafusion/results --arriba \ - --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ + --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} + - name: Dry test squid build run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub --build_references \ --outdir /home/runner/work/rnafusion/rnafusion/results --squid \ - --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ + --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} + - name: Dry test squid run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ --outdir /home/runner/work/rnafusion/rnafusion/results --squid \ - --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ + --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} + - name: Dry test pizzly build run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub --build_references \ --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly \ - --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ + --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} + - name: Dry test pizzly run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ --outdir /home/runner/work/rnafusion/rnafusion/results --pizzly \ - --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ + --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} + - name: Dry test fusioncatcher build run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub --build_references \ --outdir /home/runner/work/rnafusion/rnafusion/results --fusioncatcher \ - --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ + --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} + - name: Dry test fusioncatcher run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ --outdir /home/runner/work/rnafusion/rnafusion/results --fusioncatcher \ - --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ + --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} + - name: Dry test starfusion build run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub build_references \ --outdir /home/runner/work/rnafusion/rnafusion/results --starfusion \ - --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ + --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} + - name: Dry test starfusion run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ --outdir /home/runner/work/rnafusion/rnafusion/results --starfusion \ - --genomes_base /home/runner/work/rnafusion/rnafusion/results/references + --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ + --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} + diff --git a/modules/local/arriba/download/main.nf b/modules/local/arriba/download/main.nf index 66692b1e..0d102435 100644 --- a/modules/local/arriba/download/main.nf +++ b/modules/local/arriba/download/main.nf @@ -2,12 +2,11 @@ process ARRIBA_DOWNLOAD { tag "arriba" label 'process_low' - conda (params.enable_conda ? "bioconda::gnu-wget=1.18" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h5bf99c6_5" - } else { - container "quay.io/biocontainers/gnu-wget:1.18--h5bf99c6_5" - } + conda "bioconda::gnu-wget=1.18" + conda "bioconda::arriba=2.3.0" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h5bf99c6_5' : + 'quay.io/biocontainers/gnu-wget:1.18--h5bf99c6_5' }" output: path "versions.yml" , emit: versions From c2da262fa1284c6ad6b5ed002e9d98457e399d08 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 19:38:58 +0100 Subject: [PATCH 104/176] prettier --- .github/workflows/ci.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 73d7fbfe..30db85cf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,6 @@ jobs: --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} - - name: Dry test squid build run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub --build_references \ @@ -57,7 +56,6 @@ jobs: --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} - - name: Dry test squid run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ @@ -65,7 +63,6 @@ jobs: --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} - - name: Dry test pizzly build run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub --build_references \ @@ -73,7 +70,6 @@ jobs: --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} - - name: Dry test pizzly run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ @@ -81,7 +77,6 @@ jobs: --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} - - name: Dry test fusioncatcher build run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub --build_references \ @@ -89,7 +84,6 @@ jobs: --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} - - name: Dry test fusioncatcher run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ @@ -97,7 +91,6 @@ jobs: --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} - - name: Dry test starfusion build run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub build_references \ @@ -105,11 +98,9 @@ jobs: --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} - - name: Dry test starfusion run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ --outdir /home/runner/work/rnafusion/rnafusion/results --starfusion \ --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} - From eeb2c8a83a5c32820a5cc46ad1a67ee4a834c37e Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 19:43:11 +0100 Subject: [PATCH 105/176] editing --- modules/local/picard/collectrnaseqmetrics/main.nf | 1 - modules/local/uscs/custom_gtftogenepred/main.nf | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/local/picard/collectrnaseqmetrics/main.nf b/modules/local/picard/collectrnaseqmetrics/main.nf index ba41c997..f1b2fff5 100644 --- a/modules/local/picard/collectrnaseqmetrics/main.nf +++ b/modules/local/picard/collectrnaseqmetrics/main.nf @@ -65,5 +65,4 @@ process PICARD_COLLECTRNASEQMETRICS { picard: \$(picard CollectRnaMetrics --version 2>&1 | grep -o 'Version.*' | cut -f2- -d:) END_VERSIONS """ - } diff --git a/modules/local/uscs/custom_gtftogenepred/main.nf b/modules/local/uscs/custom_gtftogenepred/main.nf index 86b06884..46052b5a 100644 --- a/modules/local/uscs/custom_gtftogenepred/main.nf +++ b/modules/local/uscs/custom_gtftogenepred/main.nf @@ -24,7 +24,7 @@ process GTF_TO_REFFLAT { gtfToGenePred: 377 END_VERSIONS """ - + stub: def refflat = gtf + '.refflat' """ From e2dc6f1a30452b7d5c83f351c9ecfa9fe0c43bae Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 20:06:29 +0100 Subject: [PATCH 106/176] remove double conda statement --- modules/local/arriba/download/main.nf | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/local/arriba/download/main.nf b/modules/local/arriba/download/main.nf index 0d102435..44e6cb48 100644 --- a/modules/local/arriba/download/main.nf +++ b/modules/local/arriba/download/main.nf @@ -3,7 +3,6 @@ process ARRIBA_DOWNLOAD { label 'process_low' conda "bioconda::gnu-wget=1.18" - conda "bioconda::arriba=2.3.0" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h5bf99c6_5' : 'quay.io/biocontainers/gnu-wget:1.18--h5bf99c6_5' }" From d40b4abefba806ce16803c5d5451746d78bcd1c6 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 21:06:47 +0100 Subject: [PATCH 107/176] fix bugs --- conf/test.config | 2 -- main.nf | 7 ++----- modules/local/pizzly/download/main.nf | 8 -------- modules/local/starfusion/build/main.nf | 9 --------- modules/nf-core/arriba/main.nf | 1 - nextflow.config | 3 +++ 6 files changed, 5 insertions(+), 25 deletions(-) diff --git a/conf/test.config b/conf/test.config index 726f1cf3..236d1a39 100644 --- a/conf/test.config +++ b/conf/test.config @@ -20,7 +20,5 @@ params { max_time = 6.h // Input data - build_references = true - all = true input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' } diff --git a/main.nf b/main.nf index 57ad5c5c..a85874e4 100644 --- a/main.nf +++ b/main.nf @@ -55,14 +55,11 @@ include { RNAFUSION } from './workflows/rnafusion' // workflow NFCORE_RNAFUSION { - if (params.build_references) { + if (params.build_references) { BUILD_REFERENCES () - } - - if (file(params.input).exists()) { + } else { RNAFUSION() } - } /* diff --git a/modules/local/pizzly/download/main.nf b/modules/local/pizzly/download/main.nf index f4355025..571cd4dc 100644 --- a/modules/local/pizzly/download/main.nf +++ b/modules/local/pizzly/download/main.nf @@ -37,12 +37,4 @@ process PIZZLY_DOWNLOAD { END_VERSIONS """ - stub: - """ - touch index.idx - cat <<-END_VERSIONS > versions.yml - "${task.process}": - kallisto: \$(echo \$(kallisto 2>&1) | sed 's/^kallisto //; s/Usage.*\$//') - END_VERSIONS - """ } diff --git a/modules/local/starfusion/build/main.nf b/modules/local/starfusion/build/main.nf index 64db06c1..5218a215 100644 --- a/modules/local/starfusion/build/main.nf +++ b/modules/local/starfusion/build/main.nf @@ -51,13 +51,4 @@ process STARFUSION_BUILD { END_VERSIONS """ - stub: - """ - mkdir ctat_genome_lib_build_dir - touch ref_annot.cdna.fa - cat <<-END_VERSIONS > versions.yml - "${task.process}": - STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') - END_VERSIONS - """ } diff --git a/modules/nf-core/arriba/main.nf b/modules/nf-core/arriba/main.nf index e4b48be2..cb2860e2 100644 --- a/modules/nf-core/arriba/main.nf +++ b/modules/nf-core/arriba/main.nf @@ -33,7 +33,6 @@ process ARRIBA { def structural_variants = structural_variants ? "-d $structual_variants" : "" def tags = tags ? "-t $tags" : "" def protein_domains = protein_domains ? "-p $protein_domains" : "" - """ arriba \\ -x $bam \\ diff --git a/nextflow.config b/nextflow.config index 2fe67c81..3c7a878e 100644 --- a/nextflow.config +++ b/nextflow.config @@ -208,6 +208,9 @@ profiles { test { includeConfig 'conf/test.config' } + test_full { + includeConfig 'conf/test_full.config' + } gitpod { executor.name = 'local' From 2737a4e81b7fa6b357bc7d63566e2295a1cba381 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 21:10:49 +0100 Subject: [PATCH 108/176] fix bugs --- main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.nf b/main.nf index a85874e4..972c7f5a 100644 --- a/main.nf +++ b/main.nf @@ -55,7 +55,7 @@ include { RNAFUSION } from './workflows/rnafusion' // workflow NFCORE_RNAFUSION { - if (params.build_references) { + if (params.build_references) { BUILD_REFERENCES () } else { RNAFUSION() From a9e74e694db697175b0f7843af873cda322c1bd5 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 7 Feb 2023 21:11:34 +0100 Subject: [PATCH 109/176] fix bugs --- modules/nf-core/arriba/main.nf | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/nf-core/arriba/main.nf b/modules/nf-core/arriba/main.nf index cb2860e2..e4b48be2 100644 --- a/modules/nf-core/arriba/main.nf +++ b/modules/nf-core/arriba/main.nf @@ -33,6 +33,7 @@ process ARRIBA { def structural_variants = structural_variants ? "-d $structual_variants" : "" def tags = tags ? "-t $tags" : "" def protein_domains = protein_domains ? "-p $protein_domains" : "" + """ arriba \\ -x $bam \\ From 16c0efc447db14a9bb7367cda43eb13ee9606bc5 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 8 Feb 2023 11:03:57 +0100 Subject: [PATCH 110/176] modify awstest --- .github/workflows/awstest.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/awstest.yml b/.github/workflows/awstest.yml index 8184cfd7..13e9cb3c 100644 --- a/.github/workflows/awstest.yml +++ b/.github/workflows/awstest.yml @@ -25,5 +25,7 @@ jobs: "cosmic_username": "${{ secrets.cosmic_username }}", "cosmic_passwd": "${{ secrets.cosmic_passwd }}" "stub": true + "arriba: true" + "build_references: true" } - profiles: test_build,aws_tower + profiles: test,aws_tower From 79e0f236aefeeb3b165f29691bface3c5eff23d3 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 8 Feb 2023 11:06:23 +0100 Subject: [PATCH 111/176] fix typos --- .github/workflows/awstest.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/awstest.yml b/.github/workflows/awstest.yml index 13e9cb3c..be1b6798 100644 --- a/.github/workflows/awstest.yml +++ b/.github/workflows/awstest.yml @@ -23,9 +23,9 @@ jobs: "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", "cosmic_username": "${{ secrets.cosmic_username }}", - "cosmic_passwd": "${{ secrets.cosmic_passwd }}" - "stub": true - "arriba: true" - "build_references: true" + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "stub": true, + "arriba": true, + "build_references": true } profiles: test,aws_tower From 2bb98c6fb611cc454f4d6d32b6f1acde68a76e59 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 8 Feb 2023 11:08:23 +0100 Subject: [PATCH 112/176] add arriba run to awstest --- .github/workflows/awstest.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/awstest.yml b/.github/workflows/awstest.yml index be1b6798..5ff77104 100644 --- a/.github/workflows/awstest.yml +++ b/.github/workflows/awstest.yml @@ -29,3 +29,21 @@ jobs: "build_references": true } profiles: test,aws_tower + + - 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "stub": true, + "arriba": true, + } + profiles: test,aws_tower From af8ac1b1428a427f5ec931da5ca0635fd7030f2d Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 8 Feb 2023 11:13:24 +0100 Subject: [PATCH 113/176] update changelog --- CHANGELOG.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddeb51f5..cfaf5e17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,19 +14,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Test profiles unified under 'test' but if the references do not all need to be downloaded, run with `-stub` -- UPDATE IN USAGE: in order to make AWS tests work, now the analysis part of the pipeline will run after downloading the references with `build_references` if an `input` parameter is provided - Update CUSTOM_DUMPSOFTWAREVERSIONS to use multiqc version 1.13 -- Updated to nf-core template 2.6, with all module updates +- Updated to nf-core template 2.7.2, with all module updates - `MultiQC` updated to 1.13a in process dumpsoftwareversion -- Updated nf-core and local modules with stub options - Patch fusion-report version with fixed mittelman DB and DB extraction date written into software_version.yaml - `Arriba` references back to downloading with `build_references` instead of taking from container -- arriba visualisation updated to 2.3.0 -- Updated starfusion to 1.12.0 +- `Arriba` visualisation now running with `Arriba` v2.3.0 +- Updated `STAR-Fusion` to 1.12.0 ### Fixed -- `Arriba` visualisation now running with `Arriba` v2.3.0 - AWS megatest to display on nf-core website ### Removed From bd130304eb6318a6a9eb57a5f48f8720539ea98e Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 8 Feb 2023 14:50:46 +0100 Subject: [PATCH 114/176] make detailed awsfull test and awstest same but with stub --- .github/workflows/awsfulltest.yml | 185 +++++++++++++++++++++++++++++- .github/workflows/awstest.yml | 174 +++++++++++++++++++++++++++- conf/test_full.config | 18 +++ 3 files changed, 367 insertions(+), 10 deletions(-) diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index b12bafc8..61a9203a 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -13,7 +13,7 @@ jobs: if: github.repository == 'nf-core/rnafusion' runs-on: ubuntu-latest steps: - - name: Launch build workflow via tower + - name: Launch build arriba workflow via tower uses: nf-core/tower-action@v3 with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} @@ -25,9 +25,182 @@ jobs: "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", "cosmic_username": "${{ secrets.cosmic_username }}", - "cosmic_passwd": "${{ secrets.cosmic_passwd }}" + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "arriba": true, + "build_references": true } - profiles: test_full_build,aws_tower - nextflow_config: | - process.errorStrategy = 'retry' - process.maxRetries = 3 + profiles: test,aws_tower + + - name: Launch arriba 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "arriba": true, + } + profiles: test,aws_tower + + - name: Launch build squid 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "squid": true, + "build_references": true + } + profiles: test,aws_tower + + - name: Launch squid 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "squid": true, + } + profiles: test,aws_tower + + - name: Launch build starfusion 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "starfusion": true, + "build_references": true + } + profiles: test,aws_tower + + - name: Launch starfusion 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "starfusion": true, + } + profiles: test,aws_tower + + - name: Launch build fusioncatcher 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "fusioncatcher": true, + "build_references": true + } + profiles: test,aws_tower + + - name: Launch fusioncatcher 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "fusioncatcher": true, + } + profiles: test,aws_tower + + - name: Launch build pizzly 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "pizzly": true, + "build_references": true + } + profiles: test,aws_tower + + - name: Launch pizzly 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "pizzly": true, + } + profiles: test,aws_tower + + - name: Launch stringtie 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "stringtie": true, + } + profiles: test,aws_tower diff --git a/.github/workflows/awstest.yml b/.github/workflows/awstest.yml index 5ff77104..036579de 100644 --- a/.github/workflows/awstest.yml +++ b/.github/workflows/awstest.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: # Launch workflow using Tower CLI tool action - - name: Launch build workflow via tower + - name: Launch build arriba workflow via tower uses: nf-core/tower-action@v3 with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} @@ -24,13 +24,13 @@ jobs: "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", "cosmic_username": "${{ secrets.cosmic_username }}", "cosmic_passwd": "${{ secrets.cosmic_passwd }}", - "stub": true, "arriba": true, + "stub": true, "build_references": true } profiles: test,aws_tower - - name: Launch workflow via tower + - name: Launch arriba workflow via tower uses: nf-core/tower-action@v3 with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} @@ -43,7 +43,173 @@ jobs: "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", "cosmic_username": "${{ secrets.cosmic_username }}", "cosmic_passwd": "${{ secrets.cosmic_passwd }}", - "stub": true, "arriba": true, + "stub": true + } + profiles: test,aws_tower + + - name: Launch build squid 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "squid": true, + "stub": true, + "build_references": true + } + profiles: test,aws_tower + + - name: Launch squid 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "squid": true, + "stub": true + } + profiles: test,aws_tower + + - name: Launch build starfusion 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "starfusion": true, + "build_references": true, + "stub": true + } + profiles: test,aws_tower + + - name: Launch starfusion 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "starfusion": true, + "stub": true + } + profiles: test,aws_tower + + - name: Launch build fusioncatcher 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "fusioncatcher": true, + "build_references": true, + "stub": true + } + profiles: test,aws_tower + + - name: Launch fusioncatcher 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "fusioncatcher": true, + "stub": true + } + profiles: test,aws_tower + + - name: Launch build pizzly 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "pizzly": true, + "build_references": true, + "stub": true + } + profiles: test,aws_tower + + - name: Launch pizzly 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "pizzly": true, + "stub": true + } + profiles: test,aws_tower + + - name: Launch stringtie 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/rnafusion/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", + "cosmic_username": "${{ secrets.cosmic_username }}", + "cosmic_passwd": "${{ secrets.cosmic_passwd }}", + "stringtie": true, + "stub": true } profiles: test,aws_tower diff --git a/conf/test_full.config b/conf/test_full.config index e69de29b..39c64928 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -0,0 +1,18 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running full-size tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a full size pipeline test. + Use as follows: + nextflow run nf-core/sarek -profile test_full, --outdir +---------------------------------------------------------------------------------------- +*/ + +params { + config_profile_name = 'Full test profile' + config_profile_description = 'Full test dataset to check pipeline function' + + // Input data for full size test + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' + + // Other params From e64c97adea9e693ca423b65d56197189d7e83a39 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 8 Feb 2023 15:15:59 +0100 Subject: [PATCH 115/176] use simplified syntax when singularity and docker containers are the same --- modules/local/fusioncatcher/detect/main.nf | 4 +--- modules/local/fusioncatcher/download/main.nf | 4 +--- modules/local/fusionreport/detect/main.nf | 4 +--- modules/local/fusionreport/download/main.nf | 5 ++--- modules/local/squid/annotate/main.nf | 4 +--- modules/local/squid/detect/main.nf | 4 +--- 6 files changed, 7 insertions(+), 18 deletions(-) diff --git a/modules/local/fusioncatcher/detect/main.nf b/modules/local/fusioncatcher/detect/main.nf index f668c84a..fa072bf4 100644 --- a/modules/local/fusioncatcher/detect/main.nf +++ b/modules/local/fusioncatcher/detect/main.nf @@ -3,9 +3,7 @@ process FUSIONCATCHER { label 'process_high' conda "bioconda::fusioncatcher=1.33" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/clinicalgenomics/fusioncatcher:1.33' : - 'docker.io/clinicalgenomics/fusioncatcher:1.33' }" + container "docker.io/clinicalgenomics/fusioncatcher:1.33" input: tuple val(meta), path(fasta) diff --git a/modules/local/fusioncatcher/download/main.nf b/modules/local/fusioncatcher/download/main.nf index 1153d6a4..156e70b6 100644 --- a/modules/local/fusioncatcher/download/main.nf +++ b/modules/local/fusioncatcher/download/main.nf @@ -3,9 +3,7 @@ process FUSIONCATCHER_DOWNLOAD { label 'process_medium' conda "bioconda::fusioncatcher=1.33" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/clinicalgenomics/fusioncatcher:1.33' : - 'docker.io/clinicalgenomics/fusioncatcher:1.33' }" + container "docker.io/clinicalgenomics/fusioncatcher:1.33" output: path "*" , emit: reference diff --git a/modules/local/fusionreport/detect/main.nf b/modules/local/fusionreport/detect/main.nf index 049a8503..12090a03 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/local/fusionreport/detect/main.nf @@ -4,9 +4,7 @@ process FUSIONREPORT { // Note: 2.7X indices incompatible with AWS iGenomes. conda "bioconda::star=2.7.9a" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/clinicalgenomics/fusion-report:2.1.5patched' : - 'docker.io/clinicalgenomics/fusion-report:2.1.5patched' }" + container "docker.io/clinicalgenomics/fusion-report:2.1.5patched" input: diff --git a/modules/local/fusionreport/download/main.nf b/modules/local/fusionreport/download/main.nf index c5b804a7..5f42214a 100644 --- a/modules/local/fusionreport/download/main.nf +++ b/modules/local/fusionreport/download/main.nf @@ -4,9 +4,8 @@ process FUSIONREPORT_DOWNLOAD { // Note: 2.7X indices incompatible with AWS iGenomes. conda "bioconda::star=2.7.9a" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/clinicalgenomics/fusion-report:2.1.5patched' : - 'docker.io/clinicalgenomics/fusion-report:2.1.5patched' }" + container "docker.io/clinicalgenomics/fusion-report:2.1.5patched" + input: diff --git a/modules/local/squid/annotate/main.nf b/modules/local/squid/annotate/main.nf index 37d372df..19975b00 100644 --- a/modules/local/squid/annotate/main.nf +++ b/modules/local/squid/annotate/main.nf @@ -4,9 +4,7 @@ process SQUID_ANNOTATE { label 'process_medium' conda "bioconda::squid=1.5" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/nfcore/rnafusion:squid_1.5-star2.7.1a' : - 'docker.io/nfcore/rnafusion:squid_1.5-star2.7.1a' }" + container "docker.io/nfcore/rnafusion:squid_1.5-star2.7.1a" diff --git a/modules/local/squid/detect/main.nf b/modules/local/squid/detect/main.nf index f6f3642c..3ccb6e3e 100644 --- a/modules/local/squid/detect/main.nf +++ b/modules/local/squid/detect/main.nf @@ -4,9 +4,7 @@ process SQUID { label 'process_medium' conda "bioconda::squid=1.5" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker.io/nfcore/rnafusion:squid_1.5-star2.7.1a' : - 'docker.io/nfcore/rnafusion:squid_1.5-star2.7.1a' }" + container "docker.io/nfcore/rnafusion:squid_1.5-star2.7.1a" From 2cb747f7b2f68af97805e603a64f9d7af7a14408 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 8 Feb 2023 15:45:22 +0100 Subject: [PATCH 116/176] impove documentation on running with test profile --- README.md | 5 ++++- docs/usage.md | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8e84f6c0..07d59349 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,10 @@ In rnafusion the full-sized test includes reference building and fusion detectio 3. Download the pipeline and test it on a minimal dataset with a single command: ```bash - nextflow run nf-core/rnafusion -profile test,YOURPROFILE --outdir + nextflow run nf-core/rnafusion -profile test,YOURPROFILE --outdir -stub --all --build_references + + nextflow run nf-core/rnafusion -profile test,YOURPROFILE --outdir -stub --all + ``` 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. diff --git a/docs/usage.md b/docs/usage.md index 1f41a1e8..24f74e52 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -207,8 +207,6 @@ There are two parameters to increase the `--limitSjdbInsertNsj` parameter if nec - `--fusioncatcher_limitSjdbInsertNsj`, default: 2000000 - `--fusioninspector_limitSjdbInsertNsj`, default: 1000000 -> **IMPORTANT** Note that with any other value than default for `--fusioninsepctor_limitSjdbInsertNsj`, FusionInspector will run the **development version** 2.8.0dev1 and not the released version. Use at your own risk! - ### Updating the pipeline When you run the above command, Nextflow automatically pulls the pipeline code from GitHub and stores it as a cached version. When running the pipeline after this, it will always use the cached version if available - even if the pipeline has been updated since. To make sure that you're running the latest version of the pipeline, make sure that you regularly update the cached version of the pipeline: @@ -262,6 +260,7 @@ If `-profile` is not specified, the pipeline will run locally and expect all sof - `test` - A profile with a complete configuration for automated testing - Includes links to test data so needs no other parameters + - Needs to run in two steps: with `--build_references` first and then without `--build_references` to run the analysis - !!!! Run with `-stub` as all references need to be downloaded otherwise !!!! ### `-resume` From b3ff37a1b71fa9e282f021075514a1ecc14617f7 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 14 Feb 2023 21:38:56 +0100 Subject: [PATCH 117/176] formatting --- subworkflows/local/qc_workflow.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/local/qc_workflow.nf b/subworkflows/local/qc_workflow.nf index 8cb8008a..b8fe1007 100644 --- a/subworkflows/local/qc_workflow.nf +++ b/subworkflows/local/qc_workflow.nf @@ -4,7 +4,7 @@ include { QUALIMAP_RNASEQ } from '../../modules/nf-core/qualimap/rnaseq/main' include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_QC } from '../../modules/nf-core/samtools/index/main' -include { PICARD_COLLECTRNASEQMETRICS } from '../../modules/local/picard/collectrnaseqmetrics/main' +include { PICARD_COLLECTRNASEQMETRICS } from '../../modules/local/picard/collectrnaseqmetrics/main' include { PICARD_MARKDUPLICATES } from '../../modules/nf-core/picard/markduplicates/main' workflow QC_WORKFLOW { From 7cedd2ef88cdc7d34aaa730cb7692d85fbd3e204 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 14 Feb 2023 21:39:58 +0100 Subject: [PATCH 118/176] add generation of ribosomal rna interval list in build_references --- bin/get_rrna_transcripts.py | 76 +++++++++++++++++++ conf/modules.config | 8 ++ modules.json | 10 +++ modules/local/convert2bed/main.nf | 36 +++++++++ modules/local/convert2bed/meta.yml | 30 ++++++++ modules/local/rrnatranscripts/main.nf | 42 ++++++++++ .../nf-core/gatk4/bedtointervallist/main.nf | 55 ++++++++++++++ .../nf-core/gatk4/bedtointervallist/meta.yml | 40 ++++++++++ .../gatk4/createsequencedictionary/main.nf | 51 +++++++++++++ .../gatk4/createsequencedictionary/meta.yml | 32 ++++++++ workflows/build_references.nf | 29 +++++-- 11 files changed, 402 insertions(+), 7 deletions(-) create mode 100755 bin/get_rrna_transcripts.py create mode 100644 modules/local/convert2bed/main.nf create mode 100644 modules/local/convert2bed/meta.yml create mode 100644 modules/local/rrnatranscripts/main.nf create mode 100644 modules/nf-core/gatk4/bedtointervallist/main.nf create mode 100644 modules/nf-core/gatk4/bedtointervallist/meta.yml create mode 100644 modules/nf-core/gatk4/createsequencedictionary/main.nf create mode 100644 modules/nf-core/gatk4/createsequencedictionary/meta.yml diff --git a/bin/get_rrna_transcripts.py b/bin/get_rrna_transcripts.py new file mode 100755 index 00000000..46ec2e15 --- /dev/null +++ b/bin/get_rrna_transcripts.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 + +import argparse +import logging +import sys +from pathlib import Path + +def get_rrna_intervals(file_in, file_out): + """ + Get the commented out header + Get lines containing ``#`` or ``gene_type rRNA`` or ```` or ``gene_type rRNA_pseudogene`` or ``gene_type MT_rRNA`` + Create output file + + Args: + file_in (pathlib.Path): The given GTF file. + file_out (pathlib.Path): Where the ribosomal RNA GTF file should + be created; always in GTF format. + """ + + patterns = {"#", "transcript_biotype \"Mt_rRNA\"", "transcript_biotype \"rRNA\"", "transcript_biotype \"rRNA_pseudogene\""} + line_starts = {"MT", "1", "2", "3", "4", "5", "6", "7", "8", "9"} + out_lines = [] + with file_in.open() as f: + data = f.readlines() + for line in data: + for pattern in patterns: + if (pattern in line): + for line_start in line_starts: + if (line.startswith(line_start)): + out_lines.append(line) + + with file_out.open(mode="w") as out_file: + out_file.writelines(out_lines) + + +def parse_args(argv=None): + """Define and immediately parse command line arguments.""" + parser = argparse.ArgumentParser( + description="Extract ribosomal RNA intervals from a gtf file.", + epilog="Example: python get_rrna_transcripts.py ", + ) + parser.add_argument( + "file_in", + metavar="FILE_IN", + type=Path, + help="Input in GTF format.", + ) + parser.add_argument( + "file_out", + metavar="FILE_OUT", + type=Path, + help="Transformed output intervals in GTF format.", + ) + parser.add_argument( + "-l", + "--log-level", + help="The desired log level (default WARNING).", + choices=("CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"), + default="WARNING", + ) + return parser.parse_args(argv) + + +def main(argv=None): + """Coordinate argument parsing and program execution.""" + args = parse_args(argv) + logging.basicConfig(level=args.log_level, format="[%(levelname)s] %(message)s") + if not args.file_in.is_file(): + logger.error(f"The given input file {args.file_in} was not found!") + sys.exit(2) + args.file_out.parent.mkdir(parents=True, exist_ok=True) + get_rrna_intervals(args.file_in, args.file_out) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/conf/modules.config b/conf/modules.config index 1768b2c5..68f92c02 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -101,6 +101,14 @@ process { ] } + withName: GATK4_BEDTOINTERVALLIST { + publishDir = [ + path: { "${params.genomes_base}/ensembl" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + withName: GTF_TO_REFFLAT { publishDir = [ path: { "${params.genomes_base}/ensembl" }, diff --git a/modules.json b/modules.json index 3bd594a3..a2ae7960 100644 --- a/modules.json +++ b/modules.json @@ -25,6 +25,16 @@ "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", "installed_by": ["modules"] }, + "gatk4/bedtointervallist": { + "branch": "master", + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "installed_by": ["modules"] + }, + "gatk4/createsequencedictionary": { + "branch": "master", + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "installed_by": ["modules"] + }, "kallisto/index": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", diff --git a/modules/local/convert2bed/main.nf b/modules/local/convert2bed/main.nf new file mode 100644 index 00000000..6d526eb4 --- /dev/null +++ b/modules/local/convert2bed/main.nf @@ -0,0 +1,36 @@ +process CONVERT2BED { + tag "$meta.id" + label 'process_single' + + conda "bioconda::bedops=2.4.41" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'bedops:2.4.41--h9f5acd7_0' : + 'quay.io/biocontainers/bedops:2.4.41--h9f5acd7_0' }" + + input: + tuple val(meta), path(gtf) + + output: + tuple val(meta), path("*.bed") , emit: bed + + script: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + convert2bed -i gtf < $gtf > ${prefix}.bed + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + convert2bed: \$(convert2bed --version | grep vers | sed 's/^.*.version: //') + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.bed + cat <<-END_VERSIONS > versions.yml + "${task.process}": + convert2bed: \$(convert2bed --version | grep vers | sed 's/^.*.version: //') + END_VERSIONS + """ +} diff --git a/modules/local/convert2bed/meta.yml b/modules/local/convert2bed/meta.yml new file mode 100644 index 00000000..e578330b --- /dev/null +++ b/modules/local/convert2bed/meta.yml @@ -0,0 +1,30 @@ +name: +description: convert from GTF to BED format + - convert2bed +tools: + - convert2bed: + description: convert from GTF to BED format + homepage: https://pachterlab.github.io/kallisto/ + documentation: https://bedops.readthedocs.io/en/latest/index.html + tool_dev_url: https://github.com/bedops/bedops + doi: "" + licence: ["GNU GENERAL PUBLIC LICENSE"] + +input: + - gtf: + type: file + description: Path to GTF file + pattern: "*.{gtf*}" + +output: + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + - bed: + type: file + description: bed file + pattern: "*.bed" + +authors: + - "@rannick" diff --git a/modules/local/rrnatranscripts/main.nf b/modules/local/rrnatranscripts/main.nf new file mode 100644 index 00000000..e4afc284 --- /dev/null +++ b/modules/local/rrnatranscripts/main.nf @@ -0,0 +1,42 @@ +process RRNA_TRANSCRIPTS { + tag "$meta.id" + label 'process_single' + + conda "conda-forge::python=3.8.3" + + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/python:3.9--1' : + 'quay.io/biocontainers/python:3.9--1' }" + + + input: + tuple val(meta), path(gtf) + + output: + tuple val(meta), path("*rrna_intervals.gtf") , emit: rrna_gtf + path "versions.yml" , emit: versions + + + when: + task.ext.when == null || task.ext.when + + script: // This script is bundled with the pipeline, in nf-core/rnafusion/bin/ + def prefix = task.ext.prefix ?: "${meta.id}" + """ + get_rrna_transcripts.py $gtf ${prefix}_rrna_intervals.gtf + cat <<-END_VERSIONS > versions.yml + "${task.process}": + python: \$(python --version | sed 's/Python //g') + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}_rrna_intervals.gtf + cat <<-END_VERSIONS > versions.yml + "${task.process}": + python: \$(python --version | sed 's/Python //g') + END_VERSIONS + """ +} diff --git a/modules/nf-core/gatk4/bedtointervallist/main.nf b/modules/nf-core/gatk4/bedtointervallist/main.nf new file mode 100644 index 00000000..41fab003 --- /dev/null +++ b/modules/nf-core/gatk4/bedtointervallist/main.nf @@ -0,0 +1,55 @@ +process GATK4_BEDTOINTERVALLIST { + tag "$meta.id" + label 'process_medium' + + conda "bioconda::gatk4=4.3.0.0" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/gatk4:4.3.0.0--py36hdfd78af_0': + 'quay.io/biocontainers/gatk4:4.3.0.0--py36hdfd78af_0' }" + + input: + tuple val(meta), path(bed) + path dict + + output: + tuple val(meta), path('*.interval_list'), emit: interval_list + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + + def avail_mem = 3 + if (!task.memory) { + log.info '[GATK BedToIntervalList] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' + } else { + avail_mem = task.memory.giga + } + """ + gatk --java-options "-Xmx${avail_mem}g" BedToIntervalList \\ + --INPUT $bed \\ + --OUTPUT ${prefix}.interval_list \\ + --SEQUENCE_DICTIONARY $dict \\ + --TMP_DIR . \\ + $args + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.interval_list + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') + END_VERSIONS + """ +} diff --git a/modules/nf-core/gatk4/bedtointervallist/meta.yml b/modules/nf-core/gatk4/bedtointervallist/meta.yml new file mode 100644 index 00000000..986f1592 --- /dev/null +++ b/modules/nf-core/gatk4/bedtointervallist/meta.yml @@ -0,0 +1,40 @@ +name: gatk4_bedtointervallist +description: Creates an interval list from a bed file and a reference dict +keywords: + - bed + - interval list +tools: + - gatk4: + description: | + Developed in the Data Sciences Platform at the Broad Institute, the toolkit offers a wide variety of tools + with a primary focus on variant discovery and genotyping. Its powerful processing engine + and high-performance computing features make it capable of taking on projects of any size. + homepage: https://gatk.broadinstitute.org/hc/en-us + documentation: https://gatk.broadinstitute.org/hc/en-us/categories/360002369672s + doi: 10.1158/1538-7445.AM2017-3590 + licence: ["Apache-2.0"] +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test'] + - bed: + type: file + description: Input bed file + pattern: "*.bed" + - dict: + type: file + description: Sequence dictionary + pattern: "*.dict" +output: + - interval_list: + type: file + description: gatk interval list file + pattern: "*.interval_list" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" +authors: + - "@kevinmenden" diff --git a/modules/nf-core/gatk4/createsequencedictionary/main.nf b/modules/nf-core/gatk4/createsequencedictionary/main.nf new file mode 100644 index 00000000..bc324ada --- /dev/null +++ b/modules/nf-core/gatk4/createsequencedictionary/main.nf @@ -0,0 +1,51 @@ +process GATK4_CREATESEQUENCEDICTIONARY { + tag "$fasta" + label 'process_medium' + + conda "bioconda::gatk4=4.3.0.0" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/gatk4:4.3.0.0--py36hdfd78af_0': + 'quay.io/biocontainers/gatk4:4.3.0.0--py36hdfd78af_0' }" + + input: + path fasta + + output: + path "*.dict" , emit: dict + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + + def avail_mem = 6 + if (!task.memory) { + log.info '[GATK CreateSequenceDictionary] Available memory not known - defaulting to 6GB. Specify process memory requirements to change this.' + } else { + avail_mem = task.memory.giga + } + """ + gatk --java-options "-Xmx${avail_mem}g" CreateSequenceDictionary \\ + --REFERENCE $fasta \\ + --URI $fasta \\ + --TMP_DIR . \\ + $args + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') + END_VERSIONS + """ + + stub: + """ + touch ${fasta.baseName}.dict + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//') + END_VERSIONS + """ +} diff --git a/modules/nf-core/gatk4/createsequencedictionary/meta.yml b/modules/nf-core/gatk4/createsequencedictionary/meta.yml new file mode 100644 index 00000000..bd247888 --- /dev/null +++ b/modules/nf-core/gatk4/createsequencedictionary/meta.yml @@ -0,0 +1,32 @@ +name: gatk4_createsequencedictionary +description: Creates a sequence dictionary for a reference sequence +keywords: + - dictionary + - fasta +tools: + - gatk: + description: | + Developed in the Data Sciences Platform at the Broad Institute, the toolkit offers a wide variety of tools + with a primary focus on variant discovery and genotyping. Its powerful processing engine + and high-performance computing features make it capable of taking on projects of any size. + homepage: https://gatk.broadinstitute.org/hc/en-us + documentation: https://gatk.broadinstitute.org/hc/en-us/categories/360002369672s + doi: 10.1158/1538-7445.AM2017-3590 + licence: ["Apache-2.0"] + +input: + - fasta: + type: file + description: Input fasta file + pattern: "*.{fasta,fa}" +output: + - dict: + type: file + description: gatk dictionary file + pattern: "*.{dict}" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" +authors: + - "@maxulysse" diff --git a/workflows/build_references.nf b/workflows/build_references.nf index 277f03ea..d097acdf 100644 --- a/workflows/build_references.nf +++ b/workflows/build_references.nf @@ -11,7 +11,8 @@ include { FUSIONREPORT_DOWNLOAD } from '../modules/local/fusionreport/ include { STARFUSION_BUILD } from '../modules/local/starfusion/build/main' include { STARFUSION_DOWNLOAD } from '../modules/local/starfusion/download/main' include { GTF_TO_REFFLAT } from '../modules/local/uscs/custom_gtftogenepred/main' - +include { RRNA_TRANSCRIPTS } from '../modules/local/rrnatranscripts/main' +include { CONVERT2BED } from '../modules/local/convert2bed/main' /* ======================================================================================== IMPORT NF-CORE MODULES/SUBWORKFLOWS @@ -21,6 +22,8 @@ include { GTF_TO_REFFLAT } from '../modules/local/uscs/custom_g include { SAMTOOLS_FAIDX } from '../modules/nf-core/samtools/faidx/main' include { STAR_GENOMEGENERATE } from '../modules/nf-core/star/genomegenerate/main' include { KALLISTO_INDEX as PIZZLY_INDEX } from '../modules/nf-core/kallisto/index/main' +include { GATK4_CREATESEQUENCEDICTIONARY } from '../modules/nf-core/gatk4/createsequencedictionary/main' +include { GATK4_BEDTOINTERVALLIST } from '../modules/nf-core/gatk4/bedtointervallist/main' /* ======================================================================================== @@ -31,8 +34,20 @@ include { KALLISTO_INDEX as PIZZLY_INDEX } from '../modules/nf-core/kallisto/in workflow BUILD_REFERENCES { ENSEMBL_DOWNLOAD( params.ensembl_version ) - ch_fasta_w_meta = ENSEMBL_DOWNLOAD.out.fasta.map{ it -> [[id:it[0].baseName], it] } + ENSEMBL_DOWNLOAD.out.fasta + .map { it -> tuple(id:it.baseName, it) } + .set { ch_fasta_w_meta } + SAMTOOLS_FAIDX(ch_fasta_w_meta) + GATK4_CREATESEQUENCEDICTIONARY(ENSEMBL_DOWNLOAD.out.fasta) + + ENSEMBL_DOWNLOAD.out.gtf + .map { it -> tuple(id:it.baseName, it) } + .set { ch_gtf_w_meta } + RRNA_TRANSCRIPTS(ch_gtf_w_meta) + CONVERT2BED(RRNA_TRANSCRIPTS.out.rrna_gtf) + + GATK4_BEDTOINTERVALLIST(CONVERT2BED.out.bed, GATK4_CREATESEQUENCEDICTIONARY.out.dict) if (params.starindex || params.all || params.starfusion || params.arriba || params.squid ) { @@ -59,11 +74,11 @@ workflow BUILD_REFERENCES { } } - if (params.starfusion_build){ - GTF_TO_REFFLAT(ENSEMBL_DOWNLOAD.out.chrgtf) - } else { - GTF_TO_REFFLAT(STARFUSION_DOWNLOAD.out.chrgtf) - } + // if (params.starfusion_build){ + // GTF_TO_REFFLAT(ENSEMBL_DOWNLOAD.out.chrgtf) + // } else { + // GTF_TO_REFFLAT(STARFUSION_DOWNLOAD.out.chrgtf) + // } if (params.fusionreport || params.all) { FUSIONREPORT_DOWNLOAD( params.cosmic_username, params.cosmic_passwd ) From 688b826cd0e2ec47ed26c91b828e32d3c0a16b36 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 14 Feb 2023 21:51:10 +0100 Subject: [PATCH 119/176] use rrna invervals --- conf/genomes.config | 2 ++ docs/output.md | 1 + main.nf | 1 + modules/local/picard/collectrnaseqmetrics/meta.yml | 2 +- nextflow_schema.json | 8 ++++++++ subworkflows/local/qc_workflow.nf | 3 ++- workflows/rnafusion.nf | 4 +++- 7 files changed, 18 insertions(+), 3 deletions(-) diff --git a/conf/genomes.config b/conf/genomes.config index 64343922..e7a01b6d 100644 --- a/conf/genomes.config +++ b/conf/genomes.config @@ -17,6 +17,8 @@ params { chrgtf = "${params.genomes_base}/ensembl/Homo_sapiens.${params.genome}.${params.ensembl_version}.chr.gtf" transcript = "${params.genomes_base}/ensembl/Homo_sapiens.${params.genome}.${params.ensembl_version}.cdna.all.fa.gz" refflat = "${params.genomes_base}/ensembl/Homo_sapiens.${params.genome}.${params.ensembl_version}.chr.gtf.refflat" + rrna_intervals= "${params.genomes_base}/ensembl/Homo_sapiens.${params.genome}.${params.ensembl_version}.interval_list" + } } } diff --git a/docs/output.md b/docs/output.md index c9c709f1..8ed07454 100644 --- a/docs/output.md +++ b/docs/output.md @@ -45,6 +45,7 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d - `Homo_sapiens.GRCh38.{ensembl_version}.gtf` - `Homo_sapiens.GRCh38.{ensembl_version}.chr.gtf` - `Homo_sapiens.GRCh38.{ensembl_version}.chr.gtf.refflat` + - `Homo_sapiens.GRCh38.{ensembl_version}.interval_list` - `fusioncatcher` - `human_v` - dir with all references for fusioncatcher - `fusion_report_db` diff --git a/main.nf b/main.nf index 972c7f5a..54dddc53 100644 --- a/main.nf +++ b/main.nf @@ -24,6 +24,7 @@ params.gtf = WorkflowMain.getGenomeAttribute(params, 'gtf') params.chrgtf = WorkflowMain.getGenomeAttribute(params, 'chrgtf') params.transcript = WorkflowMain.getGenomeAttribute(params, 'transcript') params.refflat = WorkflowMain.getGenomeAttribute(params, 'refflat') +params.rrna_intervals = WorkflowMain.getGenomeAttribute(params, 'rrna_intervals') /* ======================================================================================== diff --git a/modules/local/picard/collectrnaseqmetrics/meta.yml b/modules/local/picard/collectrnaseqmetrics/meta.yml index 131b8337..0cae7d07 100644 --- a/modules/local/picard/collectrnaseqmetrics/meta.yml +++ b/modules/local/picard/collectrnaseqmetrics/meta.yml @@ -32,7 +32,7 @@ input: - refflat: type: file description: Gene annotations in refFlat form - - rrna_interval: + - rrna_intervals: type: file description: Location of rRNA sequences in genome, in interval_list format output: diff --git a/nextflow_schema.json b/nextflow_schema.json index 66d19be1..c5d6d87c 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -327,6 +327,14 @@ "pattern": "^\\S+\\.refflat?$", "description": "Path to GTF genome file.", "fa_icon": "far fa-file-code" + }, + "rrna_intervals": { + "type": "string", + "format": "file-path", + "mimetype": "text/plain", + "pattern": "^\\S+\\.interval_list?$", + "description": "Path to ribosomal interval list.", + "fa_icon": "far fa-file-code" } } }, diff --git a/subworkflows/local/qc_workflow.nf b/subworkflows/local/qc_workflow.nf index b8fe1007..a2a1dec9 100644 --- a/subworkflows/local/qc_workflow.nf +++ b/subworkflows/local/qc_workflow.nf @@ -14,6 +14,7 @@ workflow QC_WORKFLOW { ch_refflat ch_fasta ch_fai + ch_rrna_interval main: ch_versions = Channel.empty() @@ -27,7 +28,7 @@ workflow QC_WORKFLOW { bam_indexed = bam_sorted.join(SAMTOOLS_INDEX_FOR_QC.out.bai) - PICARD_COLLECTRNASEQMETRICS(bam_indexed, ch_refflat, []) + PICARD_COLLECTRNASEQMETRICS(bam_indexed, ch_refflat, ch_rrna_interval) ch_versions = ch_versions.mix(PICARD_COLLECTRNASEQMETRICS.out.versions) ch_rnaseq_metrics = Channel.empty().mix(PICARD_COLLECTRNASEQMETRICS.out.metrics) diff --git a/workflows/rnafusion.nf b/workflows/rnafusion.nf index 1feba931..d2bfe170 100644 --- a/workflows/rnafusion.nf +++ b/workflows/rnafusion.nf @@ -18,6 +18,7 @@ ch_chrgtf = params.starfusion_build ? file(params.chrgtf) : file("${params.starf ch_starindex_ref = params.starfusion_build ? params.starindex_ref : "${params.starfusion_ref}/ref_genome.fa.star.idx" ch_starindex_ensembl_ref = params.starindex_ref ch_refflat = params.starfusion_build ? file(params.refflat) : "${params.ensembl_ref}/ref_annot.gtf.refflat" +ch_rrna_interval = params.starfusion_build ? file(params.rrna_intervals) : "${params.ensembl_ref}/ref_annot.interval_list" def checkPathParamList = [ @@ -26,7 +27,8 @@ def checkPathParamList = [ params.gtf, ch_chrgtf, params.transcript, - ch_refflat + ch_refflat, + ch_rrna_interval ] From f1cafbe2f3bceef8e69ea922fa2848b6093b1c58 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 14 Feb 2023 21:58:12 +0100 Subject: [PATCH 120/176] polish --- CHANGELOG.md | 1 + workflows/rnafusion.nf | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cfaf5e17..427a33f7 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 - exitStatus 140 now part of the retry strategy - stubs to all local modules - `--stringtie` option added with StringTie v2.2.1 to detect splicing events. Not included in `fusion-report` or `fusionInspector` summaries. Included in the `--all` workflow +- generation of ribosomal RNA interval list with build_references and use it in picard CollectRnaMetrics ### Changed diff --git a/workflows/rnafusion.nf b/workflows/rnafusion.nf index d2bfe170..67dd1d50 100644 --- a/workflows/rnafusion.nf +++ b/workflows/rnafusion.nf @@ -235,7 +235,8 @@ workflow RNAFUSION { ch_chrgtf, ch_refflat, ch_fasta, - ch_fai + ch_fai, + ch_rrna_interval ) ch_versions = ch_versions.mix(QC_WORKFLOW.out.versions.first().ifEmpty(null)) From 8d19bc8f70658812b5dafaf4438b3e3f8c1a2c4d Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 14 Feb 2023 21:59:38 +0100 Subject: [PATCH 121/176] black linting --- bin/get_rrna_transcripts.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/bin/get_rrna_transcripts.py b/bin/get_rrna_transcripts.py index 46ec2e15..46812caf 100755 --- a/bin/get_rrna_transcripts.py +++ b/bin/get_rrna_transcripts.py @@ -5,6 +5,7 @@ import sys from pathlib import Path + def get_rrna_intervals(file_in, file_out): """ Get the commented out header @@ -17,16 +18,21 @@ def get_rrna_intervals(file_in, file_out): be created; always in GTF format. """ - patterns = {"#", "transcript_biotype \"Mt_rRNA\"", "transcript_biotype \"rRNA\"", "transcript_biotype \"rRNA_pseudogene\""} + patterns = { + "#", + 'transcript_biotype "Mt_rRNA"', + 'transcript_biotype "rRNA"', + 'transcript_biotype "rRNA_pseudogene"', + } line_starts = {"MT", "1", "2", "3", "4", "5", "6", "7", "8", "9"} out_lines = [] with file_in.open() as f: data = f.readlines() for line in data: for pattern in patterns: - if (pattern in line): + if pattern in line: for line_start in line_starts: - if (line.startswith(line_start)): + if line.startswith(line_start): out_lines.append(line) with file_out.open(mode="w") as out_file: From 03aa85d746134ac42ebd55bb945a427fe5f94ff5 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 14 Feb 2023 22:05:53 +0100 Subject: [PATCH 122/176] uncomment what was commented out for testing --- workflows/build_references.nf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/workflows/build_references.nf b/workflows/build_references.nf index d097acdf..c43ecc84 100644 --- a/workflows/build_references.nf +++ b/workflows/build_references.nf @@ -74,11 +74,11 @@ workflow BUILD_REFERENCES { } } - // if (params.starfusion_build){ - // GTF_TO_REFFLAT(ENSEMBL_DOWNLOAD.out.chrgtf) - // } else { - // GTF_TO_REFFLAT(STARFUSION_DOWNLOAD.out.chrgtf) - // } + if (params.starfusion_build){ + GTF_TO_REFFLAT(ENSEMBL_DOWNLOAD.out.chrgtf) + } else { + GTF_TO_REFFLAT(STARFUSION_DOWNLOAD.out.chrgtf) + } if (params.fusionreport || params.all) { FUSIONREPORT_DOWNLOAD( params.cosmic_username, params.cosmic_passwd ) From 0b54592734be6433ecda138782836ee2775492e8 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 15 Feb 2023 15:43:28 +0100 Subject: [PATCH 123/176] add whitelist, fusions.json in publish dir of fusionreport and trinity version=2.13.2 --- modules.json | 5 ++ modules/local/fusioninspector/main.nf | 2 +- modules/local/fusionreport/detect/main.nf | 4 ++ modules/local/starfusion/build/main.nf | 2 +- modules/local/starfusion/detect/main.nf | 2 +- modules/local/starfusion/download/main.nf | 2 +- modules/nf-core/cat/cat/main.nf | 62 +++++++++++++++++++ modules/nf-core/cat/cat/meta.yml | 37 +++++++++++ nextflow.config | 1 + nextflow_schema.json | 5 ++ .../local/fusioninspector_workflow.nf | 12 ++++ whitelist-test | 2 + 12 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 modules/nf-core/cat/cat/main.nf create mode 100644 modules/nf-core/cat/cat/meta.yml create mode 100644 whitelist-test diff --git a/modules.json b/modules.json index a2ae7960..d813ac79 100644 --- a/modules.json +++ b/modules.json @@ -10,6 +10,11 @@ "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", "installed_by": ["modules"] }, + "cat/cat": { + "branch": "master", + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "installed_by": ["modules"] + }, "cat/fastq": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", diff --git a/modules/local/fusioninspector/main.nf b/modules/local/fusioninspector/main.nf index c6f4431f..5de9f096 100644 --- a/modules/local/fusioninspector/main.nf +++ b/modules/local/fusioninspector/main.nf @@ -2,7 +2,7 @@ process FUSIONINSPECTOR { tag "$meta.id" label 'process_high' - conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.12.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" + conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.12.0 bioconda::trinity=2.13.2 bioconda::samtools=1.9 bioconda::star=2.7.8a" container 'docker.io/trinityctat/starfusion:1.12.0' input: diff --git a/modules/local/fusionreport/detect/main.nf b/modules/local/fusionreport/detect/main.nf index 12090a03..6db28088 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/local/fusionreport/detect/main.nf @@ -16,6 +16,7 @@ process FUSIONREPORT { tuple val(meta), path("*fusionreport.tsv") , emit: fusion_list tuple val(meta), path("*fusionreport_filtered.tsv") , emit: fusion_list_filtered tuple val(meta), path("*.html") , emit: report + tuple val(meta), path("*.json") , emit: json when: task.ext.when == null || task.ext.when @@ -32,6 +33,7 @@ process FUSIONREPORT { mv fusion_list.tsv ${prefix}.fusionreport.tsv mv fusion_list_filtered.tsv ${prefix}.fusionreport_filtered.tsv + mv fusions.json ${prefix}.fusions.json cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -46,6 +48,8 @@ process FUSIONREPORT { touch ${prefix}.fusionreport_filtered.tsv touch ${prefix}.fusionreport.tsv touch index.html + touch fusions.json + cat <<-END_VERSIONS > versions.yml "${task.process}": fusion_report: \$(fusion_report --version | sed 's/fusion-report //') diff --git a/modules/local/starfusion/build/main.nf b/modules/local/starfusion/build/main.nf index 22db445f..cf6f9d76 100644 --- a/modules/local/starfusion/build/main.nf +++ b/modules/local/starfusion/build/main.nf @@ -1,7 +1,7 @@ process STARFUSION_BUILD { tag 'star-fusion' - conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.12.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" + conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.12.0 bioconda::trinity=2.13.2 bioconda::samtools=1.9 bioconda::star=2.7.8a" container "docker.io/trinityctat/starfusion:1.12.0" input: diff --git a/modules/local/starfusion/detect/main.nf b/modules/local/starfusion/detect/main.nf index cae20049..fba671b6 100644 --- a/modules/local/starfusion/detect/main.nf +++ b/modules/local/starfusion/detect/main.nf @@ -2,7 +2,7 @@ process STARFUSION { tag "$meta.id" label 'process_high' - conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.12.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" + conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.12.0 bioconda::=2.13.2 bioconda::samtools=1.9 bioconda::star=2.7.8a" container 'docker.io/trinityctat/starfusion:1.12.0' input: diff --git a/modules/local/starfusion/download/main.nf b/modules/local/starfusion/download/main.nf index f48511be..9c9b1482 100644 --- a/modules/local/starfusion/download/main.nf +++ b/modules/local/starfusion/download/main.nf @@ -1,7 +1,7 @@ process STARFUSION_DOWNLOAD { tag 'star-fusion' - conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.12.0 bioconda::trinity bioconda::samtools=1.9 bioconda::star=2.7.8a" + conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.12.0 bioconda::trinity=2.13.2 bioconda::samtools=1.9 bioconda::star=2.7.8a" container 'docker.io/trinityctat/starfusion:1.12.0' output: diff --git a/modules/nf-core/cat/cat/main.nf b/modules/nf-core/cat/cat/main.nf new file mode 100644 index 00000000..840af4b9 --- /dev/null +++ b/modules/nf-core/cat/cat/main.nf @@ -0,0 +1,62 @@ +process CAT_CAT { + tag "$meta.id" + label 'process_low' + + conda "conda-forge::pigz=2.3.4" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/pigz:2.3.4' : + 'quay.io/biocontainers/pigz:2.3.4' }" + + input: + tuple val(meta), path(files_in) + + output: + tuple val(meta), path("${prefix}"), emit: file_out + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def args2 = task.ext.args2 ?: '' + def file_list = files_in.collect { it.toString() } + + // | input | output | command1 | command2 | + // |-----------|------------|----------|----------| + // | gzipped | gzipped | cat | | + // | ungzipped | ungzipped | cat | | + // | gzipped | ungzipped | zcat | | + // | ungzipped | gzipped | cat | pigz | + + // Use input file ending as default + prefix = task.ext.prefix ?: "${meta.id}${file_list[0].substring(file_list[0].lastIndexOf('.'))}" + out_zip = prefix.endsWith('.gz') + in_zip = file_list[0].endsWith('.gz') + command1 = (in_zip && !out_zip) ? 'zcat' : 'cat' + command2 = (!in_zip && out_zip) ? "| pigz -c -p $task.cpus $args2" : '' + """ + $command1 \\ + $args \\ + ${file_list.join(' ')} \\ + $command2 \\ + > ${prefix} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + pigz: \$( pigz --version 2>&1 | sed 's/pigz //g' ) + END_VERSIONS + """ + + stub: + def file_list = files_in.collect { it.toString() } + prefix = task.ext.prefix ?: "${meta.id}${file_list[0].substring(file_list[0].lastIndexOf('.'))}" + """ + touch $prefix + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + pigz: \$( pigz --version 2>&1 | sed 's/pigz //g' ) + END_VERSIONS + """ +} diff --git a/modules/nf-core/cat/cat/meta.yml b/modules/nf-core/cat/cat/meta.yml new file mode 100644 index 00000000..5eeff5a6 --- /dev/null +++ b/modules/nf-core/cat/cat/meta.yml @@ -0,0 +1,37 @@ +name: cat_cat +description: A module for concatenation of gzipped or uncompressed files +keywords: + - concatenate + - gzip + - cat +tools: + - cat: + description: Just concatenation + homepage: None + documentation: https://man7.org/linux/man-pages/man1/cat.1.html + tool_dev_url: None + licence: ["GPL-3.0-or-later"] +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - files_in: + type: file + description: List of compressed / uncompressed files + pattern: "*" + +output: + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + - file_out: + type: file + description: Concatenated file. Will be gzipped if file_out ends with ".gz" + pattern: "${file_out}" + +authors: + - "@erikrikarddaniel" + - "@FriederikeHanssen" diff --git a/nextflow.config b/nextflow.config index 3c7a878e..b41cca23 100644 --- a/nextflow.config +++ b/nextflow.config @@ -85,6 +85,7 @@ params { starfusion_fusions = null fusioncatcher_fusions = null fusioninspector_fusions = null + whitelist = null // Boilerplate options outdir = null diff --git a/nextflow_schema.json b/nextflow_schema.json index c5d6d87c..d31243a3 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -229,6 +229,11 @@ "fa_icon": "far fa-file-code", "description": "Run stringtie analysis" }, + "whitelist": { + "type": "string", + "fa_icon": "far fa-file-code", + "description": "Path to fusions to add to the input of fusioninspector" + }, "cosmic_username": { "type": "string", "fa_icon": "far fa-file-code", diff --git a/subworkflows/local/fusioninspector_workflow.nf b/subworkflows/local/fusioninspector_workflow.nf index 9ff00327..b324cf41 100644 --- a/subworkflows/local/fusioninspector_workflow.nf +++ b/subworkflows/local/fusioninspector_workflow.nf @@ -1,4 +1,5 @@ include { FUSIONINSPECTOR } from '../../modules/local/fusioninspector/main' +include { CAT_CAT } from '../../modules/nf-core/cat/cat/main' workflow FUSIONINSPECTOR_WORKFLOW { take: @@ -10,6 +11,17 @@ workflow FUSIONINSPECTOR_WORKFLOW { ch_versions = Channel.empty() index ="${params.starfusion_ref}" ch_fusion_list = params.fusioninspector_filter ? fusion_list_filtered : fusion_list + + if (file(params.whitelist).exists()) { + ch_whitelist = ch_fusion_list.combine(Channel.value(file(params.whitelist, checkIfExists:true))) + .map { meta, fusions, whitelist -> [ meta, [fusions, whitelist] ] } + + CAT_CAT(ch_whitelist) + ch_versions = ch_versions.mix(CAT_CAT.out.versions) + + ch_fusion_list = CAT_CAT.out.file_out + } + reads_fusion = reads.join(ch_fusion_list ) FUSIONINSPECTOR( reads_fusion, index) diff --git a/whitelist-test b/whitelist-test new file mode 100644 index 00000000..300c3213 --- /dev/null +++ b/whitelist-test @@ -0,0 +1,2 @@ +ARN--ARN +ARN--ARN From abd4bdb2d3b2a18f9c755aa1bb13c9058e161325 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 15 Feb 2023 15:57:04 +0100 Subject: [PATCH 124/176] fix singularity link to bedops --- modules/local/convert2bed/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/convert2bed/main.nf b/modules/local/convert2bed/main.nf index 6d526eb4..c4313f0a 100644 --- a/modules/local/convert2bed/main.nf +++ b/modules/local/convert2bed/main.nf @@ -4,7 +4,7 @@ process CONVERT2BED { conda "bioconda::bedops=2.4.41" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'bedops:2.4.41--h9f5acd7_0' : + 'https://depot.galaxyproject.org/singularity/bedops:2.4.41--h9f5acd7_0' : 'quay.io/biocontainers/bedops:2.4.41--h9f5acd7_0' }" input: From c58d2371c40b4553c4651e9686be10f699bd6907 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 15 Feb 2023 16:16:38 +0100 Subject: [PATCH 125/176] change if statement to work when whitelist is null --- subworkflows/local/fusioninspector_workflow.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/local/fusioninspector_workflow.nf b/subworkflows/local/fusioninspector_workflow.nf index b324cf41..25a99658 100644 --- a/subworkflows/local/fusioninspector_workflow.nf +++ b/subworkflows/local/fusioninspector_workflow.nf @@ -12,7 +12,7 @@ workflow FUSIONINSPECTOR_WORKFLOW { index ="${params.starfusion_ref}" ch_fusion_list = params.fusioninspector_filter ? fusion_list_filtered : fusion_list - if (file(params.whitelist).exists()) { + if (params.whitelist) { ch_whitelist = ch_fusion_list.combine(Channel.value(file(params.whitelist, checkIfExists:true))) .map { meta, fusions, whitelist -> [ meta, [fusions, whitelist] ] } From 061d2a4848ec83d248ab869a6351a39a16c3180d Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 15 Feb 2023 18:07:17 +0100 Subject: [PATCH 126/176] add documentation --- CHANGELOG.md | 1 + docs/usage.md | 12 ++++++++++++ subworkflows/local/fusioninspector_workflow.nf | 2 +- whitelist-test | 2 -- 4 files changed, 14 insertions(+), 3 deletions(-) delete mode 100644 whitelist-test diff --git a/CHANGELOG.md b/CHANGELOG.md index 427a33f7..0d717cb9 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 - stubs to all local modules - `--stringtie` option added with StringTie v2.2.1 to detect splicing events. Not included in `fusion-report` or `fusionInspector` summaries. Included in the `--all` workflow - generation of ribosomal RNA interval list with build_references and use it in picard CollectRnaMetrics +- `whitelist` parameter to add custom fusions to the detected ones and consider the whole for the `fusionInspector` analysis ### Changed diff --git a/docs/usage.md b/docs/usage.md index 24f74e52..ad0f50bd 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -124,6 +124,18 @@ nextflow run nf-core/rnafusion \ --outdir ``` +#### Adding custom fusions to consider as well as the detected set: whitelist + +```bash +nextflow run nf-core/rnafusion \ + -- -- ... \ + --input \ + --genomes_base \ + --outdir + --whitelist +``` + + #### Running FusionInspector only FusionInspector can be run standalone with: diff --git a/subworkflows/local/fusioninspector_workflow.nf b/subworkflows/local/fusioninspector_workflow.nf index 25a99658..944f0daf 100644 --- a/subworkflows/local/fusioninspector_workflow.nf +++ b/subworkflows/local/fusioninspector_workflow.nf @@ -16,7 +16,7 @@ workflow FUSIONINSPECTOR_WORKFLOW { ch_whitelist = ch_fusion_list.combine(Channel.value(file(params.whitelist, checkIfExists:true))) .map { meta, fusions, whitelist -> [ meta, [fusions, whitelist] ] } - CAT_CAT(ch_whitelist) + CAT_CAT(ch_whitelist) // fusioninspector takes care of possible duplicates ch_versions = ch_versions.mix(CAT_CAT.out.versions) ch_fusion_list = CAT_CAT.out.file_out diff --git a/whitelist-test b/whitelist-test deleted file mode 100644 index 300c3213..00000000 --- a/whitelist-test +++ /dev/null @@ -1,2 +0,0 @@ -ARN--ARN -ARN--ARN From 15e39377effdb803758184da2d08a8ff938b4943 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 15 Feb 2023 18:09:47 +0100 Subject: [PATCH 127/176] prettier --- docs/usage.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index ad0f50bd..a2c9da61 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -135,7 +135,6 @@ nextflow run nf-core/rnafusion \ --whitelist ``` - #### Running FusionInspector only FusionInspector can be run standalone with: From db678e8f47a88242197321cf012c19a6a90b1b38 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 15 Feb 2023 19:41:33 +0100 Subject: [PATCH 128/176] add trimming workflow --- CHANGELOG.md | 1 + adapter_fasta_test | 0 conf/modules.config | 4 ++ docs/usage.md | 33 ++++++++- modules.json | 5 ++ modules/nf-core/fastp/main.nf | 103 ++++++++++++++++++++++++++++ modules/nf-core/fastp/meta.yml | 73 ++++++++++++++++++++ nextflow.config | 3 + nextflow_schema.json | 15 ++++ subworkflows/local/trim_workflow.nf | 25 +++++-- workflows/rnafusion.nf | 18 ++--- 11 files changed, 267 insertions(+), 13 deletions(-) create mode 100644 adapter_fasta_test create mode 100644 modules/nf-core/fastp/main.nf create mode 100644 modules/nf-core/fastp/meta.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 427a33f7..10e9c8a2 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 - stubs to all local modules - `--stringtie` option added with StringTie v2.2.1 to detect splicing events. Not included in `fusion-report` or `fusionInspector` summaries. Included in the `--all` workflow - generation of ribosomal RNA interval list with build_references and use it in picard CollectRnaMetrics +- trimming workflow using `fastp`: use trimmed reads for all tools ### Changed diff --git a/adapter_fasta_test b/adapter_fasta_test new file mode 100644 index 00000000..e69de29b diff --git a/conf/modules.config b/conf/modules.config index 68f92c02..49960cee 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -53,6 +53,10 @@ process { ] } + withName: FASTP { + ext.args = params.trim_tail ? "--trim_tail1 ${params.trim_tail}" : '' + } + withName: FASTQC { ext.args = '--quiet' } diff --git a/docs/usage.md b/docs/usage.md index 24f74e52..7b55c19b 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -124,6 +124,37 @@ nextflow run nf-core/rnafusion \ --outdir ``` +#### Trimming + +There are 2 options to trim + +1. fastp + In this case all tools use the trimmed reads. Quality and adapter trimming by default. In addition, tail trimming and adapter_fastq specification are possible. Example usage: + + ```bash +nextflow run nf-core/rnafusion \ + -- -- ... \ + --input \ + --genomes_base \ + --outdir \ + --fastp_trim \ + --trim_tail (optional) \ + --adapter_fastq (optional) +``` + +2. hard trimming + In this case, only reads fed to fusioncatcher are trimmed. This is a harsh workaround in case of high read-through. The recommended trimming is thus the fastp_trim one. The trimming is done at 75 bp from the tails. Example usage: + + ```bash +nextflow run nf-core/rnafusion \ + -- -- ... \ + --input \ + --genomes_base \ + --outdir \ + --trim +`` + + #### Running FusionInspector only FusionInspector can be run standalone with: @@ -140,7 +171,7 @@ The custom fusion file should have the following format: ``` GENE1--GENE2 -GENE3--GENE3 +GENE3--GENE4 ``` #### Optional manual feed-in of fusion files diff --git a/modules.json b/modules.json index a2ae7960..05cc1ed5 100644 --- a/modules.json +++ b/modules.json @@ -20,6 +20,11 @@ "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", "installed_by": ["modules"] }, + "fastp": { + "branch": "master", + "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "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 00000000..e1ed9288 --- /dev/null +++ b/modules/nf-core/fastp/main.nf @@ -0,0 +1,103 @@ +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 \\ + --stdout \\ + --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 00000000..6f6fad74 --- /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: https://doi.org/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" diff --git a/nextflow.config b/nextflow.config index 3c7a878e..6ab8bc4a 100644 --- a/nextflow.config +++ b/nextflow.config @@ -41,6 +41,9 @@ params { // Trimming trim = false + fastp_trim = false + trim_tail = null + adapter_fasta = [] // Alignment options star_ignore_sjdbgtf = false diff --git a/nextflow_schema.json b/nextflow_schema.json index c5d6d87c..5f3ea1b2 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -251,6 +251,21 @@ "type": "boolean", "description": "Preform trimming of reads, default: false", "fa_icon": "fas fa-cut" + }, + "fastp_trim": { + "type": "boolean", + "description": "Preform fastp trimming of reads, default: false", + "fa_icon": "fas fa-cut" + }, + "trim_tail": { + "type": "integer", + "description": "Preform tail trimming of reads, default: null", + "fa_icon": "fas fa-cut" + }, + "adapter_fasta": { + "type": "string", + "description": "Path to adapter fasta file: default: []", + "fa_icon": "fas fa-cut" } } }, diff --git a/subworkflows/local/trim_workflow.nf b/subworkflows/local/trim_workflow.nf index c4a01971..7420c20e 100644 --- a/subworkflows/local/trim_workflow.nf +++ b/subworkflows/local/trim_workflow.nf @@ -1,5 +1,8 @@ include { REFORMAT } from '../../modules/local/reformat/main' include { FASTQC as FASTQC_FOR_TRIM } from '../../modules/nf-core/fastqc/main' +include { FASTP } from '../../modules/nf-core/fastp/main' +include { FASTQC as FASTQC_FOR_FASTP } from '../../modules/nf-core/fastqc/main' + workflow TRIM_WORKFLOW { take: @@ -12,16 +15,30 @@ workflow TRIM_WORKFLOW { REFORMAT( reads ) ch_versions = ch_versions.mix(REFORMAT.out.versions) - ch_reads_out = REFORMAT.out.reads_out + FASTQC_FOR_TRIM (REFORMAT.out.reads_out) + ch_versions = ch_versions.mix(FASTQC_FOR_TRIM.out.versions) + + ch_reads_all = reads + ch_reads_fusioncatcher = REFORMAT.out.reads_out + } + else if (params.fastp_trim) { + FASTP(reads, params.adapter_fasta, false, false) + ch_versions = ch_versions.mix(FASTP.out.versions) + + FASTQC_FOR_FASTP(FASTP.out.reads) + ch_versions = ch_versions.mix(FASTQC_FOR_FASTP.out.versions) - FASTQC_FOR_TRIM (ch_reads_out) + ch_reads_all = FASTP.out.reads + ch_reads_fusioncatcher = ch_reads_all } else { - ch_reads_out = reads + ch_reads_all = reads + ch_reads_fusioncatcher = reads } emit: - reads = ch_reads_out + ch_reads_all + ch_reads_fusioncatcher versions = ch_versions.ifEmpty(null) } diff --git a/workflows/rnafusion.nf b/workflows/rnafusion.nf index 67dd1d50..d79f864c 100644 --- a/workflows/rnafusion.nf +++ b/workflows/rnafusion.nf @@ -151,11 +151,13 @@ workflow RNAFUSION { TRIM_WORKFLOW ( ch_cat_fastq ) - ch_cat_trim_fastq = TRIM_WORKFLOW.out.reads + ch_reads_fusioncatcher = TRIM_WORKFLOW.out.ch_reads_fusioncatcher + ch_reads_all = TRIM_WORKFLOW.out.ch_reads_all + // Run STAR alignment and Arriba ARRIBA_WORKFLOW ( - ch_cat_fastq, + ch_reads_all, ch_gtf, ch_fasta, ch_starindex_ensembl_ref @@ -165,7 +167,7 @@ workflow RNAFUSION { // Run pizzly/kallisto PIZZLY_WORKFLOW ( - ch_cat_fastq, + ch_reads_all, ch_gtf, ch_transcript ) @@ -175,7 +177,7 @@ workflow RNAFUSION { // Run squid SQUID_WORKFLOW ( - ch_cat_fastq, + ch_reads_all, ch_gtf, ch_starindex_ensembl_ref, ch_fasta @@ -185,7 +187,7 @@ workflow RNAFUSION { //Run STAR fusion STARFUSION_WORKFLOW ( - ch_cat_fastq, + ch_reads_all, ch_chrgtf, ch_starindex_ref ) @@ -194,7 +196,7 @@ workflow RNAFUSION { //Run fusioncatcher FUSIONCATCHER_WORKFLOW ( - ch_cat_trim_fastq + ch_reads_fusioncatcher ) ch_versions = ch_versions.mix(FUSIONCATCHER_WORKFLOW.out.versions.first().ifEmpty(null)) @@ -209,7 +211,7 @@ workflow RNAFUSION { //Run fusion-report FUSIONREPORT_WORKFLOW ( - ch_cat_fastq, + ch_reads_all, params.fusionreport_ref, ARRIBA_WORKFLOW.out.fusions, PIZZLY_WORKFLOW.out.fusions, @@ -222,7 +224,7 @@ workflow RNAFUSION { //Run fusionInpector FUSIONINSPECTOR_WORKFLOW ( - ch_cat_fastq, + ch_reads_all, FUSIONREPORT_WORKFLOW.out.fusion_list, FUSIONREPORT_WORKFLOW.out.fusion_list_filtered ) From dbe427012ca0b3dfa025cc3da5ab5a01f9f2d8d7 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 15 Feb 2023 19:44:08 +0100 Subject: [PATCH 129/176] add format the whitelist should have --- docs/usage.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/usage.md b/docs/usage.md index a2c9da61..27a6f557 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -135,6 +135,13 @@ nextflow run nf-core/rnafusion \ --whitelist ``` +The custom fusion file should have the following format: + +``` +GENE1--GENE2 +GENE3--GENE4 +``` + #### Running FusionInspector only FusionInspector can be run standalone with: From db94c37ee6bf223099ad4ebfd173b232ed5f84c7 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 15 Feb 2023 19:47:25 +0100 Subject: [PATCH 130/176] prettier --- docs/usage.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 7b55c19b..e24a974b 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -129,29 +129,29 @@ nextflow run nf-core/rnafusion \ There are 2 options to trim 1. fastp - In this case all tools use the trimmed reads. Quality and adapter trimming by default. In addition, tail trimming and adapter_fastq specification are possible. Example usage: + In this case all tools use the trimmed reads. Quality and adapter trimming by default. In addition, tail trimming and adapter_fastq specification are possible. Example usage: - ```bash +```bash nextflow run nf-core/rnafusion \ - -- -- ... \ - --input \ - --genomes_base \ - --outdir \ - --fastp_trim \ - --trim_tail (optional) \ - --adapter_fastq (optional) +-- -- ... \ +--input \ +--genomes_base \ +--outdir \ +--fastp_trim \ +--trim_tail (optional) \ +--adapter_fastq (optional) ``` 2. hard trimming - In this case, only reads fed to fusioncatcher are trimmed. This is a harsh workaround in case of high read-through. The recommended trimming is thus the fastp_trim one. The trimming is done at 75 bp from the tails. Example usage: + In this case, only reads fed to fusioncatcher are trimmed. This is a harsh workaround in case of high read-through. The recommended trimming is thus the fastp_trim one. The trimming is done at 75 bp from the tails. Example usage: - ```bash +````bash nextflow run nf-core/rnafusion \ - -- -- ... \ - --input \ - --genomes_base \ - --outdir \ - --trim +-- -- ... \ +--input \ +--genomes_base \ +--outdir \ +--trim `` @@ -161,11 +161,11 @@ FusionInspector can be run standalone with: ```bash nextflow run nf-core/rnafusion \ - --fusioninspector_only \ - --fusioninspector_fusions \ - --input \ - --outdir -``` +--fusioninspector_only \ +--fusioninspector_fusions \ +--input \ +--outdir +```` The custom fusion file should have the following format: From 5e21e48697d4c60a56b12c87044e0670d51d40f1 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 21 Feb 2023 14:07:22 +0100 Subject: [PATCH 131/176] add csv output to fusionreport --- CHANGELOG.md | 1 + conf/modules.config | 1 + modules/local/fusionreport/detect/main.nf | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 427a33f7..85ee6e1d 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 - stubs to all local modules - `--stringtie` option added with StringTie v2.2.1 to detect splicing events. Not included in `fusion-report` or `fusionInspector` summaries. Included in the `--all` workflow - generation of ribosomal RNA interval list with build_references and use it in picard CollectRnaMetrics +- add csv output to fusionreport ### Changed diff --git a/conf/modules.config b/conf/modules.config index 68f92c02..b075631b 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -86,6 +86,7 @@ process { withName: FUSIONREPORT { ext.when = { !params.skip_vis } + ext.args = "--export csv" publishDir = [ path: { "${params.outdir}/fusionreport/${meta.id}" }, mode: params.publish_dir_mode, diff --git a/modules/local/fusionreport/detect/main.nf b/modules/local/fusionreport/detect/main.nf index 12090a03..c5e6f838 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/local/fusionreport/detect/main.nf @@ -16,11 +16,13 @@ process FUSIONREPORT { tuple val(meta), path("*fusionreport.tsv") , emit: fusion_list tuple val(meta), path("*fusionreport_filtered.tsv") , emit: fusion_list_filtered tuple val(meta), path("*.html") , emit: report + tuple val(meta), path("*.csv") , emit: csv when: task.ext.when == null || task.ext.when script: + def args = task.ext.args ?: '' def tools = params.arriba || params.all ? "--arriba ${arriba_fusions} " : '' tools += params.pizzly || params.all ? "--pizzly ${pizzly_fusions} " : '' tools += params.squid || params.all ? "--squid ${squid_fusions} " : '' @@ -28,7 +30,7 @@ process FUSIONREPORT { tools += params.fusioncatcher || params.all ? "--fusioncatcher ${fusioncatcher_fusions} " : '' def prefix = task.ext.prefix ?: "${meta.id}" """ - fusion_report run $meta.id . $fusionreport_ref $tools --allow-multiple-gene-symbols + fusion_report run $meta.id . $fusionreport_ref $tools --allow-multiple-gene-symbols $args mv fusion_list.tsv ${prefix}.fusionreport.tsv mv fusion_list_filtered.tsv ${prefix}.fusionreport_filtered.tsv From 3e5a86d41d575cb88561622682cbb49c2d13142e Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 21 Feb 2023 14:46:25 +0100 Subject: [PATCH 132/176] add stub --- modules/local/fusionreport/detect/main.nf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/local/fusionreport/detect/main.nf b/modules/local/fusionreport/detect/main.nf index c5e6f838..ddf909c6 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/local/fusionreport/detect/main.nf @@ -34,6 +34,7 @@ process FUSIONREPORT { mv fusion_list.tsv ${prefix}.fusionreport.tsv mv fusion_list_filtered.tsv ${prefix}.fusionreport_filtered.tsv + mv fusions.csv ${prefix}.fusions.csv cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -48,6 +49,7 @@ process FUSIONREPORT { touch ${prefix}.fusionreport_filtered.tsv touch ${prefix}.fusionreport.tsv touch index.html + touch ${prefix}.fusions.csv cat <<-END_VERSIONS > versions.yml "${task.process}": fusion_report: \$(fusion_report --version | sed 's/fusion-report //') From 743558bfaf3a91dcc0b034b8df9ff523e2ee8fea Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 21 Feb 2023 14:51:53 +0100 Subject: [PATCH 133/176] clean up merging properly --- modules/local/fusionreport/detect/main.nf | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/local/fusionreport/detect/main.nf b/modules/local/fusionreport/detect/main.nf index 719567b1..be8befa9 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/local/fusionreport/detect/main.nf @@ -54,7 +54,6 @@ process FUSIONREPORT { touch ${prefix}.fusions.csv touch ${prefix}.fusions.json ->>>>>>> 3a374daf082dc20936b6d35fadb2f40072f7ae60 cat <<-END_VERSIONS > versions.yml "${task.process}": fusion_report: \$(fusion_report --version | sed 's/fusion-report //') From 9e9c9e6d5d0fcf855e83d8bf13907a3462c8aea9 Mon Sep 17 00:00:00 2001 From: rannick Date: Tue, 28 Feb 2023 14:47:04 +0100 Subject: [PATCH 134/176] add memory for star download --- conf/modules.config | 5 +++++ modules/local/starfusion/build/main.nf | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/conf/modules.config b/conf/modules.config index 49960cee..8695b06d 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -330,4 +330,9 @@ process { saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } + + withName: STAR_GENOMEGENERATE { + memory = "8343904778" + } + } diff --git a/modules/local/starfusion/build/main.nf b/modules/local/starfusion/build/main.nf index cf6f9d76..bf4b6a26 100644 --- a/modules/local/starfusion/build/main.nf +++ b/modules/local/starfusion/build/main.nf @@ -12,7 +12,7 @@ process STARFUSION_BUILD { path "*" , emit: reference script: - def binPath = ( workflow.conda.enabled = true ? "prep_genome_lib.pl" : "/usr/local/src/STAR-Fusion/ctat-genome-lib-builder/prep_genome_lib.pl" ) + def binPath = "/usr/local/src/STAR-Fusion/ctat-genome-lib-builder/prep_genome_lib.pl" """ export TMPDIR=/tmp wget http://ftp.ebi.ac.uk/pub/databases/Pfam/releases/Pfam34.0/Pfam-A.hmm.gz --no-check-certificate From 8d9a26e43897b460bb587dfd449d7b900a8cc6bc Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 28 Feb 2023 15:03:17 +0100 Subject: [PATCH 135/176] rearrange --- conf/modules.config | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 8695b06d..87c15158 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -294,6 +294,7 @@ process { withName: STAR_GENOMEGENERATE { ext.args = "--sjdbOverhang ${params.read_length - 1}" + memory = "8343904778" publishDir = [ path: { "${params.genomes_base}" }, mode: params.publish_dir_mode, @@ -330,9 +331,4 @@ process { saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } - - withName: STAR_GENOMEGENERATE { - memory = "8343904778" - } - } From 81900dff50f195ba5e917d2c40dc5904ec7e8b34 Mon Sep 17 00:00:00 2001 From: rannick Date: Tue, 28 Feb 2023 16:24:54 +0100 Subject: [PATCH 136/176] fix check for conda condition --- modules/local/starfusion/build/main.nf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/local/starfusion/build/main.nf b/modules/local/starfusion/build/main.nf index bf4b6a26..f891d149 100644 --- a/modules/local/starfusion/build/main.nf +++ b/modules/local/starfusion/build/main.nf @@ -12,7 +12,9 @@ process STARFUSION_BUILD { path "*" , emit: reference script: - def binPath = "/usr/local/src/STAR-Fusion/ctat-genome-lib-builder/prep_genome_lib.pl" + def binPath = (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) ? "prep_genome_lib.pl" : "/usr/local/src/STAR-Fusion/ctat-genome-lib-builder/prep_genome_lib.pl" + + """ export TMPDIR=/tmp wget http://ftp.ebi.ac.uk/pub/databases/Pfam/releases/Pfam34.0/Pfam-A.hmm.gz --no-check-certificate From 42be2be908fa8bc0b1ceb2bb9c5537ca98bb6131 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 28 Feb 2023 16:26:51 +0100 Subject: [PATCH 137/176] prettier --- modules/local/starfusion/build/main.nf | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/local/starfusion/build/main.nf b/modules/local/starfusion/build/main.nf index f891d149..da5b0c3b 100644 --- a/modules/local/starfusion/build/main.nf +++ b/modules/local/starfusion/build/main.nf @@ -13,8 +13,6 @@ process STARFUSION_BUILD { script: def binPath = (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) ? "prep_genome_lib.pl" : "/usr/local/src/STAR-Fusion/ctat-genome-lib-builder/prep_genome_lib.pl" - - """ export TMPDIR=/tmp wget http://ftp.ebi.ac.uk/pub/databases/Pfam/releases/Pfam34.0/Pfam-A.hmm.gz --no-check-certificate From ab478f00d77b9aac2f391746a17e85dd9dcdd2f5 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 28 Feb 2023 16:38:59 +0100 Subject: [PATCH 138/176] limit memory to max memory in STAR_GENOMEGENERATE --- conf/modules.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/modules.config b/conf/modules.config index 87c15158..8b79b621 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -294,7 +294,7 @@ process { withName: STAR_GENOMEGENERATE { ext.args = "--sjdbOverhang ${params.read_length - 1}" - memory = "8343904778" + memory = { check_min(max_memory, 8343904778) } publishDir = [ path: { "${params.genomes_base}" }, mode: params.publish_dir_mode, From 0e918d3374719cae826cf0d5fc5a823fa81cf7ee Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 28 Feb 2023 16:41:11 +0100 Subject: [PATCH 139/176] limit memory to max memory in STAR_GENOMEGENERATE --- conf/modules.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/modules.config b/conf/modules.config index 64b7eb6f..0db96774 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -295,7 +295,7 @@ process { withName: STAR_GENOMEGENERATE { ext.args = "--sjdbOverhang ${params.read_length - 1}" - memory = { check_min(max_memory, 8343904778) } + memory = { check_max(max_memory, 8343904778) } publishDir = [ path: { "${params.genomes_base}" }, mode: params.publish_dir_mode, From b137799d6d13058564aa31f0f3ab8c713148927d Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Tue, 28 Feb 2023 16:46:20 +0100 Subject: [PATCH 140/176] add json and csv as optional output --- modules/local/fusionreport/detect/main.nf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/local/fusionreport/detect/main.nf b/modules/local/fusionreport/detect/main.nf index be8befa9..2bea2bad 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/local/fusionreport/detect/main.nf @@ -12,12 +12,12 @@ process FUSIONREPORT { path(fusionreport_ref) output: - path "versions.yml" , emit: versions - tuple val(meta), path("*fusionreport.tsv") , emit: fusion_list - tuple val(meta), path("*fusionreport_filtered.tsv") , emit: fusion_list_filtered - tuple val(meta), path("*.html") , emit: report - tuple val(meta), path("*.csv") , emit: csv - tuple val(meta), path("*.json") , emit: json + path "versions.yml" , emit: versions + tuple val(meta), path("*fusionreport.tsv") , emit: fusion_list + tuple val(meta), path("*fusionreport_filtered.tsv") , emit: fusion_list_filtered + tuple val(meta), path("*.html") , emit: report + tuple val(meta), path("*.csv") , optional:true, emit: csv + tuple val(meta), path("*.json") , optional:true, emit: json when: task.ext.when == null || task.ext.when From 15904d90269350c2259549b9ab26b0459082ed9a Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 1 Mar 2023 17:53:04 +0100 Subject: [PATCH 141/176] add cram compression --- conf/modules.config | 32 +++++++++++++++++++ nextflow.config | 3 ++ nextflow_schema.json | 16 ++++++++++ subworkflows/local/arriba_workflow.nf | 10 +++++- .../local/fusioninspector_workflow.nf | 2 ++ subworkflows/local/squid_workflow.nf | 16 ++++++---- subworkflows/local/starfusion_workflow.nf | 9 ++++-- workflows/rnafusion.nf | 3 +- 8 files changed, 81 insertions(+), 10 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 776fc911..f6f09ab1 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -219,6 +219,38 @@ process { withName: SAMTOOLS_VIEW_FOR_SQUID { ext.args = { "-Sb -o ${meta.id}_chimeric.bam" } + publishDir = [ + path: { "${params.outdir}/samtools_view_for_squid" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + + withName: SAMTOOLS_VIEW_FOR_SQUID_CRAM { + ext.args = { "--output-fmt cram" } + publishDir = [ + path: { "${params.outdir}/cram_squid" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + + withName: SAMTOOLS_VIEW_FOR_ARRIBA { + ext.args = { "--output-fmt cram" } + publishDir = [ + path: { "${params.outdir}/cram_arriba" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + + withName: SAMTOOLS_VIEW_FOR_STARFUSION { + ext.args = { "--output-fmt cram" } + publishDir = [ + path: { "${params.outdir}/cram_starfusion" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] } withName: STAR_FOR_ARRIBA { diff --git a/nextflow.config b/nextflow.config index d8c177fa..86a541f5 100644 --- a/nextflow.config +++ b/nextflow.config @@ -45,6 +45,9 @@ params { trim_tail = null adapter_fasta = [] + // Compression + cram = [] + // Alignment options star_ignore_sjdbgtf = false seq_center = null diff --git a/nextflow_schema.json b/nextflow_schema.json index 796f0e75..d08aca6d 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -274,6 +274,19 @@ } } }, + "compression_options": { + "title": "Alignment compression options", + "type": "object", + "fa_icon": "fas fa-cut", + "description": "Option to compress BAM files to CRAM.", + "properties": { + "cram": { + "type": "string", + "description": "List of tools for which to compress BAM file to CRAM,default: []", + "fa_icon": "fas fa-cut" + } + } + }, "reference_genome_options": { "title": "Reference genome options", "type": "object", @@ -576,6 +589,9 @@ { "$ref": "#/definitions/read_trimming_options" }, + { + "$ref": "#/definitions/compression_options" + }, { "$ref": "#/definitions/reference_genome_options" }, diff --git a/subworkflows/local/arriba_workflow.nf b/subworkflows/local/arriba_workflow.nf index 9c4db9da..3ba5076f 100644 --- a/subworkflows/local/arriba_workflow.nf +++ b/subworkflows/local/arriba_workflow.nf @@ -3,7 +3,7 @@ include { ARRIBA_VISUALISATION } from '../../modules/loca include { SAMTOOLS_SORT as SAMTOOLS_SORT_FOR_ARRIBA } from '../../modules/nf-core/samtools/sort/main' include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_ARRIBA} from '../../modules/nf-core/samtools/index/main' include { STAR_ALIGN as STAR_FOR_ARRIBA } from '../../modules/nf-core/star/align/main' - +include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_ARRIBA} from '../../modules/nf-core/samtools/view/main' workflow ARRIBA_WORKFLOW { take: @@ -47,6 +47,14 @@ workflow ARRIBA_WORKFLOW { ch_arriba_visualisation = ARRIBA_VISUALISATION.out.pdf + if ("arriba" in params.cram ){ + SAMTOOLS_VIEW_FOR_ARRIBA(bam_indexed, ch_fasta, []) + ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_ARRIBA.out.versions ) + + } + + + } else { ch_arriba_fusions = reads.combine(Channel.value( file(ch_dummy_file, checkIfExists:true ) ) ) diff --git a/subworkflows/local/fusioninspector_workflow.nf b/subworkflows/local/fusioninspector_workflow.nf index 944f0daf..c714b993 100644 --- a/subworkflows/local/fusioninspector_workflow.nf +++ b/subworkflows/local/fusioninspector_workflow.nf @@ -27,6 +27,8 @@ workflow FUSIONINSPECTOR_WORKFLOW { FUSIONINSPECTOR( reads_fusion, index) ch_versions = ch_versions.mix(FUSIONINSPECTOR.out.versions) + + emit: versions = ch_versions.ifEmpty(null) } diff --git a/subworkflows/local/squid_workflow.nf b/subworkflows/local/squid_workflow.nf index 1e08c916..5ff15983 100644 --- a/subworkflows/local/squid_workflow.nf +++ b/subworkflows/local/squid_workflow.nf @@ -1,9 +1,9 @@ -include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_SQUID} from '../../modules/nf-core/samtools/index/main' -include { SAMTOOLS_SORT as SAMTOOLS_SORT_FOR_SQUID } from '../../modules/nf-core/samtools/sort/main' -include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_SQUID } from '../../modules/nf-core/samtools/view/main' -include { SQUID } from '../../modules/local/squid/detect/main' -include { SQUID_ANNOTATE } from '../../modules/local/squid/annotate/main' -include { STAR_ALIGN as STAR_FOR_SQUID } from '../../modules/nf-core/star/align/main' +include { SAMTOOLS_SORT as SAMTOOLS_SORT_FOR_SQUID } from '../../modules/nf-core/samtools/sort/main' +include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_SQUID } from '../../modules/nf-core/samtools/view/main' +include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_SQUID_CRAM } from '../../modules/nf-core/samtools/view/main' +include { SQUID } from '../../modules/local/squid/detect/main' +include { SQUID_ANNOTATE } from '../../modules/local/squid/annotate/main' +include { STAR_ALIGN as STAR_FOR_SQUID } from '../../modules/nf-core/star/align/main' workflow SQUID_WORKFLOW { @@ -34,6 +34,10 @@ workflow SQUID_WORKFLOW { SAMTOOLS_VIEW_FOR_SQUID ( sam_indexed, ch_fasta, [] ) ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_SQUID.out.versions ) + SAMTOOLS_VIEW_FOR_SQUID_CRAM ( sam_indexed, ch_fasta, [] ) + ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_SQUID_CRAM.out.versions ) + + SAMTOOLS_SORT_FOR_SQUID ( SAMTOOLS_VIEW_FOR_SQUID.out.bam ) ch_versions = ch_versions.mix(SAMTOOLS_SORT_FOR_SQUID.out.versions ) diff --git a/subworkflows/local/starfusion_workflow.nf b/subworkflows/local/starfusion_workflow.nf index 719040fa..2c8d5540 100644 --- a/subworkflows/local/starfusion_workflow.nf +++ b/subworkflows/local/starfusion_workflow.nf @@ -1,11 +1,13 @@ -include { STAR_ALIGN as STAR_FOR_STARFUSION } from '../../modules/nf-core/star/align/main' -include { STARFUSION } from '../../modules/local/starfusion/detect/main' +include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_STARFUSION } from '../../modules/nf-core/samtools/view/main' +include { STAR_ALIGN as STAR_FOR_STARFUSION } from '../../modules/nf-core/star/align/main' +include { STARFUSION } from '../../modules/local/starfusion/detect/main' workflow STARFUSION_WORKFLOW { take: reads ch_chrgtf ch_starindex_ref + ch_fasta main: ch_versions = Channel.empty() @@ -21,6 +23,9 @@ workflow STARFUSION_WORKFLOW { ch_versions = ch_versions.mix(STAR_FOR_STARFUSION.out.versions) ch_align = STAR_FOR_STARFUSION.out.bam_sorted + SAMTOOLS_VIEW_FOR_STARFUSION ( ch_align, ch_fasta, [] ) + ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_STARFUSION.out.versions) + reads_junction = reads.join(STAR_FOR_STARFUSION.out.junction ) STARFUSION( reads_junction, params.starfusion_ref) diff --git a/workflows/rnafusion.nf b/workflows/rnafusion.nf index d79f864c..bf521135 100644 --- a/workflows/rnafusion.nf +++ b/workflows/rnafusion.nf @@ -189,7 +189,8 @@ workflow RNAFUSION { STARFUSION_WORKFLOW ( ch_reads_all, ch_chrgtf, - ch_starindex_ref + ch_starindex_ref, + ch_fasta ) ch_versions = ch_versions.mix(STARFUSION_WORKFLOW.out.versions.first().ifEmpty(null)) From 9ed3d8a56a92a18c471082f997160e64c8f14b0e Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 1 Mar 2023 20:22:20 +0100 Subject: [PATCH 142/176] fix logic --- CHANGELOG.md | 1 + conf/modules.config | 20 ++++++++++---------- docs/usage.md | 7 +++++++ nextflow_schema.json | 2 +- subworkflows/local/arriba_workflow.nf | 2 +- subworkflows/local/squid_workflow.nf | 7 ++++--- subworkflows/local/starfusion_workflow.nf | 17 +++++++++++------ 7 files changed, 35 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ccb734e..faa6501f 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 - add csv output to fusionreport - trimming workflow using `fastp`: use trimmed reads for all tools - `whitelist` parameter to add custom fusions to the detected ones and consider the whole for the `fusionInspector` analysis +- Compression to CRAM files for arriba, squid and starfusion workflows (fusioncatcher and pizzly do not produce SAM/BAM files, fusioninspector BAM files are too small to benefit from compression) ### Changed diff --git a/conf/modules.config b/conf/modules.config index f6f09ab1..90651f5a 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -183,9 +183,9 @@ process { ] } - withName: SAMTOOLS_INDEX_FOR_SQUID { + withName: SAMTOOLS_INDEX_FOR_STARFUSION { publishDir = [ - path: { "${params.outdir}/samtools_index_for_squid" }, + path: { "${params.outdir}/samtools_index_for_starfusion" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] @@ -217,28 +217,28 @@ process { ] } - withName: SAMTOOLS_VIEW_FOR_SQUID { - ext.args = { "-Sb -o ${meta.id}_chimeric.bam" } + withName: SAMTOOLS_VIEW_FOR_ARRIBA { + ext.args = { "--output-fmt cram" } publishDir = [ - path: { "${params.outdir}/samtools_view_for_squid" }, + path: { "${params.outdir}/cram_arriba" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } - withName: SAMTOOLS_VIEW_FOR_SQUID_CRAM { - ext.args = { "--output-fmt cram" } + withName: SAMTOOLS_VIEW_FOR_SQUID { + ext.args = { "-Sb -o ${meta.id}_chimeric.bam" } publishDir = [ - path: { "${params.outdir}/cram_squid" }, + path: { "${params.outdir}/samtools_view_for_squid" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } - withName: SAMTOOLS_VIEW_FOR_ARRIBA { + withName: SAMTOOLS_VIEW_FOR_SQUID_CRAM { ext.args = { "--output-fmt cram" } publishDir = [ - path: { "${params.outdir}/cram_arriba" }, + path: { "${params.outdir}/cram_squid" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] diff --git a/docs/usage.md b/docs/usage.md index aed9e0cd..6cccf5b4 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -263,6 +263,13 @@ When you run the above command, Nextflow automatically pulls the pipeline code f nextflow pull nf-core/rnafusion ``` +#### Compress to CRAM file + +Use the parameter `--cram` to compress the BAM files to CRAM for specific tools. Options: arriba, squid, starfusion. Leave no space between options: + +- `--cram arriba,squid,starfusion`, default: [] +- `--cram arriba` + ### Reproducibility It is a good idea to specify a pipeline version when running the pipeline on your data. This ensures that a specific version of the pipeline code and software are used when you run your pipeline. If you keep using the same tag, you'll be running the same version of the pipeline, even if there have been changes to the code since. diff --git a/nextflow_schema.json b/nextflow_schema.json index d08aca6d..cba5d934 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -282,7 +282,7 @@ "properties": { "cram": { "type": "string", - "description": "List of tools for which to compress BAM file to CRAM,default: []", + "description": "List of tools for which to compress BAM file to CRAM,default: [], options: arriba, squid, starfusion. Leave no space between options", "fa_icon": "fas fa-cut" } } diff --git a/subworkflows/local/arriba_workflow.nf b/subworkflows/local/arriba_workflow.nf index 3ba5076f..e3c6e87a 100644 --- a/subworkflows/local/arriba_workflow.nf +++ b/subworkflows/local/arriba_workflow.nf @@ -47,7 +47,7 @@ workflow ARRIBA_WORKFLOW { ch_arriba_visualisation = ARRIBA_VISUALISATION.out.pdf - if ("arriba" in params.cram ){ + if (params.cram.contains('arriba') ){ SAMTOOLS_VIEW_FOR_ARRIBA(bam_indexed, ch_fasta, []) ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_ARRIBA.out.versions ) diff --git a/subworkflows/local/squid_workflow.nf b/subworkflows/local/squid_workflow.nf index 5ff15983..c5f9d059 100644 --- a/subworkflows/local/squid_workflow.nf +++ b/subworkflows/local/squid_workflow.nf @@ -34,9 +34,10 @@ workflow SQUID_WORKFLOW { SAMTOOLS_VIEW_FOR_SQUID ( sam_indexed, ch_fasta, [] ) ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_SQUID.out.versions ) - SAMTOOLS_VIEW_FOR_SQUID_CRAM ( sam_indexed, ch_fasta, [] ) - ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_SQUID_CRAM.out.versions ) - + if (params.cram.contains('squid')){ + SAMTOOLS_VIEW_FOR_SQUID_CRAM ( sam_indexed, ch_fasta, [] ) + ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_SQUID_CRAM.out.versions ) + } SAMTOOLS_SORT_FOR_SQUID ( SAMTOOLS_VIEW_FOR_SQUID.out.bam ) ch_versions = ch_versions.mix(SAMTOOLS_SORT_FOR_SQUID.out.versions ) diff --git a/subworkflows/local/starfusion_workflow.nf b/subworkflows/local/starfusion_workflow.nf index 2c8d5540..1849d7e1 100644 --- a/subworkflows/local/starfusion_workflow.nf +++ b/subworkflows/local/starfusion_workflow.nf @@ -1,6 +1,7 @@ -include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_STARFUSION } from '../../modules/nf-core/samtools/view/main' -include { STAR_ALIGN as STAR_FOR_STARFUSION } from '../../modules/nf-core/star/align/main' -include { STARFUSION } from '../../modules/local/starfusion/detect/main' +include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_STARFUSION } from '../../modules/nf-core/samtools/view/main' +include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_STARFUSION } from '../../modules/nf-core/samtools/index/main' +include { STAR_ALIGN as STAR_FOR_STARFUSION } from '../../modules/nf-core/star/align/main' +include { STARFUSION } from '../../modules/local/starfusion/detect/main' workflow STARFUSION_WORKFLOW { take: @@ -23,9 +24,13 @@ workflow STARFUSION_WORKFLOW { ch_versions = ch_versions.mix(STAR_FOR_STARFUSION.out.versions) ch_align = STAR_FOR_STARFUSION.out.bam_sorted - SAMTOOLS_VIEW_FOR_STARFUSION ( ch_align, ch_fasta, [] ) - ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_STARFUSION.out.versions) - + if (params.cram.contains('starfusion')){ + SAMTOOLS_INDEX_FOR_STARFUSION(STAR_FOR_STARFUSION.out.bam_sorted) + ch_versions = ch_versions.mix(SAMTOOLS_INDEX_FOR_STARFUSION.out.versions) + bam_sorted_indexed = STAR_FOR_STARFUSION.out.bam_sorted.join(SAMTOOLS_INDEX_FOR_STARFUSION.out.bai) + SAMTOOLS_VIEW_FOR_STARFUSION (bam_sorted_indexed, ch_fasta, [] ) + ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_STARFUSION.out.versions) + } reads_junction = reads.join(STAR_FOR_STARFUSION.out.junction ) STARFUSION( reads_junction, params.starfusion_ref) From d4267c9e50c884dc5cf69f170616f8ec777762e1 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 1 Mar 2023 20:37:36 +0100 Subject: [PATCH 143/176] add qiagen option --- conf/modules.config | 1 + modules/local/fusionreport/detect/main.nf | 3 ++- modules/local/fusionreport/download/main.nf | 3 ++- nextflow.config | 2 +- nextflow_schema.json | 5 +++++ 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 0db96774..d61e51d7 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -99,6 +99,7 @@ process { } withName: FUSIONREPORT_DOWNLOAD { + ext.args = { params.qiagen ? "--qiagen" : "" } publishDir = [ path: { "${params.genomes_base}/fusion_report_db" }, mode: params.publish_dir_mode, diff --git a/modules/local/fusionreport/detect/main.nf b/modules/local/fusionreport/detect/main.nf index 2bea2bad..06251b4f 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/local/fusionreport/detect/main.nf @@ -24,6 +24,7 @@ process FUSIONREPORT { script: def args = task.ext.args ?: '' + def args2 = task.ext.args2 ?: '' def tools = params.arriba || params.all ? "--arriba ${arriba_fusions} " : '' tools += params.pizzly || params.all ? "--pizzly ${pizzly_fusions} " : '' tools += params.squid || params.all ? "--squid ${squid_fusions} " : '' @@ -31,7 +32,7 @@ process FUSIONREPORT { tools += params.fusioncatcher || params.all ? "--fusioncatcher ${fusioncatcher_fusions} " : '' def prefix = task.ext.prefix ?: "${meta.id}" """ - fusion_report run $meta.id . $fusionreport_ref $tools --allow-multiple-gene-symbols $args + fusion_report run $meta.id . $fusionreport_ref $tools --allow-multiple-gene-symbols $args $args2 mv fusion_list.tsv ${prefix}.fusionreport.tsv mv fusion_list_filtered.tsv ${prefix}.fusionreport_filtered.tsv diff --git a/modules/local/fusionreport/download/main.nf b/modules/local/fusionreport/download/main.nf index 5f42214a..23272290 100644 --- a/modules/local/fusionreport/download/main.nf +++ b/modules/local/fusionreport/download/main.nf @@ -17,8 +17,9 @@ process FUSIONREPORT_DOWNLOAD { path "versions.yml" , emit: versions script: + def args = task.ext.args ?: '' """ - fusion_report download --cosmic_usr $username --cosmic_passwd $passwd . + fusion_report download --cosmic_usr $username --cosmic_passwd $passwd $args . cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/nextflow.config b/nextflow.config index d8c177fa..509c713f 100644 --- a/nextflow.config +++ b/nextflow.config @@ -14,7 +14,7 @@ params { build_references = false cosmic_username = null cosmic_passwd = null - + qiagen = null // References genome = null diff --git a/nextflow_schema.json b/nextflow_schema.json index 796f0e75..4d115135 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -243,6 +243,11 @@ "type": "string", "fa_icon": "far fa-file-code", "description": "COSMIC password" + }, + "qiagen": { + "type": "string", + "fa_icon": "far fa-file-code", + "description": "Use QIAGEN instead of SANGER to download COSMIC database" } } }, From 1f7516134ce405d9a1369b5b4092c14bee39fd68 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Wed, 1 Mar 2023 20:42:03 +0100 Subject: [PATCH 144/176] add docs --- CHANGELOG.md | 1 + docs/usage.md | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ccb734e..f020f821 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 - add csv output to fusionreport - trimming workflow using `fastp`: use trimmed reads for all tools - `whitelist` parameter to add custom fusions to the detected ones and consider the whole for the `fusionInspector` analysis +- `--qiagen` option to download from QIAGEN instead of COSMIC (use QIAGEN user and password for `cosmic_username` and `cosmic_passwd`) ### Changed diff --git a/docs/usage.md b/docs/usage.md index aed9e0cd..1b082bd9 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -48,6 +48,16 @@ nextflow run nf-core/rnafusion \ --outdir ``` +#### Using QIAGEN download insead of SANGER (non-academic usage) for the COSMIC database + +```bash +nextflow run nf-core/rnafusion \ + --build_references -- -- ... \ + --cosmic_username --cosmic_passwd \ + --genomes_base \ + --outdir --qiagen +``` + #### References directory tree ```text From ee29d3d86d26cfc8306db1ce0646cd13e2943df8 Mon Sep 17 00:00:00 2001 From: Alexander Peltzer Date: Thu, 2 Mar 2023 14:19:50 +0000 Subject: [PATCH 145/176] Add different type so that linting doesn't fail --- nextflow.config | 2 +- nextflow_schema.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nextflow.config b/nextflow.config index 999da1a1..8e9d5bde 100644 --- a/nextflow.config +++ b/nextflow.config @@ -14,7 +14,7 @@ params { build_references = false cosmic_username = null cosmic_passwd = null - qiagen = null + qiagen = false // References genome = null diff --git a/nextflow_schema.json b/nextflow_schema.json index e25ad11d..bb6c4d95 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -245,7 +245,7 @@ "description": "COSMIC password" }, "qiagen": { - "type": "string", + "type": "boolean", "fa_icon": "far fa-file-code", "description": "Use QIAGEN instead of SANGER to download COSMIC database" } From 3d4f7ebc31620ee18d5f1c1fc35a17af4e9a188e Mon Sep 17 00:00:00 2001 From: Alexander Peltzer Date: Fri, 3 Mar 2023 08:27:21 +0000 Subject: [PATCH 146/176] Update to latest docker image with qiagen changes --- modules/local/fusionreport/detect/main.nf | 2 +- modules/local/fusionreport/download/main.nf | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/local/fusionreport/detect/main.nf b/modules/local/fusionreport/detect/main.nf index 06251b4f..ce9793c1 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/local/fusionreport/detect/main.nf @@ -4,7 +4,7 @@ process FUSIONREPORT { // Note: 2.7X indices incompatible with AWS iGenomes. conda "bioconda::star=2.7.9a" - container "docker.io/clinicalgenomics/fusion-report:2.1.5patched" + container "docker.io/clinicalgenomics/fusion-report:2.1.5p2" input: diff --git a/modules/local/fusionreport/download/main.nf b/modules/local/fusionreport/download/main.nf index 23272290..03108833 100644 --- a/modules/local/fusionreport/download/main.nf +++ b/modules/local/fusionreport/download/main.nf @@ -4,9 +4,7 @@ process FUSIONREPORT_DOWNLOAD { // Note: 2.7X indices incompatible with AWS iGenomes. conda "bioconda::star=2.7.9a" - container "docker.io/clinicalgenomics/fusion-report:2.1.5patched" - - + container "docker.io/clinicalgenomics/fusion-report:2.1.5p2" input: val(username) From 8ef6d98cbe6e1f2cb0cdd7cbf4cf4a8d76ac2859 Mon Sep 17 00:00:00 2001 From: Alexander Peltzer Date: Mon, 6 Mar 2023 15:40:32 +0000 Subject: [PATCH 147/176] Fix downloading cosmic --- modules/local/fusionreport/download/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/fusionreport/download/main.nf b/modules/local/fusionreport/download/main.nf index 03108833..78afeede 100644 --- a/modules/local/fusionreport/download/main.nf +++ b/modules/local/fusionreport/download/main.nf @@ -17,7 +17,7 @@ process FUSIONREPORT_DOWNLOAD { script: def args = task.ext.args ?: '' """ - fusion_report download --cosmic_usr $username --cosmic_passwd $passwd $args . + fusion_report download --cosmic_usr $username --cosmic_passwd $passwd $args ./ cat <<-END_VERSIONS > versions.yml "${task.process}": From 857b15cdc66e5bd6ac4c942977b3b1b1dd795bd6 Mon Sep 17 00:00:00 2001 From: Alexander Peltzer Date: Mon, 6 Mar 2023 15:49:57 +0000 Subject: [PATCH 148/176] Adjust starfusion request --- conf/base.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/conf/base.config b/conf/base.config index 2496946e..581238dc 100644 --- a/conf/base.config +++ b/conf/base.config @@ -54,4 +54,7 @@ process { withName:CUSTOM_DUMPSOFTWAREVERSIONS { cache = false } + withName:STARFUSION_BUILD { + time = { check_max( 24.h * task.attempt, 'time' ) } + } } From 5f08da34374a5d1fbe51623705ab553b6a54fbe5 Mon Sep 17 00:00:00 2001 From: Alexander Peltzer Date: Mon, 6 Mar 2023 15:50:37 +0000 Subject: [PATCH 149/176] Add changelog option --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0b44804..934feda4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `whitelist` parameter to add custom fusions to the detected ones and consider the whole for the `fusionInspector` analysis - Compression to CRAM files for arriba, squid and starfusion workflows (fusioncatcher and pizzly do not produce SAM/BAM files, fusioninspector BAM files are too small to benefit from compression) - `--qiagen` option to download from QIAGEN instead of COSMIC (use QIAGEN user and password for `cosmic_username` and `cosmic_passwd`) +- Bumped `starfusion` time request for building as it was always crashing for most users ### Changed From ef94e047835e5d497c632f8c1d3f77502d314043 Mon Sep 17 00:00:00 2001 From: Alexander Peltzer Date: Mon, 6 Mar 2023 15:52:32 +0000 Subject: [PATCH 150/176] Its been star genome generate --- CHANGELOG.md | 2 +- conf/base.config | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 934feda4..4f994d11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `whitelist` parameter to add custom fusions to the detected ones and consider the whole for the `fusionInspector` analysis - Compression to CRAM files for arriba, squid and starfusion workflows (fusioncatcher and pizzly do not produce SAM/BAM files, fusioninspector BAM files are too small to benefit from compression) - `--qiagen` option to download from QIAGEN instead of COSMIC (use QIAGEN user and password for `cosmic_username` and `cosmic_passwd`) -- Bumped `starfusion` time request for building as it was always crashing for most users +- Bumped `STAR genomegenerate` time request for building as it was always crashing for most users ### Changed diff --git a/conf/base.config b/conf/base.config index 581238dc..a25d6434 100644 --- a/conf/base.config +++ b/conf/base.config @@ -54,7 +54,9 @@ process { withName:CUSTOM_DUMPSOFTWAREVERSIONS { cache = false } - withName:STARFUSION_BUILD { + withName:STAR_GENOMEGENERATE { + cpus = { check_max( 12 * task.attempt, 'cpus' ) } + memory = { check_max( 72.GB * task.attempt, 'memory' ) } time = { check_max( 24.h * task.attempt, 'time' ) } } } From 43843c34271d5766cab9f1b3d5f6f2a48f846dc3 Mon Sep 17 00:00:00 2001 From: Alexander Peltzer Date: Mon, 6 Mar 2023 15:53:20 +0000 Subject: [PATCH 151/176] Lets do both --- conf/base.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/conf/base.config b/conf/base.config index a25d6434..39036f32 100644 --- a/conf/base.config +++ b/conf/base.config @@ -59,4 +59,7 @@ process { memory = { check_max( 72.GB * task.attempt, 'memory' ) } time = { check_max( 24.h * task.attempt, 'time' ) } } + withName:STARFUSION_BUILD { + time = { check_max( 24.h * task.attempt, 'time' ) } + } } From 7fff72d61ced5e67c49df6c6a31600bbe24bf201 Mon Sep 17 00:00:00 2001 From: Alexander Peltzer Date: Mon, 6 Mar 2023 15:55:06 +0000 Subject: [PATCH 152/176] Adjust slightly --- conf/base.config | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/base.config b/conf/base.config index 39036f32..e83773b7 100644 --- a/conf/base.config +++ b/conf/base.config @@ -62,4 +62,5 @@ process { withName:STARFUSION_BUILD { time = { check_max( 24.h * task.attempt, 'time' ) } } + } From 1991dd458748321d1699c807869d82d59a3fc6fb Mon Sep 17 00:00:00 2001 From: Alexander Peltzer Date: Mon, 6 Mar 2023 15:56:27 +0000 Subject: [PATCH 153/176] Adjust config --- conf/base.config | 1 - 1 file changed, 1 deletion(-) diff --git a/conf/base.config b/conf/base.config index e83773b7..39036f32 100644 --- a/conf/base.config +++ b/conf/base.config @@ -62,5 +62,4 @@ process { withName:STARFUSION_BUILD { time = { check_max( 24.h * task.attempt, 'time' ) } } - } From 47db72a164dbe058ddc21a62af5cd0f5263afdd4 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 6 Mar 2023 18:57:26 +0100 Subject: [PATCH 154/176] update arriba references to 2.3.0 --- CHANGELOG.md | 1 + conf/modules.config | 2 -- modules/local/arriba/download/main.nf | 3 +++ modules/local/arriba/visualisation/main.nf | 10 +++++++--- nextflow.config | 2 ++ nextflow_schema.json | 10 ++++++++++ subworkflows/local/arriba_workflow.nf | 4 ++-- 7 files changed, 25 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f994d11..5854e2e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - AWS megatest to display on nf-core website +- `arriba` visualisation references updated to 2.3.0 ### Removed diff --git a/conf/modules.config b/conf/modules.config index 99ae415a..52ef97ca 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -33,8 +33,6 @@ process { mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] - ext.args = "cytobands_hg38_GRCh38_v2.1.0.tsv" - ext.args2 = "protein_domains_hg38_GRCh38_v2.1.0.gff3" } withName: CUSTOM_DUMPSOFTWAREVERSIONS { diff --git a/modules/local/arriba/download/main.nf b/modules/local/arriba/download/main.nf index 44e6cb48..166ed69f 100644 --- a/modules/local/arriba/download/main.nf +++ b/modules/local/arriba/download/main.nf @@ -29,6 +29,9 @@ process ARRIBA_DOWNLOAD { """ touch blacklist_hg38_GRCh38_v2.3.0.tsv.gz touch protein_domains_hg38_GRCh38_v2.3.0.gff3 + touch cytobands_hg38_GRCh38_v2.3.0.tsv + touch known_fusions_hg38_GRCh38_v2.3.0.tsv.gz + touch protein_domains_hg38_GRCh38_v2.3.0.gff3 cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/local/arriba/visualisation/main.nf b/modules/local/arriba/visualisation/main.nf index d31cf9a7..ec23bfb6 100644 --- a/modules/local/arriba/visualisation/main.nf +++ b/modules/local/arriba/visualisation/main.nf @@ -11,6 +11,8 @@ process ARRIBA_VISUALISATION { tuple val(meta), path(bam), path(bai), path(fusions) path reference path gtf + path protein_domains + path cytobands output: tuple val(meta), path("*.pdf") , emit: pdf @@ -21,16 +23,18 @@ process ARRIBA_VISUALISATION { script: def args = task.ext.args ?: '' - def args2 = task.ext.args2 ?: '' + def cytobands = cytobands ? " --cytobands=$cytobands" : "" def prefix = task.ext.prefix ?: "${meta.id}" + def protein_domains = protein_domains ? "-p $protein_domains" : "" """ draw_fusions.R \\ --fusions=$fusions \\ --alignments=$bam \\ --output=${prefix}.pdf \\ --annotation=${gtf} \\ - --cytobands=${reference}/${args} \\ - --proteinDomains=${reference}/${args2} + $cytobands \\ + $protein_domains \\ + $args cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/nextflow.config b/nextflow.config index 8e9d5bde..c27b449f 100644 --- a/nextflow.config +++ b/nextflow.config @@ -75,6 +75,8 @@ params { ensembl_ref = "${params.genomes_base}/ensembl" arriba_ref = "${params.genomes_base}/arriba" arriba_ref_blacklist = "${params.genomes_base}/arriba/blacklist_hg38_GRCh38_v2.3.0.tsv.gz" + arriba_ref_cytobands = "${params.genomes_base}/arriba/cytobands_hg38_GRCh38_v2.3.0.tsv" + arriba_ref_known_fusions = "${params.genomes_base}/arriba/known_fusions_hg38_GRCh38_v2.3.0.tsv.gz" arriba_ref_protein_domain = "${params.genomes_base}/arriba/protein_domains_hg38_GRCh38_v2.3.0.gff3" fusioncatcher_ref = "${params.genomes_base}/fusioncatcher/human_v102" pizzly_ref = "${params.genomes_base}/pizzly/kallisto" diff --git a/nextflow_schema.json b/nextflow_schema.json index bb6c4d95..53a3b122 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -104,6 +104,16 @@ "fa_icon": "far fa-file-code", "description": "Path to arriba reference blacklist" }, + "arriba_ref_cytobands": { + "type": "string", + "fa_icon": "far fa-file-code", + "description": "Path to arriba reference cytobands" + }, + "arriba_ref_known_fusions": { + "type": "string", + "fa_icon": "far fa-file-code", + "description": "Path to arriba reference known fusions" + }, "arriba_ref_protein_domain": { "type": "string", "fa_icon": "far fa-file-code", diff --git a/subworkflows/local/arriba_workflow.nf b/subworkflows/local/arriba_workflow.nf index e3c6e87a..6653974e 100644 --- a/subworkflows/local/arriba_workflow.nf +++ b/subworkflows/local/arriba_workflow.nf @@ -35,14 +35,14 @@ workflow ARRIBA_WORKFLOW { .map { meta, reads, fusions -> [ meta, fusions ] } ch_arriba_fusion_fail = ch_dummy_file } else { - ARRIBA ( STAR_FOR_ARRIBA.out.bam, ch_fasta, ch_gtf, params.arriba_ref_blacklist, [], [], [], params.arriba_ref_protein_domain ) + ARRIBA ( STAR_FOR_ARRIBA.out.bam, ch_fasta, ch_gtf, params.arriba_ref_blacklist, params.arriba_ref_known_fusions, [], [], params.arriba_ref_protein_domain ) ch_versions = ch_versions.mix(ARRIBA.out.versions) ch_arriba_fusions = ARRIBA.out.fusions ch_arriba_fusion_fail = ARRIBA.out.fusions_fail.map{ meta, file -> return file} } bam_indexed_arriba_fusions = bam_indexed.join(ch_arriba_fusions) - ARRIBA_VISUALISATION(bam_indexed_arriba_fusions, params.arriba_ref, ch_gtf) + ARRIBA_VISUALISATION(bam_indexed_arriba_fusions, params.arriba_ref, ch_gtf, params.arriba_ref_protein_domain, params.arriba_ref_cytobands) ch_versions = ch_versions.mix(ARRIBA_VISUALISATION.out.versions) ch_arriba_visualisation = ARRIBA_VISUALISATION.out.pdf From c0411fc6d7c6349a058b7e5f5e01be7dc72d1090 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 6 Mar 2023 18:58:22 +0100 Subject: [PATCH 155/176] update picard --- modules.json | 4 ++-- modules/nf-core/picard/collectwgsmetrics/main.nf | 6 +++--- modules/nf-core/picard/markduplicates/main.nf | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules.json b/modules.json index acfc9208..8e82f544 100644 --- a/modules.json +++ b/modules.json @@ -57,12 +57,12 @@ }, "picard/collectwgsmetrics": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "2f88b26e9804b99e98f7cd08e74c3f88288a3358", "installed_by": ["modules"] }, "picard/markduplicates": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "2f88b26e9804b99e98f7cd08e74c3f88288a3358", "installed_by": ["modules"] }, "qualimap/rnaseq": { diff --git a/modules/nf-core/picard/collectwgsmetrics/main.nf b/modules/nf-core/picard/collectwgsmetrics/main.nf index b767b99c..827dfb23 100644 --- a/modules/nf-core/picard/collectwgsmetrics/main.nf +++ b/modules/nf-core/picard/collectwgsmetrics/main.nf @@ -2,10 +2,10 @@ process PICARD_COLLECTWGSMETRICS { tag "$meta.id" label 'process_single' - conda "bioconda::picard=2.27.4 r::r-base" + conda "bioconda::picard=3.0.0 r::r-base" 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), path(bai) diff --git a/modules/nf-core/picard/markduplicates/main.nf b/modules/nf-core/picard/markduplicates/main.nf index 14800392..be243a95 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) From f6741b2b125fa428fb9d082cd616826d66625824 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 6 Mar 2023 21:03:47 +0100 Subject: [PATCH 156/176] release version bump --- nextflow.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nextflow.config b/nextflow.config index c27b449f..2e2a0ceb 100644 --- a/nextflow.config +++ b/nextflow.config @@ -267,7 +267,7 @@ manifest { description = """Nextflow rnafusion analysis pipeline, part of the nf-core community.""" mainScript = 'main.nf' nextflowVersion = '!>=22.10.1' - version = '2.2.0dev' + version = '2.2.0' doi = '' } From bbb16c3fd2e31acc261e0cead5341f42189da7a2 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 6 Mar 2023 21:06:14 +0100 Subject: [PATCH 157/176] add release date to changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5854e2e0..4438a990 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). -## v2.2.0dev - [date] +## v2.2.0 - [2022/03/06] ### Added From e66160946bb515608d1c6c461a9c9ded14f34c86 Mon Sep 17 00:00:00 2001 From: Alexander Peltzer Date: Tue, 7 Mar 2023 07:44:25 +0000 Subject: [PATCH 158/176] STAR needs a minimum of 32GB --- conf/modules.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/modules.config b/conf/modules.config index 52ef97ca..32051f05 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -326,7 +326,7 @@ process { withName: STAR_GENOMEGENERATE { ext.args = "--sjdbOverhang ${params.read_length - 1}" - memory = { check_max(max_memory, 8343904778) } + memory = { check_max(max_memory, 141733920768) } publishDir = [ path: { "${params.genomes_base}" }, mode: params.publish_dir_mode, From cb0806fdef24bd4dea9b134c28c47ce21dc0b610 Mon Sep 17 00:00:00 2001 From: Alexander Peltzer Date: Tue, 7 Mar 2023 07:58:29 +0000 Subject: [PATCH 159/176] Moved all params to modules.config --- conf/base.config | 8 -------- conf/modules.config | 4 +++- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/conf/base.config b/conf/base.config index 39036f32..2496946e 100644 --- a/conf/base.config +++ b/conf/base.config @@ -54,12 +54,4 @@ process { withName:CUSTOM_DUMPSOFTWAREVERSIONS { cache = false } - withName:STAR_GENOMEGENERATE { - cpus = { check_max( 12 * task.attempt, 'cpus' ) } - memory = { check_max( 72.GB * task.attempt, 'memory' ) } - time = { check_max( 24.h * task.attempt, 'time' ) } - } - withName:STARFUSION_BUILD { - time = { check_max( 24.h * task.attempt, 'time' ) } - } } diff --git a/conf/modules.config b/conf/modules.config index 32051f05..a6e82559 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -326,7 +326,9 @@ process { withName: STAR_GENOMEGENERATE { ext.args = "--sjdbOverhang ${params.read_length - 1}" - memory = { check_max(max_memory, 141733920768) } + cpus = { check_max( 12 * task.attempt, 'cpus' ) } + memory = { check_max( 72.GB * task.attempt, 'memory' ) } + time = { check_max( 24.h * task.attempt, 'time' ) } publishDir = [ path: { "${params.genomes_base}" }, mode: params.publish_dir_mode, From 1db2dde5438644416f6fc92e8b789627cab8984c Mon Sep 17 00:00:00 2001 From: rannick Date: Tue, 7 Mar 2023 16:34:29 +0100 Subject: [PATCH 160/176] add memory to test profile for star genomegenerate --- conf/test.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/test.config b/conf/test.config index 236d1a39..69858eaf 100644 --- a/conf/test.config +++ b/conf/test.config @@ -16,7 +16,7 @@ params { // Limit resources so that this can run on GitHub Actions max_cpus = 2 - max_memory = 6.GB + max_memory = 8.GB max_time = 6.h // Input data From bea27dc6dc854e55a30b877b10a557e244f83b43 Mon Sep 17 00:00:00 2001 From: Alexander Peltzer Date: Thu, 9 Mar 2023 12:44:53 +0000 Subject: [PATCH 161/176] checkMax doesnt work like this --- conf/modules.config | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/conf/modules.config b/conf/modules.config index 52ef97ca..7c6b7f9f 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -326,7 +326,9 @@ process { withName: STAR_GENOMEGENERATE { ext.args = "--sjdbOverhang ${params.read_length - 1}" - memory = { check_max(max_memory, 8343904778) } + cpus = { check_max( 24 * task.attempt, 'cpus' ) } + memory = { check_max( 100.GB * task.attempt, 'memory' ) } + time = { check_max( 2.d * task.attempt, 'time' ) } publishDir = [ path: { "${params.genomes_base}" }, mode: params.publish_dir_mode, From 7bf4fd1ef472991d3a995aea949891388cf8255b Mon Sep 17 00:00:00 2001 From: Alexander Peltzer Date: Thu, 9 Mar 2023 15:19:01 +0000 Subject: [PATCH 162/176] modified to --proteinDomains --- CHANGELOG.md | 1 + modules/local/arriba/visualisation/main.nf | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4438a990..fbde38d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Compression to CRAM files for arriba, squid and starfusion workflows (fusioncatcher and pizzly do not produce SAM/BAM files, fusioninspector BAM files are too small to benefit from compression) - `--qiagen` option to download from QIAGEN instead of COSMIC (use QIAGEN user and password for `cosmic_username` and `cosmic_passwd`) - Bumped `STAR genomegenerate` time request for building as it was always crashing for most users +- Fixed issue with arriba visualisation parameters [#326](https://github.com/nf-core/rnafusion/issues/326) ### Changed diff --git a/modules/local/arriba/visualisation/main.nf b/modules/local/arriba/visualisation/main.nf index ec23bfb6..e8095044 100644 --- a/modules/local/arriba/visualisation/main.nf +++ b/modules/local/arriba/visualisation/main.nf @@ -25,7 +25,7 @@ process ARRIBA_VISUALISATION { def args = task.ext.args ?: '' def cytobands = cytobands ? " --cytobands=$cytobands" : "" def prefix = task.ext.prefix ?: "${meta.id}" - def protein_domains = protein_domains ? "-p $protein_domains" : "" + def protein_domains = protein_domains ? "--proteinDomains $protein_domains" : "" """ draw_fusions.R \\ --fusions=$fusions \\ From f345d1d23791fe7de940cc00fe72604d2645691c Mon Sep 17 00:00:00 2001 From: Alexander Peltzer Date: Thu, 9 Mar 2023 16:29:05 +0100 Subject: [PATCH 163/176] Update main.nf --- modules/local/arriba/visualisation/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/arriba/visualisation/main.nf b/modules/local/arriba/visualisation/main.nf index e8095044..1b5f87c8 100644 --- a/modules/local/arriba/visualisation/main.nf +++ b/modules/local/arriba/visualisation/main.nf @@ -25,7 +25,7 @@ process ARRIBA_VISUALISATION { def args = task.ext.args ?: '' def cytobands = cytobands ? " --cytobands=$cytobands" : "" def prefix = task.ext.prefix ?: "${meta.id}" - def protein_domains = protein_domains ? "--proteinDomains $protein_domains" : "" + def protein_domains = protein_domains ? "--proteinDomains=$protein_domains" : "" """ draw_fusions.R \\ --fusions=$fusions \\ From 4e4683c657cdeee9dd88f6ea7c32162133044038 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Sun, 12 Mar 2023 16:51:54 +0100 Subject: [PATCH 164/176] change SAMTOOLS_VIEW_FOR_SQUID multiple output -o --- conf/modules.config | 12 +++++++++++- subworkflows/local/squid_workflow.nf | 16 +++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 7c6b7f9f..0c26fee9 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -226,7 +226,7 @@ process { } withName: SAMTOOLS_VIEW_FOR_SQUID { - ext.args = { "-Sb -o ${meta.id}_chimeric.bam" } + ext.prefix = { "${meta.id}_chimeric" } publishDir = [ path: { "${params.outdir}/samtools_view_for_squid" }, mode: params.publish_dir_mode, @@ -243,6 +243,16 @@ process { ] } + withName: SAMTOOLS_VIEW_FOR_SQUID_CRAM_CHIMERIC { + ext.args = { "--output-fmt cram" } + ext.prefix = { "${meta.id}_chimeric" } + publishDir = [ + path: { "${params.outdir}/cram_squid" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + withName: SAMTOOLS_VIEW_FOR_STARFUSION { ext.args = { "--output-fmt cram" } publishDir = [ diff --git a/subworkflows/local/squid_workflow.nf b/subworkflows/local/squid_workflow.nf index c5f9d059..abd1ad1d 100644 --- a/subworkflows/local/squid_workflow.nf +++ b/subworkflows/local/squid_workflow.nf @@ -29,21 +29,23 @@ workflow SQUID_WORKFLOW { STAR_FOR_SQUID.out.sam .map { meta, sam -> return [meta, sam, []] - }.set { sam_indexed } + }.set { chimeric_sam_indexed } - SAMTOOLS_VIEW_FOR_SQUID ( sam_indexed, ch_fasta, [] ) + SAMTOOLS_VIEW_FOR_SQUID ( chimeric_sam_indexed, ch_fasta, [] ) ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_SQUID.out.versions ) - if (params.cram.contains('squid')){ - SAMTOOLS_VIEW_FOR_SQUID_CRAM ( sam_indexed, ch_fasta, [] ) - ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_SQUID_CRAM.out.versions ) - } - SAMTOOLS_SORT_FOR_SQUID ( SAMTOOLS_VIEW_FOR_SQUID.out.bam ) ch_versions = ch_versions.mix(SAMTOOLS_SORT_FOR_SQUID.out.versions ) bam_sorted = STAR_FOR_SQUID.out.bam_sorted.join(SAMTOOLS_SORT_FOR_SQUID.out.bam ) + if (params.cram.contains('squid')){ + SAMTOOLS_VIEW_FOR_SQUID_CRAM ( STAR_FOR_SQUID.out.bam_sorted, ch_fasta, [] ) + ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_SQUID_CRAM.out.versions ) + SAMTOOLS_VIEW_FOR_SQUID_CRAM_CHIMERIC ( chimeric_sam_indexed, ch_fasta, [] ) + ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_SQUID_CRAM.out.versions ) + } + SQUID ( bam_sorted ) ch_versions = ch_versions.mix(SQUID.out.versions) From 7dc8f8f89d31ed33db658979e489003e6a6bf647 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Sun, 12 Mar 2023 17:01:57 +0100 Subject: [PATCH 165/176] fix include --- subworkflows/local/squid_workflow.nf | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/subworkflows/local/squid_workflow.nf b/subworkflows/local/squid_workflow.nf index abd1ad1d..2079da61 100644 --- a/subworkflows/local/squid_workflow.nf +++ b/subworkflows/local/squid_workflow.nf @@ -1,9 +1,10 @@ -include { SAMTOOLS_SORT as SAMTOOLS_SORT_FOR_SQUID } from '../../modules/nf-core/samtools/sort/main' -include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_SQUID } from '../../modules/nf-core/samtools/view/main' -include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_SQUID_CRAM } from '../../modules/nf-core/samtools/view/main' -include { SQUID } from '../../modules/local/squid/detect/main' -include { SQUID_ANNOTATE } from '../../modules/local/squid/annotate/main' -include { STAR_ALIGN as STAR_FOR_SQUID } from '../../modules/nf-core/star/align/main' +include { SAMTOOLS_SORT as SAMTOOLS_SORT_FOR_SQUID } from '../../modules/nf-core/samtools/sort/main' +include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_SQUID } from '../../modules/nf-core/samtools/view/main' +include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_SQUID_CRAM } from '../../modules/nf-core/samtools/view/main' +include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_SQUID_CRAM_CHIMERIC } from '../../modules/nf-core/samtools/view/main' +include { SQUID } from '../../modules/local/squid/detect/main' +include { SQUID_ANNOTATE } from '../../modules/local/squid/annotate/main' +include { STAR_ALIGN as STAR_FOR_SQUID } from '../../modules/nf-core/star/align/main' workflow SQUID_WORKFLOW { From 7639cb2d60a1fe75907a50d4ff35c12d71489539 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Sun, 12 Mar 2023 17:25:56 +0100 Subject: [PATCH 166/176] correct output format sam-> bam --- conf/modules.config | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/modules.config b/conf/modules.config index 0c26fee9..69471829 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -227,6 +227,7 @@ process { withName: SAMTOOLS_VIEW_FOR_SQUID { ext.prefix = { "${meta.id}_chimeric" } + ext.args = { "--output-fmt bam" } publishDir = [ path: { "${params.outdir}/samtools_view_for_squid" }, mode: params.publish_dir_mode, From 73192a96c49e8dfa324bf6a16084c1d7e634bc56 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Sun, 12 Mar 2023 17:31:36 +0100 Subject: [PATCH 167/176] update changelog --- CHANGELOG.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbde38d8..0df530f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - exitStatus 140 now part of the retry strategy - stubs to all local modules - `--stringtie` option added with StringTie v2.2.1 to detect splicing events. Not included in `fusion-report` or `fusionInspector` summaries. Included in the `--all` workflow -- generation of ribosomal RNA interval list with build_references and use it in picard CollectRnaMetrics -- add csv output to fusionreport -- trimming workflow using `fastp`: use trimmed reads for all tools +- Generation of ribosomal RNA interval list with build_references and use it in picard CollectRnaMetrics +- Add csv output to fusionreport +- Trimming workflow using `fastp`: use trimmed reads for all tools - `whitelist` parameter to add custom fusions to the detected ones and consider the whole for the `fusionInspector` analysis - Compression to CRAM files for arriba, squid and starfusion workflows (fusioncatcher and pizzly do not produce SAM/BAM files, fusioninspector BAM files are too small to benefit from compression) - `--qiagen` option to download from QIAGEN instead of COSMIC (use QIAGEN user and password for `cosmic_username` and `cosmic_passwd`) @@ -34,6 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - AWS megatest to display on nf-core website - `arriba` visualisation references updated to 2.3.0 +- Removed issue with multiple outputs in samtools view for squid ### Removed From 21ba0e3beceb93ee2500417633275d5f24e23984 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Sun, 12 Mar 2023 18:18:14 +0100 Subject: [PATCH 168/176] update fusionreport --- modules/local/fusionreport/detect/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/fusionreport/detect/main.nf b/modules/local/fusionreport/detect/main.nf index ce9793c1..8e3fbbfa 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/local/fusionreport/detect/main.nf @@ -4,7 +4,7 @@ process FUSIONREPORT { // Note: 2.7X indices incompatible with AWS iGenomes. conda "bioconda::star=2.7.9a" - container "docker.io/clinicalgenomics/fusion-report:2.1.5p2" + container "docker.io/clinicalgenomics/fusion-report:2.1.5p2.1" input: From c151d56f30ade1cce567741f6a9d21f390506f0e Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Sun, 12 Mar 2023 18:28:12 +0100 Subject: [PATCH 169/176] change mv of filenames in fusionreport so csv or json are possible --- modules/local/fusionreport/detect/main.nf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/local/fusionreport/detect/main.nf b/modules/local/fusionreport/detect/main.nf index 8e3fbbfa..d023868f 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/local/fusionreport/detect/main.nf @@ -36,8 +36,8 @@ process FUSIONREPORT { mv fusion_list.tsv ${prefix}.fusionreport.tsv mv fusion_list_filtered.tsv ${prefix}.fusionreport_filtered.tsv - mv fusions.csv ${prefix}.fusions.csv - mv fusions.json ${prefix}.fusions.json + [ ! -f fusions.csv ] || mv fusions.csv ${prefix}.fusions.csv + [ ! -f fusions.json ] || mv fusions.json ${prefix}.fusions.json cat <<-END_VERSIONS > versions.yml "${task.process}": From 26c8c7319a83e46a1439e2f56c036d1b1cef49b8 Mon Sep 17 00:00:00 2001 From: Alexander Peltzer Date: Mon, 13 Mar 2023 09:27:48 +0100 Subject: [PATCH 170/176] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0df530f1..2569db82 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). -## v2.2.0 - [2022/03/06] +## v2.2.0 - [2022/03/13] ### Added From 87609c7260ff26df35e02dce01f2bf9f1df3741d Mon Sep 17 00:00:00 2001 From: Alexander Peltzer Date: Mon, 13 Mar 2023 10:45:40 +0100 Subject: [PATCH 171/176] Update README.md Co-authored-by: Maxime U. Garcia --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 07d59349..f5ee4390 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ![nf-core/rnafusion](docs/images/nf-core-rnafusion_logo_light.png#gh-light-mode-only) ![nf-core/rnafusion](docs/images/nf-core-rnafusion_logo_dark.png#gh-dark-mode-only) -[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/rnafusion/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX) +[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/rnafusion/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.2565517-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.2565517) [![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A522.10.1-23aa62.svg)](https://www.nextflow.io/) [![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/) From cc85523bb37da771e72e39f2437db82de1a721e4 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 13 Mar 2023 13:09:55 +0100 Subject: [PATCH 172/176] fix missing } --- conf/test_full.config | 2 ++ modules/local/fusionreport/download/main.nf | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/conf/test_full.config b/conf/test_full.config index 39c64928..eb8f5cd6 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -16,3 +16,5 @@ params { input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' // Other params + + } diff --git a/modules/local/fusionreport/download/main.nf b/modules/local/fusionreport/download/main.nf index 78afeede..7e686ce6 100644 --- a/modules/local/fusionreport/download/main.nf +++ b/modules/local/fusionreport/download/main.nf @@ -4,7 +4,7 @@ process FUSIONREPORT_DOWNLOAD { // Note: 2.7X indices incompatible with AWS iGenomes. conda "bioconda::star=2.7.9a" - container "docker.io/clinicalgenomics/fusion-report:2.1.5p2" + container "docker.io/clinicalgenomics/fusion-report:2.1.5p2.1" input: val(username) From 423b4b7c67de69a3afe565af422b01340d62b0b1 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 13 Mar 2023 13:12:52 +0100 Subject: [PATCH 173/176] remove superfluous igenomes/genomes statements --- nextflow.config | 5 ----- 1 file changed, 5 deletions(-) diff --git a/nextflow.config b/nextflow.config index 2e2a0ceb..5a66ee80 100644 --- a/nextflow.config +++ b/nextflow.config @@ -16,11 +16,6 @@ params { cosmic_passwd = null qiagen = false - // References - genome = null - igenomes_base = 's3://ngi-igenomes/igenomes' - igenomes_ignore = true - // MultiQC options multiqc_config = null multiqc_title = null From b95617fc7b85ff5cbad51a6c7ac158c5630bc60f Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 13 Mar 2023 13:16:56 +0100 Subject: [PATCH 174/176] change aws full test to test_full profile without memory limits --- .github/workflows/awsfulltest.yml | 22 +++++++++++----------- conf/test.config | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 61a9203a..caad7c58 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -29,7 +29,7 @@ jobs: "arriba": true, "build_references": true } - profiles: test,aws_tower + profiles: test_full,aws_tower - name: Launch arriba workflow via tower uses: nf-core/tower-action@v3 @@ -46,7 +46,7 @@ jobs: "cosmic_passwd": "${{ secrets.cosmic_passwd }}", "arriba": true, } - profiles: test,aws_tower + profiles: test_full,aws_tower - name: Launch build squid workflow via tower uses: nf-core/tower-action@v3 @@ -64,7 +64,7 @@ jobs: "squid": true, "build_references": true } - profiles: test,aws_tower + profiles: test_full,aws_tower - name: Launch squid workflow via tower uses: nf-core/tower-action@v3 @@ -81,7 +81,7 @@ jobs: "cosmic_passwd": "${{ secrets.cosmic_passwd }}", "squid": true, } - profiles: test,aws_tower + profiles: test_full,aws_tower - name: Launch build starfusion workflow via tower uses: nf-core/tower-action@v3 @@ -99,7 +99,7 @@ jobs: "starfusion": true, "build_references": true } - profiles: test,aws_tower + profiles: test_full,aws_tower - name: Launch starfusion workflow via tower uses: nf-core/tower-action@v3 @@ -116,7 +116,7 @@ jobs: "cosmic_passwd": "${{ secrets.cosmic_passwd }}", "starfusion": true, } - profiles: test,aws_tower + profiles: test_full,aws_tower - name: Launch build fusioncatcher workflow via tower uses: nf-core/tower-action@v3 @@ -134,7 +134,7 @@ jobs: "fusioncatcher": true, "build_references": true } - profiles: test,aws_tower + profiles: test_full,aws_tower - name: Launch fusioncatcher workflow via tower uses: nf-core/tower-action@v3 @@ -151,7 +151,7 @@ jobs: "cosmic_passwd": "${{ secrets.cosmic_passwd }}", "fusioncatcher": true, } - profiles: test,aws_tower + profiles: test_full,aws_tower - name: Launch build pizzly workflow via tower uses: nf-core/tower-action@v3 @@ -169,7 +169,7 @@ jobs: "pizzly": true, "build_references": true } - profiles: test,aws_tower + profiles: test_full,aws_tower - name: Launch pizzly workflow via tower uses: nf-core/tower-action@v3 @@ -186,7 +186,7 @@ jobs: "cosmic_passwd": "${{ secrets.cosmic_passwd }}", "pizzly": true, } - profiles: test,aws_tower + profiles: test_full,aws_tower - name: Launch stringtie workflow via tower uses: nf-core/tower-action@v3 @@ -203,4 +203,4 @@ jobs: "cosmic_passwd": "${{ secrets.cosmic_passwd }}", "stringtie": true, } - profiles: test,aws_tower + profiles: test_full,aws_tower diff --git a/conf/test.config b/conf/test.config index 69858eaf..236d1a39 100644 --- a/conf/test.config +++ b/conf/test.config @@ -16,7 +16,7 @@ params { // Limit resources so that this can run on GitHub Actions max_cpus = 2 - max_memory = 8.GB + max_memory = 6.GB max_time = 6.h // Input data From eb6af7da2a122b5cb56885746a7731784334614c Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 13 Mar 2023 13:45:26 +0100 Subject: [PATCH 175/176] update --- modules/nf-core/cat/cat/meta.yml | 4 +-- .../custom/dumpsoftwareversions/main.nf | 6 ++-- modules/nf-core/fastp/main.nf | 1 - modules/nf-core/fastp/meta.yml | 2 +- .../gatk4/createsequencedictionary/meta.yml | 34 +++++++++---------- modules/nf-core/kallisto/index/meta.yml | 2 +- .../nf-core/picard/collectwgsmetrics/meta.yml | 2 ++ modules/nf-core/samtools/index/meta.yml | 2 +- modules/nf-core/samtools/sort/meta.yml | 2 +- modules/nf-core/samtools/view/meta.yml | 2 +- 10 files changed, 29 insertions(+), 28 deletions(-) diff --git a/modules/nf-core/cat/cat/meta.yml b/modules/nf-core/cat/cat/meta.yml index 5eeff5a6..8acc0bfa 100644 --- a/modules/nf-core/cat/cat/meta.yml +++ b/modules/nf-core/cat/cat/meta.yml @@ -7,9 +7,9 @@ keywords: tools: - cat: description: Just concatenation - homepage: None + documentation: https://man7.org/linux/man-pages/man1/cat.1.html - tool_dev_url: None + licence: ["GPL-3.0-or-later"] input: - meta: diff --git a/modules/nf-core/custom/dumpsoftwareversions/main.nf b/modules/nf-core/custom/dumpsoftwareversions/main.nf index 3df21765..800a6099 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/fastp/main.nf b/modules/nf-core/fastp/main.nf index e1ed9288..5eeb9b09 100644 --- a/modules/nf-core/fastp/main.nf +++ b/modules/nf-core/fastp/main.nf @@ -58,7 +58,6 @@ process FASTP { [ ! -f ${prefix}.fastq.gz ] && ln -sf $reads ${prefix}.fastq.gz fastp \\ - --stdout \\ --in1 ${prefix}.fastq.gz \\ --out1 ${prefix}.fastp.fastq.gz \\ --thread $task.cpus \\ diff --git a/modules/nf-core/fastp/meta.yml b/modules/nf-core/fastp/meta.yml index 6f6fad74..197ea7ca 100644 --- a/modules/nf-core/fastp/meta.yml +++ b/modules/nf-core/fastp/meta.yml @@ -9,7 +9,7 @@ tools: 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: https://doi.org/10.1093/bioinformatics/bty560 + doi: 10.1093/bioinformatics/bty560 licence: ["MIT"] input: - meta: diff --git a/modules/nf-core/gatk4/createsequencedictionary/meta.yml b/modules/nf-core/gatk4/createsequencedictionary/meta.yml index bd247888..69c23581 100644 --- a/modules/nf-core/gatk4/createsequencedictionary/meta.yml +++ b/modules/nf-core/gatk4/createsequencedictionary/meta.yml @@ -5,28 +5,28 @@ keywords: - fasta tools: - gatk: - description: | - Developed in the Data Sciences Platform at the Broad Institute, the toolkit offers a wide variety of tools - with a primary focus on variant discovery and genotyping. Its powerful processing engine - and high-performance computing features make it capable of taking on projects of any size. - homepage: https://gatk.broadinstitute.org/hc/en-us - documentation: https://gatk.broadinstitute.org/hc/en-us/categories/360002369672s - doi: 10.1158/1538-7445.AM2017-3590 - licence: ["Apache-2.0"] + description: | + Developed in the Data Sciences Platform at the Broad Institute, the toolkit offers a wide variety of tools + with a primary focus on variant discovery and genotyping. Its powerful processing engine + and high-performance computing features make it capable of taking on projects of any size. + homepage: https://gatk.broadinstitute.org/hc/en-us + documentation: https://gatk.broadinstitute.org/hc/en-us/categories/360002369672s + doi: 10.1158/1538-7445.AM2017-3590 + licence: ["Apache-2.0"] input: - fasta: - type: file - description: Input fasta file - pattern: "*.{fasta,fa}" + type: file + description: Input fasta file + pattern: "*.{fasta,fa}" output: - dict: - type: file - description: gatk dictionary file - pattern: "*.{dict}" + type: file + description: gatk dictionary file + pattern: "*.{dict}" - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + type: file + description: File containing software versions + pattern: "versions.yml" authors: - "@maxulysse" diff --git a/modules/nf-core/kallisto/index/meta.yml b/modules/nf-core/kallisto/index/meta.yml index 307650b2..47f40c9a 100644 --- a/modules/nf-core/kallisto/index/meta.yml +++ b/modules/nf-core/kallisto/index/meta.yml @@ -8,7 +8,7 @@ tools: homepage: https://pachterlab.github.io/kallisto/ documentation: https://pachterlab.github.io/kallisto/manual tool_dev_url: https://github.com/pachterlab/kallisto - doi: "" + licence: ["BSD-2-Clause"] input: diff --git a/modules/nf-core/picard/collectwgsmetrics/meta.yml b/modules/nf-core/picard/collectwgsmetrics/meta.yml index 57ab9cfe..2f8dbd3c 100644 --- a/modules/nf-core/picard/collectwgsmetrics/meta.yml +++ b/modules/nf-core/picard/collectwgsmetrics/meta.yml @@ -29,6 +29,7 @@ input: description: (Optional) Aligned reads file index pattern: "*.{bai,crai}" - meta2: + type: map description: | Groovy Map containing reference information e.g. [ id:'genome' ] @@ -37,6 +38,7 @@ input: description: Genome fasta file pattern: "*.{fa,fasta,fna}" - meta2: + type: map description: | Groovy Map containing reference information e.g. [ id:'genome' ] diff --git a/modules/nf-core/samtools/index/meta.yml b/modules/nf-core/samtools/index/meta.yml index e5cadbc2..8bd2fa6f 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 09289751..07328431 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/view/meta.yml b/modules/nf-core/samtools/view/meta.yml index a52e4f8d..2e597d34 100644 --- a/modules/nf-core/samtools/view/meta.yml +++ b/modules/nf-core/samtools/view/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: From 3c3e1ce01eed062cef3d5c0442ac88b1a1356989 Mon Sep 17 00:00:00 2001 From: Annick Renevey <47788523+rannick@users.noreply.github.com> Date: Mon, 13 Mar 2023 13:49:17 +0100 Subject: [PATCH 176/176] update modules --- conf/igenomes.config | 432 ------------------------------------------- modules.json | 18 +- nextflow.config | 7 - nextflow_schema.json | 15 -- 4 files changed, 9 insertions(+), 463 deletions(-) delete mode 100644 conf/igenomes.config diff --git a/conf/igenomes.config b/conf/igenomes.config deleted file mode 100644 index 7a1b3ac6..00000000 --- a/conf/igenomes.config +++ /dev/null @@ -1,432 +0,0 @@ -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Nextflow config file for iGenomes paths -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Defines reference genomes using iGenome paths. - Can be used by any config that customises the base path using: - $params.igenomes_base / --igenomes_base ----------------------------------------------------------------------------------------- -*/ - -params { - // illumina iGenomes reference file paths - genomes { - 'GRCh37' { - fasta = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/README.txt" - mito_name = "MT" - macs_gsize = "2.7e9" - blacklist = "${projectDir}/assets/blacklists/GRCh37-blacklist.bed" - } - 'GRCh38' { - fasta = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Annotation/Genes/genes.bed" - mito_name = "chrM" - macs_gsize = "2.7e9" - blacklist = "${projectDir}/assets/blacklists/hg38-blacklist.bed" - } - 'GRCm38' { - fasta = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/README.txt" - mito_name = "MT" - macs_gsize = "1.87e9" - blacklist = "${projectDir}/assets/blacklists/GRCm38-blacklist.bed" - } - 'TAIR10' { - fasta = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/README.txt" - mito_name = "Mt" - } - 'EB2' { - fasta = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/README.txt" - } - 'UMD3.1' { - fasta = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/README.txt" - mito_name = "MT" - } - 'WBcel235' { - fasta = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Annotation/Genes/genes.bed" - mito_name = "MtDNA" - macs_gsize = "9e7" - } - 'CanFam3.1' { - fasta = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/README.txt" - mito_name = "MT" - } - 'GRCz10' { - fasta = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Annotation/Genes/genes.bed" - mito_name = "MT" - } - 'BDGP6' { - fasta = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Annotation/Genes/genes.bed" - mito_name = "M" - macs_gsize = "1.2e8" - } - 'EquCab2' { - fasta = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/README.txt" - mito_name = "MT" - } - 'EB1' { - fasta = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/README.txt" - } - 'Galgal4' { - fasta = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Annotation/Genes/genes.bed" - mito_name = "MT" - } - 'Gm01' { - fasta = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/README.txt" - } - 'Mmul_1' { - fasta = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/README.txt" - mito_name = "MT" - } - 'IRGSP-1.0' { - fasta = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Annotation/Genes/genes.bed" - mito_name = "Mt" - } - 'CHIMP2.1.4' { - fasta = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/README.txt" - mito_name = "MT" - } - 'Rnor_5.0' { - fasta = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Annotation/Genes/genes.bed" - mito_name = "MT" - } - 'Rnor_6.0' { - fasta = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Annotation/Genes/genes.bed" - mito_name = "MT" - } - 'R64-1-1' { - fasta = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.bed" - mito_name = "MT" - macs_gsize = "1.2e7" - } - 'EF2' { - fasta = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/README.txt" - mito_name = "MT" - macs_gsize = "1.21e7" - } - 'Sbi1' { - fasta = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/README.txt" - } - 'Sscrofa10.2' { - fasta = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/README.txt" - mito_name = "MT" - } - 'AGPv3' { - fasta = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Annotation/Genes/genes.bed" - mito_name = "Mt" - } - 'hg38' { - fasta = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Annotation/Genes/genes.bed" - mito_name = "chrM" - macs_gsize = "2.7e9" - blacklist = "${projectDir}/assets/blacklists/hg38-blacklist.bed" - } - 'hg19' { - fasta = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/README.txt" - mito_name = "chrM" - macs_gsize = "2.7e9" - blacklist = "${projectDir}/assets/blacklists/hg19-blacklist.bed" - } - 'mm10' { - fasta = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/README.txt" - mito_name = "chrM" - macs_gsize = "1.87e9" - blacklist = "${projectDir}/assets/blacklists/mm10-blacklist.bed" - } - 'bosTau8' { - fasta = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Annotation/Genes/genes.bed" - mito_name = "chrM" - } - 'ce10' { - fasta = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/README.txt" - mito_name = "chrM" - macs_gsize = "9e7" - } - 'canFam3' { - fasta = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/README.txt" - mito_name = "chrM" - } - 'danRer10' { - fasta = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Annotation/Genes/genes.bed" - mito_name = "chrM" - macs_gsize = "1.37e9" - } - 'dm6' { - fasta = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Annotation/Genes/genes.bed" - mito_name = "chrM" - macs_gsize = "1.2e8" - } - 'equCab2' { - fasta = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/README.txt" - mito_name = "chrM" - } - 'galGal4' { - fasta = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/README.txt" - mito_name = "chrM" - } - 'panTro4' { - fasta = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/README.txt" - mito_name = "chrM" - } - 'rn6' { - fasta = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Annotation/Genes/genes.bed" - mito_name = "chrM" - } - 'sacCer3' { - fasta = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/BismarkIndex/" - readme = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Annotation/README.txt" - mito_name = "chrM" - macs_gsize = "1.2e7" - } - 'susScr3' { - fasta = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/README.txt" - mito_name = "chrM" - } - } -} diff --git a/modules.json b/modules.json index 8e82f544..cfa3ec10 100644 --- a/modules.json +++ b/modules.json @@ -12,7 +12,7 @@ }, "cat/cat": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["modules"] }, "cat/fastq": { @@ -22,12 +22,12 @@ }, "custom/dumpsoftwareversions": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "b6d4d476aee074311c89d82a69c1921bd70c8180", "installed_by": ["modules"] }, "fastp": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "20a508676f40d0fd3f911ac595af91ec845704c4", "installed_by": ["modules"] }, "fastqc": { @@ -42,12 +42,12 @@ }, "gatk4/createsequencedictionary": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["modules"] }, "kallisto/index": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["modules"] }, "multiqc": { @@ -57,7 +57,7 @@ }, "picard/collectwgsmetrics": { "branch": "master", - "git_sha": "2f88b26e9804b99e98f7cd08e74c3f88288a3358", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["modules"] }, "picard/markduplicates": { @@ -77,17 +77,17 @@ }, "samtools/index": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["modules"] }, "samtools/sort": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["modules"] }, "samtools/view": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "0f8a77ff00e65eaeebc509b8156eaa983192474b", "installed_by": ["modules"] }, "star/align": { diff --git a/nextflow.config b/nextflow.config index 5a66ee80..81028ad0 100644 --- a/nextflow.config +++ b/nextflow.config @@ -122,13 +122,6 @@ params { max_time = '240.h' } -// Load igenomes.config if required -if (!params.igenomes_ignore) { - includeConfig 'conf/igenomes.config' -} else { - params.genomes = [:] -} - // Load base.config by default for all pipelines includeConfig 'conf/base.config' diff --git a/nextflow_schema.json b/nextflow_schema.json index 53a3b122..be0436d0 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -329,21 +329,6 @@ "description": "Path to FASTA genome index file.", "fa_icon": "far fa-file-code" }, - "igenomes_base": { - "type": "string", - "format": "directory-path", - "description": "Directory / URL base for iGenomes references.", - "default": "s3://ngi-igenomes/igenomes", - "fa_icon": "fas fa-cloud-download-alt", - "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`." - }, "gtf": { "type": "string", "format": "file-path",