diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 4ecfbfe3..b290e090 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -10,15 +10,7 @@ "vscode": { // Set *default* container specific settings.json values on container create. "settings": { - "python.defaultInterpreterPath": "/opt/conda/bin/python", - "python.linting.enabled": true, - "python.linting.pylintEnabled": true, - "python.formatting.autopep8Path": "/opt/conda/bin/autopep8", - "python.formatting.yapfPath": "/opt/conda/bin/yapf", - "python.linting.flake8Path": "/opt/conda/bin/flake8", - "python.linting.pycodestylePath": "/opt/conda/bin/pycodestyle", - "python.linting.pydocstylePath": "/opt/conda/bin/pydocstyle", - "python.linting.pylintPath": "/opt/conda/bin/pylint" + "python.defaultInterpreterPath": "/opt/conda/bin/python" }, // Add the IDs of extensions you want installed when the container is created. diff --git a/.editorconfig b/.editorconfig index 9b990088..0e269142 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,7 +8,7 @@ trim_trailing_whitespace = true indent_size = 4 indent_style = space -[*.{md,yml,yaml,html,css,scss,js}] +[*.{md,yml,yaml,html,css,scss,js,R,Rmd}] indent_size = 2 # These files are edited and tested upstream in nf-core/modules @@ -18,15 +18,24 @@ end_of_line = unset insert_final_newline = unset trim_trailing_whitespace = unset indent_style = unset -indent_size = 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] +# ignore python and markdown +[*.{py,md}] indent_style = unset -# ignore python -[*.{py}] -indent_style = unset +# ignore ro-crate metadata files +[**/ro-crate-metadata.json] +insert_final_newline = unset + +# Follow tidyverse style for R +[*.{R,Rmd}] +indent_size = 2 diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 74553c01..2a281c08 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# nf-core/nascent: Contributing Guidelines +# `nf-core/nascent`: Contributing Guidelines Hi there! Many thanks for taking an interest in improving nf-core/nascent. @@ -9,9 +9,8 @@ Please use the pre-filled template to save time. However, don't be put off by this template - other more general issues and suggestions are welcome! Contributions to the code are even more welcome ;) -:::info -If you need help using or modifying nf-core/nascent then the best place to ask is on the nf-core Slack [#nascent](https://nfcore.slack.com/channels/nascent) channel ([join our Slack here](https://nf-co.re/join/slack)). -::: +> [!NOTE] +> If you need help using or modifying nf-core/nascent then the best place to ask is on the nf-core Slack [#nascent](https://nfcore.slack.com/channels/nascent) channel ([join our Slack here](https://nf-co.re/join/slack)). ## Contribution workflow @@ -20,15 +19,18 @@ If you'd like to write some code for nf-core/nascent, the standard workflow is a 1. Check that there isn't already an issue about your idea in the [nf-core/nascent issues](https://github.com/nf-core/nascent/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/nascent repository](https://github.com/nf-core/nascent) 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/). ## Tests -You can optionally test your changes by running the pipeline locally. Then it is recommended to use the `debug` profile to -receive warnings about process selectors and other debug info. Example: `nextflow run . -profile debug,test,docker --outdir `. +You have the option to test your changes locally by running the pipeline. For receiving warnings about process selectors and other `debug` information, it is recommended to use the debug profile. Execute all the tests with the following command: + +```bash +nf-test test --profile debug,test,docker --verbose +``` When you create a pull request with changes, [GitHub Actions](https://github.com/features/actions) will run automatic tests. Typically, pull-requests are only fully reviewed when these tests are passing, though of course we can help out before then. @@ -38,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. @@ -53,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 @@ -63,17 +65,17 @@ For further information/help, please consult the [nf-core/nascent documentation] ## Pipeline contribution conventions -To make the nf-core/nascent 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/nascent` 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`. @@ -82,15 +84,15 @@ If you wish to contribute a new step, please use the following coding standards: ### Default values -Parameters should be initialised / defined with default values in `nextflow.config` under the `params` scope. +Parameters should be initialised / defined with default values within the `params` scope in `nextflow.config`. -Once there, use `nf-core 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.cpu}` and `${task.memory}` variables in the `script:` block. +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. ### Naming schemes @@ -101,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 d004c11d..02dcdcfb 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/nascent pipeline documentation](https://nf-co.re/nascent/usage) - - type: textarea id: description attributes: diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e33f09a1..44a94364 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -17,7 +17,7 @@ Learn more about contributing: [CONTRIBUTING.md](https://github.com/nf-core/nasc - [ ] 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/nascent/tree/master/.github/CONTRIBUTING.md) - [ ] If necessary, also make a PR on the nf-core/nascent _branch_ on the [nf-core/test-datasets](https://github.com/nf-core/test-datasets) repository. -- [ ] Make sure your code lints (`nf-core lint`). +- [ ] Make sure your code lints (`nf-core pipelines lint`). - [ ] Ensure the test suite passes (`nextflow run . -profile test,docker --outdir `). - [ ] Check for unexpected warnings in debug mode (`nextflow run . -profile debug,test,docker --outdir `). - [ ] Usage Documentation in `docs/usage.md` is updated. diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index bdf5ec1d..40777fab 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -1,19 +1,49 @@ 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: - release: - types: [published] + pull_request: + branches: + - main + - master workflow_dispatch: + pull_request_review: + types: [submitted] + jobs: - run-tower: + run-platform: name: Run AWS full tests - if: github.repository == 'nf-core/nascent' + # run only if the PR is approved by at least 2 reviewers and against the master branch or manually triggered + if: github.repository == 'nf-core/nascent' && github.event.review.state == 'approved' && github.event.pull_request.base.ref == 'master' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest steps: - - name: Launch workflow via tower + - name: Get PR reviews + uses: octokit/request-action@v2.x + if: github.event_name != 'workflow_dispatch' + id: check_approvals + continue-on-error: true + with: + route: GET /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews?per_page=100 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Check for approvals + if: ${{ failure() && github.event_name != 'workflow_dispatch' }} + run: | + echo "No review approvals found. At least 2 approvals are required to run this action automatically." + exit 1 + + - name: Check for enough approvals (>=2) + id: test_variables + if: github.event_name != 'workflow_dispatch' + run: | + JSON_RESPONSE='${{ steps.check_approvals.outputs.data }}' + CURRENT_APPROVALS_COUNT=$(echo $JSON_RESPONSE | jq -c '[.[] | select(.state | contains("APPROVED")) ] | length') + test $CURRENT_APPROVALS_COUNT -ge 2 || exit 1 # At least 2 approvals are required + + - name: Launch workflow via Seqera Platform uses: seqeralabs/action-tower-launch@v2 with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} @@ -30,7 +60,7 @@ jobs: - uses: actions/upload-artifact@v4 with: - name: Tower debug log file + name: Seqera Platform debug log file path: | - tower_action_*.log - tower_action_*.json + seqera_platform_action_*.log + seqera_platform_action_*.json diff --git a/.github/workflows/awstest.yml b/.github/workflows/awstest.yml index bf337a02..6c6c6458 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/nascent' runs-on: ubuntu-latest steps: - # Launch workflow using Tower CLI tool action - - name: Launch 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 }} @@ -27,7 +27,7 @@ jobs: - uses: actions/upload-artifact@v4 with: - name: Tower debug log file + name: Seqera Platform debug log file path: | - tower_action_*.log - tower_action_*.json + seqera_platform_action_*.log + seqera_platform_action_*.json diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml index 72227f54..7467bd12 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/nascent' run: | @@ -19,10 +21,10 @@ jobs: # NOTE - this doesn't currently work if the PR is coming from a fork, due to limitations in GitHub actions secrets - name: Post PR comment if: failure() - uses: mshick/add-pr-comment@v2 + uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2 with: message: | - ## This PR is against the `master` branch :x: + ## This PR is against the `${{github.event.pull_request.base.ref}}` branch :x: * Do not close this PR * Click _Edit_ and change the `base` to `dev` @@ -32,9 +34,9 @@ jobs: Hi @${{ github.event.pull_request.user.login }}, - It looks like this pull-request is has been made against the [${{github.event.pull_request.head.repo.full_name }}](https://github.com/${{github.event.pull_request.head.repo.full_name }}) `master` branch. - The `master` branch on nf-core repositories should always contain code from the latest release. - Because of this, PRs to `master` are only allowed if they come from the [${{github.event.pull_request.head.repo.full_name }}](https://github.com/${{github.event.pull_request.head.repo.full_name }}) `dev` branch. + It looks like this pull-request is has been made against the [${{github.event.pull_request.head.repo.full_name }}](https://github.com/${{github.event.pull_request.head.repo.full_name }}) ${{github.event.pull_request.base.ref}} branch. + The ${{github.event.pull_request.base.ref}} branch on nf-core repositories should always contain code from the latest release. + Because of this, PRs to ${{github.event.pull_request.base.ref}} are only allowed if they come from the [${{github.event.pull_request.head.repo.full_name }}](https://github.com/${{github.event.pull_request.head.repo.full_name }}) `dev` branch. You do not need to close this PR, you can change the target branch to `dev` by clicking the _"Edit"_ button at the top of this page. Note that even after this, the test will continue to show as failing until you push a new commit. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a4e171f0..2c1e3f68 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,9 +7,16 @@ on: pull_request: release: types: [published] + workflow_dispatch: env: NXF_ANSI_LOG: false + NXF_SINGULARITY_CACHEDIR: ${{ github.workspace }}/.singularity + NXF_SINGULARITY_LIBRARYDIR: ${{ github.workspace }}/.singularity + NFT_VER: "0.9.2" + NFT_WORKDIR: "~" + NFT_DIFF: "pdiff" + NFT_DIFF_ARGS: "--line-numbers --expand-tabs=2" concurrency: group: "${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}" @@ -17,66 +24,96 @@ concurrency: jobs: test: - name: nf-test ${{ matrix.profile }}-${{ matrix.NXF_VER }} + name: "Run pipeline with test data (${{ matrix.NXF_VER }} | ${{ matrix.test_name }} | ${{ matrix.profile }})" # Only run on push if this is the nf-core dev branch (merged PRs) if: "${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/nascent') }}" runs-on: ubuntu-latest strategy: + fail-fast: false matrix: NXF_VER: - - "23.04.0" + - "24.04.2" - "latest-everything" - profile: ["docker"] # TODO , "singularity", "conda"] + profile: + - "conda" + - "docker" + - "singularity" + test_name: + - "test" + isMaster: + - ${{ github.base_ref == 'master' }} + # Exclude conda and singularity on dev + exclude: + - isMaster: false + profile: "conda" + - isMaster: false + profile: "singularity" + shard: [1, 2, 3, 4] steps: - name: Check out pipeline code - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + fetch-depth: 0 - - name: Cache Nextflow installation - id: cache-software - uses: actions/cache@v3 + - uses: actions/setup-python@v4 with: - path: | - /usr/local/bin/nf-test - /home/runner/.nf-test/nf-test.jar - key: nascent-${{ runner.os }}-${{ matrix.NXF_VER }} + python-version: "3.11" + architecture: "x64" + + - name: Install pdiff to see diff between nf-test snapshots + run: | + python -m pip install --upgrade pip + pip install pdiff - - name: Install Nextflow - uses: nf-core/setup-nextflow@v1 + - uses: nf-core/setup-nextflow@v2 with: version: "${{ matrix.NXF_VER }}" - - name: Install nf-test - if: steps.cache-software.outputs.cache-hit != 'true' - run: | - wget -qO- https://code.askimed.com/install/nf-test | bash - sudo mv nf-test /usr/local/bin/ + - uses: nf-core/setup-nf-test@v1 + with: + version: ${{ env.NFT_VER }} + + - name: Set up Apptainer + if: matrix.profile == 'singularity' + uses: eWaterCycle/setup-apptainer@main - name: Set up Singularity if: matrix.profile == 'singularity' - uses: eWaterCycle/setup-singularity@v5 - with: - singularity-version: 3.7.1 + run: | + mkdir -p $NXF_SINGULARITY_CACHEDIR + mkdir -p $NXF_SINGULARITY_LIBRARYDIR - - name: Set up miniconda + - name: Set up Miniconda if: matrix.profile == 'conda' - uses: conda-incubator/setup-miniconda@v2 + uses: conda-incubator/setup-miniconda@a4260408e20b96e80095f42ff7f1a15b27dd94ca # v3 with: + miniconda-version: "latest" auto-update-conda: true - channels: conda-forge,bioconda,defaults - python-version: ${{ matrix.python-version }} + conda-solver: libmamba + channels: conda-forge,bioconda - - name: Conda clean + - name: Set up Conda if: matrix.profile == 'conda' - run: conda clean -a + run: | + echo $(realpath $CONDA)/condabin >> $GITHUB_PATH + echo $(realpath python) >> $GITHUB_PATH + + - name: Clean up Disk space + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 - - name: Run nf-test + - name: Run Tests (Shard ${{ matrix.shard }}/4) run: | + NFT_WORKDIR=~ \ nf-test test \ - --profile=${{ matrix.profile }} \ - workflows/tests/*.nf.test \ - --tap=test.tap + --ci \ + --shard ${{ matrix.shard }}/4 \ + --changed-since HEAD^ \ + --profile "+${{ matrix.profile }}" \ + --verbose \ + --filter pipeline - - uses: pcolby/tap-summary@v1 + - name: Publish Test Report + uses: mikepenz/action-junit-report@v3 + if: always() # always run even if the previous step fails with: - path: >- - test.tap + report_paths: test.xml diff --git a/.github/workflows/clean-up.yml b/.github/workflows/clean-up.yml index e37cfda5..0b6b1f27 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@v9 + - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # 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 4a5fe7c7..13b51e2c 100644 --- a/.github/workflows/download_pipeline.yml +++ b/.github/workflows/download_pipeline.yml @@ -1,37 +1,55 @@ -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 pipelines download." + required: true + default: "dev" pull_request: types: - opened + - edited + - synchronize branches: + - main - master pull_request_target: branches: + - main - master env: NXF_ANSI_LOG: false jobs: - download: + 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: 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@v5 + - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5 with: - python-version: "3.11" + python-version: "3.12" architecture: "x64" - - uses: eWaterCycle/setup-singularity@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: | @@ -39,30 +57,74 @@ jobs: pip install git+https://github.com/nf-core/tools.git@dev - name: Get the repository name and current branch set as environment variable + id: get_repo_properties run: | - echo "REPO_LOWERCASE=${GITHUB_REPOSITORY,,}" >> ${GITHUB_ENV} - echo "REPOTITLE_LOWERCASE=$(basename ${GITHUB_REPOSITORY,,})" >> ${GITHUB_ENV} + 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" - echo "{% raw %}REPO_BRANCH=${{ github.event.inputs.testbranch || 'dev' }}" >> ${GITHUB_ENV} + - name: Make a cache directory for the container images + run: | + mkdir -p ./singularity_container_images + download: + runs-on: ubuntu-latest + needs: configure + steps: - 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: 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: ./singularity_container_images + NXF_SINGULARITY_HOME_MOUNT: true + run: nextflow run ./${{needs.configure.outputs.REPOTITLE_LOWERCASE }}/$( sed 's/\W/_/g' <<< ${{ needs.configure.outputs.REPO_BRANCH }}) -stub -profile test,singularity --outdir ./results + - name: Run the downloaded pipeline (stub run not supported) + id: run_pipeline + if: ${{ steps.stub_run_pipeline.outcome == 'failure' }} env: - NXF_SINGULARITY_CACHEDIR: ./ + NXF_SINGULARITY_CACHEDIR: ./singularity_container_images NXF_SINGULARITY_HOME_MOUNT: true - run: nextflow run ./${{ env.REPOTITLE_LOWERCASE }}/$( sed 's/\W/_/g' <<< ${{ env.REPO_BRANCH }}) -stub -profile test,singularity --outdir ./results{% endraw %} + run: nextflow run ./${{ needs.configure.outputs.REPOTITLE_LOWERCASE }}/$( sed 's/\W/_/g' <<< ${{ needs.configure.outputs.REPO_BRANCH }}) -profile test,singularity --outdir ./results + + - name: Count the downloaded number of container images + id: count_afterwards + run: | + image_count=$(ls -1 ./singularity_container_images | wc -l | xargs) + echo "Post-pipeline run container image count: $image_count" + echo "IMAGE_COUNT_AFTER=$image_count" >> "$GITHUB_OUTPUT" + + - name: Compare container image counts + 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 + exit 1 + else + echo "The pipeline can be downloaded successfully!" + fi diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml index 1c6f70c9..7e31ee9b 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@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5 with: - python-version: 3.11 + python-version: "3.12" - name: Install pre-commit run: pip install pre-commit diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 81cd098e..dbd52d5a 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -1,6 +1,6 @@ name: nf-core linting # This workflow is triggered on pushes and PRs to the repository. -# It runs the `nf-core lint` and markdown lint tests to ensure +# It runs the `nf-core pipelines lint` and markdown lint tests to ensure # that the code meets the nf-core guidelines. on: push: @@ -14,13 +14,12 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - - name: Set up Python 3.11 - uses: actions/setup-python@v5 + - name: Set up Python 3.12 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5 with: - python-version: 3.11 - cache: "pip" + python-version: "3.12" - name: Install pre-commit run: pip install pre-commit @@ -32,27 +31,42 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out pipeline code - uses: actions/checkout@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@v5 + - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5 with: - python-version: "3.11" + python-version: "3.12" architecture: "x64" + - name: read .nf-core.yml + uses: pietrobolcato/action-read-yaml@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 +74,7 @@ jobs: - name: Upload linting log file artifact if: ${{ always() }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4 with: name: linting-logs path: | diff --git a/.github/workflows/linting_comment.yml b/.github/workflows/linting_comment.yml index 147bcd10..0bed96d3 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@v3 + uses: dawidd6/action-download-artifact@80620a5d27ce0ae443b965134db88467fc607b43 # v7 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@v2 + uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31 # v2 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} number: ${{ steps.pr_number.outputs.pr_number }} diff --git a/.github/workflows/release-announcements.yml b/.github/workflows/release-announcements.yml index 21ac3f06..450b1d5e 100644 --- a/.github/workflows/release-announcements.yml +++ b/.github/workflows/release-announcements.yml @@ -9,6 +9,11 @@ jobs: toot: runs-on: ubuntu-latest steps: + - name: get topics and convert to hashtags + id: get_topics + run: | + echo "topics=$(curl -s https://nf-co.re/pipelines.json | jq -r '.remote_workflows[] | select(.full_name == "${{ github.repository }}") | .topics[]' | awk '{print "#"$0}' | tr '\n' ' ')" | sed 's/-//g' >> $GITHUB_OUTPUT + - uses: rzr/fediverse-action@master with: access-token: ${{ secrets.MASTODON_ACCESS_TOKEN }} @@ -20,11 +25,13 @@ jobs: Please see the changelog: ${{ github.event.release.html_url }} + ${{ steps.get_topics.outputs.topics }} #nfcore #openscience #nextflow #bioinformatics + send-tweet: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v5 + - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5 with: python-version: "3.10" - name: Install dependencies @@ -56,7 +63,7 @@ jobs: bsky-post: runs-on: ubuntu-latest steps: - - uses: zentered/bluesky-post-action@v0.1.0 + - uses: zentered/bluesky-post-action@80dbe0a7697de18c15ad22f4619919ceb5ccf597 # v0.1.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 00000000..537529bc --- /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@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 089a4079..23b0c7de 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ results/ testing/ testing* *.pyc -.nf-test +null/ +.nf-test* diff --git a/.gitpod.yml b/.gitpod.yml index 363d5b1d..83599f63 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -4,19 +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 - - codezombiech.gitignore # Language support for .gitignore files - # - cssho.vscode-svgviewer # SVG viewer - - esbenp.prettier-vscode # Markdown/CommonMark linting and style checking for Visual Studio Code - - eamodio.gitlens # Quickly glimpse into whom, why, and when a line or code block was changed - - 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 + extensions: + - nf-core.nf-core-extensionpack # https://github.com/nf-core/vscode-extensionpack diff --git a/.nf-core.yml b/.nf-core.yml index 89348e55..243dcc37 100644 --- a/.nf-core.yml +++ b/.nf-core.yml @@ -1,6 +1,17 @@ -repository_type: pipeline lint: + actions_ci: false files_unchanged: - .github/workflows/linting.yml - LICENSE - assets/email_template.html +nf_core_version: 3.1.1 +repository_type: pipeline +template: + author: Edmund Miller, Ignacio Tripodi, Margaret Gruca + description: Global Run-On sequencing analysis pipeline + force: false + is_nfcore: true + name: nascent + org: nf-core + outdir: . + version: 2.3.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index af57081f..9e9f0e1c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,8 +3,11 @@ repos: rev: "v3.1.0" hooks: - id: prettier + additional_dependencies: + - prettier@3.2.5 + - repo: https://github.com/editorconfig-checker/editorconfig-checker.python - rev: "2.7.3" + rev: "3.0.3" hooks: - id: editorconfig-checker alias: ec diff --git a/.prettierignore b/.prettierignore index 437d763d..edd29f01 100644 --- a/.prettierignore +++ b/.prettierignore @@ -10,3 +10,4 @@ testing/ testing* *.pyc bin/ +ro-crate-metadata.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..a33b527c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "markdown.styles": ["public/vscode_markdown.css"] +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dcf1174..ef22efa2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,14 +3,51 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## v2.3.0 - 2024-12-23 + +### Added + +- [5bcfe4f](https://github.com/nf-core/nascent/commit/5bcfe4ff1729b89e9e5741c473d32168b836a57f) - Update pipeline template to [nf-core/tools 2.13](https://github.com/nf-core/tools/releases/tag/2.13) +- [a3bc907](https://github.com/nf-core/nascent/commit/a3bc907e9afd9dd2a9572798fa16fbc781c3dcb0) - Update pipeline template to [nf-core/tools 2.13.1](https://github.com/nf-core/tools/releases/tag/2.13.1) +- [#140](https://github.com/nf-core/nascent/pull/140) - Add HISAT2 aligner +- [#142](https://github.com/nf-core/nascent/pull/142) - Add STAR aligner +- [#149](https://github.com/nf-core/nascent/pull/149) - Add Software citations to MultiQC +- [#175](https://github.com/nf-core/nascent/pull/175) - Add HOMER uniqmap support +- [a3bc907](https://github.com/nf-core/nascent/commit/a3bc907e9afd9dd2a9572798fa16fbc781c3dcb0) - Update pipeline template to [nf-core/tools 2.13.1](https://github.com/nf-core/tools/releases/tag/2.13.1) +- [14fdbb8](https://github.com/nf-core/nascent/commit/14fdbb83fe944fc4d8d77e804f0332510d82fea4) - Update pipeline template to [nf-core/tools 3.0.0](https://github.com/nf-core/tools/releases/tag/3.0.0) +- [b4ac8c5](https://github.com/nf-core/nascent/commit/b4ac8c5) - Update pipeline template to [nf-core/tools 3.0.1](https://github.com/nf-core/tools/releases/tag/3.0.1) +- [a9ae47a](https://github.com/nf-core/nascent/commit/a9ae47a) - Update pipeline template to [nf-core/tools 3.0.1](https://github.com/nf-core/tools/releases/tag/3.0.2) +- [bfcd97c](https://github.com/nf-core/nascent/commit/bfcd97c) - Update pipeline template to [nf-core/tools 3.1.0](https://github.com/nf-core/tools/releases/tag/3.1.0) +- [7a4e356](https://github.com/nf-core/nascent/commit/7a4e356) - Update pipeline template to [nf-core/tools 3.1.1](https://github.com/nf-core/tools/releases/tag/3.1.1) + +### Fixed + +- [#171](https://github.com/nf-core/nascent/pull/171) - Clean up MultiQC report +- [#170](https://github.com/nf-core/nascent/pull/170) - Remove "Access to undefined parameter forwardStranded" warnings +- [#173](https://github.com/nf-core/nascent/pull/173) - Fix config selectors +- [#173](https://github.com/nf-core/nascent/pull/173) - Remove STAR transcriptome run + +### Changed + +- [#137](https://github.com/nf-core/nascent/pull/137) - Use singularity containers for PINTS +- [#142](https://github.com/nf-core/nascent/pull/142) - Updated CHM13 references +- [#171](https://github.com/nf-core/nascent/pull/171) - Use assertAll in tests +- [#165](https://github.com/nf-core/nascent/pull/165) - groHMM overhaul. Removed R mclapply calls and replaced with Nextflow scatter gather for parameter tuning. This creates a job for each parameter set. +- [#174](https://github.com/nf-core/nascent/pull/174) - PINTS Scatter gather pattern by chromosome +- [#178](https://github.com/nf-core/nascent/pull/178) - Remove groHMM parameter tuning publishing and remove `each` inputs from parameter tuning module + +### Removed + +- [[#165](https://github.com/nf-core/nascent/pull/165)] - Removed support for groHMM tuning files. + ## v2.2.0 - 2024-03-05 ### Added -- [1494fff](https://github.com/nf-core/nascent/commit/1494fff2ecd8b498e19d7d0fa3f7ee0f71088ab4) - Update pipeline template to [nf-core/tools 2.12](https://github.com/nf-core/tools/releases/tag/2.12) -- [ec24cfb](https://github.com/nf-core/nascent/commit/ec24cfb2646904bcc78379a071b50b53a855b9a9) - Update pipeline template to [nf-core/tools 2.11.1](https://github.com/nf-core/tools/releases/tag/2.11.1) -- [15b8ff3](https://github.com/nf-core/nascent/commit/15b8ff31cd43ec2e330ce7958bd6d7d65529b4d3) - Update pipeline template to [nf-core/tools 2.11](https://github.com/nf-core/tools/releases/tag/2.11) - [9712163](https://github.com/nf-core/nascent/commit/97121638eb77e175b912ff45a669426e532c5d7f) - Update pipeline template to [nf-core/tools 2.10](https://github.com/nf-core/tools/releases/tag/2.10) +- [15b8ff3](https://github.com/nf-core/nascent/commit/15b8ff31cd43ec2e330ce7958bd6d7d65529b4d3) - Update pipeline template to [nf-core/tools 2.11](https://github.com/nf-core/tools/releases/tag/2.11) +- [ec24cfb](https://github.com/nf-core/nascent/commit/ec24cfb2646904bcc78379a071b50b53a855b9a9) - Update pipeline template to [nf-core/tools 2.11.1](https://github.com/nf-core/tools/releases/tag/2.11.1) +- [1494fff](https://github.com/nf-core/nascent/commit/1494fff2ecd8b498e19d7d0fa3f7ee0f71088ab4) - Update pipeline template to [nf-core/tools 2.12](https://github.com/nf-core/tools/releases/tag/2.12) - [[#130](https://github.com/nf-core/nascent/pull/130)] - AWS Mega Tests - [[#132](https://github.com/nf-core/nascent/pull/132)] - Add Bowtie 2 as an aligner option diff --git a/CITATIONS.md b/CITATIONS.md index 1f9ec210..6e4513b4 100644 --- a/CITATIONS.md +++ b/CITATIONS.md @@ -50,9 +50,13 @@ > Pertea G, Pertea M. GFF Utilities: GffRead and GffCompare. F1000Res. 2020 Apr 28;9:ISCB Comm J-304. doi: 10.12688/f1000research.23297.2. eCollection 2020. PubMed PMID: 32489650; PubMed Central PMCID: PMC7222033. +- [HISAT2](https://pubmed.ncbi.nlm.nih.gov/31375807/) + + > Kim D, Paggi JM, Park C, Bennett C, Salzberg SL. Graph-based genome alignment and genotyping with HISAT2 and HISAT-genotype Graph-based genome alignment and genotyping with HISAT2 and HISAT-genotype. Nat Biotechnol. 2019 Aug;37(8):907-915. doi: 10.1038/s41587-019-0201-4. Epub 2019 Aug 2. PubMed PMID: 31375807. + - [HOMER](http://homer.ucsd.edu/homer/index.html) -> Heinz S, Benner C, Spann N, Bertolino E et al. Simple Combinations of Lineage-Determining Transcription Factors Prime cis-Regulatory Elements Required for Macrophage and B Cell Identities. Mol Cell 2010 May 28;38(4):576-589. PMID: 20513432 + > Heinz S, Benner C, Spann N, Bertolino E et al. Simple Combinations of Lineage-Determining Transcription Factors Prime cis-Regulatory Elements Required for Macrophage and B Cell Identities. Mol Cell 2010 May 28;38(4):576-589. PMID: 20513432 - [MultiQC](https://pubmed.ncbi.nlm.nih.gov/27312411/) @@ -74,6 +78,10 @@ > Li H, Handsaker B, Wysoker A, Fennell T, Ruan J, Homer N, Marth G, Abecasis G, Durbin R; 1000 Genome Project Data Processing Subgroup. The Sequence Alignment/Map format and SAMtools. Bioinformatics. 2009 Aug 15;25(16):2078-9. doi: 10.1093/bioinformatics/btp352. Epub 2009 Jun 8. PubMed PMID: 19505943; PubMed Central PMCID: PMC2723002. +- [STAR](https://pubmed.ncbi.nlm.nih.gov/23104886/) + + > Dobin A, Davis CA, Schlesinger F, Drenkow J, Zaleski C, Jha S, Batut P, Chaisson M, Gingeras TR. STAR: ultrafast universal RNA-seq aligner Bioinformatics. 2013 Jan 1;29(1):15-21. doi: 10.1093/bioinformatics/bts635. Epub 2012 Oct 25. PubMed PMID: 23104886; PubMed Central PMCID: PMC3530905. + - [UMI-tools](https://pubmed.ncbi.nlm.nih.gov/28100584/) > Smith T, Heger A, Sudbery I. UMI-tools: modeling sequencing errors in Unique Molecular Identifiers to improve quantification accuracy Genome Res. 2017 Mar;27(3):491-499. doi: 10.1101/gr.209601.116. Epub 2017 Jan 18. PubMed PMID: 28100584; PubMed Central PMCID: PMC5340976. diff --git a/LICENSE b/LICENSE index afec2257..15d7da24 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) Edmund Miller, Ignacio Tripodi, Margaret Gruca +Copyright (c) The nf-core/nascent 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 107fac57..b1952d7b 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,16 @@ nf-core/nascent -[![GitHub Actions CI Status](https://github.com/nf-core/nascent/workflows/nf-core%20CI/badge.svg)](https://github.com/nf-core/nascent/actions?query=workflow%3A%22nf-core+CI%22) -[![GitHub Actions Linting Status](https://github.com/nf-core/nascent/workflows/nf-core%20linting/badge.svg)](https://github.com/nf-core/nascent/actions?query=workflow%3A%22nf-core+linting%22)[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/nascent/results)[![Cite with Zenodo](https://img.shields.io/badge/DOI-10.5281%2Fzenodo.7245273-blue)](https://doi.org/10.5281/zenodo.7245273) -[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A523.04.0-23aa62.svg)](https://www.nextflow.io/) +[![GitHub Actions CI Status](https://github.com/nf-core/nascent/actions/workflows/ci.yml/badge.svg)](https://github.com/nf-core/nascent/actions/workflows/ci.yml) +[![GitHub Actions Linting Status](https://github.com/nf-core/nascent/actions/workflows/linting.yml/badge.svg)](https://github.com/nf-core/nascent/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/nascent/results)[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.7245273-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.7245273) +[![nf-test](https://img.shields.io/badge/unit_tests-nf--test-337ab7.svg)](https://www.nf-test.com) + +[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A524.04.2-23aa62.svg)](https://www.nextflow.io/) [![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/) [![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/) [![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/) -[![Launch on Nextflow Tower](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Nextflow%20Tower-%234256e7)](https://tower.nf/launch?pipeline=https://github.com/nf-core/nascent) +[![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/nascent) [![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23nascent-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/nascent)[![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) @@ -51,7 +53,7 @@ On release, automated continuous integration tests run the pipeline on a full-si ## Usage > [!NOTE] -> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data. +> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how to set-up Nextflow.Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) with `-profile test` before running the workflow on actual data. \n\nNow, you can run the pipeline using:\n\n```bash\nnextflow run nf-core/nascent \\\n -profile \\\n --input samplesheet.csv \\\n --outdir \n```\n\n> [!WARNING]\n> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; see [docs](https://nf-co.re/docs/usage/getting_started/configuration#custom-configuration-files).\n\nFor more details and further functionality, please refer to the [usage documentation](https://nf-co.re/nascent/usage) and the [parameter documentation](https://nf-co.re/nascent/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/nascent/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/nascent/output).\n\n## Credits\n\nnf-core/nascent was originally written by Ignacio Tripodi ([@ignaciot](https://github.com/ignaciot)) and Margaret Gruca ([@magruca](https://github.com/magruca)).\n\nThe pipeline was re-written in Nextflow DSL2 by Edmund Miller ([@edmundmiller](https://github.com/edmundmiller)) and Sruthi Suresh ([@sruthipsuresh](https://github.com/sruthipsuresh)) from [The Functional Genomics Laboratory](https://taehoonkim.org/) at [The Univeristy of Texas at Dallas](https://www.utdallas.edu/)\n\nWe thank the following people for their extensive assistance in the development of this pipeline:\n\n- [@apeltzer](https://github.com/apeltzer)\n- [@ewels](https://github.com/ewels)\n- [@drpatelh](https://github.com/drpatelh)\n- [@pditommaso](https://github.com/pditommaso)\n- [@FriederikeHanssen](https://github.com/FriederikeHanssen)\n- [Tae Hoon Kim](https://github.com/taehoonkim-phd)\n- [@easterwoods](https://github.com/easterwoods)\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 `#nascent` channel](https://nfcore.slack.com/channels/nascent) (you can join with [this invite](https://nf-co.re/join/slack)).\n\n## Citations\n\nIf you use nf-core/nascent for your analysis, please cite it using the following doi: [10.5281/zenodo.7245273](https://doi.org/10.5281/zenodo.7245273)\n\nAn extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file.\n\nYou can cite the `nf-core` publication as follows:\n\n> **The nf-core framework for community-curated bioinformatics pipelines.**\n>\n> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.\n>\n> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).\n", + "hasPart": [ + { + "@id": "main.nf" + }, + { + "@id": "assets/" + }, + { + "@id": "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/nascent", + "license": "MIT", + "mainEntity": { + "@id": "main.nf" + }, + "mentions": [ + { + "@id": "#daaf6fca-5723-48f3-8e28-467003b1ba8b" + } + ], + "name": "nf-core/nascent" + }, + { + "@id": "ro-crate-metadata.json", + "@type": "CreativeWork", + "about": { + "@id": "./" + }, + "conformsTo": [ + { + "@id": "https://w3id.org/ro/crate/1.1" + }, + { + "@id": "https://w3id.org/workflowhub/workflow-ro-crate/1.0" + } + ] + }, + { + "@id": "main.nf", + "@type": [ + "File", + "SoftwareSourceCode", + "ComputationalWorkflow" + ], + "creator": [ + { + "@id": "https://orcid.org/0000-0002-6503-2180" + }, + { + "@id": "#git@edmundmiller.dev" + } + ], + "dateCreated": "", + "dateModified": "2024-12-22T12:18:10Z", + "dct:conformsTo": "https://bioschemas.org/profiles/ComputationalWorkflow/1.0-RELEASE/", + "keywords": [ + "nf-core", + "nextflow", + "gro-seq", + "nascent", + "pro-seq", + "rna", + "transcription", + "tss" + ], + "license": [ + "MIT" + ], + "maintainer": [ + { + "@id": "#git@edmundmiller.dev" + } + ], + "name": [ + "nf-core/nascent" + ], + "programmingLanguage": { + "@id": "https://w3id.org/workflowhub/workflow-ro-crate#nextflow" + }, + "sdPublisher": { + "@id": "https://nf-co.re/" + }, + "url": [ + "https://github.com/nf-core/nascent", + "https://nf-co.re/nascent/2.3.0/" + ], + "version": [ + "2.3.0" + ] + }, + { + "@id": "https://w3id.org/workflowhub/workflow-ro-crate#nextflow", + "@type": "ComputerLanguage", + "identifier": { + "@id": "https://www.nextflow.io/" + }, + "name": "Nextflow", + "url": { + "@id": "https://www.nextflow.io/" + }, + "version": "!>=24.04.2" + }, + { + "@id": "#daaf6fca-5723-48f3-8e28-467003b1ba8b", + "@type": "TestSuite", + "instance": [ + { + "@id": "#c8ba6d45-39ba-478f-a2d2-2ec121776d34" + } + ], + "mainEntity": { + "@id": "main.nf" + }, + "name": "Test suite for nf-core/nascent" + }, + { + "@id": "#c8ba6d45-39ba-478f-a2d2-2ec121776d34", + "@type": "TestInstance", + "name": "GitHub Actions workflow for testing nf-core/nascent", + "resource": "repos/nf-core/nascent/actions/workflows/ci.yml", + "runsOn": { + "@id": "https://w3id.org/ro/terms/test#GithubService" + }, + "url": "https://api.github.com" + }, + { + "@id": "https://w3id.org/ro/terms/test#GithubService", + "@type": "TestService", + "name": "Github Actions", + "url": { + "@id": "https://github.com" + } + }, + { + "@id": "assets/", + "@type": "Dataset", + "description": "Additional files" + }, + { + "@id": "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": "https://orcid.org/0000-0002-6503-2180", + "@type": "Person", + "email": "alex.peltzer@gmail.com", + "name": "Alexander Peltzer" + }, + { + "@id": "https://orcid.org/0000-0002-6503-2180", + "@type": "Person", + "email": "nf-core@edmundmiller.dev", + "name": "Edmund Miller" + } + ] +} diff --git a/subworkflows/local/align_bwamem2/main.nf b/subworkflows/local/align_bwamem2/main.nf index b950954e..f1ffb959 100644 --- a/subworkflows/local/align_bwamem2/main.nf +++ b/subworkflows/local/align_bwamem2/main.nf @@ -2,15 +2,15 @@ // Alignment with BWAMEM2 // -include { BWAMEM2_MEM } from '../../../modules/nf-core/bwamem2/mem/main' +include { BWAMEM2_MEM } from '../../../modules/nf-core/bwamem2/mem/main' include { BAM_SORT_STATS_SAMTOOLS } from '../../nf-core/bam_sort_stats_samtools/main' workflow ALIGN_BWAMEM2 { take: - ch_reads // channel (mandatory): [ val(meta), [ path(reads) ] ] - ch_index // channel (mandatory): [ val(meta2), path(index) ] - val_sort_bam // boolean (mandatory): true or false - ch_fasta // channel (optional) : [ val(meta3), path(fasta) ] + ch_reads // channel (mandatory): [ val(meta), [ path(reads) ] ] + ch_index // channel (mandatory): [ val(meta2), path(index) ] + val_sort_bam // boolean (mandatory): true or false + ch_fasta // channel (optional) : [ val(meta3), path(fasta) ] main: ch_versions = Channel.empty() @@ -19,25 +19,23 @@ workflow ALIGN_BWAMEM2 { // Map reads with BWA // - BWAMEM2_MEM ( ch_reads, ch_index, val_sort_bam ) + BWAMEM2_MEM(ch_reads, ch_index, ch_fasta, val_sort_bam) ch_versions = ch_versions.mix(BWAMEM2_MEM.out.versions.first()) // // Sort, index BAM file and run samtools stats, flagstat and idxstats // - BAM_SORT_STATS_SAMTOOLS ( BWAMEM2_MEM.out.bam, ch_fasta ) + BAM_SORT_STATS_SAMTOOLS(BWAMEM2_MEM.out.bam, ch_fasta) ch_versions = ch_versions.mix(BAM_SORT_STATS_SAMTOOLS.out.versions) emit: - bam_orig = BWAMEM2_MEM.out.bam // channel: [ val(meta), path(bam) ] - - bam = BAM_SORT_STATS_SAMTOOLS.out.bam // channel: [ val(meta), path(bam) ] - bai = BAM_SORT_STATS_SAMTOOLS.out.bai // channel: [ val(meta), path(bai) ] - csi = BAM_SORT_STATS_SAMTOOLS.out.csi // channel: [ val(meta), path(csi) ] - stats = BAM_SORT_STATS_SAMTOOLS.out.stats // channel: [ val(meta), path(stats) ] + bam_orig = BWAMEM2_MEM.out.bam // channel: [ val(meta), path(bam) ] + bam = BAM_SORT_STATS_SAMTOOLS.out.bam // channel: [ val(meta), path(bam) ] + bai = BAM_SORT_STATS_SAMTOOLS.out.bai // channel: [ val(meta), path(bai) ] + csi = BAM_SORT_STATS_SAMTOOLS.out.csi // channel: [ val(meta), path(csi) ] + stats = BAM_SORT_STATS_SAMTOOLS.out.stats // channel: [ val(meta), path(stats) ] flagstat = BAM_SORT_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), path(flagstat) ] idxstats = BAM_SORT_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), path(idxstats) ] - - versions = ch_versions // channel: [ path(versions.yml) ] + versions = ch_versions // channel: [ path(versions.yml) ] } diff --git a/subworkflows/local/align_dragmap/main.nf b/subworkflows/local/align_dragmap/main.nf index 34f641c8..73a181b8 100644 --- a/subworkflows/local/align_dragmap/main.nf +++ b/subworkflows/local/align_dragmap/main.nf @@ -2,15 +2,15 @@ // Alignment with dragmap // -include { DRAGMAP_ALIGN } from '../../../modules/nf-core/dragmap/align/main' +include { DRAGMAP_ALIGN } from '../../../modules/nf-core/dragmap/align/main' include { BAM_SORT_STATS_SAMTOOLS } from '../../nf-core/bam_sort_stats_samtools/main' workflow ALIGN_DRAGMAP { take: - ch_reads // channel (mandatory): [ val(meta), [ path(reads) ] ] - ch_index // channel (mandatory): [ val(meta2), path(index) ] - val_sort_bam // boolean (mandatory): true or false - ch_fasta // channel (optional) : [ val(meta3), path(fasta) ] + ch_reads // channel (mandatory): [ val(meta), [ path(reads) ] ] + ch_index // channel (mandatory): [ val(meta2), path(index) ] + val_sort_bam // boolean (mandatory): true or false + ch_fasta // channel (optional) : [ val(meta3), path(fasta) ] main: ch_versions = Channel.empty() @@ -19,25 +19,23 @@ workflow ALIGN_DRAGMAP { // Map reads with dragmap // - DRAGMAP_ALIGN ( ch_reads, ch_index, val_sort_bam ) + DRAGMAP_ALIGN(ch_reads, ch_index, ch_fasta, val_sort_bam) ch_versions = ch_versions.mix(DRAGMAP_ALIGN.out.versions.first()) // // Sort, index BAM file and run samtools stats, flagstat and idxstats // - BAM_SORT_STATS_SAMTOOLS ( DRAGMAP_ALIGN.out.bam, ch_fasta ) + BAM_SORT_STATS_SAMTOOLS(DRAGMAP_ALIGN.out.bam, ch_fasta) ch_versions = ch_versions.mix(BAM_SORT_STATS_SAMTOOLS.out.versions) emit: - bam_orig = DRAGMAP_ALIGN.out.bam // channel: [ val(meta), path(bam) ] - - bam = BAM_SORT_STATS_SAMTOOLS.out.bam // channel: [ val(meta), path(bam) ] - bai = BAM_SORT_STATS_SAMTOOLS.out.bai // channel: [ val(meta), path(bai) ] - csi = BAM_SORT_STATS_SAMTOOLS.out.csi // channel: [ val(meta), path(csi) ] - stats = BAM_SORT_STATS_SAMTOOLS.out.stats // channel: [ val(meta), path(stats) ] + bam_orig = DRAGMAP_ALIGN.out.bam // channel: [ val(meta), path(bam) ] + bam = BAM_SORT_STATS_SAMTOOLS.out.bam // channel: [ val(meta), path(bam) ] + bai = BAM_SORT_STATS_SAMTOOLS.out.bai // channel: [ val(meta), path(bai) ] + csi = BAM_SORT_STATS_SAMTOOLS.out.csi // channel: [ val(meta), path(csi) ] + stats = BAM_SORT_STATS_SAMTOOLS.out.stats // channel: [ val(meta), path(stats) ] flagstat = BAM_SORT_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), path(flagstat) ] idxstats = BAM_SORT_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), path(idxstats) ] - - versions = ch_versions // channel: [ path(versions.yml) ] + versions = ch_versions // channel: [ path(versions.yml) ] } diff --git a/subworkflows/local/coverage_graphs.nf b/subworkflows/local/coverage_graphs.nf index a64fdc29..ac8c46db 100644 --- a/subworkflows/local/coverage_graphs.nf +++ b/subworkflows/local/coverage_graphs.nf @@ -2,54 +2,54 @@ * Create bigWig and bedGraph files */ -include { - BEDTOOLS_GENOMECOV as BEDTOOLS_GENOMECOV_PLUS - BEDTOOLS_GENOMECOV as BEDTOOLS_GENOMECOV_MINUS } from '../../modules/nf-core/bedtools/genomecov/main' +include { BEDTOOLS_GENOMECOV as BEDTOOLS_GENOMECOV_PLUS } from '../../modules/nf-core/bedtools/genomecov/main' +include { BEDTOOLS_GENOMECOV as BEDTOOLS_GENOMECOV_MINUS } from '../../modules/nf-core/bedtools/genomecov/main' -include { - DEEPTOOLS_BAMCOVERAGE as DEEPTOOLS_BAMCOVERAGE_PLUS - DEEPTOOLS_BAMCOVERAGE as DEEPTOOLS_BAMCOVERAGE_MINUS } from '../../modules/nf-core/deeptools/bamcoverage/main' +include { DEEPTOOLS_BAMCOVERAGE as DEEPTOOLS_BAMCOVERAGE_PLUS } from '../../modules/nf-core/deeptools/bamcoverage/main' +include { DEEPTOOLS_BAMCOVERAGE as DEEPTOOLS_BAMCOVERAGE_MINUS } from '../../modules/nf-core/deeptools/bamcoverage/main' + +include { DREG_PREP } from '../../modules/local/dreg_prep/main' workflow COVERAGE_GRAPHS { take: - bam - bai + bam_bai sizes fasta fai main: + bam = bam_bai.map { [it[0], it[1]] } + ch_versions = Channel.empty() ch_genomecov_bam = bam.combine(Channel.from(1)) - BEDTOOLS_GENOMECOV_PLUS ( + BEDTOOLS_GENOMECOV_PLUS( ch_genomecov_bam, - [], - 'bedGraph' + sizes, + 'bedGraph', + true ) ch_versions = ch_versions.mix(BEDTOOLS_GENOMECOV_PLUS.out.versions.first()) - BEDTOOLS_GENOMECOV_MINUS ( + BEDTOOLS_GENOMECOV_MINUS( ch_genomecov_bam, - [], - 'bedGraph' + sizes, + 'bedGraph', + true ) ch_versions = ch_versions.mix(BEDTOOLS_GENOMECOV_MINUS.out.versions.first()) - - bam.join(bai, by: [0], remainder: true).set { ch_bam_bai } - - DEEPTOOLS_BAMCOVERAGE_PLUS ( - ch_bam_bai, + DEEPTOOLS_BAMCOVERAGE_PLUS( + bam_bai, fasta, fai ) ch_versions = ch_versions.mix(DEEPTOOLS_BAMCOVERAGE_PLUS.out.versions.first()) - DEEPTOOLS_BAMCOVERAGE_MINUS ( - ch_bam_bai, + DEEPTOOLS_BAMCOVERAGE_MINUS( + bam_bai, fasta, fai ) @@ -57,11 +57,15 @@ workflow COVERAGE_GRAPHS { ch_plus_minus = DEEPTOOLS_BAMCOVERAGE_PLUS.out.bigwig.join(DEEPTOOLS_BAMCOVERAGE_MINUS.out.bigwig) + DREG_PREP( + bam_bai, + sizes, + params.assay_type + ) + emit: - plus_bedGraph = BEDTOOLS_GENOMECOV_PLUS.out.genomecov + plus_bedGraph = BEDTOOLS_GENOMECOV_PLUS.out.genomecov minus_bedGraph = BEDTOOLS_GENOMECOV_MINUS.out.genomecov - - plus_minus = ch_plus_minus - - versions = ch_versions + plus_minus = ch_plus_minus + versions = ch_versions } diff --git a/subworkflows/local/dreg_prep/main.nf b/subworkflows/local/dreg_prep/main.nf new file mode 100644 index 00000000..942d97ec --- /dev/null +++ b/subworkflows/local/dreg_prep/main.nf @@ -0,0 +1,13 @@ +include { BEDTOOLS_BAMTOBED } from '../modules/nf-core/bedtools/bamtobed/main' + +workflow DREG_PREP { + take: + bam + bai + sizes + + main: + BEDTOOLS_BAMTOBED( + bam + ) +} diff --git a/subworkflows/local/grohmm/main.nf b/subworkflows/local/grohmm/main.nf index ed5ca20b..77607319 100644 --- a/subworkflows/local/grohmm/main.nf +++ b/subworkflows/local/grohmm/main.nf @@ -2,38 +2,59 @@ * Run parametertuning optionally, otherwise just run transcript calling */ -include { GROHMM_TRANSCRIPTCALLING } from '../../../modules/local/grohmm/transcriptcalling/main.nf' include { GROHMM_PARAMETERTUNING } from '../../../modules/local/grohmm/parametertuning/main.nf' +include { GROHMM_TRANSCRIPTCALLING } from '../../../modules/local/grohmm/transcriptcalling/main.nf' /* * Note meta refers to all merged files */ workflow GROHMM { take: - bams + bams_bais gtf - tuning_file + // TODO Support rerunning with a tuning file + // tuning_file main: ch_versions = Channel.empty() - ch_tuning = [] + // Run transcriptcalling eval for each tuning param + // Should avoid a tuning file with a row for everything + // 5..45 by 5 for UTS is what we had currently + ch_uts = channel.fromList((params.grohmm_min_uts..params.grohmm_max_uts).step(5)) + // -100..-400 by 50 for LtProbB + ch_ltprobb = channel.fromList((params.grohmm_min_ltprobb..params.grohmm_max_ltprobb).step(50)) - if(!params.skip_tuning) { - GROHMM_PARAMETERTUNING ( - bams, - gtf, - tuning_file + GROHMM_PARAMETERTUNING ( + bams_bais.combine(ch_uts).combine(ch_ltprobb), + gtf + ) + .tuning + .collectFile( + keepHeader: true, + skip: 1, + newLine: false, + storeDir: "${params.outdir}/transcript_identification/grohmm/", ) - ch_tuning = GROHMM_PARAMETERTUNING.out.tuning - ch_versions = ch_versions.mix(GROHMM_PARAMETERTUNING.out.versions.first()) + { meta, file -> + filename = "${meta.id}.${meta.single_end ? 'SE': 'PE' }.tuning.csv" + [filename, file.text] } + .map { path -> + meta = [ + id:path.getSimpleName(), + single_end: path.getName().split("\\.")[1] == 'SE' ? true : false + ] + [meta, file(path)] + } + .set { ch_tuning } + + ch_versions = ch_versions.mix(GROHMM_PARAMETERTUNING.out.versions.first()) GROHMM_TRANSCRIPTCALLING ( - bams, + bams_bais.join(ch_tuning, by: [0]), gtf, - ch_tuning ) ch_versions = ch_versions.mix(GROHMM_TRANSCRIPTCALLING.out.versions.first()) diff --git a/subworkflows/local/grohmm/tests/main.nf.test b/subworkflows/local/grohmm/tests/main.nf.test index c54ce88a..39f9f380 100644 --- a/subworkflows/local/grohmm/tests/main.nf.test +++ b/subworkflows/local/grohmm/tests/main.nf.test @@ -1,93 +1,52 @@ nextflow_workflow { - name "Test Workflow GROHMM" + name "Test subworkflow GROHMM" script "../main.nf" workflow "GROHMM" + tag "grohmm" - test("Should run without a tuning file") { + test("Should run without a tuning file and multiplex") { when { params { outdir = "$outputDir" - skip_tuning = true + grohmm_min_uts = 5 + grohmm_max_uts = 10 + grohmm_min_ltprobb = -100 + grohmm_max_ltprobb = -150 } workflow { """ - input[0] = [ - [ id: 'mR1' ], - [ file("https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/sarscov2/illumina/bam/test.single_end.sorted.bam", checkIfExists: true), ] - ] - // FIXME This needs to match up with s40 - input[1] = file( - "https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/sarscov2/genome/genome.gtf", - checkIfExists: true - ) - input[2] = [] - """ - } - } - - then { - assert workflow.success - assert snapshot(workflow.out).match() - } - - } - - test("Should run with multiple bams") { - when { - params { - outdir = "$outputDir" - } - workflow { - """ - input[0] = [ - [ id: 'mR1' ], - [ file("https://raw.githubusercontent.com/Kraus-Lab/groHMM/master/inst/extdata/S0mR1.bam", checkIfExists: true), - file("https://raw.githubusercontent.com/Kraus-Lab/groHMM/master/inst/extdata/S40mR1.bam", checkIfExists: true) ] - ] - input[1] = file( - "https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/homo_sapiens/genome/genome.gtf", - checkIfExists: true - ) - input[2] = [] - """ - } - } - - then { - assert workflow.success - assert snapshot(workflow.out).match() - } - - } - - test("Should run with a tuning file") { - - when { - params { - outdir = "$outputDir" - } - workflow { - """ - input[0] = [ - [ id: 'mR1' ], + input[0] = Channel.of([ + [ id: 'Sall' ], [ file("https://raw.githubusercontent.com/Kraus-Lab/groHMM/master/inst/extdata/S0mR1.bam", checkIfExists: true), - file("https://raw.githubusercontent.com/Kraus-Lab/groHMM/master/inst/extdata/S40mR1.bam", checkIfExists: true) ] - ] - input[1] = file( - "https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/homo_sapiens/genome/genome.gtf", - checkIfExists: true - ) - input[2] = file("https://raw.githubusercontent.com/nf-core/test-datasets/nascent/misc/tune.csv", checkIfExists: true) + file("https://raw.githubusercontent.com/Kraus-Lab/groHMM/master/inst/extdata/S40mR1.bam", checkIfExists: true) ], + [], + ]) + input[1] = Channel.of([file( + "https://raw.githubusercontent.com/nf-core/test-datasets/nascent/reference/hg19.chr7.refGene.gtf", + checkIfExists: true + )]).first() """ } } then { - assert workflow.success - assert snapshot(workflow.out).match() + assertAll( + { assert workflow.success }, + // FIXME this snapshot reports nothing? Probably the test + { assert snapshot( + workflow.trace.tasks().size(), + workflow.out.transcripts, + workflow.out.bed, + // workflow.out.td_plot, + ).match() + }, + { + assert snapshot( + path(workflow.out.versions.get(0)).yaml + ).match("versions") + }, + ) } - } - } diff --git a/subworkflows/local/grohmm/tests/main.nf.test.snap b/subworkflows/local/grohmm/tests/main.nf.test.snap new file mode 100644 index 00000000..d5b4fa62 --- /dev/null +++ b/subworkflows/local/grohmm/tests/main.nf.test.snap @@ -0,0 +1,33 @@ +{ + "versions": { + "content": [ + { + "GROHMM:GROHMM_PARAMETERTUNING": { + "r-base": "4.3.3", + "bioconductor-grohmm": "1.39.0" + } + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-24T12:58:04.996402914" + }, + "Should run without a tuning file and multiplex": { + "content": [ + 4, + [ + + ], + [ + + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-24T16:07:41.806165357" + } +} \ No newline at end of file diff --git a/subworkflows/local/prepare_genome.nf b/subworkflows/local/prepare_genome.nf index 8b860e25..1e802c27 100644 --- a/subworkflows/local/prepare_genome.nf +++ b/subworkflows/local/prepare_genome.nf @@ -2,22 +2,24 @@ // Uncompress and prepare reference genome files // -include { GTF2BED } from '../../modules/local/gtf2bed' +include { GTF2BED } from '../../modules/local/gtf2bed' include { - GUNZIP as GUNZIP_FASTA - GUNZIP as GUNZIP_GTF - GUNZIP as GUNZIP_GFF - GUNZIP as GUNZIP_GENE_BED } from '../../modules/nf-core/gunzip/main' + GUNZIP as GUNZIP_FASTA ; + GUNZIP as GUNZIP_GTF ; + GUNZIP as GUNZIP_GFF ; + GUNZIP as GUNZIP_GENE_BED +} from '../../modules/nf-core/gunzip/main' include { - UNTAR as UNTAR_BWA_INDEX - UNTAR as UNTAR_DRAGMAP } from '../../modules/nf-core/untar/main' -include { GFFREAD } from '../../modules/nf-core/gffread/main' -include { BWA_INDEX } from '../../modules/nf-core/bwa/index/main' -include { BWAMEM2_INDEX } from '../../modules/nf-core/bwamem2/index/main' -include { DRAGMAP_HASHTABLE } from '../../modules/nf-core/dragmap/hashtable/main' -include { BOWTIE2_BUILD } from '../../modules/nf-core/bowtie2/build/main' -include { CUSTOM_GETCHROMSIZES } from '../../modules/nf-core/custom/getchromsizes/main' + UNTAR as UNTAR_BWA_INDEX ; + UNTAR as UNTAR_DRAGMAP +} from '../../modules/nf-core/untar/main' +include { GFFREAD } from '../../modules/nf-core/gffread/main' +include { BWA_INDEX } from '../../modules/nf-core/bwa/index/main' +include { BWAMEM2_INDEX } from '../../modules/nf-core/bwamem2/index/main' +include { DRAGMAP_HASHTABLE } from '../../modules/nf-core/dragmap/hashtable/main' +include { BOWTIE2_BUILD } from '../../modules/nf-core/bowtie2/build/main' +include { CUSTOM_GETCHROMSIZES } from '../../modules/nf-core/custom/getchromsizes/main' workflow PREPARE_GENOME { take: @@ -25,6 +27,12 @@ workflow PREPARE_GENOME { fasta gtf gff + gene_bed + bwa_index + bwamem2_index + dragmap + bowtie2_index + hisat2_index main: @@ -34,9 +42,10 @@ workflow PREPARE_GENOME { // Uncompress genome fasta file if required // if (fasta.endsWith('.gz')) { - ch_fasta = GUNZIP_FASTA ( [ [:], fasta ] ).gunzip.map { it[1] } + ch_fasta = GUNZIP_FASTA([[:], fasta]).gunzip.map { it[1] } ch_versions = ch_versions.mix(GUNZIP_FASTA.out.versions) - } else { + } + else { ch_fasta = Channel.value(file(fasta)) } @@ -46,19 +55,22 @@ workflow PREPARE_GENOME { if (gtf || gff) { if (gtf) { if (gtf.endsWith('.gz')) { - ch_gtf = GUNZIP_GTF ( [ [:], gtf ] ).gunzip.map { it[1] } + ch_gtf = GUNZIP_GTF([[:], gtf]).gunzip.map { it[1] } ch_versions = ch_versions.mix(GUNZIP_GTF.out.versions) - } else { + } + else { ch_gtf = Channel.value(file(gtf)) } - } else if (gff) { + } + else if (gff) { if (gff.endsWith('.gz')) { - ch_gff = GUNZIP_GFF ( [ [:], gff ] ).gunzip.map { it[1] } + ch_gff = GUNZIP_GFF([[:], gff]).gunzip ch_versions = ch_versions.mix(GUNZIP_GFF.out.versions) - } else { - ch_gff = Channel.value(file(gff)) } - ch_gtf = GFFREAD ( ch_gff ).gtf + else { + ch_gff = [[:], file(gff)] + } + ch_gtf = GFFREAD(ch_gff, ch_fasta).gtf.map { it[1] } ch_versions = ch_versions.mix(GFFREAD.out.versions) } } @@ -66,25 +78,27 @@ workflow PREPARE_GENOME { // // Uncompress gene BED annotation file or create from GTF if required // - if (params.gene_bed) { - if (params.gene_bed.endsWith('.gz')) { - ch_gene_bed = GUNZIP_GENE_BED ( [ [:], params.gene_bed ] ).gunzip.map { it[1] } + if (gene_bed) { + if (gene_bed.endsWith('.gz')) { + ch_gene_bed = GUNZIP_GENE_BED([[:], gene_bed]).gunzip.map { it[1] } ch_versions = ch_versions.mix(GUNZIP_GENE_BED.out.versions) - } else { - ch_gene_bed = file(params.gene_bed) } - } else { - ch_gene_bed = GTF2BED ( ch_gtf ).bed + else { + ch_gene_bed = file(gene_bed) + } + } + else { + ch_gene_bed = GTF2BED(ch_gtf).bed ch_versions = ch_versions.mix(GTF2BED.out.versions) } // // Create chromosome sizes file // - CUSTOM_GETCHROMSIZES ( ch_fasta.map { [ [:], it ] } ) - ch_fai = CUSTOM_GETCHROMSIZES.out.fai.map { it[1] } + CUSTOM_GETCHROMSIZES(ch_fasta.map { [[:], it] }) + ch_fai = CUSTOM_GETCHROMSIZES.out.fai.map { it[1] } ch_chrom_sizes = CUSTOM_GETCHROMSIZES.out.sizes.map { it[1] } - ch_versions = ch_versions.mix(CUSTOM_GETCHROMSIZES.out.versions) + ch_versions = ch_versions.mix(CUSTOM_GETCHROMSIZES.out.versions) // // Uncompress BWA index or generate from scratch if required @@ -94,68 +108,78 @@ workflow PREPARE_GENOME { ch_bowtie2_index = Channel.empty() // TODO Turn this into a switch if ('bwa' in prepare_tool_indices) { - if (params.bwa_index) { - if (params.bwa_index.endsWith('.tar.gz')) { - ch_bwa_index = UNTAR_BWA_INDEX ( params.bwa_index ).untar + if (bwa_index) { + if (bwa_index.endsWith('.tar.gz')) { + ch_bwa_index = UNTAR_BWA_INDEX([[:], bwa_index]).untar ch_versions = ch_versions.mix(UNTAR_BWA_INDEX.out.versions) - } else { + } + else { // TODO Give the meta from basename or genome? - ch_bwa_index = [ [meta: "Genome"], file(params.bwa_index) ] + ch_bwa_index = [[meta: "Genome"], file(bwa_index)] } - } else { - ch_bwa_index = BWA_INDEX ( ch_fasta.map { [ [:], it ] } ).index + } + else { + ch_bwa_index = BWA_INDEX(ch_fasta.map { [[:], it] }).index ch_versions = ch_versions.mix(BWA_INDEX.out.versions) } - } else if ('bwamem2' in prepare_tool_indices) { - if (params.bwamem2_index) { - if (params.bwamem2_index.endsWith('.tar.gz') || params.bwamem2_index.endsWith('.tgz')) { - ch_bwa_index = UNTAR_BWA_INDEX ( [ [:], params.bwamem2_index ] ).untar + } + else if ('bwamem2' in prepare_tool_indices) { + if (bwamem2_index) { + if (bwamem2_index.endsWith('.tar.gz') || bwamem2_index.endsWith('.tgz')) { + ch_bwa_index = UNTAR_BWA_INDEX([[:], bwamem2_index]).untar ch_versions = ch_versions.mix(UNTAR_BWA_INDEX.out.versions) - } else { + } + else { // TODO Give the meta from basename or genome? - ch_bwa_index = [ [meta: "Genome"], file(params.bwamem2_index) ] + ch_bwa_index = [[meta: "Genome"], file(bwamem2_index)] } - } else { - ch_bwa_index = BWAMEM2_INDEX ( ch_fasta.map { [ [:], it ] } ).index + } + else { + ch_bwa_index = BWAMEM2_INDEX(ch_fasta.map { [[:], it] }).index ch_versions = ch_versions.mix(BWAMEM2_INDEX.out.versions) } - } else if ('dragmap' in prepare_tool_indices) { - if (params.dragmap) { - if (params.dragmap.endsWith('.tar.gz')) { - ch_dragmap = UNTAR_DRAGMAP_INDEX ( params.dragmap ).untar + } + else if ('dragmap' in prepare_tool_indices) { + if (dragmap) { + if (dragmap.endsWith('.tar.gz')) { + ch_dragmap = UNTAR_DRAGMAP_INDEX(dragmap).untar ch_versions = ch_versions.mix(UNTAR_DRAGMAP_INDEX.out.versions) - } else { + } + else { // TODO Give the meta from basename or genome? - ch_dragmap = [ [meta: "Genome"], file(params.dragmap) ] + ch_dragmap = [[meta: "Genome"], file(dragmap)] } - } else { - ch_dragmap = DRAGMAP_HASHTABLE( ch_fasta.map { [ [:], it ] } ).hashmap + } + else { + ch_dragmap = DRAGMAP_HASHTABLE(ch_fasta.map { [[:], it] }).hashmap ch_versions = ch_versions.mix(DRAGMAP_HASHTABLE.out.versions) } - } else if ('bowtie2' in prepare_tool_indices) { - if (params.bowtie2_index) { - if (params.bowtie2_index.endsWith('.tar.gz')) { - ch_bowtie2_index = UNTAR_BOWTIE2_INDEX ( params.bowtie2_index ).untar + } + else if ('bowtie2' in prepare_tool_indices) { + if (bowtie2_index) { + if (bowtie2_index.endsWith('.tar.gz')) { + ch_bowtie2_index = UNTAR_BOWTIE2_INDEX(bowtie2_index).untar ch_versions = ch_versions.mix(UNTAR_BOWTIE2_INDEX.out.versions) - } else { + } + else { // TODO Give the meta from basename or genome? - ch_bowtie2_index = [ [meta: "Genome"], file(params.bowtie2_index) ] + ch_bowtie2_index = [[meta: "Genome"], file(bowtie2_index)] } - } else { - ch_bowtie2_index = BOWTIE2_BUILD ( ch_fasta.map { [ [:], it ] } ).index + } + else { + ch_bowtie2_index = BOWTIE2_BUILD(ch_fasta.map { [[:], it] }).index ch_versions = ch_versions.mix(BOWTIE2_BUILD.out.versions) } } emit: - fasta = ch_fasta - fai = ch_fai - gtf = ch_gtf - gene_bed = ch_gene_bed - chrom_sizes = ch_chrom_sizes - bwa_index = ch_bwa_index - dragmap = ch_dragmap + fasta = ch_fasta + fai = ch_fai + gtf = ch_gtf + gene_bed = ch_gene_bed + chrom_sizes = ch_chrom_sizes + bwa_index = ch_bwa_index + dragmap = ch_dragmap bowtie2_index = ch_bowtie2_index - - versions = ch_versions.ifEmpty(null) + versions = ch_versions.ifEmpty(null) } diff --git a/subworkflows/local/quality_control.nf b/subworkflows/local/quality_control.nf index dd438bcc..9169d4cd 100644 --- a/subworkflows/local/quality_control.nf +++ b/subworkflows/local/quality_control.nf @@ -1,56 +1,44 @@ -include { PRESEQ_CCURVE } from '../../modules/nf-core/preseq/ccurve/main' +include { PRESEQ_CCURVE } from '../../modules/nf-core/preseq/ccurve/main' include { PRESEQ_LCEXTRAP } from '../../modules/nf-core/preseq/lcextrap/main' -include { RSEQC_READDISTRIBUTION } from '../../modules/nf-core/rseqc/readdistribution/main' -include { RSEQC_READDUPLICATION } from '../../modules/nf-core/rseqc/readduplication/main' -include { RSEQC_INFEREXPERIMENT } from '../../modules/nf-core/rseqc/inferexperiment/main' -include { BBMAP_PILEUP } from '../../modules/nf-core/bbmap/pileup/main' +include { BBMAP_PILEUP } from '../../modules/nf-core/bbmap/pileup/main' + +include { BAM_RSEQC } from '../../subworkflows/nf-core/bam_rseqc' workflow QUALITY_CONTROL { take: - bam + bam_bai bed main: + bam = bam_bai.map { [it[0], it[1]] } + ch_versions = Channel.empty() - PRESEQ_CCURVE ( bam ) + PRESEQ_CCURVE(bam) ch_versions = ch_versions.mix(PRESEQ_CCURVE.out.versions.first()) - PRESEQ_LCEXTRAP ( bam ) + PRESEQ_LCEXTRAP(bam) ch_versions = ch_versions.mix(PRESEQ_LCEXTRAP.out.versions.first()) - RSEQC_READDISTRIBUTION ( - bam, - bed - ) - ch_versions = ch_versions.mix(RSEQC_READDISTRIBUTION.out.versions.first()) - - RSEQC_READDUPLICATION ( bam ) - ch_versions = ch_versions.mix(RSEQC_READDUPLICATION.out.versions.first()) - - RSEQC_INFEREXPERIMENT ( - bam, - bed - ) - ch_versions = ch_versions.mix(RSEQC_INFEREXPERIMENT.out.versions.first()) + // TODO Set this in a param? + rseqc_modules = ['read_duplication', 'read_distribution', 'infer_experiment'] + BAM_RSEQC(bam_bai, bed, rseqc_modules) + ch_versions = ch_versions.mix(BAM_RSEQC.out.versions) - BBMAP_PILEUP ( bam ) + BBMAP_PILEUP(bam) ch_versions = ch_versions.mix(BBMAP_PILEUP.out.versions.first()) emit: - preseq_ccurve = PRESEQ_CCURVE.out.c_curve - preseq_lcextrap = PRESEQ_LCEXTRAP.out.lc_extrap - - readdistribution_txt = RSEQC_READDISTRIBUTION.out.txt - readduplication_seq_xls = RSEQC_READDUPLICATION.out.seq_xls - readduplication_pos_xls = RSEQC_READDUPLICATION.out.pos_xls - readduplication_pdf = RSEQC_READDUPLICATION.out.pdf - readduplication_rscript = RSEQC_READDUPLICATION.out.rscript - inferexperiment_txt = RSEQC_INFEREXPERIMENT.out.txt - - pileup_stats = BBMAP_PILEUP.out.covstats - pileup_hist = BBMAP_PILEUP.out.hist - - versions = ch_versions + preseq_ccurve = PRESEQ_CCURVE.out.c_curve + preseq_lcextrap = PRESEQ_LCEXTRAP.out.lc_extrap + inferexperiment_txt = BAM_RSEQC.out.inferexperiment_txt + readdistribution_txt = BAM_RSEQC.out.readdistribution_txt + readduplication_seq_xls = BAM_RSEQC.out.readduplication_seq_xls + readduplication_pos_xls = BAM_RSEQC.out.readduplication_pos_xls + readduplication_pdf = BAM_RSEQC.out.readduplication_pdf + readduplication_rscript = BAM_RSEQC.out.readduplication_rscript + pileup_stats = BBMAP_PILEUP.out.covstats + pileup_hist = BBMAP_PILEUP.out.hist + versions = ch_versions } diff --git a/subworkflows/local/transcript_identification.nf b/subworkflows/local/transcript_identification.nf deleted file mode 100644 index 27c88707..00000000 --- a/subworkflows/local/transcript_identification.nf +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Calls Transcripts and Transcript Start Sites and various cleaning steps - */ - -include { GROHMM } from './grohmm/main' -include { HOMER_GROSEQ } from '../nf-core/homer/groseq/main' -include { PINTS_CALLER } from '../../modules/nf-core/pints/caller/main' -include { CAT_CAT } from '../../modules/nf-core/cat/cat/main' -include { BEDTOOLS_MERGE } from '../../modules/nf-core/bedtools/merge/main' -include { BEDTOOLS_SORT } from '../../modules/nf-core/bedtools/sort/main' -include { BEDTOOLS_INTERSECT as BEDTOOLS_INTERSECT_FILTER } from '../../modules/nf-core/bedtools/intersect/main' -include { BEDTOOLS_INTERSECT } from '../../modules/nf-core/bedtools/intersect/main' - -workflow TRANSCRIPT_INDENTIFICATION { - take: - group_bams - gtf - fasta - chrom_sizes - - main: - - ch_versions = Channel.empty() - ch_identification_bed = Channel.empty() - - ch_tuning_file = params.tuning_file ? file(params.tuning_file, checkIfExists: true) : file("${projectDir}/assets/tuningparamstotest.csv") - grohmm_td_plot = Channel.empty() - if(!params.skip_grohmm && params.assay_type == "GROseq") { - GROHMM ( group_bams, gtf, ch_tuning_file ) - ch_identification_bed = ch_identification_bed.mix(GROHMM.out.bed) - grohmm_td_plot = GROHMM.out.td_plot - ch_versions = ch_versions.mix(GROHMM.out.versions.first()) - } - - - homer_peaks = Channel.empty() - homer_tagdir = Channel.empty() - if(params.assay_type == "GROseq") { - HOMER_GROSEQ ( group_bams, fasta ) - ch_identification_bed = ch_identification_bed.mix(HOMER_GROSEQ.out.bed) - homer_peaks = HOMER_GROSEQ.out.peaks - homer_tagdir = HOMER_GROSEQ.out.tagdir - ch_versions = ch_versions.mix(HOMER_GROSEQ.out.versions.first()) - } - - - // TODO https://github.com/hyulab/PINTS/issues/15 - PINTS_CALLER ( group_bams, params.assay_type ) - ch_versions = ch_versions.mix(PINTS_CALLER.out.versions.first()) - // HACK Not sure if this is as good as reporting all of them, but it should - // reduce the overall noise. - CAT_CAT ( PINTS_CALLER.out.bidirectional_TREs ) - ch_versions = ch_versions.mix(CAT_CAT.out.versions.first()) - BEDTOOLS_SORT ( CAT_CAT.out.file_out, [] ) - ch_versions = ch_versions.mix(BEDTOOLS_SORT.out.versions.first()) - BEDTOOLS_MERGE ( BEDTOOLS_SORT.out.sorted ) - ch_identification_bed = ch_identification_bed.mix(BEDTOOLS_MERGE.out.bed) - ch_versions = ch_versions.mix(BEDTOOLS_MERGE.out.versions.first()) - - if(params.filter_bed) { - ch_filter_bed = Channel.from(params.filter_bed) - BEDTOOLS_INTERSECT_FILTER ( ch_identification_bed.combine(ch_filter_bed), chrom_sizes.map { [ [:], it ] } ) - ch_identification_bed = BEDTOOLS_INTERSECT_FILTER.out.intersect - ch_versions = ch_versions.mix(BEDTOOLS_INTERSECT_FILTER.out.versions.first()) - } - if(params.intersect_bed) { - ch_intersect_bed = Channel.from(params.intersect_bed) - BEDTOOLS_INTERSECT ( ch_identification_bed.combine(ch_intersect_bed), chrom_sizes.map { [ [:], it ] } ) - ch_identification_bed = BEDTOOLS_INTERSECT.out.intersect - ch_versions = ch_versions.mix(BEDTOOLS_INTERSECT.out.versions.first()) - } - - ch_identification_bed - // Drop any empty bed files - .filter { meta, bed -> bed.size() > 0 } - .set { ch_identification_bed_clean } - - emit: - grohmm_td_plot - homer_peaks - homer_tagdir - - transcript_beds = ch_identification_bed_clean - - versions = ch_versions -} diff --git a/subworkflows/local/transcript_identification/main.nf b/subworkflows/local/transcript_identification/main.nf new file mode 100644 index 00000000..537c8552 --- /dev/null +++ b/subworkflows/local/transcript_identification/main.nf @@ -0,0 +1,118 @@ +/* + * Calls Transcripts and Transcript Start Sites and various cleaning steps + */ + +include { GROHMM } from '../grohmm' +include { HOMER_GROSEQ } from '../../nf-core/homer_groseq' +include { PINTS_CALLER } from '../../../modules/nf-core/pints/caller/main' +include { SAMTOOLS_MERGE } from '../../../modules/nf-core/samtools/merge/main' +include { CAT_CAT } from '../../../modules/nf-core/cat/cat/main' +include { BEDTOOLS_MERGE } from '../../../modules/nf-core/bedtools/merge/main' +include { BEDTOOLS_SORT } from '../../../modules/nf-core/bedtools/sort/main' +include { BEDTOOLS_INTERSECT as BEDTOOLS_INTERSECT_FILTER } from '../../../modules/nf-core/bedtools/intersect/main' +include { BEDTOOLS_INTERSECT } from '../../../modules/nf-core/bedtools/intersect/main' + +workflow TRANSCRIPT_INDENTIFICATION { + take: + group_bam_bai + gxf + fasta + chrom_sizes + uniqmap + + main: + + ch_versions = Channel.empty() + ch_identification_bed = Channel.empty() + + grohmm_td_plot = Channel.empty() + if (!params.skip_grohmm && params.assay_type == "GROseq") { + GROHMM(group_bam_bai, gxf) + ch_identification_bed = ch_identification_bed.mix(GROHMM.out.bed) + grohmm_td_plot = GROHMM.out.td_plot + ch_versions = ch_versions.mix(GROHMM.out.versions.first()) + } + + + homer_peaks = Channel.empty() + homer_tagdir = Channel.empty() + if (params.assay_type == "GROseq") { + group_bam = group_bam_bai.map { meta, bam, _bai -> [meta, bam] } + HOMER_GROSEQ(group_bam, fasta, uniqmap) + ch_identification_bed = ch_identification_bed.mix(HOMER_GROSEQ.out.bed) + homer_peaks = HOMER_GROSEQ.out.peaks + homer_tagdir = HOMER_GROSEQ.out.tagdir + ch_versions = ch_versions.mix(HOMER_GROSEQ.out.versions.first()) + } + + // Scatter the chromosomes + // TODO Might turn this into a param + skip_chr = ["chrY", "_random", "chrUn_", "chrEBV", "chrM"] + ch_chr = fasta + .splitFasta(record: [id: true]) + .map { record -> record.id } + .filter { !(it in skip_chr) } + + // NOTE https://github.com/hyulab/PINTS/issues/15 + // We want to run PINTS once per biological/technical sample. + // Let Nextflow handle the parallelization Per the docs + // Per the docs: + // {SID} will be replaced with the number of samples that peaks are called from, + // if you only provide PINTS with one sample, then {SID} will be replaced with 1, + // if you try to use PINTS with three replicates (--bam-file A.bam B.bam C.bam), + // then {SID} for peaks identified from A.bam will be replaced with 1. + SAMTOOLS_MERGE( + group_bam_bai.map { meta, bams, _bais -> [meta, bams] }, + [[], []], + [[], []] + ) + ch_versions = ch_versions.mix(SAMTOOLS_MERGE.out.versions.first()) + + PINTS_CALLER( + SAMTOOLS_MERGE.out.bam.combine(ch_chr), + params.assay_type + ) + ch_versions = ch_versions.mix(PINTS_CALLER.out.versions.first()) + + // Gather the chromosomes + // TODO Tests don't seem to hit this because there's no bidirectional_TREs + // Need to collect all of the beds for each chromosome/sample and concatenate them + // Nextflow makes this super easy + ch_bidirectional_tres = PINTS_CALLER.out.unidirectional_TREs.groupTuple(by: [0]).map { meta, beds -> + [meta, beds.flatten()] + } + + // HACK Not sure if this is as good as reporting all of them, but it should + // reduce the overall noise. + CAT_CAT(ch_bidirectional_tres) + ch_versions = ch_versions.mix(CAT_CAT.out.versions.first()) + BEDTOOLS_SORT(CAT_CAT.out.file_out, []) + ch_versions = ch_versions.mix(BEDTOOLS_SORT.out.versions.first()) + BEDTOOLS_MERGE(BEDTOOLS_SORT.out.sorted) + ch_identification_bed = ch_identification_bed.mix(BEDTOOLS_MERGE.out.bed) + ch_versions = ch_versions.mix(BEDTOOLS_MERGE.out.versions.first()) + + if (params.filter_bed) { + ch_filter_bed = Channel.from(params.filter_bed) + BEDTOOLS_INTERSECT_FILTER(ch_identification_bed.combine(ch_filter_bed.first()), chrom_sizes.map { [[:], it] }) + ch_identification_bed = BEDTOOLS_INTERSECT_FILTER.out.intersect + ch_versions = ch_versions.mix(BEDTOOLS_INTERSECT_FILTER.out.versions.first()) + } + if (params.intersect_bed) { + ch_intersect_bed = Channel.from(params.intersect_bed) + BEDTOOLS_INTERSECT(ch_identification_bed.combine(ch_intersect_bed.first()), chrom_sizes.map { [[:], it] }) + ch_identification_bed = BEDTOOLS_INTERSECT.out.intersect + ch_versions = ch_versions.mix(BEDTOOLS_INTERSECT.out.versions.first()) + } + + ch_identification_bed + .filter { _meta, bed -> bed.size() > 0 } + .set { ch_identification_bed_clean } + + emit: + grohmm_td_plot + homer_peaks + homer_tagdir + transcript_beds = ch_identification_bed_clean + versions = ch_versions +} diff --git a/subworkflows/local/transcript_identification/tests/main.nf.test b/subworkflows/local/transcript_identification/tests/main.nf.test new file mode 100644 index 00000000..dcb5dc56 --- /dev/null +++ b/subworkflows/local/transcript_identification/tests/main.nf.test @@ -0,0 +1,2 @@ +// TODO Test ChrY filtering +// TODO Test _random filtering diff --git a/subworkflows/local/utils_nfcore_nascent_pipeline/main.nf b/subworkflows/local/utils_nfcore_nascent_pipeline/main.nf new file mode 100644 index 00000000..9a421fa5 --- /dev/null +++ b/subworkflows/local/utils_nfcore_nascent_pipeline/main.nf @@ -0,0 +1,291 @@ +// +// Subworkflow with functionality specific to the nf-core/nascent pipeline +// + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +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 { imNotification } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + SUBWORKFLOW TO INITIALISE PIPELINE +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow PIPELINE_INITIALISATION { + take: + version // boolean: Display version and exit + validate_params // boolean: Boolean whether to validate parameters against the schema at runtime + 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: + + ch_versions = Channel.empty() + + // + // Print version and exit if required and dump pipeline parameters to JSON file + // + UTILS_NEXTFLOW_PIPELINE( + version, + true, + outdir, + workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1 + ) + + // + // Validate parameters and generate parameter summary to stdout + // + UTILS_NFSCHEMA_PLUGIN( + workflow, + validate_params, + null + ) + + // + // Check config provided to the pipeline + // + UTILS_NFCORE_PIPELINE( + nextflow_cli_args + ) + + // + // Custom validation for pipeline parameters + // + 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 -> + if (!fastq_2) { + return [meta.id, meta + [single_end: true], [fastq_1]] + } + else { + return [meta.id, meta + [single_end: false], [fastq_1, fastq_2]] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { meta, fastqs -> + return [meta, fastqs.flatten()] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + SUBWORKFLOW FOR PIPELINE COMPLETION +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow PIPELINE_COMPLETION { + take: + email // string: email address + email_on_fail // string: email address sent on pipeline failure + plaintext_email // boolean: Send plain-text email instead of HTML + outdir // path: Path to output directory where results will be published + monochrome_logs // boolean: Disable ANSI colour codes in log output + hook_url // string: hook URL for notifications + multiqc_report // string: Path to MultiQC report + + main: + summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json") + def multiqc_reports = multiqc_report.toList() + + // + // Completion email and summary + // + workflow.onComplete { + if (email || email_on_fail) { + completionEmail( + summary_params, + email, + email_on_fail, + plaintext_email, + outdir, + monochrome_logs, + multiqc_reports.getVal() + ) + } + + completionSummary(monochrome_logs) + if (hook_url) { + imNotification(summary_params, hook_url) + } + } + + workflow.onError { + log.error("Pipeline failed. Please refer to troubleshooting docs: https://nf-co.re/docs/usage/troubleshooting") + } +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +// +// Check and validate pipeline parameters +// +def validateInputParameters() { + genomeExistsError() +} + +// +// Validate channels from input samplesheet +// +def validateInputSamplesheet(input) { + def (metas, fastqs) = input[1..2] + + // Check that multiple runs of the same sample are of the same datatype i.e. single-end / paired-end + def endedness_ok = metas.collect { meta -> meta.single_end }.unique().size == 1 + if (!endedness_ok) { + error("Please check input samplesheet -> Multiple runs of a sample must be of the same datatype i.e. single-end or paired-end: ${metas[0].id}") + } + + return [metas[0], fastqs] +} +// +// Get attribute from genome config file e.g. fasta +// +def getGenomeAttribute(attribute) { + if (params.genomes && params.genome && params.genomes.containsKey(params.genome)) { + if (params.genomes[params.genome].containsKey(attribute)) { + return params.genomes[params.genome][attribute] + } + } + return null +} + +// +// Exit pipeline if incorrect --genome key provided +// +def genomeExistsError() { + if (params.genomes && params.genome && !params.genomes.containsKey(params.genome)) { + def error_string = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " Genome '${params.genome}' not found in any config files provided to the pipeline.\n" + " Currently, the available genome keys are:\n" + " ${params.genomes.keySet().join(", ")}\n" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + error(error_string) + } +} +// +// Generate methods description for MultiQC +// +def toolCitationText() { + // Can use ternary operators to dynamically construct based conditions, e.g. params["run_xyz"] ? "Tool (Foo et al. 2023)" : "", + // Uncomment function in methodsDescriptionText to render in MultiQC report + def citation_text = "Tools used in the workflow included: " + [ + "BEDTools (Quinlan 2010)", + "Bowtie 2 (Langmead 2012)", + "BWA-MEM (Li 2013)", // TODO if bwamem + "BWA-MEM2 (Vasimuddin 2019)", // TODO if bwamem2 + "deepTools (Ramírez 2016)", + "FastQC (Andrews 2010)", + "FastP (Chen 2018)", // TODO if trimming + "featureCounts (Liao 2013)", + "GffRead (Pertea 2013)", + "HISAT2 (Kim 2019)", // TODO if hisat2 + "HOMER (Heinz 2010)", // TODO if homer + "MultiQC (Ewels et al. 2016)", + "PINTS (Yao 2022)", // TODO if pints + "preseq (Daley 2013)", + "RSeQC (Wang 2012)", + "SAMTools (Li 2009)", + "STAR (Dobin 2013)", // TODO if STAR + "UMI-tools (Li 2009)", + "Genomic Alignments (Lawrence 2013)", + "groHMM (Chae 2015)", // TODO if grohmm + "." + ].join(', ').trim() + + return citation_text +} + +def toolBibliographyText() { + // Can use ternary operators to dynamically construct based conditions, e.g. params["run_xyz"] ? "
  • Author (2023) Pub name, Journal, DOI
  • " : "", + // Uncomment function in methodsDescriptionText to render in MultiQC report + def reference_text = "
  • " + [ + "Quinlan AR, Hall IM. BEDTools: a flexible suite of utilities for comparing genomic features. Bioinformatics. 2010 Mar 15;26(6):841-2. doi: 10.1093/bioinformatics/btq033. Epub 2010 Jan 28. PubMed PMID: 20110278; PubMed Central PMCID: PMC2832824.", + "Langmead, B., Salzberg, S. Fast gapped-read alignment with Bowtie 2. Nat Methods 9, 357–359 (2012). doi: 10.1038/nmeth.1923.", + "Li H: Aligning sequence reads, clone sequences and assembly contigs with BWA-MEM. arXiv 2013. doi: 10.48550/arXiv.1303.3997", // TODO if bwamem + "M. Vasimuddin, S. Misra, H. Li and S. Aluru, Efficient Architecture-Aware Acceleration of BWA-MEM for Multicore Systems, 2019 IEEE International Parallel and Distributed Processing Symposium (IPDPS), 2019, pp. 314-324. doi: 10.1109/IPDPS.2019.00041.", // TODO if bwamem2 + "Ramírez, Fidel, Devon P. Ryan, Björn Grüning, Vivek Bhardwaj, Fabian Kilpert, Andreas S. Richter, Steffen Heyne, Friederike Dündar, and Thomas Manke. deepTools2: A next Generation Web Server for Deep-Sequencing Data Analysis. Nucleic Acids Research (2016). doi:10.1093/nar/gkw257.", + "Shifu Chen, Yanqing Zhou, Yaru Chen, Jia Gu, fastp: an ultra-fast all-in-one FASTQ preprocessor, Bioinformatics, Volume 34, Issue 17, 01 September 2018, Pages i884–i890, doi: 10.1093/bioinformatics/bty560. PubMed PMID: 30423086. PubMed Central PMCID: PMC6129281", + "Andrews, S. (2010). FastQC: A Quality Control Tool for High Throughput Sequence Data [Online].", + "Liao Y, Smyth GK, Shi W. featureCounts: an efficient general purpose program for assigning sequence reads to genomic features. Bioinformatics. 2014 Apr 1;30(7):923-30. doi: 10.1093/bioinformatics/btt656. Epub 2013 Nov 13. PubMed PMID: 24227677.", + "Pertea G, Pertea M. GFF Utilities: GffRead and GffCompare. F1000Res. 2020 Apr 28;9:ISCB Comm J-304. doi: 10.12688/f1000research.23297.2. eCollection 2020. PubMed PMID: 32489650; PubMed Central PMCID: PMC7222033.", + "Kim D, Paggi JM, Park C, Bennett C, Salzberg SL. Graph-based genome alignment and genotyping with HISAT2 and HISAT-genotype Graph-based genome alignment and genotyping with HISAT2 and HISAT-genotype. Nat Biotechnol. 2019 Aug;37(8):907-915. doi: 10.1038/s41587-019-0201-4. Epub 2019 Aug 2. PubMed PMID: 31375807.", // TODO if hisat2 + "Heinz S, Benner C, Spann N, Bertolino E et al. Simple Combinations of Lineage-Determining Transcription Factors Prime cis-Regulatory Elements Required for Macrophage and B Cell Identities. Mol Cell 2010 May 28;38(4):576-589. PMID: 20513432", // TODO if homer + "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.", + "Yao, L., Liang, J., Ozer, A. et al. A comparison of experimental assays and analytical methods for genome-wide identification of active enhancers. Nat Biotechnol 40, 1056–1065 (2022). https://doi.org/10.1038/s41587-022-01211-7", // TODO if pints + "Daley T, Smith AD. Predicting the molecular complexity of sequencing libraries. Nat Methods. 2013 Apr;10(4):325-7. doi: 10.1038/nmeth.2375. Epub 2013 Feb 24. PubMed PMID: 23435259; PubMed Central PMCID: PMC3612374.", + "Wang L, Wang S, Li W. RSeQC: quality control of RNA-seq experiments Bioinformatics. 2012 Aug 15;28(16):2184-5. doi: 10.1093/bioinformatics/bts356. Epub 2012 Jun 27. PubMed PMID: 22743226.", + "Li H, Handsaker B, Wysoker A, Fennell T, Ruan J, Homer N, Marth G, Abecasis G, Durbin R; 1000 Genome Project Data Processing Subgroup. The Sequence Alignment/Map format and SAMtools. Bioinformatics. 2009 Aug 15;25(16):2078-9. doi: 10.1093/bioinformatics/btp352. Epub 2009 Jun 8. PubMed PMID: 19505943; PubMed Central PMCID: PMC2723002.", + "Dobin A, Davis CA, Schlesinger F, Drenkow J, Zaleski C, Jha S, Batut P, Chaisson M, Gingeras TR. STAR: ultrafast universal RNA-seq aligner Bioinformatics. 2013 Jan 1;29(1):15-21. doi: 10.1093/bioinformatics/bts635. Epub 2012 Oct 25. PubMed PMID: 23104886; PubMed Central PMCID: PMC3530905.", // TODO if STAR + "Smith T, Heger A, Sudbery I. UMI-tools: modeling sequencing errors in Unique Molecular Identifiers to improve quantification accuracy Genome Res. 2017 Mar;27(3):491-499. doi: 10.1101/gr.209601.116. Epub 2017 Jan 18. PubMed PMID: 28100584; PubMed Central PMCID: PMC5340976.", + "Lawrence M, Huber W, Pagès H, Aboyoun P, Carlson M, Gentleman R, Morgan M, Carey V (2013). “Software for Computing and Annotating Genomic Ranges.” PLoS Computational Biology, 9. doi: 10.1371/journal.pcbi.1003118, http://www.ploscompbiol.org/article/info%3Adoi%2F10.1371%2Fjournal.pcbi.1003118.", + "Chae M, Danko CG, Kraus WL (2015). “groHMM: a computational tool for identifying unannotated and cell type-specific transcription units from global run-on sequencing data.” BMC Bioinformatics, 16(222).", // TODO if grohmm + ].join('
  • ').trim() + + return reference_text +} + +def methodsDescriptionText(mqc_methods_yaml) { + // 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 + 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"] = "" + + meta["tool_citations"] = toolCitationText().replaceAll(", \\.", ".").replaceAll("\\. \\.", ".").replaceAll(", \\.", ".") + meta["tool_bibliography"] = toolBibliographyText() + + + def methods_text = mqc_methods_yaml.text + + def engine = new groovy.text.SimpleTemplateEngine() + def description_html = engine.createTemplate(methods_text).make(meta) + + return description_html.toString() +} diff --git a/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/main.nf b/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/main.nf index 7c07084f..fe6ff312 100644 --- a/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/main.nf +++ b/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/main.nf @@ -44,6 +44,7 @@ workflow BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS { emit: bam = UMITOOLS_DEDUP.out.bam // channel: [ val(meta), path(bam) ] + deduplog = UMITOOLS_DEDUP.out.log // channel: [ val(meta), path(log) ] bai = SAMTOOLS_INDEX.out.bai // channel: [ val(meta), path(bai) ] csi = SAMTOOLS_INDEX.out.csi // channel: [ val(meta), path(csi) ] diff --git a/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/meta.yml b/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/meta.yml index e655484e..93e1238b 100644 --- a/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/meta.yml +++ b/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/meta.yml @@ -37,6 +37,10 @@ output: description: | CSI samtools index Structure: [ val(meta), path(csi) ] + - deduplog: + description: | + UMI-tools deduplication log + Structure: [ val(meta), path(log) ] - stats: description: | File containing samtools stats output diff --git a/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/tests/main.nf.test b/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/tests/main.nf.test index 476e7320..93e62485 100644 --- a/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/tests/main.nf.test +++ b/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/tests/main.nf.test @@ -20,17 +20,14 @@ nextflow_workflow { test("sarscov2_bam_bai") { when { - params { - outdir = "$outputDir" - } workflow { """ val_get_dedup_stats = false input[0] = Channel.of([ [ id:'test'], // meta map - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.umi.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.umi.sorted.bam.bai', checkIfExists: true) ]) input[1] = val_get_dedup_stats """ @@ -40,14 +37,44 @@ nextflow_workflow { then { assertAll( { assert workflow.success}, + { assert workflow.out.deduplog.get(0).get(1) ==~ ".*.log"}, { assert workflow.out.bam.get(0).get(1) ==~ ".*.bam"}, { assert workflow.out.bai.get(0).get(1) ==~ ".*.bai"}, - { assert snapshot(workflow.out.stats).match("test_bam_dedup_stats_samtools_umitools_stats") }, - { assert snapshot(workflow.out.flagstat).match("test_bam_dedup_stats_samtools_umitools_flagstats") }, - { assert snapshot(workflow.out.idxstats).match("test_bam_dedup_stats_samtools_umitools_idxstats") } + { assert snapshot( + bam(workflow.out.bam[0][1]).getSamLinesMD5(), + workflow.out.stats, + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.versions + ).match() } ) } - } + test("sarscov2_bam_bai - stub") { + + options "-stub" + + when { + workflow { + """ + val_get_dedup_stats = false + + input[0] = Channel.of([ + [ id:'test'], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.umi.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.umi.sorted.bam.bai', checkIfExists: true) + ]) + input[1] = val_get_dedup_stats + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot(workflow.out).match() } + ) + } + } } diff --git a/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/tests/main.nf.test.snap b/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/tests/main.nf.test.snap index 5a3e80b4..3b361357 100644 --- a/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/tests/main.nf.test.snap +++ b/subworkflows/nf-core/bam_dedup_stats_samtools_umitools/tests/main.nf.test.snap @@ -1,53 +1,170 @@ { - "test_bam_dedup_stats_samtools_umitools_idxstats": { + "sarscov2_bam_bai": { "content": [ + "b7be15ac7aae194b04bdbb56f3534495", [ [ { "id": "test" }, - "test.idxstats:md5,1adb27b52d4d64b826f48b59d61dcd4d" + "test.stats:md5,41ba57a9b90b54587e7d154e5405ea5e" ] - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.01.0" - }, - "timestamp": "2023-11-06T09:58:40.394333937" - }, - "test_bam_dedup_stats_samtools_umitools_flagstats": { - "content": [ + ], [ [ { "id": "test" }, - "test.flagstat:md5,0bb716e40fae381b97484b58e0b16efe" + "test.flagstat:md5,18d602435a02a4d721b78d1812622159" ] - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.01.0" - }, - "timestamp": "2023-11-06T09:58:40.385185447" - }, - "test_bam_dedup_stats_samtools_umitools_stats": { - "content": [ + ], [ [ { "id": "test" }, - "test.stats:md5,02342d307779941001376ff5d19e941a" + "test.idxstats:md5,85d20a901eef23ca50c323638a2eb602" ] + ], + [ + "versions.yml:md5,2bf4310f1d49429016f5633f965e9ed0", + "versions.yml:md5,306b85f2109aeac87f1bf0eed94e6940", + "versions.yml:md5,db76f947845712952426efae5356018f", + "versions.yml:md5,eb35d8fd0745ef0ebacb9e26d4124e1d", + "versions.yml:md5,f4935d4e563646266cc6bb4d75d0fb7d" ] ], "meta": { "nf-test": "0.8.4", - "nextflow": "24.01.0" + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-25T17:23:13.841219" + }, + "sarscov2_bam_bai - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test" + }, + "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + + ], + "4": [ + [ + { + "id": "test" + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + [ + { + "id": "test" + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test" + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + "versions.yml:md5,2bf4310f1d49429016f5633f965e9ed0", + "versions.yml:md5,306b85f2109aeac87f1bf0eed94e6940", + "versions.yml:md5,db76f947845712952426efae5356018f", + "versions.yml:md5,eb35d8fd0745ef0ebacb9e26d4124e1d", + "versions.yml:md5,f4935d4e563646266cc6bb4d75d0fb7d" + ], + "bai": [ + [ + { + "id": "test" + }, + "test.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam": [ + [ + { + "id": "test" + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "csi": [ + + ], + "deduplog": [ + [ + { + "id": "test" + }, + "test.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "flagstat": [ + [ + { + "id": "test" + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "idxstats": [ + [ + { + "id": "test" + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "stats": [ + [ + { + "id": "test" + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,2bf4310f1d49429016f5633f965e9ed0", + "versions.yml:md5,306b85f2109aeac87f1bf0eed94e6940", + "versions.yml:md5,db76f947845712952426efae5356018f", + "versions.yml:md5,eb35d8fd0745ef0ebacb9e26d4124e1d", + "versions.yml:md5,f4935d4e563646266cc6bb4d75d0fb7d" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" }, - "timestamp": "2024-02-13T16:45:33.563016651" + "timestamp": "2024-09-16T08:04:43.790052381" } } \ No newline at end of file diff --git a/subworkflows/nf-core/bam_rseqc/main.nf b/subworkflows/nf-core/bam_rseqc/main.nf new file mode 100644 index 00000000..043321a1 --- /dev/null +++ b/subworkflows/nf-core/bam_rseqc/main.nf @@ -0,0 +1,185 @@ +// +// Run RSeQC modules +// + +include { RSEQC_BAMSTAT } from '../../../modules/nf-core/rseqc/bamstat/main' +include { RSEQC_INNERDISTANCE } from '../../../modules/nf-core/rseqc/innerdistance/main' +include { RSEQC_INFEREXPERIMENT } from '../../../modules/nf-core/rseqc/inferexperiment/main' +include { RSEQC_JUNCTIONANNOTATION } from '../../../modules/nf-core/rseqc/junctionannotation/main' +include { RSEQC_JUNCTIONSATURATION } from '../../../modules/nf-core/rseqc/junctionsaturation/main' +include { RSEQC_READDISTRIBUTION } from '../../../modules/nf-core/rseqc/readdistribution/main' +include { RSEQC_READDUPLICATION } from '../../../modules/nf-core/rseqc/readduplication/main' +include { RSEQC_TIN } from '../../../modules/nf-core/rseqc/tin/main' + +workflow BAM_RSEQC { + take: + bam_bai // channel: [ val(meta), [ bam, bai ] ] + bed // channel: [ genome.bed ] + rseqc_modules // list: rseqc modules to run + + main: + + bam = bam_bai.map{ [ it[0], it[1] ] } + + versions = Channel.empty() + + // + // Run RSeQC bam_stat.py + // + bamstat_txt = Channel.empty() + + if ('bam_stat' in rseqc_modules) { + RSEQC_BAMSTAT(bam) + bamstat_txt = RSEQC_BAMSTAT.out.txt + versions = versions.mix(RSEQC_BAMSTAT.out.versions.first()) + } + + // + // Run RSeQC inner_distance.py + // + innerdistance_all = Channel.empty() + innerdistance_distance = Channel.empty() + innerdistance_freq = Channel.empty() + innerdistance_mean = Channel.empty() + innerdistance_pdf = Channel.empty() + innerdistance_rscript = Channel.empty() + + if ('inner_distance' in rseqc_modules) { + RSEQC_INNERDISTANCE(bam, bed) + innerdistance_distance = RSEQC_INNERDISTANCE.out.distance + innerdistance_freq = RSEQC_INNERDISTANCE.out.freq + innerdistance_mean = RSEQC_INNERDISTANCE.out.mean + innerdistance_pdf = RSEQC_INNERDISTANCE.out.pdf + innerdistance_rscript = RSEQC_INNERDISTANCE.out.rscript + innerdistance_all = innerdistance_distance.mix(innerdistance_freq, innerdistance_mean, innerdistance_pdf, innerdistance_rscript) + versions = versions.mix(RSEQC_INNERDISTANCE.out.versions.first()) + } + + // + // Run RSeQC infer_experiment.py + // + inferexperiment_txt = Channel.empty() + if ('infer_experiment' in rseqc_modules) { + RSEQC_INFEREXPERIMENT(bam, bed) + inferexperiment_txt = RSEQC_INFEREXPERIMENT.out.txt + versions = versions.mix(RSEQC_INFEREXPERIMENT.out.versions.first()) + } + + // + // Run RSeQC junction_annotation.py + // + junctionannotation_all = Channel.empty() + junctionannotation_bed = Channel.empty() + junctionannotation_interact_bed = Channel.empty() + junctionannotation_xls = Channel.empty() + junctionannotation_pdf = Channel.empty() + junctionannotation_events_pdf = Channel.empty() + junctionannotation_rscript = Channel.empty() + junctionannotation_log = Channel.empty() + + if ('junction_annotation' in rseqc_modules) { + RSEQC_JUNCTIONANNOTATION(bam, bed) + junctionannotation_bed = RSEQC_JUNCTIONANNOTATION.out.bed + junctionannotation_interact_bed = RSEQC_JUNCTIONANNOTATION.out.interact_bed + junctionannotation_xls = RSEQC_JUNCTIONANNOTATION.out.xls + junctionannotation_pdf = RSEQC_JUNCTIONANNOTATION.out.pdf + junctionannotation_events_pdf = RSEQC_JUNCTIONANNOTATION.out.events_pdf + junctionannotation_rscript = RSEQC_JUNCTIONANNOTATION.out.rscript + junctionannotation_log = RSEQC_JUNCTIONANNOTATION.out.log + junctionannotation_all = junctionannotation_bed.mix(junctionannotation_interact_bed, junctionannotation_xls, junctionannotation_pdf, junctionannotation_events_pdf, junctionannotation_rscript, junctionannotation_log) + versions = versions.mix(RSEQC_JUNCTIONANNOTATION.out.versions.first()) + } + + // + // Run RSeQC junction_saturation.py + // + junctionsaturation_all = Channel.empty() + junctionsaturation_pdf = Channel.empty() + junctionsaturation_rscript = Channel.empty() + + if ('junction_saturation' in rseqc_modules) { + RSEQC_JUNCTIONSATURATION(bam, bed) + junctionsaturation_pdf = RSEQC_JUNCTIONSATURATION.out.pdf + junctionsaturation_rscript = RSEQC_JUNCTIONSATURATION.out.rscript + junctionsaturation_all = junctionsaturation_pdf.mix(junctionsaturation_rscript) + versions = versions.mix(RSEQC_JUNCTIONSATURATION.out.versions.first()) + } + + // + // Run RSeQC read_distribution.py + // + readdistribution_txt = Channel.empty() + + if ('read_distribution' in rseqc_modules) { + RSEQC_READDISTRIBUTION(bam, bed) + readdistribution_txt = RSEQC_READDISTRIBUTION.out.txt + versions = versions.mix(RSEQC_READDISTRIBUTION.out.versions.first()) + } + + // + // Run RSeQC read_duplication.py + // + readduplication_all = Channel.empty() + readduplication_seq_xls = Channel.empty() + readduplication_pos_xls = Channel.empty() + readduplication_pdf = Channel.empty() + readduplication_rscript = Channel.empty() + + if ('read_duplication' in rseqc_modules) { + RSEQC_READDUPLICATION(bam ) + readduplication_seq_xls = RSEQC_READDUPLICATION.out.seq_xls + readduplication_pos_xls = RSEQC_READDUPLICATION.out.pos_xls + readduplication_pdf = RSEQC_READDUPLICATION.out.pdf + readduplication_rscript = RSEQC_READDUPLICATION.out.rscript + readduplication_all = readduplication_seq_xls.mix(readduplication_pos_xls, readduplication_pdf, readduplication_rscript) + versions = versions.mix(RSEQC_READDUPLICATION.out.versions.first()) + } + + // + // Run RSeQC tin.py + // + tin_txt = Channel.empty() + + if ('tin' in rseqc_modules) { + RSEQC_TIN(bam_bai, bed) + tin_txt = RSEQC_TIN.out.txt + versions = versions.mix(RSEQC_TIN.out.versions.first()) + } + + emit: + bamstat_txt // channel: [ val(meta), txt ] + + innerdistance_all // channel: [ val(meta), {txt, pdf, r} ] + innerdistance_distance // channel: [ val(meta), txt ] + innerdistance_freq // channel: [ val(meta), txt ] + innerdistance_mean // channel: [ val(meta), txt ] + innerdistance_pdf // channel: [ val(meta), pdf ] + innerdistance_rscript // channel: [ val(meta), r ] + + inferexperiment_txt // channel: [ val(meta), txt ] + + junctionannotation_all // channel: [ val(meta), {bed, xls, pdf, r, log} ] + junctionannotation_bed // channel: [ val(meta), bed ] + junctionannotation_interact_bed // channel: [ val(meta), bed ] + junctionannotation_xls // channel: [ val(meta), xls ] + junctionannotation_pdf // channel: [ val(meta), pdf ] + junctionannotation_events_pdf // channel: [ val(meta), pdf ] + junctionannotation_rscript // channel: [ val(meta), r ] + junctionannotation_log // channel: [ val(meta), log ] + + junctionsaturation_all // channel: [ val(meta), {pdf, r} ] + junctionsaturation_pdf // channel: [ val(meta), pdf ] + junctionsaturation_rscript // channel: [ val(meta), r ] + + readdistribution_txt // channel: [ val(meta), txt ] + + readduplication_all // channel: [ val(meta), {xls, pdf, r} ] + readduplication_seq_xls // channel: [ val(meta), xls ] + readduplication_pos_xls // channel: [ val(meta), xls ] + readduplication_pdf // channel: [ val(meta), pdf ] + readduplication_rscript // channel: [ val(meta), r ] + + tin_txt // channel: [ val(meta), txt ] + + versions // channel: [ versions.yml ] +} diff --git a/subworkflows/nf-core/bam_rseqc/meta.yml b/subworkflows/nf-core/bam_rseqc/meta.yml new file mode 100644 index 00000000..6e76ff56 --- /dev/null +++ b/subworkflows/nf-core/bam_rseqc/meta.yml @@ -0,0 +1,162 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: bam_rseqc +description: Subworkflow to run multiple commands in the RSeqC package +keywords: + - rnaseq + - experiment + - inferexperiment + - bamstat + - innerdistance + - junctionannotation + - junctionsaturation + - readdistribution + - readduplication + - tin +components: + - rseqc + - rseqc/tin + - rseqc/readduplication + - rseqc/readdistribution + - rseqc/junctionsaturation + - rseqc/junctionannotation + - rseqc/innerdistance + - rseqc/inferexperiment + - rseqc/bamstat +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bam: + type: file + description: BAM file to calculate statistics + pattern: "*.{bam}" + - bai: + type: file + description: Index for input BAM file + pattern: "*.{bai}" + - bed: + type: file + description: BED file for the reference gene model + pattern: "*.{bed}" + - rseqc_modules: + type: list + description: | + List of rseqc modules to run + e.g. [ 'bam_stat', 'infer_experiment' ] +output: + - bamstat_txt: + type: file + description: bam statistics report + pattern: "*.bam_stat.txt" + - innerdistance_all: + type: file + description: All the output files from RSEQC_INNERDISTANCE + pattern: "*.{txt,pdf,R}" + - innerdistance_distance: + type: file + description: the inner distances + pattern: "*.inner_distance.txt" + - innerdistance_freq: + type: file + description: frequencies of different insert sizes + pattern: "*.inner_distance_freq.txt" + - innerdistance_mean: + type: file + description: mean/median values of inner distances + pattern: "*.inner_distance_mean.txt" + - innerdistance_pdf: + type: file + description: distribution plot of inner distances + pattern: "*.inner_distance_plot.pdf" + - innerdistance_rscript: + type: file + description: script to reproduce the plot + pattern: "*.inner_distance_plot.R" + - inferexperiment_txt: + type: file + description: infer_experiment results report + pattern: "*.infer_experiment.txt" + - junctionannotation_all: + type: file + description: All the output files from RSEQC_JUNCTIONANNOTATION + pattern: "*.{bed,xls,pdf,R,log}" + - junctionannotation_bed: + type: file + description: bed file of annotated junctions + pattern: "*.junction.bed" + - junctionannotation_interact_bed: + type: file + description: Interact bed file + pattern: "*.Interact.bed" + - junctionannotation_xls: + type: file + description: xls file with junction information + pattern: "*.xls" + - junctionannotation_pdf: + type: file + description: junction plot + pattern: "*.junction.pdf" + - junctionannotation_events_pdf: + type: file + description: events plot + pattern: "*.events.pdf" + - junctionannotation_rscript: + type: file + description: Rscript to reproduce the plots + pattern: "*.r" + - junctionannotation_log: + type: file + description: Log file generated by tool + pattern: "*.log" + - junctionsaturation_all: + type: file + description: All the output files from RSEQC_JUNCTIONSATURATION + pattern: "*.{pdf,R}" + - junctionsaturation_pdf: + type: file + description: Junction saturation report + pattern: "*.pdf" + - junctionsaturation_rscript: + type: file + description: Junction saturation R-script + pattern: "*.r" + - readdistribution_txt: + type: file + description: the read distribution report + pattern: "*.read_distribution.txt" + - readduplication_all: + type: file + description: All the output files from RSEQC_READDUPLICATION + pattern: "*.{xls,pdf,R}" + - readduplication_seq_xls: + type: file + description: Read duplication rate determined from mapping position of read + pattern: "*seq.DupRate.xls" + - readduplication_pos_xls: + type: file + description: Read duplication rate determined from sequence of read + pattern: "*pos.DupRate.xls" + - readduplication_pdf: + type: file + description: plot of duplication rate + pattern: "*.pdf" + - readduplication_rscript: + type: file + description: script to reproduce the plot + pattern: "*.R" + - tin_txt: + type: file + description: TXT file containing tin.py results summary + pattern: "*.txt" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" +authors: + - "@drpatelh" + - "@kevinmenden" +maintainers: + - "@drpatelh" + - "@kevinmenden" diff --git a/subworkflows/nf-core/bam_rseqc/tests/main.nf.test b/subworkflows/nf-core/bam_rseqc/tests/main.nf.test new file mode 100644 index 00000000..d228c6b4 --- /dev/null +++ b/subworkflows/nf-core/bam_rseqc/tests/main.nf.test @@ -0,0 +1,147 @@ +nextflow_workflow { + + name "Test Workflow BAM_RSEQC" + script "../main.nf" + workflow "BAM_RSEQC" + tag "subworkflows" + tag "subworkflows_nfcore" + tag "subworkflows/bam_rseqc" + tag "bam_rseqc" + tag "rseqc" + tag "rseqc/bamstat" + tag "rseqc/inferexperiment" + tag "rseqc/innerdistance" + tag "rseqc/junctionannotation" + tag "rseqc/junctionsaturation" + tag "rseqc/readdistribution" + tag "rseqc/readduplication" + tag "rseqc/tin" + + test("sarscov2 paired-end [bam]") { + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test' ], // 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([ + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/bed/test.bed12', checkIfExists: true) + ]) + input[2] = ['bam_stat', 'inner_distance', 'infer_experiment', 'junction_annotation', 'junction_saturation', 'read_distribution', 'read_duplication', 'tin'] + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert workflow.out.innerdistance_all.any { it[1].endsWith('.pdf') && file(it[1]).exists() } }, + { assert workflow.out.readduplication_all.any { it[1].endsWith('.pdf') && file(it[1]).exists() } }, + { assert workflow.out.junctionsaturation_all.any { it[1].endsWith('.pdf') && file(it[1]).exists() } }, + { assert snapshot( + workflow.out.bamstat_txt, + workflow.out.innerdistance_all.findAll { it[1].endsWith('.pdf') == false }, + workflow.out.inferexperiment_txt, + workflow.out.junctionannotation_all.findAll { it[1].endsWith('.xls') == false && it[1].endsWith('.r') == false }, + workflow.out.junctionsaturation_all.findAll { it[1].endsWith('.pdf') == false }, + workflow.out.readdistribution_txt, + workflow.out.readduplication_all.findAll { it[1].endsWith('.pdf') == false }, + workflow.out.tin_txt, + workflow.out.versions).match()} + ) + } + } + + test("sarscov2 paired-end [bam] no modules") { + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test' ], // 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([ + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/bed/test.bed12', checkIfExists: true) + ]) + input[2] = [] + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert workflow.out.bamstat_txt.size() == 0 }, + { assert workflow.out.innerdistance_all.size() == 0 }, + { assert workflow.out.inferexperiment_txt.size() == 0 }, + { assert workflow.out.junctionannotation_all.size() == 0 }, + { assert workflow.out.junctionsaturation_all.size() == 0 }, + { assert workflow.out.readdistribution_txt.size() == 0 }, + { assert workflow.out.readduplication_all.size() == 0 }, + { assert workflow.out.tin_txt.size() == 0 }, + { assert workflow.out.versions.size() == 0 } + ) + } + } + + test("sarscov2 paired-end [bam] - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test' ], // 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([ + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/bed/test.bed12', checkIfExists: true) + ]) + input[2] = ['bam_stat', 'inner_distance', 'infer_experiment', 'junction_annotation', 'junction_saturation', 'read_distribution', 'read_duplication', 'tin'] + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot(workflow.out).match()} + ) + } + } + + test("sarscov2 paired-end [bam] no modules - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test' ], // 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([ + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/bed/test.bed12', checkIfExists: true) + ]) + input[2] = [] + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot(workflow.out).match()} + ) + } + } +} diff --git a/subworkflows/nf-core/bam_rseqc/tests/main.nf.test.snap b/subworkflows/nf-core/bam_rseqc/tests/main.nf.test.snap new file mode 100644 index 00000000..0040810c --- /dev/null +++ b/subworkflows/nf-core/bam_rseqc/tests/main.nf.test.snap @@ -0,0 +1,903 @@ +{ + "sarscov2 paired-end [bam]": { + "content": [ + [ + [ + { + "id": "test" + }, + "test.bam_stat.txt:md5,2675857864c1d1139b2a19d25dc36b09" + ] + ], + [ + [ + { + "id": "test" + }, + "test.inner_distance.txt:md5,a1acc9def0f64a5500d4c4cb47cbe32b" + ], + [ + { + "id": "test" + }, + "test.inner_distance_freq.txt:md5,3fc037501f5899b5da009c8ce02fc25e" + ], + [ + { + "id": "test" + }, + "test.inner_distance_mean.txt:md5,58398b7d5a29a5e564f9e3c50b55996c" + ], + [ + { + "id": "test" + }, + "test.inner_distance_plot.r:md5,5859fbd5b42046d47e8b9aa85077f4ea" + ] + ], + [ + [ + { + "id": "test" + }, + "test.infer_experiment.txt:md5,f9d0bfc239df637cd8aeda40ade3c59a" + ] + ], + [ + [ + { + "id": "test" + }, + "test.junction_annotation.log:md5,d75e0f5d62fada8aa9449991b209554c" + ] + ], + [ + [ + { + "id": "test" + }, + "test.junctionSaturation_plot.r:md5,caa6e63dcb477aabb169882b2f30dadd" + ] + ], + [ + [ + { + "id": "test" + }, + "test.read_distribution.txt:md5,56893fdc0809d968629a363551a1655f" + ] + ], + [ + [ + { + "id": "test" + }, + "test.DupRate_plot.r:md5,3c0325095cee4835b921e57d61c23dca" + ], + [ + { + "id": "test" + }, + "test.pos.DupRate.xls:md5,a859bc2031d46bf1cc4336205847caa3" + ], + [ + { + "id": "test" + }, + "test.seq.DupRate.xls:md5,ee8783399eec5a18522a6f08bece338b" + ] + ], + [ + [ + { + "id": "test" + }, + "test.paired_end.sorted.summary.txt:md5,9d98447e178b89a89f6f5aba7a772fe6" + ] + ], + [ + "versions.yml:md5,60dc1afce7fecb7270e998a00ee393e2", + "versions.yml:md5,9bc3caee6aeb54f23f5296b499546515", + "versions.yml:md5,a25161998ca60d5ce4e9a86abbf1bcb8", + "versions.yml:md5,c175b92f50b5be38a8808cbf7ac7452e", + "versions.yml:md5,ca7e95cf7ff7cff5d052b890729f7ead", + "versions.yml:md5,d03beea3c68934c3f3623a005c1424d2", + "versions.yml:md5,f2f3ecd549045f7595245f904f5d9414", + "versions.yml:md5,fd16f1098b9c285f3ea7bd3daf4e8f10" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-03T12:07:54.452949" + }, + "sarscov2 paired-end [bam] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.bam_stat.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test.inner_distance.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.inner_distance_freq.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.inner_distance_mean.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.inner_distance_plot.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.inner_distance_plot.r:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "10": [ + [ + { + "id": "test" + }, + "test.Interact.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "11": [ + [ + { + "id": "test" + }, + "test.junction.xls:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "12": [ + [ + { + "id": "test" + }, + "test.junction.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "13": [ + [ + { + "id": "test" + }, + "test.events.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "14": [ + [ + { + "id": "test" + }, + "test.junction_plot.r:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "15": [ + [ + { + "id": "test" + }, + "test.junction_annotation.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "16": [ + [ + { + "id": "test" + }, + "test.junctionSaturation_plot.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.junctionSaturation_plot.r:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "17": [ + [ + { + "id": "test" + }, + "test.junctionSaturation_plot.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "18": [ + [ + { + "id": "test" + }, + "test.junctionSaturation_plot.r:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "19": [ + [ + { + "id": "test" + }, + "test.read_distribution.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test" + }, + "test.inner_distance.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "20": [ + [ + { + "id": "test" + }, + "test.DupRate_plot.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.DupRate_plot.r:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.pos.DupRate.xls:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.seq.DupRate.xls:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "21": [ + [ + { + "id": "test" + }, + "test.seq.DupRate.xls:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "22": [ + [ + { + "id": "test" + }, + "test.pos.DupRate.xls:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "23": [ + [ + { + "id": "test" + }, + "test.DupRate_plot.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "24": [ + [ + { + "id": "test" + }, + "test.DupRate_plot.r:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "25": [ + [ + { + "id": "test" + }, + "test.paired_end.sorted.bam.summary.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "26": [ + "versions.yml:md5,60dc1afce7fecb7270e998a00ee393e2", + "versions.yml:md5,9bc3caee6aeb54f23f5296b499546515", + "versions.yml:md5,a25161998ca60d5ce4e9a86abbf1bcb8", + "versions.yml:md5,c175b92f50b5be38a8808cbf7ac7452e", + "versions.yml:md5,ca7e95cf7ff7cff5d052b890729f7ead", + "versions.yml:md5,d03beea3c68934c3f3623a005c1424d2", + "versions.yml:md5,f2f3ecd549045f7595245f904f5d9414", + "versions.yml:md5,fd16f1098b9c285f3ea7bd3daf4e8f10" + ], + "3": [ + [ + { + "id": "test" + }, + "test.inner_distance_freq.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test" + }, + "test.inner_distance_mean.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + [ + { + "id": "test" + }, + "test.inner_distance_plot.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + [ + { + "id": "test" + }, + "test.inner_distance_plot.r:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test" + }, + "test.infer_experiment.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + [ + { + "id": "test" + }, + "test.Interact.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.events.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.junction.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.junction.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.junction.xls:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.junction_annotation.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.junction_plot.r:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "9": [ + [ + { + "id": "test" + }, + "test.junction.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bamstat_txt": [ + [ + { + "id": "test" + }, + "test.bam_stat.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "inferexperiment_txt": [ + [ + { + "id": "test" + }, + "test.infer_experiment.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "innerdistance_all": [ + [ + { + "id": "test" + }, + "test.inner_distance.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.inner_distance_freq.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.inner_distance_mean.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.inner_distance_plot.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.inner_distance_plot.r:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "innerdistance_distance": [ + [ + { + "id": "test" + }, + "test.inner_distance.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "innerdistance_freq": [ + [ + { + "id": "test" + }, + "test.inner_distance_freq.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "innerdistance_mean": [ + [ + { + "id": "test" + }, + "test.inner_distance_mean.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "innerdistance_pdf": [ + [ + { + "id": "test" + }, + "test.inner_distance_plot.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "innerdistance_rscript": [ + [ + { + "id": "test" + }, + "test.inner_distance_plot.r:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "junctionannotation_all": [ + [ + { + "id": "test" + }, + "test.Interact.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.events.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.junction.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.junction.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.junction.xls:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.junction_annotation.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.junction_plot.r:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "junctionannotation_bed": [ + [ + { + "id": "test" + }, + "test.junction.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "junctionannotation_events_pdf": [ + [ + { + "id": "test" + }, + "test.events.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "junctionannotation_interact_bed": [ + [ + { + "id": "test" + }, + "test.Interact.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "junctionannotation_log": [ + [ + { + "id": "test" + }, + "test.junction_annotation.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "junctionannotation_pdf": [ + [ + { + "id": "test" + }, + "test.junction.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "junctionannotation_rscript": [ + [ + { + "id": "test" + }, + "test.junction_plot.r:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "junctionannotation_xls": [ + [ + { + "id": "test" + }, + "test.junction.xls:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "junctionsaturation_all": [ + [ + { + "id": "test" + }, + "test.junctionSaturation_plot.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.junctionSaturation_plot.r:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "junctionsaturation_pdf": [ + [ + { + "id": "test" + }, + "test.junctionSaturation_plot.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "junctionsaturation_rscript": [ + [ + { + "id": "test" + }, + "test.junctionSaturation_plot.r:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "readdistribution_txt": [ + [ + { + "id": "test" + }, + "test.read_distribution.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "readduplication_all": [ + [ + { + "id": "test" + }, + "test.DupRate_plot.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.DupRate_plot.r:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.pos.DupRate.xls:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test" + }, + "test.seq.DupRate.xls:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "readduplication_pdf": [ + [ + { + "id": "test" + }, + "test.DupRate_plot.pdf:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "readduplication_pos_xls": [ + [ + { + "id": "test" + }, + "test.pos.DupRate.xls:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "readduplication_rscript": [ + [ + { + "id": "test" + }, + "test.DupRate_plot.r:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "readduplication_seq_xls": [ + [ + { + "id": "test" + }, + "test.seq.DupRate.xls:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tin_txt": [ + [ + { + "id": "test" + }, + "test.paired_end.sorted.bam.summary.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,60dc1afce7fecb7270e998a00ee393e2", + "versions.yml:md5,9bc3caee6aeb54f23f5296b499546515", + "versions.yml:md5,a25161998ca60d5ce4e9a86abbf1bcb8", + "versions.yml:md5,c175b92f50b5be38a8808cbf7ac7452e", + "versions.yml:md5,ca7e95cf7ff7cff5d052b890729f7ead", + "versions.yml:md5,d03beea3c68934c3f3623a005c1424d2", + "versions.yml:md5,f2f3ecd549045f7595245f904f5d9414", + "versions.yml:md5,fd16f1098b9c285f3ea7bd3daf4e8f10" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-03T12:08:17.304769" + }, + "sarscov2 paired-end [bam] no modules - stub": { + "content": [ + { + "0": [ + + ], + "1": [ + + ], + "10": [ + + ], + "11": [ + + ], + "12": [ + + ], + "13": [ + + ], + "14": [ + + ], + "15": [ + + ], + "16": [ + + ], + "17": [ + + ], + "18": [ + + ], + "19": [ + + ], + "2": [ + + ], + "20": [ + + ], + "21": [ + + ], + "22": [ + + ], + "23": [ + + ], + "24": [ + + ], + "25": [ + + ], + "26": [ + + ], + "3": [ + + ], + "4": [ + + ], + "5": [ + + ], + "6": [ + + ], + "7": [ + + ], + "8": [ + + ], + "9": [ + + ], + "bamstat_txt": [ + + ], + "inferexperiment_txt": [ + + ], + "innerdistance_all": [ + + ], + "innerdistance_distance": [ + + ], + "innerdistance_freq": [ + + ], + "innerdistance_mean": [ + + ], + "innerdistance_pdf": [ + + ], + "innerdistance_rscript": [ + + ], + "junctionannotation_all": [ + + ], + "junctionannotation_bed": [ + + ], + "junctionannotation_events_pdf": [ + + ], + "junctionannotation_interact_bed": [ + + ], + "junctionannotation_log": [ + + ], + "junctionannotation_pdf": [ + + ], + "junctionannotation_rscript": [ + + ], + "junctionannotation_xls": [ + + ], + "junctionsaturation_all": [ + + ], + "junctionsaturation_pdf": [ + + ], + "junctionsaturation_rscript": [ + + ], + "readdistribution_txt": [ + + ], + "readduplication_all": [ + + ], + "readduplication_pdf": [ + + ], + "readduplication_pos_xls": [ + + ], + "readduplication_rscript": [ + + ], + "readduplication_seq_xls": [ + + ], + "tin_txt": [ + + ], + "versions": [ + + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-03T12:08:24.443731" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/bam_rseqc/tests/tags.yml b/subworkflows/nf-core/bam_rseqc/tests/tags.yml new file mode 100644 index 00000000..c8dfce3a --- /dev/null +++ b/subworkflows/nf-core/bam_rseqc/tests/tags.yml @@ -0,0 +1,2 @@ +subworkflows/bam_rseqc: + - subworkflows/nf-core/bam_rseqc/** diff --git a/subworkflows/nf-core/bam_sort_stats_samtools/main.nf b/subworkflows/nf-core/bam_sort_stats_samtools/main.nf index fc1c652b..b716375b 100644 --- a/subworkflows/nf-core/bam_sort_stats_samtools/main.nf +++ b/subworkflows/nf-core/bam_sort_stats_samtools/main.nf @@ -15,7 +15,7 @@ workflow BAM_SORT_STATS_SAMTOOLS { ch_versions = Channel.empty() - SAMTOOLS_SORT ( ch_bam ) + SAMTOOLS_SORT ( ch_bam, ch_fasta ) ch_versions = ch_versions.mix(SAMTOOLS_SORT.out.versions.first()) SAMTOOLS_INDEX ( SAMTOOLS_SORT.out.bam ) 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 index 75b5b934..821a3cf5 100644 --- a/subworkflows/nf-core/bam_sort_stats_samtools/tests/main.nf.test +++ b/subworkflows/nf-core/bam_sort_stats_samtools/tests/main.nf.test @@ -19,9 +19,6 @@ nextflow_workflow { test("test_bam_sort_stats_samtools_single_end") { when { - params { - outdir = "$outputDir" - } workflow { """ input[0] = Channel.of([ @@ -41,9 +38,11 @@ nextflow_workflow { { 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.stats).match("test_bam_sort_stats_samtools_single_end_stats") }, - { assert snapshot(workflow.out.flagstat).match("test_bam_sort_stats_samtools_single_end_flagstats") }, - { assert snapshot(workflow.out.idxstats).match("test_bam_sort_stats_samtools_single_end_idxstats") } + { assert snapshot( + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.stats, + workflow.out.versions).match() } ) } } @@ -51,9 +50,6 @@ nextflow_workflow { test("test_bam_sort_stats_samtools_paired_end") { when { - params { - outdir = "$outputDir" - } workflow { """ input[0] = Channel.of([ @@ -73,9 +69,65 @@ nextflow_workflow { { 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.stats).match("test_bam_sort_stats_samtools_paired_end_stats") }, - { assert snapshot(workflow.out.flagstat).match("test_bam_sort_stats_samtools_paired_end_flagstats") }, - { assert snapshot(workflow.out.idxstats).match("test_bam_sort_stats_samtools_paired_end_idxstats") } + { 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 index 6645a092..c3c9a049 100644 --- 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 @@ -1,5 +1,5 @@ { - "test_bam_sort_stats_samtools_paired_end_flagstats": { + "test_bam_sort_stats_samtools_single_end": { "content": [ [ [ @@ -7,53 +7,42 @@ "id": "test", "single_end": false }, - "test.flagstat:md5,4f7ffd1e6a5e85524d443209ac97d783" + "test.flagstat:md5,2191911d72575a2358b08b1df64ccb53" ] - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.01.0" - }, - "timestamp": "2023-10-22T20:25:03.687121177" - }, - "test_bam_sort_stats_samtools_paired_end_idxstats": { - "content": [ + ], [ [ { "id": "test", "single_end": false }, - "test.idxstats:md5,df60a8c8d6621100d05178c93fb053a2" + "test.idxstats:md5,613e048487662c694aa4a2f73ca96a20" ] - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.01.0" - }, - "timestamp": "2023-10-22T20:25:03.709648916" - }, - "test_bam_sort_stats_samtools_single_end_stats": { - "content": [ + ], [ [ { "id": "test", "single_end": false }, - "test.stats:md5,cb0bf2b79de52fdf0c61e80efcdb0bb4" + "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.8.4", - "nextflow": "24.01.0" + "nf-test": "0.9.0", + "nextflow": "24.04.4" }, - "timestamp": "2024-02-13T16:44:38.553256801" + "timestamp": "2024-09-16T08:26:24.36986488" }, - "test_bam_sort_stats_samtools_paired_end_stats": { + "test_bam_sort_stats_samtools_paired_end": { "content": [ [ [ @@ -61,50 +50,281 @@ "id": "test", "single_end": false }, - "test.stats:md5,d7796222a087b9bb97f631f1c21b9c95" + "test.flagstat:md5,4f7ffd1e6a5e85524d443209ac97d783" ] - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.01.0" - }, - "timestamp": "2024-02-13T16:44:48.355870518" - }, - "test_bam_sort_stats_samtools_single_end_idxstats": { - "content": [ + ], [ [ { "id": "test", "single_end": false }, - "test.idxstats:md5,613e048487662c694aa4a2f73ca96a20" + "test.idxstats:md5,df60a8c8d6621100d05178c93fb053a2" ] - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.01.0" - }, - "timestamp": "2024-01-18T17:10:02.84631" - }, - "test_bam_sort_stats_samtools_single_end_flagstats": { - "content": [ + ], [ [ { "id": "test", "single_end": false }, - "test.flagstat:md5,2191911d72575a2358b08b1df64ccb53" + "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.8.4", - "nextflow": "24.01.0" + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:26:38.683996037" + }, + "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.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:07:18.896460047" + }, + "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.0", + "nextflow": "24.04.4" }, - "timestamp": "2024-01-18T17:10:02.829756" + "timestamp": "2024-09-16T08:07:39.028688324" } } \ No newline at end of file diff --git a/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test b/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test index c8b21f28..76e7a40a 100644 --- a/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test +++ b/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test @@ -15,9 +15,6 @@ nextflow_workflow { test("test_bam_stats_samtools_single_end") { when { - params { - outdir = "$outputDir" - } workflow { """ input[0] = Channel.of([ @@ -36,9 +33,11 @@ nextflow_workflow { then { assertAll( { assert workflow.success}, - { assert snapshot(workflow.out.stats).match("test_bam_stats_samtools_single_end_stats") }, - { assert snapshot(workflow.out.flagstat).match("test_bam_stats_samtools_single_end_flagstats") }, - { assert snapshot(workflow.out.idxstats).match("test_bam_stats_samtools_single_end_idxstats") } + { assert snapshot( + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.stats, + workflow.out.versions).match() } ) } } @@ -46,9 +45,6 @@ nextflow_workflow { test("test_bam_stats_samtools_paired_end") { when { - params { - outdir = "$outputDir" - } workflow { """ input[0] = Channel.of([ @@ -67,9 +63,11 @@ nextflow_workflow { then { assertAll( { assert workflow.success }, - { assert snapshot(workflow.out.stats).match("test_bam_stats_samtools_paired_end_stats") }, - { assert snapshot(workflow.out.flagstat).match("test_bam_stats_samtools_paired_end_flagstats") }, - { assert snapshot(workflow.out.idxstats).match("test_bam_stats_samtools_paired_end_idxstats") } + { assert snapshot( + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.stats, + workflow.out.versions).match() } ) } } @@ -77,9 +75,6 @@ nextflow_workflow { test("test_bam_stats_samtools_paired_end_cram") { when { - params { - outdir = "$outputDir" - } workflow { """ input[0] = Channel.of([ @@ -98,11 +93,96 @@ nextflow_workflow { then { assertAll( { assert workflow.success}, - { assert snapshot(workflow.out.stats).match("test_bam_stats_samtools_paired_end_cram_stats") }, - { assert snapshot(workflow.out.flagstat).match("test_bam_stats_samtools_paired_end_cram_flagstats") }, - { assert snapshot(workflow.out.idxstats).match("test_bam_stats_samtools_paired_end_cram_idxstats") } + { 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 index bf0b0c69..8ca22526 100644 --- a/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test.snap +++ b/subworkflows/nf-core/bam_stats_samtools/tests/main.nf.test.snap @@ -1,59 +1,230 @@ { - "test_bam_stats_samtools_paired_end_cram_flagstats": { + "test_bam_stats_samtools_paired_end - stub": { "content": [ - [ - [ - { - "id": "test", - "single_end": false - }, - "test.flagstat:md5,a53f3d26e2e9851f7d528442bbfe9781" + { + "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.8.4", - "nextflow": "24.01.0" + "nf-test": "0.9.0", + "nextflow": "24.04.4" }, - "timestamp": "2023-11-06T09:31:26.194017574" + "timestamp": "2024-09-16T08:08:35.660286921" }, - "test_bam_stats_samtools_paired_end_stats": { + "test_bam_stats_samtools_single_end - stub": { "content": [ - [ - [ - { - "id": "test", - "single_end": true - }, - "test.stats:md5,ddaf8f33fe9c1ebe9b06933213aec8ed" + { + "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.8.4", - "nextflow": "24.01.0" + "nf-test": "0.9.0", + "nextflow": "24.04.4" }, - "timestamp": "2024-02-13T16:45:06.230091746" + "timestamp": "2024-09-16T08:08:24.220305512" }, - "test_bam_stats_samtools_paired_end_flagstats": { + "test_bam_stats_samtools_paired_end_cram - stub": { "content": [ - [ - [ - { - "id": "test", - "single_end": true - }, - "test.flagstat:md5,4f7ffd1e6a5e85524d443209ac97d783" + { + "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.8.4", - "nextflow": "24.01.0" + "nf-test": "0.9.0", + "nextflow": "24.04.4" }, - "timestamp": "2024-01-18T17:17:27.717482" + "timestamp": "2024-09-16T08:08:54.206770141" }, - "test_bam_stats_samtools_single_end_flagstats": { + "test_bam_stats_samtools_single_end": { "content": [ [ [ @@ -63,52 +234,48 @@ }, "test.flagstat:md5,2191911d72575a2358b08b1df64ccb53" ] - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.01.0" - }, - "timestamp": "2023-11-06T09:26:10.340046381" - }, - "test_bam_stats_samtools_paired_end_cram_idxstats": { - "content": [ + ], [ [ { "id": "test", - "single_end": false + "single_end": true }, - "test.idxstats:md5,e179601fa7b8ebce81ac3765206f6c15" + "test.idxstats:md5,613e048487662c694aa4a2f73ca96a20" ] - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.01.0" - }, - "timestamp": "2023-11-06T09:31:26.207052003" - }, - "test_bam_stats_samtools_single_end_stats": { - "content": [ + ], [ [ { "id": "test", "single_end": true }, - "test.stats:md5,dc178e1a4956043aba8abc83e203521b" + "test.stats:md5,291bb2393ec947140d12d42c2795b222" ] + ], + [ + "versions.yml:md5,73c55059ed478cd2f9cd93dd3185da3a", + "versions.yml:md5,80d8653e01575b3c381d87073f672fb5", + "versions.yml:md5,cb889532237a2f3d813978ac14a12d51" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.01.0" + "nf-test": "0.9.0", + "nextflow": "24.04.4" }, - "timestamp": "2024-02-13T16:44:57.442208382" + "timestamp": "2024-09-16T08:07:49.731645858" }, - "test_bam_stats_samtools_paired_end_idxstats": { + "test_bam_stats_samtools_paired_end": { "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.flagstat:md5,4f7ffd1e6a5e85524d443209ac97d783" + ] + ], [ [ { @@ -117,33 +284,29 @@ }, "test.idxstats:md5,df60a8c8d6621100d05178c93fb053a2" ] - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.01.0" - }, - "timestamp": "2024-01-18T17:17:27.726719" - }, - "test_bam_stats_samtools_single_end_idxstats": { - "content": [ + ], [ [ { "id": "test", "single_end": true }, - "test.idxstats:md5,613e048487662c694aa4a2f73ca96a20" + "test.stats:md5,8140d69cdedd77570ca1d7618a744e16" ] + ], + [ + "versions.yml:md5,73c55059ed478cd2f9cd93dd3185da3a", + "versions.yml:md5,80d8653e01575b3c381d87073f672fb5", + "versions.yml:md5,cb889532237a2f3d813978ac14a12d51" ] ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.01.0" + "nf-test": "0.9.0", + "nextflow": "24.04.4" }, - "timestamp": "2023-11-06T09:26:10.349439801" + "timestamp": "2024-09-16T08:08:01.421996172" }, - "test_bam_stats_samtools_paired_end_cram_stats": { + "test_bam_stats_samtools_paired_end_cram": { "content": [ [ [ @@ -151,14 +314,37 @@ "id": "test", "single_end": false }, - "test.stats:md5,d3345c4887f4a9ea4f7f56405b495db0" + "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.8.4", - "nextflow": "24.01.0" + "nf-test": "0.9.0", + "nextflow": "24.04.4" }, - "timestamp": "2024-02-13T16:45:14.997164209" + "timestamp": "2024-09-16T08:08:12.640915756" } } \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_align_bowtie2/main.nf b/subworkflows/nf-core/fastq_align_bowtie2/main.nf index ba4420f7..cafaa9bf 100644 --- a/subworkflows/nf-core/fastq_align_bowtie2/main.nf +++ b/subworkflows/nf-core/fastq_align_bowtie2/main.nf @@ -20,17 +20,17 @@ workflow FASTQ_ALIGN_BOWTIE2 { // // Map reads with Bowtie2 // - BOWTIE2_ALIGN ( ch_reads, ch_index, save_unaligned, sort_bam ) + BOWTIE2_ALIGN ( ch_reads, ch_index, ch_fasta, save_unaligned, sort_bam ) ch_versions = ch_versions.mix(BOWTIE2_ALIGN.out.versions) // // Sort, index BAM file and run samtools stats, flagstat and idxstats // - BAM_SORT_STATS_SAMTOOLS ( BOWTIE2_ALIGN.out.aligned, ch_fasta ) + BAM_SORT_STATS_SAMTOOLS ( BOWTIE2_ALIGN.out.bam, ch_fasta ) ch_versions = ch_versions.mix(BAM_SORT_STATS_SAMTOOLS.out.versions) emit: - bam_orig = BOWTIE2_ALIGN.out.aligned // channel: [ val(meta), aligned ] + bam_orig = BOWTIE2_ALIGN.out.bam // channel: [ val(meta), aligned ] log_out = BOWTIE2_ALIGN.out.log // channel: [ val(meta), log ] fastq = BOWTIE2_ALIGN.out.fastq // channel: [ val(meta), fastq ] diff --git a/subworkflows/nf-core/fastq_align_bowtie2/meta.yml b/subworkflows/nf-core/fastq_align_bowtie2/meta.yml index 58023a89..b18e4054 100644 --- a/subworkflows/nf-core/fastq_align_bowtie2/meta.yml +++ b/subworkflows/nf-core/fastq_align_bowtie2/meta.yml @@ -37,7 +37,7 @@ input: - sort_bam: type: boolean description: | - Save reads that do not map to the reference (true) or discard them (false) + Use samtools sort (true) or samtools view (false) default: false - ch_fasta: type: file diff --git a/subworkflows/nf-core/fastq_align_bowtie2/tests/main.nf.test b/subworkflows/nf-core/fastq_align_bowtie2/tests/main.nf.test new file mode 100644 index 00000000..2fabb42e --- /dev/null +++ b/subworkflows/nf-core/fastq_align_bowtie2/tests/main.nf.test @@ -0,0 +1,189 @@ +nextflow_workflow { + + name "Test Subworkflow FASTQ_ALIGN_BOWTIE2" + script "../main.nf" + config "./nextflow.config" + workflow "FASTQ_ALIGN_BOWTIE2" + + tag "subworkflows" + tag "subworkflows_nfcore" + tag "subworkflows/fastq_align_bowtie2" + tag "subworkflows/bam_sort_stats_samtools" + tag "bowtie2" + tag "bowtie2/build" + tag "bowtie2/align" + + test("test_align_bowtie2_single_end") { + setup { + run("BOWTIE2_BUILD") { + script "../../../../modules/nf-core/bowtie2/build/main.nf" + process { + """ + input[0] = Channel.value([ [ id:'genome' ],file(params.test_data['sarscov2']['genome']['genome_fasta'], checkIfExists: true)]) + """ + } + } + } + when { + workflow { + """ + input[0] = Channel.of([[ id:'test', single_end:true ], [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true) ]]) + input[1] = BOWTIE2_BUILD.out.index + input[2] = false + input[3] = false + input[4] = Channel.value([ [ id:'genome' ],file(params.test_data['sarscov2']['genome']['genome_fasta'], checkIfExists: true)]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot( + file(workflow.out.bam_orig[0][1]).name, + workflow.out.fastq, + workflow.out.log_out, + file(workflow.out.bam[0][1]).name, + file(workflow.out.bai[0][1]).name, + workflow.out.csi, + workflow.out.stats, + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.versions + ).match()} + ) + } + } + + test("test_align_bowtie2_paired_end") { + setup { + run("BOWTIE2_BUILD") { + script "../../../../modules/nf-core/bowtie2/build/main.nf" + process { + """ + input[0] = Channel.value([ [ id:'genome' ],file(params.test_data['sarscov2']['genome']['genome_fasta'], checkIfExists: true)]) + """ + } + } + } + when { + workflow { + """ + input[0] = Channel.of([[ id:'test', single_end:false ], [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] = BOWTIE2_BUILD.out.index + input[2] = false + input[3] = false + input[4] = Channel.value([ [ id:'genome' ],file(params.test_data['sarscov2']['genome']['genome_fasta'], checkIfExists: true)]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot( + file(workflow.out.bam_orig[0][1]).name, + workflow.out.fastq, + workflow.out.log_out, + file(workflow.out.bam[0][1]).name, + file(workflow.out.bai[0][1]).name, + workflow.out.csi, + workflow.out.stats, + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.versions + ).match()} + ) + } + } + + test("test_align_bowtie2_single_end - stub") { + + options "-stub" + + setup { + run("BOWTIE2_BUILD") { + script "../../../../modules/nf-core/bowtie2/build/main.nf" + process { + """ + input[0] = Channel.value([ [ id:'genome' ],file(params.test_data['sarscov2']['genome']['genome_fasta'], checkIfExists: true)]) + """ + } + } + } + when { + workflow { + """ + input[0] = Channel.of([[ id:'test', single_end:true ], [ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true) ]]) + input[1] = BOWTIE2_BUILD.out.index + input[2] = false + input[3] = false + input[4] = Channel.value([ [ id:'genome' ],file(params.test_data['sarscov2']['genome']['genome_fasta'], checkIfExists: true)]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot( + file(workflow.out.bam_orig[0][1]).name, + workflow.out.fastq, + workflow.out.log_out, + file(workflow.out.bam[0][1]).name, + file(workflow.out.bai[0][1]).name, + workflow.out.csi, + workflow.out.stats, + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.versions + ).match()} + ) + } + } + + test("test_align_bowtie2_paired_end - stub") { + + options "-stub" + + setup { + run("BOWTIE2_BUILD") { + script "../../../../modules/nf-core/bowtie2/build/main.nf" + process { + """ + input[0] = Channel.value([ [ id:'genome' ],file(params.test_data['sarscov2']['genome']['genome_fasta'], checkIfExists: true)]) + """ + } + } + } + when { + workflow { + """ + input[0] = Channel.of([[ id:'test', single_end:false ], [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] = BOWTIE2_BUILD.out.index + input[2] = false + input[3] = false + input[4] = Channel.value([ [ id:'genome' ],file(params.test_data['sarscov2']['genome']['genome_fasta'], checkIfExists: true)]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot( + file(workflow.out.bam_orig[0][1]).name, + workflow.out.fastq, + workflow.out.log_out, + file(workflow.out.bam[0][1]).name, + file(workflow.out.bai[0][1]).name, + workflow.out.csi, + workflow.out.stats, + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.versions + ).match()} + ) + } + } +} diff --git a/subworkflows/nf-core/fastq_align_bowtie2/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_align_bowtie2/tests/main.nf.test.snap new file mode 100644 index 00000000..c8490961 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_bowtie2/tests/main.nf.test.snap @@ -0,0 +1,126 @@ +{ + "test_align_bowtie2_single_end": { + "content": [ + "test.bam", + [ + + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.bowtie2.log:md5,7b8a9e61b7646da1089b041333c41a87" + ] + ], + "test.sorted.bam", + "test.sorted.bam.bai", + [ + + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.stats:md5,d499a70739ffa0a96880eaad229dcf7c" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.flagstat:md5,e9ce9093133116bc54fd335cfe698372" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.idxstats:md5,e16eb632f7f462514b0873c7ac8ac905" + ] + ], + [ + "versions.yml:md5,0b1901279f738fa8e22cabea6e2a48bd", + "versions.yml:md5,60be918ac1032f74137ad27024c002ef", + "versions.yml:md5,8644be336f2fd05a04b95050a4de9094", + "versions.yml:md5,aab337e63eac9055aadb9a35cec16053", + "versions.yml:md5,dd60999d74ea42ae4f5483c9d94507f3", + "versions.yml:md5,ddb252583f75777033ee6467e4b6d545" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-03T13:07:32.050239" + }, + "test_align_bowtie2_paired_end": { + "content": [ + "test.bam", + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.bowtie2.log:md5,bd89ce1b28c93bf822bae391ffcedd19" + ] + ], + "test.sorted.bam", + "test.sorted.bam.bai", + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.stats:md5,c02dbd116c1f49339dda208cb950261d" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.flagstat:md5,49f3d51a8804ce58fe9cecd2549d279b" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.idxstats:md5,29ff2fa56d35b2a47625b8f517f1a947" + ] + ], + [ + "versions.yml:md5,0b1901279f738fa8e22cabea6e2a48bd", + "versions.yml:md5,60be918ac1032f74137ad27024c002ef", + "versions.yml:md5,8644be336f2fd05a04b95050a4de9094", + "versions.yml:md5,aab337e63eac9055aadb9a35cec16053", + "versions.yml:md5,dd60999d74ea42ae4f5483c9d94507f3", + "versions.yml:md5,ddb252583f75777033ee6467e4b6d545" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-07-03T13:07:48.653475" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_align_bowtie2/tests/nextflow.config b/subworkflows/nf-core/fastq_align_bowtie2/tests/nextflow.config new file mode 100644 index 00000000..2f85e807 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_bowtie2/tests/nextflow.config @@ -0,0 +1,8 @@ +process { + 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_bowtie2/tests/tags.yml b/subworkflows/nf-core/fastq_align_bowtie2/tests/tags.yml new file mode 100644 index 00000000..267bcc77 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_bowtie2/tests/tags.yml @@ -0,0 +1,2 @@ +subworkflows/fastq_align_bowtie2: + - subworkflows/nf-core/fastq_align_bowtie2/** diff --git a/subworkflows/nf-core/fastq_align_bwa/main.nf b/subworkflows/nf-core/fastq_align_bwa/main.nf index 9192550d..c7408d08 100644 --- a/subworkflows/nf-core/fastq_align_bwa/main.nf +++ b/subworkflows/nf-core/fastq_align_bwa/main.nf @@ -19,7 +19,7 @@ workflow FASTQ_ALIGN_BWA { // Map reads with BWA // - BWA_MEM ( ch_reads, ch_index, val_sort_bam ) + BWA_MEM ( ch_reads, ch_index, ch_fasta, val_sort_bam ) ch_versions = ch_versions.mix(BWA_MEM.out.versions.first()) // diff --git a/subworkflows/nf-core/fastq_align_bwa/tests/main.nf.test b/subworkflows/nf-core/fastq_align_bwa/tests/main.nf.test new file mode 100644 index 00000000..93c3aac3 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_bwa/tests/main.nf.test @@ -0,0 +1,77 @@ +nextflow_workflow { + + name "Test Subworkflow FASTQ_ALIGN_BWA" + script "../main.nf" + config "./nextflow.config" + workflow "FASTQ_ALIGN_BWA" + + tag "subworkflows" + tag "subworkflows_nfcore" + tag "subworkflows/fastq_align_bwa" + tag "subworkflows/bam_sort_stats_samtools" + tag "bwa" + tag "bwa/mem" + tag "bwa/index" + + + test("fastq_align_bwa_single_end") { + setup { + run("BWA_INDEX") { + script "../../../../modules/nf-core/bwa/index/main.nf" + process { + """ + input[0] = Channel.value([ [ id:'genome' ],file(params.test_data['sarscov2']['genome']['genome_fasta'], checkIfExists: true)]) + """ + } + } + } + when { + workflow { + """ + input[0] = Channel.of([[ id:'test', single_end:true ],[ file(params.test_data['sarscov2']['illumina']['test_1_fastq_gz'], checkIfExists: true) ]]) + input[1] = BWA_INDEX.out.index + input[2] = false + input[3] = Channel.value([[id: 'genome'], file(params.test_data['sarscov2']['genome']['genome_fasta'], checkIfExists: true)]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot(workflow.out).match()} + ) + } + } + + test("fastq_align_bwa_paired_end") { + setup { + run("BWA_INDEX") { + script "../../../../modules/nf-core/bwa/index/main.nf" + process { + """ + input[0] = Channel.value([ [ id:'genome' ],file(params.test_data['sarscov2']['genome']['genome_fasta'], checkIfExists: true)]) + """ + } + } + } + when { + workflow { + """ + input[0] = Channel.of([[ id:'test', single_end:false ], [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] = BWA_INDEX.out.index + input[2] = false + input[3] = Channel.value([[id: 'genome'], file(params.test_data['sarscov2']['genome']['genome_fasta'], checkIfExists: true)]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot(workflow.out).match()} + ) + } + } +} diff --git a/subworkflows/nf-core/fastq_align_bwa/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_align_bwa/tests/main.nf.test.snap new file mode 100644 index 00000000..afd97b70 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_bwa/tests/main.nf.test.snap @@ -0,0 +1,284 @@ +{ + "fastq_align_bwa_paired_end": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,0bac6813d36636e735eae75887e70cd5" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,bfea46d006b5884fcca0653cc5b886e1" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.bai:md5,140d22f4f374b485ac49e8b8c56a59b6" + ] + ], + "3": [ + + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.stats:md5,42029d1e18c289f441232c0e6851fe5a" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.flagstat:md5,18d602435a02a4d721b78d1812622159" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.idxstats:md5,85d20a901eef23ca50c323638a2eb602" + ] + ], + "7": [ + "versions.yml:md5,1a2ad0aad8b5a39089079d531734bdfe", + "versions.yml:md5,4905894958d972728ef3fb67d420971d", + "versions.yml:md5,54b76f87f10cc17e260aefd4e61b73ba", + "versions.yml:md5,616f164b996173af56b58861be3e6130", + "versions.yml:md5,7d1cd2920757b85fbae766a6b28b8e27", + "versions.yml:md5,ee109695a3b368e657b190ccf0f21ab5" + ], + "bai": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.bai:md5,140d22f4f374b485ac49e8b8c56a59b6" + ] + ], + "bam": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,bfea46d006b5884fcca0653cc5b886e1" + ] + ], + "bam_orig": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,0bac6813d36636e735eae75887e70cd5" + ] + ], + "csi": [ + + ], + "flagstat": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.flagstat:md5,18d602435a02a4d721b78d1812622159" + ] + ], + "idxstats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.idxstats:md5,85d20a901eef23ca50c323638a2eb602" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.stats:md5,42029d1e18c289f441232c0e6851fe5a" + ] + ], + "versions": [ + "versions.yml:md5,1a2ad0aad8b5a39089079d531734bdfe", + "versions.yml:md5,4905894958d972728ef3fb67d420971d", + "versions.yml:md5,54b76f87f10cc17e260aefd4e61b73ba", + "versions.yml:md5,616f164b996173af56b58861be3e6130", + "versions.yml:md5,7d1cd2920757b85fbae766a6b28b8e27", + "versions.yml:md5,ee109695a3b368e657b190ccf0f21ab5" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T12:27:40.432319749" + }, + "fastq_align_bwa_single_end": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam:md5,dc633d557de438092c4d72d04195c5a8" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam:md5,c5820f18aeaab8715195824f1f693f9f" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.bai:md5,13ba4b9f3445fa6de43cea9b28342783" + ] + ], + "3": [ + + ], + "4": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.stats:md5,71846e184d196d1b6664028aeb318bac" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.flagstat:md5,2191911d72575a2358b08b1df64ccb53" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.idxstats:md5,613e048487662c694aa4a2f73ca96a20" + ] + ], + "7": [ + "versions.yml:md5,1a2ad0aad8b5a39089079d531734bdfe", + "versions.yml:md5,4905894958d972728ef3fb67d420971d", + "versions.yml:md5,54b76f87f10cc17e260aefd4e61b73ba", + "versions.yml:md5,616f164b996173af56b58861be3e6130", + "versions.yml:md5,7d1cd2920757b85fbae766a6b28b8e27", + "versions.yml:md5,ee109695a3b368e657b190ccf0f21ab5" + ], + "bai": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.bai:md5,13ba4b9f3445fa6de43cea9b28342783" + ] + ], + "bam": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam:md5,c5820f18aeaab8715195824f1f693f9f" + ] + ], + "bam_orig": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam:md5,dc633d557de438092c4d72d04195c5a8" + ] + ], + "csi": [ + + ], + "flagstat": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.flagstat:md5,2191911d72575a2358b08b1df64ccb53" + ] + ], + "idxstats": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.idxstats:md5,613e048487662c694aa4a2f73ca96a20" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.stats:md5,71846e184d196d1b6664028aeb318bac" + ] + ], + "versions": [ + "versions.yml:md5,1a2ad0aad8b5a39089079d531734bdfe", + "versions.yml:md5,4905894958d972728ef3fb67d420971d", + "versions.yml:md5,54b76f87f10cc17e260aefd4e61b73ba", + "versions.yml:md5,616f164b996173af56b58861be3e6130", + "versions.yml:md5,7d1cd2920757b85fbae766a6b28b8e27", + "versions.yml:md5,ee109695a3b368e657b190ccf0f21ab5" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-03T12:27:19.693756639" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_align_bwa/tests/nextflow.config b/subworkflows/nf-core/fastq_align_bwa/tests/nextflow.config new file mode 100644 index 00000000..2f85e807 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_bwa/tests/nextflow.config @@ -0,0 +1,8 @@ +process { + 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_bwa/tests/tags.yml b/subworkflows/nf-core/fastq_align_bwa/tests/tags.yml new file mode 100644 index 00000000..bfe89ccf --- /dev/null +++ b/subworkflows/nf-core/fastq_align_bwa/tests/tags.yml @@ -0,0 +1,2 @@ +subworkflows/fastq_align_bwa: + - subworkflows/nf-core/fastq_align_bwa/** diff --git a/subworkflows/nf-core/fastq_align_hisat2/main.nf b/subworkflows/nf-core/fastq_align_hisat2/main.nf new file mode 100644 index 00000000..511fe035 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_hisat2/main.nf @@ -0,0 +1,43 @@ +include { HISAT2_ALIGN } from '../../../modules/nf-core/hisat2/align/main' +include { BAM_SORT_STATS_SAMTOOLS } from '../bam_sort_stats_samtools/main' + +workflow FASTQ_ALIGN_HISAT2 { + + take: + reads // channel: [ val(meta), [ reads ] ] + index // channel: /path/to/hisat2/index + splicesites // channel: /path/to/genome.splicesites.txt + ch_fasta // channel: [ fasta ] + + main: + + ch_versions = Channel.empty() + + + // + // Map reads with HISAT2 + // + HISAT2_ALIGN ( reads, index, splicesites ) + ch_versions = ch_versions.mix(HISAT2_ALIGN.out.versions.first()) + + // + // Sort, index BAM file and run samtools stats, flagstat and idxstats + // + BAM_SORT_STATS_SAMTOOLS ( HISAT2_ALIGN.out.bam, ch_fasta ) + ch_versions = ch_versions.mix(BAM_SORT_STATS_SAMTOOLS.out.versions) + + + emit: + orig_bam = HISAT2_ALIGN.out.bam // channel: [ val(meta), bam ] + summary = HISAT2_ALIGN.out.summary // channel: [ val(meta), log ] + fastq = HISAT2_ALIGN.out.fastq // channel: [ val(meta), fastq ] + + bam = BAM_SORT_STATS_SAMTOOLS.out.bam // channel: [ val(meta), [ bam ] ] + bai = BAM_SORT_STATS_SAMTOOLS.out.bai // channel: [ val(meta), [ bai ] ] + csi = BAM_SORT_STATS_SAMTOOLS.out.csi // channel: [ val(meta), [ csi ] ] + stats = BAM_SORT_STATS_SAMTOOLS.out.stats // channel: [ val(meta), [ stats ] ] + flagstat = BAM_SORT_STATS_SAMTOOLS.out.flagstat // channel: [ val(meta), [ flagstat ] ] + idxstats = BAM_SORT_STATS_SAMTOOLS.out.idxstats // channel: [ val(meta), [ idxstats ] ] + + versions = ch_versions // channel: [ versions.yml ] +} diff --git a/subworkflows/nf-core/fastq_align_hisat2/meta.yml b/subworkflows/nf-core/fastq_align_hisat2/meta.yml new file mode 100644 index 00000000..6f00d4da --- /dev/null +++ b/subworkflows/nf-core/fastq_align_hisat2/meta.yml @@ -0,0 +1,91 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: "fastq_align_hisat2" +description: Align reads to a reference genome using hisat2 then sort with samtools +keywords: + - align + - sort + - rnaseq + - genome + - fastq + - bam + - sam + - cram +components: + - hisat2/align + - samtools/stats + - samtools/idxstats + - samtools/flagstat + - bam_sort_stats_samtools +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. + - index: + type: file + description: HISAT2 genome index file + pattern: "*.ht2" + - splicesites: + type: file + description: Splices sites in gtf file + pattern: "*.{txt}" + - fasta: + type: file + description: Reference genome fasta file + pattern: "*.{fasta,fa}" +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test' ] + - bam: + type: file + description: Output BAM file containing read alignments + pattern: "*.{bam}" + - summary: + type: file + description: Aligment log + pattern: "*.log" + - fastq: + type: file + description: Optional output FASTQ file containing unaligned reads + pattern: ".fastq.gz" + - 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: + - "@priyanka-surana" +maintainers: + - "@priyanka-surana" diff --git a/subworkflows/nf-core/fastq_align_hisat2/tests/main.nf.test b/subworkflows/nf-core/fastq_align_hisat2/tests/main.nf.test new file mode 100644 index 00000000..221ce56d --- /dev/null +++ b/subworkflows/nf-core/fastq_align_hisat2/tests/main.nf.test @@ -0,0 +1,222 @@ +nextflow_workflow { + + name "Test Subworkflow FASTQ_ALIGN_HISAT2" + script "../main.nf" + workflow "FASTQ_ALIGN_HISAT2" + config "./nextflow.config" + + tag "subworkflows" + tag "subworkflows_nfcore" + tag "subworkflows/fastq_align_hisat2" + + tag "hisat2/align" + tag "hisat2/build" + tag "hisat2/extractsplicesites" + + tag "samtools/flagstat" + tag "samtools/idxstats" + tag "samtools/index" + tag "samtools/sort" + tag "samtools/stats" + tag "subworkflows/bam_sort_stats_samtools" + + setup { + run("HISAT2_EXTRACTSPLICESITES") { + script "../../../../modules/nf-core/hisat2/extractsplicesites/main.nf" + process { + """ + input[0] = Channel.of([ + [id: 'test'], + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gtf", checkIfExists: true) + ]) + """ + } + } + + run("HISAT2_EXTRACTSPLICESITES", alias: "HISAT2_EXTRACTSPLICESITES_STUB") { + script "../../../../modules/nf-core/hisat2/extractsplicesites/main.nf" + process { + """ + input[0] = Channel.of([ + [id: 'test'], + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gtf", checkIfExists: true) + ]) + """ + } + } + + run("HISAT2_BUILD") { + script "../../../../modules/nf-core/hisat2/build/main.nf" + process { + """ + input[0] = Channel.of([ + [id: 'test'], + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.fasta", checkIfExists: true) + ]) + input[1] = Channel.of([ + [id: 'test'], + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gtf", checkIfExists: true) + ]) + input[2] = HISAT2_EXTRACTSPLICESITES.out.txt + """ + } + } + + run("HISAT2_BUILD", alias: "HISAT2_BUILD_STUB") { + script "../../../../modules/nf-core/hisat2/build/main.nf" + process { + """ + input[0] = Channel.of([ + [id: 'test'], + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.fasta", checkIfExists: true) + ]) + input[1] = Channel.of([ + [id: 'test'], + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.gtf", checkIfExists: true) + ]) + input[2] = HISAT2_EXTRACTSPLICESITES_STUB.out.txt + """ + } + } + } + + test("sarscov2 - bam - single_end") { + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], + [ + file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_1.fastq.gz", checkIfExists: true) + ] + ]) + input[1] = HISAT2_BUILD.out.index + input[2] = HISAT2_EXTRACTSPLICESITES.out.txt + input[3] = Channel.of([ + [ id:'test' ], + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.fasta", checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot( + file(workflow.out.bai[0][1]).name, + file(workflow.out.bam[0][1]).name, + file(workflow.out.orig_bam[0][1]).name, + workflow.out.csi, + workflow.out.fastq, + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.stats, + workflow.out.summary, + workflow.out.versions).match()} + ) + } + } + test("sarscov2 - bam - paired_end") { + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], + [ + file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_1.fastq.gz", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_2.fastq.gz", checkIfExists: true) + ] + ]) + input[1] = HISAT2_BUILD.out.index + input[2] = HISAT2_EXTRACTSPLICESITES.out.txt + input[3] = Channel.of([ + [ id:'test' ], + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.fasta", checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot( + file(workflow.out.bai[0][1]).name, + file(workflow.out.bam[0][1]).name, + file(workflow.out.orig_bam[0][1]).name, + workflow.out.csi, + workflow.out.fastq, + workflow.out.flagstat, + workflow.out.idxstats, + workflow.out.stats, + workflow.out.summary, + workflow.out.versions).match()} + ) + } + } + + test("sarscov2 - bam - single_end - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', single_end:true ], + [ + file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_1.fastq.gz", checkIfExists: true) + ] + ]) + input[1] = HISAT2_BUILD_STUB.out.index + input[2] = HISAT2_EXTRACTSPLICESITES_STUB.out.txt + input[3] = Channel.of([ + [ id:'test' ], + file(params.modules_testdata_base_path + "genomics/sarscov2/genome/genome.fasta", checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert workflow.success}, + { assert snapshot(workflow.out).match()} + ) + } + } + test("sarscov2 - bam - paired_end - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = Channel.of([ + [ id:'test', single_end:false ], + [ + file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_1.fastq.gz", checkIfExists: true), + file(params.modules_testdata_base_path + "genomics/sarscov2/illumina/fastq/test_2.fastq.gz", checkIfExists: true) + ] + ]) + input[1] = HISAT2_BUILD_STUB.out.index + input[2] = HISAT2_EXTRACTSPLICESITES_STUB.out.txt + input[3] = Channel.of([ + [ id:'test' ], + 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/fastq_align_hisat2/tests/main.nf.test.snap b/subworkflows/nf-core/fastq_align_hisat2/tests/main.nf.test.snap new file mode 100644 index 00000000..f5a87298 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_hisat2/tests/main.nf.test.snap @@ -0,0 +1,456 @@ +{ + "sarscov2 - bam - single_end": { + "content": [ + "test.sorted.bam.bai", + "test.sorted.bam", + "test.bam", + [ + + ], + [ + + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.flagstat:md5,6de3bfde9582ad2532033832091f5c46" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.idxstats:md5,2a5df85e0d90e55bb2b359f6e05d5fbb" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.stats:md5,0ebab7bf6149e6378b263997d7073067" + ] + ], + [ + [ + { + "id": "test", + "single_end": true + }, + "test.hisat2.summary.log:md5,7b8a9e61b7646da1089b041333c41a87" + ] + ], + [ + "versions.yml:md5,60b3d72afae0af5e6ba9d522ed2a865d", + "versions.yml:md5,6d9f7a6b7da221197ec81a78012dd306", + "versions.yml:md5,9bb4be2b6931086977d43355fd7c9edb", + "versions.yml:md5,b4ccce0351e5718d36600858452dd4b1", + "versions.yml:md5,e5ba15fd38b21e5c3050edc8cf2ab665", + "versions.yml:md5,e65b217d1cb47f1c163fdc37023c0909" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:27:35.808393107" + }, + "sarscov2 - bam - single_end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": true + }, + "test.hisat2.summary.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + + ], + "3": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + + ], + "6": [ + [ + { + "id": "test", + "single_end": true + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": true + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + [ + { + "id": "test", + "single_end": true + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "9": [ + "versions.yml:md5,60b3d72afae0af5e6ba9d522ed2a865d", + "versions.yml:md5,6d9f7a6b7da221197ec81a78012dd306", + "versions.yml:md5,9bb4be2b6931086977d43355fd7c9edb", + "versions.yml:md5,b4ccce0351e5718d36600858452dd4b1", + "versions.yml:md5,e5ba15fd38b21e5c3050edc8cf2ab665", + "versions.yml:md5,e65b217d1cb47f1c163fdc37023c0909" + ], + "bai": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam": [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "csi": [ + + ], + "fastq": [ + + ], + "flagstat": [ + [ + { + "id": "test", + "single_end": true + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "idxstats": [ + [ + { + "id": "test", + "single_end": true + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "orig_bam": [ + [ + { + "id": "test", + "single_end": true + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": true + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "summary": [ + [ + { + "id": "test", + "single_end": true + }, + "test.hisat2.summary.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,60b3d72afae0af5e6ba9d522ed2a865d", + "versions.yml:md5,6d9f7a6b7da221197ec81a78012dd306", + "versions.yml:md5,9bb4be2b6931086977d43355fd7c9edb", + "versions.yml:md5,b4ccce0351e5718d36600858452dd4b1", + "versions.yml:md5,e5ba15fd38b21e5c3050edc8cf2ab665", + "versions.yml:md5,e65b217d1cb47f1c163fdc37023c0909" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:10:09.451605417" + }, + "sarscov2 - bam - paired_end": { + "content": [ + "test.sorted.bam.bai", + "test.sorted.bam", + "test.bam", + [ + + ], + [ + + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.flagstat:md5,2fa0d90162a1b655863796c2a6bd8f45" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,1adb27b52d4d64b826f48b59d61dcd4d" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,74b78cbd41df459e1037735f714cda4f" + ] + ], + [ + [ + { + "id": "test", + "single_end": false + }, + "test.hisat2.summary.log:md5,9839b31db795958cc4b70711a3414e9c" + ] + ], + [ + "versions.yml:md5,60b3d72afae0af5e6ba9d522ed2a865d", + "versions.yml:md5,6d9f7a6b7da221197ec81a78012dd306", + "versions.yml:md5,9bb4be2b6931086977d43355fd7c9edb", + "versions.yml:md5,b4ccce0351e5718d36600858452dd4b1", + "versions.yml:md5,e5ba15fd38b21e5c3050edc8cf2ab665", + "versions.yml:md5,e65b217d1cb47f1c163fdc37023c0909" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:28:01.671969576" + }, + "sarscov2 - bam - paired_end - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.hisat2.summary.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "8": [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "9": [ + "versions.yml:md5,60b3d72afae0af5e6ba9d522ed2a865d", + "versions.yml:md5,6d9f7a6b7da221197ec81a78012dd306", + "versions.yml:md5,9bb4be2b6931086977d43355fd7c9edb", + "versions.yml:md5,b4ccce0351e5718d36600858452dd4b1", + "versions.yml:md5,e5ba15fd38b21e5c3050edc8cf2ab665", + "versions.yml:md5,e65b217d1cb47f1c163fdc37023c0909" + ], + "bai": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "bam": [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "csi": [ + + ], + "fastq": [ + + ], + "flagstat": [ + [ + { + "id": "test", + "single_end": false + }, + "test.flagstat:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "idxstats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.idxstats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "orig_bam": [ + [ + { + "id": "test", + "single_end": false + }, + "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "test.stats:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "summary": [ + [ + { + "id": "test", + "single_end": false + }, + "test.hisat2.summary.log:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,60b3d72afae0af5e6ba9d522ed2a865d", + "versions.yml:md5,6d9f7a6b7da221197ec81a78012dd306", + "versions.yml:md5,9bb4be2b6931086977d43355fd7c9edb", + "versions.yml:md5,b4ccce0351e5718d36600858452dd4b1", + "versions.yml:md5,e5ba15fd38b21e5c3050edc8cf2ab665", + "versions.yml:md5,e65b217d1cb47f1c163fdc37023c0909" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-16T08:10:28.136547114" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/fastq_align_hisat2/tests/nextflow.config b/subworkflows/nf-core/fastq_align_hisat2/tests/nextflow.config new file mode 100644 index 00000000..d2a119b5 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_hisat2/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: SAMTOOLS_SORT { + ext.prefix = { "${meta.id}.sorted" } + } +} diff --git a/subworkflows/nf-core/fastq_align_hisat2/tests/tags.yml b/subworkflows/nf-core/fastq_align_hisat2/tests/tags.yml new file mode 100644 index 00000000..8993cde0 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_hisat2/tests/tags.yml @@ -0,0 +1,2 @@ +subworkflows/fastq_align_hisat2: + - subworkflows/nf-core/fastq_align_hisat2/** 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 00000000..00d553d9 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_star/main.nf @@ -0,0 +1,68 @@ +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 = 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 00000000..796d3e4b --- /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 00000000..926eae71 --- /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 00000000..2c512c96 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_star/tests/main.nf.test @@ -0,0 +1,262 @@ +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(workflow.out.orig_bam).match('orig_bam_single_end')}, + { assert snapshot(workflow.out.bam_sorted).match('bam_sorted_single_end')}, + { assert snapshot(workflow.out.fastq).match('fastq_single_end')}, + { assert snapshot(workflow.out.tab).match('tab_single_end')}, + { assert snapshot(workflow.out.orig_bam_transcript).match('orig_bam_transcript_single_end')}, + { assert snapshot(workflow.out.bam).match('bam_single_end')}, + { assert snapshot(workflow.out.bai).match('bai_single_end')}, + { assert snapshot(workflow.out.stats).match('stats_single_end')}, + { assert snapshot(workflow.out.flagstat).match('flagstat_single_end')}, + { assert snapshot(workflow.out.idxstats).match('idxstats_single_end')}, + { assert snapshot(workflow.out.bam_transcript).match('bam_transcript_single_end')}, + { assert snapshot(workflow.out.bai_transcript).match('bai_transcript_single_end')}, + { assert snapshot(workflow.out.stats_transcript).match('stats_transcript_single_end')}, + { assert snapshot(workflow.out.flagstat_transcript).match('flagstat_transcript_single_end')}, + { assert snapshot(workflow.out.idxstats_transcript).match('idxstats_transcript_single_end')}, + { 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(workflow.out.orig_bam).match('orig_bam_paired_end')}, + { assert snapshot(workflow.out.bam_sorted).match('bam_sorted_paired_end')}, + { assert snapshot(workflow.out.fastq).match('fastq_paired_end')}, + { assert snapshot(workflow.out.tab).match('tab_paired_end')}, + { assert snapshot(workflow.out.orig_bam_transcript).match('orig_bam_transcript_paired_end')}, + { assert snapshot(workflow.out.bam).match('bam_paired_end')}, + { assert snapshot(workflow.out.bai).match('bai_paired_end')}, + { assert snapshot(workflow.out.stats).match('stats_paired_end')}, + { assert snapshot(workflow.out.flagstat).match('flagstat_paired_end')}, + { assert snapshot(workflow.out.idxstats).match('idxstats_paired_end')}, + { assert snapshot(workflow.out.bam_transcript).match('bam_transcript_paired_end')}, + { assert snapshot(workflow.out.bai_transcript).match('bai_transcript_paired_end')}, + { assert snapshot(workflow.out.stats_transcript).match('stats_transcript_paired_end')}, + { assert snapshot(workflow.out.flagstat_transcript).match('flagstat_transcript_paired_end')}, + { assert snapshot(workflow.out.idxstats_transcript).match('idxstats_transcript_paired_end')}, + { assert snapshot(workflow.out.idxstats_transcript).match('versions_paired_end')}, + { 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(workflow.out.orig_bam).match('orig_bam_paired_end_with_transcriptome')}, + { assert snapshot(workflow.out.bam_sorted).match('bam_sorted_paired_end_with_transcriptome')}, + { assert snapshot(workflow.out.fastq).match('fastq_paired_end_with_transcriptome')}, + { assert snapshot(workflow.out.tab).match('tab_paired_end_with_transcriptome')}, + { assert snapshot(workflow.out.orig_bam_transcript).match('orig_bam_transcript_paired_end_with_transcriptome')}, + { assert snapshot(workflow.out.bam).match('bam_paired_end_with_transcriptome')}, + { assert snapshot(workflow.out.bai).match('bai_paired_end_with_transcriptome')}, + { assert snapshot(workflow.out.stats).match('stats_paired_end_with_transcriptome')}, + { assert snapshot(workflow.out.flagstat).match('flagstat_paired_end_with_transcriptome')}, + { assert snapshot(workflow.out.idxstats).match('idxstats_paired_end_with_transcriptome')}, + { assert snapshot(workflow.out.bam_transcript).match('bam_transcript_paired_end_with_transcriptome')}, + { assert snapshot(workflow.out.bai_transcript).match('bai_transcript_paired_end_with_transcriptome')}, + { assert snapshot(workflow.out.stats_transcript).match('stats_transcript_paired_end_with_transcriptome')}, + { assert snapshot(workflow.out.flagstat_transcript).match('flagstat_transcript_paired_end_with_transcriptome')}, + { assert snapshot(workflow.out.idxstats_transcript).match('idxstats_transcript_paired_end_with_transcriptome')}, + { assert snapshot(workflow.out.idxstats_transcript).match('versions_paired_end_with_transcriptome')}, + { 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(workflow.out.orig_bam).match('orig_bam_paired_end_transcripts_no_transcriptome')}, + { assert snapshot(workflow.out.bam_sorted).match('bam_sorted_paired_end_transcripts_no_transcriptome')}, + { assert snapshot(workflow.out.fastq).match('fastq_paired_end_transcripts_no_transcriptome')}, + { assert snapshot(workflow.out.tab).match('tab_paired_end_transcripts_no_transcriptome')}, + { assert snapshot(workflow.out.orig_bam_transcript).match('orig_bam_transcript_paired_end_transcripts_no_transcriptome')}, + { assert snapshot(workflow.out.bam).match('bam_paired_end_transcripts_no_transcriptome')}, + { assert snapshot(workflow.out.bai).match('bai_paired_end_transcripts_no_transcriptome')}, + { assert snapshot(workflow.out.stats).match('stats_paired_end_transcripts_no_transcriptome')}, + { assert snapshot(workflow.out.flagstat).match('flagstat_paired_end_transcripts_no_transcriptome')}, + { assert snapshot(workflow.out.idxstats).match('idxstats_paired_end_transcripts_no_transcriptome')}, + { assert snapshot(workflow.out.bam_transcript).match('bam_transcript_paired_end_transcripts_no_transcriptome')}, + { assert snapshot(workflow.out.bai_transcript).match('bai_transcript_paired_end_transcripts_no_transcriptome')}, + { assert snapshot(workflow.out.stats_transcript).match('stats_transcript_paired_end_transcripts_no_transcriptome')}, + { assert snapshot(workflow.out.flagstat_transcript).match('flagstat_transcript_paired_end_transcripts_no_transcriptome')}, + { assert snapshot(workflow.out.idxstats_transcript).match('idxstats_transcript_paired_end_transcripts_no_transcriptome')}, + { assert snapshot(workflow.out.idxstats_transcript).match('versions_paired_end_transcripts_no_transcriptome')}, + { 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 00000000..93a4329a --- /dev/null +++ b/subworkflows/nf-core/fastq_align_star/tests/main.nf.test.snap @@ -0,0 +1,1010 @@ +{ + "flagstat_transcript_paired_end_with_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.flagstat:md5,a204dee59ef8b7cd0f7d952a80119b77" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-16T11:04:06.836115665" + }, + "orig_bam_paired_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.out.bam:md5,51d2ef198d5725978a4b6da6fbec17dd" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:37:37.493635239" + }, + "tab_paired_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.SJ.out.tab:md5,844af19ab0fc8cd9a3f75228445aca0d" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:37:37.62565966" + }, + "stats_single_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.stats:md5,8e74b58e799fbf5082c39f98f14c3f46" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T10:58:48.537976" + }, + "bam_sorted_single_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:36:01.366823434" + }, + "idxstats_paired_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.idxstats:md5,107ca94dd426cc44db316f0d402307c5" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:37:37.799888732" + }, + "fastq_paired_end_with_transcriptome": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-16T11:04:06.404150611" + }, + "stats_transcript_single_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:36:01.92597042" + }, + "idxstats_transcript_paired_end_with_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.idxstats:md5,4030919b4a05393dcd7e699d72725803" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-16T11:04:06.869017036" + }, + "flagstat_paired_end_transcripts_no_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.flagstat:md5,db0e25cd0b37d3030e807846c022199e" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:39:50.673278468" + }, + "bam_transcript_single_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:36:01.816422587" + }, + "bai_transcript_single_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:36:01.889271918" + }, + "idxstats_transcript_paired_end_transcripts_no_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.idxstats:md5,4030919b4a05393dcd7e699d72725803" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:39:50.933689327" + }, + "idxstats_paired_end_transcripts_no_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.idxstats:md5,107ca94dd426cc44db316f0d402307c5" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:39:50.717133215" + }, + "bai_paired_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.bai:md5,ad0665b0f48b4374f21ca3dd6d3c0d88" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T10:59:42.224779" + }, + "stats_paired_end_with_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.stats:md5,ba343720cd202366636bdb606c1361b9" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T11:00:38.630724" + }, + "tab_single_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.SJ.out.tab:md5,75a516ab950fb958f40b29996474949c" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-16T11:01:50.81938497" + }, + "orig_bam_paired_end_transcripts_no_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.out.bam:md5,8bb13b5b1530a4682d662f1a5c40ab88" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:39:50.324025875" + }, + "tab_paired_end_transcripts_no_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.SJ.out.tab:md5,844af19ab0fc8cd9a3f75228445aca0d" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:39:50.450949052" + }, + "bam_transcript_paired_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:37:37.848680274" + }, + "bam_transcript_paired_end_transcripts_no_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,40de55db306ef865530f939bbf9299d5" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T11:01:40.533399" + }, + "bai_transcript_paired_end_with_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.bai:md5,1dd687a38a2d7fb959272c659678a484" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T11:00:38.813279" + }, + "bai_paired_end_with_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.bai:md5,f4104865dd069f7b0922f94bd7b05b9f" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T11:00:38.552294" + }, + "idxstats_transcript_paired_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:37:37.998050296" + }, + "versions_paired_end_transcripts_no_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.idxstats:md5,4030919b4a05393dcd7e699d72725803" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:39:51.008404374" + }, + "bam_single_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam:md5,6c4beda83d0372cc3f16864e2f5990de" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T10:58:48.479685" + }, + "idxstats_single_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.idxstats:md5,0d5a12e3e3ffdb15f1c6c50f02f22575" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-16T11:01:51.104899639" + }, + "orig_bam_transcript_paired_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:37:37.646770561" + }, + "stats_transcript_paired_end_with_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.stats:md5,ba860fb9ece9a136b262d4b7779c6a52" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T11:00:38.911706" + }, + "orig_bam_transcript_paired_end_transcripts_no_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.toTranscriptome.out.bam:md5,deb116674bf9a17a8082dd4899b0f11f" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:39:50.500316187" + }, + "orig_bam_transcript_paired_end_with_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.toTranscriptome.out.bam:md5,deb116674bf9a17a8082dd4899b0f11f" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-16T11:04:06.46731827" + }, + "orig_bam_paired_end_with_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.Aligned.out.bam:md5,8bb13b5b1530a4682d662f1a5c40ab88" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-16T11:04:06.343819207" + }, + "bam_transcript_paired_end_with_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,7dccfc9a0e8d530aa222dd8fde13c03e" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T11:00:38.714095" + }, + "fastq_single_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:36:01.387908106" + }, + "stats_paired_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.stats:md5,ba343720cd202366636bdb606c1361b9" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T10:59:42.341245" + }, + "flagstat_paired_end_with_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.flagstat:md5,db0e25cd0b37d3030e807846c022199e" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-16T11:04:06.670712229" + }, + "flagstat_single_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.flagstat:md5,075e7a684a7ceb5fd1dae154f823128a" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-16T11:01:51.065241319" + }, + "bam_paired_end_with_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,318219d2960e6ae1fdde8d3da0d4bb64" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T11:00:38.477259" + }, + "flagstat_transcript_paired_end_transcripts_no_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.flagstat:md5,a204dee59ef8b7cd0f7d952a80119b77" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:39:50.890160347" + }, + "flagstat_transcript_paired_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:37:37.97328443" + }, + "versions_paired_end_with_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.idxstats:md5,4030919b4a05393dcd7e699d72725803" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-16T11:04:06.905277179" + }, + "bam_sorted_paired_end_transcripts_no_transcriptome": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:39:50.369745857" + }, + "bam_sorted_paired_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:37:37.548813329" + }, + "stats_paired_end_transcripts_no_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.stats:md5,ba343720cd202366636bdb606c1361b9" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T11:01:40.477062" + }, + "bai_transcript_paired_end_transcripts_no_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.bai:md5,e6382105b52943a408505f25f27872b0" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T11:01:40.58742" + }, + "orig_bam_single_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.Aligned.out.bam:md5,cd655e6c7309158d42fcfb202a6100e7" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-16T11:01:50.699345543" + }, + "tab_paired_end_with_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.SJ.out.tab:md5,844af19ab0fc8cd9a3f75228445aca0d" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-16T11:04:06.431755269" + }, + "bam_paired_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,3758b81996c73509c052aac035530aaf" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T10:59:42.104272" + }, + "bam_paired_end_transcripts_no_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam:md5,318219d2960e6ae1fdde8d3da0d4bb64" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T11:01:40.363913" + }, + "stats_transcript_paired_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:37:37.945610051" + }, + "versions_paired_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:37:38.025358383" + }, + "bai_paired_end_transcripts_no_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.bai:md5,f4104865dd069f7b0922f94bd7b05b9f" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T11:01:40.422582" + }, + "idxstats_paired_end_with_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.idxstats:md5,107ca94dd426cc44db316f0d402307c5" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-16T11:04:06.702727344" + }, + "orig_bam_transcript_single_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:36:01.449184828" + }, + "idxstats_transcript_single_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:36:01.992614899" + }, + "bai_transcript_paired_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:37:37.897935922" + }, + "flagstat_paired_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.flagstat:md5,db0e25cd0b37d3030e807846c022199e" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:37:37.74949925" + }, + "stats_transcript_paired_end_transcripts_no_transcriptome": { + "content": [ + [ + [ + { + "id": "test", + "single_end": false + }, + "test.sorted.bam.stats:md5,625f0d8e29429337c7383d4d25814c6c" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-21T11:01:40.644021" + }, + "bam_sorted_paired_end_with_transcriptome": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-16T11:04:06.3779095" + }, + "bai_single_end": { + "content": [ + [ + [ + { + "id": "test", + "single_end": true + }, + "test.sorted.bam.bai:md5,73c7f3fe35663c287cb421f1c8b761ae" + ] + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-03-01T14:09:07.343206" + }, + "fastq_paired_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:37:37.594559814" + }, + "flagstat_transcript_single_end": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:36:01.971850654" + }, + "fastq_paired_end_transcripts_no_transcriptome": { + "content": [ + [ + + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-15T19:39:50.410098606" + } +} \ 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 00000000..6af49d58 --- /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/tags.yml b/subworkflows/nf-core/fastq_align_star/tests/tags.yml new file mode 100644 index 00000000..a919a2d1 --- /dev/null +++ b/subworkflows/nf-core/fastq_align_star/tests/tags.yml @@ -0,0 +1,2 @@ +subworkflows/fastq_align_star: + - subworkflows/nf-core/fastq_align_star/** 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 00000000..62f15250 --- /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/homer/groseq/main.nf b/subworkflows/nf-core/homer/groseq/main.nf deleted file mode 100644 index ad6f0bf1..00000000 --- a/subworkflows/nf-core/homer/groseq/main.nf +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Identify transcripts with homer - */ - -include { HOMER_MAKETAGDIRECTORY } from '../../../../modules/nf-core/homer/maketagdirectory/main' -include { HOMER_MAKEUCSCFILE } from '../../../../modules/nf-core/homer/makeucscfile/main' -include { HOMER_FINDPEAKS } from '../../../../modules/nf-core/homer/findpeaks/main' -include { HOMER_POS2BED } from '../../../../modules/nf-core/homer/pos2bed/main' - -workflow HOMER_GROSEQ { - take: - bam // channel: [ val(meta), [ reads ] ] - fasta // file: /path/to/bwa/index/ - - main: - - ch_versions = Channel.empty() - - /* - * Create a Tag Directory From The GRO-Seq experiment - */ - HOMER_MAKETAGDIRECTORY ( bam, fasta ) - ch_versions = ch_versions.mix(HOMER_MAKETAGDIRECTORY.out.versions.first()) - - /* - * Creating UCSC Visualization Files - */ - HOMER_MAKEUCSCFILE ( HOMER_MAKETAGDIRECTORY.out.tagdir ) - ch_versions = ch_versions.mix(HOMER_MAKEUCSCFILE.out.versions.first()) - - /* - * Find transcripts directly from GRO-Seq - */ - HOMER_FINDPEAKS ( HOMER_MAKETAGDIRECTORY.out.tagdir ) - ch_versions = ch_versions.mix(HOMER_FINDPEAKS.out.versions.first()) - - /* - * Convert peak file to bed file - */ - HOMER_POS2BED ( HOMER_FINDPEAKS.out.txt ) - ch_versions = ch_versions.mix(HOMER_POS2BED.out.versions.first()) - - emit: - tagdir = HOMER_MAKETAGDIRECTORY.out.tagdir // channel: [ val(meta), [ tagdir ] ] - bed_graph = HOMER_MAKEUCSCFILE.out.bedGraph // channel: [ val(meta), [ tag_dir/*ucsc.bedGraph.gz ] ] - peaks = HOMER_FINDPEAKS.out.txt // channel: [ val(meta), [ *peaks.txt ] ] - bed = HOMER_POS2BED.out.bed // channel: [ val(meta), [ *peaks.txt ] ] - - versions = ch_versions // channel: [ versions.yml ] -} diff --git a/subworkflows/nf-core/homer_groseq/main.nf b/subworkflows/nf-core/homer_groseq/main.nf new file mode 100644 index 00000000..cd30b98c --- /dev/null +++ b/subworkflows/nf-core/homer_groseq/main.nf @@ -0,0 +1,65 @@ +/* + * Identify transcripts with homer + */ + +include { UNZIP } from '../../../modules/nf-core/unzip/main' + +include { HOMER_MAKETAGDIRECTORY } from '../../../modules/nf-core/homer/maketagdirectory/main' +include { HOMER_MAKEUCSCFILE } from '../../../modules/nf-core/homer/makeucscfile/main' +include { HOMER_FINDPEAKS } from '../../../modules/nf-core/homer/findpeaks/main' +include { HOMER_POS2BED } from '../../../modules/nf-core/homer/pos2bed/main' + +workflow HOMER_GROSEQ { + take: + bam // channel: [ val(meta), [ reads ] ] + fasta // file: /path/to/bwa/index/ + uniqmap + + main: + + ch_versions = Channel.empty() + + ch_uniqmap = Channel.empty() + + if (!uniqmap) { + ch_uniqmap = [] + } + else if (uniqmap.endsWith('.zip')) { + ch_uniqmap = UNZIP([[:], uniqmap]).unzipped_archive.map { it[1] } + ch_versions = ch_versions.mix(UNZIP.out.versions) + } + else { + ch_uniqmap = uniqmap + } + + /* + * Create a Tag Directory From The GRO-Seq experiment + */ + HOMER_MAKETAGDIRECTORY(bam, fasta) + ch_versions = ch_versions.mix(HOMER_MAKETAGDIRECTORY.out.versions) + + /* + * Creating UCSC Visualization Files + */ + HOMER_MAKEUCSCFILE(HOMER_MAKETAGDIRECTORY.out.tagdir) + ch_versions = ch_versions.mix(HOMER_MAKEUCSCFILE.out.versions) + + /* + * Find transcripts directly from GRO-Seq + */ + HOMER_FINDPEAKS(HOMER_MAKETAGDIRECTORY.out.tagdir, ch_uniqmap) + ch_versions = ch_versions.mix(HOMER_FINDPEAKS.out.versions) + + /* + * Convert peak file to bed file + */ + HOMER_POS2BED(HOMER_FINDPEAKS.out.txt) + ch_versions = ch_versions.mix(HOMER_POS2BED.out.versions) + + emit: + tagdir = HOMER_MAKETAGDIRECTORY.out.tagdir // channel: [ val(meta), [ tagdir ] ] + bed_graph = HOMER_MAKEUCSCFILE.out.bedGraph // channel: [ val(meta), [ tag_dir/*ucsc.bedGraph.gz ] ] + peaks = HOMER_FINDPEAKS.out.txt // channel: [ val(meta), [ *peaks.txt ] ] + bed = HOMER_POS2BED.out.bed // channel: [ val(meta), [ *peaks.txt ] ] + versions = ch_versions // channel: [ versions.yml ] +} diff --git a/subworkflows/nf-core/homer/groseq/meta.yml b/subworkflows/nf-core/homer_groseq/meta.yml similarity index 69% rename from subworkflows/nf-core/homer/groseq/meta.yml rename to subworkflows/nf-core/homer_groseq/meta.yml index 11718b7a..fd1db63c 100644 --- a/subworkflows/nf-core/homer/groseq/meta.yml +++ b/subworkflows/nf-core/homer_groseq/meta.yml @@ -1,34 +1,35 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json name: homer_groseq -description: Perform variant calling on a set of normal samples using mutect2 panel of normals mode. Group them into a genomicsdbworkspace using genomicsdbimport, then use this to create a panel of normals using createsomaticpanelofnormals. +description: Basic process of trying to analyze GRO-Seq data with HOMER. From the + [GRO-Seq Analysis Tutorial](http://homer.ucsd.edu/homer/ngs/groseq/groseq.html). keywords: - homer - groseq - nascent components: + - unzip - homer/maketagdirectory - homer/makeucscfile - homer/findpeaks - homer/pos2bed input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test' ] - - input: - type: list + - bam: description: list of BAM files, also able to take SAM and BED as input pattern: "[ *.{bam/sam/bed} ]" - fasta: type: file description: The reference fasta file pattern: "*.fasta" + - uniqmap: + type: file + description: Optional HOMER uniqmap + pattern: "*.zip" output: - tagdir: type: directory description: The "Tag Directory" pattern: "*_tagdir" - - bedGraph: + - bed_graph: type: file description: The UCSC bed graph pattern: "*.bedGraph.gz" diff --git a/subworkflows/nf-core/homer_groseq/tests/bed.config b/subworkflows/nf-core/homer_groseq/tests/bed.config new file mode 100644 index 00000000..bdf78d14 --- /dev/null +++ b/subworkflows/nf-core/homer_groseq/tests/bed.config @@ -0,0 +1,5 @@ +process { + withName: 'HOMER_GROSEQ:HOMER_MAKETAGDIRECTORY' { + ext.args = "-checkGC -format bed -single" + } +} diff --git a/subworkflows/nf-core/homer_groseq/tests/main.nf.test b/subworkflows/nf-core/homer_groseq/tests/main.nf.test new file mode 100644 index 00000000..48e75981 --- /dev/null +++ b/subworkflows/nf-core/homer_groseq/tests/main.nf.test @@ -0,0 +1,143 @@ +nextflow_workflow { + + name "Test Workflow HOMER_GROSEQ" + script "../main.nf" + workflow "HOMER_GROSEQ" + + tag "subworkflows" + tag "subworkflows_nfcore" + tag "subworkflows/homer_groseq" + tag "homer" + tag "unzip" + tag "homer/maketagdirectory" + tag "homer/makeucscfile" + tag "homer/findpeaks" + tag "homer/pos2bed" + + test("Should run HOMER_GROSEQ with BAM input") { + + when { + workflow { + """ + input[0] = [ + [ id: 'test' ], + 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.fasta', checkIfExists: true) + input[2] = [] + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + // NOTE tagdir + path(workflow.out.bed_graph.get(0).get(1)).linesGzip.size(), + workflow.out.peaks, + workflow.out.bed, + path(workflow.out.versions.get(0)).yaml, + ).match() }, + ) + } + } + + test("Should run HOMER_GROSEQ with BED input") { + config "./bed.config" + + when { + workflow { + """ + input[0] = [ + [ id: 'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/bed/test.bed', checkIfExists: true), + ] + input[1] = file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true) + input[2] = [] + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + // NOTE tagdir + path(workflow.out.bed_graph.get(0).get(1)).linesGzip.size(), + workflow.out.peaks, + workflow.out.bed, + path(workflow.out.versions.get(0)).yaml, + ).match() }, + ) + } + } + + test("Test files from GROseq tutorial with uniqmap") { + + tag "uniqmap" + + config "./bed.config" + + when { + workflow { + """ + input[0] = [ + [ id: 'test' ], + [file('ftp://ftp.ncbi.nlm.nih.gov/geo/samples/GSM340nnn/GSM340901/suppl/GSM340901_lib1_aligned.bed.gz', checkIfExists: true), + file('ftp://ftp.ncbi.nlm.nih.gov/geo/samples/GSM340nnn/GSM340902/suppl/GSM340902_lib2_aligned.bed.gz', checkIfExists: true)], + ] + input[1] = file('https://hgdownload.soe.ucsc.edu/goldenPath/hg18/chromosomes/chr14.fa.gz', checkIfExists: true) + input[2] = file('https://raw.githubusercontent.com/nf-core/test-datasets/nascent/reference/uniqmap.GRCh38_chr21.50nt.zip', checkIfExists: true) + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + // NOTE tagdir + path(workflow.out.bed_graph.get(0).get(1)).linesGzip.size(), + workflow.out.peaks, + workflow.out.bed, + path(workflow.out.bed.get(0).get(1)).readLines()[30], + path(workflow.out.bed.get(0).get(1)).readLines()[32], + path(workflow.out.versions.get(0)).yaml, + ).match() }, + ) + } + } + + test("sarscov2 - stub") { + + options "-stub" + + when { + workflow { + """ + input[0] = [ + [ id: 'test' ], + 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.fasta', checkIfExists: true) + input[2] = [] + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + // NOTE tagdir + path(workflow.out.bed_graph.get(0).get(1)).linesGzip.size(), + workflow.out.peaks, + workflow.out.bed, + path(workflow.out.versions.get(0)).yaml, + ).match() }, + { assert snapshot(path(workflow.out.versions.get(0)).yaml).match("versions") }, + ) + } + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/homer_groseq/tests/main.nf.test.snap b/subworkflows/nf-core/homer_groseq/tests/main.nf.test.snap new file mode 100644 index 00000000..61e8eb64 --- /dev/null +++ b/subworkflows/nf-core/homer_groseq/tests/main.nf.test.snap @@ -0,0 +1,142 @@ +{ + "sarscov2 - stub": { + "content": [ + 1, + [ + [ + { + "id": "test" + }, + "test.peaks.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + [ + { + "id": "test" + }, + "test.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + { + "HOMER_GROSEQ:HOMER_POS2BED": { + "homer": 4.11 + } + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-23T20:49:13.598633" + }, + "versions": { + "content": [ + { + "HOMER_GROSEQ:HOMER_POS2BED": { + "homer": 4.11 + } + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-24T14:22:34.952862" + }, + "Should run HOMER_GROSEQ with BAM input": { + "content": [ + 346, + [ + [ + { + "id": "test" + }, + "test.peaks.txt:md5,470ad70471ef668cab50d9c41e5b124c" + ] + ], + [ + [ + { + "id": "test" + }, + "test.bed:md5,470ad70471ef668cab50d9c41e5b124c" + ] + ], + { + "HOMER_GROSEQ:HOMER_POS2BED": { + "homer": 4.11 + } + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-23T20:47:40.376043" + }, + "Should run HOMER_GROSEQ with BED input": { + "content": [ + 6, + [ + [ + { + "id": "test" + }, + "test.peaks.txt:md5,0b0b174b135fd5404a9b462e27ab4ce1" + ] + ], + [ + [ + { + "id": "test" + }, + "test.bed:md5,0b0b174b135fd5404a9b462e27ab4ce1" + ] + ], + { + "HOMER_GROSEQ:HOMER_POS2BED": { + "homer": 4.11 + } + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-23T20:47:47.733612" + }, + "Test files from GROseq tutorial with uniqmap": { + "content": [ + 15368354, + [ + [ + { + "id": "test" + }, + "test-uniqmap.GRCh38_chr21.50nt.peaks.txt:md5,3220d07ce56785d77045282345ddf1cd" + ] + ], + [ + [ + { + "id": "test" + }, + "test.bed:md5,49433f826697cd237dfdb740a0cb2c54" + ] + ], + "# uniqMapDirectory = uniqmap.GRCh38_chr21.50nt.zip", + "# cmd = findPeaks test_tagdir -o test-uniqmap.GRCh38_chr21.50nt.peaks.txt -uniqmap uniqmap.GRCh38_chr21.50nt.zip", + { + "HOMER_GROSEQ:HOMER_POS2BED": { + "homer": 4.11 + } + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-07T17:59:14.024175" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf new file mode 100644 index 00000000..d6e593e8 --- /dev/null +++ b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf @@ -0,0 +1,126 @@ +// +// Subworkflow with functionality that may be useful for any Nextflow pipeline +// + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + SUBWORKFLOW DEFINITION +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow UTILS_NEXTFLOW_PIPELINE { + take: + print_version // boolean: print version + dump_parameters // boolean: dump parameters + outdir // path: base directory used to publish pipeline results + check_conda_channels // boolean: check conda channels + + main: + + // + // Print workflow version and exit on --version + // + if (print_version) { + log.info("${workflow.manifest.name} ${getWorkflowVersion()}") + System.exit(0) + } + + // + // Dump pipeline parameters to a JSON file + // + if (dump_parameters && outdir) { + dumpParametersToJSON(outdir) + } + + // + // When running with Conda, warn if channels have not been set-up appropriately + // + if (check_conda_channels) { + checkCondaChannels() + } + + emit: + dummy_emit = true +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// Generate version string +// +def getWorkflowVersion() { + 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}" + } + + if (workflow.commitId) { + def git_shortsha = workflow.commitId.substring(0, 7) + version_string += "-g${git_shortsha}" + } + + return version_string +} + +// +// Dump pipeline parameters to a JSON file +// +def dumpParametersToJSON(outdir) { + def timestamp = new java.util.Date().format('yyyy-MM-dd_HH-mm-ss') + def filename = "params_${timestamp}.json" + def temp_pf = new File(workflow.launchDir.toString(), ".${filename}") + def jsonStr = groovy.json.JsonOutput.toJson(params) + temp_pf.text = groovy.json.JsonOutput.prettyPrint(jsonStr) + + nextflow.extension.FilesEx.copyTo(temp_pf.toPath(), "${outdir}/pipeline_info/params_${timestamp}.json") + temp_pf.delete() +} + +// +// When running with -profile conda, warn if channels have not been set-up appropriately +// +def checkCondaChannels() { + 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 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'] + 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 = required_channels_in_order != channels.findAll { ch -> ch in required_channels_in_order } + + if (channels_missing | channel_priority_violation) { + 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/meta.yml b/subworkflows/nf-core/utils_nextflow_pipeline/meta.yml new file mode 100644 index 00000000..e5c3a0a8 --- /dev/null +++ b/subworkflows/nf-core/utils_nextflow_pipeline/meta.yml @@ -0,0 +1,38 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: "UTILS_NEXTFLOW_PIPELINE" +description: Subworkflow with functionality that may be useful for any Nextflow pipeline +keywords: + - utility + - pipeline + - initialise + - version +components: [] +input: + - print_version: + type: boolean + description: | + Print the version of the pipeline and exit + - dump_parameters: + type: boolean + description: | + Dump the parameters of the pipeline to a JSON file + - output_directory: + type: directory + description: Path to output dir to write JSON file to. + pattern: "results/" + - check_conda_channel: + type: boolean + description: | + Check if the conda channel priority is correct. +output: + - dummy_emit: + type: boolean + description: | + Dummy emit to make nf-core subworkflows lint happy +authors: + - "@adamrtalbot" + - "@drpatelh" +maintainers: + - "@adamrtalbot" + - "@drpatelh" + - "@maxulysse" diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.function.nf.test b/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.function.nf.test new file mode 100644 index 00000000..68718e4f --- /dev/null +++ b/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.function.nf.test @@ -0,0 +1,54 @@ + +nextflow_function { + + name "Test Functions" + script "subworkflows/nf-core/utils_nextflow_pipeline/main.nf" + config "subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config" + tag 'subworkflows' + tag 'utils_nextflow_pipeline' + tag 'subworkflows/utils_nextflow_pipeline' + + test("Test Function getWorkflowVersion") { + + function "getWorkflowVersion" + + then { + assertAll( + { assert function.success }, + { assert snapshot(function.result).match() } + ) + } + } + + test("Test Function dumpParametersToJSON") { + + function "dumpParametersToJSON" + + when { + function { + """ + // define inputs of the function here. Example: + input[0] = "$outputDir" + """.stripIndent() + } + } + + then { + assertAll( + { assert function.success } + ) + } + } + + test("Test Function checkCondaChannels") { + + function "checkCondaChannels" + + then { + assertAll( + { assert function.success }, + { assert snapshot(function.result).match() } + ) + } + } +} diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.function.nf.test.snap b/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.function.nf.test.snap new file mode 100644 index 00000000..e3f0baf4 --- /dev/null +++ b/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.function.nf.test.snap @@ -0,0 +1,20 @@ +{ + "Test Function getWorkflowVersion": { + "content": [ + "v9.9.9" + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-28T12:02:05.308243" + }, + "Test Function checkCondaChannels": { + "content": null, + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-28T12:02:12.425833" + } +} \ No newline at end of file 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 new file mode 100644 index 00000000..02dbf094 --- /dev/null +++ b/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.workflow.nf.test @@ -0,0 +1,113 @@ +nextflow_workflow { + + name "Test Workflow UTILS_NEXTFLOW_PIPELINE" + script "../main.nf" + config "subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config" + workflow "UTILS_NEXTFLOW_PIPELINE" + tag 'subworkflows' + tag 'utils_nextflow_pipeline' + tag 'subworkflows/utils_nextflow_pipeline' + + test("Should run no inputs") { + + when { + workflow { + """ + print_version = false + dump_parameters = false + outdir = null + check_conda_channels = false + + input[0] = print_version + input[1] = dump_parameters + input[2] = outdir + input[3] = check_conda_channels + """ + } + } + + then { + assertAll( + { assert workflow.success } + ) + } + } + + test("Should print version") { + + when { + workflow { + """ + print_version = true + dump_parameters = false + outdir = null + check_conda_channels = false + + input[0] = print_version + input[1] = dump_parameters + input[2] = outdir + input[3] = check_conda_channels + """ + } + } + + then { + expect { + with(workflow) { + assert success + assert "nextflow_workflow v9.9.9" in stdout + } + } + } + } + + test("Should dump params") { + + when { + workflow { + """ + print_version = false + dump_parameters = true + outdir = 'results' + check_conda_channels = false + + input[0] = false + input[1] = true + input[2] = outdir + input[3] = false + """ + } + } + + then { + assertAll( + { assert workflow.success } + ) + } + } + + test("Should not create params JSON if no output directory") { + + when { + workflow { + """ + print_version = false + dump_parameters = true + outdir = null + check_conda_channels = false + + input[0] = false + input[1] = true + input[2] = outdir + input[3] = false + """ + } + } + + then { + assertAll( + { assert workflow.success } + ) + } + } +} diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config b/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config new file mode 100644 index 00000000..a09572e5 --- /dev/null +++ b/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config @@ -0,0 +1,9 @@ +manifest { + name = 'nextflow_workflow' + author = """nf-core""" + homePage = 'https://127.0.0.1' + description = """Dummy pipeline""" + 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 new file mode 100644 index 00000000..f8476112 --- /dev/null +++ b/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml @@ -0,0 +1,2 @@ +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 new file mode 100644 index 00000000..bfd25876 --- /dev/null +++ b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf @@ -0,0 +1,419 @@ +// +// Subworkflow with utility functions specific to the nf-core pipeline template +// + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + SUBWORKFLOW DEFINITION +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow UTILS_NFCORE_PIPELINE { + take: + nextflow_cli_args + + main: + valid_config = checkConfigProvided() + checkProfileProvided(nextflow_cli_args) + + emit: + valid_config +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// Warn if a -profile or Nextflow config has not been provided to run the pipeline +// +def checkConfigProvided() { + def valid_config = true as Boolean + if (workflow.profile == 'standard' && workflow.configFiles.size() <= 1) { + log.warn( + "[${workflow.manifest.name}] You are attempting to run the pipeline without any custom configuration!\n\n" + "This will be dependent on your local compute environment but can be achieved via one or more of the following:\n" + " (1) Using an existing pipeline profile e.g. `-profile docker` or `-profile singularity`\n" + " (2) Using an existing nf-core/configs for your Institution e.g. `-profile crick` or `-profile uppmax`\n" + " (3) Using your own local custom config e.g. `-c /path/to/your/custom.config`\n\n" + "Please refer to the quick start section and usage docs for the pipeline.\n " + ) + valid_config = false + } + return valid_config +} + +// +// Exit pipeline if --profile contains spaces +// +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" + ) + } + 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" + ) + } +} + +// +// Generate workflow version string +// +def getWorkflowVersion() { + 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}" + } + + if (workflow.commitId) { + def git_shortsha = workflow.commitId.substring(0, 7) + version_string += "-g${git_shortsha}" + } + + return version_string +} + +// +// Get software versions for pipeline +// +def processVersionsFromYAML(yaml_file) { + 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() +} + +// +// Get workflow version for pipeline +// +def workflowVersionToYAML() { + return """ + Workflow: + ${workflow.manifest.name}: ${getWorkflowVersion()} + Nextflow: ${workflow.nextflow.version} + """.stripIndent().trim() +} + +// +// Get channel of software versions used in pipeline in YAML format +// +def softwareVersionsToYAML(ch_versions) { + return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(Channel.of(workflowVersionToYAML())) +} + +// +// Get workflow summary for MultiQC +// +def paramsSummaryMultiqc(summary_params) { + def summary_section = '' + summary_params + .keySet() + .each { group -> + def group_params = summary_params.get(group) + // This gets the parameters of that particular group + if (group_params) { + summary_section += "

    ${group}

    \n" + summary_section += "
    \n" + group_params + .keySet() + .sort() + .each { param -> + summary_section += "
    ${param}
    ${group_params.get(param) ?: 'N/A'}
    \n" + } + summary_section += "
    \n" + } + } + + def yaml_file_text = "id: '${workflow.manifest.name.replace('/', '-')}-summary'\n" as String + yaml_file_text += "description: ' - this information is collected when the pipeline is started.'\n" + yaml_file_text += "section_name: '${workflow.manifest.name} Workflow Summary'\n" + yaml_file_text += "section_href: 'https://github.com/${workflow.manifest.name}'\n" + yaml_file_text += "plot_type: 'html'\n" + yaml_file_text += "data: |\n" + yaml_file_text += "${summary_section}" + + return yaml_file_text +} + +// +// ANSII colours used for terminal logging +// +def logColours(monochrome_logs=true) { + def colorcodes = [:] as Map + + // Reset / Meta + colorcodes['reset'] = monochrome_logs ? '' : "\033[0m" + colorcodes['bold'] = monochrome_logs ? '' : "\033[1m" + colorcodes['dim'] = monochrome_logs ? '' : "\033[2m" + colorcodes['underlined'] = monochrome_logs ? '' : "\033[4m" + colorcodes['blink'] = monochrome_logs ? '' : "\033[5m" + colorcodes['reverse'] = monochrome_logs ? '' : "\033[7m" + 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" + + // 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" + + // 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" + + // 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" + + // 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" + + return colorcodes +} + +// 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 + } +} + +// +// Construct and send completion email +// +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}" + if (!workflow.success) { + subject = "[${workflow.manifest.name}] FAILED: ${workflow.runName}" + } + + def summary = [:] + 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 + misc_fields['Nextflow Compile Timestamp'] = workflow.nextflow.timestamp + + def email_fields = [:] + email_fields['version'] = getWorkflowVersion() + email_fields['runName'] = workflow.runName + email_fields['success'] = workflow.success + email_fields['dateComplete'] = workflow.complete + email_fields['duration'] = workflow.duration + email_fields['exitStatus'] = workflow.exitStatus + email_fields['errorMessage'] = (workflow.errorMessage ?: 'None') + email_fields['errorReport'] = (workflow.errorReport ?: 'None') + email_fields['commandLine'] = workflow.commandLine + email_fields['projectDir'] = workflow.projectDir + email_fields['summary'] = summary << misc_fields + + // On success try attach the multiqc report + def mqc_report = getSingleReport(multiqc_report) + + // Check if we are only sending emails on failure + def email_address = email + if (!email && email_on_fail && !workflow.success) { + email_address = email_on_fail + } + + // Render the TXT template + def engine = new groovy.text.GStringTemplateEngine() + def tf = new File("${workflow.projectDir}/assets/email_template.txt") + def txt_template = engine.createTemplate(tf).make(email_fields) + def email_txt = txt_template.toString() + + // Render the HTML template + def hf = new File("${workflow.projectDir}/assets/email_template.html") + def html_template = engine.createTemplate(hf).make(email_fields) + 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 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 + def colors = logColours(monochrome_logs) as Map + if (email_address) { + try { + 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 (Exception msg) { + log.debug(msg.toString()) + log.debug("Trying with mail instead of sendmail") + // Catch failures and try with plaintext + def mail_cmd = ['mail', '-s', subject, '--content-type=text/html', email_address] + mail_cmd.execute() << email_html + log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Sent summary e-mail to ${email_address} (mail)-") + } + } + + // Write summary e-mail HTML to a file + def output_hf = new File(workflow.launchDir.toString(), ".pipeline_report.html") + output_hf.withWriter { w -> w << email_html } + nextflow.extension.FilesEx.copyTo(output_hf.toPath(), "${outdir}/pipeline_info/pipeline_report.html") + output_hf.delete() + + // Write summary e-mail TXT to a file + def output_tf = new File(workflow.launchDir.toString(), ".pipeline_report.txt") + output_tf.withWriter { w -> w << email_txt } + nextflow.extension.FilesEx.copyTo(output_tf.toPath(), "${outdir}/pipeline_info/pipeline_report.txt") + output_tf.delete() +} + +// +// Print pipeline summary on completion +// +def completionSummary(monochrome_logs=true) { + def colors = logColours(monochrome_logs) as Map + if (workflow.success) { + if (workflow.stats.ignoredCount == 0) { + log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Pipeline completed successfully${colors.reset}-") + } + else { + log.info("-${colors.purple}[${workflow.manifest.name}]${colors.yellow} Pipeline completed successfully, but with errored process(es) ${colors.reset}-") + } + } + else { + log.info("-${colors.purple}[${workflow.manifest.name}]${colors.red} Pipeline completed with errors${colors.reset}-") + } +} + +// +// Construct and send a notification to a web server as JSON e.g. Microsoft Teams and Slack +// +def imNotification(summary_params, hook_url) { + def summary = [:] + summary_params + .keySet() + .sort() + .each { group -> + summary << summary_params[group] + } + + def misc_fields = [:] + misc_fields['start'] = workflow.start + misc_fields['complete'] = workflow.complete + misc_fields['scriptfile'] = workflow.scriptFile + misc_fields['scriptid'] = workflow.scriptId + if (workflow.repository) { + misc_fields['repository'] = workflow.repository + } + if (workflow.commitId) { + misc_fields['commitid'] = workflow.commitId + } + if (workflow.revision) { + misc_fields['revision'] = workflow.revision + } + misc_fields['nxf_version'] = workflow.nextflow.version + misc_fields['nxf_build'] = workflow.nextflow.build + misc_fields['nxf_timestamp'] = workflow.nextflow.timestamp + + def msg_fields = [:] + msg_fields['version'] = getWorkflowVersion() + msg_fields['runName'] = workflow.runName + msg_fields['success'] = workflow.success + msg_fields['dateComplete'] = workflow.complete + msg_fields['duration'] = workflow.duration + msg_fields['exitStatus'] = workflow.exitStatus + msg_fields['errorMessage'] = (workflow.errorMessage ?: 'None') + msg_fields['errorReport'] = (workflow.errorReport ?: 'None') + msg_fields['commandLine'] = workflow.commandLine.replaceFirst(/ +--hook_url +[^ ]+/, "") + msg_fields['projectDir'] = workflow.projectDir + msg_fields['summary'] = summary << misc_fields + + // Render the JSON template + def engine = new groovy.text.GStringTemplateEngine() + // Different JSON depending on the service provider + // Defaults to "Adaptive Cards" (https://adaptivecards.io), except Slack which has its own format + def json_path = hook_url.contains("hooks.slack.com") ? "slackreport.json" : "adaptivecard.json" + def hf = new File("${workflow.projectDir}/assets/${json_path}") + def json_template = engine.createTemplate(hf).make(msg_fields) + def json_message = json_template.toString() + + // POST + def post = new URL(hook_url).openConnection() + post.setRequestMethod("POST") + post.setDoOutput(true) + post.setRequestProperty("Content-Type", "application/json") + post.getOutputStream().write(json_message.getBytes("UTF-8")) + def postRC = post.getResponseCode() + if (!postRC.equals(200)) { + log.warn(post.getErrorStream().getText()) + } +} diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/meta.yml b/subworkflows/nf-core/utils_nfcore_pipeline/meta.yml new file mode 100644 index 00000000..d08d2434 --- /dev/null +++ b/subworkflows/nf-core/utils_nfcore_pipeline/meta.yml @@ -0,0 +1,24 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: "UTILS_NFCORE_PIPELINE" +description: Subworkflow with utility functions specific to the nf-core pipeline template +keywords: + - utility + - pipeline + - initialise + - version +components: [] +input: + - nextflow_cli_args: + type: list + description: | + Nextflow CLI positional arguments +output: + - success: + type: boolean + description: | + Dummy output to indicate success +authors: + - "@adamrtalbot" +maintainers: + - "@adamrtalbot" + - "@maxulysse" 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 new file mode 100644 index 00000000..f117040c --- /dev/null +++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test @@ -0,0 +1,126 @@ + +nextflow_function { + + name "Test Functions" + script "../main.nf" + config "subworkflows/nf-core/utils_nfcore_pipeline/tests/nextflow.config" + tag "subworkflows" + tag "subworkflows_nfcore" + tag "utils_nfcore_pipeline" + tag "subworkflows/utils_nfcore_pipeline" + + test("Test Function checkConfigProvided") { + + function "checkConfigProvided" + + then { + assertAll( + { assert function.success }, + { assert snapshot(function.result).match() } + ) + } + } + + test("Test Function checkProfileProvided") { + + function "checkProfileProvided" + + when { + function { + """ + input[0] = [] + """ + } + } + + then { + assertAll( + { assert function.success }, + { assert snapshot(function.result).match() } + ) + } + } + + test("Test Function without logColours") { + + function "logColours" + + when { + function { + """ + input[0] = true + """ + } + } + + then { + assertAll( + { assert function.success }, + { assert snapshot(function.result).match() } + ) + } + } + + test("Test Function with logColours") { + function "logColours" + + when { + function { + """ + input[0] = false + """ + } + } + + then { + assertAll( + { assert function.success }, + { assert snapshot(function.result).match() } + ) + } + } + + test("Test Function getSingleReport with a single file") { + function "getSingleReport" + + when { + function { + """ + input[0] = file(params.modules_testdata_base_path + '/generic/tsv/test.tsv', checkIfExists: true) + """ + } + } + + then { + assertAll( + { assert function.success }, + { assert function.result.contains("test.tsv") } + ) + } + } + + test("Test Function getSingleReport with multiple files") { + function "getSingleReport" + + when { + function { + """ + 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) + ] + """ + } + } + + then { + assertAll( + { assert function.success }, + { 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 new file mode 100644 index 00000000..02c67014 --- /dev/null +++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test.snap @@ -0,0 +1,136 @@ +{ + "Test Function checkProfileProvided": { + "content": null, + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-28T12:03:03.360873" + }, + "Test Function checkConfigProvided": { + "content": [ + true + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-28T12:02:59.729647" + }, + "Test Function without logColours": { + "content": [ + { + "reset": "", + "bold": "", + "dim": "", + "underlined": "", + "blink": "", + "reverse": "", + "hidden": "", + "black": "", + "red": "", + "green": "", + "yellow": "", + "blue": "", + "purple": "", + "cyan": "", + "white": "", + "bblack": "", + "bred": "", + "bgreen": "", + "byellow": "", + "bblue": "", + "bpurple": "", + "bcyan": "", + "bwhite": "", + "ublack": "", + "ured": "", + "ugreen": "", + "uyellow": "", + "ublue": "", + "upurple": "", + "ucyan": "", + "uwhite": "", + "iblack": "", + "ired": "", + "igreen": "", + "iyellow": "", + "iblue": "", + "ipurple": "", + "icyan": "", + "iwhite": "", + "biblack": "", + "bired": "", + "bigreen": "", + "biyellow": "", + "biblue": "", + "bipurple": "", + "bicyan": "", + "biwhite": "" + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-28T12:03:17.969323" + }, + "Test Function with logColours": { + "content": [ + { + "reset": "\u001b[0m", + "bold": "\u001b[1m", + "dim": "\u001b[2m", + "underlined": "\u001b[4m", + "blink": "\u001b[5m", + "reverse": "\u001b[7m", + "hidden": "\u001b[8m", + "black": "\u001b[0;30m", + "red": "\u001b[0;31m", + "green": "\u001b[0;32m", + "yellow": "\u001b[0;33m", + "blue": "\u001b[0;34m", + "purple": "\u001b[0;35m", + "cyan": "\u001b[0;36m", + "white": "\u001b[0;37m", + "bblack": "\u001b[1;30m", + "bred": "\u001b[1;31m", + "bgreen": "\u001b[1;32m", + "byellow": "\u001b[1;33m", + "bblue": "\u001b[1;34m", + "bpurple": "\u001b[1;35m", + "bcyan": "\u001b[1;36m", + "bwhite": "\u001b[1;37m", + "ublack": "\u001b[4;30m", + "ured": "\u001b[4;31m", + "ugreen": "\u001b[4;32m", + "uyellow": "\u001b[4;33m", + "ublue": "\u001b[4;34m", + "upurple": "\u001b[4;35m", + "ucyan": "\u001b[4;36m", + "uwhite": "\u001b[4;37m", + "iblack": "\u001b[0;90m", + "ired": "\u001b[0;91m", + "igreen": "\u001b[0;92m", + "iyellow": "\u001b[0;93m", + "iblue": "\u001b[0;94m", + "ipurple": "\u001b[0;95m", + "icyan": "\u001b[0;96m", + "iwhite": "\u001b[0;97m", + "biblack": "\u001b[1;90m", + "bired": "\u001b[1;91m", + "bigreen": "\u001b[1;92m", + "biyellow": "\u001b[1;93m", + "biblue": "\u001b[1;94m", + "bipurple": "\u001b[1;95m", + "bicyan": "\u001b[1;96m", + "biwhite": "\u001b[1;97m" + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-28T12:03:21.714424" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test new file mode 100644 index 00000000..8940d32d --- /dev/null +++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test @@ -0,0 +1,29 @@ +nextflow_workflow { + + name "Test Workflow UTILS_NFCORE_PIPELINE" + script "../main.nf" + config "subworkflows/nf-core/utils_nfcore_pipeline/tests/nextflow.config" + workflow "UTILS_NFCORE_PIPELINE" + tag "subworkflows" + tag "subworkflows_nfcore" + tag "utils_nfcore_pipeline" + tag "subworkflows/utils_nfcore_pipeline" + + test("Should run without failures") { + + when { + workflow { + """ + input[0] = [] + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } +} diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap new file mode 100644 index 00000000..859d1030 --- /dev/null +++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap @@ -0,0 +1,19 @@ +{ + "Should run without failures": { + "content": [ + { + "0": [ + true + ], + "valid_config": [ + true + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "23.10.1" + }, + "timestamp": "2024-02-28T12:03:25.726491" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/nextflow.config b/subworkflows/nf-core/utils_nfcore_pipeline/tests/nextflow.config new file mode 100644 index 00000000..d0a926bf --- /dev/null +++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/nextflow.config @@ -0,0 +1,9 @@ +manifest { + name = 'nextflow_workflow' + author = """nf-core""" + homePage = 'https://127.0.0.1' + description = """Dummy pipeline""" + nextflowVersion = '!>=23.04.0' + version = '9.9.9' + doi = 'https://doi.org/10.5281/zenodo.5070524' +} diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml b/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml new file mode 100644 index 00000000..ac8523c9 --- /dev/null +++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml @@ -0,0 +1,2 @@ +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 00000000..4994303e --- /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 00000000..f7d9f028 --- /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 00000000..8fb30164 --- /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 00000000..0907ac58 --- /dev/null +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config @@ -0,0 +1,8 @@ +plugins { + id "nf-schema@2.1.0" +} + +validation { + parametersSchema = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json" + monochromeLogs = true +} \ No newline at end of file diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json new file mode 100644 index 00000000..331e0d2f --- /dev/null +++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json @@ -0,0 +1,96 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/./master/nextflow_schema.json", + "title": ". pipeline parameters", + "description": "", + "type": "object", + "$defs": { + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["outdir"], + "properties": { + "validate_params": { + "type": "boolean", + "description": "Validate parameters?", + "default": true, + "hidden": true + }, + "outdir": { + "type": "string", + "format": "directory-path", + "description": "The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure.", + "fa_icon": "fas fa-folder-open" + }, + "test_data_base": { + "type": "string", + "default": "https://raw.githubusercontent.com/nf-core/test-datasets/modules", + "description": "Base for test data directory", + "hidden": true + }, + "test_data": { + "type": "string", + "description": "Fake test data param", + "hidden": true + } + } + }, + "generic_options": { + "title": "Generic options", + "type": "object", + "fa_icon": "fas fa-file-import", + "description": "Less common options for the pipeline, typically set in a config file.", + "help_text": "These options are common to all nf-core pipelines and allow you to customise some of the core preferences for how the pipeline runs.\n\nTypically these options would be set in a Nextflow config file loaded for all pipeline runs, such as `~/.nextflow/config`.", + "properties": { + "help": { + "type": "boolean", + "description": "Display help text.", + "fa_icon": "fas fa-question-circle", + "hidden": true + }, + "version": { + "type": "boolean", + "description": "Display version and exit.", + "fa_icon": "fas fa-question-circle", + "hidden": true + }, + "logo": { + "type": "boolean", + "default": true, + "description": "Display nf-core logo in console output.", + "fa_icon": "fas fa-image", + "hidden": true + }, + "singularity_pull_docker_container": { + "type": "boolean", + "description": "Pull Singularity container from Docker?", + "hidden": true + }, + "publish_dir_mode": { + "type": "string", + "default": "copy", + "description": "Method used to save pipeline results to output directory.", + "help_text": "The Nextflow `publishDir` option specifies which intermediate files should be saved to the output directory. This option tells the pipeline what method should be used to move these files. See [Nextflow docs](https://www.nextflow.io/docs/latest/process.html#publishdir) for details.", + "fa_icon": "fas fa-copy", + "enum": ["symlink", "rellink", "link", "copy", "copyNoFollow", "move"], + "hidden": true + }, + "monochrome_logs": { + "type": "boolean", + "description": "Use monochrome_logs", + "hidden": true + } + } + } + }, + "allOf": [ + { + "$ref": "#/$defs/input_output_options" + }, + { + "$ref": "#/$defs/generic_options" + } + ] +} diff --git a/tests/.nftignore b/tests/.nftignore new file mode 100644 index 00000000..60cbdcea --- /dev/null +++ b/tests/.nftignore @@ -0,0 +1,40 @@ +preprocessing/fastqc/*.{html,zip} +preprocessing/fastp/*.{html,log} + +multiqc/multiqc_data/** +multiqc/multiqc_data/*.{log,json} +multiqc/multiqc_data/multiqc_general_stats.txt +multiqc/multiqc_data/fastqc_top_overrepresented_sequences_table.txt +multiqc/multiqc_data/homer_tagdir.txt +multiqc/multiqc_data/rseqc_read_dups.txt +multiqc/multiqc_data/multiqc_software_versions.txt +multiqc/multiqc_data/multiqc_sources.txt +multiqc/multiqc_report.html +multiqc/multiqc_plots/** +multiqc/multiqc_plots/{pdf,png,svg}/*.{pdf,png,svg} +pipeline_info/*.{html,json,txt,yml} + +*/alignments/logs/*.txt +star/log/*.Log.{final.out,out,progress.out} +star/star/Log.out +hisat2/log/*.hisat2.summary.log +*/deduplicated/logs/*.txt +*/{reports,summary}/*.{html,txt} +**/*.command.log +**/*.bedGraph.gz +**/tagInfo.txt +**/*.{bam,bai} +**/*.featureCounts.txt +**/*.featureCounts.txt.summary +**/*.pdf + +transcript_identification/homer/*_tagdir/* +transcript_identification/filtered/*_filtered.bed +transcript_identification/intersect/*_intersect.bed +transcript_identification/grohmm/*.tdFinal.txt +transcript_identification/grohmm/*.tdFinal_mqc.csv +transcript_identification/grohmm/*.tdplot_mqc.png + +quality_control/bbsplit/*.stats.txt +quality_control/** +**/DupRate_plot.pdf diff --git a/tests/config/tuningparams_small.csv b/tests/config/tuningparams_small.csv index 047b4186..e28ef149 100644 --- a/tests/config/tuningparams_small.csv +++ b/tests/config/tuningparams_small.csv @@ -1,3 +1,10 @@ -"LtProbB","UTS" --100,5 --200,5 +LtProbB,UTS,merged,dissociated,total,errorRate,txSize +-100,5,50,135,185,0.07769845,1391 +-100,10,61,177,238,0.07775237,2071 +-100,15,68,201,269,0.07441217,2625 +-200,5,64,47,111,0.06098901,830 +-200,10,74,65,139,0.06547339,1133 +-200,15,80,76,156,0.06643952,1358 +-300,5,69,22,91,0.05501814,664 +-300,10,82,30,112,0.06005362,875 +-300,15,90,41,131,0.06498016,1026 diff --git a/tests/lib/UTILS.groovy b/tests/lib/UTILS.groovy new file mode 100644 index 00000000..a5c780ee --- /dev/null +++ b/tests/lib/UTILS.groovy @@ -0,0 +1,34 @@ +class UTILS { + // Recursively list all files in a directory and its sub-directories, matching a given suffix + // TODO: use regex pattern instead of suffix? + public static getAllFilesFromDir(dir, suffix) { + def output = [] + new File(dir).eachFileRecurse() { + if (it.name.toString().endsWith(suffix)) { + output.add(it) + } + } + return output.sort() + } + // Recursively list all files names in a directory and its sub-directories, matching a given suffix, return file names + public static getAllFileNamesFromDir(dir, suffix) { + def output = [] + new File(dir).eachFileRecurse() { + if (it.name.toString().endsWith(suffix)) { + output.add(it.toString().split("/")[-1]) + } + } + return output.sort() + } + + // Recursively list all files names in a directory and its sub-directories, matching a given suffix, return if check if given string is in file + public static checkAllFilesNamesFromDirForString(dir, suffix, string) { + def output = [] + new File(dir).eachFileRecurse() { + if (it.name.toString().endsWith(suffix)) { + output.add(it.text.contains(string)) + } + } + return output.sort() + } +} diff --git a/tests/nextflow.config b/tests/nextflow.config index 8d899cb5..a029ac75 100644 --- a/tests/nextflow.config +++ b/tests/nextflow.config @@ -18,7 +18,7 @@ process { // Impose same minimum Nextflow version as the pipeline for testing manifest { - nextflowVersion = '!>=23.04.0' + nextflowVersion = '!>=24.04.2' } // Disable all Nextflow reporting options @@ -30,7 +30,7 @@ dag { enabled = false } // HACK Hard code all the params for now params { // Input data - input = "${projectDir}/assets/samplesheet.csv" + input = "${projectDir}/assets/small_samplesheet.csv" // Genome references fasta = 'https://raw.githubusercontent.com/nf-core/test-datasets/nascent/reference/GRCh38_chr21.fa' @@ -38,7 +38,6 @@ params { assay_type = "GROseq" skip_grohmm = true // FIXME Fails due to higher memory requirements - tuning_file = "${projectDir}/tests/config/tuningparams_small.csv" filter_bed = "${projectDir}/tests/config/unwanted_region.bed" intersect_bed = "${projectDir}/tests/config/wanted_region.bed" } diff --git a/workflows/nascent.nf b/workflows/nascent.nf index 26cb4e63..724bf1bb 100644 --- a/workflows/nascent.nf +++ b/workflows/nascent.nf @@ -1,72 +1,41 @@ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - PRINT PARAMS SUMMARY + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -include { paramsSummaryLog; paramsSummaryMap; fromSamplesheet } from 'plugin/nf-validation' +include { BED2SAF } from '../modules/local/bed2saf' -def logo = NfcoreTemplate.logo(workflow, params.monochrome_logs) -def citation = '\n' + WorkflowMain.citation(workflow) + '\n' -def summary_params = paramsSummaryMap(workflow) +include { PREPARE_GENOME } from '../subworkflows/local/prepare_genome' +include { ALIGN_BWAMEM2 } from '../subworkflows/local/align_bwamem2/main' +include { ALIGN_DRAGMAP } from '../subworkflows/local/align_dragmap/main' +include { QUALITY_CONTROL } from '../subworkflows/local/quality_control.nf' +include { COVERAGE_GRAPHS } from '../subworkflows/local/coverage_graphs.nf' +include { TRANSCRIPT_INDENTIFICATION } from '../subworkflows/local/transcript_identification' -// Print parameter summary log to screen -log.info logo + paramsSummaryLog(workflow) + citation +include { FASTP } from '../modules/nf-core/fastp/main' +include { UNTAR as UNTAR_HISAT2_INDEX } from '../modules/nf-core/untar/main' +include { UNTAR as UNTAR_STAR_INDEX } from '../modules/nf-core/untar/main' +include { STAR_GENOMEGENERATE } from '../modules/nf-core/star/genomegenerate/main' +include { SUBREAD_FEATURECOUNTS as SUBREAD_FEATURECOUNTS_GENE } from '../modules/nf-core/subread/featurecounts/main' +include { SUBREAD_FEATURECOUNTS as SUBREAD_FEATURECOUNTS_PREDICTED } from '../modules/nf-core/subread/featurecounts/main' -WorkflowNascent.initialise(params, log) - -// HACK Rework this because of nf-validation -def prepareToolIndices = [] -if (!params.skip_alignment) { prepareToolIndices << params.aligner } - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - CONFIG FILES -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -ch_multiqc_config = Channel.fromPath("$projectDir/assets/multiqc_config.yml", checkIfExists: true) -ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath( params.multiqc_config, checkIfExists: true ) : Channel.empty() -ch_multiqc_logo = params.multiqc_logo ? Channel.fromPath( params.multiqc_logo, checkIfExists: true ) : Channel.empty() -ch_multiqc_custom_methods_description = params.multiqc_methods_description ? file(params.multiqc_methods_description, checkIfExists: true) : file("$projectDir/assets/methods_description_template.yml", checkIfExists: true) - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - IMPORT LOCAL MODULES/SUBWORKFLOWS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -include { BED2SAF } from '../modules/local/bed2saf' - -include { PREPARE_GENOME } from '../subworkflows/local/prepare_genome' -include { ALIGN_BWAMEM2 } from '../subworkflows/local/align_bwamem2/main' -include { ALIGN_DRAGMAP } from '../subworkflows/local/align_dragmap/main' -include { QUALITY_CONTROL } from '../subworkflows/local/quality_control.nf' -include { COVERAGE_GRAPHS } from '../subworkflows/local/coverage_graphs.nf' -include { TRANSCRIPT_INDENTIFICATION } from '../subworkflows/local/transcript_identification.nf' - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - IMPORT NF-CORE MODULES/SUBWORKFLOWS -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -include { FASTQC } from '../modules/nf-core/fastqc/main' -include { FASTP } from '../modules/nf-core/fastp/main' -include { CAT_FASTQ } from '../modules/nf-core/cat/fastq/main' -include { - SUBREAD_FEATURECOUNTS as SUBREAD_FEATURECOUNTS_GENE - SUBREAD_FEATURECOUNTS as SUBREAD_FEATURECOUNTS_PREDICTED } from '../modules/nf-core/subread/featurecounts/main' -include { MULTIQC } from '../modules/nf-core/multiqc/main' -include { CUSTOM_DUMPSOFTWAREVERSIONS } from '../modules/nf-core/custom/dumpsoftwareversions/main' +include { FASTQC } from '../modules/nf-core/fastqc/main' +include { MULTIQC } from '../modules/nf-core/multiqc/main' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { paramsSummaryMultiqc } from '../subworkflows/nf-core/utils_nfcore_pipeline' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' +include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_nascent_pipeline' // // SUBWORKFLOW: Consisting entirely of nf-core/modules // -include { FASTQ_ALIGN_BWA } from '../subworkflows/nf-core/fastq_align_bwa/main' -include { FASTQ_ALIGN_BOWTIE2 } from '../subworkflows/nf-core/fastq_align_bowtie2/main' -include { BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS } from '../subworkflows/nf-core/bam_dedup_stats_samtools_umitools/main' +include { FASTQ_ALIGN_BWA } from '../subworkflows/nf-core/fastq_align_bwa/main' +include { FASTQ_ALIGN_BOWTIE2 } from '../subworkflows/nf-core/fastq_align_bowtie2/main' +include { FASTQ_ALIGN_HISAT2 } from '../subworkflows/nf-core/fastq_align_hisat2/main' +include { FASTQ_ALIGN_STAR } from '../subworkflows/nf-core/fastq_align_star/main' +include { BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS } from '../subworkflows/nf-core/bam_dedup_stats_samtools_umitools/main' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -74,64 +43,66 @@ include { BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS } from '../subworkflows/nf-core/bam_ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -// Info required for completion email and summary -def multiqc_report = [] - workflow NASCENT { + take: + ch_samplesheet // channel: samplesheet read in from --input + ch_fasta + ch_gtf + ch_gff + ch_gene_bed + ch_bwa_index + ch_bwamem2_index + ch_dragmap + ch_bowtie2_index + ch_hisat2_index + ch_star_index + ch_uniqmap + + main: ch_versions = Channel.empty() - ch_nascent_logo = Channel.fromPath("$projectDir/docs/images/nf-core-nascent_logo_light.png") - + ch_multiqc_files = Channel.empty() // // SUBWORKFLOW: Uncompress and prepare reference genome files // - PREPARE_GENOME ( + + // HACK Rework this because of nf-validation + def prepareToolIndices = [] + if (!params.skip_alignment) { + prepareToolIndices << params.aligner + } + PREPARE_GENOME( prepareToolIndices, - params.fasta, - params.gtf, - params.gff, + ch_fasta, + ch_gtf, + ch_gff, + ch_gene_bed, + ch_bwa_index, + ch_bwamem2_index, + ch_dragmap, + ch_bowtie2_index, + ch_hisat2_index ) - ch_versions = ch_versions.mix(PREPARE_GENOME.out.versions.first()) - ch_fasta = PREPARE_GENOME.out.fasta.map{ fasta -> [ [ id:fasta.baseName ], fasta ] } - - // - // Create input channel from input file provided through params.input - // - Channel - .fromSamplesheet("input") - .map { - meta, fastq_1, fastq_2 -> - if (!fastq_2) { - return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] - } else { - return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] - } - } - .groupTuple() - .map { - WorkflowNascent.validateInput(it) - } - .map { - meta, fastqs -> - return [ meta, fastqs.flatten() ] - } - .set { ch_fastq } + ch_versions = ch_versions.mix(PREPARE_GENOME.out.versions) + ch_fasta = PREPARE_GENOME.out.fasta.map { fasta -> [[id: fasta.baseName], fasta] } // // MODULE: Run FastQC // - FASTQC ( - ch_fastq + FASTQC( + ch_samplesheet ) + ch_multiqc_files = ch_multiqc_files.mix(FASTQC.out.zip.collect { it[1] }) ch_versions = ch_versions.mix(FASTQC.out.versions.first()) ch_reads = Channel.empty() - if(!params.skip_trimming) { - FASTP ( ch_fastq, [], false, false ) + if (!params.skip_trimming) { + FASTP(ch_samplesheet, [], false, false, false) ch_reads = FASTP.out.reads ch_versions = ch_versions.mix(FASTP.out.versions.first()) - } else { - ch_reads = ch_fastq + } + else { + ch_reads = ch_samplesheet } // @@ -147,11 +118,11 @@ workflow NASCENT { ch_aligner_clustering_multiqc = Channel.empty() ch_bowtie2_multiqc = Channel.empty() if (!params.skip_alignment && params.aligner == 'bwa') { - FASTQ_ALIGN_BWA ( + FASTQ_ALIGN_BWA( ch_reads, PREPARE_GENOME.out.bwa_index, false, - ch_fasta, + ch_fasta ) ch_genome_bam = FASTQ_ALIGN_BWA.out.bam ch_genome_bai = FASTQ_ALIGN_BWA.out.bai @@ -160,12 +131,13 @@ workflow NASCENT { ch_samtools_idxstats = FASTQ_ALIGN_BWA.out.idxstats ch_versions = ch_versions.mix(FASTQ_ALIGN_BWA.out.versions.first()) - } else if (!params.skip_alignment && params.aligner == 'bwamem2') { - ALIGN_BWAMEM2 ( + } + else if (!params.skip_alignment && params.aligner == 'bwamem2') { + ALIGN_BWAMEM2( ch_reads, PREPARE_GENOME.out.bwa_index, false, - ch_fasta, + ch_fasta ) ch_genome_bam = ALIGN_BWAMEM2.out.bam ch_genome_bai = ALIGN_BWAMEM2.out.bai @@ -174,12 +146,13 @@ workflow NASCENT { ch_samtools_idxstats = ALIGN_BWAMEM2.out.idxstats ch_versions = ch_versions.mix(ALIGN_BWAMEM2.out.versions) - } else if (!params.skip_alignment && params.aligner == 'dragmap') { - ALIGN_DRAGMAP ( + } + else if (!params.skip_alignment && params.aligner == 'dragmap') { + ALIGN_DRAGMAP( ch_reads, PREPARE_GENOME.out.dragmap, false, - ch_fasta, + ch_fasta ) ch_genome_bam = ALIGN_DRAGMAP.out.bam ch_genome_bai = ALIGN_DRAGMAP.out.bai @@ -188,13 +161,14 @@ workflow NASCENT { ch_samtools_idxstats = ALIGN_DRAGMAP.out.idxstats ch_versions = ch_versions.mix(ALIGN_DRAGMAP.out.versions) - } else if (!params.skip_alignment && params.aligner == 'bowtie2') { - FASTQ_ALIGN_BOWTIE2 ( + } + else if (!params.skip_alignment && params.aligner == 'bowtie2') { + FASTQ_ALIGN_BOWTIE2( ch_reads, PREPARE_GENOME.out.bowtie2_index, false, false, - ch_fasta, + ch_fasta ) ch_genome_bam = FASTQ_ALIGN_BOWTIE2.out.bam ch_genome_bai = FASTQ_ALIGN_BOWTIE2.out.bai @@ -205,9 +179,69 @@ workflow NASCENT { ch_bowtie2_multiqc = FASTQ_ALIGN_BOWTIE2.out.log_out ch_versions = ch_versions.mix(FASTQ_ALIGN_BOWTIE2.out.versions) } + else if (!params.skip_alignment && params.aligner == 'hisat2') { + if (ch_hisat2_index.endsWith('.tar.gz')) { + ch_hisat2_index = UNTAR_HISAT2_INDEX([[:], ch_hisat2_index]).untar + ch_versions = ch_versions.mix(UNTAR_HISAT2_INDEX.out.versions) + } + else { + // TODO Give the meta from basename or genome? + ch_hisat2_index = [[meta: "Genome"], file(ch_hisat2_index)] + } + + FASTQ_ALIGN_HISAT2( + ch_reads, + ch_hisat2_index, + [[:], []], + ch_fasta + ) + ch_genome_bam = FASTQ_ALIGN_HISAT2.out.bam + ch_genome_bai = FASTQ_ALIGN_HISAT2.out.bai + ch_samtools_stats = FASTQ_ALIGN_HISAT2.out.stats + ch_samtools_flagstat = FASTQ_ALIGN_HISAT2.out.flagstat + ch_samtools_idxstats = FASTQ_ALIGN_HISAT2.out.idxstats + + ch_HISAT2_multiqc = FASTQ_ALIGN_HISAT2.out.summary + ch_versions = ch_versions.mix(FASTQ_ALIGN_HISAT2.out.versions) + } + else if (!params.skip_alignment && params.aligner == 'star') { + if (!ch_star_index) { + ch_star_index = STAR_GENOMEGENERATE( + ch_fasta, + PREPARE_GENOME.out.gtf.map { [[:], it] } + ).index + } + else if (ch_star_index.endsWith('.tar.gz')) { + ch_star_index = UNTAR_STAR_INDEX([[:], ch_star_index]).untar + ch_versions = ch_versions.mix(UNTAR_STAR_INDEX.out.versions) + } + else { + // TODO Give the meta from basename or genome? + ch_star_index = [[meta: "Genome"], file(ch_star_index)] + } - if(params.with_umi) { - BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS ( + FASTQ_ALIGN_STAR( + ch_reads, + ch_star_index, + PREPARE_GENOME.out.gtf.map { [[:], it] }, + false, + '', + '', + ch_fasta, + Channel.of([[:], []]) + ) + ch_genome_bam = FASTQ_ALIGN_STAR.out.bam + ch_genome_bai = FASTQ_ALIGN_STAR.out.bai + ch_transcriptome_bam = FASTQ_ALIGN_STAR.out.bam_transcript + ch_star_log = FASTQ_ALIGN_STAR.out.log_final + ch_multiqc_files = ch_multiqc_files.mix(FASTQ_ALIGN_STAR.out.stats.collect { it[1] }) + ch_multiqc_files = ch_multiqc_files.mix(FASTQ_ALIGN_STAR.out.flagstat.collect { it[1] }) + ch_multiqc_files = ch_multiqc_files.mix(FASTQ_ALIGN_STAR.out.idxstats.collect { it[1] }) + ch_multiqc_files = ch_multiqc_files.mix(ch_star_log.collect { it[1] }) + } + + if (params.with_umi) { + BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS( ch_genome_bam.join(ch_genome_bai, by: [0]), params.umitools_dedup_stats ) @@ -220,15 +254,16 @@ workflow NASCENT { ch_versions = ch_versions.mix(BAM_DEDUP_STATS_SAMTOOLS_UMITOOLS.out.versions) } - QUALITY_CONTROL ( - ch_genome_bam, + ch_genome_bam_bai = ch_genome_bam.join(ch_genome_bai, by: [0], remainder: true) + + QUALITY_CONTROL( + ch_genome_bam_bai, PREPARE_GENOME.out.gene_bed ) ch_versions = ch_versions.mix(QUALITY_CONTROL.out.versions) - COVERAGE_GRAPHS ( - ch_genome_bam, - ch_genome_bai, + COVERAGE_GRAPHS( + ch_genome_bam_bai, PREPARE_GENOME.out.chrom_sizes, PREPARE_GENOME.out.fasta, PREPARE_GENOME.out.fai @@ -238,109 +273,134 @@ workflow NASCENT { // // SUBWORKFLOW: Transcript indetification // - ch_genome_bam.map { - meta, bam -> - fmeta = meta.findAll { it.key != 'read_group' } - // Split and take the first element - fmeta.id = fmeta.id.split('_')[0] - [ fmeta, bam ] } + ch_genome_bam + .map { meta, bam -> + fmeta = meta.findAll { it.key != 'read_group' } + // Split and take the first element + fmeta.id = fmeta.id.split('_')[0] + [fmeta, bam] + } + .groupTuple(by: [0]) + .map { it -> [it[0], it[1].flatten()] } + .set { ch_group_bam } + // Group the index files with bams + ch_genome_bai + .map { meta, bai -> + fmeta = meta.findAll { it.key != 'read_group' } + // Split and take the first element + fmeta.id = fmeta.id.split('_')[0] + [fmeta, bai] + } .groupTuple(by: [0]) - .map { it -> [ it[0], it[1].flatten() ] } - .set { ch_sort_bam } + .map { it -> [it[0], it[1].flatten()] } + .set { ch_group_bai } - TRANSCRIPT_INDENTIFICATION ( - ch_sort_bam, - PREPARE_GENOME.out.gtf, + ch_group_bam_bai = ch_group_bam.join(ch_group_bai, by: [0]) + + ch_gxf = ch_gff ? ch_gff : PREPARE_GENOME.out.gtf + + TRANSCRIPT_INDENTIFICATION( + ch_group_bam_bai, + ch_gxf, PREPARE_GENOME.out.fasta, PREPARE_GENOME.out.chrom_sizes, + ch_uniqmap ) ch_grohmm_multiqc = TRANSCRIPT_INDENTIFICATION.out.grohmm_td_plot.collect() ch_homer_multiqc = TRANSCRIPT_INDENTIFICATION.out.homer_peaks ch_homer_multiqc = ch_homer_multiqc.mix(TRANSCRIPT_INDENTIFICATION.out.homer_tagdir) ch_versions = ch_versions.mix(TRANSCRIPT_INDENTIFICATION.out.versions) - SUBREAD_FEATURECOUNTS_PREDICTED ( - ch_sort_bam.combine( - BED2SAF ( + SUBREAD_FEATURECOUNTS_PREDICTED( + ch_group_bam.combine( + BED2SAF( TRANSCRIPT_INDENTIFICATION.out.transcript_beds ).saf.map { it[1] } ) ) ch_versions = ch_versions.mix(SUBREAD_FEATURECOUNTS_PREDICTED.out.versions.first()) - SUBREAD_FEATURECOUNTS_GENE ( - ch_sort_bam.combine(PREPARE_GENOME.out.gtf) + SUBREAD_FEATURECOUNTS_GENE( + ch_group_bam.combine(PREPARE_GENOME.out.gtf) ) ch_versions = ch_versions.mix(SUBREAD_FEATURECOUNTS_GENE.out.versions.first()) - CUSTOM_DUMPSOFTWAREVERSIONS ( - ch_versions.unique().collectFile(name: 'collated_versions.yml') - ) + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'nf_core_' + 'nascent_software_' + 'mqc_' + 'versions.yml', + sort: true, + newLine: true + ) + .set { ch_collated_versions } + // // MODULE: MultiQC // - workflow_summary = WorkflowNascent.paramsSummaryMultiqc(workflow, summary_params) - ch_workflow_summary = Channel.value(workflow_summary) + 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) + ) - methods_description = WorkflowNascent.methodsDescriptionText(workflow, ch_multiqc_custom_methods_description, params) - ch_methods_description = Channel.value(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 + ) + ) - ch_multiqc_files = Channel.empty() - .mix(ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) - .mix(ch_methods_description.collectFile(name: 'methods_description_mqc.yaml')) - .mix(CUSTOM_DUMPSOFTWAREVERSIONS.out.mqc_yml.collect()) - .mix(FASTQC.out.zip.collect{it[1]}.ifEmpty([])) - .mix(ch_bowtie2_multiqc.collect{it[1]}.ifEmpty([])) - .mix(ch_samtools_stats.collect{it[1]}.ifEmpty([])) - .mix(ch_samtools_flagstat.collect{it[1]}.ifEmpty([])) - .mix(ch_samtools_idxstats.collect{it[1]}.ifEmpty([])) - .mix(QUALITY_CONTROL.out.preseq_ccurve.collect{it[1]}.ifEmpty([])) - .mix(QUALITY_CONTROL.out.preseq_lcextrap.collect{it[1]}.ifEmpty([])) - .mix(QUALITY_CONTROL.out.readdistribution_txt.collect{it[1]}.ifEmpty([])) - .mix(QUALITY_CONTROL.out.readduplication_seq_xls.collect{it[1]}.ifEmpty([])) - .mix(QUALITY_CONTROL.out.readduplication_pos_xls.collect{it[1]}.ifEmpty([])) - .mix(QUALITY_CONTROL.out.inferexperiment_txt.collect{it[1]}.ifEmpty([])) - .mix(ch_grohmm_multiqc.collect{it[1]}.ifEmpty([])) - .mix(ch_homer_multiqc.collect{it[1]}.ifEmpty([])) - .mix(SUBREAD_FEATURECOUNTS_PREDICTED.out.summary.collect{it[1]}.ifEmpty([])) - .mix(SUBREAD_FEATURECOUNTS_GENE.out.summary.collect{it[1]}.ifEmpty([])) - - MULTIQC ( + ch_multiqc_files = ch_multiqc_files.mix(FASTQC.out.zip.collect { it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(ch_bowtie2_multiqc.collect { it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(ch_samtools_stats.collect { it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(ch_samtools_flagstat.collect { it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(ch_samtools_idxstats.collect { it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(QUALITY_CONTROL.out.preseq_ccurve.collect { it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(QUALITY_CONTROL.out.preseq_lcextrap.collect { it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(QUALITY_CONTROL.out.readdistribution_txt.collect { it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(QUALITY_CONTROL.out.readduplication_seq_xls.collect { it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(QUALITY_CONTROL.out.readduplication_pos_xls.collect { it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(QUALITY_CONTROL.out.inferexperiment_txt.collect { it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(ch_grohmm_multiqc.collect { it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(ch_homer_multiqc.collect { it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(SUBREAD_FEATURECOUNTS_PREDICTED.out.summary.collect { it[1] }.ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(SUBREAD_FEATURECOUNTS_GENE.out.summary.collect { it[1] }.ifEmpty([])) + + MULTIQC( ch_multiqc_files.collect(), ch_multiqc_config.toList(), ch_multiqc_custom_config.toList(), - ch_multiqc_logo.toList() + ch_multiqc_logo.toList(), + [], + [] ) - multiqc_report = MULTIQC.out.report.toList() -} - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - COMPLETION EMAIL AND SUMMARY -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -workflow.onComplete { - if (params.email || params.email_on_fail) { - NfcoreTemplate.email(workflow, params, summary_params, projectDir, log, multiqc_report) - } - NfcoreTemplate.dump_parameters(workflow, params) - NfcoreTemplate.summary(workflow, params, log) - if (params.hook_url) { - NfcoreTemplate.IM_notification(workflow, params, summary_params, projectDir, log) - } -} -workflow.onError { - if (workflow.errorReport.contains("Process requirement exceeds available memory")) { - println("🛑 Default resources exceed availability 🛑 ") - println("💡 See here on how to configure pipeline: https://nf-co.re/docs/usage/configuration#tuning-workflow-resources 💡") - } + emit: + multiqc_report = MULTIQC.out.report.toList() // channel: /path/to/multiqc_report.html + versions = ch_versions // channel: [ path(versions.yml) ] } - -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - THE END -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ diff --git a/workflows/tests/aligner/bowtie2.nf.test b/workflows/tests/aligner/bowtie2.nf.test new file mode 100644 index 00000000..4f91e553 --- /dev/null +++ b/workflows/tests/aligner/bowtie2.nf.test @@ -0,0 +1,41 @@ +nextflow_pipeline { + + name "Bowtie2" + script "../../../main.nf" + tag "aligner" + tag "bowtie2" + + test("Should run with defaults") { + + when { + params { + outdir = "$outputDir" + aligner = "bowtie2" + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}', 'multiqc/multiqc_plots', 'multiqc/multiqc_plots/**']) + // stable_path: All files in ${params.outdir}/ with stable content + def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') + // bam_files: All bam files + def bam_files = getAllFilesFromDir(params.outdir, include: ['**/*.bam']) + assertAll( + { assert workflow.success }, + { assert snapshot( + // Number of 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_nascent_software_mqc_versions.yml"), + // All stable path name + stable_name, + // All files with stable contents + stable_path, + // All bam files + // FIXME bam_files.collect{ file -> [ file.getName(), bam(file.toString()).getReadsMD5() ] } + ).match() } + ) + } + } +} diff --git a/workflows/tests/aligner/bowtie2.nf.test.snap b/workflows/tests/aligner/bowtie2.nf.test.snap new file mode 100644 index 00000000..4a26bb95 --- /dev/null +++ b/workflows/tests/aligner/bowtie2.nf.test.snap @@ -0,0 +1,327 @@ +{ + "Should run with defaults": { + "content": [ + 77, + { + "BBMAP_PILEUP": { + "bbmap": 39.01, + "samtools": "1.16.1", + "pigz": 2.6 + }, + "BEDTOOLS_GENOMECOV_MINUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_GENOMECOV_PLUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT_FILTER": { + "bedtools": "2.31.1" + }, + "BOWTIE2_ALIGN": { + "bowtie2": "2.5.2", + "samtools": 1.18, + "pigz": 2.6 + }, + "BOWTIE2_BUILD": { + "bowtie2": "2.5.2" + }, + "CUSTOM_GETCHROMSIZES": { + "getchromsizes": 1.2 + }, + "DEEPTOOLS_BAMCOVERAGE_MINUS": { + "deeptools": "3.5.5" + }, + "DEEPTOOLS_BAMCOVERAGE_PLUS": { + "deeptools": "3.5.5" + }, + "FASTP": { + "fastp": "0.23.4" + }, + "FASTQC": { + "fastqc": "0.12.1" + }, + "GTF2BED": { + "perl": "5.26.2" + }, + "HOMER_MAKETAGDIRECTORY": { + "homer": 4.11, + "samtools": 1.21 + }, + "PRESEQ_CCURVE": { + "preseq": "3.1.1" + }, + "PRESEQ_LCEXTRAP": { + "preseq": "3.1.1" + }, + "RSEQC_INFEREXPERIMENT": { + "rseqc": "5.0.2" + }, + "RSEQC_READDISTRIBUTION": { + "rseqc": "5.0.2" + }, + "RSEQC_READDUPLICATION": { + "rseqc": "5.0.2" + }, + "SAMTOOLS_FLAGSTAT": { + "samtools": 1.21 + }, + "SAMTOOLS_IDXSTATS": { + "samtools": 1.21 + }, + "SAMTOOLS_INDEX": { + "samtools": 1.21 + }, + "SAMTOOLS_MERGE": { + "samtools": 1.21 + }, + "SAMTOOLS_SORT": { + "samtools": 1.21 + }, + "SAMTOOLS_STATS": { + "samtools": 1.21 + }, + "SUBREAD_FEATURECOUNTS_GENE": { + "subread": "2.0.1" + }, + "Workflow": { + "nf-core/nascent": "v2.3.0" + } + }, + [ + "bowtie2", + "bowtie2/cd4_REP1.sorted.bam", + "bowtie2/cd4_REP1.sorted.bam.bai", + "bowtie2/cd4_REP2.sorted.bam", + "bowtie2/cd4_REP2.sorted.bam.bai", + "bowtie2/jurkat.sorted.bam", + "bowtie2/jurkat.sorted.bam.bai", + "bowtie2/log", + "bowtie2/log/cd4_REP1.bowtie2.log", + "bowtie2/log/cd4_REP2.bowtie2.log", + "bowtie2/log/jurkat.bowtie2.log", + "bowtie2/samtools_stats", + "bowtie2/samtools_stats/cd4_REP1.sorted.bam.flagstat", + "bowtie2/samtools_stats/cd4_REP1.sorted.bam.idxstats", + "bowtie2/samtools_stats/cd4_REP1.sorted.bam.stats", + "bowtie2/samtools_stats/cd4_REP2.sorted.bam.flagstat", + "bowtie2/samtools_stats/cd4_REP2.sorted.bam.idxstats", + "bowtie2/samtools_stats/cd4_REP2.sorted.bam.stats", + "bowtie2/samtools_stats/jurkat.sorted.bam.flagstat", + "bowtie2/samtools_stats/jurkat.sorted.bam.idxstats", + "bowtie2/samtools_stats/jurkat.sorted.bam.stats", + "coverage_graphs", + "coverage_graphs/cd4_REP1.dreg.bedGraph", + "coverage_graphs/cd4_REP1.minus.bedGraph", + "coverage_graphs/cd4_REP1.minus.bigWig", + "coverage_graphs/cd4_REP1.plus.bedGraph", + "coverage_graphs/cd4_REP1.plus.bigWig", + "coverage_graphs/cd4_REP2.dreg.bedGraph", + "coverage_graphs/cd4_REP2.minus.bedGraph", + "coverage_graphs/cd4_REP2.minus.bigWig", + "coverage_graphs/cd4_REP2.plus.bedGraph", + "coverage_graphs/cd4_REP2.plus.bigWig", + "coverage_graphs/jurkat.dreg.bedGraph", + "coverage_graphs/jurkat.minus.bedGraph", + "coverage_graphs/jurkat.minus.bigWig", + "coverage_graphs/jurkat.plus.bedGraph", + "coverage_graphs/jurkat.plus.bigWig", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_data/fastqc-status-check-heatmap.txt", + "multiqc/multiqc_data/fastqc_adapter_content_plot.txt", + "multiqc/multiqc_data/fastqc_overrepresented_sequences_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_n_content_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_sequence_quality_plot.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Counts.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Percentages.txt", + "multiqc/multiqc_data/fastqc_per_sequence_quality_scores_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_counts_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_duplication_levels_plot.txt", + "multiqc/multiqc_data/fastqc_top_overrepresented_sequences_table.txt", + "multiqc/multiqc_data/homer-tag-directory-gc-content.txt", + "multiqc/multiqc_data/homer-tag-info-dist.txt", + "multiqc/multiqc_data/homer-tag-length-dist.txt", + "multiqc/multiqc_data/homer_tagdir.txt", + "multiqc/multiqc_data/multiqc.log", + "multiqc/multiqc_data/multiqc_citations.txt", + "multiqc/multiqc_data/multiqc_data.json", + "multiqc/multiqc_data/multiqc_fastqc.txt", + "multiqc/multiqc_data/multiqc_general_stats.txt", + "multiqc/multiqc_data/multiqc_rseqc_infer_experiment.txt", + "multiqc/multiqc_data/multiqc_rseqc_read_distribution.txt", + "multiqc/multiqc_data/multiqc_samtools_flagstat.txt", + "multiqc/multiqc_data/multiqc_samtools_idxstats.txt", + "multiqc/multiqc_data/multiqc_samtools_stats.txt", + "multiqc/multiqc_data/multiqc_software_versions.txt", + "multiqc/multiqc_data/multiqc_sources.txt", + "multiqc/multiqc_data/preseq.txt", + "multiqc/multiqc_data/preseq_complexity_plot_molecules.txt", + "multiqc/multiqc_data/rseqc_infer_experiment_plot.txt", + "multiqc/multiqc_data/rseqc_read_distribution_plot.txt", + "multiqc/multiqc_data/rseqc_read_dups.txt", + "multiqc/multiqc_data/rseqc_read_dups_plot.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Percentage_of_total.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Read_counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Normalised_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Observed_over_Expected_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Raw_Counts.txt", + "multiqc/multiqc_data/samtools-stats-dp.txt", + "multiqc/multiqc_data/samtools_alignment_plot.txt", + "multiqc/multiqc_report.html", + "pipeline_info", + "pipeline_info/nf_core_nascent_software_mqc_versions.yml", + "preprocessing", + "preprocessing/fastp", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.log", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.log", + "preprocessing/fastp/jurkat.trimmed.fastp.html", + "preprocessing/fastp/jurkat.trimmed.fastp.json", + "preprocessing/fastp/jurkat.trimmed.fastp.log", + "preprocessing/fastqc", + "preprocessing/fastqc/cd4_REP1_fastqc.html", + "preprocessing/fastqc/cd4_REP1_fastqc.zip", + "preprocessing/fastqc/cd4_REP2_fastqc.html", + "preprocessing/fastqc/cd4_REP2_fastqc.zip", + "preprocessing/fastqc/jurkat_fastqc.html", + "preprocessing/fastqc/jurkat_fastqc.zip", + "quality_control", + "quality_control/bbsplit", + "quality_control/bbsplit/cd4_REP1.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP1.coverage.stats.txt", + "quality_control/bbsplit/cd4_REP2.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP2.coverage.stats.txt", + "quality_control/bbsplit/jurkat.coverage.hist.txt", + "quality_control/bbsplit/jurkat.coverage.stats.txt", + "quality_control/preseq", + "quality_control/preseq/cd4_REP1.c_curve.txt", + "quality_control/preseq/cd4_REP1.lc_extrap.txt", + "quality_control/preseq/cd4_REP2.c_curve.txt", + "quality_control/preseq/cd4_REP2.lc_extrap.txt", + "quality_control/preseq/jurkat.c_curve.txt", + "quality_control/preseq/jurkat.lc_extrap.txt", + "quality_control/preseq/log", + "quality_control/preseq/log/cd4_REP1.command.log", + "quality_control/preseq/log/cd4_REP2.command.log", + "quality_control/preseq/log/jurkat.command.log", + "quality_control/rseqc", + "quality_control/rseqc/infer_experiment", + "quality_control/rseqc/infer_experiment/cd4_REP1.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/cd4_REP2.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/jurkat.infer_experiment.txt", + "quality_control/rseqc/read_distribution", + "quality_control/rseqc/read_distribution/cd4_REP1.read_distribution.txt", + "quality_control/rseqc/read_distribution/cd4_REP2.read_distribution.txt", + "quality_control/rseqc/read_distribution/jurkat.read_distribution.txt", + "quality_control/rseqc/read_duplication", + "quality_control/rseqc/read_duplication/pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP1.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP2.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/jurkat.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/rscript", + "quality_control/rseqc/read_duplication/rscript/cd4_REP1.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/cd4_REP2.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/jurkat.DupRate_plot.r", + "quality_control/rseqc/read_duplication/xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.seq.DupRate.xls", + "quantification", + "quantification/gene", + "quantification/gene/cd4.featureCounts.txt", + "quantification/gene/cd4.featureCounts.txt.summary", + "quantification/gene/jurkat.featureCounts.txt", + "quantification/gene/jurkat.featureCounts.txt.summary", + "samtools", + "samtools/cd4.bam", + "samtools/jurkat.bam", + "transcript_identification", + "transcript_identification/filtered", + "transcript_identification/filtered/cd4_filtered.bed", + "transcript_identification/filtered/jurkat_filtered.bed", + "transcript_identification/homer", + "transcript_identification/homer/cd4.bed", + "transcript_identification/homer/cd4.bedGraph.gz", + "transcript_identification/homer/cd4.peaks.txt", + "transcript_identification/homer/cd4_tagdir", + "transcript_identification/homer/cd4_tagdir/chr21.tags.tsv", + "transcript_identification/homer/cd4_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/cd4_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/cd4_tagdir/tagFreq.txt", + "transcript_identification/homer/cd4_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/cd4_tagdir/tagGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagInfo.txt", + "transcript_identification/homer/cd4_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/jurkat.bed", + "transcript_identification/homer/jurkat.bedGraph.gz", + "transcript_identification/homer/jurkat.peaks.txt", + "transcript_identification/homer/jurkat_tagdir", + "transcript_identification/homer/jurkat_tagdir/chr21.tags.tsv", + "transcript_identification/homer/jurkat_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/jurkat_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreq.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/jurkat_tagdir/tagGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagInfo.txt", + "transcript_identification/homer/jurkat_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/versions.yml", + "transcript_identification/intersect", + "transcript_identification/intersect/cd4_intersect.bed", + "transcript_identification/intersect/jurkat_intersect.bed" + ], + [ + "cd4_REP1.bowtie2.log:md5,024c3b6bca27f3836cdd86c0287d2971", + "cd4_REP2.bowtie2.log:md5,089af358aad637ec94c10172eb024773", + "jurkat.bowtie2.log:md5,24031e901f4ce11cfb227c7d30d1373a", + "cd4_REP1.sorted.bam.flagstat:md5,14e684e73cb41155ab1168a0a99a97e6", + "cd4_REP1.sorted.bam.idxstats:md5,e32ac3215ba948bb7dd1559dab6c3c36", + "cd4_REP1.sorted.bam.stats:md5,9dcac9f6f5e9afbb3b2880aaf3256603", + "cd4_REP2.sorted.bam.flagstat:md5,e00d036bcbea6f944d45fb5cb7c34516", + "cd4_REP2.sorted.bam.idxstats:md5,0803f2dce4b972ccc14943e22145c3e8", + "cd4_REP2.sorted.bam.stats:md5,c7882ce1e3e7ae5cf9889479f897307d", + "jurkat.sorted.bam.flagstat:md5,1b24ceabc8cecf34d745d06cf9d43cd0", + "jurkat.sorted.bam.idxstats:md5,15e67d4d9d71c6cc6c37d5ce5414ede0", + "jurkat.sorted.bam.stats:md5,396021be96da9e3a14e07849c1e1abc8", + "cd4_REP1.dreg.bedGraph:md5,f48ab66b1ddaf0d1b4867183aedb670a", + "cd4_REP1.minus.bedGraph:md5,6930097f008d44b850d8bb5c681e0d1d", + "cd4_REP1.minus.bigWig:md5,a28d277b360522476ceead81b28adc7f", + "cd4_REP1.plus.bedGraph:md5,c9f9c25c6af4285d7535907e37d62793", + "cd4_REP1.plus.bigWig:md5,fb555dbbb1458d56f167660ebfa0f4f0", + "cd4_REP2.dreg.bedGraph:md5,754cbac7c960a8d3424a11f14f78ff71", + "cd4_REP2.minus.bedGraph:md5,843cdcf18dcd791a7d2030c37eb8d62f", + "cd4_REP2.minus.bigWig:md5,782c83b97ea4794f191a6ac7f9231151", + "cd4_REP2.plus.bedGraph:md5,12892778f9451ed5d3578955f14dda7e", + "cd4_REP2.plus.bigWig:md5,ef622d439b5b90bf6d0232ed2faa9ab6", + "jurkat.dreg.bedGraph:md5,01bab031eee63726446d9260f6ebd3eb", + "jurkat.minus.bedGraph:md5,529ad9cfc3f050366f54a2d99085b94b", + "jurkat.minus.bigWig:md5,f211b5371583f0e373c508ad6ab311ee", + "jurkat.plus.bedGraph:md5,2475bada8a001c763caffa12c5c0e98e", + "jurkat.plus.bigWig:md5,c30a99c3f603b268442f8b6081f6f2c9", + "cd4_REP1.trimmed.fastp.json:md5,bd9a3344c1591d6be4d524451f9dca53", + "cd4_REP2.trimmed.fastp.json:md5,bc6e3f9ff7835f220535cc393b8eb25f", + "jurkat.trimmed.fastp.json:md5,65f7247a87479c7157c7357d575336e2", + "cd4.bed:md5,c311e32ebdca7f3e978a271407de7241", + "cd4.peaks.txt:md5,66589ceaf2aabf1e4e7bad64b94b6fd8", + "jurkat.bed:md5,5e170e72c4e2b27a7bb0a6de7b735c1c", + "jurkat.peaks.txt:md5,100cb761b6b7abad3901775e499a6aa1", + "versions.yml:md5,7c0dcd0a18b3c753def73b96cb825792" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-28T21:38:27.737347" + } +} \ No newline at end of file diff --git a/workflows/tests/aligner/bwa.nf.test b/workflows/tests/aligner/bwa.nf.test new file mode 100644 index 00000000..ed8e201a --- /dev/null +++ b/workflows/tests/aligner/bwa.nf.test @@ -0,0 +1,93 @@ +nextflow_pipeline { + + name "BWA" + script "../../../main.nf" + tag "aligner" + tag "bwa" + + test("Should run with defaults") { + + when { + params { + outdir = "$outputDir" + aligner = "bwa" + input = "${projectDir}/assets/samplesheet.csv" + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}', 'multiqc/multiqc_plots', 'multiqc/multiqc_plots/**']) + // stable_path: All files in ${params.outdir}/ with stable content + def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') + // bam_files: All bam files + def bam_files = getAllFilesFromDir(params.outdir, include: ['**/*.bam']) + assertAll( + { assert workflow.success }, + { assert snapshot( + // Number of 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_nascent_software_mqc_versions.yml"), + // All stable path name + stable_name, + // All files with stable contents + stable_path, + // All bam files + // FIXME bam_files.collect{ file -> [ file.getName(), bam(file.toString()).getHeaderMD5() ] } + ).match() } + ) + } + } + + def igenomes_base = 's3://ngi-igenomes/igenomes' + + // https://github.com/nf-core/nascent/issues/106 + test("Should work with BWA Index") { + // FIXME PINTS Fails because it doesn't find anything. + config '../skip_pints.config' + when { + params { + outdir = "$outputDir" + aligner = "bwa" + // TODO Update these to human + bwa_index = "${igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/BWAIndex/version0.6.0/" + fasta = "${igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/WholeGenomeFasta/genome.fa" + gtf = "${igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.gtf" + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.trace.tasks().size(), + ).match() + } + ) + } + } + + // https://github.com/nf-core/nascent/issues/119 + test("Should work with gzipped references") { + config '../skip_gzip.config' + when { + params { + outdir = "$outputDir" + aligner = "bwa" + fasta = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/reference/genome.fasta.gz' + gtf = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/reference/genes.gtf.gz' + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.trace.tasks().size(), + ).match() + } + ) + } + } +} diff --git a/workflows/tests/aligner/bwa.nf.test.snap b/workflows/tests/aligner/bwa.nf.test.snap new file mode 100644 index 00000000..0035dabc --- /dev/null +++ b/workflows/tests/aligner/bwa.nf.test.snap @@ -0,0 +1,465 @@ +{ + "Should work with gzipped references": { + "content": [ + 55 + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-25T20:54:01.863106" + }, + "Should work with BWA Index": { + "content": [ + 59 + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-18T08:28:08.960886" + }, + "Should run with defaults": { + "content": [ + 149, + { + "BBMAP_PILEUP": { + "bbmap": 39.01, + "samtools": "1.16.1", + "pigz": 2.6 + }, + "BEDTOOLS_GENOMECOV_MINUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_GENOMECOV_PLUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT_FILTER": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_MERGE": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_SORT": { + "bedtools": "2.31.1" + }, + "BWA_INDEX": { + "bwa": "0.7.18-r1243-dirty" + }, + "BWA_MEM": { + "bwa": "0.7.18-r1243-dirty", + "samtools": 1.2 + }, + "CAT_CAT": { + "pigz": "2.3.4" + }, + "CUSTOM_GETCHROMSIZES": { + "getchromsizes": 1.2 + }, + "DEEPTOOLS_BAMCOVERAGE_MINUS": { + "deeptools": "3.5.5" + }, + "DEEPTOOLS_BAMCOVERAGE_PLUS": { + "deeptools": "3.5.5" + }, + "FASTP": { + "fastp": "0.23.4" + }, + "FASTQC": { + "fastqc": "0.12.1" + }, + "GTF2BED": { + "perl": "5.26.2" + }, + "HOMER_MAKETAGDIRECTORY": { + "homer": 4.11, + "samtools": 1.21 + }, + "PINTS_CALLER": { + "python": "3.12.6", + "pints": "1.1.13" + }, + "PRESEQ_CCURVE": { + "preseq": "3.1.1" + }, + "PRESEQ_LCEXTRAP": { + "preseq": "3.1.1" + }, + "RSEQC_INFEREXPERIMENT": { + "rseqc": "5.0.2" + }, + "RSEQC_READDISTRIBUTION": { + "rseqc": "5.0.2" + }, + "RSEQC_READDUPLICATION": { + "rseqc": "5.0.2" + }, + "SAMTOOLS_MERGE": { + "samtools": 1.21 + }, + "SUBREAD_FEATURECOUNTS_GENE": { + "subread": "2.0.1" + }, + "SUBREAD_FEATURECOUNTS_PREDICTED": { + "subread": "2.0.1" + }, + "Workflow": { + "nf-core/nascent": "v2.3.0" + } + }, + [ + "bwa", + "bwa/cd4_REP1.sorted.bam", + "bwa/cd4_REP1.sorted.bam.bai", + "bwa/cd4_REP2.sorted.bam", + "bwa/cd4_REP2.sorted.bam.bai", + "bwa/cd4_REP3.sorted.bam", + "bwa/cd4_REP3.sorted.bam.bai", + "bwa/cd4_REP4.sorted.bam", + "bwa/cd4_REP4.sorted.bam.bai", + "bwa/jurkat_REP1.sorted.bam", + "bwa/jurkat_REP1.sorted.bam.bai", + "bwa/jurkat_REP2.sorted.bam", + "bwa/jurkat_REP2.sorted.bam.bai", + "bwa/samtools_stats", + "bwa/samtools_stats/cd4_REP1.sorted.bam.flagstat", + "bwa/samtools_stats/cd4_REP1.sorted.bam.idxstats", + "bwa/samtools_stats/cd4_REP1.sorted.bam.stats", + "bwa/samtools_stats/cd4_REP2.sorted.bam.flagstat", + "bwa/samtools_stats/cd4_REP2.sorted.bam.idxstats", + "bwa/samtools_stats/cd4_REP2.sorted.bam.stats", + "bwa/samtools_stats/cd4_REP3.sorted.bam.flagstat", + "bwa/samtools_stats/cd4_REP3.sorted.bam.idxstats", + "bwa/samtools_stats/cd4_REP3.sorted.bam.stats", + "bwa/samtools_stats/cd4_REP4.sorted.bam.flagstat", + "bwa/samtools_stats/cd4_REP4.sorted.bam.idxstats", + "bwa/samtools_stats/cd4_REP4.sorted.bam.stats", + "bwa/samtools_stats/jurkat_REP1.sorted.bam.flagstat", + "bwa/samtools_stats/jurkat_REP1.sorted.bam.idxstats", + "bwa/samtools_stats/jurkat_REP1.sorted.bam.stats", + "bwa/samtools_stats/jurkat_REP2.sorted.bam.flagstat", + "bwa/samtools_stats/jurkat_REP2.sorted.bam.idxstats", + "bwa/samtools_stats/jurkat_REP2.sorted.bam.stats", + "cat", + "cat/cd4.bed", + "cat/jurkat.bed", + "coverage_graphs", + "coverage_graphs/cd4_REP1.dreg.bedGraph", + "coverage_graphs/cd4_REP1.minus.bedGraph", + "coverage_graphs/cd4_REP1.minus.bigWig", + "coverage_graphs/cd4_REP1.plus.bedGraph", + "coverage_graphs/cd4_REP1.plus.bigWig", + "coverage_graphs/cd4_REP2.dreg.bedGraph", + "coverage_graphs/cd4_REP2.minus.bedGraph", + "coverage_graphs/cd4_REP2.minus.bigWig", + "coverage_graphs/cd4_REP2.plus.bedGraph", + "coverage_graphs/cd4_REP2.plus.bigWig", + "coverage_graphs/cd4_REP3.dreg.bedGraph", + "coverage_graphs/cd4_REP3.minus.bedGraph", + "coverage_graphs/cd4_REP3.minus.bigWig", + "coverage_graphs/cd4_REP3.plus.bedGraph", + "coverage_graphs/cd4_REP3.plus.bigWig", + "coverage_graphs/cd4_REP4.dreg.bedGraph", + "coverage_graphs/cd4_REP4.minus.bedGraph", + "coverage_graphs/cd4_REP4.minus.bigWig", + "coverage_graphs/cd4_REP4.plus.bedGraph", + "coverage_graphs/cd4_REP4.plus.bigWig", + "coverage_graphs/jurkat_REP1.dreg.bedGraph", + "coverage_graphs/jurkat_REP1.minus.bedGraph", + "coverage_graphs/jurkat_REP1.minus.bigWig", + "coverage_graphs/jurkat_REP1.plus.bedGraph", + "coverage_graphs/jurkat_REP1.plus.bigWig", + "coverage_graphs/jurkat_REP2.dreg.bedGraph", + "coverage_graphs/jurkat_REP2.minus.bedGraph", + "coverage_graphs/jurkat_REP2.minus.bigWig", + "coverage_graphs/jurkat_REP2.plus.bedGraph", + "coverage_graphs/jurkat_REP2.plus.bigWig", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_data/fastqc-status-check-heatmap.txt", + "multiqc/multiqc_data/fastqc_adapter_content_plot.txt", + "multiqc/multiqc_data/fastqc_overrepresented_sequences_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_n_content_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_sequence_quality_plot.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Counts.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Percentages.txt", + "multiqc/multiqc_data/fastqc_per_sequence_quality_scores_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_counts_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_duplication_levels_plot.txt", + "multiqc/multiqc_data/fastqc_top_overrepresented_sequences_table.txt", + "multiqc/multiqc_data/homer-tag-directory-gc-content.txt", + "multiqc/multiqc_data/homer-tag-info-dist.txt", + "multiqc/multiqc_data/homer-tag-length-dist.txt", + "multiqc/multiqc_data/homer_tagdir.txt", + "multiqc/multiqc_data/multiqc.log", + "multiqc/multiqc_data/multiqc_citations.txt", + "multiqc/multiqc_data/multiqc_data.json", + "multiqc/multiqc_data/multiqc_fastqc.txt", + "multiqc/multiqc_data/multiqc_general_stats.txt", + "multiqc/multiqc_data/multiqc_rseqc_infer_experiment.txt", + "multiqc/multiqc_data/multiqc_rseqc_read_distribution.txt", + "multiqc/multiqc_data/multiqc_samtools_flagstat.txt", + "multiqc/multiqc_data/multiqc_samtools_idxstats.txt", + "multiqc/multiqc_data/multiqc_samtools_stats.txt", + "multiqc/multiqc_data/multiqc_software_versions.txt", + "multiqc/multiqc_data/multiqc_sources.txt", + "multiqc/multiqc_data/preseq.txt", + "multiqc/multiqc_data/preseq_complexity_plot_molecules.txt", + "multiqc/multiqc_data/rseqc_infer_experiment_plot.txt", + "multiqc/multiqc_data/rseqc_read_distribution_plot.txt", + "multiqc/multiqc_data/rseqc_read_dups.txt", + "multiqc/multiqc_data/rseqc_read_dups_plot.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Percentage_of_total.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Read_counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Normalised_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Observed_over_Expected_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Raw_Counts.txt", + "multiqc/multiqc_data/samtools-stats-dp.txt", + "multiqc/multiqc_data/samtools_alignment_plot.txt", + "multiqc/multiqc_report.html", + "pipeline_info", + "pipeline_info/nf_core_nascent_software_mqc_versions.yml", + "preprocessing", + "preprocessing/fastp", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.log", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.log", + "preprocessing/fastp/cd4_REP3.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP3.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP3.trimmed.fastp.log", + "preprocessing/fastp/cd4_REP4.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP4.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP4.trimmed.fastp.log", + "preprocessing/fastp/jurkat_REP1.trimmed.fastp.html", + "preprocessing/fastp/jurkat_REP1.trimmed.fastp.json", + "preprocessing/fastp/jurkat_REP1.trimmed.fastp.log", + "preprocessing/fastp/jurkat_REP2.trimmed.fastp.html", + "preprocessing/fastp/jurkat_REP2.trimmed.fastp.json", + "preprocessing/fastp/jurkat_REP2.trimmed.fastp.log", + "preprocessing/fastqc", + "preprocessing/fastqc/cd4_REP1_fastqc.html", + "preprocessing/fastqc/cd4_REP1_fastqc.zip", + "preprocessing/fastqc/cd4_REP2_fastqc.html", + "preprocessing/fastqc/cd4_REP2_fastqc.zip", + "preprocessing/fastqc/cd4_REP3_fastqc.html", + "preprocessing/fastqc/cd4_REP3_fastqc.zip", + "preprocessing/fastqc/cd4_REP4_fastqc.html", + "preprocessing/fastqc/cd4_REP4_fastqc.zip", + "preprocessing/fastqc/jurkat_REP1_fastqc.html", + "preprocessing/fastqc/jurkat_REP1_fastqc.zip", + "preprocessing/fastqc/jurkat_REP2_fastqc.html", + "preprocessing/fastqc/jurkat_REP2_fastqc.zip", + "quality_control", + "quality_control/bbsplit", + "quality_control/bbsplit/cd4_REP1.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP1.coverage.stats.txt", + "quality_control/bbsplit/cd4_REP2.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP2.coverage.stats.txt", + "quality_control/bbsplit/cd4_REP3.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP3.coverage.stats.txt", + "quality_control/bbsplit/cd4_REP4.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP4.coverage.stats.txt", + "quality_control/bbsplit/jurkat_REP1.coverage.hist.txt", + "quality_control/bbsplit/jurkat_REP1.coverage.stats.txt", + "quality_control/bbsplit/jurkat_REP2.coverage.hist.txt", + "quality_control/bbsplit/jurkat_REP2.coverage.stats.txt", + "quality_control/preseq", + "quality_control/preseq/cd4_REP1.c_curve.txt", + "quality_control/preseq/cd4_REP1.lc_extrap.txt", + "quality_control/preseq/cd4_REP2.c_curve.txt", + "quality_control/preseq/cd4_REP2.lc_extrap.txt", + "quality_control/preseq/cd4_REP3.c_curve.txt", + "quality_control/preseq/cd4_REP3.lc_extrap.txt", + "quality_control/preseq/cd4_REP4.c_curve.txt", + "quality_control/preseq/cd4_REP4.lc_extrap.txt", + "quality_control/preseq/jurkat_REP1.c_curve.txt", + "quality_control/preseq/jurkat_REP1.lc_extrap.txt", + "quality_control/preseq/jurkat_REP2.c_curve.txt", + "quality_control/preseq/jurkat_REP2.lc_extrap.txt", + "quality_control/preseq/log", + "quality_control/preseq/log/cd4_REP1.command.log", + "quality_control/preseq/log/cd4_REP2.command.log", + "quality_control/preseq/log/cd4_REP3.command.log", + "quality_control/preseq/log/cd4_REP4.command.log", + "quality_control/preseq/log/jurkat_REP1.command.log", + "quality_control/preseq/log/jurkat_REP2.command.log", + "quality_control/rseqc", + "quality_control/rseqc/infer_experiment", + "quality_control/rseqc/infer_experiment/cd4_REP1.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/cd4_REP2.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/cd4_REP3.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/cd4_REP4.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/jurkat_REP1.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/jurkat_REP2.infer_experiment.txt", + "quality_control/rseqc/read_distribution", + "quality_control/rseqc/read_distribution/cd4_REP1.read_distribution.txt", + "quality_control/rseqc/read_distribution/cd4_REP2.read_distribution.txt", + "quality_control/rseqc/read_distribution/cd4_REP3.read_distribution.txt", + "quality_control/rseqc/read_distribution/cd4_REP4.read_distribution.txt", + "quality_control/rseqc/read_distribution/jurkat_REP1.read_distribution.txt", + "quality_control/rseqc/read_distribution/jurkat_REP2.read_distribution.txt", + "quality_control/rseqc/read_duplication", + "quality_control/rseqc/read_duplication/pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP1.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP2.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP3.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP4.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/jurkat_REP1.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/jurkat_REP2.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/rscript", + "quality_control/rseqc/read_duplication/rscript/cd4_REP1.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/cd4_REP2.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/cd4_REP3.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/cd4_REP4.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/jurkat_REP1.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/jurkat_REP2.DupRate_plot.r", + "quality_control/rseqc/read_duplication/xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP3.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP3.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP4.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP4.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat_REP1.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat_REP1.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat_REP2.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat_REP2.seq.DupRate.xls", + "quantification", + "quantification/gene", + "quantification/gene/cd4.featureCounts.txt", + "quantification/gene/cd4.featureCounts.txt.summary", + "quantification/gene/jurkat.featureCounts.txt", + "quantification/gene/jurkat.featureCounts.txt.summary", + "quantification/nascent", + "quantification/nascent/cd4-group_cd4_intersect-transcripts.featureCounts.txt", + "quantification/nascent/cd4-group_cd4_intersect-transcripts.featureCounts.txt.summary", + "quantification/nascent/jurkat-group_cd4_intersect-transcripts.featureCounts.txt", + "quantification/nascent/jurkat-group_cd4_intersect-transcripts.featureCounts.txt.summary", + "samtools", + "samtools/cd4.bam", + "samtools/jurkat.bam", + "transcript_identification", + "transcript_identification/filtered", + "transcript_identification/filtered/cd4_filtered.bed", + "transcript_identification/filtered/jurkat_filtered.bed", + "transcript_identification/homer", + "transcript_identification/homer/cd4.bed", + "transcript_identification/homer/cd4.bedGraph.gz", + "transcript_identification/homer/cd4.peaks.txt", + "transcript_identification/homer/cd4_tagdir", + "transcript_identification/homer/cd4_tagdir/chr21.tags.tsv", + "transcript_identification/homer/cd4_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/cd4_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/cd4_tagdir/tagFreq.txt", + "transcript_identification/homer/cd4_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/cd4_tagdir/tagGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagInfo.txt", + "transcript_identification/homer/cd4_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/jurkat.bed", + "transcript_identification/homer/jurkat.bedGraph.gz", + "transcript_identification/homer/jurkat.peaks.txt", + "transcript_identification/homer/jurkat_tagdir", + "transcript_identification/homer/jurkat_tagdir/chr21.tags.tsv", + "transcript_identification/homer/jurkat_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/jurkat_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreq.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/jurkat_tagdir/tagGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagInfo.txt", + "transcript_identification/homer/jurkat_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/versions.yml", + "transcript_identification/intersect", + "transcript_identification/intersect/cd4_intersect.bed", + "transcript_identification/intersect/jurkat_intersect.bed", + "transcript_identification/merged", + "transcript_identification/merged/cd4_merged.bed", + "transcript_identification/merged/jurkat_merged.bed", + "transcript_identification/pints", + "transcript_identification/pints/cd4_chr21_1_unidirectional_peaks.bed", + "transcript_identification/pints/jurkat_chr21_1_unidirectional_peaks.bed" + ], + [ + "cd4_REP1.sorted.bam.flagstat:md5,863e2d506d5cc4239af98a5f31bbc906", + "cd4_REP1.sorted.bam.idxstats:md5,b1dd8bcbd23c53c21f0e11082d9315f2", + "cd4_REP1.sorted.bam.stats:md5,70b7cd3040a9b7ca70e919afb4dc7fea", + "cd4_REP2.sorted.bam.flagstat:md5,0fd86dbf8f799fad49ba471702979bdc", + "cd4_REP2.sorted.bam.idxstats:md5,53204e4c6a9f68664087e4a8123be46a", + "cd4_REP2.sorted.bam.stats:md5,c0e8d8d265fce71dcd43e43c93d29ef3", + "cd4_REP3.sorted.bam.flagstat:md5,793c9cadbf80e35dbae3774e9b5bd93f", + "cd4_REP3.sorted.bam.idxstats:md5,42de227ff397013cf288759871b0e938", + "cd4_REP3.sorted.bam.stats:md5,b262fbc5a0cb83b5be1cbb71e921e4da", + "cd4_REP4.sorted.bam.flagstat:md5,ed6c609505097f3cc9d9902d69e016f8", + "cd4_REP4.sorted.bam.idxstats:md5,959dc185ae59de4cebe374026711a55e", + "cd4_REP4.sorted.bam.stats:md5,e912817bed2ca2321455010e5a95df94", + "jurkat_REP1.sorted.bam.flagstat:md5,fd5f02b0f02a407447b804b1d80f5421", + "jurkat_REP1.sorted.bam.idxstats:md5,c61af0847c1ad76c06a8de2815975b32", + "jurkat_REP1.sorted.bam.stats:md5,da19804248dcde941b4a1eb860583830", + "jurkat_REP2.sorted.bam.flagstat:md5,86ed47bd41a745ab59de473082c7742d", + "jurkat_REP2.sorted.bam.idxstats:md5,3db8f88c1f836eb5d10f37ca1df81ae9", + "jurkat_REP2.sorted.bam.stats:md5,141032fd40420e3aa80d37c7bf7ed2b1", + "cd4.bed:md5,76ee3b56d3e518f88a34b42039ec719c", + "jurkat.bed:md5,862a5e81119acc691845f3b426847401", + "cd4_REP1.dreg.bedGraph:md5,8948a8fa86d8f6d413b77983189ff56e", + "cd4_REP1.minus.bedGraph:md5,2a1c34f9d9ef9ff1b9da7874b9e3aaad", + "cd4_REP1.minus.bigWig:md5,5280319275c98dcce023779fa389884d", + "cd4_REP1.plus.bedGraph:md5,1509ec3a921e3109c5914e1bcef8cf33", + "cd4_REP1.plus.bigWig:md5,72ccab3173f2018a22a4b36841247ba2", + "cd4_REP2.dreg.bedGraph:md5,29f865a5668fae4a52a41589ac2b3179", + "cd4_REP2.minus.bedGraph:md5,c530bc34fa3ec7ac49e88ff65f9c2f92", + "cd4_REP2.minus.bigWig:md5,5e748c794e037f441741f7f409c8c5ad", + "cd4_REP2.plus.bedGraph:md5,a675141da2874ec08d91591e5ea8242b", + "cd4_REP2.plus.bigWig:md5,08674d52e9eeb08807c33ed3e4b3d504", + "cd4_REP3.dreg.bedGraph:md5,201e690c619ee231416b643740141588", + "cd4_REP3.minus.bedGraph:md5,1c44c165f663d08c869a013b78f051b0", + "cd4_REP3.minus.bigWig:md5,aa3f5e86c635e182f9173543751cfbfd", + "cd4_REP3.plus.bedGraph:md5,a475098ed14da6f3242c4cfdf3abb713", + "cd4_REP3.plus.bigWig:md5,b255ae7c47424c223c537d00ecc025b5", + "cd4_REP4.dreg.bedGraph:md5,dfcfce7df666c0e24a3d0d4e21447a0b", + "cd4_REP4.minus.bedGraph:md5,b7a3d3c822155dfd8052c67a330fd6d5", + "cd4_REP4.minus.bigWig:md5,fc61c62613dc0f74a65c32419aba8f76", + "cd4_REP4.plus.bedGraph:md5,5623367b681562a2567afc62a8da4151", + "cd4_REP4.plus.bigWig:md5,ed00ad7a22c49860debc86cfa7ffb457", + "jurkat_REP1.dreg.bedGraph:md5,c25a4fb095e9f7d6766a3ce33e08f7d8", + "jurkat_REP1.minus.bedGraph:md5,8d5d9a41df6eb6c56b1bfd3f39dc1fc6", + "jurkat_REP1.minus.bigWig:md5,d06c8015c996bf520fff17266fd01f84", + "jurkat_REP1.plus.bedGraph:md5,6ed63e5983edaa74fb3965676efdb674", + "jurkat_REP1.plus.bigWig:md5,7a02334f2c7300ffdb5a2253c0937390", + "jurkat_REP2.dreg.bedGraph:md5,aad861b6fd8d296fe6bb4bc82d5eeeed", + "jurkat_REP2.minus.bedGraph:md5,cd83486cb6bb71e6b6e31a69c94d0d85", + "jurkat_REP2.minus.bigWig:md5,686f719978de948f7045acc95f9d1c82", + "jurkat_REP2.plus.bedGraph:md5,569e8a25c9cf48d1ef953f3da77c48a1", + "jurkat_REP2.plus.bigWig:md5,cbe3fd38fe8f9508645bbfad83924212", + "cd4_REP1.trimmed.fastp.json:md5,bd9a3344c1591d6be4d524451f9dca53", + "cd4_REP2.trimmed.fastp.json:md5,bc6e3f9ff7835f220535cc393b8eb25f", + "cd4_REP3.trimmed.fastp.json:md5,c9c3a1dd0a2ebac77c9d7c3b0daf3790", + "cd4_REP4.trimmed.fastp.json:md5,c073bd26609ddca91396d0f374ec5b80", + "jurkat_REP1.trimmed.fastp.json:md5,329fd8e56421a196fc2ebd37ab3bc22d", + "jurkat_REP2.trimmed.fastp.json:md5,8bad5b02a27e5386255b998a6a69db15", + "cd4.bed:md5,ab94918610a560772fdbec591200295f", + "cd4.peaks.txt:md5,6edefe0a75b76240d3b49d12e49cb600", + "jurkat.bed:md5,41908723fa423a78476feb2e7627a3a4", + "jurkat.peaks.txt:md5,1247c21dbc92f8114dbcb2320fa09a3a", + "versions.yml:md5,7c0dcd0a18b3c753def73b96cb825792", + "cd4_merged.bed:md5,4d8f9dc54f886f379b95609908a08662", + "jurkat_merged.bed:md5,cae11a1bfb707ea2df5fe612ae7268c8", + "cd4_chr21_1_unidirectional_peaks.bed:md5,76ee3b56d3e518f88a34b42039ec719c", + "jurkat_chr21_1_unidirectional_peaks.bed:md5,862a5e81119acc691845f3b426847401" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-28T21:40:27.445964" + } +} \ No newline at end of file diff --git a/workflows/tests/aligner/bwamem2.nf.test b/workflows/tests/aligner/bwamem2.nf.test new file mode 100644 index 00000000..2bebf8ff --- /dev/null +++ b/workflows/tests/aligner/bwamem2.nf.test @@ -0,0 +1,39 @@ +nextflow_pipeline { + + name "bwamem2" + script "../../../main.nf" + + test("Should run with defaults") { + + when { + params { + outdir = "$outputDir" + aligner = "bwamem2" + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}', 'multiqc/multiqc_plots', 'multiqc/multiqc_plots/**']) + // stable_path: All files in ${params.outdir}/ with stable content + def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') + // bam_files: All bam files + def bam_files = getAllFilesFromDir(params.outdir, include: ['**/*.bam']) + assertAll( + { assert workflow.success }, + { assert snapshot( + // Number of 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_nascent_software_mqc_versions.yml"), + // All stable path name + stable_name, + // All files with stable contents + stable_path, + // All bam files + // FIXME bam_files.collect{ file -> [ file.getName(), bam(file.toString()).getReadsMD5() ] } + ).match() } + ) + } + } +} diff --git a/workflows/tests/aligner/bwamem2.nf.test.snap b/workflows/tests/aligner/bwamem2.nf.test.snap new file mode 100644 index 00000000..6db4b3d8 --- /dev/null +++ b/workflows/tests/aligner/bwamem2.nf.test.snap @@ -0,0 +1,355 @@ +{ + "Should run with defaults": { + "content": [ + 92, + { + "BBMAP_PILEUP": { + "bbmap": 39.01, + "samtools": "1.16.1", + "pigz": 2.6 + }, + "BEDTOOLS_GENOMECOV_MINUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_GENOMECOV_PLUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT_FILTER": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_MERGE": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_SORT": { + "bedtools": "2.31.1" + }, + "BWAMEM2_INDEX": { + "bwamem2": "2.2.1" + }, + "BWAMEM2_MEM": { + "bwamem2": "2.2.1", + "samtools": "1.19.2" + }, + "CAT_CAT": { + "pigz": "2.3.4" + }, + "CUSTOM_GETCHROMSIZES": { + "getchromsizes": 1.2 + }, + "DEEPTOOLS_BAMCOVERAGE_MINUS": { + "deeptools": "3.5.5" + }, + "DEEPTOOLS_BAMCOVERAGE_PLUS": { + "deeptools": "3.5.5" + }, + "FASTP": { + "fastp": "0.23.4" + }, + "FASTQC": { + "fastqc": "0.12.1" + }, + "GTF2BED": { + "perl": "5.26.2" + }, + "HOMER_MAKETAGDIRECTORY": { + "homer": 4.11, + "samtools": 1.21 + }, + "PINTS_CALLER": { + "python": "3.12.6", + "pints": "1.1.13" + }, + "PRESEQ_CCURVE": { + "preseq": "3.1.1" + }, + "PRESEQ_LCEXTRAP": { + "preseq": "3.1.1" + }, + "RSEQC_INFEREXPERIMENT": { + "rseqc": "5.0.2" + }, + "RSEQC_READDISTRIBUTION": { + "rseqc": "5.0.2" + }, + "RSEQC_READDUPLICATION": { + "rseqc": "5.0.2" + }, + "SAMTOOLS_FLAGSTAT": { + "samtools": 1.21 + }, + "SAMTOOLS_IDXSTATS": { + "samtools": 1.21 + }, + "SAMTOOLS_INDEX": { + "samtools": 1.21 + }, + "SAMTOOLS_MERGE": { + "samtools": 1.21 + }, + "SAMTOOLS_SORT": { + "samtools": 1.21 + }, + "SAMTOOLS_STATS": { + "samtools": 1.21 + }, + "SUBREAD_FEATURECOUNTS_GENE": { + "subread": "2.0.1" + }, + "SUBREAD_FEATURECOUNTS_PREDICTED": { + "subread": "2.0.1" + }, + "Workflow": { + "nf-core/nascent": "v2.3.0" + } + }, + [ + "bwamem2", + "bwamem2/cd4_REP1.sorted.bam", + "bwamem2/cd4_REP1.sorted.bam.bai", + "bwamem2/cd4_REP2.sorted.bam", + "bwamem2/cd4_REP2.sorted.bam.bai", + "bwamem2/jurkat.sorted.bam", + "bwamem2/jurkat.sorted.bam.bai", + "bwamem2/samtools_stats", + "bwamem2/samtools_stats/cd4_REP1.sorted.bam.flagstat", + "bwamem2/samtools_stats/cd4_REP1.sorted.bam.idxstats", + "bwamem2/samtools_stats/cd4_REP1.sorted.bam.stats", + "bwamem2/samtools_stats/cd4_REP2.sorted.bam.flagstat", + "bwamem2/samtools_stats/cd4_REP2.sorted.bam.idxstats", + "bwamem2/samtools_stats/cd4_REP2.sorted.bam.stats", + "bwamem2/samtools_stats/jurkat.sorted.bam.flagstat", + "bwamem2/samtools_stats/jurkat.sorted.bam.idxstats", + "bwamem2/samtools_stats/jurkat.sorted.bam.stats", + "cat", + "cat/cd4.bed", + "cat/jurkat.bed", + "coverage_graphs", + "coverage_graphs/cd4_REP1.dreg.bedGraph", + "coverage_graphs/cd4_REP1.minus.bedGraph", + "coverage_graphs/cd4_REP1.minus.bigWig", + "coverage_graphs/cd4_REP1.plus.bedGraph", + "coverage_graphs/cd4_REP1.plus.bigWig", + "coverage_graphs/cd4_REP2.dreg.bedGraph", + "coverage_graphs/cd4_REP2.minus.bedGraph", + "coverage_graphs/cd4_REP2.minus.bigWig", + "coverage_graphs/cd4_REP2.plus.bedGraph", + "coverage_graphs/cd4_REP2.plus.bigWig", + "coverage_graphs/jurkat.dreg.bedGraph", + "coverage_graphs/jurkat.minus.bedGraph", + "coverage_graphs/jurkat.minus.bigWig", + "coverage_graphs/jurkat.plus.bedGraph", + "coverage_graphs/jurkat.plus.bigWig", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_data/fastqc-status-check-heatmap.txt", + "multiqc/multiqc_data/fastqc_adapter_content_plot.txt", + "multiqc/multiqc_data/fastqc_overrepresented_sequences_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_n_content_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_sequence_quality_plot.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Counts.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Percentages.txt", + "multiqc/multiqc_data/fastqc_per_sequence_quality_scores_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_counts_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_duplication_levels_plot.txt", + "multiqc/multiqc_data/fastqc_top_overrepresented_sequences_table.txt", + "multiqc/multiqc_data/homer-tag-directory-gc-content.txt", + "multiqc/multiqc_data/homer-tag-info-dist.txt", + "multiqc/multiqc_data/homer-tag-length-dist.txt", + "multiqc/multiqc_data/homer_tagdir.txt", + "multiqc/multiqc_data/multiqc.log", + "multiqc/multiqc_data/multiqc_citations.txt", + "multiqc/multiqc_data/multiqc_data.json", + "multiqc/multiqc_data/multiqc_fastqc.txt", + "multiqc/multiqc_data/multiqc_general_stats.txt", + "multiqc/multiqc_data/multiqc_rseqc_infer_experiment.txt", + "multiqc/multiqc_data/multiqc_rseqc_read_distribution.txt", + "multiqc/multiqc_data/multiqc_samtools_flagstat.txt", + "multiqc/multiqc_data/multiqc_samtools_idxstats.txt", + "multiqc/multiqc_data/multiqc_samtools_stats.txt", + "multiqc/multiqc_data/multiqc_software_versions.txt", + "multiqc/multiqc_data/multiqc_sources.txt", + "multiqc/multiqc_data/preseq.txt", + "multiqc/multiqc_data/preseq_complexity_plot_molecules.txt", + "multiqc/multiqc_data/rseqc_infer_experiment_plot.txt", + "multiqc/multiqc_data/rseqc_read_distribution_plot.txt", + "multiqc/multiqc_data/rseqc_read_dups.txt", + "multiqc/multiqc_data/rseqc_read_dups_plot.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Percentage_of_total.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Read_counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Normalised_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Observed_over_Expected_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Raw_Counts.txt", + "multiqc/multiqc_data/samtools-stats-dp.txt", + "multiqc/multiqc_data/samtools_alignment_plot.txt", + "multiqc/multiqc_report.html", + "pipeline_info", + "pipeline_info/nf_core_nascent_software_mqc_versions.yml", + "preprocessing", + "preprocessing/fastp", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.log", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.log", + "preprocessing/fastp/jurkat.trimmed.fastp.html", + "preprocessing/fastp/jurkat.trimmed.fastp.json", + "preprocessing/fastp/jurkat.trimmed.fastp.log", + "preprocessing/fastqc", + "preprocessing/fastqc/cd4_REP1_fastqc.html", + "preprocessing/fastqc/cd4_REP1_fastqc.zip", + "preprocessing/fastqc/cd4_REP2_fastqc.html", + "preprocessing/fastqc/cd4_REP2_fastqc.zip", + "preprocessing/fastqc/jurkat_fastqc.html", + "preprocessing/fastqc/jurkat_fastqc.zip", + "quality_control", + "quality_control/bbsplit", + "quality_control/bbsplit/cd4_REP1.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP1.coverage.stats.txt", + "quality_control/bbsplit/cd4_REP2.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP2.coverage.stats.txt", + "quality_control/bbsplit/jurkat.coverage.hist.txt", + "quality_control/bbsplit/jurkat.coverage.stats.txt", + "quality_control/preseq", + "quality_control/preseq/cd4_REP1.c_curve.txt", + "quality_control/preseq/cd4_REP1.lc_extrap.txt", + "quality_control/preseq/cd4_REP2.c_curve.txt", + "quality_control/preseq/cd4_REP2.lc_extrap.txt", + "quality_control/preseq/jurkat.c_curve.txt", + "quality_control/preseq/jurkat.lc_extrap.txt", + "quality_control/preseq/log", + "quality_control/preseq/log/cd4_REP1.command.log", + "quality_control/preseq/log/cd4_REP2.command.log", + "quality_control/preseq/log/jurkat.command.log", + "quality_control/rseqc", + "quality_control/rseqc/infer_experiment", + "quality_control/rseqc/infer_experiment/cd4_REP1.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/cd4_REP2.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/jurkat.infer_experiment.txt", + "quality_control/rseqc/read_distribution", + "quality_control/rseqc/read_distribution/cd4_REP1.read_distribution.txt", + "quality_control/rseqc/read_distribution/cd4_REP2.read_distribution.txt", + "quality_control/rseqc/read_distribution/jurkat.read_distribution.txt", + "quality_control/rseqc/read_duplication", + "quality_control/rseqc/read_duplication/pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP1.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP2.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/jurkat.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/rscript", + "quality_control/rseqc/read_duplication/rscript/cd4_REP1.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/cd4_REP2.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/jurkat.DupRate_plot.r", + "quality_control/rseqc/read_duplication/xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.seq.DupRate.xls", + "quantification", + "quantification/gene", + "quantification/gene/cd4.featureCounts.txt", + "quantification/gene/cd4.featureCounts.txt.summary", + "quantification/gene/jurkat.featureCounts.txt", + "quantification/gene/jurkat.featureCounts.txt.summary", + "quantification/nascent", + "quantification/nascent/cd4-group_cd4_intersect-transcripts.featureCounts.txt", + "quantification/nascent/cd4-group_cd4_intersect-transcripts.featureCounts.txt.summary", + "quantification/nascent/jurkat-group_cd4_intersect-transcripts.featureCounts.txt", + "quantification/nascent/jurkat-group_cd4_intersect-transcripts.featureCounts.txt.summary", + "samtools", + "samtools/cd4.bam", + "samtools/jurkat.bam", + "transcript_identification", + "transcript_identification/filtered", + "transcript_identification/filtered/cd4_filtered.bed", + "transcript_identification/filtered/jurkat_filtered.bed", + "transcript_identification/homer", + "transcript_identification/homer/cd4.bed", + "transcript_identification/homer/cd4.bedGraph.gz", + "transcript_identification/homer/cd4.peaks.txt", + "transcript_identification/homer/cd4_tagdir", + "transcript_identification/homer/cd4_tagdir/chr21.tags.tsv", + "transcript_identification/homer/cd4_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/cd4_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/cd4_tagdir/tagFreq.txt", + "transcript_identification/homer/cd4_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/cd4_tagdir/tagGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagInfo.txt", + "transcript_identification/homer/cd4_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/jurkat.bed", + "transcript_identification/homer/jurkat.bedGraph.gz", + "transcript_identification/homer/jurkat.peaks.txt", + "transcript_identification/homer/jurkat_tagdir", + "transcript_identification/homer/jurkat_tagdir/chr21.tags.tsv", + "transcript_identification/homer/jurkat_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/jurkat_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreq.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/jurkat_tagdir/tagGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagInfo.txt", + "transcript_identification/homer/jurkat_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/versions.yml", + "transcript_identification/intersect", + "transcript_identification/intersect/cd4_intersect.bed", + "transcript_identification/intersect/jurkat_intersect.bed", + "transcript_identification/merged", + "transcript_identification/merged/cd4_merged.bed", + "transcript_identification/merged/jurkat_merged.bed", + "transcript_identification/pints", + "transcript_identification/pints/cd4_chr21_1_unidirectional_peaks.bed", + "transcript_identification/pints/jurkat_chr21_1_unidirectional_peaks.bed" + ], + [ + "cd4_REP1.sorted.bam.flagstat:md5,863e2d506d5cc4239af98a5f31bbc906", + "cd4_REP1.sorted.bam.idxstats:md5,b1dd8bcbd23c53c21f0e11082d9315f2", + "cd4_REP1.sorted.bam.stats:md5,70b7cd3040a9b7ca70e919afb4dc7fea", + "cd4_REP2.sorted.bam.flagstat:md5,0fd86dbf8f799fad49ba471702979bdc", + "cd4_REP2.sorted.bam.idxstats:md5,53204e4c6a9f68664087e4a8123be46a", + "cd4_REP2.sorted.bam.stats:md5,c0e8d8d265fce71dcd43e43c93d29ef3", + "jurkat.sorted.bam.flagstat:md5,fd5f02b0f02a407447b804b1d80f5421", + "jurkat.sorted.bam.idxstats:md5,c61af0847c1ad76c06a8de2815975b32", + "jurkat.sorted.bam.stats:md5,c9a6ec83d8fb1a14f53351c76cfcd24b", + "cd4.bed:md5,0193e58943726af89bfd00e9da2536d8", + "jurkat.bed:md5,cb6932229eea2e09f61d48d7dd397ae1", + "cd4_REP1.dreg.bedGraph:md5,8948a8fa86d8f6d413b77983189ff56e", + "cd4_REP1.minus.bedGraph:md5,2a1c34f9d9ef9ff1b9da7874b9e3aaad", + "cd4_REP1.minus.bigWig:md5,5280319275c98dcce023779fa389884d", + "cd4_REP1.plus.bedGraph:md5,1509ec3a921e3109c5914e1bcef8cf33", + "cd4_REP1.plus.bigWig:md5,72ccab3173f2018a22a4b36841247ba2", + "cd4_REP2.dreg.bedGraph:md5,29f865a5668fae4a52a41589ac2b3179", + "cd4_REP2.minus.bedGraph:md5,c530bc34fa3ec7ac49e88ff65f9c2f92", + "cd4_REP2.minus.bigWig:md5,5e748c794e037f441741f7f409c8c5ad", + "cd4_REP2.plus.bedGraph:md5,a675141da2874ec08d91591e5ea8242b", + "cd4_REP2.plus.bigWig:md5,08674d52e9eeb08807c33ed3e4b3d504", + "jurkat.dreg.bedGraph:md5,c25a4fb095e9f7d6766a3ce33e08f7d8", + "jurkat.minus.bedGraph:md5,8d5d9a41df6eb6c56b1bfd3f39dc1fc6", + "jurkat.minus.bigWig:md5,d06c8015c996bf520fff17266fd01f84", + "jurkat.plus.bedGraph:md5,6ed63e5983edaa74fb3965676efdb674", + "jurkat.plus.bigWig:md5,7a02334f2c7300ffdb5a2253c0937390", + "cd4_REP1.trimmed.fastp.json:md5,bd9a3344c1591d6be4d524451f9dca53", + "cd4_REP2.trimmed.fastp.json:md5,bc6e3f9ff7835f220535cc393b8eb25f", + "jurkat.trimmed.fastp.json:md5,65f7247a87479c7157c7357d575336e2", + "cd4.bed:md5,b55e5290d78941f36c3d1ecfef8e0062", + "cd4.peaks.txt:md5,bdcd2ec3a56a8a4a01ed19e17da003f2", + "jurkat.bed:md5,383cfaf10535dbe5d7f47607e345f4cb", + "jurkat.peaks.txt:md5,d4914194eca6f06aadfe7eed08ab1bb8", + "versions.yml:md5,7c0dcd0a18b3c753def73b96cb825792", + "cd4_merged.bed:md5,9ace0ca4f1544bb0949355a20de98e6b", + "jurkat_merged.bed:md5,f1dde43c4ad9dec972ff9fa38cc6f2fe", + "cd4_chr21_1_unidirectional_peaks.bed:md5,0193e58943726af89bfd00e9da2536d8", + "jurkat_chr21_1_unidirectional_peaks.bed:md5,cb6932229eea2e09f61d48d7dd397ae1" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-28T21:43:08.022898" + } +} \ No newline at end of file diff --git a/workflows/tests/aligner/dragmap.nf.test b/workflows/tests/aligner/dragmap.nf.test new file mode 100644 index 00000000..72948f1f --- /dev/null +++ b/workflows/tests/aligner/dragmap.nf.test @@ -0,0 +1,22 @@ +nextflow_pipeline { + + name "DRAGMAP" + script "../../../main.nf" + + test("Should run with defaults") { + + when { + params { + outdir = "$outputDir" + aligner = "dragmap" + } + } + + then { + // FIXME Broken on ARM and difficult to maintain, considering deprecating + assertAll( + { assert workflow.success }, + ) + } + } +} diff --git a/workflows/tests/aligner/hisat2.nf.test b/workflows/tests/aligner/hisat2.nf.test new file mode 100644 index 00000000..8deb6f2b --- /dev/null +++ b/workflows/tests/aligner/hisat2.nf.test @@ -0,0 +1,42 @@ +nextflow_pipeline { + + name "HISAT2" + script "../../../main.nf" + + test("Should run with defaults") { + + tag "HISAT2" + + when { + params { + outdir = "$outputDir" + aligner = "hisat2" + hisat2_index = 'https://raw.githubusercontent.com/nf-core/test-datasets/nascent/reference/GRCh38_chr21_hisat2.tar.gz' + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}', 'multiqc/multiqc_plots', 'multiqc/multiqc_plots/**']) + // stable_path: All files in ${params.outdir}/ with stable content + def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') + // bam_files: All bam files + def bam_files = getAllFilesFromDir(params.outdir, include: ['**/*.bam']) + assertAll( + { assert workflow.success }, + { assert snapshot( + // Number of 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_nascent_software_mqc_versions.yml"), + // All stable path name + stable_name, + // All files with stable contents + stable_path, + // All bam files + // FIXME bam_files.collect{ file -> [ file.getName(), bam(file.toString()).getReadsMD5() ] } + ).match() } + ) + } + } +} diff --git a/workflows/tests/aligner/hisat2.nf.test.snap b/workflows/tests/aligner/hisat2.nf.test.snap new file mode 100644 index 00000000..eb4693e2 --- /dev/null +++ b/workflows/tests/aligner/hisat2.nf.test.snap @@ -0,0 +1,369 @@ +{ + "Should run with defaults": { + "content": [ + 89, + { + "BBMAP_PILEUP": { + "bbmap": 39.01, + "samtools": "1.16.1", + "pigz": 2.6 + }, + "BEDTOOLS_GENOMECOV_MINUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_GENOMECOV_PLUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT_FILTER": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_MERGE": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_SORT": { + "bedtools": "2.31.1" + }, + "CAT_CAT": { + "pigz": "2.3.4" + }, + "CUSTOM_GETCHROMSIZES": { + "getchromsizes": 1.2 + }, + "DEEPTOOLS_BAMCOVERAGE_MINUS": { + "deeptools": "3.5.5" + }, + "DEEPTOOLS_BAMCOVERAGE_PLUS": { + "deeptools": "3.5.5" + }, + "FASTP": { + "fastp": "0.23.4" + }, + "FASTQC": { + "fastqc": "0.12.1" + }, + "GTF2BED": { + "perl": "5.26.2" + }, + "HISAT2_ALIGN": { + "hisat2": "2.2.1", + "samtools": "1.16.1" + }, + "HOMER_MAKETAGDIRECTORY": { + "homer": 4.11, + "samtools": 1.21 + }, + "PINTS_CALLER": { + "python": "3.12.6", + "pints": "1.1.13" + }, + "PRESEQ_CCURVE": { + "preseq": "3.1.1" + }, + "PRESEQ_LCEXTRAP": { + "preseq": "3.1.1" + }, + "RSEQC_INFEREXPERIMENT": { + "rseqc": "5.0.2" + }, + "RSEQC_READDISTRIBUTION": { + "rseqc": "5.0.2" + }, + "RSEQC_READDUPLICATION": { + "rseqc": "5.0.2" + }, + "SAMTOOLS_FLAGSTAT": { + "samtools": 1.21 + }, + "SAMTOOLS_IDXSTATS": { + "samtools": 1.21 + }, + "SAMTOOLS_INDEX": { + "samtools": 1.21 + }, + "SAMTOOLS_MERGE": { + "samtools": 1.21 + }, + "SAMTOOLS_SORT": { + "samtools": 1.21 + }, + "SAMTOOLS_STATS": { + "samtools": 1.21 + }, + "SUBREAD_FEATURECOUNTS_GENE": { + "subread": "2.0.1" + }, + "UNTAR_HISAT2_INDEX": { + "untar": 1.34 + }, + "Workflow": { + "nf-core/nascent": "v2.3.0" + } + }, + [ + "cat", + "cat/cd4.bed", + "cat/jurkat.bed", + "coverage_graphs", + "coverage_graphs/cd4_REP1.dreg.bedGraph", + "coverage_graphs/cd4_REP1.minus.bedGraph", + "coverage_graphs/cd4_REP1.minus.bigWig", + "coverage_graphs/cd4_REP1.plus.bedGraph", + "coverage_graphs/cd4_REP1.plus.bigWig", + "coverage_graphs/cd4_REP2.dreg.bedGraph", + "coverage_graphs/cd4_REP2.minus.bedGraph", + "coverage_graphs/cd4_REP2.minus.bigWig", + "coverage_graphs/cd4_REP2.plus.bedGraph", + "coverage_graphs/cd4_REP2.plus.bigWig", + "coverage_graphs/jurkat.dreg.bedGraph", + "coverage_graphs/jurkat.minus.bedGraph", + "coverage_graphs/jurkat.minus.bigWig", + "coverage_graphs/jurkat.plus.bedGraph", + "coverage_graphs/jurkat.plus.bigWig", + "hisat2", + "hisat2/cd4_REP1.sorted.bam", + "hisat2/cd4_REP1.sorted.bam.bai", + "hisat2/cd4_REP2.sorted.bam", + "hisat2/cd4_REP2.sorted.bam.bai", + "hisat2/jurkat.sorted.bam", + "hisat2/jurkat.sorted.bam.bai", + "hisat2/log", + "hisat2/log/cd4_REP1.hisat2.summary.log", + "hisat2/log/cd4_REP2.hisat2.summary.log", + "hisat2/log/jurkat.hisat2.summary.log", + "hisat2/samtools_stats", + "hisat2/samtools_stats/cd4_REP1.sorted.bam.flagstat", + "hisat2/samtools_stats/cd4_REP1.sorted.bam.idxstats", + "hisat2/samtools_stats/cd4_REP1.sorted.bam.stats", + "hisat2/samtools_stats/cd4_REP2.sorted.bam.flagstat", + "hisat2/samtools_stats/cd4_REP2.sorted.bam.idxstats", + "hisat2/samtools_stats/cd4_REP2.sorted.bam.stats", + "hisat2/samtools_stats/jurkat.sorted.bam.flagstat", + "hisat2/samtools_stats/jurkat.sorted.bam.idxstats", + "hisat2/samtools_stats/jurkat.sorted.bam.stats", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_data/fastqc-status-check-heatmap.txt", + "multiqc/multiqc_data/fastqc_adapter_content_plot.txt", + "multiqc/multiqc_data/fastqc_overrepresented_sequences_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_n_content_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_sequence_quality_plot.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Counts.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Percentages.txt", + "multiqc/multiqc_data/fastqc_per_sequence_quality_scores_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_counts_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_duplication_levels_plot.txt", + "multiqc/multiqc_data/fastqc_top_overrepresented_sequences_table.txt", + "multiqc/multiqc_data/homer-tag-directory-gc-content.txt", + "multiqc/multiqc_data/homer-tag-info-dist.txt", + "multiqc/multiqc_data/homer-tag-length-dist.txt", + "multiqc/multiqc_data/homer_tagdir.txt", + "multiqc/multiqc_data/multiqc.log", + "multiqc/multiqc_data/multiqc_citations.txt", + "multiqc/multiqc_data/multiqc_data.json", + "multiqc/multiqc_data/multiqc_fastqc.txt", + "multiqc/multiqc_data/multiqc_general_stats.txt", + "multiqc/multiqc_data/multiqc_rseqc_infer_experiment.txt", + "multiqc/multiqc_data/multiqc_rseqc_read_distribution.txt", + "multiqc/multiqc_data/multiqc_samtools_flagstat.txt", + "multiqc/multiqc_data/multiqc_samtools_idxstats.txt", + "multiqc/multiqc_data/multiqc_samtools_stats.txt", + "multiqc/multiqc_data/multiqc_software_versions.txt", + "multiqc/multiqc_data/multiqc_sources.txt", + "multiqc/multiqc_data/preseq.txt", + "multiqc/multiqc_data/preseq_complexity_plot_molecules.txt", + "multiqc/multiqc_data/rseqc_infer_experiment_plot.txt", + "multiqc/multiqc_data/rseqc_read_distribution_plot.txt", + "multiqc/multiqc_data/rseqc_read_dups.txt", + "multiqc/multiqc_data/rseqc_read_dups_plot.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Percentage_of_total.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Read_counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Normalised_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Observed_over_Expected_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Raw_Counts.txt", + "multiqc/multiqc_data/samtools-stats-dp.txt", + "multiqc/multiqc_data/samtools_alignment_plot.txt", + "multiqc/multiqc_report.html", + "pipeline_info", + "pipeline_info/nf_core_nascent_software_mqc_versions.yml", + "preprocessing", + "preprocessing/fastp", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.log", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.log", + "preprocessing/fastp/jurkat.trimmed.fastp.html", + "preprocessing/fastp/jurkat.trimmed.fastp.json", + "preprocessing/fastp/jurkat.trimmed.fastp.log", + "preprocessing/fastqc", + "preprocessing/fastqc/cd4_REP1_fastqc.html", + "preprocessing/fastqc/cd4_REP1_fastqc.zip", + "preprocessing/fastqc/cd4_REP2_fastqc.html", + "preprocessing/fastqc/cd4_REP2_fastqc.zip", + "preprocessing/fastqc/jurkat_fastqc.html", + "preprocessing/fastqc/jurkat_fastqc.zip", + "quality_control", + "quality_control/bbsplit", + "quality_control/bbsplit/cd4_REP1.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP1.coverage.stats.txt", + "quality_control/bbsplit/cd4_REP2.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP2.coverage.stats.txt", + "quality_control/bbsplit/jurkat.coverage.hist.txt", + "quality_control/bbsplit/jurkat.coverage.stats.txt", + "quality_control/preseq", + "quality_control/preseq/cd4_REP1.c_curve.txt", + "quality_control/preseq/cd4_REP1.lc_extrap.txt", + "quality_control/preseq/cd4_REP2.c_curve.txt", + "quality_control/preseq/cd4_REP2.lc_extrap.txt", + "quality_control/preseq/jurkat.c_curve.txt", + "quality_control/preseq/jurkat.lc_extrap.txt", + "quality_control/preseq/log", + "quality_control/preseq/log/cd4_REP1.command.log", + "quality_control/preseq/log/cd4_REP2.command.log", + "quality_control/preseq/log/jurkat.command.log", + "quality_control/rseqc", + "quality_control/rseqc/infer_experiment", + "quality_control/rseqc/infer_experiment/cd4_REP1.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/cd4_REP2.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/jurkat.infer_experiment.txt", + "quality_control/rseqc/read_distribution", + "quality_control/rseqc/read_distribution/cd4_REP1.read_distribution.txt", + "quality_control/rseqc/read_distribution/cd4_REP2.read_distribution.txt", + "quality_control/rseqc/read_distribution/jurkat.read_distribution.txt", + "quality_control/rseqc/read_duplication", + "quality_control/rseqc/read_duplication/pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP1.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP2.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/jurkat.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/rscript", + "quality_control/rseqc/read_duplication/rscript/cd4_REP1.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/cd4_REP2.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/jurkat.DupRate_plot.r", + "quality_control/rseqc/read_duplication/xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.seq.DupRate.xls", + "quantification", + "quantification/gene", + "quantification/gene/cd4.featureCounts.txt", + "quantification/gene/cd4.featureCounts.txt.summary", + "quantification/gene/jurkat.featureCounts.txt", + "quantification/gene/jurkat.featureCounts.txt.summary", + "samtools", + "samtools/cd4.bam", + "samtools/jurkat.bam", + "transcript_identification", + "transcript_identification/filtered", + "transcript_identification/filtered/cd4_filtered.bed", + "transcript_identification/filtered/jurkat_filtered.bed", + "transcript_identification/homer", + "transcript_identification/homer/cd4.bed", + "transcript_identification/homer/cd4.bedGraph.gz", + "transcript_identification/homer/cd4.peaks.txt", + "transcript_identification/homer/cd4_tagdir", + "transcript_identification/homer/cd4_tagdir/chr21.tags.tsv", + "transcript_identification/homer/cd4_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/cd4_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/cd4_tagdir/tagFreq.txt", + "transcript_identification/homer/cd4_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/cd4_tagdir/tagGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagInfo.txt", + "transcript_identification/homer/cd4_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/jurkat.bed", + "transcript_identification/homer/jurkat.bedGraph.gz", + "transcript_identification/homer/jurkat.peaks.txt", + "transcript_identification/homer/jurkat_tagdir", + "transcript_identification/homer/jurkat_tagdir/chr21.tags.tsv", + "transcript_identification/homer/jurkat_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/jurkat_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreq.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/jurkat_tagdir/tagGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagInfo.txt", + "transcript_identification/homer/jurkat_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/versions.yml", + "transcript_identification/intersect", + "transcript_identification/intersect/cd4_intersect.bed", + "transcript_identification/intersect/jurkat_intersect.bed", + "transcript_identification/merged", + "transcript_identification/merged/cd4_merged.bed", + "transcript_identification/merged/jurkat_merged.bed", + "transcript_identification/pints", + "transcript_identification/pints/cd4_chr21_1_unidirectional_peaks.bed", + "transcript_identification/pints/jurkat_chr21_1_unidirectional_peaks.bed", + "untar", + "untar/GRCh38_chr21_hisat2", + "untar/GRCh38_chr21_hisat2/GRCh38_chr21.1.ht2", + "untar/GRCh38_chr21_hisat2/GRCh38_chr21.2.ht2", + "untar/GRCh38_chr21_hisat2/GRCh38_chr21.3.ht2", + "untar/GRCh38_chr21_hisat2/GRCh38_chr21.4.ht2", + "untar/GRCh38_chr21_hisat2/GRCh38_chr21.5.ht2", + "untar/GRCh38_chr21_hisat2/GRCh38_chr21.6.ht2", + "untar/GRCh38_chr21_hisat2/GRCh38_chr21.7.ht2", + "untar/GRCh38_chr21_hisat2/GRCh38_chr21.8.ht2" + ], + [ + "cd4.bed:md5,1c4f3b80b9b606855d0e6b1609fc90a3", + "jurkat.bed:md5,1a07210f46be7235f6fd3ea7260c2a55", + "cd4_REP1.dreg.bedGraph:md5,9afeff7c6ca37640e946de7c6153f77f", + "cd4_REP1.minus.bedGraph:md5,22f749f499c9a66e77d7cb4d0b05f115", + "cd4_REP1.minus.bigWig:md5,7430ec6b29bad01cc195bff48e7c3318", + "cd4_REP1.plus.bedGraph:md5,a5371fb8da790607b820b449711efda9", + "cd4_REP1.plus.bigWig:md5,051b50fa9bb4de523d54a37b2d7353f5", + "cd4_REP2.dreg.bedGraph:md5,7db28452604d25f084f5c90a844acfaa", + "cd4_REP2.minus.bedGraph:md5,ccbc07a515c079678fe9aac66943a94d", + "cd4_REP2.minus.bigWig:md5,59d6c644860efb1852d1d88f12e5328e", + "cd4_REP2.plus.bedGraph:md5,47a5ac385c35a0a12fca2fea5c060a30", + "cd4_REP2.plus.bigWig:md5,7e1f1319b32f591d6704050447317108", + "jurkat.dreg.bedGraph:md5,2263e002f2867d8c306e52cf0a5ed495", + "jurkat.minus.bedGraph:md5,b06abe7efd4e332e73fa1895e554dc06", + "jurkat.minus.bigWig:md5,8a0ca6db6626d3fefb518f0d35dd1abc", + "jurkat.plus.bedGraph:md5,835edbd98f6d5d69e56de05e1a837b7c", + "jurkat.plus.bigWig:md5,66e82005e6c6730e970f7506bf93325c", + "cd4_REP1.sorted.bam.flagstat:md5,aa26d19a689b2fe97e254f125e1f7bcb", + "cd4_REP1.sorted.bam.idxstats:md5,d523e6e25ce8659871df4104dab503b0", + "cd4_REP1.sorted.bam.stats:md5,244977b276c63d2d348976d15d0cdc1c", + "cd4_REP2.sorted.bam.flagstat:md5,6235482c2c1be02a23826261e2f8a033", + "cd4_REP2.sorted.bam.idxstats:md5,89de35c9f4f1eafa6944d5d574db1675", + "cd4_REP2.sorted.bam.stats:md5,733cb9aeb26c7093ed936702bd7a8ba8", + "jurkat.sorted.bam.flagstat:md5,8e59ad91dd9df6003cb6c3070b0aa34c", + "jurkat.sorted.bam.idxstats:md5,56608a565532fc8ae2b93a3be28d5e8d", + "jurkat.sorted.bam.stats:md5,18f79cf0b37c7052d4a5d602987a8e64", + "cd4_REP1.trimmed.fastp.json:md5,bd9a3344c1591d6be4d524451f9dca53", + "cd4_REP2.trimmed.fastp.json:md5,bc6e3f9ff7835f220535cc393b8eb25f", + "jurkat.trimmed.fastp.json:md5,65f7247a87479c7157c7357d575336e2", + "cd4.bed:md5,d8c78818eb1666575ef4c2534ea3727e", + "cd4.peaks.txt:md5,8bb1c5655a1cce187290a3409e82a43b", + "jurkat.bed:md5,7298daa579135dfb8924067abaa2ba4e", + "jurkat.peaks.txt:md5,f514028265e7c4881f155f860211cbba", + "versions.yml:md5,7c0dcd0a18b3c753def73b96cb825792", + "cd4_merged.bed:md5,d71436c8df71a82bfbe0e9afb74145df", + "jurkat_merged.bed:md5,bd6458d033db136523d32ffba259f564", + "cd4_chr21_1_unidirectional_peaks.bed:md5,1c4f3b80b9b606855d0e6b1609fc90a3", + "jurkat_chr21_1_unidirectional_peaks.bed:md5,1a07210f46be7235f6fd3ea7260c2a55", + "GRCh38_chr21.1.ht2:md5,eb322cf410ecc616d7fe63cc1be2785b", + "GRCh38_chr21.2.ht2:md5,46be3356d4c236ebd5d1e52e9eaf4e12", + "GRCh38_chr21.3.ht2:md5,dbf5af96efd98d6b03f1e5d2baed848a", + "GRCh38_chr21.4.ht2:md5,bd952f748321c4c230671e8fce7b1650", + "GRCh38_chr21.5.ht2:md5,103032edf695164b32cc9e6781e8f08b", + "GRCh38_chr21.6.ht2:md5,242e36d01cd1719b6bd05f157c644eed", + "GRCh38_chr21.7.ht2:md5,24e7d0673a77e07fbe40400f9a6b3db6", + "GRCh38_chr21.8.ht2:md5,5e0626bdb7f7a267990f72ae45c3e44a" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.3" + }, + "timestamp": "2024-12-23T14:30:09.535125" + } +} \ No newline at end of file diff --git a/workflows/tests/aligner/star.nf.test b/workflows/tests/aligner/star.nf.test new file mode 100644 index 00000000..1fbcd996 --- /dev/null +++ b/workflows/tests/aligner/star.nf.test @@ -0,0 +1,63 @@ +nextflow_pipeline { + + name "STAR" + script "../../../main.nf" + tag "aligner" + tag "star" + + test("Should run with defaults") { + + when { + params { + outdir = "$outputDir" + aligner = "star" + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}', 'multiqc/multiqc_plots', 'multiqc/multiqc_plots/**']) + // stable_path: All files in ${params.outdir}/ with stable content + def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') + // bam_files: All bam files + def bam_files = getAllFilesFromDir(params.outdir, include: ['**/*.bam']) + assertAll( + { assert workflow.success }, + { assert snapshot( + // Number of 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_nascent_software_mqc_versions.yml"), + // All stable path name + stable_name, + // All files with stable contents + stable_path, + // All bam files + // FIXME bam_files.collect{ file -> [ file.getName(), bam(file.toString()).getReadsMD5() ] } + ).match() } + ) + } + } + + test("Should run with gzipped gtf") { + + when { + params { + outdir = "$outputDir" + aligner = "star" + gtf = "https://raw.githubusercontent.com/nf-core/test-datasets/nascent/reference/genes_chr21.gtf.gz" + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(removeNextflowVersion("$outputDir/pipeline_info/nf_core_nascent_software_mqc_versions.yml")).match("gzip_software_versions") }, + { assert snapshot( + workflow.trace.tasks().size(), + ).match() + } + ) + } + } +} diff --git a/workflows/tests/aligner/star.nf.test.snap b/workflows/tests/aligner/star.nf.test.snap new file mode 100644 index 00000000..5e3ecb27 --- /dev/null +++ b/workflows/tests/aligner/star.nf.test.snap @@ -0,0 +1,478 @@ +{ + "Should run with gzipped gtf": { + "content": [ + 93 + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-21T11:57:47.575681" + }, + "Should run with defaults": { + "content": [ + 92, + { + "BBMAP_PILEUP": { + "bbmap": 39.01, + "samtools": "1.16.1", + "pigz": 2.6 + }, + "BEDTOOLS_GENOMECOV_MINUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_GENOMECOV_PLUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT_FILTER": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_MERGE": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_SORT": { + "bedtools": "2.31.1" + }, + "CAT_CAT": { + "pigz": "2.3.4" + }, + "CUSTOM_GETCHROMSIZES": { + "getchromsizes": 1.2 + }, + "DEEPTOOLS_BAMCOVERAGE_MINUS": { + "deeptools": "3.5.5" + }, + "DEEPTOOLS_BAMCOVERAGE_PLUS": { + "deeptools": "3.5.5" + }, + "FASTP": { + "fastp": "0.23.4" + }, + "FASTQC": { + "fastqc": "0.12.1" + }, + "GTF2BED": { + "perl": "5.26.2" + }, + "HOMER_MAKETAGDIRECTORY": { + "homer": 4.11, + "samtools": 1.21 + }, + "PINTS_CALLER": { + "python": "3.12.6", + "pints": "1.1.13" + }, + "PRESEQ_CCURVE": { + "preseq": "3.1.1" + }, + "PRESEQ_LCEXTRAP": { + "preseq": "3.1.1" + }, + "RSEQC_INFEREXPERIMENT": { + "rseqc": "5.0.2" + }, + "RSEQC_READDISTRIBUTION": { + "rseqc": "5.0.2" + }, + "RSEQC_READDUPLICATION": { + "rseqc": "5.0.2" + }, + "SAMTOOLS_MERGE": { + "samtools": 1.21 + }, + "SUBREAD_FEATURECOUNTS_GENE": { + "subread": "2.0.1" + }, + "SUBREAD_FEATURECOUNTS_PREDICTED": { + "subread": "2.0.1" + }, + "Workflow": { + "nf-core/nascent": "v2.3.0" + } + }, + [ + "cat", + "cat/cd4.bed", + "cat/jurkat.bed", + "coverage_graphs", + "coverage_graphs/cd4_REP1.dreg.bedGraph", + "coverage_graphs/cd4_REP1.minus.bedGraph", + "coverage_graphs/cd4_REP1.minus.bigWig", + "coverage_graphs/cd4_REP1.plus.bedGraph", + "coverage_graphs/cd4_REP1.plus.bigWig", + "coverage_graphs/cd4_REP2.dreg.bedGraph", + "coverage_graphs/cd4_REP2.minus.bedGraph", + "coverage_graphs/cd4_REP2.minus.bigWig", + "coverage_graphs/cd4_REP2.plus.bedGraph", + "coverage_graphs/cd4_REP2.plus.bigWig", + "coverage_graphs/jurkat.dreg.bedGraph", + "coverage_graphs/jurkat.minus.bedGraph", + "coverage_graphs/jurkat.minus.bigWig", + "coverage_graphs/jurkat.plus.bedGraph", + "coverage_graphs/jurkat.plus.bigWig", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_data/fastqc-status-check-heatmap.txt", + "multiqc/multiqc_data/fastqc_adapter_content_plot.txt", + "multiqc/multiqc_data/fastqc_overrepresented_sequences_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_n_content_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_sequence_quality_plot.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Counts.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Percentages.txt", + "multiqc/multiqc_data/fastqc_per_sequence_quality_scores_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_counts_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_duplication_levels_plot.txt", + "multiqc/multiqc_data/fastqc_top_overrepresented_sequences_table.txt", + "multiqc/multiqc_data/homer-tag-directory-gc-content.txt", + "multiqc/multiqc_data/homer-tag-info-dist.txt", + "multiqc/multiqc_data/homer-tag-length-dist.txt", + "multiqc/multiqc_data/homer_tagdir.txt", + "multiqc/multiqc_data/multiqc.log", + "multiqc/multiqc_data/multiqc_citations.txt", + "multiqc/multiqc_data/multiqc_data.json", + "multiqc/multiqc_data/multiqc_fastqc.txt", + "multiqc/multiqc_data/multiqc_general_stats.txt", + "multiqc/multiqc_data/multiqc_rseqc_infer_experiment.txt", + "multiqc/multiqc_data/multiqc_rseqc_read_distribution.txt", + "multiqc/multiqc_data/multiqc_samtools_flagstat.txt", + "multiqc/multiqc_data/multiqc_samtools_idxstats.txt", + "multiqc/multiqc_data/multiqc_samtools_stats.txt", + "multiqc/multiqc_data/multiqc_software_versions.txt", + "multiqc/multiqc_data/multiqc_sources.txt", + "multiqc/multiqc_data/preseq.txt", + "multiqc/multiqc_data/preseq_complexity_plot_molecules.txt", + "multiqc/multiqc_data/rseqc_infer_experiment_plot.txt", + "multiqc/multiqc_data/rseqc_read_distribution_plot.txt", + "multiqc/multiqc_data/rseqc_read_dups.txt", + "multiqc/multiqc_data/rseqc_read_dups_plot.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Percentage_of_total.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Read_counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Normalised_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Observed_over_Expected_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Raw_Counts.txt", + "multiqc/multiqc_data/samtools-stats-dp.txt", + "multiqc/multiqc_data/samtools_alignment_plot.txt", + "multiqc/multiqc_report.html", + "pipeline_info", + "pipeline_info/nf_core_nascent_software_mqc_versions.yml", + "preprocessing", + "preprocessing/fastp", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.log", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.log", + "preprocessing/fastp/jurkat.trimmed.fastp.html", + "preprocessing/fastp/jurkat.trimmed.fastp.json", + "preprocessing/fastp/jurkat.trimmed.fastp.log", + "preprocessing/fastqc", + "preprocessing/fastqc/cd4_REP1_fastqc.html", + "preprocessing/fastqc/cd4_REP1_fastqc.zip", + "preprocessing/fastqc/cd4_REP2_fastqc.html", + "preprocessing/fastqc/cd4_REP2_fastqc.zip", + "preprocessing/fastqc/jurkat_fastqc.html", + "preprocessing/fastqc/jurkat_fastqc.zip", + "quality_control", + "quality_control/bbsplit", + "quality_control/bbsplit/cd4_REP1.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP1.coverage.stats.txt", + "quality_control/bbsplit/cd4_REP2.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP2.coverage.stats.txt", + "quality_control/bbsplit/jurkat.coverage.hist.txt", + "quality_control/bbsplit/jurkat.coverage.stats.txt", + "quality_control/preseq", + "quality_control/preseq/cd4_REP1.c_curve.txt", + "quality_control/preseq/cd4_REP1.lc_extrap.txt", + "quality_control/preseq/cd4_REP2.c_curve.txt", + "quality_control/preseq/cd4_REP2.lc_extrap.txt", + "quality_control/preseq/jurkat.c_curve.txt", + "quality_control/preseq/jurkat.lc_extrap.txt", + "quality_control/preseq/log", + "quality_control/preseq/log/cd4_REP1.command.log", + "quality_control/preseq/log/cd4_REP2.command.log", + "quality_control/preseq/log/jurkat.command.log", + "quality_control/rseqc", + "quality_control/rseqc/infer_experiment", + "quality_control/rseqc/infer_experiment/cd4_REP1.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/cd4_REP2.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/jurkat.infer_experiment.txt", + "quality_control/rseqc/read_distribution", + "quality_control/rseqc/read_distribution/cd4_REP1.read_distribution.txt", + "quality_control/rseqc/read_distribution/cd4_REP2.read_distribution.txt", + "quality_control/rseqc/read_distribution/jurkat.read_distribution.txt", + "quality_control/rseqc/read_duplication", + "quality_control/rseqc/read_duplication/pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP1.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP2.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/jurkat.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/rscript", + "quality_control/rseqc/read_duplication/rscript/cd4_REP1.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/cd4_REP2.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/jurkat.DupRate_plot.r", + "quality_control/rseqc/read_duplication/xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.seq.DupRate.xls", + "quantification", + "quantification/gene", + "quantification/gene/cd4.featureCounts.txt", + "quantification/gene/cd4.featureCounts.txt.summary", + "quantification/gene/jurkat.featureCounts.txt", + "quantification/gene/jurkat.featureCounts.txt.summary", + "quantification/nascent", + "quantification/nascent/cd4-group_cd4_intersect-transcripts.featureCounts.txt", + "quantification/nascent/cd4-group_cd4_intersect-transcripts.featureCounts.txt.summary", + "quantification/nascent/jurkat-group_cd4_intersect-transcripts.featureCounts.txt", + "quantification/nascent/jurkat-group_cd4_intersect-transcripts.featureCounts.txt.summary", + "samtools", + "samtools/cd4.bam", + "samtools/jurkat.bam", + "star", + "star/log", + "star/log/cd4_REP1.Log.final.out", + "star/log/cd4_REP1.Log.out", + "star/log/cd4_REP1.Log.progress.out", + "star/log/cd4_REP1.SJ.out.tab", + "star/log/cd4_REP2.Log.final.out", + "star/log/cd4_REP2.Log.out", + "star/log/cd4_REP2.Log.progress.out", + "star/log/cd4_REP2.SJ.out.tab", + "star/log/jurkat.Log.final.out", + "star/log/jurkat.Log.out", + "star/log/jurkat.Log.progress.out", + "star/log/jurkat.SJ.out.tab", + "star/samtools_stats", + "star/samtools_stats/cd4_REP1_genome.flagstat", + "star/samtools_stats/cd4_REP1_genome.idxstats", + "star/samtools_stats/cd4_REP1_genome.stats", + "star/samtools_stats/cd4_REP2_genome.flagstat", + "star/samtools_stats/cd4_REP2_genome.idxstats", + "star/samtools_stats/cd4_REP2_genome.stats", + "star/samtools_stats/jurkat_genome.flagstat", + "star/samtools_stats/jurkat_genome.idxstats", + "star/samtools_stats/jurkat_genome.stats", + "star/star", + "star/star/Genome", + "star/star/Log.out", + "star/star/SA", + "star/star/SAindex", + "star/star/chrLength.txt", + "star/star/chrName.txt", + "star/star/chrNameLength.txt", + "star/star/chrStart.txt", + "star/star/exonGeTrInfo.tab", + "star/star/exonInfo.tab", + "star/star/geneInfo.tab", + "star/star/genomeParameters.txt", + "star/star/sjdbInfo.txt", + "star/star/sjdbList.fromGTF.out.tab", + "star/star/sjdbList.out.tab", + "star/star/transcriptInfo.tab", + "transcript_identification", + "transcript_identification/filtered", + "transcript_identification/filtered/cd4_filtered.bed", + "transcript_identification/filtered/jurkat_filtered.bed", + "transcript_identification/homer", + "transcript_identification/homer/cd4.bed", + "transcript_identification/homer/cd4.bedGraph.gz", + "transcript_identification/homer/cd4.peaks.txt", + "transcript_identification/homer/cd4_tagdir", + "transcript_identification/homer/cd4_tagdir/chr21.tags.tsv", + "transcript_identification/homer/cd4_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/cd4_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/cd4_tagdir/tagFreq.txt", + "transcript_identification/homer/cd4_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/cd4_tagdir/tagGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagInfo.txt", + "transcript_identification/homer/cd4_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/jurkat.bed", + "transcript_identification/homer/jurkat.bedGraph.gz", + "transcript_identification/homer/jurkat.peaks.txt", + "transcript_identification/homer/jurkat_tagdir", + "transcript_identification/homer/jurkat_tagdir/chr21.tags.tsv", + "transcript_identification/homer/jurkat_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/jurkat_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreq.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/jurkat_tagdir/tagGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagInfo.txt", + "transcript_identification/homer/jurkat_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/versions.yml", + "transcript_identification/intersect", + "transcript_identification/intersect/cd4_intersect.bed", + "transcript_identification/intersect/jurkat_intersect.bed", + "transcript_identification/merged", + "transcript_identification/merged/cd4_merged.bed", + "transcript_identification/merged/jurkat_merged.bed", + "transcript_identification/pints", + "transcript_identification/pints/cd4_chr21_1_unidirectional_peaks.bed", + "transcript_identification/pints/jurkat_chr21_1_unidirectional_peaks.bed" + ], + [ + "cd4.bed:md5,26765aa153cb1d6bb668f5786da5763e", + "jurkat.bed:md5,15a3bec7a3ffb53c1e621665b3f45873", + "cd4_REP1.dreg.bedGraph:md5,6ecfb93ba1a56308ce7d3c4703e0e5e3", + "cd4_REP1.minus.bedGraph:md5,9e07f1d5637b2193f55da08d6877bd93", + "cd4_REP1.minus.bigWig:md5,fa4743c954c2d96c38d1d53511ebf647", + "cd4_REP1.plus.bedGraph:md5,c111dc157dc7ecd53e7f6b8ce8d5ccc0", + "cd4_REP1.plus.bigWig:md5,37f187a2a476cba99a00ab7683079f84", + "cd4_REP2.dreg.bedGraph:md5,949a822bee0b968f118fb4d2d0fcf251", + "cd4_REP2.minus.bedGraph:md5,d0bdd2bf54e343a00d620d41da32e2f3", + "cd4_REP2.minus.bigWig:md5,9f8cb0bdf31650b1af341b5522cf7634", + "cd4_REP2.plus.bedGraph:md5,268311481da2d62204f71a1a8bc5d43b", + "cd4_REP2.plus.bigWig:md5,4f5f27b5e3258ebf2ee7bf1f8fe17357", + "jurkat.dreg.bedGraph:md5,9a2a287e9d8e73185d5754442051055b", + "jurkat.minus.bedGraph:md5,964feef1a4988cbf900840fa572a676e", + "jurkat.minus.bigWig:md5,172ea254e30275889eb94a2f2f7f04cf", + "jurkat.plus.bedGraph:md5,198a0f027ca6799ecc74196232402c81", + "jurkat.plus.bigWig:md5,0bd721f298a8dde14ffdbda6db303f93", + "cd4_REP1.trimmed.fastp.json:md5,bd9a3344c1591d6be4d524451f9dca53", + "cd4_REP2.trimmed.fastp.json:md5,bc6e3f9ff7835f220535cc393b8eb25f", + "jurkat.trimmed.fastp.json:md5,65f7247a87479c7157c7357d575336e2", + "cd4_REP1.SJ.out.tab:md5,991ac1fa28719c078a4827fcf66e90b0", + "cd4_REP2.SJ.out.tab:md5,5accd405e613d28731f111dfd070a3ba", + "jurkat.SJ.out.tab:md5,8e5de2dc83e2478528528a86a2ffd456", + "cd4_REP1_genome.flagstat:md5,6379888a79d90e28dd969e21f7b03a33", + "cd4_REP1_genome.idxstats:md5,65e8e2d1ed65620f9750f2981e997a9d", + "cd4_REP1_genome.stats:md5,98b8edc46f4553462af6a395fa36ccb1", + "cd4_REP2_genome.flagstat:md5,ab83e3fbca17cf463fc5293a82e4bb3a", + "cd4_REP2_genome.idxstats:md5,9cdf3dd50a9862a02592c3768071fe32", + "cd4_REP2_genome.stats:md5,5b0f411f23fce70ed0c509f1e5a2aa01", + "jurkat_genome.flagstat:md5,b5f1d127de493e406882aced667210c9", + "jurkat_genome.idxstats:md5,5e4a68fda75c954324d659af58d12c62", + "jurkat_genome.stats:md5,e69e49feae0a1840403894aea26c4a33", + "Genome:md5,612664e3cfde5e1b73ad541d93752b31", + "SA:md5,074ae54177bb7b9cb981382f043f36e5", + "SAindex:md5,c8cae2d81bec99f68eddc0afe570090b", + "chrLength.txt:md5,b0be0a56ddefa84552742c72d4859eac", + "chrName.txt:md5,e99d7d1051eee43ceab5563c2d09fcee", + "chrNameLength.txt:md5,c985a141685e8431ec27c782816cb744", + "chrStart.txt:md5,6925b594ea2eeb964ba87cd6d42ab98f", + "exonGeTrInfo.tab:md5,ea42dd46e177f95a72a8f6a2925f7348", + "exonInfo.tab:md5,42a3ce2024f396b2298c0a84b07fb6e4", + "geneInfo.tab:md5,d0092fb1ea6fcdac270c4df788de70fb", + "genomeParameters.txt:md5,9e6f272d058d48c729d355ede94f8c87", + "sjdbInfo.txt:md5,12fb05dc7cea89735a0c19e1c0df61cb", + "sjdbList.fromGTF.out.tab:md5,5d9761b49920fb70a77d74e390d196b9", + "sjdbList.out.tab:md5,766fbca932681f8666b3a9e5fb3640bd", + "transcriptInfo.tab:md5,21c1f470ffe3b55b23900e7b7eaec2f4", + "cd4.bed:md5,28eafdfa41f98475e5e651fd0e8f95f2", + "cd4.peaks.txt:md5,4ab7c16a5f6d0e78275448bbce7c21c2", + "jurkat.bed:md5,7e59345b336cc8a9c5f96bf7df7b3d06", + "jurkat.peaks.txt:md5,91e7580ebde81aceaf3bb1b1c3c3db1c", + "versions.yml:md5,7c0dcd0a18b3c753def73b96cb825792", + "cd4_merged.bed:md5,07860f90354c4f5f66eddbed3e5d3bd2", + "jurkat_merged.bed:md5,95a5279ec2387dfa0b4c2e7820083527", + "cd4_chr21_1_unidirectional_peaks.bed:md5,26765aa153cb1d6bb668f5786da5763e", + "jurkat_chr21_1_unidirectional_peaks.bed:md5,15a3bec7a3ffb53c1e621665b3f45873" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-28T21:46:42.36263" + }, + "gzip_software_versions": { + "content": [ + { + "BBMAP_PILEUP": { + "bbmap": 39.01, + "samtools": "1.16.1", + "pigz": 2.6 + }, + "BEDTOOLS_GENOMECOV_MINUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_GENOMECOV_PLUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT_FILTER": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_MERGE": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_SORT": { + "bedtools": "2.31.1" + }, + "CAT_CAT": { + "pigz": "2.3.4" + }, + "CUSTOM_GETCHROMSIZES": { + "getchromsizes": 1.2 + }, + "DEEPTOOLS_BAMCOVERAGE_MINUS": { + "deeptools": "3.5.5" + }, + "DEEPTOOLS_BAMCOVERAGE_PLUS": { + "deeptools": "3.5.5" + }, + "FASTP": { + "fastp": "0.23.4" + }, + "FASTQC": { + "fastqc": "0.12.1" + }, + "GTF2BED": { + "perl": "5.26.2" + }, + "GUNZIP_GTF": { + "gunzip": 1.1 + }, + "HOMER_MAKETAGDIRECTORY": { + "homer": 4.11, + "samtools": 1.21 + }, + "PINTS_CALLER": { + "python": "3.12.6", + "pints": "1.1.13" + }, + "PRESEQ_CCURVE": { + "preseq": "3.1.1" + }, + "PRESEQ_LCEXTRAP": { + "preseq": "3.1.1" + }, + "RSEQC_INFEREXPERIMENT": { + "rseqc": "5.0.2" + }, + "RSEQC_READDISTRIBUTION": { + "rseqc": "5.0.2" + }, + "RSEQC_READDUPLICATION": { + "rseqc": "5.0.2" + }, + "SAMTOOLS_MERGE": { + "samtools": 1.21 + }, + "SUBREAD_FEATURECOUNTS_GENE": { + "subread": "2.0.1" + }, + "SUBREAD_FEATURECOUNTS_PREDICTED": { + "subread": "2.0.1" + }, + "Workflow": { + "nf-core/nascent": "v2.3.0" + } + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.1" + }, + "timestamp": "2024-11-25T21:02:16.63526" + } +} \ No newline at end of file diff --git a/workflows/tests/bowtie2.nf.test b/workflows/tests/bowtie2.nf.test deleted file mode 100644 index c1e32cb2..00000000 --- a/workflows/tests/bowtie2.nf.test +++ /dev/null @@ -1,24 +0,0 @@ -nextflow_pipeline { - - name "Test Workflow main.nf" - script "../../main.nf" - tag "aligner" - tag "bowtie2" - - test("Should run with bowtie2 (default)") { - - when { - params { - outdir = "$outputDir" - aligner = "bowtie2" - } - } - - then { - assert workflow.success - assert snapshot( - workflow.trace.tasks().size(), - ).match() - } - } -} diff --git a/workflows/tests/bowtie2.nf.test.snap b/workflows/tests/bowtie2.nf.test.snap deleted file mode 100644 index e6dff48c..00000000 --- a/workflows/tests/bowtie2.nf.test.snap +++ /dev/null @@ -1,12 +0,0 @@ -{ - "Should run with bowtie2 (default)": { - "content": [ - 127 - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-02-15T09:57:57.950183345" - } -} \ No newline at end of file diff --git a/workflows/tests/inputs/gff/main.nf.test b/workflows/tests/inputs/gff/main.nf.test new file mode 100644 index 00000000..258a30bf --- /dev/null +++ b/workflows/tests/inputs/gff/main.nf.test @@ -0,0 +1,41 @@ +nextflow_pipeline { + + name "GFF" + script "../../../../main.nf" + tag "input" + tag "gff" + + test("Should run with an unzipped GFF file") { + + when { + params { + outdir = "$outputDir" + gff = 'https://raw.githubusercontent.com/nf-core/test-datasets/nascent/reference/genes_chr21.gff' + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}', 'multiqc/multiqc_plots', 'multiqc/multiqc_plots/**']) + // stable_path: All files in ${params.outdir}/ with stable content + def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') + // bam_files: All bam files + def bam_files = getAllFilesFromDir(params.outdir, include: ['**/*.bam']) + assertAll( + { assert workflow.success }, + { assert snapshot( + // Number of 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_nascent_software_mqc_versions.yml"), + // All stable path name + stable_name, + // All files with stable contents + stable_path, + // All bam files + // FIXME bam_files.collect{ file -> [ file.getName(), bam(file.toString()).getReadsMD5() ] } + ).match() } + ) + } + } +} diff --git a/workflows/tests/inputs/gff/main.nf.test.snap b/workflows/tests/inputs/gff/main.nf.test.snap new file mode 100644 index 00000000..ce95984f --- /dev/null +++ b/workflows/tests/inputs/gff/main.nf.test.snap @@ -0,0 +1,340 @@ +{ + "Should run with an unzipped GFF file": { + "content": [ + 92, + { + "BBMAP_PILEUP": { + "bbmap": 39.01, + "samtools": "1.16.1", + "pigz": 2.6 + }, + "BEDTOOLS_GENOMECOV_MINUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_GENOMECOV_PLUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT_FILTER": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_MERGE": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_SORT": { + "bedtools": "2.31.1" + }, + "BWA_INDEX": { + "bwa": "0.7.18-r1243-dirty" + }, + "BWA_MEM": { + "bwa": "0.7.18-r1243-dirty", + "samtools": 1.2 + }, + "CAT_CAT": { + "pigz": "2.3.4" + }, + "CUSTOM_GETCHROMSIZES": { + "getchromsizes": 1.2 + }, + "DEEPTOOLS_BAMCOVERAGE_MINUS": { + "deeptools": "3.5.5" + }, + "DEEPTOOLS_BAMCOVERAGE_PLUS": { + "deeptools": "3.5.5" + }, + "FASTP": { + "fastp": "0.23.4" + }, + "FASTQC": { + "fastqc": "0.12.1" + }, + "GTF2BED": { + "perl": "5.26.2" + }, + "HOMER_MAKETAGDIRECTORY": { + "homer": 4.11, + "samtools": 1.21 + }, + "PINTS_CALLER": { + "python": "3.12.6", + "pints": "1.1.13" + }, + "PRESEQ_CCURVE": { + "preseq": "3.1.1" + }, + "PRESEQ_LCEXTRAP": { + "preseq": "3.1.1" + }, + "RSEQC_INFEREXPERIMENT": { + "rseqc": "5.0.2" + }, + "RSEQC_READDISTRIBUTION": { + "rseqc": "5.0.2" + }, + "RSEQC_READDUPLICATION": { + "rseqc": "5.0.2" + }, + "SAMTOOLS_MERGE": { + "samtools": 1.21 + }, + "SUBREAD_FEATURECOUNTS_GENE": { + "subread": "2.0.1" + }, + "SUBREAD_FEATURECOUNTS_PREDICTED": { + "subread": "2.0.1" + }, + "Workflow": { + "nf-core/nascent": "v2.3.0" + } + }, + [ + "bwa", + "bwa/cd4_REP1.sorted.bam", + "bwa/cd4_REP1.sorted.bam.bai", + "bwa/cd4_REP2.sorted.bam", + "bwa/cd4_REP2.sorted.bam.bai", + "bwa/jurkat.sorted.bam", + "bwa/jurkat.sorted.bam.bai", + "bwa/samtools_stats", + "bwa/samtools_stats/cd4_REP1.sorted.bam.flagstat", + "bwa/samtools_stats/cd4_REP1.sorted.bam.idxstats", + "bwa/samtools_stats/cd4_REP1.sorted.bam.stats", + "bwa/samtools_stats/cd4_REP2.sorted.bam.flagstat", + "bwa/samtools_stats/cd4_REP2.sorted.bam.idxstats", + "bwa/samtools_stats/cd4_REP2.sorted.bam.stats", + "bwa/samtools_stats/jurkat.sorted.bam.flagstat", + "bwa/samtools_stats/jurkat.sorted.bam.idxstats", + "bwa/samtools_stats/jurkat.sorted.bam.stats", + "cat", + "cat/cd4.bed", + "cat/jurkat.bed", + "coverage_graphs", + "coverage_graphs/cd4_REP1.dreg.bedGraph", + "coverage_graphs/cd4_REP1.minus.bedGraph", + "coverage_graphs/cd4_REP1.minus.bigWig", + "coverage_graphs/cd4_REP1.plus.bedGraph", + "coverage_graphs/cd4_REP1.plus.bigWig", + "coverage_graphs/cd4_REP2.dreg.bedGraph", + "coverage_graphs/cd4_REP2.minus.bedGraph", + "coverage_graphs/cd4_REP2.minus.bigWig", + "coverage_graphs/cd4_REP2.plus.bedGraph", + "coverage_graphs/cd4_REP2.plus.bigWig", + "coverage_graphs/jurkat.dreg.bedGraph", + "coverage_graphs/jurkat.minus.bedGraph", + "coverage_graphs/jurkat.minus.bigWig", + "coverage_graphs/jurkat.plus.bedGraph", + "coverage_graphs/jurkat.plus.bigWig", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_data/fastqc-status-check-heatmap.txt", + "multiqc/multiqc_data/fastqc_adapter_content_plot.txt", + "multiqc/multiqc_data/fastqc_overrepresented_sequences_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_n_content_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_sequence_quality_plot.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Counts.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Percentages.txt", + "multiqc/multiqc_data/fastqc_per_sequence_quality_scores_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_counts_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_duplication_levels_plot.txt", + "multiqc/multiqc_data/fastqc_top_overrepresented_sequences_table.txt", + "multiqc/multiqc_data/homer-tag-directory-gc-content.txt", + "multiqc/multiqc_data/homer-tag-info-dist.txt", + "multiqc/multiqc_data/homer-tag-length-dist.txt", + "multiqc/multiqc_data/homer_tagdir.txt", + "multiqc/multiqc_data/multiqc.log", + "multiqc/multiqc_data/multiqc_citations.txt", + "multiqc/multiqc_data/multiqc_data.json", + "multiqc/multiqc_data/multiqc_fastqc.txt", + "multiqc/multiqc_data/multiqc_general_stats.txt", + "multiqc/multiqc_data/multiqc_rseqc_infer_experiment.txt", + "multiqc/multiqc_data/multiqc_rseqc_read_distribution.txt", + "multiqc/multiqc_data/multiqc_samtools_flagstat.txt", + "multiqc/multiqc_data/multiqc_samtools_idxstats.txt", + "multiqc/multiqc_data/multiqc_samtools_stats.txt", + "multiqc/multiqc_data/multiqc_software_versions.txt", + "multiqc/multiqc_data/multiqc_sources.txt", + "multiqc/multiqc_data/preseq.txt", + "multiqc/multiqc_data/preseq_complexity_plot_molecules.txt", + "multiqc/multiqc_data/rseqc_infer_experiment_plot.txt", + "multiqc/multiqc_data/rseqc_read_distribution_plot.txt", + "multiqc/multiqc_data/rseqc_read_dups.txt", + "multiqc/multiqc_data/rseqc_read_dups_plot.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Percentage_of_total.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Read_counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Normalised_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Observed_over_Expected_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Raw_Counts.txt", + "multiqc/multiqc_data/samtools-stats-dp.txt", + "multiqc/multiqc_data/samtools_alignment_plot.txt", + "multiqc/multiqc_report.html", + "pipeline_info", + "pipeline_info/nf_core_nascent_software_mqc_versions.yml", + "preprocessing", + "preprocessing/fastp", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.log", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.log", + "preprocessing/fastp/jurkat.trimmed.fastp.html", + "preprocessing/fastp/jurkat.trimmed.fastp.json", + "preprocessing/fastp/jurkat.trimmed.fastp.log", + "preprocessing/fastqc", + "preprocessing/fastqc/cd4_REP1_fastqc.html", + "preprocessing/fastqc/cd4_REP1_fastqc.zip", + "preprocessing/fastqc/cd4_REP2_fastqc.html", + "preprocessing/fastqc/cd4_REP2_fastqc.zip", + "preprocessing/fastqc/jurkat_fastqc.html", + "preprocessing/fastqc/jurkat_fastqc.zip", + "quality_control", + "quality_control/bbsplit", + "quality_control/bbsplit/cd4_REP1.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP1.coverage.stats.txt", + "quality_control/bbsplit/cd4_REP2.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP2.coverage.stats.txt", + "quality_control/bbsplit/jurkat.coverage.hist.txt", + "quality_control/bbsplit/jurkat.coverage.stats.txt", + "quality_control/preseq", + "quality_control/preseq/cd4_REP1.c_curve.txt", + "quality_control/preseq/cd4_REP1.lc_extrap.txt", + "quality_control/preseq/cd4_REP2.c_curve.txt", + "quality_control/preseq/cd4_REP2.lc_extrap.txt", + "quality_control/preseq/jurkat.c_curve.txt", + "quality_control/preseq/jurkat.lc_extrap.txt", + "quality_control/preseq/log", + "quality_control/preseq/log/cd4_REP1.command.log", + "quality_control/preseq/log/cd4_REP2.command.log", + "quality_control/preseq/log/jurkat.command.log", + "quality_control/rseqc", + "quality_control/rseqc/infer_experiment", + "quality_control/rseqc/infer_experiment/cd4_REP1.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/cd4_REP2.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/jurkat.infer_experiment.txt", + "quality_control/rseqc/read_distribution", + "quality_control/rseqc/read_distribution/cd4_REP1.read_distribution.txt", + "quality_control/rseqc/read_distribution/cd4_REP2.read_distribution.txt", + "quality_control/rseqc/read_distribution/jurkat.read_distribution.txt", + "quality_control/rseqc/read_duplication", + "quality_control/rseqc/read_duplication/pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP1.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP2.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/jurkat.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/rscript", + "quality_control/rseqc/read_duplication/rscript/cd4_REP1.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/cd4_REP2.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/jurkat.DupRate_plot.r", + "quality_control/rseqc/read_duplication/xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.seq.DupRate.xls", + "quantification", + "quantification/gene", + "quantification/gene/cd4.featureCounts.txt", + "quantification/gene/cd4.featureCounts.txt.summary", + "quantification/gene/jurkat.featureCounts.txt", + "quantification/gene/jurkat.featureCounts.txt.summary", + "quantification/nascent", + "quantification/nascent/cd4-group_cd4_intersect-transcripts.featureCounts.txt", + "quantification/nascent/cd4-group_cd4_intersect-transcripts.featureCounts.txt.summary", + "quantification/nascent/jurkat-group_cd4_intersect-transcripts.featureCounts.txt", + "quantification/nascent/jurkat-group_cd4_intersect-transcripts.featureCounts.txt.summary", + "samtools", + "samtools/cd4.bam", + "samtools/jurkat.bam", + "transcript_identification", + "transcript_identification/filtered", + "transcript_identification/filtered/cd4_filtered.bed", + "transcript_identification/filtered/jurkat_filtered.bed", + "transcript_identification/homer", + "transcript_identification/homer/cd4.bed", + "transcript_identification/homer/cd4.bedGraph.gz", + "transcript_identification/homer/cd4.peaks.txt", + "transcript_identification/homer/cd4_tagdir", + "transcript_identification/homer/cd4_tagdir/chr21.tags.tsv", + "transcript_identification/homer/cd4_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/cd4_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/cd4_tagdir/tagFreq.txt", + "transcript_identification/homer/cd4_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/cd4_tagdir/tagGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagInfo.txt", + "transcript_identification/homer/cd4_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/jurkat.bed", + "transcript_identification/homer/jurkat.bedGraph.gz", + "transcript_identification/homer/jurkat.peaks.txt", + "transcript_identification/homer/jurkat_tagdir", + "transcript_identification/homer/jurkat_tagdir/chr21.tags.tsv", + "transcript_identification/homer/jurkat_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/jurkat_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreq.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/jurkat_tagdir/tagGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagInfo.txt", + "transcript_identification/homer/jurkat_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/versions.yml", + "transcript_identification/intersect", + "transcript_identification/intersect/cd4_intersect.bed", + "transcript_identification/intersect/jurkat_intersect.bed", + "transcript_identification/merged", + "transcript_identification/merged/cd4_merged.bed", + "transcript_identification/merged/jurkat_merged.bed", + "transcript_identification/pints", + "transcript_identification/pints/cd4_chr21_1_unidirectional_peaks.bed", + "transcript_identification/pints/jurkat_chr21_1_unidirectional_peaks.bed" + ], + [ + "cd4_REP1.sorted.bam.flagstat:md5,863e2d506d5cc4239af98a5f31bbc906", + "cd4_REP1.sorted.bam.idxstats:md5,b1dd8bcbd23c53c21f0e11082d9315f2", + "cd4_REP1.sorted.bam.stats:md5,70b7cd3040a9b7ca70e919afb4dc7fea", + "cd4_REP2.sorted.bam.flagstat:md5,0fd86dbf8f799fad49ba471702979bdc", + "cd4_REP2.sorted.bam.idxstats:md5,53204e4c6a9f68664087e4a8123be46a", + "cd4_REP2.sorted.bam.stats:md5,c0e8d8d265fce71dcd43e43c93d29ef3", + "jurkat.sorted.bam.flagstat:md5,fd5f02b0f02a407447b804b1d80f5421", + "jurkat.sorted.bam.idxstats:md5,c61af0847c1ad76c06a8de2815975b32", + "jurkat.sorted.bam.stats:md5,c9a6ec83d8fb1a14f53351c76cfcd24b", + "cd4.bed:md5,0193e58943726af89bfd00e9da2536d8", + "jurkat.bed:md5,cb6932229eea2e09f61d48d7dd397ae1", + "cd4_REP1.dreg.bedGraph:md5,8948a8fa86d8f6d413b77983189ff56e", + "cd4_REP1.minus.bedGraph:md5,2a1c34f9d9ef9ff1b9da7874b9e3aaad", + "cd4_REP1.minus.bigWig:md5,5280319275c98dcce023779fa389884d", + "cd4_REP1.plus.bedGraph:md5,1509ec3a921e3109c5914e1bcef8cf33", + "cd4_REP1.plus.bigWig:md5,72ccab3173f2018a22a4b36841247ba2", + "cd4_REP2.dreg.bedGraph:md5,29f865a5668fae4a52a41589ac2b3179", + "cd4_REP2.minus.bedGraph:md5,c530bc34fa3ec7ac49e88ff65f9c2f92", + "cd4_REP2.minus.bigWig:md5,5e748c794e037f441741f7f409c8c5ad", + "cd4_REP2.plus.bedGraph:md5,a675141da2874ec08d91591e5ea8242b", + "cd4_REP2.plus.bigWig:md5,08674d52e9eeb08807c33ed3e4b3d504", + "jurkat.dreg.bedGraph:md5,c25a4fb095e9f7d6766a3ce33e08f7d8", + "jurkat.minus.bedGraph:md5,8d5d9a41df6eb6c56b1bfd3f39dc1fc6", + "jurkat.minus.bigWig:md5,d06c8015c996bf520fff17266fd01f84", + "jurkat.plus.bedGraph:md5,6ed63e5983edaa74fb3965676efdb674", + "jurkat.plus.bigWig:md5,7a02334f2c7300ffdb5a2253c0937390", + "cd4_REP1.trimmed.fastp.json:md5,bd9a3344c1591d6be4d524451f9dca53", + "cd4_REP2.trimmed.fastp.json:md5,bc6e3f9ff7835f220535cc393b8eb25f", + "jurkat.trimmed.fastp.json:md5,65f7247a87479c7157c7357d575336e2", + "cd4.bed:md5,b55e5290d78941f36c3d1ecfef8e0062", + "cd4.peaks.txt:md5,bdcd2ec3a56a8a4a01ed19e17da003f2", + "jurkat.bed:md5,383cfaf10535dbe5d7f47607e345f4cb", + "jurkat.peaks.txt:md5,d4914194eca6f06aadfe7eed08ab1bb8", + "versions.yml:md5,7c0dcd0a18b3c753def73b96cb825792", + "cd4_merged.bed:md5,9ace0ca4f1544bb0949355a20de98e6b", + "jurkat_merged.bed:md5,f1dde43c4ad9dec972ff9fa38cc6f2fe", + "cd4_chr21_1_unidirectional_peaks.bed:md5,0193e58943726af89bfd00e9da2536d8", + "jurkat_chr21_1_unidirectional_peaks.bed:md5,cb6932229eea2e09f61d48d7dd397ae1" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-28T21:50:29.316626" + } +} \ No newline at end of file diff --git a/workflows/tests/inputs/gzipped_gff/main.nf.test b/workflows/tests/inputs/gzipped_gff/main.nf.test new file mode 100644 index 00000000..33bc949f --- /dev/null +++ b/workflows/tests/inputs/gzipped_gff/main.nf.test @@ -0,0 +1,41 @@ +nextflow_pipeline { + + name "gzipped GFF" + script "../../../../main.nf" + tag "input" + tag "gff" + + test("Should run with a gzipped GFF file") { + + when { + params { + outdir = "$outputDir" + gff = 'https://raw.githubusercontent.com/nf-core/test-datasets/nascent/reference/genes_chr21.gff.gz' + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}', 'multiqc/multiqc_plots', 'multiqc/multiqc_plots/**']) + // stable_path: All files in ${params.outdir}/ with stable content + def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') + // bam_files: All bam files + def bam_files = getAllFilesFromDir(params.outdir, include: ['**/*.bam']) + assertAll( + { assert workflow.success }, + { assert snapshot( + // Number of 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_nascent_software_mqc_versions.yml"), + // All stable path name + stable_name, + // All files with stable contents + stable_path, + // All bam files + // FIXME bam_files.collect{ file -> [ file.getName(), bam(file.toString()).getReadsMD5() ] } + ).match() } + ) + } + } +} diff --git a/workflows/tests/inputs/gzipped_gff/main.nf.test.snap b/workflows/tests/inputs/gzipped_gff/main.nf.test.snap new file mode 100644 index 00000000..e68bfc2c --- /dev/null +++ b/workflows/tests/inputs/gzipped_gff/main.nf.test.snap @@ -0,0 +1,340 @@ +{ + "Should run with a gzipped GFF file": { + "content": [ + 92, + { + "BBMAP_PILEUP": { + "bbmap": 39.01, + "samtools": "1.16.1", + "pigz": 2.6 + }, + "BEDTOOLS_GENOMECOV_MINUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_GENOMECOV_PLUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT_FILTER": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_MERGE": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_SORT": { + "bedtools": "2.31.1" + }, + "BWA_INDEX": { + "bwa": "0.7.18-r1243-dirty" + }, + "BWA_MEM": { + "bwa": "0.7.18-r1243-dirty", + "samtools": 1.2 + }, + "CAT_CAT": { + "pigz": "2.3.4" + }, + "CUSTOM_GETCHROMSIZES": { + "getchromsizes": 1.2 + }, + "DEEPTOOLS_BAMCOVERAGE_MINUS": { + "deeptools": "3.5.5" + }, + "DEEPTOOLS_BAMCOVERAGE_PLUS": { + "deeptools": "3.5.5" + }, + "FASTP": { + "fastp": "0.23.4" + }, + "FASTQC": { + "fastqc": "0.12.1" + }, + "GTF2BED": { + "perl": "5.26.2" + }, + "HOMER_MAKETAGDIRECTORY": { + "homer": 4.11, + "samtools": 1.21 + }, + "PINTS_CALLER": { + "python": "3.12.6", + "pints": "1.1.13" + }, + "PRESEQ_CCURVE": { + "preseq": "3.1.1" + }, + "PRESEQ_LCEXTRAP": { + "preseq": "3.1.1" + }, + "RSEQC_INFEREXPERIMENT": { + "rseqc": "5.0.2" + }, + "RSEQC_READDISTRIBUTION": { + "rseqc": "5.0.2" + }, + "RSEQC_READDUPLICATION": { + "rseqc": "5.0.2" + }, + "SAMTOOLS_MERGE": { + "samtools": 1.21 + }, + "SUBREAD_FEATURECOUNTS_GENE": { + "subread": "2.0.1" + }, + "SUBREAD_FEATURECOUNTS_PREDICTED": { + "subread": "2.0.1" + }, + "Workflow": { + "nf-core/nascent": "v2.3.0" + } + }, + [ + "bwa", + "bwa/cd4_REP1.sorted.bam", + "bwa/cd4_REP1.sorted.bam.bai", + "bwa/cd4_REP2.sorted.bam", + "bwa/cd4_REP2.sorted.bam.bai", + "bwa/jurkat.sorted.bam", + "bwa/jurkat.sorted.bam.bai", + "bwa/samtools_stats", + "bwa/samtools_stats/cd4_REP1.sorted.bam.flagstat", + "bwa/samtools_stats/cd4_REP1.sorted.bam.idxstats", + "bwa/samtools_stats/cd4_REP1.sorted.bam.stats", + "bwa/samtools_stats/cd4_REP2.sorted.bam.flagstat", + "bwa/samtools_stats/cd4_REP2.sorted.bam.idxstats", + "bwa/samtools_stats/cd4_REP2.sorted.bam.stats", + "bwa/samtools_stats/jurkat.sorted.bam.flagstat", + "bwa/samtools_stats/jurkat.sorted.bam.idxstats", + "bwa/samtools_stats/jurkat.sorted.bam.stats", + "cat", + "cat/cd4.bed", + "cat/jurkat.bed", + "coverage_graphs", + "coverage_graphs/cd4_REP1.dreg.bedGraph", + "coverage_graphs/cd4_REP1.minus.bedGraph", + "coverage_graphs/cd4_REP1.minus.bigWig", + "coverage_graphs/cd4_REP1.plus.bedGraph", + "coverage_graphs/cd4_REP1.plus.bigWig", + "coverage_graphs/cd4_REP2.dreg.bedGraph", + "coverage_graphs/cd4_REP2.minus.bedGraph", + "coverage_graphs/cd4_REP2.minus.bigWig", + "coverage_graphs/cd4_REP2.plus.bedGraph", + "coverage_graphs/cd4_REP2.plus.bigWig", + "coverage_graphs/jurkat.dreg.bedGraph", + "coverage_graphs/jurkat.minus.bedGraph", + "coverage_graphs/jurkat.minus.bigWig", + "coverage_graphs/jurkat.plus.bedGraph", + "coverage_graphs/jurkat.plus.bigWig", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_data/fastqc-status-check-heatmap.txt", + "multiqc/multiqc_data/fastqc_adapter_content_plot.txt", + "multiqc/multiqc_data/fastqc_overrepresented_sequences_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_n_content_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_sequence_quality_plot.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Counts.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Percentages.txt", + "multiqc/multiqc_data/fastqc_per_sequence_quality_scores_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_counts_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_duplication_levels_plot.txt", + "multiqc/multiqc_data/fastqc_top_overrepresented_sequences_table.txt", + "multiqc/multiqc_data/homer-tag-directory-gc-content.txt", + "multiqc/multiqc_data/homer-tag-info-dist.txt", + "multiqc/multiqc_data/homer-tag-length-dist.txt", + "multiqc/multiqc_data/homer_tagdir.txt", + "multiqc/multiqc_data/multiqc.log", + "multiqc/multiqc_data/multiqc_citations.txt", + "multiqc/multiqc_data/multiqc_data.json", + "multiqc/multiqc_data/multiqc_fastqc.txt", + "multiqc/multiqc_data/multiqc_general_stats.txt", + "multiqc/multiqc_data/multiqc_rseqc_infer_experiment.txt", + "multiqc/multiqc_data/multiqc_rseqc_read_distribution.txt", + "multiqc/multiqc_data/multiqc_samtools_flagstat.txt", + "multiqc/multiqc_data/multiqc_samtools_idxstats.txt", + "multiqc/multiqc_data/multiqc_samtools_stats.txt", + "multiqc/multiqc_data/multiqc_software_versions.txt", + "multiqc/multiqc_data/multiqc_sources.txt", + "multiqc/multiqc_data/preseq.txt", + "multiqc/multiqc_data/preseq_complexity_plot_molecules.txt", + "multiqc/multiqc_data/rseqc_infer_experiment_plot.txt", + "multiqc/multiqc_data/rseqc_read_distribution_plot.txt", + "multiqc/multiqc_data/rseqc_read_dups.txt", + "multiqc/multiqc_data/rseqc_read_dups_plot.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Percentage_of_total.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Read_counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Normalised_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Observed_over_Expected_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Raw_Counts.txt", + "multiqc/multiqc_data/samtools-stats-dp.txt", + "multiqc/multiqc_data/samtools_alignment_plot.txt", + "multiqc/multiqc_report.html", + "pipeline_info", + "pipeline_info/nf_core_nascent_software_mqc_versions.yml", + "preprocessing", + "preprocessing/fastp", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.log", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.log", + "preprocessing/fastp/jurkat.trimmed.fastp.html", + "preprocessing/fastp/jurkat.trimmed.fastp.json", + "preprocessing/fastp/jurkat.trimmed.fastp.log", + "preprocessing/fastqc", + "preprocessing/fastqc/cd4_REP1_fastqc.html", + "preprocessing/fastqc/cd4_REP1_fastqc.zip", + "preprocessing/fastqc/cd4_REP2_fastqc.html", + "preprocessing/fastqc/cd4_REP2_fastqc.zip", + "preprocessing/fastqc/jurkat_fastqc.html", + "preprocessing/fastqc/jurkat_fastqc.zip", + "quality_control", + "quality_control/bbsplit", + "quality_control/bbsplit/cd4_REP1.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP1.coverage.stats.txt", + "quality_control/bbsplit/cd4_REP2.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP2.coverage.stats.txt", + "quality_control/bbsplit/jurkat.coverage.hist.txt", + "quality_control/bbsplit/jurkat.coverage.stats.txt", + "quality_control/preseq", + "quality_control/preseq/cd4_REP1.c_curve.txt", + "quality_control/preseq/cd4_REP1.lc_extrap.txt", + "quality_control/preseq/cd4_REP2.c_curve.txt", + "quality_control/preseq/cd4_REP2.lc_extrap.txt", + "quality_control/preseq/jurkat.c_curve.txt", + "quality_control/preseq/jurkat.lc_extrap.txt", + "quality_control/preseq/log", + "quality_control/preseq/log/cd4_REP1.command.log", + "quality_control/preseq/log/cd4_REP2.command.log", + "quality_control/preseq/log/jurkat.command.log", + "quality_control/rseqc", + "quality_control/rseqc/infer_experiment", + "quality_control/rseqc/infer_experiment/cd4_REP1.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/cd4_REP2.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/jurkat.infer_experiment.txt", + "quality_control/rseqc/read_distribution", + "quality_control/rseqc/read_distribution/cd4_REP1.read_distribution.txt", + "quality_control/rseqc/read_distribution/cd4_REP2.read_distribution.txt", + "quality_control/rseqc/read_distribution/jurkat.read_distribution.txt", + "quality_control/rseqc/read_duplication", + "quality_control/rseqc/read_duplication/pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP1.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP2.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/jurkat.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/rscript", + "quality_control/rseqc/read_duplication/rscript/cd4_REP1.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/cd4_REP2.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/jurkat.DupRate_plot.r", + "quality_control/rseqc/read_duplication/xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.seq.DupRate.xls", + "quantification", + "quantification/gene", + "quantification/gene/cd4.featureCounts.txt", + "quantification/gene/cd4.featureCounts.txt.summary", + "quantification/gene/jurkat.featureCounts.txt", + "quantification/gene/jurkat.featureCounts.txt.summary", + "quantification/nascent", + "quantification/nascent/cd4-group_cd4_intersect-transcripts.featureCounts.txt", + "quantification/nascent/cd4-group_cd4_intersect-transcripts.featureCounts.txt.summary", + "quantification/nascent/jurkat-group_cd4_intersect-transcripts.featureCounts.txt", + "quantification/nascent/jurkat-group_cd4_intersect-transcripts.featureCounts.txt.summary", + "samtools", + "samtools/cd4.bam", + "samtools/jurkat.bam", + "transcript_identification", + "transcript_identification/filtered", + "transcript_identification/filtered/cd4_filtered.bed", + "transcript_identification/filtered/jurkat_filtered.bed", + "transcript_identification/homer", + "transcript_identification/homer/cd4.bed", + "transcript_identification/homer/cd4.bedGraph.gz", + "transcript_identification/homer/cd4.peaks.txt", + "transcript_identification/homer/cd4_tagdir", + "transcript_identification/homer/cd4_tagdir/chr21.tags.tsv", + "transcript_identification/homer/cd4_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/cd4_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/cd4_tagdir/tagFreq.txt", + "transcript_identification/homer/cd4_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/cd4_tagdir/tagGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagInfo.txt", + "transcript_identification/homer/cd4_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/jurkat.bed", + "transcript_identification/homer/jurkat.bedGraph.gz", + "transcript_identification/homer/jurkat.peaks.txt", + "transcript_identification/homer/jurkat_tagdir", + "transcript_identification/homer/jurkat_tagdir/chr21.tags.tsv", + "transcript_identification/homer/jurkat_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/jurkat_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreq.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/jurkat_tagdir/tagGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagInfo.txt", + "transcript_identification/homer/jurkat_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/versions.yml", + "transcript_identification/intersect", + "transcript_identification/intersect/cd4_intersect.bed", + "transcript_identification/intersect/jurkat_intersect.bed", + "transcript_identification/merged", + "transcript_identification/merged/cd4_merged.bed", + "transcript_identification/merged/jurkat_merged.bed", + "transcript_identification/pints", + "transcript_identification/pints/cd4_chr21_1_unidirectional_peaks.bed", + "transcript_identification/pints/jurkat_chr21_1_unidirectional_peaks.bed" + ], + [ + "cd4_REP1.sorted.bam.flagstat:md5,863e2d506d5cc4239af98a5f31bbc906", + "cd4_REP1.sorted.bam.idxstats:md5,b1dd8bcbd23c53c21f0e11082d9315f2", + "cd4_REP1.sorted.bam.stats:md5,70b7cd3040a9b7ca70e919afb4dc7fea", + "cd4_REP2.sorted.bam.flagstat:md5,0fd86dbf8f799fad49ba471702979bdc", + "cd4_REP2.sorted.bam.idxstats:md5,53204e4c6a9f68664087e4a8123be46a", + "cd4_REP2.sorted.bam.stats:md5,c0e8d8d265fce71dcd43e43c93d29ef3", + "jurkat.sorted.bam.flagstat:md5,fd5f02b0f02a407447b804b1d80f5421", + "jurkat.sorted.bam.idxstats:md5,c61af0847c1ad76c06a8de2815975b32", + "jurkat.sorted.bam.stats:md5,c9a6ec83d8fb1a14f53351c76cfcd24b", + "cd4.bed:md5,0193e58943726af89bfd00e9da2536d8", + "jurkat.bed:md5,cb6932229eea2e09f61d48d7dd397ae1", + "cd4_REP1.dreg.bedGraph:md5,8948a8fa86d8f6d413b77983189ff56e", + "cd4_REP1.minus.bedGraph:md5,2a1c34f9d9ef9ff1b9da7874b9e3aaad", + "cd4_REP1.minus.bigWig:md5,5280319275c98dcce023779fa389884d", + "cd4_REP1.plus.bedGraph:md5,1509ec3a921e3109c5914e1bcef8cf33", + "cd4_REP1.plus.bigWig:md5,72ccab3173f2018a22a4b36841247ba2", + "cd4_REP2.dreg.bedGraph:md5,29f865a5668fae4a52a41589ac2b3179", + "cd4_REP2.minus.bedGraph:md5,c530bc34fa3ec7ac49e88ff65f9c2f92", + "cd4_REP2.minus.bigWig:md5,5e748c794e037f441741f7f409c8c5ad", + "cd4_REP2.plus.bedGraph:md5,a675141da2874ec08d91591e5ea8242b", + "cd4_REP2.plus.bigWig:md5,08674d52e9eeb08807c33ed3e4b3d504", + "jurkat.dreg.bedGraph:md5,c25a4fb095e9f7d6766a3ce33e08f7d8", + "jurkat.minus.bedGraph:md5,8d5d9a41df6eb6c56b1bfd3f39dc1fc6", + "jurkat.minus.bigWig:md5,d06c8015c996bf520fff17266fd01f84", + "jurkat.plus.bedGraph:md5,6ed63e5983edaa74fb3965676efdb674", + "jurkat.plus.bigWig:md5,7a02334f2c7300ffdb5a2253c0937390", + "cd4_REP1.trimmed.fastp.json:md5,bd9a3344c1591d6be4d524451f9dca53", + "cd4_REP2.trimmed.fastp.json:md5,bc6e3f9ff7835f220535cc393b8eb25f", + "jurkat.trimmed.fastp.json:md5,65f7247a87479c7157c7357d575336e2", + "cd4.bed:md5,b55e5290d78941f36c3d1ecfef8e0062", + "cd4.peaks.txt:md5,bdcd2ec3a56a8a4a01ed19e17da003f2", + "jurkat.bed:md5,383cfaf10535dbe5d7f47607e345f4cb", + "jurkat.peaks.txt:md5,d4914194eca6f06aadfe7eed08ab1bb8", + "versions.yml:md5,7c0dcd0a18b3c753def73b96cb825792", + "cd4_merged.bed:md5,9ace0ca4f1544bb0949355a20de98e6b", + "jurkat_merged.bed:md5,f1dde43c4ad9dec972ff9fa38cc6f2fe", + "cd4_chr21_1_unidirectional_peaks.bed:md5,0193e58943726af89bfd00e9da2536d8", + "jurkat_chr21_1_unidirectional_peaks.bed:md5,cb6932229eea2e09f61d48d7dd397ae1" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-28T21:51:56.754194" + } +} \ No newline at end of file diff --git a/workflows/tests/inputs/only_gff/main.nf.test b/workflows/tests/inputs/only_gff/main.nf.test new file mode 100644 index 00000000..b9fd1389 --- /dev/null +++ b/workflows/tests/inputs/only_gff/main.nf.test @@ -0,0 +1,43 @@ +nextflow_pipeline { + + name "GFF" + script "../../../../main.nf" + tag "input" + tag "gff" + + test("Should run with only a GFF file") { + + when { + params { + outdir = "$outputDir" + gff = 'https://raw.githubusercontent.com/nf-core/test-datasets/nascent/reference/genes_chr21.gff' + gtf = null + bed = null + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}', 'multiqc/multiqc_plots', 'multiqc/multiqc_plots/**']) + // stable_path: All files in ${params.outdir}/ with stable content + def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') + // bam_files: All bam files + def bam_files = getAllFilesFromDir(params.outdir, include: ['**/*.bam']) + assertAll( + { assert workflow.success }, + { assert snapshot( + // Number of 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_nascent_software_mqc_versions.yml"), + // All stable path name + stable_name, + // All files with stable contents + stable_path, + // All bam files + // FIXME bam_files.collect{ file -> [ file.getName(), bam(file.toString()).getReadsMD5() ] } + ).match() } + ) + } + } +} diff --git a/workflows/tests/inputs/only_gff/main.nf.test.snap b/workflows/tests/inputs/only_gff/main.nf.test.snap new file mode 100644 index 00000000..683a1fe9 --- /dev/null +++ b/workflows/tests/inputs/only_gff/main.nf.test.snap @@ -0,0 +1,343 @@ +{ + "Should run with only a GFF file": { + "content": [ + 93, + { + "BBMAP_PILEUP": { + "bbmap": 39.01, + "samtools": "1.16.1", + "pigz": 2.6 + }, + "BEDTOOLS_GENOMECOV_MINUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_GENOMECOV_PLUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT_FILTER": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_MERGE": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_SORT": { + "bedtools": "2.31.1" + }, + "BWA_INDEX": { + "bwa": "0.7.18-r1243-dirty" + }, + "BWA_MEM": { + "bwa": "0.7.18-r1243-dirty", + "samtools": 1.2 + }, + "CAT_CAT": { + "pigz": "2.3.4" + }, + "CUSTOM_GETCHROMSIZES": { + "getchromsizes": 1.2 + }, + "DEEPTOOLS_BAMCOVERAGE_MINUS": { + "deeptools": "3.5.5" + }, + "DEEPTOOLS_BAMCOVERAGE_PLUS": { + "deeptools": "3.5.5" + }, + "FASTP": { + "fastp": "0.23.4" + }, + "FASTQC": { + "fastqc": "0.12.1" + }, + "GFFREAD": { + "gffread": "0.12.7" + }, + "GTF2BED": { + "perl": "5.26.2" + }, + "HOMER_MAKETAGDIRECTORY": { + "homer": 4.11, + "samtools": 1.21 + }, + "PINTS_CALLER": { + "python": "3.12.6", + "pints": "1.1.13" + }, + "PRESEQ_CCURVE": { + "preseq": "3.1.1" + }, + "PRESEQ_LCEXTRAP": { + "preseq": "3.1.1" + }, + "RSEQC_INFEREXPERIMENT": { + "rseqc": "5.0.2" + }, + "RSEQC_READDISTRIBUTION": { + "rseqc": "5.0.2" + }, + "RSEQC_READDUPLICATION": { + "rseqc": "5.0.2" + }, + "SAMTOOLS_MERGE": { + "samtools": 1.21 + }, + "SUBREAD_FEATURECOUNTS_GENE": { + "subread": "2.0.1" + }, + "SUBREAD_FEATURECOUNTS_PREDICTED": { + "subread": "2.0.1" + }, + "Workflow": { + "nf-core/nascent": "v2.3.0" + } + }, + [ + "bwa", + "bwa/cd4_REP1.sorted.bam", + "bwa/cd4_REP1.sorted.bam.bai", + "bwa/cd4_REP2.sorted.bam", + "bwa/cd4_REP2.sorted.bam.bai", + "bwa/jurkat.sorted.bam", + "bwa/jurkat.sorted.bam.bai", + "bwa/samtools_stats", + "bwa/samtools_stats/cd4_REP1.sorted.bam.flagstat", + "bwa/samtools_stats/cd4_REP1.sorted.bam.idxstats", + "bwa/samtools_stats/cd4_REP1.sorted.bam.stats", + "bwa/samtools_stats/cd4_REP2.sorted.bam.flagstat", + "bwa/samtools_stats/cd4_REP2.sorted.bam.idxstats", + "bwa/samtools_stats/cd4_REP2.sorted.bam.stats", + "bwa/samtools_stats/jurkat.sorted.bam.flagstat", + "bwa/samtools_stats/jurkat.sorted.bam.idxstats", + "bwa/samtools_stats/jurkat.sorted.bam.stats", + "cat", + "cat/cd4.bed", + "cat/jurkat.bed", + "coverage_graphs", + "coverage_graphs/cd4_REP1.dreg.bedGraph", + "coverage_graphs/cd4_REP1.minus.bedGraph", + "coverage_graphs/cd4_REP1.minus.bigWig", + "coverage_graphs/cd4_REP1.plus.bedGraph", + "coverage_graphs/cd4_REP1.plus.bigWig", + "coverage_graphs/cd4_REP2.dreg.bedGraph", + "coverage_graphs/cd4_REP2.minus.bedGraph", + "coverage_graphs/cd4_REP2.minus.bigWig", + "coverage_graphs/cd4_REP2.plus.bedGraph", + "coverage_graphs/cd4_REP2.plus.bigWig", + "coverage_graphs/jurkat.dreg.bedGraph", + "coverage_graphs/jurkat.minus.bedGraph", + "coverage_graphs/jurkat.minus.bigWig", + "coverage_graphs/jurkat.plus.bedGraph", + "coverage_graphs/jurkat.plus.bigWig", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_data/fastqc-status-check-heatmap.txt", + "multiqc/multiqc_data/fastqc_adapter_content_plot.txt", + "multiqc/multiqc_data/fastqc_overrepresented_sequences_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_n_content_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_sequence_quality_plot.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Counts.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Percentages.txt", + "multiqc/multiqc_data/fastqc_per_sequence_quality_scores_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_counts_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_duplication_levels_plot.txt", + "multiqc/multiqc_data/fastqc_top_overrepresented_sequences_table.txt", + "multiqc/multiqc_data/homer-tag-directory-gc-content.txt", + "multiqc/multiqc_data/homer-tag-info-dist.txt", + "multiqc/multiqc_data/homer-tag-length-dist.txt", + "multiqc/multiqc_data/homer_tagdir.txt", + "multiqc/multiqc_data/multiqc.log", + "multiqc/multiqc_data/multiqc_citations.txt", + "multiqc/multiqc_data/multiqc_data.json", + "multiqc/multiqc_data/multiqc_fastqc.txt", + "multiqc/multiqc_data/multiqc_general_stats.txt", + "multiqc/multiqc_data/multiqc_rseqc_infer_experiment.txt", + "multiqc/multiqc_data/multiqc_rseqc_read_distribution.txt", + "multiqc/multiqc_data/multiqc_samtools_flagstat.txt", + "multiqc/multiqc_data/multiqc_samtools_idxstats.txt", + "multiqc/multiqc_data/multiqc_samtools_stats.txt", + "multiqc/multiqc_data/multiqc_software_versions.txt", + "multiqc/multiqc_data/multiqc_sources.txt", + "multiqc/multiqc_data/preseq.txt", + "multiqc/multiqc_data/preseq_complexity_plot_molecules.txt", + "multiqc/multiqc_data/rseqc_infer_experiment_plot.txt", + "multiqc/multiqc_data/rseqc_read_distribution_plot.txt", + "multiqc/multiqc_data/rseqc_read_dups.txt", + "multiqc/multiqc_data/rseqc_read_dups_plot.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Percentage_of_total.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Read_counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Normalised_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Observed_over_Expected_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Raw_Counts.txt", + "multiqc/multiqc_data/samtools-stats-dp.txt", + "multiqc/multiqc_data/samtools_alignment_plot.txt", + "multiqc/multiqc_report.html", + "pipeline_info", + "pipeline_info/nf_core_nascent_software_mqc_versions.yml", + "preprocessing", + "preprocessing/fastp", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.log", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.log", + "preprocessing/fastp/jurkat.trimmed.fastp.html", + "preprocessing/fastp/jurkat.trimmed.fastp.json", + "preprocessing/fastp/jurkat.trimmed.fastp.log", + "preprocessing/fastqc", + "preprocessing/fastqc/cd4_REP1_fastqc.html", + "preprocessing/fastqc/cd4_REP1_fastqc.zip", + "preprocessing/fastqc/cd4_REP2_fastqc.html", + "preprocessing/fastqc/cd4_REP2_fastqc.zip", + "preprocessing/fastqc/jurkat_fastqc.html", + "preprocessing/fastqc/jurkat_fastqc.zip", + "quality_control", + "quality_control/bbsplit", + "quality_control/bbsplit/cd4_REP1.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP1.coverage.stats.txt", + "quality_control/bbsplit/cd4_REP2.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP2.coverage.stats.txt", + "quality_control/bbsplit/jurkat.coverage.hist.txt", + "quality_control/bbsplit/jurkat.coverage.stats.txt", + "quality_control/preseq", + "quality_control/preseq/cd4_REP1.c_curve.txt", + "quality_control/preseq/cd4_REP1.lc_extrap.txt", + "quality_control/preseq/cd4_REP2.c_curve.txt", + "quality_control/preseq/cd4_REP2.lc_extrap.txt", + "quality_control/preseq/jurkat.c_curve.txt", + "quality_control/preseq/jurkat.lc_extrap.txt", + "quality_control/preseq/log", + "quality_control/preseq/log/cd4_REP1.command.log", + "quality_control/preseq/log/cd4_REP2.command.log", + "quality_control/preseq/log/jurkat.command.log", + "quality_control/rseqc", + "quality_control/rseqc/infer_experiment", + "quality_control/rseqc/infer_experiment/cd4_REP1.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/cd4_REP2.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/jurkat.infer_experiment.txt", + "quality_control/rseqc/read_distribution", + "quality_control/rseqc/read_distribution/cd4_REP1.read_distribution.txt", + "quality_control/rseqc/read_distribution/cd4_REP2.read_distribution.txt", + "quality_control/rseqc/read_distribution/jurkat.read_distribution.txt", + "quality_control/rseqc/read_duplication", + "quality_control/rseqc/read_duplication/pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP1.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP2.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/jurkat.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/rscript", + "quality_control/rseqc/read_duplication/rscript/cd4_REP1.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/cd4_REP2.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/jurkat.DupRate_plot.r", + "quality_control/rseqc/read_duplication/xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.seq.DupRate.xls", + "quantification", + "quantification/gene", + "quantification/gene/cd4.featureCounts.txt", + "quantification/gene/cd4.featureCounts.txt.summary", + "quantification/gene/jurkat.featureCounts.txt", + "quantification/gene/jurkat.featureCounts.txt.summary", + "quantification/nascent", + "quantification/nascent/cd4-group_cd4_intersect-transcripts.featureCounts.txt", + "quantification/nascent/cd4-group_cd4_intersect-transcripts.featureCounts.txt.summary", + "quantification/nascent/jurkat-group_cd4_intersect-transcripts.featureCounts.txt", + "quantification/nascent/jurkat-group_cd4_intersect-transcripts.featureCounts.txt.summary", + "samtools", + "samtools/cd4.bam", + "samtools/jurkat.bam", + "transcript_identification", + "transcript_identification/filtered", + "transcript_identification/filtered/cd4_filtered.bed", + "transcript_identification/filtered/jurkat_filtered.bed", + "transcript_identification/homer", + "transcript_identification/homer/cd4.bed", + "transcript_identification/homer/cd4.bedGraph.gz", + "transcript_identification/homer/cd4.peaks.txt", + "transcript_identification/homer/cd4_tagdir", + "transcript_identification/homer/cd4_tagdir/chr21.tags.tsv", + "transcript_identification/homer/cd4_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/cd4_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/cd4_tagdir/tagFreq.txt", + "transcript_identification/homer/cd4_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/cd4_tagdir/tagGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagInfo.txt", + "transcript_identification/homer/cd4_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/jurkat.bed", + "transcript_identification/homer/jurkat.bedGraph.gz", + "transcript_identification/homer/jurkat.peaks.txt", + "transcript_identification/homer/jurkat_tagdir", + "transcript_identification/homer/jurkat_tagdir/chr21.tags.tsv", + "transcript_identification/homer/jurkat_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/jurkat_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreq.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/jurkat_tagdir/tagGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagInfo.txt", + "transcript_identification/homer/jurkat_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/versions.yml", + "transcript_identification/intersect", + "transcript_identification/intersect/cd4_intersect.bed", + "transcript_identification/intersect/jurkat_intersect.bed", + "transcript_identification/merged", + "transcript_identification/merged/cd4_merged.bed", + "transcript_identification/merged/jurkat_merged.bed", + "transcript_identification/pints", + "transcript_identification/pints/cd4_chr21_1_unidirectional_peaks.bed", + "transcript_identification/pints/jurkat_chr21_1_unidirectional_peaks.bed" + ], + [ + "cd4_REP1.sorted.bam.flagstat:md5,863e2d506d5cc4239af98a5f31bbc906", + "cd4_REP1.sorted.bam.idxstats:md5,b1dd8bcbd23c53c21f0e11082d9315f2", + "cd4_REP1.sorted.bam.stats:md5,70b7cd3040a9b7ca70e919afb4dc7fea", + "cd4_REP2.sorted.bam.flagstat:md5,0fd86dbf8f799fad49ba471702979bdc", + "cd4_REP2.sorted.bam.idxstats:md5,53204e4c6a9f68664087e4a8123be46a", + "cd4_REP2.sorted.bam.stats:md5,c0e8d8d265fce71dcd43e43c93d29ef3", + "jurkat.sorted.bam.flagstat:md5,fd5f02b0f02a407447b804b1d80f5421", + "jurkat.sorted.bam.idxstats:md5,c61af0847c1ad76c06a8de2815975b32", + "jurkat.sorted.bam.stats:md5,c9a6ec83d8fb1a14f53351c76cfcd24b", + "cd4.bed:md5,0193e58943726af89bfd00e9da2536d8", + "jurkat.bed:md5,cb6932229eea2e09f61d48d7dd397ae1", + "cd4_REP1.dreg.bedGraph:md5,8948a8fa86d8f6d413b77983189ff56e", + "cd4_REP1.minus.bedGraph:md5,2a1c34f9d9ef9ff1b9da7874b9e3aaad", + "cd4_REP1.minus.bigWig:md5,5280319275c98dcce023779fa389884d", + "cd4_REP1.plus.bedGraph:md5,1509ec3a921e3109c5914e1bcef8cf33", + "cd4_REP1.plus.bigWig:md5,72ccab3173f2018a22a4b36841247ba2", + "cd4_REP2.dreg.bedGraph:md5,29f865a5668fae4a52a41589ac2b3179", + "cd4_REP2.minus.bedGraph:md5,c530bc34fa3ec7ac49e88ff65f9c2f92", + "cd4_REP2.minus.bigWig:md5,5e748c794e037f441741f7f409c8c5ad", + "cd4_REP2.plus.bedGraph:md5,a675141da2874ec08d91591e5ea8242b", + "cd4_REP2.plus.bigWig:md5,08674d52e9eeb08807c33ed3e4b3d504", + "jurkat.dreg.bedGraph:md5,c25a4fb095e9f7d6766a3ce33e08f7d8", + "jurkat.minus.bedGraph:md5,8d5d9a41df6eb6c56b1bfd3f39dc1fc6", + "jurkat.minus.bigWig:md5,d06c8015c996bf520fff17266fd01f84", + "jurkat.plus.bedGraph:md5,6ed63e5983edaa74fb3965676efdb674", + "jurkat.plus.bigWig:md5,7a02334f2c7300ffdb5a2253c0937390", + "cd4_REP1.trimmed.fastp.json:md5,bd9a3344c1591d6be4d524451f9dca53", + "cd4_REP2.trimmed.fastp.json:md5,bc6e3f9ff7835f220535cc393b8eb25f", + "jurkat.trimmed.fastp.json:md5,65f7247a87479c7157c7357d575336e2", + "cd4.bed:md5,b55e5290d78941f36c3d1ecfef8e0062", + "cd4.peaks.txt:md5,bdcd2ec3a56a8a4a01ed19e17da003f2", + "jurkat.bed:md5,383cfaf10535dbe5d7f47607e345f4cb", + "jurkat.peaks.txt:md5,d4914194eca6f06aadfe7eed08ab1bb8", + "versions.yml:md5,7c0dcd0a18b3c753def73b96cb825792", + "cd4_merged.bed:md5,9ace0ca4f1544bb0949355a20de98e6b", + "jurkat_merged.bed:md5,f1dde43c4ad9dec972ff9fa38cc6f2fe", + "cd4_chr21_1_unidirectional_peaks.bed:md5,0193e58943726af89bfd00e9da2536d8", + "jurkat_chr21_1_unidirectional_peaks.bed:md5,cb6932229eea2e09f61d48d7dd397ae1" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-28T21:53:21.62668" + } +} \ No newline at end of file diff --git a/workflows/tests/inputs/uniqmap/main.nf.test b/workflows/tests/inputs/uniqmap/main.nf.test new file mode 100644 index 00000000..945b0929 --- /dev/null +++ b/workflows/tests/inputs/uniqmap/main.nf.test @@ -0,0 +1,54 @@ +nextflow_pipeline { + + name "HOMER Uniqmap" + script "../../../../main.nf" + tag "input" + tag "homer" + + test("Should run with an zipped uniqmap") { + + config "./nextflow.config" + + when { + params { + outdir = "$outputDir" + use_homer_uniqmap = true + homer_uniqmap = 'https://raw.githubusercontent.com/nf-core/test-datasets/nascent/reference/uniqmap.GRCh38_chr21.50nt.zip' + skip_grohmm = true + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(removeNextflowVersion("$outputDir/pipeline_info/nf_core_nascent_software_mqc_versions.yml")).match("software_versions") }, + // Files should have -uniqmap in the header + { assert path("$outputDir/transcript_identification/homer/cd4.bed").readLines()[18].contains("uniqMapDirectory = uniqmap.GRCh38_chr21.50nt") }, + { assert path("$outputDir/transcript_identification/homer/cd4.bed").readLines()[20].contains("-uniqmap") }, + { assert path("$outputDir/transcript_identification/homer/jurkat.bed").readLines()[18].contains("uniqMapDirectory = uniqmap.GRCh38_chr21.50nt") }, + { assert path("$outputDir/transcript_identification/homer/jurkat.bed").readLines()[20].contains("-uniqmap") }, + // TODO Test for uniqmap unzip process + // { assert workflow.trace.tasks().find { it.process == "UNZIP" } }, + { assert snapshot( + workflow.trace.tasks().size(), + path("$outputDir/transcript_identification/homer/cd4.bed").readLines()[18], + path("$outputDir/transcript_identification/homer/cd4.bed").readLines()[20], + path("$outputDir/transcript_identification/homer/jurkat.bed").readLines()[18], + path("$outputDir/transcript_identification/homer/jurkat.bed").readLines()[20], + path("$outputDir/transcript_identification/homer/cd4.bed"), + path("$outputDir/transcript_identification/homer/jurkat.bed"), + path("$outputDir/transcript_identification/homer/cd4-uniqmap.GRCh38_chr21.peaks.txt"), + path("$outputDir/transcript_identification/homer/jurkat-uniqmap.GRCh38_chr21.peaks.txt"), + path("$outputDir/transcript_identification/intersect/").list(), + path("$outputDir/transcript_identification/filtered/").list(), + // FIXME Not determinstic because of the order of files + // Add to the other tests when fixed + // path("$outputDir/quantification/").list(), + path("$outputDir/multiqc/multiqc_report.html").exists(), + ).match("output_files") + }, + ) + } + } + // TODO Check for running with unzipped uniqmap +} diff --git a/workflows/tests/inputs/uniqmap/main.nf.test.snap b/workflows/tests/inputs/uniqmap/main.nf.test.snap new file mode 100644 index 00000000..465bd58a --- /dev/null +++ b/workflows/tests/inputs/uniqmap/main.nf.test.snap @@ -0,0 +1,109 @@ +{ + "output_files": { + "content": [ + 78, + "# uniqMapDirectory = uniqmap.GRCh38_chr21.50nt", + "# cmd = findPeaks cd4_tagdir -style groseq -o cd4-uniqmap.GRCh38_chr21.peaks.txt -uniqmap uniqmap.GRCh38_chr21.50nt", + "# uniqMapDirectory = uniqmap.GRCh38_chr21.50nt", + "# cmd = findPeaks jurkat_tagdir -style groseq -o jurkat-uniqmap.GRCh38_chr21.peaks.txt -uniqmap uniqmap.GRCh38_chr21.50nt", + "cd4.bed:md5,bbe77431f7c1ac833d1f939012435962", + "jurkat.bed:md5,98dd0b5dde7b11c0604b35c391754c9d", + "cd4-uniqmap.GRCh38_chr21.peaks.txt:md5,bbe77431f7c1ac833d1f939012435962", + "jurkat-uniqmap.GRCh38_chr21.peaks.txt:md5,98dd0b5dde7b11c0604b35c391754c9d", + [ + "cd4_intersect.bed:md5,d41d8cd98f00b204e9800998ecf8427e", + "jurkat_intersect.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + "cd4_filtered.bed:md5,d41d8cd98f00b204e9800998ecf8427e", + "jurkat_filtered.bed:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + true + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-21T07:55:14.410658" + }, + "software_versions": { + "content": [ + { + "BBMAP_PILEUP": { + "bbmap": 39.01, + "samtools": "1.16.1", + "pigz": 2.6 + }, + "BEDTOOLS_GENOMECOV_MINUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_GENOMECOV_PLUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT_FILTER": { + "bedtools": "2.31.1" + }, + "BWA_INDEX": { + "bwa": "0.7.18-r1243-dirty" + }, + "BWA_MEM": { + "bwa": "0.7.18-r1243-dirty", + "samtools": 1.2 + }, + "CUSTOM_GETCHROMSIZES": { + "getchromsizes": 1.2 + }, + "DEEPTOOLS_BAMCOVERAGE_MINUS": { + "deeptools": "3.5.5" + }, + "DEEPTOOLS_BAMCOVERAGE_PLUS": { + "deeptools": "3.5.5" + }, + "FASTP": { + "fastp": "0.23.4" + }, + "FASTQC": { + "fastqc": "0.12.1" + }, + "GTF2BED": { + "perl": "5.26.2" + }, + "PRESEQ_CCURVE": { + "preseq": "3.1.1" + }, + "PRESEQ_LCEXTRAP": { + "preseq": "3.1.1" + }, + "RSEQC_INFEREXPERIMENT": { + "rseqc": "5.0.2" + }, + "RSEQC_READDISTRIBUTION": { + "rseqc": "5.0.2" + }, + "RSEQC_READDUPLICATION": { + "rseqc": "5.0.2" + }, + "SAMTOOLS_MERGE": { + "samtools": 1.21 + }, + "SUBREAD_FEATURECOUNTS_GENE": { + "subread": "2.0.1" + }, + "UNZIP": { + "7za": 16.02 + }, + "Workflow": { + "nf-core/nascent": "v2.3.0" + } + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-21T08:17:33.996307" + } +} \ No newline at end of file diff --git a/workflows/tests/inputs/uniqmap/nextflow.config b/workflows/tests/inputs/uniqmap/nextflow.config new file mode 100644 index 00000000..a3d80f05 --- /dev/null +++ b/workflows/tests/inputs/uniqmap/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: PINTS_CALLER { + ext.when = false + } +} diff --git a/workflows/tests/main.nf.test b/workflows/tests/main.nf.test deleted file mode 100644 index 5d881502..00000000 --- a/workflows/tests/main.nf.test +++ /dev/null @@ -1,109 +0,0 @@ -nextflow_pipeline { - - name "Test Workflow main.nf" - script "../../main.nf" - - test("Should run with bwa (default)") { - - when { - params { - outdir = "$outputDir" - aligner = "bwa" - } - } - - then { - assert workflow.success - assert snapshot( - workflow.trace.tasks().size(), - path("$outputDir/bbmap").list(), - // BUG https://github.com/nf-core/nascent/issues/102 - // path("$outputDir/bedtools").list(), - // FIXME gtf2bed isn't deterministic - // path("$outputDir/bwa/featurecounts/gene").list(), - // FIXME cd4 isn't deterministic - // path("$outputDir/bwa/featurecounts/predicted").list(), - // path("$outputDir/deeptools").list(), - // path("$outputDir/fastp/*.json").list(), - // FIXME gtf2bed isn't deterministic - // path("$outputDir/gtf2bed").list(), - path("$outputDir/homer/cd4.bed"), - path("$outputDir/homer/jurkat.bed"), - path("$outputDir/preseq").list(), - // path("$outputDir/rseqc").list(), - path("$outputDir/samtools").list(), - ).match() - } - - } - - test("Should run with bwamem2") { - - when { - params { - outdir = "$outputDir" - aligner = "bwamem2" - } - } - - then { - assert workflow.success - assert snapshot( - workflow.trace.tasks().size(), - path("$outputDir/bbmap").list(), - // BUG https://github.com/nf-core/nascent/issues/102 - // path("$outputDir/bedtools").list(), - // FIXME gtf2bed isn't deterministic - // path("$outputDir/bwa/featurecounts/gene").list(), - // FIXME cd4 isn't deterministic - // path("$outputDir/bwa/featurecounts/predicted").list(), - // path("$outputDir/deeptools").list(), - // path("$outputDir/fastp/*.json").list(), - // FIXME gtf2bed isn't deterministic - // path("$outputDir/gtf2bed").list(), - path("$outputDir/homer/cd4.bed"), - path("$outputDir/homer/jurkat.bed"), - path("$outputDir/preseq").list(), - // path("$outputDir/rseqc").list(), - path("$outputDir/samtools").list(), - ).match() - } - - } - - test("Should run with dragmap") { - - when { - params { - outdir = "$outputDir" - aligner = "dragmap" - } - } - - then { - assert workflow.success - assert snapshot( - workflow.trace.tasks().size(), - path("$outputDir/bbmap").list(), - // BUG https://github.com/nf-core/nascent/issues/102 - // path("$outputDir/bedtools").list(), - // FIXME gtf2bed isn't deterministic - // path("$outputDir/bwa/featurecounts/gene").list(), - // FIXME cd4 isn't deterministic - // path("$outputDir/bwa/featurecounts/predicted").list(), - // path("$outputDir/deeptools").list(), - // path("$outputDir/fastp/*.json").list(), - // FIXME gtf2bed isn't deterministic - // path("$outputDir/gtf2bed").list(), - path("$outputDir/homer/cd4.bed"), - path("$outputDir/homer/jurkat.bed"), - path("$outputDir/preseq").list(), - // path("$outputDir/rseqc").list(), - // FIXME Not deterministic - // path("$outputDir/samtools").list(), - ).match() - } - - } - -} diff --git a/workflows/tests/main.nf.test.snap b/workflows/tests/main.nf.test.snap deleted file mode 100644 index 3b846411..00000000 --- a/workflows/tests/main.nf.test.snap +++ /dev/null @@ -1,204 +0,0 @@ -{ - "Should run with bwa (default)": { - "content": [ - 129, - [ - "cd4_REP1.coverage.hist.txt:md5,7cbb473be8d3b32ff2e52fdf4e5d10d2", - "cd4_REP1.coverage.stats.txt:md5,f1471b61ac17dba283d80e08450c7e55", - "cd4_REP2.coverage.hist.txt:md5,8d5258a0882494bc4e3f1aa6aa5ed685", - "cd4_REP2.coverage.stats.txt:md5,3cdb4473211f9da44166ffa6aaa5b602", - "cd4_REP3.coverage.hist.txt:md5,4a8397c1ea08f35ca7046e3c2c014a08", - "cd4_REP3.coverage.stats.txt:md5,b88592b469d504a93f2389255ac15f38", - "cd4_REP4.coverage.hist.txt:md5,d2cbf89e1f753d99bcd03b4e472270dd", - "cd4_REP4.coverage.stats.txt:md5,4c2b5fe6793aab8560cc87c176ac06ab", - "jurkat_REP1.coverage.hist.txt:md5,71a893d9d1d55fd47399f6d47b628d6e", - "jurkat_REP1.coverage.stats.txt:md5,381c69a30099d82066a959deab1a2569", - "jurkat_REP2.coverage.hist.txt:md5,d124bdadaf2dc5cdd9e3db5a1ab4c588", - "jurkat_REP2.coverage.stats.txt:md5,b1940346719e4070091f2eef6e508f49" - ], - "cd4.bed:md5,ab94918610a560772fdbec591200295f", - "jurkat.bed:md5,41908723fa423a78476feb2e7627a3a4", - [ - "cd4_REP1.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "cd4_REP1.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "cd4_REP1.lc_extrap.txt:md5,6d0e7f782f34ee54213c022cbe19df5b", - "cd4_REP2.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "cd4_REP2.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "cd4_REP2.lc_extrap.txt:md5,6aac6dd78dfd85a18fadd20be7377019", - "cd4_REP3.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "cd4_REP3.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "cd4_REP3.lc_extrap.txt:md5,02c4b0fc0afd282a402a316d44598173", - "cd4_REP4.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "cd4_REP4.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "cd4_REP4.lc_extrap.txt:md5,9efbab9d2aee791e7e9cae9237f2c500", - "jurkat_REP1.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "jurkat_REP1.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "jurkat_REP1.lc_extrap.txt:md5,390386e428ce783b3a373a5f60ee912f", - "jurkat_REP2.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "jurkat_REP2.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "jurkat_REP2.lc_extrap.txt:md5,cfdda91d83dd381dcefdc754e4b4c54c" - ], - [ - "cd4_REP1.flagstat:md5,863e2d506d5cc4239af98a5f31bbc906", - "cd4_REP1.idxstats:md5,b1dd8bcbd23c53c21f0e11082d9315f2", - "cd4_REP1.sorted.bam:md5,bcf7172fc9681b8a4d6da53dc885d369", - "cd4_REP1.sorted.bam.bai:md5,81a74745a7b117da0c8d7f7f95b352d0", - "cd4_REP1.stats:md5,1a937e63fb7b1f8063121d8f14f4e918", - "cd4_REP2.flagstat:md5,0fd86dbf8f799fad49ba471702979bdc", - "cd4_REP2.idxstats:md5,53204e4c6a9f68664087e4a8123be46a", - "cd4_REP2.sorted.bam:md5,58402e4242c81af27c031907abd7bf49", - "cd4_REP2.sorted.bam.bai:md5,f75a9e0ac39ca322f1d084f968d67fe3", - "cd4_REP2.stats:md5,6ac59691b72f0ccbe2dfa4408586a39b", - "cd4_REP3.flagstat:md5,793c9cadbf80e35dbae3774e9b5bd93f", - "cd4_REP3.idxstats:md5,42de227ff397013cf288759871b0e938", - "cd4_REP3.sorted.bam:md5,7ecd4f4eafc7551a0d37cfbd690005d2", - "cd4_REP3.sorted.bam.bai:md5,64cb3302603284eb4cc6a66c1bcbe857", - "cd4_REP3.stats:md5,43cfc143cb086a7fa22a0c8d9d1fc9bb", - "cd4_REP4.flagstat:md5,ed6c609505097f3cc9d9902d69e016f8", - "cd4_REP4.idxstats:md5,959dc185ae59de4cebe374026711a55e", - "cd4_REP4.sorted.bam:md5,401da47cbdf9c262f6c84017efedd567", - "cd4_REP4.sorted.bam.bai:md5,901fadf09dcd111606522766123fba07", - "cd4_REP4.stats:md5,e91a8bd8d0918555892235999ff15b1e", - "jurkat_REP1.flagstat:md5,fd5f02b0f02a407447b804b1d80f5421", - "jurkat_REP1.idxstats:md5,c61af0847c1ad76c06a8de2815975b32", - "jurkat_REP1.sorted.bam:md5,a3178b414156d28cf22b98fd9d742392", - "jurkat_REP1.sorted.bam.bai:md5,67c37ae4d072ebbf2cc15999d8e18e41", - "jurkat_REP1.stats:md5,895eddd56d3fc3487f54649dcf063fc7", - "jurkat_REP2.flagstat:md5,86ed47bd41a745ab59de473082c7742d", - "jurkat_REP2.idxstats:md5,3db8f88c1f836eb5d10f37ca1df81ae9", - "jurkat_REP2.sorted.bam:md5,175cf112edf380e1e0cab23a818b6ab0", - "jurkat_REP2.sorted.bam.bai:md5,a2f3e49a63c02bde49c24c56a1050606", - "jurkat_REP2.stats:md5,9466c2094bb843e845d1c15d25aec2ab" - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-02-17T22:45:14.737941295" - }, - "Should run with bwamem2": { - "content": [ - 129, - [ - "cd4_REP1.coverage.hist.txt:md5,7cbb473be8d3b32ff2e52fdf4e5d10d2", - "cd4_REP1.coverage.stats.txt:md5,f1471b61ac17dba283d80e08450c7e55", - "cd4_REP2.coverage.hist.txt:md5,8d5258a0882494bc4e3f1aa6aa5ed685", - "cd4_REP2.coverage.stats.txt:md5,3cdb4473211f9da44166ffa6aaa5b602", - "cd4_REP3.coverage.hist.txt:md5,4a8397c1ea08f35ca7046e3c2c014a08", - "cd4_REP3.coverage.stats.txt:md5,b88592b469d504a93f2389255ac15f38", - "cd4_REP4.coverage.hist.txt:md5,d2cbf89e1f753d99bcd03b4e472270dd", - "cd4_REP4.coverage.stats.txt:md5,4c2b5fe6793aab8560cc87c176ac06ab", - "jurkat_REP1.coverage.hist.txt:md5,71a893d9d1d55fd47399f6d47b628d6e", - "jurkat_REP1.coverage.stats.txt:md5,381c69a30099d82066a959deab1a2569", - "jurkat_REP2.coverage.hist.txt:md5,d124bdadaf2dc5cdd9e3db5a1ab4c588", - "jurkat_REP2.coverage.stats.txt:md5,b1940346719e4070091f2eef6e508f49" - ], - "cd4.bed:md5,ab94918610a560772fdbec591200295f", - "jurkat.bed:md5,41908723fa423a78476feb2e7627a3a4", - [ - "cd4_REP1.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "cd4_REP1.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "cd4_REP1.lc_extrap.txt:md5,6d0e7f782f34ee54213c022cbe19df5b", - "cd4_REP2.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "cd4_REP2.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "cd4_REP2.lc_extrap.txt:md5,6aac6dd78dfd85a18fadd20be7377019", - "cd4_REP3.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "cd4_REP3.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "cd4_REP3.lc_extrap.txt:md5,02c4b0fc0afd282a402a316d44598173", - "cd4_REP4.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "cd4_REP4.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "cd4_REP4.lc_extrap.txt:md5,9efbab9d2aee791e7e9cae9237f2c500", - "jurkat_REP1.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "jurkat_REP1.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "jurkat_REP1.lc_extrap.txt:md5,390386e428ce783b3a373a5f60ee912f", - "jurkat_REP2.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "jurkat_REP2.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "jurkat_REP2.lc_extrap.txt:md5,cfdda91d83dd381dcefdc754e4b4c54c" - ], - [ - "cd4_REP1.flagstat:md5,863e2d506d5cc4239af98a5f31bbc906", - "cd4_REP1.idxstats:md5,b1dd8bcbd23c53c21f0e11082d9315f2", - "cd4_REP1.sorted.bam:md5,8ba4050082d4c90f6aab1dbdfc10750d", - "cd4_REP1.sorted.bam.bai:md5,a8d78c0a98c7d984cfd15c180cca3dfe", - "cd4_REP1.stats:md5,1a937e63fb7b1f8063121d8f14f4e918", - "cd4_REP2.flagstat:md5,0fd86dbf8f799fad49ba471702979bdc", - "cd4_REP2.idxstats:md5,53204e4c6a9f68664087e4a8123be46a", - "cd4_REP2.sorted.bam:md5,daa348ffd92d1b7bd9461b630fe0cadd", - "cd4_REP2.sorted.bam.bai:md5,512539251014f664aa66d1ca091914d5", - "cd4_REP2.stats:md5,6ac59691b72f0ccbe2dfa4408586a39b", - "cd4_REP3.flagstat:md5,793c9cadbf80e35dbae3774e9b5bd93f", - "cd4_REP3.idxstats:md5,42de227ff397013cf288759871b0e938", - "cd4_REP3.sorted.bam:md5,54401355efd28816d914e1528d10ca56", - "cd4_REP3.sorted.bam.bai:md5,e48a3892b710d2de5878cad3cf83d711", - "cd4_REP3.stats:md5,43cfc143cb086a7fa22a0c8d9d1fc9bb", - "cd4_REP4.flagstat:md5,ed6c609505097f3cc9d9902d69e016f8", - "cd4_REP4.idxstats:md5,959dc185ae59de4cebe374026711a55e", - "cd4_REP4.sorted.bam:md5,faa381807425a2b5822380391fb25d30", - "cd4_REP4.sorted.bam.bai:md5,30eae2c6d450930679e7680cdfa3f98a", - "cd4_REP4.stats:md5,e91a8bd8d0918555892235999ff15b1e", - "jurkat_REP1.flagstat:md5,fd5f02b0f02a407447b804b1d80f5421", - "jurkat_REP1.idxstats:md5,c61af0847c1ad76c06a8de2815975b32", - "jurkat_REP1.sorted.bam:md5,755d348bae58bdb87483a11932cfe2c6", - "jurkat_REP1.sorted.bam.bai:md5,af8e82924f430046f8f16f8d87cd26d8", - "jurkat_REP1.stats:md5,895eddd56d3fc3487f54649dcf063fc7", - "jurkat_REP2.flagstat:md5,86ed47bd41a745ab59de473082c7742d", - "jurkat_REP2.idxstats:md5,3db8f88c1f836eb5d10f37ca1df81ae9", - "jurkat_REP2.sorted.bam:md5,eb6ff38a542eb6ed99dfdbf97dce5507", - "jurkat_REP2.sorted.bam.bai:md5,69795a27982c966af95a398fea7d60e9", - "jurkat_REP2.stats:md5,9466c2094bb843e845d1c15d25aec2ab" - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-02-17T22:47:07.961805653" - }, - "Should run with dragmap": { - "content": [ - 129, - [ - "cd4_REP1.coverage.hist.txt:md5,bff6862bc8e2015eef927b40671dec1b", - "cd4_REP1.coverage.stats.txt:md5,c1e912cd0bebc51b289160ff7ab3365a", - "cd4_REP2.coverage.hist.txt:md5,edadf440d1c3658118ffd6b6a46821f8", - "cd4_REP2.coverage.stats.txt:md5,cb1ce057d05fc53e7ad9b0b2e3d5aaad", - "cd4_REP3.coverage.hist.txt:md5,096ce6905c96587ba80ebcbe5893cf3e", - "cd4_REP3.coverage.stats.txt:md5,f4b88f4eebab0c010a1cfdc3404dfafb", - "cd4_REP4.coverage.hist.txt:md5,01f93b5c248e0b78f6d94e28eee3f9e7", - "cd4_REP4.coverage.stats.txt:md5,a4c6f61be8263e7461f8b961cfcc9053", - "jurkat_REP1.coverage.hist.txt:md5,468c864f655947edb3b306cb7a72633d", - "jurkat_REP1.coverage.stats.txt:md5,338f3095395c8d8f172e0e27f9a5a60a", - "jurkat_REP2.coverage.hist.txt:md5,03301957b2f29c43cb8ea3462998c315", - "jurkat_REP2.coverage.stats.txt:md5,c3fc3f11e84f4d075ba95adbdbb2ee29" - ], - "cd4.bed:md5,e9380700e48c1e52f76a2bb3fa4f59d9", - "jurkat.bed:md5,fe88d4dc3c100262d7aec484e15b1c73", - [ - "cd4_REP1.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "cd4_REP1.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "cd4_REP1.lc_extrap.txt:md5,5ecde39eb3bbec0b056b57a5f95f10e7", - "cd4_REP2.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "cd4_REP2.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "cd4_REP2.lc_extrap.txt:md5,abb6a284d959110d35dd3b9659244188", - "cd4_REP3.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "cd4_REP3.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "cd4_REP3.lc_extrap.txt:md5,af11536a40238dc3417468a2f670126c", - "cd4_REP4.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "cd4_REP4.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "cd4_REP4.lc_extrap.txt:md5,b36b409ec88047cd354eb04a42b852e5", - "jurkat_REP1.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "jurkat_REP1.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "jurkat_REP1.lc_extrap.txt:md5,024057a6211bf22384df658bce250d21", - "jurkat_REP2.c_curve.txt:md5,cf4743abdd355595d6ec1fb3f38e66e5", - "jurkat_REP2.command.log:md5,d41d8cd98f00b204e9800998ecf8427e", - "jurkat_REP2.lc_extrap.txt:md5,33bdd91e7df616988c1ec043818b346b" - ] - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-02-17T22:49:01.647145296" - } -} \ No newline at end of file diff --git a/workflows/tests/references.nf.test b/workflows/tests/references.nf.test deleted file mode 100644 index a7a5cfd1..00000000 --- a/workflows/tests/references.nf.test +++ /dev/null @@ -1,52 +0,0 @@ -def igenomes_base = 's3://ngi-igenomes/igenomes' - -nextflow_pipeline { - - name "Test passing references" - script "../../main.nf" - - // https://github.com/nf-core/nascent/issues/106 - test("Should work with BWA Index") { - // FIXME PINTS Fails because it doesn't find anything. - config './skip_pints.config' - when { - params { - outdir = "$outputDir" - aligner = "bwa" - // TODO Update these to human - bwa_index = "${igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/BWAIndex/version0.6.0/" - fasta = "${igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/WholeGenomeFasta/genome.fa" - gtf = "${igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.gtf" - } - } - - then { - assert workflow.success - assert snapshot( - workflow.trace.tasks().size(), - ).match() - } - } - - // https://github.com/nf-core/nascent/issues/119 - test("Should work with gzipped references") { - config './skip_gzip.config' - when { - params { - outdir = "$outputDir" - aligner = "bwa" - fasta = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/reference/genome.fasta.gz' - gtf = 'https://raw.githubusercontent.com/nf-core/test-datasets/rnaseq/reference/genes.gtf.gz' - } - } - - then { - assert workflow.success - assert snapshot( - workflow.trace.tasks().size(), - ).match() - } - - } - -} diff --git a/workflows/tests/references.nf.test.snap b/workflows/tests/references.nf.test.snap deleted file mode 100644 index 29076018..00000000 --- a/workflows/tests/references.nf.test.snap +++ /dev/null @@ -1,22 +0,0 @@ -{ - "Should work with gzipped references": { - "content": [ - 99 - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-02-14T16:39:27.539091004" - }, - "Should work with BWA Index": { - "content": [ - 114 - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "23.10.1" - }, - "timestamp": "2024-02-18T08:05:07.088179653" - } -} \ No newline at end of file diff --git a/workflows/tests/skip_gzip.config b/workflows/tests/skip_gzip.config index 768823ea..b3822812 100644 --- a/workflows/tests/skip_gzip.config +++ b/workflows/tests/skip_gzip.config @@ -19,4 +19,8 @@ process { withName: HOMER_MAKETAGDIRECTORY { ext.when = false } + + withName: DREG_PREP { + ext.when = false + } } diff --git a/workflows/tests/skip_pints.config b/workflows/tests/skip_pints.config index c3f0af53..1b3dad74 100644 --- a/workflows/tests/skip_pints.config +++ b/workflows/tests/skip_pints.config @@ -2,4 +2,8 @@ process { withName: '.*:TRANSCRIPT_INDENTIFICATION:.*' { ext.when = false } + + withName: DREG_PREP { + ext.when = false + } } diff --git a/workflows/tests/transcript_indentification/grohmm/only_gff/main.nf.test b/workflows/tests/transcript_indentification/grohmm/only_gff/main.nf.test new file mode 100644 index 00000000..638a7ba0 --- /dev/null +++ b/workflows/tests/transcript_indentification/grohmm/only_gff/main.nf.test @@ -0,0 +1,47 @@ +nextflow_pipeline { + + name "GROHMM" + script "../../../../../main.nf" + tag "input" + tag "grohmm" + tag "gff" + tag "chm13" + // triggers 'bin/parameter_tuning.R', 'bin/transcriptcalling_grohmm.R' + + test("Should run groHMM with only a GFF file") { + when { + params { + outdir = "$outputDir" + skip_grohmm = false + gff = 'https://huggingface.co/datasets/edmundmiller/nascent-test-data/resolve/main/chm13v2.0_RefSeq_Liftoff_v5.1.chr21.gff3.gz' + fasta = 'https://raw.githubusercontent.com/nf-core/test-datasets/nascent/reference/chm13v2.0.chr21.fa.gz' + gtf = null + bed = null + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}', 'multiqc/multiqc_plots', 'multiqc/multiqc_plots/**']) + // stable_path: All files in ${params.outdir}/ with stable content + def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') + // bam_files: All bam files + def bam_files = getAllFilesFromDir(params.outdir, include: ['**/*.bam']) + assertAll( + { assert workflow.success }, + { assert snapshot( + // Number of 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_nascent_software_mqc_versions.yml"), + // All stable path name + stable_name, + // All files with stable contents + stable_path, + // All bam files + // FIXME bam_files.collect{ file -> [ file.getName(), bam(file.toString()).getReadsMD5() ] } + ).match() } + ) + } + } +} diff --git a/workflows/tests/transcript_indentification/grohmm/only_gff/main.nf.test.snap b/workflows/tests/transcript_indentification/grohmm/only_gff/main.nf.test.snap new file mode 100644 index 00000000..7a124e34 --- /dev/null +++ b/workflows/tests/transcript_indentification/grohmm/only_gff/main.nf.test.snap @@ -0,0 +1,380 @@ +{ + "Should run groHMM with only a GFF file": { + "content": [ + 112, + { + "BBMAP_PILEUP": { + "bbmap": 39.01, + "samtools": "1.16.1", + "pigz": 2.6 + }, + "BEDTOOLS_GENOMECOV_MINUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_GENOMECOV_PLUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT_FILTER": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_MERGE": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_SORT": { + "bedtools": "2.31.1" + }, + "BWA_INDEX": { + "bwa": "0.7.18-r1243-dirty" + }, + "BWA_MEM": { + "bwa": "0.7.18-r1243-dirty", + "samtools": 1.2 + }, + "CAT_CAT": { + "pigz": "2.3.4" + }, + "CUSTOM_GETCHROMSIZES": { + "getchromsizes": 1.2 + }, + "DEEPTOOLS_BAMCOVERAGE_MINUS": { + "deeptools": "3.5.5" + }, + "DEEPTOOLS_BAMCOVERAGE_PLUS": { + "deeptools": "3.5.5" + }, + "FASTP": { + "fastp": "0.23.4" + }, + "FASTQC": { + "fastqc": "0.12.1" + }, + "GFFREAD": { + "gffread": "0.12.7" + }, + "GROHMM_PARAMETERTUNING": { + "r-base": "4.3.3", + "bioconductor-grohmm": "1.39.0" + }, + "GTF2BED": { + "perl": "5.26.2" + }, + "GUNZIP_FASTA": { + "gunzip": 1.1 + }, + "GUNZIP_GFF": { + "gunzip": 1.1 + }, + "HOMER_MAKETAGDIRECTORY": { + "homer": 4.11, + "samtools": 1.21 + }, + "PINTS_CALLER": { + "python": "3.12.6", + "pints": "1.1.13" + }, + "PRESEQ_CCURVE": { + "preseq": "3.1.1" + }, + "PRESEQ_LCEXTRAP": { + "preseq": "3.1.1" + }, + "RSEQC_INFEREXPERIMENT": { + "rseqc": "5.0.2" + }, + "RSEQC_READDISTRIBUTION": { + "rseqc": "5.0.2" + }, + "RSEQC_READDUPLICATION": { + "rseqc": "5.0.2" + }, + "SAMTOOLS_MERGE": { + "samtools": 1.21 + }, + "SUBREAD_FEATURECOUNTS_GENE": { + "subread": "2.0.1" + }, + "SUBREAD_FEATURECOUNTS_PREDICTED": { + "subread": "2.0.1" + }, + "Workflow": { + "nf-core/nascent": "v2.3.0" + } + }, + [ + "bwa", + "bwa/cd4_REP1.sorted.bam", + "bwa/cd4_REP1.sorted.bam.bai", + "bwa/cd4_REP2.sorted.bam", + "bwa/cd4_REP2.sorted.bam.bai", + "bwa/jurkat.sorted.bam", + "bwa/jurkat.sorted.bam.bai", + "bwa/samtools_stats", + "bwa/samtools_stats/cd4_REP1.sorted.bam.flagstat", + "bwa/samtools_stats/cd4_REP1.sorted.bam.idxstats", + "bwa/samtools_stats/cd4_REP1.sorted.bam.stats", + "bwa/samtools_stats/cd4_REP2.sorted.bam.flagstat", + "bwa/samtools_stats/cd4_REP2.sorted.bam.idxstats", + "bwa/samtools_stats/cd4_REP2.sorted.bam.stats", + "bwa/samtools_stats/jurkat.sorted.bam.flagstat", + "bwa/samtools_stats/jurkat.sorted.bam.idxstats", + "bwa/samtools_stats/jurkat.sorted.bam.stats", + "cat", + "cat/cd4.bed", + "cat/jurkat.bed", + "coverage_graphs", + "coverage_graphs/cd4_REP1.dreg.bedGraph", + "coverage_graphs/cd4_REP1.minus.bedGraph", + "coverage_graphs/cd4_REP1.minus.bigWig", + "coverage_graphs/cd4_REP1.plus.bedGraph", + "coverage_graphs/cd4_REP1.plus.bigWig", + "coverage_graphs/cd4_REP2.dreg.bedGraph", + "coverage_graphs/cd4_REP2.minus.bedGraph", + "coverage_graphs/cd4_REP2.minus.bigWig", + "coverage_graphs/cd4_REP2.plus.bedGraph", + "coverage_graphs/cd4_REP2.plus.bigWig", + "coverage_graphs/jurkat.dreg.bedGraph", + "coverage_graphs/jurkat.minus.bedGraph", + "coverage_graphs/jurkat.minus.bigWig", + "coverage_graphs/jurkat.plus.bedGraph", + "coverage_graphs/jurkat.plus.bigWig", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_data/fastqc-status-check-heatmap.txt", + "multiqc/multiqc_data/fastqc_adapter_content_plot.txt", + "multiqc/multiqc_data/fastqc_overrepresented_sequences_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_n_content_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_sequence_quality_plot.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Counts.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Percentages.txt", + "multiqc/multiqc_data/fastqc_per_sequence_quality_scores_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_counts_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_duplication_levels_plot.txt", + "multiqc/multiqc_data/fastqc_top_overrepresented_sequences_table.txt", + "multiqc/multiqc_data/homer-tag-directory-gc-content.txt", + "multiqc/multiqc_data/homer-tag-info-dist.txt", + "multiqc/multiqc_data/homer-tag-length-dist.txt", + "multiqc/multiqc_data/homer_tagdir.txt", + "multiqc/multiqc_data/multiqc.log", + "multiqc/multiqc_data/multiqc_citations.txt", + "multiqc/multiqc_data/multiqc_data.json", + "multiqc/multiqc_data/multiqc_fastqc.txt", + "multiqc/multiqc_data/multiqc_general_stats.txt", + "multiqc/multiqc_data/multiqc_rseqc_infer_experiment.txt", + "multiqc/multiqc_data/multiqc_rseqc_read_distribution.txt", + "multiqc/multiqc_data/multiqc_samtools_flagstat.txt", + "multiqc/multiqc_data/multiqc_samtools_idxstats.txt", + "multiqc/multiqc_data/multiqc_samtools_stats.txt", + "multiqc/multiqc_data/multiqc_software_versions.txt", + "multiqc/multiqc_data/multiqc_sources.txt", + "multiqc/multiqc_data/preseq.txt", + "multiqc/multiqc_data/preseq_complexity_plot_molecules.txt", + "multiqc/multiqc_data/rseqc_infer_experiment_plot.txt", + "multiqc/multiqc_data/rseqc_read_distribution_plot.txt", + "multiqc/multiqc_data/rseqc_read_dups.txt", + "multiqc/multiqc_data/rseqc_read_dups_plot.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Percentage_of_total.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Read_counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Normalised_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Observed_over_Expected_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Raw_Counts.txt", + "multiqc/multiqc_data/samtools-stats-dp.txt", + "multiqc/multiqc_data/samtools_alignment_plot.txt", + "multiqc/multiqc_report.html", + "pipeline_info", + "pipeline_info/nf_core_nascent_software_mqc_versions.yml", + "preprocessing", + "preprocessing/fastp", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.log", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.log", + "preprocessing/fastp/jurkat.trimmed.fastp.html", + "preprocessing/fastp/jurkat.trimmed.fastp.json", + "preprocessing/fastp/jurkat.trimmed.fastp.log", + "preprocessing/fastqc", + "preprocessing/fastqc/cd4_REP1_fastqc.html", + "preprocessing/fastqc/cd4_REP1_fastqc.zip", + "preprocessing/fastqc/cd4_REP2_fastqc.html", + "preprocessing/fastqc/cd4_REP2_fastqc.zip", + "preprocessing/fastqc/jurkat_fastqc.html", + "preprocessing/fastqc/jurkat_fastqc.zip", + "quality_control", + "quality_control/bbsplit", + "quality_control/bbsplit/cd4_REP1.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP1.coverage.stats.txt", + "quality_control/bbsplit/cd4_REP2.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP2.coverage.stats.txt", + "quality_control/bbsplit/jurkat.coverage.hist.txt", + "quality_control/bbsplit/jurkat.coverage.stats.txt", + "quality_control/preseq", + "quality_control/preseq/cd4_REP1.c_curve.txt", + "quality_control/preseq/cd4_REP1.lc_extrap.txt", + "quality_control/preseq/cd4_REP2.c_curve.txt", + "quality_control/preseq/cd4_REP2.lc_extrap.txt", + "quality_control/preseq/jurkat.c_curve.txt", + "quality_control/preseq/jurkat.lc_extrap.txt", + "quality_control/preseq/log", + "quality_control/preseq/log/cd4_REP1.command.log", + "quality_control/preseq/log/cd4_REP2.command.log", + "quality_control/preseq/log/jurkat.command.log", + "quality_control/rseqc", + "quality_control/rseqc/infer_experiment", + "quality_control/rseqc/infer_experiment/cd4_REP1.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/cd4_REP2.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/jurkat.infer_experiment.txt", + "quality_control/rseqc/read_distribution", + "quality_control/rseqc/read_distribution/cd4_REP1.read_distribution.txt", + "quality_control/rseqc/read_distribution/cd4_REP2.read_distribution.txt", + "quality_control/rseqc/read_distribution/jurkat.read_distribution.txt", + "quality_control/rseqc/read_duplication", + "quality_control/rseqc/read_duplication/pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP1.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP2.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/jurkat.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/rscript", + "quality_control/rseqc/read_duplication/rscript/cd4_REP1.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/cd4_REP2.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/jurkat.DupRate_plot.r", + "quality_control/rseqc/read_duplication/xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.seq.DupRate.xls", + "quantification", + "quantification/gene", + "quantification/gene/cd4.featureCounts.txt", + "quantification/gene/cd4.featureCounts.txt.summary", + "quantification/gene/jurkat.featureCounts.txt", + "quantification/gene/jurkat.featureCounts.txt.summary", + "quantification/nascent", + "quantification/nascent/cd4-group_cd4_intersect-transcripts.featureCounts.txt", + "quantification/nascent/cd4-group_cd4_intersect-transcripts.featureCounts.txt.summary", + "quantification/nascent/cd4-group_jurkat_intersect-transcripts.featureCounts.txt", + "quantification/nascent/cd4-group_jurkat_intersect-transcripts.featureCounts.txt.summary", + "quantification/nascent/jurkat-group_cd4_intersect-transcripts.featureCounts.txt", + "quantification/nascent/jurkat-group_cd4_intersect-transcripts.featureCounts.txt.summary", + "quantification/nascent/jurkat-group_jurkat_intersect-transcripts.featureCounts.txt", + "quantification/nascent/jurkat-group_jurkat_intersect-transcripts.featureCounts.txt.summary", + "samtools", + "samtools/cd4.bam", + "samtools/jurkat.bam", + "transcript_identification", + "transcript_identification/filtered", + "transcript_identification/filtered/cd4_filtered.bed", + "transcript_identification/filtered/jurkat_filtered.bed", + "transcript_identification/grohmm", + "transcript_identification/grohmm/cd4.SE.tuning.csv", + "transcript_identification/grohmm/cd4.eval.txt", + "transcript_identification/grohmm/cd4.final.transcripts.bed", + "transcript_identification/grohmm/cd4.tdFinal.txt", + "transcript_identification/grohmm/cd4.tdFinal_mqc.csv", + "transcript_identification/grohmm/cd4.tdplot_mqc.png", + "transcript_identification/grohmm/cd4.transcripts.txt", + "transcript_identification/grohmm/jurkat.SE.tuning.csv", + "transcript_identification/grohmm/jurkat.eval.txt", + "transcript_identification/grohmm/jurkat.final.transcripts.bed", + "transcript_identification/grohmm/jurkat.tdFinal.txt", + "transcript_identification/grohmm/jurkat.tdFinal_mqc.csv", + "transcript_identification/grohmm/jurkat.tdplot_mqc.png", + "transcript_identification/grohmm/jurkat.transcripts.txt", + "transcript_identification/homer", + "transcript_identification/homer/cd4.bed", + "transcript_identification/homer/cd4.bedGraph.gz", + "transcript_identification/homer/cd4.peaks.txt", + "transcript_identification/homer/cd4_tagdir", + "transcript_identification/homer/cd4_tagdir/chr21.tags.tsv", + "transcript_identification/homer/cd4_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/cd4_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/cd4_tagdir/tagFreq.txt", + "transcript_identification/homer/cd4_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/cd4_tagdir/tagGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagInfo.txt", + "transcript_identification/homer/cd4_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/jurkat.bed", + "transcript_identification/homer/jurkat.bedGraph.gz", + "transcript_identification/homer/jurkat.peaks.txt", + "transcript_identification/homer/jurkat_tagdir", + "transcript_identification/homer/jurkat_tagdir/chr21.tags.tsv", + "transcript_identification/homer/jurkat_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/jurkat_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreq.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/jurkat_tagdir/tagGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagInfo.txt", + "transcript_identification/homer/jurkat_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/versions.yml", + "transcript_identification/intersect", + "transcript_identification/intersect/cd4_intersect.bed", + "transcript_identification/intersect/jurkat_intersect.bed", + "transcript_identification/merged", + "transcript_identification/merged/cd4_merged.bed", + "transcript_identification/merged/jurkat_merged.bed", + "transcript_identification/pints", + "transcript_identification/pints/cd4_chr21_1_unidirectional_peaks.bed", + "transcript_identification/pints/jurkat_chr21_1_unidirectional_peaks.bed" + ], + [ + "cd4_REP1.sorted.bam.flagstat:md5,98ee509d07c1db03ccce634ccf410d07", + "cd4_REP1.sorted.bam.idxstats:md5,3f30696c4c8628b47029f63d9521f0e7", + "cd4_REP1.sorted.bam.stats:md5,a778d8eaf5f819ab4cdfca253c55f96a", + "cd4_REP2.sorted.bam.flagstat:md5,235f511666cc191d1ba0d0e7334eb6ad", + "cd4_REP2.sorted.bam.idxstats:md5,5eb0e894286a602d8c34b18ae226863e", + "cd4_REP2.sorted.bam.stats:md5,2eb00b3b786faf06a62b79309070c514", + "jurkat.sorted.bam.flagstat:md5,a1eec107305fe681a02771574de5c5fb", + "jurkat.sorted.bam.idxstats:md5,02590cdcaec907c42cf6507d62844a4c", + "jurkat.sorted.bam.stats:md5,1feee32d0fcf66f2042aba5627fdc019", + "cd4.bed:md5,60e0da7e5691e55d86eb9df9f6ea0c46", + "jurkat.bed:md5,3584ff1a08cdecc92b6fcf6b2db8dc90", + "cd4_REP1.dreg.bedGraph:md5,35eb3dce09cf8a32e71fe459e0f4a0a5", + "cd4_REP1.minus.bedGraph:md5,141abb85ef58f8cd77b3908ac22a35c6", + "cd4_REP1.minus.bigWig:md5,52d93314a403c1303e91c34ea731b445", + "cd4_REP1.plus.bedGraph:md5,fac7dc18180431b03e367da72383da88", + "cd4_REP1.plus.bigWig:md5,8b869ed53753eafa00dcc63070078883", + "cd4_REP2.dreg.bedGraph:md5,b1fc188a70aa795a38649954fc41896c", + "cd4_REP2.minus.bedGraph:md5,5ff711ae9e757b1a60364131b8003880", + "cd4_REP2.minus.bigWig:md5,deb81acab23d25a991e26af82b33b04e", + "cd4_REP2.plus.bedGraph:md5,c48f7894fabd484661226fde193a67fb", + "cd4_REP2.plus.bigWig:md5,f308509ebc485ed7b1ba8616aba8e400", + "jurkat.dreg.bedGraph:md5,f5c6f0e6035c2d3f1cb803f532c3fb93", + "jurkat.minus.bedGraph:md5,4da08f7094f8ff6c2e1ab33ea982c328", + "jurkat.minus.bigWig:md5,378935c83fe428a878cb91490ce5e297", + "jurkat.plus.bedGraph:md5,1e801978023f381e151403b572a9bd70", + "jurkat.plus.bigWig:md5,59bbb8db066fb91c82685eff1c675823", + "cd4_REP1.trimmed.fastp.json:md5,bd9a3344c1591d6be4d524451f9dca53", + "cd4_REP2.trimmed.fastp.json:md5,bc6e3f9ff7835f220535cc393b8eb25f", + "jurkat.trimmed.fastp.json:md5,65f7247a87479c7157c7357d575336e2", + "cd4.SE.tuning.csv:md5,9d76e9a83079d587459fda16af8c4da8", + "cd4.eval.txt:md5,de1f790f721a67dfd1e1bf1592a7971a", + "cd4.final.transcripts.bed:md5,3707df9ae8e7a95b6b5bfc336cfb1c8a", + "cd4.transcripts.txt:md5,48d15103e5f67abc30b4da71a595243b", + "jurkat.SE.tuning.csv:md5,d339a8072a8789896d4df6b78eeef6a2", + "jurkat.eval.txt:md5,f8f6402c871cd55d6cfb9c2be04627b6", + "jurkat.final.transcripts.bed:md5,cd3ce78611dcad5a1893a6da3d70a39f", + "jurkat.transcripts.txt:md5,901825bc4b6b93e718f7082fb4c2c579", + "cd4.bed:md5,202652821e59d0357c699b217d02f755", + "cd4.peaks.txt:md5,84b08e639d17d480cbc90b465ecfff73", + "jurkat.bed:md5,7c37a46578dac48f8bf15155cd78b214", + "jurkat.peaks.txt:md5,4cc5640d1e7c84db1116d6514265a4c3", + "versions.yml:md5,7c0dcd0a18b3c753def73b96cb825792", + "cd4_merged.bed:md5,f79432639c3f1b86787947e8d7242c75", + "jurkat_merged.bed:md5,a94e1ec47f0564122ae1eb0f73be4ebd", + "cd4_chr21_1_unidirectional_peaks.bed:md5,60e0da7e5691e55d86eb9df9f6ea0c46", + "jurkat_chr21_1_unidirectional_peaks.bed:md5,3584ff1a08cdecc92b6fcf6b2db8dc90" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-28T22:00:45.272491" + } +} \ No newline at end of file diff --git a/workflows/tests/transcript_indentification/grohmm/tuning/main.nf.test b/workflows/tests/transcript_indentification/grohmm/tuning/main.nf.test new file mode 100644 index 00000000..847b907c --- /dev/null +++ b/workflows/tests/transcript_indentification/grohmm/tuning/main.nf.test @@ -0,0 +1,39 @@ +nextflow_pipeline { + name "groHMM" + script "../../../../../main.nf" + tag "groHMM" + // triggers 'bin/parameter_tuning.R', 'bin/transcriptcalling_grohmm.R' + + test("Should run with defaults") { + when { + params { + outdir = "$outputDir" + skip_grohmm = false + } + } + + then { + // stable_name: All files + folders in ${params.outdir}/ with a stable name + def stable_name = getAllFilesFromDir(params.outdir, relative: true, includeDir: true, ignore: ['pipeline_info/*.{html,json,txt}', 'multiqc/multiqc_plots', 'multiqc/multiqc_plots/**']) + // stable_path: All files in ${params.outdir}/ with stable content + def stable_path = getAllFilesFromDir(params.outdir, ignoreFile: 'tests/.nftignore') + // bam_files: All bam files + def bam_files = getAllFilesFromDir(params.outdir, include: ['**/*.bam']) + assertAll( + { assert workflow.success }, + { assert snapshot( + // Number of 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_nascent_software_mqc_versions.yml"), + // All stable path name + stable_name, + // All files with stable contents + stable_path, + // All bam files + // FIXME bam_files.collect{ file -> [ file.getName(), bam(file.toString()).getReadsMD5() ] } + ).match() } + ) + } + } +} diff --git a/workflows/tests/transcript_indentification/grohmm/tuning/main.nf.test.snap b/workflows/tests/transcript_indentification/grohmm/tuning/main.nf.test.snap new file mode 100644 index 00000000..8b61a072 --- /dev/null +++ b/workflows/tests/transcript_indentification/grohmm/tuning/main.nf.test.snap @@ -0,0 +1,371 @@ +{ + "Should run with defaults": { + "content": [ + 112, + { + "BBMAP_PILEUP": { + "bbmap": 39.01, + "samtools": "1.16.1", + "pigz": 2.6 + }, + "BEDTOOLS_GENOMECOV_MINUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_GENOMECOV_PLUS": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_INTERSECT_FILTER": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_MERGE": { + "bedtools": "2.31.1" + }, + "BEDTOOLS_SORT": { + "bedtools": "2.31.1" + }, + "BWA_INDEX": { + "bwa": "0.7.18-r1243-dirty" + }, + "BWA_MEM": { + "bwa": "0.7.18-r1243-dirty", + "samtools": 1.2 + }, + "CAT_CAT": { + "pigz": "2.3.4" + }, + "CUSTOM_GETCHROMSIZES": { + "getchromsizes": 1.2 + }, + "DEEPTOOLS_BAMCOVERAGE_MINUS": { + "deeptools": "3.5.5" + }, + "DEEPTOOLS_BAMCOVERAGE_PLUS": { + "deeptools": "3.5.5" + }, + "FASTP": { + "fastp": "0.23.4" + }, + "FASTQC": { + "fastqc": "0.12.1" + }, + "GROHMM_PARAMETERTUNING": { + "r-base": "4.3.3", + "bioconductor-grohmm": "1.39.0" + }, + "GTF2BED": { + "perl": "5.26.2" + }, + "HOMER_MAKETAGDIRECTORY": { + "homer": 4.11, + "samtools": 1.21 + }, + "PINTS_CALLER": { + "python": "3.12.6", + "pints": "1.1.13" + }, + "PRESEQ_CCURVE": { + "preseq": "3.1.1" + }, + "PRESEQ_LCEXTRAP": { + "preseq": "3.1.1" + }, + "RSEQC_INFEREXPERIMENT": { + "rseqc": "5.0.2" + }, + "RSEQC_READDISTRIBUTION": { + "rseqc": "5.0.2" + }, + "RSEQC_READDUPLICATION": { + "rseqc": "5.0.2" + }, + "SAMTOOLS_MERGE": { + "samtools": 1.21 + }, + "SUBREAD_FEATURECOUNTS_GENE": { + "subread": "2.0.1" + }, + "SUBREAD_FEATURECOUNTS_PREDICTED": { + "subread": "2.0.1" + }, + "Workflow": { + "nf-core/nascent": "v2.3.0" + } + }, + [ + "bwa", + "bwa/cd4_REP1.sorted.bam", + "bwa/cd4_REP1.sorted.bam.bai", + "bwa/cd4_REP2.sorted.bam", + "bwa/cd4_REP2.sorted.bam.bai", + "bwa/jurkat.sorted.bam", + "bwa/jurkat.sorted.bam.bai", + "bwa/samtools_stats", + "bwa/samtools_stats/cd4_REP1.sorted.bam.flagstat", + "bwa/samtools_stats/cd4_REP1.sorted.bam.idxstats", + "bwa/samtools_stats/cd4_REP1.sorted.bam.stats", + "bwa/samtools_stats/cd4_REP2.sorted.bam.flagstat", + "bwa/samtools_stats/cd4_REP2.sorted.bam.idxstats", + "bwa/samtools_stats/cd4_REP2.sorted.bam.stats", + "bwa/samtools_stats/jurkat.sorted.bam.flagstat", + "bwa/samtools_stats/jurkat.sorted.bam.idxstats", + "bwa/samtools_stats/jurkat.sorted.bam.stats", + "cat", + "cat/cd4.bed", + "cat/jurkat.bed", + "coverage_graphs", + "coverage_graphs/cd4_REP1.dreg.bedGraph", + "coverage_graphs/cd4_REP1.minus.bedGraph", + "coverage_graphs/cd4_REP1.minus.bigWig", + "coverage_graphs/cd4_REP1.plus.bedGraph", + "coverage_graphs/cd4_REP1.plus.bigWig", + "coverage_graphs/cd4_REP2.dreg.bedGraph", + "coverage_graphs/cd4_REP2.minus.bedGraph", + "coverage_graphs/cd4_REP2.minus.bigWig", + "coverage_graphs/cd4_REP2.plus.bedGraph", + "coverage_graphs/cd4_REP2.plus.bigWig", + "coverage_graphs/jurkat.dreg.bedGraph", + "coverage_graphs/jurkat.minus.bedGraph", + "coverage_graphs/jurkat.minus.bigWig", + "coverage_graphs/jurkat.plus.bedGraph", + "coverage_graphs/jurkat.plus.bigWig", + "multiqc", + "multiqc/multiqc_data", + "multiqc/multiqc_data/fastqc-status-check-heatmap.txt", + "multiqc/multiqc_data/fastqc_adapter_content_plot.txt", + "multiqc/multiqc_data/fastqc_overrepresented_sequences_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_n_content_plot.txt", + "multiqc/multiqc_data/fastqc_per_base_sequence_quality_plot.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Counts.txt", + "multiqc/multiqc_data/fastqc_per_sequence_gc_content_plot_Percentages.txt", + "multiqc/multiqc_data/fastqc_per_sequence_quality_scores_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_counts_plot.txt", + "multiqc/multiqc_data/fastqc_sequence_duplication_levels_plot.txt", + "multiqc/multiqc_data/fastqc_top_overrepresented_sequences_table.txt", + "multiqc/multiqc_data/homer-tag-directory-gc-content.txt", + "multiqc/multiqc_data/homer-tag-info-dist.txt", + "multiqc/multiqc_data/homer-tag-length-dist.txt", + "multiqc/multiqc_data/homer_tagdir.txt", + "multiqc/multiqc_data/multiqc.log", + "multiqc/multiqc_data/multiqc_citations.txt", + "multiqc/multiqc_data/multiqc_data.json", + "multiqc/multiqc_data/multiqc_fastqc.txt", + "multiqc/multiqc_data/multiqc_general_stats.txt", + "multiqc/multiqc_data/multiqc_rseqc_infer_experiment.txt", + "multiqc/multiqc_data/multiqc_rseqc_read_distribution.txt", + "multiqc/multiqc_data/multiqc_samtools_flagstat.txt", + "multiqc/multiqc_data/multiqc_samtools_idxstats.txt", + "multiqc/multiqc_data/multiqc_samtools_stats.txt", + "multiqc/multiqc_data/multiqc_software_versions.txt", + "multiqc/multiqc_data/multiqc_sources.txt", + "multiqc/multiqc_data/preseq.txt", + "multiqc/multiqc_data/preseq_complexity_plot_molecules.txt", + "multiqc/multiqc_data/rseqc_infer_experiment_plot.txt", + "multiqc/multiqc_data/rseqc_read_distribution_plot.txt", + "multiqc/multiqc_data/rseqc_read_dups.txt", + "multiqc/multiqc_data/rseqc_read_dups_plot.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Percentage_of_total.txt", + "multiqc/multiqc_data/samtools-flagstat-dp_Read_counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Normalised_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Observed_over_Expected_Counts.txt", + "multiqc/multiqc_data/samtools-idxstats-mapped-reads-plot_Raw_Counts.txt", + "multiqc/multiqc_data/samtools-stats-dp.txt", + "multiqc/multiqc_data/samtools_alignment_plot.txt", + "multiqc/multiqc_report.html", + "pipeline_info", + "pipeline_info/nf_core_nascent_software_mqc_versions.yml", + "preprocessing", + "preprocessing/fastp", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP1.trimmed.fastp.log", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.html", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.json", + "preprocessing/fastp/cd4_REP2.trimmed.fastp.log", + "preprocessing/fastp/jurkat.trimmed.fastp.html", + "preprocessing/fastp/jurkat.trimmed.fastp.json", + "preprocessing/fastp/jurkat.trimmed.fastp.log", + "preprocessing/fastqc", + "preprocessing/fastqc/cd4_REP1_fastqc.html", + "preprocessing/fastqc/cd4_REP1_fastqc.zip", + "preprocessing/fastqc/cd4_REP2_fastqc.html", + "preprocessing/fastqc/cd4_REP2_fastqc.zip", + "preprocessing/fastqc/jurkat_fastqc.html", + "preprocessing/fastqc/jurkat_fastqc.zip", + "quality_control", + "quality_control/bbsplit", + "quality_control/bbsplit/cd4_REP1.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP1.coverage.stats.txt", + "quality_control/bbsplit/cd4_REP2.coverage.hist.txt", + "quality_control/bbsplit/cd4_REP2.coverage.stats.txt", + "quality_control/bbsplit/jurkat.coverage.hist.txt", + "quality_control/bbsplit/jurkat.coverage.stats.txt", + "quality_control/preseq", + "quality_control/preseq/cd4_REP1.c_curve.txt", + "quality_control/preseq/cd4_REP1.lc_extrap.txt", + "quality_control/preseq/cd4_REP2.c_curve.txt", + "quality_control/preseq/cd4_REP2.lc_extrap.txt", + "quality_control/preseq/jurkat.c_curve.txt", + "quality_control/preseq/jurkat.lc_extrap.txt", + "quality_control/preseq/log", + "quality_control/preseq/log/cd4_REP1.command.log", + "quality_control/preseq/log/cd4_REP2.command.log", + "quality_control/preseq/log/jurkat.command.log", + "quality_control/rseqc", + "quality_control/rseqc/infer_experiment", + "quality_control/rseqc/infer_experiment/cd4_REP1.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/cd4_REP2.infer_experiment.txt", + "quality_control/rseqc/infer_experiment/jurkat.infer_experiment.txt", + "quality_control/rseqc/read_distribution", + "quality_control/rseqc/read_distribution/cd4_REP1.read_distribution.txt", + "quality_control/rseqc/read_distribution/cd4_REP2.read_distribution.txt", + "quality_control/rseqc/read_distribution/jurkat.read_distribution.txt", + "quality_control/rseqc/read_duplication", + "quality_control/rseqc/read_duplication/pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP1.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/cd4_REP2.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/pdf/jurkat.DupRate_plot.pdf", + "quality_control/rseqc/read_duplication/rscript", + "quality_control/rseqc/read_duplication/rscript/cd4_REP1.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/cd4_REP2.DupRate_plot.r", + "quality_control/rseqc/read_duplication/rscript/jurkat.DupRate_plot.r", + "quality_control/rseqc/read_duplication/xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP1.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/cd4_REP2.seq.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.pos.DupRate.xls", + "quality_control/rseqc/read_duplication/xls/jurkat.seq.DupRate.xls", + "quantification", + "quantification/gene", + "quantification/gene/cd4.featureCounts.txt", + "quantification/gene/cd4.featureCounts.txt.summary", + "quantification/gene/jurkat.featureCounts.txt", + "quantification/gene/jurkat.featureCounts.txt.summary", + "quantification/nascent", + "quantification/nascent/cd4-group_cd4_intersect-transcripts.featureCounts.txt", + "quantification/nascent/cd4-group_cd4_intersect-transcripts.featureCounts.txt.summary", + "quantification/nascent/cd4-group_jurkat_intersect-transcripts.featureCounts.txt", + "quantification/nascent/cd4-group_jurkat_intersect-transcripts.featureCounts.txt.summary", + "quantification/nascent/jurkat-group_cd4_intersect-transcripts.featureCounts.txt", + "quantification/nascent/jurkat-group_cd4_intersect-transcripts.featureCounts.txt.summary", + "quantification/nascent/jurkat-group_jurkat_intersect-transcripts.featureCounts.txt", + "quantification/nascent/jurkat-group_jurkat_intersect-transcripts.featureCounts.txt.summary", + "samtools", + "samtools/cd4.bam", + "samtools/jurkat.bam", + "transcript_identification", + "transcript_identification/filtered", + "transcript_identification/filtered/cd4_filtered.bed", + "transcript_identification/filtered/jurkat_filtered.bed", + "transcript_identification/grohmm", + "transcript_identification/grohmm/cd4.SE.tuning.csv", + "transcript_identification/grohmm/cd4.eval.txt", + "transcript_identification/grohmm/cd4.final.transcripts.bed", + "transcript_identification/grohmm/cd4.tdFinal.txt", + "transcript_identification/grohmm/cd4.tdFinal_mqc.csv", + "transcript_identification/grohmm/cd4.tdplot_mqc.png", + "transcript_identification/grohmm/cd4.transcripts.txt", + "transcript_identification/grohmm/jurkat.SE.tuning.csv", + "transcript_identification/grohmm/jurkat.eval.txt", + "transcript_identification/grohmm/jurkat.final.transcripts.bed", + "transcript_identification/grohmm/jurkat.tdFinal.txt", + "transcript_identification/grohmm/jurkat.tdFinal_mqc.csv", + "transcript_identification/grohmm/jurkat.tdplot_mqc.png", + "transcript_identification/grohmm/jurkat.transcripts.txt", + "transcript_identification/homer", + "transcript_identification/homer/cd4.bed", + "transcript_identification/homer/cd4.bedGraph.gz", + "transcript_identification/homer/cd4.peaks.txt", + "transcript_identification/homer/cd4_tagdir", + "transcript_identification/homer/cd4_tagdir/chr21.tags.tsv", + "transcript_identification/homer/cd4_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/cd4_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/cd4_tagdir/tagFreq.txt", + "transcript_identification/homer/cd4_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/cd4_tagdir/tagGCcontent.txt", + "transcript_identification/homer/cd4_tagdir/tagInfo.txt", + "transcript_identification/homer/cd4_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/jurkat.bed", + "transcript_identification/homer/jurkat.bedGraph.gz", + "transcript_identification/homer/jurkat.peaks.txt", + "transcript_identification/homer/jurkat_tagdir", + "transcript_identification/homer/jurkat_tagdir/chr21.tags.tsv", + "transcript_identification/homer/jurkat_tagdir/genomeGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagAutocorrelation.txt", + "transcript_identification/homer/jurkat_tagdir/tagCountDistribution.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreq.txt", + "transcript_identification/homer/jurkat_tagdir/tagFreqUniq.txt", + "transcript_identification/homer/jurkat_tagdir/tagGCcontent.txt", + "transcript_identification/homer/jurkat_tagdir/tagInfo.txt", + "transcript_identification/homer/jurkat_tagdir/tagLengthDistribution.txt", + "transcript_identification/homer/versions.yml", + "transcript_identification/intersect", + "transcript_identification/intersect/cd4_intersect.bed", + "transcript_identification/intersect/jurkat_intersect.bed", + "transcript_identification/merged", + "transcript_identification/merged/cd4_merged.bed", + "transcript_identification/merged/jurkat_merged.bed", + "transcript_identification/pints", + "transcript_identification/pints/cd4_chr21_1_unidirectional_peaks.bed", + "transcript_identification/pints/jurkat_chr21_1_unidirectional_peaks.bed" + ], + [ + "cd4_REP1.sorted.bam.flagstat:md5,863e2d506d5cc4239af98a5f31bbc906", + "cd4_REP1.sorted.bam.idxstats:md5,b1dd8bcbd23c53c21f0e11082d9315f2", + "cd4_REP1.sorted.bam.stats:md5,70b7cd3040a9b7ca70e919afb4dc7fea", + "cd4_REP2.sorted.bam.flagstat:md5,0fd86dbf8f799fad49ba471702979bdc", + "cd4_REP2.sorted.bam.idxstats:md5,53204e4c6a9f68664087e4a8123be46a", + "cd4_REP2.sorted.bam.stats:md5,c0e8d8d265fce71dcd43e43c93d29ef3", + "jurkat.sorted.bam.flagstat:md5,fd5f02b0f02a407447b804b1d80f5421", + "jurkat.sorted.bam.idxstats:md5,c61af0847c1ad76c06a8de2815975b32", + "jurkat.sorted.bam.stats:md5,c9a6ec83d8fb1a14f53351c76cfcd24b", + "cd4.bed:md5,0193e58943726af89bfd00e9da2536d8", + "jurkat.bed:md5,cb6932229eea2e09f61d48d7dd397ae1", + "cd4_REP1.dreg.bedGraph:md5,8948a8fa86d8f6d413b77983189ff56e", + "cd4_REP1.minus.bedGraph:md5,2a1c34f9d9ef9ff1b9da7874b9e3aaad", + "cd4_REP1.minus.bigWig:md5,5280319275c98dcce023779fa389884d", + "cd4_REP1.plus.bedGraph:md5,1509ec3a921e3109c5914e1bcef8cf33", + "cd4_REP1.plus.bigWig:md5,72ccab3173f2018a22a4b36841247ba2", + "cd4_REP2.dreg.bedGraph:md5,29f865a5668fae4a52a41589ac2b3179", + "cd4_REP2.minus.bedGraph:md5,c530bc34fa3ec7ac49e88ff65f9c2f92", + "cd4_REP2.minus.bigWig:md5,5e748c794e037f441741f7f409c8c5ad", + "cd4_REP2.plus.bedGraph:md5,a675141da2874ec08d91591e5ea8242b", + "cd4_REP2.plus.bigWig:md5,08674d52e9eeb08807c33ed3e4b3d504", + "jurkat.dreg.bedGraph:md5,c25a4fb095e9f7d6766a3ce33e08f7d8", + "jurkat.minus.bedGraph:md5,8d5d9a41df6eb6c56b1bfd3f39dc1fc6", + "jurkat.minus.bigWig:md5,d06c8015c996bf520fff17266fd01f84", + "jurkat.plus.bedGraph:md5,6ed63e5983edaa74fb3965676efdb674", + "jurkat.plus.bigWig:md5,7a02334f2c7300ffdb5a2253c0937390", + "cd4_REP1.trimmed.fastp.json:md5,bd9a3344c1591d6be4d524451f9dca53", + "cd4_REP2.trimmed.fastp.json:md5,bc6e3f9ff7835f220535cc393b8eb25f", + "jurkat.trimmed.fastp.json:md5,65f7247a87479c7157c7357d575336e2", + "cd4.SE.tuning.csv:md5,00e1c530e2ce3b09fd413b8f87eef5d0", + "cd4.eval.txt:md5,6f688621a2acb60f2e48163f132d390c", + "cd4.final.transcripts.bed:md5,5eb7209e5bb45744ae03f89010a162aa", + "cd4.transcripts.txt:md5,4b339fcbf7ca955c12ca1198b2c0db36", + "jurkat.SE.tuning.csv:md5,6d6551f5ded9a49e05ffdbd233ae82b8", + "jurkat.eval.txt:md5,dac8d86b680c5a9d59558b62a3fc896b", + "jurkat.final.transcripts.bed:md5,d7149560c228316a2de2af10b48361ec", + "jurkat.transcripts.txt:md5,ad6c62cf26bcb7f56d073d5404bc8674", + "cd4.bed:md5,b55e5290d78941f36c3d1ecfef8e0062", + "cd4.peaks.txt:md5,bdcd2ec3a56a8a4a01ed19e17da003f2", + "jurkat.bed:md5,383cfaf10535dbe5d7f47607e345f4cb", + "jurkat.peaks.txt:md5,d4914194eca6f06aadfe7eed08ab1bb8", + "versions.yml:md5,7c0dcd0a18b3c753def73b96cb825792", + "cd4_merged.bed:md5,9ace0ca4f1544bb0949355a20de98e6b", + "jurkat_merged.bed:md5,f1dde43c4ad9dec972ff9fa38cc6f2fe", + "cd4_chr21_1_unidirectional_peaks.bed:md5,0193e58943726af89bfd00e9da2536d8", + "jurkat_chr21_1_unidirectional_peaks.bed:md5,cb6932229eea2e09f61d48d7dd397ae1" + ] + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "24.10.2" + }, + "timestamp": "2024-12-28T22:06:41.107934" + } +} \ No newline at end of file