diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 4ecfbfe3..97c8c97f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,28 +1,20 @@ { "name": "nfcore", - "image": "nfcore/gitpod:latest", - "remoteUser": "gitpod", - "runArgs": ["--privileged"], + "image": "nfcore/devcontainer:latest", - // Configure tool-specific properties. - "customizations": { - // Configure properties specific to VS Code. - "vscode": { - // Set *default* container specific settings.json values on container create. - "settings": { - "python.defaultInterpreterPath": "/opt/conda/bin/python", - "python.linting.enabled": true, - "python.linting.pylintEnabled": true, - "python.formatting.autopep8Path": "/opt/conda/bin/autopep8", - "python.formatting.yapfPath": "/opt/conda/bin/yapf", - "python.linting.flake8Path": "/opt/conda/bin/flake8", - "python.linting.pycodestylePath": "/opt/conda/bin/pycodestyle", - "python.linting.pydocstylePath": "/opt/conda/bin/pydocstyle", - "python.linting.pylintPath": "/opt/conda/bin/pylint" - }, + "remoteUser": "root", + "privileged": true, - // Add the IDs of extensions you want installed when the container is created. - "extensions": ["ms-python.python", "ms-python.vscode-pylance", "nf-core.nf-core-extensionpack"] - } + "remoteEnv": { + // Workspace path on the host for mounting with docker-outside-of-docker + "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" + }, + + "onCreateCommand": "./.devcontainer/setup.sh", + + "hostRequirements": { + "cpus": 4, + "memory": "16gb", + "storage": "32gb" } } diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh new file mode 100755 index 00000000..3ad5e2ac --- /dev/null +++ b/.devcontainer/setup.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# Customise the terminal command prompt +echo "export PROMPT_DIRTRIM=2" >> $HOME/.bashrc +echo "export PS1='\[\e[3;36m\]\w ->\[\e[0m\\] '" >> $HOME/.bashrc +export PROMPT_DIRTRIM=2 +export PS1='\[\e[3;36m\]\w ->\[\e[0m\\] ' + +# Update Nextflow +nextflow self-update + +# Update welcome message +echo "Welcome to the nf-cmgg/preprocessing devcontainer!" > /usr/local/etc/vscode-dev-containers/first-run-notice.txt diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 8ec14c5d..47f18382 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -71,7 +71,7 @@ If you wish to contribute a new step, please use the following coding standards: 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`. +8. If applicable, add a new test in the `tests` directory. 9. Update MultiQC config `assets/multiqc_config.yml` so relevant suffixes, file name clean up and module plots are in the appropriate order. If applicable, add a [MultiQC](https://https://multiqc.info/) module. 10. Add a description of the output files and if relevant any appropriate images from the MultiQC report to `docs/output.md`. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 78b6b627..d0f648f7 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -13,42 +13,29 @@ body: id: command_used attributes: label: Command used and terminal output - description: Steps to reproduce the behaviour. Please paste the command you used - to launch the pipeline and the output from your terminal. + description: Steps to reproduce the behaviour. Please paste the command you used to launch the pipeline and the output from your terminal. render: console - placeholder: "$ nextflow run ... - + placeholder: | + $ nextflow run ... Some output where something broke - " - type: textarea id: files attributes: label: Relevant files - description: "Please drag and drop the relevant files here. Create a `.zip` archive - if the extension is not allowed. - - Your verbose log file `.nextflow.log` is often useful _(this is a hidden file - in the directory where you launched the pipeline)_ as well as custom Nextflow - configuration files. + description: | + Please drag and drop the relevant files here. Create a `.zip` archive if the extension is not allowed. + Your verbose log file `.nextflow.log` is often useful _(this is a hidden file in the directory where you launched the pipeline)_ as well as custom Nextflow configuration files. - " - type: textarea id: system attributes: label: System information - description: "* Nextflow version _(eg. 23.04.0)_ - + description: | + * Nextflow version _(eg. 23.04.0)_ * Hardware _(eg. HPC, Desktop, Cloud)_ - * Executor _(eg. slurm, local, awsbatch)_ - - * Container engine: _(e.g. Docker, Singularity, Conda, Podman, Shifter, Charliecloud, - or Apptainer)_ - + * Container engine: _(e.g. Docker, Singularity, Podman, Shifter, Charliecloud, or Apptainer)_ * OS _(eg. CentOS Linux, macOS, Linux Mint)_ - * Version of nf-cmgg/preprocessing _(eg. 1.1, 1.5, 1.8.2)_ - - " diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 712d9a25..8e00290d 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -8,14 +8,14 @@ These are the most common things requested on pull requests (PRs). Remember that PRs should be made against the dev branch, unless you're preparing a pipeline release. -Learn more about contributing: [CONTRIBUTING.md](https://github.com/nf-cmgg/preprocessing/tree/master/.github/CONTRIBUTING.md) +Learn more about contributing: [CONTRIBUTING.md](https://github.com/nf-cmgg/preprocessing/tree/main/.github/CONTRIBUTING.md) --> ## PR checklist - [ ] This comment contains a description of changes (with reason). - [ ] If you've fixed a bug or added code that should be tested, add tests! -- [ ] If you've added a new tool - have you followed the pipeline conventions in the [contribution docs](https://github.com/nf-cmgg/preprocessing/tree/master/.github/CONTRIBUTING.md) +- [ ] If you've added a new tool - have you followed the pipeline conventions in the [contribution docs](https://github.com/nf-cmgg/preprocessing/tree/main/.github/CONTRIBUTING.md) - [ ] 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 `). diff --git a/.github/actions/get-shards/action.yml b/.github/actions/get-shards/action.yml new file mode 100644 index 00000000..34085279 --- /dev/null +++ b/.github/actions/get-shards/action.yml @@ -0,0 +1,69 @@ +name: "Get number of shards" +description: "Get the number of nf-test shards for the current CI job" +inputs: + max_shards: + description: "Maximum number of shards allowed" + required: true + paths: + description: "Component paths to test" + required: false + tags: + description: "Tags to pass as argument for nf-test --tag parameter" + required: false +outputs: + shard: + description: "Array of shard numbers" + value: ${{ steps.shards.outputs.shard }} + total_shards: + description: "Total number of shards" + value: ${{ steps.shards.outputs.total_shards }} +runs: + using: "composite" + steps: + - name: Install nf-test + uses: nf-core/setup-nf-test@v1 + with: + version: ${{ env.NFT_VER }} + - name: Get number of shards + id: shards + shell: bash + run: | + # Run nf-test with dynamic parameter + nftest_output=$(nf-test test \ + --profile +docker \ + $(if [ -n "${{ inputs.tags }}" ]; then echo "--tag ${{ inputs.tags }}"; fi) \ + --dry-run \ + --ci \ + --changed-since HEAD^) || { + echo "nf-test command failed with exit code $?" + echo "Full output: $nftest_output" + exit 1 + } + echo "nf-test dry-run output: $nftest_output" + + # Default values for shard and total_shards + shard="[]" + total_shards=0 + + # Check if there are related tests + if echo "$nftest_output" | grep -q 'No tests to execute'; then + echo "No related tests found." + else + # Extract the number of related tests + number_of_shards=$(echo "$nftest_output" | sed -n 's|.*Executed \([0-9]*\) tests.*|\1|p') + if [[ -n "$number_of_shards" && "$number_of_shards" -gt 0 ]]; then + shards_to_run=$(( $number_of_shards < ${{ inputs.max_shards }} ? $number_of_shards : ${{ inputs.max_shards }} )) + shard=$(seq 1 "$shards_to_run" | jq -R . | jq -c -s .) + total_shards="$shards_to_run" + else + echo "Unexpected output format. Falling back to default values." + fi + fi + + # Write to GitHub Actions outputs + echo "shard=$shard" >> $GITHUB_OUTPUT + echo "total_shards=$total_shards" >> $GITHUB_OUTPUT + + # Debugging output + echo "Final shard array: $shard" + echo "Total number of shards: $total_shards" diff --git a/.github/actions/nf-test/action.yml b/.github/actions/nf-test/action.yml new file mode 100644 index 00000000..9c844d5a --- /dev/null +++ b/.github/actions/nf-test/action.yml @@ -0,0 +1,101 @@ +name: "nf-test Action" +description: "Runs nf-test with common setup steps" +inputs: + profile: + description: "Profile to use" + required: true + shard: + description: "Shard number for this CI job" + required: true + total_shards: + description: "Total number of test shards(NOT the total number of matrix jobs)" + required: true + paths: + description: "Test paths" + required: true + tags: + description: "Tags to pass as argument for nf-test --tag parameter" + required: false +runs: + using: "composite" + steps: + - name: Setup Nextflow + uses: nf-core/setup-nextflow@v2 + with: + version: "${{ env.NXF_VERSION }}" + + - name: Set up Python + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6 + with: + python-version: "3.14" + + - name: Install nf-test + uses: nf-core/setup-nf-test@v1 + with: + version: "${{ env.NFT_VER }}" + install-pdiff: true + + - name: Setup apptainer + if: contains(inputs.profile, 'singularity') + uses: eWaterCycle/setup-apptainer@main + + - name: Set up Singularity + if: contains(inputs.profile, 'singularity') + shell: bash + run: | + mkdir -p $NXF_SINGULARITY_CACHEDIR + mkdir -p $NXF_SINGULARITY_LIBRARYDIR + + - name: Run nf-test + shell: bash + env: + NFT_WORKDIR: ${{ env.NFT_WORKDIR }} + run: | + nf-test test \ + --profile=+${{ inputs.profile }} \ + $(if [ -n "${{ inputs.tags }}" ]; then echo "--tag ${{ inputs.tags }}"; fi) \ + --ci \ + --changed-since HEAD^ \ + --verbose \ + --tap=test.tap \ + --shard ${{ inputs.shard }}/${{ inputs.total_shards }} + + # Save the absolute path of the test.tap file to the output + echo "tap_file_path=$(realpath test.tap)" >> $GITHUB_OUTPUT + + - name: Generate test summary + if: always() + shell: bash + run: | + # Add header if it doesn't exist (using a token file to track this) + if [ ! -f ".summary_header" ]; then + echo "# 🚀 nf-test results" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "| Status | Test Name | Profile | Shard |" >> $GITHUB_STEP_SUMMARY + echo "|:------:|-----------|---------|-------|" >> $GITHUB_STEP_SUMMARY + touch .summary_header + fi + + if [ -f test.tap ]; then + while IFS= read -r line; do + if [[ $line =~ ^ok ]]; then + test_name="${line#ok }" + # Remove the test number from the beginning + test_name="${test_name#* }" + echo "| ✅ | ${test_name} | ${{ inputs.profile }} | ${{ inputs.shard }}/${{ inputs.total_shards }} |" >> $GITHUB_STEP_SUMMARY + elif [[ $line =~ ^not\ ok ]]; then + test_name="${line#not ok }" + # Remove the test number from the beginning + test_name="${test_name#* }" + echo "| ❌ | ${test_name} | ${{ inputs.profile }} | ${{ inputs.shard }}/${{ inputs.total_shards }} |" >> $GITHUB_STEP_SUMMARY + fi + done < test.tap + else + echo "| ⚠️ | No test results found | ${{ inputs.profile }} | ${{ inputs.shard }}/${{ inputs.total_shards }} |" >> $GITHUB_STEP_SUMMARY + fi + + - name: Clean up + if: always() + shell: bash + run: | + sudo rm -rf /home/ubuntu/tests/ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 0f45f92e..00000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,101 +0,0 @@ -name: nf-core CI -# This workflow runs the pipeline with the minimal test dataset to check that it completes without any syntax errors -on: - push: - branches: - - dev - pull_request: - release: - types: [published] - -env: - NXF_ANSI_LOG: false - NFT_VER: "0.9.2" - NFT_WORKDIR: "~" - NFT_DIFF: "pdiff" - NFT_DIFF_ARGS: "--line-numbers --expand-tabs=2" - AWS_ACCESS_KEY_ID: ${{ secrets.UGENT_S3_ACCESS_KEY }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.UGENT_S3_SECRET_KEY }} - -concurrency: - group: "${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}" - cancel-in-progress: true - -jobs: - test: - name: ${{ matrix.tags }} ${{ matrix.profile }} NF-${{ matrix.NXF_VER }} - # 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-cmgg/preprocessing') }}" - runs-on: ubuntu-latest - strategy: - matrix: - NXF_VER: - - "25.04.0" - tags: - - "modules/local/panelcoverage" - - "subworkflows/local/bam_qc" - - "subworkflows/local/coverage" - - "subworkflows/local/fastq_to_aligned_cram" - - "subworkflows/local/fastq_align_rna" - - "subworkflows/local/fastq_to_unaligned_cram" - - "workflows/preprocessing" - - "pipeline" - profile: - - "test,docker" - steps: - - name: Check out pipeline code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - - name: Install Nextflow - uses: nf-core/setup-nextflow@v1 - with: - version: "${{ matrix.NXF_VER }}" - - - name: Disk space cleanup - uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 - - - uses: actions/setup-python@v4 - with: - python-version: "3.11" - architecture: "x64" - - - name: Install pdiff to see diff between nf-test snapshots - run: | - python -m pip install --upgrade pip - pip install pdiff - - - name: Cache nf-test installation - id: cache-software - uses: actions/cache@v3 - with: - path: | - /usr/local/bin/nf-test - /home/runner/.nf-test/nf-test.jar - key: ${{ runner.os }}-${{ env.NFT_VER }}-nftest - - - name: Install nf-test - if: steps.cache-software.outputs.cache-hit != 'true' - run: | - wget -qO- https://code.askimed.com/install/nf-test | bash - sudo mv nf-test /usr/local/bin/ - - - name: Run nf-test - run: | - nf-test test --verbose --tag "${{ matrix.tags }}" --profile "+${{ matrix.profile }}" --junitxml=test.xml --tap=test.tap - - - uses: pcolby/tap-summary@v1 - with: - path: >- - test.tap - - - name: Output log on failure - if: failure() - run: | - sudo apt install bat > /dev/null - batcat --decorations=always --color=always ${{ github.workspace }}/.nf-test/tests/*/meta/nextflow.log - - - name: Publish Test Report - uses: mikepenz/action-junit-report@v3 - if: always() # always run even if the previous step fails - with: - report_paths: test.xml diff --git a/.github/workflows/clean-up.yml b/.github/workflows/clean-up.yml index 0b6b1f27..587faa0b 100644 --- a/.github/workflows/clean-up.yml +++ b/.github/workflows/clean-up.yml @@ -10,11 +10,11 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9 + - uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10 with: - stale-issue-message: "This issue has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment otherwise this issue will be closed in 20 days." - stale-pr-message: "This PR has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment if it is still useful." - close-issue-message: "This issue was closed because it has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor and then staled for 20 days with no activity." + stale-issue-message: "This issue has been tagged as awaiting-changes or awaiting-feedback by an nf-cmgg contributor. Remove stale label or add a comment otherwise this issue will be closed in 20 days." + stale-pr-message: "This PR has been tagged as awaiting-changes or awaiting-feedback by an nf-cmgg contributor. Remove stale label or add a comment if it is still useful." + close-issue-message: "This issue was closed because it has been tagged as awaiting-changes or awaiting-feedback by an nf-cmgg contributor and then staled for 20 days with no activity." days-before-stale: 30 days-before-close: 20 days-before-pr-close: -1 diff --git a/.github/workflows/download_pipeline.yml b/.github/workflows/download_pipeline.yml deleted file mode 100644 index f823210d..00000000 --- a/.github/workflows/download_pipeline.yml +++ /dev/null @@ -1,72 +0,0 @@ -name: Test successful pipeline download with 'nf-core download' - -# Run the workflow when: -# - dispatched manually -# - when a PR is opened or reopened to 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: - inputs: - testbranch: - description: "The specific branch you wish to utilize for the test execution of nf-core download." - required: true - default: "dev" - pull_request: - types: - - opened - branches: - - master - pull_request_target: - branches: - - master - -env: - NXF_ANSI_LOG: false - -jobs: - download: - runs-on: ubuntu-latest - steps: - - name: Install Nextflow - uses: nf-core/setup-nextflow@b9f764e8ba5c76b712ace14ecbfcef0e40ae2dd8 # v1 - - - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5 - with: - python-version: "3.11" - architecture: "x64" - - uses: eWaterCycle/setup-singularity@931d4e31109e875b13309ae1d07c70ca8fbc8537 # v7 - with: - singularity-version: 3.8.3 - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install git+https://github.com/nf-core/tools.git@dev - - - name: Get the repository name and current branch set as environment variable - run: | - echo "REPO_LOWERCASE=${GITHUB_REPOSITORY,,}" >> ${GITHUB_ENV} - echo "REPOTITLE_LOWERCASE=$(basename ${GITHUB_REPOSITORY,,})" >> ${GITHUB_ENV} - echo "REPO_BRANCH=${{ github.event.inputs.testbranch || 'dev' }}" >> ${GITHUB_ENV} - - - name: Download the pipeline - env: - NXF_SINGULARITY_CACHEDIR: ./ - run: | - nf-core 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-cache-utilisation 'amend' \ - --download-configuration - - - name: Inspect download - run: tree ./${{ env.REPOTITLE_LOWERCASE }} - - - name: Run the downloaded pipeline - env: - NXF_SINGULARITY_CACHEDIR: ./ - NXF_SINGULARITY_HOME_MOUNT: true - run: nextflow run ./${{ env.REPOTITLE_LOWERCASE }}/$( sed 's/\W/_/g' <<< ${{ env.REPO_BRANCH }}) -stub -profile test,singularity --outdir ./results diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml deleted file mode 100644 index 2230aafb..00000000 --- a/.github/workflows/fix-linting.yml +++ /dev/null @@ -1,89 +0,0 @@ -name: Fix linting from a comment -on: - issue_comment: - types: [created] - -jobs: - fix-linting: - # Only run if comment is on a PR with the main repo, and if it contains the magic keywords - if: > - contains(github.event.comment.html_url, '/pull/') && - contains(github.event.comment.body, '@nf-core-bot fix linting') && - github.repository == 'nf-cmgg/preprocessing' - runs-on: ubuntu-latest - steps: - # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - with: - token: ${{ secrets.nf_core_bot_auth_token }} - - # indication that the linting is being fixed - - name: React on comment - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4 - with: - comment-id: ${{ github.event.comment.id }} - reactions: eyes - - # Action runs on the issue comment, so we don't get the PR by default - # Use the gh cli to check out the PR - - name: Checkout Pull Request - run: gh pr checkout ${{ github.event.issue.number }} - env: - GITHUB_TOKEN: ${{ secrets.nf_core_bot_auth_token }} - - # Install and run pre-commit - - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5 - with: - python-version: 3.11 - - - name: Install pre-commit - run: pip install pre-commit - - - name: Run pre-commit - id: pre-commit - run: pre-commit run --all-files - continue-on-error: true - - # indication that the linting has finished - - name: react if linting finished succesfully - if: steps.pre-commit.outcome == 'success' - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4 - with: - comment-id: ${{ github.event.comment.id }} - reactions: "+1" - - - name: Commit & push changes - id: commit-and-push - if: steps.pre-commit.outcome == 'failure' - run: | - git config user.email "core@nf-co.re" - git config user.name "nf-core-bot" - git config push.default upstream - git add . - git status - git commit -m "[automated] Fix code linting" - git push - - - name: react if linting errors were fixed - id: react-if-fixed - if: steps.commit-and-push.outcome == 'success' - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4 - with: - comment-id: ${{ github.event.comment.id }} - reactions: hooray - - - name: react if linting errors were not fixed - if: steps.commit-and-push.outcome == 'failure' - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4 - with: - comment-id: ${{ github.event.comment.id }} - reactions: confused - - - name: react if linting errors were not fixed - if: steps.commit-and-push.outcome == 'failure' - uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4 - with: - issue-number: ${{ github.event.issue.number }} - body: | - @${{ github.actor }} I tried to fix the linting errors, but it didn't work. Please fix them manually. - See [CI log](https://github.com/nf-cmgg/preprocessing/actions/runs/${{ github.run_id }}) for more details. diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index dbd52d5a..7a527a34 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -3,9 +3,6 @@ name: nf-core linting # It runs the `nf-core pipelines lint` and markdown lint tests to ensure # that the code meets the nf-core guidelines. on: - push: - branches: - - dev pull_request: release: types: [published] @@ -14,12 +11,12 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - - name: Set up Python 3.12 - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5 + - name: Set up Python 3.14 + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6 with: - python-version: "3.12" + python-version: "3.14" - name: Install pre-commit run: pip install pre-commit @@ -31,18 +28,18 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out pipeline code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: Install Nextflow uses: nf-core/setup-nextflow@v2 - - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5 + - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6 with: - python-version: "3.12" + python-version: "3.14" architecture: "x64" - name: read .nf-core.yml - uses: pietrobolcato/action-read-yaml@1.1.0 + uses: pietrobolcato/action-read-yaml@9f13718d61111b69f30ab4ac683e67a56d254e1d # 1.1.0 id: read_yml with: config: ${{ github.workspace }}/.nf-core.yml @@ -74,7 +71,7 @@ jobs: - name: Upload linting log file artifact if: ${{ always() }} - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 with: name: linting-logs path: | diff --git a/.github/workflows/linting_comment.yml b/.github/workflows/linting_comment.yml index 0bed96d3..e6e9bc26 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@80620a5d27ce0ae443b965134db88467fc607b43 # v7 + uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 with: workflow: linting.yml workflow_conclusion: completed @@ -21,7 +21,7 @@ jobs: run: echo "pr_number=$(cat linting-logs/PR_number.txt)" >> $GITHUB_OUTPUT - name: Post PR comment - uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31 # v2 + uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} number: ${{ steps.pr_number.outputs.pr_number }} diff --git a/.github/workflows/nf-test.yml b/.github/workflows/nf-test.yml new file mode 100644 index 00000000..f55b0075 --- /dev/null +++ b/.github/workflows/nf-test.yml @@ -0,0 +1,141 @@ +name: Run nf-test +on: + pull_request: + paths-ignore: + - "docs/**" + - "**/meta.yml" + - "**/*.md" + - "**/*.png" + - "**/*.svg" + release: + types: [published] + workflow_dispatch: null + +# Cancel if a newer run is started +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NFT_VER: "0.9.3" + NFT_WORKDIR: "~" + NXF_ANSI_LOG: false + NXF_SINGULARITY_CACHEDIR: ${{ github.workspace }}/.singularity + NXF_SINGULARITY_LIBRARYDIR: ${{ github.workspace }}/.singularity + AWS_ACCESS_KEY_ID: ${{ secrets.UGENT_S3_ACCESS_KEY }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.UGENT_S3_SECRET_KEY }} + +jobs: + nf-test-changes: + name: nf-test-changes + runs-on: # use GitHub runners + - "ubuntu-latest" + outputs: + shard: ${{ steps.set-shards.outputs.shard }} + total_shards: ${{ steps.set-shards.outputs.total_shards }} + steps: + - name: Clean Workspace # Purge the workspace in case it's running on a self-hosted runner + run: | + ls -la ./ + rm -rf ./* || true + rm -rf ./.??* || true + ls -la ./ + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + with: + fetch-depth: 0 + + - name: get number of shards + id: set-shards + uses: ./.github/actions/get-shards + env: + NFT_VER: ${{ env.NFT_VER }} + with: + max_shards: 7 + + - name: debug + run: | + echo ${{ steps.set-shards.outputs.shard }} + echo ${{ steps.set-shards.outputs.total_shards }} + + nf-test: + name: "${{ matrix.profile }} | ${{ matrix.NXF_VER }} | ${{ matrix.shard }}/${{ needs.nf-test-changes.outputs.total_shards }}" + needs: [nf-test-changes] + if: ${{ needs.nf-test-changes.outputs.total_shards != '0' }} + runs-on: # use GitHub runners + - "ubuntu-latest" + strategy: + fail-fast: false + matrix: + shard: ${{ fromJson(needs.nf-test-changes.outputs.shard) }} + profile: [docker, singularity] + isMain: + - ${{ github.base_ref == 'master' || github.base_ref == 'main' }} + # Exclude singularity on dev + exclude: + - isMain: false + profile: "singularity" + NXF_VER: + - 25.10.0 + - latest-everything + env: + NXF_ANSI_LOG: false + TOTAL_SHARDS: ${{ needs.nf-test-changes.outputs.total_shards }} + + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + with: + fetch-depth: 0 + + - name: Run nf-test + id: run_nf_test + uses: ./.github/actions/nf-test + continue-on-error: ${{ matrix.NXF_VER == 'latest-everything' }} + env: + NFT_WORKDIR: ${{ env.NFT_WORKDIR }} + NXF_VERSION: ${{ matrix.NXF_VER }} + with: + profile: ${{ matrix.profile }} + shard: ${{ matrix.shard }} + total_shards: ${{ env.TOTAL_SHARDS }} + + - name: Report test status + if: ${{ always() }} + run: | + if [[ "${{ steps.run_nf_test.outcome }}" == "failure" ]]; then + echo "::error::Test with ${{ matrix.NXF_VER }} failed" + # Add to workflow summary + echo "## ❌ Test failed: ${{ matrix.profile }} | ${{ matrix.NXF_VER }} | Shard ${{ matrix.shard }}/${{ env.TOTAL_SHARDS }}" >> $GITHUB_STEP_SUMMARY + if [[ "${{ matrix.NXF_VER }}" == "latest-everything" ]]; then + echo "::warning::Test with latest-everything failed but will not cause workflow failure. Please check if the error is expected or if it needs fixing." + fi + if [[ "${{ matrix.NXF_VER }}" != "latest-everything" ]]; then + exit 1 + fi + fi + + confirm-pass: + needs: [nf-test] + if: always() + runs-on: # use GitHub runners + - "ubuntu-latest" + steps: + - name: One or more tests failed (excluding latest-everything) + if: ${{ contains(needs.*.result, 'failure') }} + run: exit 1 + + - name: One or more tests cancelled + if: ${{ contains(needs.*.result, 'cancelled') }} + run: exit 1 + + - name: All tests ok + if: ${{ contains(needs.*.result, 'success') }} + run: exit 0 + + - name: debug-print + if: always() + run: | + echo "::group::DEBUG: `needs` Contents" + echo "DEBUG: toJSON(needs) = ${{ toJSON(needs) }}" + echo "DEBUG: toJSON(needs.*.result) = ${{ toJSON(needs.*.result) }}" + echo "::endgroup::" diff --git a/.gitignore b/.gitignore index 23b0c7de..980c9ac3 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ testing* *.pyc null/ .nf-test* +test_fc diff --git a/.nf-core.yml b/.nf-core.yml index e5858180..d06b88e6 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -14,20 +14,25 @@ lint: - docs/images/nf-core-preprocessing_logo_light.png - docs/images/nf-core-preprocessing_logo_dark.png - .github/ISSUE_TEMPLATE/bug_report.yml + - .github/PULL_REQUEST_TEMPLATE.md - docs/README.md - LICENSE - multiqc_config: - - report_comment - nextflow_config: - - manifest.name - - manifest.homePage - subworkflow_changes: false - template_strings: - - bin/cmgg_genelists merge_markers: - bin/cmgg_genelists + multiqc_config: false + nextflow_config: false + template_strings: + - bin/cmgg_genelists + nf_test_content: false +nf_core_version: 3.5.2 repository_type: pipeline template: - prefix: nf-cmgg - skip: [] -nf_core_version: 3.1.1 + author: Matthias De Smet, Nicolas Vannieuwkerke + description: Demultiplexing, adapter trimming, alignment, and coverage calculation for NGS data. + force: false + is_nfcore: false + name: preprocessing + org: nf-cmgg + outdir: . + skip_features: ["fastqc"] + version: 3.0.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index af57081f..d06777a8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,8 +3,25 @@ repos: rev: "v3.1.0" hooks: - id: prettier - - repo: https://github.com/editorconfig-checker/editorconfig-checker.python - rev: "2.7.3" + additional_dependencies: + - prettier@3.6.2 + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 hooks: - - id: editorconfig-checker - alias: ec + - id: trailing-whitespace + args: [--markdown-linebreak-ext=md] + exclude: | + (?x)^( + .*ro-crate-metadata.json$| + modules/nf-core/.*| + subworkflows/nf-core/.*| + .*\.snap$ + )$ + - id: end-of-file-fixer + exclude: | + (?x)^( + .*ro-crate-metadata.json$| + modules/nf-core/.*| + subworkflows/nf-core/.*| + .*\.snap$ + )$ diff --git a/.prettierignore b/.prettierignore index edd29f01..dd749d43 100644 --- a/.prettierignore +++ b/.prettierignore @@ -10,4 +10,7 @@ testing/ testing* *.pyc bin/ +.nf-test/ ro-crate-metadata.json +modules/nf-core/ +subworkflows/nf-core/ diff --git a/.prettierrc.yml b/.prettierrc.yml index c81f9a76..07dbd8bb 100644 --- a/.prettierrc.yml +++ b/.prettierrc.yml @@ -1 +1,6 @@ printWidth: 120 +tabWidth: 4 +overrides: + - files: "*.{md,yml,yaml,html,css,scss,js,cff}" + options: + tabWidth: 2 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..a33b527c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "markdown.styles": ["public/vscode_markdown.css"] +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 11783049..34cc5393 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,24 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## dev +## 3.0.0 + +- Add `MultiQC-SAV` module for Illumina Run QC reports +- Migrate readgroup parsing from `preprocessing.nf` to a local subworkflow +- Update pipeline to use topic channels only, deprecation `versions` channels +- Drop `bcl_demultiplex` subworkflow in favour of `bcl-convert` module +- Update the output handling to use the new workflow output definitions. +- Bump all modules to latest versions. +- The workflow now outputs data in a subdirectory per `library`, including a library specific MultiQC report +- Drop support for unaligned cram outputs in favor of untrimmed fastq outputs, which are more widely supported and can be used for a wider range of downstream analyses. +- Add support for untrimmed fastq outputs for unsupported genomes or when aligner is set to `false`. +- Drop support for global `aligner` parameter. The aligner must now be specified per sample in the sample sheet or sample info. +- Drop support for global `markdup` and `umi_aware` parameters. Marking duplicates must now be specified per sample in the sample sheet or sample info. +- Drop support for global `run_coverage` and `disable_picard_metrics` parameters. Running coverage analysis must now be specified per sample in the sample sheet or sample info. +- Drop support for global `skip_trimming`, `trim_front`, `trim_tail`, `adapter_R1` and `adapter_R2` parameters. Trimming must now be specified per sample in the sample sheet or sample info. +- Drop support for global `roi` parameter. Regions of interest must now be specified per sample in the sample sheet or sample info. +- Simplify fastq sharding and make it user configurable via the `split_fastq` parameter. +- Added splice junctions and junctions outputs for RNA-seq alignments using STAR. ## v2.0.6 @@ -33,7 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## v2.0.2 -- Drop unsed params +- Drop unused params - Set aligner to `star` for RNA-seq - Finetune resources - Fix some bugs for different input tags diff --git a/README.md b/README.md index 0964e70c..2d6849f9 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,15 @@ -# ![nf-cmgg/preprocessing](docs/images/nf-cmgg-preprocessing_logo_light.png#gh-light-mode-only) ![nf-cmgg/preprocessing](docs/images/nf-cmgg-preprocessing_logo_dark.png#gh-dark-mode-only) +# nf-cmgg/preprocessing -[![GitHub Actions CI Status](https://github.com/nf-cmgg/preprocessing/actions/workflows/ci.yml/badge.svg)](https://github.com/nf-cmgg/preprocessing/actions/workflows/ci.yml) -[![GitHub Actions Linting Status](https://github.com/nf-cmgg/preprocessing/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-cmgg/preprocessing/actions/workflows/linting.yml) -[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A525.04.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/) +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new/nf-cmgg/preprocessing) +[![GitHub Actions CI Status](https://github.com/nf-cmgg/preprocessing/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-cmgg/preprocessing/actions/workflows/nf-test.yml) +[![GitHub Actions Linting Status](https://github.com/nf-cmgg/preprocessing/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-cmgg/preprocessing/actions/workflows/linting.yml)[![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/version-%E2%89%A525.10.0-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/) +[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.5.1-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.5.1) [![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/) [![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/) +[![Launch on 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-cmgg/preprocessing) ## Introduction @@ -14,17 +18,23 @@ It also performs basic QC and coverage analysis. The pipeline is built using Nextflow, a workflow tool to run tasks across multiple compute infrastructures in a very portable manner. It comes with docker containers making installation trivial and results highly reproducible. -Steps inlcude: +Steps include: + +- Demultiplexing using [`BCLconvert`](https://emea.support.illumina.com/sequencing/sequencing_software/bcl-convert.html) +- Run QC using [`MultiQC SAV`](https://github.com/MultiQC/MultiQC_SAV) +- Read QC and trimming using [`fastp`](https://github.com/OpenGene/fastp) or [`falco`](https://github.com/smithlabcode/falco) +- Alignment using either [`bwa`](https://github.com/lh3/bwa), [`bwa-mem2`](https://github.com/bwa-mem2/bwa-mem2), [`bowtie2`](https://github.com/BenLangmead/bowtie2), [`dragmap`](https://github.com/Illumina/DRAGMAP), [`snap`](https://github.com/amplab/snap) or [`strobe`](https://github.com/ksahlin/strobealign) for DNA-seq and [`STAR`](https://github.com/alexdobin/STAR) for RNA-seq +- Duplicate marking using [`bamsormadup`](https://gitlab.com/german.tischler/biobambam2) or [`samtools markdup`](http://www.htslib.org/doc/samtools-markdup.html) +- Coverage analysis using [`mosdepth`](https://github.com/brentp/mosdepth) and [`samtools coverage`](http://www.htslib.org/doc/samtools-coverage.html) +- Alignment QC using [`samtools flagstat`](http://www.htslib.org/doc/samtools-flagstat.html), [`samtools stats`](http://www.htslib.org/doc/samtools-stats.html), [`samtools idxstats`](http://www.htslib.org/doc/samtools-idxstats.html) and [`picard CollectHsMetrics`](https://broadinstitute.github.io/picard/command-line-overview.html#CollectHsMetrics), [`picard CollectWgsMetrics`](https://broadinstitute.github.io/picard/command-line-overview.html#CollectWgsMetrics), [`picard CollectMultipleMetrics`](https://broadinstitute.github.io/picard/command-line-overview.html#CollectMultipleMetrics) +- QC aggregation using [`multiqc`](https://multiqc.info/) -1. Demultiplexing using [`BCLconvert`](https://emea.support.illumina.com/sequencing/sequencing_software/bcl-convert.html) -2. Read QC and trimming using [`fastp`](https://github.com/OpenGene/fastp) -3. Alignment using either [`bwa`](https://github.com/lh3/bwa), [`bwa-mem2`](https://github.com/bwa-mem2/bwa-mem2), [`bowtie2`](https://github.com/BenLangmead/bowtie2), [`dragmap`](https://github.com/Illumina/DRAGMAP) or [`snap`](https://github.com/amplab/snap) for DNA-seq and [`STAR`](https://github.com/alexdobin/STAR) for RNA-seq -4. Duplicate marking using [`bamsormadup`](https://gitlab.com/german.tischler/biobambam2) or [`samtools markdup`](http://www.htslib.org/doc/samtools-markdup.html) -5. Coverage analysis using [`mosdepth`](https://github.com/brentp/mosdepth) and [`samtools coverage`](http://www.htslib.org/doc/samtools-coverage.html) -6. Alignment QC using [`samtools flagstat`](http://www.htslib.org/doc/samtools-flagstat.html), [`samtools stats`](http://www.htslib.org/doc/samtools-stats.html), [`samtools idxstats`](http://www.htslib.org/doc/samtools-idxstats.html) and [`picard CollecHsMetrics`](https://broadinstitute.github.io/picard/command-line-overview.html#CollectHsMetrics), [`picard CollectWgsMetrics`](https://broadinstitute.github.io/picard/command-line-overview.html#CollectWgsMetrics), [`picard CollectMultipleMetrics`](https://broadinstitute.github.io/picard/command-line-overview.html#CollectMultipleMetrics) -7. QC aggregation using [`multiqc`](https://multiqc.info/) + -![metro map](docs/images/metro_map.png) + + + Fallback image description + ## Usage @@ -33,36 +43,15 @@ Steps inlcude: The full documentation can be found [here](docs/README.md) -First, prepare a samplesheet with your input data that looks as follows: - -`samplesheet.csv` for fastq inputs: - -```csv -id,samplename,organism,library,fastq_1,fastq_2 -sample1,sample1,Homo sapiens,Library_Name,reads1.fq.gz,reads2.fq.gz -``` - -`samplesheet.csv` for flowcell inputs: - -```csv -id,samplesheet,lane,flowcell,sample_info -flowcell_id,/path/to/illumina_samplesheet.csv,1,/path/to/sequencer_uploaddir,/path/to/sampleinfo.csv -``` - -`sampleinfo.csv` for use with flowcell inputs: - -```csv -samplename,library,organism,tag -fc_sample1,test,Homo sapiens,WES -``` +First, prepare a samplesheet with your input data. Check the [usage docs](docs/usage.md) for details on the required format and example files. Now, you can run the pipeline using: ```bash nextflow run nf-cmgg/preprocessing \ - -profile \ + -profile \ --igenomes_base /path/to/genomes \ - --input samplesheet.csv \ + --input samplesheet. \ --outdir ``` diff --git a/assets/adaptivecard.json b/assets/adaptivecard.json deleted file mode 100644 index 92ed5f06..00000000 --- a/assets/adaptivecard.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "type": "message", - "attachments": [ - { - "contentType": "application/vnd.microsoft.card.adaptive", - "contentUrl": null, - "content": { - "\$schema": "http://adaptivecards.io/schemas/adaptive-card.json", - "msteams": { - "width": "Full" - }, - "type": "AdaptiveCard", - "version": "1.2", - "body": [ - { - "type": "TextBlock", - "size": "Large", - "weight": "Bolder", - "color": "<% if (success) { %>Good<% } else { %>Attention<%} %>", - "text": "nf-cmgg/preprocessing v${version} - ${runName}", - "wrap": true - }, - { - "type": "TextBlock", - "spacing": "None", - "text": "Completed at ${dateComplete} (duration: ${duration})", - "isSubtle": true, - "wrap": true - }, - { - "type": "TextBlock", - "text": "<% if (success) { %>Pipeline completed successfully!<% } else { %>Pipeline completed with errors. The full error message was: ${errorReport}.<% } %>", - "wrap": true - }, - { - "type": "TextBlock", - "text": "The command used to launch the workflow was as follows:", - "wrap": true - }, - { - "type": "TextBlock", - "text": "${commandLine}", - "isSubtle": true, - "wrap": true - } - ], - "actions": [ - { - "type": "Action.ShowCard", - "title": "Pipeline Configuration", - "card": { - "type": "AdaptiveCard", - "\$schema": "http://adaptivecards.io/schemas/adaptive-card.json", - "body": [ - { - "type": "FactSet", - "facts": [<% out << summary.collect{ k,v -> "{\"title\": \"$k\", \"value\" : \"$v\"}"}.join(",\n") %> - ] - } - ] - } - } - ] - } - } - ] -} diff --git a/assets/multiqc_config.yml b/assets/multiqc_config.yml index 53ed49db..3b59662f 100644 --- a/assets/multiqc_config.yml +++ b/assets/multiqc_config.yml @@ -1,6 +1,5 @@ report_comment: > - This report has been generated by the nf-cmgg/preprocessing analysis pipeline. + This report has been generated by the nf-cmgg/preprocessing analysis pipeline. report_section_order: "nf-cmgg-preprocessing-methods-description": order: -1000 @@ -8,7 +7,7 @@ report_section_order: order: -1001 "nf-cmgg-preprocessing-summary": order: -1002 -export_plots: true +export_plots: false disable_version_detection: true bclconvert: create_undetermined_barcode_barplots: true diff --git a/assets/samplesheet.csv b/assets/samplesheet.csv new file mode 100644 index 00000000..5f653ab7 --- /dev/null +++ b/assets/samplesheet.csv @@ -0,0 +1,3 @@ +sample,fastq_1,fastq_2 +SAMPLE_PAIRED_END,/path/to/fastq/files/AEG588A1_S1_L002_R1_001.fastq.gz,/path/to/fastq/files/AEG588A1_S1_L002_R2_001.fastq.gz +SAMPLE_SINGLE_END,/path/to/fastq/files/AEG588A4_S4_L003_R1_001.fastq.gz, diff --git a/assets/schema_input.json b/assets/schema_input.json index beaa2eb6..4a7bd527 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -35,9 +35,73 @@ }, "aligner": { "meta": ["aligner"], - "type": "string", + "type": ["string", "boolean"], "description": "Aligner to use to align sample to the reference genome", - "enum": ["bowtie2", "bwamem", "bwamem2", "dragmap", "snap", "star"] + "enum": ["bowtie2", "bwamem", "bwamem2", "dragmap", "snap", "strobe", "star", "false", false], + "default": "false" + }, + "markdup": { + "meta": ["markdup"], + "type": ["string", "boolean"], + "description": "Mark duplicates tool to use", + "enum": ["bamsormadup", "samtools", "false", false], + "default": "bamsormadup" + }, + "umi_aware": { + "meta": ["umi_aware"], + "type": "boolean", + "description": "Run markdup in UMI-aware mode. This applies to Samtools only and requires the UMI to be in the read name.", + "default": false + }, + "skip_trimming": { + "meta": ["skip_trimming"], + "type": "boolean", + "description": "Skip adapter trimming", + "default": false + }, + "trim_front": { + "meta": ["trim_front"], + "type": "integer", + "description": "Number of bases to trim from the front of each read", + "default": 0 + }, + "trim_tail": { + "meta": ["trim_tail"], + "type": "integer", + "description": "Number of bases to trim from the tail of each read", + "default": 0 + }, + "adapter_R1": { + "meta": ["adapter_R1"], + "type": "string", + "description": "Adapter sequence to trim from read 1", + "default": null + }, + "adapter_R2": { + "meta": ["adapter_R2"], + "type": "string", + "description": "Adapter sequence to trim from read 2", + "default": null + }, + "run_coverage": { + "meta": ["run_coverage"], + "type": "boolean", + "description": "Whether to run coverage analysis for the sample", + "default": true + }, + "disable_picard_metrics": { + "meta": ["disable_picard_metrics"], + "type": "boolean", + "description": "Whether to disable Picard metrics calculation. This can be used to speed up processing if Picard is not needed.", + "default": true + }, + "roi": { + "meta": ["roi"], + "type": "string", + "format": "file-path", + "description": "Region of interest BED file for coverage analysis", + "pattern": "^\\S+\\.bed$", + "default": null }, "tag": { "meta": ["tag"], @@ -45,12 +109,6 @@ "description": "Sample tag", "pattern": "^[a-zA-Z0-9_-]+$" }, - "purpose": { - "meta": ["purpose"], - "type": "string", - "description": "Sample purpose, can be either 'research' or 'diagnostic'", - "enum": ["research", "diagnostic"] - }, "sample_type": { "meta": ["sample_type"], "type": "string", @@ -64,14 +122,6 @@ "pattern": "^[a-zA-Z0-9_-]+$", "description": "Sample library name" }, - "roi": { - "meta": ["roi"], - "type": "string", - "format": "file-path", - "description": "Region of interest BED file for coverage analysis", - "pattern": "^[a-zA-Z0-9_]+.bed$", - "default": null - }, "lane": { "type": "integer", "meta": ["lane"], @@ -110,10 +160,10 @@ }, "anyOf": [ { - "required": ["id", "samplename", "organism", "tag", "fastq_1", "fastq_2"] + "required": ["id", "samplename", "organism", "aligner", "fastq_1", "fastq_2"] }, { - "required": ["id", "samplename", "genome", "tag", "fastq_1", "fastq_2"] + "required": ["id", "samplename", "genome", "aligner", "fastq_1", "fastq_2"] }, { "required": ["id", "samplesheet", "sample_info", "flowcell"] diff --git a/assets/schema_sampleinfo.json b/assets/schema_sampleinfo.json index b9c8aaf3..dee4c572 100644 --- a/assets/schema_sampleinfo.json +++ b/assets/schema_sampleinfo.json @@ -73,21 +73,84 @@ "type": "string" } }, + "aligner": { + "meta": ["aligner"], + "type": ["string", "boolean"], + "description": "Aligner to use to align sample to the reference genome", + "enum": ["bowtie2", "bwamem", "bwamem2", "dragmap", "snap", "strobe", "star", "false", false], + "default": "false" + }, + "markdup": { + "meta": ["markdup"], + "type": ["string", "boolean"], + "description": "Mark duplicates tool to use", + "enum": ["bamsormadup", "samtools", "false", false], + "default": "bamsormadup" + }, + "umi_aware": { + "meta": ["umi_aware"], + "type": "boolean", + "description": "Run markdup in UMI-aware mode. This applies to Samtools only and requires the UMI to be in the read name.", + "default": false + }, + "skip_trimming": { + "meta": ["skip_trimming"], + "type": "boolean", + "description": "Skip adapter trimming", + "default": false + }, + "trim_front": { + "meta": ["trim_front"], + "type": "integer", + "description": "Number of bases to trim from the front of each read", + "default": 0 + }, + "trim_tail": { + "meta": ["trim_tail"], + "type": "integer", + "description": "Number of bases to trim from the tail of each read", + "default": 0 + }, + "adapter_R1": { + "meta": ["adapter_R1"], + "type": "string", + "description": "Adapter sequence to trim from read 1", + "default": null + }, + "adapter_R2": { + "meta": ["adapter_R2"], + "type": "string", + "description": "Adapter sequence to trim from read 2", + "default": null + }, + "run_coverage": { + "meta": ["run_coverage"], + "type": "boolean", + "description": "Whether to run coverage analysis for the sample", + "default": true + }, + "disable_picard_metrics": { + "meta": ["disable_picard_metrics"], + "type": "boolean", + "description": "Whether to disable Picard metrics calculation. This can be used to speed up processing if Picard is not needed.", + "default": true + }, "roi": { "meta": ["roi"], "type": "string", "format": "file-path", "description": "Region of interest BED file for coverage analysis", - "pattern": "^[a-zA-Z0-9_]+.bed$", + "pattern": "^\\S+\\.bed$", "default": null - }, - "aligner": { - "meta": ["aligner"], - "type": "string", - "description": "Aligner to use to align sample to the reference genome", - "enum": ["bowtie2", "bwamem", "bwamem2", "dragmap", "snap", "star"] } } }, - "required": ["samplename", "tag", "organism"] + "anyOf": [ + { + "required": ["samplename", "organism", "aligner", "tag"] + }, + { + "required": ["samplename", "genome", "aligner", "tag"] + } + ] } diff --git a/assets/slackreport.json b/assets/slackreport.json deleted file mode 100644 index 84fc115a..00000000 --- a/assets/slackreport.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "attachments": [ - { - "fallback": "Plain-text summary of the attachment.", - "color": "<% if (success) { %>good<% } else { %>danger<%} %>", - "author_name": "nf-cmgg/preprocessing ${version} - ${runName}", - "author_icon": "https://www.nextflow.io/docs/latest/_static/favicon.ico", - "text": "<% if (success) { %>Pipeline completed successfully!<% } else { %>Pipeline completed with errors<% } %>", - "fields": [ - { - "title": "Command used to launch the workflow", - "value": "```${commandLine}```", - "short": false - } - <% - if (!success) { %> - , - { - "title": "Full error message", - "value": "```${errorReport}```", - "short": false - }, - { - "title": "Pipeline configuration", - "value": "<% out << summary.collect{ k,v -> k == "hook_url" ? "_${k}_: (_hidden_)" : ( ( v.class.toString().contains('Path') || ( v.class.toString().contains('String') && v.contains('/') ) ) ? "_${k}_: `${v}`" : (v.class.toString().contains('DateTime') ? ("_${k}_: " + v.format(java.time.format.DateTimeFormatter.ofLocalizedDateTime(java.time.format.FormatStyle.MEDIUM))) : "_${k}_: ${v}") ) }.join(",\n") %>", - "short": false - } - <% } - %> - ], - "footer": "Completed at <% out << dateComplete.format(java.time.format.DateTimeFormatter.ofLocalizedDateTime(java.time.format.FormatStyle.MEDIUM)) %> (duration: ${duration})" - } - ] -} diff --git a/conf/base.config b/conf/base.config index 5008f965..ac353851 100644 --- a/conf/base.config +++ b/conf/base.config @@ -10,46 +10,46 @@ process { - cpus = { 1 * task.attempt } - memory = { 8.GB * task.attempt } - time = { 4.h * task.attempt } - - errorStrategy = { task.exitStatus in ((130..145) + 104) ? 'retry' : 'finish' } - maxRetries = 1 + cpus = { 1 * task.attempt } + memory = { 8.GB * task.attempt } + time = { 4.h * task.attempt } + errorStrategy = { task.exitStatus in ((130..145) + 104 + 175 + 50001 + 50002 + 50003 + 50004 + 50005 + 50006) ? 'retry' : 'finish' } + maxRetries = 3 maxErrors = '-1' // Process-specific resource requirements - withLabel:process_single { - cpus = { 1 } + withLabel: process_single { + cpus = { 1 } memory = { 8.GB * task.attempt } - time = { 4.h * task.attempt } + time = { 4.h * task.attempt } } - withLabel:process_low { - cpus = { 2 * task.attempt } + withLabel: process_low { + cpus = { 2 * task.attempt } memory = { 16.GB * task.attempt } - time = { 4.h * task.attempt } + time = { 4.h * task.attempt } } - withLabel:process_medium { - cpus = { 8 * task.attempt } + withLabel: process_medium { + cpus = { 8 * task.attempt } memory = { 64.GB * task.attempt } - time = { 8.h * task.attempt } + time = { 8.h * task.attempt } } - withLabel:process_high { - cpus = { 16 * task.attempt } + withLabel: process_high { + cpus = { 16 * task.attempt } memory = { 128.GB * task.attempt } - time = { 16.h * task.attempt } - } - withLabel:process_long { - time = { 72.h * task.attempt } + time = { 16.h * task.attempt } } - withLabel:process_high_memory { - memory = { 200.GB * task.attempt } + withLabel: process_long { + time = { 20.h * task.attempt } } - withLabel:error_ignore { + withLabel: error_ignore { errorStrategy = 'ignore' } - withLabel:error_retry { + withLabel: error_retry { errorStrategy = 'retry' maxRetries = 2 } + withLabel: process_gpu { + ext.use_gpu = { workflow.profile.contains('gpu') } + accelerator = { workflow.profile.contains('gpu') ? 1 : null } + } } diff --git a/conf/igenomes.config b/conf/igenomes.config index 07e67809..3a6ea697 100644 --- a/conf/igenomes.config +++ b/conf/igenomes.config @@ -10,97 +10,96 @@ params { genomes { - "GRCh38" { + GRCh38 { // Genome reference - fai = "${params.igenomes_base}/Hsapiens/GRCh38/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set.fna.fai" - fasta = "${params.igenomes_base}/Hsapiens/GRCh38/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set.fna" - dict = "${params.igenomes_base}/Hsapiens/GRCh38/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set.dict" - gtf = "${params.igenomes_base}/Hsapiens/GRCh38/seq/GCA_000001405.15_GRCh38_full_analysis_set.refseq_annotation.gtf" + fai = "${params.igenomes_base}/Hsapiens/GRCh38/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set.fna.fai" + fasta = "${params.igenomes_base}/Hsapiens/GRCh38/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set.fna" + dict = "${params.igenomes_base}/Hsapiens/GRCh38/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set.dict" + gtf = "${params.igenomes_base}/Hsapiens/GRCh38/seq/GCA_000001405.15_GRCh38_full_analysis_set.refseq_annotation.gtf" // Aligner reference - bowtie2 = "${params.igenomes_base}/Hsapiens/GRCh38/bowtie2" - bwamem = "${params.igenomes_base}/Hsapiens/GRCh38/bwa" - bwamem2 = "${params.igenomes_base}/Hsapiens/GRCh38/bwamem2" - dragmap = "${params.igenomes_base}/Hsapiens/GRCh38/dragmap" - snap = "${params.igenomes_base}/Hsapiens/GRCh38/snapaligner" - star = "${params.igenomes_base}/Hsapiens/GRCh38/star" + bowtie2 = "${params.igenomes_base}/Hsapiens/GRCh38/bowtie2" + bwamem = "${params.igenomes_base}/Hsapiens/GRCh38/bwa" + bwamem2 = "${params.igenomes_base}/Hsapiens/GRCh38/bwamem2" + dragmap = "${params.igenomes_base}/Hsapiens/GRCh38/dragmap" + snap = "${params.igenomes_base}/Hsapiens/GRCh38/snapaligner" + star = "${params.igenomes_base}/Hsapiens/GRCh38/star" // ROI's - roi_copgt = "${params.igenomes_base}/Hsapiens/GRCh38/regions/CMGG_coPGT-M_analyses_ROI_v1.bed" - roi_wes = "${params.igenomes_base}/Hsapiens/GRCh38/regions/CMGG_WES_analysis_ROI_v6.bed" + roi_copgt = "${params.igenomes_base}/Hsapiens/GRCh38/regions/CMGG_coPGT-M_analyses_ROI_v1.bed" + roi_wes = "${params.igenomes_base}/Hsapiens/GRCh38/regions/CMGG_WES_analysis_ROI_v7.bed" } - "GRCm39" { + GRCm39 { // Genome reference - fai = "${params.igenomes_base}/Mmusculus/GRCm39/seq/GCF_000001635.27_GRCm39_genomic.fna.fai" - fasta = "${params.igenomes_base}/Mmusculus/GRCm39/seq/GCF_000001635.27_GRCm39_genomic.fna" - dict = "${params.igenomes_base}/Mmusculus/GRCm39/seq/GCF_000001635.27_GRCm39_genomic.dict" - gtf = "${params.igenomes_base}/Mmusculus/GRCm39/seq/GCF_000001635.27_GRCm39_genomic.gtf" + fai = "${params.igenomes_base}/Mmusculus/GRCm39/seq/GCF_000001635.27_GRCm39_genomic.fna.fai" + fasta = "${params.igenomes_base}/Mmusculus/GRCm39/seq/GCF_000001635.27_GRCm39_genomic.fna" + dict = "${params.igenomes_base}/Mmusculus/GRCm39/seq/GCF_000001635.27_GRCm39_genomic.dict" + gtf = "${params.igenomes_base}/Mmusculus/GRCm39/seq/GCF_000001635.27_GRCm39_genomic.gtf" // Aligner reference - bowtie2 = "${params.igenomes_base}/Mmusculus/GRCm39/bowtie2" - bwamem = "${params.igenomes_base}/Mmusculus/GRCm39/bwa" - bwamem2 = "${params.igenomes_base}/Mmusculus/GRCm39/bwamem2" - dragmap = "${params.igenomes_base}/Mmusculus/GRCm39/dragmap" - snap = "${params.igenomes_base}/Mmusculus/GRCm39/snapaligner" - star = "${params.igenomes_base}/Mmusculus/GRCm39/star" + bowtie2 = "${params.igenomes_base}/Mmusculus/GRCm39/bowtie2" + bwamem = "${params.igenomes_base}/Mmusculus/GRCm39/bwa" + bwamem2 = "${params.igenomes_base}/Mmusculus/GRCm39/bwamem2" + dragmap = "${params.igenomes_base}/Mmusculus/GRCm39/dragmap" + snap = "${params.igenomes_base}/Mmusculus/GRCm39/snapaligner" + star = "${params.igenomes_base}/Mmusculus/GRCm39/star" } - "mm10" { + mm10 { // Genome reference - fai = "${params.igenomes_base}/Mmusculus/mm10/seq/mm10.fa.fai" - fasta = "${params.igenomes_base}/Mmusculus/mm10/seq/mm10.fa" - dict = "${params.igenomes_base}/Mmusculus/mm10/seq/mm10.dict" - gtf = "${params.igenomes_base}/Mmusculus/mm10/seq/Mus_musculus.GRCm38.102.chr.gtf" + fai = "${params.igenomes_base}/Mmusculus/mm10/seq/mm10.fa.fai" + fasta = "${params.igenomes_base}/Mmusculus/mm10/seq/mm10.fa" + dict = "${params.igenomes_base}/Mmusculus/mm10/seq/mm10.dict" + gtf = "${params.igenomes_base}/Mmusculus/mm10/seq/Mus_musculus.GRCm38.102.chr.gtf" // Aligner reference - bowtie2 = "${params.igenomes_base}/Mmusculus/mm10/bowtie2" - bwamem = "${params.igenomes_base}/Mmusculus/mm10/bwa" - bwamem2 = "${params.igenomes_base}/Mmusculus/mm10/bwamem2" - dragmap = "${params.igenomes_base}/Mmusculus/mm10/dragmap" - snap = "${params.igenomes_base}/Mmusculus/mm10/snapaligner" - star = "${params.igenomes_base}/Mmusculus/mm10/star" + bowtie2 = "${params.igenomes_base}/Mmusculus/mm10/bowtie2" + bwamem = "${params.igenomes_base}/Mmusculus/mm10/bwa" + bwamem2 = "${params.igenomes_base}/Mmusculus/mm10/bwamem2" + dragmap = "${params.igenomes_base}/Mmusculus/mm10/dragmap" + snap = "${params.igenomes_base}/Mmusculus/mm10/snapaligner" + star = "${params.igenomes_base}/Mmusculus/mm10/star" } - "GRCz11" { + GRCz11 { // Genome reference - fai = "${params.igenomes_base}/Drerio/GRCz11/seq/GCF_000002035.6_GRCz11_genomic.fna.fai" - fasta = "${params.igenomes_base}/Drerio/GRCz11/seq/GCF_000002035.6_GRCz11_genomic.fna" - dict = "${params.igenomes_base}/Drerio/GRCz11/seq/GCF_000002035.6_GRCz11_genomic.dict" - gtf = "${params.igenomes_base}/Drerio/GRCz11/seq/GCF_000002035.6_GRCz11_genomic.gtf" + fai = "${params.igenomes_base}/Drerio/GRCz11/seq/GCF_000002035.6_GRCz11_genomic.fna.fai" + fasta = "${params.igenomes_base}/Drerio/GRCz11/seq/GCF_000002035.6_GRCz11_genomic.fna" + dict = "${params.igenomes_base}/Drerio/GRCz11/seq/GCF_000002035.6_GRCz11_genomic.dict" + gtf = "${params.igenomes_base}/Drerio/GRCz11/seq/GCF_000002035.6_GRCz11_genomic.gtf" // Aligner reference - bowtie2 = "${params.igenomes_base}/Drerio/GRCz11/bowtie2" - bwamem = "${params.igenomes_base}/Drerio/GRCz11/bwa" - bwamem2 = "${params.igenomes_base}/Drerio/GRCz11/bwamem2" - dragmap = "${params.igenomes_base}/Drerio/GRCz11/dragmap" - snap = "${params.igenomes_base}/Drerio/GRCz11/snapaligner" - star = "${params.igenomes_base}/Drerio/GRCz11/star" + bowtie2 = "${params.igenomes_base}/Drerio/GRCz11/bowtie2" + bwamem = "${params.igenomes_base}/Drerio/GRCz11/bwa" + bwamem2 = "${params.igenomes_base}/Drerio/GRCz11/bwamem2" + dragmap = "${params.igenomes_base}/Drerio/GRCz11/dragmap" + snap = "${params.igenomes_base}/Drerio/GRCz11/snapaligner" + star = "${params.igenomes_base}/Drerio/GRCz11/star" } // Legacy bcbio references - "hg38" { - fai = "${params.igenomes_base}/Hsapiens/hg38/seq/hg38.fa.fai" - fasta = "${params.igenomes_base}/Hsapiens/hg38/seq/hg38.fa" - dict = "${params.igenomes_base}/Hsapiens/hg38/seq/hg38.dict" - gtf = "${params.igenomes_base}/Hsapiens/hg38/seq/hg38.gtf" + hg38 { + fai = "${params.igenomes_base}/Hsapiens/hg38/seq/hg38.fa.fai" + fasta = "${params.igenomes_base}/Hsapiens/hg38/seq/hg38.fa" + dict = "${params.igenomes_base}/Hsapiens/hg38/seq/hg38.dict" + gtf = "${params.igenomes_base}/Hsapiens/hg38/seq/hg38.gtf" - bowtie2 = "${params.igenomes_base}/Hsapiens/hg38/bowtie2" - bwamem = "${params.igenomes_base}/Hsapiens/hg38/bwa" - bwamem2 = "${params.igenomes_base}/Hsapiens/hg38/bwamem2" - dragmap = "${params.igenomes_base}/Hsapiens/hg38/dragmap" - snap = "${params.igenomes_base}/Hsapiens/hg38/snapaligner" - star = "${params.igenomes_base}/Hsapiens/hg38/star" + bowtie2 = "${params.igenomes_base}/Hsapiens/hg38/bowtie2" + bwamem = "${params.igenomes_base}/Hsapiens/hg38/bwa" + bwamem2 = "${params.igenomes_base}/Hsapiens/hg38/bwamem2" + dragmap = "${params.igenomes_base}/Hsapiens/hg38/dragmap" + snap = "${params.igenomes_base}/Hsapiens/hg38/snapaligner" + star = "${params.igenomes_base}/Hsapiens/hg38/star" } - "hg38-noalt" { - fai = "${params.igenomes_base}/Hsapiens/hg38-noalt/seq/hg38-noalt.fa.fai" - fasta = "${params.igenomes_base}/Hsapiens/hg38-noalt/seq/hg38-noalt.fa" - dict = "${params.igenomes_base}/Hsapiens/hg38-noalt/seq/hg38-noalt.dict" - gtf = "${params.igenomes_base}/Hsapiens/hg38-noalt/seq/hg38-noalt.gtf" + 'hg38-noalt' { + fai = "${params.igenomes_base}/Hsapiens/hg38-noalt/seq/hg38-noalt.fa.fai" + fasta = "${params.igenomes_base}/Hsapiens/hg38-noalt/seq/hg38-noalt.fa" + dict = "${params.igenomes_base}/Hsapiens/hg38-noalt/seq/hg38-noalt.dict" + gtf = "${params.igenomes_base}/Hsapiens/hg38-noalt/seq/hg38-noalt.gtf" - bowtie2 = "${params.igenomes_base}/Hsapiens/hg38-noalt/bowtie2" - bwamem = "${params.igenomes_base}/Hsapiens/hg38-noalt/bwa" - bwamem2 = "${params.igenomes_base}/Hsapiens/hg38-noalt/bwamem2" - dragmap = "${params.igenomes_base}/Hsapiens/hg38-noalt/dragmap" - snap = "${params.igenomes_base}/Hsapiens/hg38-noalt/snapaligner" - star = "${params.igenomes_base}/Hsapiens/hg38-noalt/star" + bowtie2 = "${params.igenomes_base}/Hsapiens/hg38-noalt/bowtie2" + bwamem = "${params.igenomes_base}/Hsapiens/hg38-noalt/bwa" + bwamem2 = "${params.igenomes_base}/Hsapiens/hg38-noalt/bwamem2" + dragmap = "${params.igenomes_base}/Hsapiens/hg38-noalt/dragmap" + snap = "${params.igenomes_base}/Hsapiens/hg38-noalt/snapaligner" + star = "${params.igenomes_base}/Hsapiens/hg38-noalt/star" } } } - diff --git a/conf/modules.config b/conf/modules.config index 3def8896..becf78e8 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -12,94 +12,34 @@ process { - publishDir = [ - path: { meta.samplename ? "${params.outdir}/${meta.samplename}" : "${params.outdir}"}, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals("versions.yml") ? null : filename } - ] - // BCL convert - withName: BCLCONVERT { - ext.args = {[ - meta.lane ? "--bcl-only-lane ${meta.lane}" : "", - "--force", - "--bcl-num-parallel-tiles ${task.cpus}", - "--bcl-num-conversion-threads ${task.cpus}", - "--bcl-num-compression-threads ${task.cpus}", - ].join(" ").trim()} - publishDir = [ - [ - // Gather and write InterOp files - path: { "${params.outdir}/InterOp" }, - mode: params.publish_dir_mode, - overwrite: true, - pattern: "**.bin", - saveAs: {filename -> filename.split("/")[-1] } - ], - [ - // Fetch RunInfo.xml - path: { meta.lane ? "${params.outdir}/Reports/L00${meta.lane}" : "${params.outdir}/Reports/" }, - mode: params.publish_dir_mode, - pattern: "RunInfo.xml", - overwrite: true, - saveAs: {filename -> filename.split("/")[-1] } - ], - [ - // Gather and write Reports - path: { meta.lane ? "${params.outdir}/Reports/L00${meta.lane}" : "${params.outdir}/Reports/" }, - mode: params.publish_dir_mode, - pattern: "Reports", - overwrite: true, - saveAs: {filename -> filename.split("/")[-1] } - ], + withName: '.*BCLCONVERT' { + cpus = 16 + memory = { 64.GB * task.attempt } + ext.args = { [ - // Gather and write Logs - path: { meta.lane ? "${params.outdir}/Logs/L00${meta.lane}" : "${params.outdir}/Logs/" }, - mode: params.publish_dir_mode, - pattern: "Logs", - overwrite: true, - saveAs: {filename -> filename.split("/")[-1] } - ], - [ - // don't write the fastq's - pattern: "**.fastq.gz", - enabled: false - ] - ] + meta.lane ? "--bcl-only-lane ${meta.lane}" : "", + "--force", + "--strict-mode true", + ].join(" ").trim() + } } // FastP - withName: FASTP { - ext.args = {[ - meta.single_end && reads.size() > 5000000000 ? "--split_by_lines 400000000": "", - !meta.single_end && reads.any{ f -> f.size() > 5000000000 } ? "--split_by_lines 400000000": "", - params.skip_trimming ? "--disable_adapter_trimming" : "--detect_adapter_for_pe", - params.trim_front > 0 ? "--trim_front1 ${params.trim_front}" : "", - params.trim_tail > 0 ? "--trim_tail1 ${params.trim_tail}" : "", - params.adapter_R1 ? "--adapter_sequence ${params.adapter_R1}" : "", - params.adapter_R2 ? "--adapter_sequence_r2 ${params.adapter_R2}" : "", - "--compression 1" - ].join(" ").trim()} - publishDir = [ + withName: '.*FASTP' { + cpus = 4 + memory = { 4.GB * task.attempt } + ext.args = { [ - path: { "${params.outdir}/${meta.samplename}" }, - mode: params.publish_dir_mode, - pattern: "*.{html,json}" - ], - ] - } - - // FASTQ_TO_UCRAM - //// Samtools Import - withName: ".*FASTQ_TO_UCRAM:SAMTOOLS_IMPORT" { - label = "process_medium" - // WARNING: Do NOT escape the RG tag tabs when adding a readgroup - ext.args = {[ - meta.readgroup ? "--rg-line \"@RG\t" + meta.readgroup.findResults{ it.value?.trim() ? "$it.key:$it.value" : null }.join("\t") + "\"" : "", - "--output-fmt cram", - "--output-fmt-option archive" - ].join(" ").trim()} - publishDir = [ enabled: false ] + params.split_fastq > 0 ? "--split_by_lines ${params.split_fastq * 4}" : '', + meta.skip_trimming ? "--disable_adapter_trimming" : "--detect_adapter_for_pe", + meta.trim_front > 0 ? "--trim_front1 ${meta.trim_front}" : "", + meta.trim_tail > 0 ? "--trim_tail1 ${meta.trim_tail}" : "", + meta.adapter_R1 ? "--adapter_sequence ${meta.adapter_R1}" : "", + meta.adapter_R2 ? "--adapter_sequence_r2 ${meta.adapter_R2}" : "", + "--compression 1", + ].join(" ").trim() + } } // FASTQ_TO_CRAM @@ -113,46 +53,45 @@ process { // LB : library prep // SM : samplename - - // FASTQ_ALIGN_DNA - withName:".*:FASTQ_ALIGN_DNA:.*" { - publishDir = [ enabled: false ] - } - //// Bowtie2 - withName: BOWTIE2_ALIGN { - ext.args = {[ - "--local", - "--fast-local", - meta.readgroup ? "--rg-id ${meta.readgroup.ID}": "", - meta.readgroup ? "--rg " + meta.readgroup.findResults{ it.value?.trim() ? "$it.key:$it.value" : null }.join(" --rg ") : "" - ].join(" ").trim()} + withName: '.*FASTQ_ALIGN_DNA:BOWTIE2_ALIGN' { + cpus = 16 + memory = 32.GB + ext.args = { + [ + "--local", + "--fast-local", + meta.readgroup ? "--rg-id ${meta.readgroup.ID}" : "", + meta.readgroup ? "--rg " + meta.readgroup.findResults { rg -> rg.value?.trim() ? "${rg.key}:${rg.value}" : null }.join(" --rg ") : "", + ].join(" ").trim() + } ext.args2 = "--fast" - publishDir = [ - path: { meta.samplename ? "${params.outdir}/${meta.samplename}" : "${params.outdir}"}, - mode: params.publish_dir_mode, - pattern: "*.log" - ] } //// BWA mem/BWA mem2 - withName: "BWAMEM.*_MEM" { - ext.args = {[ - "-K 100000000", - "-p", - "-v 3", - "-Y", - "-c 250", - meta.readgroup ? "-R \"@RG\\t" + meta.readgroup.findResults{ it.value?.trim() ? "$it.key:$it.value" : null }.join("\\t") + "\"" : "" - ].join(" ").trim()} + withName: '.*FASTQ_ALIGN_DNA:BWAMEM.*_MEM' { + cpus = 16 + memory = 32.GB + ext.args = { + [ + "-K 100000000", + "-p", + "-v 3", + "-Y", + "-c 250", + meta.readgroup ? "-R \"@RG\\t" + meta.readgroup.findResults { rg -> rg.value?.trim() ? "${rg.key}:${rg.value}" : null }.join("\\t") + "\"" : "", + ].join(" ").trim() + } ext.args2 = "--fast" } //// DRAGEN - withName: DRAGMAP_ALIGN { - ext.args = {[ - meta.readgroup ? "--RGSM \"@RG\\t" + meta.readgroup.findResults{ it.value?.trim() ? "$it.key:$it.value" : null }.join("\\t") + "\"" : "" - ].join(" ").trim()} + withName: '.*FASTQ_ALIGN_DNA:DRAGMAP_ALIGN' { + cpus = 16 + memory = 32.GB + ext.args = { + [meta.readgroup ? "--RGSM \"@RG\\t" + meta.readgroup.findResults { rg -> rg.value?.trim() ? "${rg.key}:${rg.value}" : null }.join("\\t") + "\"" : ""].join(" ").trim() + } ext.args2 = "--fast" } @@ -165,194 +104,196 @@ process { // -xf 2 : expansion factor for reading compressed data //// SNAP - withName: SNAP_ALIGN { - ext.args = {[ - "-b-", - "-sm 20", - "-I", - "-hc-", - "-S id", - "-sa", - "-xf 2", - meta.readgroup ? "-R \"@RG\\t" + meta.readgroup.findResults{ it.value?.trim() ? "$it.key:$it.value" : null }.join("\\t") + "\"" : "" - ].join(" ").trim()} + withName: '.*FASTQ_ALIGN_DNA:SNAP_ALIGN' { + cpus = 16 + memory = 64.GB + ext.args = { + [ + "-b-", + "-sm 20", + "-I", + "-hc-", + "-S id", + "-sa", + "-xf 2", + meta.readgroup ? "-R \"@RG\\t" + meta.readgroup.findResults { rg -> rg.value?.trim() ? "${rg.key}:${rg.value}" : null }.join("\\t") + "\"" : "", + ].join(" ").trim() + } } - // FASTQ_ALIGN_RNA - withName:".*FASTQ_ALIGN_RNA:.*" { - publishDir = [ enabled: false ] + //// STROBEALIGN + withName: '.*FASTQ_ALIGN_DNA:STROBEALIGN' { + cpus = 16 + memory = 32.GB + ext.args = { + [ + meta.readgroup ? "--rg-id ${meta.readgroup.ID}" : "", + meta.readgroup ? "--rg " + meta.readgroup.findResults { rg -> rg.value?.trim() ? "${rg.key}:${rg.value}" : null }.join(" --rg ") : "", + "-C", + ].join(" ").trim() + } } - withName: STAR_ALIGN { - ext.args = {[ - // support compressed inputs - "--readFilesCommand gunzip -c", - // basic 2-pass mapping, with all 1st pass junctions inserted into the genome indices on the fly - "--twopassMode Basic", - // output unsorted BAM - "--outSAMtype BAM Unsorted", - // output unmapped reads in the unsorted bam file - "--outSAMunmapped Within", - // output all the fields in the SAM format - "--outSAMattributes All", - // the minimum mapped length of two segments in a chimeric alignment - "--chimSegmentMin 20", - // alignment will be output only if it has no more mismatches than this value. - "--outFilterMismatchNmax 4", - // set the readgroup info, if available. Flag arg MUST start with 'ID' tag - meta.readgroup ? "--outSAMattrRGline \"ID:${meta.readgroup.ID}" + meta.readgroup.findResults{ it.value?.trim() && it.key != "ID" ? "$it.key:$it.value" : null }.join(" ") + "\"" : "" - ].join(" ").trim()} + //// STAR + withName: '.*FASTQ_ALIGN_RNA:STAR_ALIGN' { + ext.prefix = { "${meta.id}.star" } + cpus = 16 + memory = 64.GB + ext.args = { + [ + "--readFilesCommand gunzip -c", + "--twopassMode Basic", + "--outSAMtype BAM Unsorted", + "--outSAMunmapped Within", + "--outSAMattributes All", + "--chimSegmentMin 20", + "--outFilterMismatchNmax 4", + meta.readgroup ? "--outSAMattrRGline \"ID:${meta.readgroup.ID}" + meta.readgroup.findResults { rg -> rg.value?.trim() && rg.key != "ID" ? "${rg.key}:${rg.value}" : null }.join(" ") + "\"" : "", + ].join(" ").trim() + } } + withName: '.*FASTQ_ALIGN_RNA:SORT_MERGE_SPLICE_JUNCTIONS' { + cpus = 1 + ext.prefix = { "${meta.id}.SJ.out" } + ext.suffix = "tab" + ext.args = '-k1,1n -k2,2n -k3,3n --merge' + } + + withName: '.*FASTQ_ALIGN_RNA:SORT_MERGE_JUNCTIONS' { + cpus = 1 + ext.prefix = { "${meta.id}.Chimeric.out" } + ext.suffix = "junction" + ext.args = '-k1,1n -k2,2n -k4,4n -k5,5n --merge' + } //// Samtools sormadup - withName: ".*FASTQ_TO_CRAM:SAMTOOLS_SORMADUP" { - ext.prefix = {"${meta.id}.merged"} - ext.args5 = {[ - "-s", // print some stats - "--json", // output stats in json format for MultiQC - "-d 2500", // The optical duplicate distance - params.umi_aware ? "--barcode-name" : "", // Use the UMI/barcode embedded in the read name (eigth colon delimited part). - "--write-index", // Write csi/crai index - "--output-fmt cram", // Output format - "--output-fmt-option archive" // Cram compression level - ].join(" ").trim()} - publishDir = [ - [ - path: { "${params.outdir}/${meta.samplename}" }, - mode: params.publish_dir_mode, - pattern: "*metrics*", - saveAs: {filename -> filename.replace("metrics", "duplicate_metrics").replace(".merged","")} - ], + withName: '.*FASTQ_TO_CRAM:SAMTOOLS_SORMADUP' { + cpus = 16 + memory = 64.GB + ext.prefix = { "${meta.id}.merged" } + ext.args = "--verbosity 5" + ext.args2 = "--verbosity 5" + ext.args3 = "--verbosity 5" + ext.args4 = "--verbosity 5" + ext.args5 = { [ - path: { "${params.outdir}/${meta.samplename}" }, - mode: params.publish_dir_mode, - pattern: "*cram*", - saveAs: {filename -> filename.replace(".merged", "")} - ], - ] + "--verbosity 5", + "-s", + "--json", + "-d 2500", + meta.umi_aware ? "--barcode-name" : "", + "--write-index", + "--output-fmt cram,version=3.0", + "--output-fmt-option archive", + ].join(" ").trim() + } } //// Samtools multisort - withName: ".*FASTQ_TO_CRAM:SAMTOOLS_SORT" { - ext.prefix = {"${meta.id}.merged"} - ext.args = {[ - "--write-index", - "--output-fmt cram", - "--output-fmt-option archive" - ].join(" ").trim()} - publishDir = [ + withName: '.*FASTQ_TO_CRAM:SAMTOOLS_SORT' { + cpus = 16 + memory = 64.GB + ext.prefix = { "${meta.id}.merged" } + ext.args = { [ - path: { "${params.outdir}/${meta.samplename}" }, - mode: params.publish_dir_mode, - pattern: "*cram*", - saveAs: {filename -> filename.replace(".merged", "")} - ], - ] + "--write-index", + "--output-fmt cram,version=3.0", + "--output-fmt-option archive", + ].join(" ").trim() + } } //// BioBamBam Bamsormadup - withName: ".*FASTQ_TO_CRAM:BIOBAMBAM_BAMSORMADUP" { - ext.prefix = {"${meta.id}.merged"} - ext.args = {[ - "indexfilename=${meta.id}.merged.bam.bai", - "optminpixeldif=2500" - ].join(" ").trim()} - ext.args2 = "exclude=QCFAIL" - publishDir = [ + withName: '.*FASTQ_TO_CRAM:BIOBAMBAM_BAMSORMADUP' { + cpus = 8 + memory = 16.GB + ext.prefix = { "${meta.id}.merged" } + ext.args = { [ - path: { "${params.outdir}/${meta.samplename}" }, - mode: params.publish_dir_mode, - pattern: "*metrics*", - saveAs: {filename -> filename.replace("metrics", "duplicate_metrics").replace(".merged","")} - ] - ] + "indexfilename=${meta.id}.merged.bam.bai", + "optminpixeldif=2500", + ].join(" ").trim() + } + ext.args2 = "exclude=QCFAIL" } //// Samtools convert - withName: ".*FASTQ_TO_CRAM:SAMTOOLS_CONVERT" { - cpus = 8 - memory = 64.GB - ext.args = {[ - "-C", - "--output-fmt cram", - "--output-fmt-option archive" - ].join(" ").trim()} - publishDir = [ + withName: '.*FASTQ_TO_CRAM:SAMTOOLS_CONVERT' { + cpus = 8 + memory = 8.GB + ext.args = { [ - path: { "${params.outdir}/${meta.samplename}" }, - mode: params.publish_dir_mode, - pattern: "*cram*", - saveAs: {filename -> filename.replace(".merged", "")} - ], - ] + "-C", + "--output-fmt cram,version=3.0", + "--output-fmt-option archive", + ].join(" ").trim() + } } // coverage //// Mosdepth - withName: ".*COVERAGE:MOSDEPTH" { - cpus = 4 - memory = { 4.GB * task.attempt } - // filter reads with flag 1804 - // read unmapped (0x4) - // mate unmapped (0x8)* - // not primary alignment (0x100) - // read fails platform/vendor quality checks (0x200) - // read is PCR or optical duplicate (0x400) - // filter reads with MAPQ < 1 - // quantize coverage to 4 bins + withName: '.*COVERAGE:MOSDEPTH' { + cpus = 4 + memory = { 4.GB * task.attempt } ext.args = [ "--flag 1804", "--mapq 1", - "--quantize 0:1:4:" + "--quantize 0:1:4:", ].join(" ").trim() } //// Samtools coverage - withName: ".*:COVERAGE:SAMTOOLS_COVERAGE" { - ext.prefix = {"${meta.id}.coverage"} - } - - //// CoverageQC (Multiqc) - // withName: ".*:COVERAGE:COVERAGEQC" { - // ext.args = { "--title \"Coverage ${meta.samplename ?: meta.id}\" } - // } - - // Checksums - withName: MD5SUM { - publishDir = [ - [ - path: { "${params.outdir}/${meta.samplename}" }, - mode: params.publish_dir_mode, - pattern: "*.md5", - saveAs: {filename -> filename.replace(".merged", "")} - ] - ] + withName: '.*COVERAGE:SAMTOOLS_COVERAGE' { + cpus = 1 + memory = 1.GB + ext.prefix = { "${meta.id}.coverage" } } // QC - withName: ".*BAM_QC.*" { - cpus = 1 + withName: '.*BAM_QC:SAMTOOLS_.*$' { + cpus = 1 + memory = 1.GB } //// Picard - withName: ".*PICARD.*" { - memory = { 8.GB * task.attempt } - ext.args = "--MAX_RECORDS_IN_RAM 15000000" + withName: '.*BAM_QC:PICARD_.*$' { + cpus = 1 + memory = { 16.GB * task.attempt } + ext.args = "--MAX_RECORDS_IN_RAM 50000000" } + withName: '.*MD5SUM' { + cpus = 1 + memory = 128.MB + } // MultiQC - withName: 'MULTIQC' { - ext.args = { params.multiqc_title ? "--title \"$params.multiqc_title\"" : '' } - publishDir = [ - path: { "${params.outdir}/multiqc" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } - ] + withName: '.*MULTIQCSAV' { + cpus = 1 + memory = 4.GB + ext.prefix = { params.multiqc_title ? "${params.multiqc_title}_SAV" : "${meta.id}_SAV" } + ext.args = { + [ + "--no-ai", + params.multiqc_title ? "--title \"${params.multiqc_title}\"" : "--title \"${meta.id}\"", + ].join(" ").trim() + } + } + withName: '.*MULTIQC' { + container = "cmgg/multiqc_cmgg:0.0.5-multiqc-v1.33" + cpus = 1 + memory = 4.GB + ext.prefix = { params.multiqc_title ? "${params.multiqc_title}_${meta.id}" : "${meta.id}" } + ext.args = { + [ + "--template \"cmgg\"", + "--no-ai", + params.multiqc_title ? "--title \"${params.multiqc_title} - ${meta.id}\"" : "--title \"${meta.id}\"", + ].join(" ").trim() + } } - } env { @@ -360,4 +301,7 @@ env { MOSDEPTH_Q0 = 'NO_COVERAGE' MOSDEPTH_Q1 = 'LOW_COVERAGE' MOSDEPTH_Q2 = 'CALLABLE' + + // Set TMPDIR for all modules + TMPDIR = "\$PWD" } diff --git a/conf/profiles/WES.config b/conf/profiles/WES.config deleted file mode 100644 index ea2298c4..00000000 --- a/conf/profiles/WES.config +++ /dev/null @@ -1,7 +0,0 @@ -params { - aligner = "snap" - run_coverage = true - disable_picard_metrics = false - roi = "${params.igenomes_base}/Hsapiens/GRCh38/regions/CMGG_WES_analysis_ROI_v6.bed" - genelists = "${params.igenomes_base}/Hsapiens/GRCh38/regions/genelists" -} diff --git a/conf/profiles/WGS.config b/conf/profiles/WGS.config deleted file mode 100644 index 39180f15..00000000 --- a/conf/profiles/WGS.config +++ /dev/null @@ -1,7 +0,0 @@ -params { - aligner = "snap" - markdup = "samtools" - umi_aware = true - run_coverage = true - disable_picard_metrics = false -} diff --git a/conf/profiles/copgt.config b/conf/profiles/copgt.config deleted file mode 100644 index 71ba2c69..00000000 --- a/conf/profiles/copgt.config +++ /dev/null @@ -1,14 +0,0 @@ -params { - aligner = "snap" - run_coverage = true - disable_picard_metrics = true - roi = "${params.igenomes_base}/Hsapiens/GRCh38/regions/CMGG_coPGT-M_analyses_ROI_v1.bed" - - // trimming options - skip_trimming = false - trim_front = 6 - adapter_R1 = "CAGATC" - - // markduplicates options - markdup = false -} diff --git a/conf/profiles/s3_ugent.config b/conf/profiles/s3_ugent.config deleted file mode 100644 index 12648118..00000000 --- a/conf/profiles/s3_ugent.config +++ /dev/null @@ -1,8 +0,0 @@ -aws { - client { - endpoint = "https://s3.ugent.be" - protocol = "https" - s3PathStyleAccess = true - connectionTimeout = 60000 - } -} diff --git a/conf/profiles/sWGS.config b/conf/profiles/sWGS.config deleted file mode 100644 index f34e5eb0..00000000 --- a/conf/profiles/sWGS.config +++ /dev/null @@ -1,6 +0,0 @@ -params { - aligner = "bowtie2" - run_coverage = false - disable_picard_metrics = true -} - diff --git a/conf/test.config b/conf/test.config index 4b9d390e..8b6c7486 100644 --- a/conf/test.config +++ b/conf/test.config @@ -15,25 +15,16 @@ params { config_profile_description = 'Minimal test dataset to check pipeline function' // Input data - input = "${projectDir}/tests/inputs/fastq.yml" - igenomes_base = "s3://reference-data/genomes" - aligner = "bwamem" + input = "${projectDir}/tests/inputs/test.yml" + igenomes_base = "s3://reference-data/genomes" } process { resourceLimits = [ cpus: 2, memory: 6.GB, - time: 6.h + time: 6.h, ] - - withName: BCLCONVERT { - ext.args = {[ - meta.lane ? "--bcl-only-lane ${meta.lane}" : "", - "--force", - "--first-tile-only true" - ].join(" ").trim()} - } } includeConfig "../tests/config/igenomes_test.config" diff --git a/conf/test_full.config b/conf/test_full.config index 07c5c697..bad1c6f1 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -17,8 +17,8 @@ params { // Input data for full size test // TODO nf-core: Specify the paths to your full test data ( on nf-core/test-datasets or directly in repositories, e.g. SRA) // TODO nf-core: Give any required params for the test so that command line flags are not needed - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_full_illumina_amplicon.csv' + input = params.pipelines_testdata_base_path + 'viralrecon/samplesheet/samplesheet_full_illumina_amplicon.csv' // Genome references - genome = 'R64-1-1' + genome = 'R64-1-1' } diff --git a/docs/images/metro_map.png b/docs/images/metro_map.png deleted file mode 100644 index f2057abd..00000000 Binary files a/docs/images/metro_map.png and /dev/null differ diff --git a/docs/images/metro_map.svg b/docs/images/metro_map.svg deleted file mode 100644 index cfd9b083..00000000 --- a/docs/images/metro_map.svg +++ /dev/null @@ -1,1263 +0,0 @@ - - - -nf-cmgg/preprocessingfastqflowcellfastqORfastqfastqbclbclbclbclbclFastP trimming,QC andadapterremovalAlignbowtie2, bwamem,bwamem2, snapdragmap or starcramMultiQCreportindexfastaORMandatory process(es)Supported genomes flowReport filesLegendsOptional process(es)Additional outputs/inputsUnsupported genomes flowCreate indexwhen index ismissing Sort & mark duplicatessamtools sormadup or bamsormadupsamtools convertbam -> crambedmosdepthsamtools importfastq -> ucramPicard metricspicard CollectMultipleMetrics,picard CollectWgsMetrics andpicard CollectHsMetrics--disable_picard_metrics falsesamtools metricssamtools stats,samtools flagstat andsamtools idxstatsucramreportsAll generatedreportssamtools catmerge ucramsfrom same samplebcl-convertbcl -> fastqinteropdetermine coveragein genelist panelssamtoolscoveragebed diff --git a/docs/images/metro_map_dark.md b/docs/images/metro_map_dark.md new file mode 100644 index 00000000..65349f39 --- /dev/null +++ b/docs/images/metro_map_dark.md @@ -0,0 +1,45 @@ +```mermaid +%%metro logo: ./nf-cmgg-preprocessing_logo_dark.png +%%metro style: dark +%%metro line: main | Alignment and Postprocessing | #00ff00 +%%metro line: qc | Quality control | #ff0000 +%%metro file: BCL_IN | BCL +%%metro file: FASTQ_IN | FASTQ +%%metro file: CRAM_OUT | CRAM +%%metro file: MULTIQC_LIBRARY | HTML +%%metro file: MULTIQC_SAV | HTML +%%metro compact_offsets: true + +graph TD + + BCL_IN[] + FASTQ_IN[] + MULTIQC_SAV[] + CRAM_OUT[] + MULTIQC_LIBRARY[] + + BCL_IN -->|main | BCLCONVERT + BCL_IN -->|qc| MULTIQC_SAV + BCLCONVERT -->|qc| MULTIQC_SAV + + FASTQ_IN[] + FASTQ_IN -->|qc,main| FASTP + BCLCONVERT -->|qc| FALCO + BCLCONVERT -->|qc,main| FASTP + FALCO -->|qc| MULTIQC_LIBRARY + FASTP -->|qc| MULTIQC_LIBRARY + + FASTP -->|main| ALIGN + ALIGN -->|main| MARKDUP + MARKDUP -->|main| CRAM_OUT + + CRAM_OUT -->|qc| MOSDEPTH + CRAM_OUT -->|qc| SAMTOOLS_COV + MOSDEPTH -->|qc| MULTIQC_LIBRARY + SAMTOOLS_COV -->|qc| MULTIQC_LIBRARY + + CRAM_OUT -->|qc| SAMTOOLS_QC + CRAM_OUT -->|qc| PICARD + SAMTOOLS_QC -->|qc| MULTIQC_LIBRARY + PICARD -->|qc| MULTIQC_LIBRARY +``` diff --git a/docs/images/metro_map_dark.svg b/docs/images/metro_map_dark.svg new file mode 100644 index 00000000..0f452bc5 --- /dev/null +++ b/docs/images/metro_map_dark.svg @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +BCL + + + + + +HTML + + + + +FASTQ + + + + + + +HTML + + + + + + +CRAM + + + + +BCL_IN +FASTQ_IN +BCLCONVERT +MULTIQC_SAV +FASTP +FALCO +ALIGN +MARKDUP +CRAM_OUT +MOSDEPTH +SAMTOOLS_COV +SAMTOOLS_QC +PICARD +MULTIQC_LIBRARY + + + +Alignment and Postprocessing + +Quality control +created with nf-metro v0.5.4 + diff --git a/docs/images/metro_map_light.md b/docs/images/metro_map_light.md new file mode 100644 index 00000000..5cd6a5b0 --- /dev/null +++ b/docs/images/metro_map_light.md @@ -0,0 +1,45 @@ +```mermaid +%%metro logo: ./nf-cmgg-preprocessing_logo_light.png +%%metro style: light +%%metro line: main | Alignment and Postprocessing | #00ff00 +%%metro line: qc | Quality control | #ff0000 +%%metro file: BCL_IN | BCL +%%metro file: FASTQ_IN | FASTQ +%%metro file: CRAM_OUT | CRAM +%%metro file: MULTIQC_LIBRARY | HTML +%%metro file: MULTIQC_SAV | HTML +%%metro compact_offsets: true + +graph TD + + BCL_IN[] + FASTQ_IN[] + MULTIQC_SAV[] + CRAM_OUT[] + MULTIQC_LIBRARY[] + + BCL_IN -->|main | BCLCONVERT + BCL_IN -->|qc| MULTIQC_SAV + BCLCONVERT -->|qc| MULTIQC_SAV + + FASTQ_IN[] + FASTQ_IN -->|qc,main| FASTP + BCLCONVERT -->|qc| FALCO + BCLCONVERT -->|qc,main| FASTP + FALCO -->|qc| MULTIQC_LIBRARY + FASTP -->|qc| MULTIQC_LIBRARY + + FASTP -->|main| ALIGN + ALIGN -->|main| MARKDUP + MARKDUP -->|main| CRAM_OUT + + CRAM_OUT -->|qc| MOSDEPTH + CRAM_OUT -->|qc| SAMTOOLS_COV + MOSDEPTH -->|qc| MULTIQC_LIBRARY + SAMTOOLS_COV -->|qc| MULTIQC_LIBRARY + + CRAM_OUT -->|qc| SAMTOOLS_QC + CRAM_OUT -->|qc| PICARD + SAMTOOLS_QC -->|qc| MULTIQC_LIBRARY + PICARD -->|qc| MULTIQC_LIBRARY +``` diff --git a/docs/images/metro_map_light.svg b/docs/images/metro_map_light.svg new file mode 100644 index 00000000..ac3be697 --- /dev/null +++ b/docs/images/metro_map_light.svg @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +BCL + + + + + +HTML + + + + +FASTQ + + + + + + +HTML + + + + + + +CRAM + + + + +BCL_IN +FASTQ_IN +BCLCONVERT +MULTIQC_SAV +FASTP +FALCO +ALIGN +MARKDUP +CRAM_OUT +MOSDEPTH +SAMTOOLS_COV +SAMTOOLS_QC +PICARD +MULTIQC_LIBRARY + + + +Alignment and Postprocessing + +Quality control +created with nf-metro v0.5.4 + diff --git a/docs/images/nf-cmgg-preprocessing_logo_dark.png b/docs/images/nf-cmgg-preprocessing_logo_dark.png index 2f4bd13f..d91e6379 100644 Binary files a/docs/images/nf-cmgg-preprocessing_logo_dark.png and b/docs/images/nf-cmgg-preprocessing_logo_dark.png differ diff --git a/docs/images/nf-cmgg-preprocessing_logo_dark.svg b/docs/images/nf-cmgg-preprocessing_logo_dark.svg index 4fc66fb4..dd5620b1 100644 --- a/docs/images/nf-cmgg-preprocessing_logo_dark.svg +++ b/docs/images/nf-cmgg-preprocessing_logo_dark.svg @@ -5,7 +5,7 @@ width="1456.784" height="522.443" version="1.1" - sodipodi:docname="nf-core-preprocessing_logo_dark.svg" + sodipodi:docname="nf-cmgg-preprocessing_logo_dark.svg" inkscape:version="1.2 (dc2aeda, 2022-05-15)" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" @@ -54,7 +54,7 @@ id="path9" d="m280.17 136.33-21.5-21.584h61v21.584z" />.st0{fill:#24af63}.st1{font-family:Arial, Helvetica, sans-serif;;font-weight:"bold"}.st2{font-size:209.8672px}.st4{fill:#ecdc86}.st7{fill:#396e35}nf-nf-cmgg/preprocessingpreproc.st0{fill:#24af63}.st1{font-family:Arial, Helvetica, sans-serif;font-weight:bold;}.st2{font-size:209.8672px}.st4{fill:#ecdc86}.st7{fill:#396e35}nf-nf-cmgg/preprocessingpreproc Output files - `SAMPLE` - `SAMPLE.CollectHsMetrics.coverage_metrics`: The coverage metrics calculated by `picard CollectHsMetrics` - - `SAMPLE.CollectMultipleMetrics.alignment_summary_metrics`: The alignment summary metrics calculated by `picard CollectMultipleMEtrics` + - `SAMPLE.CollectMultipleMetrics.alignment_summary_metrics`: The alignment summary metrics calculated by `picard CollectMultipleMetrics` - `SAMPLE.CollectMultipleMetrics.base_distribution_by_cycle_metrics`: The base distribution by cycle metrics calculated by `picard CollectMultipleMetrics` - `SAMPLE.CollectMultipleMetrics.base_distribution_by_cycle.pdf`: PDF file containing the base distribution by cycle metrics - `SAMPLE.CollectMultipleMetrics.quality_by_cycle_metrics`: The quality by cycle metrics calculated by `picard CollectMultipleMetrics` - `SAMPLE.CollectMultipleMetrics.quality_by_cycle.pdf`: PDF file containing the quality by cycle metrics - `SAMPLE.CollectMultipleMetrics.quality_distribution_metrics`: The quality by distribution metrics calculated by `picard CollectMultipleMetrics` - `SAMPLE.CollectMultipleMetrics.quality_distribution.pdf`: PDF file containing the quality distribution metrics - - `SAMPLE.CollectMultipleMetrics.read_length_histogram.pdf`: A histogram detailing the read lenghts made with `picard CollectMultipleMetrics` + - `SAMPLE.CollectMultipleMetrics.read_length_histogram.pdf`: A histogram detailing the read lengths made with `picard CollectMultipleMetrics` - `SAMPLE.coverage.txt`: The coverage metrics calculated by `samtools coverage` - `SAMPLE.cram`: The CRAM file generated by the aligner - `SAMPLE.cram.crai`: The index of the CRAM file - `SAMPLE.cram.md5`: The md5sum of the CRAM file - - `SAMPLE.duplicate_metrics.txt`: The duplicate metrics calculated by `samtools mardup` + - `SAMPLE.duplicate_metrics.txt`: The duplicate metrics calculated by `samtools markdup` - `SAMPLE.fastp.html`: The HTML file visualising the metrics calculated by `fastp` - `SAMPLE.fastp.json`: The JSON file containing the metrics calculated by `fastp` - `SAMPLE.flagstat`: The quality control metrics calculated by `samtools flagstat` @@ -44,6 +44,7 @@ A separate directory will be created in the output directory for each sample con - `SAMPLE.regions.bed.gz`: The regional BED file, showing how well covered the requested regions are, calculated by `mosdepth` (only when a ROI BED file has been given) - `SAMPLE.regions.bed.gz.csi`: The index of the regional BED file - `SAMPLE.stats`: General statistics for the sample + - `multiqc/`: Directory containing the MultiQC report for the sample or library ### Extra outputs for flowcell inputs @@ -70,9 +71,9 @@ Some additional files will be created when a flowcell input has been used. -[MultiQC](http://multiqc.info) is a visualization tool that generates a single HTML report summarising all samples in your project. Most of the pipeline QC results are visualised in the report and further statistics are available in the report data directory. +[MultiQC](https://seqera.io/multiqc/) is a visualization tool that generates a single HTML report summarising all samples in your project. Most of the pipeline QC results are visualised in the report and further statistics are available in the report data directory. -Results generated by MultiQC collate pipeline QC from supported tools e.g. FastQC. The pipeline has special steps which also allow the software versions to be reported in the MultiQC output for future traceability. For more information about how to use MultiQC reports, see . +Results generated by MultiQC collate pipeline QC from supported tools e.g. FastQC. The pipeline has special steps which also allow the software versions to be reported in the MultiQC output for future traceability. For more information about how to use MultiQC reports, see . ### Pipeline information @@ -80,10 +81,8 @@ Results generated by MultiQC collate pipeline QC from supported tools e.g. FastQ Output files - `pipeline_info/` - - Reports generated by Nextflow: `execution_report.html`, `execution_timeline.html`, `execution_trace.txt` and `pipeline_dag.dot`/`pipeline_dag.svg`. - - Reports generated by the pipeline: `pipeline_report.html`, `pipeline_report.txt` and `software_versions.yml`. The `pipeline_report*` files will only be present if the `--email` / `--email_on_fail` parameter's are used when running the pipeline. - - Reformatted samplesheet files used as input to the pipeline: `samplesheet.valid.csv`. - - Parameters used by the pipeline run: `params.json`. + - Reports generated by Nextflow: `execution_report.html`, `execution_timeline.html`, `execution_trace.txt` and `pipeline_dag.mmd`. + - Reports generated by the pipeline: `pipeline_report.html`, `pipeline_report.txt` and `software_versions.yml`. The `pipeline_report*` files will only be present if the `--email` / `--email_on_fail` parameters are used when running the pipeline. diff --git a/docs/parameters.md b/docs/parameters.md index ba546b9b..0f7220fc 100644 --- a/docs/parameters.md +++ b/docs/parameters.md @@ -12,51 +12,50 @@ Define where the pipeline should find input data and save output data. | `outdir` | The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure. | `string` | | True | | | `email` | Email address for completion summary.
HelpSet this parameter to your e-mail address to get a summary e-mail with details of the run sent to you when the workflow exits. If set in your user config file (`~/.nextflow/config`) then you don't need to specify this on the command line for every run.
| `` | | | | | `multiqc_title` | MultiQC report title. Printed as page header, used for filename if not otherwise specified. | `string` | | | | +| `genomes` | | `object` | | | True | ## Pipeline options -| Parameter | Description | Type | Default | Required | Hidden | -| ------------------------ | ----------------------------------------------------------------------- | --------- | ----------- | -------- | ------ | -| `aligner` | Which aligner to use | `string` | bowtie2 | True | | -| `markdup` | Which alignment postprocessor to use | `string` | bamsormadup | | | -| `run_coverage` | Run coverage analysis steps | `boolean` | True | | | -| `skip_trimming` | Skip adapter trimming | `boolean` | False | | | -| `trim_front` | Number of bases to trim from the front of the read | `integer` | 0 | | | -| `trim_tail` | Number of bases to trim from the tail of the read | `integer` | 0 | | | -| `adapter_R1` | Adapter sequence to be trimmed | `string` | None | | | -| `adapter_R2` | Adapter sequence to be trimmed | `string` | None | | | -| `disable_picard_metrics` | Disable the calculation of (slow) Picard metrics | `boolean` | False | | | -| `roi` | Region of interest for coverage analysis to be applied to all samples | `string` | None | | | -| `genelists` | Directory containing gene list bed files for granular coverage analysis | `string` | None | | | +| Parameter | Description | Type | Default | Required | Hidden | +| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | --------- | -------- | ------ | +| `split_fastq` | Specify how many reads each split of a FastQ file contains. Set 0 to turn off splitting at all.
HelpUse the tool FastP to split FASTQ file by number of reads. This parallelizes across fastq file shards speeding up mapping. Note although the minimum value is 250 reads, if you have fewer than 250 reads a single FASTQ shard will still be created.
| `integer` | 100000000 | | | +| `genelists` | Directory containing gene list bed files for granular coverage analysis | `string` | None | | | ## Institutional config options Parameters used to describe centralised config profiles. These should not be edited. -| Parameter | Description | Type | Default | Required | Hidden | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------- | -------- | ------ | -| `custom_config_version` | Git commit id for Institutional configs. | `string` | master | | True | -| `custom_config_base` | Base directory for Institutional configs.
HelpIf you're running offline, Nextflow will not be able to fetch the institutional config files from the internet. If you don't need them, then this is not a problem. If you do need them, you should download the files from the repo and tell Nextflow where to find them with this parameter.
| `string` | https://raw.githubusercontent.com/nf-core/configs/master | | True | -| `config_profile_name` | Institutional config name. | `string` | | | True | -| `config_profile_description` | Institutional config description. | `string` | | | True | -| `config_profile_contact` | Institutional config contact information. | `string` | | | True | -| `config_profile_url` | Institutional config URL link. | `string` | | | True | +| Parameter | Description | Type | Default | Required | Hidden | +| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------ | -------- | ------ | +| `custom_config_version` | Git commit id for Institutional configs. | `string` | main | | True | +| `custom_config_base` | Base directory for custom configs.
HelpIf you're running offline, Nextflow will not be able to fetch the custom config files from the internet. If you don't need them, then this is not a problem. If you do need them, you should download the files from the repo and tell Nextflow where to find them with this parameter.
| `string` | https://raw.githubusercontent.com/nf-cmgg/configs/main | | True | +| `config_profile_name` | Institutional config name. | `string` | | | True | +| `config_profile_description` | Institutional config description. | `string` | | | True | +| `config_profile_contact` | Institutional config contact information. | `string` | | | True | +| `config_profile_url` | Institutional config URL link. | `string` | | | True | ## Generic options Less common options for the pipeline, typically set in a config file. -| Parameter | Description | Type | Default | Required | Hidden | -| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------- | ------- | -------- | ------ | -| `help` | Display help text. | `boolean` | | | True | -| `version` | Display version and exit. | `boolean` | | | True | -| `publish_dir_mode` | Method used to save pipeline results to output directory.
HelpThe Nextflow `publishDir` option specifies which intermediate files should be saved to the output directory. This option tells the pipeline what method should be used to move these files. See [Nextflow docs](https://www.nextflow.io/docs/latest/process.html#publishdir) for details.
| `string` | copy | | True | -| `email_on_fail` | Email address for completion summary, only when pipeline fails.
HelpAn email address to send a summary email to when the pipeline is completed - ONLY sent if the pipeline does not exit successfully.
| `string` | | | True | -| `plaintext_email` | Send plain-text email instead of HTML. | `boolean` | | | True | -| `max_multiqc_email_size` | File size limit when attaching MultiQC reports to summary emails. | `string` | 25.MB | | True | -| `monochrome_logs` | Do not use coloured log outputs. | `boolean` | | | True | -| `hook_url` | Incoming hook URL for messaging service
HelpIncoming hook URL for messaging service. Currently, MS Teams and Slack are supported.
| `string` | | | True | -| `multiqc_config` | Custom config file to supply to MultiQC. | `string` | | | True | -| `multiqc_logo` | Custom logo file to supply to MultiQC. File name must also be set in the MultiQC config file | `string` | | | True | -| `multiqc_methods_description` | Custom MultiQC yaml file containing HTML including a methods description. | `string` | | | | -| `validate_params` | Boolean whether to validate parameters against the schema at runtime | `boolean` | True | | True | +| Parameter | Description | Type | Default | Required | Hidden | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | -------------------------------------------------------- | -------- | ------ | +| `version` | Display version and exit. | `boolean` | | | True | +| `publish_dir_mode` | Method used to save pipeline results to output directory. (accepted: `symlink`\|`rellink`\|`link`\|`copy`\|`copyNoFollow`\|`move`)
HelpThe Nextflow `publishDir` option specifies which intermediate files should be saved to the output directory. This option tells the pipeline what method should be used to move these files. See [Nextflow docs](https://www.nextflow.io/docs/latest/process.html#publishdir) for details.
| `string` | copy | | True | +| `email_on_fail` | Email address for completion summary, only when pipeline fails.
HelpAn email address to send a summary email to when the pipeline is completed - ONLY sent if the pipeline does not exit successfully.
| `string` | | | True | +| `plaintext_email` | Send plain-text email instead of HTML. | `boolean` | | | True | +| `max_multiqc_email_size` | File size limit when attaching MultiQC reports to summary emails. | `string` | 25.MB | | True | +| `monochrome_logs` | Do not use coloured log outputs. | `boolean` | | | True | +| `hook_url` | Incoming hook URL for messaging service
HelpIncoming hook URL for messaging service. Currently, MS Teams and Slack are supported.
| `string` | | | True | +| `multiqc_config` | Custom config file to supply to MultiQC. | `string` | | | True | +| `multiqc_logo` | Custom logo file to supply to MultiQC. File name must also be set in the MultiQC config file | `string` | | | True | +| `multiqc_methods_description` | Custom MultiQC yaml file containing HTML including a methods description. | `string` | | | | +| `validate_params` | Boolean whether to validate parameters against the schema at runtime | `boolean` | True | | True | +| `pipelines_testdata_base_path` | Base URL or local path to location of pipeline test dataset files | `string` | https://raw.githubusercontent.com/nf-core/test-datasets/ | | True | +| `trace_report_suffix` | Suffix to add to the trace report filename. Default is the date and time in the format yyyy-MM-dd_HH-mm-ss. | `string` | | | True | +| `help` | Display the help message. | `['boolean', 'string']` | | | | +| `help_full` | Display the full detailed help message. | `boolean` | | | | +| `show_hidden` | Display hidden parameters in the help message (only works when --help or --help_full are provided). | `boolean` | | | | +| `igenomes_base` | Directory / URL base for iGenomes references. | `string` | /references/ | | True | +| `igenomes_ignore` | Do not load the iGenomes reference config.
HelpDo 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`.
| `boolean` | | | True | +| `genome` | Name of iGenomes reference.
HelpIf using a reference genome configured in the pipeline using iGenomes, use this parameter to give the ID for the reference. This is then used to build the full paths for all required reference genome files e.g. `--genome GRCh38`.

See the [nf-core website docs](https://nf-co.re/usage/reference_genomes) for more details.
| `string` | | | | diff --git a/docs/usage.md b/docs/usage.md index fe0779ab..f59c809a 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -14,97 +14,104 @@ You will need to create a samplesheet with information about the samples you wou The pipeline supports two types of samplesheets to be used as input: [`fastq`](#fastq-samplesheet) and [`flowcell`](#flowcell-samplesheet) samplesheets. The type will be automatically detected and applied by the pipeline. The pipeline will also auto-detect whether a sample is single- or paired-end using the information provided in the samplesheet. The samplesheet can have as many columns as you desire. -### Common samplesheet fields - -This table shows all samplesheet fields that can be used by both the [`fastq`](#fastq-samplesheet) and the [`flowcell`](#flowcell-samplesheet) samplesheet types. - -| Column | Description | Required for Fastq | Required for Flowcell | -| ------ | ---------------------------------------------------------------------------------- | ------------------ | --------------------- | -| `id` | Unique samplesheet/flowcell ID. Can only contain letters, numbers and underscores. | :heavy_check_mark: | :heavy_check_mark: | - ### Fastq samplesheet -A `fastq` samplesheet file consisting of both single- and paired-end data may look something like the one below. This is for 6 samples, where `TREATMENT_REP3` has been sequenced twice. - -```csv title="samplesheet.csv" -id,samplename,fastq_1,fastq_2,genome,tag -CONTROL_REP1,CONTROL_REP1,AEG588A1_S1_L002_R1_001.fastq.gz,AEG588A1_S1_L002_R2_001.fastq.gz,GRCh38,WES -CONTROL_REP2,CONTROL_REP2,AEG588A2_S2_L002_R1_001.fastq.gz,AEG588A2_S2_L002_R2_001.fastq.gz,GRCh38,WES -CONTROL_REP3,CONTROL_REP3,AEG588A3_S3_L002_R1_001.fastq.gz,AEG588A3_S3_L002_R2_001.fastq.gz,GRCh38,WES -TREATMENT_REP1,TREATMENT_REP1,AEG588A4_S4_L003_R1_001.fastq.gz,,GRCh38,WES -TREATMENT_REP2,TREATMENT_REP2,AEG588A5_S5_L003_R1_001.fastq.gz,,GRCh38,WES -TREATMENT_REP3,TREATMENT_REP3,AEG588A6_S6_L003_R1_001.fastq.gz,,GRCh38,WES -TREATMENT_REP3,TREATMENT_REP3,AEG588A6_S6_L004_R1_001.fastq.gz,,GRCh38,WES +A `fastq` samplesheet file consisting of paired-end data may look something like the one below. + +```yml +- id: DNA1_L001 + samplename: DNA_paired1 + library: test_library + genome: GRCh38 + aligner: bwamem + markdup: bamsormadup + umi_aware: false + skip_trimming: false + trim_front: 0 + trim_tail: 0 + adapter_R1: AGATCGGAAGAGCACACGTCTGAACTCCTTA + adapter_R2: AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT + run_coverage: true + disable_picard_metrics: false + roi: null + tag: WES + sample_type: DNA + fastq_1: https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/fastq/sample1_R1.fastq.gz + fastq_2: https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/fastq/sample1_R2.fastq.gz ``` Following table shows the fields that are used by the `fastq` samplesheet: -| Column | Description | Required | -| ------------ | -------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | -| `fastq_1` | FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz' | :heavy_check_mark: | -| `fastq_2` | FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz' | :x: | -| `samplename` | The sample name corresponding to the sample in the Fastq file(s) | :heavy_check_mark: | -| `genome` | The genome build to use for the analysis. Currently supports GRCh38, GRCm39 and GRCz11 | :heavy_check_mark: (unless `organism` is given) | -| `organism` | Full name of the organism. Currently supports "Homo sapiens", "Mus musculus" and "Danio rerio" | :heavy_check_mark: (unless `genome` is given) | -| `library` | Sample library name | :x: | -| `tag` | The tag used by the sample. Can be one of WES, WGS or coPGT-M | :heavy_check_mark: | -| `roi` | The path to a BED file containing Regions Of Interest for coverage analysis | :x: | -| `aligner` | The aligner to use for this sample. Can be one of these: bowtie2, bwamem, bwamem2, dragmap and snap | :x: | - -An [example samplesheet](../tests/inputs/fastq.yml) has been provided with the pipeline. +| Column | Description | Required | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | +| `id` | Unique sample identifier | :heavy_check_mark: | +| `samplename` | The sample name corresponding to the sample in the Fastq file(s) | :heavy_check_mark: | +| `genome` | The genome build to use for the analysis. Currently supports `GRCh38`, `GRCm39` and `GRCz11` | :heavy_check_mark: (unless `organism` is given) | +| `organism` | Full name of the organism. Currently supports `Homo sapiens`, `Mus musculus` and `Danio rerio` | :heavy_check_mark: (unless `genome` is given) | +| `library` | Sample library name | :x: | +| `tag` | The tag used by the sample. Can be one of `WES`, `WGS`, `SeqCap` and `coPGT-M` | :x: | +| `aligner` | The aligner to use for this sample. Can be one of these: `bowtie2`, `bwamem`, `bwamem2`, `dragmap`, `strobe` and `snap`. Set to `false` to output fastq. | :heavy_check_mark: | +| `markdup` | Markdup algorithm to use for duplicate marking. Can be set to `bamsormadup`, `samtools` or `false` | :x: | +| `umi_aware` | Whether UMI-aware processing should be used. Only applies when `markdup` is set to `samtools` | :x: | +| `skip_trimming` | Skip adapter trimming step | :x: | +| `trim_front` | Number of bases to trim from the front of reads | :x: | +| `trim_tail` | Number of bases to trim from the tail of reads | :x: | +| `adapter_R1` | Adapter sequence for read 1 | :x: | +| `adapter_R2` | Adapter sequence for read 2 | :x: | +| `run_coverage` | Run coverage analysis | :x: | +| `disable_picard_metrics` | Disable Picard metrics collection | :x: | +| `roi` | The path to a BED file containing Regions Of Interest for coverage analysis | :x: | +| `sample_type` | Sample type (e.g., `DNA`, `RNA`) | :x: | +| `fastq_1` | FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz' | :heavy_check_mark: | +| `fastq_2` | FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz' | :x: | + +An [example samplesheet](../tests/inputs/test.yml) has been provided with the pipeline. ### Flowcell samplesheet A `flowcell` samplesheet file consisting of one sequencing run may look something like the one below. -```csv title="samplesheet.csv" -id,samplesheet,sample_info,flowcell -RUN_NAME,RUN_NAME_samplesheet.csv,RUN_NAME_sampleinfo.csv,RUN_NAME_flowcell/ +```yml +- id: 200624_A00834_0183_BHMTFYDRXX + samplesheet: https://github.com/nf-cmgg/test-datasets/raw/refs/heads/preprocessing/data/genomics/homo_sapiens/illumina/flowcell/SampleSheet_2.csv + lane: 1 + flowcell: s3://test-data/genomics/homo_sapiens/illumina/bcl/ + sample_info: https://github.com/nf-cmgg/test-datasets/raw/refs/heads/preprocessing/data/genomics/homo_sapiens/illumina/flowcell/SampleInfo_2.json ``` Following table shows the fields that are used by the `flowcell` samplesheet: -| Column | Description | Required | -| ------------- | ------------------------------------------------------------------------------------------------------ | ------------------ | -| `samplesheet` | Illumina flowcell for the flowcell lane | :heavy_check_mark: | -| `sample_info` | CSV file with sample information. See the [flowcell sample info](#flowcell-sample-info) documentation. | :heavy_check_mark: | -| `flowcell` | Illumina flowcell directory | :heavy_check_mark: | -| `lane` | FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz' | :x: | +| Column | Description | Required | +| ------------- | ----------------------------------------------------------------------------------------------------------- | ------------------ | +| `samplesheet` | Illumina flowcell for the flowcell lane | :heavy_check_mark: | +| `sample_info` | JSON/YML file with sample information. See the [flowcell sample info](#flowcell-sample-info) documentation. | :heavy_check_mark: | +| `flowcell` | Illumina flowcell directory | :heavy_check_mark: | +| `lane` | Lane number | :x: | -An [example samplesheet](../tests/inputs/flowcell.yml) has been provided with the pipeline. +An [example samplesheet](../tests/inputs/test.yml) has been provided with the pipeline. ### Flowcell sample info -A `flowcell` sample info CSV file consisting for one sequencing run may look something like the one below. - -```csv title="sample_info.csv" -samplename,library,organism,tag -Sample1,test,Homo sapiens,WES -``` - -Following table shows the fields that are used by the `flowcell` samplesheet: - -| Column | Description | Required | -| --------------- | --------------------------------------------------------------------------------------------------- | ------------------ | -| `samplename` | The sample name | :heavy_check_mark: | -| `library` | The library name | :x: | -| `tag` | Sample tag. Has to be one of these: WES, WGS, coPGT-M | :heavy_check_mark: | -| `organism` | The organism of the sample. Has to be one of these: "Homo sapiens", "Mus musculus" or "Danio rerio" | :heavy_check_mark: | -| `vivar_project` | The vivar project name (currently not used by the pipeline) | :x: | -| `binsize` | The binsize for CNV analysis (currently not used by the pipeline) | :x: | -| `panels` | A list of panels for coverage analysis | :x: | -| `roi` | Region of interest BED file for coverage analysis | :x: | -| `aligner` | The aligner to use for this sample. Can be one of these: bowtie2, bwamem, bwamem2, dragmap and snap | :x: | - -### Multiple runs of the same sample - -The `sample` identifiers have to be the same when you have re-sequenced the same sample more than once e.g. to increase sequencing depth. The pipeline will concatenate the raw reads before performing any downstream analysis. Below is an example for the same sample sequenced across 3 lanes: - -```csv title="samplesheet.csv" -sample,fastq_1,fastq_2 -CONTROL_REP1,AEG588A1_S1_L002_R1_001.fastq.gz,AEG588A1_S1_L002_R2_001.fastq.gz -CONTROL_REP1,AEG588A1_S1_L003_R1_001.fastq.gz,AEG588A1_S1_L003_R2_001.fastq.gz -CONTROL_REP1,AEG588A1_S1_L004_R1_001.fastq.gz,AEG588A1_S1_L004_R2_001.fastq.gz +A `flowcell` sample info JSON/YML file consisting for one sequencing run may look something like the one below. + +```yml +- id: DNA1_L001 + samplename: DNA_paired1 + library: test_library + genome: GRCh38 + aligner: bwamem + markdup: bamsormadup + umi_aware: false + skip_trimming: false + trim_front: 0 + trim_tail: 0 + adapter_R1: AGATCGGAAGAGCACACGTCTGAACTCCTTA + adapter_R2: AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT + run_coverage: true + disable_picard_metrics: false + roi: null + tag: WES + sample_type: DNA ``` ## Running the pipeline @@ -112,7 +119,7 @@ CONTROL_REP1,AEG588A1_S1_L004_R1_001.fastq.gz,AEG588A1_S1_L004_R2_001.fastq.gz The typical command for running the pipeline is as follows: ```bash -nextflow run nf-cmgg/preprocessing --input ./samplesheet.csv --outdir ./results -profile docker +nextflow run nf-cmgg/preprocessing --input ./samplesheet. --outdir ./results -profile docker ``` This will launch the pipeline with the `docker` configuration profile. See below for more information about profiles. @@ -166,7 +173,7 @@ First, go to the [nf-cmgg/preprocessing releases page](https://github.com/nf-cmg 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 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. :::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. @@ -182,19 +189,21 @@ These options are part of Nextflow and use a _single_ hyphen (pipeline parameter Use this parameter to choose a configuration profile. Profiles can give configuration presets for different compute environments. -Several generic profiles are bundled with the pipeline which instruct the pipeline to use software packaged using different methods (Docker, Singularity, Podman, Shifter, Charliecloud, 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. -::: +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) - see below. 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). 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. +- `debug` + - A generic profile with settings to help with debugging the pipeline. It will use more verbose logging. +- `arm64` + - A generic profile with settings to run the pipeline on ARM64 architecture machines (eg. Apple Silicon). It will use software containers built for ARM64 where available. +- `emulate_amd64` + - A generic profile with settings to run the pipeline on ARM64 architecture machines (eg. Apple Silicon) using AMD64 software containers. This is for when ARM64 containers are not available but you still want to run the pipeline on an ARM64 machine. Note that this will be slower than using ARM64 containers. - `test` - A profile with a complete configuration for automated testing - Includes links to test data so needs no other parameters @@ -210,8 +219,6 @@ If `-profile` is not specified, the pipeline will run locally and expect all sof - A generic configuration profile to be used with [Charliecloud](https://hpc.github.io/charliecloud/) - `apptainer` - A generic configuration profile to be used with [Apptainer](https://apptainer.org/) -- `conda` - - A generic configuration profile to be used with [Conda](https://conda.io/docs/). Please only use Conda as a last resort i.e. when it's not possible to run the pipeline with Docker, Singularity, Podman, Shifter, Charliecloud, or Apptainer. ### `-resume` @@ -233,9 +240,9 @@ To change the resource requests, please see the [max resources](https://nf-co.re ### 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 which container 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 may be 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. +To use a different container from the default container 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. ### Custom Tool Arguments @@ -243,22 +250,14 @@ A pipeline might not always support every possible argument or option of a parti To learn how to provide additional arguments to a particular tool of the pipeline, please see the [customising tool arguments](https://nf-co.re/docs/usage/configuration#customising-tool-arguments) section of the nf-core website. -### nf-core/configs +### nf-core/configs and nf-cmgg/configs -In most cases, you will only need to create a custom config as a one-off but if you and others within your organisation are likely to be running nf-core pipelines regularly and need to use the same settings regularly it may be a good idea to request that your custom config file is uploaded to the `nf-core/configs` git repository. Before you do this please can you test that the config file works with your pipeline of choice using the `-c` parameter. You can then create a pull request to the `nf-core/configs` repository with the addition of your config file, associated documentation file (see examples in [`nf-core/configs/docs`](https://github.com/nf-core/configs/tree/master/docs)), and amending [`nfcore_custom.config`](https://github.com/nf-core/configs/blob/master/nfcore_custom.config) to include your custom profile. +In most cases, you will only need to create a custom config as a one-off but if you and others within your organisation are likely to be running nf-cmgg pipelines regularly and need to use the same settings regularly it may be a good idea to request that your custom config file is uploaded to the `nf-core/configs` git repository. Before you do this please can you test that the config file works with your pipeline of choice using the `-c` parameter. You can then create a pull request to the `nf-core/configs` repository with the addition of your config file, associated documentation file (see examples in [`nf-core/configs/docs`](https://github.com/nf-core/configs/tree/master/docs)), and amending [`nfcore_custom.config`](https://github.com/nf-core/configs/blob/master/nfcore_custom.config) to include your custom profile. See the main [Nextflow documentation](https://www.nextflow.io/docs/latest/config.html) for more information about creating your own configuration files. 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. @@ -266,7 +265,7 @@ Nextflow handles job submissions and supervises the running jobs. The Nextflow p The Nextflow `-bg` flag launches Nextflow in the background, detached from your terminal so that the workflow does not stop if you log out of your session. The logs are saved to a file. Alternatively, you can use `screen` / `tmux` or similar tool to create a detached session which you can log back into at a later time. -Some HPC setups also allow you to run nextflow within a cluster job submitted your job scheduler (from where it submits more jobs). +Some HPC setups also allow you to run nextflow within a cluster job submitted to your job scheduler (from where it submits more jobs). ## Nextflow memory requirements diff --git a/main.nf b/main.nf index 466854ee..64e8d3db 100644 --- a/main.nf +++ b/main.nf @@ -7,8 +7,6 @@ ---------------------------------------------------------------------------------------- */ -nextflow.enable.dsl = 2 - /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS / WORKFLOWS @@ -18,43 +16,6 @@ nextflow.enable.dsl = 2 include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_preprocessing_pipeline' include { PREPROCESSING } from './workflows/preprocessing' include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_preprocessing_pipeline' - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - NAMED WORKFLOWS FOR PIPELINE -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -// -// WORKFLOW: Run main analysis pipeline depending on type of input -// -workflow NFCMGG_PREPROCESSING { - - take: - samplesheet // channel: samplesheet read in from --input - genomes // map: genome reference files - aligner // string: aligner to use - markdup // string: markdup method to use - roi // string: region of interest to use - genelists // file: directory containing genelist bed files for coverage analysis - main: - - // - // WORKFLOW: Run pipeline - // - PREPROCESSING ( - samplesheet, - genomes, - aligner, - markdup, - roi, - genelists - ) - - emit: - multiqc_report = PREPROCESSING.out.multiqc_report // channel: /path/to/multiqc_report.html - -} /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN MAIN WORKFLOW @@ -64,46 +25,289 @@ workflow NFCMGG_PREPROCESSING { workflow { main: - // // SUBWORKFLOW: Run initialisation tasks // - PIPELINE_INITIALISATION ( + PIPELINE_INITIALISATION( params.version, params.validate_params, args, params.outdir, - params.input + params.input, + params.help, + params.help_full, + params.show_hidden, ) // // WORKFLOW: Run main workflow // - NFCMGG_PREPROCESSING ( + PREPROCESSING( PIPELINE_INITIALISATION.out.samplesheet, params.genomes, - params.aligner, - params.markdup, - params.roi, params.genelists, + params.multiqc_config + ? [file("${projectDir}/assets/multiqc_config.yml", checkIfExists: true), file(params.multiqc_config, checkIfExists: true)] + : [file("${projectDir}/assets/multiqc_config.yml", checkIfExists: true)], + params.multiqc_logo ? file(params.multiqc_logo, checkIfExists: true) : [], + params.multiqc_methods_description ? file(params.multiqc_methods_description, checkIfExists: true) : file("${projectDir}/assets/methods_description_template.yml", checkIfExists: true), ) // // SUBWORKFLOW: Run completion tasks // - PIPELINE_COMPLETION ( + PIPELINE_COMPLETION( params.email, params.email_on_fail, params.plaintext_email, params.outdir, params.monochrome_logs, - params.hook_url, - NFCMGG_PREPROCESSING.out.multiqc_report + PREPROCESSING.out.multiqc_report, ) + + publish: + demultiplex_reports = PREPROCESSING.out.demultiplex_reports.transpose() + demultiplex_logs = PREPROCESSING.out.demultiplex_logs.transpose() + demultiplex_fastq = PREPROCESSING.out.demultiplex_fastq.transpose() + demultiplex_interop = PREPROCESSING.out.demultiplex_interop.transpose(by: 1) + falco_html = PREPROCESSING.out.falco_html + falco_txt = PREPROCESSING.out.falco_txt + fastp_json = PREPROCESSING.out.fastp_json + fastp_html = PREPROCESSING.out.fastp_html + crams = PREPROCESSING.out.crams + rna_splice_junctions = PREPROCESSING.out.rna_splice_junctions + rna_junctions = PREPROCESSING.out.rna_junctions + align_reports = PREPROCESSING.out.align_reports + sormadup_metrics = PREPROCESSING.out.sormadup_metrics + mosdepth_global = PREPROCESSING.out.mosdepth_global + mosdepth_summary = PREPROCESSING.out.mosdepth_summary + mosdepth_regions = PREPROCESSING.out.mosdepth_regions + mosdepth_per_base_d4 = PREPROCESSING.out.mosdepth_per_base_d4 + mosdepth_per_base_bed = PREPROCESSING.out.mosdepth_per_base_bed + mosdepth_per_base_csi = PREPROCESSING.out.mosdepth_per_base_csi + mosdepth_regions_bed = PREPROCESSING.out.mosdepth_regions_bed + mosdepth_regions_csi = PREPROCESSING.out.mosdepth_regions_csi + mosdepth_quantized_bed = PREPROCESSING.out.mosdepth_quantized_bed + mosdepth_quantized_csi = PREPROCESSING.out.mosdepth_quantized_csi + mosdepth_thresholds_bed = PREPROCESSING.out.mosdepth_thresholds_bed + mosdepth_thresholds_csi = PREPROCESSING.out.mosdepth_thresholds_csi + samtools_coverage = PREPROCESSING.out.samtools_coverage + panelcoverage = PREPROCESSING.out.panelcoverage + samtools_stats = PREPROCESSING.out.samtools_stats + samtools_flagstat = PREPROCESSING.out.samtools_flagstat + samtools_idxstats = PREPROCESSING.out.samtools_idxstats + picard_multiplemetrics = PREPROCESSING.out.picard_multiplemetrics + picard_multiplemetrics_pdf = PREPROCESSING.out.picard_multiplemetrics_pdf + picard_wgsmetrics = PREPROCESSING.out.picard_wgsmetrics + picard_hsmetrics = PREPROCESSING.out.picard_hsmetrics + md5sums = PREPROCESSING.out.md5sums + multiqc_report = PREPROCESSING.out.multiqc_report + multiqc_data = PREPROCESSING.out.multiqc_data + multiqc_plots = PREPROCESSING.out.multiqc_plots + multiqcsav_report = PREPROCESSING.out.multiqcsav_report + multiqcsav_data = PREPROCESSING.out.multiqcsav_data + multiqcsav_plots = PREPROCESSING.out.multiqcsav_plots } -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - THE END -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ +output { + demultiplex_reports { + path { meta, report -> + report >> (meta.lane ? "Reports/L00${meta.lane}/${report.name}" : "Reports/${report.name}") + } + } + demultiplex_logs { + path { meta, log -> + log >> (meta.lane ? "Logs/L00${meta.lane}/${log.name}" : "Logs/${log.name}") + } + } + demultiplex_interop { + path { _meta, bin -> + bin >> "Interop/${bin.name}" + } + } + demultiplex_fastq { + path { meta, fastq -> + fastq >> (meta.library ? "${meta.library}/${meta.samplename}/${fastq.name}" : "${meta.samplename}/${fastq.name}") + } + } + falco_html { + path { meta, html -> + html >> (meta.library ? "${meta.library}/${meta.samplename}/${html.name}" : "${meta.samplename}/${html.name}") + } + } + falco_txt { + path { meta, txt -> + txt >> (meta.library ? "${meta.library}/${meta.samplename}/${txt.name}" : "${meta.samplename}/${txt.name}") + } + } + fastp_json { + path { meta, json -> + json >> (meta.library ? "${meta.library}/${meta.samplename}/${json.name}" : "${meta.samplename}/${json.name}") + } + } + fastp_html { + path { meta, html -> + html >> (meta.library ? "${meta.library}/${meta.samplename}/${html.name}" : "${meta.samplename}/${html.name}") + } + } + crams { + path { meta, cram, crai -> + cram >> (meta.library ? "${meta.library}/${meta.samplename}/${meta.samplename}.cram" : "${meta.samplename}/${meta.samplename}.cram") + crai >> (meta.library ? "${meta.library}/${meta.samplename}/${meta.samplename}.cram.crai" : "${meta.samplename}/${meta.samplename}.cram.crai") + } + } + rna_splice_junctions { + path { meta, sjt -> + sjt >> (meta.library ? "${meta.library}/${meta.samplename}/${sjt.name}" : "${meta.samplename}/${sjt.name}") + } + } + rna_junctions { + path { meta, junctions -> + junctions >> (meta.library ? "${meta.library}/${meta.samplename}/${junctions.name}" : "${meta.samplename}/${junctions.name}") + } + } + align_reports { + path { meta, log -> + log >> (meta.library ? "${meta.library}/${meta.samplename}/${log.name}" : "${meta.samplename}/${log.name}") + } + } + sormadup_metrics { + path { meta, metrics -> + metrics >> (meta.library ? "${meta.library}/${meta.samplename}/${meta.samplename}.duplicate_metrics.txt" : "${meta.samplename}/${meta.samplename}.duplicate_metrics.txt") + } + } + mosdepth_global { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + mosdepth_summary { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + mosdepth_regions { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + mosdepth_per_base_d4 { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + mosdepth_per_base_bed { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + mosdepth_per_base_csi { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + mosdepth_regions_bed { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + mosdepth_regions_csi { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + mosdepth_quantized_bed { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + mosdepth_quantized_csi { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + mosdepth_thresholds_bed { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + mosdepth_thresholds_csi { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + samtools_coverage { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + panelcoverage { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + samtools_stats { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + samtools_flagstat { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + samtools_idxstats { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + picard_multiplemetrics { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + picard_multiplemetrics_pdf { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + picard_wgsmetrics { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + picard_hsmetrics { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + md5sums { + path { meta, _file -> + return (meta.library ? "${meta.library}/${meta.samplename}/" : "${meta.samplename}/") + } + } + multiqcsav_report { + path "multiqc/" + } + multiqcsav_data { + path "multiqc/" + } + multiqcsav_plots { + path "multiqc/" + } + multiqc_report { + path { meta, _file -> + return (meta.id ? "${meta.id}/multiqc/" : "multiqc/") + } + } + multiqc_data { + path { meta, _file -> + return (meta.id ? "${meta.id}/multiqc/" : "multiqc/") + } + } + multiqc_plots { + path { meta, _file -> + return (meta.id ? "${meta.id}/multiqc/" : "multiqc/") + } + } +} diff --git a/modules.json b/modules.json index d860bfc6..5f13e2ed 100644 --- a/modules.json +++ b/modules.json @@ -5,176 +5,177 @@ "https://github.com/nf-core/modules.git": { "modules": { "nf-core": { - "bcl2fastq": { - "branch": "master", - "git_sha": "05954dab2ff481bcb999f24455da29a5828af08d", - "installed_by": ["bcl_demultiplex"] - }, "bclconvert": { "branch": "master", - "git_sha": "27cceb2eb8aa959d4a8819caab886386a59a3789", - "installed_by": ["bcl_demultiplex", "modules"] + "git_sha": "e4a7e011bee58ded839f4da6bf9bb3fbfbebdebd", + "installed_by": ["modules"] }, "biobambam/bamsormadup": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "aef75083111cea684bafb6c27cdba8a8d0916638", "installed_by": ["modules"], "patch": "modules/nf-core/biobambam/bamsormadup/biobambam-bamsormadup.diff" }, "bowtie2/align": { "branch": "master", - "git_sha": "8864afe586537bf562eac7b83349c26207f3cb4d", + "git_sha": "92b8df948fd8cdb223e051f5f5e414818a073ee0", "installed_by": ["fastq_align_dna", "modules"], "patch": "modules/nf-core/bowtie2/align/bowtie2-align.diff" }, "bwa/mem": { "branch": "master", - "git_sha": "a29f18660f5e3748d44d6f716241e70c942c065d", + "git_sha": "707241c72951f24fd89982c4c80c5983a4c437ef", "installed_by": ["fastq_align_dna"], "patch": "modules/nf-core/bwa/mem/bwa-mem.diff" }, "bwamem2/mem": { "branch": "master", - "git_sha": "a29f18660f5e3748d44d6f716241e70c942c065d", + "git_sha": "8325a8155a77a336a613a504b8e4d6cea7a2344a", "installed_by": ["fastq_align_dna"], "patch": "modules/nf-core/bwamem2/mem/bwamem2-mem.diff" }, "dragmap/align": { "branch": "master", - "git_sha": "8864afe586537bf562eac7b83349c26207f3cb4d", + "git_sha": "9fd8df2d3e0cd7add065a5c59dd1e9841a907e13", "installed_by": ["fastq_align_dna"], "patch": "modules/nf-core/dragmap/align/dragmap-align.diff" }, + "falco": { + "branch": "master", + "git_sha": "b2f164ca59b14d6e9ed2dd2a99fa015085396faf", + "installed_by": ["modules"] + }, "fastp": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", - "installed_by": ["modules"], - "patch": "modules/nf-core/fastp/fastp.diff" + "git_sha": "a331ecfd1aa48b2b2298aab23bb4516c800e410b", + "installed_by": ["modules"] + }, + "gnu/sort": { + "branch": "master", + "git_sha": "5e748ff2b0f990949081c9e49792622eb3fe9ee9", + "installed_by": ["modules"] }, "md5sum": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "7df444999424fb148e251c4de5140296c9356f54", "installed_by": ["modules"] }, "mosdepth": { "branch": "master", - "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "git_sha": "6832b69ef7f98c54876d6436360b6b945370c615", "installed_by": ["modules"], "patch": "modules/nf-core/mosdepth/mosdepth.diff" }, "multiqc": { "branch": "master", - "git_sha": "471cf3ca1617271b9b6fea09ea2ebdee78b874de", + "git_sha": "2c73cc8fa92cf48de3da0b643fdf357a8a290b36", + "installed_by": ["modules"], + "patch": "modules/nf-core/multiqc/multiqc.diff" + }, + "multiqcsav": { + "branch": "master", + "git_sha": "2c73cc8fa92cf48de3da0b643fdf357a8a290b36", "installed_by": ["modules"] }, "picard/collecthsmetrics": { "branch": "master", - "git_sha": "49f4e50534fe4b64101e62ea41d5dc43b1324358", + "git_sha": "a631e12055f6c23ba2c942d3902b3ed1b9eed859", "installed_by": ["modules"], "patch": "modules/nf-core/picard/collecthsmetrics/picard-collecthsmetrics.diff" }, "picard/collectmultiplemetrics": { "branch": "master", - "git_sha": "49f4e50534fe4b64101e62ea41d5dc43b1324358", + "git_sha": "a631e12055f6c23ba2c942d3902b3ed1b9eed859", "installed_by": ["modules"], "patch": "modules/nf-core/picard/collectmultiplemetrics/picard-collectmultiplemetrics.diff" }, "picard/collectwgsmetrics": { "branch": "master", - "git_sha": "49f4e50534fe4b64101e62ea41d5dc43b1324358", + "git_sha": "a631e12055f6c23ba2c942d3902b3ed1b9eed859", "installed_by": ["modules"], "patch": "modules/nf-core/picard/collectwgsmetrics/picard-collectwgsmetrics.diff" }, - "samtools/cat": { - "branch": "master", - "git_sha": "b13f07be4c508d6ff6312d354d09f2493243e208", - "installed_by": ["modules"], - "patch": "modules/nf-core/samtools/cat/samtools-cat.diff" - }, "samtools/convert": { "branch": "master", - "git_sha": "b13f07be4c508d6ff6312d354d09f2493243e208", + "git_sha": "51fa714751883254ede046c50acf20076b46ca81", "installed_by": ["modules"], "patch": "modules/nf-core/samtools/convert/samtools-convert.diff" }, "samtools/coverage": { "branch": "master", - "git_sha": "2d20463181b1c38981a02e90d3084b5f9fa8d540", + "git_sha": "440edf75d8782913115a7b72a88392a227f72cc1", "installed_by": ["modules"], "patch": "modules/nf-core/samtools/coverage/samtools-coverage.diff" }, "samtools/flagstat": { "branch": "master", - "git_sha": "2d20463181b1c38981a02e90d3084b5f9fa8d540", + "git_sha": "1d2fbdcbca677bbe8da0f9d0d2bb7c02f2cab1c9", "installed_by": ["modules"] }, "samtools/idxstats": { "branch": "master", - "git_sha": "2d20463181b1c38981a02e90d3084b5f9fa8d540", - "installed_by": ["modules"] - }, - "samtools/import": { - "branch": "master", - "git_sha": "2d20463181b1c38981a02e90d3084b5f9fa8d540", + "git_sha": "1d2fbdcbca677bbe8da0f9d0d2bb7c02f2cab1c9", "installed_by": ["modules"] }, "samtools/sormadup": { "branch": "master", - "git_sha": "38f3b0200093498b70ac2d63a83eac5642e3c873", + "git_sha": "0043d7ccd6b7278cd566db278c2f6ceb937e04ba", "installed_by": ["modules"], "patch": "modules/nf-core/samtools/sormadup/samtools-sormadup.diff" }, "samtools/sort": { "branch": "master", - "git_sha": "b7800db9b069ed505db3f9d91b8c72faea9be17b", + "git_sha": "5cb9a8694da0a0e550921636bb60bc8c56445fd7", "installed_by": ["modules"], "patch": "modules/nf-core/samtools/sort/samtools-sort.diff" }, "samtools/stats": { "branch": "master", - "git_sha": "2d20463181b1c38981a02e90d3084b5f9fa8d540", + "git_sha": "fe93fde0845f907fc91ad7cc7d797930408824df", "installed_by": ["modules"], "patch": "modules/nf-core/samtools/stats/samtools-stats.diff" }, "snapaligner/align": { "branch": "master", - "git_sha": "77bdd7e1047d2abe21ae8d89acc295ea553ecbae", + "git_sha": "cf0eb2bed12c39c5b714d44dd02039a0cefaedb1", "installed_by": ["fastq_align_dna", "modules"], "patch": "modules/nf-core/snapaligner/align/snapaligner-align.diff" }, "star/align": { "branch": "master", - "git_sha": "3c259f0ac1ed9ae3f6b835461d054edffc60120e", + "git_sha": "cebe21bbd158c15c8fab172e37cfe97a239f4b77", "installed_by": ["modules"], "patch": "modules/nf-core/star/align/star-align.diff" + }, + "strobealign": { + "branch": "master", + "git_sha": "698af1c52555faeba677dfafc6d0197a840ca81f", + "installed_by": ["fastq_align_dna", "modules"], + "patch": "modules/nf-core/strobealign/strobealign.diff" } } }, "subworkflows": { "nf-core": { - "bcl_demultiplex": { - "branch": "master", - "git_sha": "27cceb2eb8aa959d4a8819caab886386a59a3789", - "installed_by": ["subworkflows"] - }, "fastq_align_dna": { "branch": "master", - "git_sha": "a29f18660f5e3748d44d6f716241e70c942c065d", - "installed_by": ["subworkflows"] + "git_sha": "9afa0584136287aa20fc18296f45f103c0c4e69a", + "installed_by": ["subworkflows"], + "patch": "subworkflows/nf-core/fastq_align_dna/fastq_align_dna.diff" }, "utils_nextflow_pipeline": { "branch": "master", - "git_sha": "56372688d8979092cafbe0c5c3895b491166ca1c", + "git_sha": "05954dab2ff481bcb999f24455da29a5828af08d", "installed_by": ["subworkflows"] }, "utils_nfcore_pipeline": { "branch": "master", - "git_sha": "1b6b9a3338d011367137808b49b923515080e3ba", + "git_sha": "f0b535b3ae20080f8db03dd5388876ad1ec29d70", "installed_by": ["subworkflows"] }, "utils_nfschema_plugin": { "branch": "master", - "git_sha": "2fd2cd6d0e7b273747f32e465fdc6bcc3ae0814e", + "git_sha": "fdc08b8b1ae74f56686ce21f7ea11ad11990ce57", "installed_by": ["subworkflows"] } } diff --git a/modules/local/panelcoverage/main.nf b/modules/local/panelcoverage/main.nf index 992d4b99..6e29a9c6 100644 --- a/modules/local/panelcoverage/main.nf +++ b/modules/local/panelcoverage/main.nf @@ -1,51 +1,33 @@ process PANELCOVERAGE { - tag "$meta.id" - label 'process_single' + tag "${meta.id}" + label 'process_medium' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bedtools:2.31.1--hf5e1c6e_1' : - 'biocontainers/bedtools:2.31.1--hf5e1c6e_1' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/bedtools:2.31.1--hf5e1c6e_1' + : 'biocontainers/bedtools:2.31.1--hf5e1c6e_1'}" input: - tuple val(meta), path(perbase), path(perbase_index) - path(genelists) + tuple val(meta), path(perbase), path(perbase_index), path(genelists) output: tuple val(meta), path("*.mosdepth.region.dist.txt"), emit: regiondist - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when + tuple val("${task.process}"), val('cmgg_genelists'), eval('cmgg_genelists -v 2>&1 | sed \"s/^.*cmgg_genelists version //\"'), emit: versions_cmgg_genelists, topic: versions + tuple val("${task.process}"), val('bedtools'), eval('bedtools --version 2>&1 | sed \"s/^.*bedtools v//\"'), emit: versions_bedtools, topic: versions script: def prefix = task.ext.prefix ?: "${meta.id}" """ - for GENELIST in $genelists - do - cmgg_genelists regiondist --samplename ${prefix} --perbase ${perbase} --genelist \$GENELIST - done - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - cmgg_genelists: \$(cmgg_genelists -v 2>&1 | sed 's/^.*cmgg_genelists version //') - bedtools: \$(echo \$(bedtools --version 2>&1) | sed 's/^.*bedtools v//' )) - END_VERSIONS + echo ${genelists} | tr ' ' '\n' | xargs -n 1 -P ${task.cpus} -I {} cmgg_genelists regiondist --samplename ${prefix} --perbase ${perbase} --genelist {} """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ - for GENELIST in $genelists + for GENELIST in ${genelists} do name=\$(basename \$GENELIST .bed) touch ${prefix}_\${name}.mosdepth.region.dist.txt done - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - cmgg_genelists: \$(cmgg_genelists --version 2>&1 | sed 's/^.*cmgg_genelists version //') - bedtools: \$(echo \$(bedtools --version 2>&1) | sed 's/^.*bedtools v//' )) - END_VERSIONS """ } diff --git a/modules/nf-core/bcl2fastq/.gitignore b/modules/nf-core/bcl2fastq/.gitignore deleted file mode 100644 index 45b0ea3a..00000000 --- a/modules/nf-core/bcl2fastq/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -bcl-convert -*.rpm diff --git a/modules/nf-core/bcl2fastq/Dockerfile b/modules/nf-core/bcl2fastq/Dockerfile deleted file mode 100644 index 5600ab84..00000000 --- a/modules/nf-core/bcl2fastq/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -# Dockerfile to create container with bcl2fastq -# Push to nfcore/bcl2fastq: - -FROM debian:bullseye-slim -LABEL authors="Matthias De Smet " \ - description="Docker image containing bcl2fastq" -# Disclaimer: this container is not provided nor supported by Illumina -# 'ps' command is needed by some nextflow executions to collect system stats -# Install procps and clean apt cache -RUN apt-get update \ - && apt-get install -y \ - procps \ - && apt-get clean -y && rm -rf /var/lib/apt/lists/* -# Link hostname cmd to fix hardcoded path -RUN ln -s /bin/hostname /usr/bin/hostname - -# Add executable to image -COPY bcl2fastq /usr/local/bin/bcl2fastq - -# Add external libs to image -COPY css /usr/local/share/css -COPY xsl /usr/local/share/xsl - -# Set permission -RUN chmod +x /usr/local/bin/bcl2fastq && chmod -R +rX /usr/local/share/css && chmod -R +rX /usr/local/share/xsl diff --git a/modules/nf-core/bcl2fastq/LICENSE b/modules/nf-core/bcl2fastq/LICENSE deleted file mode 100644 index 6f523227..00000000 --- a/modules/nf-core/bcl2fastq/LICENSE +++ /dev/null @@ -1,30 +0,0 @@ -ILLUMINA END-USER SOFTWARE LICENSE AGREEMENT - -IMPORTANT-READ CAREFULLY. THIS IS A LICENSE AGREEMENT THAT YOU ARE REQUIRED TO ACCEPT BEFORE, DOWNLOADING, INSTALLING AND USING ANY SOFTWARE MADE AVAILABLE FROM THE ILLUMINA SUPPORT CENTER (https://support.illumina.com). - -CAREFULLY READ ALL THE TERMS AND CONDITIONS OF THIS LICENSE AGREEMENT BEFORE PROCEEDING WITH DOWNLOADING, INSTALLING, AND/OR USING THE SOFTWARE. YOU ARE NOT PERMITTED TO DOWNLOAD, INSTALL, AND/OR USE THE SOFTWARE UNTIL YOU HAVE AGREED TO BE BOUND BY ALL OF THE TERMS AND CONDITIONS OF THIS LICENSE AGREEMENT. YOU REPRESENT AND WARRANT THAT YOU ARE DULY AUTHORIZED TO ACCEPT THE TERMS AND CONDITIONS OF THIS LICENSE AGREEMENT ON BEHALF OF YOUR EMPLOYER. - -Software made available through the Illumina Support Center is licensed, not sold, to you. Your license to each software program made available through the Illumina Support Center is subject to your prior acceptance of either this Illumina End-User Software License Agreement (“Agreement”), or a custom end user license agreement (“Custom EULA”), if one is provided with the software. Any software that is subject to this Agreement is referred to herein as the “Software.” By accepting this Agreement, you agree the terms and conditions of this Agreement will apply to and govern any and all of your downloads, installations, and uses of each Illumina software program made available through the Illumina Support Center, except that your download, installation, and use of any software provided with a Custom EULA will be governed by the terms and conditions of the Custom EULA. - -This Agreement is made and entered into by and between Illumina, Inc., a Delaware corporation, having offices at 5200 Illumina Way, San Diego, CA 92122 (“Illumina”) and you as the end-user of the Software (hereinafter, “Licensee” or “you”). All software, firmware, and associated media, printed materials, and online and electronic documentation, including any updates or upgrades thereof, made available through the Illumina Support Center (collectively, “Software”) provided to Licensee are for use solely by Licensee and the provisions herein WILL apply with respect to such Software. - -License Grant. Subject to the terms and conditions of this Agreement, Illumina grants to Licensee, under the following terms and conditions, a personal, non-exclusive, revocable, non-transferable, non-sublicensable license, for its internal end-use purposes only, in the ordinary course of Licensee’s business to use the Software in executable object code form only, solely at the Licensee’s facility to, install and use the Software on a single computer accessible only by Licensee (and not on any public network or server), where the single computer is owned, leased, or otherwise substantially controlled by Licensee, for the purpose of processing and analyzing data generated from an Illumina genetic sequencing instrument owned and operated solely by Licensee (the “Product”). In the case of Software provided by Illumina in non-compiled form, Illumina grants Licensee a personal, non-exclusive, non-sublicenseable, restricted right to compile, install, and use one copy of the Software solely for processing and analyzing data generated from the Product. -License Restrictions. Except as expressly permitted in Section 1, Licensee may not make, have made, import, use, copy, reproduce, distribute, display, publish, sell, re-sell, lease, or sub-license the Software, in whole or in part, except as expressly provided for in this Agreement. Licensee may not modify, improve, translate, reverse engineer, decompile, disassemble, or create derivative works of the Software or otherwise attempt to (a) defeat, avoid, by-pass, remove, deactivate, or otherwise circumvent any software protection mechanisms in the Software including, without limitation, any such mechanism used to restrict or control the functionality of the Software, or (b) derive the source code or the underlying ideas, algorithms, structure, or organization form of the Software. Licensee will not allow, at any time, including during and after the term of the license, the Software or any portions or copies thereof in any form to become available to any third parties. Licensee may use the Software solely with genomic data that is generated using the Product; Licensee may not use the Software with any data generated from other products or instruments. Licensee may not use the Software to perform any data analysis services for any third party. -Ownership. The Software is protected by United States and international intellectual property laws. All right, title, and interest in and to the Software (including associated intellectual property rights) are and will remain vested in Illumina or Illumina’s affiliated companies or licensors. Licensee acknowledges that no rights, license or interest to any Illumina trademarks are granted hereunder. Licensee acknowledges that unauthorized reproduction or distribution of the Software, or any portion of it, may result in severe civil and criminal penalties. Illumina reserves all rights in and to the Software not expressly granted to Licensee under this Agreement. -Upgrades/Updates. Illumina may, at its sole discretion, provide updates or upgrades to the Software. In that case, Licensee WILL have the same rights and obligations under such updates or upgrades as it has for the versions of the Software initially provided to Licensee hereunder. Licensee recognizes that Illumina is not obligated to provide any upgrades or updates to, or support for, the Software. -Data Integrity/Loss. Licensee is responsible for the integrity and availability, including preventing the loss of data that Licensee generates, uses, analyzes, manages, or stores in connection with or through its use of the Software, including without limitation, investigating and implementing industry appropriate policies and procedures regarding the provision of access to Licensee’s data, monitoring access and use of Licensee’s data, conducting routine backups and archiving of Licensee’s data, and ensuring the adequacy of anti-virus software. Accordingly, Licensee agrees that Illumina is not responsible for any inability to access, loss or corruption of data as a result of Licensee’s use of the Software, and Illumina has no liability to Licensee in connection with such inability to access, loss or corruption of data. -Term of License. This Agreement will be in effect from the time Licensee expressly accepts the terms and conditions of this license, or otherwise installs the Software, thereby accepting the terms and conditions contained herein, and will remain in effect until terminated. This license will otherwise terminate upon the conditions set forth in this Agreement, if revoked by Illumina, or if Licensee fails to comply with any term or condition of this Agreement including failure to pay any applicable license fee. Licensee agrees upon termination of this Agreement for any reason to immediately discontinue use of and un-install the Software and destroy all copies of the Software in its possession and/or under its control, and return or destroy, at Illumina’s option, any compact disks, floppy disks or other media provided by Illumina storing the Software thereon (together with any authorized copies thereof), as well as any documentation associated therewith -Limited Warranty. Illumina warrants that, for a period of 6 months from the date of download or installation of the Software by Licensee, the Software will perform in all material respects in accordance with the accompanying documentation available on the Illumina Support Center. EXCEPT AND TO THE EXTENT EXPRESSLY PROVIDED IN THE FOREGOING, AND TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED “AS IS” AND ILLUMINA EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS REGARDING THE SOFTWARE AND RESULTS GENERATED BY THE SOFTWARE, INCLUDING WITHOUT LIMITATION, TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, ALL OTHER EXPRESS OR IMPLIED WARRANTIES OR CONDITIONS OF MERCHANTABLE QUALITY, NON-INFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE, AND THOSE ARISING BY STATUTE OR OTHERWISE IN LAW OR FROM A COURSE OF DEALING OR USAGE OF TRADE. ILLUMINA DOES NOT WARRANT THAT THE FUNCTIONS CONTAINED IN THE SOFTWARE WILL MEET LICENSEE"S REQUIREMENTS, OR THAT THE OPERATION OF THE SOFTWARE WILL BE ERROR FREE OR UNINTERRUPTED. -Limitation of Liability. -(a) ILLUMINA’S ENTIRE LIABILITY AND LICENSEE"S EXCLUSIVE REMEDY UNDER THE LIMITED WARRANTY PROVISION OF SECTION 7 ABOVE WILL BE, AT ILLUMINA’S OPTION, EITHER (i) RETURN OF THE PRICE PAID FOR THE SOFTWARE, OR (ii) REPAIR OR REPLACEMENT OF THE PORTIONS OF THE SOFTWARE THAT DO NOT COMPLY WITH ILLUMINA’S LIMITED WARRANTY. THIS LIMITED WARRANTY IS VOID AND ILLUMINA WILL HAVE NO LIABILITY AT ALL IF FAILURE OF THE SOFTWARE TO COMPLY WITH ILLUMINA LIMITED WARRANTY HAS RESULTED FROM: (w) FAILURE TO USE THE SOFTWARE IN ACCORDANCE WITH ILLUMINA’S THEN CURRENT USER MANUAL OR THIS AGREEMENT; (x) ACCIDENT, ABUSE, OR MISAPPLICATION; (y) PRODUCTS OR EQUIPMENT NOT SPECIFIED BY ILLUMINA AS BEING COMPATIBLE WITH THE SOFTWARE; OR (z) IF LICENSEE HAS NOT NOTIFIED ILLUMINA IN WRITING OF THE DEFECT WITHIN THE ABOVE WARRANTY PERIOD. - -(b) TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL ILLUMINA BE LIABLE UNDER ANY THEORY OF CONTRACT, TORT, STRICT LIABILITY OR OTHER LEGAL OR EQUITABLE THEORY FOR ANY PERSONAL INJURY OR ANY INDIRECT, CONSEQUENTIAL, OR INCIDENTAL DAMAGES, EVEN IF ILLUMINA HAS BEEN ADVISED OF THE POSSIBILITY THEREOF INCLUDING, WITHOUT LIMITATION, LOST PROFITS, LOST DATA, INTERRUPTION OF BUSINESS, LOST BUSINESS REVENUE, OTHER ECONOMIC LOSS, OR ANY LOSS OF RECORDED DATA ARISING OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE. EXCEPT AND TO THE EXTENT EXPRESSLY PROVIDED IN SECTION 7 AND 8(a) ABOVE OR AS OTHERWISE PERMITTED BY LAW, IN NO EVENT WILL ILLUMINA’S TOTAL LIABILITY TO LICENSEE FOR ALL DAMAGES (OTHER THAN AS MAY BE REQUIRED BY APPLICABLE LAW IN CASES INVOLVING PERSONAL INJURY) EXCEED THE AMOUNT OF $500 USD. THE FOREGOING LIMITATIONS WILL APPLY EVEN IF THE ABOVE STATED REMEDY FAILS OF ITS ESSENTIAL PURPOSE. - -Survival. The limitations of liability and ownership rights of Illumina contained herein and Licensee’s obligations following termination of this Agreement WILL survive the termination of this Agreement for any reason. -Research Use Only. The Software is labeled with a For Research Use Only or similar labeling statement and the performance characteristics of the Software have not been established and the Software is not for use in diagnostic procedures. Licensee acknowledges and agrees that (i) the Software has not been approved, cleared, or licensed by the United States Food and Drug Administration or any other regulatory entity whether foreign or domestic for any specific intended use, whether research, commercial, diagnostic, or otherwise, and (ii) Licensee must ensure it has any regulatory approvals that are necessary for Licensee’s intended uses of the Software. Licensee will comply with all applicable laws and regulations when using and maintaining the Software. -General. Licensee may not sublicense, assign, share, pledge, rent or transfer any of its rights under this Agreement in relation to the Software or any portion thereof including documentation. Illumina reserves the right to change this Agreement at any time. When Illumina makes any changes, Illumina will provide the updated Agreement, or a link to it, on Illumina’s website (www.illumina.com) and such updated Agreement WILL become effective immediately. Licensee’s continued access to or use of the Software represents Licensee’s agreement to any revised Agreement. If one or more provisions of this Agreement are found to be invalid or unenforceable, this Agreement WILL not be rendered inoperative but the remaining provisions WILL continue in full force and effect. This Agreement constitutes the entire agreement between the parties with respect to the subject matter of this Agreement and merges all prior communications except that a “hard-copy” form of licensing agreement relating to the Software previously agreed to in writing by Illumina and Licensee WILL supersede and govern in the event of any conflicting provisions. -Governing Law. This Agreement WILL be governed by and construed in accordance with the laws of the state of California, USA, without regard to its conflicts of laws principles, and independent of where a suit or action hereunder may be filed. -U.S. Government End Users. If Licensee is a branch agency or instrumentality of the United States Government, the following provision applies. The Software is a “commercial item” as that term is defined at 48 C.F.R. 2.101, consisting of “commercial computer software” and “commercial computer software documentation,” as such terms are used in 48 C.F.R. 12.212 or 48 C.F.R. 227.7202 (as applicable). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4, all United States Government end users acquire the Software with only those rights set forth herein. -Contact. Any questions regarding legal rights, duties, obligations, or restrictions associated with the software hereunder should be directed to Illumina, Inc., 5200 Illumina Way, San Diego, CA 92122, Attention: Legal Department, Phone: (858) 202-4500, Fax: (858) 202-4599, web site: www.illumina.com . -Third Party Components. The Software may include third party software (“Third Party Programs”). Some of the Third Party Programs are available under open source or free software licenses. The License Agreement accompanying the Licensed Software does not alter any rights or obligations Licensee may have under those open source or free software licenses. The licenses that govern the terms and conditions of use of the Third Party Programs included in the Licensed Software are provided in the READ ME provided with the Software. The READ ME also contains copyright statements for the various open source software components (or portions thereof) that are distributed with the Licensed Software. -END OF END-USER SOFTWARE LICENSE AGREEMENT. diff --git a/modules/nf-core/bcl2fastq/README.md b/modules/nf-core/bcl2fastq/README.md deleted file mode 100644 index be98aada..00000000 --- a/modules/nf-core/bcl2fastq/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Updating the docker container and making a new module release - -bcl2fastq is a commercial tool from Illumina. The container provided for the bcl2fastq nf-core module is not provided nor supported by Illumina. Updating the bcl2fastq versions in the container and pushing the update to Dockerhub needs to be done manually. - -1. Navigate to the appropriate download page. - [bcl2fastq](https://support.illumina.com/sequencing/sequencing_software/bcl2fastq-conversion-software/downloads.html): download the rpm of the desired bcl2fastq version with `curl` or `wget`. -2. Unpack the RPM package using `rpm2cpio bcl2fastq2-*.rpm | cpio -i --make-directories`. - - Move the executable located in `/usr/bin/bcl2fastq` into the same folder as the Dockerfile. - - Move the `css` and `xsl` directories from `/local/share/` into the same folder as the Dockerfile -3. Create and test the container: - - ```bash - docker build . -t nfcore/bcl2fastq: - ``` - -4. Access rights are needed to push the container to the Dockerhub nfcore organization, please ask a core team member to do so. - - ```bash - docker push nfcore/bcl2fastq: - ``` diff --git a/modules/nf-core/bcl2fastq/main.nf b/modules/nf-core/bcl2fastq/main.nf deleted file mode 100644 index 2759a364..00000000 --- a/modules/nf-core/bcl2fastq/main.nf +++ /dev/null @@ -1,73 +0,0 @@ -process BCL2FASTQ { - tag {"$meta.lane" ? "$meta.id"+"."+"$meta.lane" : "$meta.id" } - label 'process_high' - - container "nf-core/bcl2fastq:2.20.0.422" - - input: - tuple val(meta), path(samplesheet), path(run_dir) - - output: - tuple val(meta), path("output/**_S[1-9]*_R?_00?.fastq.gz") , emit: fastq - tuple val(meta), path("output/**_S[1-9]*_I?_00?.fastq.gz") , optional:true, emit: fastq_idx - tuple val(meta), path("output/**Undetermined_S0*_R?_00?.fastq.gz") , optional:true, emit: undetermined - tuple val(meta), path("output/**Undetermined_S0*_I?_00?.fastq.gz") , optional:true, emit: undetermined_idx - tuple val(meta), path("output/Reports") , emit: reports - tuple val(meta), path("output/Stats") , emit: stats - tuple val(meta), path("InterOp/*.bin") , emit: interop - path("versions.yml") , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - // Exit if running this module with -profile conda / -profile mamba - if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "BCL2FASTQ module does not support Conda. Please use Docker / Singularity / Podman instead." - } - def args = task.ext.args ?: '' - def args2 = task.ext.args2 ?: '' - def args3 = task.ext.args3 ?: '' - def input_tar = run_dir.toString().endsWith(".tar.gz") ? true : false - def input_dir = input_tar ? run_dir.toString() - '.tar.gz' : run_dir - """ - if [ ! -d ${input_dir} ]; then - mkdir -p ${input_dir} - fi - - if ${input_tar}; then - ## Ensures --strip-components only applied when top level of tar contents is a directory - ## If just files or multiple directories, place all in $input_dir - - if [[ \$(tar -taf ${run_dir} | grep -o -P "^.*?\\/" | uniq | wc -l) -eq 1 ]]; then - tar \\ - -C $input_dir --strip-components 1 \\ - -xavf \\ - $args2 \\ - $run_dir \\ - $args3 - else - tar \\ - -C $input_dir \\ - -xavf \\ - $args2 \\ - $run_dir \\ - $args3 - fi - fi - - bcl2fastq \\ - $args \\ - --output-dir output \\ - --runfolder-dir ${input_dir} \\ - --sample-sheet ${samplesheet} \\ - --processing-threads ${task.cpus} - - cp -r ${input_dir}/InterOp . - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bcl2fastq: \$(bcl2fastq -V 2>&1 | grep -m 1 bcl2fastq | sed 's/^.*bcl2fastq v//') - END_VERSIONS - """ -} diff --git a/modules/nf-core/bcl2fastq/meta.yml b/modules/nf-core/bcl2fastq/meta.yml deleted file mode 100644 index a30a33ef..00000000 --- a/modules/nf-core/bcl2fastq/meta.yml +++ /dev/null @@ -1,101 +0,0 @@ -name: "bcl2fastq" -description: Demultiplex Illumina BCL files -keywords: - - demultiplex - - illumina - - fastq -tools: - - "bcl2fastq": - description: "Demultiplex Illumina BCL files" - homepage: "https://support.illumina.com/sequencing/sequencing_software/bcl2fastq-conversion-software" - documentation: "https://support.illumina.com/content/dam/illumina-support/documents/documentation/software_documentation/bcl2fastq/bcl2fastq2-v2-20-software-guide-15051736-03.pdf" - licence: ["ILLUMINA"] - identifier: "" -input: - - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - samplesheet: - type: file - description: "Input samplesheet" - pattern: "*.{csv}" - - run_dir: - type: file - description: | - Input run directory containing RunInfo.xml and BCL data - Could be a directory or a tar of the directory -output: - - fastq: - - meta: - type: file - description: Demultiplexed sample FASTQ files - pattern: "**_S*_L00?_R?_00?.fastq.gz" - - output/**_S[1-9]*_R?_00?.fastq.gz: - type: file - description: Demultiplexed sample FASTQ files - pattern: "**_S*_L00?_R?_00?.fastq.gz" - - fastq_idx: - - meta: - type: file - description: Optional demultiplexed index FASTQ files - pattern: "**_S*_L00?_I?_00?.fastq.gz" - - output/**_S[1-9]*_I?_00?.fastq.gz: - type: file - description: Optional demultiplexed index FASTQ files - pattern: "**_S*_L00?_I?_00?.fastq.gz" - - undetermined: - - meta: - type: file - description: Optional undetermined sample FASTQ files - pattern: "Undetermined_S0_L00?_R?_00?.fastq.gz" - - output/**Undetermined_S0*_R?_00?.fastq.gz: - type: file - description: Optional undetermined sample FASTQ files - pattern: "Undetermined_S0_L00?_R?_00?.fastq.gz" - - undetermined_idx: - - meta: - type: file - description: Optional undetermined index FASTQ files - pattern: "Undetermined_S0_L00?_I?_00?.fastq.gz" - - output/**Undetermined_S0*_I?_00?.fastq.gz: - type: file - description: Optional undetermined index FASTQ files - pattern: "Undetermined_S0_L00?_I?_00?.fastq.gz" - - reports: - - meta: - type: file - description: Demultiplexing Reports - pattern: "Reports/*" - - output/Reports: - type: file - description: Demultiplexing Reports - pattern: "Reports/*" - - stats: - - meta: - type: file - description: Statistics files - pattern: "Stats/*" - - output/Stats: - type: file - description: Statistics files - pattern: "Stats/*" - - interop: - - meta: - type: file - description: Interop files - pattern: "*.{bin}" - - InterOp/*.bin: - type: file - description: Interop files - pattern: "*.{bin}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" -authors: - - "@matthdsm" -maintainers: - - "@matthdsm" diff --git a/modules/nf-core/bcl2fastq/tests/main.nf.test b/modules/nf-core/bcl2fastq/tests/main.nf.test deleted file mode 100644 index d0e0b9a5..00000000 --- a/modules/nf-core/bcl2fastq/tests/main.nf.test +++ /dev/null @@ -1,32 +0,0 @@ -nextflow_process { - - name "Test Process BCL2FASTQ" - script "modules/nf-core/bcl2fastq/main.nf" - process "BCL2FASTQ" - config "./nextflow.config" - tag "bcl2fastq" - tag "modules" - tag "modules_nfcore" - - test("homo sapiens illumina [bcl]") { - when { - process { - //TODO use new test dataset when available, see https://github.com/nf-core/test-datasets/issues/996 - """ - input[0] = [ - [ id: 'test', lane:1 ], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bcl/flowcell_samplesheet.csv', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bcl/flowcell.tar.gz', checkIfExists: true) - ] - """ - } - } - - then { - assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } - ) - } - } -} diff --git a/modules/nf-core/bcl2fastq/tests/main.nf.test.snap b/modules/nf-core/bcl2fastq/tests/main.nf.test.snap deleted file mode 100644 index 8addecc2..00000000 --- a/modules/nf-core/bcl2fastq/tests/main.nf.test.snap +++ /dev/null @@ -1,219 +0,0 @@ -{ - "homo sapiens illumina [bcl]": { - "content": [ - { - "0": [ - [ - { - "id": "test", - "lane": 1 - }, - "Sample1_S1_L001_R1_001.fastq.gz:md5,0675fb6365322eaafb33c0f8e862b54b" - ] - ], - "1": [ - - ], - "2": [ - - ], - "3": [ - - ], - "4": [ - [ - { - "id": "test", - "lane": 1 - }, - [ - [ - [ - [ - [ - [ - "lane.html:md5,794e48287f47a9f22dcb6b6d0c22c3eb", - "laneBarcode.html:md5,2bbdae3ee57151eab520c966597d7438" - ], - [ - - ] - ] - ], - [ - [ - [ - "lane.html:md5,f741870307050dcea79a838f5971770f", - "laneBarcode.html:md5,ffe2e863811c76cb9da27d5d124e0611" - ], - [ - "lane.html:md5,cca97e771d3491dbc8cd3fe389595b09", - "laneBarcode.html:md5,cca97e771d3491dbc8cd3fe389595b09" - ] - ], - [ - [ - "lane.html:md5,c383b0768d9978733d3f5d3b91c15af0", - "laneBarcode.html:md5,48842c23b9a2816aec540177df870968" - ], - [ - - ] - ] - ] - ], - "Report.css:md5,eb7d3eb68fc1539f411404987246b59b", - "index.html:md5,5747c407854ae2c358d0ec201ce622d8", - "tree.html:md5,a1b9bf592973ca829ec69ddf888b7e34" - ] - ] - ] - ], - "5": [ - [ - { - "id": "test", - "lane": 1 - }, - [ - "AdapterTrimming.txt:md5,48ed2b914b1246c0b5d8667525550946", - "ConversionStats.xml:md5,8fe0f57f3f5d256a0762dba75ac62d05", - "DemultiplexingStats.xml:md5,2047ff18f5b9107c084de06e9ff943ad", - "DemuxSummaryF1L1.txt:md5,03e5fd0c1e3079c5f8c7b4d0501b37ff", - "FastqSummaryF1L1.txt:md5,0c6f2d87ee183b84d1051cde9a5643d1", - "Stats.json:md5,8e5f038b8aa9e465599d3575f930e604" - ] - ] - ], - "6": [ - [ - { - "id": "test", - "lane": 1 - }, - [ - "ControlMetricsOut.bin:md5,6d77b38d0793a6e1ce1e85706e488953", - "CorrectedIntMetricsOut.bin:md5,2bbf84d3be72734addaa2fe794711434", - "ErrorMetricsOut.bin:md5,38c88def138e9bb832539911affdb286", - "ExtractionMetricsOut.bin:md5,7497c3178837eea8f09350b5cd252e99", - "IndexMetricsOut.bin:md5,9e688c58a5487b8eaf69c9e1005ad0bf", - "QMetricsOut.bin:md5,7e9f198d53ebdfbb699a5f94cf1ed51c", - "TileMetricsOut.bin:md5,83891751ec1c91a425a524b476b6ca3c" - ] - ] - ], - "7": [ - "versions.yml:md5,12f3dca40b6a65cec6ba51c0fd872152" - ], - "fastq": [ - [ - { - "id": "test", - "lane": 1 - }, - "Sample1_S1_L001_R1_001.fastq.gz:md5,0675fb6365322eaafb33c0f8e862b54b" - ] - ], - "fastq_idx": [ - - ], - "interop": [ - [ - { - "id": "test", - "lane": 1 - }, - [ - "ControlMetricsOut.bin:md5,6d77b38d0793a6e1ce1e85706e488953", - "CorrectedIntMetricsOut.bin:md5,2bbf84d3be72734addaa2fe794711434", - "ErrorMetricsOut.bin:md5,38c88def138e9bb832539911affdb286", - "ExtractionMetricsOut.bin:md5,7497c3178837eea8f09350b5cd252e99", - "IndexMetricsOut.bin:md5,9e688c58a5487b8eaf69c9e1005ad0bf", - "QMetricsOut.bin:md5,7e9f198d53ebdfbb699a5f94cf1ed51c", - "TileMetricsOut.bin:md5,83891751ec1c91a425a524b476b6ca3c" - ] - ] - ], - "reports": [ - [ - { - "id": "test", - "lane": 1 - }, - [ - [ - [ - [ - [ - [ - "lane.html:md5,794e48287f47a9f22dcb6b6d0c22c3eb", - "laneBarcode.html:md5,2bbdae3ee57151eab520c966597d7438" - ], - [ - - ] - ] - ], - [ - [ - [ - "lane.html:md5,f741870307050dcea79a838f5971770f", - "laneBarcode.html:md5,ffe2e863811c76cb9da27d5d124e0611" - ], - [ - "lane.html:md5,cca97e771d3491dbc8cd3fe389595b09", - "laneBarcode.html:md5,cca97e771d3491dbc8cd3fe389595b09" - ] - ], - [ - [ - "lane.html:md5,c383b0768d9978733d3f5d3b91c15af0", - "laneBarcode.html:md5,48842c23b9a2816aec540177df870968" - ], - [ - - ] - ] - ] - ], - "Report.css:md5,eb7d3eb68fc1539f411404987246b59b", - "index.html:md5,5747c407854ae2c358d0ec201ce622d8", - "tree.html:md5,a1b9bf592973ca829ec69ddf888b7e34" - ] - ] - ] - ], - "stats": [ - [ - { - "id": "test", - "lane": 1 - }, - [ - "AdapterTrimming.txt:md5,48ed2b914b1246c0b5d8667525550946", - "ConversionStats.xml:md5,8fe0f57f3f5d256a0762dba75ac62d05", - "DemultiplexingStats.xml:md5,2047ff18f5b9107c084de06e9ff943ad", - "DemuxSummaryF1L1.txt:md5,03e5fd0c1e3079c5f8c7b4d0501b37ff", - "FastqSummaryF1L1.txt:md5,0c6f2d87ee183b84d1051cde9a5643d1", - "Stats.json:md5,8e5f038b8aa9e465599d3575f930e604" - ] - ] - ], - "undetermined": [ - - ], - "undetermined_idx": [ - - ], - "versions": [ - "versions.yml:md5,12f3dca40b6a65cec6ba51c0fd872152" - ] - } - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-05T12:46:23.595844132" - } -} \ No newline at end of file diff --git a/modules/nf-core/bcl2fastq/tests/nextflow.config b/modules/nf-core/bcl2fastq/tests/nextflow.config deleted file mode 100644 index d1985111..00000000 --- a/modules/nf-core/bcl2fastq/tests/nextflow.config +++ /dev/null @@ -1,6 +0,0 @@ -process { - - publishDir = { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" } - - ext.args = "--tiles s_1_1101" -} diff --git a/modules/nf-core/bclconvert/Dockerfile b/modules/nf-core/bclconvert/Dockerfile index 441ebc2f..c5594cf2 100644 --- a/modules/nf-core/bclconvert/Dockerfile +++ b/modules/nf-core/bclconvert/Dockerfile @@ -2,8 +2,26 @@ # Dockerfile to create container with bcl-convert # Push to nfcore/bclconvert: +# Build stage: unpack the RPM file +FROM debian:bullseye-slim AS build +ARG BCLCONVERT_VERSION="4.4.6" + +# Install tools needed to extract RPM +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + rpm2cpio \ + cpio \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Extract bcl-convert from RPM +COPY bcl-convert-4.4.6-2.el8.x86_64.rpm bcl-convert.rpm +RUN rpm2cpio bcl-convert.rpm | cpio -idmv \ + && rm bcl-convert.rpm + +# Final stage: minimal image with only necessary components FROM debian:bullseye-slim -ARG BCLCONVERT_VERSION="4.3.13" +ARG BCLCONVERT_VERSION="4.4.6" LABEL org.opencontainers.image.description="Docker image containing bcl-convert" LABEL org.opencontainers.image.version="$BCLCONVERT_VERSION" LABEL org.opencontainers.image.documentation="https://github.com/nf-core/modules/blob/master/modules/nf-core/bclconvert/README.md" @@ -12,20 +30,16 @@ LABEL org.opencontainers.image.vendor="nf-core" LABEL org.opencontainers.image.license="https://github.com/nf-core/modules/blob/master/modules/nf-core/bclconvert/LICENSE" # Disclaimer: this container is not provided nor supported by Illumina -# 'ps' command is need by some nextflow executions to collect system stats -# Install procps and clean apt cache +# Install procps (for 'ps' command needed by Nextflow) and rclone (for parallel file transfers) RUN apt-get update \ && apt-get install -y --no-install-recommends \ procps \ - rpm2cpio \ - cpio \ + rclone \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* + # Link hostname cmd to fix hardcoded path RUN ln -s /bin/hostname /usr/bin/hostname -# Install bcl-convert -ADD bcl-convert-4.3.13-2.el7.x86_64.rpm bcl-convert.rpm -SHELL ["/bin/bash", "-o", "pipefail", "-c"] -RUN rpm2cpio bcl-convert.rpm | cpio -idmv \ - && rm bcl-convert.rpm -RUN rm -rf /var/log/bcl-convert && ln -sfT /tmp /var/log/bcl-convert + +# Copy bcl-convert executable from build stage +COPY --from=build /usr/bin/bcl-convert /usr/bin/bcl-convert diff --git a/modules/nf-core/bclconvert/main.nf b/modules/nf-core/bclconvert/main.nf index a9bc0197..1b83e5df 100644 --- a/modules/nf-core/bclconvert/main.nf +++ b/modules/nf-core/bclconvert/main.nf @@ -1,21 +1,21 @@ process BCLCONVERT { - tag {"$meta.lane" ? "$meta.id"+"."+"$meta.lane" : "$meta.id" } + tag "${ meta.lane ? meta.id + "." + meta.lane : meta.id }" label 'process_high' - container "nf-core/bclconvert:4.3.13" + container "nf-core/bclconvert:4.4.6" input: tuple val(meta), path(samplesheet), path(run_dir) output: - tuple val(meta), path("output/**_S[1-9]*_R?_00?.fastq.gz") , emit: fastq - tuple val(meta), path("output/**_S[1-9]*_I?_00?.fastq.gz") , optional:true, emit: fastq_idx - tuple val(meta), path("output/**Undetermined_S0*_R?_00?.fastq.gz") , optional:true, emit: undetermined - tuple val(meta), path("output/**Undetermined_S0*_I?_00?.fastq.gz") , optional:true, emit: undetermined_idx - tuple val(meta), path("output/Reports") , emit: reports - tuple val(meta), path("output/Logs") , emit: logs - tuple val(meta), path("**/InterOp/*.bin", includeInputs: true), emit: interop - path("versions.yml") , emit: versions + tuple val(meta), path("output/**_S[1-9]*_R?_00?.fastq.gz"), emit: fastq + tuple val(meta), path("output/**_S[1-9]*_I?_00?.fastq.gz"), emit: fastq_idx, optional: true + tuple val(meta), path("output/**Undetermined_S0*_R?_00?.fastq.gz"), emit: undetermined, optional: true + tuple val(meta), path("output/**Undetermined_S0*_I?_00?.fastq.gz"), emit: undetermined_idx, optional: true + tuple val(meta), path("output/Reports"), emit: reports + tuple val(meta), path("output/Logs"), emit: logs + tuple val(meta), path("output/InterOp/*.bin"), emit: interop, optional: true + tuple val("${task.process}"), val('bclconvert'), eval("bcl-convert -V 2>&1 | head -n 1 | sed 's/^.*Version //'"), topic: versions, emit: versions_bclconvert when: task.ext.when == null || task.ext.when @@ -23,7 +23,7 @@ process BCLCONVERT { script: // Exit if running this module with -profile conda / -profile mamba if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "BCLCONVERT module does not support Conda. Please use Docker / Singularity / Podman instead." + error("BCLCONVERT module does not support Conda. Please use Docker / Singularity / Podman instead.") } def args = task.ext.args ?: '' def args2 = task.ext.args2 ?: '' @@ -37,34 +37,69 @@ process BCLCONVERT { if ${input_tar}; then ## Ensures --strip-components only applied when top level of tar contents is a directory - ## If just files or multiple directories, place all in $input_dir + ## If just files or multiple directories, place all in ${input_dir} if [[ \$(tar -taf ${run_dir} | grep -o -P "^.*?\\/" | uniq | wc -l) -eq 1 ]]; then tar \\ - -C $input_dir --strip-components 1 \\ + -C ${input_dir} --strip-components 1 \\ -xavf \\ - $args2 \\ - $run_dir \\ - $args3 + ${args2} \\ + ${run_dir} \\ + ${args3} else tar \\ - -C $input_dir \\ + -C ${input_dir} \\ -xavf \\ - $args2 \\ - $run_dir \\ - $args3 + ${args2} \\ + ${run_dir} \\ + ${args3} fi fi bcl-convert \\ - $args \\ + ${args} \\ --output-directory output \\ --bcl-input-directory ${input_dir} \\ --sample-sheet ${samplesheet} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bclconvert: \$(bcl-convert -V 2>&1 | head -n 1 | sed 's/^.*Version //') - END_VERSIONS + # copy the InterOp folder contents to ensure it gets picked up when using fusion + mkdir -p output/InterOp/ + cp -n **/InterOp/*.bin output/InterOp/ + """ + + stub: + """ + mkdir -p output + echo "fake fastq file" | gzip > output/Sample1_S1_L001_R1_001.fastq.gz + echo "fake fastq file" | gzip > output/Undetermined_S0_L001_R1_001.fastq.gz + + mkdir -p output/Reports + echo "fake report file" > output/Reports/Adapter_Cycle_Metrics.csv + echo "fake report file" > output/Reports/Adapter_Metrics.csv + echo "fake report file" > output/Reports/Demultiplex_Stats.csv + echo "fake report file" > output/Reports/Demultiplex_Tile_Stats.csv + echo "fake report file" > output/Reports/fastq_list.csv + echo "fake report file" > output/Reports/Index_Hopping_Counts.csv + echo "fake report file" > output/Reports/IndexMetricsOut.bin + echo "fake report file" > output/Reports/Quality_Metrics.csv + echo "fake report file" > output/Reports/Quality_Tile_Metrics.csv + echo "fake report file" > output/Reports/RunInfo.xml + echo "fake report file" > output/Reports/SampleSheet.csv + echo "fake report file" > output/Reports/Top_Unknown_Barcodes.csv + + mkdir -p output/Logs + echo "fake log file" > output/Logs/Errors.log + echo "fake log file" > output/Logs/FastqComplete.log + echo "fake log file" > output/Logs/Info.log + echo "fake log file" > output/Logs/Warnings.log + + mkdir -p output/InterOp + echo "fake InterOp file" > output/InterOp/ControlMetricsOut.bin + echo "fake InterOp file" > output/InterOp/CorrectedIntMetricsOut.bin + echo "fake InterOp file" > output/InterOp/ErrorMetricsOut.bin + echo "fake InterOp file" > output/InterOp/ExtractionMetricsOut.bin + echo "fake InterOp file" > output/InterOp/IndexMetricsOut.bin + echo "fake InterOp file" > output/InterOp/QMetricsOut.bin + echo "fake InterOp file" > output/InterOp/TileMetricsOut.bin """ } diff --git a/modules/nf-core/bclconvert/meta.yml b/modules/nf-core/bclconvert/meta.yml index f40c8768..27f9b1db 100644 --- a/modules/nf-core/bclconvert/meta.yml +++ b/modules/nf-core/bclconvert/meta.yml @@ -9,7 +9,8 @@ tools: description: "Demultiplex Illumina BCL files" homepage: "https://support.illumina.com/sequencing/sequencing_software/bcl-convert.html" documentation: "https://support-docs.illumina.com/SW/BCL_Convert/Content/SW/FrontPages/BCL_Convert.htm" - licence: ["ILLUMINA"] + licence: + - "ILLUMINA" identifier: "" input: - - meta: @@ -22,7 +23,7 @@ input: description: "Input samplesheet" pattern: "*.{csv}" ontologies: - - edam: http://edamontology.org/format_3752 # CSV + - edam: http://edamontology.org/format_3752 #CSV - run_dir: type: file description: | @@ -30,102 +31,99 @@ input: Could be a directory or a tar of the directory ontologies: [] output: - - fastq: - - meta: - type: file - description: Demultiplexed sample FASTQ files - pattern: "**_S*_L00?_R?_00?.fastq.gz" - ontologies: - - edam: http://edamontology.org/format_3989 # GZIP format + fastq: + - - meta: + type: map + description: Groovy Map containing sample information - output/**_S[1-9]*_R?_00?.fastq.gz: type: file description: Demultiplexed sample FASTQ files pattern: "**_S*_L00?_R?_00?.fastq.gz" ontologies: - - edam: http://edamontology.org/format_3989 # GZIP format - - fastq_idx: - - meta: - type: file - description: Optional demultiplexed index FASTQ files - pattern: "**_S*_L00?_I?_00?.fastq.gz" - ontologies: - - edam: http://edamontology.org/format_3989 # GZIP format + - edam: http://edamontology.org/format_1930 #FASTQ + fastq_idx: + - - meta: + type: map + description: Groovy Map containing sample information - output/**_S[1-9]*_I?_00?.fastq.gz: type: file description: Optional demultiplexed index FASTQ files pattern: "**_S*_L00?_I?_00?.fastq.gz" ontologies: - - edam: http://edamontology.org/format_3989 # GZIP format - - undetermined: - - meta: - type: file - description: Optional undetermined sample FASTQ files - pattern: "Undetermined_S0_L00?_R?_00?.fastq.gz" - ontologies: - - edam: http://edamontology.org/format_3989 # GZIP format + - edam: http://edamontology.org/format_1930 #FASTQ + undetermined: + - - meta: + type: map + description: Groovy Map containing sample information - output/**Undetermined_S0*_R?_00?.fastq.gz: type: file description: Optional undetermined sample FASTQ files pattern: "Undetermined_S0_L00?_R?_00?.fastq.gz" ontologies: - - edam: http://edamontology.org/format_3989 # GZIP format - - undetermined_idx: - - meta: - type: file - description: Optional undetermined index FASTQ files - pattern: "Undetermined_S0_L00?_I?_00?.fastq.gz" - ontologies: - - edam: http://edamontology.org/format_3989 # GZIP format + - edam: http://edamontology.org/format_1930 #FASTQ + undetermined_idx: + - - meta: + type: map + description: Groovy Map containing sample information - output/**Undetermined_S0*_I?_00?.fastq.gz: type: file description: Optional undetermined index FASTQ files pattern: "Undetermined_S0_L00?_I?_00?.fastq.gz" ontologies: - - edam: http://edamontology.org/format_3989 # GZIP format - - reports: - - meta: - type: file - description: Demultiplexing Reports - pattern: "Reports/*.{csv,xml}" - ontologies: - - edam: http://edamontology.org/format_3752 # CSV - - edam: http://edamontology.org/format_2332 # XML + - edam: http://edamontology.org/format_1930 #FASTQ + reports: + - - meta: + type: map + description: Groovy Map containing sample information - output/Reports: type: file description: Demultiplexing Reports - pattern: "Reports/*.{csv,xml}" + pattern: "Reports" ontologies: - - edam: http://edamontology.org/format_3752 # CSV - - edam: http://edamontology.org/format_2332 # XML - - logs: - - meta: - type: file - description: Log files - pattern: "Logs/*.{log,txt}" - ontologies: [] + - edam: http://edamontology.org/format_3752 #CSV + - edam: http://edamontology.org/format_2332 #XML + - edam: http://edamontology.org/format_2333 #BINARY + logs: + - - meta: + type: map + description: Groovy Map containing sample information - output/Logs: type: file - description: Log files - pattern: "Logs/*.{log,txt}" - ontologies: [] - - interop: - - meta: - type: file - description: Interop files - pattern: "*.{bin}" - ontologies: [] - - "**/InterOp/*.bin": + description: Demultiplexing Logs + pattern: "Logs" + ontologies: + - edam: http://edamontology.org/format_2330 #TEXT + interop: + - - meta: + type: map + description: Groovy Map containing sample information + - output/InterOp/*.bin: type: file description: Interop files - pattern: "*.{bin}" - ontologies: [] - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + pattern: "InterOp/*.bin" ontologies: - - edam: http://edamontology.org/format_3750 # YAML + - edam: http://edamontology.org/format_2333 #BINARY + versions_bclconvert: + - - ${task.process}: + type: string + description: The name of the process + - bclconvert: + type: string + description: The name of the tool + - bcl-convert -V 2>&1 | head -n 1 | sed 's/^.*Version //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - bclconvert: + type: string + description: The name of the tool + - bcl-convert -V 2>&1 | head -n 1 | sed 's/^.*Version //': + type: eval + description: The expression to obtain the version of the tool authors: - "@matthdsm" maintainers: diff --git a/modules/nf-core/bclconvert/tests/main.nf.test b/modules/nf-core/bclconvert/tests/main.nf.test index b246be20..b1b7acab 100644 --- a/modules/nf-core/bclconvert/tests/main.nf.test +++ b/modules/nf-core/bclconvert/tests/main.nf.test @@ -4,14 +4,17 @@ nextflow_process { script "../main.nf" process "BCLCONVERT" config "./nextflow.config" + tag "bclconvert" tag "modules" tag "modules_nfcore" - test("homo sapiens illumina [bcl]") { + test("homo_sapiens illumina [bcl]") { when { + params { + module_args = "--force --first-tile-only true" + } process { - //TODO use new test dataset when available, see https://github.com/nf-core/test-datasets/issues/996 """ input[0] = [ [ id: 'test', lane:1 ], @@ -26,16 +29,81 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - process.out.reports, - process.out.versions, process.out.fastq, - file(process.out.logs.get(0).get(1)).list().sort(), - process.out.interop.get(0).get(1).findAll { file(it).name != "IndexMetricsOut.bin" }, - ).match() - }, - { assert process.out.undetermined.get(0).get(1) ==~ ".*/Undetermined_S0_L001_R1_001.fastq.gz"}, - { assert file(process.out.interop.get(0).get(1).find { file(it).name == "IndexMetricsOut.bin" }).exists() } + process.out.fastq_idx, + process.out.undetermined.collect { meta, fastq -> file(fastq).name }, + process.out.undetermined_idx, + process.out.reports.collect {meta, dir -> file(dir).name }, + process.out.logs.collect {meta, dir -> file(dir).name }, + process.out.interop.collect {meta, files -> files.collect { file(it).name }.sort() }, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("sars_cov2 illumina [bcl]") { + when { + params { + module_args = "--force --tiles s_1_2101" + } + process { + """ + input[0] = [ + [ id: 'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bcl/SampleSheet.csv', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bcl/200624_A00834_0183_BHMTFYDRXX.tar.gz', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.fastq.collect { + meta, fastqs -> + fastqs.findAll { + fastqfile -> + file(fastqfile).name != "SampleZ_S5_L001_R1_001.fastq.gz" + } + }, + process.out.fastq_idx, + process.out.undetermined.collect { meta, fastq -> file(fastq).name }, + process.out.undetermined_idx, + process.out.reports.collect {meta, dir -> file(dir).name }, + process.out.logs.collect {meta, dir -> file(dir).name }, + process.out.interop.collect {meta, files -> files.collect { file(it).name }.sort() }, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("homo_sapiens illumina [bcl] - stub") { + options "-stub" + + when { + params { + module_args = "--force --first-tile-only true" + } + process { + """ + input[0] = [ + [ id: 'test', lane:1 ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bcl/flowcell_samplesheet.csv', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bcl/flowcell.tar.gz', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } ) } } -} \ No newline at end of file +} diff --git a/modules/nf-core/bclconvert/tests/main.nf.test.snap b/modules/nf-core/bclconvert/tests/main.nf.test.snap index 0c366a2d..b228a5b2 100644 --- a/modules/nf-core/bclconvert/tests/main.nf.test.snap +++ b/modules/nf-core/bclconvert/tests/main.nf.test.snap @@ -1,31 +1,246 @@ { - "homo sapiens illumina [bcl]": { + "sars_cov2 illumina [bcl]": { "content": [ [ [ - { - "id": "test", - "lane": 1 - }, - [ - "Adapter_Cycle_Metrics.csv:md5,5a0c88793b4a0885fe3dda16609b576e", - "Adapter_Metrics.csv:md5,989240b8840b2169ac1061f952c90f6c", - "Demultiplex_Stats.csv:md5,93949a8cd96f907d83e0808c1ec2a04b", - "Demultiplex_Tile_Stats.csv:md5,83120160b0f22a1303fa1db31c19f6e9", - "IndexMetricsOut.bin:md5,9e688c58a5487b8eaf69c9e1005ad0bf", - "Index_Hopping_Counts.csv:md5,1059369e375fd8f8423c0f6c934be978", - "Quality_Metrics.csv:md5,6614accb1bb414fe312b17b81f5521f7", - "Quality_Tile_Metrics.csv:md5,cdc89fd2962bdd4a24f71e186112118a", - "RunInfo.xml:md5,03038959f4dd181c86bc97ae71fe270a", - "SampleSheet.csv:md5,dc0dffd39541dd6cc5b4801d768a8d2b", - "Top_Unknown_Barcodes.csv:md5,2e2faba761137f228e56bd3428453ccc", - "fastq_list.csv:md5,ae1470cd741e33b87a4ad26f849a50f9" - ] + "Sample1_S1_L001_R1_001.fastq.gz:md5,b5489d1964db8db5502eb742cc3ef3ec", + "Sample23_S3_L001_R1_001.fastq.gz:md5,767a1091320320b140288066e29bccc5", + "SampleA_S2_L001_R1_001.fastq.gz:md5,7de2ea88133409f34563f40a0d8c9e55", + "sampletest_S4_L001_R1_001.fastq.gz:md5,c16c7de1b7bffb5e4503f4d94c40f881" ] ], [ - "versions.yml:md5,3a54ec728e3eb67bfd5af57ebd36ccab" + + ], + [ + "Undetermined_S0_L001_R1_001.fastq.gz" + ], + [ + + ], + [ + "Reports" + ], + [ + "Logs" + ], + [ + [ + "BasecallingMetricsOut.bin", + "CorrectedIntMetricsOut.bin", + "EmpiricalPhasingMetricsOut.bin", + "EventMetricsOut.bin", + "ExtendedTileMetricsOut.bin", + "ExtractionMetricsOut.bin", + "FWHMGridMetricsOut.bin", + "ImageMetricsOut.bin", + "IndexMetricsOut.bin", + "OpticalModelMetricsOut.bin", + "PFGridMetricsOut.bin", + "QMetrics2030Out.bin", + "QMetricsByLaneOut.bin", + "QMetricsOut.bin", + "RegistrationMetricsOut.bin", + "TileMetricsOut.bin" + ] ], + { + "versions_bclconvert": [ + [ + "BCLCONVERT", + "bclconvert", + "4.4.6" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.4" + }, + "timestamp": "2026-03-04T20:03:26.54479" + }, + "homo_sapiens illumina [bcl] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "lane": 1 + }, + "Sample1_S1_L001_R1_001.fastq.gz:md5,1495c2d7a9b129c0968b84b149991bfc" + ] + ], + "1": [ + + ], + "2": [ + [ + { + "id": "test", + "lane": 1 + }, + "Undetermined_S0_L001_R1_001.fastq.gz:md5,1495c2d7a9b129c0968b84b149991bfc" + ] + ], + "3": [ + + ], + "4": [ + [ + { + "id": "test", + "lane": 1 + }, + [ + "Adapter_Cycle_Metrics.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "Adapter_Metrics.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "Demultiplex_Stats.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "Demultiplex_Tile_Stats.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "IndexMetricsOut.bin:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "Index_Hopping_Counts.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "Quality_Metrics.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "Quality_Tile_Metrics.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "RunInfo.xml:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "SampleSheet.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "Top_Unknown_Barcodes.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "fastq_list.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656" + ] + ] + ], + "5": [ + [ + { + "id": "test", + "lane": 1 + }, + [ + "Errors.log:md5,775935cbff2e455fde1d28930143e14f", + "FastqComplete.log:md5,775935cbff2e455fde1d28930143e14f", + "Info.log:md5,775935cbff2e455fde1d28930143e14f", + "Warnings.log:md5,775935cbff2e455fde1d28930143e14f" + ] + ] + ], + "6": [ + [ + { + "id": "test", + "lane": 1 + }, + [ + "ControlMetricsOut.bin:md5,c38bb88125390922fc469f5c8432b2a5", + "CorrectedIntMetricsOut.bin:md5,c38bb88125390922fc469f5c8432b2a5", + "ErrorMetricsOut.bin:md5,c38bb88125390922fc469f5c8432b2a5", + "ExtractionMetricsOut.bin:md5,c38bb88125390922fc469f5c8432b2a5", + "IndexMetricsOut.bin:md5,c38bb88125390922fc469f5c8432b2a5", + "QMetricsOut.bin:md5,c38bb88125390922fc469f5c8432b2a5", + "TileMetricsOut.bin:md5,c38bb88125390922fc469f5c8432b2a5" + ] + ] + ], + "7": [ + [ + "BCLCONVERT", + "bclconvert", + "4.4.6" + ] + ], + "fastq": [ + [ + { + "id": "test", + "lane": 1 + }, + "Sample1_S1_L001_R1_001.fastq.gz:md5,1495c2d7a9b129c0968b84b149991bfc" + ] + ], + "fastq_idx": [ + + ], + "interop": [ + [ + { + "id": "test", + "lane": 1 + }, + [ + "ControlMetricsOut.bin:md5,c38bb88125390922fc469f5c8432b2a5", + "CorrectedIntMetricsOut.bin:md5,c38bb88125390922fc469f5c8432b2a5", + "ErrorMetricsOut.bin:md5,c38bb88125390922fc469f5c8432b2a5", + "ExtractionMetricsOut.bin:md5,c38bb88125390922fc469f5c8432b2a5", + "IndexMetricsOut.bin:md5,c38bb88125390922fc469f5c8432b2a5", + "QMetricsOut.bin:md5,c38bb88125390922fc469f5c8432b2a5", + "TileMetricsOut.bin:md5,c38bb88125390922fc469f5c8432b2a5" + ] + ] + ], + "logs": [ + [ + { + "id": "test", + "lane": 1 + }, + [ + "Errors.log:md5,775935cbff2e455fde1d28930143e14f", + "FastqComplete.log:md5,775935cbff2e455fde1d28930143e14f", + "Info.log:md5,775935cbff2e455fde1d28930143e14f", + "Warnings.log:md5,775935cbff2e455fde1d28930143e14f" + ] + ] + ], + "reports": [ + [ + { + "id": "test", + "lane": 1 + }, + [ + "Adapter_Cycle_Metrics.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "Adapter_Metrics.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "Demultiplex_Stats.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "Demultiplex_Tile_Stats.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "IndexMetricsOut.bin:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "Index_Hopping_Counts.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "Quality_Metrics.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "Quality_Tile_Metrics.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "RunInfo.xml:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "SampleSheet.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "Top_Unknown_Barcodes.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656", + "fastq_list.csv:md5,f6efb28f2f9dcd1d0cb85b78f33aa656" + ] + ] + ], + "undetermined": [ + [ + { + "id": "test", + "lane": 1 + }, + "Undetermined_S0_L001_R1_001.fastq.gz:md5,1495c2d7a9b129c0968b84b149991bfc" + ] + ], + "undetermined_idx": [ + + ], + "versions_bclconvert": [ + [ + "BCLCONVERT", + "bclconvert", + "4.4.6" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.4" + }, + "timestamp": "2026-02-17T14:13:11.717962" + }, + "homo_sapiens illumina [bcl]": { + "content": [ [ [ { @@ -36,24 +251,45 @@ ] ], [ - "Errors.log", - "FastqComplete.txt", - "Info.log", - "Warnings.log" + + ], + [ + "Undetermined_S0_L001_R1_001.fastq.gz" + ], + [ + + ], + [ + "Reports" ], [ - "ControlMetricsOut.bin:md5,6d77b38d0793a6e1ce1e85706e488953", - "CorrectedIntMetricsOut.bin:md5,2bbf84d3be72734addaa2fe794711434", - "ErrorMetricsOut.bin:md5,38c88def138e9bb832539911affdb286", - "ExtractionMetricsOut.bin:md5,7497c3178837eea8f09350b5cd252e99", - "QMetricsOut.bin:md5,7e9f198d53ebdfbb699a5f94cf1ed51c", - "TileMetricsOut.bin:md5,83891751ec1c91a425a524b476b6ca3c" - ] + "Logs" + ], + [ + [ + "ControlMetricsOut.bin", + "CorrectedIntMetricsOut.bin", + "ErrorMetricsOut.bin", + "ExtractionMetricsOut.bin", + "IndexMetricsOut.bin", + "QMetricsOut.bin", + "TileMetricsOut.bin" + ] + ], + { + "versions_bclconvert": [ + [ + "BCLCONVERT", + "bclconvert", + "4.4.6" + ] + ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2025-06-02T12:35:36.967547" + "timestamp": "2026-03-04T20:02:51.80369" } -} +} \ No newline at end of file diff --git a/modules/nf-core/bclconvert/tests/nextflow.config b/modules/nf-core/bclconvert/tests/nextflow.config index 344f4720..47e194a6 100644 --- a/modules/nf-core/bclconvert/tests/nextflow.config +++ b/modules/nf-core/bclconvert/tests/nextflow.config @@ -1,10 +1,5 @@ process { - - publishDir = { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" } - - ext.args = {[ - meta.lane ? "--bcl-only-lane ${meta.lane}" : "", - "--force", - "--first-tile-only true" - ].join(" ").trim()} + withName: BCLCONVERT { + ext.args = params.module_args + } } diff --git a/modules/nf-core/biobambam/bamsormadup/biobambam-bamsormadup.diff b/modules/nf-core/biobambam/bamsormadup/biobambam-bamsormadup.diff index 749067c4..92881e2c 100644 --- a/modules/nf-core/biobambam/bamsormadup/biobambam-bamsormadup.diff +++ b/modules/nf-core/biobambam/bamsormadup/biobambam-bamsormadup.diff @@ -1,37 +1,19 @@ -Changes in module 'nf-core/biobambam/bamsormadup' +Changes in component 'nf-core/biobambam/bamsormadup' 'modules/nf-core/biobambam/bamsormadup/environment.yml' is unchanged 'modules/nf-core/biobambam/bamsormadup/meta.yml' is unchanged Changes in 'biobambam/bamsormadup/main.nf': --- modules/nf-core/biobambam/bamsormadup/main.nf +++ modules/nf-core/biobambam/bamsormadup/main.nf -@@ -6,8 +6,7 @@ - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/biobambam:2.0.183--h9f5acd7_1' : 'biocontainers/biobambam:2.0.183--h9f5acd7_1'}" +@@ -8,8 +8,7 @@ + : 'biocontainers/biobambam:2.0.185--h85de650_1'}" input: -- tuple val(meta) , path(bams, stageAs: "?/*") -- tuple val(meta2), path(fasta) -+ tuple val(meta) , path(bams, stageAs: "?/*"), path(fasta) +- tuple val(meta), path(bams, stageAs: "?/*") +- tuple val(meta2), path(fasta), path(fai) ++ tuple val(meta) , path(bams, stageAs: "?/*"), path(fasta), path(fai) output: - tuple val(meta), path("*.bam") ,optional:true, emit: bam -@@ -25,7 +24,7 @@ - def prefix = task.ext.prefix ?: "${meta.id}" - def suffix = args.contains("outputformat=cram") ? "cram" : "bam" - def input_string = bams instanceof List ? bams.join(" I=") : bams -- if (args.contains("outputformat=cram") && reference == null) error "Reference required for CRAM output." -+ if (args.contains("outputformat=cram") && fasta == null) error "Reference required for CRAM output." - - """ - bamcat \\ -@@ -53,7 +52,7 @@ - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def suffix = args.contains("outputformat=cram") ? "cram" : "bam" -- if (args.contains("outputformat=cram") && reference == null) error "Reference required for CRAM output." -+ if (args.contains("outputformat=cram") && fasta == null) error "Reference required for CRAM output." - - """ - touch ${prefix}.${suffix} + tuple val(meta), path("*.bam"), optional: true, emit: bam 'modules/nf-core/biobambam/bamsormadup/tests/main.nf.test.snap' is unchanged 'modules/nf-core/biobambam/bamsormadup/tests/main.nf.test' is unchanged diff --git a/modules/nf-core/biobambam/bamsormadup/environment.yml b/modules/nf-core/biobambam/bamsormadup/environment.yml index eb19895a..948d0ad9 100644 --- a/modules/nf-core/biobambam/bamsormadup/environment.yml +++ b/modules/nf-core/biobambam/bamsormadup/environment.yml @@ -1,5 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::biobambam=2.0.183 + - bioconda::biobambam=2.0.185=h85de650_1 diff --git a/modules/nf-core/biobambam/bamsormadup/main.nf b/modules/nf-core/biobambam/bamsormadup/main.nf index bb6edc3e..804a35c2 100644 --- a/modules/nf-core/biobambam/bamsormadup/main.nf +++ b/modules/nf-core/biobambam/bamsormadup/main.nf @@ -1,19 +1,21 @@ process BIOBAMBAM_BAMSORMADUP { - tag "$meta.id" + tag "${meta.id}" label "process_medium" conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/biobambam:2.0.183--h9f5acd7_1' : 'biocontainers/biobambam:2.0.183--h9f5acd7_1'}" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/biobambam:2.0.185--h85de650_1' + : 'biocontainers/biobambam:2.0.185--h85de650_1'}" input: - tuple val(meta) , path(bams, stageAs: "?/*"), path(fasta) + tuple val(meta) , path(bams, stageAs: "?/*"), path(fasta), path(fai) output: - tuple val(meta), path("*.bam") ,optional:true, emit: bam - tuple val(meta), path("*.bam.bai") ,optional:true, emit: bam_index - tuple val(meta), path("*.cram") ,optional:true, emit: cram - tuple val(meta), path("*.metrics.txt") ,emit: metrics - path "versions.yml" ,emit: versions + tuple val(meta), path("*.bam"), optional: true, emit: bam + tuple val(meta), path("*.bam.bai"), optional: true, emit: bam_index + tuple val(meta), path("*.cram"), optional: true, emit: cram + tuple val(meta), path("*.metrics.txt"), emit: metrics + tuple val("${task.process}"), val('biobambam'), eval("bamsormadup --version |& sed '1!d; s/.*version //; s/.\$//'"), topic: versions, emit: versions_biobambam when: task.ext.when == null || task.ext.when @@ -24,7 +26,9 @@ process BIOBAMBAM_BAMSORMADUP { def prefix = task.ext.prefix ?: "${meta.id}" def suffix = args.contains("outputformat=cram") ? "cram" : "bam" def input_string = bams instanceof List ? bams.join(" I=") : bams - if (args.contains("outputformat=cram") && fasta == null) error "Reference required for CRAM output." + if (args.contains("outputformat=cram") && fasta == null) { + error("Reference required for CRAM output.") + } """ bamcat \\ @@ -32,37 +36,25 @@ process BIOBAMBAM_BAMSORMADUP { level=0 \\ | bamcollate2 \\ level=0 \\ - $args2 \\ + ${args2} \\ | bamsormadup \\ - $args \\ + ${args} \\ M=${prefix}.metrics.txt \\ - tmpfile=$prefix \\ - threads=$task.cpus \\ + tmpfile=${prefix} \\ + threads=${task.cpus} \\ > ${prefix}.${suffix} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bamcat: \$(echo \$(bamcat --version 2>&1) | sed 's/^This is biobambam2 version //; s/..biobambam2 is .*\$//' ) - bamcollate2: \$(echo \$(bamcollate2 --version 2>&1) | sed 's/^This is biobambam2 version //; s/..biobambam2 is .*\$//' ) - bamsormadup: \$(echo \$(bamsormadup --version 2>&1) | sed 's/^This is biobambam2 version //; s/..biobambam2 is .*\$//' ) - END_VERSIONS """ stub: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" def suffix = args.contains("outputformat=cram") ? "cram" : "bam" - if (args.contains("outputformat=cram") && fasta == null) error "Reference required for CRAM output." + if (args.contains("outputformat=cram") && fasta == null) { + error("Reference required for CRAM output.") + } """ touch ${prefix}.${suffix} touch ${prefix}.metrics.txt - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bamcat: \$(echo \$(bamcat --version 2>&1) | sed 's/^This is biobambam2 version //; s/..biobambam2 is .*\$//' ) - bamcollate2: \$(echo \$(bamcollate2 --version 2>&1) | sed 's/^This is biobambam2 version //; s/..biobambam2 is .*\$//' ) - bamsormadup: \$(echo \$(bamsormadup --version 2>&1) | sed 's/^This is biobambam2 version //; s/..biobambam2 is .*\$//' ) - END_VERSIONS """ } diff --git a/modules/nf-core/biobambam/bamsormadup/meta.yml b/modules/nf-core/biobambam/bamsormadup/meta.yml index cfd09d87..fbfb0bbd 100644 --- a/modules/nf-core/biobambam/bamsormadup/meta.yml +++ b/modules/nf-core/biobambam/bamsormadup/meta.yml @@ -12,7 +12,8 @@ tools: homepage: https://gitlab.com/german.tischler/biobambam2 documentation: https://gitlab.com/german.tischler/biobambam2/-/blob/master/README.md doi: 10.1186/1751-0473-9-13 - licence: ["GPL v3"] + licence: + - "GPL v3" identifier: "" input: - - meta: @@ -23,6 +24,8 @@ input: - bams: type: file description: List containing 1 or more bam files + ontologies: + - edam: http://edamontology.org/format_2572 - - meta2: type: map description: | @@ -32,9 +35,17 @@ input: type: file description: Reference genome in FASTA format (optional) pattern: "*.{fa,fasta,fna}" + ontologies: + - edam: http://edamontology.org/format_1929 + - fai: + type: file + description: Reference genome in FASTA index format (optional) + pattern: "*.{fai}" + ontologies: + - edam: http://edamontology.org/format_3673 output: - - bam: - - meta: + bam: + - - meta: type: map description: | Groovy Map containing sample information @@ -43,8 +54,10 @@ output: type: file description: BAM file with duplicate reads marked/removed pattern: "*.bam" - - bam_index: - - meta: + ontologies: + - edam: http://edamontology.org/format_2572 + bam_index: + - - meta: type: map description: | Groovy Map containing sample information @@ -53,8 +66,10 @@ output: type: file description: BAM index file pattern: "*.bai" - - cram: - - meta: + ontologies: + - edam: http://edamontology.org/format_3692 + cram: + - - meta: type: map description: | Groovy Map containing sample information @@ -63,8 +78,10 @@ output: type: file description: CRAM file with duplicate reads marked/removed pattern: "*.cram" - - metrics: - - meta: + ontologies: + - edam: http://edamontology.org/format_3674 + metrics: + - - meta: type: map description: | Groovy Map containing sample information @@ -73,11 +90,29 @@ output: type: file description: Duplicate metrics file generated by biobambam pattern: "*.{metrics.txt}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3675 + versions_biobambam: + - - ${task.process}: + type: string + description: The name of the process + - biobambam: + type: string + description: The name of the tool + - bamsormadup --version |& sed '1!d; s/.*version //; s/.\$//': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - biobambam: + type: string + description: The name of the tool + - bamsormadup --version |& sed '1!d; s/.*version //; s/.\$//': + type: eval + description: The expression to obtain the version of the tool authors: - "@matthdsm" maintainers: diff --git a/modules/nf-core/biobambam/bamsormadup/tests/main.nf.test b/modules/nf-core/biobambam/bamsormadup/tests/main.nf.test index 43272ff1..0b65a21c 100644 --- a/modules/nf-core/biobambam/bamsormadup/tests/main.nf.test +++ b/modules/nf-core/biobambam/bamsormadup/tests/main.nf.test @@ -16,14 +16,13 @@ nextflow_process { process { """ input[0] = [ - [ id:'test', single_end:false ], // meta map - [ + [ id:'test', single_end:false ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) ] - ] - input[1] = [[:],[]] - + ] + input[1] = [[:],[],[]] """ } } @@ -32,13 +31,12 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - bam(process.out.bam[0][1]).getReadsMD5(), - process.out.bam_index, - process.out.cram, - file(process.out.metrics[0][1]).readLines()[3..5], - process.out.versions - ).match() - } + bam(process.out.bam[0][1]).getReadsMD5(), + process.out.bam_index, + process.out.cram, + file(process.out.metrics[0][1]).readLines()[3..5], + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } } @@ -49,13 +47,12 @@ nextflow_process { process { """ input[0] = [ - [ id:'test', single_end:false ], // meta map - [ + [ id:'test', single_end:false ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) ] - ] - input[1] = [[:],[]] - + ] + input[1] = [[:],[],[]] """ } } @@ -64,13 +61,12 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - bam(process.out.bam[0][1]).getReadsMD5(), - process.out.bam_index, - process.out.cram, - file(process.out.metrics[0][1]).readLines()[3..5], - process.out.versions - ).match() - } + bam(process.out.bam[0][1]).getReadsMD5(), + process.out.bam_index, + process.out.cram, + file(process.out.metrics[0][1]).readLines()[3..5], + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } } @@ -83,13 +79,12 @@ nextflow_process { process { """ input[0] = [ - [ id:'test', single_end:false ], // meta map - [ + [ id:'test', single_end:false ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) ] - ] - input[1] = [[:],[]] - + ] + input[1] = [[:],[],[]] """ } } @@ -97,7 +92,10 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + process.out, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } ) } } diff --git a/modules/nf-core/biobambam/bamsormadup/tests/main.nf.test.snap b/modules/nf-core/biobambam/bamsormadup/tests/main.nf.test.snap index f7a41ca6..a56a7949 100644 --- a/modules/nf-core/biobambam/bamsormadup/tests/main.nf.test.snap +++ b/modules/nf-core/biobambam/bamsormadup/tests/main.nf.test.snap @@ -13,15 +13,21 @@ "lib1\t3\t97\t3\t0\t0\t0\t0\t-1", "" ], - [ - "versions.yml:md5,67ab301f20567acd9d0e648c2a3e158c" - ] + { + "versions_biobambam": [ + [ + "BIOBAMBAM_BAMSORMADUP", + "biobambam", + "2.0.185" + ] + ] + } ], + "timestamp": "2026-02-18T12:29:21.145687", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-05T22:00:39.772883" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test-biobambam-bamsormadup-multi-input": { "content": [ @@ -37,15 +43,21 @@ "lib1\t3\t97\t3\t0\t0\t0\t0\t-1", "testN\t0\t2820\t2\t0\t828\t0\t0.293617\t3807" ], - [ - "versions.yml:md5,67ab301f20567acd9d0e648c2a3e158c" - ] + { + "versions_biobambam": [ + [ + "BIOBAMBAM_BAMSORMADUP", + "biobambam", + "2.0.185" + ] + ] + } ], + "timestamp": "2026-02-18T12:29:10.9703", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-05T22:00:31.187999" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test-biobambam-bamsormadup-single-input-stub": { "content": [ @@ -75,7 +87,11 @@ ] ], "4": [ - "versions.yml:md5,67ab301f20567acd9d0e648c2a3e158c" + [ + "BIOBAMBAM_BAMSORMADUP", + "biobambam", + "2.0.185" + ] ], "bam": [ [ @@ -101,15 +117,28 @@ "test.metrics.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,67ab301f20567acd9d0e648c2a3e158c" + "versions_biobambam": [ + [ + "BIOBAMBAM_BAMSORMADUP", + "biobambam", + "2.0.185" + ] + ] + }, + { + "versions_biobambam": [ + [ + "BIOBAMBAM_BAMSORMADUP", + "biobambam", + "2.0.185" + ] ] } ], + "timestamp": "2026-02-18T12:29:25.8377", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-05T21:57:13.430982" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/bowtie2/align/bowtie2-align.diff b/modules/nf-core/bowtie2/align/bowtie2-align.diff index 1a6f0ab5..33d3a5cf 100644 --- a/modules/nf-core/bowtie2/align/bowtie2-align.diff +++ b/modules/nf-core/bowtie2/align/bowtie2-align.diff @@ -1,11 +1,11 @@ -Changes in module 'nf-core/bowtie2/align' +Changes in component 'nf-core/bowtie2/align' 'modules/nf-core/bowtie2/align/environment.yml' is unchanged 'modules/nf-core/bowtie2/align/meta.yml' is unchanged Changes in 'bowtie2/align/main.nf': --- modules/nf-core/bowtie2/align/main.nf +++ modules/nf-core/bowtie2/align/main.nf @@ -8,9 +8,7 @@ - 'biocontainers/mulled-v2-ac74a7f02cebcfcc07d8e8d1d750af9c83b4d45a:f70b31a2db15c023d641c32f433fb02cd04df5a6-0' }" + 'community.wave.seqera.io/library/bowtie2_htslib_samtools_pigz:edeb13799090a2a6' }" input: - tuple val(meta) , path(reads) @@ -19,7 +19,6 @@ Changes in 'bowtie2/align/main.nf': 'modules/nf-core/bowtie2/align/tests/main.nf.test.snap' is unchanged 'modules/nf-core/bowtie2/align/tests/large_index.config' is unchanged 'modules/nf-core/bowtie2/align/tests/sam2.config' is unchanged -'modules/nf-core/bowtie2/align/tests/tags.yml' is unchanged 'modules/nf-core/bowtie2/align/tests/main.nf.test' is unchanged 'modules/nf-core/bowtie2/align/tests/sam.config' is unchanged 'modules/nf-core/bowtie2/align/tests/cram_crai.config' is unchanged diff --git a/modules/nf-core/bowtie2/align/main.nf b/modules/nf-core/bowtie2/align/main.nf index 4f153522..36383249 100644 --- a/modules/nf-core/bowtie2/align/main.nf +++ b/modules/nf-core/bowtie2/align/main.nf @@ -20,7 +20,9 @@ process BOWTIE2_ALIGN { tuple val(meta), path("*.crai") , emit: crai , optional:true tuple val(meta), path("*.log") , emit: log tuple val(meta), path("*fastq.gz") , emit: fastq , optional:true - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('bowtie2'), eval("bowtie2 --version 2>&1 | sed -n '1s/.*bowtie2-align-s version //p'"), emit: versions_bowtie2, topic: versions + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), emit: versions_samtools, topic: versions + tuple val("${task.process}"), val('pigz'), eval("pigz --version 2>&1 | sed 's/pigz //'"), emit: versions_pigz, topic: versions when: task.ext.when == null || task.ext.when @@ -29,6 +31,7 @@ process BOWTIE2_ALIGN { def args = task.ext.args ?: "" def args2 = task.ext.args2 ?: "" def prefix = task.ext.prefix ?: "${meta.id}" + def rg = args.contains("--rg-id") ? "" : "--rg-id ${prefix} --rg SM:${prefix}" def unaligned = "" def reads_args = "" @@ -57,6 +60,7 @@ process BOWTIE2_ALIGN { $reads_args \\ --threads $task.cpus \\ $unaligned \\ + $rg \\ $args \\ 2>| >(tee ${prefix}.bowtie2.log >&2) \\ | samtools $samtools_command $args2 --threads $task.cpus ${reference} -o ${prefix}.${extension} - @@ -68,13 +72,6 @@ process BOWTIE2_ALIGN { if [ -f ${prefix}.unmapped.fastq.2.gz ]; then mv ${prefix}.unmapped.fastq.2.gz ${prefix}.unmapped_2.fastq.gz fi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bowtie2: \$(echo \$(bowtie2 --version 2>&1) | sed 's/^.*bowtie2-align-s version //; s/ .*\$//') - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - pigz: \$( pigz --version 2>&1 | sed 's/pigz //g' ) - END_VERSIONS """ stub: @@ -102,13 +99,6 @@ process BOWTIE2_ALIGN { ${create_index} touch ${prefix}.bowtie2.log ${create_unmapped} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bowtie2: \$(echo \$(bowtie2 --version 2>&1) | sed 's/^.*bowtie2-align-s version //; s/ .*\$//') - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - pigz: \$( pigz --version 2>&1 | sed 's/pigz //g' ) - END_VERSIONS """ } diff --git a/modules/nf-core/bowtie2/align/meta.yml b/modules/nf-core/bowtie2/align/meta.yml index 7436097b..2d8051da 100644 --- a/modules/nf-core/bowtie2/align/meta.yml +++ b/modules/nf-core/bowtie2/align/meta.yml @@ -14,7 +14,7 @@ tools: sequencing reads to long reference sequences. homepage: http://bowtie-bio.sourceforge.net/bowtie2/index.shtml documentation: http://bowtie-bio.sourceforge.net/bowtie2/manual.shtml - doi: 10.1038/nmeth.1923 + doi: 10.1186/gb-2009-10-3-r25 licence: ["GPL-3.0-or-later"] identifier: "" input: @@ -28,6 +28,7 @@ input: description: | List of input FastQ files of size 1 and 2 for single-end and paired-end data, respectively. + ontologies: [] - - meta2: type: map description: | @@ -37,6 +38,7 @@ input: type: file description: Bowtie2 genome index files pattern: "*.ebwt" + ontologies: [] - - meta3: type: map description: | @@ -46,84 +48,142 @@ input: type: file description: Bowtie2 genome fasta file pattern: "*.fasta" - - - save_unaligned: - type: boolean - description: | - Save reads that do not map to the reference (true) or discard them (false) - (default: false) - - - sort_bam: - type: boolean - description: use samtools sort (true) or samtools view (false) - pattern: "true or false" + ontologies: [] + - save_unaligned: + type: boolean + description: | + Save reads that do not map to the reference (true) or discard them (false) + (default: false) + - sort_bam: + type: boolean + description: use samtools sort (true) or samtools view (false) + pattern: "true or false" output: - - sam: - - meta: - type: file - description: Output SAM file containing read alignments - pattern: "*.sam" + sam: + - - meta: + type: map + description: Groovy Map containing sample information - "*.sam": type: file description: Output SAM file containing read alignments pattern: "*.sam" - - bam: - - meta: - type: file - description: Output BAM file containing read alignments - pattern: "*.bam" + ontologies: [] + bam: + - - meta: + type: map + description: Groovy Map containing sample information - "*.bam": type: file description: Output BAM file containing read alignments pattern: "*.bam" - - cram: - - meta: - type: file - description: Output CRAM file containing read alignments - pattern: "*.cram" + ontologies: [] + cram: + - - meta: + type: map + description: Groovy Map containing sample information - "*.cram": type: file description: Output CRAM file containing read alignments pattern: "*.cram" - - csi: - - meta: - type: file - description: Output SAM/BAM index for large inputs - pattern: "*.csi" + ontologies: [] + csi: + - - meta: + type: map + description: Groovy Map containing sample information - "*.csi": type: file description: Output SAM/BAM index for large inputs pattern: "*.csi" - - crai: - - meta: - type: file - description: Output CRAM index - pattern: "*.crai" + ontologies: [] + crai: + - - meta: + type: map + description: Groovy Map containing sample information - "*.crai": type: file description: Output CRAM index pattern: "*.crai" - - log: - - meta: - type: file - description: Alignment log - pattern: "*.log" + ontologies: [] + log: + - - meta: + type: map + description: Groovy Map containing sample information - "*.log": type: file description: Alignment log pattern: "*.log" - - fastq: - - meta: - type: file - description: Unaligned FastQ files - pattern: "*.fastq.gz" + ontologies: [] + fastq: + - - meta: + type: map + description: Groovy Map containing sample information - "*fastq.gz": type: file description: Unaligned FastQ files pattern: "*.fastq.gz" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + versions_bowtie2: + - - ${task.process}: + type: string + description: The name of the process + - bowtie2: + type: string + description: The name of the tool + - "bowtie2 --version 2>&1 | sed -n '1s/.*bowtie2-align-s version //p'": + type: eval + description: The expression to obtain the version of bowtie2 + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - "samtools version | sed '1!d;s/.* //'": + type: eval + description: The expression to obtain the version of samtools + versions_pigz: + - - ${task.process}: + type: string + description: The name of the process + - pigz: + type: string + description: The name of the tool + - "pigz --version 2>&1 | sed 's/pigz //'": + type: eval + description: The expression to obtain the version of pigz + +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - bowtie2: + type: string + description: The name of the tool + - "bowtie2 --version 2>&1 | sed -n '1s/.*bowtie2-align-s version //p'": + type: eval + description: The expression to obtain the version of bowtie2 + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - "samtools version | sed '1!d;s/.* //'": + type: eval + description: The expression to obtain the version of samtools + - - ${task.process}: + type: string + description: The name of the process + - pigz: + type: string + description: The name of the tool + - "pigz --version 2>&1 | sed 's/pigz //'": + type: eval + description: The expression to obtain the version of pigz + authors: - "@joseespinosa" - "@drpatelh" diff --git a/modules/nf-core/bowtie2/align/tests/large_index.config b/modules/nf-core/bowtie2/align/tests/large_index.config index fdc1c59d..b2f0c405 100644 --- a/modules/nf-core/bowtie2/align/tests/large_index.config +++ b/modules/nf-core/bowtie2/align/tests/large_index.config @@ -2,4 +2,4 @@ process { withName: BOWTIE2_BUILD { ext.args = '--large-index' } -} \ No newline at end of file +} diff --git a/modules/nf-core/bowtie2/align/tests/main.nf.test b/modules/nf-core/bowtie2/align/tests/main.nf.test index 0de5950f..1705b66d 100644 --- a/modules/nf-core/bowtie2/align/tests/main.nf.test +++ b/modules/nf-core/bowtie2/align/tests/main.nf.test @@ -47,7 +47,7 @@ nextflow_process { file(process.out.bam[0][1]).name, process.out.log, process.out.fastq, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } @@ -93,7 +93,7 @@ nextflow_process { file(process.out.sam[0][1]).readLines()[0..4], process.out.log, process.out.fastq, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } @@ -139,7 +139,7 @@ nextflow_process { file(process.out.sam[0][1]).readLines()[0..4], process.out.log, process.out.fastq, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } @@ -184,7 +184,7 @@ nextflow_process { file(process.out.bam[0][1]).name, process.out.log, process.out.fastq, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } @@ -232,7 +232,7 @@ nextflow_process { file(process.out.bam[0][1]).name, process.out.log, process.out.fastq, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } @@ -280,7 +280,7 @@ nextflow_process { file(process.out.bam[0][1]).name, process.out.log, process.out.fastq, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } @@ -326,7 +326,7 @@ nextflow_process { file(process.out.bam[0][1]).name, process.out.log, process.out.fastq, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } @@ -375,7 +375,7 @@ nextflow_process { file(process.out.bam[0][1]).name, process.out.log, process.out.fastq, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } @@ -423,7 +423,7 @@ nextflow_process { file(process.out.bam[0][1]).name, process.out.log, process.out.fastq, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } @@ -468,7 +468,7 @@ nextflow_process { file(process.out.bam[0][1]).name, process.out.log, process.out.fastq, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) @@ -566,7 +566,7 @@ nextflow_process { file(process.out.csi[0][1]).name, file(process.out.log[0][1]).name, process.out.fastq, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } @@ -613,7 +613,7 @@ nextflow_process { file(process.out.csi[0][1]).name, file(process.out.log[0][1]).name, process.out.fastq, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } diff --git a/modules/nf-core/bowtie2/align/tests/main.nf.test.snap b/modules/nf-core/bowtie2/align/tests/main.nf.test.snap index 4ffd62e9..b1df41e7 100644 --- a/modules/nf-core/bowtie2/align/tests/main.nf.test.snap +++ b/modules/nf-core/bowtie2/align/tests/main.nf.test.snap @@ -14,24 +14,44 @@ [ ], - [ - "versions.yml:md5,2768d626cdb54c9a9b5ed7aecbc3ca11" - ] + { + "versions_bowtie2": [ + [ + "BOWTIE2_ALIGN", + "bowtie2", + "2.5.4" + ] + ], + "versions_pigz": [ + [ + "BOWTIE2_ALIGN", + "pigz", + "2.8" + ] + ], + "versions_samtools": [ + [ + "BOWTIE2_ALIGN", + "samtools", + "1.21" + ] + ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2025-03-24T12:45:59.038637" + "timestamp": "2026-02-03T15:18:12.706444258" }, "sarscov2 - fastq, index, fasta, false, false - sam2": { "content": [ [ - "ERR5069949.2151832\t16\tMT192765.1\t17453\t42\t150M\t*\t0\t0\tACGCACATTGCTAACTAAGGGCACACTAGAACCAGAATATTTCAATTCAGTGTGTAGACTTATGAAAACTATAGGTCCAGACATGTTCCTCGGAACTTGTCGGCGTTGTCCTGCTGAAATTGTTGACACTGTGAGTGCTTTGGTTTATGA\tAAAA&1 | sed -n "s/^Version: //p"'), topic: versions, emit: versions_bwa + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), topic: versions, emit: versions_samtools when: task.ext.when == null || task.ext.when @@ -42,12 +43,6 @@ process BWA_MEM { \$INDEX \\ $reads \\ | samtools $samtools_command $args2 ${reference} --threads $task.cpus -o ${prefix}.${extension} - - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bwa: \$(echo \$(bwa 2>&1) | sed 's/^.*Version: //; s/Contact:.*\$//') - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ stub: @@ -62,11 +57,5 @@ process BWA_MEM { touch ${prefix}.${extension} touch ${prefix}.csi touch ${prefix}.crai - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bwa: \$(echo \$(bwa 2>&1) | sed 's/^.*Version: //; s/Contact:.*\$//') - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/bwa/mem/meta.yml b/modules/nf-core/bwa/mem/meta.yml index b6f696c0..450a3fe9 100644 --- a/modules/nf-core/bwa/mem/meta.yml +++ b/modules/nf-core/bwa/mem/meta.yml @@ -16,7 +16,8 @@ tools: homepage: http://bio-bwa.sourceforge.net/ documentation: https://bio-bwa.sourceforge.net/bwa.shtml arxiv: arXiv:1303.3997 - licence: ["GPL-3.0-or-later"] + licence: + - "GPL-3.0-or-later" identifier: "biotools:bwa" input: - - meta: @@ -30,8 +31,8 @@ input: List of input FastQ files of size 1 and 2 for single-end and paired-end data, respectively. ontologies: - - edam: "http://edamontology.org/data_2044" # Sequence - - edam: "http://edamontology.org/format_1930" # FASTQ + - edam: "http://edamontology.org/data_2044" + - edam: "http://edamontology.org/format_1930" - - meta2: type: map description: | @@ -42,7 +43,7 @@ input: description: BWA genome index files pattern: "Directory containing BWA index *.{amb,ann,bwt,pac,sa}" ontologies: - - edam: "http://edamontology.org/data_3210" # Genome index + - edam: "http://edamontology.org/data_3210" - - meta3: type: map description: | @@ -53,54 +54,91 @@ input: description: Reference genome in FASTA format pattern: "*.{fasta,fa}" ontologies: - - edam: "http://edamontology.org/data_2044" # Sequence - - edam: "http://edamontology.org/format_1929" # FASTA - - - sort_bam: - type: boolean - description: use samtools sort (true) or samtools view (false) - pattern: "true or false" + - edam: "http://edamontology.org/data_2044" + - edam: "http://edamontology.org/format_1929" + - sort_bam: + type: boolean + description: use samtools sort (true) or samtools view (false) + pattern: "true or false" output: - - bam: - - meta: - type: file - description: Output BAM file containing read alignments + bam: + - - meta: + type: map + description: Groovy Map containing sample information - "*.bam": type: file description: Output BAM file containing read alignments pattern: "*.{bam}" ontologies: - - edam: "http://edamontology.org/format_2572" # BAM - - cram: - - meta: - type: file - description: Output CRAM file containing read alignments + - edam: "http://edamontology.org/format_2572" + cram: + - - meta: + type: map + description: Groovy Map containing sample information - "*.cram": type: file description: Output CRAM file containing read alignments pattern: "*.{cram}" ontologies: - - edam: "http://edamontology.org/format_3462" # CRAM - - csi: - - meta: - type: file - description: Optional index file for BAM file + - edam: "http://edamontology.org/format_3462" + csi: + - - meta: + type: map + description: Groovy Map containing sample information - "*.csi": type: file description: Optional index file for BAM file pattern: "*.{csi}" - - crai: - - meta: - type: file - description: Optional index file for CRAM file + ontologies: [] + crai: + - - meta: + type: map + description: Groovy Map containing sample information - "*.crai": type: file description: Optional index file for CRAM file pattern: "*.{crai}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_bwa: + - - ${task.process}: + type: string + description: The name of the process + - bwa: + type: string + description: The name of the tool + - 'bwa 2>&1 | sed -n "s/^Version: //p"': + type: eval + description: The expression to obtain the version of the tool + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - bwa: + type: string + description: The name of the tool + - 'bwa 2>&1 | sed -n "s/^Version: //p"': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool authors: - "@drpatelh" - "@jeremy1805" diff --git a/modules/nf-core/bwa/mem/tests/main.nf.test b/modules/nf-core/bwa/mem/tests/main.nf.test index 5de2c2f4..6486ab00 100644 --- a/modules/nf-core/bwa/mem/tests/main.nf.test +++ b/modules/nf-core/bwa/mem/tests/main.nf.test @@ -48,8 +48,7 @@ nextflow_process { process.out.cram, process.out.csi, process.out.crai, - process.out.versions, - bam(process.out.bam[0][1]).getHeaderMD5(), + process.out.findAll { key, val -> key.startsWith("versions") }, bam(process.out.bam[0][1]).getReadsMD5() ).match() } @@ -83,8 +82,7 @@ nextflow_process { process.out.cram, process.out.csi, process.out.crai, - process.out.versions, - bam(process.out.bam[0][1]).getHeaderMD5(), + process.out.findAll { key, val -> key.startsWith("versions") }, bam(process.out.bam[0][1]).getReadsMD5() ).match() } @@ -119,8 +117,7 @@ nextflow_process { process.out.cram, process.out.csi, process.out.crai, - process.out.versions, - bam(process.out.bam[0][1]).getHeaderMD5(), + process.out.findAll { key, val -> key.startsWith("versions") }, bam(process.out.bam[0][1]).getReadsMD5() ).match() } @@ -155,8 +152,7 @@ nextflow_process { process.out.cram, process.out.csi, process.out.crai, - process.out.versions, - bam(process.out.bam[0][1]).getHeaderMD5(), + process.out.findAll { key, val -> key.startsWith("versions") }, bam(process.out.bam[0][1]).getReadsMD5() ).match() } @@ -191,8 +187,7 @@ nextflow_process { process.out.cram, process.out.csi, process.out.crai, - process.out.versions, - bam(process.out.bam[0][1]).getHeaderMD5(), + process.out.findAll { key, val -> key.startsWith("versions") }, bam(process.out.bam[0][1]).getReadsMD5() ).match() } diff --git a/modules/nf-core/bwa/mem/tests/main.nf.test.snap b/modules/nf-core/bwa/mem/tests/main.nf.test.snap index 3aaefdda..8aca4b23 100644 --- a/modules/nf-core/bwa/mem/tests/main.nf.test.snap +++ b/modules/nf-core/bwa/mem/tests/main.nf.test.snap @@ -10,17 +10,29 @@ [ ], - [ - "versions.yml:md5,c60680eba0f00e791c0d5a0a6e9d665f" - ], - "53df0e7b72f1f85fb28af5fec435246", + { + "versions_bwa": [ + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "versions_samtools": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] + ] + }, "798439cbd7fd81cbcc5078022dc5479d" ], + "timestamp": "2026-02-18T12:42:52.901827", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-27T08:36:00.831642964" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "Single-End Sort": { "content": [ @@ -33,17 +45,29 @@ [ ], - [ - "versions.yml:md5,c60680eba0f00e791c0d5a0a6e9d665f" - ], - "5eca502b75fefc26e8000908bf0bb3a3", + { + "versions_bwa": [ + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "versions_samtools": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] + ] + }, "94fcf617f5b994584c4e8d4044e16b4f" ], + "timestamp": "2026-02-18T12:43:01.149915", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-27T08:36:16.025706238" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "Paired-End": { "content": [ @@ -56,17 +80,29 @@ [ ], - [ - "versions.yml:md5,c60680eba0f00e791c0d5a0a6e9d665f" - ], - "fec2aafbba4637767bc4e202c71aee58", + { + "versions_bwa": [ + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "versions_samtools": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] + ] + }, "57aeef88ed701a8ebc8e2f0a381b2a6" ], + "timestamp": "2026-02-18T12:43:09.528042", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-27T08:36:27.309924644" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "Paired-End Sort": { "content": [ @@ -79,17 +115,29 @@ [ ], - [ - "versions.yml:md5,c60680eba0f00e791c0d5a0a6e9d665f" - ], - "d5ad8844218280969c1f9349bd62d057", + { + "versions_bwa": [ + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "versions_samtools": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] + ] + }, "af8628d9df18b2d3d4f6fd47ef2bb872" ], + "timestamp": "2026-02-18T12:43:17.876121", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-27T08:36:45.448624985" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "Single-end - stub": { "content": [ @@ -125,7 +173,18 @@ ] ], "4": [ - "versions.yml:md5,c60680eba0f00e791c0d5a0a6e9d665f" + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "5": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] ], "bam": [ [ @@ -157,16 +216,27 @@ "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,c60680eba0f00e791c0d5a0a6e9d665f" + "versions_bwa": [ + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "versions_samtools": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] ] } ], + "timestamp": "2026-02-18T12:43:33.853248", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-27T08:37:16.211123969" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "Paired-End - no fasta": { "content": [ @@ -179,17 +249,29 @@ [ ], - [ - "versions.yml:md5,c60680eba0f00e791c0d5a0a6e9d665f" - ], - "fec2aafbba4637767bc4e202c71aee58", + { + "versions_bwa": [ + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "versions_samtools": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] + ] + }, "57aeef88ed701a8ebc8e2f0a381b2a6" ], + "timestamp": "2026-02-18T12:43:26.121474", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-27T08:36:56.592159657" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "Paired-end - stub": { "content": [ @@ -225,7 +307,18 @@ ] ], "4": [ - "versions.yml:md5,c60680eba0f00e791c0d5a0a6e9d665f" + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "5": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] ], "bam": [ [ @@ -257,15 +350,26 @@ "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,c60680eba0f00e791c0d5a0a6e9d665f" + "versions_bwa": [ + [ + "BWA_MEM", + "bwa", + "0.7.19-r1273" + ] + ], + "versions_samtools": [ + [ + "BWA_MEM", + "samtools", + "1.22.1" + ] ] } ], + "timestamp": "2026-02-18T12:43:42.119907", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-27T08:37:32.177177506" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/bwamem2/mem/bwamem2-mem.diff b/modules/nf-core/bwamem2/mem/bwamem2-mem.diff index 7c300098..579c37ca 100644 --- a/modules/nf-core/bwamem2/mem/bwamem2-mem.diff +++ b/modules/nf-core/bwamem2/mem/bwamem2-mem.diff @@ -1,22 +1,23 @@ -Changes in module 'nf-core/bwamem2/mem' +Changes in component 'nf-core/bwamem2/mem' 'modules/nf-core/bwamem2/mem/environment.yml' is unchanged 'modules/nf-core/bwamem2/mem/meta.yml' is unchanged Changes in 'bwamem2/mem/main.nf': --- modules/nf-core/bwamem2/mem/main.nf +++ modules/nf-core/bwamem2/mem/main.nf -@@ -8,9 +8,7 @@ - 'biocontainers/mulled-v2-e5d375990341c5aef3c9aff74f96f66f65375ef6:2d15960ccea84e249a150b7f5d4db3a42fc2d6c3-0' }" +@@ -8,10 +8,8 @@ + : 'community.wave.seqera.io/library/bwa-mem2_htslib_samtools:db98f81f55b64113'}" input: - tuple val(meta), path(reads) - tuple val(meta2), path(index) - tuple val(meta3), path(fasta) +- val sort_bam + tuple val(meta), path(reads), path(index), path(fasta) - val sort_bam ++ val sort_bam output: + tuple val(meta), path("*.sam"), emit: sam, optional: true 'modules/nf-core/bwamem2/mem/tests/main.nf.test.snap' is unchanged -'modules/nf-core/bwamem2/mem/tests/tags.yml' is unchanged 'modules/nf-core/bwamem2/mem/tests/main.nf.test' is unchanged ************************************************************ diff --git a/modules/nf-core/bwamem2/mem/environment.yml b/modules/nf-core/bwamem2/mem/environment.yml index c069e281..f3637444 100644 --- a/modules/nf-core/bwamem2/mem/environment.yml +++ b/modules/nf-core/bwamem2/mem/environment.yml @@ -6,8 +6,8 @@ channels: dependencies: # renovate: datasource=conda depName=bioconda/bwa-mem2 - - bwa-mem2=2.2.1 + - bwa-mem2=2.3 # renovate: datasource=conda depName=bioconda/htslib - - htslib=1.21 + - htslib=1.22.1 # renovate: datasource=conda depName=bioconda/samtools - - samtools=1.21 + - samtools=1.22.1 diff --git a/modules/nf-core/bwamem2/mem/main.nf b/modules/nf-core/bwamem2/mem/main.nf index 41e2252a..e8846da3 100644 --- a/modules/nf-core/bwamem2/mem/main.nf +++ b/modules/nf-core/bwamem2/mem/main.nf @@ -1,23 +1,24 @@ process BWAMEM2_MEM { - tag "$meta.id" + tag "${meta.id}" label 'process_high' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/9a/9ac054213e67b3c9308e409b459080bbe438f8fd6c646c351bc42887f35a42e7/data' : - 'community.wave.seqera.io/library/bwa-mem2_htslib_samtools:e1f420694f8e42bd' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/e0/e05ce34b46ad42810eb29f74e4e304c0cb592b2ca15572929ed8bbaee58faf01/data' + : 'community.wave.seqera.io/library/bwa-mem2_htslib_samtools:db98f81f55b64113'}" input: tuple val(meta), path(reads), path(index), path(fasta) val sort_bam output: - tuple val(meta), path("*.sam") , emit: sam , optional:true - tuple val(meta), path("*.bam") , emit: bam , optional:true - tuple val(meta), path("*.cram") , emit: cram, optional:true - tuple val(meta), path("*.crai") , emit: crai, optional:true - tuple val(meta), path("*.csi") , emit: csi , optional:true - path "versions.yml" , emit: versions + tuple val(meta), path("*.sam"), emit: sam, optional: true + tuple val(meta), path("*.bam"), emit: bam, optional: true + tuple val(meta), path("*.cram"), emit: cram, optional: true + tuple val(meta), path("*.crai"), emit: crai, optional: true + tuple val(meta), path("*.csi"), emit: csi, optional: true + tuple val("${task.process}"), val('bwamem2'), eval('bwa-mem2 version | grep -o -E "[0-9]+(\\.[0-9]+)+"'), emit: versions_bwamem2, topic: versions + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), emit: versions_samtools, topic: versions when: task.ext.when == null || task.ext.when @@ -29,53 +30,43 @@ process BWAMEM2_MEM { def samtools_command = sort_bam ? 'sort' : 'view' def extension_pattern = /(--output-fmt|-O)+\s+(\S+)/ - def extension_matcher = (args2 =~ extension_pattern) + def extension_matcher = (args2 =~ extension_pattern) def extension = extension_matcher.getCount() > 0 ? extension_matcher[0][2].toLowerCase() : "bam" - def reference = fasta && extension=="cram" ? "--reference ${fasta}" : "" - if (!fasta && extension=="cram") error "Fasta reference is required for CRAM output" - + def reference = fasta && extension == "cram" ? "--reference ${fasta}" : "" + if (!fasta && extension == "cram") { + error("Fasta reference is required for CRAM output") + } """ INDEX=`find -L ./ -name "*.amb" | sed 's/\\.amb\$//'` bwa-mem2 \\ mem \\ - $args \\ - -t $task.cpus \\ + ${args} \\ + -t ${task.cpus} \\ \$INDEX \\ - $reads \\ - | samtools $samtools_command $args2 -@ $task.cpus ${reference} -o ${prefix}.${extension} - - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bwamem2: \$(echo \$(bwa-mem2 version 2>&1) | sed 's/.* //') - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS + ${reads} \\ + | samtools ${samtools_command} ${args2} -@ ${task.cpus} ${reference} -o ${prefix}.${extension} - """ stub: - def args2 = task.ext.args2 ?: '' def prefix = task.ext.prefix ?: "${meta.id}" def extension_pattern = /(--output-fmt|-O)+\s+(\S+)/ - def extension_matcher = (args2 =~ extension_pattern) + def extension_matcher = (args2 =~ extension_pattern) def extension = extension_matcher.getCount() > 0 ? extension_matcher[0][2].toLowerCase() : "bam" - if (!fasta && extension=="cram") error "Fasta reference is required for CRAM output" + if (!fasta && extension == "cram") { + error("Fasta reference is required for CRAM output") + } def create_index = "" if (extension == "cram") { create_index = "touch ${prefix}.crai" - } else if (extension == "bam") { + } + else if (extension == "bam") { create_index = "touch ${prefix}.csi" } - """ touch ${prefix}.${extension} ${create_index} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - bwamem2: \$(echo \$(bwa-mem2 version 2>&1) | sed 's/.* //') - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/bwamem2/mem/meta.yml b/modules/nf-core/bwamem2/mem/meta.yml index d17e0dbd..a60d6788 100644 --- a/modules/nf-core/bwamem2/mem/meta.yml +++ b/modules/nf-core/bwamem2/mem/meta.yml @@ -16,7 +16,8 @@ tools: homepage: https://github.com/bwa-mem2/bwa-mem2 documentation: http://www.htslib.org/doc/samtools.html arxiv: arXiv:1303.3997 - licence: ["MIT"] + licence: + - "MIT" identifier: "biotools:bwa-mem2" input: - - meta: @@ -30,8 +31,8 @@ input: List of input FastQ files of size 1 and 2 for single-end and paired-end data, respectively. ontologies: - - edam: "http://edamontology.org/data_2044" # Sequence - - edam: "http://edamontology.org/format_1930" # FASTQ + - edam: "http://edamontology.org/data_2044" + - edam: "http://edamontology.org/format_1930" - - meta2: type: map description: | @@ -42,7 +43,7 @@ input: description: BWA genome index files pattern: "Directory containing BWA index *.{0132,amb,ann,bwt.2bit.64,pac}" ontologies: - - edam: "http://edamontology.org/data_3210" # Genome index + - edam: "http://edamontology.org/data_3210" - - meta3: type: map description: | @@ -53,15 +54,15 @@ input: description: Reference genome in FASTA format pattern: "*.{fa,fasta,fna}" ontologies: - - edam: "http://edamontology.org/data_2044" # Sequence - - edam: "http://edamontology.org/format_1929" # FASTA - - - sort_bam: - type: boolean - description: use samtools sort (true) or samtools view (false) - pattern: "true or false" + - edam: "http://edamontology.org/data_2044" + - edam: "http://edamontology.org/format_1929" + - sort_bam: + type: boolean + description: use samtools sort (true) or samtools view (false) + pattern: "true or false" output: - - sam: - - meta: + sam: + - - meta: type: map description: | Groovy Map containing sample information @@ -71,9 +72,9 @@ output: description: Output SAM file containing read alignments pattern: "*.{sam}" ontologies: - - edam: "http://edamontology.org/format_2573" # SAM - - bam: - - meta: + - edam: "http://edamontology.org/format_2573" + bam: + - - meta: type: map description: | Groovy Map containing sample information @@ -83,9 +84,9 @@ output: description: Output BAM file containing read alignments pattern: "*.{bam}" ontologies: - - edam: "http://edamontology.org/format_2572" # BAM - - cram: - - meta: + - edam: "http://edamontology.org/format_2572" + cram: + - - meta: type: map description: | Groovy Map containing sample information @@ -95,9 +96,9 @@ output: description: Output CRAM file containing read alignments pattern: "*.{cram}" ontologies: - - edam: "http://edamontology.org/format_3462" # CRAM - - crai: - - meta: + - edam: "http://edamontology.org/format_3462" + crai: + - - meta: type: map description: | Groovy Map containing sample information @@ -106,8 +107,9 @@ output: type: file description: Index file for CRAM file pattern: "*.{crai}" - - csi: - - meta: + ontologies: [] + csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -116,11 +118,47 @@ output: type: file description: Index file for BAM file pattern: "*.{csi}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_bwamem2: + - - ${task.process}: + type: string + description: The name of the process + - bwamem2: + type: string + description: The name of the tool + - bwa-mem2 version | grep -o -E "[0-9]+(\.[0-9]+)+": + type: eval + description: The expression to obtain the version of the tool + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - bwamem2: + type: string + description: The name of the tool + - bwa-mem2 version | grep -o -E "[0-9]+(\.[0-9]+)+": + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool authors: - "@maxulysse" - "@matthdsm" diff --git a/modules/nf-core/bwamem2/mem/tests/main.nf.test b/modules/nf-core/bwamem2/mem/tests/main.nf.test index 9e0ab14a..be33a3a7 100644 --- a/modules/nf-core/bwamem2/mem/tests/main.nf.test +++ b/modules/nf-core/bwamem2/mem/tests/main.nf.test @@ -46,11 +46,10 @@ nextflow_process { { assert snapshot( bam(process.out.bam[0][1]).getHeaderMD5(), bam(process.out.bam[0][1]).getReadsMD5(), - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } - } test("sarscov2 - fastq, index, fasta, true") { @@ -75,11 +74,10 @@ nextflow_process { { assert snapshot( bam(process.out.bam[0][1]).getHeaderMD5(), bam(process.out.bam[0][1]).getReadsMD5(), - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } - } test("sarscov2 - [fastq1, fastq2], index, fasta, false") { @@ -107,11 +105,10 @@ nextflow_process { { assert snapshot( bam(process.out.bam[0][1]).getHeaderMD5(), bam(process.out.bam[0][1]).getReadsMD5(), - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } - } test("sarscov2 - [fastq1, fastq2], index, fasta, true") { @@ -139,11 +136,10 @@ nextflow_process { { assert snapshot( bam(process.out.bam[0][1]).getHeaderMD5(), bam(process.out.bam[0][1]).getReadsMD5(), - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions")} ).match() } ) } - } test("sarscov2 - [fastq1, fastq2], index, fasta, true - stub") { @@ -170,10 +166,8 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(sanitizeOutput(process.out)).match() } ) } - } - } diff --git a/modules/nf-core/bwamem2/mem/tests/main.nf.test.snap b/modules/nf-core/bwamem2/mem/tests/main.nf.test.snap index ec90701f..06d854b0 100644 --- a/modules/nf-core/bwamem2/mem/tests/main.nf.test.snap +++ b/modules/nf-core/bwamem2/mem/tests/main.nf.test.snap @@ -1,51 +1,34 @@ { "sarscov2 - [fastq1, fastq2], index, fasta, false": { "content": [ - "9505760d66e1d5a5d34ab79a98228c6", + "e414c2d48e2e44c2c52c20ecd88e8bd8", "57aeef88ed701a8ebc8e2f0a381b2a6", - [ - "versions.yml:md5,ca1b1dcf82b92fb0751816fca16a477a" - ] - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-27T10:57:52.782442426" - }, - "sarscov2 - [fastq1, fastq2], index, fasta, true - stub": { - "content": [ { - "0": [ - - ], - "1": [ + "versions_bwamem2": [ [ - { - "id": "test", - "single_end": false - }, - "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "BWAMEM2_MEM", + "bwamem2", + "2.2.1" ] ], - "2": [ - - ], - "3": [ - - ], - "4": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + "BWAMEM2_MEM", + "samtools", + "1.22.1" ] - ], - "5": [ - "versions.yml:md5,ca1b1dcf82b92fb0751816fca16a477a" - ], + ] + } + ], + "timestamp": "2026-02-19T11:51:27.481278728", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "sarscov2 - [fastq1, fastq2], index, fasta, true - stub": { + "content": [ + { "bam": [ [ { @@ -73,57 +56,107 @@ "sam": [ ], - "versions": [ - "versions.yml:md5,ca1b1dcf82b92fb0751816fca16a477a" + "versions_bwamem2": [ + [ + "BWAMEM2_MEM", + "bwamem2", + "2.2.1" + ] + ], + "versions_samtools": [ + [ + "BWAMEM2_MEM", + "samtools", + "1.22.1" + ] ] } ], + "timestamp": "2026-02-19T11:54:06.902806102", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-27T10:58:37.140104324" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "sarscov2 - [fastq1, fastq2], index, fasta, true": { "content": [ - "e0c38d5772ca5f4d5d9999f4477e933c", + "716ed1ef39deaad346ca7cf86e08f959", "af8628d9df18b2d3d4f6fd47ef2bb872", - [ - "versions.yml:md5,ca1b1dcf82b92fb0751816fca16a477a" - ] + { + "versions_bwamem2": [ + [ + "BWAMEM2_MEM", + "bwamem2", + "2.2.1" + ] + ], + "versions_samtools": [ + [ + "BWAMEM2_MEM", + "samtools", + "1.22.1" + ] + ] + } ], + "timestamp": "2026-02-19T11:51:40.483217643", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-27T10:58:19.047052261" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "sarscov2 - fastq, index, fasta, false": { "content": [ - "58d05395bbb819e929885bde415947ae", + "283a83f604f3f5338acedfee349dccf4", "798439cbd7fd81cbcc5078022dc5479d", - [ - "versions.yml:md5,ca1b1dcf82b92fb0751816fca16a477a" - ] + { + "versions_bwamem2": [ + [ + "BWAMEM2_MEM", + "bwamem2", + "2.2.1" + ] + ], + "versions_samtools": [ + [ + "BWAMEM2_MEM", + "samtools", + "1.22.1" + ] + ] + } ], + "timestamp": "2026-02-19T11:51:02.459481643", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-27T10:56:53.456559296" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "sarscov2 - fastq, index, fasta, true": { "content": [ - "276189f6f003f99a87664e74fad2893d", + "ed99048bb552cac58e39923b550b6d5b", "94fcf617f5b994584c4e8d4044e16b4f", - [ - "versions.yml:md5,ca1b1dcf82b92fb0751816fca16a477a" - ] + { + "versions_bwamem2": [ + [ + "BWAMEM2_MEM", + "bwamem2", + "2.2.1" + ] + ], + "versions_samtools": [ + [ + "BWAMEM2_MEM", + "samtools", + "1.22.1" + ] + ] + } ], + "timestamp": "2026-02-19T11:51:15.170720681", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-27T10:57:21.949711746" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/dragmap/align/dragmap-align.diff b/modules/nf-core/dragmap/align/dragmap-align.diff index 60188aab..cf4c75e6 100644 --- a/modules/nf-core/dragmap/align/dragmap-align.diff +++ b/modules/nf-core/dragmap/align/dragmap-align.diff @@ -1,22 +1,23 @@ -Changes in module 'nf-core/dragmap/align' +Changes in component 'nf-core/dragmap/align' 'modules/nf-core/dragmap/align/environment.yml' is unchanged 'modules/nf-core/dragmap/align/meta.yml' is unchanged Changes in 'dragmap/align/main.nf': --- modules/nf-core/dragmap/align/main.nf +++ modules/nf-core/dragmap/align/main.nf -@@ -8,9 +8,7 @@ - 'biocontainers/mulled-v2-580d344d9d4a496cd403932da8765f9e0187774d:7eed251370ac7f3537c3d9472cdb2f9f5d8da1c5-0' }" +@@ -9,10 +9,8 @@ + : 'biocontainers/mulled-v2-580d344d9d4a496cd403932da8765f9e0187774d:df80ed8d23d0a2c43181a2b3dd1b39f2d00fab5c-0'}" input: -- tuple val(meta) , path(reads) +- tuple val(meta), path(reads) - tuple val(meta2), path(hashmap) - tuple val(meta3), path(fasta) +- val sort_bam + tuple val(meta) , path(reads), path(hashmap), path(fasta) - val sort_bam ++ val sort_bam output: + tuple val(meta), path("*.sam"), emit: sam, optional: true 'modules/nf-core/dragmap/align/tests/main.nf.test.snap' is unchanged -'modules/nf-core/dragmap/align/tests/tags.yml' is unchanged 'modules/nf-core/dragmap/align/tests/main.nf.test' is unchanged ************************************************************ diff --git a/modules/nf-core/dragmap/align/main.nf b/modules/nf-core/dragmap/align/main.nf index 2529cbca..a0abf087 100644 --- a/modules/nf-core/dragmap/align/main.nf +++ b/modules/nf-core/dragmap/align/main.nf @@ -19,7 +19,9 @@ process DRAGMAP_ALIGN { tuple val(meta), path("*.crai"), emit: crai, optional: true tuple val(meta), path("*.csi"), emit: csi, optional: true tuple val(meta), path('*.log'), emit: log - path "versions.yml", emit: versions + tuple val("${task.process}"), val('dragmap'), eval("dragen-os --version 2>&1"), emit: versions_dragmap, topic: versions + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), emit: versions_samtools, topic: versions + tuple val("${task.process}"), val('pigz'), eval("pigz --version 2>&1 | sed 's/pigz //'"), emit: versions_pigz, topic: versions when: task.ext.when == null || task.ext.when @@ -46,13 +48,6 @@ process DRAGMAP_ALIGN { ${reads_command} \\ 2>| >(tee ${prefix}.dragmap.log >&2) \\ | samtools ${samtools_command} ${args2} --threads ${task.cpus} ${reference} -o ${prefix}.${extension} - - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - dragmap: \$(echo \$(dragen-os --version 2>&1)) - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - pigz: \$( pigz --version 2>&1 | sed 's/pigz //g' ) - END_VERSIONS """ stub: @@ -77,12 +72,5 @@ process DRAGMAP_ALIGN { touch ${prefix}.${extension} ${create_index} touch ${prefix}.log - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - dragmap: \$(echo \$(dragen-os --version 2>&1)) - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - pigz: \$( pigz --version 2>&1 | sed 's/pigz //g' ) - END_VERSIONS """ } diff --git a/modules/nf-core/dragmap/align/meta.yml b/modules/nf-core/dragmap/align/meta.yml index 80f020f5..bdb7f00a 100644 --- a/modules/nf-core/dragmap/align/meta.yml +++ b/modules/nf-core/dragmap/align/meta.yml @@ -12,7 +12,8 @@ tools: homepage: https://github.com/Illumina/dragmap documentation: https://github.com/Illumina/dragmap tool_dev_url: https://github.com/Illumina/dragmap#basic-command-line-usage - licence: ["GPL v3"] + licence: + - "GPL v3" identifier: "" input: - - meta: @@ -25,6 +26,8 @@ input: description: | List of input FastQ files of size 1 and 2 for single-end and paired-end data, respectively. + ontologies: + - edam: http://edamontology.org/format_1930 - - meta2: type: map description: | @@ -34,6 +37,7 @@ input: type: file description: DRAGMAP hash table pattern: "Directory containing DRAGMAP hash table *.{cmp,.bin,.txt}" + ontologies: [] - - meta3: type: map description: | @@ -43,12 +47,14 @@ input: type: file description: Genome fasta reference files pattern: "*.{fa,fasta,fna}" - - - sort_bam: - type: boolean - description: Sort the BAM file + ontologies: + - edam: http://edamontology.org/format_1929 + - sort_bam: + type: boolean + description: Sort the BAM file output: - - sam: - - meta: + sam: + - - meta: type: map description: | Groovy Map containing sample information @@ -57,17 +63,22 @@ output: type: file description: Output SAM file containing read alignments pattern: "*.{sam}" - - bam: - - meta: - type: file - description: Output BAM file containing read alignments - pattern: "*.{bam}" + ontologies: + - edam: http://edamontology.org/format_2571 + bam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] - "*.bam": type: file description: Output BAM file containing read alignments pattern: "*.{bam}" - - cram: - - meta: + ontologies: + - edam: http://edamontology.org/format_2572 + cram: + - - meta: type: map description: | Groovy Map containing sample information @@ -76,8 +87,10 @@ output: type: file description: Output CRAM file containing read alignments pattern: "*.{cram}" - - crai: - - meta: + ontologies: + - edam: http://edamontology.org/format_2573 + crai: + - - meta: type: map description: | Groovy Map containing sample information @@ -86,8 +99,9 @@ output: type: file description: Index file for CRAM file pattern: "*.{crai}" - - csi: - - meta: + ontologies: [] + csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -96,8 +110,9 @@ output: type: file description: Index file for CRAM file pattern: "*.{csi}" - - log: - - meta: + ontologies: [] + log: + - - meta: type: map description: | Groovy Map containing sample information @@ -106,11 +121,67 @@ output: type: file description: Log file pattern: "*.{log}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3888 + versions_dragmap: + - - ${task.process}: + type: string + description: The name of the process + - dragmap: + type: string + description: The name of the tool + - dragen-os --version 2>&1: + type: eval + description: The expression to obtain the version of the tool + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool + versions_pigz: + - - ${task.process}: + type: string + description: The name of the process + - pigz: + type: string + description: The name of the tool + - pigz --version 2>&1 | sed 's/pigz //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - dragmap: + type: string + description: The name of the tool + - dragen-os --version 2>&1: + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - pigz: + type: string + description: The name of the tool + - pigz --version 2>&1 | sed 's/pigz //': + type: eval + description: The expression to obtain the version of the tool authors: - "@edmundmiller" maintainers: diff --git a/modules/nf-core/dragmap/align/tests/main.nf.test b/modules/nf-core/dragmap/align/tests/main.nf.test index 5abe76f6..5e8b5baa 100644 --- a/modules/nf-core/dragmap/align/tests/main.nf.test +++ b/modules/nf-core/dragmap/align/tests/main.nf.test @@ -45,8 +45,7 @@ nextflow_process { { assert snapshot( file(process.out.bam[0][1]).name, file(process.out.log[0][1]).readLines().findAll { it.startsWith("decompHash") }, - process.out.versions, - path(process.out.versions[0]).yaml + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } @@ -89,8 +88,7 @@ nextflow_process { { assert snapshot( file(process.out.bam[0][1]).name, file(process.out.log[0][1]).readLines().findAll { it.startsWith("decompHash") }, - process.out.versions, - path(process.out.versions[0]).yaml + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } @@ -136,8 +134,7 @@ nextflow_process { { assert snapshot( file(process.out.bam[0][1]).name, file(process.out.log[0][1]).readLines().findAll { it.startsWith("decompHash") }, - process.out.versions, - path(process.out.versions[0]).yaml + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } @@ -183,8 +180,7 @@ nextflow_process { { assert snapshot( file(process.out.bam[0][1]).name, file(process.out.log[0][1]).readLines().findAll { it.startsWith("decompHash") }, - process.out.versions, - path(process.out.versions[0]).yaml + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } @@ -230,8 +226,7 @@ nextflow_process { { assert snapshot( file(process.out.bam[0][1]).name, file(process.out.log[0][1]).readLines().findAll { it.startsWith("decompHash") }, - process.out.versions, - path(process.out.versions[0]).yaml + process.out.findAll { key, val -> key.startsWith("versions") }, ).match() } ) } @@ -277,7 +272,6 @@ nextflow_process { assertAll ( { assert snapshot( process.out, - path(process.out.versions[0]).yaml ).match() } ) } diff --git a/modules/nf-core/dragmap/align/tests/main.nf.test.snap b/modules/nf-core/dragmap/align/tests/main.nf.test.snap index 9a63fde0..4b355a0a 100644 --- a/modules/nf-core/dragmap/align/tests/main.nf.test.snap +++ b/modules/nf-core/dragmap/align/tests/main.nf.test.snap @@ -10,22 +10,35 @@ "decompHashTableAutoHits...", "decompHashTableSetFlags..." ], - [ - "versions.yml:md5,bec50713b6dac1cc16fe68b731848394" - ], { - "DRAGMAP_ALIGN": { - "dragmap": "1.2.1", - "samtools": "1.19.2", - "pigz": "2.3.4" - } + "versions_dragmap": [ + [ + "DRAGMAP_ALIGN", + "dragmap", + "1.2.1" + ] + ], + "versions_pigz": [ + [ + "DRAGMAP_ALIGN", + "pigz", + "2.3.4" + ] + ], + "versions_samtools": [ + [ + "DRAGMAP_ALIGN", + "samtools", + "1.19.2" + ] + ] } ], + "timestamp": "2026-02-18T13:37:09.601416", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-04-10T11:33:50.428894432" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "homo_sapiens - [fastq1, fastq2], hashtable, fasta, true": { "content": [ @@ -38,22 +51,35 @@ "decompHashTableAutoHits...", "decompHashTableSetFlags..." ], - [ - "versions.yml:md5,bec50713b6dac1cc16fe68b731848394" - ], { - "DRAGMAP_ALIGN": { - "dragmap": "1.2.1", - "samtools": "1.19.2", - "pigz": "2.3.4" - } + "versions_dragmap": [ + [ + "DRAGMAP_ALIGN", + "dragmap", + "1.2.1" + ] + ], + "versions_pigz": [ + [ + "DRAGMAP_ALIGN", + "pigz", + "2.3.4" + ] + ], + "versions_samtools": [ + [ + "DRAGMAP_ALIGN", + "samtools", + "1.19.2" + ] + ] } ], + "timestamp": "2026-02-18T13:37:59.385197", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-04-10T11:34:27.492548556" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "sarscov2 - fastq, hashtable, fasta, true": { "content": [ @@ -66,22 +92,35 @@ "decompHashTableAutoHits...", "decompHashTableSetFlags..." ], - [ - "versions.yml:md5,bec50713b6dac1cc16fe68b731848394" - ], { - "DRAGMAP_ALIGN": { - "dragmap": "1.2.1", - "samtools": "1.19.2", - "pigz": "2.3.4" - } + "versions_dragmap": [ + [ + "DRAGMAP_ALIGN", + "dragmap", + "1.2.1" + ] + ], + "versions_pigz": [ + [ + "DRAGMAP_ALIGN", + "pigz", + "2.3.4" + ] + ], + "versions_samtools": [ + [ + "DRAGMAP_ALIGN", + "samtools", + "1.19.2" + ] + ] } ], + "timestamp": "2026-02-18T13:37:02.623362", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-04-10T11:33:39.843877739" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "sarscov2 - [fastq1, fastq2], hashtable, fasta, true": { "content": [ @@ -94,22 +133,35 @@ "decompHashTableAutoHits...", "decompHashTableSetFlags..." ], - [ - "versions.yml:md5,bec50713b6dac1cc16fe68b731848394" - ], { - "DRAGMAP_ALIGN": { - "dragmap": "1.2.1", - "samtools": "1.19.2", - "pigz": "2.3.4" - } + "versions_dragmap": [ + [ + "DRAGMAP_ALIGN", + "dragmap", + "1.2.1" + ] + ], + "versions_pigz": [ + [ + "DRAGMAP_ALIGN", + "pigz", + "2.3.4" + ] + ], + "versions_samtools": [ + [ + "DRAGMAP_ALIGN", + "samtools", + "1.19.2" + ] + ] } ], + "timestamp": "2026-02-18T13:37:16.491006", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-04-10T11:34:00.702498161" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "sarscov2 - [fastq1, fastq2], hashtable, fasta, true - stub": { "content": [ @@ -151,7 +203,25 @@ ] ], "6": [ - "versions.yml:md5,bec50713b6dac1cc16fe68b731848394" + [ + "DRAGMAP_ALIGN", + "dragmap", + "1.2.1" + ] + ], + "7": [ + [ + "DRAGMAP_ALIGN", + "samtools", + "1.19.2" + ] + ], + "8": [ + [ + "DRAGMAP_ALIGN", + "pigz", + "2.3.4" + ] ], "bam": [ [ @@ -189,23 +259,34 @@ "sam": [ ], - "versions": [ - "versions.yml:md5,bec50713b6dac1cc16fe68b731848394" + "versions_dragmap": [ + [ + "DRAGMAP_ALIGN", + "dragmap", + "1.2.1" + ] + ], + "versions_pigz": [ + [ + "DRAGMAP_ALIGN", + "pigz", + "2.3.4" + ] + ], + "versions_samtools": [ + [ + "DRAGMAP_ALIGN", + "samtools", + "1.19.2" + ] ] - }, - { - "DRAGMAP_ALIGN": { - "dragmap": "1.2.1", - "samtools": "1.19.2", - "pigz": "2.3.4" - } } ], + "timestamp": "2026-02-18T13:38:06.245799", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-04-10T11:13:17.187912755" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "sarscov2 - fastq, hashtable, fasta, false": { "content": [ @@ -218,21 +299,34 @@ "decompHashTableAutoHits...", "decompHashTableSetFlags..." ], - [ - "versions.yml:md5,bec50713b6dac1cc16fe68b731848394" - ], { - "DRAGMAP_ALIGN": { - "dragmap": "1.2.1", - "samtools": "1.19.2", - "pigz": "2.3.4" - } + "versions_dragmap": [ + [ + "DRAGMAP_ALIGN", + "dragmap", + "1.2.1" + ] + ], + "versions_pigz": [ + [ + "DRAGMAP_ALIGN", + "pigz", + "2.3.4" + ] + ], + "versions_samtools": [ + [ + "DRAGMAP_ALIGN", + "samtools", + "1.19.2" + ] + ] } ], + "timestamp": "2026-02-18T13:36:55.869439", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-04-10T11:33:28.056988229" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/samtools/cat/environment.yml b/modules/nf-core/falco/environment.yml similarity index 76% rename from modules/nf-core/samtools/cat/environment.yml rename to modules/nf-core/falco/environment.yml index 62054fc9..1fc00675 100644 --- a/modules/nf-core/samtools/cat/environment.yml +++ b/modules/nf-core/falco/environment.yml @@ -4,5 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.21 - - bioconda::samtools=1.21 + - bioconda::falco=1.2.5 diff --git a/modules/nf-core/falco/main.nf b/modules/nf-core/falco/main.nf new file mode 100644 index 00000000..860d52ff --- /dev/null +++ b/modules/nf-core/falco/main.nf @@ -0,0 +1,42 @@ +process FALCO { + tag "${meta.id}" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/falco:1.2.5--h077b44d_0' + : 'biocontainers/falco:1.2.5--h077b44d_0'}" + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*.html"), emit: html + tuple val(meta), path("*.txt"), emit: txt + tuple val("${task.process}"), val('falco'), eval("falco --version | sed '1!d;s/.* //'"), topic: versions, emit: versions_falco + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + if (reads.toList().size() == 1) { + """ + falco ${args} --threads ${task.cpus} ${reads} -D ${prefix}_fastqc_data.txt -S ${prefix}_summary.txt -R ${prefix}_report.html + """ + } + else { + """ + falco ${args} --threads ${task.cpus} ${reads} + """ + } + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}_data.txt + touch ${prefix}_fastqc_data.html + touch ${prefix}_summary.txt + """ +} diff --git a/modules/nf-core/falco/meta.yml b/modules/nf-core/falco/meta.yml new file mode 100644 index 00000000..b8574289 --- /dev/null +++ b/modules/nf-core/falco/meta.yml @@ -0,0 +1,79 @@ +name: falco +description: Run falco on sequenced reads +keywords: + - quality control + - qc + - adapters + - fastq +tools: + - fastqc: + description: "falco is a drop-in C++ implementation of FastQC to assess the quality + of sequence reads." + homepage: "https://falco.readthedocs.io/" + documentation: "https://falco.readthedocs.io/" + licence: + - "GPL v3" + identifier: biotools:falco-rna +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. + ontologies: + - edam: http://edamontology.org/format_1930 +output: + html: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.html": + type: file + description: FastQC like report + pattern: "*_{fastqc_report.html}" + ontologies: + - edam: http://edamontology.org/format_3474 + txt: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.txt": + type: file + description: falco report data + pattern: "*_{data.txt}" + ontologies: + - edam: http://edamontology.org/format_3474 + versions_falco: + - - ${task.process}: + type: string + description: The name of the process + - falco: + type: string + description: The name of the tool + - falco --version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - falco: + type: string + description: The name of the tool + - falco --version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@lucacozzuto" +maintainers: + - "@lucacozzuto" diff --git a/modules/nf-core/falco/tests/main.nf.test b/modules/nf-core/falco/tests/main.nf.test new file mode 100644 index 00000000..cc8ed4bf --- /dev/null +++ b/modules/nf-core/falco/tests/main.nf.test @@ -0,0 +1,116 @@ +nextflow_process { + + name "Test Process FALCO" + script "../main.nf" + process "FALCO" + + tag "modules" + tag "modules_nfcore" + tag "falco" + + test("sarscov2 - fastq - single end") { + + when { + process { + """ + input[0] = [ + [ id: 'test', single_end:true ], + [ 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.txt.collect {meta, files -> files.collect { file(it).name }.sort() }, + file(process.out.html.get(0).get(1)).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() + }, + ) + } + + } + + test("sarscov2 - fastq - paired end") { + + when { + process { + """ + input[0] = [ + [ id: 'test', single_end:false ], + [ + 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.txt.collect {meta, files -> files.collect { file(it).name }.sort() }, + process.out.html.collect {meta, files -> files.collect { file(it).name }.sort() }, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() + }, + ) + } + + } + + test("sarscov2 - fastq - interleaved") { + + when { + process { + """ + input[0] = [ + [ id: 'test', single_end:false ], + [ 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.txt.collect {meta, files -> files.collect { file(it).name }.sort() }, + file(process.out.html.get(0).get(1)).name, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() + }, + ) + } + + } + + test("sarscov2 - fastq - single end - stub") { + options "-stub" + when { + process { + """ + input[0] = [ + [ id: 'test', single_end:true ], + [ 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/falco/tests/main.nf.test.snap b/modules/nf-core/falco/tests/main.nf.test.snap new file mode 100644 index 00000000..ea31e454 --- /dev/null +++ b/modules/nf-core/falco/tests/main.nf.test.snap @@ -0,0 +1,151 @@ +{ + "sarscov2 - fastq - single end": { + "content": [ + [ + [ + "test_fastqc_data.txt", + "test_summary.txt" + ] + ], + "test_report.html", + { + "versions_falco": [ + [ + "FALCO", + "falco", + "1.2.5" + ] + ] + } + ], + "timestamp": "2026-02-18T11:45:00.791179", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "sarscov2 - fastq - paired end": { + "content": [ + [ + [ + "test_1.fastq.gz_fastqc_data.txt", + "test_1.fastq.gz_summary.txt", + "test_2.fastq.gz_fastqc_data.txt", + "test_2.fastq.gz_summary.txt" + ] + ], + [ + [ + "test_1.fastq.gz_fastqc_report.html", + "test_2.fastq.gz_fastqc_report.html" + ] + ], + { + "versions_falco": [ + [ + "FALCO", + "falco", + "1.2.5" + ] + ] + } + ], + "timestamp": "2026-02-18T11:45:07.583855", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "sarscov2 - fastq - interleaved": { + "content": [ + [ + [ + "test_fastqc_data.txt", + "test_summary.txt" + ] + ], + "test_report.html", + { + "versions_falco": [ + [ + "FALCO", + "falco", + "1.2.5" + ] + ] + } + ], + "timestamp": "2026-02-18T11:45:13.797353", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "sarscov2 - fastq - single end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test_fastqc_data.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + [ + "test_data.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_summary.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "2": [ + [ + "FALCO", + "falco", + "1.2.5" + ] + ], + "html": [ + [ + { + "id": "test", + "single_end": true + }, + "test_fastqc_data.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "txt": [ + [ + { + "id": "test", + "single_end": true + }, + [ + "test_data.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_summary.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions_falco": [ + [ + "FALCO", + "falco", + "1.2.5" + ] + ] + } + ], + "timestamp": "2026-02-18T10:45:44.602269", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/fastp/environment.yml b/modules/nf-core/fastp/environment.yml index 26d4aca5..0c36eed2 100644 --- a/modules/nf-core/fastp/environment.yml +++ b/modules/nf-core/fastp/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::fastp=0.23.4 + # renovate: datasource=conda depName=bioconda/fastp + - bioconda::fastp=1.0.1 diff --git a/modules/nf-core/fastp/fastp.diff b/modules/nf-core/fastp/fastp.diff deleted file mode 100644 index 266c00b1..00000000 --- a/modules/nf-core/fastp/fastp.diff +++ /dev/null @@ -1,21 +0,0 @@ -Changes in module 'nf-core/fastp' -'modules/nf-core/fastp/environment.yml' is unchanged -'modules/nf-core/fastp/meta.yml' is unchanged -Changes in 'fastp/main.nf': ---- modules/nf-core/fastp/main.nf -+++ modules/nf-core/fastp/main.nf -@@ -92,7 +92,6 @@ - $fail_fastq \\ - $merge_fastq \\ - --thread $task.cpus \\ -- --detect_adapter_for_pe \\ - $args \\ - 2> >(tee ${prefix}.fastp.log >&2) - - -'modules/nf-core/fastp/tests/main.nf.test.snap' is unchanged -'modules/nf-core/fastp/tests/tags.yml' is unchanged -'modules/nf-core/fastp/tests/main.nf.test' is unchanged -'modules/nf-core/fastp/tests/nextflow.save_failed.config' is unchanged -'modules/nf-core/fastp/tests/nextflow.interleaved.config' is unchanged -************************************************************ diff --git a/modules/nf-core/fastp/main.nf b/modules/nf-core/fastp/main.nf index 02b69407..e13509ca 100644 --- a/modules/nf-core/fastp/main.nf +++ b/modules/nf-core/fastp/main.nf @@ -4,12 +4,11 @@ process FASTP { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/fastp:0.23.4--h5f740d0_0' : - 'biocontainers/fastp:0.23.4--h5f740d0_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/52/527b18847a97451091dba07a886b24f17f742a861f9f6c9a6bfb79d4f1f3bf9d/data' : + 'community.wave.seqera.io/library/fastp:1.0.1--c8b87fe62dcc103c' }" input: - tuple val(meta), path(reads) - path adapter_fasta + tuple val(meta), path(reads), path(adapter_fasta) val discard_trimmed_pass val save_trimmed_fail val save_merged @@ -21,7 +20,7 @@ process FASTP { tuple val(meta), path('*.log') , emit: log tuple val(meta), path('*.fail.fastq.gz') , optional:true, emit: reads_fail tuple val(meta), path('*.merged.fastq.gz'), optional:true, emit: reads_merged - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('fastp'), eval('fastp --version 2>&1 | sed -e "s/fastp //g"'), emit: versions_fastp, topic: versions when: task.ext.when == null || task.ext.when @@ -30,9 +29,9 @@ process FASTP { def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" def adapter_list = adapter_fasta ? "--adapter_fasta ${adapter_fasta}" : "" - def fail_fastq = save_trimmed_fail && meta.single_end ? "--failed_out ${prefix}.fail.fastq.gz" : save_trimmed_fail && !meta.single_end ? "--failed_out ${prefix}.paired.fail.fastq.gz --unpaired1 ${prefix}_1.fail.fastq.gz --unpaired2 ${prefix}_2.fail.fastq.gz" : '' - def out_fq1 = discard_trimmed_pass ?: ( meta.single_end ? "--out1 ${prefix}.fastp.fastq.gz" : "--out1 ${prefix}_1.fastp.fastq.gz" ) - def out_fq2 = discard_trimmed_pass ?: "--out2 ${prefix}_2.fastp.fastq.gz" + def fail_fastq = save_trimmed_fail && meta.single_end ? "--failed_out ${prefix}.fail.fastq.gz" : save_trimmed_fail && !meta.single_end ? "--failed_out ${prefix}.paired.fail.fastq.gz --unpaired1 ${prefix}_R1.fail.fastq.gz --unpaired2 ${prefix}_R2.fail.fastq.gz" : '' + def out_fq1 = discard_trimmed_pass ?: ( meta.single_end ? "--out1 ${prefix}.fastp.fastq.gz" : "--out1 ${prefix}_R1.fastp.fastq.gz" ) + def out_fq2 = discard_trimmed_pass ?: "--out2 ${prefix}_R2.fastp.fastq.gz" // Added soft-links to original fastqs for consistent naming in MultiQC // Use single ended for interleaved. Add --interleaved_in in config. if ( task.ext.args?.contains('--interleaved_in') ) { @@ -48,13 +47,8 @@ process FASTP { $adapter_list \\ $fail_fastq \\ $args \\ - 2> >(tee ${prefix}.fastp.log >&2) \\ + 2>| >(tee ${prefix}.fastp.log >&2) \\ | gzip -c > ${prefix}.fastp.fastq.gz - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fastp: \$(fastp --version 2>&1 | sed -e "s/fastp //g") - END_VERSIONS """ } else if (meta.single_end) { """ @@ -69,21 +63,16 @@ process FASTP { $adapter_list \\ $fail_fastq \\ $args \\ - 2> >(tee ${prefix}.fastp.log >&2) - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fastp: \$(fastp --version 2>&1 | sed -e "s/fastp //g") - END_VERSIONS + 2>| >(tee ${prefix}.fastp.log >&2) """ } else { def merge_fastq = save_merged ? "-m --merged_out ${prefix}.merged.fastq.gz" : '' """ - [ ! -f ${prefix}_1.fastq.gz ] && ln -sf ${reads[0]} ${prefix}_1.fastq.gz - [ ! -f ${prefix}_2.fastq.gz ] && ln -sf ${reads[1]} ${prefix}_2.fastq.gz + [ ! -f ${prefix}_R1.fastq.gz ] && ln -sf ${reads[0]} ${prefix}_R1.fastq.gz + [ ! -f ${prefix}_R2.fastq.gz ] && ln -sf ${reads[1]} ${prefix}_R2.fastq.gz fastp \\ - --in1 ${prefix}_1.fastq.gz \\ - --in2 ${prefix}_2.fastq.gz \\ + --in1 ${prefix}_R1.fastq.gz \\ + --in2 ${prefix}_R2.fastq.gz \\ $out_fq1 \\ $out_fq2 \\ --json ${prefix}.fastp.json \\ @@ -92,22 +81,18 @@ process FASTP { $fail_fastq \\ $merge_fastq \\ --thread $task.cpus \\ + --detect_adapter_for_pe \\ $args \\ - 2> >(tee ${prefix}.fastp.log >&2) - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fastp: \$(fastp --version 2>&1 | sed -e "s/fastp //g") - END_VERSIONS + 2>| >(tee ${prefix}.fastp.log >&2) """ } stub: def prefix = task.ext.prefix ?: "${meta.id}" def is_single_output = task.ext.args?.contains('--interleaved_in') || meta.single_end - def touch_reads = (discard_trimmed_pass) ? "" : (is_single_output) ? "echo '' | gzip > ${prefix}.fastp.fastq.gz" : "echo '' | gzip > ${prefix}_1.fastp.fastq.gz ; echo '' | gzip > ${prefix}_2.fastp.fastq.gz" + def touch_reads = (discard_trimmed_pass) ? "" : (is_single_output) ? "echo '' | gzip > ${prefix}.fastp.fastq.gz" : "echo '' | gzip > ${prefix}_R1.fastp.fastq.gz ; echo '' | gzip > ${prefix}_R2.fastp.fastq.gz" def touch_merged = (!is_single_output && save_merged) ? "echo '' | gzip > ${prefix}.merged.fastq.gz" : "" - def touch_fail_fastq = (!save_trimmed_fail) ? "" : meta.single_end ? "echo '' | gzip > ${prefix}.fail.fastq.gz" : "echo '' | gzip > ${prefix}.paired.fail.fastq.gz ; echo '' | gzip > ${prefix}_1.fail.fastq.gz ; echo '' | gzip > ${prefix}_2.fail.fastq.gz" + def touch_fail_fastq = (!save_trimmed_fail) ? "" : meta.single_end ? "echo '' | gzip > ${prefix}.fail.fastq.gz" : "echo '' | gzip > ${prefix}.paired.fail.fastq.gz ; echo '' | gzip > ${prefix}_R1.fail.fastq.gz ; echo '' | gzip > ${prefix}_R2.fail.fastq.gz" """ $touch_reads $touch_fail_fastq @@ -115,10 +100,5 @@ process FASTP { touch "${prefix}.fastp.json" touch "${prefix}.fastp.html" touch "${prefix}.fastp.log" - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fastp: \$(fastp --version 2>&1 | sed -e "s/fastp //g") - END_VERSIONS """ } diff --git a/modules/nf-core/fastp/meta.yml b/modules/nf-core/fastp/meta.yml index 159404d0..a67be395 100644 --- a/modules/nf-core/fastp/meta.yml +++ b/modules/nf-core/fastp/meta.yml @@ -24,24 +24,27 @@ input: List of input FastQ files of size 1 and 2 for single-end and paired-end data, respectively. If you wish to run interleaved paired-end data, supply as single-end data but with `--interleaved_in` in your `modules.conf`'s `ext.args` for the module. - - - adapter_fasta: + ontologies: [] + - adapter_fasta: type: file description: File in FASTA format containing possible adapters to remove. pattern: "*.{fasta,fna,fas,fa}" - - - discard_trimmed_pass: - type: boolean - description: Specify true to not write any reads that pass trimming thresholds. - | This can be used to use fastp for the output report only. - - - save_trimmed_fail: - type: boolean - description: Specify true to save files that failed to pass trimming thresholds - ending in `*.fail.fastq.gz` - - - save_merged: - type: boolean - description: Specify true to save all merged reads to a file ending in `*.merged.fastq.gz` + ontologies: [] + - discard_trimmed_pass: + type: boolean + description: | + Specify true to not write any reads that pass trimming thresholds. + This can be used to use fastp for the output report only. + - save_trimmed_fail: + type: boolean + description: Specify true to save files that failed to pass trimming thresholds + ending in `*.fail.fastq.gz` + - save_merged: + type: boolean + description: Specify true to save all merged reads to a file ending in `*.merged.fastq.gz` output: - - reads: - - meta: + reads: + - - meta: type: map description: | Groovy Map containing sample information @@ -50,8 +53,11 @@ output: type: file description: The trimmed/modified/unmerged fastq reads pattern: "*fastp.fastq.gz" - - json: - - meta: + ontologies: + - edam: http://edamontology.org/format_1930 # FASTQ + - edam: http://edamontology.org/format_3989 # GZIP format + json: + - - meta: type: map description: | Groovy Map containing sample information @@ -60,8 +66,10 @@ output: type: file description: Results in JSON format pattern: "*.json" - - html: - - meta: + ontologies: + - edam: http://edamontology.org/format_3464 # JSON + html: + - - meta: type: map description: | Groovy Map containing sample information @@ -70,8 +78,9 @@ output: type: file description: Results in HTML format pattern: "*.html" - - log: - - meta: + ontologies: [] + log: + - - meta: type: map description: | Groovy Map containing sample information @@ -80,8 +89,9 @@ output: type: file description: fastq log file pattern: "*.log" - - reads_fail: - - meta: + ontologies: [] + reads_fail: + - - meta: type: map description: | Groovy Map containing sample information @@ -90,8 +100,11 @@ output: type: file description: Reads the failed the preprocessing pattern: "*fail.fastq.gz" - - reads_merged: - - meta: + ontologies: + - edam: http://edamontology.org/format_1930 # FASTQ + - edam: http://edamontology.org/format_3989 # GZIP format + reads_merged: + - - meta: type: map description: | Groovy Map containing sample information @@ -100,14 +113,32 @@ output: type: file description: Reads that were successfully merged pattern: "*.{merged.fastq.gz}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_fastp: + - - "${task.process}": + type: string + description: The name of the process + - fastp: + type: string + description: The name of the tool + - 'fastp --version 2>&1 | sed -e "s/fastp //g"': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - "${task.process}": + type: string + description: The name of the process + - fastp: + type: string + description: The name of the tool + - 'fastp --version 2>&1 | sed -e "s/fastp //g"': + type: eval + description: The expression to obtain the version of the tool authors: - "@drpatelh" - "@kevinmenden" + - "@eit-maxlcummins" maintainers: - "@drpatelh" - "@kevinmenden" diff --git a/modules/nf-core/fastp/tests/main.nf.test b/modules/nf-core/fastp/tests/main.nf.test index 30dbb8aa..b7901578 100644 --- a/modules/nf-core/fastp/tests/main.nf.test +++ b/modules/nf-core/fastp/tests/main.nf.test @@ -13,14 +13,19 @@ nextflow_process { process { """ + adapter_fasta = [] // empty list for no adapter file! + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:true ], - [ 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_1.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -31,11 +36,11 @@ nextflow_process { { assert path(process.out.html.get(0).get(1)).getText().contains("single end (151 cycles)") }, { assert path(process.out.log.get(0).get(1)).getText().contains("reads passed filter: 99") }, { assert snapshot( - process.out.json, process.out.reads, process.out.reads_fail, process.out.reads_merged, - process.out.versions).match() } + process.out.findAll { key, val -> key.startsWith('versions') }).match() + } ) } } @@ -46,20 +51,22 @@ nextflow_process { process { """ - adapter_fasta = [] - save_trimmed_pass = true - save_trimmed_fail = false - save_merged = false + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = false 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/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -70,11 +77,10 @@ nextflow_process { { assert path(process.out.html.get(0).get(1)).getText().contains("The input has little adapter percentage (~0.000000%), probably it's trimmed before.") }, { assert path(process.out.log.get(0).get(1)).getText().contains("Q30 bases: 12281(88.3716%)") }, { assert snapshot( - process.out.json, process.out.reads, process.out.reads_fail, process.out.reads_merged, - process.out.versions).match() } + process.out.findAll { key, val -> key.startsWith('versions') }).match() } ) } } @@ -85,14 +91,19 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:true ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_interleaved.fastq.gz', checkIfExists: true) ] + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_interleaved.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -106,8 +117,7 @@ nextflow_process { { assert process.out.reads_merged == [] }, { assert snapshot( process.out.reads, - process.out.json, - process.out.versions).match() } + process.out.findAll { key, val -> key.startsWith('versions') }).match() } ) } } @@ -118,14 +128,19 @@ nextflow_process { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = true + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:true ], // 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_1.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = true - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -136,11 +151,10 @@ nextflow_process { { assert path(process.out.html.get(0).get(1)).getText().contains("single end (151 cycles)") }, { assert path(process.out.log.get(0).get(1)).getText().contains("reads passed filter: 99") }, { assert snapshot( - process.out.json, process.out.reads, process.out.reads_fail, process.out.reads_merged, - process.out.versions).match() } + process.out.findAll { key, val -> key.startsWith('versions') }).match() } ) } } @@ -151,15 +165,22 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = true + save_merged = false + 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/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = true - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -173,8 +194,7 @@ nextflow_process { process.out.reads, process.out.reads_fail, process.out.reads_merged, - process.out.json, - process.out.versions).match() } + process.out.findAll { key, val -> key.startsWith('versions') }).match() } ) } } @@ -184,15 +204,22 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = true + 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/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = false - input[4] = true + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -203,11 +230,10 @@ nextflow_process { { assert path(process.out.html.get(0).get(1)).getText().contains("The input has little adapter percentage (~0.000000%), probably it's trimmed before.") }, { assert path(process.out.log.get(0).get(1)).getText().contains("total reads: 75") }, { assert snapshot( - process.out.json, process.out.reads, process.out.reads_fail, process.out.reads_merged, - process.out.versions).match() }, + process.out.findAll { key, val -> key.startsWith('versions') }).match() }, ) } } @@ -217,15 +243,22 @@ nextflow_process { when { process { """ + adapter_fasta = file(params.modules_testdata_base_path + 'delete_me/fastp/adapters.fasta', checkIfExists: true) + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = true + 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/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ], + adapter_fasta ]) - input[1] = Channel.of([ file(params.modules_testdata_base_path + 'delete_me/fastp/adapters.fasta', checkIfExists: true) ]) + input[1] = false input[2] = false - input[3] = false - input[4] = true + input[3] = true """ } } @@ -236,11 +269,10 @@ nextflow_process { { assert path(process.out.html.get(0).get(1)).getText().contains("
") }, { assert path(process.out.log.get(0).get(1)).getText().contains("total bases: 13683") }, { assert snapshot( - process.out.json, process.out.reads, process.out.reads_fail, process.out.reads_merged, - process.out.versions).match() } + process.out.findAll { key, val -> key.startsWith('versions') }).match() } ) } } @@ -250,14 +282,20 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = true + save_trimmed_fail = false + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:true ], - [ 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_1.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = true - input[3] = false - input[4] = false + + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -268,14 +306,13 @@ nextflow_process { { assert path(process.out.html.get(0).get(1)).getText().contains("single end (151 cycles)") }, { assert path(process.out.log.get(0).get(1)).getText().contains("reads passed filter: 99") }, { assert snapshot( - process.out.json, process.out.reads, process.out.reads, process.out.reads_fail, process.out.reads_fail, process.out.reads_merged, process.out.reads_merged, - process.out.versions).match() } + process.out.findAll { key, val -> key.startsWith('versions') }).match() } ) } } @@ -285,15 +322,22 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = true + save_trimmed_fail = false + save_merged = false + 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/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ], + adapter_fasta ]) - input[1] = [] - input[2] = true - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -304,14 +348,13 @@ nextflow_process { { assert path(process.out.html.get(0).get(1)).getText().contains("The input has little adapter percentage (~0.000000%), probably it's trimmed before.") }, { assert path(process.out.log.get(0).get(1)).getText().contains("Q30 bases: 12281(88.3716%)") }, { assert snapshot( - process.out.json, process.out.reads, process.out.reads, process.out.reads_fail, process.out.reads_fail, process.out.reads_merged, process.out.reads_merged, - process.out.versions).match() } + process.out.findAll { key, val -> key.startsWith('versions') }).match() } ) } } @@ -324,14 +367,19 @@ nextflow_process { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:true ], - [ 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_1.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -352,20 +400,20 @@ nextflow_process { process { """ - adapter_fasta = [] - save_trimmed_pass = true - save_trimmed_fail = false - save_merged = false + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = false 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/test_2.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -386,14 +434,19 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:true ], // meta map - [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_interleaved.fastq.gz', checkIfExists: true) ] + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_interleaved.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -414,14 +467,19 @@ nextflow_process { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = true + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:true ], // 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_1.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = true - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -442,15 +500,20 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = true + save_merged = false + 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/test_2.fastq.gz', checkIfExists: true)], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = true - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -470,15 +533,20 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = true + 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/test_2.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = false - input[3] = false - input[4] = true + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -498,15 +566,22 @@ nextflow_process { when { process { """ + adapter_fasta = file(params.modules_testdata_base_path + 'delete_me/fastp/adapters.fasta', checkIfExists: true) + discard_trimmed_pass = false + save_trimmed_fail = false + save_merged = true + 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/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) + ], + adapter_fasta ]) - input[1] = Channel.of([ file(params.modules_testdata_base_path + 'delete_me/fastp/adapters.fasta', checkIfExists: true) ]) - input[2] = false - input[3] = false - input[4] = true + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -526,14 +601,19 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = true + save_trimmed_fail = false + save_merged = false + input[0] = Channel.of([ [ id:'test', single_end:true ], - [ 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_1.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = true - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -553,15 +633,20 @@ nextflow_process { when { process { """ + adapter_fasta = [] + discard_trimmed_pass = true + save_trimmed_fail = false + save_merged = false + 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/test_2.fastq.gz', checkIfExists: true) ], + adapter_fasta ]) - input[1] = [] - input[2] = true - input[3] = false - input[4] = false + input[1] = discard_trimmed_pass + input[2] = save_trimmed_fail + input[3] = save_merged """ } } @@ -573,4 +658,4 @@ nextflow_process { ) } } -} \ No newline at end of file +} diff --git a/modules/nf-core/fastp/tests/main.nf.test.snap b/modules/nf-core/fastp/tests/main.nf.test.snap index 54be7e45..56772358 100644 --- a/modules/nf-core/fastp/tests/main.nf.test.snap +++ b/modules/nf-core/fastp/tests/main.nf.test.snap @@ -39,7 +39,11 @@ ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -77,28 +81,23 @@ "reads_merged": [ ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T14:31:10.841098" + "timestamp": "2026-01-22T13:00:52.14535813" }, "test_fastp_paired_end": { "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.fastp.json:md5,1e0f8e27e71728e2b63fc64086be95cd" - ] - ], [ [ { @@ -106,8 +105,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7", - "test_2.fastp.fastq.gz:md5,25cbdca08e2083dbd4f0502de6b62f39" + "test_R1.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7", + "test_R2.fastp.fastq.gz:md5,25cbdca08e2083dbd4f0502de6b62f39" ] ] ], @@ -117,27 +116,24 @@ [ ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:43:28.665779" + "timestamp": "2026-01-23T09:46:26.421773402" }, "test_fastp_paired_end_merged_adapterlist": { "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.fastp.json:md5,5914ca3f21ce162123a824e33e8564f6" - ] - ], [ [ { @@ -145,8 +141,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,54b726a55e992a869fd3fa778afe1672", - "test_2.fastp.fastq.gz:md5,29d3b33b869f7b63417b8ff07bb128ba" + "test_R1.fastp.fastq.gz:md5,54b726a55e992a869fd3fa778afe1672", + "test_R2.fastp.fastq.gz:md5,29d3b33b869f7b63417b8ff07bb128ba" ] ] ], @@ -162,27 +158,24 @@ "test.merged.fastq.gz:md5,c873bb1ab3fa859dcc47306465e749d5" ] ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:44:18.210375" + "timestamp": "2026-01-23T09:46:59.832295907" }, "test_fastp_single_end_qc_only": { "content": [ - [ - [ - { - "id": "test", - "single_end": true - }, - "test.fastp.json:md5,5cc5f01e449309e0e689ed6f51a2294a" - ] - ], [ ], @@ -201,15 +194,21 @@ [ ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:44:27.380974" + "timestamp": "2026-01-23T09:47:06.486959565" }, "test_fastp_paired_end_trim_fail": { "content": [ @@ -220,8 +219,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,6ff32a64c5188b9a9192be1398c262c7", - "test_2.fastp.fastq.gz:md5,db0cb7c9977e94ac2b4b446ebd017a8a" + "test_R1.fastp.fastq.gz:md5,6ff32a64c5188b9a9192be1398c262c7", + "test_R2.fastp.fastq.gz:md5,db0cb7c9977e94ac2b4b446ebd017a8a" ] ] ], @@ -233,32 +232,29 @@ }, [ "test.paired.fail.fastq.gz:md5,409b687c734cedd7a1fec14d316e1366", - "test_1.fail.fastq.gz:md5,4f273cf3159c13f79e8ffae12f5661f6", - "test_2.fail.fastq.gz:md5,f97b9edefb5649aab661fbc9e71fc995" + "test_R1.fail.fastq.gz:md5,4f273cf3159c13f79e8ffae12f5661f6", + "test_R2.fail.fastq.gz:md5,f97b9edefb5649aab661fbc9e71fc995" ] ] ], [ ], - [ - [ - { - "id": "test", - "single_end": false - }, - "test.fastp.json:md5,4c3268ddb50ea5b33125984776aa3519" + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] - ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:43:58.749589" + "timestamp": "2026-01-23T09:46:46.736511024" }, "fastp - stub test_fastp_interleaved": { "content": [ @@ -306,7 +302,11 @@ ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -350,16 +350,20 @@ "reads_merged": [ ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:50:00.270029" + "timestamp": "2026-01-22T13:00:16.097071654" }, "test_fastp_single_end - stub": { "content": [ @@ -407,7 +411,11 @@ ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -451,16 +459,20 @@ "reads_merged": [ ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:49:42.502789" + "timestamp": "2026-01-22T13:00:03.317192706" }, "test_fastp_paired_end_merged_adapterlist - stub": { "content": [ @@ -472,8 +484,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -517,7 +529,11 @@ ] ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -553,8 +569,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -570,16 +586,20 @@ "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:54:53.458252" + "timestamp": "2026-01-22T13:00:44.851708205" }, "test_fastp_paired_end_merged - stub": { "content": [ @@ -591,8 +611,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -636,7 +656,11 @@ ] ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -672,8 +696,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -689,28 +713,23 @@ "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:50:27.689379" + "timestamp": "2026-01-22T13:00:37.581047713" }, "test_fastp_paired_end_merged": { "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.fastp.json:md5,b712fd68ed0322f4bec49ff2a5237fcc" - ] - ], [ [ { @@ -718,8 +737,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,54b726a55e992a869fd3fa778afe1672", - "test_2.fastp.fastq.gz:md5,29d3b33b869f7b63417b8ff07bb128ba" + "test_R1.fastp.fastq.gz:md5,54b726a55e992a869fd3fa778afe1672", + "test_R2.fastp.fastq.gz:md5,29d3b33b869f7b63417b8ff07bb128ba" ] ] ], @@ -735,15 +754,21 @@ "test.merged.fastq.gz:md5,c873bb1ab3fa859dcc47306465e749d5" ] ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:44:08.68476" + "timestamp": "2026-01-23T09:46:53.190202914" }, "test_fastp_paired_end - stub": { "content": [ @@ -755,8 +780,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -794,7 +819,11 @@ ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -830,8 +859,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -841,28 +870,23 @@ "reads_merged": [ ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:49:51.679221" + "timestamp": "2026-01-22T13:00:09.585957282" }, "test_fastp_single_end": { "content": [ - [ - [ - { - "id": "test", - "single_end": true - }, - "test.fastp.json:md5,c852d7a6dba5819e4ac8d9673bedcacc" - ] - ], [ [ { @@ -878,15 +902,21 @@ [ ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:43:18.834322" + "timestamp": "2026-01-23T09:46:19.624824985" }, "test_fastp_single_end_trim_fail - stub": { "content": [ @@ -940,7 +970,11 @@ ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -990,16 +1024,20 @@ "reads_merged": [ ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T14:05:36.898142" + "timestamp": "2026-01-22T13:00:22.800659826" }, "test_fastp_paired_end_trim_fail - stub": { "content": [ @@ -1011,8 +1049,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -1051,8 +1089,8 @@ }, [ "test.paired.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_1.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -1060,7 +1098,11 @@ ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -1096,8 +1138,8 @@ "single_end": false }, [ - "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], @@ -1109,24 +1151,28 @@ }, [ "test.paired.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_1.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test_2.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "test_R1.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_R2.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ] ], "reads_merged": [ ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T14:05:49.212847" + "timestamp": "2026-01-22T13:00:30.271734068" }, "fastp test_fastp_interleaved": { "content": [ @@ -1139,36 +1185,24 @@ "test.fastp.fastq.gz:md5,217d62dc13a23e92513a1bd8e1bcea39" ] ], - [ - [ - { - "id": "test", - "single_end": true - }, - "test.fastp.json:md5,b24e0624df5cc0b11cd5ba21b726fb22" + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] - ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:43:38.910832" + "timestamp": "2026-01-23T09:46:33.4628687" }, "test_fastp_single_end_trim_fail": { "content": [ - [ - [ - { - "id": "test", - "single_end": true - }, - "test.fastp.json:md5,9a7ee180f000e8d00c7fb67f06293eb5" - ] - ], [ [ { @@ -1190,27 +1224,24 @@ [ ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:43:48.22378" + "timestamp": "2026-01-23T09:46:39.895973372" }, "test_fastp_paired_end_qc_only": { "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.fastp.json:md5,623064a45912dac6f2b64e3f2e9901df" - ] - ], [ ], @@ -1229,15 +1260,21 @@ [ ], - [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" - ] + { + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T13:44:36.334938" + "timestamp": "2026-01-23T09:47:13.015833707" }, "test_fastp_paired_end_qc_only - stub": { "content": [ @@ -1279,7 +1316,11 @@ ], "6": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + "FASTP", + "fastp", + "1.0.1" + ] ], "html": [ [ @@ -1317,15 +1358,19 @@ "reads_merged": [ ], - "versions": [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + "versions_fastp": [ + [ + "FASTP", + "fastp", + "1.0.1" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-07-05T14:31:27.096468" + "timestamp": "2026-01-22T13:00:59.670106791" } } \ No newline at end of file diff --git a/modules/nf-core/fastp/tests/tags.yml b/modules/nf-core/fastp/tests/tags.yml deleted file mode 100644 index c1afcce7..00000000 --- a/modules/nf-core/fastp/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -fastp: - - modules/nf-core/fastp/** diff --git a/modules/nf-core/samtools/import/environment.yml b/modules/nf-core/gnu/sort/environment.yml similarity index 76% rename from modules/nf-core/samtools/import/environment.yml rename to modules/nf-core/gnu/sort/environment.yml index 62054fc9..0c4cd942 100644 --- a/modules/nf-core/samtools/import/environment.yml +++ b/modules/nf-core/gnu/sort/environment.yml @@ -4,5 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.21 - - bioconda::samtools=1.21 + - conda-forge::coreutils=9.5 diff --git a/modules/nf-core/gnu/sort/main.nf b/modules/nf-core/gnu/sort/main.nf new file mode 100644 index 00000000..a16f6291 --- /dev/null +++ b/modules/nf-core/gnu/sort/main.nf @@ -0,0 +1,40 @@ +process GNU_SORT { + tag "$meta.id" + label "process_low" + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/coreutils:9.5': + 'biocontainers/coreutils:9.5' }" + + input: + tuple val(meta), path(input) + + output: + tuple val(meta), path( "${output_file}" ) , emit: sorted + tuple val("${task.process}"), val('coreutils'), eval("sort --version |& sed '1!d ; s/sort (GNU coreutils) //'"), emit: versions_coreutils, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + suffix = task.ext.suffix ?: "${input.extension}" + output_file = "${prefix}.${suffix}" + if ("$input" == "$output_file") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + """ + sort ${args} ${input} > ${output_file} + + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + suffix = task.ext.suffix ?: "${input.extension}" + output_file = "${prefix}.${suffix}" + if ("$input" == "$output_file") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + """ + touch ${output_file} + + """ +} diff --git a/modules/nf-core/gnu/sort/meta.yml b/modules/nf-core/gnu/sort/meta.yml new file mode 100644 index 00000000..48dde4a0 --- /dev/null +++ b/modules/nf-core/gnu/sort/meta.yml @@ -0,0 +1,69 @@ +name: "gnu_sort" +description: | + Writes a sorted concatenation of file/s +keywords: + - GNU + - coreutils + - sort + - merge compare +tools: + - gnu: + description: "The GNU Core Utilities are the basic file, shell and text manipulation + utilities of the GNU operating system. These are the core utilities which are + expected to exist on every operating system." + homepage: "https://www.gnu.org/software/coreutils/" + documentation: "https://www.gnu.org/software/coreutils/manual/html_node/index.html" + tool_dev_url: "https://git.savannah.gnu.org/cgit/coreutils.git" + doi: "10.5281/zenodo.581670" + licence: ["GPL"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - input: + type: file + description: Draft assembly file + pattern: "*.{txt,bed,interval,genome,bins}" + ontologies: [] +output: + sorted: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + pattern: "${output_file}" + - "${output_file}": + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + pattern: "${output_file}" + versions_coreutils: + - - ${task.process}: + type: string + description: The process the versions were collected from + - coreutils: + type: string + description: The tool name + - "sort --version |& sed '1!d ; s/sort (GNU coreutils) //'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - coreutils: + type: string + description: The tool name + - "sort --version |& sed '1!d ; s/sort (GNU coreutils) //'": + type: string + description: The command used to generate the version of the tool +authors: + - "@DLBPointon" +maintainers: + - "@DLBPointon" diff --git a/modules/nf-core/gnu/sort/tests/main.nf.test b/modules/nf-core/gnu/sort/tests/main.nf.test new file mode 100644 index 00000000..9aef3daf --- /dev/null +++ b/modules/nf-core/gnu/sort/tests/main.nf.test @@ -0,0 +1,104 @@ +nextflow_process { + + name "Test Process GNU_SORT" + script "modules/nf-core/gnu/sort/main.nf" + process "GNU_SORT" + + tag "modules" + tag "modules_nfcore" + tag "gnu" + tag "gnu/sort" + + test("unsorted_genome_sort") { + config "./sort_simple_bed.config" + + when { + process { + """ + input[0] = [ + [id:'genome_test'], + file(params.modules_testdata_base_path + 'generic/unsorted_data/unsorted_text/test.genome', checkIfExists: true) + ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("unsorted_intervals_sort") { + config "./sort_simple_bed.config" + when { + process { + """ + input[0] = [ + [id:'test'], + file(params.modules_testdata_base_path + 'generic/unsorted_data/unsorted_text/test.bed', checkIfExists: true) + ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("unsorted_csv_sort") { + config "./sort_complex.config" + + when { + process { + """ + input[0] = [ + [id:'test'], + file(params.modules_testdata_base_path + 'generic/unsorted_data/unsorted_text/test.csv', checkIfExists: true) + ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("unsorted_csv_sort_stub") { + config "./sort_complex.config" + options "-stub" + + when { + process { + """ + input[0] = [ + [id:'test'], + file(params.modules_testdata_base_path + 'generic/unsorted_data/unsorted_text/test.csv', checkIfExists: true) + ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/gnu/sort/tests/main.nf.test.snap b/modules/nf-core/gnu/sort/tests/main.nf.test.snap new file mode 100644 index 00000000..f57dc6bb --- /dev/null +++ b/modules/nf-core/gnu/sort/tests/main.nf.test.snap @@ -0,0 +1,166 @@ +{ + "unsorted_csv_sort": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.csv.sorted:md5,0b52d1b4c4a0c6e972c6f94aafd75a1d" + ] + ], + "1": [ + [ + "GNU_SORT", + "coreutils", + "9.5" + ] + ], + "sorted": [ + [ + { + "id": "test" + }, + "test.csv.sorted:md5,0b52d1b4c4a0c6e972c6f94aafd75a1d" + ] + ], + "versions_coreutils": [ + [ + "GNU_SORT", + "coreutils", + "9.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.8" + }, + "timestamp": "2026-01-23T15:48:28.77537237" + }, + "unsorted_csv_sort_stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.csv.sorted:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + "GNU_SORT", + "coreutils", + "9.5" + ] + ], + "sorted": [ + [ + { + "id": "test" + }, + "test.csv.sorted:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_coreutils": [ + [ + "GNU_SORT", + "coreutils", + "9.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.8" + }, + "timestamp": "2026-01-23T15:48:45.534463019" + }, + "unsorted_genome_sort": { + "content": [ + { + "0": [ + [ + { + "id": "genome_test" + }, + "genome_test.bed.sorted:md5,fd97f7efafdbbfa71d9b560f10b4b048" + ] + ], + "1": [ + [ + "GNU_SORT", + "coreutils", + "9.5" + ] + ], + "sorted": [ + [ + { + "id": "genome_test" + }, + "genome_test.bed.sorted:md5,fd97f7efafdbbfa71d9b560f10b4b048" + ] + ], + "versions_coreutils": [ + [ + "GNU_SORT", + "coreutils", + "9.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.8" + }, + "timestamp": "2026-01-23T15:47:54.290932481" + }, + "unsorted_intervals_sort": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bed.sorted:md5,abbce903ef263d38b2f71856387799ab" + ] + ], + "1": [ + [ + "GNU_SORT", + "coreutils", + "9.5" + ] + ], + "sorted": [ + [ + { + "id": "test" + }, + "test.bed.sorted:md5,abbce903ef263d38b2f71856387799ab" + ] + ], + "versions_coreutils": [ + [ + "GNU_SORT", + "coreutils", + "9.5" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.04.8" + }, + "timestamp": "2026-01-23T15:48:11.626509684" + } +} \ No newline at end of file diff --git a/modules/nf-core/gnu/sort/tests/sort_complex.config b/modules/nf-core/gnu/sort/tests/sort_complex.config new file mode 100644 index 00000000..ce4f1518 --- /dev/null +++ b/modules/nf-core/gnu/sort/tests/sort_complex.config @@ -0,0 +1,6 @@ +process { + withName: GNU_SORT { + ext.args = { "-t ';' -g -k 1,1 -k 2,2" } + ext.suffix = { "csv.sorted" } + } +} diff --git a/modules/nf-core/gnu/sort/tests/sort_simple_bed.config b/modules/nf-core/gnu/sort/tests/sort_simple_bed.config new file mode 100644 index 00000000..8496c8d7 --- /dev/null +++ b/modules/nf-core/gnu/sort/tests/sort_simple_bed.config @@ -0,0 +1,6 @@ +process { + withName: GNU_SORT { + ext.args = { "-k1,1 -k2,2n" } + ext.suffix = { "bed.sorted" } + } +} diff --git a/modules/nf-core/gnu/sort/tests/sort_simple_genome.config b/modules/nf-core/gnu/sort/tests/sort_simple_genome.config new file mode 100644 index 00000000..c408ece1 --- /dev/null +++ b/modules/nf-core/gnu/sort/tests/sort_simple_genome.config @@ -0,0 +1,6 @@ +process { + withName: GNU_SORT { + ext.args = { "-k1,1 -k2,2n" } + ext.suffix = { "genome.sorted" } + } +} diff --git a/modules/nf-core/md5sum/environment.yml b/modules/nf-core/md5sum/environment.yml index c7eb9bd1..9b926b1f 100644 --- a/modules/nf-core/md5sum/environment.yml +++ b/modules/nf-core/md5sum/environment.yml @@ -1,5 +1,12 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - conda-forge::coreutils=8.30 + - conda-forge::coreutils=9.5 + - conda-forge::grep=3.11 + - conda-forge::gzip=1.13 + - conda-forge::lbzip2=2.5 + - conda-forge::sed=4.8 + - conda-forge::tar=1.34 diff --git a/modules/nf-core/md5sum/main.nf b/modules/nf-core/md5sum/main.nf index d77bb8ce..3412281e 100644 --- a/modules/nf-core/md5sum/main.nf +++ b/modules/nf-core/md5sum/main.nf @@ -1,11 +1,11 @@ process MD5SUM { - tag "$meta.id" + tag "${meta.id}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ubuntu:20.04' : - 'nf-core/ubuntu:20.04' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/52/52ccce28d2ab928ab862e25aae26314d69c8e38bd41ca9431c67ef05221348aa/data' + : 'community.wave.seqera.io/library/coreutils_grep_gzip_lbzip2_pruned:838ba80435a629f8'}" input: tuple val(meta), path(files) @@ -13,62 +13,43 @@ process MD5SUM { output: tuple val(meta), path("*.md5"), emit: checksum - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('md5sum'), eval("md5sum --version | sed '1!d; s/.* //'"), topic: versions, emit: versions_md5sum when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" // will only use when as_separate_files = false - if ( as_separate_files ) { + def prefix = task.ext.prefix ?: "${meta.id}" + // will only use when as_separate_files = false + if (as_separate_files) { """ find -L * -maxdepth 0 -type f \\ ! -name '*.md5' \\ - -exec sh -c 'md5sum $args "\$1" > "\$1.md5"' _ "{}" \\; - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - md5sum: \$( md5sum --version | sed '1!d; s/.* //' ) - END_VERSIONS + -exec sh -c 'md5sum ${args} "\$1" > "\$1.md5"' _ "{}" \\; """ - } else { + } + else { """ find -L * -type f \\ ! -name '*.md5' \\ - -exec md5sum $args "{}" + \\ + -exec md5sum ${args} "{}" + \\ > ${prefix}.md5 - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - md5sum: \$( md5sum --version | sed '1!d; s/.* //' ) - END_VERSIONS """ } stub: - def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - if ( as_separate_files ) { + if (as_separate_files) { """ find -L * -type f \\ ! -name '*.md5' \\ -exec sh -c 'touch "\$1.md5"' _ "{}" \\; - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - md5sum: \$( md5sum --version | sed '1!d; s/.* //' ) - END_VERSIONS """ - } else { + } + else { """ touch ${prefix}.md5 - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - md5sum: \$( md5sum --version | sed '1!d; s/.* //' ) - END_VERSIONS """ } - } diff --git a/modules/nf-core/md5sum/meta.yml b/modules/nf-core/md5sum/meta.yml index 363d763f..71066a84 100644 --- a/modules/nf-core/md5sum/meta.yml +++ b/modules/nf-core/md5sum/meta.yml @@ -9,7 +9,8 @@ tools: description: Create MD5 (128-bit) checksums for each file homepage: "https://www.gnu.org" documentation: "https://man7.org/linux/man-pages/man1/md5sum.1.html" - licence: ["GPL-3.0-or-later"] + licence: + - "GPL-3.0-or-later" identifier: "" input: - - meta: @@ -19,16 +20,18 @@ input: e.g. [ id:'test', single_end:false ] - files: type: file - description: Any number of files. One md5sum file will be generated for each. + description: Any number of files. One md5sum file will be generated for + each. pattern: "*.*" - - - as_separate_files: - type: boolean - description: | - If true, each file will have its own md5sum file. If false, all files will be - checksummed into a single md5sum file. + ontologies: [] + - as_separate_files: + type: boolean + description: | + If true, each file will have its own md5sum file. If false, all files will be + checksummed into a single md5sum file. output: - - checksum: - - meta: + checksum: + - - meta: type: map description: | Groovy Map containing sample information @@ -37,11 +40,28 @@ output: type: file description: File containing checksum pattern: "*.md5" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_md5sum: + - - ${task.process}: + type: string + description: The name of the process + - md5sum: + type: string + description: The name of the tool + - md5sum --version | sed '1!d; s/.* //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - md5sum: + type: string + description: The name of the tool + - md5sum --version | sed '1!d; s/.* //': + type: eval + description: The expression to obtain the version of the tool authors: - "@matthdsm" maintainers: diff --git a/modules/nf-core/md5sum/tests/main.nf.test.snap b/modules/nf-core/md5sum/tests/main.nf.test.snap index cd7593b4..bf78c29b 100644 --- a/modules/nf-core/md5sum/tests/main.nf.test.snap +++ b/modules/nf-core/md5sum/tests/main.nf.test.snap @@ -14,7 +14,11 @@ ] ], "1": [ - "versions.yml:md5,5745fe6b917070b6158ade64fcb4aa91" + [ + "MD5SUM", + "md5sum", + "9.5" + ] ], "checksum": [ [ @@ -27,16 +31,20 @@ ] ] ], - "versions": [ - "versions.yml:md5,5745fe6b917070b6158ade64fcb4aa91" + "versions_md5sum": [ + [ + "MD5SUM", + "md5sum", + "9.5" + ] ] } ], + "timestamp": "2026-02-18T14:31:17.339668", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-07-01T11:05:22.111018419" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "md5sum on paired fastq, separate": { "content": [ @@ -53,7 +61,11 @@ ] ], "1": [ - "versions.yml:md5,5745fe6b917070b6158ade64fcb4aa91" + [ + "MD5SUM", + "md5sum", + "9.5" + ] ], "checksum": [ [ @@ -66,16 +78,20 @@ ] ] ], - "versions": [ - "versions.yml:md5,5745fe6b917070b6158ade64fcb4aa91" + "versions_md5sum": [ + [ + "MD5SUM", + "md5sum", + "9.5" + ] ] } ], + "timestamp": "2026-02-18T14:31:11.522274", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-07-01T11:05:12.083864677" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "md5sum on hello.txt - stub": { "content": [ @@ -89,7 +105,11 @@ ] ], "1": [ - "versions.yml:md5,5745fe6b917070b6158ade64fcb4aa91" + [ + "MD5SUM", + "md5sum", + "9.5" + ] ], "checksum": [ [ @@ -99,16 +119,20 @@ "hello.txt.md5:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,5745fe6b917070b6158ade64fcb4aa91" + "versions_md5sum": [ + [ + "MD5SUM", + "md5sum", + "9.5" + ] ] } ], + "timestamp": "2026-02-18T14:30:52.301881", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-07-01T11:04:42.230073228" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "md5sum on hello.txt": { "content": [ @@ -122,7 +146,11 @@ ] ], "1": [ - "versions.yml:md5,5745fe6b917070b6158ade64fcb4aa91" + [ + "MD5SUM", + "md5sum", + "9.5" + ] ], "checksum": [ [ @@ -132,16 +160,20 @@ "hello.txt.md5:md5,5c18e1db5460fb32fed66966483165fd" ] ], - "versions": [ - "versions.yml:md5,5745fe6b917070b6158ade64fcb4aa91" + "versions_md5sum": [ + [ + "MD5SUM", + "md5sum", + "9.5" + ] ] } ], + "timestamp": "2026-02-18T14:30:41.089186", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-07-01T11:04:22.089948509" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "md5sum on paired fastq, combined": { "content": [ @@ -155,7 +187,11 @@ ] ], "1": [ - "versions.yml:md5,5745fe6b917070b6158ade64fcb4aa91" + [ + "MD5SUM", + "md5sum", + "9.5" + ] ], "checksum": [ [ @@ -165,16 +201,20 @@ "test.md5:md5,dfb98e45cbb77a9a63ae7029aee38bd1" ] ], - "versions": [ - "versions.yml:md5,5745fe6b917070b6158ade64fcb4aa91" + "versions_md5sum": [ + [ + "MD5SUM", + "md5sum", + "9.5" + ] ] } ], + "timestamp": "2026-02-18T14:30:58.611754", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-07-01T11:04:52.085480359" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "md5sum on paired fastq, combined - stub": { "content": [ @@ -188,7 +228,11 @@ ] ], "1": [ - "versions.yml:md5,5745fe6b917070b6158ade64fcb4aa91" + [ + "MD5SUM", + "md5sum", + "9.5" + ] ], "checksum": [ [ @@ -198,16 +242,20 @@ "test.md5:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,5745fe6b917070b6158ade64fcb4aa91" + "versions_md5sum": [ + [ + "MD5SUM", + "md5sum", + "9.5" + ] ] } ], + "timestamp": "2026-02-18T14:31:06.064053", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-07-01T11:05:01.935454952" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "md5sum on hello.txt (BSD-style)": { "content": [ @@ -221,7 +269,11 @@ ] ], "1": [ - "versions.yml:md5,5745fe6b917070b6158ade64fcb4aa91" + [ + "MD5SUM", + "md5sum", + "9.5" + ] ], "checksum": [ [ @@ -231,15 +283,19 @@ "hello.txt.md5:md5,152a03f5dc7aa8db6612f63154ecbca2" ] ], - "versions": [ - "versions.yml:md5,5745fe6b917070b6158ade64fcb4aa91" + "versions_md5sum": [ + [ + "MD5SUM", + "md5sum", + "9.5" + ] ] } ], + "timestamp": "2026-02-18T14:30:46.389675", "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-07-01T11:04:32.078323542" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/md5sum/tests/nextflow.config b/modules/nf-core/md5sum/tests/nextflow.config index de999064..4acada55 100644 --- a/modules/nf-core/md5sum/tests/nextflow.config +++ b/modules/nf-core/md5sum/tests/nextflow.config @@ -1,2 +1,2 @@ -process.ext.args = '--tag' \ No newline at end of file +process.ext.args = '--tag' diff --git a/modules/nf-core/md5sum/tests/tags.yml b/modules/nf-core/md5sum/tests/tags.yml deleted file mode 100644 index bb45d190..00000000 --- a/modules/nf-core/md5sum/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -md5sum: - - "modules/nf-core/md5sum/**" diff --git a/modules/nf-core/mosdepth/environment.yml b/modules/nf-core/mosdepth/environment.yml index e9379873..1c7f3ee8 100644 --- a/modules/nf-core/mosdepth/environment.yml +++ b/modules/nf-core/mosdepth/environment.yml @@ -1,6 +1,9 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: # renovate: datasource=conda depName=bioconda/mosdepth - - mosdepth=0.3.8 + - htslib=1.22.1 + - mosdepth=0.3.11=h0ec343a_1 diff --git a/modules/nf-core/mosdepth/main.nf b/modules/nf-core/mosdepth/main.nf index 3631cdb3..b5ee3823 100644 --- a/modules/nf-core/mosdepth/main.nf +++ b/modules/nf-core/mosdepth/main.nf @@ -4,8 +4,8 @@ process MOSDEPTH { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/mosdepth:0.3.8--hd299d5a_0' : - 'biocontainers/mosdepth:0.3.8--hd299d5a_0'}" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/00/00d32b53160c26794959da7303ee6e2107afd4d292060c9f287b0af1fddbd847/data' : + 'community.wave.seqera.io/library/mosdepth_htslib:0f58993cb6d93294'}" input: tuple val(meta), path(bam), path(bai), path(bed), path(fasta) @@ -23,7 +23,7 @@ process MOSDEPTH { tuple val(meta), path('*.quantized.bed.gz.csi') , optional:true, emit: quantized_csi tuple val(meta), path('*.thresholds.bed.gz') , optional:true, emit: thresholds_bed tuple val(meta), path('*.thresholds.bed.gz.csi'), optional:true, emit: thresholds_csi - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('mosdepth'), eval("mosdepth --version | sed 's/mosdepth //g'"), topic: versions, emit: versions_mosdepth when: task.ext.when == null || task.ext.when @@ -33,11 +33,11 @@ process MOSDEPTH { def prefix = task.ext.prefix ?: "${meta.id}" def reference = fasta ? "--fasta ${fasta}" : "" def interval = bed ? "--by ${bed}" : "" - if (bed && args.contains("--by")) { + if (bed && (args.contains("--by") || args.contains("-b "))) { error "'--by' can only be specified once when running mosdepth! Either remove input BED file definition or remove '--by' from 'ext.args' definition" } - if (!bed && args.contains("--thresholds")) { - error "'--thresholds' can only be specified in conjunction with '--by'" + if (args.contains("--thresholds") && !(bed || args.contains("--by") || args.contains("-b "))) { + error "'--thresholds' can only be specified in conjunction with '--by' or an input bed file" } """ @@ -48,15 +48,17 @@ process MOSDEPTH { $args \\ $prefix \\ $bam - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - mosdepth: \$(mosdepth --version 2>&1 | sed 's/^.*mosdepth //; s/ .*\$//') - END_VERSIONS """ stub: + def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" + if (bed && (args.contains("--by") || args.contains("-b "))) { + error "'--by' can only be specified once when running mosdepth! Either remove input BED file definition or remove '--by' from 'ext.args' definition" + } + if (args.contains("--thresholds") && !(bed || args.contains("--by") || args.contains("-b "))) { + error "'--thresholds' can only be specified in conjunction with '--by' or an input bed file" + } """ touch ${prefix}.global.dist.txt touch ${prefix}.region.dist.txt @@ -70,10 +72,5 @@ process MOSDEPTH { touch ${prefix}.quantized.bed.gz.csi echo "" | gzip > ${prefix}.thresholds.bed.gz touch ${prefix}.thresholds.bed.gz.csi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - mosdepth: \$(mosdepth --version 2>&1 | sed 's/^.*mosdepth //; s/ .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/mosdepth/meta.yml b/modules/nf-core/mosdepth/meta.yml index dc783c90..04c8bfe1 100644 --- a/modules/nf-core/mosdepth/meta.yml +++ b/modules/nf-core/mosdepth/meta.yml @@ -23,14 +23,17 @@ input: type: file description: Input BAM/CRAM file pattern: "*.{bam,cram}" + ontologies: [] - bai: type: file description: Index for BAM/CRAM file pattern: "*.{bai,crai}" + ontologies: [] - bed: type: file description: BED file with intersected intervals pattern: "*.{bed}" + ontologies: [] - - meta2: type: map description: | @@ -40,9 +43,10 @@ input: type: file description: Reference genome FASTA file pattern: "*.{fa,fasta}" + ontologies: [] output: - - global_txt: - - meta: + global_txt: + - - meta: type: map description: | Groovy Map containing sample information @@ -51,8 +55,9 @@ output: type: file description: Text file with global cumulative coverage distribution pattern: "*.{global.dist.txt}" - - summary_txt: - - meta: + ontologies: [] + summary_txt: + - - meta: type: map description: | Groovy Map containing sample information @@ -61,8 +66,9 @@ output: type: file description: Text file with summary mean depths per chromosome and regions pattern: "*.{summary.txt}" - - regions_txt: - - meta: + ontologies: [] + regions_txt: + - - meta: type: map description: | Groovy Map containing sample information @@ -71,8 +77,9 @@ output: type: file description: Text file with region cumulative coverage distribution pattern: "*.{region.dist.txt}" - - per_base_d4: - - meta: + ontologies: [] + per_base_d4: + - - meta: type: map description: | Groovy Map containing sample information @@ -81,8 +88,9 @@ output: type: file description: D4 file with per-base coverage pattern: "*.{per-base.d4}" - - per_base_bed: - - meta: + ontologies: [] + per_base_bed: + - - meta: type: map description: | Groovy Map containing sample information @@ -91,8 +99,9 @@ output: type: file description: BED file with per-base coverage pattern: "*.{per-base.bed.gz}" - - per_base_csi: - - meta: + ontologies: [] + per_base_csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -101,8 +110,9 @@ output: type: file description: Index file for BED file with per-base coverage pattern: "*.{per-base.bed.gz.csi}" - - regions_bed: - - meta: + ontologies: [] + regions_bed: + - - meta: type: map description: | Groovy Map containing sample information @@ -111,8 +121,9 @@ output: type: file description: BED file with per-region coverage pattern: "*.{regions.bed.gz}" - - regions_csi: - - meta: + ontologies: [] + regions_csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -121,8 +132,9 @@ output: type: file description: Index file for BED file with per-region coverage pattern: "*.{regions.bed.gz.csi}" - - quantized_bed: - - meta: + ontologies: [] + quantized_bed: + - - meta: type: map description: | Groovy Map containing sample information @@ -131,8 +143,9 @@ output: type: file description: BED file with binned coverage pattern: "*.{quantized.bed.gz}" - - quantized_csi: - - meta: + ontologies: [] + quantized_csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -141,8 +154,9 @@ output: type: file description: Index file for BED file with binned coverage pattern: "*.{quantized.bed.gz.csi}" - - thresholds_bed: - - meta: + ontologies: [] + thresholds_bed: + - - meta: type: map description: | Groovy Map containing sample information @@ -152,8 +166,9 @@ output: description: BED file with the number of bases in each region that are covered at or above each threshold pattern: "*.{thresholds.bed.gz}" - - thresholds_csi: - - meta: + ontologies: [] + thresholds_csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -162,11 +177,29 @@ output: type: file description: Index file for BED file with threshold coverage pattern: "*.{thresholds.bed.gz.csi}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_mosdepth: + - - ${task.process}: + type: string + description: The process the versions were collected from + - mosdepth: + type: string + description: The tool name + - "mosdepth --version | sed 's/mosdepth //g'": + type: string + description: The command used to generate the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - mosdepth: + type: string + description: The tool name + - "mosdepth --version | sed 's/mosdepth //g'": + type: string + description: The command used to generate the version of the tool authors: - "@joseespinosa" - "@drpatelh" @@ -174,6 +207,5 @@ authors: - "@matthdsm" maintainers: - "@joseespinosa" - - "@drpatelh" - "@ramprasadn" - "@matthdsm" diff --git a/modules/nf-core/mosdepth/mosdepth.diff b/modules/nf-core/mosdepth/mosdepth.diff index 53e32f2b..ba8f8c40 100644 --- a/modules/nf-core/mosdepth/mosdepth.diff +++ b/modules/nf-core/mosdepth/mosdepth.diff @@ -1,11 +1,11 @@ -Changes in module 'nf-core/mosdepth' +Changes in component 'nf-core/mosdepth' 'modules/nf-core/mosdepth/environment.yml' is unchanged 'modules/nf-core/mosdepth/meta.yml' is unchanged Changes in 'mosdepth/main.nf': --- modules/nf-core/mosdepth/main.nf +++ modules/nf-core/mosdepth/main.nf @@ -8,8 +8,7 @@ - 'biocontainers/mosdepth:0.3.8--hd299d5a_0'}" + 'community.wave.seqera.io/library/mosdepth_htslib:0f58993cb6d93294'}" input: - tuple val(meta), path(bam), path(bai), path(bed) @@ -16,9 +16,6 @@ Changes in 'mosdepth/main.nf': tuple val(meta), path('*.global.dist.txt') , emit: global_txt 'modules/nf-core/mosdepth/tests/main.nf.test.snap' is unchanged -'modules/nf-core/mosdepth/tests/threshold.config' is unchanged -'modules/nf-core/mosdepth/tests/quantized.config' is unchanged -'modules/nf-core/mosdepth/tests/tags.yml' is unchanged +'modules/nf-core/mosdepth/tests/nextflow.config' is unchanged 'modules/nf-core/mosdepth/tests/main.nf.test' is unchanged -'modules/nf-core/mosdepth/tests/window.config' is unchanged ************************************************************ diff --git a/modules/nf-core/mosdepth/tests/main.nf.test b/modules/nf-core/mosdepth/tests/main.nf.test index 0b3c860d..b05dde5b 100644 --- a/modules/nf-core/mosdepth/tests/main.nf.test +++ b/modules/nf-core/mosdepth/tests/main.nf.test @@ -7,10 +7,14 @@ nextflow_process { tag "modules" tag "modules_nfcore" tag "mosdepth" + config "./nextflow.config" test("homo_sapiens - bam, bai, []") { when { + params { + module_args = "" + } process { """ input[0] = [ @@ -25,9 +29,9 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out).match()} ) } @@ -36,6 +40,9 @@ nextflow_process { test("homo_sapiens - bam, bai, bed") { when { + params { + module_args = "" + } process { """ input[0] = [ @@ -50,9 +57,9 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out).match()} ) } @@ -61,6 +68,9 @@ nextflow_process { test("homo_sapiens - cram, crai, []") { when { + params { + module_args = "" + } process { """ input[0] = [ @@ -78,9 +88,9 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out).match()} ) } @@ -89,6 +99,9 @@ nextflow_process { test("homo_sapiens - cram, crai, bed") { when { + params { + module_args = "" + } process { """ input[0] = [ @@ -106,9 +119,9 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out).match()} ) } @@ -116,8 +129,10 @@ nextflow_process { test("homo_sapiens - bam, bai, [] - window") { - config "./window.config" when { + params { + module_args = "--by 100" + } process { """ input[0] = [ @@ -132,9 +147,9 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out).match()} ) } @@ -142,8 +157,10 @@ nextflow_process { test("homo_sapiens - bam, bai, [] - quantized") { - config "./quantized.config" when { + params { + module_args = "--quantize 0:1:4:100:200" + } process { """ input[0] = [ @@ -158,9 +175,9 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out).match()} ) } @@ -168,8 +185,10 @@ nextflow_process { test("homo_sapiens - bam, bai, bed - thresholds") { - config "./threshold.config" when { + params { + module_args = "--thresholds 1,10,20,30" + } process { """ input[0] = [ @@ -184,9 +203,9 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out).match()} ) } @@ -194,8 +213,10 @@ nextflow_process { test("homo_sapiens - bam, bai, bed - fail") { - config "./window.config" when { + params { + module_args = "--by 100" + } process { """ input[0] = [ @@ -210,9 +231,7 @@ nextflow_process { } then { - assertAll( - { assert process.failed } - ) + assert process.failed } } @@ -221,6 +240,9 @@ nextflow_process { options "-stub" when { + params { + module_args = "" + } process { """ input[0] = [ @@ -235,9 +257,9 @@ nextflow_process { } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out).match()} ) } diff --git a/modules/nf-core/mosdepth/tests/main.nf.test.snap b/modules/nf-core/mosdepth/tests/main.nf.test.snap index c604540b..c27fcc79 100644 --- a/modules/nf-core/mosdepth/tests/main.nf.test.snap +++ b/modules/nf-core/mosdepth/tests/main.nf.test.snap @@ -39,7 +39,11 @@ ] ], "12": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ], "2": [ [ @@ -221,16 +225,20 @@ "test.thresholds.bed.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + "versions_mosdepth": [ + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.7" }, - "timestamp": "2024-04-29T13:33:16.953408231" + "timestamp": "2025-09-23T13:06:13.219131" }, "homo_sapiens - cram, crai, bed": { "content": [ @@ -260,7 +268,11 @@ ], "12": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ], "2": [ [ @@ -289,7 +301,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "6": [ @@ -307,7 +319,7 @@ "id": "test", "single_end": true }, - "test.regions.bed.gz.csi:md5,e7df086f0a36e88ca231e143d43bd3f9" + "test.regions.bed.gz.csi:md5,c33ac5c86370039463796f01434fc0e4" ] ], "8": [ @@ -340,7 +352,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "per_base_d4": [ @@ -367,7 +379,7 @@ "id": "test", "single_end": true }, - "test.regions.bed.gz.csi:md5,e7df086f0a36e88ca231e143d43bd3f9" + "test.regions.bed.gz.csi:md5,c33ac5c86370039463796f01434fc0e4" ] ], "regions_txt": [ @@ -394,16 +406,20 @@ "thresholds_csi": [ ], - "versions": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + "versions_mosdepth": [ + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.7" }, - "timestamp": "2024-04-29T13:32:50.160217828" + "timestamp": "2025-09-23T13:22:14.011309" }, "homo_sapiens - bam, bai, [] - quantized": { "content": [ @@ -433,7 +449,11 @@ ], "12": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ], "2": [ @@ -456,7 +476,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "6": [ @@ -480,7 +500,7 @@ "id": "test", "single_end": true }, - "test.quantized.bed.gz.csi:md5,4f69e6ace50206a2768be66ded3a56f0" + "test.quantized.bed.gz.csi:md5,c0a3176a59010639455a4aefb3f247ef" ] ], "global_txt": [ @@ -507,7 +527,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "per_base_d4": [ @@ -528,7 +548,7 @@ "id": "test", "single_end": true }, - "test.quantized.bed.gz.csi:md5,4f69e6ace50206a2768be66ded3a56f0" + "test.quantized.bed.gz.csi:md5,c0a3176a59010639455a4aefb3f247ef" ] ], "regions_bed": [ @@ -555,16 +575,20 @@ "thresholds_csi": [ ], - "versions": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + "versions_mosdepth": [ + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.7" }, - "timestamp": "2024-04-29T13:33:01.164885111" + "timestamp": "2025-09-23T13:22:22.818082" }, "homo_sapiens - bam, bai, bed": { "content": [ @@ -594,7 +618,11 @@ ], "12": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ], "2": [ [ @@ -623,7 +651,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "6": [ @@ -641,7 +669,7 @@ "id": "test", "single_end": true }, - "test.regions.bed.gz.csi:md5,e7df086f0a36e88ca231e143d43bd3f9" + "test.regions.bed.gz.csi:md5,c33ac5c86370039463796f01434fc0e4" ] ], "8": [ @@ -674,7 +702,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "per_base_d4": [ @@ -701,7 +729,7 @@ "id": "test", "single_end": true }, - "test.regions.bed.gz.csi:md5,e7df086f0a36e88ca231e143d43bd3f9" + "test.regions.bed.gz.csi:md5,c33ac5c86370039463796f01434fc0e4" ] ], "regions_txt": [ @@ -728,16 +756,20 @@ "thresholds_csi": [ ], - "versions": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + "versions_mosdepth": [ + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.7" }, - "timestamp": "2024-04-29T13:32:39.071657456" + "timestamp": "2025-09-23T13:22:04.449943" }, "homo_sapiens - bam, bai, [] - window": { "content": [ @@ -767,7 +799,11 @@ ], "12": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ], "2": [ [ @@ -796,7 +832,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "6": [ @@ -814,7 +850,7 @@ "id": "test", "single_end": true }, - "test.regions.bed.gz.csi:md5,2a30bcb7f5c7632136b3efce24723970" + "test.regions.bed.gz.csi:md5,17a2cbe22a948d7c004b90a1f28347a1" ] ], "8": [ @@ -847,7 +883,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "per_base_d4": [ @@ -874,7 +910,7 @@ "id": "test", "single_end": true }, - "test.regions.bed.gz.csi:md5,2a30bcb7f5c7632136b3efce24723970" + "test.regions.bed.gz.csi:md5,17a2cbe22a948d7c004b90a1f28347a1" ] ], "regions_txt": [ @@ -901,16 +937,20 @@ "thresholds_csi": [ ], - "versions": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + "versions_mosdepth": [ + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.7" }, - "timestamp": "2024-04-29T13:32:55.631776118" + "timestamp": "2025-09-23T13:22:18.435089" }, "homo_sapiens - bam, bai, []": { "content": [ @@ -940,7 +980,11 @@ ], "12": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ], "2": [ @@ -963,7 +1007,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "6": [ @@ -1002,7 +1046,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "per_base_d4": [ @@ -1038,16 +1082,20 @@ "thresholds_csi": [ ], - "versions": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + "versions_mosdepth": [ + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.7" }, - "timestamp": "2024-04-29T13:32:33.642125299" + "timestamp": "2025-09-23T13:21:59.785829" }, "homo_sapiens - cram, crai, []": { "content": [ @@ -1077,7 +1125,11 @@ ], "12": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ], "2": [ @@ -1100,7 +1152,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "6": [ @@ -1139,7 +1191,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "per_base_d4": [ @@ -1175,16 +1227,20 @@ "thresholds_csi": [ ], - "versions": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + "versions_mosdepth": [ + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.7" }, - "timestamp": "2024-04-29T13:32:44.704920941" + "timestamp": "2025-09-23T13:22:09.294766" }, "homo_sapiens - bam, bai, bed - thresholds": { "content": [ @@ -1222,11 +1278,15 @@ "id": "test", "single_end": true }, - "test.thresholds.bed.gz.csi:md5,219414a0751185adb98d2235d83ea055" + "test.thresholds.bed.gz.csi:md5,2c52ab89e7496af475de3cb2ca04c7b3" ] ], "12": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ], "2": [ [ @@ -1255,7 +1315,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "6": [ @@ -1273,7 +1333,7 @@ "id": "test", "single_end": true }, - "test.regions.bed.gz.csi:md5,e7df086f0a36e88ca231e143d43bd3f9" + "test.regions.bed.gz.csi:md5,c33ac5c86370039463796f01434fc0e4" ] ], "8": [ @@ -1306,7 +1366,7 @@ "id": "test", "single_end": true }, - "test.per-base.bed.gz.csi:md5,6f322dc9250522a701bd68bd18fa8294" + "test.per-base.bed.gz.csi:md5,6adccf94ed775c9f53422e3e9c7af27f" ] ], "per_base_d4": [ @@ -1333,7 +1393,7 @@ "id": "test", "single_end": true }, - "test.regions.bed.gz.csi:md5,e7df086f0a36e88ca231e143d43bd3f9" + "test.regions.bed.gz.csi:md5,c33ac5c86370039463796f01434fc0e4" ] ], "regions_txt": [ @@ -1369,18 +1429,22 @@ "id": "test", "single_end": true }, - "test.thresholds.bed.gz.csi:md5,219414a0751185adb98d2235d83ea055" + "test.thresholds.bed.gz.csi:md5,2c52ab89e7496af475de3cb2ca04c7b3" ] ], - "versions": [ - "versions.yml:md5,87634e525fb18990cd98fe1080ad72ce" + "versions_mosdepth": [ + [ + "MOSDEPTH", + "mosdepth", + "0.3.11" + ] ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.7" }, - "timestamp": "2024-04-29T13:33:06.737266831" + "timestamp": "2025-09-23T13:22:27.300204" } } \ No newline at end of file diff --git a/modules/nf-core/mosdepth/tests/nextflow.config b/modules/nf-core/mosdepth/tests/nextflow.config new file mode 100644 index 00000000..b21c05b5 --- /dev/null +++ b/modules/nf-core/mosdepth/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: "MOSDEPTH" { + ext.args = params.module_args + } +} diff --git a/modules/nf-core/mosdepth/tests/quantized.config b/modules/nf-core/mosdepth/tests/quantized.config deleted file mode 100644 index 63c55350..00000000 --- a/modules/nf-core/mosdepth/tests/quantized.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = "--quantize 0:1:4:100:200" -} \ No newline at end of file diff --git a/modules/nf-core/mosdepth/tests/tags.yml b/modules/nf-core/mosdepth/tests/tags.yml deleted file mode 100644 index 5cd2e08e..00000000 --- a/modules/nf-core/mosdepth/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -mosdepth: - - "modules/nf-core/mosdepth/**" diff --git a/modules/nf-core/mosdepth/tests/threshold.config b/modules/nf-core/mosdepth/tests/threshold.config deleted file mode 100644 index 9b014ddf..00000000 --- a/modules/nf-core/mosdepth/tests/threshold.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = "--thresholds 1,10,20,30" -} \ No newline at end of file diff --git a/modules/nf-core/mosdepth/tests/window.config b/modules/nf-core/mosdepth/tests/window.config deleted file mode 100644 index 7a0f755c..00000000 --- a/modules/nf-core/mosdepth/tests/window.config +++ /dev/null @@ -1,3 +0,0 @@ -process { - ext.args = "--by 100" -} \ No newline at end of file diff --git a/modules/nf-core/multiqc/environment.yml b/modules/nf-core/multiqc/environment.yml index 812fc4c5..009874d4 100644 --- a/modules/nf-core/multiqc/environment.yml +++ b/modules/nf-core/multiqc/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::multiqc=1.29 + - bioconda::multiqc=1.33 diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index 0ac3c369..5376aea1 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -1,24 +1,21 @@ process MULTIQC { + tag "${meta.id}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.29--pyhdfd78af_0' : - 'biocontainers/multiqc:1.29--pyhdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/34/34e733a9ae16a27e80fe00f863ea1479c96416017f24a907996126283e7ecd4d/data' + : 'community.wave.seqera.io/library/multiqc:1.33--ee7739d47738383b'}" input: - path multiqc_files, stageAs: "?/*" - path(multiqc_config) - path(extra_multiqc_config) - path(multiqc_logo) - path(replace_names) - path(sample_names) + tuple val(meta), path(multiqc_files, stageAs: "?/*"), path(multiqc_config, stageAs: "?/*"), path(multiqc_logo), path(replace_names), path(sample_names) output: - path "*multiqc_report.html", emit: report - path "*_data" , emit: data - path "*_plots" , optional:true, emit: plots - path "versions.yml" , emit: versions + tuple val(meta), path("*.html"), emit: report + tuple val(meta), path("*_data"), emit: data + tuple val(meta), path("*_plots"), emit: plots, optional: true + // MultiQC should not push its versions to the `versions` topic. Its input depends on the versions topic to be resolved thus outputting to the topic will let the pipeline hang forever + tuple val("${task.process}"), val('multiqc'), eval('multiqc --version | sed "s/.* //g"'), emit: versions when: task.ext.when == null || task.ext.when @@ -26,38 +23,28 @@ process MULTIQC { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ? "--filename ${task.ext.prefix}.html" : '' - def config = multiqc_config ? "--config $multiqc_config" : '' - def extra_config = extra_multiqc_config ? "--config $extra_multiqc_config" : '' + def config = multiqc_config ? multiqc_config instanceof List ? "--config ${multiqc_config.join(' --config ')}" : "--config ${multiqc_config}" : "" def logo = multiqc_logo ? "--cl-config 'custom_logo: \"${multiqc_logo}\"'" : '' def replace = replace_names ? "--replace-names ${replace_names}" : '' def samples = sample_names ? "--sample-names ${sample_names}" : '' """ multiqc \\ --force \\ - $args \\ - $config \\ - $prefix \\ - $extra_config \\ - $logo \\ - $replace \\ - $samples \\ + ${args} \\ + ${config} \\ + ${prefix} \\ + ${logo} \\ + ${replace} \\ + ${samples} \\ . - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" ) - END_VERSIONS """ stub: """ mkdir multiqc_data + touch multiqc_data/.stub mkdir multiqc_plots + touch multiqc_plots/.stub touch multiqc_report.html - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" ) - END_VERSIONS """ } diff --git a/modules/nf-core/multiqc/meta.yml b/modules/nf-core/multiqc/meta.yml index b16c1879..ef434a9a 100644 --- a/modules/nf-core/multiqc/meta.yml +++ b/modules/nf-core/multiqc/meta.yml @@ -1,6 +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,60 +12,91 @@ tools: It's a general use tool, perfect for summarising the output from numerous bioinformatics tools. homepage: https://multiqc.info/ documentation: https://multiqc.info/docs/ - licence: ["GPL-3.0-or-later"] + licence: + - "GPL-3.0-or-later" identifier: biotools:multiqc input: - - - multiqc_files: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', single_end:false ] + - multiqc_files: type: file description: | List of reports / files recognised by MultiQC, for example the html and zip output of FastQC - - - multiqc_config: + ontologies: [] + - 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: + ontologies: + - edam: http://edamontology.org/format_3750 + - multiqc_logo: type: file description: Optional logo file for MultiQC pattern: "*.{png}" - - - replace_names: + ontologies: [] + - 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: + ontologies: + - edam: http://edamontology.org/format_3475 + - sample_names: type: file description: | Optional TSV file with headers, passed to the MultiQC --sample_names argument. pattern: "*.{tsv}" + ontologies: + - edam: http://edamontology.org/format_3475 output: - - report: - - "*multiqc_report.html": + report: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', single_end:false ] + - "*.html": type: file description: MultiQC report file - pattern: "multiqc_report.html" - - data: + pattern: ".html" + ontologies: [] + data: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', single_end:false ] - "*_data": type: directory description: MultiQC data dir pattern: "multiqc_data" - - plots: + plots: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', single_end:false ] - "*_plots": type: file description: Plots created by MultiQC - pattern: "*_data" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + pattern: "*_plots" + ontologies: [] + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - multiqc: + type: string + description: The tool name + - multiqc --version | sed "s/.* //g": + type: eval + description: The expression to obtain the version of the tool authors: - "@abhi18av" - "@bunop" @@ -76,3 +107,27 @@ maintainers: - "@bunop" - "@drpatelh" - "@jfy133" +containers: + conda: + linux/amd64: + lock_file: https://wave.seqera.io/v1alpha1/builds/bd-ee7739d47738383b_1/condalock + linux/arm64: + lock_file: https://wave.seqera.io/v1alpha1/builds/bd-58d7dee710ab3aa8_1/condalock + docker: + linux/amd64: + build_id: bd-ee7739d47738383b_1 + name: community.wave.seqera.io/library/multiqc:1.33--ee7739d47738383b + scanId: sc-6ddec592dcadd583_4 + linux/arm64: + build_id: bd-58d7dee710ab3aa8_1 + name: community.wave.seqera.io/library/multiqc:1.33--58d7dee710ab3aa8 + scanId: sc-a04c42273e34c55c_2 + singularity: + linux/amd64: + build_id: bd-e3576ddf588fa00d_1 + https: https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/34/34e733a9ae16a27e80fe00f863ea1479c96416017f24a907996126283e7ecd4d/data + name: oras://community.wave.seqera.io/library/multiqc:1.33--e3576ddf588fa00d + linux/arm64: + build_id: bd-2537ca5f8445e3c2_1 + https: https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/78/78b89e91d89e9cc99ad5ade5be311f347838cb2acbfb4f13bc343b170be09ce4/data + name: oras://community.wave.seqera.io/library/multiqc:1.33--2537ca5f8445e3c2 diff --git a/modules/nf-core/multiqc/tests/custom_prefix.config b/modules/nf-core/multiqc/tests/custom_prefix.config new file mode 100644 index 00000000..b30b1358 --- /dev/null +++ b/modules/nf-core/multiqc/tests/custom_prefix.config @@ -0,0 +1,5 @@ +process { + withName: 'MULTIQC' { + ext.prefix = "custom_prefix" + } +} diff --git a/modules/nf-core/multiqc/tests/main.nf.test b/modules/nf-core/multiqc/tests/main.nf.test index 33316a7d..0e422eaa 100644 --- a/modules/nf-core/multiqc/tests/main.nf.test +++ b/modules/nf-core/multiqc/tests/main.nf.test @@ -15,25 +15,58 @@ nextflow_process { when { process { """ - input[0] = Channel.of(file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true)) - input[1] = [] - input[2] = [] - input[3] = [] - input[4] = [] - input[5] = [] + input[0] = channel.of([ + [ id: 'FASTQC' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true), + [], + [], + [], + [] + ]) """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert process.out.report[0] ==~ ".*/multiqc_report.html" }, - { assert process.out.data[0] ==~ ".*/multiqc_data" }, - { assert snapshot(process.out.versions).match("multiqc_versions_single") } + { assert snapshot( + file(process.out.report[0][1]).name, + file(process.out.data[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") + }).match() } ) } + } + + test("sarscov2 single-end [fastqc] - custom prefix") { + config "./custom_prefix.config" + + when { + process { + """ + input[0] = channel.of([ + [ id: 'FASTQC' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true), + [], + [], + [], + [] + ]) + """ + } + } + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.report[0][1]).name, + file(process.out.data[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") + }).match() } + ) + } } test("sarscov2 single-end [fastqc] [config]") { @@ -41,22 +74,60 @@ nextflow_process { when { process { """ - input[0] = Channel.of(file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true)) - 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] = [] + input[0] = channel.of([ + [ id: 'FASTQC' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true), + file("https://github.com/nf-core/tools/raw/dev/nf_core/pipeline-template/assets/multiqc_config.yml", checkIfExists: true), + [], + [], + [] + ]) + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.report[0][1]).name, + file(process.out.data[0][1]).name, + file(process.out.plots[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") + }).match() } + ) + } + } + + test("sarscov2 single-end [fastqc] [multiple configs]") { + + when { + process { + """ + input[0] = channel.of([ + [ id: 'FASTQC' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true), + [ + file("https://github.com/nf-core/tools/raw/dev/nf_core/pipeline-template/assets/multiqc_config.yml", checkIfExists: true), + file("https://github.com/nf-core/tools/raw/dev/nf_core/pipeline-template/assets/multiqc_config.yml", checkIfExists: true) + ], + [], + [], + [] + ]) """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert process.out.report[0] ==~ ".*/multiqc_report.html" }, - { assert process.out.data[0] ==~ ".*/multiqc_data" }, - { assert snapshot(process.out.versions).match("multiqc_versions_config") } + { assert snapshot( + file(process.out.report[0][1]).name, + file(process.out.data[0][1]).name, + file(process.out.plots[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") + }).match() } ) } } @@ -68,25 +139,23 @@ nextflow_process { when { process { """ - input[0] = Channel.of(file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true)) - input[1] = [] - input[2] = [] - input[3] = [] - input[4] = [] - input[5] = [] + input[0] = channel.of([ + [ id: 'FASTQC' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true), + [], + [], + [], + [] + ]) """ } } then { + assert process.success assertAll( - { assert process.success }, - { assert snapshot(process.out.report.collect { file(it).getName() } + - process.out.data.collect { file(it).getName() } + - process.out.plots.collect { file(it).getName() } + - process.out.versions ).match("multiqc_stub") } + { assert snapshot(sanitizeOutput(process.out)).match() } ) } - } } diff --git a/modules/nf-core/multiqc/tests/main.nf.test.snap b/modules/nf-core/multiqc/tests/main.nf.test.snap index 25caea81..c022701f 100644 --- a/modules/nf-core/multiqc/tests/main.nf.test.snap +++ b/modules/nf-core/multiqc/tests/main.nf.test.snap @@ -1,41 +1,130 @@ { - "multiqc_versions_single": { + "sarscov2 single-end [fastqc] [multiple configs]": { "content": [ - [ - "versions.yml:md5,c1fe644a37468f6dae548d98bc72c2c1" - ] + "multiqc_report.html", + "multiqc_data", + "multiqc_plots", + { + "versions": [ + [ + "MULTIQC", + "multiqc", + "1.33" + ] + ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2025-06-03T09:17:40.895950399" + "timestamp": "2026-02-26T20:21:35.851707" }, - "multiqc_stub": { + "sarscov2 single-end [fastqc]": { "content": [ - [ - "multiqc_report.html", - "multiqc_data", - "multiqc_plots", - "versions.yml:md5,c1fe644a37468f6dae548d98bc72c2c1" - ] + "multiqc_report.html", + "multiqc_data", + { + "versions": [ + [ + "MULTIQC", + "multiqc", + "1.33" + ] + ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.2" + "nf-test": "0.9.4", + "nextflow": "25.10.4" }, - "timestamp": "2025-06-03T09:18:16.875131107" + "timestamp": "2026-02-26T15:10:36.019680076" }, - "multiqc_versions_config": { + "sarscov2 single-end [fastqc] - stub": { "content": [ - [ - "versions.yml:md5,c1fe644a37468f6dae548d98bc72c2c1" - ] + { + "data": [ + [ + { + "id": "FASTQC" + }, + [ + ".stub:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "plots": [ + [ + { + "id": "FASTQC" + }, + [ + ".stub:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "report": [ + [ + { + "id": "FASTQC" + }, + "multiqc_report.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + [ + "MULTIQC", + "multiqc", + "1.33" + ] + ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.2" + "nf-test": "0.9.4", + "nextflow": "25.10.4" }, - "timestamp": "2025-06-03T09:18:03.624717769" + "timestamp": "2026-02-26T15:14:39.789193051" + }, + "sarscov2 single-end [fastqc] [config]": { + "content": [ + "multiqc_report.html", + "multiqc_data", + "multiqc_plots", + { + "versions": [ + [ + "MULTIQC", + "multiqc", + "1.33" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + }, + "timestamp": "2026-02-26T15:21:29.116129274" + }, + "sarscov2 single-end [fastqc] - custom prefix": { + "content": [ + "custom_prefix.html", + "custom_prefix_data", + { + "versions": [ + [ + "MULTIQC", + "multiqc", + "1.33" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + }, + "timestamp": "2026-02-26T15:10:43.419877592" } } \ No newline at end of file diff --git a/modules/nf-core/multiqcsav/environment.yml b/modules/nf-core/multiqcsav/environment.yml new file mode 100644 index 00000000..092076ff --- /dev/null +++ b/modules/nf-core/multiqcsav/environment.yml @@ -0,0 +1,13 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + # renovate: datasource=conda depName=bioconda/multiqc + - bioconda::multiqc=1.33 + # renovate: datasource=conda depName=bioconda/multiqc_sav + - bioconda::multiqc_sav=0.2.0 + - pip=25.3 + - pip: + - interop==1.9.0 diff --git a/modules/nf-core/multiqcsav/main.nf b/modules/nf-core/multiqcsav/main.nf new file mode 100644 index 00000000..833ad6df --- /dev/null +++ b/modules/nf-core/multiqcsav/main.nf @@ -0,0 +1,53 @@ +process MULTIQCSAV { + tag "${meta.id}" + label 'process_single' + + 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/36/3634362a0bf5a0530a6459bdba392622262d6de6cc0062e9a293bacc3098b323/data' + : 'community.wave.seqera.io/library/multiqc_multiqc_sav_pip_interop:b142653b3920c82b'}" + + input: + tuple val(meta), path(xml), path(interop_bin, stageAs: "InterOp/*"), path(extra_multiqc_files, stageAs: "?/*"), path(multiqc_config, stageAs: "?/*"), path(multiqc_logo), path(replace_names), path(sample_names) + + output: + tuple val(meta), path("*.html"), emit: report + tuple val(meta), path("*_data"), emit: data + tuple val(meta), path("*_plots"), emit: plots, optional: true + // MultiQC should not push its versions to the `versions` topic. Its input depends on the versions topic to be resolved thus outputting to the topic will let the pipeline hang forever + tuple val("${task.process}"), val('multiqc'), eval('multiqc --version | sed "s/.* //g"'), emit: versions + tuple val("${task.process}"), val('multiqcsav'), eval('python -c "import multiqc_sav; print(multiqc_sav.__version__)"'), emit: versions_multiqcsav + tuple val("${task.process}"), val('interop'), eval('python -c "import interop; print(interop.__version__)"'), emit: versions_interop + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ? "--filename ${task.ext.prefix}.html" : '' + def config = multiqc_config ? multiqc_config instanceof List ? "--config ${multiqc_config.join(' --config ')}" : "--config ${multiqc_config}" : "" + def logo = multiqc_logo ? "--cl-config 'custom_logo: \"${multiqc_logo}\"'" : '' + def replace = replace_names ? "--replace-names ${replace_names}" : '' + def samples = sample_names ? "--sample-names ${sample_names}" : '' + """ + export TMPDIR="\$PWD/tmp" + multiqc \\ + --force \\ + ${args} \\ + ${config} \\ + ${prefix} \\ + ${logo} \\ + ${replace} \\ + ${samples} \\ + . + """ + + stub: + """ + mkdir multiqc_data + touch multiqc_data/.stub + mkdir multiqc_plots + touch multiqc_plots/.stub + touch multiqc_report.html + """ +} diff --git a/modules/nf-core/multiqcsav/meta.yml b/modules/nf-core/multiqcsav/meta.yml new file mode 100644 index 00000000..86545841 --- /dev/null +++ b/modules/nf-core/multiqcsav/meta.yml @@ -0,0 +1,139 @@ +name: multiqcsav +description: Aggregate results from bioinformatics analyses across many samples + into a single report, with support for multiqc_sav plugin +keywords: + - QC + - bioinformatics tools + - Beautiful stand-alone HTML report + - Illumina + - Sequencing Analysis Viewer + - SAV +tools: + - multiqc: + description: | + MultiQC searches a given directory for analysis logs and compiles a HTML report. + It's a general use tool, perfect for summarising the output from numerous bioinformatics tools. + homepage: https://multiqc.info/ + documentation: https://multiqc.info/docs/ + licence: + - "GPL-3.0-or-later" + identifier: biotools:multiqc +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', single_end:false ] + - xml: + type: file + description: xml files from an Illumina sequencing run + pattern: "*.xml" + ontologies: + - edam: http://edamontology.org/format_2332 + - interop_bin: + type: file + description: Illumina InterOp binary files + pattern: "InterOp/*.bin" + ontologies: + - edam: http://edamontology.org/format_2333 + - extra_multiqc_files: + type: file + description: | + List of reports / files recognised by MultiQC, for example the html and zip output of FastQC + ontologies: [] + - multiqc_config: + type: file + description: Optional config yml for MultiQC + pattern: "*.{yml,yaml}" + ontologies: + - edam: http://edamontology.org/format_3750 + - multiqc_logo: + type: file + description: Optional logo file for MultiQC + pattern: "*.{png}" + ontologies: [] + - 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}" + ontologies: + - edam: http://edamontology.org/format_3475 + - sample_names: + type: file + description: | + Optional TSV file with headers, passed to the MultiQC --sample_names + argument. + pattern: "*.{tsv}" + ontologies: + - edam: http://edamontology.org/format_3475 +output: + report: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', single_end:false ] + - "*.html": + type: file + description: MultiQC report file + pattern: ".html" + ontologies: [] + data: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', single_end:false ] + - "*_data": + type: directory + description: MultiQC data dir + pattern: "multiqc_data" + plots: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'sample1', single_end:false ] + - "*_plots": + type: file + description: Plots created by MultiQC + pattern: "*_data" + ontologies: [] + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - multiqc: + type: string + description: The tool name + - multiqc --version | sed "s/.* //g": + type: eval + description: The expression to obtain the version of the tool + versions_interop: + - - ${task.process}: + type: string + description: The process the versions were collected from + - interop: + type: string + description: The tool name + - python -c "import interop; print(interop.__version__)": + type: eval + description: The expression to obtain the version of the tool + versions_multiqcsav: + - - ${task.process}: + type: string + description: The process the versions were collected from + - multiqcsav: + type: string + description: The name of the tool + - python -c "import multiqc_sav; print(multiqc_sav.__version__)": + type: eval + description: The expression to obtain the version of the tool +authors: + - "@matthdsm" + - "@delfiterradas" +maintainers: + - "@matthdsm" diff --git a/modules/nf-core/multiqcsav/tests/main.nf.test b/modules/nf-core/multiqcsav/tests/main.nf.test new file mode 100644 index 00000000..3f48121e --- /dev/null +++ b/modules/nf-core/multiqcsav/tests/main.nf.test @@ -0,0 +1,136 @@ +nextflow_process { + + name "Test Process MULTIQCSAV" + script "../main.nf" + process "MULTIQCSAV" + + tag "modules" + tag "modules_nfcore" + tag "untar" + tag "multiqcsav" + + test("NovaSeq6000") { + setup { + run("UNTAR") { + script "../../untar/main.nf" + process { + """ + input[0] = [ + [ id: 'NovaSeq6000' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bcl/200624_A00834_0183_BHMTFYDRXX.tar.gz', checkIfExists: true) + ] + """ + } + } + } + + when { + process { + """ + ch_sav_in = UNTAR.out.untar.map{ meta, untar -> + + def xml = [] + untar.eachFileRecurse { file -> + if (file.fileName.toString() == 'RunInfo.xml') { + xml << file + } + } + + def interop = [] + untar.eachFileRecurse { file -> + if (file.parent.name == 'InterOp' && file.fileName.toString().endsWith(".bin")) { + interop << file + } + } + + return [ + meta, + xml, + interop, + [], + [], + [], + [], + [] + ] + } + + input[0] = ch_sav_in + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + file(process.out.report[0][1]).name, + file(process.out.data[0][1]).name, + process.out.findAll { key, val -> key.startsWith("versions") + }).match() } + ) + } + } + + test("NovaSeq6000 - stub") { + + options "-stub" + + setup { + run("UNTAR") { + script "../../untar/main.nf" + process { + """ + input[0] = [ + [ id: 'NovaSeq6000' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bcl/200624_A00834_0183_BHMTFYDRXX.tar.gz', checkIfExists: true) + ] + """ + } + } + } + + when { + process { + """ + ch_sav_in = UNTAR.out.untar.map{ meta, untar -> + + def xml = [] + untar.eachFileRecurse { file -> + if (file.fileName.toString() == 'RunInfo.xml') { + xml << file + } + } + + def interop = [] + untar.eachFileRecurse { file -> + if (file.parent.name == 'InterOp' && file.fileName.toString().endsWith(".bin")) { + interop << file + } + } + + return [ + meta, + xml, + interop, + [], + [], + [], + [], + [] + ] + } + + input[0] = ch_sav_in + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } +} diff --git a/modules/nf-core/multiqcsav/tests/main.nf.test.snap b/modules/nf-core/multiqcsav/tests/main.nf.test.snap new file mode 100644 index 00000000..3f3783a1 --- /dev/null +++ b/modules/nf-core/multiqcsav/tests/main.nf.test.snap @@ -0,0 +1,96 @@ +{ + "NovaSeq6000": { + "content": [ + "multiqc_report.html", + "multiqc_data", + { + "versions": [ + [ + "MULTIQCSAV", + "multiqc", + "1.33" + ] + ], + "versions_interop": [ + [ + "MULTIQCSAV", + "interop", + "1.9.0" + ] + ], + "versions_multiqcsav": [ + [ + "MULTIQCSAV", + "multiqcsav", + "0.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + }, + "timestamp": "2026-02-26T15:17:26.065765698" + }, + "NovaSeq6000 - stub": { + "content": [ + { + "data": [ + [ + { + "id": "NovaSeq6000" + }, + [ + ".stub:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "plots": [ + [ + { + "id": "NovaSeq6000" + }, + [ + ".stub:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "report": [ + [ + { + "id": "NovaSeq6000" + }, + "multiqc_report.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + [ + "MULTIQCSAV", + "multiqc", + "1.33" + ] + ], + "versions_interop": [ + [ + "MULTIQCSAV", + "interop", + "1.9.0" + ] + ], + "versions_multiqcsav": [ + [ + "MULTIQCSAV", + "multiqcsav", + "0.2.0" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + }, + "timestamp": "2026-02-26T15:18:42.648653899" + } +} \ No newline at end of file diff --git a/modules/nf-core/picard/collecthsmetrics/environment.yml b/modules/nf-core/picard/collecthsmetrics/environment.yml index 1d715d56..b4ac4fe0 100644 --- a/modules/nf-core/picard/collecthsmetrics/environment.yml +++ b/modules/nf-core/picard/collecthsmetrics/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::picard=3.3.0 + # renovate: datasource=conda depName=bioconda/picard + - bioconda::picard=3.4.0 diff --git a/modules/nf-core/picard/collecthsmetrics/main.nf b/modules/nf-core/picard/collecthsmetrics/main.nf index 6eb9aa0c..2b9b7588 100644 --- a/modules/nf-core/picard/collecthsmetrics/main.nf +++ b/modules/nf-core/picard/collecthsmetrics/main.nf @@ -1,18 +1,18 @@ process PICARD_COLLECTHSMETRICS { - tag "$meta.id" + tag "${meta.id}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : - 'biocontainers/picard:3.3.0--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/08/0861295baa7c01fc593a9da94e82b44a729dcaf8da92be8e565da109aa549b25/data' + : 'community.wave.seqera.io/library/picard:3.4.0--e9963040df0a9bf6'}" input: tuple val(meta), path(bam), path(bai), path(bait_intervals, stageAs: "bait/*"), path(target_intervals, stageAs: "target/*") ,path(fasta) ,path(fai) ,path(dict) output: - tuple val(meta), path("*_metrics") , emit: metrics - path "versions.yml" , emit: versions + tuple val(meta), path("*_metrics"), emit: metrics + tuple val("${task.process}"), val('picard'), eval("picard CollectHsMetrics --version 2>&1 | sed -n 's/.*Version://p'"), topic: versions, emit: versions_picard when: task.ext.when == null || task.ext.when @@ -24,56 +24,45 @@ process PICARD_COLLECTHSMETRICS { def avail_mem = 3072 if (!task.memory) { - log.info '[Picard CollectHsMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[Picard CollectHsMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } def bait_interval_list = bait_intervals def bait_intervallist_cmd = "" - if (bait_intervals =~ /.(bed|bed.gz)$/){ + if (bait_intervals =~ /.(bed|bed.gz)$/) { bait_interval_list = bait_intervals.toString().replaceAll(/.(bed|bed.gz)$/, ".interval_list") - bait_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${bait_intervals} --OUTPUT ${bait_interval_list} --SEQUENCE_DICTIONARY ${dict} --TMP_DIR ." + bait_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${bait_intervals} --OUTPUT ${bait_interval_list} --SEQUENCE_DICTIONARY ${dict} --TMP_DIR ." } def target_interval_list = target_intervals def target_intervallist_cmd = "" - if (target_intervals =~ /.(bed|bed.gz)$/){ + if (target_intervals =~ /.(bed|bed.gz)$/) { target_interval_list = target_intervals.toString().replaceAll(/.(bed|bed.gz)$/, ".interval_list") - target_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${target_intervals} --OUTPUT ${target_interval_list} --SEQUENCE_DICTIONARY ${dict} --TMP_DIR ." + target_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${target_intervals} --OUTPUT ${target_interval_list} --SEQUENCE_DICTIONARY ${dict} --TMP_DIR ." } - - """ - - $bait_intervallist_cmd - $target_intervallist_cmd + export TMP=\$PWD + ${bait_intervallist_cmd} + ${target_intervallist_cmd} picard \\ -Xmx${avail_mem}M \\ CollectHsMetrics \\ - $args \\ - $reference \\ - --BAIT_INTERVALS $bait_interval_list \\ - --TARGET_INTERVALS $target_interval_list \\ - --INPUT $bam \\ - --OUTPUT ${prefix}.CollectHsMetrics.coverage_metrics - - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(echo \$(picard CollectHsMetrics --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:) - END_VERSIONS + ${args} \\ + ${reference} \\ + --BAIT_INTERVALS ${bait_interval_list} \\ + --TARGET_INTERVALS ${target_interval_list} \\ + --INPUT ${bam} \\ + --OUTPUT ${prefix}.CollectHsMetrics.coverage_metrics \\ + --TMP_DIR . """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.CollectHsMetrics.coverage_metrics - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(echo \$(picard CollectHsMetrics --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:) - END_VERSIONS """ } diff --git a/modules/nf-core/picard/collecthsmetrics/meta.yml b/modules/nf-core/picard/collecthsmetrics/meta.yml index ea6deda3..89bc502c 100644 --- a/modules/nf-core/picard/collecthsmetrics/meta.yml +++ b/modules/nf-core/picard/collecthsmetrics/meta.yml @@ -28,51 +28,68 @@ input: type: file description: An aligned BAM/CRAM/SAM file pattern: "*.{bam,cram,sam}" + ontologies: [] - bai: type: file description: Optional aligned BAM/CRAM/SAM file index pattern: "*.{bai,crai,sai}" + ontologies: [] - bait_intervals: type: file description: An interval file that contains the locations of the baits used. pattern: "*.{interval_list,bed,bed.gz}" + ontologies: [] - target_intervals: type: file description: An interval file that contains the locations of the targets. pattern: "*.{interval_list,bed,bed.gz}" + ontologies: [] - - meta2: type: map description: | Groovy Map containing reference information e.g. [ id:'genome' ] - - fasta: + - ref: type: file description: | A reference file to calculate dropout metrics measuring reduced representation of reads. Optional input. - pattern: "*.{fa,fasta,fna}" + pattern: "*.{fa,fa.gz,fasta,fasta.gz,fna,fna.gz}" + ontologies: [] - - meta3: type: map description: | Groovy Map containing reference information e.g. [ id:'genome' ] - - fai: + - ref_fai: type: file - description: Index of FASTA file. Only needed when fasta is supplied. + description: Index of reference file. Only needed when reference is supplied. pattern: "*.fai" + ontologies: [] - - meta4: type: map description: | Groovy Map containing reference information e.g. [ id:'genome' ] - - dict: + - ref_dict: type: file description: Sequence dictionary of FASTA file. Only needed when bed interval lists are supplied. pattern: "*.dict" + ontologies: [] + - - meta5: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - ref_gzi: + type: file + description: Index of reference file. Only needed when gzipped reference is supplied. + pattern: "*.gzi" + ontologies: [] output: - - metrics: - - meta: + metrics: + - - meta: type: map description: | Groovy Map containing sample information @@ -81,11 +98,29 @@ output: type: file description: Alignment metrics files generated by picard pattern: "*_{metrics}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_picard: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard CollectHsMetrics --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard CollectHsMetrics --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool authors: - "@projectoriented" - "@matthdsm" diff --git a/modules/nf-core/picard/collecthsmetrics/picard-collecthsmetrics.diff b/modules/nf-core/picard/collecthsmetrics/picard-collecthsmetrics.diff index 951f60dc..f9b0281a 100644 --- a/modules/nf-core/picard/collecthsmetrics/picard-collecthsmetrics.diff +++ b/modules/nf-core/picard/collecthsmetrics/picard-collecthsmetrics.diff @@ -1,23 +1,62 @@ -Changes in module 'nf-core/picard/collecthsmetrics' +Changes in component 'nf-core/picard/collecthsmetrics' 'modules/nf-core/picard/collecthsmetrics/environment.yml' is unchanged 'modules/nf-core/picard/collecthsmetrics/meta.yml' is unchanged Changes in 'picard/collecthsmetrics/main.nf': --- modules/nf-core/picard/collecthsmetrics/main.nf +++ modules/nf-core/picard/collecthsmetrics/main.nf -@@ -8,10 +8,7 @@ - 'biocontainers/picard:3.3.0--hdfd78af_0' }" +@@ -8,11 +8,7 @@ + : 'community.wave.seqera.io/library/picard:3.4.0--e9963040df0a9bf6'}" input: - tuple val(meta), path(bam), path(bai), path(bait_intervals, stageAs: "baits/*"), path(target_intervals, stageAs: 'targets/*') -- tuple val(meta2), path(fasta) -- tuple val(meta3), path(fai) -- tuple val(meta4), path(dict) +- tuple val(meta2), path(ref) +- tuple val(meta3), path(ref_fai) +- tuple val(meta4), path(ref_dict) +- tuple val(meta5), path(ref_gzi) + tuple val(meta), path(bam), path(bai), path(bait_intervals, stageAs: "bait/*"), path(target_intervals, stageAs: "target/*") ,path(fasta) ,path(fai) ,path(dict) output: - tuple val(meta), path("*_metrics") , emit: metrics + tuple val(meta), path("*_metrics"), emit: metrics +@@ -24,7 +20,7 @@ + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" +- def reference = ref ? "--REFERENCE_SEQUENCE ${ref}" : "" ++ def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" + + def avail_mem = 3072 + if (!task.memory) { +@@ -38,16 +34,17 @@ + def bait_intervallist_cmd = "" + if (bait_intervals =~ /.(bed|bed.gz)$/) { + bait_interval_list = bait_intervals.toString().replaceAll(/.(bed|bed.gz)$/, ".interval_list") +- bait_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${bait_intervals} --OUTPUT ${bait_interval_list} --SEQUENCE_DICTIONARY ${ref_dict} --TMP_DIR ." ++ bait_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${bait_intervals} --OUTPUT ${bait_interval_list} --SEQUENCE_DICTIONARY ${dict} --TMP_DIR ." + } + + def target_interval_list = target_intervals + def target_intervallist_cmd = "" + if (target_intervals =~ /.(bed|bed.gz)$/) { + target_interval_list = target_intervals.toString().replaceAll(/.(bed|bed.gz)$/, ".interval_list") +- target_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${target_intervals} --OUTPUT ${target_interval_list} --SEQUENCE_DICTIONARY ${ref_dict} --TMP_DIR ." ++ target_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${target_intervals} --OUTPUT ${target_interval_list} --SEQUENCE_DICTIONARY ${dict} --TMP_DIR ." + } + """ ++ export TMP=\$PWD + ${bait_intervallist_cmd} + ${target_intervallist_cmd} + +@@ -59,7 +56,8 @@ + --BAIT_INTERVALS ${bait_interval_list} \\ + --TARGET_INTERVALS ${target_interval_list} \\ + --INPUT ${bam} \\ +- --OUTPUT ${prefix}.CollectHsMetrics.coverage_metrics ++ --OUTPUT ${prefix}.CollectHsMetrics.coverage_metrics \\ ++ --TMP_DIR . + """ + + stub: 'modules/nf-core/picard/collecthsmetrics/tests/main.nf.test.snap' is unchanged -'modules/nf-core/picard/collecthsmetrics/tests/tags.yml' is unchanged 'modules/nf-core/picard/collecthsmetrics/tests/main.nf.test' is unchanged ************************************************************ diff --git a/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test b/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test index 3bbbd8cf..d7366111 100644 --- a/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test +++ b/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test @@ -24,6 +24,7 @@ nextflow_process { input[1] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] input[2] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)] input[3] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)] + input[4] = [[:],[]] """ } } @@ -38,18 +39,50 @@ nextflow_process { file(process.out.metrics[0][1]).name, size, lines, - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } + } + + test("sarscov2 - bam - gzippedfa") { + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/picard/baits.interval_list', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/picard/targets.interval_list', checkIfExists: true) + ] + input[1] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.gz', checkIfExists: true)] + input[2] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.gz.fai', checkIfExists: true)] + input[3] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)] + input[4] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.gz.gzi', checkIfExists: true)] + """ + } + } + + then { + def size = path(process.out.metrics[0][1]).size() + def lines = path(process.out.metrics[0][1]).readLines()[0..100] + lines.remove(3) // remove timestamp + assertAll( + { assert process.success }, + { assert snapshot( + file(process.out.metrics[0][1]).name, + size, + lines, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} + ) + } } test("sarscov2 - bam - stub") { - options "-stub" - when { process { """ @@ -63,6 +96,7 @@ nextflow_process { input[1] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] input[2] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)] input[3] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)] + input[4] = [[:],[]] """ } } @@ -70,10 +104,9 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out.versions).match("versions") } + { assert snapshot(sanitizeOutput(process.out)).match() } ) } - } test("sarscov2 - bam - nofasta") { @@ -91,6 +124,7 @@ nextflow_process { input[1] = [[:],[]] input[2] = [[:],[]] input[3] = [[:],[]] + input[4] = [[:],[]] """ } } @@ -105,12 +139,10 @@ nextflow_process { file(process.out.metrics[0][1]).name, size, lines, - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } - } test("sarscov2 - bam - bed") { @@ -129,6 +161,7 @@ nextflow_process { input[1] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] input[2] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)] input[3] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)] + input[4] = [[:],[]] """ } } @@ -143,12 +176,10 @@ nextflow_process { file(process.out.metrics[0][1]).name, size, lines, - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } - } test("sarscov2 - bam - samebed") { @@ -167,6 +198,7 @@ nextflow_process { input[1] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)] input[2] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)] input[3] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)] + input[4] = [[:],[]] """ } } @@ -181,11 +213,9 @@ nextflow_process { file(process.out.metrics[0][1]).name, size, lines, - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } - } -} \ No newline at end of file +} diff --git a/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test.snap b/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test.snap index 4d21710a..43385314 100644 --- a/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test.snap +++ b/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test.snap @@ -105,27 +105,170 @@ "88\t0\t0", "89\t0\t0" ], - [ - "versions.yml:md5,bdfc7b655683e7b66f68e894c999805e" - ] + { + "versions_picard": [ + [ + "PICARD_COLLECTHSMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-01-05T17:03:29.566021877", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:51:55.291163084" + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } }, - "versions": { + "sarscov2 - bam - stub": { "content": [ + { + "metrics": [ + [ + { + "id": "test", + "single_end": false + }, + "test.CollectHsMetrics.coverage_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_picard": [ + [ + "PICARD_COLLECTHSMETRICS", + "picard", + "3.4.0" + ] + ] + } + ], + "timestamp": "2026-02-19T17:36:03.822502867", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "sarscov2 - bam - gzippedfa": { + "content": [ + "test.CollectHsMetrics.coverage_metrics", + 3601, [ - "versions.yml:md5,bdfc7b655683e7b66f68e894c999805e" - ] + "## htsjdk.samtools.metrics.StringHeader", + "# CollectHsMetrics --BAIT_INTERVALS baits/baits.interval_list --TARGET_INTERVALS targets/targets.interval_list --INPUT test.paired_end.sorted.bam --OUTPUT test.CollectHsMetrics.coverage_metrics --REFERENCE_SEQUENCE genome.fasta.gz --METRIC_ACCUMULATION_LEVEL ALL_READS --NEAR_DISTANCE 250 --MINIMUM_MAPPING_QUALITY 20 --MINIMUM_BASE_QUALITY 20 --CLIP_OVERLAPPING_READS true --INCLUDE_INDELS false --COVERAGE_CAP 200 --SAMPLE_SIZE 10000 --ALLELE_FRACTION 0.001 --ALLELE_FRACTION 0.005 --ALLELE_FRACTION 0.01 --ALLELE_FRACTION 0.02 --ALLELE_FRACTION 0.05 --ALLELE_FRACTION 0.1 --ALLELE_FRACTION 0.2 --ALLELE_FRACTION 0.3 --ALLELE_FRACTION 0.5 --VERBOSITY INFO --QUIET false --VALIDATION_STRINGENCY STRICT --COMPRESSION_LEVEL 5 --MAX_RECORDS_IN_RAM 500000 --CREATE_INDEX false --CREATE_MD5_FILE false --help false --version false --showHidden false --USE_JDK_DEFLATER false --USE_JDK_INFLATER false", + "## htsjdk.samtools.metrics.StringHeader", + "", + "## METRICS CLASS\tpicard.analysis.directed.HsMetrics", + "BAIT_SET\tBAIT_TERRITORY\tBAIT_DESIGN_EFFICIENCY\tON_BAIT_BASES\tNEAR_BAIT_BASES\tOFF_BAIT_BASES\tPCT_SELECTED_BASES\tPCT_OFF_BAIT\tON_BAIT_VS_SELECTED\tMEAN_BAIT_COVERAGE\tPCT_USABLE_BASES_ON_BAIT\tPCT_USABLE_BASES_ON_TARGET\tFOLD_ENRICHMENT\tHS_LIBRARY_SIZE\tHS_PENALTY_10X\tHS_PENALTY_20X\tHS_PENALTY_30X\tHS_PENALTY_40X\tHS_PENALTY_50X\tHS_PENALTY_100X\tTARGET_TERRITORY\tGENOME_SIZE\tTOTAL_READS\tPF_READS\tPF_BASES\tPF_UNIQUE_READS\tPF_UQ_READS_ALIGNED\tPF_BASES_ALIGNED\tPF_UQ_BASES_ALIGNED\tON_TARGET_BASES\tPCT_PF_READS\tPCT_PF_UQ_READS\tPCT_PF_UQ_READS_ALIGNED\tMEAN_TARGET_COVERAGE\tMEDIAN_TARGET_COVERAGE\tMAX_TARGET_COVERAGE\tMIN_TARGET_COVERAGE\tZERO_CVG_TARGETS_PCT\tPCT_EXC_DUPE\tPCT_EXC_ADAPTER\tPCT_EXC_MAPQ\tPCT_EXC_BASEQ\tPCT_EXC_OVERLAP\tPCT_EXC_OFF_TARGET\tFOLD_80_BASE_PENALTY\tPCT_TARGET_BASES_1X\tPCT_TARGET_BASES_2X\tPCT_TARGET_BASES_10X\tPCT_TARGET_BASES_20X\tPCT_TARGET_BASES_30X\tPCT_TARGET_BASES_40X\tPCT_TARGET_BASES_50X\tPCT_TARGET_BASES_100X\tPCT_TARGET_BASES_250X\tPCT_TARGET_BASES_500X\tPCT_TARGET_BASES_1000X\tPCT_TARGET_BASES_2500X\tPCT_TARGET_BASES_5000X\tPCT_TARGET_BASES_10000X\tPCT_TARGET_BASES_25000X\tPCT_TARGET_BASES_50000X\tPCT_TARGET_BASES_100000X\tAT_DROPOUT\tGC_DROPOUT\tHET_SNP_SENSITIVITY\tHET_SNP_Q\tSAMPLE\tLIBRARY\tREAD_GROUP", + "baits\t158\t0.594937\t725\t3985\t22691\t0.171892\t0.828108\t0.153928\t4.588608\t0.026225\t0.000181\t4.995204\t\t0\t0\t0\t0\t0\t0\t94\t29829\t200\t200\t27645\t200\t197\t27401\t27401\t5\t1\t1\t0.985\t0.053191\t0\t1\t0\t0.75\t0\t0\t0.005438\t0.054487\t0.259516\t0.680377\t?\t0.053191\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t76.595745\t23.404255\t0.015734\t0\t\t\t", + "", + "## HISTOGRAM\tjava.lang.Integer", + "coverage_or_base_quality\thigh_quality_coverage_count\tunfiltered_baseq_count", + "0\t89\t0", + "1\t5\t0", + "2\t0\t0", + "3\t0\t0", + "4\t0\t0", + "5\t0\t0", + "6\t0\t0", + "7\t0\t0", + "8\t0\t0", + "9\t0\t0", + "10\t0\t0", + "11\t0\t0", + "12\t0\t0", + "13\t0\t0", + "14\t0\t5", + "15\t0\t0", + "16\t0\t0", + "17\t0\t0", + "18\t0\t0", + "19\t0\t0", + "20\t0\t0", + "21\t0\t1", + "22\t0\t0", + "23\t0\t0", + "24\t0\t0", + "25\t0\t0", + "26\t0\t0", + "27\t0\t0", + "28\t0\t0", + "29\t0\t0", + "30\t0\t0", + "31\t0\t0", + "32\t0\t1", + "33\t0\t0", + "34\t0\t0", + "35\t0\t0", + "36\t0\t3", + "37\t0\t0", + "38\t0\t0", + "39\t0\t0", + "40\t0\t0", + "41\t0\t0", + "42\t0\t0", + "43\t0\t0", + "44\t0\t0", + "45\t0\t0", + "46\t0\t0", + "47\t0\t0", + "48\t0\t0", + "49\t0\t0", + "50\t0\t0", + "51\t0\t0", + "52\t0\t0", + "53\t0\t0", + "54\t0\t0", + "55\t0\t0", + "56\t0\t0", + "57\t0\t0", + "58\t0\t0", + "59\t0\t0", + "60\t0\t0", + "61\t0\t0", + "62\t0\t0", + "63\t0\t0", + "64\t0\t0", + "65\t0\t0", + "66\t0\t0", + "67\t0\t0", + "68\t0\t0", + "69\t0\t0", + "70\t0\t0", + "71\t0\t0", + "72\t0\t0", + "73\t0\t0", + "74\t0\t0", + "75\t0\t0", + "76\t0\t0", + "77\t0\t0", + "78\t0\t0", + "79\t0\t0", + "80\t0\t0", + "81\t0\t0", + "82\t0\t0", + "83\t0\t0", + "84\t0\t0", + "85\t0\t0", + "86\t0\t0", + "87\t0\t0", + "88\t0\t0", + "89\t0\t0" + ], + { + "versions_picard": [ + [ + "PICARD_COLLECTHSMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-01-05T17:03:04.382110367", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:51:30.748857589" + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } }, "sarscov2 - bam - samebed": { "content": [ @@ -233,15 +376,21 @@ "88\t0\t0", "89\t0\t0" ], - [ - "versions.yml:md5,bdfc7b655683e7b66f68e894c999805e" - ] + { + "versions_picard": [ + [ + "PICARD_COLLECTHSMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-01-05T17:13:22.872920293", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:52:43.803456585" + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } }, "sarscov2 - bam": { "content": [ @@ -349,15 +498,21 @@ "88\t0\t0", "89\t0\t0" ], - [ - "versions.yml:md5,bdfc7b655683e7b66f68e894c999805e" - ] + { + "versions_picard": [ + [ + "PICARD_COLLECTHSMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-01-05T17:02:47.615784738", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:51:01.881343611" + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } }, "sarscov2 - bam - bed": { "content": [ @@ -465,14 +620,20 @@ "88\t0\t0", "89\t0\t0" ], - [ - "versions.yml:md5,bdfc7b655683e7b66f68e894c999805e" - ] + { + "versions_picard": [ + [ + "PICARD_COLLECTHSMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-01-05T17:13:02.812282052", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:52:22.830749735" + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } } } \ No newline at end of file diff --git a/modules/nf-core/picard/collecthsmetrics/tests/tags.yml b/modules/nf-core/picard/collecthsmetrics/tests/tags.yml deleted file mode 100644 index b353f95e..00000000 --- a/modules/nf-core/picard/collecthsmetrics/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -picard/collecthsmetrics: - - "modules/nf-core/picard/collecthsmetrics/**" diff --git a/modules/nf-core/picard/collectmultiplemetrics/environment.yml b/modules/nf-core/picard/collectmultiplemetrics/environment.yml index 1d715d56..b4ac4fe0 100644 --- a/modules/nf-core/picard/collectmultiplemetrics/environment.yml +++ b/modules/nf-core/picard/collectmultiplemetrics/environment.yml @@ -1,5 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::picard=3.3.0 + # renovate: datasource=conda depName=bioconda/picard + - bioconda::picard=3.4.0 diff --git a/modules/nf-core/picard/collectmultiplemetrics/main.nf b/modules/nf-core/picard/collectmultiplemetrics/main.nf index de390df1..59842bdd 100644 --- a/modules/nf-core/picard/collectmultiplemetrics/main.nf +++ b/modules/nf-core/picard/collectmultiplemetrics/main.nf @@ -1,19 +1,19 @@ process PICARD_COLLECTMULTIPLEMETRICS { - tag "$meta.id" + tag "${meta.id}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : - 'biocontainers/picard:3.3.0--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/08/0861295baa7c01fc593a9da94e82b44a729dcaf8da92be8e565da109aa549b25/data' + : 'community.wave.seqera.io/library/picard:3.4.0--e9963040df0a9bf6'}" input: - tuple val(meta) , path(bam), path(bai) ,path(fasta) ,path(fai) + tuple val(meta) , path(bam), path(bai), path(intervals), path(fasta) ,path(fai), path(dict) output: tuple val(meta), path("*_metrics"), emit: metrics - tuple val(meta), path("*.pdf") , emit: pdf, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*.pdf"), emit: pdf, optional: true + tuple val("${task.process}"), val('picard'), eval("picard CollectMultipleMetrics --version 2>&1 | sed -n 's/.*Version://p'"), topic: versions, emit: versions_picard when: task.ext.when == null || task.ext.when @@ -21,26 +21,26 @@ process PICARD_COLLECTMULTIPLEMETRICS { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" + def intervals_cmd = intervals ? "--INTERVALS ${intervals.join(',')}" : "" + def reference_cmd = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" def avail_mem = 3072 if (!task.memory) { - log.info '[Picard CollectMultipleMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[Picard CollectMultipleMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ + export TMP=\$PWD picard \\ -Xmx${avail_mem}M \\ CollectMultipleMetrics \\ - $args \\ - --INPUT $bam \\ + ${args} \\ + --INPUT ${bam} \\ --OUTPUT ${prefix}.CollectMultipleMetrics \\ - $reference - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(picard CollectMultipleMetrics --version 2>&1 | grep -o 'Version.*' | cut -f2- -d:) - END_VERSIONS + --TMP_DIR . \\ + ${reference_cmd} \\ + ${intervals_cmd} """ stub: @@ -56,10 +56,5 @@ process PICARD_COLLECTMULTIPLEMETRICS { touch ${prefix}.CollectMultipleMetrics.quality_by_cycle.pdf touch ${prefix}.CollectMultipleMetrics.insert_size_histogram.pdf touch ${prefix}.CollectMultipleMetrics.quality_distribution_metrics - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(echo \$(picard CollectMultipleMetrics --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:) - END_VERSIONS """ } diff --git a/modules/nf-core/picard/collectmultiplemetrics/meta.yml b/modules/nf-core/picard/collectmultiplemetrics/meta.yml index 2b7981ac..213d600b 100644 --- a/modules/nf-core/picard/collectmultiplemetrics/meta.yml +++ b/modules/nf-core/picard/collectmultiplemetrics/meta.yml @@ -26,10 +26,12 @@ input: type: file description: SAM/BAM/CRAM file pattern: "*.{sam,bam,cram}" + ontologies: [] - bai: type: file description: Optional SAM/BAM/CRAM file index pattern: "*.{sai,bai,crai}" + ontologies: [] - - meta2: type: map description: | @@ -38,6 +40,7 @@ input: - fasta: type: file description: Genome fasta file + ontologies: [] - - meta3: type: map description: | @@ -47,9 +50,10 @@ input: type: file description: Index of FASTA file. Only needed when fasta is supplied. pattern: "*.fai" + ontologies: [] output: - - metrics: - - meta: + metrics: + - - meta: type: map description: | Groovy Map containing sample information @@ -58,8 +62,9 @@ output: type: file description: Alignment metrics files generated by picard pattern: "*_{metrics}" - - pdf: - - meta: + ontologies: [] + pdf: + - - meta: type: map description: | Groovy Map containing sample information @@ -68,11 +73,30 @@ output: type: file description: PDF plots of metrics pattern: "*.{pdf}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_picard: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard CollectMultipleMetrics --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard CollectMultipleMetrics --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool + authors: - "@drpatelh" maintainers: diff --git a/modules/nf-core/picard/collectmultiplemetrics/picard-collectmultiplemetrics.diff b/modules/nf-core/picard/collectmultiplemetrics/picard-collectmultiplemetrics.diff index 6c796d52..780c0862 100644 --- a/modules/nf-core/picard/collectmultiplemetrics/picard-collectmultiplemetrics.diff +++ b/modules/nf-core/picard/collectmultiplemetrics/picard-collectmultiplemetrics.diff @@ -1,20 +1,48 @@ -Changes in module 'nf-core/picard/collectmultiplemetrics' +Changes in component 'nf-core/picard/collectmultiplemetrics' 'modules/nf-core/picard/collectmultiplemetrics/environment.yml' is unchanged 'modules/nf-core/picard/collectmultiplemetrics/meta.yml' is unchanged Changes in 'picard/collectmultiplemetrics/main.nf': --- modules/nf-core/picard/collectmultiplemetrics/main.nf +++ modules/nf-core/picard/collectmultiplemetrics/main.nf @@ -8,9 +8,7 @@ - 'biocontainers/picard:3.3.0--hdfd78af_0' }" + : 'community.wave.seqera.io/library/picard:3.4.0--e9963040df0a9bf6'}" input: -- tuple val(meta) , path(bam), path(bai) +- tuple val(meta), path(bam), path(bai) - tuple val(meta2), path(fasta) - tuple val(meta3), path(fai) -+ tuple val(meta) , path(bam), path(bai) ,path(fasta) ,path(fai) ++ tuple val(meta) , path(bam), path(bai), path(intervals), path(fasta) ,path(fai), path(dict) output: tuple val(meta), path("*_metrics"), emit: metrics +@@ -23,7 +21,8 @@ + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" +- def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" ++ def intervals_cmd = intervals ? "--INTERVALS ${intervals.join(',')}" : "" ++ def reference_cmd = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" + def avail_mem = 3072 + if (!task.memory) { + log.info('[Picard CollectMultipleMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') +@@ -32,13 +31,16 @@ + avail_mem = (task.memory.mega * 0.8).intValue() + } + """ ++ export TMP=\$PWD + picard \\ + -Xmx${avail_mem}M \\ + CollectMultipleMetrics \\ + ${args} \\ + --INPUT ${bam} \\ + --OUTPUT ${prefix}.CollectMultipleMetrics \\ +- ${reference} ++ --TMP_DIR . \\ ++ ${reference_cmd} \\ ++ ${intervals_cmd} + """ + + stub: 'modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test.snap' is unchanged 'modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test' is unchanged diff --git a/modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test b/modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test index 5b67774f..0037acab 100644 --- a/modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test +++ b/modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test @@ -16,16 +16,15 @@ nextflow_process { process { """ input[0] = [ - [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) - ] - input[1] = [ - [id:'genome'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ] - input[2] = [[id:'genome'],[]] - + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [[id:'genome'],[]] """ } } @@ -36,9 +35,8 @@ nextflow_process { { assert snapshot( process.out.metrics[0][1].collect { file(it).name }.toSorted(), process.out.pdf[0][1].collect { file(it).name }.toSorted(), - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } } @@ -49,13 +47,12 @@ nextflow_process { process { """ input[0] = [ - [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) - ] - input[1] = [[id:'genome'],[]] + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = [[id:'genome'],[]] input[2] = [[id:'genome'],[]] - """ } } @@ -66,9 +63,8 @@ nextflow_process { { assert snapshot( process.out.metrics[0][1].collect { file(it).name }.toSorted(), process.out.pdf[0][1].collect { file(it).name }.toSorted(), - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } } @@ -79,19 +75,18 @@ nextflow_process { process { """ input[0] = [ - [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) - ] - input[1] = [ - [id:'genome'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ] - input[2] = [ - [id:'genome'], - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) - ] - + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] """ } } @@ -102,11 +97,90 @@ nextflow_process { { assert snapshot( process.out.metrics[0][1].collect { file(it).name }.toSorted(), process.out.pdf[0][1].collect { file(it).name }.toSorted(), - process.out.versions - ).match() - } + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} + ) + } + } + + test("test-picard-collectmultiplemetrics - stub") { + options "-stub" + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [[id:'genome'],[]] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } + + test("test-picard-collectmultiplemetrics-nofasta - stub") { + options "-stub" + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = [[id:'genome'],[]] + input[2] = [[id:'genome'],[]] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } ) } } + test("test-picard-collectmultiplemetrics-cram - stub") { + options "-stub" + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } } diff --git a/modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test.snap b/modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test.snap index a76a3237..393ed100 100644 --- a/modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test.snap +++ b/modules/nf-core/picard/collectmultiplemetrics/tests/main.nf.test.snap @@ -15,15 +15,117 @@ "test.CollectMultipleMetrics.quality_distribution.pdf", "test.CollectMultipleMetrics.read_length_histogram.pdf" ], - [ - "versions.yml:md5,791db2719d57a997f8253b3ba97d62d7" - ] + { + "versions_picard": [ + [ + "PICARD_COLLECTMULTIPLEMETRICS", + "picard", + "3.4.0" + ] + ] + } + ], + "timestamp": "2026-02-02T10:22:21.230301646", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } + }, + "test-picard-collectmultiplemetrics - stub": { + "content": [ + { + "metrics": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.CollectMultipleMetrics.alignment_summary_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.base_distribution_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.insert_size_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_distribution_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "pdf": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.CollectMultipleMetrics.base_distribution_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.insert_size_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_distribution.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.read_length_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions_picard": [ + [ + "PICARD_COLLECTMULTIPLEMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-20T10:32:38.701455244", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T11:05:12.591021247" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "test-picard-collectmultiplemetrics-nofasta - stub": { + "content": [ + { + "metrics": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.CollectMultipleMetrics.alignment_summary_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.base_distribution_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.insert_size_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_distribution_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "pdf": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.CollectMultipleMetrics.base_distribution_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.insert_size_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_distribution.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.read_length_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions_picard": [ + [ + "PICARD_COLLECTMULTIPLEMETRICS", + "picard", + "3.4.0" + ] + ] + } + ], + "timestamp": "2026-02-20T10:32:48.923918624", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test-picard-collectmultiplemetrics-cram": { "content": [ @@ -41,15 +143,21 @@ "test.CollectMultipleMetrics.quality_distribution.pdf", "test.CollectMultipleMetrics.read_length_histogram.pdf" ], - [ - "versions.yml:md5,791db2719d57a997f8253b3ba97d62d7" - ] + { + "versions_picard": [ + [ + "PICARD_COLLECTMULTIPLEMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-02T10:23:52.23446844", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T11:06:08.499320579" + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } }, "test-picard-collectmultiplemetrics-nofasta": { "content": [ @@ -67,14 +175,68 @@ "test.CollectMultipleMetrics.quality_distribution.pdf", "test.CollectMultipleMetrics.read_length_histogram.pdf" ], - [ - "versions.yml:md5,791db2719d57a997f8253b3ba97d62d7" - ] + { + "versions_picard": [ + [ + "PICARD_COLLECTMULTIPLEMETRICS", + "picard", + "3.4.0" + ] + ] + } + ], + "timestamp": "2026-02-02T10:23:27.387621193", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + } + }, + "test-picard-collectmultiplemetrics-cram - stub": { + "content": [ + { + "metrics": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.CollectMultipleMetrics.alignment_summary_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.base_distribution_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.insert_size_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_by_cycle_metrics:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_distribution_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "pdf": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.CollectMultipleMetrics.base_distribution_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.insert_size_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_by_cycle.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.quality_distribution.pdf:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.CollectMultipleMetrics.read_length_histogram.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions_picard": [ + [ + "PICARD_COLLECTMULTIPLEMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-20T10:32:57.11686549", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T11:05:42.117033611" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/picard/collectwgsmetrics/environment.yml b/modules/nf-core/picard/collectwgsmetrics/environment.yml index 13265842..186d4a4b 100644 --- a/modules/nf-core/picard/collectwgsmetrics/environment.yml +++ b/modules/nf-core/picard/collectwgsmetrics/environment.yml @@ -1,6 +1,9 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda dependencies: - - bioconda::picard=3.3.0 + # renovate: datasource=conda depName=bioconda/picard + - bioconda::picard=3.4.0 - conda-forge::r-base=4.4.1 diff --git a/modules/nf-core/picard/collectwgsmetrics/main.nf b/modules/nf-core/picard/collectwgsmetrics/main.nf index 468e1c8a..8048b2b6 100644 --- a/modules/nf-core/picard/collectwgsmetrics/main.nf +++ b/modules/nf-core/picard/collectwgsmetrics/main.nf @@ -1,58 +1,51 @@ process PICARD_COLLECTWGSMETRICS { - tag "$meta.id" + tag "${meta.id}" label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : - 'biocontainers/picard:3.3.0--hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/08/0861295baa7c01fc593a9da94e82b44a729dcaf8da92be8e565da109aa549b25/data' + : 'community.wave.seqera.io/library/picard:3.4.0--e9963040df0a9bf6'}" input: - tuple val(meta), path(bam), path(bai) ,path(fasta) ,path(fai) + tuple val(meta), path(bam), path(bai) ,path(fasta) ,path(fai), path(dict) path intervallist output: tuple val(meta), path("*_metrics"), emit: metrics - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('picard'), eval("picard CollectWgsMetrics --version 2>&1 | sed -n 's/.*Version://p'"), topic: versions, emit: versions_picard when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" def avail_mem = 3072 - def interval = intervallist ? "--INTERVALS ${intervallist}" : '' + def interval = intervallist ? "--INTERVALS ${intervallist}" : '' if (!task.memory) { - log.info '[Picard CollectWgsMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[Picard CollectWgsMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ + export TMP=\$PWD picard \\ -Xmx${avail_mem}M \\ CollectWgsMetrics \\ - $args \\ - --INPUT $bam \\ + ${args} \\ + --INPUT ${bam} \\ --OUTPUT ${prefix}.CollectWgsMetrics.coverage_metrics \\ --REFERENCE_SEQUENCE ${fasta} \\ - $interval + --TMP_DIR . \\ + ${interval} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(picard CollectWgsMetrics --version 2>&1 | grep -o 'Version.*' | cut -f2- -d:) - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.CollectWgsMetrics.coverage_metrics - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(picard CollectWgsMetrics --version 2>&1 | grep -o 'Version.*' | cut -f2- -d:) - END_VERSIONS """ } diff --git a/modules/nf-core/picard/collectwgsmetrics/meta.yml b/modules/nf-core/picard/collectwgsmetrics/meta.yml index bb748080..c5afe2e7 100644 --- a/modules/nf-core/picard/collectwgsmetrics/meta.yml +++ b/modules/nf-core/picard/collectwgsmetrics/meta.yml @@ -26,10 +26,12 @@ input: type: file description: Aligned reads file pattern: "*.{bam, cram}" + ontologies: [] - bai: type: file description: (Optional) Aligned reads file index pattern: "*.{bai,crai}" + ontologies: [] - - meta2: type: map description: | @@ -39,6 +41,7 @@ input: type: file description: Genome fasta file pattern: "*.{fa,fasta,fna}" + ontologies: [] - - meta3: type: map description: | @@ -48,13 +51,15 @@ input: type: file description: Genome fasta file index pattern: "*.{fai}" - - - intervallist: - type: file - description: Picard Interval List. Defines which contigs to include. Can be - generated from a BED file with GATK BedToIntervalList. + ontologies: [] + - intervallist: + type: file + description: Picard Interval List. Defines which contigs to include. Can be generated + from a BED file with GATK BedToIntervalList. + ontologies: [] output: - - metrics: - - meta: + metrics: + - - meta: type: map description: | Groovy Map containing sample information @@ -63,11 +68,28 @@ output: type: file description: Alignment metrics files generated by picard pattern: "*_{metrics}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_picard: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard CollectWgsMetrics --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - picard: + type: string + description: The tool name + - "picard CollectWgsMetrics --version 2>&1 | sed -n 's/.*Version://p'": + type: string + description: The command used to generate the version of the tool authors: - "@drpatelh" - "@flowuenne" diff --git a/modules/nf-core/picard/collectwgsmetrics/picard-collectwgsmetrics.diff b/modules/nf-core/picard/collectwgsmetrics/picard-collectwgsmetrics.diff index 98d4a1eb..5de262d0 100644 --- a/modules/nf-core/picard/collectwgsmetrics/picard-collectwgsmetrics.diff +++ b/modules/nf-core/picard/collectwgsmetrics/picard-collectwgsmetrics.diff @@ -1,20 +1,40 @@ -Changes in module 'nf-core/picard/collectwgsmetrics' +Changes in component 'nf-core/picard/collectwgsmetrics' 'modules/nf-core/picard/collectwgsmetrics/environment.yml' is unchanged 'modules/nf-core/picard/collectwgsmetrics/meta.yml' is unchanged Changes in 'picard/collectwgsmetrics/main.nf': --- modules/nf-core/picard/collectwgsmetrics/main.nf +++ modules/nf-core/picard/collectwgsmetrics/main.nf -@@ -8,9 +8,7 @@ - 'biocontainers/picard:3.3.0--hdfd78af_0' }" +@@ -8,10 +8,8 @@ + : 'community.wave.seqera.io/library/picard:3.4.0--e9963040df0a9bf6'}" input: - tuple val(meta), path(bam), path(bai) - tuple val(meta2), path(fasta) - tuple val(meta3), path(fai) -+ tuple val(meta), path(bam), path(bai) ,path(fasta) ,path(fai) - path intervallist +- path intervallist ++ tuple val(meta), path(bam), path(bai) ,path(fasta) ,path(fai), path(dict) ++ path intervallist output: + tuple val(meta), path("*_metrics"), emit: metrics +@@ -32,6 +30,7 @@ + avail_mem = (task.memory.mega * 0.8).intValue() + } + """ ++ export TMP=\$PWD + picard \\ + -Xmx${avail_mem}M \\ + CollectWgsMetrics \\ +@@ -39,7 +38,9 @@ + --INPUT ${bam} \\ + --OUTPUT ${prefix}.CollectWgsMetrics.coverage_metrics \\ + --REFERENCE_SEQUENCE ${fasta} \\ ++ --TMP_DIR . \\ + ${interval} ++ + """ + + stub: 'modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test.snap' is unchanged 'modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test' is unchanged diff --git a/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test b/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test index a3984566..1bda5980 100644 --- a/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test +++ b/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test @@ -16,19 +16,18 @@ nextflow_process { process { """ input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true), - ] - input[1] = [ - [id:'genome'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ] - input[2] = [ - [id:'genome'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) - ] - input[3] = [] - + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true), + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [] """ } } @@ -37,10 +36,9 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - file(process.out.metrics[0][1]).text.contains('coverage high_quality_coverage_count'), - process.out.versions - ).match() - } + file(process.out.metrics[0][1]).text.contains('coverage high_quality_coverage_count'), + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } } @@ -51,19 +49,18 @@ nextflow_process { process { """ input[0] = [ [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), - [] - ] - input[1] = [ - [id:'genome'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ] - input[2] = [ - [id:'genome'], - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) - ] - input[3] = file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/picard/baits.interval_list', checkIfExists: true) - + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + [] + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/picard/baits.interval_list', checkIfExists: true) """ } } @@ -72,12 +69,70 @@ nextflow_process { assertAll( { assert process.success }, { assert snapshot( - file(process.out.metrics[0][1]).text.contains('coverage high_quality_coverage_count'), - process.out.versions - ).match() - } + file(process.out.metrics[0][1]).text.contains('coverage high_quality_coverage_count'), + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} ) } } + test("test-picard-collectwgsmetrics - stub") { + options "-stub" + when { + process { + """ + input[0] = [ [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true), + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } + + test("test-picard-collectwgsmetrics-with-interval - stub") { + options "-stub" + when { + process { + """ + input[0] = [ [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + [] + ] + input[1] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [id:'genome'], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/picard/baits.interval_list', checkIfExists: true) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } } diff --git a/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test.snap b/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test.snap index 1958fcde..79f1145f 100644 --- a/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test.snap +++ b/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test.snap @@ -1,28 +1,94 @@ { + "test-picard-collectwgsmetrics-with-interval - stub": { + "content": [ + { + "metrics": [ + [ + { + "id": "test", + "single_end": false + }, + "test.CollectWgsMetrics.coverage_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_picard": [ + [ + "PICARD_COLLECTWGSMETRICS", + "picard", + "3.4.0" + ] + ] + } + ], + "timestamp": "2026-02-20T10:35:04.636691319", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, "test-picard-collectwgsmetrics-with-interval": { "content": [ - true, - [ - "versions.yml:md5,9927db69fdd55176be5cdbd427d000c2" - ] + false, + { + "versions_picard": [ + [ + "PICARD_COLLECTWGSMETRICS", + "picard", + "3.4.0" + ] + ] + } + ], + "timestamp": "2026-02-20T10:34:45.059411647", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "test-picard-collectwgsmetrics - stub": { + "content": [ + { + "metrics": [ + [ + { + "id": "test", + "single_end": false + }, + "test.CollectWgsMetrics.coverage_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_picard": [ + [ + "PICARD_COLLECTWGSMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-20T10:34:54.347278951", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:15:18.13771243" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test-picard-collectwgsmetrics": { "content": [ - true, - [ - "versions.yml:md5,9927db69fdd55176be5cdbd427d000c2" - ] + false, + { + "versions_picard": [ + [ + "PICARD_COLLECTWGSMETRICS", + "picard", + "3.4.0" + ] + ] + } ], + "timestamp": "2026-02-20T10:34:25.744978033", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-10-18T10:14:57.786056996" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/samtools/cat/main.nf b/modules/nf-core/samtools/cat/main.nf deleted file mode 100644 index 61349e59..00000000 --- a/modules/nf-core/samtools/cat/main.nf +++ /dev/null @@ -1,50 +0,0 @@ -process SAMTOOLS_CAT { - tag "$meta.id" - label 'process_low' - - conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" - - input: - tuple val(meta), path(input_files, stageAs: "?/*") - - output: - tuple val(meta), path("*.bam") , optional:true, emit: bam - tuple val(meta), path("*.cram"), optional:true, emit: cram - path "versions.yml" , emit: versions - - - when: - task.ext.when == null || task.ext.when - - script: - def args = task.ext.args ?: '' - prefix = task.ext.prefix ?: "${meta.id}" - def file_type = input_files instanceof List ? input_files[0].getExtension() : input_files.getExtension() - """ - samtools \\ - cat \\ - $args \\ - -o ${prefix}.${file_type} \\ - $input_files - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS - """ - - stub: - prefix = task.ext.suffix ? "${meta.id}${task.ext.suffix}" : "${meta.id}" - def file_type = input_files instanceof List ? input_files[0].getExtension() : input_files.getExtension() - """ - touch ${prefix}.${file_type} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS - """ -} diff --git a/modules/nf-core/samtools/cat/meta.yml b/modules/nf-core/samtools/cat/meta.yml deleted file mode 100644 index dfb0f78c..00000000 --- a/modules/nf-core/samtools/cat/meta.yml +++ /dev/null @@ -1,59 +0,0 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/yaml-schema.json -name: samtools_cat -description: Concatenate BAM or CRAM file -keywords: - - merge - - bam - - sam - - cram -tools: - - samtools: - description: | - SAMtools is a set of utilities for interacting with and post-processing - short DNA sequence read alignments in the SAM, BAM and CRAM formats, written by Heng Li. - These files are generated as output by short read aligners like BWA. - homepage: http://www.htslib.org/ - documentation: http://www.htslib.org/doc/samtools.html - doi: 10.1093/bioinformatics/btp352 - licence: ["MIT"] - identifier: biotools:samtools -input: - - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - input_files: - type: file - description: BAM/CRAM files - pattern: "*.{bam,cram}" -output: - - bam: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - ${prefix}.bam: - type: file - description: Concatenated BAM file - pattern: "*.{bam}" - - cram: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - ${prefix}.cram: - type: file - description: Concatenated CRAM file - pattern: "*.{cram}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" -authors: - - "@matthdsm" -maintainers: - - "@matthdsm" diff --git a/modules/nf-core/samtools/cat/samtools-cat.diff b/modules/nf-core/samtools/cat/samtools-cat.diff deleted file mode 100644 index 71c58b5c..00000000 --- a/modules/nf-core/samtools/cat/samtools-cat.diff +++ /dev/null @@ -1,24 +0,0 @@ -Changes in module 'nf-core/samtools/cat' -'modules/nf-core/samtools/cat/environment.yml' is unchanged -'modules/nf-core/samtools/cat/meta.yml' is unchanged -Changes in 'samtools/cat/main.nf': ---- modules/nf-core/samtools/cat/main.nf -+++ modules/nf-core/samtools/cat/main.nf -@@ -11,9 +11,9 @@ - tuple val(meta), path(input_files, stageAs: "?/*") - - output: -- tuple val(meta), path("${prefix}.bam") , optional:true, emit: bam -- tuple val(meta), path("${prefix}.cram"), optional:true, emit: cram -- path "versions.yml" , emit: versions -+ tuple val(meta), path("*.bam") , optional:true, emit: bam -+ tuple val(meta), path("*.cram"), optional:true, emit: cram -+ path "versions.yml" , emit: versions - - - when: - -'modules/nf-core/samtools/cat/tests/main.nf.test.snap' is unchanged -'modules/nf-core/samtools/cat/tests/tags.yml' is unchanged -'modules/nf-core/samtools/cat/tests/main.nf.test' is unchanged -************************************************************ diff --git a/modules/nf-core/samtools/cat/tests/main.nf.test b/modules/nf-core/samtools/cat/tests/main.nf.test deleted file mode 100644 index dad80b83..00000000 --- a/modules/nf-core/samtools/cat/tests/main.nf.test +++ /dev/null @@ -1,61 +0,0 @@ -nextflow_process { - - name "Test Process SAMTOOLS_CAT" - script "../main.nf" - process "SAMTOOLS_CAT" - - tag "modules" - tag "modules_nfcore" - tag "samtools" - tag "samtools/cat" - - test("bams") { - - 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.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.unaligned.bam', checkIfExists: true) ] - ]) - """ - } - } - - then { - assertAll( - { assert process.success }, - { assert snapshot(file(process.out.bam[0][1]).name).match("bams_bam") }, - { assert snapshot(process.out.cram).match("bams_cram") }, - { assert snapshot(process.out.versions).match("bams_versions") } - ) - } - } - - test("bams_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.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.unaligned.bam', checkIfExists: true) ] - ]) - """ - } - } - - then { - assertAll( - { assert process.success }, - { assert snapshot(file(process.out.bam[0][1]).name).match("bams_stub_bam") }, - { assert snapshot(process.out.cram).match("bams_stub_cram") }, - { assert snapshot(process.out.versions).match("bams_stub_versions") } - ) - } - } -} diff --git a/modules/nf-core/samtools/cat/tests/main.nf.test.snap b/modules/nf-core/samtools/cat/tests/main.nf.test.snap deleted file mode 100644 index 9af1b19f..00000000 --- a/modules/nf-core/samtools/cat/tests/main.nf.test.snap +++ /dev/null @@ -1,70 +0,0 @@ -{ - "bams_stub_cram": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-02T16:45:42.587418" - }, - "bams_stub_versions": { - "content": [ - [ - "versions.yml:md5,cd29ae344fb0bf5635527e1cb7a7d95f" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-16T07:47:51.511914861" - }, - "bams_bam": { - "content": [ - "test.bam" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-02T16:45:37.965199" - }, - "bams_cram": { - "content": [ - [ - - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-02T16:45:37.96805" - }, - "bams_stub_bam": { - "content": [ - "test.bam" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.04.3" - }, - "timestamp": "2024-02-02T16:45:42.583881" - }, - "bams_versions": { - "content": [ - [ - "versions.yml:md5,cd29ae344fb0bf5635527e1cb7a7d95f" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-16T08:47:50.783194958" - } -} \ No newline at end of file diff --git a/modules/nf-core/samtools/cat/tests/tags.yml b/modules/nf-core/samtools/cat/tests/tags.yml deleted file mode 100644 index 97605570..00000000 --- a/modules/nf-core/samtools/cat/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -samtools/cat: - - "modules/nf-core/samtools/cat/**" diff --git a/modules/nf-core/samtools/convert/environment.yml b/modules/nf-core/samtools/convert/environment.yml index 62054fc9..89e12a64 100644 --- a/modules/nf-core/samtools/convert/environment.yml +++ b/modules/nf-core/samtools/convert/environment.yml @@ -4,5 +4,7 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.21 - - bioconda::samtools=1.21 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.22.1 diff --git a/modules/nf-core/samtools/convert/main.nf b/modules/nf-core/samtools/convert/main.nf index 9942d052..c3ee32ac 100644 --- a/modules/nf-core/samtools/convert/main.nf +++ b/modules/nf-core/samtools/convert/main.nf @@ -4,8 +4,8 @@ process SAMTOOLS_CONVERT { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.22.1--h96c455f_0' : + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: tuple val(meta), path(input), path(index), path(fasta), path(fai) @@ -15,7 +15,7 @@ process SAMTOOLS_CONVERT { tuple val(meta), path("*.cram") , emit: cram, optional: true tuple val(meta), path("*.bai") , emit: bai , optional: true tuple val(meta), path("*.crai") , emit: crai, optional: true - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), topic: versions, emit: versions_samtools when: task.ext.when == null || task.ext.when @@ -34,11 +34,6 @@ process SAMTOOLS_CONVERT { -o ${prefix}.${output_extension} samtools index -@${task.cpus} ${prefix}.${output_extension} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ stub: @@ -48,11 +43,6 @@ process SAMTOOLS_CONVERT { """ touch ${prefix}.${output_extension} - touch ${prefix}.${index_extension} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS + touch ${prefix}.${output_extension}.${index_extension} """ } diff --git a/modules/nf-core/samtools/convert/meta.yml b/modules/nf-core/samtools/convert/meta.yml index d5bfa161..286f812f 100644 --- a/modules/nf-core/samtools/convert/meta.yml +++ b/modules/nf-core/samtools/convert/meta.yml @@ -26,10 +26,12 @@ input: type: file description: BAM/CRAM file pattern: "*.{bam,cram}" + ontologies: [] - index: type: file description: BAM/CRAM index file pattern: "*.{bai,crai}" + ontologies: [] - - meta2: type: map description: | @@ -39,18 +41,15 @@ input: type: file description: Reference file to create the CRAM file pattern: "*.{fasta,fa}" - - - meta3: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] + ontologies: [] - fai: type: file description: Reference index file to create the CRAM file pattern: "*.{fai}" + ontologies: [] output: - - bam: - - meta: + bam: + - - meta: type: map description: | Groovy Map containing sample information @@ -59,8 +58,9 @@ output: type: file description: filtered/converted BAM file pattern: "*{.bam}" - - cram: - - meta: + ontologies: [] + cram: + - - meta: type: map description: | Groovy Map containing sample information @@ -69,8 +69,9 @@ output: type: file description: filtered/converted CRAM file pattern: "*{cram}" - - bai: - - meta: + ontologies: [] + bai: + - - meta: type: map description: | Groovy Map containing sample information @@ -79,8 +80,9 @@ output: type: file description: filtered/converted BAM index pattern: "*{.bai}" - - crai: - - meta: + ontologies: [] + crai: + - - meta: type: map description: | Groovy Map containing sample information @@ -89,11 +91,28 @@ output: type: file description: filtered/converted CRAM index pattern: "*{.crai}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool authors: - "@FriederikeHanssen" - "@maxulysse" diff --git a/modules/nf-core/samtools/convert/samtools-convert.diff b/modules/nf-core/samtools/convert/samtools-convert.diff index 67617c31..2ded55b4 100644 --- a/modules/nf-core/samtools/convert/samtools-convert.diff +++ b/modules/nf-core/samtools/convert/samtools-convert.diff @@ -1,22 +1,20 @@ -Changes in module 'nf-core/samtools/convert' +Changes in component 'nf-core/samtools/convert' 'modules/nf-core/samtools/convert/environment.yml' is unchanged 'modules/nf-core/samtools/convert/meta.yml' is unchanged Changes in 'samtools/convert/main.nf': --- modules/nf-core/samtools/convert/main.nf +++ modules/nf-core/samtools/convert/main.nf -@@ -8,9 +8,7 @@ - 'biocontainers/samtools:1.21--h50ea8bc_0' }" +@@ -8,8 +8,7 @@ + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: - tuple val(meta), path(input), path(index) -- tuple val(meta2), path(fasta) -- tuple val(meta3), path(fai) +- tuple val(meta2), path(fasta), path(fai) + tuple val(meta), path(input), path(index), path(fasta), path(fai) output: tuple val(meta), path("*.bam") , emit: bam , optional: true 'modules/nf-core/samtools/convert/tests/main.nf.test.snap' is unchanged -'modules/nf-core/samtools/convert/tests/tags.yml' is unchanged 'modules/nf-core/samtools/convert/tests/main.nf.test' is unchanged ************************************************************ diff --git a/modules/nf-core/samtools/convert/tests/main.nf.test b/modules/nf-core/samtools/convert/tests/main.nf.test index 91a0c69e..638caabe 100644 --- a/modules/nf-core/samtools/convert/tests/main.nf.test +++ b/modules/nf-core/samtools/convert/tests/main.nf.test @@ -9,99 +9,88 @@ nextflow_process { tag "samtools" tag "samtools/convert" - test("sarscov2 - [bam, bai], fasta, fai") { + test("sarscov2 - [bam, bai], [fasta, fai]") { when { process { """ - input[0] = Channel.of([ - [id: 'test', single_end: false], // meta map + input[0] = [ + [id: 'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) - ]) - input[1] = Channel.of([ - [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ]) - input[2] = Channel.of([ - [ id:'fai' ], // meta map + ] + input[1] = [ + [ id:'fasta' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) - ]) + ] """ } } then { - assertAll( - { assert process.success }, - { assert snapshot(file(process.out.cram[0][1]).name).match("bam_to_cram_alignment") }, - { assert snapshot(file(process.out.crai[0][1]).name).match("bam_to_cram_index") }, - { assert snapshot(process.out.versions).match("bam_to_cram_versions") } - ) + assert process.success + assert snapshot( + process.out.cram.collect{ meta, cram_file -> [ meta, file(cram_file).name] }, + process.out.crai.collect{ meta, crai_file -> [ meta, file(crai_file).name] }, + ["versions_samtools": process.out.versions_samtools] + ).match() } } - test("homo_sapiens - [cram, crai], fasta, fai") { + test("homo_sapiens - [cram, crai], [fasta, fai]") { when { process { """ - input[0] = Channel.of([ - [id: 'test', single_end: false], // meta map + input[0] = [ + [id: 'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true) - ]) - input[1] = Channel.of([ - [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) - ]) - input[2] = Channel.of([ - [ id:'fai' ], // meta map + ] + input[1] = [ + [ id:'fasta' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) - ]) + ] """ } } then { - assertAll( - { assert process.success }, - { assert snapshot(file(process.out.bam[0][1]).name).match("cram_to_bam_alignment") }, - { assert snapshot(file(process.out.bai[0][1]).name).match("cram_to_bam_alignment_index") }, - { assert snapshot(process.out.versions).match("cram_to_bam_versions") } - ) + assert process.success + assert snapshot( + process.out.bam.collect{ meta, bam_file -> [ meta, file(bam_file).name, bam(bam_file).getReadsMD5()] }, + process.out.bai.collect{ meta, bai_file -> [ meta, file(bai_file).name] }, + ["versions_samtools": process.out.versions_samtools] + ).match() } } - test("sarscov2 - [bam, bai], fasta, fai - stub") { - + test("sarscov2 - [bam, bai], [fasta, fai] - stub") { + options "-stub" when { process { """ - input[0] = Channel.of([ - [id: 'test', single_end: false], // meta map + input[0] = [ + [id: 'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) - ]) - input[1] = Channel.of([ - [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ]) - input[2] = Channel.of([ - [ id:'fai' ], // meta map + ] + input[1] = [ + [ id:'fasta' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) - ]) + ] """ } } then { - assertAll( - { assert process.success }, - { assert snapshot(process.out).match("stub") } - ) + assert process.success + assert snapshot(sanitizeOutput(process.out)).match() } } } diff --git a/modules/nf-core/samtools/convert/tests/main.nf.test.snap b/modules/nf-core/samtools/convert/tests/main.nf.test.snap index a021254e..57e7ccb3 100644 --- a/modules/nf-core/samtools/convert/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/convert/tests/main.nf.test.snap @@ -1,78 +1,76 @@ { - "cram_to_bam_alignment": { - "content": [ - "test.bam" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-03-06T11:14:51.300147176" - }, - "bam_to_cram_alignment": { - "content": [ - "test.cram" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-03-06T11:14:36.625470184" - }, - "cram_to_bam_versions": { + "sarscov2 - [bam, bai], [fasta, fai]": { "content": [ [ - "versions.yml:md5,5bc6eb42ab2a1ea6661f8ee998467ad6" - ] + [ + { + "id": "test" + }, + "test.cram" + ] + ], + [ + [ + { + "id": "test" + }, + "test.cram.crai" + ] + ], + { + "versions_samtools": [ + [ + "SAMTOOLS_CONVERT", + "samtools", + "1.22.1" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-09-16T07:52:35.516411351" + "timestamp": "2026-02-05T11:02:26.691358025" }, - "bam_to_cram_versions": { + "homo_sapiens - [cram, crai], [fasta, fai]": { "content": [ [ - "versions.yml:md5,5bc6eb42ab2a1ea6661f8ee998467ad6" - ] + [ + { + "id": "test" + }, + "test.bam", + "2f11e4fe3390b8ad0a1852616fd1da04" + ] + ], + [ + [ + { + "id": "test" + }, + "test.bam.bai" + ] + ], + { + "versions_samtools": [ + [ + "SAMTOOLS_CONVERT", + "samtools", + "1.22.1" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-09-16T07:52:24.694454205" + "timestamp": "2026-02-05T11:24:13.012572069" }, - "stub": { + "sarscov2 - [bam, bai], [fasta, fai] - stub": { "content": [ { - "0": [ - - ], - "1": [ - [ - { - "id": "test", - "single_end": false - }, - "test.cram:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "2": [ - - ], - "3": [ - [ - { - "id": "test", - "single_end": false - }, - "test.crai:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "4": [ - "versions.yml:md5,5bc6eb42ab2a1ea6661f8ee998467ad6" - ], "bai": [ ], @@ -82,50 +80,32 @@ "crai": [ [ { - "id": "test", - "single_end": false + "id": "test" }, - "test.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "cram": [ [ { - "id": "test", - "single_end": false + "id": "test" }, "test.cram:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,5bc6eb42ab2a1ea6661f8ee998467ad6" + "versions_samtools": [ + [ + "SAMTOOLS_CONVERT", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-16T07:52:45.799885099" - }, - "bam_to_cram_index": { - "content": [ - "test.cram.crai" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-03-06T11:14:36.640009334" - }, - "cram_to_bam_alignment_index": { - "content": [ - "test.bam.bai" - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-03-06T11:14:51.304477426" + "timestamp": "2026-02-05T11:24:19.471055529" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/convert/tests/tags.yml b/modules/nf-core/samtools/convert/tests/tags.yml deleted file mode 100644 index 030d5eb5..00000000 --- a/modules/nf-core/samtools/convert/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -samtools/convert: - - "modules/nf-core/samtools/convert/**" diff --git a/modules/nf-core/samtools/coverage/environment.yml b/modules/nf-core/samtools/coverage/environment.yml index 62054fc9..89e12a64 100644 --- a/modules/nf-core/samtools/coverage/environment.yml +++ b/modules/nf-core/samtools/coverage/environment.yml @@ -4,5 +4,7 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.21 - - bioconda::samtools=1.21 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.22.1 diff --git a/modules/nf-core/samtools/coverage/main.nf b/modules/nf-core/samtools/coverage/main.nf index 11e347e8..ff566999 100644 --- a/modules/nf-core/samtools/coverage/main.nf +++ b/modules/nf-core/samtools/coverage/main.nf @@ -4,15 +4,15 @@ process SAMTOOLS_COVERAGE { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.22.1--h96c455f_0' : + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: tuple val(meta), path(input), path(input_index), path(fasta), path(fai) output: tuple val(meta), path("*.txt"), emit: coverage - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), topic: versions, emit: versions_samtools when: task.ext.when == null || task.ext.when @@ -20,28 +20,23 @@ process SAMTOOLS_COVERAGE { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" + def reference = fasta ? "--reference ${fasta}" : "" + + if (input.name.endsWith('.cram') && (!fasta || !fai)) { + error "CRAM input file provided but no reference FASTA and/or FAI index for said reference, both are required for CRAM input." + } """ samtools \\ coverage \\ $args \\ -o ${prefix}.txt \\ - --reference ${fasta} \\ + $reference \\ $input - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//' ) - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}.txt - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//' ) - END_VERSIONS + echo "#rname\tstartpos\tendpos\tnumreads\tcovbases\tcoverage\tmeandepth\tmeanbaseq\tmeanmapq" > ${prefix}.txt """ } diff --git a/modules/nf-core/samtools/coverage/meta.yml b/modules/nf-core/samtools/coverage/meta.yml index fb9ba6f3..b2262177 100644 --- a/modules/nf-core/samtools/coverage/meta.yml +++ b/modules/nf-core/samtools/coverage/meta.yml @@ -25,10 +25,12 @@ input: type: file description: BAM/CRAM/SAM file pattern: "*.{bam,cram,sam}" + ontologies: [] - input_index: type: file description: BAM/CRAM index file pattern: "*.{bai,crai}" + ontologies: [] - - meta2: type: map description: | @@ -38,32 +40,48 @@ input: type: file description: Reference genome file pattern: "*.{fa,fasta}" - - - meta3: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] + ontologies: [] - fai: type: file description: Reference genome index file pattern: "*.fai" + ontologies: [] output: - - coverage: - - meta: + coverage: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - "*.txt": type: file - description: Tabulated text containing the coverage at each position or region - or an ASCII-art histogram (with --histogram). + description: Tabulated text containing the coverage at each position or + region or an ASCII-art histogram (with --histogram). pattern: "*.txt" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool + authors: - "@LouisLeNezet" maintainers: diff --git a/modules/nf-core/samtools/coverage/samtools-coverage.diff b/modules/nf-core/samtools/coverage/samtools-coverage.diff index 3b0e1f03..fe18381a 100644 --- a/modules/nf-core/samtools/coverage/samtools-coverage.diff +++ b/modules/nf-core/samtools/coverage/samtools-coverage.diff @@ -1,22 +1,20 @@ -Changes in module 'nf-core/samtools/coverage' +Changes in component 'nf-core/samtools/coverage' 'modules/nf-core/samtools/coverage/environment.yml' is unchanged 'modules/nf-core/samtools/coverage/meta.yml' is unchanged Changes in 'samtools/coverage/main.nf': --- modules/nf-core/samtools/coverage/main.nf +++ modules/nf-core/samtools/coverage/main.nf -@@ -8,9 +8,7 @@ - 'biocontainers/samtools:1.21--h50ea8bc_0' }" +@@ -8,8 +8,7 @@ + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: - tuple val(meta), path(input), path(input_index) -- tuple val(meta2), path(fasta) -- tuple val(meta3), path(fai) +- tuple val(meta2), path(fasta), path(fai) + tuple val(meta), path(input), path(input_index), path(fasta), path(fai) output: tuple val(meta), path("*.txt"), emit: coverage 'modules/nf-core/samtools/coverage/tests/main.nf.test.snap' is unchanged -'modules/nf-core/samtools/coverage/tests/tags.yml' is unchanged 'modules/nf-core/samtools/coverage/tests/main.nf.test' is unchanged ************************************************************ diff --git a/modules/nf-core/samtools/coverage/tests/main.nf.test b/modules/nf-core/samtools/coverage/tests/main.nf.test index 1e3ad5a4..c59ba4f8 100644 --- a/modules/nf-core/samtools/coverage/tests/main.nf.test +++ b/modules/nf-core/samtools/coverage/tests/main.nf.test @@ -14,19 +14,12 @@ nextflow_process { when { process { """ - input[0] = Channel.of([ - [id: 'test', single_end: false], // meta map + input[0] = [ + [id: 'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) - ]) - input[1] = Channel.of([ - [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ]) - input[2] = Channel.of([ - [ id:'fai' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) - ]) + ] + input[1] = [[], [], []] """ } } @@ -34,7 +27,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(sanitizeOutput(process.out)).match() } ) } } @@ -44,19 +37,16 @@ nextflow_process { when { process { """ - input[0] = Channel.of([ - [id: 'test', single_end: false], // meta map + input[0] = [ + [id: 'test'], file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true) - ]) - input[1] = Channel.of([ - [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) - ]) - input[2] = Channel.of([ - [ id:'fai' ], // meta map + ] + input[1] = [ + [ id:'fasta_fai' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) - ]) + ] """ } } @@ -69,6 +59,58 @@ nextflow_process { } } + test("test_samtools_coverage_cram_no_fasta") { + when { + process { + """ + input[0] = [ + [id: 'test'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true) + ] + input[1] = [ + [ id:'fai' ], [], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert !process.success }, + { assert process.stdout.toString().contains("CRAM input file provided but no reference FASTA and/or FAI index for said reference, both are required for CRAM input.") }, + ) + } + } + + test("test_samtools_coverage_cram_no_fai") { + when { + process { + """ + input[0] = [ + [id: 'test'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true) + ] + input[1] = [ + [ id:'fasta' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + [] + ] + """ + } + } + + then { + assertAll( + { assert !process.success }, + { assert process.stdout.toString().contains("CRAM input file provided but no reference FASTA and/or FAI index for said reference, both are required for CRAM input.") }, + ) + } + } + + test("test_samtools_coverage_stub") { options "-stub" @@ -76,19 +118,16 @@ nextflow_process { when { process { """ - input[0] = Channel.of([ - [id: 'test', single_end: false], // meta map + input[0] = [ + [id: 'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) - ]) - input[1] = Channel.of([ - [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ]) - input[2] = Channel.of([ - [ id:'fai' ], // meta map + ] + input[1] = [ + [ id:'fasta' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) - ]) + ] """ } } @@ -96,7 +135,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(sanitizeOutput(process.out)).match() } ) } diff --git a/modules/nf-core/samtools/coverage/tests/main.nf.test.snap b/modules/nf-core/samtools/coverage/tests/main.nf.test.snap index b9ddb18d..0d72500a 100644 --- a/modules/nf-core/samtools/coverage/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/coverage/tests/main.nf.test.snap @@ -2,72 +2,54 @@ "test_samtools_coverage_stub": { "content": [ { - "0": [ + "coverage": [ [ { - "id": "test", - "single_end": false + "id": "test" }, - "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.txt:md5,ea885d54c0223dff86e2e44f5bc08374" ] ], - "1": [ - "versions.yml:md5,9c876b9db54dc710c87c404e4b28243c" - ], - "coverage": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + "SAMTOOLS_COVERAGE", + "samtools", + "1.22.1" ] - ], - "versions": [ - "versions.yml:md5,9c876b9db54dc710c87c404e4b28243c" ] } ], + "timestamp": "2026-03-03T16:16:25.616671578", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-16T07:53:42.773351407" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test_samtools_coverage_bam": { "content": [ { - "0": [ + "coverage": [ [ { - "id": "test", - "single_end": false + "id": "test" }, "test.txt:md5,99a521b3bf53b6acf8055a44a571ea84" ] ], - "1": [ - "versions.yml:md5,9c876b9db54dc710c87c404e4b28243c" - ], - "coverage": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.txt:md5,99a521b3bf53b6acf8055a44a571ea84" + "SAMTOOLS_COVERAGE", + "samtools", + "1.22.1" ] - ], - "versions": [ - "versions.yml:md5,9c876b9db54dc710c87c404e4b28243c" ] } ], + "timestamp": "2026-02-10T15:27:06.759689511", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-16T07:53:22.798338025" + "nf-test": "0.9.3", + "nextflow": "25.10.3" + } }, "test_samtools_coverage_cram": { "content": [ @@ -75,33 +57,39 @@ "0": [ [ { - "id": "test", - "single_end": false + "id": "test" }, "test.txt:md5,ce896534bac51cfcc97e5508ae907e99" ] ], "1": [ - "versions.yml:md5,9c876b9db54dc710c87c404e4b28243c" + [ + "SAMTOOLS_COVERAGE", + "samtools", + "1.22.1" + ] ], "coverage": [ [ { - "id": "test", - "single_end": false + "id": "test" }, "test.txt:md5,ce896534bac51cfcc97e5508ae907e99" ] ], - "versions": [ - "versions.yml:md5,9c876b9db54dc710c87c404e4b28243c" + "versions_samtools": [ + [ + "SAMTOOLS_COVERAGE", + "samtools", + "1.22.1" + ] ] } ], + "timestamp": "2026-02-10T15:27:12.949845604", "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-09-16T07:53:32.409876082" + "nf-test": "0.9.3", + "nextflow": "25.10.3" + } } } \ No newline at end of file diff --git a/modules/nf-core/samtools/coverage/tests/tags.yml b/modules/nf-core/samtools/coverage/tests/tags.yml deleted file mode 100644 index 2b4f53c2..00000000 --- a/modules/nf-core/samtools/coverage/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -samtools/coverage: - - "modules/nf-core/samtools/coverage/**" diff --git a/modules/nf-core/samtools/flagstat/environment.yml b/modules/nf-core/samtools/flagstat/environment.yml index 62054fc9..89e12a64 100644 --- a/modules/nf-core/samtools/flagstat/environment.yml +++ b/modules/nf-core/samtools/flagstat/environment.yml @@ -4,5 +4,7 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.21 - - bioconda::samtools=1.21 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.22.1 diff --git a/modules/nf-core/samtools/flagstat/main.nf b/modules/nf-core/samtools/flagstat/main.nf index c23f3a5c..0cfb7e87 100644 --- a/modules/nf-core/samtools/flagstat/main.nf +++ b/modules/nf-core/samtools/flagstat/main.nf @@ -4,15 +4,15 @@ process SAMTOOLS_FLAGSTAT { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.22.1--h96c455f_0' : + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: tuple val(meta), path(bam), path(bai) output: tuple val(meta), path("*.flagstat"), emit: flagstat - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), emit: versions_samtools, topic: versions when: task.ext.when == null || task.ext.when @@ -25,21 +25,23 @@ process SAMTOOLS_FLAGSTAT { --threads ${task.cpus} \\ $bam \\ > ${prefix}.flagstat - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}.flagstat - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS + cat <<-END_FLAGSTAT > ${prefix}.flagstat + 1000000 + 0 in total (QC-passed reads + QC-failed reads) + 0 + 0 secondary + 0 + 0 supplementary + 0 + 0 duplicates + 900000 + 0 mapped (90.00% : N/A) + 1000000 + 0 paired in sequencing + 500000 + 0 read1 + 500000 + 0 read2 + 800000 + 0 properly paired (80.00% : N/A) + 850000 + 0 with mate mapped to a different chr + 50000 + 0 with mate mapped to a different chr (mapQ>=5) + END_FLAGSTAT """ } diff --git a/modules/nf-core/samtools/flagstat/meta.yml b/modules/nf-core/samtools/flagstat/meta.yml index cdc4c254..8caa1bcc 100644 --- a/modules/nf-core/samtools/flagstat/meta.yml +++ b/modules/nf-core/samtools/flagstat/meta.yml @@ -1,6 +1,6 @@ name: samtools_flagstat -description: Counts the number of alignments in a BAM/CRAM/SAM file for each FLAG - type +description: Counts the number of alignments in a BAM/CRAM/SAM file for each + FLAG type keywords: - stats - mapping @@ -17,7 +17,8 @@ tools: homepage: http://www.htslib.org/ documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 - licence: ["MIT"] + licence: + - "MIT" identifier: biotools:samtools input: - - meta: @@ -29,13 +30,15 @@ input: type: file description: BAM/CRAM/SAM file pattern: "*.{bam,cram,sam}" + ontologies: [] - bai: type: file description: Index for BAM/CRAM/SAM file pattern: "*.{bai,crai,sai}" + ontologies: [] output: - - flagstat: - - meta: + flagstat: + - - meta: type: map description: | Groovy Map containing sample information @@ -44,11 +47,28 @@ output: type: file description: File containing samtools flagstat output pattern: "*.{flagstat}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool authors: - "@drpatelh" maintainers: diff --git a/modules/nf-core/samtools/flagstat/tests/main.nf.test.snap b/modules/nf-core/samtools/flagstat/tests/main.nf.test.snap index 04c3852b..f5c882da 100644 --- a/modules/nf-core/samtools/flagstat/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/flagstat/tests/main.nf.test.snap @@ -8,11 +8,15 @@ "id": "test", "single_end": false }, - "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.flagstat:md5,67394650dbae96d1a4fcc70484822159" ] ], "1": [ - "versions.yml:md5,108a155f2d4a99f50bf3176904208d27" + [ + "SAMTOOLS_FLAGSTAT", + "samtools", + "1.22.1" + ] ], "flagstat": [ [ @@ -20,19 +24,23 @@ "id": "test", "single_end": false }, - "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.flagstat:md5,67394650dbae96d1a4fcc70484822159" ] ], - "versions": [ - "versions.yml:md5,108a155f2d4a99f50bf3176904208d27" + "versions_samtools": [ + [ + "SAMTOOLS_FLAGSTAT", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-09-16T08:02:58.866491759" + "timestamp": "2026-02-03T11:14:30.820969684" }, "BAM": { "content": [ @@ -47,7 +55,11 @@ ] ], "1": [ - "versions.yml:md5,108a155f2d4a99f50bf3176904208d27" + [ + "SAMTOOLS_FLAGSTAT", + "samtools", + "1.22.1" + ] ], "flagstat": [ [ @@ -58,15 +70,19 @@ "test.flagstat:md5,4f7ffd1e6a5e85524d443209ac97d783" ] ], - "versions": [ - "versions.yml:md5,108a155f2d4a99f50bf3176904208d27" + "versions_samtools": [ + [ + "SAMTOOLS_FLAGSTAT", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-09-16T08:02:47.383332837" + "timestamp": "2026-02-03T11:14:25.581619424" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/flagstat/tests/tags.yml b/modules/nf-core/samtools/flagstat/tests/tags.yml deleted file mode 100644 index 2d2b7255..00000000 --- a/modules/nf-core/samtools/flagstat/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -samtools/flagstat: - - modules/nf-core/samtools/flagstat/** diff --git a/modules/nf-core/samtools/idxstats/environment.yml b/modules/nf-core/samtools/idxstats/environment.yml index 62054fc9..89e12a64 100644 --- a/modules/nf-core/samtools/idxstats/environment.yml +++ b/modules/nf-core/samtools/idxstats/environment.yml @@ -4,5 +4,7 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.21 - - bioconda::samtools=1.21 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.22.1 diff --git a/modules/nf-core/samtools/idxstats/main.nf b/modules/nf-core/samtools/idxstats/main.nf index e2bb6b20..d5b70a7f 100644 --- a/modules/nf-core/samtools/idxstats/main.nf +++ b/modules/nf-core/samtools/idxstats/main.nf @@ -4,15 +4,15 @@ process SAMTOOLS_IDXSTATS { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.22.1--h96c455f_0' : + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: tuple val(meta), path(bam), path(bai) output: tuple val(meta), path("*.idxstats"), emit: idxstats - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), emit: versions_samtools, topic: versions when: task.ext.when == null || task.ext.when @@ -21,16 +21,12 @@ process SAMTOOLS_IDXSTATS { def prefix = task.ext.prefix ?: "${meta.id}" """ + # Note: --threads value represents *additional* CPUs to allocate (total CPUs = 1 + --threads). samtools \\ idxstats \\ --threads ${task.cpus-1} \\ $bam \\ > ${prefix}.idxstats - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ stub: @@ -38,10 +34,5 @@ process SAMTOOLS_IDXSTATS { """ touch ${prefix}.idxstats - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/samtools/idxstats/meta.yml b/modules/nf-core/samtools/idxstats/meta.yml index f0a6bcb2..fd153841 100644 --- a/modules/nf-core/samtools/idxstats/meta.yml +++ b/modules/nf-core/samtools/idxstats/meta.yml @@ -17,7 +17,8 @@ tools: homepage: http://www.htslib.org/ documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 - licence: ["MIT"] + licence: + - "MIT" identifier: biotools:samtools input: - - meta: @@ -29,13 +30,15 @@ input: type: file description: BAM/CRAM/SAM file pattern: "*.{bam,cram,sam}" + ontologies: [] - bai: type: file description: Index for BAM/CRAM/SAM file pattern: "*.{bai,crai,sai}" + ontologies: [] output: - - idxstats: - - meta: + idxstats: + - - meta: type: map description: | Groovy Map containing sample information @@ -44,11 +47,28 @@ output: type: file description: File containing samtools idxstats output pattern: "*.{idxstats}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool authors: - "@drpatelh" maintainers: diff --git a/modules/nf-core/samtools/idxstats/tests/main.nf.test b/modules/nf-core/samtools/idxstats/tests/main.nf.test index 5fd1fc78..c990cd55 100644 --- a/modules/nf-core/samtools/idxstats/tests/main.nf.test +++ b/modules/nf-core/samtools/idxstats/tests/main.nf.test @@ -25,7 +25,10 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + process.out.idxstats, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } ) } } @@ -47,7 +50,10 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + process.out.idxstats, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } ) } }} diff --git a/modules/nf-core/samtools/idxstats/tests/main.nf.test.snap b/modules/nf-core/samtools/idxstats/tests/main.nf.test.snap index 2cc89a3b..19a54c7c 100644 --- a/modules/nf-core/samtools/idxstats/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/idxstats/tests/main.nf.test.snap @@ -1,72 +1,56 @@ { "bam - stub": { "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "1": [ - "versions.yml:md5,c8d7394830c3c1e5be150589571534fb" - ], - "idxstats": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + "SAMTOOLS_IDXSTATS", + "samtools", + "1.22.1" ] - ], - "versions": [ - "versions.yml:md5,c8d7394830c3c1e5be150589571534fb" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-09-16T08:11:56.466856235" + "timestamp": "2026-02-02T16:21:46.333090477" }, "bam": { "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,df60a8c8d6621100d05178c93fb053a2" + ] + ], { - "0": [ - [ - { - "id": "test", - "single_end": false - }, - "test.idxstats:md5,df60a8c8d6621100d05178c93fb053a2" - ] - ], - "1": [ - "versions.yml:md5,c8d7394830c3c1e5be150589571534fb" - ], - "idxstats": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.idxstats:md5,df60a8c8d6621100d05178c93fb053a2" + "SAMTOOLS_IDXSTATS", + "samtools", + "1.22.1" ] - ], - "versions": [ - "versions.yml:md5,c8d7394830c3c1e5be150589571534fb" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-09-16T08:11:46.311550359" + "timestamp": "2026-02-02T16:21:41.063422521" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/idxstats/tests/tags.yml b/modules/nf-core/samtools/idxstats/tests/tags.yml deleted file mode 100644 index d3057c61..00000000 --- a/modules/nf-core/samtools/idxstats/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -samtools/idxstats: - - modules/nf-core/samtools/idxstats/** diff --git a/modules/nf-core/samtools/import/main.nf b/modules/nf-core/samtools/import/main.nf deleted file mode 100644 index b6927949..00000000 --- a/modules/nf-core/samtools/import/main.nf +++ /dev/null @@ -1,59 +0,0 @@ -process SAMTOOLS_IMPORT { - tag "$meta.id" - label 'process_single' - - conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0': - 'biocontainers/samtools:1.21--h50ea8bc_0' }" - - input: - tuple val(meta), path(reads) - - output: - tuple val(meta), path("*.sam") , emit: sam, optional: true - tuple val(meta), path("*.bam") , emit: bam, optional: true - tuple val(meta), path("*.cram"), emit: cram, optional: true - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def suffix = args.contains("--output-fmt sam") ? "sam" : - args.contains("--output-fmt bam") ? "bam" : - args.contains("--output-fmt cram") ? "cram" : - "bam" - def input = reads instanceof List && meta.single_end ? reads.join(" -0") : // multiple single-end files - reads instanceof List && !meta.single_end ? "-1 ${reads[0]} -2 ${reads[1]}": // paired end file - meta.single_end ? "-0 $reads" : // single single-end file - !meta.single_end ? "-s $reads": // interleave paired-end file - reads // if all else fails, just add the reads without flags - """ - samtools \\ - import \\ - $input \\ - $args \\ - -@ $task.cpus \\ - -o ${prefix}.${suffix} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS - """ - - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - - """ - touch ${prefix}.bam - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS - """ -} diff --git a/modules/nf-core/samtools/import/meta.yml b/modules/nf-core/samtools/import/meta.yml deleted file mode 100644 index 5c98b8be..00000000 --- a/modules/nf-core/samtools/import/meta.yml +++ /dev/null @@ -1,70 +0,0 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/yaml-schema.json -name: "samtools_import" -description: converts FASTQ files to unmapped SAM/BAM/CRAM -keywords: - - import - - fastq - - bam - - sam - - cram -tools: - - samtools: - description: | - SAMtools is a set of utilities for interacting with and post-processing - short DNA sequence read alignments in the SAM, BAM and CRAM formats, written by Heng Li. - These files are generated as output by short read aligners like BWA. - homepage: http://www.htslib.org/ - documentation: http://www.htslib.org/doc/samtools.html - doi: 10.1093/bioinformatics/btp352 - licence: ["MIT"] - identifier: biotools:samtools -input: - - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. `[ id:'test', single_end:false ]` - - reads: - type: file - description: fastq data to be converted to SAM/BAM/CRAM - pattern: "*.{fastq,fq,fastq.gz,fq.gz}" -output: - - sam: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. `[ id:'test', single_end:false ]` - - "*.sam": - type: file - description: SAM file - pattern: "*.sam" - - bam: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. `[ id:'test', single_end:false ]` - - "*.bam": - type: file - description: Unaligned BAM file - pattern: "*.bam" - - cram: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. `[ id:'test', single_end:false ]` - - "*.cram": - type: file - description: Unaligned CRAM file - pattern: "*.cram" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" -authors: - - "@matthdsm" -maintainers: - - "@matthdsm" diff --git a/modules/nf-core/samtools/import/tests/main.nf.test b/modules/nf-core/samtools/import/tests/main.nf.test deleted file mode 100644 index 9c7ce5d9..00000000 --- a/modules/nf-core/samtools/import/tests/main.nf.test +++ /dev/null @@ -1,83 +0,0 @@ -nextflow_process { - - name "Test Process SAMTOOLS_IMPORT" - script "../main.nf" - process "SAMTOOLS_IMPORT" - tag "modules" - tag "modules_nfcore" - tag "samtools" - tag "samtools/import" - - test("samtools_import_single ") { - - when { - params { - outdir = "$outputDir" - } - process { - """ - input[0] = Channel.of([ - [ id:'test', 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.bam.collect { it.collect { it instanceof Map ? it : file(it).name } }).match()} - ) - } - } - - test("samtools_import_paired ") { - - when { - params { - outdir = "$outputDir" - } - 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.bam.collect { it.collect { it instanceof Map ? it : file(it).name } }).match()} - ) - } - } - - test("samtools_import_interleaved") { - - when { - params { - outdir = "$outputDir" - } - 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.bam.collect { it.collect { it instanceof Map ? it : file(it).name } }).match()} - ) - } - } -} diff --git a/modules/nf-core/samtools/import/tests/main.nf.test.snap b/modules/nf-core/samtools/import/tests/main.nf.test.snap deleted file mode 100644 index eb730a06..00000000 --- a/modules/nf-core/samtools/import/tests/main.nf.test.snap +++ /dev/null @@ -1,103 +0,0 @@ -{ - "samtools_import_single ": { - "content": [ - [ - [ - { - "id": "test", - "single_end": true - }, - "test.bam" - ] - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-05-31T11:38:44.388259606" - }, - "samtools_import_interleaved": { - "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.bam" - ] - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-05-31T11:38:56.393371331" - }, - "samtools_import_paired ": { - "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.bam" - ] - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-05-31T11:38:50.437197406" - }, - "samtools_import_interleaved ": { - "content": [ - { - "0": [ - - ], - "1": [ - [ - { - "id": "test", - "single_end": false - }, - "test.bam:md5,fad91b070f51c77d7abe22cd31243710" - ] - ], - "2": [ - - ], - "3": [ - "versions.yml:md5,a529fc2aa6485db14986c95c53638b11" - ], - "bam": [ - [ - { - "id": "test", - "single_end": false - }, - "test.bam:md5,fad91b070f51c77d7abe22cd31243710" - ] - ], - "cram": [ - - ], - "sam": [ - - ], - "versions": [ - "versions.yml:md5,a529fc2aa6485db14986c95c53638b11" - ] - } - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-05-30T12:12:43.491200967" - } -} \ No newline at end of file diff --git a/modules/nf-core/samtools/import/tests/tags.yml b/modules/nf-core/samtools/import/tests/tags.yml deleted file mode 100644 index 89c89128..00000000 --- a/modules/nf-core/samtools/import/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -samtools/import: - - modules/nf-core/samtools/import/** diff --git a/modules/nf-core/samtools/sormadup/environment.yml b/modules/nf-core/samtools/sormadup/environment.yml index 62054fc9..89e12a64 100644 --- a/modules/nf-core/samtools/sormadup/environment.yml +++ b/modules/nf-core/samtools/sormadup/environment.yml @@ -4,5 +4,7 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.21 - - bioconda::samtools=1.21 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.22.1 diff --git a/modules/nf-core/samtools/sormadup/main.nf b/modules/nf-core/samtools/sormadup/main.nf index 0ee7a0a7..15bcf5ff 100644 --- a/modules/nf-core/samtools/sormadup/main.nf +++ b/modules/nf-core/samtools/sormadup/main.nf @@ -4,11 +4,11 @@ process SAMTOOLS_SORMADUP { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.22.1--h96c455f_0' : + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: - tuple val(meta), path(input), path(fasta) + tuple val(meta), path(input), path(fasta), path(fai) output: tuple val(meta), path("*.bam") , emit: bam, optional: true @@ -16,7 +16,7 @@ process SAMTOOLS_SORMADUP { tuple val(meta), path("*.csi") , emit: csi, optional: true tuple val(meta), path("*.crai") , emit: crai, optional: true tuple val(meta), path("*.metrics") , emit: metrics - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), topic: versions, emit: versions_samtools when: task.ext.when == null || task.ext.when @@ -32,9 +32,6 @@ process SAMTOOLS_SORMADUP { args5.contains("--output-fmt cram") ? "cram" : "bam" def reference = fasta ? "--reference ${fasta}" : "" - // memory per thread for samtools sort - // set to 50% of the memory per thread, but at least 768M (samtools default) - def sort_memory = Math.max(768,(task.memory.mega/task.cpus*0.50).intValue()) """ samtools cat \\ @@ -63,7 +60,6 @@ process SAMTOOLS_SORMADUP { -u \\ -T ${prefix}.sort \\ --threads $task.cpus \\ - -m ${sort_memory}M \\ - \\ | \\ samtools markdup \\ @@ -75,10 +71,6 @@ process SAMTOOLS_SORMADUP { - \\ ${prefix}.${extension} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ stub: @@ -91,10 +83,5 @@ process SAMTOOLS_SORMADUP { """ touch ${prefix}.${extension} touch ${prefix}.metrics - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/samtools/sormadup/meta.yml b/modules/nf-core/samtools/sormadup/meta.yml index bec58e87..02b9ad4e 100644 --- a/modules/nf-core/samtools/sormadup/meta.yml +++ b/modules/nf-core/samtools/sormadup/meta.yml @@ -1,4 +1,3 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json name: "samtools_sormadup" description: Collate/Fixmate/Sort/Markdup SAM/BAM/CRAM file keywords: @@ -20,7 +19,8 @@ tools: homepage: http://www.htslib.org/ documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 - licence: ["MIT"] + licence: + - "MIT" args_id: "$args" identifier: biotools:samtools - samtools_collate: @@ -31,7 +31,8 @@ tools: homepage: http://www.htslib.org/ documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 - licence: ["MIT"] + licence: + - "MIT" args_id: "$args2" identifier: biotools:samtools - samtools_fixmate: @@ -42,7 +43,8 @@ tools: homepage: http://www.htslib.org/ documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 - licence: ["MIT"] + licence: + - "MIT" args_id: "$args3" identifier: biotools:samtools - samtools_sort: @@ -53,7 +55,8 @@ tools: homepage: http://www.htslib.org/ documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 - licence: ["MIT"] + licence: + - "MIT" args_id: "$args4" identifier: biotools:samtools - samtools_markdup: @@ -64,7 +67,8 @@ tools: homepage: http://www.htslib.org/ documentation: http://www.htslib.org/doc/samtools.html doi: 10.1093/bioinformatics/btp352 - licence: ["MIT"] + licence: + - "MIT" args_id: "$args5" identifier: biotools:samtools input: @@ -77,6 +81,7 @@ input: type: file description: BAM/CRAM/SAM files pattern: "*.{bam,cram,sam}" + ontologies: [] - - meta2: type: map description: | @@ -86,9 +91,15 @@ input: type: file description: Reference genome file pattern: "*.{fasta,fa,fna}" + ontologies: [] + - fai: + type: file + description: Reference genome index file + pattern: "*.fai" + ontologies: [] output: - - bam: - - meta: + bam: + - - meta: type: map description: | Groovy Map containing sample information @@ -97,8 +108,9 @@ output: type: file description: Sorted and duplicate marked BAM file pattern: "*.bam" - - cram: - - meta: + ontologies: [] + cram: + - - meta: type: map description: | Groovy Map containing sample information @@ -107,8 +119,9 @@ output: type: file description: Sorted and duplicate marked CRAM file pattern: "*.cram" - - csi: - - meta: + ontologies: [] + csi: + - - meta: type: map description: | Groovy Map containing sample information @@ -117,8 +130,9 @@ output: type: file description: Sorted and duplicate marked BAM index file pattern: "*.csi" - - crai: - - meta: + ontologies: [] + crai: + - - meta: type: map description: | Groovy Map containing sample information @@ -127,8 +141,9 @@ output: type: file description: Sorted and duplicate marked CRAM index file pattern: "*.crai" - - metrics: - - meta: + ontologies: [] + metrics: + - - meta: type: map description: | Groovy Map containing sample information @@ -137,11 +152,28 @@ output: type: file description: Duplicate metrics file pattern: "*.metrics" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_samtools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - samtools: + type: string + description: The tool name + - "samtools version | sed '1!d;s/.* //'": + type: eval + description: The command used to generate the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - samtools: + type: string + description: The tool name + - "samtools version | sed '1!d;s/.* //'": + type: eval + description: The command used to generate the version of the tool authors: - "@matthdsm" maintainers: diff --git a/modules/nf-core/samtools/sormadup/samtools-sormadup.diff b/modules/nf-core/samtools/sormadup/samtools-sormadup.diff index 6da27c02..e5a640be 100644 --- a/modules/nf-core/samtools/sormadup/samtools-sormadup.diff +++ b/modules/nf-core/samtools/sormadup/samtools-sormadup.diff @@ -1,11 +1,11 @@ -Changes in module 'nf-core/samtools/sormadup' +Changes in component 'nf-core/samtools/sormadup' 'modules/nf-core/samtools/sormadup/environment.yml' is unchanged 'modules/nf-core/samtools/sormadup/meta.yml' is unchanged Changes in 'samtools/sormadup/main.nf': --- modules/nf-core/samtools/sormadup/main.nf +++ modules/nf-core/samtools/sormadup/main.nf @@ -8,8 +8,7 @@ - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: - tuple val(meta), path(input) @@ -14,10 +14,27 @@ Changes in 'samtools/sormadup/main.nf': output: tuple val(meta), path("*.bam") , emit: bam, optional: true +@@ -33,9 +32,6 @@ + args5.contains("--output-fmt cram") ? "cram" : + "bam" + def reference = fasta ? "--reference ${fasta}" : "" +- // memory per thread for samtools sort +- // set to 50% of the memory per thread, but at least 768M (samtools default) +- def sort_memory = Math.max(768,(task.memory.mega/task.cpus*0.50).intValue()) + + """ + samtools cat \\ +@@ -64,7 +60,6 @@ + -u \\ + -T ${prefix}.sort \\ + --threads $task.cpus \\ +- -m ${sort_memory}M \\ + - \\ + | \\ + samtools markdup \\ 'modules/nf-core/samtools/sormadup/tests/main.nf.test.snap' is unchanged 'modules/nf-core/samtools/sormadup/tests/bam.config' is unchanged -'modules/nf-core/samtools/sormadup/tests/tags.yml' is unchanged 'modules/nf-core/samtools/sormadup/tests/cram.config' is unchanged 'modules/nf-core/samtools/sormadup/tests/main.nf.test' is unchanged ************************************************************ diff --git a/modules/nf-core/samtools/sormadup/tests/cram.config b/modules/nf-core/samtools/sormadup/tests/cram.config index 8d6ce11a..69897ef7 100644 --- a/modules/nf-core/samtools/sormadup/tests/cram.config +++ b/modules/nf-core/samtools/sormadup/tests/cram.config @@ -7,7 +7,7 @@ process { "-d 2500", // The optical duplicate distance "--barcode-name", // Use the UMI/barcode embedded in the read name (eigth colon delimited part). "--write-index", // Write csi/crai index - "--output-fmt cram", // Output format + "--output-fmt cram,version=3.0",// Output format "--output-fmt-option archive" // Cram compression level ].join(" ").trim()} } diff --git a/modules/nf-core/samtools/sormadup/tests/main.nf.test b/modules/nf-core/samtools/sormadup/tests/main.nf.test index 574d70c6..f9bc34e5 100644 --- a/modules/nf-core/samtools/sormadup/tests/main.nf.test +++ b/modules/nf-core/samtools/sormadup/tests/main.nf.test @@ -13,22 +13,23 @@ nextflow_process { when { process { """ - input[0] = Channel.of([ - [id: 'test', single_end: false], // meta map + input[0] = [ + [id: 'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) - ]) - input[1] = Channel.of([ - [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ]) + ] + input[1] = [ + [ id:'fasta' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ] """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } @@ -42,23 +43,24 @@ nextflow_process { } process { """ - input[0] = Channel.of([ - [id: 'test', single_end: false], // meta map + input[0] = [ + [id: 'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) - ]) - input[1] = Channel.of([ - [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ]) + ] + input[1] = [ + [ id:'fasta' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ] """ } } then { + assert process.success def fasta = params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta' assertAll( - { assert process.success }, { assert snapshot( cram( @@ -67,6 +69,7 @@ nextflow_process { ).getReadsMD5(), file(process.out.crai[0][1]).name, process.out.metrics, + process.out.findAll { key, val -> key.startsWith("versions") } ).match() } ) @@ -81,22 +84,23 @@ nextflow_process { when { process { """ - input[0] = Channel.of([ - [id: 'test', single_end: false], // meta map + input[0] = [ + [id: 'test'], file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) - ]) - input[1] = Channel.of([ - [ id:'fasta' ], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) - ]) + ] + input[1] = [ + [ id:'fasta' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) + ] """ } } then { + assert process.success assertAll( - { assert process.success }, { assert snapshot(process.out).match() } ) } diff --git a/modules/nf-core/samtools/sormadup/tests/main.nf.test.snap b/modules/nf-core/samtools/sormadup/tests/main.nf.test.snap index 56776605..9d04d5d2 100644 --- a/modules/nf-core/samtools/sormadup/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/sormadup/tests/main.nf.test.snap @@ -5,8 +5,7 @@ "0": [ [ { - "id": "test", - "single_end": false + "id": "test" }, "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] @@ -23,20 +22,22 @@ "4": [ [ { - "id": "test", - "single_end": false + "id": "test" }, "test.metrics:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "5": [ - "versions.yml:md5,ad563b12da6299eec5c39564782d0814" + [ + "SAMTOOLS_SORMADUP", + "samtools", + "1.22.1" + ] ], "bam": [ [ { - "id": "test", - "single_end": false + "id": "test" }, "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] @@ -53,22 +54,25 @@ "metrics": [ [ { - "id": "test", - "single_end": false + "id": "test" }, "test.metrics:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,ad563b12da6299eec5c39564782d0814" + "versions_samtools": [ + [ + "SAMTOOLS_SORMADUP", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-09-16T08:56:24.200237922" + "timestamp": "2026-02-03T14:50:54.695296905" }, "sarscov2 - cram": { "content": [ @@ -77,18 +81,26 @@ [ [ { - "id": "test", - "single_end": false + "id": "test" }, - "test.merged.metrics:md5,548ff6d0d22ef710858639fe22e90004" + "test.merged.metrics:md5,02eebd31b097e165e1b18d84b023f18d" ] - ] + ], + { + "versions_samtools": [ + [ + "SAMTOOLS_SORMADUP", + "samtools", + "1.22.1" + ] + ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2025-02-05T12:24:12.517796" + "timestamp": "2026-02-04T09:59:00.393494" }, "sarscov2 - bam": { "content": [ @@ -96,10 +108,9 @@ "0": [ [ { - "id": "test", - "single_end": false + "id": "test" }, - "test.bam:md5,4dd85f1abbd2806887c6942f9c84595a" + "test.bam:md5,b191a8b4d5b8b9884def3a613fee914a" ] ], "1": [ @@ -114,22 +125,24 @@ "4": [ [ { - "id": "test", - "single_end": false + "id": "test" }, "test.metrics:md5,6093d8853805578a1868f22ff68177e7" ] ], "5": [ - "versions.yml:md5,ad563b12da6299eec5c39564782d0814" + [ + "SAMTOOLS_SORMADUP", + "samtools", + "1.22.1" + ] ], "bam": [ [ { - "id": "test", - "single_end": false + "id": "test" }, - "test.bam:md5,4dd85f1abbd2806887c6942f9c84595a" + "test.bam:md5,b191a8b4d5b8b9884def3a613fee914a" ] ], "crai": [ @@ -144,21 +157,24 @@ "metrics": [ [ { - "id": "test", - "single_end": false + "id": "test" }, "test.metrics:md5,6093d8853805578a1868f22ff68177e7" ] ], - "versions": [ - "versions.yml:md5,ad563b12da6299eec5c39564782d0814" + "versions_samtools": [ + [ + "SAMTOOLS_SORMADUP", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2025-02-05T11:48:51.866973" + "timestamp": "2026-02-04T10:01:06.229966" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/sormadup/tests/tags.yml b/modules/nf-core/samtools/sormadup/tests/tags.yml deleted file mode 100644 index cf362be7..00000000 --- a/modules/nf-core/samtools/sormadup/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -samtools/sormadup: - - "modules/nf-core/samtools/sormadup/**" diff --git a/modules/nf-core/samtools/sort/environment.yml b/modules/nf-core/samtools/sort/environment.yml index 62054fc9..89e12a64 100644 --- a/modules/nf-core/samtools/sort/environment.yml +++ b/modules/nf-core/samtools/sort/environment.yml @@ -4,5 +4,7 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.21 - - bioconda::samtools=1.21 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.22.1 diff --git a/modules/nf-core/samtools/sort/main.nf b/modules/nf-core/samtools/sort/main.nf index 53bb171a..4abb5f3c 100644 --- a/modules/nf-core/samtools/sort/main.nf +++ b/modules/nf-core/samtools/sort/main.nf @@ -4,30 +4,41 @@ process SAMTOOLS_SORT { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.22.1--h96c455f_0' : + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: tuple val(meta) , path(bam), path(fasta) + val index_format output: - tuple val(meta), path("*.bam"), emit: bam, optional: true - tuple val(meta), path("*.cram"), emit: cram, optional: true - tuple val(meta), path("*.crai"), emit: crai, optional: true - tuple val(meta), path("*.csi"), emit: csi, optional: true - path "versions.yml", emit: versions + tuple val(meta), path("${prefix}.bam"), emit: bam, optional: true + tuple val(meta), path("${prefix}.cram"), emit: cram, optional: true + tuple val(meta), path("${prefix}.sam"), emit: sam, optional: true + tuple val(meta), path("${prefix}.${extension}.crai"), emit: crai, optional: true + tuple val(meta), path("${prefix}.${extension}.csi"), emit: csi, optional: true + tuple val(meta), path("${prefix}.${extension}.bai"), emit: bai, optional: true + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), topic: versions, emit: versions_samtools when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def extension = args.contains("--output-fmt sam") ? "sam" : - args.contains("--output-fmt cram") ? "cram" : - "bam" + prefix = task.ext.prefix ?: "${meta.id}" + extension = args.contains("--output-fmt sam") ? "sam" : + args.contains("--output-fmt cram") ? "cram" : + "bam" def reference = fasta ? "--reference ${fasta}" : "" def sort_memory = (task.memory.mega/task.cpus*0.75).intValue() + output_file = index_format ? "${prefix}.${extension}##idx##${prefix}.${extension}.${index_format} --write-index" : "${prefix}.${extension}" + if (index_format) { + if (!index_format.matches('bai|csi|crai')) { + error "Index format not one of bai, csi, crai." + } else if (extension == "sam") { + error "Indexing not compatible with SAM output" + } + } if ("$bam" == "${prefix}.bam") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" """ @@ -40,34 +51,29 @@ process SAMTOOLS_SORT { --threads $task.cpus \\ ${reference} \\ -m ${sort_memory}M \\ - -o ${prefix}.${extension} \\ + -o ${output_file} \\ - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ stub: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def extension = args.contains("--output-fmt sam") ? "sam" : - args.contains("--output-fmt cram") ? "cram" : - "bam" + prefix = task.ext.prefix ?: "${meta.id}" + extension = args.contains("--output-fmt sam") ? "sam" : + args.contains("--output-fmt cram") ? "cram" : + "bam" + if (index_format) { + if (!index_format.matches('bai|csi|crai')) { + error "Index format not one of bai, csi, crai." + } else if (extension == "sam") { + error "Indexing not compatible with SAM output" + } + } + index = index_format ? "touch ${prefix}.${extension}.${index_format}" : "" + """ touch ${prefix}.${extension} - if [ "${extension}" == "bam" ]; - then - touch ${prefix}.${extension}.csi - elif [ "${extension}" == "cram" ]; - then - touch ${prefix}.${extension}.crai - fi + ${index} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/samtools/sort/meta.yml b/modules/nf-core/samtools/sort/meta.yml index a9dbec5a..69968304 100644 --- a/modules/nf-core/samtools/sort/meta.yml +++ b/modules/nf-core/samtools/sort/meta.yml @@ -26,6 +26,7 @@ input: type: file description: BAM/CRAM/SAM file(s) pattern: "*.{bam,cram,sam}" + ontologies: [] - - meta2: type: map description: | @@ -36,52 +37,101 @@ input: description: Reference genome FASTA file pattern: "*.{fa,fasta,fna}" optional: true + ontologies: [] + - index_format: + type: string + description: Index format to use (optional) + pattern: "bai|csi|crai" output: - - bam: - - meta: + bam: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.bam": + - "${prefix}.bam": type: file description: Sorted BAM file pattern: "*.{bam}" - - cram: - - meta: + ontologies: [] + cram: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.cram": + - "${prefix}.cram": type: file description: Sorted CRAM file pattern: "*.{cram}" - - crai: - - meta: + ontologies: [] + sam: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.crai": + - "${prefix}.sam": + type: file + description: Sorted SAM file + pattern: "*.{sam}" + ontologies: [] + crai: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "${prefix}.${extension}.crai": type: file description: CRAM index file (optional) pattern: "*.crai" - - csi: - - meta: + ontologies: [] + csi: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - "*.csi": + - "${prefix}.${extension}.csi": type: file description: BAM index file (optional) pattern: "*.csi" - - versions: - - versions.yml: + ontologies: [] + bai: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "${prefix}.${extension}.bai": type: file - description: File containing software versions - pattern: "versions.yml" + description: BAM index file (optional) + pattern: "*.bai" + ontologies: [] + versions_samtools: + - - ${task.process}: + type: string + description: The process the versions were collected from + - samtools: + type: string + description: The tool name + - "samtools version | sed '1!d;s/.* //'": + type: string + description: The command used to generate the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: The process the versions were collected from + - samtools: + type: string + description: The tool name + - "samtools version | sed '1!d;s/.* //'": + type: string + description: The command used to generate the version of the tool + authors: - "@drpatelh" - "@ewels" diff --git a/modules/nf-core/samtools/sort/samtools-sort.diff b/modules/nf-core/samtools/sort/samtools-sort.diff index 817f68c5..a7a10b78 100644 --- a/modules/nf-core/samtools/sort/samtools-sort.diff +++ b/modules/nf-core/samtools/sort/samtools-sort.diff @@ -1,39 +1,37 @@ -Changes in module 'nf-core/samtools/sort' +Changes in component 'nf-core/samtools/sort' 'modules/nf-core/samtools/sort/environment.yml' is unchanged 'modules/nf-core/samtools/sort/meta.yml' is unchanged Changes in 'samtools/sort/main.nf': --- modules/nf-core/samtools/sort/main.nf +++ modules/nf-core/samtools/sort/main.nf @@ -8,8 +8,7 @@ - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: - tuple val(meta) , path(bam) - tuple val(meta2), path(fasta) + tuple val(meta) , path(bam), path(fasta) + val index_format output: - tuple val(meta), path("*.bam"), emit: bam, optional: true - -@@ -28,6 +27,7 @@ - args.contains("--output-fmt cram") ? "cram" : - "bam" +@@ -31,6 +30,7 @@ + args.contains("--output-fmt cram") ? "cram" : + "bam" def reference = fasta ? "--reference ${fasta}" : "" + def sort_memory = (task.memory.mega/task.cpus*0.75).intValue() - if ("$bam" == "${prefix}.bam") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" - - """ -@@ -39,6 +39,7 @@ + output_file = index_format ? "${prefix}.${extension}##idx##${prefix}.${extension}.${index_format} --write-index" : "${prefix}.${extension}" + if (index_format) { + if (!index_format.matches('bai|csi|crai')) { +@@ -50,6 +50,7 @@ -T ${prefix} \\ --threads $task.cpus \\ ${reference} \\ + -m ${sort_memory}M \\ - -o ${prefix}.${extension} \\ + -o ${output_file} \\ - 'modules/nf-core/samtools/sort/tests/main.nf.test.snap' is unchanged -'modules/nf-core/samtools/sort/tests/tags.yml' is unchanged 'modules/nf-core/samtools/sort/tests/nextflow_cram.config' is unchanged 'modules/nf-core/samtools/sort/tests/nextflow.config' is unchanged 'modules/nf-core/samtools/sort/tests/main.nf.test' is unchanged diff --git a/modules/nf-core/samtools/sort/tests/main.nf.test b/modules/nf-core/samtools/sort/tests/main.nf.test index b05e6691..df47bb25 100644 --- a/modules/nf-core/samtools/sort/tests/main.nf.test +++ b/modules/nf-core/samtools/sort/tests/main.nf.test @@ -8,7 +8,7 @@ nextflow_process { tag "samtools" tag "samtools/sort" - test("bam") { + test("bam_no_index") { config "./nextflow.config" @@ -23,6 +23,7 @@ nextflow_process { [ id:'fasta' ], // meta map file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ]) + input[2] = '' """ } } @@ -32,8 +33,72 @@ nextflow_process { { assert process.success }, { assert snapshot( process.out.bam, - process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.bai, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} + ) + } + } + + test("bam_bai_index") { + + config "./nextflow.config" + + 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.bam', checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'fasta' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + input[2] = 'bai' + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + process.out.bam, + process.out.bai, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} + ) + } + } + + test("bam_csi_index") { + + config "./nextflow.config" + + 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.bam', checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'fasta' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + input[2] = 'csi' + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + process.out.bam, + process.out.csi, + process.out.findAll { key, val -> key.startsWith("versions") } ).match()} ) } @@ -57,6 +122,77 @@ nextflow_process { [ id:'fasta' ], // meta map file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ]) + input[2] = '' + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + process.out.bam, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} + ) + } + } + + test("multiple bam bai index") { + + config "./nextflow.config" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.sorted.bam', checkIfExists: true) + ] + ]) + input[1] = Channel.of([ + [ id:'fasta' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ]) + input[2] = 'bai' + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + process.out.bam, + process.out.bai.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match()} + ) + } + } + + test("multiple bam csi index") { + + config "./nextflow.config" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.sorted.bam', checkIfExists: true) + ] + ]) + input[1] = Channel.of([ + [ id:'fasta' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ]) + input[2] = 'csi' """ } } @@ -67,7 +203,7 @@ nextflow_process { { assert snapshot( process.out.bam, process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match()} ) } @@ -88,6 +224,7 @@ nextflow_process { [ id:'fasta' ], // meta map file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ]) + input[2] = '' """ } } @@ -98,7 +235,7 @@ nextflow_process { { assert snapshot( process.out.cram.collect { it.collect { it instanceof Map ? it : file(it).name } }, process.out.crai.collect { it.collect { it instanceof Map ? it : file(it).name } }, - process.out.versions + process.out.findAll { key, val -> key.startsWith("versions") } ).match()} ) } @@ -120,6 +257,7 @@ nextflow_process { [ id:'fasta' ], // meta map file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ]) + input[2] = '' """ } } @@ -127,7 +265,7 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out.findAll { key, val -> key.startsWith("versions") }).match() } ) } } @@ -150,6 +288,7 @@ nextflow_process { [ id:'fasta' ], // meta map file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ]) + input[2] = '' """ } } @@ -157,7 +296,7 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out.findAll { key, val -> key.startsWith("versions") }).match() } ) } } @@ -178,6 +317,7 @@ nextflow_process { [ id:'fasta' ], // meta map file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ]) + input[2] = '' """ } } @@ -185,7 +325,7 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot(process.out.findAll { key, val -> key.startsWith("versions") }).match() } ) } } diff --git a/modules/nf-core/samtools/sort/tests/main.nf.test.snap b/modules/nf-core/samtools/sort/tests/main.nf.test.snap index 469891fe..4e618fa3 100644 --- a/modules/nf-core/samtools/sort/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/sort/tests/main.nf.test.snap @@ -19,147 +19,77 @@ "test.sorted.cram.crai" ] ], - [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" - ] + { + "versions_samtools": [ + [ + "SAMTOOLS_SORT", + "samtools", + "1.22.1" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-09-16T08:49:58.207549273" + "timestamp": "2025-10-29T12:47:01.171084" }, - "bam - stub": { + "bam_csi_index": { "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,72ca1dff5344a5e5e6b892fe5f6b134d" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.csi:md5,01394e702c729cb478df914ffaf9f7f8" + ] + ], { - "0": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "SAMTOOLS_SORT", + "samtools", + "1.22.1" ] - ], - "1": [ - - ], - "2": [ - - ], - "3": [ - [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "4": [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" - ], - "bam": [ - [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "crai": [ - - ], - "cram": [ - - ], - "csi": [ - [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "versions": [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-09-16T08:50:08.630951018" + "timestamp": "2025-10-29T12:46:00.961675" }, - "cram - stub": { + "bam - stub": { "content": [ { - "0": [ - - ], - "1": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.sorted.cram:md5,d41d8cd98f00b204e9800998ecf8427e" + "SAMTOOLS_SORT", + "samtools", + "1.22.1" ] - ], - "2": [ - [ - { - "id": "test", - "single_end": false - }, - "test.sorted.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "3": [ - - ], - "4": [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" - ], - "bam": [ - - ], - "crai": [ - [ - { - "id": "test", - "single_end": false - }, - "test.sorted.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "cram": [ - [ - { - "id": "test", - "single_end": false - }, - "test.sorted.cram:md5,d41d8cd98f00b204e9800998ecf8427e" - ] - ], - "csi": [ - - ], - "versions": [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-09-16T08:50:19.061912443" + "timestamp": "2025-10-29T12:47:12.154354" }, - "multiple bam": { + "multiple bam bai index": { "content": [ [ [ @@ -167,7 +97,7 @@ "id": "test", "single_end": false }, - "test.sorted.bam:md5,8a16ba90c7d294cbb4c33ac0f7127a12" + "test.sorted.bam:md5,3ffa2affc29f0aa6e7b36dded84625fe" ] ], [ @@ -176,85 +106,122 @@ "id": "test", "single_end": false }, - "test.sorted.bam.csi" + "test.sorted.bam.bai" ] ], - [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" - ] + { + "versions_samtools": [ + [ + "SAMTOOLS_SORT", + "samtools", + "1.22.1" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.09.0" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-10-08T11:59:55.479443" + "timestamp": "2025-10-29T12:46:25.488622" }, - "multiple bam - stub": { + "cram - stub": { "content": [ { - "0": [ + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam:md5,8a16ba90c7d294cbb4c33ac0f7127a12" + "SAMTOOLS_SORT", + "samtools", + "1.22.1" ] - ], - "1": [ - - ], - "2": [ - - ], - "3": [ + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-10-29T12:47:28.485045" + }, + "multiple bam": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,cd4eb0077f25e9cff395366b8883dd1f" + ] + ], + [ + + ], + { + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam.csi:md5,d185916eaff9afeb4d0aeab3310371f9" + "SAMTOOLS_SORT", + "samtools", + "1.22.1" ] - ], - "4": [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" - ], - "bam": [ + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-10-29T12:46:13.168476" + }, + "multiple bam - stub": { + "content": [ + { + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam:md5,8a16ba90c7d294cbb4c33ac0f7127a12" + "SAMTOOLS_SORT", + "samtools", + "1.22.1" ] - ], - "crai": [ - - ], - "cram": [ - - ], - "csi": [ + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-10-29T12:47:21.628088" + }, + "bam_no_index": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,26b27d1f9bcb61c25da21b562349784e" + ] + ], + [ + + ], + { + "versions_samtools": [ [ - { - "id": "test", - "single_end": false - }, - "test.sorted.bam.csi:md5,d185916eaff9afeb4d0aeab3310371f9" + "SAMTOOLS_SORT", + "samtools", + "1.22.1" ] - ], - "versions": [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.09.0" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-10-08T11:36:13.781404" + "timestamp": "2025-10-29T12:45:47.139418" }, - "bam": { + "multiple bam csi index": { "content": [ [ [ @@ -262,7 +229,7 @@ "id": "test", "single_end": false }, - "test.sorted.bam:md5,34aa85e86abefe637f7a4a9887f016fc" + "test.sorted.bam:md5,295503ba5342531a3310c33ad0efbc22" ] ], [ @@ -274,14 +241,56 @@ "test.sorted.bam.csi" ] ], + { + "versions_samtools": [ + [ + "SAMTOOLS_SORT", + "samtools", + "1.22.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-10-29T12:46:51.5531" + }, + "bam_bai_index": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,cae7564cb83bb4a5911205bf94124b54" + ] + ], [ - "versions.yml:md5,2659b187d681241451539d4c53500b9f" - ] + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.bai:md5,50dd467c169545a4d5d1f709f7e986e0" + ] + ], + { + "versions_samtools": [ + [ + "SAMTOOLS_SORT", + "samtools", + "1.22.1" + ] + ] + } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.09.0" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-10-08T11:59:46.372244" + "timestamp": "2025-10-29T12:45:52.796936" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/sort/tests/nextflow.config b/modules/nf-core/samtools/sort/tests/nextflow.config index f642771f..723f62b2 100644 --- a/modules/nf-core/samtools/sort/tests/nextflow.config +++ b/modules/nf-core/samtools/sort/tests/nextflow.config @@ -2,7 +2,6 @@ process { withName: SAMTOOLS_SORT { ext.prefix = { "${meta.id}.sorted" } - ext.args = "--write-index" } } diff --git a/modules/nf-core/samtools/sort/tests/tags.yml b/modules/nf-core/samtools/sort/tests/tags.yml deleted file mode 100644 index cd63ea20..00000000 --- a/modules/nf-core/samtools/sort/tests/tags.yml +++ /dev/null @@ -1,3 +0,0 @@ -samtools/sort: - - modules/nf-core/samtools/sort/** - - tests/modules/nf-core/samtools/sort/** diff --git a/modules/nf-core/samtools/stats/environment.yml b/modules/nf-core/samtools/stats/environment.yml index 62054fc9..89e12a64 100644 --- a/modules/nf-core/samtools/stats/environment.yml +++ b/modules/nf-core/samtools/stats/environment.yml @@ -4,5 +4,7 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::htslib=1.21 - - bioconda::samtools=1.21 + # renovate: datasource=conda depName=bioconda/htslib + - bioconda::htslib=1.22.1 + # renovate: datasource=conda depName=bioconda/samtools + - bioconda::samtools=1.22.1 diff --git a/modules/nf-core/samtools/stats/main.nf b/modules/nf-core/samtools/stats/main.nf index 1e32e8a0..f9032148 100644 --- a/modules/nf-core/samtools/stats/main.nf +++ b/modules/nf-core/samtools/stats/main.nf @@ -4,44 +4,36 @@ process SAMTOOLS_STATS { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.22.1--h96c455f_0' : + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: tuple val(meta), path(input), path(input_index), path(fasta) output: tuple val(meta), path("*.stats"), emit: stats - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('samtools'), eval('samtools version | sed "1!d;s/.* //"'), emit: versions_samtools, topic: versions when: task.ext.when == null || task.ext.when script: - def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" def reference = fasta ? "--reference ${fasta}" : "" """ samtools \\ stats \\ + ${args} \\ --threads ${task.cpus} \\ ${reference} \\ ${input} \\ > ${prefix}.stats - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ stub: def prefix = task.ext.prefix ?: "${meta.id}" """ touch ${prefix}.stats - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/samtools/stats/meta.yml b/modules/nf-core/samtools/stats/meta.yml index 77b020f7..5c59cce4 100644 --- a/modules/nf-core/samtools/stats/meta.yml +++ b/modules/nf-core/samtools/stats/meta.yml @@ -27,10 +27,12 @@ input: type: file description: BAM/CRAM file from alignment pattern: "*.{bam,cram}" + ontologies: [] - input_index: type: file description: BAI/CRAI file from alignment pattern: "*.{bai,crai}" + ontologies: [] - - meta2: type: map description: | @@ -40,9 +42,10 @@ input: type: file description: Reference file the CRAM was created with (optional) pattern: "*.{fasta,fa}" + ontologies: [] output: - - stats: - - meta: + stats: + - - meta: type: map description: | Groovy Map containing sample information @@ -51,11 +54,30 @@ output: type: file description: File containing samtools stats output pattern: "*.{stats}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: [] + versions_samtools: + - - ${task.process}: + type: string + description: Name of the process + - samtools: + type: string + description: Name of the tool + - samtools version | sed "1!d;s/.* //": + type: eval + description: The expression to obtain the version of the tool + +topics: + versions: + - - ${task.process}: + type: string + description: Name of the process + - samtools: + type: string + description: Name of the tool + - samtools version | sed "1!d;s/.* //": + type: eval + description: The expression to obtain the version of the tool + authors: - "@drpatelh" - "@FriederikeHanssen" diff --git a/modules/nf-core/samtools/stats/samtools-stats.diff b/modules/nf-core/samtools/stats/samtools-stats.diff index dc243ad7..1ccaf8fe 100644 --- a/modules/nf-core/samtools/stats/samtools-stats.diff +++ b/modules/nf-core/samtools/stats/samtools-stats.diff @@ -1,11 +1,11 @@ -Changes in module 'nf-core/samtools/stats' +Changes in component 'nf-core/samtools/stats' 'modules/nf-core/samtools/stats/environment.yml' is unchanged 'modules/nf-core/samtools/stats/meta.yml' is unchanged Changes in 'samtools/stats/main.nf': --- modules/nf-core/samtools/stats/main.nf +++ modules/nf-core/samtools/stats/main.nf @@ -8,8 +8,7 @@ - 'biocontainers/samtools:1.21--h50ea8bc_0' }" + 'biocontainers/samtools:1.22.1--h96c455f_0' }" input: - tuple val(meta), path(input), path(input_index) @@ -16,6 +16,5 @@ Changes in 'samtools/stats/main.nf': tuple val(meta), path("*.stats"), emit: stats 'modules/nf-core/samtools/stats/tests/main.nf.test.snap' is unchanged -'modules/nf-core/samtools/stats/tests/tags.yml' is unchanged 'modules/nf-core/samtools/stats/tests/main.nf.test' is unchanged ************************************************************ diff --git a/modules/nf-core/samtools/stats/tests/main.nf.test.snap b/modules/nf-core/samtools/stats/tests/main.nf.test.snap index df507be7..94d981b2 100644 --- a/modules/nf-core/samtools/stats/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/stats/tests/main.nf.test.snap @@ -8,11 +8,15 @@ "id": "test", "single_end": false }, - "test.stats:md5,a27fe55e49a341f92379bb20a65c6a06" + "test.stats:md5,f4aec6c41b73d34ac2fc6b3253aa39ba" ] ], "1": [ - "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + [ + "SAMTOOLS_STATS", + "samtools", + "1.22.1" + ] ], "stats": [ [ @@ -20,19 +24,23 @@ "id": "test", "single_end": false }, - "test.stats:md5,a27fe55e49a341f92379bb20a65c6a06" + "test.stats:md5,f4aec6c41b73d34ac2fc6b3253aa39ba" ] ], - "versions": [ - "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + "versions_samtools": [ + [ + "SAMTOOLS_STATS", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-09-16T09:29:16.767396182" + "timestamp": "2025-11-01T02:27:18.460724" }, "bam - stub": { "content": [ @@ -47,7 +55,11 @@ ] ], "1": [ - "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + [ + "SAMTOOLS_STATS", + "samtools", + "1.22.1" + ] ], "stats": [ [ @@ -58,16 +70,20 @@ "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + "versions_samtools": [ + [ + "SAMTOOLS_STATS", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-09-16T09:29:29.721580274" + "timestamp": "2025-11-01T02:27:30.245839" }, "cram - stub": { "content": [ @@ -82,7 +98,11 @@ ] ], "1": [ - "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + [ + "SAMTOOLS_STATS", + "samtools", + "1.22.1" + ] ], "stats": [ [ @@ -93,16 +113,20 @@ "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + "versions_samtools": [ + [ + "SAMTOOLS_STATS", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-09-16T09:29:53.567964304" + "timestamp": "2025-11-01T02:27:39.041649" }, "bam": { "content": [ @@ -113,11 +137,15 @@ "id": "test", "single_end": false }, - "test.stats:md5,d53a2584376d78942839e9933a34d11b" + "test.stats:md5,41ba8ad30ddb598dadb177a54c222ab9" ] ], "1": [ - "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + [ + "SAMTOOLS_STATS", + "samtools", + "1.22.1" + ] ], "stats": [ [ @@ -125,18 +153,22 @@ "id": "test", "single_end": false }, - "test.stats:md5,d53a2584376d78942839e9933a34d11b" + "test.stats:md5,41ba8ad30ddb598dadb177a54c222ab9" ] ], - "versions": [ - "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + "versions_samtools": [ + [ + "SAMTOOLS_STATS", + "samtools", + "1.22.1" + ] ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.9.3", + "nextflow": "25.10.0" }, - "timestamp": "2024-09-16T09:28:50.73610604" + "timestamp": "2025-11-01T02:26:55.988241" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/stats/tests/tags.yml b/modules/nf-core/samtools/stats/tests/tags.yml deleted file mode 100644 index 7c28e30f..00000000 --- a/modules/nf-core/samtools/stats/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -samtools/stats: - - modules/nf-core/samtools/stats/** diff --git a/modules/nf-core/snapaligner/align/environment.yml b/modules/nf-core/snapaligner/align/environment.yml index c2bd7a6a..5dc75127 100644 --- a/modules/nf-core/snapaligner/align/environment.yml +++ b/modules/nf-core/snapaligner/align/environment.yml @@ -4,4 +4,5 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::snap-aligner=2.0.3 + # renovate: datasource=conda depName=bioconda/snap-aligner + - bioconda::snap-aligner=2.0.5 diff --git a/modules/nf-core/snapaligner/align/main.nf b/modules/nf-core/snapaligner/align/main.nf index 5cf6d6bc..177d5b82 100644 --- a/modules/nf-core/snapaligner/align/main.nf +++ b/modules/nf-core/snapaligner/align/main.nf @@ -4,8 +4,8 @@ process SNAPALIGNER_ALIGN { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/snap-aligner:2.0.3--hd03093a_0': - 'biocontainers/snap-aligner:2.0.3--hd03093a_0' }" + 'https://depot.galaxyproject.org/singularity/snap-aligner:2.0.5--h077b44d_2': + 'biocontainers/snap-aligner:2.0.5--h077b44d_2' }" input: tuple val(meta) , path(reads, stageAs: "?/*"), path(index) @@ -13,7 +13,7 @@ process SNAPALIGNER_ALIGN { output: tuple val(meta), path("*.bam"), emit: bam tuple val(meta), path("*.bai"), optional: true, emit: bai - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('snap-aligner'), eval("snap-aligner 2>&1 | sed 's/^.*version //;s/.\$//;q'"), topic: versions, emit: versions_snapaligner when: task.ext.when == null || task.ext.when @@ -33,21 +33,11 @@ process SNAPALIGNER_ALIGN { -o ${prefix}.bam \\ -t ${task.cpus} \\ $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - snapaligner: \$(snap-aligner 2>&1| head -n 1 | sed 's/^.*version //;s/.\$//') - END_VERSIONS """ stub: """ touch test.bam touch test.bam.bai - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - snapaligner: \$(snap-aligner 2>&1| head -n 1 | sed 's/^.*version //;s/.\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/snapaligner/align/meta.yml b/modules/nf-core/snapaligner/align/meta.yml index e0a71c04..c7aab28d 100644 --- a/modules/nf-core/snapaligner/align/meta.yml +++ b/modules/nf-core/snapaligner/align/meta.yml @@ -14,7 +14,8 @@ tools: documentation: "https://1drv.ms/b/s!AhuEg_0yZD86hcpblUt-muHKYsG8fA?e=R8ogug" tool_dev_url: "https://github.com/amplab/snap" doi: "10.1101/2021.11.23.469039" - licence: ["Apache v2"] + licence: + - "Apache v2" identifier: "" input: - - meta: @@ -24,9 +25,11 @@ input: e.g. [ id:'test', single_end:false ] - reads: type: file - description: List of input fastq files of size 2 for paired fastq or 1 for bam - or single fastq + description: List of input fastq files of size 2 for paired fastq or 1 for + bam or single fastq pattern: "*.{fastq.gz,fq.gz,fastq,fq,bam}" + ontologies: + - edam: http://edamontology.org/format_1930 - - meta2: type: map description: | @@ -36,9 +39,10 @@ input: type: file description: List of SNAP genome index files pattern: "{Genome,GenomeIndex,GenomeIndexHash,OverflowTable}" + ontologies: [] output: - - bam: - - meta: + bam: + - - meta: type: map description: | Groovy Map containing sample information @@ -47,8 +51,10 @@ output: type: file description: Aligned BAM file pattern: "*.{bam}" - - bai: - - meta: + ontologies: + - edam: http://edamontology.org/format_2572 + bai: + - - meta: type: map description: | Groovy Map containing sample information @@ -57,11 +63,29 @@ output: type: file description: Optional aligned BAM file index pattern: "*.{bai}" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_2572 + versions_snapaligner: + - - ${task.process}: + type: string + description: The name of the process + - snap-aligner: + type: string + description: The name of the tool + - snap-aligner 2>&1 | sed 's/^.*version //;s/.\$//;q': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - snap-aligner: + type: string + description: The name of the tool + - snap-aligner 2>&1 | sed 's/^.*version //;s/.\$//;q': + type: eval + description: The expression to obtain the version of the tool authors: - "@matthdsm" maintainers: diff --git a/modules/nf-core/snapaligner/align/snapaligner-align.diff b/modules/nf-core/snapaligner/align/snapaligner-align.diff index f6f326aa..34d23cd4 100644 --- a/modules/nf-core/snapaligner/align/snapaligner-align.diff +++ b/modules/nf-core/snapaligner/align/snapaligner-align.diff @@ -5,7 +5,7 @@ Changes in 'snapaligner/align/main.nf': --- modules/nf-core/snapaligner/align/main.nf +++ modules/nf-core/snapaligner/align/main.nf @@ -8,8 +8,7 @@ - 'biocontainers/snap-aligner:2.0.3--hd03093a_0' }" + 'community.wave.seqera.io/library/snap-aligner:2.0.5--23601d3a3a2ae452' }" input: - tuple val(meta) , path(reads, stageAs: "?/*") diff --git a/modules/nf-core/snapaligner/align/tests/main.nf.test b/modules/nf-core/snapaligner/align/tests/main.nf.test index 43a6d935..254ea40d 100644 --- a/modules/nf-core/snapaligner/align/tests/main.nf.test +++ b/modules/nf-core/snapaligner/align/tests/main.nf.test @@ -112,7 +112,7 @@ nextflow_process { } } } - + when { params { module_args = "-so" @@ -136,4 +136,4 @@ nextflow_process { ) } } -} \ No newline at end of file +} diff --git a/modules/nf-core/snapaligner/align/tests/main.nf.test.snap b/modules/nf-core/snapaligner/align/tests/main.nf.test.snap index 9b03ecd9..f6107c9c 100644 --- a/modules/nf-core/snapaligner/align/tests/main.nf.test.snap +++ b/modules/nf-core/snapaligner/align/tests/main.nf.test.snap @@ -8,7 +8,7 @@ "id": "test", "single_end": true }, - "test.bam:md5,ca1c2472d7fd405edd7d8edebc7a2373" + "test.bam:md5,fc98a93036a3c5f7c674d470f7c5515a" ] ], "1": [ @@ -21,7 +21,11 @@ ] ], "2": [ - "versions.yml:md5,991ee6a1ff9cb59542426a1ecf063188" + [ + "SNAPALIGNER_ALIGN", + "snap-aligner", + "2.0.5" + ] ], "bai": [ [ @@ -38,19 +42,23 @@ "id": "test", "single_end": true }, - "test.bam:md5,ca1c2472d7fd405edd7d8edebc7a2373" + "test.bam:md5,fc98a93036a3c5f7c674d470f7c5515a" ] ], - "versions": [ - "versions.yml:md5,991ee6a1ff9cb59542426a1ecf063188" + "versions_snapaligner": [ + [ + "SNAPALIGNER_ALIGN", + "snap-aligner", + "2.0.5" + ] ] } ], + "timestamp": "2026-02-18T13:58:48.808573", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-26T14:27:48.935351249" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test_snapaligner_stub": { "content": [ @@ -74,7 +82,11 @@ ] ], "2": [ - "versions.yml:md5,991ee6a1ff9cb59542426a1ecf063188" + [ + "SNAPALIGNER_ALIGN", + "snap-aligner", + "2.0.5" + ] ], "bai": [ [ @@ -94,16 +106,20 @@ "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "versions": [ - "versions.yml:md5,991ee6a1ff9cb59542426a1ecf063188" + "versions_snapaligner": [ + [ + "SNAPALIGNER_ALIGN", + "snap-aligner", + "2.0.5" + ] ] } ], + "timestamp": "2026-02-18T13:59:04.153824", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-26T14:41:41.497793191" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test_snapaligner_paired": { "content": [ @@ -114,7 +130,7 @@ "id": "test", "single_end": false }, - "test.bam:md5,7fef4ace398a5e5060ae54d4466c1503" + "test.bam:md5,d4e6df5e063034da268fa4b97db369d3" ] ], "1": [ @@ -127,7 +143,11 @@ ] ], "2": [ - "versions.yml:md5,991ee6a1ff9cb59542426a1ecf063188" + [ + "SNAPALIGNER_ALIGN", + "snap-aligner", + "2.0.5" + ] ], "bai": [ [ @@ -144,18 +164,22 @@ "id": "test", "single_end": false }, - "test.bam:md5,7fef4ace398a5e5060ae54d4466c1503" + "test.bam:md5,d4e6df5e063034da268fa4b97db369d3" ] ], - "versions": [ - "versions.yml:md5,991ee6a1ff9cb59542426a1ecf063188" + "versions_snapaligner": [ + [ + "SNAPALIGNER_ALIGN", + "snap-aligner", + "2.0.5" + ] ] } ], + "timestamp": "2026-02-18T13:58:57.101052", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-26T14:27:59.945692303" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/modules/nf-core/star/align/environment.yml b/modules/nf-core/star/align/environment.yml index 9ed1940f..91e37ae1 100644 --- a/modules/nf-core/star/align/environment.yml +++ b/modules/nf-core/star/align/environment.yml @@ -1,3 +1,5 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda diff --git a/modules/nf-core/star/align/main.nf b/modules/nf-core/star/align/main.nf index d61ffdfa..653996ad 100644 --- a/modules/nf-core/star/align/main.nf +++ b/modules/nf-core/star/align/main.nf @@ -16,7 +16,9 @@ process STAR_ALIGN { tuple val(meta), path('*Log.final.out') , emit: log_final tuple val(meta), path('*Log.out') , emit: log_out tuple val(meta), path('*Log.progress.out'), emit: log_progress - path "versions.yml" , emit: versions + tuple val("${task.process}"), val('star'), eval('STAR --version | sed "s/STAR_//"'), emit: versions_star, topic: versions + tuple val("${task.process}"), val('samtools'), eval("samtools --version | sed -n '1s/samtools //p'"), emit: versions_samtools, topic: versions + tuple val("${task.process}"), val('gawk'), eval("gawk --version | sed -n '1s/GNU Awk \\([0-9.]*\\).*/\\1/p'"), emit: versions_gawk, topic: versions tuple val(meta), path('*d.out.bam') , optional:true, emit: bam tuple val(meta), path("${prefix}.sortedByCoord.out.bam") , optional:true, emit: bam_sorted @@ -40,8 +42,8 @@ process STAR_ALIGN { prefix = task.ext.prefix ?: "${meta.id}" def reads1 = [] def reads2 = [] - meta.single_end ? [reads].flatten().each{reads1 << it} : reads.eachWithIndex{ v, ix -> ( ix & 1 ? reads2 : reads1) << v } - def ignore_gtf = gtf ? "--sjdbGTFfile $gtf" : "" + meta.single_end ? [reads].flatten().each{ read -> reads1 << read} : reads.eachWithIndex{ v, ix -> ( ix & 1 ? reads2 : reads1) << v } + def ignore_gtf = gtf ? "--sjdbGTFfile $gtf" : '' def seq_platform_arg = seq_platform ? "'PL:$seq_platform'" : "" def seq_center_arg = seq_center ? "'CN:$seq_center'" : "" attrRG = args.contains("--outSAMattrRGline") ? "" : "--outSAMattrRGline 'ID:$prefix' $seq_center_arg 'SM:$prefix' $seq_platform_arg" @@ -68,13 +70,6 @@ process STAR_ALIGN { mv ${prefix}.Unmapped.out.mate2 ${prefix}.unmapped_2.fastq gzip ${prefix}.unmapped_2.fastq fi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - star: \$(STAR --version | sed -e "s/STAR_//g") - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - gawk: \$(echo \$(gawk --version 2>&1) | sed 's/^.*GNU Awk //; s/, .*\$//') - END_VERSIONS """ stub: @@ -97,12 +92,5 @@ process STAR_ALIGN { touch ${prefix}.out.sam touch ${prefix}.Signal.UniqueMultiple.str1.out.wig touch ${prefix}.Signal.UniqueMultiple.str1.out.bg - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - star: \$(STAR --version | sed -e "s/STAR_//g") - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - gawk: \$(echo \$(gawk --version 2>&1) | sed 's/^.*GNU Awk //; s/, .*\$//') - END_VERSIONS """ } diff --git a/modules/nf-core/star/align/meta.yml b/modules/nf-core/star/align/meta.yml index 5cfe763e..3df5cfe7 100644 --- a/modules/nf-core/star/align/meta.yml +++ b/modules/nf-core/star/align/meta.yml @@ -26,6 +26,7 @@ input: description: | List of input FastQ files of size 1 and 2 for single-end and paired-end data, respectively. + ontologies: [] - - meta2: type: map description: | @@ -44,18 +45,13 @@ input: type: file description: Annotation GTF file pattern: "*.{gtf}" - - - star_ignore_sjdbgtf: - type: boolean - description: Ignore annotation GTF file - - - seq_platform: - type: string - description: Sequencing platform - - - seq_center: - type: string - description: Sequencing center + ontologies: [] + - star_ignore_sjdbgtf: + type: boolean + description: Ignore annotation GTF file output: - - log_final: - - meta: + log_final: + - - meta: type: map description: | Groovy Map containing sample information @@ -64,8 +60,9 @@ output: type: file description: STAR final log file pattern: "*Log.final.out" - - log_out: - - meta: + ontologies: [] + log_out: + - - meta: type: map description: | Groovy Map containing sample information @@ -74,8 +71,9 @@ output: type: file description: STAR lot out file pattern: "*Log.out" - - log_progress: - - meta: + ontologies: [] + log_progress: + - - meta: type: map description: | Groovy Map containing sample information @@ -84,13 +82,40 @@ output: type: file description: STAR log progress file pattern: "*Log.progress.out" - - versions: - - versions.yml: - type: file - description: File containing software versions - pattern: "versions.yml" - - bam: - - meta: + ontologies: [] + versions_star: + - - ${task.process}: + type: string + description: The name of the process + - star: + type: string + description: The name of the tool + - STAR --version | sed "s/STAR_//": + type: eval + description: The expression to obtain the version of the tool + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools --version | sed -n '1s/samtools //p': + type: eval + description: The expression to obtain the version of the tool + versions_gawk: + - - ${task.process}: + type: string + description: The name of the process + - gawk: + type: string + description: The name of the tool + - gawk --version | sed -n '1s/GNU Awk \([0-9.]*\).*/\1/p': + type: eval + description: The expression to obtain the version of the tool + + bam: + - - meta: type: map description: | Groovy Map containing sample information @@ -99,8 +124,9 @@ output: type: file description: Output BAM file containing read alignments pattern: "*.{bam}" - - bam_sorted: - - meta: + ontologies: [] + bam_sorted: + - - meta: type: map description: | Groovy Map containing sample information @@ -109,8 +135,9 @@ output: type: file description: Sorted BAM file of read alignments (optional) pattern: "*sortedByCoord.out.bam" - - bam_sorted_aligned: - - meta: + ontologies: [] + bam_sorted_aligned: + - - meta: type: map description: | Groovy Map containing sample information @@ -119,8 +146,9 @@ output: type: file description: Sorted BAM file of read alignments (optional) pattern: "*.Aligned.sortedByCoord.out.bam" - - bam_transcript: - - meta: + ontologies: [] + bam_transcript: + - - meta: type: map description: | Groovy Map containing sample information @@ -129,8 +157,9 @@ output: type: file description: Output BAM file of transcriptome alignment (optional) pattern: "*toTranscriptome.out.bam" - - bam_unsorted: - - meta: + ontologies: [] + bam_unsorted: + - - meta: type: map description: | Groovy Map containing sample information @@ -139,8 +168,9 @@ output: type: file description: Unsorted BAM file of read alignments (optional) pattern: "*Aligned.unsort.out.bam" - - fastq: - - meta: + ontologies: [] + fastq: + - - meta: type: map description: | Groovy Map containing sample information @@ -149,8 +179,10 @@ output: type: file description: Unmapped FastQ files (optional) pattern: "*fastq.gz" - - tab: - - meta: + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + tab: + - - meta: type: map description: | Groovy Map containing sample information @@ -159,8 +191,10 @@ output: type: file description: STAR output tab file(s) (optional) pattern: "*.tab" - - spl_junc_tab: - - meta: + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + spl_junc_tab: + - - meta: type: map description: | Groovy Map containing sample information @@ -169,8 +203,10 @@ output: type: file description: STAR output splice junction tab file pattern: "*.SJ.out.tab" - - read_per_gene_tab: - - meta: + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + read_per_gene_tab: + - - meta: type: map description: | Groovy Map containing sample information @@ -179,8 +215,10 @@ output: type: file description: STAR output read per gene tab file pattern: "*.ReadsPerGene.out.tab" - - junction: - - meta: + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + junction: + - - meta: type: map description: | Groovy Map containing sample information @@ -189,19 +227,20 @@ output: type: file description: STAR chimeric junction output file (optional) pattern: "*.out.junction" - - sam: - - meta: + ontologies: [] + sam: + - - meta: type: map description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - pattern: "*.out.sam" - "*.out.sam": type: file description: STAR output SAM file(s) (optional) pattern: "*.out.sam" - - wig: - - meta: + ontologies: [] + wig: + - - meta: type: map description: | Groovy Map containing sample information @@ -210,8 +249,9 @@ output: type: file description: STAR output wiggle format file(s) (optional) pattern: "*.wig" - - bedgraph: - - meta: + ontologies: [] + bedgraph: + - - meta: type: map description: | Groovy Map containing sample information @@ -220,6 +260,37 @@ output: type: file description: STAR output bedGraph format file(s) (optional) pattern: "*.bg" + ontologies: [] +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - star: + type: string + description: The name of the tool + - STAR --version | sed "s/STAR_//": + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools --version | sed -n '1s/samtools //p': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - gawk: + type: string + description: The name of the tool + - gawk --version | sed -n '1s/GNU Awk \([0-9.]*\).*/\1/p': + type: eval + description: The expression to obtain the version of the tool + authors: - "@kevinmenden" - "@drpatelh" diff --git a/modules/nf-core/star/align/star-align.diff b/modules/nf-core/star/align/star-align.diff index 93befc80..07d96b66 100644 --- a/modules/nf-core/star/align/star-align.diff +++ b/modules/nf-core/star/align/star-align.diff @@ -1,8 +1,10 @@ Changes in component 'nf-core/star/align' +'modules/nf-core/star/align/environment.yml' is unchanged +'modules/nf-core/star/align/meta.yml' is unchanged Changes in 'star/align/main.nf': --- modules/nf-core/star/align/main.nf +++ modules/nf-core/star/align/main.nf -@@ -8,10 +8,7 @@ +@@ -8,10 +8,9 @@ 'community.wave.seqera.io/library/htslib_samtools_star_gawk:ae438e9a604351a4' }" input: @@ -11,25 +13,28 @@ Changes in 'star/align/main.nf': - tuple val(meta3), path(gtf) - val star_ignore_sjdbgtf + tuple val(meta), path(reads, stageAs: "input*/*"), path(index), path(gtf) - val seq_platform - val seq_center ++ val seq_platform ++ val seq_center -@@ -44,7 +41,7 @@ + output: + tuple val(meta), path('*Log.final.out') , emit: log_final +@@ -44,8 +43,10 @@ def reads1 = [] def reads2 = [] - meta.single_end ? [reads].flatten().each{reads1 << it} : reads.eachWithIndex{ v, ix -> ( ix & 1 ? reads2 : reads1) << v } + meta.single_end ? [reads].flatten().each{ read -> reads1 << read} : reads.eachWithIndex{ v, ix -> ( ix & 1 ? reads2 : reads1) << v } - def ignore_gtf = star_ignore_sjdbgtf ? '' : "--sjdbGTFfile $gtf" -+ def ignore_gtf = gtf ? "--sjdbGTFfile $gtf" : "" - def seq_platform_arg = seq_platform ? "'PL:$seq_platform'" : "" - def seq_center_arg = seq_center ? "'CN:$seq_center'" : "" - attrRG = args.contains("--outSAMattrRGline") ? "" : "--outSAMattrRGline 'ID:$prefix' $seq_center_arg 'SM:$prefix' $seq_platform_arg" +- attrRG = args.contains("--outSAMattrRGline") ? "" : "--outSAMattrRGline 'ID:$prefix' 'SM:$prefix'" ++ def ignore_gtf = gtf ? "--sjdbGTFfile $gtf" : '' ++ def seq_platform_arg = seq_platform ? "'PL:$seq_platform'" : "" ++ def seq_center_arg = seq_center ? "'CN:$seq_center'" : "" ++ attrRG = args.contains("--outSAMattrRGline") ? "" : "--outSAMattrRGline 'ID:$prefix' $seq_center_arg 'SM:$prefix' $seq_platform_arg" + def out_sam_type = (args.contains('--outSAMtype')) ? '' : '--outSAMtype BAM Unsorted' + mv_unsorted_bam = (args.contains('--outSAMtype BAM Unsorted SortedByCoordinate')) ? "mv ${prefix}.Aligned.out.bam ${prefix}.Aligned.unsort.out.bam" : '' + """ -'modules/nf-core/star/align/environment.yml' is unchanged -'modules/nf-core/star/align/meta.yml' is unchanged -'modules/nf-core/star/align/tests/tags.yml' is unchanged -'modules/nf-core/star/align/tests/nextflow.starfusion.config' is unchanged -'modules/nf-core/star/align/tests/main.nf.test' is unchanged -'modules/nf-core/star/align/tests/nextflow.arriba.config' is unchanged 'modules/nf-core/star/align/tests/main.nf.test.snap' is unchanged +'modules/nf-core/star/align/tests/nextflow.arriba.config' is unchanged +'modules/nf-core/star/align/tests/nextflow.starfusion.config' is unchanged 'modules/nf-core/star/align/tests/nextflow.config' is unchanged +'modules/nf-core/star/align/tests/main.nf.test' is unchanged ************************************************************ diff --git a/modules/nf-core/star/align/tests/main.nf.test b/modules/nf-core/star/align/tests/main.nf.test index a62c17db..d7c6ccbd 100644 --- a/modules/nf-core/star/align/tests/main.nf.test +++ b/modules/nf-core/star/align/tests/main.nf.test @@ -43,8 +43,6 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) input[3] = false - input[4] = 'illumina' - input[5] = false """ } } @@ -65,7 +63,7 @@ nextflow_process { process.out.spl_junc_tab, process.out.tab, process.out.wig, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } @@ -108,8 +106,6 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) input[3] = false - input[4] = 'illumina' - input[5] = false """ } } @@ -130,7 +126,7 @@ nextflow_process { process.out.spl_junc_tab, process.out.tab, process.out.wig, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } @@ -173,8 +169,6 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) input[3] = false - input[4] = 'illumina' - input[5] = false """ } } @@ -194,7 +188,7 @@ nextflow_process { process.out.spl_junc_tab, process.out.tab, process.out.wig, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } @@ -237,8 +231,6 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) input[3] = false - input[4] = 'illumina' - input[5] = false """ } } @@ -259,7 +251,7 @@ nextflow_process { process.out.spl_junc_tab, process.out.tab, process.out.wig, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } @@ -304,8 +296,6 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) input[3] = false - input[4] = 'illumina' - input[5] = false """ } } @@ -326,7 +316,7 @@ nextflow_process { process.out.spl_junc_tab, process.out.tab, process.out.wig, - process.out.versions + process.out.findAll { key, val -> key.startsWith('versions') } ).match() } ) } @@ -367,8 +357,6 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) input[3] = false - input[4] = 'illumina' - input[5] = false """ } } @@ -419,8 +407,6 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) input[3] = false - input[4] = 'illumina' - input[5] = false """ } } @@ -471,8 +457,6 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) input[3] = false - input[4] = 'illumina' - input[5] = false """ } } @@ -523,8 +507,6 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) input[3] = false - input[4] = 'illumina' - input[5] = false """ } } @@ -577,8 +559,6 @@ nextflow_process { [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) input[3] = false - input[4] = 'illumina' - input[5] = false """ } } diff --git a/modules/nf-core/star/align/tests/main.nf.test.snap b/modules/nf-core/star/align/tests/main.nf.test.snap index a1ec3a3d..2b5755db 100644 --- a/modules/nf-core/star/align/tests/main.nf.test.snap +++ b/modules/nf-core/star/align/tests/main.nf.test.snap @@ -21,6 +21,27 @@ ] ], "10": [ + [ + { + "id": "test", + "single_end": true + }, + "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": true + }, + [ + "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "12": [ [ { "id": "test", @@ -33,7 +54,7 @@ ] ] ], - "11": [ + "13": [ [ { "id": "test", @@ -42,7 +63,7 @@ "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "12": [ + "14": [ [ { "id": "test", @@ -51,7 +72,7 @@ "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "13": [ + "15": [ [ { "id": "test", @@ -60,7 +81,7 @@ "test.Chimeric.out.junction:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "14": [ + "16": [ [ { "id": "test", @@ -69,7 +90,7 @@ "test.out.sam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "15": [ + "17": [ [ { "id": "test", @@ -78,7 +99,7 @@ "test.Signal.UniqueMultiple.str1.out.wig:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "16": [ + "18": [ [ { "id": "test", @@ -97,28 +118,24 @@ ] ], "3": [ - "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + [ + "STAR_ALIGN", + "star", + "2.7.11b" + ] ], "4": [ [ - { - "id": "test", - "single_end": true - }, - [ - "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", - "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "STAR_ALIGN", + "samtools", + "1.21" ] ], "5": [ [ - { - "id": "test", - "single_end": true - }, - "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "STAR_ALIGN", + "gawk", + "5.1.0" ] ], "6": [ @@ -127,7 +144,11 @@ "id": "test", "single_end": true }, - "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + [ + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] ], "7": [ @@ -136,7 +157,7 @@ "id": "test", "single_end": true }, - "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "8": [ @@ -145,7 +166,7 @@ "id": "test", "single_end": true }, - "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "9": [ @@ -154,10 +175,7 @@ "id": "test", "single_end": true }, - [ - "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] + "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "bam": [ @@ -306,8 +324,26 @@ ] ] ], - "versions": [ - "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + "versions_gawk": [ + [ + "STAR_ALIGN", + "gawk", + "5.1.0" + ] + ], + "versions_samtools": [ + [ + "STAR_ALIGN", + "samtools", + "1.21" + ] + ], + "versions_star": [ + [ + "STAR_ALIGN", + "star", + "2.7.11b" + ] ], "wig": [ [ @@ -321,10 +357,10 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-12-11T16:28:39.242074494" + "timestamp": "2026-02-03T09:28:25.802437191" }, "homo_sapiens - paired_end - arriba - stub": { "content": [ @@ -348,6 +384,27 @@ ] ], "10": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "12": [ [ { "id": "test", @@ -360,7 +417,7 @@ ] ] ], - "11": [ + "13": [ [ { "id": "test", @@ -369,7 +426,7 @@ "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "12": [ + "14": [ [ { "id": "test", @@ -378,7 +435,7 @@ "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "13": [ + "15": [ [ { "id": "test", @@ -387,7 +444,7 @@ "test.Chimeric.out.junction:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "14": [ + "16": [ [ { "id": "test", @@ -396,7 +453,7 @@ "test.out.sam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "15": [ + "17": [ [ { "id": "test", @@ -405,7 +462,7 @@ "test.Signal.UniqueMultiple.str1.out.wig:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "16": [ + "18": [ [ { "id": "test", @@ -424,28 +481,24 @@ ] ], "3": [ - "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + [ + "STAR_ALIGN", + "star", + "2.7.11b" + ] ], "4": [ [ - { - "id": "test", - "single_end": false - }, - [ - "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", - "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "STAR_ALIGN", + "samtools", + "1.21" ] ], "5": [ [ - { - "id": "test", - "single_end": false - }, - "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "STAR_ALIGN", + "gawk", + "5.1.0" ] ], "6": [ @@ -454,7 +507,11 @@ "id": "test", "single_end": false }, - "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + [ + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] ], "7": [ @@ -463,7 +520,7 @@ "id": "test", "single_end": false }, - "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "8": [ @@ -472,7 +529,7 @@ "id": "test", "single_end": false }, - "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "9": [ @@ -481,10 +538,7 @@ "id": "test", "single_end": false }, - [ - "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] + "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "bam": [ @@ -633,8 +687,26 @@ ] ] ], - "versions": [ - "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + "versions_gawk": [ + [ + "STAR_ALIGN", + "gawk", + "5.1.0" + ] + ], + "versions_samtools": [ + [ + "STAR_ALIGN", + "samtools", + "1.21" + ] + ], + "versions_star": [ + [ + "STAR_ALIGN", + "star", + "2.7.11b" + ] ], "wig": [ [ @@ -648,10 +720,10 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-12-11T16:29:08.392620556" + "timestamp": "2026-02-03T09:28:38.483306917" }, "homo_sapiens - single_end": { "content": [ @@ -702,15 +774,35 @@ [ ], - [ - "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" - ] + { + "versions_gawk": [ + [ + "STAR_ALIGN", + "gawk", + "5.1.0" + ] + ], + "versions_samtools": [ + [ + "STAR_ALIGN", + "samtools", + "1.21" + ] + ], + "versions_star": [ + [ + "STAR_ALIGN", + "star", + "2.7.11b" + ] + ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-12-11T16:21:34.549483887" + "timestamp": "2026-02-02T23:44:45.378997" }, "homo_sapiens - paired_end": { "content": [ @@ -761,15 +853,35 @@ [ ], - [ - "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" - ] + { + "versions_gawk": [ + [ + "STAR_ALIGN", + "gawk", + "5.1.0" + ] + ], + "versions_samtools": [ + [ + "STAR_ALIGN", + "samtools", + "1.21" + ] + ], + "versions_star": [ + [ + "STAR_ALIGN", + "star", + "2.7.11b" + ] + ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.2" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2024-12-11T16:22:17.011253146" + "timestamp": "2026-02-02T23:50:50.657212" }, "homo_sapiens - paired_end - multiple - stub": { "content": [ @@ -793,6 +905,27 @@ ] ], "10": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "12": [ [ { "id": "test", @@ -805,7 +938,7 @@ ] ] ], - "11": [ + "13": [ [ { "id": "test", @@ -814,7 +947,7 @@ "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "12": [ + "14": [ [ { "id": "test", @@ -823,7 +956,7 @@ "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "13": [ + "15": [ [ { "id": "test", @@ -832,7 +965,7 @@ "test.Chimeric.out.junction:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "14": [ + "16": [ [ { "id": "test", @@ -841,7 +974,7 @@ "test.out.sam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "15": [ + "17": [ [ { "id": "test", @@ -850,7 +983,7 @@ "test.Signal.UniqueMultiple.str1.out.wig:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "16": [ + "18": [ [ { "id": "test", @@ -869,28 +1002,24 @@ ] ], "3": [ - "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + [ + "STAR_ALIGN", + "star", + "2.7.11b" + ] ], "4": [ [ - { - "id": "test", - "single_end": false - }, - [ - "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", - "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "STAR_ALIGN", + "samtools", + "1.21" ] ], "5": [ [ - { - "id": "test", - "single_end": false - }, - "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "STAR_ALIGN", + "gawk", + "5.1.0" ] ], "6": [ @@ -899,7 +1028,11 @@ "id": "test", "single_end": false }, - "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + [ + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] ], "7": [ @@ -908,7 +1041,7 @@ "id": "test", "single_end": false }, - "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "8": [ @@ -917,7 +1050,7 @@ "id": "test", "single_end": false }, - "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "9": [ @@ -926,10 +1059,7 @@ "id": "test", "single_end": false }, - [ - "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] + "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "bam": [ @@ -1078,8 +1208,26 @@ ] ] ], - "versions": [ - "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + "versions_gawk": [ + [ + "STAR_ALIGN", + "gawk", + "5.1.0" + ] + ], + "versions_samtools": [ + [ + "STAR_ALIGN", + "samtools", + "1.21" + ] + ], + "versions_star": [ + [ + "STAR_ALIGN", + "star", + "2.7.11b" + ] ], "wig": [ [ @@ -1093,10 +1241,10 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-12-11T16:29:31.072104862" + "timestamp": "2026-02-03T09:28:51.288466085" }, "homo_sapiens - paired_end - multiple": { "content": [ @@ -1147,15 +1295,35 @@ [ ], - [ - "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" - ] + { + "versions_gawk": [ + [ + "STAR_ALIGN", + "gawk", + "5.1.0" + ] + ], + "versions_samtools": [ + [ + "STAR_ALIGN", + "samtools", + "1.21" + ] + ], + "versions_star": [ + [ + "STAR_ALIGN", + "star", + "2.7.11b" + ] + ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-12-11T16:28:26.645008336" + "timestamp": "2026-02-03T09:28:19.516063466" }, "homo_sapiens - paired_end - stub": { "content": [ @@ -1179,6 +1347,27 @@ ] ], "10": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "12": [ [ { "id": "test", @@ -1191,7 +1380,7 @@ ] ] ], - "11": [ + "13": [ [ { "id": "test", @@ -1200,7 +1389,7 @@ "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "12": [ + "14": [ [ { "id": "test", @@ -1209,7 +1398,7 @@ "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "13": [ + "15": [ [ { "id": "test", @@ -1218,7 +1407,7 @@ "test.Chimeric.out.junction:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "14": [ + "16": [ [ { "id": "test", @@ -1227,7 +1416,7 @@ "test.out.sam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "15": [ + "17": [ [ { "id": "test", @@ -1236,7 +1425,7 @@ "test.Signal.UniqueMultiple.str1.out.wig:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "16": [ + "18": [ [ { "id": "test", @@ -1255,28 +1444,24 @@ ] ], "3": [ - "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + [ + "STAR_ALIGN", + "star", + "2.7.11b" + ] ], "4": [ [ - { - "id": "test", - "single_end": false - }, - [ - "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", - "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "STAR_ALIGN", + "samtools", + "1.21" ] ], "5": [ [ - { - "id": "test", - "single_end": false - }, - "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "STAR_ALIGN", + "gawk", + "5.1.0" ] ], "6": [ @@ -1285,7 +1470,11 @@ "id": "test", "single_end": false }, - "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + [ + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] ], "7": [ @@ -1294,7 +1483,7 @@ "id": "test", "single_end": false }, - "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "8": [ @@ -1303,7 +1492,7 @@ "id": "test", "single_end": false }, - "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "9": [ @@ -1312,10 +1501,7 @@ "id": "test", "single_end": false }, - [ - "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] + "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "bam": [ @@ -1464,8 +1650,26 @@ ] ] ], - "versions": [ - "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + "versions_gawk": [ + [ + "STAR_ALIGN", + "gawk", + "5.1.0" + ] + ], + "versions_samtools": [ + [ + "STAR_ALIGN", + "samtools", + "1.21" + ] + ], + "versions_star": [ + [ + "STAR_ALIGN", + "star", + "2.7.11b" + ] ], "wig": [ [ @@ -1479,10 +1683,10 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-12-11T16:28:53.816280805" + "timestamp": "2026-02-03T09:28:32.099657738" }, "homo_sapiens - paired_end - starfusion": { "content": [ @@ -1524,15 +1728,35 @@ [ ], - [ - "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" - ] + { + "versions_gawk": [ + [ + "STAR_ALIGN", + "gawk", + "5.1.0" + ] + ], + "versions_samtools": [ + [ + "STAR_ALIGN", + "samtools", + "1.21" + ] + ], + "versions_star": [ + [ + "STAR_ALIGN", + "star", + "2.7.11b" + ] + ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-12-11T16:27:14.136111964" + "timestamp": "2026-02-03T09:26:46.244829386" }, "homo_sapiens - paired_end - arriba": { "content": [ @@ -1573,15 +1797,35 @@ [ ], - [ - "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" - ] + { + "versions_gawk": [ + [ + "STAR_ALIGN", + "gawk", + "5.1.0" + ] + ], + "versions_samtools": [ + [ + "STAR_ALIGN", + "samtools", + "1.21" + ] + ], + "versions_star": [ + [ + "STAR_ALIGN", + "star", + "2.7.11b" + ] + ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-12-11T16:24:00.829462526" + "timestamp": "2026-02-03T09:22:41.580434639" }, "homo_sapiens - paired_end - starfusion - stub": { "content": [ @@ -1605,6 +1849,27 @@ ] ], "10": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "12": [ [ { "id": "test", @@ -1617,7 +1882,7 @@ ] ] ], - "11": [ + "13": [ [ { "id": "test", @@ -1626,7 +1891,7 @@ "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "12": [ + "14": [ [ { "id": "test", @@ -1635,7 +1900,7 @@ "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "13": [ + "15": [ [ { "id": "test", @@ -1644,7 +1909,7 @@ "test.Chimeric.out.junction:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "14": [ + "16": [ [ { "id": "test", @@ -1653,7 +1918,7 @@ "test.out.sam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "15": [ + "17": [ [ { "id": "test", @@ -1662,7 +1927,7 @@ "test.Signal.UniqueMultiple.str1.out.wig:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], - "16": [ + "18": [ [ { "id": "test", @@ -1681,28 +1946,24 @@ ] ], "3": [ - "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + [ + "STAR_ALIGN", + "star", + "2.7.11b" + ] ], "4": [ [ - { - "id": "test", - "single_end": false - }, - [ - "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", - "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" - ] + "STAR_ALIGN", + "samtools", + "1.21" ] ], "5": [ [ - { - "id": "test", - "single_end": false - }, - "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "STAR_ALIGN", + "gawk", + "5.1.0" ] ], "6": [ @@ -1711,7 +1972,11 @@ "id": "test", "single_end": false }, - "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + [ + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] ], "7": [ @@ -1720,7 +1985,7 @@ "id": "test", "single_end": false }, - "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "8": [ @@ -1729,7 +1994,7 @@ "id": "test", "single_end": false }, - "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "9": [ @@ -1738,10 +2003,7 @@ "id": "test", "single_end": false }, - [ - "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", - "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" - ] + "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "bam": [ @@ -1890,8 +2152,26 @@ ] ] ], - "versions": [ - "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + "versions_gawk": [ + [ + "STAR_ALIGN", + "gawk", + "5.1.0" + ] + ], + "versions_samtools": [ + [ + "STAR_ALIGN", + "samtools", + "1.21" + ] + ], + "versions_star": [ + [ + "STAR_ALIGN", + "star", + "2.7.11b" + ] ], "wig": [ [ @@ -1905,9 +2185,9 @@ } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.2" + "nf-test": "0.9.3", + "nextflow": "25.10.3" }, - "timestamp": "2024-12-11T16:29:20.015372487" + "timestamp": "2026-02-03T09:28:44.836246776" } } \ No newline at end of file diff --git a/modules/nf-core/star/align/tests/tags.yml b/modules/nf-core/star/align/tests/tags.yml deleted file mode 100644 index 8beace16..00000000 --- a/modules/nf-core/star/align/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -star/align: - - modules/nf-core/star/align/** diff --git a/modules/nf-core/strobealign/environment.yml b/modules/nf-core/strobealign/environment.yml new file mode 100644 index 00000000..fc1f89b8 --- /dev/null +++ b/modules/nf-core/strobealign/environment.yml @@ -0,0 +1,9 @@ +channels: + - conda-forge + - bioconda + +dependencies: + - bioconda::htslib=1.22.1 + - bioconda::samtools=1.22.1 + - bioconda::strobealign=0.16.1 + - conda-forge::pigz=2.8 diff --git a/modules/nf-core/strobealign/main.nf b/modules/nf-core/strobealign/main.nf new file mode 100644 index 00000000..aae11f08 --- /dev/null +++ b/modules/nf-core/strobealign/main.nf @@ -0,0 +1,96 @@ +process STROBEALIGN { + tag "${meta.id}" + label 'process_high' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/59/59cce6872df48a1e5cc9ccee89f066210694c6ec9f62d9c931cc6925ca0f6a5f/data' : + 'community.wave.seqera.io/library/htslib_samtools_strobealign_pigz:4fa4f439c6bea386' }" + + input: + tuple val(meta) , path(reads), path(fasta), path(index) + val sort_bam + + output: + tuple val(meta), path("*.bam") , emit: bam , optional: true + tuple val(meta), path("*.cram") , emit: cram, optional: true + tuple val(meta), path("*.csi") , emit: csi , optional: true + tuple val(meta), path("*.crai") , emit: crai, optional: true + tuple val(meta), path("*.paf.gz") , emit: paf , optional: true + tuple val(meta), path("*.tsv.gz") , emit: tsv , optional: true + tuple val(meta), path("*.sti") , emit: sti , optional: true + tuple val("${task.process}"), val('strobealign'), eval("strobealign --version"), topic: versions, emit: versions_strobealign + tuple val("${task.process}"), val('samtools'), eval("samtools version | sed '1!d;s/.* //'"), emit: versions_samtools, topic: versions + tuple val("${task.process}"), val('pigz'), eval("pigz --version 2>&1 | sed 's/pigz //'"), emit: versions_pigz, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def args2 = task.ext.args2 ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + + // Determine output file extension and command + def samtools_command = sort_bam ? 'sort' : 'view' + def extension = args.contains("-x") + ? "paf" + : args.contains("--aemb") + ? "tsv" + : args.contains("--create-index") + ? "sti" + : args2.contains("--output-fmt cram") + ? "cram" + : sort_bam && args2.contains("-O cram") + ? "cram" + : !sort_bam && args2.contains("-C") + ? "cram" + : "bam" + def reference = fasta && extension == "cram" ? "--reference ${fasta}" : "" + if (!fasta && extension == "cram") { + error("Fasta reference is required for CRAM output") + } + def output_cmd = extension == "bam" || extension == "cram" + ? "samtools ${samtools_command} ${args2} ${reference} --threads ${task.cpus} -o ${prefix}.${extension} -" + : extension == "paf" + ? "pigz ${args2} > ${prefix}.paf.gz" + : extension == "tsv" + ? "pigz ${args2} > ${prefix}.tsv.gz" + : extension == "sti" + ? "tee ${prefix}.log > /dev/null" + : error("Unable to determine output command for extension: ${extension}") + + """ + strobealign \\ + ${args} \\ + -t ${task.cpus} \\ + ${fasta} \\ + ${reads} \\ + | ${output_cmd} + """ + + stub: + def args = task.ext.args ?: '' + def args2 = task.ext.args2 ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def extension = args.contains("-x") + ? "paf" + : args.contains("--aemb") + ? "tsv" + : args2.contains("--output-fmt cram") + ? "cram" + : sort_bam && args2.contains("-O cram") + ? "cram" + : !sort_bam && args2.contains("-C") + ? "cram" + : "bam" + + """ + touch ${prefix}.${extension} + touch ${prefix}.csi + touch ${prefix}.crai + echo "" | pigz > ${prefix}.paf.gz + echo "" | pigz > ${prefix}.tsv.gz + touch ${prefix}.sti + """ +} diff --git a/modules/nf-core/strobealign/meta.yml b/modules/nf-core/strobealign/meta.yml new file mode 100644 index 00000000..f4b85b24 --- /dev/null +++ b/modules/nf-core/strobealign/meta.yml @@ -0,0 +1,192 @@ +name: "strobealign" +description: "Align short reads using dynamic seed size with strobemers" +keywords: + - strobealign + - strobemers + - alignment + - map + - fastq + - bam + - sam +tools: + - "strobealign": + description: "Align short reads using dynamic seed size with strobemers" + homepage: "https://github.com/ksahlin/strobealign" + documentation: "https://github.com/ksahlin/strobealign?tab=readme-ov-file#usage" + tool_dev_url: "https://github.com/ksahlin/strobealign" + doi: "10.1186/s13059-022-02831-7" + licence: + - "MIT" + identifier: biotools:strobealign +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. + ontologies: + - edam: "http://edamontology.org/data_2044" + - edam: "http://edamontology.org/format_1930" + - - meta2: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - fasta: + type: file + description: Reference genome in FASTA format + pattern: "*.{fasta,fa}" + ontologies: + - edam: "http://edamontology.org/data_2044" + - edam: "http://edamontology.org/format_1929" + - - meta3: + type: map + description: | + Groovy Map containing reference information. + e.g. [ id:'test', single_end:false ] + - index: + type: file + description: Strobealign genome index file + pattern: "*.sti" + ontologies: + - edam: "http://edamontology.org/data_3210" + - sort_bam: + type: boolean + description: use samtools sort (true) or samtools view (false) + pattern: "true or false" +output: + bam: + - - meta: + type: map + description: Groovy Map containing sample information + - "*.bam": + type: file + description: Output BAM file containing read alignments + pattern: "*.{bam}" + ontologies: + - edam: "http://edamontology.org/format_2572" + cram: + - - meta: + type: map + description: Groovy Map containing sample information + - "*.cram": + type: file + description: Output CRAM file containing read alignments + pattern: "*.{cram}" + ontologies: + - edam: "http://edamontology.org/format_3462" + csi: + - - meta: + type: map + description: Groovy Map containing sample information + - "*.csi": + type: file + description: Optional index file for BAM file + pattern: "*.{csi}" + ontologies: [] + crai: + - - meta: + type: map + description: Groovy Map containing sample information + - "*.crai": + type: file + description: Optional index file for CRAM file + pattern: "*.{crai}" + ontologies: [] + paf: + - - meta: + type: map + description: Groovy Map containing sample information + - "*.paf.gz": + type: file + description: Output PAF file containing read alignments + pattern: "*.{paf.gz}" + ontologies: [] + tsv: + - - meta: + type: map + description: Groovy Map containing sample information + - "*.tsv.gz": + type: file + description: Output TSV file containing read alignments + pattern: "*.{tsv.gz}" + ontologies: + - edam: "http://edamontology.org/format_3475" + sti: + - - meta: + type: map + description: Groovy Map containing sample information + - "*.sti": + type: file + description: Optional strobealign index file for fasta reference + pattern: "*.{sti}" + ontologies: [] + versions_strobealign: + - - ${task.process}: + type: string + description: The name of the process + - strobealign: + type: string + description: The name of the tool + - strobealign --version: + type: eval + description: The expression to obtain the version of the tool + versions_samtools: + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool + versions_pigz: + - - ${task.process}: + type: string + description: The name of the process + - pigz: + type: string + description: The name of the tool + - pigz --version 2>&1 | sed 's/pigz //': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - strobealign: + type: string + description: The name of the tool + - strobealign --version: + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - samtools: + type: string + description: The name of the tool + - samtools version | sed '1!d;s/.* //': + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - pigz: + type: string + description: The name of the tool + - pigz --version 2>&1 | sed 's/pigz //': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@matthdsm" +maintainers: + - "@matthdsm" + - "@nvnieuwk" diff --git a/modules/nf-core/strobealign/strobealign.diff b/modules/nf-core/strobealign/strobealign.diff new file mode 100644 index 00000000..2e5880dd --- /dev/null +++ b/modules/nf-core/strobealign/strobealign.diff @@ -0,0 +1,22 @@ +Changes in component 'nf-core/strobealign' +'modules/nf-core/strobealign/environment.yml' is unchanged +'modules/nf-core/strobealign/meta.yml' is unchanged +Changes in 'strobealign/main.nf': +--- modules/nf-core/strobealign/main.nf ++++ modules/nf-core/strobealign/main.nf +@@ -8,9 +8,7 @@ + 'community.wave.seqera.io/library/htslib_samtools_strobealign_pigz:4fa4f439c6bea386' }" + + input: +- tuple val(meta) , path(reads) +- tuple val(meta2), path(fasta) +- tuple val(meta3), path(index) ++ tuple val(meta) , path(reads), path(fasta), path(index) + val sort_bam + + output: + +'modules/nf-core/strobealign/tests/main.nf.test.snap' is unchanged +'modules/nf-core/strobealign/tests/nextflow.config' is unchanged +'modules/nf-core/strobealign/tests/main.nf.test' is unchanged +************************************************************ diff --git a/modules/nf-core/strobealign/tests/main.nf.test b/modules/nf-core/strobealign/tests/main.nf.test new file mode 100644 index 00000000..adab50bc --- /dev/null +++ b/modules/nf-core/strobealign/tests/main.nf.test @@ -0,0 +1,303 @@ +// TODO nf-core: Once you have added the required tests, please run the following command to build this file: +// nf-core modules test strobealign +nextflow_process { + + name "Test Process STROBEALIGN" + script "../main.nf" + config './nextflow.config' + process "STROBEALIGN" + + tag "modules" + tag "modules_nfcore" + tag "strobealign" + + test("fastq - sorted bam") { + when { + params { + module_args = "" + module_args2 = "--output-fmt bam --write-index" + } + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + 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) + ], + ] + input[1] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + ] + input[2] = [[:], []] + input[3] = true + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.bam, + process.out.csi, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("fastq - unsorted bam") { + when { + params { + module_args = "" + module_args2 = "--output-fmt bam" + } + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + 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) + ], + ] + input[1] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + ] + input[2] = [[:], []] + input[3] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.bam, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("fastq - sorted cram") { + when { + params { + module_args = "" + module_args2 = "--output-fmt cram,version=3.0 --write-index" + } + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + 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) + ], + ] + input[1] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + ] + input[2] = [[:], []] + input[3] = true + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + cram(process.out.cram[0][1], 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/sarscov2/genome/genome.fasta').getReadsMD5(), + file(process.out.crai[0][1]).exists(), + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("fastq - unsorted cram") { + when { + params { + module_args = "" + module_args2 = "--output-fmt cram,version=3.0" + } + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + 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) + ], + ] + input[1] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + ] + input[2] = [[:], []] + input[3] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + cram(process.out.cram[0][1], 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/sarscov2/genome/genome.fasta').getReadsMD5(), + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("fastq - paf") { + when { + params { + module_args = "-x" + module_args2 = "" + } + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + 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) + ], + ] + input[1] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + ] + input[2] = [[:], []] + input[3] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.paf, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("fastq - tsv") { + when { + params { + module_args = "--aemb" + module_args2 = "" + } + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + 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) + ], + ] + input[1] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + ] + input[2] = [[:], []] + input[3] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.tsv, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("fastq - sti") { + when { + params { + module_args = "--create-index" + module_args2 = "" + } + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + 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) + ], + ] + input[1] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + ] + input[2] = [[:], []] + input[3] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.sti, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("stub") { + options "-stub" + when { + params { + module_args = "" + module_args2 = "" + } + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + 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) + ], + ] + input[1] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + ] + input[2] = [[:], []] + input[3] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/strobealign/tests/main.nf.test.snap b/modules/nf-core/strobealign/tests/main.nf.test.snap new file mode 100644 index 00000000..7e53f32d --- /dev/null +++ b/modules/nf-core/strobealign/tests/main.nf.test.snap @@ -0,0 +1,450 @@ +{ + "fastq - sorted cram": { + "content": [ + "f3a1593b170cf1e9b9008b3afb77cc53", + true, + { + "versions_pigz": [ + [ + "STROBEALIGN", + "pigz", + "2.8" + ] + ], + "versions_samtools": [ + [ + "STROBEALIGN", + "samtools", + "1.22.1" + ] + ], + "versions_strobealign": [ + [ + "STROBEALIGN", + "strobealign", + "0.16.1" + ] + ] + } + ], + "timestamp": "2026-02-18T14:11:52.319915", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "fastq - sti": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "genome.fasta.r150.sti:md5,1fa95f6ba0167a729ddc6a444eb5e8f7" + ] + ], + { + "versions_pigz": [ + [ + "STROBEALIGN", + "pigz", + "2.8" + ] + ], + "versions_samtools": [ + [ + "STROBEALIGN", + "samtools", + "1.22.1" + ] + ], + "versions_strobealign": [ + [ + "STROBEALIGN", + "strobealign", + "0.16.1" + ] + ] + } + ], + "timestamp": "2026-02-18T14:12:18.718682", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "fastq - unsorted cram": { + "content": [ + "57aeef88ed701a8ebc8e2f0a381b2a6", + { + "versions_pigz": [ + [ + "STROBEALIGN", + "pigz", + "2.8" + ] + ], + "versions_samtools": [ + [ + "STROBEALIGN", + "samtools", + "1.22.1" + ] + ], + "versions_strobealign": [ + [ + "STROBEALIGN", + "strobealign", + "0.16.1" + ] + ] + } + ], + "timestamp": "2026-02-18T14:11:59.009249", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "fastq - tsv": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.tsv.gz:md5,1fcb7444ba029b7f41b3a836fec7ecac" + ] + ], + { + "versions_pigz": [ + [ + "STROBEALIGN", + "pigz", + "2.8" + ] + ], + "versions_samtools": [ + [ + "STROBEALIGN", + "samtools", + "1.22.1" + ] + ], + "versions_strobealign": [ + [ + "STROBEALIGN", + "strobealign", + "0.16.1" + ] + ] + } + ], + "timestamp": "2026-02-18T14:12:12.224719", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.tsv.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sti:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + "STROBEALIGN", + "strobealign", + "0.16.1" + ] + ], + "8": [ + [ + "STROBEALIGN", + "samtools", + "1.22.1" + ] + ], + "9": [ + [ + "STROBEALIGN", + "pigz", + "2.8" + ] + ], + "bam": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "crai": [ + [ + { + "id": "test", + "single_end": false + }, + "test.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "cram": [ + + ], + "csi": [ + [ + { + "id": "test", + "single_end": false + }, + "test.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "paf": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "sti": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sti:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tsv": [ + [ + { + "id": "test", + "single_end": false + }, + "test.tsv.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_pigz": [ + [ + "STROBEALIGN", + "pigz", + "2.8" + ] + ], + "versions_samtools": [ + [ + "STROBEALIGN", + "samtools", + "1.22.1" + ] + ], + "versions_strobealign": [ + [ + "STROBEALIGN", + "strobealign", + "0.16.1" + ] + ] + } + ], + "timestamp": "2026-02-18T14:12:25.287429", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "fastq - unsorted bam": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,740d88010349b3cd487a8b6244c64c0d" + ] + ], + { + "versions_pigz": [ + [ + "STROBEALIGN", + "pigz", + "2.8" + ] + ], + "versions_samtools": [ + [ + "STROBEALIGN", + "samtools", + "1.22.1" + ] + ], + "versions_strobealign": [ + [ + "STROBEALIGN", + "strobealign", + "0.16.1" + ] + ] + } + ], + "timestamp": "2026-02-18T14:11:44.848089", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "fastq - paf": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.paf.gz:md5,0992a1eb3dff9beca5849b9d1fc66390" + ] + ], + { + "versions_pigz": [ + [ + "STROBEALIGN", + "pigz", + "2.8" + ] + ], + "versions_samtools": [ + [ + "STROBEALIGN", + "samtools", + "1.22.1" + ] + ], + "versions_strobealign": [ + [ + "STROBEALIGN", + "strobealign", + "0.16.1" + ] + ] + } + ], + "timestamp": "2026-02-18T14:12:05.638183", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "fastq - sorted bam": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,c9bf092d8998eac47b6b85afe9aa9038" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam.csi:md5,8d53854f92b3f263db0ed27f4bbad054" + ] + ], + { + "versions_pigz": [ + [ + "STROBEALIGN", + "pigz", + "2.8" + ] + ], + "versions_samtools": [ + [ + "STROBEALIGN", + "samtools", + "1.22.1" + ] + ], + "versions_strobealign": [ + [ + "STROBEALIGN", + "strobealign", + "0.16.1" + ] + ] + } + ], + "timestamp": "2026-02-18T14:11:38.040997", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/strobealign/tests/nextflow.config b/modules/nf-core/strobealign/tests/nextflow.config new file mode 100644 index 00000000..7c6b31b6 --- /dev/null +++ b/modules/nf-core/strobealign/tests/nextflow.config @@ -0,0 +1,6 @@ +process { + withName: STROBEALIGN { + ext.args = params.module_args + ext.args2 = params.module_args2 + } +} diff --git a/nextflow.config b/nextflow.config index cb90bae7..61685c2d 100644 --- a/nextflow.config +++ b/nextflow.config @@ -10,117 +10,88 @@ params { // Input options - input = null - - // Analysis options - aligner = 'bowtie2' - markdup = 'bamsormadup' - umi_aware = false - skip_trimming = false - trim_front = 0 - trim_tail = 0 - adapter_R1 = null - adapter_R2 = null - run_coverage = true - disable_picard_metrics = false - roi = null - genelists = null - + input = null // References - genomes = [:] - igenomes_base = '/references' - // igenomes_base = "s3://reference-data/genomes/" + genome = null + genomes = [:] + igenomes_base = '/references/' + igenomes_ignore = false + + // Analysis options + split_fastq = 100000000 + genelists = null // MultiQC options - multiqc_config = null - multiqc_title = null - multiqc_logo = null - max_multiqc_email_size = '25.MB' - multiqc_methods_description = null + multiqc_config = null + multiqc_title = null + multiqc_logo = null + max_multiqc_email_size = '25.MB' + multiqc_methods_description = null // Boilerplate options - outdir = "./results" - publish_dir_mode = 'copy' - email = null - email_on_fail = null - plaintext_email = false - monochrome_logs = false - hook_url = System.getenv('HOOK_URL') - help = false - version = false + outdir = null + publish_dir_mode = 'copy' + email = null + email_on_fail = null + plaintext_email = false + monochrome_logs = false + hook_url = System.getenv('HOOK_URL') + help = false + help_full = false + show_hidden = false + version = false + pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/' + trace_report_suffix = new java.util.Date().format('yyyy-MM-dd_HH-mm-ss') // 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 + config_profile_name = null + config_profile_description = null - // Schema validation default options - validate_params = true + custom_config_version = 'main' + custom_config_base = "https://raw.githubusercontent.com/nf-cmgg/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 includeConfig 'conf/base.config' -// Load nf-core custom profiles from different Institutions -includeConfig "${params.custom_config_base}/nfcore_custom.config" - -// Load nf-cmgg cluster profiles -includeConfig !System.getenv('NXF_OFFLINE') ? "https://raw.githubusercontent.com/nf-cmgg/configs/main/clusters/cmgg_clusters.config" : "/dev/null" - -// Include the igenomes config -includeConfig 'conf/igenomes.config' +// Load igenomes.config if required +includeConfig !params.igenomes_ignore ? 'conf/igenomes.config' : 'conf/igenomes_ignored.config' -// Load nf-cmgg/preprocessing custom profiles from different institutions. -// Warning: Uncomment only if a pipeline-specific institutional config already exists on nf-core/configs! -// try { -// includeConfig "${params.custom_config_base}/pipeline/preprocessing.config" -// } catch (Exception e) { -// System.err.println("WARNING: Could not load nf-core/config/preprocessing profiles: ${params.custom_config_base}/pipeline/preprocessing.config") -// } profiles { debug { - dumpHashes = true - process.beforeScript = 'echo $HOSTNAME' - cleanup = false + process.beforeScript = 'echo $HOSTNAME' + cleanup = false nextflow.enable.configProcessNamesValidation = true } - conda { - conda.enabled = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - conda.channels = ['conda-forge', 'bioconda'] - apptainer.enabled = false - } - mamba { - conda.enabled = true - conda.useMamba = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - apptainer.enabled = false - } docker { - docker.enabled = true - conda.enabled = false - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - apptainer.enabled = false - docker.runOptions = '-u $(id -u):$(id -g)' + docker.enabled = true + conda.enabled = false + singularity.enabled = false + podman.enabled = false + shifter.enabled = false + charliecloud.enabled = false + apptainer.enabled = false + docker.runOptions = '-u $(id -u):$(id -g)' } - arm { - docker.runOptions = '-u $(id -u):$(id -g) --platform=linux/amd64' + arm64 { + process.arch = 'arm64' + // TODO https://github.com/nf-core/modules/issues/6694 + // For now if you're using arm64 you have to use wave for the sake of the maintainers + // wave profile + apptainer.ociAutoPull = true + singularity.ociAutoPull = true + wave.enabled = true + wave.freeze = true + wave.strategy = ["conda", "container"] + } + emulate_amd64 { + docker.runOptions = '-u $(id -u):$(id -g) --platform=linux/amd64' } singularity { singularity.enabled = true @@ -133,77 +104,80 @@ profiles { apptainer.enabled = false } podman { - podman.enabled = true - conda.enabled = false - docker.enabled = false - singularity.enabled = false - shifter.enabled = false - charliecloud.enabled = false - apptainer.enabled = false + podman.enabled = true + conda.enabled = false + docker.enabled = false + singularity.enabled = false + shifter.enabled = false + charliecloud.enabled = false + apptainer.enabled = false } shifter { - shifter.enabled = true - conda.enabled = false - docker.enabled = false - singularity.enabled = false - podman.enabled = false - charliecloud.enabled = false - apptainer.enabled = false + shifter.enabled = true + conda.enabled = false + docker.enabled = false + singularity.enabled = false + podman.enabled = false + charliecloud.enabled = false + apptainer.enabled = false } charliecloud { - charliecloud.enabled = true - conda.enabled = false - docker.enabled = false - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - apptainer.enabled = false + charliecloud.enabled = true + conda.enabled = false + docker.enabled = false + singularity.enabled = false + podman.enabled = false + shifter.enabled = false + apptainer.enabled = false } apptainer { - apptainer.enabled = true - apptainer.autoMounts = true - conda.enabled = false - docker.enabled = false - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false + apptainer.enabled = true + apptainer.autoMounts = true + conda.enabled = false + docker.enabled = false + singularity.enabled = false + podman.enabled = false + shifter.enabled = false + charliecloud.enabled = false } - gitpod { - executor.name = 'local' - executor.cpus = 4 - executor.memory = 8.GB + wave { + apptainer.ociAutoPull = true + singularity.ociAutoPull = true + wave.enabled = true + wave.freeze = true + wave.strategy = ["conda", "container"] + } + gpu { + docker.runOptions = '-u $(id -u):$(id -g) --gpus all' + apptainer.runOptions = '--nv' + singularity.runOptions = '--nv' + } + test { + includeConfig 'conf/test.config' + } + test_full { + includeConfig 'conf/test_full.config' } - s3_ugent { includeConfig 'conf/profiles/s3_ugent.config' } - test { includeConfig 'conf/test.config' } - test_full { includeConfig 'conf/test_full.config' } - // analysis profiles - sWGS { includeConfig 'conf/profiles/sWGS.config' } - WGS { includeConfig 'conf/profiles/WGS.config' } - WES { includeConfig 'conf/profiles/WES.config' } - copgt { includeConfig 'conf/profiles/copgt.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 -// Nextflow plugins -plugins { - id 'nf-schema@2.1.1' // Validation of pipeline parameters and creation of an input channel from a sample sheet -} +// If params.custom_config_base is set AND either the NXF_OFFLINE environment variable is not set or params.custom_config_base is a local path, the nfcore_custom.config file from the specified base path is included. +// Load nf-cmgg/preprocessing custom profiles from different institutions. +includeConfig params.custom_config_base && (!System.getenv('NXF_OFFLINE') || !params.custom_config_base.startsWith('http')) ? "${params.custom_config_base}/nfcore_custom.config" : "/dev/null" -// 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" // Load nf-cmgg/preprocessing 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/preprocessing.config" : "/dev/null" +includeConfig params.custom_config_base && params.custom_config_base.contains('nf-cmgg') && (!System.getenv('NXF_OFFLINE') || !params.custom_config_base.startsWith('http')) ? "${params.custom_config_base}/pipeline/preprocessing.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' // 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. @@ -217,70 +191,91 @@ env { } // Set bash options -process.shell = [ - "bash", - "-e", // Exit if a tool returns a non-zero status/exit code - "-u", // Treat unset variables and parameters as an error - "-o", // Returns the status of the last command to exit.. - "pipefail" // ..with a non-zero status or zero if all successfully execute -] +process.shell = ["bash", "-C", "-e", "-u", "-o", "pipefail"].join(' ') // Disable process selector warnings by default. Use debug profile to enable warnings. nextflow.enable.configProcessNamesValidation = false -// Enable module binaries by default -nextflow.enable.moduleBinaries = true - timeline { - enabled = true - file = "${params.outdir}/pipeline_info/execution_timeline_${new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss')}.html" + enabled = true + overwrite = true + file = "${params.outdir}/pipeline_info/execution_timeline_${params.trace_report_suffix}.html" } report { - enabled = true - file = "${params.outdir}/pipeline_info/execution_report_${new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss')}.html" + enabled = true + overwrite = true + file = "${params.outdir}/pipeline_info/execution_report_${params.trace_report_suffix}.html" } trace { - enabled = true - file = "${params.outdir}/pipeline_info/execution_trace_${new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss')}.txt" + enabled = true + overwrite = true + file = "${params.outdir}/pipeline_info/execution_trace_${params.trace_report_suffix}.txt" } dag { - enabled = true - file = "${params.outdir}/pipeline_info/pipeline_dag_${new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss')}.html" + enabled = true + overwrite = true + file = "${params.outdir}/pipeline_info/pipeline_dag_${params.trace_report_suffix}.mmd" } manifest { name = 'nf-cmgg/preprocessing' - author = """CMGG ICT team""" + contributors = [ + [ + name: 'Matthias De Smet', + affiliation: 'Center for Medical Genetics Ghent, Ghent University, Belgium', + email: 'matthias.desmet@ugent.be', + github: '@matthdsm', + contribution: ["author", "maintainer"], + orcid: 'https://orcid.org/0000-0003-2555-3114', + ], + [ + name: ' Nicolas Vannieuwkerke', + affiliation: 'Center for Medical Genetics Ghent, Ghent University Hospital, Belgium', + email: 'nicolas.vannieuwkerke@ugent.be', + github: '@nvnieuwk', + contribution: ["maintainer"], + orcid: 'https://orcid.org/0009-0003-5619-1555', + ], + ] homePage = 'https://github.com/nf-cmgg/preprocessing' description = """Demultiplexing, adapter trimming, alignment, and coverage calculation for NGS data.""" mainScript = 'main.nf' - nextflowVersion = '!>=25.04.0' - version = '2.0.6' + defaultBranch = 'main' + nextflowVersion = '!>=25.10.0' + version = '3.0.0' doi = '' } +// Nextflow plugins +plugins { + id 'nf-cgroup-metrics@1.0.1' + id 'nf-cmgg@0.1.0' + id 'nf-schema@2.6.1' + id 'nf-teams@0.1.0' +} + validation { - defaultIgnoreParams = ["genomes", "igenomes_base"] - help { - enabled = true - command = "nextflow run ${manifest.name} -profile docker --input --outdir " - fullParameter = "help_full" - showHiddenParameter = "show_hidden" - beforeText = """ --\033[2m----------------------------------------------------\033[0m- - \033[0;34m ///\033[0;32m/// \033[0m -\033[0;34m ___ __ _ _ __ __ \033[0;34m ///\033[0;32m///// \033[0m -\033[0;34m |\\ | |__ __ / ` | \\/ | / _` / _` \033[0;34m////\033[0;32m////// \033[0m -\033[0;34m | \\| | \\__, | | \\__| \\__| \033[0;34m///\033[0;32m///// \033[0m - \033[0;34m///\033[0;32m/// \033[0m -\033[0;35m ${manifest.name} ${manifest.version}\033[0m --\033[2m----------------------------------------------------\033[0m- -""" - } - summary { - beforeText = validation.help.beforeText + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs +} + +// TODO remove this once minimal nf-version is 26.0X with strict syntax. +cmgg { + samplesheets.enabled = true + done.enabled = true +} +teams { + enabled = true + webHook { + url = params.hook_url ? params.hook_url : System.getenv('TEAMS_WEBHOOK_URL') } + onComplete.enabled = true } // Load modules.config for DSL2 module specific options includeConfig 'conf/modules.config' + +// Set default output dir and publish mode +// Temporary fix until the nf-core template supports workflow output definitions +workflow.output.mode = params.publish_dir_mode +outputDir = params.outdir diff --git a/nextflow_schema.json b/nextflow_schema.json index 6a2a3685..e0d5f227 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -38,6 +38,10 @@ "type": "string", "description": "MultiQC report title. Printed as page header, used for filename if not otherwise specified.", "fa_icon": "fas fa-file-signature" + }, + "genomes": { + "type": "object", + "hidden": true } } }, @@ -47,62 +51,20 @@ "description": "", "default": "", "properties": { - "aligner": { - "type": "string", - "default": "bowtie2", - "description": "Which aligner to use", - "enum": ["bowtie2", "bwamem", "bwamem2", "dragmap", "snap", "star"] - }, - "markdup": { - "type": "string", - "default": "bamsormadup", - "description": "Which alignment postprocessor to use", - "enum": ["bamsormadup", "samtools", "false"] - }, - "umi_aware": { - "type": "boolean", - "default": "false", - "description": "Run markdup in UMI-aware mode. This applies to Samtools only and requires the UMI to be in the read name." - }, - "run_coverage": { - "type": "boolean", - "description": "Run coverage analysis steps", - "default": true - }, - "skip_trimming": { - "type": "boolean", - "description": "Skip adapter trimming", - "default": false - }, - "trim_front": { - "type": "integer", - "default": 0, - "description": "Number of bases to trim from the front of the read" - }, - "trim_tail": { + "split_fastq": { "type": "integer", - "default": 0, - "description": "Number of bases to trim from the tail of the read" - }, - "adapter_R1": { - "type": "string", - "default": null, - "description": "Adapter sequence to be trimmed" - }, - "adapter_R2": { - "type": "string", - "default": null, - "description": "Adapter sequence to be trimmed" - }, - "disable_picard_metrics": { - "type": "boolean", - "default": false, - "description": "Disable the calculation of (slow) Picard metrics" - }, - "roi": { - "type": "string", - "default": null, - "description": "Region of interest for coverage analysis to be applied to all samples" + "oneOf": [ + { + "minimum": 250 + }, + { + "const": 0 + } + ], + "default": 100000000, + "fa_icon": "fas fa-clock", + "description": "Specify how many reads each split of a FastQ file contains. Set 0 to turn off splitting at all.", + "help_text": "Use the the tool FastP to split FASTQ file by number of reads. This parallelizes across fastq file shards speeding up mapping. Note although the minimum value is 250 reads, if you have fewer than 250 reads a single FASTQ shard will still be created." }, "genelists": { "type": "string", @@ -111,8 +73,7 @@ "format": "directory-path", "description": "Directory containing gene list bed files for granular coverage analysis" } - }, - "required": ["aligner"] + } }, "institutional_config_options": { "title": "Institutional config options", @@ -124,16 +85,16 @@ "custom_config_version": { "type": "string", "description": "Git commit id for Institutional configs.", - "default": "master", + "default": "main", "hidden": true, "fa_icon": "fas fa-users-cog" }, "custom_config_base": { "type": "string", - "description": "Base directory for Institutional configs.", - "default": "https://raw.githubusercontent.com/nf-core/configs/master", + "description": "Base directory for custom configs.", + "default": "https://raw.githubusercontent.com/nf-cmgg/configs/main", "hidden": true, - "help_text": "If you're running offline, Nextflow will not be able to fetch the institutional config files from the internet. If you don't need them, then this is not a problem. If you do need them, you should download the files from the repo and tell Nextflow where to find them with this parameter.", + "help_text": "If you're running offline, Nextflow will not be able to fetch the custom config files from the internet. If you don't need them, then this is not a problem. If you do need them, you should download the files from the repo and tell Nextflow where to find them with this parameter.", "fa_icon": "fas fa-users-cog" }, "config_profile_name": { @@ -169,12 +130,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.", @@ -249,6 +204,52 @@ "default": true, "fa_icon": "fas fa-check-square", "hidden": true + }, + "pipelines_testdata_base_path": { + "type": "string", + "fa_icon": "far fa-check-circle", + "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 + }, + "help": { + "type": ["boolean", "string"], + "description": "Display the help message." + }, + "help_full": { + "type": "boolean", + "description": "Display the full detailed help message." + }, + "show_hidden": { + "type": "boolean", + "description": "Display hidden parameters in the help message (only works when --help or --help_full are provided)." + }, + "igenomes_base": { + "type": "string", + "format": "directory-path", + "description": "Directory / URL base for iGenomes references.", + "fa_icon": "fas fa-cloud-download-alt", + "default": "/references/", + "hidden": true + }, + "igenomes_ignore": { + "type": "boolean", + "description": "Do not load the iGenomes reference config.", + "fa_icon": "fas fa-ban", + "hidden": true, + "help_text": "Do not load `igenomes.config` when running the pipeline. You may choose this option if you observe clashes between custom parameters and those supplied in `igenomes.config`." + }, + "genome": { + "type": "string", + "description": "Name of iGenomes reference.", + "fa_icon": "fas fa-book", + "help_text": "If using a reference genome configured in the pipeline using iGenomes, use this parameter to give the ID for the reference. This is then used to build the full paths for all required reference genome files e.g. `--genome GRCh38`. \n\nSee the [nf-core website docs](https://nf-co.re/usage/reference_genomes) for more details." } } } diff --git a/nf-test.config b/nf-test.config index 0688f302..bda04274 100644 --- a/nf-test.config +++ b/nf-test.config @@ -1,9 +1,24 @@ config { + // location for all nf-test tests + testsDir = "." - testsDir "tests" - workDir ".nf-test" - configFile "tests/config/nf-test.config" - profile "docker" - options "-dump-channels" + // nf-test directory including temporary files for each test + workDir = System.getenv("NFT_WORKDIR") ?: ".nf-test" + // location of an optional nextflow.config file specific for executing tests + configFile = "tests/nextflow.config" + + // ignore tests coming from the nf-core/modules repo + ignore = ['modules/nf-core/**/tests/*', 'subworkflows/nf-core/**/tests/*'] + + // run all test with defined profile(s) from the main nextflow.config + profile = "test,s3_ugent" + + // list of filenames or patterns that should be trigger a full test run + triggers = ['nextflow.config', 'nf-test.config', 'conf/test.config', 'tests/nextflow.config', 'tests/.nftignore'] + + // load the necessary plugins + plugins { + load "nft-utils@0.0.7" + } } diff --git a/ro-crate-metadata.json b/ro-crate-metadata.json new file mode 100644 index 00000000..40119c7b --- /dev/null +++ b/ro-crate-metadata.json @@ -0,0 +1,358 @@ +{ + "@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": "2026-03-04T08:40:34+00:00", + "description": "# nf-cmgg/preprocessing\n\n[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new/nf-cmgg/preprocessing)\n[![GitHub Actions CI Status](https://github.com/nf-cmgg/preprocessing/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-cmgg/preprocessing/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-cmgg/preprocessing/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-cmgg/preprocessing/actions/workflows/linting.yml)[![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/version-%E2%89%A525.10.0-green?style=flat&logo=nextflow&logoColor=white&color=%230DC09D&link=https%3A%2F%2Fnextflow.io)](https://www.nextflow.io/)\n[![nf-core template version](https://img.shields.io/badge/nf--core_template-3.5.1-green?style=flat&logo=nfcore&logoColor=white&color=%2324B064&link=https%3A%2F%2Fnf-co.re)](https://github.com/nf-core/tools/releases/tag/3.5.1)\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-cmgg/preprocessing)\n\n## Introduction\n\n**nf-cmgg/preprocessing** is a bioinformatics pipeline that demultiplexes and aligns raw sequencing data.\nIt also performs basic QC and coverage analysis.\n\nThe pipeline is built using Nextflow, a workflow tool to run tasks across multiple compute infrastructures in a very portable manner. It comes with docker containers making installation trivial and results highly reproducible.\n\nSteps inlcude:\n\n1. Demultiplexing using [`BCLconvert`](https://emea.support.illumina.com/sequencing/sequencing_software/bcl-convert.html)\n2. Read QC and trimming using [`fastp`](https://github.com/OpenGene/fastp)\n3. Alignment using either [`bwa`](https://github.com/lh3/bwa), [`bwa-mem2`](https://github.com/bwa-mem2/bwa-mem2), [`bowtie2`](https://github.com/BenLangmead/bowtie2), [`dragmap`](https://github.com/Illumina/DRAGMAP), [`snap`](https://github.com/amplab/snap) or [`strobe`](https://github.com/ksahlin/strobealign) for DNA-seq and [`STAR`](https://github.com/alexdobin/STAR) for RNA-seq\n4. Duplicate marking using [`bamsormadup`](https://gitlab.com/german.tischler/biobambam2) or [`samtools markdup`](http://www.htslib.org/doc/samtools-markdup.html)\n5. Coverage analysis using [`mosdepth`](https://github.com/brentp/mosdepth) and [`samtools coverage`](http://www.htslib.org/doc/samtools-coverage.html)\n6. Alignment QC using [`samtools flagstat`](http://www.htslib.org/doc/samtools-flagstat.html), [`samtools stats`](http://www.htslib.org/doc/samtools-stats.html), [`samtools idxstats`](http://www.htslib.org/doc/samtools-idxstats.html) and [`picard CollecHsMetrics`](https://broadinstitute.github.io/picard/command-line-overview.html#CollectHsMetrics), [`picard CollectWgsMetrics`](https://broadinstitute.github.io/picard/command-line-overview.html#CollectWgsMetrics), [`picard CollectMultipleMetrics`](https://broadinstitute.github.io/picard/command-line-overview.html#CollectMultipleMetrics)\n7. QC aggregation using [`multiqc`](https://multiqc.info/)\n\n![metro map](docs/images/metro_map.png)\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\nThe full documentation can be found [here](docs/README.md)\n\nFirst, prepare a samplesheet with your input data that looks as follows:\n\n`samplesheet.csv` for fastq inputs:\n\n```csv\nid,samplename,organism,library,aligner,fastq_1,fastq_2\nsample1,sample1,Homo sapiens,Library_Name,bwamem,reads1.fq.gz,reads2.fq.gz\n```\n\n`samplesheet.csv` for flowcell inputs:\n\n```csv\nid,samplesheet,lane,flowcell,sample_info\nflowcell_id,/path/to/illumina_samplesheet.csv,1,/path/to/sequencer_uploaddir,/path/to/sampleinfo.csv\n```\n\n`sampleinfo.csv` for use with flowcell inputs:\n\n```csv\nsamplename,library,organism,tag,aligner\nfc_sample1,test,Homo sapiens,WES,bwamem\n```\n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-cmgg/preprocessing \\\n -profile \\\n --igenomes_base /path/to/genomes \\\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**_;\n> see [docs](https://nf-co.re/usage/configuration#custom-configuration-files).\n\n## Credits\n\nnf-cmgg/preprocessing was originally written by the CMGG ICT team.\n\n## Support\n\nThis pipeline uses code and infrastructure developed and maintained by the [nf-core](https://nf-co.re) community, reused here under the [MIT license](https://github.com/nf-core/tools/blob/master/LICENSE).\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": "docs/images/metro_map.png" + }, + { + "@id": "assets/" + }, + { + "@id": "bin/" + }, + { + "@id": "conf/" + }, + { + "@id": "docs/" + }, + { + "@id": "docs/images/" + }, + { + "@id": "modules/" + }, + { + "@id": "modules/local/" + }, + { + "@id": "modules/nf-core/" + }, + { + "@id": "workflows/" + }, + { + "@id": "subworkflows/" + }, + { + "@id": "nextflow.config" + }, + { + "@id": "README.md" + }, + { + "@id": "nextflow_schema.json" + }, + { + "@id": "CHANGELOG.md" + }, + { + "@id": "LICENSE" + }, + { + "@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-cmgg/preprocessing", + "license": "MIT", + "mainEntity": { + "@id": "main.nf" + }, + "mentions": [ + { + "@id": "#a7d7e3e1-4abb-45b6-8465-8056924d5808" + } + ], + "name": "nf-cmgg/preprocessing" + }, + { + "@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/0009-0003-5619-1555" + }, + { + "@id": "https://orcid.org/0000-0003-2555-3114" + } + ], + "dateCreated": "", + "dateModified": "2026-03-04T09:40:34Z", + "dct:conformsTo": "https://bioschemas.org/profiles/ComputationalWorkflow/1.0-RELEASE/", + "image": { + "@id": "docs/images/metro_map.png" + }, + "keywords": [ + "nf-core", + "nextflow" + ], + "license": [ + "MIT" + ], + "maintainer": [ + { + "@id": "https://orcid.org/0000-0003-2555-3114" + } + ], + "name": [ + "nf-cmgg/preprocessing" + ], + "programmingLanguage": { + "@id": "https://w3id.org/workflowhub/workflow-ro-crate#nextflow" + }, + "sdPublisher": { + "@id": "https://nf-co.re/" + }, + "url": [ + "https://github.com/nf-cmgg/preprocessing", + "https://nf-co.re/nf-cmgg/preprocessing/3.0.0/" + ], + "version": [ + "3.0.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": "!>=25.10.0" + }, + { + "@id": "docs/images/metro_map.png", + "@type": [ + "File", + "ImageObject" + ], + "name": "Workflow diagram" + }, + { + "@id": "#a7d7e3e1-4abb-45b6-8465-8056924d5808", + "@type": "TestSuite", + "instance": [ + { + "@id": "#61347af5-7167-4ebd-a8c0-2b36f46308d1" + } + ], + "mainEntity": { + "@id": "main.nf" + }, + "name": "Test suite for nf-cmgg/preprocessing" + }, + { + "@id": "#61347af5-7167-4ebd-a8c0-2b36f46308d1", + "@type": "TestInstance", + "name": "GitHub Actions workflow for testing nf-cmgg/preprocessing", + "resource": "repos/nf-cmgg/preprocessing/actions/workflows/nf-test.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": "bin/", + "@type": "Dataset", + "description": "Scripts that must be callable from a pipeline process" + }, + { + "@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/local/", + "@type": "Dataset", + "description": "Pipeline-specific modules" + }, + { + "@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": "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/0009-0003-5619-1555", + "@type": "Person", + "email": "101190534+nvnieuwk@users.noreply.github.com", + "name": "Nicolas Vannieuwkerke" + }, + { + "@id": "https://orcid.org/0000-0003-2555-3114", + "@type": "Person", + "email": "11850640+matthdsm@users.noreply.github.com", + "name": "Matthias De Smet" + } + ] +} \ No newline at end of file diff --git a/subworkflows/local/bam_qc/main.nf b/subworkflows/local/bam_qc/main.nf index 392bcd10..b6cd772c 100644 --- a/subworkflows/local/bam_qc/main.nf +++ b/subworkflows/local/bam_qc/main.nf @@ -1,7 +1,7 @@ // samtools modules -include { SAMTOOLS_STATS } from '../../../modules/nf-core/samtools/stats/main' -include { SAMTOOLS_IDXSTATS } from '../../../modules/nf-core/samtools/idxstats/main' -include { SAMTOOLS_FLAGSTAT } from '../../../modules/nf-core/samtools/flagstat/main' +include { SAMTOOLS_STATS } from '../../../modules/nf-core/samtools/stats/main' +include { SAMTOOLS_IDXSTATS } from '../../../modules/nf-core/samtools/idxstats/main' +include { SAMTOOLS_FLAGSTAT } from '../../../modules/nf-core/samtools/flagstat/main' // picard modules include { PICARD_COLLECTMULTIPLEMETRICS } from '../../../modules/nf-core/picard/collectmultiplemetrics/main' @@ -10,66 +10,55 @@ include { PICARD_COLLECTWGSMETRICS } from '../../../modules/nf-core/picard/ workflow BAM_QC { take: - ch_bam_bai_roi_fasta_fai_dict // channel: [ val(meta), path(bam), path(bai), path(roi), path(fasta), path(fai), path(dict)] - disable_picard // boolean + ch_bam_bai_roi_fasta_fai_dict // channel: [ val(meta), path(bam), path(bai), path(roi), path(fasta), path(fai), path(dict)] main: - ch_versions = Channel.empty() - ch_bam_bai_roi_fasta_fai_dict - .map{ meta, bam, bai, roi, fasta, fai, dict -> return [meta, bam, bai, fasta]} - .set{ ch_bam_bai_fasta } - - SAMTOOLS_STATS ( ch_bam_bai_fasta ) - ch_versions = ch_versions.mix(SAMTOOLS_STATS.out.versions) - - ch_bam_bai_fasta - .map{ meta, bam, bai, fasta -> return [meta, bam, bai]} - .set{ ch_bam_bai } - - SAMTOOLS_FLAGSTAT ( ch_bam_bai ) - ch_versions = ch_versions.mix(SAMTOOLS_FLAGSTAT.out.versions) + .map { meta, bam, bai, _roi, fasta, fai, _dict -> + return [meta, bam, bai, fasta, fai] + } + .set { ch_bam_bai_fasta_fai } - SAMTOOLS_IDXSTATS ( ch_bam_bai ) - ch_versions = ch_versions.mix(SAMTOOLS_IDXSTATS.out.versions) + SAMTOOLS_STATS(ch_bam_bai_fasta_fai) + SAMTOOLS_FLAGSTAT(ch_bam_bai_fasta_fai) + SAMTOOLS_IDXSTATS(ch_bam_bai_fasta_fai) - ch_picard_hsmetrics = Channel.empty() - ch_picard_multiplemetrics = Channel.empty() - ch_picard_wgsmetrics = Channel.empty() - if (!disable_picard) { + ch_picard_hsmetrics = channel.empty() + ch_picard_multiplemetrics = channel.empty() + ch_picard_multiplemetrics_pdf = channel.empty() + ch_picard_wgsmetrics = channel.empty() - ch_bam_bai_roi_fasta_fai_dict - .map{ meta, bam, bai, roi, fasta, fai, dict -> return [meta, bam, bai, fasta, fai]} - .set{ ch_bam_bai_fasta_fai } + ch_bam_bai_roi_fasta_fai_dict + .filter { meta, _bam, _bai, _roi, _fasta, _fai, _dict -> + !meta.disable_picard_metrics + } + .set { ch_picard } - PICARD_COLLECTMULTIPLEMETRICS ( ch_bam_bai_fasta_fai ) - ch_versions = ch_versions.mix(PICARD_COLLECTMULTIPLEMETRICS.out.versions) - ch_picard_multiplemetrics = ch_picard_multiplemetrics.mix(PICARD_COLLECTMULTIPLEMETRICS.out.metrics) + PICARD_COLLECTMULTIPLEMETRICS(ch_picard) + ch_picard_multiplemetrics = PICARD_COLLECTMULTIPLEMETRICS.out.metrics + ch_picard_multiplemetrics_pdf = PICARD_COLLECTMULTIPLEMETRICS.out.pdf - ch_bam_bai_roi_fasta_fai_dict - .branch{ meta, bam, bai, roi, fasta, fai, dict -> - hsmetrics : roi != [] - return [meta, bam, bai, roi, roi, fasta, fai, dict] - wgsmetrics : roi == [] - return [meta, bam, bai, fasta, fai] + ch_picard + .branch { meta, bam, bai, roi, fasta, fai, dict -> + hsmetrics: roi != [] + return [meta, bam, bai, roi, roi, fasta, fai, dict] + wgsmetrics: roi == [] + return [meta, bam, bai, fasta, fai, dict] } - .set{ch_picard} + .set { ch_picard_coverage } - PICARD_COLLECTWGSMETRICS ( ch_picard.wgsmetrics, [] ) - ch_versions = ch_versions.mix(PICARD_COLLECTWGSMETRICS.out.versions) - ch_picard_wgsmetrics = ch_picard_wgsmetrics.mix(PICARD_COLLECTWGSMETRICS.out.metrics) + PICARD_COLLECTWGSMETRICS(ch_picard_coverage.wgsmetrics, []) + ch_picard_wgsmetrics = PICARD_COLLECTWGSMETRICS.out.metrics - PICARD_COLLECTHSMETRICS ( ch_picard.hsmetrics ) - ch_versions = ch_versions.mix(PICARD_COLLECTHSMETRICS.out.versions) - ch_picard_hsmetrics = ch_picard_hsmetrics.mix(PICARD_COLLECTHSMETRICS.out.metrics) - } + PICARD_COLLECTHSMETRICS(ch_picard_coverage.hsmetrics) + ch_picard_hsmetrics = PICARD_COLLECTHSMETRICS.out.metrics emit: - samtools_stats = SAMTOOLS_STATS.out.stats - samtools_flagstat = SAMTOOLS_FLAGSTAT.out.flagstat - samtools_idxstats = SAMTOOLS_IDXSTATS.out.idxstats - picard_multiplemetrics = ch_picard_multiplemetrics - picard_wgsmetrics = ch_picard_wgsmetrics - picard_hsmetrics = ch_picard_hsmetrics - versions = ch_versions + samtools_stats = SAMTOOLS_STATS.out.stats + samtools_flagstat = SAMTOOLS_FLAGSTAT.out.flagstat + samtools_idxstats = SAMTOOLS_IDXSTATS.out.idxstats + picard_multiplemetrics = ch_picard_multiplemetrics + picard_multiplemetrics_pdf = ch_picard_multiplemetrics_pdf + picard_wgsmetrics = ch_picard_wgsmetrics + picard_hsmetrics = ch_picard_hsmetrics } diff --git a/subworkflows/local/bam_qc/meta.yml b/subworkflows/local/bam_qc/meta.yml new file mode 100644 index 00000000..e69de29b diff --git a/subworkflows/local/coverage/main.nf b/subworkflows/local/coverage/main.nf index 331d9d60..a3458574 100644 --- a/subworkflows/local/coverage/main.nf +++ b/subworkflows/local/coverage/main.nf @@ -1,49 +1,62 @@ #!/usr/bin/env nextflow // MODULES -include { MOSDEPTH } from "../../../modules/nf-core/mosdepth/main.nf" -include { SAMTOOLS_COVERAGE } from "../../../modules/nf-core/samtools/coverage/main" -include { PANELCOVERAGE } from "../../../modules/local/panelcoverage/main" +include { MOSDEPTH } from "../../../modules/nf-core/mosdepth/main.nf" +include { SAMTOOLS_COVERAGE } from "../../../modules/nf-core/samtools/coverage/main" +include { PANELCOVERAGE } from "../../../modules/local/panelcoverage/main" workflow COVERAGE { take: - ch_meta_cram_crai_fasta_fai_roi // channel: [mandatory] [meta, cram, crai, fasta, fai, roi] - ch_genelists // channel: [optional] [genelists] + ch_meta_cram_crai_fasta_fai_roi // channel: [mandatory] [meta, cram, crai, fasta, fai, roi] + ch_genelists // channel: [optional] [genelists] + main: + MOSDEPTH( + ch_meta_cram_crai_fasta_fai_roi.map { meta, cram, crai, fasta, _fai, roi -> + return [meta, cram, crai, roi, fasta] + } + ) - ch_versions = Channel.empty() - ch_coverageqc_files = Channel.empty() + SAMTOOLS_COVERAGE( + ch_meta_cram_crai_fasta_fai_roi.map { meta, cram, crai, fasta, fai, _roi -> + return [meta, cram, crai, fasta, fai] + } + ) - MOSDEPTH( - ch_meta_cram_crai_fasta_fai_roi.map{ - meta, cram, crai, fasta, fai, roi -> - return [meta, cram, crai, roi, fasta] + PANELCOVERAGE( + MOSDEPTH.out.per_base_bed.join(MOSDEPTH.out.per_base_csi).combine(ch_genelists).map { meta, bed, index, genelists -> + // Because groovy typing sucks ass; apparently an array of 1 is automatically converted to a string... + if (genelists !instanceof List) { + genelists = [genelists] } - ) - ch_versions = ch_versions.mix(MOSDEPTH.out.versions.first()) + def filtered_genelists = meta.tag.toLowerCase() == "seqcap" + ? genelists.findAll { genelist -> genelist.name.toLowerCase().contains("seqcap") } + : genelists.findAll { genelist -> !genelist.name.toLowerCase().contains("seqcap") } - SAMTOOLS_COVERAGE( - ch_meta_cram_crai_fasta_fai_roi.map{ - meta, cram, crai, fasta, fai, roi -> - return [meta, cram, crai, fasta, fai] + if (filtered_genelists.size() > 0) { + return [ + meta, + bed, + index, + filtered_genelists, + ] } - ) - ch_versions = ch_versions.mix(SAMTOOLS_COVERAGE.out.versions.first()) - ch_coverageqc_files = ch_coverageqc_files.merge(SAMTOOLS_COVERAGE.out.coverage) - - PANELCOVERAGE( - MOSDEPTH.out.per_base_bed - .join(MOSDEPTH.out.per_base_csi), - ch_genelists - ) - ch_versions = ch_versions.mix(PANELCOVERAGE.out.versions.first()) - ch_coverageqc_files = ch_coverageqc_files.mix(PANELCOVERAGE.out.regiondist) + } + ) emit: - mosdepth_summary = MOSDEPTH.out.summary_txt - mosdepth_global = MOSDEPTH.out.global_txt - mosdepth_regions = MOSDEPTH.out.regions_txt - samtools_coverage = SAMTOOLS_COVERAGE.out.coverage - panelcoverage = PANELCOVERAGE.out.regiondist - versions = ch_versions + mosdepth_global = MOSDEPTH.out.global_txt + mosdepth_summary = MOSDEPTH.out.summary_txt + mosdepth_regions = MOSDEPTH.out.regions_txt + mosdepth_per_base_d4 = MOSDEPTH.out.per_base_d4 + mosdepth_per_base_bed = MOSDEPTH.out.per_base_bed + mosdepth_per_base_csi = MOSDEPTH.out.per_base_csi + mosdepth_regions_bed = MOSDEPTH.out.regions_bed + mosdepth_regions_csi = MOSDEPTH.out.regions_csi + mosdepth_quantized_bed = MOSDEPTH.out.quantized_bed + mosdepth_quantized_csi = MOSDEPTH.out.quantized_csi + mosdepth_thresholds_bed = MOSDEPTH.out.thresholds_bed + mosdepth_thresholds_csi = MOSDEPTH.out.thresholds_csi + samtools_coverage = SAMTOOLS_COVERAGE.out.coverage + panelcoverage = PANELCOVERAGE.out.regiondist } diff --git a/subworkflows/local/coverage/meta.yml b/subworkflows/local/coverage/meta.yml new file mode 100644 index 00000000..e69de29b diff --git a/subworkflows/local/fastq_align_rna/main.nf b/subworkflows/local/fastq_align_rna/main.nf index 5ec99dc9..676b6172 100644 --- a/subworkflows/local/fastq_align_rna/main.nf +++ b/subworkflows/local/fastq_align_rna/main.nf @@ -5,41 +5,78 @@ // -include { STAR_ALIGN } from "../../../modules/nf-core/star/align/main.nf" +include { STAR_ALIGN } from "../../../modules/nf-core/star/align/main.nf" +include { GNU_SORT as SORT_MERGE_JUNCTIONS } from "../../../modules/nf-core/gnu/sort/main.nf" +include { GNU_SORT as SORT_MERGE_SPLICE_JUNCTIONS } from "../../../modules/nf-core/gnu/sort/main.nf" workflow FASTQ_ALIGN_RNA { take: - ch_reads_aligner_index_gtf // channel: [mandatory] reads, aligner, index, gtf + ch_reads_aligner_index_gtf // channel: [mandatory] reads, aligner, index, gtf main: - ch_bam = Channel.empty() - ch_reports = Channel.empty() - ch_versions = Channel.empty() + ch_bam = channel.empty() + ch_reports = channel.empty() - ch_reads_aligner_index_gtf.branch { meta, reads, aligner, index, gtf -> + ch_reads_aligner_index_gtf + .branch { meta, reads, aligner, index, gtf -> star: aligner == 'star' - return [meta, reads, index, gtf] + return [meta, reads, index, gtf] other: true } - .set{ch_to_align} + .set { ch_to_align } - // Throw error for all samples with unsupported aligners - ch_to_align.other.map{ meta, _reads, aligner, _index, _fasta -> - error "Unsupported aligner ${aligner} for sample ${meta.id}" - } + // Throw error for all samples with unsupported aligners + ch_to_align.other.map { meta, _reads, aligner, _index, _fasta -> + error("Unsupported aligner ${aligner} for sample ${meta.id}") + } + + // Align fastq files to reference genome + STAR_ALIGN(ch_to_align.star, "Illumina", "CMGG") + // if aligner is STAR + ch_bam = ch_bam.mix(STAR_ALIGN.out.bam) + ch_reports = ch_reports.mix( + STAR_ALIGN.out.log_final, + STAR_ALIGN.out.log_progress, + STAR_ALIGN.out.log_out, + ) - // Align fastq files to reference genome - STAR_ALIGN(ch_to_align.star, "Illumina", "CMGG") // if aligner is STAR - ch_bam = ch_bam.mix(STAR_ALIGN.out.bam) - ch_reports = ch_reports.mix( - STAR_ALIGN.out.log_final, - STAR_ALIGN.out.log_progress, - STAR_ALIGN.out.log_out - ) - ch_versions = ch_versions.mix(STAR_ALIGN.out.versions) + // Concatenate splice junction files + SORT_MERGE_SPLICE_JUNCTIONS(group_junctions(STAR_ALIGN.out.spl_junc_tab)) + // Concatenate junction files + SORT_MERGE_JUNCTIONS(group_junctions(STAR_ALIGN.out.junction)) emit: - bam = ch_bam // channel: [ [meta], bam ] - reports = ch_reports // channel: [ [meta], log ] - versions = ch_versions // channel: [ versions.yml ] + bam = ch_bam // channel: [ [meta], bam ] + splice_junctions = SORT_MERGE_SPLICE_JUNCTIONS.out.sorted // channel: [ [meta], splice_junctions ] + junctions = SORT_MERGE_JUNCTIONS.out.sorted // channel: [ [meta], junctions ] + reports = ch_reports // channel: [ [meta], log ] +} + +def group_junctions(ch) { + return ch + .map { meta, files -> + def gk = (meta.chunks as Integer ?: 1) + return [ + groupKey( + meta - meta.subMap('readgroup', 'chunks') + [id: meta.id ==~ /^\d{4}\..*$/ ? meta.id[5..-1] : meta.id], + gk, + ), + files, + ] + } + .groupTuple() + .map { meta, files -> + def gk = (meta.count as Integer ?: 1) + return [ + groupKey( + meta - meta.subMap('count') + [id: meta.samplename ?: meta.id], + gk, + ), + files, + ] + } + .groupTuple() + .map { meta, files -> + return [meta, files.flatten()] + } } diff --git a/subworkflows/local/fastq_align_rna/meta.yml b/subworkflows/local/fastq_align_rna/meta.yml new file mode 100644 index 00000000..e69de29b diff --git a/subworkflows/local/fastq_to_aligned_cram/main.nf b/subworkflows/local/fastq_to_aligned_cram/main.nf index ee57fd08..dfccf2d5 100644 --- a/subworkflows/local/fastq_to_aligned_cram/main.nf +++ b/subworkflows/local/fastq_to_aligned_cram/main.nf @@ -11,151 +11,146 @@ include { SAMTOOLS_SORMADUP } from "../../../modules/nf-core/samtools/sormad include { SAMTOOLS_SORT } from "../../../modules/nf-core/samtools/sort/main" // SUBWORKFLOWS -include { FASTQ_ALIGN_DNA } from '../../nf-core/fastq_align_dna/main' -include { FASTQ_ALIGN_RNA } from '../../local/fastq_align_rna/main' +include { FASTQ_ALIGN_DNA } from '../../nf-core/fastq_align_dna/main' +include { FASTQ_ALIGN_RNA } from '../../local/fastq_align_rna/main' // FUNCTIONS -include { getGenomeAttribute } from '../../local/utils_nfcore_preprocessing_pipeline' +include { getGenomeAttribute } from '../../local/utils_nfcore_preprocessing_pipeline' workflow FASTQ_TO_CRAM { take: - ch_meta_reads_aligner_index_fasta_gtf // channel: [mandatory] [meta, [fastq, ...], aligner [bowtie2, bwamem, bwamem2, dragmap, snap, star], aligner_index, fasta, gtf] - markdup // string: [optional ] markdup [bamsormadup, samtools, false] + ch_meta_reads_aligner_index_fasta_gtf // channel: [mandatory] [meta, [fastq, ...], aligner [bowtie2, bwamem, bwamem2, dragmap, snap, star], aligner_index, fasta, gtf] main: - - ch_versions = Channel.empty() - ch_multiqc_files = Channel.empty() - - /* - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // STEP: ALIGNMENT - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - - ch_meta_reads_aligner_index_fasta_gtf.dump(tag: "FASTQ_TO_CRAM: reads to align",pretty: true) - - ch_meta_reads_aligner_index_fasta_gtf - .branch { meta, reads, aligner, index, fasta, gtf -> - rna: meta.sample_type == "RNA" - return [meta, reads, "star", index, gtf] - dna: meta.sample_type == "DNA" || meta.sample_type == "Tissue" - return [meta, reads, aligner, index, fasta] - } - .set { ch_meta_reads_aligner_index_fasta_datatype } - - // align fastq files per sample - // ALIGNMENT([meta,fastq], index, sort) - FASTQ_ALIGN_DNA( - ch_meta_reads_aligner_index_fasta_datatype.dna, - false - ) - ch_versions = ch_versions.mix(FASTQ_ALIGN_DNA.out.versions) - - FASTQ_ALIGN_RNA( - ch_meta_reads_aligner_index_fasta_datatype.rna - ) - ch_versions = ch_versions.mix(FASTQ_ALIGN_DNA.out.versions) - - /* - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // STEP: MARK DUPLICATES - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - - FASTQ_ALIGN_DNA.out.bam + ch_sormadup_metrics = channel.empty() + + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // STEP: ALIGNMENT + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + + ch_meta_reads_aligner_index_fasta_gtf.dump(tag: "FASTQ_TO_CRAM: reads to align", pretty: true) + ch_meta_reads_aligner_index_fasta_gtf + .branch { meta, reads, aligner, index, fasta, gtf -> + rna: meta.sample_type == "RNA" + return [meta, reads, "star", getGenomeAttribute(meta.genome_data, 'star'), gtf] + dna: true + // catch all non-RNA samples as DNA, as some may be missing sample_type or have other sample types (e.g. tissue, cell line, etc.) that should be aligned with the DNA aligner + //dna: meta.sample_type == "DNA" || meta.sample_type == "Tissue" + return [meta, reads, aligner, index, fasta] + } + .set { ch_meta_reads_aligner_index_fasta_datatype } + + // align fastq files per sample + // ALIGNMENT([meta,fastq], index, sort) + FASTQ_ALIGN_DNA( + ch_meta_reads_aligner_index_fasta_datatype.dna, + false, + ) + FASTQ_ALIGN_RNA( + ch_meta_reads_aligner_index_fasta_datatype.rna + ) + + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // STEP: MARK DUPLICATES + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + + FASTQ_ALIGN_DNA.out.bam .mix(FASTQ_ALIGN_RNA.out.bam) - .map { - meta, files -> + .map { meta, files -> def gk = (meta.chunks as Integer ?: 1) return [ groupKey( - // Remove the chunk prefix from the id when present, remove readgroup and chunks from meta meta - meta.subMap('readgroup', 'chunks') + [id: meta.id ==~ /^\d{4}\..*$/ ? meta.id[5..-1] : meta.id], - gk + gk, ), - files + files, ] } - .groupTuple() // Group all files in the same lane - .map { - meta, files -> + .groupTuple() + .map { meta, files -> def gk = (meta.count as Integer ?: 1) return [ groupKey( - // drop count and set id to samplename meta - meta.subMap('count') + [id: meta.samplename ?: meta.id], - gk + gk, ), - files + files, ] } - .groupTuple() // Group all files from the same sample + .groupTuple() .map { meta, files -> - return [meta, files.flatten(), getGenomeAttribute(meta.genome_data, 'fasta')] + return [meta, files.flatten(), getGenomeAttribute(meta.genome_data, 'fasta'), getGenomeAttribute(meta.genome_data, 'fai')] } - .set{ch_bam_fasta} - ch_bam_fasta.dump(tag: "FASTQ_TO_CRAM: aligned bam per sample", pretty: true) + .dump(tag: "FASTQ_TO_CRAM: aligned bam per sample", pretty: true) + .branch { meta, files, fasta, fai -> + bamsormadup: meta.markdup == "bamsormadup" + return [meta, files, fasta, fai] + samtools: meta.markdup == "samtools" + return [meta, files, fasta, fai] + sort: meta.markdup == "false" || meta.markdup == false + return [meta, files, fasta, fai] + unknown: true + error("markdup option ${meta.markdup} not supported") + } + .set { ch_bam_fasta } - ch_markdup_index = Channel.empty() + ch_markdup_index = channel.empty() - if ( markdup == "bamsormadup") { - // BIOBAMBAM_BAMSORMADUP([meta, [bam, bam]], fasta) - BIOBAMBAM_BAMSORMADUP(ch_bam_fasta) - ch_markdup_index = ch_markdup_index.mix(BIOBAMBAM_BAMSORMADUP.out.bam.join(BIOBAMBAM_BAMSORMADUP.out.bam_index, failOnMismatch:true, failOnDuplicate:true)) - ch_multiqc_files = ch_multiqc_files.mix( BIOBAMBAM_BAMSORMADUP.out.metrics.map { meta, metrics -> return metrics} ) - ch_versions = ch_versions.mix(BIOBAMBAM_BAMSORMADUP.out.versions) - } - else if ( markdup == "samtools") { - SAMTOOLS_SORMADUP(ch_bam_fasta) - ch_markdup_index = ch_markdup_index.mix(SAMTOOLS_SORMADUP.out.cram.join(SAMTOOLS_SORMADUP.out.crai, failOnMismatch:true, failOnDuplicate:true)) - ch_multiqc_files = ch_multiqc_files.mix( SAMTOOLS_SORMADUP.out.metrics.map { meta, metrics -> return metrics} ) - ch_versions = ch_versions.mix(SAMTOOLS_SORMADUP.out.versions) - } - else if ( markdup == "false" || markdup == false) { - // Merge bam files and compress - // SAMTOOLS_SORT([meta, [bam, bam], fasta]) - SAMTOOLS_SORT(ch_bam_fasta) - ch_markdup_index = ch_markdup_index.mix(SAMTOOLS_SORT.out.cram.join(SAMTOOLS_SORT.out.crai, failOnMismatch:true, failOnDuplicate:true)) - ch_versions = ch_versions.mix(SAMTOOLS_SORT.out.versions) - } - else { - error "markdup: ${markdup} not supported" - } - ch_markdup_index.dump(tag: "FASTQ_TO_CRAM: postprocessed bam", pretty: true) + // BIOBAMBAM_BAMSORMADUP([meta, [bam, bam]], fasta, fai) + BIOBAMBAM_BAMSORMADUP(ch_bam_fasta.bamsormadup) + ch_markdup_index = ch_markdup_index.mix(BIOBAMBAM_BAMSORMADUP.out.bam.join(BIOBAMBAM_BAMSORMADUP.out.bam_index, failOnMismatch: true, failOnDuplicate: true)) + ch_sormadup_metrics = ch_sormadup_metrics.mix(BIOBAMBAM_BAMSORMADUP.out.metrics) + + // SAMTOOLS_SORMADUP([meta, [bam, bam]], fasta, fai) + SAMTOOLS_SORMADUP(ch_bam_fasta.samtools) + ch_markdup_index = ch_markdup_index.mix(SAMTOOLS_SORMADUP.out.cram.join(SAMTOOLS_SORMADUP.out.crai, failOnMismatch: true, failOnDuplicate: true)) + ch_sormadup_metrics = ch_sormadup_metrics.mix(SAMTOOLS_SORMADUP.out.metrics) + + // Merge bam files and compress + // SAMTOOLS_SORT([meta, [bam, bam], fasta],index_format) + SAMTOOLS_SORT(ch_bam_fasta.sort, "crai") + ch_markdup_index = ch_markdup_index.mix(SAMTOOLS_SORT.out.cram.join(SAMTOOLS_SORT.out.crai, failOnMismatch: true, failOnDuplicate: true)) + + ch_markdup_index.dump(tag: "FASTQ_TO_CRAM: postprocessed bam", pretty: true) - /* - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // COMPRESSION - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // COMPRESSION + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ - ch_markdup_index + ch_markdup_index .branch { meta, reads, index -> bam: reads.getExtension() == "bam" - return [meta, reads, index] + return [meta, reads, index] cram: reads.getExtension() == "cram" - return [meta, reads, index] + return [meta, reads, index] } - .set {ch_markdup_index} + .set { ch_markdup_index } - ch_markdup_index.bam + ch_markdup_index.bam .map { meta, bam, bai -> bam_bai: [meta, bam, bai, getGenomeAttribute(meta.genome_data, 'fasta'), getGenomeAttribute(meta.genome_data, 'fai')] } - .set {ch_bam_bai_fasta_fai} + .set { ch_bam_bai_fasta_fai } - SAMTOOLS_CONVERT(ch_bam_bai_fasta_fai) + SAMTOOLS_CONVERT(ch_bam_bai_fasta_fai) - ch_markdup_index.cram + ch_markdup_index.cram .mix( - SAMTOOLS_CONVERT.out.cram.join(SAMTOOLS_CONVERT.out.crai, failOnMismatch:true, failOnDuplicate:true) + SAMTOOLS_CONVERT.out.cram.join(SAMTOOLS_CONVERT.out.crai, failOnMismatch: true, failOnDuplicate: true) ) - .set{ch_cram_crai} - ch_cram_crai.dump(tag: "FASTQ_TO_CRAM: cram and crai", pretty: true) + .set { ch_cram_crai } + ch_cram_crai.dump(tag: "FASTQ_TO_CRAM: cram and crai", pretty: true) emit: - cram_crai = ch_cram_crai - multiqc_files = ch_multiqc_files - versions = ch_versions + cram_crai = ch_cram_crai + rna_splice_junctions = FASTQ_ALIGN_RNA.out.splice_junctions + rna_junctions = FASTQ_ALIGN_RNA.out.junctions + sormadup_metrics = ch_sormadup_metrics + align_reports = FASTQ_ALIGN_DNA.out.reports } diff --git a/subworkflows/local/fastq_to_aligned_cram/meta.yml b/subworkflows/local/fastq_to_aligned_cram/meta.yml new file mode 100644 index 00000000..e69de29b diff --git a/subworkflows/local/fastq_to_unaligned_cram/main.nf b/subworkflows/local/fastq_to_unaligned_cram/main.nf deleted file mode 100644 index 28bdcbfe..00000000 --- a/subworkflows/local/fastq_to_unaligned_cram/main.nf +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env nextflow - -// -// Take fastq; convert to ubam and compress - -// MODULES -include { SAMTOOLS_CAT } from '../../../modules/nf-core/samtools/cat/main' -include { SAMTOOLS_IMPORT } from "../../../modules/nf-core/samtools/import/main" -include { MD5SUM } from "../../../modules/nf-core/md5sum/main" - -workflow FASTQ_TO_UCRAM { - take: - ch_fastq // channel: [mandatory] [meta, [fastq, ...]] - - main: - - ch_versions = Channel.empty() - - /* - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // STEP: FASTQ TO BAM CONVERSION - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - - ch_fastq - .dump(tag: "FASTQ_TO_UCRAM: reads to convert",pretty: true) - - // SAMTOOLS_IMPORT([meta, fastq]) - SAMTOOLS_IMPORT(ch_fastq) - ch_versions = ch_versions.mix(SAMTOOLS_IMPORT.out.versions) - - SAMTOOLS_IMPORT.out.cram - .map { - // set id to samplename, drop readgroup and count meta values - meta, files -> - def gk = (meta.chunks as Integer ?: 1) - return [ - groupKey( - // replace id by samplename, drop readgroup meta and chunks - meta - meta.subMap('id', 'readgroup', 'chunks') + [id: meta.samplename ? meta.samplename + ".unaligned" : meta.id + ".unaligned"], - gk - ), - files - ] - } - .groupTuple(by:[0]) - .dump(tag: "FASTQ_TO_UCRAM: unaligned cram per replicate",pretty: true) - .map { - meta, files -> - def gk = (meta.count as Integer ?: 1) - return [ - groupKey( - // drop count - meta - meta.subMap('count'), - gk - ), - files - ] - } - .groupTuple(by:[0]) - .map { meta, files -> - return [meta, files.flatten()] - } - .dump(tag: "FASTQ_TO_UCRAM: unaligned cram per sample",pretty: true) - .set{ch_ubam_per_sample} - - // Merge bam files per sample - SAMTOOLS_CAT(ch_ubam_per_sample) - ch_versions = ch_versions.mix(SAMTOOLS_CAT.out.versions) - - emit: - cram = SAMTOOLS_CAT.out.cram // [meta, cram] - versions = ch_versions // versions - -} diff --git a/subworkflows/local/utils_nfcmgg_preprocessing_pipeline/main.nf b/subworkflows/local/utils_nfcmgg_preprocessing_pipeline/main.nf new file mode 100644 index 00000000..a20d0849 --- /dev/null +++ b/subworkflows/local/utils_nfcmgg_preprocessing_pipeline/main.nf @@ -0,0 +1,95 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// Mock subworkflow to please linting +workflow UTILS_NFCMGG_PREPROCESSING_PIPELINE { +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// Generate readgroup information from FASTQ header +// +def getReadgroupFromFastq(fastq, SM, LB, CN) { + // expected format: + // xx:yy:FLOWCELLID:LANE:... (seven fields) + // or + // FLOWCELLID:LANE:xx:... (five fields) + def line + fastq.withInputStream { fq -> + def isGzip = fastq.name.toString().endsWith('.gz') + def stream = isGzip ? new java.util.zip.GZIPInputStream(fq) as InputStream : fq as InputStream + def decoder = new InputStreamReader(stream, 'ASCII') + def buffered = new BufferedReader(decoder) + line = buffered.readLine() + } + assert line.startsWith('@') + line = line.substring(1) + def fields = line.split(':') + def rg = [:] + rg.LB = LB ?: '' + rg.CN = CN ?: '' + rg.PL = 'ILLUMINA' + rg.SM = SM ?: fastq.name.toString() - ~/_R[0-9]_001.*$/ + if (fields.size() >= 7) { + // CASAVA 1.8+ format, from https://support.illumina.com/help/BaseSpace_OLH_009008/Content/Source/Informatics/BS/FileFormat_FASTQ-files_swBS.htm + // "@::::::: :::" + // def sequencer_serial = fields[0] + // def run_number = fields[1] + def fcid = fields[2] + def lane = fields[3] + def index = fields[-1] ==~ /^[GATCN+-]+$/ ? fields[-1] : '' + rg.ID = [index ?: fcid, lane].join('.') + rg.PU = [fcid, lane].join('.') + } + else if (fields.size() == 5) { + def fcid = fields[0] + def lane = fields[1] + rg.ID = [fcid, lane].join('.') + rg.PU = [fcid, lane].join('.') + } + return rg +} + +// +// Generate readgroup from bclconvert outputs +// +def getReadgroupsFromBclconvert(ch_fastq_list_csv, ch_fastq) { + return ch_fastq_list_csv + .join(ch_fastq, by: [0]) + .map { meta, csv_file, fastq_list -> + def meta_fastq = [] + csv_file + .splitCsv(header: true) + .each { row -> + // Create the readgroup tuple + // RGID,RGSM,RGLB,Lane,Read1File,Read2File + def rg = [:] + // row.RGID is index1.index2.lane + rg.ID = row.RGID + // RGPU is a custom column in the samplesheet containing the flowcell ID + rg.PU = row.RGPU ? row.RGPU : meta.id + "." + row.Lane + rg.SM = row.RGSM + rg.LB = row.RGLB ? row.RGLB : "" + rg.PL = "ILLUMINA" + + // dereference the fastq files in the csv + def fastq1 = fastq_list.find { fq -> file(fq).name == file(row.Read1File).name } + def fastq2 = row.Read2File ? fastq_list.find { fq -> file(fq).name == file(row.Read2File).name } : null + + // set fastq metadata + def new_meta = meta + [id: fastq1.getSimpleName().toString() - ~/_R[0-9]_001.*$/, readgroup: rg, single_end: !fastq2] + + meta_fastq << [new_meta, fastq2 ? [fastq1, fastq2] : [fastq1]] + } + return meta_fastq + } + .flatMap() +} diff --git a/subworkflows/local/utils_nfcmgg_preprocessing_pipeline/meta.yml b/subworkflows/local/utils_nfcmgg_preprocessing_pipeline/meta.yml new file mode 100644 index 00000000..e69de29b diff --git a/subworkflows/local/utils_nfcore_preprocessing_pipeline/main.nf b/subworkflows/local/utils_nfcore_preprocessing_pipeline/main.nf index f80a2639..d7b7103b 100644 --- a/subworkflows/local/utils_nfcore_preprocessing_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_preprocessing_pipeline/main.nf @@ -1,5 +1,5 @@ // -// Subworkflow with functionality specific to the nf-core/pipeline pipeline +// Subworkflow with functionality specific to the nf-cmgg/preprocessing pipeline // /* @@ -8,120 +8,130 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' -include { paramsSummaryMap } from 'plugin/nf-schema' -include { samplesheetToList } from 'plugin/nf-schema' -include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' -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_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' +include { paramsHelp } from 'plugin/nf-schema' +include { completionEmail } from '../../nf-core/utils_nfcore_pipeline' +include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' +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 { - take: - version // boolean: Display version and exit - validate_params // boolean: Boolean whether to validate parameters against the schema at runtime + version // boolean: Display version and exit + validate_params // boolean: Boolean whether to validate parameters against the schema at runtime nextflow_cli_args // array: List of positional nextflow CLI args - outdir // string: The output directory where the results will be saved - input // string: Path to input samplesheet + outdir // string: The output directory where the results will be saved + input // string: Path to input samplesheet + help // boolean: Display help message and exit + help_full // boolean: Show the full help message + show_hidden // boolean: Show hidden parameters in the help message main: - ch_versions = Channel.empty() - // // Print version and exit if required and dump pipeline parameters to JSON file // - UTILS_NEXTFLOW_PIPELINE ( + UTILS_NEXTFLOW_PIPELINE( version, true, outdir, - workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1 + workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1, ) // // Validate parameters and generate parameter summary to stdout // - UTILS_NFSCHEMA_PLUGIN ( + command = "nextflow run ${workflow.manifest.name} -profile --input samplesheet.csv --outdir " + + UTILS_NFSCHEMA_PLUGIN( workflow, validate_params, - null + null, + help, + help_full, + show_hidden, + "", + "", + command, ) // // Check config provided to the pipeline // - UTILS_NFCORE_PIPELINE ( + UTILS_NFCORE_PIPELINE( nextflow_cli_args ) + // // Custom validation for pipeline parameters // - //validateInputParameters() + validateInputParameters() // // Create channel from input file provided through params.input // - Channel - .fromList(samplesheetToList(input, "assets/schema_input.json")) + channel.fromList(samplesheetToList(input, "assets/schema_input.json")) .set { ch_samplesheet } emit: samplesheet = ch_samplesheet - versions = ch_versions } /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SUBWORKFLOW FOR PIPELINE COMPLETION -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ workflow PIPELINE_COMPLETION { - take: - email // string: email address - email_on_fail // string: email address sent on pipeline failure + 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 + 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 + multiqc_report // string: Path to MultiQC report main: - summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") + def multiqc_reports = multiqc_report.toList() // // Completion email and summary // 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_reports.getVal(), + ) } completionSummary(monochrome_logs) + } - if (hook_url) { - imNotification(summary_params, hook_url) - } + workflow.onError { + log.error("Pipeline failed. Please refer to troubleshooting docs: https://nf-co.re/docs/usage/troubleshooting") } } /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FUNCTIONS -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ // // Check and validate pipeline parameters @@ -137,22 +147,19 @@ 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{ meta -> meta.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}") } - return [ metas[0], fastqs ] + return [metas[0], fastqs] } - // // Get attribute from genome config file e.g. fasta // -def getGenomeAttribute(genome, attribute) { - if (genome instanceof Map && genome.containsKey(attribute)) { - return nextflow.Nextflow.file(genome[attribute], checkIfExists: true) - } else { - nextflow.Nextflow.error("Genome config does not contain attribute ${attribute}") +def getGenomeAttribute(genomes, attribute) { + if (genomes && genomes.containsKey(attribute)) { + return genomes[attribute] } return null } @@ -162,15 +169,10 @@ def getGenomeAttribute(genome, attribute) { // def genomeExistsError() { if (params.genomes && params.genome && !params.genomes.containsKey(params.genome)) { - def error_string = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + - " Genome '${params.genome}' not found in any config files provided to the pipeline.\n" + - " Currently, the available genome keys are:\n" + - " ${params.genomes.keySet().join(", ")}\n" + - "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + def error_string = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " Genome '${params.genome}' not found in any config files provided to the pipeline.\n" + " Currently, the available genome keys are:\n" + " ${params.genomes.keySet().join(", ")}\n" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" error(error_string) } } - // // Generate methods description for MultiQC // @@ -179,9 +181,11 @@ def toolCitationText() { // Can use ternary operators to dynamically construct based conditions, e.g. params["run_xyz"] ? "Tool (Foo et al. 2023)" : "", // Uncomment function in methodsDescriptionText to render in MultiQC report def citation_text = [ - "Tools used in the workflow included:", - "MultiQC (Ewels et al. 2016)", - ].join(' ').trim() + "Tools used in the workflow included:", + "FastQC (Andrews 2010),", + "MultiQC (Ewels et al. 2016)", + ".", + ].join(' ').trim() return citation_text } @@ -191,8 +195,9 @@ def toolBibliographyText() { // Can use ternary operators to dynamically construct based conditions, e.g. params["run_xyz"] ? "
  • Author (2023) Pub name, Journal, DOI
  • " : "", // Uncomment function in methodsDescriptionText to render in MultiQC report def reference_text = [ - "
  • Ewels, P., Magnusson, M., Lundin, S., & Käller, M. (2016). MultiQC: summarize analysis results for multiple tools and samples in a single report. Bioinformatics , 32(19), 3047–3048. doi: /10.1093/bioinformatics/btw354
  • ", - ].join(' ').trim() + "
  • Andrews S, (2010) FastQC, URL: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/).
  • ", + "
  • Ewels, P., Magnusson, M., Lundin, S., & Käller, M. (2016). MultiQC: summarize analysis results for multiple tools and samples in a single report. Bioinformatics , 32(19), 3047–3048. doi: /10.1093/bioinformatics/btw354
  • ", + ].join(' ').trim() return reference_text } @@ -214,7 +219,10 @@ def methodsDescriptionText(mqc_methods_yaml) { 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"] = "" + } + 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.
  • " // Tool references @@ -228,7 +236,7 @@ def methodsDescriptionText(mqc_methods_yaml) { def methods_text = mqc_methods_yaml.text - def engine = new groovy.text.SimpleTemplateEngine() + def engine = new groovy.text.SimpleTemplateEngine() def description_html = engine.createTemplate(methods_text).make(meta) return description_html.toString() diff --git a/subworkflows/local/utils_nfcore_preprocessing_pipeline/meta.yml b/subworkflows/local/utils_nfcore_preprocessing_pipeline/meta.yml new file mode 100644 index 00000000..e69de29b diff --git a/subworkflows/nf-core/bcl_demultiplex/main.nf b/subworkflows/nf-core/bcl_demultiplex/main.nf deleted file mode 100644 index 5526fc41..00000000 --- a/subworkflows/nf-core/bcl_demultiplex/main.nf +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env nextflow - -// -// Demultiplex Illumina BCL data using bcl-convert or bcl2fastq -// - -include { BCLCONVERT } from "../../../modules/nf-core/bclconvert/main" -include { BCL2FASTQ } from "../../../modules/nf-core/bcl2fastq/main" - -workflow BCL_DEMULTIPLEX { - take: - ch_flowcell // [[id:"", lane:""], samplesheet.csv, path/to/bcl/files] - demultiplexer // bclconvert or bcl2fastq - - main: - ch_versions = Channel.empty() - ch_fastq = Channel.empty() - ch_reports = Channel.empty() - ch_stats = Channel.empty() - ch_interop = Channel.empty() - - // Split flowcells into separate channels containing run as tar and run as path - // https://nextflow.slack.com/archives/C02T98A23U7/p1650963988498929 - ch_flowcell - .branch { _meta, _samplesheet, run -> - tar: run.toString().endsWith(".tar.gz") - dir: true - }.set { ch_flowcells } - - ch_flowcells.tar - .multiMap { meta, samplesheet, run -> - samplesheets: [ meta, samplesheet ] - run_dirs: [ meta, run ] - }.set { ch_flowcells_tar } - - // Runs when run_dir is a tar archive - // Re-join the metadata and the untarred run directory with the samplesheet - ch_flowcells_tar_merged = ch_flowcells_tar - .samplesheets - .join( ch_flowcells_tar.run_dirs ) - - // Merge the two channels back together - ch_flowcells = ch_flowcells.dir.mix(ch_flowcells_tar_merged) - - // MODULE: bclconvert - // Demultiplex the bcl files - if (demultiplexer == "bclconvert") { - BCLCONVERT( ch_flowcells ) - ch_fastq = ch_fastq.mix(BCLCONVERT.out.fastq) - ch_interop = ch_interop.mix(BCLCONVERT.out.interop) - ch_reports = ch_reports.mix(BCLCONVERT.out.reports) - ch_versions = ch_versions.mix(BCLCONVERT.out.versions) - } - - // MODULE: bcl2fastq - // Demultiplex the bcl files - if (demultiplexer == "bcl2fastq") { - BCL2FASTQ( ch_flowcells ) - ch_fastq = ch_fastq.mix(BCL2FASTQ.out.fastq) - ch_interop = ch_interop.mix(BCL2FASTQ.out.interop) - ch_reports = ch_reports.mix(BCL2FASTQ.out.reports) - ch_stats = ch_stats.mix(BCL2FASTQ.out.stats) - ch_versions = ch_versions.mix(BCL2FASTQ.out.versions) - } - - // Generate meta for each fastq - ch_fastq - // reshapes the channel from a single emit of [meta, [fastq, fastq, fastq...]] - // to emits per fastq file like [meta, fastq] - .transpose() - .map { fc_meta, fastq -> - def meta = [:] - meta.id = fastq.getSimpleName().toString() - ~/_R[0-9]_001.*$/ - meta.samplename = fastq.getSimpleName().toString() - ~/_S[0-9]+.*$/ - meta.fcid = fc_meta.id - meta.lane = fc_meta.lane - // The buffered input stream allows reading directly from cloud storage - // It will not make a local copy of the file. - def line = "" - fastq.withInputStream { fq -> - def gzipStream = new java.util.zip.GZIPInputStream(fq) - def decoder = new InputStreamReader(gzipStream, 'ASCII') - def buffered = new BufferedReader(decoder) - line = buffered.readLine() - buffered.close() - } - if ( line != null && line.startsWith('@') ) { - line = line.substring(1) - // expected format is like: - // xx:yy:FLOWCELLID:LANE:... (seven fields) - def fields = line.split(':') - // CASAVA 1.8+ format, from https://support.illumina.com/help/BaseSpace_OLH_009008/Content/Source/Informatics/BS/FileFormat_FASTQ-files_swBS.htm - // "@::::::: :::" - //def sequencer_serial = fields[0] - //def run_nubmer = fields[1] - def fcid = fields[2] - def lane = fields[3] - def index = fields[-1] =~ /[GATC+-]/ ? fields[-1] : "" - def ID = [fcid, lane].join(".") - def PU = [fcid, lane, index].findAll().join(".") - def PL = "ILLUMINA" - def SM = fastq.getSimpleName().toString() - ~/_S[0-9]+.*$/ - meta.readgroup = [ - "ID": ID, - "SM": SM, - "PL": PL, - "PU": PU - ] - meta.empty = false - } else { - println "No reads were found in FASTQ file: ${fastq}" - meta.readgroup = [:] - meta.empty = true - } - return [meta, fastq] - } - // Group by the meta id so that we can find mate pairs if they exist - .groupTuple(by: [0]) - .map { meta, fastq -> - meta.single_end = fastq.size() == 1 - return [meta, fastq.flatten()] - } - .branch { - fastq : it[0].empty == false - empty_fastq : it[0].empty == true - } - .set{ch_fastq_with_meta} - - emit: - fastq = ch_fastq_with_meta.fastq - empty_fastq = ch_fastq_with_meta.empty_fastq - reports = ch_reports - stats = ch_stats - interop = ch_interop - versions = ch_versions -} diff --git a/subworkflows/nf-core/bcl_demultiplex/meta.yml b/subworkflows/nf-core/bcl_demultiplex/meta.yml deleted file mode 100644 index 2fc8f7aa..00000000 --- a/subworkflows/nf-core/bcl_demultiplex/meta.yml +++ /dev/null @@ -1,58 +0,0 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json -name: "bcl_demultiplex" -description: Demultiplex Illumina BCL data using bcl-convert or bcl2fastq -keywords: - - bcl - - bclconvert - - bcl2fastq - - demultiplex - - fastq -components: - - bcl2fastq - - bclconvert -input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'string', lane: int ] - - samplesheet: - type: file - description: | - CSV file containing information about samples to be demultiplexed in Illumina SampleSheet format - - flowcell: - type: file - description: Directory or tar archive containing Illumina BCL data, sequencer output directory - - demultiplexer: - type: string - description: Which demultiplexer to use, bcl2fastq or bclconvert -output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test' ] - - fastq: - type: file - description: Demultiplexed fastq files - pattern: "*.fastq.gz" - - reports: - type: file - description: Demultiplexing reports - pattern: "Reports/*" - - interop: - type: file - description: InterOp files - pattern: "InterOp/*" - - stats: - type: file - description: Demultiplexing statistics (bcl2fastq only) - pattern: "Stats/*" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" -authors: - - "@matthdsm" -maintainers: - - "@matthdsm" diff --git a/subworkflows/nf-core/bcl_demultiplex/tests/main.nf.test b/subworkflows/nf-core/bcl_demultiplex/tests/main.nf.test deleted file mode 100644 index 838a56cf..00000000 --- a/subworkflows/nf-core/bcl_demultiplex/tests/main.nf.test +++ /dev/null @@ -1,79 +0,0 @@ -// nf-core subworkflows test bcl_demultiplex -nextflow_workflow { - - name "Test Subworkflow test_bcl_demultiplex_bclconvert" - script "../main.nf" - config "./nextflow.config" - workflow "BCL_DEMULTIPLEX" - - tag "subworkflows" - tag "subworkflows_nfcore" - tag "subworkflows/bcl_demultiplex" - tag "bclconvert" - tag "bcl2fastq" - - test("bclconvert") { - - when { - - workflow { - """ - input[0] = Channel.value([ - [id:'HMTFYDRXX', lane:1], - "https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/sarscov2/illumina/bcl/SampleSheet.csv", - "https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/sarscov2/illumina/bcl/200624_A00834_0183_BHMTFYDRXX.tar.gz" - ]) - input[1] = "bclconvert" - """ - } - } - - then { - assertAll( - { assert workflow.success }, - { assert snapshot( - workflow.out.reports, - workflow.out.versions, - workflow.out.fastq, - workflow.out.stats, - workflow.out.interop.get(0).get(1).findAll { file(it).name != "IndexMetricsOut.bin" }, - ).match() - }, - { assert file(workflow.out.interop.get(0).get(1).find { file(it).name == "IndexMetricsOut.bin" }).exists() }, - { assert file(workflow.out.empty_fastq.get(0).get(1).find { file(it).name == "SampleZ_S5_L001_R1_001.fastq.gz" }).exists() } - ) - } - } - - test("bcl2fastq") { - - when { - - workflow { - """ - input[0] = Channel.value([ - [id:'test', lane:1 ], - "https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/homo_sapiens/illumina/bcl/flowcell_samplesheet.csv", - "https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/homo_sapiens/illumina/bcl/flowcell.tar.gz" - ]) - input[1] = "bcl2fastq" - """ - } - } - - then { - assertAll( - { assert workflow.success }, - { assert snapshot( - workflow.out.reports, - workflow.out.versions, - workflow.out.fastq, - workflow.out.stats, - workflow.out.interop.get(0).get(1).findAll { file(it).name != "IndexMetricsOut.bin" }, - ).match() - }, - { assert file(workflow.out.interop.get(0).get(1).find { file(it).name == "IndexMetricsOut.bin" }).exists() } - ) - } - } -} diff --git a/subworkflows/nf-core/bcl_demultiplex/tests/main.nf.test.snap b/subworkflows/nf-core/bcl_demultiplex/tests/main.nf.test.snap deleted file mode 100644 index 88cc0e93..00000000 --- a/subworkflows/nf-core/bcl_demultiplex/tests/main.nf.test.snap +++ /dev/null @@ -1,240 +0,0 @@ -{ - "bclconvert": { - "content": [ - [ - [ - { - "id": "HMTFYDRXX", - "lane": 1 - }, - [ - "Adapter_Cycle_Metrics.csv:md5,05fbe7b2b0acdd557d355b448aa88ace", - "Adapter_Metrics.csv:md5,0fa4ac708955417af9d18cec4955552f", - "Demultiplex_Stats.csv:md5,4a3f451faa098156623b55b0f2ff27ee", - "Demultiplex_Tile_Stats.csv:md5,8f6fb58990572c4aa19c0100d8351484", - "IndexMetricsOut.bin:md5,fb16c8a9873e5b5950ae5949126af76c", - "Index_Hopping_Counts.csv:md5,f59474d96afe8218c7590bb240b19690", - "Quality_Metrics.csv:md5,c4622066f85d93b1661c928a46cfc508", - "Quality_Tile_Metrics.csv:md5,e22bc5e2f147695150b02afcccb38c4f", - "RunInfo.xml:md5,f283cb4600235db9261ee1e319b1407e", - "SampleSheet.csv:md5,4113eabae23136cc819c7f15ac5b6aad", - "Top_Unknown_Barcodes.csv:md5,37dbc2860c640fc721820b0217ea0504", - "fastq_list.csv:md5,482cf7fe9b304a900e4ede3bb25b4912" - ] - ] - ], - [ - "versions.yml:md5,d5d640ea998880b16202e0989b6e3926" - ], - [ - [ - { - "id": "Sample1_S1_L001", - "samplename": "Sample1", - "fcid": "HMTFYDRXX", - "lane": 1, - "readgroup": { - "ID": "HMTFYDRXX.1", - "SM": "Sample1", - "PL": "ILLUMINA", - "PU": "HMTFYDRXX.1.GAACTGAGCG+TCGTGGAGCG" - }, - "empty": false, - "single_end": true - }, - [ - "Sample1_S1_L001_R1_001.fastq.gz:md5,b5489d1964db8db5502eb742cc3ef3ec" - ] - ], - [ - { - "id": "Sample23_S3_L001", - "samplename": "Sample23", - "fcid": "HMTFYDRXX", - "lane": 1, - "readgroup": { - "ID": "HMTFYDRXX.1", - "SM": "Sample23", - "PL": "ILLUMINA", - "PU": "HMTFYDRXX.1.CGTCTCATAT+TATAGTAGCT" - }, - "empty": false, - "single_end": true - }, - [ - "Sample23_S3_L001_R1_001.fastq.gz:md5,767a1091320320b140288066e29bccc5" - ] - ], - [ - { - "id": "SampleA_S2_L001", - "samplename": "SampleA", - "fcid": "HMTFYDRXX", - "lane": 1, - "readgroup": { - "ID": "HMTFYDRXX.1", - "SM": "SampleA", - "PL": "ILLUMINA", - "PU": "HMTFYDRXX.1.AGGTCAGATA+CTACAAGATA" - }, - "empty": false, - "single_end": true - }, - [ - "SampleA_S2_L001_R1_001.fastq.gz:md5,7de2ea88133409f34563f40a0d8c9e55" - ] - ], - [ - { - "id": "sampletest_S4_L001", - "samplename": "sampletest", - "fcid": "HMTFYDRXX", - "lane": 1, - "readgroup": { - "ID": "HMTFYDRXX.1", - "SM": "sampletest", - "PL": "ILLUMINA", - "PU": "HMTFYDRXX.1.ATTCCATAAG+TGCCTGGTGG" - }, - "empty": false, - "single_end": true - }, - [ - "sampletest_S4_L001_R1_001.fastq.gz:md5,c16c7de1b7bffb5e4503f4d94c40f881" - ] - ] - ], - [ - - ], - [ - "BasecallingMetricsOut.bin:md5,7fb651325cba614d497d376eaf43fef4", - "CorrectedIntMetricsOut.bin:md5,dc8d57282ba9ece9e5fc58a92aa2ac52", - "EmpiricalPhasingMetricsOut.bin:md5,1ef4631faf0a3a3beb31b10fc38a734d", - "EventMetricsOut.bin:md5,dee320ce29bdadde44589aa9439f53ab", - "ExtendedTileMetricsOut.bin:md5,f01d1a9cf8445adf719e652ad7304cf2", - "ExtractionMetricsOut.bin:md5,972f4082ad950baaf42a6d28517d28a8", - "FWHMGridMetricsOut.bin:md5,6e297bafcd845bfd0440d08e1bb27685", - "ImageMetricsOut.bin:md5,ac5d1f0a1f611c0c7c9dd8e6b9e701b1", - "OpticalModelMetricsOut.bin:md5,3eaea5fcf2d353950b1e720c73695ccb", - "PFGridMetricsOut.bin:md5,ae469858ee96ffafbcaf3afb814bdab2", - "QMetrics2030Out.bin:md5,438248760db58917b32f4eccc6c64c39", - "QMetricsByLaneOut.bin:md5,e8254cb4a27846710a2a143296be2d8f", - "QMetricsOut.bin:md5,8f6b83028a42be721200a598161ac5c6", - "RegistrationMetricsOut.bin:md5,b5ebd957aed067b6403d851ba2ce0139", - "TileMetricsOut.bin:md5,21388348d81fa9be326d30ef6d348464" - ] - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-06-02T12:35:59.918717" - }, - "bcl2fastq": { - "content": [ - [ - [ - { - "id": "test", - "lane": 1 - }, - [ - [ - [ - [ - [ - [ - "lane.html:md5,794e48287f47a9f22dcb6b6d0c22c3eb", - "laneBarcode.html:md5,2bbdae3ee57151eab520c966597d7438" - ], - [ - - ] - ] - ], - [ - [ - [ - "lane.html:md5,f741870307050dcea79a838f5971770f", - "laneBarcode.html:md5,ffe2e863811c76cb9da27d5d124e0611" - ], - [ - "lane.html:md5,cca97e771d3491dbc8cd3fe389595b09", - "laneBarcode.html:md5,cca97e771d3491dbc8cd3fe389595b09" - ] - ], - [ - [ - "lane.html:md5,c383b0768d9978733d3f5d3b91c15af0", - "laneBarcode.html:md5,48842c23b9a2816aec540177df870968" - ], - [ - - ] - ] - ] - ], - "Report.css:md5,eb7d3eb68fc1539f411404987246b59b", - "index.html:md5,5747c407854ae2c358d0ec201ce622d8", - "tree.html:md5,a1b9bf592973ca829ec69ddf888b7e34" - ] - ] - ] - ], - [ - "versions.yml:md5,513271615cb02dbe541a6202d713ef81" - ], - [ - [ - { - "id": "Sample1_S1_L001", - "samplename": "Sample1", - "fcid": "test", - "lane": 1, - "readgroup": { - "ID": "000000000-K9H97.1", - "SM": "Sample1", - "PL": "ILLUMINA", - "PU": "000000000-K9H97.1" - }, - "empty": false, - "single_end": true - }, - [ - "Sample1_S1_L001_R1_001.fastq.gz:md5,0675fb6365322eaafb33c0f8e862b54b" - ] - ] - ], - [ - [ - { - "id": "test", - "lane": 1 - }, - [ - "AdapterTrimming.txt:md5,48ed2b914b1246c0b5d8667525550946", - "ConversionStats.xml:md5,8fe0f57f3f5d256a0762dba75ac62d05", - "DemultiplexingStats.xml:md5,2047ff18f5b9107c084de06e9ff943ad", - "DemuxSummaryF1L1.txt:md5,03e5fd0c1e3079c5f8c7b4d0501b37ff", - "FastqSummaryF1L1.txt:md5,0c6f2d87ee183b84d1051cde9a5643d1", - "Stats.json:md5,8e5f038b8aa9e465599d3575f930e604" - ] - ] - ], - [ - "ControlMetricsOut.bin:md5,6d77b38d0793a6e1ce1e85706e488953", - "CorrectedIntMetricsOut.bin:md5,2bbf84d3be72734addaa2fe794711434", - "ErrorMetricsOut.bin:md5,38c88def138e9bb832539911affdb286", - "ExtractionMetricsOut.bin:md5,7497c3178837eea8f09350b5cd252e99", - "QMetricsOut.bin:md5,7e9f198d53ebdfbb699a5f94cf1ed51c", - "TileMetricsOut.bin:md5,83891751ec1c91a425a524b476b6ca3c" - ] - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-05T13:35:57.172636143" - } -} \ No newline at end of file diff --git a/subworkflows/nf-core/bcl_demultiplex/tests/nextflow.config b/subworkflows/nf-core/bcl_demultiplex/tests/nextflow.config deleted file mode 100644 index dd8bfa2a..00000000 --- a/subworkflows/nf-core/bcl_demultiplex/tests/nextflow.config +++ /dev/null @@ -1,13 +0,0 @@ -process { - withName: BCLCONVERT { - ext.args = {[ - meta.lane ? "--bcl-only-lane ${meta.lane}" : "", - "--force" - ].join(" ").trim()} - } - withName: BCL2FASTQ { - ext.args = {[ - "--tiles s_1_1101" - ].join(" ").trim()} - } -} diff --git a/subworkflows/nf-core/fastq_align_dna/fastq_align_dna.diff b/subworkflows/nf-core/fastq_align_dna/fastq_align_dna.diff new file mode 100644 index 00000000..2f585e04 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_dna/fastq_align_dna.diff @@ -0,0 +1,116 @@ +Changes in component 'nf-core/fastq_align_dna' +'subworkflows/nf-core/fastq_align_dna/meta.yml' is unchanged +Changes in 'fastq_align_dna/main.nf': +--- subworkflows/nf-core/fastq_align_dna/main.nf ++++ subworkflows/nf-core/fastq_align_dna/main.nf +@@ -16,53 +16,64 @@ + + workflow FASTQ_ALIGN_DNA { + take: +- ch_reads // channel: [mandatory] meta, reads +- ch_aligner_index // channel: [mandatory] aligner index +- ch_fasta // channel: [mandatory] fasta file +- aligner // string: [mandatory] aligner [bowtie2, bwamem, bwamem2, dragmap, snap] +- sort // boolean: [mandatory] true -> sort, false -> don't sort ++ ch_reads_aligner_index_fasta // channel: [mandatory] reads, aligner, index, fasta ++ sort // boolean: [mandatory] true -> sort, false -> don't sort + + main: + +- ch_bam_index = channel.empty() +- ch_bam = channel.empty() +- ch_reports = channel.empty() ++ ch_bam_index = channel.empty() ++ ch_bam = channel.empty() ++ ch_reports = channel.empty() + +- // Align fastq files to reference genome and (optionally) sort +- if (aligner == 'bowtie2') { +- BOWTIE2_ALIGN(ch_reads, ch_aligner_index, ch_fasta, false, sort) // if aligner is bowtie2 +- ch_bam = ch_bam.mix(BOWTIE2_ALIGN.out.bam) ++ ch_reads_aligner_index_fasta ++ .branch { meta, reads, aligner, index, fasta -> ++ bowtie2: aligner == 'bowtie2' ++ return [meta, reads, index, fasta] ++ bwamem: aligner == 'bwamem' ++ return [meta, reads, index, fasta] ++ bwamem2: aligner == 'bwamem2' ++ return [meta, reads, index, fasta] ++ dragmap: aligner == 'dragmap' ++ return [meta, reads, index, fasta] ++ snap: aligner == 'snap' ++ return [meta, reads, index] ++ strobe: aligner == 'strobe' ++ return [meta, reads, fasta, index] ++ other: true + } +- else if (aligner == 'bwamem'){ +- BWAMEM1_MEM (ch_reads, ch_aligner_index, ch_fasta, sort) // If aligner is bwa-mem +- ch_bam = ch_bam.mix(BWAMEM1_MEM.out.bam) +- ch_bam_index = ch_bam_index.mix(BWAMEM1_MEM.out.csi) +- } +- else if (aligner == 'bwamem2'){ +- BWAMEM2_MEM (ch_reads, ch_aligner_index, ch_fasta, sort) // If aligner is bwa-mem2 +- ch_bam = ch_bam.mix(BWAMEM2_MEM.out.bam) +- } +- else if (aligner == 'dragmap'){ +- DRAGMAP_ALIGN(ch_reads, ch_aligner_index, ch_fasta, sort) // If aligner is dragmap +- ch_bam = ch_bam.mix(DRAGMAP_ALIGN.out.bam) +- ch_reports = ch_reports.mix(DRAGMAP_ALIGN.out.log) +- } +- else if (aligner == 'snap'){ +- SNAP_ALIGN (ch_reads, ch_aligner_index) // If aligner is snap +- ch_bam = ch_bam.mix(SNAP_ALIGN.out.bam) +- ch_bam_index.mix(SNAP_ALIGN.out.bai) +- } +- else if (aligner == 'strobealign'){ +- STROBEALIGN (ch_reads, ch_fasta, ch_aligner_index, sort) // If aligner is strobealign +- ch_bam = ch_bam.mix(STROBEALIGN.out.bam) +- ch_bam_index = ch_bam_index.mix(STROBEALIGN.out.csi) +- } +- else { +- error "Unknown aligner: ${aligner}" +- } ++ .set { ch_to_align } ++ ++ // Throw error for all samples with unsupported aligners ++ ch_to_align.other.map { meta, _reads, aligner, _index, _fasta -> ++ error("Unsupported aligner ${aligner} for sample ${meta.id}") ++ } ++ ++ // Align fastq files to reference genome and (optionally) sort ++ BOWTIE2_ALIGN(ch_to_align.bowtie2, false, sort) ++ // if aligner is bowtie2 ++ ch_bam = ch_bam.mix(BOWTIE2_ALIGN.out.bam) ++ BWAMEM1_MEM(ch_to_align.bwamem, sort) ++ // If aligner is bwa-mem ++ ch_bam = ch_bam.mix(BWAMEM1_MEM.out.bam) ++ ch_bam_index = ch_bam_index.mix(BWAMEM1_MEM.out.csi) ++ BWAMEM2_MEM(ch_to_align.bwamem2, sort) ++ // If aligner is bwa-mem2 ++ ch_bam = ch_bam.mix(BWAMEM2_MEM.out.bam) ++ DRAGMAP_ALIGN(ch_to_align.dragmap, sort) ++ // If aligner is dragmap ++ ch_bam = ch_bam.mix(DRAGMAP_ALIGN.out.bam) ++ ch_reports = ch_reports.mix(DRAGMAP_ALIGN.out.log) ++ SNAP_ALIGN(ch_to_align.snap) ++ // If aligner is snap ++ ch_bam = ch_bam.mix(SNAP_ALIGN.out.bam) ++ ch_bam_index.mix(SNAP_ALIGN.out.bai) ++ STROBEALIGN(ch_to_align.strobe, sort) ++ // If aligner is strobealign ++ ch_bam = ch_bam.mix(STROBEALIGN.out.bam) ++ ch_bam_index = ch_bam_index.mix(STROBEALIGN.out.csi) + + emit: +- bam = ch_bam // channel: [ [meta], bam ] +- bam_index = ch_bam_index // channel: [ [meta], csi/bai ] +- reports = ch_reports // channel: [ [meta], log ] ++ bam = ch_bam // channel: [ [meta], bam ] ++ bam_index = ch_bam_index // channel: [ [meta], csi/bai ] ++ reports = ch_reports // channel: [ [meta], log ] + } + +'subworkflows/nf-core/fastq_align_dna/tests/main.nf.test.snap' is unchanged +'subworkflows/nf-core/fastq_align_dna/tests/main.nf.test' is unchanged +************************************************************ diff --git a/subworkflows/nf-core/fastq_align_dna/main.nf b/subworkflows/nf-core/fastq_align_dna/main.nf index 80414235..b7d43c3f 100644 --- a/subworkflows/nf-core/fastq_align_dna/main.nf +++ b/subworkflows/nf-core/fastq_align_dna/main.nf @@ -10,68 +10,70 @@ include { BWA_MEM as BWAMEM1_MEM } from '../../../modules/nf-core/bwa include { BWAMEM2_MEM as BWAMEM2_MEM } from '../../../modules/nf-core/bwamem2/mem/main' include { DRAGMAP_ALIGN } from "../../../modules/nf-core/dragmap/align/main" include { SNAPALIGNER_ALIGN as SNAP_ALIGN } from '../../../modules/nf-core/snapaligner/align/main' +include { STROBEALIGN } from "../../../modules/nf-core/strobealign/main" workflow FASTQ_ALIGN_DNA { take: - ch_reads_aligner_index_fasta // channel: [mandatory] reads, aligner, index, fasta - sort // boolean: [mandatory] true -> sort, false -> don't sort + ch_reads_aligner_index_fasta // channel: [mandatory] reads, aligner, index, fasta + sort // boolean: [mandatory] true -> sort, false -> don't sort main: - ch_bam_index = Channel.empty() - ch_bam = Channel.empty() - ch_reports = Channel.empty() - ch_versions = Channel.empty() - - ch_reads_aligner_index_fasta.branch { meta, reads, aligner, index, fasta -> - bowtie2 : aligner == 'bowtie2' - return [meta, reads, index, fasta] - bwamem : aligner == 'bwamem' - return [meta, reads, index, fasta] - bwamem2 : aligner == 'bwamem2' - return [meta, reads, index, fasta] - dragmap : aligner == 'dragmap' - return [meta, reads, index, fasta] - snap : aligner == 'snap' - return [meta, reads, index] - other : true - } - .set{ch_to_align} - - // Throw error for all samples with unsupported aligners - ch_to_align.other.map{ meta, _reads, aligner, _index, _fasta -> - error "Unsupported aligner ${aligner} for sample ${meta.id}" + ch_bam_index = channel.empty() + ch_bam = channel.empty() + ch_reports = channel.empty() + + ch_reads_aligner_index_fasta + .branch { meta, reads, aligner, index, fasta -> + bowtie2: aligner == 'bowtie2' + return [meta, reads, index, fasta] + bwamem: aligner == 'bwamem' + return [meta, reads, index, fasta] + bwamem2: aligner == 'bwamem2' + return [meta, reads, index, fasta] + dragmap: aligner == 'dragmap' + return [meta, reads, index, fasta] + snap: aligner == 'snap' + return [meta, reads, index] + strobe: aligner == 'strobe' + return [meta, reads, fasta, index] + other: true } - - // Align fastq files to reference genome and (optionally) sort - BOWTIE2_ALIGN(ch_to_align.bowtie2, false, sort) // if aligner is bowtie2 - ch_bam = ch_bam.mix(BOWTIE2_ALIGN.out.bam) - ch_versions = ch_versions.mix(BOWTIE2_ALIGN.out.versions) - - BWAMEM1_MEM (ch_to_align.bwamem, sort) // If aligner is bwa-mem - ch_bam = ch_bam.mix(BWAMEM1_MEM.out.bam) - ch_bam_index = ch_bam_index.mix(BWAMEM1_MEM.out.csi) - ch_versions = ch_versions.mix(BWAMEM1_MEM.out.versions) - - BWAMEM2_MEM (ch_to_align.bwamem2, sort) // If aligner is bwa-mem2 - ch_bam = ch_bam.mix(BWAMEM2_MEM.out.bam) - ch_versions = ch_versions.mix(BWAMEM2_MEM.out.versions) - - DRAGMAP_ALIGN(ch_to_align.dragmap, sort) // If aligner is dragmap - ch_bam = ch_bam.mix(DRAGMAP_ALIGN.out.bam) - ch_reports = ch_reports.mix(DRAGMAP_ALIGN.out.log) - ch_versions = ch_versions.mix(DRAGMAP_ALIGN.out.versions) - - SNAP_ALIGN(ch_to_align.snap) // If aligner is snap - ch_bam = ch_bam.mix(SNAP_ALIGN.out.bam) - ch_bam_index.mix(SNAP_ALIGN.out.bai) - ch_versions = ch_versions.mix(SNAP_ALIGN.out.versions) + .set { ch_to_align } + + // Throw error for all samples with unsupported aligners + ch_to_align.other.map { meta, _reads, aligner, _index, _fasta -> + error("Unsupported aligner ${aligner} for sample ${meta.id}") + } + + // Align fastq files to reference genome and (optionally) sort + BOWTIE2_ALIGN(ch_to_align.bowtie2, false, sort) + // if aligner is bowtie2 + ch_bam = ch_bam.mix(BOWTIE2_ALIGN.out.bam) + BWAMEM1_MEM(ch_to_align.bwamem, sort) + // If aligner is bwa-mem + ch_bam = ch_bam.mix(BWAMEM1_MEM.out.bam) + ch_bam_index = ch_bam_index.mix(BWAMEM1_MEM.out.csi) + BWAMEM2_MEM(ch_to_align.bwamem2, sort) + // If aligner is bwa-mem2 + ch_bam = ch_bam.mix(BWAMEM2_MEM.out.bam) + DRAGMAP_ALIGN(ch_to_align.dragmap, sort) + // If aligner is dragmap + ch_bam = ch_bam.mix(DRAGMAP_ALIGN.out.bam) + ch_reports = ch_reports.mix(DRAGMAP_ALIGN.out.log) + SNAP_ALIGN(ch_to_align.snap) + // If aligner is snap + ch_bam = ch_bam.mix(SNAP_ALIGN.out.bam) + ch_bam_index.mix(SNAP_ALIGN.out.bai) + STROBEALIGN(ch_to_align.strobe, sort) + // If aligner is strobealign + ch_bam = ch_bam.mix(STROBEALIGN.out.bam) + ch_bam_index = ch_bam_index.mix(STROBEALIGN.out.csi) emit: - bam = ch_bam // channel: [ [meta], bam ] - bam_index = ch_bam_index // channel: [ [meta], csi/bai ] - reports = ch_reports // channel: [ [meta], log ] - versions = ch_versions // channel: [ versions.yml ] + bam = ch_bam // channel: [ [meta], bam ] + bam_index = ch_bam_index // channel: [ [meta], csi/bai ] + reports = ch_reports // channel: [ [meta], log ] } diff --git a/subworkflows/nf-core/fastq_align_dna/meta.yml b/subworkflows/nf-core/fastq_align_dna/meta.yml index cd452612..26c3e237 100644 --- a/subworkflows/nf-core/fastq_align_dna/meta.yml +++ b/subworkflows/nf-core/fastq_align_dna/meta.yml @@ -9,12 +9,14 @@ keywords: - bwamem2 - dragmap - snapaligner + - strobealign components: - bowtie2/align - bwa/mem - bwamem2/mem - dragmap/align - snapaligner/align + - strobealign input: - meta: type: map @@ -53,6 +55,7 @@ input: - bwamem2 - dragmap - snap + - strobealign - sort_bam: type: boolean description: sort output diff --git a/subworkflows/nf-core/fastq_align_dna/tests/main.nf.test b/subworkflows/nf-core/fastq_align_dna/tests/main.nf.test index 48988102..b1b3c1c9 100644 --- a/subworkflows/nf-core/fastq_align_dna/tests/main.nf.test +++ b/subworkflows/nf-core/fastq_align_dna/tests/main.nf.test @@ -22,6 +22,7 @@ nextflow_workflow { tag "snapaligner" tag "snapaligner/index" tag "snapaligner/align" + tag "strobealign" test("test_fastq_align_bowtie2_SE") { setup { @@ -51,7 +52,6 @@ nextflow_workflow { { assert workflow.success}, { assert snapshot( file(workflow.out.bam[0][1]).name, - workflow.out.versions[0] ).match() } ) } @@ -85,7 +85,6 @@ nextflow_workflow { { assert workflow.success}, { assert snapshot( file(workflow.out.bam[0][1]).name, - workflow.out.versions[0] ).match() } ) } @@ -120,7 +119,6 @@ nextflow_workflow { file(workflow.out.bam[0][1]).name, workflow.out.bam_index, workflow.out.reports, - workflow.out.versions, ).match() } ) @@ -156,7 +154,6 @@ nextflow_workflow { file(workflow.out.bam[0][1]).name, workflow.out.bam_index, workflow.out.reports, - workflow.out.versions, ).match() } ) @@ -192,7 +189,6 @@ nextflow_workflow { file(workflow.out.bam[0][1]).name, workflow.out.bam_index, workflow.out.reports, - workflow.out.versions, ).match() } ) @@ -228,7 +224,6 @@ nextflow_workflow { file(workflow.out.bam[0][1]).name, workflow.out.bam_index, workflow.out.reports, - workflow.out.versions, ).match() } ) @@ -263,7 +258,6 @@ nextflow_workflow { { assert snapshot( file(workflow.out.bam[0][1]).name, file(workflow.out.reports[0][1]).readLines().findAll { it.startsWith("decompHash") }, - file(workflow.out.versions[0]).name ).match() } ) } @@ -297,7 +291,6 @@ nextflow_workflow { { assert snapshot( file(workflow.out.bam[0][1]).name, file(workflow.out.reports[0][1]).readLines().findAll { it.startsWith("decompHash") }, - file(workflow.out.versions[0]).name ).match() } ) } @@ -355,6 +348,46 @@ nextflow_workflow { } } + then { + assertAll( + { assert workflow.success}, + { assert snapshot(workflow.out).match()} + ) + } + } + test ("test_fastq_align_strobealign_SE"){ + when { + workflow { + """ + input[0] = Channel.of([[ id:'test', single_end:true ], [file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true)]]) + input[1] = [[:],[]] + input[2] = Channel.of([ [ id:'genome' ],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]) + input[3] = "strobealign" + input[4] = true + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot(workflow.out).match()} + ) + } + } + test ("test_fastq_align_strobealign_PE"){ + when { + workflow { + """ + input[0] = Channel.of([[ id:'test', single_end:false ], [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)]]) + input[1] = [[:],[]] + input[2] = Channel.of([ [ id:'genome' ],file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]) + input[3] = "strobealign" + input[4] = true + """ + } + } + then { assertAll( { assert workflow.success}, diff --git a/subworkflows/nf-core/fastq_align_dna/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_align_dna/tests/main.nf.test.snap index a4fd38bc..f002d8a4 100644 --- a/subworkflows/nf-core/fastq_align_dna/tests/main.nf.test.snap +++ b/subworkflows/nf-core/fastq_align_dna/tests/main.nf.test.snap @@ -7,16 +7,13 @@ ], [ - ], - [ - "versions.yml:md5,0e1a9cd2ce7baf650bec3dd365fbced7" ] ], + "timestamp": "2026-02-18T14:49:11.253548", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-27T08:57:56.74202649" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test_fastq_align_dragmap_PE": { "content": [ @@ -28,14 +25,54 @@ "decompHashTableExtIndex...", "decompHashTableAutoHits...", "decompHashTableSetFlags..." - ], - "versions.yml" + ] + ], + "timestamp": "2026-02-18T13:45:07.40135", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "test_fastq_align_strobealign_PE": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,1d8fb5dce75cbfb87955c7ee03c17a5f" + ] + ], + "1": [ + + ], + "2": [ + + ], + "bam": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,1d8fb5dce75cbfb87955c7ee03c17a5f" + ] + ], + "bam_index": [ + + ], + "reports": [ + + ] + } ], + "timestamp": "2026-02-18T14:49:56.04299", "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-03-14T08:28:25.283436546" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test_fastq_align_bwa_mem_SE": { "content": [ @@ -45,16 +82,13 @@ ], [ - ], - [ - "versions.yml:md5,83f7314fe48e4c905a39e47723c78039" ] ], + "timestamp": "2026-02-18T14:48:28.855536", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-27T08:56:27.900928171" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test_fastq_align_bwamem2_SE": { "content": [ @@ -64,16 +98,13 @@ ], [ - ], - [ - "versions.yml:md5,0e1a9cd2ce7baf650bec3dd365fbced7" ] ], + "timestamp": "2026-02-18T14:48:54.331973", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-27T08:57:28.080810832" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test_fastq_align_bwa_mem_PE": { "content": [ @@ -83,27 +114,23 @@ ], [ - ], - [ - "versions.yml:md5,83f7314fe48e4c905a39e47723c78039" ] ], + "timestamp": "2026-02-18T14:48:37.392571", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-27T08:56:55.897418514" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test_fastq_align_bowtie2_SE": { "content": [ - "test.bam", - "versions.yml:md5,ef191e9624d747934f15d368715d87db" + "test.bam" ], + "timestamp": "2026-02-18T14:48:09.863021", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" - }, - "timestamp": "2025-03-24T14:20:30.468391" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test_fastq_align_dragmap_SE": { "content": [ @@ -115,25 +142,23 @@ "decompHashTableExtIndex...", "decompHashTableAutoHits...", "decompHashTableSetFlags..." - ], - "versions.yml" + ] ], + "timestamp": "2026-02-18T13:49:05.298349", "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-03-14T08:28:12.991034375" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test_fastq_align_bowtie2_PE": { "content": [ - "test.bam", - "versions.yml:md5,ef191e9624d747934f15d368715d87db" + "test.bam" ], + "timestamp": "2026-02-18T14:48:20.207038", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.4" - }, - "timestamp": "2025-03-24T14:25:41.372083" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test_fastq_align_snapaligner_PE": { "content": [ @@ -144,7 +169,7 @@ "id": "test", "single_end": false }, - "test.bam:md5,1f4f6c38e40ddd5da7f644bb0f794aa8" + "test.bam:md5,504bcc1ac7f8d8e1e728276a4ce4f4d4" ] ], "1": [ @@ -152,9 +177,6 @@ ], "2": [ - ], - "3": [ - "versions.yml:md5,ef9883fd373e293fbf6a98985d3c0308" ], "bam": [ [ @@ -162,7 +184,7 @@ "id": "test", "single_end": false }, - "test.bam:md5,1f4f6c38e40ddd5da7f644bb0f794aa8" + "test.bam:md5,504bcc1ac7f8d8e1e728276a4ce4f4d4" ] ], "bam_index": [ @@ -170,17 +192,55 @@ ], "reports": [ + ] + } + ], + "timestamp": "2026-02-18T14:49:42.350796", + "meta": { + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } + }, + "test_fastq_align_strobealign_SE": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam:md5,30a9339ac99b881844cf8514f719f204" + ] + ], + "1": [ + + ], + "2": [ + ], - "versions": [ - "versions.yml:md5,ef9883fd373e293fbf6a98985d3c0308" + "bam": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam:md5,30a9339ac99b881844cf8514f719f204" + ] + ], + "bam_index": [ + + ], + "reports": [ + ] } ], + "timestamp": "2026-02-18T14:49:49.102483", "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-03-14T08:19:36.298315938" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } }, "test_fastq_align_snapaligner_SE": { "content": [ @@ -191,7 +251,7 @@ "id": "test", "single_end": true }, - "test.bam:md5,6b3188b8e48ec5c155cfe02b9a24d37a" + "test.bam:md5,9de00a20df23dc66ddf0d9bba2e486c3" ] ], "1": [ @@ -199,9 +259,6 @@ ], "2": [ - ], - "3": [ - "versions.yml:md5,ef9883fd373e293fbf6a98985d3c0308" ], "bam": [ [ @@ -209,7 +266,7 @@ "id": "test", "single_end": true }, - "test.bam:md5,6b3188b8e48ec5c155cfe02b9a24d37a" + "test.bam:md5,9de00a20df23dc66ddf0d9bba2e486c3" ] ], "bam_index": [ @@ -217,16 +274,13 @@ ], "reports": [ - ], - "versions": [ - "versions.yml:md5,ef9883fd373e293fbf6a98985d3c0308" ] } ], + "timestamp": "2026-02-18T14:49:34.584076", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.5" - }, - "timestamp": "2025-03-25T08:46:43.073714962" + "nf-test": "0.9.4", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_align_dna/tests/nextflow.config b/subworkflows/nf-core/fastq_align_dna/tests/nextflow.config deleted file mode 100644 index 87892757..00000000 --- a/subworkflows/nf-core/fastq_align_dna/tests/nextflow.config +++ /dev/null @@ -1,12 +0,0 @@ -process { - withName: BOWTIE2_BUILD { - } - withName: BWA_INDEX { - } - withName: BWAMEM2_INDEX { - } - withName: DRAGMAP_HASHTABLE { - } - withName: SNAPALIGNER_INDEX { - } -} diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf index 0fcbf7b3..d6e593e8 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/tags.yml b/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml deleted file mode 100644 index f8476112..00000000 --- a/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -subworkflows/utils_nextflow_pipeline: - - subworkflows/nf-core/utils_nextflow_pipeline/** diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf index 5cb7bafe..bf568a08 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 // @@ -113,7 +98,7 @@ def workflowVersionToYAML() { // Get channel of software versions used in pipeline in YAML format // def softwareVersionsToYAML(ch_versions) { - return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(Channel.of(workflowVersionToYAML())) + return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(channel.of(workflowVersionToYAML())) } // @@ -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 @@ -396,67 +353,3 @@ def completionSummary(monochrome_logs=true) { log.info("-${colors.purple}[${workflow.manifest.name}]${colors.red} Pipeline completed with errors${colors.reset}-") } } - -// -// Construct and send a notification to a web server as JSON e.g. Microsoft Teams and Slack -// -def imNotification(summary_params, hook_url) { - def summary = [:] - 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 - - def msg_fields = [:] - msg_fields['version'] = getWorkflowVersion() - msg_fields['runName'] = workflow.runName - msg_fields['success'] = workflow.success - msg_fields['dateComplete'] = workflow.complete - msg_fields['duration'] = workflow.duration - msg_fields['exitStatus'] = workflow.exitStatus - msg_fields['errorMessage'] = (workflow.errorMessage ?: 'None') - msg_fields['errorReport'] = (workflow.errorReport ?: 'None') - msg_fields['commandLine'] = workflow.commandLine.replaceFirst(/ +--hook_url +[^ ]+/, "") - msg_fields['projectDir'] = workflow.projectDir - msg_fields['summary'] = summary << misc_fields - - // Render the JSON template - def engine = new groovy.text.GStringTemplateEngine() - // Different JSON depending on the service provider - // Defaults to "Adaptive Cards" (https://adaptivecards.io), except Slack which has its own format - def json_path = hook_url.contains("hooks.slack.com") ? "slackreport.json" : "adaptivecard.json" - def hf = new File("${workflow.projectDir}/assets/${json_path}") - def json_template = engine.createTemplate(hf).make(msg_fields) - def json_message = json_template.toString() - - // POST - def post = new URL(hook_url).openConnection() - post.setRequestMethod("POST") - post.setDoOutput(true) - post.setRequestProperty("Content-Type", "application/json") - post.getOutputStream().write(json_message.getBytes("UTF-8")) - def postRC = post.getResponseCode() - if (!postRC.equals(200)) { - log.warn(post.getErrorStream().getText()) - } -} 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 1dc317f8..f117040c 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 1037232c..02c67014 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_nfcore_pipeline/tests/main.workflow.nf.test b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test similarity index 100% rename from subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test rename to subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test.snap similarity index 100% rename from subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap rename to subworkflows/nf-core/utils_nfcore_pipeline/tests/main.nf.test.snap diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml b/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml deleted file mode 100644 index ac8523c9..00000000 --- a/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -subworkflows/utils_nfcore_pipeline: - - subworkflows/nf-core/utils_nfcore_pipeline/** diff --git a/subworkflows/nf-core/utils_nfschema_plugin/main.nf b/subworkflows/nf-core/utils_nfschema_plugin/main.nf index 4994303e..1df8b76f 100644 --- a/subworkflows/nf-core/utils_nfschema_plugin/main.nf +++ b/subworkflows/nf-core/utils_nfschema_plugin/main.nf @@ -4,6 +4,7 @@ include { paramsSummaryLog } from 'plugin/nf-schema' include { validateParameters } from 'plugin/nf-schema' +include { paramsHelp } from 'plugin/nf-schema' workflow UTILS_NFSCHEMA_PLUGIN { @@ -15,32 +16,58 @@ workflow UTILS_NFSCHEMA_PLUGIN { // 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 + help // boolean: show help message + help_full // boolean: show full help message + show_hidden // boolean: show hidden parameters in help message + before_text // string: text to show before the help message and parameters summary + after_text // string: text to show after the help message and parameters summary + command // string: an example command of the pipeline main: + if(help || help_full) { + help_options = [ + beforeText: before_text, + afterText: after_text, + command: command, + showHidden: show_hidden, + fullHelp: help_full, + ] + if(parameters_schema) { + help_options << [parametersSchema: parameters_schema] + } + log.info paramsHelp( + help_options, + (params.help instanceof String && params.help != "true") ? params.help : "", + ) + exit 0 + } + // // Print parameter summary to stdout. This will display the parameters // that differ from the default given in the JSON schema // + + summary_options = [:] if(parameters_schema) { - log.info paramsSummaryLog(input_workflow, parameters_schema:parameters_schema) - } else { - log.info paramsSummaryLog(input_workflow) + summary_options << [parametersSchema: parameters_schema] } + log.info before_text + log.info paramsSummaryLog(summary_options, input_workflow) + log.info after_text // // Validate the parameters using nextflow_schema.json or the schema // given via the validation.parametersSchema configuration option // if(validate_params) { + validateOptions = [:] if(parameters_schema) { - validateParameters(parameters_schema:parameters_schema) - } else { - validateParameters() + validateOptions << [parametersSchema: parameters_schema] } + validateParameters(validateOptions) } emit: dummy_emit = true } - 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 8fb30164..c977917a 100644 --- a/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test @@ -25,6 +25,12 @@ nextflow_workflow { input[0] = workflow input[1] = validate_params input[2] = "" + input[3] = false + input[4] = false + input[5] = false + input[6] = "" + input[7] = "" + input[8] = "" """ } } @@ -51,6 +57,12 @@ nextflow_workflow { input[0] = workflow input[1] = validate_params input[2] = "" + input[3] = false + input[4] = false + input[5] = false + input[6] = "" + input[7] = "" + input[8] = "" """ } } @@ -77,6 +89,12 @@ nextflow_workflow { input[0] = workflow input[1] = validate_params input[2] = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json" + input[3] = false + input[4] = false + input[5] = false + input[6] = "" + input[7] = "" + input[8] = "" """ } } @@ -103,6 +121,12 @@ nextflow_workflow { input[0] = workflow input[1] = validate_params input[2] = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json" + input[3] = false + input[4] = false + input[5] = false + input[6] = "" + input[7] = "" + input[8] = "" """ } } @@ -114,4 +138,36 @@ nextflow_workflow { ) } } + + test("Should create a help message") { + + when { + + params { + test_data = '' + outdir = null + } + + workflow { + """ + validate_params = true + input[0] = workflow + input[1] = validate_params + input[2] = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json" + input[3] = true + input[4] = false + input[5] = false + input[6] = "Before" + input[7] = "After" + input[8] = "nextflow run test/test" + """ + } + } + + then { + assertAll( + { assert workflow.success } + ) + } + } } diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config index 0907ac58..f6537cc3 100644 --- a/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config @@ -1,8 +1,8 @@ plugins { - id "nf-schema@2.1.0" + id "nf-schema@2.6.1" } validation { parametersSchema = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json" monochromeLogs = true -} \ No newline at end of file +} diff --git a/tests/.nftignore b/tests/.nftignore new file mode 100644 index 00000000..e128a128 --- /dev/null +++ b/tests/.nftignore @@ -0,0 +1,12 @@ +.DS_Store +multiqc/multiqc_data/fastqc_top_overrepresented_sequences_table.txt +multiqc/multiqc_data/multiqc.parquet +multiqc/multiqc_data/multiqc.log +multiqc/multiqc_data/multiqc_data.json +multiqc/multiqc_data/multiqc_sources.txt +multiqc/multiqc_data/multiqc_software_versions.txt +multiqc/multiqc_data/llms-full.txt +multiqc/multiqc_plots/{svg,pdf,png}/*.{svg,pdf,png} +multiqc/multiqc_report.html +fastqc/*_fastqc.{html,zip} +pipeline_info/*.{html,json,txt,yml} diff --git a/tests/config/igenomes_test.config b/tests/config/igenomes_test.config index 3b3e3263..e71fec6f 100644 --- a/tests/config/igenomes_test.config +++ b/tests/config/igenomes_test.config @@ -1,21 +1,13 @@ params { genomes { GRCh38 { - bwamem = "s3://test-data/genomics/homo_sapiens/genome/bwa/" - dict = "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict" - fai = "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai" - fasta = "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna" - star = "s3://test-data/genomics/homo_sapiens/genome/star/" - gtf = "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + bwamem = "s3://test-data/genomics/homo_sapiens/genome/bwa/" + dict = "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict" + fai = "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai" + fasta = "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna" + star = "s3://test-data/genomics/homo_sapiens/genome/star/" + gtf = "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + genelists = "s3://test-data/genomics/homo_sapiens/genome/regions/genelists" } } } - -aws { - client { - endpoint = "https://s3.ugent.be" - protocol = "https" - s3PathStyleAccess = true - connectionTimeout = 60000 - } -} diff --git a/tests/config/nf-test.config b/tests/config/nf-test.config index 68e597f9..88f7efd5 100644 --- a/tests/config/nf-test.config +++ b/tests/config/nf-test.config @@ -2,15 +2,6 @@ process { resourceLimits = [ cpus: 2, memory: 6.GB, - time: 6.h + time: 6.h, ] } - -aws { - client { - endpoint = "https://s3.ugent.be" - protocol = "https" - s3PathStyleAccess = true - connectionTimeout = 60000 - } -} diff --git a/tests/default.nf.test b/tests/default.nf.test new file mode 100644 index 00000000..d32cc960 --- /dev/null +++ b/tests/default.nf.test @@ -0,0 +1,26 @@ +nextflow_pipeline { + + name "Test Workflow main.nf" + script "main.nf" + config "tests/config/igenomes_test.config" + + tag "pipeline" + tag "pipeline/main" + + test("main") { + + when { + params { + input = "${projectDir}/tests/inputs/test.yml" + igenomes_base = "s3://reference-data/genomes" + outdir = "$outputDir" + } + } + + then { + assert workflow.success + } + + } + +} diff --git a/tests/inputs/fastq.yml b/tests/inputs/fastq.yml deleted file mode 100644 index bfb9e2d0..00000000 --- a/tests/inputs/fastq.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -# fastq inputs -- id: sample1_L001 - samplename: fastq_paired1 - library: test - organism: Homo sapiens - tag: WES - fastq_1: https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/fastq/sample1_R1.fastq.gz - fastq_2: https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/fastq/sample1_R2.fastq.gz -- id: sample1_L002 - samplename: fastq_paired1 - library: test - organism: Homo sapiens - tag: WES - fastq_1: https://github.com/nf-cmgg/test-datasets/raw/main/data/genomics/homo_sapiens/illumina/fastq/test_R1.fastq.gz - fastq_2: https://github.com/nf-cmgg/test-datasets/raw/main/data/genomics/homo_sapiens/illumina/fastq/test_R2.fastq.gz diff --git a/tests/inputs/flowcell.yml b/tests/inputs/flowcell.yml deleted file mode 100644 index 4711c5b9..00000000 --- a/tests/inputs/flowcell.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- id: 200624_A00834_0183_BHMTFYDRXX - samplesheet: https://github.com/nf-cmgg/test-datasets/raw/refs/heads/preprocessing/data/genomics/homo_sapiens/illumina/flowcell/SampleSheet_2.csv - lane: 1 - flowcell: https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/flowcell/200624_A00834_0183_BHMTFYDRXX.tar.gz - sample_info: https://github.com/nf-cmgg/test-datasets/raw/refs/heads/preprocessing/data/genomics/homo_sapiens/illumina/flowcell/SampleInfo_2.json diff --git a/tests/inputs/test.yml b/tests/inputs/test.yml new file mode 100644 index 00000000..3a432b4b --- /dev/null +++ b/tests/inputs/test.yml @@ -0,0 +1,51 @@ +--- +# flowcell inputs +- id: 200624_A00834_0183_BHMTFYDRXX + samplesheet: https://github.com/nf-cmgg/test-datasets/raw/refs/heads/preprocessing/data/genomics/homo_sapiens/illumina/flowcell/SampleSheet_2.csv + lane: 1 + flowcell: s3://test-data/genomics/homo_sapiens/illumina/bcl/ + sample_info: https://github.com/nf-cmgg/test-datasets/raw/refs/heads/preprocessing/data/genomics/homo_sapiens/illumina/flowcell/SampleInfo_2.json +# DNA fastq inputs +- id: DNA1_L001 + samplename: DNA_paired1 + library: test_library + organism: Homo sapiens + tag: WES + aligner: bwamem + markdup: bamsormadup + run_coverage: true + fastq_1: https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/fastq/sample1_R1.fastq.gz + fastq_2: https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/fastq/sample1_R2.fastq.gz +- id: DNA1_L002 + samplename: DNA_paired1 + library: test_library + organism: Homo sapiens + tag: WES + aligner: bwamem + markdup: bamsormadup + run_coverage: true + fastq_1: https://github.com/nf-cmgg/test-datasets/raw/main/data/genomics/homo_sapiens/illumina/fastq/test_R1.fastq.gz + fastq_2: https://github.com/nf-cmgg/test-datasets/raw/main/data/genomics/homo_sapiens/illumina/fastq/test_R2.fastq.gz +# RNA fastq inputs +- id: RNA1_L001 + samplename: RNA_paired1 + library: test_library + organism: Homo sapiens + tag: WES + sample_type: RNA + aligner: star + markdup: bamsormadup + run_coverage: true + fastq_1: https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/fastq/sample1_R1.fastq.gz + fastq_2: https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/fastq/sample1_R2.fastq.gz +- id: RNA1_L002 + samplename: RNA_paired1 + library: test_library + organism: Homo sapiens + tag: WES + sample_type: RNA + aligner: star + markdup: bamsormadup + run_coverage: true + fastq_1: https://github.com/nf-cmgg/test-datasets/raw/main/data/genomics/homo_sapiens/illumina/fastq/test_R1.fastq.gz + fastq_2: https://github.com/nf-cmgg/test-datasets/raw/main/data/genomics/homo_sapiens/illumina/fastq/test_R2.fastq.gz diff --git a/tests/main.nf.test b/tests/main.nf.test deleted file mode 100644 index 14b7f084..00000000 --- a/tests/main.nf.test +++ /dev/null @@ -1,42 +0,0 @@ -nextflow_pipeline { - - name "Test Workflow main.nf" - script "main.nf" - config "tests/config/igenomes_test.config" - - tag "pipeline" - tag "pipeline/main" - - test("main - fastq input") { - - when { - params { - input = "${projectDir}/tests/inputs/fastq.yml" - aligner = "bwamem" - igenomes_base = "s3://reference-data/genomes" - } - } - - then { - assert workflow.success - } - - } - - test("main - flowcell input") { - - when { - params { - input = "${projectDir}/tests/inputs/flowcell.yml" - aligner = "bwamem" - igenomes_base = "s3://reference-data/genomes" - } - } - - then { - assert workflow.success - } - - } - -} diff --git a/tests/modules/local/panelcoverage/main.nf.test b/tests/modules/local/panelcoverage/main.nf.test index 3d3f351d..4a2dd77d 100644 --- a/tests/modules/local/panelcoverage/main.nf.test +++ b/tests/modules/local/panelcoverage/main.nf.test @@ -17,9 +17,9 @@ nextflow_process { [id: "test", single_end: false ], file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/bed/sample1.per-base.bed.gz", checkIfExists:true), file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/bed/sample1.per-base.bed.gz.csi", checkIfExists:true), - ] - input[1] = [ - file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/genelists/genelist_chr21_per_exon.bed",checkIfExists:true) + [ + file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/genelists/genelist_chr21_per_exon.bed",checkIfExists:true) + ] ] """ } diff --git a/tests/modules/local/panelcoverage/main.nf.test.snap b/tests/modules/local/panelcoverage/main.nf.test.snap index cdb60adb..49122c84 100644 --- a/tests/modules/local/panelcoverage/main.nf.test.snap +++ b/tests/modules/local/panelcoverage/main.nf.test.snap @@ -12,7 +12,18 @@ ] ], "1": [ - "versions.yml:md5,2452395e283f5046f40bee1d26a09121" + [ + "PANELCOVERAGE", + "cmgg_genelists", + "0.1.0" + ] + ], + "2": [ + [ + "PANELCOVERAGE", + "bedtools", + "2.31.1" + ] ], "regiondist": [ [ @@ -23,15 +34,26 @@ "test_genelist_chr21_per_exon.mosdepth.region.dist.txt:md5,b29a7f12cef3be13215923edf6dde674" ] ], - "versions": [ - "versions.yml:md5,2452395e283f5046f40bee1d26a09121" + "versions_bedtools": [ + [ + "PANELCOVERAGE", + "bedtools", + "2.31.1" + ] + ], + "versions_cmgg_genelists": [ + [ + "PANELCOVERAGE", + "cmgg_genelists", + "0.1.0" + ] ] } ], + "timestamp": "2026-02-11T19:45:02.994288", "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-04-12T14:47:04.895941" + "nf-test": "0.9.3", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/tests/nextflow.config b/tests/nextflow.config index e69de29b..548fbe63 100644 --- a/tests/nextflow.config +++ b/tests/nextflow.config @@ -0,0 +1 @@ +includeConfig "config/nf-test.config" diff --git a/tests/subworkflows/local/bam_qc/main.nf.test b/tests/subworkflows/local/bam_qc/main.nf.test index 68bc3cc9..acb2f53a 100644 --- a/tests/subworkflows/local/bam_qc/main.nf.test +++ b/tests/subworkflows/local/bam_qc/main.nf.test @@ -15,7 +15,7 @@ nextflow_workflow { """ // [meta, bam, bai, roi, fasta, fai, dict] input[0] = Channel.of([ - [ id:'test', single_end:false ], + [ id:'test', single_end:false, disable_picard_metrics:false ], file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/cram/sample1.sorted.cram", checkIfExists: true), file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/cram/sample1.sorted.cram.crai", checkIfExists: true), file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", checkIfExists: true), @@ -23,8 +23,6 @@ nextflow_workflow { file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", checkIfExists: true), file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", checkIfExists: true), ]) - // boolean - input[1] = false """ } } @@ -32,11 +30,12 @@ nextflow_workflow { then { assert workflow.success assert snapshot( - workflow.out.samtools_stats, - workflow.out.samtools_flagstat, - workflow.out.samtools_idxstats, - file(workflow.out.picard_multiplemetrics[0][1][0]).name, - file(workflow.out.picard_hsmetrics[0][1]).name, + sanitizeOutput(workflow.out, unstableKeys:[ + "picard_wgsmetrics", + "picard_multiplemetrics_pdf", + "picard_multiplemetrics", + "picard_hsmetrics" + ]) ).match() } @@ -48,7 +47,7 @@ nextflow_workflow { """ // [meta, bam, bai, roi, fasta, fai, dict] input[0] = Channel.of([ - [ id:'test', single_end:false ], + [ id:'test', single_end:false, disable_picard_metrics:false ], file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/cram/sample1.sorted.cram", checkIfExists: true), file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/cram/sample1.sorted.cram.crai", checkIfExists: true), [], @@ -56,8 +55,6 @@ nextflow_workflow { file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", checkIfExists: true), file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", checkIfExists: true), ]) - // boolean - input[1] = false """ } } @@ -65,11 +62,12 @@ nextflow_workflow { then { assert workflow.success assert snapshot( - workflow.out.samtools_stats, - workflow.out.samtools_flagstat, - workflow.out.samtools_idxstats, - file(workflow.out.picard_multiplemetrics[0][1][0]).name, - file(workflow.out.picard_wgsmetrics[0][1]).name, + sanitizeOutput(workflow.out, unstableKeys:[ + "picard_wgsmetrics", + "picard_multiplemetrics_pdf", + "picard_multiplemetrics", + "picard_hsmetrics" + ]) ).match() } } @@ -80,7 +78,7 @@ nextflow_workflow { """ // [meta, bam, bai, roi, fasta, fai, dict] input[0] = Channel.of([ - [ id:'test', single_end:false ], + [ id:'test', single_end:false, disable_picard_metrics:true ], file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/cram/sample1.sorted.cram", checkIfExists: true), file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/cram/sample1.sorted.cram.crai", checkIfExists: true), file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", checkIfExists: true), @@ -88,8 +86,6 @@ nextflow_workflow { file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", checkIfExists: true), file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", checkIfExists: true), ]) - // boolean - input[1] = true """ } } @@ -97,9 +93,12 @@ nextflow_workflow { then { assert workflow.success assert snapshot( - workflow.out.samtools_stats, - workflow.out.samtools_flagstat, - workflow.out.samtools_idxstats, + sanitizeOutput(workflow.out, unstableKeys:[ + "picard_wgsmetrics", + "picard_multiplemetrics_pdf", + "picard_multiplemetrics", + "picard_hsmetrics" + ]) ).match() } } diff --git a/tests/subworkflows/local/bam_qc/main.nf.test.snap b/tests/subworkflows/local/bam_qc/main.nf.test.snap index 776c3f35..5c83a450 100644 --- a/tests/subworkflows/local/bam_qc/main.nf.test.snap +++ b/tests/subworkflows/local/bam_qc/main.nf.test.snap @@ -1,114 +1,227 @@ { "Bam QC - HSmetrics": { "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.stats:md5,18292ec37f6ff9eff458683e3abf638b" + { + "picard_hsmetrics": [ + [ + { + "disable_picard_metrics": false, + "id": "test", + "single_end": false + }, + "test.CollectHsMetrics.coverage_metrics" + ] + ], + "picard_multiplemetrics": [ + [ + { + "disable_picard_metrics": false, + "id": "test", + "single_end": false + }, + [ + "test.CollectMultipleMetrics.alignment_summary_metrics", + "test.CollectMultipleMetrics.base_distribution_by_cycle_metrics", + "test.CollectMultipleMetrics.insert_size_metrics", + "test.CollectMultipleMetrics.quality_by_cycle_metrics", + "test.CollectMultipleMetrics.quality_distribution_metrics" + ] + ] + ], + "picard_multiplemetrics_pdf": [ + [ + { + "disable_picard_metrics": false, + "id": "test", + "single_end": false + }, + [ + "test.CollectMultipleMetrics.base_distribution_by_cycle.pdf", + "test.CollectMultipleMetrics.insert_size_histogram.pdf", + "test.CollectMultipleMetrics.quality_by_cycle.pdf", + "test.CollectMultipleMetrics.quality_distribution.pdf", + "test.CollectMultipleMetrics.read_length_histogram.pdf" + ] + ] + ], + "picard_wgsmetrics": [ + + ], + "samtools_flagstat": [ + [ + { + "id": "test", + "single_end": false, + "disable_picard_metrics": false + }, + "test.flagstat:md5,167e69b479663a15194ddf56cbc9e60e" + ] + ], + "samtools_idxstats": [ + [ + { + "id": "test", + "single_end": false, + "disable_picard_metrics": false + }, + "test.idxstats:md5,081d0431383fb7ea6b51b7077c6ec93c" + ] + ], + "samtools_stats": [ + [ + { + "id": "test", + "single_end": false, + "disable_picard_metrics": false + }, + "test.stats:md5,3535d8d302e61ca0d77ac718db8309f1" + ] ] - ], - [ - [ - { - "id": "test", - "single_end": false - }, - "test.flagstat:md5,167e69b479663a15194ddf56cbc9e60e" - ] - ], - [ - [ - { - "id": "test", - "single_end": false - }, - "test.idxstats:md5,081d0431383fb7ea6b51b7077c6ec93c" - ] - ], - "test.CollectMultipleMetrics.alignment_summary_metrics", - "test.CollectHsMetrics.coverage_metrics" + } ], + "timestamp": "2026-02-11T20:41:14.126057", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.1" - }, - "timestamp": "2024-11-19T15:23:54.440455" + "nf-test": "0.9.3", + "nextflow": "25.10.4" + } }, "Bam QC - Samtools": { "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.stats:md5,18292ec37f6ff9eff458683e3abf638b" - ] - ], - [ - [ - { - "id": "test", - "single_end": false - }, - "test.flagstat:md5,167e69b479663a15194ddf56cbc9e60e" + { + "picard_hsmetrics": [ + + ], + "picard_multiplemetrics": [ + + ], + "picard_multiplemetrics_pdf": [ + + ], + "picard_wgsmetrics": [ + + ], + "samtools_flagstat": [ + [ + { + "id": "test", + "single_end": false, + "disable_picard_metrics": true + }, + "test.flagstat:md5,167e69b479663a15194ddf56cbc9e60e" + ] + ], + "samtools_idxstats": [ + [ + { + "id": "test", + "single_end": false, + "disable_picard_metrics": true + }, + "test.idxstats:md5,081d0431383fb7ea6b51b7077c6ec93c" + ] + ], + "samtools_stats": [ + [ + { + "id": "test", + "single_end": false, + "disable_picard_metrics": true + }, + "test.stats:md5,3535d8d302e61ca0d77ac718db8309f1" + ] ] - ], - [ - [ - { - "id": "test", - "single_end": false - }, - "test.idxstats:md5,081d0431383fb7ea6b51b7077c6ec93c" - ] - ] + } ], + "timestamp": "2026-02-11T20:27:00.941719", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.1" - }, - "timestamp": "2024-11-19T15:25:06.200354" + "nf-test": "0.9.3", + "nextflow": "25.10.4" + } }, "Bam QC - WGSmetrics": { "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.stats:md5,18292ec37f6ff9eff458683e3abf638b" - ] - ], - [ - [ - { - "id": "test", - "single_end": false - }, - "test.flagstat:md5,167e69b479663a15194ddf56cbc9e60e" - ] - ], - [ - [ - { - "id": "test", - "single_end": false - }, - "test.idxstats:md5,081d0431383fb7ea6b51b7077c6ec93c" + { + "picard_hsmetrics": [ + + ], + "picard_multiplemetrics": [ + [ + { + "disable_picard_metrics": false, + "id": "test", + "single_end": false + }, + [ + "test.CollectMultipleMetrics.alignment_summary_metrics", + "test.CollectMultipleMetrics.base_distribution_by_cycle_metrics", + "test.CollectMultipleMetrics.insert_size_metrics", + "test.CollectMultipleMetrics.quality_by_cycle_metrics", + "test.CollectMultipleMetrics.quality_distribution_metrics" + ] + ] + ], + "picard_multiplemetrics_pdf": [ + [ + { + "disable_picard_metrics": false, + "id": "test", + "single_end": false + }, + [ + "test.CollectMultipleMetrics.base_distribution_by_cycle.pdf", + "test.CollectMultipleMetrics.insert_size_histogram.pdf", + "test.CollectMultipleMetrics.quality_by_cycle.pdf", + "test.CollectMultipleMetrics.quality_distribution.pdf", + "test.CollectMultipleMetrics.read_length_histogram.pdf" + ] + ] + ], + "picard_wgsmetrics": [ + [ + { + "disable_picard_metrics": false, + "id": "test", + "single_end": false + }, + "test.CollectWgsMetrics.coverage_metrics" + ] + ], + "samtools_flagstat": [ + [ + { + "id": "test", + "single_end": false, + "disable_picard_metrics": false + }, + "test.flagstat:md5,167e69b479663a15194ddf56cbc9e60e" + ] + ], + "samtools_idxstats": [ + [ + { + "id": "test", + "single_end": false, + "disable_picard_metrics": false + }, + "test.idxstats:md5,081d0431383fb7ea6b51b7077c6ec93c" + ] + ], + "samtools_stats": [ + [ + { + "id": "test", + "single_end": false, + "disable_picard_metrics": false + }, + "test.stats:md5,3535d8d302e61ca0d77ac718db8309f1" + ] ] - ], - "test.CollectMultipleMetrics.alignment_summary_metrics", - "test.CollectWgsMetrics.coverage_metrics" + } ], + "timestamp": "2026-02-11T20:26:15.482881", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.1" - }, - "timestamp": "2024-11-19T15:24:51.243661" + "nf-test": "0.9.3", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/tests/subworkflows/local/coverage/main.nf.test b/tests/subworkflows/local/coverage/main.nf.test index 17e8b833..c13bd512 100644 --- a/tests/subworkflows/local/coverage/main.nf.test +++ b/tests/subworkflows/local/coverage/main.nf.test @@ -8,14 +8,14 @@ nextflow_workflow { tag "subworkflows/local" tag "subworkflows/local/coverage" - test("Coverage") { + test("Coverage - seqcap") { when { workflow { """ // ch_meta_cram_crai_fasta_fai_roi input[0] = Channel.of([ - [id: "test", single_end: false], // meta + [id: "test", single_end: false, tag: "seqcap"], // meta file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/cram/sample1.sorted.cram", checkIfExists: true), file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/cram/sample1.sorted.cram.crai", checkIfExists: true), file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", checkIfExists: true), @@ -23,9 +23,36 @@ nextflow_workflow { file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", checkIfExists: true), ]) // genelists - input[1] = Channel.of([ - file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/genelists/genelist_chr21_per_exon.bed",checkIfExists:true) + def genelists_path = "s3://test-data/genomics/homo_sapiens/genome/regions/genelists" + input[1] = channel.fromPath(genelists_path + "/*.bed").collect().map{ files -> [ files ] }.ifEmpty { channel.empty() } + """ + } + } + + then { + assert workflow.success + assert snapshot(workflow.out).match() + } + + } + + test("Coverage - WES") { + + when { + workflow { + """ + // ch_meta_cram_crai_fasta_fai_roi + input[0] = Channel.of([ + [id: "test", single_end: false, tag: "WES"], // meta + file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/cram/sample1.sorted.cram", checkIfExists: true), + file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/cram/sample1.sorted.cram.crai", checkIfExists: true), + file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", checkIfExists: true), + file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", checkIfExists: true), + file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", checkIfExists: true), ]) + // genelists + def genelists_path = "s3://test-data/genomics/homo_sapiens/genome/regions/genelists" + input[1] = channel.fromPath(genelists_path + "/*.bed").collect().map{ files -> [ files ] }.ifEmpty { channel.empty() } """ } } diff --git a/tests/subworkflows/local/coverage/main.nf.test.snap b/tests/subworkflows/local/coverage/main.nf.test.snap index 068dc48d..cb468e45 100644 --- a/tests/subworkflows/local/coverage/main.nf.test.snap +++ b/tests/subworkflows/local/coverage/main.nf.test.snap @@ -1,113 +1,506 @@ { - "Coverage": { + "Coverage - WES": { "content": [ { "0": [ [ { "id": "test", - "single_end": false + "single_end": false, + "tag": "WES" }, - "test.mosdepth.summary.txt:md5,c929389c608f49ca01d800fb5cc94bb9" + "test.mosdepth.global.dist.txt:md5,ceec5e216dac6a4e15b961713ee8b16c" ] ], "1": [ [ { "id": "test", - "single_end": false + "single_end": false, + "tag": "WES" }, - "test.mosdepth.global.dist.txt:md5,ceec5e216dac6a4e15b961713ee8b16c" + "test.mosdepth.summary.txt:md5,c929389c608f49ca01d800fb5cc94bb9" + ] + ], + "10": [ + + ], + "11": [ + + ], + "12": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.coverage.txt:md5,2d81e108bf4175f2b892ab6e749fdf92" + ] + ], + "13": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + [ + "test_Treatable_ID_per_exon.mosdepth.region.dist.txt:md5,6c2b5237d98e0a2f118a3553c2ba478e", + "test_bladder_cancer_per_exon.mosdepth.region.dist.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] ], "2": [ [ { "id": "test", - "single_end": false + "single_end": false, + "tag": "WES" }, "test.mosdepth.region.dist.txt:md5,baffaa91e753347fd44c2e6e0a618d1f" ] ], "3": [ + + ], + "4": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.per-base.bed.gz:md5,c89a207273626f8415df1710bc522e8e" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.per-base.bed.gz.csi:md5,6593f9115e934350c326206088e8bc7c" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.regions.bed.gz:md5,82848481047cda38748ec0409db8a669" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.regions.bed.gz.csi:md5,68d13d373b9fd8b92535f566e77ed036" + ] + ], + "8": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.quantized.bed.gz:md5,8975e3f5a62bb2ea6f349539daf8e9a4" + ] + ], + "9": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.quantized.bed.gz.csi:md5,22e9d1096b7afd3d628526c831b26397" + ] + ], + "mosdepth_global": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.mosdepth.global.dist.txt:md5,ceec5e216dac6a4e15b961713ee8b16c" + ] + ], + "mosdepth_per_base_bed": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.per-base.bed.gz:md5,c89a207273626f8415df1710bc522e8e" + ] + ], + "mosdepth_per_base_csi": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.per-base.bed.gz.csi:md5,6593f9115e934350c326206088e8bc7c" + ] + ], + "mosdepth_per_base_d4": [ + + ], + "mosdepth_quantized_bed": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.quantized.bed.gz:md5,8975e3f5a62bb2ea6f349539daf8e9a4" + ] + ], + "mosdepth_quantized_csi": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.quantized.bed.gz.csi:md5,22e9d1096b7afd3d628526c831b26397" + ] + ], + "mosdepth_regions": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.mosdepth.region.dist.txt:md5,baffaa91e753347fd44c2e6e0a618d1f" + ] + ], + "mosdepth_regions_bed": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.regions.bed.gz:md5,82848481047cda38748ec0409db8a669" + ] + ], + "mosdepth_regions_csi": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.regions.bed.gz.csi:md5,68d13d373b9fd8b92535f566e77ed036" + ] + ], + "mosdepth_summary": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.mosdepth.summary.txt:md5,c929389c608f49ca01d800fb5cc94bb9" + ] + ], + "mosdepth_thresholds_bed": [ + + ], + "mosdepth_thresholds_csi": [ + + ], + "panelcoverage": [ [ { "id": "test", - "single_end": false + "single_end": false, + "tag": "WES" }, - "test.txt:md5,2d81e108bf4175f2b892ab6e749fdf92" + [ + "test_Treatable_ID_per_exon.mosdepth.region.dist.txt:md5,6c2b5237d98e0a2f118a3553c2ba478e", + "test_bladder_cancer_per_exon.mosdepth.region.dist.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] + ], + "samtools_coverage": [ + [ + { + "id": "test", + "single_end": false, + "tag": "WES" + }, + "test.coverage.txt:md5,2d81e108bf4175f2b892ab6e749fdf92" + ] + ] + } + ], + "timestamp": "2026-02-11T22:37:17.825377", + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.4" + } + }, + "Coverage - seqcap": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false, + "tag": "seqcap" + }, + "test.mosdepth.global.dist.txt:md5,ceec5e216dac6a4e15b961713ee8b16c" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false, + "tag": "seqcap" + }, + "test.mosdepth.summary.txt:md5,c929389c608f49ca01d800fb5cc94bb9" + ] + ], + "10": [ + + ], + "11": [ + + ], + "12": [ + [ + { + "id": "test", + "single_end": false, + "tag": "seqcap" + }, + "test.coverage.txt:md5,2d81e108bf4175f2b892ab6e749fdf92" + ] + ], + "13": [ + [ + { + "id": "test", + "single_end": false, + "tag": "seqcap" + }, + "test_seqcap_Connective_tissue_per_exon.mosdepth.region.dist.txt:md5,e098c901acb1da8c2cf64a248306e71c" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false, + "tag": "seqcap" + }, + "test.mosdepth.region.dist.txt:md5,baffaa91e753347fd44c2e6e0a618d1f" + ] + ], + "3": [ + ], "4": [ [ { "id": "test", - "single_end": false + "single_end": false, + "tag": "seqcap" }, - "test_genelist_chr21_per_exon.mosdepth.region.dist.txt:md5,e5c7b4f381721888249c57aa55be2d34" + "test.per-base.bed.gz:md5,c89a207273626f8415df1710bc522e8e" ] ], "5": [ - "versions.yml:md5,2d22ebfca674911d28ac60f352a98b1b", - "versions.yml:md5,731a006ffa265ac74ad677b4e5a68640", - "versions.yml:md5,d7c2bc4717e6518d6ce017a70a3f1df0" + [ + { + "id": "test", + "single_end": false, + "tag": "seqcap" + }, + "test.per-base.bed.gz.csi:md5,6593f9115e934350c326206088e8bc7c" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false, + "tag": "seqcap" + }, + "test.regions.bed.gz:md5,82848481047cda38748ec0409db8a669" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false, + "tag": "seqcap" + }, + "test.regions.bed.gz.csi:md5,68d13d373b9fd8b92535f566e77ed036" + ] + ], + "8": [ + [ + { + "id": "test", + "single_end": false, + "tag": "seqcap" + }, + "test.quantized.bed.gz:md5,8975e3f5a62bb2ea6f349539daf8e9a4" + ] + ], + "9": [ + [ + { + "id": "test", + "single_end": false, + "tag": "seqcap" + }, + "test.quantized.bed.gz.csi:md5,22e9d1096b7afd3d628526c831b26397" + ] ], "mosdepth_global": [ [ { "id": "test", - "single_end": false + "single_end": false, + "tag": "seqcap" }, "test.mosdepth.global.dist.txt:md5,ceec5e216dac6a4e15b961713ee8b16c" ] ], + "mosdepth_per_base_bed": [ + [ + { + "id": "test", + "single_end": false, + "tag": "seqcap" + }, + "test.per-base.bed.gz:md5,c89a207273626f8415df1710bc522e8e" + ] + ], + "mosdepth_per_base_csi": [ + [ + { + "id": "test", + "single_end": false, + "tag": "seqcap" + }, + "test.per-base.bed.gz.csi:md5,6593f9115e934350c326206088e8bc7c" + ] + ], + "mosdepth_per_base_d4": [ + + ], + "mosdepth_quantized_bed": [ + [ + { + "id": "test", + "single_end": false, + "tag": "seqcap" + }, + "test.quantized.bed.gz:md5,8975e3f5a62bb2ea6f349539daf8e9a4" + ] + ], + "mosdepth_quantized_csi": [ + [ + { + "id": "test", + "single_end": false, + "tag": "seqcap" + }, + "test.quantized.bed.gz.csi:md5,22e9d1096b7afd3d628526c831b26397" + ] + ], "mosdepth_regions": [ [ { "id": "test", - "single_end": false + "single_end": false, + "tag": "seqcap" }, "test.mosdepth.region.dist.txt:md5,baffaa91e753347fd44c2e6e0a618d1f" ] ], + "mosdepth_regions_bed": [ + [ + { + "id": "test", + "single_end": false, + "tag": "seqcap" + }, + "test.regions.bed.gz:md5,82848481047cda38748ec0409db8a669" + ] + ], + "mosdepth_regions_csi": [ + [ + { + "id": "test", + "single_end": false, + "tag": "seqcap" + }, + "test.regions.bed.gz.csi:md5,68d13d373b9fd8b92535f566e77ed036" + ] + ], "mosdepth_summary": [ [ { "id": "test", - "single_end": false + "single_end": false, + "tag": "seqcap" }, "test.mosdepth.summary.txt:md5,c929389c608f49ca01d800fb5cc94bb9" ] + ], + "mosdepth_thresholds_bed": [ + + ], + "mosdepth_thresholds_csi": [ + ], "panelcoverage": [ [ { "id": "test", - "single_end": false + "single_end": false, + "tag": "seqcap" }, - "test_genelist_chr21_per_exon.mosdepth.region.dist.txt:md5,e5c7b4f381721888249c57aa55be2d34" + "test_seqcap_Connective_tissue_per_exon.mosdepth.region.dist.txt:md5,e098c901acb1da8c2cf64a248306e71c" ] ], "samtools_coverage": [ [ { "id": "test", - "single_end": false + "single_end": false, + "tag": "seqcap" }, - "test.txt:md5,2d81e108bf4175f2b892ab6e749fdf92" + "test.coverage.txt:md5,2d81e108bf4175f2b892ab6e749fdf92" ] - ], - "versions": [ - "versions.yml:md5,2d22ebfca674911d28ac60f352a98b1b", - "versions.yml:md5,731a006ffa265ac74ad677b4e5a68640", - "versions.yml:md5,d7c2bc4717e6518d6ce017a70a3f1df0" ] } ], + "timestamp": "2026-02-11T22:36:21.526017", "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.1" - }, - "timestamp": "2024-11-19T15:25:37.147132" + "nf-test": "0.9.3", + "nextflow": "25.10.4" + } } } \ No newline at end of file diff --git a/tests/subworkflows/local/fastq_align_rna/main.nf.test b/tests/subworkflows/local/fastq_align_rna/main.nf.test index 05f22be6..c8319d20 100644 --- a/tests/subworkflows/local/fastq_align_rna/main.nf.test +++ b/tests/subworkflows/local/fastq_align_rna/main.nf.test @@ -39,9 +39,7 @@ nextflow_workflow { then { assert workflow.success assert snapshot( - workflow.out.bam.collect { it.collect { it instanceof Map ? it : file(it).name } }, - workflow.out.reports.collect { it.collect { it instanceof Map ? it : file(it).name } }, - workflow.out.versions + sanitizeOutput(workflow.out, unstableKeys:["bam", "reports", "junctions"]) ).match() } diff --git a/tests/subworkflows/local/fastq_align_rna/main.nf.test.snap b/tests/subworkflows/local/fastq_align_rna/main.nf.test.snap index cb4a1d6d..900be6c9 100644 --- a/tests/subworkflows/local/fastq_align_rna/main.nf.test.snap +++ b/tests/subworkflows/local/fastq_align_rna/main.nf.test.snap @@ -1,71 +1,106 @@ { "fastq align rna - star": { "content": [ - [ - [ - { - "id": "test", - "samplename": "test", - "single_end": false, - "sample_type": "RNA", - "genome": { - "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", - "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai" - } - }, - "test.Aligned.out.bam" - ] - ], - [ - [ - { - "id": "test", - "samplename": "test", - "single_end": false, - "sample_type": "RNA", - "genome": { - "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", - "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai" - } - }, - "test.Log.final.out" + { + "bam": [ + [ + { + "genome": { + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna" + }, + "id": "test", + "sample_type": "RNA", + "samplename": "test", + "single_end": false + }, + "test.star.Aligned.out.bam" + ] ], - [ - { - "id": "test", - "samplename": "test", - "single_end": false, - "sample_type": "RNA", - "genome": { - "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", - "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai" - } - }, - "test.Log.out" + "junctions": [ + [ + { + "groupSize": 1, + "groupTarget": { + "genome": { + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna" + }, + "id": "test", + "sample_type": "RNA", + "samplename": "test", + "single_end": false + } + }, + "test.Chimeric.out.junction" + ] ], - [ - { - "id": "test", - "samplename": "test", - "single_end": false, - "sample_type": "RNA", - "genome": { - "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", - "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai" - } - }, - "test.Log.progress.out" + "reports": [ + [ + { + "genome": { + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna" + }, + "id": "test", + "sample_type": "RNA", + "samplename": "test", + "single_end": false + }, + "test.star.Log.final.out" + ], + [ + { + "genome": { + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna" + }, + "id": "test", + "sample_type": "RNA", + "samplename": "test", + "single_end": false + }, + "test.star.Log.out" + ], + [ + { + "genome": { + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna" + }, + "id": "test", + "sample_type": "RNA", + "samplename": "test", + "single_end": false + }, + "test.star.Log.progress.out" + ] + ], + "splice_junctions": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "samplename": "test", + "single_end": false, + "sample_type": "RNA", + "genome": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai" + } + } + }, + "test.SJ.out.tab:md5,15852c5678c04e86dcb66793b7e02bb9" + ] ] - ], - [ - "versions.yml:md5,a08c174f2d393f0b39c2cfe003ffafb9" - ] + } ], + "timestamp": "2026-02-11T22:49:27.454517", "meta": { - "nf-test": "0.9.1", - "nextflow": "24.10.3" - }, - "timestamp": "2025-01-14T10:45:55.903470736" + "nf-test": "0.9.3", + "nextflow": "25.10.4" + } }, "fastq align rna - unknown aligner": { "content": [ @@ -73,10 +108,10 @@ "Unsupported aligner woop for sample test" ] ], + "timestamp": "2024-05-28T16:17:08.089796673", "meta": { "nf-test": "0.8.4", "nextflow": "24.04.1" - }, - "timestamp": "2024-05-28T16:17:08.089796673" + } } } \ No newline at end of file diff --git a/tests/subworkflows/local/fastq_to_aligned_cram/main.nf.test b/tests/subworkflows/local/fastq_to_aligned_cram/main.nf.test index bd73587b..65b68c4c 100644 --- a/tests/subworkflows/local/fastq_to_aligned_cram/main.nf.test +++ b/tests/subworkflows/local/fastq_to_aligned_cram/main.nf.test @@ -19,6 +19,7 @@ nextflow_workflow { samplename:'test', single_end:false, sample_type:'DNA', + markdup: "bamsormadup", genome_data: [ fasta: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", fai: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai" @@ -33,8 +34,6 @@ nextflow_workflow { file("s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna"), [] ]) - // markdup - input[1] = "bamsormadup" """ } } @@ -44,9 +43,7 @@ nextflow_workflow { { assert workflow.success assert snapshot( - workflow.out.cram_crai.collect { it.findAll { !(it instanceof Map) }.collect { file(it).name } }, - workflow.out.multiqc_files, - workflow.out.versions + sanitizeOutput(workflow.out, unstableKeys:["cram_crai"]) ).match() } ) @@ -64,9 +61,11 @@ nextflow_workflow { samplename:'test', single_end:false, sample_type:'RNA', + markdup: "bamsormadup", genome_data: [ fasta: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", - fai: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai" + fai: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + star: "s3://test-data/genomics/homo_sapiens/genome/star/" ] ], // meta map [ @@ -78,8 +77,6 @@ nextflow_workflow { file("s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna"), [] ]) - // markdup - input[1] = "bamsormadup" """ } } @@ -89,9 +86,7 @@ nextflow_workflow { { assert workflow.success assert snapshot( - workflow.out.cram_crai.collect { it.findAll { !(it instanceof Map) }.collect { file(it).name } }, - workflow.out.multiqc_files, - workflow.out.versions + sanitizeOutput(workflow.out, unstableKeys:["cram_crai","rna_junctions"]) ).match() } ) @@ -105,10 +100,11 @@ nextflow_workflow { // [meta, [fq_1,fq_2], aligner, index, fasta] input[0] = Channel.of([ [ - id:'test', - samplename:'test', - single_end:false, - sample_type:'DNA', + id: "test", + samplename: "test", + single_end: false, + sample_type: "DNA", + markdup: "samtools", genome_data: [ fasta: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", fai: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai" @@ -123,8 +119,6 @@ nextflow_workflow { file("s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna"), [] ]) - // markdup - input[1] = "samtools" """ } } @@ -134,9 +128,7 @@ nextflow_workflow { { assert workflow.success assert snapshot( - workflow.out.cram_crai.collect { it.findAll { !(it instanceof Map) }.collect { file(it).name } }, - workflow.out.multiqc_files, - workflow.out.versions + sanitizeOutput(workflow.out, unstableKeys:["cram_crai"]) ).match() } ) @@ -150,10 +142,11 @@ nextflow_workflow { // [meta, [fq_1,fq_2], aligner, index, fasta] input[0] = Channel.of([ [ - id:'test', - samplename:'test', - single_end:false, - sample_type:'DNA', + id: "test", + samplename: "test", + single_end: false, + sample_type: "DNA", + markdup: "false", genome_data: [ fasta: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", fai: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai" @@ -168,8 +161,6 @@ nextflow_workflow { file("s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna"), [] ]) - // markdup - input[1] = "false" """ } } @@ -179,9 +170,7 @@ nextflow_workflow { { assert workflow.success assert snapshot( - workflow.out.cram_crai.collect { it.findAll { !(it instanceof Map) }.collect { file(it).name } }, - workflow.out.multiqc_files, - workflow.out.versions + sanitizeOutput(workflow.out, unstableKeys:["cram_crai"]) ).match() } ) @@ -196,10 +185,11 @@ nextflow_workflow { // [meta, [fq_1,fq_2], aligner, index, fasta] input[0] = Channel.of([ [ - id:'test', - samplename:'test', - single_end:false, - sample_type:'DNA', + id: "test", + samplename: "test", + single_end: false, + sample_type: "DNA", + markdup: "false", genome_data: [ fasta: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", fai: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai" @@ -214,8 +204,6 @@ nextflow_workflow { file("s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna"), [] ]) - // markdup - input[1] = "false" """ } } @@ -225,9 +213,7 @@ nextflow_workflow { { assert workflow.success assert snapshot( - workflow.out.cram_crai.collect { it.findAll { !(it instanceof Map) }.collect { file(it).name } }, - workflow.out.multiqc_files, - workflow.out.versions + sanitizeOutput(workflow.out, unstableKeys:["cram_crai"]) ).match() } ) diff --git a/tests/subworkflows/local/fastq_to_aligned_cram/main.nf.test.snap b/tests/subworkflows/local/fastq_to_aligned_cram/main.nf.test.snap index ad5924a6..e5a3ef5f 100644 --- a/tests/subworkflows/local/fastq_to_aligned_cram/main.nf.test.snap +++ b/tests/subworkflows/local/fastq_to_aligned_cram/main.nf.test.snap @@ -1,115 +1,301 @@ { "fastq to cram - stub": { "content": [ - [ - [ - "test.merged.cram", - "test.merged.cram.crai" + { + "align_reports": [ + + ], + "cram_crai": [ + [ + { + "groupSize": 1, + "groupTarget": { + "genome_data": { + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna" + }, + "id": "test", + "markdup": "false", + "sample_type": "DNA", + "samplename": "test", + "single_end": false + } + }, + "test.merged.cram", + "test.merged.cram.crai" + ] + ], + "rna_junctions": [ + + ], + "rna_splice_junctions": [ + + ], + "sormadup_metrics": [ + ] - ], - [ - - ], - [ - "versions.yml:md5,a7ccfeb53d42f57673ea59012c30e897", - "versions.yml:md5,d92f130d879deee51a23917c6e272233", - "versions.yml:md5,d92f130d879deee51a23917c6e272233" - ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2025-06-03T10:39:18.407178" + "timestamp": "2026-02-11T20:19:51.825749" }, "fastq to cram - bwa - bamsormadup": { "content": [ - [ - [ - "test.cram", - "test.cram.crai" + { + "align_reports": [ + + ], + "cram_crai": [ + [ + { + "groupSize": 1, + "groupTarget": { + "genome_data": { + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna" + }, + "id": "test", + "markdup": "bamsormadup", + "sample_type": "DNA", + "samplename": "test", + "single_end": false + } + }, + "test.cram", + "test.cram.crai" + ] + ], + "rna_junctions": [ + + ], + "rna_splice_junctions": [ + + ], + "sormadup_metrics": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "samplename": "test", + "single_end": false, + "sample_type": "DNA", + "markdup": "bamsormadup", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai" + } + } + }, + "test.merged.metrics.txt:md5,4ee20f12cb4d6077479a08310c8f6c70" + ] ] - ], - [ - "test.merged.metrics.txt:md5,4ee20f12cb4d6077479a08310c8f6c70" - ], - [ - "versions.yml:md5,d8544811f6b511ef45e9c3547430a30d", - "versions.yml:md5,d92f130d879deee51a23917c6e272233", - "versions.yml:md5,d92f130d879deee51a23917c6e272233" - ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2025-06-03T10:36:05.605497" + "timestamp": "2026-02-11T20:10:31.616836" }, "fastq to cram - bwa - samtools sormadup": { "content": [ - [ - [ - "test.merged.cram", - "test.merged.cram.crai" + { + "align_reports": [ + + ], + "cram_crai": [ + [ + { + "groupSize": 1, + "groupTarget": { + "genome_data": { + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna" + }, + "id": "test", + "markdup": "samtools", + "sample_type": "DNA", + "samplename": "test", + "single_end": false + } + }, + "test.merged.cram", + "test.merged.cram.crai" + ] + ], + "rna_junctions": [ + + ], + "rna_splice_junctions": [ + + ], + "sormadup_metrics": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "samplename": "test", + "single_end": false, + "sample_type": "DNA", + "markdup": "samtools", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai" + } + } + }, + "test.merged.metrics:md5,795c73aa836eb480e418f52db98e37cc" + ] ] - ], - [ - "test.merged.metrics:md5,6e4d03a56877997e0e035d267550e381" - ], - [ - "versions.yml:md5,7d966b1716b0f134534741313257f0ec", - "versions.yml:md5,d92f130d879deee51a23917c6e272233", - "versions.yml:md5,d92f130d879deee51a23917c6e272233" - ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2025-06-03T10:38:15.994769" + "timestamp": "2026-02-11T20:15:15.495706" }, "fastq to cram - star - bamsormadup": { "content": [ - [ - [ - "test.cram", - "test.cram.crai" + { + "align_reports": [ + + ], + "cram_crai": [ + [ + { + "groupSize": 1, + "groupTarget": { + "genome_data": { + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "star": "s3://test-data/genomics/homo_sapiens/genome/star/" + }, + "id": "test", + "markdup": "bamsormadup", + "sample_type": "RNA", + "samplename": "test", + "single_end": false + } + }, + "test.cram", + "test.cram.crai" + ] + ], + "rna_junctions": [ + [ + { + "groupSize": 1, + "groupTarget": { + "genome_data": { + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "star": "s3://test-data/genomics/homo_sapiens/genome/star/" + }, + "id": "test", + "markdup": "bamsormadup", + "sample_type": "RNA", + "samplename": "test", + "single_end": false + } + }, + "test.Chimeric.out.junction" + ] + ], + "rna_splice_junctions": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "samplename": "test", + "single_end": false, + "sample_type": "RNA", + "markdup": "bamsormadup", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "star": "s3://test-data/genomics/homo_sapiens/genome/star/" + } + } + }, + "test.SJ.out.tab:md5,15852c5678c04e86dcb66793b7e02bb9" + ] + ], + "sormadup_metrics": [ + [ + { + "groupSize": 1, + "groupTarget": { + "id": "test", + "samplename": "test", + "single_end": false, + "sample_type": "RNA", + "markdup": "bamsormadup", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "star": "s3://test-data/genomics/homo_sapiens/genome/star/" + } + } + }, + "test.merged.metrics.txt:md5,641527401576375d7c0b0b54fbaf63ab" + ] ] - ], - [ - "test.merged.metrics.txt:md5,641527401576375d7c0b0b54fbaf63ab" - ], - [ - "versions.yml:md5,d8544811f6b511ef45e9c3547430a30d" - ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2024-07-16T08:41:12.044485" + "timestamp": "2026-02-19T11:32:22.214357" }, "fastq to cram - bwa - samtools sort": { "content": [ - [ - [ - "test.merged.cram", - "test.merged.cram.crai" + { + "align_reports": [ + + ], + "cram_crai": [ + [ + { + "groupSize": 1, + "groupTarget": { + "genome_data": { + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna" + }, + "id": "test", + "markdup": "false", + "sample_type": "DNA", + "samplename": "test", + "single_end": false + } + }, + "test.merged.cram", + "test.merged.cram.crai" + ] + ], + "rna_junctions": [ + + ], + "rna_splice_junctions": [ + + ], + "sormadup_metrics": [ + ] - ], - [ - - ], - [ - "versions.yml:md5,a7ccfeb53d42f57673ea59012c30e897", - "versions.yml:md5,d92f130d879deee51a23917c6e272233", - "versions.yml:md5,d92f130d879deee51a23917c6e272233" - ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.2" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2025-06-03T10:38:46.909512" + "timestamp": "2026-02-11T20:16:26.285299" } } \ No newline at end of file diff --git a/tests/subworkflows/local/fastq_to_unaligned_cram/main.nf.test b/tests/subworkflows/local/fastq_to_unaligned_cram/main.nf.test deleted file mode 100644 index c3f9d375..00000000 --- a/tests/subworkflows/local/fastq_to_unaligned_cram/main.nf.test +++ /dev/null @@ -1,37 +0,0 @@ -nextflow_workflow { - - name "Test Workflow FASTQ_TO_UCRAM" - script "subworkflows/local/fastq_to_unaligned_cram/main.nf" - workflow "FASTQ_TO_UCRAM" - - tag "subworkflows" - tag "subworkflows/local" - tag "subworkflows/local/fastq_to_unaligned_cram" - - test("fastq to unaligned cram") { - - when { - workflow { - """ - input[0] = Channel.of([ - [ id:'test', samplename:'test', single_end:false ], // meta map - [ - file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/fastq/sample1_R1.fastq.gz", checkIfExists: true), - file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/fastq/sample1_R2.fastq.gz", checkIfExists: true) - ] - ]) - """ - } - } - - then { - assert workflow.success - assert snapshot( - file(workflow.out.cram[0][1]).name, - workflow.out.versions - ).match() - } - - } - -} diff --git a/tests/subworkflows/local/fastq_to_unaligned_cram/main.nf.test.snap b/tests/subworkflows/local/fastq_to_unaligned_cram/main.nf.test.snap deleted file mode 100644 index be64fb72..00000000 --- a/tests/subworkflows/local/fastq_to_unaligned_cram/main.nf.test.snap +++ /dev/null @@ -1,16 +0,0 @@ -{ - "fastq to unaligned cram": { - "content": [ - "test.unaligned.cram", - [ - "versions.yml:md5,422c9b3605121c3528ee755bbdb12a85", - "versions.yml:md5,f494e9f15ef064e11d31abca2f2ba51c" - ] - ], - "meta": { - "nf-test": "0.9.2", - "nextflow": "24.10.1" - }, - "timestamp": "2024-11-19T15:29:54.134408" - } -} \ No newline at end of file diff --git a/tests/workflows/preprocessing.nf.test b/tests/workflows/preprocessing.nf.test index 0bb017be..d8bac5f5 100644 --- a/tests/workflows/preprocessing.nf.test +++ b/tests/workflows/preprocessing.nf.test @@ -21,7 +21,11 @@ nextflow_workflow { library: "test", organism: "Homo sapiens", tag: "WES", - sample_type: "DNA" + sample_type: "DNA", + aligner: "bwamem", + markdup: "bamsormadup", + run_coverage: true, + roi: file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", checkIfExists: true) ], //fastq_1 file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/fastq/sample1_R1.fastq.gz", checkIfExists: true), @@ -43,12 +47,13 @@ nextflow_workflow { gtf: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" ] ] - // aligner - input[2] = "bwamem" - // markdup - input[3] = "bamsormadup" - // roi - input[4] = "https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed" + // genelists + input[2] = null + // mqc_config + input[3] = [file("${projectDir}/assets/multiqc_config.yml", checkIfExists: true)] + // mqc_logo + input[4] = [] + // mqc methods description input[5] = null """ } @@ -57,8 +62,24 @@ nextflow_workflow { then { assert workflow.success assert snapshot( - file(workflow.out.multiqc_report[0][0]).name, - workflow.out.versions + sanitizeOutput(workflow.out, unstableKeys:[ + "multiqc_report", + "multiqc_data", + "multiqc_plots", + "multiqcsav_report", + "multiqcsav_data", + "multiqcsav_plots", + "md5sums", + "fastp_html", + "crams", + "picard_wgsmetrics", + "picard_multiplemetrics_pdf", + "picard_multiplemetrics", + "picard_hsmetrics", + "samtools_flagstat", + "samtools_coverage", + "samtools_stats" + ]) ).match() } } @@ -77,7 +98,10 @@ nextflow_workflow { library: "test", organism: "Homo sapiens", tag: "WGS", - sample_type: "DNA" + sample_type: "DNA", + aligner: "bwamem", + markdup: "bamsormadup", + run_coverage: true ], //fastq_1 file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/fastq/sample1_R1.fastq.gz", checkIfExists: true), @@ -99,12 +123,13 @@ nextflow_workflow { gtf: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" ] ] - // aligner - input[2] = "bwamem" - // markdup - input[3] = "bamsormadup" - // roi - input[4] = "" + // genelists + input[2] = null + // mqc_config + input[3] = [file("${projectDir}/assets/multiqc_config.yml", checkIfExists: true)] + // mqc_logo + input[4] = [] + // mqc methods description input[5] = null """ } @@ -113,8 +138,24 @@ nextflow_workflow { then { assert workflow.success assert snapshot( - file(workflow.out.multiqc_report[0][0]).name, - workflow.out.versions + sanitizeOutput(workflow.out, unstableKeys:[ + "multiqc_report", + "multiqc_data", + "multiqc_plots", + "multiqcsav_report", + "multiqcsav_data", + "multiqcsav_plots", + "md5sums", + "fastp_html", + "crams", + "picard_wgsmetrics", + "picard_multiplemetrics_pdf", + "picard_multiplemetrics", + "picard_hsmetrics", + "samtools_flagstat", + "samtools_coverage", + "samtools_stats" + ]) ).match() } } @@ -136,7 +177,12 @@ nextflow_workflow { library: "test", organism: "Homo sapiens", tag: "WES", - sample_type: "DNA" + sample_type: "DNA", + aligner: "bwamem", + markdup: "bamsormadup", + run_coverage: false, + disable_picard_metrics: true, + roi: file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", checkIfExists: true) ], //fastq_1 file("https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/fastq/sample1_R1.fastq.gz", checkIfExists: true), @@ -158,12 +204,13 @@ nextflow_workflow { gtf: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" ] ] - // aligner - input[2] = "bwamem" - // markdup - input[3] = "bamsormadup" - // roi - input[4] = "https://github.com/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed" + // genelists + input[2] = null + // mqc_config + input[3] = [file("${projectDir}/assets/multiqc_config.yml", checkIfExists: true)] + // mqc_logo + input[4] = [] + // mqc methods description input[5] = null """ } @@ -172,9 +219,100 @@ nextflow_workflow { then { assert workflow.success assert snapshot( - file(workflow.out.multiqc_report[0][0]).name, - workflow.out.versions + sanitizeOutput(workflow.out, unstableKeys:[ + "multiqc_report", + "multiqc_data", + "multiqc_plots", + "multiqcsav_report", + "multiqcsav_data", + "multiqcsav_plots", + "md5sums", + "fastp_html", + "crams", + "picard_wgsmetrics", + "picard_multiplemetrics_pdf", + "picard_multiplemetrics", + "picard_hsmetrics", + "samtools_flagstat", + "samtools_coverage", + "samtools_stats" + ]) ).match() } } + + test("preprocessing - flowcell - bwa - bamsormadup - roi") { + when { + workflow { + """ + // ch_samplesheet + input[0] = Channel.of( + [ + [ // meta + id: "200624_A00834_0183_BHMTFYDRXX", + lane: 1, + ], + [], // fastq_1 + [], // fastq_2 + file("https://github.com/nf-cmgg/test-datasets/raw/refs/heads/preprocessing/data/genomics/homo_sapiens/illumina/flowcell/SampleSheet_2.csv", checkIfExists: true), + file("https://github.com/nf-cmgg/test-datasets/raw/refs/heads/preprocessing/data/genomics/homo_sapiens/illumina/flowcell/SampleInfo_2.json", checkIfExists: true), + file("s3://test-data/genomics/homo_sapiens/illumina/bcl", checkIfExists: true) + + ] + ) + // genomes + input[1] = [ + GRCh38: [ + fasta: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + fai: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + dict: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + bwamem: "s3://test-data/genomics/homo_sapiens/genome/bwa/", + gtf: "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + ] + ] + // genelists + input[2] = null + // mqc_config + input[3] = [file("${projectDir}/assets/multiqc_config.yml", checkIfExists: true)] + // mqc_logo + input[4] = [] + // mqc methods description + input[5] = null + """ + } + } + + then { + assert workflow.success + assert snapshot( + sanitizeOutput(workflow.out, unstableKeys:[ + "demultiplex_logs", + "demultiplex_reports", + "multiqc_report", + "multiqc_data", + "multiqc_plots", + "multiqcsav_report", + "multiqcsav_data", + "multiqcsav_plots", + "md5sums", + "fastp_html", + "crams", + "picard_wgsmetrics", + "picard_multiplemetrics_pdf", + "picard_multiplemetrics", + "picard_hsmetrics", + "samtools_flagstat", + "samtools_coverage", + "samtools_stats" + ]).collectEntries { key, value -> + if (key in ["demultiplex_logs", "demultiplex_reports"]) { + [ key: value.sort() ] + } else { + [ key: value ] + } + } + ).match() + } + } + } diff --git a/tests/workflows/preprocessing.nf.test.snap b/tests/workflows/preprocessing.nf.test.snap index 80141e0d..f1d096fa 100644 --- a/tests/workflows/preprocessing.nf.test.snap +++ b/tests/workflows/preprocessing.nf.test.snap @@ -1,67 +1,1782 @@ { "preprocessing - fastq - bwa - bamsormadup - roi": { "content": [ - "multiqc_report.html", - [ - "versions.yml:md5,321e55c8f19102dc87a10e981635edda", - "versions.yml:md5,3e9382a1dc62d4f405bcfb58fe6b7768", - "versions.yml:md5,4445e842758f99d74d032eab0af01ff6", - "versions.yml:md5,4445e842758f99d74d032eab0af01ff6", - "versions.yml:md5,67e17554941666c3f3da7ab6e3b1ac5d", - "versions.yml:md5,84a41fdb642c270c5f36846cd7d8f033", - "versions.yml:md5,8ede2c6189fe1f73ef7e36b42528473c", - "versions.yml:md5,a18197a27823760677276bdf9a17c0b6", - "versions.yml:md5,d11c133ecb39ba9f6d7e081a8a6ff868", - "versions.yml:md5,ebdd9fe0c553612c66238375b920f178", - "versions.yml:md5,fecf2763ae04725fa0ca7c995018dcea" - ] + { + "align_reports": [ + + ], + "crams": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WES" + } + }, + "sample1.cram", + "sample1.cram.crai" + ] + ], + "demultiplex_fastq": [ + + ], + "demultiplex_interop": [ + + ], + "demultiplex_logs": [ + + ], + "demultiplex_reports": [ + + ], + "falco_html": [ + + ], + "falco_txt": [ + + ], + "fastp_html": [ + [ + { + "aligner": "bwamem", + "count": 1, + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "readgroup": { + "CN": "", + "ID": "H5T2YDSX3.1", + "LB": "test", + "PL": "ILLUMINA", + "PU": "H5T2YDSX3.1", + "SM": "sample1" + }, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WES" + }, + "sample1.fastp.html" + ] + ], + "fastp_json": [ + [ + { + "id": "sample1", + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WES", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "single_end": false, + "readgroup": { + "LB": "test", + "CN": "", + "PL": "ILLUMINA", + "SM": "sample1", + "ID": "H5T2YDSX3.1", + "PU": "H5T2YDSX3.1" + }, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "count": 1 + }, + "sample1.fastp.json:md5,5a65f5141251ac26b8f0a0d0a618b524" + ] + ], + "md5sums": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WES" + } + }, + "sample1.md5" + ] + ], + "mosdepth_global": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WES", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.mosdepth.global.dist.txt:md5,4574a0f755903d7ab7aa07297cc1efee" + ] + ], + "mosdepth_per_base_bed": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WES", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.per-base.bed.gz:md5,e5c10c94f3870f6ed2c75a904e9ade7f" + ] + ], + "mosdepth_per_base_csi": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WES", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.per-base.bed.gz.csi:md5,b9223463b0f024768ebbbb3e42ace8da" + ] + ], + "mosdepth_per_base_d4": [ + + ], + "mosdepth_quantized_bed": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WES", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.quantized.bed.gz:md5,d54d469a692c3fe4a4e1db02c08be518" + ] + ], + "mosdepth_quantized_csi": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WES", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.quantized.bed.gz.csi:md5,efa0455ec39b49b96fd44c1efcbef8ab" + ] + ], + "mosdepth_regions": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WES", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.mosdepth.region.dist.txt:md5,388e05b0b4d7754be6fdc0b1b6eabed9" + ] + ], + "mosdepth_regions_bed": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WES", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.regions.bed.gz:md5,6b7cc84380695011ffd0681dc79cefaa" + ] + ], + "mosdepth_regions_csi": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WES", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.regions.bed.gz.csi:md5,45cbd8c0f3d231c114a2d79d7dd21a80" + ] + ], + "mosdepth_summary": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WES", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.mosdepth.summary.txt:md5,f1f18d9bd23783bedb7f9e246e192a7e" + ] + ], + "mosdepth_thresholds_bed": [ + + ], + "mosdepth_thresholds_csi": [ + + ], + "multiqc_data": [ + [ + { + "id": "test" + }, + "test_data" + ] + ], + "multiqc_plots": [ + + ], + "multiqc_report": [ + [ + { + "id": "test" + }, + "test.html" + ] + ], + "multiqcsav_data": [ + [ + + ] + ], + "multiqcsav_plots": [ + [ + + ] + ], + "multiqcsav_report": [ + [ + + ] + ], + "panelcoverage": [ + + ], + "picard_hsmetrics": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WES" + } + }, + "sample1.CollectHsMetrics.coverage_metrics" + ] + ], + "picard_multiplemetrics": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WES" + } + }, + [ + "sample1.CollectMultipleMetrics.alignment_summary_metrics", + "sample1.CollectMultipleMetrics.base_distribution_by_cycle_metrics", + "sample1.CollectMultipleMetrics.quality_by_cycle_metrics", + "sample1.CollectMultipleMetrics.quality_distribution_metrics" + ] + ] + ], + "picard_multiplemetrics_pdf": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WES" + } + }, + [ + "sample1.CollectMultipleMetrics.base_distribution_by_cycle.pdf", + "sample1.CollectMultipleMetrics.quality_by_cycle.pdf", + "sample1.CollectMultipleMetrics.quality_distribution.pdf", + "sample1.CollectMultipleMetrics.read_length_histogram.pdf" + ] + ] + ], + "picard_wgsmetrics": [ + + ], + "rna_junctions": [ + + ], + "rna_splice_junctions": [ + + ], + "samtools_coverage": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WES" + } + }, + "sample1.coverage.txt" + ] + ], + "samtools_flagstat": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WES" + } + }, + "sample1.flagstat" + ] + ], + "samtools_idxstats": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WES", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.idxstats:md5,ecc89a474dced28b0610f17a82785007" + ] + ], + "samtools_stats": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WES" + } + }, + "sample1.stats" + ] + ], + "sormadup_metrics": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WES", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.merged.metrics.txt:md5,01b7286134f5cb6530c3bab2c86fd169" + ] + ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2025-06-04T14:32:22.782118028" + "timestamp": "2026-03-05T14:04:31.848677" }, "preprocessing - fastq - bwa - bamsormadup - roi - no coverage/no picard": { "content": [ - "multiqc_report.html", - [ - "versions.yml:md5,321e55c8f19102dc87a10e981635edda", - "versions.yml:md5,4445e842758f99d74d032eab0af01ff6", - "versions.yml:md5,4445e842758f99d74d032eab0af01ff6", - "versions.yml:md5,67e17554941666c3f3da7ab6e3b1ac5d", - "versions.yml:md5,8ede2c6189fe1f73ef7e36b42528473c", - "versions.yml:md5,a18197a27823760677276bdf9a17c0b6", - "versions.yml:md5,d11c133ecb39ba9f6d7e081a8a6ff868" - ] + { + "align_reports": [ + + ], + "crams": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "disable_picard_metrics": true, + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "run_coverage": false, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WES" + } + }, + "sample1.cram", + "sample1.cram.crai" + ] + ], + "demultiplex_fastq": [ + + ], + "demultiplex_interop": [ + + ], + "demultiplex_logs": [ + + ], + "demultiplex_reports": [ + + ], + "falco_html": [ + + ], + "falco_txt": [ + + ], + "fastp_html": [ + [ + { + "aligner": "bwamem", + "count": 1, + "disable_picard_metrics": true, + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "readgroup": { + "CN": "", + "ID": "H5T2YDSX3.1", + "LB": "test", + "PL": "ILLUMINA", + "PU": "H5T2YDSX3.1", + "SM": "sample1" + }, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "run_coverage": false, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WES" + }, + "sample1.fastp.html" + ] + ], + "fastp_json": [ + [ + { + "id": "sample1", + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WES", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": false, + "disable_picard_metrics": true, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "single_end": false, + "readgroup": { + "LB": "test", + "CN": "", + "PL": "ILLUMINA", + "SM": "sample1", + "ID": "H5T2YDSX3.1", + "PU": "H5T2YDSX3.1" + }, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "count": 1 + }, + "sample1.fastp.json:md5,5a65f5141251ac26b8f0a0d0a618b524" + ] + ], + "md5sums": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "disable_picard_metrics": true, + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "run_coverage": false, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WES" + } + }, + "sample1.md5" + ] + ], + "mosdepth_global": [ + + ], + "mosdepth_per_base_bed": [ + + ], + "mosdepth_per_base_csi": [ + + ], + "mosdepth_per_base_d4": [ + + ], + "mosdepth_quantized_bed": [ + + ], + "mosdepth_quantized_csi": [ + + ], + "mosdepth_regions": [ + + ], + "mosdepth_regions_bed": [ + + ], + "mosdepth_regions_csi": [ + + ], + "mosdepth_summary": [ + + ], + "mosdepth_thresholds_bed": [ + + ], + "mosdepth_thresholds_csi": [ + + ], + "multiqc_data": [ + [ + { + "id": "test" + }, + "test_data" + ] + ], + "multiqc_plots": [ + + ], + "multiqc_report": [ + [ + { + "id": "test" + }, + "test.html" + ] + ], + "multiqcsav_data": [ + [ + + ] + ], + "multiqcsav_plots": [ + [ + + ] + ], + "multiqcsav_report": [ + [ + + ] + ], + "panelcoverage": [ + + ], + "picard_hsmetrics": [ + + ], + "picard_multiplemetrics": [ + + ], + "picard_multiplemetrics_pdf": [ + + ], + "picard_wgsmetrics": [ + + ], + "rna_junctions": [ + + ], + "rna_splice_junctions": [ + + ], + "samtools_coverage": [ + + ], + "samtools_flagstat": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "disable_picard_metrics": true, + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "run_coverage": false, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WES" + } + }, + "sample1.flagstat" + ] + ], + "samtools_idxstats": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WES", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": false, + "disable_picard_metrics": true, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.idxstats:md5,ecc89a474dced28b0610f17a82785007" + ] + ], + "samtools_stats": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "disable_picard_metrics": true, + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "run_coverage": false, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WES" + } + }, + "sample1.stats" + ] + ], + "sormadup_metrics": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WES", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": false, + "disable_picard_metrics": true, + "roi": "/nf-cmgg/test-datasets/raw/preprocessing/data/genomics/homo_sapiens/illumina/regions/roi_chr21.bed", + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.merged.metrics.txt:md5,01b7286134f5cb6530c3bab2c86fd169" + ] + ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2025-06-04T14:36:49.460737865" + "timestamp": "2026-03-05T14:08:24.880945" }, "preprocessing - fastq - bwa - bamsormadup - no roi": { "content": [ - "multiqc_report.html", - [ - "versions.yml:md5,2dbfdf50978986550dbe621f1d49fea7", - "versions.yml:md5,321e55c8f19102dc87a10e981635edda", - "versions.yml:md5,3e9382a1dc62d4f405bcfb58fe6b7768", - "versions.yml:md5,4445e842758f99d74d032eab0af01ff6", - "versions.yml:md5,4445e842758f99d74d032eab0af01ff6", - "versions.yml:md5,67e17554941666c3f3da7ab6e3b1ac5d", - "versions.yml:md5,84a41fdb642c270c5f36846cd7d8f033", - "versions.yml:md5,8ede2c6189fe1f73ef7e36b42528473c", - "versions.yml:md5,a18197a27823760677276bdf9a17c0b6", - "versions.yml:md5,d11c133ecb39ba9f6d7e081a8a6ff868", - "versions.yml:md5,fecf2763ae04725fa0ca7c995018dcea" - ] + { + "align_reports": [ + + ], + "crams": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WGS" + } + }, + "sample1.cram", + "sample1.cram.crai" + ] + ], + "demultiplex_fastq": [ + + ], + "demultiplex_interop": [ + + ], + "demultiplex_logs": [ + + ], + "demultiplex_reports": [ + + ], + "falco_html": [ + + ], + "falco_txt": [ + + ], + "fastp_html": [ + [ + { + "aligner": "bwamem", + "count": 1, + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "readgroup": { + "CN": "", + "ID": "H5T2YDSX3.1", + "LB": "test", + "PL": "ILLUMINA", + "PU": "H5T2YDSX3.1", + "SM": "sample1" + }, + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WGS" + }, + "sample1.fastp.html" + ] + ], + "fastp_json": [ + [ + { + "id": "sample1", + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WGS", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "single_end": false, + "readgroup": { + "LB": "test", + "CN": "", + "PL": "ILLUMINA", + "SM": "sample1", + "ID": "H5T2YDSX3.1", + "PU": "H5T2YDSX3.1" + }, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "count": 1 + }, + "sample1.fastp.json:md5,5a65f5141251ac26b8f0a0d0a618b524" + ] + ], + "md5sums": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WGS" + } + }, + "sample1.md5" + ] + ], + "mosdepth_global": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WGS", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.mosdepth.global.dist.txt:md5,4574a0f755903d7ab7aa07297cc1efee" + ] + ], + "mosdepth_per_base_bed": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WGS", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.per-base.bed.gz:md5,e5c10c94f3870f6ed2c75a904e9ade7f" + ] + ], + "mosdepth_per_base_csi": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WGS", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.per-base.bed.gz.csi:md5,b9223463b0f024768ebbbb3e42ace8da" + ] + ], + "mosdepth_per_base_d4": [ + + ], + "mosdepth_quantized_bed": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WGS", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.quantized.bed.gz:md5,d54d469a692c3fe4a4e1db02c08be518" + ] + ], + "mosdepth_quantized_csi": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WGS", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.quantized.bed.gz.csi:md5,efa0455ec39b49b96fd44c1efcbef8ab" + ] + ], + "mosdepth_regions": [ + + ], + "mosdepth_regions_bed": [ + + ], + "mosdepth_regions_csi": [ + + ], + "mosdepth_summary": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WGS", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.mosdepth.summary.txt:md5,699b955719b06ff290edbe0692492213" + ] + ], + "mosdepth_thresholds_bed": [ + + ], + "mosdepth_thresholds_csi": [ + + ], + "multiqc_data": [ + [ + { + "id": "test" + }, + "test_data" + ] + ], + "multiqc_plots": [ + + ], + "multiqc_report": [ + [ + { + "id": "test" + }, + "test.html" + ] + ], + "multiqcsav_data": [ + [ + + ] + ], + "multiqcsav_plots": [ + [ + + ] + ], + "multiqcsav_report": [ + [ + + ] + ], + "panelcoverage": [ + + ], + "picard_hsmetrics": [ + + ], + "picard_multiplemetrics": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WGS" + } + }, + [ + "sample1.CollectMultipleMetrics.alignment_summary_metrics", + "sample1.CollectMultipleMetrics.base_distribution_by_cycle_metrics", + "sample1.CollectMultipleMetrics.quality_by_cycle_metrics", + "sample1.CollectMultipleMetrics.quality_distribution_metrics" + ] + ] + ], + "picard_multiplemetrics_pdf": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WGS" + } + }, + [ + "sample1.CollectMultipleMetrics.base_distribution_by_cycle.pdf", + "sample1.CollectMultipleMetrics.quality_by_cycle.pdf", + "sample1.CollectMultipleMetrics.quality_distribution.pdf", + "sample1.CollectMultipleMetrics.read_length_histogram.pdf" + ] + ] + ], + "picard_wgsmetrics": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WGS" + } + }, + "sample1.CollectWgsMetrics.coverage_metrics" + ] + ], + "rna_junctions": [ + + ], + "rna_splice_junctions": [ + + ], + "samtools_coverage": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WGS" + } + }, + "sample1.coverage.txt" + ] + ], + "samtools_flagstat": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WGS" + } + }, + "sample1.flagstat" + ] + ], + "samtools_idxstats": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WGS", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.idxstats:md5,ecc89a474dced28b0610f17a82785007" + ] + ], + "samtools_stats": [ + [ + { + "groupSize": 1, + "groupTarget": { + "aligner": "bwamem", + "genome": "GRCh38", + "genome_data": { + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1", + "library": "test", + "markdup": "bamsormadup", + "organism": "Homo sapiens", + "run_coverage": true, + "sample_type": "DNA", + "samplename": "sample1", + "single_end": false, + "tag": "WGS" + } + }, + "sample1.stats" + ] + ], + "sormadup_metrics": [ + [ + { + "groupSize": 1, + "groupTarget": { + "samplename": "sample1", + "library": "test", + "organism": "Homo sapiens", + "tag": "WGS", + "sample_type": "DNA", + "aligner": "bwamem", + "markdup": "bamsormadup", + "run_coverage": true, + "single_end": false, + "genome": "GRCh38", + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "sample1" + } + }, + "sample1.merged.metrics.txt:md5,01b7286134f5cb6530c3bab2c86fd169" + ] + ] + } ], "meta": { - "nf-test": "0.9.2", - "nextflow": "25.04.3" + "nf-test": "0.9.3", + "nextflow": "25.10.4" }, - "timestamp": "2025-06-04T14:35:21.629978137" + "timestamp": "2026-03-05T14:07:05.010944" + }, + "preprocessing - flowcell - bwa - bamsormadup - roi": { + "content": [ + { + "key": [ + [ + { + "groupSize": 1, + "groupTarget": { + "single_end": true, + "samplename": "Sample1", + "sample_type": "DNA", + "library": "test", + "tag": "WES", + "purpose": [ + + ], + "organism": "Homo sapiens", + "genome": "GRCh38", + "vivar_project": [ + + ], + "binsize": [ + + ], + "panels": [ + + ], + "aligner": "bwamem", + "markdup": "bamsormadup", + "umi_aware": false, + "skip_trimming": false, + "trim_front": 0, + "trim_tail": 0, + "adapter_R1": null, + "adapter_R2": null, + "run_coverage": true, + "disable_picard_metrics": true, + "roi": null, + "genome_data": { + "fasta": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna", + "fai": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.fna.fai", + "dict": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.dict", + "bwamem": "s3://test-data/genomics/homo_sapiens/genome/bwa/", + "gtf": "s3://test-data/genomics/homo_sapiens/genome/seq/GCA_000001405.15_GRCh38_full_plus_hs38d1_analysis_set_chr21.gtf" + }, + "id": "Sample1" + } + }, + "Sample1.merged.metrics.txt:md5,f23933cc5957694d2286bdae22039097" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.4" + }, + "timestamp": "2026-03-05T14:02:04.847019" } } \ No newline at end of file diff --git a/workflows/preprocessing.nf b/workflows/preprocessing.nf index d23a17b1..5337ae93 100644 --- a/workflows/preprocessing.nf +++ b/workflows/preprocessing.nf @@ -1,4 +1,4 @@ -include { samplesheetToList } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -7,25 +7,27 @@ include { samplesheetToList } from 'plugin/nf-schema' */ // Modules -include { FASTP } from '../modules/nf-core/fastp/main' -include { MD5SUM } from '../modules/nf-core/md5sum/main' -include { MOSDEPTH } from '../modules/nf-core/mosdepth/main' -include { MULTIQC } from '../modules/nf-core/multiqc/main' -include { SAMTOOLS_COVERAGE } from '../modules/nf-core/samtools/coverage/main' +include { BCLCONVERT } from '../modules/nf-core/bclconvert' +include { FALCO } from '../modules/nf-core/falco' +include { FASTP } from '../modules/nf-core/fastp' +include { MD5SUM } from '../modules/nf-core/md5sum' +include { MULTIQC } from '../modules/nf-core/multiqc' +include { MULTIQCSAV } from '../modules/nf-core/multiqcsav' +include { SAMTOOLS_COVERAGE } from '../modules/nf-core/samtools/coverage' // Subworkflows -include { BAM_QC } from '../subworkflows/local/bam_qc/main' -include { BCL_DEMULTIPLEX } from '../subworkflows/nf-core/bcl_demultiplex/main' -include { COVERAGE } from '../subworkflows/local/coverage/main' -include { FASTQ_TO_UCRAM } from '../subworkflows/local/fastq_to_unaligned_cram/main' -include { FASTQ_TO_CRAM } from '../subworkflows/local/fastq_to_aligned_cram/main' +include { BAM_QC } from '../subworkflows/local/bam_qc' +include { COVERAGE } from '../subworkflows/local/coverage' +include { FASTQ_TO_CRAM } from '../subworkflows/local/fastq_to_aligned_cram' // Functions -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_preprocessing_pipeline' -include { getGenomeAttribute } from '../subworkflows/local/utils_nfcore_preprocessing_pipeline' +include { getReadgroupsFromBclconvert } from '../subworkflows/local/utils_nfcmgg_preprocessing_pipeline' +include { getReadgroupFromFastq } from '../subworkflows/local/utils_nfcmgg_preprocessing_pipeline' +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_preprocessing_pipeline' +include { getGenomeAttribute } from '../subworkflows/local/utils_nfcore_preprocessing_pipeline' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -34,349 +36,316 @@ include { getGenomeAttribute } from '../subworkflows/local/utils_nfcore_prep */ workflow PREPROCESSING { - take: ch_samplesheet // channel: samplesheet read in from --input - genomes // map: genome reference files - aligner // string: global aligner to use - markdup // string: markdup method to use - roi // file: regions of interest bed file to be applied to all samples - genelists // file: directory containing genelist bed files for coverage analysis + genomes // map: genome reference files + genelists // file: directory containing genelist bed files for coverage analysis + multiqc_config // file(s): MultiQC config file(s) + multiqc_logo // file: MultiQC logo file + multiqc_methods_description // file: custom methods description for MultiQC report main: - ch_versions = Channel.empty() - ch_multiqc_files = Channel.empty() + ch_multiqc_files = channel.empty() ch_samplesheet - .branch {meta, fastq_1, fastq_2, samplesheet, sampleinfo, flowcell -> - illumina_flowcell : (flowcell && samplesheet && sampleinfo) && !(fastq_1 || fastq_2) - return [meta, samplesheet, sampleinfo, flowcell] - fastq : (fastq_1) && !(flowcell || samplesheet || sampleinfo) + .branch { meta, fastq_1, fastq_2, samplesheet, sampleinfo, flowcell -> + illumina_flowcell: (flowcell && samplesheet && sampleinfo) && !(fastq_1 || fastq_2) + return [["id": meta.id, "lane": meta.lane], samplesheet, sampleinfo, flowcell] + fastq: (fastq_1) && !(flowcell || samplesheet || sampleinfo) return [meta, [fastq_1, fastq_2].findAll()] - other: true - error "Unable to determine input type, please check inputs" - } - .set{ch_inputs_from_samplesheet} - - roi = roi ? file(roi, checkIfExists:true) : null - - genelists = genelists ? Channel.value(file(genelists + "/*.bed", checkIfExists:true)) : Channel.empty() + other: true + error("Unable to determine input type, please check inputs") + } + .set { ch_inputs_from_samplesheet } + // construct a value channel containing an array of files, because the coverage subworkflow expects a channel of arrays of genelist files (to allow for multiple genelist files per sample) + ch_genelists = genelists ? channel.fromPath(genelists + "/*.bed").collect().map { files -> [files] } : channel.empty() -/* + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // PROCESS FLOWCELL INPUTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ ch_inputs_from_samplesheet.illumina_flowcell - .multiMap { meta, samplesheet, sampleinfo, flowcell -> - flowcell: [meta, samplesheet, flowcell] - info : samplesheetToList(sampleinfo, "assets/schema_sampleinfo.json") - } - .set{ ch_illumina_flowcell } + .multiMap { meta, samplesheet, sampleinfo, flowcell -> + flowcell: [meta, samplesheet, flowcell] + info: samplesheetToList(sampleinfo, "assets/schema_sampleinfo.json") + } + .set { ch_illumina_flowcell } + + // BCLCONVERT([meta, samplesheet, flowcell]) + BCLCONVERT(ch_illumina_flowcell.flowcell) + BCLCONVERT.out.fastq.dump(tag: "DEMULTIPLEX: fastq", pretty: true) + + getReadgroupsFromBclconvert( + BCLCONVERT.out.reports.map { meta, reports -> + return [meta, file(reports).resolve("fastq_list.csv")] + }, + BCLCONVERT.out.fastq, + ).dump(tag: "DEMULTIPLEX: fastq with meta", pretty: true).map { meta, fastq -> [meta.readgroup.SM, meta, fastq] }.set { ch_demultiplexed_fastq } + + // Run QC + ch_mqcsav_input = ch_illumina_flowcell.flowcell + .map { meta, _samplesheet, flowcell -> + def interop = files(flowcell.resolve("InterOp/*.bin"), checkIfExists: true) + def xml = files(flowcell.resolve("*.xml"), checkIfExists: true) + return [meta, xml, interop] + } + .join(BCLCONVERT.out.reports, by: 0) + .map { meta, xml, interop, reports -> + return [meta - meta.subMap(['lane']), xml, interop, reports] + } + .groupTuple(by: [0]) + .map { meta, xml, interop, reports -> + return [meta, xml.flatten().unique(), interop.flatten().unique(), reports.flatten(), multiqc_config, multiqc_logo, [], []] + } + .dump(tag: "MULTIQC SAV input", pretty: true) - // BCL_DEMULTIPLEX([meta, samplesheet, flowcell], demultiplexer) - BCL_DEMULTIPLEX(ch_illumina_flowcell.flowcell, "bclconvert") - BCL_DEMULTIPLEX.out.fastq.dump(tag: "DEMULTIPLEX: fastq",pretty: true) - ch_multiqc_files = ch_multiqc_files.mix( - BCL_DEMULTIPLEX.out.reports.map { meta, reports -> return reports}, - BCL_DEMULTIPLEX.out.stats.map { meta, stats -> return stats } + MULTIQCSAV( + ch_mqcsav_input ) - ch_versions = ch_versions.mix(BCL_DEMULTIPLEX.out.versions) - - BCL_DEMULTIPLEX.out.fastq - .map{meta, fastq -> [meta.samplename, meta, fastq]} - .set{ch_demultiplexed_fastq} + // Merge fastq meta with sample info ch_illumina_flowcell.info - .flatten() - .transpose() - .map{sampleinfo -> [sampleinfo.samplename, sampleinfo]} - .set{ch_sampleinfo} + .flatten() + .transpose() + .map { sampleinfo -> [sampleinfo.samplename, sampleinfo] } + .set { ch_sampleinfo } - // Merge fastq meta with sample info ch_demultiplexed_fastq - .combine(ch_sampleinfo, by: 0) - .map { samplename, meta, fastq, sampleinfo -> - def new_meta = meta + sampleinfo - def readgroup = readgroup_from_fastq(fastq[0]) - readgroup = readgroup + ['SM': samplename, 'LB': new_meta.library ?: ""] - new_meta = new_meta + ['readgroup' : readgroup] - return [ new_meta, fastq ] - } - .groupTuple( by: [0]) - .map { meta, fq -> - return [meta, fq.flatten().unique()] - } - .set {ch_demultiplexed_fastq_with_sampleinfo} -/* + .combine(ch_sampleinfo, by: 0) + .map { _samplename, meta, fastq, sampleinfo -> + def new_rg = [:] + if (sampleinfo.library) { + new_rg = meta.readgroup + ['LB': sampleinfo.library] + } + else { + new_rg = meta.readgroup + } + def new_meta = meta + sampleinfo + ['readgroup': new_rg] + return [new_meta, fastq] + } + .groupTuple(by: [0]) + .map { meta, fq -> + return [meta, fq.flatten().unique()] + } + .branch { meta, _fastq -> + to_align: meta.aligner && meta.aligner != "false" + other: true + } + .set { ch_demultiplexed_fastq_with_sampleinfo } + + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // PROCESS FASTQ INPUTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ ch_inputs_from_samplesheet.fastq - .map { meta, fastq -> - // if no fastq_2, then single-end - def single_end = fastq[1] ? false : true - // add readgroup metadata - def rg = readgroup_from_fastq(fastq[0]) - // if the sample name starts with "snp_", remove it so the sampletracking works later on. - def samplename = meta.samplename.startsWith("snp_") ? meta.samplename.substring(4) : meta.samplename - rg = rg + [ 'SM': samplename, - 'LB': meta.library ?: "", - 'PL': meta.platform ?: rg.PL, - 'ID': meta.readgroup ?: rg.ID - ] - def meta_with_readgroup = meta + ['single_end': single_end, 'readgroup': rg] - return [meta_with_readgroup, fastq] - } - .set {ch_input_fastq} + .map { meta, fastq -> + // if no fastq_2, then single-end + def single_end = fastq[1] ? false : true + // add readgroup metadata + // if the sample name starts with "snp_", remove it so the sampletracking works later on. + def samplename = meta.samplename.startsWith("snp_") ? meta.samplename.substring(4) : meta.samplename + def rg = getReadgroupFromFastq(fastq[0], samplename, meta.library, meta.platform) + def meta_with_readgroup = meta + ['single_end': single_end, 'readgroup': rg] + return [meta_with_readgroup, fastq] + } + .set { ch_input_fastq } -/* + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ASSOCIATE CORRECT GENOME AND COUNT SAMPLE REPLICATES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ ch_input_fastq - .mix(ch_demultiplexed_fastq_with_sampleinfo) - // Add the genome config to the tuple - // set genome based on organism key - .map{ meta, reads -> - if (meta.organism && !meta.genome) { - if (meta.organism ==~ /(?i)Homo[\s_]sapiens/) { - meta = meta + ["genome":"GRCh38"] - } else if (meta.organism ==~ /(?i)Mus[\s_]musculus/) { - meta = meta + ["genome":"mm10"] - } else if (meta.organism ==~/(?i)Danio[\s_]rerio/) { - meta = meta + ["genome":"GRCz11"] - } else { - meta = meta + ["genome": null ] + .mix(ch_demultiplexed_fastq_with_sampleinfo.to_align) + .map { meta, reads -> + if (meta.organism && !meta.genome) { + if (meta.organism ==~ /(?i)Homo[\s_]sapiens/) { + meta = meta + ["genome": "GRCh38"] + } + else if (meta.organism ==~ /(?i)Mus[\s_]musculus/) { + meta = meta + ["genome": "mm10"] + } + else if (meta.organism ==~ /(?i)Danio[\s_]rerio/) { + meta = meta + ["genome": "GRCz11"] + } + else { + meta = meta + ["genome": null] + } } + if (genomes && genomes[meta.genome]) { + meta = meta + ["genome_data": genomes[meta.genome]] + } + else { + meta = meta + ["genome_data": [:]] + } + return [meta, reads] } - if (genomes && genomes[meta.genome]){ - meta = meta + ["genome_data": genomes[meta.genome]] - } else { - meta = meta + ["genome_data": [:]] - } - // set the aligner - if (aligner && !meta.aligner) { - meta = meta + ["aligner": aligner] - } - // set the ROI - // // Special case for coPGT samples - // // if there's no global ROI AND no sample speficic ROI - // // AND the sample tag is "coPGT-M", set the sample ROI to "roi_copgt" - if (!roi && !meta.roi && meta.tag == "coPGT-M") { - meta = meta + ["roi": getGenomeAttribute(meta.genome_data, "roi_copgt")] + .map { meta, reads -> [meta.samplename, [meta, reads]] } + .groupTuple() + .map { _samplename, meta_fastq -> [meta_fastq, meta_fastq.size()] } + .transpose() + .map { meta_fastq, count -> [meta_fastq[0] + ['count': count], meta_fastq[1]] } + .map { meta, fastq -> + return [meta - meta.subMap('fcid', 'lane'), fastq] } - // // if there's a global ROI AND no sample specific ROI - // // set the global ROI to the sample - if (roi && !meta.roi) { - meta = meta + ["roi": roi] + .branch { meta, _reads -> + supported: meta.genome_data instanceof Map && meta.genome_data.size() > 0 && meta.aligner + other: true } - return [meta, reads] - } - // Count the number of samples per samplename - .map{ meta, reads -> [meta.samplename, [meta, reads]]} - .groupTuple() - .map{ samplename, meta_fastq -> [meta_fastq, meta_fastq.size()]} - .transpose() - .map{meta_fastq, count -> [meta_fastq[0] + ['count': count], meta_fastq[1]]} - // Clean up metadata - .map{meta, fastq -> - return [meta - meta.subMap('fcid','lane','library'), fastq] - } - .set{ch_fastq_per_sample} + .set { ch_fastq_per_sample } - ch_fastq_per_sample.dump(tag:"FASTQ per sample", pretty: true) + ch_fastq_per_sample.supported.dump(tag: "Supported FASTQ per sample", pretty: true) + ch_fastq_per_sample.other.dump(tag: "Other FASTQ per sample", pretty: true) - -/* + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // FASTQ TRIMMING AND QC ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + // MODULE: FALCO + // Run FALCO for "unsupported" fastq QC + // FALCO([meta, fastq]) + FALCO(ch_fastq_per_sample.other) + ch_multiqc_files = ch_multiqc_files.mix(FALCO.out.html) + ch_multiqc_files = ch_multiqc_files.mix(FALCO.out.txt) + // MODULE: fastp // Run QC, trimming and adapter removal - // FASTP([meta, fastq], adapter_fasta, save_trimmed, save_merged) - FASTP(ch_fastq_per_sample, [], false, false, false) - ch_multiqc_files = ch_multiqc_files.mix(FASTP.out.json.map { meta, json -> return json} ) - ch_versions = ch_versions.mix(FASTP.out.versions) + // FASTP([meta, fastq, adapter_fasta], save_trimmed, save_merged) + FASTP( + ch_fastq_per_sample.supported.map { meta, fastq -> + return [meta, fastq, []] + }, + false, + false, + false, + ) + ch_multiqc_files = ch_multiqc_files.mix(FASTP.out.json) // edit meta.id to match sample name FASTP.out.reads - .map { meta, reads -> - def read_files = meta.single_end.toBoolean() ? reads : reads.sort{ a,b -> a.getName().tokenize('.')[0] <=> b.getName().tokenize('.')[0] }.collate(2) - return [ - meta + [ chunks: read_files instanceof List ? read_files.size() : [read_files].size() ], - read_files - ] - } - // transpose to get read pairs - .transpose() - // set new meta.id to include split number - .map { meta, reads -> - def new_id = reads instanceof List ? reads[0].getName() - ~/_1.fastp.*/ : reads.getName() - ~/.fastp.*/ - return [ - meta - meta.subMap('id') + [ id: new_id ], - reads - ] - } - // split samples into human and non human data - .branch { meta, reads -> - supported: meta.genome_data instanceof Map && meta.genome_data.size() > 0 - other: true - } - .set { ch_trimmed_reads } - - ch_trimmed_reads.supported.dump(tag:"Supported trimmed reads per sample", pretty: true) - ch_trimmed_reads.other.dump(tag:"Other trimmed reads per sample", pretty: true) - - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// STEP: FASTQ TO UNALIGNED CRAM CONVERSION -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - - FASTQ_TO_UCRAM(ch_trimmed_reads.other) - ch_versions = ch_versions.mix(FASTQ_TO_UCRAM.out.versions) + .map { meta, reads -> + def read_files = meta.single_end.toBoolean() ? reads : reads.sort { a, b -> a.getName().tokenize('.')[0] <=> b.getName().tokenize('.')[0] }.collate(2) + return [ + meta + [chunks: read_files instanceof List ? read_files.size() : [read_files].size()], + read_files, + ] + } + .transpose() + .map { meta, reads -> + def new_id = reads instanceof List ? reads[0].getName() - ~/_R1.fastp.*/ : reads.getName() - ~/.fastp.*/ + return [ + meta - meta.subMap('id') + [id: new_id], + reads, + ] + } + .set { ch_trimmed_reads } -/* + ch_trimmed_reads.dump(tag: "Supported trimmed reads per sample", pretty: true) -/* + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // STEP: FASTQ TO ALIGNED CRAM CONVERSION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - ch_trimmed_reads.supported.map{ meta, reads -> - return [ - meta, - reads, - meta.aligner, - getGenomeAttribute(meta.genome_data, meta.aligner), - getGenomeAttribute(meta.genome_data, "fasta"), - getGenomeAttribute(meta.genome_data, "gtf") + ch_trimmed_reads + .map { meta, reads -> + return [ + meta, + reads, + meta.aligner, + getGenomeAttribute(meta.genome_data, meta.aligner), + getGenomeAttribute(meta.genome_data, "fasta"), + getGenomeAttribute(meta.genome_data, "gtf"), ] - } - .set{ch_meta_reads_aligner_index_fasta_gtf} + } + .set { ch_meta_reads_aligner_index_fasta_gtf } FASTQ_TO_CRAM( - ch_meta_reads_aligner_index_fasta_gtf, - markdup + ch_meta_reads_aligner_index_fasta_gtf ) + ch_multiqc_files = ch_multiqc_files.mix(FASTQ_TO_CRAM.out.sormadup_metrics) - ch_multiqc_files = ch_multiqc_files.mix(FASTQ_TO_CRAM.out.multiqc_files) - ch_versions = ch_versions.mix(FASTQ_TO_CRAM.out.versions) - - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// STEP: FILTER SAMPLES WITH 'SNP' TAG -// samples with SNP tag contain only data for sample tracking -// and as such don't need all the QC steps -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - - FASTQ_TO_CRAM.out.cram_crai - .filter{ meta, cram, crai -> - meta.tag != "SNP" - } - .set{ch_no_snp_samples} - -/* + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // STEP: COVERAGE ANALYSIS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - ch_no_snp_samples - .map { meta, cram, crai -> - if (meta.roi) { - return [ - meta, - cram, - crai, - getGenomeAttribute(meta.genome_data, "fasta"), - getGenomeAttribute(meta.genome_data, "fai"), - file(meta.roi, checkIfExists:true), - ] - } else { + FASTQ_TO_CRAM.out.cram_crai + .filter { meta, _cram, _crai -> + meta.run_coverage.toBoolean() + } + .map { meta, cram, crai -> return [ meta, cram, crai, getGenomeAttribute(meta.genome_data, "fasta"), getGenomeAttribute(meta.genome_data, "fai"), - [], + meta.roi && meta.roi != [] ? file(meta.roi, checkIfExists: true) : [], ] } - } - .set{ch_cram_crai_fasta_fai_roi} - - if (params.run_coverage == true || params.run_coverage == "true") { - COVERAGE(ch_cram_crai_fasta_fai_roi, genelists) - ch_multiqc_files = ch_multiqc_files.mix( - COVERAGE.out.mosdepth_summary .map{ meta, txt -> return txt }, - COVERAGE.out.mosdepth_global .map{ meta, txt -> return txt }, - COVERAGE.out.mosdepth_regions .map{ meta, txt -> return txt }, - COVERAGE.out.samtools_coverage.map{ meta, txt -> return txt }, - ) - ch_versions = ch_versions.mix(COVERAGE.out.versions) - } + .set { ch_coverage } -/* + COVERAGE(ch_coverage, ch_genelists) + ch_multiqc_files = ch_multiqc_files.mix( + COVERAGE.out.mosdepth_summary, + COVERAGE.out.mosdepth_global, + COVERAGE.out.mosdepth_regions, + COVERAGE.out.samtools_coverage, + ) + + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // STEP: QC FOR ALIGNMENTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - ch_no_snp_samples - .map { meta, cram, crai -> - if (meta.roi) { - return [ - meta, - cram, - crai, - file(meta.roi, checkIfExists:true), - getGenomeAttribute(meta.genome_data, "fasta"), - getGenomeAttribute(meta.genome_data, "fai"), - getGenomeAttribute(meta.genome_data, "dict"), - ] - } else { + FASTQ_TO_CRAM.out.cram_crai + .map { meta, cram, crai -> return [ meta, cram, crai, - [], + meta.roi && meta.roi != [] ? file(meta.roi, checkIfExists: true) : [], getGenomeAttribute(meta.genome_data, "fasta"), getGenomeAttribute(meta.genome_data, "fai"), getGenomeAttribute(meta.genome_data, "dict"), ] } - } - .set{ch_cram_crai_roi_fasta_fai_dict} + .set { ch_bam_qc } - BAM_QC(ch_cram_crai_roi_fasta_fai_dict, params.disable_picard_metrics) + BAM_QC(ch_bam_qc) ch_multiqc_files = ch_multiqc_files.mix( - BAM_QC.out.samtools_stats .map{ meta, txt -> return txt }, - BAM_QC.out.samtools_flagstat .map{ meta, txt -> return txt }, - BAM_QC.out.samtools_idxstats .map{ meta, txt -> return txt }, - BAM_QC.out.picard_multiplemetrics .map{ meta, txt -> return txt }, - BAM_QC.out.picard_wgsmetrics .map{ meta, txt -> return txt }, - BAM_QC.out.picard_hsmetrics .map{ meta, txt -> return txt }, + BAM_QC.out.samtools_stats, + BAM_QC.out.samtools_flagstat, + BAM_QC.out.samtools_idxstats, + BAM_QC.out.picard_multiplemetrics, + BAM_QC.out.picard_wgsmetrics, + BAM_QC.out.picard_wgsmetrics, + BAM_QC.out.picard_hsmetrics, ) - ch_versions = ch_versions.mix(BAM_QC.out.versions) -/* + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // STEP: CHECKSUMS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - MD5SUM(FASTQ_TO_CRAM.out.cram_crai.map{ meta, cram, crai -> return [meta,cram] }, false) + MD5SUM( + ch_fastq_per_sample.other.mix( + FASTQ_TO_CRAM.out.cram_crai.map { meta, cram, _crai -> + return [meta, cram] + } + ), + false, + ) -/* + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // AGGREGATE QC ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -384,85 +353,109 @@ workflow PREPROCESSING { // // Collate and save software versions // - softwareVersionsToYAML(ch_versions) - .collectFile(storeDir: "${params.outdir}/pipeline_info", name: 'nf_core_pipeline_software_mqc_versions.yml', sort: true, newLine: true) + def topic_versions = channel.topic("versions") + .distinct() + .branch { entry -> + versions_file: entry instanceof Path + versions_tuple: true + } + + def topic_versions_string = topic_versions.versions_tuple + .map { process, tool, version -> + [process[process.lastIndexOf(':') + 1..-1], " ${tool}: ${version}"] + } + .groupTuple(by: 0) + .map { process, tool_versions -> + tool_versions.unique().sort() + "${process}:\n${tool_versions.join('\n')}" + } + + softwareVersionsToYAML(topic_versions.versions_file) + .mix(topic_versions_string) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'nf_cmgg_preprocessing_software_mqc_versions.yml', + sort: true, + newLine: true, + ) .set { ch_collated_versions } // // MODULE: MultiQC // - ch_multiqc_config = Channel.fromPath("$projectDir/assets/multiqc_config.yml", checkIfExists: true) - ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath(params.multiqc_config, checkIfExists: true) : Channel.empty() - ch_multiqc_logo = params.multiqc_logo ? Channel.fromPath(params.multiqc_logo, checkIfExists: true) : Channel.empty() - summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") - ch_workflow_summary = Channel.value(paramsSummaryMultiqc(summary_params)) - ch_multiqc_custom_methods_description = params.multiqc_methods_description ? file(params.multiqc_methods_description, checkIfExists: true) : file("$projectDir/assets/methods_description_template.yml", checkIfExists: true) - ch_methods_description = Channel.value(methodsDescriptionText(ch_multiqc_custom_methods_description)) - ch_multiqc_files = ch_multiqc_files.mix(ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) - ch_multiqc_files = ch_multiqc_files.mix(ch_collated_versions) - ch_multiqc_files = ch_multiqc_files.mix(ch_methods_description.collectFile(name: 'methods_description_mqc.yaml', sort: false)) - - MULTIQC ( - ch_multiqc_files.collect(), - ch_multiqc_config.toList(), - ch_multiqc_custom_config.toList(), - ch_multiqc_logo.toList(), - [], - [] - ) + // summary files without meta, e.g. versions, params + summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") + ch_workflow_summary = channel.value(paramsSummaryMultiqc(summary_params)) + ch_methods_description = channel.value(multiqc_methods_description ? methodsDescriptionText(multiqc_methods_description) : "") + + ch_summary_files = channel.empty() + .mix(ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) + .mix(ch_collated_versions) + .mix(ch_methods_description.collectFile(name: 'methods_description_mqc.yaml', sort: true)) + .toList() + .map { files -> [files] } + .dump(tag: "Summary files for MultiQC", pretty: true) + + ch_multiqc_input = ch_multiqc_files + .map { meta, files -> + def new_meta = meta.library ? [id: meta.library] : [id: 'multiqc'] + return [new_meta, files] + } + .groupTuple(by: 0) + .combine(ch_summary_files) + .map { meta, multiqc_files, summary_files -> + return [meta, (multiqc_files + summary_files).flatten(), multiqc_config.flatten(), multiqc_logo, [], []] + } + .dump(tag: "MULTIQC files", pretty: true) - emit: - multiqc_report = MULTIQC.out.report.toList() // channel: /path/to/multiqc_report.html - versions = ch_versions // channel: [ path(versions.yml) ] -} -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - FUNCTIONS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ + // MULTIQC([meta, multiqc_files, multiqc_config, multiqc_logo, replace_names, sample_names]) + MULTIQC(ch_multiqc_input) -// https://github.com/nf-core/sarek/blob/7ba61bde8e4f3b1932118993c766ed33b5da465e/workflows/sarek.nf#L1014-L1040 -def readgroup_from_fastq(path) { - // expected format: - // xx:yy:FLOWCELLID:LANE:... (seven fields) - // or - // FLOWCELLID:LANE:xx:... (five fields) - def line - - path.withInputStream { fq -> - def gzipStream = new java.util.zip.GZIPInputStream(fq) as InputStream - def decoder = new InputStreamReader(gzipStream, 'ASCII') - def buffered = new BufferedReader(decoder) - line = buffered.readLine() + emit: + demultiplex_reports = BCLCONVERT.out.reports.map { meta, reports -> + return [meta, files(reports.resolve("*"))] } - assert line.startsWith('@') - line = line.substring(1) - def fields = line.split(':') - def rg = [:] - rg.CN = "CMGG" - - if (fields.size() >= 7) { - // CASAVA 1.8+ format, from https://support.illumina.com/help/BaseSpace_OLH_009008/Content/Source/Informatics/BS/FileFormat_FASTQ-files_swBS.htm - // "@::::::: :::" - def sequencer_serial = fields[0] - def run_nubmer = fields[1] - def fcid = fields[2] - def lane = fields[3] - def index = fields[-1] =~ /[GATC+-]/ ? fields[-1] : "" - - rg.ID = [fcid,lane].join(".") - rg.PU = [fcid, lane, index].findAll().join(".") - rg.PL = "ILLUMINA" - } else if (fields.size() == 5) { - def fcid = fields[0] - rg.ID = fcid + demultiplex_logs = BCLCONVERT.out.logs.map { meta, logs -> + return [meta, files(logs.resolve("*"))] } - return rg + demultiplex_interop = BCLCONVERT.out.interop + demultiplex_fastq = ch_demultiplexed_fastq_with_sampleinfo.other + falco_html = FALCO.out.html + falco_txt = FALCO.out.txt + fastp_json = FASTP.out.json + fastp_html = FASTP.out.html + crams = FASTQ_TO_CRAM.out.cram_crai + rna_splice_junctions = FASTQ_TO_CRAM.out.rna_splice_junctions + rna_junctions = FASTQ_TO_CRAM.out.rna_junctions + align_reports = FASTQ_TO_CRAM.out.align_reports + sormadup_metrics = FASTQ_TO_CRAM.out.sormadup_metrics + mosdepth_global = COVERAGE.out.mosdepth_global + mosdepth_summary = COVERAGE.out.mosdepth_summary + mosdepth_regions = COVERAGE.out.mosdepth_regions + mosdepth_per_base_d4 = COVERAGE.out.mosdepth_per_base_d4 + mosdepth_per_base_bed = COVERAGE.out.mosdepth_per_base_bed + mosdepth_per_base_csi = COVERAGE.out.mosdepth_per_base_csi + mosdepth_regions_bed = COVERAGE.out.mosdepth_regions_bed + mosdepth_regions_csi = COVERAGE.out.mosdepth_regions_csi + mosdepth_quantized_bed = COVERAGE.out.mosdepth_quantized_bed + mosdepth_quantized_csi = COVERAGE.out.mosdepth_quantized_csi + mosdepth_thresholds_bed = COVERAGE.out.mosdepth_thresholds_bed + mosdepth_thresholds_csi = COVERAGE.out.mosdepth_thresholds_csi + samtools_coverage = COVERAGE.out.samtools_coverage + panelcoverage = COVERAGE.out.panelcoverage + samtools_stats = BAM_QC.out.samtools_stats + samtools_flagstat = BAM_QC.out.samtools_flagstat + samtools_idxstats = BAM_QC.out.samtools_idxstats + picard_multiplemetrics = BAM_QC.out.picard_multiplemetrics + picard_multiplemetrics_pdf = BAM_QC.out.picard_multiplemetrics_pdf + picard_wgsmetrics = BAM_QC.out.picard_wgsmetrics + picard_hsmetrics = BAM_QC.out.picard_hsmetrics + md5sums = MD5SUM.out.checksum + multiqcsav_report = MULTIQCSAV.out.report.toList() + multiqcsav_data = MULTIQCSAV.out.data.toList() + multiqcsav_plots = MULTIQCSAV.out.plots.toList() + multiqc_report = MULTIQC.out.report + multiqc_data = MULTIQC.out.data + multiqc_plots = MULTIQC.out.plots } - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - THE END -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/