From 184457c1023aee839c68b62e8ba1001f674aaeaf Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Tue, 8 Oct 2024 12:32:24 +0000 Subject: [PATCH 01/22] Template update for nf-core/tools version 3.0.0 --- .editorconfig | 4 + .github/CONTRIBUTING.md | 10 +- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .github/workflows/awsfulltest.yml | 23 +- .github/workflows/ci.yml | 17 +- .github/workflows/download_pipeline.yml | 53 ++- .github/workflows/linting.yml | 23 +- .github/workflows/linting_comment.yml | 2 +- .github/workflows/release-announcements.yml | 2 +- .../workflows/template_version_comment.yml | 43 ++ .gitpod.yml | 7 +- .nf-core.yml | 20 +- .pre-commit-config.yaml | 2 +- .prettierignore | 1 + CHANGELOG.md | 2 +- CITATIONS.md | 4 +- README.md | 5 +- assets/multiqc_config.yml | 4 +- assets/nf-core-pairgenomealign_logo_light.png | Bin 90043 -> 89810 bytes assets/schema_input.json | 2 +- conf/base.config | 34 +- conf/igenomes_ignored.config | 9 + conf/modules.config | 1 - conf/test.config | 13 +- docs/images/mqc_fastqc_adapter.png | Bin 23458 -> 0 bytes docs/images/mqc_fastqc_counts.png | Bin 33918 -> 0 bytes docs/images/mqc_fastqc_quality.png | Bin 55769 -> 0 bytes .../nf-core-pairgenomealign_logo_dark.png | Bin 24961 -> 24597 bytes .../nf-core-pairgenomealign_logo_light.png | Bin 20878 -> 20505 bytes docs/output.md | 11 +- docs/usage.md | 12 +- main.nf | 10 +- modules.json | 12 +- modules/nf-core/fastqc/environment.yml | 2 - modules/nf-core/fastqc/main.nf | 5 +- modules/nf-core/fastqc/meta.yml | 57 +-- modules/nf-core/fastqc/tests/main.nf.test | 225 ++++++++--- .../nf-core/fastqc/tests/main.nf.test.snap | 370 ++++++++++++++++-- modules/nf-core/multiqc/environment.yml | 4 +- modules/nf-core/multiqc/main.nf | 14 +- modules/nf-core/multiqc/meta.yml | 78 ++-- modules/nf-core/multiqc/tests/main.nf.test | 8 + .../nf-core/multiqc/tests/main.nf.test.snap | 20 +- modules/nf-core/multiqc/tests/nextflow.config | 5 + nextflow.config | 148 ++++--- nextflow_schema.json | 85 +--- .../main.nf | 56 +-- .../nf-core/utils_nextflow_pipeline/main.nf | 24 +- .../tests/nextflow.config | 2 +- .../nf-core/utils_nfcore_pipeline/main.nf | 45 ++- .../nf-core/utils_nfschema_plugin/main.nf | 46 +++ .../nf-core/utils_nfschema_plugin/meta.yml | 35 ++ .../utils_nfschema_plugin/tests/main.nf.test | 117 ++++++ .../tests/nextflow.config | 8 + .../tests/nextflow_schema.json | 8 +- .../nf-core/utils_nfvalidation_plugin/main.nf | 62 --- .../utils_nfvalidation_plugin/meta.yml | 44 --- .../tests/main.nf.test | 200 ---------- .../utils_nfvalidation_plugin/tests/tags.yml | 2 - workflows/pairgenomealign.nf | 23 +- 60 files changed, 1211 insertions(+), 810 deletions(-) create mode 100644 .github/workflows/template_version_comment.yml create mode 100644 conf/igenomes_ignored.config delete mode 100755 docs/images/mqc_fastqc_adapter.png delete mode 100755 docs/images/mqc_fastqc_counts.png delete mode 100755 docs/images/mqc_fastqc_quality.png create mode 100644 modules/nf-core/multiqc/tests/nextflow.config create mode 100644 subworkflows/nf-core/utils_nfschema_plugin/main.nf create mode 100644 subworkflows/nf-core/utils_nfschema_plugin/meta.yml create mode 100644 subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test create mode 100644 subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config rename subworkflows/nf-core/{utils_nfvalidation_plugin => utils_nfschema_plugin}/tests/nextflow_schema.json (95%) delete mode 100644 subworkflows/nf-core/utils_nfvalidation_plugin/main.nf delete mode 100644 subworkflows/nf-core/utils_nfvalidation_plugin/meta.yml delete mode 100644 subworkflows/nf-core/utils_nfvalidation_plugin/tests/main.nf.test delete mode 100644 subworkflows/nf-core/utils_nfvalidation_plugin/tests/tags.yml diff --git a/.editorconfig b/.editorconfig index 72dda28..e105881 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,6 +11,7 @@ indent_style = space [*.{md,yml,yaml,html,css,scss,js}] indent_size = 2 + # These files are edited and tested upstream in nf-core/modules [/modules/nf-core/**] charset = unset @@ -25,9 +26,12 @@ insert_final_newline = unset trim_trailing_whitespace = unset indent_style = unset + + [/assets/email*] indent_size = unset + # ignore python and markdown [*.{py,md}] indent_style = unset diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index cf9831c..a706b78 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -19,7 +19,7 @@ If you'd like to write some code for nf-core/pairgenomealign, the standard workf 1. Check that there isn't already an issue about your idea in the [nf-core/pairgenomealign issues](/~https://github.com/nf-core/pairgenomealign/issues) to avoid duplicating work. If there isn't one already, please create one so that others know you're working on this 2. [Fork](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) the [nf-core/pairgenomealign repository](/~https://github.com/nf-core/pairgenomealign) to your GitHub account 3. Make the necessary changes / additions within your forked repository following [Pipeline conventions](#pipeline-contribution-conventions) -4. Use `nf-core schema build` and add any new parameters to the pipeline JSON schema (requires [nf-core tools](/~https://github.com/nf-core/tools) >= 1.10). +4. Use `nf-core pipelines schema build` and add any new parameters to the pipeline JSON schema (requires [nf-core tools](/~https://github.com/nf-core/tools) >= 1.10). 5. Submit a Pull Request against the `dev` branch and wait for the code to be reviewed and merged If you're not used to this workflow with git, you can start with some [docs from GitHub](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests) or even their [excellent `git` resources](https://try.github.io/). @@ -40,7 +40,7 @@ There are typically two types of tests that run: ### Lint tests `nf-core` has a [set of guidelines](https://nf-co.re/developers/guidelines) which all pipelines must adhere to. -To enforce these and ensure that all pipelines stay in sync, we have developed a helper tool which runs checks on the pipeline code. This is in the [nf-core/tools repository](/~https://github.com/nf-core/tools) and once installed can be run locally with the `nf-core lint ` command. +To enforce these and ensure that all pipelines stay in sync, we have developed a helper tool which runs checks on the pipeline code. This is in the [nf-core/tools repository](/~https://github.com/nf-core/tools) and once installed can be run locally with the `nf-core pipelines lint ` command. If any failures or warnings are encountered, please follow the listed URL for more documentation. @@ -75,7 +75,7 @@ If you wish to contribute a new step, please use the following coding standards: 2. Write the process block (see below). 3. Define the output channel if needed (see below). 4. Add any new parameters to `nextflow.config` with a default (see below). -5. Add any new parameters to `nextflow_schema.json` with help text (via the `nf-core schema build` tool). +5. Add any new parameters to `nextflow_schema.json` with help text (via the `nf-core pipelines schema build` tool). 6. Add sanity checks and validation for all relevant parameters. 7. Perform local tests to validate that the new code works as expected. 8. If applicable, add a new test command in `.github/workflow/ci.yml`. @@ -86,7 +86,7 @@ If you wish to contribute a new step, please use the following coding standards: Parameters should be initialised / defined with default values in `nextflow.config` under the `params` scope. -Once there, use `nf-core schema build` to add to `nextflow_schema.json`. +Once there, use `nf-core pipelines schema build` to add to `nextflow_schema.json`. ### Default processes resource requirements @@ -103,7 +103,7 @@ Please use the following naming schemes, to make it easy to understand what is g ### Nextflow version bumping -If you are using a new feature from core Nextflow, you may bump the minimum required version of nextflow in the pipeline with: `nf-core bump-version --nextflow . [min-nf-version]` +If you are using a new feature from core Nextflow, you may bump the minimum required version of nextflow in the pipeline with: `nf-core pipelines bump-version --nextflow . [min-nf-version]` ### Images and figures diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index a4d7ba7..4388a53 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/pair - [ ] 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/pairgenomealign/tree/master/.github/CONTRIBUTING.md) - [ ] If necessary, also make a PR on the nf-core/pairgenomealign _branch_ on the [nf-core/test-datasets](/~https://github.com/nf-core/test-datasets) repository. -- [ ] Make sure your code lints (`nf-core lint`). +- [ ] Make sure your code lints (`nf-core pipelines lint`). - [ ] Ensure the test suite passes (`nextflow run . -profile test,docker --outdir `). - [ ] Check for unexpected warnings in debug mode (`nextflow run . -profile debug,test,docker --outdir `). - [ ] Usage Documentation in `docs/usage.md` is updated. diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index c55aa4c..8cd9c11 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -1,18 +1,33 @@ name: nf-core AWS full size tests -# This workflow is triggered on published releases. +# This workflow is triggered on PRs opened against the master branch. # It can be additionally triggered manually with GitHub actions workflow dispatch button. # It runs the -profile 'test_full' on AWS batch on: - release: - types: [published] + pull_request: + branches: + - master workflow_dispatch: + pull_request_review: + types: [submitted] + jobs: run-platform: name: Run AWS full tests - if: github.repository == 'nf-core/pairgenomealign' + if: github.repository == 'nf-core/pairgenomealign' && github.event.review.state == 'approved' runs-on: ubuntu-latest steps: + - uses: octokit/request-action@v2.x + id: check_approvals + with: + route: GET /repos/${{ github.repository }}/pulls/${{ github.event.review.number }}/reviews + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - id: test_variables + run: | + JSON_RESPONSE='${{ steps.check_approvals.outputs.data }}' + CURRENT_APPROVALS_COUNT=$(echo $JSON_RESPONSE | jq -c '[.[] | select(.state | contains("APPROVED")) ] | length') + test $CURRENT_APPROVALS_COUNT -ge 2 || exit 1 # At least 2 approvals are required - name: Launch workflow via Seqera Platform uses: seqeralabs/action-tower-launch@v2 # TODO nf-core: You can customise AWS full pipeline tests as required diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ebe60da..0f8d132 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,7 @@ on: pull_request: release: types: [published] + workflow_dispatch: env: NXF_ANSI_LOG: false @@ -24,7 +25,7 @@ jobs: strategy: matrix: NXF_VER: - - "23.04.0" + - "24.04.2" - "latest-everything" steps: - name: Check out pipeline code @@ -38,9 +39,21 @@ jobs: - name: Disk space cleanup uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 - - name: Run pipeline with test data + - name: Run pipeline with test data (docker) # TODO nf-core: You can customise CI pipeline run tests as required # For example: adding multiple test runs with different parameters # Remember that you can parallelise this by using strategy.matrix run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker --outdir ./results + + - name: Run pipeline with test data (singularity) + # TODO nf-core: You can customise CI pipeline run tests as required + run: | + nextflow run ${GITHUB_WORKSPACE} -profile test,singularity --outdir ./results + if: "${{ github.base_ref == 'master' }}" + + - name: Run pipeline with test data (conda) + # TODO nf-core: You can customise CI pipeline run tests as required + run: | + nextflow run ${GITHUB_WORKSPACE} -profile test,conda --outdir ./results + if: "${{ github.base_ref == 'master' }}" diff --git a/.github/workflows/download_pipeline.yml b/.github/workflows/download_pipeline.yml index 2d20d64..713dc3e 100644 --- a/.github/workflows/download_pipeline.yml +++ b/.github/workflows/download_pipeline.yml @@ -1,4 +1,4 @@ -name: Test successful pipeline download with 'nf-core download' +name: Test successful pipeline download with 'nf-core pipelines download' # Run the workflow when: # - dispatched manually @@ -8,7 +8,7 @@ on: workflow_dispatch: inputs: testbranch: - description: "The specific branch you wish to utilize for the test execution of nf-core download." + description: "The specific branch you wish to utilize for the test execution of nf-core pipelines download." required: true default: "dev" pull_request: @@ -39,9 +39,11 @@ jobs: with: python-version: "3.12" architecture: "x64" - - uses: eWaterCycle/setup-singularity@931d4e31109e875b13309ae1d07c70ca8fbc8537 # v7 + + - name: Setup Apptainer + uses: eWaterCycle/setup-apptainer@4bb22c52d4f63406c49e94c804632975787312b3 # v2.0.0 with: - singularity-version: 3.8.3 + apptainer-version: 1.3.4 - name: Install dependencies run: | @@ -54,33 +56,64 @@ jobs: echo "REPOTITLE_LOWERCASE=$(basename ${GITHUB_REPOSITORY,,})" >> ${GITHUB_ENV} echo "REPO_BRANCH=${{ github.event.inputs.testbranch || 'dev' }}" >> ${GITHUB_ENV} + - name: Make a cache directory for the container images + run: | + mkdir -p ./singularity_container_images + - name: Download the pipeline env: - NXF_SINGULARITY_CACHEDIR: ./ + NXF_SINGULARITY_CACHEDIR: ./singularity_container_images run: | - nf-core download ${{ env.REPO_LOWERCASE }} \ + nf-core pipelines download ${{ env.REPO_LOWERCASE }} \ --revision ${{ env.REPO_BRANCH }} \ --outdir ./${{ env.REPOTITLE_LOWERCASE }} \ --compress "none" \ --container-system 'singularity' \ - --container-library "quay.io" -l "docker.io" -l "ghcr.io" \ + --container-library "quay.io" -l "docker.io" -l "community.wave.seqera.io" \ --container-cache-utilisation 'amend' \ - --download-configuration + --download-configuration 'yes' - name: Inspect download run: tree ./${{ env.REPOTITLE_LOWERCASE }} + - name: Count the downloaded number of container images + id: count_initial + run: | + image_count=$(ls -1 ./singularity_container_images | wc -l | xargs) + echo "Initial container image count: $image_count" + echo "IMAGE_COUNT_INITIAL=$image_count" >> ${GITHUB_ENV} + - name: Run the downloaded pipeline (stub) id: stub_run_pipeline continue-on-error: true env: - NXF_SINGULARITY_CACHEDIR: ./ + NXF_SINGULARITY_CACHEDIR: ./singularity_container_images NXF_SINGULARITY_HOME_MOUNT: true run: nextflow run ./${{ env.REPOTITLE_LOWERCASE }}/$( sed 's/\W/_/g' <<< ${{ env.REPO_BRANCH }}) -stub -profile test,singularity --outdir ./results - name: Run the downloaded pipeline (stub run not supported) id: run_pipeline if: ${{ job.steps.stub_run_pipeline.status == failure() }} env: - NXF_SINGULARITY_CACHEDIR: ./ + NXF_SINGULARITY_CACHEDIR: ./singularity_container_images NXF_SINGULARITY_HOME_MOUNT: true run: nextflow run ./${{ env.REPOTITLE_LOWERCASE }}/$( sed 's/\W/_/g' <<< ${{ env.REPO_BRANCH }}) -profile test,singularity --outdir ./results + + - name: Count the downloaded number of container images + id: count_afterwards + run: | + image_count=$(ls -1 ./singularity_container_images | wc -l | xargs) + echo "Post-pipeline run container image count: $image_count" + echo "IMAGE_COUNT_AFTER=$image_count" >> ${GITHUB_ENV} + + - name: Compare container image counts + run: | + if [ "${{ env.IMAGE_COUNT_INITIAL }}" -ne "${{ env.IMAGE_COUNT_AFTER }}" ]; then + initial_count=${{ env.IMAGE_COUNT_INITIAL }} + final_count=${{ env.IMAGE_COUNT_AFTER }} + difference=$((final_count - initial_count)) + echo "$difference additional container images were \n downloaded at runtime . The pipeline has no support for offline runs!" + tree ./singularity_container_images + exit 1 + else + echo "The pipeline can be downloaded successfully!" + fi diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 1fcafe8..b882838 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -1,6 +1,6 @@ name: nf-core linting # This workflow is triggered on pushes and PRs to the repository. -# It runs the `nf-core lint` and markdown lint tests to ensure +# It runs the `nf-core pipelines lint` and markdown lint tests to ensure # that the code meets the nf-core guidelines. on: push: @@ -41,17 +41,32 @@ jobs: python-version: "3.12" architecture: "x64" + - name: read .nf-core.yml + uses: pietrobolcato/action-read-yaml@1.0.0 + id: read_yml + with: + config: ${{ github.workspace }}/.nf-core.yaml + - name: Install dependencies run: | python -m pip install --upgrade pip - pip install nf-core + pip install nf-core==${{ steps.read_yml.outputs['nf_core_version'] }} + + - name: Run nf-core pipelines lint + if: ${{ github.base_ref != 'master' }} + env: + GITHUB_COMMENTS_URL: ${{ github.event.pull_request.comments_url }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_PR_COMMIT: ${{ github.event.pull_request.head.sha }} + run: nf-core -l lint_log.txt pipelines lint --dir ${GITHUB_WORKSPACE} --markdown lint_results.md - - name: Run nf-core lint + - name: Run nf-core pipelines lint --release + if: ${{ github.base_ref == 'master' }} env: GITHUB_COMMENTS_URL: ${{ github.event.pull_request.comments_url }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_PR_COMMIT: ${{ github.event.pull_request.head.sha }} - run: nf-core -l lint_log.txt lint --dir ${GITHUB_WORKSPACE} --markdown lint_results.md + run: nf-core -l lint_log.txt pipelines lint --release --dir ${GITHUB_WORKSPACE} --markdown lint_results.md - name: Save PR number if: ${{ always() }} diff --git a/.github/workflows/linting_comment.yml b/.github/workflows/linting_comment.yml index 40acc23..42e519b 100644 --- a/.github/workflows/linting_comment.yml +++ b/.github/workflows/linting_comment.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Download lint results - uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe # v3 + uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11 # v6 with: workflow: linting.yml workflow_conclusion: completed diff --git a/.github/workflows/release-announcements.yml b/.github/workflows/release-announcements.yml index 03ecfcf..c6ba35d 100644 --- a/.github/workflows/release-announcements.yml +++ b/.github/workflows/release-announcements.yml @@ -12,7 +12,7 @@ jobs: - name: get topics and convert to hashtags id: get_topics run: | - echo "topics=$(curl -s https://nf-co.re/pipelines.json | jq -r '.remote_workflows[] | select(.full_name == "${{ github.repository }}") | .topics[]' | awk '{print "#"$0}' | tr '\n' ' ')" >> $GITHUB_OUTPUT + echo "topics=$(curl -s https://nf-co.re/pipelines.json | jq -r '.remote_workflows[] | select(.full_name == "${{ github.repository }}") | .topics[]' | awk '{print "#"$0}' | tr '\n' ' ')" | sed 's/-//g' >> $GITHUB_OUTPUT - uses: rzr/fediverse-action@master with: diff --git a/.github/workflows/template_version_comment.yml b/.github/workflows/template_version_comment.yml new file mode 100644 index 0000000..9dea41f --- /dev/null +++ b/.github/workflows/template_version_comment.yml @@ -0,0 +1,43 @@ +name: nf-core template version comment +# This workflow is triggered on PRs to check if the pipeline template version matches the latest nf-core version. +# It posts a comment to the PR, even if it comes from a fork. + +on: pull_request_target + +jobs: + template_version: + runs-on: ubuntu-latest + steps: + - name: Check out pipeline code + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 + + - name: Read template version from .nf-core.yml + uses: pietrobolcato/action-read-yaml@1.0.0 + id: read_yml + with: + config: ${{ github.workspace }}/.nf-core.yml + + - name: Install nf-core + run: | + python -m pip install --upgrade pip + pip install nf-core==${{ steps.read_yml.outputs['nf_core_version'] }} + + - name: Check nf-core outdated + id: nf_core_outdated + run: pip list --outdated | grep nf-core + + - name: Post nf-core template version comment + uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2 + if: | + ${{ steps.nf_core_outdated.outputs.stdout }} =~ 'nf-core' + with: + repo-token: ${{ secrets.NF_CORE_BOT_AUTH_TOKEN }} + allow-repeats: false + message: | + ## :warning: Newer version of the nf-core template is available. + + Your pipeline is using an old version of the nf-core template: ${{ steps.read_yml.outputs['nf_core_version'] }}. + Please update your pipeline to the latest version. + + For more documentation on how to update your pipeline, please see the [nf-core documentation](/~https://github.com/nf-core/tools?tab=readme-ov-file#sync-a-pipeline-with-the-template) and [Synchronisation documentation](https://nf-co.re/docs/contributing/sync). + # diff --git a/.gitpod.yml b/.gitpod.yml index 105a182..4611863 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -4,17 +4,14 @@ tasks: command: | pre-commit install --install-hooks nextflow self-update - - name: unset JAVA_TOOL_OPTIONS - command: | - unset JAVA_TOOL_OPTIONS vscode: extensions: # based on nf-core.nf-core-extensionpack - - esbenp.prettier-vscode # Markdown/CommonMark linting and style checking for Visual Studio Code + #- esbenp.prettier-vscode # Markdown/CommonMark linting and style checking for Visual Studio Code - EditorConfig.EditorConfig # override user/workspace settings with settings found in .editorconfig files - Gruntfuggly.todo-tree # Display TODO and FIXME in a tree view in the activity bar - mechatroner.rainbow-csv # Highlight columns in csv files in different colors - # - nextflow.nextflow # Nextflow syntax highlighting + - nextflow.nextflow # Nextflow syntax highlighting - oderwat.indent-rainbow # Highlight indentation level - streetsidesoftware.code-spell-checker # Spelling checker for source code - charliermarsh.ruff # Code linter Ruff diff --git a/.nf-core.yml b/.nf-core.yml index e0b85a7..f675917 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -1,2 +1,20 @@ +bump_version: null +lint: + files_unchanged: + - assets/nf-core-pairgenomealign_logo_light.png + - docs/images/nf-core-pairgenomealign_logo_light.png + - docs/images/nf-core-pairgenomealign_logo_dark.png +nf_core_version: 3.0.0 +org_path: null repository_type: pipeline -nf_core_version: "2.14.1" +template: + author: charles-plessy + description: Pairwise alignment pipeline (genome to genome or reads to genome) + force: false + is_nfcore: true + name: pairgenomealign + org: nf-core + outdir: . + skip_features: null + version: 1.1.0 +update: null diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4dc0f1d..9e9f0e1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ repos: - prettier@3.2.5 - repo: /~https://github.com/editorconfig-checker/editorconfig-checker.python - rev: "2.7.3" + rev: "3.0.3" hooks: - id: editorconfig-checker alias: ec diff --git a/.prettierignore b/.prettierignore index 437d763..610e506 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,4 @@ + email_template.html adaptivecard.json slackreport.json diff --git a/CHANGELOG.md b/CHANGELOG.md index e5e3cb3..0028778 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). -## v1.0dev - [date] +## v1.1.0 - [date] Initial release of nf-core/pairgenomealign, created with the [nf-core](https://nf-co.re/) template. diff --git a/CITATIONS.md b/CITATIONS.md index 4867b6f..72ccaba 100644 --- a/CITATIONS.md +++ b/CITATIONS.md @@ -12,11 +12,11 @@ - [FastQC](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/) - > Andrews, S. (2010). FastQC: A Quality Control Tool for High Throughput Sequence Data [Online]. +> Andrews, S. (2010). FastQC: A Quality Control Tool for High Throughput Sequence Data [Online]. - [MultiQC](https://pubmed.ncbi.nlm.nih.gov/27312411/) - > Ewels P, Magnusson M, Lundin S, Käller M. MultiQC: summarize analysis results for multiple tools and samples in a single report. Bioinformatics. 2016 Oct 1;32(19):3047-8. doi: 10.1093/bioinformatics/btw354. Epub 2016 Jun 16. PubMed PMID: 27312411; PubMed Central PMCID: PMC5039924. +> Ewels P, Magnusson M, Lundin S, Käller M. MultiQC: summarize analysis results for multiple tools and samples in a single report. Bioinformatics. 2016 Oct 1;32(19):3047-8. doi: 10.1093/bioinformatics/btw354. Epub 2016 Jun 16. PubMed PMID: 27312411; PubMed Central PMCID: PMC5039924. ## Software packaging/containerisation tools diff --git a/README.md b/README.md index 521e9ef..c7a3b55 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![GitHub Actions Linting Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/pairgenomealign/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX) [![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com) -[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A523.04.0-23aa62.svg)](https://www.nextflow.io/) +[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A524.04.2-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/) @@ -67,8 +67,7 @@ nextflow run nf-core/pairgenomealign \ ``` > [!WARNING] -> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; -> see [docs](https://nf-co.re/usage/configuration#custom-configuration-files). +> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files). For more details and further functionality, please refer to the [usage documentation](https://nf-co.re/pairgenomealign/usage) and the [parameter documentation](https://nf-co.re/pairgenomealign/parameters). diff --git a/assets/multiqc_config.yml b/assets/multiqc_config.yml index 52f81cc..aacca39 100644 --- a/assets/multiqc_config.yml +++ b/assets/multiqc_config.yml @@ -1,7 +1,7 @@ report_comment: > - This report has been generated by the nf-core/pairgenomealign + This report has been generated by the nf-core/pairgenomealign analysis pipeline. For information about how to interpret these results, please see the - documentation. + documentation. report_section_order: "nf-core-pairgenomealign-methods-description": order: -1000 diff --git a/assets/nf-core-pairgenomealign_logo_light.png b/assets/nf-core-pairgenomealign_logo_light.png index 4f76e1873095164c08bb8ceaae5f08554f2d08fb..eb395e42a1b2775bd420c336e276c7847355618a 100644 GIT binary patch literal 89810 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
{PxC~ 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
h+bKxW?a8j2Ig7ZPHDAWB;2{_AbTAB$Mn+=^ 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

WQQ*`pW5>4xy@I8d<5o-Ok4aOyV!XuG3F z5Cug_BBRJ#51ZWL@ zEXcYaepF?e=ipbdEnkIl*`Tm8r$gwrvyGO!Ocz9~Cu{(1P)%_`bVy3EgW|h+l1eb^ zj-;ruF5q$;E5zw?PK*YmgvCrwnN;&yvOO$D%b%6(F~NKt2IR|waI0Z|j_{@(@3oyn z$X!7X7Ax3Qj&qRc4~v)TirbeNhxmjqi0vEsM1!s&O z@7xdnmz<-ck^sYdr6wMQ!r;H>Ddqq$bipD5_oCXnkp1m%vQ$+F0cp8?Uo&lQNH#jZFfxKin=uaU z%)<~)01NDBZ^@3l0@z`==uX(rUiTB*JolG9ide0~8$FEI8=XgxiY^k5him}72nHw@ zO;8oA*Y%Mt{DRRyaq(RAnp##ps;I_XfHHQ}cI>cw1$9=GTL^Aoz_gyvgQO|&ji|~V zN*{fa@%(8l7W~iHCl1Npqo6DE56^Vna%u8k`yA_v8JobPgTK2GCAcr{)yP>xzc9O!!ZtX^BpE(dKe;m%)#{`NGYbc`veJe z&g03Pc|QG@!!44{S)U*IrnY+vpY6MQDPmp^H{K3dAfo__~OnXnP4`+ke59uH^tFEKdYW^8Gz$CmWNmjd&YVMi5N!ULl8eNy9> z|3CVt6cA`s{YuwH&tTSR?09H*(^x^+K&s(4)q~5J&^|-Kp35R z0z4eG;8+cR4J?&-(PCs&71#hyw^Igq4eR8-wT>VtSf>~l72_Gyx^ zt3e~TP{)>(a9xkLgZFBOQh$aJRkOw58eWCYcS}>GTWNT%1hA zAYt38=c_xKIP=SX?`0vKUOsVH$kdx!kqt;cG-}d(uIz2v0LiPJpu$BtzobnUSnemW z84qDlyH<_)!5%;Oa2-a{GS0VX;njm67+#qmu`=~^+!?}?*W>~2XnN&Biqb+^d^NxW zf3of%-d)iCNzxcR4V6Bb%BzOZr;Uq0o@|m?RrvP2SqJ_;cz#e8Im2JmZ%dj<8FK+Q zXxk}4Zp�D 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 diff --git a/docs/images/mqc_fastqc_quality.png b/docs/images/mqc_fastqc_quality.png deleted file mode 100755 index a4b89bf56ab2ba88cab87841916eb680a816deae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55769 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�)v~C(0C)c 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 M)78&qol`;+0Fu7JivR!s diff --git a/docs/images/nf-core-pairgenomealign_logo_dark.png b/docs/images/nf-core-pairgenomealign_logo_dark.png index 7d2527f77507493425d1c948fb4ecc7d3179f594..f2499ccfcb3ff004c39a225ca47fe116202b09a2 100644 GIT binary patch delta 24116 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 Q?;+sJ)W`}^3-?I;AEBEI>Hq)$ diff --git a/docs/images/nf-core-pairgenomealign_logo_light.png b/docs/images/nf-core-pairgenomealign_logo_light.png index 433d6c9e9a568253aa74b577888ae060cc9f43d3..646ea21e346f7296f24eadf85129351374d8f736 100644 GIT binary patch delta 20076 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 diff --git a/docs/output.md b/docs/output.md index cd1a4b0..df14703 100644 --- a/docs/output.md +++ b/docs/output.md @@ -14,6 +14,7 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d - [FastQC](#fastqc) - Raw read QC - [MultiQC](#multiqc) - Aggregate report describing results and QC from the whole pipeline + - [Pipeline information](#pipeline-information) - Report metrics generated during the workflow execution ### FastQC @@ -29,16 +30,6 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d [FastQC](http://www.bioinformatics.babraham.ac.uk/projects/fastqc/) gives general quality metrics about your sequenced reads. It provides information about the quality score distribution across your reads, per base sequence content (%A/T/G/C), adapter contamination and overrepresented sequences. For further reading and documentation see the [FastQC help pages](http://www.bioinformatics.babraham.ac.uk/projects/fastqc/Help/). -![MultiQC - FastQC sequence counts plot](images/mqc_fastqc_counts.png) - -![MultiQC - FastQC mean quality scores plot](images/mqc_fastqc_quality.png) - -![MultiQC - FastQC adapter content plot](images/mqc_fastqc_adapter.png) - -:::note -The FastQC plots displayed in the MultiQC report shows _untrimmed_ reads. They may contain adapter sequence and potentially regions with low quality. -::: - ### MultiQC

diff --git a/docs/usage.md b/docs/usage.md index c8344d3..1268284 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -85,9 +85,9 @@ The above pipeline run specified with a params file in yaml format: nextflow run nf-core/pairgenomealign -profile docker -params-file params.yaml ``` -with `params.yaml` containing: +with: -```yaml +```yaml title="params.yaml" input: './samplesheet.csv' outdir: './results/' genome: 'GRCh37' @@ -199,14 +199,6 @@ 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/main.nf b/main.nf index 330eb0d..d617a07 100644 --- a/main.nf +++ b/main.nf @@ -9,8 +9,6 @@ ---------------------------------------------------------------------------------------- */ -nextflow.enable.dsl = 2 - /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS / WORKFLOWS @@ -20,7 +18,6 @@ nextflow.enable.dsl = 2 include { PAIRGENOMEALIGN } from './workflows/pairgenomealign' include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_pairgenomealign_pipeline' include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_pairgenomealign_pipeline' - include { getGenomeAttribute } from './subworkflows/local/utils_nfcore_pairgenomealign_pipeline' /* @@ -56,10 +53,8 @@ workflow NFCORE_PAIRGENOMEALIGN { PAIRGENOMEALIGN ( samplesheet ) - emit: multiqc_report = PAIRGENOMEALIGN.out.multiqc_report // channel: /path/to/multiqc_report.html - } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -70,27 +65,24 @@ workflow NFCORE_PAIRGENOMEALIGN { workflow { main: - // // SUBWORKFLOW: Run initialisation tasks // PIPELINE_INITIALISATION ( params.version, - params.help, params.validate_params, params.monochrome_logs, args, params.outdir, params.input ) - + // // WORKFLOW: Run main workflow // NFCORE_PAIRGENOMEALIGN ( PIPELINE_INITIALISATION.out.samplesheet ) - // // SUBWORKFLOW: Run completion tasks // diff --git a/modules.json b/modules.json index 1c35468..d829d44 100644 --- a/modules.json +++ b/modules.json @@ -7,12 +7,12 @@ "nf-core": { "fastqc": { "branch": "master", - "git_sha": "285a50500f9e02578d90b3ce6382ea3c30216acd", + "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", "installed_by": ["modules"] }, "multiqc": { "branch": "master", - "git_sha": "b7ebe95761cd389603f9cc0e0dc384c0f663815a", + "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", "installed_by": ["modules"] } } @@ -21,17 +21,17 @@ "nf-core": { "utils_nextflow_pipeline": { "branch": "master", - "git_sha": "5caf7640a9ef1d18d765d55339be751bb0969dfa", + "git_sha": "d20fb2a9cc3e2835e9d067d1046a63252eb17352", "installed_by": ["subworkflows"] }, "utils_nfcore_pipeline": { "branch": "master", - "git_sha": "92de218a329bfc9a9033116eb5f65fd270e72ba3", + "git_sha": "2fdce49d30c0254f76bc0f13c55c17455c1251ab", "installed_by": ["subworkflows"] }, - "utils_nfvalidation_plugin": { + "utils_nfschema_plugin": { "branch": "master", - "git_sha": "5caf7640a9ef1d18d765d55339be751bb0969dfa", + "git_sha": "bbd5a41f4535a8defafe6080e00ea74c45f4f96c", "installed_by": ["subworkflows"] } } diff --git a/modules/nf-core/fastqc/environment.yml b/modules/nf-core/fastqc/environment.yml index 1787b38..691d4c7 100644 --- a/modules/nf-core/fastqc/environment.yml +++ b/modules/nf-core/fastqc/environment.yml @@ -1,7 +1,5 @@ -name: fastqc channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::fastqc=0.12.1 diff --git a/modules/nf-core/fastqc/main.nf b/modules/nf-core/fastqc/main.nf index d79f1c8..d8989f4 100644 --- a/modules/nf-core/fastqc/main.nf +++ b/modules/nf-core/fastqc/main.nf @@ -26,7 +26,10 @@ process FASTQC { def rename_to = old_new_pairs*.join(' ').join(' ') def renamed_files = old_new_pairs.collect{ old_name, new_name -> new_name }.join(' ') - def memory_in_mb = MemoryUnit.of("${task.memory}").toUnit('MB') + // The total amount of allocated RAM by FastQC is equal to the number of threads defined (--threads) time the amount of RAM defined (--memory) + // /~https://github.com/s-andrews/FastQC/blob/1faeea0412093224d7f6a07f777fad60a5650795/fastqc#L211-L222 + // Dividing the task.memory by task.cpu allows to stick to requested amount of RAM in the label + def memory_in_mb = MemoryUnit.of("${task.memory}").toUnit('MB') / task.cpus // FastQC memory value allowed range (100 - 10000) def fastqc_memory = memory_in_mb > 10000 ? 10000 : (memory_in_mb < 100 ? 100 : memory_in_mb) diff --git a/modules/nf-core/fastqc/meta.yml b/modules/nf-core/fastqc/meta.yml index ee5507e..4827da7 100644 --- a/modules/nf-core/fastqc/meta.yml +++ b/modules/nf-core/fastqc/meta.yml @@ -16,35 +16,44 @@ tools: homepage: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/ documentation: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/Help/ licence: ["GPL-2.0-only"] + identifier: biotools:fastqc input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - reads: - type: file - description: | - List of input FastQ files of size 1 and 2 for single-end and paired-end data, - respectively. + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: | + List of input FastQ files of size 1 and 2 for single-end and paired-end data, + respectively. output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - html: - type: file - description: FastQC report - pattern: "*_{fastqc.html}" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.html": + type: file + description: FastQC report + pattern: "*_{fastqc.html}" - zip: - type: file - description: FastQC report archive - pattern: "*_{fastqc.zip}" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.zip": + type: file + description: FastQC report archive + pattern: "*_{fastqc.zip}" - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - "@drpatelh" - "@grst" diff --git a/modules/nf-core/fastqc/tests/main.nf.test b/modules/nf-core/fastqc/tests/main.nf.test index 70edae4..e9d79a0 100644 --- a/modules/nf-core/fastqc/tests/main.nf.test +++ b/modules/nf-core/fastqc/tests/main.nf.test @@ -23,17 +23,14 @@ nextflow_process { then { assertAll ( - { assert process.success }, - - // NOTE The report contains the date inside it, which means that the md5sum is stable per day, but not longer than that. So you can't md5sum it. - // looks like this:
Mon 2 Oct 2023
test.gz
- // /~https://github.com/nf-core/modules/pull/3903#issuecomment-1743620039 - - { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, - { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, - { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, - - { assert snapshot(process.out.versions).match("fastqc_versions_single") } + { assert process.success }, + // NOTE The report contains the date inside it, which means that the md5sum is stable per day, but not longer than that. So you can't md5sum it. + // looks like this:
Mon 2 Oct 2023
test.gz
+ // /~https://github.com/nf-core/modules/pull/3903#issuecomment-1743620039 + { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, + { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, + { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, + { assert snapshot(process.out.versions).match() } ) } } @@ -54,16 +51,14 @@ nextflow_process { then { assertAll ( - { assert process.success }, - - { assert process.out.html[0][1][0] ==~ ".*/test_1_fastqc.html" }, - { assert process.out.html[0][1][1] ==~ ".*/test_2_fastqc.html" }, - { assert process.out.zip[0][1][0] ==~ ".*/test_1_fastqc.zip" }, - { assert process.out.zip[0][1][1] ==~ ".*/test_2_fastqc.zip" }, - { assert path(process.out.html[0][1][0]).text.contains("File typeConventional base calls") }, - { assert path(process.out.html[0][1][1]).text.contains("File typeConventional base calls") }, - - { assert snapshot(process.out.versions).match("fastqc_versions_paired") } + { assert process.success }, + { assert process.out.html[0][1][0] ==~ ".*/test_1_fastqc.html" }, + { assert process.out.html[0][1][1] ==~ ".*/test_2_fastqc.html" }, + { assert process.out.zip[0][1][0] ==~ ".*/test_1_fastqc.zip" }, + { assert process.out.zip[0][1][1] ==~ ".*/test_2_fastqc.zip" }, + { assert path(process.out.html[0][1][0]).text.contains("File typeConventional base calls") }, + { assert path(process.out.html[0][1][1]).text.contains("File typeConventional base calls") }, + { assert snapshot(process.out.versions).match() } ) } } @@ -83,13 +78,11 @@ nextflow_process { then { assertAll ( - { assert process.success }, - - { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, - { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, - { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, - - { assert snapshot(process.out.versions).match("fastqc_versions_interleaved") } + { assert process.success }, + { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, + { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, + { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, + { assert snapshot(process.out.versions).match() } ) } } @@ -109,13 +102,11 @@ nextflow_process { then { assertAll ( - { assert process.success }, - - { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, - { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, - { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, - - { assert snapshot(process.out.versions).match("fastqc_versions_bam") } + { assert process.success }, + { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, + { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, + { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, + { assert snapshot(process.out.versions).match() } ) } } @@ -138,22 +129,20 @@ nextflow_process { then { assertAll ( - { assert process.success }, - - { assert process.out.html[0][1][0] ==~ ".*/test_1_fastqc.html" }, - { assert process.out.html[0][1][1] ==~ ".*/test_2_fastqc.html" }, - { assert process.out.html[0][1][2] ==~ ".*/test_3_fastqc.html" }, - { assert process.out.html[0][1][3] ==~ ".*/test_4_fastqc.html" }, - { assert process.out.zip[0][1][0] ==~ ".*/test_1_fastqc.zip" }, - { assert process.out.zip[0][1][1] ==~ ".*/test_2_fastqc.zip" }, - { assert process.out.zip[0][1][2] ==~ ".*/test_3_fastqc.zip" }, - { assert process.out.zip[0][1][3] ==~ ".*/test_4_fastqc.zip" }, - { assert path(process.out.html[0][1][0]).text.contains("File typeConventional base calls") }, - { assert path(process.out.html[0][1][1]).text.contains("File typeConventional base calls") }, - { assert path(process.out.html[0][1][2]).text.contains("File typeConventional base calls") }, - { assert path(process.out.html[0][1][3]).text.contains("File typeConventional base calls") }, - - { assert snapshot(process.out.versions).match("fastqc_versions_multiple") } + { assert process.success }, + { assert process.out.html[0][1][0] ==~ ".*/test_1_fastqc.html" }, + { assert process.out.html[0][1][1] ==~ ".*/test_2_fastqc.html" }, + { assert process.out.html[0][1][2] ==~ ".*/test_3_fastqc.html" }, + { assert process.out.html[0][1][3] ==~ ".*/test_4_fastqc.html" }, + { assert process.out.zip[0][1][0] ==~ ".*/test_1_fastqc.zip" }, + { assert process.out.zip[0][1][1] ==~ ".*/test_2_fastqc.zip" }, + { assert process.out.zip[0][1][2] ==~ ".*/test_3_fastqc.zip" }, + { assert process.out.zip[0][1][3] ==~ ".*/test_4_fastqc.zip" }, + { assert path(process.out.html[0][1][0]).text.contains("File typeConventional base calls") }, + { assert path(process.out.html[0][1][1]).text.contains("File typeConventional base calls") }, + { assert path(process.out.html[0][1][2]).text.contains("File typeConventional base calls") }, + { assert path(process.out.html[0][1][3]).text.contains("File typeConventional base calls") }, + { assert snapshot(process.out.versions).match() } ) } } @@ -173,21 +162,18 @@ nextflow_process { then { assertAll ( - { assert process.success }, - - { assert process.out.html[0][1] ==~ ".*/mysample_fastqc.html" }, - { assert process.out.zip[0][1] ==~ ".*/mysample_fastqc.zip" }, - { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, - - { assert snapshot(process.out.versions).match("fastqc_versions_custom_prefix") } + { assert process.success }, + { assert process.out.html[0][1] ==~ ".*/mysample_fastqc.html" }, + { assert process.out.zip[0][1] ==~ ".*/mysample_fastqc.zip" }, + { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, + { assert snapshot(process.out.versions).match() } ) } } test("sarscov2 single-end [fastq] - stub") { - options "-stub" - + options "-stub" when { process { """ @@ -201,12 +187,123 @@ nextflow_process { then { assertAll ( - { assert process.success }, - { assert snapshot(process.out.html.collect { file(it[1]).getName() } + - process.out.zip.collect { file(it[1]).getName() } + - process.out.versions ).match("fastqc_stub") } + { assert process.success }, + { assert snapshot(process.out).match() } ) } } + test("sarscov2 paired-end [fastq] - stub") { + + options "-stub" + when { + process { + """ + input[0] = Channel.of([ + [id: 'test', single_end: false], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 interleaved [fastq] - stub") { + + options "-stub" + when { + process { + """ + input[0] = Channel.of([ + [id: 'test', single_end: false], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_interleaved.fastq.gz', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 paired-end [bam] - stub") { + + options "-stub" + when { + process { + """ + input[0] = Channel.of([ + [id: 'test', single_end: false], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 multiple [fastq] - stub") { + + options "-stub" + when { + process { + """ + input[0] = Channel.of([ + [id: 'test', single_end: false], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_2.fastq.gz', checkIfExists: true) ] + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 custom_prefix - stub") { + + options "-stub" + when { + process { + """ + input[0] = Channel.of([ + [ id:'mysample', single_end:true ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } } diff --git a/modules/nf-core/fastqc/tests/main.nf.test.snap b/modules/nf-core/fastqc/tests/main.nf.test.snap index 86f7c31..d5db309 100644 --- a/modules/nf-core/fastqc/tests/main.nf.test.snap +++ b/modules/nf-core/fastqc/tests/main.nf.test.snap @@ -1,88 +1,392 @@ { - "fastqc_versions_interleaved": { + "sarscov2 custom_prefix": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:40:07.293713" + "timestamp": "2024-07-22T11:02:16.374038" }, - "fastqc_stub": { + "sarscov2 single-end [fastq] - stub": { "content": [ - [ - "test.html", - "test.zip", - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" - ] + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "test", + "single_end": true + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "test", + "single_end": true + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:02:24.993809" + }, + "sarscov2 custom_prefix - stub": { + "content": [ + { + "0": [ + [ + { + "id": "mysample", + "single_end": true + }, + "mysample.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "mysample", + "single_end": true + }, + "mysample.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "mysample", + "single_end": true + }, + "mysample.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "mysample", + "single_end": true + }, + "mysample.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:31:01.425198" + "timestamp": "2024-07-22T11:03:10.93942" }, - "fastqc_versions_multiple": { + "sarscov2 interleaved [fastq]": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:40:55.797907" + "timestamp": "2024-07-22T11:01:42.355718" }, - "fastqc_versions_bam": { + "sarscov2 paired-end [bam]": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:40:26.795862" + "timestamp": "2024-07-22T11:01:53.276274" }, - "fastqc_versions_single": { + "sarscov2 multiple [fastq]": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:39:27.043675" + "timestamp": "2024-07-22T11:02:05.527626" }, - "fastqc_versions_paired": { + "sarscov2 paired-end [fastq]": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:01:31.188871" + }, + "sarscov2 paired-end [fastq] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:02:34.273566" + }, + "sarscov2 multiple [fastq] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:39:47.584191" + "timestamp": "2024-07-22T11:03:02.304411" }, - "fastqc_versions_custom_prefix": { + "sarscov2 single-end [fastq]": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:01:19.095607" + }, + "sarscov2 interleaved [fastq] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:02:44.640184" + }, + "sarscov2 paired-end [bam] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:41:14.576531" + "timestamp": "2024-07-22T11:02:53.550742" } } \ No newline at end of file diff --git a/modules/nf-core/multiqc/environment.yml b/modules/nf-core/multiqc/environment.yml index ca39fb6..f1cd99b 100644 --- a/modules/nf-core/multiqc/environment.yml +++ b/modules/nf-core/multiqc/environment.yml @@ -1,7 +1,5 @@ -name: multiqc channels: - conda-forge - bioconda - - defaults dependencies: - - bioconda::multiqc=1.21 + - bioconda::multiqc=1.24.1 diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index 47ac352..b9ccebd 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -3,14 +3,16 @@ process MULTIQC { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.21--pyhdfd78af_0' : - 'biocontainers/multiqc:1.21--pyhdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/multiqc:1.25--pyhdfd78af_0' : + 'biocontainers/multiqc:1.25--pyhdfd78af_0' }" input: path multiqc_files, stageAs: "?/*" path(multiqc_config) path(extra_multiqc_config) path(multiqc_logo) + path(replace_names) + path(sample_names) output: path "*multiqc_report.html", emit: report @@ -23,16 +25,22 @@ process MULTIQC { script: def args = task.ext.args ?: '' + def prefix = task.ext.prefix ? "--filename ${task.ext.prefix}.html" : '' def config = multiqc_config ? "--config $multiqc_config" : '' def extra_config = extra_multiqc_config ? "--config $extra_multiqc_config" : '' - def logo = multiqc_logo ? /--cl-config 'custom_logo: "${multiqc_logo}"'/ : '' + def logo = multiqc_logo ? "--cl-config 'custom_logo: \"${multiqc_logo}\"'" : '' + def replace = replace_names ? "--replace-names ${replace_names}" : '' + def samples = sample_names ? "--sample-names ${sample_names}" : '' """ multiqc \\ --force \\ $args \\ $config \\ + $prefix \\ $extra_config \\ $logo \\ + $replace \\ + $samples \\ . cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/multiqc/meta.yml b/modules/nf-core/multiqc/meta.yml index 45a9bc3..b16c187 100644 --- a/modules/nf-core/multiqc/meta.yml +++ b/modules/nf-core/multiqc/meta.yml @@ -1,5 +1,6 @@ name: multiqc -description: Aggregate results from bioinformatics analyses across many samples into a single report +description: Aggregate results from bioinformatics analyses across many samples into + a single report keywords: - QC - bioinformatics tools @@ -12,40 +13,59 @@ tools: homepage: https://multiqc.info/ documentation: https://multiqc.info/docs/ licence: ["GPL-3.0-or-later"] + identifier: biotools:multiqc 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}" + - - 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}" + - - replace_names: + type: file + description: | + Optional two-column sample renaming file. First column a set of + patterns, second column a set of corresponding replacements. Passed via + MultiQC's `--replace-names` option. + pattern: "*.{tsv}" + - - sample_names: + type: file + description: | + Optional TSV file with headers, passed to the MultiQC --sample_names + argument. + pattern: "*.{tsv}" output: - report: - type: file - description: MultiQC report file - pattern: "multiqc_report.html" + - "*multiqc_report.html": + type: file + description: MultiQC report file + pattern: "multiqc_report.html" - data: - type: directory - description: MultiQC data dir - pattern: "multiqc_data" + - "*_data": + type: directory + description: MultiQC data dir + pattern: "multiqc_data" - plots: - type: file - description: Plots created by MultiQC - pattern: "*_data" + - "*_plots": + type: file + description: Plots created by MultiQC + pattern: "*_data" - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - "@abhi18av" - "@bunop" diff --git a/modules/nf-core/multiqc/tests/main.nf.test b/modules/nf-core/multiqc/tests/main.nf.test index f1c4242..33316a7 100644 --- a/modules/nf-core/multiqc/tests/main.nf.test +++ b/modules/nf-core/multiqc/tests/main.nf.test @@ -8,6 +8,8 @@ nextflow_process { tag "modules_nfcore" tag "multiqc" + config "./nextflow.config" + test("sarscov2 single-end [fastqc]") { when { @@ -17,6 +19,8 @@ nextflow_process { input[1] = [] input[2] = [] input[3] = [] + input[4] = [] + input[5] = [] """ } } @@ -41,6 +45,8 @@ nextflow_process { input[1] = Channel.of(file("/~https://github.com/nf-core/tools/raw/dev/nf_core/pipeline-template/assets/multiqc_config.yml", checkIfExists: true)) input[2] = [] input[3] = [] + input[4] = [] + input[5] = [] """ } } @@ -66,6 +72,8 @@ nextflow_process { input[1] = [] input[2] = [] input[3] = [] + input[4] = [] + input[5] = [] """ } } diff --git a/modules/nf-core/multiqc/tests/main.nf.test.snap b/modules/nf-core/multiqc/tests/main.nf.test.snap index bfebd80..b779e46 100644 --- a/modules/nf-core/multiqc/tests/main.nf.test.snap +++ b/modules/nf-core/multiqc/tests/main.nf.test.snap @@ -2,14 +2,14 @@ "multiqc_versions_single": { "content": [ [ - "versions.yml:md5,21f35ee29416b9b3073c28733efe4b7d" + "versions.yml:md5,8c8724363a5efe0c6f43ab34faa57efd" ] ], "meta": { "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nextflow": "24.04.2" }, - "timestamp": "2024-02-29T08:48:55.657331" + "timestamp": "2024-07-10T12:41:34.562023" }, "multiqc_stub": { "content": [ @@ -17,25 +17,25 @@ "multiqc_report.html", "multiqc_data", "multiqc_plots", - "versions.yml:md5,21f35ee29416b9b3073c28733efe4b7d" + "versions.yml:md5,8c8724363a5efe0c6f43ab34faa57efd" ] ], "meta": { "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nextflow": "24.04.2" }, - "timestamp": "2024-02-29T08:49:49.071937" + "timestamp": "2024-07-10T11:27:11.933869532" }, "multiqc_versions_config": { "content": [ [ - "versions.yml:md5,21f35ee29416b9b3073c28733efe4b7d" + "versions.yml:md5,8c8724363a5efe0c6f43ab34faa57efd" ] ], "meta": { "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nextflow": "24.04.2" }, - "timestamp": "2024-02-29T08:49:25.457567" + "timestamp": "2024-07-10T11:26:56.709849369" } -} \ No newline at end of file +} diff --git a/modules/nf-core/multiqc/tests/nextflow.config b/modules/nf-core/multiqc/tests/nextflow.config new file mode 100644 index 0000000..c537a6a --- /dev/null +++ b/modules/nf-core/multiqc/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'MULTIQC' { + ext.prefix = null + } +} diff --git a/nextflow.config b/nextflow.config index 5242373..5e5003e 100644 --- a/nextflow.config +++ b/nextflow.config @@ -16,7 +16,6 @@ params { genome = null igenomes_base = 's3://ngi-igenomes/igenomes/' igenomes_ignore = false - // MultiQC options multiqc_config = null multiqc_title = null @@ -33,48 +32,26 @@ params { monochrome_logs = false hook_url = null help = false + help_full = false + show_hidden = false version = false pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/' - // Config options config_profile_name = null config_profile_description = null + custom_config_version = 'master' custom_config_base = "https://raw.githubusercontent.com/nf-core/configs/${params.custom_config_version}" config_profile_contact = null config_profile_url = null - - // Max resource options - // Defaults only, expecting to be overwritten - max_memory = '128.GB' - max_cpus = 16 - max_time = '240.h' - // Schema validation default options - validationFailUnrecognisedParams = false - validationLenientMode = false - validationSchemaIgnoreParams = 'genomes,igenomes_base' - validationShowHiddenParams = false - validate_params = true - + validate_params = true + } // Load base.config by default for all pipelines includeConfig 'conf/base.config' -// Load nf-core custom profiles from different Institutions -try { - includeConfig "${params.custom_config_base}/nfcore_custom.config" -} catch (Exception e) { - System.err.println("WARNING: Could not load nf-core/config profiles: ${params.custom_config_base}/nfcore_custom.config") -} - -// Load nf-core/pairgenomealign custom profiles from different institutions. -try { - includeConfig "${params.custom_config_base}/pipeline/pairgenomealign.config" -} catch (Exception e) { - System.err.println("WARNING: Could not load nf-core/config/pairgenomealign profiles: ${params.custom_config_base}/pipeline/pairgenomealign.config") -} profiles { debug { dumpHashes = true @@ -89,7 +66,7 @@ profiles { podman.enabled = false shifter.enabled = false charliecloud.enabled = false - conda.channels = ['conda-forge', 'bioconda', 'defaults'] + conda.channels = ['conda-forge', 'bioconda'] apptainer.enabled = false } mamba { @@ -178,25 +155,23 @@ profiles { test_full { includeConfig 'conf/test_full.config' } } -// Set default registry for Apptainer, Docker, Podman and Singularity independent of -profile -// Will not be used unless Apptainer / Docker / Podman / Singularity are enabled -// Set to your registry if you have a mirror of containers -apptainer.registry = 'quay.io' -docker.registry = 'quay.io' -podman.registry = 'quay.io' -singularity.registry = 'quay.io' +// Load nf-core custom profiles from different Institutions +includeConfig !System.getenv('NXF_OFFLINE') && params.custom_config_base ? "${params.custom_config_base}/nfcore_custom.config" : "/dev/null" -// Nextflow plugins -plugins { - id 'nf-validation@1.1.3' // Validation of pipeline parameters and creation of an input channel from a sample sheet -} +// Load nf-core/pairgenomealign custom profiles from different institutions. +// TODO nf-core: Optionally, you can add a pipeline-specific nf-core config at /~https://github.com/nf-core/configs +// includeConfig !System.getenv('NXF_OFFLINE') && params.custom_config_base ? "${params.custom_config_base}/pipeline/pairgenomealign.config" : "/dev/null" +// Set default registry for Apptainer, Docker, Podman, Charliecloud and Singularity independent of -profile +// Will not be used unless Apptainer / Docker / Podman / Charliecloud / Singularity are enabled +// Set to your registry if you have a mirror of containers +apptainer.registry = 'quay.io' +docker.registry = 'quay.io' +podman.registry = 'quay.io' +singularity.registry = 'quay.io' +charliecloud.registry = 'quay.io' // Load igenomes.config if required -if (!params.igenomes_ignore) { - includeConfig 'conf/igenomes.config' -} else { - params.genomes = [:] -} +includeConfig !params.igenomes_ignore ? 'conf/igenomes.config' : 'conf/igenomes_ignored.config' // 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. @@ -208,8 +183,15 @@ env { JULIA_DEPOT_PATH = "/usr/local/share/julia" } -// Capture exit codes from upstream processes when piping -process.shell = ['/bin/bash', '-euo', 'pipefail'] +// Set bash options +process.shell = """\ +bash + +set -e # Exit if a tool returns a non-zero status/exit code +set -u # Treat unset variables and parameters as an error +set -o pipefail # Returns the status of the last command to exit with a non-zero status or zero if all successfully execute +set -C # No clobber - prevent output redirection from overwriting files. +""" // Disable process selector warnings by default. Use debug profile to enable warnings. nextflow.enable.configProcessNamesValidation = false @@ -238,43 +220,47 @@ manifest { homePage = '/~https://github.com/nf-core/pairgenomealign' description = """Pairwise alignment pipeline (genome to genome or reads to genome)""" mainScript = 'main.nf' - nextflowVersion = '!>=23.04.0' - version = '1.0dev' + nextflowVersion = '!>=24.04.2' + version = '1.1.0' doi = '' } -// Load modules.config for DSL2 module specific options -includeConfig 'conf/modules.config' +// Nextflow plugins +plugins { + id 'nf-schema@2.1.1' // Validation of pipeline parameters and creation of an input channel from a sample sheet +} + +validation { + defaultIgnoreParams = ["genomes"] + help { + enabled = true + command = "nextflow run $manifest.name -profile --input samplesheet.csv --outdir " + fullParameter = "help_full" + showHiddenParameter = "show_hidden" + beforeText = """ +-\033[2m----------------------------------------------------\033[0m- + \033[0;32m,--.\033[0;30m/\033[0;32m,-.\033[0m +\033[0;34m ___ __ __ __ ___ \033[0;32m/,-._.--~\'\033[0m +\033[0;34m |\\ | |__ __ / ` / \\ |__) |__ \033[0;33m} {\033[0m +\033[0;34m | \\| | \\__, \\__/ | \\ |___ \033[0;32m\\`-._,-`-,\033[0m + \033[0;32m`._,._,\'\033[0m +\033[0;35m ${manifest.name} ${manifest.version}\033[0m +-\033[2m----------------------------------------------------\033[0m- +""" + afterText = """${manifest.doi ? "* The pipeline\n" : ""}${manifest.doi.tokenize(",").collect { " https://doi.org/${it.trim().replace('https://doi.org/','')}"}.join("\n")}${manifest.doi ? "\n" : ""} +* The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x -// Function to ensure that resource requirements don't go beyond -// a maximum limit -def check_max(obj, type) { - if (type == 'memory') { - try { - if (obj.compareTo(params.max_memory as nextflow.util.MemoryUnit) == 1) - return params.max_memory as nextflow.util.MemoryUnit - else - return obj - } catch (all) { - println " ### ERROR ### Max memory '${params.max_memory}' is not valid! Using default value: $obj" - return obj - } - } else if (type == 'time') { - try { - if (obj.compareTo(params.max_time as nextflow.util.Duration) == 1) - return params.max_time as nextflow.util.Duration - else - return obj - } catch (all) { - println " ### ERROR ### Max time '${params.max_time}' is not valid! Using default value: $obj" - return obj - } - } else if (type == 'cpus') { - try { - return Math.min( obj, params.max_cpus as int ) - } catch (all) { - println " ### ERROR ### Max cpus '${params.max_cpus}' is not valid! Using default value: $obj" - return obj - } +* Software dependencies + /~https://github.com/${manifest.name}/blob/master/CITATIONS.md +""" + } + summary { + beforeText = validation.help.beforeText + afterText = validation.help.afterText } } + +// Load modules.config for DSL2 module specific options +includeConfig 'conf/modules.config' + diff --git a/nextflow_schema.json b/nextflow_schema.json index c3c84b9..ab272cb 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -1,10 +1,10 @@ { - "$schema": "http://json-schema.org/draft-07/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://raw.githubusercontent.com/nf-core/pairgenomealign/master/nextflow_schema.json", "title": "nf-core/pairgenomealign pipeline parameters", "description": "Pairwise alignment pipeline (genome to genome or reads to genome)", "type": "object", - "definitions": { + "$defs": { "input_output_options": { "title": "Input/output options", "type": "object", @@ -71,6 +71,14 @@ "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`." + }, + "igenomes_base": { + "type": "string", + "format": "directory-path", + "description": "The base path to the igenomes reference files", + "fa_icon": "fas fa-ban", + "hidden": true, + "default": "s3://ngi-igenomes/igenomes/" } } }, @@ -122,41 +130,6 @@ } } }, - "max_job_request_options": { - "title": "Max job request options", - "type": "object", - "fa_icon": "fab fa-acquisitions-incorporated", - "description": "Set the top limit for requested resources for any single job.", - "help_text": "If you are running on a smaller system, a pipeline step requesting more resources than are available may cause the Nextflow to stop the run with an error. These options allow you to cap the maximum resources requested by any single job so that the pipeline will run on your system.\n\nNote that you can not _increase_ the resources requested by any job using these options. For that you will need your own configuration file. See [the nf-core website](https://nf-co.re/usage/configuration) for details.", - "properties": { - "max_cpus": { - "type": "integer", - "description": "Maximum number of CPUs that can be requested for any single job.", - "default": 16, - "fa_icon": "fas fa-microchip", - "hidden": true, - "help_text": "Use to set an upper-limit for the CPU requirement for each process. Should be an integer e.g. `--max_cpus 1`" - }, - "max_memory": { - "type": "string", - "description": "Maximum amount of memory that can be requested for any single job.", - "default": "128.GB", - "fa_icon": "fas fa-memory", - "pattern": "^\\d+(\\.\\d+)?\\.?\\s*(K|M|G|T)?B$", - "hidden": true, - "help_text": "Use to set an upper-limit for the memory requirement for each process. Should be a string in the format integer-unit e.g. `--max_memory '8.GB'`" - }, - "max_time": { - "type": "string", - "description": "Maximum amount of time that can be requested for any single job.", - "default": "240.h", - "fa_icon": "far fa-clock", - "pattern": "^(\\d+\\.?\\s*(s|m|h|d|day)\\s*)+$", - "hidden": true, - "help_text": "Use to set an upper-limit for the time requirement for each process. Should be a string in the format integer-unit e.g. `--max_time '2.h'`" - } - } - }, "generic_options": { "title": "Generic options", "type": "object", @@ -164,12 +137,6 @@ "description": "Less common options for the pipeline, typically set in a config file.", "help_text": "These options are common to all nf-core pipelines and allow you to customise some of the core preferences for how the pipeline runs.\n\nTypically these options would be set in a Nextflow config file loaded for all pipeline runs, such as `~/.nextflow/config`.", "properties": { - "help": { - "type": "boolean", - "description": "Display help text.", - "fa_icon": "fas fa-question-circle", - "hidden": true - }, "version": { "type": "boolean", "description": "Display version and exit.", @@ -245,27 +212,6 @@ "fa_icon": "fas fa-check-square", "hidden": true }, - "validationShowHiddenParams": { - "type": "boolean", - "fa_icon": "far fa-eye-slash", - "description": "Show all params when using `--help`", - "hidden": true, - "help_text": "By default, parameters set as _hidden_ in the schema are not shown on the command line when a user runs with `--help`. Specifying this option will tell the pipeline to show all parameters." - }, - "validationFailUnrecognisedParams": { - "type": "boolean", - "fa_icon": "far fa-check-circle", - "description": "Validation of parameters fails when an unrecognised parameter is found.", - "hidden": true, - "help_text": "By default, when an unrecognised parameter is found, it returns a warinig." - }, - "validationLenientMode": { - "type": "boolean", - "fa_icon": "far fa-check-circle", - "description": "Validation of parameters in lenient more.", - "hidden": true, - "help_text": "Allows string values that are parseable as numbers or booleans. For further information see [JSONSchema docs](/~https://github.com/everit-org/json-schema#lenient-mode)." - }, "pipelines_testdata_base_path": { "type": "string", "fa_icon": "far fa-check-circle", @@ -278,19 +224,16 @@ }, "allOf": [ { - "$ref": "#/definitions/input_output_options" - }, - { - "$ref": "#/definitions/reference_genome_options" + "$ref": "#/$defs/input_output_options" }, { - "$ref": "#/definitions/institutional_config_options" + "$ref": "#/$defs/reference_genome_options" }, { - "$ref": "#/definitions/max_job_request_options" + "$ref": "#/$defs/institutional_config_options" }, { - "$ref": "#/definitions/generic_options" + "$ref": "#/$defs/generic_options" } ] } diff --git a/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf b/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf index 87776d4..a96b588 100644 --- a/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf @@ -8,17 +8,14 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -include { UTILS_NFVALIDATION_PLUGIN } from '../../nf-core/utils_nfvalidation_plugin' -include { paramsSummaryMap } from 'plugin/nf-validation' -include { fromSamplesheet } from 'plugin/nf-validation' -include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' +include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' include { completionEmail } from '../../nf-core/utils_nfcore_pipeline' include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' -include { dashedLine } from '../../nf-core/utils_nfcore_pipeline' -include { nfCoreLogo } from '../../nf-core/utils_nfcore_pipeline' include { imNotification } from '../../nf-core/utils_nfcore_pipeline' include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' -include { workflowCitation } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' /* ======================================================================================== @@ -30,7 +27,6 @@ workflow PIPELINE_INITIALISATION { take: version // boolean: Display version and exit - help // boolean: Display help text validate_params // boolean: Boolean whether to validate parameters against the schema at runtime monochrome_logs // boolean: Do not use coloured log outputs nextflow_cli_args // array: List of positional nextflow CLI args @@ -51,20 +47,16 @@ workflow PIPELINE_INITIALISATION { workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1 ) + // // Validate parameters and generate parameter summary to stdout // - pre_help_text = nfCoreLogo(monochrome_logs) - post_help_text = '\n' + workflowCitation() + '\n' + dashedLine(monochrome_logs) - def String workflow_command = "nextflow run ${workflow.manifest.name} -profile --input samplesheet.csv --outdir " - UTILS_NFVALIDATION_PLUGIN ( - help, - workflow_command, - pre_help_text, - post_help_text, + UTILS_NFSCHEMA_PLUGIN ( + workflow, validate_params, - "nextflow_schema.json" + null ) + // // Check config provided to the pipeline @@ -80,8 +72,9 @@ workflow PIPELINE_INITIALISATION { // // Create channel from input file provided through params.input // + Channel - .fromSamplesheet("input") + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) .map { meta, fastq_1, fastq_2 -> if (!fastq_2) { @@ -91,8 +84,8 @@ workflow PIPELINE_INITIALISATION { } } .groupTuple() - .map { - validateInputSamplesheet(it) + .map { samplesheet -> + validateInputSamplesheet(samplesheet) } .map { meta, fastqs -> @@ -117,13 +110,13 @@ workflow PIPELINE_COMPLETION { email // string: email address email_on_fail // string: email address sent on pipeline failure plaintext_email // boolean: Send plain-text email instead of HTML + outdir // path: Path to output directory where results will be published monochrome_logs // boolean: Disable ANSI colour codes in log output hook_url // string: hook URL for notifications multiqc_report // string: Path to MultiQC report main: - summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") // @@ -131,11 +124,18 @@ workflow PIPELINE_COMPLETION { // workflow.onComplete { if (email || email_on_fail) { - completionEmail(summary_params, email, email_on_fail, plaintext_email, outdir, monochrome_logs, multiqc_report.toList()) + completionEmail( + summary_params, + email, + email_on_fail, + plaintext_email, + outdir, + monochrome_logs, + multiqc_report.toList() + ) } completionSummary(monochrome_logs) - if (hook_url) { imNotification(summary_params, hook_url) } @@ -165,7 +165,7 @@ def validateInputSamplesheet(input) { def (metas, fastqs) = input[1..2] // Check that multiple runs of the same sample are of the same datatype i.e. single-end / paired-end - def endedness_ok = metas.collect{ it.single_end }.unique().size == 1 + def endedness_ok = metas.collect{ meta -> meta.single_end }.unique().size == 1 if (!endedness_ok) { error("Please check input samplesheet -> Multiple runs of a sample must be of the same datatype i.e. single-end or paired-end: ${metas[0].id}") } @@ -197,7 +197,6 @@ def genomeExistsError() { error(error_string) } } - // // Generate methods description for MultiQC // @@ -239,8 +238,10 @@ def methodsDescriptionText(mqc_methods_yaml) { // Removing `https://doi.org/` to handle pipelines using DOIs vs DOI resolvers // Removing ` ` since the manifest.doi is a string and not a proper list def temp_doi_ref = "" - String[] manifest_doi = meta.manifest_map.doi.tokenize(",") - for (String doi_ref: manifest_doi) temp_doi_ref += "(doi:
${doi_ref.replace("https://doi.org/", "").replace(" ", "")}), " + def manifest_doi = meta.manifest_map.doi.tokenize(",") + manifest_doi.each { doi_ref -> + temp_doi_ref += "(doi: ${doi_ref.replace("https://doi.org/", "").replace(" ", "")}), " + } meta["doi_text"] = temp_doi_ref.substring(0, temp_doi_ref.length() - 2) } else meta["doi_text"] = "" 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.
  • " @@ -261,3 +262,4 @@ def methodsDescriptionText(mqc_methods_yaml) { return description_html.toString() } + diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf index ac31f28..28e32b2 100644 --- a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf @@ -2,10 +2,6 @@ // Subworkflow with functionality that may be useful for any Nextflow pipeline // -import org.yaml.snakeyaml.Yaml -import groovy.json.JsonOutput -import nextflow.extension.FilesEx - /* ======================================================================================== SUBWORKFLOW DEFINITION @@ -58,7 +54,7 @@ workflow UTILS_NEXTFLOW_PIPELINE { // Generate version string // def getWorkflowVersion() { - String version_string = "" + def version_string = "" as String if (workflow.manifest.version) { def prefix_v = workflow.manifest.version[0] != 'v' ? 'v' : '' version_string += "${prefix_v}${workflow.manifest.version}" @@ -79,10 +75,10 @@ def dumpParametersToJSON(outdir) { def timestamp = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss') def filename = "params_${timestamp}.json" def temp_pf = new File(workflow.launchDir.toString(), ".${filename}") - def jsonStr = JsonOutput.toJson(params) - temp_pf.text = JsonOutput.prettyPrint(jsonStr) + def jsonStr = groovy.json.JsonOutput.toJson(params) + temp_pf.text = groovy.json.JsonOutput.prettyPrint(jsonStr) - FilesEx.copyTo(temp_pf.toPath(), "${outdir}/pipeline_info/params_${timestamp}.json") + nextflow.extension.FilesEx.copyTo(temp_pf.toPath(), "${outdir}/pipeline_info/params_${timestamp}.json") temp_pf.delete() } @@ -90,7 +86,7 @@ def dumpParametersToJSON(outdir) { // When running with -profile conda, warn if channels have not been set-up appropriately // def checkCondaChannels() { - Yaml parser = new Yaml() + def parser = new org.yaml.snakeyaml.Yaml() def channels = [] try { def config = parser.load("conda config --show channels".execute().text) @@ -102,14 +98,16 @@ def checkCondaChannels() { // Check that all channels are present // This channel list is ordered by required channel priority. - def required_channels_in_order = ['conda-forge', 'bioconda', 'defaults'] + def required_channels_in_order = ['conda-forge', 'bioconda'] def channels_missing = ((required_channels_in_order as Set) - (channels as Set)) as Boolean // Check that they are in the right order 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])) + + required_channels_in_order.eachWithIndex { channel, index -> + if (index < required_channels_in_order.size() - 1) { + channel_priority_violation |= !(channels.indexOf(channel) < channels.indexOf(required_channels_in_order[index+1])) + } } if (channels_missing | channel_priority_violation) { diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config b/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config index d0a926b..a09572e 100644 --- a/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config +++ b/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config @@ -3,7 +3,7 @@ manifest { author = """nf-core""" homePage = 'https://127.0.0.1' description = """Dummy pipeline""" - nextflowVersion = '!>=23.04.0' + nextflowVersion = '!>=23.04.0' version = '9.9.9' doi = 'https://doi.org/10.5281/zenodo.5070524' } diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf index 14558c3..cbd8495 100644 --- a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf @@ -2,9 +2,6 @@ // Subworkflow with utility functions specific to the nf-core pipeline template // -import org.yaml.snakeyaml.Yaml -import nextflow.extension.FilesEx - /* ======================================================================================== SUBWORKFLOW DEFINITION @@ -34,7 +31,7 @@ workflow UTILS_NFCORE_PIPELINE { // Warn if a -profile or Nextflow config has not been provided to run the pipeline // def checkConfigProvided() { - valid_config = true + def valid_config = true as Boolean if (workflow.profile == 'standard' && workflow.configFiles.size() <= 1) { log.warn "[$workflow.manifest.name] You are attempting to run the pipeline without any custom configuration!\n\n" + "This will be dependent on your local compute environment but can be achieved via one or more of the following:\n" + @@ -66,11 +63,13 @@ def checkProfileProvided(nextflow_cli_args) { // def workflowCitation() { def temp_doi_ref = "" - String[] manifest_doi = workflow.manifest.doi.tokenize(",") + def manifest_doi = workflow.manifest.doi.tokenize(",") // Using a loop to handle multiple DOIs // Removing `https://doi.org/` to handle pipelines using DOIs vs DOI resolvers // Removing ` ` since the manifest.doi is a string and not a proper list - for (String doi_ref: manifest_doi) temp_doi_ref += " https://doi.org/${doi_ref.replace('https://doi.org/', '').replace(' ', '')}\n" + manifest_doi.each { doi_ref -> + temp_doi_ref += " https://doi.org/${doi_ref.replace('https://doi.org/', '').replace(' ', '')}\n" + } return "If you use ${workflow.manifest.name} for your analysis please cite:\n\n" + "* The pipeline\n" + temp_doi_ref + "\n" + @@ -84,7 +83,7 @@ def workflowCitation() { // Generate workflow version string // def getWorkflowVersion() { - String version_string = "" + def version_string = "" as String if (workflow.manifest.version) { def prefix_v = workflow.manifest.version[0] != 'v' ? 'v' : '' version_string += "${prefix_v}${workflow.manifest.version}" @@ -102,8 +101,8 @@ def getWorkflowVersion() { // Get software versions for pipeline // def processVersionsFromYAML(yaml_file) { - Yaml yaml = new Yaml() - versions = yaml.load(yaml_file).collectEntries { k, v -> [ k.tokenize(':')[-1], v ] } + def yaml = new org.yaml.snakeyaml.Yaml() + def versions = yaml.load(yaml_file).collectEntries { k, v -> [ k.tokenize(':')[-1], v ] } return yaml.dumpAsMap(versions).trim() } @@ -124,7 +123,7 @@ def workflowVersionToYAML() { def softwareVersionsToYAML(ch_versions) { return ch_versions .unique() - .map { processVersionsFromYAML(it) } + .map { version -> processVersionsFromYAML(version) } .unique() .mix(Channel.of(workflowVersionToYAML())) } @@ -134,19 +133,19 @@ def softwareVersionsToYAML(ch_versions) { // def paramsSummaryMultiqc(summary_params) { def summary_section = '' - for (group in summary_params.keySet()) { + summary_params.keySet().each { group -> def group_params = summary_params.get(group) // This gets the parameters of that particular group if (group_params) { summary_section += "

    $group

    \n" summary_section += "
    \n" - for (param in group_params.keySet()) { + group_params.keySet().sort().each { param -> summary_section += "
    $param
    ${group_params.get(param) ?: 'N/A'}
    \n" } summary_section += "
    \n" } } - String yaml_file_text = "id: '${workflow.manifest.name.replace('/','-')}-summary'\n" + def yaml_file_text = "id: '${workflow.manifest.name.replace('/','-')}-summary'\n" as String yaml_file_text += "description: ' - this information is collected when the pipeline is started.'\n" yaml_file_text += "section_name: '${workflow.manifest.name} Workflow Summary'\n" yaml_file_text += "section_href: '/~https://github.com/${workflow.manifest.name}'\n" @@ -161,7 +160,7 @@ def paramsSummaryMultiqc(summary_params) { // nf-core logo // def nfCoreLogo(monochrome_logs=true) { - Map colors = logColours(monochrome_logs) + def colors = logColours(monochrome_logs) as Map String.format( """\n ${dashedLine(monochrome_logs)} @@ -180,7 +179,7 @@ def nfCoreLogo(monochrome_logs=true) { // Return dashed line // def dashedLine(monochrome_logs=true) { - Map colors = logColours(monochrome_logs) + def colors = logColours(monochrome_logs) as Map return "-${colors.dim}----------------------------------------------------${colors.reset}-" } @@ -188,7 +187,7 @@ def dashedLine(monochrome_logs=true) { // ANSII colours used for terminal logging // def logColours(monochrome_logs=true) { - Map colorcodes = [:] + def colorcodes = [:] as Map // Reset / Meta colorcodes['reset'] = monochrome_logs ? '' : "\033[0m" @@ -287,7 +286,7 @@ def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdi } def summary = [:] - for (group in summary_params.keySet()) { + summary_params.keySet().sort().each { group -> summary << summary_params[group] } @@ -344,10 +343,10 @@ def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdi def sendmail_html = sendmail_template.toString() // Send the HTML e-mail - Map colors = logColours(monochrome_logs) + def colors = logColours(monochrome_logs) as Map if (email_address) { try { - if (plaintext_email) { throw GroovyException('Send plaintext e-mail, not HTML') } + if (plaintext_email) { throw new org.codehaus.groovy.GroovyException('Send plaintext e-mail, not HTML') } // Try to send HTML e-mail using sendmail def sendmail_tf = new File(workflow.launchDir.toString(), ".sendmail_tmp.html") sendmail_tf.withWriter { w -> w << sendmail_html } @@ -364,13 +363,13 @@ def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdi // Write summary e-mail HTML to a file def output_hf = new File(workflow.launchDir.toString(), ".pipeline_report.html") output_hf.withWriter { w -> w << email_html } - FilesEx.copyTo(output_hf.toPath(), "${outdir}/pipeline_info/pipeline_report.html"); + nextflow.extension.FilesEx.copyTo(output_hf.toPath(), "${outdir}/pipeline_info/pipeline_report.html"); output_hf.delete() // Write summary e-mail TXT to a file def output_tf = new File(workflow.launchDir.toString(), ".pipeline_report.txt") output_tf.withWriter { w -> w << email_txt } - FilesEx.copyTo(output_tf.toPath(), "${outdir}/pipeline_info/pipeline_report.txt"); + nextflow.extension.FilesEx.copyTo(output_tf.toPath(), "${outdir}/pipeline_info/pipeline_report.txt"); output_tf.delete() } @@ -378,7 +377,7 @@ def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdi // Print pipeline summary on completion // def completionSummary(monochrome_logs=true) { - Map colors = logColours(monochrome_logs) + def colors = logColours(monochrome_logs) as Map if (workflow.success) { if (workflow.stats.ignoredCount == 0) { log.info "-${colors.purple}[$workflow.manifest.name]${colors.green} Pipeline completed successfully${colors.reset}-" @@ -395,7 +394,7 @@ def completionSummary(monochrome_logs=true) { // def imNotification(summary_params, hook_url) { def summary = [:] - for (group in summary_params.keySet()) { + summary_params.keySet().sort().each { group -> summary << summary_params[group] } diff --git a/subworkflows/nf-core/utils_nfschema_plugin/main.nf b/subworkflows/nf-core/utils_nfschema_plugin/main.nf new file mode 100644 index 0000000..4994303 --- /dev/null +++ b/subworkflows/nf-core/utils_nfschema_plugin/main.nf @@ -0,0 +1,46 @@ +// +// Subworkflow that uses the nf-schema plugin to validate parameters and render the parameter summary +// + +include { paramsSummaryLog } from 'plugin/nf-schema' +include { validateParameters } from 'plugin/nf-schema' + +workflow UTILS_NFSCHEMA_PLUGIN { + + take: + input_workflow // workflow: the workflow object used by nf-schema to get metadata from the workflow + validate_params // boolean: validate the parameters + parameters_schema // string: path to the parameters JSON schema. + // this has to be the same as the schema given to `validation.parametersSchema` + // when this input is empty it will automatically use the configured schema or + // "${projectDir}/nextflow_schema.json" as default. This input should not be empty + // for meta pipelines + + main: + + // + // Print parameter summary to stdout. This will display the parameters + // that differ from the default given in the JSON schema + // + if(parameters_schema) { + log.info paramsSummaryLog(input_workflow, parameters_schema:parameters_schema) + } else { + log.info paramsSummaryLog(input_workflow) + } + + // + // Validate the parameters using nextflow_schema.json or the schema + // given via the validation.parametersSchema configuration option + // + if(validate_params) { + if(parameters_schema) { + validateParameters(parameters_schema:parameters_schema) + } else { + validateParameters() + } + } + + emit: + dummy_emit = true +} + diff --git a/subworkflows/nf-core/utils_nfschema_plugin/meta.yml b/subworkflows/nf-core/utils_nfschema_plugin/meta.yml new file mode 100644 index 0000000..f7d9f02 --- /dev/null +++ b/subworkflows/nf-core/utils_nfschema_plugin/meta.yml @@ -0,0 +1,35 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: "utils_nfschema_plugin" +description: Run nf-schema to validate parameters and create a summary of changed parameters +keywords: + - validation + - JSON schema + - plugin + - parameters + - summary +components: [] +input: + - input_workflow: + type: object + description: | + The workflow object of the used pipeline. + This object contains meta data used to create the params summary log + - validate_params: + type: boolean + description: Validate the parameters and error if invalid. + - parameters_schema: + type: string + description: | + Path to the parameters JSON schema. + This has to be the same as the schema given to the `validation.parametersSchema` config + option. When this input is empty it will automatically use the configured schema or + "${projectDir}/nextflow_schema.json" as default. The schema should not be given in this way + for meta pipelines. +output: + - dummy_emit: + type: boolean + description: Dummy emit to make nf-core subworkflows lint happy +authors: + - "@nvnieuwk" +maintainers: + - "@nvnieuwk" diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test b/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test new file mode 100644 index 0000000..842dc43 --- /dev/null +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test @@ -0,0 +1,117 @@ +nextflow_workflow { + + name "Test Subworkflow UTILS_NFSCHEMA_PLUGIN" + script "../main.nf" + workflow "UTILS_NFSCHEMA_PLUGIN" + + tag "subworkflows" + tag "subworkflows_nfcore" + tag "subworkflows/utils_nfschema_plugin" + tag "plugin/nf-schema" + + config "./nextflow.config" + + test("Should run nothing") { + + when { + + params { + test_data = '' + } + + workflow { + """ + validate_params = false + input[0] = workflow + input[1] = validate_params + input[2] = "" + """ + } + } + + then { + assertAll( + { assert workflow.success } + ) + } + } + + test("Should validate params") { + + when { + + params { + test_data = '' + outdir = 1 + } + + workflow { + """ + validate_params = true + input[0] = workflow + input[1] = validate_params + input[2] = "" + """ + } + } + + then { + assertAll( + { assert workflow.failed }, + { assert workflow.stdout.any { it.contains('ERROR ~ Validation of pipeline parameters failed!') } } + ) + } + } + + test("Should run nothing - custom schema") { + + when { + + params { + test_data = '' + } + + workflow { + """ + validate_params = false + input[0] = workflow + input[1] = validate_params + input[2] = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json" + """ + } + } + + then { + assertAll( + { assert workflow.success } + ) + } + } + + test("Should validate params - custom schema") { + + when { + + params { + test_data = '' + outdir = 1 + } + + workflow { + """ + validate_params = true + input[0] = workflow + input[1] = validate_params + input[2] = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json" + """ + } + } + + then { + assertAll( + { assert workflow.failed }, + { assert workflow.stdout.any { it.contains('ERROR ~ Validation of pipeline parameters failed!') } } + ) + } + } +} diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config new file mode 100644 index 0000000..0907ac5 --- /dev/null +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config @@ -0,0 +1,8 @@ +plugins { + id "nf-schema@2.1.0" +} + +validation { + parametersSchema = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json" + monochromeLogs = true +} \ No newline at end of file diff --git a/subworkflows/nf-core/utils_nfvalidation_plugin/tests/nextflow_schema.json b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json similarity index 95% rename from subworkflows/nf-core/utils_nfvalidation_plugin/tests/nextflow_schema.json rename to subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json index 7626c1c..331e0d2 100644 --- a/subworkflows/nf-core/utils_nfvalidation_plugin/tests/nextflow_schema.json +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json @@ -1,10 +1,10 @@ { - "$schema": "http://json-schema.org/draft-07/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://raw.githubusercontent.com/./master/nextflow_schema.json", "title": ". pipeline parameters", "description": "", "type": "object", - "definitions": { + "$defs": { "input_output_options": { "title": "Input/output options", "type": "object", @@ -87,10 +87,10 @@ }, "allOf": [ { - "$ref": "#/definitions/input_output_options" + "$ref": "#/$defs/input_output_options" }, { - "$ref": "#/definitions/generic_options" + "$ref": "#/$defs/generic_options" } ] } diff --git a/subworkflows/nf-core/utils_nfvalidation_plugin/main.nf b/subworkflows/nf-core/utils_nfvalidation_plugin/main.nf deleted file mode 100644 index 2585b65..0000000 --- a/subworkflows/nf-core/utils_nfvalidation_plugin/main.nf +++ /dev/null @@ -1,62 +0,0 @@ -// -// Subworkflow that uses the nf-validation plugin to render help text and parameter summary -// - -/* -======================================================================================== - IMPORT NF-VALIDATION PLUGIN -======================================================================================== -*/ - -include { paramsHelp } from 'plugin/nf-validation' -include { paramsSummaryLog } from 'plugin/nf-validation' -include { validateParameters } from 'plugin/nf-validation' - -/* -======================================================================================== - SUBWORKFLOW DEFINITION -======================================================================================== -*/ - -workflow UTILS_NFVALIDATION_PLUGIN { - - take: - print_help // boolean: print help - workflow_command // string: default commmand used to run pipeline - pre_help_text // string: string to be printed before help text and summary log - post_help_text // string: string to be printed after help text and summary log - validate_params // boolean: validate parameters - schema_filename // path: JSON schema file, null to use default value - - main: - - log.debug "Using schema file: ${schema_filename}" - - // Default values for strings - pre_help_text = pre_help_text ?: '' - post_help_text = post_help_text ?: '' - workflow_command = workflow_command ?: '' - - // - // Print help message if needed - // - if (print_help) { - log.info pre_help_text + paramsHelp(workflow_command, parameters_schema: schema_filename) + post_help_text - System.exit(0) - } - - // - // Print parameter summary to stdout - // - log.info pre_help_text + paramsSummaryLog(workflow, parameters_schema: schema_filename) + post_help_text - - // - // Validate parameters relative to the parameter JSON schema - // - if (validate_params){ - validateParameters(parameters_schema: schema_filename) - } - - emit: - dummy_emit = true -} diff --git a/subworkflows/nf-core/utils_nfvalidation_plugin/meta.yml b/subworkflows/nf-core/utils_nfvalidation_plugin/meta.yml deleted file mode 100644 index 3d4a6b0..0000000 --- a/subworkflows/nf-core/utils_nfvalidation_plugin/meta.yml +++ /dev/null @@ -1,44 +0,0 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json -name: "UTILS_NFVALIDATION_PLUGIN" -description: Use nf-validation to initiate and validate a pipeline -keywords: - - utility - - pipeline - - initialise - - validation -components: [] -input: - - print_help: - type: boolean - description: | - Print help message and exit - - workflow_command: - type: string - description: | - The command to run the workflow e.g. "nextflow run main.nf" - - pre_help_text: - type: string - description: | - Text to print before the help message - - post_help_text: - type: string - description: | - Text to print after the help message - - validate_params: - type: boolean - description: | - Validate the parameters and error if invalid. - - schema_filename: - type: string - description: | - The filename of the schema to validate against. -output: - - dummy_emit: - type: boolean - description: | - Dummy emit to make nf-core subworkflows lint happy -authors: - - "@adamrtalbot" -maintainers: - - "@adamrtalbot" - - "@maxulysse" diff --git a/subworkflows/nf-core/utils_nfvalidation_plugin/tests/main.nf.test b/subworkflows/nf-core/utils_nfvalidation_plugin/tests/main.nf.test deleted file mode 100644 index 5784a33..0000000 --- a/subworkflows/nf-core/utils_nfvalidation_plugin/tests/main.nf.test +++ /dev/null @@ -1,200 +0,0 @@ -nextflow_workflow { - - name "Test Workflow UTILS_NFVALIDATION_PLUGIN" - script "../main.nf" - workflow "UTILS_NFVALIDATION_PLUGIN" - tag "subworkflows" - tag "subworkflows_nfcore" - tag "plugin/nf-validation" - tag "'plugin/nf-validation'" - tag "utils_nfvalidation_plugin" - tag "subworkflows/utils_nfvalidation_plugin" - - test("Should run nothing") { - - when { - - params { - monochrome_logs = true - test_data = '' - } - - workflow { - """ - help = false - workflow_command = null - pre_help_text = null - post_help_text = null - validate_params = false - schema_filename = "$moduleTestDir/nextflow_schema.json" - - input[0] = help - input[1] = workflow_command - input[2] = pre_help_text - input[3] = post_help_text - input[4] = validate_params - input[5] = schema_filename - """ - } - } - - then { - assertAll( - { assert workflow.success } - ) - } - } - - test("Should run help") { - - - when { - - params { - monochrome_logs = true - test_data = '' - } - workflow { - """ - help = true - workflow_command = null - pre_help_text = null - post_help_text = null - validate_params = false - schema_filename = "$moduleTestDir/nextflow_schema.json" - - input[0] = help - input[1] = workflow_command - input[2] = pre_help_text - input[3] = post_help_text - input[4] = validate_params - input[5] = schema_filename - """ - } - } - - then { - assertAll( - { assert workflow.success }, - { assert workflow.exitStatus == 0 }, - { assert workflow.stdout.any { it.contains('Input/output options') } }, - { assert workflow.stdout.any { it.contains('--outdir') } } - ) - } - } - - test("Should run help with command") { - - when { - - params { - monochrome_logs = true - test_data = '' - } - workflow { - """ - help = true - workflow_command = "nextflow run noorg/doesntexist" - pre_help_text = null - post_help_text = null - validate_params = false - schema_filename = "$moduleTestDir/nextflow_schema.json" - - input[0] = help - input[1] = workflow_command - input[2] = pre_help_text - input[3] = post_help_text - input[4] = validate_params - input[5] = schema_filename - """ - } - } - - then { - assertAll( - { assert workflow.success }, - { assert workflow.exitStatus == 0 }, - { assert workflow.stdout.any { it.contains('nextflow run noorg/doesntexist') } }, - { assert workflow.stdout.any { it.contains('Input/output options') } }, - { assert workflow.stdout.any { it.contains('--outdir') } } - ) - } - } - - test("Should run help with extra text") { - - - when { - - params { - monochrome_logs = true - test_data = '' - } - workflow { - """ - help = true - workflow_command = "nextflow run noorg/doesntexist" - pre_help_text = "pre-help-text" - post_help_text = "post-help-text" - validate_params = false - schema_filename = "$moduleTestDir/nextflow_schema.json" - - input[0] = help - input[1] = workflow_command - input[2] = pre_help_text - input[3] = post_help_text - input[4] = validate_params - input[5] = schema_filename - """ - } - } - - then { - assertAll( - { assert workflow.success }, - { assert workflow.exitStatus == 0 }, - { assert workflow.stdout.any { it.contains('pre-help-text') } }, - { assert workflow.stdout.any { it.contains('nextflow run noorg/doesntexist') } }, - { assert workflow.stdout.any { it.contains('Input/output options') } }, - { assert workflow.stdout.any { it.contains('--outdir') } }, - { assert workflow.stdout.any { it.contains('post-help-text') } } - ) - } - } - - test("Should validate params") { - - when { - - params { - monochrome_logs = true - test_data = '' - outdir = 1 - } - workflow { - """ - help = false - workflow_command = null - pre_help_text = null - post_help_text = null - validate_params = true - schema_filename = "$moduleTestDir/nextflow_schema.json" - - input[0] = help - input[1] = workflow_command - input[2] = pre_help_text - input[3] = post_help_text - input[4] = validate_params - input[5] = schema_filename - """ - } - } - - then { - assertAll( - { assert workflow.failed }, - { assert workflow.stdout.any { it.contains('ERROR ~ ERROR: Validation of pipeline parameters failed!') } } - ) - } - } -} diff --git a/subworkflows/nf-core/utils_nfvalidation_plugin/tests/tags.yml b/subworkflows/nf-core/utils_nfvalidation_plugin/tests/tags.yml deleted file mode 100644 index 60b1cff..0000000 --- a/subworkflows/nf-core/utils_nfvalidation_plugin/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -subworkflows/utils_nfvalidation_plugin: - - subworkflows/nf-core/utils_nfvalidation_plugin/** diff --git a/workflows/pairgenomealign.nf b/workflows/pairgenomealign.nf index f32678d..b6076b5 100644 --- a/workflows/pairgenomealign.nf +++ b/workflows/pairgenomealign.nf @@ -3,10 +3,9 @@ IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - include { FASTQC } from '../modules/nf-core/fastqc/main' include { MULTIQC } from '../modules/nf-core/multiqc/main' -include { paramsSummaryMap } from 'plugin/nf-validation' +include { paramsSummaryMap } from 'plugin/nf-schema' include { paramsSummaryMultiqc } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_pairgenomealign_pipeline' @@ -21,12 +20,10 @@ workflow PAIRGENOMEALIGN { take: ch_samplesheet // channel: samplesheet read in from --input - main: ch_versions = Channel.empty() ch_multiqc_files = Channel.empty() - // // MODULE: Run FastQC // @@ -42,11 +39,12 @@ workflow PAIRGENOMEALIGN { softwareVersionsToYAML(ch_versions) .collectFile( storeDir: "${params.outdir}/pipeline_info", - name: 'nf_core_pipeline_software_mqc_versions.yml', + name: 'nf_core_' + 'pipeline_software_' + 'mqc_' + 'versions.yml', sort: true, newLine: true ).set { ch_collated_versions } + // // MODULE: MultiQC // @@ -59,18 +57,19 @@ workflow PAIRGENOMEALIGN { Channel.fromPath(params.multiqc_logo, checkIfExists: true) : Channel.empty() + summary_params = paramsSummaryMap( workflow, parameters_schema: "nextflow_schema.json") ch_workflow_summary = Channel.value(paramsSummaryMultiqc(summary_params)) - + ch_multiqc_files = ch_multiqc_files.mix( + ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) + ch_multiqc_custom_methods_description = params.multiqc_methods_description ? file(params.multiqc_methods_description, checkIfExists: true) : file("$projectDir/assets/methods_description_template.yml", checkIfExists: true) ch_methods_description = Channel.value( methodsDescriptionText(ch_multiqc_custom_methods_description)) - ch_multiqc_files = ch_multiqc_files.mix( - ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) ch_multiqc_files = ch_multiqc_files.mix(ch_collated_versions) ch_multiqc_files = ch_multiqc_files.mix( ch_methods_description.collectFile( @@ -83,12 +82,14 @@ workflow PAIRGENOMEALIGN { ch_multiqc_files.collect(), ch_multiqc_config.toList(), ch_multiqc_custom_config.toList(), - ch_multiqc_logo.toList() + ch_multiqc_logo.toList(), + [], + [] ) - emit: - multiqc_report = MULTIQC.out.report.toList() // channel: /path/to/multiqc_report.html + emit:multiqc_report = MULTIQC.out.report.toList() // channel: /path/to/multiqc_report.html versions = ch_versions // channel: [ path(versions.yml) ] + } /* From 40609f5ca8b19101298aa8a57fe840fcc4241e38 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Wed, 9 Oct 2024 11:08:10 +0000 Subject: [PATCH 02/22] Template update for nf-core/tools version 3.0.1 --- .editorconfig | 4 - .github/CONTRIBUTING.md | 2 +- .github/workflows/awsfulltest.yml | 6 +- .github/workflows/linting.yml | 4 +- .nf-core.yml | 2 +- .prettierignore | 1 - docs/output.md | 1 - modules.json | 6 +- modules/nf-core/multiqc/environment.yml | 2 +- modules/nf-core/multiqc/main.nf | 4 +- .../nf-core/multiqc/tests/main.nf.test.snap | 26 +- nextflow.config | 8 +- .../main.nf | 12 +- .../nf-core/utils_nextflow_pipeline/main.nf | 46 ++- .../nf-core/utils_nfcore_pipeline/main.nf | 279 ++++++++++-------- 15 files changed, 209 insertions(+), 194 deletions(-) diff --git a/.editorconfig b/.editorconfig index e105881..72dda28 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,7 +11,6 @@ indent_style = space [*.{md,yml,yaml,html,css,scss,js}] indent_size = 2 - # These files are edited and tested upstream in nf-core/modules [/modules/nf-core/**] charset = unset @@ -26,12 +25,9 @@ insert_final_newline = unset trim_trailing_whitespace = unset indent_style = unset - - [/assets/email*] indent_size = unset - # ignore python and markdown [*.{py,md}] indent_style = unset diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index a706b78..05936b4 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -90,7 +90,7 @@ Once there, use `nf-core pipelines schema build` to add to `nextflow_schema.json ### Default processes resource requirements -Sensible defaults for process resource requirements (CPUs / memory / time) for a process should be defined in `conf/base.config`. These should generally be specified generic with `withLabel:` selectors so they can be shared across multiple processes/steps of the pipeline. A nf-core standard set of labels that should be followed where possible can be seen in the [nf-core pipeline template](/~https://github.com/nf-core/tools/blob/master/nf_core/pipeline-template/conf/base.config), which has the default process as a single core-process, and then different levels of multi-core configurations for increasingly large memory requirements defined with standardised labels. +Sensible defaults for process resource requirements (CPUs / memory / time) for a process should be defined in `conf/base.config`. These should generally be specified generic with `withLabel:` selectors so they can be shared across multiple processes/steps of the pipeline. A nf-core standard set of labels that should be followed where possible can be seen in the [nf-core pipeline template](/~https://github.com/nf-core/tools/blob/main/nf_core/pipeline-template/conf/base.config), which has the default process as a single core-process, and then different levels of multi-core configurations for increasingly large memory requirements defined with standardised labels. The process resources can be passed on to the tool dynamically within the process with the `${task.cpus}` and `${task.memory}` variables in the `script:` block. diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 8cd9c11..8c281d1 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -14,16 +14,18 @@ on: jobs: run-platform: name: Run AWS full tests - if: github.repository == 'nf-core/pairgenomealign' && github.event.review.state == 'approved' + # run only if the PR is approved by at least 2 reviewers and against the master branch or manually triggered + if: github.repository == 'nf-core/pairgenomealign' && github.event.review.state == 'approved' && github.event.pull_request.base.ref == 'master' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest steps: - uses: octokit/request-action@v2.x id: check_approvals with: - route: GET /repos/${{ github.repository }}/pulls/${{ github.event.review.number }}/reviews + route: GET /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - id: test_variables + if: github.event_name != 'workflow_dispatch' run: | JSON_RESPONSE='${{ steps.check_approvals.outputs.data }}' CURRENT_APPROVALS_COUNT=$(echo $JSON_RESPONSE | jq -c '[.[] | select(.state | contains("APPROVED")) ] | length') diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index b882838..a502573 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -42,10 +42,10 @@ jobs: architecture: "x64" - name: read .nf-core.yml - uses: pietrobolcato/action-read-yaml@1.0.0 + uses: pietrobolcato/action-read-yaml@1.1.0 id: read_yml with: - config: ${{ github.workspace }}/.nf-core.yaml + config: ${{ github.workspace }}/.nf-core.yml - name: Install dependencies run: | diff --git a/.nf-core.yml b/.nf-core.yml index f675917..042d6df 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -4,7 +4,7 @@ lint: - assets/nf-core-pairgenomealign_logo_light.png - docs/images/nf-core-pairgenomealign_logo_light.png - docs/images/nf-core-pairgenomealign_logo_dark.png -nf_core_version: 3.0.0 +nf_core_version: 3.0.1 org_path: null repository_type: pipeline template: diff --git a/.prettierignore b/.prettierignore index 610e506..437d763 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,3 @@ - email_template.html adaptivecard.json slackreport.json diff --git a/docs/output.md b/docs/output.md index df14703..a6bd20e 100644 --- a/docs/output.md +++ b/docs/output.md @@ -14,7 +14,6 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d - [FastQC](#fastqc) - Raw read QC - [MultiQC](#multiqc) - Aggregate report describing results and QC from the whole pipeline - - [Pipeline information](#pipeline-information) - Report metrics generated during the workflow execution ### FastQC diff --git a/modules.json b/modules.json index d829d44..8709171 100644 --- a/modules.json +++ b/modules.json @@ -12,7 +12,7 @@ }, "multiqc": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "b8d36829fa84b6e404364abff787e8b07f6d058c", "installed_by": ["modules"] } } @@ -21,12 +21,12 @@ "nf-core": { "utils_nextflow_pipeline": { "branch": "master", - "git_sha": "d20fb2a9cc3e2835e9d067d1046a63252eb17352", + "git_sha": "9d05360da397692321d377b6102d2fb22507c6ef", "installed_by": ["subworkflows"] }, "utils_nfcore_pipeline": { "branch": "master", - "git_sha": "2fdce49d30c0254f76bc0f13c55c17455c1251ab", + "git_sha": "772684d9d66f37b650c8ba5146ac1ee3ecba2acb", "installed_by": ["subworkflows"] }, "utils_nfschema_plugin": { diff --git a/modules/nf-core/multiqc/environment.yml b/modules/nf-core/multiqc/environment.yml index f1cd99b..6f5b867 100644 --- a/modules/nf-core/multiqc/environment.yml +++ b/modules/nf-core/multiqc/environment.yml @@ -2,4 +2,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::multiqc=1.24.1 + - bioconda::multiqc=1.25.1 diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index b9ccebd..9724d2f 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -3,8 +3,8 @@ process MULTIQC { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.25--pyhdfd78af_0' : - 'biocontainers/multiqc:1.25--pyhdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/multiqc:1.25.1--pyhdfd78af_0' : + 'biocontainers/multiqc:1.25.1--pyhdfd78af_0' }" input: path multiqc_files, stageAs: "?/*" diff --git a/modules/nf-core/multiqc/tests/main.nf.test.snap b/modules/nf-core/multiqc/tests/main.nf.test.snap index b779e46..2fcbb5f 100644 --- a/modules/nf-core/multiqc/tests/main.nf.test.snap +++ b/modules/nf-core/multiqc/tests/main.nf.test.snap @@ -2,14 +2,14 @@ "multiqc_versions_single": { "content": [ [ - "versions.yml:md5,8c8724363a5efe0c6f43ab34faa57efd" + "versions.yml:md5,41f391dcedce7f93ca188f3a3ffa0916" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.0", + "nextflow": "24.04.4" }, - "timestamp": "2024-07-10T12:41:34.562023" + "timestamp": "2024-10-02T17:51:46.317523" }, "multiqc_stub": { "content": [ @@ -17,25 +17,25 @@ "multiqc_report.html", "multiqc_data", "multiqc_plots", - "versions.yml:md5,8c8724363a5efe0c6f43ab34faa57efd" + "versions.yml:md5,41f391dcedce7f93ca188f3a3ffa0916" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.0", + "nextflow": "24.04.4" }, - "timestamp": "2024-07-10T11:27:11.933869532" + "timestamp": "2024-10-02T17:52:20.680978" }, "multiqc_versions_config": { "content": [ [ - "versions.yml:md5,8c8724363a5efe0c6f43ab34faa57efd" + "versions.yml:md5,41f391dcedce7f93ca188f3a3ffa0916" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.0", + "nextflow": "24.04.4" }, - "timestamp": "2024-07-10T11:26:56.709849369" + "timestamp": "2024-10-02T17:52:09.185842" } -} +} \ No newline at end of file diff --git a/nextflow.config b/nextflow.config index 5e5003e..0797e2d 100644 --- a/nextflow.config +++ b/nextflow.config @@ -12,10 +12,12 @@ params { // TODO nf-core: Specify your pipeline's command line flags // Input options input = null + // References genome = null igenomes_base = 's3://ngi-igenomes/igenomes/' igenomes_ignore = false + // MultiQC options multiqc_config = null multiqc_title = null @@ -36,6 +38,7 @@ params { show_hidden = false version = false pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/' + // Config options config_profile_name = null config_profile_description = null @@ -44,9 +47,9 @@ params { custom_config_base = "https://raw.githubusercontent.com/nf-core/configs/${params.custom_config_version}" config_profile_contact = null config_profile_url = null + // Schema validation default options validate_params = true - } // Load base.config by default for all pipelines @@ -161,6 +164,7 @@ includeConfig !System.getenv('NXF_OFFLINE') && params.custom_config_base ? "${pa // Load nf-core/pairgenomealign custom profiles from different institutions. // TODO nf-core: Optionally, you can add a pipeline-specific nf-core config at /~https://github.com/nf-core/configs // includeConfig !System.getenv('NXF_OFFLINE') && params.custom_config_base ? "${params.custom_config_base}/pipeline/pairgenomealign.config" : "/dev/null" + // Set default registry for Apptainer, Docker, Podman, Charliecloud and Singularity independent of -profile // Will not be used unless Apptainer / Docker / Podman / Charliecloud / Singularity are enabled // Set to your registry if you have a mirror of containers @@ -172,6 +176,7 @@ charliecloud.registry = 'quay.io' // Load igenomes.config if required includeConfig !params.igenomes_ignore ? 'conf/igenomes.config' : 'conf/igenomes_ignored.config' + // 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. @@ -263,4 +268,3 @@ validation { // Load modules.config for DSL2 module specific options includeConfig 'conf/modules.config' - diff --git a/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf b/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf index a96b588..5987d71 100644 --- a/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf @@ -18,9 +18,9 @@ include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SUBWORKFLOW TO INITIALISE PIPELINE -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ workflow PIPELINE_INITIALISATION { @@ -99,9 +99,9 @@ workflow PIPELINE_INITIALISATION { } /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SUBWORKFLOW FOR PIPELINE COMPLETION -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ workflow PIPELINE_COMPLETION { @@ -147,9 +147,9 @@ workflow PIPELINE_COMPLETION { } /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FUNCTIONS -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ // // Check and validate pipeline parameters diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf index 28e32b2..2b0dc67 100644 --- a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf @@ -3,13 +3,12 @@ // /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SUBWORKFLOW DEFINITION -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ workflow UTILS_NEXTFLOW_PIPELINE { - take: print_version // boolean: print version dump_parameters // boolean: dump parameters @@ -22,7 +21,7 @@ workflow UTILS_NEXTFLOW_PIPELINE { // Print workflow version and exit on --version // if (print_version) { - log.info "${workflow.manifest.name} ${getWorkflowVersion()}" + log.info("${workflow.manifest.name} ${getWorkflowVersion()}") System.exit(0) } @@ -45,9 +44,9 @@ workflow UTILS_NEXTFLOW_PIPELINE { } /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FUNCTIONS -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ // @@ -72,11 +71,11 @@ def getWorkflowVersion() { // Dump pipeline parameters to a JSON file // def dumpParametersToJSON(outdir) { - def timestamp = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss') - def filename = "params_${timestamp}.json" - def temp_pf = new File(workflow.launchDir.toString(), ".${filename}") - def jsonStr = groovy.json.JsonOutput.toJson(params) - temp_pf.text = groovy.json.JsonOutput.prettyPrint(jsonStr) + def timestamp = new java.util.Date().format('yyyy-MM-dd_HH-mm-ss') + def filename = "params_${timestamp}.json" + def temp_pf = new File(workflow.launchDir.toString(), ".${filename}") + def jsonStr = groovy.json.JsonOutput.toJson(params) + temp_pf.text = groovy.json.JsonOutput.prettyPrint(jsonStr) nextflow.extension.FilesEx.copyTo(temp_pf.toPath(), "${outdir}/pipeline_info/params_${timestamp}.json") temp_pf.delete() @@ -91,9 +90,14 @@ def checkCondaChannels() { try { def config = parser.load("conda config --show channels".execute().text) channels = config.channels - } catch(NullPointerException | IOException e) { - log.warn "Could not verify conda channel configuration." - return + } + catch (NullPointerException e) { + log.warn("Could not verify conda channel configuration.") + return null + } + catch (IOException e) { + log.warn("Could not verify conda channel configuration.") + return null } // Check that all channels are present @@ -106,19 +110,13 @@ def checkCondaChannels() { required_channels_in_order.eachWithIndex { channel, index -> if (index < required_channels_in_order.size() - 1) { - channel_priority_violation |= !(channels.indexOf(channel) < channels.indexOf(required_channels_in_order[index+1])) + channel_priority_violation |= !(channels.indexOf(channel) < channels.indexOf(required_channels_in_order[index + 1])) } } 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/\n" + - " The observed channel order is \n" + - " ${channels}\n" + - " but the following channel order is required:\n" + - " ${required_channels_in_order}\n" + - "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + log.warn( + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " There is a problem with your Conda configuration!\n\n" + " You will need to set-up the conda-forge and bioconda channels correctly.\n" + " Please refer to https://bioconda.github.io/\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/subworkflows/nf-core/utils_nfcore_pipeline/main.nf b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf index cbd8495..b78273c 100644 --- a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf @@ -3,13 +3,12 @@ // /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SUBWORKFLOW DEFINITION -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ workflow UTILS_NFCORE_PIPELINE { - take: nextflow_cli_args @@ -22,9 +21,9 @@ workflow UTILS_NFCORE_PIPELINE { } /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FUNCTIONS -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ // @@ -33,12 +32,9 @@ workflow UTILS_NFCORE_PIPELINE { def checkConfigProvided() { def valid_config = true as Boolean if (workflow.profile == 'standard' && workflow.configFiles.size() <= 1) { - log.warn "[$workflow.manifest.name] You are attempting to run the pipeline without any custom configuration!\n\n" + - "This will be dependent on your local compute environment but can be achieved via one or more of the following:\n" + - " (1) Using an existing pipeline profile e.g. `-profile docker` or `-profile singularity`\n" + - " (2) Using an existing nf-core/configs for your Institution e.g. `-profile crick` or `-profile uppmax`\n" + - " (3) Using your own local custom config e.g. `-c /path/to/your/custom.config`\n\n" + - "Please refer to the quick start section and usage docs for the pipeline.\n " + log.warn( + "[${workflow.manifest.name}] You are attempting to run the pipeline without any custom configuration!\n\n" + "This will be dependent on your local compute environment but can be achieved via one or more of the following:\n" + " (1) Using an existing pipeline profile e.g. `-profile docker` or `-profile singularity`\n" + " (2) Using an existing nf-core/configs for your Institution e.g. `-profile crick` or `-profile uppmax`\n" + " (3) Using your own local custom config e.g. `-c /path/to/your/custom.config`\n\n" + "Please refer to the quick start section and usage docs for the pipeline.\n " + ) valid_config = false } return valid_config @@ -49,12 +45,14 @@ def checkConfigProvided() { // def checkProfileProvided(nextflow_cli_args) { if (workflow.profile.endsWith(',')) { - error "The `-profile` option cannot end with a trailing comma, please remove it and re-run the pipeline!\n" + - "HINT: A common mistake is to provide multiple values separated by spaces e.g. `-profile test, docker`.\n" + error( + "The `-profile` option cannot end with a trailing comma, please remove it and re-run the pipeline!\n" + "HINT: A common mistake is to provide multiple values separated by spaces e.g. `-profile test, docker`.\n" + ) } if (nextflow_cli_args[0]) { - log.warn "nf-core pipelines do not accept positional arguments. The positional argument `${nextflow_cli_args[0]}` has been detected.\n" + - "HINT: A common mistake is to provide multiple values separated by spaces e.g. `-profile test, docker`.\n" + log.warn( + "nf-core pipelines do not accept positional arguments. The positional argument `${nextflow_cli_args[0]}` has been detected.\n" + "HINT: A common mistake is to provide multiple values separated by spaces e.g. `-profile test, docker`.\n" + ) } } @@ -70,13 +68,7 @@ def workflowCitation() { manifest_doi.each { doi_ref -> temp_doi_ref += " https://doi.org/${doi_ref.replace('https://doi.org/', '').replace(' ', '')}\n" } - return "If you use ${workflow.manifest.name} for your analysis please cite:\n\n" + - "* The pipeline\n" + - temp_doi_ref + "\n" + - "* The nf-core framework\n" + - " https://doi.org/10.1038/s41587-020-0439-x\n\n" + - "* Software dependencies\n" + - " /~https://github.com/${workflow.manifest.name}/blob/master/CITATIONS.md" + return "If you use ${workflow.manifest.name} for your analysis please cite:\n\n" + "* The pipeline\n" + temp_doi_ref + "\n" + "* The nf-core framework\n" + " https://doi.org/10.1038/s41587-020-0439-x\n\n" + "* Software dependencies\n" + " /~https://github.com/${workflow.manifest.name}/blob/master/CITATIONS.md" } // @@ -102,7 +94,7 @@ def getWorkflowVersion() { // def processVersionsFromYAML(yaml_file) { def yaml = new org.yaml.snakeyaml.Yaml() - def versions = yaml.load(yaml_file).collectEntries { k, v -> [ k.tokenize(':')[-1], v ] } + def versions = yaml.load(yaml_file).collectEntries { k, v -> [k.tokenize(':')[-1], v] } return yaml.dumpAsMap(versions).trim() } @@ -112,8 +104,8 @@ def processVersionsFromYAML(yaml_file) { def workflowVersionToYAML() { return """ Workflow: - $workflow.manifest.name: ${getWorkflowVersion()} - Nextflow: $workflow.nextflow.version + ${workflow.manifest.name}: ${getWorkflowVersion()} + Nextflow: ${workflow.nextflow.version} """.stripIndent().trim() } @@ -121,11 +113,7 @@ def workflowVersionToYAML() { // Get channel of software versions used in pipeline in YAML format // def softwareVersionsToYAML(ch_versions) { - return ch_versions - .unique() - .map { version -> processVersionsFromYAML(version) } - .unique() - .mix(Channel.of(workflowVersionToYAML())) + return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(Channel.of(workflowVersionToYAML())) } // @@ -133,25 +121,31 @@ def softwareVersionsToYAML(ch_versions) { // def paramsSummaryMultiqc(summary_params) { def summary_section = '' - summary_params.keySet().each { group -> - def group_params = summary_params.get(group) // This gets the parameters of that particular group - if (group_params) { - summary_section += "

    $group

    \n" - summary_section += "
    \n" - group_params.keySet().sort().each { param -> - summary_section += "
    $param
    ${group_params.get(param) ?: 'N/A'}
    \n" + summary_params + .keySet() + .each { group -> + def group_params = summary_params.get(group) + // This gets the parameters of that particular group + if (group_params) { + summary_section += "

    ${group}

    \n" + summary_section += "
    \n" + group_params + .keySet() + .sort() + .each { param -> + summary_section += "
    ${param}
    ${group_params.get(param) ?: 'N/A'}
    \n" + } + summary_section += "
    \n" } - summary_section += "
    \n" } - } - def yaml_file_text = "id: '${workflow.manifest.name.replace('/','-')}-summary'\n" as String - yaml_file_text += "description: ' - this information is collected when the pipeline is started.'\n" - yaml_file_text += "section_name: '${workflow.manifest.name} Workflow Summary'\n" - yaml_file_text += "section_href: '/~https://github.com/${workflow.manifest.name}'\n" - yaml_file_text += "plot_type: 'html'\n" - yaml_file_text += "data: |\n" - yaml_file_text += "${summary_section}" + def yaml_file_text = "id: '${workflow.manifest.name.replace('/', '-')}-summary'\n" as String + yaml_file_text += "description: ' - this information is collected when the pipeline is started.'\n" + yaml_file_text += "section_name: '${workflow.manifest.name} Workflow Summary'\n" + yaml_file_text += "section_href: '/~https://github.com/${workflow.manifest.name}'\n" + yaml_file_text += "plot_type: 'html'\n" + yaml_file_text += "data: |\n" + yaml_file_text += "${summary_section}" return yaml_file_text } @@ -199,54 +193,54 @@ def logColours(monochrome_logs=true) { colorcodes['hidden'] = monochrome_logs ? '' : "\033[8m" // Regular Colors - colorcodes['black'] = monochrome_logs ? '' : "\033[0;30m" - colorcodes['red'] = monochrome_logs ? '' : "\033[0;31m" - colorcodes['green'] = monochrome_logs ? '' : "\033[0;32m" - colorcodes['yellow'] = monochrome_logs ? '' : "\033[0;33m" - colorcodes['blue'] = monochrome_logs ? '' : "\033[0;34m" - colorcodes['purple'] = monochrome_logs ? '' : "\033[0;35m" - colorcodes['cyan'] = monochrome_logs ? '' : "\033[0;36m" - colorcodes['white'] = monochrome_logs ? '' : "\033[0;37m" + colorcodes['black'] = monochrome_logs ? '' : "\033[0;30m" + colorcodes['red'] = monochrome_logs ? '' : "\033[0;31m" + colorcodes['green'] = monochrome_logs ? '' : "\033[0;32m" + colorcodes['yellow'] = monochrome_logs ? '' : "\033[0;33m" + colorcodes['blue'] = monochrome_logs ? '' : "\033[0;34m" + colorcodes['purple'] = monochrome_logs ? '' : "\033[0;35m" + colorcodes['cyan'] = monochrome_logs ? '' : "\033[0;36m" + colorcodes['white'] = monochrome_logs ? '' : "\033[0;37m" // Bold - colorcodes['bblack'] = monochrome_logs ? '' : "\033[1;30m" - colorcodes['bred'] = monochrome_logs ? '' : "\033[1;31m" - colorcodes['bgreen'] = monochrome_logs ? '' : "\033[1;32m" - colorcodes['byellow'] = monochrome_logs ? '' : "\033[1;33m" - colorcodes['bblue'] = monochrome_logs ? '' : "\033[1;34m" - colorcodes['bpurple'] = monochrome_logs ? '' : "\033[1;35m" - colorcodes['bcyan'] = monochrome_logs ? '' : "\033[1;36m" - colorcodes['bwhite'] = monochrome_logs ? '' : "\033[1;37m" + colorcodes['bblack'] = monochrome_logs ? '' : "\033[1;30m" + colorcodes['bred'] = monochrome_logs ? '' : "\033[1;31m" + colorcodes['bgreen'] = monochrome_logs ? '' : "\033[1;32m" + colorcodes['byellow'] = monochrome_logs ? '' : "\033[1;33m" + colorcodes['bblue'] = monochrome_logs ? '' : "\033[1;34m" + colorcodes['bpurple'] = monochrome_logs ? '' : "\033[1;35m" + colorcodes['bcyan'] = monochrome_logs ? '' : "\033[1;36m" + colorcodes['bwhite'] = monochrome_logs ? '' : "\033[1;37m" // Underline - colorcodes['ublack'] = monochrome_logs ? '' : "\033[4;30m" - colorcodes['ured'] = monochrome_logs ? '' : "\033[4;31m" - colorcodes['ugreen'] = monochrome_logs ? '' : "\033[4;32m" - colorcodes['uyellow'] = monochrome_logs ? '' : "\033[4;33m" - colorcodes['ublue'] = monochrome_logs ? '' : "\033[4;34m" - colorcodes['upurple'] = monochrome_logs ? '' : "\033[4;35m" - colorcodes['ucyan'] = monochrome_logs ? '' : "\033[4;36m" - colorcodes['uwhite'] = monochrome_logs ? '' : "\033[4;37m" + colorcodes['ublack'] = monochrome_logs ? '' : "\033[4;30m" + colorcodes['ured'] = monochrome_logs ? '' : "\033[4;31m" + colorcodes['ugreen'] = monochrome_logs ? '' : "\033[4;32m" + colorcodes['uyellow'] = monochrome_logs ? '' : "\033[4;33m" + colorcodes['ublue'] = monochrome_logs ? '' : "\033[4;34m" + colorcodes['upurple'] = monochrome_logs ? '' : "\033[4;35m" + colorcodes['ucyan'] = monochrome_logs ? '' : "\033[4;36m" + colorcodes['uwhite'] = monochrome_logs ? '' : "\033[4;37m" // High Intensity - colorcodes['iblack'] = monochrome_logs ? '' : "\033[0;90m" - colorcodes['ired'] = monochrome_logs ? '' : "\033[0;91m" - colorcodes['igreen'] = monochrome_logs ? '' : "\033[0;92m" - colorcodes['iyellow'] = monochrome_logs ? '' : "\033[0;93m" - colorcodes['iblue'] = monochrome_logs ? '' : "\033[0;94m" - colorcodes['ipurple'] = monochrome_logs ? '' : "\033[0;95m" - colorcodes['icyan'] = monochrome_logs ? '' : "\033[0;96m" - colorcodes['iwhite'] = monochrome_logs ? '' : "\033[0;97m" + colorcodes['iblack'] = monochrome_logs ? '' : "\033[0;90m" + colorcodes['ired'] = monochrome_logs ? '' : "\033[0;91m" + colorcodes['igreen'] = monochrome_logs ? '' : "\033[0;92m" + colorcodes['iyellow'] = monochrome_logs ? '' : "\033[0;93m" + colorcodes['iblue'] = monochrome_logs ? '' : "\033[0;94m" + colorcodes['ipurple'] = monochrome_logs ? '' : "\033[0;95m" + colorcodes['icyan'] = monochrome_logs ? '' : "\033[0;96m" + colorcodes['iwhite'] = monochrome_logs ? '' : "\033[0;97m" // Bold High Intensity - colorcodes['biblack'] = monochrome_logs ? '' : "\033[1;90m" - colorcodes['bired'] = monochrome_logs ? '' : "\033[1;91m" - colorcodes['bigreen'] = monochrome_logs ? '' : "\033[1;92m" - colorcodes['biyellow'] = monochrome_logs ? '' : "\033[1;93m" - colorcodes['biblue'] = monochrome_logs ? '' : "\033[1;94m" - colorcodes['bipurple'] = monochrome_logs ? '' : "\033[1;95m" - colorcodes['bicyan'] = monochrome_logs ? '' : "\033[1;96m" - colorcodes['biwhite'] = monochrome_logs ? '' : "\033[1;97m" + colorcodes['biblack'] = monochrome_logs ? '' : "\033[1;90m" + colorcodes['bired'] = monochrome_logs ? '' : "\033[1;91m" + colorcodes['bigreen'] = monochrome_logs ? '' : "\033[1;92m" + colorcodes['biyellow'] = monochrome_logs ? '' : "\033[1;93m" + colorcodes['biblue'] = monochrome_logs ? '' : "\033[1;94m" + colorcodes['bipurple'] = monochrome_logs ? '' : "\033[1;95m" + colorcodes['bicyan'] = monochrome_logs ? '' : "\033[1;96m" + colorcodes['biwhite'] = monochrome_logs ? '' : "\033[1;97m" return colorcodes } @@ -261,14 +255,15 @@ def attachMultiqcReport(multiqc_report) { mqc_report = multiqc_report.getVal() if (mqc_report.getClass() == ArrayList && mqc_report.size() >= 1) { if (mqc_report.size() > 1) { - log.warn "[$workflow.manifest.name] Found multiple reports from process 'MULTIQC', will use only one" + log.warn("[${workflow.manifest.name}] Found multiple reports from process 'MULTIQC', will use only one") } mqc_report = mqc_report[0] } } - } catch (all) { + } + catch (Exception all) { if (multiqc_report) { - log.warn "[$workflow.manifest.name] Could not attach MultiQC report to summary email" + log.warn("[${workflow.manifest.name}] Could not attach MultiQC report to summary email") } } return mqc_report @@ -280,26 +275,35 @@ def attachMultiqcReport(multiqc_report) { def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdir, monochrome_logs=true, multiqc_report=null) { // Set up the e-mail variables - def subject = "[$workflow.manifest.name] Successful: $workflow.runName" + def subject = "[${workflow.manifest.name}] Successful: ${workflow.runName}" if (!workflow.success) { - subject = "[$workflow.manifest.name] FAILED: $workflow.runName" + subject = "[${workflow.manifest.name}] FAILED: ${workflow.runName}" } def summary = [:] - summary_params.keySet().sort().each { group -> - summary << summary_params[group] - } + summary_params + .keySet() + .sort() + .each { group -> + summary << summary_params[group] + } def misc_fields = [:] misc_fields['Date Started'] = workflow.start misc_fields['Date Completed'] = workflow.complete misc_fields['Pipeline script file path'] = workflow.scriptFile misc_fields['Pipeline script hash ID'] = workflow.scriptId - if (workflow.repository) misc_fields['Pipeline repository Git URL'] = workflow.repository - if (workflow.commitId) misc_fields['Pipeline repository Git Commit'] = workflow.commitId - if (workflow.revision) misc_fields['Pipeline Git branch/tag'] = workflow.revision - misc_fields['Nextflow Version'] = workflow.nextflow.version - misc_fields['Nextflow Build'] = workflow.nextflow.build + if (workflow.repository) { + misc_fields['Pipeline repository Git URL'] = workflow.repository + } + if (workflow.commitId) { + misc_fields['Pipeline repository Git Commit'] = workflow.commitId + } + if (workflow.revision) { + misc_fields['Pipeline Git branch/tag'] = workflow.revision + } + misc_fields['Nextflow Version'] = workflow.nextflow.version + misc_fields['Nextflow Build'] = workflow.nextflow.build misc_fields['Nextflow Compile Timestamp'] = workflow.nextflow.timestamp def email_fields = [:] @@ -337,7 +341,7 @@ def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdi // Render the sendmail template def max_multiqc_email_size = (params.containsKey('max_multiqc_email_size') ? params.max_multiqc_email_size : 0) as nextflow.util.MemoryUnit - def smail_fields = [ email: email_address, subject: subject, email_txt: email_txt, email_html: email_html, projectDir: "${workflow.projectDir}", mqcFile: mqc_report, mqcMaxSize: max_multiqc_email_size.toBytes() ] + def smail_fields = [email: email_address, subject: subject, email_txt: email_txt, email_html: email_html, projectDir: "${workflow.projectDir}", mqcFile: mqc_report, mqcMaxSize: max_multiqc_email_size.toBytes()] def sf = new File("${workflow.projectDir}/assets/sendmail_template.txt") def sendmail_template = engine.createTemplate(sf).make(smail_fields) def sendmail_html = sendmail_template.toString() @@ -346,30 +350,32 @@ def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdi def colors = logColours(monochrome_logs) as Map if (email_address) { try { - if (plaintext_email) { throw new org.codehaus.groovy.GroovyException('Send plaintext e-mail, not HTML') } + if (plaintext_email) { +new org.codehaus.groovy.GroovyException('Send plaintext e-mail, not HTML') } // Try to send HTML e-mail using sendmail def sendmail_tf = new File(workflow.launchDir.toString(), ".sendmail_tmp.html") sendmail_tf.withWriter { w -> w << sendmail_html } - [ 'sendmail', '-t' ].execute() << sendmail_html - log.info "-${colors.purple}[$workflow.manifest.name]${colors.green} Sent summary e-mail to $email_address (sendmail)-" - } catch (all) { + ['sendmail', '-t'].execute() << sendmail_html + log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Sent summary e-mail to ${email_address} (sendmail)-") + } + catch (Exception all) { // Catch failures and try with plaintext - def mail_cmd = [ 'mail', '-s', subject, '--content-type=text/html', email_address ] + def mail_cmd = ['mail', '-s', subject, '--content-type=text/html', email_address] mail_cmd.execute() << email_html - log.info "-${colors.purple}[$workflow.manifest.name]${colors.green} Sent summary e-mail to $email_address (mail)-" + log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Sent summary e-mail to ${email_address} (mail)-") } } // Write summary e-mail HTML to a file def output_hf = new File(workflow.launchDir.toString(), ".pipeline_report.html") output_hf.withWriter { w -> w << email_html } - nextflow.extension.FilesEx.copyTo(output_hf.toPath(), "${outdir}/pipeline_info/pipeline_report.html"); + nextflow.extension.FilesEx.copyTo(output_hf.toPath(), "${outdir}/pipeline_info/pipeline_report.html") output_hf.delete() // Write summary e-mail TXT to a file def output_tf = new File(workflow.launchDir.toString(), ".pipeline_report.txt") output_tf.withWriter { w -> w << email_txt } - nextflow.extension.FilesEx.copyTo(output_tf.toPath(), "${outdir}/pipeline_info/pipeline_report.txt"); + nextflow.extension.FilesEx.copyTo(output_tf.toPath(), "${outdir}/pipeline_info/pipeline_report.txt") output_tf.delete() } @@ -380,12 +386,14 @@ def completionSummary(monochrome_logs=true) { def colors = logColours(monochrome_logs) as Map if (workflow.success) { if (workflow.stats.ignoredCount == 0) { - log.info "-${colors.purple}[$workflow.manifest.name]${colors.green} Pipeline completed successfully${colors.reset}-" - } else { - log.info "-${colors.purple}[$workflow.manifest.name]${colors.yellow} Pipeline completed successfully, but with errored process(es) ${colors.reset}-" + log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Pipeline completed successfully${colors.reset}-") + } + else { + log.info("-${colors.purple}[${workflow.manifest.name}]${colors.yellow} Pipeline completed successfully, but with errored process(es) ${colors.reset}-") } - } else { - log.info "-${colors.purple}[$workflow.manifest.name]${colors.red} Pipeline completed with errors${colors.reset}-" + } + else { + log.info("-${colors.purple}[${workflow.manifest.name}]${colors.red} Pipeline completed with errors${colors.reset}-") } } @@ -394,21 +402,30 @@ def completionSummary(monochrome_logs=true) { // def imNotification(summary_params, hook_url) { def summary = [:] - summary_params.keySet().sort().each { group -> - summary << summary_params[group] - } + summary_params + .keySet() + .sort() + .each { group -> + 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 + 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'] = getWorkflowVersion() @@ -433,13 +450,13 @@ def imNotification(summary_params, hook_url) { def json_message = json_template.toString() // POST - def post = new URL(hook_url).openConnection(); + 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()); + post.getOutputStream().write(json_message.getBytes("UTF-8")) + def postRC = post.getResponseCode() + if (!postRC.equals(200)) { + log.warn(post.getErrorStream().getText()) } } From 4051883ec9f79d188f5d1810b2e961a64058b017 Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Thu, 10 Oct 2024 14:05:47 +0900 Subject: [PATCH 03/22] pre-commit run --all-files --- nextflow.config | 4 ++-- .../local/utils_nfcore_pairgenomealign_pipeline/main.nf | 6 +++--- workflows/pairgenomealign.nf | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/nextflow.config b/nextflow.config index 405bae1..ed83624 100644 --- a/nextflow.config +++ b/nextflow.config @@ -280,10 +280,10 @@ validation { """ afterText = """${manifest.doi ? "* The pipeline\n" : ""}${manifest.doi.tokenize(",").collect { " https://doi.org/${it.trim().replace('https://doi.org/','')}"}.join("\n")}${manifest.doi ? "\n" : ""} * The nf-core framework - https://doi.org/10.1038/s41587-020-0439-x + https://doi.org/10.1038/s41587-020-0439-x * Software dependencies - /~https://github.com/${manifest.name}/blob/master/CITATIONS.md + /~https://github.com/${manifest.name}/blob/master/CITATIONS.md """ } summary { diff --git a/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf b/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf index 99b27e2..bb3bf5b 100644 --- a/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf @@ -47,7 +47,7 @@ workflow PIPELINE_INITIALISATION { workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1 ) - + // // Validate parameters and generate parameter summary to stdout // @@ -56,7 +56,7 @@ workflow PIPELINE_INITIALISATION { validate_params, null ) - + // // Check config provided to the pipeline @@ -94,7 +94,7 @@ workflow PIPELINE_COMPLETION { email // string: email address email_on_fail // string: email address sent on pipeline failure plaintext_email // boolean: Send plain-text email instead of HTML - + outdir // path: Path to output directory where results will be published monochrome_logs // boolean: Disable ANSI colour codes in log output hook_url // string: hook URL for notifications diff --git a/workflows/pairgenomealign.nf b/workflows/pairgenomealign.nf index 6d92904..d818235 100644 --- a/workflows/pairgenomealign.nf +++ b/workflows/pairgenomealign.nf @@ -109,13 +109,13 @@ workflow PAIRGENOMEALIGN { Channel.fromPath(params.multiqc_logo, checkIfExists: true) : Channel.empty() - + summary_params = paramsSummaryMap( workflow, parameters_schema: "nextflow_schema.json") ch_workflow_summary = Channel.value(paramsSummaryMultiqc(summary_params)) ch_multiqc_files = ch_multiqc_files.mix( ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) - + 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) From 56b65338f3824accfbd849a4af6707a4e9d5d8c6 Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Thu, 10 Oct 2024 14:15:33 +0900 Subject: [PATCH 04/22] Remove the max_ parameters that I missed during the merge. --- conf/test.config | 13 ++++++++----- nextflow.config | 6 ------ 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/conf/test.config b/conf/test.config index ae05f53..8f28658 100644 --- a/conf/test.config +++ b/conf/test.config @@ -10,15 +10,18 @@ ---------------------------------------------------------------------------------------- */ +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] +} + 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 = '1.h' - // Input data input = 'https://raw.githubusercontent.com/nf-core/test-datasets/pairgenomealign/tests/testsamplesheet.csv' diff --git a/nextflow.config b/nextflow.config index ed83624..2417056 100644 --- a/nextflow.config +++ b/nextflow.config @@ -55,12 +55,6 @@ params { config_profile_contact = null config_profile_url = null - // Max resource options - // Defaults only, expecting to be overwritten - max_memory = '128.GB' - max_cpus = 16 - max_time = '240.h' - // Indexing options seed = 'YASS' softmask = 'tantan' From 63f42dce1d6bf8ce5ee932d8af70ccf20f2d9531 Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Thu, 10 Oct 2024 16:08:56 +0900 Subject: [PATCH 05/22] Update nextflow.config Co-authored-by: James A. Fellows Yates --- nextflow.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nextflow.config b/nextflow.config index 2417056..3d0d2cf 100644 --- a/nextflow.config +++ b/nextflow.config @@ -183,7 +183,7 @@ profiles { includeConfig !System.getenv('NXF_OFFLINE') && params.custom_config_base ? "${params.custom_config_base}/nfcore_custom.config" : "/dev/null" // Load nf-core/pairgenomealign custom profiles from different institutions. -// includeConfig !System.getenv('NXF_OFFLINE') && params.custom_config_base ? "${params.custom_config_base}/pipeline/pairgenomealign.config" : "/dev/null" +includeConfig !System.getenv('NXF_OFFLINE') && params.custom_config_base ? "${params.custom_config_base}/pipeline/pairgenomealign.config" : "/dev/null" // Set default registry for Apptainer, Docker, Podman, Charliecloud and Singularity independent of -profile // Will not be used unless Apptainer / Docker / Podman / Charliecloud / Singularity are enabled From 5f9097c1ff5db283e5915c04d1c380857573ac13 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Fri, 11 Oct 2024 12:34:06 +0000 Subject: [PATCH 06/22] Template update for nf-core/tools version 3.0.2 --- .github/workflows/ci.yml | 60 +++++++++++++------ .../workflows/template_version_comment.yml | 21 ++++--- .gitignore | 1 + .nf-core.yml | 2 +- main.nf | 2 +- modules.json | 6 +- modules/nf-core/multiqc/main.nf | 2 +- nextflow.config | 4 +- .../main.nf | 4 +- .../nf-core/utils_nextflow_pipeline/main.nf | 30 +++++----- .../nf-core/utils_nfcore_pipeline/main.nf | 10 ++-- workflows/pairgenomealign.nf | 2 - 12 files changed, 86 insertions(+), 58 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0f8d132..6c12d1f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,8 @@ on: env: NXF_ANSI_LOG: false + NXF_SINGULARITY_CACHEDIR: ${{ github.workspace }}/.singularity + NXF_SINGULARITY_LIBRARYDIR: ${{ github.workspace }}/.singularity concurrency: group: "${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}" @@ -18,7 +20,7 @@ concurrency: jobs: test: - name: Run pipeline with test data + name: "Run pipeline with test data (${{ matrix.NXF_VER }} | ${{ matrix.test_name }} | ${{ matrix.profile }})" # Only run on push if this is the nf-core dev branch (merged PRs) if: "${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/pairgenomealign') }}" runs-on: ubuntu-latest @@ -27,33 +29,57 @@ jobs: NXF_VER: - "24.04.2" - "latest-everything" + profile: + - "conda" + - "docker" + - "singularity" + test_name: + - "test" + isMaster: + - ${{ github.base_ref == 'master' }} + # Exclude conda and singularity on dev + exclude: + - isMaster: false + profile: "conda" + - isMaster: false + profile: "singularity" steps: - name: Check out pipeline code uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 - - name: Install Nextflow + - name: Set up Nextflow uses: nf-core/setup-nextflow@v2 with: version: "${{ matrix.NXF_VER }}" - - name: Disk space cleanup - uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + - name: Set up Apptainer + if: matrix.profile == 'singularity' + uses: eWaterCycle/setup-apptainer@main - - name: Run pipeline with test data (docker) - # TODO nf-core: You can customise CI pipeline run tests as required - # For example: adding multiple test runs with different parameters - # Remember that you can parallelise this by using strategy.matrix + - name: Set up Singularity + if: matrix.profile == 'singularity' run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker --outdir ./results + mkdir -p $NXF_SINGULARITY_CACHEDIR + mkdir -p $NXF_SINGULARITY_LIBRARYDIR + + - name: Set up Miniconda + if: matrix.profile == 'conda' + uses: conda-incubator/setup-miniconda@a4260408e20b96e80095f42ff7f1a15b27dd94ca # v3 + with: + miniconda-version: "latest" + auto-update-conda: true + conda-solver: libmamba + channels: conda-forge,bioconda - - name: Run pipeline with test data (singularity) - # TODO nf-core: You can customise CI pipeline run tests as required + - name: Set up Conda + if: matrix.profile == 'conda' run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,singularity --outdir ./results - if: "${{ github.base_ref == 'master' }}" + echo $(realpath $CONDA)/condabin >> $GITHUB_PATH + echo $(realpath python) >> $GITHUB_PATH + + - name: Clean up Disk space + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 - - name: Run pipeline with test data (conda) - # TODO nf-core: You can customise CI pipeline run tests as required + - name: "Run pipeline with test data ${{ matrix.NXF_VER }} | ${{ matrix.test_name }} | ${{ matrix.profile }}" run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,conda --outdir ./results - if: "${{ github.base_ref == 'master' }}" + nextflow run ${GITHUB_WORKSPACE} -profile ${{ matrix.test_name }},${{ matrix.profile }} --outdir ./results diff --git a/.github/workflows/template_version_comment.yml b/.github/workflows/template_version_comment.yml index 9dea41f..e8aafe4 100644 --- a/.github/workflows/template_version_comment.yml +++ b/.github/workflows/template_version_comment.yml @@ -10,9 +10,11 @@ jobs: steps: - name: Check out pipeline code uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 + with: + ref: ${{ github.event.pull_request.head.sha }} - name: Read template version from .nf-core.yml - uses: pietrobolcato/action-read-yaml@1.0.0 + uses: nichmor/minimal-read-yaml@v0.0.2 id: read_yml with: config: ${{ github.workspace }}/.nf-core.yml @@ -24,20 +26,21 @@ jobs: - name: Check nf-core outdated id: nf_core_outdated - run: pip list --outdated | grep nf-core + run: echo "OUTPUT=$(pip list --outdated | grep nf-core)" >> ${GITHUB_ENV} - name: Post nf-core template version comment uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2 if: | - ${{ steps.nf_core_outdated.outputs.stdout }} =~ 'nf-core' + contains(env.OUTPUT, 'nf-core') with: repo-token: ${{ secrets.NF_CORE_BOT_AUTH_TOKEN }} allow-repeats: false message: | - ## :warning: Newer version of the nf-core template is available. - - Your pipeline is using an old version of the nf-core template: ${{ steps.read_yml.outputs['nf_core_version'] }}. - Please update your pipeline to the latest version. - - For more documentation on how to update your pipeline, please see the [nf-core documentation](/~https://github.com/nf-core/tools?tab=readme-ov-file#sync-a-pipeline-with-the-template) and [Synchronisation documentation](https://nf-co.re/docs/contributing/sync). + > [!WARNING] + > Newer version of the nf-core template is available. + > + > Your pipeline is using an old version of the nf-core template: ${{ steps.read_yml.outputs['nf_core_version'] }}. + > Please update your pipeline to the latest version. + > + > For more documentation on how to update your pipeline, please see the [nf-core documentation](/~https://github.com/nf-core/tools?tab=readme-ov-file#sync-a-pipeline-with-the-template) and [Synchronisation documentation](https://nf-co.re/docs/contributing/sync). # diff --git a/.gitignore b/.gitignore index 5124c9a..a42ce01 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ results/ testing/ testing* *.pyc +null/ diff --git a/.nf-core.yml b/.nf-core.yml index 042d6df..8937228 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -4,7 +4,7 @@ lint: - assets/nf-core-pairgenomealign_logo_light.png - docs/images/nf-core-pairgenomealign_logo_light.png - docs/images/nf-core-pairgenomealign_logo_dark.png -nf_core_version: 3.0.1 +nf_core_version: 3.0.2 org_path: null repository_type: pipeline template: diff --git a/main.nf b/main.nf index d617a07..2c02399 100644 --- a/main.nf +++ b/main.nf @@ -76,7 +76,7 @@ workflow { params.outdir, params.input ) - + // // WORKFLOW: Run main workflow // diff --git a/modules.json b/modules.json index 8709171..fa36f31 100644 --- a/modules.json +++ b/modules.json @@ -12,7 +12,7 @@ }, "multiqc": { "branch": "master", - "git_sha": "b8d36829fa84b6e404364abff787e8b07f6d058c", + "git_sha": "cf17ca47590cc578dfb47db1c2a44ef86f89976d", "installed_by": ["modules"] } } @@ -21,12 +21,12 @@ "nf-core": { "utils_nextflow_pipeline": { "branch": "master", - "git_sha": "9d05360da397692321d377b6102d2fb22507c6ef", + "git_sha": "3aa0aec1d52d492fe241919f0c6100ebf0074082", "installed_by": ["subworkflows"] }, "utils_nfcore_pipeline": { "branch": "master", - "git_sha": "772684d9d66f37b650c8ba5146ac1ee3ecba2acb", + "git_sha": "1b6b9a3338d011367137808b49b923515080e3ba", "installed_by": ["subworkflows"] }, "utils_nfschema_plugin": { diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index 9724d2f..cc0643e 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -52,7 +52,7 @@ process MULTIQC { stub: """ mkdir multiqc_data - touch multiqc_plots + mkdir multiqc_plots touch multiqc_report.html cat <<-END_VERSIONS > versions.yml diff --git a/nextflow.config b/nextflow.config index 0797e2d..f82b053 100644 --- a/nextflow.config +++ b/nextflow.config @@ -254,10 +254,10 @@ validation { """ afterText = """${manifest.doi ? "* The pipeline\n" : ""}${manifest.doi.tokenize(",").collect { " https://doi.org/${it.trim().replace('https://doi.org/','')}"}.join("\n")}${manifest.doi ? "\n" : ""} * The nf-core framework - https://doi.org/10.1038/s41587-020-0439-x + https://doi.org/10.1038/s41587-020-0439-x * Software dependencies - /~https://github.com/${manifest.name}/blob/master/CITATIONS.md + /~https://github.com/${manifest.name}/blob/master/CITATIONS.md """ } summary { diff --git a/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf b/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf index 5987d71..1cf551c 100644 --- a/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf @@ -47,7 +47,6 @@ workflow PIPELINE_INITIALISATION { workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1 ) - // // Validate parameters and generate parameter summary to stdout // @@ -56,7 +55,6 @@ workflow PIPELINE_INITIALISATION { validate_params, null ) - // // Check config provided to the pipeline @@ -64,6 +62,7 @@ workflow PIPELINE_INITIALISATION { UTILS_NFCORE_PIPELINE ( nextflow_cli_args ) + // // Custom validation for pipeline parameters // @@ -110,7 +109,6 @@ workflow PIPELINE_COMPLETION { email // string: email address email_on_fail // string: email address sent on pipeline failure plaintext_email // boolean: Send plain-text email instead of HTML - outdir // path: Path to output directory where results will be published monochrome_logs // boolean: Disable ANSI colour codes in log output hook_url // string: hook URL for notifications diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf index 2b0dc67..0fcbf7b 100644 --- a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf @@ -3,9 +3,9 @@ // /* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SUBWORKFLOW DEFINITION -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ workflow UTILS_NEXTFLOW_PIPELINE { @@ -44,9 +44,9 @@ workflow UTILS_NEXTFLOW_PIPELINE { } /* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FUNCTIONS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ // @@ -106,17 +106,19 @@ def checkCondaChannels() { def channels_missing = ((required_channels_in_order as Set) - (channels as Set)) as Boolean // Check that they are in the right order - def channel_priority_violation = false - - required_channels_in_order.eachWithIndex { channel, index -> - if (index < required_channels_in_order.size() - 1) { - channel_priority_violation |= !(channels.indexOf(channel) < channels.indexOf(required_channels_in_order[index + 1])) - } - } + def channel_priority_violation = required_channels_in_order != channels.findAll { ch -> ch in required_channels_in_order } 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/\n" + " The observed channel order is \n" + " ${channels}\n" + " but the following channel order is required:\n" + " ${required_channels_in_order}\n" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" - ) + log.warn """\ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + There is a problem with your Conda configuration! + You will need to set-up the conda-forge and bioconda channels correctly. + Please refer to https://bioconda.github.io/ + The observed channel order is + ${channels} + but the following channel order is required: + ${required_channels_in_order} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + """.stripIndent(true) } } diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf index b78273c..5cb7baf 100644 --- a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf @@ -3,9 +3,9 @@ // /* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SUBWORKFLOW DEFINITION -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ workflow UTILS_NFCORE_PIPELINE { @@ -21,9 +21,9 @@ workflow UTILS_NFCORE_PIPELINE { } /* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FUNCTIONS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ // @@ -62,7 +62,7 @@ def checkProfileProvided(nextflow_cli_args) { def workflowCitation() { def temp_doi_ref = "" def manifest_doi = workflow.manifest.doi.tokenize(",") - // Using a loop to handle multiple DOIs + // Handling multiple DOIs // Removing `https://doi.org/` to handle pipelines using DOIs vs DOI resolvers // Removing ` ` since the manifest.doi is a string and not a proper list manifest_doi.each { doi_ref -> diff --git a/workflows/pairgenomealign.nf b/workflows/pairgenomealign.nf index b6076b5..2d973be 100644 --- a/workflows/pairgenomealign.nf +++ b/workflows/pairgenomealign.nf @@ -57,13 +57,11 @@ workflow PAIRGENOMEALIGN { Channel.fromPath(params.multiqc_logo, checkIfExists: true) : Channel.empty() - summary_params = paramsSummaryMap( workflow, parameters_schema: "nextflow_schema.json") ch_workflow_summary = Channel.value(paramsSummaryMultiqc(summary_params)) ch_multiqc_files = ch_multiqc_files.mix( ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) - 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) From 5fa28127565b498447a0d4c6f0844a22b2fc45b5 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Thu, 12 Dec 2024 11:25:35 +0000 Subject: [PATCH 07/22] Template update for nf-core/tools version 3.1.0 --- .github/CONTRIBUTING.md | 12 +- .github/workflows/awsfulltest.yml | 21 +- .github/workflows/branch.yml | 18 +- .github/workflows/ci.yml | 2 +- .github/workflows/download_pipeline.yml | 8 +- .github/workflows/fix-linting.yml | 4 +- .github/workflows/linting.yml | 10 +- .github/workflows/linting_comment.yml | 2 +- .github/workflows/release-announcements.yml | 2 +- .../workflows/template_version_comment.yml | 2 +- .gitpod.yml | 11 +- .nf-core.yml | 6 +- .vscode/settings.json | 3 + conf/base.config | 2 +- conf/modules.config | 1 + docs/usage.md | 32 +- modules.json | 8 +- modules/nf-core/fastqc/main.nf | 2 +- modules/nf-core/fastqc/meta.yml | 1 + nextflow.config | 45 ++- nextflow_schema.json | 6 + ro-crate-metadata.json | 316 ++++++++++++++++++ .../main.nf | 7 +- .../nf-core/utils_nextflow_pipeline/main.nf | 2 + .../tests/main.workflow.nf.test | 10 +- .../nf-core/utils_nfcore_pipeline/main.nf | 89 ++--- .../tests/main.function.nf.test | 46 ++- .../tests/main.function.nf.test.snap | 30 -- .../utils_nfschema_plugin/tests/main.nf.test | 4 +- workflows/pairgenomealign.nf | 2 +- 30 files changed, 486 insertions(+), 218 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 ro-crate-metadata.json diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 05936b4..d05e9ad 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# nf-core/pairgenomealign: Contributing Guidelines +# `nf-core/pairgenomealign`: Contributing Guidelines Hi there! Many thanks for taking an interest in improving nf-core/pairgenomealign. @@ -55,9 +55,9 @@ These tests are run both with the latest available version of `Nextflow` and als :warning: Only in the unlikely and regretful event of a release happening with a bug. -- On your own fork, make a new branch `patch` based on `upstream/master`. +- On your own fork, make a new branch `patch` based on `upstream/main` or `upstream/master`. - Fix the bug, and bump version (X.Y.Z+1). -- A PR should be made on `master` from patch to directly this particular bug. +- Open a pull-request from `patch` to `main`/`master` with the changes. ## Getting help @@ -65,13 +65,13 @@ For further information/help, please consult the [nf-core/pairgenomealign docume ## Pipeline contribution conventions -To make the nf-core/pairgenomealign code and processing logic more understandable for new contributors and to ensure quality, we semi-standardise the way the code and other contributions are written. +To make the `nf-core/pairgenomealign` code and processing logic more understandable for new contributors and to ensure quality, we semi-standardise the way the code and other contributions are written. ### Adding a new step If you wish to contribute a new step, please use the following coding standards: -1. Define the corresponding input channel into your new process from the expected previous process channel +1. Define the corresponding input channel into your new process from the expected previous process channel. 2. Write the process block (see below). 3. Define the output channel if needed (see below). 4. Add any new parameters to `nextflow.config` with a default (see below). @@ -84,7 +84,7 @@ If you wish to contribute a new step, please use the following coding standards: ### Default values -Parameters should be initialised / defined with default values in `nextflow.config` under the `params` scope. +Parameters should be initialised / defined with default values within the `params` scope in `nextflow.config`. Once there, use `nf-core pipelines schema build` to add to `nextflow_schema.json`. diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 8c281d1..b39d02d 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -1,11 +1,12 @@ name: nf-core AWS full size tests -# This workflow is triggered on PRs opened against the master branch. +# This workflow is triggered on PRs opened against the main/master branch. # It can be additionally triggered manually with GitHub actions workflow dispatch button. # It runs the -profile 'test_full' on AWS batch on: pull_request: branches: + - main - master workflow_dispatch: pull_request_review: @@ -18,18 +19,30 @@ jobs: if: github.repository == 'nf-core/pairgenomealign' && github.event.review.state == 'approved' && github.event.pull_request.base.ref == 'master' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest steps: - - uses: octokit/request-action@v2.x + - name: Get PR reviews + uses: octokit/request-action@v2.x + if: github.event_name != 'workflow_dispatch' id: check_approvals + continue-on-error: true with: - route: GET /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews + route: GET /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews?per_page=100 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - id: test_variables + + - name: Check for approvals + if: ${{ failure() && github.event_name != 'workflow_dispatch' }} + run: | + echo "No review approvals found. At least 2 approvals are required to run this action automatically." + exit 1 + + - name: Check for enough approvals (>=2) + id: test_variables if: github.event_name != 'workflow_dispatch' run: | JSON_RESPONSE='${{ steps.check_approvals.outputs.data }}' CURRENT_APPROVALS_COUNT=$(echo $JSON_RESPONSE | jq -c '[.[] | select(.state | contains("APPROVED")) ] | length') test $CURRENT_APPROVALS_COUNT -ge 2 || exit 1 # At least 2 approvals are required + - name: Launch workflow via Seqera Platform uses: seqeralabs/action-tower-launch@v2 # TODO nf-core: You can customise AWS full pipeline tests as required diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml index 5d593a9..ec00a70 100644 --- a/.github/workflows/branch.yml +++ b/.github/workflows/branch.yml @@ -1,15 +1,17 @@ name: nf-core branch protection -# This workflow is triggered on PRs to master branch on the repository -# It fails when someone tries to make a PR against the nf-core `master` branch instead of `dev` +# This workflow is triggered on PRs to `main`/`master` branch on the repository +# It fails when someone tries to make a PR against the nf-core `main`/`master` branch instead of `dev` on: pull_request_target: - branches: [master] + branches: + - main + - master jobs: test: runs-on: ubuntu-latest steps: - # PRs to the nf-core repo master branch are only ok if coming from the nf-core repo `dev` or any `patch` branches + # PRs to the nf-core repo main/master branch are only ok if coming from the nf-core repo `dev` or any `patch` branches - name: Check PRs if: github.repository == 'nf-core/pairgenomealign' run: | @@ -22,7 +24,7 @@ jobs: uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2 with: message: | - ## This PR is against the `master` branch :x: + ## This PR is against the `${{github.event.pull_request.base.ref}}` branch :x: * Do not close this PR * Click _Edit_ and change the `base` to `dev` @@ -32,9 +34,9 @@ jobs: Hi @${{ github.event.pull_request.user.login }}, - It looks like this pull-request is has been made against the [${{github.event.pull_request.head.repo.full_name }}](/~https://github.com/${{github.event.pull_request.head.repo.full_name }}) `master` branch. - The `master` branch on nf-core repositories should always contain code from the latest release. - Because of this, PRs to `master` are only allowed if they come from the [${{github.event.pull_request.head.repo.full_name }}](/~https://github.com/${{github.event.pull_request.head.repo.full_name }}) `dev` branch. + It looks like this pull-request is has been made against the [${{github.event.pull_request.head.repo.full_name }}](/~https://github.com/${{github.event.pull_request.head.repo.full_name }}) ${{github.event.pull_request.base.ref}} branch. + The ${{github.event.pull_request.base.ref}} branch on nf-core repositories should always contain code from the latest release. + Because of this, PRs to ${{github.event.pull_request.base.ref}} are only allowed if they come from the [${{github.event.pull_request.head.repo.full_name }}](/~https://github.com/${{github.event.pull_request.head.repo.full_name }}) `dev` branch. You do not need to close this PR, you can change the target branch to `dev` by clicking the _"Edit"_ button at the top of this page. Note that even after this, the test will continue to show as failing until you push a new commit. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c12d1f..8da0a02 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,7 +45,7 @@ jobs: profile: "singularity" steps: - name: Check out pipeline code - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Set up Nextflow uses: nf-core/setup-nextflow@v2 diff --git a/.github/workflows/download_pipeline.yml b/.github/workflows/download_pipeline.yml index 713dc3e..2576cc0 100644 --- a/.github/workflows/download_pipeline.yml +++ b/.github/workflows/download_pipeline.yml @@ -2,7 +2,7 @@ name: Test successful pipeline download with 'nf-core pipelines download' # Run the workflow when: # - dispatched manually -# - when a PR is opened or reopened to master branch +# - when a PR is opened or reopened to main/master branch # - the head branch of the pull request is updated, i.e. if fixes for a release are pushed last minute to dev. on: workflow_dispatch: @@ -17,9 +17,11 @@ on: - edited - synchronize branches: + - main - master pull_request_target: branches: + - main - master env: @@ -35,7 +37,7 @@ jobs: - name: Disk space cleanup uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 - - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5 + - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5 with: python-version: "3.12" architecture: "x64" @@ -69,7 +71,7 @@ jobs: --outdir ./${{ env.REPOTITLE_LOWERCASE }} \ --compress "none" \ --container-system 'singularity' \ - --container-library "quay.io" -l "docker.io" -l "community.wave.seqera.io" \ + --container-library "quay.io" -l "docker.io" -l "community.wave.seqera.io/library/" \ --container-cache-utilisation 'amend' \ --download-configuration 'yes' diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml index 37dca1d..8805d20 100644 --- a/.github/workflows/fix-linting.yml +++ b/.github/workflows/fix-linting.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: token: ${{ secrets.nf_core_bot_auth_token }} @@ -32,7 +32,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.nf_core_bot_auth_token }} # Install and run pre-commit - - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5 + - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5 with: python-version: "3.12" diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index a502573..dbd52d5 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -14,10 +14,10 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Set up Python 3.12 - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5 with: python-version: "3.12" @@ -31,12 +31,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out pipeline code - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Install Nextflow uses: nf-core/setup-nextflow@v2 - - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5 + - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5 with: python-version: "3.12" architecture: "x64" @@ -74,7 +74,7 @@ jobs: - name: Upload linting log file artifact if: ${{ always() }} - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4 with: name: linting-logs path: | diff --git a/.github/workflows/linting_comment.yml b/.github/workflows/linting_comment.yml index 42e519b..0bed96d 100644 --- a/.github/workflows/linting_comment.yml +++ b/.github/workflows/linting_comment.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Download lint results - uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11 # v6 + uses: dawidd6/action-download-artifact@80620a5d27ce0ae443b965134db88467fc607b43 # v7 with: workflow: linting.yml workflow_conclusion: completed diff --git a/.github/workflows/release-announcements.yml b/.github/workflows/release-announcements.yml index c6ba35d..450b1d5 100644 --- a/.github/workflows/release-announcements.yml +++ b/.github/workflows/release-announcements.yml @@ -31,7 +31,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5 + - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5 with: python-version: "3.10" - name: Install dependencies diff --git a/.github/workflows/template_version_comment.yml b/.github/workflows/template_version_comment.yml index e8aafe4..537529b 100644 --- a/.github/workflows/template_version_comment.yml +++ b/.github/workflows/template_version_comment.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out pipeline code - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: ref: ${{ github.event.pull_request.head.sha }} diff --git a/.gitpod.yml b/.gitpod.yml index 4611863..83599f6 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -6,12 +6,5 @@ tasks: nextflow self-update vscode: - extensions: # based on nf-core.nf-core-extensionpack - #- esbenp.prettier-vscode # Markdown/CommonMark linting and style checking for Visual Studio Code - - EditorConfig.EditorConfig # override user/workspace settings with settings found in .editorconfig files - - Gruntfuggly.todo-tree # Display TODO and FIXME in a tree view in the activity bar - - mechatroner.rainbow-csv # Highlight columns in csv files in different colors - - nextflow.nextflow # Nextflow syntax highlighting - - oderwat.indent-rainbow # Highlight indentation level - - streetsidesoftware.code-spell-checker # Spelling checker for source code - - charliermarsh.ruff # Code linter Ruff + extensions: + - nf-core.nf-core-extensionpack # /~https://github.com/nf-core/vscode-extensionpack diff --git a/.nf-core.yml b/.nf-core.yml index 8937228..c871964 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -1,11 +1,9 @@ -bump_version: null lint: files_unchanged: - assets/nf-core-pairgenomealign_logo_light.png - docs/images/nf-core-pairgenomealign_logo_light.png - docs/images/nf-core-pairgenomealign_logo_dark.png -nf_core_version: 3.0.2 -org_path: null +nf_core_version: 3.1.0 repository_type: pipeline template: author: charles-plessy @@ -15,6 +13,4 @@ template: name: pairgenomealign org: nf-core outdir: . - skip_features: null version: 1.1.0 -update: null diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a33b527 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "markdown.styles": ["public/vscode_markdown.css"] +} diff --git a/conf/base.config b/conf/base.config index a5a70e9..17b5c64 100644 --- a/conf/base.config +++ b/conf/base.config @@ -20,7 +20,7 @@ process { maxErrors = '-1' // Process-specific resource requirements - // NOTE - Please try and re-use the labels below as much as possible. + // NOTE - Please try and reuse the labels below as much as possible. // These labels are used and recognised by default in DSL2 files hosted on nf-core/modules. // If possible, it would be nice to keep the same label naming convention when // adding in your local modules too. diff --git a/conf/modules.config b/conf/modules.config index d266a38..d203d2b 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -21,6 +21,7 @@ process { withName: FASTQC { ext.args = '--quiet' } + withName: 'MULTIQC' { ext.args = { params.multiqc_title ? "--title \"$params.multiqc_title\"" : '' } publishDir = [ diff --git a/docs/usage.md b/docs/usage.md index 1268284..1e0f30a 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -75,9 +75,8 @@ If you wish to repeatedly use the same parameters for multiple runs, rather than Pipeline settings can be provided in a `yaml` or `json` file via `-params-file `. -:::warning -Do not use `-c ` to specify parameters as this will result in errors. Custom config files specified with `-c` must only be used for [tuning process resource specifications](https://nf-co.re/docs/usage/configuration#tuning-workflow-resources), other infrastructural tweaks (such as output directories), or module arguments (args). -::: +> [!WARNING] +> Do not use `-c ` to specify parameters as this will result in errors. Custom config files specified with `-c` must only be used for [tuning process resource specifications](https://nf-co.re/docs/usage/configuration#tuning-workflow-resources), other infrastructural tweaks (such as output directories), or module arguments (args). The above pipeline run specified with a params file in yaml format: @@ -106,23 +105,21 @@ nextflow pull nf-core/pairgenomealign ### 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. +It is a good idea to specify the 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/pairgenomealign releases page](/~https://github.com/nf-core/pairgenomealign/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. For example, at the bottom of the MultiQC reports. -To further assist in reproducbility, you can use share and re-use [parameter files](#running-the-pipeline) to repeat pipeline runs with the same settings without having to write out a command with every single parameter. +To further assist in reproducibility, you can use share and reuse [parameter files](#running-the-pipeline) to repeat pipeline runs with the same settings without having to write out a command with every single parameter. -:::tip -If you wish to share such profile (such as upload as supplementary material for academic publications), make sure to NOT include cluster specific paths to files, nor institutional specific profiles. -::: +> [!TIP] +> If you wish to share such profile (such as upload as supplementary material for academic publications), make sure to NOT include cluster specific paths to files, nor institutional specific profiles. ## Core Nextflow arguments -:::note -These options are part of Nextflow and use a _single_ hyphen (pipeline parameters use a double-hyphen). -::: +> [!NOTE] +> These options are part of Nextflow and use a _single_ hyphen (pipeline parameters use a double-hyphen) ### `-profile` @@ -130,16 +127,15 @@ Use this parameter to choose a configuration profile. Profiles can give configur Several generic profiles are bundled with the pipeline which instruct the pipeline to use software packaged using different methods (Docker, Singularity, Podman, Shifter, Charliecloud, Apptainer, Conda) - see below. -:::info -We highly recommend the use of Docker or Singularity containers for full pipeline reproducibility, however when this is not possible, Conda is also supported. -::: +> [!IMPORTANT] +> We highly recommend the use of Docker or Singularity containers for full pipeline reproducibility, however when this is not possible, Conda is also supported. -The pipeline also dynamically loads configurations from [/~https://github.com/nf-core/configs](/~https://github.com/nf-core/configs) when it runs, making multiple config profiles for various institutional clusters available at run time. For more information and to see if your system is available in these configs please see the [nf-core/configs documentation](/~https://github.com/nf-core/configs#documentation). +The pipeline also dynamically loads configurations from [/~https://github.com/nf-core/configs](/~https://github.com/nf-core/configs) when it runs, making multiple config profiles for various institutional clusters available at run time. For more information and to check if your system is suported, please see the [nf-core/configs documentation](/~https://github.com/nf-core/configs#documentation). 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, since it can lead to different results on different machines dependent on the computer enviroment. +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 environment. - `test` - A profile with a complete configuration for automated testing @@ -175,13 +171,13 @@ Specify the path to a specific config file (this is a core Nextflow command). Se ### Resource requests -Whilst the default requirements set within the pipeline will hopefully work for most people and with most input data, you may find that you want to customise the compute resources that the pipeline requests. Each step in the pipeline has a default set of requirements for number of CPUs, memory and time. For most of the steps in the pipeline, if the job exits with any of the error codes specified [here](/~https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/conf/base.config#L18) it will automatically be resubmitted with higher requests (2 x original, then 3 x original). If it still fails after the third attempt then the pipeline execution is stopped. +Whilst the default requirements set within the pipeline will hopefully work for most people and with most input data, you may find that you want to customise the compute resources that the pipeline requests. Each step in the pipeline has a default set of requirements for number of CPUs, memory and time. For most of the pipeline steps, if the job exits with any of the error codes specified [here](/~https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/conf/base.config#L18) it will automatically be resubmitted with higher resources request (2 x original, then 3 x original). If it still fails after the third attempt then the pipeline execution is stopped. To change the resource requests, please see the [max resources](https://nf-co.re/docs/usage/configuration#max-resources) and [tuning workflow resources](https://nf-co.re/docs/usage/configuration#tuning-workflow-resources) section of the nf-core website. ### Custom Containers -In some cases you may wish to change which container or conda environment a step of the pipeline uses for a particular tool. By default nf-core pipelines use containers and software from the [biocontainers](https://biocontainers.pro/) or [bioconda](https://bioconda.github.io/) projects. However in some cases the pipeline specified version maybe out of date. +In some cases, you may wish to change the container or conda environment used by a pipeline steps for a particular tool. By default, nf-core pipelines use containers and software from the [biocontainers](https://biocontainers.pro/) or [bioconda](https://bioconda.github.io/) projects. However, in some cases the pipeline specified version maybe out of date. To use a different container from the default container or conda environment specified in a pipeline, please see the [updating tool versions](https://nf-co.re/docs/usage/configuration#updating-tool-versions) section of the nf-core website. diff --git a/modules.json b/modules.json index fa36f31..127315c 100644 --- a/modules.json +++ b/modules.json @@ -7,7 +7,7 @@ "nf-core": { "fastqc": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "dc94b6ee04a05ddb9f7ae050712ff30a13149164", "installed_by": ["modules"] }, "multiqc": { @@ -21,17 +21,17 @@ "nf-core": { "utils_nextflow_pipeline": { "branch": "master", - "git_sha": "3aa0aec1d52d492fe241919f0c6100ebf0074082", + "git_sha": "c2b22d85f30a706a3073387f30380704fcae013b", "installed_by": ["subworkflows"] }, "utils_nfcore_pipeline": { "branch": "master", - "git_sha": "1b6b9a3338d011367137808b49b923515080e3ba", + "git_sha": "51ae5406a030d4da1e49e4dab49756844fdd6c7a", "installed_by": ["subworkflows"] }, "utils_nfschema_plugin": { "branch": "master", - "git_sha": "bbd5a41f4535a8defafe6080e00ea74c45f4f96c", + "git_sha": "2fd2cd6d0e7b273747f32e465fdc6bcc3ae0814e", "installed_by": ["subworkflows"] } } diff --git a/modules/nf-core/fastqc/main.nf b/modules/nf-core/fastqc/main.nf index d8989f4..752c3a1 100644 --- a/modules/nf-core/fastqc/main.nf +++ b/modules/nf-core/fastqc/main.nf @@ -24,7 +24,7 @@ process FASTQC { // Make list of old name and new name pairs to use for renaming in the bash while loop def old_new_pairs = reads instanceof Path || reads.size() == 1 ? [[ reads, "${prefix}.${reads.extension}" ]] : reads.withIndex().collect { entry, index -> [ entry, "${prefix}_${index + 1}.${entry.extension}" ] } def rename_to = old_new_pairs*.join(' ').join(' ') - def renamed_files = old_new_pairs.collect{ old_name, new_name -> new_name }.join(' ') + def renamed_files = old_new_pairs.collect{ _old_name, new_name -> new_name }.join(' ') // The total amount of allocated RAM by FastQC is equal to the number of threads defined (--threads) time the amount of RAM defined (--memory) // /~https://github.com/s-andrews/FastQC/blob/1faeea0412093224d7f6a07f777fad60a5650795/fastqc#L211-L222 diff --git a/modules/nf-core/fastqc/meta.yml b/modules/nf-core/fastqc/meta.yml index 4827da7..2b2e62b 100644 --- a/modules/nf-core/fastqc/meta.yml +++ b/modules/nf-core/fastqc/meta.yml @@ -11,6 +11,7 @@ tools: FastQC gives general quality metrics about your reads. It provides information about the quality score distribution across your reads, the per base sequence content (%A/C/G/T). + You get information about adapter contamination and other overrepresented sequences. homepage: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/ diff --git a/nextflow.config b/nextflow.config index f82b053..7d67223 100644 --- a/nextflow.config +++ b/nextflow.config @@ -38,8 +38,7 @@ params { show_hidden = false version = false pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/' - - // Config options + trace_report_suffix = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss')// Config options config_profile_name = null config_profile_description = null @@ -153,6 +152,13 @@ profiles { executor.name = 'local' executor.cpus = 4 executor.memory = 8.GB + process { + resourceLimits = [ + memory: 8.GB, + cpus : 4, + time : 1.h + ] + } } test { includeConfig 'conf/test.config' } test_full { includeConfig 'conf/test_full.config' } @@ -201,30 +207,41 @@ set -C # No clobber - prevent output redirection from overwriting files. // Disable process selector warnings by default. Use debug profile to enable warnings. nextflow.enable.configProcessNamesValidation = false -def trace_timestamp = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss') timeline { enabled = true - file = "${params.outdir}/pipeline_info/execution_timeline_${trace_timestamp}.html" + file = "${params.outdir}/pipeline_info/execution_timeline_${params.trace_report_suffix}.html" } report { enabled = true - file = "${params.outdir}/pipeline_info/execution_report_${trace_timestamp}.html" + file = "${params.outdir}/pipeline_info/execution_report_${params.trace_report_suffix}.html" } trace { enabled = true - file = "${params.outdir}/pipeline_info/execution_trace_${trace_timestamp}.txt" + file = "${params.outdir}/pipeline_info/execution_trace_${params.trace_report_suffix}.txt" } dag { enabled = true - file = "${params.outdir}/pipeline_info/pipeline_dag_${trace_timestamp}.html" + file = "${params.outdir}/pipeline_info/pipeline_dag_${params.trace_report_suffix}.html" } manifest { name = 'nf-core/pairgenomealign' - author = """charles-plessy""" + author = """charles-plessy""" // The author field is deprecated from Nextflow version 24.10.0, use contributors instead + contributors = [ + // TODO nf-core: Update the field with the details of the contributors to your pipeline. New with Nextflow version 24.10.0 + [ + name: 'charles-plessy', + affiliation: '', + email: '', + github: '', + contribution: [], // List of contribution types ('author', 'maintainer' or 'contributor') + orcid: '' + ], + ] homePage = '/~https://github.com/nf-core/pairgenomealign' description = """Pairwise alignment pipeline (genome to genome or reads to genome)""" mainScript = 'main.nf' + defaultBranch = 'master' nextflowVersion = '!>=24.04.2' version = '1.1.0' doi = '' @@ -237,9 +254,10 @@ plugins { validation { defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs help { enabled = true - command = "nextflow run $manifest.name -profile --input samplesheet.csv --outdir " + command = "nextflow run nf-core/pairgenomealign -profile --input samplesheet.csv --outdir " fullParameter = "help_full" showHiddenParameter = "show_hidden" beforeText = """ @@ -249,15 +267,15 @@ validation { \033[0;34m |\\ | |__ __ / ` / \\ |__) |__ \033[0;33m} {\033[0m \033[0;34m | \\| | \\__, \\__/ | \\ |___ \033[0;32m\\`-._,-`-,\033[0m \033[0;32m`._,._,\'\033[0m -\033[0;35m ${manifest.name} ${manifest.version}\033[0m +\033[0;35m nf-core/pairgenomealign ${manifest.version}\033[0m -\033[2m----------------------------------------------------\033[0m- """ - afterText = """${manifest.doi ? "* The pipeline\n" : ""}${manifest.doi.tokenize(",").collect { " https://doi.org/${it.trim().replace('https://doi.org/','')}"}.join("\n")}${manifest.doi ? "\n" : ""} + afterText = """${manifest.doi ? "\n* The pipeline\n" : ""}${manifest.doi.tokenize(",").collect { " https://doi.org/${it.trim().replace('https://doi.org/','')}"}.join("\n")}${manifest.doi ? "\n" : ""} * The nf-core framework https://doi.org/10.1038/s41587-020-0439-x * Software dependencies - /~https://github.com/${manifest.name}/blob/master/CITATIONS.md + /~https://github.com/nf-core/pairgenomealign/blob/master/CITATIONS.md """ } summary { @@ -265,6 +283,3 @@ validation { afterText = validation.help.afterText } } - -// Load modules.config for DSL2 module specific options -includeConfig 'conf/modules.config' diff --git a/nextflow_schema.json b/nextflow_schema.json index ab272cb..50289b2 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -218,6 +218,12 @@ "description": "Base URL or local path to location of pipeline test dataset files", "default": "https://raw.githubusercontent.com/nf-core/test-datasets/", "hidden": true + }, + "trace_report_suffix": { + "type": "string", + "fa_icon": "far calendar", + "description": "Suffix to add to the trace report filename. Default is the date and time in the format yyyy-MM-dd_HH-mm-ss.", + "hidden": true } } } diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json new file mode 100644 index 0000000..b647fec --- /dev/null +++ b/ro-crate-metadata.json @@ -0,0 +1,316 @@ +{ + "@context": [ + "https://w3id.org/ro/crate/1.1/context", + { + "GithubService": "https://w3id.org/ro/terms/test#GithubService", + "JenkinsService": "https://w3id.org/ro/terms/test#JenkinsService", + "PlanemoEngine": "https://w3id.org/ro/terms/test#PlanemoEngine", + "TestDefinition": "https://w3id.org/ro/terms/test#TestDefinition", + "TestInstance": "https://w3id.org/ro/terms/test#TestInstance", + "TestService": "https://w3id.org/ro/terms/test#TestService", + "TestSuite": "https://w3id.org/ro/terms/test#TestSuite", + "TravisService": "https://w3id.org/ro/terms/test#TravisService", + "definition": "https://w3id.org/ro/terms/test#definition", + "engineVersion": "https://w3id.org/ro/terms/test#engineVersion", + "instance": "https://w3id.org/ro/terms/test#instance", + "resource": "https://w3id.org/ro/terms/test#resource", + "runsOn": "https://w3id.org/ro/terms/test#runsOn" + } + ], + "@graph": [ + { + "@id": "./", + "@type": "Dataset", + "creativeWorkStatus": "Stable", + "datePublished": "2024-12-12T11:25:19+00:00", + "description": "

    \n \n \n \"nf-core/pairgenomealign\"\n \n

    \n\n[![GitHub Actions CI Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/ci.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/ci.yml)\n[![GitHub Actions Linting Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/pairgenomealign/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A524.04.2-23aa62.svg)](https://www.nextflow.io/)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=/~https://github.com/nf-core/pairgenomealign)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23pairgenomealign-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/pairgenomealign)[![Follow on Twitter](http://img.shields.io/badge/twitter-%40nf__core-1DA1F2?labelColor=000000&logo=twitter)](https://twitter.com/nf_core)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@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)\n\n## Introduction\n\n**nf-core/pairgenomealign** is a bioinformatics pipeline that ...\n\n\n\n\n\n\n1. Read QC ([`FastQC`](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/))\n2. Present QC for raw reads ([`MultiQC`](http://multiqc.info/))\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\n\n\nNow, you can run the pipeline using:\n\n\n\n```bash\nnextflow run nf-core/pairgenomealign \\\n -profile \\\n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/pairgenomealign/usage) and the [parameter documentation](https://nf-co.re/pairgenomealign/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/pairgenomealign/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/pairgenomealign/output).\n\n## Credits\n\nnf-core/pairgenomealign was originally written by charles-plessy.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#pairgenomealign` channel](https://nfcore.slack.com/channels/pairgenomealign) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "hasPart": [ + { + "@id": "main.nf" + }, + { + "@id": "assets/" + }, + { + "@id": "conf/" + }, + { + "@id": "docs/" + }, + { + "@id": "docs/images/" + }, + { + "@id": "modules/" + }, + { + "@id": "modules/nf-core/" + }, + { + "@id": "workflows/" + }, + { + "@id": "subworkflows/" + }, + { + "@id": "nextflow.config" + }, + { + "@id": "README.md" + }, + { + "@id": "nextflow_schema.json" + }, + { + "@id": "CHANGELOG.md" + }, + { + "@id": "LICENSE" + }, + { + "@id": "CODE_OF_CONDUCT.md" + }, + { + "@id": "CITATIONS.md" + }, + { + "@id": "modules.json" + }, + { + "@id": "docs/usage.md" + }, + { + "@id": "docs/output.md" + }, + { + "@id": ".nf-core.yml" + }, + { + "@id": ".pre-commit-config.yaml" + }, + { + "@id": ".prettierignore" + } + ], + "isBasedOn": "/~https://github.com/nf-core/pairgenomealign", + "license": "MIT", + "mainEntity": { + "@id": "main.nf" + }, + "mentions": [ + { + "@id": "#a8e256ba-7fb9-4ec0-8d4e-3cc173a8852b" + } + ], + "name": "nf-core/pairgenomealign" + }, + { + "@id": "ro-crate-metadata.json", + "@type": "CreativeWork", + "about": { + "@id": "./" + }, + "conformsTo": [ + { + "@id": "https://w3id.org/ro/crate/1.1" + }, + { + "@id": "https://w3id.org/workflowhub/workflow-ro-crate/1.0" + } + ] + }, + { + "@id": "main.nf", + "@type": ["File", "SoftwareSourceCode", "ComputationalWorkflow"], + "creator": [ + { + "@id": "https://orcid.org/0000-0001-7410-6295" + } + ], + "dateCreated": "", + "dateModified": "2024-12-12T11:25:19Z", + "dct:conformsTo": "https://bioschemas.org/profiles/ComputationalWorkflow/1.0-RELEASE/", + "keywords": [ + "nf-core", + "nextflow", + "comparative-genomics", + "dot-plot", + "genomics", + "last", + "pairwise-alignment", + "synteny", + "whole-genome-alignment" + ], + "license": ["MIT"], + "name": ["nf-core/pairgenomealign"], + "programmingLanguage": { + "@id": "https://w3id.org/workflowhub/workflow-ro-crate#nextflow" + }, + "sdPublisher": { + "@id": "https://nf-co.re/" + }, + "url": ["/~https://github.com/nf-core/pairgenomealign", "https://nf-co.re/pairgenomealign/1.1.0/"], + "version": ["1.1.0"] + }, + { + "@id": "https://w3id.org/workflowhub/workflow-ro-crate#nextflow", + "@type": "ComputerLanguage", + "identifier": { + "@id": "https://www.nextflow.io/" + }, + "name": "Nextflow", + "url": { + "@id": "https://www.nextflow.io/" + }, + "version": "!>=24.04.2" + }, + { + "@id": "#a8e256ba-7fb9-4ec0-8d4e-3cc173a8852b", + "@type": "TestSuite", + "instance": [ + { + "@id": "#95085646-ac04-49b3-9807-1c8cd0001334" + } + ], + "mainEntity": { + "@id": "main.nf" + }, + "name": "Test suite for nf-core/pairgenomealign" + }, + { + "@id": "#95085646-ac04-49b3-9807-1c8cd0001334", + "@type": "TestInstance", + "name": "GitHub Actions workflow for testing nf-core/pairgenomealign", + "resource": "repos/nf-core/pairgenomealign/actions/workflows/ci.yml", + "runsOn": { + "@id": "https://w3id.org/ro/terms/test#GithubService" + }, + "url": "https://api.github.com" + }, + { + "@id": "https://w3id.org/ro/terms/test#GithubService", + "@type": "TestService", + "name": "Github Actions", + "url": { + "@id": "https://github.com" + } + }, + { + "@id": "assets/", + "@type": "Dataset", + "description": "Additional files" + }, + { + "@id": "conf/", + "@type": "Dataset", + "description": "Configuration files" + }, + { + "@id": "docs/", + "@type": "Dataset", + "description": "Markdown files for documenting the pipeline" + }, + { + "@id": "docs/images/", + "@type": "Dataset", + "description": "Images for the documentation files" + }, + { + "@id": "modules/", + "@type": "Dataset", + "description": "Modules used by the pipeline" + }, + { + "@id": "modules/nf-core/", + "@type": "Dataset", + "description": "nf-core modules" + }, + { + "@id": "workflows/", + "@type": "Dataset", + "description": "Main pipeline workflows to be executed in main.nf" + }, + { + "@id": "subworkflows/", + "@type": "Dataset", + "description": "Smaller subworkflows" + }, + { + "@id": "nextflow.config", + "@type": "File", + "description": "Main Nextflow configuration file" + }, + { + "@id": "README.md", + "@type": "File", + "description": "Basic pipeline usage information" + }, + { + "@id": "nextflow_schema.json", + "@type": "File", + "description": "JSON schema for pipeline parameter specification" + }, + { + "@id": "CHANGELOG.md", + "@type": "File", + "description": "Information on changes made to the pipeline" + }, + { + "@id": "LICENSE", + "@type": "File", + "description": "The license - should be MIT" + }, + { + "@id": "CODE_OF_CONDUCT.md", + "@type": "File", + "description": "The nf-core code of conduct" + }, + { + "@id": "CITATIONS.md", + "@type": "File", + "description": "Citations needed when using the pipeline" + }, + { + "@id": "modules.json", + "@type": "File", + "description": "Version information for modules from nf-core/modules" + }, + { + "@id": "docs/usage.md", + "@type": "File", + "description": "Usage documentation" + }, + { + "@id": "docs/output.md", + "@type": "File", + "description": "Output documentation" + }, + { + "@id": ".nf-core.yml", + "@type": "File", + "description": "nf-core configuration file, configuring template features and linting rules" + }, + { + "@id": ".pre-commit-config.yaml", + "@type": "File", + "description": "Configuration file for pre-commit hooks" + }, + { + "@id": ".prettierignore", + "@type": "File", + "description": "Ignore file for prettier" + }, + { + "@id": "https://nf-co.re/", + "@type": "Organization", + "name": "nf-core", + "url": "https://nf-co.re/" + }, + { + "@id": "https://orcid.org/0000-0001-7410-6295", + "@type": "Person", + "email": "charles.plessy@oist.jp", + "name": "Charles Plessy" + } + ] +} diff --git a/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf b/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf index 1cf551c..3a1c91a 100644 --- a/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf @@ -116,7 +116,8 @@ workflow PIPELINE_COMPLETION { main: summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") - + def multiqc_reports = multiqc_report.toList() + // // Completion email and summary // @@ -129,7 +130,7 @@ workflow PIPELINE_COMPLETION { plaintext_email, outdir, monochrome_logs, - multiqc_report.toList() + multiqc_reports.getVal(), ) } @@ -225,7 +226,7 @@ def toolBibliographyText() { } def methodsDescriptionText(mqc_methods_yaml) { - // Convert to a named map so can be used as with familar NXF ${workflow} variable syntax in the MultiQC YML file + // Convert to a named map so can be used as with familiar NXF ${workflow} variable syntax in the MultiQC YML file def meta = [:] meta.workflow = workflow.toMap() meta["manifest_map"] = workflow.manifest.toMap() diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf index 0fcbf7b..d6e593e 100644 --- a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf @@ -92,10 +92,12 @@ def checkCondaChannels() { channels = config.channels } catch (NullPointerException e) { + log.debug(e) log.warn("Could not verify conda channel configuration.") return null } catch (IOException e) { + log.debug(e) log.warn("Could not verify conda channel configuration.") return null } diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.workflow.nf.test b/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.workflow.nf.test index ca964ce..02dbf09 100644 --- a/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.workflow.nf.test +++ b/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.workflow.nf.test @@ -52,10 +52,12 @@ nextflow_workflow { } then { - assertAll( - { assert workflow.success }, - { assert workflow.stdout.contains("nextflow_workflow v9.9.9") } - ) + expect { + with(workflow) { + assert success + assert "nextflow_workflow v9.9.9" in stdout + } + } } } diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf index 5cb7baf..bfd2587 100644 --- a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf @@ -56,21 +56,6 @@ def checkProfileProvided(nextflow_cli_args) { } } -// -// Citation string for pipeline -// -def workflowCitation() { - def temp_doi_ref = "" - def manifest_doi = workflow.manifest.doi.tokenize(",") - // Handling multiple DOIs - // Removing `https://doi.org/` to handle pipelines using DOIs vs DOI resolvers - // Removing ` ` since the manifest.doi is a string and not a proper list - manifest_doi.each { doi_ref -> - temp_doi_ref += " https://doi.org/${doi_ref.replace('https://doi.org/', '').replace(' ', '')}\n" - } - return "If you use ${workflow.manifest.name} for your analysis please cite:\n\n" + "* The pipeline\n" + temp_doi_ref + "\n" + "* The nf-core framework\n" + " https://doi.org/10.1038/s41587-020-0439-x\n\n" + "* Software dependencies\n" + " /~https://github.com/${workflow.manifest.name}/blob/master/CITATIONS.md" -} - // // Generate workflow version string // @@ -150,33 +135,6 @@ def paramsSummaryMultiqc(summary_params) { return yaml_file_text } -// -// nf-core logo -// -def nfCoreLogo(monochrome_logs=true) { - def colors = logColours(monochrome_logs) as Map - String.format( - """\n - ${dashedLine(monochrome_logs)} - ${colors.green},--.${colors.black}/${colors.green},-.${colors.reset} - ${colors.blue} ___ __ __ __ ___ ${colors.green}/,-._.--~\'${colors.reset} - ${colors.blue} |\\ | |__ __ / ` / \\ |__) |__ ${colors.yellow}} {${colors.reset} - ${colors.blue} | \\| | \\__, \\__/ | \\ |___ ${colors.green}\\`-._,-`-,${colors.reset} - ${colors.green}`._,._,\'${colors.reset} - ${colors.purple} ${workflow.manifest.name} ${getWorkflowVersion()}${colors.reset} - ${dashedLine(monochrome_logs)} - """.stripIndent() - ) -} - -// -// Return dashed line -// -def dashedLine(monochrome_logs=true) { - def colors = logColours(monochrome_logs) as Map - return "-${colors.dim}----------------------------------------------------${colors.reset}-" -} - // // ANSII colours used for terminal logging // @@ -245,28 +203,24 @@ def logColours(monochrome_logs=true) { return colorcodes } -// -// Attach the multiqc report to email -// -def attachMultiqcReport(multiqc_report) { - def mqc_report = null - try { - if (workflow.success) { - mqc_report = multiqc_report.getVal() - if (mqc_report.getClass() == ArrayList && mqc_report.size() >= 1) { - if (mqc_report.size() > 1) { - log.warn("[${workflow.manifest.name}] Found multiple reports from process 'MULTIQC', will use only one") - } - mqc_report = mqc_report[0] - } +// Return a single report from an object that may be a Path or List +// +def getSingleReport(multiqc_reports) { + if (multiqc_reports instanceof Path) { + return multiqc_reports + } else if (multiqc_reports instanceof List) { + if (multiqc_reports.size() == 0) { + log.warn("[${workflow.manifest.name}] No reports found from process 'MULTIQC'") + return null + } else if (multiqc_reports.size() == 1) { + return multiqc_reports.first() + } else { + log.warn("[${workflow.manifest.name}] Found multiple reports from process 'MULTIQC', will use only one") + return multiqc_reports.first() } + } else { + return null } - catch (Exception all) { - if (multiqc_report) { - log.warn("[${workflow.manifest.name}] Could not attach MultiQC report to summary email") - } - } - return mqc_report } // @@ -320,7 +274,7 @@ def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdi email_fields['summary'] = summary << misc_fields // On success try attach the multiqc report - def mqc_report = attachMultiqcReport(multiqc_report) + def mqc_report = getSingleReport(multiqc_report) // Check if we are only sending emails on failure def email_address = email @@ -340,7 +294,7 @@ def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdi def email_html = html_template.toString() // Render the sendmail template - def max_multiqc_email_size = (params.containsKey('max_multiqc_email_size') ? params.max_multiqc_email_size : 0) as nextflow.util.MemoryUnit + def max_multiqc_email_size = (params.containsKey('max_multiqc_email_size') ? params.max_multiqc_email_size : 0) as MemoryUnit def smail_fields = [email: email_address, subject: subject, email_txt: email_txt, email_html: email_html, projectDir: "${workflow.projectDir}", mqcFile: mqc_report, mqcMaxSize: max_multiqc_email_size.toBytes()] def sf = new File("${workflow.projectDir}/assets/sendmail_template.txt") def sendmail_template = engine.createTemplate(sf).make(smail_fields) @@ -351,14 +305,17 @@ def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdi if (email_address) { try { if (plaintext_email) { -new org.codehaus.groovy.GroovyException('Send plaintext e-mail, not HTML') } + new org.codehaus.groovy.GroovyException('Send plaintext e-mail, not HTML') + } // Try to send HTML e-mail using sendmail def sendmail_tf = new File(workflow.launchDir.toString(), ".sendmail_tmp.html") sendmail_tf.withWriter { w -> w << sendmail_html } ['sendmail', '-t'].execute() << sendmail_html log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Sent summary e-mail to ${email_address} (sendmail)-") } - catch (Exception all) { + catch (Exception msg) { + log.debug(msg.toString()) + log.debug("Trying with mail instead of sendmail") // Catch failures and try with plaintext def mail_cmd = ['mail', '-s', subject, '--content-type=text/html', email_address] mail_cmd.execute() << email_html diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test index 1dc317f..f117040 100644 --- a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test +++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test @@ -41,26 +41,14 @@ nextflow_function { } } - test("Test Function workflowCitation") { - - function "workflowCitation" - - then { - assertAll( - { assert function.success }, - { assert snapshot(function.result).match() } - ) - } - } - - test("Test Function nfCoreLogo") { + test("Test Function without logColours") { - function "nfCoreLogo" + function "logColours" when { function { """ - input[0] = false + input[0] = true """ } } @@ -73,9 +61,8 @@ nextflow_function { } } - test("Test Function dashedLine") { - - function "dashedLine" + test("Test Function with logColours") { + function "logColours" when { function { @@ -93,14 +80,13 @@ nextflow_function { } } - test("Test Function without logColours") { - - function "logColours" + test("Test Function getSingleReport with a single file") { + function "getSingleReport" when { function { """ - input[0] = true + input[0] = file(params.modules_testdata_base_path + '/generic/tsv/test.tsv', checkIfExists: true) """ } } @@ -108,18 +94,22 @@ nextflow_function { then { assertAll( { assert function.success }, - { assert snapshot(function.result).match() } + { assert function.result.contains("test.tsv") } ) } } - test("Test Function with logColours") { - function "logColours" + test("Test Function getSingleReport with multiple files") { + function "getSingleReport" when { function { """ - input[0] = false + input[0] = [ + file(params.modules_testdata_base_path + '/generic/tsv/test.tsv', checkIfExists: true), + file(params.modules_testdata_base_path + '/generic/tsv/network.tsv', checkIfExists: true), + file(params.modules_testdata_base_path + '/generic/tsv/expression.tsv', checkIfExists: true) + ] """ } } @@ -127,7 +117,9 @@ nextflow_function { then { assertAll( { assert function.success }, - { assert snapshot(function.result).match() } + { assert function.result.contains("test.tsv") }, + { assert !function.result.contains("network.tsv") }, + { assert !function.result.contains("expression.tsv") } ) } } diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test.snap b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test.snap index 1037232..02c6701 100644 --- a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test.snap +++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test.snap @@ -17,26 +17,6 @@ }, "timestamp": "2024-02-28T12:02:59.729647" }, - "Test Function nfCoreLogo": { - "content": [ - "\n\n-\u001b[2m----------------------------------------------------\u001b[0m-\n \u001b[0;32m,--.\u001b[0;30m/\u001b[0;32m,-.\u001b[0m\n\u001b[0;34m ___ __ __ __ ___ \u001b[0;32m/,-._.--~'\u001b[0m\n\u001b[0;34m |\\ | |__ __ / ` / \\ |__) |__ \u001b[0;33m} {\u001b[0m\n\u001b[0;34m | \\| | \\__, \\__/ | \\ |___ \u001b[0;32m\\`-._,-`-,\u001b[0m\n \u001b[0;32m`._,._,'\u001b[0m\n\u001b[0;35m nextflow_workflow v9.9.9\u001b[0m\n-\u001b[2m----------------------------------------------------\u001b[0m-\n" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-02-28T12:03:10.562934" - }, - "Test Function workflowCitation": { - "content": [ - "If you use nextflow_workflow for your analysis please cite:\n\n* The pipeline\n https://doi.org/10.5281/zenodo.5070524\n\n* The nf-core framework\n https://doi.org/10.1038/s41587-020-0439-x\n\n* Software dependencies\n /~https://github.com/nextflow_workflow/blob/master/CITATIONS.md" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-02-28T12:03:07.019761" - }, "Test Function without logColours": { "content": [ { @@ -95,16 +75,6 @@ }, "timestamp": "2024-02-28T12:03:17.969323" }, - "Test Function dashedLine": { - "content": [ - "-\u001b[2m----------------------------------------------------\u001b[0m-" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-02-28T12:03:14.366181" - }, "Test Function with logColours": { "content": [ { diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test b/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test index 842dc43..8fb3016 100644 --- a/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test @@ -42,7 +42,7 @@ nextflow_workflow { params { test_data = '' - outdir = 1 + outdir = null } workflow { @@ -94,7 +94,7 @@ nextflow_workflow { params { test_data = '' - outdir = 1 + outdir = null } workflow { diff --git a/workflows/pairgenomealign.nf b/workflows/pairgenomealign.nf index 2d973be..89dab58 100644 --- a/workflows/pairgenomealign.nf +++ b/workflows/pairgenomealign.nf @@ -39,7 +39,7 @@ workflow PAIRGENOMEALIGN { softwareVersionsToYAML(ch_versions) .collectFile( storeDir: "${params.outdir}/pipeline_info", - name: 'nf_core_' + 'pipeline_software_' + 'mqc_' + 'versions.yml', + name: 'nf_core_' + 'pairgenomealign_software_' + 'mqc_' + 'versions.yml', sort: true, newLine: true ).set { ch_collated_versions } From 09d35387c4a7b5b1a7fa7a7fa37c20243eb7c1f2 Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Fri, 13 Dec 2024 15:52:05 +0900 Subject: [PATCH 08/22] Fix Trailing whitespace pre-commit error --- .../local/utils_nfcore_pairgenomealign_pipeline/main.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf b/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf index 50b5886..003f9fa 100644 --- a/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_pairgenomealign_pipeline/main.nf @@ -101,7 +101,7 @@ workflow PIPELINE_COMPLETION { main: summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") def multiqc_reports = multiqc_report.toList() - + // // Completion email and summary // From 9f21a90e208e3d88e862f8fdf5c080fd67b5c352 Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Mon, 16 Dec 2024 09:28:55 +0900 Subject: [PATCH 09/22] Revert removal includeConfig 'conf/modules.config' as per Slack message > :nf-core: Friday, December 13th 11:01 PM > :alert: @channel the last tools release removed the includeConfig 'conf/modules.config' from the nextflow.config file. A patch release is on the way, meanwhile don't accept this change and don't remove this line! > thanks and sorry for the inconvenience :pray::skin-tone-2: --- nextflow.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nextflow.config b/nextflow.config index f8051ce..f25b04d 100644 --- a/nextflow.config +++ b/nextflow.config @@ -303,3 +303,6 @@ validation { afterText = validation.help.afterText } } + +// Load modules.config for DSL2 module specific options +includeConfig 'conf/modules.config' From 0303baa7c0be279ac4c08239a729642066b792ad Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Tue, 17 Dec 2024 08:56:46 +0900 Subject: [PATCH 10/22] Replace Zenodo placeholder by real value. --- README.md | 2 +- ro-crate-metadata.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5775609..1a3004e 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
    [![GitHub Actions CI Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/ci.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/ci.yml) -[![GitHub Actions Linting Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/pairgenomealign/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX) +[![GitHub Actions Linting Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/pairgenomealign/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.13910535-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.13910535) [![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com) [![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A524.04.2-23aa62.svg)](https://www.nextflow.io/) diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index b647fec..db37889 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -23,7 +23,7 @@ "@type": "Dataset", "creativeWorkStatus": "Stable", "datePublished": "2024-12-12T11:25:19+00:00", - "description": "

    \n \n \n \"nf-core/pairgenomealign\"\n \n

    \n\n[![GitHub Actions CI Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/ci.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/ci.yml)\n[![GitHub Actions Linting Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/pairgenomealign/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.XXXXXXX-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.XXXXXXX)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A524.04.2-23aa62.svg)](https://www.nextflow.io/)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=/~https://github.com/nf-core/pairgenomealign)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23pairgenomealign-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/pairgenomealign)[![Follow on Twitter](http://img.shields.io/badge/twitter-%40nf__core-1DA1F2?labelColor=000000&logo=twitter)](https://twitter.com/nf_core)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@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)\n\n## Introduction\n\n**nf-core/pairgenomealign** is a bioinformatics pipeline that ...\n\n\n\n\n\n\n1. Read QC ([`FastQC`](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/))\n2. Present QC for raw reads ([`MultiQC`](http://multiqc.info/))\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\n\n\nNow, you can run the pipeline using:\n\n\n\n```bash\nnextflow run nf-core/pairgenomealign \\\n -profile \\\n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/pairgenomealign/usage) and the [parameter documentation](https://nf-co.re/pairgenomealign/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/pairgenomealign/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/pairgenomealign/output).\n\n## Credits\n\nnf-core/pairgenomealign was originally written by charles-plessy.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#pairgenomealign` channel](https://nfcore.slack.com/channels/pairgenomealign) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "description": "

    \n \n \n \"nf-core/pairgenomealign\"\n \n

    \n\n[![GitHub Actions CI Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/ci.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/ci.yml)\n[![GitHub Actions Linting Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/pairgenomealign/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.13910535-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.13910535)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A524.04.2-23aa62.svg)](https://www.nextflow.io/)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=/~https://github.com/nf-core/pairgenomealign)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23pairgenomealign-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/pairgenomealign)[![Follow on Twitter](http://img.shields.io/badge/twitter-%40nf__core-1DA1F2?labelColor=000000&logo=twitter)](https://twitter.com/nf_core)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@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)\n\n## Introduction\n\n**nf-core/pairgenomealign** is a bioinformatics pipeline that ...\n\n\n\n\n\n\n1. Read QC ([`FastQC`](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/))\n2. Present QC for raw reads ([`MultiQC`](http://multiqc.info/))\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\n\n\nNow, you can run the pipeline using:\n\n\n\n```bash\nnextflow run nf-core/pairgenomealign \\\n -profile \\\n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/pairgenomealign/usage) and the [parameter documentation](https://nf-co.re/pairgenomealign/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/pairgenomealign/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/pairgenomealign/output).\n\n## Credits\n\nnf-core/pairgenomealign was originally written by charles-plessy.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#pairgenomealign` channel](https://nfcore.slack.com/channels/pairgenomealign) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { "@id": "main.nf" From 34636a2b50cad07083badd7bc99ce0fabef94481 Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Tue, 17 Dec 2024 09:24:10 +0900 Subject: [PATCH 11/22] Refresh --- ro-crate-metadata.json | 56 ++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index db37889..abbf886 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -22,8 +22,8 @@ "@id": "./", "@type": "Dataset", "creativeWorkStatus": "Stable", - "datePublished": "2024-12-12T11:25:19+00:00", - "description": "

    \n \n \n \"nf-core/pairgenomealign\"\n \n

    \n\n[![GitHub Actions CI Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/ci.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/ci.yml)\n[![GitHub Actions Linting Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/pairgenomealign/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.13910535-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.13910535)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A524.04.2-23aa62.svg)](https://www.nextflow.io/)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=/~https://github.com/nf-core/pairgenomealign)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23pairgenomealign-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/pairgenomealign)[![Follow on Twitter](http://img.shields.io/badge/twitter-%40nf__core-1DA1F2?labelColor=000000&logo=twitter)](https://twitter.com/nf_core)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@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)\n\n## Introduction\n\n**nf-core/pairgenomealign** is a bioinformatics pipeline that ...\n\n\n\n\n\n\n1. Read QC ([`FastQC`](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/))\n2. Present QC for raw reads ([`MultiQC`](http://multiqc.info/))\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\n\n\nNow, you can run the pipeline using:\n\n\n\n```bash\nnextflow run nf-core/pairgenomealign \\\n -profile \\\n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/pairgenomealign/usage) and the [parameter documentation](https://nf-co.re/pairgenomealign/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/pairgenomealign/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/pairgenomealign/output).\n\n## Credits\n\nnf-core/pairgenomealign was originally written by charles-plessy.\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#pairgenomealign` channel](https://nfcore.slack.com/channels/pairgenomealign) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\n\n\n\n\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "datePublished": "2024-12-17T00:15:40+00:00", + "description": "

    \n \n \n \"nf-core/pairgenomealign\"\n \n

    \n\n[![GitHub Actions CI Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/ci.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/ci.yml)\n[![GitHub Actions Linting Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/pairgenomealign/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.13910535-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.13910535)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A524.04.2-23aa62.svg)](https://www.nextflow.io/)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=/~https://github.com/nf-core/pairgenomealign)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23pairgenomealign-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/pairgenomealign)[![Follow on Twitter](http://img.shields.io/badge/twitter-%40nf__core-1DA1F2?labelColor=000000&logo=twitter)](https://twitter.com/nf_core)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@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)\n\n## Introduction\n\n**nf-core/pairgenomealign** is a bioinformatics pipeline that aligns one or more _query_ genomes to a _target_ genome, and plots pairwise representations.\n\n![Tubemap workflow summary](docs/images/pairgenomealign-tubemap.png \"Tubemap workflow summary\")\n\nThe pipeline can generate four kinds of outputs, called _many-to-many_, _many-to-one_, _one-to-many_ and _one-to-one_, depending on whether sequences of one genome are allowed match the other genome multiple times or not.\n\nThese alignments are output in [MAF](https://genome.ucsc.edu/FAQ/FAQformat.html#format5) format, and optional line plot representations are output in PNG format.\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet with your input data that looks as follows:\n\n`samplesheet.csv`:\n\n```csv\nsample,fasta\nquery_1,path-to-query-genome-file-one.fasta\nquery_2,path-to-query-genome-file-two.fasta\n```\n\nEach row represents a fasta file, this can also contain multiple rows to accomodate multiple query genomes in fasta format.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/pairgenomealign \\\n -profile \\\n --target sequencefile.fa \\\n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/pairgenomealign/usage) and the [parameter documentation](https://nf-co.re/pairgenomealign/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/pairgenomealign/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/pairgenomealign/output).\n\n## Credits\n\n`nf-core/pairgenomealign` was originally written by [charles-plessy](/~https://github.com/charles-plessy); the original versions are available at .\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n- [Mahdi Mohammed](/~https://github.com/U13bs1125) ported the original pipeline to _nf-core_ template 2.14.x.\n- [Martin Frith](/~https://github.com/mcfrith/), the author of LAST, gave us extensive feedback and advices.\n- [Michael Mansfield](/~https://github.com/mjmansfi) tested the pipeline and provided critical comments.\n- [Aleksandra Bliznina](/~https://github.com/aleksandrabliznina) contributed to the creation of the initial `last/*` modules.\n- [Jiashun Miao](/~https://github.com/miaojiashun) and [Huyen Pham](/~https://github.com/ngochuyenpham) tested the pipeline on vertebrate genomes.\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#pairgenomealign` channel](https://nfcore.slack.com/channels/pairgenomealign) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\nIf you use this pipeline, please cite:\n\n> **Extreme genome scrambling in marine planktonic Oikopleura dioica cryptic species.**\n> Charles Plessy, Michael J. Mansfield, Aleksandra Bliznina, Aki Masunaga, Charlotte West, Yongkai Tan, Andrew W. Liu, Jan Gra\u0161i\u010d, Mar\u00eda Sara del R\u00edo Pisula, Gaspar S\u00e1nchez-Serna, Marc Fabrega-Torrus, Alfonso Ferr\u00e1ndez-Rold\u00e1n, Vittoria Roncalli, Pavla Navratilova, Eric M. Thompson, Takeshi Onuma, Hiroki Nishida, Cristian Ca\u00f1estro, Nicholas M. Luscombe.\n> _Genome Res._ 2024. 34: 426-440; doi: [10.1101/2023.05.09.539028](https://doi.org/10.1101/gr.278295.123). PubMed ID: [38621828](https://pubmed.ncbi.nlm.nih.gov/38621828/)\n\n[OIST research news article](https://www.oist.jp/news-center/news/2024/4/25/oikopleura-who-species-identity-crisis-genome-community)\n\nAnd also please cite the [LAST papers](https://gitlab.com/mcfrith/last/-/blob/main/doc/last-papers.rst).\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { "@id": "main.nf" @@ -43,6 +43,9 @@ { "@id": "modules/" }, + { + "@id": "modules/local/" + }, { "@id": "modules/nf-core/" }, @@ -99,7 +102,7 @@ }, "mentions": [ { - "@id": "#a8e256ba-7fb9-4ec0-8d4e-3cc173a8852b" + "@id": "#17232a93-0952-4d69-be0d-484beb66fe9b" } ], "name": "nf-core/pairgenomealign" @@ -121,14 +124,21 @@ }, { "@id": "main.nf", - "@type": ["File", "SoftwareSourceCode", "ComputationalWorkflow"], + "@type": [ + "File", + "SoftwareSourceCode", + "ComputationalWorkflow" + ], "creator": [ + { + "@id": "#mohammed.mahdi@oist.jp" + }, { "@id": "https://orcid.org/0000-0001-7410-6295" } ], "dateCreated": "", - "dateModified": "2024-12-12T11:25:19Z", + "dateModified": "2024-12-17T09:15:40Z", "dct:conformsTo": "https://bioschemas.org/profiles/ComputationalWorkflow/1.0-RELEASE/", "keywords": [ "nf-core", @@ -141,16 +151,25 @@ "synteny", "whole-genome-alignment" ], - "license": ["MIT"], - "name": ["nf-core/pairgenomealign"], + "license": [ + "MIT" + ], + "name": [ + "nf-core/pairgenomealign" + ], "programmingLanguage": { "@id": "https://w3id.org/workflowhub/workflow-ro-crate#nextflow" }, "sdPublisher": { "@id": "https://nf-co.re/" }, - "url": ["/~https://github.com/nf-core/pairgenomealign", "https://nf-co.re/pairgenomealign/1.1.0/"], - "version": ["1.1.0"] + "url": [ + "/~https://github.com/nf-core/pairgenomealign", + "https://nf-co.re/pairgenomealign/1.1.0/" + ], + "version": [ + "1.1.0" + ] }, { "@id": "https://w3id.org/workflowhub/workflow-ro-crate#nextflow", @@ -165,11 +184,11 @@ "version": "!>=24.04.2" }, { - "@id": "#a8e256ba-7fb9-4ec0-8d4e-3cc173a8852b", + "@id": "#17232a93-0952-4d69-be0d-484beb66fe9b", "@type": "TestSuite", "instance": [ { - "@id": "#95085646-ac04-49b3-9807-1c8cd0001334" + "@id": "#361c6f7e-5625-4c07-a1b6-d19a9ca5ecd8" } ], "mainEntity": { @@ -178,7 +197,7 @@ "name": "Test suite for nf-core/pairgenomealign" }, { - "@id": "#95085646-ac04-49b3-9807-1c8cd0001334", + "@id": "#361c6f7e-5625-4c07-a1b6-d19a9ca5ecd8", "@type": "TestInstance", "name": "GitHub Actions workflow for testing nf-core/pairgenomealign", "resource": "repos/nf-core/pairgenomealign/actions/workflows/ci.yml", @@ -220,6 +239,11 @@ "@type": "Dataset", "description": "Modules used by the pipeline" }, + { + "@id": "modules/local/", + "@type": "Dataset", + "description": "Pipeline-specific modules" + }, { "@id": "modules/nf-core/", "@type": "Dataset", @@ -306,6 +330,12 @@ "name": "nf-core", "url": "https://nf-co.re/" }, + { + "@id": "#mohammed.mahdi@oist.jp", + "@type": "Person", + "email": "mohammed.mahdi@oist.jp", + "name": "Mohammed Mahdi" + }, { "@id": "https://orcid.org/0000-0001-7410-6295", "@type": "Person", @@ -313,4 +343,4 @@ "name": "Charles Plessy" } ] -} +} \ No newline at end of file From 6e4ccbd02f1afb70f00400c8c4c810f6c1d2f3d2 Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Tue, 17 Dec 2024 09:55:55 +0900 Subject: [PATCH 12/22] Use Nextflow 24.10.0 contributors declaration. --- nextflow.config | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/nextflow.config b/nextflow.config index f25b04d..421afec 100644 --- a/nextflow.config +++ b/nextflow.config @@ -246,15 +246,19 @@ dag { manifest { name = 'nf-core/pairgenomealign' - author = """charles-plessy""" // The author field is deprecated from Nextflow version 24.10.0, use contributors instead contributors = [ - // TODO nf-core: Update the field with the details of the contributors to your pipeline. New with Nextflow version 24.10.0 [ - name: 'charles-plessy', - affiliation: '', - email: '', - github: '', - contribution: [], // List of contribution types ('author', 'maintainer' or 'contributor') + affiliation: 'Okinawa Institute of Science and Technology Graduate University (OIST)', + email: 'charles.plessy@oist.jp', + github: 'charles-plessy', + contribution: ['author'], // List of contribution types ('author', 'maintainer' or 'contributor') + orcid: '0000-0001-7410-6295' + ], + [ + affiliation: 'Okinawa Institute of Science and Technology Graduate University (OIST)', + email: 'mohammed.mahdi@oist.jp', + github: 'U13bs1125', + contribution: ['contributor'], orcid: '' ], ] @@ -262,7 +266,7 @@ manifest { description = """Pairwise alignment pipeline (genome to genome or reads to genome)""" mainScript = 'main.nf' defaultBranch = 'master' - nextflowVersion = '!>=24.04.2' + nextflowVersion = '!>=24.10.0' version = '1.1.0' doi = '' } From ee1ab26eb8a8fcdd4622c1e6c7b2dcbfa8fa87a4 Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Tue, 17 Dec 2024 10:04:40 +0900 Subject: [PATCH 13/22] nf-core bump 1.1.1 I did not commit the removal of the contributor information in ro-crate-metadata.json, which was probably caused by a bug in nf-core rocrate that does not recognise the 24.10.0 format of contributor attribution. --- .nf-core.yml | 8 ++++---- assets/multiqc_config.yml | 13 +++++++++---- nextflow.config | 2 +- ro-crate-metadata.json | 26 +++++++++----------------- 4 files changed, 23 insertions(+), 26 deletions(-) diff --git a/.nf-core.yml b/.nf-core.yml index c871964..07d3261 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -1,8 +1,8 @@ lint: files_unchanged: - - assets/nf-core-pairgenomealign_logo_light.png - - docs/images/nf-core-pairgenomealign_logo_light.png - - docs/images/nf-core-pairgenomealign_logo_dark.png + - assets/nf-core-pairgenomealign_logo_light.png + - docs/images/nf-core-pairgenomealign_logo_light.png + - docs/images/nf-core-pairgenomealign_logo_dark.png nf_core_version: 3.1.0 repository_type: pipeline template: @@ -13,4 +13,4 @@ template: name: pairgenomealign org: nf-core outdir: . - version: 1.1.0 + version: 1.1.1 diff --git a/assets/multiqc_config.yml b/assets/multiqc_config.yml index 1ed94d1..f5c03f5 100644 --- a/assets/multiqc_config.yml +++ b/assets/multiqc_config.yml @@ -1,7 +1,8 @@ report_comment: > - This report has been generated by the nf-core/pairgenomealign - analysis pipeline. For information about how to interpret these results, please see the - documentation. + This report has been generated by the nf-core/pairgenomealign analysis pipeline. For information about + how to interpret these results, please see the documentation. report_section_order: "nf-core-pairgenomealign-methods-description": order: -1000 @@ -27,7 +28,11 @@ custom_data: title: "Substitution Percent Identity" "last -t": title: "Temperature" - description: "Parameter for converting between scores and probability ratios. This affects the column ambiguity estimates. A score is converted to a probability ratio by this formula: exp(score / TEMPERATURE). The default value is 1/lambda, where lambda is the scale factor of the scoring matrix, which is calculated by the method of Yu and Altschul (YK Yu et al. 2003, PNAS 100(26):15688-93)." + description: "Parameter for converting between scores and probability ratios. + This affects the column ambiguity estimates. A score is converted to a probability + ratio by this formula: exp(score / TEMPERATURE). The default value is 1/lambda, + where lambda is the scale factor of the scoring matrix, which is calculated + by the method of Yu and Altschul (YK Yu et al. 2003, PNAS 100(26):15688-93)." "last -a": title: "Gap existence" description: "Gap existence cost (lastal -a)" diff --git a/nextflow.config b/nextflow.config index 421afec..1ae0aae 100644 --- a/nextflow.config +++ b/nextflow.config @@ -267,7 +267,7 @@ manifest { mainScript = 'main.nf' defaultBranch = 'master' nextflowVersion = '!>=24.10.0' - version = '1.1.0' + version = '1.1.1' doi = '' } diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index abbf886..e90c33a 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -22,7 +22,7 @@ "@id": "./", "@type": "Dataset", "creativeWorkStatus": "Stable", - "datePublished": "2024-12-17T00:15:40+00:00", + "datePublished": "2024-12-17T01:02:25+00:00", "description": "

    \n \n \n \"nf-core/pairgenomealign\"\n \n

    \n\n[![GitHub Actions CI Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/ci.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/ci.yml)\n[![GitHub Actions Linting Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/pairgenomealign/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.13910535-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.13910535)\n[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com)\n\n[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A524.04.2-23aa62.svg)](https://www.nextflow.io/)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=/~https://github.com/nf-core/pairgenomealign)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23pairgenomealign-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/pairgenomealign)[![Follow on Twitter](http://img.shields.io/badge/twitter-%40nf__core-1DA1F2?labelColor=000000&logo=twitter)](https://twitter.com/nf_core)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@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)\n\n## Introduction\n\n**nf-core/pairgenomealign** is a bioinformatics pipeline that aligns one or more _query_ genomes to a _target_ genome, and plots pairwise representations.\n\n![Tubemap workflow summary](docs/images/pairgenomealign-tubemap.png \"Tubemap workflow summary\")\n\nThe pipeline can generate four kinds of outputs, called _many-to-many_, _many-to-one_, _one-to-many_ and _one-to-one_, depending on whether sequences of one genome are allowed match the other genome multiple times or not.\n\nThese alignments are output in [MAF](https://genome.ucsc.edu/FAQ/FAQformat.html#format5) format, and optional line plot representations are output in PNG format.\n\n## Usage\n\n> [!NOTE]\n> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data.\n\nFirst, prepare a samplesheet with your input data that looks as follows:\n\n`samplesheet.csv`:\n\n```csv\nsample,fasta\nquery_1,path-to-query-genome-file-one.fasta\nquery_2,path-to-query-genome-file-two.fasta\n```\n\nEach row represents a fasta file, this can also contain multiple rows to accomodate multiple query genomes in fasta format.\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/pairgenomealign \\\n -profile \\\n --target sequencefile.fa \\\n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/pairgenomealign/usage) and the [parameter documentation](https://nf-co.re/pairgenomealign/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/pairgenomealign/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/pairgenomealign/output).\n\n## Credits\n\n`nf-core/pairgenomealign` was originally written by [charles-plessy](/~https://github.com/charles-plessy); the original versions are available at .\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n- [Mahdi Mohammed](/~https://github.com/U13bs1125) ported the original pipeline to _nf-core_ template 2.14.x.\n- [Martin Frith](/~https://github.com/mcfrith/), the author of LAST, gave us extensive feedback and advices.\n- [Michael Mansfield](/~https://github.com/mjmansfi) tested the pipeline and provided critical comments.\n- [Aleksandra Bliznina](/~https://github.com/aleksandrabliznina) contributed to the creation of the initial `last/*` modules.\n- [Jiashun Miao](/~https://github.com/miaojiashun) and [Huyen Pham](/~https://github.com/ngochuyenpham) tested the pipeline on vertebrate genomes.\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#pairgenomealign` channel](https://nfcore.slack.com/channels/pairgenomealign) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\nIf you use this pipeline, please cite:\n\n> **Extreme genome scrambling in marine planktonic Oikopleura dioica cryptic species.**\n> Charles Plessy, Michael J. Mansfield, Aleksandra Bliznina, Aki Masunaga, Charlotte West, Yongkai Tan, Andrew W. Liu, Jan Gra\u0161i\u010d, Mar\u00eda Sara del R\u00edo Pisula, Gaspar S\u00e1nchez-Serna, Marc Fabrega-Torrus, Alfonso Ferr\u00e1ndez-Rold\u00e1n, Vittoria Roncalli, Pavla Navratilova, Eric M. Thompson, Takeshi Onuma, Hiroki Nishida, Cristian Ca\u00f1estro, Nicholas M. Luscombe.\n> _Genome Res._ 2024. 34: 426-440; doi: [10.1101/2023.05.09.539028](https://doi.org/10.1101/gr.278295.123). PubMed ID: [38621828](https://pubmed.ncbi.nlm.nih.gov/38621828/)\n\n[OIST research news article](https://www.oist.jp/news-center/news/2024/4/25/oikopleura-who-species-identity-crisis-genome-community)\n\nAnd also please cite the [LAST papers](https://gitlab.com/mcfrith/last/-/blob/main/doc/last-papers.rst).\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", "hasPart": [ { @@ -102,7 +102,7 @@ }, "mentions": [ { - "@id": "#17232a93-0952-4d69-be0d-484beb66fe9b" + "@id": "#58040922-b549-4775-9385-548d092d8ec1" } ], "name": "nf-core/pairgenomealign" @@ -129,16 +129,8 @@ "SoftwareSourceCode", "ComputationalWorkflow" ], - "creator": [ - { - "@id": "#mohammed.mahdi@oist.jp" - }, - { - "@id": "https://orcid.org/0000-0001-7410-6295" - } - ], "dateCreated": "", - "dateModified": "2024-12-17T09:15:40Z", + "dateModified": "2024-12-17T10:02:25Z", "dct:conformsTo": "https://bioschemas.org/profiles/ComputationalWorkflow/1.0-RELEASE/", "keywords": [ "nf-core", @@ -165,10 +157,10 @@ }, "url": [ "/~https://github.com/nf-core/pairgenomealign", - "https://nf-co.re/pairgenomealign/1.1.0/" + "https://nf-co.re/pairgenomealign/1.1.1/" ], "version": [ - "1.1.0" + "1.1.1" ] }, { @@ -181,14 +173,14 @@ "url": { "@id": "https://www.nextflow.io/" }, - "version": "!>=24.04.2" + "version": "!>=24.10.0" }, { - "@id": "#17232a93-0952-4d69-be0d-484beb66fe9b", + "@id": "#58040922-b549-4775-9385-548d092d8ec1", "@type": "TestSuite", "instance": [ { - "@id": "#361c6f7e-5625-4c07-a1b6-d19a9ca5ecd8" + "@id": "#63c8d934-2bef-473e-8655-36b8377947a1" } ], "mainEntity": { @@ -197,7 +189,7 @@ "name": "Test suite for nf-core/pairgenomealign" }, { - "@id": "#361c6f7e-5625-4c07-a1b6-d19a9ca5ecd8", + "@id": "#63c8d934-2bef-473e-8655-36b8377947a1", "@type": "TestInstance", "name": "GitHub Actions workflow for testing nf-core/pairgenomealign", "resource": "repos/nf-core/pairgenomealign/actions/workflows/ci.yml", From a19c336f86b76fdd5bef30a2707a6e336a716781 Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Tue, 17 Dec 2024 10:12:01 +0900 Subject: [PATCH 14/22] v1.1.1 "Kani nabe" - [December 17th, 2024] --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec6ae79..40b77b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ 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). +## v1.1.1 "Kani nabe" - [December 17th, 2024] + +This release brings the pipeline to the standards of Nextflow 24.10.0 and +nf-core 3.1.0. No changes were made to the alignment process. + ## v1.1.0 "Nattou maki" - [September 27th, 2024] Added a new `softmask` parameter, to optionally keep original softmasking. From c60ed346dd3361ac48851d0db848433ed39b9f6a Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Tue, 17 Dec 2024 10:26:57 +0900 Subject: [PATCH 15/22] Finish the transition to Nextflow 24.10.0 --- .github/workflows/ci.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8da0a02..db1ea3c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: strategy: matrix: NXF_VER: - - "24.04.2" + - "24.10.0" - "latest-everything" profile: - "conda" diff --git a/README.md b/README.md index 1a3004e..f815798 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![GitHub Actions Linting Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/pairgenomealign/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.13910535-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.13910535) [![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com) -[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A524.04.2-23aa62.svg)](https://www.nextflow.io/) +[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A524.10.0-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/) From fa631390ff7904f46b8d19f1a596b8d6c1089818 Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Tue, 17 Dec 2024 10:39:24 +0900 Subject: [PATCH 16/22] pre-commit run --all-files --- .nf-core.yml | 6 +++--- CHANGELOG.md | 2 +- ro-crate-metadata.json | 25 ++++++------------------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/.nf-core.yml b/.nf-core.yml index 07d3261..aec29ce 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -1,8 +1,8 @@ lint: files_unchanged: - - assets/nf-core-pairgenomealign_logo_light.png - - docs/images/nf-core-pairgenomealign_logo_light.png - - docs/images/nf-core-pairgenomealign_logo_dark.png + - assets/nf-core-pairgenomealign_logo_light.png + - docs/images/nf-core-pairgenomealign_logo_light.png + - docs/images/nf-core-pairgenomealign_logo_dark.png nf_core_version: 3.1.0 repository_type: pipeline template: diff --git a/CHANGELOG.md b/CHANGELOG.md index 40b77b5..5a1697e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## v1.1.1 "Kani nabe" - [December 17th, 2024] This release brings the pipeline to the standards of Nextflow 24.10.0 and -nf-core 3.1.0. No changes were made to the alignment process. +nf-core 3.1.0. No changes were made to the alignment process. ## v1.1.0 "Nattou maki" - [September 27th, 2024] diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index e90c33a..80742a6 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -124,11 +124,7 @@ }, { "@id": "main.nf", - "@type": [ - "File", - "SoftwareSourceCode", - "ComputationalWorkflow" - ], + "@type": ["File", "SoftwareSourceCode", "ComputationalWorkflow"], "dateCreated": "", "dateModified": "2024-12-17T10:02:25Z", "dct:conformsTo": "https://bioschemas.org/profiles/ComputationalWorkflow/1.0-RELEASE/", @@ -143,25 +139,16 @@ "synteny", "whole-genome-alignment" ], - "license": [ - "MIT" - ], - "name": [ - "nf-core/pairgenomealign" - ], + "license": ["MIT"], + "name": ["nf-core/pairgenomealign"], "programmingLanguage": { "@id": "https://w3id.org/workflowhub/workflow-ro-crate#nextflow" }, "sdPublisher": { "@id": "https://nf-co.re/" }, - "url": [ - "/~https://github.com/nf-core/pairgenomealign", - "https://nf-co.re/pairgenomealign/1.1.1/" - ], - "version": [ - "1.1.1" - ] + "url": ["/~https://github.com/nf-core/pairgenomealign", "https://nf-co.re/pairgenomealign/1.1.1/"], + "version": ["1.1.1"] }, { "@id": "https://w3id.org/workflowhub/workflow-ro-crate#nextflow", @@ -335,4 +322,4 @@ "name": "Charles Plessy" } ] -} \ No newline at end of file +} From 416f9744e19dcfcfff89415bec72760f6104f88f Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Tue, 17 Dec 2024 11:03:58 +0900 Subject: [PATCH 17/22] Require Nextflow 24.10.1 to support conda tests. --- .github/workflows/ci.yml | 2 +- CHANGELOG.md | 2 +- README.md | 2 +- nextflow.config | 2 +- ro-crate-metadata.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db1ea3c..20c872f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: strategy: matrix: NXF_VER: - - "24.10.0" + - "24.10.1" - "latest-everything" profile: - "conda" diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a1697e..ecb175b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## v1.1.1 "Kani nabe" - [December 17th, 2024] -This release brings the pipeline to the standards of Nextflow 24.10.0 and +This release brings the pipeline to the standards of Nextflow 24.10.1 and nf-core 3.1.0. No changes were made to the alignment process. ## v1.1.0 "Nattou maki" - [September 27th, 2024] diff --git a/README.md b/README.md index f815798..f1e9314 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![GitHub Actions Linting Status](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml/badge.svg)](/~https://github.com/nf-core/pairgenomealign/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/pairgenomealign/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.13910535-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.13910535) [![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com) -[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A524.10.0-23aa62.svg)](https://www.nextflow.io/) +[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A524.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/) diff --git a/nextflow.config b/nextflow.config index 1ae0aae..1f7ee51 100644 --- a/nextflow.config +++ b/nextflow.config @@ -266,7 +266,7 @@ manifest { description = """Pairwise alignment pipeline (genome to genome or reads to genome)""" mainScript = 'main.nf' defaultBranch = 'master' - nextflowVersion = '!>=24.10.0' + nextflowVersion = '!>=24.10.1' version = '1.1.1' doi = '' } diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json index 80742a6..6146b39 100644 --- a/ro-crate-metadata.json +++ b/ro-crate-metadata.json @@ -160,7 +160,7 @@ "url": { "@id": "https://www.nextflow.io/" }, - "version": "!>=24.10.0" + "version": "!>=24.10.1" }, { "@id": "#58040922-b549-4775-9385-548d092d8ec1", From 3ab321ba8d69e5271fb600618963f2736e2e8be5 Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Tue, 17 Dec 2024 11:11:42 +0900 Subject: [PATCH 18/22] Link to release tag. --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecb175b..889a8da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,15 +3,15 @@ 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). -## v1.1.1 "Kani nabe" - [December 17th, 2024] +## [v1.1.1](/~https://github.com/nf-core/pairgenomealign/releases/tag/1.1.1) "Kani nabe" - [December 17th, 2024] This release brings the pipeline to the standards of Nextflow 24.10.1 and nf-core 3.1.0. No changes were made to the alignment process. -## v1.1.0 "Nattou maki" - [September 27th, 2024] +## [v1.1.0](/~https://github.com/nf-core/pairgenomealign/releases/tag/1.1.0) "Nattou maki" - [September 27th, 2024] Added a new `softmask` parameter, to optionally keep original softmasking. -## v1.0.0 "Sweet potato" - [August 27th, 2024] +## [v1.0.0](/~https://github.com/nf-core/pairgenomealign/releases/tag/1.0.0) "Sweet potato" - [August 27th, 2024] Initial release of nf-core/pairgenomealign, created with the [nf-core](https://nf-co.re/) template. From 8b51273a534e6d31831fa7891fa1df0be978d94c Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Tue, 17 Dec 2024 16:00:36 +0900 Subject: [PATCH 19/22] Add missing conda environment file. --- modules/local/multiqc_assemblyscan_plot_data.nf | 2 +- .../local/multiqc_assemblyscan_plot_data_environment.yml | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 modules/local/multiqc_assemblyscan_plot_data_environment.yml diff --git a/modules/local/multiqc_assemblyscan_plot_data.nf b/modules/local/multiqc_assemblyscan_plot_data.nf index a3fa099..8f97e25 100644 --- a/modules/local/multiqc_assemblyscan_plot_data.nf +++ b/modules/local/multiqc_assemblyscan_plot_data.nf @@ -1,6 +1,6 @@ process MULTIQC_ASSEMBLYSCAN_PLOT_DATA { label 'process_single' - conda "${moduleDir}/environment.yml" + conda "${moduleDir}/multiqc_assemblyscan_plot_data_environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/jq:1.6': 'biocontainers/jq:1.6' }" diff --git a/modules/local/multiqc_assemblyscan_plot_data_environment.yml b/modules/local/multiqc_assemblyscan_plot_data_environment.yml new file mode 100644 index 0000000..444acd3 --- /dev/null +++ b/modules/local/multiqc_assemblyscan_plot_data_environment.yml @@ -0,0 +1,6 @@ +channels: + - conda-forge + - bioconda + +dependencies: + - bioconda::jq=1.6 From c8dc0f377e946fd8690431ee446f21fdeef9f2b5 Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Wed, 18 Dec 2024 10:57:51 +0900 Subject: [PATCH 20/22] Downgrade jq to version 1.5. Only this version is simultaneously available for Conda, Docker and Singularity. The local module only uses `jq -r` which is a simple command with same output in 1.5 and 1.6. --- modules/local/multiqc_assemblyscan_plot_data.nf | 4 ++-- modules/local/multiqc_assemblyscan_plot_data_environment.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/local/multiqc_assemblyscan_plot_data.nf b/modules/local/multiqc_assemblyscan_plot_data.nf index 8f97e25..a4b8075 100644 --- a/modules/local/multiqc_assemblyscan_plot_data.nf +++ b/modules/local/multiqc_assemblyscan_plot_data.nf @@ -2,8 +2,8 @@ process MULTIQC_ASSEMBLYSCAN_PLOT_DATA { label 'process_single' conda "${moduleDir}/multiqc_assemblyscan_plot_data_environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/jq:1.6': - 'biocontainers/jq:1.6' }" + 'https://depot.galaxyproject.org/singularity/jq:1.5--4': + 'biocontainers/jq:1.5--4' }" // This module parses the JSON output of the assemblyscan module with jq to extract // statistics about GC content and contig length. I do not know how to contribute diff --git a/modules/local/multiqc_assemblyscan_plot_data_environment.yml b/modules/local/multiqc_assemblyscan_plot_data_environment.yml index 444acd3..82a706e 100644 --- a/modules/local/multiqc_assemblyscan_plot_data_environment.yml +++ b/modules/local/multiqc_assemblyscan_plot_data_environment.yml @@ -3,4 +3,4 @@ channels: - bioconda dependencies: - - bioconda::jq=1.6 + - bioconda::jq=1.5 From 20e5e0d5970cd90c508f04942119493b34221c26 Mon Sep 17 00:00:00 2001 From: Sateesh Date: Wed, 18 Dec 2024 02:50:52 +0000 Subject: [PATCH 21/22] use seqera container for jq local module --- .../environment.yml} | 0 .../main.nf} | 17 +++++++++-------- workflows/pairgenomealign.nf | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) rename modules/local/{multiqc_assemblyscan_plot_data_environment.yml => multiqc_assemblyscan_plot_data/environment.yml} (100%) rename modules/local/{multiqc_assemblyscan_plot_data.nf => multiqc_assemblyscan_plot_data/main.nf} (85%) diff --git a/modules/local/multiqc_assemblyscan_plot_data_environment.yml b/modules/local/multiqc_assemblyscan_plot_data/environment.yml similarity index 100% rename from modules/local/multiqc_assemblyscan_plot_data_environment.yml rename to modules/local/multiqc_assemblyscan_plot_data/environment.yml diff --git a/modules/local/multiqc_assemblyscan_plot_data.nf b/modules/local/multiqc_assemblyscan_plot_data/main.nf similarity index 85% rename from modules/local/multiqc_assemblyscan_plot_data.nf rename to modules/local/multiqc_assemblyscan_plot_data/main.nf index a4b8075..b2814b6 100644 --- a/modules/local/multiqc_assemblyscan_plot_data.nf +++ b/modules/local/multiqc_assemblyscan_plot_data/main.nf @@ -1,9 +1,11 @@ process MULTIQC_ASSEMBLYSCAN_PLOT_DATA { + tag "${json.baseName}" label 'process_single' - conda "${moduleDir}/multiqc_assemblyscan_plot_data_environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/jq:1.5--4': - 'biocontainers/jq:1.5--4' }" + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/84/84eef7b4cd5f6304aa5ba9ac6b0051850af300abefb615b72b776d1245990749/data' + : 'community.wave.seqera.io/library/jq:fee8aafd41d9e3aa' }" // This module parses the JSON output of the assemblyscan module with jq to extract // statistics about GC content and contig length. I do not know how to contribute @@ -13,13 +15,12 @@ process MULTIQC_ASSEMBLYSCAN_PLOT_DATA { path(json) output: - path "*_mqc.tsv", emit: tsv + path ("*_mqc.tsv"), emit: tsv when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' """ echo "# id: 'base_content_summary'" > gc_summary_mqc.tsv echo "# section_name: 'Base frequency'" >> gc_summary_mqc.tsv @@ -31,7 +32,7 @@ process MULTIQC_ASSEMBLYSCAN_PLOT_DATA { echo "# title: 'per_base content and percentage'" >> gc_summary_mqc.tsv echo "# ylab: ''" >> gc_summary_mqc.tsv echo "id\tpercent_A\tpercent_C\tpercent_G\tpercent_T\tpercent_N\tcontig_non_ACGTN" >> gc_summary_mqc.tsv - for i in $json + for i in ${json} do printf "\$(basename \$i .json)\t" >> gc_summary_mqc.tsv jq -r '[.contig_percent_a, .contig_percent_c, .contig_percent_g, .contig_percent_t, .contig_percent_n, .contig_non_acgtn] | @tsv' \$i >> gc_summary_mqc.tsv @@ -47,7 +48,7 @@ process MULTIQC_ASSEMBLYSCAN_PLOT_DATA { echo "# title: 'contigs length statistics'" >> contig_length_mqc.tsv echo "# ylab: 'length'" >> contig_length_mqc.tsv echo "id\tTOTALcontiglen\tMINcontiglen\tMAXcontiglen\ttotalcontigs\tcontigs>1k\tcontigs>10k" >> contig_length_mqc.tsv - for i in $json + for i in ${json} do printf "\$(basename \$i .json)\t" >> contig_length_mqc.tsv jq -r '[.total_contig_length, .min_contig_length, .max_contig_length, .total_contig, .contigs_greater_1k, .contigs_greater_10k] | @tsv' \$i >> contig_length_mqc.tsv diff --git a/workflows/pairgenomealign.nf b/workflows/pairgenomealign.nf index 4f1a5d5..361380a 100644 --- a/workflows/pairgenomealign.nf +++ b/workflows/pairgenomealign.nf @@ -5,7 +5,7 @@ */ include { ASSEMBLYSCAN } from '../modules/nf-core/assemblyscan/main' -include { MULTIQC_ASSEMBLYSCAN_PLOT_DATA } from '../modules/local/multiqc_assemblyscan_plot_data' +include { MULTIQC_ASSEMBLYSCAN_PLOT_DATA } from '../modules/local/multiqc_assemblyscan_plot_data/main' include { PAIRALIGN_M2M } from '../subworkflows/local/pairalign_m2m/main' include { SEQTK_CUTN as CUTN_TARGET } from '../modules/nf-core/seqtk/cutn/main' include { SEQTK_CUTN as CUTN_QUERY } from '../modules/nf-core/seqtk/cutn/main' From 22d94ba086e7df989625b30346928069df78203f Mon Sep 17 00:00:00 2001 From: Charles Plessy Date: Wed, 18 Dec 2024 14:17:14 +0900 Subject: [PATCH 22/22] Update conda environment --- modules/local/multiqc_assemblyscan_plot_data/environment.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/local/multiqc_assemblyscan_plot_data/environment.yml b/modules/local/multiqc_assemblyscan_plot_data/environment.yml index 82a706e..e8331cd 100644 --- a/modules/local/multiqc_assemblyscan_plot_data/environment.yml +++ b/modules/local/multiqc_assemblyscan_plot_data/environment.yml @@ -1,6 +1,5 @@ channels: - conda-forge - bioconda - dependencies: - - bioconda::jq=1.5 + - conda-forge::jq=1.7.1