diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index dd9ffa538..000000000 --- a/.editorconfig +++ /dev/null @@ -1,37 +0,0 @@ -root = true - -[*] -charset = utf-8 -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true -indent_size = 4 -indent_style = space - -[*.{md,yml,yaml,html,css,scss,js}] -indent_size = 2 - -# These files are edited and tested upstream in nf-core/modules -[/modules/nf-core/**] -charset = unset -end_of_line = unset -insert_final_newline = unset -trim_trailing_whitespace = unset -indent_style = unset -[/subworkflows/nf-core/**] -charset = unset -end_of_line = unset -insert_final_newline = unset -trim_trailing_whitespace = unset -indent_style = unset - -[/assets/email*] -indent_size = unset - -# ignore Readme -[README.md] -indent_style = unset - -# ignore python -[*.{py,md}] -indent_style = unset diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..0a8861b61 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,12 @@ +# Maintainers +* @rannick @nvnieuwk @atrigila +*.nf.test* @rannick @nvnieuwk @atrigila +.github/workflows/ @rannick @nvnieuwk @atrigila + +# Subworkflows +subworkflows/nf-core/* @rannick @nvnieuwk @atrigila +subworkflows/local/* @rannick @nvnieuwk @atrigila + +# Modules +modules/nf-core/* @rannick @nvnieuwk @atrigila +modules/local/* @rannick @nvnieuwk @atrigila diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 3cfa08b32..9af64f9fd 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# nf-core/rnafusion: Contributing Guidelines +# `nf-core/rnafusion`: Contributing Guidelines Hi there! Many thanks for taking an interest in improving nf-core/rnafusion. @@ -19,7 +19,7 @@ If you'd like to write some code for nf-core/rnafusion, the standard workflow is 1. Check that there isn't already an issue about your idea in the [nf-core/rnafusion issues](https://github.com/nf-core/rnafusion/issues) to avoid duplicating work. If there isn't one already, please create one so that others know you're working on this 2. [Fork](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) the [nf-core/rnafusion repository](https://github.com/nf-core/rnafusion) to your GitHub account 3. Make the necessary changes / additions within your forked repository following [Pipeline conventions](#pipeline-contribution-conventions) -4. Use `nf-core schema build` and add any new parameters to the pipeline JSON schema (requires [nf-core tools](https://github.com/nf-core/tools) >= 1.10). +4. Use `nf-core pipelines schema build` and add any new parameters to the pipeline JSON schema (requires [nf-core tools](https://github.com/nf-core/tools) >= 1.10). 5. Submit a Pull Request against the `dev` branch and wait for the code to be reviewed and merged If you're not used to this workflow with git, you can start with some [docs from GitHub](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests) or even their [excellent `git` resources](https://try.github.io/). @@ -40,7 +40,7 @@ There are typically two types of tests that run: ### Lint tests `nf-core` has a [set of guidelines](https://nf-co.re/developers/guidelines) which all pipelines must adhere to. -To enforce these and ensure that all pipelines stay in sync, we have developed a helper tool which runs checks on the pipeline code. This is in the [nf-core/tools repository](https://github.com/nf-core/tools) and once installed can be run locally with the `nf-core lint ` command. +To enforce these and ensure that all pipelines stay in sync, we have developed a helper tool which runs checks on the pipeline code. This is in the [nf-core/tools repository](https://github.com/nf-core/tools) and once installed can be run locally with the `nf-core pipelines lint ` command. If any failures or warnings are encountered, please follow the listed URL for more documentation. @@ -55,9 +55,9 @@ These tests are run both with the latest available version of `Nextflow` and als :warning: Only in the unlikely and regretful event of a release happening with a bug. -- On your own fork, make a new branch `patch` based on `upstream/master`. +- On your own fork, make a new branch `patch` based on `upstream/main` or `upstream/master`. - Fix the bug, and bump version (X.Y.Z+1). -- A PR should be made on `master` from patch to directly this particular bug. +- Open a pull-request from `patch` to `main`/`master` with the changes. ## Getting help @@ -65,32 +65,32 @@ For further information/help, please consult the [nf-core/rnafusion documentatio ## Pipeline contribution conventions -To make the nf-core/rnafusion code and processing logic more understandable for new contributors and to ensure quality, we semi-standardise the way the code and other contributions are written. +To make the `nf-core/rnafusion` code and processing logic more understandable for new contributors and to ensure quality, we semi-standardise the way the code and other contributions are written. ### Adding a new step If you wish to contribute a new step, please use the following coding standards: -1. Define the corresponding input channel into your new process from the expected previous process channel +1. Define the corresponding input channel into your new process from the expected previous process channel. 2. Write the process block (see below). 3. Define the output channel if needed (see below). 4. Add any new parameters to `nextflow.config` with a default (see below). -5. Add any new parameters to `nextflow_schema.json` with help text (via the `nf-core schema build` tool). +5. Add any new parameters to `nextflow_schema.json` with help text (via the `nf-core pipelines schema build` tool). 6. Add sanity checks and validation for all relevant parameters. 7. Perform local tests to validate that the new code works as expected. -8. If applicable, add a new test command in `.github/workflow/ci.yml`. +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`. ### Default values -Parameters should be initialised / defined with default values in `nextflow.config` under the `params` scope. +Parameters should be initialised / defined with default values within the `params` scope in `nextflow.config`. -Once there, use `nf-core schema build` to add to `nextflow_schema.json`. +Once there, use `nf-core pipelines schema build` to add to `nextflow_schema.json`. ### Default processes resource requirements -Sensible defaults for process resource requirements (CPUs / memory / time) for a process should be defined in `conf/base.config`. These should generally be specified generic with `withLabel:` selectors so they can be shared across multiple processes/steps of the pipeline. A nf-core standard set of labels that should be followed where possible can be seen in the [nf-core pipeline template](https://github.com/nf-core/tools/blob/master/nf_core/pipeline-template/conf/base.config), which has the default process as a single core-process, and then different levels of multi-core configurations for increasingly large memory requirements defined with standardised labels. +Sensible defaults for process resource requirements (CPUs / memory / time) for a process should be defined in `conf/base.config`. These should generally be specified generic with `withLabel:` selectors so they can be shared across multiple processes/steps of the pipeline. A nf-core standard set of labels that should be followed where possible can be seen in the [nf-core pipeline template](https://github.com/nf-core/tools/blob/main/nf_core/pipeline-template/conf/base.config), which has the default process as a single core-process, and then different levels of multi-core configurations for increasingly large memory requirements defined with standardised labels. The process resources can be passed on to the tool dynamically within the process with the `${task.cpus}` and `${task.memory}` variables in the `script:` block. @@ -103,7 +103,7 @@ Please use the following naming schemes, to make it easy to understand what is g ### Nextflow version bumping -If you are using a new feature from core Nextflow, you may bump the minimum required version of nextflow in the pipeline with: `nf-core bump-version --nextflow . [min-nf-version]` +If you are using a new feature from core Nextflow, you may bump the minimum required version of nextflow in the pipeline with: `nf-core pipelines bump-version --nextflow . [min-nf-version]` ### Images and figures diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 7755ffb4a..5980dff43 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -9,7 +9,6 @@ body: - [nf-core website: troubleshooting](https://nf-co.re/usage/troubleshooting) - [nf-core/rnafusion pipeline documentation](https://nf-co.re/rnafusion/usage) - - type: textarea id: description attributes: diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index d2824258e..7b8124978 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -17,8 +17,8 @@ Learn more about contributing: [CONTRIBUTING.md](https://github.com/nf-core/rnaf - [ ] If you've fixed a bug or added code that should be tested, add tests! - [ ] If you've added a new tool - have you followed the pipeline conventions in the [contribution docs](https://github.com/nf-core/rnafusion/tree/master/.github/CONTRIBUTING.md) - [ ] If necessary, also make a PR on the nf-core/rnafusion _branch_ on the [nf-core/test-datasets](https://github.com/nf-core/test-datasets) repository. -- [ ] Make sure your code lints (`nf-core lint`). - +- [ ] Make sure your code lints (`nf-core pipelines lint`). +- [ ] Ensure the test suite passes (`nextflow run . -profile test,docker --outdir `). - [ ] Check for unexpected warnings in debug mode (`nextflow run . -profile debug,test,docker --outdir `). - [ ] Usage Documentation in `docs/usage.md` is updated. - [ ] Output Documentation in `docs/output.md` is updated. diff --git a/.github/actions/get-shards/action.yml b/.github/actions/get-shards/action.yml new file mode 100644 index 000000000..34085279f --- /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 000000000..bf44d9612 --- /dev/null +++ b/.github/actions/nf-test/action.yml @@ -0,0 +1,109 @@ +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@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + with: + python-version: "3.13" + + - 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: Conda setup + if: contains(inputs.profile, 'conda') + uses: conda-incubator/setup-miniconda@505e6394dae86d6a5c7fbb6e3fb8938e3e863830 # v3 + with: + auto-update-conda: true + conda-solver: libmamba + conda-remove-defaults: true + + - 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/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 904bf6afc..6b9a6d5e9 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -1,57 +1,48 @@ name: nf-core AWS full size tests -# This workflow is triggered on published releases. +# This workflow is triggered on PRs opened against the main/master branch. # It can be additionally triggered manually with GitHub actions workflow dispatch button. # It runs the -profile 'test_full' on AWS batch on: + workflow_dispatch: + pull_request_review: + types: [submitted] release: types: [published] - workflow_dispatch: + jobs: - run-tower: + run-platform: name: Run AWS full tests - if: github.repository == 'nf-core/rnafusion' + # run only if the PR is approved by at least 2 reviewers and against the master/main branch or manually triggered + if: github.repository == 'nf-core/rnafusion' && github.event.review.state == 'approved' && (github.event.pull_request.base.ref == 'master' || github.event.pull_request.base.ref == 'main') || github.event_name == 'workflow_dispatch' || github.event_name == 'release' runs-on: ubuntu-latest steps: - - name: Launch build references workflow via tower + - name: Set revision variable + id: revision + run: | + echo "revision=${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'release') && github.sha || 'dev' }}" >> "$GITHUB_OUTPUT" + + - name: Launch workflow via Seqera Platform uses: seqeralabs/action-tower-launch@v2 with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_COMPUTE_ENV }} - revision: ${{ github.sha }} - workdir: s3://${{ secrets.AWS_S3_BUCKET }}/work/rnafusion/work-${{ github.sha }} + revision: ${{ steps.revision.outputs.revision }} + workdir: s3://${{ secrets.AWS_S3_BUCKET }}/work/rnafusion/work-${{ steps.revision.outputs.revision }} parameters: | { "hook_url": "${{ secrets.MEGATESTS_ALERTS_SLACK_HOOK_URL }}", - "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", - "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", - "cosmic_username": "${{ secrets.cosmic_username }}", - "cosmic_passwd": "${{ secrets.cosmic_passwd }}", - "all": true, - "build_references": true + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ steps.revision.outputs.revision }}" + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/references", + "tools": "all", + "no_cosmic": true } - profiles: test_full,aws_tower - - uses: actions/upload-artifact@v4 - with: - name: Tower debug log file - path: | - tower_action_*.log - tower_action_*.json + profiles: test_full - - name: Launch run workflow via tower - uses: seqeralabs/action-tower-launch@v2 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: - workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} - access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} - compute_env: ${{ secrets.TOWER_COMPUTE_ENV }} - workdir: s3://${{ secrets.AWS_S3_BUCKET }}/work/rnafusion/work-${{ github.sha }} - parameters: | - { - "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", - "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", - "cosmic_username": "${{ secrets.cosmic_username }}", - "cosmic_passwd": "${{ secrets.cosmic_passwd }}", - "all": true, - } - profiles: test_full,aws_tower + name: Seqera Platform debug log file + path: | + seqera_platform_action_*.log + seqera_platform_action_*.json diff --git a/.github/workflows/awstest.yml b/.github/workflows/awstest.yml index 51db1d90f..9ce76b8d1 100644 --- a/.github/workflows/awstest.yml +++ b/.github/workflows/awstest.yml @@ -5,13 +5,13 @@ name: nf-core AWS test on: workflow_dispatch: jobs: - run-tower: + run-platform: name: Run AWS tests if: github.repository == 'nf-core/rnafusion' runs-on: ubuntu-latest steps: - # Launch workflow using Tower CLI tool action - - name: Launch build references workflow via tower + # Launch workflow using Seqera Platform CLI tool action + - name: Launch workflow via Seqera Platform uses: seqeralabs/action-tower-launch@v2 with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} @@ -22,39 +22,14 @@ jobs: parameters: | { "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", - "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", - "cosmic_username": "${{ secrets.cosmic_username }}", - "cosmic_passwd": "${{ secrets.cosmic_passwd }}", - "all": true, - "stub": true, - "build_references": true - } - profiles: test,aws_tower - - uses: actions/upload-artifact@v4 - with: - name: Tower debug log file - path: | - tower_action_*.log - tower_action_*.json - - - name: Launch workflow via tower - uses: seqeralabs/action-tower-launch@v2 - with: - workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} - access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} - compute_env: ${{ secrets.TOWER_COMPUTE_ENV }} - workdir: s3://${{ secrets.AWS_S3_BUCKET }}/work/rnafusion/work-${{ github.sha }} - parameters: | - { - "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}", - "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/results-${{ github.sha }}/references", - "cosmic_username": "${{ secrets.cosmic_username }}", - "cosmic_passwd": "${{ secrets.cosmic_passwd }}", - "all": true, + "genomes_base": "s3://${{ secrets.AWS_S3_BUCKET }}/rnafusion/references", + "tools": "all", "stub": true + "no_cosmic": true" } - profiles: test,aws_tower - - uses: actions/upload-artifact@v4 + profiles: test + + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: Tower debug log file path: | diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml index 19704d239..00e20510e 100644 --- a/.github/workflows/branch.yml +++ b/.github/workflows/branch.yml @@ -1,15 +1,17 @@ name: nf-core branch protection -# This workflow is triggered on PRs to master branch on the repository -# It fails when someone tries to make a PR against the nf-core `master` branch instead of `dev` +# This workflow is triggered on PRs to `main`/`master` branch on the repository +# It fails when someone tries to make a PR against the nf-core `main`/`master` branch instead of `dev` on: pull_request_target: - branches: [master] + branches: + - main + - master jobs: test: runs-on: ubuntu-latest steps: - # PRs to the nf-core repo master branch are only ok if coming from the nf-core repo `dev` or any `patch` branches + # PRs to the nf-core repo main/master branch are only ok if coming from the nf-core repo `dev` or any `patch` branches - name: Check PRs if: github.repository == 'nf-core/rnafusion' run: | @@ -22,7 +24,7 @@ jobs: uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2 with: message: | - ## This PR is against the `master` branch :x: + ## This PR is against the `${{github.event.pull_request.base.ref}}` branch :x: * Do not close this PR * Click _Edit_ and change the `base` to `dev` @@ -32,9 +34,9 @@ jobs: Hi @${{ github.event.pull_request.user.login }}, - It looks like this pull-request is has been made against the [${{github.event.pull_request.head.repo.full_name }}](https://github.com/${{github.event.pull_request.head.repo.full_name }}) `master` branch. - The `master` branch on nf-core repositories should always contain code from the latest release. - Because of this, PRs to `master` are only allowed if they come from the [${{github.event.pull_request.head.repo.full_name }}](https://github.com/${{github.event.pull_request.head.repo.full_name }}) `dev` branch. + It looks like this pull-request is has been made against the [${{github.event.pull_request.head.repo.full_name }}](https://github.com/${{github.event.pull_request.head.repo.full_name }}) ${{github.event.pull_request.base.ref}} branch. + The ${{github.event.pull_request.base.ref}} branch on nf-core repositories should always contain code from the latest release. + Because of this, PRs to ${{github.event.pull_request.base.ref}} are only allowed if they come from the [${{github.event.pull_request.head.repo.full_name }}](https://github.com/${{github.event.pull_request.head.repo.full_name }}) `dev` branch. You do not need to close this PR, you can change the target branch to `dev` by clicking the _"Edit"_ button at the top of this page. Note that even after this, the test will continue to show as failing until you push a new commit. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 0987a1fcc..000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,55 +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 - -concurrency: - group: "${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}" - cancel-in-progress: true - -jobs: - test: - name: Run pipeline with test data - # Only run on push if this is the nf-core dev branch (merged PRs) - if: "${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/rnafusion') }}" - runs-on: ubuntu-latest - strategy: - matrix: - NXF_VER: - - "23.04.0" - - "latest-everything" - trim_parameters: - - "--fastp_trim false" - - "--fastp_trim true" - 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 - - - name: Dry test build - run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub --build_references \ - --outdir /home/runner/work/rnafusion/rnafusion/results --all \ - --genomes_base /home/runner/work/rnafusion/rnafusion/results/references \ - --cosmic_username ${{ secrets.COSMIC_USERNAME }} --cosmic_passwd ${{ secrets.COSMIC_PASSWD }} - - - name: Dry test run - run: | - nextflow run ${GITHUB_WORKSPACE} -profile test,docker -stub \ - --outdir /home/runner/work/rnafusion/rnafusion/results --all ${{ matrix.trim_parameters }} \ - --genomes_base /home/runner/work/rnafusion/rnafusion/results/references diff --git a/.github/workflows/clean-up.yml b/.github/workflows/clean-up.yml index 0b6b1f272..ac030fd58 100644 --- a/.github/workflows/clean-up.yml +++ b/.github/workflows/clean-up.yml @@ -10,7 +10,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9 + - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9 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." diff --git a/.github/workflows/download_pipeline.yml b/.github/workflows/download_pipeline.yml index 08622fd51..11f0d0cbe 100644 --- a/.github/workflows/download_pipeline.yml +++ b/.github/workflows/download_pipeline.yml @@ -1,72 +1,127 @@ -name: Test successful pipeline download with 'nf-core download' +name: Test successful pipeline download with 'nf-core pipelines download' # Run the workflow when: # - dispatched manually -# - when a PR is opened or reopened to master branch +# - when a PR is opened or reopened to main/master branch # - the head branch of the pull request is updated, i.e. if fixes for a release are pushed last minute to dev. on: workflow_dispatch: inputs: testbranch: - description: "The specific branch you wish to utilize for the test execution of nf-core download." + description: "The specific branch you wish to utilize for the test execution of nf-core pipelines download." required: true default: "dev" pull_request: - types: - - opened - branches: - - master - pull_request_target: branches: + - main - master env: NXF_ANSI_LOG: false jobs: + configure: + runs-on: ubuntu-latest + outputs: + REPO_LOWERCASE: ${{ steps.get_repo_properties.outputs.REPO_LOWERCASE }} + REPOTITLE_LOWERCASE: ${{ steps.get_repo_properties.outputs.REPOTITLE_LOWERCASE }} + REPO_BRANCH: ${{ steps.get_repo_properties.outputs.REPO_BRANCH }} + steps: + - name: Get the repository name and current branch + id: get_repo_properties + run: | + echo "REPO_LOWERCASE=${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT" + echo "REPOTITLE_LOWERCASE=$(basename ${GITHUB_REPOSITORY,,})" >> "$GITHUB_OUTPUT" + echo "REPO_BRANCH=${{ github.event.inputs.testbranch || 'dev' }}" >> "$GITHUB_OUTPUT" + download: runs-on: ubuntu-latest + needs: configure steps: - name: Install Nextflow - uses: nf-core/setup-nextflow@v1 + uses: nf-core/setup-nextflow@v2 + + - name: Disk space cleanup + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 - - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: - python-version: "3.11" + python-version: "3.13" architecture: "x64" - - uses: eWaterCycle/setup-singularity@931d4e31109e875b13309ae1d07c70ca8fbc8537 # v7 + + - name: Setup Apptainer + uses: eWaterCycle/setup-apptainer@4bb22c52d4f63406c49e94c804632975787312b3 # v2.0.0 with: - singularity-version: 3.8.3 + apptainer-version: 1.3.4 - name: Install dependencies run: | 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 + - name: Make a cache directory for the container images 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} + mkdir -p ./singularity_container_images - name: Download the pipeline env: - NXF_SINGULARITY_CACHEDIR: ./ + NXF_SINGULARITY_CACHEDIR: ./singularity_container_images run: | - nf-core download ${{ env.REPO_LOWERCASE }} \ - --revision ${{ env.REPO_BRANCH }} \ - --outdir ./${{ env.REPOTITLE_LOWERCASE }} \ + nf-core pipelines download ${{ needs.configure.outputs.REPO_LOWERCASE }} \ + --revision ${{ needs.configure.outputs.REPO_BRANCH }} \ + --outdir ./${{ needs.configure.outputs.REPOTITLE_LOWERCASE }} \ --compress "none" \ --container-system 'singularity' \ - --container-library "quay.io" -l "docker.io" -l "ghcr.io" \ + --container-library "quay.io" -l "docker.io" -l "community.wave.seqera.io/library/" \ --container-cache-utilisation 'amend' \ - --download-configuration + --download-configuration 'yes' - name: Inspect download - run: tree ./${{ env.REPOTITLE_LOWERCASE }} + run: tree ./${{ needs.configure.outputs.REPOTITLE_LOWERCASE }} + + - name: Inspect container images + run: tree ./singularity_container_images | tee ./container_initial - - name: Run the downloaded pipeline + - name: Count the downloaded number of container images + id: count_initial + run: | + image_count=$(ls -1 ./singularity_container_images | wc -l | xargs) + echo "Initial container image count: $image_count" + echo "IMAGE_COUNT_INITIAL=$image_count" >> "$GITHUB_OUTPUT" + + - name: Run the downloaded pipeline (stub) + id: stub_run_pipeline + continue-on-error: true env: - NXF_SINGULARITY_CACHEDIR: ./ + NXF_SINGULARITY_CACHEDIR: ./singularity_container_images NXF_SINGULARITY_HOME_MOUNT: true - run: nextflow run ./${{ env.REPOTITLE_LOWERCASE }}/$( sed 's/\W/_/g' <<< ${{ env.REPO_BRANCH }}) -stub -profile test,singularity --outdir ./results + run: nextflow run ./${{needs.configure.outputs.REPOTITLE_LOWERCASE }}/$( sed 's/\W/_/g' <<< ${{ needs.configure.outputs.REPO_BRANCH }}) -stub -profile test,singularity --outdir ./results + + - name: Count the downloaded number of container images + id: count_afterwards + run: | + image_count=$(ls -1 ./singularity_container_images | wc -l | xargs) + echo "Post-pipeline run container image count: $image_count" + echo "IMAGE_COUNT_AFTER=$image_count" >> "$GITHUB_OUTPUT" + + - name: Compare container image counts + id: count_comparison + run: | + if [ "${{ steps.count_initial.outputs.IMAGE_COUNT_INITIAL }}" -ne "${{ steps.count_afterwards.outputs.IMAGE_COUNT_AFTER }}" ]; then + initial_count=${{ steps.count_initial.outputs.IMAGE_COUNT_INITIAL }} + final_count=${{ steps.count_afterwards.outputs.IMAGE_COUNT_AFTER }} + difference=$((final_count - initial_count)) + echo "$difference additional container images were \n downloaded at runtime . The pipeline has no support for offline runs!" + tree ./singularity_container_images > ./container_afterwards + diff ./container_initial ./container_afterwards + exit 1 + else + echo "The pipeline can be downloaded successfully!" + fi + + - name: Upload Nextflow logfile for debugging purposes + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: nextflow_logfile.txt + path: .nextflow.log* + include-hidden-files: true diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix_linting.yml similarity index 94% rename from .github/workflows/fix-linting.yml rename to .github/workflows/fix_linting.yml index 36ecd2076..7304c0f52 100644 --- a/.github/workflows/fix-linting.yml +++ b/.github/workflows/fix_linting.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: token: ${{ secrets.nf_core_bot_auth_token }} @@ -32,9 +32,9 @@ jobs: GITHUB_TOKEN: ${{ secrets.nf_core_bot_auth_token }} # Install and run pre-commit - - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: - python-version: 3.11 + python-version: "3.13" - name: Install pre-commit run: pip install pre-commit diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 073e18767..8b0f88c36 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -1,11 +1,8 @@ name: nf-core linting # This workflow is triggered on pushes and PRs to the repository. -# It runs the `nf-core lint` and markdown lint tests to ensure +# It runs the `nf-core pipelines lint` and markdown lint tests to ensure # that the code meets the nf-core guidelines. on: - push: - branches: - - dev pull_request: release: types: [published] @@ -14,13 +11,12 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - - name: Set up Python 3.11 - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5 + - name: Set up Python 3.13 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: - python-version: 3.11 - cache: "pip" + python-version: "3.13" - name: Install pre-commit run: pip install pre-commit @@ -32,27 +28,42 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out pipeline code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Install Nextflow - uses: nf-core/setup-nextflow@v1 + uses: nf-core/setup-nextflow@v2 - - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: - python-version: "3.11" + python-version: "3.13" architecture: "x64" + - name: read .nf-core.yml + uses: pietrobolcato/action-read-yaml@9f13718d61111b69f30ab4ac683e67a56d254e1d # 1.1.0 + id: read_yml + with: + config: ${{ github.workspace }}/.nf-core.yml + - name: Install dependencies run: | python -m pip install --upgrade pip - pip install nf-core + pip install nf-core==${{ steps.read_yml.outputs['nf_core_version'] }} + + - name: Run nf-core pipelines lint + if: ${{ github.base_ref != 'master' }} + env: + GITHUB_COMMENTS_URL: ${{ github.event.pull_request.comments_url }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_PR_COMMIT: ${{ github.event.pull_request.head.sha }} + run: nf-core -l lint_log.txt pipelines lint --dir ${GITHUB_WORKSPACE} --markdown lint_results.md - - name: Run nf-core lint + - name: Run nf-core pipelines lint --release + if: ${{ github.base_ref == 'master' }} env: GITHUB_COMMENTS_URL: ${{ github.event.pull_request.comments_url }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_PR_COMMIT: ${{ github.event.pull_request.head.sha }} - run: nf-core -l lint_log.txt lint --dir ${GITHUB_WORKSPACE} --markdown lint_results.md + run: nf-core -l lint_log.txt pipelines lint --release --dir ${GITHUB_WORKSPACE} --markdown lint_results.md - name: Save PR number if: ${{ always() }} @@ -60,7 +71,7 @@ jobs: - name: Upload linting log file artifact if: ${{ always() }} - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: linting-logs path: | diff --git a/.github/workflows/linting_comment.yml b/.github/workflows/linting_comment.yml index b706875fc..d43797d9d 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@f6b0bace624032e30a85a8fd9c1a7f8f611f5737 # v3 + 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@52423e01640425a022ef5fd42c6fb5f633a02728 # 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 000000000..e796a814c --- /dev/null +++ b/.github/workflows/nf-test.yml @@ -0,0 +1,147 @@ +name: Run nf-test +on: + pull_request: + paths-ignore: + - "docs/**" + - "**/meta.yml" + - "**/*.md" + - "**/*.png" + - "**/*.svg" + release: + types: [published] + workflow_dispatch: + +# 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.2" + NFT_WORKDIR: "~" + NXF_ANSI_LOG: false + NXF_SINGULARITY_CACHEDIR: ${{ github.workspace }}/.singularity + NXF_SINGULARITY_LIBRARYDIR: ${{ github.workspace }}/.singularity + +jobs: + nf-test-changes: + name: nf-test-changes + runs-on: # use self-hosted runners + - runs-on=${{ github.run_id }}-nf-test-changes + - runner=4cpu-linux-x64 + 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + 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 self-hosted runners + - runs-on=${{ github.run_id }}-nf-test + - runner=4cpu-linux-x64 + - disk=large + 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 conda and singularity on dev + exclude: + - isMain: false + profile: "conda" + - isMain: false + profile: "singularity" + NXF_VER: + - "24.10.5" + - "latest-everything" + env: + NXF_ANSI_LOG: false + TOTAL_SHARDS: ${{ needs.nf-test-changes.outputs.total_shards }} + + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + fetch-depth: 0 + + - name: Clean up Disk space + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + + - 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 }} + 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 self-hosted runners + - runs-on=${{ github.run_id }}-confirm-pass + - runner=2cpu-linux-x64 + 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/.github/workflows/release-announcements.yml b/.github/workflows/release-announcements.yml index d468aeaae..0f7324956 100644 --- a/.github/workflows/release-announcements.yml +++ b/.github/workflows/release-announcements.yml @@ -12,7 +12,7 @@ jobs: - name: get topics and convert to hashtags id: get_topics run: | - curl -s https://nf-co.re/pipelines.json | jq -r '.remote_workflows[] | select(.full_name == "${{ github.repository }}") | .topics[]' | awk '{print "#"$0}' | tr '\n' ' ' >> $GITHUB_OUTPUT + echo "topics=$(curl -s https://nf-co.re/pipelines.json | jq -r '.remote_workflows[] | select(.full_name == "${{ github.repository }}") | .topics[]' | awk '{print "#"$0}' | tr '\n' ' ')" | sed 's/-//g' >> $GITHUB_OUTPUT - uses: rzr/fediverse-action@master with: @@ -25,45 +25,12 @@ jobs: Please see the changelog: ${{ github.event.release.html_url }} - ${{ steps.get_topics.outputs.GITHUB_OUTPUT }} #nfcore #openscience #nextflow #bioinformatics - - send-tweet: - runs-on: ubuntu-latest - - steps: - - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5 - with: - python-version: "3.10" - - name: Install dependencies - run: pip install tweepy==4.14.0 - - name: Send tweet - shell: python - run: | - import os - import tweepy - - client = tweepy.Client( - access_token=os.getenv("TWITTER_ACCESS_TOKEN"), - access_token_secret=os.getenv("TWITTER_ACCESS_TOKEN_SECRET"), - consumer_key=os.getenv("TWITTER_CONSUMER_KEY"), - consumer_secret=os.getenv("TWITTER_CONSUMER_SECRET"), - ) - tweet = os.getenv("TWEET") - client.create_tweet(text=tweet) - env: - TWEET: | - Pipeline release! ${{ github.repository }} v${{ github.event.release.tag_name }} - ${{ github.event.release.name }}! - - Please see the changelog: ${{ github.event.release.html_url }} - TWITTER_CONSUMER_KEY: ${{ secrets.TWITTER_CONSUMER_KEY }} - TWITTER_CONSUMER_SECRET: ${{ secrets.TWITTER_CONSUMER_SECRET }} - TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }} - TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }} + ${{ steps.get_topics.outputs.topics }} #nfcore #openscience #nextflow #bioinformatics bsky-post: runs-on: ubuntu-latest steps: - - uses: zentered/bluesky-post-action@80dbe0a7697de18c15ad22f4619919ceb5ccf597 # v0.1.0 + - uses: zentered/bluesky-post-action@6461056ea355ea43b977e149f7bf76aaa572e5e8 # v0.3.0 with: post: | Pipeline release! ${{ github.repository }} v${{ github.event.release.tag_name }} - ${{ github.event.release.name }}! diff --git a/.github/workflows/template-version-comment.yml b/.github/workflows/template-version-comment.yml new file mode 100644 index 000000000..beb5c77fb --- /dev/null +++ b/.github/workflows/template-version-comment.yml @@ -0,0 +1,46 @@ +name: nf-core template version comment +# This workflow is triggered on PRs to check if the pipeline template version matches the latest nf-core version. +# It posts a comment to the PR, even if it comes from a fork. + +on: pull_request_target + +jobs: + template_version: + runs-on: ubuntu-latest + steps: + - name: Check out pipeline code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: Read template version from .nf-core.yml + uses: nichmor/minimal-read-yaml@1f7205277e25e156e1f63815781db80a6d490b8f # v0.0.2 + id: read_yml + with: + config: ${{ github.workspace }}/.nf-core.yml + + - name: Install nf-core + run: | + python -m pip install --upgrade pip + pip install nf-core==${{ steps.read_yml.outputs['nf_core_version'] }} + + - name: Check nf-core outdated + id: nf_core_outdated + run: echo "OUTPUT=$(pip list --outdated | grep nf-core)" >> ${GITHUB_ENV} + + - name: Post nf-core template version comment + uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2 + if: | + contains(env.OUTPUT, 'nf-core') + with: + repo-token: ${{ secrets.NF_CORE_BOT_AUTH_TOKEN }} + allow-repeats: false + message: | + > [!WARNING] + > Newer version of the nf-core template is available. + > + > Your pipeline is using an old version of the nf-core template: ${{ steps.read_yml.outputs['nf_core_version'] }}. + > Please update your pipeline to the latest version. + > + > For more documentation on how to update your pipeline, please see the [nf-core documentation](https://github.com/nf-core/tools?tab=readme-ov-file#sync-a-pipeline-with-the-template) and [Synchronisation documentation](https://nf-co.re/docs/contributing/sync). + # diff --git a/.gitignore b/.gitignore index 5124c9ac7..23b0c7de9 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ results/ testing/ testing* *.pyc +null/ +.nf-test* diff --git a/.gitpod.yml b/.gitpod.yml index 105a1821a..83599f633 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -4,17 +4,7 @@ tasks: command: | pre-commit install --install-hooks nextflow self-update - - name: unset JAVA_TOOL_OPTIONS - command: | - unset JAVA_TOOL_OPTIONS vscode: - extensions: # based on nf-core.nf-core-extensionpack - - esbenp.prettier-vscode # Markdown/CommonMark linting and style checking for Visual Studio Code - - EditorConfig.EditorConfig # override user/workspace settings with settings found in .editorconfig files - - Gruntfuggly.todo-tree # Display TODO and FIXME in a tree view in the activity bar - - mechatroner.rainbow-csv # Highlight columns in csv files in different colors - # - nextflow.nextflow # Nextflow syntax highlighting - - oderwat.indent-rainbow # Highlight indentation level - - streetsidesoftware.code-spell-checker # Spelling checker for source code - - charliermarsh.ruff # Code linter Ruff + extensions: + - nf-core.nf-core-extensionpack # https://github.com/nf-core/vscode-extensionpack diff --git a/.nf-core.yml b/.nf-core.yml index 78a3fd2e6..4f80b3e13 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -1,5 +1,19 @@ -repository_type: pipeline lint: files_unchanged: - .github/CONTRIBUTING.md - .github/PULL_REQUEST_TEMPLATE.md + - conf/igenomes.config + - conf/igenomes_ignored.config + files_exist: + - tests/default.nf.test +nf_core_version: 3.3.2 +repository_type: pipeline +template: + author: Martin Proks, Annick Renevey + description: Nextflow rnafusion analysis pipeline, part of the nf-core community. + force: false + is_nfcore: true + name: rnafusion + org: nf-core + outdir: . + version: 4.0.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index af57081f6..bb41beec1 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: v5.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 437d763d0..edd29f01e 100644 --- a/.prettierignore +++ b/.prettierignore @@ -10,3 +10,4 @@ testing/ testing* *.pyc bin/ +ro-crate-metadata.json diff --git a/.prettierrc.yml b/.prettierrc.yml index c81f9a766..07dbd8bb9 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/CHANGELOG.md b/CHANGELOG.md index 871c46594..2e1eb9277 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,23 +3,179 @@ 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). +## v4.0.0 - [2025-09-10] + +### Added + +- Normalized gene expression calculated [#488](https://github.com/nf-core/rnafusion/pull/488) +- Primary assembly now used as main reference genome FASTA file, as recommended by the STAR manual [#488](https://github.com/nf-core/rnafusion/pull/488) +- Use of only ensembl GTF file, not chr.gtf file as GTF reference file [#488](https://github.com/nf-core/rnafusion/pull/488) +- Add nf-test to local module: `ENSEMBL_DOWNLOAD` [#539](https://github.com/nf-core/rnafusion/pull/539) +- Add nf-test to local module: `HGNC_DOWNLOAD` [#540](https://github.com/nf-core/rnafusion/pull/540) +- Add nf-test to local subworkflow: `STRINGTIE_WORKFLOW` [#541](https://github.com/nf-core/rnafusion/pull/541) +- Option to avoid using COSMIC (for example in the case of clinical use) [#547](https://github.com/nf-core/rnafusion/pull/547) +- Add nf-test to nf-core module: `PICARD_COLLECTRNASEQMETRICS` and update module [#551](https://github.com/nf-core/rnafusion/pull/551) +- Add `--skip_vcf` boolean parameter to skip vcf file generation [#554](https://github.com/nf-core/rnafusion/pull/554) +- Add nf-test to local module: `FUSIONREPORT_DOWNLOAD` [#560](https://github.com/nf-core/rnafusion/pull/560) +- Add nf-test to local subworkflow: `QC_WORKFLOW` [#568](https://github.com/nf-core/rnafusion/pull/568) +- Add nf-test to local subworkflow: `TRIM_WORKFLOW` [#572](https://github.com/nf-core/rnafusion/pull/572) +- Add nf-test to local module: `FUSIONREPORT_DETECT`. Improve `FUSIONREPORT_DOWNLOAD` module [#577](https://github.com/nf-core/rnafusion/pull/577) +- Add nf-test to local subworkflow: `ARRIBA_WORKFLOW` [#578](https://github.com/nf-core/rnafusion/pull/578) +- Add nf-test to local module: `STARFUSION_BUILD`. [#585](https://github.com/nf-core/rnafusion/pull/585) +- Add nf-test to local module: `STARFUSION_DETECT`. [#586](https://github.com/nf-core/rnafusion/pull/586) +- Added a new module `CTATSPLICING_STARTOCANCERINTRONS` and a new parameter `--ctatsplicing`. This options creates reports on cancer splicing aberrations and requires one or both of `--arriba` and `--starfusion` to be given. [#587](https://github.com/nf-core/rnafusion/pull/587) +- Add parameter `--references_only` when no data should be analysed, but only the references should be built [#505](https://github.com/nf-core/rnafusion/pull/505) +- Add nf-test to local subworkflow: `FUSIONCATCHER_WORKFLOW` [#591](https://github.com/nf-core/rnafusion/pull/591) +- Add nf-test to local subworkflow: `STARFUSION_WORKFLOW`. [#597](https://github.com/nf-core/rnafusion/pull/597) +- Add nf-test to local module: `FUSIONINSPECTOR`. [#601](https://github.com/nf-core/rnafusion/pull/601) +- Added `CTATSPLICING_PREPGENOMELIB` to update the starfusion genome library directory with a cancer splicing index. [#610](https://github.com/nf-core/rnafusion/pull/610) +- Add nf-test to local subworkflow: `FUSIONREPORT_WORKFLOW`. [#607](https://github.com/nf-core/rnafusion/pull/607) +- Add nf-test to local module: `ARRIBA_VISUALISATION`. [#625](https://github.com/nf-core/rnafusion/pull/625) +- Added the following fields to the samplesheet [#647](https://github.com/nf-core/rnafusion/pull/647): + - `bam`: A BAM file aligned with STAR, it's the responsibility of the pipeline user to make sure this file has been correctly called. + - `bai`: The index of the BAM file, this is not required when a `bam` file has been given but can increase the pipeline speed a bit. + - `cram`: A CRAM file aligned with STAR, it's the responsibility of the pipeline user to make sure this file has been correctly called. + - `crai`: The index of the CRAM file, this is not required when a `cram` file has been given but can increase the pipeline speed a bit. + - `junctions`: A file containing the junctions determined by STAR (needed by `starfusion` and `ctatsplicing`) + - `splice_junctions` A file containing the splice junctions determined by STAR (needed by `ctatsplicing`) +- Added `--fusioncatcher_download_link`. [#650](https://github.com/nf-core/rnafusion/pull/650) +- Added the `seq_platform` and `seq_center` fields to the samplesheet. These values can be used to overwrite the value of `--seq_platform` and `--seq_center` on a sample-by-sample basis [#654](https://github.com/nf-core/rnafusion/pull/654) +- Moved strandedness determination for picard collectrnaseqmetrics into modules.config [#658](https://github.com/nf-core/rnafusion/pull/658) +- Using option `--human_gencode_filter` while building STARFusion references for human species [#657](https://github.com/nf-core/rnafusion/pull/657) +- Added `--star_limit_bam_sort_ram` to set the maximum memory for sorting the BAM files in STAR. [#668](https://github.com/nf-core/rnafusion/pull/668) +- Update STAR-Fusion to 1.15.0 and update nf-core modules [#664](https://github.com/nf-core/rnafusion/pull/664) +- Update fusionreport 4.0.0 that replaces the score of a fusion with a Fusion Indication Index [#667](https://github.com/nf-core/rnafusion/pull/667) +- Added a extra trimming step for fusioncatcher in case a different read-length is wished for this tool only [#674](https://github.com/nf-core/rnafusion/pull/674) +- Added support for references hosted on the nf-core AWS S3 bucket. [#717](https://github.com/nf-core/rnafusion/pull/717) +- Added `--dfam_hmm`, `--dfam_h3f`, `--dfam_h3i`, `--dfam_h3m`, `--dfam_h3p`, `--pfam_file` and `--annot_filter_url` parameters to allow use of custom files in `STARFUSION_BUILD` module [#709](https://github.com/nf-core/rnafusion/pull/709) +- Add nf-test to local module: `VCF_COLLECT`. [#745](https://github.com/nf-core/rnafusion/pull/745) +- Added nf-test for local subworkflow: `FUSIONINSPECTOR_WORKFLOW`. [#753](https://github.com/nf-core/rnafusion/pull/753) + +### Changed + +- Updated modules and migrated non-specific modules to nf-core/modules [#484](https://github.com/nf-core/rnafusion/pull/484) +- Updated to nf-core/tools 3.0.2 [#504](https://github.com/nf-core/rnafusion/pull/504) +- Remove local module `RRNA_TRANSCRIPTS` (replaced by nf-core module) [#541](https://github.com/nf-core/rnafusion/pull/541) +- Allow fastq files without a dot before .fn(.gz)/.fastq(.gz) files [#548](https://github.com/nf-core/rnafusion/pull/548) +- Remove double nested folder introduced in [#577](https://github.com/nf-core/rnafusion/pull/577), [#581](https://github.com/nf-core/rnafusion/pull/581) +- Use docker.io and galaxy containers for fusioncatcher and starfusion (incl. fusioninspector) instead of wave as they are not functional on wave [#588](https://github.com/nf-core/rnafusion/pull/588) +- Update STAR-Fusion to 1.14 [#588](https://github.com/nf-core/rnafusion/pull/588) +- Use "-genePredExt -geneNameAsName2 -ignoreGroupsWithoutExons" (to mimic gms/tomte) for GTF_TO_REFFLAT [#505](https://github.com/nf-core/rnafusion/pull/505) +- Integrate reference building in the main workflow [#505](https://github.com/nf-core/rnafusion/pull/505) +- Move from ensembl to gencode base [#505](https://github.com/nf-core/rnafusion/pull/505) +- Update from ensembl 102 to gencode 46 default references [#505](https://github.com/nf-core/rnafusion/pull/505) +- Update`FUSIONINSPECTOR` to v2.10.0. [#601](https://github.com/nf-core/rnafusion/pull/601) +- Remove local module `STARFUSION_DOWNLOAD` [#598](https://github.com/nf-core/rnafusion/pull/598) +- Fix error message when parameter outdir is missing [#611](https://github.com/nf-core/rnafusion/pull/611) +- Updated documentation for fusion-report score calculation to reflect 80/20 weight distribution between thttps://github.com/nf-core/rnafusion/pull/633ool detection and database hits [#620](https://github.com/nf-core/rnafusion/pull/620) +- The STAR alignment now only runs once instead of multiple times when using `--arriba` and `--starfusion` [#633](https://github.com/nf-core/rnafusion/pull/633) +- The `--cram` parameter has been converted to a boolean value instead of the comma-separated list of values. Use this parameter if you also want to create CRAM files from the BAM files created with STAR [#633](https://github.com/nf-core/rnafusion/pull/633) +- Update htslib and samtools version in `star/align` to 1.21 [#634](https://github.com/nf-core/rnafusion/pull/634) +- Updated Zenodo DOI in badge [#639](https://github.com/nf-core/rnafusion/pull/639) +- `--run_fusioncatcher` back to `fusioncatcher` [#641](https://github.com/nf-core/rnafusion/pull/641) +- Removed `--fastp_trim`, `--arriba`, `--ctatsplicing`, `--fusioncatcher`, `--starfusion`, `--stringtie` and `--all` and replaced these parameters with the `--tools` parameter. This parameter takes a comma-delimited list of tool names to run for the pipeline and is a required parameter. Following tools are supported by this parameter [#645](https://github.com/nf-core/rnafusion/pull/645): + - `arriba` + - `ctatsplicing` + - `fusioncatcher` + - `starfusion` + - `stringtie` + - `fusionreport` + - `fastp` + - `salmon` + - `fusioninspector` + - `all` => This will automatically run all of the above tools +- Updated all `wget` containers to `conda-forge::wget=1.21.4` [#655](https://github.com/nf-core/rnafusion/pull/655) +- Using FusionInspector abridged output (that now contains coding effects) for downstream analysis [#669](https://github.com/nf-core/rnafusion/pull/669) +- Replaced local `FUSIONREPORT` and `FUSIONREPORT_DOWNLOAD` with `FUSIONREPORT_DETECT` and `FUSIONREPORT_DOWNLOAD` from nf-core [#703](https://github.com/nf-core/rnafusion/pull/703) +- Updated arriba to v2.5.0 [#693](https://github.com/nf-core/rnafusion/pull/693) +- Update logo [#715](https://github.com/nf-core/rnafusion/pull/715) +- Slight documentation update [#719](https://github.com/nf-core/rnafusion/pull/719) +- Replaced local `STARFUSION_BUILD` for module from nf-core [#709](https://github.com/nf-core/rnafusion/pull/709) +- Modified `test_build` profile to use a reduced version of Pfam and Dfam files [#733](https://github.com/nf-core/rnafusion/pull/733) +- Updated the documentation to reflect the changes done in this release [#741](https://github.com/nf-core/rnafusion/pull/741) +- Changed local `ARRIBA_VISUALIZATION`, `CTATSPLICING_STARTOCANCERINTRONS`, `CTATSPLICING_PREPGENOMELIB`, `FUSIONINSPECTOR`, `STARFUSION_DETECT` for its nf-core module versions [#740](https://github.com/nf-core/rnafusion/pull/740) +- Replaced local subworkflow `TRIM_WORKFLOW` for its nf-core subworkflow equivalent `FASTQ_FASTQC_UMITOOLS_FASTP` [#752](https://github.com/nf-core/rnafusion/pull/752) +- Changed local `FASTQ_ALIGN_STAR` for subworkflow from nf-core [#756](https://github.com/nf-core/rnafusion/pull/756) +- Replaced local subworkflow `STRINGTIE_WORKFLOW` for its nf-core version `BAM_STRINGTIE_MERGE` and the local module module `GTF_TO_REFFLAT` for nf-core's `UCSC_GTFTOGENEPRED` [#758](https://github.com/nf-core/rnafusion/pull/758 +- Update modules and close todos as preparation for release [#759](https://github.com/nf-core/rnafusion/pull/759) + +### Fixed + +- Fixed some Nextflow run-commands in the docs [#491](https://github.com/nf-core/rnafusion/pull/491) +- Fixed bug when trying to build indices behind a proxy and wget was unable to download arriba indices [#495](https://github.com/nf-core/rnafusion/issues/495) +- Fixed bug in `FUSIONREPORT_DOWNLOAD` when building references with `--no_cosmic parameter` [#555](https://github.com/nf-core/rnafusion/issues/555) +- Refactor structure in `FUSIONREPORT_DOWNLOAD` to use cosmic credentials in `ext.args` [#556](https://github.com/nf-core/rnafusion/issues/556) +- Fixed bug in nf-core `RRNATRANSCRIPTS` module [#563](https://github.com/nf-core/rnafusion/issues/563) +- Fixed bug in `GFFREAD` that caused output `gffread_fasta` not being produced [#565](https://github.com/nf-core/rnafusion/issues/565) +- Fixed bug in `FUSIONCATCHER_DOWNLOAD` that caused an error when running with singularity profile [#573](https://github.com/nf-core/rnafusion/issues/573) +- Fixed missing script `gtf2bed` which caused local module `GET_RRNA_TRANSCRIPTS` to fail [#602](https://github.com/nf-core/rnafusion/issues/602) +- Fixed the codebase to be compatible with the Nextflow language server [#634](https://github.com/nf-core/rnafusion/pull/634) +- Updated the input validation to be more strict. This will prevent more errors down the line in the pipeline [#640](https://github.com/nf-core/rnafusion/pull/640) +- The `FUSIONINSPECTOR` process will no longer fail when no fusions have been found. [#651](https://github.com/nf-core/rnafusion/pull/651) +- Fixed STAR-Fusion build would fail when downloading Pfam and Dfam resources behind SSL. [#653](https://github.com/nf-core/rnafusion/pull/653) +- Fix bug in argument handling for FusionInspector [#669](https://github.com/nf-core/rnafusion/pull/669) +- Upgrade STAR-Fusion to 1.15.1 to solve problem building STAR-Fusion references with `--human_gencode_filter` [#683](https://github.com/nf-core/rnafusion/pull/683) +- Fix missing memory unit for fusioncatcher [#674](https://github.com/nf-core/rnafusion/pull/674) +- Fix fusioncatcher download link [#693](https://github.com/nf-core/rnafusion/pull/693) +- Fix fusionreport singularity container [#713](https://github.com/nf-core/rnafusion/pull/713) +- Fix behavior when no fusion is present (log a warning and avoid running depending processes)[#714](https://github.com/nf-core/rnafusion/pull/714) +- Fix CTAT-SPLICING output when no cancer introns were found [#722](https://github.com/nf-core/rnafusion/pull/722) +- Update VCF_COLLECT script to adapt to transcript_version not being an entry in fusioninspector gtf anymore [#726](https://github.com/nf-core/rnafusion/pull/726) +- Fix rRNA detection and make it more customizable with nf-core modules [#736](https://github.com/nf-core/rnafusion/pull/736) +- Fix rRNA detection in GTF using `transcript_type` [#749](https://github.com/nf-core/rnafusion/pull/749) +- Fixed nf-test for `QC_WORKFLOW` subworkflow [#756](https://github.com/nf-core/rnafusion/pull/756) +- Fixed issue with bed creation, modifying AGAT arguments for non-coding CDS [#763](https://github.com/nf-core/rnafusion/pull/763) +- Fixed fusioncatcher hardlink issues in filesystems that don't allow hardlinks [#764](https://github.com/nf-core/rnafusion/pull/764) + +### Removed + +- Remove fusionGDB from documentation and fusion-report download stubs [#503](https://github.com/nf-core/rnafusion/pull/503) +- Removed test-build as reference building gets integrated in the main workflow [#505](https://github.com/nf-core/rnafusion/pull/505) +- Removed parameter `--build_references` +- Removed fusioncatcher build [#650](https://github.com/nf-core/rnafusion/pull/650) +- Removed subworkflow with less than two modules: `ARRIBA_WORKFLOW` [#692](https://github.com/nf-core/rnafusion/pull/692) +- Removed subworkflow with less than two modules: `STARFUSION_WORKFLOW` [#707](https://github.com/nf-core/rnafusion/pull/707) +- Removed subworkflow with less than two modules: `CTATSPLICING_WORKFLOW` [#704](https://github.com/nf-core/rnafusion/pull/704) +- Removed subworkflow with less than two modules: `FUSIONREPORT_WORKFLOW` [#721](https://github.com/nf-core/rnafusion/pull/721) +- Removed local module `GET_RRNA_TRANSCRIPTS` [#736](https://github.com/nf-core/rnafusion/pull/736) +- Removed old unused parameters `params.download_refs` and `params.fusioncatcher_download_link` [#752](https://github.com/nf-core/rnafusion/pull/752) + +### Parameters + +| Old parameter | New parameter | +| --------------------- | ------------------------------- | +| | `--no_cosmic` | +| `--build_references` | `--references_only` | +| `--fastp_trim` | `--tools fastp` | +| `--arriba` | `--tools arriba` | +| `--run_fusioncatcher` | `--tools fusioncatcher` | +| `--starfusion` | `--tools starfusion` | +| `--stringtie` | `--tools stringtie` | +| `--all` | `--tools all` | +| | `--fusioncatcher_download_link` | +| | `--trim_tail_fusioncatcher` | +| | `--save_trimmed_fail` | +| | `--save_merged` | +| | `--min_trimmed_reads` | +| | `--trim_tail_fusioncatcher` | + ## v3.0.2 - [2024-04-10] ### Added ### Changed -- Update to nf-tools 2.11.1 [#457] (https://github.com/nf-core/rnafusion/pull/457) +- Update to nf-tools 2.11.1 [#457](https://github.com/nf-core/rnafusion/pull/457) - Update picard collectrnaseqmetrics memory requirements to 0.8x what is provided [#474](https://github.com/nf-core/rnafusion/pull/474) ### Fixed -- fix bug when using parameter "whitelist" [#466](https://github.com/nf-core/rnafusion/pull/466) -- fix VCF_COLLECT handling when a tool is absent from FUSIONREPORT report [#458](https://github.com/nf-core/rnafusion/pull/458) -- fix VCF_COLLECT when fusioninspector output is empty but fusionreport is not [#465](https://github.com/nf-core/rnafusion/pull/465) -- fix VCF_COLLECT bug [#481](https://github.com/nf-core/rnafusion/pull/481) -- fix conda package for starfusion/detect[#482](https://github.com/nf-core/rnafusion/pull/482) -- fix logical gate so when stringtie should run but not starfusion, starfusion will not run[#482](https://github.com/nf-core/rnafusion/pull/482) +- Fix bug when using parameter "whitelist" [#466](https://github.com/nf-core/rnafusion/pull/466) +- Fix VCF_COLLECT handling when a tool is absent from FUSIONREPORT report [#458](https://github.com/nf-core/rnafusion/pull/458) +- Fix VCF_COLLECT when fusioninspector output is empty but fusionreport is not [#465](https://github.com/nf-core/rnafusion/pull/465) +- Fix VCF_COLLECT bug [#481](https://github.com/nf-core/rnafusion/pull/481) +- Fix conda package for starfusion/detect[#482](https://github.com/nf-core/rnafusion/pull/482) +- Fix logical gate so when stringtie should run but not starfusion, starfusion will not run[#482](https://github.com/nf-core/rnafusion/pull/482) ### Removed @@ -29,7 +185,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- python3 explicit in vcf_collect [#452](https://github.com/nf-core/rnafusion/pull/452) +- Python3 explicit in vcf_collect [#452](https://github.com/nf-core/rnafusion/pull/452) ### Fixed diff --git a/CITATIONS.md b/CITATIONS.md index f058a2451..5d2845541 100644 --- a/CITATIONS.md +++ b/CITATIONS.md @@ -24,7 +24,7 @@ - [FastQC](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/) - > Andrews, S. (2010). FastQC: A Quality Control Tool for High Throughput Sequence Data [Online]. +> Andrews, S. (2010). FastQC: A Quality Control Tool for High Throughput Sequence Data [Online]. - [FusionCatcher](https://github.com/ndaniel/fusioncatcher) @@ -46,7 +46,7 @@ - [MultiQC](https://pubmed.ncbi.nlm.nih.gov/27312411/) - > Ewels P, Magnusson M, Lundin S, Käller M. MultiQC: summarize analysis results for multiple tools and samples in a single report. Bioinformatics. 2016 Oct 1;32(19):3047-8. doi: 10.1093/bioinformatics/btw354. Epub 2016 Jun 16. PubMed PMID: 27312411; PubMed Central PMCID: PMC5039924. +> Ewels P, Magnusson M, Lundin S, Käller M. MultiQC: summarize analysis results for multiple tools and samples in a single report. Bioinformatics. 2016 Oct 1;32(19):3047-8. doi: 10.1093/bioinformatics/btw354. Epub 2016 Jun 16. PubMed PMID: 27312411; PubMed Central PMCID: PMC5039924. - [picard-tools](http://broadinstitute.github.io/picard) diff --git a/LICENSE b/LICENSE index 86e71fe15..feb286272 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) Martin Proks, Annick Renevey +Copyright (c) The nf-core/rnafusion team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index b418192ac..6f1a9fd19 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,26 @@

- - nf-core/rnafusion + + nf-core/rnafusion

-[![GitHub Actions CI Status](https://github.com/nf-core/rnafusion/actions/workflows/ci.yml/badge.svg)](https://github.com/nf-core/rnafusion/actions/workflows/ci.yml) +[![GitHub Actions CI Status](https://github.com/nf-core/rnafusion/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/rnafusion/actions/workflows/nf-test.yml) [![GitHub Actions Linting Status](https://github.com/nf-core/rnafusion/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/rnafusion/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/rnafusion/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.2565517-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.2565517) [![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com) -[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A523.04.0-23aa62.svg)](https://www.nextflow.io/) +[![Nextflow](https://img.shields.io/badge/version-%E2%89%A524.10.5-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.3.2-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.3.2) [![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/) [![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/) [![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/) -[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://tower.nf/launch?pipeline=https://github.com/nf-core/rnafusion) +[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/rnafusion) -[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23rnafusion-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/rnafusion)[![Follow on Twitter](http://img.shields.io/badge/twitter-%40nf__core-1DA1F2?labelColor=000000&logo=twitter)](https://twitter.com/nf_core)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core) +[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23rnafusion-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/rnafusion)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core) ## Introduction -**nf-core/rnafusion** is a bioinformatics best-practice analysis pipeline for RNA sequencing consisting of several tools designed for detecting and visualizing fusion genes. Results from up to 5 fusion callers tools are created, and are also aggregated, most notably in a pdf visualiation document, a vcf data collection file, and html and tsv reports. +**nf-core/rnafusion** is a bioinformatics best-practice analysis pipeline for RNA sequencing consisting of several tools designed for detecting and visualizing fusion genes. Results from up to 3 fusion callers tools are created, and are also aggregated, most notably in a pdf visualisation document, a vcf data collection file, and html and tsv reports. On release, automated continuous integration tests run the pipeline on a full-sized dataset on the AWS cloud infrastructure. This ensures that the pipeline runs on AWS, has sensible resource allocation defaults set to run on real-world datasets, and permits the persistent storage of results to benchmark between pipeline releases and other analysis sources. The results obtained from the full-sized test can be viewed on the [nf-core website](https://nf-co.re/rnafusion/results). @@ -29,39 +30,50 @@ In rnafusion the full-sized test includes reference building and fusion detectio ![nf-core/rnafusion metro map](docs/images/nf-core-rnafusion_metro_map.png) -### Build references +### References -`--build_references` triggers a parallel workflow to build references, which is a prerequisite to running the pipeline: +The references for the pipeline can be downloaded from the nf-core AWS megatests S3 bucket using the following command for the [AWS CLI tool](https://github.com/aws/aws-cli): -1. Download ensembl fasta and gtf files -2. Create [STAR](https://github.com/alexdobin/STAR) index -3. Download [Arriba](https://github.com/suhrig/arriba) references -4. Download [FusionCatcher](https://github.com/ndaniel/fusioncatcher) references -5. Download and build [STAR-Fusion](https://github.com/STAR-Fusion/STAR-Fusion) references -6. Download [Fusion-report](https://github.com/Clinical-Genomics/fusion-report) DBs +```bash +aws --no-sign-request s3 sync s3://nf-core-awsmegatests/rnafusion/references/ +``` + +The path to the downloaded references can then be provided to the pipeline with the `--genomes_base` parameter. + +⚠️ **Please note that the references are large and can take a long time to download, so it is recommended to download them once and use them for all future runs of the pipeline.** + +The pipeline is also able to build the references in case files from a specific gencode version are missing (Note: only gencode 46 is available for fusioncatcher). This is done automatically when the expected references are not found and these files will be automatically published in the directory specified by the `--genomes_base` parameter. Use the `--references_only` parameter to trigger the reference building workflow only, without running the rest of the pipeline. + +1. Download gencode fasta and gtf files +2. Download the HGNC nomenclature file +3. Create files needed for QC (Sequence Dictionary and RRNA intervals) +4. Convert the gtf file to a refflat file +5. Create the [Salmon](https://salmon.readthedocs.io/en/latest/) index +6. Create [STAR](https://github.com/alexdobin/STAR) index +7. Build [STAR-Fusion](https://github.com/STAR-Fusion/STAR-Fusion) and [CTAT-SPLICING](https://github.com/TrinityCTAT/CTAT-SPLICING) references +8. Download [Fusion-report](https://github.com/Clinical-Genomics/fusion-report) DBs + +> [!WARNING] +> References for Fusioncatcher and Arriba cannot be automatically created by the pipeline and should be downloaded from the S3 bucket or another source. See the [References](#references) section for more information. #### Main workflow 1. Input samplesheet check -2. Concatenate fastq files per sample ([cat](http://www.linfo.org/cat.html)) -3. Reads quality control ([FastQC](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/)) -4. Optional trimming with [fastp](https://github.com/OpenGene/fastp) -5. Arriba subworkflow - - [STAR](https://github.com/alexdobin/STAR) alignment - - [Arriba](https://github.com/suhrig/arriba) fusion detection -6. STAR-fusion subworkflow - - [STAR](https://github.com/alexdobin/STAR) alignment - - [STAR-Fusion](https://github.com/STAR-Fusion/STAR-Fusion) fusion detection -7. Fusioncatcher subworkflow - - [FusionCatcher](https://github.com/ndaniel/fusioncatcher) fusion detection -8. StringTie subworkflow - - [StringTie](https://ccb.jhu.edu/software/stringtie/) -9. Fusion-report - - Merge all fusions detected by the selected tools with [Fusion-report](https://github.com/Clinical-Genomics/fusion-report) +2. Reads quality control ([FastQC](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/)) +3. Optional trimming with [fastp](https://github.com/OpenGene/fastp) +4. Align FASTQs to BAM with [STAR](https://github.com/alexdobin/STAR) +5. Run fusion detection with [Arriba](https://github.com/suhrig/arriba) +6. Run fusion detection with [STAR-Fusion](https://github.com/STAR-Fusion/STAR-Fusion) + 7a. Optional trimming of 3' end with [fastp](https://github.com/OpenGene/fastp) to feed into fusioncatcher (other tools not affected) + 7b. Run fusion detection with [FusionCatcher](https://github.com/ndaniel/fusioncatcher) +7. Run transcript assembly and quantification with [StringTie](https://ccb.jhu.edu/software/stringtie/) +8. Run cancer splicing aberrations detection with [CTAT-SPLICING](https://github.com/TrinityCTAT/CTAT-SPLICING) +9. Merge all fusions detected by the selected tools with [Fusion-report](https://github.com/Clinical-Genomics/fusion-report) 10. Post-processing and analysis of data - [FusionInspector](https://github.com/FusionInspector/FusionInspector) + - Summarize information into a VCF file - [Arriba](https://github.com/suhrig/arriba) visualisation - - Collect metrics ([`picard CollectRnaSeqMetrics`](https://gatk.broadinstitute.org/hc/en-us/articles/360037057492-CollectRnaSeqMetrics-Picard-), [`picard CollectInsertSizeMetrics`](https://gatk.broadinstitute.org/hc/en-us/articles/360037055772-CollectInsertSizeMetrics-Picard-) and ([`picard MarkDuplicates`](https://gatk.broadinstitute.org/hc/en-us/articles/360037052812-MarkDuplicates-Picard-)) + - Collect metrics ([`picard CollectRnaSeqMetrics`](https://gatk.broadinstitute.org/hc/en-us/articles/360037057492-CollectRnaSeqMetrics-Picard-)), [`picard CollectInsertSizeMetrics`](https://gatk.broadinstitute.org/hc/en-us/articles/360037055772-CollectInsertSizeMetrics-Picard-) and ([`GATK MarkDuplicates`](https://gatk.broadinstitute.org/hc/en-us/articles/360037052812-MarkDuplicates-Picard-)) 11. Present QC for raw reads ([`MultiQC`](http://multiqc.info/)) 12. Compress bam files to cram with [samtools view](http://www.htslib.org/) @@ -70,32 +82,17 @@ In rnafusion the full-sized test includes reference building and fusion detectio > [!NOTE] > If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data. -As the reference building is computationally heavy (> 24h on HPC), it is recommended to test the pipeline with the `-stub` parameter (creation of empty files): - -First, build the references: - -```bash -nextflow run nf-core/rnafusion \ - -profile \ - -profile test \ - --outdir \ - --build_references \ - -stub -``` - -Then perform the analysis: +As the reference building is computationally heavy (> 24h on HPC), we had to use dummy reference files in the test profile. Therefore, it is recommended to run the test profile with the `-stub` option. ```bash nextflow run nf-core/rnafusion \ - -profile \ - -profile test \ - --outdir \ + -profile test, \ + --outdir \ -stub ``` > [!WARNING] -> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; -> see [docs](https://nf-co.re/usage/configuration#custom-configuration-files). +> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files). > **Notes:** > @@ -116,12 +113,14 @@ For more details about the output files and reports, please refer to the nf-core/rnafusion was written by Martin Proks ([@matq007](https://github.com/matq007)), Maxime Garcia ([@maxulysse](https://github.com/maxulysse)) and Annick Renevey ([@rannick](https://github.com/rannick)) -We thank the following people for their help in the development of this pipeline: +## We thank the following people for their help in the development of this pipeline - [Phil Ewels](https://github.com/ewels) - [Rickard Hammarén](https://github.com/Hammarn) - [Alexander Peltzer](https://github.com/apeltzer) - [Praveen Raj](https://github.com/praveenraj2018) +- [Anabella Trigila](https://github.com/atrigila) +- [Nicolas Vannieuwkerke](https://github.com/nvnieuwk) ## Contributions and Support diff --git a/assets/dummy_file_arriba.txt b/assets/dummy_file_arriba.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/assets/dummy_file_fusioncatcher.txt b/assets/dummy_file_fusioncatcher.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/assets/dummy_file_pizzly.txt b/assets/dummy_file_pizzly.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/assets/dummy_file_squid.txt b/assets/dummy_file_squid.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/assets/dummy_file_starfusion.txt b/assets/dummy_file_starfusion.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/assets/multiqc_config.yml b/assets/multiqc_config.yml index fe0459889..73d0edd30 100644 --- a/assets/multiqc_config.yml +++ b/assets/multiqc_config.yml @@ -1,7 +1,8 @@ report_comment: > - This report has been generated by the nf-core/rnafusion - analysis pipeline. For information about how to interpret these results, please see the - documentation. + This report has been generated by the nf-core/rnafusion analysis pipeline. For information about how + to interpret these results, please see the documentation. report_section_order: nf-core-rnafusion-methods-description: diff --git a/assets/schema_input.json b/assets/schema_input.json index 12ec2cc8f..c0ff9aea6 100644 --- a/assets/schema_input.json +++ b/assets/schema_input.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://raw.githubusercontent.com/nf-core/rnafusion/master/assets/schema_input.json", "title": "nf-core/rnafusion pipeline - params.input schema", "description": "Schema for the file provided with params.input", @@ -10,31 +10,105 @@ "sample": { "type": "string", "pattern": "^\\S+$", - "errorMessage": "Sample name must be provided and cannot contain spaces", + "errorMessage": "Sample name must be provided, has to be a string and cannot contain spaces", "meta": ["id"] }, "fastq_1": { "type": "string", "format": "file-path", "exists": true, - "pattern": "^\\S+\\.f(ast)?q\\.gz$", + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", "errorMessage": "FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" }, "fastq_2": { "type": "string", "format": "file-path", "exists": true, - "pattern": "^\\S+\\.f(ast)?q\\.gz$", + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", "errorMessage": "FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" }, - "strandedness": { + "bam": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^\\S+\\.bam$", + "errorMessage": "BAM file cannot contain spaces, has to exist and must have extension '.bam'" + }, + "bai": { "type": "string", - "format": "string", + "format": "file-path", + "exists": true, + "pattern": "^\\S+\\.bam\\.bai$", + "errorMessage": "BAI file cannot contain spaces, has to exist and must have extension '.bam.bai'" + }, + "cram": { + "type": "string", + "format": "file-path", "exists": true, - "pattern": "forward|reverse|unstranded|unknown", - "errorMessage": "Strandedness has to be forward, reverse, unstranded or unknown" + "pattern": "^\\S+\\.cram$", + "errorMessage": "CRAM file cannot contain spaces, has to exist and must have extension '.cram'" + }, + "crai": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^\\S+\\.cram\\.crai$", + "errorMessage": "CRAI file cannot contain spaces, has to exist and must have extension '.cram.crai'" + }, + "junctions": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^\\S+\\.junction$", + "errorMessage": "Junctions file cannot contain spaces, has to exist and must have extension '.junction'" + }, + "splice_junctions": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^\\S+\\.SJ.out.tab$", + "errorMessage": "Split junctions file cannot contain spaces, has to exist and must have extension '.SJ.out.tab'" + }, + "strandedness": { + "type": "string", + "enum": ["forward", "reverse", "unstranded", "unknown"], + "errorMessage": "Strandedness has to be 'forward', 'reverse', 'unstranded' or 'unknown'" + }, + "seq_platform": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "Sequencing platform has to be a string and cannot contain spaces", + "meta": "seq_platform" + }, + "seq_center": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "Sequencing center has to be a string and cannot contain spaces", + "meta": "seq_center" } }, - "required": ["sample", "fastq_1", "fastq_2", "strandedness"] + "uniqueEntries": ["sample"], + "dependentRequired": { + "bai": ["bam"], + "crai": ["cram"] + }, + "required": ["sample", "strandedness"], + "anyOf": [ + { + "required": ["fastq_1", "fastq_2"] + }, + { + "required": ["bam"] + }, + { + "required": ["cram"] + }, + { + "required": ["junctions"] + }, + { + "required": ["splice_junctions"] + } + ] } } diff --git a/bin/get_rrna_transcripts.py b/bin/get_rrna_transcripts.py deleted file mode 100755 index 670d5f06c..000000000 --- a/bin/get_rrna_transcripts.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import logging -import sys -from pathlib import Path - - -def get_rrna_intervals(file_in, file_out): - """ - Get lines containing ``#`` or ``gene_type rRNA`` or ```` or ``gene_type rRNA_pseudogene`` or ``gene_type MT_rRNA`` - Create output file - - Args: - file_in (pathlib.Path): The given GTF file. - file_out (pathlib.Path): Where the ribosomal RNA GTF file should - be created; always in GTF format. - """ - - patterns = { - "#", - 'transcript_biotype "Mt_rRNA"', - 'transcript_biotype "rRNA"', - 'transcript_biotype "rRNA_pseudogene"', - } - line_starts = {"MT", "1", "2", "3", "4", "5", "6", "7", "8", "9"} - out_lines = [] - with file_in.open() as f: - data = f.readlines() - for line in data: - for pattern in patterns: - if pattern in line: - for line_start in line_starts: - if line.startswith(line_start): - out_lines.append(line) - - with file_out.open(mode="w") as out_file: - out_file.writelines(out_lines) - - -def parse_args(argv=None): - """Define and immediately parse command line arguments.""" - parser = argparse.ArgumentParser( - description="Extract ribosomal RNA intervals from a gtf file.", - epilog="Example: python get_rrna_transcripts.py ", - ) - parser.add_argument( - "file_in", - metavar="FILE_IN", - type=Path, - help="Input in GTF format.", - ) - parser.add_argument( - "file_out", - metavar="FILE_OUT", - type=Path, - help="Transformed output intervals in GTF format.", - ) - parser.add_argument( - "-l", - "--log-level", - help="The desired log level (default WARNING).", - choices=("CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"), - default="WARNING", - ) - return parser.parse_args(argv) - - -def main(argv=None): - """Coordinate argument parsing and program execution.""" - args = parse_args(argv) - logging.basicConfig(level=args.log_level, format="[%(levelname)s] %(message)s") - if not args.file_in.is_file(): - logger.error(f"The given input file {args.file_in} was not found!") - sys.exit(2) - args.file_out.parent.mkdir(parents=True, exist_ok=True) - get_rrna_intervals(args.file_in, args.file_out) - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/bin/vcf_collect.py b/bin/vcf_collect.py index 1decbe907..292c052fd 100755 --- a/bin/vcf_collect.py +++ b/bin/vcf_collect.py @@ -1,5 +1,12 @@ #!/usr/bin/env python3 +# Author: Annick Renevey, annick.renevey@scilifelab.se +# License: MIT +# +# This script is part of the rnafusion pipeline. +# For full license and authorship information, see the repository README. +# + import argparse import logging import sys @@ -89,21 +96,22 @@ def vcf_collect( | ((all_df["orig_start"] == 0) & (all_df["orig_end"] == 0)) ] + all_df["Left_transcript_version"] = all_df["CDS_LEFT_ID"].astype(str).str.split(".").str[-1] + all_df.replace("", np.nan, inplace=True) all_df = all_df.drop_duplicates() - all_df[["exon_number", "transcript_version"]] = all_df[ - ["exon_number", "transcript_version"] + all_df[["exon_number", "Left_transcript_version"]] = all_df[ + ["exon_number", "Left_transcript_version"] ].replace(0, np.nan) # Fill non-empty values within each group for 'exon_number' and 'transcript_version' all_df["exon_number"] = all_df.groupby("PosA")["exon_number"].transform( lambda x: x.fillna(method="ffill").fillna(method="bfill") ) - all_df["transcript_version"] = all_df.groupby("PosA")[ - "transcript_version" + all_df["Left_transcript_version"] = all_df.groupby("PosA")[ + "Left_transcript_version" ].transform(lambda x: x.fillna(method="ffill").fillna(method="bfill")) - all_df = all_df.rename(columns={"transcript_version": "Left_transcript_version"}) all_df = all_df.rename(columns={"exon_number": "Left_exon_number"}) all_df = all_df[ [ @@ -154,18 +162,20 @@ def vcf_collect( all_df[["PosA", "PosB"]] = all_df[["PosA", "PosB"]].replace(0, np.nan) all_df = all_df.replace("", np.nan) - all_df[["exon_number", "transcript_version"]] = all_df[ - ["exon_number", "transcript_version"] + all_df["Right_transcript_version"] = all_df["CDS_RIGHT_ID"].astype(str).str.split(".").str[-1] + + + all_df[["exon_number", "Right_transcript_version"]] = all_df[ + ["exon_number", "Right_transcript_version"] ].replace(0, np.nan) # Fill non-empty values within each group for 'exon_number' and 'transcript_version' all_df["exon_number"] = all_df.groupby("PosB")["exon_number"].transform( lambda x: x.fillna(method="ffill").fillna(method="bfill") ) - all_df["transcript_version"] = all_df.groupby("PosB")[ - "transcript_version" + all_df["Right_transcript_version"] = all_df.groupby("PosB")[ + "Right_transcript_version" ].transform(lambda x: x.fillna(method="ffill").fillna(method="bfill")) - all_df = all_df.rename(columns={"transcript_version": "Right_transcript_version"}) all_df = all_df.rename(columns={"exon_number": "Right_exon_number"}) all_df = all_df[ @@ -493,10 +503,10 @@ def column_manipulation(df: pd.DataFrame) -> pd.DataFrame: df["Left_exon_number"] = df["Left_exon_number"].fillna(0).astype(int).astype(str) df["Right_exon_number"] = df["Right_exon_number"].fillna(0).astype(int).astype(str) df["Left_transcript_version"] = ( - df["Left_transcript_version"].fillna(0).astype(int).astype(str) + pd.to_numeric(df["Left_transcript_version"], errors="coerce").fillna(0).astype(int).astype(str) ) df["Right_transcript_version"] = ( - df["Right_transcript_version"].fillna(0).astype(int).astype(str) + pd.to_numeric(df["Right_transcript_version"], errors="coerce").fillna(0).astype(int).astype(str) ) df["PosA"] = df["PosA"].fillna(0).astype(int).astype(str) df["PosB"] = df["PosB"].fillna(0).astype(int).astype(str) @@ -579,7 +589,7 @@ def build_gtf_dataframe(file: str) -> pd.DataFrame: "orig_coord_info" ].str.split(",", expand=True) return df[ - ["Transcript_id", "transcript_version", "exon_number", "orig_start", "orig_end"] + ["Transcript_id", "exon_number", "orig_start", "orig_end"] ] diff --git a/conf/base.config b/conf/base.config index 5b2e6f360..bdeb1ed3c 100644 --- a/conf/base.config +++ b/conf/base.config @@ -10,40 +10,45 @@ process { - cpus = { check_max( 1 * task.attempt, 'cpus' ) } - memory = { check_max( 6.GB * task.attempt, 'memory' ) } - time = { check_max( 4.h * task.attempt, 'time' ) } - shell = ['/bin/bash', '-euo', 'pipefail'] + cpus = { 1 * task.attempt } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } - errorStrategy = { task.exitStatus in ((130..145) + 104) ? 'retry' : 'finish' } + errorStrategy = { task.exitStatus in ((130..145) + 104 + 175) ? 'retry' : 'finish' } maxRetries = 1 maxErrors = '-1' + // Process-specific resource requirements + // NOTE - Please try and reuse the labels below as much as possible. + // These labels are used and recognised by default in DSL2 files hosted on nf-core/modules. + // If possible, it would be nice to keep the same label naming convention when + // adding in your local modules too. + // See https://www.nextflow.io/docs/latest/config.html#config-process-selectors withLabel:process_single { - cpus = { check_max( 1 , 'cpus' ) } - memory = { check_max( 6.GB * task.attempt, 'memory' ) } - time = { check_max( 4.h * task.attempt, 'time' ) } + cpus = { 1 } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } } withLabel:process_low { - cpus = { check_max( 2 * task.attempt, 'cpus' ) } - memory = { check_max( 12.GB * task.attempt, 'memory' ) } - time = { check_max( 4.h * task.attempt, 'time' ) } + cpus = { 2 * task.attempt } + memory = { 12.GB * task.attempt } + time = { 4.h * task.attempt } } withLabel:process_medium { - cpus = { check_max( 6 * task.attempt, 'cpus' ) } - memory = { check_max( 36.GB * task.attempt, 'memory' ) } - time = { check_max( 8.h * task.attempt, 'time' ) } + cpus = { 6 * task.attempt } + memory = { 36.GB * task.attempt } + time = { 8.h * task.attempt } } withLabel:process_high { - cpus = { check_max( 12 * task.attempt, 'cpus' ) } - memory = { check_max( 72.GB * task.attempt, 'memory' ) } - time = { check_max( 16.h * task.attempt, 'time' ) } + cpus = { 12 * task.attempt } + memory = { 72.GB * task.attempt } + time = { 16.h * task.attempt } } withLabel:process_long { - time = { check_max( 20.h * task.attempt, 'time' ) } + time = { 20.h * task.attempt } } withLabel:process_high_memory { - memory = { check_max( 200.GB * task.attempt, 'memory' ) } + memory = { 200.GB * task.attempt } } withLabel:error_ignore { errorStrategy = 'ignore' @@ -52,4 +57,8 @@ process { 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/genomes.config b/conf/genomes.config new file mode 100644 index 000000000..7a2a0ad99 --- /dev/null +++ b/conf/genomes.config @@ -0,0 +1,33 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for Rnafusion reference paths +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines reference genomes using paths. + Can be used by any config that customises the base path using: + $params.genomes_base / --genomes_base +---------------------------------------------------------------------------------------- +*/ + +params { + // rnafusion reference file paths + genomes { + 'GRCh38' { + fasta = "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/gencode/Homo_sapiens_GRCh38_${params.genome_gencode_version}_dna_primary_assembly.fa" + fai = "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/gencode/Homo_sapiens_GRCh38_${params.genome_gencode_version}_dna_primary_assembly.fa.fai" + gtf = "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/gencode/Homo_sapiens_GRCh38_${params.genome_gencode_version}.gtf" + refflat = "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/gencode/Homo_sapiens_GRCh38_${params.genome_gencode_version}.gtf.refflat" + rrna_intervals = "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/gencode/Homo_sapiens_GRCh38_${params.genome_gencode_version}.gtf.interval_list" + arriba_ref_blacklist = "${params.genomes_base}/GRCh38/arriba/2.5.0/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "${params.genomes_base}/GRCh38/arriba/2.5.0/cytobands_hg38_GRCh38_v2.5.0.tsv" + arriba_ref_known_fusions = "${params.genomes_base}/GRCh38/arriba/2.5.0/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_protein_domains = "${params.genomes_base}/GRCh38/arriba/2.5.0/protein_domains_hg38_GRCh38_v2.5.0.gff3" + fusioncatcher_ref = "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/fusioncatcher/" + hgnc_ref = "${params.genomes_base}/GRCh38/hgnc/hgnc_complete_set.txt" + hgnc_date = "${params.genomes_base}/GRCh38/hgnc/HGNC-DB-timestamp.txt" + salmon_index = "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/salmon" + starfusion_ref = "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/starfusion/ctat_genome_lib_build_dir" + starindex_ref = "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/star" + fusionreport_ref = "${params.genomes_base}/GRCh38/fusion_report_db" + } + } +} diff --git a/conf/genomes_ignored.config b/conf/genomes_ignored.config new file mode 100644 index 000000000..b4034d824 --- /dev/null +++ b/conf/genomes_ignored.config @@ -0,0 +1,9 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for iGenomes paths +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Empty genomes dictionary to use when igenomes is ignored. +---------------------------------------------------------------------------------------- +*/ + +params.genomes = [:] diff --git a/conf/modules.config b/conf/modules.config index 9d4ca62b1..e588e2b9a 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -18,7 +18,12 @@ process { saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] - withName: 'ARRIBA' { + + withName: 'AGAT_CONVERTGFF2BED' { + ext.args = '--nc filter' + } + + withName: 'ARRIBA_ARRIBA' { publishDir = [ path: { "${params.outdir}/arriba" }, mode: params.publish_dir_mode, @@ -27,39 +32,66 @@ process { ext.prefix = { "${meta.id}.arriba" } } - withName: 'ARRIBA_DOWNLOAD' { + withName: 'ARRIBA_VISUALISATION' { + ext.prefix = { "${meta.id}_combined_fusions_arriba_visualisation" } publishDir = [ - path: { "${params.genomes_base}/arriba" }, + path: { "${params.outdir}/arriba_visualisation" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } - withName: 'ARRIBA_VISUALISATION' { - ext.when = { !params.fusioninspector_only && (params.starfusion || params.all) } - ext.prefix = { "${meta.id}_combined_fusions_arriba_visualisation" } + withName: 'BIOAWK' { publishDir = [ - path: { "${params.outdir}/arriba_visualisation" }, + path: { "${params.outdir}/bioawk" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + ext.prefix = { "${meta.id}_rrna.gtf" } + ext.args = """-c gff '\$9 ~ /transcript_biotype "rRNA"/ || \$9 ~ /transcript_type "rRNA"/ || \$9 ~ /transcript_type "Mt_rRNA"/ || \$9 ~ /transcript_type "rRNA_pseudogene"/ || \$9 ~ /transcript_biotype "Mt_rRNA"/ || \$9 ~ /transcript_biotype "rRNA_pseudogene"/'""" + } + + withName: 'CTATSPLICING_STARTOCANCERINTRONS' { + ext.args = {[ + bam ? "--vis" : "", + "--sample_name ${meta.id}", + ].join(" ")} + publishDir = [ + path: { "${params.outdir}/ctatsplicing" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } - withName: 'ENSEMBL_DOWNLOAD' { + withName: 'GENCODE_DOWNLOAD' { publishDir = [ - path: { "${params.genomes_base}/ensembl" }, + path: { "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/gencode" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } withName: 'FASTP' { - ext.args = params.trim_tail ? "--trim_tail1 ${params.trim_tail} --trim_tail2 ${params.trim_tail} " : '' + ext.args = { params.trim_tail > 0 ? "--trim_tail1 ${params.trim_tail} --trim_tail2 ${params.trim_tail} " : '' } + publishDir = [ + path: { "${params.outdir}/fastp" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] } - withName: 'FASTQC' { + withName: 'FASTP_FOR_FUSIONCATCHER' { + ext.args = { params.trim_tail_fusioncatcher > 0 ? "--trim_tail1 ${params.trim_tail_fusioncatcher} --trim_tail2 ${params.trim_tail_fusioncatcher} " : '' } + ext.prefix = { "${meta.id}_trimmed_for_fusioncatcher" } + publishDir = [ + path: { "${params.outdir}/fastp_for_fusioncatcher" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + + withName: 'FASTQC_RAW' { ext.args = '--quiet' - ext.when = { !params.skip_qc } publishDir = [ path: { "${params.outdir}/fastqc" }, mode: params.publish_dir_mode, @@ -67,7 +99,7 @@ process { ] } - withName: 'FASTQC_FOR_FASTP' { + withName: 'FASTQC_TRIM' { ext.args = '--quiet' ext.prefix = { "${meta.id}_trimmed" } publishDir = [ @@ -77,27 +109,27 @@ process { ] } - withName: 'FUSIONCATCHER' { - ext.args = "--limitSjdbInsertNsj ${params.fusioncatcher_limitSjdbInsertNsj}" + withName: 'FUSIONCATCHER_FUSIONCATCHER' { + ext.args = {[ + "--limitSjdbInsertNsj ${params.fusioncatcher_limitSjdbInsertNsj}", + "--skip-blat", + meta.single_end ? "--single-end" : "", + ].join(' ')} } - withName: 'FUSIONCATCHER_DOWNLOAD' { + withName: 'FUSIONINSPECTOR' { + ext.args = { params.fusioninspector_limitSjdbInsertNsj != 1000000 ? "--STAR_xtra_params \"--limitSjdbInsertNsj ${params.fusioninspector_limitSjdbInsertNsj}\"" : '' } + ext.args2 = '--annotate --examine_coding_effect' publishDir = [ - path: { "${params.genomes_base}/fusioncatcher" }, + path: { "${params.outdir}/fusioninspector/${meta.id}" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } - withName: 'FUSIONINSPECTOR' { - ext.when = { !params.skip_vis } - ext.args = { params.fusioninspector_limitSjdbInsertNsj != 1000000 ? "--STAR_xtra_params \"--limitSjdbInsertNsj ${params.fusioninspector_limitSjdbInsertNsj}\"" : '' } - ext.args2 = '--annotate --examine_coding_effect' - } - - withName: 'FUSIONREPORT' { - ext.when = { !params.skip_vis } - ext.args = "--export csv" + withName: 'FUSIONREPORT_DETECT' { + ext.args = { params.no_cosmic ? "--no-cosmic" : "" } + ext.args2 = "--export csv" publishDir = [ path: { "${params.outdir}/fusionreport/${meta.id}" }, mode: params.publish_dir_mode, @@ -106,9 +138,9 @@ process { } withName: 'FUSIONREPORT_DOWNLOAD' { - ext.args = { params.qiagen ? "--qiagen" : "" } + ext.args = { params.no_cosmic ? "--no-cosmic" : params.qiagen ? "--qiagen --cosmic_usr ${params.cosmic_username} --cosmic_passwd ${params.cosmic_passwd}" : "--cosmic_usr ${params.cosmic_username} --cosmic_passwd ${params.cosmic_passwd}" } publishDir = [ - path: { "${params.genomes_base}/fusion_report_db" }, + path: { "${params.genomes_base}/GRCh38" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] @@ -116,221 +148,203 @@ process { withName: 'GATK4_BEDTOINTERVALLIST' { publishDir = [ - path: { "${params.genomes_base}/ensembl" }, + path: { "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/gencode" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } - withName: 'GTF_TO_REFFLAT' { + withName: 'GATK4_CREATESEQUENCEDICTIONARY' { publishDir = [ - path: { "${params.genomes_base}/ensembl" }, + path: { "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/gencode" }, mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } - withName: 'HGNC_DOWNLOAD' { + withName: 'GATK4_MARKDUPLICATES' { publishDir = [ - path: { "${params.genomes_base}/hgnc" }, + path: { "${params.outdir}/picard" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] } - withName: 'MULTIQC' { - ext.when = { !params.skip_qc } - ext.args = params.multiqc_title ? "--title \"$params.multiqc_title\"" : '' + withName: 'GFFREAD' { + ext.args = { '-w -S' } publishDir = [ - path: { "${params.outdir}/multiqc" }, + path: { "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/gencode" }, mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] } - withName: 'PICARD_COLLECTRNASEQMETRICS' { - ext.when = { !params.skip_qc && !params.fusioninspector_only && (params.starfusion || params.all) } - - } - - withName: 'GATK4_MARKDUPLICATES' { - ext.when = { !params.skip_qc && !params.fusioninspector_only && (params.starfusion || params.all) } + withName: 'UCSC_GTFTOGENEPRED' { + ext.args = '-genePredExt -geneNameAsName2 -ignoreGroupsWithoutExons' publishDir = [ - path: { "${params.outdir}/picard" }, + path: { "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/gencode" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] } - withName: 'PICARD_COLLECTINSERTSIZEMETRICS' { - ext.when = { !params.skip_qc && !params.fusioninspector_only && (params.starfusion || params.all) } - ext.prefix = { "${meta.id}_collectinsertsize"} + withName: 'HGNC_DOWNLOAD' { publishDir = [ - path: { "${params.outdir}/picard" }, + path: { "${params.genomes_base}/GRCh38/hgnc" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] } - withName: 'SAMPLESHEET_CHECK' { + withName: 'MULTIQC' { + ext.args = {params.multiqc_title ? "--title \"$params.multiqc_title\"" : ''} publishDir = [ - path: { "${params.outdir}/pipeline_info" }, + path: { "${params.outdir}/multiqc" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } - withName: 'SAMTOOLS_FAIDX' { + withName: 'PICARD_COLLECTINSERTSIZEMETRICS' { + ext.prefix = { "${meta.id}_collectinsertsize"} publishDir = [ - path: { "${params.genomes_base}/ensembl" }, + path: { "${params.outdir}/picard" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] } - withName: 'SAMTOOLS_INDEX_FOR_ARRIBA' { - ext.prefix = { "${meta.id}_star_for_arriba_sorted" } + + withName: 'PICARD_COLLECTRNASEQMETRICS' { + ext.args = { ( meta.strandedness == "forward" || meta.single_end ) ? + "--STRAND_SPECIFICITY FIRST_READ_TRANSCRIPTION_STRAND" : + meta.strandedness == "reverse" ? + "--STRAND_SPECIFICITY SECOND_READ_TRANSCRIPTION_STRAND" : + "--STRAND_SPECIFICITY NONE" + } publishDir = [ - path: { "${params.outdir}/cram_arriba" }, + path: { "${params.outdir}/picard" }, mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] } - withName: 'SAMTOOLS_SORT_FOR_ARRIBA' { - ext.prefix = { "${meta.id}_star_for_arriba_sorted" } + withName: 'SALMON_INDEX' { publishDir = [ - path: { "${params.outdir}/cram_arriba" }, + path: { "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}" }, mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] } - withName: 'SAMTOOLS_VIEW_FOR_ARRIBA' { - ext.args = { "--output-fmt cram" } - ext.prefix = { "${meta.id}_star_for_arriba_sorted" } + withName: 'SALMON_QUANT' { + ext.args = { [ + '--gcBias', + '--validateMappings' + ].join(' ') } publishDir = [ - path: { "${params.outdir}/cram_arriba" }, + path: { "${params.outdir}/salmon" }, mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] } - withName: 'SAMTOOLS_INDEX_FOR_STARFUSION' { + withName: 'SAMTOOLS_FAIDX' { publishDir = [ - path: { "${params.outdir}/star_for_starfusion" }, + path: { "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/gencode" }, mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] } - withName: 'SAMTOOLS_INDEX_FOR_STARFUSION_CRAM' { - ext.prefix = { "${meta.id}.star_for_starfusion.Aligned.sortedByCoord.out" } + withName: 'SAMTOOLS_CONVERT' { + ext.prefix = { "${meta.id}.Aligned.sortedByCoord.out" } publishDir = [ - path: { "${params.outdir}/cram_starfusion" }, + path: { "${params.outdir}/star" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } - withName: 'SAMTOOLS_VIEW_FOR_STARFUSION' { - ext.args = { "--output-fmt cram" } - ext.prefix = { "${meta.id}.star_for_starfusion.Aligned.sortedByCoord.out" } + withName: 'SAMTOOLS_INDEX' { publishDir = [ - path: { "${params.outdir}/cram_starfusion" }, + path: { "${params.outdir}/star" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } - withName: 'STAR_FOR_ARRIBA' { - publishDir = [ - path: { "${params.outdir}/star_for_arriba" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, - ] - ext.args = '--readFilesCommand zcat \ - --outSAMtype BAM Unsorted \ - --outSAMunmapped Within \ - --outBAMcompression 0 \ - --outFilterMultimapNmax 50 \ - --peOverlapNbasesMin 10 \ - --alignSplicedMateMapLminOverLmate 0.5 \ - --alignSJstitchMismatchNmax 5 -1 5 5 \ - --chimSegmentMin 10 \ - --chimOutType WithinBAM HardClip \ - --chimJunctionOverhangMin 10 \ - --chimScoreDropMax 30 \ - --chimScoreJunctionNonGTAG 0 \ - --chimScoreSeparation 1 \ - --chimSegmentReadGapMax 3 \ - --chimMultimapNmax 50' - } - - withName: 'STAR_FOR_STARFUSION' { + withName: SAMTOOLS_SORT { + ext.prefix = { "${meta.id}.Aligned.sortedByCoord" } + ext.args = { params.cram ? "--write-index --output-fmt cram" : "--write-index" } + } + + withName: 'STAR_ALIGN' { publishDir = [ - path: { "${params.outdir}/star_for_starfusion" }, + path: { "${params.outdir}/star" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] - ext.args = '--twopassMode Basic \ - --outReadsUnmapped None \ - --readFilesCommand zcat \ - --outSAMtype BAM SortedByCoordinate \ - --outSAMstrandField intronMotif \ - --outSAMunmapped Within \ - --chimSegmentMin 12 \ - --chimJunctionOverhangMin 8 \ - --chimOutJunctionFormat 1 \ - --alignSJDBoverhangMin 10 \ - --alignMatesGapMax 100000 \ - --alignIntronMax 100000 \ - --alignSJstitchMismatchNmax 5 -1 5 5 \ - --chimMultimapScoreRange 3 \ - --chimScoreJunctionNonGTAG -4 \ - --chimMultimapNmax 20 \ - --chimNonchimScoreDropMin 10 \ - --peOverlapNbasesMin 12 \ - --peOverlapMMp 0.1 \ - --alignInsertionFlush Right \ - --alignSplicedMateMapLminOverLmate 0 \ - --alignSplicedMateMapLmin 30 \ - --chimOutType Junctions \ - --quantMode GeneCounts' + ext.args = { [ + "--outReadsUnmapped None", + "--outSAMattrRGline 'ID:${meta.id}' 'SM:${meta.id}'${meta.seq_center ? " 'CN:${meta.seq_center}'": ''}${meta.seq_platform ? "' PL:${meta.seq_platform}'": ''}", + "--outSAMstrandField intronMotif", + "--chimOutJunctionFormat 1", + "--twopassMode None", + "--outFilterMultimapNmax 50", + "--chimMultimapNmax 50", + "--quantMode GeneCounts", + "--outSAMunmapped Within", + "--readFilesCommand zcat ", + "--alignSJstitchMismatchNmax 5 -1 5 5", + "--outSAMtype BAM SortedByCoordinate", + "--chimSegmentMin 10", + "--peOverlapNbasesMin 10", + "--alignSplicedMateMapLminOverLmate 0.5", + "--chimJunctionOverhangMin 10", + "--chimScoreJunctionNonGTAG 0", + "--chimScoreDropMax 30", + "--chimScoreSeparation 1 ", + "--chimSegmentReadGapMax 3", + "--chimOutType Junctions WithinBAM", + params.star_limit_bam_sort_ram > 0 ? "--limitBAMsortRAM ${params.star_limit_bam_sort_ram}" : "" + ].join(' ') } } withName: 'STAR_GENOMEGENERATE' { ext.args = "--sjdbOverhang ${params.read_length - 1}" - cpus = { check_max( 24 * task.attempt, 'cpus' ) } - memory = { check_max( 100.GB * task.attempt, 'memory' ) } - time = { check_max( 2.d * task.attempt, 'time' ) } + cpus = { 24 * task.attempt } + memory = { 100.GB * task.attempt } + time = { 2.d * task.attempt } publishDir = [ - path: { "${params.genomes_base}" }, + path: { "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] } withName: 'STARFUSION_BUILD' { - cpus = { check_max( 24 * task.attempt, 'cpus' ) } - memory = { check_max( 100.GB * task.attempt, 'memory' ) } - time = { check_max( 2.d * task.attempt, 'time' ) } + ext.args = { params.species.contains("homo_sapiens") ? "--human_gencode_filter": '' } + cpus = { 24 * task.attempt } + memory = { 150.GB * task.attempt } + time = { 2.d * task.attempt } + ext.prefix = "ctat" publishDir = [ - path: { "${params.genomes_base}/starfusion" }, + path: { "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/starfusion" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] } - withName: 'STARFUSION_DOWNLOAD' { - cpus = { check_max( 2 * task.attempt, 'cpus' ) } - memory = { check_max( 24.GB * task.attempt, 'memory' ) } - time = { check_max( 6.h * task.attempt, 'time' ) } + withName: 'CTATSPLICING_PREPGENOMELIB' { + cpus = { 1 * task.attempt } + memory = { 20.GB * task.attempt } publishDir = [ - path: { "${params.genomes_base}/starfusion" }, + path: { "${params.genomes_base}/GRCh38/gencode_v${params.genome_gencode_version}/starfusion" }, mode: params.publish_dir_mode, saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, ] + ext.args = "--max_readlength ${params.read_length} --human_gencode_filter" } withName: 'STRINGTIE_MERGE' { @@ -340,8 +354,4 @@ process { saveAs: { filename -> filename.equals('versions.yml') ? null : filename } ] } - - withName: 'VCF_COLLECT' { - ext.when = {!params.fusioninspector_only} - } } diff --git a/conf/test.config b/conf/test.config index 236d1a398..9cfdbf5de 100644 --- a/conf/test.config +++ b/conf/test.config @@ -14,11 +14,23 @@ params { config_profile_name = 'Test profile' config_profile_description = 'Minimal test dataset to check pipeline function' - // Limit resources so that this can run on GitHub Actions - max_cpus = 2 - max_memory = 6.GB - max_time = 6.h - // Input data - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' + input = "${projectDir}/tests/csv/fastq.csv" + tools = "all" + no_cosmic = true + genomes_base = "${params.outdir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created +} + +// Limit and standardize resources for github actions and reproducibility +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] } diff --git a/conf/test_build.config b/conf/test_build.config new file mode 100644 index 000000000..c1a7a9251 --- /dev/null +++ b/conf/test_build.config @@ -0,0 +1,69 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/rnafusion -profile test_build, --outdir + +---------------------------------------------------------------------------------------- +Uses a minimal fasta and gtf for testing purposes. +This test is designed to test the `build_references` subworkflow with the following processes on: +- SAMTOOLS_FAIDX +- HGNC_DOWNLOAD +- GATK4_CREATESEQUENCEDICTIONARY +- BIOAWK +- AGAT_CONVERTGFF2BED +- GATK4_BEDTOINTERVALLIST +- GTF_TO_REFFLAT +- GFFREAD +- STAR_GENOMEGENERATE +- STARFUSION_BUILD +- FUSIONREPORT_DOWNLOAD + +It does not test the following processes of the `build_references` subworkflow: +- GENCODE_DOWNLOAD +- FUSIONCATCHER_BUILD + +It does not test the main rnafusion subworkflows by setting references_only = true. +*/ + +params { + config_profile_name = 'Test build references profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Input data + references_only = true + input = "${projectDir}/tests/csv/fastq.csv" + genomes_base = "${params.outdir}/references" + no_cosmic = true + tools = "arriba,starfusion,fusionreport,salmon,fusioninspector" + fasta = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/minigenome.fa' + gtf = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/minigenome.gtf' + + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + species = 'homo_sapiens' + dfam_version = 3.4 + pfam_version = 37.4 + dfam_hmm = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/test_starfusion_dfam.hmm" + dfam_h3f = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/test_starfusion_dfam.hmm.h3f" + dfam_h3i = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/test_starfusion_dfam.hmm.h3i" + dfam_h3m = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/test_starfusion_dfam.hmm.h3m" + dfam_h3p = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/test_starfusion_dfam.hmm.h3p" + pfam_file = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/Pfam-A.hmm.gz" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + +} + +// Limit and standardize resources for github actions and reproducibility +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] +} diff --git a/conf/test_full.config b/conf/test_full.config index eb8f5cd69..e1ff7f4b1 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -14,7 +14,6 @@ params { // Input data for full size test input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' + tools = "all" - // Other params - - } +} diff --git a/docs/images/BTB_logo.svg b/docs/images/BTB_logo.svg index 099f1101f..fd3564060 100644 --- a/docs/images/BTB_logo.svg +++ b/docs/images/BTB_logo.svg @@ -181,4 +181,4 @@ d="m 249.627,285.3818 c 0,-2.5 -1.717,-4.271 -4.126,-4.271 -2.412,0 -4.13,1.771 -4.13,4.271 0,2.496 1.718,4.277 4.13,4.277 2.409,0 4.126,-1.781 4.126,-4.277" style="fill:#33b540;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path142" - inkscape:connector-curvature="0" /> \ No newline at end of file + inkscape:connector-curvature="0" /> diff --git a/docs/images/NGI_logo.svg b/docs/images/NGI_logo.svg index aef40fd81..0a880c573 100644 --- a/docs/images/NGI_logo.svg +++ b/docs/images/NGI_logo.svg @@ -330,4 +330,4 @@ d="M 76.914,107 H 97.133 V 98.797 H 76.914 Z" style="fill:#2e86ef;fill-opacity:1;fill-rule:evenodd;stroke:none" id="path170" - inkscape:connector-curvature="0" /> \ No newline at end of file + inkscape:connector-curvature="0" /> diff --git a/docs/images/SciLifeLab_logo.svg b/docs/images/SciLifeLab_logo.svg index b8a44b794..45d95b731 100644 --- a/docs/images/SciLifeLab_logo.svg +++ b/docs/images/SciLifeLab_logo.svg @@ -96,4 +96,4 @@ d="m 265.398,144.591 c 3.801,0 7,3.101 7,7.101 0,3.801 -3.199,6.899 -7,6.899 -3.898,0 -7,-3.098 -7,-6.899 0,-4 3.102,-7.101 7,-7.101 z" style="fill:#7fcb28;fill-opacity:1;fill-rule:evenodd;stroke:none" id="path34" - inkscape:connector-curvature="0" /> \ No newline at end of file + inkscape:connector-curvature="0" /> diff --git a/docs/images/mqc_fastqc_adapter.png b/docs/images/mqc_fastqc_adapter.png deleted file mode 100755 index 361d0e47a..000000000 Binary files a/docs/images/mqc_fastqc_adapter.png and /dev/null differ diff --git a/docs/images/mqc_fastqc_counts.png b/docs/images/mqc_fastqc_counts.png deleted file mode 100755 index cb39ebb80..000000000 Binary files a/docs/images/mqc_fastqc_counts.png and /dev/null differ diff --git a/docs/images/mqc_fastqc_quality.png b/docs/images/mqc_fastqc_quality.png deleted file mode 100755 index a4b89bf56..000000000 Binary files a/docs/images/mqc_fastqc_quality.png and /dev/null differ diff --git a/docs/images/nf-core-rnafusion_logo_dark_new.png b/docs/images/nf-core-rnafusion_logo_dark_new.png new file mode 100644 index 000000000..c79d6e1e1 Binary files /dev/null and b/docs/images/nf-core-rnafusion_logo_dark_new.png differ diff --git a/docs/images/nf-core-rnafusion_logo_light_new.png b/docs/images/nf-core-rnafusion_logo_light_new.png new file mode 100644 index 000000000..c705907e1 Binary files /dev/null and b/docs/images/nf-core-rnafusion_logo_light_new.png differ diff --git a/docs/images/nf-core-rnafusion_metro_map.png b/docs/images/nf-core-rnafusion_metro_map.png index 76b6bc3fd..d48e484b9 100644 Binary files a/docs/images/nf-core-rnafusion_metro_map.png and b/docs/images/nf-core-rnafusion_metro_map.png differ diff --git a/docs/images/nf-core-rnafusion_metro_map.svg b/docs/images/nf-core-rnafusion_metro_map.svg index 1cd7980f7..dfac1b6b5 100644 --- a/docs/images/nf-core-rnafusion_metro_map.svg +++ b/docs/images/nf-core-rnafusion_metro_map.svg @@ -26,16 +26,17 @@ inkscape:pagecheckerboard="0" inkscape:document-units="mm" showgrid="true" - inkscape:zoom="0.79542318" - inkscape:cx="538.70696" - inkscape:cy="330.01301" - inkscape:window-width="1366" - inkscape:window-height="1051" - inkscape:window-x="696" - inkscape:window-y="83" + inkscape:zoom="1.0167732" + inkscape:cx="187.35742" + inkscape:cy="358.97879" + inkscape:window-width="1904" + inkscape:window-height="1012" + inkscape:window-x="8" + inkscape:window-y="33" inkscape:window-maximized="0" inkscape:current-layer="layer1" - inkscape:snap-grids="false"> + inkscape:snap-grids="false" + showguides="false"> @@ -46,6 +47,11 @@ inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1"> + + transform="translate(-39.222983,0.557051)"> - - - - - - - - - - - - txt - + id="g49405"> + + + + + + + + + + + + + txt + + - - - - - - - - StringTie Arriba + x="97.913979" + y="64.78643">CTAT-Splicing - - - align fastpfastptrimming + x="44.034595" + y="79.588753" + id="tspan6319-3" /> FusionCatcher + x="99.272034" + y="82.737106">STAR-Fusion align + x="107.0855" + y="99.206078">Arriba - - + - - STAR-Fusion + y="99.785919" /> FastQC + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Maven Pro';-inkscape-font-specification:'Maven Pro Bold';text-align:center;text-anchor:middle;stroke-width:0.264583" + x="68.836182" + y="132.34033">fastptrimming MultiQC + x="192.49725" + y="45.24485">MultiQC FusionInspector + y="120.03577">FusionInspector fusion-report + x="181.46404" + y="90.574486">fusion-report Picard:Picard:- CollectRnaSeqMetrics- CollectWgsMetrics- CollectInsertSizeMetrics - + - - - - - - - fusioncatcher - starfusion - qc - - Workflows: - - - - arriba - stringtie - ArribaArribavisualisation VCFVCFcollect + STARalign + + + fastqc + + FusionCatcher + + + + diff --git a/docs/images/rnafusion_logo.svg b/docs/images/rnafusion_logo.svg index fcd196c81..ff3631448 100644 --- a/docs/images/rnafusion_logo.svg +++ b/docs/images/rnafusion_logo.svg @@ -205,4 +205,4 @@ d="m 300.43725,166.1155 -21.53224,21.61638 h 61.0915 V 166.1155 Z" id="path67" inkscape:connector-curvature="0" - style="fill:url(#f)" /> \ No newline at end of file + style="fill:url(#f)" /> diff --git a/docs/images/rnafusion_logo_new.svg b/docs/images/rnafusion_logo_new.svg new file mode 100644 index 000000000..6885517f7 --- /dev/null +++ b/docs/images/rnafusion_logo_new.svg @@ -0,0 +1,19439 @@ + + + + + + + + + + + diff --git a/docs/output.md b/docs/output.md index dede2c87b..3e3171e27 100644 --- a/docs/output.md +++ b/docs/output.md @@ -11,19 +11,20 @@ The directories listed below will be created in the results directory after the The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes data using the following steps: - [Download and build references](#references) - Build references needed to run the rest of the pipeline -- [STAR](#star) - Alignment for arriba, and STAR-fusion -- [Cat](#cat) - Concatenate fastq files per sample ID +- [STAR](#star) - Alignment of FASTQ files - [Arriba](#arriba) - Arriba fusion detection - [STAR-fusion](#starfusion) - STAR-fusion fusion detection - [StringTie](#stringtie) - StringTie assembly - [FusionCatcher](#fusioncatcher) - Fusion catcher fusion detection +- [CTAT-SPLICING](#ctat-splicing) - Detection and annotation of cancer splicing aberrations - [Samtools](#samtools) - SAM/BAM file manipulation -- [Fusion-report](#fusion-report) - Summary of the findings of each tool and comparison to COSMIC, Mitelman, FusionGBD and FusionGDB2 databases +- [Fusion-report](#fusion-report) - Summary of the findings of each tool and comparison to COSMIC, Mitelman, and FusionGDB2 databases - [FusionInspector](#fusionInspector) - Supervised analysis of fusion predictions from fusion-report, recover and re-score evidence for such predictions - [Arriba visualisation](#arriba-visualisation) - Arriba visualisation report for FusionInspector fusions - [Picard](#picard) - Collect QC metrics -- [FastQC](#fastqc) - Raw read quality control -- [MultiQC](#multiqc) - Aggregate reports describing QC results from the whole pipeline +- [FastQC](#fastqc) - Raw read QC +- [Salmon](#salmon) - Normalized gene expression calculation +- [MultiQC](#multiqc) - Aggregate report describing results and QC from the whole pipeline - [Pipeline information](#pipeline-information) - Report metrics generated during the workflow execution ## Download and build references @@ -33,29 +34,33 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d ### References directory structure -- `references/` - - `arriba` - - `blacklist_hg38_GRCh38_v2.1.0.tsv.gz` - - `protein_domains_hg38_GRCh38_v2.1.0.gff3` - - `cytobands_hg38_GRCh38_v2.1.0.tsv` - - `ensembl` - - `Homo_sapiens.GRCh38.{ensembl_version}.all.fa` - - `Homo_sapiens.GRCh38.{ensembl_version}.cdna.all.fa.gz` - - `Homo_sapiens.GRCh38.{ensembl_version}.gtf` - - `Homo_sapiens.GRCh38.{ensembl_version}.chr.gtf` - - `Homo_sapiens.GRCh38.{ensembl_version}.chr.gtf.refflat` - - `Homo_sapiens.GRCh38.{ensembl_version}.interval_list` - - `fusioncatcher` - - `human_v` - dir with all references for fusioncatcher - - `fusion_report_db` - - `cosmic.db` - - `fusiongdb.db` - - `fusiongdb2.db` - - `mitelman.db` - - `star` - dir with STAR index - - `starfusion` - - files and dirs used to build the index - - `ctat_genome_lib_build_dir` - dir containing the index +- `/` + - `/` + - `arriba/` + - `blacklist_hg38_GRCh38_v.tsv.gz` + - `cytobands_hg38_GRCh38_v.tsv` + - `known_fusions_hg38_GRCh38_v.tsv.gz` + - `protein_domains_hg38_GRCh38_v.gff3` + - `fusion_report_db/` + - `cosmic.db` + - `fusiongdb2.db` + - `mitelman.db` + - `gencode_v/` + - `fusioncatcher/` + - `gencode/` + - `Homo_sapiens.GRCh38..all.fa` + - `Homo_sapiens.GRCh38..cdna.all.fa.gz` + - `Homo_sapiens.GRCh38..gtf` + - `Homo_sapiens.GRCh38..chr.gtf` + - `Homo_sapiens.GRCh38..chr.gtf.refflat` + - `Homo_sapiens.GRCh38..interval_list` + - `salmon/` + - `star/` + - `starfusion/` + - `ctat_genome_lib_build_dir/` + - `hgnc/` + - `hgnc_complete_set.txt` + - `HGNC-DB-timestamp.txt` (Only files or folders used by the pipeline are mentioned explicitly.) @@ -69,30 +74,41 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d ```text {outdir} +├── agat ├── arriba ├── arriba_visualisation -├── cram_arriba -├── cram_starfusion +├── ctatsplicing ├── fastp ├── fastqc +├── fastqc_for_fastp ├── fusioncatcher ├── fusioninspector ├── fusionreport -├── kallisto_quant -├── megafusion ├── multiqc ├── picard ├── pipeline_info -├── samtools_sort_for_arriba -├── star_for_arriba -├── star_for_starfusion +├── salmon +├── star ├── starfusion -└── work +├── stringtie +└── vcf .nextflow.log ``` If no parameters are specified, the default is applied. +### Agat + +[Agat](https://github.com/NBISweden/AGAT) is to convert the GFF file to a TSV file, which is then used in the VCF creation. + +
+Output files + +- `agat/` + - `.tsv` + +
+ ### Arriba [Arriba](https://arriba.readthedocs.io/en/latest/) is used for i) detect gene fusions and ii) create a PDF report for the fusions found (visualisation): @@ -120,22 +136,35 @@ If no parameters are specified, the default is applied. The visualisation displays the fusions that fusioninspector outputs. That means that fusions from all callers are aggregated (by fusion-report) and then analyzed through fusioninspector (Note: Fusioninspecor contains a filtering step!). -### Cat +### CTAT-SPLICING + +If `--tools ctatsplicing` is present, [CTAT-SPLICING](https://github.com/TrinityCTAT/CTAT-SPLICING) will detect cancer splicing aberrations.
Output files -- `cat/` - - `_1.merged.fastq.gz` - - `_2.merged.fastq.gz` +- `ctatsplicing/` + - `.cancer_intron_reads.sorted.bam` + - `.cancer_intron_reads.sorted.bam.bai` + - `.cancer.introns` + - `.cancer.introns.prelim` + - `.chckpts` + - `.ctat-splicing.igv.html` + - `.gene_reads.sorted.sifted.bam` + - `.gene_reads.sorted.sifted.bam.bai` + - `.igv.tracks` + - `.introns` + - `.introns.for_IGV.bed`
-If multiple libraries or runs have been provided for the same sample in the input samplesheet (e.g. to increase sequencing depth) then these will be merged at the very beginning of the pipeline in order to have consistent sample naming throughout the pipeline. Please refer to the [usage](https://nf-co.re/rnafusion/usage#samplesheet-input) documentation to see how to specify these samples in the input samplesheet. +[CTAT-SPLICING](https://github.com/TrinityCTAT/CTAT-SPLICING/wiki) detects and annotates of aberrant splicing isoforms in cancer. This is run on the input files for `arriba` and/or `starfusion`. ### Fastp -If `--trim_fastp` is selected, [fastp](https://github.com/OpenGene/fastp) will filter low quality reads as well as bases at the 5' and 3' ends, trim adapters (automatically detected, but input with parameter `--adapter_fasta` is possible). 3' trimming is also possible via parameter `--trim_tail`. +If `--tools fastp` is present, [fastp](https://github.com/OpenGene/fastp) will filter low quality reads as well as bases at the 5' and 3' ends, trim adapters (automatically detected, but input with parameter `--adapter_fasta` is possible). 3' trimming is also possible via parameter `--trim_tail`. + +As fusioncatcher is especially sensitive to read length, 100 bp being the recommended length, an additional parameter `--trim_tail_fusioncatcher` triggers an extra fastp process with 3' trimming of the length given, these triggered reads are then fed to fusioncatcher but the non-extra trimmed ones are still used for arriba and STAR-Fusion.
Output files @@ -149,6 +178,22 @@ If `--trim_fastp` is selected, [fastp](https://github.com/OpenGene/fastp) will f
+### Fastp for fusioncatcher + +If `trim_tail_fusioncatcher` has any value other than 0, [fastp](https://github.com/OpenGene/fastp) will be run again as above. This allows for additional trimming of read tails before running FusionCatcher. For example if reads are 150bp, using `--trim_tail_fusioncatcher 50` will shorten reads to 100 bp by 50 bases from the 3′ end. 100 bp is the recommended read length to feed into FusionCatcher. The default for `--trim_tail_fusioncatcher` is 0 (no trimming). + +
+Output files + +- `fastp/` + - `_trimmed_for_fusioncatcher_1.fastp.fastq.gz` + - `_trimmed_for_fusioncatcher_2.fastp.fastq.gz` + - `_trimmed_for_fusioncatcher.fastp.html` + - `_trimmed_for_fusioncatcher.fastp.json` + - `_trimmed_for_fusioncatcher.fastp.log` + +
+ ### FastQC
@@ -162,15 +207,18 @@ If `--trim_fastp` is selected, [fastp](https://github.com/OpenGene/fastp) will f [FastQC](http://www.bioinformatics.babraham.ac.uk/projects/fastqc/) gives general quality metrics about your sequenced reads. It provides information about the quality score distribution across your reads, per base sequence content (%A/T/G/C), adapter contamination and overrepresented sequences. For further reading and documentation see the [FastQC help pages](http://www.bioinformatics.babraham.ac.uk/projects/fastqc/Help/). -![MultiQC - FastQC sequence counts plot](images/mqc_fastqc_counts.png) +### FastQC for fastp -![MultiQC - FastQC mean quality scores plot](images/mqc_fastqc_quality.png) +
+Output files -![MultiQC - FastQC adapter content plot](images/mqc_fastqc_adapter.png) +- `fastqc_for_fastp/` + - `*.html`: FastQC report containing quality metrics. + - `*.zip`: Zip archive containing the FastQC report, tab-delimited data file and plot images. -:::note -The FastQC plots displayed in the MultiQC report shows _untrimmed_ reads. They may contain adapter sequence and potentially regions with low quality. -::: +
+ +This directory contains FastQC reports for the fastp trimmed reads. ### FusionCatcher @@ -178,9 +226,9 @@ The FastQC plots displayed in the MultiQC report shows _untrimmed_ reads. They m Output files - `fusioncatcher` - - `.fusioncatcher.fusion-genes.txt` - - `.fusioncatcher.summary.txt` - - `.fusioncatcher.log` + - `.fusion-genes.txt` + - `.summary.txt` + - `.log`
@@ -192,9 +240,14 @@ The FastQC plots displayed in the MultiQC report shows _untrimmed_ reads. They m Output files - `fusioninspector` - - `.fusion_inspector_web.html` - visualisation report described in details [here](https://github.com/FusionInspector/FusionInspector/wiki/FusionInspector-Visualizations) - - `FusionInspector.log` - - `.FusionInspector.fusions.abridged.tsv` + - `/` + - `chckpts_dir/` - contains checkpoints for FusionInspector + - `fi_workdir/` - The working directory for FusionInspector + - `FusionInspector.log` + - `IGV_inputs/` - contains IGV input files + - `.FusionInspector.fusions.abridged.tsv` + - `.FusionInspector.fusions.tsv` + - `.fusion_inspector_web.html` - visualisation report described in details [here](https://github.com/FusionInspector/FusionInspector/wiki/FusionInspector-Visualizations) @@ -209,16 +262,17 @@ Please note that fusion-report is executed from fork https://github.com/Clinical - `fusionreport` - - - `.fusionreport.tsv` - `.fusionreport_filtered.tsv` - `_fusionreport_index.html` - general report for all filtered fusions + - `.fusionreport.tsv` - `.fusions.csv` - index in csv format + - `.fusions.json` - index in json format - `_.html` - specific report for each filtered fusion [Fusion-report](https://github.com/matq007/fusion-report) is a tool for parsing outputs from fusion detection tools. -The score is explained here: . Summary: +The Fusion Indication Index is explained here: . Summary: The weights for databases are as follows: @@ -226,39 +280,17 @@ The weights for databases are as follows: - MITELMAN (50) - FusionGDB2 (0) -The final formula for calculating score is: - -$$ -score = 0.5 * \sum_{tool}^{tools} f(fusion, tool)*w(tool) + 0.5 * \sum_{db}^{dbs} g(fusion, db)*w(db) -$$ +The Fusion Indication Index FII is calculated using two components: -All tools have the same weight. +1. Tool Detection (50% of total FII) + - Calculated as: (number of tools detecting the fusion) / (number of tools actually used) + - This reflects how many of the active tools found the fusion -### Kallisto +2. Database Hits (50% of total FII) + - Based on database matches using weights above + - Calculated as: (number of database hits) / (total possible database hits) -
-Output files - -- `kallisto` - - `.kallisto_quant.fusions.txt` - -
- -Quantifying abundances of transcripts from bulk and single-cell RNA-Seq data, or more generally of target sequences using high-throughput sequencing reads. - -### Vcf_collect - -
-Output files - -- `vcf_collect` - - `_fusion_data.vcf` - contains the fusions in vcf format with collected statistics. - -Vcf-collect takes as input the results of fusion-report and fusioninspector. That means fusions from all tools are aggregated. Fusioninspector applies a filter so it is possible some fusions detected by a caller are not filtered out by fusioninspector. In those cases, vcf-collect will display the fusions, but a lot of data will be missing as fusioninspector performs the analysis for each fusion. - -
- -[Megafusion](https://github.com/J35P312/MegaFusion) converts RNA fusion files to SV VCF and collects statistics and metrics in a VCF file. +Final score = (0.5 × Tool Detection Score) + (0.5 × Database Hits Score) ### MultiQC @@ -291,112 +323,58 @@ Picard CollectRnaMetrics and picard MarkDuplicates share the same output directo -### Samtools - -#### Samtools sort - -Samtools sort is used to sort BAM files from STAR_FOR_STARFUSION (for arriba visualisation) +### Pipeline information
Output files -- `samtools_sort_for_` - - `(_chimeric)_sorted.bam` - sorted BAM file +- `pipeline_info/` + - Reports generated by Nextflow: `execution_report_.html`, `execution_timeline_.html`, `execution_trace_.txt`, `pipeline_dag_.dot`/`pipeline_dag_.svg` and `manifest_.bco.json`. + - 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. + - Parameters used by the pipeline run: `params_.json`.
-#### Samtools index +[Nextflow](https://www.nextflow.io/docs/latest/tracing.html) provides excellent functionality for generating various reports relevant to the running and execution of the pipeline. This will allow you to troubleshoot errors with the running of the pipeline, and also provide you with other information such as launch commands, run times and resource usage. -Samtools index is used to index BAM files from STAR_FOR_ARRIBA (for arriba visualisation) and STAR_FOR_STARFUSION (for QC) +### Salmon
Output files -- `samtools_for_` - - `.(Aligned.sortedByCoord).out.bam.bai` - +- `salmon` + - ``
-### STAR +Folder containing the quantification results -STAR is used to align to genome reference - -STAR is run for 3 tools: - -For `arriba` with the parameters: - -```bash ---readFilesCommand zcat \ ---outSAMtype BAM Unsorted \ ---outSAMunmapped Within \ ---outBAMcompression 0 \ ---outFilterMultimapNmax 50 \ ---peOverlapNbasesMin 10 \ ---alignSplicedMateMapLminOverLmate 0.5 \ ---alignSJstitchMismatchNmax 5 -1 5 5 \ ---chimSegmentMin 10 \ ---chimOutType WithinBAM HardClip \ ---chimJunctionOverhangMin 10 \ ---chimScoreDropMax 30 \ ---chimScoreJunctionNonGTAG 0 \ ---chimScoreSeparation 1 \ ---chimSegmentReadGapMax 3 \ ---chimMultimapNmax 50 -``` +### STAR -For `STAR-fusion` with the parameters: - -```bash ---twopassMode Basic \ ---outReadsUnmapped None \ ---readFilesCommand zcat \ ---outSAMstrandField intronMotif \ ---outSAMunmapped Within \ ---chimSegmentMin 12 \ ---chimJunctionOverhangMin 8 \ ---chimOutJunctionFormat 1 \ ---alignSJDBoverhangMin 10 \ ---alignMatesGapMax 100000 \ ---alignIntronMax 100000 \ ---alignSJstitchMismatchNmax 5 -1 5 5 \ ---chimMultimapScoreRange 3 \ ---chimScoreJunctionNonGTAG -4 \ ---chimMultimapNmax 20 \ ---chimNonchimScoreDropMin 10 \ ---peOverlapNbasesMin 12 \ ---peOverlapMMp 0.1 \ ---alignInsertionFlush Right \ ---alignSplicedMateMapLminOverLmate 0 \ ---alignSplicedMateMapLmin 30 \ ---chimOutType Junctions \ ---quantMode GeneCounts -``` +STAR is used to align FASTQ files to the genome reference. -> STAR_FOR_STARFUSION uses `${params.ensembl}/Homo_sapiens.GRCh38.${params.ensembl_version}.chr.gtf` whereas STAR_FOR_ARRIBA uses `${params.ensembl_ref}/Homo_sapiens.GRCh38.${params.ensembl_version}.gtf` +Additionally, CRAM files can also be created when passing the `--cram` option. The CRAM conversion is done with a combination of `samtools view` and `samtools index`.
Output files **Common** -- `star_for_` -- `.Log.final.out` -- `.Log.progress.out` -- `.SJ.out.tab` - -**For arriba:** - -- `.Aligned.out.bam` - - **For starfusion:** - -- `.Aligned.sortedByCoord.out.bam` -- `.Chimeric.out.junction` -- `.ReadsPerGene.out.tab` +- `star` + - `.Aligned.sortedByCoord.out.bam` + - `.Aligned.sortedByCoord.out.bam.bai` + - `.Aligned.sortedByCoord.out.cram` - when `--cram` is used + - `.Aligned.sortedByCoord.out.cram.crai` - when `--cram` is used + - `.Chimeric.out.junction` + - `.Log.final.out` + - `.Log.out` + - `.Log.progress.out` + - `.ReadsPerGene.out.tab` + - `.SJ.out.tab`
-The STAR index is generated with `--sjdbOverhang ${params.read_length - 1}`, params.read_length default is 100. +The STAR index is generated with `--sjdbOverhang ${params.read_length - 1}`, `params.read_length` default is 100. ### STAR-fusion @@ -406,7 +384,6 @@ The STAR index is generated with `--sjdbOverhang ${params.read_length - 1}`, par - `starfusion` - `.starfusion.fusion_predictions.tsv` - contains the identified fusions - `.starfusion.abridged.tsv` - contains the identified fusions abridged - - `starfusion.abridged.coding_effect.tsv` @@ -418,17 +395,14 @@ The STAR index is generated with `--sjdbOverhang ${params.read_length - 1}`, par - `stringtie//stringtie.merged.gtf` - merged gtf from annotation and stringtie output gtfs -### Pipeline information +### Vcf_collect
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`. +- `vcf` + - `_fusion_data.vcf` - contains the fusions in vcf format with collected statistics. -
+Vcf-collect takes as input the results of fusion-report and fusioninspector. That means fusions from all tools are aggregated. Fusioninspector applies a filter so it is possible some fusions detected by a caller are not filtered out by fusioninspector. In those cases, vcf-collect will display the fusions, but a lot of data will be missing as fusioninspector performs the analysis for each fusion. -[Nextflow](https://www.nextflow.io/docs/latest/tracing.html) provides excellent functionality for generating various reports relevant to the running and execution of the pipeline. This will allow you to troubleshoot errors with the running of the pipeline, and also provide you with other information such as launch commands, run times and resource usage. + diff --git a/docs/usage.md b/docs/usage.md index fe370b363..0ce3485be 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -10,13 +10,12 @@ The pipeline is divided into two parts: 1. Download and build references -- specified with `--build_references` parameter -- required only once before running the pipeline -- **Important**: has to be run with each new release +- [Download](#download-and-build-references) the references from the S3 bucket (recommended) or build them with the pipeline +- **Important**: has to be done with each new release -2. Detecting fusions +2. Running the analysis -- Supported tools: `Arriba`, `FusionCatcher`, `STAR-Fusion`, and `StringTie` +- Supported tools: `Arriba`, `FusionCatcher`, `STAR-Fusion`, `StringTie` and `CTAT-SPLICING` (the last two are not supported by fusion-report and `StringTie` can be seen as more of an assembly tool that requires manual investigation). - QC: `Fastqc`, `MultiQC`, and `Picard CollectInsertSize`, `Picard CollectWgsMetrics`, `Picard Markduplicates` - Fusions visualization: `Arriba`, `fusion-report`, `FusionInspector`, and `vcf_collect` @@ -24,30 +23,48 @@ The pipeline is divided into two parts: The rnafusion pipeline needs references for the fusion detection tools, so downloading these is a **requirement**. -> **IMPORTANT** -> -> - Note that this step takes about 24 hours to complete on HPC. -> - Do not provide a samplesheet via the `input` parameter, otherwise the pipeline will run the analysis directly after downloading the references (except if that is what you want). +The references for the pipeline can be downloaded from the nf-core AWS megatests S3 bucket using the following command for the [AWS CLI tool](https://github.com/aws/aws-cli): + +```bash +aws --no-sign-request s3 sync s3://nf-core-awsmegatests/rnafusion/references/ +``` + +The path to the downloaded references can then be provided to the pipeline with the `--genomes_base` parameter. + +> [!WARNING] +> Please note that the references are large and can take a long time to download, so it is recommended to download them once and use them for all future runs of the pipeline. + +The fusion report references available on the S3 bucket do not contain information from cosmic due to licensing issues. If you want to use the cosmic database, you will need to build the fusion report references yourself by either deleting the `fusion_report_db` folder in the references directory or by specifying a different location for the fusion report directory with `--fusionreport_ref `. The cosmic username and password should also be given in this case using `--cosmic_username ` and `--cosmic_passwd `. + +Additionally, the references can be built by the pipeline using the following command: ```bash nextflow run nf-core/rnafusion \ - --build_references --all \ + -profile \ + --references_only --tools all \ --cosmic_username --cosmic_passwd \ --genomes_base \ --outdir ``` +> **IMPORTANT** +> +> - Note that this step takes about 24 hours to complete on HPC. + References for each tools can also be downloaded separately with: ```bash nextflow run nf-core/rnafusion \ - --build_references -- -- ... \ + -profile \ + --references_only --tools \ --cosmic_username --cosmic_passwd \ --genomes_base \ --outdir ``` -### Downloading the cosmic database with SANGER or QUIAGEN +If you are not covered by the research COSMIC license and want to avoid using COSMIC, you can provide the additional option `--no_cosmic`. + +### Downloading the cosmic database with SANGER or QIAGEN #### For academic users @@ -59,25 +76,23 @@ Use credentials from QIAGEN and add `--qiagen` ```bash nextflow run nf-core/rnafusion \ - --build_references -- -- ... \ + -profile \ + --references_only --tools \ --cosmic_username --cosmic_passwd \ --genomes_base \ --outdir --qiagen ``` -#### STAR-Fusion references downloaded vs built - -By default STAR-Fusion references are **built**. You can also download them from [CTAT](https://github.com/NCIP/Trinity_CTAT/wiki) by using the flag `--starfusion_build FALSE` for both reference building and fusion detection. This allows more flexibility for different organisms but **be aware that STAR-Fusion reference download is not recommended as not fully tested!** - #### Issues with building references If process `FUSIONREPORT_DOWNLOAD` times out, it could be due to network restriction (for example if trying to run on HPC). As this process is lightweight in cpu, memory and time, running on local machines with the following options might solve the issue: ```bash nextflow run nf-core/rnafusion \ - --build_references \ + -profile \ + --references_only \ --cosmic_username --cosmic_passwd \ - --fusionreport \ + --tools fusionreport \ --genomes_base \ --outdir ``` @@ -87,14 +102,14 @@ Where the custom configuration could look like (adaptation to local machine nece ```text process { - withName: 'NFCORE_RNAFUSION:BUILD_REFERENCES:FUSIONREPORT_DOWNLOAD' { + withName: 'NFCORE_RNAFUSION:RNAFUSION:BUILD_REFERENCES:FUSIONREPORT_DOWNLOAD' { memory = '8.GB' cpus = 4 } } ``` -The four `fusion-report` files: `cosmic.db`, `fusiongdb.db`, `fusiongdb2.db`, `mitelman.db` +The four `fusion-report` files: `cosmic.db`, `fusiongdb2.db`, `mitelman.db` should then be copied into the HPC `/references/fusion_report_db`. #### Note about fusioncatcher references @@ -105,8 +120,11 @@ The references are only built based on ensembl version 102. It is not possible c ### Samplesheet input -You will need to create a samplesheet with information about the samples you would like to analyse before running the pipeline. The pipeline will detect whether a sample is single- or paired-end from the samplesheet - the `fastq_2` column is empty for single-end. The samplesheet has to be a comma-separated file (.csv) but can have as many columns as you desire. There is a strict requirement for the first 4 columns to match those defined in the table below with the header row included. -A final 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. +You will need to create a samplesheet with information about the samples you would like to analyse before running the pipeline. The pipeline will detect whether a sample is single- or paired-end from the samplesheet - the `fastq_2` column is empty for single-end. + +The samplesheet has to be a comma-separated (.csv), tab-separated (.tsv), yaml (.yaml or .yml) or json (.json) file but can have as many entries as you desire. There is a strict requirement for the `sample` and `strandedness` fields. One or more of these fields should be provided too: `fastq_1`, `bam`, `cram`, `junctions` and `splice_junctions` + +A final samplesheet file consisting of both single- and paired-end data may look something like the one below: ```csv title="samplesheet.csv" sample,fastq_1,fastq_2,strandedness @@ -116,43 +134,93 @@ CONTROL_REP3,AEG588A3_S3_L002_R1_001.fastq.gz,AEG588A3_S3_L002_R2_001.fastq.gz,f TREATMENT_REP1,AEG588A4_S4_L003_R1_001.fastq.gz,,forward TREATMENT_REP2,AEG588A5_S5_L003_R1_001.fastq.gz,,forward TREATMENT_REP3,AEG588A6_S6_L003_R1_001.fastq.gz,,forward -TREATMENT_REP3,AEG588A6_S6_L004_R1_001.fastq.gz,,forward ``` -As you can see above for multiple runs of the same sample, the `sample` name has 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. +| Column | Description | Required | +| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| `sample` | Custom sample name. This value needs to be unique across all entries in the samplesheet and cannot contain spaces | ✅ | +| `strandedness` | Strandedness: forward or reverse. | ✅ | +| `fastq_1` | Full path to FastQ file for Illumina short reads 1. File must exist, has to be gzipped and have the extension ".fastq.gz" or ".fq.gz". It's recommended to always provide the FASTQ files because the pipeline will be able to create any missing files from these. The FASTQ files are required to run `salmon`, `fusioninspector` and `fusioncatcher`. | ❓ | +| `fastq_2` | Full path to FastQ file for Illumina short reads 2. File must exist, has to be gzipped and have the extension ".fastq.gz" or ".fq.gz". It's recommended to always provide the FASTQ files because the pipeline will be able to create any missing files from these. The FASTQ files are required to run `salmon`, `fusioninspector` and `fusioncatcher`". | ❓ | +| `bam` | Full path to the BAM file created with STAR. File has to exist and must have the extension ".bam". It's the responsibility of the pipeline user to make sure this file has been correctly created, see the [prepare chapter](#preparing-bamcramjunctionssplice_junctions) for more information. The BAM file is required to run `ctatsplicing`, `stringtie`, `fusioninspector` and `arriba` when the `fastq_1` and `cram` fields are empty. | ❓ | +| `bai` | Full path to the index of the BAM file. File has to exist and must have the extension ".bai". | ❌ | +| `cram` | Full path to the CRAM file created with STAR. File has to exist and must have the extension ".cram". It's the responsibility of the pipeline user to make sure this file has been correctly created, see the [prepare chapter](#preparing-bamcramjunctionssplice_junctions) for more information. The CRAM file is required to run `ctatsplicing`, `stringtie`, `fusioninspector` and `arriba` when the `fastq_1` and `bam` fields are empty. | ❓ | +| `crai` | Full path to the index of the CRAM file. File has to exist and must have the extension ".crai". | ❌ | +| `junctions` | Full path to the file containing chimeric junctions determined by STAR. File has to exist and must have the extension ".junction". It's the responsibility of the pipeline user to make sure this file has been correctly created, see the [prepare chapter](#preparing-bamcramjunctionssplice_junctions) for more information. The junctions file is required to run `starfusion` and `ctatsplicing` when the `fastq_1` field is empty. | ❓ | +| `splice_junctions` | Full path to the file containing splice junctions determined by STAR. File has to exist and must have the extension ".SJ.out.tab". It's the responsibility of the pipeline user to make sure this file has been correctly created, see the [prepare chapter](#preparing-bamcramjunctionssplice_junctions) for more information. The splice junctions file is required to run `ctatsplicing` when the `fastq_1` field is empty. | ❓ | +| `seq_platform` | The sequencing platform used to create to sequence the data in the FASTQ files. This value will take precedence over the value provided with `--seq_platform`. | ❌ | +| `seq_center` | The sequencing center in which the data in the FASTQ files was sequenced. This value will take precedence over the value provided with `--seq_center`. | ❌ | + +- ✅ = Required +- ❌ = Not required +- ❓ = One of these columns should be provided + +### Preparing BAM/CRAM/junctions/splice_junctions + +In the pipeline the following STAR command is used to produce the needed files: + +```bash +STAR \\ + --genomeDir \ + --readFilesIn \ + --runThreadN \ + --outFileNamePrefix . \ + --outSAMattrRGline 'ID:' 'SM:' \ + --outReadsUnmapped None \ + --outSAMstrandField intronMotif \ + --chimOutJunctionFormat 1 \ + --twopassMode None \ + --outFilterMultimapNmax 50 \ + --chimMultimapNmax 50 \ + --quantMode GeneCounts \ + --outSAMunmapped Within \ + --readFilesCommand zcat \ + --alignSJstitchMismatchNmax 5 -1 5 5 \ + --outSAMtype BAM SortedByCoordinate \ + --chimSegmentMin 10 \ + --peOverlapNbasesMin 10 \ + --alignSplicedMateMapLminOverLmate 0.5 \ + --chimJunctionOverhangMin 10 \ + --chimScoreJunctionNonGTAG 0 \ + --chimScoreDropMax 30 \ + --chimScoreSeparation 1 \ + --chimSegmentReadGapMax 3 \ + --chimOutType Junctions WithinBAM' +``` + +We found that this command produces the best results for all downstream processes in the pipeline. It is highly recommended to use the same command for the input BAM, CRAM, junctions and splice_junctions files. -| Column | Description | -| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `sample` | Custom sample name. This entry will be identical for multiple sequencing libraries/runs from the same sample. Spaces in sample names are automatically converted to underscores (`_`). | -| `fastq_1` | Full path to FastQ file for Illumina short reads 1. File has to be gzipped and have the extension ".fastq.gz" or ".fq.gz". | -| `fastq_2` | Full path to FastQ file for Illumina short reads 2. File has to be gzipped and have the extension ".fastq.gz" or ".fq.gz". | -| `strandedness` | Strandedness: forward or reverse. | +The pipeline will still work when another command has been used, but it is possible that the results will be significantly different from the standard flow. ### Starting commands -The pipeline can either be run using all fusion detection tools or specifying individual tools. Visualisation tools will be run on all fusions detected. To run all tools (`arriba`, `fusioncatcher`, `starfusion`, `stringtie`) use the `--all` parameter: +The pipeline can either be run using all tools or by specifying individual tools. Visualisation tools will be run on all fusions detected. To run all tools (`arriba`, `ctatsplicing`, `fusioncatcher`, `starfusion`, `stringtie`, `fusionreport`, `fastp`, `salmon`, `fusioninspector`) use the `all` option for the `--tools` parameter: ```bash nextflow run nf-core/rnafusion \ - --all \ + -profile \ + --tools all \ --input \ --genomes_base \ --outdir ``` -To run only a specific detection tool use: `--tool`: +To run only a set of specific tools use `--tools` with a comma separated list of requested tools: ```bash nextflow run nf-core/rnafusion \ - -- -- ... \ + -profile \ + --tools \ --input \ --genomes_base \ --outdir ``` -> **IMPORTANT: Either `--all` or `--`** is necessary to run detection tools +If you are not covered by the research COSMIC license and want to avoid using COSMIC, you can provide the additional option `--no_cosmic`. -`--genomes_base` should be the path to the directory containing the folder `references/` that was built with `--build_references`. +> **IMPORTANT: `--tools`** is necessary to run detection tools + +`--genomes_base` should be the path to the directory containing the references that were [downloaded or built](#download-and-build-references). Note that the pipeline will create the following files in your working directory: @@ -167,9 +235,8 @@ If you wish to repeatedly use the same parameters for multiple runs, rather than Pipeline settings can be provided in a `yaml` or `json` file via `-params-file `. -:::warning -Do not use `-c ` to specify parameters as this will result in errors. Custom config files specified with `-c` must only be used for [tuning process resource specifications](https://nf-co.re/docs/usage/configuration#tuning-workflow-resources), other infrastructural tweaks (such as output directories), or module arguments (args). -::: +> [!WARNING] +> Do not use `-c ` to specify parameters as this will result in errors. Custom config files specified with `-c` must only be used for [tuning process resource specifications](https://nf-co.re/docs/usage/configuration#tuning-workflow-resources), other infrastructural tweaks (such as output directories), or module arguments (args). The above pipeline run specified with a params file in yaml format: @@ -177,9 +244,9 @@ The above pipeline run specified with a params file in yaml format: nextflow run nf-core/rnafusion -profile docker -params-file params.yaml ``` -with `params.yaml` containing: +with: -```yaml +```yaml title="params.yaml" input: './samplesheet.csv' outdir: './results/' <...> @@ -187,33 +254,36 @@ outdir: './results/' You can also generate such `YAML`/`JSON` files via [nf-core/launch](https://nf-co.re/launch). -:::warning -Conda is not currently supported. -Supported genome is currently only GRCh38. -::: +> [!WARNING] +> Conda is not currently supported. +> Supported genome is currently only GRCh38. ### Options #### Trimming -When the flag `--fastp_trim` is used, `fastp` is used to provide all tools with trimmed reads. Quality and adapter trimming by default. In addition, tail trimming and adapter_fastq specification are possible. Example usage: +When the flag `fastp` tool is used in `--tools`, `fastp` is used to provide all tools with trimmed reads. Quality and adapter trimming are performed by default. In addition, tail trimming for fusioncatcher and adapter fasta specification are possible. Example usage: ```bash nextflow run nf-core/rnafusion \ --- -- ... \ +-profile \ +--tools fastp,... \ --input \ --genomes_base \ --outdir \ --fastp_trim \ ---trim_tail (optional) \ ---adapter_fastq (optional) +--trim_tail_fusioncatcher (optional) \ +--adapter_fasta (optional) ``` -#### Filter fusions detected by 2 or more tools +The additional `--trim_tail_fusioncatcher` flag will toggle an additional `fastp` process, especially useful if reads are above 100 bp, which is not handled well by FusionCatcher. The parameter `--trim_tail_fusioncatcher` needs to be provided with the number of bases to remove from the tail end. + +#### Filter for fusions detected by several tools ```bash nextflow run nf-core/rnafusion \ - -- -- ... \ + -profile \ + --tools \ --input \ --genomes_base \ --outdir @@ -226,7 +296,8 @@ nextflow run nf-core/rnafusion \ ```bash nextflow run nf-core/rnafusion \ - -- -- ... \ + -profile \ + --tools \ --input \ --genomes_base \ --outdir @@ -246,7 +317,11 @@ FusionInspector can be run as a standalone with: ```bash nextflow run nf-core/rnafusion \ ---fusioninspector_only \ +-profile \ +--tools fusioninspector \ +--skip_qc \ +--skip_vis \ +--skip_vcf \ --fusioninspector_fusions \ --input \ --outdir @@ -263,8 +338,9 @@ GENE3--GENE4 ```bash nextflow run nf-core/rnafusion \ +-profile \ --skip_qc \ ---all OR <--tool> +--tools \ --input \ --genomes_base \ --outdir @@ -276,8 +352,9 @@ This will skip all QC-related processes (picard metrics collection) ```bash nextflow run nf-core/rnafusion \ +-profile \ --skip_vis \ ---all OR <--tool> +--tools \ --input \ --genomes_base \ --outdir @@ -287,7 +364,7 @@ This will skip all visualisation processes, including `fusion-report`, `FusionIn #### Optional manual feed-in of fusion files -It is possible to give the output of each tool manually using the argument: `--_fusions PATH/TO/FUSION/FILE`: this feature need more testing, don't hesitate to open an issue if you encounter problems. +It is possible to give the output of each fusion detection tool manually using the argument: `--_fusions PATH/TO/FUSION/FILE`: this feature needs more testing, don't hesitate to open an issue if you encounter problems. #### Set different `--limitSjdbInsertNsj` parameter @@ -296,10 +373,9 @@ There are two parameters to increase the `--limitSjdbInsertNsj` parameter if nec - `--fusioncatcher_limitSjdbInsertNsj`, default: 2000000 - `--fusioninspector_limitSjdbInsertNsj`, default: 1000000 -Use the parameter `--cram` to compress the BAM files to CRAM for specific tools. Options: arriba, starfusion. Leave no space between options: +#### CRAM compression -- `--cram arriba,starfusion`, default: [] -- `--cram arriba` +Use the parameter `--cram` to compress the BAM files to CRAM. ### Troubleshooting @@ -316,7 +392,7 @@ As the error message suggests, it is a STAR-related error and your best luck in ### Updating the pipeline -When you run the above command, Nextflow automatically pulls the pipeline code from GitHub and stores it as a cached version. When running the pipeline after this, it will always use the cached version if available - even if the pipeline has been updated since. To make sure that you're running the latest version of the pipeline, make sure that you regularly update the cached version of the pipeline: +When you run the command below, Nextflow automatically pulls the pipeline code from GitHub and stores it as a cached version. When running the pipeline after this, it will always use the cached version if available - even if the pipeline has been updated since. To make sure that you're running the latest version of the pipeline, make sure that you regularly update the cached version of the pipeline: ```bash nextflow pull nf-core/rnafusion @@ -324,23 +400,21 @@ nextflow pull nf-core/rnafusion ### Reproducibility -It is a good idea to specify a pipeline version when running the pipeline on your data. This ensures that a specific version of the pipeline code and software are used when you run your pipeline. If you keep using the same tag, you'll be running the same version of the pipeline, even if there have been changes to the code since. +It is a good idea to specify the pipeline version when running the pipeline on your data. This ensures that a specific version of the pipeline code and software are used when you run your pipeline. If you keep using the same tag, you'll be running the same version of the pipeline, even if there have been changes to the code since. First, go to the [nf-core/rnafusion releases page](https://github.com/nf-core/rnafusion/releases) and find the latest pipeline version - numeric only (eg. `1.3.1`). Then specify this when running the pipeline with `-r` (one hyphen) - eg. `-r 1.3.1`. Of course, you can switch to another version by changing the number after the `-r` flag. This version number will be logged in reports when you run the pipeline, so that you'll know what you used when you look back in the future. For example, at the bottom of the MultiQC reports. -To further assist in reproducbility, you can use share and re-use [parameter files](#running-the-pipeline) to repeat pipeline runs with the same settings without having to write out a command with every single parameter. +To further assist in reproducibility, you can use share and reuse [parameter files](#running-the-pipeline) to repeat pipeline runs with the same settings without having to write out a command with every single parameter. -:::tip -If you wish to share such profile (such as upload as supplementary material for academic publications), make sure to NOT include cluster specific paths to files, nor institutional specific profiles. -::: +> [!TIP] +> If you wish to share such profile (such as upload as supplementary material for academic publications), make sure to NOT include cluster specific paths to files, nor institutional specific profiles. ## Core Nextflow arguments -:::note -These options are part of Nextflow and use a _single_ hyphen (pipeline parameters use a double-hyphen). -::: +> [!NOTE] +> These options are part of Nextflow and use a _single_ hyphen (pipeline parameters use a double-hyphen) ### `-profile` @@ -348,16 +422,15 @@ Use this parameter to choose a configuration profile. Profiles can give configur Several generic profiles are bundled with the pipeline which instruct the pipeline to use software packaged using different methods (Docker, Singularity, Podman, Shifter, Charliecloud, Apptainer, Conda) - see below. -:::info -We highly recommend the use of Docker or Singularity containers for full pipeline reproducibility, however when this is not possible, Conda is also supported. -::: +> [!IMPORTANT] +> We highly recommend the use of Docker or Singularity containers, ctatsplicing is not supported by Conda and Conda was not specifically tested for the rest of the pipeline. -The pipeline also dynamically loads configurations from [https://github.com/nf-core/configs](https://github.com/nf-core/configs) when it runs, making multiple config profiles for various institutional clusters available at run time. For more information and to see if your system is available in these configs please see the [nf-core/configs documentation](https://github.com/nf-core/configs#documentation). +The pipeline also dynamically loads configurations from [https://github.com/nf-core/configs](https://github.com/nf-core/configs) when it runs, making multiple config profiles for various institutional clusters available at run time. For more information and to check if your system is supported, please see the [nf-core/configs documentation](https://github.com/nf-core/configs#documentation). Note that multiple profiles can be loaded, for example: `-profile test,docker` - the order of arguments is important! They are loaded in sequence, so later profiles can overwrite earlier profiles. -If `-profile` is not specified, the pipeline will run locally and expect all software to be installed and available on the `PATH`. This is _not_ recommended, since it can lead to different results on different machines dependent on the computer enviroment. +If `-profile` is not specified, the pipeline will run locally and expect all software to be installed and available on the `PATH`. This is _not_ recommended, since it can lead to different results on different machines dependent on the computer environment. - `test` - A profile with a complete configuration for automated testing @@ -374,12 +447,13 @@ 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/) +- `wave` + - A generic configuration profile to enable [Wave](https://seqera.io/wave/) containers. Use together with one of the above (requires Nextflow ` 24.03.0-edge` or later). - `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. - `test` - A profile with a complete configuration for automated testing - Includes links to test data so needs no other parameters - - Needs to run in two steps: with `--build_references` first and then without `--build_references` to run the analysis - !!!! Run with `-stub` as all references need to be downloaded otherwise !!!! ### `-resume` @@ -396,15 +470,15 @@ Specify the path to a specific config file (this is a core Nextflow command). Se ### Resource requests -Whilst the default requirements set within the pipeline will hopefully work for most people and with most input data, you may find that you want to customise the compute resources that the pipeline requests. Each step in the pipeline has a default set of requirements for number of CPUs, memory and time. For most of the steps in the pipeline, if the job exits with any of the error codes specified [here](https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/conf/base.config#L18) it will automatically be resubmitted with higher requests (2 x original, then 3 x original). If it still fails after the third attempt then the pipeline execution is stopped. +Whilst the default requirements set within the pipeline will hopefully work for most people and with most input data, you may find that you want to customise the compute resources that the pipeline requests. Each step in the pipeline has a default set of requirements for number of CPUs, memory and time. For most of the pipeline steps, if the job exits with any of the error codes specified [here](https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/conf/base.config#L18) it will automatically be resubmitted with higher resources request (2 x original, then 3 x original). If it still fails after the third attempt then the pipeline execution is stopped. To change the resource requests, please see the [max resources](https://nf-co.re/docs/usage/configuration#max-resources) and [tuning workflow resources](https://nf-co.re/docs/usage/configuration#tuning-workflow-resources) section of the nf-core website. ### Custom Containers -In some cases you may wish to change which container or conda environment a step of the pipeline uses for a particular tool. By default nf-core pipelines use containers and software from the [biocontainers](https://biocontainers.pro/) or [bioconda](https://bioconda.github.io/) projects. However in some cases the pipeline specified version maybe out of date. +In some cases, you may wish to change the container used by a pipeline steps for a particular tool. By default, nf-core pipelines use containers and software from the [biocontainers](https://biocontainers.pro/) or [bioconda](https://bioconda.github.io/) projects (via wave for docker and singularity). -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 @@ -420,14 +494,6 @@ See the main [Nextflow documentation](https://www.nextflow.io/docs/latest/config If you have any questions or issues please send us a message on [Slack](https://nf-co.re/join/slack) on the [`#configs` channel](https://nfcore.slack.com/channels/configs). --> -## Azure Resource Requests - -To be used with the `azurebatch` profile by specifying the `-profile azurebatch`. -We recommend providing a compute `params.vm_type` of `Standard_D16_v3` VMs by default but these options can be changed if required. - -Note that the choice of VM size depends on your quota and the overall workload during the analysis. -For a thorough list, please refer the [Azure Sizes for virtual machines in Azure](https://docs.microsoft.com/en-us/azure/virtual-machines/sizes). - ## Running in the background Nextflow handles job submissions and supervises the running jobs. The Nextflow process must run until the pipeline is finished. diff --git a/main.nf b/main.nf index ac96ab669..56a8fcf9e 100644 --- a/main.nf +++ b/main.nf @@ -9,55 +9,41 @@ ---------------------------------------------------------------------------------------- */ -nextflow.enable.dsl = 2 - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS / WORKFLOWS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_rnafusion_pipeline' -include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_rnafusion_pipeline' -include { getGenomeAttribute } from './subworkflows/local/utils_nfcore_rnafusion_pipeline' -include { BUILD_REFERENCES } from './workflows/build_references' -include { RNAFUSION } from './workflows/rnafusion' - - /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GENOME PARAMETER VALUES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +include { getGenomeAttribute } from './subworkflows/local/utils_nfcore_rnafusion_pipeline' - - +params.fasta = getGenomeAttribute("fasta") +params.fai = getGenomeAttribute("fai") +params.gtf = getGenomeAttribute("gtf") +params.refflat = getGenomeAttribute("refflat") +params.rrna_intervals = getGenomeAttribute("rrna_intervals") +params.arriba_ref_blacklist = getGenomeAttribute("arriba_ref_blacklist") +params.arriba_ref_cytobands = getGenomeAttribute("arriba_ref_cytobands") +params.arriba_ref_known_fusions = getGenomeAttribute("arriba_ref_known_fusions") +params.arriba_ref_protein_domains = getGenomeAttribute("arriba_ref_protein_domains") +params.fusioncatcher_ref = getGenomeAttribute("fusioncatcher_ref") +params.hgnc_ref = getGenomeAttribute("hgnc_ref") +params.hgnc_date = getGenomeAttribute("hgnc_date") +params.salmon_index = getGenomeAttribute("salmon_index") +params.starfusion_ref = getGenomeAttribute("starfusion_ref") +params.starindex_ref = getGenomeAttribute("starindex_ref") +params.fusionreport_ref = getGenomeAttribute("fusionreport_ref") /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - NAMED WORKFLOWS FOR PIPELINE + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS / WORKFLOWS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -// -// WORKFLOW: Run main analysis pipeline depending on type of input -// -workflow NFCORE_RNAFUSION { - - main: - - // - // WORKFLOW: Run pipeline - // - if (params.build_references) { - BUILD_REFERENCES () - } else { - ch_samplesheet = Channel.value(file(params.input, checkIfExists: true)) - RNAFUSION(ch_samplesheet) - } +include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_rnafusion_pipeline' +include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_rnafusion_pipeline' +include { RNAFUSION } from './workflows/rnafusion' -} /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN MAIN WORKFLOW @@ -67,24 +53,58 @@ workflow NFCORE_RNAFUSION { workflow { main: - // // SUBWORKFLOW: Run initialisation tasks // PIPELINE_INITIALISATION ( params.version, - params.help, params.validate_params, - params.monochrome_logs, args, params.outdir, - params.input ) + def tools = params.tools.tokenize(",") + if (tools.contains("all")) { + def json = new groovy.json.JsonSlurper().parseText(file("${projectDir}/nextflow_schema.json").text) + def pattern = json.get('$defs')?.get('input_output_options')?.get('properties')?.get('tools')?.get('pattern') + if (!pattern) { + error("Could not fetch the allowed tools from the JSON schema, please check the code. If you see this as a pipeline user, please contact the developers instead.") + } + tools = pattern.replace('^((', "").replace(')?,?)*(? versions.yml - "${task.process}": - wget: \$(echo wget -V 2>&1 | grep "GNU Wget" | cut -d" " -f3 > versions.yml) - END_VERSIONS - """ - - stub: - """ - touch blacklist_hg38_GRCh38_v2.4.0.tsv.gz - touch protein_domains_hg38_GRCh38_v2.4.0.gff3 - touch cytobands_hg38_GRCh38_v2.4.0.tsv - touch known_fusions_hg38_GRCh38_v2.4.0.tsv.gz - touch protein_domains_hg38_GRCh38_v2.4.0.gff3 - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - wget: \$(echo wget -V 2>&1 | grep "GNU Wget" | cut -d" " -f3 > versions.yml) - END_VERSIONS - """ -} diff --git a/modules/local/arriba/download/meta.yml b/modules/local/arriba/download/meta.yml deleted file mode 100644 index 55e50b115..000000000 --- a/modules/local/arriba/download/meta.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: arriba_download -description: Arriba is a command-line tool for the detection of gene fusions from RNA-Seq data. -keywords: - - fusion - - arriba -tools: - - arriba: - description: Fast and accurate gene fusion detection from RNA-Seq data - homepage: https://github.com/suhrig/arriba - documentation: https://arriba.readthedocs.io/en/latest/ - tool_dev_url: https://github.com/suhrig/arriba - doi: "10.1101/gr.257246.119" - licence: ["MIT"] - -output: - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - reference: - type: directory - description: Folder with arriba references - pattern: "*" - -authors: - - "@praveenraj2018, @rannick" diff --git a/modules/local/arriba/visualisation/meta.yml b/modules/local/arriba/visualisation/meta.yml deleted file mode 100644 index a7418ca24..000000000 --- a/modules/local/arriba/visualisation/meta.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: arriba_visualisation -description: Arriba is a command-line tool for the detection of gene fusions from RNA-Seq data. -keywords: - - visualisation - - arriba -tools: - - arriba: - description: Fast and accurate gene fusion detection from RNA-Seq data - homepage: https://github.com/suhrig/arriba - documentation: https://arriba.readthedocs.io/en/latest/ - tool_dev_url: https://github.com/suhrig/arriba - doi: "10.1101/gr.257246.119" - licence: ["MIT"] - -input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: BAM/CRAM/SAM file - pattern: "*.{bam,cram,sam}" - - bai: - type: file - description: BAMindex file - pattern: "*.{bai}" - - fusions: - type: file - description: Arriba fusions file - pattern: "*.{tsv}" - - gtf: - type: file - description: Annotation GTF file - pattern: "*.{gtf}" - -output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - pdf: - type: file - description: File contains fusions visualisation - pattern: "*.{pdf}" - -authors: - - "@rannick" diff --git a/modules/local/convert2bed/main.nf b/modules/local/convert2bed/main.nf deleted file mode 100644 index c4313f0a7..000000000 --- a/modules/local/convert2bed/main.nf +++ /dev/null @@ -1,36 +0,0 @@ -process CONVERT2BED { - tag "$meta.id" - label 'process_single' - - conda "bioconda::bedops=2.4.41" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bedops:2.4.41--h9f5acd7_0' : - 'quay.io/biocontainers/bedops:2.4.41--h9f5acd7_0' }" - - input: - tuple val(meta), path(gtf) - - output: - tuple val(meta), path("*.bed") , emit: bed - - script: - def prefix = task.ext.prefix ?: "${meta.id}" - """ - convert2bed -i gtf < $gtf > ${prefix}.bed - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - convert2bed: \$(convert2bed --version | grep vers | sed 's/^.*.version: //') - END_VERSIONS - """ - - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - """ - touch ${prefix}.bed - cat <<-END_VERSIONS > versions.yml - "${task.process}": - convert2bed: \$(convert2bed --version | grep vers | sed 's/^.*.version: //') - END_VERSIONS - """ -} diff --git a/modules/local/convert2bed/meta.yml b/modules/local/convert2bed/meta.yml deleted file mode 100644 index 31ff3649a..000000000 --- a/modules/local/convert2bed/meta.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: -description: convert from GTF to BED format - - convert2bed -tools: - - convert2bed: - description: convert from GTF to BED format - homepage: https://github.com/bedops/bedops - documentation: https://bedops.readthedocs.io/en/latest/index.html - tool_dev_url: https://github.com/bedops/bedops - doi: "" - licence: ["GNU GENERAL PUBLIC LICENSE"] - -input: - - gtf: - type: file - description: Path to GTF file - pattern: "*.{gtf*}" - -output: - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - bed: - type: file - description: bed file - pattern: "*.bed" - -authors: - - "@rannick" diff --git a/modules/local/ensembl/main.nf b/modules/local/ensembl/main.nf deleted file mode 100644 index 4a782c0df..000000000 --- a/modules/local/ensembl/main.nf +++ /dev/null @@ -1,57 +0,0 @@ -process ENSEMBL_DOWNLOAD { - tag "ensembl" - label 'process_low' - - conda "bioconda::gnu-wget=1.18" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h5bf99c6_5' : - 'quay.io/biocontainers/gnu-wget:1.18--h5bf99c6_5' }" - - input: - val ensembl_version - val genome - val meta - - output: - tuple val(meta), path("Homo_sapiens.${genome}.${ensembl_version}.all.fa") , emit: fasta - tuple val(meta), path("Homo_sapiens.${genome}.${ensembl_version}.gtf") , emit: gtf - tuple val(meta), path("Homo_sapiens.${genome}.${ensembl_version}.chr.gtf") , emit: chrgtf - tuple val(meta), path("Homo_sapiens.${genome}.${ensembl_version}.cdna.all.fa.gz"), emit: transcript - path "versions.yml" , emit: versions - - - script: - """ - wget ftp://ftp.ensembl.org/pub/release-${ensembl_version}/fasta/homo_sapiens/dna/Homo_sapiens.${params.genome}.dna.chromosome.{1..22}.fa.gz - wget ftp://ftp.ensembl.org/pub/release-${ensembl_version}/fasta/homo_sapiens/dna/Homo_sapiens.${params.genome}.dna.chromosome.{MT,X,Y}.fa.gz - - wget ftp://ftp.ensembl.org/pub/release-${ensembl_version}/gtf/homo_sapiens/Homo_sapiens.${params.genome}.${ensembl_version}.gtf.gz - wget ftp://ftp.ensembl.org/pub/release-${ensembl_version}/gtf/homo_sapiens/Homo_sapiens.${params.genome}.${ensembl_version}.chr.gtf.gz - wget ftp://ftp.ensembl.org/pub/release-${ensembl_version}/fasta/homo_sapiens/cdna/Homo_sapiens.${params.genome}.cdna.all.fa.gz -O Homo_sapiens.${params.genome}.${ensembl_version}.cdna.all.fa.gz - - gunzip -c Homo_sapiens.${params.genome}.dna.chromosome.* > Homo_sapiens.${params.genome}.${ensembl_version}.all.fa - gunzip Homo_sapiens.${params.genome}.${ensembl_version}.gtf.gz - gunzip Homo_sapiens.${params.genome}.${ensembl_version}.chr.gtf.gz - - - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - wget: \$(echo wget -V 2>&1 | grep "GNU Wget" | cut -d" " -f3 > versions.yml) - END_VERSIONS - """ - - stub: - """ - touch "Homo_sapiens.${genome}.${ensembl_version}.all.fa" - touch "Homo_sapiens.${genome}.${ensembl_version}.gtf" - touch "Homo_sapiens.${genome}.${ensembl_version}.chr.gtf" - touch "Homo_sapiens.${genome}.${ensembl_version}.cdna.all.fa.gz" - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - wget: \$(echo wget -V 2>&1 | grep "GNU Wget" | cut -d" " -f3 > versions.yml) - END_VERSIONS - """ - -} diff --git a/modules/local/fusioncatcher/detect/main.nf b/modules/local/fusioncatcher/detect/main.nf deleted file mode 100644 index 2977d6686..000000000 --- a/modules/local/fusioncatcher/detect/main.nf +++ /dev/null @@ -1,58 +0,0 @@ -process FUSIONCATCHER { - tag "$meta.id" - label 'process_high' - - conda "bioconda::fusioncatcher=1.33" - container "docker.io/clinicalgenomics/fusioncatcher:1.33" - - input: - tuple val(meta), path(fasta) - path reference - - output: - tuple val(meta), path("*.fusioncatcher.fusion-genes.txt") , optional:true , emit: fusions - tuple val(meta), path("*.fusioncatcher.summary.txt") , optional:true , emit: summary - tuple val(meta), path("*.fusioncatcher.log") , emit: log - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def reads = fasta.toString().replace(" ", ",") - def single_end = meta.single_end ? "--single-end" : "" - """ - fusioncatcher.py \\ - -d $reference \\ - -i $reads \\ - -p $task.cpus \\ - -o . \\ - --skip-blat \\ - $single_end \\ - $args - - mv final-list_candidate-fusion-genes.txt ${prefix}.fusioncatcher.fusion-genes.txt - mv summary_candidate_fusions.txt ${prefix}.fusioncatcher.summary.txt - mv fusioncatcher.log ${prefix}.fusioncatcher.log - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fusioncatcher: \$(echo \$(fusioncatcher.py --version 2>&1)| sed 's/fusioncatcher.py //') - END_VERSIONS - """ - - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - - """ - touch ${prefix}.fusioncatcher.fusion-genes.txt - touch ${prefix}.fusioncatcher.summary.txt - touch ${prefix}.fusioncatcher.log - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fusioncatcher: \$(echo \$(fusioncatcher.py --version 2>&1)| sed 's/fusioncatcher.py //') - END_VERSIONS - """ -} diff --git a/modules/local/fusioncatcher/detect/meta.yml b/modules/local/fusioncatcher/detect/meta.yml deleted file mode 100644 index 7c8ee425a..000000000 --- a/modules/local/fusioncatcher/detect/meta.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: fusioncatcher -description: FusionCatcher searches for novel/known somatic fusion genes, translocations, and chimeras in RNA-seq data -keywords: - - fusioncatcher -tools: - - fusioncatcher: - description: FusionCatcher searches for novel/known somatic fusion genes, translocations, and chimeras in RNA-seq data - homepage: https://github.com/ndaniel/fusioncatcher - documentation: https://github.com/ndaniel/fusioncatcher/wiki - tool_dev_url: https://github.com/ndaniel/fusioncatcher - doi: "10.1101/011650v1" - licence: ["GPL v3"] - -input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - reads: - type: file - description: FASTQ file - pattern: "*.{fastq}" - - reference: - type: directory - description: Path to fusioncatcher references - pattern: "*" - -output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - fusions: - type: file - description: Final list of candidate fusion genes - pattern: "*.fusioncatcher.fusion-genes.txt" - - summary: - type: file - description: Summary of fusion results - pattern: "*.fusioncatcher_summary.txt" - - log: - type: file - description: Log of fusion results - pattern: "*.fusioncatcher.log" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - -authors: - - "@praveenraj2018. @rannick" diff --git a/modules/local/fusioncatcher/download/main.nf b/modules/local/fusioncatcher/download/main.nf deleted file mode 100644 index 156e70b65..000000000 --- a/modules/local/fusioncatcher/download/main.nf +++ /dev/null @@ -1,51 +0,0 @@ -process FUSIONCATCHER_DOWNLOAD { - tag "fusioncatcher_download" - label 'process_medium' - - conda "bioconda::fusioncatcher=1.33" - container "docker.io/clinicalgenomics/fusioncatcher:1.33" - - output: - path "*" , emit: reference - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - - def args = task.ext.args ?: '' - def args2 = task.ext.args2 ?: '' - def human_version = "v102" - def url = "http://sourceforge.net/projects/fusioncatcher/files/data/human_${human_version}.tar.gz.aa" - """ - if wget --spider "$url" 2>/dev/null; then - wget $args $url - wget $args http://sourceforge.net/projects/fusioncatcher/files/data/human_${human_version}.tar.gz.ab - wget $args http://sourceforge.net/projects/fusioncatcher/files/data/human_${human_version}.tar.gz.ac - wget $args http://sourceforge.net/projects/fusioncatcher/files/data/human_${human_version}.tar.gz.ad - cat human_${human_version}.tar.gz.* | tar xz - rm human_${human_version}.tar* - else - fusioncatcher-build \\ - -g homo_sapiens \\ - -o human_${human_version} \\ - $args2 - fi - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fusioncatcher: \$(echo \$(fusioncatcher --version 2>&1)) - END_VERSIONS - """ - - stub: - def human_version = "v102" - """ - mkdir human_${human_version} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fusioncatcher: \$(echo \$(fusioncatcher --version 2>&1)) - END_VERSIONS - """ -} diff --git a/modules/local/fusioncatcher/download/meta.yml b/modules/local/fusioncatcher/download/meta.yml deleted file mode 100644 index 40421a4ee..000000000 --- a/modules/local/fusioncatcher/download/meta.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: fusioncatcher_download -description: Build genome for fusioncatcher -keywords: - - sort -tools: - - fusioncatcher: - description: Build genome for fusioncatcher - homepage: https://github.com/ndaniel/fusioncatcher/ - documentation: https://github.com/ndaniel/fusioncatcher/blob/master/doc/manual.md - tool_dev_url: https://github.com/ndaniel/fusioncatcher/ - doi: "10.1101/011650" - licence: ["GPL v3"] - -output: - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - reference: - type: directory - description: Path to fusioncatcher references - pattern: "*" - -authors: - - "@praveenraj2018, @rannick" diff --git a/modules/local/fusioninspector/main.nf b/modules/local/fusioninspector/main.nf deleted file mode 100644 index c7fcd3f04..000000000 --- a/modules/local/fusioninspector/main.nf +++ /dev/null @@ -1,56 +0,0 @@ -process FUSIONINSPECTOR { - tag "$meta.id" - label 'process_high' - - conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.12.0 bioconda::samtools=1.9 bioconda::star=2.7.8a" - container 'docker.io/trinityctat/starfusion:1.12.0' - - input: - tuple val(meta), path(reads), path(fusion_list) - path reference - - output: - tuple val(meta), path("*FusionInspector.fusions.tsv") , emit: tsv - tuple val(meta), path("*.coding_effect") , optional:true, emit: tsv_coding_effect - tuple val(meta), path("*.gtf") , optional:true, emit: out_gtf - path "*" , emit: output - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def prefix = task.ext.prefix ?: "${meta.id}" - def fasta = meta.single_end ? "--left_fq ${reads[0]}" : "--left_fq ${reads[0]} --right_fq ${reads[1]}" - def args = task.ext.args ?: '' - def args2 = task.ext.args2 ?: '' - """ - FusionInspector \\ - --fusions $fusion_list \\ - --genome_lib ${reference} \\ - $fasta \\ - --CPU ${task.cpus} \\ - -O . \\ - --out_prefix $prefix \\ - --vis $args $args2 - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') - END_VERSIONS - """ - - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - """ - touch ${prefix}.FusionInspector.log - touch ${prefix}.FusionInspector.fusions.tsv - touch ${prefix}.FusionInspector.fusions.tsv.annotated.coding_effect - touch ${prefix}.gtf - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') - END_VERSIONS - """ -} diff --git a/modules/local/fusioninspector/meta.yml b/modules/local/fusioninspector/meta.yml deleted file mode 100644 index cc03239be..000000000 --- a/modules/local/fusioninspector/meta.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: fusioninspector -description: Validation of Fusion Transcript Predictions -keywords: - - fusioninspector -tools: - - fusioninspector: - description: Validation of Fusion Transcript Predictions - homepage: https://github.com/FusionInspector/FusionInspector - documentation: https://github.com/FusionInspector/FusionInspector/wiki - tool_dev_url: https://github.com/FusionInspector/FusionInspector - doi: 10.1101/2021.08.02.454639" - licence: https://github.com/FusionInspector/FusionInspector/blob/master/LICENSE.txt - -input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - reads: - type: file - description: FASTQ file - pattern: "*.{fastq*}" - - reference: - type: directory - description: Path to ctat references - pattern: "*" - -output: - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - reference: - type: directory - description: Genome resource path - pattern: "*" - -authors: - - "@rannick" diff --git a/modules/local/fusionreport/detect/meta.yml b/modules/local/fusionreport/detect/meta.yml deleted file mode 100644 index ae3601dc5..000000000 --- a/modules/local/fusionreport/detect/meta.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: fusionreport -description: fusionreport -keywords: - - sort -tools: - - fusionreport: - description: Tool for parsing outputs from fusion detection tools - homepage: https://github.com/Clinical-Genomics/fusion-report - documentation: https://matq007.github.io/fusion-report/#/ - doi: "10.1101/011650" - licence: ["GPL v3"] - -input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - reference: - type: path - description: Path to fusionreport references - pattern: "*" - - arriba_fusions: - type: path - description: File - pattern: "*.fusions.tsv" - - starfusion_fusions: - type: path - description: File containing fusions from STARfusion - pattern: "*.starfusion.fusion_predictions.tsv" - - fusioncatcher_fusions: - type: path - description: File containing fusions from fusioncatcher - pattern: "*.fusions.tsv" - -output: - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - fusion_list: - type: file - description: File containing the summary of all fusions fed-in - pattern: "*.tsv" - - report: - type: file - description: HTML files - pattern: "*.html" - -authors: - - "@praveenraj2018, @rannick" diff --git a/modules/local/fusionreport/download/main.nf b/modules/local/fusionreport/download/main.nf deleted file mode 100644 index ac288ade9..000000000 --- a/modules/local/fusionreport/download/main.nf +++ /dev/null @@ -1,39 +0,0 @@ -process FUSIONREPORT_DOWNLOAD { - tag 'fusionreport' - label 'process_medium' - - conda "bioconda::star=2.7.9a" - container "docker.io/clinicalgenomics/fusion-report:2.1.8" - - input: - val(username) - val(passwd) - - output: - path "*" , emit: reference - path "versions.yml" , emit: versions - - script: - def args = task.ext.args ?: '' - """ - fusion_report download --cosmic_usr "$username" --cosmic_passwd "$passwd" $args ./ - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fusion_report: \$(fusion_report --version | sed 's/fusion-report //') - END_VERSIONS - """ - - stub: - """ - touch cosmic.db - touch fusiongdb2.db - touch fusiongdb.db - touch mitelman.db - cat <<-END_VERSIONS > versions.yml - "${task.process}": - fusion_report: \$(fusion_report --version | sed 's/fusion-report //') - END_VERSIONS - """ - -} diff --git a/modules/local/fusionreport/download/meta.yml b/modules/local/fusionreport/download/meta.yml deleted file mode 100644 index 21a15a893..000000000 --- a/modules/local/fusionreport/download/meta.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: fusionreport_download -description: Build DB for fusionreport -keywords: - - sort -tools: - - fusioncatcher: - description: Build DB for fusionreport - homepage: https://github.com/ndaniel/fusioncatcher/ - documentation: https://github.com/ndaniel/fusioncatcher/blob/master/doc/manual.md - tool_dev_url: https://github.com/ndaniel/fusioncatcher/ - doi: "10.1101/011650" - licence: ["GPL v3"] - -input: - - username: - type: value - description: Organism for which the data is downloaded from Ensembl database and built - pattern: "*" - - passwd: - type: value - description: Organism for which the data is downloaded from Ensembl database and built - pattern: "*" - -output: - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - reference: - type: directory - description: directory containing the genome resource files required for fusioncatcher - pattern: "fusioncatcher-genome" - -authors: - - "@praveenraj2018" diff --git a/modules/local/gencode_download/main.nf b/modules/local/gencode_download/main.nf new file mode 100644 index 000000000..569c8df1e --- /dev/null +++ b/modules/local/gencode_download/main.nf @@ -0,0 +1,49 @@ +process GENCODE_DOWNLOAD { + tag "gencode_download" + label 'process_low' + + conda "bioconda::gnu-wget=1.18" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/3b/3b54fa9135194c72a18d00db6b399c03248103f87e43ca75e4b50d61179994b3/data' : + 'community.wave.seqera.io/library/wget:1.21.4--8b0fcde81c17be5e' }" + + input: + val genome_gencode_version + val genome + + output: + path "*.fa" , emit: fasta + path "*.gtf" , emit: gtf + path "versions.yml", emit: versions + + + when: + task.ext.when == null || task.ext.when + + script: + def folder_gencode = genome.contains("38") ? "" : "/${genome}_mapping" + def gtf_file_name = genome.contains("38") ? "gencode.v${genome_gencode_version}.primary_assembly.annotation.gtf.gz" : "gencode.v${genome_gencode_version}lift${genome_gencode_version}.annotation.gtf.gz" + """ + wget --no-check-certificate ftp://ftp.ebi.ac.uk/pub/databases/gencode/Gencode_human/release_${genome_gencode_version}/${folder_gencode}${genome}.primary_assembly.genome.fa.gz -O Homo_sapiens_${genome}_${genome_gencode_version}_dna_primary_assembly.fa.gz + gunzip Homo_sapiens_${genome}_${genome_gencode_version}_dna_primary_assembly.fa.gz + wget --no-check-certificate ftp://ftp.ebi.ac.uk/pub/databases/gencode/Gencode_human/release_${genome_gencode_version}/${folder_gencode}${gtf_file_name} -O Homo_sapiens_${genome}_${genome_gencode_version}.gtf.gz + gunzip Homo_sapiens_${genome}_${genome_gencode_version}.gtf.gz + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + wget: \$(wget --version | head -1 | cut -d ' ' -f 3) + END_VERSIONS + """ + + stub: + """ + touch Homo_sapiens.${genome}.${genome_gencode_version}_dna_primary_assembly.fa + touch Homo_sapiens.${genome}.${genome_gencode_version}.gtf + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + wget: \$(wget --version | head -1 | cut -d ' ' -f 3) + END_VERSIONS + """ + +} diff --git a/modules/local/hgnc/main.nf b/modules/local/hgnc/main.nf index 1b3808f6d..ee14e2c3b 100644 --- a/modules/local/hgnc/main.nf +++ b/modules/local/hgnc/main.nf @@ -4,26 +4,23 @@ process HGNC_DOWNLOAD { conda "bioconda::gnu-wget=1.18" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gnu-wget:1.18--h5bf99c6_5' : - 'quay.io/biocontainers/gnu-wget:1.18--h5bf99c6_5' }" - - input: + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/3b/3b54fa9135194c72a18d00db6b399c03248103f87e43ca75e4b50d61179994b3/data' : + 'community.wave.seqera.io/library/wget:1.21.4--8b0fcde81c17be5e' }" output: path "hgnc_complete_set.txt" , emit: hgnc_ref path "HGNC-DB-timestamp.txt" , emit: hgnc_date - - path "versions.yml" , emit: versions + path "versions.yml" , emit: versions script: """ - wget https://ftp.ebi.ac.uk/pub/databases/genenames/hgnc/tsv/hgnc_complete_set.txt + wget --no-check-certificate https://storage.googleapis.com/public-download-files/hgnc/tsv/tsv/hgnc_complete_set.txt date +%Y-%m-%d/%H:%M > HGNC-DB-timestamp.txt cat <<-END_VERSIONS > versions.yml "${task.process}": - wget: \$(echo wget -V 2>&1 | grep "GNU Wget" | cut -d" " -f3 > versions.yml) + wget: \$(wget --version | head -1 | cut -d ' ' -f 3) END_VERSIONS """ @@ -34,7 +31,7 @@ process HGNC_DOWNLOAD { cat <<-END_VERSIONS > versions.yml "${task.process}": - wget: \$(echo wget -V 2>&1 | grep "GNU Wget" | cut -d" " -f3 > versions.yml) + wget: \$(wget --version | head -1 | cut -d ' ' -f 3) END_VERSIONS """ diff --git a/modules/local/hgnc/tests/main.nf.test b/modules/local/hgnc/tests/main.nf.test new file mode 100644 index 000000000..795044d24 --- /dev/null +++ b/modules/local/hgnc/tests/main.nf.test @@ -0,0 +1,52 @@ +nextflow_process { + + name "Test Process HGNC_DOWNLOAD" + script "../main.nf" + process "HGNC_DOWNLOAD" + + test("Should download HGNC files") { + + when { + process { + """ + // This process doesn't have any inputs + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + file(process.out.hgnc_date[0]).name, + ).match() }, + { assert path(process.out.hgnc_ref[0]).exists() }, + { assert path(process.out.versions[0]).exists() } + ) + } + } + + test("Should create stub files") { + + options "-stub" + + when { + process { + """ + // This process doesn't have any inputs + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + file(process.out.hgnc_date[0]).name, + ).match() }, + { assert path(process.out.hgnc_ref[0]).exists() }, + { assert path(process.out.versions[0]).exists() } + ) + } + } +} diff --git a/modules/local/hgnc/tests/main.nf.test.snap b/modules/local/hgnc/tests/main.nf.test.snap new file mode 100644 index 000000000..87dab9036 --- /dev/null +++ b/modules/local/hgnc/tests/main.nf.test.snap @@ -0,0 +1,22 @@ +{ + "Should create stub files": { + "content": [ + "HGNC-DB-timestamp.txt" + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-07-22T13:23:08.771393" + }, + "Should download HGNC files": { + "content": [ + "HGNC-DB-timestamp.txt" + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-07-14T15:48:18.667694" + } +} \ No newline at end of file diff --git a/modules/local/picard/collectrnaseqmetrics/main.nf b/modules/local/picard/collectrnaseqmetrics/main.nf deleted file mode 100644 index ede593e0e..000000000 --- a/modules/local/picard/collectrnaseqmetrics/main.nf +++ /dev/null @@ -1,68 +0,0 @@ -process PICARD_COLLECTRNASEQMETRICS { - tag "$meta.id" - label 'process_medium' - - conda "bioconda::picard=3.1.0" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.1.0--hdfd78af_0' : - 'biocontainers/picard:3.1.0--hdfd78af_0' }" - - input: - tuple val(meta), path(bam), path(bai) - tuple val(meta2), path(refflat) - tuple val(meta3), path(rrna_intervals) - - output: - tuple val(meta), path("*rna_metrics.txt") , emit: metrics - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def strandedness = '' - // def strandedness = '--STRAND_SPECIFICITY FIRST_READ_TRANSCRIPTION_STRAND' - if ("${meta.strandedness}" == 'forward') { - strandedness = '--STRAND_SPECIFICITY FIRST_READ_TRANSCRIPTION_STRAND' - } else if ("${meta.strandedness}" == 'reverse') { - strandedness = '--STRAND_SPECIFICITY SECOND_READ_TRANSCRIPTION_STRAND' - } else { - strandedness = '--STRAND_SPECIFICITY NONE' - } - - def rrna = rrna_intervals == [] ? '' : "--RIBOSOMAL_INTERVALS ${rrna_intervals}" - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def avail_mem = 3072 - if (!task.memory) { - log.info '[Picard CollectRnaMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() - } - """ - picard \\ - -Xmx${avail_mem}M \\ - CollectRnaSeqMetrics \\ - --TMP_DIR ./tmp \\ - ${strandedness} \\ - ${rrna} \\ - --REF_FLAT ${refflat} \\ - --INPUT ${bam} \\ - --OUTPUT ${prefix}_rna_metrics.txt \\ - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(picard CollectRnaMetrics --version 2>&1 | grep -o 'Version.*' | cut -f2- -d:) - END_VERSIONS - """ - - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - """ - touch ${prefix}_rna_metrics.txt - cat <<-END_VERSIONS > versions.yml - "${task.process}": - picard: \$(picard CollectRnaMetrics --version 2>&1 | grep -o 'Version.*' | cut -f2- -d:) - END_VERSIONS - """ -} diff --git a/modules/local/picard/collectrnaseqmetrics/meta.yml b/modules/local/picard/collectrnaseqmetrics/meta.yml deleted file mode 100644 index 0cae7d07a..000000000 --- a/modules/local/picard/collectrnaseqmetrics/meta.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: picard_collectrnaseqmetrics -description: Produces RNA alignment metrics for a SAM or BAM file. -keywords: - - alignment - - metrics - - statistics - - quality - - bam - - RNA -tools: - - picard: - description: | - A set of command line tools (in Java) for manipulating high-throughput sequencing (HTS) - data and formats such as SAM/BAM/CRAM and VCF. - homepage: https://broadinstitute.github.io/picard/ - documentation: https://broadinstitute.github.io/picard/ - licence: ["MIT"] -input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: BAM file - pattern: "*.{bam}" - - bai: - type: file - description: An optional BAM index file. If desired, --CREATE_INDEX must be passed as a flag - pattern: "*.{bai}" - - refflat: - type: file - description: Gene annotations in refFlat form - - rrna_intervals: - type: file - description: Location of rRNA sequences in genome, in interval_list format -output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - metrics: - type: file - description: Alignment metrics files generated by picard - pattern: "*_{metrics}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" -authors: - - "@rannick" diff --git a/modules/local/rrnatranscripts/main.nf b/modules/local/rrnatranscripts/main.nf deleted file mode 100644 index e4afc2845..000000000 --- a/modules/local/rrnatranscripts/main.nf +++ /dev/null @@ -1,42 +0,0 @@ -process RRNA_TRANSCRIPTS { - tag "$meta.id" - label 'process_single' - - conda "conda-forge::python=3.8.3" - - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/python:3.9--1' : - 'quay.io/biocontainers/python:3.9--1' }" - - - input: - tuple val(meta), path(gtf) - - output: - tuple val(meta), path("*rrna_intervals.gtf") , emit: rrna_gtf - path "versions.yml" , emit: versions - - - when: - task.ext.when == null || task.ext.when - - script: // This script is bundled with the pipeline, in nf-core/rnafusion/bin/ - def prefix = task.ext.prefix ?: "${meta.id}" - """ - get_rrna_transcripts.py $gtf ${prefix}_rrna_intervals.gtf - cat <<-END_VERSIONS > versions.yml - "${task.process}": - python: \$(python --version | sed 's/Python //g') - END_VERSIONS - """ - - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - """ - touch ${prefix}_rrna_intervals.gtf - cat <<-END_VERSIONS > versions.yml - "${task.process}": - python: \$(python --version | sed 's/Python //g') - END_VERSIONS - """ -} diff --git a/modules/local/starfusion/build/main.nf b/modules/local/starfusion/build/main.nf deleted file mode 100644 index e2bd7879f..000000000 --- a/modules/local/starfusion/build/main.nf +++ /dev/null @@ -1,54 +0,0 @@ -process STARFUSION_BUILD { - tag 'star-fusion' - - conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.12.0 bioconda::trinity=2.13.2 bioconda::samtools=1.9 bioconda::star=2.7.8a" - container "docker.io/trinityctat/starfusion:1.12.0" - - input: - tuple val(meta), path(fasta) - tuple val(meta2), path(gtf) - - output: - path "*" , emit: reference - - script: - def binPath = (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) ? "prep_genome_lib.pl" : "/usr/local/src/STAR-Fusion/ctat-genome-lib-builder/prep_genome_lib.pl" - """ - export TMPDIR=/tmp - wget http://ftp.ebi.ac.uk/pub/databases/Pfam/releases/Pfam34.0/Pfam-A.hmm.gz --no-check-certificate - wget https://github.com/FusionAnnotator/CTAT_HumanFusionLib/releases/download/v0.3.0/fusion_lib.Mar2021.dat.gz -O CTAT_HumanFusionLib_Mar2021.dat.gz --no-check-certificate - wget https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/AnnotFilterRule.pm -O AnnotFilterRule.pm --no-check-certificate - wget https://www.dfam.org/releases/Dfam_3.4/infrastructure/dfamscan/homo_sapiens_dfam.hmm --no-check-certificate - wget https://www.dfam.org/releases/Dfam_3.4/infrastructure/dfamscan/homo_sapiens_dfam.hmm.h3f --no-check-certificate - wget https://www.dfam.org/releases/Dfam_3.4/infrastructure/dfamscan/homo_sapiens_dfam.hmm.h3i --no-check-certificate - wget https://www.dfam.org/releases/Dfam_3.4/infrastructure/dfamscan/homo_sapiens_dfam.hmm.h3m --no-check-certificate - wget https://www.dfam.org/releases/Dfam_3.4/infrastructure/dfamscan/homo_sapiens_dfam.hmm.h3p --no-check-certificate - gunzip Pfam-A.hmm.gz && hmmpress Pfam-A.hmm - $binPath \\ - --genome_fa $fasta \\ - --gtf $gtf \\ - --annot_filter_rule AnnotFilterRule.pm \\ - --fusion_annot_lib CTAT_HumanFusionLib_Mar2021.dat.gz \\ - --pfam_db Pfam-A.hmm \\ - --dfam_db homo_sapiens_dfam.hmm \\ - --max_readlength $params.read_length \\ - --CPU $task.cpus - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') - END_VERSIONS - """ - - stub: - """ - mkdir ctat_genome_lib_build_dir - touch ref_annot.cdna.fa - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') - END_VERSIONS - """ - -} diff --git a/modules/local/starfusion/build/meta.yml b/modules/local/starfusion/build/meta.yml deleted file mode 100644 index c87b251b1..000000000 --- a/modules/local/starfusion/build/meta.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: starfusion_downloadgenome -description: Download STAR-fusion genome resource required to run STAR-Fusion caller -keywords: - - downoad -tools: - - star-fusion: - description: Fusion calling algorithm for RNAseq data - homepage: https://github.com/STAR-Fusion/ - documentation: https://github.com/STAR-Fusion/STAR-Fusion/wiki/installing-star-fusion - tool_dev_url: https://github.com/STAR-Fusion/STAR-Fusion - doi: "10.1186/s13059-019-1842-9" - licence: ["GPL v3"] - -input: - - fasta: - type: file - description: genome fasta file - pattern: "*.{fasta}" - - gtf: - type: file - description: genome gtf file - pattern: "*.{gtf}" - -output: - - reference: - type: directory - description: Reference dir - pattern: "ctat_genome_lib_build_dir" - -authors: - - "@praveenraj2018" diff --git a/modules/local/starfusion/detect/main.nf b/modules/local/starfusion/detect/main.nf deleted file mode 100644 index 1994d5551..000000000 --- a/modules/local/starfusion/detect/main.nf +++ /dev/null @@ -1,55 +0,0 @@ -process STARFUSION { - tag "$meta.id" - label 'process_high' - - conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.12.0 bioconda::trinity=2.13.2 bioconda::samtools=1.9 bioconda::star=2.7.8a" - container 'docker.io/trinityctat/starfusion:1.12.0' - - input: - tuple val(meta), path(reads), path(junction) - path reference - - output: - tuple val(meta), path("*.fusion_predictions.tsv") , emit: fusions - tuple val(meta), path("*.abridged.tsv") , emit: abridged - tuple val(meta), path("*.coding_effect.tsv") , optional: true , emit: coding_effect - path "versions.yml" , emit: versions - - script: - def prefix = task.ext.prefix ?: "${meta.id}" - def fasta = meta.single_end ? "--left_fq ${reads[0]}" : "--left_fq ${reads[0]} --right_fq ${reads[1]}" - def args = task.ext.args ?: '' - """ - STAR-Fusion \\ - --genome_lib_dir $reference \\ - $fasta \\ - -J $junction \\ - --CPU $task.cpus \\ - --examine_coding_effect \\ - --output_dir . \\ - $args - - mv star-fusion.fusion_predictions.tsv ${prefix}.starfusion.fusion_predictions.tsv - mv star-fusion.fusion_predictions.abridged.tsv ${prefix}.starfusion.abridged.tsv - mv star-fusion.fusion_predictions.abridged.coding_effect.tsv ${prefix}.starfusion.abridged.coding_effect.tsv - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') - END_VERSIONS - """ - - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - """ - touch ${prefix}.starfusion.fusion_predictions.tsv - touch ${prefix}.starfusion.abridged.tsv - touch ${prefix}.starfusion.abridged.coding_effect.tsv - cat <<-END_VERSIONS > versions.yml - "${task.process}": - STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') - END_VERSIONS - """ -} - - diff --git a/modules/local/starfusion/detect/meta.yml b/modules/local/starfusion/detect/meta.yml deleted file mode 100644 index 7337dad5c..000000000 --- a/modules/local/starfusion/detect/meta.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: starfusion -description: Fast and Accurate Fusion Transcript Detection from RNA-Seq -keywords: - - Fusion -tools: - - star-fusion: - description: Fast and Accurate Fusion Transcript Detection from RNA-Seq - homepage: https://github.com/STAR-Fusion/STAR-Fusion - documentation: https://github.com/STAR-Fusion/STAR-Fusion/wiki - tool_dev_url: https://github.com/STAR-Fusion/STAR-Fusion/releases - doi: "10.1101/120295v1" - licence: ["GPL v3"] - -input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - genome_lib: - type: path - description: STAR-fusion reference genome lib folder - - junction: - type: file - description: Chimeric junction output from STAR aligner - pattern: "*.{out.junction}" - - reference: - type: directory - description: Reference dir - pattern: "ctat_genome_lib_build_dir" - -output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - version: - type: file - description: File containing software version - pattern: "*.{versions.yml}" - - fusions: - type: file - description: Fusion events from STAR-fusion - pattern: "*.{fusion_predictions.tsv}" - - abridged: - type: file - description: Fusion events from STAR-fusion - pattern: "*.{fusion.abridged.tsv}" - - coding_effect: - type: file - description: Fusion events from STAR-fusion - pattern: "*.{coding_effect.tsv}" - -authors: - - "@praveenraj2018" diff --git a/modules/local/starfusion/download/main.nf b/modules/local/starfusion/download/main.nf deleted file mode 100644 index 9c9b14827..000000000 --- a/modules/local/starfusion/download/main.nf +++ /dev/null @@ -1,32 +0,0 @@ -process STARFUSION_DOWNLOAD { - tag 'star-fusion' - - conda "bioconda::dfam=3.3 bioconda::hmmer=3.3.2 bioconda::star-fusion=1.12.0 bioconda::trinity=2.13.2 bioconda::samtools=1.9 bioconda::star=2.7.8a" - container 'docker.io/trinityctat/starfusion:1.12.0' - - output: - path "ctat_genome_lib_build_dir/*" , emit: reference - path "ctat_genome_lib_build_dir/ref_annot.gtf", emit: chrgtf - - - script: - """ - wget https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/__genome_libs_StarFv1.10/GRCh38_gencode_v37_CTAT_lib_Mar012021.plug-n-play.tar.gz --no-check-certificate - - tar xvf GRCh38_gencode_v37_CTAT_lib_Mar012021.plug-n-play.tar.gz - - rm GRCh38_gencode_v37_CTAT_lib_Mar012021.plug-n-play.tar.gz - - mv */ctat_genome_lib_build_dir . - """ - - stub: - """ - mkdir ctat_genome_lib_build_dir - touch ref_annot.cdna.fa - cat <<-END_VERSIONS > versions.yml - "${task.process}": - STAR-Fusion: \$(STAR-Fusion --version 2>&1 | grep -i 'version' | sed 's/STAR-Fusion version: //') - END_VERSIONS - """ -} diff --git a/modules/local/starfusion/download/meta.yml b/modules/local/starfusion/download/meta.yml deleted file mode 100644 index 24e842520..000000000 --- a/modules/local/starfusion/download/meta.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: starfusion_downloadgenome -description: Download STAR-fusion genome resource required to run STAR-Fusion caller -keywords: - - downoad -tools: - - star-fusion: - description: Fusion calling algorithm for RNAseq data - homepage: https://github.com/STAR-Fusion/ - documentation: https://github.com/STAR-Fusion/STAR-Fusion/wiki/installing-star-fusion - tool_dev_url: https://github.com/STAR-Fusion/STAR-Fusion - doi: "10.1186/s13059-019-1842-9" - licence: ["GPL v3"] - -output: - - reference: - type: directory - description: Genome resource path - pattern: "star-fusion-genome" - - gtf: - type: file - description: genome gtf file - pattern: "*.{gtf}" - -authors: - - "@praveenraj2018,@rannick" diff --git a/modules/local/uscs/custom_gtftogenepred/main.nf b/modules/local/uscs/custom_gtftogenepred/main.nf deleted file mode 100644 index 78fcbd296..000000000 --- a/modules/local/uscs/custom_gtftogenepred/main.nf +++ /dev/null @@ -1,37 +0,0 @@ -process GTF_TO_REFFLAT { - label 'process_low' - - conda "bioconda::ucsc-gtftogenepred=377" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/ucsc-gtftogenepred:377--ha8a8165_5' : - 'quay.io/biocontainers/ucsc-gtftogenepred:377--ha8a8165_5' }" - - input: - tuple val(meta), path (gtf) - - output: - path('*.refflat'), emit: refflat - - script: - def genepred = gtf + '.genepred' - def refflat = gtf + '.refflat' - """ - gtfToGenePred -genePredExt -geneNameAsName2 ${gtf} ${genepred} - paste ${genepred} ${genepred} | cut -f12,16-25 > ${refflat} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gtfToGenePred: 377 - END_VERSIONS - """ - - stub: - def refflat = gtf + '.refflat' - """ - touch ${refflat} - cat <<-END_VERSIONS > versions.yml - "${task.process}": - gtfToGenePred: 377 - END_VERSIONS - """ -} diff --git a/modules/local/uscs/custom_gtftogenepred/meta.yml b/modules/local/uscs/custom_gtftogenepred/meta.yml deleted file mode 100644 index 09711f438..000000000 --- a/modules/local/uscs/custom_gtftogenepred/meta.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: gtf_to_refflat -description: generate gene annotations in refFlat form - - gtftorefflat -tools: - - gtf_to_refflat: - description: generate gene annotations in refFlat form - homepage: https://pachterlab.github.io/kallisto/ - documentation: https://pachterlab.github.io/kallisto/manual - tool_dev_url: https://github.com/pachterlab/kallisto - doi: "" - licence: ["BSD-2-Clause"] - -input: - - fasta: - type: file - description: genome fasta file - pattern: "*.{fasta*}" - - reference: - type: directory - description: Path to kallisto index - pattern: "*" - -output: - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - fusions: - type: file - description: fusions - pattern: "*.txt" - -authors: - - "@rannick" diff --git a/modules/local/vcf_collect/main.nf b/modules/local/vcf_collect/main.nf index 3ede7936c..e43a11711 100644 --- a/modules/local/vcf_collect/main.nf +++ b/modules/local/vcf_collect/main.nf @@ -5,7 +5,7 @@ process VCF_COLLECT { conda "conda-forge::pandas=1.5.2" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/pandas:1.5.2' : - 'quay.io/biocontainers/pandas:1.5.2' }" + 'biocontainers/pandas:1.5.2' }" input: tuple val(meta), path(fusioninspector_tsv), path(fusioninspector_gtf_tsv), path(fusionreport_report), path(fusionreport_csv) @@ -14,7 +14,7 @@ process VCF_COLLECT { output: path "versions.yml" , emit: versions - tuple val(meta), path("*vcf.gz") , emit: vcf + tuple val(meta), path("*vcf") , emit: vcf when: task.ext.when == null || task.ext.when @@ -23,11 +23,11 @@ process VCF_COLLECT { def prefix = task.ext.prefix ?: "${meta.id}" """ vcf_collect.py --fusioninspector $fusioninspector_tsv --fusionreport $fusionreport_report --fusioninspector_gtf $fusioninspector_gtf_tsv --fusionreport_csv $fusionreport_csv --hgnc $hgnc_ref --sample ${prefix} --out ${prefix}_fusion_data.vcf - gzip ${prefix}_fusion_data.vcf cat <<-END_VERSIONS > versions.yml "${task.process}": python: \$(python --version | sed 's/Python //g') + vcf_collect: 0.1 HGNC DB retrieval: \$(cat $hgnc_date) END_VERSIONS """ @@ -35,11 +35,12 @@ process VCF_COLLECT { stub: def prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}.vcf + touch ${prefix}_fusion_data.vcf cat <<-END_VERSIONS > versions.yml "${task.process}": python: \$(python --version | sed 's/Python //g') + vcf_collect: 0.1 END_VERSIONS """ } diff --git a/modules/local/vcf_collect/tests/main.nf.test b/modules/local/vcf_collect/tests/main.nf.test new file mode 100644 index 000000000..559849301 --- /dev/null +++ b/modules/local/vcf_collect/tests/main.nf.test @@ -0,0 +1,56 @@ +nextflow_process { + + name "Test Process VCF_COLLECT" + script "../main.nf" + process "VCF_COLLECT" + + test("VCF_COLLECT - human - fusionreport - fusioninspector") { + + when { + process { + """ + input[0] = Channel.of([ id:'test_sample' ]) + .combine(Channel.of(file("https://github.com/nf-core/test-datasets/raw/rnafusion/testdata/human/test.FusionInspector.fusions.abridged.tsv", checkIfExists: true))) + .combine(Channel.of(file("https://github.com/nf-core/test-datasets/raw/rnafusion/testdata/human/test.tsv", checkIfExists: true))) + .combine(Channel.of(file("https://github.com/nf-core/test-datasets/raw/rnafusion/testdata/human/fusionreport/test_sample_fusionreport_index.html", checkIfExists: true))) + .combine(Channel.of(file("https://github.com/nf-core/test-datasets/raw/rnafusion/testdata/human/test.fusions.csv", checkIfExists: true))) + input[1] = [[ id:'hgnc' ], file("https://github.com/nf-core/test-datasets/raw/rnafusion/testdata/reference/hgnc/hgnc_complete_set.txt")] + input[2] = [[ id:'hgnc_timestamp' ], file("https://github.com/nf-core/test-datasets/raw/rnafusion/testdata/reference/hgnc/HGNC-DB-timestamp.txt")] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("VCF_COLLECT - human - fusionreport - fusioninspector - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ id:'test_sample' ]) + .combine(Channel.of(file("https://github.com/nf-core/test-datasets/raw/rnafusion/testdata/human/test.FusionInspector.fusions.abridged.tsv", checkIfExists: true))) + .combine(Channel.of(file("https://github.com/nf-core/test-datasets/raw/rnafusion/testdata/human/test.tsv", checkIfExists: true))) + .combine(Channel.of(file("https://github.com/nf-core/test-datasets/raw/rnafusion/testdata/human/fusionreport/test_sample_fusionreport_index.html", checkIfExists: true))) + .combine(Channel.of(file("https://github.com/nf-core/test-datasets/raw/rnafusion/testdata/human/test.fusions.csv", checkIfExists: true))) + input[1] = [[ id:'hgnc' ], file("https://github.com/nf-core/test-datasets/raw/rnafusion/testdata/reference/hgnc/hgnc_complete_set.txt")] + input[2] = [[ id:'hgnc_timestamp' ], file("https://github.com/nf-core/test-datasets/raw/rnafusion/testdata/reference/hgnc/HGNC-DB-timestamp.txt")] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/local/vcf_collect/tests/main.nf.test.snap b/modules/local/vcf_collect/tests/main.nf.test.snap new file mode 100644 index 000000000..1e203d0c1 --- /dev/null +++ b/modules/local/vcf_collect/tests/main.nf.test.snap @@ -0,0 +1,68 @@ +{ + "VCF_COLLECT - human - fusionreport - fusioninspector - stub": { + "content": [ + { + "0": [ + "versions.yml:md5,0e9daf1986d2c5f0ce94eb1ca2cb4fed" + ], + "1": [ + [ + { + "id": "test_sample" + }, + "test_sample_fusion_data.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "test_sample" + }, + "test_sample_fusion_data.vcf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,0e9daf1986d2c5f0ce94eb1ca2cb4fed" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-12T20:45:40.474082615" + }, + "VCF_COLLECT - human - fusionreport - fusioninspector": { + "content": [ + { + "0": [ + "versions.yml:md5,646edd06d506d0b35d32ee663bafb804" + ], + "1": [ + [ + { + "id": "test_sample" + }, + "test_sample_fusion_data.vcf:md5,0ae5bd8c5b24ffbec7ae617feec91583" + ] + ], + "vcf": [ + [ + { + "id": "test_sample" + }, + "test_sample_fusion_data.vcf:md5,0ae5bd8c5b24ffbec7ae617feec91583" + ] + ], + "versions": [ + "versions.yml:md5,646edd06d506d0b35d32ee663bafb804" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-12T20:45:25.283350308" + } +} diff --git a/modules/nf-core/agat/convertgff2bed/environment.yml b/modules/nf-core/agat/convertgff2bed/environment.yml new file mode 100644 index 000000000..0e342bfda --- /dev/null +++ b/modules/nf-core/agat/convertgff2bed/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - "bioconda::agat=1.5.1" diff --git a/modules/nf-core/agat/convertgff2bed/main.nf b/modules/nf-core/agat/convertgff2bed/main.nf new file mode 100644 index 000000000..39ed1f617 --- /dev/null +++ b/modules/nf-core/agat/convertgff2bed/main.nf @@ -0,0 +1,46 @@ +process AGAT_CONVERTGFF2BED { + 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/03/033434db0bd6ba28660401e1059286f36641fd8ce55faa11973fe5eaf312adcd/data' : + 'community.wave.seqera.io/library/agat:1.5.1--ae3cd948ce5e9795' }" + + input: + tuple val(meta), path(gff) + + output: + tuple val(meta), path("*.bed") , emit: bed + 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}" + """ + agat_convert_sp_gff2bed.pl \\ + --gff ${gff} \\ + -o ${prefix}.bed \\ + ${args} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + agat: \$(agat_convert_sp_gff2bed.pl --help | sed -n 's/.*(AGAT) - Version: \\(.*\\) .*/\\1/p') + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.bed + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + agat: \$(agat_convert_sp_gff2bed.pl --help | sed -n 's/.*(AGAT) - Version: \\(.*\\) .*/\\1/p') + END_VERSIONS + """ +} diff --git a/modules/nf-core/agat/convertgff2bed/meta.yml b/modules/nf-core/agat/convertgff2bed/meta.yml new file mode 100644 index 000000000..1e1108f53 --- /dev/null +++ b/modules/nf-core/agat/convertgff2bed/meta.yml @@ -0,0 +1,57 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "agat_convertgff2bed" +description: Takes a GFF3 file and converts to a bed12 file +keywords: + - genome + - bed + - gff + - conversion +tools: + - "agat": + description: "Another Gff Analysis Toolkit (AGAT). Suite of tools to handle gene + annotations in any GTF/GFF format." + homepage: "https://agat.readthedocs.io/en/latest/" + documentation: "https://agat.readthedocs.io/en/latest/" + tool_dev_url: "https://github.com/NBISweden/AGAT" + doi: "10.5281/zenodo.3552717" + licence: ["GPL v3"] + identifier: biotools:AGAT + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - gff: + type: file + description: Input GFF3 file + pattern: "*.{gff}" + ontologies: + - edam: "http://edamontology.org/format_1975" # GFF3 + +output: + bed: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.bed": + type: file + description: Output bed12 file + pattern: "*.bed" + ontologies: + - edam: "http://edamontology.org/format_3586" # bed12 + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: "http://edamontology.org/format_3750" # YAML + +authors: + - "@atrigila" +maintainers: + - "@atrigila" diff --git a/modules/nf-core/agat/convertgff2bed/tests/main.nf.test b/modules/nf-core/agat/convertgff2bed/tests/main.nf.test new file mode 100644 index 000000000..70402a803 --- /dev/null +++ b/modules/nf-core/agat/convertgff2bed/tests/main.nf.test @@ -0,0 +1,58 @@ +nextflow_process { + + name "Test Process AGAT_CONVERTGFF2BED" + script "../main.nf" + process "AGAT_CONVERTGFF2BED" + + tag "modules" + tag "modules_nfcore" + tag "agat" + tag "agat/convertgff2bed" + + test("sarscov2 genome - gff3") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/sarscov2/genome/genome.gff3", checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 genome - gff3 - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/sarscov2/genome/genome.gff3", checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} \ No newline at end of file diff --git a/modules/nf-core/agat/convertgff2bed/tests/main.nf.test.snap b/modules/nf-core/agat/convertgff2bed/tests/main.nf.test.snap new file mode 100644 index 000000000..455a78c7c --- /dev/null +++ b/modules/nf-core/agat/convertgff2bed/tests/main.nf.test.snap @@ -0,0 +1,72 @@ +{ + "sarscov2 genome - gff3": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bed:md5,d424ee1b9d9982f129412f491fca709e" + ] + ], + "1": [ + "versions.yml:md5,7e74ce85271b5cc6b522c049c3902f4f" + ], + "bed": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bed:md5,d424ee1b9d9982f129412f491fca709e" + ] + ], + "versions": [ + "versions.yml:md5,7e74ce85271b5cc6b522c049c3902f4f" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-01T15:44:10.214333104" + }, + "sarscov2 genome - gff3 - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,7e74ce85271b5cc6b522c049c3902f4f" + ], + "bed": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,7e74ce85271b5cc6b522c049c3902f4f" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-01T15:44:21.236419314" + } +} \ No newline at end of file diff --git a/modules/nf-core/agat/convertgff2bed/tests/nextflow.config b/modules/nf-core/agat/convertgff2bed/tests/nextflow.config new file mode 100644 index 000000000..b465c0ea0 --- /dev/null +++ b/modules/nf-core/agat/convertgff2bed/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: CONVERTGFF2BED { + ext.args = "-f gene,mRNA,exon,CDS,five_prime_UTR,three_prime_UTR" + } +} diff --git a/modules/nf-core/agat/convertspgff2tsv/environment.yml b/modules/nf-core/agat/convertspgff2tsv/environment.yml index b5fdf3dbb..072565894 100644 --- a/modules/nf-core/agat/convertspgff2tsv/environment.yml +++ b/modules/nf-core/agat/convertspgff2tsv/environment.yml @@ -1,7 +1,7 @@ -name: agat_convertspgff2tsv +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults dependencies: - - bioconda::agat=1.2.0 + - bioconda::agat=1.4.2 diff --git a/modules/nf-core/agat/convertspgff2tsv/main.nf b/modules/nf-core/agat/convertspgff2tsv/main.nf index cef483600..d2b9b8608 100644 --- a/modules/nf-core/agat/convertspgff2tsv/main.nf +++ b/modules/nf-core/agat/convertspgff2tsv/main.nf @@ -4,8 +4,8 @@ process AGAT_CONVERTSPGFF2TSV { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/agat:1.2.0--pl5321hdfd78af_0' : - 'biocontainers/agat:1.2.0--pl5321hdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/agat:1.4.2--pl5321hdfd78af_0' : + 'biocontainers/agat:1.4.2--pl5321hdfd78af_0' }" input: tuple val(meta), path(gff) @@ -18,18 +18,28 @@ process AGAT_CONVERTSPGFF2TSV { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' + def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - """ agat_convert_sp_gff2tsv.pl \\ - --gff $gff \\ + --gff ${gff} \\ --output ${prefix}.tsv \\ - $args + ${args} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + agat: \$(agat_convert_sp_gff2tsv.pl --help | sed -n 's/.*(AGAT) - Version: \\(.*\\) .*/\\1/p') + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.tsv cat <<-END_VERSIONS > versions.yml "${task.process}": - agat: \$(agat_convert_sp_gff2tsv.pl --help | sed '3!d; s/.*v//' | sed 's/ .*//') + agat: \$(agat_convert_sp_gff2tsv.pl --help | sed -n 's/.*(AGAT) - Version: \\(.*\\) .*/\\1/p') END_VERSIONS """ } diff --git a/modules/nf-core/agat/convertspgff2tsv/meta.yml b/modules/nf-core/agat/convertspgff2tsv/meta.yml index f5865dfe7..4c80ee890 100644 --- a/modules/nf-core/agat/convertspgff2tsv/meta.yml +++ b/modules/nf-core/agat/convertspgff2tsv/meta.yml @@ -9,30 +9,46 @@ keywords: - tsv tools: - agat: - description: "AGAT is a toolkit for manipulation and getting information from GFF/GTF files" + description: "AGAT is a toolkit for manipulation and getting information from + GFF/GTF files" homepage: "https://github.com/NBISweden/AGAT" documentation: "https://agat.readthedocs.io/" tool_dev_url: "https://github.com/NBISweden/AGAT" doi: "10.5281/zenodo.3552717" licence: ["GPL v3"] + identifier: biotools:AGAT input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - gff: - type: file - description: Annotation file in GFF3/GTF format - pattern: "*.{gff, gtf}" + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - gff: + type: file + description: Annotation file in GFF3/GTF format + pattern: "*.{gff, gtf}" + ontologies: + - edam: "http://edamontology.org/format_1975" # GFF3 + - edam: "http://edamontology.org/format_2306" # GTF output: - - tsv: - type: file - description: Annotation file in TSV format - pattern: "*.{gtf}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + tsv: + - - meta: + type: map + description: Groovy Map containing sample information + - "*.tsv": + type: file + description: Annotation file in TSV format + pattern: "*.{gtf}" + ontologies: + - edam: http://edamontology.org/format_2306 # GTF + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: "http://edamontology.org/format_3750" # YAML authors: - "@rannick" +maintainers: + - "@gallvp" diff --git a/modules/nf-core/agat/convertspgff2tsv/tests/main.nf.test b/modules/nf-core/agat/convertspgff2tsv/tests/main.nf.test new file mode 100644 index 000000000..6a2e8942e --- /dev/null +++ b/modules/nf-core/agat/convertspgff2tsv/tests/main.nf.test @@ -0,0 +1,59 @@ +nextflow_process { + + name "Test Process AGAT_CONVERTSPGFF2TSV" + script "../main.nf" + process "AGAT_CONVERTSPGFF2TSV" + + tag "modules" + tag "modules_nfcore" + tag "agat" + tag "agat/convertspgff2tsv" + + test("sarscov2 - genome [gff3]") { + + when { + process { + """ + input[0] = [ + [ id: 'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.gff3', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - genome [gff3] - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id: 'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.gff3', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.tsv.collect { file(it[1]).getName() } + + process.out.versions).match() } + ) + } + + } + +} diff --git a/modules/nf-core/agat/convertspgff2tsv/tests/main.nf.test.snap b/modules/nf-core/agat/convertspgff2tsv/tests/main.nf.test.snap new file mode 100644 index 000000000..50a428d62 --- /dev/null +++ b/modules/nf-core/agat/convertspgff2tsv/tests/main.nf.test.snap @@ -0,0 +1,48 @@ +{ + "sarscov2 - genome [gff3] - stub": { + "content": [ + [ + "test.tsv", + "versions.yml:md5,1866660991c9d87acc28236b9d026438" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.10.3" + }, + "timestamp": "2025-01-15T13:13:51.099041" + }, + "sarscov2 - genome [gff3]": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.tsv:md5,8373d2035689d23694f87606116cdccd" + ] + ], + "1": [ + "versions.yml:md5,1866660991c9d87acc28236b9d026438" + ], + "tsv": [ + [ + { + "id": "test" + }, + "test.tsv:md5,8373d2035689d23694f87606116cdccd" + ] + ], + "versions": [ + "versions.yml:md5,1866660991c9d87acc28236b9d026438" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.10.3" + }, + "timestamp": "2025-01-15T13:13:44.904263" + } +} \ No newline at end of file diff --git a/modules/nf-core/arriba/arriba/environment.yml b/modules/nf-core/arriba/arriba/environment.yml new file mode 100644 index 000000000..b30731312 --- /dev/null +++ b/modules/nf-core/arriba/arriba/environment.yml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::arriba=2.5.0 + - conda-forge::wget=1.21.4 diff --git a/modules/nf-core/arriba/arriba/main.nf b/modules/nf-core/arriba/arriba/main.nf new file mode 100644 index 000000000..bb4b63770 --- /dev/null +++ b/modules/nf-core/arriba/arriba/main.nf @@ -0,0 +1,66 @@ +process ARRIBA_ARRIBA { + tag "$meta.id" + label 'process_medium' + + 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/27/27475cdcdbcc8c0ffb6b5ca8c2e6567dbe490edb96f5df4e8f01f4f95912dcd3/data' : + 'community.wave.seqera.io/library/arriba_wget:a3e48cf793a0b654' }" + + input: + tuple val(meta), path(bam) + tuple val(meta2), path(fasta) + tuple val(meta3), path(gtf) + path(blacklist) + path(known_fusions) + path(cytobands) + path(protein_domains) + + output: + tuple val(meta), path("*.fusions.tsv") , emit: fusions + tuple val(meta), path("*.fusions.discarded.tsv"), emit: fusions_fail + 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 blacklist_arg = blacklist ? "-b ${blacklist}" : "-f blacklist" + def known_fusions_arg = known_fusions ? "-k ${known_fusions}" : "" + def cytobands_arg = cytobands ? "-d ${cytobands}" : "" + def protein_domains_arg = protein_domains ? "-p ${protein_domains}" : "" + + """ + arriba \\ + -x ${bam} \\ + -a ${fasta} \\ + -g ${gtf} \\ + -o ${prefix}.fusions.tsv \\ + -O ${prefix}.fusions.discarded.tsv \\ + ${blacklist_arg} \\ + ${known_fusions_arg} \\ + ${cytobands_arg} \\ + ${protein_domains_arg} \\ + ${args} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + arriba: \$(arriba -h | grep 'Version:' 2>&1 | sed 's/Version:\s//') + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + echo stub > ${prefix}.fusions.tsv + echo stub > ${prefix}.fusions.discarded.tsv + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + arriba: \$(arriba -h | grep 'Version:' 2>&1 | sed 's/Version:\s//') + END_VERSIONS + """ +} diff --git a/modules/nf-core/arriba/arriba/meta.yml b/modules/nf-core/arriba/arriba/meta.yml new file mode 100644 index 000000000..967f83756 --- /dev/null +++ b/modules/nf-core/arriba/arriba/meta.yml @@ -0,0 +1,108 @@ +name: arriba_arriba +description: Arriba is a command-line tool for the detection of gene fusions from + RNA-Seq data. +keywords: + - fusion + - arriba + - detection + - RNA-Seq +tools: + - arriba: + description: Fast and accurate gene fusion detection from RNA-Seq data + homepage: https://github.com/suhrig/arriba + documentation: https://arriba.readthedocs.io/en/latest/ + tool_dev_url: https://github.com/suhrig/arriba + doi: "10.1101/gr.257246.119" + licence: ["MIT"] + identifier: biotools:Arriba +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: BAM/CRAM/SAM file + pattern: "*.{bam,cram,sam}" + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'test' ] + - fasta: + type: file + description: Assembly FASTA file + pattern: "*.{fasta}" + ontologies: [] + - - meta3: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'test' ] + - gtf: + type: file + description: Annotation GTF file + pattern: "*.{gtf}" + ontologies: [] + - blacklist: + type: file + description: Blacklist file + pattern: "*.{tsv}" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + - known_fusions: + type: file + description: Known fusions file + pattern: "*.{tsv}" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + - cytobands: + type: file + description: Cytobands file + pattern: "*.{tsv}" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + - protein_domains: + type: file + description: Protein domains file + pattern: "*.{gff3}" + ontologies: [] +output: + fusions: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.fusions.tsv": + type: file + description: File contains fusions which pass all of Arriba's filters. + pattern: "*.{fusions.tsv}" + ontologies: [] + fusions_fail: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.fusions.discarded.tsv": + type: file + description: File contains fusions that Arriba classified as an artifact or + that are also observed in healthy tissue. + pattern: "*.{fusions.discarded.tsv}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@praveenraj2018" + - "@rannick" +maintainers: + - "@praveenraj2018" + - "@rannick" diff --git a/modules/nf-core/arriba/arriba/tests/main.nf.test b/modules/nf-core/arriba/arriba/tests/main.nf.test new file mode 100644 index 000000000..b5f404134 --- /dev/null +++ b/modules/nf-core/arriba/arriba/tests/main.nf.test @@ -0,0 +1,128 @@ + +nextflow_process { + + name "Test Process ARRIBA_ARRIBA" + script "../main.nf" + process "ARRIBA_ARRIBA" + + tag "modules" + tag "modules_nfcore" + tag "arriba" + tag "arriba/arriba" + tag "arriba/download" + tag "star/genomegenerate" + tag "star/align" + + test("arriba - homo_sapiens - paired_end") { + config "./nextflow.config" + + setup{ + run("STAR_GENOMEGENERATE") { + script '../../../star/genomegenerate/main.nf' + process { + """ + input[0] = Channel.of([ + [ id:'test_fasta' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[1] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + """ + } + } + + run("STAR_ALIGN") { + script '../../../star/align/main.nf' + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true) + ] + ]) + input[1] = STAR_GENOMEGENERATE.out.index + input[2] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + input[3] = false + input[4] = 'illumina' + input[5] = false + """ + } + } + } + + when { + process { + """ + input[0] = STAR_ALIGN.out.bam + input[1] = Channel.of([ + [ id:'test_fasta' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[2] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + input[3] = [] + + input[4] = [] + + input[5] = [] + + input[6] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("arriba - homo_sapiens - paired_end - stub") { + + options "-stub" + + 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.rna.paired_end.sorted.bam', checkIfExists: true) ] + ]) + input[1] = Channel.of([ + [ id:'test_fasta' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[2] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + input[3] = [] + + input[4] = [] + + input[5] = [] + + input[6] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/arriba/arriba/tests/main.nf.test.snap b/modules/nf-core/arriba/arriba/tests/main.nf.test.snap new file mode 100644 index 000000000..ad3e7aa9c --- /dev/null +++ b/modules/nf-core/arriba/arriba/tests/main.nf.test.snap @@ -0,0 +1,108 @@ +{ + "arriba - homo_sapiens - paired_end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fusions.tsv:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fusions.discarded.tsv:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ], + "2": [ + "versions.yml:md5,d2eb9bb3bd4b21571a6aa2f39f1283af" + ], + "fusions": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fusions.tsv:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ], + "fusions_fail": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fusions.discarded.tsv:md5,f50b84b1db4b83ba62ec1deacc69c260" + ] + ], + "versions": [ + "versions.yml:md5,d2eb9bb3bd4b21571a6aa2f39f1283af" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-07-04T12:35:18.703566" + }, + "arriba - homo_sapiens - paired_end": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fusions.tsv:md5,7c3383f7eb6d79b84b0bd30a7ef02d70" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fusions.discarded.tsv:md5,445cb87a27f063e751f93498cf8d10b5" + ] + ], + "2": [ + "versions.yml:md5,d2eb9bb3bd4b21571a6aa2f39f1283af" + ], + "fusions": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fusions.tsv:md5,7c3383f7eb6d79b84b0bd30a7ef02d70" + ] + ], + "fusions_fail": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fusions.discarded.tsv:md5,445cb87a27f063e751f93498cf8d10b5" + ] + ], + "versions": [ + "versions.yml:md5,d2eb9bb3bd4b21571a6aa2f39f1283af" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-07-22T14:12:04.304647041" + } +} \ No newline at end of file diff --git a/modules/nf-core/arriba/arriba/tests/nextflow.config b/modules/nf-core/arriba/arriba/tests/nextflow.config new file mode 100644 index 000000000..60aac1728 --- /dev/null +++ b/modules/nf-core/arriba/arriba/tests/nextflow.config @@ -0,0 +1,9 @@ +process { + withName: STAR_GENOMEGENERATE { + ext.args = '--genomeSAindexNbases 9' + } + + withName: STAR_ALIGN { + ext.args = '--readFilesCommand zcat --outSAMtype BAM Unsorted --outSAMunmapped Within --outBAMcompression 0 --outFilterMultimapNmax 50 --peOverlapNbasesMin 10 --alignSplicedMateMapLminOverLmate 0.5 --alignSJstitchMismatchNmax 5 -1 5 5 --chimSegmentMin 10 --chimOutType WithinBAM HardClip --chimJunctionOverhangMin 10 --chimScoreDropMax 30 --chimScoreJunctionNonGTAG 0 --chimScoreSeparation 1 --chimSegmentReadGapMax 3 --chimMultimapNmax 50' + } +} diff --git a/modules/nf-core/arriba/main.nf b/modules/nf-core/arriba/main.nf deleted file mode 100644 index 2537d05b8..000000000 --- a/modules/nf-core/arriba/main.nf +++ /dev/null @@ -1,66 +0,0 @@ -process ARRIBA { - tag "$meta.id" - label 'process_medium' - - conda "bioconda::arriba=2.4.0" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/arriba:2.4.0--h0033a41_2' : - 'biocontainers/arriba:2.4.0--h0033a41_2' }" - - input: - tuple val(meta), path(bam) - tuple val(meta2), path(fasta) - tuple val(meta3), path(gtf) - tuple val(meta4), path(blacklist) - tuple val(meta5), path(known_fusions) - tuple val(meta6), path(structural_variants) - tuple val(meta7), path(tags) - tuple val(meta8), path(protein_domains) - - output: - tuple val(meta), path("*.fusions.tsv") , emit: fusions - tuple val(meta), path("*.fusions.discarded.tsv"), emit: fusions_fail - 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 blacklist = blacklist ? "-b $blacklist" : "-f blacklist" - def known_fusions = known_fusions ? "-k $known_fusions" : "" - def structural_variants = structural_variants ? "-d $structual_variants" : "" - def tags = tags ? "-t $tags" : "" - def protein_domains = protein_domains ? "-p $protein_domains" : "" - - """ - arriba \\ - -x $bam \\ - -a $fasta \\ - -g $gtf \\ - -o ${prefix}.fusions.tsv \\ - -O ${prefix}.fusions.discarded.tsv \\ - $blacklist \\ - $known_fusions \\ - $structural_variants \\ - $tags \\ - $protein_domains \\ - $args - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - arriba: \$(arriba -h | grep 'Version:' 2>&1 | sed 's/Version:\s//') - END_VERSIONS - """ - - stub: - def prefix = task.ext.prefix ?: "${meta.id}" - """ - echo stub > ${prefix}.fusions.tsv - echo stub > ${prefix}.fusions.discarded.tsv - - echo "${task.process}:" > versions.yml - echo ' arriba: 2.2.1' >> versions.yml - """ -} diff --git a/modules/nf-core/arriba/meta.yml b/modules/nf-core/arriba/meta.yml deleted file mode 100644 index 85b3a30b5..000000000 --- a/modules/nf-core/arriba/meta.yml +++ /dev/null @@ -1,111 +0,0 @@ -name: arriba -description: Arriba is a command-line tool for the detection of gene fusions from RNA-Seq data. -keywords: - - fusion - - arriba - - detection - - RNA-Seq -tools: - - arriba: - description: Fast and accurate gene fusion detection from RNA-Seq data - homepage: https://github.com/suhrig/arriba - documentation: https://arriba.readthedocs.io/en/latest/ - tool_dev_url: https://github.com/suhrig/arriba - doi: "10.1101/gr.257246.119" - licence: ["MIT"] - -input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: BAM/CRAM/SAM file - pattern: "*.{bam,cram,sam}" - - meta2: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'test' ] - - fasta: - type: file - description: Assembly FASTA file - pattern: "*.{fasta}" - - meta3: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'test' ] - - gtf: - type: file - description: Annotation GTF file - pattern: "*.{gtf}" - - meta4: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'test' ] - - blacklist: - type: file - description: Blacklist file - pattern: "*.{tsv}" - - meta5: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'test' ] - - known_fusions: - type: file - description: Known fusions file - pattern: "*.{tsv}" - - meta6: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'test' ] - - structural_variants: - type: file - description: Structural variants file - pattern: "*.{tsv}" - - meta7: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'test' ] - - tags: - type: file - description: Tags file - pattern: "*.{tsv}" - - meta8: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'test' ] - - protein_domains: - type: file - description: Protein domains file - pattern: "*.{gff3}" - -output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - fusions: - type: file - description: File contains fusions which pass all of Arriba's filters. - pattern: "*.{fusions.tsv}" - - fusions_fail: - type: file - description: File contains fusions that Arriba classified as an artifact or that are also observed in healthy tissue. - pattern: "*.{fusions.discarded.tsv}" - -authors: - - "@praveenraj2018,@rannick" diff --git a/modules/nf-core/arriba/visualisation/environment.yml b/modules/nf-core/arriba/visualisation/environment.yml new file mode 100644 index 000000000..fa3366764 --- /dev/null +++ b/modules/nf-core/arriba/visualisation/environment.yml @@ -0,0 +1,6 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::arriba=2.5.0 + - conda-forge::wget=1.21.4 diff --git a/modules/local/arriba/visualisation/main.nf b/modules/nf-core/arriba/visualisation/main.nf similarity index 51% rename from modules/local/arriba/visualisation/main.nf rename to modules/nf-core/arriba/visualisation/main.nf index cc1201191..a1e2ce8d6 100644 --- a/modules/local/arriba/visualisation/main.nf +++ b/modules/nf-core/arriba/visualisation/main.nf @@ -2,37 +2,38 @@ process ARRIBA_VISUALISATION { tag "$meta.id" label 'process_medium' - conda "bioconda::arriba=2.4.0" + conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/arriba:2.4.0--h0033a41_2' : - 'biocontainers/arriba:2.4.0--h0033a41_2' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/27/27475cdcdbcc8c0ffb6b5ca8c2e6567dbe490edb96f5df4e8f01f4f95912dcd3/data' : + 'community.wave.seqera.io/library/arriba_wget:a3e48cf793a0b654' }" input: - tuple val(meta), path(bam), path(bai), path(fusions) + tuple val(meta) , path(bam), path(bai), path(fusions) tuple val(meta2), path(gtf) tuple val(meta3), path(protein_domains) tuple val(meta4), path(cytobands) output: - tuple val(meta), path("*.pdf") , emit: pdf - path "versions.yml" , emit: versions + tuple val(meta), path("*.pdf"), emit: pdf + path "versions.yml" , emit: versions when: task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def cytobands = cytobands ? " --cytobands=$cytobands" : "" - def prefix = task.ext.prefix ?: "${meta.id}" - def protein_domains = protein_domains ? "--proteinDomains=$protein_domains" : "" + def args = task.ext.args ?: '' + def arg_cytobands = cytobands ? " --cytobands=$cytobands" : "" + def arg_alignment = bam ? " --alignments=$bam" : "" + def arg_protein_domains = protein_domains ? "--proteinDomains=$protein_domains" : "" + def prefix = task.ext.prefix ?: "${meta.id}" """ draw_fusions.R \\ --fusions=$fusions \\ - --alignments=$bam \\ --output=${prefix}.pdf \\ --annotation=${gtf} \\ - $cytobands \\ - $protein_domains \\ + $arg_alignment \\ + $arg_cytobands \\ + $arg_protein_domains \\ $args cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/arriba/visualisation/meta.yml b/modules/nf-core/arriba/visualisation/meta.yml new file mode 100644 index 000000000..fa2a20683 --- /dev/null +++ b/modules/nf-core/arriba/visualisation/meta.yml @@ -0,0 +1,99 @@ +name: arriba_visualisation +description: Arriba is a command-line tool for the detection of gene fusions + from RNA-Seq data. +keywords: + - visualisation + - arriba + - fusion + - RNA-Seq +tools: + - arriba: + description: Fast and accurate gene fusion detection from RNA-Seq data + homepage: https://github.com/suhrig/arriba + documentation: https://arriba.readthedocs.io/en/latest/ + tool_dev_url: https://github.com/suhrig/arriba + doi: "10.1101/gr.257246.119" + licence: ["MIT"] + identifier: biotools:Arriba +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: BAM/CRAM/SAM file + pattern: "*.{bam,cram,sam}" + ontologies: + - edam: "http://edamontology.org/format_2572" # BAM + - edam: "http://edamontology.org/format_3462" # CRAM + - edam: "http://edamontology.org/format_2573" # SAM + - bai: + type: file + description: BAM index file + pattern: "*.bai" + ontologies: + - edam: "http://edamontology.org/format_3327" # BAI + - fusions: + type: file + description: Arriba fusions file + pattern: "*.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + - - meta2: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - gtf: + type: file + description: Annotation GTF file + pattern: "*.gtf" + ontologies: + - edam: "http://edamontology.org/format_2306" # GTF + - - meta3: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - protein_domains: + type: file + description: Protein domain annotation files + pattern: "*.gff3" + ontologies: + - edam: "http://edamontology.org/format_1975" # GFF3 + - - meta4: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - cytobands: + type: file + description: Coordinates of the Giemsa staining bands needed to draw + ideograms + pattern: ".tsv" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV +output: + pdf: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.pdf": + type: file + description: File contains fusions visualisation + pattern: "*.pdf" + ontologies: + - edam: "http://edamontology.org/format_3508" # PDF + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: "http://edamontology.org/format_3750" # YAML +authors: + - "@rannick" diff --git a/modules/nf-core/arriba/visualisation/tests/main.nf.test b/modules/nf-core/arriba/visualisation/tests/main.nf.test new file mode 100644 index 000000000..33b274c01 --- /dev/null +++ b/modules/nf-core/arriba/visualisation/tests/main.nf.test @@ -0,0 +1,184 @@ +nextflow_process { + + name "Test Process ARRIBA_VISUALISATION" + script "../main.nf" + process "ARRIBA_VISUALISATION" + tag "modules" + tag "modules_nfcore" + tag "arriba" + tag "arriba/visualisation" + tag "star/align" + tag "star/genomegenerate" + tag "arriba/arriba" + tag "arriba/download" + + test("ARRIBA_VISUALISATION") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [], + [], + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/rnafusion/testdata/reference/arriba/test_fastqs.arriba.fusions.tsv", checkIfExists: true) + ] + input[1] = [ + [ id:'test_gtf' ], + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/rnafusion/testdata/reference/ensembl/Homo_sapiens.GRCh38.102.chr4.gtf", checkIfExists: true) + ] + input[2] = [ + [ id:'test_protein_domains' ], + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3", checkIfExists: true) + ] + input[3] = [ + [ id:'test_cytobands' ], + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv", checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(file(process.out.pdf[0][1]).length()) }, + { assert snapshot(process.out.versions).match("versions") } + ) + } + } + + test("ARRIBA_VISUALISATION - arriba test") { + config "./nextflow.config" + + setup{ + + run("STAR_GENOMEGENERATE") { + script '../../../star/genomegenerate/main.nf' + process { + """ + input[0] = Channel.of([ + [ id:'test_fasta' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[1] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + """ + } + } + + run("STAR_ALIGN") { + script '../../../star/align/main.nf' + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true) + ] + ]) + input[1] = STAR_GENOMEGENERATE.out.index + input[2] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + input[3] = false + input[4] = 'illumina' + input[5] = false + """ + } + } + + run("ARRIBA_ARRIBA") { + script '../../arriba/main.nf' + process { + """ + input[0] = STAR_ALIGN.out.bam + input[1] = Channel.of([ + [ id:'test_fasta' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[2] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + input[3] = [] + input[4] = [] + input[5] = [] + input[6] = [] + """ + } + } + run("ARRIBA_DOWNLOAD") { + script '../../download/main.nf' + process { + """ + input[0] = 'GRCh38' + """ + } + } + } + + when { + process { + """ + input[0] = ARRIBA_ARRIBA.out.fusions.map { meta, fusions -> [ meta, [], [], fusions ] } + input[1] = [ + [ id:'test_gtf' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) + ] + input[2] = ARRIBA_DOWNLOAD.out.protein_domains.map { protein_domains -> [[ id:'test_protein_domains' ], protein_domains] } + input[3] = ARRIBA_DOWNLOAD.out.cytobands.map { cytobands -> [[ id:'test_cytobands' ], cytobands] } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(file(process.out.pdf[0][1]).length()) }, + { assert snapshot(process.out.versions).match("versions") } + ) + } + } + + test("ARRIBA_VISUALISATION stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file("https://github.com/nf-core/test-datasets/raw/modules/data/genomics/homo_sapiens/illumina/bam/test.paired_end.markduplicates.sorted.bam", checkIfExists: true), + file("https://github.com/nf-core/test-datasets/raw/modules/data/genomics/homo_sapiens/illumina/bam/test.paired_end.markduplicates.sorted.bam.bai", checkIfExists: true), + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/rnafusion/testdata/reference/arriba/test_fastqs.arriba.fusions.tsv", checkIfExists: true) + ] + input[1] = [ + [ id:'test_gtf' ], + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/rnafusion/testdata/reference/ensembl/Homo_sapiens.GRCh38.102.chr4.gtf", checkIfExists: true) + ] + input[2] = [ + [ id:'test_protein_domains' ], + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3", checkIfExists: true) + ] + input[3] = [ + [ id:'test_cytobands' ], + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv", checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} \ No newline at end of file diff --git a/modules/nf-core/arriba/visualisation/tests/main.nf.test.snap b/modules/nf-core/arriba/visualisation/tests/main.nf.test.snap new file mode 100644 index 000000000..c46b1b0e1 --- /dev/null +++ b/modules/nf-core/arriba/visualisation/tests/main.nf.test.snap @@ -0,0 +1,49 @@ +{ + "versions": { + "content": [ + [ + "versions.yml:md5,6f45b05e1e9ad4830266e897f3ee41b7" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-07-22T14:26:51.236386176" + }, + "ARRIBA_VISUALISATION stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,6f45b05e1e9ad4830266e897f3ee41b7" + ], + "pdf": [ + [ + { + "id": "test", + "single_end": false + }, + "test.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,6f45b05e1e9ad4830266e897f3ee41b7" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-07-21T14:05:27.049968298" + } +} \ No newline at end of file diff --git a/modules/nf-core/arriba/visualisation/tests/nextflow.config b/modules/nf-core/arriba/visualisation/tests/nextflow.config new file mode 100644 index 000000000..595437321 --- /dev/null +++ b/modules/nf-core/arriba/visualisation/tests/nextflow.config @@ -0,0 +1,10 @@ +process { + withName: STAR_GENOMEGENERATE { + ext.args = '--genomeSAindexNbases 9' + } + + withName: STAR_ALIGN { + ext.args = '--readFilesCommand zcat --outSAMtype BAM Unsorted --outSAMunmapped Within --outBAMcompression 0 --outFilterMultimapNmax 50 --peOverlapNbasesMin 10 --alignSplicedMateMapLminOverLmate 0.5 --alignSJstitchMismatchNmax 5 -1 5 5 --chimSegmentMin 10 --chimOutType WithinBAM HardClip --chimJunctionOverhangMin 10 --chimScoreDropMax 30 --chimScoreJunctionNonGTAG 0 --chimScoreSeparation 1 --chimSegmentReadGapMax 3 --chimMultimapNmax 50' + } +} + diff --git a/modules/nf-core/bioawk/environment.yml b/modules/nf-core/bioawk/environment.yml new file mode 100644 index 000000000..0be1e105f --- /dev/null +++ b/modules/nf-core/bioawk/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::bioawk=1.0 diff --git a/modules/nf-core/bioawk/main.nf b/modules/nf-core/bioawk/main.nf new file mode 100644 index 000000000..a537dcf4a --- /dev/null +++ b/modules/nf-core/bioawk/main.nf @@ -0,0 +1,38 @@ +process BIOAWK { + 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/bioawk:1.0--h5bf99c6_6': + 'biocontainers/bioawk:1.0--h5bf99c6_6' }" + + input: + tuple val(meta), path(input) + + output: + tuple val(meta), path("*.gz"), emit: output + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' // args is used for the main arguments of the tool + prefix = task.ext.prefix ?: "${meta.id}" + if ("${input}" == "${prefix}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + def VERSION = '1.0' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + """ + bioawk \\ + $args \\ + $input \\ + > ${prefix} + + gzip ${prefix} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + bioawk: $VERSION + END_VERSIONS + """ +} diff --git a/modules/nf-core/bioawk/meta.yml b/modules/nf-core/bioawk/meta.yml new file mode 100644 index 000000000..92b0a13c5 --- /dev/null +++ b/modules/nf-core/bioawk/meta.yml @@ -0,0 +1,58 @@ +name: "bioawk" +description: Bioawk is an extension to Brian Kernighan's awk, adding the support of + several common biological data formats. +keywords: + - bioawk + - fastq + - fasta + - sam + - file manipulation + - awk +tools: + - "bioawk": + description: "BWK awk modified for biological data" + homepage: "https://github.com/lh3/bioawk" + documentation: "https://github.com/lh3/bioawk" + tool_dev_url: "https://github.com/lh3/bioawk" + licence: ["Free software license (https://github.com/lh3/bioawk/blob/master/README.awk#L1)"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - input: + type: file + description: Input sequence biological sequence file (optionally gzipped) to + be manipulated via program specified in `$args`. + pattern: "*.{bed,gff,sam,vcf,fastq,fasta,tab,bed.gz,gff.gz,sam.gz,vcf.gz,fastq.gz,fasta.gz,tab.gz}" + ontologies: + - edam: http://edamontology.org/format_1930 # FASTQ + - edam: http://edamontology.org/format_3475 # TSV +output: + output: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.gz": + type: file + description: | + Manipulated and gzipped version of input sequence file following program specified in `args`. + File name will be what is specified in `$prefix`. Do not include `.gz` suffix in `$prefix`! Output files` will be gzipped for you! + pattern: "*.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@jfy133" +maintainers: + - "@jfy133" diff --git a/modules/nf-core/bioawk/tests/main.nf.test b/modules/nf-core/bioawk/tests/main.nf.test new file mode 100644 index 000000000..270ff1ef3 --- /dev/null +++ b/modules/nf-core/bioawk/tests/main.nf.test @@ -0,0 +1,35 @@ + +nextflow_process { + + name "Test Process BIOAWK" + script "../main.nf" + process "BIOAWK" + config "./nextflow.config" + + tag "modules" + tag "modules_nfcore" + tag "bioawk" + + test("test-bioawk") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + +} diff --git a/modules/nf-core/bioawk/tests/main.nf.test.snap b/modules/nf-core/bioawk/tests/main.nf.test.snap new file mode 100644 index 000000000..fa9b59305 --- /dev/null +++ b/modules/nf-core/bioawk/tests/main.nf.test.snap @@ -0,0 +1,37 @@ +{ + "test-bioawk": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "sample_1.fa.gz:md5,b558dd15d8940373a032a827d490e693" + ] + ], + "1": [ + "versions.yml:md5,5fe88e58a71f10551df56518c35ba91a" + ], + "output": [ + [ + { + "id": "test", + "single_end": false + }, + "sample_1.fa.gz:md5,b558dd15d8940373a032a827d490e693" + ] + ], + "versions": [ + "versions.yml:md5,5fe88e58a71f10551df56518c35ba91a" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-28T10:24:46.397249" + } +} \ No newline at end of file diff --git a/modules/nf-core/bioawk/tests/nextflow.config b/modules/nf-core/bioawk/tests/nextflow.config new file mode 100644 index 000000000..5ef017d97 --- /dev/null +++ b/modules/nf-core/bioawk/tests/nextflow.config @@ -0,0 +1,6 @@ +process { + withName: BIOAWK { + ext.args = "-c fastx \'{print \">\" \$name ORS length(\$seq)}\'" + ext.prefix = "sample_1.fa" + } +} diff --git a/modules/nf-core/cat/cat/environment.yml b/modules/nf-core/cat/cat/environment.yml index 17a04ef23..50c2059af 100644 --- a/modules/nf-core/cat/cat/environment.yml +++ b/modules/nf-core/cat/cat/environment.yml @@ -1,7 +1,7 @@ -name: cat_cat +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults dependencies: - conda-forge::pigz=2.3.4 diff --git a/modules/nf-core/cat/cat/main.nf b/modules/nf-core/cat/cat/main.nf index 4264a92cc..2862c64cd 100644 --- a/modules/nf-core/cat/cat/main.nf +++ b/modules/nf-core/cat/cat/main.nf @@ -22,6 +22,8 @@ process CAT_CAT { def args2 = task.ext.args2 ?: '' def file_list = files_in.collect { it.toString() } + // choose appropriate concatenation tool depending on input and output format + // | input | output | command1 | command2 | // |-----------|------------|----------|----------| // | gzipped | gzipped | cat | | @@ -30,11 +32,15 @@ process CAT_CAT { // | ungzipped | gzipped | cat | pigz | // Use input file ending as default - prefix = task.ext.prefix ?: "${meta.id}${file_list[0].substring(file_list[0].lastIndexOf('.'))}" + prefix = task.ext.prefix ?: "${meta.id}${getFileSuffix(file_list[0])}" out_zip = prefix.endsWith('.gz') in_zip = file_list[0].endsWith('.gz') command1 = (in_zip && !out_zip) ? 'zcat' : 'cat' command2 = (!in_zip && out_zip) ? "| pigz -c -p $task.cpus $args2" : '' + if(file_list.contains(prefix.trim())) { + error "The name of the input file can't be the same as for the output prefix in the " + + "module CAT_CAT (currently `$prefix`). Please choose a different one." + } """ $command1 \\ $args \\ @@ -49,8 +55,12 @@ process CAT_CAT { """ stub: - def file_list = files_in.collect { it.toString() } - prefix = task.ext.prefix ?: "${meta.id}${file_list[0].substring(file_list[0].lastIndexOf('.'))}" + def file_list = files_in.collect { it.toString() } + prefix = task.ext.prefix ?: "${meta.id}${file_list[0].substring(file_list[0].lastIndexOf('.'))}" + if(file_list.contains(prefix.trim())) { + error "The name of the input file can't be the same as for the output prefix in the " + + "module CAT_CAT (currently `$prefix`). Please choose a different one." + } """ touch $prefix @@ -60,3 +70,9 @@ process CAT_CAT { END_VERSIONS """ } + +// for .gz files also include the second to last extension if it is present. E.g., .fasta.gz +def getFileSuffix(filename) { + def match = filename =~ /^.*?((\.\w{1,5})?(\.\w{1,5}\.gz$))/ + return match ? match[0][1] : filename.substring(filename.lastIndexOf('.')) +} diff --git a/modules/nf-core/cat/cat/meta.yml b/modules/nf-core/cat/cat/meta.yml index 00a8db0bc..2a9284d7f 100644 --- a/modules/nf-core/cat/cat/meta.yml +++ b/modules/nf-core/cat/cat/meta.yml @@ -9,25 +9,35 @@ tools: description: Just concatenation documentation: https://man7.org/linux/man-pages/man1/cat.1.html licence: ["GPL-3.0-or-later"] + identifier: "" input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - files_in: - type: file - description: List of compressed / uncompressed files - pattern: "*" + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - files_in: + type: file + description: List of compressed / uncompressed files + pattern: "*" + ontologies: [] output: - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - file_out: - type: file - description: Concatenated file. Will be gzipped if file_out ends with ".gz" - pattern: "${file_out}" + file_out: + - - meta: + type: map + description: Groovy Map containing sample information + - ${prefix}: + type: file + description: Concatenated file. Will be gzipped if file_out ends with ".gz" + pattern: "${file_out}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@erikrikarddaniel" - "@FriederikeHanssen" diff --git a/modules/nf-core/cat/cat/tests/main.nf.test b/modules/nf-core/cat/cat/tests/main.nf.test index 5766daafb..9cb161788 100644 --- a/modules/nf-core/cat/cat/tests/main.nf.test +++ b/modules/nf-core/cat/cat/tests/main.nf.test @@ -8,6 +8,33 @@ nextflow_process { tag "cat" tag "cat/cat" + test("test_cat_name_conflict") { + when { + params { + outdir = "${outputDir}" + } + process { + """ + input[0] = + [ + [ id:'genome', single_end:true ], + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.sizes', checkIfExists: true) + ] + ] + """ + } + } + then { + assertAll( + { assert !process.success }, + { assert process.stdout.toString().contains("The name of the input file can't be the same as for the output prefix") }, + { assert snapshot(process.out.versions).match() } + ) + } + } + test("test_cat_unzipped_unzipped") { when { params { @@ -19,8 +46,8 @@ nextflow_process { [ [ id:'test', single_end:true ], [ - file(params.test_data['sarscov2']['genome']['genome_fasta'], checkIfExists: true), - file(params.test_data['sarscov2']['genome']['genome_sizes'], checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.sizes', checkIfExists: true) ] ] """ @@ -46,8 +73,8 @@ nextflow_process { [ [ id:'test', single_end:true ], [ - file(params.test_data['sarscov2']['genome']['genome_gff3_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['genome']['contigs_genome_maf_gz'], checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.gff3.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/alignment/last/contigs.genome.maf.gz', checkIfExists: true) ] ] """ @@ -57,8 +84,12 @@ nextflow_process { def lines = path(process.out.file_out.get(0).get(1)).linesGzip assertAll( { assert process.success }, - { assert snapshot(lines[0..5]).match("test_cat_zipped_zipped_lines") }, - { assert snapshot(lines.size()).match("test_cat_zipped_zipped_size")} + { assert snapshot( + lines[0..5], + lines.size(), + process.out.versions + ).match() + } ) } } @@ -76,8 +107,8 @@ nextflow_process { [ [ id:'test', single_end:true ], [ - file(params.test_data['sarscov2']['genome']['genome_gff3_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['genome']['contigs_genome_maf_gz'], checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.gff3.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/alignment/last/contigs.genome.maf.gz', checkIfExists: true) ] ] """ @@ -105,8 +136,8 @@ nextflow_process { [ [ id:'test', single_end:true ], [ - file(params.test_data['sarscov2']['genome']['genome_fasta'], checkIfExists: true), - file(params.test_data['sarscov2']['genome']['genome_sizes'], checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.sizes', checkIfExists: true) ] ] """ @@ -116,8 +147,12 @@ nextflow_process { def lines = path(process.out.file_out.get(0).get(1)).linesGzip assertAll( { assert process.success }, - { assert snapshot(lines[0..5]).match("test_cat_unzipped_zipped_lines") }, - { assert snapshot(lines.size()).match("test_cat_unzipped_zipped_size")} + { assert snapshot( + lines[0..5], + lines.size(), + process.out.versions + ).match() + } ) } } @@ -134,7 +169,7 @@ nextflow_process { [ [ id:'test', single_end:true ], [ - file(params.test_data['sarscov2']['genome']['genome_fasta'], checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] ] """ @@ -144,10 +179,13 @@ nextflow_process { def lines = path(process.out.file_out.get(0).get(1)).linesGzip assertAll( { assert process.success }, - { assert snapshot(lines[0..5]).match("test_cat_one_file_unzipped_zipped_lines") }, - { assert snapshot(lines.size()).match("test_cat_one_file_unzipped_zipped_size")} + { assert snapshot( + lines[0..5], + lines.size(), + process.out.versions + ).match() + } ) } } } - diff --git a/modules/nf-core/cat/cat/tests/main.nf.test.snap b/modules/nf-core/cat/cat/tests/main.nf.test.snap index 423571ba2..b7623ee65 100644 --- a/modules/nf-core/cat/cat/tests/main.nf.test.snap +++ b/modules/nf-core/cat/cat/tests/main.nf.test.snap @@ -1,10 +1,4 @@ { - "test_cat_unzipped_zipped_size": { - "content": [ - 375 - ], - "timestamp": "2023-10-16T14:33:08.049445686" - }, "test_cat_unzipped_unzipped": { "content": [ { @@ -34,6 +28,10 @@ ] } ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, "timestamp": "2023-10-16T14:32:18.500464399" }, "test_cat_zipped_unzipped": { @@ -65,9 +63,13 @@ ] } ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, "timestamp": "2023-10-16T14:32:49.642741302" }, - "test_cat_zipped_zipped_lines": { + "test_cat_zipped_zipped": { "content": [ [ "MT192765.1\tGenbank\ttranscript\t259\t29667\t.\t+\t.\tID=unknown_transcript_1;geneID=orf1ab;gene_name=orf1ab", @@ -76,11 +78,31 @@ "MT192765.1\tGenbank\tCDS\t13461\t21548\t.\t+\t0\tParent=unknown_transcript_1;exception=\"ribosomal slippage\";gbkey=CDS;gene=orf1ab;note=\"pp1ab;translated=by -1 ribosomal frameshift\";product=\"orf1ab polyprotein\";protein_id=QIK50426.1", "MT192765.1\tGenbank\tCDS\t21556\t25377\t.\t+\t0\tParent=unknown_transcript_1;gbkey=CDS;gene=S;note=\"structural protein\";product=\"surface glycoprotein\";protein_id=QIK50427.1", "MT192765.1\tGenbank\tgene\t21556\t25377\t.\t+\t.\tParent=unknown_transcript_1" + ], + 78, + [ + "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:51:46.802978" + }, + "test_cat_name_conflict": { + "content": [ + [ + ] ], - "timestamp": "2023-10-16T14:32:33.629048645" + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:51:29.45394" }, - "test_cat_unzipped_zipped_lines": { + "test_cat_one_file_unzipped_zipped": { "content": [ [ ">MT192765.1 Severe acute respiratory syndrome coronavirus 2 isolate SARS-CoV-2/human/USA/PC00101P/2020, complete genome", @@ -89,11 +111,19 @@ "TAACTCGTCTATCTTCTGCAGGCTGCTTACGGTTTCGTCCGTGTTGCAGCCGATCATCAGCACATCTAGGTTTTGTCCGG", "GTGTGACCGAAAGGTAAGATGGAGAGCCTTGTCCCTGGTTTCAACGAGAAAACACACGTCCAACTCAGTTTGCCTGTTTT", "ACAGGTTCGCGACGTGCTCGTACGTGGCTTTGGAGACTCCGTGGAGGAGGTCTTATCAGAGGCACGTCAACATCTTAAAG" + ], + 374, + [ + "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" ] ], - "timestamp": "2023-10-16T14:33:08.038830506" + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:52:02.774016" }, - "test_cat_one_file_unzipped_zipped_lines": { + "test_cat_unzipped_zipped": { "content": [ [ ">MT192765.1 Severe acute respiratory syndrome coronavirus 2 isolate SARS-CoV-2/human/USA/PC00101P/2020, complete genome", @@ -102,20 +132,16 @@ "TAACTCGTCTATCTTCTGCAGGCTGCTTACGGTTTCGTCCGTGTTGCAGCCGATCATCAGCACATCTAGGTTTTGTCCGG", "GTGTGACCGAAAGGTAAGATGGAGAGCCTTGTCCCTGGTTTCAACGAGAAAACACACGTCCAACTCAGTTTGCCTGTTTT", "ACAGGTTCGCGACGTGCTCGTACGTGGCTTTGGAGACTCCGTGGAGGAGGTCTTATCAGAGGCACGTCAACATCTTAAAG" + ], + 375, + [ + "versions.yml:md5,115ed6177ebcff24eb99d503fa5ef894" ] ], - "timestamp": "2023-10-16T14:33:21.39642399" - }, - "test_cat_zipped_zipped_size": { - "content": [ - 78 - ], - "timestamp": "2023-10-16T14:32:33.641869244" - }, - "test_cat_one_file_unzipped_zipped_size": { - "content": [ - 374 - ], - "timestamp": "2023-10-16T14:33:21.4094373" + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:51:57.581523" } } \ No newline at end of file diff --git a/modules/nf-core/cat/cat/tests/tags.yml b/modules/nf-core/cat/cat/tests/tags.yml deleted file mode 100644 index 37b578f52..000000000 --- a/modules/nf-core/cat/cat/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -cat/cat: - - modules/nf-core/cat/cat/** diff --git a/modules/nf-core/cat/fastq/environment.yml b/modules/nf-core/cat/fastq/environment.yml index bff93add0..9b926b1ff 100644 --- a/modules/nf-core/cat/fastq/environment.yml +++ b/modules/nf-core/cat/fastq/environment.yml @@ -1,7 +1,12 @@ -name: cat_fastq +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults dependencies: - - conda-forge::sed=4.7 + - 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/cat/fastq/main.nf b/modules/nf-core/cat/fastq/main.nf index 3d963784c..acfb6d0e6 100644 --- a/modules/nf-core/cat/fastq/main.nf +++ b/modules/nf-core/cat/fastq/main.nf @@ -1,26 +1,25 @@ process CAT_FASTQ { - 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(reads, stageAs: "input*/*") output: tuple val(meta), path("*.merged.fastq.gz"), emit: reads - path "versions.yml" , emit: versions + 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 readList = reads instanceof List ? reads.collect{ it.toString() } : [reads.toString()] + def readList = reads instanceof List ? reads.collect { it.toString() } : [reads.toString()] if (meta.single_end) { if (readList.size >= 1) { """ @@ -31,12 +30,15 @@ process CAT_FASTQ { cat: \$(echo \$(cat --version 2>&1) | sed 's/^.*coreutils) //; s/ .*\$//') END_VERSIONS """ + } else { + error("Could not find any FASTQ files to concatenate in the process input") } - } else { + } + else { if (readList.size >= 2) { def read1 = [] def read2 = [] - readList.eachWithIndex{ v, ix -> ( ix & 1 ? read2 : read1 ) << v } + readList.eachWithIndex { v, ix -> (ix & 1 ? read2 : read1) << v } """ cat ${read1.join(' ')} > ${prefix}_1.merged.fastq.gz cat ${read2.join(' ')} > ${prefix}_2.merged.fastq.gz @@ -46,35 +48,41 @@ process CAT_FASTQ { cat: \$(echo \$(cat --version 2>&1) | sed 's/^.*coreutils) //; s/ .*\$//') END_VERSIONS """ + } else { + error("Could not find any FASTQ file pairs to concatenate in the process input") } } stub: def prefix = task.ext.prefix ?: "${meta.id}" - def readList = reads instanceof List ? reads.collect{ it.toString() } : [reads.toString()] + def readList = reads instanceof List ? reads.collect { it.toString() } : [reads.toString()] if (meta.single_end) { - if (readList.size > 1) { + if (readList.size >= 1) { """ - touch ${prefix}.merged.fastq.gz + echo '' | gzip > ${prefix}.merged.fastq.gz cat <<-END_VERSIONS > versions.yml "${task.process}": cat: \$(echo \$(cat --version 2>&1) | sed 's/^.*coreutils) //; s/ .*\$//') END_VERSIONS """ + } else { + error("Could not find any FASTQ files to concatenate in the process input") } - } else { - if (readList.size > 2) { + } + else { + if (readList.size >= 2) { """ - touch ${prefix}_1.merged.fastq.gz - touch ${prefix}_2.merged.fastq.gz + echo '' | gzip > ${prefix}_1.merged.fastq.gz + echo '' | gzip > ${prefix}_2.merged.fastq.gz cat <<-END_VERSIONS > versions.yml "${task.process}": cat: \$(echo \$(cat --version 2>&1) | sed 's/^.*coreutils) //; s/ .*\$//') END_VERSIONS """ + } else { + error("Could not find any FASTQ file pairs to concatenate in the process input") } } - } diff --git a/modules/nf-core/cat/fastq/meta.yml b/modules/nf-core/cat/fastq/meta.yml index db4ac3c79..40d2f627c 100644 --- a/modules/nf-core/cat/fastq/meta.yml +++ b/modules/nf-core/cat/fastq/meta.yml @@ -10,30 +10,37 @@ tools: The cat utility reads files sequentially, writing them to the standard output. documentation: https://www.gnu.org/software/coreutils/manual/html_node/cat-invocation.html licence: ["GPL-3.0-or-later"] + identifier: "" 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 to be concatenated. + - - 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 to be concatenated. + ontologies: [] output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - reads: - type: file - description: Merged fastq file - pattern: "*.{merged.fastq.gz}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + reads: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.merged.fastq.gz": + type: file + description: Merged fastq file + pattern: "*.{merged.fastq.gz}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@joseespinosa" - "@drpatelh" diff --git a/modules/nf-core/cat/fastq/tests/main.nf.test b/modules/nf-core/cat/fastq/tests/main.nf.test index f5f941825..013c1d0f4 100644 --- a/modules/nf-core/cat/fastq/tests/main.nf.test +++ b/modules/nf-core/cat/fastq/tests/main.nf.test @@ -11,16 +11,13 @@ nextflow_process { test("test_cat_fastq_single_end") { when { - params { - outdir = "$outputDir" - } process { """ - input[0] = [ - [ id:'test', single_end:true ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test2_1_fastq_gz'], checkIfExists: true) ] - ] + 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_2.fastq.gz', checkIfExists: true)] + ]) """ } } @@ -28,8 +25,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out.reads).match() }, - { assert path(process.out.versions.get(0)).getText().contains("cat") } + { assert snapshot(process.out).match() } ) } } @@ -37,18 +33,15 @@ nextflow_process { test("test_cat_fastq_paired_end") { when { - params { - outdir = "$outputDir" - } process { """ - input[0] = [ + input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test_2_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test2_1_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test2_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), + 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)] + ]) """ } } @@ -56,8 +49,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out.reads).match() }, - { assert path(process.out.versions.get(0)).getText().contains("cat") } + { assert snapshot(process.out).match() } ) } } @@ -65,16 +57,13 @@ nextflow_process { test("test_cat_fastq_single_end_same_name") { when { - params { - outdir = "$outputDir" - } process { """ - input[0] = [ + input[0] = Channel.of([ [ id:'test', single_end:true ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test_1_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_1.fastq.gz', checkIfExists: true)] + ]) """ } } @@ -82,8 +71,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out.reads).match() }, - { assert path(process.out.versions.get(0)).getText().contains("cat") } + { assert snapshot(process.out).match() } ) } } @@ -91,18 +79,15 @@ nextflow_process { test("test_cat_fastq_paired_end_same_name") { when { - params { - outdir = "$outputDir" - } process { """ - input[0] = [ + input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test_2_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['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), + 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)] + ]) """ } } @@ -110,8 +95,7 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out.reads).match() }, - { assert path(process.out.versions.get(0)).getText().contains("cat") } + { assert snapshot(process.out).match() } ) } } @@ -119,15 +103,112 @@ nextflow_process { test("test_cat_fastq_single_end_single_file") { 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).match() } + ) + } + } + + test("test_cat_fastq_single_end - stub") { + + options "-stub" + + when { + 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), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true)] + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_cat_fastq_paired_end - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_2.fastq.gz', checkIfExists: true)] + ]) + """ } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_cat_fastq_single_end_same_name - stub") { + + options "-stub" + + when { process { """ - input[0] = [ + input[0] = Channel.of([ [ id:'test', single_end:true ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_1_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_1.fastq.gz', checkIfExists: true)] + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_cat_fastq_paired_end_same_name - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true)] + ]) """ } } @@ -135,8 +216,118 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out.reads).match() }, - { assert path(process.out.versions.get(0)).getText().contains("cat") } + { assert snapshot(process.out).match() } + ) + } + } + + test("test_cat_fastq_single_end_single_file - stub") { + + options "-stub" + + when { + 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).match() } + ) + } + } + + test("test_cat_fastq_single_end_no_files") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [] + ]) + """ + } + } + + then { + assertAll( + { assert process.failed }, + { assert snapshot(process.stdout.find { it.contains("-- Check script") }.split(" -- Check script")[0]).match() } + ) + } + } + + test("test_cat_fastq_paired_end_no_files") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [] + ]) + """ + } + } + + then { + assertAll( + { assert process.failed }, + { assert snapshot(process.stdout.find { it.contains("-- Check script") }.split(" -- Check script")[0]).match() } + ) + } + } + + test("test_cat_fastq_single_end_no_files - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [] + ]) + """ + } + } + + then { + assertAll( + { assert process.failed }, + { assert snapshot(process.stdout.find { it.contains("-- Check script") }.split(" -- Check script")[0]).match() } + ) + } + } + + test("test_cat_fastq_paired_end_no_files - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [] + ]) + """ + } + } + + then { + assertAll( + { assert process.failed }, + { assert snapshot(process.stdout.find { it.contains("-- Check script") }.split(" -- Check script")[0]).match() } ) } } diff --git a/modules/nf-core/cat/fastq/tests/main.nf.test.snap b/modules/nf-core/cat/fastq/tests/main.nf.test.snap index ec2342e54..ee5ab3647 100644 --- a/modules/nf-core/cat/fastq/tests/main.nf.test.snap +++ b/modules/nf-core/cat/fastq/tests/main.nf.test.snap @@ -1,78 +1,416 @@ { + "test_cat_fastq_paired_end_no_files - stub": { + "content": [ + " Could not find any FASTQ file pairs to concatenate in the process input" + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:14:51.248685461" + }, + "test_cat_fastq_single_end_single_file": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + "1": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,4161df271f9bfcd25d5845a1e220dbec" + ] + ], + "versions": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:24:04.902821069" + }, + "test_cat_fastq_paired_end_same_name": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22", + "test_2.merged.fastq.gz:md5,a52cab0b840c7178b0ea83df1fdbe8d5" + ] + ] + ], + "1": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22", + "test_2.merged.fastq.gz:md5,a52cab0b840c7178b0ea83df1fdbe8d5" + ] + ] + ], + "versions": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:23:57.476357974" + }, + "test_cat_fastq_paired_end_same_name - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "versions": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:24:34.615815265" + }, "test_cat_fastq_single_end": { "content": [ - [ - [ - { - "id": "test", - "single_end": true - }, - "test.merged.fastq.gz:md5,f9cf5e375f7de81a406144a2c70cc64d" + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,ee314a9bd568d06617171b0c85f508da" + ] + ], + "1": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,ee314a9bd568d06617171b0c85f508da" + ] + ], + "versions": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" ] - ] + } ], - "timestamp": "2023-10-17T23:19:12.990284837" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:23:32.489874386" }, "test_cat_fastq_single_end_same_name": { "content": [ - [ - [ - { - "id": "test", - "single_end": true - }, - "test.merged.fastq.gz:md5,63f817db7a29a03eb538104495556f66" + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22" + ] + ], + "1": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22" + ] + ], + "versions": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" ] - ] + } ], - "timestamp": "2023-10-17T23:19:31.554568147" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:23:49.184759506" }, - "test_cat_fastq_single_end_single_file": { + "test_cat_fastq_single_end - stub": { "content": [ - [ - [ - { - "id": "test", - "single_end": true - }, - "test.merged.fastq.gz:md5,e325ef7deb4023447a1f074e285761af" + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" ] - ] + } ], - "timestamp": "2023-10-17T23:19:49.629360033" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:24:12.857293744" }, - "test_cat_fastq_paired_end_same_name": { + "test_cat_fastq_paired_end_no_files": { + "content": [ + " Could not find any FASTQ file pairs to concatenate in the process input" + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:14:40.806088747" + }, + "test_cat_fastq_single_end_no_files - stub": { "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, + " Could not find any FASTQ files to concatenate in the process input" + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:14:45.852365218" + }, + "test_cat_fastq_single_end_same_name - stub": { + "content": [ + { + "0": [ [ - "test_1.merged.fastq.gz:md5,63f817db7a29a03eb538104495556f66", - "test_2.merged.fastq.gz:md5,fe9f266f43a6fc3dcab690a18419a56e" + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] + ], + "1": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" ] - ] + } ], - "timestamp": "2023-10-17T23:19:40.711617539" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:24:27.816080065" }, "test_cat_fastq_paired_end": { "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22", + "test_2.merged.fastq.gz:md5,a52cab0b840c7178b0ea83df1fdbe8d5" + ] + ] + ], + "1": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,3ad9406595fafec8172368f9cd0b6a22", + "test_2.merged.fastq.gz:md5,a52cab0b840c7178b0ea83df1fdbe8d5" + ] + ] + ], + "versions": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:23:41.739469187" + }, + "test_cat_fastq_single_end_no_files": { + "content": [ + " Could not find any FASTQ files to concatenate in the process input" + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:14:35.695192409" + }, + "test_cat_fastq_paired_end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "versions": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:24:21.178950408" + }, + "test_cat_fastq_single_end_single_file - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" + ], + "reads": [ [ - "test_1.merged.fastq.gz:md5,f9cf5e375f7de81a406144a2c70cc64d", - "test_2.merged.fastq.gz:md5,77c8e966e130d8c6b6ec9be52fcb2bda" + { + "id": "test", + "single_end": true + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] + ], + "versions": [ + "versions.yml:md5,6ef4fd28546a005865b9454bbedbf81a" ] - ] + } ], - "timestamp": "2023-10-18T07:53:20.923560211" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-25T17:24:40.851404993" } } \ No newline at end of file diff --git a/modules/nf-core/cat/fastq/tests/tags.yml b/modules/nf-core/cat/fastq/tests/tags.yml deleted file mode 100644 index 6ac436140..000000000 --- a/modules/nf-core/cat/fastq/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -cat/fastq: - - modules/nf-core/cat/fastq/** diff --git a/modules/nf-core/ctatsplicing/prepgenomelib/ctatsplicing-prepgenomelib.diff b/modules/nf-core/ctatsplicing/prepgenomelib/ctatsplicing-prepgenomelib.diff new file mode 100644 index 000000000..cfb1ff5f4 --- /dev/null +++ b/modules/nf-core/ctatsplicing/prepgenomelib/ctatsplicing-prepgenomelib.diff @@ -0,0 +1,114 @@ +Changes in component 'nf-core/ctatsplicing/prepgenomelib' +'modules/nf-core/ctatsplicing/prepgenomelib/meta.yml' is unchanged +Changes in 'ctatsplicing/prepgenomelib/main.nf': +--- modules/nf-core/ctatsplicing/prepgenomelib/main.nf ++++ modules/nf-core/ctatsplicing/prepgenomelib/main.nf +@@ -1,7 +1,6 @@ + process CTATSPLICING_PREPGENOMELIB { + tag "$meta.id" + label 'process_single' +- stageInMode 'copy' + + container "nf-core/ctatsplicing:0.0.3" + +@@ -10,7 +9,7 @@ + path(cancer_intron_tsv) + + output: +- tuple val(meta), path(genome_lib), emit: reference ++ tuple val(meta), path(genome_lib, includeInputs:true), emit: reference + path "versions.yml" , emit: versions + + when: +@@ -40,85 +39,10 @@ + def prefix = task.ext.prefix ?: "${meta.id}" + def VERSION = '0.0.2' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + """ +- mkdir -p $genome_lib/ +- mkdir -p $genome_lib/ref_genome.fa.star.idx +- mkdir -p $genome_lib/__chkpts +- mkdir -p $genome_lib/cancer_splicing_lib +- touch $genome_lib/ref_genome.fa.star.idx/chrName.txt +- touch $genome_lib/ref_genome.fa.star.idx/exonInfo.tab +- touch $genome_lib/ref_genome.fa.star.idx/SAindex +- touch $genome_lib/ref_genome.fa.star.idx/Genome +- touch $genome_lib/ref_genome.fa.star.idx/geneInfo.tab +- touch $genome_lib/ref_genome.fa.star.idx/sjdbList.out.tab +- touch $genome_lib/ref_genome.fa.star.idx/sjdbInfo.txt +- touch $genome_lib/ref_genome.fa.star.idx/transcriptInfo.tab +- touch $genome_lib/ref_genome.fa.star.idx/sjdbList.fromGTF.out.tab +- touch $genome_lib/ref_genome.fa.star.idx/build.ok +- touch $genome_lib/ref_genome.fa.star.idx/chrLength.txt +- touch $genome_lib/ref_genome.fa.star.idx/Log.out +- touch $genome_lib/ref_genome.fa.star.idx/genomeParameters.txt +- touch $genome_lib/ref_genome.fa.star.idx/chrStart.txt +- touch $genome_lib/ref_genome.fa.star.idx/SA +- touch $genome_lib/ref_genome.fa.star.idx/chrNameLength.txt +- touch $genome_lib/ref_genome.fa.star.idx/exonGeTrInfo.tab +- touch $genome_lib/ref_annot.cds +- touch $genome_lib/ref_annot.gtf.gene_spans +- touch $genome_lib/pfam_domains.dbm +- touch $genome_lib/ref_annot.cdsplus.fa.idx +- touch $genome_lib/ref_genome.fa.ndb +- touch $genome_lib/ref_genome.fa.nin +- touch $genome_lib/ref_genome.fa +- touch $genome_lib/ref_annot.prot_info.dbm +- echo | gzip > $genome_lib/PFAM.domtblout.dat.gz +- touch $genome_lib/trans.blast.align_coords.align_coords.dat +- touch $genome_lib/fusion_annot_lib.idx +- touch $genome_lib/ref_annot.pep +- touch $genome_lib/__chkpts/trans.blast.dat.cp.ok +- touch $genome_lib/__chkpts/cp_ref_annot_cdna.ok +- touch $genome_lib/__chkpts/ref_annot.cdsplus.dfam_masked.fa.cp.ok +- touch $genome_lib/__chkpts/annotfiltrule_cp.ok +- touch $genome_lib/__chkpts/validate_ctat_genome_lib.ok +- touch $genome_lib/__chkpts/cp_pfam_dat.ok +- touch $genome_lib/__chkpts/fusion_annot_lib.cp.ok +- touch $genome_lib/__chkpts/ref_genome.fa.ok +- touch $genome_lib/__chkpts/cp_gene_blast_pairs.ok +- touch $genome_lib/__chkpts/mm2_genome_idx.ok +- touch $genome_lib/__chkpts/trans.blast.dat.index.ok +- touch $genome_lib/__chkpts/ref_genome_fai.ok +- touch $genome_lib/__chkpts/index_ref_annot_cdna.ok +- touch $genome_lib/__chkpts/ref_annot.gtf.ok +- touch $genome_lib/__chkpts/blast_pairs.idx.ok +- touch $genome_lib/__chkpts/ref_annot.cdsplus.dfam_masked.fa.idx.ok +- touch $genome_lib/__chkpts/_prot_info_db.ok +- touch $genome_lib/__chkpts/_fusion_annot_lib.idx.ok +- touch $genome_lib/__chkpts/index_pfam_hits.ok +- touch $genome_lib/__chkpts/makeblastdb.ok +- touch $genome_lib/__chkpts/ref_annot.gtf.gene_spans.ok +- touch $genome_lib/__chkpts/mm2.splice_bed.ok +- touch $genome_lib/__chkpts/ref_annot.gtf.mini.sortu.ok +- touch $genome_lib/ref_genome.fa.ntf +- touch $genome_lib/ref_genome.fa.nto +- touch $genome_lib/ref_annot.gtf +- touch $genome_lib/ref_annot.gtf.mm2.splice.bed +- touch $genome_lib/ref_genome.fa.mm2 +- echo | gzip > $genome_lib/fusion_annot_lib.gz +- touch $genome_lib/ref_annot.cdsplus.fa +- touch $genome_lib/AnnotFilterRule.pm +- echo | gzip > $genome_lib/trans.blast.dat.gz +- touch $genome_lib/ref_genome.fa.nhr +- touch $genome_lib/blast_pairs.idx +- touch $genome_lib/ref_genome.fa.nsq +- echo | gzip > $genome_lib/blast_pairs.dat.gz +- touch $genome_lib/ref_annot.cdna.fa.idx +- touch $genome_lib/ref_genome.fa.not +- touch $genome_lib/ref_annot.cdna.fa +- touch $genome_lib/ref_annot.gtf.mini.sortu +- touch $genome_lib/trans.blast.align_coords.align_coords.dbm +- touch $genome_lib/ref_genome.fa.njs +- touch $genome_lib/ref_genome.fa.fai + touch $genome_lib/refGene.bed + echo | gzip > $genome_lib/refGene.sort.bed.gz +- echo | gzip > $genome_lib/refGene.sort.bed.gz.tbi ++ touch $genome_lib/refGene.sort.bed.gz.tbi ++ mkdir $genome_lib/cancer_splicing_lib + touch $genome_lib/cancer_splicing_lib/cancer_splicing.idx + + cat <<-END_VERSIONS > versions.yml + +'modules/nf-core/ctatsplicing/prepgenomelib/tests/main.nf.test' is unchanged +'modules/nf-core/ctatsplicing/prepgenomelib/tests/main.nf.test.snap' is unchanged +************************************************************ diff --git a/modules/nf-core/ctatsplicing/prepgenomelib/main.nf b/modules/nf-core/ctatsplicing/prepgenomelib/main.nf new file mode 100644 index 000000000..c87dc8907 --- /dev/null +++ b/modules/nf-core/ctatsplicing/prepgenomelib/main.nf @@ -0,0 +1,53 @@ +process CTATSPLICING_PREPGENOMELIB { + tag "$meta.id" + label 'process_single' + + container "nf-core/ctatsplicing:0.0.3" + + input: + tuple val(meta), path(genome_lib) + path(cancer_intron_tsv) + + output: + tuple val(meta), path(genome_lib, includeInputs:true), emit: reference + 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 "CTATSPLICING_PREPGENOMELIB module does not support Conda. Please use Docker / Singularity / Podman instead." + } + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def VERSION = '0.0.2' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + """ + /usr/local/src/CTAT-SPLICING/prep_genome_lib/ctat-splicing-lib-integration.py \\ + --cancer_introns_tsv $cancer_intron_tsv \\ + --genome_lib_dir $genome_lib + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + ctatsplicing: $VERSION + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def VERSION = '0.0.2' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + """ + touch $genome_lib/refGene.bed + echo | gzip > $genome_lib/refGene.sort.bed.gz + touch $genome_lib/refGene.sort.bed.gz.tbi + mkdir $genome_lib/cancer_splicing_lib + touch $genome_lib/cancer_splicing_lib/cancer_splicing.idx + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + ctatsplicing: $VERSION + END_VERSIONS + """ +} diff --git a/modules/nf-core/ctatsplicing/prepgenomelib/meta.yml b/modules/nf-core/ctatsplicing/prepgenomelib/meta.yml new file mode 100644 index 000000000..1efecef75 --- /dev/null +++ b/modules/nf-core/ctatsplicing/prepgenomelib/meta.yml @@ -0,0 +1,57 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "ctatsplicing_prepgenomelib" +description: Reference preparation for CTAT-splicing +long_description: | + This module prepares the CTAT genome library reference for splicing analysis by integrating cancer intron annotations. + It takes a CTAT genome library and a cancer intron TSV file as input, and outputs a modified genome library reference. + The output can be used in subsequent CTAT-splicing analyses to detect and annotate cancer splicing aberrations. + Make sure to provide the correct genome library and cancer intron data resource. +keywords: + - splicing + - cancer + - rna + - rnaseq +tools: + - "ctatsplicing": + description: "Detection and annotation of cancer splicing aberrations" + homepage: "https://github.com/TrinityCTAT/CTAT-SPLICING" + documentation: "https://github.com/TrinityCTAT/CTAT-SPLICING" + tool_dev_url: "https://github.com/TrinityCTAT/CTAT-SPLICING" + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - genome_lib: + type: file + description: CTAT genome library reference + pattern: "*" + - cancer_intron_tsv: + type: file + description: CTAT-splicing data resource supplement + +output: + reference: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - genome_lib: + type: file + description: Modified CTAT genome library reference + pattern: "*" + versions: + - "versions.yml": + type: file + description: File containing software versions + pattern: "versions.yml" + +authors: + - "@anoronh4" + - "@nvnieuwk" +maintainers: + - "@anoronh4" diff --git a/modules/nf-core/ctatsplicing/prepgenomelib/tests/main.nf.test b/modules/nf-core/ctatsplicing/prepgenomelib/tests/main.nf.test new file mode 100644 index 000000000..b9fec4a72 --- /dev/null +++ b/modules/nf-core/ctatsplicing/prepgenomelib/tests/main.nf.test @@ -0,0 +1,109 @@ +nextflow_process { + + name "Test Process CTATSPLICING_PREPGENOMELIB" + script "../main.nf" + process "CTATSPLICING_PREPGENOMELIB" + + tag "modules" + tag "modules_nfcore" + tag "ctatsplicing" + tag "ctatsplicing/prepgenomelib" + tag "starfusion/build" + + test("homo_sapiens - reference") { + setup { + run("STARFUSION_BUILD") { + script "../../../starfusion/build/main.nf" + process { + """ + input[0] = [ + [ id:'minigenome_fasta' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/minigenome.fa') + ] + input[1] = [ + [ id:'minigenome_gtf' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/minigenome.gtf') + ] + input[2] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/CTAT_HumanFusionLib.mini.dat.gz') + input[3] = "homo_sapiens" + input[4] = "http://ftp.ebi.ac.uk/pub/databases/Pfam/releases/Pfam37.4/Pfam-A.hmm.gz" + input[5] = [ + "https://www.dfam.org/releases/Dfam_3.8/infrastructure/dfamscan/homo_sapiens_dfam.hmm", + "https://www.dfam.org/releases/Dfam_3.8/infrastructure/dfamscan/homo_sapiens_dfam.hmm.h3f", + "https://www.dfam.org/releases/Dfam_3.8/infrastructure/dfamscan/homo_sapiens_dfam.hmm.h3i", + "https://www.dfam.org/releases/Dfam_3.8/infrastructure/dfamscan/homo_sapiens_dfam.hmm.h3m", + "https://www.dfam.org/releases/Dfam_3.8/infrastructure/dfamscan/homo_sapiens_dfam.hmm.h3p" + ] + input[6] = "https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/AnnotFilterRule.pm" + """ + } + } + } + + when { + process { + """ + input[0] = STARFUSION_BUILD.out.reference + input[1] = [ + file("https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/CANCER_SPLICING_LIB_SUPPLEMENT/cancer_introns.GRCh38.Jun232020.tsv.gz", checkIfExists:true) + ] + """ + } + } + + then { + def stable_name = getAllFilesFromDir(process.out.reference.get(0).get(1), includeDir: true) + def stable_files = getAllFilesFromDir(process.out.reference.get(0).get(1), includeDir: false, include: ['*','**/*'], + ignore: ['refGene.sort.bed.gz.tbi','**/refGene.sort.bed.gz.tbi', 'refGene.bed', '**/cancer_splicing.idx', 'ref_annot.c*', + 'PFAM.domtblout.dat.gz', 'blast_pairs*', 'fusion_annot_lib.idx', 'pfam_domains.dbm', 'ref_annot.gtf.gene_spans', + 'ref_annot.prot_info.dbm', 'ref_annot.pep', 'ref_genome.fa.nin', 'ref_genome.fa.njs', '**/Log.out', '**/genomeParameters.txt', 'trans.blast.align_coords.align_coords.dbm']) + def stable_content = stable_files.findAll { it.size() > 0 } + assertAll( + { assert process.success }, + { + assert snapshot( + stable_name*.name, + stable_content, + process.out.versions + ).match() + } + ) + + } + } + + test("homo_sapiens - reference - stub") { + + options "-stub" + + when { + process { + """ + new File('ctat_genome_lib_build_dir').mkdirs() + input[0] = [[id:"ctat_genome_lib_build_dir"],file("ctat_genome_lib_build_dir/")] + input[1] = [ + file("https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/CANCER_SPLICING_LIB_SUPPLEMENT/cancer_introns.GRCh38.Jun232020.tsv.gz", checkIfExists:true) + ] + """ + } + } + + then { + def stable_name = getAllFilesFromDir(process.out.reference.get(0).get(1), includeDir: true) + def stable_content = getAllFilesFromDir(process.out.reference.get(0).get(1), includeDir: false, include: ['*','**/*'], ignore: ['refGene.sort.bed.gz.tbi','**/refGene.sort.bed.gz.tbi','**/cancer_splicing.idx']) + assertAll( + { assert process.success }, + { + assert snapshot( + stable_name*.name, + stable_content, + process.out.versions + ).match() + } + ) + + } + + } + +} diff --git a/modules/nf-core/ctatsplicing/prepgenomelib/tests/main.nf.test.snap b/modules/nf-core/ctatsplicing/prepgenomelib/tests/main.nf.test.snap new file mode 100644 index 000000000..8d801aa01 --- /dev/null +++ b/modules/nf-core/ctatsplicing/prepgenomelib/tests/main.nf.test.snap @@ -0,0 +1,299 @@ +{ + "homo_sapiens - reference": { + "content": [ + [ + "minigenome_fasta_genome_lib_build_dir", + "AnnotFilterRule.pm", + "PFAM.domtblout.dat.gz", + "__chkpts", + "_fusion_annot_lib.idx.ok", + "_prot_info_db.ok", + "annotfiltrule_cp.ok", + "blast_pairs.idx.ok", + "cp_gene_blast_pairs.ok", + "cp_pfam_dat.ok", + "cp_ref_annot_cdna.ok", + "fusion_annot_lib.cp.ok", + "index_pfam_hits.ok", + "index_ref_annot_cdna.ok", + "makeblastdb.ok", + "mm2.splice_bed.ok", + "mm2_genome_idx.ok", + "ref_annot.cdsplus.dfam_masked.fa.cp.ok", + "ref_annot.cdsplus.dfam_masked.fa.idx.ok", + "ref_annot.gtf.gene_spans.ok", + "ref_annot.gtf.mini.sortu.ok", + "ref_annot.gtf.ok", + "ref_genome.fa.ok", + "ref_genome_fai.ok", + "trans.blast.dat.cp.ok", + "trans.blast.dat.index.ok", + "validate_ctat_genome_lib.ok", + "blast_pairs.dat.gz", + "blast_pairs.idx", + "cancer_splicing_lib", + "cancer_splicing.idx", + "fusion_annot_lib.gz", + "fusion_annot_lib.idx", + "pfam_domains.dbm", + "refGene.bed", + "refGene.sort.bed.gz", + "refGene.sort.bed.gz.tbi", + "ref_annot.cdna.fa", + "ref_annot.cdna.fa.idx", + "ref_annot.cds", + "ref_annot.cdsplus.fa", + "ref_annot.cdsplus.fa.idx", + "ref_annot.gtf", + "ref_annot.gtf.gene_spans", + "ref_annot.gtf.mini.sortu", + "ref_annot.gtf.mm2.splice.bed", + "ref_annot.pep", + "ref_annot.prot_info.dbm", + "ref_genome.fa", + "ref_genome.fa.fai", + "ref_genome.fa.mm2", + "ref_genome.fa.ndb", + "ref_genome.fa.nhr", + "ref_genome.fa.nin", + "ref_genome.fa.njs", + "ref_genome.fa.not", + "ref_genome.fa.nsq", + "ref_genome.fa.ntf", + "ref_genome.fa.nto", + "ref_genome.fa.star.idx", + "Genome", + "Log.out", + "SA", + "SAindex", + "build.ok", + "chrLength.txt", + "chrName.txt", + "chrNameLength.txt", + "chrStart.txt", + "exonGeTrInfo.tab", + "exonInfo.tab", + "geneInfo.tab", + "genomeParameters.txt", + "sjdbInfo.txt", + "sjdbList.fromGTF.out.tab", + "sjdbList.out.tab", + "transcriptInfo.tab", + "trans.blast.align_coords.align_coords.dat", + "trans.blast.align_coords.align_coords.dbm", + "trans.blast.dat.gz" + ], + [ + "AnnotFilterRule.pm:md5,f94966013cd0df9624a6dda0b75fefa0", + "fusion_annot_lib.gz:md5,23d82a5da81f91ca4e1ecd6481992a12", + "refGene.sort.bed.gz:md5,01bf4093e3e9dcad8ed3a0f45a381c95", + "ref_annot.gtf:md5,5ce8afe99ef3940a877a04caeacf9181", + "ref_annot.gtf.mini.sortu:md5,1d29ccecdbb7b40a99c84a02d6c2c1be", + "ref_annot.gtf.mm2.splice.bed:md5,340585ea1843bf06bf555575ddecf28c", + "ref_genome.fa:md5,ad699c56ed38566c7d3e9579486b1706", + "ref_genome.fa.fai:md5,e3f74a27219b33ae80fd5de5cbeaf32b", + "ref_genome.fa.mm2:md5,ce50979ea284748eb9f84ae88cfd930e", + "ref_genome.fa.ndb:md5,6ea574753b557610f62f6e4ab79e19f5", + "ref_genome.fa.nhr:md5,50f28dae71683c4394bfaf94a1ef4392", + "ref_genome.fa.not:md5,1e53e9d08f1d23af0299cfa87478a7bb", + "ref_genome.fa.nsq:md5,d2361e7871ce4cf51181c112a48f191b", + "ref_genome.fa.ntf:md5,de1250813f0c7affc6d12dac9d0fb6bb", + "ref_genome.fa.nto:md5,33cdeccccebe80329f1fdbee7f5874cb", + "Genome:md5,9e3efdd0901cabb5a2d589664a63b372", + "SA:md5,7dd9083264be9c6a2194d990bc10d237", + "SAindex:md5,ac4711df685109e04356db9e9cb9fb7f", + "chrLength.txt:md5,e02cd536b7281b894246863b160d5d06", + "chrName.txt:md5,f4d0d6595f423084e6b9472e40dfe6e8", + "chrNameLength.txt:md5,07a67d7ac441d7d30d80840b0927e717", + "chrStart.txt:md5,e2031239a74fe5ee9051e9364e4f608a", + "exonGeTrInfo.tab:md5,3c35618d07a8e35a0f9108699fcdda42", + "exonInfo.tab:md5,bcbb3f32fa31fe504cc737f337ad341c", + "geneInfo.tab:md5,db5db4b6e003904e9908fce7c05f0125", + "sjdbInfo.txt:md5,e4cc1bbf8bd687cfc3d7c2c702e6def7", + "sjdbList.fromGTF.out.tab:md5,8f3e8604b00d4067e4eb80aa476a8113", + "sjdbList.out.tab:md5,5d78dd49d5db24ca2c056b7ebe5c2059", + "transcriptInfo.tab:md5,b758c0ccaddcf0453bab5905b3cec4a2", + "trans.blast.align_coords.align_coords.dat:md5,9f6b7a75aea03a9671190be25ecdd4c2", + "trans.blast.dat.gz:md5,85ba5ea96c566f751ad83a3e4b8ab128" + ], + [ + "versions.yml:md5,3554c611ce8fa5c21460b6a99e8e36dc" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-07-30T16:22:20.140859164" + }, + "homo_sapiens - reference - stub": { + "content": [ + [ + "ctat_genome_lib_build_dir", + "AnnotFilterRule.pm", + "PFAM.domtblout.dat.gz", + "__chkpts", + "_fusion_annot_lib.idx.ok", + "_prot_info_db.ok", + "annotfiltrule_cp.ok", + "blast_pairs.idx.ok", + "cp_gene_blast_pairs.ok", + "cp_pfam_dat.ok", + "cp_ref_annot_cdna.ok", + "fusion_annot_lib.cp.ok", + "index_pfam_hits.ok", + "index_ref_annot_cdna.ok", + "makeblastdb.ok", + "mm2.splice_bed.ok", + "mm2_genome_idx.ok", + "ref_annot.cdsplus.dfam_masked.fa.cp.ok", + "ref_annot.cdsplus.dfam_masked.fa.idx.ok", + "ref_annot.gtf.gene_spans.ok", + "ref_annot.gtf.mini.sortu.ok", + "ref_annot.gtf.ok", + "ref_genome.fa.ok", + "ref_genome_fai.ok", + "trans.blast.dat.cp.ok", + "trans.blast.dat.index.ok", + "validate_ctat_genome_lib.ok", + "blast_pairs.dat.gz", + "blast_pairs.idx", + "cancer_splicing_lib", + "cancer_splicing.idx", + "fusion_annot_lib.gz", + "fusion_annot_lib.idx", + "pfam_domains.dbm", + "refGene.bed", + "refGene.sort.bed.gz", + "refGene.sort.bed.gz.tbi", + "ref_annot.cdna.fa", + "ref_annot.cdna.fa.idx", + "ref_annot.cds", + "ref_annot.cdsplus.fa", + "ref_annot.cdsplus.fa.idx", + "ref_annot.gtf", + "ref_annot.gtf.gene_spans", + "ref_annot.gtf.mini.sortu", + "ref_annot.gtf.mm2.splice.bed", + "ref_annot.pep", + "ref_annot.prot_info.dbm", + "ref_genome.fa", + "ref_genome.fa.fai", + "ref_genome.fa.mm2", + "ref_genome.fa.ndb", + "ref_genome.fa.nhr", + "ref_genome.fa.nin", + "ref_genome.fa.njs", + "ref_genome.fa.not", + "ref_genome.fa.nsq", + "ref_genome.fa.ntf", + "ref_genome.fa.nto", + "ref_genome.fa.star.idx", + "Genome", + "Log.out", + "SA", + "SAindex", + "build.ok", + "chrLength.txt", + "chrName.txt", + "chrNameLength.txt", + "chrStart.txt", + "exonGeTrInfo.tab", + "exonInfo.tab", + "geneInfo.tab", + "genomeParameters.txt", + "sjdbInfo.txt", + "sjdbList.fromGTF.out.tab", + "sjdbList.out.tab", + "transcriptInfo.tab", + "trans.blast.align_coords.align_coords.dat", + "trans.blast.align_coords.align_coords.dbm", + "trans.blast.dat.gz" + ], + [ + "AnnotFilterRule.pm:md5,d41d8cd98f00b204e9800998ecf8427e", + "PFAM.domtblout.dat.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "_fusion_annot_lib.idx.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "_prot_info_db.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "annotfiltrule_cp.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "blast_pairs.idx.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "cp_gene_blast_pairs.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "cp_pfam_dat.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "cp_ref_annot_cdna.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "fusion_annot_lib.cp.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "index_pfam_hits.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "index_ref_annot_cdna.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "makeblastdb.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "mm2.splice_bed.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "mm2_genome_idx.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdsplus.dfam_masked.fa.cp.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdsplus.dfam_masked.fa.idx.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.gene_spans.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.mini.sortu.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome_fai.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "trans.blast.dat.cp.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "trans.blast.dat.index.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "validate_ctat_genome_lib.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "blast_pairs.dat.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "blast_pairs.idx:md5,d41d8cd98f00b204e9800998ecf8427e", + "fusion_annot_lib.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "fusion_annot_lib.idx:md5,d41d8cd98f00b204e9800998ecf8427e", + "pfam_domains.dbm:md5,d41d8cd98f00b204e9800998ecf8427e", + "refGene.bed:md5,d41d8cd98f00b204e9800998ecf8427e", + "refGene.sort.bed.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "ref_annot.cdna.fa:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdna.fa.idx:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cds:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdsplus.fa:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdsplus.fa.idx:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.gene_spans:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.mini.sortu:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.mm2.splice.bed:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.pep:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.prot_info.dbm:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.fai:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.mm2:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.ndb:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.nhr:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.nin:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.njs:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.not:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.nsq:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.ntf:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.nto:md5,d41d8cd98f00b204e9800998ecf8427e", + "Genome:md5,d41d8cd98f00b204e9800998ecf8427e", + "Log.out:md5,d41d8cd98f00b204e9800998ecf8427e", + "SA:md5,d41d8cd98f00b204e9800998ecf8427e", + "SAindex:md5,d41d8cd98f00b204e9800998ecf8427e", + "build.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrLength.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrName.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrNameLength.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrStart.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "exonGeTrInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "exonInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "geneInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "genomeParameters.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "sjdbInfo.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "sjdbList.fromGTF.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "sjdbList.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "transcriptInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "trans.blast.align_coords.align_coords.dat:md5,d41d8cd98f00b204e9800998ecf8427e", + "trans.blast.align_coords.align_coords.dbm:md5,d41d8cd98f00b204e9800998ecf8427e", + "trans.blast.dat.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ], + [ + "versions.yml:md5,3554c611ce8fa5c21460b6a99e8e36dc" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.3" + }, + "timestamp": "2025-03-31T16:20:05.986978" + } +} diff --git a/modules/nf-core/ctatsplicing/startocancerintrons/ctatsplicing-startocancerintrons.diff b/modules/nf-core/ctatsplicing/startocancerintrons/ctatsplicing-startocancerintrons.diff new file mode 100644 index 000000000..7ec847711 --- /dev/null +++ b/modules/nf-core/ctatsplicing/startocancerintrons/ctatsplicing-startocancerintrons.diff @@ -0,0 +1,120 @@ +Changes in component 'nf-core/ctatsplicing/startocancerintrons' +'modules/nf-core/ctatsplicing/startocancerintrons/main.nf' is unchanged +Changes in 'ctatsplicing/startocancerintrons/meta.yml': +--- modules/nf-core/ctatsplicing/startocancerintrons/meta.yml ++++ modules/nf-core/ctatsplicing/startocancerintrons/meta.yml +@@ -63,7 +63,7 @@ + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] +- - '*.cancer_intron_reads.sorted.bam': ++ - "*.cancer_intron_reads.sorted.bam": + type: file + description: "Sorted BAM file containing reads mapped to cancer introns" + pattern: "*.cancer_intron_reads.sorted.bam" +@@ -75,7 +75,7 @@ + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] +- - '*.cancer_intron_reads.sorted.bam.bai': ++ - "*.cancer_intron_reads.sorted.bam.bai": + type: file + description: "Index file for the sorted BAM of cancer introns" + pattern: "*.cancer_intron_reads.sorted.bam.bai" +@@ -87,7 +87,7 @@ + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] +- - '*.gene_reads.sorted.sifted.bam': ++ - "*.gene_reads.sorted.sifted.bam": + type: file + description: "Sorted BAM file containing reads mapped to gene regions after downsampling coverage" + pattern: "*.gene_reads.sorted.sifted.bam" +@@ -99,7 +99,7 @@ + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] +- - '*.gene_reads.sorted.sifted.bam.bai': ++ - "*.gene_reads.sorted.sifted.bam.bai": + type: file + description: "Index file for the sorted BAM of gene reads after filtering" + pattern: "*.gene_reads.sorted.sifted.bam.bai" +@@ -111,7 +111,7 @@ + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] +- - '*.cancer.introns': ++ - "*.cancer.introns": + type: file + description: "File containing detected and filtered introns that are found to be enriched in cancer transcriptomes" + pattern: "*.cancer.introns" +@@ -121,7 +121,7 @@ + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] +- - '*.cancer.introns.prelim': ++ - "*.cancer.introns.prelim": + type: file + description: "File containing detected introns that have at least one supporting read and are found to be enriched in cancer transcriptomes" + pattern: "*.cancer.introns.prelim" +@@ -131,7 +131,7 @@ + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] +- - '*${prefix}.introns': ++ - "*${prefix}.introns": + type: file + description: "File containing all detected introns" + pattern: "*${prefix}.introns" +@@ -141,7 +141,7 @@ + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] +- - '*.introns.for_IGV.bed': ++ - "*.introns.for_IGV.bed": + type: file + description: "Bed file used as input for IGV-report visualization, containing cancer introns" + pattern: "*.introns.for_IGV.bed" +@@ -153,7 +153,7 @@ + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] +- - '*.ctat-splicing.igv.html': ++ - "*.ctat-splicing.igv.html": + type: file + description: "Self-contained IGV-report in HTML format for visualization of cancer introns" + pattern: "*.ctat-splicing.igv.html" +@@ -163,7 +163,7 @@ + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] +- - '*.igv.tracks': ++ - "*.igv.tracks": + type: file + description: "IGV tracks file for visualizing cancer introns in IGV" + pattern: "*.igv.tracks" +@@ -173,15 +173,15 @@ + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] +- - '*.chckpts': ++ - "*.chckpts": + type: file + description: "Checkpoint files for CTAT-SPLICING, useful for debugging or resuming interrupted runs" + pattern: "*.chckpts" + versions: + - versions.yml: +- type: file +- description: File containing software versions +- pattern: "versions.yml" ++ type: file ++ description: File containing software versions ++ pattern: "versions.yml" + authors: + - "@anoronh4" + - "@nvnieuwk" + +'modules/nf-core/ctatsplicing/startocancerintrons/tests/main.nf.test' is unchanged +'modules/nf-core/ctatsplicing/startocancerintrons/tests/main.nf.test.snap' is unchanged +'modules/nf-core/ctatsplicing/startocancerintrons/tests/nextflow.config' is unchanged +************************************************************ diff --git a/modules/nf-core/ctatsplicing/startocancerintrons/main.nf b/modules/nf-core/ctatsplicing/startocancerintrons/main.nf new file mode 100644 index 000000000..dbaaf20c1 --- /dev/null +++ b/modules/nf-core/ctatsplicing/startocancerintrons/main.nf @@ -0,0 +1,77 @@ +process CTATSPLICING_STARTOCANCERINTRONS { + tag "$meta.id" + label 'process_single' + + container "nf-core/ctatsplicing:0.0.3" + + input: + tuple val(meta), path(split_junction), path(junction), path(bam), path(bai) + tuple val(meta2), path(genome_lib) + + output: + tuple val(meta), path("*.cancer_intron_reads.sorted.bam") , emit: cancer_introns_sorted_bam, optional: true + tuple val(meta), path("*.cancer_intron_reads.sorted.bam.bai"), emit: cancer_introns_sorted_bai, optional: true + tuple val(meta), path("*.gene_reads.sorted.sifted.bam") , emit: gene_reads_sorted_bam , optional: true + tuple val(meta), path("*.gene_reads.sorted.sifted.bam.bai") , emit: gene_reads_sorted_bai , optional: true + tuple val(meta), path("*.cancer.introns") , emit: cancer_introns + tuple val(meta), path("*.cancer.introns.prelim") , emit: cancer_introns_prelim + tuple val(meta), path("*${prefix}.introns") , emit: introns + tuple val(meta), path("*.introns.for_IGV.bed") , emit: introns_igv_bed , optional: true + tuple val(meta), path("*.ctat-splicing.igv.html") , emit: igv_html , optional: true + tuple val(meta), path("*.igv.tracks") , emit: igv_tracks , optional: true + tuple val(meta), path("*.chckpts") , emit: chckpts , optional: true + 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 "CTATSPLICING_STARTOCANCERINTRONS module does not support Conda. Please use Docker / Singularity / Podman instead." + } + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + def bam_arg = bam ? "--bam_file ${bam}" : "" + def VERSION = '0.0.2' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + def create_index = bam && !bai ? "samtools index ${bam}" : "" + """ + ${create_index} + + /usr/local/src/CTAT-SPLICING/STAR_to_cancer_introns.py \\ + --SJ_tab_file ${split_junction} \\ + --chimJ_file ${junction} \\ + ${bam_arg} \\ + --output_prefix ${prefix} \\ + --ctat_genome_lib ${genome_lib} \\ + ${args} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + ctat-splicing: $VERSION + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + def VERSION = '0.0.2' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + def create_igv_files = args.contains("--vis") ? "touch ${prefix}.introns.for_IGV.bed && touch ${prefix}.ctat-splicing.igv.html && touch ${prefix}.igv.tracks" : "" + """ + ${create_igv_files} + touch ${prefix}.cancer_intron_reads.sorted.bam + touch ${prefix}.cancer_intron_reads.sorted.bam.bai + touch ${prefix}.gene_reads.sorted.sifted.bam + touch ${prefix}.gene_reads.sorted.sifted.bam.bai + touch ${prefix}.cancer.introns + touch ${prefix}.cancer.introns.prelim + touch ${prefix}.introns + touch ${prefix}.chckpts + + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + ctat-splicing: $VERSION + END_VERSIONS + """ +} diff --git a/modules/nf-core/ctatsplicing/startocancerintrons/meta.yml b/modules/nf-core/ctatsplicing/startocancerintrons/meta.yml new file mode 100644 index 000000000..1f69d7988 --- /dev/null +++ b/modules/nf-core/ctatsplicing/startocancerintrons/meta.yml @@ -0,0 +1,189 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "ctatsplicing_startocancerintrons" +description: "Detection and annotation of aberrant splicing isoforms in cancer transcriptomes" +long_description: | + This module detects and annotates aberrant splicing isoforms in cancer transcriptomes using CTAT-splicing. + It takes STAR alignment files, a sorted BAM file, and a CTAT genome library reference as input, and outputs various files related to cancer introns. + The output can be used for further analysis of splicing aberrations in cancer. + Make sure to provide the correct STAR alignment files and CTAT genome library reference. +keywords: + - splicing + - cancer + - rna + - rnaseq +tools: + - "ctatsplicing": + description: "Detection and annotation of cancer splicing aberrations" + homepage: "https://github.com/TrinityCTAT/CTAT-SPLICING" + documentation: "https://github.com/TrinityCTAT/CTAT-SPLICING" + tool_dev_url: "https://github.com/TrinityCTAT/CTAT-SPLICING" + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - split_junction: + type: file + description: "STAR alignment splice junction tab file" + pattern: "*.SJ.out.tab" + - junction: + type: file + description: "STAR alignment chimeric junction file" + pattern: "*.out.junction" + - bam: + type: file + description: "Sorted BAM/CRAM/SAM file" + pattern: "*.{bam,cram,sam}" + ontologies: + - edam: "http://edamontology.org/format_2572" + - edam: "http://edamontology.org/format_2573" + - edam: "http://edamontology.org/format_3462" + - bai: + type: file + description: "BAM/CRAM/SAM index file" + pattern: "*.{bai,crai,sai}" + ontologies: + - edam: "http://edamontology.org/format_3327" + - - meta2: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - genome_lib: + type: file + description: "CTAT genome library reference with integrated cancer intron annotation" + pattern: "*" + +output: + cancer_introns_sorted_bam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.cancer_intron_reads.sorted.bam": + type: file + description: "Sorted BAM file containing reads mapped to cancer introns" + pattern: "*.cancer_intron_reads.sorted.bam" + ontologies: + - edam: "http://edamontology.org/format_2572" + cancer_introns_sorted_bai: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.cancer_intron_reads.sorted.bam.bai": + type: file + description: "Index file for the sorted BAM of cancer introns" + pattern: "*.cancer_intron_reads.sorted.bam.bai" + ontologies: + - edam: "http://edamontology.org/format_3327" + gene_reads_sorted_bam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.gene_reads.sorted.sifted.bam": + type: file + description: "Sorted BAM file containing reads mapped to gene regions after downsampling coverage" + pattern: "*.gene_reads.sorted.sifted.bam" + ontologies: + - edam: "http://edamontology.org/format_2572" + gene_reads_sorted_bai: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.gene_reads.sorted.sifted.bam.bai": + type: file + description: "Index file for the sorted BAM of gene reads after filtering" + pattern: "*.gene_reads.sorted.sifted.bam.bai" + ontologies: + - edam: "http://edamontology.org/format_3327" + cancer_introns: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.cancer.introns": + type: file + description: "File containing detected and filtered introns that are found to be enriched in cancer transcriptomes" + pattern: "*.cancer.introns" + cancer_introns_prelim: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.cancer.introns.prelim": + type: file + description: "File containing detected introns that have at least one supporting read and are found to be enriched in cancer transcriptomes" + pattern: "*.cancer.introns.prelim" + introns: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*${prefix}.introns": + type: file + description: "File containing all detected introns" + pattern: "*${prefix}.introns" + introns_igv_bed: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.introns.for_IGV.bed": + type: file + description: "Bed file used as input for IGV-report visualization, containing cancer introns" + pattern: "*.introns.for_IGV.bed" + ontologies: + - edam: "http://edamontology.org/format_3586" + igv_html: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.ctat-splicing.igv.html": + type: file + description: "Self-contained IGV-report in HTML format for visualization of cancer introns" + pattern: "*.ctat-splicing.igv.html" + igv_tracks: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.igv.tracks": + type: file + description: "IGV tracks file for visualizing cancer introns in IGV" + pattern: "*.igv.tracks" + chckpts: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.chckpts": + type: file + description: "Checkpoint files for CTAT-SPLICING, useful for debugging or resuming interrupted runs" + pattern: "*.chckpts" + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" +authors: + - "@anoronh4" + - "@nvnieuwk" +maintainers: + - "@anoronh4" diff --git a/modules/nf-core/ctatsplicing/startocancerintrons/tests/main.nf.test b/modules/nf-core/ctatsplicing/startocancerintrons/tests/main.nf.test new file mode 100644 index 000000000..102423258 --- /dev/null +++ b/modules/nf-core/ctatsplicing/startocancerintrons/tests/main.nf.test @@ -0,0 +1,186 @@ +nextflow_process { + + name "Test Process CTATSPLICING_STARTOCANCERINTRONS" + script "../main.nf" + process "CTATSPLICING_STARTOCANCERINTRONS" + + tag "modules" + tag "modules_nfcore" + tag "ctatsplicing" + tag "ctatsplicing/startocancerintrons" + tag "ctatsplicing/prepgenomelib" + tag "star/align" + tag "samtools/index" + tag "starfusion/build" + + test("homo_sapiens - bam - junctions") { + + config './nextflow.config' + setup { + run("STARFUSION_BUILD") { + script "../../../starfusion/build/main.nf" + process { + """ + input[0] = [ + [ id:'minigenome_fasta' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/minigenome.fa') + ] + input[1] = [ + [ id:'minigenome_gtf' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/minigenome.gtf') + ] + input[2] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/CTAT_HumanFusionLib.mini.dat.gz') + input[3] = "homo_sapiens" + input[4] = "http://ftp.ebi.ac.uk/pub/databases/Pfam/releases/Pfam37.4/Pfam-A.hmm.gz" + input[5] = [ + "https://www.dfam.org/releases/Dfam_3.8/infrastructure/dfamscan/homo_sapiens_dfam.hmm", + "https://www.dfam.org/releases/Dfam_3.8/infrastructure/dfamscan/homo_sapiens_dfam.hmm.h3f", + "https://www.dfam.org/releases/Dfam_3.8/infrastructure/dfamscan/homo_sapiens_dfam.hmm.h3i", + "https://www.dfam.org/releases/Dfam_3.8/infrastructure/dfamscan/homo_sapiens_dfam.hmm.h3m", + "https://www.dfam.org/releases/Dfam_3.8/infrastructure/dfamscan/homo_sapiens_dfam.hmm.h3p" + ] + input[6] = "https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/AnnotFilterRule.pm" + """ + } + } + run("CTATSPLICING_PREPGENOMELIB") { + script "../../prepgenomelib/main.nf" + process { + """ + input[0] = STARFUSION_BUILD.out.reference + input[1] = [ + file("https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/CANCER_SPLICING_LIB_SUPPLEMENT/cancer_introns.GRCh38.Jun232020.tsv.gz", checkIfExists:true) + ] + """ + } + } + run("STAR_ALIGN") { + script "../../../star/align/main.nf" + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true) + ] + ]) + input[1] = CTATSPLICING_PREPGENOMELIB.out.reference.map{ meta, reference -> + [ meta, "\$reference/ref_genome.fa.star.idx" ] + } + input[2] = CTATSPLICING_PREPGENOMELIB.out.reference.map{ meta, reference -> + [ meta, "\$reference/ref_annot.gtf" ] + } + input[3] = false + input[4] = 'illumina' + input[5] = false + """ + } + } + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = STAR_ALIGN.out.bam_sorted_aligned + """ + } + } + } + + when { + process { + """ + input[0] = STAR_ALIGN.out.spl_junc_tab + .join(STAR_ALIGN.out.junction, by:[0]) + .join(STAR_ALIGN.out.bam, by:[0]) + .join(SAMTOOLS_INDEX.out.bai, by:[0]) + input[1] = CTATSPLICING_PREPGENOMELIB.out.reference + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.cancer_introns, + process.out.cancer_introns_prelim, + file(process.out.introns[0][1]).name, + process.out.versions + ).match() } + ) + } + + } + + test("homo_sapiens - bam - junctions - stub") { + + options "-stub" + config './nextflow.config' + setup { + run("CTATSPLICING_PREPGENOMELIB") { + script "../../prepgenomelib/main.nf" + process { + """ + new File('ctat_genome_lib_build_dir').mkdirs() + input[0] = [[id:"ctat_genome_lib_build_dir"],file("ctat_genome_lib_build_dir/")] + input[1] = [ + file("https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/CANCER_SPLICING_LIB_SUPPLEMENT/cancer_introns.GRCh38.Jun232020.tsv.gz", checkIfExists:true) + ] + """ + } + } + run("STAR_ALIGN") { + script "../../../star/align/main.nf" + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true) + ] + ]) + input[1] = CTATSPLICING_PREPGENOMELIB.out.reference.map{ meta, reference -> + [ meta, "\$reference/ref_genome.fa.star.idx" ] + } + input[2] = CTATSPLICING_PREPGENOMELIB.out.reference.map{ meta, reference -> + [ meta, "\$reference/ref_annot.gtf" ] + } + input[3] = false + input[4] = 'illumina' + input[5] = false + """ + } + } + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = STAR_ALIGN.out.bam_sorted_aligned + """ + } + + } + } + + when { + process { + """ + input[0] = STAR_ALIGN.out.spl_junc_tab + .join(STAR_ALIGN.out.junction, by:[0]) + .join(STAR_ALIGN.out.bam, by:[0]) + .join(SAMTOOLS_INDEX.out.bai, by:[0]) + input[1] = CTATSPLICING_PREPGENOMELIB.out.reference + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/ctatsplicing/startocancerintrons/tests/main.nf.test.snap b/modules/nf-core/ctatsplicing/startocancerintrons/tests/main.nf.test.snap new file mode 100644 index 000000000..604821ef0 --- /dev/null +++ b/modules/nf-core/ctatsplicing/startocancerintrons/tests/main.nf.test.snap @@ -0,0 +1,248 @@ +{ + "homo_sapiens - bam - junctions": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.cancer.introns:md5,c0eb94972d845218c2e470b85c55871b" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.cancer.introns.prelim:md5,c0eb94972d845218c2e470b85c55871b" + ] + ], + "test.introns", + [ + "versions.yml:md5,fcf861a15f9951342a874b6bc476a37e" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-07-31T03:52:51.492834709" + }, + "homo_sapiens - bam - junctions - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.cancer_intron_reads.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.cancer_intron_reads.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + { + "id": "test", + "single_end": true + }, + "test.chckpts:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "11": [ + "versions.yml:md5,fcf861a15f9951342a874b6bc476a37e" + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.gene_reads.sorted.sifted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": true + }, + "test.gene_reads.sorted.sifted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": true + }, + "test.cancer.introns:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": true + }, + "test.cancer.introns.prelim:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": true + }, + "test.introns:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": true + }, + "test.introns.for_IGV.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + [ + { + "id": "test", + "single_end": true + }, + "test.ctat-splicing.igv.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "9": [ + [ + { + "id": "test", + "single_end": true + }, + "test.igv.tracks:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "cancer_introns": [ + [ + { + "id": "test", + "single_end": true + }, + "test.cancer.introns:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "cancer_introns_prelim": [ + [ + { + "id": "test", + "single_end": true + }, + "test.cancer.introns.prelim:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "cancer_introns_sorted_bai": [ + [ + { + "id": "test", + "single_end": true + }, + "test.cancer_intron_reads.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "cancer_introns_sorted_bam": [ + [ + { + "id": "test", + "single_end": true + }, + "test.cancer_intron_reads.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "chckpts": [ + [ + { + "id": "test", + "single_end": true + }, + "test.chckpts:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "gene_reads_sorted_bai": [ + [ + { + "id": "test", + "single_end": true + }, + "test.gene_reads.sorted.sifted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "gene_reads_sorted_bam": [ + [ + { + "id": "test", + "single_end": true + }, + "test.gene_reads.sorted.sifted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "igv_html": [ + [ + { + "id": "test", + "single_end": true + }, + "test.ctat-splicing.igv.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "igv_tracks": [ + [ + { + "id": "test", + "single_end": true + }, + "test.igv.tracks:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "introns": [ + [ + { + "id": "test", + "single_end": true + }, + "test.introns:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "introns_igv_bed": [ + [ + { + "id": "test", + "single_end": true + }, + "test.introns.for_IGV.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,fcf861a15f9951342a874b6bc476a37e" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.3" + }, + "timestamp": "2025-04-03T15:19:53.688973" + } +} diff --git a/modules/nf-core/ctatsplicing/startocancerintrons/tests/nextflow.config b/modules/nf-core/ctatsplicing/startocancerintrons/tests/nextflow.config new file mode 100644 index 000000000..817872ce3 --- /dev/null +++ b/modules/nf-core/ctatsplicing/startocancerintrons/tests/nextflow.config @@ -0,0 +1,33 @@ +process { + withName: STAR_ALIGN { + ext.args = { + [ + "--readFilesCommand zcat", + "--outSAMtype BAM SortedByCoordinate", + "--outReadsUnmapped None", + "--twopassMode None", + "--outSAMstrandField intronMotif", + "--outSAMunmapped Within", + "--chimSegmentMin 12", + "--chimJunctionOverhangMin 8", + "--chimOutJunctionFormat 1", + "--alignSJDBoverhangMin 10", + "--alignMatesGapMax 100000", + "--alignIntronMax 100000", + "--alignSJstitchMismatchNmax 5 -1 5 5", + "--chimMultimapScoreRange 3", + "--chimScoreJunctionNonGTAG -4", + "--chimMultimapNmax 20", + "--chimNonchimScoreDropMin 10", + "--peOverlapNbasesMin 12", + "--peOverlapMMp 0.1", + "--alignInsertionFlush Right", + "--alignSplicedMateMapLminOverLmate 0", + "--alignSplicedMateMapLmin 30" + ].join(" ").trim() + } + } + withName: CTATSPLICING_STARTOCANCERINTRONS { + ext.args = "--min_total_reads 1 --vis" + } +} diff --git a/modules/nf-core/fastp/environment.yml b/modules/nf-core/fastp/environment.yml index 70389e664..90adcd2c5 100644 --- a/modules/nf-core/fastp/environment.yml +++ b/modules/nf-core/fastp/environment.yml @@ -1,7 +1,7 @@ -name: fastp +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults dependencies: - - bioconda::fastp=0.23.4 + - bioconda::fastp=0.24.0 diff --git a/modules/nf-core/fastp/main.nf b/modules/nf-core/fastp/main.nf index c8e815aea..6e3e6c43a 100644 --- a/modules/nf-core/fastp/main.nf +++ b/modules/nf-core/fastp/main.nf @@ -4,12 +4,13 @@ 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/88/889a182b8066804f4799f3808a5813ad601381a8a0e3baa4ab8d73e739b97001/data' : + 'community.wave.seqera.io/library/fastp:0.24.0--62c97b06e8447690' }" input: tuple val(meta), path(reads) path adapter_fasta + val discard_trimmed_pass val save_trimmed_fail val save_merged @@ -18,9 +19,9 @@ process FASTP { tuple val(meta), path('*.json') , emit: json tuple val(meta), path('*.html') , emit: html tuple val(meta), path('*.log') , emit: log - path "versions.yml" , emit: versions tuple val(meta), path('*.fail.fastq.gz') , optional:true, emit: reads_fail tuple val(meta), path('*.merged.fastq.gz'), optional:true, emit: reads_merged + path "versions.yml" , emit: versions when: task.ext.when == null || task.ext.when @@ -29,7 +30,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 ? "--unpaired1 ${prefix}_1.fail.fastq.gz --unpaired2 ${prefix}_2.fail.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}_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" // 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') ) { @@ -45,7 +48,7 @@ process FASTP { $adapter_list \\ $fail_fastq \\ $args \\ - 2> ${prefix}.fastp.log \\ + 2>| >(tee ${prefix}.fastp.log >&2) \\ | gzip -c > ${prefix}.fastp.fastq.gz cat <<-END_VERSIONS > versions.yml @@ -59,14 +62,14 @@ process FASTP { fastp \\ --in1 ${prefix}.fastq.gz \\ - --out1 ${prefix}.fastp.fastq.gz \\ + $out_fq1 \\ --thread $task.cpus \\ --json ${prefix}.fastp.json \\ --html ${prefix}.fastp.html \\ $adapter_list \\ $fail_fastq \\ $args \\ - 2> ${prefix}.fastp.log + 2>| >(tee ${prefix}.fastp.log >&2) cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -81,8 +84,8 @@ process FASTP { fastp \\ --in1 ${prefix}_1.fastq.gz \\ --in2 ${prefix}_2.fastq.gz \\ - --out1 ${prefix}_1.fastp.fastq.gz \\ - --out2 ${prefix}_2.fastp.fastq.gz \\ + $out_fq1 \\ + $out_fq2 \\ --json ${prefix}.fastp.json \\ --html ${prefix}.fastp.html \\ $adapter_list \\ @@ -91,7 +94,7 @@ process FASTP { --thread $task.cpus \\ --detect_adapter_for_pe \\ $args \\ - 2> ${prefix}.fastp.log + 2>| >(tee ${prefix}.fastp.log >&2) cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -99,4 +102,24 @@ process FASTP { END_VERSIONS """ } + + 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_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" + """ + $touch_reads + $touch_fail_fastq + $touch_merged + 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 c22a16abd..b8673272a 100644 --- a/modules/nf-core/fastp/meta.yml +++ b/modules/nf-core/fastp/meta.yml @@ -11,62 +11,114 @@ tools: documentation: https://github.com/OpenGene/fastp doi: 10.1093/bioinformatics/bty560 licence: ["MIT"] + identifier: biotools:fastp input: - - meta: - type: map - description: | - Groovy Map containing sample information. Use 'single_end: true' to specify single ended or interleaved FASTQs. Use 'single_end: false' for paired-end reads. - e.g. [ id:'test', single_end:false ] - - reads: - type: file - description: | - List of input FastQ files of size 1 and 2 for single-end and paired-end data, - respectively. If you wish to run interleaved paired-end data, supply as single-end data - but with `--interleaved_in` in your `modules.conf`'s `ext.args` for the module. + - - meta: + type: map + description: | + Groovy Map containing sample information. Use 'single_end: true' to specify single ended or interleaved FASTQs. Use 'single_end: false' for paired-end reads. + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: | + List of input FastQ files of size 1 and 2 for single-end and paired-end data, + respectively. If you wish to run interleaved paired-end data, supply as single-end data + but with `--interleaved_in` in your `modules.conf`'s `ext.args` for the module. + ontologies: [] - adapter_fasta: type: file description: File in FASTA format containing possible adapters to remove. pattern: "*.{fasta,fna,fas,fa}" + 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` + description: Specify true to save files that failed to pass trimming thresholds + ending in `*.fail.fastq.gz` - save_merged: type: boolean - description: Specify true to save all merged reads to the a file ending in `*.merged.fastq.gz` + description: Specify true to save all merged reads to a file ending in `*.merged.fastq.gz` output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - reads: - type: file - description: The trimmed/modified/unmerged fastq reads - pattern: "*fastp.fastq.gz" - - json: - type: file - description: Results in JSON format - pattern: "*.json" - - html: - type: file - description: Results in HTML format - pattern: "*.html" - - log: - type: file - description: fastq log file - pattern: "*.log" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - reads_fail: - type: file - description: Reads the failed the preprocessing - pattern: "*fail.fastq.gz" - - reads_merged: - type: file - description: Reads that were successfully merged - pattern: "*.{merged.fastq.gz}" + reads: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.fastp.fastq.gz": + type: file + description: The trimmed/modified/unmerged fastq reads + pattern: "*fastp.fastq.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + json: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.json": + type: file + description: Results in JSON format + pattern: "*.json" + ontologies: + - edam: http://edamontology.org/format_3464 # JSON + html: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.html": + type: file + description: Results in HTML format + pattern: "*.html" + ontologies: [] + log: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.log": + type: file + description: fastq log file + pattern: "*.log" + ontologies: [] + reads_fail: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.fail.fastq.gz": + type: file + description: Reads the failed the preprocessing + pattern: "*fail.fastq.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + reads_merged: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.merged.fastq.gz": + type: file + description: Reads that were successfully merged + pattern: "*.{merged.fastq.gz}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@drpatelh" - "@kevinmenden" diff --git a/modules/nf-core/fastp/tests/main.nf.test b/modules/nf-core/fastp/tests/main.nf.test index f610b735e..30dbb8aab 100644 --- a/modules/nf-core/fastp/tests/main.nf.test +++ b/modules/nf-core/fastp/tests/main.nf.test @@ -10,54 +10,32 @@ nextflow_process { test("test_fastp_single_end") { when { - params { - outdir = "$outputDir" - } + process { """ - adapter_fasta = [] - save_trimmed_fail = false - save_merged = false - - input[0] = [ + input[0] = Channel.of([ [ id:'test', single_end:true ], - [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true) ] - ] - - input[1] = adapter_fasta - input[2] = save_trimmed_fail - input[3] = save_merged + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ] + ]) + input[1] = [] + input[2] = false + input[3] = false + input[4] = false """ } } then { - def html_text = [ "Q20 bases:12.922000 K (92.984097%)", - "single end (151 cycles)" ] - def log_text = [ "Q20 bases: 12922(92.9841%)", - "reads passed filter: 99" ] - def read_lines = ["@ERR5069949.2151832 NS500628:121:HK3MMAFX2:2:21208:10793:15304/1", - "TCATAAACCAAAGCACTCACAGTGTCAACAATTTCAGCAGGACAACGCCGACAAGTTCCGAGGAACATGTCTGGACCTATAGTTTTCATAAGTCTACACACTGAATTGAAATATTCTGGTTCTAGTGTGCCCTTAGTTAGCAATGTGCGT", - "AAAAAAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEE - { assert path(process.out.reads.get(0).get(1)).linesGzip.contains(read_line) } - } - }, - { html_text.each { html_part -> - { assert path(process.out.html.get(0).get(1)).getText().contains(html_part) } - } - }, - { assert snapshot(process.out.json).match("test_fastp_single_end_json") }, - { log_text.each { log_part -> - { assert path(process.out.log.get(0).get(1)).getText().contains(log_part) } - } - }, - { assert snapshot(process.out.versions).match("versions") } + { 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() } ) } } @@ -65,421 +43,534 @@ nextflow_process { test("test_fastp_paired_end") { when { - params { - outdir = "$outputDir" - } + process { """ adapter_fasta = [] + save_trimmed_pass = true save_trimmed_fail = false save_merged = false - input[0] = [ + input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test_2_fastq_gz'], checkIfExists: true) ] - ] - - input[1] = adapter_fasta - input[2] = save_trimmed_fail - input[3] = save_merged + [ 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] = false + input[3] = false + input[4] = false """ } } then { - def html_text = [ "Q20 bases:25.719000 K (93.033098%)", - "The input has little adapter percentage (~0.000000%), probably it's trimmed before."] - def log_text = [ "No adapter detected for read1", - "Q30 bases: 12281(88.3716%)"] - def json_text = ['"passed_filter_reads": 198'] - def read1_lines = ["@ERR5069949.2151832 NS500628:121:HK3MMAFX2:2:21208:10793:15304/1", - "TCATAAACCAAAGCACTCACAGTGTCAACAATTTCAGCAGGACAACGCCGACAAGTTCCGAGGAACATGTCTGGACCTATAGTTTTCATAAGTCTACACACTGAATTGAAATATTCTGGTTCTAGTGTGCCCTTAGTTAGCAATGTGCGT", - "AAAAAAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEE - { assert path(process.out.reads.get(0).get(1).get(0)).linesGzip.contains(read1_line) } - } - }, - { read2_lines.each { read2_line -> - { assert path(process.out.reads.get(0).get(1).get(1)).linesGzip.contains(read2_line) } - } - }, - { html_text.each { html_part -> - { assert path(process.out.html.get(0).get(1)).getText().contains(html_part) } - } - }, - { json_text.each { json_part -> - { assert path(process.out.json.get(0).get(1)).getText().contains(json_part) } - } - }, - { log_text.each { log_part -> - { assert path(process.out.log.get(0).get(1)).getText().contains(log_part) } - } - }, - { assert snapshot(process.out.versions).match("versions") } + { 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() } ) } } test("fastp test_fastp_interleaved") { - config './nextflow.config' + + config './nextflow.interleaved.config' 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_interleaved.fastq.gz', checkIfExists: true) ] + ]) + input[1] = [] + input[2] = false + input[3] = false + input[4] = false + """ } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.html.get(0).get(1)).getText().contains("paired end (151 cycles + 151 cycles)") }, + { assert path(process.out.log.get(0).get(1)).getText().contains("reads passed filter: 162") }, + { assert process.out.reads_fail == [] }, + { assert process.out.reads_merged == [] }, + { assert snapshot( + process.out.reads, + process.out.json, + process.out.versions).match() } + ) + } + } + + test("test_fastp_single_end_trim_fail") { + + when { + process { """ - adapter_fasta = [] - 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_1.fastq.gz', checkIfExists: true) ] + ]) + input[1] = [] + input[2] = false + input[3] = true + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { 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() } + ) + } + } - input[0] = [ [ id:'test', single_end:true ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_interleaved_fastq_gz'], checkIfExists: true) ] - ] + test("test_fastp_paired_end_trim_fail") { - input[1] = adapter_fasta - input[2] = save_trimmed_fail - input[3] = save_merged + config './nextflow.save_failed.config' + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true)] + ]) + input[1] = [] + input[2] = false + input[3] = true + input[4] = false """ } } then { - def html_text = [ "Q20 bases:25.719000 K (93.033098%)", - "paired end (151 cycles + 151 cycles)"] - def log_text = [ "Q20 bases: 12922(92.9841%)", - "reads passed filter: 198"] - def read_lines = [ "@ERR5069949.2151832 NS500628:121:HK3MMAFX2:2:21208:10793:15304/1", - "TCATAAACCAAAGCACTCACAGTGTCAACAATTTCAGCAGGACAACGCCGACAAGTTCCGAGGAACATGTCTGGACCTATAGTTTTCATAAGTCTACACACTGAATTGAAATATTCTGGTTCTAGTGTGCCCTTAGTTAGCAATGTGCGT", - "AAAAAAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEE - { assert path(process.out.reads.get(0).get(1)).linesGzip.contains(read_line) } - } - }, - { html_text.each { html_part -> - { assert path(process.out.html.get(0).get(1)).getText().contains(html_part) } - } - }, - { assert snapshot(process.out.json).match("fastp test_fastp_interleaved_json") }, - { log_text.each { log_part -> - { assert path(process.out.log.get(0).get(1)).getText().contains(log_part) } - } - }, - { assert snapshot(process.out.versions).match("versions") } + { 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("reads passed filter: 162") }, + { assert snapshot( + process.out.reads, + process.out.reads_fail, + process.out.reads_merged, + process.out.json, + process.out.versions).match() } ) } } - test("test_fastp_single_end_trim_fail") { + test("test_fastp_paired_end_merged") { 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) ] + ]) + input[1] = [] + input[2] = false + input[3] = false + input[4] = true + """ } + } + + then { + assertAll( + { assert process.success }, + { 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() }, + ) + } + } + + test("test_fastp_paired_end_merged_adapterlist") { + + when { process { """ - adapter_fasta = [] - 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) ] + ]) + 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[0] = [ [ id:'test', single_end:true ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true) ] - ] - input[1] = adapter_fasta - input[2] = save_trimmed_fail - input[3] = save_merged + then { + assertAll( + { assert process.success }, + { 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() } + ) + } + } + + test("test_fastp_single_end_qc_only") { + + when { + process { + """ + 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] = true + input[3] = false + input[4] = false """ } } then { - def html_text = [ "Q20 bases:12.922000 K (92.984097%)", - "single end (151 cycles)"] - def log_text = [ "Q20 bases: 12922(92.9841%)", - "reads passed filter: 99" ] - def read_lines = [ "@ERR5069949.2151832 NS500628:121:HK3MMAFX2:2:21208:10793:15304/1", - "TCATAAACCAAAGCACTCACAGTGTCAACAATTTCAGCAGGACAACGCCGACAAGTTCCGAGGAACATGTCTGGACCTATAGTTTTCATAAGTCTACACACTGAATTGAAATATTCTGGTTCTAGTGTGCCCTTAGTTAGCAATGTGCGT", - "AAAAAAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEE - { assert path(process.out.reads.get(0).get(1)).linesGzip.contains(read_line) } - } - }, - { failed_read_lines.each { failed_read_line -> - { assert path(process.out.reads_fail.get(0).get(1)).linesGzip.contains(failed_read_line) } - } - }, - { html_text.each { html_part -> - { assert path(process.out.html.get(0).get(1)).getText().contains(html_part) } - } - }, - { assert snapshot(process.out.json).match("test_fastp_single_end_trim_fail_json") }, - { log_text.each { log_part -> - { assert path(process.out.log.get(0).get(1)).getText().contains(log_part) } - } - }, - { assert snapshot(process.out.versions).match("versions") } + { 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() } ) } } - test("test_fastp_paired_end_trim_fail") { + test("test_fastp_paired_end_qc_only") { 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) ] + ]) + input[1] = [] + input[2] = true + input[3] = false + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { 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() } + ) + } + } + + test("test_fastp_single_end - stub") { + + options "-stub" + + when { + + process { + """ + 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] = false + input[3] = false + input[4] = false + """ } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_fastp_paired_end - stub") { + + options "-stub" + + when { + process { """ adapter_fasta = [] - save_trimmed_fail = true + save_trimmed_pass = true + save_trimmed_fail = false save_merged = false - input[0] = [ + input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map - [ - file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test_2_fastq_gz'], checkIfExists: true) - ] - ] - input[1] = adapter_fasta - input[2] = save_trimmed_fail - input[3] = save_merged + [ 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] = false + input[3] = false + input[4] = false """ } } then { - def html_text = [ "Q20 bases:25.719000 K (93.033098%)", - "The input has little adapter percentage (~0.000000%), probably it's trimmed before."] - def log_text = [ "No adapter detected for read1", - "Q30 bases: 12281(88.3716%)"] - def json_text = ['"passed_filter_reads": 198'] - def read1_lines = ["@ERR5069949.2151832 NS500628:121:HK3MMAFX2:2:21208:10793:15304/1", - "TCATAAACCAAAGCACTCACAGTGTCAACAATTTCAGCAGGACAACGCCGACAAGTTCCGAGGAACATGTCTGGACCTATAGTTTTCATAAGTCTACACACTGAATTGAAATATTCTGGTTCTAGTGTGCCCTTAGTTAGCAATGTGCGT", - "AAAAAAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEE - { assert path(process.out.reads.get(0).get(1).get(0)).linesGzip.contains(read1_line) } - } - }, - { read2_lines.each { read2_line -> - { assert path(process.out.reads.get(0).get(1).get(1)).linesGzip.contains(read2_line) } - } - }, - { failed_read2_lines.each { failed_read2_line -> - { assert path(process.out.reads_fail.get(0).get(1).get(1)).linesGzip.contains(failed_read2_line) } - } - }, - { html_text.each { html_part -> - { assert path(process.out.html.get(0).get(1)).getText().contains(html_part) } - } - }, - { json_text.each { json_part -> - { assert path(process.out.json.get(0).get(1)).getText().contains(json_part) } - } - }, - { log_text.each { log_part -> - { assert path(process.out.log.get(0).get(1)).getText().contains(log_part) } - } - }, - { assert snapshot(process.out.versions).match("versions") } + { assert snapshot(process.out).match() } ) } } - test("test_fastp_paired_end_merged") { + test("fastp - stub test_fastp_interleaved") { + + options "-stub" + config './nextflow.interleaved.config' 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_interleaved.fastq.gz', checkIfExists: true) ] + ]) + input[1] = [] + input[2] = false + input[3] = false + input[4] = false + """ } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_fastp_single_end_trim_fail - stub") { + + options "-stub" + + when { + process { """ - adapter_fasta = [] - save_trimmed_fail = false - save_merged = true + 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) ] + ]) + input[1] = [] + input[2] = false + input[3] = true + input[4] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_fastp_paired_end_trim_fail - stub") { - input[0] = [ [ id:'test', single_end:false ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test_2_fastq_gz'], checkIfExists: true) ] - ] - input[1] = adapter_fasta - input[2] = save_trimmed_fail - input[3] = save_merged + options "-stub" + + config './nextflow.save_failed.config' + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true)] + ]) + input[1] = [] + input[2] = false + input[3] = true + input[4] = false """ } } then { - def html_text = [ "
"] - def log_text = [ "Merged and filtered:", - "total reads: 75", - "total bases: 13683"] - def json_text = ['"merged_and_filtered": {', '"total_reads": 75', '"total_bases": 13683'] - def read1_lines = [ "@ERR5069949.1066259 NS500628:121:HK3MMAFX2:1:11312:18369:8333/1", - "CCTTATGACAGCAAGAACTGTGTATGATGATGGTGCTAGGAGAGTGTGGACACTTATGAATGTCTTGACACTCGTTTATAAAGTTTATTATGGTAATGCTTTAGATCAAGCCATTTCCATGTGGGCTCTTATAATCTCTGTTACTTC", - "AAAAAEAEEAEEEEEEEEEEEEEEEEAEEEEAEEEEEEEEAEEEEEEEEEEEEEEEEE/EAEEEEEE/6EEEEEEEEEEAEEAEEE/EE/AEEAEEEEEAEEEA/EEAAEAE - { assert path(process.out.reads.get(0).get(1).get(0)).linesGzip.contains(read1_line) } - } - }, - { read2_lines.each { read2_line -> - { assert path(process.out.reads.get(0).get(1).get(1)).linesGzip.contains(read2_line) } - } - }, - { read_merged_lines.each { read_merged_line -> - { assert path(process.out.reads_merged.get(0).get(1)).linesGzip.contains(read_merged_line) } - } - }, - { html_text.each { html_part -> - { assert path(process.out.html.get(0).get(1)).getText().contains(html_part) } - } - }, - { json_text.each { json_part -> - { assert path(process.out.json.get(0).get(1)).getText().contains(json_part) } - } - }, - { log_text.each { log_part -> - { assert path(process.out.log.get(0).get(1)).getText().contains(log_part) } - } - }, - { assert snapshot(process.out.versions).match("versions") } + { assert snapshot(process.out).match() } ) } } - test("test_fastp_paired_end_merged_adapterlist") { + test("test_fastp_paired_end_merged - stub") { + + options "-stub" 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) ] + ]) + input[1] = [] + input[2] = false + input[3] = false + input[4] = true + """ } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_fastp_paired_end_merged_adapterlist - stub") { + + options "-stub" + + when { process { """ - adapter_fasta = file("https://github.com/nf-core/test-datasets/raw/modules/data/delete_me/fastp/adapters.fasta", checkIfExists: true) - 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) ] + ]) + 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[0] = [ [ id:'test', single_end:false ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test_2_fastq_gz'], checkIfExists: true) ] - ] - input[1] = adapter_fasta - input[2] = save_trimmed_fail - input[3] = save_merged + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_fastp_single_end_qc_only - stub") { + + options "-stub" + + when { + process { + """ + 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] = true + input[3] = false + input[4] = false """ } } then { - def html_text = [ "
"] - def log_text = [ "Merged and filtered:", - "total reads: 75", - "total bases: 13683"] - def json_text = ['"merged_and_filtered": {', '"total_reads": 75', '"total_bases": 13683',"--adapter_fasta"] - def read1_lines = ["@ERR5069949.1066259 NS500628:121:HK3MMAFX2:1:11312:18369:8333/1", - "CCTTATGACAGCAAGAACTGTGTATGATGATGGTGCTAGGAGAGTGTGGACACTTATGAATGTCTTGACACTCGTTTATAAAGTTTATTATGGTAATGCTTTAGATCAAGCCATTTCCATGTGGGCTCTTATAATCTCTGTTACTTC", - "AAAAAEAEEAEEEEEEEEEEEEEEEEAEEEEAEEEEEEEEAEEEEEEEEEEEEEEEEE/EAEEEEEE/6EEEEEEEEEEAEEAEEE/EE/AEEAEEEEEAEEEA/EEAAEAE - { assert path(process.out.reads.get(0).get(1).get(0)).linesGzip.contains(read1_line) } - } - }, - { read2_lines.each { read2_line -> - { assert path(process.out.reads.get(0).get(1).get(1)).linesGzip.contains(read2_line) } - } - }, - { read_merged_lines.each { read_merged_line -> - { assert path(process.out.reads_merged.get(0).get(1)).linesGzip.contains(read_merged_line) } - } - }, - { html_text.each { html_part -> - { assert path(process.out.html.get(0).get(1)).getText().contains(html_part) } - } - }, - { json_text.each { json_part -> - { assert path(process.out.json.get(0).get(1)).getText().contains(json_part) } - } - }, - { log_text.each { log_part -> - { assert path(process.out.log.get(0).get(1)).getText().contains(log_part) } - } - }, - { assert snapshot(process.out.versions).match("versions") } + { assert snapshot(process.out).match() } ) } } -} +} \ 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 0fa68c7d7..9e2aaf315 100644 --- a/modules/nf-core/fastp/tests/main.nf.test.snap +++ b/modules/nf-core/fastp/tests/main.nf.test.snap @@ -1,5 +1,178 @@ { - "fastp test_fastp_interleaved_json": { + "test_fastp_single_end_qc_only - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ], + "html": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + + ], + "reads_fail": [ + + ], + "reads_merged": [ + + ], + "versions": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:40:51.8619133" + }, + "test_fastp_paired_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,7cf3bff1922b512bcca58439eb2d3679" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7", + "test_2.fastp.fastq.gz:md5,25cbdca08e2083dbd4f0502de6b62f39" + ] + ] + ], + [ + + ], + [ + + ], + [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:39:15.121411815" + }, + "test_fastp_paired_end_merged_adapterlist": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,533983f8c11cc3f2ccdcea01531f68ae" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,54b726a55e992a869fd3fa778afe1672", + "test_2.fastp.fastq.gz:md5,29d3b33b869f7b63417b8ff07bb128ba" + ] + ] + ], + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,c873bb1ab3fa859dcc47306465e749d5" + ] + ], + [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:39:51.561598206" + }, + "test_fastp_single_end_qc_only": { "content": [ [ [ @@ -7,35 +180,985 @@ "id": "test", "single_end": true }, - "test.fastp.json:md5,168f516f7bd4b7b6c32da7cba87299a4" + "test.fastp.json:md5,93f407199ee8b94c023c291bddfc4dce" + ] + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:39:56.392912049" + }, + "test_fastp_paired_end_trim_fail": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,6ff32a64c5188b9a9192be1398c262c7", + "test_2.fastp.fastq.gz:md5,db0cb7c9977e94ac2b4b446ebd017a8a" + ] + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.paired.fail.fastq.gz:md5,409b687c734cedd7a1fec14d316e1366", + "test_1.fail.fastq.gz:md5,4f273cf3159c13f79e8ffae12f5661f6", + "test_2.fail.fastq.gz:md5,f97b9edefb5649aab661fbc9e71fc995" + ] + ] + ], + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,5009a892192f2084c2af69c153d88d6c" ] + ], + [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" ] ], - "timestamp": "2023-10-17T11:04:45.794175881" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:39:38.690242568" + }, + "fastp - stub test_fastp_interleaved": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ], + "html": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "reads_fail": [ + + ], + "reads_merged": [ + + ], + "versions": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:40:23.678200076" + }, + "test_fastp_single_end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ], + "html": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "reads_fail": [ + + ], + "reads_merged": [ + + ], + "versions": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:40:08.756547678" + }, + "test_fastp_paired_end_merged_adapterlist - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "6": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "reads_fail": [ + + ], + "reads_merged": [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:40:47.596331823" }, - "test_fastp_single_end_json": { + "test_fastp_paired_end_merged - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "6": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "reads_fail": [ + + ], + "reads_merged": [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:40:39.962303534" + }, + "test_fastp_paired_end_merged": { "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,8f99097bfa04b629891105b8af9c429f" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,54b726a55e992a869fd3fa778afe1672", + "test_2.fastp.fastq.gz:md5,29d3b33b869f7b63417b8ff07bb128ba" + ] + ] + ], + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,c873bb1ab3fa859dcc47306465e749d5" + ] + ], + [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:39:46.300238743" + }, + "test_fastp_paired_end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "reads_fail": [ + + ], + "reads_merged": [ + + ], + "versions": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:40:16.309925689" + }, + "test_fastp_single_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,81dc86dd695967bb5c015e0a978bf20c" + ] + ], [ [ { "id": "test", "single_end": true }, - "test.fastp.json:md5,c852d7a6dba5819e4ac8d9673bedcacc" + "test.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7" ] + ], + [ + + ], + [ + + ], + [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" ] ], - "timestamp": "2023-10-17T11:04:10.566343705" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:39:07.133909607" }, - "versions": { + "test_fastp_single_end_trim_fail - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ], + "html": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "reads_fail": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "reads_merged": [ + + ], + "versions": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:40:28.086573661" + }, + "test_fastp_paired_end_trim_fail - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.paired.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_1.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "reads_fail": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.paired.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_1.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "reads_merged": [ + + ], + "versions": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:40:35.606162029" + }, + "fastp test_fastp_interleaved": { "content": [ [ - "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02" + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,217d62dc13a23e92513a1bd8e1bcea39" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,101003b8ac634ca5fd381656ac2b8b9f" + ] + ], + [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" ] ], - "timestamp": "2023-10-17T11:04:10.582076024" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:39:23.114582408" }, - "test_fastp_single_end_trim_fail_json": { + "test_fastp_single_end_trim_fail": { "content": [ [ [ @@ -43,10 +1166,166 @@ "id": "test", "single_end": true }, - "test.fastp.json:md5,9a7ee180f000e8d00c7fb67f06293eb5" + "test.fastp.json:md5,d721f75d68a382c819b6499e6325a942" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.fail.fastq.gz:md5,3e4aaadb66a5b8fc9b881bf39c227abd" ] + ], + [ + + ], + [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" ] ], - "timestamp": "2023-10-17T11:05:00.379878948" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:39:30.757538842" + }, + "test_fastp_paired_end_qc_only": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,1ad31d6559ff5d4d275f501f3f5c02b9" + ] + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:40:01.381972575" + }, + "test_fastp_paired_end_qc_only - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + + ], + "reads_fail": [ + + ], + "reads_merged": [ + + ], + "versions": [ + "versions.yml:md5,3799377c4173131ba9392346e1c40bb9" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:40:56.392034947" } } \ No newline at end of file diff --git a/modules/nf-core/fastp/tests/nextflow.interleaved.config b/modules/nf-core/fastp/tests/nextflow.interleaved.config new file mode 100644 index 000000000..4be8dbd2c --- /dev/null +++ b/modules/nf-core/fastp/tests/nextflow.interleaved.config @@ -0,0 +1,5 @@ +process { + withName: FASTP { + ext.args = "--interleaved_in -e 30" + } +} diff --git a/modules/nf-core/fastp/tests/nextflow.config b/modules/nf-core/fastp/tests/nextflow.save_failed.config similarity index 50% rename from modules/nf-core/fastp/tests/nextflow.config rename to modules/nf-core/fastp/tests/nextflow.save_failed.config index 0f7849ad9..53b61b0c1 100644 --- a/modules/nf-core/fastp/tests/nextflow.config +++ b/modules/nf-core/fastp/tests/nextflow.save_failed.config @@ -1,6 +1,5 @@ process { - withName: FASTP { - ext.args = "--interleaved_in" + ext.args = "-e 30" } } diff --git a/modules/nf-core/fastp/tests/tags.yml b/modules/nf-core/fastp/tests/tags.yml deleted file mode 100644 index c1afcce75..000000000 --- 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/fastqc/environment.yml b/modules/nf-core/fastqc/environment.yml index 1787b38a9..f9f54ee9b 100644 --- a/modules/nf-core/fastqc/environment.yml +++ b/modules/nf-core/fastqc/environment.yml @@ -1,7 +1,7 @@ -name: fastqc +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::fastqc=0.12.1 diff --git a/modules/nf-core/fastqc/main.nf b/modules/nf-core/fastqc/main.nf index 9e19a74c5..23e16634c 100644 --- a/modules/nf-core/fastqc/main.nf +++ b/modules/nf-core/fastqc/main.nf @@ -1,5 +1,5 @@ process FASTQC { - tag "$meta.id" + tag "${meta.id}" label 'process_medium' conda "${moduleDir}/environment.yml" @@ -19,21 +19,30 @@ process FASTQC { 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}" // Make list of old name and new name pairs to use for renaming in the bash while loop def old_new_pairs = reads instanceof Path || reads.size() == 1 ? [[ reads, "${prefix}.${reads.extension}" ]] : reads.withIndex().collect { entry, index -> [ entry, "${prefix}_${index + 1}.${entry.extension}" ] } - def rename_to = old_new_pairs*.join(' ').join(' ') - def renamed_files = old_new_pairs.collect{ old_name, new_name -> new_name }.join(' ') + def rename_to = old_new_pairs*.join(' ').join(' ') + def renamed_files = old_new_pairs.collect{ _old_name, new_name -> new_name }.join(' ') + + // The total amount of allocated RAM by FastQC is equal to the number of threads defined (--threads) time the amount of RAM defined (--memory) + // https://github.com/s-andrews/FastQC/blob/1faeea0412093224d7f6a07f777fad60a5650795/fastqc#L211-L222 + // Dividing the task.memory by task.cpu allows to stick to requested amount of RAM in the label + def memory_in_mb = task.memory ? task.memory.toUnit('MB') / task.cpus : null + // FastQC memory value allowed range (100 - 10000) + def fastqc_memory = memory_in_mb > 10000 ? 10000 : (memory_in_mb < 100 ? 100 : memory_in_mb) + """ - printf "%s %s\\n" $rename_to | while read old_name new_name; do + printf "%s %s\\n" ${rename_to} | while read old_name new_name; do [ -f "\${new_name}" ] || ln -s \$old_name \$new_name done fastqc \\ - $args \\ - --threads $task.cpus \\ - $renamed_files + ${args} \\ + --threads ${task.cpus} \\ + --memory ${fastqc_memory} \\ + ${renamed_files} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/fastqc/meta.yml b/modules/nf-core/fastqc/meta.yml index ee5507e06..c8d9d025a 100644 --- a/modules/nf-core/fastqc/meta.yml +++ b/modules/nf-core/fastqc/meta.yml @@ -11,40 +11,55 @@ tools: FastQC gives general quality metrics about your reads. It provides information about the quality score distribution across your reads, the per base sequence content (%A/C/G/T). + You get information about adapter contamination and other overrepresented sequences. homepage: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/ documentation: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/Help/ licence: ["GPL-2.0-only"] + identifier: biotools:fastqc input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - reads: - type: file - description: | - List of input FastQ files of size 1 and 2 for single-end and paired-end data, - respectively. + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: | + List of input FastQ files of size 1 and 2 for single-end and paired-end data, + respectively. + ontologies: [] output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - html: - type: file - description: FastQC report - pattern: "*_{fastqc.html}" - - zip: - type: file - description: FastQC report archive - pattern: "*_{fastqc.zip}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + html: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.html": + type: file + description: FastQC report + pattern: "*_{fastqc.html}" + ontologies: [] + zip: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.zip": + type: file + description: FastQC report archive + pattern: "*_{fastqc.zip}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@drpatelh" - "@grst" diff --git a/modules/nf-core/fastqc/tests/main.nf.test b/modules/nf-core/fastqc/tests/main.nf.test index 70edae4d9..e9d79a074 100644 --- a/modules/nf-core/fastqc/tests/main.nf.test +++ b/modules/nf-core/fastqc/tests/main.nf.test @@ -23,17 +23,14 @@ nextflow_process { then { assertAll ( - { assert process.success }, - - // NOTE The report contains the date inside it, which means that the md5sum is stable per day, but not longer than that. So you can't md5sum it. - // looks like this:
Mon 2 Oct 2023
test.gz
- // https://github.com/nf-core/modules/pull/3903#issuecomment-1743620039 - - { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, - { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, - { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, - - { assert snapshot(process.out.versions).match("fastqc_versions_single") } + { assert process.success }, + // NOTE The report contains the date inside it, which means that the md5sum is stable per day, but not longer than that. So you can't md5sum it. + // looks like this:
Mon 2 Oct 2023
test.gz
+ // https://github.com/nf-core/modules/pull/3903#issuecomment-1743620039 + { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, + { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, + { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, + { assert snapshot(process.out.versions).match() } ) } } @@ -54,16 +51,14 @@ nextflow_process { then { assertAll ( - { assert process.success }, - - { assert process.out.html[0][1][0] ==~ ".*/test_1_fastqc.html" }, - { assert process.out.html[0][1][1] ==~ ".*/test_2_fastqc.html" }, - { assert process.out.zip[0][1][0] ==~ ".*/test_1_fastqc.zip" }, - { assert process.out.zip[0][1][1] ==~ ".*/test_2_fastqc.zip" }, - { assert path(process.out.html[0][1][0]).text.contains("File typeConventional base calls") }, - { assert path(process.out.html[0][1][1]).text.contains("File typeConventional base calls") }, - - { assert snapshot(process.out.versions).match("fastqc_versions_paired") } + { assert process.success }, + { assert process.out.html[0][1][0] ==~ ".*/test_1_fastqc.html" }, + { assert process.out.html[0][1][1] ==~ ".*/test_2_fastqc.html" }, + { assert process.out.zip[0][1][0] ==~ ".*/test_1_fastqc.zip" }, + { assert process.out.zip[0][1][1] ==~ ".*/test_2_fastqc.zip" }, + { assert path(process.out.html[0][1][0]).text.contains("File typeConventional base calls") }, + { assert path(process.out.html[0][1][1]).text.contains("File typeConventional base calls") }, + { assert snapshot(process.out.versions).match() } ) } } @@ -83,13 +78,11 @@ nextflow_process { then { assertAll ( - { assert process.success }, - - { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, - { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, - { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, - - { assert snapshot(process.out.versions).match("fastqc_versions_interleaved") } + { assert process.success }, + { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, + { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, + { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, + { assert snapshot(process.out.versions).match() } ) } } @@ -109,13 +102,11 @@ nextflow_process { then { assertAll ( - { assert process.success }, - - { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, - { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, - { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, - - { assert snapshot(process.out.versions).match("fastqc_versions_bam") } + { assert process.success }, + { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" }, + { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" }, + { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, + { assert snapshot(process.out.versions).match() } ) } } @@ -138,22 +129,20 @@ nextflow_process { then { assertAll ( - { assert process.success }, - - { assert process.out.html[0][1][0] ==~ ".*/test_1_fastqc.html" }, - { assert process.out.html[0][1][1] ==~ ".*/test_2_fastqc.html" }, - { assert process.out.html[0][1][2] ==~ ".*/test_3_fastqc.html" }, - { assert process.out.html[0][1][3] ==~ ".*/test_4_fastqc.html" }, - { assert process.out.zip[0][1][0] ==~ ".*/test_1_fastqc.zip" }, - { assert process.out.zip[0][1][1] ==~ ".*/test_2_fastqc.zip" }, - { assert process.out.zip[0][1][2] ==~ ".*/test_3_fastqc.zip" }, - { assert process.out.zip[0][1][3] ==~ ".*/test_4_fastqc.zip" }, - { assert path(process.out.html[0][1][0]).text.contains("File typeConventional base calls") }, - { assert path(process.out.html[0][1][1]).text.contains("File typeConventional base calls") }, - { assert path(process.out.html[0][1][2]).text.contains("File typeConventional base calls") }, - { assert path(process.out.html[0][1][3]).text.contains("File typeConventional base calls") }, - - { assert snapshot(process.out.versions).match("fastqc_versions_multiple") } + { assert process.success }, + { assert process.out.html[0][1][0] ==~ ".*/test_1_fastqc.html" }, + { assert process.out.html[0][1][1] ==~ ".*/test_2_fastqc.html" }, + { assert process.out.html[0][1][2] ==~ ".*/test_3_fastqc.html" }, + { assert process.out.html[0][1][3] ==~ ".*/test_4_fastqc.html" }, + { assert process.out.zip[0][1][0] ==~ ".*/test_1_fastqc.zip" }, + { assert process.out.zip[0][1][1] ==~ ".*/test_2_fastqc.zip" }, + { assert process.out.zip[0][1][2] ==~ ".*/test_3_fastqc.zip" }, + { assert process.out.zip[0][1][3] ==~ ".*/test_4_fastqc.zip" }, + { assert path(process.out.html[0][1][0]).text.contains("File typeConventional base calls") }, + { assert path(process.out.html[0][1][1]).text.contains("File typeConventional base calls") }, + { assert path(process.out.html[0][1][2]).text.contains("File typeConventional base calls") }, + { assert path(process.out.html[0][1][3]).text.contains("File typeConventional base calls") }, + { assert snapshot(process.out.versions).match() } ) } } @@ -173,21 +162,18 @@ nextflow_process { then { assertAll ( - { assert process.success }, - - { assert process.out.html[0][1] ==~ ".*/mysample_fastqc.html" }, - { assert process.out.zip[0][1] ==~ ".*/mysample_fastqc.zip" }, - { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, - - { assert snapshot(process.out.versions).match("fastqc_versions_custom_prefix") } + { assert process.success }, + { assert process.out.html[0][1] ==~ ".*/mysample_fastqc.html" }, + { assert process.out.zip[0][1] ==~ ".*/mysample_fastqc.zip" }, + { assert path(process.out.html[0][1]).text.contains("File typeConventional base calls") }, + { assert snapshot(process.out.versions).match() } ) } } test("sarscov2 single-end [fastq] - stub") { - options "-stub" - + options "-stub" when { process { """ @@ -201,12 +187,123 @@ nextflow_process { then { assertAll ( - { assert process.success }, - { assert snapshot(process.out.html.collect { file(it[1]).getName() } + - process.out.zip.collect { file(it[1]).getName() } + - process.out.versions ).match("fastqc_stub") } + { assert process.success }, + { assert snapshot(process.out).match() } ) } } + test("sarscov2 paired-end [fastq] - stub") { + + options "-stub" + when { + process { + """ + input[0] = Channel.of([ + [id: 'test', single_end: false], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ] + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 interleaved [fastq] - stub") { + + options "-stub" + when { + process { + """ + input[0] = Channel.of([ + [id: 'test', single_end: false], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_interleaved.fastq.gz', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 paired-end [bam] - stub") { + + options "-stub" + when { + process { + """ + input[0] = Channel.of([ + [id: 'test', single_end: false], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 multiple [fastq] - stub") { + + options "-stub" + when { + process { + """ + input[0] = Channel.of([ + [id: 'test', single_end: false], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_2.fastq.gz', checkIfExists: true) ] + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 custom_prefix - stub") { + + options "-stub" + when { + process { + """ + input[0] = Channel.of([ + [ id:'mysample', single_end:true ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } } diff --git a/modules/nf-core/fastqc/tests/main.nf.test.snap b/modules/nf-core/fastqc/tests/main.nf.test.snap index 86f7c3115..d5db3092f 100644 --- a/modules/nf-core/fastqc/tests/main.nf.test.snap +++ b/modules/nf-core/fastqc/tests/main.nf.test.snap @@ -1,88 +1,392 @@ { - "fastqc_versions_interleaved": { + "sarscov2 custom_prefix": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:40:07.293713" + "timestamp": "2024-07-22T11:02:16.374038" }, - "fastqc_stub": { + "sarscov2 single-end [fastq] - stub": { "content": [ - [ - "test.html", - "test.zip", - "versions.yml:md5,e1cc25ca8af856014824abd842e93978" - ] + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "test", + "single_end": true + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "test", + "single_end": true + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:02:24.993809" + }, + "sarscov2 custom_prefix - stub": { + "content": [ + { + "0": [ + [ + { + "id": "mysample", + "single_end": true + }, + "mysample.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "mysample", + "single_end": true + }, + "mysample.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "mysample", + "single_end": true + }, + "mysample.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "mysample", + "single_end": true + }, + "mysample.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:31:01.425198" + "timestamp": "2024-07-22T11:03:10.93942" }, - "fastqc_versions_multiple": { + "sarscov2 interleaved [fastq]": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:40:55.797907" + "timestamp": "2024-07-22T11:01:42.355718" }, - "fastqc_versions_bam": { + "sarscov2 paired-end [bam]": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:40:26.795862" + "timestamp": "2024-07-22T11:01:53.276274" }, - "fastqc_versions_single": { + "sarscov2 multiple [fastq]": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:39:27.043675" + "timestamp": "2024-07-22T11:02:05.527626" }, - "fastqc_versions_paired": { + "sarscov2 paired-end [fastq]": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:01:31.188871" + }, + "sarscov2 paired-end [fastq] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:02:34.273566" + }, + "sarscov2 multiple [fastq] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:39:47.584191" + "timestamp": "2024-07-22T11:03:02.304411" }, - "fastqc_versions_custom_prefix": { + "sarscov2 single-end [fastq]": { "content": [ [ "versions.yml:md5,e1cc25ca8af856014824abd842e93978" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:01:19.095607" + }, + "sarscov2 interleaved [fastq] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" + }, + "timestamp": "2024-07-22T11:02:44.640184" + }, + "sarscov2 paired-end [bam] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e1cc25ca8af856014824abd842e93978" + ], + "zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.3" }, - "timestamp": "2024-01-31T17:41:14.576531" + "timestamp": "2024-07-22T11:02:53.550742" } } \ No newline at end of file diff --git a/modules/nf-core/fastqc/tests/tags.yml b/modules/nf-core/fastqc/tests/tags.yml deleted file mode 100644 index 7834294ba..000000000 --- a/modules/nf-core/fastqc/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -fastqc: - - modules/nf-core/fastqc/** diff --git a/modules/nf-core/fusioncatcher/fusioncatcher/environment.yml b/modules/nf-core/fusioncatcher/fusioncatcher/environment.yml new file mode 100644 index 000000000..8651e2af4 --- /dev/null +++ b/modules/nf-core/fusioncatcher/fusioncatcher/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - "bioconda::fusioncatcher=1.33b" diff --git a/modules/nf-core/fusioncatcher/fusioncatcher/fusioncatcher-fusioncatcher.diff b/modules/nf-core/fusioncatcher/fusioncatcher/fusioncatcher-fusioncatcher.diff new file mode 100644 index 000000000..49b2daf36 --- /dev/null +++ b/modules/nf-core/fusioncatcher/fusioncatcher/fusioncatcher-fusioncatcher.diff @@ -0,0 +1,30 @@ +Changes in component 'nf-core/fusioncatcher/fusioncatcher' +Changes in 'fusioncatcher/fusioncatcher/main.nf': +--- modules/nf-core/fusioncatcher/fusioncatcher/main.nf ++++ modules/nf-core/fusioncatcher/fusioncatcher/main.nf +@@ -4,8 +4,8 @@ + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? +- 'https://depot.galaxyproject.org/singularity/fusioncatcher:1.33--hdfd78af_5': +- 'biocontainers/fusioncatcher:1.33--hdfd78af_5' }" ++ 'https://depot.galaxyproject.org/singularity/fusioncatcher:1.33b--hdfd78af_0': ++ 'biocontainers/fusioncatcher:1.33b--hdfd78af_0' }" + + input: + tuple val(meta), path(fastqs) + +Changes in 'fusioncatcher/fusioncatcher/environment.yml': +--- modules/nf-core/fusioncatcher/fusioncatcher/environment.yml ++++ modules/nf-core/fusioncatcher/fusioncatcher/environment.yml +@@ -4,4 +4,4 @@ + - conda-forge + - bioconda + dependencies: +- - "bioconda::fusioncatcher=1.33" ++ - "bioconda::fusioncatcher=1.33b" + +'modules/nf-core/fusioncatcher/fusioncatcher/meta.yml' is unchanged +'modules/nf-core/fusioncatcher/fusioncatcher/tests/main.nf.test' is unchanged +'modules/nf-core/fusioncatcher/fusioncatcher/tests/main.nf.test.snap' is unchanged +************************************************************ diff --git a/modules/nf-core/fusioncatcher/fusioncatcher/main.nf b/modules/nf-core/fusioncatcher/fusioncatcher/main.nf new file mode 100644 index 000000000..ae44e6864 --- /dev/null +++ b/modules/nf-core/fusioncatcher/fusioncatcher/main.nf @@ -0,0 +1,65 @@ +process FUSIONCATCHER_FUSIONCATCHER { + 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/fusioncatcher:1.33b--hdfd78af_0': + 'biocontainers/fusioncatcher:1.33b--hdfd78af_0' }" + + input: + tuple val(meta), path(fastqs) + tuple val(meta2), path(reference) + + output: + tuple val(meta), path("*.fusion-genes.txt"), emit: fusions, optional: true + tuple val(meta), path("*.summary.txt") , emit: summary, optional: true + tuple val(meta), path("*.log") , emit: log + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def input = fastqs.join(",") + + def avail_mem = 3072 + if (!task.memory) { + log.info '[FusionCatcher] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' + } else { + avail_mem = (task.memory.mega*0.8).intValue() + } + """ + fusioncatcher \\ + --input=${input} \\ + --output=. \\ + --data=${reference} \\ + --threads=${task.cpus} \\ + --Xmx=${avail_mem}M \\ + ${args} + + mv final-list_candidate-fusion-genes.txt ${prefix}.fusion-genes.txt + mv summary_candidate_fusions.txt ${prefix}.summary.txt + mv fusioncatcher.log ${prefix}.log + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fusioncatcher: "\$(fusioncatcher --version 2>&1 | awk '{print \$2}')" + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.fusion-genes.txt + touch ${prefix}.summary.txt + touch ${prefix}.log + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fusioncatcher: "\$(fusioncatcher --version 2>&1 | awk '{print \$2}')" + END_VERSIONS + """ +} diff --git a/modules/nf-core/fusioncatcher/fusioncatcher/meta.yml b/modules/nf-core/fusioncatcher/fusioncatcher/meta.yml new file mode 100644 index 000000000..ae9c37e95 --- /dev/null +++ b/modules/nf-core/fusioncatcher/fusioncatcher/meta.yml @@ -0,0 +1,85 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "fusioncatcher_fusioncatcher" +description: FusionCatcher searches for novel/known somatic fusion genes, translocations, + and chimeras in RNA-seq data +keywords: + - fusion + - rna + - fastq +tools: + - fusioncatcher: + description: FusionCatcher searches for novel/known somatic fusion genes, translocations, + and chimeras in RNA-seq data + homepage: https://github.com/ndaniel/fusioncatcher + documentation: https://github.com/ndaniel/fusioncatcher/wiki + tool_dev_url: https://github.com/ndaniel/fusioncatcher + doi: "10.1101/011650v1" + licence: ["GPL v3"] + identifier: biotools:fusioncatcher + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - fastqs: + type: list + description: A list of input fastq files + pattern: "*.{fastq,fq}.gz" + - - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. `[ id:'sample1', single_end:false ]` + - reference: + type: file + description: Directory containing fusioncatcher reference files + + ontologies: [] +output: + fusions: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - "*.fusion-genes.txt": + type: file + description: The detected fusions in the input files + pattern: "*.fusion-genes.txt" + ontologies: [] + summary: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - "*.summary.txt": + type: file + description: The generated summary + pattern: "*.summary.txt" + ontologies: [] + log: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - "*.log": + type: file + description: The Fusioncatcher log + pattern: "*.log" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@nvnieuwk" +maintainers: + - "@nvnieuwk" diff --git a/modules/nf-core/fusioncatcher/fusioncatcher/tests/main.nf.test b/modules/nf-core/fusioncatcher/fusioncatcher/tests/main.nf.test new file mode 100644 index 000000000..28e9d13ec --- /dev/null +++ b/modules/nf-core/fusioncatcher/fusioncatcher/tests/main.nf.test @@ -0,0 +1,43 @@ +nextflow_process { + + name "Test Process FUSIONCATCHER_FUSIONCATCHER" + script "../main.nf" + process "FUSIONCATCHER_FUSIONCATCHER" + + tag "modules" + tag "modules_nfcore" + tag "fusioncatcher" + tag "fusioncatcher/fusioncatcher" + + // Only stub tests because the refernce is about 50 GB of data + + test("sarscov2 - fastq - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ 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), + ] + input[1] = [ + [ id:'reference'], + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/fusioncatcher/fusioncatcher/tests/main.nf.test.snap b/modules/nf-core/fusioncatcher/fusioncatcher/tests/main.nf.test.snap new file mode 100644 index 000000000..a1916e553 --- /dev/null +++ b/modules/nf-core/fusioncatcher/fusioncatcher/tests/main.nf.test.snap @@ -0,0 +1,73 @@ +{ + "sarscov2 - fastq - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fusion-genes.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.summary.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,6a54daab2ec7621d8493678e832cf45e" + ], + "fusions": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fusion-genes.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "summary": [ + [ + { + "id": "test", + "single_end": false + }, + "test.summary.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,6a54daab2ec7621d8493678e832cf45e" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-04-11T11:01:13.392512529" + } +} \ No newline at end of file diff --git a/modules/nf-core/fusioninspector/environment.yml b/modules/nf-core/fusioninspector/environment.yml new file mode 100644 index 000000000..e0e8ab3f3 --- /dev/null +++ b/modules/nf-core/fusioninspector/environment.yml @@ -0,0 +1,12 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::fusion-inspector=2.10.0 + - bioconda::igv-reports=1.14.1 + - bioconda::perl-json-xs=4.03 + - bioconda::pysam=0.22.1 + - conda-forge::perl-carp-assert=0.21 + - conda-forge::pip==24.3.1 + - pip: + - intervaltree==3.1.0 diff --git a/modules/nf-core/fusioninspector/main.nf b/modules/nf-core/fusioninspector/main.nf new file mode 100644 index 000000000..5e2546692 --- /dev/null +++ b/modules/nf-core/fusioninspector/main.nf @@ -0,0 +1,66 @@ +process FUSIONINSPECTOR { + 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/13/139b94a1f10c6e23a8c27eaed1e5a689db978a513d0ee155e74d35f0970814fe/data' : + 'community.wave.seqera.io/library/fusion-inspector_igv-reports_perl-json-xs_pysam_pruned:c6147971d107ab11'}" + + input: + tuple val(meta), path(reads), path(fusion_list) + tuple val(meta2), path(reference) + + output: + tuple val(meta), path("*FusionInspector.fusions.tsv"), emit: tsv , optional:true + tuple val(meta), path("fi_workdir/*.gtf") , emit: out_gtf , optional:true + tuple val(meta), path("*FusionInspector.log") , emit: log , optional:true + tuple val(meta), path("*html") , emit: html , optional:true + tuple val(meta), path("*abridged.tsv") , emit: abridged_tsv, optional:true + tuple val(meta), path("IGV_inputs") , emit: igv_inputs , optional:true + tuple val(meta), path("fi_workdir") , emit: fi_workdir , optional:true + tuple val(meta), path("chckpts_dir") , emit: chckpts_dir , optional:true + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def prefix = task.ext.prefix ?: "${meta.id}" + def fasta = meta.single_end ? "--left_fq ${reads[0]}" : "--left_fq ${reads[0]} --right_fq ${reads[1]}" + def args = task.ext.args ?: '' + def args2 = task.ext.args2 ?: '' + """ + FusionInspector \\ + --fusions $fusion_list \\ + --genome_lib ${reference} \\ + $fasta \\ + --CPU ${task.cpus} \\ + -O . \\ + --out_prefix $prefix \\ + --vis $args $args2 + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + FusionInspector: \$(FusionInspector --version 2>&1 | grep -i 'version' | sed -e 's/FusionInspector version: //' -e 's/[[:space:]]//g') + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch FusionInspector.log + touch ${prefix}.FusionInspector.fusions.abridged.tsv + touch ${prefix}.FusionInspector.fusions.tsv + touch ${prefix}.fusion_inspector_web.html + mkdir -p chckpts_dir + mkdir -p fi_workdir + touch fi_workdir/${prefix}.gtf + mkdir -p IGV_inputs + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + FusionInspector: \$(FusionInspector --version 2>&1 | grep -i 'version' | sed -e 's/FusionInspector version: //' -e 's/[[:space:]]//g') + END_VERSIONS + """ +} diff --git a/modules/nf-core/fusioninspector/meta.yml b/modules/nf-core/fusioninspector/meta.yml new file mode 100644 index 000000000..1e94eee2d --- /dev/null +++ b/modules/nf-core/fusioninspector/meta.yml @@ -0,0 +1,150 @@ +name: fusioninspector +description: Validation of Fusion Transcript Predictions +keywords: + - fusioninspector + - fusion + - RNA-seq + - fastq +tools: + - fusioninspector: + description: Validation of Fusion Transcript Predictions + homepage: https://github.com/FusionInspector/FusionInspector + documentation: https://github.com/FusionInspector/FusionInspector/wiki + tool_dev_url: https://github.com/FusionInspector/FusionInspector + doi: 10.1101/2021.08.02.454639" + licence: ["BSD-3-Clause"] + identifier: "" + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: FASTQ file + pattern: "*.{fastq*}" + ontologies: + - edam: "http://edamontology.org/format_1930" # FASTQ + - fusion_list: + type: file + description: Fusion targets list + pattern: "*.{txt}" + ontologies: + - edam: "http://edamontology.org/format_2330" # Textual format + - - meta2: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reference: + type: directory + description: Path to CTAT references + pattern: "*" + +output: + tsv: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*FusionInspector.fusions.tsv": + type: file + description: FusionInspector output TSV file + pattern: "*.tsv" + ontologies: + - edam: "http://edamontology.org/format_3475" # TSV + out_gtf: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - fi_workdir/*.gtf: + type: file + description: GTF output file + pattern: "*.gtf" + ontologies: + - edam: "http://edamontology.org/format_2306" # GTF + log: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*FusionInspector.log": + type: file + description: FusionInspector log file + pattern: "*.log" + ontologies: + - edam: "http://edamontology.org/data_1678" # Log file + - edam: "http://edamontology.org/format_2330" # Plain text + html: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*html": + type: file + description: HTML output files + pattern: "*.html" + ontologies: + - edam: "http://edamontology.org/format_2331" # HTML + abridged_tsv: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*abridged.tsv": + type: file + description: Abridged TSV output file + pattern: "*.tsv" + ontologies: + - edam: "http://edamontology.org/format_3475" # TSV + igv_inputs: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - IGV_inputs: + type: directory + description: IGV inputs directory + pattern: "IGV_inputs" + fi_workdir: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - fi_workdir: + type: directory + description: FusionInspector work directory + pattern: "fi_workdir" + chckpts_dir: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - chckpts_dir: + type: directory + description: Checkpoints directory + pattern: "chckpts_dir" + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@rannick" + - "@delfiterradas" + - "@sofiromano" + - "@alanmmobbs93" + - "@martings" diff --git a/modules/nf-core/fusioninspector/tests/main.nf.test b/modules/nf-core/fusioninspector/tests/main.nf.test new file mode 100644 index 000000000..01e186f7f --- /dev/null +++ b/modules/nf-core/fusioninspector/tests/main.nf.test @@ -0,0 +1,111 @@ +nextflow_process { + + name "Test Process FUSIONINSPECTOR" + script "../main.nf" + process "FUSIONINSPECTOR" + tag "modules" + tag "modules_local" + tag "fusioninspector" + tag "starfusion/build" + tag "modules_nfcore" + + test("FUSIONINSPECTOR - test") { + config './nextflow.config' + + setup { + run("STARFUSION_BUILD") { + script "../../starfusion/build/main.nf" + process { + """ + input[0] = [ + [ id:'minigenome_fasta' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/minigenome.fa') + ] + input[1] = [ + [ id:'minigenome_gtf' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/minigenome.gtf') + ] + + input[2] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/CTAT_HumanFusionLib.mini.dat.gz') + input[3] = "homo_sapiens" + input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/Pfam-A.hmm.gz') + input[5] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3f'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3i'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3m'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3p') + ] + input[6] = "https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/AnnotFilterRule.pm" + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_rnaseq_1.fastq.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_rnaseq_2.fastq.gz') + ], // reads + [ + file("https://github.com/FusionInspector/FusionInspector/raw/master/test/fusion_targets.A.txt") + ] + ] + input[1] = STARFUSION_BUILD.out.reference + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert file(process.out.tsv[0][1]).getText().contains("THRA--AC090627.1\t72\t83\t72.00\t80.15") }, + { assert file(process.out.abridged_tsv[0][1]).getText().contains("THRA--AC090627.1\t72\t83\t72.00\t80.15") }, + { assert snapshot( + file(process.out.tsv[0][1]).name, + process.out.out_gtf, + file(process.out.abridged_tsv[0][1]).name, + file(process.out.log[0][1]).name, + process.out.versions + ).match() } + ) + } + + } + + test("FUSIONINSPECTOR - test - stub") { + options "-stub" + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_rnaseq_1.fastq.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_rnaseq_2.fastq.gz') + ], // reads + [ + file("https://github.com/FusionInspector/FusionInspector/raw/master/test/fusion_targets.A.txt") + ] + ] + input[1] = [[id:'minigenome_refs'],[]] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out + ).match() } + ) + } + + } + +} diff --git a/modules/nf-core/fusioninspector/tests/main.nf.test.snap b/modules/nf-core/fusioninspector/tests/main.nf.test.snap new file mode 100644 index 000000000..4a8d000ee --- /dev/null +++ b/modules/nf-core/fusioninspector/tests/main.nf.test.snap @@ -0,0 +1,199 @@ +{ + "FUSIONINSPECTOR - test": { + "content": [ + "test.FusionInspector.fusions.tsv", + [ + [ + { + "id": "test", + "single_end": false + }, + "test.gtf:md5,d523061bd8b443a014d4cca9406ec772" + ] + ], + "test.FusionInspector.fusions.abridged.tsv", + "FusionInspector.log", + [ + "versions.yml:md5,7c9694f4a2d8edbd30fd9674566b764c" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-07-07T13:48:15.295143368" + }, + "FUSIONINSPECTOR - test - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.FusionInspector.fusions.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "FusionInspector.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fusion_inspector_web.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "test.FusionInspector.fusions.abridged.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + [ + + ] + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false + }, + [ + + ] + ] + ], + "8": [ + "versions.yml:md5,7c9694f4a2d8edbd30fd9674566b764c" + ], + "abridged_tsv": [ + [ + { + "id": "test", + "single_end": false + }, + "test.FusionInspector.fusions.abridged.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "chckpts_dir": [ + [ + { + "id": "test", + "single_end": false + }, + [ + + ] + ] + ], + "fi_workdir": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fusion_inspector_web.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "igv_inputs": [ + [ + { + "id": "test", + "single_end": false + }, + [ + + ] + ] + ], + "log": [ + [ + { + "id": "test", + "single_end": false + }, + "FusionInspector.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "out_gtf": [ + [ + { + "id": "test", + "single_end": false + }, + "test.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tsv": [ + [ + { + "id": "test", + "single_end": false + }, + "test.FusionInspector.fusions.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,7c9694f4a2d8edbd30fd9674566b764c" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-07-18T20:42:22.142466729" + } +} \ No newline at end of file diff --git a/modules/nf-core/fusioninspector/tests/nextflow.config b/modules/nf-core/fusioninspector/tests/nextflow.config new file mode 100644 index 000000000..ca61431b2 --- /dev/null +++ b/modules/nf-core/fusioninspector/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'FUSIONINSPECTOR' { + ext.args = '--annotate --examine_coding_effect' + } +} diff --git a/modules/nf-core/fusionreport/detect/environment.yml b/modules/nf-core/fusionreport/detect/environment.yml new file mode 100644 index 000000000..f14a523ea --- /dev/null +++ b/modules/nf-core/fusionreport/detect/environment.yml @@ -0,0 +1,6 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::fusion-report=4.0.1 + - conda-forge::openpyxl=3.1.5 diff --git a/modules/local/fusionreport/detect/main.nf b/modules/nf-core/fusionreport/detect/main.nf similarity index 51% rename from modules/local/fusionreport/detect/main.nf rename to modules/nf-core/fusionreport/detect/main.nf index 8024d8f8e..618c14504 100644 --- a/modules/local/fusionreport/detect/main.nf +++ b/modules/nf-core/fusionreport/detect/main.nf @@ -1,24 +1,25 @@ -process FUSIONREPORT { +process FUSIONREPORT_DETECT { tag "$meta.id" label 'process_medium' - conda "bioconda::star=2.7.9a" - container "docker.io/clinicalgenomics/fusion-report:2.1.8" - + 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/ed/ed32f46746a5b33a1b5d597cfe2f62d3b1cfa54638f57cadc5d5158d6a4959d2/data' : + 'community.wave.seqera.io/library/fusion-report_beautifulsoup4_click_colorlog_pruned:78488bd99166aa9a'}" input: - tuple val(meta), path(reads), path(arriba_fusions), path(starfusion_fusions), path(fusioncatcher_fusions) + tuple val(meta), path(arriba_fusions), path(starfusion_fusions), path(fusioncatcher_fusions) tuple val(meta2), path(fusionreport_ref) val(tools_cutoff) output: - path "versions.yml" , emit: versions - tuple val(meta), path("*fusionreport.tsv") , emit: fusion_list - tuple val(meta), path("*fusionreport_filtered.tsv") , emit: fusion_list_filtered - tuple val(meta), path("*index.html") , emit: report - tuple val(meta), path("*_*.html") , optional:true, emit: html - tuple val(meta), path("*.csv") , optional:true, emit: csv - tuple val(meta), path("*.json") , optional:true, emit: json + tuple val(meta), path("*fusionreport.tsv") , emit: fusion_list + tuple val(meta), path("*fusionreport_filtered.tsv") , emit: fusion_list_filtered + tuple val(meta), path("*index.html") , emit: report + tuple val(meta), path("*_*.html") , emit: html , optional:true + tuple val(meta), path("*.csv") , emit: csv , optional:true + tuple val(meta), path("*.json") , emit: json , optional:true + path "versions.yml" , emit: versions when: task.ext.when == null || task.ext.when @@ -26,9 +27,9 @@ process FUSIONREPORT { script: def args = task.ext.args ?: '' def args2 = task.ext.args2 ?: '' - def tools = params.arriba || params.all ? "--arriba ${arriba_fusions} " : '' - tools += params.starfusion || params.all ? "--starfusion ${starfusion_fusions} " : '' - tools += params.fusioncatcher || params.all ? "--fusioncatcher ${fusioncatcher_fusions} " : '' + def tools = arriba_fusions ? "--arriba ${arriba_fusions} " : '' + tools += starfusion_fusions ? "--starfusion ${starfusion_fusions} " : '' + tools += fusioncatcher_fusions ? "--fusioncatcher ${fusioncatcher_fusions} " : '' def prefix = task.ext.prefix ?: "${meta.id}" """ fusion_report run $meta.id . $fusionreport_ref $tools --allow-multiple-gene-symbols --tool-cutoff $tools_cutoff $args $args2 diff --git a/modules/nf-core/fusionreport/detect/meta.yml b/modules/nf-core/fusionreport/detect/meta.yml new file mode 100644 index 000000000..dc87feed9 --- /dev/null +++ b/modules/nf-core/fusionreport/detect/meta.yml @@ -0,0 +1,151 @@ +name: fusionreport_detect +description: fusionreport_detect +keywords: + - sort + - RNA-seq + - fusion report + - detect +tools: + - fusionreport: + description: Tool for parsing outputs from fusion detection tools + homepage: https://github.com/Clinical-Genomics/fusion-report + documentation: https://matq007.github.io/fusion-report/#/ + doi: "10.1101/011650" + licence: ["GPL v3"] + identifier: "" + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + - arriba_fusions: + type: file + description: File + pattern: "*.fusions.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + - starfusion_fusions: + type: file + description: File containing fusions from STARfusion + pattern: "*.starfusion.fusion_predictions.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + - fusioncatcher_fusions: + type: file + description: File containing fusions from fusioncatcher + pattern: "*.fusions.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + - - meta2: + type: map + description: | + Groovy Map containing sample information + - fusionreport_ref: + type: directory + description: File + pattern: "fusion_report_db" + - tools_cutoff: + type: integer + description: Discard fusions detected by less than $tools_cutoff tools both for display in fusionreport html index and to consider in fusioninspector. + +output: + fusion_list: + - - meta: + type: map + description: | + Groovy Map containing sample information + pattern: "*.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + - "*fusionreport.tsv": + type: map + description: | + Groovy Map containing sample information + pattern: "*.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + fusion_list_filtered: + - - meta: + type: map + description: | + Groovy Map containing sample information + pattern: "*.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + - "*fusionreport_filtered.tsv": + type: map + description: | + Groovy Map containing sample information + pattern: "*.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + report: + - - meta: + type: map + description: | + Groovy Map containing sample information + pattern: "*.index.html" + ontologies: + - edam: "http://edamontology.org/format_2331" # HTML + - "*index.html": + type: map + description: | + Groovy Map containing sample information + pattern: "*.index.html" + ontologies: + - edam: "http://edamontology.org/format_2331" # HTML + html: + - - meta: + type: map + description: | + Groovy Map containing sample information + pattern: "*_*.html" + ontologies: + - edam: "http://edamontology.org/format_2331" # HTML + - "*_*.html": + type: map + description: | + Groovy Map containing sample information + pattern: "*_*.html" + ontologies: + - edam: "http://edamontology.org/format_2331" # HTML + csv: + - - meta: + type: map + description: | + Groovy Map containing sample information + pattern: "*.csv" + ontologies: + - edam: "http://edamontology.org/format_3752" # CSV + - "*.csv": + type: map + description: | + Groovy Map containing sample information + pattern: "*.csv" + ontologies: + - edam: "http://edamontology.org/format_3752" # CSV + json: + - - meta: + type: map + description: | + Groovy Map containing sample information + pattern: "*.json" + ontologies: + - edam: "http://edamontology.org/format_3464" # JSON + - "*.json": + type: map + description: | + Groovy Map containing sample information + pattern: "*.json" + ontologies: + - edam: "http://edamontology.org/format_3464" # JSON + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@praveenraj2018, @rannick" diff --git a/modules/nf-core/fusionreport/detect/tests/main.nf.test b/modules/nf-core/fusionreport/detect/tests/main.nf.test new file mode 100644 index 000000000..baf1ce12f --- /dev/null +++ b/modules/nf-core/fusionreport/detect/tests/main.nf.test @@ -0,0 +1,116 @@ +nextflow_process { + + name "Test Process FUSIONREPORT_DETECT" + script "../main.nf" + process "FUSIONREPORT_DETECT" + tag "modules" + tag "modules_local" + tag "fusionreport" + tag "fusionreport/detect" + tag "modules_nfcore" + tag "fusionreport/download" + + + test("FUSIONREPORT - arriba - starfusion - fusioncatcher") { + config './nextflow.config' + + setup { + run("FUSIONREPORT_DOWNLOAD") { + script "../../../fusionreport/download/main.nf" + process { + """ + """ + } + } + } + + when { + process { + """ + input[0] = [ + [ id:'test_sample' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/arriba.tsv', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/starfusion.tsv', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/fusioncatcher.txt', checkIfExists: true) + ] + input[1] = FUSIONREPORT_DOWNLOAD.out.fusionreport_ref + input[2] = 1 + """ + } + params { + arriba = true + starfusion = true + fusioncatcher = true + no_cosmic = true + outdir = "$outputDir" + fusionreport_download_args = '--no-cosmic' + fusionreport_detect_args = {params.no_cosmic} ? "--no-cosmic" : "" + fusionreport_detect_args2 = "--export csv" + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.fusion_list, + process.out.fusion_list_filtered, + process.out.csv, + file(process.out.report[0][1]).name, + process.out.html[0][1].collect { file(it).name }, + process.out.json, + process.out.versions.flatten().first().toString().split('/')[-1] // md5sum not stable as versions contains DB timestamp + ).match() } + ) + } + + } + + test("FUSIONREPORT - arriba - starfusion - fusioncatcher - stub") { + config './nextflow.config' + + setup { + run("FUSIONREPORT_DOWNLOAD") { + script "../../../fusionreport/download/main.nf" + process { + """ + """ + } + } + } + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test_sample' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/arriba.tsv', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/starfusion.tsv', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/fusioncatcher.txt', checkIfExists: true) + ] + input[1] = FUSIONREPORT_DOWNLOAD.out.fusionreport_ref + input[2] = 1 + """ + } + params { + arriba = true + starfusion = true + fusioncatcher = true + no_cosmic = true + outdir = "$outputDir" + fusionreport_download_args = '--no-cosmic' + fusionreport_detect_args = {params.no_cosmic} ? "--no-cosmic" : "" + fusionreport_detect_args2 = "--export csv" + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} \ No newline at end of file diff --git a/modules/nf-core/fusionreport/detect/tests/main.nf.test.snap b/modules/nf-core/fusionreport/detect/tests/main.nf.test.snap new file mode 100644 index 000000000..7b71aa358 --- /dev/null +++ b/modules/nf-core/fusionreport/detect/tests/main.nf.test.snap @@ -0,0 +1,186 @@ +{ + "FUSIONREPORT - arriba - starfusion - fusioncatcher": { + "content": [ + [ + [ + { + "id": "test_sample" + }, + "test_sample.fusionreport.tsv:md5,3593b7021f26cc5427fdc96f0d1c72f0" + ] + ], + [ + [ + { + "id": "test_sample" + }, + "test_sample.fusionreport_filtered.tsv:md5,3593b7021f26cc5427fdc96f0d1c72f0" + ] + ], + [ + [ + { + "id": "test_sample" + }, + "test_sample.fusions.csv:md5,ee6c6838110d68bc75a13c19dca0a321" + ] + ], + "test_sample_fusionreport_index.html", + [ + "AKAP9_BRAF.html", + "BRD4-1_NUTM1.html", + "BRD4_NUTM1.html", + "CD74_AL132671.2.html", + "CD74_ROS1.html", + "CIC_DUX4.html", + "DUX4_IGH@.html", + "EML4_ALK.html", + "ETV6_NTRK3.html", + "EWSR1_ATF1.html", + "EWSR1_FLI1.html", + "FGFR3_TACC3.html", + "FIP1L1_PDGFRA.html", + "GOPC_ROS1.html", + "HOOK3_RET.html", + "IGH@_CRLF2.html", + "MALT1_IGH@.html", + "NPM1_ALK.html", + "TMPRSS2_ETV1.html", + "test_sample_fusionreport_index.html" + ], + [ + [ + { + "id": "test_sample" + }, + "fusion_genes_mqc.json:md5,b196dc8d064a47d17fd3a032b8fbed4f" + ] + ], + "versions.yml" + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-06-26T16:15:03.892288278" + }, + "FUSIONREPORT - arriba - starfusion - fusioncatcher - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test_sample" + }, + "test_sample.fusionreport.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test_sample" + }, + "test_sample.fusionreport_filtered.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test_sample" + }, + "test_sample_fusionreport_index.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test_sample" + }, + [ + "AAA_BBB.html:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_fusionreport_index.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "4": [ + [ + { + "id": "test_sample" + }, + "test_sample.fusions.csv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + [ + { + "id": "test_sample" + }, + "test_sample.fusions.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + "versions.yml:md5,947ac2c0ed1623930f951f4f4ee3501e" + ], + "csv": [ + [ + { + "id": "test_sample" + }, + "test_sample.fusions.csv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fusion_list": [ + [ + { + "id": "test_sample" + }, + "test_sample.fusionreport.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fusion_list_filtered": [ + [ + { + "id": "test_sample" + }, + "test_sample.fusionreport_filtered.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "html": [ + [ + { + "id": "test_sample" + }, + [ + "AAA_BBB.html:md5,d41d8cd98f00b204e9800998ecf8427e", + "test_sample_fusionreport_index.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "json": [ + [ + { + "id": "test_sample" + }, + "test_sample.fusions.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "report": [ + [ + { + "id": "test_sample" + }, + "test_sample_fusionreport_index.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,947ac2c0ed1623930f951f4f4ee3501e" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-07-01T14:42:59.809164059" + } +} \ No newline at end of file diff --git a/modules/nf-core/fusionreport/detect/tests/nextflow.config b/modules/nf-core/fusionreport/detect/tests/nextflow.config new file mode 100644 index 000000000..ed07a62ee --- /dev/null +++ b/modules/nf-core/fusionreport/detect/tests/nextflow.config @@ -0,0 +1,10 @@ +process { + withName: 'FUSIONREPORT_DOWNLOAD' { + ext.args = params.fusionreport_download_args + } + + withName: 'FUSIONREPORT_DETECT' { + ext.args = params.fusionreport_detect_args + ext.args2 = params.fusionreport_detect_args2 + } +} diff --git a/modules/nf-core/fusionreport/download/environment.yml b/modules/nf-core/fusionreport/download/environment.yml new file mode 100644 index 000000000..ae86909d1 --- /dev/null +++ b/modules/nf-core/fusionreport/download/environment.yml @@ -0,0 +1,18 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::fusion-report=4.0.1 + - conda-forge::beautifulsoup4=4.13.4 + - conda-forge::click=8.2.1 + - conda-forge::colorlog=6.9.0 + - conda-forge::jinja2=3.1.6 + - conda-forge::markupsafe=3.0.2 + - conda-forge::numpy=2.3.0 + - conda-forge::openpyxl=3.1.5 + - conda-forge::pandas=2.3.0 + - conda-forge::pyyaml=6.0.2 + - conda-forge::requests=2.32.4 + - conda-forge::tabulate=0.9.0 + - conda-forge::tqdm=4.67.1 + - conda-forge::xlrd=2.0.1 diff --git a/modules/nf-core/fusionreport/download/main.nf b/modules/nf-core/fusionreport/download/main.nf new file mode 100644 index 000000000..3fd7ada4a --- /dev/null +++ b/modules/nf-core/fusionreport/download/main.nf @@ -0,0 +1,46 @@ +process FUSIONREPORT_DOWNLOAD { + tag 'fusionreport' + label 'process_medium' + + 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/ed/ed32f46746a5b33a1b5d597cfe2f62d3b1cfa54638f57cadc5d5158d6a4959d2/data' : + 'community.wave.seqera.io/library/fusion-report_beautifulsoup4_click_colorlog_pruned:78488bd99166aa9a'}" + + output: + tuple val(meta), path("fusion_report_db"), emit: fusionreport_ref + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + meta = [id: 'fusion_report_db'] + def args = task.ext.args ?: '' + """ + fusion_report download $args ./ + mkdir fusion_report_db + mv *.txt *.log *.db fusion_report_db/ + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fusion_report: \$(fusion_report --version | sed 's/fusion-report //') + END_VERSIONS + """ + + stub: + meta = [id: 'fusion_report_db'] + """ + mkdir fusion_report_db + touch fusion_report_db/cosmic.db + touch fusion_report_db/fusiongdb2.db + touch fusion_report_db/mitelman.db + touch fusion_report_db/DB-timestamp.txt + touch fusion_report_db/fusion_report.log + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + fusion_report: \$(fusion_report --version | sed 's/fusion-report //') + END_VERSIONS + """ +} diff --git a/modules/nf-core/fusionreport/download/meta.yml b/modules/nf-core/fusionreport/download/meta.yml new file mode 100644 index 000000000..8922d7549 --- /dev/null +++ b/modules/nf-core/fusionreport/download/meta.yml @@ -0,0 +1,36 @@ +name: fusionreport_download +description: Build DB for fusionreport +keywords: + - sort + - RNA-seq + - fusion_report + - download +tools: + - fusionreport: + description: Generate an interactive summary report from fusion detection tools. + homepage: https://github.com/Clinical-Genomics/fusion-report + documentation: https://github.com/Clinical-Genomics/fusion-report/blob/master/README.md + tool_dev_url: https://github.com/Clinical-Genomics/fusion-report + licence: ["GPL v3"] + identifier: "" + +output: + fusionreport_ref: + - - meta: + type: string + description: directory containing the genome resource files required for fusioncatcher + pattern: "fusion_report_db" + - fusion_report_db: + type: directory + description: directory containing the genome resource files required for fusioncatcher + pattern: "fusion_report_db" + + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@praveenraj2018" diff --git a/modules/nf-core/fusionreport/download/tests/main.nf.test b/modules/nf-core/fusionreport/download/tests/main.nf.test new file mode 100644 index 000000000..f05728932 --- /dev/null +++ b/modules/nf-core/fusionreport/download/tests/main.nf.test @@ -0,0 +1,61 @@ +nextflow_process { + + name "Test Process FUSIONREPORT_DOWNLOAD" + script "../main.nf" + process "FUSIONREPORT_DOWNLOAD" + tag "modules" + tag "modules_nfcore" + tag "fusionreport" + tag "fusionreport/download" + + test("Download fusionreport databases") { + config './nextflow.config' + + when { + params { + module_args = '--no-cosmic' + } + process { + """ + // This process doesn't have any inputs + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.fusionreport_ref[0][1]).resolve("fusiongdb2.db"), + path(process.out.fusionreport_ref[0][1]).resolve("mitelman.db"), + path(process.out.fusionreport_ref[0][1]).resolve("DB-timestamp.txt").exists(), + path(process.out.fusionreport_ref[0][1]).resolve("fusion_report.log").exists(), + process.out.versions + ).match() } + ) + } + } + + test("Create stub files") { + + options "-stub" + + when { + params { + module_args = '--no-cosmic' + } + process { + """ + // This process doesn't have any inputs + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} \ No newline at end of file diff --git a/modules/nf-core/fusionreport/download/tests/main.nf.test.snap b/modules/nf-core/fusionreport/download/tests/main.nf.test.snap new file mode 100644 index 000000000..ae2d0bc85 --- /dev/null +++ b/modules/nf-core/fusionreport/download/tests/main.nf.test.snap @@ -0,0 +1,63 @@ +{ + "Download fusionreport databases": { + "content": [ + "fusiongdb2.db:md5,9dec75bfc146f56b36e5a84358f9e515", + "mitelman.db:md5,c271894c1cd62ba2735a060411c16dea", + true, + true, + [ + "versions.yml:md5,620c6e01391800a7e7b717d7a3024003" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-07-15T18:56:45.064154384" + }, + "Create stub files": { + "content": [ + { + "0": [ + [ + { + "id": "fusion_report_db" + }, + [ + "DB-timestamp.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "cosmic.db:md5,d41d8cd98f00b204e9800998ecf8427e", + "fusion_report.log:md5,d41d8cd98f00b204e9800998ecf8427e", + "fusiongdb2.db:md5,d41d8cd98f00b204e9800998ecf8427e", + "mitelman.db:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + "versions.yml:md5,620c6e01391800a7e7b717d7a3024003" + ], + "fusionreport_ref": [ + [ + { + "id": "fusion_report_db" + }, + [ + "DB-timestamp.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "cosmic.db:md5,d41d8cd98f00b204e9800998ecf8427e", + "fusion_report.log:md5,d41d8cd98f00b204e9800998ecf8427e", + "fusiongdb2.db:md5,d41d8cd98f00b204e9800998ecf8427e", + "mitelman.db:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions": [ + "versions.yml:md5,620c6e01391800a7e7b717d7a3024003" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-06-27T19:34:10.41756869" + } +} \ No newline at end of file diff --git a/modules/nf-core/fusionreport/download/tests/nextflow.config b/modules/nf-core/fusionreport/download/tests/nextflow.config new file mode 100644 index 000000000..505233327 --- /dev/null +++ b/modules/nf-core/fusionreport/download/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'FUSIONREPORT_DOWNLOAD' { + ext.args = params.module_args + } +} diff --git a/modules/nf-core/gatk4/bedtointervallist/environment.yml b/modules/nf-core/gatk4/bedtointervallist/environment.yml index e7cb4280e..b562b72c7 100644 --- a/modules/nf-core/gatk4/bedtointervallist/environment.yml +++ b/modules/nf-core/gatk4/bedtointervallist/environment.yml @@ -1,7 +1,9 @@ -name: gatk4_bedtointervallist +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults dependencies: - - bioconda::gatk4=4.4.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.1.0 + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/bedtointervallist/main.nf b/modules/nf-core/gatk4/bedtointervallist/main.nf index 88b24b1ac..21e668c09 100644 --- a/modules/nf-core/gatk4/bedtointervallist/main.nf +++ b/modules/nf-core/gatk4/bedtointervallist/main.nf @@ -1,11 +1,11 @@ process GATK4_BEDTOINTERVALLIST { - tag "$meta.id" - label 'process_medium' + 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/gatk4:4.4.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.4.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/b2/b28daf5d9bb2f0d129dcad1b7410e0dd8a9b087aaf3ec7ced929b1f57624ad98/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:e48d414933d188cd'}" input: tuple val(meta), path(bed) @@ -13,7 +13,7 @@ process GATK4_BEDTOINTERVALLIST { output: tuple val(meta), path('*.interval_list'), emit: interval_list - path "versions.yml" , emit: versions + path "versions.yml", emit: versions when: task.ext.when == null || task.ext.when @@ -24,18 +24,19 @@ process GATK4_BEDTOINTERVALLIST { def avail_mem = 3072 if (!task.memory) { - log.info '[GATK BedToIntervalList] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK BedToIntervalList] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ BedToIntervalList \\ - --INPUT $bed \\ + --INPUT ${bed} \\ --OUTPUT ${prefix}.interval_list \\ - --SEQUENCE_DICTIONARY $dict \\ + --SEQUENCE_DICTIONARY ${dict} \\ --TMP_DIR . \\ - $args + ${args} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/gatk4/bedtointervallist/meta.yml b/modules/nf-core/gatk4/bedtointervallist/meta.yml index 187da8850..b186132d0 100644 --- a/modules/nf-core/gatk4/bedtointervallist/meta.yml +++ b/modules/nf-core/gatk4/bedtointervallist/meta.yml @@ -15,34 +15,47 @@ tools: documentation: https://gatk.broadinstitute.org/hc/en-us/categories/360002369672s doi: 10.1158/1538-7445.AM2017-3590 licence: ["Apache-2.0"] + identifier: "" input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test'] - - bed: - type: file - description: Input bed file - pattern: "*.bed" - - meta2: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'genome' ] - - dict: - type: file - description: Sequence dictionary - pattern: "*.dict" + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test'] + - bed: + type: file + description: Input bed file + pattern: "*.bed" + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - dict: + type: file + description: Sequence dictionary + pattern: "*.dict" + ontologies: [] output: - - interval_list: - type: file - description: gatk interval list file - pattern: "*.interval_list" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + interval_list: + - - meta: + type: file + description: gatk interval list file + pattern: "*.interval_list" + ontologies: [] + - "*.interval_list": + type: file + description: gatk interval list file + pattern: "*.interval_list" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@kevinmenden" - "@ramprasadn" diff --git a/modules/nf-core/gatk4/bedtointervallist/tests/main.nf.test b/modules/nf-core/gatk4/bedtointervallist/tests/main.nf.test new file mode 100644 index 000000000..2289f73fa --- /dev/null +++ b/modules/nf-core/gatk4/bedtointervallist/tests/main.nf.test @@ -0,0 +1,38 @@ +nextflow_process { + + name "Test Process GATK4_BEDTOINTERVALLIST" + script "../main.nf" + process "GATK4_BEDTOINTERVALLIST" + + tag "modules" + tag "modules_nfcore" + tag "gatk4" + tag "gatk4/bedtointervallist" + + test("test_gatk4_bedtointervallist") { + + when { + process { + """ + input[0] = [ [ id:'test' ], // meta map + [file(params.modules_testdata_base_path + + 'genomics/sarscov2/genome/bed/test.bed', checkIfExists: true) ] + ] + input[1] = [ [ id:'dict' ], // meta map + [file(params.modules_testdata_base_path + + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true) ] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} \ No newline at end of file diff --git a/modules/nf-core/gatk4/bedtointervallist/tests/main.nf.test.snap b/modules/nf-core/gatk4/bedtointervallist/tests/main.nf.test.snap new file mode 100644 index 000000000..6936cf971 --- /dev/null +++ b/modules/nf-core/gatk4/bedtointervallist/tests/main.nf.test.snap @@ -0,0 +1,35 @@ +{ + "test_gatk4_bedtointervallist": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.interval_list:md5,e51101c9357fb2d59fd30e370eefa39c" + ] + ], + "1": [ + "versions.yml:md5,6b3aa4d49cc3ba433ecf92e31f155d00" + ], + "interval_list": [ + [ + { + "id": "test" + }, + "test.interval_list:md5,e51101c9357fb2d59fd30e370eefa39c" + ] + ], + "versions": [ + "versions.yml:md5,6b3aa4d49cc3ba433ecf92e31f155d00" + ] + } + ], + "meta": { + "nf-test": "0.9.1", + "nextflow": "24.10.0" + }, + "timestamp": "2024-10-31T10:37:25.720782902" + } +} \ No newline at end of file diff --git a/modules/nf-core/gatk4/createsequencedictionary/environment.yml b/modules/nf-core/gatk4/createsequencedictionary/environment.yml index db663e148..b562b72c7 100644 --- a/modules/nf-core/gatk4/createsequencedictionary/environment.yml +++ b/modules/nf-core/gatk4/createsequencedictionary/environment.yml @@ -1,7 +1,9 @@ -name: gatk4_createsequencedictionary +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults dependencies: - - bioconda::gatk4=4.4.0.0 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.1.0 + - bioconda::gcnvkernel=0.9 diff --git a/modules/nf-core/gatk4/createsequencedictionary/main.nf b/modules/nf-core/gatk4/createsequencedictionary/main.nf index b47ad1622..872648a5e 100644 --- a/modules/nf-core/gatk4/createsequencedictionary/main.nf +++ b/modules/nf-core/gatk4/createsequencedictionary/main.nf @@ -1,18 +1,18 @@ process GATK4_CREATESEQUENCEDICTIONARY { - tag "$fasta" - label 'process_medium' + tag "${fasta}" + label 'process_single' conda "${moduleDir}/environment.yml" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/gatk4:4.4.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.4.0.0--py36hdfd78af_0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/b2/b28daf5d9bb2f0d129dcad1b7410e0dd8a9b087aaf3ec7ced929b1f57624ad98/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel:e48d414933d188cd'}" input: tuple val(meta), path(fasta) output: - tuple val(meta), path('*.dict') , emit: dict - path "versions.yml" , emit: versions + tuple val(meta), path('*.dict'), emit: dict + path "versions.yml", emit: versions when: task.ext.when == null || task.ext.when @@ -22,17 +22,18 @@ process GATK4_CREATESEQUENCEDICTIONARY { def avail_mem = 6144 if (!task.memory) { - log.info '[GATK CreateSequenceDictionary] Available memory not known - defaulting to 6GB. Specify process memory requirements to change this.' - } else { - avail_mem = (task.memory.mega*0.8).intValue() + log.info('[GATK CreateSequenceDictionary] Available memory not known - defaulting to 6GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } """ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ CreateSequenceDictionary \\ - --REFERENCE $fasta \\ - --URI $fasta \\ + --REFERENCE ${fasta} \\ + --URI ${fasta} \\ --TMP_DIR . \\ - $args + ${args} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/gatk4/createsequencedictionary/meta.yml b/modules/nf-core/gatk4/createsequencedictionary/meta.yml index f9d70be09..72dced28c 100644 --- a/modules/nf-core/gatk4/createsequencedictionary/meta.yml +++ b/modules/nf-core/gatk4/createsequencedictionary/meta.yml @@ -15,25 +15,37 @@ tools: documentation: https://gatk.broadinstitute.org/hc/en-us/categories/360002369672s doi: 10.1158/1538-7445.AM2017-3590 licence: ["Apache-2.0"] + identifier: "" input: - - meta: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'genome' ] - - fasta: - type: file - description: Input fasta file - pattern: "*.{fasta,fa}" + - - meta: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fasta: + type: file + description: Input fasta file + pattern: "*.{fasta,fa}" + ontologies: [] output: - - dict: - type: file - description: gatk dictionary file - pattern: "*.{dict}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + dict: + - - meta: + type: file + description: gatk dictionary file + pattern: "*.{dict}" + ontologies: [] + - "*.dict": + type: file + description: gatk dictionary file + pattern: "*.{dict}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@maxulysse" - "@ramprasadn" diff --git a/modules/nf-core/gatk4/createsequencedictionary/tests/main.nf.test b/modules/nf-core/gatk4/createsequencedictionary/tests/main.nf.test new file mode 100644 index 000000000..a8a9c6d2e --- /dev/null +++ b/modules/nf-core/gatk4/createsequencedictionary/tests/main.nf.test @@ -0,0 +1,56 @@ +nextflow_process { + + name "Test Process GATK4_CREATESEQUENCEDICTIONARY" + script "../main.nf" + process "GATK4_CREATESEQUENCEDICTIONARY" + + tag "modules" + tag "modules_nfcore" + tag "gatk4" + tag "gatk4/createsequencedictionary" + + test("sarscov2 - fasta") { + + when { + process { + """ + input[0] = [ [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - fasta - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/gatk4/createsequencedictionary/tests/main.nf.test.snap b/modules/nf-core/gatk4/createsequencedictionary/tests/main.nf.test.snap new file mode 100644 index 000000000..e8a600fd1 --- /dev/null +++ b/modules/nf-core/gatk4/createsequencedictionary/tests/main.nf.test.snap @@ -0,0 +1,68 @@ +{ + "sarscov2 - fasta - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "genome.dict:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,e993b2c99f7f6b0fcd8428de15c61439" + ], + "dict": [ + [ + { + "id": "test" + }, + "genome.dict:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e993b2c99f7f6b0fcd8428de15c61439" + ] + } + ], + "meta": { + "nf-test": "0.9.1", + "nextflow": "24.10.0" + }, + "timestamp": "2024-10-31T10:51:56.155954077" + }, + "sarscov2 - fasta": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "genome.dict:md5,7362679f176e0f52add03c08f457f646" + ] + ], + "1": [ + "versions.yml:md5,e993b2c99f7f6b0fcd8428de15c61439" + ], + "dict": [ + [ + { + "id": "test" + }, + "genome.dict:md5,7362679f176e0f52add03c08f457f646" + ] + ], + "versions": [ + "versions.yml:md5,e993b2c99f7f6b0fcd8428de15c61439" + ] + } + ], + "meta": { + "nf-test": "0.9.1", + "nextflow": "24.10.0" + }, + "timestamp": "2024-10-31T10:51:45.562993875" + } +} \ No newline at end of file diff --git a/modules/nf-core/gatk4/markduplicates/environment.yml b/modules/nf-core/gatk4/markduplicates/environment.yml index 9adad104d..ca0fc1923 100644 --- a/modules/nf-core/gatk4/markduplicates/environment.yml +++ b/modules/nf-core/gatk4/markduplicates/environment.yml @@ -1,8 +1,12 @@ -name: gatk4_markduplicates +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults + dependencies: - - bioconda::gatk4=4.4.0.0 - - bioconda::samtools=1.17 + # renovate: datasource=conda depName=bioconda/gatk4 + - bioconda::gatk4=4.6.1.0 + - bioconda::gcnvkernel=0.9 + - bioconda::htslib=1.21 + - bioconda::samtools=1.21 diff --git a/modules/nf-core/gatk4/markduplicates/main.nf b/modules/nf-core/gatk4/markduplicates/main.nf index 564b86d3d..5fb161b4f 100644 --- a/modules/nf-core/gatk4/markduplicates/main.nf +++ b/modules/nf-core/gatk4/markduplicates/main.nf @@ -1,22 +1,22 @@ process GATK4_MARKDUPLICATES { - tag "$meta.id" - label 'process_medium' + 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/mulled-v2-d9e7bad0f7fbc8f4458d5c3ab7ffaaf0235b59fb:f857e2d6cc88d35580d01cf39e0959a68b83c1d9-0': - 'biocontainers/mulled-v2-d9e7bad0f7fbc8f4458d5c3ab7ffaaf0235b59fb:f857e2d6cc88d35580d01cf39e0959a68b83c1d9-0' }" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/92/927ff9bb80d65b425cbe752db6648a84043feff6e8ca90e60f9ff6ddbe8938d5/data' + : 'community.wave.seqera.io/library/gatk4_gcnvkernel_htslib_samtools:c1e4292d6ee27439'}" input: tuple val(meta), path(bam) - path fasta - path fasta_fai + path fasta + path fasta_fai output: - tuple val(meta), path("*cram"), emit: cram, optional: true - tuple val(meta), path("*bam"), emit: bam, optional: true - tuple val(meta), path("*.crai"), emit: crai, optional: true - tuple val(meta), path("*.bai"), emit: bai, optional: true + tuple val(meta), path("*cram"), emit: cram, optional: true + tuple val(meta), path("*bam"), emit: bam, optional: true + tuple val(meta), path("*.crai"), emit: crai, optional: true + tuple val(meta), path("*.bai"), emit: bai, optional: true tuple val(meta), path("*.metrics"), emit: metrics path "versions.yml", emit: versions @@ -30,14 +30,15 @@ process GATK4_MARKDUPLICATES { // If the extension is CRAM, then change it to BAM prefix_bam = prefix.tokenize('.')[-1] == 'cram' ? "${prefix.substring(0, prefix.lastIndexOf('.'))}.bam" : prefix - def input_list = bam.collect{"--INPUT $it"}.join(' ') + def input_list = bam.collect { "--INPUT ${it}" }.join(' ') def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" def avail_mem = 3072 if (!task.memory) { - log.info '[GATK MarkDuplicates] 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('[GATK MarkDuplicates] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.') + } + else { + avail_mem = (task.memory.mega * 0.8).intValue() } // Using samtools and not Markduplicates to compress to CRAM speeds up computation: @@ -45,12 +46,12 @@ process GATK4_MARKDUPLICATES { """ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\ MarkDuplicates \\ - $input_list \\ + ${input_list} \\ --OUTPUT ${prefix_bam} \\ --METRICS_FILE ${prefix}.metrics \\ --TMP_DIR . \\ ${reference} \\ - $args + ${args} # If cram files are wished as output, the run samtools for conversion if [[ ${prefix} == *.cram ]]; then diff --git a/modules/nf-core/gatk4/markduplicates/meta.yml b/modules/nf-core/gatk4/markduplicates/meta.yml index b0f09d4b8..335c309a9 100644 --- a/modules/nf-core/gatk4/markduplicates/meta.yml +++ b/modules/nf-core/gatk4/markduplicates/meta.yml @@ -1,5 +1,6 @@ name: gatk4_markduplicates -description: This tool locates and tags duplicate reads in a BAM or SAM file, where duplicate reads are defined as originating from a single fragment of DNA. +description: This tool locates and tags duplicate reads in a BAM or SAM file, where + duplicate reads are defined as originating from a single fragment of DNA. keywords: - bam - gatk4 @@ -7,60 +8,100 @@ keywords: - sort tools: - gatk4: - description: Developed in the Data Sciences Platform at the Broad Institute, the toolkit offers a wide variety of tools with a primary focus on variant discovery and genotyping. Its powerful processing engine and high-performance computing features make it capable of taking on projects of any size. + description: Developed in the Data Sciences Platform at the Broad Institute, the + toolkit offers a wide variety of tools with a primary focus on variant discovery + and genotyping. Its powerful processing engine and high-performance computing + features make it capable of taking on projects of any size. homepage: https://gatk.broadinstitute.org/hc/en-us documentation: https://gatk.broadinstitute.org/hc/en-us/articles/360037052812-MarkDuplicates-Picard- tool_dev_url: https://github.com/broadinstitute/gatk doi: 10.1158/1538-7445.AM2017-3590 licence: ["MIT"] + identifier: "" input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: Sorted BAM file - pattern: "*.{bam}" + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: Sorted BAM file + pattern: "*.{bam}" + ontologies: [] - fasta: type: file description: Fasta file pattern: "*.{fasta}" + ontologies: [] - fasta_fai: type: file description: Fasta index file pattern: "*.{fai}" + ontologies: [] output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - bam: - type: file - description: Marked duplicates BAM file - pattern: "*.{bam}" - - cram: - type: file - description: Marked duplicates CRAM file - pattern: "*.{cram}" - - bai: - type: file - description: BAM index file - pattern: "*.{bam.bai}" - - crai: - type: file - description: CRAM index file - pattern: "*.{cram.crai}" - - metrics: - type: file - description: Duplicate metrics file generated by GATK - pattern: "*.{metrics.txt}" + cram: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*cram": + type: file + description: Marked duplicates CRAM file + pattern: "*.{cram}" + ontologies: [] + bam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*bam": + type: file + description: Marked duplicates BAM file + pattern: "*.{bam}" + ontologies: [] + crai: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.crai": + type: file + description: CRAM index file + pattern: "*.{cram.crai}" + ontologies: [] + bai: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.bai": + type: file + description: BAM index file + pattern: "*.{bam.bai}" + ontologies: [] + metrics: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.metrics": + type: file + description: Duplicate metrics file generated by GATK + pattern: "*.{metrics.txt}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@ajodeh-juma" - "@FriederikeHanssen" diff --git a/modules/nf-core/gatk4/markduplicates/tests/bam.config b/modules/nf-core/gatk4/markduplicates/tests/bam.config new file mode 100644 index 000000000..0bbfbac35 --- /dev/null +++ b/modules/nf-core/gatk4/markduplicates/tests/bam.config @@ -0,0 +1,8 @@ +process { + + withName: GATK4_MARKDUPLICATES { + ext.args = '--CREATE_INDEX true' + ext.prefix = { "${meta.id}.bam" } + } + +} diff --git a/modules/nf-core/gatk4/markduplicates/tests/cram.config b/modules/nf-core/gatk4/markduplicates/tests/cram.config new file mode 100644 index 000000000..04a9b0745 --- /dev/null +++ b/modules/nf-core/gatk4/markduplicates/tests/cram.config @@ -0,0 +1,8 @@ +process { + + withName: GATK4_MARKDUPLICATES { + ext.args = '--CREATE_INDEX true' + ext.prefix = { "${meta.id}.cram" } + } + +} diff --git a/modules/nf-core/gatk4/markduplicates/tests/main.nf.test b/modules/nf-core/gatk4/markduplicates/tests/main.nf.test new file mode 100644 index 000000000..bbcf74db6 --- /dev/null +++ b/modules/nf-core/gatk4/markduplicates/tests/main.nf.test @@ -0,0 +1,126 @@ +nextflow_process { + + name "Test Process GATK4_MARKDUPLICATES" + script "../main.nf" + process "GATK4_MARKDUPLICATES" + + tag "modules" + tag "modules_nfcore" + tag "gatk4" + tag "gatk4/markduplicates" + + test("sarscov2 - bam") { + config "./bam.config" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) + ] + input[1] = [] + input[2] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.bam).match("bam") }, + { assert snapshot(process.out.bai).match("bai") }, + { assert snapshot(process.out.versions).match("versions") }, + { assert snapshot(file(process.out.metrics[0][1]).name).match("test.metrics") } + ) + } + } + + test("homo_sapiens - multiple bam") { + config "./bam.config" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], + [ + 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] = [] + input[2] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out.bam).match("multi bam") }, + { assert snapshot(process.out.bai).match("multi bai") }, + { assert snapshot(process.out.versions).match("multi versions") }, + { assert snapshot(file(process.out.metrics[0][1]).name).match("multi test.metrics") } + ) + } + + } + + test("homo_sapiens - multiple cram") { + config "./cram.config" + + when { + process { + """ + input[0] = [ + [ 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] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + input[2] = 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.cram[0][1]).name).match("multi cram")}, + { assert snapshot(file(process.out.crai[0][1]).name).match("multi crai") }, + { assert snapshot(process.out.versions).match("multi cram versions") }, + { assert snapshot(file(process.out.metrics[0][1]).name).match("multi cram test.metrics") } + ) + } + + } + + test("stub") { + config "./bam.config" + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], + [] + ] + input[1] = [] + input[2] = [] + """ + } + } + + then { + assertAll( + { assert process.success } + ) + } + + } + +} diff --git a/modules/nf-core/gatk4/markduplicates/tests/main.nf.test.snap b/modules/nf-core/gatk4/markduplicates/tests/main.nf.test.snap new file mode 100644 index 000000000..227ce6985 --- /dev/null +++ b/modules/nf-core/gatk4/markduplicates/tests/main.nf.test.snap @@ -0,0 +1,160 @@ +{ + "multi bam": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,d4c87a668273b589b59cf88b5a00bceb" + ] + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.03.1" + }, + "timestamp": "2025-05-06T19:13:35.646267615" + }, + "multi crai": { + "content": [ + "test.cram.crai" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.0" + }, + "timestamp": "2023-12-12T17:43:37.780426007" + }, + "multi bai": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.bai:md5,2b1603773979ad06f4dbcbaa90e93e8c" + ] + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.03.1" + }, + "timestamp": "2025-05-06T19:13:35.773636892" + }, + "versions": { + "content": [ + [ + "versions.yml:md5,836be8dcb8e596b2e5eeb2d667db0832" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.03.1" + }, + "timestamp": "2025-05-06T19:37:41.921624379" + }, + "multi test.metrics": { + "content": [ + "test.bam.metrics" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.0" + }, + "timestamp": "2023-12-12T17:43:11.732892667" + }, + "bai": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.bai:md5,fd1c3cc02f4e223d32eedeed842b86c7" + ] + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.03.1" + }, + "timestamp": "2025-05-06T19:13:21.104275114" + }, + "multi cram versions": { + "content": [ + [ + "versions.yml:md5,836be8dcb8e596b2e5eeb2d667db0832" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.03.1" + }, + "timestamp": "2025-05-06T19:38:08.855960769" + }, + "multi versions": { + "content": [ + [ + "versions.yml:md5,836be8dcb8e596b2e5eeb2d667db0832" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.03.1" + }, + "timestamp": "2025-05-06T19:37:55.051564286" + }, + "multi cram test.metrics": { + "content": [ + "test.cram.metrics" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.0" + }, + "timestamp": "2023-12-12T17:43:37.798977444" + }, + "multi cram": { + "content": [ + "test.cram" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.0" + }, + "timestamp": "2023-12-12T17:43:37.771137858" + }, + "bam": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,5542c553af351a43b97e84181c51a84e" + ] + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.03.1" + }, + "timestamp": "2025-05-06T19:13:21.060566406" + }, + "test.metrics": { + "content": [ + "test.bam.metrics" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.0" + }, + "timestamp": "2023-12-12T17:42:39.672508385" + } +} \ No newline at end of file diff --git a/modules/nf-core/gffread/environment.yml b/modules/nf-core/gffread/environment.yml new file mode 100644 index 000000000..46c5faece --- /dev/null +++ b/modules/nf-core/gffread/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::gffread=0.12.7 diff --git a/modules/nf-core/gffread/main.nf b/modules/nf-core/gffread/main.nf new file mode 100644 index 000000000..da55cbab7 --- /dev/null +++ b/modules/nf-core/gffread/main.nf @@ -0,0 +1,60 @@ +process GFFREAD { + 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/gffread:0.12.7--hdcf5f25_4' : + 'biocontainers/gffread:0.12.7--hdcf5f25_4' }" + + input: + tuple val(meta), path(gff) + path fasta + + output: + tuple val(meta), path("*.gtf") , emit: gtf , optional: true + tuple val(meta), path("*.gff3") , emit: gffread_gff , optional: true + tuple val(meta), path("*.fasta"), emit: gffread_fasta , 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 extension = args.contains("-T") ? 'gtf' : ( ( ['-w', '-x', '-y' ].any { args.contains(it) } ) ? 'fasta' : 'gff3' ) + def fasta_arg = fasta ? "-g $fasta" : '' + def output_name = "${prefix}.${extension}" + def output = extension == "fasta" ? "$output_name" : "-o $output_name" + def args_sorted = args.replaceAll(/(.*)(-[wxy])(.*)/) { all, pre, param, post -> "$pre $post $param" }.trim() + // args_sorted = Move '-w', '-x', and '-y' to the end of the args string as gffread expects the file name after these parameters + if ( "$output_name" in [ "$gff", "$fasta" ] ) error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + """ + gffread \\ + $gff \\ + $fasta_arg \\ + $args_sorted \\ + $output + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + gffread: \$(gffread --version 2>&1) + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def extension = args.contains("-T") ? 'gtf' : ( ( ['-w', '-x', '-y' ].any { args.contains(it) } ) ? 'fasta' : 'gff3' ) + def output_name = "${prefix}.${extension}" + if ( "$output_name" in [ "$gff", "$fasta" ] ) error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" + """ + touch $output_name + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + gffread: \$(gffread --version 2>&1) + END_VERSIONS + """ +} diff --git a/modules/nf-core/gffread/meta.yml b/modules/nf-core/gffread/meta.yml new file mode 100644 index 000000000..715efec8e --- /dev/null +++ b/modules/nf-core/gffread/meta.yml @@ -0,0 +1,82 @@ +name: gffread +description: Validate, filter, convert and perform various other operations on GFF + files +keywords: + - gff + - conversion + - validation +tools: + - gffread: + description: GFF/GTF utility providing format conversions, region filtering, FASTA + sequence extraction and more. + homepage: http://ccb.jhu.edu/software/stringtie/gff.shtml#gffread + documentation: http://ccb.jhu.edu/software/stringtie/gff.shtml#gffread + tool_dev_url: https://github.com/gpertea/gffread + doi: 10.12688/f1000research.23297.1 + licence: ["MIT"] + identifier: biotools:gffread +input: + - - meta: + type: map + description: | + Groovy Map containing meta data + e.g. [ id:'test' ] + - gff: + type: file + description: A reference file in either the GFF3, GFF2 or GTF format. + pattern: "*.{gff, gtf}" + ontologies: [] + - fasta: + type: file + description: A multi-fasta file with the genomic sequences + pattern: "*.{fasta,fa,faa,fas,fsa}" + ontologies: [] +output: + gtf: + - - meta: + type: map + description: | + Groovy Map containing meta data + e.g. [ id:'test' ] + - "*.gtf": + type: file + description: GTF file resulting from the conversion of the GFF input file + if '-T' argument is present + pattern: "*.{gtf}" + ontologies: [] + gffread_gff: + - - meta: + type: map + description: | + Groovy Map containing meta data + e.g. [ id:'test' ] + - "*.gff3": + type: file + description: GFF3 file resulting from the conversion of the GFF input file + if '-T' argument is absent + pattern: "*.gff3" + ontologies: [] + gffread_fasta: + - - meta: + type: map + description: | + Groovy Map containing meta data + e.g. [ id:'test' ] + - "*.fasta": + type: file + description: Fasta file produced when either of '-w', '-x', '-y' parameters + is present + pattern: "*.fasta" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@edmundmiller" +maintainers: + - "@edmundmiller" + - "@gallvp" diff --git a/modules/nf-core/gffread/tests/main.nf.test b/modules/nf-core/gffread/tests/main.nf.test new file mode 100644 index 000000000..d039f367c --- /dev/null +++ b/modules/nf-core/gffread/tests/main.nf.test @@ -0,0 +1,224 @@ +nextflow_process { + + name "Test Process GFFREAD" + script "../main.nf" + process "GFFREAD" + + tag "gffread" + tag "modules_nfcore" + tag "modules" + + test("sarscov2-gff3-gtf") { + + config "./nextflow.config" + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = [ + [id: 'test'], + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gff3", checkIfExists: true) + ] + input[1] = [] + + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() }, + { assert process.out.gffread_gff == [] }, + { assert process.out.gffread_fasta == [] } + ) + } + + } + + test("sarscov2-gff3-gtf-stub") { + + options '-stub' + config "./nextflow.config" + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = [ + [id: 'test'], + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gff3", checkIfExists: true) + ] + input[1] = [] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() }, + { assert process.out.gffread_gff == [] }, + { assert process.out.gffread_fasta == [] } + ) + } + + } + + test("sarscov2-gff3-gff3") { + + config "./nextflow-gff3.config" + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = [ + [id: 'test'], + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gff3", checkIfExists: true) + ] + input[1] = [] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() }, + { assert process.out.gtf == [] }, + { assert process.out.gffread_fasta == [] } + ) + } + + } + + test("sarscov2-gff3-gff3-stub") { + + options '-stub' + config "./nextflow-gff3.config" + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = [ + [id: 'test'], + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gff3", checkIfExists: true) + ] + input[1] = [] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() }, + { assert process.out.gtf == [] }, + { assert process.out.gffread_fasta == [] } + ) + } + + } + + test("sarscov2-gff3-fasta") { + + config "./nextflow-fasta.config" + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = [ + [id: 'test'], + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gff3", checkIfExists: true) + ] + input[1] = file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.fasta", checkIfExists: true) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() }, + { assert process.out.gtf == [] }, + { assert process.out.gffread_gff == [] } + ) + } + + } + + test("sarscov2-gff3-fasta-stub") { + + options '-stub' + config "./nextflow-fasta.config" + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = [ + [id: 'test'], + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gff3", checkIfExists: true) + ] + input[1] = file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.fasta", checkIfExists: true) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() }, + { assert process.out.gtf == [] }, + { assert process.out.gffread_gff == [] } + ) + } + + } + + test("sarscov2-gff3-fasta-fail-catch") { + + options '-stub' + config "./nextflow-fasta.config" + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = [ + [id: 'genome'], + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gff3", checkIfExists: true) + ] + input[1] = file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.fasta", checkIfExists: true) + """ + } + } + + then { + assertAll ( + { assert ! process.success }, + { assert process.stdout.toString().contains("Input and output names are the same") } + ) + } + + } + +} \ No newline at end of file diff --git a/modules/nf-core/gffread/tests/main.nf.test.snap b/modules/nf-core/gffread/tests/main.nf.test.snap new file mode 100644 index 000000000..15262320d --- /dev/null +++ b/modules/nf-core/gffread/tests/main.nf.test.snap @@ -0,0 +1,272 @@ +{ + "sarscov2-gff3-gtf": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.gtf:md5,1ea0ae98d3388e0576407dc4a24ef428" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,05f671c6c6e530acedad0af0a5948dbd" + ], + "gffread_fasta": [ + + ], + "gffread_gff": [ + + ], + "gtf": [ + [ + { + "id": "test" + }, + "test.gtf:md5,1ea0ae98d3388e0576407dc4a24ef428" + ] + ], + "versions": [ + "versions.yml:md5,05f671c6c6e530acedad0af0a5948dbd" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-04-09T10:48:56.496187" + }, + "sarscov2-gff3-gff3": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test" + }, + "test.gff3:md5,c4e5da6267c6bee5899a2c204ae1ad91" + ] + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,05f671c6c6e530acedad0af0a5948dbd" + ], + "gffread_fasta": [ + + ], + "gffread_gff": [ + [ + { + "id": "test" + }, + "test.gff3:md5,c4e5da6267c6bee5899a2c204ae1ad91" + ] + ], + "gtf": [ + + ], + "versions": [ + "versions.yml:md5,05f671c6c6e530acedad0af0a5948dbd" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-04-09T10:49:00.892782" + }, + "sarscov2-gff3-gtf-stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,05f671c6c6e530acedad0af0a5948dbd" + ], + "gffread_fasta": [ + + ], + "gffread_gff": [ + + ], + "gtf": [ + [ + { + "id": "test" + }, + "test.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,05f671c6c6e530acedad0af0a5948dbd" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-04-09T11:11:26.975666" + }, + "sarscov2-gff3-fasta-stub": { + "content": [ + { + "0": [ + + ], + "1": [ + + ], + "2": [ + [ + { + "id": "test" + }, + "test.fasta:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,05f671c6c6e530acedad0af0a5948dbd" + ], + "gffread_fasta": [ + [ + { + "id": "test" + }, + "test.fasta:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "gffread_gff": [ + + ], + "gtf": [ + + ], + "versions": [ + "versions.yml:md5,05f671c6c6e530acedad0af0a5948dbd" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-04-09T11:11:44.34792" + }, + "sarscov2-gff3-gff3-stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test" + }, + "test.gff3:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,05f671c6c6e530acedad0af0a5948dbd" + ], + "gffread_fasta": [ + + ], + "gffread_gff": [ + [ + { + "id": "test" + }, + "test.gff3:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "gtf": [ + + ], + "versions": [ + "versions.yml:md5,05f671c6c6e530acedad0af0a5948dbd" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-04-09T11:11:35.221671" + }, + "sarscov2-gff3-fasta": { + "content": [ + { + "0": [ + + ], + "1": [ + + ], + "2": [ + [ + { + "id": "test" + }, + "test.fasta:md5,5f8108fb51739a0588ccf0a251de919a" + ] + ], + "3": [ + "versions.yml:md5,05f671c6c6e530acedad0af0a5948dbd" + ], + "gffread_fasta": [ + [ + { + "id": "test" + }, + "test.fasta:md5,5f8108fb51739a0588ccf0a251de919a" + ] + ], + "gffread_gff": [ + + ], + "gtf": [ + + ], + "versions": [ + "versions.yml:md5,05f671c6c6e530acedad0af0a5948dbd" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-04-09T10:54:02.88143" + } +} \ No newline at end of file diff --git a/modules/nf-core/gffread/tests/nextflow-fasta.config b/modules/nf-core/gffread/tests/nextflow-fasta.config new file mode 100644 index 000000000..ac6cb1484 --- /dev/null +++ b/modules/nf-core/gffread/tests/nextflow-fasta.config @@ -0,0 +1,5 @@ +process { + withName: GFFREAD { + ext.args = '-w -S' + } +} diff --git a/modules/nf-core/gffread/tests/nextflow-gff3.config b/modules/nf-core/gffread/tests/nextflow-gff3.config new file mode 100644 index 000000000..afe0830e5 --- /dev/null +++ b/modules/nf-core/gffread/tests/nextflow-gff3.config @@ -0,0 +1,5 @@ +process { + withName: GFFREAD { + ext.args = '' + } +} diff --git a/modules/nf-core/gffread/tests/nextflow.config b/modules/nf-core/gffread/tests/nextflow.config new file mode 100644 index 000000000..74b25094f --- /dev/null +++ b/modules/nf-core/gffread/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: GFFREAD { + ext.args = '-T' + } +} diff --git a/modules/nf-core/multiqc/environment.yml b/modules/nf-core/multiqc/environment.yml index ca39fb67e..f89370483 100644 --- a/modules/nf-core/multiqc/environment.yml +++ b/modules/nf-core/multiqc/environment.yml @@ -1,7 +1,7 @@ -name: multiqc +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults dependencies: - - bioconda::multiqc=1.21 + - bioconda::multiqc=1.30 diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index 47ac352f9..67460de9a 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -3,14 +3,16 @@ process MULTIQC { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.21--pyhdfd78af_0' : - 'biocontainers/multiqc:1.21--pyhdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/multiqc:1.30--pyhdfd78af_1' : + 'biocontainers/multiqc:1.30--pyhdfd78af_1' }" input: path multiqc_files, stageAs: "?/*" path(multiqc_config) path(extra_multiqc_config) path(multiqc_logo) + path(replace_names) + path(sample_names) output: path "*multiqc_report.html", emit: report @@ -23,16 +25,22 @@ process MULTIQC { script: def args = task.ext.args ?: '' + def prefix = task.ext.prefix ? "--filename ${task.ext.prefix}.html" : '' def config = multiqc_config ? "--config $multiqc_config" : '' def extra_config = extra_multiqc_config ? "--config $extra_multiqc_config" : '' - def logo = multiqc_logo ? /--cl-config 'custom_logo: "${multiqc_logo}"'/ : '' + def logo = multiqc_logo ? "--cl-config 'custom_logo: \"${multiqc_logo}\"'" : '' + def replace = replace_names ? "--replace-names ${replace_names}" : '' + def samples = sample_names ? "--sample-names ${sample_names}" : '' """ multiqc \\ --force \\ $args \\ $config \\ + $prefix \\ $extra_config \\ $logo \\ + $replace \\ + $samples \\ . cat <<-END_VERSIONS > versions.yml @@ -44,7 +52,7 @@ process MULTIQC { stub: """ mkdir multiqc_data - touch multiqc_plots + mkdir multiqc_plots touch multiqc_report.html cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/multiqc/meta.yml b/modules/nf-core/multiqc/meta.yml index 45a9bc35e..ce30eb732 100644 --- a/modules/nf-core/multiqc/meta.yml +++ b/modules/nf-core/multiqc/meta.yml @@ -1,5 +1,6 @@ name: multiqc -description: Aggregate results from bioinformatics analyses across many samples into a single report +description: Aggregate results from bioinformatics analyses across many samples into + a single report keywords: - QC - bioinformatics tools @@ -12,40 +13,73 @@ tools: homepage: https://multiqc.info/ documentation: https://multiqc.info/docs/ licence: ["GPL-3.0-or-later"] + identifier: biotools:multiqc input: - multiqc_files: type: file description: | List of reports / files recognised by MultiQC, for example the html and zip output of FastQC + ontologies: [] - multiqc_config: type: file description: Optional config yml for MultiQC pattern: "*.{yml,yaml}" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML - extra_multiqc_config: type: file - description: Second optional config yml for MultiQC. Will override common sections in multiqc_config. + description: Second optional config yml for MultiQC. Will override common sections + in multiqc_config. pattern: "*.{yml,yaml}" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML - multiqc_logo: type: file description: Optional logo file for MultiQC pattern: "*.{png}" -output: - - report: - type: file - description: MultiQC report file - pattern: "multiqc_report.html" - - data: - type: directory - description: MultiQC data dir - pattern: "multiqc_data" - - plots: + ontologies: [] + - replace_names: type: file - description: Plots created by MultiQC - pattern: "*_data" - - versions: + 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 # TSV + - sample_names: type: file - description: File containing software versions - pattern: "versions.yml" + description: | + Optional TSV file with headers, passed to the MultiQC --sample_names + argument. + pattern: "*.{tsv}" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV +output: + report: + - "*multiqc_report.html": + type: file + description: MultiQC report file + pattern: "multiqc_report.html" + ontologies: [] + data: + - "*_data": + type: directory + description: MultiQC data dir + pattern: "multiqc_data" + plots: + - "*_plots": + type: file + description: Plots created by MultiQC + pattern: "*_data" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@abhi18av" - "@bunop" diff --git a/modules/nf-core/multiqc/tests/main.nf.test b/modules/nf-core/multiqc/tests/main.nf.test index f1c4242ef..33316a7dd 100644 --- a/modules/nf-core/multiqc/tests/main.nf.test +++ b/modules/nf-core/multiqc/tests/main.nf.test @@ -8,6 +8,8 @@ nextflow_process { tag "modules_nfcore" tag "multiqc" + config "./nextflow.config" + test("sarscov2 single-end [fastqc]") { when { @@ -17,6 +19,8 @@ nextflow_process { input[1] = [] input[2] = [] input[3] = [] + input[4] = [] + input[5] = [] """ } } @@ -41,6 +45,8 @@ nextflow_process { input[1] = Channel.of(file("https://github.com/nf-core/tools/raw/dev/nf_core/pipeline-template/assets/multiqc_config.yml", checkIfExists: true)) input[2] = [] input[3] = [] + input[4] = [] + input[5] = [] """ } } @@ -66,6 +72,8 @@ nextflow_process { input[1] = [] input[2] = [] input[3] = [] + input[4] = [] + input[5] = [] """ } } diff --git a/modules/nf-core/multiqc/tests/main.nf.test.snap b/modules/nf-core/multiqc/tests/main.nf.test.snap index bfebd8029..0d3f288bd 100644 --- a/modules/nf-core/multiqc/tests/main.nf.test.snap +++ b/modules/nf-core/multiqc/tests/main.nf.test.snap @@ -2,14 +2,14 @@ "multiqc_versions_single": { "content": [ [ - "versions.yml:md5,21f35ee29416b9b3073c28733efe4b7d" + "versions.yml:md5,e65ce731db2128b8e4dd43d6e880fc1c" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.3" }, - "timestamp": "2024-02-29T08:48:55.657331" + "timestamp": "2025-07-10T08:06:23.563041241" }, "multiqc_stub": { "content": [ @@ -17,25 +17,25 @@ "multiqc_report.html", "multiqc_data", "multiqc_plots", - "versions.yml:md5,21f35ee29416b9b3073c28733efe4b7d" + "versions.yml:md5,e65ce731db2128b8e4dd43d6e880fc1c" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.3" }, - "timestamp": "2024-02-29T08:49:49.071937" + "timestamp": "2025-07-10T08:06:48.96226832" }, "multiqc_versions_config": { "content": [ [ - "versions.yml:md5,21f35ee29416b9b3073c28733efe4b7d" + "versions.yml:md5,e65ce731db2128b8e4dd43d6e880fc1c" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" + "nf-test": "0.9.2", + "nextflow": "25.04.3" }, - "timestamp": "2024-02-29T08:49:25.457567" + "timestamp": "2025-07-10T08:06:40.627008706" } -} \ No newline at end of file +} diff --git a/modules/nf-core/multiqc/tests/nextflow.config b/modules/nf-core/multiqc/tests/nextflow.config new file mode 100644 index 000000000..c537a6a3e --- /dev/null +++ b/modules/nf-core/multiqc/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'MULTIQC' { + ext.prefix = null + } +} diff --git a/modules/nf-core/multiqc/tests/tags.yml b/modules/nf-core/multiqc/tests/tags.yml deleted file mode 100644 index bea6c0d37..000000000 --- a/modules/nf-core/multiqc/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -multiqc: - - modules/nf-core/multiqc/** diff --git a/modules/nf-core/picard/collectinsertsizemetrics/environment.yml b/modules/nf-core/picard/collectinsertsizemetrics/environment.yml index 5c85f8725..8f34e975c 100644 --- a/modules/nf-core/picard/collectinsertsizemetrics/environment.yml +++ b/modules/nf-core/picard/collectinsertsizemetrics/environment.yml @@ -1,7 +1,7 @@ -name: picard_collectinsertsizemetrics +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults dependencies: - - bioconda::picard=3.1.0 + - bioconda::picard=3.3.0 diff --git a/modules/nf-core/picard/collectinsertsizemetrics/main.nf b/modules/nf-core/picard/collectinsertsizemetrics/main.nf index 48e4d2ad2..bed044028 100644 --- a/modules/nf-core/picard/collectinsertsizemetrics/main.nf +++ b/modules/nf-core/picard/collectinsertsizemetrics/main.nf @@ -4,8 +4,8 @@ process PICARD_COLLECTINSERTSIZEMETRICS { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.1.0--hdfd78af_0' : - 'biocontainers/picard:3.1.0--hdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : + 'biocontainers/picard:3.3.0--hdfd78af_0' }" input: tuple val(meta), path(bam) @@ -32,7 +32,6 @@ process PICARD_COLLECTINSERTSIZEMETRICS { picard \\ -Xmx${avail_mem}M \\ CollectInsertSizeMetrics \\ - $args \\ --INPUT $bam \\ --OUTPUT ${prefix}.txt \\ --Histogram_FILE ${prefix}.pdf \\ @@ -47,6 +46,9 @@ process PICARD_COLLECTINSERTSIZEMETRICS { stub: def prefix = task.ext.prefix ?: "${meta.id}" + if (!task.memory) { + log.info '[Picard CollectInsertSizeMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' + } """ touch ${prefix}.pdf touch ${prefix}.txt diff --git a/modules/nf-core/picard/collectinsertsizemetrics/meta.yml b/modules/nf-core/picard/collectinsertsizemetrics/meta.yml index efd5abe06..1c4572c58 100644 --- a/modules/nf-core/picard/collectinsertsizemetrics/meta.yml +++ b/modules/nf-core/picard/collectinsertsizemetrics/meta.yml @@ -12,35 +12,49 @@ tools: homepage: "https://broadinstitute.github.io/picard/" documentation: "https://broadinstitute.github.io/picard/" tool_dev_url: "https://github.com/broadinstitute/picard" - licence: "['MIT']" + licence: ["MIT"] + identifier: biotools:picard_tools input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: BAM/CRAM/SAM file - pattern: "*.{bam,cram,sam}" + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: BAM/CRAM/SAM file + pattern: "*.{bam,cram,sam}" + ontologies: [] output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - pdf: - type: file - description: Histogram plots of the insert size metrics computed by Picard - pattern: "*.pdf" - - metrics: - type: file - description: Values used by Picard to generate the insert size histograms - pattern: "*.txt" + metrics: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.txt": + type: file + description: Values used by Picard to generate the insert size histograms + pattern: "*.txt" + ontologies: [] + histogram: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.pdf": + type: file + description: Insert size histogram in PDF format + pattern: "*.pdf" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@FerriolCalvet" maintainers: diff --git a/modules/nf-core/picard/collectinsertsizemetrics/tests/main.nf.test b/modules/nf-core/picard/collectinsertsizemetrics/tests/main.nf.test new file mode 100644 index 000000000..4cf7a3323 --- /dev/null +++ b/modules/nf-core/picard/collectinsertsizemetrics/tests/main.nf.test @@ -0,0 +1,62 @@ + +nextflow_process { + + name "Test Process PICARD_COLLECTINSERTSIZEMETRICS" + script "../main.nf" + process "PICARD_COLLECTINSERTSIZEMETRICS" + + tag "modules" + tag "modules_nfcore" + tag "picard" + tag "picard/collectinsertsizemetrics" + + test("test-picard-collectinsertsizemetrics") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) + ] + + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + file(process.out.metrics[0][1]).readLines()[5..8], + file(process.out.histogram[0][1]).name, + process.out.versions + ).match() + } + ) + } + } + + test("test-picard-collectinsertsizemetrics-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.bam', checkIfExists: true) + ] + + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + +} diff --git a/modules/nf-core/picard/collectinsertsizemetrics/tests/main.nf.test.snap b/modules/nf-core/picard/collectinsertsizemetrics/tests/main.nf.test.snap new file mode 100644 index 000000000..cbe9329d0 --- /dev/null +++ b/modules/nf-core/picard/collectinsertsizemetrics/tests/main.nf.test.snap @@ -0,0 +1,74 @@ +{ + "test-picard-collectinsertsizemetrics": { + "content": [ + [ + "## METRICS CLASS\tpicard.analysis.InsertSizeMetrics", + "MEDIAN_INSERT_SIZE\tMODE_INSERT_SIZE\tMEDIAN_ABSOLUTE_DEVIATION\tMIN_INSERT_SIZE\tMAX_INSERT_SIZE\tMEAN_INSERT_SIZE\tSTANDARD_DEVIATION\tREAD_PAIRS\tPAIR_ORIENTATION\tWIDTH_OF_10_PERCENT\tWIDTH_OF_20_PERCENT\tWIDTH_OF_30_PERCENT\tWIDTH_OF_40_PERCENT\tWIDTH_OF_50_PERCENT\tWIDTH_OF_60_PERCENT\tWIDTH_OF_70_PERCENT\tWIDTH_OF_80_PERCENT\tWIDTH_OF_90_PERCENT\tWIDTH_OF_95_PERCENT\tWIDTH_OF_99_PERCENT\tSAMPLE\tLIBRARY\tREAD_GROUP", + "209\t159\t46\t77\t364\t207.659794\t66.769018\t97\tFR\t25\t49\t59\t77\t93\t123\t145\t183\t223\t255\t311\t\t\t", + "" + ], + "test.pdf", + [ + "versions.yml:md5,38d39e9882afe7ac015213c286745056" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T10:55:45.769771444" + }, + "test-picard-collectinsertsizemetrics-stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,38d39e9882afe7ac015213c286745056" + ], + "histogram": [ + [ + { + "id": "test", + "single_end": false + }, + "test.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "metrics": [ + [ + { + "id": "test", + "single_end": false + }, + "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,38d39e9882afe7ac015213c286745056" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T10:56:09.914953495" + } +} \ No newline at end of file diff --git a/modules/nf-core/picard/collectrnaseqmetrics/environment.yml b/modules/nf-core/picard/collectrnaseqmetrics/environment.yml new file mode 100644 index 000000000..8f34e975c --- /dev/null +++ b/modules/nf-core/picard/collectrnaseqmetrics/environment.yml @@ -0,0 +1,7 @@ +--- +# 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 diff --git a/modules/nf-core/picard/collectrnaseqmetrics/main.nf b/modules/nf-core/picard/collectrnaseqmetrics/main.nf new file mode 100644 index 000000000..eb80fdc70 --- /dev/null +++ b/modules/nf-core/picard/collectrnaseqmetrics/main.nf @@ -0,0 +1,62 @@ +process PICARD_COLLECTRNASEQMETRICS { + 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' }" + + input: + tuple val(meta), path(bam) + path ref_flat + path fasta + path rrna_intervals + + output: + tuple val(meta), path("*.rna_metrics") , emit: metrics + tuple val(meta), path("*.pdf") , emit: pdf, 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 reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : "" + def rrna = rrna_intervals ? "--RIBOSOMAL_INTERVALS ${rrna_intervals}" : "" + def avail_mem = 3072 + if (!task.memory) { + log.info '[Picard CollectRnaSeqMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.' + } else { + avail_mem = (task.memory.mega*0.8).intValue() + } + """ + picard \\ + -Xmx${avail_mem}M \\ + CollectRnaSeqMetrics \\ + $args \\ + $reference \\ + $rrna \\ + --REF_FLAT $ref_flat \\ + --INPUT $bam \\ + --OUTPUT ${prefix}.rna_metrics + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + picard: \$(echo \$(picard CollectRnaSeqMetrics --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:) + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.rna_metrics + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + picard: \$(echo \$(picard CollectRnaSeqMetrics --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:) + END_VERSIONS + """ +} diff --git a/modules/nf-core/picard/collectrnaseqmetrics/meta.yml b/modules/nf-core/picard/collectrnaseqmetrics/meta.yml new file mode 100644 index 000000000..b8da63e9f --- /dev/null +++ b/modules/nf-core/picard/collectrnaseqmetrics/meta.yml @@ -0,0 +1,76 @@ +name: "picard_collectrnaseqmetrics" +description: Collect metrics from a RNAseq BAM file +keywords: + - rna + - bam + - metrics + - alignment + - statistics + - quality +tools: + - "picard": + description: | + A set of command line tools (in Java) for manipulating high-throughput sequencing (HTS) + data and formats such as SAM/BAM/CRAM and VCF. + homepage: "https://broadinstitute.github.io/picard/" + documentation: "https://broadinstitute.github.io/picard/" + tool_dev_url: "https://github.com/broadinstitute/picard" + licence: ["MIT"] + identifier: biotools:picard_tools +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false, strandedness:true ] + - bam: + type: file + description: BAM/SAM file + pattern: "*.{bam,sam}" + ontologies: [] + - ref_flat: + type: file + description: Genome ref_flat file + ontologies: [] + - fasta: + type: file + description: Genome fasta file + ontologies: [] + - rrna_intervals: + type: file + description: Interval file of ribosomal RNA regions + ontologies: [] +output: + metrics: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.rna_metrics": + type: file + description: RNA alignment metrics files generated by picard + pattern: "*.rna_metrics" + ontologies: [] + pdf: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.pdf": + type: file + description: Plot normalized position vs. coverage in a pdf file generated + by picard + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@anoronh4" +maintainers: + - "@anoronh4" diff --git a/modules/nf-core/picard/collectrnaseqmetrics/tests/main.nf.test b/modules/nf-core/picard/collectrnaseqmetrics/tests/main.nf.test new file mode 100644 index 000000000..9ab185521 --- /dev/null +++ b/modules/nf-core/picard/collectrnaseqmetrics/tests/main.nf.test @@ -0,0 +1,81 @@ +nextflow_process { + + name "Test Process PICARD_COLLECTRNASEQMETRICS" + script "../main.nf" + process "PICARD_COLLECTRNASEQMETRICS" + config "./nextflow.config" + + tag "modules" + tag "modules_nfcore" + tag "picard" + tag "picard/collectrnaseqmetrics" + tag "ucsc/gtftogenepred" + + setup { + run("UCSC_GTFTOGENEPRED") { + script "../../../ucsc/gtftogenepred/main.nf" + process { + """ + input[0] = Channel.of([ + [ id:'test' ], + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.gtf', checkIfExists: true) ] + ]) + """ + } + } + } + + test("sarscov2 - fasta - gtf") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false, strandedness:'forward' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) + ] + input[1] = UCSC_GTFTOGENEPRED.out.refflat.map{ it[1] } + input[2] = file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + input[3] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert file(process.out.metrics[0][1]).text.contains('CollectRnaSeqMetrics') }, + { assert snapshot( + process.out.versions, + process.out.pdf + ).match() } + ) + } + } + + test("sarscov2 - fasta - gtf - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false, strandedness:'forward' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) + ] + input[1] = UCSC_GTFTOGENEPRED.out.refflat.map{ it[1] } + input[2] = file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + input[3] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/picard/collectrnaseqmetrics/tests/main.nf.test.snap b/modules/nf-core/picard/collectrnaseqmetrics/tests/main.nf.test.snap new file mode 100644 index 000000000..ad6503afd --- /dev/null +++ b/modules/nf-core/picard/collectrnaseqmetrics/tests/main.nf.test.snap @@ -0,0 +1,60 @@ +{ + "sarscov2 - fasta - gtf": { + "content": [ + [ + "versions.yml:md5,8d0867f89947c081711de09338138c2e" + ], + [ + + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T16:10:39.199344417" + }, + "sarscov2 - fasta - gtf - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false, + "strandedness": "forward" + }, + "test.rna_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + "versions.yml:md5,8d0867f89947c081711de09338138c2e" + ], + "metrics": [ + [ + { + "id": "test", + "single_end": false, + "strandedness": "forward" + }, + "test.rna_metrics:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "pdf": [ + + ], + "versions": [ + "versions.yml:md5,8d0867f89947c081711de09338138c2e" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T16:10:57.248132065" + } +} \ No newline at end of file diff --git a/modules/nf-core/picard/collectrnaseqmetrics/tests/nextflow.config b/modules/nf-core/picard/collectrnaseqmetrics/tests/nextflow.config new file mode 100644 index 000000000..bc82e10c1 --- /dev/null +++ b/modules/nf-core/picard/collectrnaseqmetrics/tests/nextflow.config @@ -0,0 +1,13 @@ +process { + withName:UCSC_GTFTOGENEPRED { + ext.args = "-genePredExt -geneNameAsName2 -ignoreGroupsWithoutExons" + } + withName:PICARD_COLLECTRNASEQMETRICS { + ext.args = { ( meta.strandedness == "forward" || meta.single_end ) ? + "--STRAND_SPECIFICITY FIRST_READ_TRANSCRIPTION_STRAND" : + meta.strandedness == "reverse" ? + "--STRAND_SPECIFICITY SECOND_READ_TRANSCRIPTION_STRAND" : + "--STRAND_SPECIFICITY NONE" + } + } +} diff --git a/modules/nf-core/picard/collectwgsmetrics/environment.yml b/modules/nf-core/picard/collectwgsmetrics/environment.yml index 8adda4914..5f2dfc031 100644 --- a/modules/nf-core/picard/collectwgsmetrics/environment.yml +++ b/modules/nf-core/picard/collectwgsmetrics/environment.yml @@ -1,8 +1,8 @@ -name: picard_collectwgsmetrics +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults dependencies: - - bioconda::picard=3.1.0 - - r::r-base + - bioconda::picard=3.3.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 67aa5b5e8..39cf7d2b7 100644 --- a/modules/nf-core/picard/collectwgsmetrics/main.nf +++ b/modules/nf-core/picard/collectwgsmetrics/main.nf @@ -4,8 +4,8 @@ process PICARD_COLLECTWGSMETRICS { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/picard:3.1.0--hdfd78af_0' : - 'biocontainers/picard:3.1.0--hdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/picard:3.3.0--hdfd78af_0' : + 'biocontainers/picard:3.3.0--hdfd78af_0' }" input: tuple val(meta), path(bam), path(bai) diff --git a/modules/nf-core/picard/collectwgsmetrics/meta.yml b/modules/nf-core/picard/collectwgsmetrics/meta.yml index 5576ef928..a27e0a88c 100644 --- a/modules/nf-core/picard/collectwgsmetrics/meta.yml +++ b/modules/nf-core/picard/collectwgsmetrics/meta.yml @@ -1,5 +1,6 @@ name: picard_collectwgsmetrics -description: Collect metrics about coverage and performance of whole genome sequencing (WGS) experiments. +description: Collect metrics about coverage and performance of whole genome sequencing + (WGS) experiments. keywords: - alignment - metrics @@ -14,55 +15,67 @@ tools: homepage: https://broadinstitute.github.io/picard/ documentation: https://broadinstitute.github.io/picard/ licence: ["MIT"] + identifier: biotools:picard_tools input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: Aligned reads file - pattern: "*.{bam, cram}" - - bai: - type: file - description: (Optional) Aligned reads file index - pattern: "*.{bai,crai}" - - meta2: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'genome' ] - - fasta: - type: file - description: Genome fasta file - pattern: "*.{fa,fasta,fna}" - - meta3: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'genome' ] - - fai: - type: file - description: Genome fasta file index - pattern: "*.{fai}" + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + 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: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fasta: + type: file + description: Genome fasta file + pattern: "*.{fa,fasta,fna}" + ontologies: [] + - - meta3: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fai: + type: file + description: Genome fasta file index + pattern: "*.{fai}" + ontologies: [] - intervallist: type: file - description: Picard Interval List. Defines which contigs to include. Can be generated from a BED file with GATK BedToIntervalList. + description: Picard Interval List. Defines which contigs to include. Can be generated + from a BED file with GATK BedToIntervalList. + ontologies: [] output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - metrics: - type: file - description: Alignment metrics files generated by picard - pattern: "*_{metrics}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + metrics: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*_metrics": + type: file + description: Alignment metrics files generated by picard + pattern: "*_{metrics}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@drpatelh" - "@flowuenne" diff --git a/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test b/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test new file mode 100644 index 000000000..a3984566d --- /dev/null +++ b/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test @@ -0,0 +1,83 @@ + +nextflow_process { + + name "Test Process PICARD_COLLECTWGSMETRICS" + script "../main.nf" + process "PICARD_COLLECTWGSMETRICS" + + tag "modules" + tag "modules_nfcore" + tag "picard" + tag "picard/collectwgsmetrics" + + test("test-picard-collectwgsmetrics") { + + 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( + file(process.out.metrics[0][1]).text.contains('coverage high_quality_coverage_count'), + process.out.versions + ).match() + } + ) + } + } + + test("test-picard-collectwgsmetrics-with-interval") { + + 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( + file(process.out.metrics[0][1]).text.contains('coverage high_quality_coverage_count'), + process.out.versions + ).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 new file mode 100644 index 000000000..1958fcdeb --- /dev/null +++ b/modules/nf-core/picard/collectwgsmetrics/tests/main.nf.test.snap @@ -0,0 +1,28 @@ +{ + "test-picard-collectwgsmetrics-with-interval": { + "content": [ + true, + [ + "versions.yml:md5,9927db69fdd55176be5cdbd427d000c2" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T10:15:18.13771243" + }, + "test-picard-collectwgsmetrics": { + "content": [ + true, + [ + "versions.yml:md5,9927db69fdd55176be5cdbd427d000c2" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T10:14:57.786056996" + } +} \ No newline at end of file diff --git a/modules/nf-core/salmon/index/environment.yml b/modules/nf-core/salmon/index/environment.yml new file mode 100644 index 000000000..c9d531434 --- /dev/null +++ b/modules/nf-core/salmon/index/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::salmon=1.10.3 diff --git a/modules/nf-core/salmon/index/main.nf b/modules/nf-core/salmon/index/main.nf new file mode 100644 index 000000000..2e9c6224c --- /dev/null +++ b/modules/nf-core/salmon/index/main.nf @@ -0,0 +1,79 @@ +process SALMON_INDEX { + tag "$transcript_fasta" + label "process_medium" + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/salmon:1.10.3--h6dccd9a_2' : + 'biocontainers/salmon:1.10.3--h6dccd9a_2' }" + + input: + path genome_fasta + path transcript_fasta + + output: + path "salmon" , emit: index + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def decoys = '' + def fasta = transcript_fasta + if (genome_fasta){ + if (genome_fasta.endsWith('.gz')) { + genome_fasta = "<(gunzip -c $genome_fasta)" + } + decoys='-d decoys.txt' + fasta='gentrome.fa' + } + if (transcript_fasta.endsWith('.gz')) { + transcript_fasta = "<(gunzip -c $transcript_fasta)" + } + """ + if [ -n '$genome_fasta' ]; then + grep '^>' $genome_fasta | cut -d ' ' -f 1 | cut -d \$'\\t' -f 1 | sed 's/>//g' > decoys.txt + cat $transcript_fasta $genome_fasta > $fasta + fi + + salmon \\ + index \\ + --threads $task.cpus \\ + -t $fasta \\ + $decoys \\ + $args \\ + -i salmon + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + salmon: \$(echo \$(salmon --version) | sed -e "s/salmon //g") + END_VERSIONS + """ + + stub: + """ + mkdir salmon + touch salmon/complete_ref_lens.bin + touch salmon/ctable.bin + touch salmon/ctg_offsets.bin + touch salmon/duplicate_clusters.tsv + touch salmon/info.json + touch salmon/mphf.bin + touch salmon/pos.bin + touch salmon/pre_indexing.log + touch salmon/rank.bin + touch salmon/refAccumLengths.bin + touch salmon/ref_indexing.log + touch salmon/reflengths.bin + touch salmon/refseq.bin + touch salmon/seq.bin + touch salmon/versionInfo.json + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + salmon: \$(echo \$(salmon --version) | sed -e "s/salmon //g") + END_VERSIONS + """ +} diff --git a/modules/nf-core/salmon/index/meta.yml b/modules/nf-core/salmon/index/meta.yml new file mode 100644 index 000000000..4e0367b4a --- /dev/null +++ b/modules/nf-core/salmon/index/meta.yml @@ -0,0 +1,44 @@ +name: salmon_index +description: Create index for salmon +keywords: + - index + - fasta + - genome + - reference +tools: + - salmon: + description: | + Salmon is a tool for wicked-fast transcript quantification from RNA-seq data + homepage: https://salmon.readthedocs.io/en/latest/salmon.html + manual: https://salmon.readthedocs.io/en/latest/salmon.html + doi: 10.1038/nmeth.4197 + licence: ["GPL-3.0-or-later"] + identifier: biotools:salmon +input: + - genome_fasta: + type: file + description: Fasta file of the reference genome + ontologies: [] + - transcript_fasta: + type: file + description: Fasta file of the reference transcriptome + ontologies: [] +output: + index: + - salmon: + type: directory + description: Folder containing the star index files + pattern: "salmon" + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@kevinmenden" + - "@drpatelh" +maintainers: + - "@kevinmenden" + - "@drpatelh" diff --git a/modules/nf-core/salmon/index/tests/main.nf.test b/modules/nf-core/salmon/index/tests/main.nf.test new file mode 100644 index 000000000..30b7359b9 --- /dev/null +++ b/modules/nf-core/salmon/index/tests/main.nf.test @@ -0,0 +1,92 @@ +nextflow_process { + + name "Test Process SALMON_INDEX" + script "../main.nf" + process "SALMON_INDEX" + tag "modules" + tag "modules_nfcore" + tag "salmon" + tag "salmon/index" + + test("sarscov2") { + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = Channel.of([file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.fasta", checkIfExists: true)]) + input[1] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/transcriptome.fasta", checkIfExists: true)]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.index.get(0)).exists() }, + { assert snapshot( + file(process.out.index[0]).listFiles().collect { it.getName() }.sort().toString(), + process.out.versions + ).match()} + ) + } + + } + + test("sarscov2 transcriptome only") { + + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = Channel.of([]) + input[1] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/transcriptome.fasta", checkIfExists: true)]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.index.get(0)).exists() }, + { assert snapshot( + file(process.out.index[0]).listFiles().collect { it.getName() }.sort().toString(), + process.out.versions + ).match()} + ) + } + + } + + test("sarscov2 stub") { + options "-stub" + when { + params { + outdir = "$outputDir" + } + process { + """ + input[0] = Channel.of([file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.fasta", checkIfExists: true)]) + input[1] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/transcriptome.fasta", checkIfExists: true)]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.index.get(0)).exists() }, + { assert snapshot( + file(process.out.index[0]).listFiles().collect { it.getName() }.sort().toString(), + process.out.versions + ).match()} + ) + } + + } + +} \ No newline at end of file diff --git a/modules/nf-core/salmon/index/tests/main.nf.test.snap b/modules/nf-core/salmon/index/tests/main.nf.test.snap new file mode 100644 index 000000000..f8ed44d7d --- /dev/null +++ b/modules/nf-core/salmon/index/tests/main.nf.test.snap @@ -0,0 +1,41 @@ +{ + "sarscov2 stub": { + "content": [ + "[complete_ref_lens.bin, ctable.bin, ctg_offsets.bin, duplicate_clusters.tsv, info.json, mphf.bin, pos.bin, pre_indexing.log, rank.bin, refAccumLengths.bin, ref_indexing.log, reflengths.bin, refseq.bin, seq.bin, versionInfo.json]", + [ + "versions.yml:md5,85337fa0a286ea35073ee5260974e307" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2025-01-20T12:57:51.498323" + }, + "sarscov2": { + "content": [ + "[complete_ref_lens.bin, ctable.bin, ctg_offsets.bin, duplicate_clusters.tsv, info.json, mphf.bin, pos.bin, pre_indexing.log, rank.bin, refAccumLengths.bin, ref_indexing.log, reflengths.bin, refseq.bin, seq.bin, versionInfo.json]", + [ + "versions.yml:md5,85337fa0a286ea35073ee5260974e307" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2025-01-20T12:57:33.474302" + }, + "sarscov2 transcriptome only": { + "content": [ + "[complete_ref_lens.bin, ctable.bin, ctg_offsets.bin, duplicate_clusters.tsv, info.json, mphf.bin, pos.bin, pre_indexing.log, rank.bin, refAccumLengths.bin, ref_indexing.log, reflengths.bin, refseq.bin, seq.bin, versionInfo.json]", + [ + "versions.yml:md5,85337fa0a286ea35073ee5260974e307" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2025-01-20T12:57:42.420247" + } +} \ No newline at end of file diff --git a/modules/nf-core/salmon/quant/environment.yml b/modules/nf-core/salmon/quant/environment.yml new file mode 100644 index 000000000..c9d531434 --- /dev/null +++ b/modules/nf-core/salmon/quant/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::salmon=1.10.3 diff --git a/modules/nf-core/salmon/quant/main.nf b/modules/nf-core/salmon/quant/main.nf new file mode 100644 index 000000000..b7c71871c --- /dev/null +++ b/modules/nf-core/salmon/quant/main.nf @@ -0,0 +1,112 @@ +process SALMON_QUANT { + 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/salmon:1.10.3--h6dccd9a_2' + : 'biocontainers/salmon:1.10.3--h6dccd9a_2'}" + + input: + tuple val(meta), path(reads) + path index + path gtf + path transcript_fasta + val alignment_mode + val lib_type + + output: + tuple val(meta), path("${prefix}"), emit: results + tuple val(meta), path("*info.json"), emit: json_info, optional: true + tuple val(meta), path("*lib_format_counts.json"), emit: lib_format_counts, optional: true + 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 reference = "--index ${index}" + def reads1 = [] + def reads2 = [] + meta.single_end ? [reads].flatten().each { reads1 << it } : reads.eachWithIndex { v, ix -> (ix & 1 ? reads2 : reads1) << v } + def input_reads = meta.single_end ? "-r ${reads1.join(" ")}" : "-1 ${reads1.join(" ")} -2 ${reads2.join(" ")}" + if (alignment_mode) { + reference = "-t ${transcript_fasta}" + input_reads = "-a ${reads}" + } + + def strandedness_opts = [ + 'A', + 'U', + 'SF', + 'SR', + 'IS', + 'IU', + 'ISF', + 'ISR', + 'OS', + 'OU', + 'OSF', + 'OSR', + 'MS', + 'MU', + 'MSF', + 'MSR', + ] + def strandedness = 'A' + if (lib_type) { + if (strandedness_opts.contains(lib_type)) { + strandedness = lib_type + } + else { + log.info("[Salmon Quant] Invalid library type specified '--libType=${lib_type}', defaulting to auto-detection with '--libType=A'.") + } + } + else { + strandedness = meta.single_end ? 'U' : 'IU' + if (meta.strandedness == 'forward') { + strandedness = meta.single_end ? 'SF' : 'ISF' + } + else if (meta.strandedness == 'reverse') { + strandedness = meta.single_end ? 'SR' : 'ISR' + } + } + """ + salmon quant \\ + --geneMap ${gtf} \\ + --threads ${task.cpus} \\ + --libType=${strandedness} \\ + ${reference} \\ + ${input_reads} \\ + ${args} \\ + -o ${prefix} + + if [ -f ${prefix}/aux_info/meta_info.json ]; then + cp ${prefix}/aux_info/meta_info.json "${prefix}_meta_info.json" + fi + if [ -f ${prefix}/lib_format_counts.json ]; then + cp ${prefix}/lib_format_counts.json "${prefix}_lib_format_counts.json" + fi + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + salmon: \$(echo \$(salmon --version) | sed -e "s/salmon //g") + END_VERSIONS + """ + + stub: + prefix = task.ext.prefix ?: "${meta.id}" + """ + mkdir ${prefix} + touch ${prefix}_meta_info.json + touch ${prefix}_lib_format_counts.json + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + salmon: \$(echo \$(salmon --version) | sed -e "s/salmon //g") + END_VERSIONS + """ +} diff --git a/modules/nf-core/salmon/quant/meta.yml b/modules/nf-core/salmon/quant/meta.yml new file mode 100644 index 000000000..40e8eb965 --- /dev/null +++ b/modules/nf-core/salmon/quant/meta.yml @@ -0,0 +1,92 @@ +name: salmon_quant +description: gene/transcript quantification with Salmon +keywords: + - index + - fasta + - genome + - reference +tools: + - salmon: + description: | + Salmon is a tool for wicked-fast transcript quantification from RNA-seq data + homepage: https://salmon.readthedocs.io/en/latest/salmon.html + manual: https://salmon.readthedocs.io/en/latest/salmon.html + doi: 10.1038/nmeth.4197 + licence: ["GPL-3.0-or-later"] + identifier: biotools:salmon +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 for single-end or paired-end data. + Multiple single-end fastqs or pairs of paired-end fastqs are + handled. + ontologies: [] + - index: + type: directory + description: Folder containing the star index files + - gtf: + type: file + description: GTF of the reference transcriptome + ontologies: [] + - transcript_fasta: + type: file + description: Fasta file of the reference transcriptome + ontologies: [] + - alignment_mode: + type: boolean + description: whether to run salmon in alignment mode + - lib_type: + type: string + description: | + Override library type inferred based on strandedness defined in meta object +output: + results: + - - meta: + type: directory + description: Folder containing the quantification results for a specific sample + pattern: "${prefix}" + - ${prefix}: + type: directory + description: Folder containing the quantification results for a specific sample + pattern: "${prefix}" + json_info: + - - meta: + type: directory + description: Folder containing the quantification results for a specific sample + pattern: "${prefix}" + - "*info.json": + type: file + description: File containing meta information from Salmon quant + pattern: "*info.json" + ontologies: + - edam: http://edamontology.org/format_3464 # JSON + lib_format_counts: + - - meta: + type: directory + description: Folder containing the quantification results for a specific sample + pattern: "${prefix}" + - "*lib_format_counts.json": + type: file + description: File containing the library format counts + pattern: "*lib_format_counts.json" + ontologies: + - edam: http://edamontology.org/format_3464 # JSON + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@kevinmenden" + - "@drpatelh" +maintainers: + - "@kevinmenden" + - "@drpatelh" diff --git a/modules/nf-core/salmon/quant/tests/main.nf.test b/modules/nf-core/salmon/quant/tests/main.nf.test new file mode 100644 index 000000000..2964cc3d0 --- /dev/null +++ b/modules/nf-core/salmon/quant/tests/main.nf.test @@ -0,0 +1,320 @@ +nextflow_process { + + name "Test Process SALMON_QUANT" + script "../main.nf" + process "SALMON_QUANT" + config "./nextflow.config" + tag "modules" + tag "modules_nfcore" + tag "salmon" + tag "salmon/quant" + tag "salmon/index" + + setup { + run("SALMON_INDEX") { + script "../../../salmon/index/main.nf" + process { + """ + input[0] = Channel.of([file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.fasta", checkIfExists: true)]) + input[1] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/transcriptome.fasta", checkIfExists: true)]) + """ + } + } + } + + test("sarscov2 - single_end") { + + 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) ] + ]) + input[1] = SALMON_INDEX.out.index + input[2] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gtf", checkIfExists: true)]) + input[3] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/transcriptome.fasta", checkIfExists: true)]) + input[4] = false + input[5] = '' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.json_info.get(0).get(1)).exists() }, + { assert path(process.out.results.get(0).get(1)).exists() }, + { assert snapshot( + process.out.versions, + process.out.lib_format_counts + ).match() } + ) + } + + } + + test("sarscov2 - single_end stub") { + options "-stub" + 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) ] + ]) + input[1] = SALMON_INDEX.out.index + input[2] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gtf", checkIfExists: true)]) + input[3] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/transcriptome.fasta", checkIfExists: true)]) + input[4] = false + input[5] = '' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.json_info.get(0).get(1)).exists() }, + { assert path(process.out.results.get(0).get(1)).exists() }, + { assert snapshot( + process.out.versions, + process.out.lib_format_counts + ).match() } + ) + } + + } + + test("sarscov2 - single_end lib type A") { + + 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) ] + ]) + input[1] = SALMON_INDEX.out.index + input[2] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gtf", checkIfExists: true)]) + input[3] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/transcriptome.fasta", checkIfExists: true)]) + input[4] = false + input[5] = 'A' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.json_info.get(0).get(1)).exists() }, + { assert path(process.out.results.get(0).get(1)).exists() }, + { assert snapshot( + process.out.versions, + process.out.lib_format_counts + ).match() } + ) + } + + } + + test("sarscov2 - single_end lib type A stub") { + options "-stub" + 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) ] + ]) + input[1] = SALMON_INDEX.out.index + input[2] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gtf", checkIfExists: true)]) + input[3] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/transcriptome.fasta", checkIfExists: true)]) + input[4] = false + input[5] = 'A' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.json_info.get(0).get(1)).exists() }, + { assert path(process.out.results.get(0).get(1)).exists() }, + { assert snapshot( + process.out.versions, + process.out.lib_format_counts + ).match() } + ) + } + + } + + test("sarscov2 - pair_end") { + + 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), + file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_2.fastq.gz", checkIfExists: true) + ] + ]) + input[1] = SALMON_INDEX.out.index + input[2] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gtf", checkIfExists: true)]) + input[3] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/transcriptome.fasta", checkIfExists: true)]) + input[4] = false + input[5] = '' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.json_info.get(0).get(1)).exists() }, + { assert path(process.out.results.get(0).get(1)).exists() }, + { assert snapshot( + process.out.versions, + process.out.lib_format_counts + ).match() } + ) + } + + } + + test("sarscov2 - pair_end stub") { + options "-stub" + 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), + file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_2.fastq.gz", checkIfExists: true) + ] + ]) + input[1] = SALMON_INDEX.out.index + input[2] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gtf", checkIfExists: true)]) + input[3] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/transcriptome.fasta", checkIfExists: true)]) + input[4] = false + input[5] = '' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.json_info.get(0).get(1)).exists() }, + { assert path(process.out.results.get(0).get(1)).exists() }, + { assert snapshot( + process.out.versions, + process.out.lib_format_counts + ).match() } + ) + } + + } + + test("sarscov2 - pair_end multiple") { + + 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), + 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] = SALMON_INDEX.out.index + input[2] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gtf", checkIfExists: true)]) + input[3] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/transcriptome.fasta", checkIfExists: true)]) + input[4] = false + input[5] = '' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.json_info.get(0).get(1)).exists() }, + { assert path(process.out.results.get(0).get(1)).exists() }, + { assert snapshot( + process.out.versions, + process.out.lib_format_counts + ).match() } + ) + } + + } + + test("sarscov2 - pair_end multiple stub") { + options "-stub" + 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), + 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] = SALMON_INDEX.out.index + input[2] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gtf", checkIfExists: true)]) + input[3] = Channel.of([file(params.modules_testdata_base_path + "genomics/sarscov2/genome/transcriptome.fasta", checkIfExists: true)]) + input[4] = false + input[5] = '' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert path(process.out.json_info.get(0).get(1)).exists() }, + { assert path(process.out.results.get(0).get(1)).exists() }, + { assert snapshot( + process.out.versions, + process.out.lib_format_counts + ).match() } + ) + } + + } +} diff --git a/modules/nf-core/salmon/quant/tests/main.nf.test.snap b/modules/nf-core/salmon/quant/tests/main.nf.test.snap new file mode 100644 index 000000000..ea22a80ce --- /dev/null +++ b/modules/nf-core/salmon/quant/tests/main.nf.test.snap @@ -0,0 +1,170 @@ +{ + "sarscov2 - single_end": { + "content": [ + [ + "versions.yml:md5,0d510d5db6398e2c8ca9443330740607" + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test_lib_format_counts.json:md5,c7999dfccd32c090d94e5951522eecd4" + ] + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T10:01:16.989080539" + }, + "sarscov2 - single_end stub": { + "content": [ + [ + "versions.yml:md5,0d510d5db6398e2c8ca9443330740607" + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test_lib_format_counts.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T10:01:29.340996235" + }, + "sarscov2 - single_end lib type A": { + "content": [ + [ + "versions.yml:md5,0d510d5db6398e2c8ca9443330740607" + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test_lib_format_counts.json:md5,c7999dfccd32c090d94e5951522eecd4" + ] + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T10:01:43.056167576" + }, + "sarscov2 - pair_end multiple": { + "content": [ + [ + "versions.yml:md5,0d510d5db6398e2c8ca9443330740607" + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test_lib_format_counts.json:md5,4a2ee0fac91a4a3471872808d8bd3ff8" + ] + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T10:03:05.500792631" + }, + "sarscov2 - pair_end multiple stub": { + "content": [ + [ + "versions.yml:md5,0d510d5db6398e2c8ca9443330740607" + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test_lib_format_counts.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T10:03:26.428959203" + }, + "sarscov2 - single_end lib type A stub": { + "content": [ + [ + "versions.yml:md5,0d510d5db6398e2c8ca9443330740607" + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test_lib_format_counts.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T10:02:03.420850208" + }, + "sarscov2 - pair_end": { + "content": [ + [ + "versions.yml:md5,0d510d5db6398e2c8ca9443330740607" + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test_lib_format_counts.json:md5,e9516e73c9fb39145513b2a41a0af95f" + ] + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T10:02:16.130074696" + }, + "sarscov2 - pair_end stub": { + "content": [ + [ + "versions.yml:md5,0d510d5db6398e2c8ca9443330740607" + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test_lib_format_counts.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T10:02:39.470004547" + } +} \ No newline at end of file diff --git a/modules/nf-core/salmon/quant/tests/nextflow.config b/modules/nf-core/salmon/quant/tests/nextflow.config new file mode 100644 index 000000000..37c082129 --- /dev/null +++ b/modules/nf-core/salmon/quant/tests/nextflow.config @@ -0,0 +1,7 @@ +process { + + withName: SALMON_QUANT { + ext.args = '--minAssignedFrags 1' + } + +} diff --git a/modules/nf-core/samtools/convert/environment.yml b/modules/nf-core/samtools/convert/environment.yml new file mode 100644 index 000000000..62054fc97 --- /dev/null +++ b/modules/nf-core/samtools/convert/environment.yml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::htslib=1.21 + - bioconda::samtools=1.21 diff --git a/modules/nf-core/samtools/convert/main.nf b/modules/nf-core/samtools/convert/main.nf new file mode 100644 index 000000000..9667e72d8 --- /dev/null +++ b/modules/nf-core/samtools/convert/main.nf @@ -0,0 +1,60 @@ +process SAMTOOLS_CONVERT { + 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), path(index) + tuple val(meta2), path(fasta) + tuple val(meta3), path(fai) + + output: + tuple val(meta), path("*.bam") , emit: bam , optional: true + 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 + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def output_extension = input.getExtension() == "bam" ? "cram" : "bam" + + """ + samtools view \\ + --threads ${task.cpus} \\ + --reference ${fasta} \\ + $args \\ + $input \\ + -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: + def prefix = task.ext.prefix ?: "${meta.id}" + def output_extension = input.getExtension() == "bam" ? "cram" : "bam" + def index_extension = output_extension == "bam" ? "bai" : "crai" + + """ + touch ${prefix}.${output_extension} + touch ${prefix}.${output_extension}.${index_extension} + + 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/convert/meta.yml b/modules/nf-core/samtools/convert/meta.yml new file mode 100644 index 000000000..519812ab5 --- /dev/null +++ b/modules/nf-core/samtools/convert/meta.yml @@ -0,0 +1,113 @@ +name: samtools_convert +description: convert and then index CRAM -> BAM or BAM -> CRAM file +keywords: + - view + - index + - bam + - 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: + 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: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - fasta: + type: file + description: Reference file to create the CRAM file + pattern: "*.{fasta,fa}" + ontologies: [] + - - meta3: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - fai: + type: file + description: Reference index file to create the CRAM file + pattern: "*.{fai}" + ontologies: [] +output: + bam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.bam": + type: file + description: filtered/converted BAM file + pattern: "*{.bam}" + ontologies: [] + cram: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.cram": + type: file + description: filtered/converted CRAM file + pattern: "*{cram}" + ontologies: [] + bai: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.bai": + type: file + description: filtered/converted BAM index + pattern: "*{.bai}" + ontologies: [] + crai: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.crai": + type: file + description: filtered/converted CRAM index + pattern: "*{.crai}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@FriederikeHanssen" + - "@maxulysse" +maintainers: + - "@FriederikeHanssen" + - "@maxulysse" + - "@matthdsm" diff --git a/modules/nf-core/samtools/convert/tests/main.nf.test b/modules/nf-core/samtools/convert/tests/main.nf.test new file mode 100644 index 000000000..91a0c69ea --- /dev/null +++ b/modules/nf-core/samtools/convert/tests/main.nf.test @@ -0,0 +1,107 @@ +nextflow_process { + + name "Test Process SAMTOOLS_CONVERT" + script "../main.nf" + process "SAMTOOLS_CONVERT" + + tag "modules" + tag "modules_nfcore" + tag "samtools" + tag "samtools/convert" + + test("sarscov2 - [bam, bai], fasta, fai") { + + when { + process { + """ + input[0] = Channel.of([ + [id: 'test', single_end: false], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + 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) + ]) + """ + } + } + + 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") } + ) + } + } + + test("homo_sapiens - [cram, crai], fasta, fai") { + + when { + process { + """ + input[0] = Channel.of([ + [id: 'test', single_end: false], // meta map + 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 + 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") } + ) + } + } + + test("sarscov2 - [bam, bai], fasta, fai - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [id: 'test', single_end: false], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + 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) + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match("stub") } + ) + } + } +} diff --git a/modules/nf-core/samtools/convert/tests/main.nf.test.snap b/modules/nf-core/samtools/convert/tests/main.nf.test.snap new file mode 100644 index 000000000..a7bff30d5 --- /dev/null +++ b/modules/nf-core/samtools/convert/tests/main.nf.test.snap @@ -0,0 +1,131 @@ +{ + "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": { + "content": [ + [ + "versions.yml:md5,5bc6eb42ab2a1ea6661f8ee998467ad6" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T07:52:35.516411351" + }, + "bam_to_cram_versions": { + "content": [ + [ + "versions.yml:md5,5bc6eb42ab2a1ea6661f8ee998467ad6" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T07:52:24.694454205" + }, + "stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.cram:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + "versions.yml:md5,5bc6eb42ab2a1ea6661f8ee998467ad6" + ], + "bai": [ + + ], + "bam": [ + + ], + "crai": [ + [ + { + "id": "test", + "single_end": false + }, + "test.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "cram": [ + [ + { + "id": "test", + "single_end": false + }, + "test.cram:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,5bc6eb42ab2a1ea6661f8ee998467ad6" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-17T17:05:45.33625491" + }, + "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" + }, + "timestamp": "2024-03-06T11:14:51.304477426" + } +} \ No newline at end of file diff --git a/modules/nf-core/samtools/faidx/environment.yml b/modules/nf-core/samtools/faidx/environment.yml index 73badedb1..62054fc97 100644 --- a/modules/nf-core/samtools/faidx/environment.yml +++ b/modules/nf-core/samtools/faidx/environment.yml @@ -1,7 +1,8 @@ -name: samtools_faidx +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults dependencies: - - bioconda::samtools=1.17 + - bioconda::htslib=1.21 + - bioconda::samtools=1.21 diff --git a/modules/nf-core/samtools/faidx/main.nf b/modules/nf-core/samtools/faidx/main.nf index 3aa988224..6de0095d8 100644 --- a/modules/nf-core/samtools/faidx/main.nf +++ b/modules/nf-core/samtools/faidx/main.nf @@ -4,15 +4,17 @@ process SAMTOOLS_FAIDX { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.17--h00cdaf9_0' : - 'biocontainers/samtools:1.17--h00cdaf9_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : + 'biocontainers/samtools:1.21--h50ea8bc_0' }" input: tuple val(meta), path(fasta) tuple val(meta2), path(fai) + val get_sizes output: - tuple val(meta), path ("*.{fa,fasta}") , emit: fa , optional: true + tuple val(meta), path ("*.{fa,fasta}") , emit: fa, optional: true + tuple val(meta), path ("*.sizes") , emit: sizes, optional: true tuple val(meta), path ("*.fai") , emit: fai, optional: true tuple val(meta), path ("*.gzi") , emit: gzi, optional: true path "versions.yml" , emit: versions @@ -22,12 +24,15 @@ process SAMTOOLS_FAIDX { script: def args = task.ext.args ?: '' + def get_sizes_command = get_sizes ? "cut -f 1,2 ${fasta}.fai > ${fasta}.sizes" : '' """ samtools \\ faidx \\ $fasta \\ $args + ${get_sizes_command} + cat <<-END_VERSIONS > versions.yml "${task.process}": samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') @@ -37,9 +42,15 @@ process SAMTOOLS_FAIDX { stub: def match = (task.ext.args =~ /-o(?:utput)?\s(.*)\s?/).findAll() def fastacmd = match[0] ? "touch ${match[0][1]}" : '' + def get_sizes_command = get_sizes ? "touch ${fasta}.sizes" : '' """ ${fastacmd} touch ${fasta}.fai + if [[ "${fasta.extension}" == "gz" ]]; then + touch ${fasta}.gzi + fi + + ${get_sizes_command} cat <<-END_VERSIONS > versions.yml diff --git a/modules/nf-core/samtools/faidx/meta.yml b/modules/nf-core/samtools/faidx/meta.yml index e189af28f..b7a2e0c1a 100644 --- a/modules/nf-core/samtools/faidx/meta.yml +++ b/modules/nf-core/samtools/faidx/meta.yml @@ -1,9 +1,10 @@ name: samtools_faidx -description: Index FASTA file +description: Index FASTA file, and optionally generate a file of chromosome sizes keywords: - index - fasta - faidx + - chromosome tools: - samtools: description: | @@ -14,48 +15,88 @@ tools: 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 reference information - e.g. [ id:'test' ] - - fasta: - type: file - description: FASTA file - pattern: "*.{fa,fasta}" - - meta2: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'test' ] - - fai: - type: file - description: FASTA index file - pattern: "*.{fai}" + - - meta: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'test' ] + - fasta: + type: file + description: FASTA file + pattern: "*.{fa,fasta}" + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'test' ] + - fai: + type: file + description: FASTA index file + pattern: "*.{fai}" + ontologies: [] + - get_sizes: + type: boolean + description: use cut to get the sizes of the index (true) or not (false) + output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - fai: - type: file - description: FASTA index file - pattern: "*.{fai}" - - gzi: - type: file - description: Optional gzip index file for compressed inputs - pattern: "*.gzi" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + fa: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.{fa,fasta}": + type: file + description: FASTA file + pattern: "*.{fa}" + ontologies: [] + sizes: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.sizes": + type: file + description: File containing chromosome lengths + pattern: "*.{sizes}" + ontologies: [] + fai: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.fai": + type: file + description: FASTA index file + pattern: "*.{fai}" + ontologies: [] + gzi: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.gzi": + type: file + description: Optional gzip index file for compressed inputs + pattern: "*.gzi" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@drpatelh" - "@ewels" - "@phue" maintainers: - - "@drpatelh" - - "@ewels" + - "@maxulysse" - "@phue" diff --git a/modules/nf-core/samtools/faidx/tests/main.nf.test b/modules/nf-core/samtools/faidx/tests/main.nf.test new file mode 100644 index 000000000..64219b7d9 --- /dev/null +++ b/modules/nf-core/samtools/faidx/tests/main.nf.test @@ -0,0 +1,219 @@ +nextflow_process { + + name "Test Process SAMTOOLS_FAIDX" + script "../main.nf" + process "SAMTOOLS_FAIDX" + + tag "modules" + tag "modules_nfcore" + tag "samtools" + tag "samtools/faidx" + + test("test_samtools_faidx") { + + when { + process { + """ + input[0] = [ [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] + input[1] = [[],[]] + input[2] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_samtools_faidx_bgzip") { + + when { + process { + """ + input[0] = [ [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.gz', checkIfExists: true)] + input[1] = [[],[]] + input[2] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_samtools_faidx_fasta") { + + config "./nextflow.config" + + when { + process { + """ + input[0] = [ [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] + input[1] = [ [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ] + input[2] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_samtools_faidx_stub_fasta") { + + config "./nextflow2.config" + + when { + process { + """ + input[0] = [ [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] + input[1] = [ [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true) ] + input[2] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_samtools_faidx_stub_fai") { + + when { + process { + """ + input[0] = [ [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) ] + input[1] = [[],[]] + input[2] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_samtools_faidx_get_sizes") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + input[1] = [[],[]] + input[2] = true + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_samtools_faidx_get_sizes_bgzip") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.gz', checkIfExists: true) + ]) + input[1] = [[],[]] + input[2] = true + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_samtools_faidx_get_sizes - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + input[1] = [[],[]] + input[2] = true + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("test_samtools_faidx_get_sizes_bgzip - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.gz', checkIfExists: true) + ]) + input[1] = [[],[]] + input[2] = true + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + +} \ No newline at end of file diff --git a/modules/nf-core/samtools/faidx/tests/main.nf.test.snap b/modules/nf-core/samtools/faidx/tests/main.nf.test.snap new file mode 100644 index 000000000..737224148 --- /dev/null +++ b/modules/nf-core/samtools/faidx/tests/main.nf.test.snap @@ -0,0 +1,543 @@ +{ + "test_samtools_faidx": { + "content": [ + { + "0": [ + + ], + "1": [ + + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "genome.fasta.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + ] + ], + "3": [ + + ], + "4": [ + "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + ], + "fa": [ + + ], + "fai": [ + [ + { + "id": "test", + "single_end": false + }, + "genome.fasta.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + ] + ], + "gzi": [ + + ], + "sizes": [ + + ], + "versions": [ + "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-20T17:31:48.258623157" + }, + "test_samtools_faidx_get_sizes_bgzip - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test" + }, + "genome.fasta.gz.sizes:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test" + }, + "genome.fasta.gz.fai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test" + }, + "genome.fasta.gz.gzi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + "versions.yml:md5,e3e4ba35a02020d173be8d1ee04eaebf" + ], + "fa": [ + + ], + "fai": [ + [ + { + "id": "test" + }, + "genome.fasta.gz.fai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "gzi": [ + [ + { + "id": "test" + }, + "genome.fasta.gz.gzi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "sizes": [ + [ + { + "id": "test" + }, + "genome.fasta.gz.sizes:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e3e4ba35a02020d173be8d1ee04eaebf" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-20T17:32:41.122428188" + }, + "test_samtools_faidx_get_sizes": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test" + }, + "genome.fasta.sizes:md5,a57c401f27ae5133823fb09fb21c8a3c" + ] + ], + "2": [ + [ + { + "id": "test" + }, + "genome.fasta.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + ] + ], + "3": [ + + ], + "4": [ + "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + ], + "fa": [ + + ], + "fai": [ + [ + { + "id": "test" + }, + "genome.fasta.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + ] + ], + "gzi": [ + + ], + "sizes": [ + [ + { + "id": "test" + }, + "genome.fasta.sizes:md5,a57c401f27ae5133823fb09fb21c8a3c" + ] + ], + "versions": [ + "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-20T17:34:02.353546697" + }, + "test_samtools_faidx_bgzip": { + "content": [ + { + "0": [ + + ], + "1": [ + + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "genome.fasta.gz.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "genome.fasta.gz.gzi:md5,7dea362b3fac8e00956a4952a3d4f474" + ] + ], + "4": [ + "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + ], + "fa": [ + + ], + "fai": [ + [ + { + "id": "test", + "single_end": false + }, + "genome.fasta.gz.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + ] + ], + "gzi": [ + [ + { + "id": "test", + "single_end": false + }, + "genome.fasta.gz.gzi:md5,7dea362b3fac8e00956a4952a3d4f474" + ] + ], + "sizes": [ + + ], + "versions": [ + "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-20T17:31:55.157487176" + }, + "test_samtools_faidx_fasta": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "extract.fa:md5,6a0774a0ad937ba0bfd2ac7457d90f36" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + + ], + "4": [ + "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + ], + "fa": [ + [ + { + "id": "test", + "single_end": false + }, + "extract.fa:md5,6a0774a0ad937ba0bfd2ac7457d90f36" + ] + ], + "fai": [ + + ], + "gzi": [ + + ], + "sizes": [ + + ], + "versions": [ + "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-20T17:32:02.149455586" + }, + "test_samtools_faidx_get_sizes - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test" + }, + "genome.fasta.sizes:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test" + }, + "genome.fasta.fai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + + ], + "4": [ + "versions.yml:md5,e3e4ba35a02020d173be8d1ee04eaebf" + ], + "fa": [ + + ], + "fai": [ + [ + { + "id": "test" + }, + "genome.fasta.fai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "gzi": [ + + ], + "sizes": [ + [ + { + "id": "test" + }, + "genome.fasta.sizes:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,e3e4ba35a02020d173be8d1ee04eaebf" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-20T17:32:34.29376776" + }, + "test_samtools_faidx_stub_fasta": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "extract.fa:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + + ], + "4": [ + "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + ], + "fa": [ + [ + { + "id": "test", + "single_end": false + }, + "extract.fa:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + ] + ], + "fai": [ + + ], + "gzi": [ + + ], + "sizes": [ + + ], + "versions": [ + "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-20T17:32:09.125065185" + }, + "test_samtools_faidx_stub_fai": { + "content": [ + { + "0": [ + + ], + "1": [ + + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "genome.fasta.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + ] + ], + "3": [ + + ], + "4": [ + "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + ], + "fa": [ + + ], + "fai": [ + [ + { + "id": "test", + "single_end": false + }, + "genome.fasta.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + ] + ], + "gzi": [ + + ], + "sizes": [ + + ], + "versions": [ + "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-20T17:32:16.274287863" + }, + "test_samtools_faidx_get_sizes_bgzip": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test" + }, + "genome.fasta.gz.sizes:md5,a57c401f27ae5133823fb09fb21c8a3c" + ] + ], + "2": [ + [ + { + "id": "test" + }, + "genome.fasta.gz.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + ] + ], + "3": [ + [ + { + "id": "test" + }, + "genome.fasta.gz.gzi:md5,7dea362b3fac8e00956a4952a3d4f474" + ] + ], + "4": [ + "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + ], + "fa": [ + + ], + "fai": [ + [ + { + "id": "test" + }, + "genome.fasta.gz.fai:md5,9da2a56e2853dc8c0b86a9e7229c9fe5" + ] + ], + "gzi": [ + [ + { + "id": "test" + }, + "genome.fasta.gz.gzi:md5,7dea362b3fac8e00956a4952a3d4f474" + ] + ], + "sizes": [ + [ + { + "id": "test" + }, + "genome.fasta.gz.sizes:md5,a57c401f27ae5133823fb09fb21c8a3c" + ] + ], + "versions": [ + "versions.yml:md5,6bbe80a2e14bd61202ca63e12d66027f" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-20T17:32:28.117654855" + } +} \ No newline at end of file diff --git a/modules/nf-core/samtools/faidx/tests/nextflow.config b/modules/nf-core/samtools/faidx/tests/nextflow.config new file mode 100644 index 000000000..f76a3ba09 --- /dev/null +++ b/modules/nf-core/samtools/faidx/tests/nextflow.config @@ -0,0 +1,7 @@ +process { + + withName: SAMTOOLS_FAIDX { + ext.args = 'MT192765.1 -o extract.fa' + } + +} diff --git a/modules/nf-core/samtools/faidx/tests/nextflow2.config b/modules/nf-core/samtools/faidx/tests/nextflow2.config new file mode 100644 index 000000000..33ebbd5df --- /dev/null +++ b/modules/nf-core/samtools/faidx/tests/nextflow2.config @@ -0,0 +1,6 @@ +process { + + withName: SAMTOOLS_FAIDX { + ext.args = '-o extract.fa' + } +} diff --git a/modules/nf-core/samtools/flagstat/environment.yml b/modules/nf-core/samtools/flagstat/environment.yml new file mode 100644 index 000000000..62054fc97 --- /dev/null +++ b/modules/nf-core/samtools/flagstat/environment.yml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::htslib=1.21 + - bioconda::samtools=1.21 diff --git a/modules/nf-core/samtools/flagstat/main.nf b/modules/nf-core/samtools/flagstat/main.nf new file mode 100644 index 000000000..c23f3a5cf --- /dev/null +++ b/modules/nf-core/samtools/flagstat/main.nf @@ -0,0 +1,45 @@ +process SAMTOOLS_FLAGSTAT { + 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(bam), path(bai) + + output: + tuple val(meta), path("*.flagstat"), emit: flagstat + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + 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 + """ +} diff --git a/modules/nf-core/samtools/flagstat/meta.yml b/modules/nf-core/samtools/flagstat/meta.yml new file mode 100644 index 000000000..ebbc15f27 --- /dev/null +++ b/modules/nf-core/samtools/flagstat/meta.yml @@ -0,0 +1,60 @@ +name: samtools_flagstat +description: Counts the number of alignments in a BAM/CRAM/SAM file for each FLAG + type +keywords: + - stats + - mapping + - counts + - bam + - sam + - cram +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 ] + - bam: + 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: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.flagstat": + type: file + description: File containing samtools flagstat output + pattern: "*.{flagstat}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@drpatelh" +maintainers: + - "@drpatelh" diff --git a/modules/nf-core/samtools/flagstat/tests/main.nf.test b/modules/nf-core/samtools/flagstat/tests/main.nf.test new file mode 100644 index 000000000..3b648a37d --- /dev/null +++ b/modules/nf-core/samtools/flagstat/tests/main.nf.test @@ -0,0 +1,56 @@ +nextflow_process { + + name "Test Process SAMTOOLS_FLAGSTAT" + script "../main.nf" + process "SAMTOOLS_FLAGSTAT" + tag "modules" + tag "modules_nfcore" + tag "samtools" + tag "samtools/flagstat" + + test("BAM") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("BAM - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/samtools/flagstat/tests/main.nf.test.snap b/modules/nf-core/samtools/flagstat/tests/main.nf.test.snap new file mode 100644 index 000000000..04c3852b2 --- /dev/null +++ b/modules/nf-core/samtools/flagstat/tests/main.nf.test.snap @@ -0,0 +1,72 @@ +{ + "BAM - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,108a155f2d4a99f50bf3176904208d27" + ], + "flagstat": [ + [ + { + "id": "test", + "single_end": false + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,108a155f2d4a99f50bf3176904208d27" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:02:58.866491759" + }, + "BAM": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.flagstat:md5,4f7ffd1e6a5e85524d443209ac97d783" + ] + ], + "1": [ + "versions.yml:md5,108a155f2d4a99f50bf3176904208d27" + ], + "flagstat": [ + [ + { + "id": "test", + "single_end": false + }, + "test.flagstat:md5,4f7ffd1e6a5e85524d443209ac97d783" + ] + ], + "versions": [ + "versions.yml:md5,108a155f2d4a99f50bf3176904208d27" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:02:47.383332837" + } +} \ No newline at end of file diff --git a/modules/nf-core/samtools/idxstats/environment.yml b/modules/nf-core/samtools/idxstats/environment.yml new file mode 100644 index 000000000..62054fc97 --- /dev/null +++ b/modules/nf-core/samtools/idxstats/environment.yml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::htslib=1.21 + - bioconda::samtools=1.21 diff --git a/modules/nf-core/samtools/idxstats/main.nf b/modules/nf-core/samtools/idxstats/main.nf new file mode 100644 index 000000000..3d5bf4bdc --- /dev/null +++ b/modules/nf-core/samtools/idxstats/main.nf @@ -0,0 +1,48 @@ +process SAMTOOLS_IDXSTATS { + 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(bam), path(bai) + + output: + tuple val(meta), path("*.idxstats"), emit: idxstats + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + 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: + def prefix = task.ext.prefix ?: "${meta.id}" + + """ + 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 new file mode 100644 index 000000000..96d427466 --- /dev/null +++ b/modules/nf-core/samtools/idxstats/meta.yml @@ -0,0 +1,60 @@ +name: samtools_idxstats +description: Reports alignment summary statistics for a BAM/CRAM/SAM file +keywords: + - stats + - mapping + - counts + - chromosome + - bam + - sam + - cram +tools: + - samtools: + description: | + SAMtools is a set of utilities for interacting with and post-processing + short DNA sequence read alignments in the SAM, BAM and CRAM formats, written by Heng Li. + These files are generated as output by short read aligners like BWA. + homepage: http://www.htslib.org/ + documentation: 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 ] + - bam: + 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: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.idxstats": + type: file + description: File containing samtools idxstats output + pattern: "*.{idxstats}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@drpatelh" +maintainers: + - "@drpatelh" diff --git a/modules/nf-core/samtools/idxstats/tests/main.nf.test b/modules/nf-core/samtools/idxstats/tests/main.nf.test new file mode 100644 index 000000000..5fd1fc78e --- /dev/null +++ b/modules/nf-core/samtools/idxstats/tests/main.nf.test @@ -0,0 +1,53 @@ +nextflow_process { + + name "Test Process SAMTOOLS_IDXSTATS" + script "../main.nf" + process "SAMTOOLS_IDXSTATS" + tag "modules" + tag "modules_nfcore" + tag "samtools" + tag "samtools/idxstats" + + test("bam") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("bam - stub") { + options "-stub" + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).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 new file mode 100644 index 000000000..2cc89a3b8 --- /dev/null +++ b/modules/nf-core/samtools/idxstats/tests/main.nf.test.snap @@ -0,0 +1,72 @@ +{ + "bam - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,c8d7394830c3c1e5be150589571534fb" + ], + "idxstats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,c8d7394830c3c1e5be150589571534fb" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:11:56.466856235" + }, + "bam": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,df60a8c8d6621100d05178c93fb053a2" + ] + ], + "1": [ + "versions.yml:md5,c8d7394830c3c1e5be150589571534fb" + ], + "idxstats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,df60a8c8d6621100d05178c93fb053a2" + ] + ], + "versions": [ + "versions.yml:md5,c8d7394830c3c1e5be150589571534fb" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:11:46.311550359" + } +} \ No newline at end of file diff --git a/modules/nf-core/samtools/index/environment.yml b/modules/nf-core/samtools/index/environment.yml index 3c6f95b25..62054fc97 100644 --- a/modules/nf-core/samtools/index/environment.yml +++ b/modules/nf-core/samtools/index/environment.yml @@ -1,7 +1,8 @@ -name: samtools_index +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults dependencies: - - bioconda::samtools=1.17 + - bioconda::htslib=1.21 + - bioconda::samtools=1.21 diff --git a/modules/nf-core/samtools/index/main.nf b/modules/nf-core/samtools/index/main.nf index 256bd7c46..7019a72e4 100644 --- a/modules/nf-core/samtools/index/main.nf +++ b/modules/nf-core/samtools/index/main.nf @@ -4,8 +4,8 @@ process SAMTOOLS_INDEX { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.17--h00cdaf9_0' : - 'biocontainers/samtools:1.17--h00cdaf9_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : + 'biocontainers/samtools:1.21--h50ea8bc_0' }" input: tuple val(meta), path(input) @@ -24,7 +24,7 @@ process SAMTOOLS_INDEX { """ samtools \\ index \\ - -@ ${task.cpus-1} \\ + -@ ${task.cpus} \\ $args \\ $input @@ -35,10 +35,11 @@ process SAMTOOLS_INDEX { """ stub: + def args = task.ext.args ?: '' + def extension = file(input).getExtension() == 'cram' ? + "crai" : args.contains("-c") ? "csi" : "bai" """ - touch ${input}.bai - touch ${input}.crai - touch ${input}.csi + touch ${input}.${extension} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/samtools/index/meta.yml b/modules/nf-core/samtools/index/meta.yml index 01a4ee03e..1bed6bca6 100644 --- a/modules/nf-core/samtools/index/meta.yml +++ b/modules/nf-core/samtools/index/meta.yml @@ -15,38 +15,58 @@ tools: 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 ] - - bam: - type: file - description: BAM/CRAM/SAM file - pattern: "*.{bam,cram,sam}" + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - input: + type: file + description: input file + ontologies: [] output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bai: - type: file - description: BAM/CRAM/SAM index file - pattern: "*.{bai,crai,sai}" - - crai: - type: file - description: BAM/CRAM/SAM index file - pattern: "*.{bai,crai,sai}" - - csi: - type: file - description: CSI index file - pattern: "*.{csi}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + bai: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.bai": + type: file + description: BAM/CRAM/SAM index file + pattern: "*.{bai,crai,sai}" + ontologies: [] + csi: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.csi": + type: file + description: CSI index file + pattern: "*.{csi}" + ontologies: [] + crai: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.crai": + type: file + description: BAM/CRAM/SAM index file + pattern: "*.{bai,crai,sai}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@drpatelh" - "@ewels" diff --git a/modules/nf-core/samtools/index/tests/main.nf.test b/modules/nf-core/samtools/index/tests/main.nf.test index c76a9169f..ca34fb5cd 100644 --- a/modules/nf-core/samtools/index/tests/main.nf.test +++ b/modules/nf-core/samtools/index/tests/main.nf.test @@ -8,18 +8,34 @@ nextflow_process { tag "samtools" tag "samtools/index" - test("sarscov2 [BAI]") { - + test("bai") { 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/bam/test.paired_end.sorted.bam', checkIfExists: true) + ]) + """ } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("crai") { + when { process { """ - input[0] = [ - [ id:'test' ], // meta map - file(params.test_data['sarscov2']['illumina']['test_paired_end_sorted_bam'], checkIfExists: true) - ] + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram', checkIfExists: true) + ]) """ } } @@ -27,24 +43,45 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out.bai).match("bai") }, - { assert path(process.out.versions.get(0)).getText().contains("samtools") } + { assert snapshot(process.out).match() } ) } } - test("homo_sapiens [CRAI]") { + test("csi") { + config "./csi.nextflow.config" 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/bam/test.paired_end.sorted.bam', checkIfExists: true) + ]) + """ } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + file(process.out.csi[0][1]).name, + process.out.versions + ).match() } + ) + } + } + + test("bai - stub") { + options "-stub" + when { process { """ - input[0] = [ - [ id:'test' ], // meta map - file(params.test_data['homo_sapiens']['illumina']['test_paired_end_recalibrated_sorted_cram'], checkIfExists: true) - ] + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) + ]) """ } } @@ -52,26 +89,43 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out.crai).match("crai") }, - { assert path(process.out.versions.get(0)).getText().contains("samtools") } + { assert snapshot(process.out).match() } ) } } - test("homo_sapiens [CSI]") { + test("crai - stub") { + options "-stub" + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + test("csi - stub") { + options "-stub" config "./csi.nextflow.config" when { - params { - outdir = "$outputDir" - } process { """ - input[0] = [ - [ id:'test' ], // meta map - file(params.test_data['sarscov2']['illumina']['test_paired_end_sorted_bam'], checkIfExists: true) - ] + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true) + ]) """ } } @@ -79,8 +133,7 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert path(process.out.csi.get(0).get(1)).exists() }, - { assert path(process.out.versions.get(0)).getText().contains("samtools") } + { assert snapshot(process.out).match() } ) } } diff --git a/modules/nf-core/samtools/index/tests/main.nf.test.snap b/modules/nf-core/samtools/index/tests/main.nf.test.snap index b3baee7fb..72d65e81a 100644 --- a/modules/nf-core/samtools/index/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/index/tests/main.nf.test.snap @@ -1,28 +1,250 @@ { - "crai": { + "csi - stub": { "content": [ - [ - [ - { - "id": "test" - }, - "test.paired_end.recalibrated.sorted.cram.crai:md5,14bc3bd5c89cacc8f4541f9062429029" + { + "0": [ + + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.sorted.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,5e09a6fdf76de396728f877193d72315" + ], + "bai": [ + + ], + "crai": [ + + ], + "csi": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.sorted.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,5e09a6fdf76de396728f877193d72315" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:21:25.261127166" + }, + "crai - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.recalibrated.sorted.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,5e09a6fdf76de396728f877193d72315" + ], + "bai": [ + + ], + "crai": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.recalibrated.sorted.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "csi": [ + + ], + "versions": [ + "versions.yml:md5,5e09a6fdf76de396728f877193d72315" ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:21:12.653194876" + }, + "bai - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,5e09a6fdf76de396728f877193d72315" + ], + "bai": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "crai": [ + + ], + "csi": [ + + ], + "versions": [ + "versions.yml:md5,5e09a6fdf76de396728f877193d72315" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:21:01.854932651" + }, + "csi": { + "content": [ + "test.paired_end.sorted.bam.csi", + [ + "versions.yml:md5,5e09a6fdf76de396728f877193d72315" ] ], - "timestamp": "2023-11-15T15:17:37.30801" + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:20:51.485364222" + }, + "crai": { + "content": [ + { + "0": [ + + ], + "1": [ + + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.recalibrated.sorted.cram.crai:md5,14bc3bd5c89cacc8f4541f9062429029" + ] + ], + "3": [ + "versions.yml:md5,5e09a6fdf76de396728f877193d72315" + ], + "bai": [ + + ], + "crai": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.recalibrated.sorted.cram.crai:md5,14bc3bd5c89cacc8f4541f9062429029" + ] + ], + "csi": [ + + ], + "versions": [ + "versions.yml:md5,5e09a6fdf76de396728f877193d72315" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:20:40.518873972" }, "bai": { "content": [ - [ - [ - { - "id": "test" - }, - "test.paired_end.sorted.bam.bai:md5,704c10dd1326482448ca3073fdebc2f4" + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.sorted.bam.bai:md5,704c10dd1326482448ca3073fdebc2f4" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,5e09a6fdf76de396728f877193d72315" + ], + "bai": [ + [ + { + "id": "test", + "single_end": false + }, + "test.paired_end.sorted.bam.bai:md5,704c10dd1326482448ca3073fdebc2f4" + ] + ], + "crai": [ + + ], + "csi": [ + + ], + "versions": [ + "versions.yml:md5,5e09a6fdf76de396728f877193d72315" ] - ] + } ], - "timestamp": "2023-11-15T15:17:30.869234" + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:20:21.184050361" } } \ No newline at end of file diff --git a/modules/nf-core/samtools/index/tests/tags.yml b/modules/nf-core/samtools/index/tests/tags.yml deleted file mode 100644 index e0f58a7a3..000000000 --- a/modules/nf-core/samtools/index/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -samtools/index: - - modules/nf-core/samtools/index/** diff --git a/modules/nf-core/samtools/sort/environment.yml b/modules/nf-core/samtools/sort/environment.yml index 508659f02..62054fc97 100644 --- a/modules/nf-core/samtools/sort/environment.yml +++ b/modules/nf-core/samtools/sort/environment.yml @@ -1,7 +1,8 @@ -name: samtools_sort +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults dependencies: - - bioconda::samtools=1.17 + - bioconda::htslib=1.21 + - bioconda::samtools=1.21 diff --git a/modules/nf-core/samtools/sort/main.nf b/modules/nf-core/samtools/sort/main.nf index 60f0c634d..6c436c043 100644 --- a/modules/nf-core/samtools/sort/main.nf +++ b/modules/nf-core/samtools/sort/main.nf @@ -4,31 +4,54 @@ process SAMTOOLS_SORT { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/samtools:1.17--h00cdaf9_0' : - 'biocontainers/samtools:1.17--h00cdaf9_0' }" + 'https://depot.galaxyproject.org/singularity/samtools:1.21--h50ea8bc_0' : + 'biocontainers/samtools:1.21--h50ea8bc_0' }" input: - tuple val(meta), path(bam) + tuple val(meta) , path(bam) + tuple val(meta2), path(fasta) + val index_format output: - tuple val(meta), path("*.bam"), emit: bam - 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 + 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}" + prefix = task.ext.prefix ?: "${meta.id}" + extension = args.contains("--output-fmt sam") ? "sam" : + args.contains("--output-fmt cram") ? "cram" : + "bam" + reference = fasta ? "--reference ${fasta}" : "" + 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!" + """ + samtools cat \\ + ${bam} \\ + | \\ samtools sort \\ $args \\ - -@ $task.cpus \\ - -o ${prefix}.bam \\ - -T $prefix \\ - $bam + -T ${prefix} \\ + --threads $task.cpus \\ + ${reference} \\ + -o ${output_file} \\ + - cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -37,9 +60,24 @@ process SAMTOOLS_SORT { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + 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}" : "" + 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}.bam + touch ${prefix}.${extension} + ${index} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/samtools/sort/meta.yml b/modules/nf-core/samtools/sort/meta.yml index 2200de72f..4c4010bbb 100644 --- a/modules/nf-core/samtools/sort/meta.yml +++ b/modules/nf-core/samtools/sort/meta.yml @@ -15,37 +15,113 @@ tools: 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 ] - - bam: - type: file - description: BAM/CRAM/SAM file - pattern: "*.{bam,cram,sam}" + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: BAM/CRAM/SAM file(s) + pattern: "*.{bam,cram,sam}" + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fasta: + type: file + 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: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: Sorted BAM/CRAM/SAM file - pattern: "*.{bam,cram,sam}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - csi: - type: file - description: BAM index file (optional) - pattern: "*.csi" + bam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "${prefix}.bam": + type: file + description: Sorted BAM file + pattern: "*.{bam}" + ontologies: [] + cram: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "${prefix}.cram": + type: file + description: Sorted CRAM file + pattern: "*.{cram}" + ontologies: [] + sam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "${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" + ontologies: [] + csi: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "${prefix}.${extension}.csi": + type: file + description: BAM index file (optional) + pattern: "*.csi" + ontologies: [] + bai: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "${prefix}.${extension}.bai": + type: file + description: BAM index file (optional) + pattern: "*.bai" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@drpatelh" - "@ewels" + - "@matthdsm" maintainers: - "@drpatelh" - "@ewels" + - "@matthdsm" diff --git a/modules/nf-core/samtools/sort/tests/main.nf.test b/modules/nf-core/samtools/sort/tests/main.nf.test index 1f72f3b96..fa2778722 100644 --- a/modules/nf-core/samtools/sort/tests/main.nf.test +++ b/modules/nf-core/samtools/sort/tests/main.nf.test @@ -8,22 +8,121 @@ nextflow_process { tag "samtools" tag "samtools/sort" - test("test_samtools_sort") { + test("bam_no_index") { config "./nextflow.config" 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/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] = '' + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot( + process.out.bam, + process.out.bai, + process.out.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.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.versions + ).match()} + ) + } + } + + test("multiple bam") { + + config "./nextflow.config" + + when { process { """ - input[0] = [ - [ id:'test', single_end:false ], + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map [ - file(params.test_data['sarscov2']['illumina']['test_paired_end_bam'], checkIfExists: true) + 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] = '' """ } } @@ -31,29 +130,134 @@ nextflow_process { then { assertAll ( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + process.out.bam, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.versions + ).match()} ) } - } - test("test_samtools_sort_stub") { + test("multiple bam bai index") { config "./nextflow.config" - options "-stub-run" when { - params { - outdir = "$outputDir" + 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.versions + ).match()} + ) + } + } + + test("multiple bam csi index") { + + config "./nextflow.config" + + when { process { """ - input[0] = [ - [ id:'test', single_end:false ], + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map [ - file(params.test_data['sarscov2']['illumina']['test_paired_end_bam'], checkIfExists: true) + 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' + """ + } + } + + 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.versions + ).match()} + ) + } + } + + test("cram") { + + config "./nextflow_cram.config" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', 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] = '' + """ + } + } + + then { + assertAll ( + { assert process.success }, + { 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 + ).match()} + ) + } + } + + test("bam - stub") { + + options "-stub" + 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] = '' """ } } @@ -64,7 +268,65 @@ nextflow_process { { assert snapshot(process.out).match() } ) } + } + + test("multiple bam - stub") { + + 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] = '' + """ + } + } + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } } + test("cram - stub") { + + options "-stub" + config "./nextflow_cram.config" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', 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] = '' + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).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 a43566dab..84e728024 100644 --- a/modules/nf-core/samtools/sort/tests/main.nf.test.snap +++ b/modules/nf-core/samtools/sort/tests/main.nf.test.snap @@ -1,5 +1,249 @@ { - "test_samtools_sort": { + "cram": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.cram" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.cram.crai" + ] + ], + [ + "versions.yml:md5,2659b187d681241451539d4c53500b9f" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-13T16:39:40.803476526" + }, + "bam - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + + ], + "4": [ + + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,2659b187d681241451539d4c53500b9f" + ], + "bai": [ + + ], + "bam": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "crai": [ + + ], + "cram": [ + + ], + "csi": [ + + ], + "sam": [ + + ], + "versions": [ + "versions.yml:md5,2659b187d681241451539d4c53500b9f" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-13T16:39:46.797296642" + }, + "bam_csi_index": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,d9645c9b6d7f991426d47ad80c275ef7" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.csi:md5,124e6600a0a811227c43fd6864c72902" + ] + ], + [ + "versions.yml:md5,2659b187d681241451539d4c53500b9f" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-13T16:39:13.394881233" + }, + "multiple bam bai index": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,0669e48038989db924a9f2957e26317c" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.bai" + ] + ], + [ + "versions.yml:md5,2659b187d681241451539d4c53500b9f" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-13T16:39:28.192036852" + }, + "cram - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.cram:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + + ], + "3": [ + + ], + "4": [ + + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,2659b187d681241451539d4c53500b9f" + ], + "bai": [ + + ], + "bam": [ + + ], + "crai": [ + + ], + "cram": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.cram:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "csi": [ + + ], + "sam": [ + + ], + "versions": [ + "versions.yml:md5,2659b187d681241451539d4c53500b9f" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-13T16:39:58.847704746" + }, + "multiple bam": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,c6ab045cc495485d3819bd44c5d69b92" + ] + ], + [ + + ], + [ + "versions.yml:md5,2659b187d681241451539d4c53500b9f" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-13T14:00:50.550947084" + }, + "multiple bam - stub": { "content": [ { "0": [ @@ -8,14 +252,29 @@ "id": "test", "single_end": false }, - "test.sorted.bam:md5,a29570e7607d217c2fa4d75829e09cd7" + "test.sorted.bam:md5,c6ab045cc495485d3819bd44c5d69b92" ] ], "1": [ ], "2": [ - "versions.yml:md5,46f7a36082fa1f68285fe30d689244e8" + + ], + "3": [ + + ], + "4": [ + + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,2659b187d681241451539d4c53500b9f" + ], + "bai": [ + ], "bam": [ [ @@ -23,17 +282,144 @@ "id": "test", "single_end": false }, - "test.sorted.bam:md5,a29570e7607d217c2fa4d75829e09cd7" + "test.sorted.bam:md5,c6ab045cc495485d3819bd44c5d69b92" ] + ], + "crai": [ + + ], + "cram": [ + ], "csi": [ + ], + "sam": [ + ], "versions": [ - "versions.yml:md5,46f7a36082fa1f68285fe30d689244e8" + "versions.yml:md5,2659b187d681241451539d4c53500b9f" ] } ], - "timestamp": "2023-10-17T17:21:46.5427968" + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-13T14:02:05.837266709" + }, + "bam_no_index": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,7fa751088f8d86c2685fb50a8b90f53f" + ] + ], + [ + + ], + [ + "versions.yml:md5,2659b187d681241451539d4c53500b9f" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-13T14:00:20.988801663" + }, + "multiple bam csi index": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,3fe979e8bd453d33224706d1478df7a1" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.csi" + ] + ], + [ + "versions.yml:md5,2659b187d681241451539d4c53500b9f" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-13T16:39:34.591655792" + }, + "bam": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,34aa85e86abefe637f7a4a9887f016fc" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.csi" + ] + ], + [ + "versions.yml:md5,2659b187d681241451539d4c53500b9f" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.09.0" + }, + "timestamp": "2024-10-08T11:59:46.372244" + }, + "bam_bai_index": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,31e1c0224336156ea9ca81dcfe23356d" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.bai:md5,0575b098cbea8c3af1f58d2a83efa07f" + ] + ], + [ + "versions.yml:md5,2659b187d681241451539d4c53500b9f" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-13T16:39:06.968372189" } } \ 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 d0f350868..723f62b21 100644 --- a/modules/nf-core/samtools/sort/tests/nextflow.config +++ b/modules/nf-core/samtools/sort/tests/nextflow.config @@ -1,7 +1,7 @@ process { withName: SAMTOOLS_SORT { - ext.prefix = { "${meta.id}.sorted" } + ext.prefix = { "${meta.id}.sorted" } } } diff --git a/modules/nf-core/samtools/sort/tests/nextflow_cram.config b/modules/nf-core/samtools/sort/tests/nextflow_cram.config new file mode 100644 index 000000000..3a8c0188b --- /dev/null +++ b/modules/nf-core/samtools/sort/tests/nextflow_cram.config @@ -0,0 +1,8 @@ +process { + + withName: SAMTOOLS_SORT { + ext.prefix = { "${meta.id}.sorted" } + ext.args = "--write-index --output-fmt cram" + } + +} 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 cd63ea208..000000000 --- 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 new file mode 100644 index 000000000..62054fc97 --- /dev/null +++ b/modules/nf-core/samtools/stats/environment.yml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::htslib=1.21 + - bioconda::samtools=1.21 diff --git a/modules/nf-core/samtools/stats/main.nf b/modules/nf-core/samtools/stats/main.nf new file mode 100644 index 000000000..4443948b7 --- /dev/null +++ b/modules/nf-core/samtools/stats/main.nf @@ -0,0 +1,48 @@ +process SAMTOOLS_STATS { + 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(input), path(input_index) + tuple val(meta2), path(fasta) + + output: + tuple val(meta), path("*.stats"), emit: stats + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def prefix = task.ext.prefix ?: "${meta.id}" + def reference = fasta ? "--reference ${fasta}" : "" + """ + samtools \\ + stats \\ + --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 new file mode 100644 index 000000000..6dc51885d --- /dev/null +++ b/modules/nf-core/samtools/stats/meta.yml @@ -0,0 +1,72 @@ +name: samtools_stats +description: Produces comprehensive statistics from SAM/BAM/CRAM file +keywords: + - statistics + - counts + - bam + - sam + - cram +tools: + - samtools: + description: | + SAMtools is a set of utilities for interacting with and post-processing + short DNA sequence read alignments in the SAM, BAM and CRAM formats, written by Heng Li. + These files are generated as output by short read aligners like BWA. + homepage: http://www.htslib.org/ + documentation: 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: + 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: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fasta: + type: file + description: Reference file the CRAM was created with (optional) + pattern: "*.{fasta,fa}" + ontologies: [] +output: + stats: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.stats": + type: file + description: File containing samtools stats output + pattern: "*.{stats}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@drpatelh" + - "@FriederikeHanssen" + - "@ramprasadn" +maintainers: + - "@drpatelh" + - "@FriederikeHanssen" + - "@ramprasadn" diff --git a/modules/nf-core/samtools/stats/tests/main.nf.test b/modules/nf-core/samtools/stats/tests/main.nf.test new file mode 100644 index 000000000..5bc893095 --- /dev/null +++ b/modules/nf-core/samtools/stats/tests/main.nf.test @@ -0,0 +1,113 @@ +nextflow_process { + + name "Test Process SAMTOOLS_STATS" + script "../main.nf" + process "SAMTOOLS_STATS" + + tag "modules" + tag "modules_nfcore" + tag "samtools" + tag "samtools/stats" + + test("bam") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ]) + input[1] = [[],[]] + """ + } + } + + then { + assertAll( + {assert process.success}, + {assert snapshot(process.out).match()} + ) + } + } + + test("cram") { + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram.crai', checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'genome' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + {assert process.success}, + {assert snapshot(process.out).match()} + ) + } + } + + test("bam - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ]) + input[1] = [[],[]] + """ + } + } + + then { + assertAll( + {assert process.success}, + {assert snapshot(process.out).match()} + ) + } + } + + test("cram - stub") { + + options "-stub" + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram.crai', checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'genome' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + {assert process.success}, + {assert snapshot(process.out).match()} + ) + } + } +} diff --git a/modules/nf-core/samtools/stats/tests/main.nf.test.snap b/modules/nf-core/samtools/stats/tests/main.nf.test.snap new file mode 100644 index 000000000..df507be7a --- /dev/null +++ b/modules/nf-core/samtools/stats/tests/main.nf.test.snap @@ -0,0 +1,142 @@ +{ + "cram": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,a27fe55e49a341f92379bb20a65c6a06" + ] + ], + "1": [ + "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,a27fe55e49a341f92379bb20a65c6a06" + ] + ], + "versions": [ + "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T09:29:16.767396182" + }, + "bam - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T09:29:29.721580274" + }, + "cram - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T09:29:53.567964304" + }, + "bam": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d53a2584376d78942839e9933a34d11b" + ] + ], + "1": [ + "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d53a2584376d78942839e9933a34d11b" + ] + ], + "versions": [ + "versions.yml:md5,15b91d8c0e0440332e0fe4df80957043" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T09:28:50.73610604" + } +} \ No newline at end of file diff --git a/modules/nf-core/samtools/view/environment.yml b/modules/nf-core/samtools/view/environment.yml deleted file mode 100644 index 141e7bd82..000000000 --- a/modules/nf-core/samtools/view/environment.yml +++ /dev/null @@ -1,7 +0,0 @@ -name: samtools_view -channels: - - conda-forge - - bioconda - - defaults -dependencies: - - bioconda::samtools=1.17 diff --git a/modules/nf-core/samtools/view/main.nf b/modules/nf-core/samtools/view/main.nf deleted file mode 100644 index ddf3f88ae..000000000 --- a/modules/nf-core/samtools/view/main.nf +++ /dev/null @@ -1,66 +0,0 @@ -process SAMTOOLS_VIEW { - 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.17--h00cdaf9_0' : - 'biocontainers/samtools:1.17--h00cdaf9_0' }" - - input: - tuple val(meta), path(input), path(index) - tuple val(meta2), path(fasta) - path qname - - output: - tuple val(meta), path("*.bam"), emit: bam, optional: true - tuple val(meta), path("*.cram"), emit: cram, optional: true - tuple val(meta), path("*.sam"), emit: sam, optional: true - tuple val(meta), path("*.bai"), emit: bai, optional: true - tuple val(meta), path("*.csi"), emit: csi, optional: true - tuple val(meta), path("*.crai"), emit: crai, optional: true - path "versions.yml", emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def args = task.ext.args ?: '' - def args2 = task.ext.args2 ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def reference = fasta ? "--reference ${fasta}" : "" - def readnames = qname ? "--qname-file ${qname}": "" - def file_type = args.contains("--output-fmt sam") ? "sam" : - args.contains("--output-fmt bam") ? "bam" : - args.contains("--output-fmt cram") ? "cram" : - input.getExtension() - if ("$input" == "${prefix}.${file_type}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!" - """ - samtools \\ - view \\ - --threads ${task.cpus-1} \\ - ${reference} \\ - ${readnames} \\ - $args \\ - -o ${prefix}.${file_type} \\ - $input \\ - $args2 - - 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 - touch ${prefix}.cram - - 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/view/meta.yml b/modules/nf-core/samtools/view/meta.yml deleted file mode 100644 index 3dadafae7..000000000 --- a/modules/nf-core/samtools/view/meta.yml +++ /dev/null @@ -1,89 +0,0 @@ -name: samtools_view -description: filter/convert SAM/BAM/CRAM file -keywords: - - view - - 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"] -input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - input: - type: file - description: BAM/CRAM/SAM file - pattern: "*.{bam,cram,sam}" - - index: - type: file - description: BAM.BAI/BAM.CSI/CRAM.CRAI file (optional) - pattern: "*.{.bai,.csi,.crai}" - - meta2: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'test' ] - - fasta: - type: file - description: Reference file the CRAM was created with (optional) - pattern: "*.{fasta,fa}" - - qname: - type: file - description: Optional file with read names to output only select alignments - pattern: "*.{txt,list}" -output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: optional filtered/converted BAM file - pattern: "*.{bam}" - - cram: - type: file - description: optional filtered/converted CRAM file - pattern: "*.{cram}" - - sam: - type: file - description: optional filtered/converted SAM file - pattern: "*.{sam}" - # bai, csi, and crai are created with `--write-index` - - bai: - type: file - description: optional BAM file index - pattern: "*.{bai}" - - csi: - type: file - description: optional tabix BAM file index - pattern: "*.{csi}" - - crai: - type: file - description: optional CRAM file index - pattern: "*.{crai}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" -authors: - - "@drpatelh" - - "@joseespinosa" - - "@FriederikeHanssen" - - "@priyanka-surana" -maintainers: - - "@drpatelh" - - "@joseespinosa" - - "@FriederikeHanssen" - - "@priyanka-surana" diff --git a/modules/nf-core/star/align/environment.yml b/modules/nf-core/star/align/environment.yml index 6db209884..91e37ae12 100644 --- a/modules/nf-core/star/align/environment.yml +++ b/modules/nf-core/star/align/environment.yml @@ -1,9 +1,11 @@ -name: star_align +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults + dependencies: - - bioconda::star=2.7.10a - - bioconda::samtools=1.16.1 + - bioconda::htslib=1.21 + - bioconda::samtools=1.21 + - bioconda::star=2.7.11b - conda-forge::gawk=5.1.0 diff --git a/modules/nf-core/star/align/main.nf b/modules/nf-core/star/align/main.nf index cc4f5af52..22a52184d 100644 --- a/modules/nf-core/star/align/main.nf +++ b/modules/nf-core/star/align/main.nf @@ -4,8 +4,8 @@ process STAR_ALIGN { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/mulled-v2-1fa26d1ce03c295fe2fdcf85831a92fbcbd7e8c2:019f262d90511939dce2dca4b7c868fc108f73db-0' : - 'biocontainers/mulled-v2-1fa26d1ce03c295fe2fdcf85831a92fbcbd7e8c2:019f262d90511939dce2dca4b7c868fc108f73db-0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/26/268b4c9c6cbf8fa6606c9b7fd4fafce18bf2c931d1a809a0ce51b105ec06c89d/data' : + 'community.wave.seqera.io/library/htslib_samtools_star_gawk:ae438e9a604351a4' }" input: tuple val(meta), path(reads, stageAs: "input*/*") @@ -21,33 +21,35 @@ process STAR_ALIGN { tuple val(meta), path('*Log.progress.out'), emit: log_progress path "versions.yml" , emit: versions - tuple val(meta), path('*d.out.bam') , optional:true, emit: bam - tuple val(meta), path('*sortedByCoord.out.bam') , optional:true, emit: bam_sorted - tuple val(meta), path('*toTranscriptome.out.bam'), optional:true, emit: bam_transcript - tuple val(meta), path('*Aligned.unsort.out.bam') , optional:true, emit: bam_unsorted - tuple val(meta), path('*fastq.gz') , optional:true, emit: fastq - tuple val(meta), path('*.tab') , optional:true, emit: tab - tuple val(meta), path('*.SJ.out.tab') , optional:true, emit: spl_junc_tab - tuple val(meta), path('*.ReadsPerGene.out.tab') , optional:true, emit: read_per_gene_tab - tuple val(meta), path('*.out.junction') , optional:true, emit: junction - tuple val(meta), path('*.out.sam') , optional:true, emit: sam - tuple val(meta), path('*.wig') , optional:true, emit: wig - tuple val(meta), path('*.bg') , optional:true, emit: bedgraph + tuple val(meta), path('*d.out.bam') , optional:true, emit: bam + tuple val(meta), path("${prefix}.sortedByCoord.out.bam") , optional:true, emit: bam_sorted + tuple val(meta), path("${prefix}.Aligned.sortedByCoord.out.bam") , optional:true, emit: bam_sorted_aligned + tuple val(meta), path('*toTranscriptome.out.bam') , optional:true, emit: bam_transcript + tuple val(meta), path('*Aligned.unsort.out.bam') , optional:true, emit: bam_unsorted + tuple val(meta), path('*fastq.gz') , optional:true, emit: fastq + tuple val(meta), path('*.tab') , optional:true, emit: tab + tuple val(meta), path('*.SJ.out.tab') , optional:true, emit: spl_junc_tab + tuple val(meta), path('*.ReadsPerGene.out.tab') , optional:true, emit: read_per_gene_tab + tuple val(meta), path('*.out.junction') , optional:true, emit: junction + tuple val(meta), path('*.out.sam') , optional:true, emit: sam + tuple val(meta), path('*.wig') , optional:true, emit: wig + tuple val(meta), path('*.bg') , optional:true, emit: bedgraph when: task.ext.when == null || task.ext.when script: def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def reads1 = [], reads2 = [] + 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 = star_ignore_sjdbgtf ? '' : "--sjdbGTFfile $gtf" - def seq_platform = seq_platform ? "'PL:$seq_platform'" : "" - def seq_center = seq_center ? "'CN:$seq_center'" : "" - def attrRG = args.contains("--outSAMattrRGline") ? "" : "--outSAMattrRGline 'ID:$prefix' $seq_center 'SM:$prefix' $seq_platform" + 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' - def mv_unsorted_bam = (args.contains('--outSAMtype BAM Unsorted SortedByCoordinate')) ? "mv ${prefix}.Aligned.out.bam ${prefix}.Aligned.unsort.out.bam" : '' + mv_unsorted_bam = (args.contains('--outSAMtype BAM Unsorted SortedByCoordinate')) ? "mv ${prefix}.Aligned.out.bam ${prefix}.Aligned.unsort.out.bam" : '' """ STAR \\ --genomeDir $index \\ @@ -79,8 +81,10 @@ process STAR_ALIGN { """ stub: - def prefix = task.ext.prefix ?: "${meta.id}" + prefix = task.ext.prefix ?: "${meta.id}" """ + echo "" | gzip > ${prefix}.unmapped_1.fastq.gz + echo "" | gzip > ${prefix}.unmapped_2.fastq.gz touch ${prefix}Xd.out.bam touch ${prefix}.Log.final.out touch ${prefix}.Log.out @@ -89,8 +93,6 @@ process STAR_ALIGN { touch ${prefix}.toTranscriptome.out.bam touch ${prefix}.Aligned.unsort.out.bam touch ${prefix}.Aligned.sortedByCoord.out.bam - touch ${prefix}.unmapped_1.fastq.gz - touch ${prefix}.unmapped_2.fastq.gz touch ${prefix}.tab touch ${prefix}.SJ.out.tab touch ${prefix}.ReadsPerGene.out.tab diff --git a/modules/nf-core/star/align/meta.yml b/modules/nf-core/star/align/meta.yml index e80dbb7dd..1ee469052 100644 --- a/modules/nf-core/star/align/meta.yml +++ b/modules/nf-core/star/align/meta.yml @@ -14,35 +14,38 @@ tools: manual: https://github.com/alexdobin/STAR/blob/master/doc/STARmanual.pdf doi: 10.1093/bioinformatics/bts635 licence: ["MIT"] + identifier: biotools:star 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. - - meta2: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'test' ] - - index: - type: directory - description: STAR genome index - pattern: "star" - - meta3: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'test' ] - - gtf: - type: file - description: Annotation GTF file - pattern: "*.{gtf}" + - - 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: [] + - - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'test' ] + - index: + type: directory + description: STAR genome index + pattern: "star" + - - meta3: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'test' ] + - gtf: + type: file + description: Annotation GTF file + pattern: "*.{gtf}" + ontologies: [] - star_ignore_sjdbgtf: type: boolean description: Ignore annotation GTF file @@ -53,58 +56,193 @@ input: type: string description: Sequencing center output: - - bam: - type: file - description: Output BAM file containing read alignments - pattern: "*.{bam}" - - log_final: - type: file - description: STAR final log file - pattern: "*Log.final.out" - - log_out: - type: file - description: STAR lot out file - pattern: "*Log.out" - - log_progress: - type: file - description: STAR log progress file - pattern: "*Log.progress.out" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - bam_sorted: - type: file - description: Sorted BAM file of read alignments (optional) - pattern: "*sortedByCoord.out.bam" - - bam_transcript: - type: file - description: Output BAM file of transcriptome alignment (optional) - pattern: "*toTranscriptome.out.bam" - - bam_unsorted: - type: file - description: Unsorted BAM file of read alignments (optional) - pattern: "*Aligned.unsort.out.bam" - - fastq: - type: file - description: Unmapped FastQ files (optional) - pattern: "*fastq.gz" - - tab: - type: file - description: STAR output tab file(s) (optional) - pattern: "*.tab" - - junction: - type: file - description: STAR chimeric junction output file (optional) - pattern: "*.out.junction" - - wig: - type: file - description: STAR output wiggle format file(s) (optional) - pattern: "*.wig" - - bedgraph: - type: file - description: STAR output bedGraph format file(s) (optional) - pattern: "*.bg" + log_final: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*Log.final.out": + type: file + description: STAR final log file + pattern: "*Log.final.out" + ontologies: [] + log_out: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*Log.out": + type: file + description: STAR lot out file + pattern: "*Log.out" + ontologies: [] + log_progress: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*Log.progress.out": + type: file + description: STAR log progress file + pattern: "*Log.progress.out" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML + bam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*d.out.bam": + type: file + description: Output BAM file containing read alignments + pattern: "*.{bam}" + ontologies: [] + bam_sorted: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - ${prefix}.sortedByCoord.out.bam: + type: file + description: Sorted BAM file of read alignments (optional) + pattern: "*sortedByCoord.out.bam" + ontologies: [] + bam_sorted_aligned: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - ${prefix}.Aligned.sortedByCoord.out.bam: + type: file + description: Sorted BAM file of read alignments (optional) + pattern: "*.Aligned.sortedByCoord.out.bam" + ontologies: [] + bam_transcript: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*toTranscriptome.out.bam": + type: file + description: Output BAM file of transcriptome alignment (optional) + pattern: "*toTranscriptome.out.bam" + ontologies: [] + bam_unsorted: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*Aligned.unsort.out.bam": + type: file + description: Unsorted BAM file of read alignments (optional) + pattern: "*Aligned.unsort.out.bam" + ontologies: [] + fastq: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*fastq.gz": + type: file + description: Unmapped FastQ files (optional) + pattern: "*fastq.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format + tab: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.tab": + type: file + description: STAR output tab file(s) (optional) + pattern: "*.tab" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + spl_junc_tab: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.SJ.out.tab": + type: file + description: STAR output splice junction tab file + pattern: "*.SJ.out.tab" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + read_per_gene_tab: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.ReadsPerGene.out.tab": + type: file + description: STAR output read per gene tab file + pattern: "*.ReadsPerGene.out.tab" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + junction: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.out.junction": + type: file + description: STAR chimeric junction output file (optional) + pattern: "*.out.junction" + ontologies: [] + sam: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.out.sam": + type: file + description: STAR output SAM file(s) (optional) + pattern: "*.out.sam" + ontologies: [] + wig: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.wig": + type: file + description: STAR output wiggle format file(s) (optional) + pattern: "*.wig" + ontologies: [] + bedgraph: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.bg": + type: file + description: STAR output bedGraph format file(s) (optional) + pattern: "*.bg" + ontologies: [] authors: - "@kevinmenden" - "@drpatelh" diff --git a/modules/nf-core/star/align/tests/main.nf.test b/modules/nf-core/star/align/tests/main.nf.test index 4c8784741..a62c17db0 100644 --- a/modules/nf-core/star/align/tests/main.nf.test +++ b/modules/nf-core/star/align/tests/main.nf.test @@ -7,6 +7,7 @@ nextflow_process { tag "modules_nfcore" tag "star" tag "star/align" + tag "star/genomegenerate" test("homo_sapiens - single_end") { config "./nextflow.config" @@ -18,11 +19,11 @@ nextflow_process { """ input[0] = Channel.of([ [ id:'test_fasta' ], - [file(params.test_data['homo_sapiens']['genome']['genome_fasta'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] ]) input[1] = Channel.of([ [ id:'test_gtf' ], - [file(params.test_data['homo_sapiens']['genome']['genome_gtf'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) """ } @@ -34,12 +35,12 @@ nextflow_process { """ input[0] = Channel.of([ [ id:'test', single_end:true ], // meta map - [ file(params.test_data['homo_sapiens']['illumina']['test_rnaseq_1_fastq_gz'], checkIfExists: true) ] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true) ] ]) input[1] = STAR_GENOMEGENERATE.out.index input[2] = Channel.of([ [ id:'test_gtf' ], - [file(params.test_data['homo_sapiens']['genome']['genome_gtf'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) input[3] = false input[4] = 'illumina' @@ -51,22 +52,21 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(file(process.out.log_final[0][1]).name).match("homo_sapiens - single_end - log_final") }, - { assert snapshot(file(process.out.log_out[0][1]).name).match("homo_sapiens - single_end - log_out") }, - { assert snapshot(process.out.bam).match("homo_sapiens - single_end - bam") }, - { assert snapshot(process.out.bam_sorted).match("homo_sapiens - single_end - bam_sorted") }, - { assert snapshot(process.out.bam_transcript).match("homo_sapiens - single_end - bam_transcript") }, - { assert snapshot(process.out.bam_unsorted).match("homo_sapiens - single_end - bam_unsorted") }, - { assert snapshot(process.out.bedgraph).match("homo_sapiens - single_end - bedgraph") }, - { assert snapshot(process.out.fastq).match("homo_sapiens - single_end - fastq") }, - { assert snapshot(process.out.junction).match("homo_sapiens - single_end - junction") }, - { assert snapshot(process.out.log_progress).match("homo_sapiens - single_end - log_progress") }, - { assert snapshot(process.out.read_per_gene_tab).match("homo_sapiens - single_end - read_per_gene_tab") }, - { assert snapshot(process.out.sam).match("homo_sapiens - single_end - sam") }, - { assert snapshot(process.out.spl_junc_tab).match("homo_sapiens - single_end - spl_junc_tab") }, - { assert snapshot(process.out.tab).match("homo_sapiens - single_end - tab") }, - { assert snapshot(process.out.wig).match("homo_sapiens - single_end - wig") }, - { assert snapshot(process.out.versions).match("homo_sapiens - single_end - versions") } + { assert snapshot( + file(process.out.log_final[0][1]).name, + file(process.out.log_out[0][1]).name, + file(process.out.log_progress[0][1]).name, + bam(process.out.bam[0][1]).getReadsMD5(), + bam(process.out.bam_sorted_aligned[0][1]).getReadsMD5(), + process.out.bedgraph, + process.out.fastq, + process.out.read_per_gene_tab, + process.out.sam, + process.out.spl_junc_tab, + process.out.tab, + process.out.wig, + process.out.versions + ).match() } ) } } @@ -81,11 +81,11 @@ nextflow_process { """ input[0] = Channel.of([ [ id:'test_fasta' ], - [file(params.test_data['homo_sapiens']['genome']['genome_fasta'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] ]) input[1] = Channel.of([ [ id:'test_gtf' ], - [file(params.test_data['homo_sapiens']['genome']['genome_gtf'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) """ } @@ -98,14 +98,14 @@ nextflow_process { input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map [ - file(params.test_data['homo_sapiens']['illumina']['test_rnaseq_1_fastq_gz'], checkIfExists: true), - file(params.test_data['homo_sapiens']['illumina']['test_rnaseq_2_fastq_gz'], checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true) ] ]) input[1] = STAR_GENOMEGENERATE.out.index input[2] = Channel.of([ [ id:'test_gtf' ], - [file(params.test_data['homo_sapiens']['genome']['genome_gtf'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) input[3] = false input[4] = 'illumina' @@ -117,22 +117,21 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(file(process.out.log_final[0][1]).name).match("homo_sapiens - paired_end - log_final") }, - { assert snapshot(file(process.out.log_out[0][1]).name).match("homo_sapiens - paired_end - log_out") }, - { assert snapshot(process.out.bam).match("homo_sapiens - paired_end - bam") }, - { assert snapshot(process.out.bam_sorted).match("homo_sapiens - paired_end - bam_sorted") }, - { assert snapshot(process.out.bam_transcript).match("homo_sapiens - paired_end - bam_transcript") }, - { assert snapshot(process.out.bam_unsorted).match("homo_sapiens - paired_end - bam_unsorted") }, - { assert snapshot(process.out.bedgraph).match("homo_sapiens - paired_end - bedgraph") }, - { assert snapshot(process.out.fastq).match("homo_sapiens - paired_end - fastq") }, - { assert snapshot(process.out.junction).match("homo_sapiens - paired_end - junction") }, - { assert snapshot(process.out.log_progress).match("homo_sapiens - paired_end - log_progress") }, - { assert snapshot(process.out.read_per_gene_tab).match("homo_sapiens - paired_end - read_per_gene_tab") }, - { assert snapshot(process.out.sam).match("homo_sapiens - paired_end - sam") }, - { assert snapshot(process.out.spl_junc_tab).match("homo_sapiens - paired_end - spl_junc_tab") }, - { assert snapshot(process.out.tab).match("homo_sapiens - paired_end - tab") }, - { assert snapshot(process.out.wig).match("homo_sapiens - paired_end - wig") }, - { assert snapshot(process.out.versions).match("homo_sapiens - paired_end - versions") } + { assert snapshot( + file(process.out.log_final[0][1]).name, + file(process.out.log_out[0][1]).name, + file(process.out.log_progress[0][1]).name, + bam(process.out.bam[0][1]).getReadsMD5(), + bam(process.out.bam_sorted_aligned[0][1]).getReadsMD5(), + process.out.bedgraph, + process.out.fastq, + process.out.read_per_gene_tab, + process.out.sam, + process.out.spl_junc_tab, + process.out.tab, + process.out.wig, + process.out.versions + ).match() } ) } } @@ -147,11 +146,11 @@ nextflow_process { """ input[0] = Channel.of([ [ id:'test_fasta' ], - [file(params.test_data['homo_sapiens']['genome']['genome_fasta'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] ]) input[1] = Channel.of([ [ id:'test_gtf' ], - [file(params.test_data['homo_sapiens']['genome']['genome_gtf'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) """ } @@ -164,14 +163,14 @@ nextflow_process { input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map [ - file(params.test_data['homo_sapiens']['illumina']['test_rnaseq_1_fastq_gz'], checkIfExists: true), - file(params.test_data['homo_sapiens']['illumina']['test_rnaseq_2_fastq_gz'], checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true) ] ]) input[1] = STAR_GENOMEGENERATE.out.index input[2] = Channel.of([ [ id:'test_gtf' ], - [file(params.test_data['homo_sapiens']['genome']['genome_gtf'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) input[3] = false input[4] = 'illumina' @@ -183,22 +182,20 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(file(process.out.log_final[0][1]).name).match("homo_sapiens - paired_end - arriba - log_final") }, - { assert snapshot(file(process.out.log_out[0][1]).name).match("homo_sapiens - paired_end - arriba - log_out") }, - { assert snapshot(file(process.out.log_progress[0][1]).name).match("homo_sapiens - paired_end - arriba - log_progress") }, - { assert snapshot(process.out.bam).match("homo_sapiens - paired_end - arriba - bam") }, - { assert snapshot(process.out.bam_sorted).match("homo_sapiens - paired_end - arriba - bam_sorted") }, - { assert snapshot(process.out.bam_transcript).match("homo_sapiens - paired_end - arriba - bam_transcript") }, - { assert snapshot(process.out.bam_unsorted).match("homo_sapiens - paired_end - arriba - bam_unsorted") }, - { assert snapshot(process.out.bedgraph).match("homo_sapiens - paired_end - arriba - bedgraph") }, - { assert snapshot(process.out.fastq).match("homo_sapiens - paired_end - arriba - fastq") }, - { assert snapshot(process.out.junction).match("homo_sapiens - paired_end - arriba - junction") }, - { assert snapshot(process.out.read_per_gene_tab).match("homo_sapiens - paired_end - arriba - read_per_gene_tab") }, - { assert snapshot(process.out.sam).match("homo_sapiens - paired_end - arriba - sam") }, - { assert snapshot(process.out.spl_junc_tab).match("homo_sapiens - paired_end - arriba - spl_junc_tab") }, - { assert snapshot(process.out.tab).match("homo_sapiens - paired_end - arriba - tab") }, - { assert snapshot(process.out.wig).match("homo_sapiens - paired_end - arriba - wig") }, - { assert snapshot(process.out.versions).match("homo_sapiens - paired_end - arriba - versions") } + { assert snapshot( + file(process.out.log_final[0][1]).name, + file(process.out.log_out[0][1]).name, + file(process.out.log_progress[0][1]).name, + bam(process.out.bam[0][1]).getReadsMD5(), + process.out.bedgraph, + process.out.fastq, + process.out.read_per_gene_tab, + process.out.sam, + process.out.spl_junc_tab, + process.out.tab, + process.out.wig, + process.out.versions + ).match() } ) } } @@ -213,11 +210,11 @@ nextflow_process { """ input[0] = Channel.of([ [ id:'test_fasta' ], - [file(params.test_data['homo_sapiens']['genome']['genome_fasta'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] ]) input[1] = Channel.of([ [ id:'test_gtf' ], - [file(params.test_data['homo_sapiens']['genome']['genome_gtf'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) """ } @@ -230,14 +227,14 @@ nextflow_process { input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map [ - file(params.test_data['homo_sapiens']['illumina']['test_rnaseq_1_fastq_gz'], checkIfExists: true), - file(params.test_data['homo_sapiens']['illumina']['test_rnaseq_2_fastq_gz'], checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true) ] ]) input[1] = STAR_GENOMEGENERATE.out.index input[2] = Channel.of([ [ id:'test_gtf' ], - [file(params.test_data['homo_sapiens']['genome']['genome_gtf'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) input[3] = false input[4] = 'illumina' @@ -249,22 +246,21 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(file(process.out.log_final[0][1]).name).match("homo_sapiens - paired_end - starfusion - log_final") }, - { assert snapshot(file(process.out.log_out[0][1]).name).match("homo_sapiens - paired_end - starfusion - log_out") }, - { assert snapshot(file(process.out.log_progress[0][1]).name).match("homo_sapiens - paired_end - starfusion - log_progress") }, - { assert snapshot(process.out.bam).match("homo_sapiens - paired_end - starfusion - bam") }, - { assert snapshot(process.out.bam_sorted).match("homo_sapiens - paired_end - starfusion - bam_sorted") }, - { assert snapshot(process.out.bam_transcript).match("homo_sapiens - paired_end - starfusion - bam_transcript") }, - { assert snapshot(process.out.bam_unsorted).match("homo_sapiens - paired_end - starfusion - bam_unsorted") }, - { assert snapshot(process.out.bedgraph).match("homo_sapiens - paired_end - starfusion - bedgraph") }, - { assert snapshot(process.out.fastq).match("homo_sapiens - paired_end - starfusion - fastq") }, - { assert snapshot(process.out.junction).match("homo_sapiens - paired_end - starfusion - junction") }, - { assert snapshot(process.out.read_per_gene_tab).match("homo_sapiens - paired_end - starfusion - read_per_gene_tab") }, - { assert snapshot(process.out.sam).match("homo_sapiens - paired_end - starfusion - sam") }, - { assert snapshot(process.out.spl_junc_tab).match("homo_sapiens - paired_end - starfusion - spl_junc_tab") }, - { assert snapshot(process.out.tab).match("homo_sapiens - paired_end - starfusion - tab") }, - { assert snapshot(process.out.wig).match("homo_sapiens - paired_end - starfusion - wig") }, - { assert snapshot(process.out.versions).match("homo_sapiens - paired_end - starfusion - versions") } + { assert snapshot( + file(process.out.log_final[0][1]).name, + file(process.out.log_out[0][1]).name, + file(process.out.log_progress[0][1]).name, + file(process.out.junction[0][1]).name, + bam(process.out.bam[0][1]).getReadsMD5(), + process.out.bedgraph, + process.out.fastq, + process.out.read_per_gene_tab, + process.out.sam, + process.out.spl_junc_tab, + process.out.tab, + process.out.wig, + process.out.versions + ).match() } ) } } @@ -279,11 +275,11 @@ nextflow_process { """ input[0] = Channel.of([ [ id:'test_fasta' ], - [file(params.test_data['homo_sapiens']['genome']['genome_fasta'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] ]) input[1] = Channel.of([ [ id:'test_gtf' ], - [file(params.test_data['homo_sapiens']['genome']['genome_gtf'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) """ } @@ -296,16 +292,16 @@ nextflow_process { input[0] = Channel.of([ [ id:'test', single_end:false ], // meta map [ - file(params.test_data['homo_sapiens']['illumina']['test_rnaseq_1_fastq_gz'], checkIfExists: true), - file(params.test_data['homo_sapiens']['illumina']['test_rnaseq_2_fastq_gz'], checkIfExists: true), - file(params.test_data['homo_sapiens']['illumina']['test_rnaseq_1_fastq_gz'], checkIfExists: true), - file(params.test_data['homo_sapiens']['illumina']['test_rnaseq_2_fastq_gz'], checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true) ] ]) input[1] = STAR_GENOMEGENERATE.out.index input[2] = Channel.of([ [ id:'test_gtf' ], - [file(params.test_data['homo_sapiens']['genome']['genome_gtf'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) input[3] = false input[4] = 'illumina' @@ -317,23 +313,281 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(file(process.out.log_final[0][1]).name).match("homo_sapiens - paired_end - multiple - log_final") }, - { assert snapshot(file(process.out.log_out[0][1]).name).match("homo_sapiens - paired_end - multiple - log_out") }, - { assert snapshot(file(process.out.log_progress[0][1]).name).match("homo_sapiens - paired_end - multiple - log_progress") }, - { assert snapshot(process.out.bam).match("homo_sapiens - paired_end - multiple - bam") }, - { assert snapshot(process.out.bam_sorted).match("homo_sapiens - paired_end - multiple - bam_sorted") }, - { assert snapshot(process.out.bam_transcript).match("homo_sapiens - paired_end - multiple - bam_transcript") }, - { assert snapshot(process.out.bam_unsorted).match("homo_sapiens - paired_end - multiple - bam_unsorted") }, - { assert snapshot(process.out.bedgraph).match("homo_sapiens - paired_end - multiple - bedgraph") }, - { assert snapshot(process.out.fastq).match("homo_sapiens - paired_end - multiple - fastq") }, - { assert snapshot(process.out.junction).match("homo_sapiens - paired_end - multiple - junction") }, - { assert snapshot(process.out.read_per_gene_tab).match("homo_sapiens - paired_end - multiple - read_per_gene_tab") }, - { assert snapshot(process.out.sam).match("homo_sapiens - paired_end - multiple - sam") }, - { assert snapshot(process.out.spl_junc_tab).match("homo_sapiens - paired_end - multiple - spl_junc_tab") }, - { assert snapshot(process.out.tab).match("homo_sapiens - paired_end - multiple - tab") }, - { assert snapshot(process.out.wig).match("homo_sapiens - paired_end - multiple - wig") }, - { assert snapshot(process.out.versions).match("homo_sapiens - paired_end - multiple - versions") } + { assert snapshot( + file(process.out.log_final[0][1]).name, + file(process.out.log_out[0][1]).name, + file(process.out.log_progress[0][1]).name, + bam(process.out.bam[0][1]).getReadsMD5(), + bam(process.out.bam_sorted_aligned[0][1]).getReadsMD5(), + process.out.bedgraph, + process.out.fastq, + process.out.read_per_gene_tab, + process.out.sam, + process.out.spl_junc_tab, + process.out.tab, + process.out.wig, + process.out.versions + ).match() } ) } } -} \ No newline at end of file + + test("homo_sapiens - single_end - stub") { + options "-stub" + config "./nextflow.config" + + setup { + run("STAR_GENOMEGENERATE") { + script "../../../star/genomegenerate/main.nf" + process { + """ + input[0] = Channel.of([ + [ id:'test_fasta' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[1] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + """ + } + } + } + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true) ] + ]) + input[1] = STAR_GENOMEGENERATE.out.index + input[2] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + input[3] = false + input[4] = 'illumina' + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("homo_sapiens - paired_end - stub") { + options "-stub" + config "./nextflow.config" + + setup { + run("STAR_GENOMEGENERATE") { + script "../../../star/genomegenerate/main.nf" + process { + """ + input[0] = Channel.of([ + [ id:'test_fasta' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[1] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + """ + } + } + } + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true) + ] + ]) + input[1] = STAR_GENOMEGENERATE.out.index + input[2] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + input[3] = false + input[4] = 'illumina' + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("homo_sapiens - paired_end - arriba - stub") { + options "-stub" + config "./nextflow.arriba.config" + + setup { + run("STAR_GENOMEGENERATE") { + script "../../../star/genomegenerate/main.nf" + process { + """ + input[0] = Channel.of([ + [ id:'test_fasta' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[1] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + """ + } + } + } + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true) + ] + ]) + input[1] = STAR_GENOMEGENERATE.out.index + input[2] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + input[3] = false + input[4] = 'illumina' + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("homo_sapiens - paired_end - starfusion - stub") { + options "-stub" + config "./nextflow.starfusion.config" + + setup { + run("STAR_GENOMEGENERATE") { + script "../../../star/genomegenerate/main.nf" + process { + """ + input[0] = Channel.of([ + [ id:'test_fasta' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[1] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + """ + } + } + } + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true) + ] + ]) + input[1] = STAR_GENOMEGENERATE.out.index + input[2] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + input[3] = false + input[4] = 'illumina' + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("homo_sapiens - paired_end - multiple - stub") { + options "-stub" + config "./nextflow.config" + + setup { + run("STAR_GENOMEGENERATE") { + script "../../../star/genomegenerate/main.nf" + process { + """ + input[0] = Channel.of([ + [ id:'test_fasta' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[1] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + """ + } + } + } + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true) + ] + ]) + input[1] = STAR_GENOMEGENERATE.out.index + input[2] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + input[3] = false + input[4] = 'illumina' + input[5] = false + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} 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 59b735d44..a1ec3a3d0 100644 --- a/modules/nf-core/star/align/tests/main.nf.test.snap +++ b/modules/nf-core/star/align/tests/main.nf.test.snap @@ -1,231 +1,665 @@ { - "homo_sapiens - paired_end - multiple - bam_sorted": { + "homo_sapiens - single_end - stub": { "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.Aligned.sortedByCoord.out.bam:md5,ab07c21d63ab0a6c07d171d213c81d5a" - ] - ] - ], - "timestamp": "2023-11-23T13:29:01.19639" - }, - "homo_sapiens - paired_end - multiple - wig": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:29:01.857804" - }, - "homo_sapiens - paired_end - arriba - tab": { - "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.SJ.out.tab:md5,5155c9fd1f787ad6d7d80987fb06219c" - ] - ] - ], - "timestamp": "2023-11-23T13:25:07.396223" - }, - "homo_sapiens - single_end - wig": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:22:55.24701" - }, - "homo_sapiens - paired_end - sam": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:23:33.383818" - }, - "homo_sapiens - paired_end - arriba - versions": { - "content": [ - [ - "versions.yml:md5,452ef035aacbc68d47041e86279a9333" - ] - ], - "timestamp": "2023-11-23T13:25:07.494015" - }, - "homo_sapiens - paired_end - multiple - bedgraph": { - "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, + { + "0": [ [ - "test.Signal.Unique.str1.out.bg:md5,d7bf8b70b436ca048a62513e1d0ece3a", - "test.Signal.UniqueMultiple.str1.out.bg:md5,686d58493b9eb445b56ace4d67f76ef6" + { + "id": "test", + "single_end": true + }, + "test.Log.final.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.Log.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + { + "id": "test", + "single_end": true + }, + [ + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": true + }, + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "12": [ + [ + { + "id": "test", + "single_end": true + }, + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "13": [ + [ + { + "id": "test", + "single_end": true + }, + "test.Chimeric.out.junction:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "14": [ + [ + { + "id": "test", + "single_end": true + }, + "test.out.sam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "15": [ + [ + { + "id": "test", + "single_end": true + }, + "test.Signal.UniqueMultiple.str1.out.wig:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "16": [ + [ + { + "id": "test", + "single_end": true + }, + "test.Signal.UniqueMultiple.str1.out.bg:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.Log.progress.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + ], + "4": [ + [ + { + "id": "test", + "single_end": true + }, + [ + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": true + }, + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": true + }, + "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + [ + { + "id": "test", + "single_end": true + }, + "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "9": [ + [ + { + "id": "test", + "single_end": true + }, + [ + "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "bam": [ + [ + { + "id": "test", + "single_end": true + }, + [ + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "bam_sorted": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam_sorted_aligned": [ + [ + { + "id": "test", + "single_end": true + }, + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam_transcript": [ + [ + { + "id": "test", + "single_end": true + }, + "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam_unsorted": [ + [ + { + "id": "test", + "single_end": true + }, + "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bedgraph": [ + [ + { + "id": "test", + "single_end": true + }, + "test.Signal.UniqueMultiple.str1.out.bg:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastq": [ + [ + { + "id": "test", + "single_end": true + }, + [ + "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "junction": [ + [ + { + "id": "test", + "single_end": true + }, + "test.Chimeric.out.junction:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log_final": [ + [ + { + "id": "test", + "single_end": true + }, + "test.Log.final.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log_out": [ + [ + { + "id": "test", + "single_end": true + }, + "test.Log.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log_progress": [ + [ + { + "id": "test", + "single_end": true + }, + "test.Log.progress.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "read_per_gene_tab": [ + [ + { + "id": "test", + "single_end": true + }, + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "sam": [ + [ + { + "id": "test", + "single_end": true + }, + "test.out.sam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "spl_junc_tab": [ + [ + { + "id": "test", + "single_end": true + }, + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tab": [ + [ + { + "id": "test", + "single_end": true + }, + [ + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions": [ + "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + ], + "wig": [ + [ + { + "id": "test", + "single_end": true + }, + "test.Signal.UniqueMultiple.str1.out.wig:md5,d41d8cd98f00b204e9800998ecf8427e" ] ] - ] - ], - "timestamp": "2023-11-23T13:29:01.396383" - }, - "homo_sapiens - paired_end - read_per_gene_tab": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:23:33.368841" - }, - "homo_sapiens - paired_end - arriba - bedgraph": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:25:07.102537" - }, - "homo_sapiens - single_end - junction": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:22:55.185369" - }, - "homo_sapiens - paired_end - arriba - spl_junc_tab": { - "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.SJ.out.tab:md5,5155c9fd1f787ad6d7d80987fb06219c" - ] - ] - ], - "timestamp": "2023-11-23T13:25:07.348239" - }, - "homo_sapiens - single_end - sam": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:22:55.216183" - }, - "homo_sapiens - paired_end - fastq": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:23:33.327236" - }, - "homo_sapiens - single_end - versions": { - "content": [ - [ - "versions.yml:md5,452ef035aacbc68d47041e86279a9333" - ] - ], - "timestamp": "2023-11-23T13:22:55.259282" - }, - "homo_sapiens - paired_end - multiple - log_out": { - "content": [ - "test.Log.out" - ], - "timestamp": "2023-11-23T13:29:01.022176" - }, - "homo_sapiens - paired_end - arriba - fastq": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:25:07.15277" - }, - "homo_sapiens - paired_end - multiple - junction": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:29:01.52923" - }, - "homo_sapiens - paired_end - multiple - spl_junc_tab": { - "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.SJ.out.tab:md5,069877e053714e23010fe4e1c003b4a2" - ] - ] + } ], - "timestamp": "2023-11-23T13:29:01.729175" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T16:28:39.242074494" }, - "homo_sapiens - paired_end - starfusion - log_final": { + "homo_sapiens - paired_end - arriba - stub": { "content": [ - "test.Log.final.out" - ], - "timestamp": "2023-11-23T13:27:55.905883" - }, - "homo_sapiens - paired_end - starfusion - fastq": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:27:56.192302" - }, - "homo_sapiens - paired_end - multiple - sam": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:29:01.661837" - }, - "homo_sapiens - paired_end - multiple - log_final": { - "content": [ - "test.Log.final.out" - ], - "timestamp": "2023-11-23T13:29:00.966417" - }, - "homo_sapiens - paired_end - starfusion - bam": { - "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.Aligned.out.bam:md5,bcad07b838f6762fc01eea52b5cd3f84" + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.final.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": false + }, + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "12": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "13": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Chimeric.out.junction:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "14": [ + [ + { + "id": "test", + "single_end": false + }, + "test.out.sam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "15": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Signal.UniqueMultiple.str1.out.wig:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "16": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Signal.UniqueMultiple.str1.out.bg:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.progress.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false + }, + "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "9": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "bam": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "bam_sorted": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam_sorted_aligned": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam_transcript": [ + [ + { + "id": "test", + "single_end": false + }, + "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam_unsorted": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bedgraph": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Signal.UniqueMultiple.str1.out.bg:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastq": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "junction": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Chimeric.out.junction:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log_final": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.final.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log_out": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log_progress": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.progress.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "read_per_gene_tab": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "sam": [ + [ + { + "id": "test", + "single_end": false + }, + "test.out.sam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "spl_junc_tab": [ + [ + { + "id": "test", + "single_end": false + }, + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tab": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions": [ + "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + ], + "wig": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Signal.UniqueMultiple.str1.out.wig:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] - ] - ], - "timestamp": "2023-11-23T13:27:56.003675" - }, - "homo_sapiens - paired_end - arriba - junction": { - "content": [ - [ - - ] + } ], - "timestamp": "2023-11-23T13:25:07.202776" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T16:29:08.392620556" }, - "homo_sapiens - single_end - bedgraph": { + "homo_sapiens - single_end": { "content": [ + "test.Log.final.out", + "test.Log.out", + "test.Log.progress.out", + "9f76be49a6607613a64f760101bdddce", + "9f76be49a6607613a64f760101bdddce", [ [ { @@ -237,312 +671,440 @@ "test.Signal.UniqueMultiple.str1.out.bg:md5,e93373cf6f2a2a9506e2efdb260cdd4f" ] ] - ] - ], - "timestamp": "2023-11-23T13:22:55.163495" - }, - "homo_sapiens - paired_end - arriba - read_per_gene_tab": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:25:07.251962" - }, - "homo_sapiens - paired_end - starfusion - bam_sorted": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:27:56.040843" - }, - "homo_sapiens - single_end - bam_unsorted": { - "content": [ + ], [ - ] - ], - "timestamp": "2023-11-23T13:22:55.154172" - }, - "homo_sapiens - paired_end - bam": { - "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.Aligned.sortedByCoord.out.bam:md5,b9ee1c607e07323bc1652ef3babb543f" - ] - ] - ], - "timestamp": "2023-11-23T13:23:33.265265" - }, - "homo_sapiens - paired_end - arriba - bam_transcript": { - "content": [ + ], [ - ] - ], - "timestamp": "2023-11-23T13:25:06.998817" - }, - "homo_sapiens - paired_end - log_out": { - "content": [ - "test.Log.out" - ], - "timestamp": "2023-11-23T13:23:33.259699" - }, - "homo_sapiens - paired_end - arriba - log_out": { - "content": [ - "test.Log.out" - ], - "timestamp": "2023-11-23T13:25:06.849451" - }, - "homo_sapiens - paired_end - multiple - versions": { - "content": [ - [ - "versions.yml:md5,452ef035aacbc68d47041e86279a9333" - ] - ], - "timestamp": "2023-11-23T13:29:01.937182" - }, - "homo_sapiens - paired_end - starfusion - bam_transcript": { - "content": [ + ], [ - ] - ], - "timestamp": "2023-11-23T13:27:56.082408" - }, - "homo_sapiens - paired_end - starfusion - tab": { - "content": [ + ], [ [ { "id": "test", - "single_end": false + "single_end": true }, - "test.SJ.out.tab:md5,19c3faa1bfa9a0cc5e4c45f17065b53a" + "test.SJ.out.tab:md5,75a516ab950fb958f40b29996474949c" ] - ] - ], - "timestamp": "2023-11-23T13:27:56.379367" - }, - "homo_sapiens - single_end - fastq": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:22:55.175307" - }, - "homo_sapiens - paired_end - tab": { - "content": [ + ], [ [ { "id": "test", - "single_end": false + "single_end": true }, - "test.SJ.out.tab:md5,844af19ab0fc8cd9a3f75228445aca0d" + "test.SJ.out.tab:md5,75a516ab950fb958f40b29996474949c" ] - ] - ], - "timestamp": "2023-11-23T13:23:33.413683" - }, - "homo_sapiens - paired_end - starfusion - bedgraph": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:27:56.155413" - }, - "homo_sapiens - single_end - bam_transcript": { - "content": [ + ], [ - ] - ], - "timestamp": "2023-11-23T13:22:55.144852" - }, - "homo_sapiens - paired_end - versions": { - "content": [ + ], [ - "versions.yml:md5,452ef035aacbc68d47041e86279a9333" + "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" ] ], - "timestamp": "2023-11-23T13:23:33.445323" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T16:21:34.549483887" }, - "homo_sapiens - paired_end - multiple - tab": { + "homo_sapiens - paired_end": { "content": [ + "test.Log.final.out", + "test.Log.out", + "test.Log.progress.out", + "db9a8324b5163b025bcc0c33e848486", + "db9a8324b5163b025bcc0c33e848486", [ [ { "id": "test", "single_end": false }, - "test.SJ.out.tab:md5,069877e053714e23010fe4e1c003b4a2" - ] - ] - ], - "timestamp": "2023-11-23T13:29:01.793129" - }, - "homo_sapiens - single_end - bam": { - "content": [ - [ - [ - { - "id": "test", - "single_end": true - }, - "test.Aligned.sortedByCoord.out.bam:md5,c6cfaccaf91bc7fdabed3cfe236d4535" + [ + "test.Signal.Unique.str1.out.bg:md5,d7bf8b70b436ca048a62513e1d0ece3a", + "test.Signal.UniqueMultiple.str1.out.bg:md5,686d58493b9eb445b56ace4d67f76ef6" + ] ] - ] - ], - "timestamp": "2023-11-23T13:22:55.128568" - }, - "homo_sapiens - paired_end - arriba - wig": { - "content": [ + ], [ - ] - ], - "timestamp": "2023-11-23T13:25:07.444214" - }, - "homo_sapiens - paired_end - log_progress": { - "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.Log.progress.out:md5,b2bd061d6cbaaf3d6d3b1fed547f69b8" - ] - ] - ], - "timestamp": "2023-11-23T13:23:33.354416" - }, - "homo_sapiens - paired_end - arriba - log_final": { - "content": [ - "test.Log.final.out" - ], - "timestamp": "2023-11-23T13:25:06.829799" - }, - "homo_sapiens - paired_end - bam_unsorted": { - "content": [ + ], [ - ] - ], - "timestamp": "2023-11-23T13:23:33.300509" - }, - "homo_sapiens - paired_end - arriba - sam": { - "content": [ + ], [ - ] - ], - "timestamp": "2023-11-23T13:25:07.300383" - }, - "homo_sapiens - paired_end - multiple - bam": { - "content": [ + ], [ [ { "id": "test", "single_end": false }, - "test.Aligned.sortedByCoord.out.bam:md5,ab07c21d63ab0a6c07d171d213c81d5a" + "test.SJ.out.tab:md5,844af19ab0fc8cd9a3f75228445aca0d" ] - ] - ], - "timestamp": "2023-11-23T13:29:01.13168" - }, - "homo_sapiens - paired_end - multiple - fastq": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:29:01.462257" - }, - "homo_sapiens - single_end - bam_sorted": { - "content": [ + ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "test.Aligned.sortedByCoord.out.bam:md5,c6cfaccaf91bc7fdabed3cfe236d4535" + "test.SJ.out.tab:md5,844af19ab0fc8cd9a3f75228445aca0d" ] - ] - ], - "timestamp": "2023-11-23T13:22:55.134799" - }, - "homo_sapiens - paired_end - arriba - bam_sorted": { - "content": [ + ], [ - ] - ], - "timestamp": "2023-11-23T13:25:06.94699" - }, - "homo_sapiens - paired_end - starfusion - junction": { - "content": [ + ], [ - [ - { - "id": "test", - "single_end": false - }, - "test.Chimeric.out.junction:md5,c10ef219f4a30e83711b995bc5e40dba" - ] + "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" ] ], - "timestamp": "2023-11-23T13:27:56.228327" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T16:22:17.011253146" }, - "homo_sapiens - single_end - tab": { + "homo_sapiens - paired_end - multiple - stub": { "content": [ - [ - [ - { - "id": "test", - "single_end": true - }, - "test.SJ.out.tab:md5,75a516ab950fb958f40b29996474949c" + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.final.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": false + }, + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "12": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "13": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Chimeric.out.junction:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "14": [ + [ + { + "id": "test", + "single_end": false + }, + "test.out.sam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "15": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Signal.UniqueMultiple.str1.out.wig:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "16": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Signal.UniqueMultiple.str1.out.bg:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.progress.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false + }, + "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "9": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "bam": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "bam_sorted": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam_sorted_aligned": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam_transcript": [ + [ + { + "id": "test", + "single_end": false + }, + "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam_unsorted": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bedgraph": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Signal.UniqueMultiple.str1.out.bg:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastq": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "junction": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Chimeric.out.junction:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log_final": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.final.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log_out": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log_progress": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.progress.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "read_per_gene_tab": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "sam": [ + [ + { + "id": "test", + "single_end": false + }, + "test.out.sam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "spl_junc_tab": [ + [ + { + "id": "test", + "single_end": false + }, + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tab": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions": [ + "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + ], + "wig": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Signal.UniqueMultiple.str1.out.wig:md5,d41d8cd98f00b204e9800998ecf8427e" + ] ] - ] - ], - "timestamp": "2023-11-23T13:22:55.236346" - }, - "homo_sapiens - paired_end - starfusion - versions": { - "content": [ - [ - "versions.yml:md5,452ef035aacbc68d47041e86279a9333" - ] - ], - "timestamp": "2023-11-23T13:27:56.460903" - }, - "homo_sapiens - paired_end - multiple - bam_unsorted": { - "content": [ - [ - - ] - ], - "timestamp": "2023-11-23T13:29:01.330463" - }, - "homo_sapiens - paired_end - arriba - log_progress": { - "content": [ - "test.Log.progress.out" + } ], - "timestamp": "2023-11-23T13:25:06.86866" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T16:29:31.072104862" }, - "homo_sapiens - paired_end - bedgraph": { + "homo_sapiens - paired_end - multiple": { "content": [ + "test.Log.final.out", + "test.Log.out", + "test.Log.progress.out", + "3e54e45f5dc3e9c1f2fc55bc41531a87", + "3e54e45f5dc3e9c1f2fc55bc41531a87", [ [ { @@ -554,216 +1116,798 @@ "test.Signal.UniqueMultiple.str1.out.bg:md5,686d58493b9eb445b56ace4d67f76ef6" ] ] - ] - ], - "timestamp": "2023-11-23T13:23:33.313258" - }, - "homo_sapiens - paired_end - starfusion - bam_unsorted": { - "content": [ + ], [ - ] - ], - "timestamp": "2023-11-23T13:27:56.118974" - }, - "homo_sapiens - paired_end - starfusion - read_per_gene_tab": { - "content": [ + ], [ - ] - ], - "timestamp": "2023-11-23T13:27:56.264699" - }, - "homo_sapiens - paired_end - multiple - log_progress": { - "content": [ - "test.Log.progress.out" - ], - "timestamp": "2023-11-23T13:29:01.076947" - }, - "homo_sapiens - paired_end - arriba - bam_unsorted": { - "content": [ + ], [ - ] - ], - "timestamp": "2023-11-23T13:25:07.050409" - }, - "homo_sapiens - paired_end - bam_sorted": { - "content": [ + ], [ [ { "id": "test", "single_end": false }, - "test.Aligned.sortedByCoord.out.bam:md5,b9ee1c607e07323bc1652ef3babb543f" - ] - ] - ], - "timestamp": "2023-11-23T13:23:33.274809" - }, - "homo_sapiens - single_end - spl_junc_tab": { - "content": [ - [ - [ - { - "id": "test", - "single_end": true - }, - "test.SJ.out.tab:md5,75a516ab950fb958f40b29996474949c" + "test.SJ.out.tab:md5,069877e053714e23010fe4e1c003b4a2" ] - ] - ], - "timestamp": "2023-11-23T13:22:55.226143" - }, - "homo_sapiens - paired_end - starfusion - spl_junc_tab": { - "content": [ + ], [ [ { "id": "test", "single_end": false }, - "test.SJ.out.tab:md5,19c3faa1bfa9a0cc5e4c45f17065b53a" + "test.SJ.out.tab:md5,069877e053714e23010fe4e1c003b4a2" ] - ] - ], - "timestamp": "2023-11-23T13:27:56.337072" - }, - "homo_sapiens - single_end - log_out": { - "content": [ - "test.Log.out" - ], - "timestamp": "2023-11-23T13:22:55.126286" - }, - "homo_sapiens - paired_end - log_final": { - "content": [ - "test.Log.final.out" - ], - "timestamp": "2023-11-23T13:23:33.253884" - }, - "homo_sapiens - single_end - log_final": { - "content": [ - "test.Log.final.out" - ], - "timestamp": "2023-11-23T13:22:55.11799" - }, - "homo_sapiens - paired_end - bam_transcript": { - "content": [ + ], [ + ], + [ + "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" ] ], - "timestamp": "2023-11-23T13:23:33.287684" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T16:28:26.645008336" }, - "homo_sapiens - paired_end - starfusion - log_progress": { + "homo_sapiens - paired_end - stub": { "content": [ - "test.Log.progress.out" + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.final.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": false + }, + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "12": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "13": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Chimeric.out.junction:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "14": [ + [ + { + "id": "test", + "single_end": false + }, + "test.out.sam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "15": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Signal.UniqueMultiple.str1.out.wig:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "16": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Signal.UniqueMultiple.str1.out.bg:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.progress.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false + }, + "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "9": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "bam": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "bam_sorted": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam_sorted_aligned": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam_transcript": [ + [ + { + "id": "test", + "single_end": false + }, + "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam_unsorted": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bedgraph": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Signal.UniqueMultiple.str1.out.bg:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastq": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "junction": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Chimeric.out.junction:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log_final": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.final.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log_out": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log_progress": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.progress.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "read_per_gene_tab": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "sam": [ + [ + { + "id": "test", + "single_end": false + }, + "test.out.sam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "spl_junc_tab": [ + [ + { + "id": "test", + "single_end": false + }, + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tab": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions": [ + "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + ], + "wig": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Signal.UniqueMultiple.str1.out.wig:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } ], - "timestamp": "2023-11-23T13:27:55.971484" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T16:28:53.816280805" }, - "homo_sapiens - paired_end - multiple - bam_transcript": { + "homo_sapiens - paired_end - starfusion": { "content": [ + "test.Log.final.out", + "test.Log.out", + "test.Log.progress.out", + "test.Chimeric.out.junction", + "caee9dcda13882d4913456973c25b57a", [ - ] - ], - "timestamp": "2023-11-23T13:29:01.264176" - }, - "homo_sapiens - paired_end - multiple - read_per_gene_tab": { - "content": [ + ], [ - ] - ], - "timestamp": "2023-11-23T13:29:01.596406" - }, - "homo_sapiens - single_end - read_per_gene_tab": { - "content": [ + ], [ - ] - ], - "timestamp": "2023-11-23T13:22:55.205936" - }, - "homo_sapiens - paired_end - junction": { - "content": [ + ], [ - ] - ], - "timestamp": "2023-11-23T13:23:33.340653" - }, - "homo_sapiens - paired_end - spl_junc_tab": { - "content": [ + ], [ [ { "id": "test", "single_end": false }, - "test.SJ.out.tab:md5,844af19ab0fc8cd9a3f75228445aca0d" + "test.SJ.out.tab:md5,19c3faa1bfa9a0cc5e4c45f17065b53a" ] - ] - ], - "timestamp": "2023-11-23T13:23:33.398603" - }, - "homo_sapiens - paired_end - starfusion - sam": { - "content": [ + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.SJ.out.tab:md5,19c3faa1bfa9a0cc5e4c45f17065b53a" + ] + ], [ + ], + [ + "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" ] ], - "timestamp": "2023-11-23T13:27:56.300637" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T16:27:14.136111964" }, - "homo_sapiens - paired_end - arriba - bam": { + "homo_sapiens - paired_end - arriba": { "content": [ + "test.Log.final.out", + "test.Log.out", + "test.Log.progress.out", + "1a3abe88fb2490589c58497d39921bcc", + [ + + ], + [ + + ], + [ + + ], + [ + + ], [ [ { "id": "test", "single_end": false }, - "test.Aligned.out.bam:md5,c1b1747f5873f2d17762725636e891d5" + "test.SJ.out.tab:md5,5155c9fd1f787ad6d7d80987fb06219c" ] - ] - ], - "timestamp": "2023-11-23T13:25:06.887604" - }, - "homo_sapiens - single_end - log_progress": { - "content": [ + ], [ [ { "id": "test", - "single_end": true + "single_end": false }, - "test.Log.progress.out:md5,b2bd061d6cbaaf3d6d3b1fed547f69b8" + "test.SJ.out.tab:md5,5155c9fd1f787ad6d7d80987fb06219c" ] - ] - ], - "timestamp": "2023-11-23T13:22:55.195544" - }, - "homo_sapiens - paired_end - starfusion - wig": { - "content": [ + ], [ - ] - ], - "timestamp": "2023-11-23T13:27:56.422018" - }, - "homo_sapiens - paired_end - wig": { - "content": [ + ], [ - + "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" ] ], - "timestamp": "2023-11-23T13:23:33.429457" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T16:24:00.829462526" }, - "homo_sapiens - paired_end - starfusion - log_out": { + "homo_sapiens - paired_end - starfusion - stub": { "content": [ - "test.Log.out" + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.final.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": false + }, + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "12": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "13": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Chimeric.out.junction:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "14": [ + [ + { + "id": "test", + "single_end": false + }, + "test.out.sam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "15": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Signal.UniqueMultiple.str1.out.wig:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "16": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Signal.UniqueMultiple.str1.out.bg:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.progress.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false + }, + "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "9": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "bam": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e", + "testXd.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "bam_sorted": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam_sorted_aligned": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.sortedByCoord.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam_transcript": [ + [ + { + "id": "test", + "single_end": false + }, + "test.toTranscriptome.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam_unsorted": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.unsort.out.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bedgraph": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Signal.UniqueMultiple.str1.out.bg:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastq": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.unmapped_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.unmapped_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "junction": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Chimeric.out.junction:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log_final": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.final.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log_out": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "log_progress": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Log.progress.out:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "read_per_gene_tab": [ + [ + { + "id": "test", + "single_end": false + }, + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "sam": [ + [ + { + "id": "test", + "single_end": false + }, + "test.out.sam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "spl_junc_tab": [ + [ + { + "id": "test", + "single_end": false + }, + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tab": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.ReadsPerGene.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.SJ.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions": [ + "versions.yml:md5,b416145d7b5b8a080e832a7f7cde4c44" + ], + "wig": [ + [ + { + "id": "test", + "single_end": false + }, + "test.Signal.UniqueMultiple.str1.out.wig:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } ], - "timestamp": "2023-11-23T13:27:55.93945" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T16:29:20.015372487" } } \ No newline at end of file diff --git a/modules/nf-core/star/align/tests/nextflow.arriba.config b/modules/nf-core/star/align/tests/nextflow.arriba.config index 2324b9e58..cf09323fc 100644 --- a/modules/nf-core/star/align/tests/nextflow.arriba.config +++ b/modules/nf-core/star/align/tests/nextflow.arriba.config @@ -9,6 +9,3 @@ process { } } - -// Fix chown issue for the output star folder -docker.runOptions = '--platform=linux/amd64 -u $(id -u):$(id -g)' diff --git a/modules/nf-core/star/align/tests/nextflow.config b/modules/nf-core/star/align/tests/nextflow.config index c4ac58088..18bc2ee8a 100644 --- a/modules/nf-core/star/align/tests/nextflow.config +++ b/modules/nf-core/star/align/tests/nextflow.config @@ -9,6 +9,3 @@ process { } } - -// Fix chown issue for the output star folder -docker.runOptions = '--platform=linux/amd64 -u $(id -u):$(id -g)' diff --git a/modules/nf-core/star/align/tests/nextflow.starfusion.config b/modules/nf-core/star/align/tests/nextflow.starfusion.config index 467b64977..7880bfcf5 100644 --- a/modules/nf-core/star/align/tests/nextflow.starfusion.config +++ b/modules/nf-core/star/align/tests/nextflow.starfusion.config @@ -9,6 +9,3 @@ process { } } - -// Fix chown issue for the output star folder -docker.runOptions = '--platform=linux/amd64 -u $(id -u):$(id -g)' 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 8beace16e..000000000 --- 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/star/genomegenerate/environment.yml b/modules/nf-core/star/genomegenerate/environment.yml index 0b35ff518..91e37ae12 100644 --- a/modules/nf-core/star/genomegenerate/environment.yml +++ b/modules/nf-core/star/genomegenerate/environment.yml @@ -1,9 +1,11 @@ -name: star_genomegenerate +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults + dependencies: - - bioconda::star=2.7.10a - - bioconda::samtools=1.16.1 + - bioconda::htslib=1.21 + - bioconda::samtools=1.21 + - bioconda::star=2.7.11b - conda-forge::gawk=5.1.0 diff --git a/modules/nf-core/star/genomegenerate/main.nf b/modules/nf-core/star/genomegenerate/main.nf index d20618443..4eb95654b 100644 --- a/modules/nf-core/star/genomegenerate/main.nf +++ b/modules/nf-core/star/genomegenerate/main.nf @@ -4,8 +4,8 @@ process STAR_GENOMEGENERATE { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/mulled-v2-1fa26d1ce03c295fe2fdcf85831a92fbcbd7e8c2:019f262d90511939dce2dca4b7c868fc108f73db-0' : - 'biocontainers/mulled-v2-1fa26d1ce03c295fe2fdcf85831a92fbcbd7e8c2:019f262d90511939dce2dca4b7c868fc108f73db-0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/26/268b4c9c6cbf8fa6606c9b7fd4fafce18bf2c931d1a809a0ce51b105ec06c89d/data' : + 'community.wave.seqera.io/library/htslib_samtools_star_gawk:ae438e9a604351a4' }" input: tuple val(meta), path(fasta) @@ -19,9 +19,10 @@ process STAR_GENOMEGENERATE { task.ext.when == null || task.ext.when script: - def args = task.ext.args ?: '' - def args_list = args.tokenize() - def memory = task.memory ? "--limitGenomeGenerateRAM ${task.memory.toBytes() - 100000000}" : '' + def args = task.ext.args ?: '' + def args_list = args.tokenize() + def memory = task.memory ? "--limitGenomeGenerateRAM ${task.memory.toBytes() - 100000000}" : '' + def include_gtf = gtf ? "--sjdbGTFfile $gtf" : '' if (args_list.contains('--genomeSAindexNbases')) { """ mkdir star @@ -29,7 +30,7 @@ process STAR_GENOMEGENERATE { --runMode genomeGenerate \\ --genomeDir star/ \\ --genomeFastaFiles $fasta \\ - --sjdbGTFfile $gtf \\ + $include_gtf \\ --runThreadN $task.cpus \\ $memory \\ $args @@ -51,7 +52,7 @@ process STAR_GENOMEGENERATE { --runMode genomeGenerate \\ --genomeDir star/ \\ --genomeFastaFiles $fasta \\ - --sjdbGTFfile $gtf \\ + $include_gtf \\ --runThreadN $task.cpus \\ --genomeSAindexNbases \$NUM_BASES \\ $memory \\ @@ -67,30 +68,52 @@ process STAR_GENOMEGENERATE { } stub: - """ - mkdir star - touch star/Genome - touch star/Log.out - touch star/SA - touch star/SAindex - touch star/chrLength.txt - touch star/chrName.txt - touch star/chrNameLength.txt - touch star/chrStart.txt - touch star/exonGeTrInfo.tab - touch star/exonInfo.tab - touch star/geneInfo.tab - touch star/genomeParameters.txt - touch star/sjdbInfo.txt - touch star/sjdbList.fromGTF.out.tab - touch star/sjdbList.out.tab - touch star/transcriptInfo.tab + if (gtf) { + """ + mkdir star + touch star/Genome + touch star/Log.out + touch star/SA + touch star/SAindex + touch star/chrLength.txt + touch star/chrName.txt + touch star/chrNameLength.txt + touch star/chrStart.txt + touch star/exonGeTrInfo.tab + touch star/exonInfo.tab + touch star/geneInfo.tab + touch star/genomeParameters.txt + touch star/sjdbInfo.txt + touch star/sjdbList.fromGTF.out.tab + touch star/sjdbList.out.tab + touch star/transcriptInfo.tab - cat <<-END_VERSIONS > versions.yml - "${task.process}": - star: \$(STAR --version | sed -e "s/STAR_//g") - samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//') - gawk: \$(echo \$(gawk --version 2>&1) | sed 's/^.*GNU Awk //; s/, .*\$//') - END_VERSIONS - """ + 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 + """ + } else { + """ + mkdir star + touch star/Genome + touch star/Log.out + touch star/SA + touch star/SAindex + touch star/chrLength.txt + touch star/chrName.txt + touch star/chrNameLength.txt + touch star/chrStart.txt + touch star/genomeParameters.txt + + 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/genomegenerate/meta.yml b/modules/nf-core/star/genomegenerate/meta.yml index 1061e1b8d..39ed3cbde 100644 --- a/modules/nf-core/star/genomegenerate/meta.yml +++ b/modules/nf-core/star/genomegenerate/meta.yml @@ -14,37 +14,44 @@ tools: manual: https://github.com/alexdobin/STAR/blob/master/doc/STARmanual.pdf doi: 10.1093/bioinformatics/bts635 licence: ["MIT"] + identifier: biotools:star input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - fasta: - type: file - description: Fasta file of the reference genome - - meta2: - type: map - description: | - Groovy Map containing reference information - e.g. [ id:'test' ] - - gtf: - type: file - description: GTF file of the reference genome + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - fasta: + type: file + description: Fasta file of the reference genome + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'test' ] + - gtf: + type: file + description: GTF file of the reference genome + ontologies: [] output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - index: - type: directory - description: Folder containing the star index files - pattern: "star" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + index: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - star: + type: directory + description: Folder containing the star index files + pattern: "star" + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@kevinmenden" - "@drpatelh" diff --git a/modules/nf-core/star/genomegenerate/tests/main.nf.test b/modules/nf-core/star/genomegenerate/tests/main.nf.test index eed82926f..4d619c473 100644 --- a/modules/nf-core/star/genomegenerate/tests/main.nf.test +++ b/modules/nf-core/star/genomegenerate/tests/main.nf.test @@ -8,18 +8,18 @@ nextflow_process { tag "star" tag "star/genomegenerate" - test("homo_sapiens") { + test("fasta_gtf") { when { process { """ input[0] = Channel.of([ [ id:'test_fasta' ], - [file(params.test_data['homo_sapiens']['genome']['genome_fasta'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] ]) input[1] = Channel.of([ [ id:'test_gtf' ], - [file(params.test_data['homo_sapiens']['genome']['genome_gtf'], checkIfExists: true)] + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] ]) """ } @@ -28,11 +28,87 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(file(process.out.index[0][1]).name).match("index") }, - { assert snapshot(process.out.versions).match("versions") } + { assert snapshot( + file(process.out.index[0][1]).listFiles().collect { it.getName() }.sort().toString(), + process.out.versions) + .match() } ) } + } + + test("fasta") { + when { + process { + """ + input[0] = Channel.of([ + [ id:'test_fasta' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[1] = Channel.of([ [], [] ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + file(process.out.index[0][1]).listFiles().collect { it.getName() }.sort().toString(), + process.out.versions + ).match() } + ) + } } -} \ No newline at end of file + test("fasta_gtf_stub") { + + options '-stub' + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test_fasta' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[1] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("fasta_stub") { + + options '-stub' + + when { + process { + """ + input[0] = Channel.of([ + [ id:'test_fasta' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[1] = Channel.of([ [], [] ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/nf-core/star/genomegenerate/tests/main.nf.test.snap b/modules/nf-core/star/genomegenerate/tests/main.nf.test.snap index bd4e0caa6..b79da991d 100644 --- a/modules/nf-core/star/genomegenerate/tests/main.nf.test.snap +++ b/modules/nf-core/star/genomegenerate/tests/main.nf.test.snap @@ -1,16 +1,148 @@ { - "versions": { + "fasta_gtf": { "content": [ + "[Genome, Log.out, SA, SAindex, chrLength.txt, chrName.txt, chrNameLength.txt, chrStart.txt, exonGeTrInfo.tab, exonInfo.tab, geneInfo.tab, genomeParameters.txt, sjdbInfo.txt, sjdbList.fromGTF.out.tab, sjdbList.out.tab, transcriptInfo.tab]", [ - "versions.yml:md5,9c11319b80fdedc90dadce4e0fb42ded" + "versions.yml:md5,0c6c5fab50cc8601f9072268a2f49aad" ] ], - "timestamp": "2023-11-23T11:18:14.835118" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T16:29:40.748676908" }, - "index": { + "fasta_gtf_stub": { "content": [ - "star" + { + "0": [ + [ + { + "id": "test_fasta" + }, + [ + "Genome:md5,d41d8cd98f00b204e9800998ecf8427e", + "Log.out:md5,d41d8cd98f00b204e9800998ecf8427e", + "SA:md5,d41d8cd98f00b204e9800998ecf8427e", + "SAindex:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrLength.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrName.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrNameLength.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrStart.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "exonGeTrInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "exonInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "geneInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "genomeParameters.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "sjdbInfo.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "sjdbList.fromGTF.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "sjdbList.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "transcriptInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + "versions.yml:md5,0c6c5fab50cc8601f9072268a2f49aad" + ], + "index": [ + [ + { + "id": "test_fasta" + }, + [ + "Genome:md5,d41d8cd98f00b204e9800998ecf8427e", + "Log.out:md5,d41d8cd98f00b204e9800998ecf8427e", + "SA:md5,d41d8cd98f00b204e9800998ecf8427e", + "SAindex:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrLength.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrName.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrNameLength.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrStart.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "exonGeTrInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "exonInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "geneInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "genomeParameters.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "sjdbInfo.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "sjdbList.fromGTF.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "sjdbList.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "transcriptInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions": [ + "versions.yml:md5,0c6c5fab50cc8601f9072268a2f49aad" + ] + } ], - "timestamp": "2023-11-23T11:31:47.560528" + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T16:30:11.024076742" + }, + "fasta_stub": { + "content": [ + { + "0": [ + [ + { + "id": "test_fasta" + }, + [ + "Genome:md5,d41d8cd98f00b204e9800998ecf8427e", + "Log.out:md5,d41d8cd98f00b204e9800998ecf8427e", + "SA:md5,d41d8cd98f00b204e9800998ecf8427e", + "SAindex:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrLength.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrName.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrNameLength.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrStart.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "genomeParameters.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "1": [ + "versions.yml:md5,0c6c5fab50cc8601f9072268a2f49aad" + ], + "index": [ + [ + { + "id": "test_fasta" + }, + [ + "Genome:md5,d41d8cd98f00b204e9800998ecf8427e", + "Log.out:md5,d41d8cd98f00b204e9800998ecf8427e", + "SA:md5,d41d8cd98f00b204e9800998ecf8427e", + "SAindex:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrLength.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrName.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrNameLength.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrStart.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "genomeParameters.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + "versions": [ + "versions.yml:md5,0c6c5fab50cc8601f9072268a2f49aad" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T16:30:22.674364031" + }, + "fasta": { + "content": [ + "[Genome, Log.out, SA, SAindex, chrLength.txt, chrName.txt, chrNameLength.txt, chrStart.txt, genomeParameters.txt]", + [ + "versions.yml:md5,0c6c5fab50cc8601f9072268a2f49aad" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T16:29:57.958812354" } } \ No newline at end of file diff --git a/modules/nf-core/star/genomegenerate/tests/tags.yml b/modules/nf-core/star/genomegenerate/tests/tags.yml deleted file mode 100644 index 79f619bfe..000000000 --- a/modules/nf-core/star/genomegenerate/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -star/genomegenerate: - - modules/nf-core/star/genomegenerate/** diff --git a/modules/nf-core/starfusion/build/environment.yml b/modules/nf-core/starfusion/build/environment.yml new file mode 100644 index 000000000..f62e01ff4 --- /dev/null +++ b/modules/nf-core/starfusion/build/environment.yml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::dfam=3.7 + - bioconda::hmmer=3.4 + - bioconda::minimap2=2.30 + - bioconda::star-fusion=1.15.1 diff --git a/modules/nf-core/starfusion/build/main.nf b/modules/nf-core/starfusion/build/main.nf new file mode 100644 index 000000000..33882c082 --- /dev/null +++ b/modules/nf-core/starfusion/build/main.nf @@ -0,0 +1,148 @@ +process STARFUSION_BUILD { + tag "$meta.id" + label 'process_high' + stageInMode 'copy' + + 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/75/75d085bf2a8e40c6693b357800eef0f9568f661226d0888339bc77f7852234bb/data' : + 'community.wave.seqera.io/library/dfam_hmmer_minimap2_star-fusion:e285bb3eb373b9a7'}" + + input: + tuple val(meta), path(fasta) + tuple val(meta2), path(gtf) + path fusion_annot_lib + val dfam_species + path pfam_url + path dfam_urls, arity: '5' + path annot_filter_url + + output: + tuple val(meta), path("${prefix}_genome_lib_build_dir"), emit: reference + 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 VERSION = '1.15.1' // WARN: This is the actual version of the STAR-FUSION, but version information of tool is not updated and prints '1.15.0' + """ + gunzip ${pfam_url} && hmmpress Pfam-A.hmm + + prep_genome_lib.pl \\ + --genome_fa $fasta \\ + --gtf $gtf \\ + --dfam_db *_dfam.hmm \\ + --pfam_db Pfam-A.hmm \\ + --fusion_annot_lib $fusion_annot_lib \\ + --annot_filter_rule ${annot_filter_url} \\ + --CPU $task.cpus \\ + --output_dir ${prefix}_genome_lib_build_dir \\ + ${args} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + gunzip: \$(echo \$(gunzip --version 2>&1) | sed 's/^.*(gzip) //; s/ Copyright.*\$//') + hmmer: \$(echo \$(hmmpress -h | grep HMMER | sed 's/# HMMER //' | sed 's/ .*//' 2>&1)) + STAR-Fusion: $VERSION + END_VERSIONS + """ + + stub: + prefix = task.ext.prefix ?: "${meta.id}" + def VERSION = '1.15.1' // WARN: This is the actual version of the STAR-FUSION, but version information of tool is not updated and prints '1.15.0' + """ + mkdir -p ${prefix}_genome_lib_build_dir + + touch ${prefix}_genome_lib_build_dir/AnnotFilterRule.pm + echo | gzip > ${prefix}_genome_lib_build_dir/blast_pairs.dat.gz + touch ${prefix}_genome_lib_build_dir/blast_pairs.idx + + mkdir -p ${prefix}_genome_lib_build_dir/__chkpts + touch ${prefix}_genome_lib_build_dir/__chkpts/annotfiltrule_cp.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/blast_pairs.idx.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/cp_gene_blast_pairs.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/cp_pfam_dat.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/cp_ref_annot_cdna.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/fusion_annot_lib.cp.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/_fusion_annot_lib.idx.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/index_pfam_hits.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/index_ref_annot_cdna.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/makeblastdb.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/mm2_genome_idx.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/mm2.splice_bed.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/_prot_info_db.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.cp.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.idx.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/ref_annot.gtf.gene_spans.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/ref_annot.gtf.mini.sortu.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/ref_annot.gtf.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/ref_genome_fai.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/ref_genome.fa.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/trans.blast.dat.cp.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/trans.blast.dat.index.ok + touch ${prefix}_genome_lib_build_dir/__chkpts/validate_ctat_genome_lib.ok + + echo | gzip > ${prefix}_genome_lib_build_dir/fusion_annot_lib.gz + touch ${prefix}_genome_lib_build_dir/fusion_annot_lib.idx + touch ${prefix}_genome_lib_build_dir/pfam_domains.dbm + echo | gzip > ${prefix}_genome_lib_build_dir/PFAM.domtblout.dat.gz + + touch ${prefix}_genome_lib_build_dir/ref_annot.cdna.fa + touch ${prefix}_genome_lib_build_dir/ref_annot.cdna.fa.idx + touch ${prefix}_genome_lib_build_dir/ref_annot.cds + touch ${prefix}_genome_lib_build_dir/ref_annot.cdsplus.fa + touch ${prefix}_genome_lib_build_dir/ref_annot.cdsplus.fa.idx + touch ${prefix}_genome_lib_build_dir/ref_annot.gtf + touch ${prefix}_genome_lib_build_dir/ref_annot.gtf.gene_spans + touch ${prefix}_genome_lib_build_dir/ref_annot.gtf.mini.sortu + touch ${prefix}_genome_lib_build_dir/ref_annot.gtf.mm2.splice.bed + touch ${prefix}_genome_lib_build_dir/ref_annot.pep + touch ${prefix}_genome_lib_build_dir/ref_annot.prot_info.dbm + + touch ${prefix}_genome_lib_build_dir/ref_genome.fa + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.fai + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.mm2 + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.ndb + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.nhr + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.nin + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.njs + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.not + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.nsq + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.ntf + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.nto + + mkdir -p ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/build.ok + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/chrLength.txt + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/chrNameLength.txt + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/chrName.txt + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/chrStart.txt + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/exonGeTrInfo.tab + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/exonInfo.tab + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/geneInfo.tab + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/Genome + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/genomeParameters.txt + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/Log.out + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/SA + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/SAindex + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbInfo.txt + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.fromGTF.out.tab + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.out.tab + touch ${prefix}_genome_lib_build_dir/ref_genome.fa.star.idx/transcriptInfo.tab + + touch ${prefix}_genome_lib_build_dir/trans.blast.align_coords.align_coords.dat + touch ${prefix}_genome_lib_build_dir/trans.blast.align_coords.align_coords.dbm + echo | gzip > ${prefix}_genome_lib_build_dir/trans.blast.dat.gz + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + gunzip: \$(echo \$(gunzip --version 2>&1) | sed 's/^.*(gzip) //; s/ Copyright.*\$//') + hmmer: \$(echo \$(hmmpress -h | grep HMMER | sed 's/# HMMER //' | sed 's/ .*//' 2>&1)) + STAR-Fusion: $VERSION + END_VERSIONS + """ + +} diff --git a/modules/nf-core/starfusion/build/meta.yml b/modules/nf-core/starfusion/build/meta.yml new file mode 100644 index 000000000..c7c98bf1e --- /dev/null +++ b/modules/nf-core/starfusion/build/meta.yml @@ -0,0 +1,74 @@ +name: starfusion_build +description: Download STAR-fusion genome resource required to run STAR-Fusion caller +keywords: + - download + - starfusion + - build + +tools: + - star-fusion: + description: Fusion calling algorithm for RNAseq data + homepage: https://github.com/STAR-Fusion/ + documentation: https://github.com/STAR-Fusion/STAR-Fusion/wiki/installing-star-fusion + tool_dev_url: https://github.com/STAR-Fusion/STAR-Fusion + doi: "10.1186/s13059-019-1842-9" + licence: ["GPL v3"] + identifier: "" + +input: + - - meta: + type: map + description: Metadata map + required: true + - fasta: + type: file + description: Input FASTA file + pattern: "*.{fa,fasta}" + required: true + ontologies: + - edam: http://edamontology.org/format_1929 # FASTA + - - meta2: + type: map + description: Second metadata map + required: true + - gtf: + type: file + description: Input GTF (Gene Transfer Format) file + pattern: "*.gtf" + required: true + ontologies: + - edam: "http://edamontology.org/format_2306" # GTF + - fusion_annot_lib: + type: file + description: Fusion annotation library file containing known fusion genes + required: true + ontologies: + - edam: "http://edamontology.org/topic_0203" # Gene fusion + - dfam_species: + type: string + description: Dfam species name +output: + reference: + - - meta: + type: map + description: Metadata map + - ${prefix}_genome_lib_build_dir: + type: directory + description: Genome library build directory + pattern: "*_genome_lib_build_dir" + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@praveenraj2018" + - "@martings" + - "@alanmmobbs93" + - "@delfiterradas" + - "@sofiromano" + +maintainers: + - "@praveenraj2018" diff --git a/modules/nf-core/starfusion/build/tests/main.nf.test b/modules/nf-core/starfusion/build/tests/main.nf.test new file mode 100644 index 000000000..2fa9f044c --- /dev/null +++ b/modules/nf-core/starfusion/build/tests/main.nf.test @@ -0,0 +1,188 @@ +nextflow_process { + name "Test Process STARFUSION_BUILD" + script "../main.nf" + process "STARFUSION_BUILD" + tag "modules" + tag "modules_nfcore" + tag "starfusion" + tag "starfusion/build" + tag "fusioninspector" + + test("STARFUSION_BUILD - human - minigenome") { + when { + process { + """ + input[0] = [ + [ id:'minigenome_fasta' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/minigenome.fa') + ] + input[1] = [ + [ id:'minigenome_gtf' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/minigenome.gtf') + ] + + input[2] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/CTAT_HumanFusionLib.mini.dat.gz') + input[3] = "homo_sapiens" + input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/Pfam-A.hmm.gz') + input[5] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3f'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3i'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3m'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3p') + ] + input[6] = "https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/AnnotFilterRule.pm" + """ + } + } + + then { + def outputDir = file(process.out.reference[0][1]) + assert snapshot( + path(process.out.reference[0][1]).resolve("AnnotFilterRule.pm"), + file("$outputDir/blast_pairs.dat.gz").name, + file("$outputDir/blast_pairs.idx").name, + file("$outputDir/__chkpts/annotfiltrule_cp.ok").name, + file("$outputDir/__chkpts/blast_pairs.idx.ok").name, + file("$outputDir/__chkpts/cp_gene_blast_pairs.ok").name, + file("$outputDir/__chkpts/cp_pfam_dat.ok").name, + file("$outputDir/__chkpts/cp_ref_annot_cdna.ok").name, + file("$outputDir/__chkpts/fusion_annot_lib.cp.ok").name, + file("$outputDir/__chkpts/_fusion_annot_lib.idx.ok").name, + file("$outputDir/__chkpts/index_pfam_hits.ok").name, + file("$outputDir/__chkpts/index_ref_annot_cdna.ok").name, + file("$outputDir/__chkpts/makeblastdb.ok").name, + file("$outputDir/__chkpts/mm2_genome_idx.ok").name, + file("$outputDir/__chkpts/mm2.splice_bed.ok").name, + file("$outputDir/__chkpts/_prot_info_db.ok").name, + file("$outputDir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.cp.ok").name, + file("$outputDir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.idx.ok").name, + file("$outputDir/__chkpts/ref_annot.gtf.gene_spans.ok").name, + file("$outputDir/__chkpts/ref_annot.gtf.mini.sortu.ok").name, + file("$outputDir/__chkpts/ref_annot.gtf.ok").name, + file("$outputDir/__chkpts/ref_genome_fai.ok").name, + file("$outputDir/__chkpts/ref_genome.fa.ok").name, + file("$outputDir/__chkpts/trans.blast.dat.cp.ok").name, + file("$outputDir/__chkpts/trans.blast.dat.index.ok").name, + file("$outputDir/__chkpts/validate_ctat_genome_lib.ok").name, + path(process.out.reference[0][1]).resolve("fusion_annot_lib.gz"), + file("$outputDir/fusion_annot_lib.idx").name, + file("$outputDir/pfam_domains.dbm").name, + file("$outputDir/PFAM.domtblout.dat.gz").name, + file("$outputDir/ref_annot.cdna.fa").name, + file("$outputDir/ref_annot.cdna.fa.idx").name, + file("$outputDir/ref_annot.cds").name, + file("$outputDir/ref_annot.cdsplus.fa").name, + file("$outputDir/ref_annot.cdsplus.fa.idx").name, + path(process.out.reference[0][1]).resolve("ref_annot.gtf"), + file("$outputDir/ref_annot.gtf.gene_spans").name, + path(process.out.reference[0][1]).resolve("ref_annot.gtf.mini.sortu"), + path(process.out.reference[0][1]).resolve("ref_annot.gtf.mm2.splice.bed"), + file("$outputDir/ref_annot.pep").name, + file("$outputDir/ref_annot.prot_info.dbm").name, + path(process.out.reference[0][1]).resolve("ref_genome.fa"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.fai"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.mm2"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.ndb"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.nhr"), + file("$outputDir/ref_genome.fa.nin").name, + file("$outputDir/ref_genome.fa.njs").name, + path(process.out.reference[0][1]).resolve("ref_genome.fa.not"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.nsq"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.ntf"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.nto"), + file("$outputDir/ref_genome.fa.star.idx").name, + file("$outputDir/ref_genome.fa.star.idx/build.ok").name, + path(process.out.reference[0][1]).resolve("ref_genome.fa.star.idx/chrLength.txt"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.star.idx/chrNameLength.txt"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.star.idx/chrName.txt"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.star.idx/chrStart.txt"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.star.idx/exonGeTrInfo.tab"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.star.idx/exonInfo.tab"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.star.idx/geneInfo.tab"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.star.idx/Genome"), + file("$outputDir/ref_genome.fa.star.idx/genomeParameters.txt").name, + file("$outputDir/ref_genome.fa.star.idx/Log.out").name, + path(process.out.reference[0][1]).resolve("ref_genome.fa.star.idx/SA"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.star.idx/SAindex"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.star.idx/sjdbInfo.txt"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.star.idx/sjdbList.fromGTF.out.tab"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.star.idx/sjdbList.out.tab"), + path(process.out.reference[0][1]).resolve("ref_genome.fa.star.idx/transcriptInfo.tab"), + path(process.out.reference[0][1]).resolve("trans.blast.align_coords.align_coords.dat"), + file("$outputDir/trans.blast.align_coords.align_coords.dbm").name, + path(process.out.reference[0][1]).resolve("trans.blast.dat.gz"), + process.out.versions + ).match() + } + } + + test("STARFUSION_BUILD - human - minigenome - stub") { + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'minigenome_fasta' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/minigenome.fa') + ] + input[1] = [ + [ id:'minigenome_gtf' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/minigenome.gtf') + ] + + input[2] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/CTAT_HumanFusionLib.mini.dat.gz') + input[3] = "homo_sapiens" + input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/Pfam-A.hmm.gz') + input[5] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3f'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3i'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3m'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3p') + ] + input[6] = "https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/AnnotFilterRule.pm" + """ + } + } + + then { + assert snapshot(process.out).match() + } + } + + test("STARFUSION_BUILD - stub - fail") { + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'minigenome_fasta' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/minigenome.fa') + ] + input[1] = [ + [ id:'minigenome_gtf' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/minigenome.gtf') + ] + + input[2] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/CTAT_HumanFusionLib.mini.dat.gz') + input[3] = "homo_sapiens" + input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/Pfam-A.hmm.gz') + input[5] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3f'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3i'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3m') + ] + input[6] = "https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/AnnotFilterRule.pm" + """ + } + } + + then { + assert process.failed + } + } +} diff --git a/modules/nf-core/starfusion/build/tests/main.nf.test.snap b/modules/nf-core/starfusion/build/tests/main.nf.test.snap new file mode 100644 index 000000000..c26afe6ea --- /dev/null +++ b/modules/nf-core/starfusion/build/tests/main.nf.test.snap @@ -0,0 +1,274 @@ +{ + "STARFUSION_BUILD - human - minigenome": { + "content": [ + "AnnotFilterRule.pm:md5,f94966013cd0df9624a6dda0b75fefa0", + "blast_pairs.dat.gz", + "blast_pairs.idx", + "annotfiltrule_cp.ok", + "blast_pairs.idx.ok", + "cp_gene_blast_pairs.ok", + "cp_pfam_dat.ok", + "cp_ref_annot_cdna.ok", + "fusion_annot_lib.cp.ok", + "_fusion_annot_lib.idx.ok", + "index_pfam_hits.ok", + "index_ref_annot_cdna.ok", + "makeblastdb.ok", + "mm2_genome_idx.ok", + "mm2.splice_bed.ok", + "_prot_info_db.ok", + "ref_annot.cdsplus.dfam_masked.fa.cp.ok", + "ref_annot.cdsplus.dfam_masked.fa.idx.ok", + "ref_annot.gtf.gene_spans.ok", + "ref_annot.gtf.mini.sortu.ok", + "ref_annot.gtf.ok", + "ref_genome_fai.ok", + "ref_genome.fa.ok", + "trans.blast.dat.cp.ok", + "trans.blast.dat.index.ok", + "validate_ctat_genome_lib.ok", + "fusion_annot_lib.gz:md5,23d82a5da81f91ca4e1ecd6481992a12", + "fusion_annot_lib.idx", + "pfam_domains.dbm", + "PFAM.domtblout.dat.gz", + "ref_annot.cdna.fa", + "ref_annot.cdna.fa.idx", + "ref_annot.cds", + "ref_annot.cdsplus.fa", + "ref_annot.cdsplus.fa.idx", + "ref_annot.gtf:md5,5ce8afe99ef3940a877a04caeacf9181", + "ref_annot.gtf.gene_spans", + "ref_annot.gtf.mini.sortu:md5,1d29ccecdbb7b40a99c84a02d6c2c1be", + "ref_annot.gtf.mm2.splice.bed:md5,340585ea1843bf06bf555575ddecf28c", + "ref_annot.pep", + "ref_annot.prot_info.dbm", + "ref_genome.fa:md5,ad699c56ed38566c7d3e9579486b1706", + "ref_genome.fa.fai:md5,e3f74a27219b33ae80fd5de5cbeaf32b", + "ref_genome.fa.mm2:md5,ce50979ea284748eb9f84ae88cfd930e", + "ref_genome.fa.ndb:md5,6ea574753b557610f62f6e4ab79e19f5", + "ref_genome.fa.nhr:md5,50f28dae71683c4394bfaf94a1ef4392", + "ref_genome.fa.nin", + "ref_genome.fa.njs", + "ref_genome.fa.not:md5,1e53e9d08f1d23af0299cfa87478a7bb", + "ref_genome.fa.nsq:md5,d2361e7871ce4cf51181c112a48f191b", + "ref_genome.fa.ntf:md5,de1250813f0c7affc6d12dac9d0fb6bb", + "ref_genome.fa.nto:md5,33cdeccccebe80329f1fdbee7f5874cb", + "ref_genome.fa.star.idx", + "build.ok", + "chrLength.txt:md5,e02cd536b7281b894246863b160d5d06", + "chrNameLength.txt:md5,07a67d7ac441d7d30d80840b0927e717", + "chrName.txt:md5,f4d0d6595f423084e6b9472e40dfe6e8", + "chrStart.txt:md5,e2031239a74fe5ee9051e9364e4f608a", + "exonGeTrInfo.tab:md5,3c35618d07a8e35a0f9108699fcdda42", + "exonInfo.tab:md5,bcbb3f32fa31fe504cc737f337ad341c", + "geneInfo.tab:md5,db5db4b6e003904e9908fce7c05f0125", + "Genome:md5,9e3efdd0901cabb5a2d589664a63b372", + "genomeParameters.txt", + "Log.out", + "SA:md5,7dd9083264be9c6a2194d990bc10d237", + "SAindex:md5,ac4711df685109e04356db9e9cb9fb7f", + "sjdbInfo.txt:md5,e4cc1bbf8bd687cfc3d7c2c702e6def7", + "sjdbList.fromGTF.out.tab:md5,8f3e8604b00d4067e4eb80aa476a8113", + "sjdbList.out.tab:md5,5d78dd49d5db24ca2c056b7ebe5c2059", + "transcriptInfo.tab:md5,b758c0ccaddcf0453bab5905b3cec4a2", + "trans.blast.align_coords.align_coords.dat:md5,9f6b7a75aea03a9671190be25ecdd4c2", + "trans.blast.align_coords.align_coords.dbm", + "trans.blast.dat.gz:md5,85ba5ea96c566f751ad83a3e4b8ab128", + [ + "versions.yml:md5,8a4a70b89be13a4fae8eac764b62045c" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.5" + }, + "timestamp": "2025-07-04T14:34:34.16518489" + }, + "STARFUSION_BUILD - human - minigenome - stub": { + "content": [ + { + "0": [ + [ + { + "id": "minigenome_fasta" + }, + [ + "AnnotFilterRule.pm:md5,d41d8cd98f00b204e9800998ecf8427e", + "PFAM.domtblout.dat.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + [ + "_fusion_annot_lib.idx.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "_prot_info_db.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "annotfiltrule_cp.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "blast_pairs.idx.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "cp_gene_blast_pairs.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "cp_pfam_dat.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "cp_ref_annot_cdna.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "fusion_annot_lib.cp.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "index_pfam_hits.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "index_ref_annot_cdna.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "makeblastdb.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "mm2.splice_bed.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "mm2_genome_idx.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdsplus.dfam_masked.fa.cp.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdsplus.dfam_masked.fa.idx.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.gene_spans.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.mini.sortu.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome_fai.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "trans.blast.dat.cp.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "trans.blast.dat.index.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "validate_ctat_genome_lib.ok:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + "blast_pairs.dat.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "blast_pairs.idx:md5,d41d8cd98f00b204e9800998ecf8427e", + "fusion_annot_lib.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "fusion_annot_lib.idx:md5,d41d8cd98f00b204e9800998ecf8427e", + "pfam_domains.dbm:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdna.fa:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdna.fa.idx:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cds:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdsplus.fa:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdsplus.fa.idx:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.gene_spans:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.mini.sortu:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.mm2.splice.bed:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.pep:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.prot_info.dbm:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.fai:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.mm2:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.ndb:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.nhr:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.nin:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.njs:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.not:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.nsq:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.ntf:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.nto:md5,d41d8cd98f00b204e9800998ecf8427e", + [ + "Genome:md5,d41d8cd98f00b204e9800998ecf8427e", + "Log.out:md5,d41d8cd98f00b204e9800998ecf8427e", + "SA:md5,d41d8cd98f00b204e9800998ecf8427e", + "SAindex:md5,d41d8cd98f00b204e9800998ecf8427e", + "build.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrLength.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrName.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrNameLength.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrStart.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "exonGeTrInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "exonInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "geneInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "genomeParameters.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "sjdbInfo.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "sjdbList.fromGTF.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "sjdbList.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "transcriptInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + "trans.blast.align_coords.align_coords.dat:md5,d41d8cd98f00b204e9800998ecf8427e", + "trans.blast.align_coords.align_coords.dbm:md5,d41d8cd98f00b204e9800998ecf8427e", + "trans.blast.dat.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + "versions.yml:md5,8a4a70b89be13a4fae8eac764b62045c" + ], + "reference": [ + [ + { + "id": "minigenome_fasta" + }, + [ + "AnnotFilterRule.pm:md5,d41d8cd98f00b204e9800998ecf8427e", + "PFAM.domtblout.dat.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + [ + "_fusion_annot_lib.idx.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "_prot_info_db.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "annotfiltrule_cp.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "blast_pairs.idx.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "cp_gene_blast_pairs.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "cp_pfam_dat.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "cp_ref_annot_cdna.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "fusion_annot_lib.cp.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "index_pfam_hits.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "index_ref_annot_cdna.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "makeblastdb.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "mm2.splice_bed.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "mm2_genome_idx.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdsplus.dfam_masked.fa.cp.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdsplus.dfam_masked.fa.idx.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.gene_spans.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.mini.sortu.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome_fai.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "trans.blast.dat.cp.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "trans.blast.dat.index.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "validate_ctat_genome_lib.ok:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + "blast_pairs.dat.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "blast_pairs.idx:md5,d41d8cd98f00b204e9800998ecf8427e", + "fusion_annot_lib.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "fusion_annot_lib.idx:md5,d41d8cd98f00b204e9800998ecf8427e", + "pfam_domains.dbm:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdna.fa:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdna.fa.idx:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cds:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdsplus.fa:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdsplus.fa.idx:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.gene_spans:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.mini.sortu:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.mm2.splice.bed:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.pep:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.prot_info.dbm:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.fai:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.mm2:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.ndb:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.nhr:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.nin:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.njs:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.not:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.nsq:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.ntf:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.nto:md5,d41d8cd98f00b204e9800998ecf8427e", + [ + "Genome:md5,d41d8cd98f00b204e9800998ecf8427e", + "Log.out:md5,d41d8cd98f00b204e9800998ecf8427e", + "SA:md5,d41d8cd98f00b204e9800998ecf8427e", + "SAindex:md5,d41d8cd98f00b204e9800998ecf8427e", + "build.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrLength.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrName.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrNameLength.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrStart.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "exonGeTrInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "exonInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "geneInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "genomeParameters.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "sjdbInfo.txt:md5,d41d8cd98f00b204e9800998ecf8427e", + "sjdbList.fromGTF.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "sjdbList.out.tab:md5,d41d8cd98f00b204e9800998ecf8427e", + "transcriptInfo.tab:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + "trans.blast.align_coords.align_coords.dat:md5,d41d8cd98f00b204e9800998ecf8427e", + "trans.blast.align_coords.align_coords.dbm:md5,d41d8cd98f00b204e9800998ecf8427e", + "trans.blast.dat.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "versions": [ + "versions.yml:md5,8a4a70b89be13a4fae8eac764b62045c" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.5" + }, + "timestamp": "2025-07-04T14:35:41.16179905" + } +} \ No newline at end of file diff --git a/modules/nf-core/starfusion/detect/environment.yml b/modules/nf-core/starfusion/detect/environment.yml new file mode 100644 index 000000000..f62e01ff4 --- /dev/null +++ b/modules/nf-core/starfusion/detect/environment.yml @@ -0,0 +1,8 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::dfam=3.7 + - bioconda::hmmer=3.4 + - bioconda::minimap2=2.30 + - bioconda::star-fusion=1.15.1 diff --git a/modules/nf-core/starfusion/detect/main.nf b/modules/nf-core/starfusion/detect/main.nf new file mode 100644 index 000000000..acec416a4 --- /dev/null +++ b/modules/nf-core/starfusion/detect/main.nf @@ -0,0 +1,62 @@ +process STARFUSION_DETECT { + 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/75/75d085bf2a8e40c6693b357800eef0f9568f661226d0888339bc77f7852234bb/data' : + 'community.wave.seqera.io/library/dfam_hmmer_minimap2_star-fusion:e285bb3eb373b9a7'}" + + input: + tuple val(meta), path(reads), path(junction) + path reference + + output: + tuple val(meta), path("*.fusion_predictions.tsv"), emit: fusions + tuple val(meta), path("*.abridged.tsv") , emit: abridged + tuple val(meta), path("*.coding_effect.tsv") , emit: coding_effect, optional: true + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def prefix = task.ext.prefix ?: "${meta.id}.starfusion" + def fastq_arg = reads ? (meta.single_end ? "--left_fq ${reads[0]}" : "--left_fq ${reads[0]} --right_fq ${reads[1]}") : "" + def junction_arg = junction ? "-J ${junction}" : "" + def args = task.ext.args ?: '' + def VERSION = '1.15.1' // WARN: This is the actual version of the STAR-FUSION, but version information of tool is not updated and prints '1.15.0' + """ + STAR-Fusion \\ + --genome_lib_dir $reference \\ + $fastq_arg \\ + $junction_arg \\ + --CPU $task.cpus \\ + --output_dir . \\ + $args + + mv star-fusion.fusion_predictions.tsv ${prefix}.fusion_predictions.tsv + mv star-fusion.fusion_predictions.abridged.tsv ${prefix}.abridged.tsv + if [ -f star-fusion.fusion_predictions.abridged.coding_effect.tsv ]; then + mv star-fusion.fusion_predictions.abridged.coding_effect.tsv ${prefix}.abridged.coding_effect.tsv + fi + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + STAR-Fusion: $VERSION + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}.starfusion" + def VERSION = '1.15.1' + """ + touch ${prefix}.fusion_predictions.tsv + touch ${prefix}.abridged.tsv + touch ${prefix}.abridged.coding_effect.tsv + cat <<-END_VERSIONS > versions.yml + "${task.process}": + STAR-Fusion: $VERSION + END_VERSIONS + """ +} diff --git a/modules/nf-core/starfusion/detect/meta.yml b/modules/nf-core/starfusion/detect/meta.yml new file mode 100644 index 000000000..455981efe --- /dev/null +++ b/modules/nf-core/starfusion/detect/meta.yml @@ -0,0 +1,80 @@ +name: starfusion_detect +description: Fast and Accurate Fusion Transcript Detection from RNA-Seq +keywords: + - Fusion + - starfusion + - RNA-Seq + - detect +tools: + - star-fusion: + description: Fast and Accurate Fusion Transcript Detection from RNA-Seq + homepage: https://github.com/STAR-Fusion/STAR-Fusion + documentation: https://github.com/STAR-Fusion/STAR-Fusion/wiki + tool_dev_url: https://github.com/STAR-Fusion/STAR-Fusion/releases + doi: "10.1101/120295v1" + licence: ["GPL v3"] + identifier: "" + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: Input fastq files + pattern: "*.{fq,fastq,fq.gz,fastq.gz}" + ontologies: + - edam: "http://edamontology.org/format_1930" # FASTQ + - junction: + type: file + description: Chimeric junction output from STAR aligner + pattern: "*.{out.junction}" + ontologies: [] + - reference: + type: directory + description: STAR-fusion reference genome lib folder + pattern: "*genome_lib_build_dir" + +output: + fusions: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.fusion_predictions.tsv": + type: file + description: Fusion events from STAR-fusion + pattern: "*.{fusion_predictions.tsv}" + abridged: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.abridged.tsv": + type: file + description: Abridged version of fusion events from STAR-fusion + pattern: "*.{fusion.abridged.tsv}" + coding_effect: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.coding_effect.tsv": + type: file + description: Fusion events with their coding effect from STAR-fusion + pattern: "*.{coding_effect.tsv}" + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: "http://edamontology.org/format_3750" # YAML + +authors: + - "@praveenraj2018" diff --git a/modules/nf-core/starfusion/detect/tests/main.nf.test b/modules/nf-core/starfusion/detect/tests/main.nf.test new file mode 100644 index 000000000..7c2c24d68 --- /dev/null +++ b/modules/nf-core/starfusion/detect/tests/main.nf.test @@ -0,0 +1,148 @@ +nextflow_process { + + name "Test Process STARFUSION_DETECT" + script "../main.nf" + process "STARFUSION_DETECT" + tag "modules_nfcore" + tag "starfusion/build" + tag "starfusion" + tag "starfusion/detect" + tag "modules" + config "./nextflow.config" + + setup { + run("STARFUSION_BUILD") { + script "../../../../nf-core/starfusion/build/main.nf" + process { + """ + input[0] = [ + [ id:'minigenome_fasta' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/minigenome.fa') + ] + input[1] = [ + [ id:'minigenome_gtf' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/minigenome.gtf') + ] + + input[2] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/CTAT_HumanFusionLib.mini.dat.gz') + input[3] = "homo_sapiens" + input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/Pfam-A.hmm.gz') + input[5] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3f'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3i'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3m'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_dfam.hmm.h3p') + ] + input[6] = "https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/AnnotFilterRule.pm" + """ + } + } + } + + test("Paired end - Should run without failures") { + + when { + params { + starfusion_detect_args = "--examine_coding_effect" + } + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_rnaseq_1.fastq.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_rnaseq_2.fastq.gz') + ], // reads + [] // empty list for junction, as we don't have a pre-computed Chimeric.out.junction file + ] + input[1] = STARFUSION_BUILD.out.reference.map { it[1] } + """ + } + } + + then { + assert process.success + assert snapshot( + process.out.fusions, + process.out.abridged, + process.out.versions, + process.out.coding_effect.collect { meta, tsv -> + [meta, path(tsv).readLines().collect { line -> + line.split('\t')[0] // Get first column (tab-separated) + }] + } + ).match() + } + + } + + test("Single end - Should run without failures") { + tag "single" + when { + params { + starfusion_detect_args = "--examine_coding_effect" + } + process { + """ + input[0] = [ + [ id:'test', single_end:true ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_rnaseq_1.fastq.gz') + ], // reads + [] // empty list for junction, as we don't have a pre-computed Chimeric.out.junction file + ] + input[1] = STARFUSION_BUILD.out.reference.map { it[1] } + """ + } + } + + then { + assert process.success + assert snapshot( + process.out.fusions, + process.out.abridged, + process.out.versions, + process.out.coding_effect.collect { meta, tsv -> + [meta, path(tsv).readLines().collect { line -> + line.split('\t')[0] // Get first column (tab-separated) + }] + } + ).match() + } + + } + + test("Should create stub files") { + + options "-stub" + + when { + params { + starfusion_detect_args = "--examine_coding_effect" + } + process { + """ + input[0] = [ + [ id:'test_stub', single_end:false ], + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_rnaseq_1.fastq.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/test_starfusion_rnaseq_2.fastq.gz') + ], + [] // empty list for junction + ] + input[1] = STARFUSION_BUILD.out.reference.map { it[1] } + """ + } + } + + then { + assert process.success + assert snapshot( + process.out + ).match() + } + + } + +} \ No newline at end of file diff --git a/modules/nf-core/starfusion/detect/tests/main.nf.test.snap b/modules/nf-core/starfusion/detect/tests/main.nf.test.snap new file mode 100644 index 000000000..b497edcff --- /dev/null +++ b/modules/nf-core/starfusion/detect/tests/main.nf.test.snap @@ -0,0 +1,197 @@ +{ + "Should create stub files": { + "content": [ + { + "0": [ + [ + { + "id": "test_stub", + "single_end": false + }, + "test_stub.starfusion.fusion_predictions.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test_stub", + "single_end": false + }, + "test_stub.starfusion.abridged.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test_stub", + "single_end": false + }, + "test_stub.starfusion.abridged.coding_effect.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,a21fed36ad3c5144d6a06d48d34f5a2b" + ], + "abridged": [ + [ + { + "id": "test_stub", + "single_end": false + }, + "test_stub.starfusion.abridged.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "coding_effect": [ + [ + { + "id": "test_stub", + "single_end": false + }, + "test_stub.starfusion.abridged.coding_effect.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fusions": [ + [ + { + "id": "test_stub", + "single_end": false + }, + "test_stub.starfusion.fusion_predictions.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,a21fed36ad3c5144d6a06d48d34f5a2b" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-07-29T17:50:20.401704096" + }, + "Paired end - Should run without failures": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.starfusion.fusion_predictions.tsv:md5,82834fffed743afe07da82bd56d50c99" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.starfusion.abridged.tsv:md5,d6d20fdd4b5cba21b9c0ebf8e0ea19ff" + ] + ], + [ + "versions.yml:md5,a21fed36ad3c5144d6a06d48d34f5a2b" + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "#FusionName", + "TATDN1--GSDMB", + "ACACA--STAC2", + "TATDN1--GSDMB", + "CCDC6--RET", + "TOB1--SYNRG", + "TATDN1--GSDMB", + "BCAS4--BCAS3", + "RPS6KB1--SNF8", + "BAG6--SLC44A4", + "BCR--ABL1", + "VAPB--IKZF3", + "CYTH1--EIF3H", + "RAB22A--MYO9B", + "RARA--PKIA", + "ARFGEF2--SULF2", + "SUMF1--LRRFIP2", + "ANKHD1--PCDH1", + "MED1--ACSF2", + "AHCTF1--NAAA", + "MED1--STXBP4", + "BCAS4--BCAS3", + "ZMYND8--CEP250", + "AC007562.1--AC012005.2", + "VAPB--IKZF3", + "SUMF1--LRRFIP2", + "ZMYND8--CEP250", + "RARA--PKIA", + "CYTH1--EIF3H", + "MED13--BCAS3", + "VAPB--IKZF3" + ] + ] + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-07-29T17:14:52.628015363" + }, + "Single end - Should run without failures": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.starfusion.fusion_predictions.tsv:md5,62edb2285932b5afd88f6aba7d4ebdd1" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.starfusion.abridged.tsv:md5,4f76c050e3b012320b5e526f7076ffb8" + ] + ], + [ + "versions.yml:md5,a21fed36ad3c5144d6a06d48d34f5a2b" + ], + [ + [ + { + "id": "test", + "single_end": true + }, + [ + "#FusionName", + "CCDC6--RET", + "TATDN1--GSDMB", + "TOB1--SYNRG", + "ACACA--STAC2", + "TATDN1--GSDMB", + "BAG6--SLC44A4", + "TATDN1--GSDMB", + "RARA--PKIA", + "AC007562.1--AC012005.2", + "SUMF1--LRRFIP2", + "RAB22A--MYO9B", + "BCR--ABL1" + ] + ] + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-07-29T17:42:24.763176482" + } +} \ No newline at end of file diff --git a/modules/nf-core/starfusion/detect/tests/nextflow.config b/modules/nf-core/starfusion/detect/tests/nextflow.config new file mode 100644 index 000000000..dd8a78dba --- /dev/null +++ b/modules/nf-core/starfusion/detect/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'STARFUSION_DETECT' { + ext.args = params.starfusion_detect_args + } +} diff --git a/modules/nf-core/stringtie/merge/environment.yml b/modules/nf-core/stringtie/merge/environment.yml index 9914b2025..ef1f3d0e1 100644 --- a/modules/nf-core/stringtie/merge/environment.yml +++ b/modules/nf-core/stringtie/merge/environment.yml @@ -1,7 +1,7 @@ -name: stringtie_merge +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults dependencies: - bioconda::stringtie=2.2.1 diff --git a/modules/nf-core/stringtie/merge/meta.yml b/modules/nf-core/stringtie/merge/meta.yml index 5d02d6786..3201746c2 100644 --- a/modules/nf-core/stringtie/merge/meta.yml +++ b/modules/nf-core/stringtie/merge/meta.yml @@ -11,27 +11,34 @@ tools: homepage: https://ccb.jhu.edu/software/stringtie/index.shtml documentation: https://ccb.jhu.edu/software/stringtie/index.shtml?t=manual licence: ["MIT"] + identifier: biotools:stringtie input: - stringtie_gtf: type: file description: | Stringtie transcript gtf output(s). pattern: "*.gtf" + ontologies: [] - annotation_gtf: type: file description: | Annotation gtf file (optional). pattern: "*.gtf" + ontologies: [] output: - - merged_gtf: - type: map - description: | - Merged gtf from annotation and stringtie output gtfs. - pattern: "*.gtf" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + gtf: + - stringtie.merged.gtf: + type: file + description: Merged gtf file + pattern: "stringtie.merged.gtf" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@yuukiiwa" maintainers: diff --git a/modules/nf-core/stringtie/merge/tests/main.nf.test b/modules/nf-core/stringtie/merge/tests/main.nf.test index 90368134b..bcc648bc7 100644 --- a/modules/nf-core/stringtie/merge/tests/main.nf.test +++ b/modules/nf-core/stringtie/merge/tests/main.nf.test @@ -7,30 +7,30 @@ nextflow_process { tag "modules_nfcore" tag "stringtie" tag "stringtie/merge" + tag "stringtie/stringtie" - test("homo_sapiens - forward strandedness") { - - setup { - run("STRINGTIE_STRINGTIE") { - script "../../stringtie/main.nf" - process { - """ - input[0] = [ - [ id:'test', strandedness:'forward' ], // meta map - [ file(params.test_data['homo_sapiens']['illumina']['test_paired_end_sorted_bam'], checkIfExists: true) ] - ] - input[1] = file(params.test_data['homo_sapiens']['genome']['genome_gtf'], checkIfExists: true) - """ - } + setup { + run("STRINGTIE_STRINGTIE") { + script "../../stringtie/main.nf" + process { + """ + input[0] = [ + [ id:'test', strandedness:'reverse' ], // meta map + [ file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam", checkIfExists: true) ] + ] + input[1] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) + """ } - } + } + + test("homo_sapiens - forward strandedness") { when { process { """ input[0] = STRINGTIE_STRINGTIE.out.transcript_gtf.map { it -> it[1] } - input[1] = file(params.test_data['homo_sapiens']['genome']['genome_gtf'], checkIfExists: true) + input[1] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) """ } } @@ -46,27 +46,11 @@ nextflow_process { test("homo_sapiens - reverse strandedness") { - setup { - run("STRINGTIE_STRINGTIE") { - script "../../stringtie/main.nf" - process { - """ - input[0] = [ - [ id:'test', strandedness:'reverse' ], // meta map - [ file(params.test_data['homo_sapiens']['illumina']['test_paired_end_sorted_bam'], checkIfExists: true) ] - ] - input[1] = file(params.test_data['homo_sapiens']['genome']['genome_gtf'], checkIfExists: true) - """ - } - } - - } - when { process { """ input[0] = STRINGTIE_STRINGTIE.out.transcript_gtf.map { it -> it[1] } - input[1] = file(params.test_data['homo_sapiens']['genome']['genome_gtf'], checkIfExists: true) + input[1] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) """ } } diff --git a/modules/nf-core/stringtie/merge/tests/main.nf.test.snap b/modules/nf-core/stringtie/merge/tests/main.nf.test.snap index 3e4bc68f6..e10406964 100644 --- a/modules/nf-core/stringtie/merge/tests/main.nf.test.snap +++ b/modules/nf-core/stringtie/merge/tests/main.nf.test.snap @@ -5,6 +5,10 @@ "versions.yml:md5,b73d45fdebf4c8c446bb01817db1665d" ] ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, "timestamp": "2023-11-23T14:14:39.697712988" }, "rs_gtf": { @@ -13,15 +17,23 @@ "stringtie.merged.gtf:md5,6da479298d73d5b3216d4e1576a2bdf4" ] ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, "timestamp": "2023-11-23T14:14:39.691894799" }, "fs_gtf": { "content": [ [ - "stringtie.merged.gtf:md5,d959eb2fab0db48ded7275e0a2e83c05" + "stringtie.merged.gtf:md5,6da479298d73d5b3216d4e1576a2bdf4" ] ], - "timestamp": "2023-11-23T14:14:20.872841278" + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-07T16:43:48.130184" }, "fs_versions": { "content": [ @@ -29,6 +41,10 @@ "versions.yml:md5,b73d45fdebf4c8c446bb01817db1665d" ] ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, "timestamp": "2023-11-23T14:14:20.883140097" } } \ No newline at end of file diff --git a/modules/nf-core/stringtie/merge/tests/tags.yml b/modules/nf-core/stringtie/merge/tests/tags.yml deleted file mode 100644 index 58cef46ba..000000000 --- a/modules/nf-core/stringtie/merge/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -stringtie/merge: - - modules/nf-core/stringtie/merge/** diff --git a/modules/nf-core/stringtie/stringtie/environment.yml b/modules/nf-core/stringtie/stringtie/environment.yml index 7a0eccdb8..a51985b4f 100644 --- a/modules/nf-core/stringtie/stringtie/environment.yml +++ b/modules/nf-core/stringtie/stringtie/environment.yml @@ -1,7 +1,7 @@ -name: stringtie_stringtie +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults dependencies: - - bioconda::stringtie=2.2.1 + - bioconda::stringtie=2.2.3 diff --git a/modules/nf-core/stringtie/stringtie/main.nf b/modules/nf-core/stringtie/stringtie/main.nf index 6e25ba27d..4635c8c5b 100644 --- a/modules/nf-core/stringtie/stringtie/main.nf +++ b/modules/nf-core/stringtie/stringtie/main.nf @@ -4,8 +4,8 @@ process STRINGTIE_STRINGTIE { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/stringtie:2.2.1--hecb563c_2' : - 'biocontainers/stringtie:2.2.1--hecb563c_2' }" + 'https://depot.galaxyproject.org/singularity/stringtie:2.2.3--h43eeafb_0' : + 'biocontainers/stringtie:2.2.3--h43eeafb_0' }" input: tuple val(meta), path(bam) diff --git a/modules/nf-core/stringtie/stringtie/meta.yml b/modules/nf-core/stringtie/stringtie/meta.yml index d8ebdd88a..9cdd14004 100644 --- a/modules/nf-core/stringtie/stringtie/meta.yml +++ b/modules/nf-core/stringtie/stringtie/meta.yml @@ -12,46 +12,75 @@ tools: homepage: https://ccb.jhu.edu/software/stringtie/index.shtml documentation: https://ccb.jhu.edu/software/stringtie/index.shtml?t=manual licence: ["MIT"] + identifier: biotools:stringtie input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - bam: - type: file - description: | - Stringtie transcript gtf output(s). + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: | + Stringtie transcript gtf output(s). + ontologies: [] - annotation_gtf: type: file description: | Annotation gtf file (optional). + ontologies: [] output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - transcript_gtf: - type: file - description: transcript gtf - pattern: "*.{transcripts.gtf}" - - coverage_gtf: - type: file - description: coverage gtf - pattern: "*.{coverage.gtf}" - - abudance: - type: file - description: abudance - pattern: "*.{abudance.txt}" - - ballgown: - type: file - description: for running ballgown - pattern: "*.{ballgown}" - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + transcript_gtf: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.transcripts.gtf": + type: file + description: transcript gtf + pattern: "*.{transcripts.gtf}" + ontologies: [] + abundance: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.abundance.txt": + type: file + description: abundance + pattern: "*.{abundance.txt}" + ontologies: [] + coverage_gtf: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.coverage.gtf": + type: file + description: coverage gtf + pattern: "*.{coverage.gtf}" + ontologies: [] + ballgown: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.ballgown": + type: file + description: for running ballgown + pattern: "*.{ballgown}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML authors: - "@drpatelh" maintainers: diff --git a/modules/nf-core/stringtie/stringtie/tests/main.nf.test b/modules/nf-core/stringtie/stringtie/tests/main.nf.test index 68786b745..2204e849f 100644 --- a/modules/nf-core/stringtie/stringtie/tests/main.nf.test +++ b/modules/nf-core/stringtie/stringtie/tests/main.nf.test @@ -3,6 +3,7 @@ nextflow_process { name "Test Process STRINGTIE_STRINGTIE" script "../main.nf" process "STRINGTIE_STRINGTIE" + config "./nextflow.config" tag "modules" tag "modules_nfcore" tag "stringtie" @@ -15,8 +16,8 @@ nextflow_process { """ input[0] = [ [ id:'test', strandedness:'forward' ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_paired_end_sorted_bam'], checkIfExists: true) ] - ] + [ file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam", checkIfExists: true) ] + ] input[1] = [] """ } @@ -24,10 +25,12 @@ nextflow_process { then { assertAll( - { assert process.success }, - { assert snapshot(process.out.transcript_gtf).match("fs_transcript_gtf") }, - { assert snapshot(process.out.abundance).match("fs_abundance") }, - { assert snapshot(process.out.versions).match("fs_versions") } + { assert process.success }, + { assert snapshot( + process.out.abundance, + process.out.transcript_gtf, + process.out.versions + ).match() } ) } } @@ -38,10 +41,10 @@ nextflow_process { process { """ input[0] = [ - [ id:'test', strandedness:'forward' ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_paired_end_sorted_bam'], checkIfExists: true) ] - ] - input[1] = file(params.test_data['sarscov2']['genome']['genome_gtf'], checkIfExists: true) + [ id:'test', strandedness:'forward' ], // meta map + [ file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam", checkIfExists: true) ] + ] + input[1] = file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gtf", checkIfExists: true) """ } } @@ -49,10 +52,12 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out.transcript_gtf).match("fs_gtf_transcript_gtf") }, - { assert snapshot(process.out.abundance).match("fs_gtf_abundance") }, - { assert snapshot(process.out.ballgown).match("fs_gtf_ballgown") }, - { assert snapshot(process.out.versions).match("fs_gtf_versions") } + { assert snapshot( + process.out.abundance, + process.out.ballgown, + process.out.transcript_gtf, + process.out.versions + ).match() } ) } } @@ -64,8 +69,8 @@ nextflow_process { """ input[0] = [ [ id:'test', strandedness:'reverse' ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_paired_end_sorted_bam'], checkIfExists: true) ] - ] + [ file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam", checkIfExists: true) ] + ] input[1] = [] """ } @@ -73,10 +78,12 @@ nextflow_process { then { assertAll( - { assert process.success }, - { assert snapshot(process.out.transcript_gtf).match("rs_transcript_gtf") }, - { assert snapshot(process.out.abundance).match("rs_abundance") }, - { assert snapshot(process.out.versions).match("rs_versions") } + { assert process.success }, + { assert snapshot( + process.out.abundance, + process.out.transcript_gtf, + process.out.versions + ).match() } ) } } @@ -88,20 +95,118 @@ nextflow_process { """ input[0] = [ [ id:'test', strandedness:'reverse' ], // meta map - [ file(params.test_data['sarscov2']['illumina']['test_paired_end_sorted_bam'], checkIfExists: true) ] - ] - input[1] = file(params.test_data['sarscov2']['genome']['genome_gtf'], checkIfExists: true) + [ file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam", checkIfExists: true) ] + ] + input[1] = file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gtf", checkIfExists: true) """ } } then { assertAll( - { assert process.success }, - { assert snapshot(process.out.transcript_gtf).match("rs_gtf_transcript_gtf") }, - { assert snapshot(process.out.abundance).match("rs_gtf_abundance") }, - { assert snapshot(process.out.ballgown).match("rs_gtf_ballgown") }, - { assert snapshot(process.out.versions).match("rs_gtf_versions") } + { assert process.success }, + { assert snapshot( + process.out.abundance, + process.out.ballgown, + process.out.transcript_gtf, + process.out.versions + ).match() } + ) + } + } + + test("sarscov2 [bam] - forward strandedness - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', strandedness:'forward' ], // meta map + [ file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam", checkIfExists: true) ] + ] + input[1] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 [bam] - forward strandedness + reference annotation - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', strandedness:'forward' ], // meta map + [ file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam", checkIfExists: true) ] + ] + input[1] = file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gtf", checkIfExists: true) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 [bam] - reverse strandedness - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', strandedness:'reverse' ], // meta map + [ file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam", checkIfExists: true) ] + ] + input[1] = [] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("sarscov2 [bam] - reverse strandedness + reference annotation - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', strandedness:'reverse' ], // meta map + [ file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam", checkIfExists: true) ] + ] + input[1] = file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gtf", checkIfExists: true) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } ) } } diff --git a/modules/nf-core/stringtie/stringtie/tests/main.nf.test.snap b/modules/nf-core/stringtie/stringtie/tests/main.nf.test.snap index bf7516364..d4645de3e 100644 --- a/modules/nf-core/stringtie/stringtie/tests/main.nf.test.snap +++ b/modules/nf-core/stringtie/stringtie/tests/main.nf.test.snap @@ -1,5 +1,5 @@ { - "fs_abundance": { + "sarscov2 [bam] - forward strandedness + reference annotation": { "content": [ [ [ @@ -7,49 +7,44 @@ "id": "test", "strandedness": "forward" }, - "test.gene.abundance.txt:md5,d6f5c8cadb8458f1df0427cf790246e3" + "test.gene.abundance.txt:md5,7d8bce7f2a922e367cedccae7267c22e" ] - ] - ], - "timestamp": "2023-11-23T13:55:41.032044613" - }, - "fs_transcript_gtf": { - "content": [ + ], [ [ { "id": "test", "strandedness": "forward" }, - "test.transcripts.gtf:md5,569137af5be452413086b50653a97203" + [ + "e2t.ctab:md5,e981c0038295ae54b63cedb1083f1540", + "e_data.ctab:md5,6b4cf69bc03f3f69890f972a0e8b7471", + "i2t.ctab:md5,8a117c8aa4334b4c2d4711932b006fb4", + "i_data.ctab:md5,be3abe09740603213f83d50dcf81427f", + "t_data.ctab:md5,3b66c065da73ae0dd41cc332eff6a818" + ] ] - ] - ], - "timestamp": "2023-11-23T13:55:41.017978904" - }, - "rs_abundance": { - "content": [ + ], [ [ { "id": "test", - "strandedness": "reverse" + "strandedness": "forward" }, - "test.gene.abundance.txt:md5,d6f5c8cadb8458f1df0427cf790246e3" + "test.transcripts.gtf:md5,37154e7bda96544f24506ee902bb561d" ] - ] - ], - "timestamp": "2023-11-23T13:56:13.601112933" - }, - "fs_gtf_versions": { - "content": [ + ], [ - "versions.yml:md5,3410e8ac349d18c85ddee89337851d38" + "versions.yml:md5,06593ea00cc35bf06f2de2753e0c3913" ] ], - "timestamp": "2023-11-23T13:56:00.523797974" + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T09:56:50.294157199" }, - "fs_gtf_transcript_gtf": { + "sarscov2 [bam] - forward strandedness": { "content": [ [ [ @@ -57,50 +52,395 @@ "id": "test", "strandedness": "forward" }, - "test.transcripts.gtf:md5,f56cf8aba2c4a5673bc7963ba5f12d04" + "test.gene.abundance.txt:md5,d6f5c8cadb8458f1df0427cf790246e3" ] + ], + [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.transcripts.gtf:md5,6087dfc9700a52d9e4a1ae3fcd1d1dfd" + ] + ], + [ + "versions.yml:md5,06593ea00cc35bf06f2de2753e0c3913" ] ], - "timestamp": "2023-11-23T13:56:00.475164879" + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T09:56:39.4249133" }, - "rs_versions": { + "sarscov2 [bam] - forward strandedness - stub": { "content": [ - [ - "versions.yml:md5,3410e8ac349d18c85ddee89337851d38" - ] + { + "0": [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.transcripts.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.gene.abundance.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.coverage.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.ballgown:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + "versions.yml:md5,06593ea00cc35bf06f2de2753e0c3913" + ], + "abundance": [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.gene.abundance.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "ballgown": [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.ballgown:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "coverage_gtf": [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.coverage.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "transcript_gtf": [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.transcripts.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,06593ea00cc35bf06f2de2753e0c3913" + ] + } ], - "timestamp": "2023-11-23T13:56:13.623892691" + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T09:57:23.008470065" }, - "rs_gtf_transcript_gtf": { + "sarscov2 [bam] - forward strandedness + reference annotation - stub": { "content": [ - [ - [ - { - "id": "test", - "strandedness": "reverse" - }, - "test.transcripts.gtf:md5,bb346053a8c156b803b055133376c7fa" + { + "0": [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.transcripts.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.gene.abundance.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.coverage.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.ballgown:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + "versions.yml:md5,06593ea00cc35bf06f2de2753e0c3913" + ], + "abundance": [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.gene.abundance.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "ballgown": [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.ballgown:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "coverage_gtf": [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.coverage.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "transcript_gtf": [ + [ + { + "id": "test", + "strandedness": "forward" + }, + "test.transcripts.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,06593ea00cc35bf06f2de2753e0c3913" ] - ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T09:57:33.622824981" + }, + "sarscov2 [bam] - reverse strandedness + reference annotation - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "strandedness": "reverse" + }, + "test.transcripts.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "strandedness": "reverse" + }, + "test.gene.abundance.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "strandedness": "reverse" + }, + "test.coverage.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "strandedness": "reverse" + }, + "test.ballgown:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + "versions.yml:md5,06593ea00cc35bf06f2de2753e0c3913" + ], + "abundance": [ + [ + { + "id": "test", + "strandedness": "reverse" + }, + "test.gene.abundance.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "ballgown": [ + [ + { + "id": "test", + "strandedness": "reverse" + }, + "test.ballgown:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "coverage_gtf": [ + [ + { + "id": "test", + "strandedness": "reverse" + }, + "test.coverage.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "transcript_gtf": [ + [ + { + "id": "test", + "strandedness": "reverse" + }, + "test.transcripts.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,06593ea00cc35bf06f2de2753e0c3913" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T09:57:55.803421433" + }, + "sarscov2 [bam] - reverse strandedness - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "strandedness": "reverse" + }, + "test.transcripts.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "strandedness": "reverse" + }, + "test.gene.abundance.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "strandedness": "reverse" + }, + "test.coverage.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "strandedness": "reverse" + }, + "test.ballgown:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + "versions.yml:md5,06593ea00cc35bf06f2de2753e0c3913" + ], + "abundance": [ + [ + { + "id": "test", + "strandedness": "reverse" + }, + "test.gene.abundance.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "ballgown": [ + [ + { + "id": "test", + "strandedness": "reverse" + }, + "test.ballgown:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "coverage_gtf": [ + [ + { + "id": "test", + "strandedness": "reverse" + }, + "test.coverage.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "transcript_gtf": [ + [ + { + "id": "test", + "strandedness": "reverse" + }, + "test.transcripts.gtf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,06593ea00cc35bf06f2de2753e0c3913" + ] + } ], - "timestamp": "2023-11-23T13:56:22.693599559" + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T09:57:44.825389635" }, - "fs_gtf_abundance": { + "sarscov2 [bam] - reverse strandedness + reference annotation": { "content": [ [ [ { "id": "test", - "strandedness": "forward" + "strandedness": "reverse" }, - "test.gene.abundance.txt:md5,7d8bce7f2a922e367cedccae7267c22e" + "test.gene.abundance.txt:md5,7385b870b955dae2c2ab78a70cf05cce" ] - ] - ], - "timestamp": "2023-11-23T13:56:00.482135418" - }, - "rs_gtf_ballgown": { - "content": [ + ], [ [ { @@ -115,72 +455,54 @@ "t_data.ctab:md5,3b66c065da73ae0dd41cc332eff6a818" ] ] - ] - ], - "timestamp": "2023-11-23T13:56:22.715698347" - }, - "rs_transcript_gtf": { - "content": [ + ], [ [ { "id": "test", "strandedness": "reverse" }, - "test.transcripts.gtf:md5,31c34aec2bf36bb0ea3c16c2afeeeb1f" + "test.transcripts.gtf:md5,fbabb4e3888bbede67f11f692e484880" ] - ] - ], - "timestamp": "2023-11-23T13:56:13.590054035" - }, - "rs_gtf_versions": { - "content": [ + ], [ - "versions.yml:md5,3410e8ac349d18c85ddee89337851d38" + "versions.yml:md5,06593ea00cc35bf06f2de2753e0c3913" ] ], - "timestamp": "2023-11-23T13:56:22.725513476" + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T09:57:11.793664242" }, - "fs_gtf_ballgown": { + "sarscov2 [bam] - reverse strandedness": { "content": [ [ [ { "id": "test", - "strandedness": "forward" + "strandedness": "reverse" }, - [ - "e2t.ctab:md5,e981c0038295ae54b63cedb1083f1540", - "e_data.ctab:md5,6b4cf69bc03f3f69890f972a0e8b7471", - "i2t.ctab:md5,8a117c8aa4334b4c2d4711932b006fb4", - "i_data.ctab:md5,be3abe09740603213f83d50dcf81427f", - "t_data.ctab:md5,3b66c065da73ae0dd41cc332eff6a818" - ] + "test.gene.abundance.txt:md5,d6f5c8cadb8458f1df0427cf790246e3" ] - ] - ], - "timestamp": "2023-11-23T13:56:00.494299817" - }, - "fs_versions": { - "content": [ - [ - "versions.yml:md5,3410e8ac349d18c85ddee89337851d38" - ] - ], - "timestamp": "2023-11-23T13:55:41.049417582" - }, - "rs_gtf_abundance": { - "content": [ + ], [ [ { "id": "test", "strandedness": "reverse" }, - "test.gene.abundance.txt:md5,7385b870b955dae2c2ab78a70cf05cce" + "test.transcripts.gtf:md5,01d6da00a3c458420841e57427297183" ] + ], + [ + "versions.yml:md5,06593ea00cc35bf06f2de2753e0c3913" ] ], - "timestamp": "2023-11-23T13:56:22.701059059" + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-18T09:57:01.166309777" } -} +} \ No newline at end of file diff --git a/modules/nf-core/stringtie/stringtie/tests/nextflow.config b/modules/nf-core/stringtie/stringtie/tests/nextflow.config new file mode 100644 index 000000000..e3aaa0999 --- /dev/null +++ b/modules/nf-core/stringtie/stringtie/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'STRINGTIE_STRINGTIE' { + ext.args = '' + } +} diff --git a/modules/nf-core/stringtie/stringtie/tests/tags.yml b/modules/nf-core/stringtie/stringtie/tests/tags.yml deleted file mode 100644 index da9b051c3..000000000 --- a/modules/nf-core/stringtie/stringtie/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -stringtie/stringtie: - - modules/nf-core/stringtie/stringtie/** diff --git a/modules/nf-core/ucsc/gtftogenepred/environment.yml b/modules/nf-core/ucsc/gtftogenepred/environment.yml new file mode 100644 index 000000000..86709a0d4 --- /dev/null +++ b/modules/nf-core/ucsc/gtftogenepred/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::ucsc-gtftogenepred=447 diff --git a/modules/nf-core/ucsc/gtftogenepred/main.nf b/modules/nf-core/ucsc/gtftogenepred/main.nf new file mode 100644 index 000000000..afbb5f3f9 --- /dev/null +++ b/modules/nf-core/ucsc/gtftogenepred/main.nf @@ -0,0 +1,54 @@ +process UCSC_GTFTOGENEPRED { + 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/ucsc-gtftogenepred:447--h954228d_0': + 'biocontainers/ucsc-gtftogenepred:447--h954228d_0' }" + + input: + tuple val(meta), path(gtf) + + output: + tuple val(meta), path("*.genepred"), emit: genepred + tuple val(meta), path("*.refflat") , emit: refflat , optional: true + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def gen_refflat = args.contains("-genePredExt") && args.contains("-geneNameAsName2") ? "true" : "false" + def prefix = task.ext.prefix ?: "${meta.id}" + def VERSION = '447' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + """ + gtfToGenePred \\ + $args \\ + $gtf \\ + ${prefix}.genepred + + if [ "${gen_refflat}" == "true" ] ; then + awk 'BEGIN { OFS="\\t"} {print \$12, \$1, \$2, \$3, \$4, \$5, \$6, \$7, \$8, \$9, \$10}' ${prefix}.genepred > ${prefix}.refflat + fi + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + ucsc: $VERSION + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + def VERSION = '447' + """ + touch ${prefix}.genepred + touch ${prefix}.refflat + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + ucsc: $VERSION + END_VERSIONS + """ +} diff --git a/modules/nf-core/ucsc/gtftogenepred/meta.yml b/modules/nf-core/ucsc/gtftogenepred/meta.yml new file mode 100644 index 000000000..5939538df --- /dev/null +++ b/modules/nf-core/ucsc/gtftogenepred/meta.yml @@ -0,0 +1,61 @@ +name: ucsc_gtftogenepred +description: compute average score of bigwig over bed file +keywords: + - gtf + - genepred + - refflat + - ucsc + - gtftogenepred +tools: + - ucsc: + description: Convert GTF files to GenePred format + homepage: http://hgdownload.cse.ucsc.edu/admin/exe/ + licence: ["varies; see http://genome.ucsc.edu/license"] + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - gtf: + type: file + description: GTF file + pattern: "*.{gtf}" + ontologies: [] +output: + genepred: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.genepred": + type: file + description: genepred file + pattern: "*.{genepred}" + ontologies: [] + refflat: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.refflat": + type: file + description: refflat file + pattern: "*.{refflat}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@BarryDigby" + - "@anoronh4" +maintainers: + - "@BarryDigby" + - "@anoronh4" diff --git a/modules/nf-core/ucsc/gtftogenepred/tests/main.nf.test b/modules/nf-core/ucsc/gtftogenepred/tests/main.nf.test new file mode 100644 index 000000000..e0396a63c --- /dev/null +++ b/modules/nf-core/ucsc/gtftogenepred/tests/main.nf.test @@ -0,0 +1,36 @@ + +nextflow_process { + + name "Test Process UCSC_GTFTOGENEPRED" + script "../main.nf" + process "UCSC_GTFTOGENEPRED" + config "./nextflow.config" + + tag "modules" + tag "modules_nfcore" + tag "ucsc" + tag "ucsc/gtftogenepred" + + test("test-ucsc-gtftogenepred") { + + when { + process { + """ + input[0] = [ + [ id: 'test' ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.gtf', checkIfExists: true) ] + ] + + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + +} diff --git a/modules/nf-core/ucsc/gtftogenepred/tests/main.nf.test.snap b/modules/nf-core/ucsc/gtftogenepred/tests/main.nf.test.snap new file mode 100644 index 000000000..f021f8238 --- /dev/null +++ b/modules/nf-core/ucsc/gtftogenepred/tests/main.nf.test.snap @@ -0,0 +1,51 @@ +{ + "test-ucsc-gtftogenepred": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.genepred:md5,779e4749efaf38da3443ddfde30cc76c" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.refflat:md5,4101802f41d4cf7ee2667587da11bf42" + ] + ], + "2": [ + "versions.yml:md5,fd95365619a316eb451190365b1b799e" + ], + "genepred": [ + [ + { + "id": "test" + }, + "test.genepred:md5,779e4749efaf38da3443ddfde30cc76c" + ] + ], + "refflat": [ + [ + { + "id": "test" + }, + "test.refflat:md5,4101802f41d4cf7ee2667587da11bf42" + ] + ], + "versions": [ + "versions.yml:md5,fd95365619a316eb451190365b1b799e" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-23T08:55:50.58172" + } +} \ No newline at end of file diff --git a/modules/nf-core/ucsc/gtftogenepred/tests/nextflow.config b/modules/nf-core/ucsc/gtftogenepred/tests/nextflow.config new file mode 100644 index 000000000..889bb6ce6 --- /dev/null +++ b/modules/nf-core/ucsc/gtftogenepred/tests/nextflow.config @@ -0,0 +1,8 @@ +process { + withName: UCSC_GTFTOGENEPRED { + ext.args = [ + "-genePredExt", + "-geneNameAsName2" + ].join(' ').trim() + } +} diff --git a/modules/nf-core/umitools/extract/environment.yml b/modules/nf-core/umitools/extract/environment.yml new file mode 100644 index 000000000..e5721f1e7 --- /dev/null +++ b/modules/nf-core/umitools/extract/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::umi_tools=1.1.5 diff --git a/modules/nf-core/umitools/extract/main.nf b/modules/nf-core/umitools/extract/main.nf new file mode 100644 index 000000000..b97900e09 --- /dev/null +++ b/modules/nf-core/umitools/extract/main.nf @@ -0,0 +1,74 @@ +process UMITOOLS_EXTRACT { + tag "$meta.id" + label "process_single" + label "process_long" + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/umi_tools:1.1.5--py39hf95cd2a_0' : + 'biocontainers/umi_tools:1.1.5--py39hf95cd2a_0' }" + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*.fastq.gz"), emit: reads + tuple val(meta), path("*.log") , emit: log + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + if (meta.single_end) { + """ + umi_tools \\ + extract \\ + -I $reads \\ + -S ${prefix}.umi_extract.fastq.gz \\ + $args \\ + > ${prefix}.umi_extract.log + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + umitools: \$( umi_tools --version | sed '/version:/!d; s/.*: //' ) + END_VERSIONS + """ + } else { + """ + umi_tools \\ + extract \\ + -I ${reads[0]} \\ + --read2-in=${reads[1]} \\ + -S ${prefix}.umi_extract_1.fastq.gz \\ + --read2-out=${prefix}.umi_extract_2.fastq.gz \\ + $args \\ + > ${prefix}.umi_extract.log + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + umitools: \$( umi_tools --version | sed '/version:/!d; s/.*: //' ) + END_VERSIONS + """ + } + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + if (meta.single_end) { + output_command = "echo '' | gzip > ${prefix}.umi_extract.fastq.gz" + } else { + output_command = "echo '' | gzip > ${prefix}.umi_extract_1.fastq.gz ;" + output_command += "echo '' | gzip > ${prefix}.umi_extract_2.fastq.gz" + } + """ + touch ${prefix}.umi_extract.log + ${output_command} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + umitools: \$( umi_tools --version | sed '/version:/!d; s/.*: //' ) + END_VERSIONS + """ +} diff --git a/modules/nf-core/umitools/extract/meta.yml b/modules/nf-core/umitools/extract/meta.yml new file mode 100644 index 000000000..19a7fa644 --- /dev/null +++ b/modules/nf-core/umitools/extract/meta.yml @@ -0,0 +1,64 @@ +name: umitools_extract +description: Extracts UMI barcode from a read and add it to the read name, leaving + any sample barcode in place +keywords: + - UMI + - barcode + - extract + - umitools +tools: + - umi_tools: + description: > + UMI-tools contains tools for dealing with Unique Molecular Identifiers (UMIs)/Random + Molecular Tags (RMTs) and single cell RNA-Seq cell barcodes + documentation: https://umi-tools.readthedocs.io/en/latest/ + license: "MIT" + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: list + description: | + List of input FASTQ files whose UMIs will be extracted. +output: + reads: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.fastq.gz": + type: file + description: > + Extracted FASTQ files. | For single-end reads, pattern is \${prefix}.umi_extract.fastq.gz. + | For paired-end reads, pattern is \${prefix}.umi_extract_{1,2}.fastq.gz. + pattern: "*.{fastq.gz}" + ontologies: [] + log: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.log": + type: file + description: Logfile for umi_tools + pattern: "*.{log}" + ontologies: [] + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: + - "@drpatelh" + - "@grst" +maintainers: + - "@drpatelh" + - "@grst" diff --git a/modules/nf-core/umitools/extract/tests/main.nf.test b/modules/nf-core/umitools/extract/tests/main.nf.test new file mode 100644 index 000000000..bb8a06582 --- /dev/null +++ b/modules/nf-core/umitools/extract/tests/main.nf.test @@ -0,0 +1,106 @@ +nextflow_process { + + name "Test Process UMITOOLS_EXTRACT" + script "../main.nf" + process "UMITOOLS_EXTRACT" + config "./nextflow.config" + tag "modules_nfcore" + tag "modules" + tag "umitools" + tag "umitools/extract" + + test("single end") { + + when { + process { + """ + input[0] = [ [ 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.reads.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.log.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.versions + ).match() } + ) + } + } + + test("single end - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ [ 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).match() } + ) + } + } + + test("pair end") { + + when { + process { + """ + input[0] = [ [ 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( + file(process.out.reads[0][1][0]).name, + file(process.out.reads[0][1][1]).name, + process.out.log.collect { it.collect { it instanceof Map ? it : file(it).name }}, + process.out.versions + ).match() } + ) + } + } + + test("pair end - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ [ id:'test', single_end:false ], // meta map + [ file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_1.fastq.gz", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_2.fastq.gz", checkIfExists: true) ] + ] + """ + } + } + + then { + assertAll ( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} \ No newline at end of file diff --git a/modules/nf-core/umitools/extract/tests/main.nf.test.snap b/modules/nf-core/umitools/extract/tests/main.nf.test.snap new file mode 100644 index 000000000..b1159054b --- /dev/null +++ b/modules/nf-core/umitools/extract/tests/main.nf.test.snap @@ -0,0 +1,167 @@ +{ + "pair end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.umi_extract_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.umi_extract_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.umi_extract.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,568d243174c081a0301e74ed42e59b48" + ], + "log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.umi_extract.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.umi_extract_1.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.umi_extract_2.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "versions": [ + "versions.yml:md5,568d243174c081a0301e74ed42e59b48" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-02T15:05:20.008312" + }, + "single end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.umi_extract.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.umi_extract.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,568d243174c081a0301e74ed42e59b48" + ], + "log": [ + [ + { + "id": "test", + "single_end": true + }, + "test.umi_extract.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.umi_extract.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,568d243174c081a0301e74ed42e59b48" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-02T15:04:12.145999" + }, + "pair end": { + "content": [ + "test.umi_extract_1.fastq.gz", + "test.umi_extract_2.fastq.gz", + [ + [ + { + "id": "test", + "single_end": false + }, + "test.umi_extract.log" + ] + ], + [ + "versions.yml:md5,568d243174c081a0301e74ed42e59b48" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-02T15:21:09.578031" + }, + "single end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.umi_extract.fastq.gz" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.umi_extract.log" + ] + ], + [ + "versions.yml:md5,568d243174c081a0301e74ed42e59b48" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-02T15:03:52.464606" + } +} \ No newline at end of file diff --git a/modules/nf-core/umitools/extract/tests/nextflow.config b/modules/nf-core/umitools/extract/tests/nextflow.config new file mode 100644 index 000000000..c866f5a00 --- /dev/null +++ b/modules/nf-core/umitools/extract/tests/nextflow.config @@ -0,0 +1,9 @@ +process { + + publishDir = { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" } + + withName: UMITOOLS_EXTRACT { + ext.args = '--bc-pattern="NNNN"' + } + +} diff --git a/nextflow.config b/nextflow.config index 17375158e..8f5370a58 100644 --- a/nextflow.config +++ b/nextflow.config @@ -11,11 +11,11 @@ params { // Input options input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' - - build_references = false + references_only = false cosmic_username = null cosmic_passwd = null qiagen = false + outdir = null // MultiQC options multiqc_config = null @@ -26,67 +26,56 @@ params { // Genome genome = 'GRCh38' - genomes_base = "${params.outdir}/references" - ensembl_version = 102 + genomes_base = "s3://nf-core-awsmegatests/rnafusion/references" + genomes_ignore = false + genome_gencode_version = 46 read_length = 100 - starfusion_build = true genomes = [:] - - // Genomes options - fasta = "${params.genomes_base}/ensembl/Homo_sapiens.${params.genome}.${params.ensembl_version}.all.fa" - fai = "${params.genomes_base}/ensembl/Homo_sapiens.${params.genome}.${params.ensembl_version}.all.fa.fai" - gtf = "${params.genomes_base}/ensembl/Homo_sapiens.${params.genome}.${params.ensembl_version}.gtf" - chrgtf = "${params.genomes_base}/ensembl/Homo_sapiens.${params.genome}.${params.ensembl_version}.chr.gtf" - transcript = "${params.genomes_base}/ensembl/Homo_sapiens.${params.genome}.${params.ensembl_version}.cdna.all.fa.gz" - refflat = "${params.genomes_base}/ensembl/Homo_sapiens.${params.genome}.${params.ensembl_version}.chr.gtf.refflat" - rrna_intervals = "${params.genomes_base}/ensembl/Homo_sapiens.${params.genome}.${params.ensembl_version}.interval_list" + fusion_annot_lib = "https://github.com/FusionAnnotator/CTAT_HumanFusionLib/releases/download/v0.3.0/fusion_lib.Mar2021.dat.gz" // path to dat.gz CTAT genome lib // TODO: Update to latest with s3 link when available // Filtering tools_cutoff = 1 // Trimming - fastp_trim = false - trim_tail = null + trim_tail = 0 + trim_tail_fusioncatcher = 0 adapter_fasta = [] + save_trimmed_fail = false + save_merged = false + min_trimmed_reads = 1 // Compression - cram = [] + cram = false // Alignment options star_ignore_sjdbgtf = false - seq_center = null - seq_platform = null + star_limit_bam_sort_ram = 0 + seq_center = "" + seq_platform = "" fusioncatcher_limitSjdbInsertNsj = 2000000 fusioninspector_limitSjdbInsertNsj = 1000000 - // Enable or disable tools - all = false - arriba = false - fusioncatcher = false - starindex = false - starfusion = false - stringtie = false - fusionreport = false - fusioninspector_only = false + // Enable tools + tools = null // Skip steps skip_qc = false skip_vis = false - - // Path to references - ensembl_ref = "${params.genomes_base}/ensembl" - arriba_ref = "${params.genomes_base}/arriba" - arriba_ref_blacklist = "${params.genomes_base}/arriba/blacklist_hg38_GRCh38_v2.4.0.tsv.gz" - arriba_ref_cytobands = "${params.genomes_base}/arriba/cytobands_hg38_GRCh38_v2.4.0.tsv" - arriba_ref_known_fusions = "${params.genomes_base}/arriba/known_fusions_hg38_GRCh38_v2.4.0.tsv.gz" - arriba_ref_protein_domains = "${params.genomes_base}/arriba/protein_domains_hg38_GRCh38_v2.4.0.gff3" - fusioncatcher_ref = "${params.genomes_base}/fusioncatcher/human_v102" - hgnc_ref = "${params.genomes_base}/hgnc/hgnc_complete_set.txt" - hgnc_date = "${params.genomes_base}/hgnc/HGNC-DB-timestamp.txt" - starfusion_ref = "${params.genomes_base}/starfusion/ctat_genome_lib_build_dir" - starindex_ref = "${params.genomes_base}/star" - fusionreport_ref = "${params.genomes_base}/fusion_report_db" - + skip_vcf = false + + // Reference options + no_cosmic = false + ctatsplicing_cancer_introns = "https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/CANCER_SPLICING_LIB_SUPPLEMENT/cancer_introns.GRCh38.Jun232020.tsv.gz" + species = "homo_sapiens" + dfam_version = 3.8 + pfam_version = 37.4 + dfam_hmm = "https://www.dfam.org/releases/Dfam_${params.dfam_version}/infrastructure/dfamscan/${params.species}_dfam.hmm" + dfam_h3f = "https://www.dfam.org/releases/Dfam_${params.dfam_version}/infrastructure/dfamscan/${params.species}_dfam.hmm.h3f" + dfam_h3i = "https://www.dfam.org/releases/Dfam_${params.dfam_version}/infrastructure/dfamscan/${params.species}_dfam.hmm.h3i" + dfam_h3m = "https://www.dfam.org/releases/Dfam_${params.dfam_version}/infrastructure/dfamscan/${params.species}_dfam.hmm.h3m" + dfam_h3p = "https://www.dfam.org/releases/Dfam_${params.dfam_version}/infrastructure/dfamscan/${params.species}_dfam.hmm.h3p" + pfam_file = "http://ftp.ebi.ac.uk/pub/databases/Pfam/releases/Pfam${params.pfam_version}/Pfam-A.hmm.gz" + annot_filter_url = "https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/AnnotFilterRule.pm" // Path to fusion outputs arriba_fusions = null @@ -96,169 +85,177 @@ params { whitelist = null // Boilerplate options - outdir = null - publish_dir_mode = 'copy' - email = null - email_on_fail = null - plaintext_email = false - monochrome_logs = false - hook_url = null - help = false - version = false - - // Config options + publish_dir_mode = 'copy' + email = null + email_on_fail = null + plaintext_email = false + monochrome_logs = false + hook_url = null + help = false + help_full = false + show_hidden = false + version = false + pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/' + 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 - // Max resource options - // Defaults only, expecting to be overwritten - max_memory = '128.GB' - max_cpus = 16 - max_time = '240.h' - - // Schema validation default options - validationFailUnrecognisedParams = false - validationLenientMode = false - validationSchemaIgnoreParams = 'genomes' - validationShowHiddenParams = false - validate_params = true + validate_params = true } // Load base.config by default for all pipelines includeConfig 'conf/base.config' -// Load nf-core custom profiles from different Institutions -try { - includeConfig "${params.custom_config_base}/nfcore_custom.config" -} catch (Exception e) { - System.err.println("WARNING: Could not load nf-core/config profiles: ${params.custom_config_base}/nfcore_custom.config") -} - -// Load nf-core/rnafusion custom profiles from different institutions. -// Warning: Uncomment only if a pipeline-specific instititutional config already exists on nf-core/configs! -try { - includeConfig "${params.custom_config_base}/pipeline/rnafusion.config" -} catch (Exception e) { - System.err.println("WARNING: Could not load nf-core/config/rnafusion profiles: ${params.custom_config_base}/pipeline/rnafusion.config") -} profiles { debug { - dumpHashes = true - process.beforeScript = 'echo $HOSTNAME' - cleanup = false + dumpHashes = true + 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 - channels = ['conda-forge', 'bioconda', 'defaults'] - apptainer.enabled = false + 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 + 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' + docker.runOptions = '-u $(id -u):$(id -g) --platform=linux/amd64' } singularity { - singularity.enabled = true - singularity.autoMounts = true - conda.enabled = false - docker.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - apptainer.enabled = false + singularity.enabled = true + singularity.autoMounts = true + conda.enabled = false + docker.enabled = false + podman.enabled = false + shifter.enabled = false + charliecloud.enabled = false + 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 + } + wave { + apptainer.ociAutoPull = true + singularity.ociAutoPull = true + wave.enabled = true + wave.freeze = true + wave.strategy = 'conda,container' } test { includeConfig 'conf/test.config' } + test_build { + includeConfig 'conf/test_build.config' + } test_full { includeConfig 'conf/test_full.config' } gitpod { - executor.name = 'local' - executor.cpus = 4 - executor.memory = 8.GB + executor.name = 'local' + executor.cpus = 4 + executor.memory = 8.GB + process { + resourceLimits = [ + memory: 8.GB, + cpus : 4, + time : 1.h + ] + } + } + gpu { + docker.runOptions = '-u $(id -u):$(id -g) --gpus all' + apptainer.runOptions = '--nv' + singularity.runOptions = '--nv' } } -// Set default registry for Apptainer, Docker, Podman and Singularity independent of -profile -// Will not be used unless Apptainer / Docker / Podman / Singularity are enabled +// Load nf-core custom profiles from different institutions + +// 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-core/rnafusion 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/rnafusion custom profiles from different institutions. +includeConfig !System.getenv('NXF_OFFLINE') && params.custom_config_base ? "${params.custom_config_base}/pipeline/rnafusion.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' +apptainer.registry = 'quay.io' +docker.registry = 'quay.io' +podman.registry = 'quay.io' +singularity.registry = 'quay.io' +charliecloud.registry = 'quay.io' -// Nextflow plugins -plugins { - id 'nf-validation@1.1.3' // Validation of pipeline parameters and creation of an input channel from a sample sheet -} +// Load genomes.config if required +includeConfig !params.genomes_ignore ? 'conf/genomes.config' : 'conf/genomes_ignored.config' // Export these variables to prevent local Python/R libraries from conflicting with those in the container // The JULIA depot path has been adjusted to a fixed path `/usr/local/share/julia` that needs to be used for packages in the container. @@ -271,73 +268,135 @@ env { JULIA_DEPOT_PATH = "/usr/local/share/julia" } -// Capture exit codes from upstream processes when piping -process.shell = ['/bin/bash', '-euo', 'pipefail'] +// Set bash options +process.shell = [ + "bash", + "-C", // No clobber - prevent output redirection from overwriting files. + "-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 +] // Disable process selector warnings by default. Use debug profile to enable warnings. nextflow.enable.configProcessNamesValidation = false -def trace_timestamp = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss') timeline { enabled = true - file = "${params.outdir}/pipeline_info/execution_timeline_${trace_timestamp}.html" + file = "${params.outdir}/pipeline_info/execution_timeline_${params.trace_report_suffix}.html" } report { enabled = true - file = "${params.outdir}/pipeline_info/execution_report_${trace_timestamp}.html" + file = "${params.outdir}/pipeline_info/execution_report_${params.trace_report_suffix}.html" } trace { enabled = true - file = "${params.outdir}/pipeline_info/execution_trace_${trace_timestamp}.txt" + file = "${params.outdir}/pipeline_info/execution_trace_${params.trace_report_suffix}.txt" } dag { enabled = true - file = "${params.outdir}/pipeline_info/pipeline_dag_${trace_timestamp}.html" + file = "${params.outdir}/pipeline_info/pipeline_dag_${params.trace_report_suffix}.html" } manifest { name = 'nf-core/rnafusion' - author = """Martin Proks, Annick Renevey""" + contributors = [ + [ + name: 'Martin Proks', + affiliation: '', + email: '', + github: '@matq007', + contribution: ['author'], + orcid: '' + ], + [ + name: 'Annick Renevey', + affiliation: 'SciLifeLab, Karolinska Institutet', + email: 'annick.renevey@scilifelab.se', + github: '@rannick', + contribution: ['author', 'maintainer'], + orcid: '0000-0001-7411-6063' + ], + [ + name: 'Maxime U Garcia', + affiliation: 'Seqera', + email: 'maxime.garcia@seqera.io', + github: '@maxulysse', + contribution: ['author'], + orcid: '0000-0003-2827-9261' + ], + [ + name: 'Anabella Trigila', + affiliation: 'ZS Associates', + email: '', + github: '@atrigila', + contribution: ['contributor', 'maintainer'], + orcid: '' + ], + [ + name: 'Nicolas Vannieuwkerke', + affiliation: 'Center for Medical Genetics Ghent', + email: '', + github: '@nvnieuwk', + contribution: ['contributor', 'maintainer'], + orcid: '' + ], + [ + name: 'Delfina Terradas', + affiliation: 'ZS Associates', + email: '', + github: '@delfiterradas', + contribution: ['contributor'], + orcid: '' + ] + + ] homePage = 'https://github.com/nf-core/rnafusion' description = """Nextflow rnafusion analysis pipeline, part of the nf-core community.""" mainScript = 'main.nf' - nextflowVersion = '!>=23.04.0' - version = '3.0.2' + defaultBranch = 'master' + nextflowVersion = '!>=24.10.5' + version = '4.0.0' doi = '' } -// Load modules.config for DSL2 module specific options -includeConfig 'conf/modules.config' +// Nextflow plugins +plugins { + id 'nf-schema@2.4.2' // Validation of pipeline parameters and creation of an input channel from a sample sheet +} -// Function to ensure that resource requirements don't go beyond -// a maximum limit -def check_max(obj, type) { - if (type == 'memory') { - try { - if (obj.compareTo(params.max_memory as nextflow.util.MemoryUnit) == 1) - return params.max_memory as nextflow.util.MemoryUnit - else - return obj - } catch (all) { - println " ### ERROR ### Max memory '${params.max_memory}' is not valid! Using default value: $obj" - return obj - } - } else if (type == 'time') { - try { - if (obj.compareTo(params.max_time as nextflow.util.Duration) == 1) - return params.max_time as nextflow.util.Duration - else - return obj - } catch (all) { - println " ### ERROR ### Max time '${params.max_time}' is not valid! Using default value: $obj" - return obj - } - } else if (type == 'cpus') { - try { - return Math.min( obj, params.max_cpus as int ) - } catch (all) { - println " ### ERROR ### Max cpus '${params.max_cpus}' is not valid! Using default value: $obj" - return obj - } +validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + help { + enabled = true + command = "nextflow run nf-core/rnafusion -profile --input samplesheet.csv --outdir " + fullParameter = "help_full" + showHiddenParameter = "show_hidden" + beforeText = """ +-\033[2m----------------------------------------------------\033[0m- + \033[0;32m,--.\033[0;30m/\033[0;32m,-.\033[0m +\033[0;34m ___ __ __ __ ___ \033[0;32m/,-._.--~\'\033[0m +\033[0;34m |\\ | |__ __ / ` / \\ |__) |__ \033[0;33m} {\033[0m +\033[0;34m | \\| | \\__, \\__/ | \\ |___ \033[0;32m\\`-._,-`-,\033[0m + \033[0;32m`._,._,\'\033[0m +\033[0;35m nf-core/rnafusion ${manifest.version}\033[0m +-\033[2m----------------------------------------------------\033[0m- +""" + afterText = """${manifest.doi ? "\n* The pipeline\n" : ""}${manifest.doi.tokenize(",").collect { " https://doi.org/${it.trim().replace('https://doi.org/','')}"}.join("\n")}${manifest.doi ? "\n" : ""} +* The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + +* Software dependencies + https://github.com/nf-core/rnafusion/blob/master/CITATIONS.md +""" + } + summary { + beforeText = validation.help.beforeText + afterText = validation.help.afterText + hideParams = ["cosmic_username", "cosmic_passwd"] } } + +// Load modules.config for DSL2 module specific options +includeConfig 'conf/modules.config' diff --git a/nextflow_schema.json b/nextflow_schema.json index 2a3112961..ee0a623e2 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -1,10 +1,10 @@ { - "$schema": "http://json-schema.org/draft-07/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://raw.githubusercontent.com/nf-core/rnafusion/master/nextflow_schema.json", "title": "nf-core/rnafusion pipeline parameters", "description": "Nextflow rnafusion analysis pipeline, part of the nf-core community.", "type": "object", - "definitions": { + "$defs": { "skip_steps": { "title": "Skip steps", "type": "object", @@ -13,11 +13,18 @@ "properties": { "skip_qc": { "type": "boolean", - "description": "Skip QC steps" + "description": "Skip QC steps", + "fa_icon": "fas fa-forward" + }, + "skip_vcf": { + "type": "boolean", + "description": "Skip vcf creation step", + "fa_icon": "fas fa-forward" }, "skip_vis": { "type": "boolean", - "description": "Skip visualisation steps" + "description": "Skip visualisation steps", + "fa_icon": "fas fa-forward" } }, "fa_icon": "fas fa-fast-forward" @@ -27,16 +34,16 @@ "type": "object", "fa_icon": "fas fa-terminal", "description": "Define where the pipeline should find input data and save output data.", - "required": ["genomes_base", "outdir"], + "required": ["outdir", "genomes_base", "tools"], "properties": { "input": { "type": "string", "format": "file-path", - "exists": false, - "schema": "assets/schema_input.json", "mimetype": "text/csv", - "pattern": "^\\S+\\.csv$", - "description": "Path to comma-separated file containing information about the samples in the experiment.", + "schema": "assets/schema_input.json", + "exists": true, + "pattern": "^\\S+\\.(csv|yaml|yml|json)$", + "description": "Path to samplesheet file containing information about the samples in the experiment.", "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row. See [usage docs](https://nf-co.re/rnafusion/usage#samplesheet-input).", "fa_icon": "fas fa-file-csv" }, @@ -58,11 +65,6 @@ "description": "MultiQC report title. Printed as page header, used for filename if not otherwise specified.", "fa_icon": "fas fa-file-signature" }, - "build_references": { - "type": "boolean", - "fa_icon": "far fa-file-code", - "description": "Specifies which analysis type for the pipeline - either build references or analyse data" - }, "cosmic_username": { "type": "string", "fa_icon": "far fa-file-code", @@ -78,120 +80,118 @@ "fa_icon": "far fa-file-code", "description": "Path to reference folder" }, - "ensembl_version": { - "type": "integer", - "fa_icon": "far fa-file-code", - "description": "ensembl version", - "default": 102 - }, - "starfusion_build": { + "genomes_ignore": { "type": "boolean", "fa_icon": "far fa-file-code", - "description": "If set, starfusion references are built from scratch instead of downloaded (default)" + "description": "Don't automatically assign reference parameters to the correct references in --genomes_base" }, - "read_length": { + "genome_gencode_version": { "type": "integer", "fa_icon": "far fa-file-code", - "description": "Read length", - "default": 100 + "description": "gencode version" }, - "all": { - "type": "boolean", - "fa_icon": "far fa-file-code", - "description": "Build or run all references/analyses" - }, - "arriba": { - "type": "boolean", + "tools": { + "type": "string", + "description": "Comma-delimited list of tools to run", "fa_icon": "far fa-file-code", - "description": "Build or run arriba references/analyses" + "pattern": "^((arriba|ctatsplicing|fusioncatcher|starfusion|stringtie|fusionreport|fastp|salmon|fusioninspector|all)?,?)*(?\n \n \n \"nf-core/rnafusion\"\n \n\n\n[![GitHub Actions CI Status](https://github.com/nf-core/rnafusion/actions/workflows/nf-test.yml/badge.svg)](https://github.com/nf-core/rnafusion/actions/workflows/nf-test.yml)\n[![GitHub Actions Linting Status](https://github.com/nf-core/rnafusion/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/rnafusion/actions/workflows/linting.yml)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/rnafusion/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.2565517-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.2565517)\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%A524.10.5-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.3.2-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.3.2)\n[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/)\n[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/)\n[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/)\n[![Launch on Seqera Platform](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Seqera%20Platform-%234256e7)](https://cloud.seqera.io/launch?pipeline=https://github.com/nf-core/rnafusion)\n\n[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23rnafusion-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/rnafusion)[![Follow on Bluesky](https://img.shields.io/badge/bluesky-%40nf__core-1185fe?labelColor=000000&logo=bluesky)](https://bsky.app/profile/nf-co.re)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core)\n\n## Introduction\n\n**nf-core/rnafusion** is a bioinformatics best-practice analysis pipeline for RNA sequencing consisting of several tools designed for detecting and visualizing fusion genes. Results from up to 3 fusion callers tools are created, and are also aggregated, most notably in a pdf visualisation document, a vcf data collection file, and html and tsv reports.\n\nOn release, automated continuous integration tests run the pipeline on a full-sized dataset on the AWS cloud infrastructure. This ensures that the pipeline runs on AWS, has sensible resource allocation defaults set to run on real-world datasets, and permits the persistent storage of results to benchmark between pipeline releases and other analysis sources. The results obtained from the full-sized test can be viewed on the [nf-core website](https://nf-co.re/rnafusion/results).\n\nIn rnafusion the full-sized test includes reference building and fusion detection. The test dataset is taken from [here](https://github.com/nf-core/test-datasets/tree/rnafusion/testdata/human).\n\n## Pipeline summary\n\n![nf-core/rnafusion metro map](docs/images/nf-core-rnafusion_metro_map.png)\n\n### References\n\nThe references for the pipeline can be downloaded from the nf-core AWS megatests S3 bucket using the following command for the [AWS CLI tool](https://github.com/aws/aws-cli):\n\n```bash\naws --no-sign-request s3 sync s3://nf-core-awsmegatests/rnafusion/references/ \n```\n\nThe path to the downloaded references can then be provided to the pipeline with the `--genomes_base` parameter.\n\n\u26a0\ufe0f **Please note that the references are large and can take a long time to download, so it is recommended to download them once and use them for all future runs of the pipeline.**\n\nThe pipeline is also able to build the references in case files from a specific gencode version are missing (Note: only gencode 46 is available for fusioncatcher). This is done automatically when the expected references are not found and these files will be automatically published in the directory specified by the `--genomes_base` parameter. Use the `--references_only` parameter to trigger the reference building workflow only, without running the rest of the pipeline.\n\n1. Download gencode fasta and gtf files\n2. Download the HGNC nomenclature file\n3. Create files needed for QC (Sequence Dictionary and RRNA intervals)\n4. Convert the gtf file to a refflat file\n5. Create the [Salmon](https://salmon.readthedocs.io/en/latest/) index\n6. Create [STAR](https://github.com/alexdobin/STAR) index\n7. Build [STAR-Fusion](https://github.com/STAR-Fusion/STAR-Fusion) and [CTAT-SPLICING](https://github.com/TrinityCTAT/CTAT-SPLICING) references\n8. Download [Fusion-report](https://github.com/Clinical-Genomics/fusion-report) DBs\n\n> [!WARNING]\n> References for Fusioncatcher and Arriba cannot be automatically created by the pipeline and should be downloaded from the S3 bucket or another source. See the [References](#references) section for more information.\n\n#### Main workflow\n\n1. Input samplesheet check\n2. Reads quality control ([FastQC](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/))\n3. Optional trimming with [fastp](https://github.com/OpenGene/fastp)\n4. Align FASTQs to BAM with [STAR](https://github.com/alexdobin/STAR)\n5. Run fusion detection with [Arriba](https://github.com/suhrig/arriba)\n6. Run fusion detection with [STAR-Fusion](https://github.com/STAR-Fusion/STAR-Fusion)\n 7a. Optional trimming of 3' end with [fastp](https://github.com/OpenGene/fastp) to feed into fusioncatcher (other tools not affected)\n 7b. Run fusion detection with [FusionCatcher](https://github.com/ndaniel/fusioncatcher)\n7. Run transcript assembly and quantification with [StringTie](https://ccb.jhu.edu/software/stringtie/)\n8. Run cancer splicing aberrations detection with [CTAT-SPLICING](https://github.com/TrinityCTAT/CTAT-SPLICING)\n9. Merge all fusions detected by the selected tools with [Fusion-report](https://github.com/Clinical-Genomics/fusion-report)\n10. Post-processing and analysis of data\n - [FusionInspector](https://github.com/FusionInspector/FusionInspector)\n - Summarize information into a VCF file\n - [Arriba](https://github.com/suhrig/arriba) visualisation\n - Collect metrics ([`picard CollectRnaSeqMetrics`](https://gatk.broadinstitute.org/hc/en-us/articles/360037057492-CollectRnaSeqMetrics-Picard-)), [`picard CollectInsertSizeMetrics`](https://gatk.broadinstitute.org/hc/en-us/articles/360037055772-CollectInsertSizeMetrics-Picard-) and ([`GATK MarkDuplicates`](https://gatk.broadinstitute.org/hc/en-us/articles/360037052812-MarkDuplicates-Picard-))\n11. Present QC for raw reads ([`MultiQC`](http://multiqc.info/))\n12. Compress bam files to cram with [samtools view](http://www.htslib.org/)\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\nAs the reference building is computationally heavy (> 24h on HPC), we had to use dummy reference files in the test profile. Therefore, it is recommended to run the test profile with the `-stub` option.\n\n```bash\nnextflow run nf-core/rnafusion \\\n -profile test, \\\n --outdir \\\n -stub\n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\n> **Notes:**\n>\n> - Conda is not currently supported; run with singularity or docker.\n> - Paths need to be absolute.\n> - GRCh38 is the only supported reference.\n> - Single-end reads are to be used as last-resort. Paired-end reads are recommended. FusionCatcher cannot be used with single-end reads shorter than 130 bp.\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/rnafusion/usage) and the [parameter documentation](https://nf-co.re/rnafusion/parameters).\n\n## Pipeline output\n\nTo see the results of an example test run with a full size dataset refer to the [results](https://nf-co.re/rnafusion/results) tab on the nf-core website pipeline page.\nFor more details about the output files and reports, please refer to the\n[output documentation](https://nf-co.re/rnafusion/output).\n\n## Credits\n\nnf-core/rnafusion was written by Martin Proks ([@matq007](https://github.com/matq007)), Maxime Garcia ([@maxulysse](https://github.com/maxulysse)) and Annick Renevey ([@rannick](https://github.com/rannick))\n\n## We thank the following people for their help in the development of this pipeline\n\n- [Phil Ewels](https://github.com/ewels)\n- [Rickard Hammar\u00e9n](https://github.com/Hammarn)\n- [Alexander Peltzer](https://github.com/apeltzer)\n- [Praveen Raj](https://github.com/praveenraj2018)\n- [Anabella Trigila](https://github.com/atrigila)\n- [Nicolas Vannieuwkerke](https://github.com/nvnieuwk)\n\n## Contributions and Support\n\nIf you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md).\n\nFor further information or help, don't hesitate to get in touch on the [Slack `#rnafusion` channel](https://nfcore.slack.com/channels/rnafusion) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\nIf you use nf-core/rnafusion for your analysis, please cite it using the following doi: [10.5281/zenodo.3946477](https://doi.org/10.5281/zenodo.3946477)\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "hasPart": [ + { + "@id": "main.nf" + }, + { + "@id": "docs/images/nf-core-rnafusion_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": "CODE_OF_CONDUCT.md" + }, + { + "@id": "CITATIONS.md" + }, + { + "@id": "modules.json" + }, + { + "@id": "docs/usage.md" + }, + { + "@id": "docs/output.md" + }, + { + "@id": ".nf-core.yml" + }, + { + "@id": ".pre-commit-config.yaml" + }, + { + "@id": ".prettierignore" + } + ], + "isBasedOn": "https://github.com/nf-core/rnafusion", + "license": "MIT", + "mainEntity": { + "@id": "main.nf" + }, + "mentions": [ + { + "@id": "#22caf67a-5268-45f3-acca-9cff28a06eda" + } + ], + "name": "nf-core/rnafusion" + }, + { + "@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": "#max.u.garcia@gmail.com" + }, + { + "@id": "https://orcid.org/0000-0001-7411-6063" + }, + { + "@id": "https://orcid.org/0000-0002-8178-3128" + }, + { + "@id": "#phil.ewels@scilifelab.se" + }, + { + "@id": "https://orcid.org/0009-0003-5619-1555" + }, + { + "@id": "https://orcid.org/0000-0001-9017-591X" + } + ], + "dateCreated": "", + "dateModified": "2025-09-10T13:04:42Z", + "dct:conformsTo": "https://bioschemas.org/profiles/ComputationalWorkflow/1.0-RELEASE/", + "image": { + "@id": "docs/images/nf-core-rnafusion_metro_map.png" + }, + "keywords": [ + "nf-core", + "nextflow", + "fusion", + "fusion-genes", + "gene-fusion", + "rna", + "rna-seq" + ], + "license": [ + "MIT" + ], + "maintainer": [ + { + "@id": "https://orcid.org/0000-0001-7411-6063" + }, + { + "@id": "https://orcid.org/0000-0002-8178-3128" + }, + { + "@id": "https://orcid.org/0009-0003-5619-1555" + } + ], + "name": [ + "nf-core/rnafusion" + ], + "programmingLanguage": { + "@id": "https://w3id.org/workflowhub/workflow-ro-crate#nextflow" + }, + "sdPublisher": { + "@id": "https://nf-co.re/" + }, + "url": [ + "https://github.com/nf-core/rnafusion", + "https://nf-co.re/rnafusion/4.0.0/" + ], + "version": [ + "4.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": "!>=24.10.5" + }, + { + "@id": "docs/images/nf-core-rnafusion_metro_map.png", + "@type": [ + "File", + "ImageObject" + ], + "name": "Workflow diagram" + }, + { + "@id": "#22caf67a-5268-45f3-acca-9cff28a06eda", + "@type": "TestSuite", + "instance": [ + { + "@id": "#ee1eeb2c-e0a3-45fc-8770-0e80c9d1489b" + } + ], + "mainEntity": { + "@id": "main.nf" + }, + "name": "Test suite for nf-core/rnafusion" + }, + { + "@id": "#ee1eeb2c-e0a3-45fc-8770-0e80c9d1489b", + "@type": "TestInstance", + "name": "GitHub Actions workflow for testing nf-core/rnafusion", + "resource": "repos/nf-core/rnafusion/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": "CODE_OF_CONDUCT.md", + "@type": "File", + "description": "The nf-core code of conduct" + }, + { + "@id": "CITATIONS.md", + "@type": "File", + "description": "Citations needed when using the pipeline" + }, + { + "@id": "modules.json", + "@type": "File", + "description": "Version information for modules from nf-core/modules" + }, + { + "@id": "docs/usage.md", + "@type": "File", + "description": "Usage documentation" + }, + { + "@id": "docs/output.md", + "@type": "File", + "description": "Output documentation" + }, + { + "@id": ".nf-core.yml", + "@type": "File", + "description": "nf-core configuration file, configuring template features and linting rules" + }, + { + "@id": ".pre-commit-config.yaml", + "@type": "File", + "description": "Configuration file for pre-commit hooks" + }, + { + "@id": ".prettierignore", + "@type": "File", + "description": "Ignore file for prettier" + }, + { + "@id": "https://nf-co.re/", + "@type": "Organization", + "name": "nf-core", + "url": "https://nf-co.re/" + }, + { + "@id": "#max.u.garcia@gmail.com", + "@type": "Person", + "email": "max.u.garcia@gmail.com", + "name": "Maxime Garcia" + }, + { + "@id": "https://orcid.org/0000-0001-7411-6063", + "@type": "Person", + "email": "47788523+rannick@users.noreply.github.com", + "name": "Annick Renevey" + }, + { + "@id": "https://orcid.org/0000-0002-8178-3128", + "@type": "Person", + "email": "mproksik@gmail.com", + "name": "Martin Proks" + }, + { + "@id": "#phil.ewels@scilifelab.se", + "@type": "Person", + "email": "phil.ewels@scilifelab.se", + "name": "Phil Ewels" + }, + { + "@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-0001-9017-591X", + "@type": "Person", + "email": "rickard.hammaren@scilifelab.se", + "name": "Rickard Hammar\u00e9n" + } + ] +} \ No newline at end of file diff --git a/subworkflows/local/arriba_workflow.nf b/subworkflows/local/arriba_workflow.nf deleted file mode 100644 index f59018dc9..000000000 --- a/subworkflows/local/arriba_workflow.nf +++ /dev/null @@ -1,64 +0,0 @@ -include { ARRIBA } from '../../modules/nf-core/arriba/main' -include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_ARRIBA} from '../../modules/nf-core/samtools/index/main' -include { SAMTOOLS_SORT as SAMTOOLS_SORT_FOR_ARRIBA} from '../../modules/nf-core/samtools/sort/main' -include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_ARRIBA} from '../../modules/nf-core/samtools/view/main' -include { STAR_ALIGN as STAR_FOR_ARRIBA } from '../../modules/nf-core/star/align/main' - -workflow ARRIBA_WORKFLOW { - take: - reads - ch_gtf - ch_fasta - ch_starindex_ref - ch_arriba_ref_blacklist - ch_arriba_ref_known_fusions - ch_arriba_ref_protein_domains - - main: - ch_versions = Channel.empty() - ch_dummy_file = file("$baseDir/assets/dummy_file_arriba.txt", checkIfExists: true) - - if ((params.arriba || params.all) && !params.fusioninspector_only) { - - STAR_FOR_ARRIBA( reads, ch_starindex_ref, ch_gtf, params.star_ignore_sjdbgtf, '', params.seq_center ?: '') - ch_versions = ch_versions.mix(STAR_FOR_ARRIBA.out.versions) - - if (params.arriba_fusions) { - ch_arriba_fusions = reads.combine( Channel.value( file( params.arriba_fusions, checkIfExists: true ) ) ) - .map { meta, reads, fusions -> [ meta, fusions ] } - ch_arriba_fusion_fail = ch_dummy_file - } else { - ARRIBA ( STAR_FOR_ARRIBA.out.bam, ch_fasta, ch_gtf, ch_arriba_ref_blacklist, ch_arriba_ref_known_fusions, [[],[]], [[],[]], ch_arriba_ref_protein_domains ) - ch_versions = ch_versions.mix(ARRIBA.out.versions) - - ch_arriba_fusions = ARRIBA.out.fusions - ch_arriba_fusion_fail = ARRIBA.out.fusions_fail.map{ meta, file -> return file} - } - - if (params.cram.contains('arriba') ){ - - SAMTOOLS_SORT_FOR_ARRIBA(STAR_FOR_ARRIBA.out.bam) - ch_versions = ch_versions.mix(SAMTOOLS_SORT_FOR_ARRIBA.out.versions ) - - SAMTOOLS_VIEW_FOR_ARRIBA(SAMTOOLS_SORT_FOR_ARRIBA.out.bam.map { meta, bam -> [ meta, bam, [] ] }, ch_fasta, []) - ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_ARRIBA.out.versions ) - - SAMTOOLS_INDEX_FOR_ARRIBA(SAMTOOLS_VIEW_FOR_ARRIBA.out.cram) - ch_versions = ch_versions.mix(SAMTOOLS_INDEX_FOR_ARRIBA.out.versions ) - - } - - } - else { - ch_arriba_fusions = reads.combine(Channel.value( file(ch_dummy_file, checkIfExists:true ) ) ) - .map { meta, reads, fusions -> [ meta, fusions ] } - - ch_arriba_fusion_fail = ch_dummy_file - } - - emit: - fusions = ch_arriba_fusions - fusions_fail = ch_arriba_fusion_fail - versions = ch_versions - } - diff --git a/subworkflows/local/build_references/main.nf b/subworkflows/local/build_references/main.nf new file mode 100644 index 000000000..78d413709 --- /dev/null +++ b/subworkflows/local/build_references/main.nf @@ -0,0 +1,266 @@ +/* +======================================================================================== + IMPORT LOCAL MODULES/SUBWORKFLOWS +======================================================================================== +*/ + +include { GENCODE_DOWNLOAD } from '../../../modules/local/gencode_download/main' +include { HGNC_DOWNLOAD } from '../../../modules/local/hgnc/main' + +/* +======================================================================================== + IMPORT NF-CORE MODULES/SUBWORKFLOWS +======================================================================================== +*/ +include { UCSC_GTFTOGENEPRED } from '../../../modules/nf-core/ucsc/gtftogenepred/main' +include { CTATSPLICING_PREPGENOMELIB } from '../../../modules/nf-core/ctatsplicing/prepgenomelib/main.nf' +include { BIOAWK } from '../../../modules/nf-core/bioawk/main' +include { AGAT_CONVERTGFF2BED } from '../../../modules/nf-core/agat/convertgff2bed/main' +include { SAMTOOLS_FAIDX } from '../../../modules/nf-core/samtools/faidx/main' +include { STAR_GENOMEGENERATE } from '../../../modules/nf-core/star/genomegenerate/main' +include { GATK4_CREATESEQUENCEDICTIONARY } from '../../../modules/nf-core/gatk4/createsequencedictionary/main' +include { GATK4_BEDTOINTERVALLIST } from '../../../modules/nf-core/gatk4/bedtointervallist/main' +include { SALMON_INDEX } from '../../../modules/nf-core/salmon/index/main' +include { FUSIONREPORT_DOWNLOAD } from '../../../modules/nf-core/fusionreport/download/main' +include { STARFUSION_BUILD } from '../../../modules/nf-core/starfusion/build/main' +include { GFFREAD } from '../../../modules/nf-core/gffread/main' + +/* +======================================================================================== + RUN MAIN WORKFLOW +======================================================================================== +*/ + +workflow BUILD_REFERENCES { + + take: + tools // list of all the tools to create references for + + main: + def ch_versions = Channel.empty() + + def ch_fasta = Channel.empty() + def ch_gtf = Channel.empty() + if (!exists_not_empty(params.fasta) || !exists_not_empty(params.gtf)){ + GENCODE_DOWNLOAD(params.genome_gencode_version, params.genome) + ch_versions = ch_versions.mix(GENCODE_DOWNLOAD.out.versions) + ch_fasta = GENCODE_DOWNLOAD.out.fasta.map { that -> [[id:that.Name], that] } + ch_gtf = GENCODE_DOWNLOAD.out.gtf.map { that -> [[id:that.Name], that] } + } else { + ch_fasta = Channel.fromPath(params.fasta).map { that -> [[id:that.Name], that] } + ch_gtf = Channel.fromPath(params.gtf).map { that -> [[id:that.Name], that] } + } + + def ch_fai = Channel.empty() + if (!exists_not_empty(params.fai)){ + SAMTOOLS_FAIDX(ch_fasta, [[],[]], false) + ch_versions = ch_versions.mix(SAMTOOLS_FAIDX.out.versions) + ch_fai = SAMTOOLS_FAIDX.out.fai + } else { + ch_fai = Channel.fromPath(params.fai).map { that -> [[id:that.Name], that] } + } + + def ch_hgnc_date = Channel.empty() + def ch_hgnc_ref = Channel.empty() + //TODO: unify as if(tools.contains("fusioninspector")) once nextflow bug fixed + def run_fusioninspector = tools.contains("fusioninspector") + if(run_fusioninspector && !params.skip_vcf) { + if ((!exists_not_empty(params.hgnc_ref) || !exists_not_empty(params.hgnc_date)) && !params.skip_vcf){ + HGNC_DOWNLOAD( ) + ch_versions = ch_versions.mix(HGNC_DOWNLOAD.out.versions) + ch_hgnc_ref = HGNC_DOWNLOAD.out.hgnc_ref.map { that -> [[id:that.Name], that] } + ch_hgnc_date = HGNC_DOWNLOAD.out.hgnc_date.map { that -> [[id:that.Name], that] } + } else { + ch_hgnc_ref = Channel.fromPath(params.hgnc_ref).map { that -> [[id:that.Name], that] } + ch_hgnc_date = Channel.fromPath(params.hgnc_date).map { that -> [[id:that.Name], that] } + } + } + + def ch_rrna_interval = Channel.empty() + if (!params.skip_qc) { + if (!exists_not_empty(params.rrna_intervals)){ + GATK4_CREATESEQUENCEDICTIONARY(ch_fasta) + ch_versions = ch_versions.mix(GATK4_CREATESEQUENCEDICTIONARY.out.versions) + + BIOAWK(ch_gtf) + ch_versions = ch_versions.mix(BIOAWK.out.versions) + + AGAT_CONVERTGFF2BED(BIOAWK.out.output) + ch_versions = ch_versions.mix(AGAT_CONVERTGFF2BED.out.versions) + + GATK4_BEDTOINTERVALLIST(AGAT_CONVERTGFF2BED.out.bed, GATK4_CREATESEQUENCEDICTIONARY.out.dict ) + ch_versions = ch_versions.mix(GATK4_BEDTOINTERVALLIST.out.versions) + + ch_rrna_interval = GATK4_BEDTOINTERVALLIST.out.interval_list + } else { + ch_rrna_interval = Channel.fromPath(params.rrna_intervals).map { that -> [[id:that.Name], that] } + } + } + + def ch_refflat = Channel.empty() + if (!params.skip_qc) { + if (!exists_not_empty(params.refflat)){ + UCSC_GTFTOGENEPRED(ch_gtf) + ch_versions = ch_versions.mix(UCSC_GTFTOGENEPRED.out.versions) + ch_refflat = UCSC_GTFTOGENEPRED.out.refflat.map { meta, rf -> [[id: meta.id], rf] } + } else { + ch_refflat = Channel.fromPath(params.refflat).map { that -> [[id:that.Name], that] } + } + } + + def ch_salmon_index = Channel.empty() + if (tools.contains("salmon")) { + if (!params.skip_qc) { + if (!exists_not_empty(params.salmon_index)){ + GFFREAD(ch_gtf, ch_fasta.map{ it -> it[1] }) + ch_versions = ch_versions.mix(GFFREAD.out.versions) + + SALMON_INDEX(ch_fasta.map{ it -> it[1] }, GFFREAD.out.gffread_fasta.map{ it -> it[1] }) + ch_versions = ch_versions.mix(SALMON_INDEX.out.versions) + ch_salmon_index = SALMON_INDEX.out.index + } else { + ch_salmon_index = Channel.fromPath(params.salmon_index) + } + } + } + + def ch_starindex_ref = Channel.empty() + def star_index_tools = tools.intersect(["starfusion", "arriba", "ctatsplicing", "stringtie"]) + if (star_index_tools) { + if (!exists_not_empty(params.starindex_ref)) { + STAR_GENOMEGENERATE(ch_fasta, ch_gtf) + ch_versions = ch_versions.mix(STAR_GENOMEGENERATE.out.versions) + ch_starindex_ref = STAR_GENOMEGENERATE.out.index + } else { + ch_starindex_ref = Channel.fromPath(params.starindex_ref).map { that -> [[id:that.Name], that] } + } + } + + def ch_arriba_ref_blacklist = params.arriba_ref_blacklist ? Channel.fromPath(params.arriba_ref_blacklist) : Channel.empty() + def ch_arriba_ref_cytobands = params.arriba_ref_cytobands ? Channel.fromPath(params.arriba_ref_cytobands) : Channel.empty() + def ch_arriba_ref_known_fusions = params.arriba_ref_known_fusions ? Channel.fromPath(params.arriba_ref_known_fusions) : Channel.empty() + def ch_arriba_ref_protein_domains = params.arriba_ref_protein_domains ? Channel.fromPath(params.arriba_ref_protein_domains) : Channel.empty() + + def ch_fusioncatcher_ref = params.fusioncatcher_ref ? Channel.fromPath(params.fusioncatcher_ref).map { it -> [[id:it.name], it] } : Channel.empty() + + def ch_starfusion_ref = Channel.empty() + if (tools.intersect(["starfusion", "ctatsplicing", "fusioninspector"])) { + if (!exists_not_empty(params.starfusion_ref)) { + if(!params.fusion_annot_lib) { + error("Expected --fusion_annot_lib to be specified when using StarFusion or any tools that depend on it") + } + + if(params.pfam_file) { + pfam_file = Channel.fromPath(params.pfam_file, checkIfExists: true) + } else { + error("Expected `--pfam_version` to be specified when using StarFusion to automatically fill in Pfam database or specify `--pfam_file` for custom input") + } + + if(params.dfam_hmm && params.dfam_h3p && params.dfam_h3m && params.dfam_h3i && params.dfam_h3f) { + dfam_hmm = Channel.fromPath(params.dfam_hmm, checkIfExists: true) + dfam_h3f = Channel.fromPath(params.dfam_h3f, checkIfExists: true) + dfam_h3i = Channel.fromPath(params.dfam_h3i, checkIfExists: true) + dfam_h3m = Channel.fromPath(params.dfam_h3m, checkIfExists: true) + dfam_h3p = Channel.fromPath(params.dfam_h3p, checkIfExists: true) + } else { + error("Expected `--dfam_version` and `--species` to be specified when using StarFusion to automatically fill in Dfam database or specify `--dfam_{hmm,h3f,h3i,h3m,h3p}` for custom input") + } + + dfam_urls_ch = dfam_hmm + .concat( + dfam_h3f, + dfam_h3i, + dfam_h3m, + dfam_h3p + ) + .collect() + + STARFUSION_BUILD(ch_fasta, ch_gtf, params.fusion_annot_lib, params.species, pfam_file, dfam_urls_ch, params.annot_filter_url) + ch_versions = ch_versions.mix(STARFUSION_BUILD.out.versions) + if (tools.contains("ctatsplicing")) { + CTATSPLICING_PREPGENOMELIB( + STARFUSION_BUILD.out.reference, + params.ctatsplicing_cancer_introns + ) + ch_versions = ch_versions.mix(CTATSPLICING_PREPGENOMELIB.out.versions) + ch_starfusion_ref = CTATSPLICING_PREPGENOMELIB.out.reference + } else { + ch_starfusion_ref = STARFUSION_BUILD.out.reference + } + } + else { + ch_starfusion_ref = Channel.fromPath(params.starfusion_ref).map { it -> [[id:it.name], it] } + } + } + + def ch_fusionreport_ref = Channel.empty() + if (tools.contains("fusionreport")) { + if (!exists_not_empty(params.fusionreport_ref)) { + if (!params.no_cosmic && (!params.cosmic_username || !params.cosmic_passwd)) { + error('COSMIC username and/or password missing, this is needed to download the fusionreport reference') + } + FUSIONREPORT_DOWNLOAD() + ch_versions = ch_versions.mix(FUSIONREPORT_DOWNLOAD.out.versions) + ch_fusionreport_ref = FUSIONREPORT_DOWNLOAD.out.fusionreport_ref + } else { + ch_fusionreport_ref = Channel.fromPath(params.fusionreport_ref).map { that -> [[id:that.Name], that] } + } + } + + emit: + fasta = ch_fasta.collect() + gtf = ch_gtf.collect() + fai = ch_fai.collect() + hgnc_ref = ch_hgnc_ref.collect() + hgnc_date = ch_hgnc_date.collect() + rrna_interval = ch_rrna_interval.collect() + refflat = ch_refflat.collect() + salmon_index = ch_salmon_index.collect() + starindex_ref = ch_starindex_ref.collect() + arriba_ref_blacklist = ch_arriba_ref_blacklist.collect() + arriba_ref_cytobands = ch_arriba_ref_cytobands.collect() + arriba_ref_known_fusions = ch_arriba_ref_known_fusions.collect() + arriba_ref_protein_domains = ch_arriba_ref_protein_domains.collect() + fusioncatcher_ref = ch_fusioncatcher_ref.collect() + starfusion_ref = ch_starfusion_ref.collect() + fusionreport_ref = ch_fusionreport_ref.collect() + versions = ch_versions +} + +/* +======================================================================================== + FUNCTIONS +======================================================================================== +*/ + +// +// A function to test if a file exists and is not empty. +// Input: A string that represents a file path +// Output: A boolean +// +def exists_not_empty(path) { + // Return false for invalid values + if(!path) { + return false + } + + def path_to_check = file(path as String) + // Return false if the path does not exist + if(!path_to_check.exists()) { + return false + } + + // Don't check directories if the path is not local + def is_local = path_to_check.getScheme() == "file" + if(!is_local || !path_to_check.toFile().isDirectory()) { + return !path_to_check.isEmpty() + } + + // Get the first file in a directory and return whether it is empty or not + def first_file = null + path_to_check.toFile().eachFileRecurse(groovy.io.FileType.FILES) { file -> + first_file = file + return + } + return !first_file.toPath().isEmpty() +} diff --git a/adapter_fasta_test b/subworkflows/local/build_references/tests/empty_folder/empty_file.txt similarity index 100% rename from adapter_fasta_test rename to subworkflows/local/build_references/tests/empty_folder/empty_file.txt diff --git a/subworkflows/local/build_references/tests/functions.nf.test b/subworkflows/local/build_references/tests/functions.nf.test new file mode 100644 index 000000000..2933918eb --- /dev/null +++ b/subworkflows/local/build_references/tests/functions.nf.test @@ -0,0 +1,273 @@ + +nextflow_function { + + name "Test Functions" + script "subworkflows/local/build_references/main.nf" + + test("Test Function exists_not_empty - local file exists") { + + function "exists_not_empty" + + when { + function { + """ + input[0] = "${projectDir}/main.nf" + """ + } + } + + then { + assert function.success + assert function.result == true + } + + } + + test("Test Function exists_not_empty - local directory exists") { + + function "exists_not_empty" + + when { + function { + """ + input[0] = "${projectDir}/assets" + """ + } + } + + then { + assert function.success + assert function.result == true + } + + } + + test("Test Function exists_not_empty - local file not exists") { + + function "exists_not_empty" + + when { + function { + """ + input[0] = "${projectDir}/non_existing_file.txt" + """ + } + } + + then { + assert function.success + assert function.result == false + } + + } + + test("Test Function exists_not_empty - local directory not exists") { + + function "exists_not_empty" + + when { + function { + """ + input[0] = "${projectDir}/non_existing_directory" + """ + } + } + + then { + assert function.success + assert function.result == false + } + + } + + test("Test Function exists_not_empty - local file empty") { + + function "exists_not_empty" + + when { + function { + """ + input[0] = "${projectDir}/subworkflows/local/build_references/tests/empty_folder/empty_file.txt" + """ + } + } + + then { + assert function.success + assert function.result == false + } + + } + + test("Test Function exists_not_empty - local directory empty") { + + function "exists_not_empty" + + when { + function { + """ + input[0] = "${projectDir}/subworkflows/local/build_references/tests/empty_folder/" + """ + } + } + + then { + assert function.success + assert function.result == false + } + + } + + test("Test Function exists_not_empty - HTTPS file exists") { + + function "exists_not_empty" + + when { + function { + """ + input[0] = "https://github.com/nf-core/test-datasets/raw/afe31d4ea9be70bbaaf1fb633a4ae7a4afeaf215/README.md" + """ + } + } + + then { + assert function.success + assert function.result == true + } + + } + + test("Test Function exists_not_empty - HTTPS directory exists") { + + function "exists_not_empty" + + when { + function { + """ + input[0] = "https://github.com/nf-core/test-datasets/raw/afe31d4ea9be70bbaaf1fb633a4ae7a4afeaf215/testdata/" + """ + } + } + + then { + assert function.success + assert function.result == true + } + + } + + test("Test Function exists_not_empty - HTTPS file not exists") { + + function "exists_not_empty" + + when { + function { + """ + input[0] = "https://github.com/nf-core/test-datasets/raw/afe31d4ea9be70bbaaf1fb633a4ae7a4afeaf215/non_existing_file.txt" + """ + } + } + + then { + assert function.success + assert function.result == false + } + + } + + test("Test Function exists_not_empty - HTTPS directory not exists") { + + function "exists_not_empty" + + when { + function { + """ + input[0] = "https://github.com/nf-core/test-datasets/raw/afe31d4ea9be70bbaaf1fb633a4ae7a4afeaf215/non_existing_directory/" + """ + } + } + + then { + assert function.success + assert function.result == false + } + + } + + test("Test Function exists_not_empty - s3 file exists") { + + function "exists_not_empty" + + when { + function { + """ + input[0] = "s3://ngi-igenomes/igenomes/Homo_sapiens/Ensembl/GRCh37/Sequence/WholeGenomeFasta/genome.fa" + """ + } + } + + then { + assert function.success + assert function.result == true + } + + } + + test("Test Function exists_not_empty - s3 directory exists") { + + function "exists_not_empty" + + when { + function { + """ + input[0] = "s3://ngi-igenomes/igenomes/Homo_sapiens/Ensembl/GRCh37/Sequence/WholeGenomeFasta/" + """ + } + } + + then { + assert function.success + assert function.result == true + } + + } + + test("Test Function exists_not_empty - s3 file not exists") { + + function "exists_not_empty" + + when { + function { + """ + input[0] = "s3://ngi-igenomes/igenomes/this_file_does_not_exist.txt" + """ + } + } + + then { + assert function.success + assert function.result == false + } + + } + + test("Test Function exists_not_empty - s3 directory not exists") { + + function "exists_not_empty" + + when { + function { + """ + input[0] = "s3://ngi-igenomes/igenomes/this_directory_does_not_exist/" + """ + } + } + + then { + assert function.success + assert function.result == false + } + + } + +} diff --git a/subworkflows/local/fusioncatcher_workflow.nf b/subworkflows/local/fusioncatcher_workflow.nf deleted file mode 100644 index ebb09e60f..000000000 --- a/subworkflows/local/fusioncatcher_workflow.nf +++ /dev/null @@ -1,34 +0,0 @@ -include { FUSIONCATCHER } from '../../modules/local/fusioncatcher/detect/main' - - -workflow FUSIONCATCHER_WORKFLOW { - take: - reads - - main: - ch_versions = Channel.empty() - ch_dummy_file = file("$baseDir/assets/dummy_file_fusioncatcher.txt", checkIfExists: true) - - if ((params.fusioncatcher || params.all) && !params.fusioninspector_only) { - if (params.fusioncatcher_fusions){ - ch_fusioncatcher_fusions = reads.combine(Channel.value(file(params.fusioncatcher_fusions, checkIfExists:true))) - .map { meta, reads, fusions -> [ meta, fusions ] } - } else { - FUSIONCATCHER ( - reads, - params.fusioncatcher_ref - ) - ch_fusioncatcher_fusions = FUSIONCATCHER.out.fusions - ch_versions = ch_versions.mix(FUSIONCATCHER.out.versions) - } - } - else { - ch_fusioncatcher_fusions = reads.combine(Channel.value(file(ch_dummy_file, checkIfExists:true))) - .map { meta, reads, fusions -> [ meta, fusions ] } - } - - emit: - fusions = ch_fusioncatcher_fusions - versions = ch_versions - } - diff --git a/subworkflows/local/fusioncatcher_workflow/main.nf b/subworkflows/local/fusioncatcher_workflow/main.nf new file mode 100644 index 000000000..d842fa291 --- /dev/null +++ b/subworkflows/local/fusioncatcher_workflow/main.nf @@ -0,0 +1,47 @@ +include { FASTP as FASTP_FOR_FUSIONCATCHER } from '../../../modules/nf-core/fastp/main' +include { FUSIONCATCHER_FUSIONCATCHER } from '../../../modules/nf-core/fusioncatcher/fusioncatcher/main' + +// TODO: Remove fusioncatcher_fusions as parameter. +// TODO: remove dummy file. Work with Channel.empty() +// TODO: if the files were already produced and the user want to skip the module because of this, they should be taken them from the sample sheet + +workflow FUSIONCATCHER_WORKFLOW { + take: + reads // channel [ meta, [ fastqs ] ] + fusioncatcher_trimming // boolean + adapter_fasta // channel [ path ] + fusioncatcher_ref // channel [ meta, path ] + fusioncatcher_fusions // path, string + + main: + ch_versions = Channel.empty() + + if (fusioncatcher_fusions){ + + ch_fusioncatcher_fusions = reads.combine(Channel.value(file(fusioncatcher_fusions, checkIfExists:true))) + .map { meta, _reads, fusions -> [ meta, fusions ] } + } else { + if (fusioncatcher_trimming) { + FASTP_FOR_FUSIONCATCHER( + reads, + adapter_fasta, + false, // discard_trimmed_pass + false, // save_trimmed_fail + false // skip_qc + ) + ch_versions = ch_versions.mix(FASTP_FOR_FUSIONCATCHER.out.versions) + reads = FASTP_FOR_FUSIONCATCHER.out.reads + } + + FUSIONCATCHER_FUSIONCATCHER ( + reads, + fusioncatcher_ref + ) + ch_fusioncatcher_fusions = FUSIONCATCHER_FUSIONCATCHER.out.fusions + ch_versions = ch_versions.mix(FUSIONCATCHER_FUSIONCATCHER.out.versions) + } + + emit: + fusions = ch_fusioncatcher_fusions // channel [ meta, fusions ] + versions = ch_versions // channel [ versions ] + } diff --git a/subworkflows/local/fusioncatcher_workflow/tests/main.nf.test b/subworkflows/local/fusioncatcher_workflow/tests/main.nf.test new file mode 100644 index 000000000..cca6c6e2d --- /dev/null +++ b/subworkflows/local/fusioncatcher_workflow/tests/main.nf.test @@ -0,0 +1,53 @@ +nextflow_workflow { + + name "Test Subworkflow FUSIONCATCHER_WORKFLOW" + script "../main.nf" + workflow "FUSIONCATCHER_WORKFLOW" + + tag "subworkflow" + tag "fusioncatcher_workflow" + tag "fusioncatcher" + + test("FUSIONCATCHER_WORKFLOW - Stub") { + options "-stub" + + when { + workflow { + """ + // Input channels + input[0] = Channel.of( + [ [ id:'test_sample' ], + file("https://github.com/nf-core/test-datasets/raw/rnafusion/testdata/human/reads_1.fq.gz"), + file("https://github.com/nf-core/test-datasets/raw/rnafusion/testdata/human/reads_2.fq.gz") ] + ) + + input[1] = true + + input[2] = [] + + input[3] = [ + [ id:'fusioncatcher_ref' ], + [] + ] + + input[4] = [] + + """ + } + params { + tools = 'fusioncatcher' + trim_tail_fusioncatcher = 50 + outdir = "$outputDir" + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.versions + ).match() } + ) + } + } +} diff --git a/subworkflows/local/fusioncatcher_workflow/tests/main.nf.test.snap b/subworkflows/local/fusioncatcher_workflow/tests/main.nf.test.snap new file mode 100644 index 000000000..ec8b6cd3d --- /dev/null +++ b/subworkflows/local/fusioncatcher_workflow/tests/main.nf.test.snap @@ -0,0 +1,15 @@ +{ + "FUSIONCATCHER_WORKFLOW - Stub": { + "content": [ + [ + "versions.yml:md5,24a191a82bb19899f88f6493ad4f1b8c", + "versions.yml:md5,ec8d5c08a6f0c436e14c29931cc92379" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-09-10T09:33:14.158266322" + } +} \ No newline at end of file diff --git a/subworkflows/local/fusioninspector_workflow.nf b/subworkflows/local/fusioninspector_workflow.nf deleted file mode 100644 index f521ae8cb..000000000 --- a/subworkflows/local/fusioninspector_workflow.nf +++ /dev/null @@ -1,65 +0,0 @@ -include { AGAT_CONVERTSPGFF2TSV } from '../../modules/nf-core/agat/convertspgff2tsv/main' -include { ARRIBA_VISUALISATION } from '../../modules/local/arriba/visualisation/main' -include { CAT_CAT } from '../../modules/nf-core/cat/cat/main' -include { VCF_COLLECT } from '../../modules/local/vcf_collect/main' -include { FUSIONINSPECTOR } from '../../modules/local/fusioninspector/main' - -workflow FUSIONINSPECTOR_WORKFLOW { - take: - reads - fusion_list - fusion_list_filtered - fusionreport_out - fusionreport_csv - bam_sorted_indexed - ch_gtf - ch_arriba_ref_protein_domains - ch_arriba_ref_cytobands - ch_hgnc_ref - ch_hgnc_date - - main: - ch_versions = Channel.empty() - ch_arriba_visualisation = Channel.empty() - index ="${params.starfusion_ref}" - - ch_fusion_list = ( params.tools_cutoff > 1 ? fusion_list_filtered : fusion_list ) - .branch{ - no_fusions: it[1].size() == 0 - fusions: it[1].size() > 0 - } - - if (params.whitelist) { - ch_whitelist = ch_fusion_list.fusions.combine(Channel.value(file(params.whitelist, checkIfExists:true))) - .map { meta, fusions, whitelist -> [ meta, [fusions, whitelist] ] } - - CAT_CAT(ch_whitelist) // fusioninspector takes care of possible duplicates - ch_versions = ch_versions.mix(CAT_CAT.out.versions) - ch_reads_fusion = reads.join(CAT_CAT.out.file_out ) - } - else { - ch_reads_fusion = reads.join(ch_fusion_list.fusions ) - } - - FUSIONINSPECTOR( ch_reads_fusion, index) - ch_versions = ch_versions.mix(FUSIONINSPECTOR.out.versions) - - AGAT_CONVERTSPGFF2TSV(FUSIONINSPECTOR.out.out_gtf) - ch_versions = ch_versions.mix(AGAT_CONVERTSPGFF2TSV.out.versions) - - fusion_data = FUSIONINSPECTOR.out.tsv_coding_effect.join(AGAT_CONVERTSPGFF2TSV.out.tsv).join(fusionreport_out).join(fusionreport_csv) - VCF_COLLECT(fusion_data, ch_hgnc_ref, ch_hgnc_date) - ch_versions = ch_versions.mix(VCF_COLLECT.out.versions) - - if ((params.starfusion || params.all || params.stringtie) && !params.fusioninspector_only && !params.skip_vis) { - ch_bam_sorted_indexed_fusions = bam_sorted_indexed.join(FUSIONINSPECTOR.out.tsv) - ARRIBA_VISUALISATION(ch_bam_sorted_indexed_fusions, ch_gtf, ch_arriba_ref_protein_domains, ch_arriba_ref_cytobands) - ch_versions = ch_versions.mix(ARRIBA_VISUALISATION.out.versions) - ch_arriba_visualisation = ARRIBA_VISUALISATION.out.pdf - } - - emit: - ch_arriba_visualisation - versions = ch_versions -} - diff --git a/subworkflows/local/fusioninspector_workflow/main.nf b/subworkflows/local/fusioninspector_workflow/main.nf new file mode 100644 index 000000000..6fb7e86d2 --- /dev/null +++ b/subworkflows/local/fusioninspector_workflow/main.nf @@ -0,0 +1,84 @@ +include { AGAT_CONVERTSPGFF2TSV } from '../../../modules/nf-core/agat/convertspgff2tsv/main' +include { ARRIBA_VISUALISATION } from '../../../modules/nf-core/arriba/visualisation/main' +include { CAT_CAT } from '../../../modules/nf-core/cat/cat/main' +include { VCF_COLLECT } from '../../../modules/local/vcf_collect/main' +include { FUSIONINSPECTOR } from '../../../modules/nf-core/fusioninspector/main' + +workflow FUSIONINSPECTOR_WORKFLOW { + take: + reads + fusion_list + fusion_list_filtered + fusionreport_out + fusionreport_csv + bam_sorted_indexed + ch_gtf + ch_arriba_ref_protein_domains + ch_arriba_ref_cytobands + ch_hgnc_ref + ch_hgnc_date + ch_starfusion_ref + skip_vis + skip_vcf + tools_cutoff + whitelist + + main: + ch_versions = Channel.empty() + ch_arriba_visualisation = Channel.empty() + + ch_fusion_list = ( tools_cutoff > 1 ? fusion_list_filtered : fusion_list ) + + if (whitelist) { + ch_whitelist = ch_fusion_list.combine(Channel.value(file(whitelist, checkIfExists:true))) + .map { meta, fusions, whitelist_file -> [ meta, [fusions, whitelist_file] ] } + + CAT_CAT(ch_whitelist) // fusioninspector takes care of possible duplicates + ch_versions = ch_versions.mix(CAT_CAT.out.versions) + ch_reads_fusion = reads.join(CAT_CAT.out.file_out ) + } + else { + ch_reads_fusion = reads.join(ch_fusion_list) + } + + FUSIONINSPECTOR( ch_reads_fusion, ch_starfusion_ref) + ch_versions = ch_versions.mix(FUSIONINSPECTOR.out.versions) + + def tsv_nonempty = FUSIONINSPECTOR.out.tsv.filter { _meta, file -> file.exists() && file.size() > 0 } + def tsv_abridged_nonempty = FUSIONINSPECTOR.out.abridged_tsv.filter { _meta, file -> file.exists() && file.size() > 0 } + def gtf_nonempty = FUSIONINSPECTOR.out.out_gtf.filter { _meta, file -> file.exists() && file.size() > 0 } + if (!tsv_nonempty) { + log.warn("FUSIONINSPECTOR confirmed no fusions, skipping VCF and visualisation steps.") + } + if ( + !skip_vcf + ) { + AGAT_CONVERTSPGFF2TSV(gtf_nonempty) + ch_versions = ch_versions.mix(AGAT_CONVERTSPGFF2TSV.out.versions) + + fusion_data = tsv_abridged_nonempty + .join(AGAT_CONVERTSPGFF2TSV.out.tsv) + .join(fusionreport_out) + .join(fusionreport_csv) + + VCF_COLLECT(fusion_data, ch_hgnc_ref, ch_hgnc_date) + ch_versions = ch_versions.mix(VCF_COLLECT.out.versions) + } + if ( + !skip_vis + ) { + ch_bam_sorted_indexed_fusions = bam_sorted_indexed.join(tsv_nonempty) + ARRIBA_VISUALISATION( + ch_bam_sorted_indexed_fusions, + ch_gtf, + ch_arriba_ref_protein_domains.map { it -> [[id:it.name], it]}, + ch_arriba_ref_cytobands.map { it -> [[id:it.name], it]} + ) + ch_versions = ch_versions.mix(ARRIBA_VISUALISATION.out.versions) + ch_arriba_visualisation = ARRIBA_VISUALISATION.out.pdf + } + + emit: + ch_arriba_visualisation + versions = ch_versions +} diff --git a/subworkflows/local/fusioninspector_workflow/tests/main.nf.test b/subworkflows/local/fusioninspector_workflow/tests/main.nf.test new file mode 100644 index 000000000..37034d577 --- /dev/null +++ b/subworkflows/local/fusioninspector_workflow/tests/main.nf.test @@ -0,0 +1,231 @@ +nextflow_workflow { + + name "Test Workflow FUSIONINSPECTOR_WORKFLOW" + script "../main.nf" + workflow "FUSIONINSPECTOR_WORKFLOW" + config './nextflow.config' + tag 'subworkflows' + tag 'subworkflows/fusioninspector_workflow' + tag 'cat/cat' + tag 'subworkflows_nfcore' + tag 'fusionreport/detect' + tag 'fusioninspector' + tag 'starfusion/build' + tag 'fusionreport/download' + tag 'arriba/visualisation' + tag 'subworkflows/../../modules/local/vcf_collect' + tag 'agat/convertspgff2tsv' + + test("FUSIONINSPECTOR_WORKFLOW - human") { + + setup { + run("STARFUSION_BUILD") { + script "../../../../modules/nf-core/starfusion/build/main.nf" + process { + """ + input[0] = [ + [ id:'minigenome_fasta' ], + file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/minigenome.fa') + ] + input[1] = [ + [ id:'minigenome_gtf' ], + file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/minigenome.gtf') + ] + input[2] = file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/CTAT_HumanFusionLib.mini.dat.gz') + input[3] = "homo_sapiens" + input[4] = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/Pfam-A.hmm.gz" + input[5] = [ + "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/test_starfusion_dfam.hmm", + "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/test_starfusion_dfam.hmm.h3f", + "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/test_starfusion_dfam.hmm.h3i", + "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/test_starfusion_dfam.hmm.h3m", + "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/test_starfusion_dfam.hmm.h3p" + ] + input[6] = "https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/AnnotFilterRule.pm" + """ + } + } + + run("FUSIONREPORT_DOWNLOAD") { + script "../../../../modules/nf-core/fusionreport/download/main.nf" + process { + """ + """ + } + } + + run("FUSIONREPORT_DETECT") { + script "../../../../modules/nf-core/fusionreport/detect/main.nf" + process { + """ + input[0] = Channel.of([ + [ id:'test_sample' ], // meta map + file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/arriba.tsv', checkIfExists: true), + file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/starfusion.tsv', checkIfExists: true), + file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/fusioncatcher.txt', checkIfExists: true) + ]) + input[1] = FUSIONREPORT_DOWNLOAD.out.fusionreport_ref + input[2] = 1 + """ + } + } + } + + when { + params { + no_cosmic = true + whitelist = "" + outdir = "test" + genomes_base = "test" + fusionreport_download_args = '--no-cosmic' + fusionreport_detect_args = "--no-cosmic" + fusionreport_detect_args2 = "--export csv" + } + workflow { + """ + input[0] = Channel.of( + [ [ id:'test_sample' ], + [ + file("https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/v0.0.1/rnaseq_1.fastq.gz"), + file("https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/v0.0.1/rnaseq_2.fastq.gz") + ] + ]) + input[1] = Channel.of([ [id:'test_sample'], file("https://github.com/FusionInspector/FusionInspector/raw/master/test/fusion_targets.A.txt")]) + input[2] = Channel.of([ [id:'test_sample'], file("https://github.com/FusionInspector/FusionInspector/raw/master/test/fusion_targets.A.txt")]) + input[3] = FUSIONREPORT_DETECT.out.report + input[4] = FUSIONREPORT_DETECT.out.csv + input[5] = Channel.of([[ id:'test', single_end:false ], // meta map + file("https://github.com/nf-core/test-datasets/raw/modules/data/genomics/homo_sapiens/illumina/bam/test.paired_end.markduplicates.sorted.bam", checkIfExists: true), + file("https://github.com/nf-core/test-datasets/raw/modules/data/genomics/homo_sapiens/illumina/bam/test.paired_end.markduplicates.sorted.bam.bai", checkIfExists: true) + ]) + input[6] = Channel.of( + [ [ id:'test_gtf' ], + file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/minigenome.gtf')]) + input[7] = Channel.fromPath("https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3") + input[8] = Channel.fromPath("https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv") + input[9] = Channel.of([[ id:'hgnc' ], file("https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/hgnc/hgnc_complete_set.txt")] ) + input[10] = Channel.of([[ id:'hgnc_timestamp' ], file("https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/hgnc/HGNC-DB-timestamp.txt")] ) + input[11] = STARFUSION_BUILD.out.reference + input[12] = false + input[13] = true + input[14] = 1 + input[15] = null + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out.versions).match() } + ) + } + } + + test("FUSIONINSPECTOR_WORKFLOW - human - stub") { + options "-stub" + + setup { + run("STARFUSION_BUILD") { + script "../../../../modules/nf-core/starfusion/build/main.nf" + process { + """ + input[0] = [ + [ id:'minigenome_fasta' ], + file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/minigenome.fa') + ] + input[1] = [ + [ id:'minigenome_gtf' ], + file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/minigenome.gtf') + ] + input[2] = file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/CTAT_HumanFusionLib.mini.dat.gz') + input[3] = "homo_sapiens" + input[4] = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/Pfam-A.hmm.gz" + input[5] = [ + "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/test_starfusion_dfam.hmm", + "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/test_starfusion_dfam.hmm.h3f", + "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/test_starfusion_dfam.hmm.h3i", + "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/test_starfusion_dfam.hmm.h3m", + "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/human/test_starfusion_dfam.hmm.h3p" + ] + input[6] = "https://data.broadinstitute.org/Trinity/CTAT_RESOURCE_LIB/AnnotFilterRule.pm" + """ + } + } + + run("FUSIONREPORT_DOWNLOAD") { + script "../../../../modules/nf-core/fusionreport/download/main.nf" + process { + """ + """ + } + } + + run("FUSIONREPORT_DETECT") { + script "../../../../modules/nf-core/fusionreport/detect/main.nf" + process { + """ + input[0] = Channel.of([ + [ id:'test_sample' ], // meta map + file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/arriba.tsv', checkIfExists: true), + file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/starfusion.tsv', checkIfExists: true), + file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/fusioncatcher.txt', checkIfExists: true) + ]) + input[1] = FUSIONREPORT_DOWNLOAD.out.fusionreport_ref + input[2] = 1 + """ + } + } + } + + when { + params { + no_cosmic = true + whitelist = "" + outdir = "test" + genomes_base = "test" + fusionreport_download_args = '--no-cosmic' + fusionreport_detect_args = "--no-cosmic" + fusionreport_detect_args2 = "--export csv" + } + workflow { + """ + input[0] = Channel.of( + [ [ id:'test_sample' ], + [ + file("https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/v0.0.1/rnaseq_1.fastq.gz"), + file("https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/v0.0.1/rnaseq_2.fastq.gz") + ] + ]) + input[1] = Channel.of([ [id:'test_sample'], file("https://github.com/FusionInspector/FusionInspector/raw/master/test/fusion_targets.A.txt")]) + input[2] = Channel.of([ [id:'test_sample'], file("https://github.com/FusionInspector/FusionInspector/raw/master/test/fusion_targets.A.txt")]) + input[3] = FUSIONREPORT_DETECT.out.report + input[4] = FUSIONREPORT_DETECT.out.csv + input[5] = Channel.of([[ id:'test', single_end:false ], // meta map + file("https://github.com/nf-core/test-datasets/raw/modules/data/genomics/homo_sapiens/illumina/bam/test.paired_end.markduplicates.sorted.bam", checkIfExists: true), + file("https://github.com/nf-core/test-datasets/raw/modules/data/genomics/homo_sapiens/illumina/bam/test.paired_end.markduplicates.sorted.bam.bai", checkIfExists: true) + ]) + input[6] = Channel.of( + [ [ id:'test_gtf' ], + file('https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/minigenome.gtf')]) + input[7] = Channel.fromPath("https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3") + input[8] = Channel.fromPath("https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv") + input[9] = Channel.of([[ id:'hgnc' ], file("https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/hgnc/hgnc_complete_set.txt")] ) + input[10] = Channel.of([[ id:'hgnc_timestamp' ], file("https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/hgnc/HGNC-DB-timestamp.txt")] ) + input[11] = STARFUSION_BUILD.out.reference + input[12] = false + input[13] = true + input[14] = 1 + input[15] = null + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } +} diff --git a/subworkflows/local/fusioninspector_workflow/tests/main.nf.test.snap b/subworkflows/local/fusioninspector_workflow/tests/main.nf.test.snap new file mode 100644 index 000000000..f156b0d2e --- /dev/null +++ b/subworkflows/local/fusioninspector_workflow/tests/main.nf.test.snap @@ -0,0 +1,37 @@ +{ + "FUSIONINSPECTOR_WORKFLOW - human - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + "versions.yml:md5,3be8e23309ed0bacebcad3d2fb30642a" + ], + "ch_arriba_visualisation": [ + + ], + "versions": [ + "versions.yml:md5,3be8e23309ed0bacebcad3d2fb30642a" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-09-08T17:38:59.895142" + }, + "FUSIONINSPECTOR_WORKFLOW - human": { + "content": [ + [ + "versions.yml:md5,3be8e23309ed0bacebcad3d2fb30642a" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-09-08T17:14:05.797063" + } +} \ No newline at end of file diff --git a/subworkflows/local/fusioninspector_workflow/tests/nextflow.config b/subworkflows/local/fusioninspector_workflow/tests/nextflow.config new file mode 100644 index 000000000..5dad203b1 --- /dev/null +++ b/subworkflows/local/fusioninspector_workflow/tests/nextflow.config @@ -0,0 +1,10 @@ +process { + withName: 'STARFUSION_BUILD' { + ext.args = [] + } + + + withName: 'FUSIONINSPECTOR' { + ext.args = '--annotate --examine_coding_effect' + } +} diff --git a/subworkflows/local/fusionreport_workflow.nf b/subworkflows/local/fusionreport_workflow.nf deleted file mode 100644 index 09ec99657..000000000 --- a/subworkflows/local/fusionreport_workflow.nf +++ /dev/null @@ -1,44 +0,0 @@ -include { FUSIONREPORT } from '../../modules/local/fusionreport/detect/main' - - -workflow FUSIONREPORT_WORKFLOW { - take: - reads - fusionreport_ref - arriba_fusions - starfusion_fusions - fusioncatcher_fusions - - main: - ch_versions = Channel.empty() - ch_report = Channel.empty() - ch_csv = Channel.empty() - - if (!params.fusioninspector_only) { - reads_fusions = reads - .join(arriba_fusions, remainder: true) - .join(starfusion_fusions, remainder: true) - .join(fusioncatcher_fusions, remainder: true) - - FUSIONREPORT(reads_fusions, fusionreport_ref, params.tools_cutoff) - ch_fusion_list = FUSIONREPORT.out.fusion_list - ch_fusion_list_filtered = FUSIONREPORT.out.fusion_list_filtered - ch_versions = ch_versions.mix(FUSIONREPORT.out.versions) - ch_report = FUSIONREPORT.out.report - ch_csv = FUSIONREPORT.out.csv - } else { - ch_fusion_list = reads.combine(Channel.value(file(params.fusioninspector_fusions, checkIfExists:true))) - .map { meta, reads, fusions -> [ meta, fusions ] } - - ch_fusion_list_filtered = ch_fusion_list - } - - emit: - versions = ch_versions - fusion_list = ch_fusion_list - fusion_list_filtered = ch_fusion_list_filtered - report = ch_report.ifEmpty(null) - csv = ch_csv.ifEmpty(null) - -} - diff --git a/subworkflows/local/qc_workflow.nf b/subworkflows/local/qc_workflow.nf deleted file mode 100644 index 6b53358ad..000000000 --- a/subworkflows/local/qc_workflow.nf +++ /dev/null @@ -1,42 +0,0 @@ -// -// Check input samplesheet and get read channels -// - -include { PICARD_COLLECTRNASEQMETRICS } from '../../modules/local/picard/collectrnaseqmetrics/main' -include { GATK4_MARKDUPLICATES } from '../../modules/nf-core/gatk4/markduplicates/main' -include { PICARD_COLLECTINSERTSIZEMETRICS } from '../../modules/nf-core/picard/collectinsertsizemetrics/main' - -workflow QC_WORKFLOW { - take: - ch_bam_sorted - ch_bam_sorted_indexed - ch_chrgtf - ch_refflat - ch_fasta - ch_fai - ch_rrna_interval - - main: - ch_versions = Channel.empty() - - PICARD_COLLECTRNASEQMETRICS(ch_bam_sorted_indexed, ch_refflat, ch_rrna_interval) - ch_versions = ch_versions.mix(PICARD_COLLECTRNASEQMETRICS.out.versions) - ch_rnaseq_metrics = Channel.empty().mix(PICARD_COLLECTRNASEQMETRICS.out.metrics) - - GATK4_MARKDUPLICATES(ch_bam_sorted, ch_fasta.map { meta, fasta -> [ fasta ]}, ch_fai.map { meta, fasta_fai -> [ fasta_fai ]}) - ch_versions = ch_versions.mix(GATK4_MARKDUPLICATES.out.versions) - ch_duplicate_metrics = Channel.empty().mix(GATK4_MARKDUPLICATES.out.metrics) - - PICARD_COLLECTINSERTSIZEMETRICS(ch_bam_sorted) - ch_versions = ch_versions.mix(PICARD_COLLECTINSERTSIZEMETRICS.out.versions) - ch_insertsize_metrics = Channel.empty().mix(PICARD_COLLECTINSERTSIZEMETRICS.out.metrics) - - - emit: - versions = ch_versions - rnaseq_metrics = ch_rnaseq_metrics - duplicate_metrics = ch_duplicate_metrics - insertsize_metrics = ch_insertsize_metrics - -} - diff --git a/subworkflows/local/qc_workflow/main.nf b/subworkflows/local/qc_workflow/main.nf new file mode 100644 index 000000000..d83fea35c --- /dev/null +++ b/subworkflows/local/qc_workflow/main.nf @@ -0,0 +1,49 @@ +// +// Extract descriptive values from BAMs +// + +include { PICARD_COLLECTRNASEQMETRICS } from '../../../modules/nf-core/picard/collectrnaseqmetrics' +include { GATK4_MARKDUPLICATES } from '../../../modules/nf-core/gatk4/markduplicates' +include { PICARD_COLLECTINSERTSIZEMETRICS } from '../../../modules/nf-core/picard/collectinsertsizemetrics' + +workflow QC_WORKFLOW { + take: + ch_bam_sorted // channel [ meta, bam ] + ch_refflat // channel [ meta, refflat ] + ch_fasta // channel [ meta, fasta ] + ch_fai // channel [ meta, fai ] + ch_rrna_interval // channel [ meta, interval ] + + main: + ch_versions = Channel.empty() + + PICARD_COLLECTRNASEQMETRICS( + ch_bam_sorted, + ch_refflat.map{ _meta, refflat -> refflat }, + ch_fasta.map{ _meta, fasta -> fasta }, + ch_rrna_interval.map{ _meta, intervals -> intervals } + ) // Some chromosome or annotation may not have rRNA genes + ch_versions = ch_versions.mix(PICARD_COLLECTRNASEQMETRICS.out.versions) + ch_rnaseq_metrics = PICARD_COLLECTRNASEQMETRICS.out.metrics + + GATK4_MARKDUPLICATES( + ch_bam_sorted, + ch_fasta.map { _meta, fasta -> [ fasta ]}, + ch_fai.map { _meta, fasta_fai -> [ fasta_fai ]} + ) + ch_versions = ch_versions.mix(GATK4_MARKDUPLICATES.out.versions) + ch_duplicate_metrics = GATK4_MARKDUPLICATES.out.metrics + + PICARD_COLLECTINSERTSIZEMETRICS( + ch_bam_sorted + ) + ch_versions = ch_versions.mix(PICARD_COLLECTINSERTSIZEMETRICS.out.versions) + ch_insertsize_metrics = PICARD_COLLECTINSERTSIZEMETRICS.out.metrics + + emit: + versions = ch_versions // channel [ path ] + rnaseq_metrics = ch_rnaseq_metrics // channel [ meta, path ] + duplicate_metrics = ch_duplicate_metrics // channel [ meta, path ] + insertsize_metrics = ch_insertsize_metrics // channel [ meta, path ] + +} diff --git a/subworkflows/local/qc_workflow/test/main.nf.test b/subworkflows/local/qc_workflow/test/main.nf.test new file mode 100644 index 000000000..06a6a4c62 --- /dev/null +++ b/subworkflows/local/qc_workflow/test/main.nf.test @@ -0,0 +1,128 @@ +nextflow_workflow { + + name "Test Subworkflow QC_WORKFLOW" + script "../main.nf" + config "./nextflow.config" + workflow "QC_WORKFLOW" + tag "qc" + tag "subworkflow" + + test("QC_WORKFLOW - Homo sapiens chr22") { + + // Generate refflat file + setup { + + // Create refflat reference + run("UCSC_GTFTOGENEPRED") { + script "../../../../modules/nf-core/ucsc/gtftogenepred/main.nf" + process { + """ + input[0] =Channel.of( + [ + [id: 'gtf'], + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/genome.gtf", checkIfExists: true) + ] + ) + """ + } + } + + // Filter GTF to extract rRNA genes + run("BIOAWK") { + script "../../../../modules/nf-core/bioawk/main.nf" + process { + """ + input[0] = Channel.of( + [ + [id: 'gtf'], + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/genome.gtf", checkIfExists: true) + ] + ) + """ + } + } + + run("AGAT_CONVERTGFF2BED") { + script "../../../../modules/nf-core/agat/convertgff2bed/main.nf" + process { + """ + input[0] = BIOAWK.out.output + """ + } + } + + + // Convert rRNA BED to interval list (the necessary file) + run("GATK4_BEDTOINTERVALLIST") { + script "../../../../modules/nf-core/gatk4/bedtointervallist/main.nf" + process { + """ + input[0] = AGAT_CONVERTGFF2BED.out.bed + input[1] = Channel.of( + [ + [id: 'chr22_dict'], + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/genome.dict", checkIfExist: true) + ] + ) + """ + } + } + + } + + when { + params { + skip_qc = false + fusioninspector_only = false + tools = "all" + outdir = "test" + + } + + workflow { + """ + // ch_bam_sorted + input[0] = Channel.of( + [ + [id: "chr22_bam"], + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam", checkIfExists: true) + ]) + + // ch_refflat + input[1] = UCSC_GTFTOGENEPRED.out.refflat + // ch_fasta + input[2] = Channel.of( + [ + [ id: "test_ref" ], + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/genome.fasta", checkIfExists: true) + ] + ) + + // ch_fai + input[3] = Channel.of( + [ + [ id: "test_ref" ], + file("https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/modules/data/genomics/homo_sapiens/genome/genome.fasta.fai", checkIfExists: true) + ] ) + + // ch rRNA interval list + input[4] = GATK4_BEDTOINTERVALLIST.out.interval_list + """ + + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + file(workflow.out.rnaseq_metrics[0][1]).readLines()[5..8], + file(workflow.out.duplicate_metrics[0][1]).readLines()[5..8], + file(workflow.out.insertsize_metrics[0][1]).readLines()[5..8], + workflow.out.versions + ).match() } + ) + } + } + +} diff --git a/subworkflows/local/qc_workflow/test/main.nf.test.snap b/subworkflows/local/qc_workflow/test/main.nf.test.snap new file mode 100644 index 000000000..80a937268 --- /dev/null +++ b/subworkflows/local/qc_workflow/test/main.nf.test.snap @@ -0,0 +1,34 @@ +{ + "QC_WORKFLOW - Homo sapiens chr22": { + "content": [ + [ + "## METRICS CLASS\tpicard.analysis.RnaSeqMetrics", + "PF_BASES\tPF_ALIGNED_BASES\tRIBOSOMAL_BASES\tCODING_BASES\tUTR_BASES\tINTRONIC_BASES\tINTERGENIC_BASES\tIGNORED_READS\tCORRECT_STRAND_READS\tINCORRECT_STRAND_READS\tNUM_R1_TRANSCRIPT_STRAND_READS\tNUM_R2_TRANSCRIPT_STRAND_READS\tNUM_UNEXPLAINED_READS\tPCT_R1_TRANSCRIPT_STRAND_READS\tPCT_R2_TRANSCRIPT_STRAND_READS\tPCT_RIBOSOMAL_BASES\tPCT_CODING_BASES\tPCT_UTR_BASES\tPCT_INTRONIC_BASES\tPCT_INTERGENIC_BASES\tPCT_MRNA_BASES\tPCT_USABLE_BASES\tPCT_CORRECT_STRAND_READS\tMEDIAN_CV_COVERAGE\tMEDIAN_5PRIME_BIAS\tMEDIAN_3PRIME_BIAS\tMEDIAN_5PRIME_TO_3PRIME_BIAS\tSAMPLE\tLIBRARY\tREAD_GROUP", + "672131\t670989\t0\t0\t323630\t84236\t263123\t0\t1324\t1328\t664\t661\t1\t0.501132\t0.498868\t0\t0\t0.482318\t0.12554\t0.392142\t0.482318\t0.481498\t0.499246\t4.318717\t0\t0.529614\t0\t\t\t", + "" + ], + [ + "## METRICS CLASS\tpicard.sam.DuplicationMetrics", + "LIBRARY\tUNPAIRED_READS_EXAMINED\tREAD_PAIRS_EXAMINED\tSECONDARY_OR_SUPPLEMENTARY_RDS\tUNMAPPED_READS\tUNPAIRED_READ_DUPLICATES\tREAD_PAIR_DUPLICATES\tREAD_PAIR_OPTICAL_DUPLICATES\tPERCENT_DUPLICATION\tESTIMATED_LIBRARY_SIZE", + "testN\t0\t2820\t2\t2\t0\t828\t0\t0.293617\t3807", + "" + ], + [ + "## METRICS CLASS\tpicard.analysis.InsertSizeMetrics", + "MEDIAN_INSERT_SIZE\tMODE_INSERT_SIZE\tMEDIAN_ABSOLUTE_DEVIATION\tMIN_INSERT_SIZE\tMAX_INSERT_SIZE\tMEAN_INSERT_SIZE\tSTANDARD_DEVIATION\tREAD_PAIRS\tPAIR_ORIENTATION\tWIDTH_OF_10_PERCENT\tWIDTH_OF_20_PERCENT\tWIDTH_OF_30_PERCENT\tWIDTH_OF_40_PERCENT\tWIDTH_OF_50_PERCENT\tWIDTH_OF_60_PERCENT\tWIDTH_OF_70_PERCENT\tWIDTH_OF_80_PERCENT\tWIDTH_OF_90_PERCENT\tWIDTH_OF_95_PERCENT\tWIDTH_OF_99_PERCENT\tSAMPLE\tLIBRARY\tREAD_GROUP", + "123\t96\t23\t32\t300\t125.684397\t32.447863\t2820\tFR\t11\t17\t27\t37\t47\t57\t69\t83\t103\t125\t169\t\t\t", + "" + ], + [ + "versions.yml:md5,43d6a3cb756a214f3956bd5c740cb26a", + "versions.yml:md5,5c0ffe79bb7206c2652cf7f477f9b53f", + "versions.yml:md5,9951386776792bef3fd644ef9da67e7a" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-28T17:08:08.334459479" + } +} diff --git a/subworkflows/local/qc_workflow/test/nextflow.config b/subworkflows/local/qc_workflow/test/nextflow.config new file mode 100644 index 000000000..498c456f0 --- /dev/null +++ b/subworkflows/local/qc_workflow/test/nextflow.config @@ -0,0 +1,10 @@ +process { + withName: PICARD_COLLECTRNASEQMETRICS { + ext.args = "--STRAND_SPECIFICITY SECOND_READ_TRANSCRIPTION_STRAND" + } + + withName: GATK4_BEDTOINTERVALLIST { + ext.args = "--KEEP_LENGTH_ZERO_INTERVALS true" + } + +} diff --git a/subworkflows/local/starfusion_workflow.nf b/subworkflows/local/starfusion_workflow.nf deleted file mode 100644 index de99d8e51..000000000 --- a/subworkflows/local/starfusion_workflow.nf +++ /dev/null @@ -1,67 +0,0 @@ -include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_STARFUSION } from '../../modules/nf-core/samtools/index/main' -include { SAMTOOLS_INDEX as SAMTOOLS_INDEX_FOR_STARFUSION_CRAM } from '../../modules/nf-core/samtools/index/main' -include { SAMTOOLS_VIEW as SAMTOOLS_VIEW_FOR_STARFUSION } from '../../modules/nf-core/samtools/view/main' -include { STAR_ALIGN as STAR_FOR_STARFUSION } from '../../modules/nf-core/star/align/main' -include { STARFUSION } from '../../modules/local/starfusion/detect/main' - -workflow STARFUSION_WORKFLOW { - take: - reads - ch_chrgtf - ch_starindex_ref - ch_fasta - - main: - ch_versions = Channel.empty() - ch_align = Channel.empty() - bam_sorted_indexed = Channel.empty() - - ch_dummy_file = file("$baseDir/assets/dummy_file_starfusion.txt", checkIfExists: true) - - if ((params.starfusion || params.all || params.stringtie) && !params.fusioninspector_only) { - if (params.starfusion_fusions){ - ch_starfusion_fusions = reads.combine(Channel.value(file(params.starfusion_fusions, checkIfExists:true))) - .map { meta, reads, fusions -> [ meta, fusions ] } - } else { - STAR_FOR_STARFUSION( reads, ch_starindex_ref, ch_chrgtf, params.star_ignore_sjdbgtf, '', params.seq_center ?: '') - ch_versions = ch_versions.mix(STAR_FOR_STARFUSION.out.versions) - ch_align = STAR_FOR_STARFUSION.out.bam_sorted - - SAMTOOLS_INDEX_FOR_STARFUSION(STAR_FOR_STARFUSION.out.bam_sorted) - ch_versions = ch_versions.mix(SAMTOOLS_INDEX_FOR_STARFUSION.out.versions) - bam_sorted_indexed = STAR_FOR_STARFUSION.out.bam_sorted.join(SAMTOOLS_INDEX_FOR_STARFUSION.out.bai) - reads_junction = reads.join(STAR_FOR_STARFUSION.out.junction ) - - if (params.cram.contains('starfusion')){ - SAMTOOLS_VIEW_FOR_STARFUSION (bam_sorted_indexed, ch_fasta, [] ) - ch_versions = ch_versions.mix(SAMTOOLS_VIEW_FOR_STARFUSION.out.versions) - - SAMTOOLS_INDEX_FOR_STARFUSION_CRAM (SAMTOOLS_VIEW_FOR_STARFUSION.out.cram) - ch_versions = ch_versions.mix(SAMTOOLS_INDEX_FOR_STARFUSION_CRAM.out.versions) - } - if (params.starfusion || params.all){ - STARFUSION( reads_junction, params.starfusion_ref) - ch_versions = ch_versions.mix(STARFUSION.out.versions) - ch_starfusion_fusions = STARFUSION.out.fusions - } - - ch_star_stats = STAR_FOR_STARFUSION.out.log_final - ch_star_gene_count = STAR_FOR_STARFUSION.out.read_per_gene_tab - } - } - else { - ch_starfusion_fusions = reads.combine(Channel.value(file(ch_dummy_file, checkIfExists:true))) - .map { meta, reads, fusions -> [ meta, fusions ] } - ch_star_stats = Channel.empty() - ch_star_gene_count = Channel.empty() - } - emit: - fusions = ch_starfusion_fusions - star_stats = ch_star_stats - star_gene_count = ch_star_gene_count - ch_bam_sorted = ch_align.ifEmpty([[],[]]) - ch_bam_sorted_indexed = bam_sorted_indexed.ifEmpty([[],[],[]]) - versions = ch_versions - - } - diff --git a/subworkflows/local/stringtie_workflow.nf b/subworkflows/local/stringtie_workflow.nf deleted file mode 100644 index 60bd4f38b..000000000 --- a/subworkflows/local/stringtie_workflow.nf +++ /dev/null @@ -1,36 +0,0 @@ -include { STRINGTIE_STRINGTIE } from '../../modules/nf-core/stringtie/stringtie/main' -include { STRINGTIE_MERGE } from '../../modules/nf-core/stringtie/merge/main' - - -workflow STRINGTIE_WORKFLOW { - take: - bam_sorted - ch_chrgtf - - main: - ch_versions = Channel.empty() - ch_stringtie_gtf = Channel.empty() - - if ((params.stringtie || params.all) && !params.fusioninspector_only) { - STRINGTIE_STRINGTIE(bam_sorted, ch_chrgtf.map { meta, gtf -> [ gtf ]}) - ch_versions = ch_versions.mix(STRINGTIE_STRINGTIE.out.versions) - - STRINGTIE_STRINGTIE - .out - .transcript_gtf - .map { it -> it[1] } - .set { stringtie_gtf } - ch_versions = ch_versions.mix(STRINGTIE_STRINGTIE.out.versions) - - - STRINGTIE_MERGE (stringtie_gtf, ch_chrgtf.map { meta, gtf -> [ gtf ]}) - ch_versions = ch_versions.mix(STRINGTIE_MERGE.out.versions) - ch_stringtie_gtf = STRINGTIE_MERGE.out.gtf - } - - emit: - stringtie_gtf = ch_stringtie_gtf.ifEmpty(null) - versions = ch_versions - - } - diff --git a/subworkflows/local/trim_workflow.nf b/subworkflows/local/trim_workflow.nf deleted file mode 100644 index ea21134db..000000000 --- a/subworkflows/local/trim_workflow.nf +++ /dev/null @@ -1,42 +0,0 @@ -include { FASTP } from '../../modules/nf-core/fastp/main' -include { FASTQC as FASTQC_FOR_FASTP } from '../../modules/nf-core/fastqc/main' - - -workflow TRIM_WORKFLOW { - take: - reads - - main: - ch_versions = Channel.empty() - ch_fastp_html = Channel.empty() - ch_fastp_json = Channel.empty() - ch_fastqc_trimmed = Channel.empty() - - if (params.fastp_trim) { - FASTP(reads, params.adapter_fasta, false, false) - ch_versions = ch_versions.mix(FASTP.out.versions) - - FASTQC_FOR_FASTP(FASTP.out.reads) - ch_versions = ch_versions.mix(FASTQC_FOR_FASTP.out.versions) - - ch_reads_all = FASTP.out.reads - ch_reads_fusioncatcher = ch_reads_all - ch_fastp_html = FASTP.out.html - ch_fastp_json = FASTP.out.json - ch_fastqc_trimmed = FASTQC_FOR_FASTP.out.zip - - } - else { - ch_reads_all = reads - ch_reads_fusioncatcher = reads - } - - emit: - ch_reads_all - ch_reads_fusioncatcher - ch_fastp_html - ch_fastp_json - ch_fastqc_trimmed - versions = ch_versions - } - diff --git a/subworkflows/local/utils_nfcore_rnafusion_pipeline/main.nf b/subworkflows/local/utils_nfcore_rnafusion_pipeline/main.nf index 3a02b058b..89219ce3d 100644 --- a/subworkflows/local/utils_nfcore_rnafusion_pipeline/main.nf +++ b/subworkflows/local/utils_nfcore_rnafusion_pipeline/main.nf @@ -2,42 +2,34 @@ // Subworkflow with functionality specific to the nf-core/rnafusion pipeline // -import groovy.json.JsonSlurper - /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -include { UTILS_NFVALIDATION_PLUGIN } from '../../nf-core/utils_nfvalidation_plugin' -include { paramsSummaryMap } from 'plugin/nf-validation' -include { fromSamplesheet } from 'plugin/nf-validation' -include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' +include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' include { completionEmail } from '../../nf-core/utils_nfcore_pipeline' include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' -include { dashedLine } from '../../nf-core/utils_nfcore_pipeline' -include { nfCoreLogo } from '../../nf-core/utils_nfcore_pipeline' include { imNotification } from '../../nf-core/utils_nfcore_pipeline' include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' -include { workflowCitation } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SUBWORKFLOW TO INITIALISE PIPELINE -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ workflow PIPELINE_INITIALISATION { take: version // boolean: Display version and exit - help // boolean: Display help text validate_params // boolean: Boolean whether to validate parameters against the schema at runtime - monochrome_logs // boolean: Do not use coloured log outputs nextflow_cli_args // array: List of positional nextflow CLI args outdir // string: The output directory where the results will be saved - input // string: Path to input samplesheet main: @@ -56,17 +48,10 @@ workflow PIPELINE_INITIALISATION { // // Validate parameters and generate parameter summary to stdout // - pre_help_text = nfCoreLogo(monochrome_logs) - post_help_text = '\n' + workflowCitation() + '\n' + dashedLine(monochrome_logs) - def String workflow_command = "nextflow run ${workflow.manifest.name} -profile --input samplesheet.csv --genome_base } --outdir " - - UTILS_NFVALIDATION_PLUGIN ( - help, - workflow_command, - pre_help_text, - post_help_text, + UTILS_NFSCHEMA_PLUGIN ( + workflow, validate_params, - "nextflow_schema.json" + null ) // @@ -81,12 +66,42 @@ workflow PIPELINE_INITIALISATION { // validateInputParameters() + // + // Create channel from input file provided through params.input + // + + Channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { meta, fastq_1, fastq_2, bam, bai, cram, crai, junctions, splice_junctions, strandedness -> + def meta_fastqs = [] + if (!fastq_1) { + meta_fastqs = [ meta, [] ] + } else if (!fastq_2) { + meta_fastqs = [ meta + [single_end:true], [ fastq_1 ] ] + } else { + meta_fastqs = [ meta + [single_end:false], [ fastq_1, fastq_2 ] ] + } + return [ meta.id ] + meta_fastqs + [ bam, bai, cram, crai, junctions, splice_junctions, strandedness ] + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs, bam, bai, cram, crai, junctions, splice_junctions -> + return [ meta, fastqs.flatten(), bam, bai, cram, crai, junctions, splice_junctions ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions } /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SUBWORKFLOW FOR PIPELINE COMPLETION -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ workflow PIPELINE_COMPLETION { @@ -98,31 +113,43 @@ workflow PIPELINE_COMPLETION { outdir // path: Path to output directory where results will be published monochrome_logs // boolean: Disable ANSI colour codes in log output hook_url // string: hook URL for notifications + multiqc_report // string: Path to MultiQC report main: - summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") + 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, null) + 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 -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ // @@ -130,13 +157,72 @@ workflow PIPELINE_COMPLETION { // def validateInputParameters() { genomeExistsError() + + if (params.no_cosmic) { + log.warn("Skipping COSMIC DB download from `FUSIONREPORT_DOWNLOAD` and skip using it in `FUSIONREPORT`") + } + + def dfamParams = ['dfam_hmm', 'dfam_h3p', 'dfam_h3m', 'dfam_h3i', 'dfam_h3f'] + + if (params.dfam_version) { + def dfamPattern = "https://www.dfam.org/releases/Dfam_${params.dfam_version}/infrastructure/dfamscan/${params.species}_dfam" + + def setDfamParams = dfamParams.findAll { params[it] } + + if (setDfamParams) { + def customParams = setDfamParams.findAll { paramName -> + !params[paramName]?.startsWith(dfamPattern) + } + if (customParams) { + def paramDetails = customParams.collect { paramName -> + " --${paramName}: ${params[paramName]}" + }.join('\n') + def dfam_warn = "Both custom DFAM paths as well as `--dfam_version` (${params.dfam_version}) and `--species` (${params.species}) were provided.\n" + + "Custom DFAM paths parameters provided:\n${paramDetails}\n" + + "The pipeline will prioritize these custom files specified with `--${customParams}` and **will NOT** construct these URLs based on `--dfam_version` nor `--species`.\n" + + " - If you intend to use custom DFAM files, please ensure that all `--dfam_h*` parameters point to full and valid paths.\n" + + " - If you prefer to let the pipeline build the DFAM URLs automatically, omit `--dfam_h*` and instead provide only `--dfam_version` and `--species`." + log.warn(dfam_warn) + } + } + } + + if (params.pfam_version){ + def pfamPattern = "http://ftp.ebi.ac.uk/pub/databases/Pfam/releases/Pfam${params.pfam_version}/Pfam-A" + + if (!(params.pfam_file?.startsWith(pfamPattern))) { + def pfam_warn = "Both `--pfam_file` (${params.pfam_file}) and `--pfam_version` (${params.pfam_version}) were provided.\n" + + "The pipeline will prioritize the custom file from `--pfam_file` and **will NOT** construct the URL based on `--pfam_version`.\n" + + " - If you intend to use a custom PFAM file, please ensure that `--pfam_file` points to a full and valid path.\n" + + " - If you prefer to let the pipeline build the PFAM URL automatically, omit `--pfam_file` and instead provide only `--pfam_version`." + log.warn(pfam_warn) + } + } } // // Validate channels from input samplesheet // def validateInputSamplesheet(input) { - def (metas, fastqs) = input[1..2] + def (metas, fastqs, bam, bai, cram, crai, junctions, splice_junctions) = input[1..8] + + def bam_list = bam.findAll { it -> it != [] } + def cram_list = cram.findAll { it -> it != [] } + def junctions_list = junctions.findAll { it -> it != [] } + def splice_junctions_list = splice_junctions.findAll { it -> it != [] } + // Check alignment and junction files (input is a list) + if (bam_list.size() > 1 || cram_list.size() > 1 || junctions_list.size() > 1 || splice_junctions_list.size() > 1) { + error("Please check input samplesheet -> Only one BAM or CRAM, junctions and split junctions file is allowed per sample: ${metas[0].id}") + } + + bam = bam_list.size() > 0 ? bam_list[0] : [] + cram = cram_list.size() > 0 ? cram_list[0] : [] + junctions = junctions_list.size() > 0 ? junctions_list[0] : [] + splice_junctions = splice_junctions_list.size() > 0 ? splice_junctions_list[0] : [] + + if (bam != [] && cram != []) { + error("Please check input samplesheet -> Using both BAM and CRAM files isn't allowed: ${metas[0].id}") + } // Check that multiple runs of the same sample are of the same strandedness def strandedness_ok = metas.collect{ it.strandedness }.unique().size == 1 @@ -145,12 +231,12 @@ def validateInputSamplesheet(input) { } // Check that multiple runs of the same sample are of the same datatype i.e. single-end / paired-end - def endedness_ok = metas.collect{ it.single_end }.unique().size == 1 - if (!endedness_ok) { + def endedness_ok = metas.collect{ meta -> meta.single_end }.unique().size == 1 + if (!endedness_ok && fastqs) { 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, bam, bai.find { it -> it != [] } ?: [], cram, crai.find { it -> it != [] } ?: [], junctions, splice_junctions ] } // @@ -178,12 +264,10 @@ def genomeExistsError() { error(error_string) } } - // // Generate methods description for MultiQC // def toolCitationText() { - // TODO nf-core: Optionally add in-text citation tools to this list. // 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 = [ @@ -197,7 +281,6 @@ def toolCitationText() { } def toolBibliographyText() { - // TODO nf-core: Optionally add bibliographic entries to this list. // 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 = [ @@ -209,20 +292,30 @@ def toolBibliographyText() { } def methodsDescriptionText(mqc_methods_yaml) { - // Convert to a named map so can be used as with familar NXF ${workflow} variable syntax in the MultiQC YML file + // Convert to a named map so can be used as with familiar NXF ${workflow} variable syntax in the MultiQC YML file def meta = [:] meta.workflow = workflow.toMap() meta["manifest_map"] = workflow.manifest.toMap() // Pipeline DOI - meta["doi_text"] = meta.manifest_map.doi ? "(doi: ${meta.manifest_map.doi})" : "" - meta["nodoi_text"] = meta.manifest_map.doi ? "": "
  • If available, make sure to update the text to include the Zenodo DOI of version of the pipeline used.
  • " + if (meta.manifest_map.doi) { + // Using a loop to handle multiple DOIs + // Removing `https://doi.org/` to handle pipelines using DOIs vs DOI resolvers + // Removing ` ` since the manifest.doi is a string and not a proper list + def temp_doi_ref = "" + def manifest_doi = meta.manifest_map.doi.tokenize(",") + manifest_doi.each { doi_ref -> + temp_doi_ref += "(doi: ${doi_ref.replace("https://doi.org/", "").replace(" ", "")}), " + } + meta["doi_text"] = temp_doi_ref.substring(0, temp_doi_ref.length() - 2) + } else meta["doi_text"] = "" + meta["nodoi_text"] = meta.manifest_map.doi ? "" : "
  • If available, make sure to update the text to include the Zenodo DOI of version of the pipeline used.
  • " // Tool references meta["tool_citations"] = "" meta["tool_bibliography"] = "" - // TODO nf-core: Only uncomment below if logic in toolCitationText/toolBibliographyText has been filled! + // nf-core: Only uncomment below if logic in toolCitationText/toolBibliographyText has been filled! // meta["tool_citations"] = toolCitationText().replaceAll(", \\.", ".").replaceAll("\\. \\.", ".").replaceAll(", \\.", ".") // meta["tool_bibliography"] = toolBibliographyText() @@ -233,26 +326,3 @@ def methodsDescriptionText(mqc_methods_yaml) { return description_html.toString() } - -// -// Function to generate an error if contigs in genome fasta file > 512 Mbp -// -def checkMaxContigSize(fai_file) { - def max_size = 512000000 - fai_file.eachLine { line -> - def lspl = line.split('\t') - def chrom = lspl[0] - def size = lspl[1] - if (size.toInteger() > max_size) { - def error_string = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + - " Contig longer than ${max_size}bp found in reference genome!\n\n" + - " ${chrom}: ${size}\n\n" + - " Provide the '--bam_csi_index' parameter to use a CSI instead of BAI index.\n\n" + - " Please see:\n" + - " https://github.com/nf-core/rnaseq/issues/744\n" + - "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" - error(error_string) - } - } -} - diff --git a/subworkflows/nf-core/bam_sort_stats_samtools/main.nf b/subworkflows/nf-core/bam_sort_stats_samtools/main.nf new file mode 100644 index 000000000..460726368 --- /dev/null +++ b/subworkflows/nf-core/bam_sort_stats_samtools/main.nf @@ -0,0 +1,50 @@ +// +// Sort, index BAM file and run samtools stats, flagstat and idxstats +// + +include { SAMTOOLS_SORT } from '../../../modules/nf-core/samtools/sort/main' +include { SAMTOOLS_INDEX } from '../../../modules/nf-core/samtools/index/main' +include { BAM_STATS_SAMTOOLS } from '../bam_stats_samtools/main' + +workflow BAM_SORT_STATS_SAMTOOLS { + take: + ch_bam // channel: [ val(meta), [ bam ] ] + ch_fasta // channel: [ val(meta), path(fasta) ] + + main: + + ch_versions = Channel.empty() + + SAMTOOLS_SORT ( ch_bam, ch_fasta, '' ) + ch_versions = ch_versions.mix(SAMTOOLS_SORT.out.versions.first()) + + SAMTOOLS_INDEX ( SAMTOOLS_SORT.out.bam ) + ch_versions = ch_versions.mix(SAMTOOLS_INDEX.out.versions.first()) + + SAMTOOLS_SORT.out.bam + .join(SAMTOOLS_INDEX.out.bai, by: [0], remainder: true) + .join(SAMTOOLS_INDEX.out.csi, by: [0], remainder: true) + .map { + meta, bam, bai, csi -> + if (bai) { + [ meta, bam, bai ] + } else { + [ meta, bam, csi ] + } + } + .set { ch_bam_bai } + + BAM_STATS_SAMTOOLS ( ch_bam_bai, ch_fasta ) + ch_versions = ch_versions.mix(BAM_STATS_SAMTOOLS.out.versions) + + emit: + bam = SAMTOOLS_SORT.out.bam // channel: [ val(meta), [ bam ] ] + bai = SAMTOOLS_INDEX.out.bai // channel: [ val(meta), [ bai ] ] + csi = SAMTOOLS_INDEX.out.csi // channel: [ val(meta), [ csi ] ] + + stats = BAM_STATS_SAMTOOLS.out.stats // channel: [ val(meta), [ stats ] ] + flagstat = BAM_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), [ flagstat ] ] + idxstats = BAM_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), [ idxstats ] ] + + versions = ch_versions // channel: [ versions.yml ] +} diff --git a/subworkflows/nf-core/bam_sort_stats_samtools/meta.yml b/subworkflows/nf-core/bam_sort_stats_samtools/meta.yml new file mode 100644 index 000000000..e01f9ccf6 --- /dev/null +++ b/subworkflows/nf-core/bam_sort_stats_samtools/meta.yml @@ -0,0 +1,70 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: bam_sort_stats_samtools +description: Sort SAM/BAM/CRAM file +keywords: + - sort + - bam + - sam + - cram +components: + - samtools/sort + - samtools/index + - samtools/stats + - samtools/idxstats + - samtools/flagstat + - bam_stats_samtools +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: BAM/CRAM/SAM file + pattern: "*.{bam,cram,sam}" + - fasta: + type: file + description: Reference genome fasta file + pattern: "*.{fasta,fa}" +# TODO Update when we decide on a standard for subworkflow docs +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: Sorted BAM/CRAM/SAM file + pattern: "*.{bam,cram,sam}" + - bai: + type: file + description: BAM/CRAM/SAM index file + pattern: "*.{bai,crai,sai}" + - crai: + type: file + description: BAM/CRAM/SAM index file + pattern: "*.{bai,crai,sai}" + - stats: + type: file + description: File containing samtools stats output + pattern: "*.{stats}" + - flagstat: + type: file + description: File containing samtools flagstat output + pattern: "*.{flagstat}" + - idxstats: + type: file + description: File containing samtools idxstats output + pattern: "*.{idxstats}" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" +authors: + - "@drpatelh" + - "@ewels" +maintainers: + - "@drpatelh" + - "@ewels" diff --git a/subworkflows/nf-core/bam_sort_stats_samtools/tests/main.nf.test b/subworkflows/nf-core/bam_sort_stats_samtools/tests/main.nf.test new file mode 100644 index 000000000..821a3cf50 --- /dev/null +++ b/subworkflows/nf-core/bam_sort_stats_samtools/tests/main.nf.test @@ -0,0 +1,134 @@ +nextflow_workflow { + + name "Test Workflow BAM_SORT_STATS_SAMTOOLS" + script "../main.nf" + workflow "BAM_SORT_STATS_SAMTOOLS" + tag "subworkflows" + tag "subworkflows_nfcore" + tag "subworkflows/bam_sort_stats_samtools" + tag "bam_sort_stats_samtools" + tag "subworkflows/bam_stats_samtools" + tag "bam_stats_samtools" + tag "samtools" + tag "samtools/index" + tag "samtools/sort" + tag "samtools/stats" + tag "samtools/idxstats" + tag "samtools/flagstat" + + test("test_bam_sort_stats_samtools_single_end") { + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert workflow.out.bam.get(0).get(1) ==~ ".*.bam"}, + { assert workflow.out.bai.get(0).get(1) ==~ ".*.bai"}, + { assert snapshot( + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.stats, + workflow.out.versions).match() } + ) + } + } + + test("test_bam_sort_stats_samtools_paired_end") { + + when { + workflow { + """ + 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:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert workflow.out.bam.get(0).get(1) ==~ ".*.bam"}, + { assert workflow.out.bai.get(0).get(1) ==~ ".*.bai"}, + { assert snapshot( + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.stats, + workflow.out.versions).match() } + ) + } + } + + test("test_bam_sort_stats_samtools_single_end - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot(workflow.out).match() } + ) + } + } + + test("test_bam_sort_stats_samtools_paired_end - stub") { + + options "-stub" + + when { + workflow { + """ + 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:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot(workflow.out).match() } + ) + } + } +} diff --git a/subworkflows/nf-core/bam_sort_stats_samtools/tests/main.nf.test.snap b/subworkflows/nf-core/bam_sort_stats_samtools/tests/main.nf.test.snap new file mode 100644 index 000000000..e4b8af9a5 --- /dev/null +++ b/subworkflows/nf-core/bam_sort_stats_samtools/tests/main.nf.test.snap @@ -0,0 +1,330 @@ +{ + "test_bam_sort_stats_samtools_single_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.flagstat:md5,2191911d72575a2358b08b1df64ccb53" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,613e048487662c694aa4a2f73ca96a20" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,2fe0f3a7a1f07906061c1dadb62e0d05" + ] + ], + [ + "versions.yml:md5,032c89015461d597fcc5a5331b619d0a", + "versions.yml:md5,416c5e4a374c61167db999b0e400e3cf", + "versions.yml:md5,721391fd94c417808516480c9451c6fd", + "versions.yml:md5,9e12386b91a2977d23292754e3bcb522", + "versions.yml:md5,c294c162aeb09862cc5e55b602647452" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-13T14:07:28.387184086" + }, + "test_bam_sort_stats_samtools_paired_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.flagstat:md5,4f7ffd1e6a5e85524d443209ac97d783" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,df60a8c8d6621100d05178c93fb053a2" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,ba007b13981dad548358c7c957d41e12" + ] + ], + [ + "versions.yml:md5,032c89015461d597fcc5a5331b619d0a", + "versions.yml:md5,416c5e4a374c61167db999b0e400e3cf", + "versions.yml:md5,721391fd94c417808516480c9451c6fd", + "versions.yml:md5,9e12386b91a2977d23292754e3bcb522", + "versions.yml:md5,c294c162aeb09862cc5e55b602647452" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-13T14:07:39.841563832" + }, + "test_bam_sort_stats_samtools_single_end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + "versions.yml:md5,032c89015461d597fcc5a5331b619d0a", + "versions.yml:md5,416c5e4a374c61167db999b0e400e3cf", + "versions.yml:md5,721391fd94c417808516480c9451c6fd", + "versions.yml:md5,9e12386b91a2977d23292754e3bcb522", + "versions.yml:md5,c294c162aeb09862cc5e55b602647452" + ], + "bai": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "csi": [ + + ], + "flagstat": [ + [ + { + "id": "test", + "single_end": false + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "idxstats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,032c89015461d597fcc5a5331b619d0a", + "versions.yml:md5,416c5e4a374c61167db999b0e400e3cf", + "versions.yml:md5,721391fd94c417808516480c9451c6fd", + "versions.yml:md5,9e12386b91a2977d23292754e3bcb522", + "versions.yml:md5,c294c162aeb09862cc5e55b602647452" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-13T16:43:39.764967263" + }, + "test_bam_sort_stats_samtools_paired_end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + "versions.yml:md5,032c89015461d597fcc5a5331b619d0a", + "versions.yml:md5,416c5e4a374c61167db999b0e400e3cf", + "versions.yml:md5,721391fd94c417808516480c9451c6fd", + "versions.yml:md5,9e12386b91a2977d23292754e3bcb522", + "versions.yml:md5,c294c162aeb09862cc5e55b602647452" + ], + "bai": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "csi": [ + + ], + "flagstat": [ + [ + { + "id": "test", + "single_end": false + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "idxstats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,032c89015461d597fcc5a5331b619d0a", + "versions.yml:md5,416c5e4a374c61167db999b0e400e3cf", + "versions.yml:md5,721391fd94c417808516480c9451c6fd", + "versions.yml:md5,9e12386b91a2977d23292754e3bcb522", + "versions.yml:md5,c294c162aeb09862cc5e55b602647452" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-13T16:43:47.431619557" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/bam_stats_samtools/main.nf b/subworkflows/nf-core/bam_stats_samtools/main.nf new file mode 100644 index 000000000..44d4c010a --- /dev/null +++ b/subworkflows/nf-core/bam_stats_samtools/main.nf @@ -0,0 +1,32 @@ +// +// Run SAMtools stats, flagstat and idxstats +// + +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' + +workflow BAM_STATS_SAMTOOLS { + take: + ch_bam_bai // channel: [ val(meta), path(bam), path(bai) ] + ch_fasta // channel: [ val(meta), path(fasta) ] + + main: + ch_versions = Channel.empty() + + SAMTOOLS_STATS ( ch_bam_bai, ch_fasta ) + ch_versions = ch_versions.mix(SAMTOOLS_STATS.out.versions) + + SAMTOOLS_FLAGSTAT ( ch_bam_bai ) + ch_versions = ch_versions.mix(SAMTOOLS_FLAGSTAT.out.versions) + + SAMTOOLS_IDXSTATS ( ch_bam_bai ) + ch_versions = ch_versions.mix(SAMTOOLS_IDXSTATS.out.versions) + + emit: + stats = SAMTOOLS_STATS.out.stats // channel: [ val(meta), path(stats) ] + flagstat = SAMTOOLS_FLAGSTAT.out.flagstat // channel: [ val(meta), path(flagstat) ] + idxstats = SAMTOOLS_IDXSTATS.out.idxstats // channel: [ val(meta), path(idxstats) ] + + versions = ch_versions // channel: [ path(versions.yml) ] +} diff --git a/subworkflows/nf-core/bam_stats_samtools/meta.yml b/subworkflows/nf-core/bam_stats_samtools/meta.yml new file mode 100644 index 000000000..809bf736b --- /dev/null +++ b/subworkflows/nf-core/bam_stats_samtools/meta.yml @@ -0,0 +1,43 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: bam_stats_samtools +description: Produces comprehensive statistics from SAM/BAM/CRAM file +keywords: + - statistics + - counts + - bam + - sam + - cram +components: + - samtools/stats + - samtools/idxstats + - samtools/flagstat +input: + - ch_bam_bai: + description: | + The input channel containing the BAM/CRAM and it's index + Structure: [ val(meta), path(bam), path(bai) ] + - ch_fasta: + description: | + Reference genome fasta file + Structure: [ path(fasta) ] +output: + - stats: + description: | + File containing samtools stats output + Structure: [ val(meta), path(stats) ] + - flagstat: + description: | + File containing samtools flagstat output + Structure: [ val(meta), path(flagstat) ] + - idxstats: + description: | + File containing samtools idxstats output + Structure: [ val(meta), path(idxstats)] + - versions: + description: | + Files containing software versions + Structure: [ path(versions.yml) ] +authors: + - "@drpatelh" +maintainers: + - "@drpatelh" diff --git a/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test b/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test new file mode 100644 index 000000000..76e7a40a0 --- /dev/null +++ b/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test @@ -0,0 +1,188 @@ +nextflow_workflow { + + name "Test Workflow BAM_STATS_SAMTOOLS" + script "../main.nf" + workflow "BAM_STATS_SAMTOOLS" + tag "subworkflows" + tag "subworkflows_nfcore" + tag "bam_stats_samtools" + tag "subworkflows/bam_stats_samtools" + tag "samtools" + tag "samtools/flagstat" + tag "samtools/idxstats" + tag "samtools/stats" + + test("test_bam_stats_samtools_single_end") { + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.sorted.bam.bai', checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot( + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.stats, + workflow.out.versions).match() } + ) + } + } + + test("test_bam_stats_samtools_paired_end") { + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // 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] = Channel.of([ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.stats, + workflow.out.versions).match() } + ) + } + } + + test("test_bam_stats_samtools_paired_end_cram") { + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + 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:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot( + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.stats, + workflow.out.versions).match() } + ) + } + } + + test ("test_bam_stats_samtools_single_end - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.sorted.bam.bai', checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot(workflow.out).match() } + ) + } + } + + test("test_bam_stats_samtools_paired_end - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // 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] = Channel.of([ + [ id:'genome' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + + test("test_bam_stats_samtools_paired_end_cram - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + 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:'genome' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot(workflow.out).match() } + ) + } + } +} diff --git a/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test.snap b/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test.snap new file mode 100644 index 000000000..8ca225263 --- /dev/null +++ b/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test.snap @@ -0,0 +1,350 @@ +{ + "test_bam_stats_samtools_paired_end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,73c55059ed478cd2f9cd93dd3185da3a", + "versions.yml:md5,80d8653e01575b3c381d87073f672fb5", + "versions.yml:md5,cb889532237a2f3d813978ac14a12d51" + ], + "flagstat": [ + [ + { + "id": "test", + "single_end": true + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "idxstats": [ + [ + { + "id": "test", + "single_end": true + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": true + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,73c55059ed478cd2f9cd93dd3185da3a", + "versions.yml:md5,80d8653e01575b3c381d87073f672fb5", + "versions.yml:md5,cb889532237a2f3d813978ac14a12d51" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:08:35.660286921" + }, + "test_bam_stats_samtools_single_end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,73c55059ed478cd2f9cd93dd3185da3a", + "versions.yml:md5,80d8653e01575b3c381d87073f672fb5", + "versions.yml:md5,cb889532237a2f3d813978ac14a12d51" + ], + "flagstat": [ + [ + { + "id": "test", + "single_end": true + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "idxstats": [ + [ + { + "id": "test", + "single_end": true + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": true + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,73c55059ed478cd2f9cd93dd3185da3a", + "versions.yml:md5,80d8653e01575b3c381d87073f672fb5", + "versions.yml:md5,cb889532237a2f3d813978ac14a12d51" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:08:24.220305512" + }, + "test_bam_stats_samtools_paired_end_cram - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,73c55059ed478cd2f9cd93dd3185da3a", + "versions.yml:md5,80d8653e01575b3c381d87073f672fb5", + "versions.yml:md5,cb889532237a2f3d813978ac14a12d51" + ], + "flagstat": [ + [ + { + "id": "test", + "single_end": false + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "idxstats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,73c55059ed478cd2f9cd93dd3185da3a", + "versions.yml:md5,80d8653e01575b3c381d87073f672fb5", + "versions.yml:md5,cb889532237a2f3d813978ac14a12d51" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:08:54.206770141" + }, + "test_bam_stats_samtools_single_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.flagstat:md5,2191911d72575a2358b08b1df64ccb53" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.idxstats:md5,613e048487662c694aa4a2f73ca96a20" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.stats:md5,291bb2393ec947140d12d42c2795b222" + ] + ], + [ + "versions.yml:md5,73c55059ed478cd2f9cd93dd3185da3a", + "versions.yml:md5,80d8653e01575b3c381d87073f672fb5", + "versions.yml:md5,cb889532237a2f3d813978ac14a12d51" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:07:49.731645858" + }, + "test_bam_stats_samtools_paired_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.flagstat:md5,4f7ffd1e6a5e85524d443209ac97d783" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.idxstats:md5,df60a8c8d6621100d05178c93fb053a2" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.stats:md5,8140d69cdedd77570ca1d7618a744e16" + ] + ], + [ + "versions.yml:md5,73c55059ed478cd2f9cd93dd3185da3a", + "versions.yml:md5,80d8653e01575b3c381d87073f672fb5", + "versions.yml:md5,cb889532237a2f3d813978ac14a12d51" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:08:01.421996172" + }, + "test_bam_stats_samtools_paired_end_cram": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.flagstat:md5,a53f3d26e2e9851f7d528442bbfe9781" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,e179601fa7b8ebce81ac3765206f6c15" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,1622856127bafd6cdbadee9cd64ec9b7" + ] + ], + [ + "versions.yml:md5,73c55059ed478cd2f9cd93dd3185da3a", + "versions.yml:md5,80d8653e01575b3c381d87073f672fb5", + "versions.yml:md5,cb889532237a2f3d813978ac14a12d51" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:08:12.640915756" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/bam_stringtie_merge/main.nf b/subworkflows/nf-core/bam_stringtie_merge/main.nf new file mode 100644 index 000000000..7cbd582ed --- /dev/null +++ b/subworkflows/nf-core/bam_stringtie_merge/main.nf @@ -0,0 +1,35 @@ +include { STRINGTIE_STRINGTIE } from '../../../modules/nf-core/stringtie/stringtie/main' +include { STRINGTIE_MERGE } from '../../../modules/nf-core/stringtie/merge/main' + + +workflow BAM_STRINGTIE_MERGE { + + take: + bam_sorted // channel: [ meta, bam ] + ch_chrgtf // channel: [ meta, gtf ] + + main: + ch_versions = Channel.empty() + ch_stringtie_gtfs = Channel.empty() + + STRINGTIE_STRINGTIE( + bam_sorted, + ch_chrgtf.map { _meta, gtf -> [ gtf ] } + ) + ch_versions = ch_versions.mix(STRINGTIE_STRINGTIE.out.versions) + + STRINGTIE_STRINGTIE.out.transcript_gtf + .map { it[1] } + .set { stringtie_gtfs } + + STRINGTIE_MERGE( + stringtie_gtfs, + ch_chrgtf.map { _meta, gtf -> [ gtf ] } + ) + ch_versions = ch_versions.mix(STRINGTIE_MERGE.out.versions) + ch_stringtie_gtfs = STRINGTIE_MERGE.out.gtf + + emit: + stringtie_gtf = ch_stringtie_gtfs // channel: [ meta, gtf ] + versions = ch_versions // channel: [ path(versions.yml) ] +} diff --git a/subworkflows/nf-core/bam_stringtie_merge/meta.yml b/subworkflows/nf-core/bam_stringtie_merge/meta.yml new file mode 100644 index 000000000..19c1496bf --- /dev/null +++ b/subworkflows/nf-core/bam_stringtie_merge/meta.yml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: "bam_stringtie_merge" +description: > + Assemble transcripts from sorted BAM alignments using StringTie, then merge + per-sample transcript GTFs into a unified annotation. +keywords: + - rna-seq + - transcript-assembly + - transcript-merge + - stringtie + - gtf +components: + - stringtie/stringtie + - stringtie/merge +input: + - bam_sorted: + type: file + description: | + Sorted alignment files. + Structure: [ val(meta), path(bam) ] + pattern: "*.bam" + - ch_chrgtf: + type: file + description: | + Reference gene annotation (GTF) for guided assembly and merge. + Structure: [ val(meta), path(gtf) ] + pattern: "*.gtf" +output: + - stringtie_gtf: + type: file + description: | + Merged transcript annotation produced by StringTie --merge. + Structure: [ val(meta), path(gtf) ] + pattern: "*.gtf" + - versions: + type: file + description: | + File containing software versions for the subworkflow components. + Structure: [ path(versions.yml) ] + pattern: "versions.yml" +authors: + - "@atrigila" + - "@rannick" + - "@nvnieuwk" +maintainers: + - "@atrigila" + - "@rannick" + - "@nvnieuwk" diff --git a/subworkflows/nf-core/bam_stringtie_merge/tests/main.nf.test b/subworkflows/nf-core/bam_stringtie_merge/tests/main.nf.test new file mode 100644 index 000000000..48408633d --- /dev/null +++ b/subworkflows/nf-core/bam_stringtie_merge/tests/main.nf.test @@ -0,0 +1,38 @@ +nextflow_workflow { + + name "Test BAM_STRINGTIE_MERGE" + script "../main.nf" + workflow "BAM_STRINGTIE_MERGE" + tag "subworkflows" + tag "subworkflows_nfcore" + tag "stringtie" + tag "stringtie/stringtie" + tag "stringtie/merge" + tag "subworkflows/bam_stringtie_merge" + + test("Should run stringtie subworkflow") { + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', strandedness:'reverse' ], // meta map + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam", checkIfExists: true) + ]) + input[1] = Channel.of([ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genome.gtf", checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() }, + ) + } + } + +} \ No newline at end of file diff --git a/subworkflows/nf-core/bam_stringtie_merge/tests/main.nf.test.snap b/subworkflows/nf-core/bam_stringtie_merge/tests/main.nf.test.snap new file mode 100644 index 000000000..f671dd0b0 --- /dev/null +++ b/subworkflows/nf-core/bam_stringtie_merge/tests/main.nf.test.snap @@ -0,0 +1,27 @@ +{ + "Should run stringtie subworkflow": { + "content": [ + { + "0": [ + "stringtie.merged.gtf:md5,6da479298d73d5b3216d4e1576a2bdf4" + ], + "1": [ + "versions.yml:md5,3ab29dfb260f355cad809acd8dbd1424", + "versions.yml:md5,7c84e875854527473ba6ada66b51e4a6" + ], + "stringtie_gtf": [ + "stringtie.merged.gtf:md5,6da479298d73d5b3216d4e1576a2bdf4" + ], + "versions": [ + "versions.yml:md5,3ab29dfb260f355cad809acd8dbd1424", + "versions.yml:md5,7c84e875854527473ba6ada66b51e4a6" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.6" + }, + "timestamp": "2025-08-31T23:17:24.40243201" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_align_star/fastq_align_star.diff b/subworkflows/nf-core/fastq_align_star/fastq_align_star.diff new file mode 100644 index 000000000..1f4a289e5 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_star/fastq_align_star.diff @@ -0,0 +1,23 @@ +Changes in component 'nf-core/fastq_align_star' +Changes in 'fastq_align_star/main.nf': +--- subworkflows/nf-core/fastq_align_star/main.nf ++++ subworkflows/nf-core/fastq_align_star/main.nf +@@ -51,6 +51,10 @@ + fastq = STAR_ALIGN.out.fastq // channel: [ val(meta), path(fastq) ] + tab = STAR_ALIGN.out.tab // channel: [ val(meta), path(tab) ] + orig_bam_transcript = STAR_ALIGN.out.bam_transcript // channel: [ val(meta), path(bam) ] ++ bam_sorted_aligned = STAR_ALIGN.out.bam_sorted_aligned // channel: [ val(meta), path(bam) ] ++ junctions = STAR_ALIGN.out.junction // channel: [ val(meta), path(junction) ] ++ spl_junc_tabs = STAR_ALIGN.out.spl_junc_tab // channel: [ val(meta), path(spl_junc_tab) ] ++ gene_count = STAR_ALIGN.out.read_per_gene_tab // channel: [ val(meta), path(read_tab) ] + + bam = BAM_SORT_STATS_SAMTOOLS_GENOME.out.bam // channel: [ val(meta), path(bam) ] + bai = BAM_SORT_STATS_SAMTOOLS_GENOME.out.bai // channel: [ val(meta), path(bai) ] + +'subworkflows/nf-core/fastq_align_star/meta.yml' is unchanged +'subworkflows/nf-core/fastq_align_star/nextflow.config' is unchanged +'subworkflows/nf-core/fastq_align_star/tests/main.nf.test' is unchanged +'subworkflows/nf-core/fastq_align_star/tests/main.nf.test.snap' is unchanged +'subworkflows/nf-core/fastq_align_star/tests/nextflow.config' is unchanged +'subworkflows/nf-core/fastq_align_star/tests/with_transcripts.config' is unchanged +************************************************************ diff --git a/subworkflows/nf-core/fastq_align_star/main.nf b/subworkflows/nf-core/fastq_align_star/main.nf new file mode 100644 index 000000000..c4b382ebb --- /dev/null +++ b/subworkflows/nf-core/fastq_align_star/main.nf @@ -0,0 +1,72 @@ +include { STAR_ALIGN } from '../../../modules/nf-core/star/align/main' +include { BAM_SORT_STATS_SAMTOOLS as BAM_SORT_STATS_SAMTOOLS_GENOME } from '../bam_sort_stats_samtools/main' +include { BAM_SORT_STATS_SAMTOOLS as BAM_SORT_STATS_SAMTOOLS_TRANSCRIPTOME } from '../bam_sort_stats_samtools/main' + + +workflow FASTQ_ALIGN_STAR { + + take: + ch_reads // channel: [ val(meta), [ path(reads) ] ] + ch_index // channel: [ path(index) ] + ch_gtf // channel: [ path(gtf) ] + val_star_ignore_sjdbgtf // boolean: when using pre-built STAR indices do not re-extract and use splice junctions from the GTF file + val_seq_platform // string : sequencing platform + val_seq_center // string : sequencing center + ch_fasta // channel: [ val(meta), path(fasta) ] + ch_transcripts_fasta // channel: [ val(meta), path(fasta) ] + + main: + + ch_versions = Channel.empty() + + // + // Map reads with STAR + // + STAR_ALIGN ( ch_reads, ch_index, ch_gtf, val_star_ignore_sjdbgtf, val_seq_platform, val_seq_center ) + ch_versions = ch_versions.mix(STAR_ALIGN.out.versions.first()) + + // + // Sort, index BAM file and run samtools stats, flagstat and idxstats + // + BAM_SORT_STATS_SAMTOOLS_GENOME ( STAR_ALIGN.out.bam, ch_fasta ) + ch_versions = ch_versions.mix(BAM_SORT_STATS_SAMTOOLS_GENOME.out.versions) + + // + // Sort, index BAM file and run samtools stats, flagstat and idxstats + // + // Only runs when '--quantMode TranscriptomeSAM' is set in args and + // STAR_ALIGN.out.bam_transcript is populated + // + + BAM_SORT_STATS_SAMTOOLS_TRANSCRIPTOME ( STAR_ALIGN.out.bam_transcript, ch_transcripts_fasta ) + ch_versions = ch_versions.mix(BAM_SORT_STATS_SAMTOOLS_TRANSCRIPTOME.out.versions) + + emit: + + orig_bam = STAR_ALIGN.out.bam // channel: [ val(meta), path(bam) ] + log_final = STAR_ALIGN.out.log_final // channel: [ val(meta), path(log_final) ] + log_out = STAR_ALIGN.out.log_out // channel: [ val(meta), path(log_out) ] + log_progress = STAR_ALIGN.out.log_progress // channel: [ val(meta), path(log_progress) ] + bam_sorted = STAR_ALIGN.out.bam_sorted // channel: [ val(meta), path(bam) ] + fastq = STAR_ALIGN.out.fastq // channel: [ val(meta), path(fastq) ] + tab = STAR_ALIGN.out.tab // channel: [ val(meta), path(tab) ] + orig_bam_transcript = STAR_ALIGN.out.bam_transcript // channel: [ val(meta), path(bam) ] + bam_sorted_aligned = STAR_ALIGN.out.bam_sorted_aligned // channel: [ val(meta), path(bam) ] + junctions = STAR_ALIGN.out.junction // channel: [ val(meta), path(junction) ] + spl_junc_tabs = STAR_ALIGN.out.spl_junc_tab // channel: [ val(meta), path(spl_junc_tab) ] + gene_count = STAR_ALIGN.out.read_per_gene_tab // channel: [ val(meta), path(read_tab) ] + + bam = BAM_SORT_STATS_SAMTOOLS_GENOME.out.bam // channel: [ val(meta), path(bam) ] + bai = BAM_SORT_STATS_SAMTOOLS_GENOME.out.bai // channel: [ val(meta), path(bai) ] + stats = BAM_SORT_STATS_SAMTOOLS_GENOME.out.stats // channel: [ val(meta), path(stats) ] + flagstat = BAM_SORT_STATS_SAMTOOLS_GENOME.out.flagstat // channel: [ val(meta), path(flagstat) ] + idxstats = BAM_SORT_STATS_SAMTOOLS_GENOME.out.idxstats // channel: [ val(meta), path(idxstats) ] + + bam_transcript = BAM_SORT_STATS_SAMTOOLS_TRANSCRIPTOME.out.bam // channel: [ val(meta), path(bam) ] + bai_transcript = BAM_SORT_STATS_SAMTOOLS_TRANSCRIPTOME.out.bai // channel: [ val(meta), path(bai) ] + stats_transcript = BAM_SORT_STATS_SAMTOOLS_TRANSCRIPTOME.out.stats // channel: [ val(meta), path(stats) ] + flagstat_transcript = BAM_SORT_STATS_SAMTOOLS_TRANSCRIPTOME.out.flagstat // channel: [ val(meta), path(flagstat) ] + idxstats_transcript = BAM_SORT_STATS_SAMTOOLS_TRANSCRIPTOME.out.idxstats // channel: [ val(meta), path(idxstats) ] + + versions = ch_versions // channel: [ path(versions.yml) ] +} diff --git a/subworkflows/nf-core/fastq_align_star/meta.yml b/subworkflows/nf-core/fastq_align_star/meta.yml new file mode 100644 index 000000000..796d3e4b6 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_star/meta.yml @@ -0,0 +1,133 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: "fastq_align_star" +description: Align reads to a reference genome using bowtie2 then sort with samtools +keywords: + - align + - fasta + - genome + - reference +components: + - star/align + - samtools/sort + - samtools/index + - samtools/stats + - samtools/idxstats + - samtools/flagstat + - bam_sort_stats_samtools +input: + - ch_reads: + description: | + List of input FastQ files of size 1 and 2 for single-end and paired-end data, + respectively. + Structure: [ val(meta), [ path(reads) ] ] + - ch_index: + type: directory + description: STAR genome index + pattern: "star" + - ch_gtf: + type: file + description: | + GTF file used to set the splice junctions with the --sjdbGTFfile flag + pattern: "*.gtf" + - val_star_ignore_sjdbgtf: + type: boolean + description: | + If true the --sjdbGTFfile flag is set + pattern: "true|false" + - val_seq_platform: + type: string + description: | + Sequencing platform to be added to the bam header using the --outSAMattrRGline flag + - val_seq_center: + type: string + description: | + Sequencing center to be added to the bam header using the --outSAMattrRGline flag + - ch_fasta: + type: file + description: Reference genome fasta file + pattern: "*.{fasta,fa,fna}" + - ch_transcripts_fasta: + type: file + description: Optional reference genome fasta file + pattern: "*.{fasta,fa,fna}" +output: + - orig_bam: + description: | + Output BAM file containing read alignments + Structure: [ val(meta), path(bam) ] + - log_final: + description: | + STAR final log file + Structure: [ val(meta), path(log_final) ] + - log_out: + description: | + STAR log out file + Structure: [ val(meta), path(log_out) ] + - log_progress: + description: | + STAR log progress file + Structure: [ val(meta), path(log_progress) ] + - bam_sorted: + description: | + Sorted BAM file of read alignments (optional) + Structure: [ val(meta), path(bam) ] + - orig_bam_transcript: + description: | + Output BAM file of transcriptome alignment (optional) + Structure: [ val(meta), path(bam) ] + - fastq: + description: | + Unmapped FastQ files (optional) + Structure: [ val(meta), path(fastq) ] + - tab: + description: | + STAR output tab file(s) (optional) + Structure: [ val(meta), path(tab) ] + - bam: + description: | + BAM file ordered by samtools + Structure: [ val(meta), path(bam) ] + - bai: + description: | + BAI index of the ordered BAM file + Structure: [ val(meta), path(bai) ] + - stats: + description: | + File containing samtools stats output + Structure: [ val(meta), path(stats) ] + - flagstat: + description: | + File containing samtools flagstat output + Structure: [ val(meta), path(flagstat) ] + - idxstats: + description: | + File containing samtools idxstats output + Structure: [ val(meta), path(idxstats) ] + - bam_transcript: + description: | + Transcriptome-level BAM file ordered by samtools (optional) + Structure: [ val(meta), path(bam) ] + - bai_transcript: + description: | + Transcriptome-level BAI index of the ordered BAM file (optional) + Structure: [ val(meta), path(bai) ] + - stats_transcript: + description: | + Transcriptome-level file containing samtools stats output (optional) + Structure: [ val(meta), path(stats) ] + - flagstat_transcript: + description: | + Transcriptome-level file containing samtools flagstat output (optional) + Structure: [ val(meta), path(flagstat) ] + - idxstats_transcript: + description: | + Transcriptome-level file containing samtools idxstats output (optional) + Structure: [ val(meta), path(idxstats) ] + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" +authors: + - "@JoseEspinosa" +maintainers: + - "@JoseEspinosa" diff --git a/subworkflows/nf-core/fastq_align_star/nextflow.config b/subworkflows/nf-core/fastq_align_star/nextflow.config new file mode 100644 index 000000000..926eae710 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_star/nextflow.config @@ -0,0 +1,10 @@ +// IMPORTANT: Add this configuration to your modules.config + +process { + withName: ".*:FASTQ_ALIGN_STAR:BAM_SORT_STATS_SAMTOOLS_GENOME:.*" { + ext.prefix = {"${meta.id}_genome"} + } + withName: ".*:FASTQ_ALIGN_STAR:BAM_SORT_STATS_SAMTOOLS_TRANSCRIPTOME:.*" { + ext.prefix = {"${meta.id}_transcriptome"} + } +} diff --git a/subworkflows/nf-core/fastq_align_star/tests/main.nf.test b/subworkflows/nf-core/fastq_align_star/tests/main.nf.test new file mode 100644 index 000000000..c1ad73a93 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_star/tests/main.nf.test @@ -0,0 +1,250 @@ +nextflow_workflow { + + name "Test Subworkflow FASTQ_ALIGN_STAR" + script "../main.nf" + workflow "FASTQ_ALIGN_STAR" + + tag "subworkflows" + tag "subworkflows_nfcore" + tag "subworkflows/fastq_align_star" + tag "star/align" + tag "star/genomegenerate" + tag "rsem/preparereference" + tag "subworkflows/bam_sort_stats_samtools" + + setup { + run("STAR_GENOMEGENERATE") { + script "../../../../modules/nf-core/star/genomegenerate/main.nf" + process { + """ + input[0] = Channel.of([ + [ id:'test_fasta' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[1] = Channel.of([ + [ id:'test_gtf' ], + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + """ + } + } + } + + test("homo_sapiens - fastq - single_end") { + config "./nextflow.config" + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true) ] + ]) + input[1] = STAR_GENOMEGENERATE.out.index + input[2] = Channel.of([ + [ id:'test_gtf' ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + input[3] = true // star_ignore_sjdbgtf + input[4] = 'illumina' // seq_platform + input[5] = false // seq_center + input[6] = Channel.of([ + [ id:'test_fasta' ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[7] = Channel.of([[:], []]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot( + bam(workflow.out.bam[0][1]).getReadsMD5(), + bam(workflow.out.orig_bam[0][1]).getReadsMD5(), + workflow.out.fastq, + workflow.out.tab, + workflow.out.stats, + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.versions + ).match() }, + { assert path(workflow.out.bai.get(0).get(1)).exists() }, + { assert path(workflow.out.log_out.get(0).get(1)).exists() }, + { assert path(workflow.out.log_final.get(0).get(1)).exists() }, + { assert path(workflow.out.log_progress.get(0).get(1)).exists() } + ) + } + } + + test("homo_sapiens - fastq - paired_end") { + config "./nextflow.config" + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true) + ] + ]) + input[1] = STAR_GENOMEGENERATE.out.index + input[2] = Channel.of([ + [ id:'test_gtf' ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + input[3] = true // star_ignore_sjdbgtf + input[4] = 'illumina' // seq_platform + input[5] = false // seq_center + input[6] = Channel.of([ + [ id:'test_fasta' ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[7] = Channel.of([[:], []]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot( + bam(workflow.out.bam[0][1]).getReadsMD5(), + bam(workflow.out.orig_bam[0][1]).getReadsMD5(), + workflow.out.fastq, + workflow.out.tab, + workflow.out.stats, + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.versions + ).match() }, + { assert path(workflow.out.bai.get(0).get(1)).exists() }, + { assert path(workflow.out.log_out.get(0).get(1)).exists() }, + { assert path(workflow.out.log_final.get(0).get(1)).exists() }, + { assert path(workflow.out.log_progress.get(0).get(1)).exists() } + ) + } + } + + test("homo_sapiens - fastq - paired_end - with_transcriptome") { + config "./with_transcripts.config" + + setup { + run("RSEM_PREPAREREFERENCE") { + script "../../../../modules/nf-core/rsem/preparereference/main.nf" + process { + """ + input[0] = channel.of(file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkifexists: true)) + input[1] = channel.of(file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkifexists: true)) + """ + } + } + } + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true) + ] + ]) + input[1] = STAR_GENOMEGENERATE.out.index + input[2] = Channel.of([ + [ id:'test_gtf' ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + input[3] = true // star_ignore_sjdbgtf + input[4] = 'illumina' // seq_platform + input[5] = false // seq_center + input[6] = Channel.of([ + [ id:'test_fasta' ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[7] = RSEM_PREPAREREFERENCE.out.transcript_fasta.map{[[:], it]} + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot( + bam(workflow.out.bam[0][1]).getReadsMD5(), + bam(workflow.out.orig_bam[0][1]).getReadsMD5(), + bam(workflow.out.bam_transcript[0][1]).getReadsMD5(), + bam(workflow.out.orig_bam_transcript[0][1]).getReadsMD5(), + workflow.out.fastq, + workflow.out.tab, + workflow.out.stats, + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.stats_transcript, + workflow.out.flagstat_transcript, + workflow.out.idxstats_transcript, + workflow.out.versions + ).match() }, + { assert path(workflow.out.bai.get(0).get(1)).exists() }, + { assert path(workflow.out.bai_transcript.get(0).get(1)).exists() }, + { assert path(workflow.out.log_out.get(0).get(1)).exists() }, + { assert path(workflow.out.log_final.get(0).get(1)).exists() }, + { assert path(workflow.out.log_progress.get(0).get(1)).exists() } + ) + } + } + + test("homo_sapiens - fastq - paired_end - transcripts - no_transcriptome") { + config "./with_transcripts.config" + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_rnaseq_2.fastq.gz', checkIfExists: true) + ] + ]) + input[1] = STAR_GENOMEGENERATE.out.index + input[2] = Channel.of([ + [ id:'test_gtf' ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.gtf', checkIfExists: true) ] + ]) + input[3] = true // star_ignore_sjdbgtf + input[4] = 'illumina' // seq_platform + input[5] = false // seq_center + input[6] = Channel.of([ + [ id:'test_fasta' ], // meta map + [ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) ] + ]) + input[7] = Channel.of([[:], []]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot( + bam(workflow.out.bam[0][1]).getReadsMD5(), + bam(workflow.out.orig_bam[0][1]).getReadsMD5(), + workflow.out.fastq, + workflow.out.tab, + workflow.out.stats, + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.stats_transcript, + workflow.out.versions + ).match() }, + { assert path(workflow.out.bai.get(0).get(1)).exists() }, + { assert path(workflow.out.log_out.get(0).get(1)).exists() }, + { assert path(workflow.out.log_final.get(0).get(1)).exists() }, + { assert path(workflow.out.log_progress.get(0).get(1)).exists() } + ) + } + } +} diff --git a/subworkflows/nf-core/fastq_align_star/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_align_star/tests/main.nf.test.snap new file mode 100644 index 000000000..c21ec0cc9 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_star/tests/main.nf.test.snap @@ -0,0 +1,282 @@ +{ + "homo_sapiens - fastq - paired_end - transcripts - no_transcriptome": { + "content": [ + "1e02b8e6b4a02ab58bfe4ee795aba815", + "47a5da42b696886e2ed36af199a9042e", + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.SJ.out.tab:md5,844af19ab0fc8cd9a3f75228445aca0d" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.stats:md5,d7509941ffbfb221115faa2481115f23" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.flagstat:md5,db0e25cd0b37d3030e807846c022199e" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.idxstats:md5,107ca94dd426cc44db316f0d402307c5" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.stats:md5,10c63f09ff2b849443bafad71a824b0e" + ] + ], + [ + "versions.yml:md5,167faaf660e4936645b0ad5a9d3bf620", + "versions.yml:md5,24b681997fbdd563910240af500d965e", + "versions.yml:md5,2bdea75e8dad77676c54b806ceecb68b", + "versions.yml:md5,2e0fd05eea17eb1f5cdf079c12a30b88", + "versions.yml:md5,421308f325b1038feafdb6862cebc28a", + "versions.yml:md5,63c683e2834a8968f4d626dbe9b7a07f", + "versions.yml:md5,6a96fec10a72e1da236e6e1d7519590e", + "versions.yml:md5,9dd7217e54100569bf9f87f7a1cca54a", + "versions.yml:md5,a305cb08e7cb3194be54d0bb8a257722", + "versions.yml:md5,ade8e9901ff456f43bc0f93f5f7af793", + "versions.yml:md5,ec328c7ea462702388fa15204aeb6689" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T17:09:46.703861921" + }, + "homo_sapiens - fastq - paired_end - with_transcriptome": { + "content": [ + "1e02b8e6b4a02ab58bfe4ee795aba815", + "47a5da42b696886e2ed36af199a9042e", + "9b8ec790f8138071a0731b5225c84f00", + "9b8ec790f8138071a0731b5225c84f00", + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.SJ.out.tab:md5,844af19ab0fc8cd9a3f75228445aca0d" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.stats:md5,d7509941ffbfb221115faa2481115f23" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.flagstat:md5,db0e25cd0b37d3030e807846c022199e" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.idxstats:md5,107ca94dd426cc44db316f0d402307c5" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.stats:md5,10ca84181b17dafd7248296114f05333" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.flagstat:md5,a204dee59ef8b7cd0f7d952a80119b77" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.idxstats:md5,4030919b4a05393dcd7e699d72725803" + ] + ], + [ + "versions.yml:md5,167faaf660e4936645b0ad5a9d3bf620", + "versions.yml:md5,24b681997fbdd563910240af500d965e", + "versions.yml:md5,2bdea75e8dad77676c54b806ceecb68b", + "versions.yml:md5,2e0fd05eea17eb1f5cdf079c12a30b88", + "versions.yml:md5,421308f325b1038feafdb6862cebc28a", + "versions.yml:md5,63c683e2834a8968f4d626dbe9b7a07f", + "versions.yml:md5,6a96fec10a72e1da236e6e1d7519590e", + "versions.yml:md5,9dd7217e54100569bf9f87f7a1cca54a", + "versions.yml:md5,a305cb08e7cb3194be54d0bb8a257722", + "versions.yml:md5,ade8e9901ff456f43bc0f93f5f7af793", + "versions.yml:md5,ec328c7ea462702388fa15204aeb6689" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T17:08:59.431516768" + }, + "homo_sapiens - fastq - single_end": { + "content": [ + "8b3699d1b3344c90f82363edadae6427", + "c491ec34a25f55c7583e325e0a191b5d", + [ + + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.SJ.out.tab:md5,75a516ab950fb958f40b29996474949c" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.stats:md5,30abf517cda76c6a7468541781c4dd7a" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.flagstat:md5,075e7a684a7ceb5fd1dae154f823128a" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.idxstats:md5,0d5a12e3e3ffdb15f1c6c50f02f22575" + ] + ], + [ + "versions.yml:md5,167faaf660e4936645b0ad5a9d3bf620", + "versions.yml:md5,24b681997fbdd563910240af500d965e", + "versions.yml:md5,2e0fd05eea17eb1f5cdf079c12a30b88", + "versions.yml:md5,421308f325b1038feafdb6862cebc28a", + "versions.yml:md5,6a96fec10a72e1da236e6e1d7519590e", + "versions.yml:md5,9dd7217e54100569bf9f87f7a1cca54a" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T17:07:23.833781959" + }, + "homo_sapiens - fastq - paired_end": { + "content": [ + "1e02b8e6b4a02ab58bfe4ee795aba815", + "47a5da42b696886e2ed36af199a9042e", + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.SJ.out.tab:md5,844af19ab0fc8cd9a3f75228445aca0d" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.stats:md5,d7509941ffbfb221115faa2481115f23" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.flagstat:md5,db0e25cd0b37d3030e807846c022199e" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.idxstats:md5,107ca94dd426cc44db316f0d402307c5" + ] + ], + [ + "versions.yml:md5,167faaf660e4936645b0ad5a9d3bf620", + "versions.yml:md5,24b681997fbdd563910240af500d965e", + "versions.yml:md5,2e0fd05eea17eb1f5cdf079c12a30b88", + "versions.yml:md5,421308f325b1038feafdb6862cebc28a", + "versions.yml:md5,6a96fec10a72e1da236e6e1d7519590e", + "versions.yml:md5,9dd7217e54100569bf9f87f7a1cca54a" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-11T17:08:08.904146433" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_align_star/tests/nextflow.config b/subworkflows/nf-core/fastq_align_star/tests/nextflow.config new file mode 100644 index 000000000..6af49d586 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_star/tests/nextflow.config @@ -0,0 +1,21 @@ +process { + + publishDir = { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" } + + withName: STAR_GENOMEGENERATE { + ext.args = '--genomeSAindexNbases 9' + } + + withName: STAR_ALIGN { + ext.args = '--readFilesCommand zcat' + } + + withName: '.*:BAM_SORT_STATS_SAMTOOLS_.*:SAMTOOLS_.*' { + ext.prefix = { "${meta.id}.sorted" } + } + + withName: '.*:BAM_SORT_STATS_SAMTOOLS_.*:BAM_STATS_SAMTOOLS:.*' { + ext.prefix = { "${meta.id}.sorted.bam" } + } + +} diff --git a/subworkflows/nf-core/fastq_align_star/tests/with_transcripts.config b/subworkflows/nf-core/fastq_align_star/tests/with_transcripts.config new file mode 100644 index 000000000..62f152501 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_star/tests/with_transcripts.config @@ -0,0 +1,21 @@ +process { + + publishDir = { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" } + + withName: STAR_GENOMEGENERATE { + ext.args = '--genomeSAindexNbases 9' + } + + withName: STAR_ALIGN { + ext.args = '--readFilesCommand zcat --quantMode TranscriptomeSAM' + } + + withName: '.*:BAM_SORT_STATS_SAMTOOLS_.*:SAMTOOLS_.*' { + ext.prefix = { "${meta.id}.sorted" } + } + + withName: '.*:BAM_SORT_STATS_SAMTOOLS_.*:BAM_STATS_SAMTOOLS:.*' { + ext.prefix = { "${meta.id}.sorted.bam" } + } + +} diff --git a/subworkflows/nf-core/fastq_fastqc_umitools_fastp/main.nf b/subworkflows/nf-core/fastq_fastqc_umitools_fastp/main.nf new file mode 100644 index 000000000..170ce78c3 --- /dev/null +++ b/subworkflows/nf-core/fastq_fastqc_umitools_fastp/main.nf @@ -0,0 +1,153 @@ +// +// Read QC, UMI extraction and trimming +// +include { FASTQC as FASTQC_RAW } from '../../../modules/nf-core/fastqc/main' +include { FASTQC as FASTQC_TRIM } from '../../../modules/nf-core/fastqc/main' +include { UMITOOLS_EXTRACT } from '../../../modules/nf-core/umitools/extract/main' +include { FASTP } from '../../../modules/nf-core/fastp/main' + +// +// Function that parses fastp json output file to get total number of reads after trimming +// + +def getFastpReadsAfterFiltering(json_file, min_num_reads) { + + if (workflow.stubRun) { + return min_num_reads + } + + def json = new groovy.json.JsonSlurper().parseText(json_file.text).get('summary') as Map + return json['after_filtering']['total_reads'].toLong() +} + +def getFastpAdapterSequence(json_file) { + // Handle stub runs + if (workflow.stubRun) { + return "" + } + + def json = new groovy.json.JsonSlurper().parseText(json_file.text) as Map + try { + return json['adapter_cutting']['read1_adapter_sequence'] + } + catch (Exception ex) { + return "" + } +} + +workflow FASTQ_FASTQC_UMITOOLS_FASTP { + take: + reads // channel: [ val(meta), [ reads ] ] + skip_fastqc // boolean: true/false + with_umi // boolean: true/false + skip_umi_extract // boolean: true/false + umi_discard_read // integer: 0, 1 or 2 + skip_trimming // boolean: true/false + adapter_fasta // file: adapter.fasta + save_trimmed_fail // boolean: true/false + save_merged // boolean: true/false + min_trimmed_reads // integer: > 0 + + main: + ch_versions = Channel.empty() + fastqc_raw_html = Channel.empty() + fastqc_raw_zip = Channel.empty() + umi_log = Channel.empty() + trim_json = Channel.empty() + trim_html = Channel.empty() + trim_log = Channel.empty() + trim_reads_fail = Channel.empty() + trim_reads_merged = Channel.empty() + fastqc_trim_html = Channel.empty() + fastqc_trim_zip = Channel.empty() + trim_read_count = Channel.empty() + adapter_seq = Channel.empty() + + if (!skip_fastqc) { + FASTQC_RAW( + reads + ) + fastqc_raw_html = FASTQC_RAW.out.html + fastqc_raw_zip = FASTQC_RAW.out.zip + ch_versions = ch_versions.mix(FASTQC_RAW.out.versions.first()) + } + + umi_reads = reads + if (with_umi && !skip_umi_extract) { + UMITOOLS_EXTRACT( + reads + ) + umi_reads = UMITOOLS_EXTRACT.out.reads + umi_log = UMITOOLS_EXTRACT.out.log + ch_versions = ch_versions.mix(UMITOOLS_EXTRACT.out.versions.first()) + + // Discard R1 / R2 if required + if (umi_discard_read in [1, 2]) { + UMITOOLS_EXTRACT.out.reads + .map { meta, _reads -> + meta.single_end ? [meta, _reads] : [meta + [single_end: true], _reads[umi_discard_read % 2]] + } + .set { umi_reads } + } + } + + trim_reads = umi_reads + if (!skip_trimming) { + FASTP( + umi_reads, + adapter_fasta, + false, + save_trimmed_fail, + save_merged, + ) + trim_json = FASTP.out.json + trim_html = FASTP.out.html + trim_log = FASTP.out.log + trim_reads_fail = FASTP.out.reads_fail + trim_reads_merged = FASTP.out.reads_merged + ch_versions = ch_versions.mix(FASTP.out.versions.first()) + + // + // Filter FastQ files based on minimum trimmed read count after adapter trimming + // + FASTP.out.reads.join(trim_json).map { meta, _reads, json -> [meta, _reads, getFastpReadsAfterFiltering(json, min_trimmed_reads.toLong())] }.set { ch_num_trimmed_reads } + + ch_num_trimmed_reads + .filter { _meta, _reads, num_reads -> num_reads >= min_trimmed_reads.toLong() } + .map { meta, _reads, _num_reads -> [meta, _reads] } + .set { trim_reads } + + ch_num_trimmed_reads + .map { meta, _reads, num_reads -> [meta, num_reads] } + .set { trim_read_count } + + trim_json + .map { meta, json -> [meta, getFastpAdapterSequence(json)] } + .set { adapter_seq } + + if (!skip_fastqc) { + FASTQC_TRIM( + trim_reads + ) + fastqc_trim_html = FASTQC_TRIM.out.html + fastqc_trim_zip = FASTQC_TRIM.out.zip + ch_versions = ch_versions.mix(FASTQC_TRIM.out.versions.first()) + } + } + + emit: + reads = trim_reads // channel: [ val(meta), [ reads ] ] + fastqc_raw_html // channel: [ val(meta), [ html ] ] + fastqc_raw_zip // channel: [ val(meta), [ zip ] ] + umi_log // channel: [ val(meta), [ log ] ] + adapter_seq // channel: [ val(meta), [ adapter_seq] ] + trim_json // channel: [ val(meta), [ json ] ] + trim_html // channel: [ val(meta), [ html ] ] + trim_log // channel: [ val(meta), [ log ] ] + trim_reads_fail // channel: [ val(meta), [ fastq.gz ] ] + trim_reads_merged // channel: [ val(meta), [ fastq.gz ] ] + trim_read_count // channel: [ val(meta), val(count) ] + fastqc_trim_html // channel: [ val(meta), [ html ] ] + fastqc_trim_zip // channel: [ val(meta), [ zip ] ] + versions = ch_versions // channel: [ versions.yml ] +} diff --git a/subworkflows/nf-core/fastq_fastqc_umitools_fastp/meta.yml b/subworkflows/nf-core/fastq_fastqc_umitools_fastp/meta.yml new file mode 100644 index 000000000..9308fe9ba --- /dev/null +++ b/subworkflows/nf-core/fastq_fastqc_umitools_fastp/meta.yml @@ -0,0 +1,129 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +# yaml-language-server: $schema=yaml-schema.json +name: "fastq_fastqc_umitools_fastp" +description: Read QC, UMI extraction and trimming +keywords: + - fastq + - fastqc + - qc + - UMI + - trimming + - fastp +components: + - fastqc + - umitools/extract + - fastp +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - reads: + type: file + description: | + List of input FastQ files of size 1 and 2 for single-end and paired-end data, + respectively. + - skip_fastqc: + type: boolean + description: | + Skip fastqc process + - with_umi: + type: boolean + description: | + With or without umi detection + - skip_umi_extract: + type: boolean + description: | + With or without umi extrection + - umi_discard_read: + type: integer + description: | + Discard R1 / R2 if required + - skip_trimming: + type: boolean + description: | + Allows to skip FastP execution + - adapter_fasta: + type: file + description: | + Fasta file of adapter sequences + - save_trimmed_fail: + type: boolean + description: | + Save trimmed fastqs of failed samples + - save_merged: + type: boolean + description: | + Save merged fastqs + - min_trimmed_reads: + type: integer + description: | + Inputs with fewer than this reads will be filtered out of the "reads" output channel +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - reads: + type: file + description: > + Extracted FASTQ files. | For single-end reads, pattern is \${prefix}.umi_extract.fastq.gz. | + For paired-end reads, pattern is \${prefix}.umi_extract_{1,2}.fastq.gz. + pattern: "*.{fastq.gz}" + - fastqc_html: + type: file + description: FastQC report + pattern: "*_{fastqc.html}" + - fastqc_zip: + type: file + description: FastQC report archive + pattern: "*_{fastqc.zip}" + - log: + type: file + description: Logfile for umi_tools + pattern: "*.{log}" + - trim_json: + type: file + description: FastP Trimming report + pattern: "*.{fastp.json}" + - trim_html: + type: file + description: FastP Trimming report + pattern: "*.{fastp.html}" + - log: + type: file + description: Logfile FastP + pattern: "*.{fastp.log}" + - trim_reads_fail: + type: file + description: Trimmed fastq files failing QC + pattern: "*.{fastq.gz}" + - trim_reads_merged: + type: file + description: Trimmed and merged fastq files + pattern: "*.{fastq.gz}" + - trim_read_count: + type: integer + description: Number of reads after trimming + - fastqc_trim_html: + type: file + description: FastQC report + pattern: "*_{fastqc.html}" + - fastqc_trim_zip: + type: file + description: FastQC report archive + pattern: "*_{fastqc.zip}" + - adapter_seq: + type: string + description: | + Adapter Sequence found in read1 + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" +authors: + - "@robsyme" +maintainers: + - "@robsyme" diff --git a/subworkflows/nf-core/fastq_fastqc_umitools_fastp/tests/main.nf.test b/subworkflows/nf-core/fastq_fastqc_umitools_fastp/tests/main.nf.test new file mode 100644 index 000000000..edf325e6e --- /dev/null +++ b/subworkflows/nf-core/fastq_fastqc_umitools_fastp/tests/main.nf.test @@ -0,0 +1,996 @@ +nextflow_workflow { + + name "Test Workflow FASTQ_FASTQC_UMITOOLS_FASTP" + script "../main.nf" + workflow "FASTQ_FASTQC_UMITOOLS_FASTP" + config './nextflow.config' + + tag "subworkflows" + tag "subworkflows_nfcore" + tag "subworkflows/fastq_fastqc_umitools_fastp" + tag "fastq_fastqc_umitools_fastp" + tag "fastqc" + tag "umitools/extract" + tag "fastp" + + + test("sarscov2 paired-end [fastq]") { + + when { + params { + skip_fastqc = false + with_umi = false + skip_umi_extract = false + umi_discard_read = 1 + skip_trimming = false + adapter_fasta = [] + save_trimmed_fail = false + save_merged = false + min_trimmed_reads = 1 + fastp_args = "" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert workflow.out.fastqc_raw_html }, + { assert workflow.out.fastqc_raw_zip }, + { assert workflow.out.fastqc_trim_html }, + { assert workflow.out.fastqc_trim_zip }, + { assert workflow.out.trim_html }, + { assert workflow.out.trim_log }, + { assert snapshot( + workflow.out.adapter_seq, + workflow.out.reads, + workflow.out.trim_json, + workflow.out.trim_read_count, + workflow.out.trim_reads_fail, + workflow.out.trim_reads_merged, + workflow.out.umi_log, + workflow.out.versions + ).match() + } + ) + } + } + + test("sarscov2 paired-end [fastq] | skip_fastqc") { + + when { + params { + skip_fastqc = true + with_umi = false + skip_umi_extract = false + umi_discard_read = 1 + skip_trimming = false + adapter_fasta = [] + save_trimmed_fail = false + save_merged = false + min_trimmed_reads = 1 + fastp_args = "" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert workflow.out.trim_html }, + { assert workflow.out.trim_log }, + { assert !workflow.out.fastqc_raw_html }, + { assert !workflow.out.fastqc_raw_zip }, + { assert !workflow.out.fastqc_trim_html }, + { assert !workflow.out.fastqc_trim_zip }, + { assert snapshot( + workflow.out.adapter_seq, + workflow.out.reads, + workflow.out.trim_json, + workflow.out.trim_read_count, + workflow.out.trim_reads_fail, + workflow.out.trim_reads_merged, + workflow.out.umi_log, + workflow.out.versions + ).match() + } + ) + } + } + + test("sarscov2 paired-end [fastq] | with_umi") { + + when { + params { + skip_fastqc = false + with_umi = true + skip_umi_extract = false + umi_discard_read = 1 + skip_trimming = false + adapter_fasta = [] + save_trimmed_fail = false + save_merged = false + min_trimmed_reads = 1 + fastp_args = "" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert workflow.out.fastqc_raw_html }, + { assert workflow.out.fastqc_raw_zip }, + { assert workflow.out.fastqc_trim_html }, + { assert workflow.out.fastqc_trim_zip }, + { assert workflow.out.trim_html }, + { assert workflow.out.trim_log }, + { assert snapshot( + workflow.out.adapter_seq, + workflow.out.reads, + workflow.out.trim_json, + workflow.out.trim_read_count, + workflow.out.trim_reads_fail, + workflow.out.trim_reads_merged, + workflow.out.versions + ).match() + } + ) + } + } + + + test("sarscov2 paired-end [fastq] | skip_umi_extract") { + + when { + params { + skip_fastqc = false + with_umi = true + skip_umi_extract = true + umi_discard_read = 1 + skip_trimming = false + adapter_fasta = [] + save_trimmed_fail = false + save_merged = false + min_trimmed_reads = 1 + fastp_args = "" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert workflow.out.fastqc_raw_html }, + { assert workflow.out.fastqc_raw_zip }, + { assert workflow.out.fastqc_trim_html }, + { assert workflow.out.fastqc_trim_zip }, + { assert workflow.out.trim_html }, + { assert workflow.out.trim_log }, + { assert snapshot( + workflow.out.adapter_seq, + workflow.out.reads, + workflow.out.trim_json, + workflow.out.trim_read_count, + workflow.out.trim_reads_fail, + workflow.out.trim_reads_merged, + workflow.out.umi_log, + workflow.out.versions + ).match() + } + ) + } + } + + test("sarscov2 paired-end [fastq] | umi_discard_read = 2") { + + when { + params { + skip_fastqc = false + with_umi = true + skip_umi_extract = true + umi_discard_read = 2 + skip_trimming = false + adapter_fasta = [] + save_trimmed_fail = false + save_merged = false + min_trimmed_reads = 1 + fastp_args = "" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert workflow.out.fastqc_raw_html }, + { assert workflow.out.fastqc_raw_zip }, + { assert workflow.out.fastqc_trim_html }, + { assert workflow.out.fastqc_trim_zip }, + { assert workflow.out.trim_html }, + { assert workflow.out.trim_log }, + { assert snapshot( + workflow.out.adapter_seq, + workflow.out.reads, + workflow.out.trim_json, + workflow.out.trim_read_count, + workflow.out.trim_reads_fail, + workflow.out.trim_reads_merged, + workflow.out.umi_log, + workflow.out.versions + ).match() + } + ) + } + } + + test("sarscov2 paired-end [fastq] | skip_trimming") { + + when { + params { + skip_fastqc = false + with_umi = false + skip_umi_extract = false + umi_discard_read = 1 + skip_trimming = true + adapter_fasta = [] + save_trimmed_fail = false + save_merged = false + min_trimmed_reads = 1 + fastp_args = "" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert workflow.out.fastqc_raw_html }, + { assert workflow.out.fastqc_raw_zip }, + { assert !workflow.out.fastqc_trim_html }, + { assert !workflow.out.fastqc_trim_zip }, + { assert !workflow.out.trim_html }, + { assert !workflow.out.trim_log }, + { assert snapshot( + // If we skip trimming then input is output, so not snapshotting + workflow.out.adapter_seq, + workflow.out.reads.get(0).get(0), // Reads meta map + workflow.out.trim_json, + workflow.out.trim_read_count, + workflow.out.trim_reads_fail, + workflow.out.trim_reads_merged, + workflow.out.umi_log, + workflow.out.versions + ).match() + } + ) + } + } + + test("sarscov2 paired-end [fastq] | save_trimmed_fail") { + + when { + params { + skip_fastqc = false + with_umi = false + skip_umi_extract = false + umi_discard_read = 1 + skip_trimming = false + adapter_fasta = [] + save_trimmed_fail = true + save_merged = false + min_trimmed_reads = 1 + fastp_args = "-e 30" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert workflow.out.fastqc_raw_html }, + { assert workflow.out.fastqc_raw_zip }, + { assert workflow.out.fastqc_trim_html }, + { assert workflow.out.fastqc_trim_zip }, + { assert workflow.out.trim_html }, + { assert workflow.out.trim_log }, + { assert snapshot( + workflow.out.adapter_seq, + workflow.out.reads, + workflow.out.trim_json, + workflow.out.trim_read_count, + workflow.out.trim_reads_fail, + workflow.out.trim_reads_merged, + workflow.out.umi_log, + workflow.out.versions + ).match() + } + ) + } + } + + test("sarscov2 paired-end [fastq] | save_merged") { + + when { + params { + skip_fastqc = false + with_umi = false + skip_umi_extract = false + umi_discard_read = 1 + skip_trimming = false + adapter_fasta = [] + save_trimmed_fail = false + save_merged = true + min_trimmed_reads = 1 + fastp_args = "" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert workflow.out.fastqc_raw_html }, + { assert workflow.out.fastqc_raw_zip }, + { assert workflow.out.fastqc_trim_html }, + { assert workflow.out.fastqc_trim_zip }, + { assert workflow.out.trim_html }, + { assert workflow.out.trim_log }, + { assert snapshot( + workflow.out.adapter_seq, + workflow.out.reads, + workflow.out.trim_json, + workflow.out.trim_read_count, + workflow.out.trim_reads_fail, + workflow.out.trim_reads_merged, + workflow.out.umi_log, + workflow.out.versions + ).match() + } + ) + } + } + + test("sarscov2 paired-end [fastq] | min_trimmed_reads = 26") { + // Subworkflow should stop after FASTP which trims down to 25 reads + + when { + params { + skip_fastqc = false + with_umi = false + skip_umi_extract = false + umi_discard_read = 1 + skip_trimming = false + adapter_fasta = [] + save_trimmed_fail = false + save_merged = true + min_trimmed_reads = 26 + fastp_args = "" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert workflow.out.fastqc_raw_html }, + { assert workflow.out.fastqc_raw_zip }, + { assert workflow.out.fastqc_trim_html }, + { assert workflow.out.fastqc_trim_zip }, + { assert workflow.out.trim_html }, + { assert workflow.out.trim_log }, + { assert snapshot( + workflow.out.adapter_seq, + workflow.out.reads, + workflow.out.trim_json, + workflow.out.trim_read_count, + workflow.out.trim_reads_fail, + workflow.out.trim_reads_merged, + workflow.out.umi_log, + workflow.out.versions + ).match() + } + ) + } + } + + test("sarscov2 paired-end [fastq] - stub") { + options '-stub-run' + + when { + params { + skip_fastqc = false + with_umi = false + skip_umi_extract = false + umi_discard_read = 1 + skip_trimming = false + adapter_fasta = [] + save_trimmed_fail = false + save_merged = false + min_trimmed_reads = 1 + fastp_args = "" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + + test("sarscov2 paired-end [fastq] | skip_fastqc - stub") { + options "-stub-run" + + when { + params { + skip_fastqc = true + with_umi = false + skip_umi_extract = false + umi_discard_read = 1 + skip_trimming = false + adapter_fasta = [] + save_trimmed_fail = false + save_merged = false + min_trimmed_reads = 1 + fastp_args = "" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + + test("sarscov2 paired-end [fastq] | with_umi - stub") { + options "-stub-run" + + when { + params { + skip_fastqc = false + with_umi = true + skip_umi_extract = false + umi_discard_read = 1 + skip_trimming = false + adapter_fasta = [] + save_trimmed_fail = false + save_merged = false + min_trimmed_reads = 1 + fastp_args = "" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + + + test("sarscov2 paired-end [fastq] | skip_umi_extract - stub") { + options "-stub-run" + + when { + params { + skip_fastqc = false + with_umi = true + skip_umi_extract = true + umi_discard_read = 1 + skip_trimming = false + adapter_fasta = [] + save_trimmed_fail = false + save_merged = false + min_trimmed_reads = 1 + fastp_args = "" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + + test("sarscov2 paired-end [fastq] | umi_discard_read = 2 - stub") { + options "-stub-run" + + when { + params { + skip_fastqc = false + with_umi = true + skip_umi_extract = true + umi_discard_read = 2 + skip_trimming = false + adapter_fasta = [] + save_trimmed_fail = false + save_merged = false + min_trimmed_reads = 1 + fastp_args = "" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + + test("sarscov2 paired-end [fastq] | skip_trimming - stub") { + options "-stub-run" + + when { + params { + skip_fastqc = false + with_umi = false + skip_umi_extract = false + umi_discard_read = 1 + skip_trimming = true + adapter_fasta = [] + save_trimmed_fail = false + save_merged = false + min_trimmed_reads = 1 + fastp_args = "" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.adapter_seq, + workflow.out.fastqc_raw_html, + workflow.out.fastqc_raw_zip, + workflow.out.fastqc_trim_html, + workflow.out.fastqc_trim_zip, + workflow.out.trim_html, + workflow.out.trim_json, + workflow.out.trim_log, + workflow.out.trim_read_count, + workflow.out.trim_reads_fail, + workflow.out.trim_reads_merged, + workflow.out.umi_log, + workflow.out.versions).match() } + ) + } + } + + test("sarscov2 paired-end [fastq] | save_trimmed_fail - stub") { + options "-stub-run" + + when { + params { + skip_fastqc = false + with_umi = false + skip_umi_extract = false + umi_discard_read = 1 + skip_trimming = false + adapter_fasta = [] + save_trimmed_fail = true + save_merged = false + min_trimmed_reads = 1 + fastp_args = "-e 30" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + + test("sarscov2 paired-end [fastq] | save_merged - stub") { + options "-stub-run" + + when { + params { + skip_fastqc = false + with_umi = false + skip_umi_extract = false + umi_discard_read = 1 + skip_trimming = false + adapter_fasta = [] + save_trimmed_fail = false + save_merged = true + min_trimmed_reads = 1 + fastp_args = "" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + + test("sarscov2 paired-end [fastq] | min_trimmed_reads = 26 - stub") { + // Subworkflow should stop after FASTP which trims down to 25 reads + options "-stub-run" + + when { + params { + skip_fastqc = false + with_umi = false + skip_umi_extract = false + umi_discard_read = 1 + skip_trimming = false + adapter_fasta = [] + save_trimmed_fail = false + save_merged = true + min_trimmed_reads = 26 + fastp_args = "" + } + workflow { + """ + 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) + ] + ]) + input[1] = params.skip_fastqc + input[2] = params.with_umi + input[3] = params.skip_umi_extract + input[4] = params.umi_discard_read + input[5] = params.skip_trimming + input[6] = params.adapter_fasta + input[7] = params.save_trimmed_fail + input[8] = params.save_merged + input[9] = params.min_trimmed_reads + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } +} diff --git a/subworkflows/nf-core/fastq_fastqc_umitools_fastp/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_fastqc_umitools_fastp/tests/main.nf.test.snap new file mode 100644 index 000000000..47c8b1d55 --- /dev/null +++ b/subworkflows/nf-core/fastq_fastqc_umitools_fastp/tests/main.nf.test.snap @@ -0,0 +1,2407 @@ +{ + "sarscov2 paired-end [fastq] | skip_umi_extract": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "unspecified" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7", + "test_2.fastp.fastq.gz:md5,25cbdca08e2083dbd4f0502de6b62f39" + ] + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,7cf3bff1922b512bcca58439eb2d3679" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + 198 + ] + ], + [ + + ], + [ + + ], + [ + + ], + [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:42:42.262180451" + }, + "sarscov2 paired-end [fastq] | with_umi": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,ba8c6c3a7ce718d9a2c5857e2edf53bc" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,da0403af3eb7d950f209a1e758de2db0" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + 99 + ] + ], + [ + + ], + [ + + ], + [ + "versions.yml:md5,01f264f78de3c6d893c449cc6d3cd721", + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:42:31.905020586" + }, + "sarscov2 paired-end [fastq] | umi_discard_read = 2 - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + { + "id": "test", + "single_end": false + }, + 1 + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "12": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "13": [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + + ], + "9": [ + + ], + "adapter_seq": [ + [ + { + "id": "test", + "single_end": false + }, + "" + ] + ], + "fastqc_raw_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_raw_zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_trim_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_trim_zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "trim_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_read_count": [ + [ + { + "id": "test", + "single_end": false + }, + 1 + ] + ], + "trim_reads_fail": [ + + ], + "trim_reads_merged": [ + + ], + "umi_log": [ + + ], + "versions": [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T14:19:10.965815964" + }, + "sarscov2 paired-end [fastq] | skip_trimming - stub": { + "content": [ + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-12T14:32:15.355312216" + }, + "sarscov2 paired-end [fastq] | skip_trimming": { + "content": [ + [ + + ], + { + "id": "test", + "single_end": false + }, + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + + ], + [ + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-12T14:24:19.774510678" + }, + "sarscov2 paired-end [fastq] | umi_discard_read = 2": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "unspecified" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7", + "test_2.fastp.fastq.gz:md5,25cbdca08e2083dbd4f0502de6b62f39" + ] + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,7cf3bff1922b512bcca58439eb2d3679" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + 198 + ] + ], + [ + + ], + [ + + ], + [ + + ], + [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:42:49.469455815" + }, + "sarscov2 paired-end [fastq] | min_trimmed_reads = 26 - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + { + "id": "test", + "single_end": false + }, + 26 + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "12": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "13": [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + + ], + "9": [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "adapter_seq": [ + [ + { + "id": "test", + "single_end": false + }, + "" + ] + ], + "fastqc_raw_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_raw_zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_trim_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_trim_zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "trim_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_read_count": [ + [ + { + "id": "test", + "single_end": false + }, + 26 + ] + ], + "trim_reads_fail": [ + + ], + "trim_reads_merged": [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "umi_log": [ + + ], + "versions": [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T14:19:34.087570563" + }, + "sarscov2 paired-end [fastq] | save_trimmed_fail": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "unspecified" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,6ff32a64c5188b9a9192be1398c262c7", + "test_2.fastp.fastq.gz:md5,db0cb7c9977e94ac2b4b446ebd017a8a" + ] + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,5009a892192f2084c2af69c153d88d6c" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + 162 + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.paired.fail.fastq.gz:md5,409b687c734cedd7a1fec14d316e1366", + "test_1.fail.fastq.gz:md5,4f273cf3159c13f79e8ffae12f5661f6", + "test_2.fail.fastq.gz:md5,f97b9edefb5649aab661fbc9e71fc995" + ] + ] + ], + [ + + ], + [ + + ], + [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:43:06.081852222" + }, + "sarscov2 paired-end [fastq] | skip_fastqc": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "unspecified" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7", + "test_2.fastp.fastq.gz:md5,25cbdca08e2083dbd4f0502de6b62f39" + ] + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,7cf3bff1922b512bcca58439eb2d3679" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + 198 + ] + ], + [ + + ], + [ + + ], + [ + + ], + [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:41:40.619624901" + }, + "sarscov2 paired-end [fastq] | save_trimmed_fail - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + { + "id": "test", + "single_end": false + }, + 1 + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "12": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "13": [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.paired.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_1.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "9": [ + + ], + "adapter_seq": [ + [ + { + "id": "test", + "single_end": false + }, + "" + ] + ], + "fastqc_raw_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_raw_zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_trim_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_trim_zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "trim_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_read_count": [ + [ + { + "id": "test", + "single_end": false + }, + 1 + ] + ], + "trim_reads_fail": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test.paired.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_1.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "trim_reads_merged": [ + + ], + "umi_log": [ + + ], + "versions": [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T14:19:23.614397633" + }, + "sarscov2 paired-end [fastq] | skip_fastqc - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + + ], + "10": [ + [ + { + "id": "test", + "single_end": false + }, + 1 + ] + ], + "11": [ + + ], + "12": [ + + ], + "13": [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce" + ], + "2": [ + + ], + "3": [ + + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + + ], + "9": [ + + ], + "adapter_seq": [ + [ + { + "id": "test", + "single_end": false + }, + "" + ] + ], + "fastqc_raw_html": [ + + ], + "fastqc_raw_zip": [ + + ], + "fastqc_trim_html": [ + + ], + "fastqc_trim_zip": [ + + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "trim_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_read_count": [ + [ + { + "id": "test", + "single_end": false + }, + 1 + ] + ], + "trim_reads_fail": [ + + ], + "trim_reads_merged": [ + + ], + "umi_log": [ + + ], + "versions": [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T14:18:50.988594099" + }, + "sarscov2 paired-end [fastq] | save_merged - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + { + "id": "test", + "single_end": false + }, + 1 + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "12": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "13": [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + + ], + "9": [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "adapter_seq": [ + [ + { + "id": "test", + "single_end": false + }, + "" + ] + ], + "fastqc_raw_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_raw_zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_trim_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_trim_zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "trim_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_read_count": [ + [ + { + "id": "test", + "single_end": false + }, + 1 + ] + ], + "trim_reads_fail": [ + + ], + "trim_reads_merged": [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "umi_log": [ + + ], + "versions": [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T14:19:28.872773752" + }, + "sarscov2 paired-end [fastq] | min_trimmed_reads = 26": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "unspecified" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,54b726a55e992a869fd3fa778afe1672", + "test_2.fastp.fastq.gz:md5,29d3b33b869f7b63417b8ff07bb128ba" + ] + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,8f99097bfa04b629891105b8af9c429f" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + 75 + ] + ], + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,c873bb1ab3fa859dcc47306465e749d5" + ] + ], + [ + + ], + [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:43:23.073649509" + }, + "sarscov2 paired-end [fastq]": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "unspecified" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7", + "test_2.fastp.fastq.gz:md5,25cbdca08e2083dbd4f0502de6b62f39" + ] + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,7cf3bff1922b512bcca58439eb2d3679" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + 198 + ] + ], + [ + + ], + [ + + ], + [ + + ], + [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:41:35.19441141" + }, + "sarscov2 paired-end [fastq] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + { + "id": "test", + "single_end": false + }, + 1 + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "12": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "13": [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + + ], + "9": [ + + ], + "adapter_seq": [ + [ + { + "id": "test", + "single_end": false + }, + "" + ] + ], + "fastqc_raw_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_raw_zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_trim_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_trim_zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "trim_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_read_count": [ + [ + { + "id": "test", + "single_end": false + }, + 1 + ] + ], + "trim_reads_fail": [ + + ], + "trim_reads_merged": [ + + ], + "umi_log": [ + + ], + "versions": [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:43:31.664576438" + }, + "sarscov2 paired-end [fastq] | save_merged": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "unspecified" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,54b726a55e992a869fd3fa778afe1672", + "test_2.fastp.fastq.gz:md5,29d3b33b869f7b63417b8ff07bb128ba" + ] + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,8f99097bfa04b629891105b8af9c429f" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + 75 + ] + ], + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.merged.fastq.gz:md5,c873bb1ab3fa859dcc47306465e749d5" + ] + ], + [ + + ], + [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T13:43:16.218890529" + }, + "sarscov2 paired-end [fastq] | with_umi - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + { + "id": "test", + "single_end": true + }, + 1 + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": true + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "12": [ + [ + { + "id": "test", + "single_end": true + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "13": [ + "versions.yml:md5,01f264f78de3c6d893c449cc6d3cd721", + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.umi_extract.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": true + }, + "" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + + ], + "9": [ + + ], + "adapter_seq": [ + [ + { + "id": "test", + "single_end": true + }, + "" + ] + ], + "fastqc_raw_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_raw_zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_trim_html": [ + [ + { + "id": "test", + "single_end": true + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_trim_zip": [ + [ + { + "id": "test", + "single_end": true + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "trim_html": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_json": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_log": [ + [ + { + "id": "test", + "single_end": true + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_read_count": [ + [ + { + "id": "test", + "single_end": true + }, + 1 + ] + ], + "trim_reads_fail": [ + + ], + "trim_reads_merged": [ + + ], + "umi_log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.umi_extract.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,01f264f78de3c6d893c449cc6d3cd721", + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T14:19:00.760820449" + }, + "sarscov2 paired-end [fastq] | skip_umi_extract - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + { + "id": "test", + "single_end": false + }, + 1 + ] + ], + "11": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "12": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "13": [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + + ], + "9": [ + + ], + "adapter_seq": [ + [ + { + "id": "test", + "single_end": false + }, + "" + ] + ], + "fastqc_raw_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_raw_zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_trim_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "fastqc_trim_zip": [ + [ + { + "id": "test", + "single_end": false + }, + "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ] + ], + "trim_html": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_json": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_log": [ + [ + { + "id": "test", + "single_end": false + }, + "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "trim_read_count": [ + [ + { + "id": "test", + "single_end": false + }, + 1 + ] + ], + "trim_reads_fail": [ + + ], + "trim_reads_merged": [ + + ], + "umi_log": [ + + ], + "versions": [ + "versions.yml:md5,20ceba9ff7bc15c1fbe2b369022178ce", + "versions.yml:md5,c50aa59475ab901bc6f9a2cf7b1a14e0", + "versions.yml:md5,f3dcaae948e8eed92b4a5557b4c6668e" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.5" + }, + "timestamp": "2025-03-31T14:19:05.849804123" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_fastqc_umitools_fastp/tests/nextflow.config b/subworkflows/nf-core/fastq_fastqc_umitools_fastp/tests/nextflow.config new file mode 100644 index 000000000..428b0d37c --- /dev/null +++ b/subworkflows/nf-core/fastq_fastqc_umitools_fastp/tests/nextflow.config @@ -0,0 +1,16 @@ +process { + + withName: UMITOOLS_EXTRACT { + ext.args = '--bc-pattern="NNNN" --bc-pattern2="NNNN"' + } + + withName: UMICOLLAPSE { + ext.prefix = { "${meta.id}.dedup" } + } + + // Make filtering more aggressive to make more reads fail + withName: FASTP { + ext.args = params.fastp_args + } + +} diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf index ac31f28f6..d6e593e85 100644 --- a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf @@ -2,18 +2,13 @@ // Subworkflow with functionality that may be useful for any Nextflow pipeline // -import org.yaml.snakeyaml.Yaml -import groovy.json.JsonOutput -import nextflow.extension.FilesEx - /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SUBWORKFLOW DEFINITION -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ workflow UTILS_NEXTFLOW_PIPELINE { - take: print_version // boolean: print version dump_parameters // boolean: dump parameters @@ -26,7 +21,7 @@ workflow UTILS_NEXTFLOW_PIPELINE { // Print workflow version and exit on --version // if (print_version) { - log.info "${workflow.manifest.name} ${getWorkflowVersion()}" + log.info("${workflow.manifest.name} ${getWorkflowVersion()}") System.exit(0) } @@ -49,16 +44,16 @@ workflow UTILS_NEXTFLOW_PIPELINE { } /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FUNCTIONS -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ // // Generate version string // def getWorkflowVersion() { - String version_string = "" + def version_string = "" as String if (workflow.manifest.version) { def prefix_v = workflow.manifest.version[0] != 'v' ? 'v' : '' version_string += "${prefix_v}${workflow.manifest.version}" @@ -76,13 +71,13 @@ def getWorkflowVersion() { // Dump pipeline parameters to a JSON file // def dumpParametersToJSON(outdir) { - def timestamp = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss') - def filename = "params_${timestamp}.json" - def temp_pf = new File(workflow.launchDir.toString(), ".${filename}") - def jsonStr = JsonOutput.toJson(params) - temp_pf.text = JsonOutput.prettyPrint(jsonStr) + def timestamp = new java.util.Date().format('yyyy-MM-dd_HH-mm-ss') + def filename = "params_${timestamp}.json" + def temp_pf = new File(workflow.launchDir.toString(), ".${filename}") + def jsonStr = groovy.json.JsonOutput.toJson(params) + temp_pf.text = groovy.json.JsonOutput.prettyPrint(jsonStr) - FilesEx.copyTo(temp_pf.toPath(), "${outdir}/pipeline_info/params_${timestamp}.json") + nextflow.extension.FilesEx.copyTo(temp_pf.toPath(), "${outdir}/pipeline_info/params_${timestamp}.json") temp_pf.delete() } @@ -90,37 +85,42 @@ def dumpParametersToJSON(outdir) { // When running with -profile conda, warn if channels have not been set-up appropriately // def checkCondaChannels() { - Yaml parser = new Yaml() + def parser = new org.yaml.snakeyaml.Yaml() def channels = [] try { def config = parser.load("conda config --show channels".execute().text) channels = config.channels - } catch(NullPointerException | IOException e) { - log.warn "Could not verify conda channel configuration." - return + } + 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 } // Check that all channels are present // This channel list is ordered by required channel priority. - def required_channels_in_order = ['conda-forge', 'bioconda', 'defaults'] + def required_channels_in_order = ['conda-forge', 'bioconda'] def channels_missing = ((required_channels_in_order as Set) - (channels as Set)) as Boolean // Check that they are in the right order - def channel_priority_violation = false - def n = required_channels_in_order.size() - for (int i = 0; i < n - 1; i++) { - channel_priority_violation |= !(channels.indexOf(required_channels_in_order[i]) < channels.indexOf(required_channels_in_order[i+1])) - } + def channel_priority_violation = required_channels_in_order != channels.findAll { ch -> ch in required_channels_in_order } if (channels_missing | channel_priority_violation) { - log.warn "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + - " There is a problem with your Conda configuration!\n\n" + - " You will need to set-up the conda-forge and bioconda channels correctly.\n" + - " Please refer to https://bioconda.github.io/\n" + - " The observed channel order is \n" + - " ${channels}\n" + - " but the following channel order is required:\n" + - " ${required_channels_in_order}\n" + - "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + log.warn """\ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + There is a problem with your Conda configuration! + You will need to set-up the conda-forge and bioconda channels correctly. + Please refer to https://bioconda.github.io/ + The observed channel order is + ${channels} + but the following channel order is required: + ${required_channels_in_order} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + """.stripIndent(true) } } diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.workflow.nf.test b/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.workflow.nf.test index ca964ce8e..02dbf094c 100644 --- a/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.workflow.nf.test +++ b/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.workflow.nf.test @@ -52,10 +52,12 @@ nextflow_workflow { } then { - assertAll( - { assert workflow.success }, - { assert workflow.stdout.contains("nextflow_workflow v9.9.9") } - ) + expect { + with(workflow) { + assert success + assert "nextflow_workflow v9.9.9" in stdout + } + } } } diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config b/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config index d0a926bf6..a09572e5b 100644 --- a/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config +++ b/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config @@ -3,7 +3,7 @@ manifest { author = """nf-core""" homePage = 'https://127.0.0.1' description = """Dummy pipeline""" - nextflowVersion = '!>=23.04.0' + nextflowVersion = '!>=23.04.0' version = '9.9.9' doi = 'https://doi.org/10.5281/zenodo.5070524' } diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml b/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml deleted file mode 100644 index f84761125..000000000 --- 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 a8b55d6fe..bfd258760 100644 --- a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf +++ b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf @@ -2,17 +2,13 @@ // Subworkflow with utility functions specific to the nf-core pipeline template // -import org.yaml.snakeyaml.Yaml -import nextflow.extension.FilesEx - /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SUBWORKFLOW DEFINITION -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ workflow UTILS_NFCORE_PIPELINE { - take: nextflow_cli_args @@ -25,23 +21,20 @@ workflow UTILS_NFCORE_PIPELINE { } /* -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FUNCTIONS -======================================================================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ // // Warn if a -profile or Nextflow config has not been provided to run the pipeline // def checkConfigProvided() { - valid_config = true + def valid_config = true as Boolean if (workflow.profile == 'standard' && workflow.configFiles.size() <= 1) { - log.warn "[$workflow.manifest.name] You are attempting to run the pipeline without any custom configuration!\n\n" + - "This will be dependent on your local compute environment but can be achieved via one or more of the following:\n" + - " (1) Using an existing pipeline profile e.g. `-profile docker` or `-profile singularity`\n" + - " (2) Using an existing nf-core/configs for your Institution e.g. `-profile crick` or `-profile uppmax`\n" + - " (3) Using your own local custom config e.g. `-c /path/to/your/custom.config`\n\n" + - "Please refer to the quick start section and usage docs for the pipeline.\n " + log.warn( + "[${workflow.manifest.name}] You are attempting to run the pipeline without any custom configuration!\n\n" + "This will be dependent on your local compute environment but can be achieved via one or more of the following:\n" + " (1) Using an existing pipeline profile e.g. `-profile docker` or `-profile singularity`\n" + " (2) Using an existing nf-core/configs for your Institution e.g. `-profile crick` or `-profile uppmax`\n" + " (3) Using your own local custom config e.g. `-c /path/to/your/custom.config`\n\n" + "Please refer to the quick start section and usage docs for the pipeline.\n " + ) valid_config = false } return valid_config @@ -52,33 +45,22 @@ def checkConfigProvided() { // def checkProfileProvided(nextflow_cli_args) { if (workflow.profile.endsWith(',')) { - error "The `-profile` option cannot end with a trailing comma, please remove it and re-run the pipeline!\n" + - "HINT: A common mistake is to provide multiple values separated by spaces e.g. `-profile test, docker`.\n" + error( + "The `-profile` option cannot end with a trailing comma, please remove it and re-run the pipeline!\n" + "HINT: A common mistake is to provide multiple values separated by spaces e.g. `-profile test, docker`.\n" + ) } if (nextflow_cli_args[0]) { - log.warn "nf-core pipelines do not accept positional arguments. The positional argument `${nextflow_cli_args[0]}` has been detected.\n" + - "HINT: A common mistake is to provide multiple values separated by spaces e.g. `-profile test, docker`.\n" + log.warn( + "nf-core pipelines do not accept positional arguments. The positional argument `${nextflow_cli_args[0]}` has been detected.\n" + "HINT: A common mistake is to provide multiple values separated by spaces e.g. `-profile test, docker`.\n" + ) } } -// -// Citation string for pipeline -// -def workflowCitation() { - return "If you use ${workflow.manifest.name} for your analysis please cite:\n\n" + - "* The pipeline\n" + - " ${workflow.manifest.doi}\n\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 // def getWorkflowVersion() { - String version_string = "" + def version_string = "" as String if (workflow.manifest.version) { def prefix_v = workflow.manifest.version[0] != 'v' ? 'v' : '' version_string += "${prefix_v}${workflow.manifest.version}" @@ -96,8 +78,8 @@ def getWorkflowVersion() { // Get software versions for pipeline // def processVersionsFromYAML(yaml_file) { - Yaml yaml = new Yaml() - versions = yaml.load(yaml_file).collectEntries { k, v -> [ k.tokenize(':')[-1], v ] } + def yaml = new org.yaml.snakeyaml.Yaml() + def versions = yaml.load(yaml_file).collectEntries { k, v -> [k.tokenize(':')[-1], v] } return yaml.dumpAsMap(versions).trim() } @@ -107,8 +89,8 @@ def processVersionsFromYAML(yaml_file) { def workflowVersionToYAML() { return """ Workflow: - $workflow.manifest.name: ${getWorkflowVersion()} - Nextflow: $workflow.nextflow.version + ${workflow.manifest.name}: ${getWorkflowVersion()} + Nextflow: ${workflow.nextflow.version} """.stripIndent().trim() } @@ -116,11 +98,7 @@ def workflowVersionToYAML() { // Get channel of software versions used in pipeline in YAML format // def softwareVersionsToYAML(ch_versions) { - return ch_versions - .unique() - .map { processVersionsFromYAML(it) } - .unique() - .mix(Channel.of(workflowVersionToYAML())) + return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(Channel.of(workflowVersionToYAML())) } // @@ -128,61 +106,40 @@ def softwareVersionsToYAML(ch_versions) { // def paramsSummaryMultiqc(summary_params) { def summary_section = '' - for (group in summary_params.keySet()) { - def group_params = summary_params.get(group) // This gets the parameters of that particular group - if (group_params) { - summary_section += "

    $group

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

    ${group}

    \n" + summary_section += "
    \n" + group_params + .keySet() + .sort() + .each { param -> + summary_section += "
    ${param}
    ${group_params.get(param) ?: 'N/A'}
    \n" + } + summary_section += "
    \n" } - summary_section += "
    \n" } - } - String yaml_file_text = "id: '${workflow.manifest.name.replace('/','-')}-summary'\n" - yaml_file_text += "description: ' - this information is collected when the pipeline is started.'\n" - yaml_file_text += "section_name: '${workflow.manifest.name} Workflow Summary'\n" - yaml_file_text += "section_href: 'https://github.com/${workflow.manifest.name}'\n" - yaml_file_text += "plot_type: 'html'\n" - yaml_file_text += "data: |\n" - yaml_file_text += "${summary_section}" + def yaml_file_text = "id: '${workflow.manifest.name.replace('/', '-')}-summary'\n" as String + yaml_file_text += "description: ' - this information is collected when the pipeline is started.'\n" + yaml_file_text += "section_name: '${workflow.manifest.name} Workflow Summary'\n" + yaml_file_text += "section_href: 'https://github.com/${workflow.manifest.name}'\n" + yaml_file_text += "plot_type: 'html'\n" + yaml_file_text += "data: |\n" + yaml_file_text += "${summary_section}" return yaml_file_text } -// -// nf-core logo -// -def nfCoreLogo(monochrome_logs=true) { - Map colors = logColours(monochrome_logs) - 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) { - Map colors = logColours(monochrome_logs) - return "-${colors.dim}----------------------------------------------------${colors.reset}-" -} - // // ANSII colours used for terminal logging // def logColours(monochrome_logs=true) { - Map colorcodes = [:] + def colorcodes = [:] as Map // Reset / Meta colorcodes['reset'] = monochrome_logs ? '' : "\033[0m" @@ -194,79 +151,76 @@ def logColours(monochrome_logs=true) { colorcodes['hidden'] = monochrome_logs ? '' : "\033[8m" // Regular Colors - colorcodes['black'] = monochrome_logs ? '' : "\033[0;30m" - colorcodes['red'] = monochrome_logs ? '' : "\033[0;31m" - colorcodes['green'] = monochrome_logs ? '' : "\033[0;32m" - colorcodes['yellow'] = monochrome_logs ? '' : "\033[0;33m" - colorcodes['blue'] = monochrome_logs ? '' : "\033[0;34m" - colorcodes['purple'] = monochrome_logs ? '' : "\033[0;35m" - colorcodes['cyan'] = monochrome_logs ? '' : "\033[0;36m" - colorcodes['white'] = monochrome_logs ? '' : "\033[0;37m" + colorcodes['black'] = monochrome_logs ? '' : "\033[0;30m" + colorcodes['red'] = monochrome_logs ? '' : "\033[0;31m" + colorcodes['green'] = monochrome_logs ? '' : "\033[0;32m" + colorcodes['yellow'] = monochrome_logs ? '' : "\033[0;33m" + colorcodes['blue'] = monochrome_logs ? '' : "\033[0;34m" + colorcodes['purple'] = monochrome_logs ? '' : "\033[0;35m" + colorcodes['cyan'] = monochrome_logs ? '' : "\033[0;36m" + colorcodes['white'] = monochrome_logs ? '' : "\033[0;37m" // Bold - colorcodes['bblack'] = monochrome_logs ? '' : "\033[1;30m" - colorcodes['bred'] = monochrome_logs ? '' : "\033[1;31m" - colorcodes['bgreen'] = monochrome_logs ? '' : "\033[1;32m" - colorcodes['byellow'] = monochrome_logs ? '' : "\033[1;33m" - colorcodes['bblue'] = monochrome_logs ? '' : "\033[1;34m" - colorcodes['bpurple'] = monochrome_logs ? '' : "\033[1;35m" - colorcodes['bcyan'] = monochrome_logs ? '' : "\033[1;36m" - colorcodes['bwhite'] = monochrome_logs ? '' : "\033[1;37m" + colorcodes['bblack'] = monochrome_logs ? '' : "\033[1;30m" + colorcodes['bred'] = monochrome_logs ? '' : "\033[1;31m" + colorcodes['bgreen'] = monochrome_logs ? '' : "\033[1;32m" + colorcodes['byellow'] = monochrome_logs ? '' : "\033[1;33m" + colorcodes['bblue'] = monochrome_logs ? '' : "\033[1;34m" + colorcodes['bpurple'] = monochrome_logs ? '' : "\033[1;35m" + colorcodes['bcyan'] = monochrome_logs ? '' : "\033[1;36m" + colorcodes['bwhite'] = monochrome_logs ? '' : "\033[1;37m" // Underline - colorcodes['ublack'] = monochrome_logs ? '' : "\033[4;30m" - colorcodes['ured'] = monochrome_logs ? '' : "\033[4;31m" - colorcodes['ugreen'] = monochrome_logs ? '' : "\033[4;32m" - colorcodes['uyellow'] = monochrome_logs ? '' : "\033[4;33m" - colorcodes['ublue'] = monochrome_logs ? '' : "\033[4;34m" - colorcodes['upurple'] = monochrome_logs ? '' : "\033[4;35m" - colorcodes['ucyan'] = monochrome_logs ? '' : "\033[4;36m" - colorcodes['uwhite'] = monochrome_logs ? '' : "\033[4;37m" + colorcodes['ublack'] = monochrome_logs ? '' : "\033[4;30m" + colorcodes['ured'] = monochrome_logs ? '' : "\033[4;31m" + colorcodes['ugreen'] = monochrome_logs ? '' : "\033[4;32m" + colorcodes['uyellow'] = monochrome_logs ? '' : "\033[4;33m" + colorcodes['ublue'] = monochrome_logs ? '' : "\033[4;34m" + colorcodes['upurple'] = monochrome_logs ? '' : "\033[4;35m" + colorcodes['ucyan'] = monochrome_logs ? '' : "\033[4;36m" + colorcodes['uwhite'] = monochrome_logs ? '' : "\033[4;37m" // High Intensity - colorcodes['iblack'] = monochrome_logs ? '' : "\033[0;90m" - colorcodes['ired'] = monochrome_logs ? '' : "\033[0;91m" - colorcodes['igreen'] = monochrome_logs ? '' : "\033[0;92m" - colorcodes['iyellow'] = monochrome_logs ? '' : "\033[0;93m" - colorcodes['iblue'] = monochrome_logs ? '' : "\033[0;94m" - colorcodes['ipurple'] = monochrome_logs ? '' : "\033[0;95m" - colorcodes['icyan'] = monochrome_logs ? '' : "\033[0;96m" - colorcodes['iwhite'] = monochrome_logs ? '' : "\033[0;97m" + colorcodes['iblack'] = monochrome_logs ? '' : "\033[0;90m" + colorcodes['ired'] = monochrome_logs ? '' : "\033[0;91m" + colorcodes['igreen'] = monochrome_logs ? '' : "\033[0;92m" + colorcodes['iyellow'] = monochrome_logs ? '' : "\033[0;93m" + colorcodes['iblue'] = monochrome_logs ? '' : "\033[0;94m" + colorcodes['ipurple'] = monochrome_logs ? '' : "\033[0;95m" + colorcodes['icyan'] = monochrome_logs ? '' : "\033[0;96m" + colorcodes['iwhite'] = monochrome_logs ? '' : "\033[0;97m" // Bold High Intensity - colorcodes['biblack'] = monochrome_logs ? '' : "\033[1;90m" - colorcodes['bired'] = monochrome_logs ? '' : "\033[1;91m" - colorcodes['bigreen'] = monochrome_logs ? '' : "\033[1;92m" - colorcodes['biyellow'] = monochrome_logs ? '' : "\033[1;93m" - colorcodes['biblue'] = monochrome_logs ? '' : "\033[1;94m" - colorcodes['bipurple'] = monochrome_logs ? '' : "\033[1;95m" - colorcodes['bicyan'] = monochrome_logs ? '' : "\033[1;96m" - colorcodes['biwhite'] = monochrome_logs ? '' : "\033[1;97m" + colorcodes['biblack'] = monochrome_logs ? '' : "\033[1;90m" + colorcodes['bired'] = monochrome_logs ? '' : "\033[1;91m" + colorcodes['bigreen'] = monochrome_logs ? '' : "\033[1;92m" + colorcodes['biyellow'] = monochrome_logs ? '' : "\033[1;93m" + colorcodes['biblue'] = monochrome_logs ? '' : "\033[1;94m" + colorcodes['bipurple'] = monochrome_logs ? '' : "\033[1;95m" + colorcodes['bicyan'] = monochrome_logs ? '' : "\033[1;96m" + colorcodes['biwhite'] = monochrome_logs ? '' : "\033[1;97m" return colorcodes } -// -// 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] - } - } - } catch (all) { - if (multiqc_report) { - log.warn "[$workflow.manifest.name] Could not attach MultiQC report to summary email" +// 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 } - return mqc_report } // @@ -275,26 +229,35 @@ def attachMultiqcReport(multiqc_report) { def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdir, monochrome_logs=true, multiqc_report=null) { // Set up the e-mail variables - def subject = "[$workflow.manifest.name] Successful: $workflow.runName" + def subject = "[${workflow.manifest.name}] Successful: ${workflow.runName}" if (!workflow.success) { - subject = "[$workflow.manifest.name] FAILED: $workflow.runName" + subject = "[${workflow.manifest.name}] FAILED: ${workflow.runName}" } def summary = [:] - for (group in summary_params.keySet()) { - summary << summary_params[group] - } + summary_params + .keySet() + .sort() + .each { group -> + summary << summary_params[group] + } def misc_fields = [:] misc_fields['Date Started'] = workflow.start misc_fields['Date Completed'] = workflow.complete misc_fields['Pipeline script file path'] = workflow.scriptFile misc_fields['Pipeline script hash ID'] = workflow.scriptId - if (workflow.repository) misc_fields['Pipeline repository Git URL'] = workflow.repository - if (workflow.commitId) misc_fields['Pipeline repository Git Commit'] = workflow.commitId - if (workflow.revision) misc_fields['Pipeline Git branch/tag'] = workflow.revision - misc_fields['Nextflow Version'] = workflow.nextflow.version - misc_fields['Nextflow Build'] = workflow.nextflow.build + if (workflow.repository) { + misc_fields['Pipeline repository Git URL'] = workflow.repository + } + if (workflow.commitId) { + misc_fields['Pipeline repository Git Commit'] = workflow.commitId + } + if (workflow.revision) { + misc_fields['Pipeline Git branch/tag'] = workflow.revision + } + misc_fields['Nextflow Version'] = workflow.nextflow.version + misc_fields['Nextflow Build'] = workflow.nextflow.build misc_fields['Nextflow Compile Timestamp'] = workflow.nextflow.timestamp def email_fields = [:] @@ -311,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 @@ -331,40 +294,45 @@ 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 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 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) def sendmail_html = sendmail_template.toString() // Send the HTML e-mail - Map colors = logColours(monochrome_logs) + def colors = logColours(monochrome_logs) as Map if (email_address) { try { - if (plaintext_email) { throw GroovyException('Send plaintext e-mail, not HTML') } + if (plaintext_email) { + new org.codehaus.groovy.GroovyException('Send plaintext e-mail, not HTML') + } // Try to send HTML e-mail using sendmail def sendmail_tf = new File(workflow.launchDir.toString(), ".sendmail_tmp.html") sendmail_tf.withWriter { w -> w << sendmail_html } - [ 'sendmail', '-t' ].execute() << sendmail_html - log.info "-${colors.purple}[$workflow.manifest.name]${colors.green} Sent summary e-mail to $email_address (sendmail)-" - } catch (all) { + ['sendmail', '-t'].execute() << sendmail_html + log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Sent summary e-mail to ${email_address} (sendmail)-") + } + catch (Exception 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 ] + def mail_cmd = ['mail', '-s', subject, '--content-type=text/html', email_address] mail_cmd.execute() << email_html - log.info "-${colors.purple}[$workflow.manifest.name]${colors.green} Sent summary e-mail to $email_address (mail)-" + log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Sent summary e-mail to ${email_address} (mail)-") } } // Write summary e-mail HTML to a file def output_hf = new File(workflow.launchDir.toString(), ".pipeline_report.html") output_hf.withWriter { w -> w << email_html } - FilesEx.copyTo(output_hf.toPath(), "${outdir}/pipeline_info/pipeline_report.html"); + nextflow.extension.FilesEx.copyTo(output_hf.toPath(), "${outdir}/pipeline_info/pipeline_report.html") output_hf.delete() // Write summary e-mail TXT to a file def output_tf = new File(workflow.launchDir.toString(), ".pipeline_report.txt") output_tf.withWriter { w -> w << email_txt } - FilesEx.copyTo(output_tf.toPath(), "${outdir}/pipeline_info/pipeline_report.txt"); + nextflow.extension.FilesEx.copyTo(output_tf.toPath(), "${outdir}/pipeline_info/pipeline_report.txt") output_tf.delete() } @@ -372,15 +340,17 @@ def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdi // Print pipeline summary on completion // def completionSummary(monochrome_logs=true) { - Map colors = logColours(monochrome_logs) + def colors = logColours(monochrome_logs) as Map if (workflow.success) { if (workflow.stats.ignoredCount == 0) { - log.info "-${colors.purple}[$workflow.manifest.name]${colors.green} Pipeline completed successfully${colors.reset}-" - } else { - log.info "-${colors.purple}[$workflow.manifest.name]${colors.yellow} Pipeline completed successfully, but with errored process(es) ${colors.reset}-" + log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Pipeline completed successfully${colors.reset}-") } - } else { - log.info "-${colors.purple}[$workflow.manifest.name]${colors.red} Pipeline completed with errors${colors.reset}-" + else { + log.info("-${colors.purple}[${workflow.manifest.name}]${colors.yellow} Pipeline completed successfully, but with errored process(es) ${colors.reset}-") + } + } + else { + log.info("-${colors.purple}[${workflow.manifest.name}]${colors.red} Pipeline completed with errors${colors.reset}-") } } @@ -389,21 +359,30 @@ def completionSummary(monochrome_logs=true) { // def imNotification(summary_params, hook_url) { def summary = [:] - for (group in summary_params.keySet()) { - summary << summary_params[group] - } + summary_params + .keySet() + .sort() + .each { group -> + summary << summary_params[group] + } def misc_fields = [:] - misc_fields['start'] = workflow.start - misc_fields['complete'] = workflow.complete - misc_fields['scriptfile'] = workflow.scriptFile - misc_fields['scriptid'] = workflow.scriptId - if (workflow.repository) misc_fields['repository'] = workflow.repository - if (workflow.commitId) misc_fields['commitid'] = workflow.commitId - if (workflow.revision) misc_fields['revision'] = workflow.revision - misc_fields['nxf_version'] = workflow.nextflow.version - misc_fields['nxf_build'] = workflow.nextflow.build - misc_fields['nxf_timestamp'] = workflow.nextflow.timestamp + misc_fields['start'] = workflow.start + misc_fields['complete'] = workflow.complete + misc_fields['scriptfile'] = workflow.scriptFile + misc_fields['scriptid'] = workflow.scriptId + if (workflow.repository) { + misc_fields['repository'] = workflow.repository + } + if (workflow.commitId) { + misc_fields['commitid'] = workflow.commitId + } + if (workflow.revision) { + misc_fields['revision'] = workflow.revision + } + misc_fields['nxf_version'] = workflow.nextflow.version + misc_fields['nxf_build'] = workflow.nextflow.build + misc_fields['nxf_timestamp'] = workflow.nextflow.timestamp def msg_fields = [:] msg_fields['version'] = getWorkflowVersion() @@ -428,13 +407,13 @@ def imNotification(summary_params, hook_url) { def json_message = json_template.toString() // POST - def post = new URL(hook_url).openConnection(); + def post = new URL(hook_url).openConnection() post.setRequestMethod("POST") post.setDoOutput(true) post.setRequestProperty("Content-Type", "application/json") - post.getOutputStream().write(json_message.getBytes("UTF-8")); - def postRC = post.getResponseCode(); - if (! postRC.equals(200)) { - log.warn(post.getErrorStream().getText()); + post.getOutputStream().write(json_message.getBytes("UTF-8")) + def postRC = post.getResponseCode() + if (!postRC.equals(200)) { + log.warn(post.getErrorStream().getText()) } } 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 1dc317f8f..f117040cb 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 1037232c9..02c670141 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/tags.yml b/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml deleted file mode 100644 index ac8523c9a..000000000 --- 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 new file mode 100644 index 000000000..4994303ea --- /dev/null +++ b/subworkflows/nf-core/utils_nfschema_plugin/main.nf @@ -0,0 +1,46 @@ +// +// Subworkflow that uses the nf-schema plugin to validate parameters and render the parameter summary +// + +include { paramsSummaryLog } from 'plugin/nf-schema' +include { validateParameters } from 'plugin/nf-schema' + +workflow UTILS_NFSCHEMA_PLUGIN { + + take: + input_workflow // workflow: the workflow object used by nf-schema to get metadata from the workflow + validate_params // boolean: validate the parameters + parameters_schema // string: path to the parameters JSON schema. + // this has to be the same as the schema given to `validation.parametersSchema` + // when this input is empty it will automatically use the configured schema or + // "${projectDir}/nextflow_schema.json" as default. This input should not be empty + // for meta pipelines + + main: + + // + // Print parameter summary to stdout. This will display the parameters + // that differ from the default given in the JSON schema + // + if(parameters_schema) { + log.info paramsSummaryLog(input_workflow, parameters_schema:parameters_schema) + } else { + log.info paramsSummaryLog(input_workflow) + } + + // + // Validate the parameters using nextflow_schema.json or the schema + // given via the validation.parametersSchema configuration option + // + if(validate_params) { + if(parameters_schema) { + validateParameters(parameters_schema:parameters_schema) + } else { + validateParameters() + } + } + + emit: + dummy_emit = true +} + diff --git a/subworkflows/nf-core/utils_nfschema_plugin/meta.yml b/subworkflows/nf-core/utils_nfschema_plugin/meta.yml new file mode 100644 index 000000000..f7d9f0288 --- /dev/null +++ b/subworkflows/nf-core/utils_nfschema_plugin/meta.yml @@ -0,0 +1,35 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: "utils_nfschema_plugin" +description: Run nf-schema to validate parameters and create a summary of changed parameters +keywords: + - validation + - JSON schema + - plugin + - parameters + - summary +components: [] +input: + - input_workflow: + type: object + description: | + The workflow object of the used pipeline. + This object contains meta data used to create the params summary log + - validate_params: + type: boolean + description: Validate the parameters and error if invalid. + - parameters_schema: + type: string + description: | + Path to the parameters JSON schema. + This has to be the same as the schema given to the `validation.parametersSchema` config + option. When this input is empty it will automatically use the configured schema or + "${projectDir}/nextflow_schema.json" as default. The schema should not be given in this way + for meta pipelines. +output: + - dummy_emit: + type: boolean + description: Dummy emit to make nf-core subworkflows lint happy +authors: + - "@nvnieuwk" +maintainers: + - "@nvnieuwk" diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test b/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test new file mode 100644 index 000000000..8fb301648 --- /dev/null +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test @@ -0,0 +1,117 @@ +nextflow_workflow { + + name "Test Subworkflow UTILS_NFSCHEMA_PLUGIN" + script "../main.nf" + workflow "UTILS_NFSCHEMA_PLUGIN" + + tag "subworkflows" + tag "subworkflows_nfcore" + tag "subworkflows/utils_nfschema_plugin" + tag "plugin/nf-schema" + + config "./nextflow.config" + + test("Should run nothing") { + + when { + + params { + test_data = '' + } + + workflow { + """ + validate_params = false + input[0] = workflow + input[1] = validate_params + input[2] = "" + """ + } + } + + then { + assertAll( + { assert workflow.success } + ) + } + } + + test("Should validate params") { + + when { + + params { + test_data = '' + outdir = null + } + + workflow { + """ + validate_params = true + input[0] = workflow + input[1] = validate_params + input[2] = "" + """ + } + } + + then { + assertAll( + { assert workflow.failed }, + { assert workflow.stdout.any { it.contains('ERROR ~ Validation of pipeline parameters failed!') } } + ) + } + } + + test("Should run nothing - custom schema") { + + when { + + params { + test_data = '' + } + + workflow { + """ + validate_params = false + input[0] = workflow + input[1] = validate_params + input[2] = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json" + """ + } + } + + then { + assertAll( + { assert workflow.success } + ) + } + } + + test("Should validate params - custom schema") { + + when { + + params { + test_data = '' + outdir = 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" + """ + } + } + + then { + assertAll( + { assert workflow.failed }, + { assert workflow.stdout.any { it.contains('ERROR ~ Validation of pipeline parameters failed!') } } + ) + } + } +} diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config new file mode 100644 index 000000000..443e828cf --- /dev/null +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config @@ -0,0 +1,8 @@ +plugins { + id "nf-schema@2.4.2" +} + +validation { + parametersSchema = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json" + monochromeLogs = true +} diff --git a/subworkflows/nf-core/utils_nfvalidation_plugin/tests/nextflow_schema.json b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json similarity index 95% rename from subworkflows/nf-core/utils_nfvalidation_plugin/tests/nextflow_schema.json rename to subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json index 7626c1c93..331e0d2f4 100644 --- a/subworkflows/nf-core/utils_nfvalidation_plugin/tests/nextflow_schema.json +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json @@ -1,10 +1,10 @@ { - "$schema": "http://json-schema.org/draft-07/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://raw.githubusercontent.com/./master/nextflow_schema.json", "title": ". pipeline parameters", "description": "", "type": "object", - "definitions": { + "$defs": { "input_output_options": { "title": "Input/output options", "type": "object", @@ -87,10 +87,10 @@ }, "allOf": [ { - "$ref": "#/definitions/input_output_options" + "$ref": "#/$defs/input_output_options" }, { - "$ref": "#/definitions/generic_options" + "$ref": "#/$defs/generic_options" } ] } diff --git a/subworkflows/nf-core/utils_nfvalidation_plugin/main.nf b/subworkflows/nf-core/utils_nfvalidation_plugin/main.nf deleted file mode 100644 index 2585b65d1..000000000 --- a/subworkflows/nf-core/utils_nfvalidation_plugin/main.nf +++ /dev/null @@ -1,62 +0,0 @@ -// -// Subworkflow that uses the nf-validation plugin to render help text and parameter summary -// - -/* -======================================================================================== - IMPORT NF-VALIDATION PLUGIN -======================================================================================== -*/ - -include { paramsHelp } from 'plugin/nf-validation' -include { paramsSummaryLog } from 'plugin/nf-validation' -include { validateParameters } from 'plugin/nf-validation' - -/* -======================================================================================== - SUBWORKFLOW DEFINITION -======================================================================================== -*/ - -workflow UTILS_NFVALIDATION_PLUGIN { - - take: - print_help // boolean: print help - workflow_command // string: default commmand used to run pipeline - pre_help_text // string: string to be printed before help text and summary log - post_help_text // string: string to be printed after help text and summary log - validate_params // boolean: validate parameters - schema_filename // path: JSON schema file, null to use default value - - main: - - log.debug "Using schema file: ${schema_filename}" - - // Default values for strings - pre_help_text = pre_help_text ?: '' - post_help_text = post_help_text ?: '' - workflow_command = workflow_command ?: '' - - // - // Print help message if needed - // - if (print_help) { - log.info pre_help_text + paramsHelp(workflow_command, parameters_schema: schema_filename) + post_help_text - System.exit(0) - } - - // - // Print parameter summary to stdout - // - log.info pre_help_text + paramsSummaryLog(workflow, parameters_schema: schema_filename) + post_help_text - - // - // Validate parameters relative to the parameter JSON schema - // - if (validate_params){ - validateParameters(parameters_schema: schema_filename) - } - - emit: - dummy_emit = true -} diff --git a/subworkflows/nf-core/utils_nfvalidation_plugin/meta.yml b/subworkflows/nf-core/utils_nfvalidation_plugin/meta.yml deleted file mode 100644 index 3d4a6b04f..000000000 --- a/subworkflows/nf-core/utils_nfvalidation_plugin/meta.yml +++ /dev/null @@ -1,44 +0,0 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json -name: "UTILS_NFVALIDATION_PLUGIN" -description: Use nf-validation to initiate and validate a pipeline -keywords: - - utility - - pipeline - - initialise - - validation -components: [] -input: - - print_help: - type: boolean - description: | - Print help message and exit - - workflow_command: - type: string - description: | - The command to run the workflow e.g. "nextflow run main.nf" - - pre_help_text: - type: string - description: | - Text to print before the help message - - post_help_text: - type: string - description: | - Text to print after the help message - - validate_params: - type: boolean - description: | - Validate the parameters and error if invalid. - - schema_filename: - type: string - description: | - The filename of the schema to validate against. -output: - - dummy_emit: - type: boolean - description: | - Dummy emit to make nf-core subworkflows lint happy -authors: - - "@adamrtalbot" -maintainers: - - "@adamrtalbot" - - "@maxulysse" diff --git a/subworkflows/nf-core/utils_nfvalidation_plugin/tests/main.nf.test b/subworkflows/nf-core/utils_nfvalidation_plugin/tests/main.nf.test deleted file mode 100644 index 5784a33f2..000000000 --- a/subworkflows/nf-core/utils_nfvalidation_plugin/tests/main.nf.test +++ /dev/null @@ -1,200 +0,0 @@ -nextflow_workflow { - - name "Test Workflow UTILS_NFVALIDATION_PLUGIN" - script "../main.nf" - workflow "UTILS_NFVALIDATION_PLUGIN" - tag "subworkflows" - tag "subworkflows_nfcore" - tag "plugin/nf-validation" - tag "'plugin/nf-validation'" - tag "utils_nfvalidation_plugin" - tag "subworkflows/utils_nfvalidation_plugin" - - test("Should run nothing") { - - when { - - params { - monochrome_logs = true - test_data = '' - } - - workflow { - """ - help = false - workflow_command = null - pre_help_text = null - post_help_text = null - validate_params = false - schema_filename = "$moduleTestDir/nextflow_schema.json" - - input[0] = help - input[1] = workflow_command - input[2] = pre_help_text - input[3] = post_help_text - input[4] = validate_params - input[5] = schema_filename - """ - } - } - - then { - assertAll( - { assert workflow.success } - ) - } - } - - test("Should run help") { - - - when { - - params { - monochrome_logs = true - test_data = '' - } - workflow { - """ - help = true - workflow_command = null - pre_help_text = null - post_help_text = null - validate_params = false - schema_filename = "$moduleTestDir/nextflow_schema.json" - - input[0] = help - input[1] = workflow_command - input[2] = pre_help_text - input[3] = post_help_text - input[4] = validate_params - input[5] = schema_filename - """ - } - } - - then { - assertAll( - { assert workflow.success }, - { assert workflow.exitStatus == 0 }, - { assert workflow.stdout.any { it.contains('Input/output options') } }, - { assert workflow.stdout.any { it.contains('--outdir') } } - ) - } - } - - test("Should run help with command") { - - when { - - params { - monochrome_logs = true - test_data = '' - } - workflow { - """ - help = true - workflow_command = "nextflow run noorg/doesntexist" - pre_help_text = null - post_help_text = null - validate_params = false - schema_filename = "$moduleTestDir/nextflow_schema.json" - - input[0] = help - input[1] = workflow_command - input[2] = pre_help_text - input[3] = post_help_text - input[4] = validate_params - input[5] = schema_filename - """ - } - } - - then { - assertAll( - { assert workflow.success }, - { assert workflow.exitStatus == 0 }, - { assert workflow.stdout.any { it.contains('nextflow run noorg/doesntexist') } }, - { assert workflow.stdout.any { it.contains('Input/output options') } }, - { assert workflow.stdout.any { it.contains('--outdir') } } - ) - } - } - - test("Should run help with extra text") { - - - when { - - params { - monochrome_logs = true - test_data = '' - } - workflow { - """ - help = true - workflow_command = "nextflow run noorg/doesntexist" - pre_help_text = "pre-help-text" - post_help_text = "post-help-text" - validate_params = false - schema_filename = "$moduleTestDir/nextflow_schema.json" - - input[0] = help - input[1] = workflow_command - input[2] = pre_help_text - input[3] = post_help_text - input[4] = validate_params - input[5] = schema_filename - """ - } - } - - then { - assertAll( - { assert workflow.success }, - { assert workflow.exitStatus == 0 }, - { assert workflow.stdout.any { it.contains('pre-help-text') } }, - { assert workflow.stdout.any { it.contains('nextflow run noorg/doesntexist') } }, - { assert workflow.stdout.any { it.contains('Input/output options') } }, - { assert workflow.stdout.any { it.contains('--outdir') } }, - { assert workflow.stdout.any { it.contains('post-help-text') } } - ) - } - } - - test("Should validate params") { - - when { - - params { - monochrome_logs = true - test_data = '' - outdir = 1 - } - workflow { - """ - help = false - workflow_command = null - pre_help_text = null - post_help_text = null - validate_params = true - schema_filename = "$moduleTestDir/nextflow_schema.json" - - input[0] = help - input[1] = workflow_command - input[2] = pre_help_text - input[3] = post_help_text - input[4] = validate_params - input[5] = schema_filename - """ - } - } - - then { - assertAll( - { assert workflow.failed }, - { assert workflow.stdout.any { it.contains('ERROR ~ ERROR: Validation of pipeline parameters failed!') } } - ) - } - } -} diff --git a/subworkflows/nf-core/utils_nfvalidation_plugin/tests/tags.yml b/subworkflows/nf-core/utils_nfvalidation_plugin/tests/tags.yml deleted file mode 100644 index 60b1cfff4..000000000 --- a/subworkflows/nf-core/utils_nfvalidation_plugin/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -subworkflows/utils_nfvalidation_plugin: - - subworkflows/nf-core/utils_nfvalidation_plugin/** diff --git a/tests/.nftignore b/tests/.nftignore new file mode 100644 index 000000000..da508b609 --- /dev/null +++ b/tests/.nftignore @@ -0,0 +1,46 @@ +.DS_Store +multiqc/multiqc_data/fastqc_top_overrepresented_sequences_table.txt +multiqc/multiqc_data/BETA-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_plots/{svg,pdf,png}/*.{svg,pdf,png} +multiqc/multiqc_report.html +fastqc/*_fastqc.{html,zip} +pipeline_info/*.{html,json,txt,yml} +references/GRCh38/hgnc/HGNC-DB-timestamp.txt +references/GRCh38/hgnc/hgnc_complete_set.txt +references/GRCh38/fusion_report_db/DB-timestamp.txt +references/GRCh38/fusion_report_db/fusiongdb2.db +references/GRCh38/fusion_report_db/mitelman.db +references/GRCh38/gencode_v*/salmon/ctable.bin +references/GRCh38/gencode_v*/salmon/pos.bin +references/GRCh38/gencode_v*/salmon/pre_indexing.log +references/GRCh38/gencode_v*/salmon/ref_indexing.log +references/GRCh38/gencode_v*/salmon/seq.bin +references/GRCh38/gencode_v*/star/Log.out +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/cancer_splicing_lib/cancer_splicing.idx +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/ref_genome.fa.star.idx/ +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/PFAM.domtblout.dat.gz +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/blast_pairs.dat.gz +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/blast_pairs.idx +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/fusion_annot_lib.idx +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/pfam_domains.dbm +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/refGene.bed +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/ref_annot.cdna.fa +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/ref_annot.cdna.fa.idx +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/ref_annot.cds +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/ref_annot.cdsplus.fa +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/ref_annot.cdsplus.fa.idx +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/ref_annot.gtf.gene_spans +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/ref_annot.pep +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/ref_annot.prot_info.dbm +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/ref_genome.fa.nin +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/ref_genome.fa.njs +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/ref_genome.fa.star.idx/Log.out +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/trans.blast.align_coords.align_coords.dbm +references/GRCh38/gencode_v*/star/genomeParameters.txt +references/GRCh38/gencode_v*/starfusion/*_genome_lib_build_dir/ref_genome.fa.star.idx/genomeParameters.txt +references/GRCh38/fusion_report_db/mitelman.db +references/GRCh38/fusion_report_db/fusiongdb2.db diff --git a/tests/csv/fastq.csv b/tests/csv/fastq.csv new file mode 100644 index 000000000..7765b1bf1 --- /dev/null +++ b/tests/csv/fastq.csv @@ -0,0 +1,2 @@ +sample,fastq_1,fastq_2,strandedness +test,https://github.com/nf-core/test-datasets/raw/81cb45949e75cbb85cbf6c5ec9009ab45b160823/testdata/human/reads_1.fq.gz,https://github.com/nf-core/test-datasets/raw/81cb45949e75cbb85cbf6c5ec9009ab45b160823/testdata/human/reads_2.fq.gz,forward diff --git a/tests/main.nf.test b/tests/main.nf.test deleted file mode 100644 index 715335d8f..000000000 --- a/tests/main.nf.test +++ /dev/null @@ -1,49 +0,0 @@ -nextflow_pipeline { - - name "Test pipeline" - script "../main.nf" - tag "pipeline" - tag "pipeline_rnafusion" - - test("Run build references with profile test") { - - when { - params { - build_references = true - outdir = "results" - genome_base = "references" - max_cpus = 2 - max_memory = '6.GB' - max_time = '6.h' - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' - cosmic_username = COSMIC_USERNAME - cosmic_passwd = COSMIC_PASSWD - } - } - - then { - assertAll( - { assert workflow.success } - ) - } - } - test("Run fusion detection with profile test") { - - when { - params { - outdir = "results" - genome_base = "references" - max_cpus = 2 - max_memory = '6.GB' - max_time = '6.h' - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnafusion/testdata/human/samplesheet_valid.csv' - } - } - - then { - assertAll( - { assert workflow.success } - ) - } - } -} diff --git a/tests/nextflow.config b/tests/nextflow.config index ebd067ac8..eef755fe4 100644 --- a/tests/nextflow.config +++ b/tests/nextflow.config @@ -1,35 +1,38 @@ /* ======================================================================================== - Nextflow config file for running tests + Nextflow config file for running nf-test tests ======================================================================================== */ params { - // Base directory for nf-core/modules test data - modules_testdata_base_path = 's3://ngi-igenomes/testdata/nf-core/modules/' - - // Base directory for nf-core/rnaseq test data - pipelines_testdata_base_path = 's3://ngi-igenomes/testdata/nf-core/pipelines/rnaseq/3.15/' - - outdir = 'results' + modules_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' + pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/rnafusion' } -// Impose sensible resource limits for testing +aws.client.anonymous = true // fixes S3 access issues on self-hosted runners +// Limit and standardize resources for github actions and reproducibility process { - withName: '.*' { - cpus = 2 - memory = 3.GB - time = 2.h + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '4.h' + ] + + withName: 'STARFUSION_BUILD' { + ext.args = '' } } -// Impose same minimum Nextflow version as the pipeline for testing -manifest { - nextflowVersion = '!>=23.04.0' +params { + dfam_hmm = "${pipelines_testdata_base_path}/testdata/human/test_starfusion_dfam.hmm" + dfam_h3f = "${pipelines_testdata_base_path}/testdata/human/test_starfusion_dfam.hmm.h3f" + dfam_h3i = "${pipelines_testdata_base_path}/testdata/human/test_starfusion_dfam.hmm.h3i" + dfam_h3m = "${pipelines_testdata_base_path}/testdata/human/test_starfusion_dfam.hmm.h3m" + dfam_h3p = "${pipelines_testdata_base_path}/testdata/human/test_starfusion_dfam.hmm.h3p" + pfam_file = "${pipelines_testdata_base_path}/testdata/human/Pfam-A.hmm.gz" + fusioncatcher_ref = "${projectDir}/assets" + arriba_ref_blacklist = "s3://nf-core-awsmegatests/rnafusion/references/GRCh38/arriba/2.5.0/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "s3://nf-core-awsmegatests/rnafusion/references/GRCh38/arriba/2.5.0/cytobands_hg38_GRCh38_v2.5.0.tsv" + arriba_ref_known_fusions = "s3://nf-core-awsmegatests/rnafusion/references/GRCh38/arriba/2.5.0/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_protein_domains = "s3://nf-core-awsmegatests/rnafusion/references/GRCh38/arriba/2.5.0/protein_domains_hg38_GRCh38_v2.5.0.gff3" } - -// Disable all Nextflow reporting options -timeline { enabled = false } -report { enabled = false } -trace { enabled = false } -dag { enabled = false } diff --git a/tests/test_build.nf.test b/tests/test_build.nf.test new file mode 100644 index 000000000..ba53d9fec --- /dev/null +++ b/tests/test_build.nf.test @@ -0,0 +1,57 @@ +nextflow_pipeline { + + name "Test pipeline" + script "../main.nf" + profile "test_build" + tag "pipeline" + tag "pipeline_rnafusion" + tag "test_build" + + test("Test build references") { + when { + params { + config_profile_name = 'Test build references profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Input data + references_only = true + input = "${projectDir}/tests/csv/fastq.csv" + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + no_cosmic = true + tools = "all" + fasta = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/minigenome.fa' + gtf = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/minigenome.gtf' + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + species = 'homo_sapiens' + dfam_version = 3.4 + outdir = "$outputDir" + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + stable_path + ).match() } + ) + } + } +} diff --git a/tests/test_build.nf.test.snap b/tests/test_build.nf.test.snap new file mode 100644 index 000000000..8eb7bdc62 --- /dev/null +++ b/tests/test_build.nf.test.snap @@ -0,0 +1,291 @@ +{ + "Test build references": { + "content": [ + 13, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "CTATSPLICING_PREPGENOMELIB": { + "ctatsplicing": "0.0.2" + }, + "FUSIONREPORT_DOWNLOAD": { + "fusion_report": "4.0.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GFFREAD": { + "gffread": "0.12.7" + }, + "HGNC_DOWNLOAD": { + "wget": "1.21.4" + }, + "SALMON_INDEX": { + "salmon": "1.10.3" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "STARFUSION_BUILD": { + "gunzip": 1.12, + "hmmer": 3.4, + "STAR-Fusion": "1.15.1" + }, + "STAR_GENOMEGENERATE": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/minigenome.gtf.bed", + "bioawk", + "bioawk/minigenome.gtf_rrna.gtf.gz", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/fusion_report_db", + "references/GRCh38/fusion_report_db/DB-timestamp.txt", + "references/GRCh38/fusion_report_db/fusion_report.log", + "references/GRCh38/fusion_report_db/fusiongdb2.db", + "references/GRCh38/fusion_report_db/mitelman.db", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/minigenome.dict", + "references/GRCh38/gencode_v46/gencode/minigenome.fa.fai", + "references/GRCh38/gencode_v46/gencode/minigenome.gtf.fasta", + "references/GRCh38/gencode_v46/gencode/minigenome.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/minigenome.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/minigenome.gtf.refflat", + "references/GRCh38/gencode_v46/salmon", + "references/GRCh38/gencode_v46/salmon/complete_ref_lens.bin", + "references/GRCh38/gencode_v46/salmon/ctable.bin", + "references/GRCh38/gencode_v46/salmon/ctg_offsets.bin", + "references/GRCh38/gencode_v46/salmon/duplicate_clusters.tsv", + "references/GRCh38/gencode_v46/salmon/info.json", + "references/GRCh38/gencode_v46/salmon/mphf.bin", + "references/GRCh38/gencode_v46/salmon/pos.bin", + "references/GRCh38/gencode_v46/salmon/pre_indexing.log", + "references/GRCh38/gencode_v46/salmon/rank.bin", + "references/GRCh38/gencode_v46/salmon/refAccumLengths.bin", + "references/GRCh38/gencode_v46/salmon/ref_indexing.log", + "references/GRCh38/gencode_v46/salmon/reflengths.bin", + "references/GRCh38/gencode_v46/salmon/refseq.bin", + "references/GRCh38/gencode_v46/salmon/seq.bin", + "references/GRCh38/gencode_v46/salmon/versionInfo.json", + "references/GRCh38/gencode_v46/star", + "references/GRCh38/gencode_v46/star/Genome", + "references/GRCh38/gencode_v46/star/Log.out", + "references/GRCh38/gencode_v46/star/SA", + "references/GRCh38/gencode_v46/star/SAindex", + "references/GRCh38/gencode_v46/star/chrLength.txt", + "references/GRCh38/gencode_v46/star/chrName.txt", + "references/GRCh38/gencode_v46/star/chrNameLength.txt", + "references/GRCh38/gencode_v46/star/chrStart.txt", + "references/GRCh38/gencode_v46/star/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/star/exonInfo.tab", + "references/GRCh38/gencode_v46/star/geneInfo.tab", + "references/GRCh38/gencode_v46/star/genomeParameters.txt", + "references/GRCh38/gencode_v46/star/sjdbInfo.txt", + "references/GRCh38/gencode_v46/star/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/star/sjdbList.out.tab", + "references/GRCh38/gencode_v46/star/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/AnnotFilterRule.pm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/PFAM.domtblout.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_fusion_annot_lib.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_prot_info_db.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/annotfiltrule_cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/blast_pairs.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_gene_blast_pairs.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_pfam_dat.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/fusion_annot_lib.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_pfam_hits.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/makeblastdb.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2.splice_bed.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2_genome_idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.gene_spans.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.mini.sortu.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome.fa.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome_fai.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.index.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/validate_ctat_genome_lib.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/cancer_splicing_lib", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/cancer_splicing_lib/cancer_splicing.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/pfam_domains.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/refGene.bed", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/refGene.sort.bed.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/refGene.sort.bed.gz.tbi", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cds", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.gene_spans", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mini.sortu", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mm2.splice.bed", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.pep", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.prot_info.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.fai", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.mm2", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ndb", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nhr", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nin", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.njs", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.not", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nsq", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ntf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nto", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Genome", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Log.out", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SA", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SAindex", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/build.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrName.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrNameLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrStart.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/geneInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/genomeParameters.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbInfo.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dat", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.dat.gz", + "references/GRCh38/hgnc", + "references/GRCh38/hgnc/HGNC-DB-timestamp.txt", + "references/GRCh38/hgnc/hgnc_complete_set.txt" + ], + [ + "minigenome.gtf.bed:md5,d41d8cd98f00b204e9800998ecf8427e", + "minigenome.gtf_rrna.gtf.gz:md5,fb03ec66f68bc4becc71c299ed38b62d", + "fusion_report.log:md5,d41d8cd98f00b204e9800998ecf8427e", + "minigenome.dict:md5,f2dfb8df1d1f860050fc0dba1399fd9e", + "minigenome.fa.fai:md5,e3f74a27219b33ae80fd5de5cbeaf32b", + "minigenome.gtf.fasta:md5,349d42b5dbd73e163cdbad3453d8cd3a", + "minigenome.gtf.genepred:md5,c5b0d2118efd89f7a2831e2dc486b999", + "minigenome.gtf.interval_list:md5,9111fe876b17e5c18314206e9f985b8c", + "minigenome.gtf.refflat:md5,ed76bc063c98087f1100a928923758c7", + "complete_ref_lens.bin:md5,3b6d71ddb3eb8239be6623ab350a636d", + "ctg_offsets.bin:md5,174ead59c00c5264300d3ff1de673074", + "duplicate_clusters.tsv:md5,d30ab58d133298ed9ba51f1ba20ce89c", + "info.json:md5,d91d8a954afcb4be9fe7bfb3e84b5be6", + "mphf.bin:md5,b364192c6c73de4c38ec2ed0750f5155", + "rank.bin:md5,3fe9c2dc9da7faff6362510c4f29e87d", + "refAccumLengths.bin:md5,26d9405e7591ec9a606caa36a094941a", + "reflengths.bin:md5,187a4a0dee316c5dbf440fa3c58d9eec", + "refseq.bin:md5,712c4a8d988c15016ea746db7022e549", + "versionInfo.json:md5,d2c799050e81aa6e282ac8a73e773941", + "Genome:md5,1621486e3b854fefa37c0b4e77275233", + "SA:md5,9b6b936f3a8a1232c4fc5533daf9401d", + "SAindex:md5,8b2025227b78fdc83e3e5b17c0f538f7", + "chrLength.txt:md5,e02cd536b7281b894246863b160d5d06", + "chrName.txt:md5,f4d0d6595f423084e6b9472e40dfe6e8", + "chrNameLength.txt:md5,07a67d7ac441d7d30d80840b0927e717", + "chrStart.txt:md5,e2031239a74fe5ee9051e9364e4f608a", + "exonGeTrInfo.tab:md5,3c35618d07a8e35a0f9108699fcdda42", + "exonInfo.tab:md5,bcbb3f32fa31fe504cc737f337ad341c", + "geneInfo.tab:md5,db5db4b6e003904e9908fce7c05f0125", + "sjdbInfo.txt:md5,f044cb1cd38af66c832f3afc4b1655cb", + "sjdbList.fromGTF.out.tab:md5,8f3e8604b00d4067e4eb80aa476a8113", + "sjdbList.out.tab:md5,5d78dd49d5db24ca2c056b7ebe5c2059", + "transcriptInfo.tab:md5,b758c0ccaddcf0453bab5905b3cec4a2", + "AnnotFilterRule.pm:md5,f94966013cd0df9624a6dda0b75fefa0", + "_fusion_annot_lib.idx.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "_prot_info_db.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "annotfiltrule_cp.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "blast_pairs.idx.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "cp_gene_blast_pairs.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "cp_pfam_dat.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "cp_ref_annot_cdna.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "fusion_annot_lib.cp.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "index_pfam_hits.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "index_ref_annot_cdna.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "makeblastdb.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "mm2.splice_bed.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "mm2_genome_idx.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdsplus.dfam_masked.fa.cp.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.cdsplus.dfam_masked.fa.idx.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.gene_spans.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.mini.sortu.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_annot.gtf.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome.fa.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "ref_genome_fai.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "trans.blast.dat.cp.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "trans.blast.dat.index.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "validate_ctat_genome_lib.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "fusion_annot_lib.gz:md5,23d82a5da81f91ca4e1ecd6481992a12", + "refGene.sort.bed.gz:md5,01bf4093e3e9dcad8ed3a0f45a381c95", + "refGene.sort.bed.gz.tbi:md5,6dd8cd94a5cd10699fe8445a70c5b232", + "ref_annot.gtf:md5,5ce8afe99ef3940a877a04caeacf9181", + "ref_annot.gtf.mini.sortu:md5,1d29ccecdbb7b40a99c84a02d6c2c1be", + "ref_annot.gtf.mm2.splice.bed:md5,340585ea1843bf06bf555575ddecf28c", + "ref_genome.fa:md5,ad699c56ed38566c7d3e9579486b1706", + "ref_genome.fa.fai:md5,e3f74a27219b33ae80fd5de5cbeaf32b", + "ref_genome.fa.mm2:md5,ce50979ea284748eb9f84ae88cfd930e", + "ref_genome.fa.ndb:md5,6ea574753b557610f62f6e4ab79e19f5", + "ref_genome.fa.nhr:md5,50f28dae71683c4394bfaf94a1ef4392", + "ref_genome.fa.not:md5,1e53e9d08f1d23af0299cfa87478a7bb", + "ref_genome.fa.nsq:md5,d2361e7871ce4cf51181c112a48f191b", + "ref_genome.fa.ntf:md5,de1250813f0c7affc6d12dac9d0fb6bb", + "ref_genome.fa.nto:md5,33cdeccccebe80329f1fdbee7f5874cb", + "Genome:md5,9e3efdd0901cabb5a2d589664a63b372", + "SA:md5,7dd9083264be9c6a2194d990bc10d237", + "SAindex:md5,ac4711df685109e04356db9e9cb9fb7f", + "build.ok:md5,d41d8cd98f00b204e9800998ecf8427e", + "chrLength.txt:md5,e02cd536b7281b894246863b160d5d06", + "chrName.txt:md5,f4d0d6595f423084e6b9472e40dfe6e8", + "chrNameLength.txt:md5,07a67d7ac441d7d30d80840b0927e717", + "chrStart.txt:md5,e2031239a74fe5ee9051e9364e4f608a", + "exonGeTrInfo.tab:md5,3c35618d07a8e35a0f9108699fcdda42", + "exonInfo.tab:md5,bcbb3f32fa31fe504cc737f337ad341c", + "geneInfo.tab:md5,db5db4b6e003904e9908fce7c05f0125", + "sjdbInfo.txt:md5,e4cc1bbf8bd687cfc3d7c2c702e6def7", + "sjdbList.fromGTF.out.tab:md5,8f3e8604b00d4067e4eb80aa476a8113", + "sjdbList.out.tab:md5,5d78dd49d5db24ca2c056b7ebe5c2059", + "transcriptInfo.tab:md5,b758c0ccaddcf0453bab5905b3cec4a2", + "trans.blast.align_coords.align_coords.dat:md5,9f6b7a75aea03a9671190be25ecdd4c2", + "trans.blast.dat.gz:md5,85ba5ea96c566f751ad83a3e4b8ab128" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:15:36.32959" + } +} \ No newline at end of file diff --git a/tests/test_stub.nf.test b/tests/test_stub.nf.test new file mode 100644 index 000000000..08492ea92 --- /dev/null +++ b/tests/test_stub.nf.test @@ -0,0 +1,431 @@ +nextflow_pipeline { + + name "Test pipeline" + script "../main.nf" + profile "test" + options "-stub" // TODO remove once reference files are available + tag "pipeline" + tag "pipeline_rnafusion" + tag "test_stub" + + test("stub test all") { + + when { + params { + outdir = "$outputDir" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + tools = "all" + no_cosmic = true + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test arriba") { + + when { + params { + outdir = "$outputDir" + tools = "arriba" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test ctatsplicing") { + + when { + params { + outdir = "$outputDir" + tools = "ctatsplicing" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test fusioncatcher") { + + when { + params { + outdir = "$outputDir" + tools = "fusioncatcher" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test fusioncatcher trim") { + + when { + params { + outdir = "$outputDir" + tools = "fusioncatcher" + trim_tail_fusioncatcher = 50 + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test starfusion") { + + when { + params { + outdir = "$outputDir" + tools = "starfusion" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test stringtie") { + + when { + params { + outdir = "$outputDir" + tools = "stringtie" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test fusionreport") { + + when { + params { + outdir = "$outputDir" + tools = "fusionreport,arriba,starfusion,fusioncatcher" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + no_cosmic = true + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test fastp") { + + when { + params { + outdir = "$outputDir" + tools = "fastp" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test salmon") { + + when { + params { + outdir = "$outputDir" + tools = "salmon" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test fusioninspector") { + + when { + params { + outdir = "$outputDir" + tools = "fusioninspector,arriba,fusionreport" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + no_cosmic = true + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } +} diff --git a/tests/test_stub.nf.test.snap b/tests/test_stub.nf.test.snap new file mode 100644 index 000000000..65d5a3c2d --- /dev/null +++ b/tests/test_stub.nf.test.snap @@ -0,0 +1,2066 @@ +{ + "stub test starfusion": { + "content": [ + 27, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "SAMTOOLS_FLAGSTAT": { + "samtools": 1.21 + }, + "SAMTOOLS_IDXSTATS": { + "samtools": 1.21 + }, + "SAMTOOLS_INDEX": { + "samtools": 1.21 + }, + "SAMTOOLS_SORT": { + "samtools": 1.21 + }, + "SAMTOOLS_STATS": { + "samtools": 1.21 + }, + "STARFUSION_BUILD": { + "gunzip": 1.12, + "hmmer": 3.4, + "STAR-Fusion": "1.15.1" + }, + "STARFUSION_DETECT": { + "STAR-Fusion": "1.15.1" + }, + "STAR_ALIGN": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "STAR_GENOMEGENERATE": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai", + "references/GRCh38/gencode_v46/star", + "references/GRCh38/gencode_v46/star/Genome", + "references/GRCh38/gencode_v46/star/Log.out", + "references/GRCh38/gencode_v46/star/SA", + "references/GRCh38/gencode_v46/star/SAindex", + "references/GRCh38/gencode_v46/star/chrLength.txt", + "references/GRCh38/gencode_v46/star/chrName.txt", + "references/GRCh38/gencode_v46/star/chrNameLength.txt", + "references/GRCh38/gencode_v46/star/chrStart.txt", + "references/GRCh38/gencode_v46/star/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/star/exonInfo.tab", + "references/GRCh38/gencode_v46/star/geneInfo.tab", + "references/GRCh38/gencode_v46/star/genomeParameters.txt", + "references/GRCh38/gencode_v46/star/sjdbInfo.txt", + "references/GRCh38/gencode_v46/star/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/star/sjdbList.out.tab", + "references/GRCh38/gencode_v46/star/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/AnnotFilterRule.pm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/PFAM.domtblout.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_fusion_annot_lib.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_prot_info_db.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/annotfiltrule_cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/blast_pairs.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_gene_blast_pairs.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_pfam_dat.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/fusion_annot_lib.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_pfam_hits.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/makeblastdb.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2.splice_bed.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2_genome_idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.gene_spans.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.mini.sortu.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome.fa.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome_fai.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.index.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/validate_ctat_genome_lib.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/pfam_domains.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cds", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.gene_spans", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mini.sortu", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mm2.splice.bed", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.pep", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.prot_info.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.fai", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.mm2", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ndb", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nhr", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nin", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.njs", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.not", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nsq", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ntf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nto", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Genome", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Log.out", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SA", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SAindex", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/build.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrName.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrNameLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrStart.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/geneInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/genomeParameters.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbInfo.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dat", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.dat.gz", + "samtools", + "samtools/test.Aligned.sortedByCoord.bam", + "samtools/test.flagstat", + "samtools/test.idxstats", + "samtools/test.stats", + "star", + "star/test.Aligned.sortedByCoord.bam.bai", + "star/test.Aligned.sortedByCoord.out.bam", + "star/test.Aligned.sortedByCoord.out.bam.bai", + "star/test.Aligned.unsort.out.bam", + "star/test.Chimeric.out.junction", + "star/test.Log.final.out", + "star/test.Log.out", + "star/test.Log.progress.out", + "star/test.ReadsPerGene.out.tab", + "star/test.SJ.out.tab", + "star/test.Signal.UniqueMultiple.str1.out.bg", + "star/test.Signal.UniqueMultiple.str1.out.wig", + "star/test.out.sam", + "star/test.sortedByCoord.out.bam", + "star/test.tab", + "star/test.toTranscriptome.out.bam", + "star/test.unmapped_1.fastq.gz", + "star/test.unmapped_2.fastq.gz", + "star/testXd.out.bam", + "starfusion", + "starfusion/test.starfusion.abridged.coding_effect.tsv", + "starfusion/test.starfusion.abridged.tsv", + "starfusion/test.starfusion.fusion_predictions.tsv" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:26:56.896294" + }, + "stub test stringtie": { + "content": [ + 27, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "SAMTOOLS_FLAGSTAT": { + "samtools": 1.21 + }, + "SAMTOOLS_IDXSTATS": { + "samtools": 1.21 + }, + "SAMTOOLS_INDEX": { + "samtools": 1.21 + }, + "SAMTOOLS_SORT": { + "samtools": 1.21 + }, + "SAMTOOLS_STATS": { + "samtools": 1.21 + }, + "STAR_ALIGN": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "STAR_GENOMEGENERATE": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "STRINGTIE_MERGE": { + "stringtie": "2.2.1" + }, + "STRINGTIE_STRINGTIE": { + "stringtie": "2.2.3" + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai", + "references/GRCh38/gencode_v46/star", + "references/GRCh38/gencode_v46/star/Genome", + "references/GRCh38/gencode_v46/star/Log.out", + "references/GRCh38/gencode_v46/star/SA", + "references/GRCh38/gencode_v46/star/SAindex", + "references/GRCh38/gencode_v46/star/chrLength.txt", + "references/GRCh38/gencode_v46/star/chrName.txt", + "references/GRCh38/gencode_v46/star/chrNameLength.txt", + "references/GRCh38/gencode_v46/star/chrStart.txt", + "references/GRCh38/gencode_v46/star/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/star/exonInfo.tab", + "references/GRCh38/gencode_v46/star/geneInfo.tab", + "references/GRCh38/gencode_v46/star/genomeParameters.txt", + "references/GRCh38/gencode_v46/star/sjdbInfo.txt", + "references/GRCh38/gencode_v46/star/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/star/sjdbList.out.tab", + "references/GRCh38/gencode_v46/star/transcriptInfo.tab", + "samtools", + "samtools/test.Aligned.sortedByCoord.bam", + "samtools/test.flagstat", + "samtools/test.idxstats", + "samtools/test.stats", + "star", + "star/test.Aligned.sortedByCoord.bam.bai", + "star/test.Aligned.sortedByCoord.out.bam", + "star/test.Aligned.sortedByCoord.out.bam.bai", + "star/test.Aligned.unsort.out.bam", + "star/test.Chimeric.out.junction", + "star/test.Log.final.out", + "star/test.Log.out", + "star/test.Log.progress.out", + "star/test.ReadsPerGene.out.tab", + "star/test.SJ.out.tab", + "star/test.Signal.UniqueMultiple.str1.out.bg", + "star/test.Signal.UniqueMultiple.str1.out.wig", + "star/test.out.sam", + "star/test.sortedByCoord.out.bam", + "star/test.tab", + "star/test.toTranscriptome.out.bam", + "star/test.unmapped_1.fastq.gz", + "star/test.unmapped_2.fastq.gz", + "star/testXd.out.bam", + "stringtie", + "stringtie/[:]", + "stringtie/[:]/stringtie.merged.gtf", + "stringtie/test.ballgown", + "stringtie/test.coverage.gtf", + "stringtie/test.gene.abundance.txt", + "stringtie/test.transcripts.gtf" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:28:41.962459" + }, + "stub test arriba": { + "content": [ + 26, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "ARRIBA_ARRIBA": { + "arriba": "2.5.0" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "SAMTOOLS_FLAGSTAT": { + "samtools": 1.21 + }, + "SAMTOOLS_IDXSTATS": { + "samtools": 1.21 + }, + "SAMTOOLS_INDEX": { + "samtools": 1.21 + }, + "SAMTOOLS_SORT": { + "samtools": 1.21 + }, + "SAMTOOLS_STATS": { + "samtools": 1.21 + }, + "STAR_ALIGN": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "STAR_GENOMEGENERATE": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "arriba", + "arriba/test.arriba.fusions.discarded.tsv", + "arriba/test.arriba.fusions.tsv", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai", + "references/GRCh38/gencode_v46/star", + "references/GRCh38/gencode_v46/star/Genome", + "references/GRCh38/gencode_v46/star/Log.out", + "references/GRCh38/gencode_v46/star/SA", + "references/GRCh38/gencode_v46/star/SAindex", + "references/GRCh38/gencode_v46/star/chrLength.txt", + "references/GRCh38/gencode_v46/star/chrName.txt", + "references/GRCh38/gencode_v46/star/chrNameLength.txt", + "references/GRCh38/gencode_v46/star/chrStart.txt", + "references/GRCh38/gencode_v46/star/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/star/exonInfo.tab", + "references/GRCh38/gencode_v46/star/geneInfo.tab", + "references/GRCh38/gencode_v46/star/genomeParameters.txt", + "references/GRCh38/gencode_v46/star/sjdbInfo.txt", + "references/GRCh38/gencode_v46/star/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/star/sjdbList.out.tab", + "references/GRCh38/gencode_v46/star/transcriptInfo.tab", + "samtools", + "samtools/test.Aligned.sortedByCoord.bam", + "samtools/test.flagstat", + "samtools/test.idxstats", + "samtools/test.stats", + "star", + "star/test.Aligned.sortedByCoord.bam.bai", + "star/test.Aligned.sortedByCoord.out.bam", + "star/test.Aligned.sortedByCoord.out.bam.bai", + "star/test.Aligned.unsort.out.bam", + "star/test.Chimeric.out.junction", + "star/test.Log.final.out", + "star/test.Log.out", + "star/test.Log.progress.out", + "star/test.ReadsPerGene.out.tab", + "star/test.SJ.out.tab", + "star/test.Signal.UniqueMultiple.str1.out.bg", + "star/test.Signal.UniqueMultiple.str1.out.wig", + "star/test.out.sam", + "star/test.sortedByCoord.out.bam", + "star/test.tab", + "star/test.toTranscriptome.out.bam", + "star/test.unmapped_1.fastq.gz", + "star/test.unmapped_2.fastq.gz", + "star/testXd.out.bam" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:21:05.508972" + }, + "stub test fusioninspector": { + "content": [ + 31, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "ARRIBA_ARRIBA": { + "arriba": "2.5.0" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "FUSIONINSPECTOR": { + "FusionInspector": "2.10.0" + }, + "FUSIONREPORT_DETECT": { + "fusion_report": "4.0.1" + }, + "FUSIONREPORT_DOWNLOAD": { + "fusion_report": "4.0.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "HGNC_DOWNLOAD": { + "wget": "1.21.4" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "SAMTOOLS_FLAGSTAT": { + "samtools": 1.21 + }, + "SAMTOOLS_IDXSTATS": { + "samtools": 1.21 + }, + "SAMTOOLS_INDEX": { + "samtools": 1.21 + }, + "SAMTOOLS_SORT": { + "samtools": 1.21 + }, + "SAMTOOLS_STATS": { + "samtools": 1.21 + }, + "STARFUSION_BUILD": { + "gunzip": 1.12, + "hmmer": 3.4, + "STAR-Fusion": "1.15.1" + }, + "STAR_ALIGN": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "STAR_GENOMEGENERATE": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "arriba", + "arriba/test.arriba.fusions.discarded.tsv", + "arriba/test.arriba.fusions.tsv", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "fusioninspector", + "fusioninspector/test", + "fusioninspector/test/FusionInspector.log", + "fusioninspector/test/IGV_inputs", + "fusioninspector/test/chckpts_dir", + "fusioninspector/test/fi_workdir", + "fusioninspector/test/fi_workdir/test.gtf", + "fusioninspector/test/test.FusionInspector.fusions.abridged.tsv", + "fusioninspector/test/test.FusionInspector.fusions.tsv", + "fusioninspector/test/test.fusion_inspector_web.html", + "fusionreport", + "fusionreport/test", + "fusionreport/test/AAA_BBB.html", + "fusionreport/test/test.fusionreport.tsv", + "fusionreport/test/test.fusionreport_filtered.tsv", + "fusionreport/test/test.fusions.csv", + "fusionreport/test/test.fusions.json", + "fusionreport/test/test_fusionreport_index.html", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/fusion_report_db", + "references/GRCh38/fusion_report_db/DB-timestamp.txt", + "references/GRCh38/fusion_report_db/cosmic.db", + "references/GRCh38/fusion_report_db/fusion_report.log", + "references/GRCh38/fusion_report_db/fusiongdb2.db", + "references/GRCh38/fusion_report_db/mitelman.db", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai", + "references/GRCh38/gencode_v46/star", + "references/GRCh38/gencode_v46/star/Genome", + "references/GRCh38/gencode_v46/star/Log.out", + "references/GRCh38/gencode_v46/star/SA", + "references/GRCh38/gencode_v46/star/SAindex", + "references/GRCh38/gencode_v46/star/chrLength.txt", + "references/GRCh38/gencode_v46/star/chrName.txt", + "references/GRCh38/gencode_v46/star/chrNameLength.txt", + "references/GRCh38/gencode_v46/star/chrStart.txt", + "references/GRCh38/gencode_v46/star/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/star/exonInfo.tab", + "references/GRCh38/gencode_v46/star/geneInfo.tab", + "references/GRCh38/gencode_v46/star/genomeParameters.txt", + "references/GRCh38/gencode_v46/star/sjdbInfo.txt", + "references/GRCh38/gencode_v46/star/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/star/sjdbList.out.tab", + "references/GRCh38/gencode_v46/star/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/AnnotFilterRule.pm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/PFAM.domtblout.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_fusion_annot_lib.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_prot_info_db.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/annotfiltrule_cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/blast_pairs.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_gene_blast_pairs.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_pfam_dat.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/fusion_annot_lib.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_pfam_hits.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/makeblastdb.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2.splice_bed.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2_genome_idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.gene_spans.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.mini.sortu.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome.fa.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome_fai.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.index.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/validate_ctat_genome_lib.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/pfam_domains.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cds", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.gene_spans", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mini.sortu", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mm2.splice.bed", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.pep", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.prot_info.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.fai", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.mm2", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ndb", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nhr", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nin", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.njs", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.not", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nsq", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ntf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nto", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Genome", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Log.out", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SA", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SAindex", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/build.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrName.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrNameLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrStart.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/geneInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/genomeParameters.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbInfo.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dat", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.dat.gz", + "references/GRCh38/hgnc", + "references/GRCh38/hgnc/HGNC-DB-timestamp.txt", + "references/GRCh38/hgnc/hgnc_complete_set.txt", + "samtools", + "samtools/test.Aligned.sortedByCoord.bam", + "samtools/test.flagstat", + "samtools/test.idxstats", + "samtools/test.stats", + "star", + "star/test.Aligned.sortedByCoord.bam.bai", + "star/test.Aligned.sortedByCoord.out.bam", + "star/test.Aligned.sortedByCoord.out.bam.bai", + "star/test.Aligned.unsort.out.bam", + "star/test.Chimeric.out.junction", + "star/test.Log.final.out", + "star/test.Log.out", + "star/test.Log.progress.out", + "star/test.ReadsPerGene.out.tab", + "star/test.SJ.out.tab", + "star/test.Signal.UniqueMultiple.str1.out.bg", + "star/test.Signal.UniqueMultiple.str1.out.wig", + "star/test.out.sam", + "star/test.sortedByCoord.out.bam", + "star/test.tab", + "star/test.toTranscriptome.out.bam", + "star/test.unmapped_1.fastq.gz", + "star/test.unmapped_2.fastq.gz", + "star/testXd.out.bam" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:35:06.932469" + }, + "stub test salmon": { + "content": [ + 12, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "GFFREAD": { + "gffread": "0.12.7" + }, + "SALMON_INDEX": { + "salmon": "1.10.3" + }, + "SALMON_QUANT": { + "salmon": "1.10.3" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.fasta", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai", + "references/GRCh38/gencode_v46/salmon", + "references/GRCh38/gencode_v46/salmon/complete_ref_lens.bin", + "references/GRCh38/gencode_v46/salmon/ctable.bin", + "references/GRCh38/gencode_v46/salmon/ctg_offsets.bin", + "references/GRCh38/gencode_v46/salmon/duplicate_clusters.tsv", + "references/GRCh38/gencode_v46/salmon/info.json", + "references/GRCh38/gencode_v46/salmon/mphf.bin", + "references/GRCh38/gencode_v46/salmon/pos.bin", + "references/GRCh38/gencode_v46/salmon/pre_indexing.log", + "references/GRCh38/gencode_v46/salmon/rank.bin", + "references/GRCh38/gencode_v46/salmon/refAccumLengths.bin", + "references/GRCh38/gencode_v46/salmon/ref_indexing.log", + "references/GRCh38/gencode_v46/salmon/reflengths.bin", + "references/GRCh38/gencode_v46/salmon/refseq.bin", + "references/GRCh38/gencode_v46/salmon/seq.bin", + "references/GRCh38/gencode_v46/salmon/versionInfo.json", + "salmon", + "salmon/test", + "salmon/test_lib_format_counts.json", + "salmon/test_meta_info.json" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:32:56.766056" + }, + "stub test ctatsplicing": { + "content": [ + 28, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "CTATSPLICING_PREPGENOMELIB": { + "ctatsplicing": "0.0.2" + }, + "CTATSPLICING_STARTOCANCERINTRONS": { + "ctat-splicing": "0.0.2" + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "SAMTOOLS_FLAGSTAT": { + "samtools": 1.21 + }, + "SAMTOOLS_IDXSTATS": { + "samtools": 1.21 + }, + "SAMTOOLS_INDEX": { + "samtools": 1.21 + }, + "SAMTOOLS_SORT": { + "samtools": 1.21 + }, + "SAMTOOLS_STATS": { + "samtools": 1.21 + }, + "STARFUSION_BUILD": { + "gunzip": 1.12, + "hmmer": 3.4, + "STAR-Fusion": "1.15.1" + }, + "STAR_ALIGN": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "STAR_GENOMEGENERATE": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "ctatsplicing", + "ctatsplicing/test.cancer.introns", + "ctatsplicing/test.cancer.introns.prelim", + "ctatsplicing/test.cancer_intron_reads.sorted.bam", + "ctatsplicing/test.cancer_intron_reads.sorted.bam.bai", + "ctatsplicing/test.chckpts", + "ctatsplicing/test.ctat-splicing.igv.html", + "ctatsplicing/test.gene_reads.sorted.sifted.bam", + "ctatsplicing/test.gene_reads.sorted.sifted.bam.bai", + "ctatsplicing/test.igv.tracks", + "ctatsplicing/test.introns", + "ctatsplicing/test.introns.for_IGV.bed", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai", + "references/GRCh38/gencode_v46/star", + "references/GRCh38/gencode_v46/star/Genome", + "references/GRCh38/gencode_v46/star/Log.out", + "references/GRCh38/gencode_v46/star/SA", + "references/GRCh38/gencode_v46/star/SAindex", + "references/GRCh38/gencode_v46/star/chrLength.txt", + "references/GRCh38/gencode_v46/star/chrName.txt", + "references/GRCh38/gencode_v46/star/chrNameLength.txt", + "references/GRCh38/gencode_v46/star/chrStart.txt", + "references/GRCh38/gencode_v46/star/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/star/exonInfo.tab", + "references/GRCh38/gencode_v46/star/geneInfo.tab", + "references/GRCh38/gencode_v46/star/genomeParameters.txt", + "references/GRCh38/gencode_v46/star/sjdbInfo.txt", + "references/GRCh38/gencode_v46/star/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/star/sjdbList.out.tab", + "references/GRCh38/gencode_v46/star/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/AnnotFilterRule.pm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/PFAM.domtblout.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_fusion_annot_lib.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_prot_info_db.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/annotfiltrule_cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/blast_pairs.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_gene_blast_pairs.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_pfam_dat.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/fusion_annot_lib.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_pfam_hits.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/makeblastdb.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2.splice_bed.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2_genome_idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.gene_spans.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.mini.sortu.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome.fa.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome_fai.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.index.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/validate_ctat_genome_lib.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/cancer_splicing_lib", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/cancer_splicing_lib/cancer_splicing.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/pfam_domains.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/refGene.bed", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/refGene.sort.bed.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/refGene.sort.bed.gz.tbi", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cds", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.gene_spans", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mini.sortu", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mm2.splice.bed", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.pep", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.prot_info.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.fai", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.mm2", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ndb", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nhr", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nin", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.njs", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.not", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nsq", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ntf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nto", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Genome", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Log.out", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SA", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SAindex", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/build.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrName.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrNameLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrStart.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/geneInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/genomeParameters.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbInfo.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dat", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.dat.gz", + "samtools", + "samtools/test.Aligned.sortedByCoord.bam", + "samtools/test.flagstat", + "samtools/test.idxstats", + "samtools/test.stats", + "star", + "star/test.Aligned.sortedByCoord.bam.bai", + "star/test.Aligned.sortedByCoord.out.bam", + "star/test.Aligned.sortedByCoord.out.bam.bai", + "star/test.Aligned.unsort.out.bam", + "star/test.Chimeric.out.junction", + "star/test.Log.final.out", + "star/test.Log.out", + "star/test.Log.progress.out", + "star/test.ReadsPerGene.out.tab", + "star/test.SJ.out.tab", + "star/test.Signal.UniqueMultiple.str1.out.bg", + "star/test.Signal.UniqueMultiple.str1.out.wig", + "star/test.out.sam", + "star/test.sortedByCoord.out.bam", + "star/test.tab", + "star/test.toTranscriptome.out.bam", + "star/test.unmapped_1.fastq.gz", + "star/test.unmapped_2.fastq.gz", + "star/testXd.out.bam" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:22:53.217808" + }, + "stub test fusionreport": { + "content": [ + 31, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "ARRIBA_ARRIBA": { + "arriba": "2.5.0" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "FUSIONCATCHER_FUSIONCATCHER": { + "fusioncatcher": "1.35" + }, + "FUSIONREPORT_DETECT": { + "fusion_report": "4.0.1" + }, + "FUSIONREPORT_DOWNLOAD": { + "fusion_report": "4.0.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "SAMTOOLS_FLAGSTAT": { + "samtools": 1.21 + }, + "SAMTOOLS_IDXSTATS": { + "samtools": 1.21 + }, + "SAMTOOLS_INDEX": { + "samtools": 1.21 + }, + "SAMTOOLS_SORT": { + "samtools": 1.21 + }, + "SAMTOOLS_STATS": { + "samtools": 1.21 + }, + "STARFUSION_BUILD": { + "gunzip": 1.12, + "hmmer": 3.4, + "STAR-Fusion": "1.15.1" + }, + "STARFUSION_DETECT": { + "STAR-Fusion": "1.15.1" + }, + "STAR_ALIGN": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "STAR_GENOMEGENERATE": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "arriba", + "arriba/test.arriba.fusions.discarded.tsv", + "arriba/test.arriba.fusions.tsv", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "fusioncatcher", + "fusioncatcher/test.fusion-genes.txt", + "fusioncatcher/test.log", + "fusioncatcher/test.summary.txt", + "fusionreport", + "fusionreport/test", + "fusionreport/test/AAA_BBB.html", + "fusionreport/test/test.fusionreport.tsv", + "fusionreport/test/test.fusionreport_filtered.tsv", + "fusionreport/test/test.fusions.csv", + "fusionreport/test/test.fusions.json", + "fusionreport/test/test_fusionreport_index.html", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/fusion_report_db", + "references/GRCh38/fusion_report_db/DB-timestamp.txt", + "references/GRCh38/fusion_report_db/cosmic.db", + "references/GRCh38/fusion_report_db/fusion_report.log", + "references/GRCh38/fusion_report_db/fusiongdb2.db", + "references/GRCh38/fusion_report_db/mitelman.db", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai", + "references/GRCh38/gencode_v46/star", + "references/GRCh38/gencode_v46/star/Genome", + "references/GRCh38/gencode_v46/star/Log.out", + "references/GRCh38/gencode_v46/star/SA", + "references/GRCh38/gencode_v46/star/SAindex", + "references/GRCh38/gencode_v46/star/chrLength.txt", + "references/GRCh38/gencode_v46/star/chrName.txt", + "references/GRCh38/gencode_v46/star/chrNameLength.txt", + "references/GRCh38/gencode_v46/star/chrStart.txt", + "references/GRCh38/gencode_v46/star/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/star/exonInfo.tab", + "references/GRCh38/gencode_v46/star/geneInfo.tab", + "references/GRCh38/gencode_v46/star/genomeParameters.txt", + "references/GRCh38/gencode_v46/star/sjdbInfo.txt", + "references/GRCh38/gencode_v46/star/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/star/sjdbList.out.tab", + "references/GRCh38/gencode_v46/star/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/AnnotFilterRule.pm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/PFAM.domtblout.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_fusion_annot_lib.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_prot_info_db.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/annotfiltrule_cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/blast_pairs.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_gene_blast_pairs.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_pfam_dat.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/fusion_annot_lib.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_pfam_hits.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/makeblastdb.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2.splice_bed.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2_genome_idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.gene_spans.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.mini.sortu.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome.fa.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome_fai.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.index.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/validate_ctat_genome_lib.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/pfam_domains.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cds", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.gene_spans", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mini.sortu", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mm2.splice.bed", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.pep", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.prot_info.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.fai", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.mm2", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ndb", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nhr", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nin", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.njs", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.not", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nsq", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ntf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nto", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Genome", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Log.out", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SA", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SAindex", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/build.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrName.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrNameLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrStart.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/geneInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/genomeParameters.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbInfo.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dat", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.dat.gz", + "samtools", + "samtools/test.Aligned.sortedByCoord.bam", + "samtools/test.flagstat", + "samtools/test.idxstats", + "samtools/test.stats", + "star", + "star/test.Aligned.sortedByCoord.bam.bai", + "star/test.Aligned.sortedByCoord.out.bam", + "star/test.Aligned.sortedByCoord.out.bam.bai", + "star/test.Aligned.unsort.out.bam", + "star/test.Chimeric.out.junction", + "star/test.Log.final.out", + "star/test.Log.out", + "star/test.Log.progress.out", + "star/test.ReadsPerGene.out.tab", + "star/test.SJ.out.tab", + "star/test.Signal.UniqueMultiple.str1.out.bg", + "star/test.Signal.UniqueMultiple.str1.out.wig", + "star/test.out.sam", + "star/test.sortedByCoord.out.bam", + "star/test.tab", + "star/test.toTranscriptome.out.bam", + "star/test.unmapped_1.fastq.gz", + "star/test.unmapped_2.fastq.gz", + "star/testXd.out.bam", + "starfusion", + "starfusion/test.starfusion.abridged.coding_effect.tsv", + "starfusion/test.starfusion.abridged.tsv", + "starfusion/test.starfusion.fusion_predictions.tsv" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:30:41.638938" + }, + "stub test fastp": { + "content": [ + 11, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTP": { + "fastp": "0.24.0" + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "FASTQC_TRIM": { + "fastqc": "0.12.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastp", + "fastp/test.fastp.html", + "fastp/test.fastp.json", + "fastp/test.fastp.log", + "fastp/test_1.fastp.fastq.gz", + "fastp/test_2.fastp.fastq.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "fastqc_for_fastp", + "fastqc_for_fastp/test_trimmed.html", + "fastqc_for_fastp/test_trimmed.zip", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:31:48.594211" + }, + "stub test fusioncatcher": { + "content": [ + 10, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "FUSIONCATCHER_FUSIONCATCHER": { + "fusioncatcher": "1.35" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "fusioncatcher", + "fusioncatcher/test.fusion-genes.txt", + "fusioncatcher/test.log", + "fusioncatcher/test.summary.txt", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:24:00.433475" + }, + "stub test fusioncatcher trim": { + "content": [ + 11, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTP_FOR_FUSIONCATCHER": { + "fastp": "0.24.0" + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "FUSIONCATCHER_FUSIONCATCHER": { + "fusioncatcher": "1.35" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastp_for_fusioncatcher", + "fastp_for_fusioncatcher/test_trimmed_for_fusioncatcher.fastp.html", + "fastp_for_fusioncatcher/test_trimmed_for_fusioncatcher.fastp.json", + "fastp_for_fusioncatcher/test_trimmed_for_fusioncatcher.fastp.log", + "fastp_for_fusioncatcher/test_trimmed_for_fusioncatcher_1.fastp.fastq.gz", + "fastp_for_fusioncatcher/test_trimmed_for_fusioncatcher_2.fastp.fastq.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "fusioncatcher", + "fusioncatcher/test.fusion-genes.txt", + "fusioncatcher/test.log", + "fusioncatcher/test.summary.txt", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:25:10.408652" + }, + "stub test all": { + "content": [ + 42, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "ARRIBA_ARRIBA": { + "arriba": "2.5.0" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "CTATSPLICING_PREPGENOMELIB": { + "ctatsplicing": "0.0.2" + }, + "CTATSPLICING_STARTOCANCERINTRONS": { + "ctat-splicing": "0.0.2" + }, + "FASTP": { + "fastp": "0.24.0" + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "FASTQC_TRIM": { + "fastqc": "0.12.1" + }, + "FUSIONCATCHER_FUSIONCATCHER": { + "fusioncatcher": "1.35" + }, + "FUSIONINSPECTOR": { + "FusionInspector": "2.10.0" + }, + "FUSIONREPORT_DETECT": { + "fusion_report": "4.0.1" + }, + "FUSIONREPORT_DOWNLOAD": { + "fusion_report": "4.0.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "GFFREAD": { + "gffread": "0.12.7" + }, + "HGNC_DOWNLOAD": { + "wget": "1.21.4" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SALMON_INDEX": { + "salmon": "1.10.3" + }, + "SALMON_QUANT": { + "salmon": "1.10.3" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "SAMTOOLS_FLAGSTAT": { + "samtools": 1.21 + }, + "SAMTOOLS_IDXSTATS": { + "samtools": 1.21 + }, + "SAMTOOLS_INDEX": { + "samtools": 1.21 + }, + "SAMTOOLS_SORT": { + "samtools": 1.21 + }, + "SAMTOOLS_STATS": { + "samtools": 1.21 + }, + "STARFUSION_BUILD": { + "gunzip": 1.12, + "hmmer": 3.4, + "STAR-Fusion": "1.15.1" + }, + "STARFUSION_DETECT": { + "STAR-Fusion": "1.15.1" + }, + "STAR_ALIGN": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "STAR_GENOMEGENERATE": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "STRINGTIE_MERGE": { + "stringtie": "2.2.1" + }, + "STRINGTIE_STRINGTIE": { + "stringtie": "2.2.3" + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "arriba", + "arriba/test.arriba.fusions.discarded.tsv", + "arriba/test.arriba.fusions.tsv", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "ctatsplicing", + "ctatsplicing/test.cancer.introns", + "ctatsplicing/test.cancer.introns.prelim", + "ctatsplicing/test.cancer_intron_reads.sorted.bam", + "ctatsplicing/test.cancer_intron_reads.sorted.bam.bai", + "ctatsplicing/test.chckpts", + "ctatsplicing/test.ctat-splicing.igv.html", + "ctatsplicing/test.gene_reads.sorted.sifted.bam", + "ctatsplicing/test.gene_reads.sorted.sifted.bam.bai", + "ctatsplicing/test.igv.tracks", + "ctatsplicing/test.introns", + "ctatsplicing/test.introns.for_IGV.bed", + "fastp", + "fastp/test.fastp.html", + "fastp/test.fastp.json", + "fastp/test.fastp.log", + "fastp/test_1.fastp.fastq.gz", + "fastp/test_2.fastp.fastq.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "fastqc_for_fastp", + "fastqc_for_fastp/test_trimmed.html", + "fastqc_for_fastp/test_trimmed.zip", + "fusioncatcher", + "fusioncatcher/test.fusion-genes.txt", + "fusioncatcher/test.log", + "fusioncatcher/test.summary.txt", + "fusioninspector", + "fusioninspector/test", + "fusioninspector/test/FusionInspector.log", + "fusioninspector/test/IGV_inputs", + "fusioninspector/test/chckpts_dir", + "fusioninspector/test/fi_workdir", + "fusioninspector/test/fi_workdir/test.gtf", + "fusioninspector/test/test.FusionInspector.fusions.abridged.tsv", + "fusioninspector/test/test.FusionInspector.fusions.tsv", + "fusioninspector/test/test.fusion_inspector_web.html", + "fusionreport", + "fusionreport/test", + "fusionreport/test/AAA_BBB.html", + "fusionreport/test/test.fusionreport.tsv", + "fusionreport/test/test.fusionreport_filtered.tsv", + "fusionreport/test/test.fusions.csv", + "fusionreport/test/test.fusions.json", + "fusionreport/test/test_fusionreport_index.html", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/fusion_report_db", + "references/GRCh38/fusion_report_db/DB-timestamp.txt", + "references/GRCh38/fusion_report_db/cosmic.db", + "references/GRCh38/fusion_report_db/fusion_report.log", + "references/GRCh38/fusion_report_db/fusiongdb2.db", + "references/GRCh38/fusion_report_db/mitelman.db", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.fasta", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai", + "references/GRCh38/gencode_v46/salmon", + "references/GRCh38/gencode_v46/salmon/complete_ref_lens.bin", + "references/GRCh38/gencode_v46/salmon/ctable.bin", + "references/GRCh38/gencode_v46/salmon/ctg_offsets.bin", + "references/GRCh38/gencode_v46/salmon/duplicate_clusters.tsv", + "references/GRCh38/gencode_v46/salmon/info.json", + "references/GRCh38/gencode_v46/salmon/mphf.bin", + "references/GRCh38/gencode_v46/salmon/pos.bin", + "references/GRCh38/gencode_v46/salmon/pre_indexing.log", + "references/GRCh38/gencode_v46/salmon/rank.bin", + "references/GRCh38/gencode_v46/salmon/refAccumLengths.bin", + "references/GRCh38/gencode_v46/salmon/ref_indexing.log", + "references/GRCh38/gencode_v46/salmon/reflengths.bin", + "references/GRCh38/gencode_v46/salmon/refseq.bin", + "references/GRCh38/gencode_v46/salmon/seq.bin", + "references/GRCh38/gencode_v46/salmon/versionInfo.json", + "references/GRCh38/gencode_v46/star", + "references/GRCh38/gencode_v46/star/Genome", + "references/GRCh38/gencode_v46/star/Log.out", + "references/GRCh38/gencode_v46/star/SA", + "references/GRCh38/gencode_v46/star/SAindex", + "references/GRCh38/gencode_v46/star/chrLength.txt", + "references/GRCh38/gencode_v46/star/chrName.txt", + "references/GRCh38/gencode_v46/star/chrNameLength.txt", + "references/GRCh38/gencode_v46/star/chrStart.txt", + "references/GRCh38/gencode_v46/star/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/star/exonInfo.tab", + "references/GRCh38/gencode_v46/star/geneInfo.tab", + "references/GRCh38/gencode_v46/star/genomeParameters.txt", + "references/GRCh38/gencode_v46/star/sjdbInfo.txt", + "references/GRCh38/gencode_v46/star/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/star/sjdbList.out.tab", + "references/GRCh38/gencode_v46/star/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/AnnotFilterRule.pm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/PFAM.domtblout.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_fusion_annot_lib.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_prot_info_db.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/annotfiltrule_cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/blast_pairs.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_gene_blast_pairs.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_pfam_dat.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/fusion_annot_lib.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_pfam_hits.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/makeblastdb.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2.splice_bed.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2_genome_idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.gene_spans.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.mini.sortu.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome.fa.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome_fai.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.index.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/validate_ctat_genome_lib.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/cancer_splicing_lib", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/cancer_splicing_lib/cancer_splicing.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/pfam_domains.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/refGene.bed", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/refGene.sort.bed.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/refGene.sort.bed.gz.tbi", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cds", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.gene_spans", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mini.sortu", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mm2.splice.bed", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.pep", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.prot_info.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.fai", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.mm2", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ndb", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nhr", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nin", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.njs", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.not", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nsq", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ntf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nto", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Genome", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Log.out", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SA", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SAindex", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/build.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrName.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrNameLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrStart.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/geneInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/genomeParameters.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbInfo.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dat", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.dat.gz", + "references/GRCh38/hgnc", + "references/GRCh38/hgnc/HGNC-DB-timestamp.txt", + "references/GRCh38/hgnc/hgnc_complete_set.txt", + "salmon", + "salmon/test", + "salmon/test_lib_format_counts.json", + "salmon/test_meta_info.json", + "samtools", + "samtools/test.Aligned.sortedByCoord.bam", + "samtools/test.flagstat", + "samtools/test.idxstats", + "samtools/test.stats", + "star", + "star/test.Aligned.sortedByCoord.bam.bai", + "star/test.Aligned.sortedByCoord.out.bam", + "star/test.Aligned.sortedByCoord.out.bam.bai", + "star/test.Aligned.unsort.out.bam", + "star/test.Chimeric.out.junction", + "star/test.Log.final.out", + "star/test.Log.out", + "star/test.Log.progress.out", + "star/test.ReadsPerGene.out.tab", + "star/test.SJ.out.tab", + "star/test.Signal.UniqueMultiple.str1.out.bg", + "star/test.Signal.UniqueMultiple.str1.out.wig", + "star/test.out.sam", + "star/test.sortedByCoord.out.bam", + "star/test.tab", + "star/test.toTranscriptome.out.bam", + "star/test.unmapped_1.fastq.gz", + "star/test.unmapped_2.fastq.gz", + "star/testXd.out.bam", + "starfusion", + "starfusion/test.starfusion.abridged.coding_effect.tsv", + "starfusion/test.starfusion.abridged.tsv", + "starfusion/test.starfusion.fusion_predictions.tsv", + "stringtie", + "stringtie/[:]", + "stringtie/[:]/stringtie.merged.gtf", + "stringtie/test.ballgown", + "stringtie/test.coverage.gtf", + "stringtie/test.gene.abundance.txt", + "stringtie/test.transcripts.gtf" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:19:22.837273" + } +} \ No newline at end of file diff --git a/tests/test_stub_bam.nf.test b/tests/test_stub_bam.nf.test new file mode 100644 index 000000000..036540242 --- /dev/null +++ b/tests/test_stub_bam.nf.test @@ -0,0 +1,408 @@ +nextflow_pipeline { + + name "Test pipeline" + script "../main.nf" + profile "test" + options "-stub" // TODO remove once reference files are available + tag "pipeline" + tag "pipeline_rnafusion" + tag "test_stub_bam" + + test("stub test all") { + + when { + params { + outdir = "$outputDir" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + input = "${projectDir}/tests/yml/bam.yml" + tools = "all" + no_cosmic = true + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test arriba") { + + when { + params { + outdir = "$outputDir" + tools = "arriba" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + input = "${projectDir}/tests/yml/bam.yml" + no_cosmic = true + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test ctatsplicing") { + + when { + params { + outdir = "$outputDir" + tools = "ctatsplicing" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + input = "${projectDir}/tests/yml/bam.yml" + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test fusioncatcher") { + + when { + params { + outdir = "$outputDir" + tools = "fusioncatcher" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + input = "${projectDir}/tests/yml/bam.yml" + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test starfusion") { + + tag "starfusion" + + when { + params { + outdir = "$outputDir" + tools = "starfusion" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + input = "${projectDir}/tests/yml/bam.yml" + genomes_base = "${outputDir}/references" + pfam_file = "http://ftp.ebi.ac.uk/pub/databases/Pfam/releases/Pfam37.4/Pfam-A.hmm.gz" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test stringtie") { + + when { + params { + outdir = "$outputDir" + tools = "stringtie" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + input = "${projectDir}/tests/yml/bam.yml" + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test fusionreport") { + tag "fusionreport" + + when { + params { + outdir = "$outputDir" + tools = "fusionreport,arriba,starfusion,fusioncatcher" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + input = "${projectDir}/tests/yml/bam.yml" + no_cosmic = true + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test fastp") { + + when { + params { + outdir = "$outputDir" + tools = "fastp" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + input = "${projectDir}/tests/yml/bam.yml" + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test salmon") { + + when { + params { + outdir = "$outputDir" + tools = "salmon" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + input = "${projectDir}/tests/yml/bam.yml" + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } + + test("stub test fusioninspector") { + + when { + params { + outdir = "$outputDir" + tools = "fusioninspector,arriba,fusionreport" + fusion_annot_lib = 'https://github.com/STAR-Fusion/STAR-Fusion-Tutorial/raw/master/CTAT_HumanFusionLib.mini.dat.gz' + input = "${projectDir}/tests/yml/bam.yml" + no_cosmic = true + genomes_base = "${outputDir}/references" + arriba_ref_protein_domains = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/protein_domains_hg38_GRCh38_v2.5.0.gff3" + arriba_ref_known_fusions = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/known_fusions_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_blacklist = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/blacklist_hg38_GRCh38_v2.5.0.tsv.gz" + arriba_ref_cytobands = "https://github.com/nf-core/test-datasets/raw/refs/heads/rnafusion/testdata/reference/arriba/cytobands_hg38_GRCh38_v2.5.0.tsv" + fusioncatcher_ref = "${projectDir}/assets" // This is a placeholder until a small reference can be created + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + // Ignore files with timestamps in their names + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}']) + // stable_path: All files in ${params.outdir}/ with stable content + // def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') //TODO uncomment once -stub is removed + assertAll( + { assert workflow.success}, + { assert snapshot( + // Number of successful tasks + workflow.trace.succeeded().size(), + // pipeline versions.yml file for multiqc from which Nextflow version is removed because we tests pipelines on multiple Nextflow versions + removeNextflowVersion("$outputDir/pipeline_info/nf_core_rnafusion_software_mqc_versions.yml"), + // All stable path name, with a relative path + stable_name, + // All files with stable contents + // stable_path // TODO uncomment once -stub is removed + ).match() } + ) + } + } +} diff --git a/tests/test_stub_bam.nf.test.snap b/tests/test_stub_bam.nf.test.snap new file mode 100644 index 000000000..c895d618b --- /dev/null +++ b/tests/test_stub_bam.nf.test.snap @@ -0,0 +1,1739 @@ +{ + "stub test starfusion": { + "content": [ + 15, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "STARFUSION_BUILD": { + "gunzip": 1.12, + "hmmer": 3.4, + "STAR-Fusion": "1.15.1" + }, + "STARFUSION_DETECT": { + "STAR-Fusion": "1.15.1" + }, + "STAR_GENOMEGENERATE": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai", + "references/GRCh38/gencode_v46/star", + "references/GRCh38/gencode_v46/star/Genome", + "references/GRCh38/gencode_v46/star/Log.out", + "references/GRCh38/gencode_v46/star/SA", + "references/GRCh38/gencode_v46/star/SAindex", + "references/GRCh38/gencode_v46/star/chrLength.txt", + "references/GRCh38/gencode_v46/star/chrName.txt", + "references/GRCh38/gencode_v46/star/chrNameLength.txt", + "references/GRCh38/gencode_v46/star/chrStart.txt", + "references/GRCh38/gencode_v46/star/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/star/exonInfo.tab", + "references/GRCh38/gencode_v46/star/geneInfo.tab", + "references/GRCh38/gencode_v46/star/genomeParameters.txt", + "references/GRCh38/gencode_v46/star/sjdbInfo.txt", + "references/GRCh38/gencode_v46/star/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/star/sjdbList.out.tab", + "references/GRCh38/gencode_v46/star/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/AnnotFilterRule.pm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/PFAM.domtblout.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_fusion_annot_lib.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_prot_info_db.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/annotfiltrule_cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/blast_pairs.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_gene_blast_pairs.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_pfam_dat.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/fusion_annot_lib.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_pfam_hits.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/makeblastdb.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2.splice_bed.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2_genome_idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.gene_spans.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.mini.sortu.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome.fa.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome_fai.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.index.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/validate_ctat_genome_lib.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/pfam_domains.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cds", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.gene_spans", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mini.sortu", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mm2.splice.bed", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.pep", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.prot_info.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.fai", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.mm2", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ndb", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nhr", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nin", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.njs", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.not", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nsq", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ntf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nto", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Genome", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Log.out", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SA", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SAindex", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/build.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrName.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrNameLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrStart.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/geneInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/genomeParameters.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbInfo.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dat", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.dat.gz", + "starfusion", + "starfusion/test.starfusion.abridged.coding_effect.tsv", + "starfusion/test.starfusion.abridged.tsv", + "starfusion/test.starfusion.fusion_predictions.tsv" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:43:47.567472" + }, + "stub test stringtie": { + "content": [ + 16, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "STAR_GENOMEGENERATE": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "STRINGTIE_MERGE": { + "stringtie": "2.2.1" + }, + "STRINGTIE_STRINGTIE": { + "stringtie": "2.2.3" + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai", + "references/GRCh38/gencode_v46/star", + "references/GRCh38/gencode_v46/star/Genome", + "references/GRCh38/gencode_v46/star/Log.out", + "references/GRCh38/gencode_v46/star/SA", + "references/GRCh38/gencode_v46/star/SAindex", + "references/GRCh38/gencode_v46/star/chrLength.txt", + "references/GRCh38/gencode_v46/star/chrName.txt", + "references/GRCh38/gencode_v46/star/chrNameLength.txt", + "references/GRCh38/gencode_v46/star/chrStart.txt", + "references/GRCh38/gencode_v46/star/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/star/exonInfo.tab", + "references/GRCh38/gencode_v46/star/geneInfo.tab", + "references/GRCh38/gencode_v46/star/genomeParameters.txt", + "references/GRCh38/gencode_v46/star/sjdbInfo.txt", + "references/GRCh38/gencode_v46/star/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/star/sjdbList.out.tab", + "references/GRCh38/gencode_v46/star/transcriptInfo.tab", + "star", + "star/test.Aligned.sortedByCoord.out.bam", + "star/test.Aligned.sortedByCoord.out.bam.bai", + "stringtie", + "stringtie/[:]", + "stringtie/[:]/stringtie.merged.gtf", + "stringtie/test.ballgown", + "stringtie/test.coverage.gtf", + "stringtie/test.gene.abundance.txt", + "stringtie/test.transcripts.gtf" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:45:23.291041" + }, + "stub test arriba": { + "content": [ + 14, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "ARRIBA_ARRIBA": { + "arriba": "2.5.0" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "STAR_GENOMEGENERATE": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "arriba", + "arriba/test.arriba.fusions.discarded.tsv", + "arriba/test.arriba.fusions.tsv", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai", + "references/GRCh38/gencode_v46/star", + "references/GRCh38/gencode_v46/star/Genome", + "references/GRCh38/gencode_v46/star/Log.out", + "references/GRCh38/gencode_v46/star/SA", + "references/GRCh38/gencode_v46/star/SAindex", + "references/GRCh38/gencode_v46/star/chrLength.txt", + "references/GRCh38/gencode_v46/star/chrName.txt", + "references/GRCh38/gencode_v46/star/chrNameLength.txt", + "references/GRCh38/gencode_v46/star/chrStart.txt", + "references/GRCh38/gencode_v46/star/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/star/exonInfo.tab", + "references/GRCh38/gencode_v46/star/geneInfo.tab", + "references/GRCh38/gencode_v46/star/genomeParameters.txt", + "references/GRCh38/gencode_v46/star/sjdbInfo.txt", + "references/GRCh38/gencode_v46/star/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/star/sjdbList.out.tab", + "references/GRCh38/gencode_v46/star/transcriptInfo.tab" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:38:57.291156" + }, + "stub test fusioninspector": { + "content": [ + 20, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "ARRIBA_ARRIBA": { + "arriba": "2.5.0" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "FUSIONINSPECTOR": { + "FusionInspector": "2.10.0" + }, + "FUSIONREPORT_DETECT": { + "fusion_report": "4.0.1" + }, + "FUSIONREPORT_DOWNLOAD": { + "fusion_report": "4.0.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "HGNC_DOWNLOAD": { + "wget": "1.21.4" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "STARFUSION_BUILD": { + "gunzip": 1.12, + "hmmer": 3.4, + "STAR-Fusion": "1.15.1" + }, + "STAR_GENOMEGENERATE": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "arriba", + "arriba/test.arriba.fusions.discarded.tsv", + "arriba/test.arriba.fusions.tsv", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "fusioninspector", + "fusioninspector/test", + "fusioninspector/test/FusionInspector.log", + "fusioninspector/test/IGV_inputs", + "fusioninspector/test/chckpts_dir", + "fusioninspector/test/fi_workdir", + "fusioninspector/test/fi_workdir/test.gtf", + "fusioninspector/test/test.FusionInspector.fusions.abridged.tsv", + "fusioninspector/test/test.FusionInspector.fusions.tsv", + "fusioninspector/test/test.fusion_inspector_web.html", + "fusionreport", + "fusionreport/test", + "fusionreport/test/AAA_BBB.html", + "fusionreport/test/test.fusionreport.tsv", + "fusionreport/test/test.fusionreport_filtered.tsv", + "fusionreport/test/test.fusions.csv", + "fusionreport/test/test.fusions.json", + "fusionreport/test/test_fusionreport_index.html", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/fusion_report_db", + "references/GRCh38/fusion_report_db/DB-timestamp.txt", + "references/GRCh38/fusion_report_db/cosmic.db", + "references/GRCh38/fusion_report_db/fusion_report.log", + "references/GRCh38/fusion_report_db/fusiongdb2.db", + "references/GRCh38/fusion_report_db/mitelman.db", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai", + "references/GRCh38/gencode_v46/star", + "references/GRCh38/gencode_v46/star/Genome", + "references/GRCh38/gencode_v46/star/Log.out", + "references/GRCh38/gencode_v46/star/SA", + "references/GRCh38/gencode_v46/star/SAindex", + "references/GRCh38/gencode_v46/star/chrLength.txt", + "references/GRCh38/gencode_v46/star/chrName.txt", + "references/GRCh38/gencode_v46/star/chrNameLength.txt", + "references/GRCh38/gencode_v46/star/chrStart.txt", + "references/GRCh38/gencode_v46/star/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/star/exonInfo.tab", + "references/GRCh38/gencode_v46/star/geneInfo.tab", + "references/GRCh38/gencode_v46/star/genomeParameters.txt", + "references/GRCh38/gencode_v46/star/sjdbInfo.txt", + "references/GRCh38/gencode_v46/star/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/star/sjdbList.out.tab", + "references/GRCh38/gencode_v46/star/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/AnnotFilterRule.pm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/PFAM.domtblout.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_fusion_annot_lib.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_prot_info_db.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/annotfiltrule_cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/blast_pairs.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_gene_blast_pairs.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_pfam_dat.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/fusion_annot_lib.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_pfam_hits.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/makeblastdb.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2.splice_bed.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2_genome_idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.gene_spans.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.mini.sortu.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome.fa.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome_fai.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.index.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/validate_ctat_genome_lib.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/pfam_domains.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cds", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.gene_spans", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mini.sortu", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mm2.splice.bed", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.pep", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.prot_info.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.fai", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.mm2", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ndb", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nhr", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nin", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.njs", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.not", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nsq", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ntf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nto", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Genome", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Log.out", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SA", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SAindex", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/build.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrName.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrNameLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrStart.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/geneInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/genomeParameters.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbInfo.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dat", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.dat.gz", + "references/GRCh38/hgnc", + "references/GRCh38/hgnc/HGNC-DB-timestamp.txt", + "references/GRCh38/hgnc/hgnc_complete_set.txt", + "star", + "star/test.Aligned.sortedByCoord.out.bam", + "star/test.Aligned.sortedByCoord.out.bam.bai" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:52:15.87533" + }, + "stub test salmon": { + "content": [ + 15, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "GFFREAD": { + "gffread": "0.12.7" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SALMON_INDEX": { + "salmon": "1.10.3" + }, + "SALMON_QUANT": { + "salmon": "1.10.3" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.fasta", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai", + "references/GRCh38/gencode_v46/salmon", + "references/GRCh38/gencode_v46/salmon/complete_ref_lens.bin", + "references/GRCh38/gencode_v46/salmon/ctable.bin", + "references/GRCh38/gencode_v46/salmon/ctg_offsets.bin", + "references/GRCh38/gencode_v46/salmon/duplicate_clusters.tsv", + "references/GRCh38/gencode_v46/salmon/info.json", + "references/GRCh38/gencode_v46/salmon/mphf.bin", + "references/GRCh38/gencode_v46/salmon/pos.bin", + "references/GRCh38/gencode_v46/salmon/pre_indexing.log", + "references/GRCh38/gencode_v46/salmon/rank.bin", + "references/GRCh38/gencode_v46/salmon/refAccumLengths.bin", + "references/GRCh38/gencode_v46/salmon/ref_indexing.log", + "references/GRCh38/gencode_v46/salmon/reflengths.bin", + "references/GRCh38/gencode_v46/salmon/refseq.bin", + "references/GRCh38/gencode_v46/salmon/seq.bin", + "references/GRCh38/gencode_v46/salmon/versionInfo.json", + "salmon", + "salmon/test", + "salmon/test_lib_format_counts.json", + "salmon/test_meta_info.json" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:50:21.195099" + }, + "stub test ctatsplicing": { + "content": [ + 17, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "CTATSPLICING_PREPGENOMELIB": { + "ctatsplicing": "0.0.2" + }, + "CTATSPLICING_STARTOCANCERINTRONS": { + "ctat-splicing": "0.0.2" + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "STARFUSION_BUILD": { + "gunzip": 1.12, + "hmmer": 3.4, + "STAR-Fusion": "1.15.1" + }, + "STAR_GENOMEGENERATE": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "ctatsplicing", + "ctatsplicing/test.cancer.introns", + "ctatsplicing/test.cancer.introns.prelim", + "ctatsplicing/test.cancer_intron_reads.sorted.bam", + "ctatsplicing/test.cancer_intron_reads.sorted.bam.bai", + "ctatsplicing/test.chckpts", + "ctatsplicing/test.ctat-splicing.igv.html", + "ctatsplicing/test.gene_reads.sorted.sifted.bam", + "ctatsplicing/test.gene_reads.sorted.sifted.bam.bai", + "ctatsplicing/test.igv.tracks", + "ctatsplicing/test.introns", + "ctatsplicing/test.introns.for_IGV.bed", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai", + "references/GRCh38/gencode_v46/star", + "references/GRCh38/gencode_v46/star/Genome", + "references/GRCh38/gencode_v46/star/Log.out", + "references/GRCh38/gencode_v46/star/SA", + "references/GRCh38/gencode_v46/star/SAindex", + "references/GRCh38/gencode_v46/star/chrLength.txt", + "references/GRCh38/gencode_v46/star/chrName.txt", + "references/GRCh38/gencode_v46/star/chrNameLength.txt", + "references/GRCh38/gencode_v46/star/chrStart.txt", + "references/GRCh38/gencode_v46/star/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/star/exonInfo.tab", + "references/GRCh38/gencode_v46/star/geneInfo.tab", + "references/GRCh38/gencode_v46/star/genomeParameters.txt", + "references/GRCh38/gencode_v46/star/sjdbInfo.txt", + "references/GRCh38/gencode_v46/star/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/star/sjdbList.out.tab", + "references/GRCh38/gencode_v46/star/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/AnnotFilterRule.pm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/PFAM.domtblout.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_fusion_annot_lib.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_prot_info_db.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/annotfiltrule_cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/blast_pairs.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_gene_blast_pairs.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_pfam_dat.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/fusion_annot_lib.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_pfam_hits.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/makeblastdb.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2.splice_bed.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2_genome_idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.gene_spans.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.mini.sortu.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome.fa.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome_fai.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.index.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/validate_ctat_genome_lib.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/cancer_splicing_lib", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/cancer_splicing_lib/cancer_splicing.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/pfam_domains.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/refGene.bed", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/refGene.sort.bed.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/refGene.sort.bed.gz.tbi", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cds", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.gene_spans", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mini.sortu", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mm2.splice.bed", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.pep", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.prot_info.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.fai", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.mm2", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ndb", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nhr", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nin", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.njs", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.not", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nsq", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ntf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nto", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Genome", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Log.out", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SA", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SAindex", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/build.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrName.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrNameLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrStart.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/geneInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/genomeParameters.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbInfo.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dat", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.dat.gz", + "star", + "star/test.Aligned.sortedByCoord.out.bam", + "star/test.Aligned.sortedByCoord.out.bam.bai" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:40:36.520194" + }, + "stub test fusionreport": { + "content": [ + 19, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "ARRIBA_ARRIBA": { + "arriba": "2.5.0" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "FUSIONCATCHER_FUSIONCATCHER": { + "fusioncatcher": "1.35" + }, + "FUSIONREPORT_DETECT": { + "fusion_report": "4.0.1" + }, + "FUSIONREPORT_DOWNLOAD": { + "fusion_report": "4.0.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "STARFUSION_BUILD": { + "gunzip": 1.12, + "hmmer": 3.4, + "STAR-Fusion": "1.15.1" + }, + "STARFUSION_DETECT": { + "STAR-Fusion": "1.15.1" + }, + "STAR_GENOMEGENERATE": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "arriba", + "arriba/test.arriba.fusions.discarded.tsv", + "arriba/test.arriba.fusions.tsv", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "fusioncatcher", + "fusioncatcher/test.fusion-genes.txt", + "fusioncatcher/test.log", + "fusioncatcher/test.summary.txt", + "fusionreport", + "fusionreport/test", + "fusionreport/test/AAA_BBB.html", + "fusionreport/test/test.fusionreport.tsv", + "fusionreport/test/test.fusionreport_filtered.tsv", + "fusionreport/test/test.fusions.csv", + "fusionreport/test/test.fusions.json", + "fusionreport/test/test_fusionreport_index.html", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/fusion_report_db", + "references/GRCh38/fusion_report_db/DB-timestamp.txt", + "references/GRCh38/fusion_report_db/cosmic.db", + "references/GRCh38/fusion_report_db/fusion_report.log", + "references/GRCh38/fusion_report_db/fusiongdb2.db", + "references/GRCh38/fusion_report_db/mitelman.db", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai", + "references/GRCh38/gencode_v46/star", + "references/GRCh38/gencode_v46/star/Genome", + "references/GRCh38/gencode_v46/star/Log.out", + "references/GRCh38/gencode_v46/star/SA", + "references/GRCh38/gencode_v46/star/SAindex", + "references/GRCh38/gencode_v46/star/chrLength.txt", + "references/GRCh38/gencode_v46/star/chrName.txt", + "references/GRCh38/gencode_v46/star/chrNameLength.txt", + "references/GRCh38/gencode_v46/star/chrStart.txt", + "references/GRCh38/gencode_v46/star/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/star/exonInfo.tab", + "references/GRCh38/gencode_v46/star/geneInfo.tab", + "references/GRCh38/gencode_v46/star/genomeParameters.txt", + "references/GRCh38/gencode_v46/star/sjdbInfo.txt", + "references/GRCh38/gencode_v46/star/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/star/sjdbList.out.tab", + "references/GRCh38/gencode_v46/star/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/AnnotFilterRule.pm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/PFAM.domtblout.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_fusion_annot_lib.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_prot_info_db.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/annotfiltrule_cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/blast_pairs.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_gene_blast_pairs.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_pfam_dat.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/fusion_annot_lib.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_pfam_hits.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/makeblastdb.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2.splice_bed.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2_genome_idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.gene_spans.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.mini.sortu.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome.fa.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome_fai.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.index.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/validate_ctat_genome_lib.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/pfam_domains.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cds", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.gene_spans", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mini.sortu", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mm2.splice.bed", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.pep", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.prot_info.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.fai", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.mm2", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ndb", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nhr", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nin", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.njs", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.not", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nsq", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ntf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nto", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Genome", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Log.out", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SA", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SAindex", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/build.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrName.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrNameLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrStart.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/geneInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/genomeParameters.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbInfo.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dat", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.dat.gz", + "starfusion", + "starfusion/test.starfusion.abridged.coding_effect.tsv", + "starfusion/test.starfusion.abridged.tsv", + "starfusion/test.starfusion.fusion_predictions.tsv" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:47:10.448091" + }, + "stub test fastp": { + "content": [ + 14, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTP": { + "fastp": "0.24.0" + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "FASTQC_TRIM": { + "fastqc": "0.12.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastp", + "fastp/test.fastp.html", + "fastp/test.fastp.json", + "fastp/test.fastp.log", + "fastp/test_1.fastp.fastq.gz", + "fastp/test_2.fastp.fastq.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "fastqc_for_fastp", + "fastqc_for_fastp/test_trimmed.html", + "fastqc_for_fastp/test_trimmed.zip", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:48:46.423679" + }, + "stub test fusioncatcher": { + "content": [ + 13, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "FUSIONCATCHER_FUSIONCATCHER": { + "fusioncatcher": "1.35" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "fusioncatcher", + "fusioncatcher/test.fusion-genes.txt", + "fusioncatcher/test.log", + "fusioncatcher/test.summary.txt", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:42:09.411678" + }, + "stub test all": { + "content": [ + 31, + { + "AGAT_CONVERTGFF2BED": { + "agat": "v1.5.1" + }, + "ARRIBA_ARRIBA": { + "arriba": "2.5.0" + }, + "BIOAWK": { + "bioawk": 1.0 + }, + "CTATSPLICING_PREPGENOMELIB": { + "ctatsplicing": "0.0.2" + }, + "CTATSPLICING_STARTOCANCERINTRONS": { + "ctat-splicing": "0.0.2" + }, + "FASTP": { + "fastp": "0.24.0" + }, + "FASTQC_RAW": { + "fastqc": "0.12.1" + }, + "FASTQC_TRIM": { + "fastqc": "0.12.1" + }, + "FUSIONCATCHER_FUSIONCATCHER": { + "fusioncatcher": "1.35" + }, + "FUSIONINSPECTOR": { + "FusionInspector": "2.10.0" + }, + "FUSIONREPORT_DETECT": { + "fusion_report": "4.0.1" + }, + "FUSIONREPORT_DOWNLOAD": { + "fusion_report": "4.0.1" + }, + "GATK4_BEDTOINTERVALLIST": { + "gatk4": "4.6.1.0" + }, + "GATK4_CREATESEQUENCEDICTIONARY": { + "gatk4": "4.6.1.0" + }, + "GATK4_MARKDUPLICATES": { + "gatk4": "4.6.1.0", + "samtools": 1.21 + }, + "GENCODE_DOWNLOAD": { + "wget": "1.21.4" + }, + "GFFREAD": { + "gffread": "0.12.7" + }, + "HGNC_DOWNLOAD": { + "wget": "1.21.4" + }, + "PICARD_COLLECTINSERTSIZEMETRICS": { + "picard": "3.3.0" + }, + "PICARD_COLLECTRNASEQMETRICS": { + "picard": "3.3.0" + }, + "SALMON_INDEX": { + "salmon": "1.10.3" + }, + "SALMON_QUANT": { + "salmon": "1.10.3" + }, + "SAMTOOLS_FAIDX": { + "samtools": 1.21 + }, + "STARFUSION_BUILD": { + "gunzip": 1.12, + "hmmer": 3.4, + "STAR-Fusion": "1.15.1" + }, + "STARFUSION_DETECT": { + "STAR-Fusion": "1.15.1" + }, + "STAR_GENOMEGENERATE": { + "star": "2.7.11b", + "samtools": 1.21, + "gawk": "5.1.0" + }, + "STRINGTIE_MERGE": { + "stringtie": "2.2.1" + }, + "STRINGTIE_STRINGTIE": { + "stringtie": "2.2.3" + }, + "UCSC_GTFTOGENEPRED": { + "ucsc": 447 + }, + "Workflow": { + "nf-core/rnafusion": "v4.0.0" + } + }, + [ + "agat", + "agat/Homo_sapiens.GRCh38.46.gtf.bed", + "arriba", + "arriba/test.arriba.fusions.discarded.tsv", + "arriba/test.arriba.fusions.tsv", + "bioawk", + "bioawk/Homo_sapiens.GRCh38.46.gtf_rrna.gtf.gz", + "ctatsplicing", + "ctatsplicing/test.cancer.introns", + "ctatsplicing/test.cancer.introns.prelim", + "ctatsplicing/test.cancer_intron_reads.sorted.bam", + "ctatsplicing/test.cancer_intron_reads.sorted.bam.bai", + "ctatsplicing/test.chckpts", + "ctatsplicing/test.ctat-splicing.igv.html", + "ctatsplicing/test.gene_reads.sorted.sifted.bam", + "ctatsplicing/test.gene_reads.sorted.sifted.bam.bai", + "ctatsplicing/test.igv.tracks", + "ctatsplicing/test.introns", + "ctatsplicing/test.introns.for_IGV.bed", + "fastp", + "fastp/test.fastp.html", + "fastp/test.fastp.json", + "fastp/test.fastp.log", + "fastp/test_1.fastp.fastq.gz", + "fastp/test_2.fastp.fastq.gz", + "fastqc", + "fastqc/test.html", + "fastqc/test.zip", + "fastqc_for_fastp", + "fastqc_for_fastp/test_trimmed.html", + "fastqc_for_fastp/test_trimmed.zip", + "fusioncatcher", + "fusioncatcher/test.fusion-genes.txt", + "fusioncatcher/test.log", + "fusioncatcher/test.summary.txt", + "fusioninspector", + "fusioninspector/test", + "fusioninspector/test/FusionInspector.log", + "fusioninspector/test/IGV_inputs", + "fusioninspector/test/chckpts_dir", + "fusioninspector/test/fi_workdir", + "fusioninspector/test/fi_workdir/test.gtf", + "fusioninspector/test/test.FusionInspector.fusions.abridged.tsv", + "fusioninspector/test/test.FusionInspector.fusions.tsv", + "fusioninspector/test/test.fusion_inspector_web.html", + "fusionreport", + "fusionreport/test", + "fusionreport/test/AAA_BBB.html", + "fusionreport/test/test.fusionreport.tsv", + "fusionreport/test/test.fusionreport_filtered.tsv", + "fusionreport/test/test.fusions.csv", + "fusionreport/test/test.fusions.json", + "fusionreport/test/test_fusionreport_index.html", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_plots", + "multiqc/multiqc_report.html", + "picard", + "picard/test.bai", + "picard/test.bam", + "picard/test.bam.metrics", + "picard/test.cram", + "picard/test.cram.crai", + "picard/test.rna_metrics", + "picard/test_collectinsertsize.pdf", + "picard/test_collectinsertsize.txt", + "pipeline_info", + "pipeline_info/nf_core_rnafusion_software_mqc_versions.yml", + "references", + "references/GRCh38", + "references/GRCh38/fusion_report_db", + "references/GRCh38/fusion_report_db/DB-timestamp.txt", + "references/GRCh38/fusion_report_db/cosmic.db", + "references/GRCh38/fusion_report_db/fusion_report.log", + "references/GRCh38/fusion_report_db/fusiongdb2.db", + "references/GRCh38/fusion_report_db/mitelman.db", + "references/GRCh38/gencode_v46", + "references/GRCh38/gencode_v46/gencode", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.fasta", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.genepred", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.interval_list", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46.gtf.refflat", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.dict", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa", + "references/GRCh38/gencode_v46/gencode/Homo_sapiens.GRCh38.46_dna_primary_assembly.fa.fai", + "references/GRCh38/gencode_v46/salmon", + "references/GRCh38/gencode_v46/salmon/complete_ref_lens.bin", + "references/GRCh38/gencode_v46/salmon/ctable.bin", + "references/GRCh38/gencode_v46/salmon/ctg_offsets.bin", + "references/GRCh38/gencode_v46/salmon/duplicate_clusters.tsv", + "references/GRCh38/gencode_v46/salmon/info.json", + "references/GRCh38/gencode_v46/salmon/mphf.bin", + "references/GRCh38/gencode_v46/salmon/pos.bin", + "references/GRCh38/gencode_v46/salmon/pre_indexing.log", + "references/GRCh38/gencode_v46/salmon/rank.bin", + "references/GRCh38/gencode_v46/salmon/refAccumLengths.bin", + "references/GRCh38/gencode_v46/salmon/ref_indexing.log", + "references/GRCh38/gencode_v46/salmon/reflengths.bin", + "references/GRCh38/gencode_v46/salmon/refseq.bin", + "references/GRCh38/gencode_v46/salmon/seq.bin", + "references/GRCh38/gencode_v46/salmon/versionInfo.json", + "references/GRCh38/gencode_v46/star", + "references/GRCh38/gencode_v46/star/Genome", + "references/GRCh38/gencode_v46/star/Log.out", + "references/GRCh38/gencode_v46/star/SA", + "references/GRCh38/gencode_v46/star/SAindex", + "references/GRCh38/gencode_v46/star/chrLength.txt", + "references/GRCh38/gencode_v46/star/chrName.txt", + "references/GRCh38/gencode_v46/star/chrNameLength.txt", + "references/GRCh38/gencode_v46/star/chrStart.txt", + "references/GRCh38/gencode_v46/star/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/star/exonInfo.tab", + "references/GRCh38/gencode_v46/star/geneInfo.tab", + "references/GRCh38/gencode_v46/star/genomeParameters.txt", + "references/GRCh38/gencode_v46/star/sjdbInfo.txt", + "references/GRCh38/gencode_v46/star/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/star/sjdbList.out.tab", + "references/GRCh38/gencode_v46/star/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/AnnotFilterRule.pm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/PFAM.domtblout.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_fusion_annot_lib.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/_prot_info_db.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/annotfiltrule_cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/blast_pairs.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_gene_blast_pairs.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_pfam_dat.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/cp_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/fusion_annot_lib.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_pfam_hits.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/index_ref_annot_cdna.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/makeblastdb.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2.splice_bed.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/mm2_genome_idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.cdsplus.dfam_masked.fa.idx.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.gene_spans.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.mini.sortu.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_annot.gtf.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome.fa.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/ref_genome_fai.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.cp.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/trans.blast.dat.index.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/__chkpts/validate_ctat_genome_lib.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.dat.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/blast_pairs.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/cancer_splicing_lib", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/cancer_splicing_lib/cancer_splicing.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/fusion_annot_lib.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/pfam_domains.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/refGene.bed", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/refGene.sort.bed.gz", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/refGene.sort.bed.gz.tbi", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdna.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cds", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.cdsplus.fa.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.gene_spans", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mini.sortu", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.gtf.mm2.splice.bed", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.pep", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_annot.prot_info.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.fai", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.mm2", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ndb", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nhr", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nin", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.njs", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.not", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nsq", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.ntf", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.nto", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Genome", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/Log.out", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SA", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/SAindex", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/build.ok", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrName.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrNameLength.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/chrStart.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonGeTrInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/exonInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/geneInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/genomeParameters.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbInfo.txt", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.fromGTF.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/sjdbList.out.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/ref_genome.fa.star.idx/transcriptInfo.tab", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dat", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.align_coords.align_coords.dbm", + "references/GRCh38/gencode_v46/starfusion/ctat_genome_lib_build_dir/trans.blast.dat.gz", + "references/GRCh38/hgnc", + "references/GRCh38/hgnc/HGNC-DB-timestamp.txt", + "references/GRCh38/hgnc/hgnc_complete_set.txt", + "salmon", + "salmon/test", + "salmon/test_lib_format_counts.json", + "salmon/test_meta_info.json", + "star", + "star/test.Aligned.sortedByCoord.out.bam", + "star/test.Aligned.sortedByCoord.out.bam.bai", + "starfusion", + "starfusion/test.starfusion.abridged.coding_effect.tsv", + "starfusion/test.starfusion.abridged.tsv", + "starfusion/test.starfusion.fusion_predictions.tsv", + "stringtie", + "stringtie/[:]", + "stringtie/[:]/stringtie.merged.gtf", + "stringtie/test.ballgown", + "stringtie/test.coverage.gtf", + "stringtie/test.gene.abundance.txt", + "stringtie/test.transcripts.gtf" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.7" + }, + "timestamp": "2025-09-10T15:37:20.367608" + } +} \ No newline at end of file diff --git a/tests/yml/bam.yml b/tests/yml/bam.yml new file mode 100644 index 000000000..345ac7029 --- /dev/null +++ b/tests/yml/bam.yml @@ -0,0 +1,10 @@ +- sample: test + fastq_1: https://github.com/nf-core/test-datasets/raw/81cb45949e75cbb85cbf6c5ec9009ab45b160823/testdata/human/reads_1.fq.gz + fastq_2: https://github.com/nf-core/test-datasets/raw/81cb45949e75cbb85cbf6c5ec9009ab45b160823/testdata/human/reads_2.fq.gz + # bam: https://github.com/nf-core/test-datasets/raw/81cb45949e75cbb85cbf6c5ec9009ab45b160823/testdata/human/test.Aligned.sortedByCoord.out.bam + # bai: https://github.com/nf-core/test-datasets/raw/81cb45949e75cbb85cbf6c5ec9009ab45b160823/testdata/human/test.Aligned.sortedByCoord.out.bam.bai + cram: https://github.com/nf-core/test-datasets/raw/81cb45949e75cbb85cbf6c5ec9009ab45b160823/testdata/human/test.Aligned.sortedByCoord.out.cram + crai: https://github.com/nf-core/test-datasets/raw/81cb45949e75cbb85cbf6c5ec9009ab45b160823/testdata/human/test.Aligned.sortedByCoord.out.cram.crai + junctions: https://github.com/nf-core/test-datasets/raw/81cb45949e75cbb85cbf6c5ec9009ab45b160823/testdata/human/test.Chimeric.out.junction + splice_junctions: https://github.com/nf-core/test-datasets/raw/81cb45949e75cbb85cbf6c5ec9009ab45b160823/testdata/human/test.SJ.out.tab + strandedness: forward diff --git a/tower.yml b/tower.yml index 2edf5a7fe..be938b3cb 100644 --- a/tower.yml +++ b/tower.yml @@ -7,13 +7,25 @@ reports: display: "PDF visualisation of the transcripts involved in predicted fusions" "**/fastp/*fastp.html": display: "Post fastp trimming HTML report" + "**/fastqc/*_fastqc.html": + display: "FastQC HTML report" + "**/fastqc_for_fastp/*_fastqc.html": + display: "FastQC HTML report for trimmed reads" "**/fusioncatcher/*.fusioncatcher.fusion-genes.txt": display: "FusionCatcher identified fusion TXT report" + "**/fusioninspector/*.fusion_inspector_web.html": + display: "FusionInspector web HTML report" "**/fusioninspector/*.FusionInspector.fusions.abridged.tsv": display: "FusionInspector TSV report" "**/fusionreport/*/*_fusionreport_index.html": display: "Fusion-report HTML report" - "**/vcf/*_fusion_data.vcf.gz": + "**/fusionreport/*/*.html": + display: "Individual fusion report HTML files" + "**/pipeline_info/execution_report_*.html": + display: "Pipeline execution report HTML" + "**/pipeline_info/pipeline_dag_*.html": + display: "Pipeline DAG HTML" + "**/vcf/*_fusion_data.vcf": display: "Collected statistics on each fusion fed to FusionInspector in VCF format" "**/picard/*.MarkDuplicates.metrics.txt": display: "Picard: Metrics from CollectRnaMetrics" diff --git a/workflows/build_references.nf b/workflows/build_references.nf deleted file mode 100644 index 7847dd055..000000000 --- a/workflows/build_references.nf +++ /dev/null @@ -1,87 +0,0 @@ -/* -======================================================================================== - IMPORT LOCAL MODULES/SUBWORKFLOWS -======================================================================================== -*/ - -include { ARRIBA_DOWNLOAD } from '../modules/local/arriba/download/main' -include { ENSEMBL_DOWNLOAD } from '../modules/local/ensembl/main' -include { FUSIONCATCHER_DOWNLOAD } from '../modules/local/fusioncatcher/download/main' -include { FUSIONREPORT_DOWNLOAD } from '../modules/local/fusionreport/download/main' -include { HGNC_DOWNLOAD } from '../modules/local/hgnc/main' -include { STARFUSION_BUILD } from '../modules/local/starfusion/build/main' -include { STARFUSION_DOWNLOAD } from '../modules/local/starfusion/download/main' -include { GTF_TO_REFFLAT } from '../modules/local/uscs/custom_gtftogenepred/main' -include { RRNA_TRANSCRIPTS } from '../modules/local/rrnatranscripts/main' -include { CONVERT2BED } from '../modules/local/convert2bed/main' -/* -======================================================================================== - IMPORT NF-CORE MODULES/SUBWORKFLOWS -======================================================================================== -*/ - -include { SAMTOOLS_FAIDX } from '../modules/nf-core/samtools/faidx/main' -include { STAR_GENOMEGENERATE } from '../modules/nf-core/star/genomegenerate/main' -include { GATK4_CREATESEQUENCEDICTIONARY } from '../modules/nf-core/gatk4/createsequencedictionary/main' -include { GATK4_BEDTOINTERVALLIST } from '../modules/nf-core/gatk4/bedtointervallist/main' - -/* -======================================================================================== - RUN MAIN WORKFLOW -======================================================================================== -*/ - -workflow BUILD_REFERENCES { - - def fake_meta = [:] - fake_meta.id = "Homo_sapiens.${params.genome}.${params.ensembl_version}" - ENSEMBL_DOWNLOAD( params.ensembl_version, params.genome, fake_meta ) - HGNC_DOWNLOAD( ) - - - SAMTOOLS_FAIDX(ENSEMBL_DOWNLOAD.out.fasta, [[],[]]) - GATK4_CREATESEQUENCEDICTIONARY(ENSEMBL_DOWNLOAD.out.fasta) - - RRNA_TRANSCRIPTS(ENSEMBL_DOWNLOAD.out.gtf) - CONVERT2BED(RRNA_TRANSCRIPTS.out.rrna_gtf) - - GATK4_BEDTOINTERVALLIST(CONVERT2BED.out.bed, GATK4_CREATESEQUENCEDICTIONARY.out.dict) - - - if (params.starindex || params.all || params.starfusion || params.arriba) { - STAR_GENOMEGENERATE( ENSEMBL_DOWNLOAD.out.fasta, ENSEMBL_DOWNLOAD.out.gtf ) - } - - if (params.arriba || params.all) { - ARRIBA_DOWNLOAD() - } - - if (params.fusioncatcher || params.all) { - FUSIONCATCHER_DOWNLOAD() - } - - if (params.starfusion || params.all) { - if (params.starfusion_build){ - STARFUSION_BUILD( ENSEMBL_DOWNLOAD.out.fasta, ENSEMBL_DOWNLOAD.out.chrgtf ) - } else { - STARFUSION_DOWNLOAD() - } - } - - if (params.starfusion_build){ - GTF_TO_REFFLAT(ENSEMBL_DOWNLOAD.out.chrgtf) - } else { - GTF_TO_REFFLAT(STARFUSION_DOWNLOAD.out.chrgtf) - } - - if (params.fusionreport || params.all) { - FUSIONREPORT_DOWNLOAD( params.cosmic_username, params.cosmic_passwd ) - } - -} - -/* -======================================================================================== - THE END -======================================================================================== -*/ diff --git a/workflows/rnafusion.nf b/workflows/rnafusion.nf index 7483f1be5..d8568d990 100644 --- a/workflows/rnafusion.nf +++ b/workflows/rnafusion.nf @@ -4,61 +4,29 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -include { FASTQC } from '../modules/nf-core/fastqc/main' -include { MULTIQC } from '../modules/nf-core/multiqc/main' -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_rnafusion_pipeline' -include { paramsSummaryLog; paramsSummaryMap } from 'plugin/nf-validation' - -ch_chrgtf = params.starfusion_build ? Channel.fromPath(params.chrgtf).map { it -> [[id:it.Name], it] }.collect() : Channel.fromPath("${params.starfusion_ref}/ref_annot.gtf").map { it -> [[id:it.Name], it] }.collect() -ch_starindex_ref = params.starfusion_build ? Channel.fromPath(params.starindex_ref).map { it -> [[id:it.Name], it] }.collect() : Channel.fromPath("${params.starfusion_ref}/ref_genome.fa.star.idx").map { it -> [[id:it.Name], it] }.collect() -ch_starindex_ensembl_ref = Channel.fromPath(params.starindex_ref).map { it -> [[id:it.Name], it] }.collect() -ch_refflat = params.starfusion_build ? Channel.fromPath(params.refflat).map { it -> [[id:it.Name], it] }.collect() : Channel.fromPath("${params.ensembl_ref}/ref_annot.gtf.refflat").map { it -> [[id:it.Name], it] }.collect() -ch_rrna_interval = params.starfusion_build ? Channel.fromPath(params.rrna_intervals).map { it -> [[id:it.Name], it] }.collect() : Channel.fromPath("${params.ensembl_ref}/ref_annot.interval_list").map { it -> [[id:it.Name], it] }.collect() -ch_fusionreport_ref = Channel.fromPath(params.fusionreport_ref).map { it -> [[id:it.Name], it] }.collect() -ch_arriba_ref_blacklist = Channel.fromPath(params.arriba_ref_blacklist).map { it -> [[id:it.Name], it] }.collect() -ch_arriba_ref_known_fusions = Channel.fromPath(params.arriba_ref_known_fusions).map { it -> [[id:it.Name], it] }.collect() -ch_arriba_ref_protein_domains = Channel.fromPath(params.arriba_ref_protein_domains).map { it -> [[id:it.Name], it] }.collect() -ch_arriba_ref_cytobands = Channel.fromPath(params.arriba_ref_cytobands).map { it -> [[id:it.Name], it] }.collect() -ch_hgnc_ref = Channel.fromPath(params.hgnc_ref).map { it -> [[id:it.Name], it] }.collect() -ch_hgnc_date = Channel.fromPath(params.hgnc_date).map { it -> [[id:it.Name], it] }.collect() -ch_fasta = Channel.fromPath(params.fasta).map { it -> [[id:it.Name], it] }.collect() -ch_gtf = Channel.fromPath(params.gtf).map { it -> [[id:it.Name], it] }.collect() -ch_transcript = Channel.fromPath(params.transcript).map { it -> [[id:it.Name], it] }.collect() -ch_fai = Channel.fromPath(params.fai).map { it -> [[id:it.Name], it] }.collect() - - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - IMPORT LOCAL MODULES/SUBWORKFLOWS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -// -// SUBWORKFLOW: Consisting of a mix of local and nf-core/modules -// - -include { TRIM_WORKFLOW } from '../subworkflows/local/trim_workflow' -include { ARRIBA_WORKFLOW } from '../subworkflows/local/arriba_workflow' +include { BUILD_REFERENCES } from '../subworkflows/local/build_references' +include { CAT_FASTQ } from '../modules/nf-core/cat/fastq/main' +include { FASTQ_FASTQC_UMITOOLS_FASTP } from '../subworkflows/nf-core/fastq_fastqc_umitools_fastp/main' include { QC_WORKFLOW } from '../subworkflows/local/qc_workflow' -include { STARFUSION_WORKFLOW } from '../subworkflows/local/starfusion_workflow' -include { STRINGTIE_WORKFLOW } from '../subworkflows/local/stringtie_workflow' +include { STARFUSION_DETECT } from '../modules/nf-core/starfusion/detect/main' +include { BAM_STRINGTIE_MERGE } from '../subworkflows/nf-core/bam_stringtie_merge/main' include { FUSIONCATCHER_WORKFLOW } from '../subworkflows/local/fusioncatcher_workflow' include { FUSIONINSPECTOR_WORKFLOW } from '../subworkflows/local/fusioninspector_workflow' -include { FUSIONREPORT_WORKFLOW } from '../subworkflows/local/fusionreport_workflow' +include { FUSIONREPORT_DETECT } from '../modules/nf-core/fusionreport/detect/main' +include { FASTQC } from '../modules/nf-core/fastqc/main' +include { MULTIQC } from '../modules/nf-core/multiqc/main' +include { STAR_ALIGN } from '../modules/nf-core/star/align/main' +include { SALMON_QUANT } from '../modules/nf-core/salmon/quant/main' +include { SAMTOOLS_CONVERT } from '../modules/nf-core/samtools/convert/main' +include { SAMTOOLS_INDEX } from '../modules/nf-core/samtools/index/main' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { FASTQ_ALIGN_STAR } from '../subworkflows/nf-core/fastq_align_star' +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_rnafusion_pipeline' include { validateInputSamplesheet } from '../subworkflows/local/utils_nfcore_rnafusion_pipeline' - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - IMPORT NF-CORE MODULES/SUBWORKFLOWS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -// -// MODULE: Installed directly from nf-core/modules -// -include { CAT_FASTQ } from '../modules/nf-core/cat/fastq/main' +include { ARRIBA_ARRIBA } from '../modules/nf-core/arriba/arriba/main' +include { CTATSPLICING_STARTOCANCERINTRONS } from '../modules/nf-core/ctatsplicing/startocancerintrons' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -68,190 +36,430 @@ include { CAT_FASTQ } from '../modules/nf-core/cat/fastq/main' workflow RNAFUSION { + take: - ch_samplesheet + ch_samplesheet_input // channel: samplesheet read in from --input + tools // list: a list of tools to run main: - ch_versions = Channel.empty() - ch_multiqc_files = Channel.empty() + def ch_versions = Channel.empty() + def ch_multiqc_files = Channel.empty() // - // Create channel from input file provided through params.input + // Create references if necessary // - Channel - .fromSamplesheet("input") - .map { - meta, fastq_1, fastq_2, strandedness -> - if (!fastq_2) { - return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] - } else { - return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] - } + + BUILD_REFERENCES(tools) + ch_versions = ch_versions.mix(BUILD_REFERENCES.out.versions) + + if (!params.references_only) { + + def ch_input = ch_samplesheet_input.map { meta, fastqs, bam, bai, cram, crai, junctions, splice_junctions -> + def align = false + // Check if we need split junctions + if (tools.contains("ctatsplicing") && !splice_junctions) { + align = true + } + + // Check if we need junctions + if (tools.intersect(["starfusion", "ctatsplicing"]) && !junctions) { + align = true + } + + // Check if we need BAM or CRAM files + if (tools.intersect(["ctatsplicing", "arriba", "stringtie", "fusioninspector"]) && !bam && !cram) { + align = true + } + + // Check if there are fastqs when we need to align + if (align && !fastqs) { + error("No fastq files found for ${meta.id}. Either provide fastq files to align or provide a BAM/CRAM file, a junctions file and a split junctions file.") + } + def new_meta = meta + [align:align, seq_center:meta.seq_center ?: params.seq_center, seq_platform:meta.seq_platform ?: params.seq_platform] + return [ new_meta, fastqs, bam, bai, cram, crai, junctions, splice_junctions ] } - .groupTuple() - .map { - validateInputSamplesheet(it) + .tap { ch_samplesheet } + .multiMap { meta, fastqs, bam, bai, cram, crai, junctions, splice_junctions -> + fastqs: [ meta, fastqs ] + bam: [ meta, bam, bai ] + cram: [ meta, cram, crai ] + junctions: [ meta, junctions ] + splice_junctions: [ meta, splice_junctions ] } - .branch { - meta, fastqs -> - single : fastqs.size() == 1 - return [ meta, fastqs.flatten() ] - multiple: fastqs.size() > 1 - return [ meta, fastqs.flatten() ] + + // Define which fastqs need to be processes (all analysis that's not aligning) + def fastq_tools = ["salmon", "fusioninspector", "fusioncatcher"] + selected_fastq_tools = tools.intersect(fastq_tools) + def ch_fastqs_to_process = ch_input.fastqs.branch { meta, fastqs -> + if (!fastqs && selected_fastq_tools) { + log.warn("Fastq files not found for sample '${meta.id}'. Skipping the following tools for this sample: ${selected_fastq_tools.join(', ')}") + } + found: fastqs + not_found: !fastqs } - .set { ch_fastq } - // - // MODULE: Concatenate FastQ files from same sample if required - // - CAT_FASTQ ( - ch_fastq.multiple - ) - .reads - .mix(ch_fastq.single) - .set { ch_cat_fastq } - ch_versions = ch_versions.mix(CAT_FASTQ.out.versions) + // Convert CRAM to BAM when needed (when tools that don't support CRAM are used and when the sample isn't aligned) + def only_bam_tools = ["ctatsplicing", "stringtie", "fusioninspector"] + def ch_aligned_inputs = ch_input.bam.filter { meta, file, _bai -> file && !meta.align } + if(tools.intersect(only_bam_tools)) { + SAMTOOLS_CONVERT( + ch_input.cram.filter { meta, file, _crai -> file && !meta.align }, + BUILD_REFERENCES.out.fasta, + BUILD_REFERENCES.out.fai + ) + ch_aligned_inputs = ch_aligned_inputs.mix( + SAMTOOLS_CONVERT.out.bam.join(SAMTOOLS_CONVERT.out.bai, failOnMismatch:true, failOnDuplicate:true) + ) + } else { + ch_aligned_inputs = ch_aligned_inputs.mix(ch_input.cram.filter { meta, file, _crai -> file && !meta.align }) + } - // - // MODULE: Run FastQC - // - FASTQC ( - ch_cat_fastq - ) - ch_multiqc_files = ch_multiqc_files.mix(FASTQC.out.zip.collect{it[1]}) - ch_versions = ch_versions.mix(FASTQC.out.versions) - - TRIM_WORKFLOW ( - ch_cat_fastq - ) - ch_reads_fusioncatcher = TRIM_WORKFLOW.out.ch_reads_fusioncatcher - ch_reads_all = TRIM_WORKFLOW.out.ch_reads_all - ch_versions = ch_versions.mix(TRIM_WORKFLOW.out.versions) + // + // SUBWORKFLOW: Read QC and trimming (nf-core) + // + + def ch_reads = Channel.empty() + + // adapter_fasta as a channel (or empty if not provided) + def ch_adapter_fasta = params.adapter_fasta ? Channel.fromPath(params.adapter_fasta).collect() : [] + + // disable umi usage in this subworkflow for this pipeline + def with_umi = false + def skip_umi_extract = false + def umi_discard_read = 0 + + // if 'fastp' isn't selected, we still run the subworkflow but skip trimming + def skip_trimming = (!tools.contains("fastp")) + + // optional fastp output controls + minimum reads after trimming + def save_trimmed_fail = params.save_trimmed_fail ?: false + def save_merged = params.save_merged ?: false + def min_trimmed_reads = (params.min_trimmed_reads ?: 1) as Integer + + FASTQ_FASTQC_UMITOOLS_FASTP( + ch_fastqs_to_process.found, // reads: [ val(meta), [fastqs] ] + params.skip_qc, // skip_fastqc + with_umi, // with_umi + skip_umi_extract, // skip_umi_extract + umi_discard_read, // umi_discard_read (0,1,2) + skip_trimming, // skip_trimming + ch_adapter_fasta, // adapter_fasta + save_trimmed_fail, // save_trimmed_fail + save_merged, // save_merged + min_trimmed_reads // min_trimmed_reads + ) + + ch_reads = FASTQ_FASTQC_UMITOOLS_FASTP.out.reads + ch_versions = ch_versions.mix(FASTQ_FASTQC_UMITOOLS_FASTP.out.versions) + + ch_sbwf_fastp_mqc = Channel.empty() + .mix(FASTQ_FASTQC_UMITOOLS_FASTP.out.fastqc_raw_zip.map { it[1] }) + .mix(FASTQ_FASTQC_UMITOOLS_FASTP.out.fastqc_trim_zip.map { it[1] }) + .mix(FASTQ_FASTQC_UMITOOLS_FASTP.out.trim_html.map { it[1] }) + .mix(FASTQ_FASTQC_UMITOOLS_FASTP.out.trim_json.map { it[1] }) + .ifEmpty([]) + + ch_multiqc_files = ch_multiqc_files.mix(ch_sbwf_fastp_mqc) + + // + // MODULE: SALMON_QUANT + // + + if(tools.contains("salmon") && !params.skip_qc) { + SALMON_QUANT( + ch_reads, + BUILD_REFERENCES.out.salmon_index, + BUILD_REFERENCES.out.gtf.map{ it -> it[1] }, + [], + false, + 'A' + ) + ch_multiqc_files = ch_multiqc_files.mix(SALMON_QUANT.out.json_info.collect{it[1]}) + ch_versions = ch_versions.mix(SALMON_QUANT.out.versions) + } + + // + // SUBWORKFLOW: Run STAR alignment + // + + // Define which fastqs need to be aligned + def ch_fastqs_to_align = ch_reads + .filter { meta, _fastqs -> meta.align } + + // Add the alignment files to the correct channel if their fastqs aren't aligned + def ch_aligned_reads = ch_aligned_inputs + def ch_star_junctions = ch_input.junctions.filter { meta, file -> file && !meta.align } + def ch_star_splice_junctions = ch_input.splice_junctions.filter { meta, file -> file && !meta.align } + if(tools.intersect(["ctatsplicing", "arriba", "starfusion", "stringtie"])) { + FASTQ_ALIGN_STAR( + ch_fastqs_to_align, + BUILD_REFERENCES.out.starindex_ref, + BUILD_REFERENCES.out.gtf, + params.star_ignore_sjdbgtf, + ch_fastqs_to_align.map { meta, _fastqs -> meta.seq_platform }, + ch_fastqs_to_align.map { meta, _fastqs -> meta.seq_center }, + BUILD_REFERENCES.out.fasta, + [[:], []] + ) + SAMTOOLS_INDEX(FASTQ_ALIGN_STAR.out.bam_sorted_aligned) + ch_bam_bai = FASTQ_ALIGN_STAR.out.bam_sorted_aligned + .join(SAMTOOLS_INDEX.out.bai, failOnMismatch:true, failOnDuplicate:true) + ch_versions = ch_versions.mix(FASTQ_ALIGN_STAR.out.versions) + ch_aligned_reads = ch_aligned_reads.mix(ch_bam_bai) + ch_star_junctions = ch_star_junctions.mix(FASTQ_ALIGN_STAR.out.junctions) + ch_star_splice_junctions = ch_star_splice_junctions.mix(FASTQ_ALIGN_STAR.out.spl_junc_tabs) + ch_multiqc_files = ch_multiqc_files.mix(FASTQ_ALIGN_STAR.out.log_final.collect{it[1]}.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(FASTQ_ALIGN_STAR.out.gene_count.collect{it[1]}.ifEmpty([])) + } + + // + // MODULE: Run CTAT-SPLICING + // + + if(tools.contains("ctatsplicing")) { + def ch_ctatsplicing_input = ch_star_splice_junctions + .join(ch_star_junctions, failOnMismatch:true, failOnDuplicate:true) + .join(ch_aligned_reads, failOnMismatch:true, failOnDuplicate:true) + + CTATSPLICING_STARTOCANCERINTRONS( + ch_ctatsplicing_input, + BUILD_REFERENCES.out.starfusion_ref + ) + + ch_versions = ch_versions.mix(CTATSPLICING_STARTOCANCERINTRONS.out.versions.first()) + } + + // + // MODULE: Run Arriba + // + + // TODO: improve how params.arriba_fusions would avoid running arriba module. Maybe imputed from samplesheet? + + def fusions_created = false + def ch_arriba_fusions = ch_samplesheet.map { it -> [it[0], []] } // Set arriba fusions to empty by default + + if (tools.contains("arriba")) { + fusions_created = true + + if (params.arriba_fusions) { + ch_arriba_fusions = ch_aligned_reads.map { meta, _bam, _bai -> meta } + .combine(Channel.value(file(params.arriba_fusions, checkIfExists: true))) + .map { meta, fusion_file -> [meta, fusion_file] } + } else { + ARRIBA_ARRIBA( + ch_aligned_reads.map { meta, bam, _bai -> [meta, bam] }, + BUILD_REFERENCES.out.fasta, + BUILD_REFERENCES.out.gtf, + BUILD_REFERENCES.out.arriba_ref_blacklist, + BUILD_REFERENCES.out.arriba_ref_known_fusions, + BUILD_REFERENCES.out.arriba_ref_cytobands, + BUILD_REFERENCES.out.arriba_ref_protein_domains + ) + ch_arriba_fusions = ARRIBA_ARRIBA.out.fusions + ch_versions = ch_versions.mix(ARRIBA_ARRIBA.out.versions) + } + } + + + // + // MODULE: Run StarFusion + // + + def ch_starfusion_fusions = ch_samplesheet.map { it -> [it[0], []] } // Set starfusion fusions to empty by default + if (tools.contains("starfusion")) { + fusions_created = true + + if (params.starfusion_fusions) { + def fusions = file(params.starfusion_fusions, checkIfExists:true) + ch_starfusion_fusions = ch_star_junctions.map { meta, _junc -> [ meta, fusions ] } + } else { + STARFUSION_DETECT( + ch_star_junctions.map { meta, junc -> [ meta, [], junc ] }, + BUILD_REFERENCES.out.starfusion_ref.map { it -> it[1] } + ) + ch_versions = ch_versions.mix(STARFUSION_DETECT.out.versions) + ch_starfusion_fusions = STARFUSION_DETECT.out.fusions + } + } - // - // SUBWORKFLOW: Run STAR alignment and Arriba - // - ARRIBA_WORKFLOW ( - ch_reads_all, - ch_gtf, - ch_fasta, - ch_starindex_ensembl_ref, - ch_arriba_ref_blacklist, - ch_arriba_ref_known_fusions, - ch_arriba_ref_protein_domains - ) - ch_versions = ch_versions.mix(ARRIBA_WORKFLOW.out.versions) - - -//Run STAR fusion - STARFUSION_WORKFLOW ( - ch_reads_all, - ch_chrgtf, - ch_starindex_ref, - ch_fasta - ) - ch_versions = ch_versions.mix(STARFUSION_WORKFLOW.out.versions) - - -//Run fusioncatcher - FUSIONCATCHER_WORKFLOW ( - ch_reads_fusioncatcher - ) - ch_versions = ch_versions.mix(FUSIONCATCHER_WORKFLOW.out.versions) - - -//Run stringtie - STRINGTIE_WORKFLOW ( - STARFUSION_WORKFLOW.out.ch_bam_sorted, - ch_chrgtf - ) - ch_versions = ch_versions.mix(STRINGTIE_WORKFLOW.out.versions) - - - //Run fusion-report - FUSIONREPORT_WORKFLOW ( - ch_reads_all, - ch_fusionreport_ref, - ARRIBA_WORKFLOW.out.fusions, - STARFUSION_WORKFLOW.out.fusions, - FUSIONCATCHER_WORKFLOW.out.fusions - ) - ch_versions = ch_versions.mix(FUSIONREPORT_WORKFLOW.out.versions) - - - //Run fusionInpector - FUSIONINSPECTOR_WORKFLOW ( - ch_reads_all, - FUSIONREPORT_WORKFLOW.out.fusion_list, - FUSIONREPORT_WORKFLOW.out.fusion_list_filtered, - FUSIONREPORT_WORKFLOW.out.report, - FUSIONREPORT_WORKFLOW.out.csv, - STARFUSION_WORKFLOW.out.ch_bam_sorted_indexed, - ch_chrgtf, - ch_arriba_ref_protein_domains, - ch_arriba_ref_cytobands, - ch_hgnc_ref, - ch_hgnc_date - ) - ch_versions = ch_versions.mix(FUSIONINSPECTOR_WORKFLOW.out.versions) - - - //QC - QC_WORKFLOW ( - STARFUSION_WORKFLOW.out.ch_bam_sorted, - STARFUSION_WORKFLOW.out.ch_bam_sorted_indexed, - ch_chrgtf, - ch_refflat, - ch_fasta, - ch_fai, - ch_rrna_interval - ) - ch_versions = ch_versions.mix(QC_WORKFLOW.out.versions) + // + // SUBWORKFLOW: Run FusionCatcher + // + + def ch_fusioncatcher_fusions = ch_samplesheet.map { it -> [it[0], []] } // Set fusioncatcher fusions to empty by default + if(tools.contains("fusioncatcher")) { + fusions_created = true + fusioncatcher_trimming = params.trim_tail_fusioncatcher != 0 + FUSIONCATCHER_WORKFLOW ( + ch_reads, + fusioncatcher_trimming, + params.adapter_fasta, + BUILD_REFERENCES.out.fusioncatcher_ref, // channel [ meta, path ] + params.fusioncatcher_fusions + ) + ch_versions = ch_versions.mix(FUSIONCATCHER_WORKFLOW.out.versions) + // Add output of fusioncatcher to a channel + add empty entries for the samples that could not be run + ch_fusioncatcher_fusions = FUSIONCATCHER_WORKFLOW.out.fusions.mix(ch_fastqs_to_process.not_found) + } + + // + // SUBWORKFLOW: Run Stringtie + // + + if(tools.contains("stringtie")) { + BAM_STRINGTIE_MERGE ( + ch_aligned_reads.map { meta, bam, _bai -> [meta, bam]}, + BUILD_REFERENCES.out.gtf + ) + ch_versions = ch_versions.mix(BAM_STRINGTIE_MERGE.out.versions) + } + + // + // SUBWORKFLOW: Run FusionReport + // + + def ch_fusion_list = Channel.empty() + def ch_fusion_list_filtered = Channel.empty() + def ch_fusionreport_report = Channel.empty() + def ch_fusionreport_csv = Channel.empty() + if (!params.skip_vis && tools.contains("fusionreport")) { + if (!fusions_created) { + error("Could not find any fusion files. Please generate some with `--tools arriba`, `--tools starfusion` and/or `--tools fusioncatcher`") + } + + def ch_fusions = ch_arriba_fusions + .join(ch_starfusion_fusions, failOnMismatch:true, failOnDuplicate:true) + .join(ch_fusioncatcher_fusions, failOnMismatch:true, failOnDuplicate:true) + + FUSIONREPORT_DETECT( + ch_fusions, + BUILD_REFERENCES.out.fusionreport_ref, + params.tools_cutoff + ) + + ch_versions = ch_versions.mix(FUSIONREPORT_DETECT.out.versions) + ch_fusion_list = FUSIONREPORT_DETECT.out.fusion_list + ch_fusion_list_filtered = FUSIONREPORT_DETECT.out.fusion_list_filtered + ch_fusionreport_report = FUSIONREPORT_DETECT.out.report + ch_fusionreport_csv = FUSIONREPORT_DETECT.out.csv + } else if(params.fusioninspector_fusions) { + def input_fusions = file(params.fusioninspector_fusions, checkIfExists:true) + ch_fusion_list = ch_reads.map { it -> [ it[0], input_fusions ] } + ch_fusion_list_filtered = ch_fusion_list + ch_fusionreport_csv = null + ch_fusionreport_report = null + } else if(tools.contains("fusioninspector")) { + error("Could not find any valid fusions for fusioninspector input. Please provide some via --fusioninspector_fusions or generate them with `--tools arriba`, `--tools starfusion` and/or `--tools fusioncatcher` with --skip_vis disabled and `--tools fusionreport enabled") + } + + // + // SUBWORKFLOW: Run FusionInspector + // + + if (tools.contains("fusioninspector")) { + FUSIONINSPECTOR_WORKFLOW ( + ch_reads, + ch_fusion_list, + ch_fusion_list_filtered, + ch_fusionreport_report, + ch_fusionreport_csv, + ch_aligned_reads, + BUILD_REFERENCES.out.gtf, + BUILD_REFERENCES.out.arriba_ref_protein_domains, + BUILD_REFERENCES.out.arriba_ref_cytobands, + BUILD_REFERENCES.out.hgnc_ref, + BUILD_REFERENCES.out.hgnc_date, + BUILD_REFERENCES.out.starfusion_ref, + params.skip_vis, + params.skip_vcf, + params.tools_cutoff, + params.whitelist + ) + ch_versions = ch_versions.mix(FUSIONINSPECTOR_WORKFLOW.out.versions) + ch_multiqc_files = ch_multiqc_files.mix(FUSIONINSPECTOR_WORKFLOW.out.ch_arriba_visualisation.collect{it[1]}.ifEmpty([])) + } + + // + // SUBWORKFLOW: Run QC + // + + if(!params.skip_qc) { + QC_WORKFLOW ( + ch_aligned_reads.map { meta, bam, _bai -> [meta, bam] }, + BUILD_REFERENCES.out.refflat, + BUILD_REFERENCES.out.fasta, + BUILD_REFERENCES.out.fai, + BUILD_REFERENCES.out.rrna_interval + ) + ch_versions = ch_versions.mix(QC_WORKFLOW.out.versions) + ch_multiqc_files = ch_multiqc_files.mix(QC_WORKFLOW.out.rnaseq_metrics.collect{it[1]}) + ch_multiqc_files = ch_multiqc_files.mix(QC_WORKFLOW.out.duplicate_metrics.collect{it[1]}) + ch_multiqc_files = ch_multiqc_files.mix(QC_WORKFLOW.out.insertsize_metrics.collect{it[1]}) + } + } // // 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) - .set { ch_collated_versions } + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'nf_core_' + 'rnafusion_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 = Channel.empty() - 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)) - ch_multiqc_files = ch_multiqc_files.mix(FASTQC.out.zip.collect{it[1]}.ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(TRIM_WORKFLOW.out.ch_fastp_html.collect{it[1]}.ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(TRIM_WORKFLOW.out.ch_fastp_json.collect{it[1]}.ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(TRIM_WORKFLOW.out.ch_fastqc_trimmed.collect{it[1]}.ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(STARFUSION_WORKFLOW.out.star_stats.collect{it[1]}.ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(STARFUSION_WORKFLOW.out.star_gene_count.collect{it[1]}.ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(QC_WORKFLOW.out.rnaseq_metrics.collect{it[1]}.ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(QC_WORKFLOW.out.duplicate_metrics.collect{it[1]}.ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(QC_WORKFLOW.out.insertsize_metrics.collect{it[1]}.ifEmpty([])) - ch_multiqc_files = ch_multiqc_files.mix(FUSIONINSPECTOR_WORKFLOW.out.ch_arriba_visualisation.collect{it[1]}.ifEmpty([])) - - MULTIQC ( - ch_multiqc_files.collect(), - ch_multiqc_config.toList(), - ch_multiqc_custom_config.toList(), - ch_multiqc_logo.toList() - ) + + def ch_multiqc_output = Channel.empty() + if(!params.skip_qc && !params.references_only) { + 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_files = ch_multiqc_files.mix( + ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) + ch_multiqc_custom_methods_description = params.multiqc_methods_description ? + file(params.multiqc_methods_description, checkIfExists: true) : + file("$projectDir/assets/methods_description_template.yml", checkIfExists: true) + ch_methods_description = Channel.value( + methodsDescriptionText(ch_multiqc_custom_methods_description)) + + ch_multiqc_files = ch_multiqc_files.mix(ch_collated_versions) + ch_multiqc_files = ch_multiqc_files.mix( + ch_methods_description.collectFile( + name: 'methods_description_mqc.yaml', + sort: true + ) + ) + + MULTIQC ( + ch_multiqc_files.collect(), + ch_multiqc_config.toList(), + ch_multiqc_custom_config.toList(), + ch_multiqc_logo.toList(), + [], + [] + ) + ch_multiqc_output = MULTIQC.out.report.toList() + } + emit: - multiqc_report = MULTIQC.out.report.toList() // channel: /path/to/multiqc_report.html - versions = ch_versions // channel: [ path(versions.yml) ] + multiqc_report = ch_multiqc_output // channel: /path/to/multiqc_report.html + versions = ch_versions // channel: [ path(versions.yml) ] }